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

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 (229) hide show
  1. package/README.md +161 -116
  2. package/README.zh-CN.md +173 -144
  3. package/bin/gotry-booking-copilot.js +53 -0
  4. package/bin/gotry-bootstrap.js +113 -66
  5. package/bin/gotry-inner.js +436 -70
  6. package/bin/gotry-runtime-resolution.d.ts +27 -0
  7. package/bin/gotry-runtime-resolution.js +50 -0
  8. package/bin/gotry.js +1 -1
  9. package/cordis.gotry-patch.yml +5 -1
  10. package/dist/capabilities/agent-reach-deep.js +1 -1
  11. package/dist/capabilities/agent-reach.js +1 -1
  12. package/dist/capabilities/anything.js +1 -1
  13. package/dist/capabilities/artifacts.js +1 -1
  14. package/dist/capabilities/effect.js +1 -1
  15. package/dist/capabilities/fact-log.js +1 -1
  16. package/dist/capabilities/flyai.js +20 -6
  17. package/dist/capabilities/hbcli.js +1 -1
  18. package/dist/capabilities/incident-log.js +1 -1
  19. package/dist/capabilities/model-override.js +18 -0
  20. package/dist/capabilities/opensky.js +1 -1
  21. package/dist/capabilities/resilience.js +1 -1
  22. package/dist/capabilities/session/action-cache.js +1 -1
  23. package/dist/capabilities/session/adapters/ctrip-flight.js +1 -1
  24. package/dist/capabilities/session/adapters/meituan-local.js +1 -1
  25. package/dist/capabilities/session/benchmark.js +1 -1
  26. package/dist/capabilities/session/extension-bridge.js +19 -6
  27. package/dist/capabilities/session/extension-channel.js +3 -3
  28. package/dist/capabilities/session/extension-distribution.js +234 -0
  29. package/dist/capabilities/session/extract.js +1 -1
  30. package/dist/capabilities/session/golden-score.js +92 -0
  31. package/dist/capabilities/session/health-watch.js +1 -1
  32. package/dist/capabilities/session/read-guard.js +1 -1
  33. package/dist/capabilities/session/static-flight-golden.js +137 -0
  34. package/dist/capabilities/session/transport.js +1 -1
  35. package/dist/capabilities/session/wizard.js +21 -251
  36. package/dist/capabilities/session-consent.js +1 -1
  37. package/dist/capabilities/session-login.js +11 -5
  38. package/dist/capabilities/session-search.js +46 -4
  39. package/dist/capabilities/weather.js +168 -46
  40. package/dist/data/session-golden-20.json +25 -0
  41. package/dist/data/sf-golden-manifest.json +102 -0
  42. package/dist/data/sf-static-routes.json +91 -0
  43. package/dist/scripts/action-cache-tests.js +1 -1
  44. package/dist/scripts/agent-planning-budget-e2e.js +227 -0
  45. package/dist/scripts/agent-planning-budget-tests.js +173 -0
  46. package/dist/scripts/agent-reach-deep-tests.js +1 -1
  47. package/dist/scripts/agent-reach-tests.js +1 -1
  48. package/dist/scripts/agent-reach-wrapper-tests.js +1 -1
  49. package/dist/scripts/anything-tests.js +1 -1
  50. package/dist/scripts/async-collect.js +1 -1
  51. package/dist/scripts/benchmark-environment-bridge-e2e.js +981 -0
  52. package/dist/scripts/benchmark-environment-bridge-tests.js +2544 -0
  53. package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +335 -0
  54. package/dist/scripts/booking-copilot-availability-policy-v2-tests.js +1355 -0
  55. package/dist/scripts/booking-copilot-bin-proof-tests.js +89 -0
  56. package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +113 -0
  57. package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +356 -0
  58. package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +557 -0
  59. package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +140 -0
  60. package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +202 -0
  61. package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +102 -0
  62. package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +374 -0
  63. package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +447 -0
  64. package/dist/scripts/booking-copilot-runtime-proof-tests.js +205 -0
  65. package/dist/scripts/booking-copilot-server-proof-tests.js +317 -0
  66. package/dist/scripts/booking-copilot-startup-proof-tests.js +283 -0
  67. package/dist/scripts/booking-copilot-v2-runtime-proof-tests.js +3935 -0
  68. package/dist/scripts/booking-saga-tests.js +1 -1
  69. package/dist/scripts/booking-surface-contract-proof-tests.js +393 -0
  70. package/dist/scripts/booking-surface-v2-contract-proof-tests.js +1174 -0
  71. package/dist/scripts/bootstrap-tests.js +45 -39
  72. package/dist/scripts/build-changelog.js +1 -1
  73. package/dist/scripts/changelog-tests.js +1 -1
  74. package/dist/scripts/companion-tests.js +1 -1
  75. package/dist/scripts/diff-test.js +1 -1
  76. package/dist/scripts/dsh-runtime-closure-tests.js +225 -0
  77. package/dist/scripts/dsh-runtime-closure.js +150 -0
  78. package/dist/scripts/effect-tests.js +1 -1
  79. package/dist/scripts/engine-run.js +1 -1
  80. package/dist/scripts/engine-tests.js +1 -1
  81. package/dist/scripts/evaluation-cadence-tests.js +347 -0
  82. package/dist/scripts/evaluation-contract-tests.js +574 -0
  83. package/dist/scripts/extension-distribution-cli.js +35 -0
  84. package/dist/scripts/extension-distribution-tests.js +341 -0
  85. package/dist/scripts/extension-tests.js +128 -23
  86. package/dist/scripts/fact-gate-tests.js +1 -1
  87. package/dist/scripts/flyai-tests.js +1 -1
  88. package/dist/scripts/hbcli-e2e-tests.js +1 -1
  89. package/dist/scripts/hbcli-tests.js +1 -1
  90. package/dist/scripts/health-watch-cli.js +1 -1
  91. package/dist/scripts/i18n-tests.js +1 -1
  92. package/dist/scripts/incident-tests.js +1 -1
  93. package/dist/scripts/journey-tests.js +1 -1
  94. package/dist/scripts/ledger-tests.js +1 -1
  95. package/dist/scripts/ledger-workflow-crash.js +1 -1
  96. package/dist/scripts/memory-capture-tests.js +1 -1
  97. package/dist/scripts/memory-decay-tests.js +1 -1
  98. package/dist/scripts/memory-metrics.js +1 -1
  99. package/dist/scripts/memory-value-report.js +1 -1
  100. package/dist/scripts/model-override-e2e.js +176 -0
  101. package/dist/scripts/nightly-evidence-tests.js +1 -1
  102. package/dist/scripts/nightly-evidence.js +1 -1
  103. package/dist/scripts/nudge-digest.js +1 -1
  104. package/dist/scripts/onboarding-tests.js +21 -53
  105. package/dist/scripts/opensky-check.js +1 -1
  106. package/dist/scripts/opensky-tests.js +1 -1
  107. package/dist/scripts/pnpm-dsh-closure-proof.js +20 -0
  108. package/dist/scripts/price-drift-tests.js +1 -1
  109. package/dist/scripts/price-drift-watch.js +1 -1
  110. package/dist/scripts/probe-poi-tests.js +1 -1
  111. package/dist/scripts/product-metrics.js +1 -1
  112. package/dist/scripts/publish-preverify.js +40 -4
  113. package/dist/scripts/realtime-pricing-tests.js +1 -1
  114. package/dist/scripts/replay-async.js +1 -1
  115. package/dist/scripts/replay-real.js +1 -1
  116. package/dist/scripts/replay.js +1 -1
  117. package/dist/scripts/session-attach-diagnose.js +1 -1
  118. package/dist/scripts/session-attach-poc.js +1 -1
  119. package/dist/scripts/session-benchmark.js +1 -1
  120. package/dist/scripts/session-extract-tests.js +1 -1
  121. package/dist/scripts/session-login.js +1 -1
  122. package/dist/scripts/session-tests.js +70 -20
  123. package/dist/scripts/sf-live-benchmark.js +338 -0
  124. package/dist/scripts/sf-live-cli-tests.js +21 -0
  125. package/dist/scripts/sf-soft-score-tests.js +108 -0
  126. package/dist/scripts/sf-summary.js +93 -0
  127. package/dist/scripts/skeleton-check.js +1 -1
  128. package/dist/scripts/skeleton-integration-test.js +1 -1
  129. package/dist/scripts/skills-contract-tests.js +1 -1
  130. package/dist/scripts/smoke-session-gate-tests.js +29 -0
  131. package/dist/scripts/smoke.js +79 -33
  132. package/dist/scripts/state-cli-tests.js +1 -1
  133. package/dist/scripts/state-cli.js +1 -1
  134. package/dist/scripts/static-golden-tests.js +299 -0
  135. package/dist/scripts/time-eval-tests.js +1 -1
  136. package/dist/scripts/travel-timeline-tests.js +1 -1
  137. package/dist/scripts/unified-tests.js +1 -1
  138. package/dist/scripts/weather-tests.js +694 -44
  139. package/dist/scripts/z3-race-tests.js +1 -1
  140. package/dist/src/artifact-gate.js +1 -1
  141. package/dist/src/benchmark-agent-conformance.js +370 -0
  142. package/dist/src/benchmark-environment-bridge.js +384 -0
  143. package/dist/src/benchmark-headless-child-diagnostics.js +173 -0
  144. package/dist/src/benchmark-tool-isolation.js +124 -0
  145. package/dist/src/bookable-facts.js +1 -1
  146. package/dist/src/booking-saga.js +1 -1
  147. package/dist/src/booking-surface/availability-policy-v2.js +830 -0
  148. package/dist/src/booking-surface/canonical-schema.js +113 -0
  149. package/dist/src/booking-surface/contracts-v2.js +89 -0
  150. package/dist/src/booking-surface/contracts.js +46 -0
  151. package/dist/src/booking-surface/dsh-planner.js +453 -0
  152. package/dist/src/booking-surface/dsh-plugin.js +93 -0
  153. package/dist/src/booking-surface/error-codes.js +94 -0
  154. package/dist/src/booking-surface/index.js +15 -0
  155. package/dist/src/booking-surface/profile.js +68 -0
  156. package/dist/src/booking-surface/runtime-v2.js +1771 -0
  157. package/dist/src/booking-surface/runtime.js +351 -0
  158. package/dist/src/booking-surface/server-v2.js +334 -0
  159. package/dist/src/booking-surface/server.js +302 -0
  160. package/dist/src/booking-surface/startup.js +159 -0
  161. package/dist/src/booking-surface/validation-v2.js +319 -0
  162. package/dist/src/booking-surface/validation.js +809 -0
  163. package/dist/src/bridge.js +1 -1
  164. package/dist/src/companions.js +1 -1
  165. package/dist/src/contracts.js +1 -1
  166. package/dist/src/dsh-llm.js +1 -1
  167. package/dist/src/engine.js +1 -1
  168. package/dist/src/evaluation-cadence.js +234 -0
  169. package/dist/src/evaluation-contracts.js +906 -0
  170. package/dist/src/i18n.js +1 -1
  171. package/dist/src/index.js +50 -19
  172. package/dist/src/journey.js +1 -1
  173. package/dist/src/loop.js +1 -1
  174. package/dist/src/memory-capture.js +1 -1
  175. package/dist/src/memory-decay.js +1 -1
  176. package/dist/src/memory-utility.js +1 -1
  177. package/dist/src/mock-llm.js +1 -1
  178. package/dist/src/model.js +1 -1
  179. package/dist/src/realtime-pricing.js +1 -1
  180. package/dist/src/slot-spec.js +1 -1
  181. package/dist/src/state-ledger.js +2 -1
  182. package/dist/src/time-anchor.js +1 -1
  183. package/dist/src/tool-budget.js +136 -0
  184. package/dist/src/tool-packet.js +1 -1
  185. package/dist/src/travel-slots.js +1 -1
  186. package/dist/src/travel-timeline.js +1 -1
  187. package/dist/src/unified.js +1 -1
  188. package/dist/src/wish-pool.js +1 -1
  189. package/dist/src/z3-shared.js +1 -1
  190. package/extension/README.md +31 -7
  191. package/package.json +286 -11
  192. package/schemas/booking.surface.v1.schema.json +927 -0
  193. package/schemas/booking.surface.v2.schema.json +61 -0
  194. package/ts/capabilities/flyai.ts +16 -3
  195. package/ts/capabilities/session/extension-bridge.ts +37 -14
  196. package/ts/capabilities/session/extension-channel.ts +6 -3
  197. package/ts/capabilities/session/extension-distribution.ts +264 -0
  198. package/ts/capabilities/session/golden-score.ts +139 -0
  199. package/ts/capabilities/session/health-watch.ts +1 -1
  200. package/ts/capabilities/session/static-flight-golden.ts +209 -0
  201. package/ts/capabilities/session/wizard.ts +34 -176
  202. package/ts/capabilities/session-login.ts +15 -5
  203. package/ts/capabilities/session-search.ts +40 -3
  204. package/ts/capabilities/weather.ts +141 -52
  205. package/ts/package.json +3 -3
  206. package/ts/src/benchmark-agent-conformance.ts +448 -0
  207. package/ts/src/benchmark-environment-bridge.ts +348 -0
  208. package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
  209. package/ts/src/benchmark-tool-isolation.ts +166 -0
  210. package/ts/src/booking-surface/availability-policy-v2.ts +523 -0
  211. package/ts/src/booking-surface/canonical-schema.js +113 -0
  212. package/ts/src/booking-surface/contracts-v2.ts +118 -0
  213. package/ts/src/booking-surface/contracts.ts +380 -0
  214. package/ts/src/booking-surface/dsh-planner.ts +452 -0
  215. package/ts/src/booking-surface/dsh-plugin.js +93 -0
  216. package/ts/src/booking-surface/error-codes.ts +101 -0
  217. package/ts/src/booking-surface/index.ts +12 -0
  218. package/ts/src/booking-surface/profile.ts +42 -0
  219. package/ts/src/booking-surface/runtime-v2.ts +1466 -0
  220. package/ts/src/booking-surface/runtime.ts +483 -0
  221. package/ts/src/booking-surface/server-v2.ts +247 -0
  222. package/ts/src/booking-surface/server.ts +324 -0
  223. package/ts/src/booking-surface/startup.ts +196 -0
  224. package/ts/src/booking-surface/validation-v2.ts +205 -0
  225. package/ts/src/booking-surface/validation.ts +453 -0
  226. package/ts/src/index.ts +64 -11
  227. package/ts/src/state-ledger.ts +1 -0
  228. package/ts/src/tool-budget.ts +165 -0
  229. package/dist/scripts/wizard-bootstrap.js +0 -32
@@ -0,0 +1,384 @@
1
+ import { accessSync, constants, lstatSync, readFileSync, statSync } from 'node:fs';
2
+ import { getuid } from 'node:process';
3
+ import { isAbsolute } from 'node:path';
4
+ import { defineTool } from '@deepseek-ai/dsh-tools';
5
+ import { validateTerminalOutputConfig } from './benchmark-agent-conformance.js';
6
+ const SCHEMA_VERSION = 'gotry_benchmark_environment_bridge_v2';
7
+ const IDENTIFIER = /^[A-Za-z][A-Za-z0-9_.-]*$/;
8
+ const CONFIG_KEYS = [
9
+ 'allowed_tools',
10
+ 'argv_prefix',
11
+ 'cwd',
12
+ 'enabled',
13
+ 'executable',
14
+ 'isolation',
15
+ 'max_output_bytes',
16
+ 'schema_version',
17
+ 'terminal_output',
18
+ 'timeout_ms'
19
+ ];
20
+ const OPTIONAL_CONFIG_KEYS = [
21
+ 'allowed_output_keys'
22
+ ];
23
+ function plainObject(value) {
24
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
25
+ }
26
+ function existingExecutable(value) {
27
+ if (typeof value !== 'string' || !isAbsolute(value)) return false;
28
+ try {
29
+ const stat = statSync(value);
30
+ accessSync(value, constants.X_OK);
31
+ return stat.isFile();
32
+ } catch {
33
+ return false;
34
+ }
35
+ }
36
+ function existingDirectory(value) {
37
+ if (typeof value !== 'string' || !isAbsolute(value)) return false;
38
+ try {
39
+ return statSync(value).isDirectory();
40
+ } catch {
41
+ return false;
42
+ }
43
+ }
44
+ function identifiers(value) {
45
+ return Array.isArray(value) && value.length > 0 && value.length <= 64 && new Set(value).size === value.length && value.every((item)=>typeof item === 'string' && item.length > 0 && IDENTIFIER.test(item));
46
+ }
47
+ function allowedOutputKeys(value, allowedTools) {
48
+ if (!plainObject(value)) return false;
49
+ const keys = Object.keys(value);
50
+ return keys.length > 0 && keys.length <= 64 && keys.every((tool)=>allowedTools.includes(tool) && identifiers(value[tool]));
51
+ }
52
+ function argvPrefix(value) {
53
+ return Array.isArray(value) && value.length > 0 && value.length <= 32 && value.every((item)=>typeof item === 'string' && item.length > 0 && item.length <= 256 && !item.includes('\0') && !item.includes('\r') && !item.includes('\n'));
54
+ }
55
+ function exactIsolation(value) {
56
+ if (!plainObject(value)) return false;
57
+ const keys = Object.keys(value).sort();
58
+ return JSON.stringify(keys) === JSON.stringify([
59
+ 'mode',
60
+ 'network',
61
+ 'writes'
62
+ ]) && value.mode === 'host-enforced' && value.writes === 'forbidden' && value.network === 'denied';
63
+ }
64
+ function validBound(value, maximum) {
65
+ return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= maximum;
66
+ }
67
+ function validate(value) {
68
+ const configKeys = plainObject(value) ? Object.keys(value).sort() : [];
69
+ const baseKeys = [
70
+ ...CONFIG_KEYS
71
+ ].sort();
72
+ const extendedKeys = [
73
+ ...CONFIG_KEYS,
74
+ ...OPTIONAL_CONFIG_KEYS
75
+ ].sort();
76
+ if (!plainObject(value) || ![
77
+ baseKeys,
78
+ extendedKeys
79
+ ].some((keys)=>JSON.stringify(configKeys) === JSON.stringify(keys)) || value.schema_version !== SCHEMA_VERSION || value.enabled !== true || !existingExecutable(value.executable) || !existingDirectory(value.cwd) || !argvPrefix(value.argv_prefix) || !identifiers(value.allowed_tools) || !validBound(value.timeout_ms, 120_000) || !validBound(value.max_output_bytes, 10 * 1024 * 1024) || !validateTerminalOutputConfig(value.terminal_output) || !exactIsolation(value.isolation) || Object.hasOwn(value, 'allowed_output_keys') && !allowedOutputKeys(value.allowed_output_keys, value.allowed_tools)) return false;
80
+ return true;
81
+ }
82
+ export function loadBenchmarkEnvironmentConfig(path) {
83
+ try {
84
+ if (!isAbsolute(path)) return null;
85
+ const metadata = lstatSync(path);
86
+ if (!metadata.isFile() || metadata.isSymbolicLink() || metadata.size > 64 * 1024) return null;
87
+ if (typeof getuid !== 'function' || metadata.uid !== getuid()) return null;
88
+ if ((metadata.mode & 0o022) !== 0) return null;
89
+ const parsed = JSON.parse(readFileSync(path, 'utf8'));
90
+ return validate(parsed) ? parsed : null;
91
+ } catch {
92
+ return null;
93
+ }
94
+ }
95
+ function structuredObject(text) {
96
+ try {
97
+ const parsed = JSON.parse(text.trim());
98
+ return plainObject(parsed) ? parsed : null;
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
103
+ function jsonObject(value) {
104
+ return JSON.parse(JSON.stringify(value));
105
+ }
106
+ const FORBIDDEN_OUTPUT_KEY_FRAGMENTS = [
107
+ 'answer',
108
+ 'expected',
109
+ 'gold',
110
+ 'groundtruth',
111
+ 'hiddenquery',
112
+ 'label',
113
+ 'loadermetadata',
114
+ 'oracle',
115
+ 'reference',
116
+ 'reward',
117
+ 'score'
118
+ ];
119
+ function inspectOutput(value) {
120
+ const pending = [
121
+ {
122
+ value,
123
+ depth: 0
124
+ }
125
+ ];
126
+ let nodes = 0;
127
+ while(pending.length > 0){
128
+ const current = pending.pop();
129
+ if (++nodes > 10_000 || current.depth > 24) return 'structure_limit';
130
+ if (Array.isArray(current.value)) {
131
+ for (const child of current.value)pending.push({
132
+ value: child,
133
+ depth: current.depth + 1
134
+ });
135
+ continue;
136
+ }
137
+ if (!plainObject(current.value)) continue;
138
+ for (const [key, child] of Object.entries(current.value)){
139
+ if (!/^[\x20-\x7E]+$/.test(key)) return 'forbidden_key';
140
+ const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, '');
141
+ if (FORBIDDEN_OUTPUT_KEY_FRAGMENTS.some((fragment)=>normalized.includes(fragment))) return 'forbidden_key';
142
+ pending.push({
143
+ value: child,
144
+ depth: current.depth + 1
145
+ });
146
+ }
147
+ }
148
+ return 'ok';
149
+ }
150
+ function inspectAllowedOutput(value, allowedKeys) {
151
+ const allowed = new Set(allowedKeys);
152
+ const pending = [
153
+ {
154
+ value,
155
+ depth: 0
156
+ }
157
+ ];
158
+ let nodes = 0;
159
+ while(pending.length > 0){
160
+ const current = pending.pop();
161
+ if (++nodes > 10_000 || current.depth > 24) return false;
162
+ if (Array.isArray(current.value)) {
163
+ for (const child of current.value)pending.push({
164
+ value: child,
165
+ depth: current.depth + 1
166
+ });
167
+ continue;
168
+ }
169
+ if (!plainObject(current.value)) continue;
170
+ for (const [key, child] of Object.entries(current.value)){
171
+ if (!allowed.has(key)) return false;
172
+ pending.push({
173
+ value: child,
174
+ depth: current.depth + 1
175
+ });
176
+ }
177
+ }
178
+ return true;
179
+ }
180
+ function serializedArguments(value) {
181
+ const seen = new Set();
182
+ let nodes = 0;
183
+ let keys = 0;
184
+ const inspect = (current, depth)=>{
185
+ if (++nodes > 10_000 || depth > 12) return false;
186
+ if (current && typeof current === 'object') {
187
+ if (seen.has(current)) return false;
188
+ seen.add(current);
189
+ if (Array.isArray(current)) return current.every((item)=>inspect(item, depth + 1));
190
+ return Object.entries(current).every(([key, child])=>{
191
+ if (++keys > 10_000) return false;
192
+ return inspect(key, depth + 1) && inspect(child, depth + 1);
193
+ });
194
+ }
195
+ return true;
196
+ };
197
+ if (!inspect(value, 0)) return {
198
+ reason: 'serialization_limit'
199
+ };
200
+ try {
201
+ const json = JSON.stringify(value);
202
+ if (typeof json !== 'string' || Buffer.byteLength(json, 'utf8') > 65_536) return {
203
+ reason: 'serialization_limit'
204
+ };
205
+ return {
206
+ json
207
+ };
208
+ } catch {
209
+ return {
210
+ reason: 'serialization_limit'
211
+ };
212
+ }
213
+ }
214
+ export function registerBenchmarkEnvironmentBridge(path, register, subprocess) {
215
+ const bridge = loadBenchmarkEnvironmentConfig(path);
216
+ if (!bridge) throw new Error('benchmark environment bridge configuration unavailable');
217
+ if (!subprocess) throw new Error('benchmark environment bridge subprocess unavailable');
218
+ register(defineTool({
219
+ name: 'gotry_benchmark_environment',
220
+ description: 'When a prompt asks to run agent_env.cli, use action=call here with the mapped tool; arbitrary shell is not exposed.',
221
+ parameters: {
222
+ query: {
223
+ type: 'json',
224
+ required: true,
225
+ description: '{ action: "tools" | "call", tool?: string, arguments?: object }'
226
+ }
227
+ },
228
+ output: {
229
+ schema: {
230
+ type: 'json'
231
+ },
232
+ render: (_args, value)=>[
233
+ {
234
+ type: 'text',
235
+ text: JSON.stringify(value)
236
+ }
237
+ ]
238
+ },
239
+ async execute (args) {
240
+ const query = plainObject(args?.query) ? args.query : {};
241
+ if (query.action === 'tools') return jsonObject({
242
+ ok: true,
243
+ tools: bridge.allowed_tools
244
+ });
245
+ if (query.action !== 'call') return jsonObject({
246
+ ok: false,
247
+ error: 'invalid_action'
248
+ });
249
+ if (typeof query.tool !== 'string' || !bridge.allowed_tools.includes(query.tool)) {
250
+ return jsonObject({
251
+ ok: false,
252
+ error: 'disallowed_tool'
253
+ });
254
+ }
255
+ if (query.arguments !== undefined && !plainObject(query.arguments)) {
256
+ return jsonObject({
257
+ ok: false,
258
+ error: 'invalid_arguments'
259
+ });
260
+ }
261
+ const callArguments = query.arguments === undefined ? {} : query.arguments;
262
+ const serialized = serializedArguments(callArguments);
263
+ if (serialized.reason) return jsonObject({
264
+ ok: false,
265
+ error: 'invalid_arguments',
266
+ reason: serialized.reason
267
+ });
268
+ const controller = new AbortController();
269
+ const timer = setTimeout(()=>{
270
+ controller.abort();
271
+ }, bridge.timeout_ms);
272
+ let handle;
273
+ try {
274
+ const env = Object.fromEntries(Object.keys(process.env).map((key)=>[
275
+ key,
276
+ undefined
277
+ ]));
278
+ for (const key of [
279
+ 'PATH',
280
+ 'LANG',
281
+ 'LC_ALL',
282
+ 'LC_CTYPE',
283
+ 'TZ'
284
+ ]){
285
+ if (process.env[key] !== undefined) env[key] = process.env[key];
286
+ }
287
+ env.PYTHONDONTWRITEBYTECODE = '1';
288
+ env.PYTHONNOUSERSITE = '1';
289
+ handle = subprocess.spawn({
290
+ argv: [
291
+ bridge.executable,
292
+ ...bridge.argv_prefix,
293
+ 'call',
294
+ query.tool,
295
+ serialized.json
296
+ ],
297
+ cwd: bridge.cwd,
298
+ stdio: {
299
+ stdin: 'ignore',
300
+ stdout: {
301
+ maxBytes: bridge.max_output_bytes
302
+ },
303
+ stderr: {
304
+ maxBytes: bridge.max_output_bytes
305
+ }
306
+ },
307
+ graceMs: Math.min(1_000, bridge.timeout_ms),
308
+ env,
309
+ signal: controller.signal
310
+ });
311
+ const status = await handle.done;
312
+ if (controller.signal.aborted) return jsonObject({
313
+ ok: false,
314
+ error: 'timed_out'
315
+ });
316
+ const stdout = handle.collected.stdout.readFrom(0);
317
+ const stderr = handle.collected.stderr.readFrom(0);
318
+ if (stdout.lossy || stderr.lossy) return jsonObject({
319
+ ok: false,
320
+ error: 'output_truncated'
321
+ });
322
+ if (status.exitCode !== 0) {
323
+ return jsonObject({
324
+ ok: false,
325
+ error: 'runner_failed',
326
+ exit_code: status.exitCode,
327
+ signal: status.signal ?? null
328
+ });
329
+ }
330
+ const parsed = structuredObject(stdout.text);
331
+ if (!parsed) return jsonObject({
332
+ ok: false,
333
+ error: 'invalid_json'
334
+ });
335
+ const outputInspection = inspectOutput(parsed);
336
+ if (outputInspection === 'forbidden_key') return jsonObject({
337
+ ok: false,
338
+ error: 'forbidden_output'
339
+ });
340
+ if (outputInspection === 'structure_limit') return jsonObject({
341
+ ok: false,
342
+ error: 'invalid_output'
343
+ });
344
+ const visibleResult = parsed.result ?? parsed;
345
+ if (!plainObject(visibleResult) && !Array.isArray(visibleResult)) return jsonObject({
346
+ ok: false,
347
+ error: 'invalid_output'
348
+ });
349
+ const outputKeys = bridge.allowed_output_keys && Object.hasOwn(bridge.allowed_output_keys, query.tool) ? bridge.allowed_output_keys[query.tool] : undefined;
350
+ if (outputKeys && !inspectAllowedOutput(visibleResult, outputKeys)) return jsonObject({
351
+ ok: false,
352
+ error: 'forbidden_output'
353
+ });
354
+ return jsonObject({
355
+ ok: true,
356
+ result: visibleResult
357
+ });
358
+ } catch {
359
+ if (controller.signal.aborted) return jsonObject({
360
+ ok: false,
361
+ error: 'timed_out'
362
+ });
363
+ return jsonObject({
364
+ ok: false,
365
+ error: !handle || handle.pid === -1 ? 'spawn_failed' : 'runner_failed'
366
+ });
367
+ } finally{
368
+ clearTimeout(timer);
369
+ }
370
+ }
371
+ }));
372
+ return Object.freeze({
373
+ toolName: 'gotry_benchmark_environment',
374
+ allowedTools: Object.freeze([
375
+ ...bridge.allowed_tools
376
+ ]),
377
+ terminal: Object.freeze({
378
+ ...bridge.terminal_output
379
+ })
380
+ });
381
+ }
382
+
383
+
384
+ //# sourceURL=ts/src/benchmark-environment-bridge.ts
@@ -0,0 +1,173 @@
1
+ import { writeSync } from 'node:fs';
2
+ export const BENCHMARK_CHILD_DIAGNOSTIC_SCHEMA = 'gotry_benchmark_child_diagnostic_v1';
3
+ export const BENCHMARK_CHILD_DIAGNOSTIC_FD_ENV = 'GOTRY_BENCHMARK_DIAGNOSTIC_FD';
4
+ export const BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES = 4 * 1024;
5
+ const FAILURE_CODES = new Set([
6
+ 'child_output_truncated',
7
+ 'child_signaled',
8
+ 'child_lifecycle_failure',
9
+ 'child_conformance_failure',
10
+ 'child_bridge_timed_out',
11
+ 'child_bridge_runner_failed',
12
+ 'child_bridge_spawn_failed',
13
+ 'child_bridge_output_truncated',
14
+ 'child_bridge_failure',
15
+ 'child_terminal_invalid',
16
+ 'child_nonzero_exit',
17
+ 'child_spawn_failure',
18
+ 'child_model_auth',
19
+ 'child_model_capacity',
20
+ 'child_model_server',
21
+ 'child_model_transport',
22
+ 'child_model_stream',
23
+ 'child_model_request',
24
+ 'child_runtime_error',
25
+ 'child_blocked',
26
+ 'child_max_tokens',
27
+ 'child_aborted',
28
+ 'child_interrupted'
29
+ ]);
30
+ const MODEL_AUTH = new Set([
31
+ 'AUTH',
32
+ 'INVALID_CREDENTIAL',
33
+ 'MISSING_CREDENTIAL'
34
+ ]);
35
+ const MODEL_CAPACITY = new Set([
36
+ 'QUOTA',
37
+ 'RATE_LIMIT'
38
+ ]);
39
+ const MODEL_SERVER = new Set([
40
+ 'SERVER'
41
+ ]);
42
+ const MODEL_TRANSPORT = new Set([
43
+ 'TRANSPORT',
44
+ 'TIMEOUT'
45
+ ]);
46
+ const MODEL_STREAM = new Set([
47
+ 'EMPTY_RESPONSE',
48
+ 'STREAM_CLOSED',
49
+ 'MALFORMED_RESPONSE',
50
+ 'INVALID_RESPONSE'
51
+ ]);
52
+ const MODEL_REQUEST = new Set([
53
+ 'INVALID_REQUEST',
54
+ 'CONTEXT_WINDOW_EXCEEDED',
55
+ 'NO_ADAPTER',
56
+ 'UNKNOWN_MODEL',
57
+ 'UNSUPPORTED_OPTION'
58
+ ]);
59
+ export function classifyBenchmarkTurnEnd(reason) {
60
+ if (!plainObject(reason) || typeof reason.kind !== 'string') return 'child_runtime_error';
61
+ switch(reason.kind){
62
+ case 'completed':
63
+ return undefined;
64
+ case 'blocked':
65
+ return 'child_blocked';
66
+ case 'max-tokens':
67
+ return 'child_max_tokens';
68
+ case 'aborted':
69
+ return 'child_aborted';
70
+ case 'interrupted':
71
+ return 'child_interrupted';
72
+ case 'error':
73
+ {
74
+ const error = plainObject(reason.error) ? reason.error : {};
75
+ const code = typeof error.code === 'string' ? error.code : '';
76
+ const status = typeof error.status === 'number' && Number.isInteger(error.status) && error.status >= 100 && error.status <= 599 ? error.status : undefined;
77
+ if (MODEL_AUTH.has(code)) return 'child_model_auth';
78
+ if (MODEL_CAPACITY.has(code)) return 'child_model_capacity';
79
+ if (MODEL_SERVER.has(code)) return 'child_model_server';
80
+ if (MODEL_TRANSPORT.has(code)) return 'child_model_transport';
81
+ if (MODEL_STREAM.has(code)) return 'child_model_stream';
82
+ if (MODEL_REQUEST.has(code)) return 'child_model_request';
83
+ if (code === 'ABORTED') return 'child_aborted';
84
+ if (status === 401 || status === 403) return 'child_model_auth';
85
+ if (status === 429) return 'child_model_capacity';
86
+ if (status !== undefined && status >= 500 && status <= 599) return 'child_model_server';
87
+ return 'child_runtime_error';
88
+ }
89
+ default:
90
+ return 'child_runtime_error';
91
+ }
92
+ }
93
+ export function createBenchmarkDiagnosticArbiter(write) {
94
+ const pending = new Map();
95
+ const emitted = new Set();
96
+ const rank = (code)=>code.startsWith('child_bridge_') ? 4 : code === 'child_conformance_failure' ? 3 : code === 'child_runtime_error' ? 1 : 2;
97
+ return {
98
+ offer (session, code) {
99
+ if (code === undefined || emitted.has(session)) return;
100
+ const previous = pending.get(session);
101
+ if (previous === undefined || rank(code) > rank(previous)) pending.set(session, code);
102
+ },
103
+ flush (session) {
104
+ if (emitted.has(session)) return;
105
+ const code = pending.get(session);
106
+ if (code === undefined) return;
107
+ emitted.add(session);
108
+ pending.delete(session);
109
+ write(code);
110
+ }
111
+ };
112
+ }
113
+ function plainObject(value) {
114
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
115
+ }
116
+ export function appendBoundedChildDiagnostic(current, chunk) {
117
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
118
+ if (bytes.length >= BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES) {
119
+ return bytes.subarray(bytes.length - BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES);
120
+ }
121
+ if (current.length + bytes.length <= BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES) {
122
+ return Buffer.concat([
123
+ current,
124
+ bytes
125
+ ]);
126
+ }
127
+ const keep = BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES - bytes.length;
128
+ return Buffer.concat([
129
+ current.subarray(current.length - keep),
130
+ bytes
131
+ ]);
132
+ }
133
+ export function parseBenchmarkChildDiagnostic(raw) {
134
+ const lines = raw.split('\n').map((line)=>line.trim()).filter(Boolean);
135
+ for(let index = lines.length - 1; index >= 0; index -= 1){
136
+ try {
137
+ const parsed = JSON.parse(lines[index]);
138
+ if (!plainObject(parsed)) continue;
139
+ const keys = Object.keys(parsed).sort();
140
+ if (JSON.stringify(keys) !== JSON.stringify([
141
+ 'code',
142
+ 'schema_version'
143
+ ])) continue;
144
+ if (parsed.schema_version !== BENCHMARK_CHILD_DIAGNOSTIC_SCHEMA) continue;
145
+ if (typeof parsed.code !== 'string' || !FAILURE_CODES.has(parsed.code)) continue;
146
+ return parsed.code;
147
+ } catch {}
148
+ }
149
+ return undefined;
150
+ }
151
+ export function emitBenchmarkChildDiagnostic(code) {
152
+ const fd = Number(process.env[BENCHMARK_CHILD_DIAGNOSTIC_FD_ENV]);
153
+ if (!Number.isInteger(fd) || fd < 3) return;
154
+ const record = `\n${JSON.stringify({
155
+ schema_version: BENCHMARK_CHILD_DIAGNOSTIC_SCHEMA,
156
+ code
157
+ })}\n`;
158
+ if (Buffer.byteLength(record, 'utf8') > BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES) return;
159
+ try {
160
+ writeSync(fd, record);
161
+ } catch {}
162
+ }
163
+ export function classifyBenchmarkChildFailure(input) {
164
+ if (input.outputTruncated) return 'child_output_truncated';
165
+ if (input.signal) return 'child_signaled';
166
+ const structured = parseBenchmarkChildDiagnostic(input.diagnostic ?? '');
167
+ if (structured) return structured;
168
+ if (input.code !== 0) return 'child_nonzero_exit';
169
+ return 'child_lifecycle_failure';
170
+ }
171
+
172
+
173
+ //# sourceURL=ts/src/benchmark-headless-child-diagnostics.ts
@@ -0,0 +1,124 @@
1
+ import { isDeepStrictEqual } from 'node:util';
2
+ const BRIDGE_TOOL = 'gotry_benchmark_environment';
3
+ const DENIED = 'BENCHMARK_TOOL_NOT_ALLOWED';
4
+ const SURFACE_VIOLATION = 'BENCHMARK_TOOL_SURFACE_VIOLATION';
5
+ function requireDisposer(value, capability) {
6
+ if (typeof value !== 'function') throw new Error(`benchmark environment ${capability} disposer unavailable`);
7
+ return value;
8
+ }
9
+ export function installBenchmarkToolIsolation(ctx) {
10
+ const rootTools = ctx.tools;
11
+ if (typeof rootTools.get !== 'function') throw new Error('benchmark environment root tool lookup unavailable');
12
+ if (typeof rootTools.schemas !== 'function') throw new Error('benchmark environment root tool schemas unavailable');
13
+ const bridgeDefinition = rootTools.get(BRIDGE_TOOL);
14
+ if (!bridgeDefinition) throw new Error('benchmark environment bridge definition unavailable');
15
+ const rootSchemas = rootTools.schemas();
16
+ const expected = Array.isArray(rootSchemas) ? rootSchemas.filter((schema)=>schema && typeof schema === 'object' && schema.name === BRIDGE_TOOL) : [];
17
+ if (expected.length !== 1) throw new Error('benchmark environment bridge schema unavailable');
18
+ const expectedSchemas = structuredClone(expected);
19
+ const getService = ctx.get;
20
+ const agents = typeof getService === 'function' ? getService.call(ctx, 'agents') : ctx.agents;
21
+ const listAgents = agents?.list;
22
+ if (typeof listAgents !== 'function') throw new Error('benchmark environment agent registry unavailable');
23
+ if (listAgents.call(agents).length > 0) throw new Error('benchmark environment isolation requires cold-start; live agents are not allowed');
24
+ const bus = ctx;
25
+ if (typeof bus.on !== 'function') throw new Error('benchmark environment isolation event bus unavailable');
26
+ if (typeof bus.effect !== 'function') throw new Error('benchmark environment isolation effect unavailable');
27
+ const active = new Map();
28
+ let stopping = false;
29
+ const assertSurface = (agent, schemas = rootTools.schemas(agent))=>{
30
+ if (!active.has(agent) || rootTools.get(BRIDGE_TOOL, agent) !== bridgeDefinition || !isDeepStrictEqual(schemas, expectedSchemas)) {
31
+ throw new Error(SURFACE_VIOLATION);
32
+ }
33
+ };
34
+ const take = (agent)=>{
35
+ const dispose = active.get(agent);
36
+ if (!dispose) return;
37
+ active.delete(agent);
38
+ return dispose();
39
+ };
40
+ requireDisposer(bus.effect(function*() {
41
+ yield requireDisposer(bus.on('agent/created', (payload)=>{
42
+ if (stopping) throw new Error(SURFACE_VIOLATION);
43
+ const agent = payload.agent;
44
+ const tools = agent?.ctx?.tools;
45
+ const agentEffect = agent?.ctx?.effect;
46
+ const agentOn = agent?.ctx?.on;
47
+ if (!agent) throw new Error('benchmark environment created agent unavailable');
48
+ if (typeof tools?.restrict !== 'function') throw new Error('benchmark environment scoped restrict unavailable');
49
+ if (typeof tools.guard !== 'function') throw new Error('benchmark environment scoped guard unavailable');
50
+ if (typeof tools.presentAs !== 'function') throw new Error('benchmark environment scoped presentAs unavailable');
51
+ if (typeof agentEffect !== 'function') throw new Error('benchmark environment scoped effect unavailable');
52
+ if (typeof agentOn !== 'function') throw new Error('benchmark environment scoped event bus unavailable');
53
+ if (active.has(agent)) throw new Error('benchmark environment duplicate agent isolation');
54
+ let owned;
55
+ owned = requireDisposer(agentEffect.call(agent.ctx, function*() {
56
+ yield ()=>{
57
+ if (active.get(agent) === owned) active.delete(agent);
58
+ };
59
+ yield requireDisposer(tools.guard((execution)=>{
60
+ if (stopping || execution.name !== BRIDGE_TOOL || !execution.agent) return DENIED;
61
+ return rootTools.get(BRIDGE_TOOL, execution.agent) === bridgeDefinition ? undefined : DENIED;
62
+ }), 'scoped guard');
63
+ yield requireDisposer(agentOn.call(agent.ctx, 'system-prompt/assemble', async (_assembly, _context, next)=>{
64
+ if (stopping) throw new Error(SURFACE_VIOLATION);
65
+ if (typeof next !== 'function') throw new Error('benchmark environment scoped assembly continuation unavailable');
66
+ const result = await next();
67
+ if (stopping) throw new Error(SURFACE_VIOLATION);
68
+ return result;
69
+ }, {
70
+ prepend: true
71
+ }), 'scoped assembly listener');
72
+ yield requireDisposer(tools.presentAs('native'), 'scoped presentAs');
73
+ yield requireDisposer(tools.restrict({
74
+ allow: [
75
+ BRIDGE_TOOL
76
+ ]
77
+ }), 'scoped restrict');
78
+ }, 'benchmark-environment-agent-tool-isolation'), 'scoped effect');
79
+ active.set(agent, owned);
80
+ try {
81
+ assertSurface(agent);
82
+ } catch (error) {
83
+ try {
84
+ const pending = take(agent);
85
+ pending?.catch(()=>undefined);
86
+ } catch {}
87
+ throw error;
88
+ }
89
+ }), 'agent/created listener');
90
+ yield requireDisposer(bus.on('agent/disposed', (payload)=>{
91
+ if (payload.agent) return take(payload.agent);
92
+ }), 'agent/disposed listener');
93
+ yield requireDisposer(bus.on('system-prompt/assemble', async (_assembly, context, next)=>{
94
+ if (typeof next !== 'function') throw new Error('benchmark environment assembly continuation unavailable');
95
+ const result = await next();
96
+ const agent = context?.agent;
97
+ if (!agent) return result;
98
+ if (stopping || context?.scope !== agent || !result || typeof result !== 'object') throw new Error(SURFACE_VIOLATION);
99
+ assertSurface(agent, result.tools);
100
+ return result;
101
+ }, {
102
+ prepend: true
103
+ }), 'system-prompt/assemble listener');
104
+ yield requireDisposer(bus.on('agent/pre-step', async (payload, next)=>{
105
+ if (typeof next !== 'function') throw new Error('benchmark environment pre-step continuation unavailable');
106
+ const decision = await next();
107
+ const agent = payload.agent;
108
+ if (stopping || !agent) throw new Error(SURFACE_VIOLATION);
109
+ assertSurface(agent);
110
+ return decision;
111
+ }, {
112
+ prepend: true
113
+ }), 'agent/pre-step listener');
114
+ yield ()=>{
115
+ active.clear();
116
+ };
117
+ yield ()=>{
118
+ stopping = true;
119
+ };
120
+ }, 'benchmark-environment-tool-isolation'), 'root effect');
121
+ }
122
+
123
+
124
+ //# sourceURL=ts/src/benchmark-tool-isolation.ts
@@ -346,4 +346,4 @@ export function renderNightsLine(it) {
346
346
  }
347
347
 
348
348
 
349
- //# sourceURL=/Users/bytedance/work/gotry-publish/ts/src/bookable-facts.ts
349
+ //# sourceURL=ts/src/bookable-facts.ts