feat(core): admit v2 skill guidance (#30843)
This commit is contained in:
parent
cc487dd032
commit
3f64b5e621
40 changed files with 3119 additions and 174 deletions
|
|
@ -38,7 +38,9 @@ describe("SkillTool", () => {
|
|||
location: AbsolutePath.make(location),
|
||||
content: "# Effect\n\nGuidance",
|
||||
}
|
||||
let current = [info]
|
||||
const assertions: PermissionV2.AssertInput[] = []
|
||||
let deny = false
|
||||
const truncations: ToolOutputStore.TruncateInput[] = []
|
||||
let truncate = (input: ToolOutputStore.TruncateInput): Effect.Effect<ToolOutputStore.TruncateResult> =>
|
||||
Effect.succeed({ content: input.content, truncated: false })
|
||||
|
|
@ -55,7 +57,10 @@ describe("SkillTool", () => {
|
|||
const permission = Layer.succeed(
|
||||
PermissionV2.Service,
|
||||
PermissionV2.Service.of({
|
||||
assert: (input) => Effect.sync(() => assertions.push(input)),
|
||||
assert: (input) =>
|
||||
Effect.sync(() => assertions.push(input)).pipe(
|
||||
Effect.andThen(deny ? Effect.fail(new PermissionV2.DeniedError({ rules: [] })) : Effect.void),
|
||||
),
|
||||
ask: () => Effect.die("unused"),
|
||||
reply: () => Effect.die("unused"),
|
||||
get: () => Effect.die("unused"),
|
||||
|
|
@ -68,8 +73,7 @@ describe("SkillTool", () => {
|
|||
SkillV2.Service.of({
|
||||
transform: () => Effect.die("unused"),
|
||||
sources: () => Effect.die("unused"),
|
||||
list: () => Effect.succeed([info]),
|
||||
forAgent: () => Effect.die("unused"),
|
||||
list: () => Effect.succeed(current),
|
||||
}),
|
||||
)
|
||||
const registry = ToolRegistry.defaultLayer.pipe(Layer.provide(permission))
|
||||
|
|
@ -97,7 +101,7 @@ describe("SkillTool", () => {
|
|||
expect(bootWaited).toBe(true)
|
||||
expect((yield* registry.definitions())[0]).toMatchObject({
|
||||
name: "skill",
|
||||
description: expect.stringContaining("**effect**: Use Effect"),
|
||||
description: SkillTool.description,
|
||||
})
|
||||
expect(
|
||||
yield* registry.execute({
|
||||
|
|
@ -141,7 +145,35 @@ describe("SkillTool", () => {
|
|||
sessionID,
|
||||
call: { type: "tool-call", id: "call-missing-skill", name: "skill", input: { name: "missing" } },
|
||||
}),
|
||||
).toEqual({ type: "error", value: 'Skill "missing" not found. Available skills: effect' })
|
||||
).toEqual({ type: "error", value: "Unable to load skill missing" })
|
||||
deny = true
|
||||
expect(
|
||||
yield* registry.execute({
|
||||
sessionID,
|
||||
call: { type: "tool-call", id: "call-denied-skill", name: "skill", input: { name: "effect" } },
|
||||
}),
|
||||
).toEqual({ type: "error", value: "Unable to load skill effect" })
|
||||
deny = false
|
||||
const flat = new SkillV2.Info({
|
||||
name: "public",
|
||||
description: "Public guidance",
|
||||
location: AbsolutePath.make(path.join(tmp.path, "public.md")),
|
||||
content: "Public",
|
||||
})
|
||||
yield* Effect.promise(() =>
|
||||
Promise.all([
|
||||
fs.writeFile(flat.location, "public"),
|
||||
fs.writeFile(path.join(tmp.path, "secret.md"), "secret"),
|
||||
]),
|
||||
)
|
||||
current = [flat]
|
||||
truncate = (input) => Effect.succeed({ content: input.content, truncated: false })
|
||||
expect(
|
||||
yield* registry.execute({
|
||||
sessionID,
|
||||
call: { type: "tool-call", id: "call-flat-skill", name: "skill", input: { name: "public" } },
|
||||
}),
|
||||
).toEqual({ type: "text", value: SkillTool.toModelOutput(flat, []) })
|
||||
}).pipe(Effect.provide(layer))
|
||||
}),
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue