@xopcai/xopc 0.0.306 → 0.0.307

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 (216) 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-DLtim-_I.js → activity-store-wgSB2HYK.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-iQXtiilH.js → agent-avatar-dicebear-CZeQo09T.js} +1 -1
  5. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BPsRb9Ck.js +1 -0
  6. package/dist/gateway/static/root/assets/agents-BlrHMbRx.js +1 -0
  7. package/dist/gateway/static/root/assets/{api-DfSU0-lD.js → api-BKHmTb0w.js} +1 -1
  8. package/dist/gateway/static/root/assets/api-DFOlahZv.js +1 -0
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-BpYFKz7B.js → app-management-settings-panel-Bzw4fQP8.js} +1 -1
  10. package/dist/gateway/static/root/assets/appearance-settings-8GZpUXva.js +1 -0
  11. package/dist/gateway/static/root/assets/apps-page-BkQQtIxH.js +1 -0
  12. package/dist/gateway/static/root/assets/{archive-plugin-BxOvZ-ZX.js → archive-plugin-CQ2NaoHb.js} +1 -1
  13. package/dist/gateway/static/root/assets/{attachment-load-B0FzTMAJ.js → attachment-load-BFi1H7yJ.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automations-page-BpXuPaPg.js → automations-page-CDBXcii_.js} +1 -1
  15. package/dist/gateway/static/root/assets/automations-workspace-CUpiTTiY.js +6 -0
  16. package/dist/gateway/static/root/assets/{binary-plugins-BP7wfpqy.js → binary-plugins-D07eWmOx.js} +1 -1
  17. package/dist/gateway/static/root/assets/{block-editor-oMLvdnOQ.js → block-editor-CtVnjyYU.js} +3 -3
  18. package/dist/gateway/static/root/assets/{browser-automation-inputs-DTxSZ00u.js → browser-automation-inputs-BzkJog8e.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-automations-page-IbJnwEY4.js → browser-automations-page-DyrSbDdG.js} +2 -2
  20. package/dist/gateway/static/root/assets/browser-settings-page-CqTxLpil.js +3 -0
  21. package/dist/gateway/static/root/assets/capabilities-settings-panel-BZ_-pnS6.js +8 -0
  22. package/dist/gateway/static/root/assets/channels-settings-DAD9qE3J.js +1 -0
  23. package/dist/gateway/static/root/assets/{channels-status-swr-D2AmAoty.js → channels-status-swr-B2JwuTjG.js} +1 -1
  24. package/dist/gateway/static/root/assets/{chat-terminal-dock-B-yI3Mi1.js → chat-terminal-dock-B62SZdAo.js} +1 -1
  25. package/dist/gateway/static/root/assets/{computer-settings-page-CWx_jnng.js → computer-settings-page-ClSresNq.js} +1 -1
  26. package/dist/gateway/static/root/assets/connector-service-page-CPqVmNvx.js +1 -0
  27. package/dist/gateway/static/root/assets/connectors-page-BUQyg3CW.js +2 -0
  28. package/dist/gateway/static/root/assets/{cron-expression-DMRRL4Zg.js → cron-expression-CTMi_tql.js} +1 -1
  29. package/dist/gateway/static/root/assets/{date-picker-BSwL0e6E.js → date-picker-B71AJK50.js} +1 -1
  30. package/dist/gateway/static/root/assets/{dependency-picker-BQTspLzC.js → dependency-picker-DlyGK-kA.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-C3lFxDF6.js → desktop-pet-DGkbTE8_.js} +1 -1
  32. package/dist/gateway/static/root/assets/{desktop-pet-settings-Y8pjpXFE.js → desktop-pet-settings-BY8r9j66.js} +1 -1
  33. package/dist/gateway/static/root/assets/device-pairing-wizard-DzRrgd59.js +1 -0
  34. package/dist/gateway/static/root/assets/{extension-debug-page-CVGiGVcR.js → extension-debug-page-L8Mm1n3A.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-page-g3JtCP_y.js → extension-page-CFc4vSNU.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-settings-page-CjpoKV1f.js → extension-settings-page-B5zWyHr3.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-BSvXXpKM.js → gateway-config-swr-B6wHa6ZI.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-realtime-BDCpS7U1.js → gateway-realtime-B53R0CA4.js} +1 -1
  39. package/dist/gateway/static/root/assets/gateway-realtime-store-BLDgrJ30.js +1 -0
  40. package/dist/gateway/static/root/assets/{gateway-settings-CYG9WCZn.js → gateway-settings-D7qmTH4R.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-startup-retry-Caf8g3sC.js → gateway-startup-retry-DRzGnEV-.js} +1 -1
  42. package/dist/gateway/static/root/assets/{heartbeat-settings-Cl834-SS.js → heartbeat-settings-Glsl3X5b.js} +1 -1
  43. package/dist/gateway/static/root/assets/home-page-s9hDQ8Hc.js +1 -0
  44. package/dist/gateway/static/root/assets/{image-generation-api-BwEWBUVC.js → image-generation-api-Ck_pyDom.js} +1 -1
  45. package/dist/gateway/static/root/assets/{imports-page-CoMlgSIA.js → imports-page-ByBX7ome.js} +1 -1
  46. package/dist/gateway/static/root/assets/{index-Do9MltC4.js → index-RBCkv8a_.js} +48 -48
  47. package/dist/gateway/static/root/assets/index-cFU4S35z.css +1 -0
  48. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CNq5D4pe.js → keyboard-shortcuts-settings-C45RlO8a.js} +1 -1
  49. package/dist/gateway/static/root/assets/local-app-workbench-page-DP0x2jpR.js +2 -0
  50. package/dist/gateway/static/root/assets/{local-apps-page-DQnRA598.js → local-apps-page-C_AQc2bI.js} +1 -1
  51. package/dist/gateway/static/root/assets/{locale-store-D16nmbaN.js → locale-store-msTfRK8P.js} +1 -1
  52. package/dist/gateway/static/root/assets/logs-page-DvM8Pyok.js +2 -0
  53. package/dist/gateway/static/root/assets/{management-settings-DKcO5fQ-.js → management-settings-D1uwSutV.js} +1 -1
  54. package/dist/gateway/static/root/assets/{markdown-view-DCp4BlZP.js → markdown-view-BInabSKf.js} +1 -1
  55. package/dist/gateway/static/root/assets/{media-plugins-Cy64sn_C.js → media-plugins-C4mhf13f.js} +1 -1
  56. package/dist/gateway/static/root/assets/{messages-C-9oo69N.js → messages-F74LVAiU.js} +3 -3
  57. package/dist/gateway/static/root/assets/note-detail-panel-D35sErp2.js +5 -0
  58. package/dist/gateway/static/root/assets/notes-page-8jCDklDn.js +8 -0
  59. package/dist/gateway/static/root/assets/{page-tabs-CgEoHSVT.js → page-tabs-1go_BtX1.js} +1 -1
  60. package/dist/gateway/static/root/assets/{preview-open-alternatives-Ck2uKTbf.js → preview-open-alternatives-DmoSC0j1.js} +1 -1
  61. package/dist/gateway/static/root/assets/{proactive-page-Dr1mCJhZ.js → proactive-page-xAjKTIID.js} +1 -1
  62. package/dist/gateway/static/root/assets/{product-open-page-DbZvJ5GE.js → product-open-page-gmi5LLwM.js} +1 -1
  63. package/dist/gateway/static/root/assets/project-detail-page-BUMQHy_N.js +1 -0
  64. package/dist/gateway/static/root/assets/projects-page-DT-Mt7XR.js +1 -0
  65. package/dist/gateway/static/root/assets/{registry-api-DcQdwpPu.js → registry-api-BSWtko7U.js} +1 -1
  66. package/dist/gateway/static/root/assets/remote-access-hub-Clz3byir.js +1 -0
  67. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CPwdgWKo.js → runtime-tools-settings-panel-ClkOoxDl.js} +2 -2
  68. package/dist/gateway/static/root/assets/{schema-form-8psK4cFO.js → schema-form-BuEmLiaU.js} +1 -1
  69. package/dist/gateway/static/root/assets/sessions-page-tQRwktKm.js +1 -0
  70. package/dist/gateway/static/root/assets/settings-advanced-gate-DqWg9XS5.js +1 -0
  71. package/dist/gateway/static/root/assets/{settings-form-section-D_Gsz5rl.js → settings-form-section-Dor39QON.js} +1 -1
  72. package/dist/gateway/static/root/assets/{settings-page-C_Tj_mkZ.js → settings-page-Xj-yvIc8.js} +1 -1
  73. package/dist/gateway/static/root/assets/setup-status-panel-BB_sMB7P.js +1 -0
  74. package/dist/gateway/static/root/assets/{share-preview-page-B_M_oPsT.js → share-preview-page-BFWZoXdm.js} +1 -1
  75. package/dist/gateway/static/root/assets/shares-settings-oDALm4b6.js +1 -0
  76. package/dist/gateway/static/root/assets/skill-reload-api-DmwelnfK.js +1 -0
  77. package/dist/gateway/static/root/assets/{skills-page-DYgwzl5B.js → skills-page-BE9JXz4U.js} +1 -1
  78. package/dist/gateway/static/root/assets/{skills-page.utils-Cuh6s2HM.js → skills-page.utils-Ii8qeXhs.js} +1 -1
  79. package/dist/gateway/static/root/assets/{system-settings-panel-aassGyNb.js → system-settings-panel-Di6OSO-0.js} +1 -1
  80. package/dist/gateway/static/root/assets/task-detail-page-D1AWszc7.js +1 -0
  81. package/dist/gateway/static/root/assets/theme-store-1SZ-HFHX.js +1 -0
  82. package/dist/gateway/static/root/assets/{tunnel-api-DJYcPWIV.js → tunnel-api-DDOlOYlj.js} +1 -1
  83. package/dist/gateway/static/root/assets/{use-autosave-QGYG7oMZ.js → use-autosave-CQ8uWNnB.js} +1 -1
  84. package/dist/gateway/static/root/assets/user-model-page-C00i4ea0.js +2 -0
  85. package/dist/gateway/static/root/assets/{voice-api-key-field-D1s0gIRW.js → voice-api-key-field-COTzshjL.js} +1 -1
  86. package/dist/gateway/static/root/assets/{voice-config-api-D2goEn5e.js → voice-config-api-DgJML_uM.js} +1 -1
  87. package/dist/gateway/static/root/assets/{work-discovery-overlay-DkFW9aJ6.js → work-discovery-overlay-_URrXbi4.js} +1 -1
  88. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BYToUPUY.js → workflow-run-setup-panel-CALs-1nd.js} +2 -2
  89. package/dist/gateway/static/root/assets/workflows-page-BUiBjz6m.js +6 -0
  90. package/dist/gateway/static/root/channel-icons/feishu.svg +6 -12
  91. package/dist/gateway/static/root/connector-icons/SOURCES.md +12 -0
  92. package/dist/gateway/static/root/connector-icons/dingtalk-mark.svg +1 -0
  93. package/dist/gateway/static/root/connector-icons/tencent-meeting-mark.svg +37 -0
  94. package/dist/gateway/static/root/connector-icons/wps-calendar.svg +14 -0
  95. package/dist/gateway/static/root/connector-icons/wps-docs.svg +14 -0
  96. package/dist/gateway/static/root/connector-icons/wps-mail.svg +7 -0
  97. package/dist/gateway/static/root/index.html +12 -12
  98. package/dist/package.js +1 -1
  99. package/dist/src/agent/external-tools/composio-provider.js +83 -20
  100. package/dist/src/agent/external-tools/gateway-tools.js +2 -1
  101. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  102. package/dist/src/agent/mcp/oauth/mcp-oauth-manager.js +1 -1
  103. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  104. package/dist/src/cli/commands/gateway/lifecycle.js +2 -2
  105. package/dist/src/cli/commands/update.js +1 -1
  106. package/dist/src/config/schema.d.ts +12 -0
  107. package/dist/src/config/schema.js +4 -2
  108. package/dist/src/connectors/account-access.d.ts +4 -0
  109. package/dist/src/connectors/account-access.js +23 -0
  110. package/dist/src/connectors/approval-resume.d.ts +4 -0
  111. package/dist/src/connectors/approval-resume.js +23 -0
  112. package/dist/src/connectors/auth-provider-registry.d.ts +1 -0
  113. package/dist/src/connectors/auth-provider-registry.js +2 -1
  114. package/dist/src/connectors/authorization-attempts.d.ts +21 -0
  115. package/dist/src/connectors/authorization-attempts.js +33 -0
  116. package/dist/src/connectors/builtin-catalog.js +1 -3
  117. package/dist/src/connectors/catalog.js +2 -1
  118. package/dist/src/connectors/china-catalog.d.ts +2 -0
  119. package/dist/src/connectors/china-catalog.js +430 -0
  120. package/dist/src/connectors/composio-backends.d.ts +26 -0
  121. package/dist/src/connectors/composio-backends.js +65 -0
  122. package/dist/src/connectors/composio-catalog.js +2 -1
  123. package/dist/src/connectors/composio-managed-client.js +3 -1
  124. package/dist/src/connectors/composio-managed-events.js +5 -2
  125. package/dist/src/connectors/composio-session-types.d.ts +2 -0
  126. package/dist/src/connectors/composio-sessions.d.ts +11 -2
  127. package/dist/src/connectors/composio-sessions.js +137 -35
  128. package/dist/src/connectors/composio-triggers.js +4 -2
  129. package/dist/src/connectors/composio.d.ts +11 -8
  130. package/dist/src/connectors/composio.js +68 -84
  131. package/dist/src/connectors/connected-source-ingestion.js +4 -3
  132. package/dist/src/connectors/connection-recovery-service.js +25 -13
  133. package/dist/src/connectors/connector-identity.d.ts +2 -0
  134. package/dist/src/connectors/connector-identity.js +18 -5
  135. package/dist/src/connectors/content-enrichment.js +1 -1
  136. package/dist/src/connectors/instances.js +1 -7
  137. package/dist/src/connectors/learning-coordinator.js +4 -3
  138. package/dist/src/connectors/materialize.js +14 -1
  139. package/dist/src/connectors/policy.d.ts +1 -1
  140. package/dist/src/connectors/policy.js +1 -1
  141. package/dist/src/connectors/principal.js +24 -3
  142. package/dist/src/connectors/providers.d.ts +1 -0
  143. package/dist/src/connectors/providers.js +14 -2
  144. package/dist/src/connectors/runtime-adapter-registry.js +4 -9
  145. package/dist/src/connectors/secret-store.d.ts +4 -1
  146. package/dist/src/connectors/secret-store.js +7 -3
  147. package/dist/src/connectors/source-change-publisher.js +4 -2
  148. package/dist/src/connectors/types.d.ts +16 -11
  149. package/dist/src/connectors/workflow-preflight.d.ts +2 -1
  150. package/dist/src/connectors/workflow-preflight.js +20 -3
  151. package/dist/src/gateway/hono/routes/connectors.js +208 -17
  152. package/dist/src/gateway/hono/routes/context-sources.js +1 -1
  153. package/dist/src/gateway/hono/routes/home.js +4 -1
  154. package/dist/src/gateway/hono/routes/imports.js +1 -1
  155. package/dist/src/gateway/hono/routes/local-apps.js +1 -1
  156. package/dist/src/gateway/hono/routes/mcp.js +1 -1
  157. package/dist/src/gateway/hono/routes/update.js +2 -2
  158. package/dist/src/gateway/index.js +1 -1
  159. package/dist/src/gateway/run-loop.js +1 -1
  160. package/dist/src/gateway/service.js +10 -10
  161. package/dist/src/infra/gateway-processes.js +1 -1
  162. package/dist/src/infra/update-restart.js +2 -2
  163. package/dist/src/infra/update-runner.js +2 -2
  164. package/dist/src/infra/update-startup.js +1 -1
  165. package/dist/src/proactive/follow-ups.js +2 -1
  166. package/dist/src/storage/sqlite/connection-wait-repository.d.ts +3 -0
  167. package/dist/src/storage/sqlite/connection-wait-repository.js +63 -2
  168. package/dist/src/storage/sqlite/connector-account-repository.d.ts +6 -0
  169. package/dist/src/storage/sqlite/connector-account-repository.js +35 -7
  170. package/dist/src/storage/sqlite/connector-repository.js +15 -10
  171. package/dist/src/storage/sqlite/connector-sync-policy-repository.js +1 -1
  172. package/dist/src/storage/sqlite/index.js +4 -2
  173. package/dist/src/storage/sqlite/migrations/182_connector_account_policies.sql +92 -0
  174. package/dist/src/storage/sqlite/migrations/183_connector_backend_consistency.sql +20 -0
  175. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  176. package/dist/src/storage/sqlite/migrations/runner.js +7 -7
  177. package/dist/src/storage/sqlite/schema.js +1 -1
  178. package/dist/src/tasks/home-query-service.js +3 -3
  179. package/dist/src/tui/backends/gateway-realtime-backend.js +1 -1
  180. package/dist/src/tui/tui-startup-resources.js +1 -1
  181. package/dist/src/workflows/domain/definition.d.ts +1 -0
  182. package/dist/src/workflows/domain/validation.js +1 -1
  183. package/dist/src/workflows/service/workflow-run-service.js +14 -0
  184. package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
  185. package/dist/src/workflows/service/workflow-session-bridge.js +1 -0
  186. package/package.json +3 -3
  187. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CxOv4ivK.js +0 -1
  188. package/dist/gateway/static/root/assets/agents-DzKx7z3k.js +0 -1
  189. package/dist/gateway/static/root/assets/api-gpHh07OL.js +0 -1
  190. package/dist/gateway/static/root/assets/appearance-settings-BQfR5vrq.js +0 -1
  191. package/dist/gateway/static/root/assets/apps-page-BceB7JHZ.js +0 -1
  192. package/dist/gateway/static/root/assets/automations-workspace-Cn_p8zY_.js +0 -6
  193. package/dist/gateway/static/root/assets/browser-settings-page-CCUO3G23.js +0 -3
  194. package/dist/gateway/static/root/assets/capabilities-settings-panel-BjMb5H2_.js +0 -8
  195. package/dist/gateway/static/root/assets/channels-settings-P22-_i13.js +0 -1
  196. package/dist/gateway/static/root/assets/connectors-page-BLgPORmH.js +0 -2
  197. package/dist/gateway/static/root/assets/device-pairing-wizard-DM4_GMzo.js +0 -1
  198. package/dist/gateway/static/root/assets/gateway-realtime-store-BGmP1obI.js +0 -1
  199. package/dist/gateway/static/root/assets/home-page-CB_XVtIM.js +0 -1
  200. package/dist/gateway/static/root/assets/index-CI37dTAn.css +0 -1
  201. package/dist/gateway/static/root/assets/local-app-workbench-page-BxQlEje6.js +0 -2
  202. package/dist/gateway/static/root/assets/logs-page-CT5GrcMs.js +0 -2
  203. package/dist/gateway/static/root/assets/note-detail-panel-5dc3LKTL.js +0 -5
  204. package/dist/gateway/static/root/assets/notes-page-AbwxgXuG.js +0 -8
  205. package/dist/gateway/static/root/assets/project-detail-page-DnE1zI1c.js +0 -1
  206. package/dist/gateway/static/root/assets/projects-page-BD0nLYxk.js +0 -1
  207. package/dist/gateway/static/root/assets/remote-access-hub-TYuE6A3S.js +0 -1
  208. package/dist/gateway/static/root/assets/sessions-page-BcWDQQFX.js +0 -1
  209. package/dist/gateway/static/root/assets/settings-advanced-gate-DzGQX6Hq.js +0 -1
  210. package/dist/gateway/static/root/assets/setup-status-panel-CE2X89qN.js +0 -1
  211. package/dist/gateway/static/root/assets/shares-settings-BL4H9Iym.js +0 -1
  212. package/dist/gateway/static/root/assets/skill-reload-api-WMKIgUOp.js +0 -1
  213. package/dist/gateway/static/root/assets/task-detail-page-BjeRslap.js +0 -1
  214. package/dist/gateway/static/root/assets/theme-store-RUBQBsFP.js +0 -1
  215. package/dist/gateway/static/root/assets/user-model-page-PrRsd4go.js +0 -2
  216. package/dist/gateway/static/root/assets/workflows-page-Z8iZe9YP.js +0 -6
@@ -1,32 +1,39 @@
1
- import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
2
1
  import { createLogger } from "../utils/logger/index.js";
3
2
  import { init_logger } from "../utils/logger.js";
4
- import { appendConnectorExecutionAudit, getConnectorConnection, getConnectorInstallation, listConnectorConnections, upsertConnectorConnection } from "../storage/sqlite/connector-repository.js";
5
- import { reconcileConnectorAccount } from "../storage/sqlite/connector-account-repository.js";
3
+ import { getSqliteDatabase, init_transaction } from "../storage/sqlite/transaction.js";
4
+ import { getConnectorAccount, init_connector_account_repository, reconcileConnectorAccount } from "../storage/sqlite/connector-account-repository.js";
5
+ import { appendConnectorExecutionAudit, getConnectorConnection, getConnectorInstallation, init_connector_repository, listConnectorConnections, upsertConnectorConnection } from "../storage/sqlite/connector-repository.js";
6
6
  import { CredentialResolver, init_credentials } from "../auth/credentials.js";
7
+ import { ensureComposioBackend, getComposioBackend, listComposioBackends, resolveBackendKey } from "./composio-backends.js";
8
+ import { saveAuthorizationAttempt } from "./authorization-attempts.js";
7
9
  import { connectorIdentityKey, mergeConnectorIdentity } from "./connector-identity.js";
8
10
  import { evaluateConnectorExecutionPolicy } from "./policy.js";
9
- import { resolve } from "node:path";
11
+ import { canAccessConnectorAccount } from "./account-access.js";
10
12
  import { createHash } from "node:crypto";
11
13
  //#region src/connectors/composio-sessions.ts
12
14
  init_credentials();
13
- init_paths_state();
15
+ init_transaction();
16
+ init_connector_account_repository();
17
+ init_connector_repository();
14
18
  init_logger();
15
19
  const log = createLogger("Connectors:ComposioSessions");
16
- const COMPOSIO_API_KEY_PROVIDER = "connector-composio-api-key";
17
20
  async function resolveComposioApiKey(resolver = new CredentialResolver()) {
18
- return (await resolver.resolveApiKey(COMPOSIO_API_KEY_PROVIDER).catch(() => void 0))?.trim() || process.env.XOPC_COMPOSIO_API_KEY?.trim() || process.env.COMPOSIO_API_KEY?.trim() || null;
21
+ return resolveBackendKey(await ensureComposioBackend(resolver), resolver);
19
22
  }
20
23
  async function assertComposioAccessConfigured(resolver = new CredentialResolver()) {
21
- if (await resolveComposioApiKey(resolver)) return "byok";
24
+ const backend = await ensureComposioBackend(resolver);
25
+ if (backend.mode === "byok") {
26
+ if (await resolveBackendKey(backend, resolver)) return "byok";
27
+ throw new Error("This Composio project needs its API key. Open connection service settings.");
28
+ }
22
29
  if ((await resolver.resolveApiKey("xopc-cloud").catch(() => null))?.trim()) return "managed";
23
- throw new Error("Composio API key is not configured and XOPC Cloud is not signed in. Install the \"Composio API Key\" connector first or sign in to XOPC Cloud.");
30
+ throw new Error("Composio API key is not configured and XOPC Cloud is not signed in. Open connection service settings or sign in to XOPC Cloud.");
24
31
  }
25
32
  function stableHash(value) {
26
33
  return createHash("sha256").update(value).digest("hex").slice(0, 24);
27
34
  }
28
35
  function defaultInstallationScope() {
29
- return resolve(resolveStateDir());
36
+ return getSqliteDatabase().prepare("SELECT installation_id FROM connector_runtime_identity WHERE id = 1").get().installation_id;
30
37
  }
31
38
  /** Convert local identities to stable opaque Composio user IDs without disclosing user data. */
32
39
  function createComposioPrincipalId(principalId, installationScope = defaultInstallationScope()) {
@@ -84,17 +91,26 @@ function missingAuthConfigMessage(error, toolkit, authConfigId) {
84
91
  }
85
92
  var ComposioSessionsAdapter = class {
86
93
  createClient;
94
+ injectedClient;
95
+ resolver;
87
96
  constructor(options = {}) {
97
+ this.resolver = options.resolver ?? new CredentialResolver();
98
+ this.injectedClient = Boolean(options.clientFactory || options.apiKey);
88
99
  if (options.clientFactory) {
89
100
  this.createClient = options.clientFactory;
90
101
  return;
91
102
  }
92
- const resolver = options.resolver ?? new CredentialResolver();
93
- this.createClient = async () => {
94
- const apiKey = await resolveComposioApiKey(resolver);
95
- if (!apiKey) {
103
+ const resolver = this.resolver;
104
+ this.createClient = async (backendId) => {
105
+ const backend = options.apiKey ? void 0 : backendId ? getComposioBackend(backendId) : await ensureComposioBackend(resolver);
106
+ if (backendId && !backend) throw new Error("Connection service is unavailable.");
107
+ const apiKey = options.apiKey ?? (backend ? await resolveBackendKey(backend, resolver) : null);
108
+ if (backend?.mode === "byok" && !apiKey) throw new Error("This Composio project needs its API key.");
109
+ if (backend?.mode === "managed") {
96
110
  const { ManagedComposioClient } = await import("./composio-managed-client.js");
97
- return new ManagedComposioClient();
111
+ const client = new ManagedComposioClient();
112
+ client.backendId = backend.id;
113
+ return client;
98
114
  }
99
115
  let Composio;
100
116
  try {
@@ -112,11 +128,12 @@ var ComposioSessionsAdapter = class {
112
128
  host: "xopc"
113
129
  });
114
130
  client.mode = "byok";
131
+ client.backendId = backend?.id;
115
132
  return client;
116
133
  };
117
134
  }
118
135
  async createSession(context) {
119
- const client = await this.createClient();
136
+ const client = await this.createClient(context.backendId);
120
137
  const config = {
121
138
  manageConnections: {
122
139
  enable: true,
@@ -183,11 +200,13 @@ var ComposioSessionsAdapter = class {
183
200
  return items;
184
201
  }
185
202
  async authorize(context) {
203
+ const backendId = (await this.createClient(context.backendId)).backendId;
186
204
  const providerPrincipalId = createComposioPrincipalId(context.principalId, context.installationScope);
187
205
  let session;
188
206
  try {
189
207
  session = await this.createSession({
190
208
  ...context,
209
+ backendId,
191
210
  providerPrincipalId,
192
211
  toolkits: [context.toolkit],
193
212
  ...context.authConfigId ? { authConfigs: { [context.toolkit]: context.authConfigId } } : {}
@@ -202,8 +221,8 @@ var ComposioSessionsAdapter = class {
202
221
  alias: context.alias
203
222
  });
204
223
  const connectorId = `composio-${context.toolkit}`;
205
- upsertConnectorConnection({
206
- id: `composio-${request.id}`,
224
+ const pending = upsertConnectorConnection({
225
+ id: `composio-${backendId ? `${backendId}-` : ""}${request.id}`,
207
226
  installationId: context.installationId && getConnectorInstallation(context.installationId) ? context.installationId : void 0,
208
227
  connectorId,
209
228
  provider: "composio",
@@ -212,29 +231,74 @@ var ComposioSessionsAdapter = class {
212
231
  alias: context.alias,
213
232
  identity: {},
214
233
  status: connectionStatus(request.status),
215
- isDefault: listConnectorConnections({
216
- principalId: context.principalId,
217
- connectorId
218
- }).length === 0,
234
+ isDefault: false,
219
235
  metadata: {
220
236
  toolkit: context.toolkit,
221
237
  providerPrincipalId,
222
- ...context.authConfigId ? { authConfigId: context.authConfigId } : {}
238
+ ...context.authConfigId ? { authConfigId: context.authConfigId } : {},
239
+ ...backendId ? { backendId } : {}
223
240
  }
224
241
  });
242
+ if (backendId && pending.accountId) getSqliteDatabase().prepare("UPDATE connector_accounts SET backend_id = ? WHERE id = ?").run(backendId, pending.accountId);
225
243
  return {
244
+ attemptId: saveAuthorizationAttempt({
245
+ connectionId: pending.id,
246
+ principalId: context.principalId,
247
+ connectorId,
248
+ backendId,
249
+ expectedAccountId: context.expectedAccountId,
250
+ url: request.redirectUrl ?? void 0
251
+ }),
226
252
  toolkit: context.toolkit,
227
253
  connectionId: request.id,
228
254
  connectUrl: request.redirectUrl ?? void 0,
229
255
  status: request.status
230
256
  };
231
257
  }
232
- async syncConnections(context) {
258
+ /** Verify a replacement credential without changing local authorizations. */
259
+ async verifyConnections(connections) {
233
260
  const client = await this.createClient();
261
+ const users = [...new Set(connections.map((connection) => connection.metadata.providerPrincipalId))];
262
+ for (const userId of users) {
263
+ if (typeof userId !== "string" || !userId) throw new Error("Refresh existing account identities before replacing this key.");
264
+ const rows = await this.listAllAccounts(client, [userId]);
265
+ const ids = new Set(rows.flatMap((row) => row && typeof row === "object" ? [readString(row, ["id", "connected_account_id"])] : []));
266
+ if (connections.some((connection) => connection.metadata.providerPrincipalId === userId && !ids.has(connection.providerConnectionId))) throw new Error("This key cannot access the existing accounts. Add it as a new project instead.");
267
+ }
268
+ }
269
+ async listAllAccounts(client, userIds) {
270
+ const rows = [];
271
+ const cursors = /* @__PURE__ */ new Set();
272
+ let cursor;
273
+ do {
274
+ const payload = await client.connectedAccounts.list({
275
+ userIds,
276
+ ...cursor ? { cursor } : {}
277
+ });
278
+ rows.push(...readArray(payload));
279
+ cursor = payload && typeof payload === "object" ? readString(payload, ["nextCursor", "next_cursor"]) : void 0;
280
+ if (cursor && (cursors.has(cursor) || cursors.size >= 100)) throw new Error("Unable to retrieve the complete connected account list. Retry syncing.");
281
+ if (cursor) cursors.add(cursor);
282
+ } while (cursor);
283
+ return rows;
284
+ }
285
+ async syncConnections(context) {
286
+ if (!this.injectedClient && !context.backendId) {
287
+ await ensureComposioBackend(this.resolver);
288
+ const results = await Promise.allSettled(listComposioBackends().map((backend) => this.syncConnections({
289
+ ...context,
290
+ backendId: backend.id
291
+ })));
292
+ if (results.every((result) => result.status === "rejected")) throw results[0].reason;
293
+ return results.flatMap((result) => result.status === "fulfilled" ? result.value : []);
294
+ }
295
+ const client = await this.createClient(context.backendId);
234
296
  const providerPrincipalId = createComposioPrincipalId(context.principalId, context.installationScope);
235
- const payload = await client.connectedAccounts.list({ userIds: [providerPrincipalId] });
297
+ const stored = listConnectorConnections({ principalId: context.principalId }).filter((connection) => (connection.metadata.backendId ?? getConnectorAccount(connection.accountId)?.backendId) === client.backendId);
298
+ const userIds = [...new Set([providerPrincipalId, ...stored.flatMap((connection) => typeof connection.metadata.providerPrincipalId === "string" ? [connection.metadata.providerPrincipalId] : [])])];
299
+ const rows = await this.listAllAccounts(client, userIds);
236
300
  const synced = [];
237
- for (const item of readArray(payload)) {
301
+ for (const item of rows) {
238
302
  if (!item || typeof item !== "object" || Array.isArray(item)) continue;
239
303
  const row = item;
240
304
  const toolkitRecord = row.toolkit && typeof row.toolkit === "object" && !Array.isArray(row.toolkit) ? row.toolkit : {};
@@ -250,10 +314,10 @@ var ComposioSessionsAdapter = class {
250
314
  const existing = listConnectorConnections({
251
315
  principalId: context.principalId,
252
316
  connectorId
253
- }).find((connection) => connection.providerConnectionId === providerConnectionId);
317
+ }).find((connection) => connection.providerConnectionId === providerConnectionId && (connection.metadata.backendId ?? getConnectorAccount(connection.accountId)?.backendId) === client.backendId);
254
318
  const identity = row.connectionData && typeof row.connectionData === "object" && !Array.isArray(row.connectionData) ? row.connectionData : {};
255
319
  const connection = upsertConnectorConnection({
256
- id: existing?.id ?? `composio-${providerConnectionId}`,
320
+ id: existing?.id ?? `composio-${client.backendId ? `${client.backendId}-` : ""}${providerConnectionId}`,
257
321
  accountId: existing?.accountId,
258
322
  installationId: existing?.installationId,
259
323
  connectorId,
@@ -269,12 +333,37 @@ var ComposioSessionsAdapter = class {
269
333
  metadata: {
270
334
  ...existing?.metadata,
271
335
  toolkit,
272
- providerPrincipalId
336
+ providerPrincipalId: existing?.metadata.providerPrincipalId ?? readString(row, ["userId", "user_id"]) ?? providerPrincipalId,
337
+ ...client.backendId ? { backendId: client.backendId } : {}
273
338
  }
274
339
  });
275
- const identityKey = connectorIdentityKey(toolkit, connection.identity);
340
+ if (client.backendId && connection.accountId && !connectorIdentityKey(toolkit, connection.identity)) getSqliteDatabase().prepare("UPDATE connector_accounts SET backend_id = ? WHERE id = ?").run(client.backendId, connection.accountId);
341
+ let identityKey = connectorIdentityKey(toolkit, connection.identity);
342
+ const probe = {
343
+ gmail: "GMAIL_GET_PROFILE",
344
+ googledrive: "GOOGLEDRIVE_GET_ABOUT",
345
+ github: "GITHUB_GET_THE_AUTHENTICATED_USER",
346
+ slack: "SLACK_TEST_AUTH"
347
+ }[toolkit];
348
+ if (!identityKey && probe && connection.status === "active" && Date.now() - Number(connection.metadata.identityCheckedAt ?? 0) > 3e5) {
349
+ try {
350
+ const profile = await (await this.createSession({
351
+ ...context,
352
+ backendId: client.backendId,
353
+ toolkits: [toolkit],
354
+ authConfigs: typeof connection.metadata.authConfigId === "string" ? { [toolkit]: connection.metadata.authConfigId } : void 0,
355
+ providerPrincipalId: String(connection.metadata.providerPrincipalId),
356
+ connectedAccounts: { [toolkit]: [providerConnectionId] }
357
+ })).execute(probe, {}, { account: providerConnectionId });
358
+ connection.identity = mergeConnectorIdentity(toolkit, connection.identity, profile && typeof profile === "object" ? profile : {});
359
+ identityKey = connectorIdentityKey(toolkit, connection.identity);
360
+ } catch {}
361
+ connection.metadata.identityCheckedAt = Date.now();
362
+ upsertConnectorConnection(connection);
363
+ }
276
364
  if (identityKey) reconcileConnectorAccount({
277
365
  connectionId: connection.id,
366
+ backendId: client.backendId,
278
367
  identityKey,
279
368
  identity: connection.identity
280
369
  });
@@ -283,7 +372,9 @@ var ComposioSessionsAdapter = class {
283
372
  return synced;
284
373
  }
285
374
  async revokeConnection(connection) {
286
- await (await this.createClient()).connectedAccounts.delete(connection.providerConnectionId);
375
+ const backendId = getConnectorAccount(connection.accountId)?.backendId;
376
+ if (!this.injectedClient && !backendId) throw new Error("Refresh account status to verify its connection service first.");
377
+ await (await this.createClient(backendId)).connectedAccounts.delete(connection.providerConnectionId);
287
378
  upsertConnectorConnection({
288
379
  ...connection,
289
380
  status: "revoked",
@@ -292,16 +383,25 @@ var ComposioSessionsAdapter = class {
292
383
  });
293
384
  }
294
385
  async refreshConnection(connection) {
295
- await (await this.createClient()).connectedAccounts.refresh(connection.providerConnectionId);
296
- const synced = await this.syncConnections({ principalId: connection.principalId });
386
+ const backendId = getConnectorAccount(connection.accountId)?.backendId;
387
+ if (!this.injectedClient && !backendId) throw new Error("Refresh account status to verify its connection service first.");
388
+ await (await this.createClient(backendId)).connectedAccounts.refresh(connection.providerConnectionId);
389
+ const synced = await this.syncConnections({
390
+ principalId: connection.principalId,
391
+ backendId
392
+ });
297
393
  return synced.find((candidate) => candidate.id === connection.id) ?? synced.find((candidate) => candidate.providerConnectionId === connection.providerConnectionId) ?? connection;
298
394
  }
299
395
  async executeWithPolicy(input) {
396
+ if (!input.connection || input.connection.status !== "active" || !canAccessConnectorAccount(input.connection, input.installation, input.agentId)) return {
397
+ decision: "denied",
398
+ reason: "Account is unavailable to this agent."
399
+ };
300
400
  const evaluation = evaluateConnectorExecutionPolicy({
301
401
  installation: input.installation,
302
402
  action: input.action,
303
403
  agentId: input.agentId,
304
- connectionId: input.connection?.id,
404
+ accountId: input.connection?.accountId,
305
405
  confirmed: input.confirmed
306
406
  });
307
407
  if (evaluation.decision !== "allowed") {
@@ -324,6 +424,7 @@ var ComposioSessionsAdapter = class {
324
424
  }
325
425
  const startedAt = Date.now();
326
426
  try {
427
+ if (!this.injectedClient && input.connection && !getConnectorAccount(input.connection.accountId)?.backendId) throw new Error("The account connection service has not been verified. Refresh account status first.");
327
428
  const toolkit = input.action.toolkit;
328
429
  const connectedAccounts = toolkit && input.connection ? { [toolkit]: [input.connection.providerConnectionId] } : input.context.connectedAccounts;
329
430
  const providerPrincipalId = input.connection?.metadata.providerPrincipalId;
@@ -331,8 +432,9 @@ var ComposioSessionsAdapter = class {
331
432
  if (input.connection && (typeof providerPrincipalId !== "string" || !providerPrincipalId.trim())) throw new Error("Connected account is missing its provider identity. Reconnect the account and try again.");
332
433
  const result = await (await this.createSession({
333
434
  ...input.context,
435
+ backendId: input.connection?.accountId ? getConnectorAccount(input.connection.accountId)?.backendId : input.context.backendId,
334
436
  connectedAccounts,
335
- ...toolkit && typeof connectionAuthConfigId === "string" && connectionAuthConfigId.trim() ? { authConfigs: { [toolkit]: connectionAuthConfigId.trim() } } : {},
437
+ ...toolkit && typeof connectionAuthConfigId === "string" && connectionAuthConfigId.trim() ? { authConfigs: { [toolkit]: connectionAuthConfigId.trim() } } : { authConfigs: void 0 },
336
438
  ...typeof providerPrincipalId === "string" ? { providerPrincipalId } : {}
337
439
  })).execute(input.action.actionId, input.args ?? {}, input.connection ? { account: input.connection.providerConnectionId } : void 0);
338
440
  appendConnectorExecutionAudit({
@@ -1,7 +1,8 @@
1
- import { listConnectorConnections, upsertConnectorConnection } from "../storage/sqlite/connector-repository.js";
1
+ import { init_connector_repository, listConnectorConnections, upsertConnectorConnection } from "../storage/sqlite/connector-repository.js";
2
2
  import { DurableState } from "../storage/sqlite/durable-state.js";
3
3
  import crypto, { createHmac, timingSafeEqual } from "node:crypto";
4
4
  //#region src/connectors/composio-triggers.ts
5
+ init_connector_repository();
5
6
  function readString(value) {
6
7
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
7
8
  }
@@ -35,7 +36,8 @@ function applyComposioConnectionLifecycleEvent(payload) {
35
36
  if (normalized.type !== "composio.connected_account.expired" && normalized.type !== "composio.connected_account.deleted") return void 0;
36
37
  const providerConnectionId = readString(normalized.data.id ?? normalized.data.nanoid ?? normalized.data.connected_account_id);
37
38
  if (!providerConnectionId) return void 0;
38
- const connection = listConnectorConnections().find((candidate) => candidate.provider === "composio" && candidate.providerConnectionId === providerConnectionId);
39
+ const candidates = listConnectorConnections().filter((candidate) => candidate.provider === "composio" && candidate.providerConnectionId === providerConnectionId);
40
+ const connection = candidates.length === 1 ? candidates[0] : void 0;
39
41
  if (!connection) return void 0;
40
42
  upsertConnectorConnection({
41
43
  ...connection,
@@ -3,13 +3,16 @@ import type { Config } from '../config/schema.js';
3
3
  import { type ComposioToolkitAuthState } from './composio-sessions.js';
4
4
  import type { ConnectorConfirmationPolicy, ConnectorDefinition, ConnectorInstallationPolicy } from './types.js';
5
5
  export type ComposioConnection = {
6
+ supportsLearning: boolean;
7
+ backendLabel?: string;
6
8
  id: string;
7
9
  accountId?: string;
10
+ accountEnabled: boolean;
11
+ allowedAgentIds: string[] | null;
8
12
  providerConnectionId: string;
9
13
  toolkit: string;
10
14
  status: string;
11
15
  alias?: string;
12
- isDefault: boolean;
13
16
  isCurrentAuthorization: boolean;
14
17
  accountEmail?: string;
15
18
  workspace?: string;
@@ -60,22 +63,20 @@ export declare function canUseComposioAction(config: Config | undefined, slug: s
60
63
  scope: ComposioScope;
61
64
  };
62
65
  export declare const COMPOSIO_CONNECTORS: readonly ConnectorDefinition[];
63
- export declare function saveComposioApiKey(input: {
64
- secrets?: Record<string, unknown>;
65
- }, resolver?: CredentialResolver): Promise<void>;
66
- export declare function configureComposioApiKey(apiKey: string, resolver?: CredentialResolver): Promise<void>;
66
+ export declare function configureComposioApiKey(apiKey: string, resolver?: CredentialResolver, replaceBackendId?: string): Promise<void>;
67
67
  export declare function listComposioConnections(resolver?: CredentialResolver): Promise<ComposioConnection[]>;
68
68
  export declare function inspectComposioConnectorHealth(toolkit: string, resolver?: CredentialResolver): Promise<ComposioConnectorHealth>;
69
- export declare function getComposioToolkitAuthState(toolkit: string, resolver?: CredentialResolver): Promise<ComposioToolkitAuthState>;
69
+ export declare function getComposioToolkitAuthState(toolkit: string, resolver?: CredentialResolver): Promise<ComposioToolkitAuthState & {
70
+ mode: 'managed' | 'byok';
71
+ }>;
70
72
  export declare function getComposioInstallationPolicy(config: Config | undefined, toolkit: string): ConnectorInstallationPolicy;
71
73
  export declare function updateComposioInstallationPolicy(config: Config | undefined, toolkit: string, patch: {
72
74
  allowedAgentIds?: string[];
73
75
  confirmationPolicy?: ConnectorConfirmationPolicy;
74
- selectedConnectionIds?: string[];
76
+ selectedAccountIds?: string[] | null;
75
77
  }): ConnectorInstallationPolicy;
76
78
  export declare function updateComposioConnection(id: string, patch: {
77
79
  alias?: string;
78
- isDefault?: boolean;
79
80
  }): ComposioConnection;
80
81
  export declare function refreshComposioConnection(id: string, resolver?: CredentialResolver): Promise<void>;
81
82
  export declare function revokeComposioConnection(id: string, resolver?: CredentialResolver): Promise<void>;
@@ -83,10 +84,12 @@ export declare function startComposioAuthorize(connectorId: string, toolkit: str
83
84
  toolkit: string;
84
85
  connectUrl: string;
85
86
  connectionId?: string;
87
+ attemptId: string;
86
88
  }>;
87
89
  export declare function listComposioTools(toolkit: string, config?: Config, resolver?: CredentialResolver): Promise<ComposioTool[]>;
88
90
  export declare function executeComposioTool(params: {
89
91
  slug: string;
92
+ accountId?: string;
90
93
  arguments?: unknown;
91
94
  config?: Config;
92
95
  }, resolver?: CredentialResolver): Promise<unknown>;
@@ -1,23 +1,31 @@
1
- import { getConnectorConnection, getConnectorInstallation, listConnectorConnections, upsertConnectorActionMetadata, upsertConnectorConnection, upsertConnectorInstallation } from "../storage/sqlite/connector-repository.js";
2
- import { getConnectorAccount, refreshConnectorAccountCurrent } from "../storage/sqlite/connector-account-repository.js";
1
+ import { getConnectorAccount, init_connector_account_repository, refreshConnectorAccountCurrent, updateConnectorAccount } from "../storage/sqlite/connector-account-repository.js";
2
+ import { getConnectorConnection, getConnectorInstallation, init_connector_repository, listConnectorConnections, upsertConnectorActionMetadata, upsertConnectorConnection, upsertConnectorInstallation } from "../storage/sqlite/connector-repository.js";
3
3
  import { CredentialResolver, init_credentials } from "../auth/credentials.js";
4
+ import { activateComposioBackend, addComposioBackend, ensureComposioBackend, getComposioBackend, listComposioBackends, markComposioBackendVerified, resolveBackendKey } from "./composio-backends.js";
4
5
  import { connectorIdentityKey } from "./connector-identity.js";
6
+ import { canAccessConnectorAccount, currentAccountConnections } from "./account-access.js";
5
7
  import { ComposioSessionsAdapter, assertComposioAccessConfigured } from "./composio-sessions.js";
8
+ import { getConnectorLearningPlan } from "./learning-recipes.js";
6
9
  import { COMPOSIO_AGENT_READY_TOOLKITS, COMPOSIO_TOOLKIT_DISPLAY_NAMES, connectorDefinitionFromComposioToolkit } from "./composio-catalog.js";
7
- import { consumeConnectorSetupSecretRef } from "./setup-secrets.js";
10
+ import { randomUUID } from "node:crypto";
8
11
  //#region src/connectors/composio.ts
9
12
  init_credentials();
13
+ init_connector_account_repository();
14
+ init_connector_repository();
10
15
  function toComposioConnection(connection) {
11
16
  const toolkit = toolkitFromConnectionMetadata(connection);
12
17
  const account = connection.accountId ? getConnectorAccount(connection.accountId) : void 0;
13
18
  return {
19
+ supportsLearning: Boolean(getConnectorLearningPlan(toolkit)),
14
20
  id: connection.id,
15
21
  accountId: connection.accountId,
22
+ backendLabel: account?.backendId ? getComposioBackend(account.backendId)?.label : void 0,
23
+ accountEnabled: account?.enabled ?? false,
24
+ allowedAgentIds: account?.allowedAgentIds ?? null,
16
25
  providerConnectionId: connection.providerConnectionId,
17
26
  toolkit,
18
27
  status: connection.status,
19
- alias: connection.alias,
20
- isDefault: connection.isDefault,
28
+ alias: account?.label ?? connection.alias,
21
29
  isCurrentAuthorization: account?.currentConnectionId === connection.id,
22
30
  accountEmail: typeof connection.identity.email === "string" ? connection.identity.email : void 0,
23
31
  workspace: typeof connection.identity.workspace === "string" ? connection.identity.workspace : void 0,
@@ -29,7 +37,6 @@ function toComposioConnection(connection) {
29
37
  lastError: connection.lastError
30
38
  };
31
39
  }
32
- const COMPOSIO_API_KEY_PROVIDER = "connector-composio-api-key";
33
40
  const COMPOSIO_SCOPE_ORDER = {
34
41
  read: 1,
35
42
  write: 2,
@@ -296,47 +303,7 @@ function canUseComposioAction(config, slug) {
296
303
  scope: action.scope
297
304
  };
298
305
  }
299
- const COMPOSIO_CONNECTORS = [{
300
- id: "composio-api-key",
301
- version: "1.0.0",
302
- displayName: "Composio API Key",
303
- description: "Store a Composio API key for direct-mode toolkit connectors.",
304
- category: "automation",
305
- kind: "composio",
306
- source: "builtin",
307
- branding: {
308
- logoUrl: "/connector-icons/composio.svg",
309
- source: "composio-catalog"
310
- },
311
- verificationLevel: "verified",
312
- capabilities: [
313
- "auth.apiKey",
314
- "tools",
315
- "events",
316
- "workflows"
317
- ],
318
- tags: [
319
- "composio",
320
- "oauth",
321
- "integrations"
322
- ],
323
- auth: { mode: "apiKey" },
324
- setup: { secrets: [{
325
- key: "COMPOSIO_API_KEY",
326
- label: "Composio API key",
327
- required: true
328
- }] },
329
- runtime: {
330
- type: "composio",
331
- toolkit: "composio",
332
- role: "credential"
333
- },
334
- integrationStrategy: {
335
- lane: "composio",
336
- workload: "long_tail",
337
- preferred: true
338
- }
339
- }, ...COMPOSIO_AGENT_READY_TOOLKITS.map((toolkit) => {
306
+ const COMPOSIO_CONNECTORS = [...COMPOSIO_AGENT_READY_TOOLKITS.map((toolkit) => {
340
307
  return {
341
308
  ...connectorDefinitionFromComposioToolkit({
342
309
  slug: toolkit,
@@ -348,29 +315,52 @@ const COMPOSIO_CONNECTORS = [{
348
315
  source: "builtin"
349
316
  };
350
317
  })];
351
- async function saveComposioApiKey(input, resolver = new CredentialResolver()) {
352
- const raw = input.secrets?.COMPOSIO_API_KEY;
353
- const resolved = typeof raw === "string" && raw.trim().startsWith("secret://") ? consumeConnectorSetupSecretRef(raw) : raw;
354
- if (typeof resolved !== "string" || !resolved.trim()) throw new Error("Composio API key is required.");
355
- await resolver.saveApiKey(COMPOSIO_API_KEY_PROVIDER, resolved.trim(), { profileName: "default" });
356
- }
357
- async function configureComposioApiKey(apiKey, resolver = new CredentialResolver()) {
318
+ async function configureComposioApiKey(apiKey, resolver = new CredentialResolver(), replaceBackendId) {
358
319
  const normalized = apiKey.trim();
359
320
  if (!normalized) throw new Error("Composio API key is required.");
360
321
  if (normalized.length > 4096) throw new Error("Composio API key is too long.");
361
- await new ComposioSessionsAdapter({ resolver: { resolveApiKey: async () => normalized } }).listToolkitCatalog({ principalId: LOCAL_OWNER_PRINCIPAL });
362
- await resolver.saveApiKey(COMPOSIO_API_KEY_PROVIDER, normalized, { profileName: "default" });
322
+ const adapter = new ComposioSessionsAdapter({ apiKey: normalized });
323
+ await adapter.listToolkitCatalog({ principalId: LOCAL_OWNER_PRINCIPAL });
324
+ await ensureComposioBackend(resolver);
325
+ if (replaceBackendId) {
326
+ const backend = getComposioBackend(replaceBackendId);
327
+ if (!backend || backend.mode !== "byok" || !backend.credential_ref) throw new Error("Unknown Composio project.");
328
+ if (backend.credential_source === "environment") throw new Error("Update this key in the gateway environment, or add a locally stored project.");
329
+ await adapter.verifyConnections(listConnectorConnections({ principalId: LOCAL_OWNER_PRINCIPAL }).filter((connection) => getConnectorAccount(connection.accountId)?.backendId === backend.id && connection.status !== "revoked"));
330
+ await resolver.saveApiKey(backend.credential_ref, normalized, { profileName: "default" });
331
+ markComposioBackendVerified(backend.id);
332
+ return;
333
+ }
334
+ for (const backend of listComposioBackends()) if (backend.mode === "byok" && await resolveBackendKey(backend, resolver) === normalized) {
335
+ activateComposioBackend(backend.id);
336
+ return;
337
+ }
338
+ const id = randomUUID();
339
+ const credentialRef = `connector-composio-${id}`;
340
+ await resolver.saveApiKey(credentialRef, normalized, { profileName: "default" });
341
+ addComposioBackend({
342
+ id,
343
+ mode: "byok",
344
+ label: `Composio · ${id.slice(0, 6)}`,
345
+ credentialRef
346
+ });
347
+ markComposioBackendVerified(id);
348
+ activateComposioBackend(id);
363
349
  }
364
350
  async function listComposioConnections(resolver = new CredentialResolver()) {
365
- await new ComposioSessionsAdapter({ resolver }).syncConnections({ principalId: LOCAL_OWNER_PRINCIPAL });
351
+ const adapter = new ComposioSessionsAdapter({ resolver });
352
+ const verified = new Set((await adapter.syncConnections({ principalId: LOCAL_OWNER_PRINCIPAL })).map((connection) => connection.id));
366
353
  const connections = listConnectorConnections({ principalId: LOCAL_OWNER_PRINCIPAL }).filter((connection) => connection.provider === "composio");
367
354
  for (const accountId of new Set(connections.flatMap((connection) => connection.accountId ? [connection.accountId] : []))) refreshConnectorAccountCurrent(accountId);
368
- return connections.map(toComposioConnection);
355
+ return connections.map((connection) => toComposioConnection(verified.has(connection.id) || connection.status !== "active" ? connection : {
356
+ ...connection,
357
+ status: "unknown"
358
+ }));
369
359
  }
370
360
  async function inspectComposioConnectorHealth(toolkit, resolver = new CredentialResolver()) {
371
361
  const normalizedToolkit = normalizeToolkit(toolkit);
372
362
  try {
373
- await assertComposioAccessConfigured(resolver);
363
+ if (!listConnectorConnections({ principalId: LOCAL_OWNER_PRINCIPAL }).length) await assertComposioAccessConfigured(resolver);
374
364
  const connections = (await listComposioConnections(resolver)).filter((connection) => connection.toolkit.toLowerCase() === normalizedToolkit);
375
365
  const byAccount = /* @__PURE__ */ new Map();
376
366
  for (const connection of connections) {
@@ -422,7 +412,11 @@ async function inspectComposioConnectorHealth(toolkit, resolver = new Credential
422
412
  }
423
413
  }
424
414
  async function getComposioToolkitAuthState(toolkit, resolver = new CredentialResolver()) {
425
- return new ComposioSessionsAdapter({ resolver }).getToolkitAuthState(normalizeToolkit(toolkit));
415
+ const backend = await ensureComposioBackend(resolver);
416
+ return {
417
+ ...await new ComposioSessionsAdapter({ resolver }).getToolkitAuthState(normalizeToolkit(toolkit)),
418
+ mode: backend.mode
419
+ };
426
420
  }
427
421
  function classifyComposioHealthError(error) {
428
422
  const message = error instanceof Error ? error.message : String(error);
@@ -464,7 +458,7 @@ function getComposioInstallationPolicy(config, toolkit) {
464
458
  allowedAgentIds: existing?.allowedAgentIds ?? [],
465
459
  maxScope: getComposioToolkitScope(config, normalizedToolkit),
466
460
  confirmationPolicy: existing?.confirmationPolicy ?? "writes",
467
- selectedConnectionIds: existing?.selectedConnectionIds ?? [],
461
+ selectedAccountIds: existing?.selectedAccountIds ?? null,
468
462
  createdAt: existing?.createdAt
469
463
  });
470
464
  }
@@ -474,16 +468,16 @@ function updateComposioInstallationPolicy(config, toolkit, patch) {
474
468
  ...current,
475
469
  allowedAgentIds: patch.allowedAgentIds ?? current.allowedAgentIds,
476
470
  confirmationPolicy: patch.confirmationPolicy ?? current.confirmationPolicy,
477
- selectedConnectionIds: patch.selectedConnectionIds ?? current.selectedConnectionIds
471
+ selectedAccountIds: patch.selectedAccountIds === void 0 ? current.selectedAccountIds : patch.selectedAccountIds
478
472
  });
479
473
  }
480
474
  function updateComposioConnection(id, patch) {
481
475
  const connection = getConnectorConnection(id);
482
476
  if (!connection || connection.provider !== "composio" || connection.principalId !== LOCAL_OWNER_PRINCIPAL) throw new Error("Composio connection not found.");
477
+ if (connection.accountId && patch.alias !== void 0) updateConnectorAccount(connection.accountId, { label: patch.alias });
483
478
  upsertConnectorConnection({
484
479
  ...connection,
485
- alias: patch.alias === void 0 ? connection.alias : patch.alias.trim() || void 0,
486
- isDefault: patch.isDefault ?? connection.isDefault
480
+ alias: patch.alias === void 0 ? connection.alias : patch.alias.trim() || void 0
487
481
  });
488
482
  return toComposioConnection(getConnectorConnection(id));
489
483
  }
@@ -509,6 +503,7 @@ async function startComposioAuthorize(connectorId, toolkit, resolver = new Crede
509
503
  if (!authorization.connectUrl) throw new Error("Composio authorize did not return a connect URL.");
510
504
  return {
511
505
  toolkit: authorization.toolkit,
506
+ attemptId: authorization.attemptId,
512
507
  connectUrl: authorization.connectUrl,
513
508
  connectionId: authorization.connectionId
514
509
  };
@@ -558,24 +553,13 @@ async function executeComposioTool(params, resolver = new CredentialResolver())
558
553
  if (allowed.ok === false) throw new Error(allowed.reason);
559
554
  if (!allowed.toolkit) throw new Error(`Unknown Composio toolkit for action: ${params.slug}`);
560
555
  const connectorId = `composio-${allowed.toolkit}`;
561
- const installation = upsertConnectorInstallation({
562
- id: `${connectorId}-${LOCAL_OWNER_PRINCIPAL}`,
563
- connectorId,
564
- principalId: LOCAL_OWNER_PRINCIPAL,
565
- enabled: true,
566
- allowedAgentIds: [],
567
- maxScope: getComposioToolkitScope(params.config, allowed.toolkit),
568
- confirmationPolicy: "writes",
569
- selectedConnectionIds: []
570
- });
571
- const connection = listConnectorConnections({
572
- principalId: LOCAL_OWNER_PRINCIPAL,
573
- connectorId
574
- }).find((candidate) => candidate.status === "active" && candidate.isDefault) ?? listConnectorConnections({
575
- principalId: LOCAL_OWNER_PRINCIPAL,
576
- connectorId
577
- }).find((candidate) => candidate.status === "active");
578
- const result = await new ComposioSessionsAdapter({ resolver }).executeWithPolicy({
556
+ const installation = getConnectorInstallation(`${connectorId}-${LOCAL_OWNER_PRINCIPAL}`);
557
+ if (!installation) throw new Error("Connector policy is unavailable.");
558
+ const adapter = new ComposioSessionsAdapter({ resolver });
559
+ const connections = currentAccountConnections((await adapter.syncConnections({ principalId: LOCAL_OWNER_PRINCIPAL })).filter((candidate) => canAccessConnectorAccount(candidate, installation)));
560
+ const connection = params.accountId ? connections.find((candidate) => candidate.accountId === params.accountId) : connections.length === 1 ? connections[0] : void 0;
561
+ if (!connection) throw new Error("Select an available account explicitly.");
562
+ const result = await adapter.executeWithPolicy({
579
563
  context: {
580
564
  principalId: LOCAL_OWNER_PRINCIPAL,
581
565
  toolkits: [allowed.toolkit],
@@ -592,10 +576,10 @@ async function executeComposioTool(params, resolver = new CredentialResolver())
592
576
  cachedAt: (/* @__PURE__ */ new Date()).toISOString()
593
577
  },
594
578
  args: params.arguments && typeof params.arguments === "object" && !Array.isArray(params.arguments) ? params.arguments : {},
595
- confirmed: true
579
+ confirmed: false
596
580
  });
597
581
  if (result.decision !== "allowed") throw new Error(result.reason);
598
582
  return result.result;
599
583
  }
600
584
  //#endregion
601
- export { COMPOSIO_CONNECTORS, canUseComposioAction, configureComposioApiKey, executeComposioTool, getComposioInstallationPolicy, getComposioToolkitAuthState, getComposioToolkitScope, getConfiguredComposioAuthConfigs, inspectComposioConnectorHealth, isComposioActionAllowedByCatalog, listComposioConnections, listComposioTools, refreshComposioConnection, revokeComposioConnection, saveComposioApiKey, scopeForComposioAction, setComposioToolkitScope, startComposioAuthorize, toolkitFromComposioSlug, updateComposioConnection, updateComposioInstallationPolicy };
585
+ export { COMPOSIO_CONNECTORS, canUseComposioAction, configureComposioApiKey, executeComposioTool, getComposioInstallationPolicy, getComposioToolkitAuthState, getComposioToolkitScope, getConfiguredComposioAuthConfigs, inspectComposioConnectorHealth, isComposioActionAllowedByCatalog, listComposioConnections, listComposioTools, refreshComposioConnection, revokeComposioConnection, scopeForComposioAction, setComposioToolkitScope, startComposioAuthorize, toolkitFromComposioSlug, updateComposioConnection, updateComposioInstallationPolicy };