@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
|
@@ -1,43 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 发布前离线预验证(发布闸,rc.9 教训固化):
|
|
3
|
+
* 1. npm pack 产 tarball;
|
|
4
|
+
* 2. 装进 mktemp 干净目录(--ignore-scripts 快速);
|
|
5
|
+
* 3. 核验:版本号一致 + dependencies 闭包可达 + 关键入口文件在 + 账本模块可 import。
|
|
6
|
+
* 任何一步失败即 FAIL——rc.9「装得上跑不起」教训的永久闸。
|
|
7
|
+
* 运行:cd ts && npx tsx scripts/publish-preverify.ts
|
|
8
|
+
*/
|
|
1
9
|
import { execSync } from 'node:child_process';
|
|
2
10
|
import { mkdtempSync, rmSync, existsSync, readFileSync } from 'node:fs';
|
|
3
11
|
import { tmpdir } from 'node:os';
|
|
4
12
|
import { join } from 'node:path';
|
|
5
13
|
import { pathToFileURL } from 'node:url';
|
|
6
14
|
import { REQUIRED_BENCHMARK_DSH_VERSION } from '../../bin/gotry-runtime-resolution.js';
|
|
7
|
-
import { parsePnpmDshLock, parsePnpmRootDshImporter, REQUIRED_DSH_RUNTIME_PACKAGE_COUNT, validateDshRuntimeClosure, validatePnpmRootDshImporter } from './dsh-runtime-closure.js';
|
|
15
|
+
import { parsePnpmDshLock, parsePnpmRootDshImporter, REQUIRED_DSH_RUNTIME_PACKAGE_COUNT, validateDshRuntimeClosure, validatePnpmRootDshImporter, } from './dsh-runtime-closure.js';
|
|
8
16
|
const repoRoot = join(import.meta.dirname, '..', '..');
|
|
9
17
|
process.chdir(repoRoot);
|
|
10
|
-
const pkg = JSON.parse(execSync('cat package.json', {
|
|
11
|
-
encoding: 'utf-8'
|
|
12
|
-
}));
|
|
18
|
+
const pkg = JSON.parse(execSync('cat package.json', { encoding: 'utf-8' }));
|
|
13
19
|
const version = pkg.version;
|
|
14
20
|
console.log(`pre-verify: @danceiny/gotry@${version}`);
|
|
15
21
|
let tgz = '';
|
|
16
22
|
let dest = '';
|
|
17
23
|
try {
|
|
24
|
+
// 1) pack(产物落临时目录,不污染仓根;输出走文件防 ENOBUFS)
|
|
18
25
|
const outDir = mkdtempSync(join(tmpdir(), 'gotry-preverify-out-'));
|
|
19
|
-
execSync(`npm pack --pack-destination ${outDir}`, {
|
|
20
|
-
stdio: 'ignore'
|
|
21
|
-
});
|
|
26
|
+
execSync(`npm pack --pack-destination ${outDir}`, { stdio: 'ignore' });
|
|
22
27
|
const tgzPath = `danceiny-gotry-${version}.tgz`;
|
|
23
|
-
if (!existsSync(join(outDir, tgzPath)))
|
|
28
|
+
if (!existsSync(join(outDir, tgzPath)))
|
|
29
|
+
throw new Error('npm pack 未产出 tarball');
|
|
24
30
|
tgz = join(outDir, tgzPath);
|
|
25
31
|
console.log(`tarball: ${tgzPath}`);
|
|
32
|
+
// 2) 直接解 tarball(免网络:验证的是 tarball 自身内容,声明依赖可达性交由 npm registry 安装时保证)
|
|
26
33
|
dest = mkdtempSync(join(tmpdir(), 'gotry-preverify-'));
|
|
27
|
-
execSync(`tar -xzf "${tgz}" -C "${dest}"`, {
|
|
28
|
-
stdio: 'pipe'
|
|
29
|
-
});
|
|
34
|
+
execSync(`tar -xzf "${tgz}" -C "${dest}"`, { stdio: 'pipe' });
|
|
30
35
|
const pkgDir = join(dest, 'package');
|
|
31
|
-
const installedPkg = JSON.parse(execSync(`cat ${join(pkgDir, 'package.json')}`, {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
const installedPkg = JSON.parse(execSync(`cat ${join(pkgDir, 'package.json')}`, { encoding: 'utf-8' }));
|
|
37
|
+
if (installedPkg.version !== version)
|
|
38
|
+
throw new Error(`版本不符:${installedPkg.version}`);
|
|
39
|
+
// DSH prerelease packages publish their internal edges as caret ranges. A
|
|
40
|
+
// clean consumer must therefore receive the whole tested family as exact
|
|
41
|
+
// top-level dependencies; otherwise a newly published alpha can be mixed
|
|
42
|
+
// into the older runtime even though the source lockfile is coherent.
|
|
35
43
|
const rootLock = JSON.parse(readFileSync(join(repoRoot, 'package-lock.json'), 'utf-8'));
|
|
36
44
|
const dshClosure = validateDshRuntimeClosure({
|
|
37
45
|
dependencies: installedPkg.dependencies ?? {},
|
|
38
46
|
lockPackages: rootLock.packages ?? {},
|
|
39
47
|
runtimeVersion: REQUIRED_BENCHMARK_DSH_VERSION,
|
|
40
|
-
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT
|
|
48
|
+
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT,
|
|
41
49
|
});
|
|
42
50
|
console.log(`dsh closure: ${dshClosure.names.length} packages pinned at ${dshClosure.version}`);
|
|
43
51
|
const pnpmLock = readFileSync(join(repoRoot, 'pnpm-lock.yaml'), 'utf-8');
|
|
@@ -45,24 +53,26 @@ try {
|
|
|
45
53
|
dependencies: installedPkg.dependencies ?? {},
|
|
46
54
|
lockPackages: parsePnpmDshLock(pnpmLock),
|
|
47
55
|
runtimeVersion: REQUIRED_BENCHMARK_DSH_VERSION,
|
|
48
|
-
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT
|
|
56
|
+
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT,
|
|
49
57
|
});
|
|
50
58
|
const pnpmImporter = validatePnpmRootDshImporter({
|
|
51
59
|
dependencies: installedPkg.dependencies ?? {},
|
|
52
60
|
importerEntries: parsePnpmRootDshImporter(pnpmLock),
|
|
53
61
|
runtimeVersion: REQUIRED_BENCHMARK_DSH_VERSION,
|
|
54
|
-
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT
|
|
62
|
+
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT,
|
|
55
63
|
});
|
|
56
64
|
console.log(`pnpm closure: ${pnpmClosure.names.length} packages, root importer ${pnpmImporter.names.length}`);
|
|
65
|
+
// 3) dependencies 声明完整性:每个依赖必须存在于安装树(rc.9 缺陷=声明了运行时使用但根本没声明依赖)
|
|
57
66
|
const deps = Object.keys(installedPkg.dependencies ?? {});
|
|
58
67
|
console.log(`dependencies: ${deps.length} declared`);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
68
|
+
// 3b) 运行时 import 的重依赖必须在 dependencies 里声明(可用性由 npm 安装时保证;rc.9 缺陷=用了但没声明)
|
|
69
|
+
const runtimeImports = ['better-sqlite3'];
|
|
70
|
+
for (const dep of runtimeImports) {
|
|
71
|
+
if (!deps.includes(dep))
|
|
72
|
+
throw new Error(`运行时依赖 ${dep} 未声明进 dependencies(rc.9 缺陷形态)`);
|
|
64
73
|
}
|
|
65
74
|
console.log('deps resolvable: OK');
|
|
75
|
+
// 4) 关键入口文件在包内 + 账本模块真实 import
|
|
66
76
|
for (const e of [
|
|
67
77
|
'dist/src/state-ledger.js',
|
|
68
78
|
'dist/src/index.js',
|
|
@@ -72,13 +82,13 @@ try {
|
|
|
72
82
|
'dist/scripts/sf-live-benchmark.js',
|
|
73
83
|
'dist/data/session-golden-20.json',
|
|
74
84
|
'dist/data/sf-golden-manifest.json',
|
|
75
|
-
'dist/data/sf-static-routes.json'
|
|
76
|
-
]){
|
|
77
|
-
if (!existsSync(join(pkgDir, e)))
|
|
85
|
+
'dist/data/sf-static-routes.json',
|
|
86
|
+
]) {
|
|
87
|
+
if (!existsSync(join(pkgDir, e)))
|
|
88
|
+
throw new Error(`发布缺文件: ${e}`);
|
|
78
89
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}).trim().match(/^[1-9]/)) {
|
|
90
|
+
// import 冒烟改静态:state-ledger 的 better-sqlite3 引用已被 §3b 声明检查覆盖(无安装树时无法真 import)
|
|
91
|
+
if (!execSync(`grep -c "better-sqlite3" ${join(pkgDir, 'dist/src/state-ledger.js')}`, { encoding: 'utf-8' }).trim().match(/^[1-9]/)) {
|
|
82
92
|
throw new Error('dist/src/state-ledger.js 未引用 better-sqlite3(声明与实现不符)');
|
|
83
93
|
}
|
|
84
94
|
const staticProvider = await import(pathToFileURL(join(pkgDir, 'dist/capabilities/session/static-flight-golden.js')).href);
|
|
@@ -87,18 +97,14 @@ try {
|
|
|
87
97
|
throw new Error('发布 static golden 快照不可加载或覆盖不足 8 条');
|
|
88
98
|
}
|
|
89
99
|
console.log('PUBLISH PREVERIFY: OK');
|
|
90
|
-
}
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
91
102
|
console.error(`PREVERIFY FAILED: ${e.message}`);
|
|
92
103
|
process.exit(1);
|
|
93
|
-
} finally{
|
|
94
|
-
if (tgz) rmSync(tgz, {
|
|
95
|
-
force: true
|
|
96
|
-
});
|
|
97
|
-
if (dest) rmSync(dest, {
|
|
98
|
-
recursive: true,
|
|
99
|
-
force: true
|
|
100
|
-
});
|
|
101
104
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
finally {
|
|
106
|
+
if (tgz)
|
|
107
|
+
rmSync(tgz, { force: true });
|
|
108
|
+
if (dest)
|
|
109
|
+
rmSync(dest, { recursive: true, force: true });
|
|
110
|
+
}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 实时票价 overlay 回归(FlyAI 实时桥 + 静态降级,三值语义;纯离线——查询注入,零网):
|
|
3
|
+
* 1. hit:dated 段按航班号精确匹配 → 价格覆写 + `[实时API:flyai@ts]` 证据链 + 静态原价留档;
|
|
4
|
+
* 2. error/miss:段原样保留(静态价即降级),降级证据行进 notes;
|
|
5
|
+
* 3. 非 YYYY-MM-DD 日期段(如「2026-07-31 或 08-01」):不查询、不触碰;
|
|
6
|
+
* 4. 无匹配航班号/打码价(NaN):不覆写不抛错;
|
|
7
|
+
* 5. 求解集成:覆写后的 spec 进 solveUnified 判定可算、钱不低于降价前。
|
|
8
|
+
*
|
|
9
|
+
* 运行(在 ts/ 下,零网):npx tsx scripts/realtime-pricing-tests.ts
|
|
10
|
+
*/
|
|
1
11
|
import assert from 'node:assert/strict';
|
|
2
12
|
import { readFile } from 'node:fs/promises';
|
|
3
13
|
import { join } from 'node:path';
|
|
@@ -6,46 +16,25 @@ import { parseFlightPackToSpec, solveUnified } from '../src/unified.js';
|
|
|
6
16
|
const packJson = JSON.parse(await readFile(join('..', 'data', 'flights_2026.json'), 'utf-8'));
|
|
7
17
|
function hit(no, price) {
|
|
8
18
|
const opt = {
|
|
9
|
-
no,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
arrDateTime: '2026-07-18 17:20:00',
|
|
13
|
-
depStation: 'HKG',
|
|
14
|
-
arrStation: 'HKT',
|
|
15
|
-
durationMin: 155,
|
|
16
|
-
price
|
|
17
|
-
};
|
|
18
|
-
return {
|
|
19
|
-
ok: true,
|
|
20
|
-
via: 'flyai',
|
|
21
|
-
verdict: 'hit',
|
|
22
|
-
kind: 'flight',
|
|
23
|
-
evidence: '[实时API:flyai@2026-08-29T06:00:00.000Z] hit',
|
|
24
|
-
latencyMs: 1,
|
|
25
|
-
options: [
|
|
26
|
-
opt
|
|
27
|
-
]
|
|
19
|
+
no, name: '测试航司',
|
|
20
|
+
depDateTime: '2026-07-18 14:45:00', arrDateTime: '2026-07-18 17:20:00',
|
|
21
|
+
depStation: 'HKG', arrStation: 'HKT', durationMin: 155, price,
|
|
28
22
|
};
|
|
23
|
+
return { ok: true, via: 'flyai', verdict: 'hit', kind: 'flight', evidence: '[实时API:flyai@2026-08-29T06:00:00.000Z] hit', latencyMs: 1, options: [opt] };
|
|
29
24
|
}
|
|
30
25
|
function err() {
|
|
31
|
-
return {
|
|
32
|
-
ok: false,
|
|
33
|
-
via: 'flyai-error',
|
|
34
|
-
verdict: 'error',
|
|
35
|
-
kind: 'flight',
|
|
36
|
-
evidence: '[实时API:flyai@error@2026-08-29T06:00:00.000Z] synthetic-timeout',
|
|
37
|
-
latencyMs: 1,
|
|
38
|
-
error: 'synthetic-timeout'
|
|
39
|
-
};
|
|
26
|
+
return { ok: false, via: 'flyai-error', verdict: 'error', kind: 'flight', evidence: '[实时API:flyai@error@2026-08-29T06:00:00.000Z] synthetic-timeout', latencyMs: 1, error: 'synthetic-timeout' };
|
|
40
27
|
}
|
|
41
28
|
const queries = [];
|
|
42
|
-
const query = async (q)=>{
|
|
29
|
+
const query = async (q) => {
|
|
43
30
|
queries.push(q);
|
|
44
|
-
|
|
31
|
+
// f1 香港→普吉:仅 CX773 有实时价(1200),HX741 无条目(无匹配分支)
|
|
32
|
+
return q.origin === '香港' ? hit('CX773', 1200) : err(); // f5 深圳→迪拜:error 降级分支
|
|
45
33
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
});
|
|
34
|
+
// 五段链 spec:f1(HKG->HKT, 2026-07-18)、f5(SZX->DXB, 2026-08-10)进查询;
|
|
35
|
+
// f2/f3 日期为「2026-07-31 或 08-01」非严格形 → 词表/日期闸跳过;f4 无 arrive_by 仍是 dated。
|
|
36
|
+
const overlay = await overlayRealtimeFlightPrices(parseFlightPackToSpec(packJson), { query });
|
|
37
|
+
// 1. hit 覆写:仅精确匹配的 CX773 被覆写,静态原价留档在证据链里
|
|
49
38
|
assert.equal(overlay.matched.length, 1, '仅 CX773 命中覆写(1 条)');
|
|
50
39
|
const m = overlay.matched[0];
|
|
51
40
|
assert.equal(m.segment, 'f1');
|
|
@@ -54,62 +43,34 @@ assert.equal(m.staticCny, 2300);
|
|
|
54
43
|
assert.equal(m.realtimeCny, 1200);
|
|
55
44
|
assert.ok(m.evidence.includes('[实时API:flyai@2026-08-29T06:00:00.000Z]'), '证据链带时间戳');
|
|
56
45
|
assert.ok(m.evidence.includes('静态包原价 ¥2300'), '静态原价留档');
|
|
57
|
-
const f1svc = (id)=>overlay.spec.segments.find(
|
|
46
|
+
const f1svc = (id) => overlay.spec.segments.find(s => s.id === 'f1').options.find(o => o.id === id).move.services[0].priceCny;
|
|
58
47
|
assert.equal(f1svc('CX773'), 1200, '实时价覆写进 spec');
|
|
59
48
|
assert.equal(f1svc('HX741'), 1600, '无匹配条目原价保留');
|
|
60
|
-
|
|
49
|
+
// 2. error 降级:f5 段原样 + 降级证据行
|
|
50
|
+
const f5svc = overlay.spec.segments.find(s => s.id === 'f5').options[0].move.services[0];
|
|
61
51
|
assert.equal(f5svc.id, 'EK329');
|
|
62
52
|
assert.equal(f5svc.priceCny, 3400, 'error 段不覆写');
|
|
63
|
-
assert.ok(overlay.notes.some(
|
|
53
|
+
assert.ok(overlay.notes.some(n => n.startsWith('f5:') && n.includes('未取回(error')), 'error 降级证据行存在');
|
|
54
|
+
// 3. 查询面:仅 dated + route 词表内城市对的段被查询(f1/f4/f5;f2/f3 非严格日期不查)
|
|
64
55
|
assert.equal(queries.length, 3, '仅 f1/f4/f5 被查询(f2/f3 非严格日期)');
|
|
65
|
-
assert.deepEqual(queries.map(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const f4prices = overlay.spec.segments.find((s)=>s.id === 'f4').options.map((o)=>o.move.services[0].priceCny);
|
|
71
|
-
assert.deepEqual(f4prices, [
|
|
72
|
-
1150,
|
|
73
|
-
980,
|
|
74
|
-
700
|
|
75
|
-
], 'f4 error 段原价保留');
|
|
56
|
+
assert.deepEqual(queries.map(q => q.origin), ['香港', '深圳', '昆明']);
|
|
57
|
+
// f4(昆明→深圳)error 降级:两班原价不动
|
|
58
|
+
const f4prices = overlay.spec.segments.find(s => s.id === 'f4').options.map(o => o.move.services[0].priceCny);
|
|
59
|
+
assert.deepEqual(f4prices, [1150, 980, 700], 'f4 error 段原价保留');
|
|
60
|
+
// 4. 求解集成:覆写后 spec 判定可算(价格只降,结果钱 ≤ 基线)
|
|
76
61
|
const baseline = await solveUnified(parseFlightPackToSpec(packJson));
|
|
77
62
|
const overlaid = await solveUnified(overlay.spec);
|
|
78
63
|
assert.equal(overlaid.feasible, true, '覆写后 spec 求解可行');
|
|
79
64
|
assert.ok(baseline.money_cny !== undefined && overlaid.money_cny !== undefined, '两条路径都出总价');
|
|
80
65
|
assert.ok(overlaid.money_cny <= baseline.money_cny, '实时价不抬高求解总钱');
|
|
66
|
+
// 5. 无 dated 段 spec:零查询零改动(结构化直验)
|
|
81
67
|
const bare = await overlayRealtimeFlightPrices({
|
|
82
68
|
note: 'no-dates',
|
|
83
|
-
segments: [
|
|
84
|
-
|
|
85
|
-
id: '
|
|
86
|
-
|
|
87
|
-
options: [
|
|
88
|
-
{
|
|
89
|
-
id: 'a',
|
|
90
|
-
label: 'x',
|
|
91
|
-
move: {
|
|
92
|
-
hub: 'SZX',
|
|
93
|
-
services: [
|
|
94
|
-
{
|
|
95
|
-
id: 'EK329',
|
|
96
|
-
depMin: 45,
|
|
97
|
-
arrMin: 260,
|
|
98
|
-
priceCny: 3400
|
|
99
|
-
}
|
|
100
|
-
],
|
|
101
|
-
bufferMin: 30,
|
|
102
|
-
originTransferMin: 0,
|
|
103
|
-
destTransferMin: 30
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
]
|
|
107
|
-
}
|
|
108
|
-
]
|
|
69
|
+
segments: [{
|
|
70
|
+
id: 'dest', role: 'choice',
|
|
71
|
+
options: [{ id: 'a', label: 'x', move: { hub: 'SZX', services: [{ id: 'EK329', depMin: 45, arrMin: 260, priceCny: 3400 }], bufferMin: 30, originTransferMin: 0, destTransferMin: 30 } }],
|
|
72
|
+
}],
|
|
109
73
|
});
|
|
110
74
|
assert.equal(bare.matched.length, 0, '无 dated 段 → 不查询');
|
|
111
75
|
assert.equal(bare.spec.segments[0].options[0].move.services[0].priceCny, 3400, '价格原样');
|
|
112
76
|
console.log('\nREALTIME PRICING TESTS: 5/5 OK(hit 覆写+证据/error 降级/日期词表闸/求解集成/无段零触碰)');
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
//# sourceURL=ts/scripts/realtime-pricing-tests.ts
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S5 架构段重放:异步深度规划的会话形态(mock,零 API key)。
|
|
3
|
+
* 运行(在 ts/ 下):npx tsx scripts/replay-async.ts
|
|
4
|
+
* 验收:复杂行程 → 「一小时后回来看看」→ 回访交付已验证方案 + 选择题,不失望四条 4/4。
|
|
5
|
+
*/
|
|
1
6
|
import { join } from 'node:path';
|
|
2
7
|
import { createMockLlm } from '../src/mock-llm.js';
|
|
3
8
|
import { collectDeepPlanning, isComplex, newState, persistAsyncTicket, requestDeepPlanning, runTurn } from '../src/loop.js';
|
|
@@ -5,40 +10,37 @@ import { solveUnified } from '../src/unified.js';
|
|
|
5
10
|
const llm = createMockLlm(join('..', 'data', 'flights_2026.json'));
|
|
6
11
|
const state = newState();
|
|
7
12
|
const history = [];
|
|
13
|
+
// 前三轮与 replay 相同:brief → 工作时间 → 已订酒店
|
|
8
14
|
const turns = [
|
|
9
15
|
'7.17周五22:40落地深圳……8.10周一凌晨从深圳起飞周一上班前到迪拜。请给我做机票和酒店的行程规划和推荐。',
|
|
10
16
|
'我的工作时间是UTC+4的早上10点到下午7点',
|
|
11
|
-
'我订了酒店:The Title East Wing Rawai,7.18入住 7.23 退房'
|
|
17
|
+
'我订了酒店:The Title East Wing Rawai,7.18入住 7.23 退房',
|
|
12
18
|
];
|
|
13
19
|
let lastReply = '';
|
|
14
|
-
for (const t of turns){
|
|
15
|
-
const { reply } = await runTurn(state, t, llm, [
|
|
16
|
-
|
|
17
|
-
], solveUnified);
|
|
18
|
-
history.push({
|
|
19
|
-
role: 'user',
|
|
20
|
-
text: t
|
|
21
|
-
}, {
|
|
22
|
-
role: 'assistant',
|
|
23
|
-
text: reply
|
|
24
|
-
});
|
|
20
|
+
for (const t of turns) {
|
|
21
|
+
const { reply } = await runTurn(state, t, llm, [...history], solveUnified);
|
|
22
|
+
history.push({ role: 'user', text: t }, { role: 'assistant', text: reply });
|
|
25
23
|
lastReply = reply;
|
|
26
24
|
}
|
|
27
|
-
|
|
25
|
+
// 第 4 轮:复杂度命中 → 切深度规划模式;工单持久化(跨进程存续,S5 编排半段)
|
|
26
|
+
if (!isComplex(state))
|
|
27
|
+
throw new Error('复杂度判据未命中,重放脚本与判据不一致');
|
|
28
28
|
const { reply: asyncReply, ticket } = await requestDeepPlanning(state);
|
|
29
29
|
const saved = await persistAsyncTicket(ticket, state);
|
|
30
30
|
console.log('用户> (约束齐备,行程复杂)\n');
|
|
31
31
|
console.log(`GoTry> ${asyncReply}\n`);
|
|
32
32
|
console.log(`(工单已持久化:${saved}——任意后续进程可执行回收)\n`);
|
|
33
|
+
// --request-only:只请求不回收(种一张待回收工单,供调度器/下一进程实证)
|
|
33
34
|
if (process.argv.includes('--request-only')) {
|
|
34
35
|
console.log(`(request-only 模式结束;回收命令:npx tsx scripts/async-collect.ts ${ticket.id})`);
|
|
35
|
-
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// 模拟一小时(mock 期秒级)——真实形态:另一个进程/loopx tick 执行 async-collect
|
|
36
39
|
console.log('……(一小时后,另一个进程执行回收)……\n');
|
|
37
40
|
const { reply: deliverable } = await collectDeepPlanning(state, ticket, solveUnified);
|
|
38
41
|
console.log(`GoTry> ${deliverable}`);
|
|
39
|
-
|
|
42
|
+
// 不失望四条是交付物的自检契约,未全过即重放失败
|
|
43
|
+
if (!deliverable.includes('4/4'))
|
|
44
|
+
throw new Error('FAIL: 不失望四条未全过');
|
|
40
45
|
console.log(`\n(真实形态命令:npx tsx scripts/async-collect.ts ${ticket.id})`);
|
|
41
46
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
//# sourceURL=ts/scripts/replay-async.ts
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 真实重放(S4 验收入口):有 LLM_API_KEY(或旧别名 DEEPSEEK_API_KEY)走真 LLM,无则明确回退 mock。
|
|
3
|
+
* 运行(在 ts/ 下):npx tsx scripts/replay-real.ts
|
|
4
|
+
* S4 验收:同一开场白,真实对话质量 ≥ mock 重放(Kimi 复盘的验收标准)。
|
|
5
|
+
*/
|
|
1
6
|
import { join } from 'node:path';
|
|
2
7
|
import { readFileSync } from 'node:fs';
|
|
8
|
+
// 仓根 .env(gitignored):每行 KEY=VALUE,不覆盖已有环境变量
|
|
3
9
|
try {
|
|
4
|
-
for (const line of readFileSync(join('..', '.env'), 'utf-8').split('\n')){
|
|
10
|
+
for (const line of readFileSync(join('..', '.env'), 'utf-8').split('\n')) {
|
|
5
11
|
const m = line.match(/^([A-Z_]+)=(.*)$/);
|
|
6
|
-
if (m && !process.env[m[1]])
|
|
12
|
+
if (m && !process.env[m[1]])
|
|
13
|
+
process.env[m[1]] = m[2].trim();
|
|
7
14
|
}
|
|
8
|
-
}
|
|
15
|
+
}
|
|
16
|
+
catch { /* .env 可选 */ }
|
|
9
17
|
import { createMockLlm } from '../src/mock-llm.js';
|
|
10
18
|
import { createOpenAICompatLlm } from '../src/dsh-llm.js';
|
|
11
19
|
import { newState, runTurn } from '../src/loop.js';
|
|
@@ -13,6 +21,7 @@ import { solveUnified } from '../src/unified.js';
|
|
|
13
21
|
import { realtimeSolvePort } from '../src/realtime-pricing.js';
|
|
14
22
|
const useReal = Boolean(process.env['LLM_API_KEY'] ?? process.env['DEEPSEEK_API_KEY']);
|
|
15
23
|
const llm = useReal ? createOpenAICompatLlm(join('..', 'data', 'flights_2026.json')) : createMockLlm(join('..', 'data', 'flights_2026.json'));
|
|
24
|
+
// 实时票价接缝(默认关):GOTRY_REALTIME_PRICING=1 时 dated 段经 FlyAI 实时价覆写,证据并进 skeleton_notes
|
|
16
25
|
const solvePort = realtimeSolvePort(solveUnified);
|
|
17
26
|
console.log(useReal ? `=== 真 LLM 模式(${process.env['LLM_MODEL'] ?? 'MiniMax-M2'})===` : '=== 无 LLM_API_KEY,回退 mock(ADR-8)===\n');
|
|
18
27
|
const state = newState();
|
|
@@ -20,21 +29,10 @@ const history = [];
|
|
|
20
29
|
const turns = [
|
|
21
30
|
'7.17周五22:40落地深圳,7.18早上去香港办银行开户&保险签约;争取7.18当天飞泰国普吉岛……8.10周一凌晨从深圳起飞,周一上班前到迪拜。请给我做机票和酒店的行程规划和推荐。',
|
|
22
31
|
'我的工作时间是UTC+4的早上10点到下午7点',
|
|
23
|
-
'我订了酒店:The Title East Wing Rawai,7.18入住 7.23 退房'
|
|
32
|
+
'我订了酒店:The Title East Wing Rawai,7.18入住 7.23 退房',
|
|
24
33
|
];
|
|
25
|
-
for (const t of turns){
|
|
26
|
-
const { reply } = await runTurn(state, t, llm, [
|
|
27
|
-
|
|
28
|
-
], solvePort);
|
|
29
|
-
history.push({
|
|
30
|
-
role: 'user',
|
|
31
|
-
text: t
|
|
32
|
-
}, {
|
|
33
|
-
role: 'assistant',
|
|
34
|
-
text: reply
|
|
35
|
-
});
|
|
34
|
+
for (const t of turns) {
|
|
35
|
+
const { reply } = await runTurn(state, t, llm, [...history], solvePort);
|
|
36
|
+
history.push({ role: 'user', text: t }, { role: 'assistant', text: reply });
|
|
36
37
|
console.log(`\n用户> ${t.slice(0, 46)}…\nGoTry> ${reply}`);
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//# sourceURL=ts/scripts/replay-real.ts
|
package/dist/scripts/replay.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S2 重放:真实对话的用户侧(压缩版)喂给循环,mock-LLM 扮演智能侧。
|
|
3
|
+
* 运行(在 ts/ 下):npx tsx scripts/replay.ts
|
|
4
|
+
* 验收:① 日历一次断言零反复 ② 系统先问工作窗口与已订资源(Kimi 第 6 轮才问)
|
|
5
|
+
* ③ 用户提供后 profile 填充,访谈收敛
|
|
6
|
+
*/
|
|
1
7
|
import { createMockLlm } from '../src/mock-llm.js';
|
|
2
8
|
import { interviewNext, newState, runTurn } from '../src/loop.js';
|
|
3
9
|
import { solveUnified } from '../src/unified.js';
|
|
@@ -7,110 +13,74 @@ let state = newState();
|
|
|
7
13
|
const userTurns = [
|
|
8
14
|
'7.17周五22:40落地深圳,7.18早上去香港办银行开户&保险签约;争取7.18当天飞泰国普吉岛……8.10周一凌晨从深圳起飞,周一上班前到迪拜。请给我做机票和酒店的行程规划和推荐。',
|
|
9
15
|
'我的工作时间是UTC+4的早上10点到下午7点,晚上不一定有时间(至少得带电脑保持在线)',
|
|
10
|
-
'我订了酒店:The Title East Wing Rawai,7.18入住 7.23 退房'
|
|
16
|
+
'我订了酒店:The Title East Wing Rawai,7.18入住 7.23 退房',
|
|
11
17
|
];
|
|
12
18
|
const history = [];
|
|
13
|
-
for (const turn of userTurns){
|
|
14
|
-
const { reply } = await runTurn(state, turn, llm, [
|
|
15
|
-
|
|
16
|
-
], (spec)=>{
|
|
17
|
-
spec.skeletonHub = true;
|
|
18
|
-
return solveUnified(spec);
|
|
19
|
-
});
|
|
20
|
-
history.push({
|
|
21
|
-
role: 'user',
|
|
22
|
-
text: turn
|
|
23
|
-
}, {
|
|
24
|
-
role: 'assistant',
|
|
25
|
-
text: reply
|
|
26
|
-
});
|
|
19
|
+
for (const turn of userTurns) {
|
|
20
|
+
const { reply } = await runTurn(state, turn, llm, [...history], ((spec) => { spec.skeletonHub = true; return solveUnified(spec); }));
|
|
21
|
+
history.push({ role: 'user', text: turn }, { role: 'assistant', text: reply });
|
|
27
22
|
console.log(`\n用户> ${turn.slice(0, 50)}…`);
|
|
28
23
|
console.log(`GoTry> ${reply}`);
|
|
29
24
|
}
|
|
30
25
|
console.log('\n===== 终态校验 =====');
|
|
31
26
|
console.log('日历断言数:', Object.keys(state.calendar.assertedWeekdays).length, '| 2026-07-17 =', state.calendar.assertedWeekdays['2026-07-17']);
|
|
32
|
-
|
|
33
|
-
console.log('
|
|
27
|
+
const replayWorkWindow = state.profile.workWindow;
|
|
28
|
+
console.log('workWindow:', replayWorkWindow?.vacation === true
|
|
29
|
+
? '休假(无工作窗口)'
|
|
30
|
+
: replayWorkWindow
|
|
31
|
+
? `${replayWorkWindow.startMin / 60}:00-${replayWorkWindow.endMin / 60}:00 ${replayWorkWindow.homeTzOffsetMin === undefined ? 'IANA home zone' : `UTC+${replayWorkWindow.homeTzOffsetMin / 60}`}(证据:${replayWorkWindow.evidence.slice(0, 24)}…)`
|
|
32
|
+
: '缺失');
|
|
33
|
+
console.log('bookedResources:', state.profile.bookedResources?.map(b => b.ref).join('; ') ?? '缺失');
|
|
34
34
|
const { missing } = interviewNext(state);
|
|
35
35
|
console.log('剩余待问:', missing.length === 0 ? '无(除预算档未答,见下)' : missing.join(','));
|
|
36
|
+
// 终态断言——进 CI 的硬门槛:日历零反复、首轮问出工作窗口与已订资源、访谈收敛到只剩预算档
|
|
36
37
|
const weekday = state.calendar.assertedWeekdays['2026-07-17'];
|
|
37
|
-
if (weekday !== 'fri')
|
|
38
|
-
|
|
39
|
-
if (!state.profile.
|
|
40
|
-
|
|
38
|
+
if (weekday !== 'fri')
|
|
39
|
+
throw new Error(`FAIL: 2026-07-17 应为 fri,实为 ${weekday}`);
|
|
40
|
+
if (!state.profile.workWindow?.evidence)
|
|
41
|
+
throw new Error('FAIL: workWindow 缺失或无证据');
|
|
42
|
+
if (!state.profile.bookedResources?.length)
|
|
43
|
+
throw new Error('FAIL: bookedResources 缺失');
|
|
44
|
+
if (!(missing.length === 1 && missing[0] === 'budgetTier'))
|
|
45
|
+
throw new Error(`FAIL: 剩余待问应为 [budgetTier],实为 [${missing.join(',')}]`);
|
|
41
46
|
console.log('REPLAY ASSERTS OK');
|
|
47
|
+
// ---- D-10 切片 C:spec↔槽位日期一致性闸 ------------------------------------------
|
|
48
|
+
// 两个面:① 单日期段 + 冲突槽位 → 闸拦下求解并追问,不猜、不静默采信;
|
|
49
|
+
// ② 多段行程(pack 全 spec)→ 槽位 v1 无逐段真值,闸必须旁路(2026-08-28 巡检
|
|
50
|
+
// 修正的回归:金标准六段行程曾被全段误判分歧,求解被永久拦截)。
|
|
42
51
|
{
|
|
43
|
-
const conflictScript = [
|
|
44
|
-
{
|
|
52
|
+
const conflictScript = [{
|
|
45
53
|
when: '重新算一下',
|
|
46
54
|
extraction: {
|
|
47
55
|
schema_version: 'travel_slot_extraction.v1',
|
|
48
56
|
language: 'zh',
|
|
49
|
-
domains: [
|
|
50
|
-
|
|
51
|
-
],
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
start_date: '2026-12-25',
|
|
57
|
-
trip_type: 'round_trip'
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
missing_slots: []
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
];
|
|
64
|
-
const solvePort = (spec)=>{
|
|
65
|
-
spec.skeletonHub = true;
|
|
66
|
-
return solveUnified(spec);
|
|
67
|
-
};
|
|
57
|
+
domains: ['requisition'],
|
|
58
|
+
slots: { requisition: { mode: 'create', destination: '普吉岛', start_date: '2026-12-25', trip_type: 'round_trip' } },
|
|
59
|
+
missing_slots: [],
|
|
60
|
+
},
|
|
61
|
+
}];
|
|
62
|
+
const solvePort = ((spec) => { spec.skeletonHub = true; return solveUnified(spec); });
|
|
63
|
+
// ① 单日期段:分歧 → 拦截 + 追问 + 不求解
|
|
68
64
|
const base = createMockLlm(join('..', 'data', 'flights_2026.json'), conflictScript);
|
|
69
65
|
const singleSpecLlm = {
|
|
70
66
|
...base,
|
|
71
|
-
extractSpec: async ()=>({
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
id: 's1',
|
|
75
|
-
role: 'choice',
|
|
76
|
-
date: '2026-07-01',
|
|
77
|
-
options: [
|
|
78
|
-
{
|
|
79
|
-
id: 'o1',
|
|
80
|
-
label: 'o1',
|
|
81
|
-
move: {
|
|
82
|
-
hub: 'SZX',
|
|
83
|
-
services: [
|
|
84
|
-
{
|
|
85
|
-
id: 'f1',
|
|
86
|
-
depMin: 600,
|
|
87
|
-
arrMin: 700
|
|
88
|
-
}
|
|
89
|
-
],
|
|
90
|
-
bufferMin: 60,
|
|
91
|
-
originTransferMin: 30,
|
|
92
|
-
destTransferMin: 30
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
]
|
|
96
|
-
}
|
|
97
|
-
]
|
|
98
|
-
})
|
|
67
|
+
extractSpec: async () => ({
|
|
68
|
+
segments: [{ id: 's1', role: 'choice', date: '2026-07-01', options: [{ id: 'o1', label: 'o1', move: { hub: 'SZX', services: [{ id: 'f1', depMin: 600, arrMin: 700 }], bufferMin: 60, originTransferMin: 30, destTransferMin: 30 } }] }],
|
|
69
|
+
}),
|
|
99
70
|
};
|
|
100
71
|
const state1 = structuredClone(state);
|
|
101
72
|
const solveBefore = state1.solve;
|
|
102
|
-
const r1 = await runTurn(state1, '12月25日出发,重新算一下', singleSpecLlm, [
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
|
|
73
|
+
const r1 = await runTurn(state1, '12月25日出发,重新算一下', singleSpecLlm, [...history], solvePort);
|
|
74
|
+
if (!r1.reply.includes('日期分歧'))
|
|
75
|
+
throw new Error(`FAIL: 单日期段分歧应被闸拦下,实际:${r1.reply.slice(0, 160)}`);
|
|
76
|
+
if (r1.state.solve !== solveBefore)
|
|
77
|
+
throw new Error('FAIL: 分歧时不应求解(spec 日期未确认)');
|
|
78
|
+
// ② 多段行程:闸旁路 → 正常求解(无日期分歧文案)
|
|
107
79
|
const state2 = structuredClone(state);
|
|
108
|
-
const r2 = await runTurn(state2, '重新算一下', base, [
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (r2.
|
|
112
|
-
|
|
80
|
+
const r2 = await runTurn(state2, '重新算一下', base, [...history], solvePort);
|
|
81
|
+
if (r2.reply.includes('日期分歧'))
|
|
82
|
+
throw new Error(`FAIL: 多段行程应旁路日期闸(无逐段真值不判),实际:${r2.reply.slice(0, 160)}`);
|
|
83
|
+
if (!r2.state.solve)
|
|
84
|
+
throw new Error('FAIL: 多段旁路后应正常求解');
|
|
113
85
|
console.log('SPEC-SLOT DATE GATE OK(单日期段分歧拦截 + 多段旁路不误伤)');
|
|
114
86
|
}
|
|
115
|
-
|
|
116
|
-
//# sourceURL=ts/scripts/replay.ts
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDP attach 诊断(RFC §2.2 路线 A=primary,founder「不能匿名实例」定案):
|
|
3
|
+
* 前置=日常 Chrome 开 chrome://inspect/#remote-debugging 开关(Chrome 144+)。
|
|
4
|
+
* 输出:attach 状态 + ctrip/meituan cookie 名单(登录票据校准)+ 登录态判定。只读,不导航。
|
|
5
|
+
* 注:Chrome 147 调试服务与 playwright 不兼容(握手后悬挂,实测),传输层一律 puppeteer-core(实测 2256 cookies)。
|
|
6
|
+
*/
|
|
1
7
|
import { openSession } from '../capabilities/session/transport.js';
|
|
2
8
|
import { LOGIN_COOKIE_NAMES } from '../capabilities/session/adapters/ctrip-flight.js';
|
|
3
|
-
const t = await openSession({
|
|
4
|
-
mode: 'cdp'
|
|
5
|
-
});
|
|
9
|
+
const t = await openSession({ mode: 'cdp' });
|
|
6
10
|
if (!t.ok) {
|
|
7
11
|
console.log('ATTACH 失败:', t.summary);
|
|
8
12
|
process.exit(1);
|
|
@@ -10,18 +14,18 @@ if (!t.ok) {
|
|
|
10
14
|
try {
|
|
11
15
|
const all = await t.browser.cookies();
|
|
12
16
|
const byDom = {};
|
|
13
|
-
for (const c of all){
|
|
17
|
+
for (const c of all) {
|
|
14
18
|
const d = c.domain.replace(/^\./, '');
|
|
15
|
-
if (/ctrip\.com$|meituan\.com$/.test(d))
|
|
19
|
+
if (/ctrip\.com$|meituan\.com$/.test(d))
|
|
20
|
+
(byDom[d] ??= []).push(c.name);
|
|
16
21
|
}
|
|
17
22
|
console.log('ATTACH ok,共', all.length, '条 cookie;相关域:');
|
|
18
|
-
for (const [d, names] of Object.entries(byDom))
|
|
19
|
-
|
|
20
|
-
const
|
|
23
|
+
for (const [d, names] of Object.entries(byDom))
|
|
24
|
+
console.log(' ', d, '=>', names.sort().join(','));
|
|
25
|
+
const ctripNames = new Set(Object.entries(byDom).filter(([d]) => d.includes('ctrip')).flatMap(([, n]) => n));
|
|
26
|
+
const known = LOGIN_COOKIE_NAMES.filter((k) => ctripNames.has(k));
|
|
21
27
|
console.log(known.length > 0 ? `携程登录态:在(${known.join(',')})` : '携程登录态:未检出——在你日常 Chrome 里正常登录携程即可(无需专门窗口)');
|
|
22
|
-
}
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
23
30
|
await t.close();
|
|
24
31
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
//# sourceURL=ts/scripts/session-attach-diagnose.ts
|