@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
|
@@ -314,6 +314,30 @@ for (const invalid of [
|
|
|
314
314
|
'<done>{"ok":</done>'
|
|
315
315
|
])assert.equal(parseBenchmarkTerminal(invalid, projection.terminal).ok, false);
|
|
316
316
|
assert.equal(parseBenchmarkTerminal(`<done>{"x":"${'y'.repeat(1024)}"}</done>`, projection.terminal).ok, false);
|
|
317
|
+
for (const [raw, expectOk] of [
|
|
318
|
+
[
|
|
319
|
+
'<think>plan it</think><done>{"ok":true}</done>',
|
|
320
|
+
true
|
|
321
|
+
],
|
|
322
|
+
[
|
|
323
|
+
'<think>a</think>\n<THINK>b</THINK>\n<done>{"ok":true}</done>',
|
|
324
|
+
true
|
|
325
|
+
],
|
|
326
|
+
[
|
|
327
|
+
'<done>{"ok":true}</done><think>after</think>',
|
|
328
|
+
true
|
|
329
|
+
],
|
|
330
|
+
[
|
|
331
|
+
'<think>unclosed<done>{"ok":true}</done>',
|
|
332
|
+
false
|
|
333
|
+
],
|
|
334
|
+
[
|
|
335
|
+
'prose<think>x</think><done>{"ok":true}</done>',
|
|
336
|
+
false
|
|
337
|
+
]
|
|
338
|
+
]){
|
|
339
|
+
assert.equal(parseBenchmarkTerminal(raw, projection.terminal).ok, expectOk, raw);
|
|
340
|
+
}
|
|
317
341
|
function turnStart(turn = 1) {
|
|
318
342
|
return {
|
|
319
343
|
type: 'turn/start',
|
|
@@ -343,11 +367,9 @@ function toolCall(callId = 'call-1', options = {}) {
|
|
|
343
367
|
callId,
|
|
344
368
|
name: projection.toolName,
|
|
345
369
|
arguments: JSON.stringify({
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
arguments: {}
|
|
350
|
-
}
|
|
370
|
+
action,
|
|
371
|
+
tool,
|
|
372
|
+
arguments: {}
|
|
351
373
|
})
|
|
352
374
|
}
|
|
353
375
|
};
|
|
@@ -1608,11 +1630,9 @@ try {
|
|
|
1608
1630
|
payload: '$(touch /tmp/nope)'
|
|
1609
1631
|
};
|
|
1610
1632
|
const result = await bridge.execute({
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
arguments: args
|
|
1615
|
-
}
|
|
1633
|
+
action: 'call',
|
|
1634
|
+
tool: 'lookup',
|
|
1635
|
+
arguments: args
|
|
1616
1636
|
}, null);
|
|
1617
1637
|
assert.deepEqual(spawnSpecs[0]?.argv, [
|
|
1618
1638
|
process.execPath,
|
|
@@ -1653,12 +1673,10 @@ try {
|
|
|
1653
1673
|
stdout: '{"result":{"city":"Dubai"}}'
|
|
1654
1674
|
});
|
|
1655
1675
|
const unmappedResult = await bridge.execute({
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
city: 'Dubai'
|
|
1661
|
-
}
|
|
1676
|
+
action: 'call',
|
|
1677
|
+
tool: 'toString',
|
|
1678
|
+
arguments: {
|
|
1679
|
+
city: 'Dubai'
|
|
1662
1680
|
}
|
|
1663
1681
|
}, null);
|
|
1664
1682
|
assert.deepEqual(unmappedResult, {
|
|
@@ -1671,12 +1689,10 @@ try {
|
|
|
1671
1689
|
stdout: '{"result":{"legacy":"value"}}'
|
|
1672
1690
|
});
|
|
1673
1691
|
const legacyResult = await bridge.execute({
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
city: 'Dubai'
|
|
1679
|
-
}
|
|
1692
|
+
action: 'call',
|
|
1693
|
+
tool: 'constructor',
|
|
1694
|
+
arguments: {
|
|
1695
|
+
city: 'Dubai'
|
|
1680
1696
|
}
|
|
1681
1697
|
}, null);
|
|
1682
1698
|
assert.deepEqual(legacyResult, {
|
|
@@ -1689,12 +1705,10 @@ try {
|
|
|
1689
1705
|
stdout: '{"result":{"city":"Dubai"}}'
|
|
1690
1706
|
});
|
|
1691
1707
|
const constructorUnexpected = await bridge.execute({
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
city: 'Dubai'
|
|
1697
|
-
}
|
|
1708
|
+
action: 'call',
|
|
1709
|
+
tool: 'constructor',
|
|
1710
|
+
arguments: {
|
|
1711
|
+
city: 'Dubai'
|
|
1698
1712
|
}
|
|
1699
1713
|
}, null);
|
|
1700
1714
|
assert.deepEqual(constructorUnexpected, {
|
|
@@ -1705,12 +1719,10 @@ try {
|
|
|
1705
1719
|
stdout: '{"result":{"nested":{"city":"Dubai"}}}'
|
|
1706
1720
|
});
|
|
1707
1721
|
const nestedAllowedResult = await bridge.execute({
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
city: 'Dubai'
|
|
1713
|
-
}
|
|
1722
|
+
action: 'call',
|
|
1723
|
+
tool: 'lookup',
|
|
1724
|
+
arguments: {
|
|
1725
|
+
city: 'Dubai'
|
|
1714
1726
|
}
|
|
1715
1727
|
}, null);
|
|
1716
1728
|
assert.deepEqual(nestedAllowedResult, {
|
|
@@ -1725,12 +1737,10 @@ try {
|
|
|
1725
1737
|
stdout: '{"result":{"city":"Dubai","unexpected":"secret"}}'
|
|
1726
1738
|
});
|
|
1727
1739
|
const unexpectedResult = await bridge.execute({
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
city: 'Dubai'
|
|
1733
|
-
}
|
|
1740
|
+
action: 'call',
|
|
1741
|
+
tool: 'lookup',
|
|
1742
|
+
arguments: {
|
|
1743
|
+
city: 'Dubai'
|
|
1734
1744
|
}
|
|
1735
1745
|
}, null);
|
|
1736
1746
|
assert.deepEqual(unexpectedResult, {
|
|
@@ -1741,12 +1751,10 @@ try {
|
|
|
1741
1751
|
stdout: '{"result":[{"city":"Dubai","nested":{"unexpected":"secret"}}]}'
|
|
1742
1752
|
});
|
|
1743
1753
|
const nestedUnexpectedResult = await bridge.execute({
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
city: 'Dubai'
|
|
1749
|
-
}
|
|
1754
|
+
action: 'call',
|
|
1755
|
+
tool: 'lookup',
|
|
1756
|
+
arguments: {
|
|
1757
|
+
city: 'Dubai'
|
|
1750
1758
|
}
|
|
1751
1759
|
}, null);
|
|
1752
1760
|
assert.deepEqual(nestedUnexpectedResult, {
|
|
@@ -1782,12 +1790,10 @@ try {
|
|
|
1782
1790
|
})
|
|
1783
1791
|
});
|
|
1784
1792
|
const forbiddenResult = await bridge.execute({
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
city: 'Dubai'
|
|
1790
|
-
}
|
|
1793
|
+
action: 'call',
|
|
1794
|
+
tool: 'lookup',
|
|
1795
|
+
arguments: {
|
|
1796
|
+
city: 'Dubai'
|
|
1791
1797
|
}
|
|
1792
1798
|
}, null);
|
|
1793
1799
|
assert.deepEqual(forbiddenResult, {
|
|
@@ -1799,12 +1805,10 @@ try {
|
|
|
1799
1805
|
stdout: '{"result":"the hidden answer"}'
|
|
1800
1806
|
});
|
|
1801
1807
|
const primitiveOutput = await bridge.execute({
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
city: 'Dubai'
|
|
1807
|
-
}
|
|
1808
|
+
action: 'call',
|
|
1809
|
+
tool: 'lookup',
|
|
1810
|
+
arguments: {
|
|
1811
|
+
city: 'Dubai'
|
|
1808
1812
|
}
|
|
1809
1813
|
}, null);
|
|
1810
1814
|
assert.deepEqual(primitiveOutput, {
|
|
@@ -1813,12 +1817,10 @@ try {
|
|
|
1813
1817
|
}, 'primitive result strings cannot bypass the structured visible-output boundary');
|
|
1814
1818
|
const beforeOversized = spawnSpecs.length;
|
|
1815
1819
|
const oversized = await bridge.execute({
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
blob: 'x'.repeat(65_537)
|
|
1821
|
-
}
|
|
1820
|
+
action: 'call',
|
|
1821
|
+
tool: 'lookup',
|
|
1822
|
+
arguments: {
|
|
1823
|
+
blob: 'x'.repeat(65_537)
|
|
1822
1824
|
}
|
|
1823
1825
|
}, null);
|
|
1824
1826
|
assert.deepEqual(oversized, {
|
|
@@ -1833,11 +1835,9 @@ try {
|
|
|
1833
1835
|
next: deep
|
|
1834
1836
|
};
|
|
1835
1837
|
const deepResult = await bridge.execute({
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
arguments: deep
|
|
1840
|
-
}
|
|
1838
|
+
action: 'call',
|
|
1839
|
+
tool: 'lookup',
|
|
1840
|
+
arguments: deep
|
|
1841
1841
|
}, null);
|
|
1842
1842
|
assert.deepEqual(deepResult, {
|
|
1843
1843
|
ok: false,
|
|
@@ -1847,17 +1847,15 @@ try {
|
|
|
1847
1847
|
assert.equal(spawnSpecs.length, beforeDeep, 'over-deep arguments are rejected before spawn');
|
|
1848
1848
|
const beforeOverride = spawnSpecs.length;
|
|
1849
1849
|
const overrideResult = await bridge.execute({
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
]
|
|
1860
|
-
}
|
|
1850
|
+
action: 'call',
|
|
1851
|
+
tool: 'lookup',
|
|
1852
|
+
arguments: {
|
|
1853
|
+
city: 'Dubai',
|
|
1854
|
+
executable: '/tmp/evil',
|
|
1855
|
+
cwd: '/tmp/evil',
|
|
1856
|
+
argv: [
|
|
1857
|
+
'--unsafe'
|
|
1858
|
+
]
|
|
1861
1859
|
}
|
|
1862
1860
|
}, null);
|
|
1863
1861
|
assert.deepEqual(spawnSpecs[beforeOverride]?.argv, [
|
|
@@ -1883,12 +1881,10 @@ try {
|
|
|
1883
1881
|
lossy: true
|
|
1884
1882
|
});
|
|
1885
1883
|
const truncated = await bridge.execute({
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
city: 'Dubai'
|
|
1891
|
-
}
|
|
1884
|
+
action: 'call',
|
|
1885
|
+
tool: 'lookup',
|
|
1886
|
+
arguments: {
|
|
1887
|
+
city: 'Dubai'
|
|
1892
1888
|
}
|
|
1893
1889
|
}, null);
|
|
1894
1890
|
assert.deepEqual(truncated, {
|
|
@@ -1902,12 +1898,10 @@ try {
|
|
|
1902
1898
|
signal: 'SIGTERM'
|
|
1903
1899
|
});
|
|
1904
1900
|
const failed = await bridge.execute({
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
city: 'Dubai'
|
|
1910
|
-
}
|
|
1901
|
+
action: 'call',
|
|
1902
|
+
tool: 'lookup',
|
|
1903
|
+
arguments: {
|
|
1904
|
+
city: 'Dubai'
|
|
1911
1905
|
}
|
|
1912
1906
|
}, null);
|
|
1913
1907
|
assert.deepEqual(failed, {
|
|
@@ -1916,6 +1910,27 @@ try {
|
|
|
1916
1910
|
exit_code: 17,
|
|
1917
1911
|
signal: 'SIGTERM'
|
|
1918
1912
|
}, 'nonzero runner result is structured without stderr echo');
|
|
1913
|
+
const errorsTable = await bridge.execute({
|
|
1914
|
+
action: 'errors'
|
|
1915
|
+
}, null);
|
|
1916
|
+
assert.ok(errorsTable.ok === true && errorsTable.errors, 'errors 契约表可拉取');
|
|
1917
|
+
for (const code of [
|
|
1918
|
+
'invalid_action',
|
|
1919
|
+
'disallowed_tool',
|
|
1920
|
+
'invalid_arguments',
|
|
1921
|
+
'timed_out',
|
|
1922
|
+
'output_truncated',
|
|
1923
|
+
'invalid_json',
|
|
1924
|
+
'invalid_output',
|
|
1925
|
+
'runner_failed',
|
|
1926
|
+
'spawn_failed',
|
|
1927
|
+
'forbidden_output'
|
|
1928
|
+
]){
|
|
1929
|
+
const row = errorsTable.errors?.[code];
|
|
1930
|
+
assert.ok(row && typeof row.recoverable === 'boolean' && row.remedy.length > 0, `契约表应含 ${code}(recoverable+remedy)`);
|
|
1931
|
+
}
|
|
1932
|
+
assert.equal(errorsTable.errors?.invalid_arguments?.recoverable, true, '参数形态错=调用方可恢复');
|
|
1933
|
+
assert.equal(errorsTable.errors?.forbidden_output?.recoverable, false, '策略边界=不可恢复');
|
|
1919
1934
|
for (const stdout of [
|
|
1920
1935
|
'not-json',
|
|
1921
1936
|
'{"result":1}{"result":2}'
|
|
@@ -1924,12 +1939,10 @@ try {
|
|
|
1924
1939
|
stdout
|
|
1925
1940
|
});
|
|
1926
1941
|
const malformed = await bridge.execute({
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
city: 'Dubai'
|
|
1932
|
-
}
|
|
1942
|
+
action: 'call',
|
|
1943
|
+
tool: 'lookup',
|
|
1944
|
+
arguments: {
|
|
1945
|
+
city: 'Dubai'
|
|
1933
1946
|
}
|
|
1934
1947
|
}, null);
|
|
1935
1948
|
assert.deepEqual(malformed, {
|
|
@@ -1941,12 +1954,10 @@ try {
|
|
|
1941
1954
|
spawnError: true
|
|
1942
1955
|
});
|
|
1943
1956
|
const spawnFailed = await bridge.execute({
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
city: 'Dubai'
|
|
1949
|
-
}
|
|
1957
|
+
action: 'call',
|
|
1958
|
+
tool: 'lookup',
|
|
1959
|
+
arguments: {
|
|
1960
|
+
city: 'Dubai'
|
|
1950
1961
|
}
|
|
1951
1962
|
}, null);
|
|
1952
1963
|
assert.deepEqual(spawnFailed, {
|
|
@@ -1957,12 +1968,10 @@ try {
|
|
|
1957
1968
|
spawnReject: true
|
|
1958
1969
|
});
|
|
1959
1970
|
const asyncSpawnFailed = await bridge.execute({
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
city: 'Dubai'
|
|
1965
|
-
}
|
|
1971
|
+
action: 'call',
|
|
1972
|
+
tool: 'lookup',
|
|
1973
|
+
arguments: {
|
|
1974
|
+
city: 'Dubai'
|
|
1966
1975
|
}
|
|
1967
1976
|
}, null);
|
|
1968
1977
|
assert.deepEqual(asyncSpawnFailed, {
|
|
@@ -1973,12 +1982,10 @@ try {
|
|
|
1973
1982
|
waitForAbort: true
|
|
1974
1983
|
});
|
|
1975
1984
|
const timedOut = await bridge.execute({
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
city: 'Dubai'
|
|
1981
|
-
}
|
|
1985
|
+
action: 'call',
|
|
1986
|
+
tool: 'lookup',
|
|
1987
|
+
arguments: {
|
|
1988
|
+
city: 'Dubai'
|
|
1982
1989
|
}
|
|
1983
1990
|
}, null);
|
|
1984
1991
|
assert.deepEqual(timedOut, {
|
|
@@ -1987,35 +1994,35 @@ try {
|
|
|
1987
1994
|
}, 'deadline abort is surfaced as timed_out');
|
|
1988
1995
|
assert.equal(timeoutSignal?.aborted, true, 'timeout abort signal is fired');
|
|
1989
1996
|
const beforeInvalidArgs = spawnSpecs.length;
|
|
1990
|
-
|
|
1991
|
-
|
|
1997
|
+
let argsTypeRejected = '';
|
|
1998
|
+
try {
|
|
1999
|
+
await bridge.execute({
|
|
1992
2000
|
action: 'call',
|
|
1993
2001
|
tool: 'lookup',
|
|
1994
2002
|
arguments: [
|
|
1995
2003
|
'not',
|
|
1996
2004
|
'plain'
|
|
1997
2005
|
]
|
|
1998
|
-
}
|
|
1999
|
-
}
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2006
|
+
}, null);
|
|
2007
|
+
} catch (e) {
|
|
2008
|
+
argsTypeRejected = e.name;
|
|
2009
|
+
}
|
|
2010
|
+
assert.equal(argsTypeRejected, 'ToolArgsError', 'arguments 非对象 → 宿主权 schema 结构化拒绝');
|
|
2003
2011
|
assert.equal(spawnSpecs.length, beforeInvalidArgs, 'non-object arguments are rejected before spawn');
|
|
2004
|
-
|
|
2005
|
-
|
|
2012
|
+
let actionRejected = '';
|
|
2013
|
+
try {
|
|
2014
|
+
await bridge.execute({
|
|
2006
2015
|
action: 'inspect'
|
|
2007
|
-
}
|
|
2008
|
-
}
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2016
|
+
}, null);
|
|
2017
|
+
} catch (e) {
|
|
2018
|
+
actionRejected = e.name;
|
|
2019
|
+
}
|
|
2020
|
+
assert.equal(actionRejected, 'ToolArgsError', '枚举外 action → 宿主权 schema 结构化拒绝(ToolArgsError)');
|
|
2012
2021
|
const beforeRejected = spawnSpecs.length;
|
|
2013
2022
|
const rejected = await bridge.execute({
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
arguments: {}
|
|
2018
|
-
}
|
|
2023
|
+
action: 'call',
|
|
2024
|
+
tool: 'delete_all',
|
|
2025
|
+
arguments: {}
|
|
2019
2026
|
}, null);
|
|
2020
2027
|
assert.deepEqual(rejected, {
|
|
2021
2028
|
ok: false,
|
|
@@ -2105,7 +2112,8 @@ try {
|
|
|
2105
2112
|
assert.deepEqual(disabledVariables, [
|
|
2106
2113
|
'current_date',
|
|
2107
2114
|
'time_anchor_card',
|
|
2108
|
-
'motivation_brief'
|
|
2115
|
+
'motivation_brief',
|
|
2116
|
+
'channel_routing_card'
|
|
2109
2117
|
], 'normal product mode keeps its prompt variables');
|
|
2110
2118
|
const whitespace = [];
|
|
2111
2119
|
const whitespaceCtx = {
|
|
@@ -2462,12 +2470,10 @@ try {
|
|
|
2462
2470
|
const legacyBridge = legacyTools.find((tool)=>tool.name === 'gotry_benchmark_environment');
|
|
2463
2471
|
assert.ok(legacyBridge?.execute, 'legacy config without allowed_output_keys registers the bridge');
|
|
2464
2472
|
assert.deepEqual(await legacyBridge.execute({
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
city: 'Dubai'
|
|
2470
|
-
}
|
|
2473
|
+
action: 'call',
|
|
2474
|
+
tool: 'lookup',
|
|
2475
|
+
arguments: {
|
|
2476
|
+
city: 'Dubai'
|
|
2471
2477
|
}
|
|
2472
2478
|
}, null), {
|
|
2473
2479
|
ok: true,
|
|
@@ -3,9 +3,9 @@ import { mkdtempSync, rmSync } from 'node:fs';
|
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { ensureLedger } from '../src/state-ledger.js';
|
|
6
|
-
import {
|
|
6
|
+
import { BookingCopilotTaskRuntime, bookingDigest } from '../src/booking-surface/runtime.js';
|
|
7
7
|
const workspace = (revision)=>({
|
|
8
|
-
schemaVersion: 'booking.surface
|
|
8
|
+
schemaVersion: 'booking.surface',
|
|
9
9
|
contextRef: 'ctx-ledger-binding',
|
|
10
10
|
surface: 'tenant',
|
|
11
11
|
revision,
|
|
@@ -56,7 +56,7 @@ const workspace = (revision)=>({
|
|
|
56
56
|
}
|
|
57
57
|
});
|
|
58
58
|
const offersReceipt = (actionId, revision)=>({
|
|
59
|
-
schemaVersion: 'booking.surface
|
|
59
|
+
schemaVersion: 'booking.surface',
|
|
60
60
|
kind: 'action.receipt',
|
|
61
61
|
actionId,
|
|
62
62
|
contextRef: 'ctx-ledger-binding',
|
|
@@ -82,7 +82,7 @@ const offersReceipt = (actionId, revision)=>({
|
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
84
|
const checkReceipt = (actionId, revision)=>({
|
|
85
|
-
schemaVersion: 'booking.surface
|
|
85
|
+
schemaVersion: 'booking.surface',
|
|
86
86
|
kind: 'action.receipt',
|
|
87
87
|
actionId,
|
|
88
88
|
contextRef: 'ctx-ledger-binding',
|
|
@@ -108,12 +108,12 @@ const checkReceipt = (actionId, revision)=>({
|
|
|
108
108
|
function fixture(stage) {
|
|
109
109
|
const root = mkdtempSync(join(tmpdir(), 'gotry-availability-ledger-binding-'));
|
|
110
110
|
const ledger = ensureLedger(root);
|
|
111
|
-
const runtime = new
|
|
111
|
+
const runtime = new BookingCopilotTaskRuntime(ledger, {
|
|
112
112
|
contextRefFactory: ()=>'ctx-ledger-binding'
|
|
113
113
|
});
|
|
114
114
|
const task = 'ledger-binding-task';
|
|
115
115
|
runtime.startTask({
|
|
116
|
-
schemaVersion: 'booking.surface
|
|
116
|
+
schemaVersion: 'booking.surface',
|
|
117
117
|
kind: 'user.turn',
|
|
118
118
|
taskId: task,
|
|
119
119
|
turnId: 'turn-1',
|
|
@@ -123,7 +123,7 @@ function fixture(stage) {
|
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
const query = {
|
|
126
|
-
schemaVersion: 'booking.surface
|
|
126
|
+
schemaVersion: 'booking.surface',
|
|
127
127
|
kind: 'offers.query',
|
|
128
128
|
actionId: 'query-1',
|
|
129
129
|
contextRef: 'ctx-ledger-binding',
|
|
@@ -139,14 +139,14 @@ function fixture(stage) {
|
|
|
139
139
|
};
|
|
140
140
|
runtime.issueOperation(task, query);
|
|
141
141
|
runtime.continueWithReceipt({
|
|
142
|
-
schemaVersion: 'booking.surface
|
|
142
|
+
schemaVersion: 'booking.surface',
|
|
143
143
|
kind: 'action.receipt.continuation',
|
|
144
144
|
taskId: task,
|
|
145
145
|
workspace: workspace(1),
|
|
146
146
|
receipt: offersReceipt('query-1', 1)
|
|
147
147
|
});
|
|
148
148
|
const check = {
|
|
149
|
-
schemaVersion: 'booking.surface
|
|
149
|
+
schemaVersion: 'booking.surface',
|
|
150
150
|
kind: 'offer.check',
|
|
151
151
|
actionId: 'check-1',
|
|
152
152
|
contextRef: 'ctx-ledger-binding',
|
|
@@ -160,7 +160,7 @@ function fixture(stage) {
|
|
|
160
160
|
};
|
|
161
161
|
runtime.issueOperation(task, check);
|
|
162
162
|
if (stage === 'receipt') runtime.continueWithReceipt({
|
|
163
|
-
schemaVersion: 'booking.surface
|
|
163
|
+
schemaVersion: 'booking.surface',
|
|
164
164
|
kind: 'action.receipt.continuation',
|
|
165
165
|
taskId: task,
|
|
166
166
|
workspace: {
|
|
@@ -191,7 +191,7 @@ function rewrite(root, kind, mutate) {
|
|
|
191
191
|
}
|
|
192
192
|
function assertCorrupt(root, label) {
|
|
193
193
|
const ledger = ensureLedger(root);
|
|
194
|
-
const runtime = new
|
|
194
|
+
const runtime = new BookingCopilotTaskRuntime(ledger, {
|
|
195
195
|
contextRefFactory: ()=>'ctx-ledger-binding'
|
|
196
196
|
});
|
|
197
197
|
assert.throws(()=>runtime.resumeTask('ledger-binding-task'), /ledger_corrupt:ledger-binding-task/, label);
|
|
@@ -200,7 +200,7 @@ function assertCorrupt(root, label) {
|
|
|
200
200
|
{
|
|
201
201
|
const fixtureState = fixture('action');
|
|
202
202
|
const ledger = ensureLedger(fixtureState.root);
|
|
203
|
-
assert.doesNotThrow(()=>new
|
|
203
|
+
assert.doesNotThrow(()=>new BookingCopilotTaskRuntime(ledger).resumeTask(fixtureState.task));
|
|
204
204
|
ledger.close();
|
|
205
205
|
rmSync(fixtureState.root, {
|
|
206
206
|
recursive: true,
|
|
@@ -211,28 +211,28 @@ function assertCorrupt(root, label) {
|
|
|
211
211
|
'candidate digest',
|
|
212
212
|
(payload)=>{
|
|
213
213
|
payload.availability.candidateSetDigest = 'f'.repeat(64);
|
|
214
|
-
payload.availabilityDigest =
|
|
214
|
+
payload.availabilityDigest = bookingDigest(payload.availability);
|
|
215
215
|
}
|
|
216
216
|
],
|
|
217
217
|
[
|
|
218
218
|
'offer set digest',
|
|
219
219
|
(payload)=>{
|
|
220
220
|
payload.availability.hotels.h1.currentGeneration.offerSetDigest = 'e'.repeat(64);
|
|
221
|
-
payload.availabilityDigest =
|
|
221
|
+
payload.availabilityDigest = bookingDigest(payload.availability);
|
|
222
222
|
}
|
|
223
223
|
],
|
|
224
224
|
[
|
|
225
225
|
'source receipt digest',
|
|
226
226
|
(payload)=>{
|
|
227
227
|
payload.availability.hotels.h1.currentGeneration.source.receiptDigest = 'd'.repeat(64);
|
|
228
|
-
payload.availabilityDigest =
|
|
228
|
+
payload.availabilityDigest = bookingDigest(payload.availability);
|
|
229
229
|
}
|
|
230
230
|
],
|
|
231
231
|
[
|
|
232
232
|
'active ordinal',
|
|
233
233
|
(payload)=>{
|
|
234
234
|
payload.availability.activeHotelOrdinal = 1;
|
|
235
|
-
payload.availabilityDigest =
|
|
235
|
+
payload.availabilityDigest = bookingDigest(payload.availability);
|
|
236
236
|
}
|
|
237
237
|
],
|
|
238
238
|
[
|
|
@@ -248,12 +248,12 @@ function assertCorrupt(root, label) {
|
|
|
248
248
|
evidence: 'conclusive'
|
|
249
249
|
};
|
|
250
250
|
payload.availability.availabilityPhase = 'terminal';
|
|
251
|
-
payload.availabilityDigest =
|
|
251
|
+
payload.availabilityDigest = bookingDigest(payload.availability);
|
|
252
252
|
}
|
|
253
253
|
]
|
|
254
254
|
]){
|
|
255
255
|
const fixtureState = fixture('action');
|
|
256
|
-
rewrite(fixtureState.root, 'booking.copilot.
|
|
256
|
+
rewrite(fixtureState.root, 'booking.copilot.action.issued', mutate);
|
|
257
257
|
assertCorrupt(fixtureState.root, label);
|
|
258
258
|
rmSync(fixtureState.root, {
|
|
259
259
|
recursive: true,
|
|
@@ -262,7 +262,7 @@ function assertCorrupt(root, label) {
|
|
|
262
262
|
}
|
|
263
263
|
{
|
|
264
264
|
const fixtureState = fixture('action');
|
|
265
|
-
rewrite(fixtureState.root, 'booking.copilot.
|
|
265
|
+
rewrite(fixtureState.root, 'booking.copilot.action.issued', (payload)=>{
|
|
266
266
|
payload.availability.activeHotelOrdinal = 1;
|
|
267
267
|
});
|
|
268
268
|
assertCorrupt(fixtureState.root, 'raw ACTION availability digest mismatch');
|
|
@@ -272,7 +272,7 @@ function assertCorrupt(root, label) {
|
|
|
272
272
|
});
|
|
273
273
|
}{
|
|
274
274
|
const fixtureState = fixture('receipt');
|
|
275
|
-
rewrite(fixtureState.root, 'booking.copilot.
|
|
275
|
+
rewrite(fixtureState.root, 'booking.copilot.receipt.observed', (payload)=>{
|
|
276
276
|
payload.availability.activeHotelOrdinal = 1;
|
|
277
277
|
});
|
|
278
278
|
assertCorrupt(fixtureState.root, 'raw RECEIPT availability digest mismatch');
|
|
@@ -282,10 +282,10 @@ function assertCorrupt(root, label) {
|
|
|
282
282
|
});
|
|
283
283
|
}{
|
|
284
284
|
const fixtureState = fixture('action');
|
|
285
|
-
rewrite(fixtureState.root, 'booking.copilot.
|
|
285
|
+
rewrite(fixtureState.root, 'booking.copilot.action.issued', (payload)=>{
|
|
286
286
|
payload.action.input.offerRef = 'o2';
|
|
287
287
|
const { actionDigest: _ignored, ...base } = payload.action;
|
|
288
|
-
payload.action.actionDigest =
|
|
288
|
+
payload.action.actionDigest = bookingDigest(base);
|
|
289
289
|
});
|
|
290
290
|
assertCorrupt(fixtureState.root, 'wrong action transition');
|
|
291
291
|
rmSync(fixtureState.root, {
|
|
@@ -295,10 +295,10 @@ function assertCorrupt(root, label) {
|
|
|
295
295
|
}{
|
|
296
296
|
const fixtureState = fixture('receipt');
|
|
297
297
|
const runtimeLedger = ensureLedger(fixtureState.root);
|
|
298
|
-
const runtime = new
|
|
298
|
+
const runtime = new BookingCopilotTaskRuntime(runtimeLedger);
|
|
299
299
|
assert.deepEqual(runtime.resumeTask(fixtureState.task)?.availability.criteria, {}, 'recovery retains the canonical offer criteria after restart');
|
|
300
300
|
const wrongDetour = {
|
|
301
|
-
schemaVersion: 'booking.surface
|
|
301
|
+
schemaVersion: 'booking.surface',
|
|
302
302
|
kind: 'search.run',
|
|
303
303
|
actionId: 'detour',
|
|
304
304
|
contextRef: 'ctx-ledger-binding',
|
|
@@ -320,9 +320,9 @@ function assertCorrupt(root, label) {
|
|
|
320
320
|
});
|
|
321
321
|
}{
|
|
322
322
|
const fixtureState = fixture('receipt');
|
|
323
|
-
rewrite(fixtureState.root, 'booking.copilot.
|
|
323
|
+
rewrite(fixtureState.root, 'booking.copilot.receipt.observed', (payload)=>{
|
|
324
324
|
payload.receipt.status = 'applied';
|
|
325
|
-
payload.receiptDigest =
|
|
325
|
+
payload.receiptDigest = bookingDigest(payload.receipt);
|
|
326
326
|
});
|
|
327
327
|
assertCorrupt(fixtureState.root, 'wrong receipt transition');
|
|
328
328
|
rmSync(fixtureState.root, {
|