@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.
Files changed (199) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/src/update-offset-store.js +17 -54
  3. package/dist/extensions/telegram/xopc.extension.json +1 -1
  4. package/dist/extensions/weixin/src/auth/accounts.js +3 -5
  5. package/dist/extensions/weixin/src/monitor/monitor.js +3 -5
  6. package/dist/extensions/weixin/src/storage/sync-buf.d.ts +3 -6
  7. package/dist/extensions/weixin/src/storage/sync-buf.js +9 -22
  8. package/dist/gateway/static/root/assets/{activity-store-BlxqErph.js → activity-store-etpmyV7S.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CJJzpYYS.js → agent-avatar-dicebear-BmKxSM1k.js} +1 -1
  10. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CUXApfcE.js +1 -0
  11. package/dist/gateway/static/root/assets/{agents-je3sRGmk.js → agents-DNq_GKuc.js} +1 -1
  12. package/dist/gateway/static/root/assets/{api-BbXzyQMj.js → api-B0-hLuZ1.js} +1 -1
  13. package/dist/gateway/static/root/assets/{app-management-settings-panel-Cnn3i00c.js → app-management-settings-panel-qfwAgyhQ.js} +1 -1
  14. package/dist/gateway/static/root/assets/{appearance-settings-BToQaw_v.js → appearance-settings-DqQVUpCC.js} +1 -1
  15. package/dist/gateway/static/root/assets/apps-page-dwIqYmXk.js +1 -0
  16. package/dist/gateway/static/root/assets/{archive-plugin-DD2SweEH.js → archive-plugin-BnMSgZvR.js} +1 -1
  17. package/dist/gateway/static/root/assets/{attachment-load-BFtcib5t.js → attachment-load-CejsQMev.js} +1 -1
  18. package/dist/gateway/static/root/assets/{automations-page-XS8wIl5o.js → automations-page-RC8EyoAf.js} +1 -1
  19. package/dist/gateway/static/root/assets/automations-workspace-SkdcSZ0i.js +6 -0
  20. package/dist/gateway/static/root/assets/{binary-plugins-Xs7pLHxR.js → binary-plugins-DGjppLSG.js} +1 -1
  21. package/dist/gateway/static/root/assets/{block-editor-BPdSzceB.js → block-editor-CWdP4bUc.js} +44 -44
  22. package/dist/gateway/static/root/assets/browser-settings-page-CKCa6TvG.js +8 -0
  23. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BAAc151l.js → browser-workflow-inputs-BQ1Ilw_o.js} +1 -1
  24. package/dist/gateway/static/root/assets/{browser-workflows-page-DUPPvE30.js → browser-workflows-page-CJh4NyxT.js} +2 -2
  25. package/dist/gateway/static/root/assets/{capabilities-settings-panel-cl9kYilL.js → capabilities-settings-panel-DSp--zIZ.js} +5 -5
  26. package/dist/gateway/static/root/assets/channels-settings-CMd2dDrI.js +1 -0
  27. package/dist/gateway/static/root/assets/{channels-status-swr-CCBCtLDg.js → channels-status-swr-Ohhee4vm.js} +1 -1
  28. package/dist/gateway/static/root/assets/{chat-terminal-dock-DKW1M6aJ.js → chat-terminal-dock-BOtoKTK3.js} +2 -2
  29. package/dist/gateway/static/root/assets/connectors-page-udWs5Kdm.js +2 -0
  30. package/dist/gateway/static/root/assets/{cron-expression-Bijb0ZQu.js → cron-expression-DTj1V3Sw.js} +1 -1
  31. package/dist/gateway/static/root/assets/{date-picker-BZuHw-SY.js → date-picker-Yr6OCvGL.js} +1 -1
  32. package/dist/gateway/static/root/assets/{dependency-picker-BsBD2JFY.js → dependency-picker-DpN3XZg9.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-Ceuw3QKb.js → desktop-pet-DbGzggPF.js} +1 -1
  34. package/dist/gateway/static/root/assets/{desktop-pet-settings-DctOXexM.js → desktop-pet-settings-DinCToZh.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-debug-page-BNlMPATK.js → extension-debug-page-DgTtk4KC.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-page-CK4Uvzge.js → extension-page-DtQeiP6f.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-settings-page-CpnXXemw.js → extension-settings-page-DcguCgsH.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-config-api-C_mlpe-r.js → gateway-config-api-Br7lSf6H.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-config-swr-826dipyU.js → gateway-config-swr-DXuXtU1w.js} +1 -1
  40. package/dist/gateway/static/root/assets/{gateway-settings-DSSW17ed.js → gateway-settings-CdPoDMuj.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-startup-retry-DyvcAIMm.js → gateway-startup-retry-CzBzglzQ.js} +1 -1
  42. package/dist/gateway/static/root/assets/{heartbeat-settings-hbmIZTpg.js → heartbeat-settings-DHk1hawP.js} +1 -1
  43. package/dist/gateway/static/root/assets/home-page-YGipe_W6.js +1 -0
  44. package/dist/gateway/static/root/assets/{image-generation-api-D7cyfks6.js → image-generation-api-TIgsn04n.js} +1 -1
  45. package/dist/gateway/static/root/assets/{index-eZjksPvq.js → index-D5TQQpeb.js} +44 -44
  46. package/dist/gateway/static/root/assets/index-DReBaaTX.css +2 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BQrDwwgi.js → keyboard-shortcuts-settings-wsWuoa8p.js} +1 -1
  48. package/dist/gateway/static/root/assets/local-app-workbench-page-CpyvYyrb.js +2 -0
  49. package/dist/gateway/static/root/assets/{local-apps-page-D-YWD6LS.js → local-apps-page-CXrbrGo8.js} +1 -1
  50. package/dist/gateway/static/root/assets/local-context-graph-BjUf7fQ9.js +1 -0
  51. package/dist/gateway/static/root/assets/{locale-store-CBoCuIMx.js → locale-store-BJFLQY8O.js} +1 -1
  52. package/dist/gateway/static/root/assets/{logs-page-DvLc9l59.js → logs-page-CXKy6E_l.js} +2 -2
  53. package/dist/gateway/static/root/assets/{management-settings-DsULLUUv.js → management-settings-BdJZFR7U.js} +1 -1
  54. package/dist/gateway/static/root/assets/{markdown-split-CjqlP6IB.js → markdown-split-NK3ACVG2.js} +1 -1
  55. package/dist/gateway/static/root/assets/{markdown-view-BXsHghJd.js → markdown-view-DTF9v1gg.js} +1 -1
  56. package/dist/gateway/static/root/assets/{media-plugins-DQL029DU.js → media-plugins-F0jcUxyl.js} +1 -1
  57. package/dist/gateway/static/root/assets/messages-CHNYp8EQ.js +3 -0
  58. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-gauprAae.js → mobile-pairing-wizard-3NKCniSp.js} +1 -1
  59. package/dist/gateway/static/root/assets/models-hub-cache-nCfkBN8M.js +1 -0
  60. package/dist/gateway/static/root/assets/{notes-page-AsEfLZt9.js → notes-page-DuqLahi6.js} +1 -1
  61. package/dist/gateway/static/root/assets/notes-workbench-C7j9EdQk.js +5 -0
  62. package/dist/gateway/static/root/assets/{oauth-api-BjSUDIgq.js → oauth-api-8lP_qJpq.js} +1 -1
  63. package/dist/gateway/static/root/assets/{product-open-page-CAJeUXeU.js → product-open-page-CxGGlWA8.js} +1 -1
  64. package/dist/gateway/static/root/assets/project-detail-page-CfebYVX0.js +1 -0
  65. package/dist/gateway/static/root/assets/projects-page-48GvzSVa.js +1 -0
  66. package/dist/gateway/static/root/assets/{registry-api-BhGKnvLP.js → registry-api-CIsNlSBi.js} +1 -1
  67. package/dist/gateway/static/root/assets/remote-access-hub-64xj_s2m.js +1 -0
  68. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DH6EilMV.js → runtime-tools-settings-panel-YkjhiQfA.js} +2 -2
  69. package/dist/gateway/static/root/assets/{schema-form-DYHmEZeZ.js → schema-form-oFGf3G3s.js} +1 -1
  70. package/dist/gateway/static/root/assets/sessions-page-CcwcdRN8.js +1 -0
  71. package/dist/gateway/static/root/assets/settings-advanced-gate-BaN84CyW.js +1 -0
  72. package/dist/gateway/static/root/assets/{settings-page-BHwPd_M3.js → settings-page-C7VWs0IT.js} +1 -1
  73. package/dist/gateway/static/root/assets/setup-status-panel-DVVOCNbr.js +1 -0
  74. package/dist/gateway/static/root/assets/{share-preview-page-BjwrS03F.js → share-preview-page-t5oz18rh.js} +1 -1
  75. package/dist/gateway/static/root/assets/shares-settings-DUYbYLi7.js +1 -0
  76. package/dist/gateway/static/root/assets/skill-reload-api-BGyD0gB9.js +1 -0
  77. package/dist/gateway/static/root/assets/{skills-page-OHyK25op.js → skills-page-CjF8DTsN.js} +1 -1
  78. package/dist/gateway/static/root/assets/{skills-page.utils-DQx9ulmg.js → skills-page.utils-DEDTYs2W.js} +1 -1
  79. package/dist/gateway/static/root/assets/{system-settings-panel-wO7DWv4C.js → system-settings-panel-BSYuRgFI.js} +1 -1
  80. package/dist/gateway/static/root/assets/task-detail-page-YZYSTJH7.js +1 -0
  81. package/dist/gateway/static/root/assets/{theme-store-hybK3oC9.js → theme-store-O597U8q_.js} +1 -1
  82. package/dist/gateway/static/root/assets/{tunnel-api-CVC8BHZu.js → tunnel-api-FKUi9wDL.js} +1 -1
  83. package/dist/gateway/static/root/assets/{use-autosave-DMvRu2XZ.js → use-autosave-B5eUJ6Zq.js} +1 -1
  84. package/dist/gateway/static/root/assets/user-context-page-BCyiduKd.js +2 -0
  85. package/dist/gateway/static/root/assets/{voice-api-key-field-DuBK2NDG.js → voice-api-key-field-CMKSwz4C.js} +1 -1
  86. package/dist/gateway/static/root/assets/{voice-config-api-CBbiF1T3.js → voice-config-api-q7B6fOFB.js} +1 -1
  87. package/dist/gateway/static/root/assets/{work-discovery-overlay-B7VXWpDr.js → work-discovery-overlay-jhT2EzeH.js} +1 -1
  88. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BokVAsWN.js → workflow-run-setup-panel-DZmvLZjb.js} +2 -2
  89. package/dist/gateway/static/root/assets/workflows-page-DQC0TpMa.js +5 -0
  90. package/dist/gateway/static/root/index.html +12 -12
  91. package/dist/package.js +1 -1
  92. package/dist/src/agent/commands/command-registry.d.ts +1 -0
  93. package/dist/src/agent/commands/command-registry.js +12 -22
  94. package/dist/src/agent/ipc/inbox.d.ts +8 -31
  95. package/dist/src/agent/ipc/inbox.js +64 -133
  96. package/dist/src/agent/service/process-direct-one-shot.js +15 -10
  97. package/dist/src/agent/workflow/catalog.d.ts +1 -8
  98. package/dist/src/agent/workflow/catalog.js +44 -102
  99. package/dist/src/agent/workflow/index.d.ts +1 -1
  100. package/dist/src/agent/workflow/index.js +2 -2
  101. package/dist/src/automations/domain/types.d.ts +1 -0
  102. package/dist/src/automations/service/action-executor.js +2 -2
  103. package/dist/src/automations/service/automation-service.js +2 -2
  104. package/dist/src/channels/manager.d.ts +1 -1
  105. package/dist/src/channels/manager.js +2 -2
  106. package/dist/src/channels/outbound/persist-store.d.ts +2 -8
  107. package/dist/src/channels/outbound/persist-store.js +11 -38
  108. package/dist/src/channels/outbound-sender.d.ts +1 -1
  109. package/dist/src/channels/outbound-sender.js +2 -2
  110. package/dist/src/cli/commands/connectors.js +1 -1
  111. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  112. package/dist/src/config/schema.js +2 -2
  113. package/dist/src/connectors/auth-provider-registry.js +1 -1
  114. package/dist/src/connectors/composio-triggers.d.ts +2 -2
  115. package/dist/src/connectors/composio-triggers.js +8 -15
  116. package/dist/src/connectors/connected-source-ingestion.js +1 -1
  117. package/dist/src/connectors/health.js +1 -1
  118. package/dist/src/gateway/automation-agent-session.js +3 -0
  119. package/dist/src/gateway/heartbeat/service.js +1 -1
  120. package/dist/src/gateway/hono/lib/extension-store.js +8 -25
  121. package/dist/src/gateway/hono/routes/capabilities.js +1 -1
  122. package/dist/src/gateway/hono/routes/connectors.js +3 -3
  123. package/dist/src/gateway/hono/routes/mcp.js +1 -1
  124. package/dist/src/gateway/hono/routes/projects.js +1 -1
  125. package/dist/src/gateway/hono/routes/you.js +20 -4
  126. package/dist/src/gateway/service.js +4 -5
  127. package/dist/src/heartbeat/index.js +1 -1
  128. package/dist/src/notes/index.d.ts +1 -1
  129. package/dist/src/notes/index.js +2 -2
  130. package/dist/src/notes/paths.d.ts +0 -3
  131. package/dist/src/notes/paths.js +1 -10
  132. package/dist/src/notes/service.d.ts +0 -1
  133. package/dist/src/notes/service.js +0 -3
  134. package/dist/src/notes/store.d.ts +0 -2
  135. package/dist/src/notes/store.js +33 -80
  136. package/dist/src/share/hosted-session-share.d.ts +1 -4
  137. package/dist/src/share/hosted-session-share.js +14 -47
  138. package/dist/src/share/share-auto.d.ts +1 -1
  139. package/dist/src/share/share-auto.js +2 -2
  140. package/dist/src/share/share-store.d.ts +2 -7
  141. package/dist/src/share/share-store.js +153 -195
  142. package/dist/src/share/share-types.d.ts +0 -4
  143. package/dist/src/share/site-share-store.d.ts +3 -8
  144. package/dist/src/share/site-share-store.js +94 -153
  145. package/dist/src/share/site-share-types.d.ts +0 -4
  146. package/dist/src/storage/sqlite/connection.d.ts +1 -2
  147. package/dist/src/storage/sqlite/connection.js +50 -47
  148. package/dist/src/storage/sqlite/durable-queue.d.ts +16 -0
  149. package/dist/src/storage/sqlite/durable-queue.js +52 -0
  150. package/dist/src/storage/sqlite/durable-state.d.ts +16 -0
  151. package/dist/src/storage/sqlite/durable-state.js +43 -0
  152. package/dist/src/storage/sqlite/migrations/146_understanding_focus_exclusions.sql +9 -0
  153. package/dist/src/storage/sqlite/migrations/147_durable_application_state.sql +39 -0
  154. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  155. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  156. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  157. package/dist/src/storage/sqlite/schema.js +1 -1
  158. package/dist/src/storage/sqlite/understanding-focus-exclusions.d.ts +2 -0
  159. package/dist/src/storage/sqlite/understanding-focus-exclusions.js +24 -0
  160. package/dist/src/tui/tui-scoped-models.js +9 -6
  161. package/dist/src/tui/tui-startup-resources.js +1 -1
  162. package/dist/src/voice/dashscope/streaming-tts-stream.js +49 -0
  163. package/dist/src/voice/realtime/agentEngine.js +63 -18
  164. package/dist/src/voice/realtime/conversationTurn.d.ts +20 -0
  165. package/dist/src/voice/realtime/conversationTurn.js +83 -0
  166. package/dist/src/voice/realtime/omniEngine.js +72 -18
  167. package/dist/src/workflows/authoring/workflow-draft-store.d.ts +1 -5
  168. package/dist/src/workflows/authoring/workflow-draft-store.js +23 -43
  169. package/dist/src/workflows/index.js +2 -2
  170. package/dist/src/workflows/store/event-store.d.ts +1 -2
  171. package/dist/src/workflows/store/event-store.js +19 -64
  172. package/dist/src/workflows/store/paths.d.ts +0 -2
  173. package/dist/src/workflows/store/paths.js +1 -7
  174. package/dist/src/workflows/store/run-store.d.ts +0 -1
  175. package/dist/src/workflows/store/run-store.js +1 -24
  176. package/package.json +3 -3
  177. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-0dRjnL2s.js +0 -1
  178. package/dist/gateway/static/root/assets/apps-page-EpUZsl4h.js +0 -1
  179. package/dist/gateway/static/root/assets/automations-workspace-BGQdHrip.js +0 -6
  180. package/dist/gateway/static/root/assets/browser-settings-page-DJGcm7rH.js +0 -8
  181. package/dist/gateway/static/root/assets/channels-settings-BcIr-_GM.js +0 -1
  182. package/dist/gateway/static/root/assets/connectors-page-DNHqaZfX.js +0 -2
  183. package/dist/gateway/static/root/assets/home-page-CaVvW77l.js +0 -1
  184. package/dist/gateway/static/root/assets/index-Dbh5SXyV.css +0 -2
  185. package/dist/gateway/static/root/assets/local-app-workbench-page-D3K1XmOM.js +0 -2
  186. package/dist/gateway/static/root/assets/messages-BbdwoxVo.js +0 -3
  187. package/dist/gateway/static/root/assets/models-hub-cache-88f4fzYS.js +0 -1
  188. package/dist/gateway/static/root/assets/notes-workbench-CI30cDh3.js +0 -4
  189. package/dist/gateway/static/root/assets/project-detail-page-jO_4I5zN.js +0 -1
  190. package/dist/gateway/static/root/assets/projects-page-BrTGFME0.js +0 -1
  191. package/dist/gateway/static/root/assets/remote-access-hub-CH70D5SH.js +0 -1
  192. package/dist/gateway/static/root/assets/sessions-page-hbfUNtNs.js +0 -1
  193. package/dist/gateway/static/root/assets/settings-advanced-gate-Vg3_jua6.js +0 -1
  194. package/dist/gateway/static/root/assets/setup-status-panel-DkcpWSss.js +0 -1
  195. package/dist/gateway/static/root/assets/shares-settings-BL4DEt6p.js +0 -1
  196. package/dist/gateway/static/root/assets/skill-reload-api-CafhNktn.js +0 -1
  197. package/dist/gateway/static/root/assets/task-detail-page-anyomXsu.js +0 -1
  198. package/dist/gateway/static/root/assets/user-context-page-BBk9YdBn.js +0 -1
  199. 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
- save({
107
- itemId: response.id,
108
- role: "assistant",
109
- text: response.text,
110
- interrupted: true
111
- });
112
- options.send("response.cancelled", {
113
- responseId: response.id,
114
- reason
115
- });
116
- if (reason === "client_cancelled" && response.generating && socket?.readyState === WebSocket.OPEN) {
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
- if (options.bargeIn) cancel("barge_in");
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
- options.send("response.created", { responseId: id });
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 draftsDir;
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 { defaultUserDir } from "../../agent/workflow/catalog.js";
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
- draftsDir;
8
- constructor(options = {}) {
9
- this.draftsDir = join(options.userDir ?? defaultUserDir(), ".drafts");
10
- }
5
+ state = new DurableState("workflow-drafts");
11
6
  list(workflowName) {
12
- if (!existsSync(this.draftsDir)) return [];
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.readFile(join(this.draftsDir, `${id}.json`));
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
- const existing = this.get(id);
24
- if (input.expectedUpdatedAtMs !== void 0 && input.expectedUpdatedAtMs !== existing?.updatedAtMs) throw new WorkflowDraftConflictError(existing?.updatedAtMs);
25
- const now = Math.max(Date.now(), (existing?.updatedAtMs ?? 0) + 1);
26
- const draft = {
27
- id,
28
- workflowName: input.workflowName.trim(),
29
- graph: structuredClone(input.graph),
30
- manifest: structuredClone(input.manifest ?? {}),
31
- baseRevision: input.baseRevision ?? existing?.baseRevision ?? 0,
32
- createdAtMs: existing?.createdAtMs ?? now,
33
- updatedAtMs: now
34
- };
35
- if (!draft.workflowName) throw new Error("workflowName is required");
36
- mkdirSync(this.draftsDir, { recursive: true });
37
- writeJsonAtomic(join(this.draftsDir, `${id}.json`), draft);
38
- return draft;
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
- const path = join(this.draftsDir, `${id}.json`);
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
- 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, resolveWorkflowRunEventsPath, resolveWorkflowRunViewPath, resolveWorkflowRunsDir, runViewToSnapshot, toWorkflowDefinitionTitle, validateWorkflowDefinitionInput, validateWorkflowGraph, validateWorkflowJsonSchema };
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(config: Config, agentId: string);
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 { createLogger } from "../../utils/logger/index.js";
2
- import { init_logger } from "../../utils/logger.js";
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(config, agentId) {
12
- this.config = config;
6
+ constructor(_config, agentId) {
13
7
  this.agentId = agentId;
14
8
  }
15
9
  async append(input) {
16
- const eventsPath = resolveWorkflowRunEventsPath(this.config, this.agentId, input.runId);
17
- await mkdir(dirname(eventsPath), { recursive: true });
18
- const previousEvents = await this.readRunEvents(input.runId);
19
- const event = {
20
- id: randomUUID(),
21
- runId: input.runId,
22
- sequence: previousEvents.length + 1,
23
- type: input.type,
24
- payload: input.payload,
25
- createdAtMs: input.createdAtMs ?? Date.now()
26
- };
27
- await appendFile(eventsPath, `${JSON.stringify(event)}\n`, "utf8");
28
- return event;
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
- const eventsPath = resolveWorkflowRunEventsPath(this.config, this.agentId, runId);
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
- const runsDir = resolveWorkflowRunsDir(this.config, this.agentId);
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, resolveWorkflowRunEventsPath, resolveWorkflowRunViewPath, resolveWorkflowRunsDir };
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
- const viewPath = resolveWorkflowRunViewPath(this.config, this.agentId, runId);
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.246",
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",