@polpo-ai/server 0.17.3 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/routes/completions/agent-step-runner.d.ts +2 -0
- package/dist/routes/completions/agent-step-runner.d.ts.map +1 -1
- package/dist/routes/completions/agent-step-runner.js +196 -96
- package/dist/routes/completions/agent-step-runner.js.map +1 -1
- package/dist/routes/completions/agent-step-runner.test.js +34 -14
- package/dist/routes/completions/agent-step-runner.test.js.map +1 -1
- package/dist/routes/completions/chat-handler.d.ts +3 -1
- package/dist/routes/completions/chat-handler.d.ts.map +1 -1
- package/dist/routes/completions/chat-handler.js +203 -49
- package/dist/routes/completions/chat-handler.js.map +1 -1
- package/dist/routes/completions/conversation-turn.d.ts.map +1 -1
- package/dist/routes/completions/conversation-turn.js +28 -0
- package/dist/routes/completions/conversation-turn.js.map +1 -1
- package/dist/routes/completions/production-tool-replay.test.d.ts +2 -0
- package/dist/routes/completions/production-tool-replay.test.d.ts.map +1 -0
- package/dist/routes/completions/production-tool-replay.test.js +232 -0
- package/dist/routes/completions/production-tool-replay.test.js.map +1 -0
- package/dist/routes/completions/project-loop-runner.d.ts.map +1 -1
- package/dist/routes/completions/project-loop-runner.js +5 -1
- package/dist/routes/completions/project-loop-runner.js.map +1 -1
- package/dist/routes/completions/sse.d.ts.map +1 -1
- package/dist/routes/completions/sse.js +3 -1
- package/dist/routes/completions/sse.js.map +1 -1
- package/dist/routes/completions/structured-output-phases.test.d.ts +2 -0
- package/dist/routes/completions/structured-output-phases.test.d.ts.map +1 -0
- package/dist/routes/completions/structured-output-phases.test.js +255 -0
- package/dist/routes/completions/structured-output-phases.test.js.map +1 -0
- package/dist/routes/completions/tool-guardrails.d.ts +21 -3
- package/dist/routes/completions/tool-guardrails.d.ts.map +1 -1
- package/dist/routes/completions/tool-guardrails.js +95 -14
- package/dist/routes/completions/tool-guardrails.js.map +1 -1
- package/dist/routes/completions/tool-guardrails.test.js +215 -5
- package/dist/routes/completions/tool-guardrails.test.js.map +1 -1
- package/dist/routes/completions/tool-mapping.d.ts +1 -0
- package/dist/routes/completions/tool-mapping.d.ts.map +1 -1
- package/dist/routes/completions/tool-mapping.js +8 -4
- package/dist/routes/completions/tool-mapping.js.map +1 -1
- package/dist/routes/completions/tool-mapping.test.js +59 -38
- package/dist/routes/completions/tool-mapping.test.js.map +1 -1
- package/dist/routes/completions-loop-runtime.test.js +45 -3
- package/dist/routes/completions-loop-runtime.test.js.map +1 -1
- package/dist/routes/completions-provider-tools.test.js +21 -2
- package/dist/routes/completions-provider-tools.test.js.map +1 -1
- package/dist/routes/completions.d.ts +2 -0
- package/dist/routes/completions.d.ts.map +1 -1
- package/dist/routes/completions.js.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { MockLanguageModelV3, convertArrayToReadableStream } from "ai/test";
|
|
3
|
+
import { normalizeChatInteractionSettings } from "@polpo-ai/core/chat-interactions";
|
|
4
|
+
import { executeStreamingChatCompletion, runNonStreamingChatCompletion, } from "./chat-handler.js";
|
|
5
|
+
import { modelOutputForResponseFormat } from "./structured-output.js";
|
|
6
|
+
import { createGuardedCompletionToolExecutor, } from "./tool-guardrails.js";
|
|
7
|
+
const responseFormat = {
|
|
8
|
+
type: "json_schema",
|
|
9
|
+
json_schema: {
|
|
10
|
+
name: "answer",
|
|
11
|
+
strict: true,
|
|
12
|
+
schema: {
|
|
13
|
+
type: "object",
|
|
14
|
+
additionalProperties: false,
|
|
15
|
+
required: ["answer"],
|
|
16
|
+
properties: { answer: { type: "string" } },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
function fixture() {
|
|
21
|
+
let operationalTurn = 0;
|
|
22
|
+
const responseFormats = [];
|
|
23
|
+
const toolCounts = [];
|
|
24
|
+
const executor = vi.fn(async () => "inspected");
|
|
25
|
+
const usage = {
|
|
26
|
+
inputTokens: { total: 4 },
|
|
27
|
+
outputTokens: { total: 2 },
|
|
28
|
+
};
|
|
29
|
+
const model = new MockLanguageModelV3({
|
|
30
|
+
doStream: async (options) => {
|
|
31
|
+
responseFormats.push(options.responseFormat);
|
|
32
|
+
toolCounts.push(options.tools?.length ?? 0);
|
|
33
|
+
if (!options.responseFormat)
|
|
34
|
+
operationalTurn += 1;
|
|
35
|
+
if (!options.responseFormat && operationalTurn === 1) {
|
|
36
|
+
return { stream: convertArrayToReadableStream([
|
|
37
|
+
{ type: "stream-start", warnings: [] },
|
|
38
|
+
{ type: "tool-call", toolCallId: "inspect_1", toolName: "inspect", input: "{}" },
|
|
39
|
+
{ type: "finish", finishReason: { unified: "tool-calls", raw: undefined }, usage },
|
|
40
|
+
]) };
|
|
41
|
+
}
|
|
42
|
+
const text = options.responseFormat
|
|
43
|
+
? '{"answer":"ready"}'
|
|
44
|
+
: "Operational work complete.";
|
|
45
|
+
return { stream: convertArrayToReadableStream([
|
|
46
|
+
{ type: "stream-start", warnings: [] },
|
|
47
|
+
{ type: "text-start", id: "text" },
|
|
48
|
+
{ type: "text-delta", id: "text", delta: text },
|
|
49
|
+
{ type: "text-end", id: "text" },
|
|
50
|
+
{ type: "finish", finishReason: { unified: "stop", raw: undefined }, usage },
|
|
51
|
+
]) };
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
const deps = {
|
|
55
|
+
getConfig: () => ({ settings: {} }),
|
|
56
|
+
emit: vi.fn(),
|
|
57
|
+
resolveAgentModel: vi.fn(async () => ({
|
|
58
|
+
model: {
|
|
59
|
+
id: "mock/model",
|
|
60
|
+
provider: "mock",
|
|
61
|
+
aiModel: model,
|
|
62
|
+
maxTokens: 8192,
|
|
63
|
+
contextWindow: 128_000,
|
|
64
|
+
},
|
|
65
|
+
})),
|
|
66
|
+
};
|
|
67
|
+
const execution = {
|
|
68
|
+
deps,
|
|
69
|
+
body: {
|
|
70
|
+
agent: "test-agent",
|
|
71
|
+
messages: [{ role: "user", content: "Inspect and answer" }],
|
|
72
|
+
response_format: responseFormat,
|
|
73
|
+
},
|
|
74
|
+
completionId: "completion",
|
|
75
|
+
agentConfig: { name: "test-agent", model: "mock/model" },
|
|
76
|
+
agentMode: true,
|
|
77
|
+
fullSystemPrompt: "Inspect before answering.",
|
|
78
|
+
m: {
|
|
79
|
+
id: "mock/model",
|
|
80
|
+
provider: "mock",
|
|
81
|
+
aiModel: model,
|
|
82
|
+
maxTokens: 8192,
|
|
83
|
+
contextWindow: 128_000,
|
|
84
|
+
},
|
|
85
|
+
modelOutput: modelOutputForResponseFormat(responseFormat),
|
|
86
|
+
effectiveTools: [{
|
|
87
|
+
name: "inspect",
|
|
88
|
+
description: "Inspect",
|
|
89
|
+
parameters: { type: "object", properties: {}, additionalProperties: false },
|
|
90
|
+
}],
|
|
91
|
+
effectiveToolExecutor: executor,
|
|
92
|
+
clientSideTools: {},
|
|
93
|
+
interactionSettings: normalizeChatInteractionSettings({}),
|
|
94
|
+
aiMessages: [{ role: "user", content: "Inspect and answer" }],
|
|
95
|
+
sessionStore: null,
|
|
96
|
+
sessionId: null,
|
|
97
|
+
};
|
|
98
|
+
return { execution, executor, responseFormats, toolCounts };
|
|
99
|
+
}
|
|
100
|
+
describe("chat structured-output phases", () => {
|
|
101
|
+
it("separates operational tools from terminal output in non-streaming chat", async () => {
|
|
102
|
+
const f = fixture();
|
|
103
|
+
const response = await runNonStreamingChatCompletion({
|
|
104
|
+
req: { raw: { signal: new AbortController().signal } },
|
|
105
|
+
json: (body) => body,
|
|
106
|
+
}, f.execution);
|
|
107
|
+
expect(response.choices[0].message.content).toBe('{"answer":"ready"}');
|
|
108
|
+
expect(f.responseFormats).toEqual([
|
|
109
|
+
undefined,
|
|
110
|
+
undefined,
|
|
111
|
+
expect.objectContaining({ type: "json" }),
|
|
112
|
+
]);
|
|
113
|
+
expect(f.toolCounts).toEqual([1, 1, 0]);
|
|
114
|
+
expect(f.executor).toHaveBeenCalledOnce();
|
|
115
|
+
});
|
|
116
|
+
it("buffers and validates terminal output before publishing streaming chat", async () => {
|
|
117
|
+
const f = fixture();
|
|
118
|
+
const frames = [];
|
|
119
|
+
const writer = {
|
|
120
|
+
write: vi.fn(async () => { }),
|
|
121
|
+
writeSSE: vi.fn(async ({ data }) => { frames.push(data); }),
|
|
122
|
+
};
|
|
123
|
+
await executeStreamingChatCompletion(writer, f.execution, new AbortController().signal);
|
|
124
|
+
expect(f.responseFormats).toEqual([
|
|
125
|
+
undefined,
|
|
126
|
+
undefined,
|
|
127
|
+
expect.objectContaining({ type: "json" }),
|
|
128
|
+
]);
|
|
129
|
+
expect(f.toolCounts).toEqual([1, 1, 0]);
|
|
130
|
+
expect(f.executor).toHaveBeenCalledOnce();
|
|
131
|
+
const contentFrames = frames
|
|
132
|
+
.filter((frame) => frame !== "[DONE]")
|
|
133
|
+
.map((frame) => JSON.parse(frame))
|
|
134
|
+
.flatMap((frame) => frame.choices ?? [])
|
|
135
|
+
.map((choice) => choice.delta?.content)
|
|
136
|
+
.filter(Boolean);
|
|
137
|
+
expect(contentFrames).toEqual(['{"answer":"ready"}']);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
function repeatedStableReadFixture() {
|
|
141
|
+
const providerCalls = vi.fn();
|
|
142
|
+
const usage = {
|
|
143
|
+
inputTokens: { total: 2 },
|
|
144
|
+
outputTokens: { total: 1 },
|
|
145
|
+
};
|
|
146
|
+
let turn = 0;
|
|
147
|
+
const model = new MockLanguageModelV3({
|
|
148
|
+
doStream: async () => {
|
|
149
|
+
providerCalls();
|
|
150
|
+
turn += 1;
|
|
151
|
+
return { stream: convertArrayToReadableStream([
|
|
152
|
+
{ type: "stream-start", warnings: [] },
|
|
153
|
+
{
|
|
154
|
+
type: "tool-call",
|
|
155
|
+
toolCallId: `read_${turn}`,
|
|
156
|
+
toolName: "stable_read",
|
|
157
|
+
input: JSON.stringify({ key: "same" }),
|
|
158
|
+
},
|
|
159
|
+
{ type: "finish", finishReason: { unified: "tool-calls", raw: undefined }, usage },
|
|
160
|
+
]) };
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
const executor = vi.fn(async () => "unchanged");
|
|
164
|
+
const progress = {};
|
|
165
|
+
const tool = {
|
|
166
|
+
name: "stable_read",
|
|
167
|
+
description: "Read stable state",
|
|
168
|
+
parameters: {
|
|
169
|
+
type: "object",
|
|
170
|
+
properties: { key: { type: "string" } },
|
|
171
|
+
required: ["key"],
|
|
172
|
+
additionalProperties: false,
|
|
173
|
+
},
|
|
174
|
+
annotations: {
|
|
175
|
+
readOnlyHint: true,
|
|
176
|
+
idempotentHint: true,
|
|
177
|
+
resultStability: "stable",
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
const guarded = createGuardedCompletionToolExecutor({
|
|
181
|
+
executor,
|
|
182
|
+
tools: [tool],
|
|
183
|
+
context: { source: "request" },
|
|
184
|
+
onProgress: ({ name, decision }) => {
|
|
185
|
+
if (decision.action !== "stall")
|
|
186
|
+
return;
|
|
187
|
+
progress.stalled = {
|
|
188
|
+
code: decision.code,
|
|
189
|
+
toolName: name,
|
|
190
|
+
fingerprint: decision.fingerprint,
|
|
191
|
+
observation: decision.observation,
|
|
192
|
+
message: decision.message,
|
|
193
|
+
};
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
const execution = {
|
|
197
|
+
deps: { getConfig: () => ({ settings: {} }), emit: vi.fn() },
|
|
198
|
+
body: { agent: "test-agent", messages: [{ role: "user", content: "Read it" }] },
|
|
199
|
+
completionId: "completion-stall",
|
|
200
|
+
agentConfig: { name: "test-agent", model: "mock/model" },
|
|
201
|
+
agentMode: true,
|
|
202
|
+
fullSystemPrompt: "Use the read tool.",
|
|
203
|
+
m: {
|
|
204
|
+
id: "mock/model",
|
|
205
|
+
provider: "mock",
|
|
206
|
+
aiModel: model,
|
|
207
|
+
maxTokens: 8192,
|
|
208
|
+
contextWindow: 128_000,
|
|
209
|
+
},
|
|
210
|
+
effectiveTools: [tool],
|
|
211
|
+
effectiveToolExecutor: guarded,
|
|
212
|
+
toolProgressState: progress,
|
|
213
|
+
clientSideTools: {},
|
|
214
|
+
interactionSettings: normalizeChatInteractionSettings({}),
|
|
215
|
+
aiMessages: [{ role: "user", content: "Read it" }],
|
|
216
|
+
sessionStore: null,
|
|
217
|
+
sessionId: null,
|
|
218
|
+
};
|
|
219
|
+
return { execution, executor, providerCalls };
|
|
220
|
+
}
|
|
221
|
+
describe("chat stable-read livelock boundary", () => {
|
|
222
|
+
it("returns a typed non-streaming error on the fourth observation", async () => {
|
|
223
|
+
const fixture = repeatedStableReadFixture();
|
|
224
|
+
let status = 200;
|
|
225
|
+
const response = await runNonStreamingChatCompletion({
|
|
226
|
+
req: { raw: { signal: new AbortController().signal } },
|
|
227
|
+
json: (body, nextStatus) => {
|
|
228
|
+
status = nextStatus ?? 200;
|
|
229
|
+
return body;
|
|
230
|
+
},
|
|
231
|
+
}, fixture.execution);
|
|
232
|
+
expect(status).toBe(409);
|
|
233
|
+
expect(response.error).toMatchObject({
|
|
234
|
+
type: "runtime_error",
|
|
235
|
+
code: "tool_loop_stalled",
|
|
236
|
+
});
|
|
237
|
+
expect(fixture.providerCalls).toHaveBeenCalledTimes(4);
|
|
238
|
+
expect(fixture.executor).toHaveBeenCalledTimes(1);
|
|
239
|
+
});
|
|
240
|
+
it("emits the same typed error and stops the streaming loop", async () => {
|
|
241
|
+
const fixture = repeatedStableReadFixture();
|
|
242
|
+
const frames = [];
|
|
243
|
+
await executeStreamingChatCompletion({
|
|
244
|
+
write: vi.fn(async () => { }),
|
|
245
|
+
writeSSE: vi.fn(async ({ data }) => { frames.push(data); }),
|
|
246
|
+
}, fixture.execution, new AbortController().signal);
|
|
247
|
+
const payloads = frames
|
|
248
|
+
.filter((frame) => frame !== "[DONE]")
|
|
249
|
+
.map((frame) => JSON.parse(frame));
|
|
250
|
+
expect(payloads.some((frame) => frame.choices?.[0]?.error?.code === "tool_loop_stalled")).toBe(true);
|
|
251
|
+
expect(fixture.providerCalls).toHaveBeenCalledTimes(4);
|
|
252
|
+
expect(fixture.executor).toHaveBeenCalledTimes(1);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
//# sourceMappingURL=structured-output-phases.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structured-output-phases.test.js","sourceRoot":"","sources":["../../../src/routes/completions/structured-output-phases.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,gCAAgC,EAAE,MAAM,kCAAkC,CAAC;AAGpF,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,GAE9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EACL,mCAAmC,GAEpC,MAAM,sBAAsB,CAAC;AAE9B,MAAM,cAAc,GAAG;IACrB,IAAI,EAAE,aAAsB;IAC5B,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,oBAAoB,EAAE,KAAK;YAC3B,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;SAC3C;KACF;CACF,CAAC;AAEF,SAAS,OAAO;IACd,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,MAAM,eAAe,GAAc,EAAE,CAAC;IACtC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG;QACZ,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;QACzB,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;KAC3B,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,mBAAmB,CAAC;QACpC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC1B,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAC7C,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;YAC5C,IAAI,CAAC,OAAO,CAAC,cAAc;gBAAE,eAAe,IAAI,CAAC,CAAC;YAClD,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;gBACrD,OAAO,EAAE,MAAM,EAAE,4BAA4B,CAAC;wBAC5C,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,EAAE;wBACtC,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE;wBAChF,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE;qBAC1E,CAAC,EAAE,CAAC;YAChB,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc;gBACjC,CAAC,CAAC,oBAAoB;gBACtB,CAAC,CAAC,4BAA4B,CAAC;YACjC,OAAO,EAAE,MAAM,EAAE,4BAA4B,CAAC;oBAC5C,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,EAAE;oBACtC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE;oBAClC,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC/C,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE;oBAChC,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE;iBACpE,CAAC,EAAE,CAAC;QAChB,CAAC;KACF,CAAC,CAAC;IACH,MAAM,IAAI,GAAG;QACX,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACnC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACb,iBAAiB,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACpC,KAAK,EAAE;gBACL,EAAE,EAAE,YAAY;gBAChB,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,IAAI;gBACf,aAAa,EAAE,OAAO;aACvB;SACF,CAAC,CAAC;KAC8B,CAAC;IACpC,MAAM,SAAS,GAA4B;QACzC,IAAI;QACJ,IAAI,EAAE;YACJ,KAAK,EAAE,YAAY;YACnB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;YAC3D,eAAe,EAAE,cAAc;SAChC;QACD,YAAY,EAAE,YAAY;QAC1B,WAAW,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;QACxD,SAAS,EAAE,IAAI;QACf,gBAAgB,EAAE,2BAA2B;QAC7C,CAAC,EAAE;YACD,EAAE,EAAE,YAAY;YAChB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,IAAI;YACf,aAAa,EAAE,OAAO;SACvB;QACD,WAAW,EAAE,4BAA4B,CAAC,cAAc,CAAC;QACzD,cAAc,EAAE,CAAC;gBACf,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,SAAS;gBACtB,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE;aAC5E,CAAC;QACF,qBAAqB,EAAE,QAAQ;QAC/B,eAAe,EAAE,EAAE;QACnB,mBAAmB,EAAE,gCAAgC,CAAC,EAAE,CAAC;QACzD,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;QAC7D,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,IAAI;KAChB,CAAC;IACF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC;AAC9D,CAAC;AAED,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC7C,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,MAAM,6BAA6B,CAAC;YACnD,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,EAAE,EAAE;YACtD,IAAI,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,IAAI;SACvB,EAAE,CAAC,CAAC,SAAS,CAAQ,CAAC;QAE9B,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACvE,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC;YAChC,SAAS;YACT,SAAS;YACT,MAAM,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SAC1C,CAAC,CAAC;QACH,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,oBAAoB,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG;YACb,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;YAC5B,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,IAAI,EAAoB,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;SAC9E,CAAC;QAEF,MAAM,8BAA8B,CAClC,MAAM,EACN,CAAC,CAAC,SAAS,EACX,IAAI,eAAe,EAAE,CAAC,MAAM,CAC7B,CAAC;QAEF,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC;YAChC,SAAS;YACT,SAAS;YACT,MAAM,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SAC1C,CAAC,CAAC;QACH,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,oBAAoB,EAAE,CAAC;QAC1C,MAAM,aAAa,GAAG,MAAM;aACzB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC;aACrC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;aACjC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;aACvC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC;aACtC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,SAAS,yBAAyB;IAChC,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG;QACZ,WAAW,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;QACzB,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;KAC3B,CAAC;IACF,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,MAAM,KAAK,GAAG,IAAI,mBAAmB,CAAC;QACpC,QAAQ,EAAE,KAAK,IAAI,EAAE;YACnB,aAAa,EAAE,CAAC;YAChB,IAAI,IAAI,CAAC,CAAC;YACV,OAAO,EAAE,MAAM,EAAE,4BAA4B,CAAC;oBAC5C,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,EAAE;oBACtC;wBACE,IAAI,EAAE,WAAW;wBACjB,UAAU,EAAE,QAAQ,IAAI,EAAE;wBAC1B,QAAQ,EAAE,aAAa;wBACvB,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;qBACvC;oBACD,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE;iBAC1E,CAAC,EAAE,CAAC;QAChB,CAAC;KACF,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAgC,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG;QACX,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,mBAAmB;QAChC,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YACvC,QAAQ,EAAE,CAAC,KAAK,CAAC;YACjB,oBAAoB,EAAE,KAAK;SAC5B;QACD,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;YACpB,eAAe,EAAE,QAAiB;SACnC;KACF,CAAC;IACF,MAAM,OAAO,GAAG,mCAAmC,CAAC;QAClD,QAAQ;QACR,KAAK,EAAE,CAAC,IAAI,CAAC;QACb,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;QAC9B,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;YACjC,IAAI,QAAQ,CAAC,MAAM,KAAK,OAAO;gBAAE,OAAO;YACxC,QAAQ,CAAC,OAAO,GAAG;gBACjB,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,OAAO,EAAE,QAAQ,CAAC,OAAO;aAC1B,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;IACH,MAAM,SAAS,GAA4B;QACzC,IAAI,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,EAAS;QACnE,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE;QAC/E,YAAY,EAAE,kBAAkB;QAChC,WAAW,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;QACxD,SAAS,EAAE,IAAI;QACf,gBAAgB,EAAE,oBAAoB;QACtC,CAAC,EAAE;YACD,EAAE,EAAE,YAAY;YAChB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,IAAI;YACf,aAAa,EAAE,OAAO;SACvB;QACD,cAAc,EAAE,CAAC,IAAI,CAAC;QACtB,qBAAqB,EAAE,OAAO;QAC9B,iBAAiB,EAAE,QAAQ;QAC3B,eAAe,EAAE,EAAE;QACnB,mBAAmB,EAAE,gCAAgC,CAAC,EAAE,CAAC;QACzD,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QAClD,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,IAAI;KAChB,CAAC;IACF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;AAChD,CAAC;AAED,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,OAAO,GAAG,yBAAyB,EAAE,CAAC;QAC5C,IAAI,MAAM,GAAG,GAAG,CAAC;QACjB,MAAM,QAAQ,GAAG,MAAM,6BAA6B,CAAC;YACnD,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,EAAE,EAAE;YACtD,IAAI,EAAE,CAAC,IAAa,EAAE,UAAmB,EAAE,EAAE;gBAC3C,MAAM,GAAG,UAAU,IAAI,GAAG,CAAC;gBAC3B,OAAO,IAAI,CAAC;YACd,CAAC;SACK,EAAE,OAAO,CAAC,SAAS,CAAQ,CAAC;QAEpC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC;YACnC,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,mBAAmB;SAC1B,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,OAAO,GAAG,yBAAyB,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,8BAA8B,CAAC;YACnC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC;YAC5B,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,IAAI,EAAoB,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;SAC9E,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,CAAC,CAAC;QAEpD,MAAM,QAAQ,GAAG,MAAM;aACpB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC;aACrC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC7B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,KAAK,mBAAmB,CACxD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,18 +1,36 @@
|
|
|
1
|
-
import { type RunToolMiddleware, type RuntimeGuardrailContext } from "@polpo-ai/core";
|
|
1
|
+
import { type ToolExecutionReceiptStore, type ToolProgressDecision, type RunToolMiddleware, type RuntimeGuardrailContext } from "@polpo-ai/core";
|
|
2
2
|
export interface CompletionToolExecutionOptions {
|
|
3
3
|
readonly callId?: string;
|
|
4
4
|
readonly signal?: AbortSignal;
|
|
5
5
|
}
|
|
6
6
|
export type CompletionToolExecutor = (name: string, args: Record<string, unknown>, options?: CompletionToolExecutionOptions) => Promise<string>;
|
|
7
|
+
export interface CompletionToolProgressStall {
|
|
8
|
+
readonly code: "tool_loop_stalled";
|
|
9
|
+
readonly toolName: string;
|
|
10
|
+
readonly fingerprint: string;
|
|
11
|
+
readonly observation: number;
|
|
12
|
+
readonly message: string;
|
|
13
|
+
}
|
|
14
|
+
/** Mutable request/run-local signal shared with the owning surface controller. */
|
|
15
|
+
export interface CompletionToolProgressState {
|
|
16
|
+
stalled?: CompletionToolProgressStall;
|
|
17
|
+
}
|
|
7
18
|
/**
|
|
8
19
|
* Adapts the shared host-neutral middleware to the completion route's legacy
|
|
9
|
-
* executor contract.
|
|
10
|
-
*
|
|
20
|
+
* executor contract. Canonical schema validation is unconditional and runs
|
|
21
|
+
* again after a middleware rewrite, immediately before the real executor.
|
|
11
22
|
*/
|
|
12
23
|
export declare function createGuardedCompletionToolExecutor(options: {
|
|
13
24
|
readonly executor: CompletionToolExecutor;
|
|
14
25
|
readonly tools: readonly any[];
|
|
15
26
|
readonly middleware?: RunToolMiddleware;
|
|
16
27
|
readonly context: RuntimeGuardrailContext;
|
|
28
|
+
/** Durable hosts may inject a store shared across resume/retry boundaries. */
|
|
29
|
+
readonly receiptStore?: ToolExecutionReceiptStore;
|
|
30
|
+
readonly onProgress?: (input: {
|
|
31
|
+
name: string;
|
|
32
|
+
args: Readonly<Record<string, unknown>>;
|
|
33
|
+
decision: ToolProgressDecision;
|
|
34
|
+
}) => void;
|
|
17
35
|
}): CompletionToolExecutor;
|
|
18
36
|
//# sourceMappingURL=tool-guardrails.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-guardrails.d.ts","sourceRoot":"","sources":["../../../src/routes/completions/tool-guardrails.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"tool-guardrails.d.ts","sourceRoot":"","sources":["../../../src/routes/completions/tool-guardrails.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC7B,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,8BAA8B,KACrC,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,kFAAkF;AAClF,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,EAAE,2BAA2B,CAAC;CACvC;AAcD;;;;GAIG;AACH,wBAAgB,mCAAmC,CAAC,OAAO,EAAE;IAC3D,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,EAAE,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAC1C,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,CAAC,EAAE,yBAAyB,CAAC;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QAC5B,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACxC,QAAQ,EAAE,oBAAoB,CAAC;KAChC,KAAK,IAAI,CAAC;CACZ,GAAG,sBAAsB,CAqHzB"}
|
|
@@ -1,31 +1,112 @@
|
|
|
1
|
-
import { inferToolSideEffect, } from "@polpo-ai/core";
|
|
2
|
-
|
|
1
|
+
import { InMemoryToolExecutionReceiptStore, admitCanonicalToolContract, inferToolSideEffect, toolArgumentsFingerprint, ToolProgressTracker, } from "@polpo-ai/core";
|
|
2
|
+
import { validateToolInput } from "@polpo-ai/llm";
|
|
3
|
+
function toolContractMap(tools) {
|
|
3
4
|
return new Map(tools
|
|
4
5
|
.filter((tool) => tool && typeof tool.name === "string")
|
|
5
|
-
.map((tool) => [tool.name, tool
|
|
6
|
+
.map((tool) => [tool.name, admitCanonicalToolContract(tool)]));
|
|
7
|
+
}
|
|
8
|
+
function invalidToolArguments(error) {
|
|
9
|
+
return `Error: Invalid tool arguments: ${error.message}`;
|
|
6
10
|
}
|
|
7
11
|
/**
|
|
8
12
|
* Adapts the shared host-neutral middleware to the completion route's legacy
|
|
9
|
-
* executor contract.
|
|
10
|
-
*
|
|
13
|
+
* executor contract. Canonical schema validation is unconditional and runs
|
|
14
|
+
* again after a middleware rewrite, immediately before the real executor.
|
|
11
15
|
*/
|
|
12
16
|
export function createGuardedCompletionToolExecutor(options) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
17
|
+
const contracts = toolContractMap(options.tools);
|
|
18
|
+
const annotations = new Map([...contracts].map(([name, contract]) => [name, contract.annotations]));
|
|
19
|
+
const progressTracker = new ToolProgressTracker();
|
|
20
|
+
const receiptStore = options.receiptStore ?? new InMemoryToolExecutionReceiptStore();
|
|
16
21
|
return async (name, args, execution) => {
|
|
22
|
+
if (!contracts.has(name)) {
|
|
23
|
+
return `Error: Tool ${JSON.stringify(name)} is not available for execution.`;
|
|
24
|
+
}
|
|
25
|
+
const schema = contracts.get(name).inputSchema;
|
|
26
|
+
const initialValidation = await validateToolInput(schema, args);
|
|
27
|
+
if (!initialValidation.success) {
|
|
28
|
+
return invalidToolArguments(initialValidation.error);
|
|
29
|
+
}
|
|
30
|
+
const executeValidated = async (request) => {
|
|
31
|
+
if (!contracts.has(request.name)) {
|
|
32
|
+
return `Error: Tool ${JSON.stringify(request.name)} is not available for execution.`;
|
|
33
|
+
}
|
|
34
|
+
const rewrittenValidation = await validateToolInput(contracts.get(request.name).inputSchema, request.args);
|
|
35
|
+
if (!rewrittenValidation.success) {
|
|
36
|
+
return invalidToolArguments(rewrittenValidation.error);
|
|
37
|
+
}
|
|
38
|
+
const validatedArgs = rewrittenValidation.value;
|
|
39
|
+
const progressCall = {
|
|
40
|
+
name: request.name,
|
|
41
|
+
args: validatedArgs,
|
|
42
|
+
annotations: annotations.get(request.name),
|
|
43
|
+
};
|
|
44
|
+
const decision = progressTracker.inspect(progressCall);
|
|
45
|
+
options.onProgress?.({ name: request.name, args: validatedArgs, decision });
|
|
46
|
+
if (decision.action === "reuse")
|
|
47
|
+
return decision.result;
|
|
48
|
+
if (decision.action === "stall")
|
|
49
|
+
return `Error: ${decision.message}`;
|
|
50
|
+
if (request.callId) {
|
|
51
|
+
const claim = await receiptStore.claim({
|
|
52
|
+
callId: request.callId,
|
|
53
|
+
toolName: request.name,
|
|
54
|
+
contractFingerprint: contracts.get(request.name).definitionFingerprint,
|
|
55
|
+
argumentsFingerprint: toolArgumentsFingerprint(request.name, validatedArgs),
|
|
56
|
+
});
|
|
57
|
+
if (claim.action === "replay")
|
|
58
|
+
return claim.result;
|
|
59
|
+
if (claim.action === "reject") {
|
|
60
|
+
return `Error [${claim.code}]: ${claim.message}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
let result;
|
|
64
|
+
try {
|
|
65
|
+
result = await options.executor(request.name, validatedArgs, {
|
|
66
|
+
callId: request.callId,
|
|
67
|
+
signal: request.signal,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (request.callId) {
|
|
72
|
+
await receiptStore.settle({
|
|
73
|
+
callId: request.callId,
|
|
74
|
+
state: "outcome-unknown",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
if (request.callId) {
|
|
80
|
+
await receiptStore.settle({
|
|
81
|
+
callId: request.callId,
|
|
82
|
+
state: result.startsWith("Error:") ? "failed" : "completed",
|
|
83
|
+
result,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
progressTracker.record({
|
|
87
|
+
...progressCall,
|
|
88
|
+
result,
|
|
89
|
+
isError: result.startsWith("Error:"),
|
|
90
|
+
});
|
|
91
|
+
return result;
|
|
92
|
+
};
|
|
93
|
+
if (!options.middleware) {
|
|
94
|
+
return executeValidated({
|
|
95
|
+
name,
|
|
96
|
+
args: initialValidation.value,
|
|
97
|
+
callId: execution?.callId,
|
|
98
|
+
signal: execution?.signal,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
17
101
|
const result = await options.middleware.execute({
|
|
18
102
|
name,
|
|
19
|
-
args,
|
|
103
|
+
args: initialValidation.value,
|
|
20
104
|
callId: execution?.callId,
|
|
21
105
|
signal: execution?.signal,
|
|
22
|
-
schema
|
|
106
|
+
schema,
|
|
23
107
|
sideEffect: inferToolSideEffect(name),
|
|
24
108
|
context: options.context,
|
|
25
|
-
},
|
|
26
|
-
callId: request.callId,
|
|
27
|
-
signal: request.signal,
|
|
28
|
-
}));
|
|
109
|
+
}, executeValidated);
|
|
29
110
|
return result.output;
|
|
30
111
|
};
|
|
31
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-guardrails.js","sourceRoot":"","sources":["../../../src/routes/completions/tool-guardrails.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,
|
|
1
|
+
{"version":3,"file":"tool-guardrails.js","sourceRoot":"","sources":["../../../src/routes/completions/tool-guardrails.ts"],"names":[],"mappings":"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"}
|