@xopcai/xopc 0.0.246 → 0.0.248
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/src/update-offset-store.js +17 -54
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/extensions/weixin/src/auth/accounts.js +3 -5
- package/dist/extensions/weixin/src/monitor/monitor.js +3 -5
- package/dist/extensions/weixin/src/storage/sync-buf.d.ts +3 -6
- package/dist/extensions/weixin/src/storage/sync-buf.js +9 -22
- package/dist/gateway/static/root/assets/{activity-store-BlxqErph.js → activity-store-etpmyV7S.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CJJzpYYS.js → agent-avatar-dicebear-BmKxSM1k.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CUXApfcE.js +1 -0
- package/dist/gateway/static/root/assets/{agents-je3sRGmk.js → agents-DNq_GKuc.js} +1 -1
- package/dist/gateway/static/root/assets/{api-BbXzyQMj.js → api-B0-hLuZ1.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Cnn3i00c.js → app-management-settings-panel-qfwAgyhQ.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BToQaw_v.js → appearance-settings-DqQVUpCC.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-dwIqYmXk.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-DD2SweEH.js → archive-plugin-BnMSgZvR.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BFtcib5t.js → attachment-load-CejsQMev.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-XS8wIl5o.js → automations-page-RC8EyoAf.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-SkdcSZ0i.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-Xs7pLHxR.js → binary-plugins-DGjppLSG.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BPdSzceB.js → block-editor-CWdP4bUc.js} +44 -44
- package/dist/gateway/static/root/assets/browser-settings-page-CKCa6TvG.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-BAAc151l.js → browser-workflow-inputs-BQ1Ilw_o.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-DUPPvE30.js → browser-workflows-page-CJh4NyxT.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-cl9kYilL.js → capabilities-settings-panel-DSp--zIZ.js} +5 -5
- package/dist/gateway/static/root/assets/channels-settings-CMd2dDrI.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-CCBCtLDg.js → channels-status-swr-Ohhee4vm.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-DKW1M6aJ.js → chat-terminal-dock-BOtoKTK3.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-udWs5Kdm.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-Bijb0ZQu.js → cron-expression-DTj1V3Sw.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-BZuHw-SY.js → date-picker-Yr6OCvGL.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-BsBD2JFY.js → dependency-picker-DpN3XZg9.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Ceuw3QKb.js → desktop-pet-DbGzggPF.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DctOXexM.js → desktop-pet-settings-DinCToZh.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BNlMPATK.js → extension-debug-page-DgTtk4KC.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CK4Uvzge.js → extension-page-DtQeiP6f.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CpnXXemw.js → extension-settings-page-DcguCgsH.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-C_mlpe-r.js → gateway-config-api-Br7lSf6H.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-826dipyU.js → gateway-config-swr-DXuXtU1w.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DSSW17ed.js → gateway-settings-CdPoDMuj.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-DyvcAIMm.js → gateway-startup-retry-CzBzglzQ.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-hbmIZTpg.js → heartbeat-settings-DHk1hawP.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-YGipe_W6.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-D7cyfks6.js → image-generation-api-TIgsn04n.js} +1 -1
- package/dist/gateway/static/root/assets/{index-eZjksPvq.js → index-D5TQQpeb.js} +44 -44
- package/dist/gateway/static/root/assets/index-DReBaaTX.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BQrDwwgi.js → keyboard-shortcuts-settings-wsWuoa8p.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-CpyvYyrb.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-D-YWD6LS.js → local-apps-page-CXrbrGo8.js} +1 -1
- package/dist/gateway/static/root/assets/local-context-graph-BjUf7fQ9.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-CBoCuIMx.js → locale-store-BJFLQY8O.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-DvLc9l59.js → logs-page-CXKy6E_l.js} +2 -2
- package/dist/gateway/static/root/assets/{management-settings-DsULLUUv.js → management-settings-BdJZFR7U.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-CjqlP6IB.js → markdown-split-NK3ACVG2.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-BXsHghJd.js → markdown-view-DTF9v1gg.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DQL029DU.js → media-plugins-F0jcUxyl.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CHNYp8EQ.js +3 -0
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-gauprAae.js → mobile-pairing-wizard-3NKCniSp.js} +1 -1
- package/dist/gateway/static/root/assets/models-hub-cache-nCfkBN8M.js +1 -0
- package/dist/gateway/static/root/assets/{notes-page-AsEfLZt9.js → notes-page-DuqLahi6.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-C7j9EdQk.js +5 -0
- package/dist/gateway/static/root/assets/{oauth-api-BjSUDIgq.js → oauth-api-8lP_qJpq.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CAJeUXeU.js → product-open-page-CxGGlWA8.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-CfebYVX0.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-48GvzSVa.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BhGKnvLP.js → registry-api-CIsNlSBi.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-64xj_s2m.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DH6EilMV.js → runtime-tools-settings-panel-YkjhiQfA.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-DYHmEZeZ.js → schema-form-oFGf3G3s.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CcwcdRN8.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BaN84CyW.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-BHwPd_M3.js → settings-page-C7VWs0IT.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DVVOCNbr.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BjwrS03F.js → share-preview-page-t5oz18rh.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DUYbYLi7.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BGyD0gB9.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-OHyK25op.js → skills-page-CjF8DTsN.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DQx9ulmg.js → skills-page.utils-DEDTYs2W.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-wO7DWv4C.js → system-settings-panel-BSYuRgFI.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-YZYSTJH7.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-hybK3oC9.js → theme-store-O597U8q_.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-CVC8BHZu.js → tunnel-api-FKUi9wDL.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DMvRu2XZ.js → use-autosave-B5eUJ6Zq.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-BCyiduKd.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DuBK2NDG.js → voice-api-key-field-CMKSwz4C.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-CBbiF1T3.js → voice-config-api-q7B6fOFB.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-B7VXWpDr.js → work-discovery-overlay-jhT2EzeH.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BokVAsWN.js → workflow-run-setup-panel-DZmvLZjb.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DQC0TpMa.js +5 -0
- package/dist/gateway/static/root/index.html +12 -12
- package/dist/package.js +1 -1
- package/dist/src/agent/commands/command-registry.d.ts +1 -0
- package/dist/src/agent/commands/command-registry.js +12 -22
- package/dist/src/agent/ipc/inbox.d.ts +8 -31
- package/dist/src/agent/ipc/inbox.js +64 -133
- package/dist/src/agent/service/process-direct-one-shot.js +15 -10
- package/dist/src/agent/workflow/catalog.d.ts +1 -8
- package/dist/src/agent/workflow/catalog.js +44 -102
- package/dist/src/agent/workflow/index.d.ts +1 -1
- package/dist/src/agent/workflow/index.js +2 -2
- package/dist/src/automations/domain/types.d.ts +1 -0
- package/dist/src/automations/service/action-executor.js +2 -2
- package/dist/src/automations/service/automation-service.js +2 -2
- package/dist/src/channels/manager.d.ts +1 -1
- package/dist/src/channels/manager.js +2 -2
- package/dist/src/channels/outbound/persist-store.d.ts +2 -8
- package/dist/src/channels/outbound/persist-store.js +11 -38
- package/dist/src/channels/outbound-sender.d.ts +1 -1
- package/dist/src/channels/outbound-sender.js +2 -2
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/schema.js +2 -2
- package/dist/src/connectors/auth-provider-registry.js +1 -1
- package/dist/src/connectors/composio-triggers.d.ts +2 -2
- package/dist/src/connectors/composio-triggers.js +8 -15
- package/dist/src/connectors/connected-source-ingestion.js +1 -1
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/gateway/automation-agent-session.js +3 -0
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +8 -25
- package/dist/src/gateway/hono/routes/capabilities.js +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +3 -3
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/projects.js +1 -1
- package/dist/src/gateway/hono/routes/you.js +20 -4
- package/dist/src/gateway/service.js +4 -5
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/notes/index.d.ts +1 -1
- package/dist/src/notes/index.js +2 -2
- package/dist/src/notes/paths.d.ts +0 -3
- package/dist/src/notes/paths.js +1 -10
- package/dist/src/notes/service.d.ts +0 -1
- package/dist/src/notes/service.js +0 -3
- package/dist/src/notes/store.d.ts +0 -2
- package/dist/src/notes/store.js +33 -80
- package/dist/src/share/hosted-session-share.d.ts +1 -4
- package/dist/src/share/hosted-session-share.js +14 -47
- package/dist/src/share/share-auto.d.ts +1 -1
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.d.ts +2 -7
- package/dist/src/share/share-store.js +153 -195
- package/dist/src/share/share-types.d.ts +0 -4
- package/dist/src/share/site-share-store.d.ts +3 -8
- package/dist/src/share/site-share-store.js +94 -153
- package/dist/src/share/site-share-types.d.ts +0 -4
- package/dist/src/storage/sqlite/connection.d.ts +1 -2
- package/dist/src/storage/sqlite/connection.js +50 -47
- package/dist/src/storage/sqlite/durable-queue.d.ts +16 -0
- package/dist/src/storage/sqlite/durable-queue.js +52 -0
- package/dist/src/storage/sqlite/durable-state.d.ts +16 -0
- package/dist/src/storage/sqlite/durable-state.js +43 -0
- package/dist/src/storage/sqlite/migrations/146_understanding_focus_exclusions.sql +9 -0
- package/dist/src/storage/sqlite/migrations/147_durable_application_state.sql +39 -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/storage/sqlite/understanding-focus-exclusions.d.ts +2 -0
- package/dist/src/storage/sqlite/understanding-focus-exclusions.js +24 -0
- package/dist/src/tui/tui-scoped-models.js +9 -6
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/voice/dashscope/streaming-tts-stream.js +49 -0
- package/dist/src/voice/realtime/agentEngine.js +63 -18
- package/dist/src/voice/realtime/conversationTurn.d.ts +20 -0
- package/dist/src/voice/realtime/conversationTurn.js +83 -0
- package/dist/src/voice/realtime/omniEngine.js +72 -18
- package/dist/src/workflows/authoring/workflow-draft-store.d.ts +1 -5
- package/dist/src/workflows/authoring/workflow-draft-store.js +23 -43
- package/dist/src/workflows/index.js +2 -2
- package/dist/src/workflows/store/event-store.d.ts +1 -2
- package/dist/src/workflows/store/event-store.js +19 -64
- package/dist/src/workflows/store/paths.d.ts +0 -2
- package/dist/src/workflows/store/paths.js +1 -7
- package/dist/src/workflows/store/run-store.d.ts +0 -1
- package/dist/src/workflows/store/run-store.js +1 -24
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-0dRjnL2s.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-EpUZsl4h.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-BGQdHrip.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-DJGcm7rH.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-BcIr-_GM.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DNHqaZfX.js +0 -2
- package/dist/gateway/static/root/assets/home-page-CaVvW77l.js +0 -1
- package/dist/gateway/static/root/assets/index-Dbh5SXyV.css +0 -2
- package/dist/gateway/static/root/assets/local-app-workbench-page-D3K1XmOM.js +0 -2
- package/dist/gateway/static/root/assets/messages-BbdwoxVo.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-cache-88f4fzYS.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-CI30cDh3.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-jO_4I5zN.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BrTGFME0.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CH70D5SH.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-hbfUNtNs.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-Vg3_jua6.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DkcpWSss.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BL4DEt6p.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CafhNktn.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-anyomXsu.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-BBk9YdBn.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-RUTv0yvR.js +0 -5
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { AudioPlaybackWindow } from "./audio-playback-window.js";
|
|
4
|
+
import { ConversationTurn } from "./conversationTurn.js";
|
|
4
5
|
import crypto from "node:crypto";
|
|
5
6
|
import WebSocket from "ws";
|
|
6
7
|
//#region src/voice/realtime/omniEngine.ts
|
|
@@ -47,6 +48,23 @@ function createOmniVoiceEngine(options) {
|
|
|
47
48
|
let queuedInputBytes = 0;
|
|
48
49
|
let uploadingBytes = 0;
|
|
49
50
|
let uploadTimer;
|
|
51
|
+
let turnSettled = false;
|
|
52
|
+
const speaking = /* @__PURE__ */ new Set();
|
|
53
|
+
const turn = new ConversationTurn(options.silenceDurationMs, () => {
|
|
54
|
+
if (closed || failed || muted || inputBlocked) return;
|
|
55
|
+
turnSettled = true;
|
|
56
|
+
if (active) publish(active);
|
|
57
|
+
});
|
|
58
|
+
function publish(response) {
|
|
59
|
+
if (response.published || active !== response) return;
|
|
60
|
+
response.published = true;
|
|
61
|
+
options.send("response.created", { responseId: response.id });
|
|
62
|
+
if (response.text) options.send("response.text.delta", {
|
|
63
|
+
responseId: response.id,
|
|
64
|
+
delta: response.text
|
|
65
|
+
});
|
|
66
|
+
response.release();
|
|
67
|
+
}
|
|
50
68
|
const send = (type, fields = {}) => {
|
|
51
69
|
if (closed || socket?.readyState !== WebSocket.OPEN) throw new Error("Omni connection is closed");
|
|
52
70
|
socket.send(JSON.stringify({
|
|
@@ -103,23 +121,29 @@ function createOmniVoiceEngine(options) {
|
|
|
103
121
|
if (!response) return false;
|
|
104
122
|
active = void 0;
|
|
105
123
|
response.abort.abort(reason);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
response.release();
|
|
125
|
+
if (response.published) {
|
|
126
|
+
save({
|
|
127
|
+
itemId: response.id,
|
|
128
|
+
role: "assistant",
|
|
129
|
+
text: response.text,
|
|
130
|
+
interrupted: true
|
|
131
|
+
});
|
|
132
|
+
options.send("response.cancelled", {
|
|
133
|
+
responseId: response.id,
|
|
134
|
+
reason
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if ((reason === "client_cancelled" || reason === "barge_in" && !options.bargeIn) && response.generating && socket?.readyState === WebSocket.OPEN) {
|
|
117
138
|
cancellationPending = true;
|
|
118
139
|
send("response.cancel");
|
|
119
140
|
}
|
|
120
141
|
return true;
|
|
121
142
|
};
|
|
122
143
|
const finish = async (response) => {
|
|
144
|
+
await response.settled;
|
|
145
|
+
if (active !== response || closed) return;
|
|
146
|
+
options.send("response.text.done", { responseId: response.id });
|
|
123
147
|
await response.tail;
|
|
124
148
|
if (active !== response || closed) return;
|
|
125
149
|
await response.playback.drain(response.abort.signal);
|
|
@@ -157,6 +181,7 @@ function createOmniVoiceEngine(options) {
|
|
|
157
181
|
function fail(code, details = {}) {
|
|
158
182
|
if (closed || failed) return;
|
|
159
183
|
failed = true;
|
|
184
|
+
turn.reset();
|
|
160
185
|
log.warn({
|
|
161
186
|
sessionId: options.callId,
|
|
162
187
|
platformRequestId,
|
|
@@ -179,6 +204,10 @@ function createOmniVoiceEngine(options) {
|
|
|
179
204
|
options.onClose("omni_error", true);
|
|
180
205
|
}
|
|
181
206
|
function discardInput() {
|
|
207
|
+
turn.reset();
|
|
208
|
+
speaking.clear();
|
|
209
|
+
turnSettled = false;
|
|
210
|
+
if (active && !active.published) cancel("client_cancelled");
|
|
182
211
|
inputQueue = [];
|
|
183
212
|
queuedInputBytes = 0;
|
|
184
213
|
inputBlocked = true;
|
|
@@ -266,12 +295,18 @@ function createOmniVoiceEngine(options) {
|
|
|
266
295
|
discardedInputs.add(String(event.item_id));
|
|
267
296
|
return;
|
|
268
297
|
}
|
|
298
|
+
if (recorded.has(String(event.item_id)) || pendingInputs.has(String(event.item_id))) return;
|
|
269
299
|
inputBlocked = false;
|
|
270
300
|
pendingInputs.add(String(event.item_id));
|
|
271
|
-
|
|
301
|
+
turnSettled = false;
|
|
302
|
+
speaking.add(String(event.item_id));
|
|
303
|
+
turn.start(String(event.item_id));
|
|
304
|
+
if (options.bargeIn || active && !active.published) cancel("barge_in");
|
|
272
305
|
options.send("input.speech_started", { utteranceId: String(event.item_id) });
|
|
273
306
|
} else if (event.type === "input_audio_buffer.speech_stopped") {
|
|
274
|
-
if (muted || inputBlocked || discardedInputs.has(String(event.item_id))) return;
|
|
307
|
+
if (muted || inputBlocked || discardedInputs.has(String(event.item_id)) || recorded.has(String(event.item_id))) return;
|
|
308
|
+
speaking.delete(String(event.item_id));
|
|
309
|
+
turn.stop(String(event.item_id));
|
|
275
310
|
options.send("input.speech_stopped", { utteranceId: String(event.item_id) });
|
|
276
311
|
} else if (event.type === "conversation.item.input_audio_transcription.completed") {
|
|
277
312
|
if (typeof event.transcript !== "string" || event.transcript.length > 32e3 || typeof event.item_id !== "string") {
|
|
@@ -280,6 +315,8 @@ function createOmniVoiceEngine(options) {
|
|
|
280
315
|
}
|
|
281
316
|
if (muted || inputBlocked || discardedInputs.has(event.item_id) || recorded.has(event.item_id)) return;
|
|
282
317
|
pendingInputs.delete(event.item_id);
|
|
318
|
+
speaking.delete(event.item_id);
|
|
319
|
+
turn.final(event.item_id, event.transcript);
|
|
283
320
|
save({
|
|
284
321
|
itemId: event.item_id,
|
|
285
322
|
role: "user",
|
|
@@ -291,8 +328,16 @@ function createOmniVoiceEngine(options) {
|
|
|
291
328
|
revision: 1,
|
|
292
329
|
text: event.transcript
|
|
293
330
|
});
|
|
331
|
+
} else if (event.type === "conversation.item.input_audio_transcription.failed") {
|
|
332
|
+
if (muted || inputBlocked || discardedInputs.has(String(event.item_id))) return;
|
|
333
|
+
discardInput();
|
|
334
|
+
options.send("session.error", {
|
|
335
|
+
code: "INPUT_DROPPED",
|
|
336
|
+
message: "Could not transcribe this voice turn. Please repeat it.",
|
|
337
|
+
recoverable: true
|
|
338
|
+
});
|
|
294
339
|
} else if (event.type === "response.created") {
|
|
295
|
-
if (muted || inputBlocked) {
|
|
340
|
+
if (muted || inputBlocked || speaking.size > 0) {
|
|
296
341
|
cancellationPending = true;
|
|
297
342
|
send("response.cancel");
|
|
298
343
|
return;
|
|
@@ -301,6 +346,10 @@ function createOmniVoiceEngine(options) {
|
|
|
301
346
|
if (active) cancel("barge_in");
|
|
302
347
|
const id = event.response?.id;
|
|
303
348
|
if (typeof id !== "string" || !id.length || id.length > 160) throw new Error("Invalid response ID");
|
|
349
|
+
let release;
|
|
350
|
+
const settled = new Promise((resolve) => {
|
|
351
|
+
release = resolve;
|
|
352
|
+
});
|
|
304
353
|
active = {
|
|
305
354
|
id,
|
|
306
355
|
text: "",
|
|
@@ -309,16 +358,19 @@ function createOmniVoiceEngine(options) {
|
|
|
309
358
|
queuedBytes: 0,
|
|
310
359
|
abort: new AbortController(),
|
|
311
360
|
playback: new AudioPlaybackWindow(),
|
|
312
|
-
tail: Promise.resolve()
|
|
361
|
+
tail: Promise.resolve(),
|
|
362
|
+
published: false,
|
|
363
|
+
settled,
|
|
364
|
+
release
|
|
313
365
|
};
|
|
314
|
-
|
|
366
|
+
if (turnSettled) publish(active);
|
|
315
367
|
} else if (active && event.response_id === active.id && event.type === "response.audio_transcript.delta") {
|
|
316
368
|
if (typeof event.delta !== "string" || active.text.length + event.delta.length > 32e3) {
|
|
317
369
|
fail("OMNI_TRANSCRIPT_LIMIT");
|
|
318
370
|
return;
|
|
319
371
|
}
|
|
320
372
|
active.text += event.delta;
|
|
321
|
-
options.send("response.text.delta", {
|
|
373
|
+
if (active.published) options.send("response.text.delta", {
|
|
322
374
|
responseId: active.id,
|
|
323
375
|
delta: event.delta
|
|
324
376
|
});
|
|
@@ -339,6 +391,7 @@ function createOmniVoiceEngine(options) {
|
|
|
339
391
|
}
|
|
340
392
|
response.queuedBytes += audio.length;
|
|
341
393
|
response.tail = response.tail.then(async () => {
|
|
394
|
+
await response.settled;
|
|
342
395
|
for (let offset = 0; offset < audio.length; offset += 24e3) {
|
|
343
396
|
if (closed || active !== response) return;
|
|
344
397
|
const chunk = audio.subarray(offset, offset + 24e3);
|
|
@@ -368,7 +421,6 @@ function createOmniVoiceEngine(options) {
|
|
|
368
421
|
else if (event.response.status !== "completed") fail("OMNI_RESPONSE_FAILED");
|
|
369
422
|
else {
|
|
370
423
|
const response = active;
|
|
371
|
-
options.send("response.text.done", { responseId: response.id });
|
|
372
424
|
finish(response).catch(() => {
|
|
373
425
|
if (!response.abort.signal.aborted) stopReply(response, "OMNI_PLAYBACK_FAILED");
|
|
374
426
|
});
|
|
@@ -429,6 +481,8 @@ function createOmniVoiceEngine(options) {
|
|
|
429
481
|
clearTimeout(timer);
|
|
430
482
|
clearTimeout(clearTimer);
|
|
431
483
|
clearTimeout(uploadTimer);
|
|
484
|
+
turn.reset();
|
|
485
|
+
speaking.clear();
|
|
432
486
|
inputQueue = [];
|
|
433
487
|
queuedInputBytes = 0;
|
|
434
488
|
rejectStart?.(/* @__PURE__ */ new Error("Omni connection closed"));
|
|
@@ -17,15 +17,11 @@ export interface SaveWorkflowAuthoringDraftInput {
|
|
|
17
17
|
expectedUpdatedAtMs?: number;
|
|
18
18
|
}
|
|
19
19
|
export declare class WorkflowDraftStore {
|
|
20
|
-
private readonly
|
|
21
|
-
constructor(options?: {
|
|
22
|
-
userDir?: string;
|
|
23
|
-
});
|
|
20
|
+
private readonly state;
|
|
24
21
|
list(workflowName?: string): WorkflowAuthoringDraft[];
|
|
25
22
|
get(id: string): WorkflowAuthoringDraft | null;
|
|
26
23
|
save(input: SaveWorkflowAuthoringDraftInput): WorkflowAuthoringDraft;
|
|
27
24
|
remove(id: string): boolean;
|
|
28
|
-
private readFile;
|
|
29
25
|
}
|
|
30
26
|
export declare class WorkflowDraftConflictError extends Error {
|
|
31
27
|
readonly currentUpdatedAtMs?: number;
|
|
@@ -1,56 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { DurableState } from "../../storage/sqlite/durable-state.js";
|
|
4
2
|
import { randomUUID } from "node:crypto";
|
|
5
3
|
//#region src/workflows/authoring/workflow-draft-store.ts
|
|
6
4
|
var WorkflowDraftStore = class {
|
|
7
|
-
|
|
8
|
-
constructor(options = {}) {
|
|
9
|
-
this.draftsDir = join(options.userDir ?? defaultUserDir(), ".drafts");
|
|
10
|
-
}
|
|
5
|
+
state = new DurableState("workflow-drafts");
|
|
11
6
|
list(workflowName) {
|
|
12
|
-
|
|
13
|
-
return readdirSync(this.draftsDir).filter((file) => file.endsWith(".json")).map((file) => this.readFile(join(this.draftsDir, file))).filter((draft) => Boolean(draft) && (!workflowName || draft.workflowName === workflowName)).sort((left, right) => right.updatedAtMs - left.updatedAtMs);
|
|
7
|
+
return this.state.values().filter((draft) => !workflowName || draft.workflowName === workflowName).sort((a, b) => b.updatedAtMs - a.updatedAtMs);
|
|
14
8
|
}
|
|
15
9
|
get(id) {
|
|
16
10
|
requireDraftId(id);
|
|
17
|
-
return this.
|
|
11
|
+
return this.state.get(id) ?? null;
|
|
18
12
|
}
|
|
19
13
|
save(input) {
|
|
20
14
|
if (!input.graph || input.graph.schemaVersion !== 1 || !Array.isArray(input.graph.nodes) || !Array.isArray(input.graph.edges)) throw new Error("workflow draft graph is invalid");
|
|
21
15
|
const id = input.id ?? randomUUID();
|
|
22
16
|
requireDraftId(id);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
17
|
+
return this.state.update(id, (existing) => {
|
|
18
|
+
if (input.expectedUpdatedAtMs !== void 0 && input.expectedUpdatedAtMs !== existing?.updatedAtMs) throw new WorkflowDraftConflictError(existing?.updatedAtMs);
|
|
19
|
+
const now = Math.max(Date.now(), (existing?.updatedAtMs ?? 0) + 1);
|
|
20
|
+
const draft = {
|
|
21
|
+
id,
|
|
22
|
+
workflowName: input.workflowName.trim(),
|
|
23
|
+
graph: structuredClone(input.graph),
|
|
24
|
+
manifest: structuredClone(input.manifest ?? {}),
|
|
25
|
+
baseRevision: input.baseRevision ?? existing?.baseRevision ?? 0,
|
|
26
|
+
createdAtMs: existing?.createdAtMs ?? now,
|
|
27
|
+
updatedAtMs: now
|
|
28
|
+
};
|
|
29
|
+
if (!draft.workflowName) throw new Error("workflowName is required");
|
|
30
|
+
return {
|
|
31
|
+
value: draft,
|
|
32
|
+
result: draft
|
|
33
|
+
};
|
|
34
|
+
});
|
|
39
35
|
}
|
|
40
36
|
remove(id) {
|
|
41
37
|
requireDraftId(id);
|
|
42
|
-
|
|
43
|
-
if (!existsSync(path)) return false;
|
|
44
|
-
unlinkSync(path);
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
readFile(path) {
|
|
48
|
-
try {
|
|
49
|
-
const value = JSON.parse(readFileSync(path, "utf-8"));
|
|
50
|
-
return value && typeof value.id === "string" && value.graph?.schemaVersion === 1 ? value : null;
|
|
51
|
-
} catch {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
38
|
+
return this.state.delete(id);
|
|
54
39
|
}
|
|
55
40
|
};
|
|
56
41
|
var WorkflowDraftConflictError = class extends Error {
|
|
@@ -63,10 +48,5 @@ var WorkflowDraftConflictError = class extends Error {
|
|
|
63
48
|
function requireDraftId(id) {
|
|
64
49
|
if (!/^[a-zA-Z0-9_-]+$/.test(id)) throw new Error("invalid workflow draft id");
|
|
65
50
|
}
|
|
66
|
-
function writeJsonAtomic(path, value) {
|
|
67
|
-
const temporaryPath = `${path}.${randomUUID()}.tmp`;
|
|
68
|
-
writeFileSync(temporaryPath, `${JSON.stringify(value, null, 2)}\n`, "utf-8");
|
|
69
|
-
renameSync(temporaryPath, path);
|
|
70
|
-
}
|
|
71
51
|
//#endregion
|
|
72
52
|
export { WorkflowDraftConflictError, WorkflowDraftStore };
|
|
@@ -8,7 +8,6 @@ import { projectWorkflowRunView } from "./engine/projector.js";
|
|
|
8
8
|
import { GraphWorkflowRuntime, createGraphWorkflowRuntime, renderWorkflowTemplate } from "./runtime/graph-workflow-runtime.js";
|
|
9
9
|
import { WorkflowEngine } from "./engine/workflow-engine.js";
|
|
10
10
|
import "./engine/index.js";
|
|
11
|
-
import { resolveWorkflowRootDir, resolveWorkflowRunArtifactsDir, resolveWorkflowRunDir, resolveWorkflowRunEventsPath, resolveWorkflowRunViewPath, resolveWorkflowRunsDir } from "./store/paths.js";
|
|
12
11
|
import { WorkflowEventStore, createWorkflowEventStore } from "./store/event-store.js";
|
|
13
12
|
import { WorkflowRunStore, createWorkflowRunStore } from "./store/run-store.js";
|
|
14
13
|
import { WorkflowRunService, buildWorkflowRunDefinitionSnapshot, buildWorkflowRunInputEnvelope, buildWorkflowRunMetadata, extractWorkflowRunSessionKey, resolveWorkflowReplayTargets } from "./service/workflow-run-service.js";
|
|
@@ -16,4 +15,5 @@ import { runViewToSnapshot } from "./service/run-view-to-snapshot.js";
|
|
|
16
15
|
import { buildWorkflowRunSessionKey, readWorkflowRunIdFromSessionCustomData } from "./service/workflow-session-key.js";
|
|
17
16
|
import { WORKFLOW_RUN_LINK_CONTEXT_KIND, WORKFLOW_SESSION_TYPE, WorkflowSessionBridge, formatParentRunLinkText } from "./service/workflow-session-bridge.js";
|
|
18
17
|
import "./registry/index.js";
|
|
19
|
-
|
|
18
|
+
import { resolveWorkflowRootDir, resolveWorkflowRunArtifactsDir, resolveWorkflowRunDir, resolveWorkflowRunsDir } from "./store/paths.js";
|
|
19
|
+
export { CatalogWorkflowDefinitionRegistry, DEFAULT_WORKFLOW_CONCURRENCY, DEFAULT_WORKFLOW_MAX_SUBAGENTS, DEFAULT_WORKFLOW_TIMEOUT_SEC, GraphWorkflowRuntime, WORKFLOW_RUN_LINK_CONTEXT_KIND, WORKFLOW_SESSION_TYPE, WorkflowEngine, WorkflowEventStore, WorkflowRunService, WorkflowRunStore, WorkflowSessionBridge, buildWorkflowDefinition, buildWorkflowRunDefinitionSnapshot, buildWorkflowRunInputEnvelope, buildWorkflowRunMetadata, buildWorkflowRunSessionKey, createGraphWorkflowRuntime, createWorkflowEventStore, createWorkflowRunStore, deriveWorkflowPhases, extractWorkflowRunSessionKey, formatParentRunLinkText, hashWorkflowStableValue, isTerminalWorkflowRunStatus, normalizeWorkflowDefinitionId, projectWorkflowRunView, readWorkflowRunIdFromSessionCustomData, renderWorkflowTemplate, resolveWorkflowReplayTargets, resolveWorkflowRootDir, resolveWorkflowRunArtifactsDir, resolveWorkflowRunDir, resolveWorkflowRunsDir, runViewToSnapshot, toWorkflowDefinitionTitle, validateWorkflowDefinitionInput, validateWorkflowGraph, validateWorkflowJsonSchema };
|
|
@@ -7,9 +7,8 @@ export interface AppendWorkflowEventInput<T extends WorkflowEventPayload = Workf
|
|
|
7
7
|
createdAtMs?: number;
|
|
8
8
|
}
|
|
9
9
|
export declare class WorkflowEventStore {
|
|
10
|
-
private readonly config;
|
|
11
10
|
private readonly agentId;
|
|
12
|
-
constructor(
|
|
11
|
+
constructor(_config: Config, agentId: string);
|
|
13
12
|
append<T extends WorkflowEventPayload>(input: AppendWorkflowEventInput<T>): Promise<WorkflowEventEnvelope<T>>;
|
|
14
13
|
readRunEvents(runId: string): Promise<WorkflowEventEnvelope[]>;
|
|
15
14
|
listRunIds(): Promise<string[]>;
|
|
@@ -1,77 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { resolveWorkflowRunEventsPath, resolveWorkflowRunsDir } from "./paths.js";
|
|
4
|
-
import { dirname } from "node:path";
|
|
1
|
+
import { requireXopcDatabase } from "../../storage/sqlite/connection.js";
|
|
2
|
+
import { runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
|
|
5
3
|
import { randomUUID } from "node:crypto";
|
|
6
|
-
import { appendFile, mkdir, readFile, readdir } from "node:fs/promises";
|
|
7
4
|
//#region src/workflows/store/event-store.ts
|
|
8
|
-
init_logger();
|
|
9
|
-
const log = createLogger("WorkflowEventStore");
|
|
10
5
|
var WorkflowEventStore = class {
|
|
11
|
-
constructor(
|
|
12
|
-
this.config = config;
|
|
6
|
+
constructor(_config, agentId) {
|
|
13
7
|
this.agentId = agentId;
|
|
14
8
|
}
|
|
15
9
|
async append(input) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
10
|
+
requireXopcDatabase();
|
|
11
|
+
return runSqliteWriteTransaction((db) => {
|
|
12
|
+
const row = db.prepare("SELECT COALESCE(MAX(sequence), 0) AS sequence FROM workflow_events WHERE agent_id = ? AND run_id = ?").get(this.agentId, input.runId);
|
|
13
|
+
const event = {
|
|
14
|
+
id: randomUUID(),
|
|
15
|
+
runId: input.runId,
|
|
16
|
+
sequence: row.sequence + 1,
|
|
17
|
+
type: input.type,
|
|
18
|
+
payload: input.payload,
|
|
19
|
+
createdAtMs: input.createdAtMs ?? Date.now()
|
|
20
|
+
};
|
|
21
|
+
db.prepare("INSERT INTO workflow_events(agent_id, run_id, sequence, id, payload) VALUES (?, ?, ?, ?, ?)").run(this.agentId, input.runId, event.sequence, event.id, JSON.stringify(event));
|
|
22
|
+
return event;
|
|
23
|
+
});
|
|
29
24
|
}
|
|
30
25
|
async readRunEvents(runId) {
|
|
31
|
-
|
|
32
|
-
let content;
|
|
33
|
-
try {
|
|
34
|
-
content = await readFile(eventsPath, "utf8");
|
|
35
|
-
} catch (err) {
|
|
36
|
-
if ((err && typeof err === "object" && "code" in err ? String(err.code) : "") === "ENOENT") return [];
|
|
37
|
-
log.warn({
|
|
38
|
-
err,
|
|
39
|
-
runId,
|
|
40
|
-
eventsPath
|
|
41
|
-
}, "Workflow events read failed");
|
|
42
|
-
return [];
|
|
43
|
-
}
|
|
44
|
-
const events = [];
|
|
45
|
-
for (const line of content.split("\n")) {
|
|
46
|
-
if (!line.trim()) continue;
|
|
47
|
-
try {
|
|
48
|
-
const event = JSON.parse(line);
|
|
49
|
-
if (event.runId === runId && Number.isFinite(event.sequence)) events.push(event);
|
|
50
|
-
} catch (err) {
|
|
51
|
-
log.warn({
|
|
52
|
-
err,
|
|
53
|
-
runId,
|
|
54
|
-
linePreview: line.slice(0, 160)
|
|
55
|
-
}, "Workflow event line parse failed");
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
events.sort((left, right) => left.sequence - right.sequence);
|
|
59
|
-
return events;
|
|
26
|
+
return requireXopcDatabase().db.prepare("SELECT payload FROM workflow_events WHERE agent_id = ? AND run_id = ? ORDER BY sequence").all(this.agentId, runId).map((row) => JSON.parse(row.payload));
|
|
60
27
|
}
|
|
61
28
|
async listRunIds() {
|
|
62
|
-
|
|
63
|
-
let entries;
|
|
64
|
-
try {
|
|
65
|
-
entries = await readdir(runsDir);
|
|
66
|
-
} catch (err) {
|
|
67
|
-
if ((err && typeof err === "object" && "code" in err ? String(err.code) : "") === "ENOENT") return [];
|
|
68
|
-
log.warn({
|
|
69
|
-
err,
|
|
70
|
-
runsDir
|
|
71
|
-
}, "Workflow runs directory read failed");
|
|
72
|
-
return [];
|
|
73
|
-
}
|
|
74
|
-
return entries.filter((entry) => !entry.startsWith(".") && !entry.includes("/") && !entry.includes("\\"));
|
|
29
|
+
return requireXopcDatabase().db.prepare("SELECT DISTINCT run_id FROM workflow_events WHERE agent_id = ? ORDER BY run_id").all(this.agentId).map((row) => row.run_id);
|
|
75
30
|
}
|
|
76
31
|
};
|
|
77
32
|
function createWorkflowEventStore(config, agentId) {
|
|
@@ -2,6 +2,4 @@ import type { Config } from '../../config/schema.js';
|
|
|
2
2
|
export declare function resolveWorkflowRootDir(config: Config, agentId: string): string;
|
|
3
3
|
export declare function resolveWorkflowRunsDir(config: Config, agentId: string): string;
|
|
4
4
|
export declare function resolveWorkflowRunDir(config: Config, agentId: string, runId: string): string;
|
|
5
|
-
export declare function resolveWorkflowRunEventsPath(config: Config, agentId: string, runId: string): string;
|
|
6
|
-
export declare function resolveWorkflowRunViewPath(config: Config, agentId: string, runId: string): string;
|
|
7
5
|
export declare function resolveWorkflowRunArtifactsDir(config: Config, agentId: string, runId: string): string;
|
|
@@ -11,14 +11,8 @@ function resolveWorkflowRunsDir(config, agentId) {
|
|
|
11
11
|
function resolveWorkflowRunDir(config, agentId, runId) {
|
|
12
12
|
return join(resolveWorkflowRunsDir(config, agentId), runId);
|
|
13
13
|
}
|
|
14
|
-
function resolveWorkflowRunEventsPath(config, agentId, runId) {
|
|
15
|
-
return join(resolveWorkflowRunDir(config, agentId, runId), "events.jsonl");
|
|
16
|
-
}
|
|
17
|
-
function resolveWorkflowRunViewPath(config, agentId, runId) {
|
|
18
|
-
return join(resolveWorkflowRunDir(config, agentId, runId), "view.json");
|
|
19
|
-
}
|
|
20
14
|
function resolveWorkflowRunArtifactsDir(config, agentId, runId) {
|
|
21
15
|
return join(resolveWorkflowRunDir(config, agentId, runId), "artifacts");
|
|
22
16
|
}
|
|
23
17
|
//#endregion
|
|
24
|
-
export { resolveWorkflowRootDir, resolveWorkflowRunArtifactsDir, resolveWorkflowRunDir,
|
|
18
|
+
export { resolveWorkflowRootDir, resolveWorkflowRunArtifactsDir, resolveWorkflowRunDir, resolveWorkflowRunsDir };
|
|
@@ -2,7 +2,6 @@ import type { Config } from '../../config/schema.js';
|
|
|
2
2
|
import type { WorkflowRunSummary, WorkflowRunView } from '../domain/run.js';
|
|
3
3
|
import { WorkflowEventStore } from './event-store.js';
|
|
4
4
|
export declare class WorkflowRunStore {
|
|
5
|
-
private readonly config;
|
|
6
5
|
private readonly agentId;
|
|
7
6
|
private readonly eventStore;
|
|
8
7
|
private readonly indexStore;
|
|
@@ -1,45 +1,22 @@
|
|
|
1
|
-
import { createLogger } from "../../utils/logger/index.js";
|
|
2
|
-
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { init_write_file_atomic, writeTextAtomic } from "../../infra/write-file-atomic.js";
|
|
4
1
|
import { projectWorkflowRunView } from "../engine/projector.js";
|
|
5
|
-
import { resolveWorkflowRunViewPath } from "./paths.js";
|
|
6
2
|
import { WorkflowEventStore } from "./event-store.js";
|
|
7
3
|
import { WorkflowRunIndexStore } from "./run-index-store.js";
|
|
8
|
-
import { readFile } from "node:fs/promises";
|
|
9
4
|
//#region src/workflows/store/run-store.ts
|
|
10
|
-
init_write_file_atomic();
|
|
11
|
-
init_logger();
|
|
12
|
-
const log = createLogger("WorkflowRunStore");
|
|
13
5
|
var WorkflowRunStore = class {
|
|
14
6
|
eventStore;
|
|
15
7
|
indexStore = new WorkflowRunIndexStore();
|
|
16
8
|
constructor(config, agentId, eventStore) {
|
|
17
|
-
this.config = config;
|
|
18
9
|
this.agentId = agentId;
|
|
19
10
|
this.eventStore = eventStore ?? new WorkflowEventStore(config, agentId);
|
|
20
11
|
}
|
|
21
12
|
async rebuildRunView(runId) {
|
|
22
13
|
const view = projectWorkflowRunView(await this.eventStore.readRunEvents(runId));
|
|
23
14
|
if (!view) return null;
|
|
24
|
-
await writeTextAtomic(resolveWorkflowRunViewPath(this.config, this.agentId, runId), `${JSON.stringify(view, null, 2)}\n`);
|
|
25
15
|
this.indexStore.upsert(this.agentId, view);
|
|
26
16
|
return view;
|
|
27
17
|
}
|
|
28
18
|
async readRunView(runId) {
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
const content = await readFile(viewPath, "utf8");
|
|
32
|
-
const view = JSON.parse(content);
|
|
33
|
-
this.indexStore.upsert(this.agentId, view);
|
|
34
|
-
return view;
|
|
35
|
-
} catch (err) {
|
|
36
|
-
if ((err && typeof err === "object" && "code" in err ? String(err.code) : "") !== "ENOENT") log.debug({
|
|
37
|
-
err,
|
|
38
|
-
runId,
|
|
39
|
-
viewPath
|
|
40
|
-
}, "Workflow run view read failed; rebuilding from events");
|
|
41
|
-
return this.rebuildRunView(runId);
|
|
42
|
-
}
|
|
19
|
+
return this.rebuildRunView(runId);
|
|
43
20
|
}
|
|
44
21
|
async listRunSummaries(limit = 50, options = {}) {
|
|
45
22
|
const safeLimit = Math.min(500, Math.max(1, Math.floor(limit)));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.248",
|
|
4
4
|
"description": "Local-first personal AI assistant with reviewable user understanding, durable tasks, workflows, automations, and local or cloud models.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -164,9 +164,9 @@
|
|
|
164
164
|
"vitest": "4.1.5",
|
|
165
165
|
"vue": "^3.5.35",
|
|
166
166
|
"@xopcai/endpoint-tools-protocol": "0.0.0",
|
|
167
|
+
"@xopcai/gateway-contract": "0.0.0",
|
|
167
168
|
"@xopcai/realtime-protocol": "0.0.0",
|
|
168
|
-
"@xopcai/realtime-client": "0.0.0"
|
|
169
|
-
"@xopcai/gateway-contract": "0.0.0"
|
|
169
|
+
"@xopcai/realtime-client": "0.0.0"
|
|
170
170
|
},
|
|
171
171
|
"scripts": {
|
|
172
172
|
"assets:brand": "node scripts/generate-brand-assets.mjs",
|