@danceiny/gotry 0.0.1-rc.21 → 0.0.1-rc.24
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 +102 -194
- package/README.zh-CN.md +115 -210
- package/bin/gotry-backend.js +53 -0
- package/bin/gotry-bootstrap.js +466 -35
- package/bin/gotry-inner.js +255 -36
- package/bin/gotry-process-liveness.d.ts +27 -0
- package/bin/gotry-process-liveness.js +97 -0
- package/bin/gotry-runtime-resolution.d.ts +1 -1
- package/bin/gotry-runtime-resolution.js +2 -2
- package/client/client.js +174 -0
- package/cordis.gotry-patch.yml +70 -93
- package/dist/capabilities/agent-reach-deep.js +45 -122
- package/dist/capabilities/agent-reach.js +63 -148
- package/dist/capabilities/anything.js +89 -75
- package/dist/capabilities/artifacts.js +123 -104
- package/dist/capabilities/channel-health.js +65 -45
- package/dist/capabilities/channel-registry.js +108 -87
- package/dist/capabilities/doctor.js +357 -235
- package/dist/capabilities/effect.js +223 -309
- package/dist/capabilities/fact-log.js +28 -14
- package/dist/capabilities/flyai.js +245 -156
- package/dist/capabilities/ground-transfer.js +509 -0
- package/dist/capabilities/hbcli.js +144 -148
- package/dist/capabilities/hotelbyte-transaction.js +194 -0
- package/dist/capabilities/incident-log.js +131 -61
- package/dist/capabilities/model-override.js +30 -10
- package/dist/capabilities/opensky.js +54 -43
- package/dist/capabilities/resilience.js +50 -32
- package/dist/capabilities/session/action-cache.js +50 -44
- package/dist/capabilities/session/adapters/ctrip-flight.js +119 -62
- package/dist/capabilities/session/adapters/ctrip-hotel.js +125 -110
- package/dist/capabilities/session/adapters/dida-portal.js +206 -0
- package/dist/capabilities/session/adapters/meituan-local.js +35 -54
- package/dist/capabilities/session/adapters/rail-12306.js +169 -112
- package/dist/capabilities/session/benchmark.js +85 -149
- package/dist/capabilities/session/extension-bridge.js +320 -259
- package/dist/capabilities/session/extension-channel.js +57 -76
- package/dist/capabilities/session/extension-distribution.js +115 -119
- package/dist/capabilities/session/extract.js +31 -21
- package/dist/capabilities/session/golden-score.js +55 -33
- package/dist/capabilities/session/health-watch.js +146 -154
- package/dist/capabilities/session/read-guard.js +55 -47
- package/dist/capabilities/session/static-flight-golden.js +49 -36
- package/dist/capabilities/session/transport.js +54 -61
- package/dist/capabilities/session/wizard.js +63 -93
- package/dist/capabilities/session-consent.js +143 -47
- package/dist/capabilities/session-login.js +95 -126
- package/dist/capabilities/session-search.js +391 -253
- package/dist/capabilities/sponsor-plugin.js +341 -0
- package/dist/capabilities/visa-policy.js +87 -73
- package/dist/capabilities/weather.js +163 -235
- package/dist/scripts/action-cache-tests.js +24 -59
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +91 -142
- package/dist/scripts/agent-planning-turn-deadline-tests.js +80 -176
- package/dist/scripts/agent-reach-deep-tests.js +30 -40
- package/dist/scripts/agent-reach-tests.js +26 -18
- package/dist/scripts/agent-reach-wrapper-tests.js +46 -50
- package/dist/scripts/anything-tests.js +58 -62
- package/dist/scripts/artifact-client-contract-tests.js +69 -0
- package/dist/scripts/artifacts-capability-tests.js +235 -0
- package/dist/scripts/async-collect.js +26 -15
- package/dist/scripts/benchmark-environment-bridge-e2e.js +287 -684
- package/dist/scripts/benchmark-environment-bridge-tests.js +818 -3123
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +66 -279
- package/dist/scripts/booking-copilot-availability-policy-tests.js +153 -1257
- package/dist/scripts/booking-copilot-bin-proof-tests.js +22 -45
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +64 -76
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +69 -199
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +393 -759
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +33 -75
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +60 -110
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +28 -66
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +72 -271
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +73 -275
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +784 -3398
- package/dist/scripts/booking-copilot-server-proof-tests.js +63 -168
- package/dist/scripts/booking-copilot-startup-proof-tests.js +38 -124
- package/dist/scripts/booking-executor-tests.js +80 -0
- package/dist/scripts/booking-recovery-chain-tests.js +182 -0
- package/dist/scripts/booking-saga-tests.js +61 -123
- package/dist/scripts/booking-surface-contract-proof-tests.js +152 -1167
- package/dist/scripts/bootstrap-tests.js +1383 -128
- package/dist/scripts/build-changelog.js +89 -130
- package/dist/scripts/build-metrics-report.js +135 -143
- package/dist/scripts/changelog-tests.js +35 -82
- package/dist/scripts/channel-probe-tests.js +44 -116
- package/dist/scripts/channel-probe.js +84 -167
- package/dist/scripts/channel-registry-tests.js +97 -185
- package/dist/scripts/companion-tests.js +25 -70
- package/dist/scripts/dida-cookie-probe.js +87 -0
- package/dist/scripts/dida-sw-probe.js +114 -0
- package/dist/scripts/diff-test.js +17 -12
- package/dist/scripts/doctor-tests.js +428 -120
- package/dist/scripts/dsh-artifact-e2e.js +150 -0
- package/dist/scripts/dsh-artifact-web-e2e.js +443 -0
- package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
- package/dist/scripts/dsh-runtime-closure-tests.js +110 -153
- package/dist/scripts/dsh-runtime-closure.js +75 -63
- package/dist/scripts/dsh-session-v3-migration-proof.js +106 -0
- package/dist/scripts/dsh-subprocess-local-proof.js +149 -0
- package/dist/scripts/dsh-target-closure-proof.js +178 -0
- package/dist/scripts/effect-tests.js +165 -552
- package/dist/scripts/engine-run.js +1 -3
- package/dist/scripts/engine-tests.js +16 -10
- package/dist/scripts/evaluation-cadence-tests.js +69 -242
- package/dist/scripts/evaluation-contract-tests.js +193 -499
- package/dist/scripts/extension-distribution-cli.js +19 -15
- package/dist/scripts/extension-distribution-tests.js +98 -211
- package/dist/scripts/extension-tests.js +366 -389
- package/dist/scripts/fact-gate-tests.js +725 -263
- package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
- package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
- package/dist/scripts/flight-malformed-tests.js +159 -0
- package/dist/scripts/flyai-tests.js +325 -68
- package/dist/scripts/g5-guard-tests.js +131 -0
- package/dist/scripts/g5-guard.js +189 -0
- package/dist/scripts/gen-lunar-anchors.js +106 -0
- package/dist/scripts/gotry-backend-kernel-tests.js +79 -0
- package/dist/scripts/ground-transfer-tests.js +956 -0
- package/dist/scripts/hbcli-e2e-tests.js +71 -90
- package/dist/scripts/hbcli-live-optin-tests.js +96 -0
- package/dist/scripts/hbcli-release-contract-tests.js +122 -0
- package/dist/scripts/hbcli-tests.js +41 -115
- package/dist/scripts/health-watch-cli.js +42 -28
- package/dist/scripts/hotel-date-gate-tests.js +496 -0
- package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
- package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
- package/dist/scripts/i18n-tests.js +16 -9
- package/dist/scripts/incident-tests.js +281 -87
- package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
- package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
- package/dist/scripts/issue-271-liveness-tests.js +547 -0
- package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
- package/dist/scripts/issue-289-model-retry-tests.js +441 -0
- package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
- package/dist/scripts/issue-338-home-city-e2e.js +577 -0
- package/dist/scripts/issue343-real-entry-e2e.js +160 -0
- package/dist/scripts/journey-tests.js +22 -27
- package/dist/scripts/kernel-manifest-evidence.js +109 -0
- package/dist/scripts/kernel-manifest-gate.js +126 -0
- package/dist/scripts/kernel-manifest-tests.js +212 -0
- package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
- package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
- package/dist/scripts/kernel-manifest.js +369 -0
- package/dist/scripts/ledger-repair-apply-tests.js +316 -0
- package/dist/scripts/ledger-repair-plan-tests.js +375 -0
- package/dist/scripts/ledger-tests.js +325 -340
- package/dist/scripts/ledger-workflow-crash.js +10 -20
- package/dist/scripts/map-tools-vendor-package-proof.js +206 -134
- package/dist/scripts/memory-capture-tests.js +242 -61
- package/dist/scripts/memory-decay-tests.js +18 -52
- package/dist/scripts/memory-lifecycle-tests.js +657 -0
- package/dist/scripts/memory-lifecycle.js +196 -0
- package/dist/scripts/memory-metrics.js +24 -12
- package/dist/scripts/memory-value-report.js +474 -222
- package/dist/scripts/memory-value-tests.js +328 -0
- package/dist/scripts/metrics-report-tests.js +62 -199
- package/dist/scripts/model-override-e2e.js +66 -105
- package/dist/scripts/nightly-evidence-tests.js +64 -89
- package/dist/scripts/nightly-evidence.js +108 -111
- package/dist/scripts/nudge-digest.js +39 -28
- package/dist/scripts/onboarding-tests.js +63 -88
- package/dist/scripts/opensky-check.js +18 -13
- package/dist/scripts/opensky-tests.js +28 -28
- package/dist/scripts/persona-surface-guard-tests.js +37 -12
- package/dist/scripts/pnpm-dsh-closure-proof.js +2 -5
- package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
- package/dist/scripts/price-drift-tests.js +126 -227
- package/dist/scripts/price-drift-watch.js +209 -253
- package/dist/scripts/probe-poi-tests.js +52 -45
- package/dist/scripts/product-metrics.js +187 -273
- package/dist/scripts/publish-preverify.js +47 -41
- package/dist/scripts/realtime-pricing-tests.js +37 -76
- package/dist/scripts/replay-async.js +20 -18
- package/dist/scripts/replay-real.js +16 -18
- package/dist/scripts/replay.js +52 -82
- package/dist/scripts/session-attach-diagnose.js +16 -12
- package/dist/scripts/session-attach-poc.js +34 -37
- package/dist/scripts/session-benchmark.js +66 -147
- package/dist/scripts/session-dida-live-e2e.js +151 -0
- package/dist/scripts/session-extract-tests.js +14 -35
- package/dist/scripts/session-login.js +14 -13
- package/dist/scripts/session-tests.js +545 -583
- package/dist/scripts/sf-live-benchmark.js +92 -110
- package/dist/scripts/sf-live-cli-tests.js +2 -9
- package/dist/scripts/sf-soft-score-tests.js +19 -60
- package/dist/scripts/sf-summary-tests.js +149 -0
- package/dist/scripts/sf-summary.js +466 -84
- package/dist/scripts/skeleton-check.js +16 -14
- package/dist/scripts/skeleton-integration-test.js +11 -10
- package/dist/scripts/skills-contract-tests.js +51 -46
- package/dist/scripts/smoke-session-gate-tests.js +12 -20
- package/dist/scripts/smoke.js +541 -422
- package/dist/scripts/sponsor-reuse-tests.js +262 -0
- package/dist/scripts/state-cli-tests.js +226 -101
- package/dist/scripts/state-cli.js +549 -212
- package/dist/scripts/static-golden-tests.js +46 -180
- package/dist/scripts/time-eval-tests.js +210 -192
- package/dist/scripts/travel-timeline-tests.js +29 -93
- package/dist/scripts/turn-handoff-collect-tests.js +46 -93
- package/dist/scripts/turn-handoff-collect.js +71 -99
- package/dist/scripts/turn-policy-tests.js +28 -29
- package/dist/scripts/typed-contract-canary.js +77 -162
- package/dist/scripts/tz-resolver-sanity.js +50 -0
- package/dist/scripts/tz-resolver-tests.js +584 -0
- package/dist/scripts/unified-tests.js +23 -19
- package/dist/scripts/visa-policy-tests.js +31 -44
- package/dist/scripts/weather-tests.js +121 -543
- package/dist/scripts/wish-channel-gate-tests.js +29 -86
- package/dist/scripts/write-gate-tests.js +522 -0
- package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
- package/dist/scripts/z3-lifecycle-tests.js +170 -0
- package/dist/scripts/z3-race-repeat-tests.js +39 -0
- package/dist/scripts/z3-race-tests.js +18 -12
- package/dist/src/artifact-gate.js +652 -221
- package/dist/src/backend/kernel.js +91 -0
- package/dist/src/backend/modules/booking-copilot.js +55 -0
- package/dist/src/backend/modules/booking-executor.js +124 -0
- package/dist/src/backend/modules/session-search.js +194 -0
- package/dist/src/benchmark-agent-conformance.js +296 -262
- package/dist/src/benchmark-environment-bridge.js +298 -413
- package/dist/src/benchmark-headless-child-diagnostics.js +93 -100
- package/dist/src/benchmark-tool-isolation.js +94 -67
- package/dist/src/bookable-facts.js +299 -174
- package/dist/src/booking-saga.js +64 -120
- package/dist/src/booking-surface/availability-policy.js +443 -576
- package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
- package/dist/src/booking-surface/contracts.js +24 -80
- package/dist/src/booking-surface/dsh-planner.js +510 -281
- package/dist/src/booking-surface/dsh-plugin.js +17 -1
- package/dist/src/booking-surface/error-codes.js +82 -10
- package/dist/src/booking-surface/index.js +0 -3
- package/dist/src/booking-surface/profile.js +10 -54
- package/dist/src/booking-surface/recovery-chain.js +367 -0
- package/dist/src/booking-surface/runtime.js +765 -891
- package/dist/src/booking-surface/server.js +200 -251
- package/dist/src/booking-surface/startup.js +58 -54
- package/dist/src/booking-surface/validation.js +150 -218
- package/dist/src/bridge.js +20 -13
- package/dist/src/companions.js +48 -74
- package/dist/src/contracts.js +21 -43
- package/dist/src/dsh-llm.js +82 -120
- package/dist/src/engine.js +253 -239
- package/dist/src/evaluation-cadence.js +72 -209
- package/dist/src/evaluation-contracts.js +220 -843
- package/dist/src/flight-pack-adapter.js +54 -0
- package/dist/src/flight-pack-contract.js +2 -0
- package/dist/src/gotry-backend.js +70 -0
- package/dist/src/hotel-date-gate.js +118 -0
- package/dist/src/i18n.js +18 -7
- package/dist/src/index.js +1425 -1629
- package/dist/src/journey.js +132 -81
- package/dist/src/ledger-repair-apply.js +538 -0
- package/dist/src/ledger-repair-plan.js +463 -0
- package/dist/src/loop.js +257 -166
- package/dist/src/memory-capture.js +180 -32
- package/dist/src/memory-decay.js +30 -14
- package/dist/src/memory-lifecycle.js +1310 -0
- package/dist/src/memory-utility.js +27 -40
- package/dist/src/mock-llm.js +36 -61
- package/dist/src/model.js +81 -36
- package/dist/src/realtime-pricing.js +63 -72
- package/dist/src/slot-spec.js +84 -106
- package/dist/src/state-ledger.js +310 -471
- package/dist/src/subagent-job-id-guard.js +58 -0
- package/dist/src/time-anchor.js +231 -33
- package/dist/src/tool-packet.js +20 -8
- package/dist/src/travel-slots.js +58 -35
- package/dist/src/travel-timeline.js +44 -63
- package/dist/src/turn-deadline.js +121 -127
- package/dist/src/turn-policy.js +61 -89
- package/dist/src/tz-resolver.js +143 -0
- package/dist/src/unified.js +504 -381
- package/dist/src/wish-pool.js +39 -14
- package/dist/src/write-gate.js +495 -0
- package/dist/src/z3-shared.js +273 -7
- package/extension/README.md +4 -3
- package/extension/background.js +125 -14
- package/extension/content-bridge.js +23 -1
- package/extension/content-main.js +15 -4
- package/extension/manifest.json +16 -8
- package/package.json +251 -220
- package/ts/capabilities/agent-reach.ts +4 -4
- package/ts/capabilities/anything.ts +1 -1
- package/ts/capabilities/artifacts.ts +46 -9
- package/ts/capabilities/flyai.ts +156 -37
- package/ts/capabilities/hbcli.ts +1 -1
- package/ts/capabilities/incident-log.ts +88 -59
- package/ts/capabilities/session/adapters/ctrip-flight.ts +99 -36
- package/ts/capabilities/session/adapters/dida-portal.ts +250 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +123 -24
- package/ts/capabilities/session/extension-bridge.ts +226 -101
- package/ts/capabilities/session/extension-channel.ts +22 -9
- package/ts/capabilities/session/wizard.ts +2 -2
- package/ts/capabilities/session-consent.ts +98 -14
- package/ts/capabilities/session-login.ts +1 -0
- package/ts/capabilities/session-search.ts +315 -31
- package/ts/dsh-runtime/vendor/README.md +8 -4
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +7 -1
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +5 -3
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +1 -1
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +1 -1
- package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +6 -6
- package/ts/package.json +236 -16
- package/ts/scripts/map-tools-vendor-package-proof.ts +152 -31
- package/ts/scripts/state-cli.ts +418 -51
- package/ts/src/artifact-gate.ts +561 -15
- package/ts/src/benchmark-environment-bridge.ts +37 -20
- package/ts/src/bookable-facts.ts +183 -7
- package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
- package/ts/src/booking-surface/dsh-planner.ts +240 -32
- package/ts/src/booking-surface/dsh-plugin.js +17 -1
- package/ts/src/booking-surface/error-codes.ts +75 -0
- package/ts/src/booking-surface/recovery-chain.ts +409 -0
- package/ts/src/booking-surface/server.ts +84 -51
- package/ts/src/booking-surface/validation.ts +2 -0
- package/ts/src/contracts.ts +12 -2
- package/ts/src/dsh-llm.ts +4 -8
- package/ts/src/index.ts +609 -90
- package/ts/src/loop.ts +116 -7
- package/ts/src/memory-capture.ts +227 -3
- package/ts/src/mock-llm.ts +4 -8
- package/ts/src/model.ts +88 -2
- package/ts/src/state-ledger.ts +47 -29
- package/ts/src/subagent-job-id-guard.ts +72 -0
- package/ts/src/time-anchor.ts +217 -13
- package/ts/src/unified.ts +316 -54
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { FLIGHT_PACK_VERSION } from './flight-pack-contract.js';
|
|
2
|
+
import { isKnownZoneLoose } from './tz-resolver.js';
|
|
3
|
+
export class WorkWindowPrecedenceError extends Error {
|
|
4
|
+
code;
|
|
5
|
+
constructor(code, message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'WorkWindowPrecedenceError';
|
|
8
|
+
this.code = code;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Merge the user's schedule onto a parsed flight-pack window.
|
|
13
|
+
*
|
|
14
|
+
* v2 pack metadata owns the home zone. The profile contributes only schedule
|
|
15
|
+
* fields; its legacy numeric offset is intentionally ignored on that path.
|
|
16
|
+
* Legacy v1 keeps the adapter's historical numeric replacement behavior.
|
|
17
|
+
*/
|
|
18
|
+
export function mergeProfileWorkWindow(spec, profileWindow) {
|
|
19
|
+
// Vacation is an explicit profile fact, not an omitted schedule. It clears
|
|
20
|
+
// any pack window for both versions before the version-specific merge.
|
|
21
|
+
if (profileWindow?.vacation === true)
|
|
22
|
+
return { ...spec, workWindow: undefined };
|
|
23
|
+
if (spec[FLIGHT_PACK_VERSION] === 2) {
|
|
24
|
+
if (!profileWindow)
|
|
25
|
+
return spec;
|
|
26
|
+
const packWindow = spec.workWindow;
|
|
27
|
+
if (!packWindow?.homeZone || !isKnownZoneLoose(packWindow.homeZone)) {
|
|
28
|
+
throw new WorkWindowPrecedenceError('v2_profile_requires_pack_home_zone', 'v2 profile schedule requires a valid explicit pack work_window.home_zone');
|
|
29
|
+
}
|
|
30
|
+
const workWindow = {
|
|
31
|
+
...packWindow,
|
|
32
|
+
startMin: profileWindow.startMin,
|
|
33
|
+
endMin: profileWindow.endMin,
|
|
34
|
+
workdays: profileWindow.workdays,
|
|
35
|
+
};
|
|
36
|
+
return { ...spec, workWindow };
|
|
37
|
+
}
|
|
38
|
+
// v1 adapter behavior: profile replaces the legacy pack window; no profile
|
|
39
|
+
// clears it as the existing adapters historically did.
|
|
40
|
+
if (!profileWindow)
|
|
41
|
+
return { ...spec, workWindow: undefined };
|
|
42
|
+
if (typeof profileWindow.homeTzOffsetMin !== 'number') {
|
|
43
|
+
throw new WorkWindowPrecedenceError('v1_profile_requires_numeric_home_offset', 'v1 profile work window requires homeTzOffsetMin');
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
...spec,
|
|
47
|
+
workWindow: {
|
|
48
|
+
homeTzOffsetMin: profileWindow.homeTzOffsetMin,
|
|
49
|
+
startMin: profileWindow.startMin,
|
|
50
|
+
endMin: profileWindow.endMin,
|
|
51
|
+
workdays: profileWindow.workdays,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gotry-backend 统一入口(founder 口径:「我只允许一个 gotry 包装出来的服务」)。
|
|
3
|
+
*
|
|
4
|
+
* 一个进程、一个 HTTP 服务面;能力 = 模块(booking-copilot、session-search,后续
|
|
5
|
+
* a2a 协议端口亦归此服务),模块自带鉴权/探活,内核只做路由分发。hotel-be 是
|
|
6
|
+
* 外层 BFF,只认本服务。
|
|
7
|
+
*
|
|
8
|
+
* 端口:GOTRY_BACKEND_PORT > GOTRY_BOOKING_COPILOT_PORT > 3082(向后兼容:
|
|
9
|
+
* 默认与既有 booking-copilot 部署同端口,路由合同不变,hotel-be BFF 零改动)。
|
|
10
|
+
*
|
|
11
|
+
* 环境变量:
|
|
12
|
+
* booking-copilot 模块:GOTRY_BOOKING_COPILOT_API_KEY/STATE_ROOT/INGRESS_MODE/
|
|
13
|
+
* ARTIFACT_ID + DEEPSEEK/LLM keys(dsh planner,同独立部署)
|
|
14
|
+
* session-search 模块:GOTRY_BACKEND_SESSION_API_KEY(缺 = 该模块 fail-closed 503)、
|
|
15
|
+
* GOTRY_SESSION_TRANSPORT=cdp、CHROME_USER_DATA_DIR、GOTRY_SESSION_AUDIT_PATH
|
|
16
|
+
*
|
|
17
|
+
* 运行:node bin/gotry-backend.js(编译产物)或 tsx ts/src/gotry-backend.ts(源码形态)。
|
|
18
|
+
*/
|
|
19
|
+
import { startBookingCopilotModule } from './backend/modules/booking-copilot.js';
|
|
20
|
+
import { startBookingExecutorModule } from './backend/modules/booking-executor.js';
|
|
21
|
+
import { startSessionSearchModule } from './backend/modules/session-search.js';
|
|
22
|
+
import { resolve } from 'node:path';
|
|
23
|
+
import { fileURLToPath } from 'node:url';
|
|
24
|
+
import { closeBackend, createBackendServer } from './backend/kernel.js';
|
|
25
|
+
export async function startGotryBackendFromEnvironment(env = process.env) {
|
|
26
|
+
const modules = [];
|
|
27
|
+
modules.push(await startBookingCopilotModule(env));
|
|
28
|
+
modules.push(startSessionSearchModule({
|
|
29
|
+
apiKey: () => env.GOTRY_BACKEND_SESSION_API_KEY ?? '',
|
|
30
|
+
auditPath: env.GOTRY_SESSION_AUDIT_PATH,
|
|
31
|
+
}));
|
|
32
|
+
modules.push(startBookingExecutorModule({
|
|
33
|
+
apiKey: () => env.GOTRY_BACKEND_BOOKING_API_KEY ?? '',
|
|
34
|
+
evidenceDir: () => env.GOTRY_BACKEND_EVIDENCE_DIR ?? '/var/lib/gotry-backend/booking-evidence',
|
|
35
|
+
}));
|
|
36
|
+
const port = Number(env.GOTRY_BACKEND_PORT ?? env.GOTRY_BOOKING_COPILOT_PORT ?? 3082);
|
|
37
|
+
const handle = await createBackendServer({
|
|
38
|
+
modules,
|
|
39
|
+
host: env.GOTRY_BACKEND_HOST ?? '127.0.0.1',
|
|
40
|
+
port: Number.isSafeInteger(port) && port > 0 ? port : 3082,
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
port: handle.port,
|
|
44
|
+
moduleNames: handle.moduleNames,
|
|
45
|
+
close: () => closeBackend(handle, modules),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function runCli() {
|
|
49
|
+
const handle = await startGotryBackendFromEnvironment();
|
|
50
|
+
process.stderr.write(`[gotry-backend] listening on http://127.0.0.1:${handle.port}; modules=${handle.moduleNames.join(',')}\n`);
|
|
51
|
+
let stopping = false;
|
|
52
|
+
const stop = () => {
|
|
53
|
+
if (stopping)
|
|
54
|
+
return;
|
|
55
|
+
stopping = true;
|
|
56
|
+
void handle.close().then(() => process.exit(0), (error) => {
|
|
57
|
+
process.stderr.write(`[gotry-backend] shutdown failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
process.once('SIGINT', stop);
|
|
62
|
+
process.once('SIGTERM', stop);
|
|
63
|
+
}
|
|
64
|
+
const invokedPath = process.argv[1] ? resolve(process.argv[1]) : '';
|
|
65
|
+
if (invokedPath === fileURLToPath(import.meta.url)) {
|
|
66
|
+
runCli().catch((error) => {
|
|
67
|
+
process.stderr.write(`[gotry-backend] startup failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 酒店日期校验闸(issue #283):`gotry_hotel_search` 在派发供应商 CLI 前必须先确认
|
|
3
|
+
* 「完整、有效且退房晚于入住」。缺/空/单侧/类型错/不可解析/倒序/同日/不存在的日历
|
|
4
|
+
* 日期(如 2026-02-30、2026-13-01),任一命中即返回可行动的 input_required,
|
|
5
|
+
* 绝不发供应商命令。有效自然语言日期复用既有 `buildTimeAnchor` /
|
|
6
|
+
* `resolveSlotDate`(已含严格 ISO 校验),不动时间锚点/slot-spec/其它工具。
|
|
7
|
+
*
|
|
8
|
+
* 失败原因(顺序决策,一次问清):
|
|
9
|
+
* missing(字段未传)> blank(空字符串)> type(非字符串)> unresolved(词表外/不存在的日历)> 倒序/同日
|
|
10
|
+
* - 同侧 缺失 + 另一侧 空串 → 两端均报缺,两轮往返压成一次
|
|
11
|
+
* - 五字段契约:reason(最小语义根因)/missing(需补齐的字段)/raw(用户原话)/message(可行动指引)/evidence(落账标签)
|
|
12
|
+
*/
|
|
13
|
+
import { buildTimeAnchor, isRealIsoDate } from './time-anchor.js';
|
|
14
|
+
import { resolveSlotDate } from './slot-spec.js';
|
|
15
|
+
/**
|
|
16
|
+
* 闸主入口。返回 success 表示闸通过,绝对日期可直接进入供应商查询;
|
|
17
|
+
* 返回 failure 表示闸失败,工具层应原样回传 input_required,不调 interpretEffect、
|
|
18
|
+
* 不写延迟日志。
|
|
19
|
+
*/
|
|
20
|
+
export function evaluateHotelStayDates(rawCheckIn, rawCheckOut, opts = {}) {
|
|
21
|
+
const anchor = buildTimeAnchor(opts.now ?? new Date());
|
|
22
|
+
const checkInStr = typeof rawCheckIn === 'string' ? rawCheckIn.trim() : '';
|
|
23
|
+
const checkOutStr = typeof rawCheckOut === 'string' ? rawCheckOut.trim() : '';
|
|
24
|
+
const raw = {
|
|
25
|
+
checkIn: typeof rawCheckIn === 'string' ? rawCheckIn : undefined,
|
|
26
|
+
checkOut: typeof rawCheckOut === 'string' ? rawCheckOut : undefined,
|
|
27
|
+
};
|
|
28
|
+
const checkInProvided = rawCheckIn !== undefined;
|
|
29
|
+
const checkOutProvided = rawCheckOut !== undefined;
|
|
30
|
+
const checkInIsString = typeof rawCheckIn === 'string';
|
|
31
|
+
const checkOutIsString = typeof rawCheckOut === 'string';
|
|
32
|
+
const checkInBlank = checkInIsString && checkInStr === '';
|
|
33
|
+
const checkOutBlank = checkOutIsString && checkOutStr === '';
|
|
34
|
+
const checkInTypeError = checkInProvided && !checkInIsString;
|
|
35
|
+
const checkOutTypeError = checkOutProvided && !checkOutIsString;
|
|
36
|
+
// 两端均缺失或一侧缺失+另一侧空串 → 一次报齐缺的两侧(避免两轮往返)
|
|
37
|
+
const bothNeedQuery = !checkInProvided && (!checkOutProvided || checkOutBlank)
|
|
38
|
+
|| !checkOutProvided && (!checkInProvided || checkInBlank);
|
|
39
|
+
// 两端均空字符串(都已传但都是空串) → 同样报齐
|
|
40
|
+
if (bothNeedQuery || (checkInBlank && checkOutBlank)) {
|
|
41
|
+
const reason = !checkInProvided || checkInBlank ? 'check_in_blank' : 'check_out_blank';
|
|
42
|
+
return fail(reason, ['checkIn', 'checkOut'], '请告诉 gotry 入住日和退房日(具体日期,例如 2026-09-18);完整、有效且退房晚于入住才能查询酒店,缺一不查', `[hotel-date-gate@input_required:${reason}:both]`, raw);
|
|
43
|
+
}
|
|
44
|
+
// 单侧缺失(另一侧已正常传入) → 报缺的一侧
|
|
45
|
+
if (!checkInProvided) {
|
|
46
|
+
return fail('check_in_missing', ['checkIn'], '请告诉 gotry 入住日(具体日期,例如 2026-09-18);退房日已收到,但缺入住日无法判定窗口', '[hotel-date-gate@input_required:check_in_missing]', raw);
|
|
47
|
+
}
|
|
48
|
+
if (!checkOutProvided) {
|
|
49
|
+
return fail('check_out_missing', ['checkOut'], '请告诉 gotry 退房日(具体日期,例如 2026-09-20);入住日已收到,但缺退房日无法判定窗口', '[hotel-date-gate@input_required:check_out_missing]', raw);
|
|
50
|
+
}
|
|
51
|
+
// 类型错误(字段已传但不是字符串) → 按 blank 同形 + 标注类型,提示用户形态
|
|
52
|
+
if (checkInTypeError) {
|
|
53
|
+
return fail('check_in_blank', ['checkIn'], '入住日格式不对(应为日期字符串,例如 2026-09-18)——请向用户确认具体日期', '[hotel-date-gate@input_required:check_in_blank:type]', raw);
|
|
54
|
+
}
|
|
55
|
+
if (checkOutTypeError) {
|
|
56
|
+
return fail('check_out_blank', ['checkOut'], '退房日格式不对(应为日期字符串,例如 2026-09-20)——请向用户确认具体日期', '[hotel-date-gate@input_required:check_out_blank:type]', raw);
|
|
57
|
+
}
|
|
58
|
+
// 单侧空字符串(另一侧已正常传入)
|
|
59
|
+
if (checkInBlank) {
|
|
60
|
+
return fail('check_in_blank', ['checkIn'], '请告诉 gotry 入住日(具体日期,例如 2026-09-18);不要留空,不要猜日期', '[hotel-date-gate@input_required:check_in_blank]', raw);
|
|
61
|
+
}
|
|
62
|
+
if (checkOutBlank) {
|
|
63
|
+
return fail('check_out_blank', ['checkOut'], '请告诉 gotry 退房日(具体日期,例如 2026-09-20);不要留空,不要猜日期', '[hotel-date-gate@input_required:check_out_blank]', raw);
|
|
64
|
+
}
|
|
65
|
+
// 解析:复用 slot-spec 词表;词表外/不存在的日历日 → unresolved
|
|
66
|
+
const inRes = resolveSlotDate(checkInStr, anchor);
|
|
67
|
+
const outRes = resolveSlotDate(checkOutStr, anchor);
|
|
68
|
+
// 终消费层严格校验(issue #283 红线):resolveSlotDate 的 +N 算术(addDaysYmd) 可能
|
|
69
|
+
// 溢出产生 Invalid Date("NaN-NaN-NaN"),或 JS 自动进位跨千年("10000-01-01")。
|
|
70
|
+
// 词表外/不存在的日历日/算术溢出 一律归 unresolved,不发供应商命令。
|
|
71
|
+
if (inRes.kind === 'unresolved' || !isStrictIsoYmd(inRes.date)) {
|
|
72
|
+
return fail('check_in_unresolved', ['checkIn'], `入住日「${inRes.raw}」不是合法的具体日期——请给完整日期(例如 2026-09-18);不接受「近期」「明天之前」这类模糊表达,也不接受 2026-02-30 这类不存在的日历日`, '[hotel-date-gate@input_required:check_in_unresolved]', raw);
|
|
73
|
+
}
|
|
74
|
+
if (outRes.kind === 'unresolved' || !isStrictIsoYmd(outRes.date)) {
|
|
75
|
+
return fail('check_out_unresolved', ['checkOut'], `退房日「${outRes.raw}」不是合法的具体日期——请给完整日期(例如 2026-09-20);不接受「近期」「下周末」这类模糊表达,也不接受 2026-13-01 这类不存在的日历日`, '[hotel-date-gate@input_required:check_out_unresolved]', raw);
|
|
76
|
+
}
|
|
77
|
+
// 退房必须晚于入住;同日视为 0 晚
|
|
78
|
+
if (outRes.date <= inRes.date) {
|
|
79
|
+
const sameDay = outRes.date === inRes.date;
|
|
80
|
+
return fail('check_out_not_after_check_in', ['checkOut'], sameDay
|
|
81
|
+
? `退房日(${outRes.date})与入住日(${inRes.date})相同,0 晚没有意义——请告诉 gotry 退房日应该晚于入住日`
|
|
82
|
+
: `退房日(${outRes.date})早于入住日(${inRes.date}),顺序反了——请告诉 gotry 正确的退房日(应该晚于入住)`, sameDay
|
|
83
|
+
? '[hotel-date-gate@input_required:check_out_not_after_check_in:same_day]'
|
|
84
|
+
: '[hotel-date-gate@input_required:check_out_not_after_check_in:reversed]', raw);
|
|
85
|
+
}
|
|
86
|
+
// 通过:绝对日期已就位;slot 解析过程产生的原话 → 绝对日期 注记回显
|
|
87
|
+
const notes = [];
|
|
88
|
+
if (inRes.raw !== inRes.date)
|
|
89
|
+
notes.push(`slot-resolved: ${inRes.raw} → ${inRes.date}`);
|
|
90
|
+
if (outRes.raw !== outRes.date)
|
|
91
|
+
notes.push(`slot-resolved: ${outRes.raw} → ${outRes.date}`);
|
|
92
|
+
return { ok: true, checkIn: inRes.date, checkOut: outRes.date, notes };
|
|
93
|
+
}
|
|
94
|
+
function fail(reason, missing, message, evidence, raw) {
|
|
95
|
+
return { ok: false, verdict: 'input_required', reason, missing, raw, message, evidence };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 闸终消费层严格校验(issue #283 红线第二层,parseAbsoluteDate 词表口径之外):
|
|
99
|
+
* 1. 必须是字符串且匹配 `YYYY-MM-DD`(4-2-2 数字,前导零),拒 null/NaN/越界格式
|
|
100
|
+
* (addDaysYmd 溢出产生 "NaN-NaN-NaN",JS 自动进位跨千年产生 "10000-01-01")。
|
|
101
|
+
* 2. 年份 1-9999;复用 `isRealIsoDate` 拒不存在的日历日(2026-02-30 / 2025-02-29 等)。
|
|
102
|
+
* 仅供 evaluateHotelStayDates 在 resolveSlotDate 返回后使用;其它层不要复用此 helper。
|
|
103
|
+
*/
|
|
104
|
+
function isStrictIsoYmd(s) {
|
|
105
|
+
if (typeof s !== 'string')
|
|
106
|
+
return false;
|
|
107
|
+
const m = s.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
108
|
+
if (!m)
|
|
109
|
+
return false;
|
|
110
|
+
const y = Number(m[1]);
|
|
111
|
+
const mo = Number(m[2]);
|
|
112
|
+
const d = Number(m[3]);
|
|
113
|
+
if (!Number.isFinite(y) || !Number.isFinite(mo) || !Number.isFinite(d))
|
|
114
|
+
return false;
|
|
115
|
+
if (y < 1 || y > 9999)
|
|
116
|
+
return false;
|
|
117
|
+
return isRealIsoDate(y, mo, d);
|
|
118
|
+
}
|
package/dist/src/i18n.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* i18n 消息目录(README Known limitation「zh-CN 体验」的工程清偿件):
|
|
3
|
+
* GoTry 自有「确定性输出面」= 求解 answer_md(候选/航班链两渲染)+ 放宽建议文案
|
|
4
|
+
* + 排除理由。LLM 人格面(对话语言)由模型跟随用户语言,不在此层。
|
|
5
|
+
*
|
|
6
|
+
* 契约:
|
|
7
|
+
* - 默认 `zh-CN`,模板与历次金标准逐字节一致(engine/unified 金标准套件即回归闸);
|
|
8
|
+
* - `GOTRY_LOCALE=en`(或 setLocale)切英文;键缺失回退 zh 再回退键名——en 目录不齐不算错;
|
|
9
|
+
* - 插值 `{var}`;数字/时刻在调用点格式化,catalog 只管词序与措辞。
|
|
10
|
+
*/
|
|
1
11
|
const ZH = {
|
|
2
12
|
'md.header': '> 憧憬:{note}',
|
|
3
13
|
'md.constraints': '> 已识别约束:窗口 {days} 天 | 预算 ¥{budget} | 动机(休整改写需求 {hours}h 有效休整)',
|
|
@@ -26,7 +36,8 @@ const ZH = {
|
|
|
26
36
|
'sg.wish_reason_engine': '动机谱系 {weights} 下,{days} 天窗口装不下这个目的地',
|
|
27
37
|
'sg.wish_reason_window': '{days} 天窗口装不下(目的需 {minDays} 天)',
|
|
28
38
|
'un.workwindow_reason': '周{wd} {dep} 起飞落在工作窗口(当地 {start}-{end})内',
|
|
29
|
-
'un.
|
|
39
|
+
'un.workwindow_unresolvable_reason': 'home zone 投影失败:{reason}',
|
|
40
|
+
'un.redflag_redeye': '{leg} 落地精力仅 {pct}%(红眼后直奔事务,当日不宜安排重要会议)',
|
|
30
41
|
};
|
|
31
42
|
const EN = {
|
|
32
43
|
'md.header': '> Aspiration: {note}',
|
|
@@ -56,7 +67,8 @@ const EN = {
|
|
|
56
67
|
'sg.wish_reason_engine': 'under motivation weights {weights}, a {days}-day window cannot fit this destination',
|
|
57
68
|
'sg.wish_reason_window': '{days}-day window cannot fit (the purpose needs {minDays} days)',
|
|
58
69
|
'un.workwindow_reason': 'Departs {dep} on weekday {wd}, inside your work window (local {start}-{end})',
|
|
59
|
-
'un.
|
|
70
|
+
'un.workwindow_unresolvable_reason': 'home zone projection failed: {reason}',
|
|
71
|
+
'un.redflag_redeye': '{leg} lands with only {pct}% energy (red-eye then straight to business — no big meetings that day)',
|
|
60
72
|
};
|
|
61
73
|
let locale = process.env['GOTRY_LOCALE'] === 'en' ? 'en' : 'zh-CN';
|
|
62
74
|
export function getLocale() {
|
|
@@ -65,13 +77,12 @@ export function getLocale() {
|
|
|
65
77
|
export function setLocale(l) {
|
|
66
78
|
locale = l;
|
|
67
79
|
}
|
|
80
|
+
/** 词条渲染:en 缺键回退 zh,再回退键名;插值 {var},缺变量原样保留 `{var}`。 */
|
|
68
81
|
export function t(key, vars = {}) {
|
|
69
82
|
const tpl = (locale === 'en' ? EN[key] : undefined) ?? ZH[key] ?? String(key);
|
|
70
|
-
return tpl.replace(/\{(\w+)\}/g, (_, k)=>k in vars ? String(vars[k]) : `{${k}}`);
|
|
83
|
+
return tpl.replace(/\{(\w+)\}/g, (_, k) => (k in vars ? String(vars[k]) : `{${k}}`));
|
|
71
84
|
}
|
|
85
|
+
/** en 目录完备性检查:缺键即列出(测试闸用,运行时回退而非抛错) */
|
|
72
86
|
export function enCoverage() {
|
|
73
|
-
return Object.keys(ZH).filter(
|
|
87
|
+
return Object.keys(ZH).filter(k => EN[k] === undefined);
|
|
74
88
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
//# sourceURL=ts/src/i18n.ts
|