@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.
- package/CHANGELOG.md +9 -140
- package/dist/application/task-lifecycle/advance.js +4 -17
- package/dist/application/task-lifecycle/observe.js +29 -43
- package/dist/application/task-lifecycle/plan-transitions.js +4 -5
- package/dist/build-stamp.json +3 -3
- package/dist/commands/client-recovery.js +55 -20
- package/dist/commands/new-task.js +5 -0
- package/dist/commands/status.js +57 -0
- package/dist/commands/task-contract.js +269 -0
- package/dist/executors/dag-pi-executor.js +230 -269
- package/dist/executors/pi-executor.js +0 -2
- package/dist/executors/pi-sdk-executor.js +39 -77
- package/dist/executors/shell-executor.js +2 -3
- package/dist/executors/shell-write-guard.js +32 -27
- package/dist/shared/pi-context-pressure/extension.js +16 -26
- package/dist/shared/pi-retry-settings.js +0 -40
- package/dist/shared/prompts.js +26 -0
- package/dist/task/config.js +2 -0
- package/dist/task/contract/validate-draft.js +106 -0
- package/dist/task/goal.js +3 -0
- package/dist/task/index.js +12 -0
- package/dist/task/lifecycle.js +1 -0
- package/dist/task/operator/capabilities.js +6 -0
- package/dist/task/operator/envelope.js +2 -0
- package/dist/task/operator/index.js +5 -0
- package/dist/task/operator/registry.js +2 -0
- package/dist/task/operator/types.js +1 -0
- package/dist/task/paths.js +1 -0
- package/dist/task/source-prepare/source-fidelity-pi.js +2 -2
- package/dist/task/source-references.js +23 -48
- package/dist/task/source-state.js +1 -0
- package/dist/task/subagent-guidance.js +1 -0
- package/dist/worker/console/chat/assistant-content.js +2 -23
- package/dist/worker/console/chat/explore-tools.js +0 -13
- package/dist/worker/console/chat/pi-runtime.js +1182 -221
- package/dist/worker/console/chat/routes.js +71 -213
- package/dist/worker/console/chat/sdd-data-alignment.js +9 -65
- package/dist/worker/console/chat/session-catalog.js +0 -32
- package/dist/worker/console/chat/session-store.js +6 -22
- package/dist/worker/console/chat/shortcuts.js +0 -6
- package/dist/worker/console/chat/sift-bridge.js +1 -0
- package/dist/worker/console/chat/tool-preview.js +0 -11
- package/dist/worker/console/chat/tools.js +0 -6
- package/dist/worker/console/console-update-and-init.js +19 -1
- package/dist/worker/console/console-update-runtime.js +20 -5
- package/dist/worker/console/index.js +20 -0
- package/dist/worker/console/operator-actions.js +1 -13
- package/dist/worker/console/routes.js +0 -8
- package/dist/worker/console/server.js +29 -11
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-C4NXyedy.js → abnfDiagram-N423BO3Z-hUmM_GRf.js} +1 -1
- package/dist/worker/console/static/assets/{arc-NZ3qXvBI.js → arc-Bt-xuieW.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-COZSRvml.js → architectureDiagram-T3A2C74G-DTqkL4DJ.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Ck0Gxi9C.js → blockDiagram-VBNYF7ZC-Cy0MNnzV.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BX5HQ4Ox.js → c4Diagram-5PPSVZJV-DDdlT0Pd.js} +1 -1
- package/dist/worker/console/static/assets/channel-BpzRnZmU.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-CoviemSL.js → chunk-2GRJ4B5K-3JawwNZ6.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DbOdOkbZ.js → chunk-2Q5K7J3B-DoTp7Cri.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BsG2pmdQ.js → chunk-5RXB4S5H-CcirhZaS.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-DGdvrNm8.js → chunk-5VM5RSS4-VrG21gnP.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-BAy7Yd6y.js → chunk-6Q2QTUOP-DDOgIS70.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-D9UA7hUb.js → chunk-GF5L2VYU-CBjmgvJ_.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-DPz7SZ8V.js → chunk-JWPE2WC7-CCQSht8M.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BmuEOIh7.js → chunk-KBJHAD2P-BpGMkUUV.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CIhBWnd8.js → chunk-RYQCIY6F-DNDT41QL.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CScR6mDD.js → chunk-XXDRQBXY-euXnDFbn.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BhlMVqCc.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BhlMVqCc.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BjpfWaUr.js → cose-bilkent-JH36ORCC-BJ6NAeql.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BFQohJgT.js → cynefin-VYW2F7L2-F5JKIvIq.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-D3gzRJnS.js → cynefinDiagram-MW4NZA55-Cwmkl_Gi.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-5eojkhoA.js → dagre-VZM6K2ZE-BmCZ8815.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CpD8LWu_.js → diagram-7IWD3JNH-zWA3hUnX.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-B8_4qJ2a.js → diagram-B4RE2ZJO-BzA-888F.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-HOsXf0eu.js → diagram-LBJQPF4R-tPNheoch.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BqwRwiWP.js → diagram-Q27KOJAE-Cdi7Fyqp.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-BRVCNZe1.js → diagram-UB23O5K3-DFK9VBf1.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Cvb1TgGh.js → ebnfDiagram-BXEA7PRR-xCUr1kpg.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DS0O0qG9.js → erDiagram-JOGREHBK-BANQHY_A.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-BHIRvRr3.js → flowDiagram-UKHOOZJN-VHJYEMkP.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DcCJ1JWx.js → ganttDiagram-PKOTCBZU-DiyZQ0C6.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-B9ia5ony.js → gitGraphDiagram-DS77QQ5N-CZtIeBBa.js} +1 -1
- package/dist/worker/console/static/assets/index-BlN6ytLr.css +1 -0
- package/dist/worker/console/static/assets/index-CA-jfWlE.js +449 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-3ogpgegn.js → infoDiagram-6WML65LV-BuSspC0X.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-4tgpQ5SL.js → ishikawaDiagram-WSZJBQD7-DRJZyPFy.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DNfgHqFx.js → journeyDiagram-NVQOT4AX-DIfXIVuE.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-Dz7ngC8z.js → kanban-definition-27J2QSJJ-CT10_7Lt.js} +1 -1
- package/dist/worker/console/static/assets/{linear-DI7Jv62E.js → linear-ufemj74H.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-CQA4Nzmo.js → mermaid.core-DEQe8-_m.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-CtsMc8Mf.js → mindmap-definition-FAOFIHXS-BRLUrbrC.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-ByppE9yH.js → pegDiagram-VL7TDLO6-BgibKtiF.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-B5PtgFgt.js → pieDiagram-7S7Q4E2Y-D3eyfdV9.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-Cq4p0k2K.js → quadrantDiagram-CIZ2JOQS-DXeTk5Px.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-DjfkyljN.js → railroadDiagram-AXF67PYL-BgXdFEe7.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-DzynNRSl.js → requirementDiagram-LRYGKXZP-CseC2A7R.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cj7TCpTJ.js → sankeyDiagram-W5VNT64P-D80PFzfJ.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-C73C6ykA.js → sequenceDiagram-SI44F4Z6-BWzHW7LS.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-BiNLgN2x.js → sizeCapture-X5ZJPWSS-xWQYTLAn.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-UwvjS64-.js → stateDiagram-OKZ733FA-CLxtpZeL.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-CiVoq4G-.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CC7DH98r.js → swimlanes-SLNWSIFB-DwugtmWV.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BkdgdpfR.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-LSBXTR70.js → timeline-definition-Z64GVDOM-DHEOwHIe.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-BAuxWwGP.js → vennDiagram-T6HMQDX7-pmbZKlBK.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y--E5_gjZx.js → wardleyDiagram-T6FBY63Y-CivHoM5q.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-dJWNmyzF.js → xychartDiagram-ELKLHX3M-BfHIE7o6.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +10 -122
- package/dist/worker/console/static-src/operator-chat/compaction-message.js +0 -7
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +15 -35
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +62 -136
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +68 -159
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +56 -75
- package/dist/worker/console/static-src/operator-chat/useComposer.js +78 -206
- package/dist/worker/console/workspace-context.js +1 -21
- package/dist/worker/observe/static/router.js +1 -1
- package/dist/worker/observe/static/styles.css +4 -7
- package/dist/worker/observe/static/views/dag-inspector.js +19 -12
- package/dist/worker/observe/static/views/dag.js +2 -2
- package/dist/worker/scheduler/index.js +25 -0
- package/dist/workflows/dag/facts.js +4 -0
- package/dist/workflows/dag/frontend-closeout.js +1 -1
- package/dist/workflows/dag/frontend-design-policy.js +1 -2
- package/dist/workflows/dag/frontend-implementation-contract.js +4 -8
- package/dist/workflows/dag/frontend-prewrite-gate.js +3 -3
- package/dist/workflows/dag/frontend-repair.js +76 -55
- package/dist/workflows/dag/frontend-review-context.js +1 -2
- package/dist/workflows/dag/frontend-review-scopes.js +12 -34
- package/dist/workflows/dag/frontend-shape-facts.js +2 -12
- package/dist/workflows/dag/frontend-verification-trace.js +42 -8
- package/dist/workflows/dag/index.js +6 -0
- package/dist/workflows/dag/init-hybrid.js +160 -97
- package/dist/workflows/dynamic/index.js +7 -0
- package/docs/architecture/runtime-boundaries.md +3 -3
- package/docs/templates/frontend-implementation-dag.json +8 -9
- package/package.json +3 -7
- package/skills/frontend-bounded-implement/SKILL.md +3 -4
- package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
- package/skills/frontend-contract/references/contract-protocol.md +1 -3
- package/skills/frontend-design-review/SKILL.md +7 -12
- package/skills/frontend-design-review/references/review-checklist.md +7 -7
- package/skills/frontend-plan/SKILL.md +0 -19
- package/skills/frontend-plan/references/decision-contract.md +19 -26
- package/skills/frontend-review/SKILL.md +18 -12
- package/skills/frontend-review/references/review-findings.md +43 -24
- package/dist/shared/pi-provider-recovery.js +0 -182
- package/dist/worker/console/chat/browser-automation.js +0 -363
- package/dist/worker/console/chat/browser-policy.js +0 -113
- package/dist/worker/console/chat/browser-routes.js +0 -162
- package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +0 -44
- package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +0 -89
- package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +0 -202
- package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +0 -79
- package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +0 -86
- package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +0 -38
- package/dist/worker/console/chat/pi-runtime/inspection-types.js +0 -28
- package/dist/worker/console/chat/pi-runtime/inspection.js +0 -439
- package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +0 -153
- package/dist/worker/console/chat/pi-runtime/sdk-session.js +0 -5
- package/dist/worker/console/chat/scm-routes.js +0 -217
- package/dist/worker/console/chat/scm-service.js +0 -283
- package/dist/worker/console/chat/scm-tools.js +0 -111
- package/dist/worker/console/chat/session-mode-view.js +0 -49
- package/dist/worker/console/chat/session-mode.js +0 -220
- package/dist/worker/console/chat/terminal-routes.js +0 -216
- package/dist/worker/console/chat/terminal-sessions.js +0 -348
- package/dist/worker/console/chat/terminal-tools.js +0 -211
- package/dist/worker/console/static/assets/channel-BxdTlb_5.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-_ByA1Nf8.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-_ByA1Nf8.js +0 -1
- package/dist/worker/console/static/assets/index-B9goN3S5.css +0 -1
- package/dist/worker/console/static/assets/index-wXlQohNs.js +0 -469
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-nLgMZ0D3.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BcYqTady.js +0 -8
- package/dist/worker/console/static-src/operator-chat/active-turn-tail.js +0 -10
- package/dist/worker/console/static-src/operator-chat/chat-link.js +0 -94
- package/dist/worker/console/static-src/operator-chat/chat-scroll-position.js +0 -24
- package/dist/worker/console/static-src/operator-chat/composer-session-ledger.js +0 -192
- package/dist/worker/console/static-src/operator-chat/process-label.js +0 -41
- package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +0 -13
- package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +0 -10
- package/dist/worker/console/static-src/operator-chat/use-searchable-hidden.js +0 -51
- package/dist/worker/console/static-src/operator-chat/user-turn-anchor-equality.js +0 -21
- package/dist/worker/console/workspace-initialization.js +0 -209
- package/dist/workflows/dag/frontend-capacity.js +0 -9
- package/dist/workflows/dag/frontend-plan-completeness.js +0 -186
- 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
|
-
}
|