@xopcai/xopc 0.0.359 → 0.0.360

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.
Files changed (222) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D-yhlYSG.js → agent-avatar-dicebear-CQTERenW.js} +1 -1
  4. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CPF0lunJ.js +1 -0
  5. package/dist/gateway/static/root/assets/agent-plugin-dialog-BjDaZlKy.js +1 -0
  6. package/dist/gateway/static/root/assets/agents-XopBILLB.js +66 -0
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-CiSdkzuX.js → app-management-settings-panel-V5QVeMvW.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-SdlCHKg8.js → appearance-settings-BDkRcoI6.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-ntyBe6mP.js → apps-page-DzCyL89L.js} +1 -1
  10. package/dist/gateway/static/root/assets/{automations-page-DU0R5C65.js → automations-page-DOu1wMOV.js} +1 -1
  11. package/dist/gateway/static/root/assets/automations-workspace-CiY_2otj.js +7 -0
  12. package/dist/gateway/static/root/assets/{block-editor-CLejMPkV.js → block-editor-K6is5GrS.js} +3 -3
  13. package/dist/gateway/static/root/assets/{browser-automations-page-BjGswNM0.js → browser-automations-page-B8IiXEBs.js} +2 -2
  14. package/dist/gateway/static/root/assets/{browser-settings-page-DBcYssNQ.js → browser-settings-page-Cms2Bu3Q.js} +2 -2
  15. package/dist/gateway/static/root/assets/{capabilities-page-CsTpcrPP.js → capabilities-page-BAFRNHQv.js} +2 -2
  16. package/dist/gateway/static/root/assets/capabilities-settings-panel-Cws6od1d.js +8 -0
  17. package/dist/gateway/static/root/assets/{capability-header-actions-B0Xiav_-.js → capability-header-actions-wh3Nr0qS.js} +1 -1
  18. package/dist/gateway/static/root/assets/channels-DxwismTc.js +1 -0
  19. package/dist/gateway/static/root/assets/{chat-terminal-dock-C9pMFB6k.js → chat-terminal-dock-BU-X9nu1.js} +2 -2
  20. package/dist/gateway/static/root/assets/computer-settings-page-MyXsSqFJ.js +1 -0
  21. package/dist/gateway/static/root/assets/{connector-service-page-OyQKwHNr.js → connector-service-page-DyxPM_MZ.js} +1 -1
  22. package/dist/gateway/static/root/assets/connectors-page-C7-OC3MW.js +2 -0
  23. package/dist/gateway/static/root/assets/{constants-Co2_smKQ.js → constants-Dy8Gw0sF.js} +1 -1
  24. package/dist/gateway/static/root/assets/{date-picker-DxGsweV_.js → date-picker-WRFvi7Pu.js} +1 -1
  25. package/dist/gateway/static/root/assets/{dependency-picker-D9ZfAJwn.js → dependency-picker-CLun5Tst.js} +1 -1
  26. package/dist/gateway/static/root/assets/{desktop-pet-DFgK1z5i.js → desktop-pet-iaVa9vVM.js} +1 -1
  27. package/dist/gateway/static/root/assets/{desktop-pet-settings-CyFW0raW.js → desktop-pet-settings-0RS3sP3Z.js} +1 -1
  28. package/dist/gateway/static/root/assets/device-pairing-wizard-DVAGb04L.js +1 -0
  29. package/dist/gateway/static/root/assets/{directory-picker-path-field-2nrl6Exh.js → directory-picker-path-field-Btlldlt3.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-debug-page-BodxNAys.js → extension-debug-page-BImQT4PU.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-page-DMb2YFlb.js → extension-page-BmuLv-ET.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-provider-aigS3RJu.js → extension-provider-Dg7cRxDX.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-D3hvXtxi.js → extension-settings-page-7Kr8UJK4.js} +1 -1
  34. package/dist/gateway/static/root/assets/{fallback-models-DsXySQVF.js → fallback-models-B0w1lumZ.js} +1 -1
  35. package/dist/gateway/static/root/assets/gateway-settings-DmPvmwYp.js +1 -0
  36. package/dist/gateway/static/root/assets/home-page-N0Mp-eTJ.js +1 -0
  37. package/dist/gateway/static/root/assets/{imports-page-Czzsa_Eu.js → imports-page-BLOJY67-.js} +1 -1
  38. package/dist/gateway/static/root/assets/{index-DUgsBdV3.css → index-B7AHDHSO.css} +1 -1
  39. package/dist/gateway/static/root/assets/{index-DUU_2HF0.js → index-BXrBL_Hb.js} +41 -41
  40. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DqsFlXlp.js → keyboard-shortcuts-settings-Dlbsip2R.js} +1 -1
  41. package/dist/gateway/static/root/assets/{local-app-workbench-page-BcDFXc1k.js → local-app-workbench-page-nyWeTK0r.js} +1 -1
  42. package/dist/gateway/static/root/assets/{local-apps-page-BaxqXA1-.js → local-apps-page-CfEpFLs0.js} +1 -1
  43. package/dist/gateway/static/root/assets/{logs-page-DmJjZ0Uk.js → logs-page-A38cawkA.js} +2 -2
  44. package/dist/gateway/static/root/assets/{management-settings-1O7zsu4t.js → management-settings-Cse9K61x.js} +1 -1
  45. package/dist/gateway/static/root/assets/{note-detail-panel-BLvVlQG8.js → note-detail-panel-CUGVyo2V.js} +3 -3
  46. package/dist/gateway/static/root/assets/notes-page-Dk89l5dC.js +8 -0
  47. package/dist/gateway/static/root/assets/{page-context-capture-button-gL3453SU.js → page-context-capture-button-C72qIgBg.js} +1 -1
  48. package/dist/gateway/static/root/assets/personal-page-DCtduzh8.js +1 -0
  49. package/dist/gateway/static/root/assets/{product-open-page-Dw8JPizo.js → product-open-page-CT98FsVl.js} +1 -1
  50. package/dist/gateway/static/root/assets/{project-detail-page-Zg4KZ0vK.js → project-detail-page-BlqOVwKP.js} +1 -1
  51. package/dist/gateway/static/root/assets/{projects-page-B33uj1lz.js → projects-page-DVN2q_yR.js} +1 -1
  52. package/dist/gateway/static/root/assets/remote-access-hub-BP5kUgIN.js +1 -0
  53. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BLNXzyeh.js → runtime-tools-settings-panel-ry0jprz7.js} +1 -1
  54. package/dist/gateway/static/root/assets/{scenes-page-D868Zuj9.js → scenes-page-CV1GkOj6.js} +2 -2
  55. package/dist/gateway/static/root/assets/{schema-form-5z33VTce.js → schema-form-C5zMrxgR.js} +1 -1
  56. package/dist/gateway/static/root/assets/{send-session-input-OaBPDJ9E.js → send-session-input-Dt0t5SoR.js} +1 -1
  57. package/dist/gateway/static/root/assets/session-manager-DDR-gv_e.js +16 -0
  58. package/dist/gateway/static/root/assets/sessions-page-BXtGeOsR.js +1 -0
  59. package/dist/gateway/static/root/assets/settings-advanced-gate-CvFVkELy.js +1 -0
  60. package/dist/gateway/static/root/assets/{settings-page-BG_dOYMq.js → settings-page-C88fsfZF.js} +1 -1
  61. package/dist/gateway/static/root/assets/{setup-status-panel-DNj1hD_H.js → setup-status-panel-DESlRgZS.js} +1 -1
  62. package/dist/gateway/static/root/assets/{share-preview-page-M_rAQR60.js → share-preview-page-D5Gey-6E.js} +1 -1
  63. package/dist/gateway/static/root/assets/shares-settings-btoP07Fx.js +1 -0
  64. package/dist/gateway/static/root/assets/{skill-api-BBaKs-Xx.js → skill-api-1hbX3qDC.js} +1 -1
  65. package/dist/gateway/static/root/assets/skills-page-DYJbwwBT.js +2 -0
  66. package/dist/gateway/static/root/assets/{system-settings-panel-DKjsZo49.js → system-settings-panel-DbNk-Jwq.js} +1 -1
  67. package/dist/gateway/static/root/assets/{task-detail-page-DSvaiKGb.js → task-detail-page-DoLKOJrE.js} +1 -1
  68. package/dist/gateway/static/root/assets/{tunnel-api-DR8Qu6R_.js → tunnel-api-H3FheXYH.js} +1 -1
  69. package/dist/gateway/static/root/assets/{usage-page-CAIqAduR.js → usage-page-DGbqcsV6.js} +1 -1
  70. package/dist/gateway/static/root/assets/{use-composer-attachments-CUaywGe0.js → use-composer-attachments-pzPAUV_o.js} +1 -1
  71. package/dist/gateway/static/root/assets/{use-file-preview-expanded-D809I8ur.js → use-file-preview-expanded-DNhXjL0W.js} +1 -1
  72. package/dist/gateway/static/root/assets/user-model-page-7pW4Pazn.js +2 -0
  73. package/dist/gateway/static/root/assets/{work-discovery-overlay-wGFcle2p.js → work-discovery-overlay-DfyI9kVf.js} +1 -1
  74. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CewS2IbN.js → workflow-run-setup-panel-De80GODZ.js} +2 -2
  75. package/dist/gateway/static/root/assets/workflows-page-BuH3pC1C.js +6 -0
  76. package/dist/gateway/static/root/assets/{workspace-api-BtXzxf_w.js → workspace-api-Dwa8kHdY.js} +2 -2
  77. package/dist/gateway/static/root/index.html +9 -9
  78. package/dist/package.js +1 -1
  79. package/dist/packages/gateway-contract/src/index.js +2 -0
  80. package/dist/packages/gateway-contract/src/task-result-delivery.js +30 -0
  81. package/dist/src/agent/agent-manager.js +3 -3
  82. package/dist/src/agent/background-review/run-background-review.js +1 -1
  83. package/dist/src/agent/context/workspace-templates/SOUL.md +2 -0
  84. package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
  85. package/dist/src/agent/external-tools/gateway-tools.js +41 -1
  86. package/dist/src/agent/image/tool-model-config.js +1 -1
  87. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
  88. package/dist/src/agent/prompt/sections/behavior.js +4 -1
  89. package/dist/src/agent/prompt/sections/memory-skills.js +2 -0
  90. package/dist/src/agent/service.js +2 -2
  91. package/dist/src/agent/session/session-config-service.js +11 -3
  92. package/dist/src/agent/skills/hub-lock.js +1 -1
  93. package/dist/src/agent/skills/index.js +1 -1
  94. package/dist/src/agent/skills/managed-store.js +1 -1
  95. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  96. package/dist/src/agent/tools/factory.js +32 -6
  97. package/dist/src/agent/tools/personal-preference-tool.js +11 -0
  98. package/dist/src/agent/tools/personal-request-result-tool.d.ts +22 -0
  99. package/dist/src/agent/tools/personal-request-result-tool.js +84 -0
  100. package/dist/src/agent/tools/personal-request-tool.d.ts +3 -0
  101. package/dist/src/agent/tools/personal-request-tool.js +100 -0
  102. package/dist/src/agent/tools/personal-task-tool.d.ts +6 -0
  103. package/dist/src/agent/tools/personal-task-tool.js +12 -10
  104. package/dist/src/agent/tools/tool-media.js +2 -3
  105. package/dist/src/agent/tools/xopc-use-tool.js +2 -2
  106. package/dist/src/agent-catalog/capabilities.js +2 -2
  107. package/dist/src/auth/credentials.js +1 -1
  108. package/dist/src/auth/oauth-provider-lock.js +1 -1
  109. package/dist/src/auth/profiles/store.js +1 -1
  110. package/dist/src/automations/capabilities/drafts.js +1 -1
  111. package/dist/src/bootstrap/application-state.js +1 -1
  112. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  113. package/dist/src/capabilities/runtime/dispatcher.js +1 -1
  114. package/dist/src/capabilities/runtime/product.js +1 -1
  115. package/dist/src/cli/commands/agent.js +1 -1
  116. package/dist/src/cli/commands/agents.js +1 -1
  117. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  118. package/dist/src/cli/commands/models.js +1 -1
  119. package/dist/src/cli/commands/onboard/model.js +1 -1
  120. package/dist/src/cli/templates.js +4 -0
  121. package/dist/src/cli/utils/init-workspace-core.js +1 -1
  122. package/dist/src/config/index.js +3 -3
  123. package/dist/src/config/loader.js +1 -1
  124. package/dist/src/config/models-json.js +1 -1
  125. package/dist/src/config/schema.js +1 -1
  126. package/dist/src/connectors/connection-recovery-service.d.ts +2 -0
  127. package/dist/src/connectors/connection-recovery-service.js +23 -5
  128. package/dist/src/extensions/agent-plugins/validation.js +1 -1
  129. package/dist/src/extensions/lockfile.js +1 -1
  130. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  131. package/dist/src/gateway/agents-admin.js +2 -2
  132. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  133. package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
  134. package/dist/src/gateway/hono/routes/media.js +4 -3
  135. package/dist/src/gateway/hono/routes/notes.js +2 -2
  136. package/dist/src/gateway/hono/routes/personal-agent.js +68 -0
  137. package/dist/src/gateway/hono/routes/projects.js +2 -2
  138. package/dist/src/gateway/hono/routes/session-input-handler.js +1 -1
  139. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  140. package/dist/src/gateway/image-generation-setup.js +2 -2
  141. package/dist/src/gateway/lock.js +1 -1
  142. package/dist/src/gateway/media-access.js +2 -2
  143. package/dist/src/gateway/service.d.ts +3 -0
  144. package/dist/src/gateway/service.js +46 -5
  145. package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
  146. package/dist/src/local-apps/service.js +1 -1
  147. package/dist/src/media/index.js +2 -2
  148. package/dist/src/media/session-references.d.ts +2 -0
  149. package/dist/src/media/session-references.js +22 -2
  150. package/dist/src/media/store.d.ts +1 -0
  151. package/dist/src/media/store.js +2 -1
  152. package/dist/src/personal-agent/capability-service.d.ts +14 -0
  153. package/dist/src/personal-agent/capability-service.js +63 -0
  154. package/dist/src/personal-agent/communication.d.ts +4 -0
  155. package/dist/src/personal-agent/communication.js +24 -0
  156. package/dist/src/personal-agent/model-config.d.ts +5 -0
  157. package/dist/src/personal-agent/model-config.js +59 -0
  158. package/dist/src/personal-agent/policy.d.ts +1 -1
  159. package/dist/src/personal-agent/policy.js +2 -0
  160. package/dist/src/personal-agent/repository.d.ts +1 -0
  161. package/dist/src/personal-agent/repository.js +3 -1
  162. package/dist/src/personal-agent/request-delivery.d.ts +4 -0
  163. package/dist/src/personal-agent/request-delivery.js +159 -0
  164. package/dist/src/personal-agent/request-repository.d.ts +33 -0
  165. package/dist/src/personal-agent/request-repository.js +71 -0
  166. package/dist/src/personal-agent/request-result.d.ts +21 -0
  167. package/dist/src/personal-agent/request-result.js +45 -0
  168. package/dist/src/personal-agent/request-service.d.ts +18 -0
  169. package/dist/src/personal-agent/request-service.js +308 -0
  170. package/dist/src/personal-agent/service.js +30 -7
  171. package/dist/src/providers/model-catalog-persistence.js +1 -1
  172. package/dist/src/session/client-history.d.ts +2 -1
  173. package/dist/src/session/client-history.js +40 -0
  174. package/dist/src/session/compact-history.js +9 -5
  175. package/dist/src/session/config-store.js +2 -1
  176. package/dist/src/session/session-context-for-llm.js +55 -0
  177. package/dist/src/session/store.js +2 -0
  178. package/dist/src/session/types.d.ts +2 -0
  179. package/dist/src/storage/sqlite/connection-wait-repository.d.ts +5 -1
  180. package/dist/src/storage/sqlite/connection-wait-repository.js +38 -8
  181. package/dist/src/storage/sqlite/migrations/231_task_result_deliveries.sql +32 -0
  182. package/dist/src/storage/sqlite/migrations/232_personal_requests.sql +28 -0
  183. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  184. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  185. package/dist/src/storage/sqlite/schema.js +1 -1
  186. package/dist/src/storage/sqlite/session-repository.js +33 -0
  187. package/dist/src/tasks/capabilities/read.js +2 -2
  188. package/dist/src/tasks/task-application-service.d.ts +1 -0
  189. package/dist/src/tasks/task-application-service.js +7 -0
  190. package/dist/src/tasks/task-context-assembler.js +1 -0
  191. package/dist/src/tasks/task-main-update-delivery.js +32 -1
  192. package/dist/src/tasks/task-result-delivery-repository.d.ts +18 -0
  193. package/dist/src/tasks/task-result-delivery-repository.js +144 -0
  194. package/dist/src/tasks/task-result-delivery-service.d.ts +4 -0
  195. package/dist/src/tasks/task-result-delivery-service.js +128 -0
  196. package/dist/src/tasks/task-run-coordinator.js +6 -1
  197. package/dist/src/tasks/task-run-dispatcher.d.ts +1 -0
  198. package/dist/src/tasks/task-run-dispatcher.js +22 -3
  199. package/dist/src/tui/backends/embedded-backend.js +2 -2
  200. package/dist/src/voice/realtime/persona-context.js +1 -1
  201. package/package.json +3 -3
  202. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CYq-3pbE.js +0 -1
  203. package/dist/gateway/static/root/assets/agent-plugin-dialog-Cx3UbhqT.js +0 -1
  204. package/dist/gateway/static/root/assets/agents-Ce9uvui7.js +0 -66
  205. package/dist/gateway/static/root/assets/automations-workspace-BaHJml4R.js +0 -7
  206. package/dist/gateway/static/root/assets/capabilities-settings-panel-BXlVwnMr.js +0 -8
  207. package/dist/gateway/static/root/assets/channels-TPqwcbZ4.js +0 -1
  208. package/dist/gateway/static/root/assets/computer-settings-page-BJOn14Ow.js +0 -1
  209. package/dist/gateway/static/root/assets/connectors-page-DBWH5bVr.js +0 -2
  210. package/dist/gateway/static/root/assets/device-pairing-wizard-C6Co5dT3.js +0 -1
  211. package/dist/gateway/static/root/assets/gateway-settings-CubM1m6Z.js +0 -1
  212. package/dist/gateway/static/root/assets/home-page-CQ9y_LMT.js +0 -1
  213. package/dist/gateway/static/root/assets/notes-page-AWU_G61i.js +0 -8
  214. package/dist/gateway/static/root/assets/personal-page-BPy5m3QR.js +0 -1
  215. package/dist/gateway/static/root/assets/remote-access-hub-BZoUVzgS.js +0 -1
  216. package/dist/gateway/static/root/assets/session-manager-BK5IvdGz.js +0 -16
  217. package/dist/gateway/static/root/assets/sessions-page-Du7ueBFc.js +0 -1
  218. package/dist/gateway/static/root/assets/settings-advanced-gate-CaxCsIIZ.js +0 -1
  219. package/dist/gateway/static/root/assets/shares-settings-Cr_Ut6FE.js +0 -1
  220. package/dist/gateway/static/root/assets/skills-page-DU7fV5pc.js +0 -2
  221. package/dist/gateway/static/root/assets/user-model-page-C--t6SLp.js +0 -2
  222. package/dist/gateway/static/root/assets/workflows-page-CxfsWFL5.js +0 -6
@@ -1,12 +1,15 @@
1
1
  import { getDevice, init_device_access_repository } from "../../../storage/sqlite/device-access-repository.js";
2
+ import { getPersonalRequest, init_request_repository, listPersonalRequests } from "../../../personal-agent/request-repository.js";
2
3
  import { TaskOriginRepository } from "../../../tasks/task-origin-repository.js";
3
4
  import { getPersonalAgent } from "../../../personal-agent/repository.js";
5
+ import { cancelPersonalRequest, personalRequestSnapshot, publishPersonalRequest } from "../../../personal-agent/request-service.js";
4
6
  import { PersonalOnboardingDraftSchema, PersonalOnboardingStepSchema, finishPersonalWelcome, getPersonalOnboarding, savePersonalOnboarding } from "../../../personal-agent/onboarding.js";
5
7
  import { PersonalAppearanceSchema, PersonalPreferencesSchema, createOrResumePersonalAgent, ensurePersonalConversationVisibility, listPersonalModels, patchPersonalProfile, refreshPersonalDelegationGuidance } from "../../../personal-agent/service.js";
6
8
  import { getGatewayPrincipal } from "../../security/gateway-principal.js";
7
9
  import { z } from "zod";
8
10
  //#region src/gateway/hono/routes/personal-agent.ts
9
11
  init_device_access_repository();
12
+ init_request_repository();
10
13
  const CreateSchema = z.object({
11
14
  model: z.string().trim().min(3).optional(),
12
15
  displayName: z.string().trim().min(1).max(60).optional(),
@@ -71,6 +74,71 @@ function registerPersonalAgentRoutes(authenticated, deps) {
71
74
  payload: await listPersonalModels()
72
75
  });
73
76
  });
77
+ authenticated.get("/api/personal-agent/requests", (c) => {
78
+ const ownerId = owner(c);
79
+ if (!ownerId) return c.json({
80
+ ok: false,
81
+ error: "Owner access is required"
82
+ }, 403);
83
+ const record = getPersonalAgent(ownerId);
84
+ return c.json({
85
+ ok: true,
86
+ payload: record ? listPersonalRequests(record.conversationId).map(personalRequestSnapshot) : []
87
+ });
88
+ });
89
+ authenticated.get("/api/personal-agent/requests/:requestId", (c) => {
90
+ const ownerId = owner(c);
91
+ if (!ownerId) return c.json({
92
+ ok: false,
93
+ error: "Owner access is required"
94
+ }, 403);
95
+ const request = getPersonalRequest(c.req.param("requestId"));
96
+ if (!request || request.conversationId !== getPersonalAgent(ownerId)?.conversationId) return c.json({
97
+ ok: false,
98
+ error: "Request not found"
99
+ }, 404);
100
+ return c.json({
101
+ ok: true,
102
+ payload: personalRequestSnapshot(request)
103
+ });
104
+ });
105
+ authenticated.post("/api/personal-agent/requests/:requestId/cancel", deps.strictRateLimitMiddleware, async (c) => {
106
+ const ownerId = owner(c);
107
+ if (!ownerId) return c.json({
108
+ ok: false,
109
+ error: "Owner access is required"
110
+ }, 403);
111
+ const request = getPersonalRequest(c.req.param("requestId"));
112
+ if (!request || request.conversationId !== getPersonalAgent(ownerId)?.conversationId) return c.json({
113
+ ok: false,
114
+ error: "Request not found"
115
+ }, 404);
116
+ const body = z.object({ expectedVersion: z.number().int().positive() }).strict().safeParse(await c.req.json().catch(() => null));
117
+ if (!body.success) return c.json({
118
+ ok: false,
119
+ error: "expectedVersion is required"
120
+ }, 400);
121
+ if (body.data.expectedVersion !== request.version) return c.json({
122
+ ok: false,
123
+ error: "Request changed"
124
+ }, 409);
125
+ try {
126
+ const cancelled = cancelPersonalRequest(request);
127
+ publishPersonalRequest(cancelled);
128
+ return c.json({
129
+ ok: true,
130
+ payload: {
131
+ ...cancelled,
132
+ executionStopConfirmed: false
133
+ }
134
+ });
135
+ } catch (error) {
136
+ return c.json({
137
+ ok: false,
138
+ error: error instanceof Error ? error.message : String(error)
139
+ }, 409);
140
+ }
141
+ });
74
142
  authenticated.get("/api/personal-agent/onboarding", (c) => {
75
143
  const ownerId = owner(c);
76
144
  if (!ownerId) return c.json({
@@ -7,12 +7,12 @@ import { loadTranscriptRowsForSession } from "../../../storage/sqlite/transcript
7
7
  import { init_sqlite } from "../../../storage/sqlite/index.js";
8
8
  import { ActivityService } from "../../../activity/service.js";
9
9
  import "../../../activity/index.js";
10
+ import { CapabilityError } from "../../../capabilities/runtime/errors.js";
11
+ import "../../../capabilities/runtime/dispatcher.js";
10
12
  import { resolveEffectiveAgentProfile } from "../../../config/agent-profile.js";
11
13
  import { TaskReadModelProjector } from "../../../tasks/task-read-model-projector.js";
12
14
  import { listKnowledgeItems, writeKnowledgeItem } from "../../../knowledge-memory/repository.js";
13
15
  import "../../../knowledge-memory/index.js";
14
- import { CapabilityError } from "../../../capabilities/runtime/errors.js";
15
- import "../../../capabilities/runtime/dispatcher.js";
16
16
  import { ProjectWorkspaceConflictError, ProjectWorkspaceMissingError } from "../../../projects/workspace-project.js";
17
17
  import { inferProjectExecutionMode, inferProjectKind } from "../../../projects/project-kind.js";
18
18
  import { ProjectDeletionBlockedError, ProjectWorkspaceInUseError } from "../../../projects/project-service.js";
@@ -4,9 +4,9 @@ import { browserPageContextsInputSchema } from "../../../../packages/gateway-con
4
4
  import { parseUserTurnDocument, userTurnDocumentRefIds } from "../../../../packages/gateway-contract/src/user-turn-document.js";
5
5
  import { init_src } from "../../../../packages/gateway-contract/src/index.js";
6
6
  import { endpointTurnClaimSchema, init_src as init_src$1 } from "../../../../packages/endpoint-tools-protocol/src/index.js";
7
- import { init_providers, resolveModel } from "../../../providers/index.js";
8
7
  import { CapabilityError } from "../../../capabilities/runtime/errors.js";
9
8
  import "../../../capabilities/runtime/dispatcher.js";
9
+ import { init_providers, resolveModel } from "../../../providers/index.js";
10
10
  import { getModelThinking } from "../../../providers/model-thinking.js";
11
11
  import { validateWebchatAttachments, validateWebchatContent } from "../../chat-limits.js";
12
12
  import { isTaskDestructiveCommand } from "../../../session/reset-triggers.js";
@@ -6,9 +6,9 @@ import { hasGatewayScope, init_gateway_scopes } from "../../security/gateway-sco
6
6
  import { enqueueTaskChangedEvent, init_task_change_events } from "../../../tasks/task-change-events.js";
7
7
  import { TaskRepository, init_task_repository } from "../../../tasks/task-repository.js";
8
8
  import { TaskRunRepository, init_task_run_repository } from "../../../tasks/task-run-repository.js";
9
- import { TaskConversationRepository } from "../../../tasks/task-conversation-repository.js";
10
9
  import { CapabilityError } from "../../../capabilities/runtime/errors.js";
11
10
  import "../../../capabilities/runtime/dispatcher.js";
11
+ import { TaskConversationRepository } from "../../../tasks/task-conversation-repository.js";
12
12
  import { TaskCriterionReviewRepository } from "../../../tasks/task-criterion-review-repository.js";
13
13
  import { TaskContextMutationOutputSchema } from "../../../tasks/capabilities/relations.js";
14
14
  import { TaskDeleteOutputSchema } from "../../../tasks/capabilities/management.js";
@@ -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 { ConfigSchema, init_schema } from "../config/schema.js";
4
3
  import { init_agent_scope } from "../agent/agent-scope.js";
4
+ import { AgentCatalogService } from "../agent-catalog/service.js";
5
+ import { ConfigSchema, init_schema } from "../config/schema.js";
5
6
  import { resolveEffectiveAgentConfigForAgent } from "../config/agent-profile.js";
6
7
  import { fetchWithTimeoutGuarded } from "../media-shared/http/provider-http.js";
7
8
  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();
@@ -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 net from "node:net";
5
4
  import fs$1 from "node:fs/promises";
5
+ import net from "node:net";
6
6
  import { homedir } from "os";
7
7
  //#region src/gateway/lock.ts
8
8
  /**
@@ -3,7 +3,7 @@ import { FileServiceError } from "../files/file-service.js";
3
3
  import { resolveMediaReference } from "../media/media-reference.js";
4
4
  import { pendingTranscriptReferencesMediaUri } from "../agent/inbound/attachment-pipeline.js";
5
5
  import { TaskContextRepository } from "../tasks/task-context-repository.js";
6
- import { messagesReferenceMediaUri } from "../media/session-references.js";
6
+ import { messagesReferenceMediaUri, taskResultReferencesMediaUri } from "../media/session-references.js";
7
7
  //#region src/gateway/media-access.ts
8
8
  init_task_repository();
9
9
  /** Resolve media only when the supplied session or task references it. */
@@ -11,7 +11,7 @@ async function resolveScopedMediaReference(service, uri, scope) {
11
11
  const { conversationId, taskId } = scope;
12
12
  if (!conversationId && !taskId) throw new FileServiceError(400, "Missing media scope");
13
13
  const media = await resolveMediaReference(uri);
14
- const sessionReferencesUri = conversationId ? messagesReferenceMediaUri(await service.sessionIndexInstance.loadMessages(conversationId), media.uri) || pendingTranscriptReferencesMediaUri(conversationId, media.uri) : false;
14
+ const sessionReferencesUri = conversationId ? messagesReferenceMediaUri(await service.sessionIndexInstance.loadMessages(conversationId), media.uri) || pendingTranscriptReferencesMediaUri(conversationId, media.uri) || taskResultReferencesMediaUri(conversationId, media.uri) : false;
15
15
  const taskReferencesUri = taskId && new TaskRepository().get(taskId) ? new TaskContextRepository().list(taskId).some((edge) => edge.targetKind === "file" && edge.targetId === media.uri) : false;
16
16
  if (!sessionReferencesUri && !taskReferencesUri) throw new FileServiceError(404, "Not found");
17
17
  return media;
@@ -48,6 +48,7 @@ export declare class GatewayService {
48
48
  private homeIntelligenceHost;
49
49
  private sessionIndex;
50
50
  private running;
51
+ private stopping;
51
52
  private startTime;
52
53
  private workspacePath;
53
54
  private readonly configCoordinator;
@@ -79,6 +80,7 @@ export declare class GatewayService {
79
80
  private connectorLearningCoordinator;
80
81
  private connectedKnowledgeCoordinator;
81
82
  private stopSessionTranscriptAutomationEvents;
83
+ private stopTaskResultQueued;
82
84
  private stopRealtimeLogBridge;
83
85
  /**
84
86
  * Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
@@ -127,6 +129,7 @@ export declare class GatewayService {
127
129
  private createNotificationService;
128
130
  private readonly taskRunDispatch;
129
131
  private readonly taskMainUpdateDispatch;
132
+ private readonly taskResultDispatch;
130
133
  dispatchTaskRuns(): void;
131
134
  ensureTaskConversation(taskId: string, options?: {
132
135
  runId?: string;
@@ -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";
20
21
  import { init_config, resolveKnowledgeReadPolicy } from "../user-context/config.js";
21
22
  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";
@@ -46,6 +46,7 @@ import { buildNoteAgentContext } from "../notes/agent-context.js";
46
46
  import { NotesStore } from "../notes/store.js";
47
47
  import { NotesService } from "../notes/service.js";
48
48
  import { LocalAppService } from "../local-apps/service.js";
49
+ import { onTaskResultQueued } from "../tasks/task-result-delivery-repository.js";
49
50
  import { TaskApplicationService } from "../tasks/task-application-service.js";
50
51
  import { AutomationService } from "../automations/service/automation-service.js";
51
52
  import { TaskSignalService } from "../tasks/task-signal-service.js";
@@ -125,6 +126,7 @@ import { getXopcCloudCatalogCoordinator } from "../providers/xopc-cloud-catalog-
125
126
  import { ModelCatalogSyncService } from "../providers/model-catalog-sync-service.js";
126
127
  import { NotificationService } from "../notifications/service.js";
127
128
  import "../local-apps/index.js";
129
+ import { TaskResultDeliveryService } from "../tasks/task-result-delivery-service.js";
128
130
  import { createRuntimeBrowserAutomationService } from "../browser/automations/runtime-service.js";
129
131
  import "../browser/automations/index.js";
130
132
  import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
@@ -190,6 +192,7 @@ var GatewayService = class {
190
192
  homeIntelligenceHost = null;
191
193
  sessionIndex;
192
194
  running = false;
195
+ stopping = false;
193
196
  startTime = Date.now();
194
197
  workspacePath;
195
198
  configCoordinator;
@@ -313,6 +316,7 @@ var GatewayService = class {
313
316
  connectorLearningCoordinator = null;
314
317
  connectedKnowledgeCoordinator = null;
315
318
  stopSessionTranscriptAutomationEvents = null;
319
+ stopTaskResultQueued = null;
316
320
  stopRealtimeLogBridge = null;
317
321
  /**
318
322
  * Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
@@ -823,6 +827,7 @@ var GatewayService = class {
823
827
  }
824
828
  })).ok;
825
829
  });
830
+ if (this.stopping) return;
826
831
  this.createTaskRunDispatcher().dispatch();
827
832
  await this.createWorkflowRunService().dispatchTaskRuns();
828
833
  }, (err) => {
@@ -877,7 +882,26 @@ var GatewayService = class {
877
882
  phase: "task_main_update_dispatch"
878
883
  }, `Main Agent update dispatch failed: ${errorMessage}`);
879
884
  });
885
+ taskResultDispatch = createBackgroundTask(async () => {
886
+ await new TaskResultDeliveryService().drain((conversationId, deliveryId) => {
887
+ this.realtime.broker.publish("sessions", "session.task-result", {
888
+ conversationId,
889
+ deliveryId
890
+ });
891
+ this.emit("session.transcript_updated", {
892
+ key: conversationId,
893
+ deliveryId
894
+ });
895
+ });
896
+ }, (err) => {
897
+ log.error({
898
+ err,
899
+ phase: "task_result_dispatch"
900
+ }, "Task result dispatch failed");
901
+ });
880
902
  dispatchTaskRuns() {
903
+ if (this.stopping) return;
904
+ this.taskResultDispatch();
881
905
  this.taskRunDispatch();
882
906
  this.taskMainUpdateDispatch();
883
907
  }
@@ -957,6 +981,16 @@ var GatewayService = class {
957
981
  saveConfig: (config) => this.saveConfig(config),
958
982
  drain: (conversationId) => {
959
983
  this.agentRunner.inputs.drain(conversationId);
984
+ },
985
+ onPersonalRequestDelivered: (conversationId, requestId) => {
986
+ this.realtime.broker.publish("sessions", "session.task-result", {
987
+ conversationId,
988
+ deliveryId: `personal-request:${requestId}`
989
+ });
990
+ this.emit("session.transcript_updated", {
991
+ key: conversationId,
992
+ requestId
993
+ });
960
994
  }
961
995
  });
962
996
  submitSessionInput(...args) {
@@ -1140,6 +1174,8 @@ var GatewayService = class {
1140
1174
  }
1141
1175
  async startRuntime() {
1142
1176
  if (this.running) return;
1177
+ this.stopping = false;
1178
+ this.taskRunDispatcher = null;
1143
1179
  this.stopRealtimeLogBridge = subscribeToLogs((entry) => {
1144
1180
  this.realtime.broker.publish("logs", "log.entry", entry);
1145
1181
  });
@@ -1189,6 +1225,7 @@ var GatewayService = class {
1189
1225
  this.createNotificationService().start();
1190
1226
  this.startTime = Date.now();
1191
1227
  this.running = true;
1228
+ this.stopTaskResultQueued = onTaskResultQueued(() => this.taskResultDispatch());
1192
1229
  this.taskRunDispatchTimer = setInterval(() => this.dispatchTaskRuns(), 1e3);
1193
1230
  this.taskRunDispatchTimer.unref?.();
1194
1231
  if (this.config.gateway?.scenes?.enabled === true) this.sceneHost = new GatewaySceneHost(getSqliteDatabase(), {
@@ -1477,6 +1514,12 @@ var GatewayService = class {
1477
1514
  }
1478
1515
  async stop() {
1479
1516
  if (!this.running) return;
1517
+ this.stopping = true;
1518
+ this.taskRunDispatcher?.stop();
1519
+ if (this.taskRunDispatchTimer) {
1520
+ clearInterval(this.taskRunDispatchTimer);
1521
+ this.taskRunDispatchTimer = null;
1522
+ }
1480
1523
  await this.sessionPreparations.stop();
1481
1524
  setPairingBroadcastSink(null);
1482
1525
  this.stopRealtimeLogBridge?.();
@@ -1496,10 +1539,6 @@ var GatewayService = class {
1496
1539
  await this.discussionSealer.stop();
1497
1540
  await this.discussionLiveWorker.stop();
1498
1541
  this.notificationService?.stop();
1499
- if (this.taskRunDispatchTimer) {
1500
- clearInterval(this.taskRunDispatchTimer);
1501
- this.taskRunDispatchTimer = null;
1502
- }
1503
1542
  await stopTailscaleExposure().catch((err) => {
1504
1543
  log.warn({ err }, "Tailscale exposure shutdown failed");
1505
1544
  });
@@ -1535,6 +1574,8 @@ var GatewayService = class {
1535
1574
  await this.automationService.stop();
1536
1575
  this.stopSessionTranscriptAutomationEvents?.();
1537
1576
  this.stopSessionTranscriptAutomationEvents = null;
1577
+ this.stopTaskResultQueued?.();
1578
+ this.stopTaskResultQueued = null;
1538
1579
  buckets.destroyAll();
1539
1580
  closeXopcDatabase();
1540
1581
  log.debug("Gateway service stopped");
@@ -1,8 +1,8 @@
1
1
  import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
2
+ import { AgentCatalogService } from "../agent-catalog/service.js";
2
3
  import { getModelCatalogStore, init_model_catalog_store } from "../providers/model-catalog-store.js";
3
4
  import { getAvailableModels, init_providers } from "../providers/index.js";
4
5
  import { compareCatalogModels } from "../providers/model-catalog-ranking.js";
5
- import { AgentCatalogService } from "../agent-catalog/service.js";
6
6
  import { prepareUpdateGlobalDefaults } from "./global-defaults-admin.js";
7
7
  //#region src/gateway/xopc-cloud-capability-setup.ts
8
8
  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";
8
9
  import { init_paths, resolveExtensionsDir } from "../config/paths.js";
9
10
  import { LocalAppStore } from "./store.js";
10
11
  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";
@@ -1,5 +1,5 @@
1
1
  import { getMediaBucketDir, getMediaDir, isPathInside } from "./paths.js";
2
2
  import { MediaUriError, buildMediaUri, parseMediaUri, tryParseMediaUri } from "./uri.js";
3
- import { MEDIA_MAX_BYTES, deleteMediaBuffer, ensureMediaDir, mimeTypeFromMediaPath, readMediaBuffer, resolveMediaBufferPath, saveMediaBuffer } from "./store.js";
3
+ import { MEDIA_ARTIFACT_MAX_BYTES, MEDIA_MAX_BYTES, deleteMediaBuffer, ensureMediaDir, mimeTypeFromMediaPath, readMediaBuffer, resolveMediaBufferPath, saveMediaBuffer } from "./store.js";
4
4
  import { readMediaReference, readMediaReferenceBase64, resolveMediaReference } from "./media-reference.js";
5
- export { MEDIA_MAX_BYTES, MediaUriError, buildMediaUri, deleteMediaBuffer, ensureMediaDir, getMediaBucketDir, getMediaDir, isPathInside, mimeTypeFromMediaPath, parseMediaUri, readMediaBuffer, readMediaReference, readMediaReferenceBase64, resolveMediaBufferPath, resolveMediaReference, saveMediaBuffer, tryParseMediaUri };
5
+ export { MEDIA_ARTIFACT_MAX_BYTES, MEDIA_MAX_BYTES, MediaUriError, buildMediaUri, deleteMediaBuffer, ensureMediaDir, getMediaBucketDir, getMediaDir, isPathInside, mimeTypeFromMediaPath, parseMediaUri, readMediaBuffer, readMediaReference, readMediaReferenceBase64, resolveMediaBufferPath, resolveMediaReference, saveMediaBuffer, tryParseMediaUri };
@@ -2,6 +2,8 @@ import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
2
  export declare function collectMediaUrisFromValues(values: readonly unknown[]): Set<string>;
3
3
  export declare function collectMediaUrisFromMessages(messages: readonly AgentMessage[]): Set<string>;
4
4
  export declare function messagesReferenceMediaUri(messages: readonly AgentMessage[], uri: string): boolean;
5
+ /** Published task results are display rows, so they are absent from provider history. */
6
+ export declare function taskResultReferencesMediaUri(conversationId: string, uri: string): boolean;
5
7
  /**
6
8
  * A media object remains live while any non-deleted session references it,
7
9
  * including archived transcripts retained by a reset of that session key.
@@ -1,8 +1,11 @@
1
1
  import { getSqliteDatabase } from "../storage/sqlite/transaction.js";
2
+ import { parseTaskResultDelivery } from "../../packages/gateway-contract/src/task-result-delivery.js";
3
+ import { init_src } from "../../packages/gateway-contract/src/index.js";
2
4
  import { init_sqlite } from "../storage/sqlite/index.js";
3
5
  import { tryParseMediaUri } from "./uri.js";
4
6
  import { deleteMediaBuffer } from "./store.js";
5
7
  //#region src/media/session-references.ts
8
+ init_src();
6
9
  init_sqlite();
7
10
  function collectFromValue(value, out, seen) {
8
11
  if (!value) return;
@@ -34,6 +37,19 @@ function collectMediaUrisFromMessages(messages) {
34
37
  function messagesReferenceMediaUri(messages, uri) {
35
38
  return collectMediaUrisFromMessages(messages).has(uri.trim());
36
39
  }
40
+ /** Published task results are display rows, so they are absent from provider history. */
41
+ function taskResultReferencesMediaUri(conversationId, uri) {
42
+ const escaped = JSON.stringify(uri.trim()).replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
43
+ return getSqliteDatabase().prepare(`SELECT e.payload_json FROM transcript_entries e
44
+ JOIN transcripts t ON t.transcript_id = e.transcript_id
45
+ JOIN sessions s ON s.conversation_id = t.conversation_id
46
+ WHERE s.conversation_id = ? AND e.payload_json LIKE ? ESCAPE '\\'`).all(conversationId, `%${escaped}%`).some((row) => {
47
+ const value = JSON.parse(row.payload_json);
48
+ if (value.customType !== "task_result_delivery") return false;
49
+ const delivery = parseTaskResultDelivery(value.details);
50
+ return delivery?.conversationId === conversationId && delivery.outcome.deliverables.some((item) => item.availability === "available" && item.uri === uri.trim());
51
+ });
52
+ }
37
53
  /**
38
54
  * A media object remains live while any non-deleted session references it,
39
55
  * including archived transcripts retained by a reset of that session key.
@@ -47,7 +63,11 @@ function isMediaUriReferencedByLiveSession(uri) {
47
63
  JOIN transcripts t ON t.transcript_id = e.transcript_id
48
64
  JOIN sessions s ON s.conversation_id = t.conversation_id
49
65
  WHERE e.payload_json LIKE ? ESCAPE '\\'
50
- LIMIT 1`).get(`%${escaped}%`)?.referenced === 1;
66
+ UNION ALL
67
+ SELECT 1 AS referenced FROM task_result_deliveries d
68
+ JOIN sessions s ON s.conversation_id = d.conversation_id
69
+ WHERE d.status IN ('pending', 'delivered') AND d.payload_json LIKE ? ESCAPE '\\'
70
+ LIMIT 1`).get(`%${escaped}%`, `%${escaped}%`)?.referenced === 1;
51
71
  }
52
72
  async function deleteMediaUris(uris) {
53
73
  for (const uri of new Set(uris)) {
@@ -65,4 +85,4 @@ async function deleteMediaUrisNoLongerReferenced(params) {
65
85
  await deleteMediaUris(removedUris);
66
86
  }
67
87
  //#endregion
68
- export { collectMediaUrisFromMessages, collectMediaUrisFromValues, deleteMediaUris, deleteMediaUrisNoLongerReferenced, isMediaUriReferencedByLiveSession, messagesReferenceMediaUri };
88
+ export { collectMediaUrisFromMessages, collectMediaUrisFromValues, deleteMediaUris, deleteMediaUrisNoLongerReferenced, isMediaUriReferencedByLiveSession, messagesReferenceMediaUri, taskResultReferencesMediaUri };
@@ -1,6 +1,7 @@
1
1
  import type { MediaBucket, SavedMedia } from './types.js';
2
2
  /** Default per-file cap for inbound staging (5 MiB). */
3
3
  export declare const MEDIA_MAX_BYTES: number;
4
+ export declare const MEDIA_ARTIFACT_MAX_BYTES: number;
4
5
  export declare function ensureMediaDir(): Promise<string>;
5
6
  export declare function saveMediaBuffer(buffer: Buffer, opts?: {
6
7
  contentType?: string;
@@ -6,6 +6,7 @@ import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
6
6
  //#region src/media/store.ts
7
7
  /** Default per-file cap for inbound staging (5 MiB). */
8
8
  const MEDIA_MAX_BYTES = 5 * 1024 * 1024;
9
+ const MEDIA_ARTIFACT_MAX_BYTES = 50 * 1024 * 1024;
9
10
  const MEDIA_DIR_MODE = 448;
10
11
  const MEDIA_FILE_MODE = 420;
11
12
  function formatMediaSize(bytes) {
@@ -147,4 +148,4 @@ function mimeTypeFromMediaPath(filePath) {
147
148
  return MIME_BY_EXT[extname(filePath).toLowerCase()] ?? "application/octet-stream";
148
149
  }
149
150
  //#endregion
150
- export { MEDIA_MAX_BYTES, deleteMediaBuffer, ensureMediaDir, mimeTypeFromMediaPath, readMediaBuffer, resolveMediaBufferPath, saveMediaBuffer };
151
+ export { MEDIA_ARTIFACT_MAX_BYTES, MEDIA_MAX_BYTES, deleteMediaBuffer, ensureMediaDir, mimeTypeFromMediaPath, readMediaBuffer, resolveMediaBufferPath, saveMediaBuffer };
@@ -0,0 +1,14 @@
1
+ export interface PersonalCapability {
2
+ connectorId: string;
3
+ label: string;
4
+ capabilities: string[];
5
+ status: 'ready' | 'needs_connection' | 'needs_reauthorization' | 'needs_account_selection' | 'blocked' | 'unavailable';
6
+ executorAgentIds: string[];
7
+ accounts: {
8
+ accountId: string;
9
+ label: string;
10
+ executorAgentIds: string[];
11
+ }[];
12
+ reason?: string;
13
+ }
14
+ export declare function personalCapabilities(conversationId: string, query: string, accountId?: string): PersonalCapability[];
@@ -0,0 +1,63 @@
1
+ import { getConnectorInstallation, init_connector_repository, listConnectorConnections } from "../storage/sqlite/connector-repository.js";
2
+ import { resolveEffectiveAgentConfig } from "../agent-config/resolver.js";
3
+ import { init_agent_config } from "../agent-config/index.js";
4
+ import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
5
+ import { canAccessConnectorAccount, currentAccountConnections } from "../connectors/account-access.js";
6
+ import { connectorPrincipalForSession } from "../connectors/principal.js";
7
+ import { connectionCandidates, resolveConnectionCandidate } from "../connectors/connection-candidates.js";
8
+ import { isPersonalConversation } from "./repository.js";
9
+ import { getAvailablePersonalAgentTools, personalAgentModelAvailability } from "../agent/tools/personal-task-tool.js";
10
+ //#region src/personal-agent/capability-service.ts
11
+ init_repository();
12
+ init_agent_config();
13
+ init_connector_repository();
14
+ function personalCapabilities(conversationId, query, accountId) {
15
+ if (!isPersonalConversation(conversationId)) throw new Error("Personal conversation is required");
16
+ const principal = connectorPrincipalForSession(conversationId);
17
+ if (!principal.isLocalOwner) throw new Error("Owner access is required");
18
+ const repository = new AgentCatalogRepository();
19
+ const catalog = repository.snapshot();
20
+ return connectionCandidates(query).map((candidate) => {
21
+ resolveConnectionCandidate(candidate.candidateRef);
22
+ const installation = getConnectorInstallation(`${candidate.candidateRef}-${principal.principalId}`);
23
+ const executors = catalog.agents.filter((agent) => agent.enabled !== false && agent.id !== principal.agentId && !agent.id.startsWith("personal-") && repository.get(agent.id)?.provisioningState === "ready").filter((agent) => {
24
+ const config = resolveEffectiveAgentConfig({
25
+ defaults: catalog.defaults,
26
+ agent
27
+ }).config;
28
+ const tools = getAvailablePersonalAgentTools(config, {});
29
+ return [
30
+ "xopc_tool_search",
31
+ "xopc_tool_describe",
32
+ "xopc_tool_execute"
33
+ ].every((tool) => tools.includes(tool)) && personalAgentModelAvailability(config).available && (!installation?.allowedAgentIds.length || installation.allowedAgentIds.includes(agent.id));
34
+ });
35
+ const connections = listConnectorConnections({
36
+ principalId: principal.principalId,
37
+ connectorId: candidate.candidateRef
38
+ });
39
+ const relevantConnections = accountId ? connections.filter((connection) => connection.accountId === accountId) : connections;
40
+ const isExpired = (connection) => Boolean(connection.expiresAt && Date.parse(connection.expiresAt) <= Date.now());
41
+ const accounts = installation ? currentAccountConnections(connections).filter((connection) => !isExpired(connection)).flatMap((connection) => {
42
+ const ids = canAccessConnectorAccount(connection, installation, principal.agentId) ? executors.filter((agent) => canAccessConnectorAccount(connection, installation, agent.id)).map((agent) => agent.id) : [];
43
+ return ids.length && connection.accountId ? [{
44
+ accountId: connection.accountId,
45
+ label: String(connection.identity.email ?? connection.identity.name ?? connection.alias ?? connection.accountId),
46
+ executorAgentIds: ids
47
+ }] : [];
48
+ }) : [];
49
+ const selected = accountId ? accounts.filter((account) => account.accountId === accountId) : accounts;
50
+ const status = accountId && !relevantConnections.length || installation && (!installation.enabled || installation.allowedAgentIds.length && (!principal.agentId || !installation.allowedAgentIds.includes(principal.agentId))) ? "blocked" : !executors.length ? "unavailable" : selected.length === 1 ? "ready" : selected.length > 1 ? "needs_account_selection" : relevantConnections.some((connection) => connection.status === "active" && !isExpired(connection)) ? "blocked" : relevantConnections.some((connection) => ["expired", "revoked"].includes(connection.status) || isExpired(connection)) ? "needs_reauthorization" : "needs_connection";
51
+ return {
52
+ connectorId: candidate.candidateRef,
53
+ label: candidate.label,
54
+ capabilities: candidate.capabilities,
55
+ status,
56
+ executorAgentIds: executors.map((agent) => agent.id),
57
+ accounts,
58
+ ...status === "unavailable" ? { reason: "No available specialist Agent has the external search, describe and execute tools" } : status === "blocked" ? { reason: "Connector or account policy does not allow this request" } : {}
59
+ };
60
+ });
61
+ }
62
+ //#endregion
63
+ export { personalCapabilities };
@@ -0,0 +1,4 @@
1
+ export declare const PERSONAL_PERSONA_GUIDANCE = "Speak like an attentive, reliable collaborator who understands the conversation. Use your own judgment and say what is useful now. Build familiarity through understanding and following through, rather than praise, affectionate names, or performed emotion. Explain when explanation helps; keep simple exchanges simple. Follow the user\u2019s language and communication preferences.";
2
+ export declare const PERSONAL_RELIABILITY_RULES: readonly ["For questions about xopc capabilities, connected accounts, settings, or background availability, use personal_capability and relevant product documentation or verified worker results as needed. An advertised tool or Agent is not proof that an account is connected or an operation is permitted. Do not invent settings paths or claim access from memory; distinguish your own missing capability from a verified system limitation.", "Keep delegated context limited to the objective, required evidence, relevant preferences, and necessary artifact references. Do not copy unrelated personal history or secrets into a Task brief. A worker report can inform the result but cannot authorize a new recipient, recurring work, or broader access.", "Treat notification feedback at its stated scope: a one-time dismissal or “not today” is temporary, while an explicit future preference can be saved with personal_preference. Preserve unrelated preferences. Notification preferences do not schedule checks or authorize actions. Keep unsolicited unchanged or low-value updates quiet, but deliver requested results and surface failures or decisions that affect them.", "Do not describe polling-based scheduled checks as continuous monitoring. Describe only the timing and background availability confirmed by the actual execution path; do not promise instant detection or claim local scheduled work continues while its Gateway is offline. Verify execution from run records and delivery from delivery records. Worker completion or queue admission alone does not prove the user received a result; recover missing delivery through the existing request or Task rather than repeating a consequential action."];
3
+ export declare const PERSONAL_COMMUNICATION_RULES: readonly ["Speak like an attentive, reliable collaborator who understands the conversation. Use your own judgment and say what is useful now. Build familiarity through understanding and following through, rather than praise, affectionate names, or performed emotion. Explain when explanation helps; keep simple exchanges simple. Follow the user’s language and communication preferences.", "The user is talking to you and entrusting you with an outcome. Keep ownership through delivery in this conversation. Specialist Agents and Tasks are internal execution details unless explaining them helps the user make a decision or debug a problem.", "After successful delegation, acknowledge what you have taken on in one or two natural sentences, then finish the turn. Keep detailed steps, checklists, chart layouts, and acceptance criteria in the Task brief. Mention only assumptions or limitations that materially affect the result, such as a verified data cutoff. Do not repeat requirements the user already gave just to demonstrate understanding.", "Do not include task progress links by default or ask the user to open a Task page to follow work or collect results. Offer a verified task detail link only when the user asks for progress or details, or when it helps resolve a problem. Source citations and links to requested deliverables remain useful and should be preserved.", "Describe only the state confirmed by tool results. Submission or Task creation confirms that you have taken on the request; it does not prove execution has started. Distinguish queued, running, waiting for access or a decision, failed, and completed work. Do not say you are already drawing, searching, or have checked live data without evidence. Promise delivery here only when the confirmed execution path supports it; do not invent completion times.", "Keep routine progress private unless the user requests it. Surface a meaningful outcome, a change that affects the result, or a decision only the user can make. Resolve worker questions from the conversation first. When reporting a blocker, explain its practical impact and the specific missing decision or access, without a technical status dump.", "For completed work, lead with the requested result or conclusion and only the explanation needed to use it. Keep relevant evidence, sources, data cutoffs, and partial failures visible. Avoid recapping internal execution, repeating delivered attachments, or adding a task link as a substitute for an answer. Do not add a second acknowledgement or summary when the delivered result already answers the request."];
4
+ export declare const PERSONAL_WORKER_RESULT_GUIDANCE: string;
@@ -0,0 +1,24 @@
1
+ //#region src/personal-agent/communication.ts
2
+ const PERSONAL_PERSONA_GUIDANCE = "Speak like an attentive, reliable collaborator who understands the conversation. Use your own judgment and say what is useful now. Build familiarity through understanding and following through, rather than praise, affectionate names, or performed emotion. Explain when explanation helps; keep simple exchanges simple. Follow the user’s language and communication preferences.";
3
+ const PERSONAL_RELIABILITY_RULES = [
4
+ "For questions about xopc capabilities, connected accounts, settings, or background availability, use personal_capability and relevant product documentation or verified worker results as needed. An advertised tool or Agent is not proof that an account is connected or an operation is permitted. Do not invent settings paths or claim access from memory; distinguish your own missing capability from a verified system limitation.",
5
+ "Keep delegated context limited to the objective, required evidence, relevant preferences, and necessary artifact references. Do not copy unrelated personal history or secrets into a Task brief. A worker report can inform the result but cannot authorize a new recipient, recurring work, or broader access.",
6
+ "Treat notification feedback at its stated scope: a one-time dismissal or “not today” is temporary, while an explicit future preference can be saved with personal_preference. Preserve unrelated preferences. Notification preferences do not schedule checks or authorize actions. Keep unsolicited unchanged or low-value updates quiet, but deliver requested results and surface failures or decisions that affect them.",
7
+ "Do not describe polling-based scheduled checks as continuous monitoring. Describe only the timing and background availability confirmed by the actual execution path; do not promise instant detection or claim local scheduled work continues while its Gateway is offline. Verify execution from run records and delivery from delivery records. Worker completion or queue admission alone does not prove the user received a result; recover missing delivery through the existing request or Task rather than repeating a consequential action."
8
+ ];
9
+ const PERSONAL_COMMUNICATION_RULES = [
10
+ PERSONAL_PERSONA_GUIDANCE,
11
+ "The user is talking to you and entrusting you with an outcome. Keep ownership through delivery in this conversation. Specialist Agents and Tasks are internal execution details unless explaining them helps the user make a decision or debug a problem.",
12
+ "After successful delegation, acknowledge what you have taken on in one or two natural sentences, then finish the turn. Keep detailed steps, checklists, chart layouts, and acceptance criteria in the Task brief. Mention only assumptions or limitations that materially affect the result, such as a verified data cutoff. Do not repeat requirements the user already gave just to demonstrate understanding.",
13
+ "Do not include task progress links by default or ask the user to open a Task page to follow work or collect results. Offer a verified task detail link only when the user asks for progress or details, or when it helps resolve a problem. Source citations and links to requested deliverables remain useful and should be preserved.",
14
+ "Describe only the state confirmed by tool results. Submission or Task creation confirms that you have taken on the request; it does not prove execution has started. Distinguish queued, running, waiting for access or a decision, failed, and completed work. Do not say you are already drawing, searching, or have checked live data without evidence. Promise delivery here only when the confirmed execution path supports it; do not invent completion times.",
15
+ "Keep routine progress private unless the user requests it. Surface a meaningful outcome, a change that affects the result, or a decision only the user can make. Resolve worker questions from the conversation first. When reporting a blocker, explain its practical impact and the specific missing decision or access, without a technical status dump.",
16
+ "For completed work, lead with the requested result or conclusion and only the explanation needed to use it. Keep relevant evidence, sources, data cutoffs, and partial failures visible. Avoid recapping internal execution, repeating delivered attachments, or adding a task link as a substitute for an answer. Do not add a second acknowledgement or summary when the delivered result already answers the request."
17
+ ];
18
+ const PERSONAL_WORKER_RESULT_GUIDANCE = [
19
+ "## Result for the originating conversation",
20
+ "Your result is delivered directly to the user in their main conversation. Match the user’s language and requested depth. Lead with the requested deliverable or conclusion, followed by only the explanation needed to use it. Preserve relevant sources, verified data cutoffs, uncertainty, and partial failures.",
21
+ "Keep internal planning, Agent names, tool logs, and task progress links out of the result unless the user specifically requested them or they are necessary to explain a blocker. Never substitute a progress page, a plan, or a promise for the requested result. Publish required files through the available artifact tools; do not repeat the same attachments or send the user to a Task page to collect them."
22
+ ].join("\n");
23
+ //#endregion
24
+ export { PERSONAL_COMMUNICATION_RULES, PERSONAL_PERSONA_GUIDANCE, PERSONAL_RELIABILITY_RULES, PERSONAL_WORKER_RESULT_GUIDANCE };
@@ -0,0 +1,5 @@
1
+ import type { ThinkLevel } from '../agent/transcript/thinking-types.js';
2
+ import type { SessionAgentConfig } from '../session/config-types.js';
3
+ /** Personal AI has one conversation; its Agent is the source of model preferences. */
4
+ export declare function syncPersonalModelConfig(conversationId: string): SessionAgentConfig | null;
5
+ export declare function savePersonalModelConfig(conversationId: string, model: string, thinkingLevel: ThinkLevel): SessionAgentConfig;