@danceiny/gotry 0.0.1-rc.17 → 0.0.1-rc.19
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/README.md +185 -148
- package/README.zh-CN.md +195 -154
- package/bin/gotry-bootstrap.js +246 -26
- package/bin/gotry-inner.js +68 -38
- package/bin/gotry-runtime-resolution.d.ts +1 -1
- package/bin/gotry-runtime-resolution.js +7 -8
- package/cordis.gotry-patch.yml +15 -5
- package/data/stations-12306-verify.json +524 -0
- package/dist/capabilities/agent-reach.js +4 -4
- package/dist/capabilities/channel-health.js +103 -0
- package/dist/capabilities/channel-registry.js +213 -0
- package/dist/capabilities/doctor.js +285 -0
- package/dist/capabilities/effect.js +178 -5
- package/dist/capabilities/flyai.js +13 -0
- package/dist/capabilities/session/adapters/ctrip-hotel.js +207 -0
- package/dist/capabilities/session/adapters/rail-12306.js +285 -0
- package/dist/capabilities/session/extension-bridge.js +14 -1
- package/dist/capabilities/session/extension-channel.js +4 -2
- package/dist/capabilities/session/extension-distribution.js +1 -1
- package/dist/capabilities/session-search.js +311 -0
- package/dist/capabilities/visa-policy.js +126 -0
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +304 -0
- package/dist/scripts/agent-planning-turn-deadline-tests.js +281 -0
- package/dist/scripts/benchmark-environment-bridge-e2e.js +5 -10
- package/dist/scripts/benchmark-environment-bridge-tests.js +148 -142
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +26 -26
- package/dist/scripts/{booking-copilot-availability-policy-v2-tests.js → booking-copilot-availability-policy-tests.js} +115 -115
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +41 -1
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +75 -120
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +370 -61
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +2 -2
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +7 -3
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +15 -9
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +19 -11
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +16 -52
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +3953 -155
- package/dist/scripts/booking-copilot-server-proof-tests.js +58 -23
- package/dist/scripts/booking-copilot-startup-proof-tests.js +10 -119
- package/dist/scripts/booking-surface-contract-proof-tests.js +1154 -326
- package/dist/scripts/bootstrap-tests.js +115 -44
- package/dist/scripts/build-metrics-report.js +339 -0
- package/dist/scripts/channel-probe-tests.js +148 -0
- package/dist/scripts/channel-probe.js +252 -0
- package/dist/scripts/channel-registry-tests.js +262 -0
- package/dist/scripts/doctor-tests.js +121 -0
- package/dist/scripts/effect-tests.js +274 -1
- package/dist/scripts/extension-tests.js +129 -11
- package/dist/scripts/fact-gate-tests.js +91 -2
- package/dist/scripts/flyai-tests.js +17 -1
- package/dist/scripts/hbcli-e2e-tests.js +1 -3
- package/dist/scripts/metrics-report-tests.js +288 -0
- package/dist/scripts/persona-surface-guard-tests.js +19 -0
- package/dist/scripts/session-tests.js +401 -1
- package/dist/scripts/smoke.js +100 -83
- package/dist/scripts/turn-handoff-collect-tests.js +216 -0
- package/dist/scripts/turn-handoff-collect.js +189 -0
- package/dist/scripts/turn-policy-tests.js +56 -0
- package/dist/scripts/typed-contract-canary.js +261 -0
- package/dist/scripts/visa-policy-tests.js +75 -0
- package/dist/scripts/wish-channel-gate-tests.js +111 -0
- package/dist/src/artifact-gate.js +91 -3
- package/dist/src/benchmark-agent-conformance.js +7 -4
- package/dist/src/benchmark-environment-bridge.js +68 -7
- package/dist/src/bookable-facts.js +62 -3
- package/dist/src/booking-surface/{availability-policy-v2.js → availability-policy.js} +89 -89
- package/dist/src/booking-surface/canonical-schema.js +8 -22
- package/dist/src/booking-surface/contracts.js +70 -19
- package/dist/src/booking-surface/dsh-planner.js +310 -177
- package/dist/src/booking-surface/dsh-plugin.js +3 -3
- package/dist/src/booking-surface/index.js +1 -5
- package/dist/src/booking-surface/profile.js +1 -1
- package/dist/src/booking-surface/runtime.js +1682 -247
- package/dist/src/booking-surface/server.js +371 -185
- package/dist/src/booking-surface/startup.js +17 -27
- package/dist/src/booking-surface/validation.js +270 -760
- package/dist/src/index.js +735 -149
- package/dist/src/turn-deadline.js +292 -0
- package/dist/src/turn-policy.js +146 -0
- package/dist/src/wish-pool.js +5 -0
- package/extension/background.js +23 -4
- package/extension/content-main.js +47 -9
- package/extension/manifest.json +27 -9
- package/package.json +6 -26
- package/schemas/booking.surface.schema.json +2593 -0
- package/ts/capabilities/agent-reach.ts +4 -4
- package/ts/capabilities/flyai.ts +21 -3
- package/ts/capabilities/session/action-cache.ts +1 -1
- package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +293 -0
- package/ts/capabilities/session/extension-bridge.ts +32 -2
- package/ts/capabilities/session/extension-channel.ts +9 -8
- package/ts/capabilities/session/extension-distribution.ts +3 -1
- package/ts/capabilities/session/health-watch.ts +1 -1
- package/ts/capabilities/session/read-guard.ts +1 -1
- package/ts/capabilities/session/wizard.ts +1 -1
- package/ts/capabilities/session-search.ts +323 -1
- package/ts/package.json +1 -0
- package/ts/scripts/turn-handoff-collect.ts +178 -0
- package/ts/src/artifact-gate.ts +82 -2
- package/ts/src/benchmark-agent-conformance.ts +14 -6
- package/ts/src/benchmark-environment-bridge.ts +29 -10
- package/ts/src/bookable-facts.ts +109 -5
- package/ts/src/booking-saga.ts +1 -1
- package/ts/src/booking-surface/{availability-policy-v2.ts → availability-policy.ts} +124 -125
- package/ts/src/booking-surface/canonical-schema.js +8 -22
- package/ts/src/booking-surface/contracts.ts +278 -239
- package/ts/src/booking-surface/dsh-planner.ts +333 -194
- package/ts/src/booking-surface/dsh-plugin.js +3 -3
- package/ts/src/booking-surface/index.ts +1 -5
- package/ts/src/booking-surface/profile.ts +11 -11
- package/ts/src/booking-surface/runtime.ts +1351 -351
- package/ts/src/booking-surface/server.ts +282 -175
- package/ts/src/booking-surface/startup.ts +36 -48
- package/ts/src/booking-surface/validation.ts +194 -442
- package/ts/src/contracts.ts +1 -1
- package/ts/src/index.ts +489 -171
- package/ts/src/loop.ts +1 -1
- package/ts/src/state-ledger.ts +1 -1
- package/ts/src/turn-deadline.ts +361 -0
- package/ts/src/turn-policy.ts +154 -0
- package/ts/src/wish-pool.ts +17 -4
- package/dist/scripts/agent-planning-budget-e2e.js +0 -227
- package/dist/scripts/agent-planning-budget-tests.js +0 -173
- package/dist/scripts/booking-copilot-v2-runtime-proof-tests.js +0 -3935
- package/dist/scripts/booking-surface-v2-contract-proof-tests.js +0 -1174
- package/dist/src/booking-surface/contracts-v2.js +0 -89
- package/dist/src/booking-surface/runtime-v2.js +0 -1771
- package/dist/src/booking-surface/server-v2.js +0 -334
- package/dist/src/booking-surface/validation-v2.js +0 -319
- package/dist/src/tool-budget.js +0 -136
- package/schemas/booking.surface.v1.schema.json +0 -927
- package/schemas/booking.surface.v2.schema.json +0 -61
- package/ts/src/booking-surface/contracts-v2.ts +0 -118
- package/ts/src/booking-surface/runtime-v2.ts +0 -1466
- package/ts/src/booking-surface/server-v2.ts +0 -247
- package/ts/src/booking-surface/validation-v2.ts +0 -205
- package/ts/src/tool-budget.ts +0 -165
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { createServer } from 'node:http';
|
|
3
|
-
import { existsSync, mkdtempSync, rmSync } from 'node:fs';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { spawn } from 'node:child_process';
|
|
7
|
-
const ROOT = join(import.meta.dirname, '..', '..');
|
|
8
|
-
const TIMEOUT_MS = 90_000;
|
|
9
|
-
const TOOL = 'gotry_artifacts_list';
|
|
10
|
-
const EXHAUSTED = 'TOOL_BUDGET_EXHAUSTED';
|
|
11
|
-
function sse(data) {
|
|
12
|
-
return `data: ${JSON.stringify(data)}\n\n`;
|
|
13
|
-
}
|
|
14
|
-
function toolResponse(number) {
|
|
15
|
-
const count = number === 18 ? 2 : 1;
|
|
16
|
-
const calls = Array.from({
|
|
17
|
-
length: count
|
|
18
|
-
}, (_, index)=>({
|
|
19
|
-
index,
|
|
20
|
-
id: `budget-call-${number}-${index + 1}`,
|
|
21
|
-
type: 'function',
|
|
22
|
-
function: {
|
|
23
|
-
name: TOOL,
|
|
24
|
-
arguments: JSON.stringify({
|
|
25
|
-
query: {
|
|
26
|
-
limit: 1
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
}));
|
|
31
|
-
return sse({
|
|
32
|
-
id: `budget-${number}`,
|
|
33
|
-
object: 'chat.completion.chunk',
|
|
34
|
-
created: 1,
|
|
35
|
-
model: 'synthetic-budget-model',
|
|
36
|
-
choices: [
|
|
37
|
-
{
|
|
38
|
-
index: 0,
|
|
39
|
-
delta: {
|
|
40
|
-
role: 'assistant',
|
|
41
|
-
tool_calls: calls
|
|
42
|
-
},
|
|
43
|
-
finish_reason: null
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
}) + sse({
|
|
47
|
-
id: `budget-${number}-finish`,
|
|
48
|
-
object: 'chat.completion.chunk',
|
|
49
|
-
created: 1,
|
|
50
|
-
model: 'synthetic-budget-model',
|
|
51
|
-
choices: [
|
|
52
|
-
{
|
|
53
|
-
index: 0,
|
|
54
|
-
delta: {},
|
|
55
|
-
finish_reason: 'tool_calls'
|
|
56
|
-
}
|
|
57
|
-
]
|
|
58
|
-
}) + 'data: [DONE]\n\n';
|
|
59
|
-
}
|
|
60
|
-
function textResponse(text, id = 'budget-final') {
|
|
61
|
-
return sse({
|
|
62
|
-
id,
|
|
63
|
-
object: 'chat.completion.chunk',
|
|
64
|
-
created: 1,
|
|
65
|
-
model: 'synthetic-budget-model',
|
|
66
|
-
choices: [
|
|
67
|
-
{
|
|
68
|
-
index: 0,
|
|
69
|
-
delta: {
|
|
70
|
-
role: 'assistant',
|
|
71
|
-
content: text
|
|
72
|
-
},
|
|
73
|
-
finish_reason: null
|
|
74
|
-
}
|
|
75
|
-
]
|
|
76
|
-
}) + sse({
|
|
77
|
-
id: `${id}-finish`,
|
|
78
|
-
object: 'chat.completion.chunk',
|
|
79
|
-
created: 1,
|
|
80
|
-
model: 'synthetic-budget-model',
|
|
81
|
-
choices: [
|
|
82
|
-
{
|
|
83
|
-
index: 0,
|
|
84
|
-
delta: {},
|
|
85
|
-
finish_reason: 'stop'
|
|
86
|
-
}
|
|
87
|
-
]
|
|
88
|
-
}) + 'data: [DONE]\n\n';
|
|
89
|
-
}
|
|
90
|
-
async function startRelay() {
|
|
91
|
-
const bodies = [];
|
|
92
|
-
const plannerBodies = [];
|
|
93
|
-
const server = createServer((req, res)=>{
|
|
94
|
-
if (req.method !== 'POST' || !req.url?.endsWith('/chat/completions')) {
|
|
95
|
-
res.writeHead(404).end('not found');
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const chunks = [];
|
|
99
|
-
req.on('data', (chunk)=>chunks.push(Buffer.from(chunk)));
|
|
100
|
-
req.on('end', ()=>{
|
|
101
|
-
let body;
|
|
102
|
-
try {
|
|
103
|
-
body = JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
104
|
-
} catch {
|
|
105
|
-
body = {};
|
|
106
|
-
}
|
|
107
|
-
bodies.push(body);
|
|
108
|
-
res.writeHead(200, {
|
|
109
|
-
'content-type': 'text/event-stream',
|
|
110
|
-
'cache-control': 'no-cache'
|
|
111
|
-
});
|
|
112
|
-
if (toolNames(body).includes(TOOL)) {
|
|
113
|
-
plannerBodies.push(body);
|
|
114
|
-
res.end(toolResponse(plannerBodies.length));
|
|
115
|
-
} else if (plannerBodies.length >= 18) {
|
|
116
|
-
res.end(textResponse('budget E2E final answer'));
|
|
117
|
-
} else {
|
|
118
|
-
res.end(textResponse('budget e2e title', 'budget-auxiliary'));
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
await new Promise((resolve)=>server.listen(0, '127.0.0.1', resolve));
|
|
123
|
-
return {
|
|
124
|
-
port: server.address().port,
|
|
125
|
-
bodies,
|
|
126
|
-
plannerBodies,
|
|
127
|
-
close: ()=>new Promise((resolve)=>server.close(()=>resolve()))
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
function allToolMessages(bodies) {
|
|
131
|
-
return bodies.flatMap((body)=>(body.messages ?? []).filter((message)=>message.role === 'tool'));
|
|
132
|
-
}
|
|
133
|
-
function toolNames(body) {
|
|
134
|
-
return (body.tools ?? []).map((tool)=>{
|
|
135
|
-
const fn = tool.function;
|
|
136
|
-
return String(fn?.name ?? tool.name ?? '');
|
|
137
|
-
}).filter(Boolean);
|
|
138
|
-
}
|
|
139
|
-
async function main() {
|
|
140
|
-
for (const file of [
|
|
141
|
-
'dist/src/index.js',
|
|
142
|
-
'dist/capabilities/artifacts.js'
|
|
143
|
-
]){
|
|
144
|
-
assert.ok(existsSync(join(ROOT, file)), `missing ${file}; run node scripts/build-dist.mjs first`);
|
|
145
|
-
}
|
|
146
|
-
const relay = await startRelay();
|
|
147
|
-
const dshHome = mkdtempSync(join(tmpdir(), 'gotry-budget-dsh-home-'));
|
|
148
|
-
const childCwd = mkdtempSync(join(tmpdir(), 'gotry-budget-cwd-'));
|
|
149
|
-
let exitCode = null;
|
|
150
|
-
let output = '';
|
|
151
|
-
const configuredBin = process.env.GOTRY_BUDGET_E2E_BIN;
|
|
152
|
-
assert.ok(configuredBin && existsSync(configuredBin), 'GOTRY_BUDGET_E2E_BIN must point to the clean installed-package binary');
|
|
153
|
-
try {
|
|
154
|
-
const executable = configuredBin;
|
|
155
|
-
const executableArgs = [
|
|
156
|
-
'exercise the tool budget'
|
|
157
|
-
];
|
|
158
|
-
const childEnv = {
|
|
159
|
-
...process.env
|
|
160
|
-
};
|
|
161
|
-
childEnv.DSH_HOME = dshHome;
|
|
162
|
-
childEnv.LLM_API_KEY = 'synthetic-e2e-key';
|
|
163
|
-
childEnv.LLM_BASE_URL = 'http://127.0.0.1:' + relay.port + '/v1';
|
|
164
|
-
childEnv.LLM_MODEL = 'synthetic-budget-model';
|
|
165
|
-
childEnv.GOTRY_LOCALE = 'zh-CN';
|
|
166
|
-
childEnv.GOTRY_DISABLE_OPTIONAL_CALENDAR = '1';
|
|
167
|
-
delete childEnv.GOTRY_LLM_MODEL;
|
|
168
|
-
const child = spawn(executable, executableArgs, {
|
|
169
|
-
cwd: childCwd,
|
|
170
|
-
env: childEnv,
|
|
171
|
-
stdio: [
|
|
172
|
-
'ignore',
|
|
173
|
-
'pipe',
|
|
174
|
-
'pipe'
|
|
175
|
-
]
|
|
176
|
-
});
|
|
177
|
-
child.stdout.on('data', (chunk)=>{
|
|
178
|
-
output += chunk.toString();
|
|
179
|
-
});
|
|
180
|
-
child.stderr.on('data', (chunk)=>{
|
|
181
|
-
output += chunk.toString();
|
|
182
|
-
});
|
|
183
|
-
exitCode = await new Promise((resolve)=>{
|
|
184
|
-
const timer = setTimeout(()=>{
|
|
185
|
-
child.kill('SIGKILL');
|
|
186
|
-
resolve(null);
|
|
187
|
-
}, TIMEOUT_MS);
|
|
188
|
-
child.once('exit', (code)=>{
|
|
189
|
-
clearTimeout(timer);
|
|
190
|
-
resolve(code);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
} finally{
|
|
194
|
-
await relay.close();
|
|
195
|
-
rmSync(dshHome, {
|
|
196
|
-
recursive: true,
|
|
197
|
-
force: true
|
|
198
|
-
});
|
|
199
|
-
rmSync(childCwd, {
|
|
200
|
-
recursive: true,
|
|
201
|
-
force: true
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
assert.equal(exitCode, 0, `headless exit=${exitCode}; output tail=${output.slice(-1200)}`);
|
|
205
|
-
assert.equal(relay.plannerBodies.length, 18, `expected 18 tool-enabled planner requests, got ${relay.plannerBodies.length}; output tail=${output.slice(-12_000)}`);
|
|
206
|
-
const finalRequest = relay.bodies.at(-1);
|
|
207
|
-
const toolMessages = allToolMessages([
|
|
208
|
-
finalRequest
|
|
209
|
-
]);
|
|
210
|
-
const normalResults = toolMessages.filter((message)=>!JSON.stringify(message).includes(EXHAUSTED));
|
|
211
|
-
const exhaustedResults = toolMessages.filter((message)=>JSON.stringify(message).includes(EXHAUSTED));
|
|
212
|
-
const toolMessageDiagnostic = JSON.stringify(toolMessages).slice(-12_000);
|
|
213
|
-
assert.equal(normalResults.length, 18, `exactly 18 real tool results/body dispatches; messages=${toolMessageDiagnostic}`);
|
|
214
|
-
assert.ok(normalResults.every((message)=>JSON.stringify(message).includes('无在册产物')), `all 18 bodies must return the registered artifact-list result; messages=${toolMessageDiagnostic}`);
|
|
215
|
-
assert.equal(exhaustedResults.length, 1, `19th call returns one structured exhaustion result; messages=${toolMessageDiagnostic}`);
|
|
216
|
-
assert.ok(JSON.stringify(exhaustedResults[0]).includes(EXHAUSTED));
|
|
217
|
-
assert.equal(exhaustedResults[0]?.tool_call_id, 'budget-call-18-2');
|
|
218
|
-
const finalNames = toolNames(finalRequest);
|
|
219
|
-
assert.ok(!finalNames.includes(TOOL), `final request inherited GoTry tool: ${finalNames.join(', ')}`);
|
|
220
|
-
assert.equal(finalNames.length, 0, `final request must be text-only, got ${finalNames.join(', ')}`);
|
|
221
|
-
assert.match(output, /budget E2E final answer/);
|
|
222
|
-
console.log(`agent planning budget E2E: OK (exit=${exitCode}, plannerRequests=${relay.plannerBodies.length}, allModelRequests=${relay.bodies.length}, realToolResults=${normalResults.length}, exhausted=${exhaustedResults.length})`);
|
|
223
|
-
}
|
|
224
|
-
await main();
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
//# sourceURL=ts/scripts/agent-planning-budget-e2e.ts
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import { createToolBudgetState, installToolBudget, TOOL_BUDGET_EXHAUSTED, toolBudgetDecision } from '../src/tool-budget.js';
|
|
3
|
-
const success = ()=>({
|
|
4
|
-
isError: false,
|
|
5
|
-
value: null,
|
|
6
|
-
content: []
|
|
7
|
-
});
|
|
8
|
-
const handlers = new Map();
|
|
9
|
-
const restricted = [];
|
|
10
|
-
const lifted = [];
|
|
11
|
-
const makeAgent = (id)=>({
|
|
12
|
-
id,
|
|
13
|
-
ctx: {
|
|
14
|
-
tools: {
|
|
15
|
-
restrict (filter) {
|
|
16
|
-
restricted.push({
|
|
17
|
-
agentId: id,
|
|
18
|
-
deny: [
|
|
19
|
-
...filter.deny
|
|
20
|
-
]
|
|
21
|
-
});
|
|
22
|
-
return ()=>lifted.push(id);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
const ctx = {
|
|
28
|
-
tools: {
|
|
29
|
-
schemas: ()=>[
|
|
30
|
-
{
|
|
31
|
-
name: 'gotry_alpha'
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
name: 'gotry_beta'
|
|
35
|
-
}
|
|
36
|
-
]
|
|
37
|
-
},
|
|
38
|
-
on (event, listener) {
|
|
39
|
-
const bucket = handlers.get(event) ?? [];
|
|
40
|
-
bucket.push(listener);
|
|
41
|
-
handlers.set(event, bucket);
|
|
42
|
-
return ()=>{};
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
installToolBudget(ctx);
|
|
46
|
-
const execute = handlers.get('tools/execute')?.[0];
|
|
47
|
-
const postExecute = handlers.get('tools/post-execute')?.[0];
|
|
48
|
-
const sessionEvent = handlers.get('session/event')?.[0];
|
|
49
|
-
const sessionDisposed = handlers.get('session/disposed')?.[0];
|
|
50
|
-
assert.ok(execute && postExecute && sessionEvent && sessionDisposed, 'all Cordis budget hooks register');
|
|
51
|
-
assert.deepEqual(toolBudgetDecision(18), {
|
|
52
|
-
kind: 'allow',
|
|
53
|
-
softSignal: false,
|
|
54
|
-
exhaustsBudget: true
|
|
55
|
-
});
|
|
56
|
-
const pureExhausted = toolBudgetDecision(19);
|
|
57
|
-
assert.equal(pureExhausted.kind, 'deny');
|
|
58
|
-
if (pureExhausted.kind === 'deny') assert.match(pureExhausted.reason, /TOOL_BUDGET_EXHAUSTED/);
|
|
59
|
-
const freshState = createToolBudgetState();
|
|
60
|
-
assert.equal(freshState.nextCall().callNumber, 1);
|
|
61
|
-
let directBodies = 0;
|
|
62
|
-
for(let i = 0; i < 25; i++){
|
|
63
|
-
const result = await execute({
|
|
64
|
-
token: Symbol(`direct-${i}`)
|
|
65
|
-
}, async ()=>{
|
|
66
|
-
directBodies++;
|
|
67
|
-
return success();
|
|
68
|
-
});
|
|
69
|
-
assert.equal(result.isError, false);
|
|
70
|
-
}
|
|
71
|
-
assert.equal(directBodies, 25);
|
|
72
|
-
const agent = makeAgent('agent-serial');
|
|
73
|
-
let serialBodies = 0;
|
|
74
|
-
let softSignals = 0;
|
|
75
|
-
for(let attempt = 1; attempt <= 18; attempt++){
|
|
76
|
-
const exec = {
|
|
77
|
-
token: Symbol(`serial-${attempt}`),
|
|
78
|
-
agent
|
|
79
|
-
};
|
|
80
|
-
const result = await execute(exec, async ()=>{
|
|
81
|
-
serialBodies++;
|
|
82
|
-
return success();
|
|
83
|
-
});
|
|
84
|
-
const post = await postExecute(exec, result, async ()=>({
|
|
85
|
-
kind: 'accept'
|
|
86
|
-
}));
|
|
87
|
-
const contextText = post.additionalContexts?.flatMap((item)=>item.content ?? []).map((item)=>item.text ?? '').join('\n') ?? '';
|
|
88
|
-
if (contextText.includes('TOOL_BUDGET_SOFT')) softSignals++;
|
|
89
|
-
}
|
|
90
|
-
assert.equal(serialBodies, 18);
|
|
91
|
-
assert.equal(softSignals, 1);
|
|
92
|
-
assert.equal(restricted.length, 0, 'same-step prepared calls remain resolvable until step/end');
|
|
93
|
-
let nineteenthBodyRan = false;
|
|
94
|
-
const nineteenth = await execute({
|
|
95
|
-
token: Symbol('serial-19'),
|
|
96
|
-
agent
|
|
97
|
-
}, async ()=>{
|
|
98
|
-
nineteenthBodyRan = true;
|
|
99
|
-
return success();
|
|
100
|
-
});
|
|
101
|
-
assert.equal(nineteenthBodyRan, false);
|
|
102
|
-
assert.equal(nineteenth.isError, true);
|
|
103
|
-
assert.deepEqual(nineteenth.error?.info, {
|
|
104
|
-
name: 'ToolBudgetError',
|
|
105
|
-
code: TOOL_BUDGET_EXHAUSTED
|
|
106
|
-
});
|
|
107
|
-
assert.match(nineteenth.content[0]?.text ?? '', /TOOL_BUDGET_EXHAUSTED/);
|
|
108
|
-
assert.match(nineteenth.additionalContexts?.[0]?.content?.[0]?.text ?? '', /Produce the final answer/);
|
|
109
|
-
sessionEvent({
|
|
110
|
-
id: agent.id
|
|
111
|
-
}, {
|
|
112
|
-
type: 'step/end'
|
|
113
|
-
});
|
|
114
|
-
assert.deepEqual(restricted.at(-1), {
|
|
115
|
-
agentId: agent.id,
|
|
116
|
-
deny: [
|
|
117
|
-
'gotry_alpha',
|
|
118
|
-
'gotry_beta'
|
|
119
|
-
]
|
|
120
|
-
});
|
|
121
|
-
sessionEvent({
|
|
122
|
-
id: agent.id
|
|
123
|
-
}, {
|
|
124
|
-
type: 'turn/end'
|
|
125
|
-
});
|
|
126
|
-
assert.equal(lifted.at(-1), agent.id);
|
|
127
|
-
sessionEvent({
|
|
128
|
-
id: agent.id
|
|
129
|
-
}, {
|
|
130
|
-
type: 'turn/start'
|
|
131
|
-
});
|
|
132
|
-
const afterReset = await execute({
|
|
133
|
-
token: Symbol('new-turn-1'),
|
|
134
|
-
agent
|
|
135
|
-
}, async ()=>success());
|
|
136
|
-
assert.equal(afterReset.isError, false);
|
|
137
|
-
const parallelAgent = makeAgent('agent-parallel');
|
|
138
|
-
let parallelBodies = 0;
|
|
139
|
-
const parallelResults = await Promise.all(Array.from({
|
|
140
|
-
length: 19
|
|
141
|
-
}, async (_, index)=>{
|
|
142
|
-
return execute({
|
|
143
|
-
token: Symbol(`parallel-${index + 1}`),
|
|
144
|
-
agent: parallelAgent
|
|
145
|
-
}, async ()=>{
|
|
146
|
-
parallelBodies++;
|
|
147
|
-
await Promise.resolve();
|
|
148
|
-
return success();
|
|
149
|
-
});
|
|
150
|
-
}));
|
|
151
|
-
assert.equal(parallelBodies, 18);
|
|
152
|
-
assert.equal(parallelResults.filter((result)=>result.isError).length, 1);
|
|
153
|
-
assert.equal(parallelResults.find((result)=>result.isError)?.error?.info?.code, TOOL_BUDGET_EXHAUSTED);
|
|
154
|
-
sessionEvent({
|
|
155
|
-
id: parallelAgent.id
|
|
156
|
-
}, {
|
|
157
|
-
type: 'step/end'
|
|
158
|
-
});
|
|
159
|
-
assert.deepEqual(restricted.at(-1), {
|
|
160
|
-
agentId: parallelAgent.id,
|
|
161
|
-
deny: [
|
|
162
|
-
'gotry_alpha',
|
|
163
|
-
'gotry_beta'
|
|
164
|
-
]
|
|
165
|
-
});
|
|
166
|
-
sessionDisposed({
|
|
167
|
-
id: parallelAgent.id
|
|
168
|
-
});
|
|
169
|
-
assert.equal(lifted.at(-1), parallelAgent.id);
|
|
170
|
-
console.log('agent planning tool budget tests: OK (Cordis execute/post/lifecycle/parallel integration)');
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
//# sourceURL=ts/scripts/agent-planning-budget-tests.ts
|