@tea-agent/loop-agent 0.43.0-next.1 → 0.43.0-next.11
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 +144 -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 +1237 -586
- package/dist/executors/pi-executor.js +22 -1
- package/dist/executors/pi-sdk-executor.js +140 -39
- package/dist/executors/shell-executor.js +8 -4
- 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 +113 -0
- package/dist/worker/console/chat/browser-routes.js +140 -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 +79 -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 +207 -1178
- package/dist/worker/console/chat/routes.js +208 -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 +49 -0
- package/dist/worker/console/chat/session-mode.js +219 -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-CTSK0xbU.js} +1 -1
- package/dist/worker/console/static/assets/{arc-DCPjC19G.js → arc-_2MfctFP.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CP5n9jmG.js → architectureDiagram-T3A2C74G-DsDe2wTg.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CmaWi_Wg.js → blockDiagram-VBNYF7ZC-Dtz_779U.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-Ct5tcMfZ.js → c4Diagram-5PPSVZJV-LaULi-gw.js} +1 -1
- package/dist/worker/console/static/assets/channel-CqS4yBWT.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-C0osm1Zf.js → chunk-2GRJ4B5K-DuHBqqX8.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CDWviED7.js → chunk-2Q5K7J3B-BZgZs1dn.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-mtSk1-j7.js → chunk-5RXB4S5H-tzwmlIO_.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-D5J9PHC7.js → chunk-5VM5RSS4-CeYrLkSn.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Begg4WAa.js → chunk-6Q2QTUOP-C92cgilm.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-sF1AEy7T.js → chunk-GF5L2VYU-XOXpGC0F.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BqbsWXZb.js → chunk-JWPE2WC7-CGHbJyCH.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BKJrPcJ6.js → chunk-KBJHAD2P-Bs2-LTzf.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CcwNMRho.js → chunk-RYQCIY6F-rN7up7E4.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-BEJi3iIs.js → chunk-XXDRQBXY-B_fWjKpR.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DVOxNOq0.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DVOxNOq0.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-DRLgTvVu.js → cose-bilkent-JH36ORCC-DE3SdJvB.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BoAVG3cs.js → cynefin-VYW2F7L2-B-4yuRAX.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-Bzol06hR.js → cynefinDiagram-MW4NZA55-TiCPFuO8.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-UmliJM77.js → dagre-VZM6K2ZE-7crzLMzA.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-BWLcJkFo.js → diagram-7IWD3JNH-Cvr-x6Fd.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-CgApOm-O.js → diagram-B4RE2ZJO-BzcRHUjH.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-Bh3RgTLs.js → diagram-LBJQPF4R-BjkAXilh.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-Dsh-D5nE.js → diagram-Q27KOJAE-BkzyATK7.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-Dkbbpcpb.js → diagram-UB23O5K3-rZuTarYP.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-3EBaA3t3.js → ebnfDiagram-BXEA7PRR-CAYENaN1.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Bq2Dc5ok.js → erDiagram-JOGREHBK-DCEam0Uq.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-De7y55ha.js → flowDiagram-UKHOOZJN-e_dH4wVO.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-fLiDbQRh.js → ganttDiagram-PKOTCBZU-CvZa2zOK.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Du617mp1.js → gitGraphDiagram-DS77QQ5N-CbT5TuKp.js} +1 -1
- package/dist/worker/console/static/assets/index-CUPeoE8W.js +468 -0
- package/dist/worker/console/static/assets/index-SAANIK8g.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-BwmlF-XP.js → infoDiagram-6WML65LV-BWzHQa_Z.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-zsGtS59u.js → ishikawaDiagram-WSZJBQD7-BTjlovtU.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DTTPTe3f.js → journeyDiagram-NVQOT4AX-DkvQoCc1.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-BkXg9aP-.js → kanban-definition-27J2QSJJ-CHSzGi3W.js} +1 -1
- package/dist/worker/console/static/assets/{linear-7U2ue5IE.js → linear-DZMkTCWH.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-BUuGHmWO.js → mermaid.core-BIMhty7A.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-7q6fX0Sv.js → mindmap-definition-FAOFIHXS-Dx-tyMl3.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-CkQPJN55.js → pegDiagram-VL7TDLO6-C6G34rbY.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-CCal_tfX.js → pieDiagram-7S7Q4E2Y-CHK9XOfm.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-B7bpxyAZ.js → quadrantDiagram-CIZ2JOQS-CDARkI0w.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CJmww7D-.js → railroadDiagram-AXF67PYL-DiuUe0ZQ.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-D6ldWJEv.js → requirementDiagram-LRYGKXZP-RE61UR56.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-VGh33I9e.js → sankeyDiagram-W5VNT64P-KDNLHMEG.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CCkDrIjU.js → sequenceDiagram-SI44F4Z6-CeVgXnD9.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-NC8f5Otb.js → sizeCapture-X5ZJPWSS-CXwGyjjG.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-_92ezZdF.js → stateDiagram-OKZ733FA-BjTfozab.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BXoYsyr2.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BdUCGtbP.js → swimlanes-SLNWSIFB-BaXOB8GT.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DfKliS4e.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CdD1H8ia.js → timeline-definition-Z64GVDOM-C3r2hqUU.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-Dkdk3oFo.js → vennDiagram-T6HMQDX7-MWKgl1S9.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CKu2uPPY.js → wardleyDiagram-T6FBY63Y-C9iFcZPk.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-ClqAnuG8.js → xychartDiagram-ELKLHX3M-DqnM24Jp.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-closeout.js +1 -1
- 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-prewrite-gate.js +3 -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-context.js +2 -1
- 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/frontend-verification-trace.js +1 -1
- package/dist/workflows/dag/init-hybrid.js +65 -167
- 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 +14 -13
- package/package.json +6 -3
- package/skills/frontend-bounded-implement/SKILL.md +3 -3
- package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
- package/skills/frontend-contract/SKILL.md +2 -1
- package/skills/frontend-contract/references/contract-protocol.md +22 -4
- package/skills/frontend-design-review/SKILL.md +22 -16
- package/skills/frontend-design-review/references/review-checklist.md +7 -7
- package/skills/frontend-plan/SKILL.md +21 -2
- package/skills/frontend-plan/references/decision-contract.md +42 -23
- package/skills/frontend-review/SKILL.md +22 -29
- package/skills/frontend-review/references/review-findings.md +24 -43
- 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 requireChatSession(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, {
|
|
@@ -2820,6 +2904,7 @@ export async function handleChatCommands(res, deps, sessionId) {
|
|
|
2820
2904
|
const warning = typeof listed.warning === "string" && listed.warning.trim()
|
|
2821
2905
|
? listed.warning.trim().slice(0, 160)
|
|
2822
2906
|
: undefined;
|
|
2907
|
+
const resolvedMode = await readChatSessionMode(deps, sessionId);
|
|
2823
2908
|
res.statusCode = 200;
|
|
2824
2909
|
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
2825
2910
|
res.end(JSON.stringify({
|
|
@@ -2827,18 +2912,25 @@ export async function handleChatCommands(res, deps, sessionId) {
|
|
|
2827
2912
|
commands,
|
|
2828
2913
|
capabilities: {
|
|
2829
2914
|
sddBingo: Boolean(await deps.sddDataAlignment?.isEligible()),
|
|
2915
|
+
...(resolvedMode.ok ? { sessionMode: resolvedMode.sessionMode } : {}),
|
|
2830
2916
|
},
|
|
2831
2917
|
...(warning ? { warning } : {}),
|
|
2832
2918
|
}));
|
|
2833
2919
|
}
|
|
2834
2920
|
catch (error) {
|
|
2835
2921
|
// Whole-list / readiness failures stay fail-soft with empty commands + warning.
|
|
2922
|
+
// Keep the two capability shapes symmetric: the fallback mode mirrors the
|
|
2923
|
+
// client-side prop fallback in useComposer.
|
|
2924
|
+
const fallbackMode = await readChatSessionMode(deps, sessionId).catch(() => undefined);
|
|
2836
2925
|
res.statusCode = 200;
|
|
2837
2926
|
res.setHeader("content-type", "application/json; charset=utf-8");
|
|
2838
2927
|
res.end(JSON.stringify({
|
|
2839
2928
|
ok: true,
|
|
2840
2929
|
commands: [],
|
|
2841
|
-
capabilities: {
|
|
2930
|
+
capabilities: {
|
|
2931
|
+
sddBingo: false,
|
|
2932
|
+
...(fallbackMode?.ok ? { sessionMode: fallbackMode.sessionMode } : {}),
|
|
2933
|
+
},
|
|
2842
2934
|
warning: error instanceof Error ? error.message : "commands unavailable",
|
|
2843
2935
|
}));
|
|
2844
2936
|
}
|
|
@@ -3083,13 +3175,7 @@ export async function ensureActiveSession(deps, sessionId) {
|
|
|
3083
3175
|
message: `chat session not found: ${sessionId}`,
|
|
3084
3176
|
};
|
|
3085
3177
|
}
|
|
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
|
-
});
|
|
3178
|
+
const reopened = await deps.runtime.reopenSession(reopenInitFromRecord(record));
|
|
3093
3179
|
if (!reopened.ok) {
|
|
3094
3180
|
return { ok: false, ...(await mapFailedReopen(deps, sessionId, reopened)) };
|
|
3095
3181
|
}
|
|
@@ -3418,7 +3504,7 @@ async function handleStartInterview(req, res, deps, sessionId) {
|
|
|
3418
3504
|
});
|
|
3419
3505
|
return;
|
|
3420
3506
|
}
|
|
3421
|
-
if (!(await
|
|
3507
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3422
3508
|
return;
|
|
3423
3509
|
try {
|
|
3424
3510
|
const body = await readJsonBody(req);
|
|
@@ -3460,7 +3546,7 @@ async function handleAnswerInterview(req, res, deps, sessionId, interviewSession
|
|
|
3460
3546
|
});
|
|
3461
3547
|
return;
|
|
3462
3548
|
}
|
|
3463
|
-
if (!(await
|
|
3549
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3464
3550
|
return;
|
|
3465
3551
|
try {
|
|
3466
3552
|
const body = await readJsonBody(req);
|
|
@@ -3496,7 +3582,7 @@ async function handleAnswerInterview(req, res, deps, sessionId, interviewSession
|
|
|
3496
3582
|
}
|
|
3497
3583
|
}
|
|
3498
3584
|
async function handleGetInterviewFact(res, deps, sessionId, interviewSessionId, fact) {
|
|
3499
|
-
if (!(await
|
|
3585
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3500
3586
|
return;
|
|
3501
3587
|
const state = await new ChatInterviewAdapter(deps.appData, deps.events).get(interviewSessionId);
|
|
3502
3588
|
if (!state || state.interview.operatorSessionId !== sessionId) {
|
|
@@ -3594,7 +3680,7 @@ async function handleContractApplyHumanGate(req, res, deps, sessionId, step) {
|
|
|
3594
3680
|
});
|
|
3595
3681
|
return;
|
|
3596
3682
|
}
|
|
3597
|
-
if (!(await
|
|
3683
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3598
3684
|
return;
|
|
3599
3685
|
const ctx = deps.runtime.actionContext;
|
|
3600
3686
|
if (!ctx) {
|
|
@@ -3776,7 +3862,7 @@ async function handleDagHumanGate(req, res, deps, sessionId, step) {
|
|
|
3776
3862
|
});
|
|
3777
3863
|
return;
|
|
3778
3864
|
}
|
|
3779
|
-
if (!(await
|
|
3865
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3780
3866
|
return;
|
|
3781
3867
|
const ctx = deps.runtime.actionContext;
|
|
3782
3868
|
if (!ctx) {
|
|
@@ -3885,7 +3971,7 @@ async function handleMutationHumanGate(req, res, deps, sessionId) {
|
|
|
3885
3971
|
});
|
|
3886
3972
|
return;
|
|
3887
3973
|
}
|
|
3888
|
-
if (!(await
|
|
3974
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3889
3975
|
return;
|
|
3890
3976
|
const ctx = deps.runtime.actionContext;
|
|
3891
3977
|
if (!ctx) {
|
|
@@ -3974,7 +4060,7 @@ async function handleConfirmTaskKind(req, res, deps, sessionId, interviewSession
|
|
|
3974
4060
|
});
|
|
3975
4061
|
return;
|
|
3976
4062
|
}
|
|
3977
|
-
if (!(await
|
|
4063
|
+
if (!(await requireWorkflowSession(res, deps, sessionId)))
|
|
3978
4064
|
return;
|
|
3979
4065
|
try {
|
|
3980
4066
|
const body = await readJsonBody(req);
|
|
@@ -4030,13 +4116,7 @@ export async function handleChatCompact(req, res, deps, sessionId) {
|
|
|
4030
4116
|
return;
|
|
4031
4117
|
}
|
|
4032
4118
|
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
|
-
});
|
|
4119
|
+
const reopened = await deps.runtime.reopenSession(reopenInitFromRecord(record));
|
|
4040
4120
|
if (!reopened.ok) {
|
|
4041
4121
|
const mapped = await mapFailedReopen(deps, sessionId, reopened);
|
|
4042
4122
|
sendJson(res, mapped.status, {
|
|
@@ -4060,7 +4140,9 @@ export async function handleChatCompact(req, res, deps, sessionId) {
|
|
|
4060
4140
|
const rawInstructions = typeof body.instructions === "string" ? body.instructions : undefined;
|
|
4061
4141
|
const currentTodos = projectCurrentTodos(deps.events.snapshot(sessionId));
|
|
4062
4142
|
const todoInstructions = buildTodoCompactionInstructions(rawInstructions, currentTodos);
|
|
4063
|
-
const customInstructions =
|
|
4143
|
+
const customInstructions = isWorkflowSessionMode(record.sessionMode)
|
|
4144
|
+
? buildGoalCompactionInstructions(todoInstructions, deps.goalRegistry?.get(sessionId) ?? null)
|
|
4145
|
+
: todoInstructions;
|
|
4064
4146
|
const turnId = deps.events.latestTurnId(sessionId) ?? `${sessionId}:compact`;
|
|
4065
4147
|
const compactionId = `${sessionId}:compaction:${randomUUID()}`;
|
|
4066
4148
|
deps.events.append(sessionId, turnId, {
|
|
@@ -4075,27 +4157,42 @@ export async function handleChatCompact(req, res, deps, sessionId) {
|
|
|
4075
4157
|
});
|
|
4076
4158
|
try {
|
|
4077
4159
|
const snapshot = await deps.runtime.compact(sessionId, customInstructions);
|
|
4160
|
+
const completedAt = new Date().toISOString();
|
|
4161
|
+
const completedData = {
|
|
4162
|
+
schemaVersion: 1,
|
|
4163
|
+
compactionId,
|
|
4164
|
+
reason: "manual",
|
|
4165
|
+
status: "completed",
|
|
4166
|
+
summary: snapshot.summary,
|
|
4167
|
+
...(snapshot.firstKeptEntryId
|
|
4168
|
+
? { firstKeptEntryId: snapshot.firstKeptEntryId }
|
|
4169
|
+
: {}),
|
|
4170
|
+
...(snapshot.tokensBefore === undefined
|
|
4171
|
+
? {}
|
|
4172
|
+
: { tokensBefore: snapshot.tokensBefore }),
|
|
4173
|
+
...(snapshot.estimatedTokensAfter === undefined
|
|
4174
|
+
? {}
|
|
4175
|
+
: { estimatedTokensAfter: snapshot.estimatedTokensAfter }),
|
|
4176
|
+
willRetry: false,
|
|
4177
|
+
};
|
|
4078
4178
|
const event = deps.events.append(sessionId, turnId, {
|
|
4079
4179
|
kind: "compaction_end",
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
: { estimatedTokensAfter: snapshot.estimatedTokensAfter }),
|
|
4095
|
-
willRetry: false,
|
|
4180
|
+
at: completedAt,
|
|
4181
|
+
data: completedData,
|
|
4182
|
+
});
|
|
4183
|
+
sendJson(res, 200, {
|
|
4184
|
+
ok: true,
|
|
4185
|
+
snapshot,
|
|
4186
|
+
eventId: event.eventId,
|
|
4187
|
+
compaction: {
|
|
4188
|
+
eventId: event.eventId,
|
|
4189
|
+
kind: "compaction_end",
|
|
4190
|
+
at: completedAt,
|
|
4191
|
+
seq: event.seq,
|
|
4192
|
+
turnId,
|
|
4193
|
+
data: completedData,
|
|
4096
4194
|
},
|
|
4097
4195
|
});
|
|
4098
|
-
sendJson(res, 200, { ok: true, snapshot, eventId: event.eventId });
|
|
4099
4196
|
}
|
|
4100
4197
|
catch (error) {
|
|
4101
4198
|
const classified = classifyChatCompactionFailure(error);
|
|
@@ -4146,6 +4243,46 @@ export async function handleChatMessages(res, deps, sessionId, url) {
|
|
|
4146
4243
|
export async function handleChatRequest(req, res, deps, pathname, workspaceScope) {
|
|
4147
4244
|
if (!deps)
|
|
4148
4245
|
return false;
|
|
4246
|
+
try {
|
|
4247
|
+
return await dispatchChatRequest(req, res, deps, pathname, workspaceScope);
|
|
4248
|
+
}
|
|
4249
|
+
catch (error) {
|
|
4250
|
+
// Store-level fail-closed for corrupt sessionMode: bounded 409 instead of
|
|
4251
|
+
// a generic 500, for any handler that reads the record without its own
|
|
4252
|
+
// UnknownChatSessionModeError mapping (readChatSessionMode covers the rest).
|
|
4253
|
+
if (error instanceof UnknownChatSessionModeError) {
|
|
4254
|
+
sendJson(res, 409, {
|
|
4255
|
+
ok: false,
|
|
4256
|
+
error: { code: error.code, message: error.message },
|
|
4257
|
+
});
|
|
4258
|
+
return true;
|
|
4259
|
+
}
|
|
4260
|
+
throw error;
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
async function dispatchChatRequest(req, res, deps, pathname, workspaceScope) {
|
|
4264
|
+
// Terminal management API (model + Console UI shared PTY registry).
|
|
4265
|
+
if (await handleTerminalRequest(req, res, {
|
|
4266
|
+
terminals: deps.terminals ?? new TerminalSessionRegistry(),
|
|
4267
|
+
gateMutation: (r) => gateMutation(r, deps),
|
|
4268
|
+
// Terminals open in the workspace repo root, not the Console process cwd.
|
|
4269
|
+
defaultCwd: deps.appData.repoRoot,
|
|
4270
|
+
}, pathname)) {
|
|
4271
|
+
return true;
|
|
4272
|
+
}
|
|
4273
|
+
// Source control API (model + Console UI shared workspace ScmService).
|
|
4274
|
+
if (deps.scm) {
|
|
4275
|
+
if (await handleScmRequest(req, res, {
|
|
4276
|
+
scm: deps.scm,
|
|
4277
|
+
gateMutation: (r) => gateMutation(r, deps),
|
|
4278
|
+
}, pathname)) {
|
|
4279
|
+
return true;
|
|
4280
|
+
}
|
|
4281
|
+
}
|
|
4282
|
+
// Browser probe API (read-only; explains iframe refusals to the panel).
|
|
4283
|
+
if (await handleBrowserRequest(req, res, {}, pathname)) {
|
|
4284
|
+
return true;
|
|
4285
|
+
}
|
|
4149
4286
|
if (!pathname.startsWith("/api/operator/v1/chat/") &&
|
|
4150
4287
|
!pathname.startsWith("/api/operator/v1/pi/"))
|
|
4151
4288
|
return false;
|