fix(core): preserve admitted tool generations (#36177)
This commit is contained in:
parent
4a006b1210
commit
3785eddfa0
5 changed files with 127 additions and 51 deletions
|
|
@ -97,12 +97,7 @@ describe("ToolRegistry", () => {
|
|||
.pipe(Effect.map((materialized) => materialized.definitions.map((tool) => tool.name)))
|
||||
|
||||
expect(yield* names({ id: "gpt-5", provider: "openai" })).toEqual(["read", "edit", "write", "patch"])
|
||||
expect(yield* names({ id: "claude-sonnet-4", provider: "anthropic" })).toEqual([
|
||||
"read",
|
||||
"edit",
|
||||
"write",
|
||||
"patch",
|
||||
])
|
||||
expect(yield* names({ id: "claude-sonnet-4", provider: "anthropic" })).toEqual(["read", "edit", "write", "patch"])
|
||||
}),
|
||||
)
|
||||
|
||||
|
|
@ -355,7 +350,7 @@ describe("ToolRegistry", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("rejects a call when its advertised registration was removed", () =>
|
||||
it.effect("executes the advertised registration after it is removed", () =>
|
||||
Effect.gen(function* () {
|
||||
const service = yield* ToolRegistry.Service
|
||||
const scope = yield* Scope.make()
|
||||
|
|
@ -363,29 +358,23 @@ describe("ToolRegistry", () => {
|
|||
const materialized = yield* service.materialize({ model: testModel })
|
||||
yield* Scope.close(scope, Exit.void)
|
||||
|
||||
expect((yield* materialized.settle(call("echo"))).result).toEqual({
|
||||
type: "error",
|
||||
value: "Stale tool call: echo",
|
||||
})
|
||||
expect((yield* materialized.settle(call("echo"))).result).toEqual({ type: "text", value: "echo" })
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("rejects only the replaced name from a multi-tool provider turn", () =>
|
||||
it.effect("executes each registration advertised for a provider turn after replacement", () =>
|
||||
Effect.gen(function* () {
|
||||
const service = yield* ToolRegistry.Service
|
||||
yield* service.register({ first: make(), second: make() })
|
||||
const materialized = yield* service.materialize({ model: testModel })
|
||||
yield* service.register({ first: make() })
|
||||
|
||||
expect((yield* materialized.settle(call("first"))).result).toEqual({
|
||||
type: "error",
|
||||
value: "Stale tool call: first",
|
||||
})
|
||||
expect((yield* materialized.settle(call("first"))).result).toEqual({ type: "text", value: "first" })
|
||||
expect((yield* materialized.settle(call("second"))).result).toEqual({ type: "text", value: "second" })
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("treats revealing a previous overlay as stale", () =>
|
||||
it.effect("executes an advertised overlay after the previous registration is revealed", () =>
|
||||
Effect.gen(function* () {
|
||||
const service = yield* ToolRegistry.Service
|
||||
yield* service.register({ echo: make() })
|
||||
|
|
@ -394,10 +383,54 @@ describe("ToolRegistry", () => {
|
|||
const materialized = yield* service.materialize({ model: testModel })
|
||||
yield* Scope.close(overlay, Exit.void)
|
||||
|
||||
expect((yield* materialized.settle(call("echo"))).result).toEqual({
|
||||
type: "error",
|
||||
value: "Stale tool call: echo",
|
||||
expect((yield* materialized.settle(call("echo"))).result).toEqual({ type: "text", value: "echo" })
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("executes deferred registrations from the advertised generation", () =>
|
||||
Effect.gen(function* () {
|
||||
const service = yield* ToolRegistry.Service
|
||||
const executed: string[] = []
|
||||
const scope = yield* Scope.make()
|
||||
yield* service
|
||||
.register(
|
||||
{
|
||||
echo: Tool.make({
|
||||
description: "Echo text",
|
||||
input: Schema.Struct({ text: Schema.String }),
|
||||
output: Schema.Struct({ text: Schema.String }),
|
||||
execute: ({ text }) => Effect.sync(() => executed.push(`old:${text}`)).pipe(Effect.as({ text })),
|
||||
}),
|
||||
},
|
||||
{ deferred: true },
|
||||
)
|
||||
.pipe(Scope.provide(scope))
|
||||
const materialized = yield* service.materialize({ model: testModel })
|
||||
yield* Scope.close(scope, Exit.void)
|
||||
yield* service.register(
|
||||
{
|
||||
echo: Tool.make({
|
||||
description: "Echo text",
|
||||
input: Schema.Struct({ text: Schema.String }),
|
||||
output: Schema.Struct({ text: Schema.String }),
|
||||
execute: ({ text }) => Effect.sync(() => executed.push(`new:${text}`)).pipe(Effect.as({ text })),
|
||||
}),
|
||||
},
|
||||
{ deferred: true },
|
||||
)
|
||||
|
||||
const settlement = yield* materialized.settle({
|
||||
...call("execute"),
|
||||
call: {
|
||||
type: "tool-call",
|
||||
id: "call-execute",
|
||||
name: "execute",
|
||||
input: { code: 'return await tools.echo({ text: "admitted" })' },
|
||||
},
|
||||
})
|
||||
|
||||
expect(settlement.result).toMatchObject({ type: "text" })
|
||||
expect(executed).toEqual(["old:admitted"])
|
||||
}),
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue