@xopcai/xopc 0.0.190 → 0.0.192
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DstnJCS5.js → activity-store-B-tzXpDD.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-9vAbkroX.js → agent-avatar-dicebear-xOu0qNwc.js} +1 -1
- package/dist/gateway/static/root/assets/agents-CxuwvDk0.js +68 -0
- package/dist/gateway/static/root/assets/{api-BTL9kayv.js → api-fMItZb-h.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DkFeIdBf.js → app-management-settings-panel-D6Rv3OWI.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-Bxs8Fpaj.js → appearance-settings-CKoNCwco.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-wAb5dnHZ.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-Ch2RmLCC.js → archive-plugin-BokNQBwH.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BhMQM_Ky.js → attachment-load-Dx1HglsM.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-Drgazevs.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-D6CqlymH.js → binary-plugins-CPYAflIG.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-ClL6HEg9.js → block-editor-BFLgl8SS.js} +47 -47
- package/dist/gateway/static/root/assets/browser-settings-page-DmYlFJW7.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-BYy48VhN.js → browser-workflow-inputs-CqLnqA9z.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-zgLibuMH.js → browser-workflows-page-Db5v3HtE.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-D7Z8T0o5.js +7 -0
- package/dist/gateway/static/root/assets/capability-presets-api-lov0J9A2.js +1 -0
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-COjnwO0U.js +3 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-BThDGiO3.js → channel-recipient-api-DSJznouK.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-DcRYBNN7.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-C2UYdebT.js +1 -0
- package/dist/gateway/static/root/assets/{code-editor-D4_k-6QN.js → code-editor-dFzqyDXS.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-api-DS9ED-EL.js → connectors-api-3ccRyS3L.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-FVmvBG9H.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-CkgsvhtW.js → cron-expression-C9hhCiuo.js} +1 -1
- package/dist/gateway/static/root/assets/dependency-picker-CTtZFZug.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-Cv8rGhYW.js → desktop-pet-DOUeNVmC.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-CIeJdwfV.js → desktop-pet-settings-D4704vtl.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-D8jXEiAY.js → directory-picker-path-field-DJDXeA1B.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CCZ9u6TZ.js → extension-debug-page-C0n2NMF1.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CV36ILRG.js → extension-page-vG-xxRNs.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-CtuY2THd.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-api-D4_r5iJM.js → gateway-config-api-CZra7GuI.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-CYlntpBH.js → gateway-settings-Cz33jRkR.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-EO9mKvzE.js → gateway-startup-retry-BbVV0udv.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-D4SyWob8.js → heartbeat-settings-D2XMlA_U.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-CPrHkPN6.js +3 -0
- package/dist/gateway/static/root/assets/html-workspace-editor-bXK5tq64.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-Bu7PyVSh.js → image-generation-api-BgrOvhaJ.js} +1 -1
- package/dist/gateway/static/root/assets/index-Cg7Xnlu3.css +1 -0
- package/dist/gateway/static/root/assets/index-DzmbmOGA.js +150 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BMhCuVBZ.js → keyboard-shortcuts-settings-BfyAEG1G.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-Clz47vSr.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-ijIe7_y2.js → local-apps-page-BYalcRSY.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-deR2zRaE.js → locale-store-VOY1wMO9.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-Cxq9WMf5.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings--V_fovKD.js → management-settings-BQf-6s32.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-editor-BvUebh3C.js → markdown-editor-TWGaF7Xa.js} +2 -2
- package/dist/gateway/static/root/assets/{markdown-split-Dt9-in6W.js → markdown-split-Cy_2SN1Q.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-B3pj_iO0.js → media-plugins-CkDupqb2.js} +1 -1
- package/dist/gateway/static/root/assets/messages-DMJ-6-1m.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-DZ366lIT.js → notes-page-kiGRR9jo.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-DkYkPGyB.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-C5ge434C.js → page-tabs-CvzSdYVj.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BFa9DgSV.js → preview-open-alternatives-kZ0nco7e.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-Dc9CcWdu.js → product-open-page-DgoieqQC.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-CeSjJd-N.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-fZ1rm4b9.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CbYI6KC8.js +1 -0
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-Bud_NTEZ.js +5 -0
- package/dist/gateway/static/root/assets/{schema-form-B84DckWe.js → schema-form-GlbsCBmv.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-sOJ_TnLm.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BI0u77dt.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-Dp9itvdy.js → settings-form-section-CKLns16d.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-CCtlhoy7.js → settings-loading-skeleton-BDzpxgk0.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-BH0pF7QB.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-EQIOJa_L.js → settings-page-layout-J793iqfm.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-Cwi-SPja.js → setup-status-panel-CGsml89P.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-C4_B2jvf.js → share-preview-page-UTm_7r0l.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-BM--lgUS.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CGCOC-rV.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-iLyaOl48.js +2 -0
- package/dist/gateway/static/root/assets/skills-page.utils-Bwid1TGB.js +1 -0
- package/dist/gateway/static/root/assets/style-TIDOdKy0.js +7 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-Dpx2ags2.js → system-settings-panel-BcB3p1e3.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-DQYEf08v.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-DnBOcGXi.js → theme-store-GVZOImyb.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-DULmTHUB.js → typed-models-lib-CT2c85Ju.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-BrjVk5VH.js → use-autosave-CcvY7DTh.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-CGI41bfO.js +1 -0
- package/dist/gateway/static/root/assets/{vendor-codemirror--gTq3YAI.js → vendor-codemirror-DRr7hFaD.js} +16 -16
- package/dist/gateway/static/root/assets/voice-api-key-field-Ricc3QGo.js +1 -0
- package/dist/gateway/static/root/assets/{work-discovery-overlay-Wr-uF7VA.js → work-discovery-overlay-BoomfqhX.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-page-BWds95sL.js → work-discovery-page-mbnepbQk.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-DSWG2xqL.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-DtV0ruyk.js +5 -0
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +2 -0
- package/dist/src/agent/agent-manager.js +76 -0
- package/dist/src/agent/background-review/prompts.d.ts +1 -1
- package/dist/src/agent/background-review/prompts.js +1 -1
- package/dist/src/agent/background-review/run-background-review.js +3 -12
- package/dist/src/agent/embedded/run-for-session.js +3 -0
- package/dist/src/agent/embedded/run-turn.js +4 -1
- package/dist/src/agent/embedded/session-runner.js +3 -4
- package/dist/src/agent/embedded/types.d.ts +10 -1
- package/dist/src/agent/embedded/xopc-stream-bridge.js +3 -2
- package/dist/src/agent/external-tools/mcp-provider.d.ts +1 -0
- package/dist/src/agent/external-tools/mcp-provider.js +21 -6
- package/dist/src/agent/image/generation/openai-images-provider.d.ts +1 -1
- package/dist/src/agent/image/generation/openai-images-provider.js +1 -1
- package/dist/src/agent/image/generation/provider-registry.d.ts +2 -0
- package/dist/src/agent/image/generation/provider-registry.js +21 -10
- package/dist/src/agent/image/generation/providers/dashscope.js +20 -0
- package/dist/src/agent/image/generation/providers/fal.d.ts +1 -1
- package/dist/src/agent/image/generation/providers/fal.js +12 -6
- package/dist/src/agent/image/generation/providers/google.js +8 -0
- package/dist/src/agent/image/generation/providers/minimax.js +20 -0
- package/dist/src/agent/image/generation/providers/openai.js +36 -26
- package/dist/src/agent/image/generation/providers/xopc-cloud.d.ts +2 -0
- package/dist/src/agent/image/generation/providers/xopc-cloud.js +74 -0
- package/dist/src/agent/image/generation/types.d.ts +15 -2
- package/dist/src/agent/mcp/bundle-mcp-gateway.d.ts +1 -0
- package/dist/src/agent/mcp/bundle-mcp-gateway.js +2 -1
- package/dist/src/agent/mcp/bundle-mcp-policy.d.ts +5 -1
- package/dist/src/agent/mcp/bundle-mcp-policy.js +11 -3
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +3 -2
- package/dist/src/agent/mcp/bundle-mcp-types.d.ts +2 -1
- package/dist/src/agent/mcp/index.js +2 -2
- package/dist/src/agent/mcp/mcp-stdio-transport.js +1 -1
- package/dist/src/agent/mcp/mcp-transport.d.ts +2 -1
- package/dist/src/agent/mcp/mcp-transport.js +22 -4
- package/dist/src/agent/memory/compaction.js +19 -17
- package/dist/src/agent/memory/context-budget.js +2 -3
- package/dist/src/agent/memory/understanding/service.d.ts +1 -0
- package/dist/src/agent/memory/understanding/service.js +49 -20
- package/dist/src/agent/memory/understanding/types.d.ts +1 -0
- package/dist/src/agent/memory/user-context-coordinator.js +6 -0
- package/dist/src/agent/orchestration/agent-orchestrator.js +15 -1
- package/dist/src/agent/service/direct-turn-helpers.js +14 -5
- package/dist/src/agent/skills/index.d.ts +1 -1
- package/dist/src/agent/skills/index.js +2 -2
- package/dist/src/agent/skills/installer.d.ts +3 -10
- package/dist/src/agent/skills/installer.js +99 -156
- package/dist/src/agent/skills/marketplace/adapter.types.d.ts +3 -1
- package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +30 -6
- package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +21 -4
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +7 -4
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +3 -0
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +7 -1
- package/dist/src/agent/skills/marketplace/search.d.ts +2 -2
- package/dist/src/agent/skills/marketplace/search.js +52 -21
- package/dist/src/agent/skills/skills-marketplace.d.ts +1 -1
- package/dist/src/agent/skills/skills-marketplace.js +2 -2
- package/dist/src/agent/skills/types.d.ts +0 -8
- package/dist/src/agent/tools/exec-command.d.ts +1 -0
- package/dist/src/agent/tools/exec-command.js +2 -1
- package/dist/src/agent/tools/factory.d.ts +1 -0
- package/dist/src/agent/tools/factory.js +17 -2
- package/dist/src/agent/tools/managed-job-tool.d.ts +1 -1
- package/dist/src/agent/tools/managed-job-tool.js +3 -2
- package/dist/src/agent/tools/skill-install-tool.d.ts +2 -2
- package/dist/src/agent/tools/skill-install-tool.js +8 -4
- package/dist/src/agent/tools/skills-marketplace-search-tool.js +3 -2
- package/dist/src/agent/tools/workflow-tool.d.ts +1 -0
- package/dist/src/agent/tools/workflow-tool.js +14 -4
- package/dist/src/agent-manifest/schema.d.ts +20 -0
- package/dist/src/agent-manifest/schema.js +6 -1
- package/dist/src/browser/providers/cloakbrowser.js +1 -1
- package/dist/src/cli/command-loaders.js +1 -0
- package/dist/src/cli/command-manifest.js +4 -0
- package/dist/src/cli/commands/doctor/checks/node-version.js +3 -3
- package/dist/src/cli/commands/doctor/checks/tool-runtimes.d.ts +2 -0
- package/dist/src/cli/commands/doctor/checks/tool-runtimes.js +36 -0
- package/dist/src/cli/commands/doctor/flow.js +2 -0
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/models.js +0 -1
- package/dist/src/cli/commands/onboard/model.d.ts +18 -0
- package/dist/src/cli/commands/onboard/model.js +81 -5
- package/dist/src/cli/commands/onboard.js +13 -1
- package/dist/src/cli/commands/runtime.d.ts +1 -0
- package/dist/src/cli/commands/runtime.js +77 -0
- package/dist/src/cli/commands/setup.js +15 -1
- package/dist/src/cli/commands/skills.js +7 -4
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/schema.d.ts +125 -0
- package/dist/src/config/schema.js +77 -2
- package/dist/src/config/voice.d.ts +6 -0
- package/dist/src/config/voice.js +17 -0
- package/dist/src/extensions/install.js +1 -1
- package/dist/src/extensions/types/providers.d.ts +4 -0
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/capability-presets-admin.d.ts +9 -0
- package/dist/src/gateway/capability-presets-admin.js +24 -6
- package/dist/src/gateway/chat-stream/mapper.js +8 -4
- package/dist/src/gateway/chat-stream/protocol.d.ts +10 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
- package/dist/src/gateway/hono/routes/commands-skills.js +2 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/models.js +11 -11
- package/dist/src/gateway/hono/routes/runtime-tools.d.ts +3 -0
- package/dist/src/gateway/hono/routes/runtime-tools.js +142 -0
- package/dist/src/gateway/hono/routes/understanding-sources.js +2 -1
- package/dist/src/gateway/hono/routes/voice.js +43 -2
- package/dist/src/gateway/hono/routes/workflows.js +1 -1
- package/dist/src/gateway/hono/routes/you.js +22 -25
- package/dist/src/gateway/image-generation-setup.d.ts +2 -3
- package/dist/src/gateway/image-generation-setup.js +39 -8
- package/dist/src/gateway/service/marketplace-service.d.ts +1 -1
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/providers/extension-stream-bridge.js +8 -7
- package/dist/src/providers/model-catalog-store.d.ts +35 -0
- package/dist/src/providers/model-catalog-store.js +25 -1
- package/dist/src/providers/model-catalog-sync-service.js +6 -0
- package/dist/src/providers/model-registry.js +4 -4
- package/dist/src/providers/prompt-cache-payload.d.ts +13 -0
- package/dist/src/providers/prompt-cache-payload.js +110 -0
- package/dist/src/providers/register-runtime-providers.js +4 -4
- package/dist/src/providers/xopc-cloud-model-source.js +101 -8
- package/dist/src/runtime-tools/archive.d.ts +8 -0
- package/dist/src/runtime-tools/archive.js +99 -0
- package/dist/src/runtime-tools/bootstrap.d.ts +16 -0
- package/dist/src/runtime-tools/bootstrap.js +33 -0
- package/dist/src/runtime-tools/catalog.d.ts +19 -0
- package/dist/src/runtime-tools/catalog.js +59 -0
- package/dist/src/runtime-tools/command.d.ts +15 -0
- package/dist/src/runtime-tools/command.js +59 -0
- package/dist/src/runtime-tools/download-source.d.ts +24 -0
- package/dist/src/runtime-tools/download-source.js +125 -0
- package/dist/src/runtime-tools/downloader.d.ts +21 -0
- package/dist/src/runtime-tools/downloader.js +137 -0
- package/dist/src/runtime-tools/environment.d.ts +20 -0
- package/dist/src/runtime-tools/environment.js +113 -0
- package/dist/src/runtime-tools/errors.d.ts +10 -0
- package/dist/src/runtime-tools/errors.js +14 -0
- package/dist/src/runtime-tools/index.d.ts +7 -0
- package/dist/src/runtime-tools/index.js +7 -0
- package/dist/src/runtime-tools/install-lock.d.ts +1 -0
- package/dist/src/runtime-tools/install-lock.js +50 -0
- package/dist/src/runtime-tools/manager.d.ts +20 -0
- package/dist/src/runtime-tools/manager.js +641 -0
- package/dist/src/runtime-tools/manifest-store.d.ts +3 -0
- package/dist/src/runtime-tools/manifest-store.js +26 -0
- package/dist/src/runtime-tools/network.d.ts +9 -0
- package/dist/src/runtime-tools/network.js +41 -0
- package/dist/src/runtime-tools/offline-bundle.d.ts +16 -0
- package/dist/src/runtime-tools/offline-bundle.js +41 -0
- package/dist/src/runtime-tools/paths.d.ts +7 -0
- package/dist/src/runtime-tools/paths.js +22 -0
- package/dist/src/runtime-tools/probe.d.ts +7 -0
- package/dist/src/runtime-tools/probe.js +71 -0
- package/dist/src/runtime-tools/prune.d.ts +10 -0
- package/dist/src/runtime-tools/prune.js +93 -0
- package/dist/src/runtime-tools/types.d.ts +70 -0
- package/dist/src/runtime-tools/types.js +1 -0
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/storage/sqlite/migrations/113_memory_evidence_single_source.sql +42 -20
- package/dist/src/tasks/home-query-service.js +1 -5
- package/dist/src/tasks/index.js +2 -2
- package/dist/src/tasks/project-operating-view-service.d.ts +2 -1
- package/dist/src/tasks/project-operating-view-service.js +6 -4
- package/dist/src/tasks/task-dependency-service.d.ts +2 -1
- package/dist/src/tasks/task-dependency-service.js +15 -0
- package/dist/src/tunnel/frpc-binary.js +1 -1
- package/dist/src/user-context/domain.d.ts +2 -1
- package/dist/src/user-context/domain.js +12 -1
- package/dist/src/user-context/manual-understanding.js +8 -10
- package/dist/src/user-context/planner.js +1 -6
- package/dist/src/user-context/sources/activity-clustering.d.ts +5 -0
- package/dist/src/user-context/sources/activity-clustering.js +130 -0
- package/dist/src/user-context/sources/catalog.js +26 -0
- package/dist/src/user-context/sources/local-source-contract.d.ts +3 -0
- package/dist/src/user-context/sources/local-source-contract.js +15 -0
- package/dist/src/user-context/sources/repository.js +7 -1
- package/dist/src/user-context/sources/types.d.ts +7 -1
- package/dist/src/user-context/understanding.d.ts +15 -0
- package/dist/src/user-context/understanding.js +24 -0
- package/dist/src/voice/local/model-files.js +1 -1
- package/dist/src/voice/metadata/builtin.js +99 -32
- package/dist/src/voice/metadata/types.d.ts +3 -0
- package/dist/src/voice/stt/availability.js +4 -1
- package/dist/src/voice/stt/config-slice.d.ts +0 -2
- package/dist/src/voice/stt/config-slice.js +1 -6
- package/dist/src/voice/stt/factory.js +2 -2
- package/dist/src/voice/stt/index.d.ts +2 -3
- package/dist/src/voice/stt/list-providers.js +1 -1
- package/dist/src/voice/stt/providers/alibaba-transcription.d.ts +0 -19
- package/dist/src/voice/stt/providers/alibaba-transcription.js +59 -132
- package/dist/src/voice/stt/providers/index.d.ts +1 -0
- package/dist/src/voice/stt/providers/index.js +2 -1
- package/dist/src/voice/stt/providers/openai-transcription.d.ts +2 -2
- package/dist/src/voice/stt/providers/openai-transcription.js +4 -4
- package/dist/src/voice/stt/providers/xopc-cloud-transcription.d.ts +2 -0
- package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +49 -0
- package/dist/src/voice/stt/types.js +2 -2
- package/dist/src/voice/tts/providers/index.d.ts +1 -0
- package/dist/src/voice/tts/providers/index.js +2 -1
- package/dist/src/voice/tts/providers/xopc-cloud-speech.d.ts +2 -0
- package/dist/src/voice/tts/providers/xopc-cloud-speech.js +113 -0
- package/dist/src/voice/tts/types.d.ts +1 -1
- package/dist/src/work-discovery/analyzer.js +9 -4
- package/dist/src/work-discovery/candidate-discovery.d.ts +1 -0
- package/dist/src/work-discovery/candidate-discovery.js +3 -3
- package/dist/src/work-discovery/index.js +2 -2
- package/dist/src/work-discovery/service.d.ts +2 -1
- package/dist/src/work-discovery/service.js +126 -37
- package/dist/src/work-discovery/types.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +8 -0
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agents-D1t4SfMQ.js +0 -68
- package/dist/gateway/static/root/assets/apps-page-Cgrgu5OW.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-CtJxstKh.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-DW99iDmD.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CHUrT9EB.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-api-BB8t4Ja7.js +0 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Cycrv0YV.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-V96gPUAU.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-Cz7SAAkm.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BhlyQoQI.js +0 -2
- package/dist/gateway/static/root/assets/extension-settings-page-IyQrSILY.js +0 -1
- package/dist/gateway/static/root/assets/home-page-B2Kagoh8.js +0 -3
- package/dist/gateway/static/root/assets/html-workspace-editor-C3DKAkMc.js +0 -1
- package/dist/gateway/static/root/assets/index-CYT5DOzr.js +0 -150
- package/dist/gateway/static/root/assets/index-D6e3tPL-.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-BHYbFjqy.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-IIn8Tess.js +0 -2
- package/dist/gateway/static/root/assets/messages-B4XqB8I6.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-S2sBVOLw.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-BilzoCJ7.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BoQUyacP.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DUyUaCRF.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-Dzxlq1F0.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-TzwlZxU6.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-DQmMKf8r.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CkyuGlZK.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BJCePQK5.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-BYWLfmJi.js +0 -2
- package/dist/gateway/static/root/assets/skills-page.utils-Jhm24i4h.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-DLAdxI6e.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-9AAFpGAL.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-BISTPfq_.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-DHqHP8_6.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-0b4_DFHr.js +0 -11
- /package/dist/gateway/static/root/assets/{workflows-page-DLioOiRN.css → style-DLioOiRN.css} +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
//#region src/runtime-tools/catalog.ts
|
|
2
|
+
const RUNTIME_CATALOG_VERSION = "2026-08-23";
|
|
3
|
+
const DEFAULT_RUNTIME_VERSIONS = {
|
|
4
|
+
node: "22.23.2",
|
|
5
|
+
uv: "0.8.12",
|
|
6
|
+
python: "3.12.11"
|
|
7
|
+
};
|
|
8
|
+
function detectRuntimePlatform(platform = process.platform, arch = process.arch) {
|
|
9
|
+
if (platform === "darwin" && arch === "arm64") return "darwin-arm64";
|
|
10
|
+
if (platform === "darwin" && arch === "x64") return "darwin-x64";
|
|
11
|
+
if (platform === "win32" && arch === "x64") return "win32-x64";
|
|
12
|
+
if (platform === "linux" && arch === "x64") return "linux-x64-gnu";
|
|
13
|
+
if (platform === "linux" && arch === "arm64") return "linux-arm64-gnu";
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
function nodePlatformSuffix(platform) {
|
|
17
|
+
return {
|
|
18
|
+
"darwin-arm64": "darwin-arm64",
|
|
19
|
+
"darwin-x64": "darwin-x64",
|
|
20
|
+
"win32-x64": "win-x64",
|
|
21
|
+
"linux-x64-gnu": "linux-x64",
|
|
22
|
+
"linux-arm64-gnu": "linux-arm64"
|
|
23
|
+
}[platform];
|
|
24
|
+
}
|
|
25
|
+
function uvPlatformSuffix(platform) {
|
|
26
|
+
return {
|
|
27
|
+
"darwin-arm64": "aarch64-apple-darwin",
|
|
28
|
+
"darwin-x64": "x86_64-apple-darwin",
|
|
29
|
+
"win32-x64": "x86_64-pc-windows-msvc",
|
|
30
|
+
"linux-x64-gnu": "x86_64-unknown-linux-gnu",
|
|
31
|
+
"linux-arm64-gnu": "aarch64-unknown-linux-gnu"
|
|
32
|
+
}[platform];
|
|
33
|
+
}
|
|
34
|
+
function resolveRuntimeAsset(params) {
|
|
35
|
+
if (params.runtime === "node") {
|
|
36
|
+
const ext = params.platform === "win32-x64" ? "zip" : "tar.gz";
|
|
37
|
+
const archiveFile = `node-v${params.version}-${nodePlatformSuffix(params.platform)}.${ext}`;
|
|
38
|
+
const releaseBase = `https://nodejs.org/download/release/v${params.version}`;
|
|
39
|
+
return {
|
|
40
|
+
...params,
|
|
41
|
+
archiveFile,
|
|
42
|
+
url: `${releaseBase}/${archiveFile}`,
|
|
43
|
+
checksumUrl: `${releaseBase}/SHASUMS256.txt`,
|
|
44
|
+
archiveType: ext
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const ext = params.platform === "win32-x64" ? "zip" : "tar.gz";
|
|
48
|
+
const archiveFile = `uv-${uvPlatformSuffix(params.platform)}.${ext}`;
|
|
49
|
+
const base = `https://github.com/astral-sh/uv/releases/download/${params.version}`;
|
|
50
|
+
return {
|
|
51
|
+
...params,
|
|
52
|
+
archiveFile,
|
|
53
|
+
url: `${base}/${archiveFile}`,
|
|
54
|
+
checksumUrl: `${base}/${archiveFile}.sha256`,
|
|
55
|
+
archiveType: ext
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { DEFAULT_RUNTIME_VERSIONS, RUNTIME_CATALOG_VERSION, detectRuntimePlatform, resolveRuntimeAsset };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface RuntimeCommandResult {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
stdout: string;
|
|
4
|
+
stderr: string;
|
|
5
|
+
exitCode: number | null;
|
|
6
|
+
timedOut: boolean;
|
|
7
|
+
aborted: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function runRuntimeCommand(params: {
|
|
10
|
+
command: string;
|
|
11
|
+
args: string[];
|
|
12
|
+
env?: NodeJS.ProcessEnv;
|
|
13
|
+
timeoutMs?: number;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
}): Promise<RuntimeCommandResult>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
//#region src/runtime-tools/command.ts
|
|
3
|
+
const DEFAULT_COMMAND_TIMEOUT_MS = 5e3;
|
|
4
|
+
async function runRuntimeCommand(params) {
|
|
5
|
+
return await new Promise((resolve) => {
|
|
6
|
+
let stdout = "";
|
|
7
|
+
let stderr = "";
|
|
8
|
+
let settled = false;
|
|
9
|
+
let timedOut = false;
|
|
10
|
+
let aborted = false;
|
|
11
|
+
const child = spawn(params.command, params.args, {
|
|
12
|
+
env: params.env,
|
|
13
|
+
shell: false,
|
|
14
|
+
windowsHide: process.platform === "win32",
|
|
15
|
+
stdio: [
|
|
16
|
+
"ignore",
|
|
17
|
+
"pipe",
|
|
18
|
+
"pipe"
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
const finish = (exitCode) => {
|
|
22
|
+
if (settled) return;
|
|
23
|
+
settled = true;
|
|
24
|
+
clearTimeout(timeout);
|
|
25
|
+
params.signal?.removeEventListener("abort", abort);
|
|
26
|
+
resolve({
|
|
27
|
+
ok: exitCode === 0 && !timedOut && !aborted,
|
|
28
|
+
stdout: stdout.trim(),
|
|
29
|
+
stderr: stderr.trim(),
|
|
30
|
+
exitCode,
|
|
31
|
+
timedOut,
|
|
32
|
+
aborted
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
const abort = () => {
|
|
36
|
+
aborted = true;
|
|
37
|
+
child.kill("SIGKILL");
|
|
38
|
+
finish(null);
|
|
39
|
+
};
|
|
40
|
+
child.stdout?.on("data", (chunk) => {
|
|
41
|
+
stdout += chunk.toString();
|
|
42
|
+
});
|
|
43
|
+
child.stderr?.on("data", (chunk) => {
|
|
44
|
+
stderr += chunk.toString();
|
|
45
|
+
});
|
|
46
|
+
child.once("error", () => finish(null));
|
|
47
|
+
child.once("close", finish);
|
|
48
|
+
const timeout = setTimeout(() => {
|
|
49
|
+
timedOut = true;
|
|
50
|
+
child.kill("SIGKILL");
|
|
51
|
+
finish(null);
|
|
52
|
+
}, params.timeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS);
|
|
53
|
+
timeout.unref();
|
|
54
|
+
if (params.signal?.aborted) abort();
|
|
55
|
+
else params.signal?.addEventListener("abort", abort, { once: true });
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { runRuntimeCommand };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { RuntimeToolsConfig } from '../config/schema.js';
|
|
2
|
+
import type { RuntimeAsset, RuntimePlatform } from './catalog.js';
|
|
3
|
+
type DownloadConfig = RuntimeToolsConfig['download'];
|
|
4
|
+
export interface ResolvedRuntimeDownload {
|
|
5
|
+
url: string;
|
|
6
|
+
sha256: string;
|
|
7
|
+
source: 'website' | 'direct';
|
|
8
|
+
}
|
|
9
|
+
export declare function runtimeGatewayPythonMirror(gatewayBaseUrl: string): string;
|
|
10
|
+
export declare function canFallbackPythonInstall(output: string, timedOut: boolean): boolean;
|
|
11
|
+
export declare function validateGatewayDescriptor(params: {
|
|
12
|
+
value: unknown;
|
|
13
|
+
gatewayBaseUrl: string;
|
|
14
|
+
asset: RuntimeAsset;
|
|
15
|
+
platform: RuntimePlatform;
|
|
16
|
+
}): ResolvedRuntimeDownload;
|
|
17
|
+
export declare function resolveRuntimeDownloadSource(params: {
|
|
18
|
+
asset: RuntimeAsset;
|
|
19
|
+
platform: RuntimePlatform;
|
|
20
|
+
config: DownloadConfig;
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
onFallback?: (message: string) => void;
|
|
23
|
+
}): Promise<ResolvedRuntimeDownload>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { RuntimeError } from "./errors.js";
|
|
2
|
+
import { fetchRuntimeResource, readRuntimeResponseText } from "./network.js";
|
|
3
|
+
import { resolveExpectedChecksum } from "./downloader.js";
|
|
4
|
+
//#region src/runtime-tools/download-source.ts
|
|
5
|
+
const MAX_GATEWAY_RESPONSE_BYTES = 64 * 1024;
|
|
6
|
+
function runtimeGatewayPythonMirror(gatewayBaseUrl) {
|
|
7
|
+
return `${gatewayBaseUrl.replace(/\/+$/, "")}/python-build-standalone`;
|
|
8
|
+
}
|
|
9
|
+
function canFallbackPythonInstall(output, timedOut) {
|
|
10
|
+
if (/checksum|digest|hash mismatch|integrity|verification failed|invalid archive/i.test(output)) return false;
|
|
11
|
+
return timedOut || /failed to download|request failed|error sending request|timed? out|connection|dns|429|50[234]/i.test(output);
|
|
12
|
+
}
|
|
13
|
+
var GatewayResolveError = class extends Error {
|
|
14
|
+
constructor(message, allowsDirectFallback, retrySameSource = allowsDirectFallback) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.allowsDirectFallback = allowsDirectFallback;
|
|
17
|
+
this.retrySameSource = retrySameSource;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
function descriptorUrl(baseUrl, asset, platform) {
|
|
21
|
+
const url = new URL(`${baseUrl.replace(/\/+$/, "")}/resolve`);
|
|
22
|
+
url.searchParams.set("runtime", asset.runtime);
|
|
23
|
+
url.searchParams.set("version", asset.version);
|
|
24
|
+
url.searchParams.set("platform", platform);
|
|
25
|
+
return url;
|
|
26
|
+
}
|
|
27
|
+
function validateGatewayDescriptor(params) {
|
|
28
|
+
const value = params.value;
|
|
29
|
+
const archive = value?.archive;
|
|
30
|
+
if (value?.schemaVersion !== 1 || value.runtime !== params.asset.runtime || value.version !== params.asset.version || value.platform !== params.platform || archive?.name !== params.asset.archiveFile || archive.archiveType !== params.asset.archiveType || typeof archive.url !== "string" || typeof archive.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(archive.sha256)) throw new GatewayResolveError("Runtime gateway returned an invalid descriptor", false);
|
|
31
|
+
const base = new URL(`${params.gatewayBaseUrl.replace(/\/+$/, "")}/`);
|
|
32
|
+
const artifact = new URL(archive.url);
|
|
33
|
+
const expectedPath = `${base.pathname}artifacts/${params.asset.runtime}/${params.asset.version}/${params.platform}/${params.asset.archiveFile}`;
|
|
34
|
+
if (artifact.origin !== base.origin || artifact.username || artifact.password || artifact.pathname !== expectedPath || artifact.search || artifact.hash) throw new GatewayResolveError("Runtime gateway returned an untrusted artifact URL", false);
|
|
35
|
+
return {
|
|
36
|
+
url: artifact.href,
|
|
37
|
+
sha256: archive.sha256,
|
|
38
|
+
source: "website"
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async function resolveFromGateway(params) {
|
|
42
|
+
let lastError;
|
|
43
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
44
|
+
if (params.signal?.aborted) throw params.signal.reason;
|
|
45
|
+
try {
|
|
46
|
+
const response = await fetchRuntimeResource({
|
|
47
|
+
url: descriptorUrl(params.config.gatewayBaseUrl, params.asset, params.platform).href,
|
|
48
|
+
timeoutMs: params.config.timeoutMs,
|
|
49
|
+
proxy: params.config.proxy,
|
|
50
|
+
signal: params.signal,
|
|
51
|
+
init: {
|
|
52
|
+
headers: { "User-Agent": "xopc-runtime-manager/1" },
|
|
53
|
+
redirect: "error"
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const declaredSize = Number(response.headers.get("content-length"));
|
|
57
|
+
if (Number.isFinite(declaredSize) && declaredSize > MAX_GATEWAY_RESPONSE_BYTES) {
|
|
58
|
+
await response.body?.cancel().catch(() => {});
|
|
59
|
+
throw new GatewayResolveError("Runtime gateway response exceeds the size limit", false);
|
|
60
|
+
}
|
|
61
|
+
let responseText;
|
|
62
|
+
try {
|
|
63
|
+
responseText = await readRuntimeResponseText(response, MAX_GATEWAY_RESPONSE_BYTES);
|
|
64
|
+
} catch {
|
|
65
|
+
throw new GatewayResolveError("Runtime gateway response exceeds the size limit", false);
|
|
66
|
+
}
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
let body = null;
|
|
69
|
+
try {
|
|
70
|
+
body = JSON.parse(responseText);
|
|
71
|
+
} catch {}
|
|
72
|
+
const unsupported = response.status === 404 && body?.error === "unsupported_catalog_entry";
|
|
73
|
+
const retryable = unsupported || response.status === 429 || response.status >= 500;
|
|
74
|
+
throw new GatewayResolveError(`Runtime gateway returned HTTP ${response.status}`, retryable, !unsupported && retryable);
|
|
75
|
+
}
|
|
76
|
+
let descriptor;
|
|
77
|
+
try {
|
|
78
|
+
descriptor = JSON.parse(responseText);
|
|
79
|
+
} catch {
|
|
80
|
+
throw new GatewayResolveError("Runtime gateway returned invalid JSON", false);
|
|
81
|
+
}
|
|
82
|
+
return validateGatewayDescriptor({
|
|
83
|
+
value: descriptor,
|
|
84
|
+
gatewayBaseUrl: params.config.gatewayBaseUrl,
|
|
85
|
+
asset: params.asset,
|
|
86
|
+
platform: params.platform
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (params.signal?.aborted) throw error;
|
|
90
|
+
const normalized = error instanceof GatewayResolveError ? error : new GatewayResolveError(error instanceof Error ? error.message : String(error), true);
|
|
91
|
+
if (!normalized.allowsDirectFallback) throw normalized;
|
|
92
|
+
lastError = normalized;
|
|
93
|
+
if (!normalized.retrySameSource) break;
|
|
94
|
+
if (attempt === 0) await new Promise((resolve) => setTimeout(resolve, 500));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
throw lastError ?? new GatewayResolveError("Runtime gateway is unavailable", true);
|
|
98
|
+
}
|
|
99
|
+
async function resolveDirect(asset, config, signal) {
|
|
100
|
+
const sha256 = await resolveExpectedChecksum({
|
|
101
|
+
runtime: asset.runtime,
|
|
102
|
+
checksumUrl: asset.checksumUrl,
|
|
103
|
+
archiveFile: asset.archiveFile,
|
|
104
|
+
timeoutMs: config.timeoutMs,
|
|
105
|
+
proxy: config.proxy,
|
|
106
|
+
signal
|
|
107
|
+
});
|
|
108
|
+
return {
|
|
109
|
+
url: asset.url,
|
|
110
|
+
sha256,
|
|
111
|
+
source: "direct"
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
async function resolveRuntimeDownloadSource(params) {
|
|
115
|
+
if (params.config.source === "direct-only") return await resolveDirect(params.asset, params.config, params.signal);
|
|
116
|
+
try {
|
|
117
|
+
return await resolveFromGateway(params);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (params.config.source === "website-only" || !(error instanceof GatewayResolveError) || !error.allowsDirectFallback) throw new RuntimeError(`Failed to resolve ${params.asset.runtime} from the runtime gateway: ${error instanceof Error ? error.message : String(error)}`, "RUNTIME_DOWNLOAD_FAILED", params.asset.runtime, "resolve_gateway", true, [], { cause: error });
|
|
120
|
+
params.onFallback?.(`Runtime gateway unavailable; downloading ${params.asset.runtime} directly`);
|
|
121
|
+
return await resolveDirect(params.asset, params.config, params.signal);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//#endregion
|
|
125
|
+
export { canFallbackPythonInstall, resolveRuntimeDownloadSource, runtimeGatewayPythonMirror, validateGatewayDescriptor };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { RuntimeKind } from './types.js';
|
|
2
|
+
export declare function canFallbackRuntimeDownload(error: unknown): boolean;
|
|
3
|
+
export declare function resolveExpectedChecksum(params: {
|
|
4
|
+
runtime: 'node' | 'uv';
|
|
5
|
+
checksumUrl: string;
|
|
6
|
+
archiveFile: string;
|
|
7
|
+
timeoutMs: number;
|
|
8
|
+
proxy?: string;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
}): Promise<string>;
|
|
11
|
+
export declare function sha256File(path: string): Promise<string>;
|
|
12
|
+
export declare function downloadVerifiedArchive(params: {
|
|
13
|
+
runtime: RuntimeKind;
|
|
14
|
+
url: string;
|
|
15
|
+
targetPath: string;
|
|
16
|
+
expectedSha256: string;
|
|
17
|
+
timeoutMs: number;
|
|
18
|
+
proxy?: string;
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
onProgress?: (downloadedBytes: number, totalBytes?: number) => void;
|
|
21
|
+
}): Promise<string>;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { RuntimeError } from "./errors.js";
|
|
2
|
+
import { fetchRuntimeResource, readRuntimeResponseText } from "./network.js";
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
import { createReadStream, createWriteStream } from "node:fs";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
import { access, mkdir, rename, rm, stat } from "node:fs/promises";
|
|
7
|
+
import { pipeline } from "node:stream/promises";
|
|
8
|
+
//#region src/runtime-tools/downloader.ts
|
|
9
|
+
const MAX_ARCHIVE_BYTES = 500 * 1024 * 1024;
|
|
10
|
+
const MAX_CHECKSUM_BYTES = 1024 * 1024;
|
|
11
|
+
var RuntimeDownloadTransportError = class extends Error {
|
|
12
|
+
constructor(message, allowsSourceFallback, options) {
|
|
13
|
+
super(message, options);
|
|
14
|
+
this.allowsSourceFallback = allowsSourceFallback;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var RuntimeDownloadContentError = class extends Error {};
|
|
18
|
+
function canFallbackRuntimeDownload(error) {
|
|
19
|
+
return error instanceof RuntimeError && error.code === "RUNTIME_DOWNLOAD_FAILED" && error.cause instanceof RuntimeDownloadTransportError && error.cause.allowsSourceFallback;
|
|
20
|
+
}
|
|
21
|
+
async function fetchText(url, timeoutMs, proxy, signal) {
|
|
22
|
+
const response = await fetchRuntimeResource({
|
|
23
|
+
url,
|
|
24
|
+
timeoutMs,
|
|
25
|
+
proxy,
|
|
26
|
+
signal,
|
|
27
|
+
init: { redirect: "follow" }
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
await response.body?.cancel().catch(() => {});
|
|
31
|
+
throw new Error(`HTTP ${response.status} for ${url}`);
|
|
32
|
+
}
|
|
33
|
+
const declaredSize = Number(response.headers.get("content-length"));
|
|
34
|
+
if (Number.isFinite(declaredSize) && declaredSize > MAX_CHECKSUM_BYTES) {
|
|
35
|
+
await response.body?.cancel().catch(() => {});
|
|
36
|
+
throw new Error("Checksum response exceeds size limit");
|
|
37
|
+
}
|
|
38
|
+
return await readRuntimeResponseText(response, MAX_CHECKSUM_BYTES);
|
|
39
|
+
}
|
|
40
|
+
async function resolveExpectedChecksum(params) {
|
|
41
|
+
const lines = (await fetchText(params.checksumUrl, params.timeoutMs, params.proxy, params.signal)).split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
42
|
+
for (const line of lines) {
|
|
43
|
+
const match = line.match(/^([a-fA-F0-9]{64})(?:\s+[*]?(.+))?$/);
|
|
44
|
+
if (!match) continue;
|
|
45
|
+
if (!match[2] || match[2] === params.archiveFile) return match[1].toLowerCase();
|
|
46
|
+
}
|
|
47
|
+
throw new RuntimeError(`Checksum for ${params.archiveFile} was not found`, "RUNTIME_CHECKSUM_MISMATCH", params.runtime, "resolve_checksum", true);
|
|
48
|
+
}
|
|
49
|
+
async function sha256File(path) {
|
|
50
|
+
const hash = createHash("sha256");
|
|
51
|
+
for await (const chunk of createReadStream(path)) hash.update(chunk);
|
|
52
|
+
return hash.digest("hex");
|
|
53
|
+
}
|
|
54
|
+
async function downloadVerifiedArchive(params) {
|
|
55
|
+
await mkdir(dirname(params.targetPath), { recursive: true });
|
|
56
|
+
const completedPath = params.targetPath.replace(/\.partial$/, "");
|
|
57
|
+
try {
|
|
58
|
+
await access(completedPath);
|
|
59
|
+
if (await sha256File(completedPath) === params.expectedSha256.toLowerCase()) return completedPath;
|
|
60
|
+
await rm(completedPath, { force: true });
|
|
61
|
+
} catch {}
|
|
62
|
+
try {
|
|
63
|
+
let resumeOffset = await stat(params.targetPath).then((info) => info.isFile() ? info.size : 0).catch(() => 0);
|
|
64
|
+
if (resumeOffset > MAX_ARCHIVE_BYTES) {
|
|
65
|
+
await rm(params.targetPath, { force: true });
|
|
66
|
+
resumeOffset = 0;
|
|
67
|
+
}
|
|
68
|
+
let response;
|
|
69
|
+
const request = async (offset) => {
|
|
70
|
+
try {
|
|
71
|
+
return await fetchRuntimeResource({
|
|
72
|
+
url: params.url,
|
|
73
|
+
timeoutMs: params.timeoutMs,
|
|
74
|
+
proxy: params.proxy,
|
|
75
|
+
signal: params.signal,
|
|
76
|
+
init: {
|
|
77
|
+
redirect: "follow",
|
|
78
|
+
headers: offset > 0 ? { Range: `bytes=${offset}-` } : void 0
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
} catch (error) {
|
|
82
|
+
throw new RuntimeDownloadTransportError(error instanceof Error ? error.message : String(error), !params.signal?.aborted, { cause: error });
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
response = await request(resumeOffset);
|
|
86
|
+
if (resumeOffset > 0 && response.status === 416) {
|
|
87
|
+
await response.body?.cancel().catch(() => {});
|
|
88
|
+
await rm(params.targetPath, { force: true });
|
|
89
|
+
resumeOffset = 0;
|
|
90
|
+
response = await request(0);
|
|
91
|
+
}
|
|
92
|
+
if (!response.ok || !response.body) {
|
|
93
|
+
await response.body?.cancel().catch(() => {});
|
|
94
|
+
throw new RuntimeDownloadTransportError(`HTTP ${response.status}`, response.status === 429 || response.status >= 500);
|
|
95
|
+
}
|
|
96
|
+
let total;
|
|
97
|
+
if (response.status === 206) {
|
|
98
|
+
const contentRange = response.headers.get("content-range")?.match(/^bytes (\d+)-(\d+)\/(\d+)$/);
|
|
99
|
+
if (!contentRange || Number(contentRange[1]) !== resumeOffset) {
|
|
100
|
+
await response.body.cancel().catch(() => {});
|
|
101
|
+
throw new RuntimeDownloadContentError("Invalid Content-Range response");
|
|
102
|
+
}
|
|
103
|
+
total = Number(contentRange[3]);
|
|
104
|
+
} else {
|
|
105
|
+
if (resumeOffset > 0) {
|
|
106
|
+
await rm(params.targetPath, { force: true });
|
|
107
|
+
resumeOffset = 0;
|
|
108
|
+
}
|
|
109
|
+
total = Number(response.headers.get("content-length")) || void 0;
|
|
110
|
+
}
|
|
111
|
+
if (total && total > MAX_ARCHIVE_BYTES) {
|
|
112
|
+
await response.body.cancel().catch(() => {});
|
|
113
|
+
throw new Error("Archive exceeds size limit");
|
|
114
|
+
}
|
|
115
|
+
let downloaded = resumeOffset;
|
|
116
|
+
const transform = new TransformStream({ transform(chunk, controller) {
|
|
117
|
+
downloaded += chunk.byteLength;
|
|
118
|
+
if (downloaded > MAX_ARCHIVE_BYTES) throw new Error("Archive exceeds size limit");
|
|
119
|
+
params.onProgress?.(downloaded, total);
|
|
120
|
+
controller.enqueue(chunk);
|
|
121
|
+
} });
|
|
122
|
+
await pipeline(response.body.pipeThrough(transform), createWriteStream(params.targetPath, {
|
|
123
|
+
flags: resumeOffset > 0 ? "a" : "w",
|
|
124
|
+
mode: 384
|
|
125
|
+
}));
|
|
126
|
+
if (total && downloaded !== total) throw new RuntimeDownloadTransportError("Archive download was truncated", true);
|
|
127
|
+
if (await sha256File(params.targetPath) !== params.expectedSha256.toLowerCase()) throw new RuntimeError(`Checksum mismatch for ${params.runtime} archive`, "RUNTIME_CHECKSUM_MISMATCH", params.runtime, "verify_archive", true);
|
|
128
|
+
await rename(params.targetPath, completedPath);
|
|
129
|
+
return completedPath;
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (error instanceof RuntimeDownloadContentError || error instanceof RuntimeError && error.code === "RUNTIME_CHECKSUM_MISMATCH" || error instanceof Error && error.message === "Archive exceeds size limit") await rm(params.targetPath, { force: true });
|
|
132
|
+
if (error instanceof RuntimeError) throw error;
|
|
133
|
+
throw new RuntimeError(`Failed to download ${params.runtime} runtime: ${error instanceof Error ? error.message : String(error)}`, "RUNTIME_DOWNLOAD_FAILED", params.runtime, "download", true, [], { cause: error });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//#endregion
|
|
137
|
+
export { canFallbackRuntimeDownload, downloadVerifiedArchive, resolveExpectedChecksum, sha256File };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RuntimeToolsConfig } from '../config/schema.js';
|
|
2
|
+
import type { ResolvedRuntime, RuntimeKind } from './types.js';
|
|
3
|
+
export interface RuntimeEnvironmentOptions {
|
|
4
|
+
stateDir: string;
|
|
5
|
+
config: RuntimeToolsConfig;
|
|
6
|
+
baseEnv: Record<string, string>;
|
|
7
|
+
runtimes?: RuntimeKind[];
|
|
8
|
+
extraBinDirs?: string[];
|
|
9
|
+
}
|
|
10
|
+
export interface RuntimeEnvironmentResult {
|
|
11
|
+
env: Record<string, string>;
|
|
12
|
+
resolved: ResolvedRuntime[];
|
|
13
|
+
}
|
|
14
|
+
export declare function buildRuntimeEnvironment(options: RuntimeEnvironmentOptions): Promise<RuntimeEnvironmentResult>;
|
|
15
|
+
export declare function resolveRuntimeCommand(params: {
|
|
16
|
+
command: string;
|
|
17
|
+
stateDir: string;
|
|
18
|
+
config: RuntimeToolsConfig;
|
|
19
|
+
allowProvision: boolean;
|
|
20
|
+
}): Promise<string>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { applyPathPrepend } from "../infra/path-prepend.js";
|
|
2
|
+
import { ManagedRuntimeManager } from "./manager.js";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { access, readdir } from "node:fs/promises";
|
|
5
|
+
//#region src/runtime-tools/environment.ts
|
|
6
|
+
const POLLUTING_ENV_KEYS = [
|
|
7
|
+
"NODE_OPTIONS",
|
|
8
|
+
"NODE_PATH",
|
|
9
|
+
"NPM_CONFIG_PREFIX",
|
|
10
|
+
"npm_config_prefix",
|
|
11
|
+
"PYTHONHOME",
|
|
12
|
+
"PYTHONPATH",
|
|
13
|
+
"VIRTUAL_ENV",
|
|
14
|
+
"CONDA_PREFIX",
|
|
15
|
+
"UV_PYTHON_INSTALL_DIR",
|
|
16
|
+
"UV_PYTHON_BIN_DIR",
|
|
17
|
+
"UV_TOOL_DIR",
|
|
18
|
+
"UV_TOOL_BIN_DIR",
|
|
19
|
+
"UV_CACHE_DIR",
|
|
20
|
+
"UV_PYTHON_INSTALL_MIRROR"
|
|
21
|
+
];
|
|
22
|
+
async function skillEnvironmentBinDirs(stateDir) {
|
|
23
|
+
const root = join(stateDir, "tools", "environments", "skills");
|
|
24
|
+
let environmentIds;
|
|
25
|
+
try {
|
|
26
|
+
environmentIds = await readdir(root);
|
|
27
|
+
} catch {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const candidates = environmentIds.flatMap((id) => [join(root, id, "bin"), join(root, id, "node_modules", ".bin")]);
|
|
31
|
+
return (await Promise.all(candidates.map(async (candidate) => {
|
|
32
|
+
try {
|
|
33
|
+
await access(candidate);
|
|
34
|
+
return candidate;
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}))).filter((candidate) => candidate !== null);
|
|
39
|
+
}
|
|
40
|
+
async function buildRuntimeEnvironment(options) {
|
|
41
|
+
const env = { ...options.baseEnv };
|
|
42
|
+
for (const key of POLLUTING_ENV_KEYS) delete env[key];
|
|
43
|
+
const manager = new ManagedRuntimeManager({
|
|
44
|
+
stateDir: options.stateDir,
|
|
45
|
+
config: options.config
|
|
46
|
+
});
|
|
47
|
+
const runtimes = options.runtimes ?? [
|
|
48
|
+
"node",
|
|
49
|
+
"uv",
|
|
50
|
+
"python"
|
|
51
|
+
];
|
|
52
|
+
const resolved = (await Promise.all(runtimes.map(async (runtime) => {
|
|
53
|
+
try {
|
|
54
|
+
return await manager.resolve({
|
|
55
|
+
runtime,
|
|
56
|
+
allowProvision: false
|
|
57
|
+
});
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}))).filter((item) => item !== null);
|
|
62
|
+
const managedBinDirs = resolved.filter((item) => item.source === "managed").map((item) => dirname(item.executable));
|
|
63
|
+
const skillBinDirs = await skillEnvironmentBinDirs(options.stateDir);
|
|
64
|
+
applyPathPrepend(env, [
|
|
65
|
+
...managedBinDirs,
|
|
66
|
+
...skillBinDirs,
|
|
67
|
+
...options.extraBinDirs ?? []
|
|
68
|
+
]);
|
|
69
|
+
if (resolved.some((item) => item.runtime === "python")) {
|
|
70
|
+
env.PYTHONNOUSERSITE = "1";
|
|
71
|
+
env.PIP_REQUIRE_VIRTUALENV = "1";
|
|
72
|
+
}
|
|
73
|
+
if (resolved.some((item) => item.runtime === "uv")) {
|
|
74
|
+
env.UV_PYTHON_INSTALL_DIR = resolved.find((item) => item.runtime === "python" && item.source === "managed")?.installDir ?? join(options.stateDir, "tools", "python", "versions");
|
|
75
|
+
env.UV_PYTHON_BIN_DIR = join(options.stateDir, "tools", "python", "bin");
|
|
76
|
+
env.UV_CACHE_DIR = join(options.stateDir, "tools", "cache", "uv");
|
|
77
|
+
env.UV_MANAGED_PYTHON = "1";
|
|
78
|
+
env.UV_NO_CONFIG = "1";
|
|
79
|
+
}
|
|
80
|
+
if (resolved.some((item) => item.runtime === "node")) {
|
|
81
|
+
env.COREPACK_HOME = join(options.stateDir, "tools", "cache", "corepack");
|
|
82
|
+
env.npm_config_cache = join(options.stateDir, "tools", "cache", "npm");
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
env,
|
|
86
|
+
resolved
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const COMMAND_RUNTIME = {
|
|
90
|
+
node: "node",
|
|
91
|
+
npm: "node",
|
|
92
|
+
npx: "node",
|
|
93
|
+
corepack: "node",
|
|
94
|
+
uv: "uv",
|
|
95
|
+
uvx: "uv",
|
|
96
|
+
python: "python",
|
|
97
|
+
python3: "python"
|
|
98
|
+
};
|
|
99
|
+
async function resolveRuntimeCommand(params) {
|
|
100
|
+
const runtime = COMMAND_RUNTIME[params.command.toLowerCase()];
|
|
101
|
+
if (!runtime) return params.command;
|
|
102
|
+
const resolved = await new ManagedRuntimeManager({
|
|
103
|
+
stateDir: params.stateDir,
|
|
104
|
+
config: params.config
|
|
105
|
+
}).resolve({
|
|
106
|
+
runtime,
|
|
107
|
+
allowProvision: params.allowProvision
|
|
108
|
+
});
|
|
109
|
+
const key = params.command.toLowerCase() === "python3" ? "python" : params.command.toLowerCase();
|
|
110
|
+
return resolved.executables[key] ?? resolved.executable;
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
export { buildRuntimeEnvironment, resolveRuntimeCommand };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RuntimeKind } from './types.js';
|
|
2
|
+
export type RuntimeErrorCode = 'RUNTIME_DISABLED' | 'RUNTIME_UNSUPPORTED' | 'RUNTIME_NOT_FOUND' | 'RUNTIME_VERSION_MISMATCH' | 'RUNTIME_DOWNLOAD_FAILED' | 'RUNTIME_CHECKSUM_MISMATCH' | 'RUNTIME_ARCHIVE_INVALID' | 'RUNTIME_INSTALL_LOCKED' | 'RUNTIME_PROBE_FAILED' | 'RUNTIME_CORRUPTED' | 'RUNTIME_PERMISSION_DENIED';
|
|
3
|
+
export declare class RuntimeError extends Error {
|
|
4
|
+
readonly code: RuntimeErrorCode;
|
|
5
|
+
readonly runtime: RuntimeKind;
|
|
6
|
+
readonly phase: string;
|
|
7
|
+
readonly repairable: boolean;
|
|
8
|
+
readonly hints: string[];
|
|
9
|
+
constructor(message: string, code: RuntimeErrorCode, runtime: RuntimeKind, phase: string, repairable: boolean, hints?: string[], options?: ErrorOptions);
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/runtime-tools/errors.ts
|
|
2
|
+
var RuntimeError = class extends Error {
|
|
3
|
+
constructor(message, code, runtime, phase, repairable, hints = [], options) {
|
|
4
|
+
super(message, options);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.runtime = runtime;
|
|
7
|
+
this.phase = phase;
|
|
8
|
+
this.repairable = repairable;
|
|
9
|
+
this.hints = hints;
|
|
10
|
+
this.name = "RuntimeError";
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { RuntimeError };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RuntimeError } from "./errors.js";
|
|
2
|
+
import { bundledPythonArchiveName, resolveOfflineBundleArtifact } from "./offline-bundle.js";
|
|
3
|
+
import { ManagedRuntimeManager } from "./manager.js";
|
|
4
|
+
import { buildRuntimeEnvironment, resolveRuntimeCommand } from "./environment.js";
|
|
5
|
+
import { provisionEagerRuntimes } from "./bootstrap.js";
|
|
6
|
+
import { pruneRuntimeTools } from "./prune.js";
|
|
7
|
+
export { ManagedRuntimeManager, RuntimeError, buildRuntimeEnvironment, bundledPythonArchiveName, provisionEagerRuntimes, pruneRuntimeTools, resolveOfflineBundleArtifact, resolveRuntimeCommand };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function withInstallLock<T>(path: string, metadata: Record<string, unknown>, fn: () => Promise<T>): Promise<T>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { dirname } from "node:path";
|
|
2
|
+
import { mkdir, open, readFile, unlink } from "node:fs/promises";
|
|
3
|
+
//#region src/runtime-tools/install-lock.ts
|
|
4
|
+
const LOCK_STALE_MS = 1800 * 1e3;
|
|
5
|
+
const LOCK_WAIT_MS = 250;
|
|
6
|
+
function isProcessAlive(pid) {
|
|
7
|
+
try {
|
|
8
|
+
process.kill(pid, 0);
|
|
9
|
+
return true;
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async function staleLock(path) {
|
|
15
|
+
try {
|
|
16
|
+
const value = JSON.parse(await readFile(path, "utf8"));
|
|
17
|
+
const pid = typeof value.pid === "number" ? value.pid : 0;
|
|
18
|
+
const createdAt = typeof value.createdAt === "number" ? value.createdAt : 0;
|
|
19
|
+
return !isProcessAlive(pid) && Date.now() - createdAt > LOCK_STALE_MS;
|
|
20
|
+
} catch {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function withInstallLock(path, metadata, fn) {
|
|
25
|
+
await mkdir(dirname(path), { recursive: true });
|
|
26
|
+
while (true) try {
|
|
27
|
+
const handle = await open(path, "wx", 384);
|
|
28
|
+
await handle.writeFile(JSON.stringify({
|
|
29
|
+
pid: process.pid,
|
|
30
|
+
createdAt: Date.now(),
|
|
31
|
+
...metadata
|
|
32
|
+
}));
|
|
33
|
+
await handle.close();
|
|
34
|
+
break;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if (error.code !== "EEXIST") throw error;
|
|
37
|
+
if (await staleLock(path)) {
|
|
38
|
+
await unlink(path).catch(() => void 0);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
await new Promise((resolve) => setTimeout(resolve, LOCK_WAIT_MS));
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
return await fn();
|
|
45
|
+
} finally {
|
|
46
|
+
await unlink(path).catch(() => void 0);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { withInstallLock };
|