@xopcai/xopc 0.0.225 → 0.0.228

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 (239) 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/{activity-store-CtTYnku4.js → activity-store-M0nAY5XB.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-dizuqu_4.js → agent-avatar-dicebear-CjGZBs4C.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-B0NI4_NI.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-CLRMz2BT.js → api-BywYxpaS.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-Cnk-DtQh.js → app-management-settings-panel--SjycrXk.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-wP0rogVI.js → appearance-settings-8G-TVUtg.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-2NiqD-YP.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-Cpzsm-DM.js → archive-plugin-7_DXaMTP.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-Bd2OOoEK.js → attachment-load-Bx44zSpz.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-DNqhguyk.js → automations-page-CrKAHqc0.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-workspace-Q3g9cf0h.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-Dcma5HdI.js → binary-plugins-DjDwnHAQ.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-D-B8ThwK.js → block-editor-7aMOKoZM.js} +3 -3
  16. package/dist/gateway/static/root/assets/browser-settings-page-DTwPkmAC.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BAPZIXrs.js → browser-workflow-inputs-8NC2qDRF.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-DHtaSKEh.js → browser-workflows-page-DVLrWKz_.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-YcP4FbN7.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-zsZQ7im3.js → capability-presets-api-o0y9WgAI.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-AcPjHHia.js +3 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-Cp8iaaXp.js → channel-recipient-api-C5ABr73b.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-Ca94Q1D-.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-38FsOnR0.js +1 -0
  25. package/dist/gateway/static/root/assets/{chat-terminal-dock-Dr6Rq2ln.js → chat-terminal-dock-BR-_7KC0.js} +2 -2
  26. package/dist/gateway/static/root/assets/connectors-page-SGxfLTd6.js +2 -0
  27. package/dist/gateway/static/root/assets/{cron-expression-BiXrpzmo.js → cron-expression-D8-c-Tkw.js} +1 -1
  28. package/dist/gateway/static/root/assets/{date-picker-BPuRtwKt.js → date-picker-kV-Jyl9J.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-BNC_W7wI.js → dependency-picker-CwKcrfGj.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-DzOpt5nI.js → desktop-pet-D9rnchu3.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-BW0brCvH.js → desktop-pet-settings-CTs5WGzk.js} +1 -1
  32. package/dist/gateway/static/root/assets/{directory-picker-path-field-Baml0uTS.js → directory-picker-path-field-CCl0aaDm.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-CBXyKmfS.js → extension-debug-page-Cau40SvC.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-BBhcr_SZ.js → extension-page-BsJXdvIL.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-4rwWpN9_.js → extension-settings-page-qWqJyF7-.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-api-Dg-BlBe4.js → gateway-config-api-BI0SELXm.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-Du0MvK9s.js → gateway-config-swr-BWGjnmDl.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-BOuYZOYe.js → gateway-settings-6ZdOIC7F.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-JbjcHCaN.js → gateway-startup-retry-B_zrtccP.js} +1 -1
  40. package/dist/gateway/static/root/assets/heartbeat-settings-KBwhXeFD.js +1 -0
  41. package/dist/gateway/static/root/assets/home-page-BA2M4CLi.js +1 -0
  42. package/dist/gateway/static/root/assets/{image-generation-api-G2tfPvKP.js → image-generation-api-YKP2me5Z.js} +1 -1
  43. package/dist/gateway/static/root/assets/index-BX0dz1JK.js +70 -0
  44. package/dist/gateway/static/root/assets/index-D_hrEKXM.css +2 -0
  45. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-L1Vtxgp9.js → keyboard-shortcuts-settings-kHtpnyEm.js} +1 -1
  46. package/dist/gateway/static/root/assets/local-app-workbench-page-D2nkn09R.js +2 -0
  47. package/dist/gateway/static/root/assets/{local-apps-page--thlkBLS.js → local-apps-page-BCXa0oUa.js} +1 -1
  48. package/dist/gateway/static/root/assets/{locale-store-DqJz-cOR.js → locale-store-CXhjfe4q.js} +1 -1
  49. package/dist/gateway/static/root/assets/logs-page-D3sNst0K.js +2 -0
  50. package/dist/gateway/static/root/assets/{management-settings-p55fR4XO.js → management-settings-tHnlfOAQ.js} +1 -1
  51. package/dist/gateway/static/root/assets/{markdown-split-DwMcRlBR.js → markdown-split-BMLqHHr5.js} +1 -1
  52. package/dist/gateway/static/root/assets/{markdown-view-DD_PgVue.css → markdown-view-CLzTdVLW.css} +1 -1
  53. package/dist/gateway/static/root/assets/markdown-view-DvM5PWEH.js +201 -0
  54. package/dist/gateway/static/root/assets/{media-plugins-O6H3GZn7.js → media-plugins-DybwqTgv.js} +1 -1
  55. package/dist/gateway/static/root/assets/messages-BMdD0LWk.js +3 -0
  56. package/dist/gateway/static/root/assets/{notes-api-CrjQbmk1.js → notes-api-BFsOGYkd.js} +1 -1
  57. package/dist/gateway/static/root/assets/{notes-page-miO9ig9C.js → notes-page-C24SfF6r.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-CTdZc3ov.js +4 -0
  59. package/dist/gateway/static/root/assets/{product-open-page-BOu07nXf.js → product-open-page-DBfCVlJq.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-COHaEpbA.js +1 -0
  61. package/dist/gateway/static/root/assets/projects-page-lMnST7D_.js +1 -0
  62. package/dist/gateway/static/root/assets/{registry-api-Bf_HDLUJ.js → registry-api-BFZrVYfy.js} +1 -1
  63. package/dist/gateway/static/root/assets/remote-access-hub-BIRKBvO_.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DthuRqUH.js → runtime-tools-settings-panel-BPEGTip5.js} +2 -2
  65. package/dist/gateway/static/root/assets/{schema-form-8W8PhXxa.js → schema-form-Dxlu60Td.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-CATO9G3y.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-Cco_W41x.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-CrsKGYiG.js → settings-form-section-ChXh3Bwk.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-WJtI0AAq.js → settings-loading-skeleton-BCAUqIe2.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-PCjwRF47.js → settings-page-D25W9Okr.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-D65CwlNC.js → setup-status-panel-DsN7Z4Fl.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-BGtvLLeZ.js → share-preview-page-CRFnUaNb.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-CAX0eNaP.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-Doy1gghe.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-C_npyryI.js → skills-page-Cl7jjTK7.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-C46Sd78k.js → skills-page.utils-BiCl4nb5.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-DomTLwki.js → system-settings-panel-BuESR7ZT.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-BRiy8NL3.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-Ce7wq__X.js → theme-store-DOdCjyuw.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-Do9mCRcY.js → use-autosave-Dg1mgJ_l.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-context-page-CqoADNKu.js +1 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-Bc5p-0tX.js → voice-api-key-field-BDNexlVR.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-BieqsmT1.js → work-discovery-overlay-BHTfeaWL.js} +1 -1
  84. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DVj8iYvm.js → workflow-run-setup-panel-Cf_w-NZy.js} +2 -2
  85. package/dist/gateway/static/root/assets/workflows-page-j0P-uECz.js +5 -0
  86. package/dist/gateway/static/root/index.html +12 -12
  87. package/dist/gateway/static/root/notification-sw.js +1 -1
  88. package/dist/package.js +1 -1
  89. package/dist/packages/gateway-contract/src/notifications.js +56 -0
  90. package/dist/packages/gateway-contract/src/turn-outcome.js +114 -0
  91. package/dist/src/agent/agent-manager.d.ts +3 -1
  92. package/dist/src/agent/agent-manager.js +22 -5
  93. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +1 -0
  94. package/dist/src/agent/lifecycle/timeout-wrapper.js +7 -6
  95. package/dist/src/agent/mcp/mcp-transport-config.d.ts +1 -1
  96. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  97. package/dist/src/agent/memory/understanding/service.js +1 -0
  98. package/dist/src/agent/memory/understanding/types.d.ts +1 -0
  99. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +2 -2
  100. package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +4 -4
  101. package/dist/src/agent/service.d.ts +2 -0
  102. package/dist/src/agent/service.js +6 -0
  103. package/dist/src/agent/skills/index.d.ts +22 -2
  104. package/dist/src/agent/skills/index.js +74 -32
  105. package/dist/src/agent/skills/skill-sources.d.ts +0 -1
  106. package/dist/src/agent/skills/skill-sources.js +1 -11
  107. package/dist/src/agent/tools/create-share-tool.js +14 -1
  108. package/dist/src/agent/tools/exec-command.js +3 -3
  109. package/dist/src/agent/tools/execute-code-tool.js +1 -1
  110. package/dist/src/agent/tools/executor.js +2 -2
  111. package/dist/src/agent/tools/image-generate-tool.js +12 -0
  112. package/dist/src/agent/tools/send-media.js +11 -0
  113. package/dist/src/agent/tools/xopc-use-tool.js +1 -1
  114. package/dist/src/cli/command-loaders.js +1 -0
  115. package/dist/src/cli/command-manifest.js +4 -0
  116. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  117. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  118. package/dist/src/cli/commands/history.d.ts +1 -0
  119. package/dist/src/cli/commands/history.js +50 -0
  120. package/dist/src/config/agent-profile.js +1 -1
  121. package/dist/src/connectors/connected-source-understanding.js +1 -1
  122. package/dist/src/gateway/agents-admin.js +1 -1
  123. package/dist/src/gateway/chat-stream/protocol.d.ts +3 -2
  124. package/dist/src/gateway/chat-stream/turn-outcome-collector.d.ts +16 -0
  125. package/dist/src/gateway/chat-stream/turn-outcome-collector.js +111 -0
  126. package/dist/src/gateway/heartbeat/service.js +1 -1
  127. package/dist/src/gateway/hono/lib/static-ui.js +7 -5
  128. package/dist/src/gateway/hono/routes/connectors.js +18 -16
  129. package/dist/src/gateway/hono/routes/index.js +2 -0
  130. package/dist/src/gateway/hono/routes/mobile.js +18 -40
  131. package/dist/src/gateway/hono/routes/notifications.d.ts +3 -0
  132. package/dist/src/gateway/hono/routes/notifications.js +45 -0
  133. package/dist/src/gateway/hono/routes/project-skills.js +30 -2
  134. package/dist/src/gateway/hono/routes/sessions.js +31 -0
  135. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  136. package/dist/src/gateway/hono/routes/voice.js +1 -1
  137. package/dist/src/gateway/hono/routes/you.js +52 -0
  138. package/dist/src/gateway/service/agent-runner.js +6 -2
  139. package/dist/src/gateway/service/run-gateway-agent.js +53 -1
  140. package/dist/src/gateway/service/sessions-api.d.ts +6 -0
  141. package/dist/src/gateway/service/sessions-api.js +60 -3
  142. package/dist/src/gateway/service.d.ts +2 -2
  143. package/dist/src/gateway/service.js +8 -7
  144. package/dist/src/heartbeat/index.js +1 -1
  145. package/dist/src/history/ctx/exporter.d.ts +14 -0
  146. package/dist/src/history/ctx/exporter.js +99 -0
  147. package/dist/src/history/ctx/format.d.ts +25 -0
  148. package/dist/src/history/ctx/format.js +282 -0
  149. package/dist/src/infra/update-restart.js +1 -1
  150. package/dist/src/knowledge/connected-understanding-pipeline.js +12 -3
  151. package/dist/src/knowledge/index.d.ts +0 -1
  152. package/dist/src/knowledge/index.js +1 -2
  153. package/dist/src/media/session-references.d.ts +6 -0
  154. package/dist/src/media/session-references.js +24 -3
  155. package/dist/src/notifications/device-store.d.ts +16 -0
  156. package/dist/src/notifications/device-store.js +96 -0
  157. package/dist/src/notifications/planner.d.ts +6 -0
  158. package/dist/src/notifications/planner.js +156 -0
  159. package/dist/src/notifications/service.d.ts +18 -0
  160. package/dist/src/notifications/service.js +184 -0
  161. package/dist/src/notifications/store.d.ts +53 -0
  162. package/dist/src/notifications/store.js +184 -0
  163. package/dist/src/notifications/types.d.ts +29 -0
  164. package/dist/src/notifications/types.js +14 -0
  165. package/dist/src/projects/project-skill-service.d.ts +28 -6
  166. package/dist/src/projects/project-skill-service.js +76 -29
  167. package/dist/src/session/client-history.d.ts +3 -1
  168. package/dist/src/session/client-history.js +13 -0
  169. package/dist/src/session/index.d.ts +1 -1
  170. package/dist/src/session/manager.d.ts +1 -0
  171. package/dist/src/session/manager.js +6 -0
  172. package/dist/src/session/store.d.ts +15 -0
  173. package/dist/src/session/store.js +58 -0
  174. package/dist/src/storage/sqlite/index.d.ts +2 -1
  175. package/dist/src/storage/sqlite/index.js +3 -2
  176. package/dist/src/storage/sqlite/migrations/135_user_people.sql +59 -0
  177. package/dist/src/storage/sqlite/migrations/136_product_notifications.sql +79 -0
  178. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  179. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  180. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  181. package/dist/src/storage/sqlite/schema.js +1 -1
  182. package/dist/src/storage/sqlite/session-input-repository.d.ts +5 -0
  183. package/dist/src/storage/sqlite/session-input-repository.js +9 -1
  184. package/dist/src/storage/sqlite/user-people-repository.d.ts +32 -0
  185. package/dist/src/storage/sqlite/user-people-repository.js +246 -0
  186. package/dist/src/tasks/index.js +2 -2
  187. package/dist/src/tasks/task-application-service.js +42 -6
  188. package/dist/src/tasks/task-change-events.d.ts +9 -0
  189. package/dist/src/tasks/task-change-events.js +17 -1
  190. package/dist/src/tasks/task-outbox-dispatcher.js +5 -1
  191. package/dist/src/tasks/task-run-dispatcher.js +4 -2
  192. package/dist/src/tasks/task-run-repository.js +13 -0
  193. package/dist/src/user-context/relationships/indexer.d.ts +13 -0
  194. package/dist/src/user-context/relationships/indexer.js +185 -0
  195. package/dist/src/user-context/relationships/service.d.ts +22 -0
  196. package/dist/src/user-context/relationships/service.js +50 -0
  197. package/dist/src/user-context/relationships/types.d.ts +55 -0
  198. package/dist/src/user-context/relationships/types.js +10 -0
  199. package/dist/src/user-context/sources/repository.d.ts +1 -1
  200. package/dist/src/user-context/sources/repository.js +8 -2
  201. package/dist/src/work-discovery/service.js +1 -1
  202. package/package.json +2 -2
  203. package/dist/gateway/static/root/assets/agents-DeEEFZJ4.js +0 -68
  204. package/dist/gateway/static/root/assets/apps-page-Db5YNHVM.js +0 -1
  205. package/dist/gateway/static/root/assets/automations-workspace-CNT05YTb.js +0 -6
  206. package/dist/gateway/static/root/assets/browser-settings-page-UbDj3LIq.js +0 -8
  207. package/dist/gateway/static/root/assets/capabilities-settings-panel-CiO152QS.js +0 -7
  208. package/dist/gateway/static/root/assets/capability-presets-settings-panel-Bc_hRwfL.js +0 -3
  209. package/dist/gateway/static/root/assets/channels-settings-CFW7zBoT.js +0 -1
  210. package/dist/gateway/static/root/assets/channels-status-swr-5rNVq7iI.js +0 -1
  211. package/dist/gateway/static/root/assets/connectors-page-DLBr5nre.js +0 -2
  212. package/dist/gateway/static/root/assets/heartbeat-settings-Dq4YAlSx.js +0 -1
  213. package/dist/gateway/static/root/assets/home-page-BIXkO0Ck.js +0 -1
  214. package/dist/gateway/static/root/assets/index-Csccu8sa.js +0 -74
  215. package/dist/gateway/static/root/assets/index-D3_xSYKd.css +0 -2
  216. package/dist/gateway/static/root/assets/local-app-workbench-page-D-eacBcO.js +0 -2
  217. package/dist/gateway/static/root/assets/logs-page-BRCglHvd.js +0 -2
  218. package/dist/gateway/static/root/assets/markdown-view-CTB9u15e.js +0 -69
  219. package/dist/gateway/static/root/assets/mermaid-render-BbqDc_LQ.js +0 -134
  220. package/dist/gateway/static/root/assets/messages-CeydamsI.js +0 -3
  221. package/dist/gateway/static/root/assets/notes-workbench-_13lmvmF.js +0 -4
  222. package/dist/gateway/static/root/assets/project-detail-page-BStRkOQr.js +0 -1
  223. package/dist/gateway/static/root/assets/projects-page-CY03RxVr.js +0 -1
  224. package/dist/gateway/static/root/assets/remote-access-hub-B19llkld.js +0 -1
  225. package/dist/gateway/static/root/assets/sessions-page-BDA2qbTd.js +0 -1
  226. package/dist/gateway/static/root/assets/settings-advanced-gate-BONIDX4v.js +0 -1
  227. package/dist/gateway/static/root/assets/shares-settings-CdzVKrBl.js +0 -1
  228. package/dist/gateway/static/root/assets/skill-reload-api-CsRWid5h.js +0 -1
  229. package/dist/gateway/static/root/assets/task-detail-page-B6YFX7kK.js +0 -1
  230. package/dist/gateway/static/root/assets/user-context-page-CiCQA40E.js +0 -1
  231. package/dist/gateway/static/root/assets/workflows-page-AG04TTuH.js +0 -5
  232. package/dist/src/knowledge/people-graph.d.ts +0 -25
  233. package/dist/src/knowledge/people-graph.js +0 -92
  234. package/dist/src/mobile/notification-service.d.ts +0 -9
  235. package/dist/src/mobile/notification-service.js +0 -156
  236. package/dist/src/mobile/notification-store.d.ts +0 -28
  237. package/dist/src/mobile/notification-store.js +0 -132
  238. package/dist/src/mobile/notification-types.d.ts +0 -37
  239. package/dist/src/mobile/notification-types.js +0 -9
@@ -0,0 +1,185 @@
1
+ import { getSqliteDatabase } from "../../storage/sqlite/transaction.js";
2
+ import { getUserPeopleIndexState, replaceUserPeopleIndex } from "../../storage/sqlite/user-people-repository.js";
3
+ import { listKnowledgeSourceItems } from "../../storage/sqlite/knowledge-repository.js";
4
+ import "../../storage/sqlite/index.js";
5
+ import { listUnderstandingSourceGrants } from "../sources/repository.js";
6
+ import { createHash } from "node:crypto";
7
+ //#region src/user-context/relationships/indexer.ts
8
+ function hash(value) {
9
+ return createHash("sha256").update(value).digest("hex").slice(0, 20);
10
+ }
11
+ function normalized(value) {
12
+ return value?.trim().toLocaleLowerCase() || void 0;
13
+ }
14
+ function readSignal(value) {
15
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
16
+ const row = value;
17
+ const read = (key) => typeof row[key] === "string" && row[key].trim() ? row[key].trim().slice(0, 160) : void 0;
18
+ const signal = {
19
+ name: read("name"),
20
+ email: read("email"),
21
+ username: read("username")
22
+ };
23
+ return signal.name || signal.email || signal.username ? signal : void 0;
24
+ }
25
+ function providerScope(sourceInstanceId) {
26
+ if (!sourceInstanceId.startsWith("composio:")) return sourceInstanceId.toLocaleLowerCase();
27
+ return sourceInstanceId.split(":")[1]?.toLocaleLowerCase() ?? sourceInstanceId.toLocaleLowerCase();
28
+ }
29
+ function personIdentityKey(signal, sourceInstanceId) {
30
+ const email = normalized(signal.email);
31
+ if (email) return `email:${email}`;
32
+ const username = normalized(signal.username);
33
+ if (username) return `provider:${providerScope(sourceInstanceId)}:${username}`;
34
+ const name = normalized(signal.name);
35
+ return name ? `name:${sourceInstanceId.toLocaleLowerCase()}:${name}` : void 0;
36
+ }
37
+ function personIdForIdentity(signal, sourceInstanceId) {
38
+ const key = personIdentityKey(signal, sourceInstanceId);
39
+ return key ? `person_${hash(key)}` : void 0;
40
+ }
41
+ function inferredKind(signal) {
42
+ const name = normalized(signal.name) ?? "";
43
+ const username = normalized(signal.username) ?? "";
44
+ const emailLocal = (normalized(signal.email) ?? "").split("@")[0] ?? "";
45
+ if (/\[bot\]|(?:^|[-_.])bot(?:$|[-_.])|bot$/.test(`${name} ${username}`)) return "bot";
46
+ if (/^(?:no[-_.]?reply|do[-_.]?not[-_.]?reply|notifications?|alerts?|mailer[-_.]?daemon)(?:$|[-+_.])/.test(emailLocal)) return "service";
47
+ if (/^(?:team|group|all|everyone|support|help|sales|contact)(?:$|[-+_.])/.test(emailLocal)) return "group";
48
+ if (!signal.name && !signal.email && signal.username) return "unknown";
49
+ return "person";
50
+ }
51
+ function confidence(signal) {
52
+ if (signal.email) return signal.name ? .95 : .88;
53
+ if (signal.username) return signal.name ? .86 : .72;
54
+ return .55;
55
+ }
56
+ function observedAt(item) {
57
+ const value = Date.parse(item.occurredAt ?? item.sourceUpdatedAt ?? item.updatedAt);
58
+ return Number.isFinite(value) ? value : Date.now();
59
+ }
60
+ function handle(personId, type, value, sourceInstanceId, time) {
61
+ return {
62
+ id: `handle_${hash(`${type}:${normalized(value)}:${sourceInstanceId}`)}`,
63
+ type,
64
+ value,
65
+ sourceInstanceId,
66
+ verification: type === "display_name" ? "inferred" : "observed",
67
+ firstObservedAt: time,
68
+ lastObservedAt: time
69
+ };
70
+ }
71
+ function activeConnectorSources() {
72
+ return new Set(listUnderstandingSourceGrants().flatMap((grant) => {
73
+ const sourceInstanceId = typeof grant.config.sourceInstanceId === "string" ? grant.config.sourceInstanceId.trim() : "";
74
+ if (sourceInstanceId) return [sourceInstanceId];
75
+ const connectorId = typeof grant.config.connectorId === "string" ? grant.config.connectorId.trim() : "";
76
+ const accountId = typeof grant.config.accountId === "string" ? grant.config.accountId.trim() : "";
77
+ return connectorId && accountId ? [`composio:${connectorId}:${accountId}`] : [];
78
+ }));
79
+ }
80
+ function loadActiveSourceItems() {
81
+ const activeSources = activeConnectorSources();
82
+ const items = [];
83
+ let offset = 0;
84
+ while (true) {
85
+ const page = listKnowledgeSourceItems({
86
+ includeDeleted: false,
87
+ limit: 500,
88
+ offset
89
+ });
90
+ items.push(...page.filter((item) => item.synthesisPipeline === "connected_knowledge" && item.sensitivity !== "secret" && item.sensitivity !== "regulated" && item.metadata.observationKind !== "inventory" && (!item.sourceInstanceId.startsWith("composio:") || activeSources.has(item.sourceInstanceId))));
91
+ if (page.length < 500) break;
92
+ offset += page.length;
93
+ }
94
+ return items;
95
+ }
96
+ function currentIndexRevision() {
97
+ const db = getSqliteDatabase();
98
+ return {
99
+ sourceChangeSequence: Number(db.prepare("SELECT COALESCE(MAX(sequence), 0) AS value FROM knowledge_source_changes").get().value),
100
+ sourceGrantsUpdatedAt: Number(db.prepare("SELECT COALESCE(MAX(updated_at), 0) AS value FROM understanding_source_grants").get().value)
101
+ };
102
+ }
103
+ function buildUserPeopleIndex(items) {
104
+ const owners = new Set(items.flatMap((item) => Array.isArray(item.metadata.ownerIdentities) ? item.metadata.ownerIdentities.filter((value) => typeof value === "string").map((value) => value.trim().toLocaleLowerCase()).filter(Boolean) : []));
105
+ const people = /* @__PURE__ */ new Map();
106
+ for (const item of items) {
107
+ const values = Array.isArray(item.metadata.personEntities) ? item.metadata.personEntities : [];
108
+ const seenInItem = /* @__PURE__ */ new Set();
109
+ for (const value of values) {
110
+ const signal = readSignal(value);
111
+ if (!signal) continue;
112
+ const strongIdentity = normalized(signal.email) ?? normalized(signal.username);
113
+ if (strongIdentity && owners.has(strongIdentity)) continue;
114
+ const identityKey = personIdentityKey(signal, item.sourceInstanceId);
115
+ const id = personIdForIdentity(signal, item.sourceInstanceId);
116
+ if (!identityKey || !id || seenInItem.has(identityKey)) continue;
117
+ seenInItem.add(identityKey);
118
+ const time = observedAt(item);
119
+ const name = signal.name ?? signal.email ?? signal.username;
120
+ const current = people.get(identityKey) ?? {
121
+ id,
122
+ displayName: name,
123
+ inferredKind: inferredKind(signal),
124
+ confidence: confidence(signal),
125
+ firstObservedAt: time,
126
+ lastObservedAt: time,
127
+ handles: /* @__PURE__ */ new Map(),
128
+ sources: /* @__PURE__ */ new Map()
129
+ };
130
+ if (signal.name && (!current.displayName || current.displayName.includes("@"))) current.displayName = signal.name;
131
+ current.inferredKind = current.inferredKind === "unknown" ? inferredKind(signal) : current.inferredKind;
132
+ current.confidence = Math.max(current.confidence, confidence(signal));
133
+ current.firstObservedAt = Math.min(current.firstObservedAt, time);
134
+ current.lastObservedAt = Math.max(current.lastObservedAt, time);
135
+ for (const [type, displayValue] of [
136
+ ["email", signal.email],
137
+ ["username", signal.username],
138
+ ["display_name", signal.name]
139
+ ]) {
140
+ if (!displayValue) continue;
141
+ const next = handle(id, type, displayValue, item.sourceInstanceId, time);
142
+ const key = `${type}:${normalized(displayValue)}:${item.sourceInstanceId}`;
143
+ const previous = current.handles.get(key);
144
+ if (previous) {
145
+ previous.firstObservedAt = Math.min(previous.firstObservedAt, time);
146
+ previous.lastObservedAt = Math.max(previous.lastObservedAt, time);
147
+ } else current.handles.set(key, next);
148
+ }
149
+ const source = current.sources.get(item.sourceInstanceId) ?? {
150
+ sourceInstanceId: item.sourceInstanceId,
151
+ interactionCount: 0,
152
+ firstObservedAt: time,
153
+ lastObservedAt: time
154
+ };
155
+ source.interactionCount += 1;
156
+ source.firstObservedAt = Math.min(source.firstObservedAt, time);
157
+ source.lastObservedAt = Math.max(source.lastObservedAt, time);
158
+ current.sources.set(item.sourceInstanceId, source);
159
+ people.set(identityKey, current);
160
+ }
161
+ }
162
+ return [...people.values()].map((person) => ({
163
+ id: person.id,
164
+ displayName: person.displayName,
165
+ inferredKind: person.inferredKind,
166
+ confidence: person.confidence,
167
+ firstObservedAt: person.firstObservedAt,
168
+ lastObservedAt: person.lastObservedAt,
169
+ handles: [...person.handles.values()],
170
+ sources: [...person.sources.values()]
171
+ }));
172
+ }
173
+ function rebuildUserPeopleIndex() {
174
+ const revision = currentIndexRevision();
175
+ const entries = buildUserPeopleIndex(loadActiveSourceItems());
176
+ replaceUserPeopleIndex(entries, revision);
177
+ return entries;
178
+ }
179
+ function ensureUserPeopleIndex() {
180
+ const revision = currentIndexRevision();
181
+ const state = getUserPeopleIndexState();
182
+ if (!state || state.sourceChangeSequence !== revision.sourceChangeSequence || state.sourceGrantsUpdatedAt !== revision.sourceGrantsUpdatedAt) rebuildUserPeopleIndex();
183
+ }
184
+ //#endregion
185
+ export { buildUserPeopleIndex, ensureUserPeopleIndex, personIdForIdentity, personIdentityKey, rebuildUserPeopleIndex };
@@ -0,0 +1,22 @@
1
+ import type { UserPerson, UserPersonKind } from './types.js';
2
+ export declare function listUserRelationships(options?: {
3
+ query?: string;
4
+ kind?: UserPersonKind;
5
+ sourceInstanceId?: string;
6
+ includeHidden?: boolean;
7
+ hiddenOnly?: boolean;
8
+ cursor?: string;
9
+ limit?: number;
10
+ }): {
11
+ nextCursor?: string;
12
+ items: UserPerson[];
13
+ summary: import("./types.js").UserRelationshipSummary;
14
+ total: number;
15
+ };
16
+ export declare function getUserRelationship(personId: string): UserPerson | null;
17
+ export declare function patchUserRelationship(personId: string, patch: {
18
+ displayName?: string | null;
19
+ kind?: UserPersonKind | null;
20
+ hidden?: boolean;
21
+ }): UserPerson | null;
22
+ export declare function mergeUserRelationships(sourcePersonId: string, targetPersonId: string): UserPerson | null;
@@ -0,0 +1,50 @@
1
+ import { listUnderstandings } from "../../storage/sqlite/user-context-repository.js";
2
+ import { getUserPerson, listUserPeople, mergeUserPeople, summarizeUserPeople, updateUserPerson } from "../../storage/sqlite/user-people-repository.js";
3
+ import "../../storage/sqlite/index.js";
4
+ import { ensureUserPeopleIndex } from "./indexer.js";
5
+ //#region src/user-context/relationships/service.ts
6
+ function withUnderstanding(person) {
7
+ const understanding = listUnderstandings().find((item) => item.kind === "relationship" && item.payload.personId === person.id && !["archived", "rejected"].includes(item.status));
8
+ return understanding ? {
9
+ ...person,
10
+ relationshipUnderstanding: {
11
+ id: understanding.id,
12
+ statement: understanding.statement,
13
+ status: understanding.status
14
+ }
15
+ } : person;
16
+ }
17
+ function listUserRelationships(options = {}) {
18
+ ensureUserPeopleIndex();
19
+ const offset = options.cursor && /^\d+$/.test(options.cursor) ? Number(options.cursor) : 0;
20
+ const result = listUserPeople({
21
+ query: options.query,
22
+ kind: options.kind,
23
+ sourceInstanceId: options.sourceInstanceId,
24
+ includeHidden: options.includeHidden,
25
+ hiddenOnly: options.hiddenOnly,
26
+ offset,
27
+ limit: options.limit
28
+ });
29
+ return {
30
+ items: result.items.map(withUnderstanding),
31
+ summary: summarizeUserPeople(),
32
+ total: result.total,
33
+ ...result.nextOffset === void 0 ? {} : { nextCursor: String(result.nextOffset) }
34
+ };
35
+ }
36
+ function getUserRelationship(personId) {
37
+ ensureUserPeopleIndex();
38
+ const person = getUserPerson(personId);
39
+ return person ? withUnderstanding(person) : null;
40
+ }
41
+ function patchUserRelationship(personId, patch) {
42
+ const person = updateUserPerson(personId, patch);
43
+ return person ? withUnderstanding(person) : null;
44
+ }
45
+ function mergeUserRelationships(sourcePersonId, targetPersonId) {
46
+ const person = mergeUserPeople(sourcePersonId, targetPersonId);
47
+ return person ? withUnderstanding(person) : null;
48
+ }
49
+ //#endregion
50
+ export { getUserRelationship, listUserRelationships, mergeUserRelationships, patchUserRelationship };
@@ -0,0 +1,55 @@
1
+ export declare const USER_PERSON_KINDS: readonly ["person", "bot", "service", "group", "unknown"];
2
+ export type UserPersonKind = typeof USER_PERSON_KINDS[number];
3
+ export type UserPersonHandle = {
4
+ id: string;
5
+ type: 'email' | 'provider_user' | 'username' | 'display_name';
6
+ value: string;
7
+ sourceInstanceId: string;
8
+ verification: 'observed' | 'inferred' | 'user_confirmed';
9
+ firstObservedAt: number;
10
+ lastObservedAt: number;
11
+ };
12
+ export type UserPersonSource = {
13
+ sourceInstanceId: string;
14
+ connectorId?: string;
15
+ toolkit?: string;
16
+ interactionCount: number;
17
+ firstObservedAt: number;
18
+ lastObservedAt: number;
19
+ };
20
+ export type UserPerson = {
21
+ id: string;
22
+ displayName: string;
23
+ kind: UserPersonKind;
24
+ hidden: boolean;
25
+ confidence: number;
26
+ primaryHandle?: string;
27
+ interactionCount: number;
28
+ firstObservedAt: number;
29
+ lastObservedAt: number;
30
+ handles: UserPersonHandle[];
31
+ sources: UserPersonSource[];
32
+ relationshipUnderstanding?: {
33
+ id: string;
34
+ statement: string;
35
+ status: 'candidate' | 'active' | 'needs_review' | 'stale' | 'archived' | 'rejected';
36
+ };
37
+ };
38
+ export type UserRelationshipSummary = {
39
+ people: number;
40
+ automatedAccounts: number;
41
+ needsReview: number;
42
+ hidden: number;
43
+ sources: number;
44
+ lastUpdatedAt?: number;
45
+ };
46
+ export type UserPersonIndexEntry = {
47
+ id: string;
48
+ displayName: string;
49
+ inferredKind: UserPersonKind;
50
+ confidence: number;
51
+ firstObservedAt: number;
52
+ lastObservedAt: number;
53
+ handles: UserPersonHandle[];
54
+ sources: UserPersonSource[];
55
+ };
@@ -0,0 +1,10 @@
1
+ //#region src/user-context/relationships/types.ts
2
+ const USER_PERSON_KINDS = [
3
+ "person",
4
+ "bot",
5
+ "service",
6
+ "group",
7
+ "unknown"
8
+ ];
9
+ //#endregion
10
+ export { USER_PERSON_KINDS };
@@ -55,6 +55,6 @@ export declare function updateUnderstandingSourceRun(id: string, patch: {
55
55
  }): UnderstandingSourceRun | null;
56
56
  export declare function upsertUserFocus(input: UserFocusInput): UserFocus;
57
57
  export declare function listUserFocuses(statuses?: UserFocus['status'][]): UserFocus[];
58
- export declare function updateUserFocus(id: string, patch: Partial<Pick<UserFocus, 'title' | 'summary' | 'status'>>, nowMs?: number): UserFocus | null;
58
+ export declare function updateUserFocus(id: string, patch: Partial<Pick<UserFocus, 'title' | 'summary' | 'status' | 'validFrom' | 'validTo' | 'reviewAt'>>, nowMs?: number): UserFocus | null;
59
59
  export declare function deleteUserFocus(id: string): boolean;
60
60
  export {};
@@ -1,5 +1,6 @@
1
1
  import { getSqliteDatabase, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
2
2
  import "../domain.js";
3
+ import { focusLifecycle } from "../focus-lifecycle.js";
3
4
  import { randomUUID } from "node:crypto";
4
5
  //#region src/user-context/sources/repository.ts
5
6
  function record(value) {
@@ -261,11 +262,16 @@ function updateUserFocus(id, patch, nowMs = Date.now()) {
261
262
  const currentRow = getSqliteDatabase().prepare("SELECT * FROM user_focuses WHERE focus_id = ?").get(id);
262
263
  if (!currentRow) return null;
263
264
  const current = focusFromRow(currentRow);
264
- if ((patch.title ?? current.title) === current.title && (patch.summary ?? current.summary) === current.summary && (patch.status ?? current.status) === current.status) return current;
265
+ const renewedLifecycle = patch.status === "active" && (current.status !== "active" || current.reviewAt !== void 0 && current.reviewAt <= nowMs || current.validTo !== void 0 && current.validTo <= nowMs) ? focusLifecycle(current.horizon, nowMs) : {};
266
+ const nextValidFrom = patch.validFrom ?? renewedLifecycle.validFrom ?? current.validFrom;
267
+ const nextValidTo = patch.validTo ?? renewedLifecycle.validTo ?? current.validTo;
268
+ const nextReviewAt = patch.reviewAt ?? renewedLifecycle.reviewAt ?? current.reviewAt;
269
+ if ((patch.title ?? current.title) === current.title && (patch.summary ?? current.summary) === current.summary && (patch.status ?? current.status) === current.status && nextValidFrom === current.validFrom && nextValidTo === current.validTo && nextReviewAt === current.reviewAt) return current;
265
270
  const versionId = randomUUID();
266
271
  runSqliteWriteTransaction((db) => {
267
272
  db.prepare(`UPDATE user_focuses
268
- SET title = ?, summary = ?, status = ?, updated_at = ? WHERE focus_id = ?`).run(patch.title ?? current.title, patch.summary ?? current.summary, patch.status ?? current.status, nowMs, id);
273
+ SET title = ?, summary = ?, status = ?, valid_from = ?, valid_to = ?, review_at = ?, updated_at = ?
274
+ WHERE focus_id = ?`).run(patch.title ?? current.title, patch.summary ?? current.summary, patch.status ?? current.status, nextValidFrom ?? null, nextValidTo ?? null, nextReviewAt ?? null, nowMs, id);
269
275
  const nextRow = db.prepare("SELECT * FROM user_focuses WHERE focus_id = ?").get(id);
270
276
  db.prepare(`INSERT INTO user_focus_versions (
271
277
  version_id, focus_id, title, summary, snapshot_json, created_by, change_reason, created_at
@@ -8,8 +8,8 @@ import { buildSessionKey, init_session_key } from "../routing/session-key.js";
8
8
  import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
9
9
  import { init_providers, resolveModel } from "../providers/index.js";
10
10
  import { isLocalModelBaseUrl } from "../providers/model-call.js";
11
- import { createUnderstandingSourceRun, getUnderstandingSourceRun, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceGrantPolicies, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant, upsertUserFocus } from "../user-context/sources/repository.js";
12
11
  import { focusLifecycle } from "../user-context/focus-lifecycle.js";
12
+ import { createUnderstandingSourceRun, getUnderstandingSourceRun, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceGrantPolicies, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant, upsertUserFocus } from "../user-context/sources/repository.js";
13
13
  import { allowsRemoteSourceProcessing } from "../user-context/sources/processing-policy.js";
14
14
  import { analyzeUnderstandingSources, analyzeWorkContext, workDiscoveryResultMarkdown } from "./analyzer.js";
15
15
  import { previewWorkDiscoveryRoot, probeWorkDiscoveryRoot, summarizeWorkContextSnapshot } from "./probe.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xopcai/xopc",
3
- "version": "0.0.225",
3
+ "version": "0.0.228",
4
4
  "description": "Local-first personal AI assistant with reviewable user understanding, durable tasks, workflows, automations, and local or cloud models.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -158,8 +158,8 @@
158
158
  "vitest": "4.1.5",
159
159
  "vue": "^3.5.35",
160
160
  "@xopcai/endpoint-tools-protocol": "0.0.0",
161
- "@xopcai/gateway-contract": "0.0.0",
162
161
  "@xopcai/realtime-protocol": "0.0.0",
162
+ "@xopcai/gateway-contract": "0.0.0",
163
163
  "@xopcai/realtime-client": "0.0.0"
164
164
  },
165
165
  "scripts": {