@xopcai/xopc 0.0.368 → 0.0.369
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/_locales/en/messages.json +30 -1
- package/dist/browser-ext/_locales/zh_CN/messages.json +30 -1
- package/dist/browser-ext/dist/assets/{auth-beGtbLPS.js → page-context-BeworyNB.js} +1331 -1355
- package/dist/browser-ext/dist/assets/{sidepanel-BT0ojEzG.css → sidepanel-Ccl0eSa1.css} +43 -0
- package/dist/browser-ext/dist/background.js +680 -182
- package/dist/browser-ext/dist/sidepanel.html +2 -2
- package/dist/browser-ext/dist/sidepanel.js +372 -193
- package/dist/browser-ext/manifest.json +2 -8
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-D9ZMh5ZR.js → activity-store-BQ3PMp2q.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Bj3rvcTm.js → agent-avatar-dicebear-Stj17S9u.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CCRfvuov.js +1 -0
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-BjdgKCnk.js → agent-plugin-dialog-CRlzd8El.js} +1 -1
- package/dist/gateway/static/root/assets/agents-_ug2LCQb.js +66 -0
- package/dist/gateway/static/root/assets/{agents-admin-api-B5QDepbW.js → agents-admin-api-HBZvVyzF.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-2rTEtB_X.js → app-management-settings-panel-pJFe6M6c.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BPVBS80k.js → appearance-settings-BrxSpBWa.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-1FuKlZYP.js → apps-page-DegSl5Lh.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-BbT1O7oK.js → archive-plugin-BO3I9zRP.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DjwP_h8h.js → automations-page-BZQ_VHjp.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BQywN6nG.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-gS7Wg68v.js → binary-plugins-gFD7vH9R.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-DbwMaivP.js → block-editor-3XjFv3kK.js} +3 -3
- package/dist/gateway/static/root/assets/browser-automation-inputs-DxRoKFun.js +1 -0
- package/dist/gateway/static/root/assets/browser-automations-page-yiEuG1v7.js +3 -0
- package/dist/gateway/static/root/assets/browser-settings-page-ch2_bQF0.js +3 -0
- package/dist/gateway/static/root/assets/{capabilities-Dd1PZRQw.js → capabilities-B48r0DDa.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-Lswa0hv8.js → capabilities-DO-vfNKI.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-page-djBsC_tG.js → capabilities-page-BEnFt_dj.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-DTHR1DrJ.js → capabilities-settings-panel-NckMsJ5N.js} +4 -4
- package/dist/gateway/static/root/assets/{capability-header-actions-494dnJsj.js → capability-header-actions-CY8KCO9j.js} +1 -1
- package/dist/gateway/static/root/assets/channels-CHOS2CGa.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-Bl7-Zk-x.js → chat-terminal-dock-Bwknnb4c.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-ByExKr_6.js → computer-settings-page-B2xeFCSt.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-BK_5aFxO.js → connector-service-page-C83DnAqK.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-D6wTmWA6.js +2 -0
- package/dist/gateway/static/root/assets/{date-picker-BXJv6472.js → date-picker-Bq9GR-DU.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-CWbbhKZa.js → dependency-picker-BTERkA9X.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DWNEC3mk.js → desktop-pet-BwsbQw8V.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BYwlxGiN.js → desktop-pet-settings-sL9i44pP.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-DI2bqaKO.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-D26tSY8Z.js → directory-picker-path-field-BFlDmsS5.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-xYIGNegB.js → extension-debug-page-7Z1Tp7-w.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BoQ1-3AW.js → extension-page-uGqvb8QX.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-provider-Cw_JU6RR.js → extension-provider-xlSyz4Z6.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BH5TFGPe.js → extension-settings-page-CKHgrjOs.js} +1 -1
- package/dist/gateway/static/root/assets/{fallback-models-04Wqmw14.js → fallback-models-BwQg0G1D.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-CNf0ZeRw.js → gateway-config-swr-7RKqgU_U.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-realtime-C4KtwMY3.js → gateway-realtime-DDWymi-o.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-BheKaO6d.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-settings-BqvCJVUC.js → gateway-settings-BAQnSEMJ.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-DIxHacUw.js → gateway-startup-retry-jiV5sbEX.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-BZDjvwet.js +2 -0
- package/dist/gateway/static/root/assets/{image-generation-api-CS0q0Kto.js → image-generation-api-DO4mXb6I.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-n_rSLo6b.js → imports-page-re1_Nh64.js} +1 -1
- package/dist/gateway/static/root/assets/index-BB1z8QxA.js +106 -0
- package/dist/gateway/static/root/assets/index-D9R6tU7r.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-tVkrHbYF.js → keyboard-shortcuts-settings-B_xja9LN.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-L8tYuas0.js → local-app-workbench-page-CErdCrPX.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-SSJ9B1bH.js → local-apps-page-BPL2RXdK.js} +1 -1
- package/dist/gateway/static/root/assets/{local-session-drafts-B_McurIj.js → local-session-drafts-DRPsDCj1.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-D6_rF-qT.js → locale-store-COVscAqC.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-BWD63eg1.js → logs-page-DL-BM0xq.js} +2 -2
- package/dist/gateway/static/root/assets/management-settings-BOVRHhXk.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-_xwUuKce.js → markdown-view-B_qnAcW2.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C631CDu4.js → media-plugins-C0Pc-wSY.js} +1 -1
- package/dist/gateway/static/root/assets/messages-Bb2GK-Nj.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-cache-DyPPksMP.js +1 -0
- package/dist/gateway/static/root/assets/note-detail-panel-DJJK2yL4.js +5 -0
- package/dist/gateway/static/root/assets/{notes-api-vIZWQ9Yt.js → notes-api-sBgBcyLW.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-oCxO7ZTv.js +8 -0
- package/dist/gateway/static/root/assets/{page-context-capture-button-BlPDM7GM.js → page-context-capture-button-tf77xIz3.js} +1 -1
- package/dist/gateway/static/root/assets/personal-page-DOk9gUK5.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-BJjWvoER.js → product-open-page-Dc3Y-Y7J.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-content-CEd4E7Gf.js → product-preview-content-MG_hmVA3.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-DM4_VLNX.js → project-detail-page-3uAzbW4T.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-lszV8HuS.js → projects-page-MllfNLGA.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-uJnjqTcn.js → registry-api-Bh9UBb-f.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-O6j9CWX0.js → remote-access-hub-Bs-C70el.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CjnNQYW8.js → runtime-tools-settings-panel-DpJ5jNzR.js} +1 -1
- package/dist/gateway/static/root/assets/{scenes-page-B3T3dDOR.js → scenes-page-Dpxamkw6.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-DT3c4Vd_.js → schema-form-DUeyQ1zh.js} +1 -1
- package/dist/gateway/static/root/assets/{send-session-input-CICkGwn-.js → send-session-input-Dgn4BRk_.js} +1 -1
- package/dist/gateway/static/root/assets/{session-api-BcQodoAu.js → session-api-yjpEz4pP.js} +1 -1
- package/dist/gateway/static/root/assets/{session-manager-B0tOE4qz.js → session-manager-LInoZ_Yi.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-BCVlNHtq.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-Bz-ue9fZ.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-D-PZjcss.js → settings-page-DouHuBXt.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-Ce3gTbT3.js → setup-status-panel-B5BoZ-1y.js} +1 -1
- package/dist/gateway/static/root/assets/{share-link-dialog-CWS8EkJS.js → share-link-dialog-DJTabLAM.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-23NJAKiq.js → share-preview-page-jw7h4t_B.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-api-iKhHbvBD.js → shares-api-c0dfWz6h.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-BlnlzGjH.js +1 -0
- package/dist/gateway/static/root/assets/{skill-api-C-MWdQwl.js → skill-api-CfyX_0zN.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-iy02aB13.js → skill-reload-api-Ge5XymHa.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page-DjdTeYzm.js +2 -0
- package/dist/gateway/static/root/assets/system-settings-panel-DWf256TE.js +1 -0
- package/dist/gateway/static/root/assets/{task-detail-page-B2SIEyhZ.js → task-detail-page-DE6N1ZQe.js} +2 -2
- package/dist/gateway/static/root/assets/{task-expandable-content-D2LRR4BC.js → task-expandable-content-hYcgCEE3.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-BJfhz-Zq.js → theme-store-BOfCKgl6.js} +1 -1
- package/dist/gateway/static/root/assets/{tracing-settings-page-aHD56iaS.js → tracing-settings-page-DDWFXcST.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-BCf8CfTC.js → tunnel-api-BBm9esrY.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-B4XUkuJd.js → usage-page-C93x89uW.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-BnnTw9RE.js → use-autosave-CSckcjFx.js} +1 -1
- package/dist/gateway/static/root/assets/{use-composer-attachments-Itczg0y1.js → use-composer-attachments-C7Gaaai1.js} +1 -1
- package/dist/gateway/static/root/assets/{use-file-preview-expanded-DJ5vyrvM.js → use-file-preview-expanded-Db2VYg1b.js} +2 -2
- package/dist/gateway/static/root/assets/user-model-page-B74LkVbp.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-BphJku8x.js → voice-api-key-field-GEw5x2fU.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-B4u4coFj.js → voice-config-api-3yyVwXln.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-jgOEP1xw.js → work-discovery-overlay-Bs2MKiTv.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-N69crzRu.js → workflow-run-setup-panel-BR_U_snV.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-Crk4SxtC.js +6 -0
- package/dist/gateway/static/root/assets/{workspace-api-Lzv6GDO8.js → workspace-api-Si2o3inw.js} +2 -2
- package/dist/gateway/static/root/index.html +27 -27
- package/dist/package.js +1 -1
- package/dist/packages/browser-control-contract/src/automation.js +213 -0
- package/dist/packages/browser-control-contract/src/index.js +43 -12
- package/dist/packages/gateway-contract/src/gateway-scopes.js +3 -1
- package/dist/packages/gateway-contract/src/notifications.js +1 -0
- package/dist/packages/realtime-protocol/src/voice.js +9 -3
- package/dist/src/agent/coding/repository-instructions.js +8 -1
- package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
- package/dist/src/agent/tool-manuals/browser.js +3 -3
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
- package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -13
- package/dist/src/agent/tools/browser/tool/schemas.js +0 -4
- package/dist/src/agent/tools/browser-automation-tool.d.ts +74 -1
- package/dist/src/agent/tools/browser-automation-tool.js +52 -6
- package/dist/src/automations/capabilities/write.d.ts +2 -0
- package/dist/src/automations/domain/types.d.ts +11 -0
- package/dist/src/automations/domain/validation.d.ts +4 -0
- package/dist/src/automations/domain/validation.js +1 -0
- package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -0
- package/dist/src/automations/service/action-executor.js +11 -3
- package/dist/src/automations/service/automation-service.d.ts +1 -0
- package/dist/src/automations/service/automation-service.js +13 -1
- package/dist/src/bootstrap/application-state.js +1 -1
- package/dist/src/browser/automations/repository.d.ts +4 -0
- package/dist/src/browser/automations/repository.js +27 -6
- package/dist/src/browser/automations/runner.js +101 -9
- package/dist/src/browser/automations/runtime-service.js +4 -3
- package/dist/src/browser/automations/schema.d.ts +84 -1
- package/dist/src/browser/automations/schema.js +68 -2
- package/dist/src/browser/automations/service.d.ts +78 -1
- package/dist/src/browser/automations/service.js +36 -4
- package/dist/src/browser/automations/types.d.ts +19 -4
- package/dist/src/browser/drivers/extension-driver.d.ts +5 -5
- package/dist/src/browser/drivers/extension-driver.js +10 -10
- package/dist/src/browser/drivers/playwright-driver.js +46 -0
- package/dist/src/browser/index.d.ts +1 -2
- package/dist/src/browser/index.js +2 -3
- package/dist/src/browser/policy/browser-policy.d.ts +0 -1
- package/dist/src/browser/policy/browser-policy.js +1 -4
- package/dist/src/browser/providers/index.d.ts +1 -1
- package/dist/src/browser/providers/index.js +2 -2
- package/dist/src/browser/providers/realtime-extension.d.ts +1 -1
- package/dist/src/browser/providers/realtime-extension.js +5 -1
- package/dist/src/browser/recordings/service.d.ts +22 -0
- package/dist/src/browser/recordings/service.js +160 -0
- package/dist/src/browser/runtime/browser-runtime.d.ts +1 -1
- package/dist/src/browser/runtime/browser-runtime.js +19 -56
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/computer/runtime.js +2 -2
- package/dist/src/config/schema.d.ts +12 -12
- package/dist/src/config/schema.js +12 -12
- package/dist/src/endpoint-tools/policy.js +4 -3
- package/dist/src/gateway/hono/routes/browser-automations.js +23 -7
- package/dist/src/gateway/hono/routes/browser-recordings.d.ts +3 -0
- package/dist/src/gateway/hono/routes/browser-recordings.js +78 -0
- package/dist/src/gateway/hono/routes/browser.js +1 -34
- package/dist/src/gateway/hono/routes/device-push.js +1 -0
- package/dist/src/gateway/hono/routes/home.js +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/personal-agent.js +35 -0
- package/dist/src/gateway/hono/routes/voice.js +5 -2
- package/dist/src/gateway/security/gateway-scopes.js +3 -1
- package/dist/src/gateway/service/agent-runner.js +1 -0
- package/dist/src/home-intelligence/generator.d.ts +2 -0
- package/dist/src/home-intelligence/generator.js +53 -4
- package/dist/src/home-intelligence/host.d.ts +2 -1
- package/dist/src/home-intelligence/host.js +23 -3
- package/dist/src/migrations/cloud-public-models.js +1 -0
- package/dist/src/notifications/clarification.d.ts +5 -0
- package/dist/src/notifications/clarification.js +66 -0
- package/dist/src/notifications/device-store.js +1 -0
- package/dist/src/notifications/harmony-push.d.ts +1 -0
- package/dist/src/notifications/harmony-push.js +3 -1
- package/dist/src/notifications/planner.d.ts +1 -0
- package/dist/src/notifications/service.d.ts +2 -2
- package/dist/src/notifications/service.js +20 -4
- package/dist/src/notifications/store.d.ts +2 -0
- package/dist/src/notifications/store.js +7 -1
- package/dist/src/notifications/types.d.ts +1 -0
- package/dist/src/notifications/types.js +1 -0
- package/dist/src/storage/sqlite/clarification-wait-repository.js +1 -0
- package/dist/src/storage/sqlite/migrations/238_browser_record_replay.sql +45 -0
- package/dist/src/storage/sqlite/migrations/239_clarification_notifications.sql +26 -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/schema.js +1 -1
- package/dist/src/tasks/home-query-service.d.ts +1 -1
- package/dist/src/tasks/home-query-service.js +6 -2
- package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +2 -1
- package/dist/src/voice/dashscope/streaming-tts-stream.js +135 -79
- package/dist/src/voice/realtime/agentEngine.js +78 -1
- package/dist/src/voice/realtime/speakable-segmenter.d.ts +2 -0
- package/dist/src/voice/realtime/speakable-segmenter.js +30 -0
- package/dist/src/voice/tts/providers/alibaba-speech.js +17 -1
- package/dist/src/voice/tts/speak-core.d.ts +3 -0
- package/dist/src/voice/tts/speak-core.js +21 -1
- package/dist/src/voice/tts/speech-provider-types.d.ts +8 -0
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-D0tD3kCe.js +0 -1
- package/dist/gateway/static/root/assets/agents-CWXKzX5L.js +0 -66
- package/dist/gateway/static/root/assets/automations-workspace-C9ZT6TAU.js +0 -6
- package/dist/gateway/static/root/assets/browser-automation-inputs-CXG_JveC.js +0 -1
- package/dist/gateway/static/root/assets/browser-automations-page-CJc7OKR3.js +0 -3
- package/dist/gateway/static/root/assets/browser-settings-page-BjaTEUR8.js +0 -3
- package/dist/gateway/static/root/assets/channels-BaYRJtz3.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DyqRwSH2.js +0 -2
- package/dist/gateway/static/root/assets/device-pairing-wizard-BAc4F35b.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-ChZUzVbe.js +0 -1
- package/dist/gateway/static/root/assets/home-page-DhPPLbdD.js +0 -2
- package/dist/gateway/static/root/assets/index-CK4O2xMa.css +0 -1
- package/dist/gateway/static/root/assets/index-DpLD-7Hc.js +0 -106
- package/dist/gateway/static/root/assets/management-settings-aKSibklM.js +0 -1
- package/dist/gateway/static/root/assets/messages-Bnx3GMDB.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-cache-Di83uIPw.js +0 -1
- package/dist/gateway/static/root/assets/note-detail-panel-B_fve3_2.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-DnChyp8S.js +0 -8
- package/dist/gateway/static/root/assets/personal-page-BM2qAgg_.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BIixHXlQ.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-49SUEWPh.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CNEZjF66.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-BndNdYsJ.js +0 -2
- package/dist/gateway/static/root/assets/system-settings-panel-EpZeMlvp.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-Bz5lkFG9.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-CPCgOfHh.js +0 -6
- package/dist/src/browser/policy/approval-store.d.ts +0 -17
- package/dist/src/browser/policy/approval-store.js +0 -62
- package/dist/src/browser/providers/extension-ws-acquire.d.ts +0 -19
- package/dist/src/browser/providers/extension-ws-acquire.js +0 -78
- package/dist/src/browser/providers/extension.d.ts +0 -61
- package/dist/src/browser/providers/extension.js +0 -378
|
@@ -109,6 +109,8 @@ export declare const HomeModelResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
109
109
|
}, z.core.$strict>], "state">;
|
|
110
110
|
export type HomeModelCandidate = z.infer<typeof HomeModelCandidateSchema>;
|
|
111
111
|
export type HomeModelResult = z.infer<typeof HomeModelResultSchema>;
|
|
112
|
+
/** Check prose rather than identifiers so English evidence cannot override Chinese output. */
|
|
113
|
+
export declare function isHomeProseLocalized(values: readonly string[], locale: HomeContextSnapshot['locale']): boolean;
|
|
112
114
|
export interface HomeModelGeneration {
|
|
113
115
|
result: HomeModelResult;
|
|
114
116
|
modelRef: string;
|
|
@@ -102,7 +102,8 @@ function buildSystemPrompt(locale) {
|
|
|
102
102
|
"Prefer outcomes over feature promotion. Mention a connector or skill only when it materially enables the outcome.",
|
|
103
103
|
"When useful work remains possible without a missing capability, provide degradedActionPrompt using only supplied evidence.",
|
|
104
104
|
"External writes always require user confirmation.",
|
|
105
|
-
`Write
|
|
105
|
+
`Write all user-visible prose values (title, outcome, rationale, proposedSteps, verification, actionPrompt, degradedActionPrompt, question, and option labels) in ${locale === "zh" ? "Simplified Chinese" : "English"}. Machine values listed above must remain in English. Translate English source material into the requested language; keep technical identifiers and proper names intact.`,
|
|
106
|
+
"Use plain text in prose values. Do not HTML-encode characters or include HTML markup."
|
|
106
107
|
].join("\n");
|
|
107
108
|
}
|
|
108
109
|
function extractHomeResponseText(response) {
|
|
@@ -126,6 +127,54 @@ function parseJson(raw) {
|
|
|
126
127
|
}
|
|
127
128
|
throw new Error("Home intelligence model did not return valid JSON");
|
|
128
129
|
}
|
|
130
|
+
function decodeProse(value) {
|
|
131
|
+
const named = {
|
|
132
|
+
amp: "&",
|
|
133
|
+
lt: "<",
|
|
134
|
+
gt: ">",
|
|
135
|
+
quot: "\"",
|
|
136
|
+
apos: "'",
|
|
137
|
+
nbsp: " "
|
|
138
|
+
};
|
|
139
|
+
return value.replace(/&(#x[0-9a-f]+|#\d+|amp|lt|gt|quot|apos|nbsp);/gi, (entity, code) => {
|
|
140
|
+
if (!code.startsWith("#")) return named[code.toLowerCase()] ?? entity;
|
|
141
|
+
const point = code.toLowerCase().startsWith("#x") ? parseInt(code.slice(2), 16) : Number(code.slice(1));
|
|
142
|
+
return point > 0 && point <= 1114111 && !(point >= 55296 && point <= 57343) ? String.fromCodePoint(point) : entity;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/** Check prose rather than identifiers so English evidence cannot override Chinese output. */
|
|
146
|
+
function isHomeProseLocalized(values, locale) {
|
|
147
|
+
return locale !== "zh" || values.every((value) => !/[a-z]/i.test(value) || /\p{Script=Han}/u.test(value));
|
|
148
|
+
}
|
|
149
|
+
function parseLocalizedResult(raw, locale) {
|
|
150
|
+
const result = HomeModelResultSchema.parse(parseJson(raw));
|
|
151
|
+
const prose = [];
|
|
152
|
+
if (result.state === "ready") for (const candidate of result.candidates) {
|
|
153
|
+
candidate.title = decodeProse(candidate.title);
|
|
154
|
+
candidate.outcome = decodeProse(candidate.outcome);
|
|
155
|
+
candidate.rationale = decodeProse(candidate.rationale);
|
|
156
|
+
candidate.proposedSteps = candidate.proposedSteps.map(decodeProse);
|
|
157
|
+
candidate.verification = candidate.verification.map(decodeProse);
|
|
158
|
+
candidate.actionPrompt = decodeProse(candidate.actionPrompt);
|
|
159
|
+
if (candidate.degradedActionPrompt) candidate.degradedActionPrompt = decodeProse(candidate.degradedActionPrompt);
|
|
160
|
+
prose.push(candidate.title, candidate.outcome, candidate.rationale, candidate.actionPrompt);
|
|
161
|
+
prose.push(...[
|
|
162
|
+
...candidate.proposedSteps,
|
|
163
|
+
...candidate.verification,
|
|
164
|
+
candidate.degradedActionPrompt ?? ""
|
|
165
|
+
].filter((value) => (value.match(/[a-z]+/gi)?.length ?? 0) >= 3));
|
|
166
|
+
}
|
|
167
|
+
else if (result.state === "clarification") {
|
|
168
|
+
result.question = decodeProse(result.question);
|
|
169
|
+
result.options = result.options.map((option) => ({
|
|
170
|
+
...option,
|
|
171
|
+
label: decodeProse(option.label)
|
|
172
|
+
}));
|
|
173
|
+
prose.push(result.question, ...result.options.map((option) => option.label).filter((value) => (value.match(/[a-z]+/gi)?.length ?? 0) >= 3));
|
|
174
|
+
}
|
|
175
|
+
if (!isHomeProseLocalized(prose, locale)) throw new Error("User-visible prose must be in Simplified Chinese; translate English source material while preserving identifiers and evidence IDs");
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
129
178
|
function validationSummary(error) {
|
|
130
179
|
if (!(error instanceof z.ZodError)) return error instanceof Error ? error.message : String(error);
|
|
131
180
|
return error.issues.slice(0, 20).map((issue) => `${issue.path.join(".") || "<root>"}: ${issue.message}`).join("; ");
|
|
@@ -194,7 +243,7 @@ var HomeAdviceGenerator = class {
|
|
|
194
243
|
const raw = extractHomeResponseText(response);
|
|
195
244
|
let result;
|
|
196
245
|
try {
|
|
197
|
-
result =
|
|
246
|
+
result = parseLocalizedResult(raw, snapshot.locale);
|
|
198
247
|
} catch (firstError) {
|
|
199
248
|
const correction = {
|
|
200
249
|
role: "user",
|
|
@@ -221,7 +270,7 @@ var HomeAdviceGenerator = class {
|
|
|
221
270
|
trigger: "retry"
|
|
222
271
|
});
|
|
223
272
|
try {
|
|
224
|
-
result =
|
|
273
|
+
result = parseLocalizedResult(extractHomeResponseText(corrected), snapshot.locale);
|
|
225
274
|
} catch (correctionError) {
|
|
226
275
|
throw new Error(`Home intelligence model returned invalid structured JSON after correction: ${validationSummary(correctionError)}`);
|
|
227
276
|
}
|
|
@@ -239,4 +288,4 @@ var HomeAdviceGenerator = class {
|
|
|
239
288
|
}
|
|
240
289
|
};
|
|
241
290
|
//#endregion
|
|
242
|
-
export { HomeAdviceBudgetExceededError, HomeAdviceGenerator, HomeModelCandidateSchema, HomeModelResultSchema };
|
|
291
|
+
export { HomeAdviceBudgetExceededError, HomeAdviceGenerator, HomeModelCandidateSchema, HomeModelResultSchema, isHomeProseLocalized };
|
|
@@ -35,12 +35,13 @@ export declare class HomeIntelligenceHost {
|
|
|
35
35
|
private stopped;
|
|
36
36
|
private abortController;
|
|
37
37
|
private localeHint;
|
|
38
|
+
private advisorLocale;
|
|
38
39
|
private contextRefreshTimer?;
|
|
39
40
|
private readonly pendingContextReasons;
|
|
40
41
|
constructor(db: DatabaseSync, deps: HomeIntelligenceHostDeps);
|
|
41
42
|
start(): void;
|
|
42
43
|
stop(): void;
|
|
43
|
-
getAdvisor(): HomeAdvisor;
|
|
44
|
+
getAdvisor(locale?: string): HomeAdvisor;
|
|
44
45
|
getMetrics(since?: number): HomeAdviceMetrics;
|
|
45
46
|
getHistory(): HomeOpportunityHistoryItem[];
|
|
46
47
|
requestRefresh(reason: HomeGenerationReason, idempotencyKey?: string, locale?: string): string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { HomeAdviceBudgetExceededError } from "./generator.js";
|
|
3
|
+
import { HomeAdviceBudgetExceededError, isHomeProseLocalized } from "./generator.js";
|
|
4
4
|
import { homePatternKey } from "./strategy.js";
|
|
5
5
|
import { HomeAdvicePolicy } from "./policy.js";
|
|
6
6
|
import { HomeIntelligenceRepository } from "./repository.js";
|
|
@@ -39,6 +39,7 @@ var HomeIntelligenceHost = class {
|
|
|
39
39
|
stopped = false;
|
|
40
40
|
abortController = new AbortController();
|
|
41
41
|
localeHint;
|
|
42
|
+
advisorLocale;
|
|
42
43
|
contextRefreshTimer;
|
|
43
44
|
pendingContextReasons = /* @__PURE__ */ new Set();
|
|
44
45
|
constructor(db, deps) {
|
|
@@ -47,6 +48,7 @@ var HomeIntelligenceHost = class {
|
|
|
47
48
|
this.opportunities = new HomeOpportunityApplicationService(db, deps.principal, () => deps.capabilities().agentId);
|
|
48
49
|
this.now = deps.now ?? Date.now;
|
|
49
50
|
this.localeHint = deps.locale();
|
|
51
|
+
this.advisorLocale = this.localeHint;
|
|
50
52
|
}
|
|
51
53
|
start() {
|
|
52
54
|
if (this.timer) return;
|
|
@@ -65,9 +67,26 @@ var HomeIntelligenceHost = class {
|
|
|
65
67
|
this.contextRefreshTimer = void 0;
|
|
66
68
|
this.pendingContextReasons.clear();
|
|
67
69
|
}
|
|
68
|
-
getAdvisor() {
|
|
70
|
+
getAdvisor(locale) {
|
|
69
71
|
if (this.deps.enabled?.() === false) return { state: "disabled" };
|
|
70
|
-
|
|
72
|
+
if (locale) {
|
|
73
|
+
const requestedLocale = locale.toLowerCase().startsWith("zh") ? "zh" : "en";
|
|
74
|
+
if (requestedLocale !== this.localeHint) this.requestRefresh("manual_refresh", `locale:${requestedLocale}:${this.now()}`, requestedLocale);
|
|
75
|
+
}
|
|
76
|
+
const advisor = this.repository.getAdvisor(this.deps.principal, this.now());
|
|
77
|
+
const prose = advisor.state === "ready" ? [advisor.primary, ...advisor.alternatives].flatMap((item) => [
|
|
78
|
+
item.title,
|
|
79
|
+
item.outcome,
|
|
80
|
+
item.rationale
|
|
81
|
+
]) : advisor.state === "clarification" ? [advisor.question.question] : [];
|
|
82
|
+
if (prose.length > 0 && this.advisorLocale !== this.localeHint || !isHomeProseLocalized(prose, this.localeHint)) return advisor.state === "ready" && advisor.stale ? {
|
|
83
|
+
state: "refreshing",
|
|
84
|
+
requestedAt: this.now()
|
|
85
|
+
} : {
|
|
86
|
+
state: "quiet",
|
|
87
|
+
reason: "generation_failed"
|
|
88
|
+
};
|
|
89
|
+
return advisor;
|
|
71
90
|
}
|
|
72
91
|
getMetrics(since = Math.max(0, this.now() - 720 * 60 * 6e4)) {
|
|
73
92
|
return this.repository.getMetrics(this.deps.principal, since, this.now());
|
|
@@ -251,6 +270,7 @@ var HomeIntelligenceHost = class {
|
|
|
251
270
|
outcomeReason: result.state === "quiet" ? result.reason : result.state,
|
|
252
271
|
completedAt
|
|
253
272
|
});
|
|
273
|
+
this.advisorLocale = snapshot.locale;
|
|
254
274
|
this.deps.publish("home.advisor.updated", {
|
|
255
275
|
state: result.state,
|
|
256
276
|
completedAt
|
|
@@ -36,6 +36,7 @@ function migrateCloudModelRef(ref, kind = "language") {
|
|
|
36
36
|
if (!ref.startsWith("xopc-cloud/")) return ref;
|
|
37
37
|
const id = ref.slice(11);
|
|
38
38
|
if (PUBLIC_IDS.has(id) || id.startsWith("openai-codex/")) return ref;
|
|
39
|
+
if (id === "computer-gui-plus-preview" || id === "gui-plus-2026-02-26") return "xopc-cloud/computer";
|
|
39
40
|
return `xopc-cloud/${kind === "omni" ? "realtime" : kind === "language" ? "auto" : kind}`;
|
|
40
41
|
}
|
|
41
42
|
/** Only model fields are rewritten; prompts and historical transcripts are untouched. */
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ProductNotification } from '@xopcai/gateway-contract';
|
|
2
|
+
import type { NotificationPlan } from './planner.js';
|
|
3
|
+
export declare function isClarificationNotificationActionable(notification: Pick<ProductNotification, 'type' | 'payload' | 'target'>): boolean;
|
|
4
|
+
/** Wait creation and intent insertion commit together; publication and settlement do too. */
|
|
5
|
+
export declare function flushClarificationNotifications(persist: (plan: NotificationPlan) => ProductNotification | null): ProductNotification[];
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
2
|
+
import { init_session_instance_repository, readCurrentTranscriptId } from "../storage/sqlite/session-instance-repository.js";
|
|
3
|
+
import { getClarification, init_clarification_wait_repository } from "../storage/sqlite/clarification-wait-repository.js";
|
|
4
|
+
//#region src/notifications/clarification.ts
|
|
5
|
+
init_clarification_wait_repository();
|
|
6
|
+
init_session_instance_repository();
|
|
7
|
+
init_transaction();
|
|
8
|
+
function isClarificationNotificationActionable(notification) {
|
|
9
|
+
if (notification.type !== "chat.needs_input") return true;
|
|
10
|
+
const wait = typeof notification.payload.waitId === "string" ? getClarification(notification.payload.waitId) : void 0;
|
|
11
|
+
return Boolean(wait && wait.status === "open" && notification.target.kind === "chat" && notification.target.conversationId === wait.conversationId && readCurrentTranscriptId(getSqliteDatabase(), wait.conversationId) === wait.transcriptId && (wait.expiresAt === void 0 || wait.expiresAt > Date.now()));
|
|
12
|
+
}
|
|
13
|
+
/** Wait creation and intent insertion commit together; publication and settlement do too. */
|
|
14
|
+
function flushClarificationNotifications(persist) {
|
|
15
|
+
return runSqliteWriteTransaction((db) => {
|
|
16
|
+
const rows = db.prepare(`SELECT wait_id FROM clarification_notification_outbox
|
|
17
|
+
WHERE status = 'pending' ORDER BY created_at, wait_id LIMIT 100`).all();
|
|
18
|
+
const published = [];
|
|
19
|
+
for (const row of rows) {
|
|
20
|
+
const wait = getClarification(String(row.wait_id));
|
|
21
|
+
if (wait && !wait.taskRunId) {
|
|
22
|
+
const personal = db.prepare("SELECT json_extract(custom_data_json, '$.personalAgent') AS personal FROM sessions WHERE conversation_id = ?").get(wait.conversationId)?.personal === 1;
|
|
23
|
+
const notification = {
|
|
24
|
+
type: "chat.needs_input",
|
|
25
|
+
target: {
|
|
26
|
+
kind: "chat",
|
|
27
|
+
conversationId: wait.conversationId,
|
|
28
|
+
...personal ? { personal: true } : {}
|
|
29
|
+
},
|
|
30
|
+
priority: "high",
|
|
31
|
+
title: wait.kind === "approval" ? {
|
|
32
|
+
en: "Your authorization is needed",
|
|
33
|
+
zh: "需要你的授权"
|
|
34
|
+
} : {
|
|
35
|
+
en: "Your decision is needed",
|
|
36
|
+
zh: "需要你判断后继续"
|
|
37
|
+
},
|
|
38
|
+
body: {
|
|
39
|
+
en: "A question is waiting for your answer. Open the conversation to continue.",
|
|
40
|
+
zh: "有一个问题等待你回答,点击继续。"
|
|
41
|
+
},
|
|
42
|
+
payload: {
|
|
43
|
+
waitId: wait.id,
|
|
44
|
+
transcriptId: wait.transcriptId,
|
|
45
|
+
originRunId: wait.originRunId,
|
|
46
|
+
objectiveRevision: wait.objectiveRevision,
|
|
47
|
+
kind: wait.kind,
|
|
48
|
+
expiresAt: wait.expiresAt
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
if (isClarificationNotificationActionable(notification)) {
|
|
52
|
+
const event = persist({
|
|
53
|
+
dedupeKey: `clarification.needs_input:${wait.id}`,
|
|
54
|
+
createdAt: wait.createdAt,
|
|
55
|
+
notification
|
|
56
|
+
});
|
|
57
|
+
if (event) published.push(event);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
db.prepare("UPDATE clarification_notification_outbox SET status = 'settled' WHERE wait_id = ?").run(row.wait_id);
|
|
61
|
+
}
|
|
62
|
+
return published;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { flushClarificationNotifications, isClarificationNotificationActionable };
|
|
@@ -13,6 +13,7 @@ function parsePreferences(raw) {
|
|
|
13
13
|
}
|
|
14
14
|
function normalizePreferences(input) {
|
|
15
15
|
return {
|
|
16
|
+
chatNeedsInput: input?.chatNeedsInput ?? DEFAULT_NOTIFICATION_PREFERENCES.chatNeedsInput,
|
|
16
17
|
chatCompleted: input?.chatCompleted ?? DEFAULT_NOTIFICATION_PREFERENCES.chatCompleted,
|
|
17
18
|
chatFailed: input?.chatFailed ?? DEFAULT_NOTIFICATION_PREFERENCES.chatFailed,
|
|
18
19
|
taskNeedsInput: input?.taskNeedsInput ?? DEFAULT_NOTIFICATION_PREFERENCES.taskNeedsInput,
|
|
@@ -18,6 +18,7 @@ export type HarmonyNotification = {
|
|
|
18
18
|
body?: string;
|
|
19
19
|
gatewayId?: string;
|
|
20
20
|
target?: NotificationTarget;
|
|
21
|
+
expiresAt?: number;
|
|
21
22
|
};
|
|
22
23
|
export declare function harmonyPushConfig(env?: NodeJS.ProcessEnv): HarmonyPushConfig | undefined;
|
|
23
24
|
export declare function createHarmonyPushJwt(account: ServiceAccount, now?: number): string;
|
|
@@ -54,6 +54,8 @@ async function sendHarmonyPush(notification, fetchImpl = fetch, config = harmony
|
|
|
54
54
|
eventId: notification.eventId,
|
|
55
55
|
target: notification.target
|
|
56
56
|
})).toString("base64url") : void 0;
|
|
57
|
+
const ttl = notification.expiresAt === void 0 ? 86400 : Math.min(86400, Math.floor((notification.expiresAt - Date.now()) / 1e3));
|
|
58
|
+
if (ttl <= 0) throw new Error("Notification expired before delivery");
|
|
57
59
|
const response = await fetchImpl(`https://push-api.cloud.huawei.com/v3/${account.project_id}/messages:send`, {
|
|
58
60
|
method: "POST",
|
|
59
61
|
redirect: "error",
|
|
@@ -78,7 +80,7 @@ async function sendHarmonyPush(notification, fetchImpl = fetch, config = harmony
|
|
|
78
80
|
target: { token: [notification.pushToken] },
|
|
79
81
|
pushOptions: {
|
|
80
82
|
testMessage: config.testMessage,
|
|
81
|
-
ttl
|
|
83
|
+
ttl
|
|
82
84
|
}
|
|
83
85
|
})
|
|
84
86
|
});
|
|
@@ -21,7 +21,7 @@ export declare class NotificationService {
|
|
|
21
21
|
persistGatewayEvent(type: string, payload: unknown): {
|
|
22
22
|
schemaVersion: 1;
|
|
23
23
|
id: string;
|
|
24
|
-
type: "work_discovery.completed" | "work_discovery.failed" | "scene.result" | "scene.digest" | "chat.completed" | "chat.failed" | "task.needs_input" | "task.blocked" | "task.failed" | "task.completed" | "automation.completed" | "automation.failed" | "home.opportunity";
|
|
24
|
+
type: "work_discovery.completed" | "work_discovery.failed" | "scene.result" | "scene.digest" | "chat.needs_input" | "chat.completed" | "chat.failed" | "task.needs_input" | "task.blocked" | "task.failed" | "task.completed" | "automation.completed" | "automation.failed" | "home.opportunity";
|
|
25
25
|
priority: "normal" | "high";
|
|
26
26
|
title: {
|
|
27
27
|
en: string;
|
|
@@ -62,7 +62,7 @@ export declare class NotificationService {
|
|
|
62
62
|
persistPlan(plan: NotificationPlan): {
|
|
63
63
|
schemaVersion: 1;
|
|
64
64
|
id: string;
|
|
65
|
-
type: "work_discovery.completed" | "work_discovery.failed" | "scene.result" | "scene.digest" | "chat.completed" | "chat.failed" | "task.needs_input" | "task.blocked" | "task.failed" | "task.completed" | "automation.completed" | "automation.failed" | "home.opportunity";
|
|
65
|
+
type: "work_discovery.completed" | "work_discovery.failed" | "scene.result" | "scene.digest" | "chat.needs_input" | "chat.completed" | "chat.failed" | "task.needs_input" | "task.blocked" | "task.failed" | "task.completed" | "automation.completed" | "automation.failed" | "home.opportunity";
|
|
66
66
|
priority: "normal" | "high";
|
|
67
67
|
title: {
|
|
68
68
|
en: string;
|
|
@@ -4,13 +4,14 @@ import { init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/t
|
|
|
4
4
|
import { localizeNotification } from "../../packages/gateway-contract/src/notifications.js";
|
|
5
5
|
import { init_src } from "../../packages/gateway-contract/src/index.js";
|
|
6
6
|
import { getOrCreateGatewayIdentity, init_gateway_identity_repository } from "../storage/sqlite/gateway-identity-repository.js";
|
|
7
|
-
import { listDeliverableNotificationDevices } from "./device-store.js";
|
|
7
|
+
import { getNotificationDevice, listDeliverableNotificationDevices } from "./device-store.js";
|
|
8
8
|
import { notificationPlanFromGatewayEvent } from "./planner.js";
|
|
9
|
-
import { createNotificationEvent, deferNotificationDelivery, expireUndeliverableNotificationDeliveries, listDueNotificationDeliveries, markNotificationDeliveryAccepted, markNotificationDeliveryDead, pruneNotificationEvents, rescheduleNotificationDelivery } from "./store.js";
|
|
9
|
+
import { cancelNotificationDelivery, createNotificationEvent, deferNotificationDelivery, expireUndeliverableNotificationDeliveries, listDueNotificationDeliveries, markNotificationDeliveryAccepted, markNotificationDeliveryDead, pruneNotificationEvents, rescheduleNotificationDelivery } from "./store.js";
|
|
10
10
|
import { sendHarmonyPush } from "./harmony-push.js";
|
|
11
|
+
import { flushClarificationNotifications, isClarificationNotificationActionable } from "./clarification.js";
|
|
11
12
|
//#region src/notifications/service.ts
|
|
12
|
-
init_transaction();
|
|
13
13
|
init_src();
|
|
14
|
+
init_transaction();
|
|
14
15
|
init_logger();
|
|
15
16
|
init_gateway_identity_repository();
|
|
16
17
|
const log = createLogger("Notifications");
|
|
@@ -23,6 +24,7 @@ const RETRY_DELAYS_MS = [
|
|
|
23
24
|
216e5
|
|
24
25
|
];
|
|
25
26
|
const STANDARD_PREFERENCES = {
|
|
27
|
+
"chat.needs_input": "chatNeedsInput",
|
|
26
28
|
"chat.completed": "chatCompleted",
|
|
27
29
|
"chat.failed": "chatFailed",
|
|
28
30
|
"task.needs_input": "taskNeedsInput",
|
|
@@ -62,6 +64,10 @@ var NotificationService = class {
|
|
|
62
64
|
}
|
|
63
65
|
handleGatewayEvent(type, payload) {
|
|
64
66
|
try {
|
|
67
|
+
if (type === "clarification.created") {
|
|
68
|
+
this.drain();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
65
71
|
const notification = this.persistGatewayEvent(type, payload);
|
|
66
72
|
if (!notification) return;
|
|
67
73
|
this.options.publish("notification.created", notification);
|
|
@@ -108,6 +114,7 @@ var NotificationService = class {
|
|
|
108
114
|
pruneNotificationEvents(now - 720 * 60 * 60 * 1e3);
|
|
109
115
|
this.lastMaintenanceAt = now;
|
|
110
116
|
}
|
|
117
|
+
for (const notification of flushClarificationNotifications((plan) => this.persistPlan(plan))) this.options.publish("notification.created", notification);
|
|
111
118
|
for (const notification of this.options.domainDelivery?.flush((plan) => this.persistPlan(plan)) ?? []) this.options.publish("notification.created", notification);
|
|
112
119
|
await this.deliverPending();
|
|
113
120
|
await this.options.domainDelivery?.drain();
|
|
@@ -126,10 +133,18 @@ var NotificationService = class {
|
|
|
126
133
|
await Promise.all(deliveries.map((delivery) => this.send(delivery)));
|
|
127
134
|
}
|
|
128
135
|
async send(delivery) {
|
|
136
|
+
if (!isClarificationNotificationActionable(delivery.event)) {
|
|
137
|
+
cancelNotificationDelivery(delivery.event.id, delivery.deviceId);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
129
140
|
if (this.options.allowsNotification?.(delivery.event) === false) {
|
|
130
141
|
markNotificationDeliveryDead(delivery.event.id, delivery.deviceId, "Notification policy changed");
|
|
131
142
|
return;
|
|
132
143
|
}
|
|
144
|
+
if (delivery.event.type === "chat.needs_input" && !getNotificationDevice(delivery.deviceId)?.preferences.chatNeedsInput) {
|
|
145
|
+
cancelNotificationDelivery(delivery.event.id, delivery.deviceId);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
133
148
|
const domain = this.options.domainDelivery?.owns(delivery.event.type) ? this.options.domainDelivery : void 0;
|
|
134
149
|
if (!domain && !Object.hasOwn(STANDARD_PREFERENCES, delivery.event.type)) {
|
|
135
150
|
markNotificationDeliveryDead(delivery.event.id, delivery.deviceId, "Notification domain delivery is not installed");
|
|
@@ -163,7 +178,8 @@ var NotificationService = class {
|
|
|
163
178
|
gatewayId: getOrCreateGatewayIdentity().id,
|
|
164
179
|
target: delivery.event.target,
|
|
165
180
|
title: preview.title,
|
|
166
|
-
body: preview.body
|
|
181
|
+
body: preview.body,
|
|
182
|
+
...delivery.event.type === "chat.needs_input" && typeof delivery.event.payload.expiresAt === "number" ? { expiresAt: delivery.event.payload.expiresAt } : {}
|
|
167
183
|
}, fetchImpl);
|
|
168
184
|
markNotificationDeliveryAccepted(delivery.event.id, delivery.deviceId, ticket, Number.MAX_SAFE_INTEGER);
|
|
169
185
|
} catch (err) {
|
|
@@ -38,6 +38,7 @@ export declare function notificationDeliveryMetrics(): {
|
|
|
38
38
|
accepted: number;
|
|
39
39
|
delivered: number;
|
|
40
40
|
dead: number;
|
|
41
|
+
cancelled: number;
|
|
41
42
|
due: number;
|
|
42
43
|
devices: {
|
|
43
44
|
deliverable: number;
|
|
@@ -56,3 +57,4 @@ export declare function expireUndeliverableNotificationDeliveries(now?: number):
|
|
|
56
57
|
export declare function pruneNotificationEvents(before: number): number;
|
|
57
58
|
export declare function deferNotificationDelivery(eventId: string, deviceId: string, nextAttemptAt: number): void;
|
|
58
59
|
export declare function getNotificationEvent(id: string): ProductNotification | null;
|
|
60
|
+
export declare function cancelNotificationDelivery(eventId: string, deviceId: string): void;
|
|
@@ -149,6 +149,7 @@ function notificationDeliveryMetrics() {
|
|
|
149
149
|
accepted: counts.accepted ?? 0,
|
|
150
150
|
delivered: counts.delivered ?? 0,
|
|
151
151
|
dead: counts.dead ?? 0,
|
|
152
|
+
cancelled: counts.cancelled ?? 0,
|
|
152
153
|
due: due.count,
|
|
153
154
|
devices: {
|
|
154
155
|
deliverable: devices.deliverable ?? 0,
|
|
@@ -190,5 +191,10 @@ function getNotificationEvent(id) {
|
|
|
190
191
|
const row = getSqliteDatabase().prepare("SELECT * FROM notification_events WHERE event_id = ?").get(id);
|
|
191
192
|
return row ? eventFromRow(row) : null;
|
|
192
193
|
}
|
|
194
|
+
function cancelNotificationDelivery(eventId, deviceId) {
|
|
195
|
+
getSqliteDatabase().prepare(`UPDATE notification_deliveries SET status = 'cancelled',
|
|
196
|
+
last_error = 'Clarification is no longer actionable', updated_at = ?
|
|
197
|
+
WHERE event_id = ? AND device_id = ? AND status = 'pending'`).run(Date.now(), eventId, deviceId);
|
|
198
|
+
}
|
|
193
199
|
//#endregion
|
|
194
|
-
export { acknowledgeNotification, createNotificationEvent, deferNotificationDelivery, expireUndeliverableNotificationDeliveries, getNotificationEvent, listDueNotificationDeliveries, listNotificationEvents, markNotificationDeliveryAccepted, markNotificationDeliveryDead, markNotificationDeliveryDelivered, notificationDeliveryMetrics, pruneNotificationEvents, rescheduleNotificationDelivery };
|
|
200
|
+
export { acknowledgeNotification, cancelNotificationDelivery, createNotificationEvent, deferNotificationDelivery, expireUndeliverableNotificationDeliveries, getNotificationEvent, listDueNotificationDeliveries, listNotificationEvents, markNotificationDeliveryAccepted, markNotificationDeliveryDead, markNotificationDeliveryDelivered, notificationDeliveryMetrics, pruneNotificationEvents, rescheduleNotificationDelivery };
|
|
@@ -2,6 +2,7 @@ export type NotificationDevicePlatform = 'ios' | 'android' | 'harmonyos';
|
|
|
2
2
|
export type NotificationPermission = 'granted' | 'denied' | 'unknown';
|
|
3
3
|
export type NotificationLanguage = 'en' | 'zh';
|
|
4
4
|
export type NotificationPreferences = {
|
|
5
|
+
chatNeedsInput: boolean;
|
|
5
6
|
chatCompleted: boolean;
|
|
6
7
|
chatFailed: boolean;
|
|
7
8
|
taskNeedsInput: boolean;
|
|
@@ -185,6 +185,7 @@ function createClarificationWait(input) {
|
|
|
185
185
|
id, principal_id, conversation_id, transcript_id, status, version, data_json,
|
|
186
186
|
origin_run_id, origin_tool_call_id
|
|
187
187
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(wait.id, wait.principalId, wait.conversationId, wait.transcriptId, wait.status, wait.version, JSON.stringify(wait), wait.originRunId, wait.originToolCallId);
|
|
188
|
+
db.prepare("INSERT INTO clarification_notification_outbox(wait_id, created_at) VALUES (?, ?)").run(wait.id, wait.createdAt);
|
|
188
189
|
markTaskWaiting(wait);
|
|
189
190
|
bumpSessionInputRevision(db, input.conversationId);
|
|
190
191
|
return wait;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
CREATE TABLE browser_automation_versions (
|
|
2
|
+
automation_id TEXT NOT NULL REFERENCES browser_automations(automation_id) ON DELETE CASCADE,
|
|
3
|
+
revision INTEGER NOT NULL,
|
|
4
|
+
definition_json TEXT NOT NULL,
|
|
5
|
+
created_at_ms INTEGER NOT NULL,
|
|
6
|
+
PRIMARY KEY (automation_id, revision)
|
|
7
|
+
);
|
|
8
|
+
INSERT INTO browser_automation_versions SELECT automation_id, revision, definition_json, updated_at_ms FROM browser_automations;
|
|
9
|
+
|
|
10
|
+
CREATE TABLE browser_automation_verifications (
|
|
11
|
+
automation_id TEXT NOT NULL,
|
|
12
|
+
revision INTEGER NOT NULL,
|
|
13
|
+
run_id TEXT NOT NULL REFERENCES browser_automation_runs(run_id) ON DELETE CASCADE,
|
|
14
|
+
verified_at_ms INTEGER NOT NULL,
|
|
15
|
+
PRIMARY KEY (automation_id, revision),
|
|
16
|
+
FOREIGN KEY (automation_id, revision) REFERENCES browser_automation_versions(automation_id, revision) ON DELETE CASCADE
|
|
17
|
+
);
|
|
18
|
+
ALTER TABLE browser_automation_runs ADD COLUMN client_request_id TEXT;
|
|
19
|
+
ALTER TABLE browser_automation_runs ADD COLUMN business_outcome TEXT;
|
|
20
|
+
CREATE UNIQUE INDEX idx_browser_run_request ON browser_automation_runs(client_request_id) WHERE client_request_id IS NOT NULL;
|
|
21
|
+
|
|
22
|
+
CREATE TABLE browser_recordings (
|
|
23
|
+
recording_id TEXT PRIMARY KEY,
|
|
24
|
+
principal_id TEXT NOT NULL,
|
|
25
|
+
state TEXT NOT NULL,
|
|
26
|
+
ack_seq INTEGER NOT NULL DEFAULT 0,
|
|
27
|
+
final_seq INTEGER,
|
|
28
|
+
automation_id TEXT REFERENCES browser_automations(automation_id) ON DELETE CASCADE,
|
|
29
|
+
error TEXT,
|
|
30
|
+
created_at_ms INTEGER NOT NULL,
|
|
31
|
+
updated_at_ms INTEGER NOT NULL
|
|
32
|
+
);
|
|
33
|
+
CREATE TABLE browser_recording_events (
|
|
34
|
+
recording_id TEXT NOT NULL REFERENCES browser_recordings(recording_id) ON DELETE CASCADE,
|
|
35
|
+
seq INTEGER NOT NULL,
|
|
36
|
+
event_id TEXT NOT NULL UNIQUE,
|
|
37
|
+
payload_json TEXT NOT NULL,
|
|
38
|
+
PRIMARY KEY (recording_id, seq)
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
UPDATE automations SET action_json=json_set(action_json, '$.revision', COALESCE((SELECT revision FROM browser_automations WHERE automation_id=json_extract(automations.action_json, '$.automationId')), 1)), enabled=0
|
|
42
|
+
WHERE json_extract(action_json, '$.kind')='browser_automation';
|
|
43
|
+
|
|
44
|
+
UPDATE devices SET scopes_json=json_insert(scopes_json, '$[#]', 'automations.read') WHERE platform='chrome' AND NOT EXISTS(SELECT 1 FROM json_each(scopes_json) WHERE value='automations.read');
|
|
45
|
+
UPDATE devices SET scopes_json=json_insert(scopes_json, '$[#]', 'automations.write') WHERE platform='chrome' AND NOT EXISTS(SELECT 1 FROM json_each(scopes_json) WHERE value='automations.write');
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
CREATE TABLE clarification_notification_outbox (
|
|
2
|
+
wait_id TEXT PRIMARY KEY REFERENCES session_clarification_waits(id) ON DELETE CASCADE,
|
|
3
|
+
status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'settled')),
|
|
4
|
+
created_at INTEGER NOT NULL
|
|
5
|
+
);
|
|
6
|
+
CREATE INDEX idx_clarification_notification_pending ON clarification_notification_outbox(status, created_at);
|
|
7
|
+
INSERT INTO clarification_notification_outbox(wait_id, created_at)
|
|
8
|
+
SELECT id, CAST(json_extract(data_json, '$.createdAt') AS INTEGER)
|
|
9
|
+
FROM session_clarification_waits WHERE status = 'open';
|
|
10
|
+
|
|
11
|
+
ALTER TABLE notification_deliveries RENAME TO notification_deliveries_old;
|
|
12
|
+
CREATE TABLE notification_deliveries (
|
|
13
|
+
event_id TEXT NOT NULL REFERENCES notification_events(event_id) ON DELETE CASCADE,
|
|
14
|
+
device_id TEXT NOT NULL REFERENCES device_push_endpoints(device_id) ON DELETE CASCADE,
|
|
15
|
+
status TEXT NOT NULL CHECK(status IN ('pending', 'accepted', 'delivered', 'dead', 'cancelled')),
|
|
16
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
17
|
+
next_attempt_at INTEGER NOT NULL,
|
|
18
|
+
provider_ticket_id TEXT,
|
|
19
|
+
last_error TEXT,
|
|
20
|
+
updated_at INTEGER NOT NULL,
|
|
21
|
+
PRIMARY KEY(event_id, device_id)
|
|
22
|
+
);
|
|
23
|
+
INSERT INTO notification_deliveries SELECT * FROM notification_deliveries_old;
|
|
24
|
+
DROP TABLE notification_deliveries_old;
|
|
25
|
+
CREATE INDEX idx_notification_deliveries_due ON notification_deliveries(status, next_attempt_at);
|
|
26
|
+
CREATE INDEX idx_notification_deliveries_device ON notification_deliveries(device_id);
|
|
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
|
|
|
3
3
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
4
4
|
export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 165;
|
|
5
5
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
6
|
-
export declare const XOPC_DB_SCHEMA_VERSION =
|
|
6
|
+
export declare const XOPC_DB_SCHEMA_VERSION = 239;
|
|
7
7
|
export declare function resolveMigrationsDir(override?: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
|
|
@@ -57,7 +57,7 @@ function applySingleMigration(db, migration, discardOldScenes = false) {
|
|
|
57
57
|
*/
|
|
58
58
|
function applyPendingMigrations(db, options = {}) {
|
|
59
59
|
db.function("xopc_operation_id", () => currentOperationId() ?? null);
|
|
60
|
-
const targetVersion = options.targetVersion ??
|
|
60
|
+
const targetVersion = options.targetVersion ?? 239;
|
|
61
61
|
let currentVersion = readSchemaVersion(db);
|
|
62
62
|
if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
|
|
63
63
|
if (!options.migrationsDir && currentVersion < 165) throw new DatabaseSchemaTooOldError(currentVersion, 165);
|
|
@@ -95,7 +95,7 @@ function applyPendingMigrations(db, options = {}) {
|
|
|
95
95
|
}
|
|
96
96
|
/** Inspect schema version without mutating the database. */
|
|
97
97
|
function inspectSchemaMigrationStatus(db, options = {}) {
|
|
98
|
-
const appVersion = options.targetVersion ??
|
|
98
|
+
const appVersion = options.targetVersion ?? 239;
|
|
99
99
|
const dbVersion = readSchemaVersion(db);
|
|
100
100
|
if (dbVersion > appVersion) return {
|
|
101
101
|
dbVersion,
|
|
@@ -137,7 +137,7 @@ var init_runner = __esmMin((() => {
|
|
|
137
137
|
init_errors();
|
|
138
138
|
log = createLogger("Sqlite:Migrations");
|
|
139
139
|
XOPC_DB_BASELINE_SCHEMA_VERSION = 165;
|
|
140
|
-
XOPC_DB_SCHEMA_VERSION =
|
|
140
|
+
XOPC_DB_SCHEMA_VERSION = 239;
|
|
141
141
|
}));
|
|
142
142
|
//#endregion
|
|
143
143
|
init_runner();
|
|
@@ -58,7 +58,7 @@ export declare class HomeQueryService {
|
|
|
58
58
|
#private;
|
|
59
59
|
private readonly service;
|
|
60
60
|
private readonly getAdvisor;
|
|
61
|
-
constructor(service: HomeGatewayPort, getAdvisor?: () => HomeAdvisor);
|
|
61
|
+
constructor(service: HomeGatewayPort, getAdvisor?: (locale?: string) => HomeAdvisor);
|
|
62
62
|
getSnapshot(locale?: string): Promise<HomeResponse>;
|
|
63
63
|
}
|
|
64
64
|
export {};
|
|
@@ -104,7 +104,11 @@ function decisionFromTask(model, projectName, locale) {
|
|
|
104
104
|
},
|
|
105
105
|
kind: "task",
|
|
106
106
|
title: task.title,
|
|
107
|
-
detail:
|
|
107
|
+
detail: isChinese ? {
|
|
108
|
+
"Agent run returned no result or evidence": "本次执行没有返回结果或依据,请重试。",
|
|
109
|
+
"The latest run failed": "最近一次执行失败,请查看详情后重试。",
|
|
110
|
+
"Task is overdue": "任务已逾期。"
|
|
111
|
+
}[item.summary] ?? item.summary : item.summary,
|
|
108
112
|
reason,
|
|
109
113
|
urgency: "now",
|
|
110
114
|
href: `/tasks/${encodeURIComponent(task.id)}`,
|
|
@@ -412,7 +416,7 @@ var HomeQueryService = class {
|
|
|
412
416
|
}),
|
|
413
417
|
runningConversations,
|
|
414
418
|
decisions,
|
|
415
|
-
advisor: this.getAdvisor(),
|
|
419
|
+
advisor: this.getAdvisor(locale),
|
|
416
420
|
attentionPolicy: governed.policy
|
|
417
421
|
};
|
|
418
422
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SpeechSynthesisStreamResult } from '../tts/speech-provider-types.js';
|
|
1
|
+
import type { SpeechStreamSession, SpeechSynthesisStreamResult } from '../tts/speech-provider-types.js';
|
|
2
2
|
export interface DashScopeStreamingTtsRequest {
|
|
3
3
|
apiKey: string;
|
|
4
4
|
baseUrl?: string;
|
|
@@ -11,3 +11,4 @@ export interface DashScopeStreamingTtsRequest {
|
|
|
11
11
|
timeoutMs: number;
|
|
12
12
|
}
|
|
13
13
|
export declare function openDashScopeStreamingTts(request: DashScopeStreamingTtsRequest): Promise<SpeechSynthesisStreamResult>;
|
|
14
|
+
export declare function openDashScopeTtsSession(request: Omit<DashScopeStreamingTtsRequest, 'text'>): Promise<SpeechStreamSession>;
|