@xopcai/xopc 0.0.171 → 0.0.173

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 (228) 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-BLz30jWq.js → activity-store-ByVA0N5n.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BKZO0EFn.js → agent-avatar-dicebear-CJ5HvqE7.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents--TQ9jM_1.js +2 -0
  6. package/dist/gateway/static/root/assets/{api-N2qKY-WI.js → api-BZtCKzg4.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-CNZkpXCD.js → app-management-settings-panel-B0oNNcFn.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-Drf5a563.js → appearance-settings-DbIj4NQ1.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-BDsoZDEn.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-ChVwOXE5.js → archive-plugin-BICLQFWJ.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-BVK3Y2d9.js → attachment-load-DV3PteSU.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automation-suggestion-card-DH4N0SYR.js → automation-suggestion-card-CZUImis0.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-page-CHrNcppN.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-CeHY6VVP.js → binary-plugins-D6zkab6N.js} +1 -1
  15. package/dist/gateway/static/root/assets/block-editor-zCzoQI-g.js +184 -0
  16. package/dist/gateway/static/root/assets/browser-settings-page-BQoRuQzH.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-femCtfpo.js → browser-workflow-inputs-CY3X83xQ.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-o0GVE_aF.js → browser-workflows-page-DDRtZLuM.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-BOcU0qeM.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-Bx-JJC0R.js → capability-presets-api-pYLW6P7g.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CJ1F_hlX.js +1 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-CTw3ibx4.js → channel-recipient-api-DxyOH3BO.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-C4vDwRil.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-B0Pgq5x2.js +1 -0
  25. package/dist/gateway/static/root/assets/connector-logo-BgANwjt-.js +1 -0
  26. package/dist/gateway/static/root/assets/connectors-page-D6JEqDEj.js +2 -0
  27. package/dist/gateway/static/root/assets/desktop-pet-BPjQbPeA.js +1 -0
  28. package/dist/gateway/static/root/assets/{desktop-pet-settings-CIeH4VyP.js → desktop-pet-settings-8CaU1Mhm.js} +1 -1
  29. package/dist/gateway/static/root/assets/{directory-picker-path-field-Ddgt6c3K.js → directory-picker-path-field-BtNRUvzM.js} +1 -1
  30. package/dist/gateway/static/root/assets/dreaming-settings-Byv-h8XZ.js +3 -0
  31. package/dist/gateway/static/root/assets/{extension-debug-page-CJGwUaQX.js → extension-debug-page-DFjTfx6f.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-B3zHKJAB.js → extension-page-NyEYtWWg.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-Cj9rrSr1.js → extension-settings-page-BynTCfgf.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-api-BdmtlJRP.js → gateway-config-api-BzOWImvU.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-C2RwKIsl.js → gateway-settings-DXepE_Jw.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-startup-retry-mcMq_uu_.js → gateway-startup-retry-C2JXXtwg.js} +1 -1
  37. package/dist/gateway/static/root/assets/{goal-create-dialog-5Ryd_rx4.js → goal-create-dialog-ClOZyG52.js} +1 -1
  38. package/dist/gateway/static/root/assets/goal-detail-page-UbZB77De.js +4 -0
  39. package/dist/gateway/static/root/assets/{goals-config-api-CAO1J4jn.js → goals-config-api-CU3JR9MI.js} +1 -1
  40. package/dist/gateway/static/root/assets/goals-page-GMqV8Fwv.js +2 -0
  41. package/dist/gateway/static/root/assets/{goals-settings-Boj2izKZ.js → goals-settings-DSZguLEx.js} +1 -1
  42. package/dist/gateway/static/root/assets/{heartbeat-settings-DbPC9a_y.js → heartbeat-settings-KRkYziEF.js} +1 -1
  43. package/dist/gateway/static/root/assets/{image-generation-api-DrLCLTXn.js → image-generation-api-Y-n6TaZ_.js} +1 -1
  44. package/dist/gateway/static/root/assets/index-BCkNJ5cR.css +1 -0
  45. package/dist/gateway/static/root/assets/{index-vHb2z7VS.js → index-CAZ9343h.js} +67 -67
  46. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BrxfptgY.js → keyboard-shortcuts-settings-CwrQv952.js} +1 -1
  47. package/dist/gateway/static/root/assets/{local-app-workbench-page-BP0_Ih0e.js → local-app-workbench-page-m5HEyrHT.js} +2 -2
  48. package/dist/gateway/static/root/assets/{local-apps-page-DNCRlfFs.js → local-apps-page-DtITcS4K.js} +1 -1
  49. package/dist/gateway/static/root/assets/{locale-store-CzIfXqm8.js → locale-store-Ccv7tH8B.js} +1 -1
  50. package/dist/gateway/static/root/assets/logs-page-Bf_nk75f.js +7 -0
  51. package/dist/gateway/static/root/assets/{markdown-split-CIUH9Lor.js → markdown-split-D1oZlq1m.js} +1 -1
  52. package/dist/gateway/static/root/assets/{media-plugins-DX4AgkCs.js → media-plugins-BKz5V32t.js} +1 -1
  53. package/dist/gateway/static/root/assets/{messages-CKZuaOeG.js → messages-DWrg3c4K.js} +2 -2
  54. package/dist/gateway/static/root/assets/{notes-page-D1KprtxL.js → notes-page-DLekBQPa.js} +1 -1
  55. package/dist/gateway/static/root/assets/notes-workbench-BTDmprHM.js +4 -0
  56. package/dist/gateway/static/root/assets/{page-tabs-DjZPJGf6.js → page-tabs-pT4nLfqS.js} +1 -1
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-DNiJTpwZ.js → preview-open-alternatives-OtAiaJm2.js} +1 -1
  58. package/dist/gateway/static/root/assets/{product-open-page-CNfR17-g.js → product-open-page-CfryBKD9.js} +1 -1
  59. package/dist/gateway/static/root/assets/project-detail-page-C7kntu4H.js +1 -0
  60. package/dist/gateway/static/root/assets/projects-page-3ubcbqHr.js +1 -0
  61. package/dist/gateway/static/root/assets/remote-access-hub-DoUkN3ik.js +1 -0
  62. package/dist/gateway/static/root/assets/{save-bar-controls-BGZFVO9S.js → save-bar-controls-nP1SB3Lf.js} +1 -1
  63. package/dist/gateway/static/root/assets/{schedule-field-BAZiHtds.js → schedule-field-OEQTsUNz.js} +1 -1
  64. package/dist/gateway/static/root/assets/{schema-form-CesBcwJH.js → schema-form-DIcAa7CJ.js} +1 -1
  65. package/dist/gateway/static/root/assets/sessions-page-ElAAlZ-R.js +1 -0
  66. package/dist/gateway/static/root/assets/settings-advanced-gate-CQn_KBqr.js +1 -0
  67. package/dist/gateway/static/root/assets/{settings-form-section-Bxc54BLj.js → settings-form-section-BxNcTbYO.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-loading-skeleton-CYrho7Db.js → settings-loading-skeleton-Dpdxu4sf.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-page-C03X5fkh.js → settings-page-DwPeOm1c.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-layout-CZAJbv4E.js → settings-page-layout-CqirFmMn.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-Jv8_bcOD.js → setup-status-panel-DX_LdcTN.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-DSC7tKKG.js → share-preview-page-D72gYeux.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-nSfe-5xK.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-1tYpZrJf.js +1 -0
  75. package/dist/gateway/static/root/assets/skills-page-BUJl8LJG.js +2 -0
  76. package/dist/gateway/static/root/assets/{system-settings-panel-BO89zw5H.js → system-settings-panel-U0tBgW46.js} +1 -1
  77. package/dist/gateway/static/root/assets/{theme-store-1OkdVC8l.js → theme-store-DCKDVPFF.js} +1 -1
  78. package/dist/gateway/static/root/assets/time-picker-BpiBF5-d.js +1 -0
  79. package/dist/gateway/static/root/assets/{typed-models-lib-D-_vct_y.js → typed-models-lib-D0XCOCAM.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-channel-catalog-VlFtjlET.js → use-channel-catalog-mq_Inao2.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-context-page-BOC6Hn19.js +1 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-BhDk-UV_.js → voice-api-key-field-CKaDitO6.js} +1 -1
  83. package/dist/gateway/static/root/assets/work-discovery-page-DWGYp5yV.js +1 -0
  84. package/dist/gateway/static/root/assets/work-item-detail-page-CpeWcpSp.js +1 -0
  85. package/dist/gateway/static/root/assets/work-page-MsEKzmSt.js +1 -0
  86. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-uVw4Yoej.js → workflow-run-setup-panel-s_kS_FYA.js} +2 -2
  87. package/dist/gateway/static/root/assets/workflows-page-ByhHaUHB.js +11 -0
  88. package/dist/gateway/static/root/index.html +7 -7
  89. package/dist/package.js +1 -1
  90. package/dist/src/agent/agent-manager.d.ts +3 -1
  91. package/dist/src/agent/agent-manager.js +4 -3
  92. package/dist/src/agent/capabilities/definitions.d.ts +2 -1
  93. package/dist/src/agent/capabilities/definitions.js +3 -1
  94. package/dist/src/agent/memory/builtin-provider.js +4 -4
  95. package/dist/src/agent/memory/manager.d.ts +4 -1
  96. package/dist/src/agent/memory/manager.js +8 -3
  97. package/dist/src/agent/memory/understanding/service.d.ts +2 -0
  98. package/dist/src/agent/memory/understanding/service.js +11 -9
  99. package/dist/src/agent/prompt/sections/tooling.js +4 -0
  100. package/dist/src/agent/service.d.ts +3 -1
  101. package/dist/src/agent/service.js +29 -0
  102. package/dist/src/agent/skills/hub-pull.js +1 -1
  103. package/dist/src/agent/skills/index.js +1 -1
  104. package/dist/src/agent/skills/install-target.js +1 -1
  105. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.d.ts +64 -0
  106. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +27 -18
  107. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +1 -1
  108. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +1 -1
  109. package/dist/src/agent/skills/marketplace/search.d.ts +46 -0
  110. package/dist/src/agent/skills/marketplace/search.js +193 -0
  111. package/dist/src/agent/skills/skill-tool-gating.js +2 -1
  112. package/dist/src/agent/tools/delegate-tool.js +2 -0
  113. package/dist/src/agent/tools/factory.d.ts +4 -2
  114. package/dist/src/agent/tools/factory.js +11 -5
  115. package/dist/src/agent/tools/index.d.ts +2 -1
  116. package/dist/src/agent/tools/index.js +2 -1
  117. package/dist/src/agent/tools/skill-install-tool.d.ts +17 -0
  118. package/dist/src/agent/tools/skill-install-tool.js +76 -8
  119. package/dist/src/agent/tools/skills-marketplace-search-tool.d.ts +17 -0
  120. package/dist/src/agent/tools/skills-marketplace-search-tool.js +77 -0
  121. package/dist/src/automations/domain/validation.d.ts +8 -8
  122. package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -1
  123. package/dist/src/browser/providers/cloakbrowser.js +1 -1
  124. package/dist/src/capabilities/store-connector.js +1 -1
  125. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  126. package/dist/src/config/agent-profile.js +1 -1
  127. package/dist/src/connectors/composio-sessions.d.ts +1 -0
  128. package/dist/src/connectors/composio-sessions.js +14 -5
  129. package/dist/src/connectors/composio-triggers.d.ts +1 -1
  130. package/dist/src/connectors/composio-triggers.js +4 -3
  131. package/dist/src/connectors/composio.js +1 -0
  132. package/dist/src/connectors/{connector-memory-sync.d.ts → connected-source-ingestion.d.ts} +11 -4
  133. package/dist/src/connectors/{connector-memory-sync.js → connected-source-ingestion.js} +49 -101
  134. package/dist/src/connectors/connected-source-normalizers.d.ts +15 -0
  135. package/dist/src/connectors/connected-source-normalizers.js +186 -0
  136. package/dist/src/connectors/connector-identity.d.ts +2 -0
  137. package/dist/src/connectors/connector-identity.js +29 -0
  138. package/dist/src/connectors/learning-coordinator.d.ts +25 -0
  139. package/dist/src/connectors/learning-coordinator.js +214 -0
  140. package/dist/src/connectors/learning-recipes.d.ts +22 -0
  141. package/dist/src/connectors/learning-recipes.js +121 -0
  142. package/dist/src/connectors/runtime-status.d.ts +1 -8
  143. package/dist/src/connectors/runtime-status.js +4 -29
  144. package/dist/src/extensions/api.js +1 -1
  145. package/dist/src/extensions/install.js +1 -1
  146. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  147. package/dist/src/gateway/agent-builtin-tools.js +2 -0
  148. package/dist/src/gateway/agents-admin.js +1 -1
  149. package/dist/src/gateway/heartbeat/service.js +1 -1
  150. package/dist/src/gateway/hono/routes/commands-skills.js +2 -2
  151. package/dist/src/gateway/hono/routes/connectors.js +76 -118
  152. package/dist/src/gateway/hono/routes/local-apps.js +1 -1
  153. package/dist/src/gateway/hono/routes/models.js +24 -0
  154. package/dist/src/gateway/hono/routes/public-gateway.js +3 -2
  155. package/dist/src/gateway/hono/routes/you.js +86 -5
  156. package/dist/src/gateway/service/marketplace-service.js +1 -1
  157. package/dist/src/gateway/service.d.ts +5 -2
  158. package/dist/src/gateway/service.js +18 -13
  159. package/dist/src/heartbeat/index.js +1 -1
  160. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +19 -0
  161. package/dist/src/knowledge/connected-understanding-pipeline.js +268 -0
  162. package/dist/src/knowledge/index.d.ts +1 -0
  163. package/dist/src/knowledge/index.js +2 -1
  164. package/dist/src/knowledge/ingestion-service.d.ts +6 -4
  165. package/dist/src/knowledge/ingestion-service.js +13 -10
  166. package/dist/src/knowledge/local-folder-adapter.js +1 -0
  167. package/dist/src/knowledge/people-graph.js +43 -110
  168. package/dist/src/knowledge/types.d.ts +3 -0
  169. package/dist/src/mcp/channel-bridge.js +1 -1
  170. package/dist/src/providers/xopc-cloud-account-service.d.ts +40 -0
  171. package/dist/src/providers/xopc-cloud-account-service.js +65 -0
  172. package/dist/src/storage/sqlite/connector-learning-repository.d.ts +47 -0
  173. package/dist/src/storage/sqlite/connector-learning-repository.js +110 -0
  174. package/dist/src/storage/sqlite/index.d.ts +3 -1
  175. package/dist/src/storage/sqlite/index.js +4 -2
  176. package/dist/src/storage/sqlite/knowledge-repository.d.ts +4 -2
  177. package/dist/src/storage/sqlite/knowledge-repository.js +24 -13
  178. package/dist/src/storage/sqlite/migrations/062_connector_learning_jobs.sql +27 -0
  179. package/dist/src/storage/sqlite/migrations/063_knowledge_collection_scopes.sql +14 -0
  180. package/dist/src/storage/sqlite/migrations/064_user_claims.sql +60 -0
  181. package/dist/src/storage/sqlite/migrations/065_knowledge_item_scope_identity.sql +116 -0
  182. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  183. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  184. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  185. package/dist/src/storage/sqlite/schema.js +1 -1
  186. package/dist/src/storage/sqlite/user-claims-repository.d.ts +101 -0
  187. package/dist/src/storage/sqlite/user-claims-repository.js +241 -0
  188. package/dist/src/user-context/projection.d.ts +36 -1
  189. package/dist/src/user-context/projection.js +84 -6
  190. package/dist/src/work-discovery/service.js +1 -0
  191. package/package.json +1 -1
  192. package/skills/tools/find-skills/SKILL.md +18 -428
  193. package/dist/gateway/static/root/assets/agents-ZCIC8mhO.js +0 -2
  194. package/dist/gateway/static/root/assets/apps-page-DJmgBaAm.js +0 -1
  195. package/dist/gateway/static/root/assets/automations-page-Ddot8-Md.js +0 -6
  196. package/dist/gateway/static/root/assets/block-editor-D3GIllO3.js +0 -184
  197. package/dist/gateway/static/root/assets/browser-settings-page-DvETvRcg.js +0 -8
  198. package/dist/gateway/static/root/assets/capabilities-settings-panel-ChXIYbys.js +0 -7
  199. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CUekXsJy.js +0 -1
  200. package/dist/gateway/static/root/assets/channels-settings-CkhveNsQ.js +0 -1
  201. package/dist/gateway/static/root/assets/channels-status-swr-DRTb8DBk.js +0 -1
  202. package/dist/gateway/static/root/assets/connector-logo-CQznQcd4.js +0 -1
  203. package/dist/gateway/static/root/assets/connectors-page-DkSGIxWP.js +0 -2
  204. package/dist/gateway/static/root/assets/desktop-pet-BtP-xUQ9.js +0 -1
  205. package/dist/gateway/static/root/assets/dreaming-settings-gd9W6SLj.js +0 -3
  206. package/dist/gateway/static/root/assets/goal-detail-page-DizZ6Cpl.js +0 -4
  207. package/dist/gateway/static/root/assets/goals-page-Dqry_hi2.js +0 -2
  208. package/dist/gateway/static/root/assets/index-DEdyUjxM.css +0 -1
  209. package/dist/gateway/static/root/assets/logs-page-mT48mcF4.js +0 -7
  210. package/dist/gateway/static/root/assets/notes-workbench-wgt2Osyk.js +0 -4
  211. package/dist/gateway/static/root/assets/project-detail-page-CDjHvxJm.js +0 -1
  212. package/dist/gateway/static/root/assets/projects-page-kJZwQXfC.js +0 -1
  213. package/dist/gateway/static/root/assets/remote-access-hub-MJdI9ek_.js +0 -1
  214. package/dist/gateway/static/root/assets/sessions-page-BqC7GDC_.js +0 -1
  215. package/dist/gateway/static/root/assets/settings-advanced-gate-CYwz8MfF.js +0 -1
  216. package/dist/gateway/static/root/assets/shares-settings-h8tGDkA3.js +0 -1
  217. package/dist/gateway/static/root/assets/skill-reload-api-D2DGvRUn.js +0 -1
  218. package/dist/gateway/static/root/assets/skills-page-vqhjSMhZ.js +0 -2
  219. package/dist/gateway/static/root/assets/time-picker-mtD64kFB.js +0 -1
  220. package/dist/gateway/static/root/assets/user-context-page-BgF0WxjM.js +0 -1
  221. package/dist/gateway/static/root/assets/work-discovery-page-CP0Daig-.js +0 -1
  222. package/dist/gateway/static/root/assets/work-item-detail-page-NEWZPKB_.js +0 -1
  223. package/dist/gateway/static/root/assets/work-page-BkWntcQh.js +0 -1
  224. package/dist/gateway/static/root/assets/workflows-page-DRvhNQGe.js +0 -11
  225. package/dist/src/connectors/memory-sync-coordinator.d.ts +0 -28
  226. package/dist/src/connectors/memory-sync-coordinator.js +0 -162
  227. package/dist/src/connectors/memory-sync-profile.d.ts +0 -13
  228. package/dist/src/connectors/memory-sync-profile.js +0 -73
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
3
3
  /** Baseline schema version applied from schema.sql on first open. */
4
4
  export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
5
5
  /** Latest schema version this release supports (increment when adding migrations). */
6
- export declare const XOPC_DB_SCHEMA_VERSION = 61;
6
+ export declare const XOPC_DB_SCHEMA_VERSION = 65;
7
7
  export declare function resolveMigrationsDir(override?: string): string;
8
8
  /**
9
9
  * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
12
12
  /** Baseline schema version applied from schema.sql on first open. */
13
13
  const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
14
14
  /** Latest schema version this release supports (increment when adding migrations). */
15
- const XOPC_DB_SCHEMA_VERSION = 61;
15
+ const XOPC_DB_SCHEMA_VERSION = 65;
16
16
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
17
17
  function resolveMigrationsDir(override) {
18
18
  if (override) return override;
@@ -46,7 +46,7 @@ function applySingleMigration(db, migration) {
46
46
  * Each step runs in its own transaction and updates schema_meta on success.
47
47
  */
48
48
  function applyPendingMigrations(db, options = {}) {
49
- const targetVersion = options.targetVersion ?? 61;
49
+ const targetVersion = options.targetVersion ?? 65;
50
50
  let currentVersion = readSchemaVersion(db);
51
51
  if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
52
52
  if (currentVersion >= targetVersion) return currentVersion;
@@ -62,7 +62,7 @@ function applyPendingMigrations(db, options = {}) {
62
62
  }
63
63
  /** Inspect schema version without mutating the database. */
64
64
  function inspectSchemaMigrationStatus(db, options = {}) {
65
- const appVersion = options.targetVersion ?? 61;
65
+ const appVersion = options.targetVersion ?? 65;
66
66
  const dbVersion = readSchemaVersion(db);
67
67
  if (dbVersion > appVersion) return {
68
68
  dbVersion,
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
19
19
  export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
20
20
 
21
21
  /** Latest schema version this release supports (increment when adding migrations). */
22
- export const XOPC_DB_SCHEMA_VERSION = 61;
22
+ export const XOPC_DB_SCHEMA_VERSION = 65;
23
23
 
24
24
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
25
25
 
@@ -31,7 +31,7 @@ function ensureXopcDatabaseSchema(db) {
31
31
  bootstrapFreshDatabase(db);
32
32
  currentVersion = 11;
33
33
  }
34
- applyPendingMigrations(db, { targetVersion: 61 });
34
+ applyPendingMigrations(db, { targetVersion: 65 });
35
35
  }
36
36
  //#endregion
37
37
  export { SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, ensureSchemaMetaTable, ensureXopcDatabaseSchema, readSchemaVersion, readSchemaVersionForTest, setSchemaVersion };
@@ -0,0 +1,101 @@
1
+ export type UserEntityType = 'person' | 'project' | 'organization';
2
+ export type UserEntityHandleType = 'email' | 'provider_user' | 'display_name';
3
+ export type UserClaimClass = 'relationship' | 'project' | 'routine';
4
+ export type UserClaimState = 'provisional' | 'active' | 'rejected' | 'stale';
5
+ export type UserClaimUserState = 'auto' | 'confirmed' | 'rejected';
6
+ export type UserEntity = {
7
+ id: string;
8
+ type: UserEntityType;
9
+ canonicalLabel: string;
10
+ createdAt: string;
11
+ updatedAt: string;
12
+ };
13
+ export type UserClaim = {
14
+ id: string;
15
+ agentId: string;
16
+ class: UserClaimClass;
17
+ key: string;
18
+ subjectEntityId?: string;
19
+ value: Record<string, unknown>;
20
+ state: UserClaimState;
21
+ userState: UserClaimUserState;
22
+ confidence: number;
23
+ independentEvidenceCount: number;
24
+ activeDayCount: number;
25
+ firstObservedAt: string;
26
+ lastReinforcedAt: string;
27
+ memoryRecordId?: string;
28
+ createdAt: string;
29
+ updatedAt: string;
30
+ };
31
+ export declare function resolveUserEntity(input: {
32
+ type: UserEntityType;
33
+ canonicalLabel: string;
34
+ handles: Array<{
35
+ type: UserEntityHandleType;
36
+ value: string;
37
+ sourceScope: string;
38
+ verified: boolean;
39
+ }>;
40
+ nowMs?: number;
41
+ }): UserEntity;
42
+ export declare function reinforceUserClaim(input: {
43
+ agentId: string;
44
+ class: UserClaimClass;
45
+ key: string;
46
+ subjectEntityId?: string;
47
+ value: Record<string, unknown>;
48
+ evidence: Array<{
49
+ logicalEventKey: string;
50
+ sourceItemId: string;
51
+ sourceInstanceId: string;
52
+ relation: 'supports' | 'contradicts';
53
+ observedAt: string;
54
+ }>;
55
+ nowMs?: number;
56
+ }): UserClaim;
57
+ export declare function removeUserClaimEvidenceForSource(sourceInstanceId: string): {
58
+ deletedClaimCount: number;
59
+ deletedMemoryRecordIds: string[];
60
+ retainedClaims: Array<{
61
+ memoryRecordId: string;
62
+ state: UserClaimState;
63
+ }>;
64
+ };
65
+ export declare function setUserClaimDecision(claimId: string, userState: Exclude<UserClaimUserState, 'auto'>): UserClaim | undefined;
66
+ export declare function linkUserClaimMemoryRecord(claimId: string, memoryRecordId: string): void;
67
+ export declare function getUserClaim(claimId: string): UserClaim | undefined;
68
+ export declare function listUserClaims(options?: {
69
+ agentId?: string;
70
+ state?: UserClaimState;
71
+ limit?: number;
72
+ }): UserClaim[];
73
+ export declare function listUserClaimEvidence(claimId: string): Array<{
74
+ logicalEventKey: string;
75
+ sourceItemId: string;
76
+ sourceInstanceId: string;
77
+ relation: string;
78
+ observedAt: string;
79
+ }>;
80
+ export declare function listUserPeopleGraphRows(): {
81
+ people: Array<UserEntity & {
82
+ handles: Array<{
83
+ type: UserEntityHandleType;
84
+ value: string;
85
+ }>;
86
+ }>;
87
+ edges: Array<{
88
+ entityId: string;
89
+ sourceInstanceId: string;
90
+ mentionCount: number;
91
+ lastObservedAt: string;
92
+ }>;
93
+ evidenceCount: number;
94
+ };
95
+ export declare function listUserClaimStatsBySource(): Record<string, {
96
+ evidenceCount: number;
97
+ provisionalClaims: number;
98
+ activeClaims: number;
99
+ resolvedEntities: number;
100
+ lastEvidenceAt?: string;
101
+ }>;
@@ -0,0 +1,241 @@
1
+ import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
2
+ import { randomUUID } from "node:crypto";
3
+ //#region src/storage/sqlite/user-claims-repository.ts
4
+ function entityFromRow(row) {
5
+ return {
6
+ id: row.entity_id,
7
+ type: row.entity_type,
8
+ canonicalLabel: row.canonical_label,
9
+ createdAt: new Date(row.created_at).toISOString(),
10
+ updatedAt: new Date(row.updated_at).toISOString()
11
+ };
12
+ }
13
+ function claimFromRow(row) {
14
+ return {
15
+ id: row.claim_id,
16
+ agentId: row.agent_id,
17
+ class: row.claim_class,
18
+ key: row.claim_key,
19
+ ...row.subject_entity_id ? { subjectEntityId: row.subject_entity_id } : {},
20
+ value: JSON.parse(row.value_json),
21
+ state: row.state,
22
+ userState: row.user_state,
23
+ confidence: row.confidence,
24
+ independentEvidenceCount: row.independent_evidence_count,
25
+ activeDayCount: row.active_day_count,
26
+ firstObservedAt: new Date(row.first_observed_at).toISOString(),
27
+ lastReinforcedAt: new Date(row.last_reinforced_at).toISOString(),
28
+ ...row.memory_record_id ? { memoryRecordId: row.memory_record_id } : {},
29
+ createdAt: new Date(row.created_at).toISOString(),
30
+ updatedAt: new Date(row.updated_at).toISOString()
31
+ };
32
+ }
33
+ function resolveUserEntity(input) {
34
+ const now = input.nowMs ?? Date.now();
35
+ return runSqliteWriteTransaction((db) => {
36
+ const handles = input.handles.map((handle) => ({
37
+ ...handle,
38
+ value: handle.value.trim().toLowerCase()
39
+ })).filter((handle) => handle.value);
40
+ const strong = handles.filter((handle) => handle.verified);
41
+ let row;
42
+ for (const handle of strong) {
43
+ row = db.prepare(`SELECT e.* FROM user_entities e JOIN user_entity_handles h ON h.entity_id = e.entity_id
44
+ WHERE h.handle_type = ? AND h.normalized_value = ? AND h.source_scope = ?`).get(handle.type, handle.value, handle.sourceScope);
45
+ if (row) break;
46
+ }
47
+ if (!row) {
48
+ const fallback = handles[0];
49
+ if (fallback) row = db.prepare(`SELECT e.* FROM user_entities e JOIN user_entity_handles h ON h.entity_id = e.entity_id
50
+ WHERE h.handle_type = ? AND h.normalized_value = ? AND h.source_scope = ?`).get(fallback.type, fallback.value, fallback.sourceScope);
51
+ }
52
+ const entityId = row?.entity_id ?? randomUUID();
53
+ if (!row) db.prepare(`INSERT INTO user_entities (entity_id, entity_type, canonical_label, created_at, updated_at)
54
+ VALUES (?, ?, ?, ?, ?)`).run(entityId, input.type, input.canonicalLabel, now, now);
55
+ else {
56
+ const incomingHumanName = input.canonicalLabel.includes(" ") && !input.canonicalLabel.includes("@");
57
+ const existingHumanName = row.canonical_label.includes(" ") && !row.canonical_label.includes("@");
58
+ if (incomingHumanName && (!existingHumanName || input.canonicalLabel.length > row.canonical_label.length)) db.prepare("UPDATE user_entities SET canonical_label = ?, updated_at = ? WHERE entity_id = ?").run(input.canonicalLabel, now, entityId);
59
+ }
60
+ for (const handle of handles) db.prepare(`INSERT OR IGNORE INTO user_entity_handles
61
+ (entity_id, handle_type, normalized_value, source_scope, verified, created_at)
62
+ VALUES (?, ?, ?, ?, ?, ?)`).run(entityId, handle.type, handle.value, handle.sourceScope, handle.verified ? 1 : 0, now);
63
+ return entityFromRow(db.prepare("SELECT * FROM user_entities WHERE entity_id = ?").get(entityId));
64
+ });
65
+ }
66
+ function thresholds(claimClass) {
67
+ return claimClass === "routine" ? {
68
+ evidence: 3,
69
+ days: 3
70
+ } : {
71
+ evidence: 3,
72
+ days: 2
73
+ };
74
+ }
75
+ function refreshUserClaim(db, row, now) {
76
+ const stats = db.prepare(`SELECT
77
+ SUM(CASE WHEN relation = 'supports' THEN 1 ELSE 0 END) AS evidence_count,
78
+ SUM(CASE WHEN relation = 'contradicts' THEN 1 ELSE 0 END) AS contradiction_count,
79
+ COUNT(DISTINCT CASE WHEN relation = 'supports' THEN date(observed_at / 1000, 'unixepoch') END) AS active_days,
80
+ MAX(observed_at) AS last_observed
81
+ FROM user_claim_evidence WHERE claim_id = ?`).get(row.claim_id);
82
+ const evidenceCount = stats.evidence_count ?? 0;
83
+ const contradictionCount = stats.contradiction_count ?? 0;
84
+ const limit = thresholds(row.claim_class);
85
+ const state = row.user_state === "rejected" ? "rejected" : row.user_state === "confirmed" ? "active" : contradictionCount >= evidenceCount && contradictionCount > 0 ? "stale" : evidenceCount >= limit.evidence && stats.active_days >= limit.days ? "active" : "provisional";
86
+ const confidence = Math.max(.1, Math.min(.92, .48 + Math.min(evidenceCount, 8) * .035 + Math.min(stats.active_days, 5) * .045 - Math.min(contradictionCount, 5) * .08));
87
+ db.prepare(`UPDATE user_claims SET state = ?, confidence = ?, independent_evidence_count = ?,
88
+ active_day_count = ?, last_reinforced_at = ?, updated_at = ? WHERE claim_id = ?`).run(state, confidence, evidenceCount, stats.active_days, stats.last_observed ?? row.last_reinforced_at, now, row.claim_id);
89
+ return claimFromRow(db.prepare("SELECT * FROM user_claims WHERE claim_id = ?").get(row.claim_id));
90
+ }
91
+ function reinforceUserClaim(input) {
92
+ const now = input.nowMs ?? Date.now();
93
+ return runSqliteWriteTransaction((db) => {
94
+ let row = db.prepare("SELECT * FROM user_claims WHERE agent_id = ? AND claim_class = ? AND claim_key = ?").get(input.agentId, input.class, input.key);
95
+ const claimId = row?.claim_id ?? randomUUID();
96
+ if (!row) {
97
+ const firstObserved = Math.min(...input.evidence.map((item) => Date.parse(item.observedAt)), now);
98
+ db.prepare(`INSERT INTO user_claims (
99
+ claim_id, agent_id, claim_class, claim_key, subject_entity_id, value_json, state, user_state,
100
+ confidence, independent_evidence_count, active_day_count, first_observed_at, last_reinforced_at,
101
+ created_at, updated_at
102
+ ) VALUES (?, ?, ?, ?, ?, ?, 'provisional', 'auto', 0, 0, 0, ?, ?, ?, ?)`).run(claimId, input.agentId, input.class, input.key, input.subjectEntityId ?? null, JSON.stringify(input.value), firstObserved, now, now, now);
103
+ }
104
+ for (const evidence of input.evidence) db.prepare(`INSERT INTO user_claim_evidence (
105
+ claim_id, logical_event_key, source_item_id, source_instance_id, relation, observed_at, created_at
106
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
107
+ ON CONFLICT(claim_id, logical_event_key) DO UPDATE SET
108
+ source_item_id = excluded.source_item_id,
109
+ source_instance_id = excluded.source_instance_id,
110
+ relation = excluded.relation,
111
+ observed_at = excluded.observed_at`).run(claimId, evidence.logicalEventKey, evidence.sourceItemId, evidence.sourceInstanceId, evidence.relation, Date.parse(evidence.observedAt), now);
112
+ db.prepare("UPDATE user_claims SET subject_entity_id = ?, value_json = ? WHERE claim_id = ?").run(input.subjectEntityId ?? null, JSON.stringify(input.value), claimId);
113
+ row = db.prepare("SELECT * FROM user_claims WHERE claim_id = ?").get(claimId);
114
+ return refreshUserClaim(db, row, now);
115
+ });
116
+ }
117
+ function removeUserClaimEvidenceForSource(sourceInstanceId) {
118
+ return runSqliteWriteTransaction((db) => {
119
+ const affected = db.prepare(`SELECT DISTINCT c.* FROM user_claims c
120
+ JOIN user_claim_evidence e ON e.claim_id = c.claim_id
121
+ WHERE e.source_instance_id = ?`).all(sourceInstanceId);
122
+ db.prepare("DELETE FROM user_claim_evidence WHERE source_instance_id = ?").run(sourceInstanceId);
123
+ const deletedMemoryRecordIds = [];
124
+ const retainedClaims = [];
125
+ let deletedClaimCount = 0;
126
+ const now = Date.now();
127
+ for (const row of affected) {
128
+ if (db.prepare("SELECT COUNT(*) AS count FROM user_claim_evidence WHERE claim_id = ?").get(row.claim_id).count === 0) {
129
+ if (row.memory_record_id) deletedMemoryRecordIds.push(row.memory_record_id);
130
+ db.prepare("DELETE FROM user_claims WHERE claim_id = ?").run(row.claim_id);
131
+ deletedClaimCount += 1;
132
+ continue;
133
+ }
134
+ const claim = refreshUserClaim(db, row, now);
135
+ if (claim.memoryRecordId) retainedClaims.push({
136
+ memoryRecordId: claim.memoryRecordId,
137
+ state: claim.state
138
+ });
139
+ }
140
+ return {
141
+ deletedClaimCount,
142
+ deletedMemoryRecordIds,
143
+ retainedClaims
144
+ };
145
+ });
146
+ }
147
+ function setUserClaimDecision(claimId, userState) {
148
+ runSqliteWriteTransaction((db) => {
149
+ db.prepare(`UPDATE user_claims SET user_state = ?, state = ?, updated_at = ? WHERE claim_id = ?`).run(userState, userState === "confirmed" ? "active" : "rejected", Date.now(), claimId);
150
+ });
151
+ return getUserClaim(claimId);
152
+ }
153
+ function linkUserClaimMemoryRecord(claimId, memoryRecordId) {
154
+ runSqliteWriteTransaction((db) => {
155
+ db.prepare("UPDATE user_claims SET memory_record_id = ?, updated_at = ? WHERE claim_id = ?").run(memoryRecordId, Date.now(), claimId);
156
+ });
157
+ }
158
+ function getUserClaim(claimId) {
159
+ const row = getSqliteDatabase().prepare("SELECT * FROM user_claims WHERE claim_id = ?").get(claimId);
160
+ return row ? claimFromRow(row) : void 0;
161
+ }
162
+ function listUserClaims(options = {}) {
163
+ const where = [];
164
+ const params = [];
165
+ if (options.agentId) {
166
+ where.push("agent_id = ?");
167
+ params.push(options.agentId);
168
+ }
169
+ if (options.state) {
170
+ where.push("state = ?");
171
+ params.push(options.state);
172
+ }
173
+ const limit = Math.max(1, Math.min(options.limit ?? 100, 500));
174
+ return getSqliteDatabase().prepare(`SELECT * FROM user_claims
175
+ ${where.length ? `WHERE ${where.join(" AND ")}` : ""}
176
+ ORDER BY confidence DESC, last_reinforced_at DESC LIMIT ?`).all(...params, limit).map(claimFromRow);
177
+ }
178
+ function listUserClaimEvidence(claimId) {
179
+ return getSqliteDatabase().prepare(`SELECT logical_event_key, source_item_id, source_instance_id, relation, observed_at
180
+ FROM user_claim_evidence WHERE claim_id = ? ORDER BY observed_at DESC`).all(claimId).map((row) => ({
181
+ logicalEventKey: row.logical_event_key,
182
+ sourceItemId: row.source_item_id,
183
+ sourceInstanceId: row.source_instance_id,
184
+ relation: row.relation,
185
+ observedAt: new Date(row.observed_at).toISOString()
186
+ }));
187
+ }
188
+ function listUserPeopleGraphRows() {
189
+ const db = getSqliteDatabase();
190
+ const entities = db.prepare(`SELECT * FROM user_entities e WHERE entity_type = 'person'
191
+ AND EXISTS (SELECT 1 FROM user_claims c JOIN user_claim_evidence ce ON ce.claim_id = c.claim_id
192
+ WHERE c.subject_entity_id = e.entity_id)`).all();
193
+ const handles = db.prepare(`SELECT entity_id, handle_type, normalized_value FROM user_entity_handles
194
+ WHERE entity_id IN (SELECT entity_id FROM user_entities WHERE entity_type = 'person')`).all();
195
+ const byEntity = /* @__PURE__ */ new Map();
196
+ for (const handle of handles) {
197
+ const values = byEntity.get(handle.entity_id) ?? [];
198
+ values.push({
199
+ type: handle.handle_type,
200
+ value: handle.normalized_value
201
+ });
202
+ byEntity.set(handle.entity_id, values);
203
+ }
204
+ const edgeRows = db.prepare(`SELECT c.subject_entity_id AS entity_id, e.source_instance_id,
205
+ COUNT(*) AS mention_count, MAX(e.observed_at) AS last_observed_at
206
+ FROM user_claims c JOIN user_claim_evidence e ON e.claim_id = c.claim_id
207
+ WHERE c.claim_class = 'relationship' AND c.subject_entity_id IS NOT NULL AND e.relation = 'supports'
208
+ GROUP BY c.subject_entity_id, e.source_instance_id`).all();
209
+ return {
210
+ people: entities.map((row) => ({
211
+ ...entityFromRow(row),
212
+ handles: byEntity.get(row.entity_id) ?? []
213
+ })),
214
+ edges: edgeRows.map((row) => ({
215
+ entityId: row.entity_id,
216
+ sourceInstanceId: row.source_instance_id,
217
+ mentionCount: row.mention_count,
218
+ lastObservedAt: new Date(row.last_observed_at).toISOString()
219
+ })),
220
+ evidenceCount: edgeRows.reduce((sum, row) => sum + row.mention_count, 0)
221
+ };
222
+ }
223
+ function listUserClaimStatsBySource() {
224
+ const rows = getSqliteDatabase().prepare(`SELECT e.source_instance_id,
225
+ COUNT(*) AS evidence_count,
226
+ COUNT(DISTINCT CASE WHEN c.state = 'provisional' THEN c.claim_id END) AS provisional_claims,
227
+ COUNT(DISTINCT CASE WHEN c.state = 'active' THEN c.claim_id END) AS active_claims,
228
+ COUNT(DISTINCT c.subject_entity_id) AS resolved_entities,
229
+ MAX(e.observed_at) AS last_evidence_at
230
+ FROM user_claim_evidence e JOIN user_claims c ON c.claim_id = e.claim_id
231
+ GROUP BY e.source_instance_id`).all();
232
+ return Object.fromEntries(rows.map((row) => [row.source_instance_id, {
233
+ evidenceCount: row.evidence_count,
234
+ provisionalClaims: row.provisional_claims,
235
+ activeClaims: row.active_claims,
236
+ resolvedEntities: row.resolved_entities,
237
+ ...row.last_evidence_at == null ? {} : { lastEvidenceAt: new Date(row.last_evidence_at).toISOString() }
238
+ }]));
239
+ }
240
+ //#endregion
241
+ export { getUserClaim, linkUserClaimMemoryRecord, listUserClaimEvidence, listUserClaimStatsBySource, listUserClaims, listUserPeopleGraphRows, reinforceUserClaim, removeUserClaimEvidenceForSource, resolveUserEntity, setUserClaimDecision };
@@ -1,6 +1,7 @@
1
1
  import type { MemoryKind, MemoryRecord } from '../agent/memory/types.js';
2
2
  import type { ConnectorConnection, ConnectorDefinition, ConnectorInstance } from '../connectors/types.js';
3
3
  import type { KnowledgeSourceItem, KnowledgeSyncRun } from '../knowledge/types.js';
4
+ import type { ConnectorLearningJob } from '../storage/sqlite/index.js';
4
5
  export type UserContextFacet = 'basics' | 'collaboration' | 'boundaries' | 'priorities' | 'people' | 'current';
5
6
  export type UserContextOrigin = 'told_by_you' | 'observed' | 'inferred' | 'connected_source';
6
7
  export declare function isUserContextRecord(record: MemoryRecord): boolean;
@@ -26,6 +27,11 @@ export declare function projectUserContextRecord(record: MemoryRecord): {
26
27
  reviewAt: string;
27
28
  reviewDue: boolean;
28
29
  evidenceCount: number;
30
+ evidenceBasis: {
31
+ eventCount: number;
32
+ activeDays: number;
33
+ windowDays: number;
34
+ };
29
35
  sourcePath: string;
30
36
  latestEvidenceAt: string;
31
37
  validFrom: string;
@@ -34,10 +40,18 @@ export declare function projectUserContextRecord(record: MemoryRecord): {
34
40
  };
35
41
  export declare function isPersonalContextConnector(definition: ConnectorDefinition): boolean;
36
42
  export declare function recordsDerivedFromPersonalContextSource(records: MemoryRecord[], sourceInstanceId: string): MemoryRecord[];
37
- export declare function projectPersonalContextSources(definitions: ConnectorDefinition[], instances: ConnectorInstance[], records?: MemoryRecord[], knowledge?: {
43
+ export declare function projectPersonalContextSources(definitions: ConnectorDefinition[], instances: ConnectorInstance[], knowledge?: {
38
44
  sourceItems?: KnowledgeSourceItem[];
39
45
  syncRuns?: KnowledgeSyncRun[];
40
46
  connections?: ConnectorConnection[];
47
+ learningJobs?: ConnectorLearningJob[];
48
+ claimStatsBySource?: Record<string, {
49
+ evidenceCount: number;
50
+ provisionalClaims: number;
51
+ activeClaims: number;
52
+ resolvedEntities: number;
53
+ lastEvidenceAt?: string;
54
+ }>;
41
55
  }): {
42
56
  category: import("../connectors/types.js").ConnectorCategory;
43
57
  capabilities: ("context" | "tools" | "events" | "memory_source")[];
@@ -57,10 +71,31 @@ export declare function projectPersonalContextSources(definitions: ConnectorDefi
57
71
  lastHealthStatus: any;
58
72
  lastActivityAt: string;
59
73
  derivedUnderstandingCount: number;
74
+ learningFunnel: {
75
+ indexedItems: number;
76
+ attributedItems: number;
77
+ resolvedEntities: number;
78
+ provisionalClaims: number;
79
+ activeClaims: number;
80
+ evidenceCount: number;
81
+ lastEvidenceAt: string;
82
+ };
60
83
  knowledgeItemCount: number;
61
84
  lastSyncAt: string;
62
85
  lastSyncStatus: import("../knowledge/types.js").KnowledgeSyncRunStatus;
63
86
  lastSyncError: string;
87
+ learning: {
88
+ status: import("../storage/sqlite/connector-learning-repository.js").ConnectorLearningStatus;
89
+ phase: import("../storage/sqlite/connector-learning-repository.js").ConnectorLearningPhase;
90
+ itemsDiscovered: number;
91
+ itemsIndexed: number;
92
+ candidatesCreated: number;
93
+ mode: import("../storage/sqlite/connector-learning-repository.js").ConnectorLearningMode;
94
+ attemptCount: number;
95
+ nextRunAt: string;
96
+ error: string;
97
+ updatedAt: string;
98
+ };
64
99
  branding?: import("../connectors/types.js").ConnectorBranding;
65
100
  id: string;
66
101
  accountLabel: any;
@@ -39,9 +39,31 @@ function originForMemoryRecord(record) {
39
39
  const origin = classifyMemoryContextOrigin(record);
40
40
  return origin === "told_by_user" ? "told_by_you" : origin;
41
41
  }
42
+ function connectedEvidenceBasis(sourceText) {
43
+ if (!sourceText) return void 0;
44
+ try {
45
+ const value = JSON.parse(sourceText);
46
+ const eventCount = Number(value.eventCount);
47
+ const activeDays = Number(value.activeDays);
48
+ const windowDays = Number(value.windowDays);
49
+ if (![
50
+ eventCount,
51
+ activeDays,
52
+ windowDays
53
+ ].every((item) => Number.isInteger(item) && item > 0)) return void 0;
54
+ return {
55
+ eventCount,
56
+ activeDays,
57
+ windowDays
58
+ };
59
+ } catch {
60
+ return;
61
+ }
62
+ }
42
63
  function projectUserContextRecord(record) {
43
64
  const lifecycle = resolveMemoryStability(record);
44
65
  const latestEvidenceAt = record.evidence?.map((evidence) => evidence.observedAt).filter((value) => Boolean(value)).sort().at(-1);
66
+ const evidenceBasis = record.evidence?.map((evidence) => connectedEvidenceBasis(evidence.sourceText)).filter((value) => Boolean(value)).at(-1);
45
67
  return {
46
68
  id: record.id,
47
69
  statement: record.content,
@@ -61,6 +83,7 @@ function projectUserContextRecord(record) {
61
83
  reviewAt: lifecycle.reviewAt,
62
84
  reviewDue: lifecycle.reviewDue,
63
85
  evidenceCount: record.evidence?.length ?? 0,
86
+ evidenceBasis,
64
87
  sourcePath: record.source.path,
65
88
  latestEvidenceAt,
66
89
  validFrom: record.validFrom,
@@ -74,7 +97,29 @@ function isPersonalContextConnector(definition) {
74
97
  function recordsDerivedFromPersonalContextSource(records, sourceInstanceId) {
75
98
  return records.filter((record) => record.source.sourceInstanceId === sourceInstanceId && isUserContextRecord(record));
76
99
  }
77
- function projectPersonalContextSources(definitions, instances, records = [], knowledge = {}) {
100
+ function connectionIdentityKey(connection) {
101
+ const email = typeof connection.identity.email === "string" ? connection.identity.email.trim().toLocaleLowerCase() : "";
102
+ if (email) return `email:${email}`;
103
+ const username = typeof connection.identity.username === "string" ? connection.identity.username.trim().toLocaleLowerCase() : "";
104
+ if (username) return `username:${username}`;
105
+ return `connection:${connection.id}`;
106
+ }
107
+ function selectAccountConnections(connections) {
108
+ const byIdentity = /* @__PURE__ */ new Map();
109
+ for (const connection of connections) {
110
+ const key = connectionIdentityKey(connection);
111
+ const current = byIdentity.get(key);
112
+ if (!current) {
113
+ byIdentity.set(key, connection);
114
+ continue;
115
+ }
116
+ const currentRank = current.status === "active" ? 1 : 0;
117
+ const candidateRank = connection.status === "active" ? 1 : 0;
118
+ if (candidateRank > currentRank || candidateRank === currentRank && connection.updatedAt.localeCompare(current.updatedAt) > 0) byIdentity.set(key, connection);
119
+ }
120
+ return [...byIdentity.values()];
121
+ }
122
+ function projectPersonalContextSources(definitions, instances, knowledge = {}) {
78
123
  const instanceByConnector = /* @__PURE__ */ new Map();
79
124
  for (const instance of instances) {
80
125
  const current = instanceByConnector.get(instance.connectorId) ?? [];
@@ -83,7 +128,13 @@ function projectPersonalContextSources(definitions, instances, records = [], kno
83
128
  }
84
129
  return definitions.filter(isPersonalContextConnector).flatMap((definition) => {
85
130
  const connected = instanceByConnector.get(definition.id) ?? [];
86
- const accounts = (knowledge.connections ?? []).filter((connection) => connection.provider === "composio" && connection.connectorId === definition.id && connection.status !== "revoked").sort((left, right) => {
131
+ const candidateAccounts = (knowledge.connections ?? []).filter((connection) => connection.provider === "composio" && connection.connectorId === definition.id && connection.status !== "revoked");
132
+ const hasActiveAccount = candidateAccounts.some((connection) => connection.status === "active");
133
+ const accounts = selectAccountConnections(candidateAccounts.filter((connection) => !hasActiveAccount || ![
134
+ "pending",
135
+ "unknown",
136
+ "disabled"
137
+ ].includes(connection.status))).sort((left, right) => {
87
138
  return (left.connectedAt ?? left.createdAt).localeCompare(right.connectedAt ?? right.createdAt) || left.id.localeCompare(right.id);
88
139
  });
89
140
  return (accounts.length > 0 ? accounts.map((connection, index) => ({
@@ -117,9 +168,13 @@ function projectPersonalContextSources(definitions, instances, records = [], kno
117
168
  lastConnectedAt: void 0,
118
169
  instances: []
119
170
  }]).map((row) => {
120
- const relatedRecords = row.sourceInstanceId ? records.filter((record) => record.source.sourceInstanceId === row.sourceInstanceId) : [];
121
171
  const sourceItems = row.sourceInstanceId ? (knowledge.sourceItems ?? []).filter((item) => item.sourceInstanceId === row.sourceInstanceId) : [];
172
+ const claimStats = row.sourceInstanceId ? knowledge.claimStatsBySource?.[row.sourceInstanceId] : void 0;
122
173
  const latestSync = (knowledge.syncRuns ?? []).filter((run) => run.sourceInstanceId === row.sourceInstanceId).sort((left, right) => Date.parse(right.startedAt) - Date.parse(left.startedAt))[0];
174
+ const learningJobs = (knowledge.learningJobs ?? []).filter((job) => job.sourceInstanceId === row.sourceInstanceId).sort((left, right) => Date.parse(right.createdAt) - Date.parse(left.createdAt));
175
+ const now = Date.now();
176
+ const nextScheduledLearning = learningJobs.filter((job) => job.status === "queued" && job.nextRunAt && Date.parse(job.nextRunAt) > now).sort((left, right) => Date.parse(left.nextRunAt) - Date.parse(right.nextRunAt))[0];
177
+ const latestLearning = learningJobs.find((job) => job.status !== "queued" || !job.nextRunAt || Date.parse(job.nextRunAt) <= now) ?? learningJobs[0];
123
178
  const latestHealth = row.instances.filter((instance) => instance.usage.lastHealthCheckAt && instance.usage.lastHealthStatus).sort((left, right) => Date.parse(right.usage.lastHealthCheckAt) - Date.parse(left.usage.lastHealthCheckAt))[0]?.usage;
124
179
  const permissionDetails = definition.permissions?.data ?? [];
125
180
  const canWrite = permissionDetails.some((permission) => /(?:^|[.:/_-])(write|create|update|delete|manage|send|admin)(?:$|[.:/_-])/i.test(permission));
@@ -154,13 +209,36 @@ function projectPersonalContextSources(definitions, instances, records = [], kno
154
209
  ...instance.audit.map((entry) => entry.at)
155
210
  ]),
156
211
  latestSync?.finishedAt,
157
- latestSync?.startedAt
212
+ latestSync?.startedAt,
213
+ latestLearning?.finishedAt,
214
+ latestLearning?.startedAt
158
215
  ].filter((value) => Boolean(value)).sort().at(-1),
159
- derivedUnderstandingCount: relatedRecords.length,
216
+ derivedUnderstandingCount: claimStats?.activeClaims ?? 0,
217
+ learningFunnel: {
218
+ indexedItems: sourceItems.filter((item) => !item.deletedAt).length,
219
+ attributedItems: sourceItems.filter((item) => !item.deletedAt && item.metadata.actorAttributed === true).length,
220
+ resolvedEntities: claimStats?.resolvedEntities ?? 0,
221
+ provisionalClaims: claimStats?.provisionalClaims ?? 0,
222
+ activeClaims: claimStats?.activeClaims ?? 0,
223
+ evidenceCount: claimStats?.evidenceCount ?? 0,
224
+ lastEvidenceAt: claimStats?.lastEvidenceAt
225
+ },
160
226
  knowledgeItemCount: sourceItems.filter((item) => !item.deletedAt).length,
161
227
  lastSyncAt: latestSync?.finishedAt ?? latestSync?.startedAt,
162
228
  lastSyncStatus: latestSync?.status,
163
- lastSyncError: latestSync?.error
229
+ lastSyncError: latestSync?.error,
230
+ learning: latestLearning ? {
231
+ status: latestLearning.status,
232
+ phase: latestLearning.phase,
233
+ itemsDiscovered: latestLearning.itemsDiscovered,
234
+ itemsIndexed: latestLearning.itemsIndexed,
235
+ candidatesCreated: latestLearning.candidatesCreated,
236
+ mode: latestLearning.mode,
237
+ attemptCount: latestLearning.attemptCount,
238
+ nextRunAt: nextScheduledLearning?.nextRunAt ?? latestLearning.nextRunAt,
239
+ error: latestLearning.error,
240
+ updatedAt: latestLearning.updatedAt
241
+ } : void 0
164
242
  };
165
243
  });
166
244
  }).sort((left, right) => {
@@ -267,6 +267,7 @@ var WorkDiscoveryService = class {
267
267
  });
268
268
  return {
269
269
  sourceInstanceId: "desktop:calendar",
270
+ collectionScope: "events",
270
271
  externalId: item.id,
271
272
  itemType: "calendar_event",
272
273
  authorRole: "unknown",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xopcai/xopc",
3
- "version": "0.0.171",
3
+ "version": "0.0.173",
4
4
  "description": "Local-first AI system that remembers context, coordinates AI, and sustains long-term progress.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",