@xopcai/xopc 0.0.414 → 0.0.416
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 +4 -1
- package/dist/browser-ext/_locales/zh_CN/messages.json +4 -1
- package/dist/browser-ext/dist/assets/{page-context-MuzjMBlJ.js → page-context-CVvmTWZb.js} +33 -9
- package/dist/browser-ext/dist/background.js +39 -10
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +22 -3
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-ClobpdW3.js → agent-avatar-dicebear-CufU7cqe.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-DHDAcss8.js +1 -0
- package/dist/gateway/static/root/assets/agents-BV3dAoa0.js +77 -0
- package/dist/gateway/static/root/assets/{agents-admin-api-CeBkHnl8.js → agents-admin-api-B1p-ghg9.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-CLunLNGp.js → app-management-settings-panel-D4-n1uBg.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DBEgoE9g.js → appearance-settings-Cgn4eNsX.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BOYzD7Zz.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-JElK4Goq.js → archive-plugin-B4btCsiV.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-CZ0UqwyU.js → automations-page-yb1EL_3N.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-J7LJ4RuV.js +8 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CXFawow6.js → binary-plugins-DQT9e258.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BoduwSYI.js → block-editor-B50rU9tL.js} +30 -30
- package/dist/gateway/static/root/assets/{browser-automation-inputs-D1pDgMJu.js → browser-automation-inputs-D6AccXaA.js} +1 -1
- package/dist/gateway/static/root/assets/browser-automations-page-BiQz6lJA.js +3 -0
- package/dist/gateway/static/root/assets/browser-settings-page-W9kuxBbE.js +3 -0
- package/dist/gateway/static/root/assets/{capabilities-Bpeh6E22.js → capabilities-BlxF36t-.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-page-iXe87MdG.js +2 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CRLSXe7Z.js +8 -0
- package/dist/gateway/static/root/assets/{capability-header-actions-BasrAWA0.js → capability-header-actions-BMnbzHms.js} +1 -1
- package/dist/gateway/static/root/assets/channels-CrRJkOKX.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CwQbzcZ_.js → chat-terminal-dock-Bd3af4gL.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-DNWeJKfF.js → computer-settings-page-DXfqy7xh.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-CxHgC5RM.js → connector-service-page-B-cw0CPU.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-DbFxc0Fd.js +1 -0
- package/dist/gateway/static/root/assets/{date-picker-CXxLbLJb.js → date-picker-CqzXevH6.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DVuWMrSj.js → dependency-picker-pgT4Gyaf.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BDlg9g4s.js → desktop-pet-settings-Dy_-i2L8.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-KbVLtAlO.js → desktop-pet-zICeqw9c.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-ByGbxqkg.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-a7xEodzo.js → directory-picker-path-field-C-aQ7qoM.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CHelH5u_.js → extension-debug-page-2NwpYkS5.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CrVHmS9-.js → extension-page-y9J0z7_Q.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CiMybi0r.js → extension-settings-page-BtowusUh.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-DF_HV6NP.js → gateway-config-swr-fQKBHBi1.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-C52ghnBK.js +1 -0
- package/dist/gateway/static/root/assets/gateway-realtime-store-Bx9KCID-.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-BYSKzUMR.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-B91CBTzO.js → gateway-startup-retry-Cfwxof4k.js} +1 -1
- package/dist/gateway/static/root/assets/highlight-code-Cz6eeDH5.js +1 -0
- package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-8ACAVktj.js → highlighted-body-KQOG7T2V-BiAa8HKC.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-Cd1BjYHj.js +2 -0
- package/dist/gateway/static/root/assets/{image-generation-api-CVBaWmrV.js → image-generation-api-gBFro48x.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-C5IP3e6d.js → imports-page-BZQpXgjj.js} +1 -1
- package/dist/gateway/static/root/assets/index-Cy16gQST.css +1 -0
- package/dist/gateway/static/root/assets/index-DRyGCING.js +710 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BhU6VYvd.js → keyboard-shortcuts-settings-CYunR34k.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-B_Ac1lly.js +1 -0
- package/dist/gateway/static/root/assets/{local-apps-page-DcP1Bdlk.js → local-apps-page-w-J5bY02.js} +1 -1
- package/dist/gateway/static/root/assets/{local-session-drafts-DvmwiLUx.js → local-session-drafts-iGX_6O0O.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-JogcXC4J.js → locale-store-B7s2Hb35.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-Dnjvvx2i.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-w1EDwgLW.js +1 -0
- package/dist/gateway/static/root/assets/{media-plugins-BnPpcJ2J.js → media-plugins-CIx1koXw.js} +1 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-DISkHmEC.js +1 -0
- package/dist/gateway/static/root/assets/{messages-RzwPiQNL.js → messages-BYq0cPbn.js} +2 -2
- package/dist/gateway/static/root/assets/note-detail-panel-CNkxMTFU.js +5 -0
- package/dist/gateway/static/root/assets/note-image-lightbox-D5GH2wuC.js +1 -0
- package/dist/gateway/static/root/assets/notes-page-DZgKqFBG.js +8 -0
- package/dist/gateway/static/root/assets/page-context-capture-button-DusR2Itk.js +1 -0
- package/dist/gateway/static/root/assets/personal-page-CR5JFkQ9.js +1 -0
- package/dist/gateway/static/root/assets/personal-settings-panel-B7undvlr.js +1 -0
- package/dist/gateway/static/root/assets/phone-model-picker-fWDltRUJ.js +1 -0
- package/dist/gateway/static/root/assets/phone-settings-page-CsOirAiy.js +1 -0
- package/dist/gateway/static/root/assets/plugin-details-dialog-BOBVIB3j.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-FGqN-mQx.js → preview-open-alternatives-CMxjsKSw.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CwnHLfdL.js → product-open-page-CrlyJx5M.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-content-BD6k5hF9.js → product-preview-content-B-Jhzi7W.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DoYUbtcI.js +7 -0
- package/dist/gateway/static/root/assets/projects-page-xGQd9oAZ.js +1 -0
- package/dist/gateway/static/root/assets/refresh-cw-BRlGaq2w.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BGqSwITi.js → registry-api-BcfoLEna.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-Gs0Xkws9.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-api-CSm5SpnR.js → runtime-tools-api-DesqGCnE.js} +1 -1
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-Bwg7U7TR.js +1 -0
- package/dist/gateway/static/root/assets/{schema-form-DoVn5jJK.js → schema-form-ByzTNR_C.js} +1 -1
- package/dist/gateway/static/root/assets/{session-api-DTxZyMta.js → session-api-DdQnMwkl.js} +1 -1
- package/dist/gateway/static/root/assets/{session-manager-B2HDomj4.js → session-manager-B_h0jlLb.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-XzK1ftbR.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-D_8Mvnog.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-Ce8vVv-9.js → settings-form-section-Brgd8IOV.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DP2w3ejC.js → settings-page-B6Mv02eg.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-header-BWyxJKOG.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-B20AfmFG.js → settings-page-layout-DLHcS-0T.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DSCj5yis.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-DV4dKrmG.js → share-preview-page-DF8Of0aZ.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DXNPe4Tl.js +1 -0
- package/dist/gateway/static/root/assets/{skill-api-DTdejInH.js → skill-api-CKCDCHLq.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BH0WF6Br.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-DFWMVRW4.js +2 -0
- package/dist/gateway/static/root/assets/system-settings-panel-DB-ttubV.js +1 -0
- package/dist/gateway/static/root/assets/task-detail-page-BJY7c8wb.js +2 -0
- package/dist/gateway/static/root/assets/{task-result-evidence-DIGSC4qF.js → task-result-evidence-B-vt1BgK.js} +1 -1
- package/dist/gateway/static/root/assets/{tracing-settings-page-BaU8frtc.js → tracing-settings-page-Dt51Z_ws.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-BCcOUsqu.js → tunnel-api-Dok3t7Qe.js} +1 -1
- package/dist/gateway/static/root/assets/usage-page-lJym5G7F.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-C1X47WVb.js → use-autosave-D4EMIB-V.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-BXdNkITp.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-Bk4DQMTw.js → voice-api-key-field-CO3KuanA.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-D7xsWrdh.js → voice-config-api-BkUlN7GH.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-B7_NmTB5.js → work-discovery-overlay-BJRtgQM3.js} +1 -1
- package/dist/gateway/static/root/assets/wrench-DFb4r8bH.js +1 -0
- package/dist/gateway/static/root/assets/xopc-cloud-account-card-CS-_GxHV.js +1 -0
- package/dist/gateway/static/root/browser-setup-test.html +5 -0
- package/dist/gateway/static/root/browser-setup-test.js +7 -0
- package/dist/gateway/static/root/index.html +17 -14
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/browser-setup.js +6 -0
- package/dist/packages/gateway-contract/src/index.js +4 -0
- package/dist/packages/gateway-contract/src/phone-setup.js +6 -0
- package/dist/packages/realtime-client/src/index.js +1 -0
- package/dist/packages/realtime-protocol/src/index.js +1 -0
- package/dist/src/agent/agent-manager.d.ts +4 -0
- package/dist/src/agent/agent-manager.js +12 -1
- package/dist/src/agent/coding/workspace-revision.js +1 -1
- package/dist/src/agent/commands/command-registry.js +1 -1
- package/dist/src/agent/embedded/tool-search-extension.js +14 -1
- package/dist/src/agent/memory/context-recovery.d.ts +1 -1
- package/dist/src/agent/service.d.ts +1 -0
- package/dist/src/agent/service.js +5 -0
- package/dist/src/agent/service.types.d.ts +2 -0
- package/dist/src/agent/skills/installer.js +3 -3
- package/dist/src/agent/tool-manuals/phone.d.ts +1 -1
- package/dist/src/agent/tool-manuals/phone.js +4 -2
- package/dist/src/agent/tool-manuals/xopc-configuration.d.ts +2 -0
- package/dist/src/agent/tool-manuals/xopc-configuration.js +25 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +2 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +6 -2
- package/dist/src/agent/tools/factory.d.ts +3 -0
- package/dist/src/agent/tools/factory.js +11 -1
- package/dist/src/agent/tools/personal-task-tool.d.ts +1 -1
- package/dist/src/agent/tools/personal-task-tool.js +23 -21
- package/dist/src/agent/tools/phone-use-tool.d.ts +1 -0
- package/dist/src/agent/tools/phone-use-tool.js +29 -1
- package/dist/src/agent/tools/tool-manual-tool.d.ts +1 -1
- package/dist/src/agent/tools/tool-manual-tool.js +3 -1
- package/dist/src/agent/tools/toolExposure.js +3 -0
- package/dist/src/agent/tools/xopc-use-tool.d.ts +4 -2
- package/dist/src/agent/tools/xopc-use-tool.js +40 -2
- package/dist/src/backup/archive.js +2 -1
- package/dist/src/browser/drivers/browser-driver.d.ts +2 -2
- package/dist/src/browser/drivers/extension-driver.d.ts +2 -2
- package/dist/src/browser/drivers/extension-driver.js +6 -3
- package/dist/src/browser/providers/browser-ext-install.js +3 -2
- package/dist/src/browser/runtime/browser-runtime.d.ts +4 -1
- package/dist/src/browser/runtime/browser-runtime.js +29 -17
- package/dist/src/browser/setup/repository.d.ts +5 -0
- package/dist/src/browser/setup/repository.js +42 -0
- package/dist/src/browser/setup/service.d.ts +152 -0
- package/dist/src/browser/setup/service.js +404 -0
- package/dist/src/browser/setup/types.d.ts +38 -0
- package/dist/src/browser/setup/types.js +1 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +3 -3
- package/dist/src/cli/commands/extension-pack.js +1 -1
- package/dist/src/cli/commands/extension.js +2 -2
- package/dist/src/config/schema.d.ts +2 -0
- package/dist/src/extensions/install.js +1 -1
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/browser-setup.d.ts +3 -0
- package/dist/src/gateway/hono/routes/browser-setup.js +114 -0
- package/dist/src/gateway/hono/routes/browser.d.ts +2 -1
- package/dist/src/gateway/hono/routes/browser.js +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/phone-dependencies.js +1 -1
- package/dist/src/gateway/hono/routes/phone-setup.d.ts +7 -0
- package/dist/src/gateway/hono/routes/phone-setup.js +162 -0
- package/dist/src/gateway/hono/routes/phone.js +11 -7
- package/dist/src/gateway/hono/routes/public-gateway.js +2 -0
- package/dist/src/gateway/provider-model-setup.js +1 -1
- package/dist/src/gateway/service/config-coordinator.d.ts +2 -0
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/session-input-coordinator.js +1 -1
- package/dist/src/gateway/service.d.ts +5 -0
- package/dist/src/gateway/service.js +52 -7
- package/dist/src/gateway/xopc-cloud-capability-setup.js +7 -1
- package/dist/src/home-intelligence/host.js +2 -2
- package/dist/src/infra/unhandled-rejections.js +2 -2
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/personal-agent/prompts.js +1 -1
- package/dist/src/phone/adb-driver.d.ts +8 -2
- package/dist/src/phone/adb-driver.js +124 -54
- package/dist/src/phone/cloud-adb.js +8 -0
- package/dist/src/phone/cloud-scrcpy.d.ts +3 -1
- package/dist/src/phone/cloud-scrcpy.js +17 -3
- package/dist/src/phone/contracts.d.ts +85 -0
- package/dist/src/phone/contracts.js +31 -5
- package/dist/src/phone/model-adapter.d.ts +141 -2
- package/dist/src/phone/model-adapter.js +176 -24
- package/dist/src/phone/numeric-entry.d.ts +31 -0
- package/dist/src/phone/numeric-entry.js +126 -0
- package/dist/src/phone/planning.d.ts +27 -0
- package/dist/src/phone/planning.js +79 -0
- package/dist/src/phone/recovery.d.ts +37 -0
- package/dist/src/phone/recovery.js +81 -0
- package/dist/src/phone/reliability.d.ts +7 -0
- package/dist/src/phone/reliability.js +66 -0
- package/dist/src/phone/repository.d.ts +1 -0
- package/dist/src/phone/repository.js +3 -0
- package/dist/src/phone/runtime.d.ts +8 -0
- package/dist/src/phone/runtime.js +387 -41
- package/dist/src/phone/scrcpy-text.d.ts +11 -0
- package/dist/src/phone/scrcpy-text.js +72 -0
- package/dist/src/phone/scrcpy.d.ts +5 -1
- package/dist/src/phone/scrcpy.js +48 -3
- package/dist/src/phone/semantic-controls.d.ts +13 -0
- package/dist/src/phone/semantic-controls.js +76 -0
- package/dist/src/phone/setup/service.d.ts +148 -0
- package/dist/src/phone/setup/service.js +251 -0
- package/dist/src/providers/presentation.js +2 -2
- package/dist/src/providers/xopc-cloud-model-source.js +6 -2
- package/dist/src/realtime/runtime.js +1 -1
- package/dist/src/storage/sqlite/connection.js +2 -2
- package/dist/src/storage/sqlite/offline-access.js +13 -7
- package/dist/src/storage/sqlite/schema-errors.d.ts +12 -0
- package/dist/src/storage/sqlite/schema-errors.js +21 -3
- package/dist/src/storage/sqlite/schema-upgrade.d.ts +4 -0
- package/dist/src/storage/sqlite/schema-upgrade.js +78 -0
- package/dist/src/storage/sqlite/schema.d.ts +4 -3
- package/dist/src/storage/sqlite/schema.js +14 -8
- package/dist/src/storage/sqlite/schema.sql +10 -0
- package/dist/src/storage/sqlite/upgrades/203_remove_retired_proactive_contracts.sql +70 -0
- package/dist/src/storage/sqlite/upgrades/204_home_intelligence.sql +78 -0
- package/dist/src/storage/sqlite/upgrades/205_agent_catalog.sql +66 -0
- package/dist/src/storage/sqlite/upgrades/206_home_advice_strategy_version.sql +2 -0
- package/dist/src/storage/sqlite/upgrades/207_user_model_policy_contract.sql +121 -0
- package/dist/src/storage/sqlite/upgrades/208_automation_management.sql +2 -0
- package/dist/src/storage/sqlite/upgrades/209_automation_event_hub.sql +48 -0
- package/dist/src/storage/sqlite/upgrades/210_remove_legacy_automation_timeout.sql +14 -0
- package/dist/src/storage/sqlite/upgrades/211_automation_result_deliveries.sql +16 -0
- package/dist/src/storage/sqlite/upgrades/212_automation_delivery_policy.sql +30 -0
- package/dist/src/storage/sqlite/upgrades/213_automation_reliability_contract.sql +188 -0
- package/dist/src/storage/sqlite/upgrades/214_ai_usage_ledger.sql +41 -0
- package/dist/src/storage/sqlite/upgrades/215_scene_execution_adapters.sql +6 -0
- package/dist/src/storage/sqlite/upgrades/216_remove_scene_model_usage.sql +1 -0
- package/dist/src/storage/sqlite/upgrades/217_remove_legacy_memory_tables.sql +4 -0
- package/dist/src/storage/sqlite/upgrades/218_core_relation_indexes.sql +26 -0
- package/dist/src/storage/sqlite/upgrades/219_json_contracts.sql +123 -0
- package/dist/src/storage/sqlite/upgrades/220_normalize_timestamps.sql +339 -0
- package/dist/src/storage/sqlite/upgrades/221_ai_usage_retention_index.sql +2 -0
- package/dist/src/storage/sqlite/upgrades/222_session_config_authority.sql +13 -0
- package/dist/src/storage/sqlite/upgrades/223_session_creation_receipts.sql +59 -0
- package/dist/src/storage/sqlite/upgrades/224_task_origin_links.sql +8 -0
- package/dist/src/storage/sqlite/upgrades/225_task_collaboration.sql +32 -0
- package/dist/src/storage/sqlite/upgrades/226_task_main_updates.sql +9 -0
- package/dist/src/storage/sqlite/upgrades/227_task_main_update_decisions.sql +8 -0
- package/dist/src/storage/sqlite/upgrades/228_task_main_agent_links.sql +14 -0
- package/dist/src/storage/sqlite/upgrades/229_task_criterion_reviews.sql +12 -0
- package/dist/src/storage/sqlite/upgrades/230_personal_agent_onboarding.sql +8 -0
- package/dist/src/storage/sqlite/upgrades/231_task_result_deliveries.sql +32 -0
- package/dist/src/storage/sqlite/upgrades/232_personal_requests.sql +28 -0
- package/dist/src/storage/sqlite/upgrades/233_observability_usage_links.sql +3 -0
- package/dist/src/storage/sqlite/upgrades/234_task_result_reply.sql +14 -0
- package/dist/src/storage/sqlite/upgrades/235_personal_conversation_priority.sql +3 -0
- package/dist/src/storage/sqlite/upgrades/236_personal_proactivity.sql +53 -0
- package/dist/src/storage/sqlite/upgrades/237_personal_strategy_versions.sql +18 -0
- package/dist/src/storage/sqlite/upgrades/238_browser_record_replay.sql +45 -0
- package/dist/src/storage/sqlite/upgrades/239_clarification_notifications.sql +26 -0
- package/dist/src/storage/sqlite/upgrades/240_device_settings.sql +5 -0
- package/dist/src/storage/sqlite/upgrades/241_device_grant_audit.sql +13 -0
- package/dist/src/storage/sqlite/upgrades/242_cloud_usage_receipts.sql +5 -0
- package/dist/src/storage/sqlite/upgrades/243_voice_opening_greetings.sql +12 -0
- package/dist/src/storage/sqlite/upgrades/244_device_request_proofs.sql +8 -0
- package/dist/src/storage/sqlite/upgrades/245_memory_learning.sql +125 -0
- package/dist/src/storage/sqlite/upgrades/246_personal_session_thinking.sql +22 -0
- package/dist/src/storage/sqlite/upgrades/247_agent_selection_records.sql +32 -0
- package/dist/src/storage/sqlite/upgrades/248_next_turn_suggestions.sql +20 -0
- package/dist/src/storage/sqlite/upgrades/249_task_allocations.sql +17 -0
- package/dist/src/storage/sqlite/upgrades/250_research_checkpoints.sql +15 -0
- package/dist/src/storage/sqlite/upgrades/251_personal_result_reads.sql +40 -0
- package/dist/src/storage/sqlite/upgrades/252_task_work_revisions.sql +15 -0
- package/dist/src/storage/sqlite/upgrades/253_discussion_processing_recovery.sql +20 -0
- package/dist/src/storage/sqlite/upgrades/254_discussion_annotations.sql +17 -0
- package/dist/src/storage/sqlite/upgrades/255_discussion_chapter_progress.sql +10 -0
- package/dist/src/storage/sqlite/upgrades/256_task_main_update_retries.sql +21 -0
- package/dist/src/storage/sqlite/upgrades/257_session_composer_history.sql +11 -0
- package/dist/src/storage/sqlite/upgrades/258_task_phase_changes.sql +20 -0
- package/dist/src/storage/sqlite/upgrades/259_personal_default_style.sql +10 -0
- package/dist/src/storage/sqlite/upgrades/260_browser_setup.sql +9 -0
- package/dist/src/storage/sqlite/windows-database-owners.js +33 -28
- package/dist/src/tasks/capabilities/relations.d.ts +2 -2
- package/dist/src/tui/clipboard-image.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/utils/index.js +1 -1
- package/dist/src/utils/logger/index.js +1 -1
- package/dist/src/utils/logger.js +1 -1
- package/dist/src/work-discovery/probe.js +1 -1
- package/package.json +3 -3
- package/skills/tools/configure-xopc/SKILL.md +47 -0
- package/skills/tools/configure-xopc/references/browser/acceptance.md +31 -0
- package/skills/tools/configure-xopc/references/browser/chrome-extension.md +19 -0
- package/skills/tools/configure-xopc/references/browser/overview.md +22 -0
- package/skills/tools/configure-xopc/references/browser/permissions.md +25 -0
- package/skills/tools/configure-xopc/references/browser/troubleshooting.md +24 -0
- package/skills/tools/configure-xopc/references/phone/acceptance.md +25 -0
- package/skills/tools/configure-xopc/references/phone/aliyun.md +29 -0
- package/skills/tools/configure-xopc/references/phone/dependencies.md +18 -0
- package/skills/tools/configure-xopc/references/phone/local.md +19 -0
- package/skills/tools/configure-xopc/references/phone/models.md +18 -0
- package/skills/tools/configure-xopc/references/phone/overview.md +30 -0
- package/skills/tools/configure-xopc/references/phone/troubleshooting.md +24 -0
- package/skills/tools/configure-xopc/references/scene-index.md +12 -0
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-mf0jgEPE.js +0 -1
- package/dist/gateway/static/root/assets/agents-CKhZ4UYQ.js +0 -77
- package/dist/gateway/static/root/assets/apps-page-BZ_MaQJf.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-CHUDHNVL.js +0 -8
- package/dist/gateway/static/root/assets/browser-automations-page-DStDm9y1.js +0 -3
- package/dist/gateway/static/root/assets/browser-settings-page-6I4oetKt.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-page-C-EecWbS.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BQoCPk3x.js +0 -8
- package/dist/gateway/static/root/assets/channels-BKf_-Mdt.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CUBg8spT.js +0 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-PmP_vGem.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-DMAzNlm-.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-CoIgC1Al.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-DnrQ28E2.js +0 -1
- package/dist/gateway/static/root/assets/highlight-code-AMjU04kR.js +0 -1
- package/dist/gateway/static/root/assets/home-page-pTwVME-g.js +0 -2
- package/dist/gateway/static/root/assets/index-BLL0wKRZ.css +0 -1
- package/dist/gateway/static/root/assets/index-ygkHNYyo.js +0 -710
- package/dist/gateway/static/root/assets/local-app-workbench-page-Cwl6EvuX.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-CS3hcTOq.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-DC-Y_-GP.js +0 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-vckgHpON.js +0 -1
- package/dist/gateway/static/root/assets/note-detail-panel-C7u4dxEk.js +0 -5
- package/dist/gateway/static/root/assets/note-image-lightbox-jvqYtySx.js +0 -1
- package/dist/gateway/static/root/assets/notes-page-Bs7F5Hpf.js +0 -8
- package/dist/gateway/static/root/assets/page-context-capture-button-DO_yhXS1.js +0 -1
- package/dist/gateway/static/root/assets/personal-page-BexL2-PQ.js +0 -1
- package/dist/gateway/static/root/assets/personal-settings-panel-BKA4fbYH.js +0 -1
- package/dist/gateway/static/root/assets/phone-dependencies-card-ChFtdFhA.js +0 -1
- package/dist/gateway/static/root/assets/phone-model-picker-CZoIAQ1j.js +0 -1
- package/dist/gateway/static/root/assets/phone-settings-page-DRyK0nHH.js +0 -1
- package/dist/gateway/static/root/assets/plugin-details-dialog-B-N61jJH.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-DtKmFBml.js +0 -7
- package/dist/gateway/static/root/assets/projects-page-CFZIz9mc.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CWEc7W0m.js +0 -1
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-q_oswAdV.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BuPqNxpd.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-QTVDCGJG.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-header-CYpuTXUW.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-ZmlE8jIE.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CtNxWqW-.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Egaf8PqZ.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-C6FKxf4J.js +0 -2
- package/dist/gateway/static/root/assets/system-settings-panel-Baxkhov7.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-C77-rpkt.js +0 -2
- package/dist/gateway/static/root/assets/usage-page-BFeIbpbi.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-u8zY5jea.js +0 -2
- package/dist/gateway/static/root/assets/xopc-cloud-account-card-CJ_akAvc.js +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ScrcpyTextChannel } from './scrcpy-text.js';
|
|
1
2
|
import type { PhoneInteractiveProvider, PhonePointer, PhoneVideoGeometry, PhoneVideoPacket } from './live-provider.js';
|
|
2
3
|
export { readScrcpyServer, scrcpyServerPath, SCRCPY_VERSION, SCRCPY_SHA256 } from './scrcpy-assets.js';
|
|
3
4
|
/** The pinned server sends codec metadata followed by bounded, length-prefixed packets. */
|
|
@@ -18,6 +19,7 @@ export declare abstract class ScrcpyProvider implements PhoneInteractiveProvider
|
|
|
18
19
|
};
|
|
19
20
|
geometry: PhoneVideoGeometry;
|
|
20
21
|
protected closing: boolean;
|
|
22
|
+
protected textChannel: ScrcpyTextChannel;
|
|
21
23
|
private touch?;
|
|
22
24
|
private listeners;
|
|
23
25
|
private config?;
|
|
@@ -29,6 +31,7 @@ export declare abstract class ScrcpyProvider implements PhoneInteractiveProvider
|
|
|
29
31
|
protected abstract startTransport(): Promise<void>;
|
|
30
32
|
protected abstract write(buffer: Buffer): Promise<void>;
|
|
31
33
|
protected abstract cleanup(): Promise<void>;
|
|
34
|
+
pasteText(text: string, signal: AbortSignal): Promise<void>;
|
|
32
35
|
start(): Promise<void>;
|
|
33
36
|
protected packet(packet: PhoneVideoPacket): void;
|
|
34
37
|
subscribe(listener: (packet: PhoneVideoPacket) => void): () => void;
|
|
@@ -42,6 +45,7 @@ export declare class LocalScrcpyProvider extends ScrcpyProvider {
|
|
|
42
45
|
private adb;
|
|
43
46
|
private serial;
|
|
44
47
|
private tuning;
|
|
48
|
+
private textOnly;
|
|
45
49
|
private process?;
|
|
46
50
|
private video?;
|
|
47
51
|
private control?;
|
|
@@ -51,7 +55,7 @@ export declare class LocalScrcpyProvider extends ScrcpyProvider {
|
|
|
51
55
|
constructor(adb: string, serial: string, onFailure: () => void, tuning?: {
|
|
52
56
|
maxSize: number;
|
|
53
57
|
bitRate: number;
|
|
54
|
-
});
|
|
58
|
+
}, textOnly?: boolean);
|
|
55
59
|
foreground(signal: AbortSignal): Promise<string>;
|
|
56
60
|
protected startTransport(): Promise<void>;
|
|
57
61
|
protected write(buffer: Buffer): Promise<void>;
|
package/dist/src/phone/scrcpy.js
CHANGED
|
@@ -2,6 +2,7 @@ import { PhoneError, init_contracts } from "./contracts.js";
|
|
|
2
2
|
import { spawnPhoneCommand } from "../process/phone-process.js";
|
|
3
3
|
import { SCRCPY_SHA256, SCRCPY_VERSION } from "../runtime-tools/phone-dependency-catalog.js";
|
|
4
4
|
import { readScrcpyServer, scrcpyServerPath } from "./scrcpy-assets.js";
|
|
5
|
+
import { ScrcpyTextChannel } from "./scrcpy-text.js";
|
|
5
6
|
import { AdbPhoneDriver, runAdb } from "./adb-driver.js";
|
|
6
7
|
import { randomBytes } from "node:crypto";
|
|
7
8
|
import { connect } from "node:net";
|
|
@@ -69,6 +70,7 @@ var ScrcpyProvider = class {
|
|
|
69
70
|
codec: ""
|
|
70
71
|
};
|
|
71
72
|
closing = false;
|
|
73
|
+
textChannel = new ScrcpyTextChannel((bytes) => this.write(bytes));
|
|
72
74
|
touch;
|
|
73
75
|
listeners = /* @__PURE__ */ new Set();
|
|
74
76
|
config;
|
|
@@ -78,6 +80,25 @@ var ScrcpyProvider = class {
|
|
|
78
80
|
constructor(onFailure) {
|
|
79
81
|
this.onFailure = onFailure;
|
|
80
82
|
}
|
|
83
|
+
async pasteText(text, signal) {
|
|
84
|
+
signal.throwIfAborted();
|
|
85
|
+
const deadline = AbortSignal.any([signal, AbortSignal.timeout(25e3)]);
|
|
86
|
+
const abort = () => {
|
|
87
|
+
this.close();
|
|
88
|
+
};
|
|
89
|
+
deadline.addEventListener("abort", abort, { once: true });
|
|
90
|
+
try {
|
|
91
|
+
try {
|
|
92
|
+
await this.start();
|
|
93
|
+
deadline.throwIfAborted();
|
|
94
|
+
} catch {
|
|
95
|
+
throw new PhoneError("PHONE_TEXT_INPUT_UNAVAILABLE", "Automatic text input is unavailable. Check Phone settings or take over and type with the phone keyboard.", 409);
|
|
96
|
+
}
|
|
97
|
+
await this.textChannel.paste(text, deadline);
|
|
98
|
+
} finally {
|
|
99
|
+
deadline.removeEventListener("abort", abort);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
81
102
|
start() {
|
|
82
103
|
if (this.closing) return Promise.reject(new PhoneError("PHONE_VIDEO_ENDED", "Phone video ended", 409));
|
|
83
104
|
if (!this.startResult) {
|
|
@@ -144,6 +165,7 @@ var ScrcpyProvider = class {
|
|
|
144
165
|
}
|
|
145
166
|
close() {
|
|
146
167
|
this.closing = true;
|
|
168
|
+
this.textChannel.close();
|
|
147
169
|
return this.closeResult ??= (async () => {
|
|
148
170
|
await this.opening?.catch(() => {});
|
|
149
171
|
try {
|
|
@@ -165,11 +187,12 @@ var LocalScrcpyProvider = class extends ScrcpyProvider {
|
|
|
165
187
|
constructor(adb, serial, onFailure, tuning = {
|
|
166
188
|
maxSize: 960,
|
|
167
189
|
bitRate: 2e6
|
|
168
|
-
}) {
|
|
190
|
+
}, textOnly = false) {
|
|
169
191
|
super(onFailure);
|
|
170
192
|
this.adb = adb;
|
|
171
193
|
this.serial = serial;
|
|
172
194
|
this.tuning = tuning;
|
|
195
|
+
this.textOnly = textOnly;
|
|
173
196
|
}
|
|
174
197
|
foreground(signal) {
|
|
175
198
|
return new AdbPhoneDriver(this.adb).foreground(this.serial, signal);
|
|
@@ -221,7 +244,8 @@ var LocalScrcpyProvider = class extends ScrcpyProvider {
|
|
|
221
244
|
"send_device_meta=false",
|
|
222
245
|
"send_codec_meta=true",
|
|
223
246
|
"send_frame_meta=true",
|
|
224
|
-
"clipboard_autosync=false"
|
|
247
|
+
"clipboard_autosync=false",
|
|
248
|
+
...this.textOnly ? ["video=false", "power_on=false"] : []
|
|
225
249
|
]);
|
|
226
250
|
this.process.once("error", () => this.fail());
|
|
227
251
|
this.process.once("exit", () => this.fail());
|
|
@@ -259,6 +283,21 @@ var LocalScrcpyProvider = class extends ScrcpyProvider {
|
|
|
259
283
|
await setTimeout$1(50);
|
|
260
284
|
}
|
|
261
285
|
if (!this.video) throw new Error("Scrcpy connection timed out");
|
|
286
|
+
if (this.textOnly) {
|
|
287
|
+
this.control = this.video;
|
|
288
|
+
this.video = void 0;
|
|
289
|
+
this.control.setNoDelay(true);
|
|
290
|
+
this.control.on("error", () => this.fail());
|
|
291
|
+
this.control.on("end", () => this.fail());
|
|
292
|
+
this.control.on("data", (data) => {
|
|
293
|
+
try {
|
|
294
|
+
this.textChannel.receive(Buffer.from(data));
|
|
295
|
+
} catch {
|
|
296
|
+
this.fail();
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
262
301
|
const parser = new ScrcpyVideoParser();
|
|
263
302
|
this.video.on("data", (data) => {
|
|
264
303
|
try {
|
|
@@ -276,7 +315,13 @@ var LocalScrcpyProvider = class extends ScrcpyProvider {
|
|
|
276
315
|
this.control.setNoDelay(true);
|
|
277
316
|
this.control.on("error", () => this.fail());
|
|
278
317
|
this.control.on("end", () => this.fail());
|
|
279
|
-
this.control.on("data", () => {
|
|
318
|
+
this.control.on("data", (data) => {
|
|
319
|
+
try {
|
|
320
|
+
this.textChannel.receive(Buffer.from(data));
|
|
321
|
+
} catch {
|
|
322
|
+
this.fail();
|
|
323
|
+
}
|
|
324
|
+
});
|
|
280
325
|
await new Promise((resolve, reject) => {
|
|
281
326
|
this.control.once("connect", resolve);
|
|
282
327
|
this.control.once("error", reject);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PhoneAction, type PhoneElementSelector, type PhoneObservation } from './contracts.js';
|
|
2
|
+
export type PhonePrimitiveAction = Exclude<PhoneAction, {
|
|
3
|
+
type: 'tapElement';
|
|
4
|
+
}>;
|
|
5
|
+
/** Offer exact identities only when one fully visible native node matches. */
|
|
6
|
+
export declare function phoneSemanticControls(screen: PhoneObservation): Array<{
|
|
7
|
+
frameId: string;
|
|
8
|
+
selector: PhoneElementSelector;
|
|
9
|
+
}>;
|
|
10
|
+
/** Ground ordinary model taps only when native hit-testing identifies one bounded control. */
|
|
11
|
+
export declare function groundPhoneCoordinateAction(action: PhoneAction, screen: PhoneObservation): PhoneAction;
|
|
12
|
+
/** Resolve against the prediction snapshot and a fresh snapshot before any dispatch. */
|
|
13
|
+
export declare function resolvePhoneSemanticAction(action: PhoneAction, predicted: PhoneObservation, fresh?: PhoneObservation): PhonePrimitiveAction;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { PhoneActionSchema, PhoneError, init_contracts } from "./contracts.js";
|
|
2
|
+
import { canDispatchPhoneAction } from "./reliability.js";
|
|
3
|
+
//#region src/phone/semantic-controls.ts
|
|
4
|
+
init_contracts();
|
|
5
|
+
function visible(node, screen) {
|
|
6
|
+
const [left, top, right, bottom] = node.bounds;
|
|
7
|
+
return !node.password && node.bounds.every(Number.isFinite) && left >= 0 && top >= 0 && right <= screen.width && bottom <= screen.height && right > left && bottom > top;
|
|
8
|
+
}
|
|
9
|
+
function matches(node, selector) {
|
|
10
|
+
return (selector.resourceId === void 0 || node.resourceId === selector.resourceId) && (selector.text === void 0 || node.text === selector.text) && (selector.description === void 0 || node.description === selector.description);
|
|
11
|
+
}
|
|
12
|
+
function candidates(screen, selector) {
|
|
13
|
+
return screen.elements.filter((node) => visible(node, screen) && matches(node, selector));
|
|
14
|
+
}
|
|
15
|
+
function exactSelector(node) {
|
|
16
|
+
const selector = {};
|
|
17
|
+
if (node.resourceId && node.resourceId.length <= 300) selector.resourceId = node.resourceId;
|
|
18
|
+
if (node.text && node.text.length <= 4e3) selector.text = node.text;
|
|
19
|
+
if (node.description && node.description.length <= 1e3) selector.description = node.description;
|
|
20
|
+
return selector;
|
|
21
|
+
}
|
|
22
|
+
/** Offer exact identities only when one fully visible native node matches. */
|
|
23
|
+
function phoneSemanticControls(screen) {
|
|
24
|
+
return screen.elements.filter((node) => visible(node, screen)).flatMap((node) => {
|
|
25
|
+
const selector = exactSelector(node);
|
|
26
|
+
return Object.keys(selector).length && candidates(screen, selector).length === 1 ? [{
|
|
27
|
+
frameId: screen.frameId,
|
|
28
|
+
selector
|
|
29
|
+
}] : [];
|
|
30
|
+
}).slice(0, 40);
|
|
31
|
+
}
|
|
32
|
+
function containsPoint(node, x, y) {
|
|
33
|
+
return x >= node.bounds[0] && y >= node.bounds[1] && x < node.bounds[2] && y < node.bounds[3];
|
|
34
|
+
}
|
|
35
|
+
function containsNode(outer, inner) {
|
|
36
|
+
return outer.bounds[0] <= inner.bounds[0] && outer.bounds[1] <= inner.bounds[1] && outer.bounds[2] >= inner.bounds[2] && outer.bounds[3] >= inner.bounds[3];
|
|
37
|
+
}
|
|
38
|
+
/** Ground ordinary model taps only when native hit-testing identifies one bounded control. */
|
|
39
|
+
function groundPhoneCoordinateAction(action, screen) {
|
|
40
|
+
if (action.type !== "tap") return action;
|
|
41
|
+
const [x, y] = [action.point[0] * screen.width / 1e3, action.point[1] * screen.height / 1e3];
|
|
42
|
+
if (screen.elements.some((node) => node.password && containsPoint(node, x, y))) return action;
|
|
43
|
+
const actionable = screen.elements.filter((node) => visible(node, screen) && (node.clickable || node.editable));
|
|
44
|
+
const hits = actionable.filter((node) => containsPoint(node, x, y));
|
|
45
|
+
const smallest = hits.filter((node) => hits.every((other) => other === node || containsNode(other, node)));
|
|
46
|
+
if (smallest.length !== 1) return action;
|
|
47
|
+
const target = smallest[0];
|
|
48
|
+
if ((target.bounds[2] - target.bounds[0]) * (target.bounds[3] - target.bounds[1]) > screen.width * screen.height / 4) return action;
|
|
49
|
+
const selector = exactSelector(target);
|
|
50
|
+
if (!Object.keys(selector).length || candidates(screen, selector).length !== 1) return action;
|
|
51
|
+
const [centerX, centerY] = [(target.bounds[0] + target.bounds[2]) / 2, (target.bounds[1] + target.bounds[3]) / 2];
|
|
52
|
+
if (screen.elements.some((node) => node.password && containsPoint(node, centerX, centerY)) || actionable.some((node) => node !== target && containsPoint(node, centerX, centerY) && !containsNode(node, target))) return action;
|
|
53
|
+
return {
|
|
54
|
+
type: "tapElement",
|
|
55
|
+
frameId: screen.frameId,
|
|
56
|
+
selector
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Resolve against the prediction snapshot and a fresh snapshot before any dispatch. */
|
|
60
|
+
function resolvePhoneSemanticAction(action, predicted, fresh = predicted) {
|
|
61
|
+
if (action.type !== "tapElement") return action;
|
|
62
|
+
if (!PhoneActionSchema.safeParse(action).success) throw new PhoneError("PHONE_SEMANTIC_INVALID", "Invalid exact native element selector", 409);
|
|
63
|
+
if (action.frameId !== predicted.frameId) throw new PhoneError("PHONE_SEMANTIC_STALE", "Native element belongs to a different observation", 409);
|
|
64
|
+
const before = candidates(predicted, action.selector);
|
|
65
|
+
const after = candidates(fresh, action.selector);
|
|
66
|
+
if (before.length !== 1 || after.length !== 1) throw new PhoneError("PHONE_SEMANTIC_TARGET", "Native element selector must match exactly one fully visible non-password node", 409);
|
|
67
|
+
const target = after[0];
|
|
68
|
+
const resolved = {
|
|
69
|
+
type: "tap",
|
|
70
|
+
point: [500 * (target.bounds[0] + target.bounds[2]) / fresh.width, 500 * (target.bounds[1] + target.bounds[3]) / fresh.height]
|
|
71
|
+
};
|
|
72
|
+
if (JSON.stringify(before[0]) !== JSON.stringify(target) || !canDispatchPhoneAction(resolved, predicted, fresh)) throw new PhoneError("PHONE_SEMANTIC_STALE", "Native element or page changed before dispatch", 409);
|
|
73
|
+
return resolved;
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { groundPhoneCoordinateAction, phoneSemanticControls, resolvePhoneSemanticAction };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import type { PhoneSetupView } from '@xopcai/gateway-contract';
|
|
2
|
+
import type { PhoneInput } from '../contracts.js';
|
|
3
|
+
import type { PhoneRuntime } from '../runtime.js';
|
|
4
|
+
type Context = {
|
|
5
|
+
conversationId: string;
|
|
6
|
+
agentId: string;
|
|
7
|
+
};
|
|
8
|
+
type Setup = Omit<PhoneSetupView, 'readiness' | 'stale' | 'settingsPath' | 'guidanceRefs'> & {
|
|
9
|
+
environmentRevision?: string;
|
|
10
|
+
calls: number;
|
|
11
|
+
owner?: string;
|
|
12
|
+
};
|
|
13
|
+
export interface PhoneSetupDeps {
|
|
14
|
+
runtime: PhoneRuntime;
|
|
15
|
+
inspect(context: Context, source?: 'local' | 'aliyun'): Promise<PhoneSetupView['readiness']>;
|
|
16
|
+
revision(context: Context, deviceId: string): string;
|
|
17
|
+
connected(deviceId: string, signal?: AbortSignal): Promise<boolean>;
|
|
18
|
+
leaseActive(deviceId: string): boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Setup only orchestrates existing settings; secrets and configuration writes stay in product forms. */
|
|
21
|
+
export declare class PhoneSetupService {
|
|
22
|
+
private readonly deps;
|
|
23
|
+
constructor(deps: PhoneSetupDeps);
|
|
24
|
+
private store;
|
|
25
|
+
current(context: Context): Setup;
|
|
26
|
+
private save;
|
|
27
|
+
private owned;
|
|
28
|
+
view(context: Context, setup: Setup): Promise<PhoneSetupView>;
|
|
29
|
+
command(command: string, args: Record<string, unknown>, context: Context, dryRun?: boolean): Promise<PhoneSetupView | {
|
|
30
|
+
dryRun?: boolean;
|
|
31
|
+
sceneId: string;
|
|
32
|
+
skillName: string;
|
|
33
|
+
readiness: {
|
|
34
|
+
enabled: boolean;
|
|
35
|
+
toolAllowed: boolean;
|
|
36
|
+
model: {
|
|
37
|
+
ref?: string;
|
|
38
|
+
chatRef?: string;
|
|
39
|
+
source?: "system" | "global" | "agent";
|
|
40
|
+
supported: boolean;
|
|
41
|
+
configured: boolean;
|
|
42
|
+
};
|
|
43
|
+
dependencies: Array<{
|
|
44
|
+
kind: "adb" | "scrcpy";
|
|
45
|
+
state: string;
|
|
46
|
+
version?: string;
|
|
47
|
+
canInstall: boolean;
|
|
48
|
+
}>;
|
|
49
|
+
devices: Array<{
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
source: "local" | "aliyun";
|
|
53
|
+
enabled: boolean;
|
|
54
|
+
settingsAllowed: boolean;
|
|
55
|
+
}>;
|
|
56
|
+
localDiscovery: Array<{
|
|
57
|
+
name: string;
|
|
58
|
+
state: string;
|
|
59
|
+
emulator: boolean;
|
|
60
|
+
}>;
|
|
61
|
+
diagnostic?: string;
|
|
62
|
+
};
|
|
63
|
+
setup: PhoneSetupView;
|
|
64
|
+
settingsPath: string;
|
|
65
|
+
guidanceRefs: {
|
|
66
|
+
sceneId: string;
|
|
67
|
+
path: string;
|
|
68
|
+
resourceVersion: string;
|
|
69
|
+
}[];
|
|
70
|
+
} | {
|
|
71
|
+
message: string;
|
|
72
|
+
id: string;
|
|
73
|
+
conversationId: string;
|
|
74
|
+
agentId: string;
|
|
75
|
+
revision: number;
|
|
76
|
+
state: "configuring" | "verifying" | "completed" | "needs_attention" | "cancelled";
|
|
77
|
+
source?: "local" | "aliyun";
|
|
78
|
+
error?: string;
|
|
79
|
+
stale: boolean;
|
|
80
|
+
settingsPath: string;
|
|
81
|
+
readiness: {
|
|
82
|
+
enabled: boolean;
|
|
83
|
+
toolAllowed: boolean;
|
|
84
|
+
model: {
|
|
85
|
+
ref?: string;
|
|
86
|
+
chatRef?: string;
|
|
87
|
+
source?: "system" | "global" | "agent";
|
|
88
|
+
supported: boolean;
|
|
89
|
+
configured: boolean;
|
|
90
|
+
};
|
|
91
|
+
dependencies: Array<{
|
|
92
|
+
kind: "adb" | "scrcpy";
|
|
93
|
+
state: string;
|
|
94
|
+
version?: string;
|
|
95
|
+
canInstall: boolean;
|
|
96
|
+
}>;
|
|
97
|
+
devices: Array<{
|
|
98
|
+
id: string;
|
|
99
|
+
name: string;
|
|
100
|
+
source: "local" | "aliyun";
|
|
101
|
+
enabled: boolean;
|
|
102
|
+
settingsAllowed: boolean;
|
|
103
|
+
}>;
|
|
104
|
+
localDiscovery: Array<{
|
|
105
|
+
name: string;
|
|
106
|
+
state: string;
|
|
107
|
+
emulator: boolean;
|
|
108
|
+
}>;
|
|
109
|
+
diagnostic?: string;
|
|
110
|
+
};
|
|
111
|
+
checks: {
|
|
112
|
+
configured: boolean;
|
|
113
|
+
read: boolean;
|
|
114
|
+
operated: boolean;
|
|
115
|
+
verified: boolean;
|
|
116
|
+
released: boolean;
|
|
117
|
+
};
|
|
118
|
+
attempt?: {
|
|
119
|
+
id: string;
|
|
120
|
+
deviceId: string;
|
|
121
|
+
modelRef: string;
|
|
122
|
+
sessionId?: string;
|
|
123
|
+
goal: string;
|
|
124
|
+
completion: {
|
|
125
|
+
appPackage: string;
|
|
126
|
+
textAny: string[];
|
|
127
|
+
requireChange: boolean;
|
|
128
|
+
};
|
|
129
|
+
maxActions: number;
|
|
130
|
+
expiresAt: number;
|
|
131
|
+
released: boolean;
|
|
132
|
+
};
|
|
133
|
+
guidanceRefs: Array<{
|
|
134
|
+
sceneId: "phone";
|
|
135
|
+
path: string;
|
|
136
|
+
resourceVersion: string;
|
|
137
|
+
}>;
|
|
138
|
+
}>;
|
|
139
|
+
source(context: Context, id: string, source: 'local' | 'aliyun', revision: number): Promise<PhoneSetupView>;
|
|
140
|
+
begin(context: Context, id: string, deviceId: string, revision: number, signal?: AbortSignal): Promise<PhoneSetupView>;
|
|
141
|
+
beforeInput(context: Context, input: PhoneInput): {
|
|
142
|
+
owner: string;
|
|
143
|
+
input: PhoneInput;
|
|
144
|
+
} | undefined;
|
|
145
|
+
afterInput(context: Context, owner: string, op: PhoneInput['op']): void;
|
|
146
|
+
release(context: Context, id: string): Promise<PhoneSetupView>;
|
|
147
|
+
}
|
|
148
|
+
export {};
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { DurableState } from "../../storage/sqlite/durable-state.js";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
//#region src/phone/setup/service.ts
|
|
4
|
+
/** Setup only orchestrates existing settings; secrets and configuration writes stay in product forms. */
|
|
5
|
+
var PhoneSetupService = class {
|
|
6
|
+
constructor(deps) {
|
|
7
|
+
this.deps = deps;
|
|
8
|
+
}
|
|
9
|
+
store(context) {
|
|
10
|
+
return new DurableState("phone.setup", context.conversationId);
|
|
11
|
+
}
|
|
12
|
+
current(context) {
|
|
13
|
+
return this.store(context).get(context.agentId);
|
|
14
|
+
}
|
|
15
|
+
save(context, next, expected = next.revision) {
|
|
16
|
+
return this.store(context).update(context.agentId, (previous) => {
|
|
17
|
+
if (previous && previous.revision !== expected) throw new Error("PHONE_SETUP_CONFLICT: Refresh the saved progress.");
|
|
18
|
+
const value = {
|
|
19
|
+
...next,
|
|
20
|
+
revision: expected + 1
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
value,
|
|
24
|
+
result: value
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
owned(context, id) {
|
|
29
|
+
const setup = this.current(context);
|
|
30
|
+
if (!setup || setup.id !== id) throw new Error("PHONE_SETUP_NOT_FOUND");
|
|
31
|
+
return setup;
|
|
32
|
+
}
|
|
33
|
+
async view(context, setup) {
|
|
34
|
+
const { owner: _owner, calls: _calls, environmentRevision: _revision, ...summary } = setup;
|
|
35
|
+
const stale = Boolean(setup.attempt && setup.environmentRevision !== this.deps.revision(context, setup.attempt.deviceId));
|
|
36
|
+
const interrupted = setup.state === "verifying" && (Date.now() > setup.attempt.expiresAt || Boolean(setup.attempt?.sessionId && !this.deps.runtime.status(setup.owner)));
|
|
37
|
+
return {
|
|
38
|
+
...summary,
|
|
39
|
+
stale,
|
|
40
|
+
state: interrupted ? "needs_attention" : setup.state,
|
|
41
|
+
error: interrupted ? "PHONE_SETUP_INTERRUPTED: Release or confirm lease expiry before starting a fresh test." : setup.error,
|
|
42
|
+
readiness: await this.deps.inspect(context, setup.source),
|
|
43
|
+
settingsPath: `/settings/phone-use?phoneSetup=${setup.id}&conversationId=${context.conversationId}`,
|
|
44
|
+
guidanceRefs: [{
|
|
45
|
+
sceneId: "phone",
|
|
46
|
+
path: `references/phone/${setup.state === "verifying" ? "acceptance" : setup.error || interrupted || stale ? "troubleshooting" : setup.source === "aliyun" ? "aliyun" : setup.source === "local" ? "local" : "overview"}.md`,
|
|
47
|
+
resourceVersion: "1"
|
|
48
|
+
}]
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async command(command, args, context, dryRun = false) {
|
|
52
|
+
let setup = this.current(context);
|
|
53
|
+
if (command === "inspect" || command === "preview" || dryRun) return {
|
|
54
|
+
sceneId: "phone",
|
|
55
|
+
skillName: "configure-xopc",
|
|
56
|
+
readiness: await this.deps.inspect(context, setup?.source),
|
|
57
|
+
setup: setup ? await this.view(context, setup) : null,
|
|
58
|
+
settingsPath: `/settings/phone-use?conversationId=${context.conversationId}`,
|
|
59
|
+
guidanceRefs: [{
|
|
60
|
+
sceneId: "phone",
|
|
61
|
+
path: "references/phone/overview.md",
|
|
62
|
+
resourceVersion: "1"
|
|
63
|
+
}],
|
|
64
|
+
...dryRun ? { dryRun: true } : {}
|
|
65
|
+
};
|
|
66
|
+
if (command === "start") {
|
|
67
|
+
if (!setup || ["completed", "cancelled"].includes(setup.state) && (!setup.attempt || setup.attempt.released)) setup = this.save(context, {
|
|
68
|
+
id: randomUUID(),
|
|
69
|
+
...context,
|
|
70
|
+
state: "configuring",
|
|
71
|
+
revision: setup?.revision ?? 0,
|
|
72
|
+
calls: 0,
|
|
73
|
+
checks: {
|
|
74
|
+
configured: false,
|
|
75
|
+
read: false,
|
|
76
|
+
operated: false,
|
|
77
|
+
verified: false,
|
|
78
|
+
released: false
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return this.view(context, setup);
|
|
82
|
+
}
|
|
83
|
+
if (typeof args.setupId !== "string") throw new Error("setupId is required");
|
|
84
|
+
setup = this.owned(context, args.setupId);
|
|
85
|
+
if ([
|
|
86
|
+
"get",
|
|
87
|
+
"recheck",
|
|
88
|
+
"verification_report"
|
|
89
|
+
].includes(command)) return this.view(context, setup);
|
|
90
|
+
if (command === "begin_verification") return {
|
|
91
|
+
...await this.view(context, setup),
|
|
92
|
+
message: "Choose the phone and approve the Settings-only test in the original conversation panel."
|
|
93
|
+
};
|
|
94
|
+
if (command === "cancel") {
|
|
95
|
+
setup = this.save(context, {
|
|
96
|
+
...setup,
|
|
97
|
+
state: "cancelled"
|
|
98
|
+
});
|
|
99
|
+
return this.release(context, setup.id);
|
|
100
|
+
}
|
|
101
|
+
throw new Error("Unsupported phone_setup command");
|
|
102
|
+
}
|
|
103
|
+
async source(context, id, source, revision) {
|
|
104
|
+
const setup = this.owned(context, id);
|
|
105
|
+
if (setup.revision !== revision || setup.attempt && !setup.attempt.released) throw new Error("PHONE_SETUP_CONFLICT: Release the active test before changing connection.");
|
|
106
|
+
if (setup.state === "cancelled" || setup.state === "completed") throw new Error("PHONE_SETUP_CLOSED: Start a new setup before changing connection.");
|
|
107
|
+
return this.view(context, this.save(context, {
|
|
108
|
+
...setup,
|
|
109
|
+
source
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
async begin(context, id, deviceId, revision, signal) {
|
|
113
|
+
let setup = this.owned(context, id);
|
|
114
|
+
if (setup.revision !== revision || setup.state === "cancelled" || setup.attempt && !setup.attempt.released) throw new Error("PHONE_SETUP_CONFLICT: Refresh progress and release the old test.");
|
|
115
|
+
const environmentRevision = this.deps.revision(context, deviceId);
|
|
116
|
+
const readiness = await this.deps.inspect(context, setup.source);
|
|
117
|
+
const device = readiness.devices.find((device) => device.id === deviceId);
|
|
118
|
+
if (!readiness.enabled || !readiness.toolAllowed) throw new Error("PHONE_SETUP_PERMISSION_REQUIRED: Enable Phone Use and allow this Agent in product settings.");
|
|
119
|
+
if (!readiness.model.ref || !readiness.model.supported || !readiness.model.configured) throw new Error("PHONE_SETUP_MODEL_REQUIRED: Save a configured real Phone Use model.");
|
|
120
|
+
if (!device?.enabled || !device.settingsAllowed) throw new Error("PHONE_SETUP_DEVICE_REQUIRED: Choose an enabled phone allowing Settings.");
|
|
121
|
+
if (setup.source && setup.source !== device.source) throw new Error("PHONE_SETUP_SOURCE_MISMATCH");
|
|
122
|
+
if (device.source === "local" && !readiness.dependencies.some((item) => item.kind === "adb" && item.state === "ready")) throw new Error("PHONE_SETUP_ADB_REQUIRED");
|
|
123
|
+
if (!await this.deps.connected(deviceId, signal)) throw new Error("PHONE_SETUP_DEVICE_OFFLINE: Authorize USB debugging or check cloud connection.");
|
|
124
|
+
const latest = this.owned(context, id);
|
|
125
|
+
if (latest.revision !== revision || environmentRevision !== this.deps.revision(context, deviceId)) throw new Error("PHONE_SETUP_CONFLICT");
|
|
126
|
+
const attempt = {
|
|
127
|
+
id: randomUUID(),
|
|
128
|
+
deviceId,
|
|
129
|
+
modelRef: readiness.model.ref,
|
|
130
|
+
goal: "From the Android Settings About phone page, open Android version details and read the version. Do not change any setting.",
|
|
131
|
+
completion: {
|
|
132
|
+
appPackage: "com.android.settings",
|
|
133
|
+
textAny: [
|
|
134
|
+
"Android version",
|
|
135
|
+
"Android 版本",
|
|
136
|
+
"Android版本"
|
|
137
|
+
],
|
|
138
|
+
requireChange: true
|
|
139
|
+
},
|
|
140
|
+
maxActions: 6,
|
|
141
|
+
expiresAt: Date.now() + 3e5,
|
|
142
|
+
released: false
|
|
143
|
+
};
|
|
144
|
+
setup = this.save(context, {
|
|
145
|
+
...latest,
|
|
146
|
+
state: "verifying",
|
|
147
|
+
source: device.source,
|
|
148
|
+
error: void 0,
|
|
149
|
+
attempt,
|
|
150
|
+
owner: `phone-setup:${latest.id}:${attempt.id}`,
|
|
151
|
+
environmentRevision,
|
|
152
|
+
calls: 0,
|
|
153
|
+
checks: {
|
|
154
|
+
configured: true,
|
|
155
|
+
read: false,
|
|
156
|
+
operated: false,
|
|
157
|
+
verified: false,
|
|
158
|
+
released: false
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
return this.view(context, setup);
|
|
162
|
+
}
|
|
163
|
+
beforeInput(context, input) {
|
|
164
|
+
const setup = this.current(context);
|
|
165
|
+
if (!setup?.attempt || setup.attempt.released || input.op === "discover") return void 0;
|
|
166
|
+
const cleanup = input.op === "close" || input.op === "cancel";
|
|
167
|
+
if (!cleanup && (setup.state !== "verifying" || Date.now() > setup.attempt.expiresAt || setup.calls >= 12 || setup.environmentRevision !== this.deps.revision(context, setup.attempt.deviceId))) throw new Error("PHONE_SETUP_STOPPED: Release the setup test and review the current state.");
|
|
168
|
+
if (!(cleanup || input.op === "status" || input.op === "observe" || input.op === "pause" || input.op === "open" && input.deviceId === setup.attempt.deviceId && input.mode === "control" && input.appPackage === "com.android.settings" || (input.op === "run" || input.op === "step") && input.goal === setup.attempt.goal && !input.scenario && input.completion?.appPackage === setup.attempt.completion.appPackage && input.completion.requireChange === true && JSON.stringify(input.completion.textAny) === JSON.stringify(setup.attempt.completion.textAny) && !input.completion.textAll && !input.completion.field && (input.maxActions ?? 6) <= 6)) throw new Error("PHONE_SETUP_ACTION_DENIED: Use only the approved Settings test.");
|
|
169
|
+
this.save(context, {
|
|
170
|
+
...setup,
|
|
171
|
+
calls: setup.calls + 1
|
|
172
|
+
});
|
|
173
|
+
if (input.op === "run" || input.op === "step") {
|
|
174
|
+
const report = this.deps.runtime.status(setup.owner);
|
|
175
|
+
const openingActions = report?.steps[0]?.action === "launch" ? 1 : 0;
|
|
176
|
+
const remaining = 6 - Math.max(0, (report?.actions ?? 0) - openingActions);
|
|
177
|
+
if (remaining <= 0) throw new Error("PHONE_SETUP_BUDGET_EXHAUSTED: Close the test and review its evidence.");
|
|
178
|
+
return {
|
|
179
|
+
owner: setup.owner,
|
|
180
|
+
input: {
|
|
181
|
+
...input,
|
|
182
|
+
maxActions: Math.min(input.maxActions ?? 6, remaining)
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
owner: setup.owner,
|
|
188
|
+
input: input.op === "open" ? {
|
|
189
|
+
...input,
|
|
190
|
+
settingsPage: "about-phone"
|
|
191
|
+
} : input
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
afterInput(context, owner, op) {
|
|
195
|
+
const setup = this.current(context);
|
|
196
|
+
if (!setup?.attempt || setup.owner !== owner) return;
|
|
197
|
+
const report = this.deps.runtime.status(owner);
|
|
198
|
+
if (!report || report.deviceId !== setup.attempt.deviceId || report.modelRef !== setup.attempt.modelRef || setup.attempt.sessionId && report.sessionId !== setup.attempt.sessionId) return;
|
|
199
|
+
const released = op === "close" && report.status === "closed" && report.controlOwner === "none";
|
|
200
|
+
const valid = setup.state === "verifying" && setup.environmentRevision === this.deps.revision(context, report.deviceId) && Date.now() <= setup.attempt.expiresAt;
|
|
201
|
+
const modelActions = Math.max(0, report.actions - (report.steps[0]?.action === "launch" ? 1 : 0));
|
|
202
|
+
const verified = valid && !report.mock && report.mode === "control" && report.verified && report.verificationLevel === "ui" && report.modelRequests > 0 && modelActions > 0;
|
|
203
|
+
const checks = {
|
|
204
|
+
...setup.checks,
|
|
205
|
+
...valid ? {
|
|
206
|
+
read: setup.checks.read || Boolean(report.facts?.length),
|
|
207
|
+
operated: setup.checks.operated || modelActions > 0,
|
|
208
|
+
verified: setup.checks.verified || verified
|
|
209
|
+
} : {},
|
|
210
|
+
released: setup.checks.released || released
|
|
211
|
+
};
|
|
212
|
+
this.save(context, {
|
|
213
|
+
...setup,
|
|
214
|
+
checks,
|
|
215
|
+
attempt: {
|
|
216
|
+
...setup.attempt,
|
|
217
|
+
sessionId: report.sessionId,
|
|
218
|
+
released: checks.released
|
|
219
|
+
},
|
|
220
|
+
state: setup.state === "cancelled" ? "cancelled" : released ? valid && checks.verified && checks.read ? "completed" : "needs_attention" : setup.state,
|
|
221
|
+
error: released && !(valid && checks.verified && checks.read) ? report.errorCode === "PHONE_MODEL_QUOTA_EXHAUSTED" ? "PHONE_MODEL_QUOTA_EXHAUSTED: Wait for the Phone model quota to reset or select a configured compatible model; device control was released." : "PHONE_SETUP_INCOMPLETE: Review progress and start a fresh test." : setup.error
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
async release(context, id) {
|
|
225
|
+
let setup = this.owned(context, id);
|
|
226
|
+
if (!setup.attempt || setup.attempt.released) return this.view(context, setup);
|
|
227
|
+
if (!this.deps.runtime.status(setup.owner)) {
|
|
228
|
+
if (this.deps.leaseActive(setup.attempt.deviceId)) throw new Error("PHONE_SETUP_LEASE_PENDING: Control expiry is not confirmed yet. Wait and recheck.");
|
|
229
|
+
setup = this.save(context, {
|
|
230
|
+
...setup,
|
|
231
|
+
state: setup.state === "cancelled" ? "cancelled" : "needs_attention",
|
|
232
|
+
attempt: {
|
|
233
|
+
...setup.attempt,
|
|
234
|
+
released: true
|
|
235
|
+
},
|
|
236
|
+
checks: {
|
|
237
|
+
...setup.checks,
|
|
238
|
+
released: true
|
|
239
|
+
},
|
|
240
|
+
error: "PHONE_SETUP_RESTARTED: Lease expiry confirmed; start a fresh test."
|
|
241
|
+
});
|
|
242
|
+
} else {
|
|
243
|
+
await this.deps.runtime.stop(setup.owner, "close");
|
|
244
|
+
this.afterInput(context, setup.owner, "close");
|
|
245
|
+
setup = this.owned(context, id);
|
|
246
|
+
}
|
|
247
|
+
return this.view(context, setup);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
//#endregion
|
|
251
|
+
export { PhoneSetupService };
|
|
@@ -239,7 +239,7 @@ function modelToCatalogView(model) {
|
|
|
239
239
|
...model.contextWindow ? { contextWindow: model.contextWindow } : {},
|
|
240
240
|
...model.maxTokens ? { maxTokens: model.maxTokens } : {},
|
|
241
241
|
vision: input.includes("image"),
|
|
242
|
-
recommended: !isDedicatedComputerModel(model) && isRecommendedModel(model.provider, model.id)
|
|
242
|
+
recommended: !("phoneUse" in model && model.phoneUse) && !isDedicatedComputerModel(model) && isRecommendedModel(model.provider, model.id)
|
|
243
243
|
};
|
|
244
244
|
}
|
|
245
245
|
function presetModelToCatalogView(provider, model) {
|
|
@@ -267,7 +267,7 @@ function sortModelsForPicker(models) {
|
|
|
267
267
|
});
|
|
268
268
|
}
|
|
269
269
|
function getRecommendedModelsForProvider(provider, limit = 4) {
|
|
270
|
-
const fromRegistry = sortModelsForPicker(getModelsByProvider(provider)).filter((model) => !isDedicatedComputerModel(model) && isRecommendedModel(provider, model.id)).slice(0, limit).map(modelToCatalogView);
|
|
270
|
+
const fromRegistry = sortModelsForPicker(getModelsByProvider(provider)).filter((model) => !("phoneUse" in model && model.phoneUse) && !isDedicatedComputerModel(model) && isRecommendedModel(provider, model.id)).slice(0, limit).map(modelToCatalogView);
|
|
271
271
|
if (fromRegistry.length > 0) return fromRegistry;
|
|
272
272
|
const preset = getDomesticProviderPreset(provider);
|
|
273
273
|
if (!preset) return [];
|