@danceiny/gotry 0.0.1-rc.18 → 0.0.1-rc.20

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.
Files changed (176) hide show
  1. package/README.md +42 -16
  2. package/README.zh-CN.md +37 -15
  3. package/bin/gotry-bootstrap.js +309 -30
  4. package/bin/gotry-inner.js +74 -23
  5. package/bin/gotry-runtime-resolution.d.ts +1 -1
  6. package/bin/gotry-runtime-resolution.js +7 -8
  7. package/cordis.gotry-patch.yml +22 -8
  8. package/data/stations-12306-verify.json +524 -0
  9. package/dist/capabilities/agent-reach.js +4 -4
  10. package/dist/capabilities/anything.js +62 -29
  11. package/dist/capabilities/channel-health.js +103 -0
  12. package/dist/capabilities/channel-registry.js +213 -0
  13. package/dist/capabilities/doctor.js +307 -0
  14. package/dist/capabilities/effect.js +178 -5
  15. package/dist/capabilities/flyai.js +13 -0
  16. package/dist/capabilities/hbcli.js +28 -2
  17. package/dist/capabilities/session/adapters/ctrip-hotel.js +207 -0
  18. package/dist/capabilities/session/adapters/rail-12306.js +285 -0
  19. package/dist/capabilities/session/extension-bridge.js +14 -1
  20. package/dist/capabilities/session/extension-channel.js +4 -2
  21. package/dist/capabilities/session/extension-distribution.js +1 -1
  22. package/dist/capabilities/session-search.js +311 -0
  23. package/dist/capabilities/visa-policy.js +126 -0
  24. package/dist/scripts/agent-planning-turn-deadline-e2e.js +305 -0
  25. package/dist/scripts/agent-planning-turn-deadline-tests.js +281 -0
  26. package/dist/scripts/anything-tests.js +70 -21
  27. package/dist/scripts/benchmark-environment-bridge-e2e.js +139 -37
  28. package/dist/scripts/benchmark-environment-bridge-tests.js +1099 -306
  29. package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +26 -26
  30. package/dist/scripts/{booking-copilot-availability-policy-v2-tests.js → booking-copilot-availability-policy-tests.js} +115 -115
  31. package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +41 -1
  32. package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +75 -120
  33. package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +370 -61
  34. package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +2 -2
  35. package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +7 -3
  36. package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +15 -9
  37. package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +19 -11
  38. package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +16 -52
  39. package/dist/scripts/booking-copilot-runtime-proof-tests.js +3953 -155
  40. package/dist/scripts/booking-copilot-server-proof-tests.js +58 -23
  41. package/dist/scripts/booking-copilot-startup-proof-tests.js +10 -119
  42. package/dist/scripts/booking-surface-contract-proof-tests.js +1154 -326
  43. package/dist/scripts/bootstrap-tests.js +113 -2
  44. package/dist/scripts/build-metrics-report.js +339 -0
  45. package/dist/scripts/channel-probe-tests.js +148 -0
  46. package/dist/scripts/channel-probe.js +252 -0
  47. package/dist/scripts/channel-registry-tests.js +262 -0
  48. package/dist/scripts/doctor-tests.js +175 -0
  49. package/dist/scripts/effect-tests.js +274 -1
  50. package/dist/scripts/extension-tests.js +129 -11
  51. package/dist/scripts/fact-gate-tests.js +91 -2
  52. package/dist/scripts/flyai-tests.js +17 -1
  53. package/dist/scripts/hbcli-e2e-tests.js +1 -3
  54. package/dist/scripts/hbcli-tests.js +38 -1
  55. package/dist/scripts/metrics-report-tests.js +288 -0
  56. package/dist/scripts/persona-surface-guard-tests.js +19 -0
  57. package/dist/scripts/session-tests.js +401 -1
  58. package/dist/scripts/smoke.js +100 -83
  59. package/dist/scripts/turn-handoff-collect-tests.js +216 -0
  60. package/dist/scripts/turn-handoff-collect.js +189 -0
  61. package/dist/scripts/turn-policy-tests.js +56 -0
  62. package/dist/scripts/typed-contract-canary.js +261 -0
  63. package/dist/scripts/visa-policy-tests.js +75 -0
  64. package/dist/scripts/wish-channel-gate-tests.js +111 -0
  65. package/dist/src/artifact-gate.js +91 -3
  66. package/dist/src/benchmark-agent-conformance.js +39 -16
  67. package/dist/src/benchmark-environment-bridge.js +316 -52
  68. package/dist/src/bookable-facts.js +62 -3
  69. package/dist/src/booking-surface/{availability-policy-v2.js → availability-policy.js} +89 -89
  70. package/dist/src/booking-surface/canonical-schema.js +8 -22
  71. package/dist/src/booking-surface/contracts.js +70 -19
  72. package/dist/src/booking-surface/dsh-planner.js +310 -177
  73. package/dist/src/booking-surface/dsh-plugin.js +3 -3
  74. package/dist/src/booking-surface/index.js +1 -5
  75. package/dist/src/booking-surface/profile.js +1 -1
  76. package/dist/src/booking-surface/runtime.js +1682 -247
  77. package/dist/src/booking-surface/server.js +371 -185
  78. package/dist/src/booking-surface/startup.js +17 -27
  79. package/dist/src/booking-surface/validation.js +270 -760
  80. package/dist/src/index.js +739 -150
  81. package/dist/src/turn-deadline.js +292 -0
  82. package/dist/src/turn-policy.js +146 -0
  83. package/dist/src/wish-pool.js +5 -0
  84. package/extension/background.js +23 -4
  85. package/extension/content-main.js +47 -9
  86. package/extension/manifest.json +27 -9
  87. package/package.json +7 -26
  88. package/schemas/booking.surface.schema.json +2593 -0
  89. package/ts/capabilities/agent-reach.ts +4 -4
  90. package/ts/capabilities/anything.ts +89 -38
  91. package/ts/capabilities/flyai.ts +21 -3
  92. package/ts/capabilities/hbcli.ts +53 -4
  93. package/ts/capabilities/session/action-cache.ts +1 -1
  94. package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
  95. package/ts/capabilities/session/adapters/rail-12306.ts +293 -0
  96. package/ts/capabilities/session/extension-bridge.ts +32 -2
  97. package/ts/capabilities/session/extension-channel.ts +9 -8
  98. package/ts/capabilities/session/extension-distribution.ts +3 -1
  99. package/ts/capabilities/session/health-watch.ts +1 -1
  100. package/ts/capabilities/session/read-guard.ts +1 -1
  101. package/ts/capabilities/session/wizard.ts +1 -1
  102. package/ts/capabilities/session-search.ts +323 -1
  103. package/ts/dsh-runtime/vendor/README.md +60 -0
  104. package/ts/dsh-runtime/vendor/dsh-map-tools/LICENSE +21 -0
  105. package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +200 -0
  106. package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +202 -0
  107. package/ts/dsh-runtime/vendor/dsh-map-tools/client/client.js +216 -0
  108. package/ts/dsh-runtime/vendor/dsh-map-tools/cordis.patch.yml +5 -0
  109. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/amap.js +371 -0
  110. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/nominatim.js +63 -0
  111. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/osrm.js +56 -0
  112. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/photon.js +55 -0
  113. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-file.js +87 -0
  114. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-route.js +126 -0
  115. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config.js +16 -0
  116. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/index.js +109 -0
  117. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +27 -0
  118. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/geocode.js +127 -0
  119. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/poi.js +84 -0
  120. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/routes.js +170 -0
  121. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/amap.d.ts +53 -0
  122. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/nominatim.d.ts +17 -0
  123. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/osrm.d.ts +15 -0
  124. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/photon.d.ts +22 -0
  125. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-file.d.ts +33 -0
  126. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-route.d.ts +20 -0
  127. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config.d.ts +23 -0
  128. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/index.d.ts +18 -0
  129. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +14 -0
  130. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/geocode.d.ts +11 -0
  131. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/poi.d.ts +9 -0
  132. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/routes.d.ts +16 -0
  133. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/types.d.ts +55 -0
  134. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types.js +16 -0
  135. package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +91 -0
  136. package/ts/package.json +9 -0
  137. package/ts/scripts/turn-handoff-collect.ts +178 -0
  138. package/ts/src/artifact-gate.ts +82 -2
  139. package/ts/src/benchmark-agent-conformance.ts +54 -15
  140. package/ts/src/benchmark-environment-bridge.ts +234 -46
  141. package/ts/src/bookable-facts.ts +109 -5
  142. package/ts/src/booking-saga.ts +1 -1
  143. package/ts/src/booking-surface/{availability-policy-v2.ts → availability-policy.ts} +124 -125
  144. package/ts/src/booking-surface/canonical-schema.js +8 -22
  145. package/ts/src/booking-surface/contracts.ts +278 -239
  146. package/ts/src/booking-surface/dsh-planner.ts +333 -194
  147. package/ts/src/booking-surface/dsh-plugin.js +3 -3
  148. package/ts/src/booking-surface/index.ts +1 -5
  149. package/ts/src/booking-surface/profile.ts +11 -11
  150. package/ts/src/booking-surface/runtime.ts +1351 -351
  151. package/ts/src/booking-surface/server.ts +282 -175
  152. package/ts/src/booking-surface/startup.ts +36 -48
  153. package/ts/src/booking-surface/validation.ts +194 -442
  154. package/ts/src/contracts.ts +1 -1
  155. package/ts/src/index.ts +492 -172
  156. package/ts/src/loop.ts +1 -1
  157. package/ts/src/state-ledger.ts +1 -1
  158. package/ts/src/turn-deadline.ts +365 -0
  159. package/ts/src/turn-policy.ts +154 -0
  160. package/ts/src/wish-pool.ts +17 -4
  161. package/dist/scripts/agent-planning-budget-e2e.js +0 -227
  162. package/dist/scripts/agent-planning-budget-tests.js +0 -173
  163. package/dist/scripts/booking-copilot-v2-runtime-proof-tests.js +0 -3935
  164. package/dist/scripts/booking-surface-v2-contract-proof-tests.js +0 -1174
  165. package/dist/src/booking-surface/contracts-v2.js +0 -89
  166. package/dist/src/booking-surface/runtime-v2.js +0 -1771
  167. package/dist/src/booking-surface/server-v2.js +0 -334
  168. package/dist/src/booking-surface/validation-v2.js +0 -319
  169. package/dist/src/tool-budget.js +0 -136
  170. package/schemas/booking.surface.v1.schema.json +0 -927
  171. package/schemas/booking.surface.v2.schema.json +0 -61
  172. package/ts/src/booking-surface/contracts-v2.ts +0 -118
  173. package/ts/src/booking-surface/runtime-v2.ts +0 -1466
  174. package/ts/src/booking-surface/server-v2.ts +0 -247
  175. package/ts/src/booking-surface/validation-v2.ts +0 -205
  176. 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