@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,40 +1,188 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* T1 动态记忆的合并守门层(M4 记忆域;DeerFlow 研究 T1 落地):
|
|
3
|
+
*
|
|
4
|
+
* 分工(founder 校正「正则匹配 rules 不对」后重写):
|
|
5
|
+
* - 事实提取 = LLM 的活。契约 (18) 已要求模型当轮把对话透露的新事实
|
|
6
|
+
* (预算/日期/窗口/出发地/同伴/实际经历)经 gotry_motivation_save 并入
|
|
7
|
+
* 画像(evidence=用户原话)——语言理解交给模型,不做第二套正则引擎。
|
|
8
|
+
* - 合并守门 = 代码的活。本文件只做三件代码才可靠的事:
|
|
9
|
+
* ① 追加不删史(evidence 永不移除,P0 反幻觉:历史依据不可篡改)
|
|
10
|
+
* ② 幂等(同 evidence 不重复入池)
|
|
11
|
+
* ③ 结构守卫(weights 存在性校验、空补丁拒绝、权重归一)
|
|
12
|
+
*
|
|
13
|
+
* 额外承载(issue #338):用户显式声明的常驻城市/默认出发地——typed
|
|
14
|
+
* homeCity 字段 + 纯函数 resolveDefaultOrigin(explicit origin, profile)。
|
|
15
|
+
* - 当前轮显式出发地永远赢(explicit origin > home city > missing)
|
|
16
|
+
* - homeCity 变更必须伴新 evidence(P0 与 weights/hard 同向);单条 evidence
|
|
17
|
+
* 可作为省略 binding 的兼容形态,多条 evidence 必须显式绑定
|
|
18
|
+
* - 该契约不触碰算术/求解——只读字段,不进 feasibility/evaluate 路径
|
|
19
|
+
*
|
|
20
|
+
* 持久化语义(issue #338):home-city 是 typed self-contained preference
|
|
21
|
+
* 记录 `{ value, evidence, updated_at }`,与全局 evidence 列表解耦——
|
|
22
|
+
* 一次不相关的动机补丁不会改写它的「证据指针」「更新时间」「当前值」。
|
|
23
|
+
* `updated_at` 由调用方在事件边界注入(账本事件行的 ts),mergeProfile
|
|
24
|
+
* 自身不在 fold 路径里再读时钟——保证 rebuildProjections() 与直读投影
|
|
25
|
+
* 永不分叉。
|
|
26
|
+
*/
|
|
27
|
+
const ISO_LIKE_TIMESTAMP = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,3})?(Z|[+-]\d{2}:\d{2})$/;
|
|
28
|
+
function isNonBlankString(value) {
|
|
29
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
30
|
+
}
|
|
31
|
+
function isValidIsoLikeTimestamp(value) {
|
|
32
|
+
if (typeof value !== 'string')
|
|
33
|
+
return false;
|
|
34
|
+
const match = ISO_LIKE_TIMESTAMP.exec(value);
|
|
35
|
+
if (!match)
|
|
36
|
+
return false;
|
|
37
|
+
const year = Number(match[1]);
|
|
38
|
+
const month = Number(match[2]);
|
|
39
|
+
const day = Number(match[3]);
|
|
40
|
+
const hour = Number(match[4]);
|
|
41
|
+
const minute = Number(match[5]);
|
|
42
|
+
const second = Number(match[6]);
|
|
43
|
+
const zone = match[7];
|
|
44
|
+
const daysInMonth = month === 2
|
|
45
|
+
? (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28)
|
|
46
|
+
: [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month - 1];
|
|
47
|
+
if (!daysInMonth || day < 1 || day > daysInMonth)
|
|
48
|
+
return false;
|
|
49
|
+
// ISO permits 24:00:00 as the end-of-day spelling; no other 24:xx value.
|
|
50
|
+
if (hour > 23 && !(hour === 24 && minute === 0 && second === 0))
|
|
51
|
+
return false;
|
|
52
|
+
if (minute > 59 || second > 59)
|
|
53
|
+
return false;
|
|
54
|
+
if (zone !== 'Z' && (Number(zone.slice(1, 3)) > 23 || Number(zone.slice(4, 6)) > 59))
|
|
55
|
+
return false;
|
|
56
|
+
return Number.isFinite(Date.parse(value));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Typed home-city preference 的唯一有效性判定。
|
|
60
|
+
* 不读取、不修写 raw profile;raw homeCity 若存在只作镜像一致性校验。
|
|
61
|
+
*/
|
|
62
|
+
export function isValidHomeCityPreference(profile) {
|
|
63
|
+
const preference = profile?.homeCityPreference;
|
|
64
|
+
if (!preference || typeof preference !== 'object' || Array.isArray(preference))
|
|
65
|
+
return false;
|
|
66
|
+
const candidate = preference;
|
|
67
|
+
if (!(candidate.value === null || isNonBlankString(candidate.value)))
|
|
68
|
+
return false;
|
|
69
|
+
if (!isNonBlankString(candidate.evidence) || !isValidIsoLikeTimestamp(candidate.updated_at))
|
|
70
|
+
return false;
|
|
71
|
+
if (!profile || !Array.isArray(profile.evidence) || !profile.evidence.some(entry => entry === candidate.evidence))
|
|
72
|
+
return false;
|
|
73
|
+
if (profile && Object.prototype.hasOwnProperty.call(profile, 'homeCity') && profile.homeCity !== candidate.value)
|
|
74
|
+
return false;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 合并守门。纯函数;不读时钟——`now` 由调用方从事件边界(appendMotivationPatch
|
|
79
|
+
* 写时 ISO 或 foldEvent 重放时 row.ts)注入,保证写路径与重建路径时间戳一致。
|
|
80
|
+
*
|
|
81
|
+
* 触发 homeCity 操作的同时,会原地维护 typed homeCityPreference:
|
|
82
|
+
* - valid new binding → 新 `{value, evidence: <homeCityEvidence exact string>, updated_at: now}`
|
|
83
|
+
* - unchanged → 沿用 base 的 homeCityPreference(若有);缺失 typed 字段保持缺失
|
|
84
|
+
* - missing/mismatched/stale binding → 返回 null,由账本跳过整次事件
|
|
85
|
+
*/
|
|
86
|
+
export function mergeProfile(current, patch, now) {
|
|
87
|
+
if (!patch)
|
|
88
|
+
return null;
|
|
3
89
|
const base = {
|
|
4
|
-
weights: current?.weights ?? {},
|
|
5
|
-
evidence: current?.evidence ?? [],
|
|
6
|
-
hard: current?.hard ?? {}
|
|
7
|
-
|
|
8
|
-
|
|
90
|
+
weights: (current?.weights ?? {}),
|
|
91
|
+
evidence: (current?.evidence ?? []),
|
|
92
|
+
hard: (current?.hard ?? {}),
|
|
93
|
+
homeCity: (current?.homeCity === undefined ? undefined : current.homeCity),
|
|
94
|
+
homeCityPreference: current?.homeCityPreference,
|
|
95
|
+
}; // 首次保存:无档案即空档案
|
|
96
|
+
const newEvidence = (patch.evidence ?? []).filter(Boolean).filter(e => !base.evidence.includes(e));
|
|
9
97
|
const patchWeights = patch.weights;
|
|
10
|
-
const weightsChanged = !!patchWeights && Object.keys(patchWeights).length > 0 &&
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
98
|
+
const weightsChanged = !!patchWeights && Object.keys(patchWeights).length > 0 &&
|
|
99
|
+
JSON.stringify(patchWeights) !== JSON.stringify(base.weights);
|
|
100
|
+
const hardChanged = !!patch.hard && Object.keys(patch.hard).length > 0 &&
|
|
101
|
+
JSON.stringify(patch.hard) !== JSON.stringify(base.hard);
|
|
102
|
+
// homeCity 变更判定:
|
|
103
|
+
// patch.homeCity === undefined → 字段未传,不视为变更
|
|
104
|
+
// string 先 trim;trim 后空白 → 视作「未传」(避免把空白值当清除语义或无意义值写入)
|
|
105
|
+
// trim 后与 base.homeCity 仍不等 → 视为变更(包括 string↔null、null↔undefined 等差异)
|
|
106
|
+
let patchedHomeCityInput = patch.homeCity;
|
|
107
|
+
if (typeof patchedHomeCityInput === 'string') {
|
|
108
|
+
const trimmed = patchedHomeCityInput.trim();
|
|
109
|
+
patchedHomeCityInput = trimmed.length === 0 ? undefined : trimmed;
|
|
110
|
+
}
|
|
111
|
+
const homeCityTouched = patchedHomeCityInput !== undefined;
|
|
112
|
+
const homeCityChanged = homeCityTouched && patchedHomeCityInput !== base.homeCity;
|
|
113
|
+
if (!homeCityTouched && patch.homeCityEvidence !== undefined)
|
|
114
|
+
return null;
|
|
115
|
+
// homeCity 的语义绑定必须在 profile patch 边界明确给出,不从自然语言或
|
|
116
|
+
// evidence 数组位置推断。唯一兼容例外:本次只有一条非空 evidence 时,
|
|
117
|
+
// 该条本身就是 unambiguous binding;多条 evidence 仍必须显式命名。
|
|
118
|
+
let homeCityEvidence;
|
|
119
|
+
let homeCityEvidenceIsNew = false;
|
|
120
|
+
if (homeCityTouched) {
|
|
121
|
+
const evidenceEntries = patch.evidence ?? [];
|
|
122
|
+
const candidate = patch.homeCityEvidence !== undefined
|
|
123
|
+
? patch.homeCityEvidence
|
|
124
|
+
: evidenceEntries.length === 1 && isNonBlankString(evidenceEntries[0])
|
|
125
|
+
? evidenceEntries[0]
|
|
126
|
+
: undefined;
|
|
127
|
+
const appearsInCall = isNonBlankString(candidate) && evidenceEntries.some(e => e === candidate);
|
|
128
|
+
homeCityEvidenceIsNew = appearsInCall && !base.evidence.includes(candidate);
|
|
129
|
+
const exactDuplicate = appearsInCall && !homeCityEvidenceIsNew && !homeCityChanged
|
|
130
|
+
&& base.homeCityPreference?.value === patchedHomeCityInput
|
|
131
|
+
&& base.homeCityPreference?.evidence === candidate;
|
|
132
|
+
if (!appearsInCall || (!homeCityEvidenceIsNew && !exactDuplicate))
|
|
133
|
+
return null;
|
|
134
|
+
homeCityEvidence = candidate;
|
|
135
|
+
}
|
|
136
|
+
// A same-city/clear operation with a new bound quote is a real preference
|
|
137
|
+
// update even though the value itself did not change. The exact duplicate
|
|
138
|
+
// above remains a no-op.
|
|
139
|
+
const homeCityPreferenceChanged = homeCityTouched && homeCityEvidenceIsNew;
|
|
140
|
+
if (newEvidence.length === 0 && !weightsChanged && !hardChanged && !homeCityChanged && !homeCityPreferenceChanged)
|
|
141
|
+
return null;
|
|
142
|
+
// 权重变更必须伴至少一条新 evidence(P0:改画像要有依据),否则拒该部分
|
|
143
|
+
let weights = { ...base.weights };
|
|
16
144
|
if (weightsChanged && newEvidence.length > 0 && patchWeights) {
|
|
17
|
-
weights = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
145
|
+
weights = { ...weights, ...patchWeights };
|
|
146
|
+
const sum = Object.values(weights).reduce((a, b) => a + b, 0);
|
|
147
|
+
if (sum > 0)
|
|
148
|
+
for (const k of Object.keys(weights))
|
|
149
|
+
weights[k] = Math.round((weights[k] / sum) * 100) / 100;
|
|
150
|
+
}
|
|
151
|
+
// homeCity 操作只接受上面验证过的 exact homeCityEvidence 绑定;无关 evidence
|
|
152
|
+
// 可以继续追加到全局池,但绝不会成为 homeCityPreference 的语义指针。
|
|
153
|
+
let homeCity = base.homeCity;
|
|
154
|
+
let homeCityPreference = base.homeCityPreference;
|
|
155
|
+
if (homeCityPreferenceChanged) {
|
|
156
|
+
homeCity = patchedHomeCityInput ?? null;
|
|
157
|
+
if (homeCityEvidence !== undefined) {
|
|
158
|
+
homeCityPreference = { value: homeCity, evidence: homeCityEvidence, updated_at: now };
|
|
159
|
+
}
|
|
23
160
|
}
|
|
24
161
|
return {
|
|
25
162
|
weights,
|
|
26
|
-
evidence: [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
hard: hardChanged ? {
|
|
31
|
-
...base.hard,
|
|
32
|
-
...patch.hard ?? {}
|
|
33
|
-
} : {
|
|
34
|
-
...base.hard
|
|
35
|
-
}
|
|
163
|
+
evidence: [...base.evidence, ...newEvidence],
|
|
164
|
+
hard: hardChanged ? { ...base.hard, ...(patch.hard ?? {}) } : { ...base.hard },
|
|
165
|
+
homeCity,
|
|
166
|
+
homeCityPreference,
|
|
36
167
|
};
|
|
37
168
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
169
|
+
export function resolveDefaultOrigin(currentTripOrigin, profile) {
|
|
170
|
+
const trimmed = typeof currentTripOrigin === 'string' ? currentTripOrigin.trim() : '';
|
|
171
|
+
const validTypedPreference = isValidHomeCityPreference(profile);
|
|
172
|
+
const preference = validTypedPreference ? profile?.homeCityPreference : undefined;
|
|
173
|
+
const typedValue = preference?.value;
|
|
174
|
+
const homeCity = validTypedPreference ? typedValue : undefined;
|
|
175
|
+
if (trimmed) {
|
|
176
|
+
return { origin: trimmed, source: 'explicit', homeCity, homeCityPreferenceSource: 'none' };
|
|
177
|
+
}
|
|
178
|
+
if (validTypedPreference && typeof typedValue === 'string') {
|
|
179
|
+
return {
|
|
180
|
+
origin: typedValue.trim(),
|
|
181
|
+
source: 'home_default',
|
|
182
|
+
homeCity,
|
|
183
|
+
homeCityEvidence: [preference.evidence],
|
|
184
|
+
homeCityPreferenceSource: 'typed',
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return { origin: null, source: 'missing', homeCity, homeCityPreferenceSource: 'none' };
|
|
188
|
+
}
|
package/dist/src/memory-decay.js
CHANGED
|
@@ -1,31 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 时间窗衰减原语(memory-design P3):行为偏好的新鲜度置信度——
|
|
3
|
+
* 30/90/180/365d 分级窗口,确定性纯函数;**只降不删**(历史事件永远在,
|
|
4
|
+
* 衰减只作用于读时置信度);地板 0.1(记忆永不因旧而消失)。
|
|
5
|
+
*
|
|
6
|
+
* 边界(memory-design §4 P3):衰减只作用于**行为事件**(效用 sidecar 等);
|
|
7
|
+
* 动机权重层零衰减——动机跨年稳定是产品设计 §4 的明文(个性化的锚点),
|
|
8
|
+
* 本模块不提供任何作用于 motivation-profile 的 API(构造性保证)。
|
|
9
|
+
*
|
|
10
|
+
* 未来消费方(行为偏好层落地时):同原语直接复用,窗口即配置。
|
|
11
|
+
*/
|
|
12
|
+
/** 分级窗口:age(天)→ 因子;单调不增,地板 0.1(只降不删) */
|
|
1
13
|
export function windowFactor(ageDays) {
|
|
2
|
-
if (ageDays <= 30)
|
|
3
|
-
|
|
4
|
-
if (ageDays <=
|
|
5
|
-
|
|
14
|
+
if (ageDays <= 30)
|
|
15
|
+
return 1.0;
|
|
16
|
+
if (ageDays <= 90)
|
|
17
|
+
return 0.75;
|
|
18
|
+
if (ageDays <= 180)
|
|
19
|
+
return 0.5;
|
|
20
|
+
if (ageDays <= 365)
|
|
21
|
+
return 0.25;
|
|
6
22
|
return 0.1;
|
|
7
23
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
applied: 0.5,
|
|
11
|
-
verified_outcome: 1.0
|
|
12
|
-
};
|
|
24
|
+
/** 事件种类权重:verified_outcome 最强,recalled 最弱(自称被召回 ≠ 有用) */
|
|
25
|
+
export const KIND_WEIGHT = { recalled: 0.25, applied: 0.5, verified_outcome: 1.0 };
|
|
13
26
|
export function ageDaysOf(ts, now) {
|
|
14
27
|
const then = new Date(ts).getTime();
|
|
15
|
-
if (Number.isNaN(then))
|
|
28
|
+
if (Number.isNaN(then))
|
|
29
|
+
return Number.POSITIVE_INFINITY;
|
|
16
30
|
return Math.max(0, (now.getTime() - then) / 86_400_000);
|
|
17
31
|
}
|
|
32
|
+
/** 单事件衰减分:KIND_WEIGHT × windowFactor;未知时间戳按地板(不猜) */
|
|
18
33
|
export function eventDecayScore(ev, now) {
|
|
19
34
|
const w = KIND_WEIGHT[ev.kind] ?? 0;
|
|
20
35
|
return round4(w * windowFactor(ageDaysOf(ev.ts, now)));
|
|
21
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* 单条记忆的新鲜置信度 ∈ [0,1]:Σ 事件衰减分,上界 1。
|
|
39
|
+
* 同 wish 同窗口内事件越多置信越高(有界);旧事件只做地板贡献。
|
|
40
|
+
*/
|
|
22
41
|
export function decayedConfidence(events, now) {
|
|
23
|
-
const sum = events.reduce((acc, ev)=>acc + eventDecayScore(ev, now), 0);
|
|
42
|
+
const sum = events.reduce((acc, ev) => acc + eventDecayScore(ev, now), 0);
|
|
24
43
|
return round4(Math.min(1, sum));
|
|
25
44
|
}
|
|
26
45
|
function round4(x) {
|
|
27
46
|
return Math.round(x * 10_000) / 10_000;
|
|
28
47
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
//# sourceURL=ts/src/memory-decay.ts
|