@xopcai/xopc 0.0.353 → 0.0.354
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-YogQEteU.js +1 -0
- package/dist/gateway/static/root/assets/activity-store-X7CG9pzB.js +1 -0
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BVIuZcCP.js → agent-avatar-dicebear-B8PS1eLP.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CLBSL9hl.js +1 -0
- package/dist/gateway/static/root/assets/agent-plugin-dialog-BninweSg.js +1 -0
- package/dist/gateway/static/root/assets/agents-CcVLP_WP.js +66 -0
- package/dist/gateway/static/root/assets/app-chrome-BeB4KgOf.js +1 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-COdQOmdT.js +1 -0
- package/dist/gateway/static/root/assets/appearance-settings-CDNjc2yy.js +1 -0
- package/dist/gateway/static/root/assets/apps-page-C-kvpPj8.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BZXXJvpX.js → archive-plugin-QfOaQPL_.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-C7VKkDb5.js → automations-page-87DN5nXX.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BdZ8NO8k.js +7 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DoT3g5SP.js → binary-plugins-BF2lVwR9.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-sqqrCafh.js → block-editor-B04Kv5DU.js} +39 -39
- package/dist/gateway/static/root/assets/bot-DjLkhyZL.js +1 -0
- package/dist/gateway/static/root/assets/{browser-automation-inputs-CZOKsAaa.js → browser-automation-inputs-FW3bYZ-z.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-TEeTmkGP.js → browser-automations-page-Ck6Zb9aU.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-DHlyYItE.js +3 -0
- package/dist/gateway/static/root/assets/{capabilities-BOrLei_L.js → capabilities-BCF_160Z.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-CF4-mrIa.js +1 -0
- package/dist/gateway/static/root/assets/capabilities-page-C-6RLFNh.js +2 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CST_HBkR.js +8 -0
- package/dist/gateway/static/root/assets/capability-header-actions-PBPJJsp6.js +1 -0
- package/dist/gateway/static/root/assets/channels-CM4sIvcP.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-Q99iKyiO.js → chat-terminal-dock-DTd7mWyE.js} +2 -2
- package/dist/gateway/static/root/assets/chevron-right-BweFrslA.js +1 -0
- package/dist/gateway/static/root/assets/circle-alert-BEjgurr2.js +1 -0
- package/dist/gateway/static/root/assets/circle-dashed-8qMD7gHf.js +1 -0
- package/dist/gateway/static/root/assets/circle-dot-BAseJTrF.js +1 -0
- package/dist/gateway/static/root/assets/circle-pause-CN9jYH2s.js +1 -0
- package/dist/gateway/static/root/assets/clock-3-DnrAnuyZ.js +1 -0
- package/dist/gateway/static/root/assets/cloud-C4-yfnnk.js +1 -0
- package/dist/gateway/static/root/assets/computer-settings-page--9rh1mvu.js +1 -0
- package/dist/gateway/static/root/assets/connector-service-page-v6Is0BOO.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-CryQzmEZ.js +2 -0
- package/dist/gateway/static/root/assets/copy-text-row-BHDs3cBa.js +1 -0
- package/dist/gateway/static/root/assets/date-picker-DTsMzjoZ.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-BjH8XrKb.js → dependency-picker-Y1QYCcLp.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DyGxNAVW.js → desktop-pet-D9dfZrOp.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-BHVOHZUL.js +1 -0
- package/dist/gateway/static/root/assets/device-pairing-wizard-Cy5YDZ2b.js +1 -0
- package/dist/gateway/static/root/assets/directory-picker-path-field-DeMo9KlE.js +1 -0
- package/dist/gateway/static/root/assets/dist-3h6cXXhT.js +1 -0
- package/dist/gateway/static/root/assets/dist-Che_jiQF.js +1 -0
- package/dist/gateway/static/root/assets/extension-debug-page-BrGWLJg9.js +1 -0
- package/dist/gateway/static/root/assets/extension-page-AWrvy1Nb.js +1 -0
- package/dist/gateway/static/root/assets/extension-provider-CUpbXB2k.js +1 -0
- package/dist/gateway/static/root/assets/extension-settings-page-C5KgmhYu.js +1 -0
- package/dist/gateway/static/root/assets/form-field-width-DJw_jULe.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-DC-lok0J.js +1 -0
- package/dist/gateway/static/root/assets/git-branch-Dh9uxTot.js +1 -0
- package/dist/gateway/static/root/assets/home-page-C29_VFAs.js +1 -0
- package/dist/gateway/static/root/assets/imports-page-BKVKfVMA.js +1 -0
- package/dist/gateway/static/root/assets/index-BJh5gU04.css +1 -0
- package/dist/gateway/static/root/assets/index-ByFXhQ-T.js +107 -0
- package/dist/gateway/static/root/assets/index.module-Cd9ENXfk.js +1 -0
- package/dist/gateway/static/root/assets/interaction-BdhHBbYa.js +1 -0
- package/dist/gateway/static/root/assets/is-masked-secret-DOkL5b_X.js +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CoYdyBRh.js → keyboard-shortcuts-settings-DiwE4gKU.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-Dt3TC64L.js +1 -0
- package/dist/gateway/static/root/assets/{local-apps-page-CeBhXeoX.js → local-apps-page-DFPhWkxU.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-C4faHZHj.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-pZLdvIiw.js +1 -0
- package/dist/gateway/static/root/assets/markdown-view-7tzqIp_G.js +201 -0
- package/dist/gateway/static/root/assets/{media-plugins-C9ya5rUH.js → media-plugins-cjgrKnne.js} +1 -1
- package/dist/gateway/static/root/assets/message-square-fVE7Ghj1.js +1 -0
- package/dist/gateway/static/root/assets/mic-CuUb7zc-.js +1 -0
- package/dist/gateway/static/root/assets/model-display-name-DXhO9rcM.js +1 -0
- package/dist/gateway/static/root/assets/models-hub-cache-HGrORbzR.js +1 -0
- package/dist/gateway/static/root/assets/note-detail-panel-BLnT1tYJ.js +5 -0
- package/dist/gateway/static/root/assets/notes-api-J0yhflxC.js +1 -0
- package/dist/gateway/static/root/assets/notes-page-BawArJvP.js +8 -0
- package/dist/gateway/static/root/assets/oauth-api-CYe61zfD.js +1 -0
- package/dist/gateway/static/root/assets/page-context-capture-button-CiBUm2Br.js +1 -0
- package/dist/gateway/static/root/assets/page-tabs-D2xpUV26.js +1 -0
- package/dist/gateway/static/root/assets/pause-DuPxgSxk.js +1 -0
- package/dist/gateway/static/root/assets/personal-page-Cng583RH.js +1 -0
- package/dist/gateway/static/root/assets/play-kxZvpBg8.js +1 -0
- package/dist/gateway/static/root/assets/popover-select-DcsFzD_i.js +1 -0
- package/dist/gateway/static/root/assets/preview-open-alternatives-Dvey7GwU.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-DUPsiVP9.js → product-open-page-B8_w6c3J.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-CDZdKiTz.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-BvahSrZi.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CU_UdkuI.js +1 -0
- package/dist/gateway/static/root/assets/rotate-ccw-JM1TBLpp.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-C25xEYTK.js → runtime-tools-settings-panel-BnMS50vK.js} +2 -2
- package/dist/gateway/static/root/assets/scenes-page-CDR1-q25.js +2 -0
- package/dist/gateway/static/root/assets/schema-form-B4Xa8w8S.js +1 -0
- package/dist/gateway/static/root/assets/secret-input-DPl3VYM8.js +1 -0
- package/dist/gateway/static/root/assets/send-session-input-C7Nqy0sK.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-Ymyg98G-.js +1 -0
- package/dist/gateway/static/root/assets/settings-2-D-csvaET.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-wMZhxwTM.js +1 -0
- package/dist/gateway/static/root/assets/settings-form-draft-Dy10ldo8.js +1 -0
- package/dist/gateway/static/root/assets/settings-form-section-exRhP9xn.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-DqCJHcdG.js → settings-page-CHZdpvkT.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-HESfALIF.js +1 -0
- package/dist/gateway/static/root/assets/share-link-dialog-COlX10Dc.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-NtRLUieq.js +2 -0
- package/dist/gateway/static/root/assets/shares-api-DICV5EKH.js +1 -0
- package/dist/gateway/static/root/assets/shares-settings-CXEBo5YL.js +1 -0
- package/dist/gateway/static/root/assets/skill-api-DYgcO7y0.js +1 -0
- package/dist/gateway/static/root/assets/skill-api-utils-C7V4JVXM.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CWH3Fmx4.js +1 -0
- package/dist/gateway/static/root/assets/skill-wire-pattern-BPpeIcCi.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-Dx5v64jU.js +2 -0
- package/dist/gateway/static/root/assets/sparkles-DHlfQFAF.js +1 -0
- package/dist/gateway/static/root/assets/system-settings-panel-wXCBwYwE.js +1 -0
- package/dist/gateway/static/root/assets/task-detail-page-hoIyr7tp.js +1 -0
- package/dist/gateway/static/root/assets/tasks-Buv1mgPF.js +1 -0
- package/dist/gateway/static/root/assets/theme-store-BKgBPLH4.js +1 -0
- package/dist/gateway/static/root/assets/tunnel-api-C0t8y3Mi.js +1 -0
- package/dist/gateway/static/root/assets/usage-page-A2DZAidl.js +1 -0
- package/dist/gateway/static/root/assets/use-async-resource-GrnWNwMZ.js +1 -0
- package/dist/gateway/static/root/assets/use-autosave-Cn6hqqyM.js +1 -0
- package/dist/gateway/static/root/assets/use-composer-attachments-DL61XeSu.js +2 -0
- package/dist/gateway/static/root/assets/use-file-preview-expanded-Cl9mU32w.js +2 -0
- package/dist/gateway/static/root/assets/user-model-page-C1jGTwjK.js +2 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-Bw05QB_V.js +1 -0
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BnfD6w0k.js → work-discovery-overlay-xB0QpOFk.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DSy57rBr.js → workflow-run-setup-panel-rM4U1FXc.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-QKC34FzQ.js +6 -0
- package/dist/gateway/static/root/assets/workspace-api-BbBT75Kg.js +2 -0
- package/dist/gateway/static/root/index.html +61 -19
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/tasks.js +19 -2
- package/dist/src/agent/agent-manager.js +7 -7
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/run-turn.js +11 -1
- package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
- package/dist/src/agent/service.js +6 -3
- package/dist/src/agent/session/session-config-service.js +27 -1
- package/dist/src/agent/session/session-hydrator.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/tools/factory.js +21 -14
- package/dist/src/agent/tools/personal-preference-tool.d.ts +10 -0
- package/dist/src/agent/tools/personal-preference-tool.js +43 -0
- package/dist/src/agent/tools/personal-task-tool.d.ts +28 -0
- package/dist/src/agent/tools/personal-task-tool.js +165 -0
- package/dist/src/agent/tools/xopc-use-tool.js +5 -4
- package/dist/src/agent-catalog/capabilities.js +2 -2
- package/dist/src/agent-catalog/service.d.ts +1 -1
- package/dist/src/agent-catalog/service.js +2 -1
- package/dist/src/agent-config/index.js +2 -2
- package/dist/src/agent-config/schema.d.ts +148 -0
- package/dist/src/agent-config/schema.js +40 -2
- package/dist/src/auth/credentials.js +1 -1
- package/dist/src/auth/oauth-provider-lock.js +1 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/automations/capabilities/drafts.js +1 -1
- package/dist/src/bootstrap/application-state.js +1 -1
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/capabilities/runtime/dispatcher.js +1 -1
- package/dist/src/capabilities/runtime/product.js +1 -1
- package/dist/src/chat-commands/builtins/thinking.js +12 -2
- package/dist/src/chat-commands/context.js +7 -1
- package/dist/src/cli/commands/agent.js +1 -1
- package/dist/src/cli/commands/agents.js +1 -1
- package/dist/src/cli/commands/auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +2 -2
- package/dist/src/cli/commands/providers.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +1 -1
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.js +1 -1
- package/dist/src/extensions/agent-plugins/validation.js +1 -1
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/notes.js +2 -2
- package/dist/src/gateway/hono/routes/personal-agent.d.ts +3 -0
- package/dist/src/gateway/hono/routes/personal-agent.js +107 -0
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/session-input-handler.js +2 -2
- package/dist/src/gateway/hono/routes/sessions.js +5 -0
- package/dist/src/gateway/hono/routes/side-chats.js +1 -1
- package/dist/src/gateway/hono/routes/tasks.js +65 -2
- package/dist/src/gateway/hono/routes/voice.js +8 -0
- package/dist/src/gateway/image-generation-setup.js +2 -2
- package/dist/src/gateway/lock.js +1 -1
- package/dist/src/gateway/service/session-command-service.js +7 -1
- package/dist/src/gateway/service/sessions-api.js +11 -1
- package/dist/src/gateway/service.js +5 -5
- package/dist/src/gateway/session-reset-service.js +5 -0
- package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
- package/dist/src/local-apps/service.js +1 -1
- package/dist/src/personal-agent/policy.d.ts +1 -0
- package/dist/src/personal-agent/policy.js +13 -0
- package/dist/src/personal-agent/repository.d.ts +25 -0
- package/dist/src/personal-agent/repository.js +68 -0
- package/dist/src/personal-agent/service.d.ts +48 -0
- package/dist/src/personal-agent/service.js +222 -0
- package/dist/src/providers/model-catalog-persistence.js +1 -1
- package/dist/src/session/resolve-session.js +4 -2
- package/dist/src/storage/sqlite/migrations/229_task_criterion_reviews.sql +12 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +13 -0
- package/dist/src/storage/sqlite/session-repository.js +6 -2
- package/dist/src/storage/sqlite/transcript-repository.js +2 -1
- package/dist/src/tasks/capabilities/read.js +5 -2
- package/dist/src/tasks/task-application-service.js +6 -1
- package/dist/src/tasks/task-criterion-review-repository.d.ts +22 -0
- package/dist/src/tasks/task-criterion-review-repository.js +74 -0
- package/dist/src/tasks/task-main-update-decision-service.js +6 -0
- package/dist/src/tui/backends/embedded-backend.js +2 -2
- package/dist/src/voice/realtime/persona-context.js +1 -1
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CcTnphqy.js +0 -1
- package/dist/gateway/static/root/assets/agent-plugin-dialog-CdCzMPhC.js +0 -1
- package/dist/gateway/static/root/assets/agents-BiNKpndr.js +0 -66
- package/dist/gateway/static/root/assets/app-management-settings-panel-BvGDN5J6.js +0 -1
- package/dist/gateway/static/root/assets/appearance-settings-BhQYkuQj.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-BQZJuM-C.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-y4qcvlg8.js +0 -7
- package/dist/gateway/static/root/assets/browser-settings-page--N4P7V0l.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-page-F7OAv-iz.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CaiIo1S1.js +0 -8
- package/dist/gateway/static/root/assets/capability-header-actions-CR_O9_Vr.js +0 -1
- package/dist/gateway/static/root/assets/channels-Bb-8c4wl.js +0 -1
- package/dist/gateway/static/root/assets/computer-settings-page-QuXZBfky.js +0 -1
- package/dist/gateway/static/root/assets/connector-service-page-BIqzVqCO.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CZ24DSBJ.js +0 -2
- package/dist/gateway/static/root/assets/date-picker-Ck-FmYEL.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-C1rKgB-S.js +0 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-UrPcOU6Q.js +0 -1
- package/dist/gateway/static/root/assets/directory-picker-path-field-BYxUgMZb.js +0 -1
- package/dist/gateway/static/root/assets/dist-CKkafhaS.js +0 -1
- package/dist/gateway/static/root/assets/dist-io9jFpN72.js +0 -1
- package/dist/gateway/static/root/assets/extension-debug-page-CGL0jpQA.js +0 -1
- package/dist/gateway/static/root/assets/extension-page-DPWf-tYg.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-DZWBY39d.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-D5w5aYXK.js +0 -1
- package/dist/gateway/static/root/assets/home-page-DPQwxBGy.js +0 -1
- package/dist/gateway/static/root/assets/imports-page-CnRWDtGz.js +0 -1
- package/dist/gateway/static/root/assets/index-B-w6Rk9Z.css +0 -1
- package/dist/gateway/static/root/assets/index-DU5Eb1V8.js +0 -106
- package/dist/gateway/static/root/assets/local-app-workbench-page-hjFeYlIq.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-CzpZDjkA.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-Beu_R_Rc.js +0 -1
- package/dist/gateway/static/root/assets/markdown-view-BlzX7Ze5.js +0 -201
- package/dist/gateway/static/root/assets/note-detail-panel-D8bpTGwP.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-OmgXowUG.js +0 -8
- package/dist/gateway/static/root/assets/page-context-capture-button-BjjjuLkz.js +0 -1
- package/dist/gateway/static/root/assets/page-tabs-_DiuzxyD.js +0 -1
- package/dist/gateway/static/root/assets/popover-select-0p9PIHRy.js +0 -1
- package/dist/gateway/static/root/assets/preview-open-alternatives-BKvUadws.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-CWlCg2x5.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-NbVNo0tP.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CD8HrqGC.js +0 -1
- package/dist/gateway/static/root/assets/scenes-page-DbWaemwR.js +0 -2
- package/dist/gateway/static/root/assets/schema-form-_3LQ4hyB.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-B7ZUdXlb.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CpKzZMft.js +0 -1
- package/dist/gateway/static/root/assets/settings-form-section-DS80hVSY.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-De-kC3yJ.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-T-0g_rwr.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-Dz33T3du.js +0 -1
- package/dist/gateway/static/root/assets/skill-api-Cx6GGpSY.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DyJ-Duem.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-B2iyN-kP.js +0 -2
- package/dist/gateway/static/root/assets/system-settings-panel-By3SZQR_.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-4yHUTs4_.js +0 -1
- package/dist/gateway/static/root/assets/tasks-BH8_WMUF.js +0 -1
- package/dist/gateway/static/root/assets/tunnel-api-BoH0LBkw.js +0 -1
- package/dist/gateway/static/root/assets/usage-page-dKU5X9zT.js +0 -1
- package/dist/gateway/static/root/assets/use-autosave-YKCwQvqT.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-Uht32LPP.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-DiqHIA8l.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-Cq3vRUbc.js +0 -6
- /package/dist/gateway/static/root/assets/{dist-CI_fqRk-2.js → dist-CI_fqRk-.js} +0 -0
|
@@ -7,6 +7,7 @@ import { STTTranscriptionError, transcribe } from "../../../voice/stt/transcribe
|
|
|
7
7
|
import { isSTTAvailable } from "../../../voice/stt/availability.js";
|
|
8
8
|
import { mergeSttConfigFromAppConfig } from "../../../voice/stt/config.js";
|
|
9
9
|
import "../../../voice/stt/index.js";
|
|
10
|
+
import { isPersonalConversation } from "../../../personal-agent/repository.js";
|
|
10
11
|
import { resolveTtsProviderConfigSlice } from "../../../voice/tts/config-slice.js";
|
|
11
12
|
import { isTTSAvailable, resolveSpeechProvider } from "../../../voice/tts/factory.js";
|
|
12
13
|
import { speak, speakStream } from "../../../voice/tts/speak-core.js";
|
|
@@ -268,6 +269,13 @@ function registerVoiceRoutes(authenticated, deps) {
|
|
|
268
269
|
message: "Invalid realtime voice session request"
|
|
269
270
|
}
|
|
270
271
|
}, 400);
|
|
272
|
+
if (parsed.data.conversationId && isPersonalConversation(parsed.data.conversationId) && parsed.data.mode !== "assistant") return c.json({
|
|
273
|
+
ok: false,
|
|
274
|
+
error: {
|
|
275
|
+
code: "INVALID_REQUEST",
|
|
276
|
+
message: "Personal AI voice requires assistant mode"
|
|
277
|
+
}
|
|
278
|
+
}, 400);
|
|
271
279
|
try {
|
|
272
280
|
const preparation = parsed.data.conversationId ? getSessionPreparation(parsed.data.conversationId) : void 0;
|
|
273
281
|
if (preparation && preparation.state !== "ready") return c.json({
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { normalizeAgentId } from "../agent-catalog/id.js";
|
|
2
2
|
import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
|
|
3
|
-
import { init_agent_scope } from "../agent/agent-scope.js";
|
|
4
|
-
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
5
3
|
import { ConfigSchema, init_schema } from "../config/schema.js";
|
|
4
|
+
import { init_agent_scope } from "../agent/agent-scope.js";
|
|
6
5
|
import { resolveEffectiveAgentConfigForAgent } from "../config/agent-profile.js";
|
|
7
6
|
import { fetchWithTimeoutGuarded } from "../media-shared/http/provider-http.js";
|
|
8
7
|
import "../media-shared/http/index.js";
|
|
8
|
+
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
9
9
|
import { getImageGenerationProvider, listImageGenerationProvidersSummary } from "../agent/image/generation/provider-registry.js";
|
|
10
10
|
//#region src/gateway/image-generation-setup.ts
|
|
11
11
|
init_repository();
|
package/dist/src/gateway/lock.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
|
-
import fs$1 from "node:fs/promises";
|
|
5
4
|
import net from "node:net";
|
|
5
|
+
import fs$1 from "node:fs/promises";
|
|
6
6
|
import { homedir } from "os";
|
|
7
7
|
//#region src/gateway/lock.ts
|
|
8
8
|
/**
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { getSessionMetadata } from "../../storage/sqlite/session-read-repository.js";
|
|
2
2
|
import { init_session_repository } from "../../storage/sqlite/session-repository.js";
|
|
3
|
+
import { resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession } from "../../config/agent-profile.js";
|
|
3
4
|
import { init_providers, resolveModel } from "../../providers/index.js";
|
|
4
5
|
import { resolveProjectAgentId } from "../../projects/project-agent.js";
|
|
5
6
|
import "../../projects/index.js";
|
|
6
7
|
import { getModelThinking } from "../../providers/model-thinking.js";
|
|
8
|
+
import { getPersonalAgentByConversation } from "../../personal-agent/repository.js";
|
|
7
9
|
import { withModelConfigLock } from "../../session/model-config-lock.js";
|
|
8
10
|
import { SessionCommandError, acceptSessionCommand, getSessionPreparation, matchSessionInputReceipt, sessionCommandHash } from "../../storage/sqlite/session-creation-repository.js";
|
|
9
11
|
//#region src/gateway/service/session-command-service.ts
|
|
@@ -24,6 +26,10 @@ function validateCreation(service, creation) {
|
|
|
24
26
|
}
|
|
25
27
|
async function receiveSessionCommand(service, conversationId, principalId, command, prepareSourceContexts = async () => []) {
|
|
26
28
|
return withModelConfigLock(conversationId, async () => {
|
|
29
|
+
const personal = getPersonalAgentByConversation(conversationId);
|
|
30
|
+
if (personal && "creation" in command && command.creation.agentId !== personal.agentId) throw new SessionCommandError("BAD_REQUEST", "Personal AI identity is fixed");
|
|
31
|
+
const configuredThinking = ("creation" in command ? resolveEffectiveAgentConfigForAgent(command.creation.agentId) : resolveEffectiveAgentConfigForSession(conversationId)).config.runtime.thinkingLevel;
|
|
32
|
+
if (configuredThinking && "creation" in command && command.creation.thinkingLevel !== configuredThinking) throw new SessionCommandError("BAD_REQUEST", `This agent uses thinking ${configuredThinking}`);
|
|
27
33
|
const clientMessageId = "commandId" in command ? command.commandId : command.clientMessageId;
|
|
28
34
|
const existing = matchSessionInputReceipt(conversationId, clientMessageId, principalId, sessionCommandHash(command));
|
|
29
35
|
if (existing) return sessionCommandSnapshot(service, existing);
|
|
@@ -50,7 +56,7 @@ async function receiveSessionCommand(service, conversationId, principalId, comma
|
|
|
50
56
|
attachments: command.input.attachments,
|
|
51
57
|
contextRefs: command.input.contextRefs,
|
|
52
58
|
sourceContexts: await prepareSourceContexts(),
|
|
53
|
-
thinking: command.kind === "start" ? command.creation.thinkingLevel : (await service.sessions.getAgentConfig(conversationId)).thinkingLevel,
|
|
59
|
+
thinking: configuredThinking ?? (command.kind === "start" ? command.creation.thinkingLevel : (await service.sessions.getAgentConfig(conversationId)).thinkingLevel),
|
|
54
60
|
origin: command.origin.type === "endpoint" ? {
|
|
55
61
|
type: "endpoint",
|
|
56
62
|
endpointId: command.origin.endpointId
|
|
@@ -2,6 +2,7 @@ import { init_agent_session_key, resolveAgentIdFromConversationId } from "../../
|
|
|
2
2
|
import { retireSessionMcpRuntimeForConversationId } from "../../agent/mcp/bundle-mcp-runtime.js";
|
|
3
3
|
import { buildSessionTimeline } from "../../session/transcript-outline.js";
|
|
4
4
|
import { transcriptRowsToClientHistory } from "../../session/client-history.js";
|
|
5
|
+
import { isPersonalConversation } from "../../personal-agent/repository.js";
|
|
5
6
|
import "../../agent/mcp/bundle-mcp-tools.js";
|
|
6
7
|
import { collectMediaUrisFromValues, deleteMediaUris } from "../../media/session-references.js";
|
|
7
8
|
import { withModelConfigLock } from "../../session/model-config-lock.js";
|
|
@@ -173,6 +174,7 @@ var GatewaySessionsApi = class {
|
|
|
173
174
|
return result;
|
|
174
175
|
}
|
|
175
176
|
async delete(key) {
|
|
177
|
+
if (isPersonalConversation(key)) return { deleted: false };
|
|
176
178
|
const transcriptRows = await this.opts.sessionIndex.getStore().loadTranscriptHistoryRows(key).catch(() => []);
|
|
177
179
|
const result = await this.opts.sessionIndex.deleteSession(key);
|
|
178
180
|
if (result) {
|
|
@@ -187,13 +189,21 @@ var GatewaySessionsApi = class {
|
|
|
187
189
|
}
|
|
188
190
|
/** Reset transcript in place (archive + new session id); preserves session key and overrides. */
|
|
189
191
|
reset(key) {
|
|
192
|
+
if (isPersonalConversation(key)) return Promise.resolve({
|
|
193
|
+
ok: false,
|
|
194
|
+
error: "Personal AI conversation cannot be reset"
|
|
195
|
+
});
|
|
190
196
|
return performSessionReset(key, {
|
|
191
197
|
sessionIndex: this.opts.sessionIndex,
|
|
192
198
|
getAgentService: this.opts.getAgentService
|
|
193
199
|
});
|
|
194
200
|
}
|
|
195
201
|
deleteMany(keys) {
|
|
196
|
-
|
|
202
|
+
const protectedKeys = keys.filter(isPersonalConversation);
|
|
203
|
+
return this.opts.sessionIndex.deleteSessions(keys.filter((key) => !isPersonalConversation(key))).then((result) => ({
|
|
204
|
+
success: result.success,
|
|
205
|
+
failed: [...result.failed, ...protectedKeys]
|
|
206
|
+
}));
|
|
197
207
|
}
|
|
198
208
|
async rename(key, name) {
|
|
199
209
|
await this.opts.sessionIndex.renameSession(key, name);
|
|
@@ -17,9 +17,9 @@ import { init_session_repository, listSessionMetadata, patchSessionMetadata } fr
|
|
|
17
17
|
import { getSessionConfig, init_config_repository } from "../storage/sqlite/config-repository.js";
|
|
18
18
|
import { init_sqlite } from "../storage/sqlite/index.js";
|
|
19
19
|
import { normalizeAgentId } from "../agent-catalog/id.js";
|
|
20
|
-
import { init_agent_scope, listAgentEntries, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
|
|
21
20
|
import { init_config, resolveKnowledgeReadPolicy } from "../user-context/config.js";
|
|
22
21
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
22
|
+
import { init_agent_scope, listAgentEntries, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
|
|
23
23
|
import { init_agent_session_key, resolveAgentMainConversationId } from "../routing/agent-session-key.js";
|
|
24
24
|
import { init_session_key, resolveConversationId, sanitizeSegment } from "../routing/session-key.js";
|
|
25
25
|
import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
@@ -70,24 +70,24 @@ import { bootstrapApplicationStateSync } from "../bootstrap/application-state.js
|
|
|
70
70
|
import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
|
|
71
71
|
import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
|
|
72
72
|
import { ChannelManager } from "../channels/manager.js";
|
|
73
|
-
import { ChatPreviewService } from "../chat-previews/service.js";
|
|
74
|
-
import "../chat-previews/index.js";
|
|
75
73
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
76
74
|
import "../config/index.js";
|
|
75
|
+
import { ChatPreviewService } from "../chat-previews/service.js";
|
|
76
|
+
import "../chat-previews/index.js";
|
|
77
77
|
import { DiscussionService } from "../discussions/service.js";
|
|
78
78
|
import { DiscussionOrganizer } from "../discussions/organizer.js";
|
|
79
79
|
import { DiscussionLiveWorker } from "../discussions/live-worker.js";
|
|
80
80
|
import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
|
|
81
81
|
import { DiscussionSealer } from "../discussions/sealer.js";
|
|
82
82
|
import "../discussions/index.js";
|
|
83
|
-
import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
|
|
84
|
-
import "../endpoint-tools/index.js";
|
|
85
83
|
import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
|
|
86
84
|
import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
|
|
87
85
|
import "../knowledge/index.js";
|
|
88
86
|
import { ConnectionRecoveryService } from "../connectors/connection-recovery-service.js";
|
|
89
87
|
import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
|
|
90
88
|
import { startConnectorSupervisor } from "../connectors/supervisor.js";
|
|
89
|
+
import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
|
|
90
|
+
import "../endpoint-tools/index.js";
|
|
91
91
|
import { HomeCapabilityPreflightService } from "../home-intelligence/capability-preflight.js";
|
|
92
92
|
import { HomeAdviceGenerator } from "../home-intelligence/generator.js";
|
|
93
93
|
import { HomeIntelligenceHost } from "../home-intelligence/host.js";
|
|
@@ -2,6 +2,7 @@ import { createLogger } from "../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
3
|
import { retireSessionMcpRuntimeForConversationId } from "../agent/mcp/bundle-mcp-runtime.js";
|
|
4
4
|
import { abortEmbeddedRun } from "../agent/embedded/runs.js";
|
|
5
|
+
import { isPersonalConversation } from "../personal-agent/repository.js";
|
|
5
6
|
import "../agent/mcp/bundle-mcp-tools.js";
|
|
6
7
|
//#region src/gateway/session-reset-service.ts
|
|
7
8
|
init_logger();
|
|
@@ -17,6 +18,10 @@ async function performSessionReset(conversationId, deps) {
|
|
|
17
18
|
ok: false,
|
|
18
19
|
error: "Session key required"
|
|
19
20
|
};
|
|
21
|
+
if (isPersonalConversation(key)) return {
|
|
22
|
+
ok: false,
|
|
23
|
+
error: "Personal AI conversation cannot be reset"
|
|
24
|
+
};
|
|
20
25
|
await abortEmbeddedRun(key);
|
|
21
26
|
const task = await deps.sessionIndex.resetSession(key);
|
|
22
27
|
if (!task) return {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
|
|
2
|
-
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
3
2
|
import { getModelCatalogStore, init_model_catalog_store } from "../providers/model-catalog-store.js";
|
|
4
3
|
import { compareCatalogModels } from "../providers/model-catalog-ranking.js";
|
|
4
|
+
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
5
5
|
import { prepareUpdateGlobalDefaults } from "./global-defaults-admin.js";
|
|
6
6
|
//#region src/gateway/xopc-cloud-capability-setup.ts
|
|
7
7
|
init_repository();
|
|
@@ -5,10 +5,10 @@ import { currentOperationId, init_operation_context } from "../infra/operation-c
|
|
|
5
5
|
import { afterSqliteCommit, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
6
6
|
import { ExtensionCapabilityBindingsSchema, extensionCapabilityPermissions } from "../../packages/gateway-contract/src/extension-capabilities.js";
|
|
7
7
|
import { init_src } from "../../packages/gateway-contract/src/index.js";
|
|
8
|
-
import { CapabilityError } from "../capabilities/runtime/errors.js";
|
|
9
8
|
import { init_paths, resolveExtensionsDir } from "../config/paths.js";
|
|
10
9
|
import { LocalAppStore } from "./store.js";
|
|
11
10
|
import { slugifyProjectName } from "../projects/project-store.js";
|
|
11
|
+
import { CapabilityError } from "../capabilities/runtime/errors.js";
|
|
12
12
|
import { DomainOutboxDispatcher } from "../infra/domain-outbox-dispatcher.js";
|
|
13
13
|
import { validateLocalAppCapabilityContracts } from "./capabilities/contracts.js";
|
|
14
14
|
import { buildLocalAppFixGuidance } from "./fix-guidance.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PERSONAL_MAIN_TOOL_IDS: readonly ["personal_task", "personal_preference", "session_recall", "user_context_search", "user_context_get", "knowledge_search", "knowledge_get", "clarify"];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/personal-agent/policy.ts
|
|
2
|
+
const PERSONAL_MAIN_TOOL_IDS = [
|
|
3
|
+
"personal_task",
|
|
4
|
+
"personal_preference",
|
|
5
|
+
"session_recall",
|
|
6
|
+
"user_context_search",
|
|
7
|
+
"user_context_get",
|
|
8
|
+
"knowledge_search",
|
|
9
|
+
"knowledge_get",
|
|
10
|
+
"clarify"
|
|
11
|
+
];
|
|
12
|
+
//#endregion
|
|
13
|
+
export { PERSONAL_MAIN_TOOL_IDS };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type PersonalAgentState = 'provisioning' | 'ready' | 'error';
|
|
2
|
+
export type PersonalAppearance = 'spark' | 'cloud' | 'bean';
|
|
3
|
+
export interface PersonalAgentRecord {
|
|
4
|
+
ownerId: string;
|
|
5
|
+
agentId: string;
|
|
6
|
+
conversationId: string;
|
|
7
|
+
state: PersonalAgentState;
|
|
8
|
+
displayName: string;
|
|
9
|
+
appearance: PersonalAppearance;
|
|
10
|
+
preferences: Record<string, unknown>;
|
|
11
|
+
revision: number;
|
|
12
|
+
errorMessage: string | null;
|
|
13
|
+
}
|
|
14
|
+
export declare const DEFAULT_PERSONAL_PREFERENCES: {
|
|
15
|
+
readonly warmth: "balanced";
|
|
16
|
+
readonly humor: "none";
|
|
17
|
+
readonly supportMode: "untangle";
|
|
18
|
+
readonly detailLevel: "balanced";
|
|
19
|
+
readonly proactivity: "decisions";
|
|
20
|
+
};
|
|
21
|
+
export declare function personalAgentId(ownerId: string): string;
|
|
22
|
+
export declare function personalConversationId(ownerId: string): string;
|
|
23
|
+
export declare function getPersonalAgent(ownerId: string): PersonalAgentRecord | null;
|
|
24
|
+
export declare function getPersonalAgentByConversation(conversationId: string): PersonalAgentRecord | null;
|
|
25
|
+
export declare function isPersonalConversation(conversationId: string): boolean;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { init_connection, isXopcDatabaseOpen } from "../storage/sqlite/connection.js";
|
|
2
|
+
import { getSqliteDatabase, init_transaction } from "../storage/sqlite/transaction.js";
|
|
3
|
+
import { getSessionConfig, init_config_repository } from "../storage/sqlite/config-repository.js";
|
|
4
|
+
import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
//#region src/personal-agent/repository.ts
|
|
7
|
+
init_repository();
|
|
8
|
+
init_connection();
|
|
9
|
+
init_config_repository();
|
|
10
|
+
init_transaction();
|
|
11
|
+
const DEFAULT_PERSONAL_PREFERENCES = {
|
|
12
|
+
warmth: "balanced",
|
|
13
|
+
humor: "none",
|
|
14
|
+
supportMode: "untangle",
|
|
15
|
+
detailLevel: "balanced",
|
|
16
|
+
proactivity: "decisions"
|
|
17
|
+
};
|
|
18
|
+
function personalAgentId(ownerId) {
|
|
19
|
+
return `personal-${createHash("sha256").update(ownerId).digest("hex").slice(0, 12)}`;
|
|
20
|
+
}
|
|
21
|
+
function personalConversationId(ownerId) {
|
|
22
|
+
const hash = createHash("sha256").update(`personal-conversation:${ownerId}`).digest("hex");
|
|
23
|
+
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-5${hash.slice(13, 16)}-8${hash.slice(17, 20)}-${hash.slice(20, 32)}`;
|
|
24
|
+
}
|
|
25
|
+
function personalSession(column, value) {
|
|
26
|
+
if (!isXopcDatabaseOpen()) return null;
|
|
27
|
+
return getSqliteDatabase().prepare(`SELECT conversation_id, agent_id
|
|
28
|
+
FROM sessions WHERE ${column} = ? AND json_extract(custom_data_json, '$.personalAgent') = 1
|
|
29
|
+
ORDER BY created_at LIMIT 1`).get(value) ?? null;
|
|
30
|
+
}
|
|
31
|
+
function appearanceFrom(agent) {
|
|
32
|
+
return agent.profile?.emoji === "☁" ? "cloud" : agent.profile?.emoji === "◕" ? "bean" : "spark";
|
|
33
|
+
}
|
|
34
|
+
function toRecord(ownerId, agent, session) {
|
|
35
|
+
const config = session ? getSessionConfig(session.conversation_id) : null;
|
|
36
|
+
const ready = agent.provisioningState === "ready" && agent.runtime?.thinkingLevel === "off" && session && config?.thinkingLevel === "off" && config.fixedModel;
|
|
37
|
+
return {
|
|
38
|
+
ownerId,
|
|
39
|
+
agentId: agent.id,
|
|
40
|
+
conversationId: session?.conversation_id ?? personalConversationId(ownerId),
|
|
41
|
+
state: agent.provisioningState === "error" ? "error" : ready ? "ready" : "provisioning",
|
|
42
|
+
displayName: agent.profile?.name ?? "Personal AI",
|
|
43
|
+
appearance: appearanceFrom(agent),
|
|
44
|
+
preferences: agent.profile?.responsePreferences ?? DEFAULT_PERSONAL_PREFERENCES,
|
|
45
|
+
revision: agent.revision,
|
|
46
|
+
errorMessage: agent.provisioningError ?? null
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function getPersonalAgent(ownerId) {
|
|
50
|
+
if (!isXopcDatabaseOpen()) return null;
|
|
51
|
+
const agent = new AgentCatalogRepository().get(personalAgentId(ownerId));
|
|
52
|
+
return agent ? toRecord(ownerId, agent, personalSession("agent_id", agent.id)) : null;
|
|
53
|
+
}
|
|
54
|
+
function getPersonalAgentByConversation(conversationId) {
|
|
55
|
+
const session = personalSession("conversation_id", conversationId);
|
|
56
|
+
if (!session) return null;
|
|
57
|
+
const agent = new AgentCatalogRepository().get(session.agent_id);
|
|
58
|
+
if (!agent) return null;
|
|
59
|
+
const ownerId = "local-owner";
|
|
60
|
+
return agent.id === personalAgentId(ownerId) ? toRecord(ownerId, agent, session) : null;
|
|
61
|
+
}
|
|
62
|
+
function isPersonalConversation(conversationId) {
|
|
63
|
+
if (!isXopcDatabaseOpen()) return false;
|
|
64
|
+
return Boolean(getSqliteDatabase().prepare(`SELECT 1 FROM sessions WHERE conversation_id = ?
|
|
65
|
+
AND agent_id = ? AND json_extract(custom_data_json, '$.personalAgent') = 1`).get(conversationId, personalAgentId("local-owner")));
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { DEFAULT_PERSONAL_PREFERENCES, getPersonalAgent, getPersonalAgentByConversation, isPersonalConversation, personalAgentId, personalConversationId };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { GatewayService } from '../gateway/service.js';
|
|
3
|
+
import { type PersonalAgentRecord } from './repository.js';
|
|
4
|
+
export declare const PersonalPreferencesSchema: z.ZodObject<{
|
|
5
|
+
addressAs: z.ZodOptional<z.ZodString>;
|
|
6
|
+
warmth: z.ZodOptional<z.ZodEnum<{
|
|
7
|
+
balanced: "balanced";
|
|
8
|
+
reserved: "reserved";
|
|
9
|
+
gentle: "gentle";
|
|
10
|
+
}>>;
|
|
11
|
+
humor: z.ZodOptional<z.ZodEnum<{
|
|
12
|
+
none: "none";
|
|
13
|
+
occasional: "occasional";
|
|
14
|
+
playful: "playful";
|
|
15
|
+
}>>;
|
|
16
|
+
supportMode: z.ZodOptional<z.ZodEnum<{
|
|
17
|
+
listen: "listen";
|
|
18
|
+
untangle: "untangle";
|
|
19
|
+
solutions: "solutions";
|
|
20
|
+
}>>;
|
|
21
|
+
detailLevel: z.ZodOptional<z.ZodEnum<{
|
|
22
|
+
brief: "brief";
|
|
23
|
+
balanced: "balanced";
|
|
24
|
+
detailed: "detailed";
|
|
25
|
+
}>>;
|
|
26
|
+
proactivity: z.ZodOptional<z.ZodEnum<{
|
|
27
|
+
open: "open";
|
|
28
|
+
decisions: "decisions";
|
|
29
|
+
important: "important";
|
|
30
|
+
}>>;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
export type PersonalPreferences = z.infer<typeof PersonalPreferencesSchema>;
|
|
33
|
+
export declare const PersonalAppearanceSchema: z.ZodEnum<{
|
|
34
|
+
cloud: "cloud";
|
|
35
|
+
spark: "spark";
|
|
36
|
+
bean: "bean";
|
|
37
|
+
}>;
|
|
38
|
+
export type PersonalAppearance = z.infer<typeof PersonalAppearanceSchema>;
|
|
39
|
+
export declare function personalInstructions(preferences: PersonalPreferences): string;
|
|
40
|
+
export declare function refreshPersonalDelegationGuidance(service: GatewayService, ownerId: string): Promise<void>;
|
|
41
|
+
export declare function listPersonalModels(): Promise<Array<{
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
}>>;
|
|
45
|
+
export declare function ensurePersonalConversationVisibility(ownerId: string): void;
|
|
46
|
+
export declare function createOrResumePersonalAgent(service: GatewayService, ownerId: string, requestedModel?: string, availableModels?: typeof listPersonalModels): Promise<PersonalAgentRecord>;
|
|
47
|
+
export declare function patchPersonalProfile(service: GatewayService, ownerId: string, revision: number, displayName: string, preferences: PersonalPreferences, appearance: PersonalAppearance): Promise<PersonalAgentRecord | null>;
|
|
48
|
+
export declare function updatePersonalProfileRecord(ownerId: string, revision: number, displayName: string, preferences: PersonalPreferences, appearance: PersonalAppearance): Promise<PersonalAgentRecord | null>;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { getSessionMetadata } from "../storage/sqlite/session-read-repository.js";
|
|
2
|
+
import { init_session_repository, patchSessionMetadata } from "../storage/sqlite/session-repository.js";
|
|
3
|
+
import { init_config_repository, setSessionConfig } from "../storage/sqlite/config-repository.js";
|
|
4
|
+
import { ResponsePreferencesSchema } from "../agent-config/schema.js";
|
|
5
|
+
import { init_agent_config } from "../agent-config/index.js";
|
|
6
|
+
import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
|
|
7
|
+
import { createConversation, init_conversation_repository } from "../storage/sqlite/conversation-repository.js";
|
|
8
|
+
import { getAvailableModels, init_providers } from "../providers/index.js";
|
|
9
|
+
import { getModelThinking } from "../providers/model-thinking.js";
|
|
10
|
+
import { AgentCatalogService } from "../agent-catalog/service.js";
|
|
11
|
+
import { DEFAULT_PERSONAL_PREFERENCES, getPersonalAgent, personalAgentId } from "./repository.js";
|
|
12
|
+
import { PERSONAL_MAIN_TOOL_IDS } from "./policy.js";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
//#region src/personal-agent/service.ts
|
|
15
|
+
init_agent_config();
|
|
16
|
+
init_repository();
|
|
17
|
+
init_providers();
|
|
18
|
+
init_conversation_repository();
|
|
19
|
+
init_session_repository();
|
|
20
|
+
init_config_repository();
|
|
21
|
+
const PersonalPreferencesSchema = ResponsePreferencesSchema;
|
|
22
|
+
const PersonalAppearanceSchema = z.enum([
|
|
23
|
+
"spark",
|
|
24
|
+
"cloud",
|
|
25
|
+
"bean"
|
|
26
|
+
]);
|
|
27
|
+
function appearanceEmoji(appearance) {
|
|
28
|
+
return appearance === "cloud" ? "☁" : appearance === "bean" ? "◕" : "✦";
|
|
29
|
+
}
|
|
30
|
+
const LEGACY_DELEGATION_RULE = "Answer simple requests directly. For complex work, use personal_task agents to find a suitable specialist, then create a Task and remain available to talk. Never claim a task was created before the tool confirms it.";
|
|
31
|
+
const PREVIOUS_DELEGATION_RULES = [
|
|
32
|
+
"Route by required capability, not task length. Answer directly only when your own tools and knowledge are sufficient. For current facts, web pages, or any tool you lack, call personal_task(command=\"agents\"), choose an Agent with the needed availableTools, then create a Task. Your own lack of browsing does not mean xopc cannot browse. Never claim the system cannot help, ask the user to switch models, or ask them to paste sources before checking Agents.",
|
|
33
|
+
"For current news, delegate to an Agent with web_search. Include the requested date or time window and topic in the brief; require source links, publication dates, and a distinction between confirmed news and uncertain reports. Tell the user briefly that you are checking. Stay available while the Task runs, then summarize verified results in their preferred style.",
|
|
34
|
+
"If no suitable Agent is available, explain the specific missing capability and offer the next useful option. Never claim a Task was created before the tool confirms it."
|
|
35
|
+
].join("\n");
|
|
36
|
+
const DELEGATION_RULES = [
|
|
37
|
+
"Own the user’s request through completion. If you cannot reliably do it yourself because of missing tools, access, knowledge, time, or specialist judgment, first call personal_task(command=\"agents\"). Match the request to another Agent’s description and availableTools, then create a Task for a plausible candidate. This applies to short requests too. Your own limitation is not a system limitation. Do not stop at “I cannot” or ask the user to switch models or do your work before checking Agents.",
|
|
38
|
+
"If the chosen Agent or tool cannot complete the Task, inspect the actual blocker and try another suitable Agent or a reasonable alternative within the user’s authorization. Do not repeat the same failed approach indefinitely. Ask the user only for a decision, access, or information that no available Agent can supply. Explain a concrete blocker only after checking the available paths; never imply that an untried path was attempted.",
|
|
39
|
+
"For current news or other live facts, find an Agent with web_search and require dated sources. For coding, analysis, writing, media, or connected-app work, choose by the Agent’s role and tools rather than a fixed name. Give the Task a short title and a complete Markdown brief. After Task creation succeeds, tell the user briefly what is happening, stay available, and summarize verified outcomes in their preferred style.",
|
|
40
|
+
"Never claim a Task was created or completed before its tool result confirms that state. Respect the user’s authorization and the selected Agent’s permissions."
|
|
41
|
+
];
|
|
42
|
+
function personalInstructions(preferences) {
|
|
43
|
+
const rules = [
|
|
44
|
+
"You are the user’s personal AI: capable, clear, attentive, and responsive. Match the user’s language. Let the user’s stated preferences and current situation shape how you speak; do not impose a cute or affectionate persona.",
|
|
45
|
+
...DELEGATION_RULES,
|
|
46
|
+
"When creating a Task, provide a short title that names the work, a one-sentence objective, and a Markdown description with all detailed instructions. Keep the title free of checklists and long background. Preserve user requirements in the description.",
|
|
47
|
+
"Adapt to the user’s current words first, then their saved preferences. If the user explicitly changes how they want you to respond in future, save it with personal_preference. Do not infer a lasting emotional trait from one conversation or claim human feelings or experiences.",
|
|
48
|
+
"Give the accurate answer or next step in the order this user prefers. Acknowledge feelings only when relevant, without guessing how the user feels. Avoid formulaic reassurance, praise, pet names, emojis, or jokes unless the user welcomes them and the moment fits. Be accurate about task state, evidence, and uncertainty."
|
|
49
|
+
];
|
|
50
|
+
if (preferences.addressAs) rules.push(`Address the user as ${JSON.stringify(preferences.addressAs)} when a name fits naturally.`);
|
|
51
|
+
if (preferences.warmth) rules.push({
|
|
52
|
+
reserved: "Tone: calm and direct; skip emotional preambles.",
|
|
53
|
+
balanced: "Tone: friendly and natural.",
|
|
54
|
+
gentle: "Tone: softly supportive without being sentimental."
|
|
55
|
+
}[preferences.warmth]);
|
|
56
|
+
if (preferences.humor) rules.push({
|
|
57
|
+
none: "Do not add jokes.",
|
|
58
|
+
occasional: "Use an occasional light touch when the moment fits.",
|
|
59
|
+
playful: "Be lightly playful in easy moments."
|
|
60
|
+
}[preferences.humor]);
|
|
61
|
+
if (preferences.supportMode) rules.push({
|
|
62
|
+
listen: "When the user is struggling, listen and reflect briefly before proposing fixes.",
|
|
63
|
+
untangle: "When the user is struggling, help name the core problem and make it manageable.",
|
|
64
|
+
solutions: "When the user is struggling, offer a concrete next step promptly."
|
|
65
|
+
}[preferences.supportMode]);
|
|
66
|
+
if (preferences.detailLevel) rules.push({
|
|
67
|
+
brief: "Keep replies short and lead with the answer.",
|
|
68
|
+
balanced: "Give the answer and only the context needed to act.",
|
|
69
|
+
detailed: "Explain reasoning and tradeoffs when useful."
|
|
70
|
+
}[preferences.detailLevel]);
|
|
71
|
+
if (preferences.proactivity) rules.push({
|
|
72
|
+
decisions: "Only proactively surface decisions and outcomes.",
|
|
73
|
+
important: "Proactively surface important milestones as well as outcomes.",
|
|
74
|
+
open: "You may offer useful suggestions without flooding the user."
|
|
75
|
+
}[preferences.proactivity]);
|
|
76
|
+
return rules.join("\n");
|
|
77
|
+
}
|
|
78
|
+
async function refreshPersonalDelegationGuidance(service, ownerId) {
|
|
79
|
+
const agent = new AgentCatalogRepository().get(personalAgentId(ownerId));
|
|
80
|
+
const instructions = agent?.profile?.instructions;
|
|
81
|
+
if (!agent || !instructions) return;
|
|
82
|
+
const oldRule = instructions.includes(PREVIOUS_DELEGATION_RULES) ? PREVIOUS_DELEGATION_RULES : instructions.includes(LEGACY_DELEGATION_RULE) ? LEGACY_DELEGATION_RULE : null;
|
|
83
|
+
if (!oldRule) return;
|
|
84
|
+
try {
|
|
85
|
+
await new AgentCatalogService().update(agent.id, { profile: {
|
|
86
|
+
...agent.profile,
|
|
87
|
+
instructions: instructions.replace(oldRule, DELEGATION_RULES.join("\n"))
|
|
88
|
+
} }, agent.revision);
|
|
89
|
+
service.refreshAgentCatalog?.();
|
|
90
|
+
const conversationId = getPersonalAgent(ownerId)?.conversationId;
|
|
91
|
+
if (conversationId) service.agentService?.evictSessionAgent(conversationId);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
if (!(error instanceof Error && error.message === "Agent revision conflict")) throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function listPersonalModels() {
|
|
97
|
+
return (await getAvailableModels()).filter((model) => getModelThinking(model).options.includes("off")).map((model) => ({
|
|
98
|
+
id: `${model.provider}/${model.id}`,
|
|
99
|
+
name: model.name ?? model.id
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
const inFlightProvisioning = /* @__PURE__ */ new Map();
|
|
103
|
+
function ensurePersonalConversationVisibility(ownerId) {
|
|
104
|
+
const conversationId = getPersonalAgent(ownerId)?.conversationId;
|
|
105
|
+
if (!conversationId) return;
|
|
106
|
+
const session = getSessionMetadata(conversationId);
|
|
107
|
+
if (!session || session.hiddenFromSessionList && session.customData?.keepHiddenFromSessionList === true) return;
|
|
108
|
+
patchSessionMetadata(conversationId, {
|
|
109
|
+
hiddenFromSessionList: true,
|
|
110
|
+
customData: {
|
|
111
|
+
...session.customData,
|
|
112
|
+
keepHiddenFromSessionList: true
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function createOrResumePersonalAgent(service, ownerId, requestedModel, availableModels = listPersonalModels) {
|
|
117
|
+
const current = inFlightProvisioning.get(ownerId);
|
|
118
|
+
if (current) return current;
|
|
119
|
+
const pending = provisionPersonalAgent(service, ownerId, requestedModel, availableModels);
|
|
120
|
+
inFlightProvisioning.set(ownerId, pending);
|
|
121
|
+
pending.finally(() => {
|
|
122
|
+
if (inFlightProvisioning.get(ownerId) === pending) inFlightProvisioning.delete(ownerId);
|
|
123
|
+
}).catch(() => {});
|
|
124
|
+
return pending;
|
|
125
|
+
}
|
|
126
|
+
async function provisionPersonalAgent(service, ownerId, requestedModel, availableModels = listPersonalModels) {
|
|
127
|
+
const existingIdentity = getPersonalAgent(ownerId);
|
|
128
|
+
if (existingIdentity?.state === "ready") {
|
|
129
|
+
await refreshPersonalDelegationGuidance(service, ownerId);
|
|
130
|
+
ensurePersonalConversationVisibility(ownerId);
|
|
131
|
+
return getPersonalAgent(ownerId) ?? existingIdentity;
|
|
132
|
+
}
|
|
133
|
+
const agentId = personalAgentId(ownerId);
|
|
134
|
+
const existing = new AgentCatalogRepository().get(agentId);
|
|
135
|
+
const available = await availableModels();
|
|
136
|
+
const preferredModel = requestedModel ?? existing?.models?.chat?.primary;
|
|
137
|
+
const fastModel = preferredModel ? void 0 : new AgentCatalogRepository().getSettings().defaults.models.intents.fast?.primary;
|
|
138
|
+
const chosen = preferredModel ? available.find((model) => model.id === preferredModel) : available.find((model) => model.id === fastModel) ?? available[0];
|
|
139
|
+
if (!chosen) throw new Error("Choose a configured model that supports thinking off");
|
|
140
|
+
const catalog = new AgentCatalogService();
|
|
141
|
+
if (!existing) await catalog.create({
|
|
142
|
+
id: agentId,
|
|
143
|
+
enabled: true,
|
|
144
|
+
profile: {
|
|
145
|
+
name: "Personal AI",
|
|
146
|
+
description: "A personal AI that adapts its responses to the user and coordinates work.",
|
|
147
|
+
creature: "assistant",
|
|
148
|
+
language: "zh",
|
|
149
|
+
emoji: appearanceEmoji("spark"),
|
|
150
|
+
responsePreferences: DEFAULT_PERSONAL_PREFERENCES,
|
|
151
|
+
instructions: personalInstructions(DEFAULT_PERSONAL_PREFERENCES)
|
|
152
|
+
},
|
|
153
|
+
toolAllowlist: [...PERSONAL_MAIN_TOOL_IDS],
|
|
154
|
+
skills: {
|
|
155
|
+
mode: "replace",
|
|
156
|
+
include: []
|
|
157
|
+
},
|
|
158
|
+
runtime: { thinkingLevel: "off" },
|
|
159
|
+
models: { chat: {
|
|
160
|
+
primary: chosen.id,
|
|
161
|
+
fallbacks: []
|
|
162
|
+
} }
|
|
163
|
+
});
|
|
164
|
+
else if (existing.provisioningState !== "ready" || existing.models?.chat?.primary !== chosen.id || existing.runtime?.thinkingLevel !== "off") await catalog.update(agentId, {
|
|
165
|
+
models: { chat: {
|
|
166
|
+
primary: chosen.id,
|
|
167
|
+
fallbacks: []
|
|
168
|
+
} },
|
|
169
|
+
runtime: {
|
|
170
|
+
...existing.runtime,
|
|
171
|
+
thinkingLevel: "off"
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
const record = getPersonalAgent(ownerId);
|
|
175
|
+
if (!record) throw new Error("Personal Agent provisioning did not complete");
|
|
176
|
+
const conversationId = record.conversationId;
|
|
177
|
+
service.refreshAgentCatalog();
|
|
178
|
+
if (!getSessionMetadata(conversationId)) createConversation({
|
|
179
|
+
agentId,
|
|
180
|
+
sourceChannel: "webchat",
|
|
181
|
+
name: record.displayName,
|
|
182
|
+
hiddenFromSessionList: true,
|
|
183
|
+
customData: {
|
|
184
|
+
personalAgent: true,
|
|
185
|
+
keepHiddenFromSessionList: true
|
|
186
|
+
}
|
|
187
|
+
}, "", conversationId);
|
|
188
|
+
ensurePersonalConversationVisibility(ownerId);
|
|
189
|
+
setSessionConfig(conversationId, {
|
|
190
|
+
modelOverride: chosen.id,
|
|
191
|
+
fixedModel: true,
|
|
192
|
+
thinkingLevel: "off"
|
|
193
|
+
}, process.cwd());
|
|
194
|
+
return getPersonalAgent(ownerId) ?? record;
|
|
195
|
+
}
|
|
196
|
+
async function patchPersonalProfile(service, ownerId, revision, displayName, preferences, appearance) {
|
|
197
|
+
const updated = await updatePersonalProfileRecord(ownerId, revision, displayName, preferences, appearance);
|
|
198
|
+
if (!updated) return null;
|
|
199
|
+
service.refreshAgentCatalog();
|
|
200
|
+
service.agentService.evictSessionAgent(updated.conversationId);
|
|
201
|
+
return updated;
|
|
202
|
+
}
|
|
203
|
+
async function updatePersonalProfileRecord(ownerId, revision, displayName, preferences, appearance) {
|
|
204
|
+
const current = new AgentCatalogRepository().get(personalAgentId(ownerId));
|
|
205
|
+
if (!current || current.provisioningState !== "ready" || current.revision !== revision || getPersonalAgent(ownerId)?.state !== "ready") return null;
|
|
206
|
+
const profile = {
|
|
207
|
+
...current.profile,
|
|
208
|
+
name: displayName,
|
|
209
|
+
emoji: appearanceEmoji(appearance),
|
|
210
|
+
responsePreferences: preferences,
|
|
211
|
+
instructions: personalInstructions(preferences)
|
|
212
|
+
};
|
|
213
|
+
try {
|
|
214
|
+
await new AgentCatalogService().update(current.id, { profile }, revision);
|
|
215
|
+
} catch (error) {
|
|
216
|
+
if (error instanceof Error && error.message === "Agent revision conflict") return null;
|
|
217
|
+
throw error;
|
|
218
|
+
}
|
|
219
|
+
return getPersonalAgent(ownerId);
|
|
220
|
+
}
|
|
221
|
+
//#endregion
|
|
222
|
+
export { PersonalAppearanceSchema, PersonalPreferencesSchema, createOrResumePersonalAgent, ensurePersonalConversationVisibility, listPersonalModels, patchPersonalProfile, personalInstructions, refreshPersonalDelegationGuidance, updatePersonalProfileRecord };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { init_paths_state, resolveXopcCloudCatalogCachePath } from "../config/paths-state.js";
|
|
3
|
-
import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
|
|
4
3
|
import { ComputerProfileSchema, init_src } from "../../packages/computer-control-contract/src/index.js";
|
|
4
|
+
import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
|
|
5
5
|
import { voiceManifestSchema } from "../../packages/realtime-protocol/src/voice-catalog.js";
|
|
6
6
|
import { init_voice } from "../../packages/realtime-protocol/src/voice.js";
|
|
7
7
|
import { readFileSync, rmSync } from "node:fs";
|
|
@@ -6,6 +6,7 @@ import { findConversationIdByTranscriptId } from "../storage/sqlite/session-repo
|
|
|
6
6
|
import { getSessionConfig } from "../storage/sqlite/config-repository.js";
|
|
7
7
|
import { init_sqlite } from "../storage/sqlite/index.js";
|
|
8
8
|
import { SessionConfigSchema, init_schema } from "../config/schema.js";
|
|
9
|
+
import { isPersonalConversation } from "../personal-agent/repository.js";
|
|
9
10
|
import { normalizeThinkLevel, normalizeVerboseLevel } from "../agent/transcript/thinking-types.js";
|
|
10
11
|
import { evaluateSessionFreshness, resolveSessionResetPolicy } from "./reset-policy.js";
|
|
11
12
|
import { resolveChannelResetConfig, resolveSessionResetType } from "./reset-type.js";
|
|
@@ -51,12 +52,13 @@ async function resolveSession(opts) {
|
|
|
51
52
|
sessionStartedAt: sessionMetadata.sessionStartedAt ? Date.parse(sessionMetadata.sessionStartedAt) : void 0,
|
|
52
53
|
lastInteractionAt: sessionMetadata.lastInteractionAt ? Date.parse(sessionMetadata.lastInteractionAt) : void 0
|
|
53
54
|
} : void 0 });
|
|
54
|
-
const
|
|
55
|
+
const freshness = sessionMetadata ? evaluateSessionFreshness({
|
|
55
56
|
updatedAt: Date.parse(sessionMetadata.updatedAt),
|
|
56
57
|
...lifecycle,
|
|
57
58
|
now,
|
|
58
59
|
policy: resetPolicy
|
|
59
|
-
}) : { fresh: false }
|
|
60
|
+
}) : { fresh: false };
|
|
61
|
+
const fresh = Boolean(sessionMetadata && conversationId && isPersonalConversation(conversationId)) || freshness.fresh;
|
|
60
62
|
const transcriptId = opts.transcriptId?.trim() || (fresh ? sessionMetadata?.transcriptId : void 0) || randomUUID();
|
|
61
63
|
const isNewSession = !fresh && !opts.transcriptId?.trim();
|
|
62
64
|
if (isNewSession && conversationId) log.debug({
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS task_criterion_reviews (
|
|
2
|
+
task_id TEXT NOT NULL,
|
|
3
|
+
contract_version INTEGER NOT NULL,
|
|
4
|
+
criterion_index INTEGER NOT NULL,
|
|
5
|
+
criterion_text TEXT NOT NULL,
|
|
6
|
+
status TEXT NOT NULL CHECK (status IN ('passed', 'failed')),
|
|
7
|
+
note TEXT,
|
|
8
|
+
reviewed_by_json TEXT NOT NULL,
|
|
9
|
+
reviewed_at INTEGER NOT NULL,
|
|
10
|
+
PRIMARY KEY (task_id, contract_version, criterion_index),
|
|
11
|
+
FOREIGN KEY (task_id, contract_version) REFERENCES task_contracts(task_id, version) ON DELETE CASCADE
|
|
12
|
+
);
|