@tea-agent/loop-agent 0.43.0-next.1 → 0.43.0-next.10
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 +129 -9
- package/dist/application/dag/run-dag.js +5 -0
- package/dist/application/evaluation/budget.js +19 -1
- package/dist/application/task-lifecycle/advance.js +17 -4
- package/dist/application/task-lifecycle/observe.js +43 -29
- package/dist/application/task-lifecycle/plan-transitions.js +5 -4
- package/dist/build-stamp.json +3 -3
- package/dist/executors/dag-pi-executor.js +1214 -584
- package/dist/executors/pi-executor.js +22 -1
- package/dist/executors/pi-sdk-executor.js +140 -39
- package/dist/executors/shell-executor.js +5 -2
- package/dist/shared/frontend-execution-policy.js +23 -0
- package/dist/task/config-types.js +4 -0
- package/dist/task/source-prepare/ledger-reconciliation.js +2 -2
- package/dist/task/source-prepare/ledger-review.js +6 -9
- package/dist/task/source-prepare/semantic-intake.js +16 -26
- package/dist/task/source-prepare/source-fidelity-pi.js +28 -9
- package/dist/task/source-references.js +48 -23
- package/dist/worker/console/chat/assistant-content.js +23 -2
- package/dist/worker/console/chat/browser-policy.js +143 -0
- package/dist/worker/console/chat/browser-routes.js +148 -0
- package/dist/worker/console/chat/explore-tools.js +13 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +44 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +202 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +78 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +86 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +38 -0
- package/dist/worker/console/chat/pi-runtime/inspection-types.js +28 -0
- package/dist/worker/console/chat/pi-runtime/inspection.js +439 -0
- package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +153 -0
- package/dist/worker/console/chat/pi-runtime/sdk-session.js +5 -0
- package/dist/worker/console/chat/pi-runtime.js +213 -1181
- package/dist/worker/console/chat/routes.js +212 -71
- package/dist/worker/console/chat/scm-routes.js +217 -0
- package/dist/worker/console/chat/scm-service.js +283 -0
- package/dist/worker/console/chat/scm-tools.js +111 -0
- package/dist/worker/console/chat/sdd-data-alignment.js +65 -9
- package/dist/worker/console/chat/session-catalog.js +32 -0
- package/dist/worker/console/chat/session-mode-view.js +48 -0
- package/dist/worker/console/chat/session-mode.js +218 -0
- package/dist/worker/console/chat/session-store.js +22 -6
- package/dist/worker/console/chat/shortcuts.js +6 -0
- package/dist/worker/console/chat/terminal-routes.js +216 -0
- package/dist/worker/console/chat/terminal-sessions.js +348 -0
- package/dist/worker/console/chat/terminal-tools.js +211 -0
- package/dist/worker/console/chat/tool-preview.js +11 -0
- package/dist/worker/console/chat/tools.js +2 -0
- package/dist/worker/console/server.js +2 -28
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-B0Q0nClf.js → abnfDiagram-N423BO3Z-D_fNbWc_.js} +1 -1
- package/dist/worker/console/static/assets/{arc-DCPjC19G.js → arc-_HuqLW6m.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CP5n9jmG.js → architectureDiagram-T3A2C74G-Djy2qY1m.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CmaWi_Wg.js → blockDiagram-VBNYF7ZC-bB-1TSyY.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-Ct5tcMfZ.js → c4Diagram-5PPSVZJV-C5Hmghrz.js} +1 -1
- package/dist/worker/console/static/assets/channel-C0A6UEIa.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-C0osm1Zf.js → chunk-2GRJ4B5K-Duyl39oy.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CDWviED7.js → chunk-2Q5K7J3B-x6mdnSyf.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-mtSk1-j7.js → chunk-5RXB4S5H-WlBuFj7W.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-D5J9PHC7.js → chunk-5VM5RSS4-CTF429HX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Begg4WAa.js → chunk-6Q2QTUOP-Dwd6r-SF.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-sF1AEy7T.js → chunk-GF5L2VYU-C-Br82D1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BqbsWXZb.js → chunk-JWPE2WC7-CuGp0DeE.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BKJrPcJ6.js → chunk-KBJHAD2P-CJhFX6Lh.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CcwNMRho.js → chunk-RYQCIY6F-DpGOa_jT.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-BEJi3iIs.js → chunk-XXDRQBXY-DXJaTynd.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DzguNppy.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DzguNppy.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-DRLgTvVu.js → cose-bilkent-JH36ORCC-CRBZWjE4.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BoAVG3cs.js → cynefin-VYW2F7L2-BdXcxtlb.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-Bzol06hR.js → cynefinDiagram-MW4NZA55-07UKsOts.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-UmliJM77.js → dagre-VZM6K2ZE-D38p9__S.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BWLcJkFo.js → diagram-7IWD3JNH-nSiBNNjH.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-CgApOm-O.js → diagram-B4RE2ZJO-BFOTot5D.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-Bh3RgTLs.js → diagram-LBJQPF4R-DypKaZ6k.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-Dsh-D5nE.js → diagram-Q27KOJAE-B6yoOQeW.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-Dkbbpcpb.js → diagram-UB23O5K3-BHYS6viX.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-3EBaA3t3.js → ebnfDiagram-BXEA7PRR-D2VD5Snj.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Bq2Dc5ok.js → erDiagram-JOGREHBK-E98mWxN1.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-De7y55ha.js → flowDiagram-UKHOOZJN-CT1zxhqP.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-fLiDbQRh.js → ganttDiagram-PKOTCBZU-6GcngNcy.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Du617mp1.js → gitGraphDiagram-DS77QQ5N-DCL6NvKe.js} +1 -1
- package/dist/worker/console/static/assets/index-24jp3aBh.js +468 -0
- package/dist/worker/console/static/assets/index-CY6y6I8M.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-BwmlF-XP.js → infoDiagram-6WML65LV-C0627e-9.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-zsGtS59u.js → ishikawaDiagram-WSZJBQD7-C_u3P6Ik.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DTTPTe3f.js → journeyDiagram-NVQOT4AX-DPDPv9HL.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-BkXg9aP-.js → kanban-definition-27J2QSJJ-D3OHdWiO.js} +1 -1
- package/dist/worker/console/static/assets/{linear-7U2ue5IE.js → linear-DI88zD7n.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-BUuGHmWO.js → mermaid.core-p2l8IrWY.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-7q6fX0Sv.js → mindmap-definition-FAOFIHXS-B1bAX-oS.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-CkQPJN55.js → pegDiagram-VL7TDLO6-DwOnWxdD.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CCal_tfX.js → pieDiagram-7S7Q4E2Y-xRkTXnJC.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-B7bpxyAZ.js → quadrantDiagram-CIZ2JOQS-_9UC5Zio.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CJmww7D-.js → railroadDiagram-AXF67PYL-CgEUirWJ.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-D6ldWJEv.js → requirementDiagram-LRYGKXZP-Czbpwiyz.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-VGh33I9e.js → sankeyDiagram-W5VNT64P-_j7_KiqY.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CCkDrIjU.js → sequenceDiagram-SI44F4Z6-BNJa6Hyi.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-NC8f5Otb.js → sizeCapture-X5ZJPWSS-DedpKtOc.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-_92ezZdF.js → stateDiagram-OKZ733FA-BBvthr7c.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BABVQnfM.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BdUCGtbP.js → swimlanes-SLNWSIFB-Ds7umgEM.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D0qsLaxR.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CdD1H8ia.js → timeline-definition-Z64GVDOM-CKa-p1nF.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-Dkdk3oFo.js → vennDiagram-T6HMQDX7-LoUNR56o.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CKu2uPPY.js → wardleyDiagram-T6FBY63Y-Bqbl6ym7.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-ClqAnuG8.js → xychartDiagram-ELKLHX3M-B8dUg4lf.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/active-turn-tail.js +10 -0
- package/dist/worker/console/static-src/operator-chat/chat-link.js +94 -0
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +122 -10
- package/dist/worker/console/static-src/operator-chat/compaction-message.js +7 -0
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +27 -15
- package/dist/worker/console/static-src/operator-chat/process-label.js +41 -0
- package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +13 -0
- package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +10 -0
- package/dist/worker/console/static-src/operator-chat/use-searchable-hidden.js +51 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +44 -24
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +18 -2
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +41 -8
- package/dist/worker/console/static-src/operator-chat/useComposer.js +26 -11
- package/dist/worker/console/static-src/operator-chat/user-turn-anchor-equality.js +21 -0
- package/dist/worker/console/workspace-context.js +15 -1
- package/dist/worker/observe/node-transparency.js +81 -72
- package/dist/worker/observe/routes.js +20 -1
- package/dist/worker/observe/static/dag-inspector-humanize.js +3 -0
- package/dist/worker/observe/static/dom.js +20 -1
- package/dist/worker/observe/static/format-pool.d.ts +2 -0
- package/dist/worker/observe/static/format-pool.js +6 -0
- package/dist/worker/observe/static/format.js +7 -0
- package/dist/worker/observe/static/inspect-workspace.js +34 -7
- package/dist/worker/observe/static/inspector-submission.js +32 -0
- package/dist/worker/observe/static/kpi.js +1 -0
- package/dist/worker/observe/static/relations.js +2 -0
- package/dist/worker/observe/static/router.js +13 -0
- package/dist/worker/observe/static/run-processing.js +2 -0
- package/dist/worker/observe/static/shell-chrome.js +36 -3
- package/dist/worker/observe/static/state.js +35 -2
- package/dist/worker/observe/static/styles.css +263 -39
- package/dist/worker/observe/static/task-failure-labels.d.ts +4 -0
- package/dist/worker/observe/static/task-failure-labels.js +67 -0
- package/dist/worker/observe/static/task-history.js +12 -0
- package/dist/worker/observe/static/views/batch.js +6 -13
- package/dist/worker/observe/static/views/dag-graph.js +50 -3
- package/dist/worker/observe/static/views/dag-inspector.js +742 -268
- package/dist/worker/observe/static/views/dag-trajectory.js +3 -0
- package/dist/worker/observe/static/views/dag.d.ts +6 -0
- package/dist/worker/observe/static/views/dag.js +49 -11
- package/dist/worker/observe/static/views/dags.js +2 -0
- package/dist/worker/observe/static/views/dashboard.js +21 -12
- package/dist/worker/observe/static/views/failures.js +21 -11
- package/dist/worker/observe/static/views/feature.js +11 -29
- package/dist/worker/observe/static/views/pool.js +37 -28
- package/dist/worker/observe/static/views/run.js +48 -5
- package/dist/worker/observe/static/views/session-timeline.js +189 -240
- package/dist/worker/observe/static/views/task.js +81 -62
- package/dist/workflows/dag/budget-enforcement.js +53 -3
- package/dist/workflows/dag/frontend-capacity.js +9 -0
- package/dist/workflows/dag/frontend-design-policy.js +2 -1
- package/dist/workflows/dag/frontend-durable-tools.js +193 -0
- package/dist/workflows/dag/frontend-execution-groups.js +24 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +13 -0
- package/dist/workflows/dag/frontend-input-projection.js +76 -0
- package/dist/workflows/dag/frontend-plan-completeness.js +186 -0
- package/dist/workflows/dag/frontend-plan-recovery-policy.js +18 -0
- package/dist/workflows/dag/frontend-plan-render.js +10 -3
- package/dist/workflows/dag/frontend-recovery-controller.js +7 -7
- package/dist/workflows/dag/frontend-recovery-lineage.js +13 -0
- package/dist/workflows/dag/frontend-recovery-run.js +4 -0
- package/dist/workflows/dag/frontend-review-scopes.js +139 -0
- package/dist/workflows/dag/frontend-session-budget.js +249 -0
- package/dist/workflows/dag/frontend-shadow-dual-write.js +20 -2
- package/dist/workflows/dag/frontend-shape-facts.js +12 -2
- package/dist/workflows/dag/frontend-shape.js +30 -1
- package/dist/workflows/dag/frontend-test-execution-evidence.js +3 -2
- package/dist/workflows/dag/frontend-typed-event-store.js +11 -0
- package/dist/workflows/dag/init-hybrid.js +16 -10
- package/dist/workflows/dag/node-execution.js +38 -155
- package/dist/workflows/dag/prompt.js +4 -0
- package/dist/workflows/dag/rerun-plan.js +7 -1
- package/dist/workflows/dag/runner.js +26 -1
- package/dist/workflows/dag/types.js +6 -0
- package/docs/operations/README.md +1 -0
- package/docs/templates/frontend-design-contract.md +4 -4
- package/docs/templates/frontend-implementation-contract.schema.json +34 -2
- package/docs/templates/frontend-implementation-dag.json +5 -5
- package/package.json +6 -3
- package/skills/frontend-contract/SKILL.md +2 -1
- package/skills/frontend-contract/references/contract-protocol.md +19 -3
- package/skills/frontend-design-review/SKILL.md +12 -11
- package/skills/frontend-plan/SKILL.md +9 -2
- package/skills/frontend-plan/references/decision-contract.md +18 -5
- package/skills/frontend-review/SKILL.md +10 -11
- package/skills/frontend-scout/references/scout-evidence.md +4 -0
- package/dist/worker/console/static/assets/channel-DAS07MdS.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-Cwk-5jiW.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-Cwk-5jiW.js +0 -1
- package/dist/worker/console/static/assets/index-C0O48S_P.js +0 -449
- package/dist/worker/console/static/assets/index-CzKf4U8P.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DyJg5gzW.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-B1cw_0Uy.js +0 -8
|
@@ -16,6 +16,7 @@ import { randomUUID } from "node:crypto";
|
|
|
16
16
|
import { access } from "node:fs/promises";
|
|
17
17
|
import { parseAssistantContent } from "./assistant-content.js";
|
|
18
18
|
import { OPERATOR_CHAT_ALLOWED_TOOLS, OPERATOR_CHAT_DENIED_TOOLS, OPERATOR_CHAT_DENIED_OPERATOR_ACTIONS, } from "./tools.js";
|
|
19
|
+
import { InvalidChatSessionModeError, SESSION_MODE_ACTION_DENIED_CODE, SESSION_MODE_ACTION_DENIED_MESSAGE, SESSION_MODE_IMMUTABLE_CODE, UnknownChatSessionModeError, isWorkflowSessionMode, parseCreateSessionMode, readStoredSessionMode, shouldAcceptOperatorSnapshot, } from "./session-mode.js";
|
|
19
20
|
import { buildModelCallableToolSchemas } from "./tool-adapter.js";
|
|
20
21
|
import { cleanChatTitle, acceptedOperationIdFromResult, isBlankChatSession } from "./session-store.js";
|
|
21
22
|
import { hashChatTurnPayload, projectChatToolEventPayload, projectCompactSnapshot, } from "./chat-event-store.js";
|
|
@@ -44,11 +45,80 @@ import { buildGoalCompactionInstructions, buildGoalContinuationContext, } from "
|
|
|
44
45
|
import { classifyGoalRoundAdmission, } from "./goal-round-driver.js";
|
|
45
46
|
import { isTerminalOperationState } from "../../../infrastructure/console/operation-store.js";
|
|
46
47
|
import { SddDataAlignmentError, } from "./sdd-data-alignment.js";
|
|
48
|
+
import { TerminalSessionRegistry } from "./terminal-sessions.js";
|
|
49
|
+
import { handleTerminalRequest } from "./terminal-routes.js";
|
|
50
|
+
import { handleScmRequest } from "./scm-routes.js";
|
|
51
|
+
import { handleBrowserRequest } from "./browser-routes.js";
|
|
47
52
|
function projectBrowserChatSession(record) {
|
|
48
53
|
const { telemetrySessionId, ...projected } = record;
|
|
49
54
|
void telemetrySessionId;
|
|
50
55
|
return projected;
|
|
51
56
|
}
|
|
57
|
+
function reopenInitFromRecord(record) {
|
|
58
|
+
return {
|
|
59
|
+
sessionId: record.sessionId,
|
|
60
|
+
sessionFile: record.sessionFile,
|
|
61
|
+
...(record.modelProvider && record.modelId
|
|
62
|
+
? { model: { provider: record.modelProvider, modelId: record.modelId } }
|
|
63
|
+
: {}),
|
|
64
|
+
sessionMode: record.sessionMode,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async function readChatSessionMode(deps, sessionId) {
|
|
68
|
+
let record;
|
|
69
|
+
try {
|
|
70
|
+
record = await deps.store.get(sessionId);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (error instanceof UnknownChatSessionModeError) {
|
|
74
|
+
return {
|
|
75
|
+
ok: false,
|
|
76
|
+
status: 409,
|
|
77
|
+
code: error.code,
|
|
78
|
+
message: error.message,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
if (!record) {
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
86
|
+
status: 404,
|
|
87
|
+
code: "NOT_FOUND",
|
|
88
|
+
message: `chat session not found: ${sessionId}`,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
// Normalize: the store contract always fills sessionMode, but handler-level
|
|
92
|
+
// fakes / partial records may omit it — treat missing as workflow (the
|
|
93
|
+
// stock-record read rule), while a present-but-unknown value still fails
|
|
94
|
+
// closed in the store layer.
|
|
95
|
+
return {
|
|
96
|
+
ok: true,
|
|
97
|
+
record,
|
|
98
|
+
sessionMode: readStoredSessionMode(record.sessionMode),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function requireWorkflowSession(res, deps, sessionId) {
|
|
102
|
+
const resolved = await readChatSessionMode(deps, sessionId);
|
|
103
|
+
if (!resolved.ok) {
|
|
104
|
+
sendJson(res, resolved.status, {
|
|
105
|
+
ok: false,
|
|
106
|
+
error: { code: resolved.code, message: resolved.message },
|
|
107
|
+
});
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
if (!isWorkflowSessionMode(resolved.sessionMode)) {
|
|
111
|
+
sendJson(res, 409, {
|
|
112
|
+
ok: false,
|
|
113
|
+
error: {
|
|
114
|
+
code: SESSION_MODE_ACTION_DENIED_CODE,
|
|
115
|
+
message: SESSION_MODE_ACTION_DENIED_MESSAGE,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
return resolved.record;
|
|
121
|
+
}
|
|
52
122
|
/**
|
|
53
123
|
* Reattach the durable event-ring order to session-store rows. The session
|
|
54
124
|
* store remains the content authority; the ring only supplies chronology.
|
|
@@ -565,6 +635,22 @@ workspaceId) {
|
|
|
565
635
|
});
|
|
566
636
|
return;
|
|
567
637
|
}
|
|
638
|
+
let sessionMode;
|
|
639
|
+
try {
|
|
640
|
+
sessionMode = parseCreateSessionMode(body.sessionMode);
|
|
641
|
+
}
|
|
642
|
+
catch (error) {
|
|
643
|
+
sendJson(res, 400, {
|
|
644
|
+
ok: false,
|
|
645
|
+
error: {
|
|
646
|
+
code: error instanceof InvalidChatSessionModeError
|
|
647
|
+
? error.code
|
|
648
|
+
: "INVALID_SESSION_MODE",
|
|
649
|
+
message: error instanceof Error ? error.message : String(error),
|
|
650
|
+
},
|
|
651
|
+
});
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
568
654
|
const provider = typeof body.modelProvider === "string" ? body.modelProvider : undefined;
|
|
569
655
|
const modelId = typeof body.modelId === "string" ? body.modelId : undefined;
|
|
570
656
|
const snapshotInput = body.snapshot;
|
|
@@ -586,6 +672,16 @@ workspaceId) {
|
|
|
586
672
|
let createdSessionId;
|
|
587
673
|
let persisted = false;
|
|
588
674
|
try {
|
|
675
|
+
if (snapshotInput !== undefined && !shouldAcceptOperatorSnapshot(sessionMode)) {
|
|
676
|
+
sendJson(res, 409, {
|
|
677
|
+
ok: false,
|
|
678
|
+
error: {
|
|
679
|
+
code: SESSION_MODE_ACTION_DENIED_CODE,
|
|
680
|
+
message: "Operator snapshots cannot be imported into Pi sessions",
|
|
681
|
+
},
|
|
682
|
+
});
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
589
685
|
const snapshot = snapshotInput === undefined ? undefined : projectCompactSnapshot(snapshotInput);
|
|
590
686
|
// A Console record promises that its Pi JSONL can be reopened after a
|
|
591
687
|
// Console restart. Do not make that promise until Pi has finished
|
|
@@ -593,6 +689,7 @@ workspaceId) {
|
|
|
593
689
|
// future JSONL path, leaving an unrecoverable orphan when init failed or
|
|
594
690
|
// the process restarted in that window.
|
|
595
691
|
const handle = await deps.runtime.createSession({
|
|
692
|
+
sessionMode,
|
|
596
693
|
...(provider && modelId ? { model: { provider, modelId } } : {}),
|
|
597
694
|
...(snapshot
|
|
598
695
|
? {
|
|
@@ -619,6 +716,7 @@ workspaceId) {
|
|
|
619
716
|
sessionFile: handle.sessionFile,
|
|
620
717
|
modelProvider: selection.model?.provider ?? handle.model?.provider,
|
|
621
718
|
modelId: selection.model?.modelId ?? handle.model?.modelId,
|
|
719
|
+
sessionMode,
|
|
622
720
|
// AC-R7-002: explicit parameter from the dispatcher — the runtime
|
|
623
721
|
// store.create wrapper is gone; body workspaceId (if any) only acts as
|
|
624
722
|
// a fallback for direct (non-dispatcher) handler tests.
|
|
@@ -689,6 +787,7 @@ export async function handleForkChatSession(req, res, deps, sourceSessionId) {
|
|
|
689
787
|
try {
|
|
690
788
|
const handle = await deps.runtime.forkSession({
|
|
691
789
|
sourceSessionFile: source.sessionFile ?? "",
|
|
790
|
+
sessionMode: source.sessionMode,
|
|
692
791
|
...(source.modelProvider && source.modelId
|
|
693
792
|
? { model: { provider: source.modelProvider, modelId: source.modelId } }
|
|
694
793
|
: {}),
|
|
@@ -755,10 +854,7 @@ export async function handleBranchChatSession(req, res, deps, sessionId) {
|
|
|
755
854
|
}
|
|
756
855
|
try {
|
|
757
856
|
if (!deps.runtime.hasSession(sessionId)) {
|
|
758
|
-
const reopened = await deps.runtime.reopenSession(
|
|
759
|
-
sessionId,
|
|
760
|
-
sessionFile: record.sessionFile,
|
|
761
|
-
});
|
|
857
|
+
const reopened = await deps.runtime.reopenSession(reopenInitFromRecord(record));
|
|
762
858
|
if (!reopened.ok) {
|
|
763
859
|
const mapped = await mapFailedReopen(deps, sessionId, reopened);
|
|
764
860
|
sendJson(res, mapped.status, {
|
|
@@ -1231,13 +1327,8 @@ export async function handleChatGoal(req, res, deps, sessionId) {
|
|
|
1231
1327
|
});
|
|
1232
1328
|
return;
|
|
1233
1329
|
}
|
|
1234
|
-
if (!(await deps
|
|
1235
|
-
sendJson(res, 404, {
|
|
1236
|
-
ok: false,
|
|
1237
|
-
error: { code: "NOT_FOUND", message: `chat session not found: ${sessionId}` },
|
|
1238
|
-
});
|
|
1330
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
1239
1331
|
return;
|
|
1240
|
-
}
|
|
1241
1332
|
if (req.method === "GET") {
|
|
1242
1333
|
sendJson(res, 200, { ok: true, goal: registry.get(sessionId) });
|
|
1243
1334
|
return;
|
|
@@ -1451,6 +1542,7 @@ export async function listChatSessionSummaries(deps, ownerWorkspaceId) {
|
|
|
1451
1542
|
...(session.thinkingLevel !== undefined
|
|
1452
1543
|
? { thinkingLevel: session.thinkingLevel }
|
|
1453
1544
|
: {}),
|
|
1545
|
+
sessionMode: session.sessionMode,
|
|
1454
1546
|
activeTurnId: active?.turnId,
|
|
1455
1547
|
turnPhase: active?.abortRequestedAt
|
|
1456
1548
|
? "stopping"
|
|
@@ -1474,6 +1566,16 @@ export async function handlePatchChatSession(req, res, deps, sessionId) {
|
|
|
1474
1566
|
}
|
|
1475
1567
|
try {
|
|
1476
1568
|
const body = await readJsonBody(req);
|
|
1569
|
+
if ("sessionMode" in body) {
|
|
1570
|
+
sendJson(res, 409, {
|
|
1571
|
+
ok: false,
|
|
1572
|
+
error: {
|
|
1573
|
+
code: SESSION_MODE_IMMUTABLE_CODE,
|
|
1574
|
+
message: "sessionMode cannot be changed after create",
|
|
1575
|
+
},
|
|
1576
|
+
});
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1477
1579
|
let record;
|
|
1478
1580
|
if (typeof body.title === "string")
|
|
1479
1581
|
record = await deps.store.rename(sessionId, body.title);
|
|
@@ -1532,13 +1634,7 @@ export async function handleReopenChatSession(req, res, deps, sessionId) {
|
|
|
1532
1634
|
});
|
|
1533
1635
|
return;
|
|
1534
1636
|
}
|
|
1535
|
-
const result = await deps.runtime.reopenSession(
|
|
1536
|
-
sessionId,
|
|
1537
|
-
sessionFile: record.sessionFile,
|
|
1538
|
-
...(record.modelProvider && record.modelId
|
|
1539
|
-
? { model: { provider: record.modelProvider, modelId: record.modelId } }
|
|
1540
|
-
: {}),
|
|
1541
|
-
});
|
|
1637
|
+
const result = await deps.runtime.reopenSession(reopenInitFromRecord(record));
|
|
1542
1638
|
if (!result.ok) {
|
|
1543
1639
|
const mapped = await mapFailedReopen(deps, sessionId, result);
|
|
1544
1640
|
sendJson(res, mapped.status, {
|
|
@@ -1618,13 +1714,7 @@ export async function handleChatPrompt(req, res, deps, sessionId) {
|
|
|
1618
1714
|
});
|
|
1619
1715
|
return;
|
|
1620
1716
|
}
|
|
1621
|
-
const reopen = await deps.runtime.reopenSession(
|
|
1622
|
-
sessionId,
|
|
1623
|
-
sessionFile: record.sessionFile,
|
|
1624
|
-
...(record.modelProvider && record.modelId
|
|
1625
|
-
? { model: { provider: record.modelProvider, modelId: record.modelId } }
|
|
1626
|
-
: {}),
|
|
1627
|
-
});
|
|
1717
|
+
const reopen = await deps.runtime.reopenSession(reopenInitFromRecord(record));
|
|
1628
1718
|
if (!reopen.ok) {
|
|
1629
1719
|
const mapped = await mapFailedReopen(deps, sessionId, reopen);
|
|
1630
1720
|
sendJson(res, mapped.status, {
|
|
@@ -1888,13 +1978,7 @@ export async function handleCreateChatTurn(req, res, deps, sessionId, trustedPay
|
|
|
1888
1978
|
});
|
|
1889
1979
|
return;
|
|
1890
1980
|
}
|
|
1891
|
-
const reopen = await deps.runtime.reopenSession(
|
|
1892
|
-
sessionId,
|
|
1893
|
-
sessionFile: record.sessionFile,
|
|
1894
|
-
...(record.modelProvider && record.modelId
|
|
1895
|
-
? { model: { provider: record.modelProvider, modelId: record.modelId } }
|
|
1896
|
-
: {}),
|
|
1897
|
-
});
|
|
1981
|
+
const reopen = await deps.runtime.reopenSession(reopenInitFromRecord(record));
|
|
1898
1982
|
if (!reopen.ok) {
|
|
1899
1983
|
const mapped = await mapFailedReopen(deps, sessionId, reopen);
|
|
1900
1984
|
sendJson(res, mapped.status, {
|
|
@@ -2172,6 +2256,10 @@ export async function driveGoalRound(deps, sessionId) {
|
|
|
2172
2256
|
registry.disarm(sessionId);
|
|
2173
2257
|
return "idle";
|
|
2174
2258
|
}
|
|
2259
|
+
if (!isWorkflowSessionMode(readStoredSessionMode(record.sessionMode))) {
|
|
2260
|
+
registry.disarm(sessionId);
|
|
2261
|
+
return "idle";
|
|
2262
|
+
}
|
|
2175
2263
|
const runtimeFacts = deps.runtime.getSessionBusyFacts(sessionId);
|
|
2176
2264
|
const operationStore = deps.runtime.actionContext?.operations;
|
|
2177
2265
|
const linkedOperationIds = linkedOperationIdsForGoal(deps.events.snapshot(sessionId));
|
|
@@ -2820,6 +2908,7 @@ export async function handleChatCommands(res, deps, sessionId) {
|
|
|
2820
2908
|
const warning = typeof listed.warning === "string" && listed.warning.trim()
|
|
2821
2909
|
? listed.warning.trim().slice(0, 160)
|
|
2822
2910
|
: undefined;
|
|
2911
|
+
const resolvedMode = await readChatSessionMode(deps, sessionId);
|
|
2823
2912
|
res.statusCode = 200;
|
|
2824
2913
|
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
2825
2914
|
res.end(JSON.stringify({
|
|
@@ -2827,18 +2916,25 @@ export async function handleChatCommands(res, deps, sessionId) {
|
|
|
2827
2916
|
commands,
|
|
2828
2917
|
capabilities: {
|
|
2829
2918
|
sddBingo: Boolean(await deps.sddDataAlignment?.isEligible()),
|
|
2919
|
+
...(resolvedMode.ok ? { sessionMode: resolvedMode.sessionMode } : {}),
|
|
2830
2920
|
},
|
|
2831
2921
|
...(warning ? { warning } : {}),
|
|
2832
2922
|
}));
|
|
2833
2923
|
}
|
|
2834
2924
|
catch (error) {
|
|
2835
2925
|
// Whole-list / readiness failures stay fail-soft with empty commands + warning.
|
|
2926
|
+
// Keep the two capability shapes symmetric: the fallback mode mirrors the
|
|
2927
|
+
// client-side prop fallback in useComposer.
|
|
2928
|
+
const fallbackMode = await readChatSessionMode(deps, sessionId).catch(() => undefined);
|
|
2836
2929
|
res.statusCode = 200;
|
|
2837
2930
|
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
2838
2931
|
res.end(JSON.stringify({
|
|
2839
2932
|
ok: true,
|
|
2840
2933
|
commands: [],
|
|
2841
|
-
capabilities: {
|
|
2934
|
+
capabilities: {
|
|
2935
|
+
sddBingo: false,
|
|
2936
|
+
...(fallbackMode?.ok ? { sessionMode: fallbackMode.sessionMode } : {}),
|
|
2937
|
+
},
|
|
2842
2938
|
warning: error instanceof Error ? error.message : "commands unavailable",
|
|
2843
2939
|
}));
|
|
2844
2940
|
}
|
|
@@ -3083,13 +3179,7 @@ export async function ensureActiveSession(deps, sessionId) {
|
|
|
3083
3179
|
message: `chat session not found: ${sessionId}`,
|
|
3084
3180
|
};
|
|
3085
3181
|
}
|
|
3086
|
-
const reopened = await deps.runtime.reopenSession(
|
|
3087
|
-
sessionId,
|
|
3088
|
-
sessionFile: record.sessionFile,
|
|
3089
|
-
...(record.modelProvider && record.modelId
|
|
3090
|
-
? { model: { provider: record.modelProvider, modelId: record.modelId } }
|
|
3091
|
-
: {}),
|
|
3092
|
-
});
|
|
3182
|
+
const reopened = await deps.runtime.reopenSession(reopenInitFromRecord(record));
|
|
3093
3183
|
if (!reopened.ok) {
|
|
3094
3184
|
return { ok: false, ...(await mapFailedReopen(deps, sessionId, reopened)) };
|
|
3095
3185
|
}
|
|
@@ -3418,7 +3508,7 @@ async function handleStartInterview(req, res, deps, sessionId) {
|
|
|
3418
3508
|
});
|
|
3419
3509
|
return;
|
|
3420
3510
|
}
|
|
3421
|
-
if (!(await
|
|
3511
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3422
3512
|
return;
|
|
3423
3513
|
try {
|
|
3424
3514
|
const body = await readJsonBody(req);
|
|
@@ -3460,7 +3550,7 @@ async function handleAnswerInterview(req, res, deps, sessionId, interviewSession
|
|
|
3460
3550
|
});
|
|
3461
3551
|
return;
|
|
3462
3552
|
}
|
|
3463
|
-
if (!(await
|
|
3553
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3464
3554
|
return;
|
|
3465
3555
|
try {
|
|
3466
3556
|
const body = await readJsonBody(req);
|
|
@@ -3496,7 +3586,7 @@ async function handleAnswerInterview(req, res, deps, sessionId, interviewSession
|
|
|
3496
3586
|
}
|
|
3497
3587
|
}
|
|
3498
3588
|
async function handleGetInterviewFact(res, deps, sessionId, interviewSessionId, fact) {
|
|
3499
|
-
if (!(await
|
|
3589
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3500
3590
|
return;
|
|
3501
3591
|
const state = await new ChatInterviewAdapter(deps.appData, deps.events).get(interviewSessionId);
|
|
3502
3592
|
if (!state || state.interview.operatorSessionId !== sessionId) {
|
|
@@ -3594,7 +3684,7 @@ async function handleContractApplyHumanGate(req, res, deps, sessionId, step) {
|
|
|
3594
3684
|
});
|
|
3595
3685
|
return;
|
|
3596
3686
|
}
|
|
3597
|
-
if (!(await
|
|
3687
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3598
3688
|
return;
|
|
3599
3689
|
const ctx = deps.runtime.actionContext;
|
|
3600
3690
|
if (!ctx) {
|
|
@@ -3776,7 +3866,7 @@ async function handleDagHumanGate(req, res, deps, sessionId, step) {
|
|
|
3776
3866
|
});
|
|
3777
3867
|
return;
|
|
3778
3868
|
}
|
|
3779
|
-
if (!(await
|
|
3869
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3780
3870
|
return;
|
|
3781
3871
|
const ctx = deps.runtime.actionContext;
|
|
3782
3872
|
if (!ctx) {
|
|
@@ -3885,7 +3975,7 @@ async function handleMutationHumanGate(req, res, deps, sessionId) {
|
|
|
3885
3975
|
});
|
|
3886
3976
|
return;
|
|
3887
3977
|
}
|
|
3888
|
-
if (!(await
|
|
3978
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3889
3979
|
return;
|
|
3890
3980
|
const ctx = deps.runtime.actionContext;
|
|
3891
3981
|
if (!ctx) {
|
|
@@ -3974,7 +4064,7 @@ async function handleConfirmTaskKind(req, res, deps, sessionId, interviewSession
|
|
|
3974
4064
|
});
|
|
3975
4065
|
return;
|
|
3976
4066
|
}
|
|
3977
|
-
if (!(await
|
|
4067
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3978
4068
|
return;
|
|
3979
4069
|
try {
|
|
3980
4070
|
const body = await readJsonBody(req);
|
|
@@ -4030,13 +4120,7 @@ export async function handleChatCompact(req, res, deps, sessionId) {
|
|
|
4030
4120
|
return;
|
|
4031
4121
|
}
|
|
4032
4122
|
if (!deps.runtime.hasSession(sessionId)) {
|
|
4033
|
-
const reopened = await deps.runtime.reopenSession(
|
|
4034
|
-
sessionId,
|
|
4035
|
-
sessionFile: record.sessionFile,
|
|
4036
|
-
...(record.modelProvider && record.modelId
|
|
4037
|
-
? { model: { provider: record.modelProvider, modelId: record.modelId } }
|
|
4038
|
-
: {}),
|
|
4039
|
-
});
|
|
4123
|
+
const reopened = await deps.runtime.reopenSession(reopenInitFromRecord(record));
|
|
4040
4124
|
if (!reopened.ok) {
|
|
4041
4125
|
const mapped = await mapFailedReopen(deps, sessionId, reopened);
|
|
4042
4126
|
sendJson(res, mapped.status, {
|
|
@@ -4060,7 +4144,9 @@ export async function handleChatCompact(req, res, deps, sessionId) {
|
|
|
4060
4144
|
const rawInstructions = typeof body.instructions === "string" ? body.instructions : undefined;
|
|
4061
4145
|
const currentTodos = projectCurrentTodos(deps.events.snapshot(sessionId));
|
|
4062
4146
|
const todoInstructions = buildTodoCompactionInstructions(rawInstructions, currentTodos);
|
|
4063
|
-
const customInstructions =
|
|
4147
|
+
const customInstructions = isWorkflowSessionMode(record.sessionMode)
|
|
4148
|
+
? buildGoalCompactionInstructions(todoInstructions, deps.goalRegistry?.get(sessionId) ?? null)
|
|
4149
|
+
: todoInstructions;
|
|
4064
4150
|
const turnId = deps.events.latestTurnId(sessionId) ?? `${sessionId}:compact`;
|
|
4065
4151
|
const compactionId = `${sessionId}:compaction:${randomUUID()}`;
|
|
4066
4152
|
deps.events.append(sessionId, turnId, {
|
|
@@ -4075,27 +4161,42 @@ export async function handleChatCompact(req, res, deps, sessionId) {
|
|
|
4075
4161
|
});
|
|
4076
4162
|
try {
|
|
4077
4163
|
const snapshot = await deps.runtime.compact(sessionId, customInstructions);
|
|
4164
|
+
const completedAt = new Date().toISOString();
|
|
4165
|
+
const completedData = {
|
|
4166
|
+
schemaVersion: 1,
|
|
4167
|
+
compactionId,
|
|
4168
|
+
reason: "manual",
|
|
4169
|
+
status: "completed",
|
|
4170
|
+
summary: snapshot.summary,
|
|
4171
|
+
...(snapshot.firstKeptEntryId
|
|
4172
|
+
? { firstKeptEntryId: snapshot.firstKeptEntryId }
|
|
4173
|
+
: {}),
|
|
4174
|
+
...(snapshot.tokensBefore === undefined
|
|
4175
|
+
? {}
|
|
4176
|
+
: { tokensBefore: snapshot.tokensBefore }),
|
|
4177
|
+
...(snapshot.estimatedTokensAfter === undefined
|
|
4178
|
+
? {}
|
|
4179
|
+
: { estimatedTokensAfter: snapshot.estimatedTokensAfter }),
|
|
4180
|
+
willRetry: false,
|
|
4181
|
+
};
|
|
4078
4182
|
const event = deps.events.append(sessionId, turnId, {
|
|
4079
4183
|
kind: "compaction_end",
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
: { estimatedTokensAfter: snapshot.estimatedTokensAfter }),
|
|
4095
|
-
willRetry: false,
|
|
4184
|
+
at: completedAt,
|
|
4185
|
+
data: completedData,
|
|
4186
|
+
});
|
|
4187
|
+
sendJson(res, 200, {
|
|
4188
|
+
ok: true,
|
|
4189
|
+
snapshot,
|
|
4190
|
+
eventId: event.eventId,
|
|
4191
|
+
compaction: {
|
|
4192
|
+
eventId: event.eventId,
|
|
4193
|
+
kind: "compaction_end",
|
|
4194
|
+
at: completedAt,
|
|
4195
|
+
seq: event.seq,
|
|
4196
|
+
turnId,
|
|
4197
|
+
data: completedData,
|
|
4096
4198
|
},
|
|
4097
4199
|
});
|
|
4098
|
-
sendJson(res, 200, { ok: true, snapshot, eventId: event.eventId });
|
|
4099
4200
|
}
|
|
4100
4201
|
catch (error) {
|
|
4101
4202
|
const classified = classifyChatCompactionFailure(error);
|
|
@@ -4146,6 +4247,46 @@ export async function handleChatMessages(res, deps, sessionId, url) {
|
|
|
4146
4247
|
export async function handleChatRequest(req, res, deps, pathname, workspaceScope) {
|
|
4147
4248
|
if (!deps)
|
|
4148
4249
|
return false;
|
|
4250
|
+
try {
|
|
4251
|
+
return await dispatchChatRequest(req, res, deps, pathname, workspaceScope);
|
|
4252
|
+
}
|
|
4253
|
+
catch (error) {
|
|
4254
|
+
// Store-level fail-closed for corrupt sessionMode: bounded 409 instead of
|
|
4255
|
+
// a generic 500, for any handler that reads the record without its own
|
|
4256
|
+
// UnknownChatSessionModeError mapping (readChatSessionMode covers the rest).
|
|
4257
|
+
if (error instanceof UnknownChatSessionModeError) {
|
|
4258
|
+
sendJson(res, 409, {
|
|
4259
|
+
ok: false,
|
|
4260
|
+
error: { code: error.code, message: error.message },
|
|
4261
|
+
});
|
|
4262
|
+
return true;
|
|
4263
|
+
}
|
|
4264
|
+
throw error;
|
|
4265
|
+
}
|
|
4266
|
+
}
|
|
4267
|
+
async function dispatchChatRequest(req, res, deps, pathname, workspaceScope) {
|
|
4268
|
+
// Terminal management API (model + Console UI shared PTY registry).
|
|
4269
|
+
if (await handleTerminalRequest(req, res, {
|
|
4270
|
+
terminals: deps.terminals ?? new TerminalSessionRegistry(),
|
|
4271
|
+
gateMutation: (r) => gateMutation(r, deps),
|
|
4272
|
+
// Terminals open in the workspace repo root, not the Console process cwd.
|
|
4273
|
+
defaultCwd: deps.appData.repoRoot,
|
|
4274
|
+
}, pathname)) {
|
|
4275
|
+
return true;
|
|
4276
|
+
}
|
|
4277
|
+
// Source control API (model + Console UI shared workspace ScmService).
|
|
4278
|
+
if (deps.scm) {
|
|
4279
|
+
if (await handleScmRequest(req, res, {
|
|
4280
|
+
scm: deps.scm,
|
|
4281
|
+
gateMutation: (r) => gateMutation(r, deps),
|
|
4282
|
+
}, pathname)) {
|
|
4283
|
+
return true;
|
|
4284
|
+
}
|
|
4285
|
+
}
|
|
4286
|
+
// Browser probe API (read-only; explains iframe refusals to the panel).
|
|
4287
|
+
if (await handleBrowserRequest(req, res, {}, pathname)) {
|
|
4288
|
+
return true;
|
|
4289
|
+
}
|
|
4149
4290
|
if (!pathname.startsWith("/api/operator/v1/chat/") &&
|
|
4150
4291
|
!pathname.startsWith("/api/operator/v1/pi/"))
|
|
4151
4292
|
return false;
|