@tea-agent/loop-agent 0.43.0-next.17 → 0.43.0-next.3

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 (187) hide show
  1. package/CHANGELOG.md +9 -140
  2. package/dist/application/task-lifecycle/advance.js +4 -17
  3. package/dist/application/task-lifecycle/observe.js +29 -43
  4. package/dist/application/task-lifecycle/plan-transitions.js +4 -5
  5. package/dist/build-stamp.json +3 -3
  6. package/dist/commands/client-recovery.js +55 -20
  7. package/dist/commands/new-task.js +5 -0
  8. package/dist/commands/status.js +57 -0
  9. package/dist/commands/task-contract.js +269 -0
  10. package/dist/executors/dag-pi-executor.js +230 -269
  11. package/dist/executors/pi-executor.js +0 -2
  12. package/dist/executors/pi-sdk-executor.js +39 -77
  13. package/dist/executors/shell-executor.js +2 -3
  14. package/dist/executors/shell-write-guard.js +32 -27
  15. package/dist/shared/pi-context-pressure/extension.js +16 -26
  16. package/dist/shared/pi-retry-settings.js +0 -40
  17. package/dist/shared/prompts.js +26 -0
  18. package/dist/task/config.js +2 -0
  19. package/dist/task/contract/validate-draft.js +106 -0
  20. package/dist/task/goal.js +3 -0
  21. package/dist/task/index.js +12 -0
  22. package/dist/task/lifecycle.js +1 -0
  23. package/dist/task/operator/capabilities.js +6 -0
  24. package/dist/task/operator/envelope.js +2 -0
  25. package/dist/task/operator/index.js +5 -0
  26. package/dist/task/operator/registry.js +2 -0
  27. package/dist/task/operator/types.js +1 -0
  28. package/dist/task/paths.js +1 -0
  29. package/dist/task/source-prepare/source-fidelity-pi.js +2 -2
  30. package/dist/task/source-references.js +23 -48
  31. package/dist/task/source-state.js +1 -0
  32. package/dist/task/subagent-guidance.js +1 -0
  33. package/dist/worker/console/chat/assistant-content.js +2 -23
  34. package/dist/worker/console/chat/explore-tools.js +0 -13
  35. package/dist/worker/console/chat/pi-runtime.js +1182 -221
  36. package/dist/worker/console/chat/routes.js +71 -213
  37. package/dist/worker/console/chat/sdd-data-alignment.js +9 -65
  38. package/dist/worker/console/chat/session-catalog.js +0 -32
  39. package/dist/worker/console/chat/session-store.js +6 -22
  40. package/dist/worker/console/chat/shortcuts.js +0 -6
  41. package/dist/worker/console/chat/sift-bridge.js +1 -0
  42. package/dist/worker/console/chat/tool-preview.js +0 -11
  43. package/dist/worker/console/chat/tools.js +0 -6
  44. package/dist/worker/console/console-update-and-init.js +19 -1
  45. package/dist/worker/console/console-update-runtime.js +20 -5
  46. package/dist/worker/console/index.js +20 -0
  47. package/dist/worker/console/operator-actions.js +1 -13
  48. package/dist/worker/console/routes.js +0 -8
  49. package/dist/worker/console/server.js +29 -11
  50. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C4NXyedy.js → abnfDiagram-N423BO3Z-hUmM_GRf.js} +1 -1
  51. package/dist/worker/console/static/assets/{arc-NZ3qXvBI.js → arc-Bt-xuieW.js} +1 -1
  52. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-COZSRvml.js → architectureDiagram-T3A2C74G-DTqkL4DJ.js} +1 -1
  53. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Ck0Gxi9C.js → blockDiagram-VBNYF7ZC-Cy0MNnzV.js} +1 -1
  54. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BX5HQ4Ox.js → c4Diagram-5PPSVZJV-DDdlT0Pd.js} +1 -1
  55. package/dist/worker/console/static/assets/channel-BpzRnZmU.js +1 -0
  56. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-CoviemSL.js → chunk-2GRJ4B5K-3JawwNZ6.js} +1 -1
  57. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DbOdOkbZ.js → chunk-2Q5K7J3B-DoTp7Cri.js} +1 -1
  58. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BsG2pmdQ.js → chunk-5RXB4S5H-CcirhZaS.js} +1 -1
  59. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DGdvrNm8.js → chunk-5VM5RSS4-VrG21gnP.js} +1 -1
  60. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-BAy7Yd6y.js → chunk-6Q2QTUOP-DDOgIS70.js} +1 -1
  61. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-D9UA7hUb.js → chunk-GF5L2VYU-CBjmgvJ_.js} +1 -1
  62. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-DPz7SZ8V.js → chunk-JWPE2WC7-CCQSht8M.js} +1 -1
  63. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BmuEOIh7.js → chunk-KBJHAD2P-BpGMkUUV.js} +1 -1
  64. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CIhBWnd8.js → chunk-RYQCIY6F-DNDT41QL.js} +1 -1
  65. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CScR6mDD.js → chunk-XXDRQBXY-euXnDFbn.js} +1 -1
  66. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BhlMVqCc.js +1 -0
  67. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BhlMVqCc.js +1 -0
  68. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BjpfWaUr.js → cose-bilkent-JH36ORCC-BJ6NAeql.js} +1 -1
  69. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BFQohJgT.js → cynefin-VYW2F7L2-F5JKIvIq.js} +1 -1
  70. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-D3gzRJnS.js → cynefinDiagram-MW4NZA55-Cwmkl_Gi.js} +1 -1
  71. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-5eojkhoA.js → dagre-VZM6K2ZE-BmCZ8815.js} +1 -1
  72. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CpD8LWu_.js → diagram-7IWD3JNH-zWA3hUnX.js} +1 -1
  73. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-B8_4qJ2a.js → diagram-B4RE2ZJO-BzA-888F.js} +1 -1
  74. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-HOsXf0eu.js → diagram-LBJQPF4R-tPNheoch.js} +1 -1
  75. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BqwRwiWP.js → diagram-Q27KOJAE-Cdi7Fyqp.js} +1 -1
  76. package/dist/worker/console/static/assets/{diagram-UB23O5K3-BRVCNZe1.js → diagram-UB23O5K3-DFK9VBf1.js} +1 -1
  77. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Cvb1TgGh.js → ebnfDiagram-BXEA7PRR-xCUr1kpg.js} +1 -1
  78. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DS0O0qG9.js → erDiagram-JOGREHBK-BANQHY_A.js} +1 -1
  79. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-BHIRvRr3.js → flowDiagram-UKHOOZJN-VHJYEMkP.js} +1 -1
  80. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DcCJ1JWx.js → ganttDiagram-PKOTCBZU-DiyZQ0C6.js} +1 -1
  81. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-B9ia5ony.js → gitGraphDiagram-DS77QQ5N-CZtIeBBa.js} +1 -1
  82. package/dist/worker/console/static/assets/index-BlN6ytLr.css +1 -0
  83. package/dist/worker/console/static/assets/index-CA-jfWlE.js +449 -0
  84. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-3ogpgegn.js → infoDiagram-6WML65LV-BuSspC0X.js} +1 -1
  85. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-4tgpQ5SL.js → ishikawaDiagram-WSZJBQD7-DRJZyPFy.js} +1 -1
  86. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DNfgHqFx.js → journeyDiagram-NVQOT4AX-DIfXIVuE.js} +1 -1
  87. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Dz7ngC8z.js → kanban-definition-27J2QSJJ-CT10_7Lt.js} +1 -1
  88. package/dist/worker/console/static/assets/{linear-DI7Jv62E.js → linear-ufemj74H.js} +1 -1
  89. package/dist/worker/console/static/assets/{mermaid.core-CQA4Nzmo.js → mermaid.core-DEQe8-_m.js} +5 -5
  90. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-CtsMc8Mf.js → mindmap-definition-FAOFIHXS-BRLUrbrC.js} +1 -1
  91. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-ByppE9yH.js → pegDiagram-VL7TDLO6-BgibKtiF.js} +1 -1
  92. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-B5PtgFgt.js → pieDiagram-7S7Q4E2Y-D3eyfdV9.js} +1 -1
  93. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-Cq4p0k2K.js → quadrantDiagram-CIZ2JOQS-DXeTk5Px.js} +1 -1
  94. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-DjfkyljN.js → railroadDiagram-AXF67PYL-BgXdFEe7.js} +1 -1
  95. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-DzynNRSl.js → requirementDiagram-LRYGKXZP-CseC2A7R.js} +1 -1
  96. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cj7TCpTJ.js → sankeyDiagram-W5VNT64P-D80PFzfJ.js} +1 -1
  97. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-C73C6ykA.js → sequenceDiagram-SI44F4Z6-BWzHW7LS.js} +1 -1
  98. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-BiNLgN2x.js → sizeCapture-X5ZJPWSS-xWQYTLAn.js} +1 -1
  99. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-UwvjS64-.js → stateDiagram-OKZ733FA-CLxtpZeL.js} +1 -1
  100. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-CiVoq4G-.js +1 -0
  101. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CC7DH98r.js → swimlanes-SLNWSIFB-DwugtmWV.js} +2 -2
  102. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BkdgdpfR.js +8 -0
  103. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-LSBXTR70.js → timeline-definition-Z64GVDOM-DHEOwHIe.js} +1 -1
  104. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-BAuxWwGP.js → vennDiagram-T6HMQDX7-pmbZKlBK.js} +1 -1
  105. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y--E5_gjZx.js → wardleyDiagram-T6FBY63Y-CivHoM5q.js} +1 -1
  106. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-dJWNmyzF.js → xychartDiagram-ELKLHX3M-BfHIE7o6.js} +1 -1
  107. package/dist/worker/console/static/index.html +2 -2
  108. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +10 -122
  109. package/dist/worker/console/static-src/operator-chat/compaction-message.js +0 -7
  110. package/dist/worker/console/static-src/operator-chat/pending-user-message.js +15 -35
  111. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +62 -136
  112. package/dist/worker/console/static-src/operator-chat/useChatStream.js +68 -159
  113. package/dist/worker/console/static-src/operator-chat/useChatThread.js +56 -75
  114. package/dist/worker/console/static-src/operator-chat/useComposer.js +78 -206
  115. package/dist/worker/console/workspace-context.js +1 -21
  116. package/dist/worker/observe/static/router.js +1 -1
  117. package/dist/worker/observe/static/styles.css +4 -7
  118. package/dist/worker/observe/static/views/dag-inspector.js +19 -12
  119. package/dist/worker/observe/static/views/dag.js +2 -2
  120. package/dist/worker/scheduler/index.js +25 -0
  121. package/dist/workflows/dag/facts.js +4 -0
  122. package/dist/workflows/dag/frontend-closeout.js +1 -1
  123. package/dist/workflows/dag/frontend-design-policy.js +1 -2
  124. package/dist/workflows/dag/frontend-implementation-contract.js +4 -8
  125. package/dist/workflows/dag/frontend-prewrite-gate.js +3 -3
  126. package/dist/workflows/dag/frontend-repair.js +76 -55
  127. package/dist/workflows/dag/frontend-review-context.js +1 -2
  128. package/dist/workflows/dag/frontend-review-scopes.js +12 -34
  129. package/dist/workflows/dag/frontend-shape-facts.js +2 -12
  130. package/dist/workflows/dag/frontend-verification-trace.js +42 -8
  131. package/dist/workflows/dag/index.js +6 -0
  132. package/dist/workflows/dag/init-hybrid.js +160 -97
  133. package/dist/workflows/dynamic/index.js +7 -0
  134. package/docs/architecture/runtime-boundaries.md +3 -3
  135. package/docs/templates/frontend-implementation-dag.json +8 -9
  136. package/package.json +3 -7
  137. package/skills/frontend-bounded-implement/SKILL.md +3 -4
  138. package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
  139. package/skills/frontend-contract/references/contract-protocol.md +1 -3
  140. package/skills/frontend-design-review/SKILL.md +7 -12
  141. package/skills/frontend-design-review/references/review-checklist.md +7 -7
  142. package/skills/frontend-plan/SKILL.md +0 -19
  143. package/skills/frontend-plan/references/decision-contract.md +19 -26
  144. package/skills/frontend-review/SKILL.md +18 -12
  145. package/skills/frontend-review/references/review-findings.md +43 -24
  146. package/dist/shared/pi-provider-recovery.js +0 -182
  147. package/dist/worker/console/chat/browser-automation.js +0 -363
  148. package/dist/worker/console/chat/browser-policy.js +0 -113
  149. package/dist/worker/console/chat/browser-routes.js +0 -162
  150. package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +0 -44
  151. package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +0 -89
  152. package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +0 -202
  153. package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +0 -79
  154. package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +0 -86
  155. package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +0 -38
  156. package/dist/worker/console/chat/pi-runtime/inspection-types.js +0 -28
  157. package/dist/worker/console/chat/pi-runtime/inspection.js +0 -439
  158. package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +0 -153
  159. package/dist/worker/console/chat/pi-runtime/sdk-session.js +0 -5
  160. package/dist/worker/console/chat/scm-routes.js +0 -217
  161. package/dist/worker/console/chat/scm-service.js +0 -283
  162. package/dist/worker/console/chat/scm-tools.js +0 -111
  163. package/dist/worker/console/chat/session-mode-view.js +0 -49
  164. package/dist/worker/console/chat/session-mode.js +0 -220
  165. package/dist/worker/console/chat/terminal-routes.js +0 -216
  166. package/dist/worker/console/chat/terminal-sessions.js +0 -348
  167. package/dist/worker/console/chat/terminal-tools.js +0 -211
  168. package/dist/worker/console/static/assets/channel-BxdTlb_5.js +0 -1
  169. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-_ByA1Nf8.js +0 -1
  170. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-_ByA1Nf8.js +0 -1
  171. package/dist/worker/console/static/assets/index-B9goN3S5.css +0 -1
  172. package/dist/worker/console/static/assets/index-wXlQohNs.js +0 -469
  173. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-nLgMZ0D3.js +0 -1
  174. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BcYqTady.js +0 -8
  175. package/dist/worker/console/static-src/operator-chat/active-turn-tail.js +0 -10
  176. package/dist/worker/console/static-src/operator-chat/chat-link.js +0 -94
  177. package/dist/worker/console/static-src/operator-chat/chat-scroll-position.js +0 -24
  178. package/dist/worker/console/static-src/operator-chat/composer-session-ledger.js +0 -192
  179. package/dist/worker/console/static-src/operator-chat/process-label.js +0 -41
  180. package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +0 -13
  181. package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +0 -10
  182. package/dist/worker/console/static-src/operator-chat/use-searchable-hidden.js +0 -51
  183. package/dist/worker/console/static-src/operator-chat/user-turn-anchor-equality.js +0 -21
  184. package/dist/worker/console/workspace-initialization.js +0 -209
  185. package/dist/workflows/dag/frontend-capacity.js +0 -9
  186. package/dist/workflows/dag/frontend-plan-completeness.js +0 -186
  187. package/dist/workflows/dag/frontend-plan-recovery-policy.js +0 -18
@@ -1 +0,0 @@
1
- import{s as r,b as e,a,S as s}from"./chunk-5RXB4S5H-BsG2pmdQ.js";import{_ as i}from"./mermaid.core-CQA4Nzmo.js";import"./chunk-XXDRQBXY-CScR6mDD.js";import"./chunk-KBJHAD2P-BmuEOIh7.js";import"./chunk-2GRJ4B5K-CoviemSL.js";import"./index-wXlQohNs.js";var u={parser:a,get db(){return new s(2)},renderer:e,styles:r,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{u as diagram};
@@ -1,8 +0,0 @@
1
- import{c as r,s as e}from"./flowDiagram-UKHOOZJN-BHIRvRr3.js";import{_ as a}from"./mermaid.core-CQA4Nzmo.js";import"./chunk-5VM5RSS4-DGdvrNm8.js";import"./chunk-XXDRQBXY-CScR6mDD.js";import"./chunk-KBJHAD2P-BmuEOIh7.js";import"./chunk-2GRJ4B5K-CoviemSL.js";import"./channel-BxdTlb_5.js";import"./index-wXlQohNs.js";var o=a(t=>`${e(t)}
2
- .swimlane.cluster rect {
3
- stroke: ${t.clusterBorder} !important;
4
- }
5
- [data-look="neo"].cluster rect {
6
- filter: none;
7
- }
8
- `,"getStyles"),s=o,n=r({defaultLayout:"swimlane",styles:s});export{n as diagram};
@@ -1,10 +0,0 @@
1
- /** Return the active turn tail, including the user row that opened the turn. */
2
- export function selectActiveTurnTail(messages, activeAssistantIndex) {
3
- let start = activeAssistantIndex;
4
- while (start > 0) {
5
- start -= 1;
6
- if (messages[start]?.role === "user")
7
- break;
8
- }
9
- return messages.slice(start);
10
- }
@@ -1,94 +0,0 @@
1
- import { isSafeMarkdownHref } from "../chat-markdown-security.js";
2
- import { buildInspectHref, rewriteInspectHrefToCanonical, splitHash } from "../shell/workspace-route.js";
3
- /** Normalize only this Console's navigation. Never infer ownership from the
4
- * currently selected shell workspace: old messages belong to their session. */
5
- export function resolveChatHref(href, scope, target = {}) {
6
- if (!isSafeMarkdownHref(href))
7
- return { error: "链接地址不可用。" };
8
- const base = scope.origin || (typeof location === "undefined" ? "http://local.invalid" : location.origin);
9
- let url;
10
- try {
11
- url = new URL(href, base);
12
- }
13
- catch {
14
- return { href };
15
- }
16
- if (url.origin !== new URL(base).origin)
17
- return { href };
18
- const documentPath = url.pathname.replace(/\/$/, "") || "/";
19
- const directInspect = /^\/inspect\/(dag|task|run|feature|batch|night|pool|failures|dags)(\/|$)/.test(documentPath);
20
- const inspectDocument = documentPath === "/inspect";
21
- const hashPath = splitHash(url.hash).path;
22
- const consoleHash = /^\/(inspect|operate|chat)(\/|$)/.test(hashPath);
23
- const oldInspectHash = /^\/(dag|task|run|feature|batch|night|pool|failures|dags)(\/|$)/.test(hashPath);
24
- if (!directInspect && !inspectDocument && !(documentPath === "/" && (consoleHash || oldInspectHash)))
25
- return { href };
26
- const canonical = directInspect ? buildInspectHref(documentPath, url.searchParams) : rewriteInspectHrefToCanonical(href, base);
27
- let { path, query } = splitHash(canonical.slice(2));
28
- if (path === "/chat")
29
- return { href: canonical };
30
- const owner = scope.workspaceId?.trim();
31
- if (!owner)
32
- return { error: "无法确认这条消息所属的工作区,请重新打开会话。" };
33
- const explicit = query.get("workspaceId")?.trim();
34
- if (explicit && explicit !== owner)
35
- return { error: "链接工作区与这条消息所属的工作区不一致,请核对链接。" };
36
- if (path === "/inspect" || path === "/inspect/") {
37
- const runId = target.dagRunId || query.get("dagRunId")?.trim();
38
- const taskId = target.taskId || query.get("taskId")?.trim();
39
- if (runId)
40
- path = `/inspect/dag/${encodeURIComponent(runId)}`;
41
- else if (taskId) {
42
- const featureId = query.get("featureId")?.trim();
43
- path = featureId ? `/inspect/feature/${encodeURIComponent(featureId)}/task/${encodeURIComponent(taskId)}` : `/inspect/task/${encodeURIComponent(taskId)}`;
44
- }
45
- else if (query.has("operationId")) {
46
- return { operationId: query.get("operationId")?.trim(), error: "需要查询这条执行记录对应的任务或运行。" };
47
- }
48
- if (runId || taskId) {
49
- for (const key of ["dagRunId", "taskId", "featureId", "operationId"])
50
- query.delete(key);
51
- }
52
- }
53
- if (path.startsWith("/inspect")) {
54
- // These are the object/collection routes consumed by Observe's router.
55
- const inspectPath = path.slice("/inspect".length);
56
- const known = /^(?:\/?|\/(?:pool|failures|night|dags)|\/(?:dag|task|run|feature|batch|night)\/[^/]+|\/feature\/[^/]+\/task\/[^/]+)$/.test(inspectPath);
57
- try {
58
- decodeURIComponent(inspectPath);
59
- }
60
- catch {
61
- return { error: "链接中的位置编码无效。" };
62
- }
63
- if (!known)
64
- return { error: "无法识别这条记录链接的页面位置。" };
65
- }
66
- query.set("workspaceId", owner);
67
- return { href: path.startsWith("/inspect") ? buildInspectHref(path, query) : `/#${path}?${query}` };
68
- }
69
- /** Read an operation only in the message's workspace, never search other repos. */
70
- export async function resolveChatOperationHref(operationId, scope, request = (url) => fetch(url, { credentials: "include", signal: AbortSignal.timeout(10_000) })) {
71
- const owner = scope.workspaceId?.trim();
72
- if (!owner)
73
- return { error: "无法确认这条消息所属的工作区。" };
74
- try {
75
- const response = await request(`${scope.origin ?? ""}/api/operator/v1/operations/${encodeURIComponent(operationId)}?workspaceId=${encodeURIComponent(owner)}`);
76
- if (!response.ok)
77
- return { error: response.status === 404 ? "当前会话工作区中找不到这条执行记录。" : `读取执行记录失败(HTTP ${response.status})。` };
78
- const data = await response.json();
79
- if (data.workspaceId !== owner)
80
- return { error: "执行记录的工作区与当前会话不一致。" };
81
- const op = data.operation;
82
- const id = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
83
- const target = {
84
- dagRunId: id(op?.dagRunId) ?? id(op?.actionParams?.dagRunId) ?? id(op?.actionParams?.runId),
85
- taskId: id(op?.taskId) ?? id(op?.actionParams?.taskId),
86
- };
87
- if (!target.dagRunId && !target.taskId)
88
- return { error: "这条执行记录尚未关联可查看的任务或运行。" };
89
- return resolveChatHref("/#/inspect", scope, target);
90
- }
91
- catch {
92
- return { error: "读取执行记录失败,请稍后重试。" };
93
- }
94
- }
@@ -1,24 +0,0 @@
1
- /** Capture immediately before prepending history, after network waits finish. */
2
- export function captureChatScrollPosition(container) {
3
- const top = container.getBoundingClientRect().top;
4
- const anchor = [...container.querySelectorAll(".oc-turn-group")]
5
- .find((row) => row.getBoundingClientRect().bottom > top);
6
- return {
7
- container,
8
- anchor,
9
- anchorTop: anchor?.getBoundingClientRect().top,
10
- scrollTop: container.scrollTop,
11
- scrollHeight: container.scrollHeight,
12
- };
13
- }
14
- /** DOM anchoring may already have moved the viewport; compensate only the
15
- * remaining displacement, before paint, rather than adding height twice. */
16
- export function restoreChatScrollPosition(position) {
17
- const { container, anchor, anchorTop } = position;
18
- if (anchor && anchorTop !== undefined && container.contains(anchor)) {
19
- container.scrollTop += anchor.getBoundingClientRect().top - anchorTop;
20
- }
21
- else {
22
- container.scrollTop = position.scrollTop + container.scrollHeight - position.scrollHeight;
23
- }
24
- }
@@ -1,192 +0,0 @@
1
- import { createInputHistoryState, navigateInputHistory, recordInputHistoryEntry, resetInputHistoryBrowsing, } from "./input-history.js";
2
- export const DUPLICATE_SUBMISSION_GESTURE_MS = 350;
3
- export function composerSessionKey(identity) {
4
- return `${identity.workspaceId ?? ""}\u0000${identity.sessionId}`;
5
- }
6
- function cloneHistory(history) {
7
- return { ...history, entries: [...history.entries] };
8
- }
9
- function cloneImages(images) {
10
- return [...images];
11
- }
12
- function createRecord() {
13
- return {
14
- draft: "",
15
- images: [],
16
- history: createInputHistoryState(),
17
- revision: 0,
18
- sequence: 0,
19
- initialized: false,
20
- attempts: new Map(),
21
- failedSubmissionCount: 0,
22
- };
23
- }
24
- function sameImages(left, right) {
25
- return (left.length === right.length &&
26
- left.every((image, index) => {
27
- const other = right[index];
28
- return (other !== undefined &&
29
- image.name === other.name &&
30
- image.type === other.type &&
31
- image.mimeType === other.mimeType &&
32
- image.data === other.data);
33
- }));
34
- }
35
- /**
36
- * Browser-local composer state addressed by durable session identity.
37
- *
38
- * Network callbacks settle immutable attempts against their owning record;
39
- * they never need to mutate whichever composer happens to be visible.
40
- */
41
- export class ComposerSessionLedger {
42
- now;
43
- records = new Map();
44
- constructor(now = Date.now) {
45
- this.now = now;
46
- }
47
- has(identity) {
48
- return this.records.has(composerSessionKey(identity));
49
- }
50
- snapshot(identity) {
51
- const record = this.record(identity);
52
- return {
53
- draft: record.draft,
54
- images: cloneImages(record.images),
55
- history: cloneHistory(record.history),
56
- revision: record.revision,
57
- failedSubmissionCount: record.failedSubmissionCount,
58
- };
59
- }
60
- seedDraft(identity, draft) {
61
- const record = this.record(identity);
62
- if (record.initialized || record.revision !== 0 || record.attempts.size > 0)
63
- return false;
64
- record.draft = draft;
65
- record.initialized = true;
66
- return true;
67
- }
68
- setDraft(identity, draft) {
69
- const record = this.record(identity);
70
- if (record.draft === draft)
71
- return false;
72
- record.draft = draft;
73
- record.history = resetInputHistoryBrowsing(record.history);
74
- record.revision += 1;
75
- record.initialized = true;
76
- return true;
77
- }
78
- setImages(identity, images) {
79
- const record = this.record(identity);
80
- record.images = cloneImages(images);
81
- record.revision += 1;
82
- record.initialized = true;
83
- return true;
84
- }
85
- recordHistory(identity, text) {
86
- const record = this.record(identity);
87
- record.history = recordInputHistoryEntry(record.history, text);
88
- }
89
- navigateHistory(identity, direction, context) {
90
- const record = this.record(identity);
91
- const decision = navigateInputHistory(record.history, direction, context);
92
- if (!decision.handled)
93
- return decision;
94
- record.history = decision.state;
95
- if (record.draft !== decision.text) {
96
- record.draft = decision.text;
97
- record.revision += 1;
98
- record.initialized = true;
99
- }
100
- return decision;
101
- }
102
- beginSubmission(identity, sessionGeneration, clientRequestId) {
103
- const record = this.record(identity);
104
- if (!record.draft.trim() && record.images.length === 0)
105
- return null;
106
- const now = this.now();
107
- const sinceLastClaim = record.lastClaim
108
- ? now - record.lastClaim.at
109
- : Number.POSITIVE_INFINITY;
110
- if (record.lastClaim &&
111
- sinceLastClaim >= 0 &&
112
- sinceLastClaim <= DUPLICATE_SUBMISSION_GESTURE_MS &&
113
- record.lastClaim.draft === record.draft &&
114
- sameImages(record.lastClaim.images, record.images))
115
- return null;
116
- record.sequence += 1;
117
- const sequence = record.sequence;
118
- const controller = new AbortController();
119
- const draftSnapshot = record.draft;
120
- const imageSnapshot = cloneImages(record.images);
121
- record.lastClaim = {
122
- draft: draftSnapshot,
123
- images: cloneImages(imageSnapshot),
124
- at: now,
125
- };
126
- record.history = recordInputHistoryEntry(record.history, draftSnapshot);
127
- record.draft = "";
128
- record.images = [];
129
- record.revision += 1;
130
- record.initialized = true;
131
- const attempt = {
132
- attemptId: `${composerSessionKey(identity)}:${sequence}:${clientRequestId}`,
133
- identity: { ...identity },
134
- sessionGeneration,
135
- sequence,
136
- clientRequestId,
137
- draftSnapshot,
138
- imageSnapshot,
139
- committedRevision: record.revision,
140
- signal: controller.signal,
141
- };
142
- record.attempts.set(attempt.attemptId, { attempt, controller });
143
- return attempt;
144
- }
145
- settle(attempt, outcome) {
146
- const key = composerSessionKey(attempt.identity);
147
- const record = this.records.get(key);
148
- const owned = record?.attempts.get(attempt.attemptId);
149
- if (!record || !owned || owned.attempt !== attempt)
150
- return "stale";
151
- record.attempts.delete(attempt.attemptId);
152
- owned.controller.abort();
153
- if (outcome === "accepted")
154
- return "accepted";
155
- if (record.revision === attempt.committedRevision &&
156
- record.draft === "" &&
157
- record.images.length === 0) {
158
- record.draft = attempt.draftSnapshot;
159
- record.images = cloneImages(attempt.imageSnapshot);
160
- record.revision += 1;
161
- return "restored";
162
- }
163
- record.failedSubmissionCount = Math.min(Number.MAX_SAFE_INTEGER, record.failedSubmissionCount + 1);
164
- return "retained";
165
- }
166
- settleByRequest(identity, clientRequestId, outcome) {
167
- const record = this.records.get(composerSessionKey(identity));
168
- const owned = record
169
- ? [...record.attempts.values()].find((entry) => entry.attempt.clientRequestId === clientRequestId)
170
- : undefined;
171
- return owned ? this.settle(owned.attempt, outcome) : "stale";
172
- }
173
- release(identity) {
174
- const key = composerSessionKey(identity);
175
- const record = this.records.get(key);
176
- if (!record)
177
- return;
178
- for (const owned of record.attempts.values())
179
- owned.controller.abort();
180
- record.attempts.clear();
181
- this.records.delete(key);
182
- }
183
- record(identity) {
184
- const key = composerSessionKey(identity);
185
- let record = this.records.get(key);
186
- if (!record) {
187
- record = createRecord();
188
- this.records.set(key, record);
189
- }
190
- return record;
191
- }
192
- }
@@ -1,41 +0,0 @@
1
- import { isSubagentTool } from "../../chat/tool-preview.js";
2
- /**
3
- * Count the collapsed-turn disclosure buckets exactly like DSH
4
- * `TurnProcessNodeView`: tool calls, process messages and subagents, in that
5
- * order. Built-in subagent delegations (`Agent` tool) count as subagents, not
6
- * as ordinary tool calls (2026-09-08 alignment).
7
- *
8
- * @param items - ordered process nodes of one turn.
9
- * @returns the three bucket counts.
10
- */
11
- export function countTurnProcessItems(items) {
12
- let toolCalls = 0;
13
- let messages = 0;
14
- let subagents = 0;
15
- for (const item of items) {
16
- if (item.kind === "tool") {
17
- if (isSubagentTool(item.tool.toolName))
18
- subagents += 1;
19
- else
20
- toolCalls += 1;
21
- continue;
22
- }
23
- messages += 1;
24
- }
25
- return { toolCalls, messages, subagents };
26
- }
27
- /**
28
- * Summary label for a completed turn's process disclosure.
29
- *
30
- * @param counts - bucket counts from {@link countTurnProcessItems}.
31
- * @returns `N 次工具调用 · M 条消息 · K 个 subagent`, or「已思考」when empty.
32
- */
33
- export function buildTurnProcessLabel(counts) {
34
- return ([
35
- counts.toolCalls > 0 ? `${counts.toolCalls} 次工具调用` : "",
36
- counts.messages > 0 ? `${counts.messages} 条消息` : "",
37
- counts.subagents > 0 ? `${counts.subagents} 个 subagent` : "",
38
- ]
39
- .filter(Boolean)
40
- .join(" · ") || "已思考");
41
- }
@@ -1,13 +0,0 @@
1
- function sameReferences(previous, next) {
2
- return (previous.length === next.length &&
3
- previous.every((value, index) => value === next[index]));
4
- }
5
- /** A completed group's rendered projection is reusable only while every source
6
- * object that feeds grouping and process-item derivation remains unchanged. */
7
- export function sameTurnGroupInputs(previous, next) {
8
- return (previous.key === next.key &&
9
- previous.user === next.user &&
10
- previous.live === next.live &&
11
- sameReferences(previous.assistants, next.assistants) &&
12
- sameReferences(previous.tools, next.tools));
13
- }
@@ -1,10 +0,0 @@
1
- export function turnProcessDisclosureKey(groupKey, answerId) {
2
- return `${groupKey}:generation-${answerId ?? "none"}`;
3
- }
4
- export function isTurnProcessCompact(input) {
5
- return (!input.historyHasMore &&
6
- !input.live &&
7
- !input.hasError &&
8
- input.processItemCount > 0 &&
9
- !input.expanded);
10
- }
@@ -1,51 +0,0 @@
1
- import { useEffect, useLayoutEffect, useRef } from "react";
2
- /** Whether this browser can reveal `hidden="until-found"` content through
3
- * `beforematch` (Chrome 102+, Firefox 148+, Safari: not supported at all).
4
- * `content-visibility` support does NOT imply this — Safari 18+ and
5
- * Firefox 125–147 have the former without the latter. */
6
- function supportsUntilFound() {
7
- return typeof document !== "undefined" && "onbeforematch" in document.body;
8
- }
9
- /**
10
- * Collapse content without removing it from the document: the element gets
11
- * `hidden="until-found"` so browser find-in-page can still reach the text, and
12
- * a match fires `beforematch`, which reveals (expands) the disclosure again.
13
- *
14
- * Mirrors DSH `useSearchableHidden` (2026-09-08 alignment). Browsers without
15
- * `until-found` support get a plain `hidden=""` element, which keeps the
16
- * pre-alignment behavior (collapsed and not searchable).
17
- *
18
- * @param hidden - whether the content is collapsed.
19
- * @param reveal - expand callback invoked on `beforematch` and when the
20
- * collapsed subtree already owns focus.
21
- * @returns ref for the collapsible container.
22
- */
23
- export function useSearchableHidden(hidden, reveal) {
24
- const ref = useRef(null);
25
- useLayoutEffect(() => {
26
- const element = ref.current;
27
- if (element === null)
28
- return;
29
- // Focus would otherwise be lost inside a hidden subtree.
30
- if (hidden && element.contains(element.ownerDocument.activeElement)) {
31
- reveal();
32
- return;
33
- }
34
- if (hidden) {
35
- element.setAttribute("hidden", supportsUntilFound() ? "until-found" : "");
36
- }
37
- else {
38
- element.removeAttribute("hidden");
39
- }
40
- }, [hidden, reveal]);
41
- useEffect(() => {
42
- const element = ref.current;
43
- if (element === null)
44
- return;
45
- element.addEventListener("beforematch", reveal);
46
- return () => {
47
- element.removeEventListener("beforematch", reveal);
48
- };
49
- }, [reveal]);
50
- return ref;
51
- }
@@ -1,21 +0,0 @@
1
- /** User anchors only depend on the ordered user-message objects, not on
2
- * assistant/process updates that rebuild their containing turn groups. */
3
- export function sameUserMessages(previous, next) {
4
- let previousIndex = 0;
5
- let nextIndex = 0;
6
- for (;;) {
7
- while (previousIndex < previous.length && !previous[previousIndex].user) {
8
- previousIndex += 1;
9
- }
10
- while (nextIndex < next.length && !next[nextIndex].user) {
11
- nextIndex += 1;
12
- }
13
- if (previousIndex === previous.length || nextIndex === next.length) {
14
- return previousIndex === previous.length && nextIndex === next.length;
15
- }
16
- if (previous[previousIndex].user !== next[nextIndex].user)
17
- return false;
18
- previousIndex += 1;
19
- nextIndex += 1;
20
- }
21
- }