fix(core): preserve bounded tool receipts

This commit is contained in:
Kit Langton 2026-07-20 14:58:58 -04:00
commit f7a72fdf32
22 changed files with 278 additions and 17 deletions

View file

@ -19,6 +19,7 @@ const assertions: PermissionV2.AssertInput[] = []
let captured: Form.CreateInput | undefined
let reject = false
let deny = false
let firstAnswer = "Build"
const capturedInput = () => captured
const questionInput = {
questions: [
@ -63,7 +64,7 @@ const form = Layer.succeed(
Effect.andThen(
Effect.sync(
(): Form.TerminalState =>
reject ? { status: "cancelled" } : { status: "answered", answer: { q0: "Build", q1: ["Dev"] } },
reject ? { status: "cancelled" } : { status: "answered", answer: { q0: firstAnswer, q1: ["Dev"] } },
),
),
),
@ -122,6 +123,7 @@ describe("QuestionTool", () => {
captured = undefined
reject = false
deny = false
firstAnswer = "Build"
const registry = yield* ToolRegistry.Service
const questions = [
{
@ -200,6 +202,27 @@ describe("QuestionTool", () => {
}),
)
it.effect("retains bounded answers for long custom responses", () =>
Effect.gen(function* () {
reject = false
deny = false
firstAnswer = "x".repeat(ToolOutputStore.MAX_STRUCTURED_BYTES)
const registry = yield* ToolRegistry.Service
const settled = yield* settleTool(registry, {
sessionID,
...toolIdentity,
call: { type: "tool-call", id: "call-question-large", name: "question", input: questionInput },
})
expect(Buffer.byteLength(JSON.stringify(settled.output?.structured))).toBeLessThanOrEqual(
ToolOutputStore.MAX_STRUCTURED_BYTES,
)
expect(settled.output?.structured).toMatchObject({
answers: [[expect.stringContaining("... truncated ...")]],
})
}).pipe(Effect.ensuring(Effect.sync(() => (firstAnswer = "Build")))),
)
it.effect("does not invent tool ownership metadata without a durable registry source", () =>
Effect.gen(function* () {
captured = undefined