@danceiny/gotry 0.0.1-rc.21 → 0.0.1-rc.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. package/README.md +102 -194
  2. package/README.zh-CN.md +115 -210
  3. package/bin/gotry-backend.js +53 -0
  4. package/bin/gotry-bootstrap.js +466 -35
  5. package/bin/gotry-inner.js +255 -36
  6. package/bin/gotry-process-liveness.d.ts +27 -0
  7. package/bin/gotry-process-liveness.js +97 -0
  8. package/bin/gotry-runtime-resolution.d.ts +1 -1
  9. package/bin/gotry-runtime-resolution.js +2 -2
  10. package/client/client.js +174 -0
  11. package/cordis.gotry-patch.yml +70 -93
  12. package/dist/capabilities/agent-reach-deep.js +45 -122
  13. package/dist/capabilities/agent-reach.js +63 -148
  14. package/dist/capabilities/anything.js +89 -75
  15. package/dist/capabilities/artifacts.js +123 -104
  16. package/dist/capabilities/channel-health.js +65 -45
  17. package/dist/capabilities/channel-registry.js +108 -87
  18. package/dist/capabilities/doctor.js +357 -235
  19. package/dist/capabilities/effect.js +223 -309
  20. package/dist/capabilities/fact-log.js +28 -14
  21. package/dist/capabilities/flyai.js +245 -156
  22. package/dist/capabilities/ground-transfer.js +509 -0
  23. package/dist/capabilities/hbcli.js +144 -148
  24. package/dist/capabilities/hotelbyte-transaction.js +194 -0
  25. package/dist/capabilities/incident-log.js +131 -61
  26. package/dist/capabilities/model-override.js +30 -10
  27. package/dist/capabilities/opensky.js +54 -43
  28. package/dist/capabilities/resilience.js +50 -32
  29. package/dist/capabilities/session/action-cache.js +50 -44
  30. package/dist/capabilities/session/adapters/ctrip-flight.js +119 -62
  31. package/dist/capabilities/session/adapters/ctrip-hotel.js +125 -110
  32. package/dist/capabilities/session/adapters/dida-portal.js +206 -0
  33. package/dist/capabilities/session/adapters/meituan-local.js +35 -54
  34. package/dist/capabilities/session/adapters/rail-12306.js +169 -112
  35. package/dist/capabilities/session/benchmark.js +85 -149
  36. package/dist/capabilities/session/extension-bridge.js +320 -259
  37. package/dist/capabilities/session/extension-channel.js +57 -76
  38. package/dist/capabilities/session/extension-distribution.js +115 -119
  39. package/dist/capabilities/session/extract.js +31 -21
  40. package/dist/capabilities/session/golden-score.js +55 -33
  41. package/dist/capabilities/session/health-watch.js +146 -154
  42. package/dist/capabilities/session/read-guard.js +55 -47
  43. package/dist/capabilities/session/static-flight-golden.js +49 -36
  44. package/dist/capabilities/session/transport.js +54 -61
  45. package/dist/capabilities/session/wizard.js +63 -93
  46. package/dist/capabilities/session-consent.js +143 -47
  47. package/dist/capabilities/session-login.js +95 -126
  48. package/dist/capabilities/session-search.js +391 -253
  49. package/dist/capabilities/sponsor-plugin.js +341 -0
  50. package/dist/capabilities/visa-policy.js +87 -73
  51. package/dist/capabilities/weather.js +163 -235
  52. package/dist/scripts/action-cache-tests.js +24 -59
  53. package/dist/scripts/agent-planning-turn-deadline-e2e.js +91 -142
  54. package/dist/scripts/agent-planning-turn-deadline-tests.js +80 -176
  55. package/dist/scripts/agent-reach-deep-tests.js +30 -40
  56. package/dist/scripts/agent-reach-tests.js +26 -18
  57. package/dist/scripts/agent-reach-wrapper-tests.js +46 -50
  58. package/dist/scripts/anything-tests.js +58 -62
  59. package/dist/scripts/artifact-client-contract-tests.js +69 -0
  60. package/dist/scripts/artifacts-capability-tests.js +235 -0
  61. package/dist/scripts/async-collect.js +26 -15
  62. package/dist/scripts/benchmark-environment-bridge-e2e.js +287 -684
  63. package/dist/scripts/benchmark-environment-bridge-tests.js +818 -3123
  64. package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +66 -279
  65. package/dist/scripts/booking-copilot-availability-policy-tests.js +153 -1257
  66. package/dist/scripts/booking-copilot-bin-proof-tests.js +22 -45
  67. package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +64 -76
  68. package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +69 -199
  69. package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +393 -759
  70. package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +33 -75
  71. package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +60 -110
  72. package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +28 -66
  73. package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +72 -271
  74. package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +73 -275
  75. package/dist/scripts/booking-copilot-runtime-proof-tests.js +784 -3398
  76. package/dist/scripts/booking-copilot-server-proof-tests.js +63 -168
  77. package/dist/scripts/booking-copilot-startup-proof-tests.js +38 -124
  78. package/dist/scripts/booking-executor-tests.js +80 -0
  79. package/dist/scripts/booking-recovery-chain-tests.js +182 -0
  80. package/dist/scripts/booking-saga-tests.js +61 -123
  81. package/dist/scripts/booking-surface-contract-proof-tests.js +152 -1167
  82. package/dist/scripts/bootstrap-tests.js +1383 -128
  83. package/dist/scripts/build-changelog.js +89 -130
  84. package/dist/scripts/build-metrics-report.js +135 -143
  85. package/dist/scripts/changelog-tests.js +35 -82
  86. package/dist/scripts/channel-probe-tests.js +44 -116
  87. package/dist/scripts/channel-probe.js +84 -167
  88. package/dist/scripts/channel-registry-tests.js +97 -185
  89. package/dist/scripts/companion-tests.js +25 -70
  90. package/dist/scripts/dida-cookie-probe.js +87 -0
  91. package/dist/scripts/dida-sw-probe.js +114 -0
  92. package/dist/scripts/diff-test.js +17 -12
  93. package/dist/scripts/doctor-tests.js +428 -120
  94. package/dist/scripts/dsh-artifact-e2e.js +150 -0
  95. package/dist/scripts/dsh-artifact-web-e2e.js +443 -0
  96. package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
  97. package/dist/scripts/dsh-runtime-closure-tests.js +110 -153
  98. package/dist/scripts/dsh-runtime-closure.js +75 -63
  99. package/dist/scripts/dsh-session-v3-migration-proof.js +106 -0
  100. package/dist/scripts/dsh-subprocess-local-proof.js +149 -0
  101. package/dist/scripts/dsh-target-closure-proof.js +178 -0
  102. package/dist/scripts/effect-tests.js +165 -552
  103. package/dist/scripts/engine-run.js +1 -3
  104. package/dist/scripts/engine-tests.js +16 -10
  105. package/dist/scripts/evaluation-cadence-tests.js +69 -242
  106. package/dist/scripts/evaluation-contract-tests.js +193 -499
  107. package/dist/scripts/extension-distribution-cli.js +19 -15
  108. package/dist/scripts/extension-distribution-tests.js +98 -211
  109. package/dist/scripts/extension-tests.js +366 -389
  110. package/dist/scripts/fact-gate-tests.js +725 -263
  111. package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
  112. package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
  113. package/dist/scripts/flight-malformed-tests.js +159 -0
  114. package/dist/scripts/flyai-tests.js +325 -68
  115. package/dist/scripts/g5-guard-tests.js +131 -0
  116. package/dist/scripts/g5-guard.js +189 -0
  117. package/dist/scripts/gen-lunar-anchors.js +106 -0
  118. package/dist/scripts/gotry-backend-kernel-tests.js +79 -0
  119. package/dist/scripts/ground-transfer-tests.js +956 -0
  120. package/dist/scripts/hbcli-e2e-tests.js +71 -90
  121. package/dist/scripts/hbcli-live-optin-tests.js +96 -0
  122. package/dist/scripts/hbcli-release-contract-tests.js +122 -0
  123. package/dist/scripts/hbcli-tests.js +41 -115
  124. package/dist/scripts/health-watch-cli.js +42 -28
  125. package/dist/scripts/hotel-date-gate-tests.js +496 -0
  126. package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
  127. package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
  128. package/dist/scripts/i18n-tests.js +16 -9
  129. package/dist/scripts/incident-tests.js +281 -87
  130. package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
  131. package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
  132. package/dist/scripts/issue-271-liveness-tests.js +547 -0
  133. package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
  134. package/dist/scripts/issue-289-model-retry-tests.js +441 -0
  135. package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
  136. package/dist/scripts/issue-338-home-city-e2e.js +577 -0
  137. package/dist/scripts/issue343-real-entry-e2e.js +160 -0
  138. package/dist/scripts/journey-tests.js +22 -27
  139. package/dist/scripts/kernel-manifest-evidence.js +109 -0
  140. package/dist/scripts/kernel-manifest-gate.js +126 -0
  141. package/dist/scripts/kernel-manifest-tests.js +212 -0
  142. package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
  143. package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
  144. package/dist/scripts/kernel-manifest.js +369 -0
  145. package/dist/scripts/ledger-repair-apply-tests.js +316 -0
  146. package/dist/scripts/ledger-repair-plan-tests.js +375 -0
  147. package/dist/scripts/ledger-tests.js +325 -340
  148. package/dist/scripts/ledger-workflow-crash.js +10 -20
  149. package/dist/scripts/map-tools-vendor-package-proof.js +206 -134
  150. package/dist/scripts/memory-capture-tests.js +242 -61
  151. package/dist/scripts/memory-decay-tests.js +18 -52
  152. package/dist/scripts/memory-lifecycle-tests.js +657 -0
  153. package/dist/scripts/memory-lifecycle.js +196 -0
  154. package/dist/scripts/memory-metrics.js +24 -12
  155. package/dist/scripts/memory-value-report.js +474 -222
  156. package/dist/scripts/memory-value-tests.js +328 -0
  157. package/dist/scripts/metrics-report-tests.js +62 -199
  158. package/dist/scripts/model-override-e2e.js +66 -105
  159. package/dist/scripts/nightly-evidence-tests.js +64 -89
  160. package/dist/scripts/nightly-evidence.js +108 -111
  161. package/dist/scripts/nudge-digest.js +39 -28
  162. package/dist/scripts/onboarding-tests.js +63 -88
  163. package/dist/scripts/opensky-check.js +18 -13
  164. package/dist/scripts/opensky-tests.js +28 -28
  165. package/dist/scripts/persona-surface-guard-tests.js +37 -12
  166. package/dist/scripts/pnpm-dsh-closure-proof.js +2 -5
  167. package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
  168. package/dist/scripts/price-drift-tests.js +126 -227
  169. package/dist/scripts/price-drift-watch.js +209 -253
  170. package/dist/scripts/probe-poi-tests.js +52 -45
  171. package/dist/scripts/product-metrics.js +187 -273
  172. package/dist/scripts/publish-preverify.js +47 -41
  173. package/dist/scripts/realtime-pricing-tests.js +37 -76
  174. package/dist/scripts/replay-async.js +20 -18
  175. package/dist/scripts/replay-real.js +16 -18
  176. package/dist/scripts/replay.js +52 -82
  177. package/dist/scripts/session-attach-diagnose.js +16 -12
  178. package/dist/scripts/session-attach-poc.js +34 -37
  179. package/dist/scripts/session-benchmark.js +66 -147
  180. package/dist/scripts/session-dida-live-e2e.js +151 -0
  181. package/dist/scripts/session-extract-tests.js +14 -35
  182. package/dist/scripts/session-login.js +14 -13
  183. package/dist/scripts/session-tests.js +545 -583
  184. package/dist/scripts/sf-live-benchmark.js +92 -110
  185. package/dist/scripts/sf-live-cli-tests.js +2 -9
  186. package/dist/scripts/sf-soft-score-tests.js +19 -60
  187. package/dist/scripts/sf-summary-tests.js +149 -0
  188. package/dist/scripts/sf-summary.js +466 -84
  189. package/dist/scripts/skeleton-check.js +16 -14
  190. package/dist/scripts/skeleton-integration-test.js +11 -10
  191. package/dist/scripts/skills-contract-tests.js +51 -46
  192. package/dist/scripts/smoke-session-gate-tests.js +12 -20
  193. package/dist/scripts/smoke.js +541 -422
  194. package/dist/scripts/sponsor-reuse-tests.js +262 -0
  195. package/dist/scripts/state-cli-tests.js +226 -101
  196. package/dist/scripts/state-cli.js +549 -212
  197. package/dist/scripts/static-golden-tests.js +46 -180
  198. package/dist/scripts/time-eval-tests.js +210 -192
  199. package/dist/scripts/travel-timeline-tests.js +29 -93
  200. package/dist/scripts/turn-handoff-collect-tests.js +46 -93
  201. package/dist/scripts/turn-handoff-collect.js +71 -99
  202. package/dist/scripts/turn-policy-tests.js +28 -29
  203. package/dist/scripts/typed-contract-canary.js +77 -162
  204. package/dist/scripts/tz-resolver-sanity.js +50 -0
  205. package/dist/scripts/tz-resolver-tests.js +584 -0
  206. package/dist/scripts/unified-tests.js +23 -19
  207. package/dist/scripts/visa-policy-tests.js +31 -44
  208. package/dist/scripts/weather-tests.js +121 -543
  209. package/dist/scripts/wish-channel-gate-tests.js +29 -86
  210. package/dist/scripts/write-gate-tests.js +522 -0
  211. package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
  212. package/dist/scripts/z3-lifecycle-tests.js +170 -0
  213. package/dist/scripts/z3-race-repeat-tests.js +39 -0
  214. package/dist/scripts/z3-race-tests.js +18 -12
  215. package/dist/src/artifact-gate.js +652 -221
  216. package/dist/src/backend/kernel.js +91 -0
  217. package/dist/src/backend/modules/booking-copilot.js +55 -0
  218. package/dist/src/backend/modules/booking-executor.js +124 -0
  219. package/dist/src/backend/modules/session-search.js +194 -0
  220. package/dist/src/benchmark-agent-conformance.js +296 -262
  221. package/dist/src/benchmark-environment-bridge.js +298 -413
  222. package/dist/src/benchmark-headless-child-diagnostics.js +93 -100
  223. package/dist/src/benchmark-tool-isolation.js +94 -67
  224. package/dist/src/bookable-facts.js +299 -174
  225. package/dist/src/booking-saga.js +64 -120
  226. package/dist/src/booking-surface/availability-policy.js +443 -576
  227. package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
  228. package/dist/src/booking-surface/contracts.js +24 -80
  229. package/dist/src/booking-surface/dsh-planner.js +510 -281
  230. package/dist/src/booking-surface/dsh-plugin.js +17 -1
  231. package/dist/src/booking-surface/error-codes.js +82 -10
  232. package/dist/src/booking-surface/index.js +0 -3
  233. package/dist/src/booking-surface/profile.js +10 -54
  234. package/dist/src/booking-surface/recovery-chain.js +367 -0
  235. package/dist/src/booking-surface/runtime.js +765 -891
  236. package/dist/src/booking-surface/server.js +200 -251
  237. package/dist/src/booking-surface/startup.js +58 -54
  238. package/dist/src/booking-surface/validation.js +150 -218
  239. package/dist/src/bridge.js +20 -13
  240. package/dist/src/companions.js +48 -74
  241. package/dist/src/contracts.js +21 -43
  242. package/dist/src/dsh-llm.js +82 -120
  243. package/dist/src/engine.js +253 -239
  244. package/dist/src/evaluation-cadence.js +72 -209
  245. package/dist/src/evaluation-contracts.js +220 -843
  246. package/dist/src/flight-pack-adapter.js +54 -0
  247. package/dist/src/flight-pack-contract.js +2 -0
  248. package/dist/src/gotry-backend.js +70 -0
  249. package/dist/src/hotel-date-gate.js +118 -0
  250. package/dist/src/i18n.js +18 -7
  251. package/dist/src/index.js +1425 -1629
  252. package/dist/src/journey.js +132 -81
  253. package/dist/src/ledger-repair-apply.js +538 -0
  254. package/dist/src/ledger-repair-plan.js +463 -0
  255. package/dist/src/loop.js +257 -166
  256. package/dist/src/memory-capture.js +180 -32
  257. package/dist/src/memory-decay.js +30 -14
  258. package/dist/src/memory-lifecycle.js +1310 -0
  259. package/dist/src/memory-utility.js +27 -40
  260. package/dist/src/mock-llm.js +36 -61
  261. package/dist/src/model.js +81 -36
  262. package/dist/src/realtime-pricing.js +63 -72
  263. package/dist/src/slot-spec.js +84 -106
  264. package/dist/src/state-ledger.js +310 -471
  265. package/dist/src/subagent-job-id-guard.js +58 -0
  266. package/dist/src/time-anchor.js +231 -33
  267. package/dist/src/tool-packet.js +20 -8
  268. package/dist/src/travel-slots.js +58 -35
  269. package/dist/src/travel-timeline.js +44 -63
  270. package/dist/src/turn-deadline.js +121 -127
  271. package/dist/src/turn-policy.js +61 -89
  272. package/dist/src/tz-resolver.js +143 -0
  273. package/dist/src/unified.js +504 -381
  274. package/dist/src/wish-pool.js +39 -14
  275. package/dist/src/write-gate.js +495 -0
  276. package/dist/src/z3-shared.js +273 -7
  277. package/extension/README.md +4 -3
  278. package/extension/background.js +125 -14
  279. package/extension/content-bridge.js +23 -1
  280. package/extension/content-main.js +15 -4
  281. package/extension/manifest.json +16 -8
  282. package/package.json +251 -220
  283. package/ts/capabilities/agent-reach.ts +4 -4
  284. package/ts/capabilities/anything.ts +1 -1
  285. package/ts/capabilities/artifacts.ts +46 -9
  286. package/ts/capabilities/flyai.ts +156 -37
  287. package/ts/capabilities/hbcli.ts +1 -1
  288. package/ts/capabilities/incident-log.ts +88 -59
  289. package/ts/capabilities/session/adapters/ctrip-flight.ts +99 -36
  290. package/ts/capabilities/session/adapters/dida-portal.ts +250 -0
  291. package/ts/capabilities/session/adapters/rail-12306.ts +123 -24
  292. package/ts/capabilities/session/extension-bridge.ts +226 -101
  293. package/ts/capabilities/session/extension-channel.ts +22 -9
  294. package/ts/capabilities/session/wizard.ts +2 -2
  295. package/ts/capabilities/session-consent.ts +98 -14
  296. package/ts/capabilities/session-login.ts +1 -0
  297. package/ts/capabilities/session-search.ts +315 -31
  298. package/ts/dsh-runtime/vendor/README.md +8 -4
  299. package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +7 -1
  300. package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +5 -3
  301. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +1 -1
  302. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +1 -1
  303. package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +6 -6
  304. package/ts/package.json +236 -16
  305. package/ts/scripts/map-tools-vendor-package-proof.ts +152 -31
  306. package/ts/scripts/state-cli.ts +418 -51
  307. package/ts/src/artifact-gate.ts +561 -15
  308. package/ts/src/benchmark-environment-bridge.ts +37 -20
  309. package/ts/src/bookable-facts.ts +183 -7
  310. package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
  311. package/ts/src/booking-surface/dsh-planner.ts +240 -32
  312. package/ts/src/booking-surface/dsh-plugin.js +17 -1
  313. package/ts/src/booking-surface/error-codes.ts +75 -0
  314. package/ts/src/booking-surface/recovery-chain.ts +409 -0
  315. package/ts/src/booking-surface/server.ts +84 -51
  316. package/ts/src/booking-surface/validation.ts +2 -0
  317. package/ts/src/contracts.ts +12 -2
  318. package/ts/src/dsh-llm.ts +4 -8
  319. package/ts/src/index.ts +609 -90
  320. package/ts/src/loop.ts +116 -7
  321. package/ts/src/memory-capture.ts +227 -3
  322. package/ts/src/mock-llm.ts +4 -8
  323. package/ts/src/model.ts +88 -2
  324. package/ts/src/state-ledger.ts +47 -29
  325. package/ts/src/subagent-job-id-guard.ts +72 -0
  326. package/ts/src/time-anchor.ts +217 -13
  327. package/ts/src/unified.ts +316 -54
@@ -0,0 +1,174 @@
1
+ /*
2
+ * GoTry's public DSH Web client half.
3
+ *
4
+ * This is a lazy-CJS browser bundle. The host serves it through the exact
5
+ * `./client` export and DSH materializes it with the platform React module.
6
+ * The Client receives the frozen `block` from the runtime; Host
7
+ * presentationMeta/presentResult values are not available here.
8
+ */
9
+ window.__ModuleLoader__.load({
10
+ id: '@danceiny/gotry',
11
+ factory: (require) => {
12
+ var module = { exports: {} }
13
+ var exports = module.exports
14
+ var React = require('react')
15
+
16
+ function element(type, props, children) {
17
+ return React.createElement(type, props, ...(Array.isArray(children) ? children : [children]))
18
+ }
19
+
20
+ function object(value) {
21
+ return value !== null && typeof value === 'object' && !Array.isArray(value) ? value : null
22
+ }
23
+
24
+ function isSettled(block) {
25
+ return object(block)?.kind === 'tool-result'
26
+ }
27
+
28
+ function resultText(block) {
29
+ var content = Array.isArray(block?.content) ? block.content : []
30
+ var text = content.map(function (item) {
31
+ return item && item.type === 'text' && typeof item.text === 'string' ? item.text : JSON.stringify(item)
32
+ }).filter(Boolean).join('\n')
33
+ var error = object(block?.error)
34
+ if (!text && error) text = String(error.name || 'Tool error') + ': ' + String(error.code || 'unknown')
35
+ return text
36
+ }
37
+
38
+ function stateOf(block) {
39
+ if (!isSettled(block)) return 'running'
40
+ return block.isError ? 'error' : 'ok'
41
+ }
42
+
43
+ function metaOf(block) {
44
+ return object(block?.meta)
45
+ }
46
+
47
+ function shellProps(type, state) {
48
+ return {
49
+ 'data-gotry-artifact-card': type,
50
+ 'data-gotry-artifact-state': state,
51
+ role: 'region',
52
+ 'aria-label': type === 'list' ? 'GoTry artifacts' : 'GoTry artifact preview',
53
+ style: {
54
+ border: '1px solid var(--dsw-alias-border-l1, rgba(127,127,127,.35))',
55
+ borderRadius: '12px',
56
+ margin: '6px 0',
57
+ overflow: 'hidden',
58
+ background: 'var(--dsw-alias-bg-layer-3, rgba(127,127,127,.05))',
59
+ },
60
+ }
61
+ }
62
+
63
+ function statusLine(state, type) {
64
+ if (state === 'running') return type === 'list' ? '正在查找产物…' : '正在读取产物…'
65
+ if (state === 'error') return type === 'list' ? '产物列表读取失败' : '产物预览失败'
66
+ return type === 'list' ? '可打开的 GoTry 产物' : '产物预览'
67
+ }
68
+
69
+ function ArtifactListCard(props) {
70
+ var block = props.block
71
+ var state = stateOf(block)
72
+ var meta = metaOf(block)
73
+ var selectedState = React.useState(null)
74
+ var selected = selectedState[0]
75
+ var setSelected = selectedState[1]
76
+ var valid = state === 'ok' && meta && meta.shape === 'paths' && Array.isArray(meta.paths) &&
77
+ meta.paths.every(function (path) { return typeof path === 'string' && path.length > 0 }) &&
78
+ typeof meta.total === 'number' && Number.isInteger(meta.total) && meta.total >= 0 &&
79
+ typeof meta.truncated === 'boolean'
80
+ var text = resultText(block)
81
+ var children = [element('div', { style: { padding: '10px 14px 4px', fontWeight: 600 } }, statusLine(state, 'list'))]
82
+ if (state === 'running') {
83
+ children.push(element('p', { 'data-gotry-artifact-status': 'running', style: { padding: '0 14px 12px', margin: 0 } }, '等待运行时返回路径…'))
84
+ } else if (state === 'error') {
85
+ children.push(element('p', { 'data-gotry-artifact-status': 'error', style: { padding: '0 14px 12px', margin: 0, color: 'var(--dsw-alias-state-error-primary, #c44)' } }, text || '未知错误'))
86
+ } else if (!valid) {
87
+ children.push(element('p', { 'data-gotry-artifact-status': 'malformed', style: { padding: '0 14px 12px', margin: 0, color: 'var(--dsw-alias-state-error-primary, #c44)' } }, '产物列表数据格式异常,已降级显示原始结果。'))
88
+ if (text) children.push(element('pre', { style: { whiteSpace: 'pre-wrap', padding: '0 14px 12px', margin: 0 } }, text))
89
+ } else {
90
+ var list = meta.paths.map(function (path) {
91
+ var isSelected = selected === path
92
+ return element('li', { key: path, style: { margin: '4px 0' } }, element('button', {
93
+ type: 'button',
94
+ 'data-gotry-artifact-path': path,
95
+ 'aria-label': 'Open artifact ' + path,
96
+ 'aria-pressed': isSelected,
97
+ onClick: function () {
98
+ setSelected(path)
99
+ if (typeof props.openFile === 'function') props.openFile(path)
100
+ },
101
+ style: {
102
+ color: 'var(--dsw-alias-accent, #4f8cff)',
103
+ background: 'none',
104
+ border: 0,
105
+ padding: 0,
106
+ cursor: 'pointer',
107
+ textAlign: 'left',
108
+ textDecoration: isSelected ? 'underline' : 'none',
109
+ },
110
+ }, path))
111
+ })
112
+ children.push(element('div', { style: { padding: '0 14px 10px', color: 'var(--dsw-alias-label-secondary, #888)' } },
113
+ '共 ' + String(meta.total) + ' 项' + (meta.truncated ? '(已截断)' : '')))
114
+ children.push(element('ul', { 'data-gotry-artifact-paths': 'true', style: { margin: '0', padding: '0 14px 12px 34px' } }, list))
115
+ if (selected) children.push(element('div', { 'data-gotry-artifact-selection': selected, style: { padding: '0 14px 12px', fontSize: '12px' } }, '已选择:' + selected))
116
+ }
117
+ return element('section', shellProps('list', state), children)
118
+ }
119
+
120
+ function ArtifactReadCard(props) {
121
+ var block = props.block
122
+ var state = stateOf(block)
123
+ var meta = metaOf(block)
124
+ var validLines = Array.isArray(meta?.lines) && meta.lines.every(function (line) {
125
+ return object(line) && Number.isInteger(line.number) && typeof line.text === 'string'
126
+ })
127
+ var valid = state === 'ok' && typeof meta?.path === 'string' && meta.path !== '' &&
128
+ Number.isInteger(meta?.offset) && meta.offset >= 1 && Number.isInteger(meta?.totalLines) &&
129
+ meta.totalLines >= 0 && validLines
130
+ var text = resultText(block)
131
+ var children = [element('div', { style: { padding: '10px 14px 4px', fontWeight: 600 } }, statusLine(state, 'read'))]
132
+ if (state === 'running') {
133
+ children.push(element('p', { 'data-gotry-artifact-status': 'running', style: { padding: '0 14px 12px', margin: 0 } }, '等待运行时返回文件内容…'))
134
+ } else if (state === 'error') {
135
+ children.push(element('p', { 'data-gotry-artifact-status': 'error', style: { padding: '0 14px 12px', margin: 0, color: 'var(--dsw-alias-state-error-primary, #c44)' } }, text || '未知错误'))
136
+ } else if (!valid) {
137
+ children.push(element('p', { 'data-gotry-artifact-status': 'malformed', style: { padding: '0 14px 12px', margin: 0, color: 'var(--dsw-alias-state-error-primary, #c44)' } }, '产物预览数据格式异常,已降级显示原始结果。'))
138
+ if (text) children.push(element('pre', { style: { whiteSpace: 'pre-wrap', padding: '0 14px 12px', margin: 0 } }, text))
139
+ } else {
140
+ var version = typeof meta.version === 'string' && meta.version ? meta.version : 'content-refresh'
141
+ children.push(element('div', { 'data-gotry-artifact-identity': 'true', style: { padding: '0 14px 8px', fontSize: '12px', color: 'var(--dsw-alias-label-secondary, #888)' } },
142
+ '来源:' + String(meta.source || 'unknown') + ' · ' + meta.path + ' · ' + String(meta.totalLines) + ' 行 · 版本:' + version))
143
+ children.push(element('div', { 'data-gotry-artifact-version': version, style: { padding: '0 14px 12px', fontFamily: 'var(--ds-font-family-code, monospace)', fontSize: '13px', lineHeight: '21px', overflowX: 'auto' } },
144
+ meta.lines.map(function (line) {
145
+ return element('div', { key: String(line.number), 'data-gotry-artifact-line': String(line.number), style: { display: 'grid', gridTemplateColumns: '4em 1fr', whiteSpace: 'pre' } }, [
146
+ element('span', { key: 'number', 'aria-hidden': 'true', style: { color: 'var(--dsw-alias-label-caption, #999)', userSelect: 'none', textAlign: 'right', paddingRight: '12px' } }, String(line.number)),
147
+ element('span', { key: 'text' }, line.text || ' '),
148
+ ])
149
+ })))
150
+ }
151
+ return element('section', shellProps('read', state), children)
152
+ }
153
+
154
+ function ArtifactToolView(props) {
155
+ if (props.toolName === 'gotry_artifacts_list') return ArtifactListCard(props)
156
+ return ArtifactReadCard(props)
157
+ }
158
+
159
+ function apply(ctx) {
160
+ ctx.inject(['slots'], function (scope) {
161
+ scope.slots.inject('tool.call.toolview', function () {
162
+ return scope.slots.register({ name: 'tool.call.toolview', key: 'gotry_artifacts_list' }, ArtifactToolView)
163
+ })
164
+ scope.slots.inject('tool.call.toolview', function () {
165
+ return scope.slots.register({ name: 'tool.call.toolview', key: 'gotry_artifacts_read' }, ArtifactToolView)
166
+ })
167
+ })
168
+ }
169
+
170
+ exports.apply = apply
171
+ exports.inject = []
172
+ return module.exports
173
+ },
174
+ })
@@ -1,7 +1,7 @@
1
1
  # GoTry × dsh 成品组合(DeepSeek 原生——创始人官方 key)
2
2
  # 用法(在仓库根或 gotry 安装目录):
3
3
  # DEEPSEEK_API_KEY=<key> dsh web --patch ./cordis.gotry-patch.yml
4
- # (从 npm 安装: npx gotry web 自动应用本 patch)
4
+ # (从 npm 安装: npx @danceiny/gotry web 自动应用本 patch)
5
5
  - insert:
6
6
  - id: gotry-tools
7
7
  name: 'placeholder/ts/src/index.ts' # 占位:bin/gotry-inner.js 运行时
@@ -23,10 +23,17 @@
23
23
  # 不挡启动。地图/路线/POI 工具,零 key 走 OSM/OSRM。
24
24
 
25
25
  # GoTry 成品人格:行为契约=产品语义
26
+ # 注:target dsh-system-prompt Config 公开读取 personaPrefix / personaSuffix;
27
+ # legacy persona 键不投影,需改用目标键。
28
+ # 2026-09-11 瘦身(M4 人格校准线,founder 指令):23→13 条,窄域细则去重归位——
29
+ # 渠道 setup→gotry_agent_reach 描述、会话授权/登录→gotry_session_search/login 描述、
30
+ # 可下单事实细则→gotry_fact_gate 描述(均原文已在,persona 纯重复);persona 只留
31
+ # 跨场景行为契约。回归锚见 ts/scripts/persona-surface-guard-tests.ts。
26
32
  - id: system-prompt
27
33
  config:
28
- persona: >-
34
+ personaPrefix: >-
29
35
  你是 GoTry——从出发到下一次出发的 AI 旅行伙伴(中国出境首发,workation 场景)。
36
+ 下面每条契约都来自真实会话的失败或同题横评证据,没有一条是装饰。
30
37
  今天是 {{current_date}}。时间锚点卡(相对日期换算的唯一依据,一律查卡不自算):
31
38
  {{time_anchor_card}}
32
39
  用户记忆 brief(空 = 首访,按 (1) 访谈;非空 = 回访——已答字段不重复问,
@@ -34,95 +41,65 @@
34
41
  {{motivation_brief}}
35
42
  行为契约:
36
43
  (1)动机先行:首轮必问工作窗口(几点到几点/什么时区)与已订资源(航班/酒店);
37
- 行程涉及同行人(见面/汇合/结伴)时,同行人是第二条到达链,同样必问——从哪出发/是否
38
- 已订/有无自己的时间窗;问明即落同行人档案(gotry_companion_save),到达账与预算按各自
39
- 的链分开算;
40
- (2)日历一次断言:日期换算以锚点卡为准并记住,冲突让用户裁决,永不重算;
41
- (3)翻译不造数:班次/价格只来自工具(gotry_feasibility_check/gotry_skeleton_check/gotry_hotel_search);
42
- (4)判定归引擎:可行性/全成本由工具计算,你只解释;
43
- (5)待决=选择题:优先用 ask_user_question 工具发结构化选项(2-3 个带 trade-off,
44
- web 界面渲染成卡片;该工具不可用或无响应时退化为文本选择题);
45
- (6)憧憬不被拒绝:不可行进 gotry_wish_pool_add(带条件);
46
- 用户表达新的出行意图时,若时间/预算窗口可能命中已存憧憬,先调
47
- gotry_wish_pool_list 查询再答——命中就用清单里的选项开场(它是用户自己许过的愿);
48
- 「下一次出发」建议一轮至多 surface 1 条(0..1 纪律),条件不命中就不硬推;
49
- 成效归因只能按用户明说的记(wish confirm-outcome),不许自评「有用」;
50
- (7)证据链:引用工具返回的标注([骨架:openflights]/[实时API:hbcli]/[静态包:估算])。
51
- (8)时间感知:以锚点卡的今天为锚点——已过的月份不说「将」,当下所在的季节
52
- 直接点明(如「现在正是雨季」而非把当前月份当成远期选项);用户给的绝对日期
53
- 早于今天时,主动点明已过并请用户裁决(笔误还是指明年),不静默顺延;
54
- 周/月/节日表述一律按锚点卡换算,不自算;用户说「在 X 年内完成」时,
55
- 只推荐今天之后的时段,今天之前的一律排除;
56
- 澄清卡/访谈/选项里向用户列出的候选时段示例(节日/周末/月份)同样只取
57
- 今天之后的——已过的节日不进示例枚举,不拿过去节日当「想用的时候」的候选。
58
- (9)年界断言:「元旦/新年/春节」先断年再谈——今天是 {{current_date}},
59
- 「2026 年内」不含 2027-01-01 元旦;农历节日先换算公历日期再判断归属年份。
60
- (10)不重复问:预算/日期/窗口/出发地等已问过或用户已给的信息,会话内
61
- 永不重复询问;缺信息先查已有上下文,再决定是否发问。
62
- (11)零示例泄漏:工具参数里的示例值只是格式占位,不是推荐目的地;
63
- 用户没提过的地点永不主动引入。
64
- (12)术语不猜:不认识的术语/缩写(如 IRW)直接问用户含义或用工具查,
65
- 绝不假装理解、绝不编造解释。
66
- (13)外部事实先查工具:价格/班次/政策/新闻等实时或外部事实,
67
- 一律先调工具,不凭记忆作答。
68
- (14)数据源路由:通用外部事实/内容平台(网页/社媒/行情/视频/播客)优先
69
- gotry_agent_reach(上游全渠道,不许自行降级跳过);酒店与目的地库存才走
70
- gotry_hotel_search / gotry_anything_search;天气/航班用专用工具。
71
- (15)渠道 setup 协助:agent-reach 渠道返回 needs-setup 不是终点——把上游
72
- 配置命令原样给用户(如 agent-reach configure --from-browser chrome
73
- --platform <渠道>),说明配好后你会复检,并主动提出下一步;绝不就此放弃该渠道。
74
- (16)域边界(宿主 skill 共存):旅行规划/目的地/行程/预算规划永远是 gotry 的
75
- 工具链,绝不因关键词(差旅/年假/IRW)路由进宿主其他 skill(如 cis-cli);
76
- 只有用户明确要查公司系统(假期余额/出差订单/报销审批)时才调对应 skill;
77
- 交界场景(用年假去旅行)分两步——余额查询归公司 skill,去哪/怎么去归 gotry。
44
+ 行程涉及同行人(见面/汇合/结伴)时,同行人是第二条到达链,同样必问——从哪出发/
45
+ 是否已订/有无自己的时间窗;问明即落同行人档案(gotry_companion_save),到达账
46
+ 与预算按各自的链分开算。
47
+ (2)不重复问:已问过或用户已给的信息,会话内永不重复询问;缺信息先查画像
48
+ 与上下文,再决定是否发问。
49
+ (3)翻译不造数,判定归引擎:班次/价格/时刻/政策等可下单事实只来自本轮
50
+ exact-date 工具结果,可行性/全成本由工具计算,你只解释与组织;exact-date
51
+ 返回 miss 就是「未确认,到 D-xx 复核」,不得用航线页当日班期、历史航季、
52
+ 相邻日期或记忆填充;交付含可下单事实的产物前必调 gotry_fact_gate,blocked
53
+ 就逐条改到可回溯,不得宣称「已验证方案」。
54
+ (4)时间是断言不是计算:日期换算一律查锚点卡并一次断言,冲突让用户裁决,
55
+ 永不重算;绝对日期早于今天时主动点明请裁决(笔误还是指明年),不静默顺延;
56
+ 「元旦/春节」先断年再谈,农历节日先换算公历再判归属年;推荐与澄清卡/
57
+ 访谈/选项里的候选时段示例(节日/周末/月份)一律只取今天之后的——
58
+ 已过的节日不进示例枚举。
59
+ (5)待决=选择题:优先用 ask_user_question 工具发结构化选项(2-3 个带
60
+ trade-off,web 界面渲染成卡片;该工具不可用或无响应时退化为文本选择题);
61
+ 校准类疑问永不阻塞推进。
62
+ (6)开放性选择不外问:班次/房型/落脚点等开放性选择,基于已知动机与约束给
63
+ 最有说服力的方案并说明理由,用户否决才改;对话中用户透露的新事实(动机/
64
+ 约束/偏好/已订资源/实际经历)当轮并入动机画像(gotry_motivation_save,
65
+ evidence=用户原话),不等确认。
66
+ (7)憧憬不被拒绝:进不了本次行程的愿望入池(gotry_wish_pool_add,带条件);
67
+ 用户表达新意图时先查 gotry_wish_pool_list——命中就用清单里的选项开场
68
+ (那是用户自己许过的愿);「下一次出发」建议一轮至多 surface 1 条,条件
69
+ 不命中就不硬推;成效归因只按用户明说的记(wish confirm-outcome),
70
+ 不自评「有用」。
71
+ (8)证据随结论必达:引用工具返回的标注([骨架:openflights]/[实时API:hbcli]/
72
+ [会话:ctrip-flight@ts]/[静态包:估算]);季节性/天气论断先查
73
+ gotry_weather_check 的 climate 模式,没查过就不写天气相关理由。
74
+ (9)检索路由查卡:通用外部事实/内容平台走 gotry_agent_reach(不许自行降级
75
+ 跳过);酒店与目的地库存走 gotry_hotel_search / gotry_anything_search;
76
+ 天气/航班走专用工具;机/火/酒通道顺位看 {{channel_routing_card}}——不背
77
+ 优先级,verdict≠hit 按结果内 routing 字段改道下一通道,同一通道本会话
78
+ 不盲试第二次;跨源结论分桶比对(直达/中转),不比裸最低价;账号会话面
79
+ (gotry_session_search)首次调用经运行时审批卡授权,用户拒绝即本会话吊销,
80
+ 无审批通道(headless)不执行;登录只在官网进行、gotry 永不碰凭证——
81
+ 操作细则见工具说明。
82
+ (10)域边界(宿主 skill 共存):旅行规划/目的地/行程/预算永远是 gotry 的
83
+ 工具链,不因关键词(差旅/年假/IRW)路由进宿主其他 skill;只有用户明确要查
84
+ 公司系统(假期余额/出差订单/报销审批)才调对应 skill;交界场景(用年假去
85
+ 旅行)分两步——余额查询归公司 skill,去哪/怎么去归 gotry。
78
86
  表层规则:gotry 的全部能力一律是【工具调用】(gotry_ 前缀,直接作为 tool
79
- 发起),不是宿主 skill——绝不把 gotry_* 名字传给 skill 加载器(skill 面只装
80
- 宿主技能;skill 调用返回 invalid/unknown 即说明用错了面,改回 tool call,
81
- 不得换名重试 skill)
82
- (17)判定前背景调查:给可行性结论前,先对每个候选目的地取气候背景
83
- (gotry_weather_check 的 climate 模式);季节性/天气论断必须带
84
- [实时API:open-meteo@ts] 证据,没查过就不写天气相关理由。
85
- (18)动态吸收与开放性选题:对话中用户透露的新事实(动机/约束/偏好/
86
- 已订资源/实际经历)当轮即并入动机画像(gotry_motivation_save,
87
- evidence=用户原话),不等确认;班次/房型/落脚点等开放性选择不外问
88
- 用户——基于已知动机与约束给出最有说服力的方案并说明理由,用户否决
89
- 才改。校准类疑问永不阻塞推进。
90
- (19)OTA 检索(工具平铺,路由查卡):机/火/酒检索通道与当前顺位看
91
- {{channel_routing_card}}——不背优先级;某次检索 verdict≠hit 时,按该结果内
92
- routing 字段改道下一通道,同一通道本会话不盲试第二次。
93
- 账号会话面 gotry_session_search(用户本人
94
- 登录态,现携程机票/酒店 + 12306 火车(公开查询面),kind=flight|hotel|train):**首次调用**经运行时审批卡向用户请求授权,本会话
95
- 内记住、不再重复弹卡;用户拒绝即本会话吊销——不再请求也不再执行,改走
96
- 其他工具推进;无审批通道(headless)不执行。返回 needs-login→调
97
- gotry_session_login 产品工具(先自动检测票据——已登录则直接确认零弹窗;未登录才
98
- 打开登录入口等待其完成,不需要任何终端命令;**登录永远发生在携程官网、不在 gotry
99
- 里进行**——gotry 永不收集/存储/传输密码、验证码或任何 cookie 值,只检查
100
- "是否已登录"这一个事实;向用户说明这一点),完成前用官方源推进,不反复
101
- 开页探测;返回 challenged→立即停手如实告知,绝不重试
102
- 绝不绕过。跨源结论各带来源标注([实时API:flyai@ts]/[会话:ctrip-flight@ts]/
103
- [静态包:估算]),分桶比对直达/中转,不比裸最低价;证据链随结论必达用户。
104
- (20)事实闸(可下单事实 fail-closed,issue #46):航班号/时刻/机场/价格/签证政策
105
- 只能来自本轮 exact-date 工具结果;exact-date 返回 miss = 「未确认/当前不可售,
106
- 到 D-xx 复核」,**不得**用航线页当日班期、历史航季、相邻日期或记忆填充;
107
- 「只验证航线存在」永不升级为「该日期有该航班」;「联程」仅用于同票保护
108
- (protected_connection),分票/自助转机必须显式标红(无行李直挂/误机无保护);
109
- 政策只能表述为「截至 YYYY-MM-DD 的现行政策」并附复核日期,不用无条件 ✓;
110
- 双机场城市的航司落点不互换(FD 落 DMK、VZ 落 BKK)。
111
- **交付任何含可下单事实的行程产物(markdown 文件或长方案)前,必须调
112
- gotry_fact_gate**;闸 blocked 时逐条修正为可回溯事实或降级措辞,
113
- 不得宣称「已验证方案」。
114
- (21)工具循环收敛(wall-clock,ADR-24 v2):工具按需取用,没有「次数预算」,
115
- 也**永远不要**向用户宣称「工具预算已耗尽」——每轮唯一的边界是运行时时间闸,
116
- 只认三种信号:收到 TURN_DEADLINE_SOFT = 时间过半,立即停止发起新工具,开始
117
- 整理已有结果;收到 TURN_DEADLINE_EXHAUSTED = 本轮时间到,只能基于已有结果
118
- 输出最终答复,不得重试或改调其他工具,更不得用记忆/常识填充工具没查到的
119
- 实时事实(如实说明哪部分未能核实);收到 TURN_DEADLINE_HANDOFF = 深规划
120
- 转入后台,按提示告知用户预计时间与回访方式(附工单号),本轮给简短确认。
121
- (22)到达账必达:红眼/凌晨起飞、或落地当天有硬安排(上班/办事)的航段,解释方案时必须
122
- 显式给出到达账——当地到达时刻(含日期偏移)、时差、到达精力与落地后可用时长,并主动给
123
- 前一晚落脚建议;时刻表正确不等于行程可行。
124
- (23)子任务等待纪律:派发后台子任务(subagent)后,它的回执 id 是子代理会话 id,
125
- 不是 job_output/job_kill 的后台 job id——对子代理绝不调用 job_output/job_kill
126
- 轮询或停止(会撞 unknown job 硬错误);子任务完成通知会自动送达当前会话,耐心做
127
- 别的独立步骤;要给子代理追加输入用 send_message。job_output/job_kill 只用于
128
- 回执明写「background job」的后台任务。
87
+ 发起),不是宿主 skill——绝不把 gotry_* 名字传给 skill 加载器;skill 调用
88
+ 返回 invalid/unknown 即说明用错了面,改回 tool call,不得换名重试 skill。
89
+ (11)诚实:用户没提过的地点永不主动引入,工具参数示例值只是格式占位不是
90
+ 推荐目的地;不认识的术语/缩写(如 IRW)直接问用户含义或用工具查,绝不
91
+ 假装理解、绝不编造解释。
92
+ (12)到达账必达:红眼/凌晨起飞、或落地当天有硬安排(上班/办事)的航段,
93
+ 必须显式给出到达账——当地到达时刻(含日期偏移)、时差、到达精力与落地后
94
+ 可用时长,并主动给前一晚落脚建议;时刻表正确不等于行程可行。
95
+ (13)后台协作:子代理回执 id 不是后台 job id——
96
+ 对子代理绝不调用 job_output/job_kill(会撞 unknown job 硬错误),完成
97
+ 通知会自动送达当前会话,要给子代理追加输入用 send_message;
98
+ job_output/job_kill 只用于回执明写「background job」的后台任务。
99
+ 每轮只认三种时间信号:
100
+ TURN_DEADLINE_SOFT=时间过半,立即停止发起新工具,开始整理已有结果;
101
+ TURN_DEADLINE_EXHAUSTED=本轮时间到,只能基于已有结果输出最终答复,
102
+ 不重试、不改调其他工具、更不得用记忆填充没查到的实时事实;
103
+ TURN_DEADLINE_HANDOFF=深规划转入后台,告知用户预计时间与回访方式
104
+ (附工单号)。工具按需取用,没有「次数预算」,永远不要向用户宣称
105
+ 「工具预算已耗尽」。
@@ -1,172 +1,95 @@
1
+ /**
2
+ * agent-reach 深度能力层:yt-dlp 字幕提取 + gh 仓库搜索(可选工具,系统有就调,没有降级)。
3
+ *
4
+ * 与 agent-reach.ts(r.jina.ai 读网页)互补——dsh LLM 的 3 个 agent-reach 工具:
5
+ * - gotry_web_search → r.jina.ai(已落,零配置)
6
+ * - gotry_video_subtitle → yt-dlp(本文件;系统装了就调,没装降级提示安装方式)
7
+ * - gotry_github_search → gh(本文件;系统装了就调,没装降级提示安装方式)
8
+ *
9
+ * 契约(与 anything/weather/opensky/agent-reach 同构,L4 不变量):
10
+ * - 永不抛错:spawn 失败/超时/工具未装一律降级返回;
11
+ * - 证据链标注:[agent-reach:yt-dlp@ts] / [agent-reach:gh@ts] / [@error@ts] / [@not-installed@ts];
12
+ * - 零强制依赖:不 npm install 任何东西,用系统 PATH 里的二进制。
13
+ */
1
14
  import { spawn } from 'node:child_process';
2
15
  function run(bin, args, timeoutMs) {
3
- return new Promise((resolve)=>{
4
- const child = spawn(bin, args, {
5
- env: process.env
6
- });
16
+ return new Promise((resolve) => {
17
+ const child = spawn(bin, args, { env: process.env });
7
18
  let stdout = '';
8
19
  let stderr = '';
9
20
  let err;
10
21
  let timedOut = false;
11
- const timer = setTimeout(()=>{
22
+ const timer = setTimeout(() => {
12
23
  timedOut = true;
13
24
  try {
14
25
  child.kill('SIGKILL');
15
- } catch {}
26
+ }
27
+ catch { /* ignore */ }
16
28
  }, timeoutMs);
17
- child.stdout.on('data', (d)=>{
18
- stdout += d.toString();
19
- });
20
- child.stderr.on('data', (d)=>{
21
- stderr += d.toString();
22
- });
23
- child.on('error', (e)=>{
24
- err = e.message;
25
- });
26
- child.on('close', (code)=>{
29
+ child.stdout.on('data', (d) => { stdout += d.toString(); });
30
+ child.stderr.on('data', (d) => { stderr += d.toString(); });
31
+ child.on('error', (e) => { err = e.message; });
32
+ child.on('close', (code) => {
27
33
  clearTimeout(timer);
28
- resolve({
29
- code,
30
- stdout,
31
- stderr,
32
- err,
33
- timedOut
34
- });
34
+ resolve({ code, stdout, stderr, err, timedOut });
35
35
  });
36
36
  });
37
37
  }
38
- const ts = ()=>new Date().toISOString();
38
+ const ts = () => new Date().toISOString();
39
+ /** yt-dlp 提取视频字幕(YouTube/B站;系统需已装 yt-dlp) */
39
40
  export async function videoSubtitle(q) {
40
41
  const started = Date.now();
41
42
  const lang = q.lang ?? 'zh-Hans,zh,en';
42
- const args = [
43
- '--write-sub',
44
- '--write-auto-sub',
45
- '--sub-langs',
46
- lang,
47
- '--skip-download',
48
- '--sub-format',
49
- 'vtt',
50
- '-o',
51
- '/tmp/gotry-sub-%(id)s',
52
- q.url
53
- ];
43
+ const args = ['--write-sub', '--write-auto-sub', '--sub-langs', lang, '--skip-download', '--sub-format', 'vtt', '-o', '/tmp/gotry-sub-%(id)s', q.url];
54
44
  const r = await run('yt-dlp', args, q.timeoutMs ?? 60_000);
55
45
  const latencyMs = Date.now() - started;
46
+ // not-installed: ENOENT
56
47
  if (r.err?.includes('ENOENT')) {
57
- return {
58
- ok: false,
59
- verdict: 'not-installed',
60
- evidence: `[agent-reach:yt-dlp@not-installed@${ts()}]`,
61
- latencyMs,
62
- stderr: 'yt-dlp 未安装;装法: brew install yt-dlp 或 pip install yt-dlp'
63
- };
48
+ return { ok: false, verdict: 'not-installed', evidence: `[agent-reach:yt-dlp@not-installed@${ts()}]`, latencyMs, stderr: 'yt-dlp 未安装;装法: brew install yt-dlp 或 pip install yt-dlp' };
64
49
  }
65
50
  if (r.timedOut) {
66
- return {
67
- ok: false,
68
- verdict: 'timeout',
69
- evidence: `[agent-reach:yt-dlp@error@${ts()}] timeout`,
70
- latencyMs
71
- };
51
+ return { ok: false, verdict: 'timeout', evidence: `[agent-reach:yt-dlp@error@${ts()}] timeout`, latencyMs };
72
52
  }
73
53
  if (r.code !== 0) {
74
- return {
75
- ok: false,
76
- verdict: 'error',
77
- evidence: `[agent-reach:yt-dlp@error@${ts()}] exit ${r.code}`,
78
- latencyMs,
79
- stderr: r.stderr.slice(0, 400)
80
- };
54
+ return { ok: false, verdict: 'error', evidence: `[agent-reach:yt-dlp@error@${ts()}] exit ${r.code}`, latencyMs, stderr: r.stderr.slice(0, 400) };
81
55
  }
56
+ // 从 stdout 抓写入的字幕文件名
82
57
  const m = r.stdout.match(/Writing subtitles to:\s*(\S+)/);
83
58
  if (!m) {
84
- return {
85
- ok: false,
86
- verdict: 'error',
87
- evidence: `[agent-reach:yt-dlp@error@${ts()}] no subtitle file in output`,
88
- latencyMs,
89
- stderr: r.stdout.slice(0, 300)
90
- };
59
+ return { ok: false, verdict: 'error', evidence: `[agent-reach:yt-dlp@error@${ts()}] no subtitle file in output`, latencyMs, stderr: r.stdout.slice(0, 300) };
91
60
  }
92
61
  const { readFile } = await import('node:fs/promises');
93
62
  let subtitles;
94
63
  try {
95
64
  subtitles = (await readFile(m[1], 'utf-8')).slice(0, 8000);
96
- } catch {}
97
- return {
98
- ok: true,
99
- verdict: 'found',
100
- evidence: `[agent-reach:yt-dlp@${ts()}]`,
101
- latencyMs,
102
- stdout: r.stdout.slice(0, 400),
103
- subtitles
104
- };
65
+ }
66
+ catch { /* 字幕文件读失败保留 undefined */ }
67
+ return { ok: true, verdict: 'found', evidence: `[agent-reach:yt-dlp@${ts()}]`, latencyMs, stdout: r.stdout.slice(0, 400), subtitles };
105
68
  }
69
+ /** gh 搜索 GitHub 仓库(系统需已装 gh 并登录) */
106
70
  export async function githubSearch(q) {
107
71
  const started = Date.now();
108
72
  const limit = q.limit ?? 5;
109
- const args = [
110
- 'search',
111
- 'repos',
112
- q.query,
113
- '--json',
114
- 'fullName,description,stargazersCount,url',
115
- '--limit',
116
- String(limit)
117
- ];
73
+ const args = ['search', 'repos', q.query, '--json', 'fullName,description,stargazersCount,url', '--limit', String(limit)];
118
74
  const r = await run('gh', args, q.timeoutMs ?? 30_000);
119
75
  const latencyMs = Date.now() - started;
120
76
  if (r.err?.includes('ENOENT')) {
121
- return {
122
- ok: false,
123
- verdict: 'not-installed',
124
- evidence: `[agent-reach:gh@not-installed@${ts()}]`,
125
- latencyMs,
126
- stderr: 'gh 未安装;装法: brew install gh && gh auth login'
127
- };
77
+ return { ok: false, verdict: 'not-installed', evidence: `[agent-reach:gh@not-installed@${ts()}]`, latencyMs, stderr: 'gh 未安装;装法: brew install gh && gh auth login' };
128
78
  }
129
79
  if (r.timedOut) {
130
- return {
131
- ok: false,
132
- verdict: 'timeout',
133
- evidence: `[agent-reach:gh@error@${ts()}] timeout`,
134
- latencyMs
135
- };
80
+ return { ok: false, verdict: 'timeout', evidence: `[agent-reach:gh@error@${ts()}] timeout`, latencyMs };
136
81
  }
137
82
  if (r.code !== 0) {
138
- return {
139
- ok: false,
140
- verdict: 'error',
141
- evidence: `[agent-reach:gh@error@${ts()}] exit ${r.code}`,
142
- latencyMs,
143
- stderr: r.stderr.slice(0, 300)
144
- };
83
+ return { ok: false, verdict: 'error', evidence: `[agent-reach:gh@error@${ts()}] exit ${r.code}`, latencyMs, stderr: r.stderr.slice(0, 300) };
145
84
  }
146
85
  try {
147
86
  const repos = JSON.parse(r.stdout);
148
87
  return {
149
- ok: true,
150
- verdict: 'found',
151
- evidence: `[agent-reach:gh@${ts()}]`,
152
- latencyMs,
153
- repos: repos.map((x)=>({
154
- name: x.fullName,
155
- description: x.description,
156
- stars: x.stargazersCount,
157
- url: x.url
158
- }))
159
- };
160
- } catch {
161
- return {
162
- ok: false,
163
- verdict: 'error',
164
- evidence: `[agent-reach:gh@error@${ts()}] parse fail`,
165
- latencyMs,
166
- stderr: r.stdout.slice(0, 300)
88
+ ok: true, verdict: 'found', evidence: `[agent-reach:gh@${ts()}]`, latencyMs,
89
+ repos: repos.map(x => ({ name: x.fullName, description: x.description, stars: x.stargazersCount, url: x.url })),
167
90
  };
168
91
  }
92
+ catch {
93
+ return { ok: false, verdict: 'error', evidence: `[agent-reach:gh@error@${ts()}] parse fail`, latencyMs, stderr: r.stdout.slice(0, 300) };
94
+ }
169
95
  }
170
-
171
-
172
- //# sourceURL=ts/capabilities/agent-reach-deep.ts