fix(core): preserve admitted tool generations (#36177)

This commit is contained in:
Kit Langton 2026-07-09 21:16:00 -04:00 committed by GitHub
commit 3785eddfa0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 127 additions and 51 deletions

View file

@ -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"])
}),
)