@xopcai/xopc 0.0.222 → 0.0.224
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-NItGQmvR.js → activity-store--GBciH10.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DsR_2U9-.js → agent-avatar-dicebear-K7V4XXt7.js} +1 -1
- package/dist/gateway/static/root/assets/agents-BsxTpXyq.js +68 -0
- package/dist/gateway/static/root/assets/{api-53ZXsuyr.js → api-HoIz_ija.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BCzVX09V.js → app-management-settings-panel-xQCmkAHh.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DgSpwqQI.js → appearance-settings-BRoeA4kU.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BXgpBA8w.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-D8o8CP9Y.js → archive-plugin-CteCVsBP.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BQHcAR6J.js → attachment-load-D7xNA2jB.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-CswK3HFb.js → automations-page-BD1vK7r5.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-wrgf-z7D.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BlpyTJ1b.js → binary-plugins-C3DaJa0W.js} +1 -1
- package/dist/gateway/static/root/assets/block-editor-lTkcHTve.js +184 -0
- package/dist/gateway/static/root/assets/browser-settings-page-zhzNkeVG.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-Bi6RSSpD.js → browser-workflow-inputs-1UZ0vnIy.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CZNOOQY4.js → browser-workflows-page-BHuJOF4M.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DuCmg2Ej.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-pC2fno7r.js → capability-presets-api-yNqTIuyd.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DjiP3mQQ.js +3 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-B5Szgu_z.js → channel-recipient-api-krezGsKc.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-B4AtvQHk.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-DMxB7slL.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-2fpzufzt.js → chat-terminal-dock-BRrL2iHA.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-fmda2NEP.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-VePLfPUR.js → cron-expression-Bl-2DzBQ.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-CJegmPTJ.js → date-picker-CxTl6Wlz.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-B2o9unBk.js → dependency-picker-DSl0mOPa.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-BH4Np-ay.js → desktop-pet-DTeCmCdb.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Duu3ctxD.js → desktop-pet-settings-BNebxg0V.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BBCUZOg2.js → directory-picker-path-field-Dn9XpmXY.js} +1 -1
- package/dist/gateway/static/root/assets/dist-DaxPZj9e.js +1 -0
- package/dist/gateway/static/root/assets/{dist-DY4Af0fY.js → dist-J_ySZvz0.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DS_o3F97.js → extension-debug-page-D-J-eOTb.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BTLBZdCq.js → extension-page-CpST24nU.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-KTGrYbgk.js → extension-settings-page-4nQXFnFq.js} +1 -1
- package/dist/gateway/static/root/assets/floating-ui.dom-B7uQOZZW.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-api-D3YJVfzY.js → gateway-config-api-BHWHduDi.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BzTbnu4O.js → gateway-config-swr-yUxMMVjK.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-B8--s3yC.js → gateway-settings-BimMKmkM.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-B2zpkNvi.js → gateway-startup-retry-9mrsL84j.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-MUJ3mEC9.js +1 -0
- package/dist/gateway/static/root/assets/home-page-DSM6aPHF.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-BXRjz-iY.js → image-generation-api-CgFAGDi8.js} +1 -1
- package/dist/gateway/static/root/assets/index-B3zYJBhK.js +74 -0
- package/dist/gateway/static/root/assets/index-D3_xSYKd.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-D-Ib-suu.js → keyboard-shortcuts-settings-6Ar5rfX4.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-tzM0wTL8.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-Bsy1lvAc.js → local-apps-page-B5n-x544.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-iKjqemWG.js → locale-store-CPylQjH9.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-CgoQlera.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-D-akydG4.js → management-settings-CXBLyU-0.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-DHH4Cu2i.js → markdown-split-CtmQemJi.js} +1 -1
- package/dist/gateway/static/root/assets/markdown-view-CUsob4Pz.js +69 -0
- package/dist/gateway/static/root/assets/{media-plugins-BwHtUXkj.js → media-plugins-Dsd-IEOW.js} +1 -1
- package/dist/gateway/static/root/assets/messages-B82nsi9k.js +3 -0
- package/dist/gateway/static/root/assets/notes-api-CfKZYrBC.js +1 -0
- package/dist/gateway/static/root/assets/{notes-page-BxM1p6hz.js → notes-page-BKbOTE2n.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-BScELo01.js +4 -0
- package/dist/gateway/static/root/assets/oauth-authorization-window-Cdolr2wE.js +1 -0
- package/dist/gateway/static/root/assets/{popover-select-BzdnTy3h.js → popover-select-CccGri5Y.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-DrfWH1ir.js → product-open-page-DqB9bsDB.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DUoyty8X.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-PeXUdGdO.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-Cx3JxXSL.js → registry-api-B_5D8epF.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-sHho-uXP.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DF7syQRd.js → runtime-tools-settings-panel-DBTH_t0O.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-BQ_qRIsM.js → schema-form-CqMKAwV0.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DyvNgaP9.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CnYf1R7z.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BBHGOQHU.js → settings-form-section-dPriuuYq.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-CiwjP2-b.js → settings-loading-skeleton-B-Mbm8Va.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Rl9waapk.js → settings-page-Dyj3w-Ml.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-C4FxY5J3.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-emEdx7YL.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-BQBVq-sN.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BFoEpQ4I.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-YbtR_zEU.js → skills-page-BNtYnrRT.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DTmx2Zza.js → skills-page.utils-DjnbNFs5.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BZDJcKdS.js → system-settings-panel-DDStf-jZ.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-ZVwr8KbS.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-BOD2D0dJ.js → theme-store-BN-32Fz5.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-Be9aR9qA.js → use-autosave-C2mKZ-ua.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-CHjIinCW.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-IMc3Ua6C.js → voice-api-key-field-D7OHeQby.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-TC-xQenr.js → work-discovery-overlay-CIiXie7F.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-B2auxcRv.js → workflow-run-setup-panel-9_dAGW3_.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DXpYJxao.js +5 -0
- package/dist/gateway/static/root/index.html +15 -14
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +3 -0
- package/dist/src/agent/agent-manager.d.ts +3 -0
- package/dist/src/agent/agent-manager.js +30 -24
- package/dist/src/agent/embedded/index.d.ts +1 -1
- package/dist/src/agent/embedded/index.js +2 -2
- package/dist/src/agent/embedded/run-for-session.js +101 -62
- package/dist/src/agent/embedded/run-turn.js +56 -28
- package/dist/src/agent/embedded/runs.d.ts +16 -29
- package/dist/src/agent/embedded/runs.js +44 -65
- package/dist/src/agent/embedded/types.d.ts +4 -0
- package/dist/src/agent/orchestration/agent-run-supervisor.d.ts +28 -0
- package/dist/src/agent/orchestration/agent-run-supervisor.js +49 -0
- package/dist/src/agent/orchestration/agent-turn-policy.d.ts +18 -0
- package/dist/src/agent/orchestration/agent-turn-policy.js +36 -0
- package/dist/src/agent/orchestration/llm-turn-retry.d.ts +5 -0
- package/dist/src/agent/orchestration/llm-turn-retry.js +34 -4
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +10 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +25 -4
- package/dist/src/agent/service/async-queue.d.ts +16 -3
- package/dist/src/agent/service/async-queue.js +29 -11
- package/dist/src/agent/service/process-direct-streaming.js +27 -4
- package/dist/src/agent/service.js +1 -0
- package/dist/src/agent/tools/exec-command.d.ts +2 -0
- package/dist/src/agent/tools/exec-command.js +70 -7
- package/dist/src/auth/oauth/index.js +3 -3
- package/dist/src/auth/oauth/registry.d.ts +2 -0
- package/dist/src/auth/oauth/registry.js +20 -12
- package/dist/src/auth/oauth/xopc-cloud.d.ts +1 -0
- package/dist/src/auth/oauth/xopc-cloud.js +32 -16
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/tunnel.js +4 -5
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/schema.d.ts +18 -0
- package/dist/src/config/schema.js +19 -1
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/hono/app.js +2 -1
- package/dist/src/gateway/hono/oauth-async.d.ts +1 -0
- package/dist/src/gateway/hono/oauth-async.js +11 -4
- package/dist/src/gateway/hono/routes/config.js +10 -0
- package/dist/src/gateway/hono/routes/host-fs.js +40 -1
- package/dist/src/gateway/hono/routes/media.js +33 -1
- package/dist/src/gateway/hono/routes/notes.js +162 -7
- package/dist/src/gateway/hono/routes/shares.js +141 -6
- package/dist/src/gateway/hono/routes/tunnel.js +47 -10
- package/dist/src/gateway/hono/routes/voice.d.ts +2 -6
- package/dist/src/gateway/hono/routes/voice.js +20 -4
- package/dist/src/gateway/hono/routes/workflows.js +2 -2
- package/dist/src/gateway/run-loop.js +3 -0
- package/dist/src/gateway/server.d.ts +3 -0
- package/dist/src/gateway/server.js +30 -5
- package/dist/src/gateway/service.js +4 -4
- package/dist/src/notes/service.d.ts +6 -2
- package/dist/src/notes/service.js +36 -4
- package/dist/src/providers/index.js +2 -2
- package/dist/src/share/note-share-service.d.ts +67 -0
- package/dist/src/share/note-share-service.js +283 -0
- package/dist/src/share/share-config.js +32 -3
- package/dist/src/share/share-landing.d.ts +5 -1
- package/dist/src/share/share-landing.js +28 -1
- package/dist/src/share/share-store.d.ts +34 -5
- package/dist/src/share/share-store.js +125 -19
- package/dist/src/share/share-thumbnail.js +4 -2
- package/dist/src/share/share-types.d.ts +52 -14
- package/dist/src/share/share-types.js +9 -0
- package/dist/src/share/share-zip.d.ts +2 -2
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tunnel/env.d.ts +12 -6
- package/dist/src/tunnel/env.js +34 -26
- package/dist/src/tunnel/gateway-lifecycle.js +2 -13
- package/dist/src/tunnel/index.d.ts +1 -1
- package/dist/src/tunnel/index.js +2 -2
- package/dist/src/tunnel/tunnel-audit.d.ts +1 -1
- package/dist/src/tunnel/tunnel-config.d.ts +1 -1
- package/dist/src/tunnel/tunnel-config.js +9 -4
- package/dist/src/tunnel/tunnel-service.d.ts +1 -1
- package/dist/src/tunnel/tunnel-service.js +3 -0
- package/dist/src/tunnel/well-known.d.ts +1 -1
- package/dist/src/tunnel/well-known.js +1 -1
- package/dist/src/tunnel/xopc-cloud-registration.d.ts +9 -0
- package/dist/src/tunnel/xopc-cloud-registration.js +42 -0
- package/dist/src/voice/stt/transcribe-core.js +17 -1
- package/dist/src/voice/stt/types.d.ts +1 -1
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/agents-DijFbC4G.js +0 -68
- package/dist/gateway/static/root/assets/apps-page-BFAmf9hq.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-B8us5JBf.js +0 -6
- package/dist/gateway/static/root/assets/block-editor-C3mwGsms.js +0 -184
- package/dist/gateway/static/root/assets/browser-settings-page-BeBd17-3.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Bv0z3KRq.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-BczD-pWE.js +0 -3
- package/dist/gateway/static/root/assets/channels-settings-2KQYq6xl.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-ByRbxC6z.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-PB1boaNy.js +0 -2
- package/dist/gateway/static/root/assets/dist-C230izr8.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-5YQ5BUwp.js +0 -1
- package/dist/gateway/static/root/assets/home-page-DfIVWJl3.js +0 -1
- package/dist/gateway/static/root/assets/index-BXGC3VFm.css +0 -2
- package/dist/gateway/static/root/assets/index-jqDCfet4.js +0 -74
- package/dist/gateway/static/root/assets/local-app-workbench-page-CAb0odzu.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-CFxKbDZl.js +0 -2
- package/dist/gateway/static/root/assets/markdown-view-DYkxMtJA.js +0 -69
- package/dist/gateway/static/root/assets/messages-kx5W39dO.js +0 -3
- package/dist/gateway/static/root/assets/notes-api-DJizatxh.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-BGjEC89c.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-Dj9kEQwg.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CBRy5Ezz.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DSwz9RBh.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-WtattyVX.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CNAz_q1F.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CNo4Ajhn.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-B7PI3yZ6.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-DpOH0zWB.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BOf4xCat.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-DrMX5Yhj.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-ewIK2ddC.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-Bdn82kFQ.js +0 -5
|
@@ -9,5 +9,5 @@ export { acquireEmbeddedSessionRunner, buildEmbeddedRunnerFingerprint, evictAllE
|
|
|
9
9
|
export { DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS, resolveLiveToolResultMaxChars, truncateToolResultMessage, } from './tool-result-truncation.js';
|
|
10
10
|
export { runXopcEmbeddedTurn, abortEmbeddedRun, queueEmbeddedSteer } from './run-turn.js';
|
|
11
11
|
export { runEmbeddedTurnForSession } from './run-for-session.js';
|
|
12
|
-
export {
|
|
12
|
+
export { getEmbeddedRunBySessionKey } from './runs.js';
|
|
13
13
|
export type { RunXopcEmbeddedTurnParams, RunXopcEmbeddedTurnResult, EmbeddedStreamEvent } from './types.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS, resolveLiveToolResultMaxChars, truncateToolResultMessage } from "./tool-result-truncation.js";
|
|
2
2
|
import { getRawSessionAppendMessage, guardSessionManager, installSessionToolResultGuard } from "./session-tool-result-guard.js";
|
|
3
3
|
import { acquireEmbeddedSessionRunner, buildEmbeddedRunnerFingerprint, evictAllEmbeddedSessionRunners, evictEmbeddedSessionRunner, getEmbeddedSessionRunnerIdleTtlMs, getEmbeddedSessionRunnerStats, isEmbeddedSessionRunnerEnabled, resetEmbeddedSessionRunnerForTest } from "./session-runner.js";
|
|
4
|
-
import { abortEmbeddedRun, getEmbeddedRunBySessionKey, queueEmbeddedSteer
|
|
4
|
+
import { abortEmbeddedRun, getEmbeddedRunBySessionKey, queueEmbeddedSteer } from "./runs.js";
|
|
5
5
|
import { repairAssistantUsageInSessionManager } from "./session-manager-init.js";
|
|
6
6
|
import { openSqliteHydratingSessionManager } from "./sqlite-hydrating-session-manager.js";
|
|
7
7
|
import { InMemoryTranscriptRuntime, createSqliteTranscriptRuntime } from "./transcript-runtime.js";
|
|
@@ -9,4 +9,4 @@ import { runXopcEmbeddedTurn } from "./run-turn.js";
|
|
|
9
9
|
import { getEmbeddedExecutionSession, runWithEmbeddedExecutionSession } from "./execution-context.js";
|
|
10
10
|
import { runEmbeddedTurnForSession } from "./run-for-session.js";
|
|
11
11
|
import { CURRENT_SESSION_VERSION, PiTranscriptManager } from "./pi-transcript.js";
|
|
12
|
-
export { CURRENT_SESSION_VERSION, DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS, InMemoryTranscriptRuntime, PiTranscriptManager, abortEmbeddedRun, acquireEmbeddedSessionRunner, buildEmbeddedRunnerFingerprint, createSqliteTranscriptRuntime, evictAllEmbeddedSessionRunners, evictEmbeddedSessionRunner, getEmbeddedExecutionSession, getEmbeddedRunBySessionKey, getEmbeddedSessionRunnerIdleTtlMs, getEmbeddedSessionRunnerStats, getRawSessionAppendMessage, guardSessionManager, installSessionToolResultGuard, isEmbeddedSessionRunnerEnabled, openSqliteHydratingSessionManager, queueEmbeddedSteer,
|
|
12
|
+
export { CURRENT_SESSION_VERSION, DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS, InMemoryTranscriptRuntime, PiTranscriptManager, abortEmbeddedRun, acquireEmbeddedSessionRunner, buildEmbeddedRunnerFingerprint, createSqliteTranscriptRuntime, evictAllEmbeddedSessionRunners, evictEmbeddedSessionRunner, getEmbeddedExecutionSession, getEmbeddedRunBySessionKey, getEmbeddedSessionRunnerIdleTtlMs, getEmbeddedSessionRunnerStats, getRawSessionAppendMessage, guardSessionManager, installSessionToolResultGuard, isEmbeddedSessionRunnerEnabled, openSqliteHydratingSessionManager, queueEmbeddedSteer, repairAssistantUsageInSessionManager, resetEmbeddedSessionRunnerForTest, resolveLiveToolResultMaxChars, runEmbeddedTurnForSession, runWithEmbeddedExecutionSession, runXopcEmbeddedTurn, truncateToolResultMessage };
|
|
@@ -8,6 +8,7 @@ import { evaluateContextBudget } from "../memory/context-budget.js";
|
|
|
8
8
|
import { resolveCompactionPolicy } from "../memory/compaction-policy.js";
|
|
9
9
|
import { runXopcEmbeddedTurn } from "./run-turn.js";
|
|
10
10
|
import { applyStartupContextToUserMessage } from "../reply/apply-turn-user-enrichment.js";
|
|
11
|
+
import { AgentRunSupervisor } from "../orchestration/agent-run-supervisor.js";
|
|
11
12
|
import crypto from "node:crypto";
|
|
12
13
|
//#region src/agent/embedded/run-for-session.ts
|
|
13
14
|
init_logger();
|
|
@@ -16,67 +17,93 @@ const log = createLogger("EmbeddedTurnForSession");
|
|
|
16
17
|
async function runEmbeddedTurnForSession(params) {
|
|
17
18
|
const { sessionKey, agentManager, modelManager, sessionStore, userMessage } = params;
|
|
18
19
|
const runId = params.runId ?? crypto.randomUUID();
|
|
19
|
-
await params.beforeTurn?.();
|
|
20
|
-
const agent = agentManager.getOrCreateAgent(sessionKey);
|
|
21
|
-
const mm = modelManager;
|
|
22
|
-
const configuredModelRef = String(mm.getModelForSession(sessionKey));
|
|
23
|
-
const candidates = typeof mm.getFallbackCandidatesForSession === "function" ? mm.getFallbackCandidatesForSession(sessionKey) : [];
|
|
24
|
-
const candidateModelRefs = candidates.length > 0 ? candidates.map((candidate) => `${candidate.provider}/${candidate.model}`) : [configuredModelRef];
|
|
25
|
-
const resolvedCandidates = [];
|
|
26
|
-
for (const [index, ref] of candidateModelRefs.entries()) try {
|
|
27
|
-
const resolved = index === 0 && typeof mm.getResolvedModelForSession === "function" ? mm.getResolvedModelForSession(sessionKey) : resolveModel(ref);
|
|
28
|
-
resolvedCandidates.push({
|
|
29
|
-
ref,
|
|
30
|
-
model: resolved
|
|
31
|
-
});
|
|
32
|
-
} catch (err) {
|
|
33
|
-
log.warn({
|
|
34
|
-
err,
|
|
35
|
-
sessionKey,
|
|
36
|
-
runId,
|
|
37
|
-
modelRef: ref
|
|
38
|
-
}, "Skipping unavailable model candidate");
|
|
39
|
-
}
|
|
40
|
-
const primary = resolvedCandidates[0];
|
|
41
|
-
if (!primary) throw new Error(`No available model candidates for '${configuredModelRef}'`);
|
|
42
|
-
const modelRef = primary.ref;
|
|
43
|
-
const model = primary.model;
|
|
44
|
-
if (typeof mm.applyResolvedModel === "function") mm.applyResolvedModel(agent, model, modelRef);
|
|
45
|
-
else await mm.applyModelForSession(agent, sessionKey);
|
|
46
|
-
agentManager.setModelForSession(sessionKey, modelRef);
|
|
47
|
-
const tools = agent.state.tools;
|
|
48
|
-
const systemPrompt = agent.state.systemPrompt ?? "";
|
|
49
|
-
const thinkingLevel = params.thinkingOverride ?? agent.state.thinkingLevel;
|
|
50
|
-
const workspaceDir = agentManager.getResolvedWorkspaceForSession(sessionKey);
|
|
51
20
|
const config = params.getConfig?.();
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (params.applyStartupContext !== false) userMessageForTurn = await applyStartupContextToUserMessage({
|
|
57
|
-
userMessage,
|
|
58
|
-
sessionKey,
|
|
59
|
-
workspaceDir,
|
|
60
|
-
cfg: config,
|
|
61
|
-
sessionStore,
|
|
62
|
-
startupAction: params.startupAction,
|
|
63
|
-
force: params.forceStartupContext
|
|
21
|
+
const supervisor = new AgentRunSupervisor({
|
|
22
|
+
timeoutMs: resolveAgentTurnTimeoutMs(config, sessionKey),
|
|
23
|
+
deadlineAtMs: params.deadlineAtMs,
|
|
24
|
+
parentSignal: params.abortSignal
|
|
64
25
|
});
|
|
65
|
-
|
|
66
|
-
await
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
26
|
+
try {
|
|
27
|
+
await params.beforeTurn?.();
|
|
28
|
+
if (supervisor.signal.aborted) return {
|
|
29
|
+
ok: false,
|
|
30
|
+
errorMessage: "aborted"
|
|
31
|
+
};
|
|
32
|
+
const agent = agentManager.getOrCreateAgent(sessionKey);
|
|
33
|
+
const mm = modelManager;
|
|
34
|
+
const configuredModelRef = String(mm.getModelForSession(sessionKey));
|
|
35
|
+
const candidates = typeof mm.getFallbackCandidatesForSession === "function" ? mm.getFallbackCandidatesForSession(sessionKey) : [];
|
|
36
|
+
const candidateModelRefs = candidates.length > 0 ? candidates.map((candidate) => `${candidate.provider}/${candidate.model}`) : [configuredModelRef];
|
|
37
|
+
const resolvedCandidates = [];
|
|
38
|
+
for (const [index, ref] of candidateModelRefs.entries()) try {
|
|
39
|
+
const resolved = index === 0 && typeof mm.getResolvedModelForSession === "function" ? mm.getResolvedModelForSession(sessionKey) : resolveModel(ref);
|
|
40
|
+
resolvedCandidates.push({
|
|
41
|
+
ref,
|
|
42
|
+
model: resolved
|
|
43
|
+
});
|
|
44
|
+
} catch (err) {
|
|
45
|
+
log.warn({
|
|
46
|
+
err,
|
|
47
|
+
sessionKey,
|
|
48
|
+
runId,
|
|
49
|
+
modelRef: ref
|
|
50
|
+
}, "Skipping unavailable model candidate");
|
|
51
|
+
}
|
|
52
|
+
const primary = resolvedCandidates[0];
|
|
53
|
+
if (!primary) throw new Error(`No available model candidates for '${configuredModelRef}'`);
|
|
54
|
+
const modelRef = primary.ref;
|
|
55
|
+
const model = primary.model;
|
|
56
|
+
if (typeof mm.applyResolvedModel === "function") mm.applyResolvedModel(agent, model, modelRef);
|
|
57
|
+
else await mm.applyModelForSession(agent, sessionKey);
|
|
58
|
+
agentManager.setModelForSession(sessionKey, modelRef);
|
|
59
|
+
const tools = agent.state.tools;
|
|
60
|
+
const turnPolicy = agentManager.createAgentTurnPolicy(sessionKey);
|
|
61
|
+
const systemPrompt = agent.state.systemPrompt ?? "";
|
|
62
|
+
const thinkingLevel = params.thinkingOverride ?? agent.state.thinkingLevel;
|
|
63
|
+
const workspaceDir = agentManager.getResolvedWorkspaceForSession(sessionKey);
|
|
64
|
+
const promptCachePolicy = resolvePromptCachePolicy(config ? resolveEffectiveAgentProfileForSession(config, sessionKey).manifest.runtime?.promptCache : void 0);
|
|
65
|
+
let userMessageForTurn = userMessage;
|
|
66
|
+
if (params.applyStartupContext !== false) {
|
|
67
|
+
userMessageForTurn = await applyStartupContextToUserMessage({
|
|
68
|
+
userMessage,
|
|
69
|
+
sessionKey,
|
|
70
|
+
workspaceDir,
|
|
71
|
+
cfg: config,
|
|
72
|
+
sessionStore,
|
|
73
|
+
startupAction: params.startupAction,
|
|
74
|
+
force: params.forceStartupContext
|
|
75
|
+
});
|
|
76
|
+
if (supervisor.signal.aborted) return {
|
|
77
|
+
ok: false,
|
|
78
|
+
errorMessage: "aborted"
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
await maybeAutoCompactBeforeTurn({
|
|
83
|
+
sessionKey,
|
|
84
|
+
sessionStore,
|
|
85
|
+
agentManager,
|
|
86
|
+
model,
|
|
87
|
+
config,
|
|
88
|
+
systemPrompt,
|
|
89
|
+
userMessage: userMessageForTurn,
|
|
90
|
+
tools,
|
|
91
|
+
imageCount: params.llmImages?.length ?? 0,
|
|
92
|
+
fallbackModels: resolvedCandidates.slice(1).map((candidate) => candidate.model),
|
|
93
|
+
abortSignal: supervisor.signal,
|
|
94
|
+
onEvent: params.onEvent
|
|
95
|
+
});
|
|
96
|
+
} catch (err) {
|
|
97
|
+
if (supervisor.signal.aborted) return {
|
|
98
|
+
ok: false,
|
|
99
|
+
errorMessage: "aborted"
|
|
100
|
+
};
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
if (supervisor.signal.aborted) return {
|
|
104
|
+
ok: false,
|
|
105
|
+
errorMessage: "aborted"
|
|
106
|
+
};
|
|
80
107
|
log.info({
|
|
81
108
|
sessionKey,
|
|
82
109
|
runId,
|
|
@@ -94,6 +121,14 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
94
121
|
const isFallbackAttempt = i > 0;
|
|
95
122
|
const candidateModel = candidate.model;
|
|
96
123
|
const hasNextCandidate = i + 1 < resolvedCandidates.length;
|
|
124
|
+
const attemptPlan = supervisor.planModelAttempt(isFallbackAttempt);
|
|
125
|
+
if (attemptPlan.ok === false) {
|
|
126
|
+
lastResult = {
|
|
127
|
+
ok: false,
|
|
128
|
+
errorMessage: attemptPlan.reason
|
|
129
|
+
};
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
97
132
|
const rowsBeforeAttempt = hasNextCandidate ? await sessionStore.loadTranscriptRows(sessionKey) : void 0;
|
|
98
133
|
if (typeof mm.applyResolvedModel === "function") mm.applyResolvedModel(agent, candidateModel, candidateModelRef);
|
|
99
134
|
agentManager.setModelForSession(sessionKey, candidateModelRef);
|
|
@@ -119,8 +154,9 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
119
154
|
promptCachePolicy,
|
|
120
155
|
workspaceDir,
|
|
121
156
|
sessionStore,
|
|
122
|
-
timeoutMs:
|
|
123
|
-
|
|
157
|
+
timeoutMs: attemptPlan.timeoutMs,
|
|
158
|
+
turnPolicy,
|
|
159
|
+
abortSignal: supervisor.signal,
|
|
124
160
|
onEvent: params.onEvent,
|
|
125
161
|
resumeLastUserMessage
|
|
126
162
|
});
|
|
@@ -136,6 +172,7 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
136
172
|
return turnResult;
|
|
137
173
|
}
|
|
138
174
|
lastResult = turnResult;
|
|
175
|
+
if (supervisor.signal.aborted || turnResult.retryable === false) break;
|
|
139
176
|
log.warn({
|
|
140
177
|
sessionKey,
|
|
141
178
|
runId,
|
|
@@ -179,7 +216,9 @@ async function runEmbeddedTurnForSession(params) {
|
|
|
179
216
|
ok: false,
|
|
180
217
|
errorMessage: "No model candidates available"
|
|
181
218
|
};
|
|
182
|
-
}
|
|
219
|
+
} finally {
|
|
220
|
+
supervisor.dispose();
|
|
221
|
+
}
|
|
183
222
|
}
|
|
184
223
|
function serializedTranscriptBytes(messages) {
|
|
185
224
|
return Buffer.byteLength(JSON.stringify(messages), "utf8");
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "../orchestration/run-agent-turn-with-timeout.js";
|
|
3
|
+
import { isAgentTurnUnsettledError, resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "../orchestration/run-agent-turn-with-timeout.js";
|
|
4
4
|
import { resolvePromptCachePolicy } from "../../providers/prompt-cache-plan.js";
|
|
5
5
|
import { wrapStreamFnForXopcExtensions } from "./xopc-stream-bridge.js";
|
|
6
|
-
import { acquireEmbeddedSessionRunner } from "./session-runner.js";
|
|
6
|
+
import { acquireEmbeddedSessionRunner, evictEmbeddedSessionRunner } from "./session-runner.js";
|
|
7
|
+
import { isContextOverflowError } from "../orchestration/context-overflow.js";
|
|
7
8
|
import { getAssistantTurnErrorMessage, isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure, stripTrailingErrorAssistantMessages } from "../orchestration/llm-turn-retry.js";
|
|
8
9
|
import { projectContextForModel } from "../memory/context-budget.js";
|
|
9
|
-
import {
|
|
10
|
+
import { EmbeddedRunConflictError, abortEmbeddedRun, acquireEmbeddedRunLease, queueEmbeddedSteer } from "./runs.js";
|
|
10
11
|
import { lastAssistantPlainText, subscribeEmbeddedSessionEvents } from "./subscribe-session.js";
|
|
11
12
|
import { detectToolLoops } from "../orchestration/loop-guard.js";
|
|
12
13
|
import { tryApplySessionTranscriptHygiene } from "../transcript/transcript-hygiene.js";
|
|
13
14
|
import { createSqliteTranscriptRuntime } from "./transcript-runtime.js";
|
|
14
|
-
import { isContextOverflowError } from "../orchestration/context-overflow.js";
|
|
15
15
|
import { buildPromptCacheSnapshot, observePromptCacheSnapshot } from "../../providers/prompt-cache-observability.js";
|
|
16
16
|
import { isPromptCacheExpired, recordPromptCacheTouch } from "../../providers/prompt-cache-lifecycle.js";
|
|
17
17
|
//#region src/agent/embedded/run-turn.ts
|
|
@@ -83,9 +83,10 @@ async function maybeRecoverContextOverflow(params) {
|
|
|
83
83
|
type: "compaction",
|
|
84
84
|
status: "started"
|
|
85
85
|
});
|
|
86
|
-
const result = await params.transcriptRuntime.compact(messages, params.model, "Preserve the current pending user request verbatim and retain every fact needed to answer it.", true);
|
|
86
|
+
const result = await params.transcriptRuntime.compact(messages, params.model, "Preserve the current pending user request verbatim and retain every fact needed to answer it.", true, { signal: params.abortSignal });
|
|
87
87
|
if (!result.compacted) throw new Error(`Context overflow recovery could not find a safe compaction range: ${errorMessage}`);
|
|
88
88
|
params.agent.state.messages = await params.transcriptRuntime.loadMessages();
|
|
89
|
+
params.abortSignal?.throwIfAborted();
|
|
89
90
|
params.onEvent?.({
|
|
90
91
|
type: "compaction",
|
|
91
92
|
status: "completed",
|
|
@@ -109,7 +110,14 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
109
110
|
if (!transcriptRuntime) throw new Error("Embedded run requires a transcript runtime");
|
|
110
111
|
let runner;
|
|
111
112
|
let unsubscribe;
|
|
113
|
+
let quarantineRunner = false;
|
|
114
|
+
let runLease;
|
|
112
115
|
try {
|
|
116
|
+
runLease = acquireEmbeddedRunLease({
|
|
117
|
+
sessionKey,
|
|
118
|
+
sessionId: transcriptRuntime.sessionId,
|
|
119
|
+
runId
|
|
120
|
+
});
|
|
113
121
|
runner = await acquireEmbeddedSessionRunner({
|
|
114
122
|
runtimeId: transcriptRuntime.runtimeId,
|
|
115
123
|
sessionId: transcriptRuntime.sessionId,
|
|
@@ -122,6 +130,15 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
122
130
|
transcriptRuntime
|
|
123
131
|
});
|
|
124
132
|
const { session, reused } = runner;
|
|
133
|
+
await runLease.attach(session, async () => session.abort());
|
|
134
|
+
const runAbortSignal = params.abortSignal ? AbortSignal.any([runLease.signal, params.abortSignal]) : runLease.signal;
|
|
135
|
+
if (runAbortSignal.aborted) {
|
|
136
|
+
await session.abort();
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
errorMessage: "aborted"
|
|
140
|
+
};
|
|
141
|
+
}
|
|
125
142
|
runner.piSm.setActiveTurnId?.(runId);
|
|
126
143
|
const streamFnWithXopcExtensions = wrapStreamFnForXopcExtensions(session.agent.streamFunction, params.promptCachePolicy);
|
|
127
144
|
const loggingStreamFn = (streamModel, context, options) => {
|
|
@@ -197,6 +214,10 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
197
214
|
return streamFnWithXopcExtensions(streamModel, effectiveContext, { ...options });
|
|
198
215
|
};
|
|
199
216
|
session.agent.streamFunction = loggingStreamFn;
|
|
217
|
+
params.turnPolicy?.reset();
|
|
218
|
+
session.agent.beforeToolCall = params.turnPolicy?.beforeToolCall;
|
|
219
|
+
session.agent.afterToolCall = params.turnPolicy?.afterToolCall;
|
|
220
|
+
session.agent.shouldStopAfterTurn = params.turnPolicy?.shouldStopAfterTurn;
|
|
200
221
|
unsubscribe = subscribeEmbeddedSessionEvents(session, (event) => {
|
|
201
222
|
if (event.type === "message_end" && event.message.role === "assistant") recordPromptCacheTouch(sessionKey, resolvedModel, event.message.usage);
|
|
202
223
|
onEvent?.({
|
|
@@ -204,29 +225,10 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
204
225
|
runId
|
|
205
226
|
});
|
|
206
227
|
});
|
|
207
|
-
const handle = {
|
|
208
|
-
sessionKey,
|
|
209
|
-
sessionId: transcriptRuntime.sessionId,
|
|
210
|
-
runId,
|
|
211
|
-
session,
|
|
212
|
-
abort: async () => {
|
|
213
|
-
await session.abort();
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
registerEmbeddedRun(handle);
|
|
217
228
|
const abortListener = () => {
|
|
218
229
|
session.abort();
|
|
219
230
|
};
|
|
220
|
-
|
|
221
|
-
if (params.abortSignal.aborted) {
|
|
222
|
-
await session.abort();
|
|
223
|
-
return {
|
|
224
|
-
ok: false,
|
|
225
|
-
errorMessage: "aborted"
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
params.abortSignal.addEventListener("abort", abortListener, { once: true });
|
|
229
|
-
}
|
|
231
|
+
runAbortSignal.addEventListener("abort", abortListener, { once: true });
|
|
230
232
|
try {
|
|
231
233
|
await runAgentTurnWithTimeout(session.agent, async () => {
|
|
232
234
|
if (params.resumeLastUserMessage) await session.agent.continue();
|
|
@@ -238,16 +240,22 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
238
240
|
await session.agent.waitForIdle();
|
|
239
241
|
await maybeRetryTurnAfterTransientLlmFailure(session.agent, {
|
|
240
242
|
sessionKey,
|
|
241
|
-
log
|
|
243
|
+
log,
|
|
244
|
+
signal: runAbortSignal
|
|
242
245
|
});
|
|
243
246
|
await maybeRecoverContextOverflow({
|
|
244
247
|
agent: session.agent,
|
|
245
248
|
model: resolvedModel,
|
|
246
249
|
sessionKey,
|
|
247
250
|
transcriptRuntime,
|
|
251
|
+
abortSignal: runAbortSignal,
|
|
248
252
|
onEvent
|
|
249
253
|
});
|
|
250
254
|
}, timeoutMs);
|
|
255
|
+
if (runAbortSignal.aborted) return {
|
|
256
|
+
ok: false,
|
|
257
|
+
errorMessage: "aborted"
|
|
258
|
+
};
|
|
251
259
|
if (isAssistantTurnAborted(session.agent)) return {
|
|
252
260
|
ok: true,
|
|
253
261
|
lastAssistantText: lastAssistantPlainText(session)
|
|
@@ -262,10 +270,28 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
262
270
|
lastAssistantText: lastAssistantPlainText(session)
|
|
263
271
|
};
|
|
264
272
|
} finally {
|
|
265
|
-
|
|
266
|
-
unregisterEmbeddedRun(handle);
|
|
273
|
+
runAbortSignal.removeEventListener("abort", abortListener);
|
|
267
274
|
}
|
|
268
275
|
} catch (err) {
|
|
276
|
+
if (err instanceof EmbeddedRunConflictError) {
|
|
277
|
+
const em = err.message;
|
|
278
|
+
log.warn({
|
|
279
|
+
sessionKey,
|
|
280
|
+
runId,
|
|
281
|
+
activeRunId: err.activeRunId
|
|
282
|
+
}, `Embedded run rejected: ${em}`);
|
|
283
|
+
onEvent?.({
|
|
284
|
+
type: "error",
|
|
285
|
+
content: em,
|
|
286
|
+
runId
|
|
287
|
+
});
|
|
288
|
+
return {
|
|
289
|
+
ok: false,
|
|
290
|
+
retryable: false,
|
|
291
|
+
errorMessage: em
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
quarantineRunner = isAgentTurnUnsettledError(err);
|
|
269
295
|
const em = err instanceof Error ? err.message : String(err);
|
|
270
296
|
log.error({
|
|
271
297
|
err,
|
|
@@ -282,11 +308,13 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
282
308
|
errorMessage: em
|
|
283
309
|
};
|
|
284
310
|
} finally {
|
|
311
|
+
runLease?.release();
|
|
285
312
|
unsubscribe?.();
|
|
286
313
|
try {
|
|
287
314
|
runner?.piSm.flushPendingToolResults?.();
|
|
288
315
|
} catch {}
|
|
289
316
|
runner?.piSm.setActiveTurnId?.(null);
|
|
317
|
+
if (quarantineRunner) evictEmbeddedSessionRunner(transcriptRuntime.runtimeId, "unsettled_after_timeout");
|
|
290
318
|
runner?.release();
|
|
291
319
|
}
|
|
292
320
|
}
|
|
@@ -1,46 +1,33 @@
|
|
|
1
1
|
import type { AgentSession } from '@earendil-works/pi-coding-agent';
|
|
2
|
-
export type
|
|
2
|
+
export type EmbeddedRunIdentity = {
|
|
3
3
|
sessionKey: string;
|
|
4
4
|
sessionId: string;
|
|
5
5
|
runId: string;
|
|
6
|
+
};
|
|
7
|
+
export type EmbeddedRunHandle = EmbeddedRunIdentity & {
|
|
6
8
|
session: AgentSession;
|
|
7
9
|
abort: () => Promise<void>;
|
|
8
10
|
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export declare class EmbeddedRunConflictError extends Error {
|
|
12
|
+
readonly sessionKey: string;
|
|
13
|
+
readonly activeRunId: string;
|
|
14
|
+
constructor(sessionKey: string, activeRunId: string);
|
|
15
|
+
}
|
|
16
|
+
export type EmbeddedRunLease = {
|
|
17
|
+
signal: AbortSignal;
|
|
18
|
+
attach(session: AgentSession, abort: () => Promise<void>): Promise<void>;
|
|
19
|
+
release(): void;
|
|
20
|
+
};
|
|
21
|
+
/** Owns one process-local execution lease per session while leaving steer/abort on the control plane. */
|
|
16
22
|
export declare class EmbeddedRunRegistry {
|
|
17
23
|
private readonly bySessionKey;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Register a new in-flight run. If a run is already registered for the same
|
|
21
|
-
* sessionKey we drop the stale handle (the new run takes ownership). The caller
|
|
22
|
-
* is responsible for aborting the previous run before re-registering if needed —
|
|
23
|
-
* we warn loudly so this does not happen silently.
|
|
24
|
-
*/
|
|
25
|
-
register(handle: EmbeddedRunHandle): void;
|
|
26
|
-
unregister(handle: EmbeddedRunHandle): void;
|
|
24
|
+
acquire(identity: EmbeddedRunIdentity): EmbeddedRunLease;
|
|
27
25
|
getBySessionKey(sessionKey: string): EmbeddedRunHandle | undefined;
|
|
28
|
-
getByRunId(runId: string): EmbeddedRunHandle | undefined;
|
|
29
26
|
abortBySessionKey(sessionKey: string): Promise<boolean>;
|
|
30
27
|
steerBySessionKey(sessionKey: string, text: string): Promise<boolean>;
|
|
31
|
-
/** Test-only helper to drop all registrations without touching live sessions. */
|
|
32
|
-
resetForTest(): void;
|
|
33
28
|
size(): number;
|
|
34
29
|
}
|
|
35
|
-
|
|
36
|
-
* Process-wide default registry. Prefer constructing a dedicated `EmbeddedRunRegistry`
|
|
37
|
-
* and injecting it; the module-level singleton stays so the existing free functions
|
|
38
|
-
* keep working until every caller has been migrated.
|
|
39
|
-
*/
|
|
40
|
-
export declare const defaultEmbeddedRunRegistry: EmbeddedRunRegistry;
|
|
41
|
-
export declare function registerEmbeddedRun(handle: EmbeddedRunHandle): void;
|
|
42
|
-
export declare function unregisterEmbeddedRun(handle: EmbeddedRunHandle): void;
|
|
30
|
+
export declare function acquireEmbeddedRunLease(identity: EmbeddedRunIdentity): EmbeddedRunLease;
|
|
43
31
|
export declare function getEmbeddedRunBySessionKey(sessionKey: string): EmbeddedRunHandle | undefined;
|
|
44
|
-
export declare function getEmbeddedRunByRunId(runId: string): EmbeddedRunHandle | undefined;
|
|
45
32
|
export declare function abortEmbeddedRun(sessionKey: string): Promise<boolean>;
|
|
46
33
|
export declare function queueEmbeddedSteer(sessionKey: string, text: string): Promise<boolean>;
|
|
@@ -1,91 +1,70 @@
|
|
|
1
|
-
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../../utils/logger.js";
|
|
3
1
|
//#region src/agent/embedded/runs.ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*/
|
|
2
|
+
var EmbeddedRunConflictError = class extends Error {
|
|
3
|
+
constructor(sessionKey, activeRunId) {
|
|
4
|
+
super(`Session '${sessionKey}' already has active embedded run '${activeRunId}'`);
|
|
5
|
+
this.sessionKey = sessionKey;
|
|
6
|
+
this.activeRunId = activeRunId;
|
|
7
|
+
this.name = "EmbeddedRunConflictError";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
/** Owns one process-local execution lease per session while leaving steer/abort on the control plane. */
|
|
13
11
|
var EmbeddedRunRegistry = class {
|
|
14
12
|
bySessionKey = /* @__PURE__ */ new Map();
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.byRunId.delete(handle.runId);
|
|
13
|
+
acquire(identity) {
|
|
14
|
+
const active = this.bySessionKey.get(identity.sessionKey);
|
|
15
|
+
if (active) throw new EmbeddedRunConflictError(identity.sessionKey, active.runId);
|
|
16
|
+
const entry = {
|
|
17
|
+
...identity,
|
|
18
|
+
abortController: new AbortController()
|
|
19
|
+
};
|
|
20
|
+
this.bySessionKey.set(identity.sessionKey, entry);
|
|
21
|
+
return {
|
|
22
|
+
signal: entry.abortController.signal,
|
|
23
|
+
attach: async (session, abort) => {
|
|
24
|
+
entry.handle = {
|
|
25
|
+
...identity,
|
|
26
|
+
session,
|
|
27
|
+
abort
|
|
28
|
+
};
|
|
29
|
+
if (entry.abortController.signal.aborted) await abort();
|
|
30
|
+
},
|
|
31
|
+
release: () => {
|
|
32
|
+
if (this.bySessionKey.get(identity.sessionKey) === entry) this.bySessionKey.delete(identity.sessionKey);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
38
35
|
}
|
|
39
36
|
getBySessionKey(sessionKey) {
|
|
40
|
-
return this.bySessionKey.get(sessionKey);
|
|
41
|
-
}
|
|
42
|
-
getByRunId(runId) {
|
|
43
|
-
return this.byRunId.get(runId);
|
|
37
|
+
return this.bySessionKey.get(sessionKey)?.handle;
|
|
44
38
|
}
|
|
45
39
|
async abortBySessionKey(sessionKey) {
|
|
46
|
-
const
|
|
47
|
-
if (!
|
|
48
|
-
|
|
40
|
+
const entry = this.bySessionKey.get(sessionKey);
|
|
41
|
+
if (!entry) return false;
|
|
42
|
+
entry.abortController.abort(/* @__PURE__ */ new Error("Embedded run aborted"));
|
|
43
|
+
if (entry.handle) await entry.handle.abort();
|
|
49
44
|
return true;
|
|
50
45
|
}
|
|
51
46
|
async steerBySessionKey(sessionKey, text) {
|
|
52
|
-
const handle = this.
|
|
47
|
+
const handle = this.getBySessionKey(sessionKey);
|
|
53
48
|
if (!handle) return false;
|
|
54
49
|
await handle.session.steer(text);
|
|
55
50
|
return true;
|
|
56
51
|
}
|
|
57
|
-
/** Test-only helper to drop all registrations without touching live sessions. */
|
|
58
|
-
resetForTest() {
|
|
59
|
-
this.bySessionKey.clear();
|
|
60
|
-
this.byRunId.clear();
|
|
61
|
-
}
|
|
62
52
|
size() {
|
|
63
53
|
return this.bySessionKey.size;
|
|
64
54
|
}
|
|
65
55
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
* keep working until every caller has been migrated.
|
|
70
|
-
*/
|
|
71
|
-
const defaultEmbeddedRunRegistry = new EmbeddedRunRegistry();
|
|
72
|
-
function registerEmbeddedRun(handle) {
|
|
73
|
-
defaultEmbeddedRunRegistry.register(handle);
|
|
74
|
-
}
|
|
75
|
-
function unregisterEmbeddedRun(handle) {
|
|
76
|
-
defaultEmbeddedRunRegistry.unregister(handle);
|
|
56
|
+
const embeddedRunRegistry = new EmbeddedRunRegistry();
|
|
57
|
+
function acquireEmbeddedRunLease(identity) {
|
|
58
|
+
return embeddedRunRegistry.acquire(identity);
|
|
77
59
|
}
|
|
78
60
|
function getEmbeddedRunBySessionKey(sessionKey) {
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
function getEmbeddedRunByRunId(runId) {
|
|
82
|
-
return defaultEmbeddedRunRegistry.getByRunId(runId);
|
|
61
|
+
return embeddedRunRegistry.getBySessionKey(sessionKey);
|
|
83
62
|
}
|
|
84
63
|
function abortEmbeddedRun(sessionKey) {
|
|
85
|
-
return
|
|
64
|
+
return embeddedRunRegistry.abortBySessionKey(sessionKey);
|
|
86
65
|
}
|
|
87
66
|
function queueEmbeddedSteer(sessionKey, text) {
|
|
88
|
-
return
|
|
67
|
+
return embeddedRunRegistry.steerBySessionKey(sessionKey, text);
|
|
89
68
|
}
|
|
90
69
|
//#endregion
|
|
91
|
-
export { EmbeddedRunRegistry, abortEmbeddedRun,
|
|
70
|
+
export { EmbeddedRunConflictError, EmbeddedRunRegistry, abortEmbeddedRun, acquireEmbeddedRunLease, getEmbeddedRunBySessionKey, queueEmbeddedSteer };
|
|
@@ -2,6 +2,7 @@ import type { AgentMessage, AgentToolResult, ThinkingLevel } from '@earendil-wor
|
|
|
2
2
|
import type { AssistantMessageEvent, Model, Api, ImageContent } from '@earendil-works/pi-ai';
|
|
3
3
|
import type { SessionStore } from '../../session/store.js';
|
|
4
4
|
import type { EmbeddedTranscriptRuntime } from './transcript-runtime.js';
|
|
5
|
+
import type { AgentTurnPolicy } from '../orchestration/agent-turn-policy.js';
|
|
5
6
|
export type EmbeddedStreamEvent = {
|
|
6
7
|
type: 'agent_start';
|
|
7
8
|
runId?: string;
|
|
@@ -97,6 +98,7 @@ export type RunXopcEmbeddedTurnParams = {
|
|
|
97
98
|
sessionStore?: SessionStore;
|
|
98
99
|
transcriptRuntime?: EmbeddedTranscriptRuntime;
|
|
99
100
|
timeoutMs: number;
|
|
101
|
+
turnPolicy?: AgentTurnPolicy;
|
|
100
102
|
abortSignal?: AbortSignal;
|
|
101
103
|
onEvent?: (event: EmbeddedStreamEvent) => void;
|
|
102
104
|
images?: ImageContent[];
|
|
@@ -105,6 +107,8 @@ export type RunXopcEmbeddedTurnParams = {
|
|
|
105
107
|
};
|
|
106
108
|
export type RunXopcEmbeddedTurnResult = {
|
|
107
109
|
ok: boolean;
|
|
110
|
+
/** False for harness failures that must not trigger another model attempt. */
|
|
111
|
+
retryable?: boolean;
|
|
108
112
|
errorMessage?: string;
|
|
109
113
|
lastAssistantText?: string;
|
|
110
114
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type ModelAttemptPlan = {
|
|
2
|
+
ok: true;
|
|
3
|
+
timeoutMs: number;
|
|
4
|
+
remainingMs: number;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
reason: string;
|
|
8
|
+
};
|
|
9
|
+
export interface AgentRunSupervisorOptions {
|
|
10
|
+
timeoutMs: number;
|
|
11
|
+
deadlineAtMs?: number;
|
|
12
|
+
parentSignal?: AbortSignal;
|
|
13
|
+
minimumFallbackMs?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Minimal run-level coordination: root cancellation and per-attempt deadline planning. */
|
|
16
|
+
export declare class AgentRunSupervisor {
|
|
17
|
+
readonly deadlineAtMs: number;
|
|
18
|
+
readonly signal: AbortSignal;
|
|
19
|
+
private readonly controller;
|
|
20
|
+
private readonly timeout;
|
|
21
|
+
private readonly forwardParentAbort;
|
|
22
|
+
private readonly timeoutMs;
|
|
23
|
+
private readonly minimumFallbackMs;
|
|
24
|
+
private readonly parentSignal?;
|
|
25
|
+
constructor(options: AgentRunSupervisorOptions);
|
|
26
|
+
planModelAttempt(isFallback: boolean): ModelAttemptPlan;
|
|
27
|
+
dispose(): void;
|
|
28
|
+
}
|