@xopcai/xopc 0.0.211 → 0.0.213
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-BzjFoSr0.js → activity-store-Xw-pOm9A.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DTfjhfVE.js → agent-avatar-dicebear-Ca1bciiK.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DD3TqNrC.js +68 -0
- package/dist/gateway/static/root/assets/{api-D269PnU9.js → api-CZK-lRew.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BFpfQDWc.js → app-management-settings-panel-BLFIG09j.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DLxFdqhY.js → appearance-settings-BsTWUq1i.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-cJkDKn72.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-DPlH4dnc.js → archive-plugin-B9LsFfEx.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-xqfLLd0I.js → attachment-load-CsWiFfmN.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-CbjU2e75.js +1 -0
- package/dist/gateway/static/root/assets/automations-workspace-C4xyo0c4.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-C0tuoPXk.js → binary-plugins-DbqhT_JB.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Deyphj1o.js → block-editor-BGpHwxZ5.js} +47 -47
- package/dist/gateway/static/root/assets/browser-settings-page-CrhpQl-e.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-CYEbXyRF.js → browser-workflow-inputs-BXlon_hL.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-Bf0tPbGi.js → browser-workflows-page-B3BBDM_r.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-B9MoPW9u.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-DPkFA_-R.js → capability-presets-api-BqvMm6UW.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-BmwldV9R.js +3 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-DqKaAcnZ.js → channel-recipient-api-9uca5kDa.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-CwLqWcy_.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-DeBw3du9.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CTDRZa7e.js → chat-terminal-dock-DJjYT3WX.js} +2 -2
- package/dist/gateway/static/root/assets/{chunk-KS7C4IRE-BMhrPKJC.js → chunk-KS7C4IRE-BaASWQor.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-api-Buu8fif8.js → connectors-api-XCLfuDrN.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-CVkGtcMS.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-DTLR82NB.js → cron-expression-DzQN7zBR.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-DyNogHQH.js → date-picker-B-r5O5qd.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-BpnCuo7B.js → dependency-picker-Ch2XBU2s.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-CDKI4gVB.js → desktop-pet-BdjX8jde.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DjT5C2a3.js → desktop-pet-settings-CzjjgMMn.js} +1 -1
- package/dist/gateway/static/root/assets/directory-picker-path-field-BCTgGTk4.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DWf2z7q5.js → extension-debug-page-6OGgOucD.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Dorx0kf9.js → extension-page-Cf6MUfCF.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-B1wU9ZOB.js → extension-settings-page-pSY_ZvQZ.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-B1lG4dNr.js → gateway-config-api-CFJMng9v.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BIxuwPQi.js → gateway-config-swr-DpiY6aub.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DqIOqJjM.js → gateway-settings-aQYxNePf.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BpZgd4U-.js → gateway-startup-retry-BZ_6ChP4.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-DG4Kmgkc.js → heartbeat-settings-CI33q9i1.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-CAIaWs6r.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-PkhYohDa.js → image-generation-api-DPndEWOU.js} +1 -1
- package/dist/gateway/static/root/assets/index-BhstAl5i.js +108 -0
- package/dist/gateway/static/root/assets/index-DQzjgIkQ.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-6OQT3gQF.js → keyboard-shortcuts-settings-CbLJRGXR.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-BqFnCaKT.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-DfruRAmE.js → local-apps-page-Crf6c3SK.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-C5MK9WcP.js → locale-store-BYSRjM6g.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-BpfLQWex.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-L1VYkywO.js → management-settings-mxyYWKgM.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-oqgHbqt-.js → markdown-split-kZaPrUTM.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-V4rcPPH0.js → markdown-view-DlsczsQ1.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Bb6gSX2o.js → media-plugins-Dk67jaG6.js} +1 -1
- package/dist/gateway/static/root/assets/messages-DyM8OOVG.js +3 -0
- package/dist/gateway/static/root/assets/notes-api-DaeeQw8A.js +1 -0
- package/dist/gateway/static/root/assets/{notes-page-B1rOXjpT.js → notes-page-CQDzw8fX.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-BYiROmRJ.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-CBuCKeyy.js → page-tabs-C4UkhX2U.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BQ0tLfPO.js → preview-open-alternatives-nzcjh6y0.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-DPeFn7Hu.js → product-open-page-3FvW5cHm.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-p45i1sMj.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-Y9yXB4DX.js +1 -0
- package/dist/gateway/static/root/assets/registry-api-Bu6OGEY2.js +2 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CNsGY0VS.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BCfQNzjG.js → runtime-tools-settings-panel-CVqPSfUb.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-Bo7YbHYN.js → schema-form-Dz6eZpqv.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-BAtpgb1t.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-pgBQ21Oe.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-B9dnKr3M.js → settings-form-section-BaWFAZv4.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-CYDV2JtY.js → settings-loading-skeleton-BWmdZfNg.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DbrIYfS9.js → settings-page-Btcb-Dc8.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BNllZUFP.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-olgr7LLN.js → share-preview-page-CGzY3S0N.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CncwbTHY.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CcW2dhSW.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-PE16CNw5.js → skills-page-Bi2IWpU0.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-nXmBcBxt.js → skills-page.utils-BancvwN2.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-C3qPwAdY.js → system-settings-panel-CihjIzWx.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-SSNFtY-d.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-KR5Otp5w.js → theme-store-D1_t_31B.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-lMZodtDF.js → typed-models-lib-C2LhiQq5.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-CKpatP3S.js → use-autosave-tf_8rxAK.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-BnPTFEar.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-CDcv0Wbh.js → voice-api-key-field-DN-y7Zfe.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-overlay-bqqH4aZ9.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BAHYNlQt.js → workflow-run-setup-panel-2H33iXOB.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-BnfxRf1q.js +5 -0
- package/dist/gateway/static/root/index.html +12 -10
- package/dist/package.js +1 -1
- package/dist/src/auth/oauth/xopc-cloud.js +1 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/tunnel.js +3 -3
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/connectors/composio-managed-client.d.ts +60 -0
- package/dist/src/connectors/composio-managed-client.js +135 -0
- package/dist/src/connectors/composio-managed-events.d.ts +41 -0
- package/dist/src/connectors/composio-managed-events.js +105 -0
- package/dist/src/connectors/composio-sessions.d.ts +2 -1
- package/dist/src/connectors/composio-sessions.js +13 -7
- package/dist/src/connectors/composio.js +2 -1
- package/dist/src/connectors/connected-source-ingestion.js +67 -25
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/connectors/learning-recipes.js +2 -0
- package/dist/src/connectors/runtime-adapter-registry.js +2 -2
- package/dist/src/discussions/sealer.js +2 -2
- package/dist/src/discussions/service.js +6 -2
- package/dist/src/discussions/transcript.d.ts +2 -0
- package/dist/src/discussions/transcript.js +16 -3
- package/dist/src/extensions/install.d.ts +10 -0
- package/dist/src/extensions/install.js +111 -14
- package/dist/src/extensions/loader.js +22 -18
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/middleware/auth.js +2 -2
- package/dist/src/gateway/hono/middleware/logger.js +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +11 -4
- package/dist/src/gateway/hono/routes/exposure.js +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +1 -1
- package/dist/src/gateway/hono/routes/home.js +2 -2
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/tunnel.js +3 -3
- package/dist/src/gateway/hono/routes/workflows.js +69 -0
- package/dist/src/gateway/index.js +2 -2
- package/dist/src/gateway/runtime-config.js +2 -2
- package/dist/src/gateway/security/audit.js +2 -2
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service.d.ts +1 -0
- package/dist/src/gateway/service.js +25 -10
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/notes/note-attachment-sync.js +1 -1
- package/dist/src/notes/service.d.ts +1 -0
- package/dist/src/notes/service.js +2 -1
- package/dist/src/notes/types.d.ts +2 -0
- package/dist/src/providers/model-catalog-persistence.d.ts +1 -1
- package/dist/src/providers/model-catalog-store.d.ts +2 -60
- package/dist/src/providers/model-catalog-types.d.ts +60 -0
- package/dist/src/providers/model-catalog-types.js +1 -0
- package/dist/src/providers/provider-disconnect-core.d.ts +11 -0
- package/dist/src/providers/provider-disconnect-core.js +35 -0
- package/dist/src/providers/provider-disconnect.d.ts +2 -10
- package/dist/src/providers/provider-disconnect.js +4 -26
- package/dist/src/providers/xopc-cloud-catalog-coordinator.js +2 -2
- package/dist/src/storage/sqlite/migrations/124_workflow_context_snapshots.sql +15 -0
- package/dist/src/storage/sqlite/migrations/125_project_workflow_presets.sql +12 -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/home-query-service.d.ts +12 -127
- package/dist/src/tasks/home-query-service.js +73 -271
- package/dist/src/tasks/index.js +2 -2
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/xopc-tui-keybindings.d.ts +2 -2
- package/dist/src/tunnel/index.js +2 -2
- package/dist/src/voice/audio/normalize.d.ts +1 -0
- package/dist/src/voice/audio/normalize.js +24 -4
- package/dist/src/voice/local/wav.d.ts +3 -0
- package/dist/src/voice/local/wav.js +10 -4
- package/dist/src/work-discovery/service.js +6 -8
- package/dist/src/work-discovery/types.d.ts +2 -0
- package/dist/src/workflows/context/workflow-context-snapshot-repository.d.ts +21 -0
- package/dist/src/workflows/context/workflow-context-snapshot-repository.js +40 -0
- package/dist/src/workflows/context/workflow-context.d.ts +18 -0
- package/dist/src/workflows/context/workflow-context.js +159 -0
- package/dist/src/workflows/domain/run.d.ts +10 -1
- package/dist/src/workflows/engine/workflow-engine.d.ts +1 -0
- package/dist/src/workflows/engine/workflow-engine.js +2 -0
- package/dist/src/workflows/project-presets/project-workflow-preset-repository.d.ts +20 -0
- package/dist/src/workflows/project-presets/project-workflow-preset-repository.js +38 -0
- package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +107 -22
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -0
- package/dist/src/workflows/service/workflow-writeback-service.d.ts +9 -0
- package/dist/src/workflows/service/workflow-writeback-service.js +106 -0
- package/package.json +6 -6
- package/dist/gateway/static/root/assets/agents-CjhgfuVJ.js +0 -68
- package/dist/gateway/static/root/assets/apps-page-CjmlGB5V.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-4m6Ey6wG.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-CAGCYx8U.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CKfLsxTI.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-CpipKNqX.js +0 -3
- package/dist/gateway/static/root/assets/channels-settings-Bvq-O4pt.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-CrMld2l7.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CSQRzaVn.js +0 -2
- package/dist/gateway/static/root/assets/directory-picker-path-field-DlJY90TM.js +0 -1
- package/dist/gateway/static/root/assets/home-page-BhqItS_s.js +0 -1
- package/dist/gateway/static/root/assets/index-DLhvsU9B.css +0 -2
- package/dist/gateway/static/root/assets/index-_cuTcWjB.js +0 -107
- package/dist/gateway/static/root/assets/local-app-workbench-page-DWjTmzxw.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-BA5efZ8B.js +0 -2
- package/dist/gateway/static/root/assets/messages-ctG2e-ix.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-CkHXVmKP.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-DCqet9-L.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-D0t_AjzG.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BUWPoBvw.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-vLhrrM3m.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-OP1y0Y8M.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Cxc-Ejl5.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-ZOqC6-aA.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DwvC3Iuf.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-DCRB-5q-.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-CoiedRuA.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-overlay-CGdT22un.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BwaU1RqI.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-DHYmh9G7.js +0 -5
|
@@ -3,14 +3,11 @@ import { getRelationshipSettings } from "../storage/sqlite/relationship-settings
|
|
|
3
3
|
import { listConnectorApprovals } from "../storage/sqlite/connector-repository.js";
|
|
4
4
|
import "../storage/sqlite/index.js";
|
|
5
5
|
import { TaskRepository } from "./task-repository.js";
|
|
6
|
-
import { TaskRunRepository } from "./task-run-repository.js";
|
|
7
6
|
import { TaskReadModelProjector } from "./task-read-model-projector.js";
|
|
8
7
|
import "../automations/domain/defaults.js";
|
|
9
8
|
import "../automations/index.js";
|
|
10
9
|
import { AttentionGovernor } from "./attention-governor.js";
|
|
11
10
|
import { listGatewayAgents } from "../gateway/agents-admin.js";
|
|
12
|
-
import { getTunnelService } from "../tunnel/tunnel-service.js";
|
|
13
|
-
import "../tunnel/index.js";
|
|
14
11
|
//#region src/tasks/home-query-service.ts
|
|
15
12
|
function toHomeWorkflowRun(run) {
|
|
16
13
|
return {
|
|
@@ -51,21 +48,6 @@ function toHomeAutomation(automation) {
|
|
|
51
48
|
nextRunAt: new Date(automation.state.nextRunAtMs).toISOString()
|
|
52
49
|
};
|
|
53
50
|
}
|
|
54
|
-
function toHomeAutomationRun(run) {
|
|
55
|
-
return {
|
|
56
|
-
id: run.id,
|
|
57
|
-
automationId: run.automationId,
|
|
58
|
-
automationName: run.automationName,
|
|
59
|
-
status: run.status,
|
|
60
|
-
createdAtMs: run.createdAtMs,
|
|
61
|
-
startedAtMs: run.startedAtMs,
|
|
62
|
-
endedAtMs: run.endedAtMs,
|
|
63
|
-
error: run.error,
|
|
64
|
-
summary: run.summary,
|
|
65
|
-
sessionKey: run.sessionKey,
|
|
66
|
-
workflowRunId: run.workflowRunId
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
51
|
function effectiveAutomationTimeoutSeconds(run, automation) {
|
|
70
52
|
return ("timeoutSeconds" in run.actionSnapshot ? run.actionSnapshot.timeoutSeconds : void 0) ?? automation?.reliability?.timeoutSeconds ?? 1800;
|
|
71
53
|
}
|
|
@@ -79,41 +61,46 @@ function attentionDetail(kind, status, locale, timeoutSeconds) {
|
|
|
79
61
|
if (isChinese) return kind === "automation_run" ? "自动化未能完成,请查看详情后重试。" : "工作流未能完成,请查看详情后重试。";
|
|
80
62
|
return kind === "automation_run" ? "The automation did not complete. Review the details and retry." : "The workflow did not complete. Review the details and retry.";
|
|
81
63
|
}
|
|
82
|
-
function decisionFromTask(model, projectName) {
|
|
83
|
-
const item = model.attention[0];
|
|
84
|
-
if (!item || !["input_required", "approval_required"].includes(item.kind)) return null;
|
|
64
|
+
function decisionFromTask(model, projectName, locale) {
|
|
85
65
|
const task = model.task;
|
|
66
|
+
const isChinese = locale?.toLowerCase().startsWith("zh") ?? task.locale === "zh";
|
|
67
|
+
if (task.phase === "review") return {
|
|
68
|
+
id: `task:${task.id}:review`,
|
|
69
|
+
kind: "task",
|
|
70
|
+
title: task.title,
|
|
71
|
+
detail: isChinese ? "执行已经完成,正在等待你验收结果。" : "The work is complete and ready for your review.",
|
|
72
|
+
reason: "decision_needed",
|
|
73
|
+
urgency: "now",
|
|
74
|
+
href: `/tasks/${encodeURIComponent(task.id)}`,
|
|
75
|
+
projectId: task.projectId,
|
|
76
|
+
projectName,
|
|
77
|
+
dueAt: task.dueAt,
|
|
78
|
+
updatedAt: task.updatedAt
|
|
79
|
+
};
|
|
80
|
+
const item = model.attention.find((candidate) => [
|
|
81
|
+
"input_required",
|
|
82
|
+
"approval_required",
|
|
83
|
+
"run_failed",
|
|
84
|
+
"verification_failed",
|
|
85
|
+
"overdue"
|
|
86
|
+
].includes(candidate.kind));
|
|
87
|
+
if (!item) return null;
|
|
88
|
+
const reason = item.kind === "input_required" ? "needs_input" : item.kind === "approval_required" ? "approval_required" : item.kind === "run_failed" || item.kind === "verification_failed" ? "retry" : item.kind === "overdue" ? "overdue" : void 0;
|
|
89
|
+
if (!reason) return null;
|
|
86
90
|
return {
|
|
87
91
|
id: `task:${task.id}`,
|
|
88
92
|
kind: "task",
|
|
89
93
|
title: task.title,
|
|
90
94
|
detail: item.summary,
|
|
91
|
-
reason
|
|
95
|
+
reason,
|
|
92
96
|
urgency: "now",
|
|
93
97
|
href: `/tasks/${encodeURIComponent(task.id)}`,
|
|
94
98
|
projectId: task.projectId,
|
|
95
99
|
projectName,
|
|
100
|
+
dueAt: task.dueAt,
|
|
96
101
|
updatedAt: task.updatedAt
|
|
97
102
|
};
|
|
98
103
|
}
|
|
99
|
-
function buildHomeBriefing(input) {
|
|
100
|
-
const isChinese = input.locale?.toLowerCase().startsWith("zh") ?? false;
|
|
101
|
-
const movingCount = input.activeWorkflowCount + input.activeTaskCount;
|
|
102
|
-
const attentionCount = input.decisions.length + input.attention.length;
|
|
103
|
-
const summary = attentionCount > 0 ? isChinese ? movingCount > 0 ? `有 ${attentionCount} 件事需要你处理;我正在继续推进 ${movingCount} 件工作。` : `有 ${attentionCount} 件事需要你处理。` : movingCount > 0 ? `${attentionCount} ${attentionCount === 1 ? "item needs" : "items need"} your attention; I’m continuing ${movingCount} in the background.` : `${attentionCount} ${attentionCount === 1 ? "item needs" : "items need"} your attention.` : movingCount > 0 ? isChinese ? `目前没有事情需要你处理;我正在继续推进 ${movingCount} 件工作。` : `Nothing needs you right now; I’m continuing ${movingCount} ${movingCount === 1 ? "item" : "items"} in the background.` : isChinese ? "今天还没有正在推进的事项。把想要的结果交给我,我会从这里开始。" : "Nothing is moving yet today. Hand me an task and I’ll take it from here.";
|
|
104
|
-
return {
|
|
105
|
-
generatedAt: input.nowMs,
|
|
106
|
-
summary,
|
|
107
|
-
focus: input.decisions.slice(0, 3),
|
|
108
|
-
progress: {
|
|
109
|
-
activeWorkflowCount: input.activeWorkflowCount,
|
|
110
|
-
activeTaskCount: input.activeTaskCount,
|
|
111
|
-
movingCount
|
|
112
|
-
},
|
|
113
|
-
wins: input.wins.slice(0, 5),
|
|
114
|
-
nextScheduled: input.nextScheduled
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
104
|
function homeActionCopy(locale) {
|
|
118
105
|
return locale?.toLowerCase().startsWith("zh") ?? false ? {
|
|
119
106
|
approve: "允许并继续",
|
|
@@ -122,21 +109,14 @@ function homeActionCopy(locale) {
|
|
|
122
109
|
retry: "重试",
|
|
123
110
|
acknowledge: "暂时忽略",
|
|
124
111
|
viewProgress: "查看进度",
|
|
125
|
-
viewResult: "查看结果",
|
|
126
112
|
viewSchedule: "查看计划",
|
|
127
|
-
remaining: "项待继续",
|
|
128
|
-
taskCompleted: "任务已完成",
|
|
129
|
-
workflowCompleted: "工作流已完成",
|
|
130
|
-
automationCompleted: "自动化已完成",
|
|
131
113
|
runningTask: "任务正在推进",
|
|
132
114
|
runningWorkflow: "工作流正在推进",
|
|
133
115
|
scheduled: "下一项定时工作",
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
startSomethingSummary: "把想要的结果交给我,我会从这里开始。",
|
|
139
|
-
askAi: "交给 Agent"
|
|
116
|
+
inputRecommendation: "建议补充所需信息,让工作继续推进。",
|
|
117
|
+
approvalRecommendation: "建议先确认操作范围;符合预期后允许本次操作。",
|
|
118
|
+
reviewRecommendation: "建议查看结果,确认符合预期后完成验收。",
|
|
119
|
+
retryRecommendation: "建议先重试;如果再次失败,再检查执行详情。"
|
|
140
120
|
} : {
|
|
141
121
|
approve: "Allow and continue",
|
|
142
122
|
deny: "Deny",
|
|
@@ -144,21 +124,14 @@ function homeActionCopy(locale) {
|
|
|
144
124
|
retry: "Retry",
|
|
145
125
|
acknowledge: "Dismiss",
|
|
146
126
|
viewProgress: "View progress",
|
|
147
|
-
viewResult: "View result",
|
|
148
127
|
viewSchedule: "View schedule",
|
|
149
|
-
remaining: "remaining",
|
|
150
|
-
taskCompleted: "Task completed",
|
|
151
|
-
workflowCompleted: "Workflow completed",
|
|
152
|
-
automationCompleted: "Automation completed",
|
|
153
128
|
runningTask: "Task in progress",
|
|
154
129
|
runningWorkflow: "Workflow in progress",
|
|
155
130
|
scheduled: "Next scheduled work",
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
startSomethingSummary: "Hand me the outcome you want and I’ll take it from here.",
|
|
161
|
-
askAi: "Ask an agent"
|
|
131
|
+
inputRecommendation: "Provide the missing information so the work can continue.",
|
|
132
|
+
approvalRecommendation: "Confirm the operation scope, then allow it if it matches your intent.",
|
|
133
|
+
reviewRecommendation: "Review the result and accept it if it meets your expectations.",
|
|
134
|
+
retryRecommendation: "Retry once; inspect the run details if it fails again."
|
|
162
135
|
};
|
|
163
136
|
}
|
|
164
137
|
function formatScheduleDistance(value, nowMs, locale) {
|
|
@@ -170,7 +143,14 @@ function formatScheduleDistance(value, nowMs, locale) {
|
|
|
170
143
|
if (hours < 48) return formatter.format(hours, "hour");
|
|
171
144
|
return formatter.format(Math.ceil(distanceMs / 864e5), "day");
|
|
172
145
|
}
|
|
173
|
-
function
|
|
146
|
+
function decisionRecommendation(decision, copy) {
|
|
147
|
+
if (decision.judgment?.recommendation) return decision.judgment.recommendation;
|
|
148
|
+
if (decision.reason === "needs_input" || decision.reason === "user_input") return copy.inputRecommendation;
|
|
149
|
+
if (decision.reason === "approval_required" || decision.reason === "user_approval") return copy.approvalRecommendation;
|
|
150
|
+
if (decision.reason === "retry") return copy.retryRecommendation;
|
|
151
|
+
return copy.reviewRecommendation;
|
|
152
|
+
}
|
|
153
|
+
function buildHomeWorkbench(input) {
|
|
174
154
|
const copy = homeActionCopy(input.locale);
|
|
175
155
|
const decisions = input.decisions.map((decision) => {
|
|
176
156
|
const openAction = decision.kind === "agent_judgment" && decision.judgment ? {
|
|
@@ -202,10 +182,10 @@ function buildHomeFocusItems(input) {
|
|
|
202
182
|
return {
|
|
203
183
|
id: decision.id,
|
|
204
184
|
kind: "decision",
|
|
205
|
-
priority: decision.urgency === "now" ? 100 : 90,
|
|
206
185
|
title: decision.title,
|
|
207
186
|
summary: decision.detail || copy.review,
|
|
208
|
-
|
|
187
|
+
recommendation: decisionRecommendation(decision, copy),
|
|
188
|
+
dueAt: decision.dueAt,
|
|
209
189
|
updatedAt: decision.updatedAt,
|
|
210
190
|
openAction,
|
|
211
191
|
...connectorActions
|
|
@@ -214,9 +194,9 @@ function buildHomeFocusItems(input) {
|
|
|
214
194
|
const failures = input.attention.map((item) => ({
|
|
215
195
|
id: item.id,
|
|
216
196
|
kind: "failure",
|
|
217
|
-
priority: 80,
|
|
218
197
|
title: item.title,
|
|
219
198
|
summary: item.detail,
|
|
199
|
+
recommendation: copy.retryRecommendation,
|
|
220
200
|
updatedAt: item.updatedAt,
|
|
221
201
|
openAction: {
|
|
222
202
|
type: "open",
|
|
@@ -245,13 +225,11 @@ function buildHomeFocusItems(input) {
|
|
|
245
225
|
return {
|
|
246
226
|
id: `workflow:${run.id}`,
|
|
247
227
|
kind: "running",
|
|
248
|
-
priority: 60,
|
|
249
228
|
title: run.title,
|
|
250
229
|
summary: copy.runningWorkflow,
|
|
251
230
|
statusLabel: run.metrics.agentCount > 0 ? `${run.metrics.doneAgentCount}/${run.metrics.agentCount}` : void 0,
|
|
252
231
|
updatedAt: run.startedAtMs ?? run.createdAtMs,
|
|
253
232
|
openAction,
|
|
254
|
-
primaryAction: openAction,
|
|
255
233
|
secondaryActions: []
|
|
256
234
|
};
|
|
257
235
|
});
|
|
@@ -264,56 +242,16 @@ function buildHomeFocusItems(input) {
|
|
|
264
242
|
return {
|
|
265
243
|
id: `task:${task.id}`,
|
|
266
244
|
kind: "running",
|
|
267
|
-
priority: 55,
|
|
268
245
|
title: task.title,
|
|
269
246
|
summary: copy.runningTask,
|
|
270
247
|
updatedAt: task.updatedAt,
|
|
271
248
|
openAction,
|
|
272
|
-
primaryAction: openAction,
|
|
273
|
-
secondaryActions: []
|
|
274
|
-
};
|
|
275
|
-
});
|
|
276
|
-
const results = input.wins.map((win) => {
|
|
277
|
-
const openAction = {
|
|
278
|
-
type: "open",
|
|
279
|
-
label: copy.viewResult,
|
|
280
|
-
href: win.href
|
|
281
|
-
};
|
|
282
|
-
return {
|
|
283
|
-
id: win.id,
|
|
284
|
-
kind: "result",
|
|
285
|
-
priority: 40,
|
|
286
|
-
title: win.title,
|
|
287
|
-
summary: win.kind === "workflow_run" ? copy.workflowCompleted : win.kind === "automation_run" ? copy.automationCompleted : copy.taskCompleted,
|
|
288
|
-
updatedAt: win.completedAt,
|
|
289
|
-
openAction,
|
|
290
|
-
primaryAction: openAction,
|
|
291
|
-
secondaryActions: []
|
|
292
|
-
};
|
|
293
|
-
});
|
|
294
|
-
const taskResults = input.recentTasks.map(({ taskId, taskTitle, receipt }) => {
|
|
295
|
-
const openAction = {
|
|
296
|
-
type: "open",
|
|
297
|
-
label: copy.viewResult,
|
|
298
|
-
href: `/tasks/${encodeURIComponent(taskId)}`
|
|
299
|
-
};
|
|
300
|
-
return {
|
|
301
|
-
id: `task-result:${taskId}:${receipt.runId}`,
|
|
302
|
-
kind: "result",
|
|
303
|
-
priority: 40,
|
|
304
|
-
title: taskTitle,
|
|
305
|
-
summary: receipt.summary,
|
|
306
|
-
statusLabel: receipt.remainingWork.length > 0 ? `${receipt.remainingWork.length} ${copy.remaining}` : void 0,
|
|
307
|
-
updatedAt: receipt.finalizedAt,
|
|
308
|
-
openAction,
|
|
309
|
-
primaryAction: openAction,
|
|
310
249
|
secondaryActions: []
|
|
311
250
|
};
|
|
312
251
|
});
|
|
313
252
|
const scheduled = input.scheduled.map((automation) => ({
|
|
314
253
|
id: `automation:${automation.id}:scheduled`,
|
|
315
254
|
kind: "scheduled",
|
|
316
|
-
priority: 30,
|
|
317
255
|
title: automation.name || automation.id,
|
|
318
256
|
summary: copy.scheduled,
|
|
319
257
|
statusLabel: formatScheduleDistance(automation.nextRunAt, input.nowMs, input.locale),
|
|
@@ -323,63 +261,27 @@ function buildHomeFocusItems(input) {
|
|
|
323
261
|
label: copy.viewSchedule,
|
|
324
262
|
href: `/automations?automation=${encodeURIComponent(automation.id)}`
|
|
325
263
|
},
|
|
326
|
-
primaryAction: {
|
|
327
|
-
type: "open",
|
|
328
|
-
label: copy.viewSchedule,
|
|
329
|
-
href: `/automations?automation=${encodeURIComponent(automation.id)}`
|
|
330
|
-
},
|
|
331
264
|
secondaryActions: []
|
|
332
265
|
}));
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
|
|
266
|
+
const urgencyById = new Map(input.decisions.map((decision) => [decision.id, decision.urgency]));
|
|
267
|
+
decisions.sort((left, right) => {
|
|
268
|
+
const leftUrgency = urgencyById.get(left.id) === "now" ? 1 : 0;
|
|
269
|
+
return (urgencyById.get(right.id) === "now" ? 1 : 0) - leftUrgency || right.updatedAt - left.updatedAt;
|
|
270
|
+
});
|
|
271
|
+
failures.sort((left, right) => right.updatedAt - left.updatedAt);
|
|
272
|
+
const needsUser = [...decisions, ...failures];
|
|
273
|
+
const allBackground = [
|
|
336
274
|
...workflows,
|
|
337
275
|
...tasks,
|
|
338
|
-
...results,
|
|
339
|
-
...taskResults,
|
|
340
276
|
...scheduled
|
|
341
|
-
]
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
347
|
-
if (items.length > 0) return items;
|
|
348
|
-
if (input.inboxCount > 0) return [{
|
|
349
|
-
id: "suggestion:organize-inbox",
|
|
350
|
-
kind: "suggestion",
|
|
351
|
-
priority: 10,
|
|
352
|
-
title: `${copy.organizeInbox} · ${input.inboxCount}`,
|
|
353
|
-
summary: copy.organizeInboxSummary,
|
|
354
|
-
updatedAt: input.nowMs,
|
|
355
|
-
openAction: {
|
|
356
|
-
type: "open",
|
|
357
|
-
label: copy.openInbox,
|
|
358
|
-
href: "/notes?status=inbox"
|
|
359
|
-
},
|
|
360
|
-
primaryAction: {
|
|
361
|
-
type: "open",
|
|
362
|
-
label: copy.openInbox,
|
|
363
|
-
href: "/notes?status=inbox"
|
|
364
|
-
},
|
|
365
|
-
secondaryActions: []
|
|
366
|
-
}];
|
|
367
|
-
return [{
|
|
368
|
-
id: "suggestion:ask-agent",
|
|
369
|
-
kind: "suggestion",
|
|
370
|
-
priority: 10,
|
|
371
|
-
title: copy.startSomething,
|
|
372
|
-
summary: copy.startSomethingSummary,
|
|
373
|
-
updatedAt: input.nowMs,
|
|
374
|
-
primaryAction: {
|
|
375
|
-
type: "ask_ai",
|
|
376
|
-
label: copy.askAi
|
|
377
|
-
},
|
|
378
|
-
secondaryActions: []
|
|
379
|
-
}];
|
|
277
|
+
];
|
|
278
|
+
return {
|
|
279
|
+
needsUser,
|
|
280
|
+
background: allBackground.slice(0, 3),
|
|
281
|
+
backgroundCount: allBackground.length
|
|
282
|
+
};
|
|
380
283
|
}
|
|
381
284
|
var HomeQueryService = class {
|
|
382
|
-
#runs = new TaskRunRepository();
|
|
383
285
|
#tasks = new TaskRepository();
|
|
384
286
|
#projector = new TaskReadModelProjector();
|
|
385
287
|
#attentionGovernor = new AttentionGovernor();
|
|
@@ -387,37 +289,12 @@ var HomeQueryService = class {
|
|
|
387
289
|
this.service = service;
|
|
388
290
|
}
|
|
389
291
|
async getSnapshot(locale) {
|
|
390
|
-
const notes = this.service.notesServiceInstance;
|
|
391
|
-
const sessions = this.service.sessions;
|
|
392
292
|
const agents = await listGatewayAgents(this.service.currentConfig);
|
|
393
293
|
const defaultAgent = agents.agents.find((agent) => agent.id === agents.defaultId) ?? agents.agents[0];
|
|
394
294
|
const workflowRunStore = this.service.createWorkflowRunService().createRunStore(defaultAgent?.id ?? agents.defaultId);
|
|
395
|
-
const tunnel = getTunnelService().getStatus();
|
|
396
|
-
const health = this.service.getHealth();
|
|
397
295
|
const nowMs = Date.now();
|
|
398
296
|
const tasks = this.#tasks.list({ limit: 60 });
|
|
399
|
-
const [
|
|
400
|
-
notes.listNotes({
|
|
401
|
-
sortBy: "lastOpenedAt",
|
|
402
|
-
sortOrder: "desc",
|
|
403
|
-
limit: 10
|
|
404
|
-
}),
|
|
405
|
-
notes.listNotes({
|
|
406
|
-
status: "inbox",
|
|
407
|
-
limit: 0
|
|
408
|
-
}),
|
|
409
|
-
notes.listNotes({
|
|
410
|
-
pendingTasksOnly: true,
|
|
411
|
-
sortBy: "createdAt",
|
|
412
|
-
sortOrder: "desc",
|
|
413
|
-
limit: 10
|
|
414
|
-
}),
|
|
415
|
-
sessions.listSessions({
|
|
416
|
-
channel: "webchat",
|
|
417
|
-
sortBy: "updatedAt",
|
|
418
|
-
sortOrder: "desc",
|
|
419
|
-
limit: 50
|
|
420
|
-
}),
|
|
297
|
+
const [workflowRuns, automations, automationRuns, projects, connectorApprovals] = await Promise.all([
|
|
421
298
|
workflowRunStore.listRunSummaries(20),
|
|
422
299
|
this.service.automationServiceInstance.list(),
|
|
423
300
|
this.service.automationServiceInstance.listRuns({ limit: 10 }),
|
|
@@ -430,16 +307,9 @@ var HomeQueryService = class {
|
|
|
430
307
|
]);
|
|
431
308
|
const activeTasks = tasks.filter((task) => task.phase !== "closed");
|
|
432
309
|
const projectsById = new Map(projects.items.map((project) => [project.id, project]));
|
|
433
|
-
const
|
|
434
|
-
key: session.key,
|
|
435
|
-
name: session.name || "Conversation",
|
|
436
|
-
updatedAt: session.updatedAt,
|
|
437
|
-
active: sessions.getActiveRun(session.key).active
|
|
438
|
-
}));
|
|
439
|
-
const activeWorkflowRuns = workflowRuns.filter((run) => run.status === "queued" || run.status === "running").slice(0, 5).map(toHomeWorkflowRun);
|
|
310
|
+
const activeWorkflowRuns = workflowRuns.filter((run) => run.status === "queued" || run.status === "running").map(toHomeWorkflowRun);
|
|
440
311
|
const failedWorkflowRuns = workflowRuns.filter((run) => run.status === "failed" || run.status === "timeout").slice(0, 5).map(toHomeWorkflowRun);
|
|
441
|
-
const
|
|
442
|
-
const upcomingAutomations = automations.map(toHomeAutomation).filter((automation) => Boolean(automation)).sort((a, b) => Date.parse(a.nextRunAt) - Date.parse(b.nextRunAt)).slice(0, 5);
|
|
312
|
+
const upcomingAutomations = automations.filter((automation) => automation.notificationPolicy !== "none").map(toHomeAutomation).filter((automation) => Boolean(automation)).sort((a, b) => Date.parse(a.nextRunAt) - Date.parse(b.nextRunAt));
|
|
443
313
|
const latestAutomationRuns = [...automationRuns].sort((left, right) => right.createdAtMs - left.createdAtMs).filter((run, index, all) => all.findIndex((candidate) => candidate.automationId === run.automationId) === index);
|
|
444
314
|
const automationsById = new Map(automations.map((automation) => [automation.id, automation]));
|
|
445
315
|
const decisionCandidates = [
|
|
@@ -468,7 +338,7 @@ var HomeQueryService = class {
|
|
|
468
338
|
...item.insight.decision && (!item.insight.proposedAction || item.insight.actionStatus === "approval_required") ? { decision: item.insight.decision } : {}
|
|
469
339
|
}
|
|
470
340
|
})),
|
|
471
|
-
...activeTasks.map((task) => decisionFromTask(this.#projector.project(task), task.projectId ? projectsById.get(task.projectId)?.name : void 0)).filter((item) => Boolean(item)),
|
|
341
|
+
...activeTasks.map((task) => decisionFromTask(this.#projector.project(task), task.projectId ? projectsById.get(task.projectId)?.name : void 0, locale)).filter((item) => Boolean(item)),
|
|
472
342
|
...connectorApprovals.filter((approval) => Date.parse(approval.expiresAt) > nowMs).map((approval) => ({
|
|
473
343
|
id: `connector-approval:${approval.id}`,
|
|
474
344
|
kind: "connector_approval",
|
|
@@ -494,7 +364,7 @@ var HomeQueryService = class {
|
|
|
494
364
|
href: `/workflows?runId=${encodeURIComponent(run.id)}`,
|
|
495
365
|
updatedAt: run.completedAtMs ?? run.startedAtMs ?? run.createdAtMs,
|
|
496
366
|
sessionKey: run.sessionKey
|
|
497
|
-
})), ...latestAutomationRuns.filter((run) => run.status === "failed" || run.status === "timeout").filter((run) => !isHomeAttentionAcknowledged("automation_run", run.id)).map((run) => ({
|
|
367
|
+
})), ...latestAutomationRuns.filter((run) => run.status === "failed" || run.status === "timeout").filter((run) => automationsById.get(run.automationId)?.notificationPolicy !== "none").filter((run) => !isHomeAttentionAcknowledged("automation_run", run.id)).map((run) => ({
|
|
498
368
|
id: `automation_run:${run.id}`,
|
|
499
369
|
kind: "automation_run",
|
|
500
370
|
runId: run.id,
|
|
@@ -512,91 +382,23 @@ var HomeQueryService = class {
|
|
|
512
382
|
});
|
|
513
383
|
const decisions = governed.decisions;
|
|
514
384
|
const attention = governed.attention;
|
|
515
|
-
const wins = [...workflowRuns.filter((run) => run.status === "succeeded").map((run) => ({
|
|
516
|
-
id: `workflow:${run.id}`,
|
|
517
|
-
kind: "workflow_run",
|
|
518
|
-
title: run.title,
|
|
519
|
-
href: `/workflows?runId=${encodeURIComponent(run.id)}`,
|
|
520
|
-
completedAt: run.completedAtMs ?? run.createdAtMs
|
|
521
|
-
})), ...latestAutomationRuns.filter((run) => run.status === "succeeded").map((run) => ({
|
|
522
|
-
id: `automation:${run.id}`,
|
|
523
|
-
kind: "automation_run",
|
|
524
|
-
title: run.automationName || run.automationId,
|
|
525
|
-
href: `/automations?automation=${encodeURIComponent(run.automationId)}&run=${encodeURIComponent(run.id)}`,
|
|
526
|
-
completedAt: run.endedAtMs ?? run.createdAtMs
|
|
527
|
-
}))].sort((left, right) => right.completedAt - left.completedAt);
|
|
528
|
-
const runningTasks = tasks.filter((task) => {
|
|
529
|
-
const state = this.#projector.project(task).operationalState;
|
|
530
|
-
return state === "queued" || state === "running" || state === "verifying";
|
|
531
|
-
}).slice(0, 20);
|
|
532
|
-
const briefing = buildHomeBriefing({
|
|
533
|
-
locale,
|
|
534
|
-
decisions,
|
|
535
|
-
attention,
|
|
536
|
-
activeWorkflowCount: activeWorkflowRuns.length,
|
|
537
|
-
activeTaskCount: activeTasks.length,
|
|
538
|
-
wins,
|
|
539
|
-
nextScheduled: upcomingAutomations[0],
|
|
540
|
-
nowMs
|
|
541
|
-
});
|
|
542
|
-
const recentTasks = tasks.flatMap((task) => this.#runs.listReceipts(task.id, 3).map((receipt) => ({
|
|
543
|
-
taskId: task.id,
|
|
544
|
-
taskTitle: task.title,
|
|
545
|
-
receipt
|
|
546
|
-
}))).sort((a, b) => b.receipt.finalizedAt - a.receipt.finalizedAt).slice(0, 8);
|
|
547
385
|
return {
|
|
548
|
-
|
|
386
|
+
...buildHomeWorkbench({
|
|
549
387
|
locale,
|
|
550
388
|
decisions,
|
|
551
389
|
attention,
|
|
552
390
|
activeWorkflowRuns,
|
|
553
|
-
runningTasks
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
391
|
+
runningTasks: tasks.filter((task) => {
|
|
392
|
+
const state = this.#projector.project(task).operationalState;
|
|
393
|
+
return state === "queued" || state === "running" || state === "verifying";
|
|
394
|
+
}),
|
|
395
|
+
scheduled: upcomingAutomations,
|
|
558
396
|
nowMs
|
|
559
397
|
}),
|
|
560
|
-
recentlyOpened: recentlyOpened.items.filter((note) => note.lastOpenedAt),
|
|
561
|
-
inboxCount: inbox.total,
|
|
562
|
-
pendingTasks: pendingTasks.items,
|
|
563
|
-
pendingTaskCount: pendingTasks.total,
|
|
564
|
-
recentSessions: recentSessions.items.slice(0, 5),
|
|
565
|
-
activeAgent: defaultAgent ? {
|
|
566
|
-
id: defaultAgent.id,
|
|
567
|
-
name: defaultAgent.name,
|
|
568
|
-
description: defaultAgent.description
|
|
569
|
-
} : { id: agents.defaultId },
|
|
570
|
-
gateway: {
|
|
571
|
-
status: health.status,
|
|
572
|
-
ready: health.ready,
|
|
573
|
-
httpListening: health.httpListening,
|
|
574
|
-
version: health.version,
|
|
575
|
-
uptime: health.uptime,
|
|
576
|
-
tunnel: {
|
|
577
|
-
state: tunnel.state,
|
|
578
|
-
publicUrl: tunnel.publicUrl,
|
|
579
|
-
connected: tunnel.state === "connected"
|
|
580
|
-
}
|
|
581
|
-
},
|
|
582
|
-
workflowRuns: {
|
|
583
|
-
active: activeWorkflowRuns,
|
|
584
|
-
recent: recentWorkflowRuns
|
|
585
|
-
},
|
|
586
|
-
briefing,
|
|
587
398
|
decisions,
|
|
588
|
-
|
|
589
|
-
attentionPolicy: governed.policy,
|
|
590
|
-
chats: {
|
|
591
|
-
running: workChats.filter((chat) => chat.active),
|
|
592
|
-
recent: workChats.filter((chat) => !chat.active).slice(0, 8)
|
|
593
|
-
},
|
|
594
|
-
upcomingAutomations,
|
|
595
|
-
tasks: { running: runningTasks },
|
|
596
|
-
recentTasks,
|
|
597
|
-
recentAutomationRuns: automationRuns.slice(0, 5).map(toHomeAutomationRun)
|
|
399
|
+
attentionPolicy: governed.policy
|
|
598
400
|
};
|
|
599
401
|
}
|
|
600
402
|
};
|
|
601
403
|
//#endregion
|
|
602
|
-
export { HomeQueryService,
|
|
404
|
+
export { HomeQueryService, buildHomeWorkbench, decisionFromTask };
|
package/dist/src/tasks/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { TaskRunRepository } from "./task-run-repository.js";
|
|
|
4
4
|
import { TaskReadModelProjector } from "./task-read-model-projector.js";
|
|
5
5
|
import { resolveExecutionContext } from "./execution-context.js";
|
|
6
6
|
import { AttentionGovernor } from "./attention-governor.js";
|
|
7
|
-
import { HomeQueryService,
|
|
7
|
+
import { HomeQueryService, buildHomeWorkbench, decisionFromTask } from "./home-query-service.js";
|
|
8
8
|
import { TaskContextRepository } from "./task-context-repository.js";
|
|
9
9
|
import { enqueueTaskChanged, enqueueTaskChangedEvent } from "./task-change-events.js";
|
|
10
10
|
import { TaskDependencyError, TaskDependencyService } from "./task-dependency-service.js";
|
|
@@ -21,4 +21,4 @@ import { TaskHandoffService } from "./task-handoff-service.js";
|
|
|
21
21
|
import { TaskOutboxDispatcher } from "./task-outbox-dispatcher.js";
|
|
22
22
|
import { TaskRunDispatcher } from "./task-run-dispatcher.js";
|
|
23
23
|
import { TaskSignalService } from "./task-signal-service.js";
|
|
24
|
-
export { AttentionGovernor, HomeQueryService, ModelTaskContractPlanner, ProjectMonitoringService, ProjectOperatingViewService, TaskApplicationService, TaskContextRepository, TaskConversationConflictError, TaskConversationRepository, TaskDependencyError, TaskDependencyService, TaskHandoffService, TaskOutboxDispatcher, TaskReadModelProjector, TaskRepository, TaskRunCoordinator, TaskRunDispatcher, TaskRunRepository, TaskSignalService, TaskValueMetricsService, TaskWorkflowCoordinator, assembleTaskContext,
|
|
24
|
+
export { AttentionGovernor, HomeQueryService, ModelTaskContractPlanner, ProjectMonitoringService, ProjectOperatingViewService, TaskApplicationService, TaskContextRepository, TaskConversationConflictError, TaskConversationRepository, TaskDependencyError, TaskDependencyService, TaskHandoffService, TaskOutboxDispatcher, TaskReadModelProjector, TaskRepository, TaskRunCoordinator, TaskRunDispatcher, TaskRunRepository, TaskSignalService, TaskValueMetricsService, TaskWorkflowCoordinator, assembleTaskContext, buildHomeWorkbench, buildTaskExecutionDirective, decideProactiveDisposition, decisionFromTask, defineTaskContract, enqueueTaskChanged, enqueueTaskChangedEvent, getTaskContextManifest, getTaskExecutionBrief, isInQuietHours, nextQuietHoursEnd, parseTaskContractResponse, proactiveDispositionReason, resolveExecutionContext, summarizeProjectOperatingView };
|
|
@@ -5,9 +5,9 @@ import { resolveBootstrapFilesSync } from "../agent/bootstrap/bootstrap-files.js
|
|
|
5
5
|
import { createSkillConfigManager, isSkillEnabled } from "../agent/skills/config.js";
|
|
6
6
|
import { loadSkills } from "../agent/skills/index.js";
|
|
7
7
|
import { createWorkflowCatalog } from "../agent/workflow/catalog.js";
|
|
8
|
+
import { listConnectorInstances } from "../connectors/instances.js";
|
|
8
9
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
9
10
|
import "../config/index.js";
|
|
10
|
-
import { listConnectorInstances } from "../connectors/instances.js";
|
|
11
11
|
import { basename } from "node:path";
|
|
12
12
|
//#region src/tui/tui-startup-resources.ts
|
|
13
13
|
init_paths();
|
|
@@ -357,11 +357,11 @@ export declare const XOPC_TUI_KEYBINDINGS: {
|
|
|
357
357
|
readonly description: "Scroll viewport down one line";
|
|
358
358
|
};
|
|
359
359
|
readonly "tui.altScreen.previousPrompt": {
|
|
360
|
-
readonly defaultKeys: "ctrl+shift+up";
|
|
360
|
+
readonly defaultKeys: ["ctrl+shift+up", "ctrl+up"];
|
|
361
361
|
readonly description: "Jump to previous semantic prompt";
|
|
362
362
|
};
|
|
363
363
|
readonly "tui.altScreen.nextPrompt": {
|
|
364
|
-
readonly defaultKeys: "ctrl+shift+down";
|
|
364
|
+
readonly defaultKeys: ["ctrl+shift+down", "ctrl+down"];
|
|
365
365
|
readonly description: "Jump to next semantic prompt";
|
|
366
366
|
};
|
|
367
367
|
readonly "tui.altScreen.search": {
|
package/dist/src/tunnel/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { loadTunnelState, resolveTunnelStatePath, saveTunnelState } from "./tunnel-state.js";
|
|
2
2
|
import { buildMobileConnectQrPayload, resolveLanGatewayUrl } from "./tunnel-qr.js";
|
|
3
3
|
import { CURRENT_TUNNEL_CONSENT_VERSION, TUNNEL_CONSENT_REQUIRED_CODE, TUNNEL_RISK_SUMMARY_LINES, TunnelConsentError, assertTunnelMayStart, getTunnelConsentState, hasValidTunnelConsent } from "./consent.js";
|
|
4
|
-
import { TunnelBrokerClient, resolveBrokerApiBase } from "./broker-client.js";
|
|
5
4
|
import { getTunnelRegistrationSecretMeta, isMaskedTunnelSecretPatchValue, isProductionTunnelBroker, resolveTunnelBrokerUrl, resolveTunnelRegistrationSecret } from "./env.js";
|
|
6
|
-
import {
|
|
5
|
+
import { TunnelBrokerClient, resolveBrokerApiBase } from "./broker-client.js";
|
|
7
6
|
import { FRPC_VERSION, clearFrpcPathForProcess, ensureFrpcBinary, publishFrpcPathForProcess } from "./frpc-binary.js";
|
|
8
7
|
import { consumePairingSecret, createPairingSecret, resetPairingSessionsForTests } from "./pairing.js";
|
|
9
8
|
import { logTunnelAudit } from "./tunnel-audit.js";
|
|
@@ -11,5 +10,6 @@ import { TunnelService, getTunnelService, hashGatewayToken } from "./tunnel-serv
|
|
|
11
10
|
import { resolveFrpSubdomainHost } from "./frp-subdomain-host.js";
|
|
12
11
|
import { clearTunnelWellKnownCache, fetchTunnelWellKnown } from "./well-known.js";
|
|
13
12
|
import { configureTunnelFromGatewayConfig, maybeAutoStartTunnelFromConfig, wireTunnelEventsToGateway } from "./gateway-lifecycle.js";
|
|
13
|
+
import { applyTunnelConsentToConfig, mergeTunnelConfigPatch, sanitizeTunnelConfig, setTunnelEnabledInConfig } from "./tunnel-config.js";
|
|
14
14
|
import { consumeTunnelMutationLimit, resetTunnelMutationLimitsForTests } from "./tunnel-rate-limit.js";
|
|
15
15
|
export { CURRENT_TUNNEL_CONSENT_VERSION, FRPC_VERSION, TUNNEL_CONSENT_REQUIRED_CODE, TUNNEL_RISK_SUMMARY_LINES, TunnelBrokerClient, TunnelConsentError, TunnelService, applyTunnelConsentToConfig, assertTunnelMayStart, buildMobileConnectQrPayload, clearFrpcPathForProcess, clearTunnelWellKnownCache, configureTunnelFromGatewayConfig, consumePairingSecret, consumeTunnelMutationLimit, createPairingSecret, ensureFrpcBinary, fetchTunnelWellKnown, getTunnelConsentState, getTunnelRegistrationSecretMeta, getTunnelService, hasValidTunnelConsent, hashGatewayToken, isMaskedTunnelSecretPatchValue, isProductionTunnelBroker, loadTunnelState, logTunnelAudit, maybeAutoStartTunnelFromConfig, mergeTunnelConfigPatch, publishFrpcPathForProcess, resetPairingSessionsForTests, resetTunnelMutationLimitsForTests, resolveBrokerApiBase, resolveFrpSubdomainHost, resolveLanGatewayUrl, resolveTunnelBrokerUrl, resolveTunnelRegistrationSecret, resolveTunnelStatePath, sanitizeTunnelConfig, saveTunnelState, setTunnelEnabledInConfig, wireTunnelEventsToGateway };
|
|
@@ -13,5 +13,6 @@ export declare function decodeAudioToMonoFloat32(input: {
|
|
|
13
13
|
export declare function forEachNormalizedAudioSegment(input: {
|
|
14
14
|
filePath: string;
|
|
15
15
|
segmentSeconds?: number;
|
|
16
|
+
maxDurationSeconds?: number;
|
|
16
17
|
signal?: AbortSignal;
|
|
17
18
|
}, consume: (buffer: Buffer, index: number) => Promise<void>): Promise<number>;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { decodeWavToMonoFloat32 } from "../local/wav.js";
|
|
1
|
+
import { UnsupportedWavEncodingError, decodeWavToMonoFloat32 } from "../local/wav.js";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
import { mkdtemp, readFile, readdir, rm } from "node:fs/promises";
|
|
6
6
|
//#region src/voice/audio/normalize.ts
|
|
7
7
|
const TARGET_SAMPLE_RATE = 16e3;
|
|
8
|
-
const
|
|
8
|
+
const MAX_DECODED_DURATION_SECONDS = 900;
|
|
9
|
+
const MAX_DECODED_BYTES = TARGET_SAMPLE_RATE * 4 * MAX_DECODED_DURATION_SECONDS;
|
|
10
|
+
const MAX_SEGMENTED_DURATION_SECONDS = 1800;
|
|
9
11
|
var AudioNormalizationError = class extends Error {
|
|
10
12
|
code = "unsupported_audio_codec";
|
|
11
13
|
constructor(message, options) {
|
|
@@ -87,7 +89,13 @@ function runFfmpeg(args, options = {}) {
|
|
|
87
89
|
});
|
|
88
90
|
}
|
|
89
91
|
async function decodeAudioToMonoFloat32(input) {
|
|
90
|
-
if (detectAudioFormat(input.buffer) === "wav")
|
|
92
|
+
if (detectAudioFormat(input.buffer) === "wav") try {
|
|
93
|
+
const decoded = decodeWavToMonoFloat32(input.buffer);
|
|
94
|
+
if (decoded.durationSeconds > MAX_DECODED_DURATION_SECONDS) throw new AudioNormalizationError("Decoded audio exceeds the supported duration");
|
|
95
|
+
return decoded;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (!(error instanceof UnsupportedWavEncodingError)) throw error;
|
|
98
|
+
}
|
|
91
99
|
const bytes = await runFfmpeg([
|
|
92
100
|
"-i",
|
|
93
101
|
"pipe:0",
|
|
@@ -117,6 +125,10 @@ async function decodeAudioToMonoFloat32(input) {
|
|
|
117
125
|
}
|
|
118
126
|
/** Decodes a recording into bounded PCM WAV files and removes all temporary files afterwards. */
|
|
119
127
|
async function forEachNormalizedAudioSegment(input, consume) {
|
|
128
|
+
const segmentSeconds = input.segmentSeconds ?? 20;
|
|
129
|
+
const maxDurationSeconds = input.maxDurationSeconds ?? MAX_SEGMENTED_DURATION_SECONDS;
|
|
130
|
+
if (!Number.isFinite(segmentSeconds) || segmentSeconds <= 0) throw new AudioNormalizationError("Audio segment duration must be positive");
|
|
131
|
+
if (!Number.isFinite(maxDurationSeconds) || maxDurationSeconds <= 0) throw new AudioNormalizationError("Maximum audio duration must be positive");
|
|
120
132
|
const directory = await mkdtemp(join(tmpdir(), "xopc-audio-"));
|
|
121
133
|
const outputPattern = join(directory, "segment-%05d.wav");
|
|
122
134
|
try {
|
|
@@ -130,18 +142,26 @@ async function forEachNormalizedAudioSegment(input, consume) {
|
|
|
130
142
|
"1",
|
|
131
143
|
"-ar",
|
|
132
144
|
String(TARGET_SAMPLE_RATE),
|
|
145
|
+
"-t",
|
|
146
|
+
String(maxDurationSeconds + segmentSeconds),
|
|
133
147
|
"-c:a",
|
|
134
148
|
"pcm_s16le",
|
|
135
149
|
"-f",
|
|
136
150
|
"segment",
|
|
137
151
|
"-segment_time",
|
|
138
|
-
String(
|
|
152
|
+
String(segmentSeconds),
|
|
139
153
|
"-reset_timestamps",
|
|
140
154
|
"1",
|
|
141
155
|
outputPattern
|
|
142
156
|
], { signal: input.signal });
|
|
143
157
|
const files = (await readdir(directory)).filter((name) => name.endsWith(".wav")).sort();
|
|
144
158
|
if (files.length === 0) throw new AudioNormalizationError("Audio decoder produced no segments");
|
|
159
|
+
let decodedDurationSeconds = 0;
|
|
160
|
+
for (const file of files) {
|
|
161
|
+
const decoded = decodeWavToMonoFloat32(await readFile(join(directory, file)));
|
|
162
|
+
decodedDurationSeconds += decoded.durationSeconds;
|
|
163
|
+
if (decodedDurationSeconds > maxDurationSeconds + .05) throw new AudioNormalizationError(`Decoded audio exceeds the ${Math.round(maxDurationSeconds)} second limit`);
|
|
164
|
+
}
|
|
145
165
|
for (let index = 0; index < files.length; index += 1) await consume(await readFile(join(directory, files[index])), index);
|
|
146
166
|
return files.length;
|
|
147
167
|
} finally {
|