@danceiny/gotry 0.0.1-rc.15 → 0.0.1-rc.17
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 +51 -13
- package/README.zh-CN.md +26 -12
- package/bin/gotry-booking-copilot.js +53 -0
- package/bin/gotry-bootstrap.js +357 -8
- package/bin/gotry-inner.js +442 -60
- package/bin/gotry-runtime-resolution.d.ts +27 -0
- package/bin/gotry-runtime-resolution.js +50 -0
- package/bin/gotry.js +1 -1
- package/cordis.gotry-patch.yml +15 -1
- package/data/airline-airports.json +39 -0
- package/dist/capabilities/agent-reach-deep.js +1 -1
- package/dist/capabilities/agent-reach.js +1 -1
- package/dist/capabilities/anything.js +1 -1
- package/dist/capabilities/artifacts.js +1 -1
- package/dist/capabilities/effect.js +293 -0
- package/dist/capabilities/fact-log.js +41 -0
- package/dist/capabilities/flyai.js +20 -6
- package/dist/capabilities/hbcli.js +43 -1
- package/dist/capabilities/incident-log.js +1 -1
- package/dist/capabilities/model-override.js +18 -0
- package/dist/capabilities/opensky.js +1 -1
- package/dist/capabilities/resilience.js +90 -0
- package/dist/capabilities/session/action-cache.js +1 -1
- package/dist/capabilities/session/adapters/ctrip-flight.js +1 -1
- package/dist/capabilities/session/adapters/meituan-local.js +1 -1
- package/dist/capabilities/session/benchmark.js +2 -1
- package/dist/capabilities/session/extension-bridge.js +358 -0
- package/dist/capabilities/session/extension-channel.js +93 -0
- package/dist/capabilities/session/extension-distribution.js +234 -0
- package/dist/capabilities/session/extract.js +1 -1
- package/dist/capabilities/session/golden-score.js +92 -0
- package/dist/capabilities/session/health-watch.js +216 -0
- package/dist/capabilities/session/read-guard.js +1 -1
- package/dist/capabilities/session/static-flight-golden.js +137 -0
- package/dist/capabilities/session/transport.js +1 -1
- package/dist/capabilities/session/wizard.js +147 -0
- package/dist/capabilities/session-consent.js +1 -1
- package/dist/capabilities/session-login.js +83 -1
- package/dist/capabilities/session-search.js +111 -2
- package/dist/capabilities/weather.js +168 -46
- package/dist/data/session-golden-20.json +25 -0
- package/dist/data/sf-golden-manifest.json +102 -0
- package/dist/data/sf-static-routes.json +91 -0
- package/dist/scripts/action-cache-tests.js +1 -1
- package/dist/scripts/agent-planning-budget-e2e.js +227 -0
- package/dist/scripts/agent-planning-budget-tests.js +173 -0
- package/dist/scripts/agent-reach-deep-tests.js +1 -1
- package/dist/scripts/agent-reach-tests.js +1 -1
- package/dist/scripts/agent-reach-wrapper-tests.js +1 -1
- package/dist/scripts/anything-tests.js +1 -1
- package/dist/scripts/async-collect.js +1 -1
- package/dist/scripts/benchmark-environment-bridge-e2e.js +981 -0
- package/dist/scripts/benchmark-environment-bridge-tests.js +2544 -0
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +335 -0
- package/dist/scripts/booking-copilot-availability-policy-v2-tests.js +1355 -0
- package/dist/scripts/booking-copilot-bin-proof-tests.js +89 -0
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +113 -0
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +356 -0
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +557 -0
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +140 -0
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +202 -0
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +102 -0
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +374 -0
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +447 -0
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +205 -0
- package/dist/scripts/booking-copilot-server-proof-tests.js +317 -0
- package/dist/scripts/booking-copilot-startup-proof-tests.js +283 -0
- package/dist/scripts/booking-copilot-v2-runtime-proof-tests.js +3935 -0
- package/dist/scripts/booking-saga-tests.js +1 -1
- package/dist/scripts/booking-surface-contract-proof-tests.js +393 -0
- package/dist/scripts/booking-surface-v2-contract-proof-tests.js +1174 -0
- package/dist/scripts/bootstrap-tests.js +59 -3
- package/dist/scripts/build-changelog.js +279 -0
- package/dist/scripts/changelog-tests.js +165 -0
- package/dist/scripts/companion-tests.js +1 -1
- package/dist/scripts/diff-test.js +1 -1
- package/dist/scripts/dsh-runtime-closure-tests.js +225 -0
- package/dist/scripts/dsh-runtime-closure.js +150 -0
- package/dist/scripts/effect-tests.js +474 -0
- package/dist/scripts/engine-run.js +1 -1
- package/dist/scripts/engine-tests.js +1 -1
- package/dist/scripts/evaluation-cadence-tests.js +347 -0
- package/dist/scripts/evaluation-contract-tests.js +574 -0
- package/dist/scripts/extension-distribution-cli.js +35 -0
- package/dist/scripts/extension-distribution-tests.js +341 -0
- package/dist/scripts/extension-tests.js +573 -0
- package/dist/scripts/fact-gate-tests.js +318 -0
- package/dist/scripts/flyai-tests.js +1 -1
- package/dist/scripts/hbcli-e2e-tests.js +180 -0
- package/dist/scripts/hbcli-tests.js +1 -1
- package/dist/scripts/health-watch-cli.js +51 -0
- package/dist/scripts/i18n-tests.js +1 -1
- package/dist/scripts/incident-tests.js +1 -1
- package/dist/scripts/journey-tests.js +1 -1
- package/dist/scripts/ledger-tests.js +1 -1
- package/dist/scripts/ledger-workflow-crash.js +1 -1
- package/dist/scripts/memory-capture-tests.js +1 -1
- package/dist/scripts/memory-decay-tests.js +1 -1
- package/dist/scripts/memory-metrics.js +1 -1
- package/dist/scripts/memory-value-report.js +1 -1
- package/dist/scripts/model-override-e2e.js +176 -0
- package/dist/scripts/nightly-evidence-tests.js +67 -4
- package/dist/scripts/nightly-evidence.js +59 -3
- package/dist/scripts/nudge-digest.js +1 -1
- package/dist/scripts/onboarding-tests.js +186 -0
- package/dist/scripts/opensky-check.js +1 -1
- package/dist/scripts/opensky-tests.js +1 -1
- package/dist/scripts/pnpm-dsh-closure-proof.js +20 -0
- package/dist/scripts/price-drift-tests.js +441 -0
- package/dist/scripts/price-drift-watch.js +491 -0
- package/dist/scripts/probe-poi-tests.js +1 -1
- package/dist/scripts/product-metrics.js +1 -1
- package/dist/scripts/publish-preverify.js +40 -4
- package/dist/scripts/realtime-pricing-tests.js +1 -1
- package/dist/scripts/replay-async.js +1 -1
- package/dist/scripts/replay-real.js +1 -1
- package/dist/scripts/replay.js +1 -1
- package/dist/scripts/session-attach-diagnose.js +1 -1
- package/dist/scripts/session-attach-poc.js +1 -1
- package/dist/scripts/session-benchmark.js +1 -1
- package/dist/scripts/session-extract-tests.js +1 -1
- package/dist/scripts/session-login.js +1 -1
- package/dist/scripts/session-tests.js +70 -20
- package/dist/scripts/sf-live-benchmark.js +338 -0
- package/dist/scripts/sf-live-cli-tests.js +21 -0
- package/dist/scripts/sf-soft-score-tests.js +108 -0
- package/dist/scripts/sf-summary.js +93 -0
- package/dist/scripts/skeleton-check.js +1 -1
- package/dist/scripts/skeleton-integration-test.js +1 -1
- package/dist/scripts/skills-contract-tests.js +1 -1
- package/dist/scripts/smoke-session-gate-tests.js +29 -0
- package/dist/scripts/smoke.js +154 -33
- package/dist/scripts/state-cli-tests.js +1 -1
- package/dist/scripts/state-cli.js +1 -1
- package/dist/scripts/static-golden-tests.js +299 -0
- package/dist/scripts/time-eval-tests.js +1 -1
- package/dist/scripts/travel-timeline-tests.js +1 -1
- package/dist/scripts/unified-tests.js +1 -1
- package/dist/scripts/weather-tests.js +694 -44
- package/dist/scripts/z3-race-tests.js +1 -1
- package/dist/src/artifact-gate.js +310 -0
- package/dist/src/benchmark-agent-conformance.js +370 -0
- package/dist/src/benchmark-environment-bridge.js +384 -0
- package/dist/src/benchmark-headless-child-diagnostics.js +173 -0
- package/dist/src/benchmark-tool-isolation.js +124 -0
- package/dist/src/bookable-facts.js +349 -0
- package/dist/src/booking-saga.js +1 -1
- package/dist/src/booking-surface/availability-policy-v2.js +830 -0
- package/dist/src/booking-surface/canonical-schema.js +113 -0
- package/dist/src/booking-surface/contracts-v2.js +89 -0
- package/dist/src/booking-surface/contracts.js +46 -0
- package/dist/src/booking-surface/dsh-planner.js +453 -0
- package/dist/src/booking-surface/dsh-plugin.js +93 -0
- package/dist/src/booking-surface/error-codes.js +94 -0
- package/dist/src/booking-surface/index.js +15 -0
- package/dist/src/booking-surface/profile.js +68 -0
- package/dist/src/booking-surface/runtime-v2.js +1771 -0
- package/dist/src/booking-surface/runtime.js +351 -0
- package/dist/src/booking-surface/server-v2.js +334 -0
- package/dist/src/booking-surface/server.js +302 -0
- package/dist/src/booking-surface/startup.js +159 -0
- package/dist/src/booking-surface/validation-v2.js +319 -0
- package/dist/src/booking-surface/validation.js +809 -0
- package/dist/src/bridge.js +1 -1
- package/dist/src/companions.js +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/dsh-llm.js +1 -1
- package/dist/src/engine.js +1 -1
- package/dist/src/evaluation-cadence.js +234 -0
- package/dist/src/evaluation-contracts.js +906 -0
- package/dist/src/i18n.js +1 -1
- package/dist/src/index.js +234 -60
- package/dist/src/journey.js +1 -1
- package/dist/src/loop.js +1 -1
- package/dist/src/memory-capture.js +1 -1
- package/dist/src/memory-decay.js +1 -1
- package/dist/src/memory-utility.js +1 -1
- package/dist/src/mock-llm.js +1 -1
- package/dist/src/model.js +1 -1
- package/dist/src/realtime-pricing.js +14 -7
- package/dist/src/slot-spec.js +1 -1
- package/dist/src/state-ledger.js +2 -1
- package/dist/src/time-anchor.js +1 -1
- package/dist/src/tool-budget.js +136 -0
- package/dist/src/tool-packet.js +1 -1
- package/dist/src/travel-slots.js +1 -1
- package/dist/src/travel-timeline.js +1 -1
- package/dist/src/unified.js +1 -1
- package/dist/src/wish-pool.js +1 -1
- package/dist/src/z3-shared.js +1 -1
- package/extension/README.md +50 -0
- package/extension/background.js +160 -0
- package/extension/content-bridge.js +41 -0
- package/extension/content-main.js +62 -0
- package/extension/manifest.json +32 -0
- package/package.json +291 -12
- package/schemas/booking.surface.v1.schema.json +927 -0
- package/schemas/booking.surface.v2.schema.json +61 -0
- package/ts/capabilities/fact-log.ts +54 -0
- package/ts/capabilities/flyai.ts +16 -3
- package/ts/capabilities/hbcli.ts +46 -0
- package/ts/capabilities/session/benchmark.ts +4 -1
- package/ts/capabilities/session/extension-bridge.ts +377 -0
- package/ts/capabilities/session/extension-channel.ts +95 -0
- package/ts/capabilities/session/extension-distribution.ts +264 -0
- package/ts/capabilities/session/golden-score.ts +139 -0
- package/ts/capabilities/session/health-watch.ts +257 -0
- package/ts/capabilities/session/static-flight-golden.ts +209 -0
- package/ts/capabilities/session/wizard.ts +140 -0
- package/ts/capabilities/session-login.ts +63 -2
- package/ts/capabilities/session-search.ts +105 -3
- package/ts/capabilities/weather.ts +141 -52
- package/ts/package.json +3 -3
- package/ts/src/artifact-gate.ts +365 -0
- package/ts/src/benchmark-agent-conformance.ts +448 -0
- package/ts/src/benchmark-environment-bridge.ts +348 -0
- package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
- package/ts/src/benchmark-tool-isolation.ts +166 -0
- package/ts/src/bookable-facts.ts +557 -0
- package/ts/src/booking-surface/availability-policy-v2.ts +523 -0
- package/ts/src/booking-surface/canonical-schema.js +113 -0
- package/ts/src/booking-surface/contracts-v2.ts +118 -0
- package/ts/src/booking-surface/contracts.ts +380 -0
- package/ts/src/booking-surface/dsh-planner.ts +452 -0
- package/ts/src/booking-surface/dsh-plugin.js +93 -0
- package/ts/src/booking-surface/error-codes.ts +101 -0
- package/ts/src/booking-surface/index.ts +12 -0
- package/ts/src/booking-surface/profile.ts +42 -0
- package/ts/src/booking-surface/runtime-v2.ts +1466 -0
- package/ts/src/booking-surface/runtime.ts +483 -0
- package/ts/src/booking-surface/server-v2.ts +247 -0
- package/ts/src/booking-surface/server.ts +324 -0
- package/ts/src/booking-surface/startup.ts +196 -0
- package/ts/src/booking-surface/validation-v2.ts +205 -0
- package/ts/src/booking-surface/validation.ts +453 -0
- package/ts/src/index.ts +161 -14
- package/ts/src/state-ledger.ts +1 -0
- package/ts/src/tool-budget.ts +165 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://gotry.dev/schemas/booking.surface.v2.schema.json",
|
|
4
|
+
"oneOf": [
|
|
5
|
+
{"$ref":"#/$defs/Workspace"},{"$ref":"#/$defs/Action"},{"$ref":"#/$defs/Receipt"},
|
|
6
|
+
{"$ref":"#/$defs/Ingress"},{"$ref":"#/$defs/UserTurn"},{"$ref":"#/$defs/Continuation"},{"$ref":"#/$defs/Event"}
|
|
7
|
+
],
|
|
8
|
+
"$defs": {
|
|
9
|
+
"Ref":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/OpaqueRef"},
|
|
10
|
+
"Hex64":{"type":"string","pattern":"^[0-9a-f]{64}$"},
|
|
11
|
+
"Surface":{"enum":["tenant","customer_portal","storefront","payment_link"]},
|
|
12
|
+
"Kind":{"enum":["search.patch","search.run","results.view.patch","hotel.focus","hotel.select","offers.query","offers.view.patch","offers.compare","offer.select","offer.check","checkout.prepare","order.observe"]},
|
|
13
|
+
"Codes":{"type":"array","minItems":0,"maxItems":28,"uniqueItems":true,"items":{"enum":["byos_mapped_risk","check_avail_failed","check_avail_unverified","component_executor_unavailable","hotel_not_visible","hotel_rates_failed","offer_facts_changed","offer_not_loaded","offer_unavailable","order_not_found","order_outcome_not_observed","order_state_unknown","order_status_unavailable","requested_offers_not_loaded","search_failed","search_form_invalid","search_session_expired","search_terminal_timeout","stale_revision","surface_adapter_failed","undo_token_not_found","unhandled","unsupported","verified_offer_required","workspace_changed_during_action","criterion_must_not_met","no_hotels_matched","offer_target_not_reached"]}},
|
|
14
|
+
"LoadedOffer":{"type":"object","additionalProperties":false,"required":["offerRef","offerVersionRef","hotelRef","evidenceLevel","factRefs"],"properties":{"offerRef":{"$ref":"#/$defs/Ref"},"offerVersionRef":{"$ref":"#/$defs/Ref"},"hotelRef":{"$ref":"#/$defs/Ref"},"evidenceLevel":{"enum":["listed","rate_loaded","checked"]},"factRefs":{"type":"array","maxItems":64,"uniqueItems":true,"items":{"$ref":"#/$defs/Ref"}}}},
|
|
15
|
+
"VerifiedOffer":{"type":"object","additionalProperties":false,"required":["offerRef","offerVersionRef","verifiedOfferRef","expiresAt"],"properties":{"offerRef":{"$ref":"#/$defs/Ref"},"offerVersionRef":{"$ref":"#/$defs/Ref"},"verifiedOfferRef":{"$ref":"#/$defs/Ref"},"expiresAt":{"type":"string","pattern":"^\\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\\d|3[01])T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d{1,9})?(?:Z|[+-](?:[01]\\d|2[0-3]):[0-5]\\d)$"}}},
|
|
16
|
+
"OfferVersionInput":{"type":"object","additionalProperties":false,"required":["offerRef","offerVersionRef"],"properties":{"offerRef":{"$ref":"#/$defs/Ref"},"offerVersionRef":{"$ref":"#/$defs/Ref"}}},
|
|
17
|
+
"CheckoutPrepareVersionInput":{"type":"object","additionalProperties":false,"required":["offerRef","offerVersionRef","verifiedOfferRef"],"properties":{"offerRef":{"$ref":"#/$defs/Ref"},"offerVersionRef":{"$ref":"#/$defs/Ref"},"verifiedOfferRef":{"$ref":"#/$defs/Ref"}}},
|
|
18
|
+
"Workspace":{"type":"object","additionalProperties":false,"required":["schemaVersion","contextRef","surface","revision","locale","currency","searchDraft","results","visibleHotels","loadedOffers","shortlistedOfferRefs","capabilities"],"properties":{"schemaVersion":{"const":"booking.surface.v2"},"contextRef":{"$ref":"#/$defs/Ref"},"surface":{"$ref":"#/$defs/Surface"},"revision":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/Revision"},"locale":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/NonEmptyString"},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"searchDraft":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/SearchDraftSnapshotV1"},"results":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/ResultViewSnapshotV1"},"visibleHotels":{"type":"array","maxItems":100,"items":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/VisibleHotelFactV1"}},"loadedOffers":{"type":"array","maxItems":200,"items":{"$ref":"#/$defs/LoadedOffer"}},"focusedHotelRef":{"$ref":"#/$defs/Ref"},"shortlistedOfferRefs":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"$ref":"#/$defs/Ref"}},"selectedOfferRef":{"$ref":"#/$defs/Ref"},"verifiedOffer":{"$ref":"#/$defs/VerifiedOffer"},"capabilities":{"type":"object","additionalProperties":false,"required":["surface","allowedActions"],"properties":{"surface":{"$ref":"#/$defs/Surface"},"allowedActions":{"type":"array","minItems":1,"maxItems":12,"uniqueItems":true,"items":{"$ref":"#/$defs/Kind"}}}}}},
|
|
19
|
+
"IngressWorkspace":{"type":"object","additionalProperties":false,"required":["schemaVersion","revision","locale","currency","searchDraft","results","visibleHotels","loadedOffers","shortlistedOfferRefs"],"properties":{"schemaVersion":{"const":"booking.surface.v2"},"revision":{"type":"integer","minimum":0},"locale":{"type":"string","minLength":1,"maxLength":64},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"searchDraft":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/SearchDraftSnapshotV1"},"results":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/ResultViewSnapshotV1"},"visibleHotels":{"type":"array","maxItems":100,"items":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/VisibleHotelFactV1"}},"loadedOffers":{"type":"array","maxItems":200,"items":{"$ref":"#/$defs/LoadedOffer"}},"focusedHotelRef":{"$ref":"#/$defs/Ref"},"shortlistedOfferRefs":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"$ref":"#/$defs/Ref"}},"selectedOfferRef":{"$ref":"#/$defs/Ref"}}},
|
|
20
|
+
"PresentationKey":{"type":"string","minLength":1,"maxLength":512},
|
|
21
|
+
"RequestKey":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9:._-]{7,127}$"},
|
|
22
|
+
"ApprovalRef":{"type":"object","additionalProperties":false,"required":["approvalId","blockerId","contextRef","sourceTurnId","presentationRequestKey","sourceActionId","targetActionId","sourceRevision","targetActionKind","to","expiresAt","nonce","sourceReceiptDigest","scope","code","criterionPath","valueDigest"],"properties":{"approvalId":{"$ref":"#/$defs/Ref"},"blockerId":{"$ref":"#/$defs/Ref"},"contextRef":{"$ref":"#/$defs/Ref"},"sourceTurnId":{"$ref":"#/$defs/Ref"},"presentationRequestKey":{"$ref":"#/$defs/PresentationKey"},"sourceActionId":{"$ref":"#/$defs/Ref"},"targetActionId":{"$ref":"#/$defs/Ref"},"sourceRevision":{"type":"integer","minimum":0},"targetActionKind":{"$ref":"#/$defs/Kind"},"to":{"enum":["prefer","drop"]},"expiresAt":{"type":"string","minLength":1},"nonce":{"$ref":"#/$defs/Ref"},"sourceReceiptDigest":{"$ref":"#/$defs/Hex64"},"scope":{"enum":["search","offer","availability","checkout"]},"code":{"enum":["no_hotels_matched","hotel_not_visible","hotel_rates_failed","criterion_must_not_met","offer_target_not_reached","offer_unavailable"]},"criterionPath":{"type":"string","pattern":"^(searchDraft|results|offers|checkout)(\\.[A-Za-z][A-Za-z0-9_]*){0,3}$","maxLength":160},"valueDigest":{"$ref":"#/$defs/Hex64"}}},
|
|
23
|
+
"ActionBase":{"type":"object","additionalProperties":false,"required":["schemaVersion","kind","actionId","contextRef","expectedRevision","reason","factRefs","input"],"properties":{"schemaVersion":{"const":"booking.surface.v2"},"kind":{"$ref":"#/$defs/Kind"},"actionId":{"$ref":"#/$defs/Ref"},"contextRef":{"$ref":"#/$defs/Ref"},"expectedRevision":{"type":"integer","minimum":0},"reason":{"type":"string","minLength":1,"maxLength":1000},"factRefs":{"type":"array","maxItems":64,"uniqueItems":true,"items":{"$ref":"#/$defs/Ref"}},"input":{"type":"object"},"relaxationApprovalRef":{"$ref":"#/$defs/ApprovalRef"}}},
|
|
24
|
+
"Action":{"oneOf":[
|
|
25
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"search.patch"},"input":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/SearchPatchInputV1"}}}]},
|
|
26
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"search.run"},"input":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/SearchRunInputV1"}}}]},
|
|
27
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"results.view.patch"},"input":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/ResultsViewPatchInputV1"}}}]},
|
|
28
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"hotel.focus"},"input":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/HotelFocusInputV1"}}}]},
|
|
29
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"hotel.select"},"input":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/HotelSelectInputV1"}}}]},
|
|
30
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"offers.query"},"input":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/OffersQueryInputV1"}}}]},
|
|
31
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"offers.view.patch"},"input":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/OffersViewPatchInputV1"}}}]},
|
|
32
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"offers.compare"},"input":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/OffersCompareInputV1"}}}]},
|
|
33
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"offer.select"},"input":{"$ref":"#/$defs/OfferVersionInput"}}}]},
|
|
34
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"offer.check"},"input":{"$ref":"#/$defs/OfferVersionInput"}}}]},
|
|
35
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"checkout.prepare"},"input":{"$ref":"#/$defs/CheckoutPrepareVersionInput"}}}]},
|
|
36
|
+
{"allOf":[{"$ref":"#/$defs/ActionBase"},{"type":"object","properties":{"kind":{"const":"order.observe"},"input":{"$ref":"https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/OrderObserveInputV1"}}}]}
|
|
37
|
+
]},
|
|
38
|
+
"Approval":{"type":"object","additionalProperties":false,"required":["taskId","contextRef","sourceTurnId","presentationRequestKey","optionDigest","approvalId","deliveryNonce","blockerId","sourceActionId","sourceReceiptDigest","scope","code","criterionPath","valueDigest","from","to","approved"],"properties":{"taskId":{"$ref":"#/$defs/Ref"},"contextRef":{"$ref":"#/$defs/Ref"},"sourceTurnId":{"$ref":"#/$defs/Ref"},"presentationRequestKey":{"$ref":"#/$defs/PresentationKey"},"optionDigest":{"$ref":"#/$defs/Hex64"},"approvalId":{"$ref":"#/$defs/Ref"},"deliveryNonce":{"$ref":"#/$defs/Ref"},"blockerId":{"$ref":"#/$defs/Ref"},"sourceActionId":{"$ref":"#/$defs/Ref"},"sourceReceiptDigest":{"$ref":"#/$defs/Hex64"},"scope":{"enum":["search","offer","availability","checkout"]},"code":{"enum":["no_hotels_matched","hotel_not_visible","hotel_rates_failed","criterion_must_not_met","offer_target_not_reached","offer_unavailable"]},"criterionPath":{"type":"string","pattern":"^(searchDraft|results|offers|checkout)(\\.[A-Za-z][A-Za-z0-9_]*){0,3}$","maxLength":160},"valueDigest":{"$ref":"#/$defs/Hex64"},"from":{"const":"must"},"to":{"enum":["prefer","drop"]},"approved":{"const":true}}},
|
|
39
|
+
"Blocker":{"type":"object","additionalProperties":false,"required":["blockerId","sourceActionId","sourceReceiptDigest","scope","code","criterionPath","strength","valueDigest","evidence"],"properties":{"blockerId":{"$ref":"#/$defs/Ref"},"sourceActionId":{"$ref":"#/$defs/Ref"},"sourceReceiptDigest":{"$ref":"#/$defs/Hex64"},"scope":{"enum":["search","offer","availability","checkout"]},"code":{"enum":["no_hotels_matched","hotel_not_visible","hotel_rates_failed","criterion_must_not_met","offer_target_not_reached","offer_unavailable"]},"criterionPath":{"type":"string","pattern":"^(searchDraft|results|offers|checkout)(\\.[A-Za-z][A-Za-z0-9_]*){0,3}$","maxLength":160},"strength":{"const":"must"},"valueDigest":{"$ref":"#/$defs/Hex64"},"valueLabel":{"type":"string","minLength":1,"maxLength":120},"evidence":{"type":"object","additionalProperties":false,"required":["factRefs","gapCodes"],"properties":{"factRefs":{"type":"array","minItems":1,"maxItems":32,"uniqueItems":true,"items":{"$ref":"#/$defs/Ref"}},"gapCodes":{"$ref":"#/$defs/Codes"},"requested":{"type":"integer","minimum":0},"actual":{"type":"integer","minimum":0}}}}},
|
|
40
|
+
"Result":{"type":"object","additionalProperties":false,"required":["outcome","hardCriteriaMet","factRefs","gapCodes","blockers","relaxationsApplied"],"properties":{"outcome":{"enum":["complete","partial","empty"]},"requestedCount":{"type":"integer","minimum":0},"actualCount":{"type":"integer","minimum":0},"hardCriteriaMet":{"type":"boolean"},"factRefs":{"type":"array","maxItems":64,"uniqueItems":true,"items":{"$ref":"#/$defs/Ref"}},"gapCodes":{"$ref":"#/$defs/Codes"},"blockers":{"type":"array","maxItems":8,"items":{"$ref":"#/$defs/Blocker"}},"relaxationsApplied":{"type":"array","maxItems":1,"items":{"$ref":"#/$defs/Approval"}}}},
|
|
41
|
+
"Observation":{"oneOf":[{"type":"object","additionalProperties":false,"required":["kind"],"properties":{"kind":{"const":"search.state"},"searchSessionRef":{"$ref":"#/$defs/Ref"},"resultCount":{"type":"integer","minimum":0},"gapCodes":{"$ref":"#/$defs/Codes"}}},{"type":"object","additionalProperties":false,"required":["kind","matchedHotelRefs","visibleCount"],"properties":{"kind":{"const":"results.state"},"matchedHotelRefs":{"type":"array","maxItems":100,"items":{"$ref":"#/$defs/Ref"}},"visibleCount":{"type":"integer","minimum":0},"gapCodes":{"$ref":"#/$defs/Codes"}}},{"type":"object","additionalProperties":false,"required":["kind","hotelRef"],"properties":{"kind":{"enum":["hotel.focus","hotel.selection"]},"hotelRef":{"$ref":"#/$defs/Ref"}}},{"type":"object","additionalProperties":false,"required":["kind","hotelRefs","offerRefs","loadedHotelCount"],"properties":{"kind":{"const":"offers.state"},"hotelRefs":{"type":"array","maxItems":100,"items":{"$ref":"#/$defs/Ref"}},"offerRefs":{"type":"array","maxItems":200,"items":{"$ref":"#/$defs/Ref"}},"loadedHotelCount":{"type":"integer","minimum":0},"gapCodes":{"$ref":"#/$defs/Codes"}}},{"type":"object","additionalProperties":false,"required":["kind","offerRef","checkedOfferVersionRef","available","changedFactRefs"],"properties":{"kind":{"const":"offer.availability"},"offerRef":{"$ref":"#/$defs/Ref"},"checkedOfferVersionRef":{"$ref":"#/$defs/Ref"},"currentOfferVersionRef":{"$ref":"#/$defs/Ref"},"verifiedOfferRef":{"$ref":"#/$defs/Ref"},"available":{"type":"boolean"},"changedFactRefs":{"type":"array","maxItems":64,"items":{"$ref":"#/$defs/Ref"}},"gapCodes":{"$ref":"#/$defs/Codes"}}},{"type":"object","additionalProperties":false,"required":["kind","code","factRefs"],"properties":{"kind":{"const":"gap"},"code":{"enum":["byos_mapped_risk","check_avail_failed","check_avail_unverified","component_executor_unavailable","hotel_not_visible","hotel_rates_failed","offer_facts_changed","offer_not_loaded","offer_unavailable","order_not_found","order_outcome_not_observed","order_state_unknown","order_status_unavailable","requested_offers_not_loaded","search_failed","search_form_invalid","search_session_expired","search_terminal_timeout","stale_revision","surface_adapter_failed","undo_token_not_found","unhandled","unsupported","verified_offer_required","workspace_changed_during_action","criterion_must_not_met","no_hotels_matched","offer_target_not_reached"]},"factRefs":{"type":"array","maxItems":64,"items":{"$ref":"#/$defs/Ref"}}}}]},
|
|
42
|
+
"OfferSelectionObservation":{"type":"object","additionalProperties":false,"required":["kind","offerRef","offerVersionRef"],"properties":{"kind":{"const":"offer.selection"},"offerRef":{"$ref":"#/$defs/Ref"},"offerVersionRef":{"$ref":"#/$defs/Ref"}}},
|
|
43
|
+
"HandoffObservation":{"type":"object","additionalProperties":false,"required":["kind","offerRef","offerVersionRef","verifiedOfferRef","handoffRef"],"properties":{"kind":{"const":"checkout.handoff"},"offerRef":{"$ref":"#/$defs/Ref"},"offerVersionRef":{"$ref":"#/$defs/Ref"},"verifiedOfferRef":{"$ref":"#/$defs/Ref"},"handoffRef":{"$ref":"#/$defs/Ref"}}},
|
|
44
|
+
"OrderObservation":{"type":"object","additionalProperties":false,"required":["kind","orderRef","state"],"properties":{"kind":{"const":"order.state"},"orderRef":{"$ref":"#/$defs/Ref"},"state":{"enum":["pending","verified","failed","unknown"]},"gapCodes":{"$ref":"#/$defs/Codes"}}},
|
|
45
|
+
"ObservationExpanded":{"oneOf":[{"$ref":"#/$defs/Observation"},{"$ref":"#/$defs/OfferSelectionObservation"},{"$ref":"#/$defs/HandoffObservation"},{"$ref":"#/$defs/OrderObservation"}]},
|
|
46
|
+
"Receipt":{"type":"object","additionalProperties":false,"required":["schemaVersion","kind","actionId","contextRef","status","revision","observation","resultContract"],"properties":{"schemaVersion":{"const":"booking.surface.v2"},"kind":{"const":"action.receipt"},"actionId":{"$ref":"#/$defs/Ref"},"contextRef":{"$ref":"#/$defs/Ref"},"status":{"enum":["applied","needs_input","partial","no_match","unavailable","changed","stale","unsupported","failed"]},"revision":{"type":"integer","minimum":0},"observation":{"$ref":"#/$defs/ObservationExpanded"},"resultContract":{"$ref":"#/$defs/Result"},"undoToken":{"$ref":"#/$defs/Ref"}}},
|
|
47
|
+
"Ingress":{"type":"object","additionalProperties":false,"required":["schemaVersion","kind","requestKey","surfaceHint","workspace","request"],"properties":{"schemaVersion":{"const":"booking.surface.v2"},"kind":{"const":"user.turn.ingress"},"requestKey":{"$ref":"#/$defs/RequestKey"},"taskHandle":{"$ref":"#/$defs/Ref"},"surfaceHint":{"$ref":"#/$defs/Surface"},"workspace":{"$ref":"#/$defs/IngressWorkspace"},"request":{"type":"object","additionalProperties":false,"required":["text"],"properties":{"text":{"type":"string","minLength":1,"maxLength":4000}}}}},
|
|
48
|
+
"UserTurn":{"type":"object","additionalProperties":false,"required":["schemaVersion","kind","taskId","turnId","workspace","request"],"properties":{"schemaVersion":{"const":"booking.surface.v2"},"kind":{"const":"user.turn"},"taskId":{"$ref":"#/$defs/Ref"},"turnId":{"$ref":"#/$defs/Ref"},"workspace":{"$ref":"#/$defs/Workspace"},"request":{"type":"object","additionalProperties":false,"required":["text"],"properties":{"text":{"type":"string","minLength":1,"maxLength":4000},"approval":{"$ref":"#/$defs/Approval"}}}}},
|
|
49
|
+
"Continuation":{"type":"object","additionalProperties":false,"required":["schemaVersion","kind","taskId","workspace","receipt"],"properties":{"schemaVersion":{"const":"booking.surface.v2"},"kind":{"const":"action.receipt.continuation"},"taskId":{"$ref":"#/$defs/Ref"},"workspace":{"$ref":"#/$defs/Workspace"},"receipt":{"$ref":"#/$defs/Receipt"}}},
|
|
50
|
+
"Event":{"oneOf":[
|
|
51
|
+
{"$ref":"#/$defs/StatusEvent"},{"$ref":"#/$defs/QuestionEvent"},{"$ref":"#/$defs/OperationEvent"},{"$ref":"#/$defs/ExplanationEvent"},{"$ref":"#/$defs/TerminalEvent"},{"$ref":"#/$defs/ErrorEvent"}
|
|
52
|
+
]},
|
|
53
|
+
"EventBase":{"type":"object","required":["schemaVersion","eventId","taskId","contextRef","sequence","emittedAt","kind"],"properties":{"schemaVersion":{"const":"booking.surface.v2"},"eventId":{"$ref":"#/$defs/Ref"},"taskId":{"$ref":"#/$defs/Ref"},"contextRef":{"$ref":"#/$defs/Ref"},"sequence":{"type":"integer","minimum":1},"emittedAt":{"type":"string","minLength":1},"kind":{"enum":["status","question","operation","explanation","terminal","error"]}}},
|
|
54
|
+
"StatusEvent":{"type":"object","allOf":[{"$ref":"#/$defs/EventBase"},{"type":"object","required":["kind","status"],"properties":{"kind":{"const":"status"},"status":{"enum":["submitted","working","waiting_receipt","input_required"]}}}],"unevaluatedProperties":false},
|
|
55
|
+
"QuestionEvent":{"type":"object","additionalProperties":false,"required":["schemaVersion","eventId","taskId","contextRef","sequence","emittedAt","kind","question"],"properties":{"schemaVersion":{"const":"booking.surface.v2"},"eventId":{"$ref":"#/$defs/Ref"},"taskId":{"$ref":"#/$defs/Ref"},"contextRef":{"$ref":"#/$defs/Ref"},"sequence":{"type":"integer","minimum":1},"emittedAt":{"type":"string","minLength":1},"kind":{"const":"question"},"question":{"type":"object","additionalProperties":false,"required":["questionId","prompt","missingFields","type","blocker","approvalOptions"],"properties":{"questionId":{"$ref":"#/$defs/Ref"},"prompt":{"type":"string","minLength":1},"missingFields":{"type":"array","maxItems":32,"items":{"type":"string"}},"type":{"const":"relaxation_approval_required"},"blocker":{"$ref":"#/$defs/Blocker"},"approvalOptions":{"type":"array","minItems":1,"maxItems":2,"items":{"type":"object","additionalProperties":false,"required":["approval"],"properties":{"approval":{"$ref":"#/$defs/Approval"}}}}}}}},
|
|
56
|
+
"OperationEvent":{"type":"object","allOf":[{"$ref":"#/$defs/EventBase"},{"type":"object","required":["kind","action"],"properties":{"kind":{"const":"operation"},"action":{"$ref":"#/$defs/Action"}}}],"unevaluatedProperties":false},
|
|
57
|
+
"ExplanationEvent":{"type":"object","allOf":[{"$ref":"#/$defs/EventBase"},{"type":"object","required":["kind","explanation"],"properties":{"kind":{"const":"explanation"},"explanation":{"type":"object","additionalProperties":false,"required":["text","factRefs"],"properties":{"text":{"type":"string","minLength":1},"factRefs":{"type":"array","maxItems":64,"items":{"$ref":"#/$defs/Ref"}}}}}}],"unevaluatedProperties":false},
|
|
58
|
+
"TerminalEvent":{"type":"object","allOf":[{"$ref":"#/$defs/EventBase"},{"type":"object","required":["kind","terminal"],"properties":{"kind":{"const":"terminal"},"terminal":{"type":"object","additionalProperties":false,"required":["status","summary","factRefs"],"properties":{"status":{"enum":["completed","stopped"]},"summary":{"type":"string","minLength":1},"factRefs":{"type":"array","maxItems":64,"items":{"$ref":"#/$defs/Ref"}}}}}}],"unevaluatedProperties":false},
|
|
59
|
+
"ErrorEvent":{"type":"object","allOf":[{"$ref":"#/$defs/EventBase"},{"type":"object","required":["kind","error"],"properties":{"kind":{"const":"error"},"error":{"type":"object","additionalProperties":false,"required":["code","message","retryable"],"properties":{"code":{"type":"string","pattern":"^[A-Z][A-Z0-9_.-]*$"},"message":{"type":"string","minLength":1},"retryable":{"type":"boolean"}}}}}],"unevaluatedProperties":false}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 可下单事实侧车持久化(issue #46,ADR-19):append-only JSONL 证据日志。
|
|
3
|
+
*
|
|
4
|
+
* 定位:这是**会话证据**而非用户状态——与 bridge-latency.jsonl / incidents.jsonl
|
|
5
|
+
* 同类(审计痕迹),不进账本投影。append-only 保历史(同 route+date 重查的旧快照
|
|
6
|
+
* 可回溯),读取侧经 dedupeFacts 取同 fact_id 最新。
|
|
7
|
+
*
|
|
8
|
+
* 路径:<stateRoot>/gotry-state/bookable-facts.jsonl
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { appendFile, mkdir, readFile } from 'node:fs/promises'
|
|
12
|
+
import { join } from 'node:path'
|
|
13
|
+
import { dedupeFacts, type BookableFact } from '../src/bookable-facts.ts'
|
|
14
|
+
|
|
15
|
+
export const FACT_LOG_NAME = 'bookable-facts.jsonl'
|
|
16
|
+
|
|
17
|
+
export function factLogPath(stateRoot: string): string {
|
|
18
|
+
const root = stateRoot === '.' ? process.cwd() : stateRoot
|
|
19
|
+
return join(root, 'gotry-state', FACT_LOG_NAME)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** 追加事实(永不抛错:落盘失败不阻塞检索工具主路径,返回 false 由调用方记 incident) */
|
|
23
|
+
export async function appendFacts(stateRoot: string, facts: BookableFact[]): Promise<boolean> {
|
|
24
|
+
if (facts.length === 0) return true
|
|
25
|
+
try {
|
|
26
|
+
const p = factLogPath(stateRoot)
|
|
27
|
+
await mkdir(join(p, '..'), { recursive: true })
|
|
28
|
+
await appendFile(p, facts.map(f => JSON.stringify(f)).join('\n') + '\n', 'utf-8')
|
|
29
|
+
return true
|
|
30
|
+
} catch {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** 读注册表(去重后视图;无文件 = 空注册表,不抛) */
|
|
36
|
+
export async function loadFactRegistry(stateRoot: string): Promise<BookableFact[]> {
|
|
37
|
+
try {
|
|
38
|
+
const raw = await readFile(factLogPath(stateRoot), 'utf-8')
|
|
39
|
+
const facts: BookableFact[] = []
|
|
40
|
+
for (const line of raw.split('\n')) {
|
|
41
|
+
const t = line.trim()
|
|
42
|
+
if (!t) continue
|
|
43
|
+
try {
|
|
44
|
+
const f = JSON.parse(t) as BookableFact
|
|
45
|
+
if (f.schema === 'gotry_bookable_fact.v1' && f.fact_id) facts.push(f)
|
|
46
|
+
} catch {
|
|
47
|
+
// 单行损坏不拖垮整本注册表(与 incidents/latency 日志同纪律)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return dedupeFacts(facts)
|
|
51
|
+
} catch {
|
|
52
|
+
return []
|
|
53
|
+
}
|
|
54
|
+
}
|
package/ts/capabilities/flyai.ts
CHANGED
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { spawn } from 'node:child_process'
|
|
18
|
+
import { closeSync, openSync, readFileSync, unlinkSync } from 'node:fs'
|
|
19
|
+
import { tmpdir } from 'node:os'
|
|
20
|
+
import { join } from 'node:path'
|
|
18
21
|
|
|
19
22
|
export type FlyaiKind = 'flight' | 'train' | 'hotel'
|
|
20
23
|
|
|
@@ -175,20 +178,30 @@ export function parseFlyaiItemList(stdout: string): unknown[] {
|
|
|
175
178
|
}
|
|
176
179
|
|
|
177
180
|
|
|
181
|
+
/**
|
|
182
|
+
* 子进程 stdout 走临时文件而非管道(issue #84):
|
|
183
|
+
* flyai CLI 异步写 stdout 后立即 process.exit();stdout 是管道时未 flush 的
|
|
184
|
+
* 尾部会被丢掉(实测截断在 ~7.6KB,exit=0 静默)。stdout 是文件时 Node 同步写,
|
|
185
|
+
* exit 不丢数据;且文件无 64KB 管道缓冲上限。close 后读文件,语义不变。
|
|
186
|
+
*/
|
|
178
187
|
function sh(cmd: string, args: string[], opts: { timeoutMs: number }) {
|
|
179
|
-
const
|
|
180
|
-
|
|
188
|
+
const outFile = join(tmpdir(), `gotry-flyai-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.out`)
|
|
189
|
+
const outFd = openSync(outFile, 'w')
|
|
190
|
+
const child = spawn(cmd, args, { env: process.env, cwd: process.cwd(), stdio: ['ignore', outFd, 'pipe'] })
|
|
181
191
|
let stderr = ''
|
|
182
192
|
let error: string | undefined
|
|
183
193
|
const timer = setTimeout(() => {
|
|
184
194
|
try { child.kill('SIGKILL') } catch { /* ignore */ }
|
|
185
195
|
}, opts.timeoutMs)
|
|
186
196
|
return new Promise<{ code: number; stdout: string; stderr: string; error?: string; timedOut?: boolean }>((resolve) => {
|
|
187
|
-
child.stdout?.on('data', (d: Buffer) => { stdout += d.toString() })
|
|
188
197
|
child.stderr?.on('data', (d: Buffer) => { stderr += d.toString() })
|
|
189
198
|
child.on('error', (e) => { error = (e as Error).message.slice(0, 200) })
|
|
190
199
|
child.on('close', (code) => {
|
|
191
200
|
clearTimeout(timer)
|
|
201
|
+
closeSync(outFd)
|
|
202
|
+
let stdout = ''
|
|
203
|
+
try { stdout = readFileSync(outFile, 'utf8') } catch { /* 子进程未启动时文件可能为空,按空 stdout 处理 */ }
|
|
204
|
+
try { unlinkSync(outFile) } catch { /* ignore */ }
|
|
192
205
|
resolve({ code: code ?? -1, stdout, stderr, error })
|
|
193
206
|
})
|
|
194
207
|
}).finally(() => clearTimeout(timer))
|
package/ts/capabilities/hbcli.ts
CHANGED
|
@@ -194,3 +194,49 @@ export async function listDestinations(opts: HbcliCallOptions = {}): Promise<Hbc
|
|
|
194
194
|
const r = await callHbcliJson(['search', 'destinations', '--json'], opts)
|
|
195
195
|
return { ...r, destinations: r.result }
|
|
196
196
|
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* 高层语义化封装:房型报价(hotel-rates;上游 hotelRates 创建后端 session,
|
|
200
|
+
* 产出带 RatePkgId 的房型列表——check-avail 与 book 的入参来源)。
|
|
201
|
+
*
|
|
202
|
+
* 价格面无静态降级(fail-closed):hotel-list 的静态包降级是定性住宿信息,
|
|
203
|
+
* 房价是钱——估算价格冒充实时价是红线;不可用就诚实失败,证据链标注,
|
|
204
|
+
* 与 bookable-facts 证据分级(live_inventory 才可进确认卡)同口径。
|
|
205
|
+
*/
|
|
206
|
+
export async function hotelRates(
|
|
207
|
+
query: {
|
|
208
|
+
hotelId: string
|
|
209
|
+
checkIn?: string
|
|
210
|
+
checkOut?: string
|
|
211
|
+
adults?: number
|
|
212
|
+
countryCode?: string
|
|
213
|
+
nationalityCode?: string
|
|
214
|
+
residencyCode?: string
|
|
215
|
+
},
|
|
216
|
+
opts: HbcliCallOptions = {},
|
|
217
|
+
): Promise<HbcliCallResult & { rates?: unknown; summary: string }> {
|
|
218
|
+
const hbArgs = ['search', 'hotel-rates', '--json', '--hotel-id', query.hotelId]
|
|
219
|
+
if (query.checkIn) hbArgs.push('--check-in', query.checkIn)
|
|
220
|
+
if (query.checkOut) hbArgs.push('--check-out', query.checkOut)
|
|
221
|
+
if (query.countryCode) hbArgs.push('--country-code', query.countryCode)
|
|
222
|
+
if (query.nationalityCode) hbArgs.push('--nationality-code', query.nationalityCode)
|
|
223
|
+
if (query.residencyCode) hbArgs.push('--residency-code', query.residencyCode)
|
|
224
|
+
if (query.adults) hbArgs.push('--room-occupancies', JSON.stringify([{ adultCount: query.adults, childrenAges: [] }]))
|
|
225
|
+
const live = await callHbcliJson(hbArgs, opts)
|
|
226
|
+
const summary = live.via === 'hbcli-realtime'
|
|
227
|
+
? `hotel ${query.hotelId}:hbcli 实时报价${query.checkIn ? `(${query.checkIn} → ${query.checkOut ?? '?'})` : ''}`
|
|
228
|
+
: `hotel ${query.hotelId}:hbcli 实时报价不可用(${live.error ?? live.via});价格面无静态降级,fail-closed 不估算`
|
|
229
|
+
return { ...live, rates: live.result, summary }
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** 高层语义化封装:下单前实时验价(check-avail;入参 RatePkgId 来自 hotel-rates 产物)。价格面同上:不可用即诚实失败。 */
|
|
233
|
+
export async function checkAvail(
|
|
234
|
+
query: { ratePkgId: string },
|
|
235
|
+
opts: HbcliCallOptions = {},
|
|
236
|
+
): Promise<HbcliCallResult & { avail?: unknown; summary: string }> {
|
|
237
|
+
const live = await callHbcliJson(['search', 'check-avail', '--json', '--rate-pkg-id', query.ratePkgId], opts)
|
|
238
|
+
const summary = live.via === 'hbcli-realtime'
|
|
239
|
+
? `ratePkg ${query.ratePkgId}:hbcli 实时验价(库存与价格以后端为准)`
|
|
240
|
+
: `ratePkg ${query.ratePkgId}:hbcli 实时验价不可用(${live.error ?? live.via});价格面无静态降级,fail-closed`
|
|
241
|
+
return { ...live, avail: live.result, summary }
|
|
242
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 只处理已经脱敏、结构化的证据;不打开浏览器、不读登录态,也不执行任何写操作。
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export type SessionEvidenceVerdict = 'hit' | 'miss' | 'error' | 'challenged' | 'cooldown' | 'needs-login' | 'needs-attach'
|
|
7
|
+
export type SessionEvidenceVerdict = 'hit' | 'miss' | 'error' | 'challenged' | 'cooldown' | 'needs-login' | 'needs-attach' | 'needs-extension'
|
|
8
8
|
|
|
9
9
|
export const SESSION_BENCHMARK_SCHEMA_VERSION = 'session-double-source.v1' as const
|
|
10
10
|
export const SESSION_FIELD_ACCURACY_THRESHOLD = 0.9
|
|
@@ -162,6 +162,7 @@ export type DoubleSourceState =
|
|
|
162
162
|
| 'divergent'
|
|
163
163
|
| 'waiting_attach'
|
|
164
164
|
| 'waiting_login'
|
|
165
|
+
| 'waiting_extension'
|
|
165
166
|
| 'challenge_stop'
|
|
166
167
|
| 'guard_violation'
|
|
167
168
|
| 'source_unavailable'
|
|
@@ -252,6 +253,8 @@ export function evaluateDoubleSource(input: {
|
|
|
252
253
|
}
|
|
253
254
|
if (!session) return baseEvaluation('source_unavailable', 'no_spend_stop')
|
|
254
255
|
if (session.verdict === 'needs-attach') return baseEvaluation('waiting_attach', 'no_spend_waiting_user')
|
|
256
|
+
// 扩展车道(2026-08-29 PRIMARY 传输)未就绪:与 waiting-* 同族 no-spend,等待用户一次性安装
|
|
257
|
+
if (session.verdict === 'needs-extension') return baseEvaluation('waiting_extension', 'no_spend_waiting_user')
|
|
255
258
|
if (session.verdict === 'needs-login') return baseEvaluation('waiting_login', 'no_spend_waiting_user')
|
|
256
259
|
if (!official || official.verdict !== 'hit' || session.verdict !== 'hit') {
|
|
257
260
|
return baseEvaluation('source_unavailable', 'no_spend_stop')
|