@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AgentTool } from '@earendil-works/pi-agent-core';
|
|
2
2
|
import type { BrowserAutomationService } from '../../browser/automations/index.js';
|
|
3
3
|
declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
|
|
4
|
-
action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"list">, import("@sinclair/typebox").TLiteral<"get">, import("@sinclair/typebox").TLiteral<"save">, import("@sinclair/typebox").TLiteral<"enable">, import("@sinclair/typebox").TLiteral<"disable">, import("@sinclair/typebox").TLiteral<"delete">, import("@sinclair/typebox").TLiteral<"run">]>;
|
|
4
|
+
action: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"list">, import("@sinclair/typebox").TLiteral<"get">, import("@sinclair/typebox").TLiteral<"save">, import("@sinclair/typebox").TLiteral<"enable">, import("@sinclair/typebox").TLiteral<"disable">, import("@sinclair/typebox").TLiteral<"delete">, import("@sinclair/typebox").TLiteral<"run">, import("@sinclair/typebox").TLiteral<"test">, import("@sinclair/typebox").TLiteral<"validate">]>;
|
|
5
5
|
automationId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
6
6
|
definition: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
7
7
|
id: import("@sinclair/typebox").TString;
|
|
@@ -32,6 +32,11 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
|
|
|
32
32
|
role: import("@sinclair/typebox").TString;
|
|
33
33
|
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
34
34
|
nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
35
|
+
testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
36
|
+
scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
37
|
+
role: import("@sinclair/typebox").TString;
|
|
38
|
+
name: import("@sinclair/typebox").TString;
|
|
39
|
+
}>>;
|
|
35
40
|
}>;
|
|
36
41
|
expect: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
37
42
|
urlIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -46,6 +51,11 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
|
|
|
46
51
|
role: import("@sinclair/typebox").TString;
|
|
47
52
|
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
48
53
|
nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
54
|
+
testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
55
|
+
scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
56
|
+
role: import("@sinclair/typebox").TString;
|
|
57
|
+
name: import("@sinclair/typebox").TString;
|
|
58
|
+
}>>;
|
|
49
59
|
}>;
|
|
50
60
|
value: import("@sinclair/typebox").TString;
|
|
51
61
|
submit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
@@ -56,12 +66,30 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
|
|
|
56
66
|
ref: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
57
67
|
state: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"visible">, import("@sinclair/typebox").TLiteral<"hidden">]>>;
|
|
58
68
|
}>>;
|
|
69
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
70
|
+
action: import("@sinclair/typebox").TLiteral<"check">;
|
|
71
|
+
target: import("@sinclair/typebox").TObject<{
|
|
72
|
+
role: import("@sinclair/typebox").TString;
|
|
73
|
+
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
74
|
+
nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
75
|
+
testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
76
|
+
scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
77
|
+
role: import("@sinclair/typebox").TString;
|
|
78
|
+
name: import("@sinclair/typebox").TString;
|
|
79
|
+
}>>;
|
|
80
|
+
}>;
|
|
81
|
+
checked: import("@sinclair/typebox").TBoolean;
|
|
59
82
|
}>, import("@sinclair/typebox").TObject<{
|
|
60
83
|
action: import("@sinclair/typebox").TLiteral<"select">;
|
|
61
84
|
target: import("@sinclair/typebox").TObject<{
|
|
62
85
|
role: import("@sinclair/typebox").TString;
|
|
63
86
|
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
64
87
|
nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
88
|
+
testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
89
|
+
scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
90
|
+
role: import("@sinclair/typebox").TString;
|
|
91
|
+
name: import("@sinclair/typebox").TString;
|
|
92
|
+
}>>;
|
|
65
93
|
}>;
|
|
66
94
|
value: import("@sinclair/typebox").TString;
|
|
67
95
|
expect: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
@@ -77,6 +105,11 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
|
|
|
77
105
|
role: import("@sinclair/typebox").TString;
|
|
78
106
|
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
79
107
|
nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
108
|
+
testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
109
|
+
scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
110
|
+
role: import("@sinclair/typebox").TString;
|
|
111
|
+
name: import("@sinclair/typebox").TString;
|
|
112
|
+
}>>;
|
|
80
113
|
}>>;
|
|
81
114
|
key: import("@sinclair/typebox").TString;
|
|
82
115
|
expect: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
@@ -92,6 +125,11 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
|
|
|
92
125
|
role: import("@sinclair/typebox").TString;
|
|
93
126
|
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
94
127
|
nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
128
|
+
testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
129
|
+
scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
130
|
+
role: import("@sinclair/typebox").TString;
|
|
131
|
+
name: import("@sinclair/typebox").TString;
|
|
132
|
+
}>>;
|
|
95
133
|
}>>;
|
|
96
134
|
deltaY: import("@sinclair/typebox").TNumber;
|
|
97
135
|
expect: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
@@ -109,11 +147,46 @@ declare const BrowserAutomationToolSchema: import("@sinclair/typebox").TObject<{
|
|
|
109
147
|
role: import("@sinclair/typebox").TString;
|
|
110
148
|
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
111
149
|
nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
150
|
+
testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
151
|
+
scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
152
|
+
role: import("@sinclair/typebox").TString;
|
|
153
|
+
name: import("@sinclair/typebox").TString;
|
|
154
|
+
}>>;
|
|
112
155
|
}>>;
|
|
113
156
|
timeoutMs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
114
157
|
}>]>>;
|
|
158
|
+
successCriteria: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
159
|
+
target: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
160
|
+
role: import("@sinclair/typebox").TString;
|
|
161
|
+
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
162
|
+
nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
163
|
+
testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
164
|
+
scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
165
|
+
role: import("@sinclair/typebox").TString;
|
|
166
|
+
name: import("@sinclair/typebox").TString;
|
|
167
|
+
}>>;
|
|
168
|
+
}>>;
|
|
169
|
+
field: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<string>[]>;
|
|
170
|
+
equals: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TString, import("@sinclair/typebox").TBoolean]>>;
|
|
171
|
+
includes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
172
|
+
}>>>;
|
|
173
|
+
outputs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TObject<{
|
|
174
|
+
target: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
175
|
+
role: import("@sinclair/typebox").TString;
|
|
176
|
+
name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
177
|
+
nameIncludes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
178
|
+
testId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
179
|
+
scope: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
180
|
+
role: import("@sinclair/typebox").TString;
|
|
181
|
+
name: import("@sinclair/typebox").TString;
|
|
182
|
+
}>>;
|
|
183
|
+
}>>;
|
|
184
|
+
field: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<string>[]>;
|
|
185
|
+
}>>>;
|
|
115
186
|
}>>;
|
|
116
187
|
inputs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TUnknown>>;
|
|
188
|
+
revision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
189
|
+
expectedRevision: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
117
190
|
}>;
|
|
118
191
|
export declare function createBrowserAutomationTool(deps: {
|
|
119
192
|
getBrowserAutomationService: () => BrowserAutomationService | undefined;
|
|
@@ -10,7 +10,12 @@ const ExpectationSchema = Type.Object({
|
|
|
10
10
|
const TargetSchema = Type.Object({
|
|
11
11
|
role: Type.String(),
|
|
12
12
|
name: Type.Optional(Type.String()),
|
|
13
|
-
nameIncludes: Type.Optional(Type.String())
|
|
13
|
+
nameIncludes: Type.Optional(Type.String()),
|
|
14
|
+
testId: Type.Optional(Type.String()),
|
|
15
|
+
scope: Type.Optional(Type.Object({
|
|
16
|
+
role: Type.String(),
|
|
17
|
+
name: Type.String()
|
|
18
|
+
}, { additionalProperties: false }))
|
|
14
19
|
}, { additionalProperties: false });
|
|
15
20
|
const StepSchema = Type.Union([
|
|
16
21
|
Type.Object({
|
|
@@ -30,6 +35,11 @@ const StepSchema = Type.Union([
|
|
|
30
35
|
submit: Type.Optional(Type.Boolean()),
|
|
31
36
|
expect: Type.Optional(ExpectationSchema)
|
|
32
37
|
}, { additionalProperties: false }),
|
|
38
|
+
Type.Object({
|
|
39
|
+
action: Type.Literal("check"),
|
|
40
|
+
target: TargetSchema,
|
|
41
|
+
checked: Type.Boolean()
|
|
42
|
+
}, { additionalProperties: false }),
|
|
33
43
|
Type.Object({
|
|
34
44
|
action: Type.Literal("select"),
|
|
35
45
|
target: TargetSchema,
|
|
@@ -69,7 +79,9 @@ const BrowserAutomationToolSchema = Type.Object({
|
|
|
69
79
|
Type.Literal("enable"),
|
|
70
80
|
Type.Literal("disable"),
|
|
71
81
|
Type.Literal("delete"),
|
|
72
|
-
Type.Literal("run")
|
|
82
|
+
Type.Literal("run"),
|
|
83
|
+
Type.Literal("test"),
|
|
84
|
+
Type.Literal("validate")
|
|
73
85
|
]),
|
|
74
86
|
automationId: Type.Optional(Type.String()),
|
|
75
87
|
definition: Type.Optional(Type.Object({
|
|
@@ -103,9 +115,33 @@ const BrowserAutomationToolSchema = Type.Object({
|
|
|
103
115
|
Type.Boolean()
|
|
104
116
|
])))
|
|
105
117
|
}, { additionalProperties: false })),
|
|
106
|
-
steps: Type.Array(StepSchema)
|
|
118
|
+
steps: Type.Array(StepSchema),
|
|
119
|
+
successCriteria: Type.Optional(Type.Array(Type.Object({
|
|
120
|
+
target: Type.Optional(TargetSchema),
|
|
121
|
+
field: Type.Union([
|
|
122
|
+
"text",
|
|
123
|
+
"value",
|
|
124
|
+
"url",
|
|
125
|
+
"title",
|
|
126
|
+
"checked"
|
|
127
|
+
].map((field) => Type.Literal(field))),
|
|
128
|
+
equals: Type.Optional(Type.Union([Type.String(), Type.Boolean()])),
|
|
129
|
+
includes: Type.Optional(Type.String())
|
|
130
|
+
}, { additionalProperties: false }))),
|
|
131
|
+
outputs: Type.Optional(Type.Record(Type.String(), Type.Object({
|
|
132
|
+
target: Type.Optional(TargetSchema),
|
|
133
|
+
field: Type.Union([
|
|
134
|
+
"text",
|
|
135
|
+
"value",
|
|
136
|
+
"url",
|
|
137
|
+
"title",
|
|
138
|
+
"href"
|
|
139
|
+
].map((field) => Type.Literal(field)))
|
|
140
|
+
}, { additionalProperties: false })))
|
|
107
141
|
}, { additionalProperties: false })),
|
|
108
|
-
inputs: Type.Optional(Type.Record(Type.String(), Type.Unknown()))
|
|
142
|
+
inputs: Type.Optional(Type.Record(Type.String(), Type.Unknown())),
|
|
143
|
+
revision: Type.Optional(Type.Integer({ minimum: 1 })),
|
|
144
|
+
expectedRevision: Type.Optional(Type.Integer({ minimum: 1 }))
|
|
109
145
|
}, { additionalProperties: false });
|
|
110
146
|
function createBrowserAutomationTool(deps) {
|
|
111
147
|
return {
|
|
@@ -123,10 +159,17 @@ function createBrowserAutomationTool(deps) {
|
|
|
123
159
|
automations
|
|
124
160
|
});
|
|
125
161
|
}
|
|
162
|
+
if (params.action === "validate") {
|
|
163
|
+
const parsed = service.validate(params.definition);
|
|
164
|
+
return output(parsed.success ? "Definition is valid; it has not been executed." : JSON.stringify(parsed.error.issues), { ok: parsed.success });
|
|
165
|
+
}
|
|
126
166
|
if (params.action === "save") {
|
|
127
167
|
if (!params.definition) return output("definition is required.", { ok: false });
|
|
128
168
|
try {
|
|
129
|
-
const automation = service.save({
|
|
169
|
+
const automation = service.save({
|
|
170
|
+
definition: params.definition,
|
|
171
|
+
expectedRevision: params.expectedRevision
|
|
172
|
+
});
|
|
130
173
|
return output(`Saved browser automation: ${automation.definition.name}`, {
|
|
131
174
|
ok: true,
|
|
132
175
|
automation
|
|
@@ -167,7 +210,10 @@ function createBrowserAutomationTool(deps) {
|
|
|
167
210
|
});
|
|
168
211
|
}
|
|
169
212
|
try {
|
|
170
|
-
const run = await service.runAndWait(id, params.inputs ?? {}, signal
|
|
213
|
+
const run = await service.runAndWait(id, params.inputs ?? {}, signal, {
|
|
214
|
+
revision: params.revision,
|
|
215
|
+
clientRequestId: _toolCallId
|
|
216
|
+
});
|
|
171
217
|
return output(run.status === "succeeded" ? `Browser automation ${id} completed.` : `Browser automation ${id} ${run.status}: ${run.error ?? "No details"}`, {
|
|
172
218
|
ok: run.status === "succeeded",
|
|
173
219
|
run
|
|
@@ -31,6 +31,7 @@ export declare const AutomationCreateCapabilityInputSchema: z.ZodObject<{
|
|
|
31
31
|
}, z.core.$strict>, z.ZodObject<{
|
|
32
32
|
kind: z.ZodLiteral<"browser_automation">;
|
|
33
33
|
automationId: z.ZodString;
|
|
34
|
+
revision: z.ZodOptional<z.ZodNumber>;
|
|
34
35
|
inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
35
36
|
timeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
36
37
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -231,6 +232,7 @@ export declare const AutomationUpdatePatchSchema: z.ZodObject<{
|
|
|
231
232
|
}, z.core.$strict>, z.ZodObject<{
|
|
232
233
|
kind: z.ZodLiteral<"browser_automation">;
|
|
233
234
|
automationId: z.ZodString;
|
|
235
|
+
revision: z.ZodOptional<z.ZodNumber>;
|
|
234
236
|
inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
235
237
|
timeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
236
238
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -48,6 +48,7 @@ export type AutomationAction = {
|
|
|
48
48
|
} | {
|
|
49
49
|
kind: 'browser_automation';
|
|
50
50
|
automationId: string;
|
|
51
|
+
revision?: number;
|
|
51
52
|
inputs?: Record<string, unknown>;
|
|
52
53
|
timeoutSeconds?: number;
|
|
53
54
|
} | {
|
|
@@ -342,8 +343,18 @@ export interface AutomationDeps {
|
|
|
342
343
|
prepareAgentSession?: (input: PrepareAutomationAgentSessionInput) => Promise<void>;
|
|
343
344
|
workflowRunService?: WorkflowRunServiceLike;
|
|
344
345
|
browserAutomationService?: {
|
|
346
|
+
get(id: string): {
|
|
347
|
+
revision: number;
|
|
348
|
+
verified: boolean;
|
|
349
|
+
} | null;
|
|
350
|
+
versions(id: string): {
|
|
351
|
+
revision: number;
|
|
352
|
+
verified: boolean;
|
|
353
|
+
}[];
|
|
345
354
|
runAndWait(automationId: string, inputs: Record<string, unknown>, signal?: AbortSignal, context?: {
|
|
346
355
|
triggerEvent?: AutomationEvent;
|
|
356
|
+
revision?: number;
|
|
357
|
+
clientRequestId?: string;
|
|
347
358
|
}): Promise<{
|
|
348
359
|
id: string;
|
|
349
360
|
status: 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled';
|
|
@@ -61,6 +61,7 @@ export declare const AutomationActionSchema: z.ZodDiscriminatedUnion<[z.ZodObjec
|
|
|
61
61
|
}, z.core.$strict>, z.ZodObject<{
|
|
62
62
|
kind: z.ZodLiteral<"browser_automation">;
|
|
63
63
|
automationId: z.ZodString;
|
|
64
|
+
revision: z.ZodOptional<z.ZodNumber>;
|
|
64
65
|
inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
65
66
|
timeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
66
67
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -281,6 +282,7 @@ export declare const AutomationSchema: z.ZodObject<{
|
|
|
281
282
|
}, z.core.$strict>, z.ZodObject<{
|
|
282
283
|
kind: z.ZodLiteral<"browser_automation">;
|
|
283
284
|
automationId: z.ZodString;
|
|
285
|
+
revision: z.ZodOptional<z.ZodNumber>;
|
|
284
286
|
inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
285
287
|
timeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
286
288
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -480,6 +482,7 @@ export declare const CreateAutomationSchema: z.ZodObject<{
|
|
|
480
482
|
}, z.core.$strict>, z.ZodObject<{
|
|
481
483
|
kind: z.ZodLiteral<"browser_automation">;
|
|
482
484
|
automationId: z.ZodString;
|
|
485
|
+
revision: z.ZodOptional<z.ZodNumber>;
|
|
483
486
|
inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
484
487
|
timeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
485
488
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -706,6 +709,7 @@ export declare const UpdateAutomationSchema: z.ZodObject<{
|
|
|
706
709
|
}, z.core.$strict>, z.ZodObject<{
|
|
707
710
|
kind: z.ZodLiteral<"browser_automation">;
|
|
708
711
|
automationId: z.ZodString;
|
|
712
|
+
revision: z.ZodOptional<z.ZodNumber>;
|
|
709
713
|
inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
710
714
|
timeoutSeconds: z.ZodOptional<z.ZodNumber>;
|
|
711
715
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -95,6 +95,7 @@ const AutomationActionSchema = z.discriminatedUnion("kind", [
|
|
|
95
95
|
z.object({
|
|
96
96
|
kind: z.literal("browser_automation"),
|
|
97
97
|
automationId: nonEmptyString.max(100),
|
|
98
|
+
revision: z.number().int().positive().optional(),
|
|
98
99
|
inputs: z.record(z.string(), z.unknown()).optional(),
|
|
99
100
|
timeoutSeconds: z.number().int().min(1).max(86400).optional()
|
|
100
101
|
}).strict(),
|
|
@@ -77,7 +77,7 @@ var AutomationActionExecutor = class {
|
|
|
77
77
|
mode: "idempotent",
|
|
78
78
|
key: "run_id"
|
|
79
79
|
}, (input, action) => this.executeWorkflow(input.automation, action, input.run, input.signal, input.hooks, input.context));
|
|
80
|
-
this.register("browser_automation", { mode: "never" }, (input, action) => this.executeBrowserAutomation(input.automation, action, input.signal, input.hooks, input.context));
|
|
80
|
+
this.register("browser_automation", { mode: "never" }, (input, action) => this.executeBrowserAutomation(input.automation, action, input.signal, input.hooks, input.context, input.run.id));
|
|
81
81
|
this.register("task_command", {
|
|
82
82
|
mode: "idempotent",
|
|
83
83
|
key: "run_id"
|
|
@@ -186,7 +186,7 @@ var AutomationActionExecutor = class {
|
|
|
186
186
|
})).summary ?? "System action completed"
|
|
187
187
|
};
|
|
188
188
|
}
|
|
189
|
-
async executeBrowserAutomation(automation, action, signal, hooks, context) {
|
|
189
|
+
async executeBrowserAutomation(automation, action, signal, hooks, context, executionRunId) {
|
|
190
190
|
await hooks.onRunPatch?.({ currentPhase: "action" });
|
|
191
191
|
const safetyMode = automation.safety?.mode ?? "auto_apply";
|
|
192
192
|
if (safetyMode !== "auto_apply") return {
|
|
@@ -198,7 +198,15 @@ var AutomationActionExecutor = class {
|
|
|
198
198
|
status: "failed",
|
|
199
199
|
error: "Browser automation is not available"
|
|
200
200
|
};
|
|
201
|
-
|
|
201
|
+
if (action.revision === void 0 || !service.versions(action.automationId).some((item) => item.revision === action.revision && item.verified)) return {
|
|
202
|
+
status: "failed",
|
|
203
|
+
error: "The scheduled browser automation version has not been verified."
|
|
204
|
+
};
|
|
205
|
+
const run = await service.runAndWait(action.automationId, action.inputs ?? {}, signal, {
|
|
206
|
+
revision: action.revision,
|
|
207
|
+
clientRequestId: `schedule:${executionRunId}:${action.revision}`,
|
|
208
|
+
...context.triggerEvent ? { triggerEvent: context.triggerEvent } : {}
|
|
209
|
+
});
|
|
202
210
|
if (run.status === "succeeded") return {
|
|
203
211
|
status: "succeeded",
|
|
204
212
|
summary: `Browser automation ${action.automationId} completed: ${JSON.stringify(run.result ?? null).slice(0, 3500)}`
|
|
@@ -31,6 +31,7 @@ export declare class AutomationService {
|
|
|
31
31
|
/** SQLite-only creation; scheduling starts after the caller commits. */
|
|
32
32
|
createAtomically(input: CreateAutomationInput): Automation;
|
|
33
33
|
private applyCreate;
|
|
34
|
+
private pinBrowserVersion;
|
|
34
35
|
list(options?: {
|
|
35
36
|
projectId?: string;
|
|
36
37
|
}): Promise<Automation[]>;
|
|
@@ -114,12 +114,23 @@ var AutomationService = class {
|
|
|
114
114
|
createdAtMs: now,
|
|
115
115
|
updatedAtMs: now
|
|
116
116
|
});
|
|
117
|
+
this.pinBrowserVersion(automation);
|
|
117
118
|
if (getAutomation(automation.id)) throw new AutomationAlreadyExistsError(automation.id);
|
|
118
119
|
automation.updatedAtMs = Math.max(automation.updatedAtMs, (getDeletedAutomationRevision(automation.id) ?? -1) + 1);
|
|
119
120
|
automation.state.nextRunAtMs = computeNextAutomationRunAtMs(automation, now);
|
|
120
121
|
saveAutomation(automation);
|
|
121
122
|
return automation;
|
|
122
123
|
}
|
|
124
|
+
pinBrowserVersion(automation) {
|
|
125
|
+
if (automation.action.kind !== "browser_automation") return;
|
|
126
|
+
const browser = this.deps.browserAutomationService;
|
|
127
|
+
if (!browser) throw new Error("Browser automation service is unavailable.");
|
|
128
|
+
const action = automation.action;
|
|
129
|
+
const version = action.revision === void 0 ? browser.get(action.automationId) : browser.versions(action.automationId).find((item) => item.revision === action.revision);
|
|
130
|
+
if (!version) throw new Error("Browser automation version not found.");
|
|
131
|
+
if (automation.enabled && !version.verified) throw new Error("Run and verify this browser automation before scheduling it.");
|
|
132
|
+
action.revision = version.revision;
|
|
133
|
+
}
|
|
123
134
|
async list(options) {
|
|
124
135
|
return listAutomations(options);
|
|
125
136
|
}
|
|
@@ -154,6 +165,7 @@ var AutomationService = class {
|
|
|
154
165
|
...parsed.state ?? {}
|
|
155
166
|
}
|
|
156
167
|
});
|
|
168
|
+
this.pinBrowserVersion(next);
|
|
157
169
|
if ("enabled" in parsed || "trigger" in parsed) next.state.nextRunAtMs = computeNextAutomationRunAtMs(next, now);
|
|
158
170
|
saveAutomation(next);
|
|
159
171
|
return next;
|
|
@@ -559,7 +571,7 @@ var AutomationService = class {
|
|
|
559
571
|
let artifacts;
|
|
560
572
|
const triggerEvent = listAutomationRunEvents(run.id).map(readAutomationEventFromRunEvent).find((item) => item !== null);
|
|
561
573
|
try {
|
|
562
|
-
const maxAttempts = Math.max(1, (automation.reliability?.retryCount ?? 0) + 1);
|
|
574
|
+
const maxAttempts = automation.action.kind === "browser_automation" ? 1 : Math.max(1, (automation.reliability?.retryCount ?? 0) + 1);
|
|
563
575
|
let task;
|
|
564
576
|
for (let attempt = 1;; attempt += 1) {
|
|
565
577
|
run = {
|
|
@@ -2,9 +2,9 @@ import { requireXopcDatabase } from "../storage/sqlite/connection.js";
|
|
|
2
2
|
import { init_sqlite } from "../storage/sqlite/index.js";
|
|
3
3
|
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
4
4
|
import { ensureStarterAgentsInitialized } from "../agent/starter-agents.js";
|
|
5
|
-
import { migrateIdentityMarkdownToCatalog } from "../agent-catalog/migrations/identity-markdown-cutover.js";
|
|
6
5
|
import { cutoverLegacyAgentConfig } from "../agent-catalog/migrations/legacy-config-cutover.js";
|
|
7
6
|
import "../agent-catalog/index.js";
|
|
7
|
+
import { migrateIdentityMarkdownToCatalog } from "../agent-catalog/migrations/identity-markdown-cutover.js";
|
|
8
8
|
import { migrateCloudPublicModelsSync } from "../migrations/cloud-public-models.js";
|
|
9
9
|
import { runBootstrapMigrationsSync } from "../migrations/runner.js";
|
|
10
10
|
//#region src/bootstrap/application-state.ts
|
|
@@ -2,6 +2,10 @@ import type { BrowserAutomation, BrowserAutomationRun, BrowserAutomationRunEvent
|
|
|
2
2
|
export declare const listBrowserAutomations: () => BrowserAutomation[];
|
|
3
3
|
export declare const getBrowserAutomation: (id: string) => BrowserAutomation | null;
|
|
4
4
|
export declare function saveBrowserAutomation(value: BrowserAutomation): void;
|
|
5
|
+
export declare function getBrowserAutomationVersion(id: string, revision: number): BrowserAutomation | null;
|
|
6
|
+
export declare function listBrowserAutomationVersions(id: string): BrowserAutomation[];
|
|
7
|
+
export declare function verifyBrowserAutomationRun(run: BrowserAutomationRun): void;
|
|
8
|
+
export declare function findBrowserAutomationRunByRequest(requestId: string): BrowserAutomationRun | null;
|
|
5
9
|
export declare const deleteBrowserAutomation: (id: string) => boolean;
|
|
6
10
|
export declare function saveBrowserAutomationRun(value: BrowserAutomationRun): void;
|
|
7
11
|
export declare const getBrowserAutomationRun: (id: string) => BrowserAutomationRun | null;
|
|
@@ -2,9 +2,10 @@ import { getSqliteDatabase, runSqliteWriteTransaction } from "../../storage/sqli
|
|
|
2
2
|
import { init_sqlite } from "../../storage/sqlite/index.js";
|
|
3
3
|
//#region src/browser/automations/repository.ts
|
|
4
4
|
init_sqlite();
|
|
5
|
-
const AUTOMATION_SELECT = "SELECT automation_id
|
|
6
|
-
const RUN_SELECT = "SELECT run_id, automation_id, automation_revision, definition_json, status, inputs_json, result_json, error, created_at_ms, started_at_ms, ended_at_ms, duration_ms FROM browser_automation_runs";
|
|
5
|
+
const AUTOMATION_SELECT = "SELECT a.*, EXISTS(SELECT 1 FROM browser_automation_verifications v WHERE v.automation_id=a.automation_id AND v.revision=a.revision) AS verified FROM browser_automations a";
|
|
6
|
+
const RUN_SELECT = "SELECT client_request_id, business_outcome, run_id, automation_id, automation_revision, definition_json, status, inputs_json, result_json, error, created_at_ms, started_at_ms, ended_at_ms, duration_ms FROM browser_automation_runs";
|
|
7
7
|
const parseAutomation = (row) => ({
|
|
8
|
+
verified: !!row.verified,
|
|
8
9
|
id: row.automation_id,
|
|
9
10
|
revision: row.revision,
|
|
10
11
|
status: row.status,
|
|
@@ -13,6 +14,8 @@ const parseAutomation = (row) => ({
|
|
|
13
14
|
updatedAtMs: row.updated_at_ms
|
|
14
15
|
});
|
|
15
16
|
const parseRun = (row) => ({
|
|
17
|
+
clientRequestId: row.client_request_id ?? void 0,
|
|
18
|
+
businessOutcome: row.business_outcome ?? void 0,
|
|
16
19
|
id: row.run_id,
|
|
17
20
|
automationId: row.automation_id,
|
|
18
21
|
automationRevision: row.automation_revision,
|
|
@@ -28,15 +31,33 @@ const parseRun = (row) => ({
|
|
|
28
31
|
});
|
|
29
32
|
const listBrowserAutomations = () => getSqliteDatabase().prepare(`${AUTOMATION_SELECT} ORDER BY updated_at_ms DESC`).all().map(parseAutomation);
|
|
30
33
|
const getBrowserAutomation = (id) => {
|
|
31
|
-
const row = getSqliteDatabase().prepare(`${AUTOMATION_SELECT} WHERE automation_id = ?`).get(id);
|
|
34
|
+
const row = getSqliteDatabase().prepare(`${AUTOMATION_SELECT} WHERE a.automation_id = ?`).get(id);
|
|
32
35
|
return row ? parseAutomation(row) : null;
|
|
33
36
|
};
|
|
34
37
|
function saveBrowserAutomation(value) {
|
|
35
|
-
runSqliteWriteTransaction((db) =>
|
|
38
|
+
runSqliteWriteTransaction((db) => {
|
|
39
|
+
db.prepare("INSERT INTO browser_automations (automation_id, revision, status, definition_json, created_at_ms, updated_at_ms) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(automation_id) DO UPDATE SET revision=excluded.revision, status=excluded.status, definition_json=excluded.definition_json, updated_at_ms=excluded.updated_at_ms").run(value.id, value.revision, value.status, JSON.stringify(value.definition), value.createdAtMs, value.updatedAtMs);
|
|
40
|
+
db.prepare("INSERT OR IGNORE INTO browser_automation_versions (automation_id, revision, definition_json, created_at_ms) VALUES (?, ?, ?, ?)").run(value.id, value.revision, JSON.stringify(value.definition), value.updatedAtMs);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function getBrowserAutomationVersion(id, revision) {
|
|
44
|
+
const row = getSqliteDatabase().prepare("SELECT v.*, a.status, a.created_at_ms, v.created_at_ms AS updated_at_ms, EXISTS(SELECT 1 FROM browser_automation_verifications p WHERE p.automation_id=v.automation_id AND p.revision=v.revision) AS verified FROM browser_automation_versions v JOIN browser_automations a USING(automation_id) WHERE v.automation_id=? AND v.revision=?").get(id, revision);
|
|
45
|
+
return row ? parseAutomation(row) : null;
|
|
46
|
+
}
|
|
47
|
+
function listBrowserAutomationVersions(id) {
|
|
48
|
+
return getSqliteDatabase().prepare("SELECT revision FROM browser_automation_versions WHERE automation_id=? ORDER BY revision DESC").all(id).map((row) => getBrowserAutomationVersion(id, row.revision));
|
|
49
|
+
}
|
|
50
|
+
function verifyBrowserAutomationRun(run) {
|
|
51
|
+
if (run.status !== "succeeded" || run.businessOutcome !== "verified") return;
|
|
52
|
+
runSqliteWriteTransaction((db) => db.prepare("INSERT INTO browser_automation_verifications (automation_id, revision, run_id, verified_at_ms) VALUES (?, ?, ?, ?) ON CONFLICT(automation_id, revision) DO UPDATE SET run_id=excluded.run_id, verified_at_ms=excluded.verified_at_ms").run(run.automationId, run.automationRevision, run.id, run.endedAtMs));
|
|
53
|
+
}
|
|
54
|
+
function findBrowserAutomationRunByRequest(requestId) {
|
|
55
|
+
const row = getSqliteDatabase().prepare(`${RUN_SELECT} WHERE client_request_id=?`).get(requestId);
|
|
56
|
+
return row ? parseRun(row) : null;
|
|
36
57
|
}
|
|
37
58
|
const deleteBrowserAutomation = (id) => runSqliteWriteTransaction((db) => db.prepare("DELETE FROM browser_automations WHERE automation_id = ?").run(id).changes > 0);
|
|
38
59
|
function saveBrowserAutomationRun(value) {
|
|
39
|
-
runSqliteWriteTransaction((db) => db.prepare("INSERT INTO browser_automation_runs (run_id, automation_id, automation_revision, definition_json, status, inputs_json, result_json, error, created_at_ms, started_at_ms, ended_at_ms, duration_ms) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(run_id) DO UPDATE SET status=excluded.status, result_json=excluded.result_json, error=excluded.error, started_at_ms=excluded.started_at_ms, ended_at_ms=excluded.ended_at_ms, duration_ms=excluded.duration_ms").run(value.id, value.automationId, value.automationRevision, JSON.stringify(value.definition), value.status, JSON.stringify(value.inputs), value.result === void 0 ? null : JSON.stringify(value.result), value.error ?? null, value.createdAtMs, value.startedAtMs ?? null, value.endedAtMs ?? null, value.durationMs ?? null));
|
|
60
|
+
runSqliteWriteTransaction((db) => db.prepare("INSERT INTO browser_automation_runs (run_id, automation_id, automation_revision, definition_json, status, inputs_json, result_json, error, created_at_ms, started_at_ms, ended_at_ms, duration_ms, client_request_id, business_outcome) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(run_id) DO UPDATE SET status=excluded.status, result_json=excluded.result_json, error=excluded.error, started_at_ms=excluded.started_at_ms, ended_at_ms=excluded.ended_at_ms, duration_ms=excluded.duration_ms, business_outcome=excluded.business_outcome").run(value.id, value.automationId, value.automationRevision, JSON.stringify(value.definition), value.status, JSON.stringify(value.inputs), value.result === void 0 ? null : JSON.stringify(value.result), value.error ?? null, value.createdAtMs, value.startedAtMs ?? null, value.endedAtMs ?? null, value.durationMs ?? null, value.clientRequestId ?? null, value.businessOutcome ?? null));
|
|
40
61
|
}
|
|
41
62
|
const getBrowserAutomationRun = (id) => {
|
|
42
63
|
const row = getSqliteDatabase().prepare(`${RUN_SELECT} WHERE run_id = ?`).get(id);
|
|
@@ -58,4 +79,4 @@ const listBrowserAutomationRunEvents = (runId) => getSqliteDatabase().prepare("S
|
|
|
58
79
|
createdAtMs: row.created_at_ms
|
|
59
80
|
}));
|
|
60
81
|
//#endregion
|
|
61
|
-
export { appendBrowserAutomationRunEvent, deleteBrowserAutomation, getBrowserAutomation, getBrowserAutomationRun, hasActiveBrowserAutomationRuns, listActiveBrowserAutomationRuns, listBrowserAutomationRunEvents, listBrowserAutomationRuns, listBrowserAutomations, nextBrowserAutomationRunEventSeq, saveBrowserAutomation, saveBrowserAutomationRun };
|
|
82
|
+
export { appendBrowserAutomationRunEvent, deleteBrowserAutomation, findBrowserAutomationRunByRequest, getBrowserAutomation, getBrowserAutomationRun, getBrowserAutomationVersion, hasActiveBrowserAutomationRuns, listActiveBrowserAutomationRuns, listBrowserAutomationRunEvents, listBrowserAutomationRuns, listBrowserAutomationVersions, listBrowserAutomations, nextBrowserAutomationRunEventSeq, saveBrowserAutomation, saveBrowserAutomationRun, verifyBrowserAutomationRun };
|