@danceiny/gotry 0.0.1-rc.9 → 0.2.0-rc.27
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 +172 -219
- package/README.zh-CN.md +222 -0
- package/bin/gotry-backend.js +53 -0
- package/bin/gotry-booking-copilot.js +53 -0
- package/bin/gotry-bootstrap.js +1744 -0
- package/bin/gotry-inner.js +733 -83
- package/bin/gotry-process-liveness.d.ts +27 -0
- package/bin/gotry-process-liveness.js +97 -0
- package/bin/gotry-runtime-resolution.d.ts +27 -0
- package/bin/gotry-runtime-resolution.js +49 -0
- package/bin/gotry.js +1 -1
- package/client/client.js +203 -0
- package/cordis.gotry-patch.yml +80 -56
- package/data/airline-airports.json +39 -0
- package/data/stations-12306-verify.json +524 -0
- package/dist/capabilities/agent-reach-deep.js +45 -122
- package/dist/capabilities/agent-reach.js +101 -146
- package/dist/capabilities/anything.js +135 -94
- package/dist/capabilities/artifacts.js +370 -0
- package/dist/capabilities/channel-health.js +131 -0
- package/dist/capabilities/channel-registry.js +256 -0
- package/dist/capabilities/doctor.js +546 -0
- package/dist/capabilities/effect.js +394 -0
- package/dist/capabilities/external-event.js +149 -0
- package/dist/capabilities/fact-log.js +55 -0
- package/dist/capabilities/flyai-config.js +337 -0
- package/dist/capabilities/flyai.js +947 -110
- package/dist/capabilities/fx-contract.js +293 -0
- package/dist/capabilities/geo-atlas.js +246 -0
- package/dist/capabilities/ground-transfer.js +509 -0
- package/dist/capabilities/hbcli.js +260 -123
- package/dist/capabilities/hotelbyte-transaction.js +194 -0
- package/dist/capabilities/incident-log.js +131 -61
- package/dist/capabilities/itinerary-artifact.js +190 -0
- package/dist/capabilities/itinerary-deck-artifact.js +194 -0
- package/dist/capabilities/itinerary-deck-export.js +339 -0
- package/dist/capabilities/lavish-local.js +924 -0
- package/dist/capabilities/model-override.js +38 -0
- package/dist/capabilities/opensky.js +54 -43
- package/dist/capabilities/resilience.js +191 -0
- package/dist/capabilities/session/action-cache.js +50 -44
- package/dist/capabilities/session/adapters/ctrip-flight.js +120 -62
- package/dist/capabilities/session/adapters/ctrip-hotel.js +222 -0
- package/dist/capabilities/session/adapters/dida-portal.js +274 -0
- package/dist/capabilities/session/adapters/meituan-local.js +35 -54
- package/dist/capabilities/session/adapters/rail-12306.js +342 -0
- package/dist/capabilities/session/benchmark.js +189 -0
- package/dist/capabilities/session/bridge-ledger.js +224 -0
- package/dist/capabilities/session/extension-bridge.js +636 -0
- package/dist/capabilities/session/extension-channel.js +109 -0
- package/dist/capabilities/session/extension-distribution.js +230 -0
- package/dist/capabilities/session/extract.js +31 -21
- package/dist/capabilities/session/golden-score.js +114 -0
- package/dist/capabilities/session/health-watch.js +215 -0
- package/dist/capabilities/session/read-guard.js +75 -24
- package/dist/capabilities/session/static-flight-golden.js +150 -0
- package/dist/capabilities/session/transport.js +97 -83
- package/dist/capabilities/session/wizard.js +117 -0
- package/dist/capabilities/session-consent.js +178 -0
- package/dist/capabilities/session-login.js +170 -0
- package/dist/capabilities/session-search.js +635 -44
- package/dist/capabilities/spawn-bounded.js +203 -0
- package/dist/capabilities/sponsor-plugin.js +341 -0
- package/dist/capabilities/visa-policy.js +140 -0
- package/dist/capabilities/weather.js +243 -138
- package/dist/data/session-golden-20.json +25 -0
- package/dist/data/sf-golden-manifest.json +103 -0
- package/dist/data/sf-static-routes.json +91 -0
- package/dist/scripts/action-cache-tests.js +24 -59
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +242 -0
- package/dist/scripts/agent-planning-turn-deadline-tests.js +185 -0
- package/dist/scripts/agent-reach-deep-tests.js +30 -40
- package/dist/scripts/agent-reach-error-tests.js +354 -0
- package/dist/scripts/agent-reach-tests.js +26 -18
- package/dist/scripts/agent-reach-wrapper-tests.js +50 -50
- package/dist/scripts/anything-tests.js +116 -60
- package/dist/scripts/artifact-client-contract-tests.js +220 -0
- package/dist/scripts/artifacts-capability-tests.js +727 -0
- package/dist/scripts/async-collect.js +50 -11
- package/dist/scripts/benchmark-environment-bridge-e2e.js +741 -0
- package/dist/scripts/benchmark-environment-bridge-tests.js +1452 -0
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +126 -0
- package/dist/scripts/booking-copilot-availability-policy-tests.js +265 -0
- package/dist/scripts/booking-copilot-bin-proof-tests.js +66 -0
- package/dist/scripts/booking-copilot-cleanup-proof-helper.js +76 -0
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +144 -0
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +424 -0
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +2839 -0
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +309 -0
- package/dist/scripts/booking-copilot-dsh-readiness-proof.js +238 -0
- package/dist/scripts/booking-copilot-dsh-warmer-proof.js +123 -0
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +156 -0
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +70 -0
- package/dist/scripts/booking-copilot-intent-proof-tests.js +422 -0
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +184 -0
- package/dist/scripts/booking-copilot-planner-live-probe.js +95 -0
- package/dist/scripts/booking-copilot-proof-runtime.js +42 -0
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +210 -0
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +2349 -0
- package/dist/scripts/booking-copilot-server-proof-tests.js +784 -0
- package/dist/scripts/booking-copilot-startup-proof-tests.js +94 -0
- 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 +125 -0
- package/dist/scripts/booking-surface-contract-proof-tests.js +212 -0
- package/dist/scripts/bootstrap-tests.js +1479 -0
- package/dist/scripts/bridge-events-tests.js +239 -0
- package/dist/scripts/bridge-ledger-tests.js +428 -0
- package/dist/scripts/build-changelog.js +238 -0
- package/dist/scripts/build-metrics-report.js +331 -0
- package/dist/scripts/changelog-tests.js +118 -0
- package/dist/scripts/channel-probe-tests.js +103 -0
- package/dist/scripts/channel-probe.js +169 -0
- package/dist/scripts/channel-registry-tests.js +208 -0
- package/dist/scripts/companion-tests.js +25 -70
- package/dist/scripts/dida-cookie-probe.js +87 -0
- package/dist/scripts/dida-runner-stop-tests.js +311 -0
- package/dist/scripts/dida-sw-probe.js +114 -0
- package/dist/scripts/diff-test.js +17 -12
- package/dist/scripts/doctor-tests.js +564 -0
- package/dist/scripts/dsh-artifact-e2e.js +279 -0
- package/dist/scripts/dsh-artifact-web-e2e.js +675 -0
- package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
- package/dist/scripts/dsh-runtime-closure-tests.js +182 -0
- package/dist/scripts/dsh-runtime-closure.js +162 -0
- package/dist/scripts/dsh-session-v3-migration-proof.js +109 -0
- package/dist/scripts/dsh-subprocess-local-proof.js +150 -0
- package/dist/scripts/dsh-target-closure-proof.js +178 -0
- package/dist/scripts/effect-tests.js +539 -0
- package/dist/scripts/engine-run.js +1 -3
- package/dist/scripts/engine-tests.js +16 -10
- package/dist/scripts/evaluation-cadence-tests.js +174 -0
- package/dist/scripts/evaluation-contract-tests.js +268 -0
- package/dist/scripts/extension-distribution-cli.js +39 -0
- package/dist/scripts/extension-distribution-tests.js +443 -0
- package/dist/scripts/extension-tests.js +988 -0
- package/dist/scripts/external-event-tests.js +350 -0
- package/dist/scripts/fact-gate-tests.js +869 -0
- 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-setup-tests.js +228 -0
- package/dist/scripts/flyai-setup-tool-tests.js +54 -0
- package/dist/scripts/flyai-tests.js +692 -0
- package/dist/scripts/flyai-tool-registration-contract-tests.js +91 -0
- package/dist/scripts/fx-contract-tests.js +201 -0
- 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/geo-atlas-tests.js +283 -0
- package/dist/scripts/gotry-backend-kernel-tests.js +206 -0
- package/dist/scripts/gotry-try-demo-tests.js +79 -0
- package/dist/scripts/gotry-try-demo.js +49 -0
- package/dist/scripts/ground-transfer-tests.js +956 -0
- package/dist/scripts/hbcli-e2e-tests.js +159 -0
- 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 +121 -69
- package/dist/scripts/health-watch-cli.js +73 -0
- 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 +41 -0
- 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 +569 -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/issue436-persisted-routing-e2e.js +247 -0
- package/dist/scripts/itinerary-artifact-tests.js +368 -0
- package/dist/scripts/itinerary-deck-artifact-tests.js +416 -0
- package/dist/scripts/itinerary-deck-export-tests.js +552 -0
- package/dist/scripts/itinerary-deck-tests.js +435 -0
- package/dist/scripts/itinerary-html-tests.js +426 -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/lavish-local-tests.js +1226 -0
- package/dist/scripts/lavish-product-tools-tests.js +537 -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 +382 -246
- package/dist/scripts/ledger-workflow-crash.js +10 -20
- package/dist/scripts/managed-dsh-cleanup-diagnostic-proof.js +184 -0
- package/dist/scripts/managed-dsh-close-failure-proof.js +172 -0
- package/dist/scripts/managed-dsh-run-port-proof.js +153 -0
- package/dist/scripts/managed-dsh-terminal-proof.js +252 -0
- package/dist/scripts/map-tools-vendor-package-proof.js +365 -0
- 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 +631 -0
- package/dist/scripts/memory-value-tests.js +328 -0
- package/dist/scripts/metrics-report-tests.js +151 -0
- package/dist/scripts/model-override-e2e.js +137 -0
- package/dist/scripts/nightly-evidence-tests.js +161 -0
- package/dist/scripts/nightly-evidence.js +286 -0
- package/dist/scripts/nudge-digest.js +39 -28
- package/dist/scripts/observability-tests.js +381 -0
- package/dist/scripts/onboarding-tests.js +161 -0
- package/dist/scripts/opensky-check.js +18 -13
- package/dist/scripts/opensky-tests.js +28 -28
- package/dist/scripts/persona-surface-guard-tests.js +49 -0
- package/dist/scripts/pnpm-dsh-closure-proof.js +17 -0
- package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
- package/dist/scripts/price-drift-tests.js +340 -0
- package/dist/scripts/price-drift-watch.js +447 -0
- package/dist/scripts/probe-poi-tests.js +53 -45
- package/dist/scripts/product-metrics.js +483 -0
- package/dist/scripts/publish-preverify.js +110 -0
- package/dist/scripts/realtime-pricing-tests.js +76 -0
- package/dist/scripts/recall-tests.js +513 -0
- package/dist/scripts/replay-async.js +20 -18
- package/dist/scripts/replay-real.js +18 -18
- package/dist/scripts/replay.js +52 -82
- package/dist/scripts/session-attach-diagnose.js +20 -20
- package/dist/scripts/session-attach-poc.js +34 -37
- package/dist/scripts/session-benchmark.js +180 -0
- package/dist/scripts/session-dida-live-e2e.js +199 -0
- package/dist/scripts/session-extract-tests.js +14 -35
- package/dist/scripts/session-link-tests.js +478 -0
- package/dist/scripts/session-login.js +27 -46
- package/dist/scripts/session-tests.js +796 -96
- package/dist/scripts/session-zones-tests.js +358 -0
- package/dist/scripts/sf-live-benchmark.js +367 -0
- package/dist/scripts/sf-live-challenge-stop-tests.js +453 -0
- package/dist/scripts/sf-live-cli-tests.js +92 -0
- package/dist/scripts/sf-live-options.js +46 -0
- package/dist/scripts/sf-manifest-tests.js +30 -0
- package/dist/scripts/sf-manifest.js +33 -0
- package/dist/scripts/sf-soft-score-tests.js +67 -0
- package/dist/scripts/sf-summary-tests.js +324 -0
- package/dist/scripts/sf-summary.js +525 -0
- package/dist/scripts/share-tests.js +432 -0
- package/dist/scripts/skeleton-check.js +16 -14
- package/dist/scripts/skeleton-integration-test.js +28 -11
- package/dist/scripts/skills-contract-tests.js +51 -46
- package/dist/scripts/smoke-session-gate-tests.js +21 -0
- package/dist/scripts/smoke.js +690 -246
- package/dist/scripts/spawn-bounded-abort-tests.js +241 -0
- package/dist/scripts/sponsor-reuse-tests.js +262 -0
- package/dist/scripts/state-cli-tests.js +226 -101
- package/dist/scripts/state-cli.js +550 -199
- package/dist/scripts/state-repair-cli.js +66 -0
- package/dist/scripts/state-repair-tests.js +140 -0
- package/dist/scripts/static-golden-tests.js +165 -0
- 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 +169 -0
- package/dist/scripts/turn-handoff-collect.js +161 -0
- package/dist/scripts/turn-policy-tests.js +55 -0
- package/dist/scripts/typed-contract-canary.js +176 -0
- 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 +62 -0
- package/dist/scripts/weather-tests.js +276 -41
- package/dist/scripts/wish-channel-gate-tests.js +54 -0
- 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 +41 -0
- package/dist/src/artifact-gate.js +829 -0
- package/dist/src/backend/kernel.js +91 -0
- package/dist/src/backend/modules/booking-copilot.js +92 -0
- package/dist/src/backend/modules/booking-executor.js +124 -0
- package/dist/src/backend/modules/session-search.js +551 -0
- package/dist/src/benchmark-agent-conformance.js +578 -0
- package/dist/src/benchmark-environment-bridge.js +515 -0
- package/dist/src/benchmark-headless-child-diagnostics.js +166 -0
- package/dist/src/benchmark-tool-isolation.js +151 -0
- package/dist/src/bookable-facts.js +533 -0
- package/dist/src/booking-saga.js +97 -0
- package/dist/src/booking-surface/availability-policy.js +697 -0
- package/dist/src/booking-surface/booking-intent.js +43 -0
- package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
- package/dist/src/booking-surface/canonical-schema.js +116 -0
- package/dist/src/booking-surface/contracts.js +75 -0
- package/dist/src/booking-surface/dsh-planner.js +1854 -0
- package/dist/src/booking-surface/dsh-plugin.js +378 -0
- package/dist/src/booking-surface/dsh-worker.js +98 -0
- package/dist/src/booking-surface/error-codes.js +231 -0
- package/dist/src/booking-surface/index.js +9 -0
- package/dist/src/booking-surface/managed-dsh-cleanup-diagnostic.js +97 -0
- package/dist/src/booking-surface/managed-dsh-run-port.js +244 -0
- package/dist/src/booking-surface/profile.js +24 -0
- package/dist/src/booking-surface/recovery-chain.js +367 -0
- package/dist/src/booking-surface/runtime.js +1968 -0
- package/dist/src/booking-surface/server.js +674 -0
- package/dist/src/booking-surface/startup.js +168 -0
- package/dist/src/booking-surface/validation.js +261 -0
- 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 +97 -111
- package/dist/src/engine.js +276 -193
- package/dist/src/evaluation-cadence.js +97 -0
- package/dist/src/evaluation-contracts.js +283 -0
- package/dist/src/flight-pack-adapter.js +54 -0
- package/dist/src/flight-pack-contract.js +2 -0
- package/dist/src/flyai-setup-tool.js +70 -0
- package/dist/src/gotry-backend.js +125 -0
- package/dist/src/hotel-date-gate.js +118 -0
- package/dist/src/i18n.js +88 -0
- package/dist/src/index.js +2227 -882
- package/dist/src/itinerary-deck.js +139 -0
- package/dist/src/itinerary-doc-shared.js +661 -0
- package/dist/src/itinerary-html.js +131 -0
- package/dist/src/journey.js +155 -108
- package/dist/src/lavish-tools.js +400 -0
- package/dist/src/ledger-repair-apply.js +538 -0
- package/dist/src/ledger-repair-plan.js +463 -0
- package/dist/src/loop.js +319 -160
- 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 +103 -0
- package/dist/src/recall/card.js +74 -0
- package/dist/src/recall/evaluator.js +140 -0
- package/dist/src/recall/integration.js +17 -0
- package/dist/src/recall/tick.js +166 -0
- package/dist/src/session-link/plan-it-action.js +48 -0
- package/dist/src/session-link/session-link.js +248 -0
- package/dist/src/session-zones.js +507 -0
- package/dist/src/share/adapters.js +51 -0
- package/dist/src/share/share-consent.js +76 -0
- package/dist/src/share/share-deck.js +58 -0
- package/dist/src/share/share-token.js +146 -0
- package/dist/src/slot-spec.js +84 -106
- package/dist/src/state-ledger.js +435 -516
- package/dist/src/state-repair.js +299 -0
- 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 +287 -0
- package/dist/src/turn-policy.js +118 -0
- package/dist/src/tz-resolver.js +143 -0
- package/dist/src/unified.js +535 -359
- package/dist/src/wish-pool.js +42 -12
- package/dist/src/write-gate.js +495 -0
- package/dist/src/z3-shared.js +284 -0
- package/extension/README.md +21 -0
- package/extension/README.zh-CN.md +21 -0
- package/extension/background.js +463 -0
- package/extension/content-bridge.js +270 -0
- package/extension/content-main.js +111 -0
- package/extension/manifest.json +60 -0
- package/package.json +407 -14
- package/schemas/booking.intent.schema.json +193 -0
- package/schemas/booking.surface.schema.json +2622 -0
- package/ts/capabilities/agent-reach-deep.ts +114 -0
- package/ts/capabilities/agent-reach.ts +198 -0
- package/ts/capabilities/anything.ts +255 -0
- package/ts/capabilities/artifacts.ts +428 -0
- package/ts/capabilities/fact-log.ts +54 -0
- package/ts/capabilities/flyai-config.ts +388 -0
- package/ts/capabilities/flyai.ts +1274 -0
- package/ts/capabilities/hbcli.ts +253 -71
- package/ts/capabilities/incident-log.ts +88 -59
- package/ts/capabilities/itinerary-artifact.ts +214 -0
- package/ts/capabilities/itinerary-deck-artifact.ts +218 -0
- package/ts/capabilities/itinerary-deck-export.ts +378 -0
- package/ts/capabilities/opensky.ts +121 -0
- package/ts/capabilities/session/action-cache.ts +148 -0
- package/ts/capabilities/session/adapters/ctrip-flight.ts +181 -0
- package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
- package/ts/capabilities/session/adapters/dida-portal.ts +338 -0
- package/ts/capabilities/session/adapters/meituan-local.ts +70 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +392 -0
- package/ts/capabilities/session/benchmark.ts +276 -0
- package/ts/capabilities/session/bridge-ledger.ts +333 -0
- package/ts/capabilities/session/extension-bridge.ts +794 -0
- package/ts/capabilities/session/extension-channel.ts +144 -0
- package/ts/capabilities/session/extension-distribution.ts +266 -0
- package/ts/capabilities/session/extract.ts +54 -0
- package/ts/capabilities/session/golden-score.ts +139 -0
- package/ts/capabilities/session/health-watch.ts +264 -0
- package/ts/capabilities/session/read-guard.ts +141 -0
- package/ts/capabilities/session/static-flight-golden.ts +209 -0
- package/ts/capabilities/session/transport.ts +146 -0
- package/ts/capabilities/session/wizard.ts +140 -0
- package/ts/capabilities/session-consent.ts +211 -0
- package/ts/capabilities/session-login.ts +208 -0
- package/ts/capabilities/session-search.ts +893 -0
- package/ts/capabilities/weather.ts +330 -0
- package/ts/dsh-runtime/vendor/README.md +68 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/LICENSE +21 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +405 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +404 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/client/client.js +1584 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/cordis.patch.yml +5 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/icon.svg +5 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/amap.js +595 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/nominatim.js +63 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/osrm.js +58 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/photon.js +55 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-file.js +87 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-route.js +131 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/geo.js +232 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/index.js +120 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +40 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/staticmap-route.js +115 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/geocode.js +127 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/poi.js +84 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/routes.js +267 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/amap.d.ts +90 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/nominatim.d.ts +17 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/osrm.d.ts +15 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/photon.d.ts +22 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-file.d.ts +33 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-route.d.ts +23 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config.d.ts +23 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/geo.d.ts +61 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/index.d.ts +18 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +14 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/staticmap-route.d.ts +31 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/geocode.d.ts +11 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/poi.d.ts +9 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/routes.d.ts +75 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/types.d.ts +68 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +97 -0
- package/ts/package.json +293 -3
- package/ts/scripts/async-collect.ts +91 -0
- package/ts/scripts/map-tools-vendor-package-proof.ts +404 -0
- package/ts/scripts/skeleton-check.ts +1 -1
- package/ts/scripts/skeleton-integration-test.ts +23 -1
- package/ts/scripts/state-cli.ts +568 -0
- package/ts/scripts/turn-handoff-collect.ts +178 -0
- package/ts/src/artifact-gate.ts +991 -0
- package/ts/src/benchmark-agent-conformance.ts +619 -0
- package/ts/src/benchmark-environment-bridge.ts +538 -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 +837 -0
- package/ts/src/booking-saga.ts +133 -0
- package/ts/src/booking-surface/availability-policy.ts +522 -0
- package/ts/src/booking-surface/booking-intent.ts +86 -0
- package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
- package/ts/src/booking-surface/canonical-schema.js +116 -0
- package/ts/src/booking-surface/contracts.ts +475 -0
- package/ts/src/booking-surface/dsh-planner.ts +1949 -0
- package/ts/src/booking-surface/dsh-plugin.js +378 -0
- package/ts/src/booking-surface/dsh-worker.ts +110 -0
- package/ts/src/booking-surface/error-codes.ts +241 -0
- package/ts/src/booking-surface/index.ts +9 -0
- package/ts/src/booking-surface/managed-dsh-cleanup-diagnostic.ts +151 -0
- package/ts/src/booking-surface/managed-dsh-run-port.ts +273 -0
- package/ts/src/booking-surface/profile.ts +42 -0
- package/ts/src/booking-surface/recovery-chain.ts +409 -0
- package/ts/src/booking-surface/runtime.ts +1793 -0
- package/ts/src/booking-surface/server.ts +733 -0
- package/ts/src/booking-surface/startup.ts +201 -0
- package/ts/src/booking-surface/validation.ts +217 -0
- package/ts/src/companions.ts +113 -0
- package/ts/src/contracts.ts +13 -3
- package/ts/src/dsh-llm.ts +44 -11
- package/ts/src/flyai-setup-tool.ts +77 -0
- package/ts/src/index.ts +1948 -198
- package/ts/src/itinerary-deck.ts +189 -0
- package/ts/src/itinerary-doc-shared.ts +741 -0
- package/ts/src/itinerary-html.ts +171 -0
- package/ts/src/loop.ts +223 -25
- package/ts/src/memory-capture.ts +283 -0
- package/ts/src/memory-decay.ts +55 -0
- package/ts/src/memory-utility.ts +70 -0
- package/ts/src/mock-llm.ts +4 -8
- package/ts/src/model.ts +88 -2
- package/ts/src/recall/card.ts +106 -0
- package/ts/src/recall/evaluator.ts +170 -0
- package/ts/src/recall/integration.ts +35 -0
- package/ts/src/recall/tick.ts +213 -0
- package/ts/src/session-link/plan-it-action.ts +78 -0
- package/ts/src/session-link/session-link.ts +275 -0
- package/ts/src/share/adapters.ts +93 -0
- package/ts/src/share/share-consent.ts +105 -0
- package/ts/src/share/share-deck.ts +85 -0
- package/ts/src/share/share-token.ts +166 -0
- package/ts/src/slot-spec.ts +172 -0
- package/ts/src/state-ledger.ts +912 -0
- package/ts/src/subagent-job-id-guard.ts +72 -0
- package/ts/src/time-anchor.ts +338 -0
- package/ts/src/tool-packet.ts +32 -0
- package/ts/src/travel-slots.ts +219 -0
- package/ts/src/travel-timeline.ts +83 -0
- package/ts/src/turn-deadline.ts +366 -0
- package/ts/src/turn-policy.ts +154 -0
- package/ts/src/unified.ts +354 -88
- package/ts/src/wish-pool.ts +79 -0
- package/dist/scripts/session-attach-wait.js +0 -41
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/** Route planning tools: driving / transit / walking / bicycling. */
|
|
2
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
3
|
+
import { AmapQuotaError } from '../clients/amap.js';
|
|
4
|
+
import { parseLngLat } from '../types.js';
|
|
5
|
+
import { simplifyGeometry, shortPlaceName } from '../geo.js';
|
|
6
|
+
/**
|
|
7
|
+
* 把工具返回值投影成卡片元数据(纯函数,可单测)。
|
|
8
|
+
*
|
|
9
|
+
* 上游数据不可信(重放的是历史日志),所以每个字段都做窄化;
|
|
10
|
+
* 几何不足两个点时**省略** `line` 而不是报错——客户端会因此退回文本卡片。
|
|
11
|
+
* @param value - 已通过 schema 校验的工具返回值。
|
|
12
|
+
* @returns 卡片元数据。
|
|
13
|
+
*/
|
|
14
|
+
export function routeCardMeta(value) {
|
|
15
|
+
const line = simplifyGeometry(Array.isArray(value.geometry) ? value.geometry : []);
|
|
16
|
+
return {
|
|
17
|
+
v: 1,
|
|
18
|
+
kind: 'route',
|
|
19
|
+
provider: value.provider === 'osrm' ? 'osrm' : 'amap',
|
|
20
|
+
distanceM: Number.isFinite(value.distanceM) ? value.distanceM : 0,
|
|
21
|
+
durationS: Number.isFinite(value.durationS) ? value.durationS : 0,
|
|
22
|
+
stepCount: Array.isArray(value.steps) ? value.steps.length : 0,
|
|
23
|
+
alternatives: Array.isArray(value.alternatives) ? value.alternatives.length : 0,
|
|
24
|
+
...(line.length >= 2 ? { line } : {}),
|
|
25
|
+
...(typeof value.fromName === 'string' && value.fromName !== '' ? { fromName: value.fromName } : {}),
|
|
26
|
+
...(typeof value.toName === 'string' && value.toName !== '' ? { toName: value.toName } : {}),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** 统一拼装工具返回值:三个返回点(高德/降级 OSRM/纯 OSRM)共用一份。 */
|
|
30
|
+
function routeValue(result, names = {}) {
|
|
31
|
+
return {
|
|
32
|
+
provider: result.provider,
|
|
33
|
+
distanceM: result.distanceM,
|
|
34
|
+
durationS: result.durationS,
|
|
35
|
+
polyline: result.polyline,
|
|
36
|
+
geometry: result.geometry,
|
|
37
|
+
steps: result.steps,
|
|
38
|
+
...(names.fromName !== undefined ? { fromName: names.fromName } : {}),
|
|
39
|
+
...(names.toName !== undefined ? { toName: names.toName } : {}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 给一个端点算"给卡片看的名字"。
|
|
44
|
+
*
|
|
45
|
+
* 参数本身是地名时直接用它(不打任何请求);参数是坐标时反查一次,
|
|
46
|
+
* 把"北京市丰台区北京南站"裁成"北京南站"。反查是**尽力而为**:没有
|
|
47
|
+
* 高德 key、配额超限、或任何异常都退回坐标原文,绝不让卡片因此失败。
|
|
48
|
+
*
|
|
49
|
+
* @param text - 用户/模型传入的原始参数。
|
|
50
|
+
* @param coord - 已解析出的坐标(起终点几何的首尾)。
|
|
51
|
+
* @param clients - 运行时客户端集合。
|
|
52
|
+
* @param signal - 取消信号。
|
|
53
|
+
* @returns 可读名称。
|
|
54
|
+
*/
|
|
55
|
+
async function placeLabel(text, coord, clients, signal) {
|
|
56
|
+
if (parseLngLat(text) === null)
|
|
57
|
+
return text;
|
|
58
|
+
if (!clients.amap)
|
|
59
|
+
return text;
|
|
60
|
+
try {
|
|
61
|
+
const r = await clients.amap.reverseGeocode(coord, signal);
|
|
62
|
+
// **省也要剥**:高德 `formatted_address` 是"省市区街道+具体位置"连写,
|
|
63
|
+
// 第一个前缀就是"湖南省",列表里没有它,后面几个前缀就一个也匹配不上
|
|
64
|
+
// (startsWith 从整串开头比),整串会原样留下——卡片抬头就会变成
|
|
65
|
+
// "湖南省长沙市雨花区东山街道长沙南站"。街道(township)同理,
|
|
66
|
+
// 不剥会得到"右安门街道北京南站"这种半成品。
|
|
67
|
+
const short = shortPlaceName(r.formatted, [r.province, r.city, r.district, r.township]);
|
|
68
|
+
return short === '' ? text : short;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return text;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function routeTool(name, description, mode, clients) {
|
|
75
|
+
const osrmProfile = mode === 'walking' ? 'walking' : mode === 'bicycling' ? 'cycling' : 'driving';
|
|
76
|
+
return defineTool({
|
|
77
|
+
name,
|
|
78
|
+
// 卡片语义是模型必须知道的:Web 界面里"最终答案下方的地图卡"**只镜像本回合**
|
|
79
|
+
// 的路线调用。实测踩坑:模型为补全主路线被截断的分段,在回答回合里顺手算了
|
|
80
|
+
// 一段"别的路口 → 终点"的核对路线,结果卡片画的是那段核对、正文讲的却是主
|
|
81
|
+
// 路线。这里把规则说清楚,模型要么在本回合重算主路线,要么至少知道自己刚才
|
|
82
|
+
// 那次调用会占掉卡片。
|
|
83
|
+
description: `${description} 注意:Web 卡片的路线图只镜像**本回合**的路线调用(本回合算几条就画几条,含为核对细节而算的分段);回答如果引用更早回合的路线,请在本回合用相同起终点再调用一次。`,
|
|
84
|
+
parameters: {
|
|
85
|
+
origin: { type: 'string', required: true, description: 'Start point: an address, or "lng,lat" coordinates.' },
|
|
86
|
+
destination: { type: 'string', required: true, description: 'End point: an address, or "lng,lat" coordinates.' },
|
|
87
|
+
waypoints: { type: 'string', description: 'Optional waypoints as "lng,lat;lng,lat" (Amap driving only).' },
|
|
88
|
+
alternatives: { type: 'boolean', description: 'Request alternative routes (default false).' },
|
|
89
|
+
},
|
|
90
|
+
output: {
|
|
91
|
+
schema: {
|
|
92
|
+
type: 'object',
|
|
93
|
+
additionalProperties: false,
|
|
94
|
+
properties: {
|
|
95
|
+
provider: { type: 'string' },
|
|
96
|
+
distanceM: { type: 'number' },
|
|
97
|
+
durationS: { type: 'number' },
|
|
98
|
+
polyline: { type: 'string' },
|
|
99
|
+
geometry: {
|
|
100
|
+
type: 'array',
|
|
101
|
+
items: { type: 'array', items: { type: 'number' } },
|
|
102
|
+
},
|
|
103
|
+
fromName: { type: 'string' },
|
|
104
|
+
toName: { type: 'string' },
|
|
105
|
+
steps: {
|
|
106
|
+
type: 'array',
|
|
107
|
+
items: {
|
|
108
|
+
type: 'object',
|
|
109
|
+
additionalProperties: false,
|
|
110
|
+
properties: {
|
|
111
|
+
instruction: { type: 'string' },
|
|
112
|
+
distanceM: { type: 'number' },
|
|
113
|
+
durationS: { type: 'number' },
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
alternatives: {
|
|
118
|
+
type: 'array',
|
|
119
|
+
items: {
|
|
120
|
+
type: 'object',
|
|
121
|
+
additionalProperties: false,
|
|
122
|
+
properties: {
|
|
123
|
+
provider: { type: 'string' },
|
|
124
|
+
distanceM: { type: 'number' },
|
|
125
|
+
durationS: { type: 'number' },
|
|
126
|
+
steps: {
|
|
127
|
+
type: 'array',
|
|
128
|
+
items: {
|
|
129
|
+
type: 'object',
|
|
130
|
+
additionalProperties: false,
|
|
131
|
+
properties: {
|
|
132
|
+
instruction: { type: 'string' },
|
|
133
|
+
distanceM: { type: 'number' },
|
|
134
|
+
durationS: { type: 'number' },
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
render: (args, value) => {
|
|
144
|
+
const v = value;
|
|
145
|
+
const mins = (s) => Math.round(s / 60);
|
|
146
|
+
const providerName = v.provider === 'amap' ? '高德' : 'OSRM';
|
|
147
|
+
const distanceText = v.distanceM >= 1000 ? `${(v.distanceM / 1000).toFixed(1)} 公里` : `${v.distanceM} 米`;
|
|
148
|
+
// Amap v5 transit returns no duration field — report it as unknown.
|
|
149
|
+
const durationText = v.durationS > 0 ? `,约 ${mins(v.durationS)} 分钟` : '';
|
|
150
|
+
const lines = [
|
|
151
|
+
`${providerName} 路线:${distanceText}${durationText}`,
|
|
152
|
+
];
|
|
153
|
+
// 回显解析后的起终点名称。坐标入参时这两个名字是**我们按坐标反查出来的**,
|
|
154
|
+
// 模型自己看不到(它的参数里只有一串数字)——实测踩坑:模型为补全分段
|
|
155
|
+
// 指引而地理编码了别的路口,却拿它当了起点,于是"算出来的路线"和它想讲
|
|
156
|
+
// 的完全不是一条。把真名回显出来,模型和读过程区的人都能立刻发现传错。
|
|
157
|
+
if (v.fromName || v.toName) {
|
|
158
|
+
const reversed = parseLngLat(args.origin) !== null || parseLngLat(args.destination) !== null;
|
|
159
|
+
lines.push(`起终点:${v.fromName || '?'} → ${v.toName || '?'}${reversed ? '(坐标反查)' : ''}`);
|
|
160
|
+
}
|
|
161
|
+
// 分段指引:以前固定只给前 12 步、再加一句"共 N 步"。实测这条截断**就是**
|
|
162
|
+
// 一连串问题的起因——模型想回答"最后几步怎么进景区大门",手里却只有前 12 步,
|
|
163
|
+
// 于是自己去地理编码路口、再算一条分段路线来反推;那条探测路线把卡片占掉,
|
|
164
|
+
// 用户看到的地图就变成了另一条路线(正文讲主路线、地图画探测)。
|
|
165
|
+
// 现在给足:≤24 步全给;更长则给前 16 步 + 省略提示 + **最后 6 步**
|
|
166
|
+
// (到达段永远在,模型没有理由再去补算)。
|
|
167
|
+
const STEP_MAX = 24;
|
|
168
|
+
const STEP_HEAD = 16;
|
|
169
|
+
const STEP_TAIL = 6;
|
|
170
|
+
if (v.steps.length <= STEP_MAX) {
|
|
171
|
+
for (const s of v.steps)
|
|
172
|
+
lines.push(`- ${s.instruction}`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
for (const s of v.steps.slice(0, STEP_HEAD))
|
|
176
|
+
lines.push(`- ${s.instruction}`);
|
|
177
|
+
lines.push(`- …(中间省略 ${v.steps.length - STEP_HEAD - STEP_TAIL} 步,共 ${v.steps.length} 步)`);
|
|
178
|
+
for (const s of v.steps.slice(v.steps.length - STEP_TAIL))
|
|
179
|
+
lines.push(`- ${s.instruction}`);
|
|
180
|
+
}
|
|
181
|
+
if (v.alternatives?.length) {
|
|
182
|
+
lines.push(`另有 ${v.alternatives.length} 条备选路线:`);
|
|
183
|
+
for (const a of v.alternatives) {
|
|
184
|
+
const aName = a.provider === 'amap' ? '高德' : 'OSRM';
|
|
185
|
+
lines.push(` - ${aName}:${(a.distanceM / 1000).toFixed(1)} 公里 / ${mins(a.durationS)} 分钟`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
189
|
+
},
|
|
190
|
+
// 卡片数据:抽稀后的几何 + 距离/耗时/分段数,随会话日志持久化,
|
|
191
|
+
// 由客户端 client/client.js 注册的同名 toolview 读取(内置 Web 客户端
|
|
192
|
+
// 不消费 presentCall/presentResult,UI 走 tool.call.toolview 槽位)。
|
|
193
|
+
presentationMeta: (_args, value) => routeCardMeta(value),
|
|
194
|
+
},
|
|
195
|
+
async execute(args, exec) {
|
|
196
|
+
let origin;
|
|
197
|
+
let destination;
|
|
198
|
+
try {
|
|
199
|
+
origin = parseLngLat(args.origin) ?? (await clients.resolve(args.origin, exec.signal));
|
|
200
|
+
destination = parseLngLat(args.destination) ?? (await clients.resolve(args.destination, exec.signal));
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
// 地址解析阶段的高德配额超限:没有坐标就无法降级,转成可操作提示。
|
|
204
|
+
if (err instanceof AmapQuotaError) {
|
|
205
|
+
throw new Error(`地址解析暂时不可用(${err.message})。请稍后重试,或直接提供 "lng,lat" 坐标。`);
|
|
206
|
+
}
|
|
207
|
+
throw err;
|
|
208
|
+
}
|
|
209
|
+
// 起终点名称:模型常常先用 map_geocode 把地名换成坐标再调路线工具,
|
|
210
|
+
// 那样参数里就只剩坐标。坐标入参时反查一次,卡片才显示得出地名。
|
|
211
|
+
// (地名入参不打任何额外请求;反查失败退回原文。)
|
|
212
|
+
const [fromName, toName] = await Promise.all([
|
|
213
|
+
placeLabel(args.origin, origin, clients, exec.signal),
|
|
214
|
+
placeLabel(args.destination, destination, clients, exec.signal),
|
|
215
|
+
]);
|
|
216
|
+
const names = { fromName, toName };
|
|
217
|
+
// Provider priority: Amap → OSRM free fallback.
|
|
218
|
+
if (clients.amap) {
|
|
219
|
+
try {
|
|
220
|
+
let city1;
|
|
221
|
+
let city2;
|
|
222
|
+
try {
|
|
223
|
+
city1 = mode === 'transit' ? await clients.resolveCity(args.origin, exec.signal) : undefined;
|
|
224
|
+
city2 = mode === 'transit' ? await clients.resolveCity(args.destination, exec.signal) : undefined;
|
|
225
|
+
}
|
|
226
|
+
catch (err) {
|
|
227
|
+
// 城市解析也受高德配额影响;公交没有 city 无法请求,但非公交不受影响。
|
|
228
|
+
if (err instanceof AmapQuotaError && mode === 'transit') {
|
|
229
|
+
throw new Error(`公交路线需要城市解析,但高德暂不可用(${err.message})。请稍后重试,或改用驾车/步行/骑行路线(自动降级 OSRM 免费源)。`);
|
|
230
|
+
}
|
|
231
|
+
throw err;
|
|
232
|
+
}
|
|
233
|
+
const result = await clients.amap.route(origin, destination, mode, { city1, city2 }, exec.signal);
|
|
234
|
+
const out = routeValue(result, names);
|
|
235
|
+
if (args.waypoints && mode === 'driving') {
|
|
236
|
+
out.waypoints = args.waypoints.split(';').map((w) => w.trim()).filter(Boolean).join(';');
|
|
237
|
+
}
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
// 高德配额超限(QPS/日配额):非公交模式自动降级 OSRM 兜底,
|
|
242
|
+
// 公交无免费兜底源,给用户可操作的提示。
|
|
243
|
+
if (err instanceof AmapQuotaError) {
|
|
244
|
+
if (mode === 'transit') {
|
|
245
|
+
throw new Error(`高德公交路线暂不可用(${err.message})。请稍后重试,或改用驾车/步行/骑行路线(自动降级 OSRM 免费源)。`);
|
|
246
|
+
}
|
|
247
|
+
const result = await clients.osrm.route(origin, destination, osrmProfile, exec.signal);
|
|
248
|
+
return routeValue(result, names);
|
|
249
|
+
}
|
|
250
|
+
throw err;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Fallback: OSRM (driving/walking/cycling only; no transit).
|
|
254
|
+
if (mode === 'transit') {
|
|
255
|
+
throw new Error('公交路线需要高德 key。请在插件配置中设置 amapKey(https://console.amap.com/dev/key/app)。');
|
|
256
|
+
}
|
|
257
|
+
const result = await clients.osrm.route(origin, destination, osrmProfile, exec.signal);
|
|
258
|
+
return routeValue(result, names);
|
|
259
|
+
},
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
export function registerRouteTools(ctx, clients, disposers = []) {
|
|
263
|
+
disposers.push(ctx.tools.register(routeTool('map_driving_route', '规划驾车路线,返回距离、预计耗时和分段指引。起点/终点支持地址或 "lng,lat" 坐标。', 'driving', clients)));
|
|
264
|
+
disposers.push(ctx.tools.register(routeTool('map_transit_route', '规划公交/地铁换乘路线(需配置高德 amapKey),返回距离、耗时和多段换乘指引。', 'transit', clients)));
|
|
265
|
+
disposers.push(ctx.tools.register(routeTool('map_walking_route', '规划步行路线,返回距离、预计耗时和分段指引。', 'walking', clients)));
|
|
266
|
+
disposers.push(ctx.tools.register(routeTool('map_bicycling_route', '规划骑行路线,返回距离、预计耗时和分段指引。', 'bicycling', clients)));
|
|
267
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/** Amap (高德) Web Service API client. */
|
|
2
|
+
import type { GeocodeResult, LngLat, PoiResult, RouteResult } from '../types.js';
|
|
3
|
+
/** 配额类错误(QPS 或日配额超限)。retryable=true 时短期内重试可能成功
|
|
4
|
+
* (QPS 超限),false 表示重试无意义(日配额已用尽)。 */
|
|
5
|
+
export declare class AmapQuotaError extends Error {
|
|
6
|
+
readonly infocode: string;
|
|
7
|
+
readonly retryable: boolean;
|
|
8
|
+
constructor(infocode: string, message: string, retryable: boolean);
|
|
9
|
+
}
|
|
10
|
+
export interface AmapClientOptions {
|
|
11
|
+
key: string;
|
|
12
|
+
timeoutMs: number;
|
|
13
|
+
/** 每秒最大高德请求数(默认 2,低于高德常见 3 QPS 上限,留余量防 10021)。 */
|
|
14
|
+
maxQps?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare class AmapClient {
|
|
17
|
+
private readonly opts;
|
|
18
|
+
private readonly limiter;
|
|
19
|
+
private readonly geoCache;
|
|
20
|
+
private readonly routeCache;
|
|
21
|
+
private readonly poiCache;
|
|
22
|
+
/** 静态地图字节缓存:同一张图不重复计费。 */
|
|
23
|
+
private readonly mapCache;
|
|
24
|
+
constructor(opts: AmapClientOptions);
|
|
25
|
+
/**
|
|
26
|
+
* 带配额保护的统一请求入口:限速排队 → 缓存命中 → 请求 → 可重试错误退避
|
|
27
|
+
* 重试 → 写入缓存。
|
|
28
|
+
*/
|
|
29
|
+
private request;
|
|
30
|
+
/** 裸 GET:拼 URL、带 key、超时 + abort、错误分类。 */
|
|
31
|
+
private rawGet;
|
|
32
|
+
/**
|
|
33
|
+
* 把高德返回的错误码翻译成面向用户的异常(key / 配额 / 其它)。
|
|
34
|
+
* @param infocode - 高德 `infocode`。
|
|
35
|
+
* @param info - 高德 `info` 文案。
|
|
36
|
+
*/
|
|
37
|
+
private throwAmapError;
|
|
38
|
+
/**
|
|
39
|
+
* 裸 GET,返回二进制(静态地图)。高德出错时返回 JSON 而不是图片,
|
|
40
|
+
* 所以响应不是 image/* 就按错误体解析。
|
|
41
|
+
*/
|
|
42
|
+
private rawGetBytes;
|
|
43
|
+
/**
|
|
44
|
+
* 静态地图:一张**真地图** PNG,路线折线与起终点标注由高德绘制。
|
|
45
|
+
*
|
|
46
|
+
* 取景框**交给高德自己适配**——不传 `location`,不传 `zoom`。这里踩过
|
|
47
|
+
* 一个很贵的坑:高德静态地图的 `zoom` 与标准 Web Mercator 差一级
|
|
48
|
+
* (它的 12 级才等于 256px 瓦片的 13 级),于是按 Mercator 公式"算准了
|
|
49
|
+
* 装得下"的 zoom 实际被放大一倍,路线溢出画布;而高德**不报错**,只是
|
|
50
|
+
* 静默把整条 `paths` 丢掉——现象正是"有底图、没路线"。
|
|
51
|
+
*
|
|
52
|
+
* 只给 `paths`(+`markers`)时高德按外包框自适应取景,实测 0.8km 步行、
|
|
53
|
+
* 20.9km 驾车、1205km 跨省、公交链各种尺度都完整居中、不裁切。
|
|
54
|
+
*
|
|
55
|
+
* 结果按参数缓存,同一张图不会被反复计费。
|
|
56
|
+
*
|
|
57
|
+
* @param line - 路线几何(GCJ-02,与高德出图坐标系一致)。
|
|
58
|
+
* @param opts - 画布尺寸与是否画起终点标注。
|
|
59
|
+
* @param signal - 取消信号。
|
|
60
|
+
* @returns PNG 字节。
|
|
61
|
+
*/
|
|
62
|
+
staticMap(line: readonly LngLat[], opts: {
|
|
63
|
+
width: number;
|
|
64
|
+
height: number;
|
|
65
|
+
markers?: boolean;
|
|
66
|
+
}, signal: AbortSignal): Promise<Uint8Array>;
|
|
67
|
+
/**
|
|
68
|
+
* Plan a route. `mode` maps to the Amap endpoint.
|
|
69
|
+
* Transit requires city1/city2 (origin/destination city names).
|
|
70
|
+
*/
|
|
71
|
+
route(origin: LngLat, destination: LngLat, mode: 'driving' | 'transit' | 'walking' | 'bicycling', opts: {
|
|
72
|
+
city1?: string;
|
|
73
|
+
city2?: string;
|
|
74
|
+
} | undefined, signal: AbortSignal): Promise<RouteResult>;
|
|
75
|
+
private transitRoute;
|
|
76
|
+
/** Forward geocode: address → coordinates. */
|
|
77
|
+
geocode(address: string, signal: AbortSignal): Promise<GeocodeResult>;
|
|
78
|
+
/** Reverse geocode: coordinates → address. */
|
|
79
|
+
reverseGeocode(location: LngLat, signal: AbortSignal): Promise<GeocodeResult>;
|
|
80
|
+
/** POI text search. */
|
|
81
|
+
poiSearch(keywords: string, opts: {
|
|
82
|
+
region?: string;
|
|
83
|
+
cityLimit?: boolean;
|
|
84
|
+
}, signal: AbortSignal): Promise<PoiResult[]>;
|
|
85
|
+
/** POI around search (nearest first by default). */
|
|
86
|
+
poiAround(location: LngLat, keywords: string, opts: {
|
|
87
|
+
radiusM?: number;
|
|
88
|
+
types?: string;
|
|
89
|
+
}, signal: AbortSignal): Promise<PoiResult[]>;
|
|
90
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Nominatim (OpenStreetMap) geocoding client — free fallback, 1 QPS policy. */
|
|
2
|
+
import type { GeocodeResult, LngLat } from '../types.js';
|
|
3
|
+
export interface NominatimClientOptions {
|
|
4
|
+
timeoutMs: number;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
/** User-Agent identifying the client (required by Nominatim usage policy). */
|
|
7
|
+
userAgent: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class NominatimClient {
|
|
10
|
+
private readonly opts;
|
|
11
|
+
constructor(opts: NominatimClientOptions);
|
|
12
|
+
private get;
|
|
13
|
+
/** Forward geocode. */
|
|
14
|
+
geocode(query: string, signal: AbortSignal): Promise<GeocodeResult>;
|
|
15
|
+
/** Reverse geocode. */
|
|
16
|
+
reverseGeocode(location: LngLat, signal: AbortSignal): Promise<GeocodeResult>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** OSRM public server client — free route fallback (no API key). */
|
|
2
|
+
import type { LngLat, RouteResult } from '../types.js';
|
|
3
|
+
export interface OsrmClientOptions {
|
|
4
|
+
timeoutMs: number;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class OsrmClient {
|
|
8
|
+
private readonly opts;
|
|
9
|
+
constructor(opts: OsrmClientOptions);
|
|
10
|
+
/**
|
|
11
|
+
* Plan a route. `profile` maps to OSRM profiles: driving | walking | cycling.
|
|
12
|
+
* OSRM has no transit profile — callers must not request transit here.
|
|
13
|
+
*/
|
|
14
|
+
route(origin: LngLat, destination: LngLat, profile: 'driving' | 'walking' | 'cycling', signal: AbortSignal): Promise<RouteResult>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Photon (photon.komoot.io) geocoding client — free, keyless, reachable on CN
|
|
3
|
+
* networks (unlike nominatim.openstreetmap.org). Backed by OpenStreetMap data.
|
|
4
|
+
*
|
|
5
|
+
* Usage policy: free public service; be reasonable with request rate. Add a
|
|
6
|
+
* `lang` parameter (default zh) for localized results.
|
|
7
|
+
*/
|
|
8
|
+
import type { GeocodeResult, LngLat } from '../types.js';
|
|
9
|
+
export interface PhotonClientOptions {
|
|
10
|
+
timeoutMs: number;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
lang?: 'zh' | 'en';
|
|
13
|
+
}
|
|
14
|
+
export declare class PhotonClient {
|
|
15
|
+
private readonly opts;
|
|
16
|
+
constructor(opts: PhotonClientOptions);
|
|
17
|
+
private get;
|
|
18
|
+
/** Forward geocode. */
|
|
19
|
+
geocode(query: string, signal: AbortSignal): Promise<GeocodeResult>;
|
|
20
|
+
/** Reverse geocode. */
|
|
21
|
+
reverseGeocode(location: LngLat, signal: AbortSignal): Promise<GeocodeResult>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-map-tools persisted config file (~/.dsh-map-tools/config.json).
|
|
3
|
+
*
|
|
4
|
+
* Follows the modlens pattern: the plugin's API keys and provider choice live
|
|
5
|
+
* in its own file (shared across profiles, never in the DSH settings
|
|
6
|
+
* document), and the settings card reads/writes it through a loopback route.
|
|
7
|
+
*/
|
|
8
|
+
/** The file the plugin's settings card reads and writes. Overridable for tests. */
|
|
9
|
+
export declare function configPath(): string;
|
|
10
|
+
/** What the plugin persists and serves to the settings card. */
|
|
11
|
+
export interface MapToolsFileConfig {
|
|
12
|
+
provider?: 'amap' | 'osm';
|
|
13
|
+
amapKey?: string;
|
|
14
|
+
timeoutMs?: number;
|
|
15
|
+
maxQps?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Read the shared config, or a thrown error. Only a missing file reads as
|
|
19
|
+
* empty: an existing-but-unparsable file is somebody's configuration, and a
|
|
20
|
+
* card that treated it as empty would overwrite it on the next save.
|
|
21
|
+
*/
|
|
22
|
+
export declare function readConfig(): MapToolsFileConfig;
|
|
23
|
+
/** Persist a patch onto the config file, then return the new whole. */
|
|
24
|
+
export declare function applyConfig(patch: Partial<MapToolsFileConfig>): MapToolsFileConfig;
|
|
25
|
+
/** Whether the config file exists (the card can offer "open config file"). */
|
|
26
|
+
export declare function configFileExists(): boolean;
|
|
27
|
+
/** Non-secret summary served to the settings card (keys are never echoed). */
|
|
28
|
+
export declare function configSummary(): {
|
|
29
|
+
provider: MapToolsFileConfig['provider'];
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
maxQps?: number;
|
|
32
|
+
hasAmapKey: boolean;
|
|
33
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loopback settings-card route for dsh-map-tools.
|
|
3
|
+
*
|
|
4
|
+
* GET /dsh-map-tools/config → non-secret summary (has-amap-key, …)
|
|
5
|
+
* GET /dsh-map-tools/config?open=true → open the config file in the editor
|
|
6
|
+
* POST /dsh-map-tools/config → apply a provider/key/timeout patch
|
|
7
|
+
*
|
|
8
|
+
* Same-origin loopback only (mirrors dsh's own /api fence and the modlens
|
|
9
|
+
* pattern); the two halves of the card read/write a real file.
|
|
10
|
+
*/
|
|
11
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
12
|
+
import type { IncomingMessage } from 'node:http';
|
|
13
|
+
/** Refuse cross-origin and non-loopback requests (the route answers same-origin loopback only). */
|
|
14
|
+
export declare function isTrustedRequest(req: IncomingMessage): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Register the settings-card route under the web server, when one exists.
|
|
17
|
+
*
|
|
18
|
+
* @param ctx - plugin context.
|
|
19
|
+
* @param reload - rebuild the tools after the card saves (the file write alone
|
|
20
|
+
* never reaches the registered tool instances; without this the new provider
|
|
21
|
+
* or key only takes effect on the next plugin reload).
|
|
22
|
+
*/
|
|
23
|
+
export declare function installConfigRoute(ctx: Context, reload?: () => void): void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Plugin configuration schema. */
|
|
2
|
+
import Schema from '@deepseek-ai/schemastery';
|
|
3
|
+
export interface Config {
|
|
4
|
+
/**
|
|
5
|
+
* Provider selection:
|
|
6
|
+
* - 'amap': 高德地图(Web 服务 API key,免费申请,推荐)
|
|
7
|
+
* - 'osm': 免费 OSM/OSRM 兜底(无 key,能力有限)
|
|
8
|
+
*/
|
|
9
|
+
provider: 'amap' | 'osm';
|
|
10
|
+
/** Amap (高德) Web Service API key. */
|
|
11
|
+
amapKey?: string;
|
|
12
|
+
/** Per-request timeout in milliseconds. */
|
|
13
|
+
timeoutMs: number;
|
|
14
|
+
/** Amap requests per second cap (高德个人 key QPS 上限低,默认 2 留余量). */
|
|
15
|
+
maxQps: number;
|
|
16
|
+
/** Default route mode when a generic route is requested. */
|
|
17
|
+
defaultMode: 'driving' | 'transit' | 'walking' | 'bicycling';
|
|
18
|
+
/** Language hint for providers that support it. */
|
|
19
|
+
language: 'zh' | 'en';
|
|
20
|
+
}
|
|
21
|
+
/** Amap apply URL (shown as a clickable link in the settings card). */
|
|
22
|
+
export declare const AMAP_APPLY_URL = "https://console.amap.com/dev/key/app";
|
|
23
|
+
export declare const Config: Schema<Config>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 路线几何的纯函数工具:解码、抽稀、取整。
|
|
3
|
+
*
|
|
4
|
+
* 这些函数是 UI 卡片的输入准备层——它们决定"会话日志里到底存了多少个点"。
|
|
5
|
+
* 全是纯函数(无 I/O、无时钟、无随机),便于单元测试。
|
|
6
|
+
*/
|
|
7
|
+
import type { LngLat } from './types.js';
|
|
8
|
+
/** 会话日志里一条路线最多保留的几何点数(卡片是示意图,不需要原始精度)。 */
|
|
9
|
+
export declare const MAX_GEOMETRY_POINTS = 200;
|
|
10
|
+
/**
|
|
11
|
+
* 解码高德的紧凑折线串 `"lng,lat;lng,lat;…"`。
|
|
12
|
+
* 非法片段被跳过(上游数据不可信,宁可少画一点也不抛错)。
|
|
13
|
+
* @param text - 高德 `polyline` 字段原文。
|
|
14
|
+
* @returns 解析出的坐标序列(可能为空)。
|
|
15
|
+
*/
|
|
16
|
+
export declare function decodeAmapPolyline(text: string | undefined): LngLat[];
|
|
17
|
+
/** 去掉相邻重复点(按取整后的坐标比较),并丢弃非法点。 */
|
|
18
|
+
export declare function dedupeGeometry(points: readonly LngLat[]): LngLat[];
|
|
19
|
+
/**
|
|
20
|
+
* 抽稀一条路线几何,使其点数不超过 `maxPoints`。
|
|
21
|
+
*
|
|
22
|
+
* 阈值从包围盒对角线推导(自适应:长途粗、短途细——40 公里路线约 40 米,
|
|
23
|
+
* 200 米步行路线约 0.2 米),逐步放宽直到达标;若 Douglas–Peucker 仍不达标
|
|
24
|
+
* (例如密集的锯齿路径),再做等间隔兜底。首尾点始终保留,坐标统一取整到
|
|
25
|
+
* 5 位小数。
|
|
26
|
+
*
|
|
27
|
+
* 注意:即使点数没超上限也会跑一遍抽稀——直线上的冗余点同样要丢掉,
|
|
28
|
+
* 因为产物要写进会话日志。
|
|
29
|
+
*
|
|
30
|
+
* @param points - 原始几何点(可为空、可含重复/非法点)。
|
|
31
|
+
* @param maxPoints - 点数上限,默认 {@link MAX_GEOMETRY_POINTS}。
|
|
32
|
+
* @returns 抽稀并取整后的几何(点数 ≤ `maxPoints`)。
|
|
33
|
+
*/
|
|
34
|
+
export declare function simplifyGeometry(points: readonly LngLat[], maxPoints?: number): LngLat[];
|
|
35
|
+
/**
|
|
36
|
+
* 把几何压成高德风格的紧凑串 `"lng,lat;lng,lat"`(日志体积的一档压缩)。
|
|
37
|
+
* @param points - 已取整的几何点。
|
|
38
|
+
* @returns 紧凑串;空序列返回空串。
|
|
39
|
+
*/
|
|
40
|
+
export declare function encodeGeometry(points: readonly LngLat[]): string;
|
|
41
|
+
/**
|
|
42
|
+
* 把高德的长地址裁成可读的短地名。
|
|
43
|
+
*
|
|
44
|
+
* 高德反查返回的 `formatted_address` 是"省市区街道 + 具体位置"连写(如
|
|
45
|
+
* "北京市丰台区右安门街道北京南站")。把已知的省/市/区/街道前缀依次剥掉、
|
|
46
|
+
* 再去掉尾部括号补充,剩下的就是用户认得的那个名字。
|
|
47
|
+
* 剥完为空则原样返回(宁可长,也不要空)。
|
|
48
|
+
*
|
|
49
|
+
* @param formatted - 高德 `formatted_address`。
|
|
50
|
+
* @param strip - 要剥掉的前缀(省 / 市 / 区 / 街道)。
|
|
51
|
+
* @returns 短地名。
|
|
52
|
+
*/
|
|
53
|
+
export declare function shortPlaceName(formatted: string, strip: readonly (string | undefined)[]): string;
|
|
54
|
+
/**
|
|
55
|
+
* 抽稀到最多 `maxPoints` 个点,再编成紧凑串(用于塞进 URL query)。
|
|
56
|
+
* 静态地图不需要 200 个点,太长会把 URL 撑爆。
|
|
57
|
+
* @param points - 路线几何。
|
|
58
|
+
* @param maxPoints - 点数上限。
|
|
59
|
+
* @returns `"lng,lat;…"`。
|
|
60
|
+
*/
|
|
61
|
+
export declare function compactLine(points: readonly LngLat[], maxPoints?: number): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-map-tools — map & routing tools for DeepSeek Harness.
|
|
3
|
+
*
|
|
4
|
+
* Registers 7 native tools:
|
|
5
|
+
* map_driving_route / map_transit_route / map_walking_route / map_bicycling_route
|
|
6
|
+
* map_geocode / map_reverse_geocode / map_poi_search
|
|
7
|
+
*
|
|
8
|
+
* Data sources: OSM/OSRM/Nominatim free fallback by default (zero-key); when
|
|
9
|
+
* amapKey is configured (or provider='amap'), Amap (高德) is used for best
|
|
10
|
+
* CN data quality (transit + POI require Amap).
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
13
|
+
import { Config } from './config.js';
|
|
14
|
+
import type { Config as ConfigType } from './config.js';
|
|
15
|
+
export declare const name = "dsh-map-tools";
|
|
16
|
+
export declare const inject: string[];
|
|
17
|
+
export { Config };
|
|
18
|
+
export declare function apply(ctx: Context, config: ConfigType): void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import type { Config as ConfigType } from './config.js';
|
|
3
|
+
/** Namespace the settings page keys this plugin's card to (plain string since DSH 0.1.2-rc.1). */
|
|
4
|
+
export declare const MAP_TOOLS_NS = "dsh-map-tools";
|
|
5
|
+
/**
|
|
6
|
+
* Wire the settings section so the card renders. The values live in the
|
|
7
|
+
* config file; the section carries only the composition entry as its base so
|
|
8
|
+
* the page has something to dispatch on.
|
|
9
|
+
*
|
|
10
|
+
* @param ctx - plugin context.
|
|
11
|
+
* @param entry - the composition entry config (schema defaults).
|
|
12
|
+
* @param reload - rebuild tools after a settings change.
|
|
13
|
+
*/
|
|
14
|
+
export declare function installSettingsNamespace(ctx: Context, entry: ConfigType, reload: () => void): void;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loopback route serving the route-card's static map image.
|
|
3
|
+
*
|
|
4
|
+
* GET /dsh-map-tools/staticmap?w=640&h=260&line=lng,lat;lng,lat;…
|
|
5
|
+
*
|
|
6
|
+
* 为什么走回环路由而不是把图片塞进工具结果:
|
|
7
|
+
* 1. **key 不出宿主**——浏览器只拿到一张本地图片 URL,高德 key 始终在服务端;
|
|
8
|
+
* 2. **不进模型上下文**——工具结果里放 image block 会被适配器跳过/或消耗
|
|
9
|
+
* 视觉额度,而卡片要的只是一张示意图;
|
|
10
|
+
* 3. **懒加载 + 可缓存**——只有卡片真正渲染时才取图,且服务端按参数缓存。
|
|
11
|
+
*
|
|
12
|
+
* 拿不到图(没 key / 配额超限 / 网络问题)时返回错误状态码,客户端卡片会
|
|
13
|
+
* 自动降级为自绘示意图(client/client.js 里的 svg 兜底)。
|
|
14
|
+
*/
|
|
15
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
16
|
+
import type { AmapClient } from './clients/amap.js';
|
|
17
|
+
import { type LngLat } from './types.js';
|
|
18
|
+
/** 解析 `line=lng,lat;lng,lat;…`;非法片段跳过,超过上限则等间隔截断。 */
|
|
19
|
+
export declare function parseLineParam(raw: string | null): LngLat[];
|
|
20
|
+
/** 把尺寸参数钳制到合法范围(默认 640×260)。 */
|
|
21
|
+
export declare function parseSizeParam(w: string | null, h: string | null): {
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Register the static-map route under the web server, when one exists.
|
|
27
|
+
*
|
|
28
|
+
* @param ctx - plugin context.
|
|
29
|
+
* @param getAmap - reads the current Amap client (rebuilt on every config save).
|
|
30
|
+
*/
|
|
31
|
+
export declare function installStaticMapRoute(ctx: Context, getAmap: () => AmapClient | undefined): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Geocoding tools: address → coordinates, and reverse. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { AmapClient } from '../clients/amap.js';
|
|
4
|
+
import type { NominatimClient } from '../clients/nominatim.js';
|
|
5
|
+
import type { PhotonClient } from '../clients/photon.js';
|
|
6
|
+
export interface GeocodeClients {
|
|
7
|
+
amap?: AmapClient;
|
|
8
|
+
nominatim?: NominatimClient;
|
|
9
|
+
photon?: PhotonClient;
|
|
10
|
+
}
|
|
11
|
+
export declare function registerGeocodeTools(ctx: Context, clients: GeocodeClients, disposers?: Array<() => void>): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** POI search tool. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { AmapClient } from '../clients/amap.js';
|
|
4
|
+
export interface PoiClients {
|
|
5
|
+
amap?: AmapClient;
|
|
6
|
+
/** Resolve an address (or `lng,lat`) to coordinates; throws with a helpful message. */
|
|
7
|
+
resolve: (text: string, signal: AbortSignal) => Promise<[number, number]>;
|
|
8
|
+
}
|
|
9
|
+
export declare function registerPoiTool(ctx: Context, clients: PoiClients, disposers?: Array<() => void>): void;
|