@tea-agent/loop-agent 0.44.0-next.1 → 0.44.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 +379 -416
- package/dist/application/evaluation/budget.js +21 -0
- package/dist/application/evaluation/corpus-hash.js +10 -15
- package/dist/application/evaluation/corpus.js +2 -1
- package/dist/application/evaluation/frontend-browser-acceptance.js +77 -0
- package/dist/application/evaluation/frontend-corpus-browser-acceptance.js +175 -0
- package/dist/application/evaluation/frontend-gateway-evidence.js +226 -0
- package/dist/application/evaluation/frontend-pair-registration.js +143 -0
- package/dist/application/evaluation/frontend-paired-summary.js +150 -0
- package/dist/application/evaluation/frontend-run-observation.js +144 -0
- package/dist/application/evaluation/frontend-shared-evidence.js +105 -0
- package/dist/application/evaluation/types.js +45 -12
- package/dist/application/task-lifecycle/observe.js +26 -1
- package/dist/build-stamp.json +3 -3
- package/dist/cli/command-definitions.js +11 -0
- package/dist/cli/program.js +4 -0
- package/dist/commands/task-advance.js +3 -5
- package/dist/commands/task-source-prepare.js +13 -1
- package/dist/executors/dag-pi/guards.js +4 -0
- package/dist/executors/dag-pi/model-config.js +30 -0
- package/dist/executors/dag-pi/plan/fact-adoption.js +55 -0
- package/dist/{workflows/dag/frontend-plan-completeness.js → executors/dag-pi/plan/facts.js} +22 -28
- package/dist/executors/dag-pi/plan/finalize-tools.js +259 -0
- package/dist/executors/dag-pi/plan/ledger-contract.js +55 -0
- package/dist/executors/dag-pi/plan/record-tools.js +861 -0
- package/dist/executors/dag-pi/plan/schema.js +129 -0
- package/dist/executors/dag-pi/plan/session.js +1 -0
- package/dist/executors/dag-pi/plan/tool-helpers.js +16 -0
- package/dist/executors/dag-pi/tools/contract-tools.js +515 -0
- package/dist/executors/dag-pi/tools/design-terminal-tools.js +159 -0
- package/dist/executors/dag-pi/tools/plan-decision-tools.js +529 -0
- package/dist/executors/dag-pi/tools/review-terminal-tools.js +159 -0
- package/dist/executors/dag-pi/tools/scout-evidence-tools.js +270 -0
- package/dist/executors/dag-pi-executor.js +398 -3384
- package/dist/executors/pi-executor.js +6 -1
- package/dist/executors/pi-sdk-executor.js +112 -19
- package/dist/executors/shell-executor.js +88 -12
- package/dist/executors/shell-presets.js +1 -1
- package/dist/executors/shell-write-guard.js +26 -3
- package/dist/infrastructure/console/operation-store.js +48 -14
- package/dist/infrastructure/evaluation/corpus-store.js +37 -12
- package/dist/shared/file-identity.js +23 -0
- package/dist/shared/git-workspace-status.js +482 -0
- package/dist/shared/operator/capabilities.js +10 -5
- package/dist/shared/path-safety.js +2 -2
- package/dist/shared/wizard-local-telemetry.js +51 -0
- package/dist/task/config-types.js +22 -8
- package/dist/task/contract/project.js +13 -0
- package/dist/task/contract/schema.js +2 -7
- package/dist/task/frontend-preflight.js +1 -1
- package/dist/task/source-prepare/parse-intent.js +124 -5
- package/dist/task/source-prepare/prepare.js +6 -1
- package/dist/task/source-prepare/semantic-intake.js +18 -3
- package/dist/task/source-prepare/source-execution.js +65 -0
- package/dist/task/source-prepare/source-fidelity-pi.js +22 -9
- package/dist/task/source-prepare/source-provider-budget.js +290 -0
- package/dist/worker/console/chat/assistant-content.js +5 -34
- package/dist/worker/console/chat/chat-event-store.js +62 -10
- package/dist/worker/console/chat/context-insights.js +723 -0
- package/dist/worker/console/chat/conversation-nodes.js +383 -0
- package/dist/worker/console/chat/db-connections.js +854 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +1 -1
- package/dist/worker/console/chat/pi-runtime/custom-tools/sql-tools.js +655 -0
- package/dist/worker/console/chat/pi-runtime.js +445 -36
- package/dist/worker/console/chat/provider-error.js +0 -12
- package/dist/worker/console/chat/repo-browser.js +52 -4
- package/dist/worker/console/chat/routes.js +577 -72
- package/dist/worker/console/chat/sdd-data-alignment.js +8 -31
- package/dist/worker/console/chat/session-store.js +147 -19
- package/dist/worker/console/chat/shortcuts.js +7 -0
- package/dist/worker/console/chat/timeline-message-order.js +22 -0
- package/dist/worker/console/chat/tools.js +34 -0
- package/dist/worker/console/chat/turn-process.js +237 -66
- package/dist/worker/console/chat/user-turn-outline.js +19 -0
- package/dist/worker/console/console-update-runtime.js +2 -2
- package/dist/worker/console/dag-confirmation.js +3 -0
- package/dist/worker/console/dag-execution-receipt.js +3 -0
- package/dist/worker/console/operator-actions.js +32 -3
- package/dist/worker/console/operator-user-error.js +28 -1
- package/dist/worker/console/pi-readiness.js +4 -4
- package/dist/worker/console/prd-intake-bridge.js +5 -12
- package/dist/worker/console/recovery-cta.js +14 -14
- package/dist/worker/console/server.js +5 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-8-j6y-sd.js → abnfDiagram-N423BO3Z-r1NAPU_5.js} +1 -1
- package/dist/worker/console/static/assets/{arc-eoQiMvuk.js → arc-dT5T4sVL.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-C4A3uMcI.js → architectureDiagram-T3A2C74G-CP_cOq46.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-D4zD2F-Q.js → blockDiagram-VBNYF7ZC-sToEZxEf.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-j1RkJziL.js → c4Diagram-5PPSVZJV-DSxwwi2m.js} +1 -1
- package/dist/worker/console/static/assets/channel-CyBY_yGk.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-YBHmhik1.js → chunk-2GRJ4B5K-B9fh0IkF.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-COfWyo9P.js → chunk-2Q5K7J3B-CAUNl-A6.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-I99OUkHY.js → chunk-5RXB4S5H-BomeqbNX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-XKxoJNJ4.js → chunk-5VM5RSS4-BNAuTOLE.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DLT_cYx1.js → chunk-6Q2QTUOP-DfzjRD5y.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CxcKZ9mV.js → chunk-GF5L2VYU-C3uE-yc2.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-V1EqXdjY.js → chunk-JWPE2WC7-C3sQMMYr.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DebTtdFp.js → chunk-KBJHAD2P-D_AtEYQL.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-B-ivNRDf.js → chunk-RYQCIY6F-DW4TwhKv.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-DC_Ds11b.js → chunk-XXDRQBXY-CTQDmJcp.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-D5lN4E_E.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-D5lN4E_E.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-sWEqKwIb.js → cose-bilkent-JH36ORCC-iMqPuBsL.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BXa_dcu4.js → cynefin-VYW2F7L2-DktIuDWs.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-C-Mle84F.js → cynefinDiagram-MW4NZA55-BgVnjyEs.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-CXPDBITe.js → dagre-VZM6K2ZE-CR25E4bu.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CC-WJQfa.js → diagram-7IWD3JNH-CPM2h5HY.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-CDAV5Vs4.js → diagram-B4RE2ZJO-DqF0x2g1.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-CmFiAcNz.js → diagram-LBJQPF4R-G8BYp2eb.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-DPBZHuyn.js → diagram-Q27KOJAE-BbC4kT_D.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-jUlm_Ds3.js → diagram-UB23O5K3-CKZwZ-G5.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-DWhQ3mfY.js → ebnfDiagram-BXEA7PRR-kJDmheia.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Tr2gMqet.js → erDiagram-JOGREHBK-DFTVHyxB.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-DJjVQHPA.js → flowDiagram-UKHOOZJN-BqdN5_os.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-D74dQ4u0.js → ganttDiagram-PKOTCBZU-SYDjVakh.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-DwW0tZ0X.js → gitGraphDiagram-DS77QQ5N-Bf8bNpGA.js} +1 -1
- package/dist/worker/console/static/assets/index-B28Onmfy.css +1 -0
- package/dist/worker/console/static/assets/index-CTMZsDmh.js +486 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-ILCbxJyb.js → infoDiagram-6WML65LV-DIeAmJ45.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-DeuWBQ89.js → ishikawaDiagram-WSZJBQD7-oikqUAlo.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-CF5ih8Fk.js → journeyDiagram-NVQOT4AX-mKEF_xYT.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-C7yOSuRO.js → kanban-definition-27J2QSJJ-BdWJHPnN.js} +1 -1
- package/dist/worker/console/static/assets/{linear-BDZ9riWi.js → linear-DGRlieMH.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-7pKqYtpZ.js → mermaid.core-4P9yPC9c.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-LeJDybSU.js → mindmap-definition-FAOFIHXS-5PTSkos6.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-BJvT3pMD.js → pegDiagram-VL7TDLO6-DONIFpG5.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-_rGqpMan.js → pieDiagram-7S7Q4E2Y-D_Z4S70M.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-DPcSv5aA.js → quadrantDiagram-CIZ2JOQS-CAsjh8iY.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-Drxx4hkJ.js → railroadDiagram-AXF67PYL-Cx4Dd6ac.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BCTUdU4z.js → requirementDiagram-LRYGKXZP-cQb7mwyH.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-B6wzbZmB.js → sankeyDiagram-W5VNT64P-Cd-DhUdf.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BGt8d3QQ.js → sequenceDiagram-SI44F4Z6-AlKYRgIk.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-7nlhJKo7.js → sizeCapture-X5ZJPWSS-CUy_ET4e.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-Cv2stqMA.js → stateDiagram-OKZ733FA-CTuVe6Sa.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BsWhs8O7.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-qDAo4Yc1.js → swimlanes-SLNWSIFB-ChFLJb-v.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-CJcioYGH.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CKbDNKTr.js → timeline-definition-Z64GVDOM-DZZeiAPr.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DI-9EHic.js → vennDiagram-T6HMQDX7-t4O91cZU.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-BrzzRDpX.js → wardleyDiagram-T6FBY63Y-CV5qGHZu.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-BclH5hGh.js → xychartDiagram-ELKLHX3M-DyXbytUI.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/app/console-types.js +9 -1
- package/dist/worker/console/static-src/operator-chat/animation-frame-batcher.js +38 -0
- package/dist/worker/console/static-src/operator-chat/chat-link.js +20 -0
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +186 -5
- package/dist/worker/console/static-src/operator-chat/chat-stream-continuity.js +101 -0
- package/dist/worker/console/static-src/operator-chat/compaction-message.js +18 -3
- package/dist/worker/console/static-src/operator-chat/context-insights-store.js +64 -0
- package/dist/worker/console/static-src/operator-chat/details-rail-surfaces.js +98 -0
- package/dist/worker/console/static-src/operator-chat/file-palette-nav.js +81 -0
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +17 -3
- package/dist/worker/console/static-src/operator-chat/process-label.js +27 -5
- package/dist/worker/console/static-src/operator-chat/tools-catalog.js +16 -7
- package/dist/worker/console/static-src/operator-chat/transcript-mode.js +21 -0
- package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +4 -1
- package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +13 -5
- package/dist/worker/console/static-src/operator-chat/turn-state-projection.js +166 -0
- package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +56 -2
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +211 -40
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +124 -27
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +88 -20
- package/dist/worker/console/static-src/operator-chat/useComposer.js +80 -6
- package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +13 -3
- package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +36 -17
- package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +18 -0
- package/dist/worker/console/static-src/operator-chat/useWorkspaceBrowserGate.js +4 -0
- package/dist/worker/console/static-src/shell/console-update-reload.js +1 -1
- package/dist/worker/console/workspace-context.js +2 -0
- package/dist/worker/console/workspace-initialization.js +3 -3
- package/dist/worker/observability/read-model.js +23 -2
- package/dist/worker/observe/node-context-insights.js +479 -0
- package/dist/worker/observe/static/console-theme.css +174 -0
- package/dist/worker/observe/static/console-theme.js +36 -0
- package/dist/worker/observe/static/operator-chrome.css +85 -0
- package/dist/worker/observe/static/operator-chrome.js +51 -0
- package/dist/worker/scheduler/scheduled-goal-dispatch.js +3 -2
- package/dist/worker/scheduler/scheduled-goal-evidence.js +66 -3
- package/dist/worker/scheduler/scheduled-goal-store.js +10 -0
- package/dist/workflows/dag/budget-enforcement.js +31 -2
- package/dist/workflows/dag/frontend-closeout.js +3 -1
- package/dist/workflows/dag/frontend-contract-facts.js +11 -8
- package/dist/workflows/dag/frontend-design-policy.js +6 -6
- package/dist/workflows/dag/frontend-durable-tools.js +90 -70
- package/dist/workflows/dag/frontend-implementation-contract.js +146 -57
- package/dist/workflows/dag/frontend-plan-canary.js +66 -16
- package/dist/workflows/dag/frontend-plan-decision-contract.js +13 -21
- package/dist/workflows/dag/frontend-plan-progress.js +92 -0
- package/dist/workflows/dag/frontend-recovery-plan.js +10 -5
- package/dist/workflows/dag/frontend-recovery-run.js +51 -46
- package/dist/workflows/dag/frontend-repair-assertions.js +36 -0
- package/dist/workflows/dag/frontend-review-context.js +29 -1
- package/dist/workflows/dag/frontend-review-scopes.js +92 -2
- package/dist/workflows/dag/frontend-risk.js +8 -3
- package/dist/workflows/dag/frontend-root-observation.js +261 -0
- package/dist/workflows/dag/frontend-session-budget.js +52 -39
- package/dist/workflows/dag/frontend-session-context.js +10 -0
- package/dist/workflows/dag/frontend-test-execution-evidence.js +206 -48
- package/dist/workflows/dag/frontend-typed-event-store.js +11 -1
- package/dist/workflows/dag/frontend-verification-trace.js +6 -0
- package/dist/workflows/dag/frontend-writer-admission.js +3 -1
- package/dist/workflows/dag/init-hybrid.js +108 -37
- package/dist/workflows/dag/node-execution.js +11 -11
- package/dist/workflows/dag/output-protocol.js +1 -0
- package/dist/workflows/dag/rerun-feedback.js +35 -4
- package/dist/workflows/dag/rerun-task.js +62 -66
- package/dist/workflows/dag/runner.js +58 -12
- package/dist/workflows/dag/types.js +15 -8
- package/dist/workflows/loop/benchmark.js +11 -8
- package/docs/README.md +1 -1
- package/docs/architecture/runtime-boundaries.md +1 -1
- package/docs/governance/harness-methodology-verification.md +11 -0
- package/docs/templates/backend-test-dag.json +5 -4
- package/docs/templates/frontend-implementation-contract.schema.json +31 -11
- package/package.json +6 -4
- package/skills/frontend-design-review/SKILL.md +8 -11
- package/skills/frontend-design-review/references/review-checklist.md +3 -4
- package/skills/frontend-review/SKILL.md +5 -1
- package/skills/loop-agent/references/command-reference.md +8 -0
- package/skills/loop-agent/references/hybrid-dag.md +1 -1
- package/dist/worker/console/static/assets/channel-ChE7y-cx.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C01TCf2X.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C01TCf2X.js +0 -1
- package/dist/worker/console/static/assets/index-BWkIfcrK.css +0 -1
- package/dist/worker/console/static/assets/index-Cdkvw_H6.js +0 -469
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DC7V5vcq.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Bwy4QUTO.js +0 -8
|
@@ -48,6 +48,8 @@ import { BrowserAutomationService } from "./browser-automation.js";
|
|
|
48
48
|
import { buildTodoContinuationContext, } from "./todos.js";
|
|
49
49
|
import { buildPersistentTerminalTools } from "./terminal-tools.js";
|
|
50
50
|
import { buildScmTools } from "./scm-tools.js";
|
|
51
|
+
import { DbConnectionRegistry } from "./db-connections.js";
|
|
52
|
+
import { buildSqlTools } from "./pi-runtime/custom-tools/sql-tools.js";
|
|
51
53
|
import { buildGoalContinuationContext, } from "./goals.js";
|
|
52
54
|
import { injectWizardLocalHeaders, } from "./sdd-data-alignment.js";
|
|
53
55
|
import { buildScheduledGoalTools } from "./pi-runtime/custom-tools/scheduled-goal-tools.js";
|
|
@@ -189,6 +191,25 @@ async function bindSessionExtensions(session) {
|
|
|
189
191
|
return;
|
|
190
192
|
await session.bindExtensions(createConsoleExtensionBindings());
|
|
191
193
|
}
|
|
194
|
+
export function branchForkedSessionManager(sessionManager, throughUserMessageIndex) {
|
|
195
|
+
const userEntries = (sessionManager.getBranch?.() ?? []).filter((entry) => {
|
|
196
|
+
if (!entry || typeof entry !== "object")
|
|
197
|
+
return false;
|
|
198
|
+
const candidate = entry;
|
|
199
|
+
return candidate.type === "message" && candidate.message?.role === "user";
|
|
200
|
+
});
|
|
201
|
+
const target = userEntries[throughUserMessageIndex];
|
|
202
|
+
if (!target || typeof target.id !== "string") {
|
|
203
|
+
throw new Error("FORK_MESSAGE_ENTRY_NOT_FOUND");
|
|
204
|
+
}
|
|
205
|
+
sessionManager.branch(target.id);
|
|
206
|
+
if (typeof sessionManager.appendCustomEntry !== "function") {
|
|
207
|
+
throw new Error("FORK_MESSAGE_ENTRY_PERSIST_UNSUPPORTED");
|
|
208
|
+
}
|
|
209
|
+
sessionManager.appendCustomEntry("loop-agent-fork-point", {
|
|
210
|
+
throughUserMessageIndex,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
192
213
|
function pinOperatorChatTools(session, sessionMode = DEFAULT_CONSOLE_CHAT_SESSION_MODE) {
|
|
193
214
|
session.setActiveToolsByName(computeChatActiveToolNames(session, sessionMode));
|
|
194
215
|
}
|
|
@@ -294,7 +315,44 @@ export function createWizardLocalHeadersExtension(options) {
|
|
|
294
315
|
}
|
|
295
316
|
export { THINKING_LEVELS, RuntimeSnapshotUnavailableError, projectRuntimeSnapshot, };
|
|
296
317
|
export { createDefaultPiSdkBindings } from "./pi-runtime/sdk-bindings.js";
|
|
318
|
+
/** Catalog listing must not load skills/extensions/context — those belong to reopen. */
|
|
319
|
+
const CATALOG_RESOURCE_LOADER_OPTIONS = Object.freeze({
|
|
320
|
+
noContextFiles: true,
|
|
321
|
+
noSkills: true,
|
|
322
|
+
noExtensions: true,
|
|
323
|
+
noPromptTemplates: true,
|
|
324
|
+
noThemes: true,
|
|
325
|
+
});
|
|
297
326
|
export { extractAssistantContentBlocks, extractAssistantText, isAssistantSdkMessage };
|
|
327
|
+
export function buildRequestContextEvent(input) {
|
|
328
|
+
const systemPrompt = input.session.state?.systemPrompt ?? input.session.systemPrompt ?? "";
|
|
329
|
+
const activeTools = input.session.getActiveToolNames()
|
|
330
|
+
.filter((name) => typeof name === "string" && name.trim())
|
|
331
|
+
.slice(0, 256);
|
|
332
|
+
const provider = input.session.model?.provider;
|
|
333
|
+
const modelId = input.session.model?.modelId ?? input.session.model?.id;
|
|
334
|
+
const sources = ["system", "conversation"];
|
|
335
|
+
if (activeTools.length > 0)
|
|
336
|
+
sources.push("tools");
|
|
337
|
+
if (input.imageCount > 0)
|
|
338
|
+
sources.push("images");
|
|
339
|
+
return {
|
|
340
|
+
type: "request_context",
|
|
341
|
+
sessionId: input.sessionId,
|
|
342
|
+
requestId: `${input.turnId}:request:1`,
|
|
343
|
+
step: 1,
|
|
344
|
+
...(provider && modelId ? { model: { provider, modelId } } : {}),
|
|
345
|
+
...(input.session.thinkingLevel
|
|
346
|
+
? { thinkingLevel: input.session.thinkingLevel }
|
|
347
|
+
: {}),
|
|
348
|
+
systemPromptHash: createHash("sha256").update(systemPrompt).digest("hex"),
|
|
349
|
+
systemPromptChars: systemPrompt.length,
|
|
350
|
+
activeTools,
|
|
351
|
+
inputChars: input.text.length,
|
|
352
|
+
imageCount: input.imageCount,
|
|
353
|
+
sources,
|
|
354
|
+
};
|
|
355
|
+
}
|
|
298
356
|
function readSessionManagerId(manager) {
|
|
299
357
|
if (!manager || typeof manager !== "object")
|
|
300
358
|
return undefined;
|
|
@@ -409,6 +467,8 @@ export class ConsolePiRuntime {
|
|
|
409
467
|
mainlineLeaves = new Map();
|
|
410
468
|
/** Per-sessionId single-flight materialization (create fast-path / readiness fence). */
|
|
411
469
|
sessionInit = new Map();
|
|
470
|
+
/** Concurrent reopen of the same historical JSONL shares one in-flight promise. */
|
|
471
|
+
reopenInFlight = new Map();
|
|
412
472
|
/** Resolved model binding after materialization (create may return before this is known). */
|
|
413
473
|
sessionModels = new Map();
|
|
414
474
|
/** Durable session mode; record is the source of truth, this is the live handle cache. */
|
|
@@ -418,12 +478,14 @@ export class ConsolePiRuntime {
|
|
|
418
478
|
compactionControllers = new Map();
|
|
419
479
|
siftStates = new Map();
|
|
420
480
|
/** Session-less tool definition caches (no AgentSession state). */
|
|
421
|
-
|
|
481
|
+
operatorCustomToolsBySession = new Map();
|
|
422
482
|
exploreCustomToolsPromise;
|
|
423
483
|
exploreOrchestrator;
|
|
424
484
|
bindings;
|
|
425
485
|
browserAutomation;
|
|
426
486
|
ownsBrowserAutomation;
|
|
487
|
+
dbConnections;
|
|
488
|
+
ownsDbConnections;
|
|
427
489
|
constructor(options) {
|
|
428
490
|
this.options = options;
|
|
429
491
|
this.loader = createOperatorChatResourceLoader();
|
|
@@ -434,6 +496,12 @@ export class ConsolePiRuntime {
|
|
|
434
496
|
downloadsDir: path.join(this.options.sessionDir, "..", "browser-downloads"),
|
|
435
497
|
screenshotsDir: path.join(this.options.sessionDir, "..", "browser-screenshots"),
|
|
436
498
|
});
|
|
499
|
+
// Governed DB connections are Console-global, not repository-scoped.
|
|
500
|
+
// This keeps named connections available when the user switches folders.
|
|
501
|
+
this.ownsDbConnections = options.dbConnections === undefined;
|
|
502
|
+
this.dbConnections =
|
|
503
|
+
options.dbConnections ??
|
|
504
|
+
new DbConnectionRegistry(path.join(options.globalAppDataRoot ?? path.resolve(this.options.sessionDir, ".."), "db"), undefined, undefined, path.join(this.options.sessionDir, "..", "db"));
|
|
437
505
|
this.exploreOrchestrator = new ExploreOrchestrator({
|
|
438
506
|
cwd: this.options.cwd,
|
|
439
507
|
bindings: this.bindings,
|
|
@@ -1018,7 +1086,7 @@ export class ConsolePiRuntime {
|
|
|
1018
1086
|
const loadWorkflowTools = shouldLoadWorkflowBusinessTools(sessionMode);
|
|
1019
1087
|
const [operatorCustomTools, exploreCustomTools] = await Promise.all([
|
|
1020
1088
|
loadWorkflowTools
|
|
1021
|
-
? this.loadOperatorCustomTools(sessionMode)
|
|
1089
|
+
? this.loadOperatorCustomTools(sessionId, sessionMode)
|
|
1022
1090
|
: Promise.resolve([]),
|
|
1023
1091
|
this.loadExploreCustomTools(),
|
|
1024
1092
|
]);
|
|
@@ -1059,6 +1127,16 @@ export class ConsolePiRuntime {
|
|
|
1059
1127
|
return [];
|
|
1060
1128
|
})
|
|
1061
1129
|
: [];
|
|
1130
|
+
const sqlTools = await buildSqlTools({
|
|
1131
|
+
sessionId,
|
|
1132
|
+
registry: this.dbConnections,
|
|
1133
|
+
...(this.options.questionRegistry
|
|
1134
|
+
? { questionRegistry: this.options.questionRegistry }
|
|
1135
|
+
: {}),
|
|
1136
|
+
}).catch((error) => {
|
|
1137
|
+
process.stderr.write(`[console] chat sql-tools build failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
1138
|
+
return [];
|
|
1139
|
+
});
|
|
1062
1140
|
const agentTool = await buildAgentCustomTool({
|
|
1063
1141
|
parentSessionId: sessionId,
|
|
1064
1142
|
orchestrator: this.exploreOrchestrator,
|
|
@@ -1092,25 +1170,28 @@ export class ConsolePiRuntime {
|
|
|
1092
1170
|
...terminalTools,
|
|
1093
1171
|
...scmTools,
|
|
1094
1172
|
...browserTools,
|
|
1173
|
+
...sqlTools,
|
|
1095
1174
|
...(agentTool ? [agentTool] : []),
|
|
1096
1175
|
];
|
|
1097
1176
|
}
|
|
1098
|
-
loadOperatorCustomTools(sessionMode) {
|
|
1177
|
+
loadOperatorCustomTools(sessionId, sessionMode) {
|
|
1099
1178
|
if (!this.options.actionContext)
|
|
1100
1179
|
return Promise.resolve([]);
|
|
1101
|
-
const
|
|
1180
|
+
const cacheKey = `${sessionId}:${sessionMode}`;
|
|
1181
|
+
const cached = this.operatorCustomToolsBySession.get(cacheKey);
|
|
1102
1182
|
if (cached)
|
|
1103
1183
|
return cached;
|
|
1104
1184
|
const promise = buildCustomOperatorTools({
|
|
1105
1185
|
actionContext: this.options.actionContext,
|
|
1186
|
+
sessionId,
|
|
1106
1187
|
sessionMode,
|
|
1107
1188
|
}).catch((error) => {
|
|
1108
1189
|
process.stderr.write(`[console] chat custom-tools build failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
1109
1190
|
// Allow a later create/reopen to retry after a transient failure.
|
|
1110
|
-
this.
|
|
1191
|
+
this.operatorCustomToolsBySession.delete(cacheKey);
|
|
1111
1192
|
return [];
|
|
1112
1193
|
});
|
|
1113
|
-
this.
|
|
1194
|
+
this.operatorCustomToolsBySession.set(cacheKey, promise);
|
|
1114
1195
|
return promise;
|
|
1115
1196
|
}
|
|
1116
1197
|
loadExploreCustomTools() {
|
|
@@ -1136,6 +1217,9 @@ export class ConsolePiRuntime {
|
|
|
1136
1217
|
targetSessionDir: this.options.sessionDir,
|
|
1137
1218
|
targetSessionId: sessionId,
|
|
1138
1219
|
});
|
|
1220
|
+
if (init.throughUserMessageIndex !== undefined) {
|
|
1221
|
+
branchForkedSessionManager(sessionManager, init.throughUserMessageIndex);
|
|
1222
|
+
}
|
|
1139
1223
|
const built = await this.buildSessionWithServices({
|
|
1140
1224
|
sessionId,
|
|
1141
1225
|
sessionManager,
|
|
@@ -1199,11 +1283,68 @@ export class ConsolePiRuntime {
|
|
|
1199
1283
|
entries: manager.getBranch?.() ?? [],
|
|
1200
1284
|
};
|
|
1201
1285
|
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Workspace-scoped model catalog. A live session's ModelRuntime is reused
|
|
1288
|
+
* when present; otherwise services are created without opening the Pi
|
|
1289
|
+
* conversation JSONL so the picker is not blocked on cold reopen.
|
|
1290
|
+
*/
|
|
1291
|
+
workspaceModelRuntime;
|
|
1292
|
+
workspaceInspection;
|
|
1293
|
+
async getWorkspaceModelRuntime() {
|
|
1294
|
+
if (!this.workspaceModelRuntime) {
|
|
1295
|
+
this.workspaceModelRuntime = (async () => {
|
|
1296
|
+
const agentDir = await safeGetAgentDir(this.bindings);
|
|
1297
|
+
const { services } = await this.bindings.createServices({
|
|
1298
|
+
cwd: this.options.cwd,
|
|
1299
|
+
agentDir,
|
|
1300
|
+
resourceLoaderOptions: { ...CATALOG_RESOURCE_LOADER_OPTIONS },
|
|
1301
|
+
});
|
|
1302
|
+
return services.modelRuntime;
|
|
1303
|
+
})().catch((error) => {
|
|
1304
|
+
this.workspaceModelRuntime = undefined;
|
|
1305
|
+
throw error;
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
return this.workspaceModelRuntime;
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Full OPEN-surface services for inspect UIs. No SessionManager / JSONL.
|
|
1312
|
+
* Cached without sessionId so todo/goal extensions stay off the shared scope.
|
|
1313
|
+
*/
|
|
1314
|
+
async getWorkspaceInspectionServices() {
|
|
1315
|
+
if (!this.workspaceInspection) {
|
|
1316
|
+
this.workspaceInspection = (async () => {
|
|
1317
|
+
const agentDir = await safeGetAgentDir(this.bindings);
|
|
1318
|
+
const appendSystemPrompt = composeChatSystemPromptParts({
|
|
1319
|
+
sessionMode: DEFAULT_CONSOLE_CHAT_SESSION_MODE,
|
|
1320
|
+
workflowPrompt: OPERATOR_CHAT_SYSTEM_PROMPT_BASE,
|
|
1321
|
+
});
|
|
1322
|
+
const { services } = await this.bindings.createServices({
|
|
1323
|
+
cwd: this.options.cwd,
|
|
1324
|
+
agentDir,
|
|
1325
|
+
resourceLoaderOptions: await this.buildResourceLoaderOptions({
|
|
1326
|
+
appendSystemPrompt,
|
|
1327
|
+
}),
|
|
1328
|
+
});
|
|
1329
|
+
return {
|
|
1330
|
+
modelRuntime: services.modelRuntime,
|
|
1331
|
+
resourceLoader: services
|
|
1332
|
+
.resourceLoader,
|
|
1333
|
+
settingsManager: services.settingsManager,
|
|
1334
|
+
};
|
|
1335
|
+
})().catch((error) => {
|
|
1336
|
+
this.workspaceInspection = undefined;
|
|
1337
|
+
throw error;
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
return this.workspaceInspection;
|
|
1341
|
+
}
|
|
1202
1342
|
async listModels(sessionId) {
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1343
|
+
const live = this.modelRuntimes.get(sessionId);
|
|
1344
|
+
if (live && this.sessions.has(sessionId)) {
|
|
1345
|
+
return this.bindings.listAvailableModels({ modelRuntime: live });
|
|
1346
|
+
}
|
|
1347
|
+
const modelRuntime = await this.getWorkspaceModelRuntime();
|
|
1207
1348
|
return this.bindings.listAvailableModels({ modelRuntime });
|
|
1208
1349
|
}
|
|
1209
1350
|
async applyModel(sessionId, model) {
|
|
@@ -1466,11 +1607,11 @@ export class ConsolePiRuntime {
|
|
|
1466
1607
|
return { ok: true, revision: this.revisions.get(sessionId) ?? 0 };
|
|
1467
1608
|
}
|
|
1468
1609
|
/**
|
|
1469
|
-
* Project the unified
|
|
1470
|
-
*
|
|
1471
|
-
*
|
|
1472
|
-
*
|
|
1473
|
-
*
|
|
1610
|
+
* Project the unified runtime snapshot (design §2.2). A live Pi session is
|
|
1611
|
+
* the source of truth when present. Inspect GETs may pass
|
|
1612
|
+
* `workspaceProjection` to render ResourceLoader inventories without
|
|
1613
|
+
* opening the conversation JSONL. Unknown ids without that hint stay
|
|
1614
|
+
* undefined so callers fail closed.
|
|
1474
1615
|
*/
|
|
1475
1616
|
/**
|
|
1476
1617
|
* ConsolePiRuntime.listSlashCommands
|
|
@@ -1489,18 +1630,27 @@ export class ConsolePiRuntime {
|
|
|
1489
1630
|
return collectSlashCommands({ session, resourceLoader });
|
|
1490
1631
|
}
|
|
1491
1632
|
async getRuntimeSnapshot(sessionId, options) {
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1633
|
+
const initializing = this.sessionInit.get(sessionId)?.status === "initializing";
|
|
1634
|
+
if (this.sessions.has(sessionId) || initializing) {
|
|
1635
|
+
try {
|
|
1636
|
+
await this.ensureSessionReady(sessionId);
|
|
1637
|
+
}
|
|
1638
|
+
catch (error) {
|
|
1639
|
+
if (error instanceof PiSessionInitFailedError)
|
|
1640
|
+
throw error;
|
|
1641
|
+
if (options?.workspaceProjection) {
|
|
1642
|
+
return this.projectWorkspaceRuntimeSnapshot(sessionId, options);
|
|
1643
|
+
}
|
|
1644
|
+
return undefined;
|
|
1645
|
+
}
|
|
1500
1646
|
}
|
|
1501
1647
|
const session = this.sessions.get(sessionId);
|
|
1502
|
-
if (!session)
|
|
1648
|
+
if (!session) {
|
|
1649
|
+
if (options?.workspaceProjection) {
|
|
1650
|
+
return this.projectWorkspaceRuntimeSnapshot(sessionId, options);
|
|
1651
|
+
}
|
|
1503
1652
|
return undefined;
|
|
1653
|
+
}
|
|
1504
1654
|
const services = this.serviceScopes.get(sessionId);
|
|
1505
1655
|
const modelRuntime = this.modelRuntimes.get(sessionId);
|
|
1506
1656
|
const resourceLoader = services?.resourceLoader;
|
|
@@ -1601,6 +1751,116 @@ export class ConsolePiRuntime {
|
|
|
1601
1751
|
hasBash: true,
|
|
1602
1752
|
});
|
|
1603
1753
|
}
|
|
1754
|
+
resolveWorkspaceThinkingSelection(sessionId, stored) {
|
|
1755
|
+
const live = this.thinkingSelections.get(sessionId);
|
|
1756
|
+
if (live)
|
|
1757
|
+
return live;
|
|
1758
|
+
if (!stored || stored === "auto")
|
|
1759
|
+
return "auto";
|
|
1760
|
+
if (THINKING_LEVELS.includes(stored)) {
|
|
1761
|
+
return stored;
|
|
1762
|
+
}
|
|
1763
|
+
return "auto";
|
|
1764
|
+
}
|
|
1765
|
+
/**
|
|
1766
|
+
* Inspect projection without SessionManager.open. Used only when the Agent
|
|
1767
|
+
* is not live and the caller confirmed a durable session record.
|
|
1768
|
+
*/
|
|
1769
|
+
async projectWorkspaceRuntimeSnapshot(sessionId, options) {
|
|
1770
|
+
const hint = options.workspaceProjection ?? {};
|
|
1771
|
+
const sessionMode = hint.sessionMode ?? this.sessionModeOf(sessionId);
|
|
1772
|
+
let inspection;
|
|
1773
|
+
try {
|
|
1774
|
+
inspection = await this.getWorkspaceInspectionServices();
|
|
1775
|
+
}
|
|
1776
|
+
catch (error) {
|
|
1777
|
+
throw new RuntimeSnapshotUnavailableError(`workspace runtime projection failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1778
|
+
}
|
|
1779
|
+
const resourceLoader = inspection.resourceLoader;
|
|
1780
|
+
const settingsManager = inspection.settingsManager;
|
|
1781
|
+
const thinkingSelection = this.resolveWorkspaceThinkingSelection(sessionId, hint.thinkingLevel);
|
|
1782
|
+
const effectiveThinkingLevel = settingsManager?.getDefaultThinkingLevel?.() ??
|
|
1783
|
+
(thinkingSelection === "auto" ? undefined : thinkingSelection);
|
|
1784
|
+
const rawSystemPrompt = resourceLoader?.getSystemPrompt?.() ||
|
|
1785
|
+
composeChatSystemPrompt({
|
|
1786
|
+
sessionMode,
|
|
1787
|
+
workflowPrompt: OPERATOR_CHAT_SYSTEM_PROMPT_BASE,
|
|
1788
|
+
});
|
|
1789
|
+
if (!rawSystemPrompt) {
|
|
1790
|
+
throw new RuntimeSnapshotUnavailableError("system prompt projection failed: workspace prompt was empty");
|
|
1791
|
+
}
|
|
1792
|
+
let models = [];
|
|
1793
|
+
try {
|
|
1794
|
+
models = this.bindings
|
|
1795
|
+
.listAvailableModels({ modelRuntime: inspection.modelRuntime })
|
|
1796
|
+
.map((entry) => ({
|
|
1797
|
+
provider: entry.provider,
|
|
1798
|
+
id: entry.id,
|
|
1799
|
+
...(entry.name ? { name: entry.name } : {}),
|
|
1800
|
+
hasCredentials: entry.hasCredentials,
|
|
1801
|
+
}));
|
|
1802
|
+
}
|
|
1803
|
+
catch (error) {
|
|
1804
|
+
throw new RuntimeSnapshotUnavailableError(`model enumeration failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1805
|
+
}
|
|
1806
|
+
const thinkingLevels = [
|
|
1807
|
+
{ value: "auto" },
|
|
1808
|
+
...THINKING_LEVELS.map((value) => ({ value })),
|
|
1809
|
+
];
|
|
1810
|
+
let skillPrefs = { schemaVersion: 1, skills: {} };
|
|
1811
|
+
let skillPrefsError;
|
|
1812
|
+
if (resourceLoader) {
|
|
1813
|
+
try {
|
|
1814
|
+
skillPrefs = await this.loadSkillAutoInvocationPreferences();
|
|
1815
|
+
}
|
|
1816
|
+
catch (error) {
|
|
1817
|
+
skillPrefsError = error;
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
const activeTools = chatActiveToolBaseline(sessionMode);
|
|
1821
|
+
const inventories = await collectRuntimeInventories({
|
|
1822
|
+
resourceLoader,
|
|
1823
|
+
skillPrefs,
|
|
1824
|
+
skillPrefsError,
|
|
1825
|
+
agentDir: await safeGetAgentDir(this.bindings),
|
|
1826
|
+
cwd: this.options.cwd,
|
|
1827
|
+
tools: [],
|
|
1828
|
+
activeToolNames: activeTools,
|
|
1829
|
+
});
|
|
1830
|
+
const storedModel = this.sessionModels.get(sessionId);
|
|
1831
|
+
const provider = storedModel?.provider ?? hint.modelProvider;
|
|
1832
|
+
const modelId = storedModel?.modelId ?? hint.modelId;
|
|
1833
|
+
return projectRuntimeSnapshot({
|
|
1834
|
+
sessionId,
|
|
1835
|
+
revision: this.revisions.get(sessionId) ?? 0,
|
|
1836
|
+
loadedAt: new Date().toISOString(),
|
|
1837
|
+
selection: {
|
|
1838
|
+
...(provider && modelId
|
|
1839
|
+
? { model: { provider, id: modelId } }
|
|
1840
|
+
: {}),
|
|
1841
|
+
thinkingSelection,
|
|
1842
|
+
...(effectiveThinkingLevel
|
|
1843
|
+
? { effectiveThinkingLevel: effectiveThinkingLevel }
|
|
1844
|
+
: {}),
|
|
1845
|
+
},
|
|
1846
|
+
models,
|
|
1847
|
+
thinkingLevels,
|
|
1848
|
+
systemPrompt: {
|
|
1849
|
+
...(options.includeRaw ? { raw: rawSystemPrompt } : {}),
|
|
1850
|
+
text: rawSystemPrompt,
|
|
1851
|
+
sha256: createHash("sha256").update(rawSystemPrompt).digest("hex"),
|
|
1852
|
+
characters: rawSystemPrompt.length,
|
|
1853
|
+
},
|
|
1854
|
+
activeTools,
|
|
1855
|
+
contextFiles: inventories.contextFiles,
|
|
1856
|
+
skills: inventories.skills,
|
|
1857
|
+
extensions: inventories.extensions,
|
|
1858
|
+
packages: inventories.packages,
|
|
1859
|
+
mcp: inventories.mcp,
|
|
1860
|
+
diagnostics: inventories.diagnostics,
|
|
1861
|
+
hasBash: true,
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1604
1864
|
/**
|
|
1605
1865
|
* Re-open a previously persisted Chat session after Console restart or
|
|
1606
1866
|
* browser refresh (roadmap M1-S04 / S05).
|
|
@@ -1615,6 +1875,19 @@ export class ConsolePiRuntime {
|
|
|
1615
1875
|
* than silently creating a fresh empty session and losing prior context.
|
|
1616
1876
|
*/
|
|
1617
1877
|
async reopenSession(init) {
|
|
1878
|
+
const sessionId = init.sessionId;
|
|
1879
|
+
const existing = this.reopenInFlight.get(sessionId);
|
|
1880
|
+
if (existing)
|
|
1881
|
+
return existing;
|
|
1882
|
+
const pending = this.reopenSessionExclusive(init).finally(() => {
|
|
1883
|
+
if (this.reopenInFlight.get(sessionId) === pending) {
|
|
1884
|
+
this.reopenInFlight.delete(sessionId);
|
|
1885
|
+
}
|
|
1886
|
+
});
|
|
1887
|
+
this.reopenInFlight.set(sessionId, pending);
|
|
1888
|
+
return pending;
|
|
1889
|
+
}
|
|
1890
|
+
async reopenSessionExclusive(init) {
|
|
1618
1891
|
await this.syncAimaxAuthToken();
|
|
1619
1892
|
const sessionId = init.sessionId;
|
|
1620
1893
|
const sessionMode = this.rememberSessionMode(sessionId, init.sessionMode ?? this.sessionModeOf(sessionId));
|
|
@@ -1954,6 +2227,14 @@ export class ConsolePiRuntime {
|
|
|
1954
2227
|
};
|
|
1955
2228
|
emitContextUsage();
|
|
1956
2229
|
await this.runPrePromptCompaction(sessionId, session, text, options?.images?.length ?? 0, onEvent);
|
|
2230
|
+
onEvent(buildRequestContextEvent({
|
|
2231
|
+
sessionId,
|
|
2232
|
+
turnId: options?.turnId ?? `${sessionId}:active`,
|
|
2233
|
+
session,
|
|
2234
|
+
text,
|
|
2235
|
+
imageCount: options?.images?.length ?? 0,
|
|
2236
|
+
}));
|
|
2237
|
+
let step = 0;
|
|
1957
2238
|
let stepStartedAt;
|
|
1958
2239
|
let firstTokenAt;
|
|
1959
2240
|
let pendingProviderError;
|
|
@@ -1962,12 +2243,24 @@ export class ConsolePiRuntime {
|
|
|
1962
2243
|
const emitPendingProviderError = () => {
|
|
1963
2244
|
if (!pendingProviderError)
|
|
1964
2245
|
return;
|
|
1965
|
-
|
|
2246
|
+
const error = pendingProviderError;
|
|
2247
|
+
onEvent(error);
|
|
2248
|
+
onEvent({
|
|
2249
|
+
type: "turn_error",
|
|
2250
|
+
sessionId,
|
|
2251
|
+
step: Math.max(1, step),
|
|
2252
|
+
...(error.providerError.code === undefined
|
|
2253
|
+
? {}
|
|
2254
|
+
: { code: String(error.providerError.code) }),
|
|
2255
|
+
message: error.message,
|
|
2256
|
+
});
|
|
1966
2257
|
pendingProviderError = undefined;
|
|
1967
2258
|
providerErrorEmitted = true;
|
|
1968
2259
|
};
|
|
1969
2260
|
unsub = session.subscribe((event) => {
|
|
1970
2261
|
const observedAt = Date.now();
|
|
2262
|
+
if (event.type === "turn_start")
|
|
2263
|
+
step += 1;
|
|
1971
2264
|
if (event.type === "message_start" && isUserSdkMessage(event.message)) {
|
|
1972
2265
|
if (!initialUserMessageStarted) {
|
|
1973
2266
|
// The first user message_start belongs to session.prompt(text), not
|
|
@@ -1998,7 +2291,7 @@ export class ConsolePiRuntime {
|
|
|
1998
2291
|
const compactionId = event.type === "compaction_start" || event.type === "compaction_end"
|
|
1999
2292
|
? activeCompaction?.compactionId ?? newCompactionId(sessionId)
|
|
2000
2293
|
: undefined;
|
|
2001
|
-
const mapped = mapSdkEvent(sessionId, event, compactionId);
|
|
2294
|
+
const mapped = mapSdkEvent(sessionId, event, compactionId, Math.max(1, step));
|
|
2002
2295
|
if (event.type === "compaction_end")
|
|
2003
2296
|
activeCompaction = undefined;
|
|
2004
2297
|
if (mapped?.type === "error") {
|
|
@@ -2023,7 +2316,7 @@ export class ConsolePiRuntime {
|
|
|
2023
2316
|
if (mapped?.type === "agent_settled") {
|
|
2024
2317
|
emitPendingProviderError();
|
|
2025
2318
|
}
|
|
2026
|
-
if (mapped?.type === "agent_start") {
|
|
2319
|
+
if (mapped?.type === "step_start" || mapped?.type === "agent_start") {
|
|
2027
2320
|
stepStartedAt = observedAt;
|
|
2028
2321
|
firstTokenAt = undefined;
|
|
2029
2322
|
}
|
|
@@ -2051,6 +2344,13 @@ export class ConsolePiRuntime {
|
|
|
2051
2344
|
: { outputTokens: usage.outputTokens }),
|
|
2052
2345
|
};
|
|
2053
2346
|
onEvent({ ...mapped, ...(timing ? { timing } : {}) });
|
|
2347
|
+
if (mapped.stopReason === "length") {
|
|
2348
|
+
onEvent({
|
|
2349
|
+
type: "turn_max_tokens",
|
|
2350
|
+
sessionId,
|
|
2351
|
+
step: mapped.step ?? Math.max(1, step),
|
|
2352
|
+
});
|
|
2353
|
+
}
|
|
2054
2354
|
if (usage)
|
|
2055
2355
|
onEvent({ type: "usage", sessionId, usage });
|
|
2056
2356
|
emitContextUsage();
|
|
@@ -2232,6 +2532,36 @@ export class ConsolePiRuntime {
|
|
|
2232
2532
|
const result = await session.compact(customInstructions);
|
|
2233
2533
|
return projectCompactSnapshot(result ?? {});
|
|
2234
2534
|
}
|
|
2535
|
+
listDatabaseConnections() {
|
|
2536
|
+
return this.dbConnections.list();
|
|
2537
|
+
}
|
|
2538
|
+
addDatabaseConnection(input) {
|
|
2539
|
+
return this.dbConnections.add(input);
|
|
2540
|
+
}
|
|
2541
|
+
updateDatabaseConnection(currentName, input) {
|
|
2542
|
+
return this.dbConnections.update(currentName, input);
|
|
2543
|
+
}
|
|
2544
|
+
removeDatabaseConnection(name) {
|
|
2545
|
+
return this.dbConnections.remove(name);
|
|
2546
|
+
}
|
|
2547
|
+
exportDatabaseConnections() {
|
|
2548
|
+
return this.dbConnections.exportConfig();
|
|
2549
|
+
}
|
|
2550
|
+
importDatabaseConnections(input, conflict) {
|
|
2551
|
+
return this.dbConnections.importConfig(input, conflict);
|
|
2552
|
+
}
|
|
2553
|
+
testDatabaseConnection(name) {
|
|
2554
|
+
return this.dbConnections.test(name);
|
|
2555
|
+
}
|
|
2556
|
+
listDatabaseDatabases(name) {
|
|
2557
|
+
return this.dbConnections.listDatabases(name);
|
|
2558
|
+
}
|
|
2559
|
+
listDatabaseTables(name, database) {
|
|
2560
|
+
return this.dbConnections.listTables(name, database);
|
|
2561
|
+
}
|
|
2562
|
+
browseDatabaseTable(name, table, page, pageSize, database) {
|
|
2563
|
+
return this.dbConnections.browseTable(name, table, page, pageSize, database);
|
|
2564
|
+
}
|
|
2235
2565
|
dispose(sessionId) {
|
|
2236
2566
|
// Mark disposed first so a late materialization never registers ready.
|
|
2237
2567
|
this.disposedSessions.add(sessionId);
|
|
@@ -2239,6 +2569,11 @@ export class ConsolePiRuntime {
|
|
|
2239
2569
|
this.sessionInit.delete(sessionId);
|
|
2240
2570
|
this.compactionControllers.delete(sessionId);
|
|
2241
2571
|
this.siftStates.delete(sessionId);
|
|
2572
|
+
for (const key of this.operatorCustomToolsBySession.keys()) {
|
|
2573
|
+
if (key.startsWith(`${sessionId}:`)) {
|
|
2574
|
+
this.operatorCustomToolsBySession.delete(key);
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2242
2577
|
const session = this.sessions.get(sessionId);
|
|
2243
2578
|
if (session) {
|
|
2244
2579
|
try {
|
|
@@ -2269,9 +2604,11 @@ export class ConsolePiRuntime {
|
|
|
2269
2604
|
void this.exploreOrchestrator.abortAll();
|
|
2270
2605
|
if (this.ownsBrowserAutomation)
|
|
2271
2606
|
void this.browserAutomation.dispose();
|
|
2607
|
+
if (this.ownsDbConnections)
|
|
2608
|
+
this.dbConnections.dispose();
|
|
2272
2609
|
}
|
|
2273
2610
|
}
|
|
2274
|
-
function mapAssistantMessageEvent(type, sessionId, message) {
|
|
2611
|
+
function mapAssistantMessageEvent(type, sessionId, message, step) {
|
|
2275
2612
|
const record = message !== null && typeof message === "object"
|
|
2276
2613
|
? message
|
|
2277
2614
|
: undefined;
|
|
@@ -2295,6 +2632,10 @@ function mapAssistantMessageEvent(type, sessionId, message) {
|
|
|
2295
2632
|
sessionId,
|
|
2296
2633
|
text: extractAssistantText(message),
|
|
2297
2634
|
...(content.length > 0 ? { content } : {}),
|
|
2635
|
+
step,
|
|
2636
|
+
...(type === "message_end" && typeof record?.stopReason === "string"
|
|
2637
|
+
? { stopReason: record.stopReason }
|
|
2638
|
+
: {}),
|
|
2298
2639
|
};
|
|
2299
2640
|
}
|
|
2300
2641
|
function isUserSdkMessage(message) {
|
|
@@ -2302,10 +2643,12 @@ function isUserSdkMessage(message) {
|
|
|
2302
2643
|
typeof message === "object" &&
|
|
2303
2644
|
message.role === "user");
|
|
2304
2645
|
}
|
|
2305
|
-
function mapSdkEvent(sessionId, event, compactionId) {
|
|
2646
|
+
export function mapSdkEvent(sessionId, event, compactionId, step = 1) {
|
|
2306
2647
|
switch (event.type) {
|
|
2307
2648
|
case "agent_start":
|
|
2308
2649
|
return { type: "agent_start", sessionId };
|
|
2650
|
+
case "turn_start":
|
|
2651
|
+
return { type: "step_start", sessionId, step };
|
|
2309
2652
|
case "agent_end":
|
|
2310
2653
|
return {
|
|
2311
2654
|
type: "agent_end",
|
|
@@ -2315,15 +2658,50 @@ function mapSdkEvent(sessionId, event, compactionId) {
|
|
|
2315
2658
|
case "message_update":
|
|
2316
2659
|
if (!isAssistantSdkMessage(event.message))
|
|
2317
2660
|
return undefined;
|
|
2318
|
-
return mapAssistantMessageEvent("message_update", sessionId, event.message);
|
|
2661
|
+
return mapAssistantMessageEvent("message_update", sessionId, event.message, step);
|
|
2319
2662
|
case "message_end":
|
|
2320
2663
|
if (!isAssistantSdkMessage(event.message))
|
|
2321
2664
|
return undefined;
|
|
2322
|
-
return mapAssistantMessageEvent("message_end", sessionId, event.message);
|
|
2323
|
-
case "turn_end":
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2665
|
+
return mapAssistantMessageEvent("message_end", sessionId, event.message, step);
|
|
2666
|
+
case "turn_end": {
|
|
2667
|
+
const record = event.message && typeof event.message === "object"
|
|
2668
|
+
? event.message
|
|
2669
|
+
: undefined;
|
|
2670
|
+
const reason = record?.stopReason;
|
|
2671
|
+
return {
|
|
2672
|
+
type: "step_end",
|
|
2673
|
+
sessionId,
|
|
2674
|
+
step,
|
|
2675
|
+
outcome: reason === "error"
|
|
2676
|
+
? "failed"
|
|
2677
|
+
: reason === "aborted"
|
|
2678
|
+
? "interrupted"
|
|
2679
|
+
: "completed",
|
|
2680
|
+
};
|
|
2681
|
+
}
|
|
2682
|
+
case "auto_retry_start":
|
|
2683
|
+
return {
|
|
2684
|
+
type: "model_retry",
|
|
2685
|
+
sessionId,
|
|
2686
|
+
step,
|
|
2687
|
+
attempt: event.attempt,
|
|
2688
|
+
maxAttempts: event.maxAttempts,
|
|
2689
|
+
delayMs: event.delayMs,
|
|
2690
|
+
errorMessage: redactRuntimeText(event.errorMessage, 600),
|
|
2691
|
+
state: "scheduled",
|
|
2692
|
+
};
|
|
2693
|
+
case "auto_retry_end":
|
|
2694
|
+
return {
|
|
2695
|
+
type: "model_retry",
|
|
2696
|
+
sessionId,
|
|
2697
|
+
step,
|
|
2698
|
+
attempt: event.attempt,
|
|
2699
|
+
state: event.success ? "completed" : "failed",
|
|
2700
|
+
success: event.success,
|
|
2701
|
+
...(event.finalError
|
|
2702
|
+
? { errorMessage: redactRuntimeText(event.finalError, 600) }
|
|
2703
|
+
: {}),
|
|
2704
|
+
};
|
|
2327
2705
|
case "tool_execution_start":
|
|
2328
2706
|
return {
|
|
2329
2707
|
type: "tool_call",
|
|
@@ -2331,6 +2709,22 @@ function mapSdkEvent(sessionId, event, compactionId) {
|
|
|
2331
2709
|
toolCallId: event.toolCallId,
|
|
2332
2710
|
toolName: event.toolName,
|
|
2333
2711
|
args: event.args,
|
|
2712
|
+
step,
|
|
2713
|
+
...(event.parentToolCallId
|
|
2714
|
+
? { parentToolCallId: event.parentToolCallId }
|
|
2715
|
+
: {}),
|
|
2716
|
+
};
|
|
2717
|
+
case "tool_execution_update":
|
|
2718
|
+
return {
|
|
2719
|
+
type: "tool_update",
|
|
2720
|
+
sessionId,
|
|
2721
|
+
toolCallId: event.toolCallId,
|
|
2722
|
+
toolName: event.toolName,
|
|
2723
|
+
partialResult: event.partialResult,
|
|
2724
|
+
step,
|
|
2725
|
+
...(event.parentToolCallId
|
|
2726
|
+
? { parentToolCallId: event.parentToolCallId }
|
|
2727
|
+
: {}),
|
|
2334
2728
|
};
|
|
2335
2729
|
case "tool_execution_end":
|
|
2336
2730
|
return {
|
|
@@ -2340,6 +2734,10 @@ function mapSdkEvent(sessionId, event, compactionId) {
|
|
|
2340
2734
|
toolName: event.toolName,
|
|
2341
2735
|
result: event.result,
|
|
2342
2736
|
isError: event.isError,
|
|
2737
|
+
step,
|
|
2738
|
+
...(event.parentToolCallId
|
|
2739
|
+
? { parentToolCallId: event.parentToolCallId }
|
|
2740
|
+
: {}),
|
|
2343
2741
|
};
|
|
2344
2742
|
case "agent_settled":
|
|
2345
2743
|
return { type: "agent_settled", sessionId };
|
|
@@ -2386,8 +2784,19 @@ function mapSdkEvent(sessionId, event, compactionId) {
|
|
|
2386
2784
|
: {}),
|
|
2387
2785
|
};
|
|
2388
2786
|
}
|
|
2389
|
-
|
|
2787
|
+
case "message_start":
|
|
2788
|
+
case "queue_update":
|
|
2390
2789
|
return undefined;
|
|
2790
|
+
default:
|
|
2791
|
+
{
|
|
2792
|
+
const unknownEvent = event;
|
|
2793
|
+
return {
|
|
2794
|
+
type: "unknown",
|
|
2795
|
+
sessionId,
|
|
2796
|
+
eventType: String(unknownEvent.type ?? "unknown"),
|
|
2797
|
+
value: unknownEvent,
|
|
2798
|
+
};
|
|
2799
|
+
}
|
|
2391
2800
|
}
|
|
2392
2801
|
}
|
|
2393
2802
|
function newCompactionId(sessionId) {
|