@xopcai/xopc 0.0.197 → 0.0.200
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/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-BwmdJ5pv.js → activity-store-DYVN1hRp.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-C5st7lt5.js → agent-avatar-dicebear-eMarz29u.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DeLW-454.js +68 -0
- package/dist/gateway/static/root/assets/{api-BM1hNzjw.js → api-B8mzbAle.js} +1 -1
- package/dist/gateway/static/root/assets/app-management-settings-panel-yfb68wq9.js +1 -0
- package/dist/gateway/static/root/assets/appearance-settings-B8SPknFM.js +1 -0
- package/dist/gateway/static/root/assets/apps-page-Bmor22Ny.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-qL07mwnY.js → archive-plugin-DmYRiOP3.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CqSobpdi.js → attachment-load-D66JvcPi.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-Q4e8m11h.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DBRPyLYE.js → binary-plugins-ChIsZArT.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-6wG1LU7t.js → block-editor-Ck-k_d0Z.js} +4 -4
- package/dist/gateway/static/root/assets/browser-settings-page--uVL73Sb.js +8 -0
- package/dist/gateway/static/root/assets/browser-workflow-inputs-_ndaecsf.js +1 -0
- package/dist/gateway/static/root/assets/{browser-workflows-page-BEu3E0et.js → browser-workflows-page-BC5jm1zL.js} +2 -2
- package/dist/gateway/static/root/assets/button-CSEbl4zT.js +1 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DXpf3QYN.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-BoOzFotX.js → capability-presets-api-Dy1jZJKs.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-NAjCsrTi.js +3 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-_8IiTxRB.js → channel-recipient-api-D-9qiuio.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-CiWUo7jW.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-B4Rbh3bM.js +1 -0
- package/dist/gateway/static/root/assets/connectors-api-5xiCRVUS.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-DOwlMseU.js +2 -0
- package/dist/gateway/static/root/assets/copy-Dv6d4Dvw.js +1 -0
- package/dist/gateway/static/root/assets/cron-expression-B3PebXKZ.js +2 -0
- package/dist/gateway/static/root/assets/date-picker-C1Vke7Xn.js +1 -0
- package/dist/gateway/static/root/assets/dependency-picker-FrQ0tsBC.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-CsLR4pWB.js → desktop-pet-CPBAzNJi.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-D6s3glDP.js +1 -0
- package/dist/gateway/static/root/assets/directory-picker-path-field-CbNQ7QQS.js +1 -0
- package/dist/gateway/static/root/assets/dist-BPoKqzeH.js +1 -0
- package/dist/gateway/static/root/assets/dist-DY4Af0fY.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-CD73euAM.js → extension-debug-page-dTK14hUv.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DAKjpNwd.js → extension-page-Cpdj1Kip.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-iNHUZGd5.js +1 -0
- package/dist/gateway/static/root/assets/external-link-DjqjBmc3.js +1 -0
- package/dist/gateway/static/root/assets/form-field-width-DJw_jULe.js +1 -0
- package/dist/gateway/static/root/assets/gateway-config-api-SvMvWqMM.js +1 -0
- package/dist/gateway/static/root/assets/gateway-config-swr-jB0hAhWO.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-BilR3dGZ.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry--2njcDpC.js → gateway-startup-retry-C-fRlHCL.js} +1 -1
- package/dist/gateway/static/root/assets/globe-DSSGFWFn.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-zK40dcQ5.js +1 -0
- package/dist/gateway/static/root/assets/home-page-NyXy5MLr.js +3 -0
- package/dist/gateway/static/root/assets/index-Bp8I_eX4.css +1 -0
- package/dist/gateway/static/root/assets/index-CCK8zdlS.js +152 -0
- package/dist/gateway/static/root/assets/interaction-BmQogeqz.js +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-HMhxgOuD.js → keyboard-shortcuts-settings-nKzsroud.js} +1 -1
- package/dist/gateway/static/root/assets/loader-circle-CifKLtgG.js +1 -0
- package/dist/gateway/static/root/assets/local-app-workbench-page-Ds3sPXTh.js +2 -0
- package/dist/gateway/static/root/assets/local-apps-page-DV1s_FYh.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-Bjvw7jtg.js → locale-store-xULEcFVs.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-Biz4eA02.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-D7KjYgHu.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-split-DvVBewS4.js → markdown-split-CTYbpkrd.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-YVj7NVzD.js → media-plugins-BXYnaiZ6.js} +1 -1
- package/dist/gateway/static/root/assets/messages-3qRsLZuX.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-BDzuL2I9.js → notes-page-CWWVXpw5.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-DnBkQihH.js +4 -0
- package/dist/gateway/static/root/assets/page-tabs-BaEQMYm_.js +1 -0
- package/dist/gateway/static/root/assets/popover-select-BzdnTy3h.js +1 -0
- package/dist/gateway/static/root/assets/preview-open-alternatives-pimQAkeI.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-Bwx_CQht.js → product-open-page-BoYSS_YR.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-ZO7t1UkB.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-By-vq41g.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-C0C_Y9d0.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Fe05Nus6.js → runtime-tools-settings-panel-DT8flaX1.js} +4 -4
- package/dist/gateway/static/root/assets/schema-form-DabEP-UI.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-BNlVwUzV.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CxYBQDaM.js +1 -0
- package/dist/gateway/static/root/assets/settings-form-draft-Dy10ldo8.js +1 -0
- package/dist/gateway/static/root/assets/settings-form-section-DCsfZAtC.js +1 -0
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-BRE_-7Da.js → settings-loading-skeleton-Dac6Yd0T.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-C1zxCpqB.js → settings-page-BDoYoEar.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-layout-BRQNel6r.js +1 -0
- package/dist/gateway/static/root/assets/settings-shell-dialog-layer-BU3UuiJr.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-DWijJ1rw.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-ie9I2_7h.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-DU9VrJLf.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-C5RaIvoE.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-N0YhaR5S.js +2 -0
- package/dist/gateway/static/root/assets/{skills-page.utils-CYwFWTso.js → skills-page.utils-C639DLXr.js} +1 -1
- package/dist/gateway/static/root/assets/system-settings-panel-CpshpQtC.js +1 -0
- package/dist/gateway/static/root/assets/task-detail-page-DsTocYkK.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-DtxpMC5S.js → theme-store-CHQRiuCF.js} +1 -1
- package/dist/gateway/static/root/assets/tool-activity-R8V9l6nk.js +1 -0
- package/dist/gateway/static/root/assets/typed-models-lib-q5-Vfqd8.js +1 -0
- package/dist/gateway/static/root/assets/use-autosave-ms6rDy59.js +1 -0
- package/dist/gateway/static/root/assets/user-context-page-BUxIemwy.js +1 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-CObrQWh2.js +1 -0
- package/dist/gateway/static/root/assets/work-discovery-overlay-BBxrnEFt.js +1 -0
- package/dist/gateway/static/root/assets/work-discovery-page-DN3l-HW3.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DqIb1oBB.js → workflow-run-setup-panel-BxXhe3IV.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-BCHkjd1i.js +5 -0
- package/dist/gateway/static/root/assets/working-directory-picker-modal-D-IgcHPp.js +1 -0
- package/dist/gateway/static/root/index.html +23 -8
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/tasks.js +103 -9
- package/dist/src/agent/agent-manager.d.ts +1 -0
- package/dist/src/agent/agent-manager.js +1 -0
- package/dist/src/agent/context/execution-scope.js +3 -1
- package/dist/src/agent/service.js +1 -0
- package/dist/src/agent/service.types.d.ts +1 -0
- package/dist/src/agent/tasks/task-judge-service.d.ts +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +3 -2
- package/dist/src/agent/tools/factory.d.ts +2 -0
- package/dist/src/agent/tools/factory.js +2 -1
- package/dist/src/agent/tools/xopc-use-tool.d.ts +1 -0
- package/dist/src/agent/tools/xopc-use-tool.js +69 -9
- package/dist/src/automations/domain/validation.d.ts +40 -12
- package/dist/src/automations/draft/automation-draft-validator.d.ts +4 -4
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/rules.js +2 -2
- package/dist/src/gateway/hono/app.d.ts +2 -0
- package/dist/src/gateway/hono/app.js +10 -3
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +8 -1
- package/dist/src/gateway/hono/routes/agent-stream.js +2 -74
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -1
- package/dist/src/gateway/hono/routes/config.js +9 -0
- package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
- package/dist/src/gateway/hono/routes/projects.js +55 -0
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +62 -0
- package/dist/src/gateway/hono/routes/session-input-handler.js +82 -0
- package/dist/src/gateway/hono/routes/tasks.js +272 -20
- package/dist/src/gateway/host.d.ts +9 -1
- package/dist/src/gateway/host.js +22 -5
- package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
- package/dist/src/gateway/rate-limit/buckets.js +12 -0
- package/dist/src/gateway/runtime-config.js +6 -5
- package/dist/src/gateway/security/audit.js +0 -7
- package/dist/src/gateway/server.js +4 -1
- package/dist/src/gateway/service/task-conversation-query-service.d.ts +58 -0
- package/dist/src/gateway/service/task-conversation-query-service.js +84 -0
- package/dist/src/gateway/service.d.ts +11 -0
- package/dist/src/gateway/service.js +75 -38
- package/dist/src/proactive/actions/service.d.ts +2 -0
- package/dist/src/proactive/actions/service.js +80 -0
- package/dist/src/proactive/execution/insight.js +20 -0
- package/dist/src/proactive/execution/repository.js +8 -2
- package/dist/src/proactive/execution/types.d.ts +14 -0
- package/dist/src/proactive/inbox/repository.js +59 -9
- package/dist/src/proactive/inbox/service.d.ts +2 -2
- package/dist/src/proactive/inbox/service.js +7 -2
- package/dist/src/proactive/inbox/types.d.ts +14 -0
- package/dist/src/proactive/inbox/worker.js +2 -0
- package/dist/src/proactive/scenarios/prompt-composer.js +2 -2
- package/dist/src/projects/project-agent.js +1 -1
- package/dist/src/storage/sqlite/migrations/118_task_board_rank.sql +6 -0
- package/dist/src/storage/sqlite/migrations/119_proactive_disposition.sql +13 -0
- package/dist/src/storage/sqlite/migrations/120_task_conversation.sql +112 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tasks/execution-context.js +8 -4
- package/dist/src/tasks/home-query-service.d.ts +5 -0
- package/dist/src/tasks/home-query-service.js +7 -2
- package/dist/src/tasks/index.d.ts +3 -0
- package/dist/src/tasks/index.js +6 -3
- package/dist/src/tasks/project-monitoring-service.d.ts +9 -0
- package/dist/src/tasks/project-monitoring-service.js +41 -3
- package/dist/src/tasks/project-operating-view-service.d.ts +1 -2
- package/dist/src/tasks/project-operating-view-service.js +26 -23
- package/dist/src/tasks/task-application-service.js +107 -21
- package/dist/src/tasks/task-change-events.d.ts +13 -0
- package/dist/src/tasks/task-change-events.js +29 -0
- package/dist/src/tasks/task-context-assembler.js +9 -4
- package/dist/src/tasks/task-context-repository.d.ts +0 -6
- package/dist/src/tasks/task-context-repository.js +0 -4
- package/dist/src/tasks/task-conversation-repository.d.ts +71 -0
- package/dist/src/tasks/task-conversation-repository.js +194 -0
- package/dist/src/tasks/task-handoff-service.d.ts +31 -0
- package/dist/src/tasks/task-handoff-service.js +143 -0
- package/dist/src/tasks/task-read-model-projector.js +3 -6
- package/dist/src/tasks/task-repository.d.ts +7 -2
- package/dist/src/tasks/task-repository.js +31 -15
- package/dist/src/tasks/task-run-coordinator.js +3 -1
- package/dist/src/tunnel/enable-lan-pairing.js +15 -26
- package/dist/src/tunnel/pair-context.js +1 -1
- package/dist/src/tunnel/pair-url.js +1 -1
- package/dist/src/tunnel/tunnel-qr.d.ts +0 -7
- package/dist/src/tunnel/tunnel-qr.js +2 -19
- package/dist/src/workflows/service/workflow-run-service.js +4 -2
- package/package.json +5 -3
- package/dist/gateway/static/root/assets/agents-Baxfj44y.js +0 -68
- package/dist/gateway/static/root/assets/app-management-settings-panel-S8LhoD6G.js +0 -1
- package/dist/gateway/static/root/assets/appearance-settings-D8Cd5vDP.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-0uCxKyE5.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-XyDat125.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-CrYNMR4w.js +0 -8
- package/dist/gateway/static/root/assets/browser-workflow-inputs-Abil4puY.js +0 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CvMcDhGf.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-CHJDY-Ih.js +0 -3
- package/dist/gateway/static/root/assets/channels-settings-Ds9BJbcY.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-DPaJSYX_.js +0 -1
- package/dist/gateway/static/root/assets/connectors-api-CgWjgPSI.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-NUs-Zf7F.js +0 -2
- package/dist/gateway/static/root/assets/cron-expression-ZdDBAoqA.js +0 -2
- package/dist/gateway/static/root/assets/dependency-picker-BGeB1jpn.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-CCjT1bdo.js +0 -1
- package/dist/gateway/static/root/assets/directory-picker-path-field-C-Te1QN3.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BLSNdlgd.js +0 -1
- package/dist/gateway/static/root/assets/gateway-config-api-CQrf0k3D.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-CvgH8IJI.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-SPpnqbjl.js +0 -1
- package/dist/gateway/static/root/assets/home-page-BFoD6047.js +0 -3
- package/dist/gateway/static/root/assets/index-84ys9u-K.js +0 -152
- package/dist/gateway/static/root/assets/index-D-srnucP.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-D5uL2_Fd.js +0 -2
- package/dist/gateway/static/root/assets/local-apps-page-DIWkFa3g.js +0 -1
- package/dist/gateway/static/root/assets/logs-page--6v8qq6y.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-DtEuS-kR.js +0 -1
- package/dist/gateway/static/root/assets/messages-DQ5X6cXp.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-IdjuNXvH.js +0 -4
- package/dist/gateway/static/root/assets/page-tabs-7bSEWfSX.js +0 -1
- package/dist/gateway/static/root/assets/preview-open-alternatives-tgLbHgcV.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-DnJXSuM4.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DckZKlBI.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CfbUHBUH.js +0 -1
- package/dist/gateway/static/root/assets/schema-form-CFfyC4CB.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BCfCh4My.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-Cbi4FvzO.js +0 -1
- package/dist/gateway/static/root/assets/settings-form-section-gEnEYT_3.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-layout-CRpXF_05.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BcHdpmFf.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-DU8L68A5.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-kjTqH9yY.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-QAGpwzIM.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-lE1-YRdK.js +0 -2
- package/dist/gateway/static/root/assets/system-settings-panel-CVDsiPKn.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-DsM13-cy.js +0 -1
- package/dist/gateway/static/root/assets/typed-models-lib-DelyYgoc.js +0 -1
- package/dist/gateway/static/root/assets/use-autosave-C50Mq5yQ.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-D-VEOt2A.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-DYfgTe3Y.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-overlay-DPbujsp3.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-D77opady.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-B9-PLmlX.js +0 -5
- package/dist/src/gateway/ensure-network-cors.d.ts +0 -3
- package/dist/src/gateway/ensure-network-cors.js +0 -23
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { init_agent_scope, listAgentEntries, normalizeAgentId } from "../agent/agent-scope.js";
|
|
4
|
+
import { buildSessionKey, init_session_key, sanitizeSegment } from "../routing/session-key.js";
|
|
5
|
+
import { TaskRepository } from "./task-repository.js";
|
|
6
|
+
import { TaskConversationRepository } from "./task-conversation-repository.js";
|
|
7
|
+
import { TaskRunRepository } from "./task-run-repository.js";
|
|
8
|
+
import { TaskContextRepository } from "./task-context-repository.js";
|
|
9
|
+
//#region src/tasks/task-handoff-service.ts
|
|
10
|
+
init_agent_scope();
|
|
11
|
+
init_session_key();
|
|
12
|
+
init_logger();
|
|
13
|
+
const log = createLogger("TaskHandoff");
|
|
14
|
+
var TaskHandoffService = class {
|
|
15
|
+
#inflight = /* @__PURE__ */ new Map();
|
|
16
|
+
constructor(deps) {
|
|
17
|
+
this.deps = deps;
|
|
18
|
+
}
|
|
19
|
+
handoff(input) {
|
|
20
|
+
const previous = this.#inflight.get(input.taskId);
|
|
21
|
+
const pending = (previous ? previous.catch(() => void 0) : Promise.resolve()).then(() => this.performHandoff(input));
|
|
22
|
+
this.#inflight.set(input.taskId, pending);
|
|
23
|
+
pending.finally(() => {
|
|
24
|
+
if (this.#inflight.get(input.taskId) === pending) this.#inflight.delete(input.taskId);
|
|
25
|
+
});
|
|
26
|
+
return pending;
|
|
27
|
+
}
|
|
28
|
+
async performHandoff(input) {
|
|
29
|
+
const config = this.deps.getConfig();
|
|
30
|
+
const toAgentId = normalizeAgentId(input.toAgentId);
|
|
31
|
+
if (!listAgentEntries(config).find((entry) => entry.enabled !== false && normalizeAgentId(entry.id) === toAgentId)) throw new Error(`Agent not found: ${toAgentId}`);
|
|
32
|
+
const tasks = new TaskRepository();
|
|
33
|
+
const task = tasks.require(input.taskId);
|
|
34
|
+
const conversations = new TaskConversationRepository();
|
|
35
|
+
const duplicate = conversations.findHandoffByIdempotencyKey({
|
|
36
|
+
taskId: task.id,
|
|
37
|
+
expectedTaskVersion: input.expectedVersion,
|
|
38
|
+
toAgentId,
|
|
39
|
+
idempotencyKey: input.idempotencyKey
|
|
40
|
+
});
|
|
41
|
+
if (duplicate) {
|
|
42
|
+
await this.abortPreviousSession(duplicate.fromSessionKey);
|
|
43
|
+
return {
|
|
44
|
+
task,
|
|
45
|
+
conversation: conversations.requireState(task.id),
|
|
46
|
+
snapshot: duplicate,
|
|
47
|
+
...duplicate.fromAgentId ? { fromAgentId: duplicate.fromAgentId } : {},
|
|
48
|
+
toAgentId,
|
|
49
|
+
activeSessionKey: duplicate.toSessionKey,
|
|
50
|
+
assignmentEpoch: duplicate.assignmentEpoch
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (task.version !== input.expectedVersion) throw new Error("Task changed");
|
|
54
|
+
const previousState = conversations.requireState(task.id);
|
|
55
|
+
if (previousState.currentExecutorAgentId === toAgentId) throw new Error("Executor is already active");
|
|
56
|
+
const assignmentEpoch = previousState.assignmentEpoch + 1;
|
|
57
|
+
const peerId = sanitizeSegment(`task-${task.id}-assignment-${assignmentEpoch}`);
|
|
58
|
+
const sessionKey = buildSessionKey({
|
|
59
|
+
agentId: toAgentId,
|
|
60
|
+
source: "webchat",
|
|
61
|
+
accountId: "default",
|
|
62
|
+
peerKind: "direct",
|
|
63
|
+
peerId
|
|
64
|
+
});
|
|
65
|
+
const runs = new TaskRunRepository();
|
|
66
|
+
const latestRun = runs.getLatestRoot(task.id);
|
|
67
|
+
const latestReceipt = latestRun ? runs.getReceipt(latestRun.id) : void 0;
|
|
68
|
+
const remainingCriteria = latestReceipt?.verification.checks.length ? latestReceipt.verification.checks.filter((check) => check.status !== "passed").map((check) => check.criterion) : task.contract?.acceptanceCriteria ?? [];
|
|
69
|
+
const payload = {
|
|
70
|
+
objective: task.contract?.objective ?? task.title,
|
|
71
|
+
expectedOutputs: task.contract?.expectedOutputs ?? [],
|
|
72
|
+
remainingCriteria,
|
|
73
|
+
constraints: task.contract?.constraints ?? [],
|
|
74
|
+
risks: task.contract?.risks ?? [],
|
|
75
|
+
approvalRequired: task.contract?.approvalRequired ?? [],
|
|
76
|
+
context: new TaskContextRepository().list(task.id),
|
|
77
|
+
...latestReceipt ? {
|
|
78
|
+
latestReceipt,
|
|
79
|
+
completedWork: latestReceipt.changes,
|
|
80
|
+
remainingWork: latestReceipt.remainingWork
|
|
81
|
+
} : {}
|
|
82
|
+
};
|
|
83
|
+
await this.deps.sessionIndex.saveMessages(sessionKey, [], { metadata: {
|
|
84
|
+
sourceChannel: "webchat",
|
|
85
|
+
sourceChatId: `default:direct:${peerId}`,
|
|
86
|
+
sessionType: "chat",
|
|
87
|
+
routing: {
|
|
88
|
+
agentId: toAgentId,
|
|
89
|
+
source: "webchat",
|
|
90
|
+
accountId: "default",
|
|
91
|
+
peerKind: "direct",
|
|
92
|
+
peerId
|
|
93
|
+
},
|
|
94
|
+
projectId: task.projectId,
|
|
95
|
+
customData: {
|
|
96
|
+
origin: "task",
|
|
97
|
+
triggerKind: "user",
|
|
98
|
+
assignmentEpoch
|
|
99
|
+
}
|
|
100
|
+
} });
|
|
101
|
+
let completed;
|
|
102
|
+
try {
|
|
103
|
+
completed = conversations.completeHandoff({
|
|
104
|
+
taskId: task.id,
|
|
105
|
+
expectedTaskVersion: input.expectedVersion,
|
|
106
|
+
toSessionKey: sessionKey,
|
|
107
|
+
toAgentId,
|
|
108
|
+
idempotencyKey: input.idempotencyKey,
|
|
109
|
+
payload
|
|
110
|
+
});
|
|
111
|
+
} catch (error) {
|
|
112
|
+
await this.deps.sessionIndex.delete(sessionKey);
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
const oldSessionKey = completed.snapshot.fromSessionKey;
|
|
116
|
+
await this.abortPreviousSession(oldSessionKey);
|
|
117
|
+
return {
|
|
118
|
+
task: tasks.require(task.id),
|
|
119
|
+
conversation: completed.state,
|
|
120
|
+
snapshot: completed.snapshot,
|
|
121
|
+
...completed.snapshot.fromAgentId ? { fromAgentId: completed.snapshot.fromAgentId } : {},
|
|
122
|
+
toAgentId,
|
|
123
|
+
activeSessionKey: sessionKey,
|
|
124
|
+
assignmentEpoch: completed.state.assignmentEpoch
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async abortPreviousSession(sessionKey) {
|
|
128
|
+
if (!sessionKey) return;
|
|
129
|
+
const activeRunId = this.deps.getActiveRunId(sessionKey);
|
|
130
|
+
if (!activeRunId) return;
|
|
131
|
+
try {
|
|
132
|
+
await this.deps.abortRun(activeRunId);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
log.warn({
|
|
135
|
+
err: error,
|
|
136
|
+
sessionKey,
|
|
137
|
+
runId: activeRunId
|
|
138
|
+
}, "Previous task executor did not stop cleanly");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
//#endregion
|
|
143
|
+
export { TaskHandoffService };
|
|
@@ -76,16 +76,13 @@ var TaskReadModelProjector = class {
|
|
|
76
76
|
}
|
|
77
77
|
allowedCommands(task, activeRunStatus, hasWaits) {
|
|
78
78
|
if (task.phase === "closed") return ["reopen"];
|
|
79
|
-
const commands = [
|
|
80
|
-
|
|
81
|
-
"delegate",
|
|
82
|
-
"close"
|
|
83
|
-
];
|
|
79
|
+
const commands = ["revise_contract", "close"];
|
|
80
|
+
if (!activeRunStatus && !hasWaits) commands.unshift("move");
|
|
84
81
|
if (hasWaits) commands.unshift("resolve_wait");
|
|
85
82
|
else if (activeRunStatus === "running" || activeRunStatus === "verifying") commands.unshift("add_wait");
|
|
86
83
|
if (task.phase === "backlog") commands.unshift("mark_ready");
|
|
87
84
|
if (!activeRunStatus && !hasWaits && task.phase !== "backlog") commands.unshift("start");
|
|
88
|
-
if (task.phase === "active") commands.push("request_review");
|
|
85
|
+
if (task.phase === "active" && !activeRunStatus) commands.push("request_review");
|
|
89
86
|
return commands;
|
|
90
87
|
}
|
|
91
88
|
};
|
|
@@ -34,11 +34,11 @@ export declare class TaskRepository {
|
|
|
34
34
|
get(id: string): TaskAggregate | undefined;
|
|
35
35
|
require(id: string): TaskAggregate;
|
|
36
36
|
getByIdempotencyKey(key: string): TaskAggregate | undefined;
|
|
37
|
-
getBySession(sessionKey: string): TaskAggregate | undefined;
|
|
38
37
|
list(input?: {
|
|
39
38
|
phase?: TaskPhase;
|
|
40
39
|
projectId?: string;
|
|
41
40
|
limit?: number;
|
|
41
|
+
order?: 'recent' | 'board';
|
|
42
42
|
}): TaskAggregate[];
|
|
43
43
|
listByProject(projectId: string, limit?: number): TaskAggregate[];
|
|
44
44
|
getContract(taskId: string, version?: number): TaskContract | undefined;
|
|
@@ -52,7 +52,6 @@ export declare class TaskRepository {
|
|
|
52
52
|
priority?: TaskPriority;
|
|
53
53
|
dueAt?: number | null;
|
|
54
54
|
ownerId?: string | null;
|
|
55
|
-
delegateAgentId?: string | null;
|
|
56
55
|
now?: number;
|
|
57
56
|
}): TaskAggregate | undefined;
|
|
58
57
|
setLifecycle(input: {
|
|
@@ -62,6 +61,12 @@ export declare class TaskRepository {
|
|
|
62
61
|
resolution?: TaskResolution;
|
|
63
62
|
now?: number;
|
|
64
63
|
}): TaskAggregate | undefined;
|
|
64
|
+
reorder(input: {
|
|
65
|
+
taskId: string;
|
|
66
|
+
expectedVersion: number;
|
|
67
|
+
beforeTaskId?: string | null;
|
|
68
|
+
now?: number;
|
|
69
|
+
}): TaskAggregate | undefined;
|
|
65
70
|
reviseContract(input: {
|
|
66
71
|
taskId: string;
|
|
67
72
|
objective: string;
|
|
@@ -38,6 +38,7 @@ function taskFromRow(row, contract) {
|
|
|
38
38
|
source: row.source,
|
|
39
39
|
...row.locale ? { locale: row.locale } : {},
|
|
40
40
|
latestContractVersion: row.latest_contract_version,
|
|
41
|
+
boardRank: row.board_rank,
|
|
41
42
|
version: row.version,
|
|
42
43
|
...contract ? { contract } : {},
|
|
43
44
|
createdAt: row.created_at,
|
|
@@ -54,11 +55,13 @@ var TaskRepository = class {
|
|
|
54
55
|
const id = input.id ?? randomUUID();
|
|
55
56
|
const now = input.now ?? Date.now();
|
|
56
57
|
runSqliteWriteTransaction((db) => {
|
|
58
|
+
const phase = input.phase ?? "backlog";
|
|
59
|
+
const boardRank = Number(db.prepare("SELECT COALESCE(MAX(board_rank), 0) + 1024 AS board_rank FROM tasks WHERE project_id IS ? AND phase = ?").get(input.projectId ?? null, phase).board_rank);
|
|
57
60
|
db.prepare(`INSERT INTO tasks (
|
|
58
61
|
task_id, creation_idempotency_key, project_id, milestone_id, parent_task_id,
|
|
59
62
|
title, body, phase, priority, due_at, owner_id, delegate_agent_id,
|
|
60
|
-
source, locale, latest_contract_version, version, created_at, updated_at
|
|
61
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 1, ?, ?)`).run(id, input.idempotencyKey ?? null, input.projectId ?? null, input.milestoneId ?? null, input.parentTaskId ?? null, title, input.body?.trim() || null,
|
|
63
|
+
source, locale, latest_contract_version, board_rank, version, created_at, updated_at
|
|
64
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, 1, ?, ?)`).run(id, input.idempotencyKey ?? null, input.projectId ?? null, input.milestoneId ?? null, input.parentTaskId ?? null, title, input.body?.trim() || null, phase, input.priority ?? "normal", input.dueAt ?? null, input.ownerId ?? null, input.delegateAgentId ?? null, input.source ?? "api", input.locale ?? null, boardRank, now, now);
|
|
62
65
|
this.insertContract(db, {
|
|
63
66
|
taskId: id,
|
|
64
67
|
version: 1,
|
|
@@ -90,13 +93,6 @@ var TaskRepository = class {
|
|
|
90
93
|
const row = getSqliteDatabase().prepare("SELECT * FROM tasks WHERE creation_idempotency_key = ?").get(key);
|
|
91
94
|
return row ? taskFromRow(row, this.getContract(row.task_id, row.latest_contract_version)) : void 0;
|
|
92
95
|
}
|
|
93
|
-
getBySession(sessionKey) {
|
|
94
|
-
const row = getSqliteDatabase().prepare(`SELECT tasks.* FROM tasks
|
|
95
|
-
JOIN task_sessions ON task_sessions.task_id = tasks.task_id
|
|
96
|
-
WHERE task_sessions.session_key = ?
|
|
97
|
-
ORDER BY task_sessions.created_at DESC LIMIT 1`).get(sessionKey);
|
|
98
|
-
return row ? taskFromRow(row, this.getContract(row.task_id, row.latest_contract_version)) : void 0;
|
|
99
|
-
}
|
|
100
96
|
list(input = {}) {
|
|
101
97
|
const clauses = [];
|
|
102
98
|
const params = [];
|
|
@@ -111,12 +107,13 @@ var TaskRepository = class {
|
|
|
111
107
|
const limit = Math.max(1, Math.min(200, Math.floor(input.limit ?? 50)));
|
|
112
108
|
params.push(limit);
|
|
113
109
|
return getSqliteDatabase().prepare(`SELECT * FROM tasks${clauses.length ? ` WHERE ${clauses.join(" AND ")}` : ""}
|
|
114
|
-
ORDER BY updated_at DESC LIMIT ?`).all(...params).map((row) => taskFromRow(row, this.getContract(row.task_id, row.latest_contract_version)));
|
|
110
|
+
ORDER BY ${input.order === "board" ? "board_rank ASC, created_at ASC, task_id ASC" : "updated_at DESC"} LIMIT ?`).all(...params).map((row) => taskFromRow(row, this.getContract(row.task_id, row.latest_contract_version)));
|
|
115
111
|
}
|
|
116
112
|
listByProject(projectId, limit = 50) {
|
|
117
113
|
return this.list({
|
|
118
114
|
projectId,
|
|
119
|
-
limit
|
|
115
|
+
limit,
|
|
116
|
+
order: "board"
|
|
120
117
|
});
|
|
121
118
|
}
|
|
122
119
|
getContract(taskId, version) {
|
|
@@ -130,18 +127,37 @@ var TaskRepository = class {
|
|
|
130
127
|
if (!title) throw new Error("Task title is required");
|
|
131
128
|
const now = Math.max(patch.now ?? Date.now(), current.updatedAt + 1);
|
|
132
129
|
return getSqliteDatabase().prepare(`UPDATE tasks SET title = ?, body = ?, project_id = ?, milestone_id = ?,
|
|
133
|
-
parent_task_id = ?, priority = ?, due_at = ?, owner_id = ?,
|
|
130
|
+
parent_task_id = ?, priority = ?, due_at = ?, owner_id = ?,
|
|
134
131
|
version = version + 1, updated_at = ?
|
|
135
|
-
WHERE task_id = ? AND version = ?`).run(title, patch.body === void 0 ? current.body ?? null : patch.body?.trim() || null, patch.projectId === void 0 ? current.projectId ?? null : patch.projectId, patch.milestoneId === void 0 ? current.milestoneId ?? null : patch.milestoneId, patch.parentTaskId === void 0 ? current.parentTaskId ?? null : patch.parentTaskId, patch.priority ?? current.priority, patch.dueAt === void 0 ? current.dueAt ?? null : patch.dueAt, patch.ownerId === void 0 ? current.ownerId ?? null : patch.ownerId,
|
|
132
|
+
WHERE task_id = ? AND version = ?`).run(title, patch.body === void 0 ? current.body ?? null : patch.body?.trim() || null, patch.projectId === void 0 ? current.projectId ?? null : patch.projectId, patch.milestoneId === void 0 ? current.milestoneId ?? null : patch.milestoneId, patch.parentTaskId === void 0 ? current.parentTaskId ?? null : patch.parentTaskId, patch.priority ?? current.priority, patch.dueAt === void 0 ? current.dueAt ?? null : patch.dueAt, patch.ownerId === void 0 ? current.ownerId ?? null : patch.ownerId, now, taskId, patch.expectedVersion).changes === 0 ? void 0 : this.get(taskId);
|
|
136
133
|
}
|
|
137
134
|
setLifecycle(input) {
|
|
138
135
|
if (input.phase === "closed" !== Boolean(input.resolution)) throw new Error("Closed tasks require a resolution and open tasks cannot have one");
|
|
139
136
|
const current = this.get(input.taskId);
|
|
140
137
|
if (!current || current.version !== input.expectedVersion) return void 0;
|
|
141
138
|
const now = Math.max(input.now ?? Date.now(), current.updatedAt + 1);
|
|
139
|
+
const boardRank = current.phase === input.phase ? current.boardRank : Number(getSqliteDatabase().prepare("SELECT COALESCE(MAX(board_rank), 0) + 1024 AS board_rank FROM tasks WHERE project_id IS ? AND phase = ?").get(current.projectId ?? null, input.phase).board_rank);
|
|
142
140
|
return getSqliteDatabase().prepare(`UPDATE tasks SET phase = ?, resolution = ?, closed_at = ?,
|
|
143
|
-
version = version + 1, updated_at = ?
|
|
144
|
-
WHERE task_id = ? AND version = ?`).run(input.phase, input.resolution ?? null, input.phase === "closed" ? now : null, now, input.taskId, input.expectedVersion).changes === 0 ? void 0 : this.get(input.taskId);
|
|
141
|
+
board_rank = ?, version = version + 1, updated_at = ?
|
|
142
|
+
WHERE task_id = ? AND version = ?`).run(input.phase, input.resolution ?? null, input.phase === "closed" ? now : null, boardRank, now, input.taskId, input.expectedVersion).changes === 0 ? void 0 : this.get(input.taskId);
|
|
143
|
+
}
|
|
144
|
+
reorder(input) {
|
|
145
|
+
const current = this.get(input.taskId);
|
|
146
|
+
if (!current || current.version !== input.expectedVersion) return void 0;
|
|
147
|
+
const before = input.beforeTaskId ? this.get(input.beforeTaskId) : void 0;
|
|
148
|
+
if (input.beforeTaskId && (!before || before.id === current.id || before.projectId !== current.projectId || before.phase !== current.phase)) throw new Error("Board position target must be another task in the same project phase");
|
|
149
|
+
const now = Math.max(input.now ?? Date.now(), current.updatedAt + 1);
|
|
150
|
+
return runSqliteWriteTransaction((db) => {
|
|
151
|
+
const ids = db.prepare(`SELECT task_id FROM tasks
|
|
152
|
+
WHERE project_id IS ? AND phase = ? AND task_id <> ?
|
|
153
|
+
ORDER BY board_rank ASC, created_at ASC, task_id ASC`).all(current.projectId ?? null, current.phase, current.id).map((row) => row.task_id);
|
|
154
|
+
const insertAt = before ? ids.indexOf(before.id) : ids.length;
|
|
155
|
+
ids.splice(insertAt, 0, current.id);
|
|
156
|
+
const updateRank = db.prepare("UPDATE tasks SET board_rank = ? WHERE task_id = ?");
|
|
157
|
+
ids.forEach((id, index) => updateRank.run((index + 1) * 1024, id));
|
|
158
|
+
return db.prepare(`UPDATE tasks SET version = version + 1, updated_at = ?
|
|
159
|
+
WHERE task_id = ? AND version = ?`).run(now, current.id, current.version).changes === 0 ? void 0 : this.get(current.id);
|
|
160
|
+
});
|
|
145
161
|
}
|
|
146
162
|
reviseContract(input) {
|
|
147
163
|
const current = this.get(input.taskId);
|
|
@@ -19,11 +19,13 @@ var TaskRunCoordinator = class TaskRunCoordinator {
|
|
|
19
19
|
let run = runs.get(input.runId);
|
|
20
20
|
if (!run) {
|
|
21
21
|
if (runs.getActiveRoot(task.id)) return void 0;
|
|
22
|
+
const agentId = task.delegateAgentId ?? input.context.agentId;
|
|
23
|
+
if (!agentId) return void 0;
|
|
22
24
|
run = runs.create({
|
|
23
25
|
id: input.runId,
|
|
24
26
|
taskId: task.id,
|
|
25
27
|
executorKind: "agent",
|
|
26
|
-
executorRef: { agentId
|
|
28
|
+
executorRef: { agentId },
|
|
27
29
|
trigger: { kind: input.context.triggerKind },
|
|
28
30
|
correlationId: input.runId,
|
|
29
31
|
idempotencyKey: input.runId,
|
|
@@ -1,39 +1,27 @@
|
|
|
1
|
-
import { buildDefaultCorsOrigins } from "../gateway/host.js";
|
|
2
|
-
import { isNetworkAccessibleBindHost, resolveGatewayBindMode, resolveGatewayEffectiveHost } from "../config/gateway-bind.js";
|
|
3
|
-
import { enumerateLanGatewayCandidates } from "./tunnel-qr.js";
|
|
4
1
|
import { assertGatewayAuthConfigured, resolveGatewayAuth } from "../gateway/auth.js";
|
|
5
2
|
import { assertGatewayRuntimeConfig } from "../gateway/runtime-config.js";
|
|
6
3
|
//#region src/tunnel/enable-lan-pairing.ts
|
|
7
|
-
function mergeCorsOriginsForLan(config, port, bindHost) {
|
|
8
|
-
if (!config.gateway) return;
|
|
9
|
-
const existing = new Set((config.gateway.corsOrigins ?? []).map((o) => o.trim()).filter(Boolean));
|
|
10
|
-
for (const origin of buildDefaultCorsOrigins({
|
|
11
|
-
port,
|
|
12
|
-
bindHost
|
|
13
|
-
})) existing.add(origin);
|
|
14
|
-
for (const candidate of enumerateLanGatewayCandidates(port)) existing.add(candidate.url);
|
|
15
|
-
config.gateway.corsOrigins = [...existing];
|
|
16
|
-
}
|
|
17
4
|
function applyLanPairingGatewayPatch(config) {
|
|
18
|
-
const bindMode = resolveGatewayBindMode(config);
|
|
19
|
-
const listenHost = resolveGatewayEffectiveHost(config);
|
|
20
|
-
if (bindMode === "lan" && isNetworkAccessibleBindHost(listenHost)) return {
|
|
21
|
-
ok: true,
|
|
22
|
-
changed: false
|
|
23
|
-
};
|
|
24
5
|
if (!config.gateway) return {
|
|
25
6
|
ok: false,
|
|
26
7
|
message: "Gateway section missing from config"
|
|
27
8
|
};
|
|
28
|
-
config.gateway
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
9
|
+
const previousGateway = JSON.stringify(config.gateway);
|
|
10
|
+
const nextGateway = {
|
|
11
|
+
...config.gateway,
|
|
12
|
+
bind: "lan"
|
|
13
|
+
};
|
|
14
|
+
delete nextGateway.customBindHost;
|
|
15
|
+
const candidate = {
|
|
16
|
+
...config,
|
|
17
|
+
gateway: nextGateway
|
|
18
|
+
};
|
|
19
|
+
const port = nextGateway.port ?? 18790;
|
|
32
20
|
try {
|
|
33
|
-
const auth = resolveGatewayAuth({ authConfig:
|
|
21
|
+
const auth = resolveGatewayAuth({ authConfig: candidate.gateway.auth });
|
|
34
22
|
assertGatewayAuthConfigured(auth);
|
|
35
23
|
assertGatewayRuntimeConfig({
|
|
36
|
-
cfg:
|
|
24
|
+
cfg: candidate,
|
|
37
25
|
auth,
|
|
38
26
|
port
|
|
39
27
|
});
|
|
@@ -43,9 +31,10 @@ function applyLanPairingGatewayPatch(config) {
|
|
|
43
31
|
message: err instanceof Error ? err.message : String(err)
|
|
44
32
|
};
|
|
45
33
|
}
|
|
34
|
+
config.gateway = candidate.gateway;
|
|
46
35
|
return {
|
|
47
36
|
ok: true,
|
|
48
|
-
changed:
|
|
37
|
+
changed: previousGateway !== JSON.stringify(config.gateway)
|
|
49
38
|
};
|
|
50
39
|
}
|
|
51
40
|
//#endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { init_public_url, normalizePublicUrlOrNull } from "../config/public-url.js";
|
|
2
|
+
import { enumerateLanGatewayCandidates } from "../gateway/host.js";
|
|
2
3
|
import { isNetworkAccessibleBindHost, resolveGatewayBindMode, resolveGatewayEffectiveHost } from "../config/gateway-bind.js";
|
|
3
|
-
import { enumerateLanGatewayCandidates } from "./tunnel-qr.js";
|
|
4
4
|
import { buildMobileConnectUrlOrder } from "./pair-url.js";
|
|
5
5
|
//#region src/tunnel/pair-context.ts
|
|
6
6
|
init_public_url();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { enumerateLanGatewayCandidates } from "../gateway/host.js";
|
|
1
2
|
import { isNetworkAccessibleBindHost, resolveGatewayEffectiveHost } from "../config/gateway-bind.js";
|
|
2
|
-
import { enumerateLanGatewayCandidates } from "./tunnel-qr.js";
|
|
3
3
|
import net from "node:net";
|
|
4
4
|
//#region src/tunnel/pair-url.ts
|
|
5
5
|
/** Normalize a gateway root URL (no trailing slash, no path). */
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import type { TunnelQrPayload } from './tunnel-types.js';
|
|
2
|
-
export type LanGatewayCandidate = {
|
|
3
|
-
url: string;
|
|
4
|
-
address: string;
|
|
5
|
-
interfaceName: string;
|
|
6
|
-
};
|
|
7
|
-
/** Non-internal IPv4 addresses on this machine (independent of gateway bind mode). */
|
|
8
|
-
export declare function enumerateLanGatewayCandidates(port: number): LanGatewayCandidate[];
|
|
9
2
|
/** First non-internal IPv4 suitable for LAN QR (when gateway listens on 0.0.0.0). */
|
|
10
3
|
export declare function resolveLanGatewayUrl(gatewayHost: string, gatewayPort: number): string | null;
|
|
11
4
|
export declare function buildMobileConnectQrPayload(input: {
|
|
@@ -1,25 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { enumerateLanGatewayCandidates } from "../gateway/host.js";
|
|
2
2
|
//#region src/tunnel/tunnel-qr.ts
|
|
3
3
|
function trimBase(raw) {
|
|
4
4
|
return raw.trim().replace(/\/+$/, "");
|
|
5
5
|
}
|
|
6
|
-
/** Non-internal IPv4 addresses on this machine (independent of gateway bind mode). */
|
|
7
|
-
function enumerateLanGatewayCandidates(port) {
|
|
8
|
-
const nets = networkInterfaces();
|
|
9
|
-
const seen = /* @__PURE__ */ new Set();
|
|
10
|
-
const out = [];
|
|
11
|
-
for (const [interfaceName, addrs] of Object.entries(nets)) for (const addr of addrs ?? []) {
|
|
12
|
-
if (addr.family !== "IPv4" || addr.internal) continue;
|
|
13
|
-
if (seen.has(addr.address)) continue;
|
|
14
|
-
seen.add(addr.address);
|
|
15
|
-
out.push({
|
|
16
|
-
address: addr.address,
|
|
17
|
-
interfaceName,
|
|
18
|
-
url: trimBase(`http://${addr.address}:${port}`)
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
return out;
|
|
22
|
-
}
|
|
23
6
|
/** First non-internal IPv4 suitable for LAN QR (when gateway listens on 0.0.0.0). */
|
|
24
7
|
function resolveLanGatewayUrl(gatewayHost, gatewayPort) {
|
|
25
8
|
const host = gatewayHost.trim().toLowerCase();
|
|
@@ -43,4 +26,4 @@ function buildMobileConnectQrPayload(input) {
|
|
|
43
26
|
};
|
|
44
27
|
}
|
|
45
28
|
//#endregion
|
|
46
|
-
export { buildMobileConnectQrPayload,
|
|
29
|
+
export { buildMobileConnectQrPayload, resolveLanGatewayUrl };
|
|
@@ -2,6 +2,7 @@ import { getDefaultAgentId, init_resolve_route } from "../../routing/resolve-rou
|
|
|
2
2
|
import { extractProfileAgentId, resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
|
|
3
3
|
import { init_providers, resolveModel } from "../../providers/index.js";
|
|
4
4
|
import { TaskRepository } from "../../tasks/task-repository.js";
|
|
5
|
+
import { TaskConversationRepository } from "../../tasks/task-conversation-repository.js";
|
|
5
6
|
import { TaskRunRepository } from "../../tasks/task-run-repository.js";
|
|
6
7
|
import { getProjectWorkspacePathForSession } from "../../projects/workspace.js";
|
|
7
8
|
import { publishAutomationProductEvent } from "../../automations/product-events.js";
|
|
@@ -161,10 +162,11 @@ var WorkflowRunService = class {
|
|
|
161
162
|
},
|
|
162
163
|
sessionKey
|
|
163
164
|
})) throw new Error("TaskRun changed before workflow execution started");
|
|
164
|
-
|
|
165
|
+
new TaskConversationRepository().activateExecutionSession({
|
|
165
166
|
taskId: task.id,
|
|
166
167
|
sessionKey,
|
|
167
|
-
|
|
168
|
+
agentId: params.agentId,
|
|
169
|
+
runId: linkedTaskRun.id
|
|
168
170
|
});
|
|
169
171
|
}
|
|
170
172
|
const source = normalizeWorkflowRunSourceForSession(params.source, sessionKey, params.parentSessionKey);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.200",
|
|
4
4
|
"description": "Local-first AI system that remembers context, coordinates AI, and sustains long-term progress.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -163,9 +163,9 @@
|
|
|
163
163
|
"vitest": "4.1.5",
|
|
164
164
|
"vue": "^3.5.35",
|
|
165
165
|
"@xopcai/endpoint-tools-protocol": "0.0.0",
|
|
166
|
-
"@xopcai/gateway-contract": "0.0.0",
|
|
167
166
|
"@xopcai/realtime-protocol": "0.0.0",
|
|
168
|
-
"@xopcai/realtime-client": "0.0.0"
|
|
167
|
+
"@xopcai/realtime-client": "0.0.0",
|
|
168
|
+
"@xopcai/gateway-contract": "0.0.0"
|
|
169
169
|
},
|
|
170
170
|
"scripts": {
|
|
171
171
|
"assets:brand": "node scripts/generate-brand-assets.mjs",
|
|
@@ -190,6 +190,8 @@
|
|
|
190
190
|
"mobile:test": "pnpm -C apps/mobile-expo test",
|
|
191
191
|
"mobile:test:stream": "pnpm --filter @xopcai/agent-stream-client test",
|
|
192
192
|
"mobile:release:patch": "bash scripts/apps/mobile-expo/release-patch.sh",
|
|
193
|
+
"mobile:configure:ios:github": "bash scripts/apps/mobile-expo/configure-ios-github-secrets.sh",
|
|
194
|
+
"mobile:release:ios:testflight": "bash scripts/apps/mobile-expo/release-ios-testflight.sh",
|
|
193
195
|
"dev": "tsx src/cli/bin.ts",
|
|
194
196
|
"dev:init": "sh -c 'mkdir -p \"$HOME/.xopc-dev\" && XOPC_STATE_DIR=\"$HOME/.xopc-dev\" XOPC_CONFIG_PATH=\"$HOME/.xopc-dev/xopc.json\" XOPC_CONFIG=\"$HOME/.xopc-dev/xopc.json\" XOPC_LOG_DIR=\"$HOME/.xopc-dev/logs\" XOPC_LOG_LEVEL=info tsx src/cli/bin.ts init \"$@\"' --",
|
|
195
197
|
"dev:gateway": "sh -c 'mkdir -p \"$HOME/.xopc-dev\" && XOPC_STATE_DIR=\"$HOME/.xopc-dev\" XOPC_CONFIG_PATH=\"$HOME/.xopc-dev/xopc.json\" XOPC_CONFIG=\"$HOME/.xopc-dev/xopc.json\" XOPC_LOG_DIR=\"$HOME/.xopc-dev/logs\" XOPC_LOG_LEVEL=info tsx src/cli/bin.ts gateway \"$@\"' --",
|