@xopcai/xopc 0.0.171 → 0.0.172

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 (189) 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-C3Y-bESI.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BKZO0EFn.js → agent-avatar-dicebear-CPyev9P7.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-Bf_kK2Ay.js +2 -0
  6. package/dist/gateway/static/root/assets/{api-N2qKY-WI.js → api-B7qEr_Rw.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-CNZkpXCD.js → app-management-settings-panel-Br_9-7fs.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-Drf5a563.js → appearance-settings-uyLcRPai.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-DXFCP5-1.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-ChVwOXE5.js → archive-plugin-B19REnR5.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-BVK3Y2d9.js → attachment-load-DLWCC4Yi.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automation-suggestion-card-DH4N0SYR.js → automation-suggestion-card-ky5S5lly.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-page-D8pT1o2O.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-CeHY6VVP.js → binary-plugins-CtPEzLlo.js} +1 -1
  15. package/dist/gateway/static/root/assets/block-editor-CQVR4Xij.js +184 -0
  16. package/dist/gateway/static/root/assets/browser-settings-page-Bav_skKN.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-femCtfpo.js → browser-workflow-inputs-CimCGbhq.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-o0GVE_aF.js → browser-workflows-page-DewuCw3p.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-BHaYYo9E.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-Bx-JJC0R.js → capability-presets-api-B5RTs-Az.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BgchTh81.js +1 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-CTw3ibx4.js → channel-recipient-api-Czu0YzIZ.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-BP0e62wt.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-DBWKfeGe.js +1 -0
  25. package/dist/gateway/static/root/assets/connector-logo-Di3gnR_D.js +1 -0
  26. package/dist/gateway/static/root/assets/connectors-page-CC5kh0de.js +2 -0
  27. package/dist/gateway/static/root/assets/desktop-pet-D-ZUNHhn.js +1 -0
  28. package/dist/gateway/static/root/assets/{desktop-pet-settings-CIeH4VyP.js → desktop-pet-settings-C3L6AI8_.js} +1 -1
  29. package/dist/gateway/static/root/assets/{directory-picker-path-field-Ddgt6c3K.js → directory-picker-path-field-Dvq4iG6P.js} +1 -1
  30. package/dist/gateway/static/root/assets/dreaming-settings-D9i54kWO.js +3 -0
  31. package/dist/gateway/static/root/assets/{extension-debug-page-CJGwUaQX.js → extension-debug-page-BecQjU0J.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-page-B3zHKJAB.js → extension-page-BeVkPSm-.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-settings-page-Cj9rrSr1.js → extension-settings-page-DMoo2mKx.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-api-BdmtlJRP.js → gateway-config-api-Bthb3_6v.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-C2RwKIsl.js → gateway-settings-Bh8nPvJQ.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-startup-retry-mcMq_uu_.js → gateway-startup-retry-D3USVm9D.js} +1 -1
  37. package/dist/gateway/static/root/assets/{goal-create-dialog-5Ryd_rx4.js → goal-create-dialog-Dp0AyDHI.js} +1 -1
  38. package/dist/gateway/static/root/assets/goal-detail-page-CNt7nrdS.js +4 -0
  39. package/dist/gateway/static/root/assets/{goals-config-api-CAO1J4jn.js → goals-config-api-C_2QWBtb.js} +1 -1
  40. package/dist/gateway/static/root/assets/goals-page-Bm_NZFiZ.js +2 -0
  41. package/dist/gateway/static/root/assets/{goals-settings-Boj2izKZ.js → goals-settings-DhL643tc.js} +1 -1
  42. package/dist/gateway/static/root/assets/{heartbeat-settings-DbPC9a_y.js → heartbeat-settings-COVFwp7C.js} +1 -1
  43. package/dist/gateway/static/root/assets/{image-generation-api-DrLCLTXn.js → image-generation-api-BNQlnwpU.js} +1 -1
  44. package/dist/gateway/static/root/assets/index-C_XSKOH6.css +1 -0
  45. package/dist/gateway/static/root/assets/{index-vHb2z7VS.js → index-DUasAutC.js} +67 -67
  46. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BrxfptgY.js → keyboard-shortcuts-settings-DfdJRJVy.js} +1 -1
  47. package/dist/gateway/static/root/assets/{local-app-workbench-page-BP0_Ih0e.js → local-app-workbench-page-DZwkD1co.js} +2 -2
  48. package/dist/gateway/static/root/assets/{local-apps-page-DNCRlfFs.js → local-apps-page-BvCPOgoi.js} +1 -1
  49. package/dist/gateway/static/root/assets/{locale-store-CzIfXqm8.js → locale-store-BP0vD37A.js} +1 -1
  50. package/dist/gateway/static/root/assets/logs-page-dNL0Y1dA.js +7 -0
  51. package/dist/gateway/static/root/assets/{markdown-split-CIUH9Lor.js → markdown-split-YO1rDk9m.js} +1 -1
  52. package/dist/gateway/static/root/assets/{media-plugins-DX4AgkCs.js → media-plugins-CU_RRf-q.js} +1 -1
  53. package/dist/gateway/static/root/assets/{messages-CKZuaOeG.js → messages-BWtP5TFz.js} +2 -2
  54. package/dist/gateway/static/root/assets/{notes-page-D1KprtxL.js → notes-page-CeFiOK3S.js} +1 -1
  55. package/dist/gateway/static/root/assets/notes-workbench-B8MKxpZb.js +4 -0
  56. package/dist/gateway/static/root/assets/{page-tabs-DjZPJGf6.js → page-tabs-tiHmRJUA.js} +1 -1
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-DNiJTpwZ.js → preview-open-alternatives-CU6XgaCz.js} +1 -1
  58. package/dist/gateway/static/root/assets/{product-open-page-CNfR17-g.js → product-open-page-Dn4_qor4.js} +1 -1
  59. package/dist/gateway/static/root/assets/project-detail-page-CWBuuX-S.js +1 -0
  60. package/dist/gateway/static/root/assets/projects-page-BJSsLsXH.js +1 -0
  61. package/dist/gateway/static/root/assets/remote-access-hub-DXJDb8vB.js +1 -0
  62. package/dist/gateway/static/root/assets/{save-bar-controls-BGZFVO9S.js → save-bar-controls-edDUIbXo.js} +1 -1
  63. package/dist/gateway/static/root/assets/{schedule-field-BAZiHtds.js → schedule-field-DqJO_5Yb.js} +1 -1
  64. package/dist/gateway/static/root/assets/{schema-form-CesBcwJH.js → schema-form-CMh0jzy5.js} +1 -1
  65. package/dist/gateway/static/root/assets/sessions-page-DeHpWgxM.js +1 -0
  66. package/dist/gateway/static/root/assets/settings-advanced-gate-Cf-TEYUd.js +1 -0
  67. package/dist/gateway/static/root/assets/{settings-form-section-Bxc54BLj.js → settings-form-section-Bb0Bc3nJ.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-loading-skeleton-CYrho7Db.js → settings-loading-skeleton-DQhADvz1.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-page-C03X5fkh.js → settings-page-b0M5HukN.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-layout-CZAJbv4E.js → settings-page-layout-hvjtIjvh.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-Jv8_bcOD.js → setup-status-panel-BFyfed_g.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-DSC7tKKG.js → share-preview-page-rbeaOpTg.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-CYnH9sTt.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-Cr8_m-jS.js +1 -0
  75. package/dist/gateway/static/root/assets/skills-page-Chtc1xDO.js +2 -0
  76. package/dist/gateway/static/root/assets/{system-settings-panel-BO89zw5H.js → system-settings-panel-BHo_hgnL.js} +1 -1
  77. package/dist/gateway/static/root/assets/{theme-store-1OkdVC8l.js → theme-store-C3KnnjcU.js} +1 -1
  78. package/dist/gateway/static/root/assets/time-picker-D-G-uwVJ.js +1 -0
  79. package/dist/gateway/static/root/assets/{typed-models-lib-D-_vct_y.js → typed-models-lib-DtRnG-YI.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-channel-catalog-VlFtjlET.js → use-channel-catalog-CWWItX2g.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-context-page-D7qMR26X.js +1 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-BhDk-UV_.js → voice-api-key-field-BTnltQHZ.js} +1 -1
  83. package/dist/gateway/static/root/assets/work-discovery-page-CpqFZze9.js +1 -0
  84. package/dist/gateway/static/root/assets/work-item-detail-page-t4dXpGC0.js +1 -0
  85. package/dist/gateway/static/root/assets/work-page-BXwDKiMZ.js +1 -0
  86. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-uVw4Yoej.js → workflow-run-setup-panel-D7vKChFZ.js} +2 -2
  87. package/dist/gateway/static/root/assets/workflows-page-Bos9HyqT.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/memory/builtin-provider.js +4 -4
  91. package/dist/src/agent/memory/manager.d.ts +4 -1
  92. package/dist/src/agent/memory/manager.js +8 -3
  93. package/dist/src/agent/memory/understanding/service.d.ts +2 -0
  94. package/dist/src/agent/memory/understanding/service.js +11 -9
  95. package/dist/src/agent/service.d.ts +1 -0
  96. package/dist/src/agent/service.js +3 -0
  97. package/dist/src/automations/domain/validation.d.ts +8 -8
  98. package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -1
  99. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  100. package/dist/src/connectors/composio-sessions.d.ts +1 -0
  101. package/dist/src/connectors/composio-sessions.js +14 -5
  102. package/dist/src/connectors/composio-triggers.d.ts +1 -1
  103. package/dist/src/connectors/composio-triggers.js +4 -3
  104. package/dist/src/connectors/composio.js +1 -0
  105. package/dist/src/connectors/{connector-memory-sync.d.ts → connected-source-ingestion.d.ts} +11 -4
  106. package/dist/src/connectors/{connector-memory-sync.js → connected-source-ingestion.js} +49 -101
  107. package/dist/src/connectors/connected-source-normalizers.d.ts +15 -0
  108. package/dist/src/connectors/connected-source-normalizers.js +186 -0
  109. package/dist/src/connectors/connector-identity.d.ts +2 -0
  110. package/dist/src/connectors/connector-identity.js +29 -0
  111. package/dist/src/connectors/learning-coordinator.d.ts +25 -0
  112. package/dist/src/connectors/learning-coordinator.js +214 -0
  113. package/dist/src/connectors/learning-recipes.d.ts +22 -0
  114. package/dist/src/connectors/learning-recipes.js +121 -0
  115. package/dist/src/connectors/runtime-status.d.ts +1 -8
  116. package/dist/src/connectors/runtime-status.js +4 -29
  117. package/dist/src/gateway/hono/routes/connectors.js +76 -118
  118. package/dist/src/gateway/hono/routes/models.js +24 -0
  119. package/dist/src/gateway/hono/routes/public-gateway.js +3 -2
  120. package/dist/src/gateway/hono/routes/you.js +86 -5
  121. package/dist/src/gateway/service.d.ts +5 -2
  122. package/dist/src/gateway/service.js +16 -11
  123. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +19 -0
  124. package/dist/src/knowledge/connected-understanding-pipeline.js +268 -0
  125. package/dist/src/knowledge/index.d.ts +1 -0
  126. package/dist/src/knowledge/index.js +2 -1
  127. package/dist/src/knowledge/ingestion-service.d.ts +6 -4
  128. package/dist/src/knowledge/ingestion-service.js +13 -10
  129. package/dist/src/knowledge/local-folder-adapter.js +1 -0
  130. package/dist/src/knowledge/people-graph.js +43 -110
  131. package/dist/src/knowledge/types.d.ts +3 -0
  132. package/dist/src/providers/xopc-cloud-account-service.d.ts +40 -0
  133. package/dist/src/providers/xopc-cloud-account-service.js +65 -0
  134. package/dist/src/storage/sqlite/connector-learning-repository.d.ts +47 -0
  135. package/dist/src/storage/sqlite/connector-learning-repository.js +110 -0
  136. package/dist/src/storage/sqlite/index.d.ts +3 -1
  137. package/dist/src/storage/sqlite/index.js +4 -2
  138. package/dist/src/storage/sqlite/knowledge-repository.d.ts +4 -2
  139. package/dist/src/storage/sqlite/knowledge-repository.js +24 -13
  140. package/dist/src/storage/sqlite/migrations/062_connector_learning_jobs.sql +27 -0
  141. package/dist/src/storage/sqlite/migrations/063_knowledge_collection_scopes.sql +14 -0
  142. package/dist/src/storage/sqlite/migrations/064_user_claims.sql +60 -0
  143. package/dist/src/storage/sqlite/migrations/065_knowledge_item_scope_identity.sql +116 -0
  144. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  145. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  146. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  147. package/dist/src/storage/sqlite/schema.js +1 -1
  148. package/dist/src/storage/sqlite/user-claims-repository.d.ts +101 -0
  149. package/dist/src/storage/sqlite/user-claims-repository.js +241 -0
  150. package/dist/src/user-context/projection.d.ts +36 -1
  151. package/dist/src/user-context/projection.js +84 -6
  152. package/dist/src/work-discovery/service.js +1 -0
  153. package/package.json +1 -1
  154. package/dist/gateway/static/root/assets/agents-ZCIC8mhO.js +0 -2
  155. package/dist/gateway/static/root/assets/apps-page-DJmgBaAm.js +0 -1
  156. package/dist/gateway/static/root/assets/automations-page-Ddot8-Md.js +0 -6
  157. package/dist/gateway/static/root/assets/block-editor-D3GIllO3.js +0 -184
  158. package/dist/gateway/static/root/assets/browser-settings-page-DvETvRcg.js +0 -8
  159. package/dist/gateway/static/root/assets/capabilities-settings-panel-ChXIYbys.js +0 -7
  160. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CUekXsJy.js +0 -1
  161. package/dist/gateway/static/root/assets/channels-settings-CkhveNsQ.js +0 -1
  162. package/dist/gateway/static/root/assets/channels-status-swr-DRTb8DBk.js +0 -1
  163. package/dist/gateway/static/root/assets/connector-logo-CQznQcd4.js +0 -1
  164. package/dist/gateway/static/root/assets/connectors-page-DkSGIxWP.js +0 -2
  165. package/dist/gateway/static/root/assets/desktop-pet-BtP-xUQ9.js +0 -1
  166. package/dist/gateway/static/root/assets/dreaming-settings-gd9W6SLj.js +0 -3
  167. package/dist/gateway/static/root/assets/goal-detail-page-DizZ6Cpl.js +0 -4
  168. package/dist/gateway/static/root/assets/goals-page-Dqry_hi2.js +0 -2
  169. package/dist/gateway/static/root/assets/index-DEdyUjxM.css +0 -1
  170. package/dist/gateway/static/root/assets/logs-page-mT48mcF4.js +0 -7
  171. package/dist/gateway/static/root/assets/notes-workbench-wgt2Osyk.js +0 -4
  172. package/dist/gateway/static/root/assets/project-detail-page-CDjHvxJm.js +0 -1
  173. package/dist/gateway/static/root/assets/projects-page-kJZwQXfC.js +0 -1
  174. package/dist/gateway/static/root/assets/remote-access-hub-MJdI9ek_.js +0 -1
  175. package/dist/gateway/static/root/assets/sessions-page-BqC7GDC_.js +0 -1
  176. package/dist/gateway/static/root/assets/settings-advanced-gate-CYwz8MfF.js +0 -1
  177. package/dist/gateway/static/root/assets/shares-settings-h8tGDkA3.js +0 -1
  178. package/dist/gateway/static/root/assets/skill-reload-api-D2DGvRUn.js +0 -1
  179. package/dist/gateway/static/root/assets/skills-page-vqhjSMhZ.js +0 -2
  180. package/dist/gateway/static/root/assets/time-picker-mtD64kFB.js +0 -1
  181. package/dist/gateway/static/root/assets/user-context-page-BgF0WxjM.js +0 -1
  182. package/dist/gateway/static/root/assets/work-discovery-page-CP0Daig-.js +0 -1
  183. package/dist/gateway/static/root/assets/work-item-detail-page-NEWZPKB_.js +0 -1
  184. package/dist/gateway/static/root/assets/work-page-BkWntcQh.js +0 -1
  185. package/dist/gateway/static/root/assets/workflows-page-DRvhNQGe.js +0 -11
  186. package/dist/src/connectors/memory-sync-coordinator.d.ts +0 -28
  187. package/dist/src/connectors/memory-sync-coordinator.js +0 -162
  188. package/dist/src/connectors/memory-sync-profile.d.ts +0 -13
  189. package/dist/src/connectors/memory-sync-profile.js +0 -73
@@ -0,0 +1,214 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ import { claimNextConnectorLearningJob, enqueueConnectorLearningJob, listConnectorLearningJobs, recoverStaleConnectorLearningJobs, setConnectorLearningPaused, updateConnectorLearningJob } from "../storage/sqlite/connector-learning-repository.js";
4
+ import { pruneBoundedKnowledgeSourceItems } from "../storage/sqlite/knowledge-repository.js";
5
+ import { getConnectorInstallation, listConnectorConnections, upsertConnectorConnection } from "../storage/sqlite/connector-repository.js";
6
+ import "../storage/sqlite/index.js";
7
+ import { ComposioSessionsAdapter } from "./composio-sessions.js";
8
+ import { getConnectorDefinition } from "./catalog.js";
9
+ import { ConnectedUnderstandingPipeline } from "../knowledge/connected-understanding-pipeline.js";
10
+ import "../knowledge/index.js";
11
+ import { ingestComposioConnectedSource } from "./connected-source-ingestion.js";
12
+ import { normalizeConnectorIdentity } from "./connector-identity.js";
13
+ import { buildConnectorLearningArguments, getConnectorLearningPlan } from "./learning-recipes.js";
14
+ //#region src/connectors/learning-coordinator.ts
15
+ init_logger();
16
+ const log = createLogger("ConnectorLearning");
17
+ const CONNECTED_ACCOUNT_UNAVAILABLE = "connected_account_unavailable";
18
+ const CONNECTED_SOURCE_SYNC_FAILED = "connected_source_sync_failed";
19
+ function learningFailureCode(error) {
20
+ const message = error instanceof Error ? error.message : String(error);
21
+ return message.includes("ToolRouterV2_InvalidConnectedAccountIds") || message.includes("Could not find connected account(s)") || message.includes("missing its provider identity") ? CONNECTED_ACCOUNT_UNAVAILABLE : CONNECTED_SOURCE_SYNC_FAILED;
22
+ }
23
+ function learningEnabled(config) {
24
+ return config.userContext.enabled && config.userContext.understanding.enabled && config.userContext.memory.mode !== "off" && config.userContext.memory.sources.includes("connectedSources");
25
+ }
26
+ function startConnectorLearningCoordinator(options) {
27
+ const intervalMs = Math.max(2e3, Math.min(options.intervalMs ?? 1e4, 6e4));
28
+ let timer = null;
29
+ let running = false;
30
+ let stopped = false;
31
+ const composioAdapter = options.composioAdapter ?? new ComposioSessionsAdapter();
32
+ const publish = (job) => options.emit?.("connector.learning.updated", job);
33
+ function enqueueConnection(connectionId, request = {}) {
34
+ if (!learningEnabled(options.getConfig())) return null;
35
+ const connection = listConnectorConnections().find((item) => item.id === connectionId && item.status === "active");
36
+ if (!connection) return null;
37
+ const definition = getConnectorDefinition(connection.connectorId);
38
+ if (definition?.runtime.type !== "composio" || definition.runtime.role !== "toolkit") return null;
39
+ if (!getConnectorLearningPlan(definition.runtime.toolkit)) return null;
40
+ const sourceInstanceId = `composio:${connection.connectorId}:${connection.id}`;
41
+ const existing = listConnectorLearningJobs({
42
+ connectionId: connection.id,
43
+ limit: 1
44
+ });
45
+ const mode = request.mode ?? (existing.length === 0 ? "bootstrap" : "incremental");
46
+ const bucket = Math.floor(Date.now() / 6e4);
47
+ const job = enqueueConnectorLearningJob({
48
+ connectorId: connection.connectorId,
49
+ connectionId: connection.id,
50
+ sourceInstanceId,
51
+ agentId: options.resolveAgentId(),
52
+ mode,
53
+ idempotencyKey: request.idempotencyKey ?? (mode === "bootstrap" ? `bootstrap:${connection.id}:v1` : `incremental:${connection.id}:${request.reason ?? "manual"}:${bucket}`),
54
+ nextRunAt: request.nextRunAt
55
+ });
56
+ publish(job);
57
+ queueMicrotask(() => void runNow());
58
+ return job;
59
+ }
60
+ function enqueueToolkit(toolkit) {
61
+ const normalized = toolkit.trim().toLowerCase();
62
+ return listConnectorConnections().filter((connection) => connection.status === "active").filter((connection) => {
63
+ const definition = getConnectorDefinition(connection.connectorId);
64
+ return definition?.runtime.type === "composio" && definition.runtime.role === "toolkit" && definition.runtime.toolkit === normalized;
65
+ }).map((connection) => enqueueConnection(connection.id, { reason: "event" })).filter((job) => Boolean(job));
66
+ }
67
+ async function execute(job) {
68
+ publish(job);
69
+ const definition = getConnectorDefinition(job.connectorId);
70
+ if (definition?.runtime.type !== "composio" || definition.runtime.role !== "toolkit") throw new Error(`Connector learning is unavailable for ${job.connectorId}.`);
71
+ const plan = getConnectorLearningPlan(definition.runtime.toolkit);
72
+ if (!plan) throw new Error(`Connector learning has no plan for ${definition.runtime.toolkit}.`);
73
+ let connection = listConnectorConnections().find((candidate) => candidate.id === job.connectionId);
74
+ if (!connection) throw new Error("Connector account no longer exists.");
75
+ const installation = getConnectorInstallation(`${job.connectorId}-local-owner`);
76
+ if (!installation?.enabled) throw new Error("Connector installation is not enabled.");
77
+ const hasIdentity = Object.values(connection.identity).some((value) => typeof value === "string" && value.trim());
78
+ if (plan.identityProbe && (job.mode === "bootstrap" || !hasIdentity)) {
79
+ const execution = await composioAdapter.executeWithPolicy({
80
+ context: {
81
+ principalId: connection.principalId,
82
+ toolkits: [plan.toolkit]
83
+ },
84
+ installation: {
85
+ ...installation,
86
+ maxScope: "read",
87
+ confirmationPolicy: "never"
88
+ },
89
+ connection,
90
+ agentId: job.agentId,
91
+ action: {
92
+ connectorId: job.connectorId,
93
+ actionId: plan.identityProbe.actionId,
94
+ toolkit: plan.toolkit,
95
+ scope: "read",
96
+ curated: true,
97
+ cachedAt: (/* @__PURE__ */ new Date()).toISOString()
98
+ },
99
+ args: {},
100
+ confirmed: true
101
+ });
102
+ if (execution.decision !== "allowed") throw new Error(execution.reason);
103
+ connection = upsertConnectorConnection({
104
+ ...connection,
105
+ identity: normalizeConnectorIdentity(plan.toolkit, execution.result)
106
+ });
107
+ }
108
+ let itemsSeen = 0;
109
+ let itemsIndexed = 0;
110
+ for (const stream of plan.streams) {
111
+ const synced = await ingestComposioConnectedSource({
112
+ config: options.getConfig(),
113
+ connectorId: job.connectorId,
114
+ connectionId: job.connectionId,
115
+ collectionScope: stream.scope,
116
+ streamKind: stream.kind,
117
+ actionId: stream.actionId,
118
+ arguments: stream.arguments,
119
+ buildArguments: (pull) => buildConnectorLearningArguments(plan, stream, pull, connection.identity),
120
+ agentId: job.agentId
121
+ });
122
+ itemsSeen += synced.itemsSeen;
123
+ itemsIndexed += synced.itemsIndexed;
124
+ }
125
+ if (listConnectorLearningJobs({
126
+ connectionId: job.connectionId,
127
+ limit: 100
128
+ }).find((candidate) => candidate.id === job.id)?.status === "paused") return;
129
+ publish(updateConnectorLearningJob(job.id, {
130
+ phase: "indexing",
131
+ itemsDiscovered: itemsSeen,
132
+ itemsIndexed
133
+ }));
134
+ publish(updateConnectorLearningJob(job.id, { phase: "deriving" }));
135
+ const understanding = await new ConnectedUnderstandingPipeline(options.getMemoryManager()).process(job.sourceInstanceId, job.connectorId, job.agentId);
136
+ publish(updateConnectorLearningJob(job.id, {
137
+ status: "completed",
138
+ phase: "completed",
139
+ candidatesCreated: understanding.created,
140
+ nextRunAt: null,
141
+ finished: true
142
+ }));
143
+ pruneBoundedKnowledgeSourceItems(job.sourceInstanceId, Date.now() - plan.bootstrapWindowDays * 24 * 60 * 6e4);
144
+ const nextRunAt = Date.now() + plan.intervalMinutes * 6e4;
145
+ enqueueConnection(job.connectionId, {
146
+ mode: "incremental",
147
+ reason: "schedule",
148
+ nextRunAt,
149
+ idempotencyKey: `scheduled:${job.connectionId}:${nextRunAt}`
150
+ });
151
+ }
152
+ async function runNow() {
153
+ if (running || stopped) return;
154
+ running = true;
155
+ try {
156
+ for (let count = 0; count < 10; count += 1) {
157
+ const job = claimNextConnectorLearningJob();
158
+ if (!job) break;
159
+ try {
160
+ await execute(job);
161
+ } catch (err) {
162
+ const errorMessage = err instanceof Error ? err.message : String(err);
163
+ const exhausted = job.attemptCount >= 5;
164
+ publish(updateConnectorLearningJob(job.id, {
165
+ status: exhausted ? "paused" : "failed",
166
+ error: learningFailureCode(err),
167
+ nextRunAt: exhausted ? null : Date.now() + Math.min(30 * 6e4, 3e4 * 2 ** Math.min(job.attemptCount, 6)),
168
+ finished: true
169
+ }));
170
+ log.warn({
171
+ err,
172
+ jobId: job.id,
173
+ connectorId: job.connectorId
174
+ }, `Connector learning failed: ${errorMessage}`);
175
+ }
176
+ }
177
+ } finally {
178
+ running = false;
179
+ }
180
+ }
181
+ recoverStaleConnectorLearningJobs(Date.now());
182
+ if (learningEnabled(options.getConfig())) {
183
+ for (const connection of listConnectorConnections().filter((item) => item.status === "active")) if (listConnectorLearningJobs({
184
+ connectionId: connection.id,
185
+ limit: 1
186
+ }).length === 0) enqueueConnection(connection.id, { reason: "schedule" });
187
+ }
188
+ timer = setTimeout(() => {
189
+ runNow();
190
+ timer = setInterval(() => void runNow(), intervalMs);
191
+ timer.unref?.();
192
+ }, Math.max(0, options.initialDelayMs ?? 2e3));
193
+ timer.unref?.();
194
+ return {
195
+ enqueueConnection,
196
+ enqueueToolkit,
197
+ setPaused(connectionId, paused) {
198
+ const changed = setConnectorLearningPaused(connectionId, paused);
199
+ if (!paused && changed > 0) queueMicrotask(() => void runNow());
200
+ return changed;
201
+ },
202
+ runNow,
203
+ stop() {
204
+ stopped = true;
205
+ if (timer) {
206
+ clearTimeout(timer);
207
+ clearInterval(timer);
208
+ timer = null;
209
+ }
210
+ }
211
+ };
212
+ }
213
+ //#endregion
214
+ export { startConnectorLearningCoordinator };
@@ -0,0 +1,22 @@
1
+ export type ConnectorIdentityProbe = {
2
+ actionId: string;
3
+ };
4
+ export type ConnectorLearningStream = {
5
+ scope: string;
6
+ actionId: string;
7
+ arguments: Record<string, unknown>;
8
+ kind: 'activity' | 'inventory';
9
+ };
10
+ export type ConnectorLearningPlan = {
11
+ toolkit: string;
12
+ identityProbe?: ConnectorIdentityProbe;
13
+ streams: ConnectorLearningStream[];
14
+ bootstrapWindowDays: number;
15
+ intervalMinutes: number;
16
+ };
17
+ export declare function buildConnectorLearningArguments(plan: ConnectorLearningPlan, stream: ConnectorLearningStream, input: {
18
+ cursor?: string;
19
+ windowStart?: string;
20
+ }, identity: Record<string, unknown>): Record<string, unknown>;
21
+ export declare function getConnectorLearningPlan(toolkit: string): ConnectorLearningPlan | undefined;
22
+ export declare function listConnectorLearningPlans(): ConnectorLearningPlan[];
@@ -0,0 +1,121 @@
1
+ //#region src/connectors/learning-recipes.ts
2
+ function buildConnectorLearningArguments(plan, stream, input, identity) {
3
+ if (plan.toolkit === "github" && stream.scope === "authored-work") {
4
+ const username = typeof identity.username === "string" ? identity.username.trim() : "";
5
+ if (!username) throw new Error("GitHub activity sync requires the authenticated username.");
6
+ return {
7
+ ...stream.arguments,
8
+ q: `author:${username} sort:updated-desc`
9
+ };
10
+ }
11
+ if (!input.cursor) return { ...stream.arguments };
12
+ if (plan.toolkit === "gmail") {
13
+ const after = Math.floor(Date.parse(input.cursor) / 1e3);
14
+ return Number.isFinite(after) ? {
15
+ ...stream.arguments,
16
+ query: `after:${after} -in:spam -in:trash`
17
+ } : { ...stream.arguments };
18
+ }
19
+ if (plan.toolkit === "googlecalendar") return {
20
+ ...stream.arguments,
21
+ time_min: input.cursor
22
+ };
23
+ return { ...stream.arguments };
24
+ }
25
+ const PLANS = {
26
+ gmail: {
27
+ toolkit: "gmail",
28
+ identityProbe: { actionId: "GMAIL_GET_PROFILE" },
29
+ streams: [{
30
+ scope: "messages",
31
+ actionId: "GMAIL_FETCH_EMAILS",
32
+ kind: "activity",
33
+ arguments: {
34
+ max_results: 100,
35
+ query: "newer_than:30d -in:spam -in:trash"
36
+ }
37
+ }],
38
+ bootstrapWindowDays: 30,
39
+ intervalMinutes: 15
40
+ },
41
+ googlecalendar: {
42
+ toolkit: "googlecalendar",
43
+ streams: [{
44
+ scope: "events",
45
+ actionId: "GOOGLECALENDAR_LIST_EVENTS",
46
+ kind: "activity",
47
+ arguments: { max_results: 200 }
48
+ }],
49
+ bootstrapWindowDays: 90,
50
+ intervalMinutes: 15
51
+ },
52
+ googledrive: {
53
+ toolkit: "googledrive",
54
+ streams: [{
55
+ scope: "files",
56
+ actionId: "GOOGLEDRIVE_SEARCH_FILES",
57
+ kind: "inventory",
58
+ arguments: {}
59
+ }],
60
+ bootstrapWindowDays: 90,
61
+ intervalMinutes: 30
62
+ },
63
+ notion: {
64
+ toolkit: "notion",
65
+ streams: [{
66
+ scope: "pages",
67
+ actionId: "NOTION_SEARCH",
68
+ kind: "inventory",
69
+ arguments: {}
70
+ }],
71
+ bootstrapWindowDays: 90,
72
+ intervalMinutes: 30
73
+ },
74
+ slack: {
75
+ toolkit: "slack",
76
+ streams: [{
77
+ scope: "channels",
78
+ actionId: "SLACK_LIST_CHANNELS",
79
+ kind: "inventory",
80
+ arguments: {}
81
+ }],
82
+ bootstrapWindowDays: 30,
83
+ intervalMinutes: 15
84
+ },
85
+ github: {
86
+ toolkit: "github",
87
+ identityProbe: { actionId: "GITHUB_GET_THE_AUTHENTICATED_USER" },
88
+ streams: [{
89
+ scope: "repositories",
90
+ actionId: "GITHUB_LIST_REPOSITORIES_FOR_THE_AUTHENTICATED_USER",
91
+ kind: "inventory",
92
+ arguments: {}
93
+ }, {
94
+ scope: "authored-work",
95
+ actionId: "GITHUB_SEARCH_ISSUES_AND_PULL_REQUESTS",
96
+ kind: "activity",
97
+ arguments: { per_page: 100 }
98
+ }],
99
+ bootstrapWindowDays: 90,
100
+ intervalMinutes: 30
101
+ },
102
+ linear: {
103
+ toolkit: "linear",
104
+ streams: [{
105
+ scope: "issues",
106
+ actionId: "LINEAR_LIST_ISSUES",
107
+ kind: "activity",
108
+ arguments: {}
109
+ }],
110
+ bootstrapWindowDays: 60,
111
+ intervalMinutes: 15
112
+ }
113
+ };
114
+ function getConnectorLearningPlan(toolkit) {
115
+ return PLANS[toolkit.trim().toLowerCase()];
116
+ }
117
+ function listConnectorLearningPlans() {
118
+ return Object.values(PLANS);
119
+ }
120
+ //#endregion
121
+ export { buildConnectorLearningArguments, getConnectorLearningPlan, listConnectorLearningPlans };
@@ -1,9 +1,2 @@
1
1
  import type { ConnectorConnection, ConnectorInstance } from './types.js';
2
- export type ComposioRuntimeProbe = {
3
- connectorId: string;
4
- checkedAt: string;
5
- toolCount?: number;
6
- error?: string;
7
- connectionError?: boolean;
8
- };
9
- export declare function projectComposioRuntimeStatus(instances: ConnectorInstance[], connections: ConnectorConnection[], probes: ComposioRuntimeProbe[]): ConnectorInstance[];
2
+ export declare function projectComposioConnectionStatus(instances: ConnectorInstance[], connections: ConnectorConnection[]): ConnectorInstance[];
@@ -1,43 +1,18 @@
1
1
  //#region src/connectors/runtime-status.ts
2
- function projectComposioRuntimeStatus(instances, connections, probes) {
3
- const probeByConnectorId = new Map(probes.map((probe) => [probe.connectorId, probe]));
2
+ function projectComposioConnectionStatus(instances, connections) {
4
3
  return instances.map((instance) => {
5
4
  if (instance.materialized.type !== "composio" || instance.materialized.role !== "toolkit" || !instance.enabled) return instance;
6
5
  const relevant = connections.filter((connection) => connection.provider === "composio" && connection.connectorId === instance.connectorId && connection.status !== "revoked");
7
6
  const active = relevant.filter((connection) => connection.status === "active");
8
- const probe = probeByConnectorId.get(instance.connectorId);
9
7
  const lastConnectedAt = active.flatMap((connection) => connection.connectedAt ? [connection.connectedAt] : []).sort().at(-1) ?? instance.lastConnectedAt;
10
- if (active.length > 0 && probe && !probe.error && (probe.toolCount ?? 0) > 0) return {
8
+ if (active.length > 0) return {
11
9
  ...instance,
12
10
  status: "connected",
13
11
  connectionStatus: "connected",
14
12
  authStatus: "connected",
15
13
  lastConnectedAt,
16
- lastError: void 0,
17
- usage: {
18
- ...instance.usage,
19
- lastHealthCheckAt: probe.checkedAt,
20
- lastHealthStatus: "ok",
21
- lastToolCount: probe.toolCount
22
- }
14
+ lastError: void 0
23
15
  };
24
- if (active.length > 0 && probe) {
25
- const error = probe.error ?? "The connection did not expose any usable tools.";
26
- return {
27
- ...instance,
28
- status: "degraded",
29
- connectionStatus: probe.connectionError ? "error" : "connected",
30
- authStatus: "connected",
31
- lastConnectedAt,
32
- lastError: error,
33
- usage: {
34
- ...instance.usage,
35
- lastHealthCheckAt: probe.checkedAt,
36
- lastHealthStatus: probe.connectionError ? "network_failed" : "tools_list_failed",
37
- lastToolCount: probe.toolCount ?? 0
38
- }
39
- };
40
- }
41
16
  if (relevant.some((connection) => connection.status === "pending")) return {
42
17
  ...instance,
43
18
  status: "connecting",
@@ -65,4 +40,4 @@ function projectComposioRuntimeStatus(instances, connections, probes) {
65
40
  });
66
41
  }
67
42
  //#endregion
68
- export { projectComposioRuntimeStatus };
43
+ export { projectComposioConnectionStatus };
@@ -1,3 +1,4 @@
1
+ import { listConnectorLearningJobs } from "../../../storage/sqlite/connector-learning-repository.js";
1
2
  import { decideConnectorApproval, getConnectorApproval, listConnectorApprovals, listConnectorConnections } from "../../../storage/sqlite/connector-repository.js";
2
3
  import "../../../storage/sqlite/index.js";
3
4
  import { init_agent_scope, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
@@ -15,11 +16,10 @@ import { composioLogoResponse } from "../../../connectors/composio-logo.js";
15
16
  import { appendComposioTriggerEvent, listComposioTriggerEvents } from "../../../connectors/composio-triggers.js";
16
17
  import { buildConnectedPeopleGraph } from "../../../knowledge/people-graph.js";
17
18
  import "../../../knowledge/index.js";
18
- import { syncComposioResultToMemory, syncLocalFolderToMemory } from "../../../connectors/connector-memory-sync.js";
19
+ import { ingestLocalFolderSource } from "../../../connectors/connected-source-ingestion.js";
19
20
  import { previewConnectorDefinition, testConnectorInstance } from "../../../connectors/health.js";
20
21
  import { setConnectorEnabled } from "../../../connectors/lifecycle.js";
21
- import { getComposioMemorySyncProfile, updateComposioMemorySyncProfile } from "../../../connectors/memory-sync-profile.js";
22
- import { projectComposioRuntimeStatus } from "../../../connectors/runtime-status.js";
22
+ import { projectComposioConnectionStatus } from "../../../connectors/runtime-status.js";
23
23
  //#region src/gateway/hono/routes/connectors.ts
24
24
  init_agent_scope();
25
25
  function errorMessage(error) {
@@ -39,45 +39,13 @@ function registerConnectorRoutes(authenticated, deps) {
39
39
  }
40
40
  });
41
41
  });
42
- authenticated.get("/api/connectors/installed", async (c) => {
42
+ authenticated.get("/api/connectors/installed", (c) => {
43
43
  const config = service.currentConfig;
44
44
  const instances = listConnectorInstances(config);
45
- const composioInstances = instances.filter((instance) => instance.materialized.type === "composio" && instance.materialized.role === "toolkit");
46
- if (composioInstances.length === 0) return c.json({
47
- ok: true,
48
- payload: { instances }
49
- });
50
- const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
51
- let connectionError;
52
- try {
53
- await listComposioConnections();
54
- } catch (error) {
55
- connectionError = errorMessage(error);
56
- }
57
- const probes = await Promise.all([...new Map(composioInstances.map((instance) => [instance.connectorId, instance])).values()].map(async (instance) => {
58
- try {
59
- const tools = await listComposioTools(instance.materialized.type === "composio" ? instance.materialized.toolkit : "", config);
60
- return {
61
- connectorId: instance.connectorId,
62
- checkedAt,
63
- toolCount: tools.length,
64
- ...connectionError ? {
65
- error: connectionError,
66
- connectionError: true
67
- } : {}
68
- };
69
- } catch (error) {
70
- return {
71
- connectorId: instance.connectorId,
72
- checkedAt,
73
- error: errorMessage(error)
74
- };
75
- }
76
- }));
77
45
  const connections = listConnectorConnections({ principalId: "local-owner" });
78
46
  return c.json({
79
47
  ok: true,
80
- payload: { instances: projectComposioRuntimeStatus(instances, connections, probes) }
48
+ payload: { instances: projectComposioConnectionStatus(instances, connections) }
81
49
  });
82
50
  });
83
51
  authenticated.post("/api/connectors/setup/request-secret", strictRateLimitMiddleware, async (c) => {
@@ -118,6 +86,54 @@ function registerConnectorRoutes(authenticated, deps) {
118
86
  }, 400);
119
87
  }
120
88
  });
89
+ authenticated.get("/api/connectors/learning", (c) => {
90
+ return c.json({
91
+ ok: true,
92
+ payload: { jobs: listConnectorLearningJobs({ limit: 100 }) }
93
+ });
94
+ });
95
+ authenticated.post("/api/connectors/composio/connections/:id/learning", strictRateLimitMiddleware, async (c) => {
96
+ try {
97
+ await listComposioConnections();
98
+ const config = service.currentConfig;
99
+ if (!config.userContext.memory.sources.includes("connectedSources")) {
100
+ config.userContext.memory.sources = [...config.userContext.memory.sources, "connectedSources"];
101
+ const saved = await service.saveConfig(config);
102
+ if (!saved.saved) return c.json({
103
+ ok: false,
104
+ error: saved.error
105
+ }, 500);
106
+ }
107
+ const job = service.requestConnectorLearning(c.req.param("id"), { reason: "manual" });
108
+ if (!job) return c.json({
109
+ ok: false,
110
+ error: "The connection is not active or does not support learning."
111
+ }, 409);
112
+ return c.json({
113
+ ok: true,
114
+ payload: { job }
115
+ }, 202);
116
+ } catch (error) {
117
+ return c.json({
118
+ ok: false,
119
+ error: errorMessage(error)
120
+ }, 400);
121
+ }
122
+ });
123
+ authenticated.post("/api/connectors/composio/connections/:id/learning/pause", strictRateLimitMiddleware, (c) => {
124
+ const changed = service.setConnectorLearningPaused(c.req.param("id"), true);
125
+ return c.json({
126
+ ok: true,
127
+ payload: { changed }
128
+ });
129
+ });
130
+ authenticated.post("/api/connectors/composio/connections/:id/learning/resume", strictRateLimitMiddleware, (c) => {
131
+ const changed = service.setConnectorLearningPaused(c.req.param("id"), false);
132
+ return c.json({
133
+ ok: true,
134
+ payload: { changed }
135
+ });
136
+ });
121
137
  authenticated.patch("/api/connectors/composio/connections/:id", strictRateLimitMiddleware, async (c) => {
122
138
  const body = await c.req.json().catch(() => ({}));
123
139
  const row = body && typeof body === "object" && !Array.isArray(body) ? body : {};
@@ -153,7 +169,9 @@ function registerConnectorRoutes(authenticated, deps) {
153
169
  });
154
170
  authenticated.delete("/api/connectors/composio/connections/:id", strictRateLimitMiddleware, async (c) => {
155
171
  try {
156
- await revokeComposioConnection(c.req.param("id"));
172
+ const connectionId = c.req.param("id");
173
+ await revokeComposioConnection(connectionId);
174
+ service.setConnectorLearningPaused(connectionId, true);
157
175
  return c.json({
158
176
  ok: true,
159
177
  payload: { revoked: true }
@@ -275,7 +293,7 @@ function registerConnectorRoutes(authenticated, deps) {
275
293
  const body = await c.req.json().catch(() => ({}));
276
294
  try {
277
295
  const event = await appendComposioTriggerEvent(service.currentConfig, body);
278
- service.requestConnectorMemorySync(event.toolkit);
296
+ if (event.toolkit) service.requestConnectorLearningForToolkit(event.toolkit);
279
297
  return c.json({
280
298
  ok: true,
281
299
  payload: { event }
@@ -313,43 +331,6 @@ function registerConnectorRoutes(authenticated, deps) {
313
331
  })
314
332
  });
315
333
  });
316
- authenticated.get("/api/connectors/:id/memory-sync-profile", (c) => {
317
- const profile = getComposioMemorySyncProfile(service.currentConfig, c.req.param("id"));
318
- return c.json({
319
- ok: true,
320
- payload: { profile: profile ?? null }
321
- });
322
- });
323
- authenticated.patch("/api/connectors/:id/memory-sync-profile", strictRateLimitMiddleware, async (c) => {
324
- const body = await c.req.json().catch(() => ({}));
325
- const row = body && typeof body === "object" && !Array.isArray(body) ? body : {};
326
- try {
327
- const config = service.currentConfig;
328
- const profile = updateComposioMemorySyncProfile(config, c.req.param("id"), {
329
- enabled: row.enabled === true,
330
- actionId: typeof row.actionId === "string" ? row.actionId : "",
331
- arguments: row.arguments && typeof row.arguments === "object" && !Array.isArray(row.arguments) ? row.arguments : {},
332
- agentId: typeof row.agentId === "string" ? row.agentId : "",
333
- connectionId: typeof row.connectionId === "string" ? row.connectionId : void 0,
334
- intervalMinutes: Number(row.intervalMinutes),
335
- triggerSync: row.triggerSync !== false
336
- });
337
- const saved = await service.saveConfig(config);
338
- if (!saved.saved) return c.json({
339
- ok: false,
340
- error: saved.error
341
- }, 500);
342
- return c.json({
343
- ok: true,
344
- payload: { profile }
345
- });
346
- } catch (error) {
347
- return c.json({
348
- ok: false,
349
- error: errorMessage(error)
350
- }, 400);
351
- }
352
- });
353
334
  authenticated.get("/api/connectors/:id", (c) => {
354
335
  const connectorId = c.req.param("id");
355
336
  const connector = getConnectorDefinition(connectorId);
@@ -395,48 +376,6 @@ function registerConnectorRoutes(authenticated, deps) {
395
376
  payload: { health }
396
377
  });
397
378
  });
398
- authenticated.post("/api/connectors/:id/memory-sync", strictRateLimitMiddleware, async (c) => {
399
- const body = await c.req.json().catch(() => ({}));
400
- const row = body && typeof body === "object" && !Array.isArray(body) ? body : {};
401
- const actionId = typeof row.actionId === "string" ? row.actionId.trim() : "";
402
- const config = service.currentConfig;
403
- const agentId = typeof row.agentId === "string" && row.agentId.trim() ? row.agentId.trim() : resolveDefaultAgentId(config);
404
- try {
405
- const connectorId = c.req.param("id");
406
- if (getConnectorDefinition(connectorId)?.runtime.type === "memorySource") {
407
- const result = await syncLocalFolderToMemory({
408
- config,
409
- connectorId,
410
- agentId
411
- });
412
- return c.json({
413
- ok: true,
414
- payload: result
415
- });
416
- }
417
- if (!actionId) return c.json({
418
- ok: false,
419
- error: "actionId is required for Composio memory sync."
420
- }, 400);
421
- const result = await syncComposioResultToMemory({
422
- config,
423
- connectorId,
424
- actionId,
425
- agentId,
426
- connectionId: typeof row.connectionId === "string" ? row.connectionId : void 0,
427
- arguments: row.arguments && typeof row.arguments === "object" && !Array.isArray(row.arguments) ? row.arguments : {}
428
- });
429
- return c.json({
430
- ok: true,
431
- payload: result
432
- });
433
- } catch (error) {
434
- return c.json({
435
- ok: false,
436
- error: errorMessage(error)
437
- }, 400);
438
- }
439
- });
440
379
  authenticated.get("/api/connectors/composio/:toolkit/policy", (c) => {
441
380
  const config = service.currentConfig;
442
381
  try {
@@ -632,6 +571,25 @@ function registerConnectorRoutes(authenticated, deps) {
632
571
  }, 500);
633
572
  }
634
573
  });
574
+ authenticated.post("/api/connectors/:id/source-sync", strictRateLimitMiddleware, async (c) => {
575
+ const config = service.currentConfig;
576
+ try {
577
+ const result = await ingestLocalFolderSource({
578
+ config,
579
+ connectorId: c.req.param("id"),
580
+ agentId: resolveDefaultAgentId(config)
581
+ });
582
+ return c.json({
583
+ ok: true,
584
+ payload: result
585
+ });
586
+ } catch (error) {
587
+ return c.json({
588
+ ok: false,
589
+ error: errorMessage(error)
590
+ }, 400);
591
+ }
592
+ });
635
593
  authenticated.post("/api/connectors/:id/config", strictRateLimitMiddleware, async (c) => {
636
594
  const instanceId = c.req.param("id");
637
595
  const body = await c.req.json().catch(() => ({}));