@truefoundry/trueforge 0.1.2 → 0.1.4-rc.0

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 (164) hide show
  1. package/dist/_frontend/assets/{ConnectorSettings-XEO5ZQO5-BXis0tQK.js → ConnectorSettings-ODC3LVHN-jhiXpbVc.js} +1 -1
  2. package/dist/_frontend/assets/ConnectorSettings-ODC3LVHN-jhiXpbVc.js.br +0 -0
  3. package/dist/_frontend/assets/ConnectorSettings-ODC3LVHN-jhiXpbVc.js.gz +0 -0
  4. package/dist/_frontend/assets/{DockLayout-F2KYSY4U-D8P84kCr.js → DockLayout-2RWDSUKE-DY3y3Is3.js} +1 -1
  5. package/dist/_frontend/assets/{DrawerLayout-FJ7XC2FU-ChH-Qykr.js → DrawerLayout-CZLJYMIN-BYncSNoi.js} +2 -2
  6. package/dist/_frontend/assets/DrawerLayout-CZLJYMIN-BYncSNoi.js.br +0 -0
  7. package/dist/_frontend/assets/DrawerLayout-CZLJYMIN-BYncSNoi.js.gz +0 -0
  8. package/dist/_frontend/assets/{ModelSettings-2QB7LE22-CDZku4g3.js → ModelSettings-CKQ5CVAC-DxQtYKup.js} +1 -1
  9. package/dist/_frontend/assets/ModelSettings-CKQ5CVAC-DxQtYKup.js.br +0 -0
  10. package/dist/_frontend/assets/ModelSettings-CKQ5CVAC-DxQtYKup.js.gz +0 -0
  11. package/dist/_frontend/assets/{SandboxSettings-QDDIPRBP-CImJLa0r.js → SandboxSettings-HSCPYUOC-DMFf-U04.js} +1 -1
  12. package/dist/_frontend/assets/SandboxSettings-HSCPYUOC-DMFf-U04.js.br +0 -0
  13. package/dist/_frontend/assets/SandboxSettings-HSCPYUOC-DMFf-U04.js.gz +0 -0
  14. package/dist/_frontend/assets/SettingsBuilder-MYWRFXRI-C4p8uaXT.js +2 -0
  15. package/dist/_frontend/assets/SettingsBuilder-MYWRFXRI-C4p8uaXT.js.br +0 -0
  16. package/dist/_frontend/assets/SettingsBuilder-MYWRFXRI-C4p8uaXT.js.gz +0 -0
  17. package/dist/_frontend/assets/{ShellRouteSync-T4WLY57Q-CetHx5EA.js → ShellRouteSync-T4WLY57Q-BC8a0ojU.js} +1 -1
  18. package/dist/_frontend/assets/ShellRouteSync-T4WLY57Q-BC8a0ojU.js.br +0 -0
  19. package/dist/_frontend/assets/ShellRouteSync-T4WLY57Q-BC8a0ojU.js.gz +0 -0
  20. package/dist/_frontend/assets/{SidebarLayout-KX6RSJTP-B8G4CTTb.js → SidebarLayout-WVY54TGZ-Ds7NVk-f.js} +2 -2
  21. package/dist/_frontend/assets/SidebarLayout-WVY54TGZ-Ds7NVk-f.js.br +0 -0
  22. package/dist/_frontend/assets/SidebarLayout-WVY54TGZ-Ds7NVk-f.js.gz +0 -0
  23. package/dist/_frontend/assets/{SkillSettings-5EETEEDI-DbJE0Ms2.js → SkillSettings-ECH6SHZ7-BtdCmc6B.js} +1 -1
  24. package/dist/_frontend/assets/SkillSettings-ECH6SHZ7-BtdCmc6B.js.br +0 -0
  25. package/dist/_frontend/assets/SkillSettings-ECH6SHZ7-BtdCmc6B.js.gz +0 -0
  26. package/dist/_frontend/assets/{TrueForgeUIWithRouter-IAQQTD5V-9G1rELmh.js → TrueForgeUIWithRouter-RKZ2E7PV-vF7U7cGf.js} +1 -1
  27. package/dist/_frontend/assets/{WidgetLayout-S6EK62TZ-BPf7T3wa.js → WidgetLayout-NWWB2SXI-DJtuM33Y.js} +1 -1
  28. package/dist/_frontend/assets/WidgetLayout-NWWB2SXI-DJtuM33Y.js.br +0 -0
  29. package/dist/_frontend/assets/WidgetLayout-NWWB2SXI-DJtuM33Y.js.gz +0 -0
  30. package/dist/_frontend/assets/{chunk-62JRHF6Z-BUuLA42_.js → chunk-62JRHF6Z-TG4aaXok.js} +1 -1
  31. package/dist/_frontend/assets/chunk-62JRHF6Z-TG4aaXok.js.br +0 -0
  32. package/dist/_frontend/assets/chunk-62JRHF6Z-TG4aaXok.js.gz +0 -0
  33. package/dist/_frontend/assets/{chunk-X6U2Q7X5-DDlfUle1.js → chunk-OZTNBS6V-axorP9qO.js} +1 -1
  34. package/dist/_frontend/assets/chunk-OZTNBS6V-axorP9qO.js.br +0 -0
  35. package/dist/_frontend/assets/chunk-OZTNBS6V-axorP9qO.js.gz +0 -0
  36. package/dist/_frontend/assets/{chunk-PTYEOSHT-C4gdhLwo.js → chunk-TCAVLWYL-BXtNAtCy.js} +2 -2
  37. package/dist/_frontend/assets/chunk-TCAVLWYL-BXtNAtCy.js.br +0 -0
  38. package/dist/_frontend/assets/chunk-TCAVLWYL-BXtNAtCy.js.gz +0 -0
  39. package/dist/_frontend/assets/{cssMode-C1whwlDW.js → cssMode-yEIs6GIw.js} +1 -1
  40. package/dist/_frontend/assets/cssMode-yEIs6GIw.js.br +0 -0
  41. package/dist/_frontend/assets/cssMode-yEIs6GIw.js.gz +0 -0
  42. package/dist/_frontend/assets/{freemarker2-CaMIS9bY.js → freemarker2-aDGnYU8i.js} +1 -1
  43. package/dist/_frontend/assets/freemarker2-aDGnYU8i.js.br +0 -0
  44. package/dist/_frontend/assets/freemarker2-aDGnYU8i.js.gz +0 -0
  45. package/dist/_frontend/assets/{handlebars-Donx2d9H.js → handlebars-B6ny31dN.js} +1 -1
  46. package/dist/_frontend/assets/handlebars-B6ny31dN.js.br +0 -0
  47. package/dist/_frontend/assets/handlebars-B6ny31dN.js.gz +0 -0
  48. package/dist/_frontend/assets/{html-CtI8kZ6e.js → html-D7u-MYoP.js} +1 -1
  49. package/dist/_frontend/assets/html-D7u-MYoP.js.br +0 -0
  50. package/dist/_frontend/assets/html-D7u-MYoP.js.gz +0 -0
  51. package/dist/_frontend/assets/{htmlMode-B6ky8VkF.js → htmlMode-kNcFDXKs.js} +1 -1
  52. package/dist/_frontend/assets/htmlMode-kNcFDXKs.js.br +0 -0
  53. package/dist/_frontend/assets/htmlMode-kNcFDXKs.js.gz +0 -0
  54. package/dist/_frontend/assets/{index-DFmgzNuj.js → index-CLJuaUhx.js} +3 -3
  55. package/dist/_frontend/assets/index-CLJuaUhx.js.br +0 -0
  56. package/dist/_frontend/assets/index-CLJuaUhx.js.gz +0 -0
  57. package/dist/_frontend/assets/{index-DWr7ad72.js → index-D1GDH6ia.js} +122 -122
  58. package/dist/_frontend/assets/index-D1GDH6ia.js.br +0 -0
  59. package/dist/_frontend/assets/index-D1GDH6ia.js.gz +0 -0
  60. package/dist/_frontend/assets/{javascript-BDngdIws.js → javascript-BLSK7s1P.js} +1 -1
  61. package/dist/_frontend/assets/{jsonMode-B7OogXWW.js → jsonMode-XHJKWC_S.js} +1 -1
  62. package/dist/_frontend/assets/jsonMode-XHJKWC_S.js.br +0 -0
  63. package/dist/_frontend/assets/jsonMode-XHJKWC_S.js.gz +0 -0
  64. package/dist/_frontend/assets/{liquid-D_8RkuUW.js → liquid-Db1WZdZB.js} +1 -1
  65. package/dist/_frontend/assets/liquid-Db1WZdZB.js.br +0 -0
  66. package/dist/_frontend/assets/liquid-Db1WZdZB.js.gz +0 -0
  67. package/dist/_frontend/assets/{lspLanguageFeatures-DJf8_W2N.js → lspLanguageFeatures-BFyBtl8M.js} +1 -1
  68. package/dist/_frontend/assets/lspLanguageFeatures-BFyBtl8M.js.br +0 -0
  69. package/dist/_frontend/assets/lspLanguageFeatures-BFyBtl8M.js.gz +0 -0
  70. package/dist/_frontend/assets/{mdx-HcpZSZ2w.js → mdx-DtFWu4ex.js} +1 -1
  71. package/dist/_frontend/assets/mdx-DtFWu4ex.js.br +0 -0
  72. package/dist/_frontend/assets/mdx-DtFWu4ex.js.gz +0 -0
  73. package/dist/_frontend/assets/{python-CPiT1vB4.js → python-2R7BOup6.js} +1 -1
  74. package/dist/_frontend/assets/python-2R7BOup6.js.br +0 -0
  75. package/dist/_frontend/assets/python-2R7BOup6.js.gz +0 -0
  76. package/dist/_frontend/assets/{razor-oizHS-vq.js → razor-DQLxdj72.js} +1 -1
  77. package/dist/_frontend/assets/razor-DQLxdj72.js.br +0 -0
  78. package/dist/_frontend/assets/razor-DQLxdj72.js.gz +0 -0
  79. package/dist/_frontend/assets/{tsMode-n5kkpKJX.js → tsMode-Ctn4PuNt.js} +1 -1
  80. package/dist/_frontend/assets/tsMode-Ctn4PuNt.js.br +0 -0
  81. package/dist/_frontend/assets/tsMode-Ctn4PuNt.js.gz +0 -0
  82. package/dist/_frontend/assets/{typescript-BfXupYGq.js → typescript-DGwzICBa.js} +1 -1
  83. package/dist/_frontend/assets/typescript-DGwzICBa.js.br +0 -0
  84. package/dist/_frontend/assets/typescript-DGwzICBa.js.gz +0 -0
  85. package/dist/_frontend/assets/{workers-DCX6qMOc.js → workers-CRRTWuKZ.js} +1 -1
  86. package/dist/_frontend/assets/workers-CRRTWuKZ.js.br +0 -0
  87. package/dist/_frontend/assets/workers-CRRTWuKZ.js.gz +0 -0
  88. package/dist/_frontend/assets/{xml-MX-qfsGl.js → xml-CFZg-QqB.js} +1 -1
  89. package/dist/_frontend/assets/xml-CFZg-QqB.js.br +0 -0
  90. package/dist/_frontend/assets/xml-CFZg-QqB.js.gz +0 -0
  91. package/dist/_frontend/assets/{yaml-DnKyyO9e.js → yaml-DUIIx9CV.js} +1 -1
  92. package/dist/_frontend/assets/yaml-DUIIx9CV.js.br +0 -0
  93. package/dist/_frontend/assets/yaml-DUIIx9CV.js.gz +0 -0
  94. package/dist/_frontend/index.html +1 -1
  95. package/dist/_frontend/index.html.br +0 -0
  96. package/dist/_frontend/index.html.gz +0 -0
  97. package/dist/main.js +2198 -519
  98. package/dist/main.js.map +1 -1
  99. package/dist/postgres/migrations/20260818_000001_mcp_pending_auth_return_to.js +17 -0
  100. package/dist/postgres/migrations/20260818_000001_mcp_pending_auth_return_to.js.map +1 -0
  101. package/dist/sqlite/migrations/20260818_000001_mcp_pending_auth_return_to.js +19 -0
  102. package/dist/sqlite/migrations/20260818_000001_mcp_pending_auth_return_to.js.map +1 -0
  103. package/package.json +10 -4
  104. package/dist/_frontend/assets/ConnectorSettings-XEO5ZQO5-BXis0tQK.js.br +0 -0
  105. package/dist/_frontend/assets/ConnectorSettings-XEO5ZQO5-BXis0tQK.js.gz +0 -0
  106. package/dist/_frontend/assets/DrawerLayout-FJ7XC2FU-ChH-Qykr.js.br +0 -0
  107. package/dist/_frontend/assets/DrawerLayout-FJ7XC2FU-ChH-Qykr.js.gz +0 -0
  108. package/dist/_frontend/assets/ModelSettings-2QB7LE22-CDZku4g3.js.br +0 -0
  109. package/dist/_frontend/assets/ModelSettings-2QB7LE22-CDZku4g3.js.gz +0 -0
  110. package/dist/_frontend/assets/SandboxSettings-QDDIPRBP-CImJLa0r.js.br +0 -0
  111. package/dist/_frontend/assets/SandboxSettings-QDDIPRBP-CImJLa0r.js.gz +0 -0
  112. package/dist/_frontend/assets/SettingsBuilder-4NF3Y7UZ-eXXDLQ6k.js +0 -2
  113. package/dist/_frontend/assets/SettingsBuilder-4NF3Y7UZ-eXXDLQ6k.js.br +0 -0
  114. package/dist/_frontend/assets/SettingsBuilder-4NF3Y7UZ-eXXDLQ6k.js.gz +0 -0
  115. package/dist/_frontend/assets/ShellRouteSync-T4WLY57Q-CetHx5EA.js.br +0 -0
  116. package/dist/_frontend/assets/ShellRouteSync-T4WLY57Q-CetHx5EA.js.gz +0 -0
  117. package/dist/_frontend/assets/SidebarLayout-KX6RSJTP-B8G4CTTb.js.br +0 -0
  118. package/dist/_frontend/assets/SidebarLayout-KX6RSJTP-B8G4CTTb.js.gz +0 -0
  119. package/dist/_frontend/assets/SkillSettings-5EETEEDI-DbJE0Ms2.js.br +0 -0
  120. package/dist/_frontend/assets/SkillSettings-5EETEEDI-DbJE0Ms2.js.gz +0 -0
  121. package/dist/_frontend/assets/WidgetLayout-S6EK62TZ-BPf7T3wa.js.br +0 -0
  122. package/dist/_frontend/assets/WidgetLayout-S6EK62TZ-BPf7T3wa.js.gz +0 -0
  123. package/dist/_frontend/assets/chunk-62JRHF6Z-BUuLA42_.js.br +0 -0
  124. package/dist/_frontend/assets/chunk-62JRHF6Z-BUuLA42_.js.gz +0 -0
  125. package/dist/_frontend/assets/chunk-PTYEOSHT-C4gdhLwo.js.br +0 -0
  126. package/dist/_frontend/assets/chunk-PTYEOSHT-C4gdhLwo.js.gz +0 -0
  127. package/dist/_frontend/assets/chunk-X6U2Q7X5-DDlfUle1.js.br +0 -0
  128. package/dist/_frontend/assets/chunk-X6U2Q7X5-DDlfUle1.js.gz +0 -0
  129. package/dist/_frontend/assets/cssMode-C1whwlDW.js.br +0 -0
  130. package/dist/_frontend/assets/cssMode-C1whwlDW.js.gz +0 -0
  131. package/dist/_frontend/assets/freemarker2-CaMIS9bY.js.br +0 -0
  132. package/dist/_frontend/assets/freemarker2-CaMIS9bY.js.gz +0 -0
  133. package/dist/_frontend/assets/handlebars-Donx2d9H.js.br +0 -0
  134. package/dist/_frontend/assets/handlebars-Donx2d9H.js.gz +0 -0
  135. package/dist/_frontend/assets/html-CtI8kZ6e.js.br +0 -0
  136. package/dist/_frontend/assets/html-CtI8kZ6e.js.gz +0 -0
  137. package/dist/_frontend/assets/htmlMode-B6ky8VkF.js.br +0 -0
  138. package/dist/_frontend/assets/htmlMode-B6ky8VkF.js.gz +0 -0
  139. package/dist/_frontend/assets/index-DFmgzNuj.js.br +0 -0
  140. package/dist/_frontend/assets/index-DFmgzNuj.js.gz +0 -0
  141. package/dist/_frontend/assets/index-DWr7ad72.js.br +0 -0
  142. package/dist/_frontend/assets/index-DWr7ad72.js.gz +0 -0
  143. package/dist/_frontend/assets/jsonMode-B7OogXWW.js.br +0 -0
  144. package/dist/_frontend/assets/jsonMode-B7OogXWW.js.gz +0 -0
  145. package/dist/_frontend/assets/liquid-D_8RkuUW.js.br +0 -0
  146. package/dist/_frontend/assets/liquid-D_8RkuUW.js.gz +0 -0
  147. package/dist/_frontend/assets/lspLanguageFeatures-DJf8_W2N.js.br +0 -0
  148. package/dist/_frontend/assets/lspLanguageFeatures-DJf8_W2N.js.gz +0 -0
  149. package/dist/_frontend/assets/mdx-HcpZSZ2w.js.br +0 -0
  150. package/dist/_frontend/assets/mdx-HcpZSZ2w.js.gz +0 -0
  151. package/dist/_frontend/assets/python-CPiT1vB4.js.br +0 -0
  152. package/dist/_frontend/assets/python-CPiT1vB4.js.gz +0 -0
  153. package/dist/_frontend/assets/razor-oizHS-vq.js.br +0 -0
  154. package/dist/_frontend/assets/razor-oizHS-vq.js.gz +0 -0
  155. package/dist/_frontend/assets/tsMode-n5kkpKJX.js.br +0 -0
  156. package/dist/_frontend/assets/tsMode-n5kkpKJX.js.gz +0 -0
  157. package/dist/_frontend/assets/typescript-BfXupYGq.js.br +0 -0
  158. package/dist/_frontend/assets/typescript-BfXupYGq.js.gz +0 -0
  159. package/dist/_frontend/assets/workers-DCX6qMOc.js.br +0 -0
  160. package/dist/_frontend/assets/workers-DCX6qMOc.js.gz +0 -0
  161. package/dist/_frontend/assets/xml-MX-qfsGl.js.br +0 -0
  162. package/dist/_frontend/assets/xml-MX-qfsGl.js.gz +0 -0
  163. package/dist/_frontend/assets/yaml-DnKyyO9e.js.br +0 -0
  164. package/dist/_frontend/assets/yaml-DnKyyO9e.js.gz +0 -0
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/db/agentStore.ts","../src/config.ts","../src/db/mcpServerStore.ts","../src/db/modelProviderStore.ts","../src/db/skillStore.ts","../src/db/sqlite/client.ts","../src/db/migrateSqlite.ts","../src/db/sqlite/sqlExpressions.ts","../src/db/sqlite/session-store/sqlExpressions.ts","../src/db/sqlite/session-store/queries/turns.ts","../src/db/sqlite/session-store/queries/capabilities.ts","../src/db/sqlite/session-store/queries/events.ts","../src/db/sessionAgentColumns.ts","../src/db/sqlite/session-store/queries/sessions.ts","../src/db/sqlite/session-store/queries/threads.ts","../src/db/sqlite/session-store/SqliteSessionStore.ts","../src/db/sqlite/model-provider-store/SqliteModelProviderStore.ts","../src/db/sqlite/mcp-server-store/SqliteMcpServerStore.ts","../src/db/sqlite/token-store/queries/pendingAuthorization.ts","../src/db/sqlite/token-store/queries/token.ts","../src/db/sqlite/token-store/SqliteOAuthTokenStore.ts","../src/db/sqlite/skill-store/SqliteSkillStore.ts","../src/db/sqlite/sandbox-provider-store/SqliteSandboxProviderStore.ts","../src/db/sqlite/agent-store/SqliteAgentStore.ts","../src/db/postgres/client.ts","../src/db/migratePostgres.ts","../src/runtime/redis.ts","../src/db/postgres/sqlExpressions.ts","../src/db/postgres/session-store/sqlExpressions.ts","../src/db/postgres/session-store/queries/turns.ts","../src/db/postgres/session-store/queries/capabilities.ts","../src/db/postgres/session-store/queries/events.ts","../src/db/postgres/session-store/queries/sessions.ts","../src/db/postgres/session-store/queries/threads.ts","../src/db/postgres/session-store/PostgresSessionStore.ts","../src/db/postgres/model-provider-store/PostgresModelProviderStore.ts","../src/db/postgres/mcp-server-store/PostgresMcpServerStore.ts","../src/db/postgres/token-store/queries/pendingAuthorization.ts","../src/db/postgres/token-store/queries/token.ts","../src/db/postgres/token-store/PostgresOAuthTokenStore.ts","../src/db/postgres/skill-store/PostgresSkillStore.ts","../src/db/postgres/sandbox-provider-store/PostgresSandboxProviderStore.ts","../src/db/postgres/agent-store/PostgresAgentStore.ts","../src/main.ts","../src/app.ts","../src/apis/agents.ts","../src/routes/agentRoutes.ts","../src/schemas/agent.ts","../src/schemas/common.ts","../src/schemas/errors.ts","../src/runtime/sessionResources.ts","../src/mcp/auth/mcpDcr.ts","../src/mcp/auth/mcpOAuthHelpers.ts","../src/sandbox/providerUtils.ts","../src/schemas/sandboxProvider.ts","../src/schemas/mcpServer.ts","../src/apis/sessions.ts","../src/routes/sessionRoutes.ts","../src/schemas/events.ts","../src/schemas/session.ts","../src/schemas/turn.ts","../src/routes/fernExtensions.ts","../src/runtime/peeringIds.ts","../src/apis/auth.ts","../src/auth/cookies.ts","../src/auth/oidc.ts","../src/auth/claims.ts","../src/auth/identity.ts","../src/auth/middleware.ts","../src/routes/authRoutes.ts","../src/schemas/auth.ts","../src/apis/capabilities.ts","../src/routes/capabilityRoutes.ts","../src/apis/catalog.ts","../src/routes/catalogRoutes.ts","../src/schemas/mcpCatalog.ts","../src/schemas/modelCatalog.ts","../src/schemas/modelProvider.ts","../src/schemas/sandboxCatalog.ts","../src/schemas/skillCatalog.ts","../src/schemas/skill.ts","../src/apis/mcpOAuth.ts","../src/routes/mcpOAuthRoutes.ts","../src/apis/mcpServers.ts","../src/routes/mcpServerRoutes.ts","../src/utils/secretRedaction.ts","../src/apis/models.ts","../src/routes/modelRoutes.ts","../src/apis/settings.ts","../src/apis/modelProviders.ts","../src/routes/modelProviderRoutes.ts","../src/apis/sandboxProviders.ts","../src/routes/sandboxProviderRoutes.ts","../src/apis/skills.ts","../src/routes/skillRoutes.ts","../src/apis/turns.ts","../src/routes/turnRoutes.ts","../src/runtime/event-subscription/inMemory.ts","../src/runtime/event-subscription/redis.ts","../src/runtime/event-subscription/index.ts","../src/runtime/sandboxFilePath.ts","../src/packageVersion.ts","../src/zodErrorResponse.ts","../src/catalog/McpCatalog.ts","../src/catalog/loadYaml.ts","../src/catalog/mcpCatalog.gen.ts","../src/catalog/ModelCatalog.ts","../src/catalog/modelCatalog.gen.ts","../src/catalog/SandboxCatalog.ts","../src/catalog/sandboxCatalog.gen.ts","../src/catalog/SkillCatalog.ts","../src/catalog/skillCatalog.gen.ts","../src/frontend.ts","../src/logger.ts","../src/runtime/activeTurns.ts","../src/startupBanner.ts"],"sourcesContent":["/**\n * DB-backed configured agents: one row per agent per tenant,\n * immutable ULID `id`, unique immutable `name` within a tenant, plus a Zod-validated\n * `AgentSpec` jsonb document.\n * Implementations: PostgresAgentStore and SqliteAgentStore.\n */\nimport { AgentSpecSchema, type AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport type { ResourceName } from '../schemas/common';\n\nexport interface AgentRecord {\n id: string;\n tenant_id: string;\n name: ResourceName;\n manifest: AgentSpec;\n /** ISO-8601 UTC instant. */\n created_at: string;\n /** ISO-8601 UTC instant. */\n updated_at: string;\n}\n\n/**\n * Re-parse persisted manifest JSON so schema defaults (e.g. nested `config`) materialize.\n * Rows written before a config field existed omit it on disk; readers must not assume presence.\n */\nexport function parseStoredAgentSpec(manifest: unknown): AgentSpec {\n return AgentSpecSchema.parse(manifest);\n}\n\n/** Look up by immutable id or unique name within a tenant. */\nexport type GetAgentInput = { tenant_id: string } & ({ id: string } | { name: string });\n\nexport interface CreateAgentInput {\n tenant_id: string;\n name: ResourceName;\n manifest: AgentSpec;\n}\n\n/** Replace manifest for an existing agent keyed by immutable id. */\nexport interface UpdateAgentInput {\n tenant_id: string;\n id: string;\n manifest: AgentSpec;\n}\n\nexport interface DeleteAgentInput {\n tenant_id: string;\n id: string;\n}\n\n/** Unique `(tenant_id, name)` violation on create. */\nexport class AgentNameConflictError extends Error {\n readonly tenant_id: string;\n readonly agent_name: string;\n\n constructor({ tenant_id, name }: { tenant_id: string; name: string }, options?: ErrorOptions) {\n super(`Agent name already exists: ${name}`, options);\n this.name = 'AgentNameConflictError';\n this.tenant_id = tenant_id;\n this.agent_name = name;\n }\n}\n\nexport interface IAgentStore<TTransaction = never> {\n listAgents(tenantId: string, transaction?: TTransaction): Promise<AgentRecord[]>;\n getAgent(input: GetAgentInput, transaction?: TTransaction): Promise<AgentRecord | undefined>;\n /** Inserts a new agent with a generated ULID. Throws AgentNameConflictError on name clash. */\n createAgent(input: CreateAgentInput, transaction?: TTransaction): Promise<AgentRecord>;\n /** Replaces `manifest` for an existing id. Returns undefined if missing. */\n updateAgent(input: UpdateAgentInput, transaction?: TTransaction): Promise<AgentRecord | undefined>;\n /** Deletes by immutable id. Idempotent if already missing. */\n deleteAgent(input: DeleteAgentInput, transaction?: TTransaction): Promise<void>;\n}\n","/**\n * Server configuration.\n *\n * Environment variables are read once at module load into a typed\n * `configuration` object exported as default. Any invalid value throws at\n * import time, so a misconfigured server fails fast at boot instead of\n * mid-run.\n *\n * `STANDALONE` is a discriminated mode selector:\n * - `true` (default): SQLite only; no Redis / executor peering.\n * - `false`: Postgres + Redis (defaults to local trueforge credentials /\n * `redis://localhost:6379`).\n */\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport envPaths from 'env-paths';\n\nconst DEFAULT_PORT = 8790;\n/** Loopback default; container images set HOST=0.0.0.0 so probes and Service traffic reach the process. */\nconst DEFAULT_HOST = 'localhost';\n/** Default HTTP request body ceiling: 30 MB. */\nconst DEFAULT_MAX_REQUEST_BODY_BYTES = 30 * 1024 * 1024;\n/**\n * Package root whether this module runs as `src/config.ts` (tsx) or is bundled\n * into `dist/main.js` / `dist/cli.js` (`import.meta` → `dist/` → parent).\n */\nconst PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');\n/** Turn ids minted by a standalone process; no peer can ever own them. */\nconst LOCAL_EXECUTOR_ID = 'local';\n/** OS-standard data dir for SQLite in standalone mode. */\nconst ENV_PATHS_APP_NAME = 'trueforge';\nconst DEFAULT_POSTGRES_USER = 'trueforge';\nconst DEFAULT_POSTGRES_PASSWORD = 'trueforge';\nconst DEFAULT_POSTGRES_DB = 'trueforge';\nconst DEFAULT_POSTGRES_HOST = 'localhost';\nconst DEFAULT_POSTGRES_PORT = 5432;\nconst DEFAULT_REDIS_URL = 'redis://localhost:6379';\n\nconst DEFAULT_OIDC_USER_REFERENCE_CLAIM = 'sub';\nconst DEFAULT_OIDC_USER_ROLE_CLAIM = 'groups';\nconst DEFAULT_OIDC_ADMIN_ROLE_VALUE = 'admin';\nconst DEFAULT_OIDC_SCOPES = 'openid,profile,email';\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\nexport interface GetEnvOptions {\n defaultValue?: string;\n required?: boolean;\n}\n\nfunction getEnv(key: string, options?: GetEnvOptions): string | undefined {\n const value = process.env[key];\n if (value !== undefined) {\n return value;\n }\n\n // Checking for undefined as value can also be 0 or \"\"\n if (options?.defaultValue !== undefined) {\n return options.defaultValue;\n }\n\n if (options?.required) {\n throw new Error(`Environment variable ${key} is required but was not specified.`);\n }\n\n return undefined;\n}\n\nfunction randomAlphanumeric(length: number): string {\n return Array.from({ length }, () => Math.floor(Math.random() * 36).toString(36)).join('');\n}\n\nfunction parsePort(raw: string | undefined): number {\n if (raw === undefined || raw.trim() === '') {\n return DEFAULT_PORT;\n }\n const port = Number(raw);\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`Environment variable PORT must be an integer between 1 and 65535, got \"${raw}\"`);\n }\n return port;\n}\n\nexport function parseOidcScopes(raw: string): string[] {\n const scopes = raw\n .split(',')\n .map(part => part.trim())\n .filter(part => part.length > 0);\n if (scopes.length === 0) {\n throw new Error('OIDC_SCOPES must contain at least one scope.');\n }\n return scopes;\n}\n\n/** Parses a positive-integer env var, falling back to `defaultValue` when unset/blank. */\nfunction parsePositiveInt(options: { envKey: string; raw: string | undefined; defaultValue: number }): number {\n const { envKey, raw, defaultValue } = options;\n if (raw === undefined || raw.trim() === '') {\n return defaultValue;\n }\n const value = Number(raw);\n if (!Number.isInteger(value) || value < 1) {\n throw new Error(`Environment variable ${envKey} must be a positive integer, got \"${raw}\"`);\n }\n return value;\n}\n\n/** Parses a boolean env var; anything but `true`/`false` throws instead of reading as `false`. */\nfunction parseBoolean(options: { envKey: string; raw: string | undefined; defaultValue: boolean }): boolean {\n const { envKey, raw, defaultValue } = options;\n if (raw === undefined || raw.trim() === '') {\n return defaultValue;\n }\n const value = raw.trim().toLowerCase();\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n throw new Error(`Environment variable ${envKey} must be \"true\" or \"false\", got \"${raw}\"`);\n}\n\n/**\n * Prefer `dist/_frontend` shipped in the npm tarball (npx / `pnpm start`).\n * Fall back to the monorepo sibling `../frontend/dist` (host-dev before a copy).\n */\nfunction resolveDefaultFrontendDir(): string {\n const packaged = path.join(PACKAGE_ROOT, 'dist', '_frontend');\n if (existsSync(path.join(packaged, 'index.html'))) {\n return packaged;\n }\n return path.join(PACKAGE_ROOT, '..', 'frontend', 'dist');\n}\n\nfunction resolveFrontendDir(): string {\n const override = getEnv('FRONTEND_DIR');\n if (override !== undefined && override.trim() !== '') {\n return path.resolve(override);\n }\n return resolveDefaultFrontendDir();\n}\n\n/** Absolute path from an optional env override; unset/blank → `undefined`. */\nfunction resolveOptionalPathEnv(envKey: string): string | undefined {\n const override = getEnv(envKey);\n if (override === undefined || override.trim() === '') {\n return undefined;\n }\n return path.resolve(override);\n}\n\n/**\n * Absolute SQLite file path for standalone mode.\n * Env: `SQLITE_PATH` (optional). Default: `{env-paths data}/db/db.sqlite`.\n */\nfunction resolveSqlitePath(): string {\n const override = getEnv('SQLITE_PATH');\n if (override !== undefined && override.trim() !== '') {\n return path.resolve(override);\n }\n const paths = envPaths(ENV_PATHS_APP_NAME, { suffix: '' });\n return path.join(paths.data, 'db', 'db.sqlite');\n}\n\n/** Redis peering URL for distributed mode. Env: `REDIS_URL`. */\nfunction resolveRedisUrl(): string {\n const raw = getEnv('REDIS_URL', { defaultValue: DEFAULT_REDIS_URL }) ?? DEFAULT_REDIS_URL;\n if (raw.trim() === '') {\n throw new Error('Environment variable REDIS_URL must be non-empty when STANDALONE=false.');\n }\n return raw;\n}\n\n/** Postgres connection string derived from `POSTGRES_*` for distributed mode. */\nfunction resolvePostgresDatabaseUrl(): string {\n const postgresUser = getEnv('POSTGRES_USER', { defaultValue: DEFAULT_POSTGRES_USER }) ?? DEFAULT_POSTGRES_USER;\n const postgresPassword =\n getEnv('POSTGRES_PASSWORD', { defaultValue: DEFAULT_POSTGRES_PASSWORD }) ?? DEFAULT_POSTGRES_PASSWORD;\n const postgresDb = getEnv('POSTGRES_DB', { defaultValue: DEFAULT_POSTGRES_DB }) ?? DEFAULT_POSTGRES_DB;\n const postgresHost = getEnv('POSTGRES_HOST', { defaultValue: DEFAULT_POSTGRES_HOST }) ?? DEFAULT_POSTGRES_HOST;\n const postgresPort = parsePositiveInt({\n envKey: 'POSTGRES_PORT',\n raw: getEnv('POSTGRES_PORT'),\n defaultValue: DEFAULT_POSTGRES_PORT,\n });\n if (\n postgresUser.trim() === '' ||\n postgresPassword.trim() === '' ||\n postgresDb.trim() === '' ||\n postgresHost.trim() === ''\n ) {\n throw new Error(\n 'POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, and POSTGRES_HOST must be non-empty when STANDALONE=false.',\n );\n }\n return buildPostgresConnectionString({\n user: postgresUser,\n password: postgresPassword,\n host: postgresHost,\n port: postgresPort,\n database: postgresDb,\n });\n}\n\n/** Builds a Postgres connection URL from discrete `POSTGRES_*` parts. */\nfunction buildPostgresConnectionString(parts: {\n user: string;\n password: string;\n host: string;\n port: number;\n database: string;\n}): string {\n return `postgres://${encodeURIComponent(parts.user)}:${encodeURIComponent(parts.password)}@${parts.host}:${String(parts.port)}/${encodeURIComponent(parts.database)}`;\n}\n\nfunction resolveOIDCConfig(): OIDCConfig | undefined {\n const issuerUrl = getEnv('OIDC_ISSUER_URL');\n const clientId = getEnv('OIDC_CLIENT_ID');\n const clientSecret = getEnv('OIDC_CLIENT_SECRET');\n\n if (!issuerUrl && !clientId && !clientSecret) {\n return undefined;\n }\n if (!issuerUrl || !clientId || !clientSecret) {\n throw new Error(\n 'OIDC_ISSUER_URL, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET must all be set together, or all left unset ' +\n '(unset = fixed local admin identity, no IdP).',\n );\n }\n return {\n OIDC_ISSUER_URL: issuerUrl,\n OIDC_CLIENT_ID: clientId,\n OIDC_CLIENT_SECRET: clientSecret,\n OIDC_USER_REFERENCE_CLAIM:\n getEnv('OIDC_USER_REFERENCE_CLAIM', { defaultValue: DEFAULT_OIDC_USER_REFERENCE_CLAIM }) ??\n DEFAULT_OIDC_USER_REFERENCE_CLAIM,\n OIDC_USER_ROLE_CLAIM:\n getEnv('OIDC_USER_ROLE_CLAIM', { defaultValue: DEFAULT_OIDC_USER_ROLE_CLAIM }) ?? DEFAULT_OIDC_USER_ROLE_CLAIM,\n OIDC_ADMIN_ROLE_VALUE:\n getEnv('OIDC_ADMIN_ROLE_VALUE', { defaultValue: DEFAULT_OIDC_ADMIN_ROLE_VALUE }) ?? DEFAULT_OIDC_ADMIN_ROLE_VALUE,\n OIDC_SCOPES: parseOidcScopes(getEnv('OIDC_SCOPES', { defaultValue: DEFAULT_OIDC_SCOPES }) ?? DEFAULT_OIDC_SCOPES),\n };\n}\n\n// ============================================================================\n// CONFIGURATION TYPES\n// ============================================================================\n\nexport interface OIDCConfig {\n /** e.g. an Okta custom authorization server, or an Azure AD tenant's v2.0 endpoint. Env: `OIDC_ISSUER_URL`. */\n OIDC_ISSUER_URL: string;\n /** Client ID for the OIDC client;*/\n OIDC_CLIENT_ID: string;\n /** Client secret for the OIDC client*/\n OIDC_CLIENT_SECRET: string;\n /** Claim to be used as the user reference; e.g. \"sub\" or \"email\"\n * Optional; defaults to \"sub\"\n */\n OIDC_USER_REFERENCE_CLAIM: string;\n /** Claim to be used as the user role; e.g. \"role\" or \"groups\"\n * Optional; defaults to \"groups\"\n */\n OIDC_USER_ROLE_CLAIM: string;\n /** Value of the user role claim that will be used to grant admin access to the server\n * Case sensitive. Optional; defaults to \"admin\"\n */\n OIDC_ADMIN_ROLE_VALUE: string;\n /** Comma-separated OAuth scopes for the authorization request. Env: `OIDC_SCOPES`.\n * Optional; defaults to \"openid,profile,email\". Whitespace around entries is stripped.\n * Okta `groups` claims require the `groups` scope; Azure AD app roles typically omit it.\n */\n OIDC_SCOPES: string[];\n}\n\nexport interface SharedServerConfiguration {\n /** Log level. Env: `LOG_LEVEL`. */\n LOG_LEVEL: string;\n /** Node environment. Env: `NODE_ENV`. */\n NODE_ENV: string | undefined;\n /** HTTP port the server listens on. Env: `PORT`. */\n PORT: number;\n /** HTTP bind address. Env: `HOST`. Default `localhost`; production images use `0.0.0.0`. */\n HOST: string;\n /** Peering identity embedded in the turn ids this process mints; `local` in standalone mode. */\n EXECUTOR_ID: string;\n /**\n * Optional override for the model catalog YAML (discovery presets for\n * GET /catalog/model-providers). When unset, the catalog inlined at build\n * time is used. Env: `MODEL_CATALOG_PATH`.\n */\n MODEL_CATALOG_PATH: string | undefined;\n /**\n * Optional override for the MCP catalog YAML (discovery presets for\n * GET /catalog/mcp-servers). When unset, the catalog inlined at build\n * time is used. Env: `MCP_CATALOG_PATH`.\n */\n MCP_CATALOG_PATH: string | undefined;\n /**\n * Optional override for the skill catalog YAML (discovery presets for\n * GET /catalog/skills). When unset, the catalog inlined at build\n * time is used. Env: `SKILL_CATALOG_PATH`.\n */\n SKILL_CATALOG_PATH: string | undefined;\n /**\n * Optional override for the sandbox catalog YAML (discovery presets for\n * GET /catalog/sandbox-providers). When unset, the catalog inlined at build\n * time is used. Env: `SANDBOX_CATALOG_PATH`.\n */\n SANDBOX_CATALOG_PATH: string | undefined;\n /**\n * Frontend build served alongside the API; a missing directory leaves the server API-only.\n * Env: `FRONTEND_DIR`. Default: packaged `dist/_frontend` (npx tarball) or\n * monorepo `packages/frontend/dist` — always absolute, independent of CWD.\n */\n FRONTEND_DIR: string;\n /** Max milliseconds for one MCP request. Env: `MCP_REQUEST_TIMEOUT_MS`. Default 4 minutes. */\n MCP_REQUEST_TIMEOUT_MS: number;\n /** Max milliseconds for an MCP transport connection. Env: `MCP_CONNECT_TIMEOUT_MS`. Default 30 seconds. */\n MCP_CONNECT_TIMEOUT_MS: number;\n /**\n * Client name used for Dynamic Client Registration (DCR) of MCP servers.\n * This is the client name shown on authorization-server consent screens.\n * Env: `MCP_DCR_OAUTH_CLIENT_NAME`. Default: \"truefoundry-harness\".\n */\n MCP_DCR_OAUTH_CLIENT_NAME: string;\n /**\n * Max bytes for a single file download out of the sandbox.\n * Env: `SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD`. Default 20 MB (same as gateway).\n */\n SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD: number;\n /**\n * Max bytes for an HTTP request body. Env: `MAX_REQUEST_BODY_BYTES`. Default 30 MB.\n */\n MAX_REQUEST_BODY_BYTES: number;\n /**\n * Max seconds to wait for turn cancellation + connection drain on SIGTERM/SIGINT.\n * Env: `GRACEFUL_TIMEOUT_SECONDS`. Default 30.\n */\n GRACEFUL_TIMEOUT_SECONDS: number;\n /**\n * Max seconds a single turn may execute before it is cancelled with\n * `server-execution-timeout`. Env: `SERVER_EXECUTION_TIMEOUT_SECONDS`. Default 600 (10 minutes).\n */\n SERVER_EXECUTION_TIMEOUT_SECONDS: number;\n /**\n * TTL for a running turn's resumable event stream.\n * Env: `TURN_STREAM_TTL_SECONDS`. Default execution timeout + 300.\n */\n TURN_STREAM_TTL_SECONDS: number;\n /**\n * TTL retained after `turn.done` so subscribers can drain remaining events.\n * Env: `TURN_STREAM_POST_COMPLETION_TTL_SECONDS`. Default 300.\n */\n TURN_STREAM_POST_COMPLETION_TTL_SECONDS: number;\n /**\n * Max ms to keep a turn subscription open.\n * Env: `TURN_SUBSCRIBE_TIMEOUT_MS`. Default 600000.\n */\n TURN_SUBSCRIBE_TIMEOUT_MS: number;\n /**\n * Max ms to wait for a peer executor's reply before failing with 424.\n * Env: `REDIS_REQUEST_REPLY_TIMEOUT_MS`. Default 60000.\n * Only used when a Redis client is wired (distributed mode).\n */\n REDIS_REQUEST_REPLY_TIMEOUT_MS: number;\n /**\n * How often this process refreshes its peering heartbeat key.\n * Env: `REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS`. Default 5000.\n * Only used when a Redis client is wired (distributed mode).\n */\n REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS: number;\n /**\n * TTL for reply values so abandoned reply keys are reclaimed.\n * Env: `REDIS_REQUEST_REPLY_REPLY_TTL_MS`. Default 120000.\n * Only used when a Redis client is wired (distributed mode).\n */\n REDIS_REQUEST_REPLY_REPLY_TTL_MS: number;\n /**\n * Sleep between reply poll attempts while waiting on a peer.\n * Env: `REDIS_REQUEST_REPLY_POLL_INTERVAL_MS`. Default 500.\n * Only used when a Redis client is wired (distributed mode).\n */\n REDIS_REQUEST_REPLY_POLL_INTERVAL_MS: number;\n}\n\nexport type StandaloneServerConfiguration = SharedServerConfiguration & {\n /**\n * Single-process topology: SQLite persistence, no Redis / executor peering.\n * Env: `STANDALONE`. Default: true.\n */\n STANDALONE: true;\n /**\n * Absolute SQLite database file path.\n * Env: `SQLITE_PATH` (optional). Default: env-paths data dir + `db/db.sqlite`.\n */\n SQLITE_PATH: string;\n};\n\nexport type DistributedServerConfiguration = SharedServerConfiguration & {\n /**\n * Multi-replica topology: Postgres persistence + Redis executor peering.\n * Env: `STANDALONE`. Default: true (so this branch requires an explicit `false`).\n */\n STANDALONE: false;\n /**\n * Public base URL of this server used as the origin of MCP OAuth and OIDC\n * callbacks. Optional at boot; MCP OAuth and OIDC callback construction fail\n * if empty.\n */\n PUBLIC_BASE_URL: string;\n /**\n * Postgres connection string derived from `POSTGRES_*` (not read from env directly).\n * Form: `postgres://USER:PASSWORD@HOST:PORT/DB` with user/password URL-encoded.\n */\n DATABASE_URL: string;\n /** Max connections in the `pg` Pool. Env: `DATABASE_POOL_MAX`. Default 10. */\n DATABASE_POOL_MAX: number;\n /**\n * Postgres `statement_timeout` for app and migrations (same pool).\n * Env: `POSTGRES_STATEMENT_TIMEOUT_MS`. Default 60000.\n */\n POSTGRES_STATEMENT_TIMEOUT_MS: number;\n /**\n * Postgres `idle_in_transaction_session_timeout` for app and migrations (same pool).\n * Env: `POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS`. Default 60000.\n */\n POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS: number;\n /** Peering URL shared by all replicas. Env: `REDIS_URL`. Default `redis://localhost:6379`. */\n REDIS_URL: string;\n /**\n * OIDC configuration for server authentication.\n * Undefined means browser login is disabled.\n */\n OIDC: OIDCConfig | undefined;\n};\n\nexport type ServerConfiguration = StandaloneServerConfiguration | DistributedServerConfiguration;\n\n// ============================================================================\n// CONFIGURATION VALUES\n// ============================================================================\n\nconst serverExecutionTimeoutSeconds = parsePositiveInt({\n envKey: 'SERVER_EXECUTION_TIMEOUT_SECONDS',\n raw: getEnv('SERVER_EXECUTION_TIMEOUT_SECONDS'),\n defaultValue: 600,\n});\n\nconst standalone = parseBoolean({\n envKey: 'STANDALONE',\n raw: getEnv('STANDALONE'),\n defaultValue: true,\n});\n\nconst port = parsePort(getEnv('PORT'));\nconst host = getEnv('HOST', { defaultValue: DEFAULT_HOST }) ?? DEFAULT_HOST;\n\nconst shared: SharedServerConfiguration = {\n LOG_LEVEL: getEnv('LOG_LEVEL', { defaultValue: 'info' }) ?? 'info',\n NODE_ENV: getEnv('NODE_ENV'),\n PORT: port,\n HOST: host,\n EXECUTOR_ID: standalone ? LOCAL_EXECUTOR_ID : randomAlphanumeric(6),\n MODEL_CATALOG_PATH: resolveOptionalPathEnv('MODEL_CATALOG_PATH'),\n MCP_CATALOG_PATH: resolveOptionalPathEnv('MCP_CATALOG_PATH'),\n SKILL_CATALOG_PATH: resolveOptionalPathEnv('SKILL_CATALOG_PATH'),\n SANDBOX_CATALOG_PATH: resolveOptionalPathEnv('SANDBOX_CATALOG_PATH'),\n FRONTEND_DIR: resolveFrontendDir(),\n\n MCP_REQUEST_TIMEOUT_MS: parsePositiveInt({\n envKey: 'MCP_REQUEST_TIMEOUT_MS',\n raw: getEnv('MCP_REQUEST_TIMEOUT_MS'),\n defaultValue: 4 * 60 * 1000,\n }),\n MCP_CONNECT_TIMEOUT_MS: parsePositiveInt({\n envKey: 'MCP_CONNECT_TIMEOUT_MS',\n raw: getEnv('MCP_CONNECT_TIMEOUT_MS'),\n defaultValue: 30 * 1000,\n }),\n MCP_DCR_OAUTH_CLIENT_NAME:\n getEnv('MCP_DCR_OAUTH_CLIENT_NAME', { defaultValue: 'truefoundry-harness' }) ?? 'truefoundry-harness',\n SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD: parsePositiveInt({\n envKey: 'SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD',\n raw: getEnv('SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD'),\n defaultValue: 20_971_520,\n }),\n MAX_REQUEST_BODY_BYTES: parsePositiveInt({\n envKey: 'MAX_REQUEST_BODY_BYTES',\n raw: getEnv('MAX_REQUEST_BODY_BYTES'),\n defaultValue: DEFAULT_MAX_REQUEST_BODY_BYTES,\n }),\n GRACEFUL_TIMEOUT_SECONDS: parsePositiveInt({\n envKey: 'GRACEFUL_TIMEOUT_SECONDS',\n raw: getEnv('GRACEFUL_TIMEOUT_SECONDS'),\n defaultValue: 30,\n }),\n SERVER_EXECUTION_TIMEOUT_SECONDS: serverExecutionTimeoutSeconds,\n TURN_STREAM_TTL_SECONDS: parsePositiveInt({\n envKey: 'TURN_STREAM_TTL_SECONDS',\n raw: getEnv('TURN_STREAM_TTL_SECONDS'),\n defaultValue: serverExecutionTimeoutSeconds + 300,\n }),\n TURN_STREAM_POST_COMPLETION_TTL_SECONDS: parsePositiveInt({\n envKey: 'TURN_STREAM_POST_COMPLETION_TTL_SECONDS',\n raw: getEnv('TURN_STREAM_POST_COMPLETION_TTL_SECONDS'),\n defaultValue: 300,\n }),\n TURN_SUBSCRIBE_TIMEOUT_MS: parsePositiveInt({\n envKey: 'TURN_SUBSCRIBE_TIMEOUT_MS',\n raw: getEnv('TURN_SUBSCRIBE_TIMEOUT_MS'),\n defaultValue: 600_000,\n }),\n REDIS_REQUEST_REPLY_TIMEOUT_MS: parsePositiveInt({\n envKey: 'REDIS_REQUEST_REPLY_TIMEOUT_MS',\n raw: getEnv('REDIS_REQUEST_REPLY_TIMEOUT_MS'),\n defaultValue: 60_000,\n }),\n REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS: parsePositiveInt({\n envKey: 'REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS',\n raw: getEnv('REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS'),\n defaultValue: 5_000,\n }),\n REDIS_REQUEST_REPLY_REPLY_TTL_MS: parsePositiveInt({\n envKey: 'REDIS_REQUEST_REPLY_REPLY_TTL_MS',\n raw: getEnv('REDIS_REQUEST_REPLY_REPLY_TTL_MS'),\n defaultValue: 120_000,\n }),\n REDIS_REQUEST_REPLY_POLL_INTERVAL_MS: parsePositiveInt({\n envKey: 'REDIS_REQUEST_REPLY_POLL_INTERVAL_MS',\n raw: getEnv('REDIS_REQUEST_REPLY_POLL_INTERVAL_MS'),\n defaultValue: 500,\n }),\n};\n\nconst configuration: ServerConfiguration = standalone\n ? {\n ...shared,\n STANDALONE: true,\n SQLITE_PATH: resolveSqlitePath(),\n }\n : {\n ...shared,\n STANDALONE: false,\n PUBLIC_BASE_URL: getEnv('PUBLIC_BASE_URL', { defaultValue: '' }) ?? '',\n DATABASE_URL: resolvePostgresDatabaseUrl(),\n DATABASE_POOL_MAX: parsePositiveInt({\n envKey: 'DATABASE_POOL_MAX',\n raw: getEnv('DATABASE_POOL_MAX'),\n defaultValue: 10,\n }),\n POSTGRES_STATEMENT_TIMEOUT_MS: parsePositiveInt({\n envKey: 'POSTGRES_STATEMENT_TIMEOUT_MS',\n raw: getEnv('POSTGRES_STATEMENT_TIMEOUT_MS'),\n defaultValue: 60_000,\n }),\n POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS: parsePositiveInt({\n envKey: 'POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS',\n raw: getEnv('POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS'),\n defaultValue: 60_000,\n }),\n REDIS_URL: resolveRedisUrl(),\n OIDC: resolveOIDCConfig(),\n };\n\nexport function isOidcConfigured(\n value: ServerConfiguration,\n): value is DistributedServerConfiguration & { OIDC: OIDCConfig } {\n return !value.STANDALONE && value.OIDC !== undefined;\n}\n\n/**\n * Public origin for OAuth callbacks.\n * Standalone → `http://localhost:$PORT`; distributed → `PUBLIC_BASE_URL` (may be `''`).\n */\nexport function getPublicBaseUrl(config: ServerConfiguration = configuration): string {\n if (config.STANDALONE) {\n return `http://localhost:${String(config.PORT)}`;\n }\n if (config.PUBLIC_BASE_URL === '') {\n throw new Error('PUBLIC_BASE_URL is required for OIDC callbacks but was empty');\n }\n return config.PUBLIC_BASE_URL;\n}\n\nexport default configuration;\n","/**\n * DB-backed configured MCP servers: one row per server per tenant,\n * identity as columns plus a Zod-validated `McpServerManifest` jsonb document.\n * Implementations: PostgresMcpServerStore and SqliteMcpServerStore.\n *\n * Also owns the DCR registration columns (`oauth_server` / `oauth_client`) via\n * `IOAuthClientStore` — those are not a separate persistence root.\n *\n * OAuth JSONB wire shapes (snake_case) and camelCase ↔ storage mappers live here\n * alongside the store contract — absence is an explicit `| null`, not an optional `?:`.\n */\nimport type {\n OAuthClientRecord as ContractOAuthClientRecord,\n OAuthPendingAuthorization as ContractOAuthPendingAuthorization,\n OAuthToken as ContractOAuthToken,\n IOAuthClientStore,\n} from '../mcp/auth/types';\nimport type { ResourceName } from '../schemas/common';\nimport type { McpServerManifest } from '../schemas/mcpServer';\n\nexport interface McpServerRecord {\n id: string;\n tenant_id: string;\n name: ResourceName;\n manifest: McpServerManifest;\n /** ISO-8601 UTC instant. */\n created_at: string;\n /** ISO-8601 UTC instant. */\n updated_at: string;\n}\n\nexport interface GetMcpServerInput {\n tenant_id: string;\n name: string;\n}\n\nexport interface ListMcpServersInput {\n tenant_id: string;\n /** `undefined` lists all; empty returns `[]` without querying; otherwise `WHERE name IN (...)`. */\n names: readonly string[] | undefined;\n}\n\nexport interface CreateMcpServerInput {\n tenant_id: string;\n name: ResourceName;\n manifest: McpServerManifest;\n}\n\n/** Same shape as create for now; kept as a distinct name for the upsert path. */\nexport type UpsertMcpServerInput = CreateMcpServerInput;\n\n/** Unique `(tenant_id, name)` violation on create. */\nexport class McpServerNameConflictError extends Error {\n readonly tenant_id: string;\n readonly server_name: string;\n\n constructor({ tenant_id, name }: { tenant_id: string; name: string }, options?: ErrorOptions) {\n super(`MCP server name already exists: ${name}`, options);\n this.name = 'McpServerNameConflictError';\n this.tenant_id = tenant_id;\n this.server_name = name;\n }\n}\n\nexport interface IMcpServerStore<TTransaction = never> extends IOAuthClientStore<TTransaction> {\n listServers(input: ListMcpServersInput, transaction?: TTransaction): Promise<McpServerRecord[]>;\n getServer(input: GetMcpServerInput, transaction?: TTransaction): Promise<McpServerRecord | undefined>;\n /**\n * Load one server while holding a row lock for the lifetime of `transaction`.\n * Postgres: `SELECT … FOR UPDATE`. SQLite: plain read under a write txn (BEGIN IMMEDIATE).\n * Required before read-modify-write of header secrets so concurrent keep/rotate cannot interleave.\n */\n getServerForUpdate(input: GetMcpServerInput, transaction: TTransaction): Promise<McpServerRecord | undefined>;\n /** Inserts a new server with a generated ULID. Throws McpServerNameConflictError on name clash. */\n createServer(input: CreateMcpServerInput, transaction?: TTransaction): Promise<McpServerRecord>;\n /**\n * Creates the server or replaces `manifest` (+ `updated_at`) only.\n * Never overwrites `id`, `oauth_server`, or `oauth_client`.\n */\n upsertServer(input: UpsertMcpServerInput, transaction?: TTransaction): Promise<McpServerRecord>;\n}\n\n/**\n * How long a pending authorization stays redeemable — long enough to finish a consent screen,\n * short enough that an abandoned `state` and its PKCE verifier stop being usable. Applied as a\n * `created_at` filter on read by both backends, so no sweep job is needed.\n */\nexport const PENDING_AUTHORIZATION_TTL_MS = 10 * 60 * 1000;\n\n/** RFC 8414 AS metadata cached at DCR time (`mcp_server.oauth_server`). */\nexport interface OAuthServer {\n authorization_endpoint: string;\n token_endpoint: string;\n code_challenge_methods_supported: string[] | null;\n}\n\n/** RFC 7591 DCR response (`mcp_server.oauth_client`). */\nexport interface OAuthClient {\n client_id: string;\n client_secret: string | null;\n}\n\n/** `oauth_pending_authorization.auth_data` JSONB. */\nexport interface OAuthPendingAuthorizationData {\n /** MCP server URL from authorize time — needed by the shared callback for RFC 8707 `resource`. */\n mcp_server_url: string;\n code_verifier: string | null;\n redirect_url: string | null;\n}\n\n/** `oauth_token.token` JSONB. */\nexport interface OAuthToken {\n access_token: string;\n refresh_token: string | null;\n /** ISO 8601 */\n expires_at: string;\n scope: string | null;\n}\n\nexport function toStoredOAuthToken(token: ContractOAuthToken): OAuthToken {\n return {\n access_token: token.accessToken,\n refresh_token: token.refreshToken,\n expires_at: token.expiresAt,\n scope: token.scope,\n };\n}\n\nexport function fromStoredOAuthToken(stored: OAuthToken): ContractOAuthToken {\n return {\n accessToken: stored.access_token,\n refreshToken: stored.refresh_token,\n expiresAt: stored.expires_at,\n scope: stored.scope,\n };\n}\n\nexport function toStoredOAuthClientRecord(record: ContractOAuthClientRecord): {\n server: OAuthServer;\n client: OAuthClient;\n} {\n return {\n server: {\n authorization_endpoint: record.server.authorizationEndpoint,\n token_endpoint: record.server.tokenEndpoint,\n code_challenge_methods_supported: record.server.codeChallengeMethodsSupported,\n },\n client: {\n client_id: record.client.clientId,\n client_secret: record.client.clientSecret,\n },\n };\n}\n\nexport function fromStoredOAuthClientRecord(params: {\n server: OAuthServer;\n client: OAuthClient;\n}): ContractOAuthClientRecord {\n return {\n server: {\n authorizationEndpoint: params.server.authorization_endpoint,\n tokenEndpoint: params.server.token_endpoint,\n codeChallengeMethodsSupported: params.server.code_challenge_methods_supported,\n },\n client: {\n clientId: params.client.client_id,\n clientSecret: params.client.client_secret,\n },\n };\n}\n\n/** The blob half of a pending authorization; `state`/`id`/`user_id` live in their own columns. */\nexport function toStoredOAuthPendingAuthorizationData(\n pending: ContractOAuthPendingAuthorization,\n): OAuthPendingAuthorizationData {\n return {\n mcp_server_url: pending.mcpServerUrl,\n code_verifier: pending.codeVerifier,\n redirect_url: pending.redirectUrl,\n };\n}\n\nexport function fromStoredOAuthPendingAuthorizationData(\n stored: OAuthPendingAuthorizationData,\n): Pick<ContractOAuthPendingAuthorization, 'mcpServerUrl' | 'codeVerifier' | 'redirectUrl'> {\n return {\n mcpServerUrl: stored.mcp_server_url,\n codeVerifier: stored.code_verifier,\n redirectUrl: stored.redirect_url,\n };\n}\n","/**\n * DB-backed configured model providers: one row per provider per tenant,\n * identity as columns plus the Zod-validated `ModelProviderManifest` document as jsonb.\n * Implementations: PostgresModelProviderStore and SqliteModelProviderStore.\n */\nimport type { ResourceName } from '../schemas/common';\nimport type { Model, ModelProviderManifest } from '../schemas/modelProvider';\n\nexport interface ModelProviderRecord {\n tenant_id: string;\n name: ResourceName;\n manifest: ModelProviderManifest;\n /** ISO-8601 UTC instant. */\n created_at: string;\n /** ISO-8601 UTC instant. */\n updated_at: string;\n}\n\nexport interface GetModelProviderInput {\n tenant_id: string;\n name: string;\n}\n\nexport interface CreateModelProviderInput {\n tenant_id: string;\n /** Derived from the document by `modelProviderName`, never chosen by the caller. */\n name: ResourceName;\n manifest: ModelProviderManifest;\n}\n\n/** Same shape as create for now; kept as a distinct name for the upsert path. */\nexport type UpsertModelProviderInput = CreateModelProviderInput;\n\n/** Unique `(tenant_id, name)` violation on create. */\nexport class ModelProviderNameConflictError extends Error {\n readonly tenant_id: string;\n readonly provider_name: string;\n\n constructor({ tenant_id, name }: { tenant_id: string; name: string }, options?: ErrorOptions) {\n super(`Model provider name already exists: ${name}`, options);\n this.name = 'ModelProviderNameConflictError';\n this.tenant_id = tenant_id;\n this.provider_name = name;\n }\n}\n\nexport interface IModelProviderStore<TTransaction = never> {\n listProviders(tenantId: string, transaction?: TTransaction): Promise<ModelProviderRecord[]>;\n getProvider(input: GetModelProviderInput, transaction?: TTransaction): Promise<ModelProviderRecord | undefined>;\n /**\n * Load one provider while holding a row lock for the lifetime of `transaction`.\n * Postgres: `SELECT … FOR UPDATE`. SQLite: plain read under a write txn (BEGIN IMMEDIATE).\n * Required before read-modify-write of secrets so concurrent keep/rotate cannot interleave.\n */\n getProviderForUpdate(\n input: GetModelProviderInput,\n transaction: TTransaction,\n ): Promise<ModelProviderRecord | undefined>;\n /** Inserts a new provider. Throws ModelProviderNameConflictError on name clash. */\n createProvider(input: CreateModelProviderInput, transaction?: TTransaction): Promise<ModelProviderRecord>;\n /** Single-row write: creates the provider or replaces the whole manifest (models included). */\n upsertProvider(input: UpsertModelProviderInput, transaction?: TTransaction): Promise<ModelProviderRecord>;\n /** Flattens manifests into the FQN read view for GET /models. */\n listModels(tenantId: string, transaction?: TTransaction): Promise<Model[]>;\n}\n\n/** Application-side flatten shared by both store implementations. */\nexport function flattenProviderModels(records: ModelProviderRecord[]): Model[] {\n return records.flatMap(record =>\n record.manifest.models.map(model => ({\n name: `${record.name}/${model.name}`,\n model_id: model.model_id,\n provider: { name: record.name },\n properties: model.properties,\n })),\n );\n}\n","/**\n * DB-backed configured skills: one row per skill per tenant,\n * identity as columns plus a Zod-validated `SkillManifest` jsonb document.\n * Implementations: PostgresSkillStore and SqliteSkillStore.\n */\nimport type { ResourceName } from '../schemas/common';\nimport type { SkillManifest } from '../schemas/skill';\n\nexport interface SkillRecord {\n tenant_id: string;\n name: ResourceName;\n manifest: SkillManifest;\n /** ISO-8601 UTC instant. */\n created_at: string;\n /** ISO-8601 UTC instant. */\n updated_at: string;\n}\n\nexport interface GetSkillInput {\n tenant_id: string;\n name: string;\n}\n\nexport interface ListSkillsInput {\n tenant_id: string;\n /** `undefined` lists all; empty returns `[]` without querying; otherwise `WHERE name IN (...)`. */\n names: readonly string[] | undefined;\n}\n\nexport interface CreateSkillInput {\n tenant_id: string;\n name: ResourceName;\n manifest: SkillManifest;\n}\n\n/** Same shape as create for now; kept as a distinct name for the upsert path. */\nexport type UpsertSkillInput = CreateSkillInput;\n\n/** Unique `(tenant_id, name)` violation on create. */\nexport class SkillNameConflictError extends Error {\n readonly tenant_id: string;\n readonly skill_name: string;\n\n constructor({ tenant_id, name }: { tenant_id: string; name: string }, options?: ErrorOptions) {\n super(`Skill name already exists: ${name}`, options);\n this.name = 'SkillNameConflictError';\n this.tenant_id = tenant_id;\n this.skill_name = name;\n }\n}\n\nexport interface ISkillStore<TTransaction = never> {\n listSkills(input: ListSkillsInput, transaction?: TTransaction): Promise<SkillRecord[]>;\n getSkill(input: GetSkillInput, transaction?: TTransaction): Promise<SkillRecord | undefined>;\n /** Inserts a new skill. Throws SkillNameConflictError on name clash. */\n createSkill(input: CreateSkillInput, transaction?: TTransaction): Promise<SkillRecord>;\n /** Single-row write: creates the skill or replaces the whole manifest. */\n upsertSkill(input: UpsertSkillInput, transaction?: TTransaction): Promise<SkillRecord>;\n}\n","import Database from 'better-sqlite3';\nimport {\n CompiledQuery,\n Kysely,\n ParseJSONResultsPlugin,\n SqliteAdapter,\n SqliteDriver,\n SqliteIntrospector,\n SqliteQueryCompiler,\n type DatabaseConnection,\n type Dialect,\n type Driver,\n type QueryCompiler,\n type TransactionSettings,\n} from 'kysely';\n\nimport type { Database as Schema } from './types';\n\n/**\n * Wraps SqliteDriver and maps Kysely access mode onto SQLite begin kinds:\n * - omit / `read only` → deferred BEGIN (matches Postgres default feel)\n * - `read write` → BEGIN IMMEDIATE (RESERVED write lock)\n *\n * Stock SqliteDriver.d.ts omits `settings` on beginTransaction; compose instead of override.\n */\nclass ImmediateSqliteDriver implements Driver {\n readonly #inner: SqliteDriver;\n\n constructor(database: Database.Database) {\n this.#inner = new SqliteDriver({ database });\n }\n\n init(): Promise<void> {\n return this.#inner.init();\n }\n\n acquireConnection(): Promise<DatabaseConnection> {\n return this.#inner.acquireConnection();\n }\n\n async beginTransaction(connection: DatabaseConnection, settings: TransactionSettings): Promise<void> {\n const begin = settings.accessMode === 'read write' ? 'begin immediate' : 'begin';\n await connection.executeQuery(CompiledQuery.raw(begin));\n }\n\n commitTransaction(connection: DatabaseConnection): Promise<void> {\n return this.#inner.commitTransaction(connection);\n }\n\n rollbackTransaction(connection: DatabaseConnection): Promise<void> {\n return this.#inner.rollbackTransaction(connection);\n }\n\n savepoint(\n connection: DatabaseConnection,\n savepointName: string,\n compileQuery: QueryCompiler['compileQuery'],\n ): Promise<void> {\n return this.#inner.savepoint(connection, savepointName, compileQuery);\n }\n\n rollbackToSavepoint(\n connection: DatabaseConnection,\n savepointName: string,\n compileQuery: QueryCompiler['compileQuery'],\n ): Promise<void> {\n return this.#inner.rollbackToSavepoint(connection, savepointName, compileQuery);\n }\n\n releaseSavepoint(\n connection: DatabaseConnection,\n savepointName: string,\n compileQuery: QueryCompiler['compileQuery'],\n ): Promise<void> {\n return this.#inner.releaseSavepoint(connection, savepointName, compileQuery);\n }\n\n releaseConnection(): Promise<void> {\n return this.#inner.releaseConnection();\n }\n\n destroy(): Promise<void> {\n return this.#inner.destroy();\n }\n}\n\nclass ImmediateSqliteDialect implements Dialect {\n readonly #database: Database.Database;\n\n constructor(database: Database.Database) {\n this.#database = database;\n }\n\n createDriver(): Driver {\n return new ImmediateSqliteDriver(this.#database);\n }\n\n createQueryCompiler() {\n return new SqliteQueryCompiler();\n }\n\n createAdapter() {\n return new SqliteAdapter();\n }\n\n createIntrospector(db: Kysely<unknown>) {\n return new SqliteIntrospector(db);\n }\n}\n\nfunction applyPragmas(database: Database.Database): void {\n database.pragma('journal_mode = WAL');\n database.pragma('busy_timeout = 5000');\n database.pragma('synchronous = NORMAL');\n database.pragma('foreign_keys = ON');\n database.pragma('temp_store = MEMORY');\n database.pragma('cache_size = -10240');\n}\n\n/**\n * Result aliases that are `json(...)` projections of JSONB columns.\n * Plain TEXT (title, ids, timestamps) must not be parsed even when they look like JSON.\n */\nconst JSON_RESULT_COLUMNS = new Set([\n 'agent_spec',\n 'custom',\n 'ancestor_ids',\n 'input',\n 'state',\n 'checkpoint',\n 'agent_info',\n 'current_context_usage',\n 'body',\n 'capability_state',\n 'turn_checkpoint',\n 'turn_state',\n 'thread_checkpoint',\n 'event',\n 'manifest',\n 'build_metadata',\n 'oauth_server',\n 'oauth_client',\n 'token',\n 'auth_data',\n]);\n\n/** Top-level row field only — `$[0].\"body\"`, not `$[0].\"body\".\"content\"`. */\nfunction shouldParseJsonResultColumn(_value: string, jsonPath: string): boolean {\n const match = /^\\$\\[\\d+\\]\\.\"([^\"]+)\"$/.exec(jsonPath);\n const column = match?.[1];\n return column !== undefined && JSON_RESULT_COLUMNS.has(column);\n}\n\nexport function createSqliteDb(filename: string): Kysely<Schema> {\n const database = new Database(filename);\n applyPragmas(database);\n return new Kysely<Schema>({\n dialect: new ImmediateSqliteDialect(database),\n // Parse only projected JSON columns once; never re-parse nested string values.\n plugins: [new ParseJSONResultsPlugin({ shouldParse: shouldParseJsonResultColumn })],\n });\n}\n\n/**\n * Match better-sqlite3 unique constraint errors without brittle instanceof checks.\n */\nexport function isUniqueViolation(err: unknown): boolean {\n if (typeof err !== 'object' || err === null || !('code' in err)) {\n return false;\n }\n const code = err.code;\n return code === 'SQLITE_CONSTRAINT_UNIQUE' || code === 'SQLITE_CONSTRAINT_PRIMARYKEY';\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport type { Kysely } from 'kysely';\nimport { FileMigrationProvider, Migrator } from 'kysely/migration';\n\nimport type { Database } from './sqlite/types';\n\n/**\n * Runs all pending SQLite migrations.\n *\n * Used at sqlite startup and by SQLite store tests.\n * Resolves `…/sqlite/migrations` next to this module (source or `dist/`).\n *\n * Kysely does not wrap SQLite migrations in a transaction (`supportsTransactionalDdl`\n * is false). Migrations that need atomicity open `db.transaction()` themselves;\n * `PRAGMA foreign_keys` must stay outside that txn.\n */\nexport async function migrateSqliteToLatest(db: Kysely<Database>): Promise<void> {\n const migrator = new Migrator({\n db,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(import.meta.dirname, 'sqlite', 'migrations'),\n }),\n });\n\n const { error, results } = await migrator.migrateToLatest();\n\n results?.forEach(it => {\n if (it.status === 'Success') {\n console.log(`migration \"${it.migrationName}\" was executed successfully`);\n } else if (it.status === 'Error') {\n console.error(`failed to execute migration \"${it.migrationName}\"`);\n }\n });\n\n if (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error('failed to migrate', { cause: error });\n }\n}\n","/**\n * Shared Kysely SQL expression helpers for SQLite stores.\n * JSON authority: SQLite JSON1 — bind text via jsonb(?); read via json(column).\n * ParseJSONResultsPlugin parses top-level json() columns only (see createSqliteDb).\n */\nimport { sql, type Expression, type RawBuilder } from 'kysely';\n\n/** Bind a JS value as SQLite JSONB BLOB (stringify in JS, convert in SQL). */\nexport function jsonbBind(value: unknown): RawBuilder<string> {\n return sql`jsonb(${JSON.stringify(value)})`;\n}\n\n/**\n * `jsonb_set(column, path, jsonb(?))`.\n * `path` must be a fixed literal from call sites (e.g. `'$.completion'`).\n */\nexport function jsonbSet(column: Expression<unknown>, path: string, value: unknown): RawBuilder<string> {\n return sql`jsonb_set(${column}, ${path}, ${jsonbBind(value)})`;\n}\n\n/**\n * Project a JSONB column to minified text JSON.\n * With ParseJSONResultsPlugin, the result row field is the parsed JS value typed as `T`.\n */\nexport function jsonText<T>(column: Expression<unknown>): RawBuilder<T> {\n return sql<T>`json(${column})`;\n}\n\n/** Current UTC instant as ISO-8601 text for TEXT timestamp columns. */\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n\nexport function isoMsAgo(ms: number): string {\n return new Date(Date.now() - ms).toISOString();\n}\n","/**\n * Session-store-only helpers for SQLite (append_id ordering quirks).\n * Shared JSON/time helpers live in `../sqlExpressions`.\n */\n\n/**\n * SQLite RETURNING row order is unspecified. Multi-row INSERT assigns increasing\n * append_id in VALUES order — sort on that before mapping to pos / per-thread lists.\n */\nexport function sortedByAppendId<T extends { append_id: number }>(rows: readonly T[]): T[] {\n return [...rows].sort((a, b) => a.append_id - b.append_id);\n}\n","import type { TurnRecord, TurnSnapshot } from '@truefoundry/trueforge-core/agent-session/models/TurnRecord';\nimport {\n type TerminalTurnState,\n type TurnInputItem,\n type TurnState,\n} from '@truefoundry/trueforge-core/agent-session/schemas/turn';\nimport { assertCreateTurnThreadDelta } from '@truefoundry/trueforge-core/agent-session/store/assertCreateTurnThreadDelta';\nimport type {\n FreezeAndGetTurnInput,\n TurnRecordWithoutSnapshot,\n UpdateTurnStateInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n PreviousTurnRunningError,\n SessionNotFoundError,\n SessionStoreConflictError,\n SessionStoreInvariantError,\n SessionStoreNotFoundError,\n TurnAlreadyExistsError,\n TurnNotFoundError,\n TurnNotRunningError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport type { CapabilityState, JsonValue } from '@truefoundry/trueforge-core/core/capabilities/AgentCapability';\nimport type { AgentInfo, AgentParent, MCPServerInitInfo } from '@truefoundry/trueforge-core/core/events/schema';\nimport type { AgentThreadSnapshot, ContextMessage } from '@truefoundry/trueforge-core/core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport { getEmptyCurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport type { SandboxInfo } from '@truefoundry/trueforge-core/core/sandbox/Sandbox';\nimport { sql, type Kysely, type RawBuilder, type Transaction } from 'kysely';\nimport { isUniqueViolation } from '../../client';\nimport { jsonbBind, jsonText, nowIso } from '../../sqlExpressions';\nimport type { Database, TurnCheckpoint, TurnThreadCheckpoint } from '../../types';\nimport { sortedByAppendId } from '../sqlExpressions';\n\ntype TurnCustom = Record<string, never>;\n\nfunction isEmptyCustomRecord(value: Record<string, unknown>): value is TurnCustom {\n return Object.keys(value).length === 0;\n}\n\nfunction parseTurnCustom(value: Record<string, unknown> | null): TurnCustom | null {\n if (value === null) {\n return null;\n }\n if (!isEmptyCustomRecord(value)) {\n throw new SessionStoreInvariantError('non-empty turn custom is not supported');\n }\n return value;\n}\n\n/** New thread metadata; mutable per-turn data arrives through dedicated fields. */\nexport interface NewThreadRegistration {\n thread_id: string;\n parent: AgentParent | null;\n agent_info: AgentInfo | null;\n}\n\nexport interface TurnKeys {\n session_id: string;\n turn_id: string;\n}\n\nexport interface NewContextAppend {\n thread_id: string;\n context: ContextMessage[];\n current_context_usage: CurrentContextUsage | null;\n}\n\nexport interface CreateTurnTurnFields {\n turn_id: string;\n first_turn_id: string;\n previous_turn_id: string | null;\n ancestor_ids: string[];\n input: TurnInputItem[];\n state: TurnState;\n custom: Record<string, unknown> | null;\n}\n\nexport interface CreateTurnInput {\n session_id: string;\n turn: CreateTurnTurnFields;\n new_threads: NewThreadRegistration[];\n new_context_appends: NewContextAppend[];\n capability_states: {\n thread_id: string;\n capability_state: CapabilityState | null;\n }[];\n last_activity_timestamp_ms: number;\n update_session_title_if_not_exist: string | null;\n mcp_servers: Record<string, MCPServerInitInfo> | null;\n sandbox_info: SandboxInfo | null;\n}\n\nexport interface GetTurnInput {\n session_id: string;\n turn_id: string;\n}\n\nexport interface ListTurnsInput {\n session_id: string;\n limit: number;\n offset: number;\n}\n\nexport interface ListTurnsResult {\n turns: TurnRecordWithoutSnapshot<TurnCustom>[];\n next_offset: number | null;\n}\n\ntype DbOrTrx = Kysely<Database> | Transaction<Database>;\n\nfunction terminalTurnState(state: TurnState, turn_id: string): TerminalTurnState {\n switch (state.status) {\n case 'running':\n throw new SessionStoreInvariantError(`expected terminal state for turn ${turn_id}, got running`);\n case 'done':\n case 'cancelled':\n case 'error':\n return state;\n }\n}\n\nasync function loadTurnState(db: DbOrTrx, keys: TurnKeys): Promise<TurnState | undefined> {\n const row = await db\n .selectFrom('turn')\n .select([jsonText<TurnState>(sql.ref('state')).as('state')])\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .executeTakeFirst();\n return row?.state;\n}\n\n/** Classify a 0-row fenced write: missing turn vs frozen/non-running turn. */\nexport async function classifyTurnFenceWriteFailure(db: DbOrTrx, keys: TurnKeys): Promise<never> {\n const state = await loadTurnState(db, keys);\n if (!state) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(state, keys.turn_id));\n}\n\n/**\n * Classify a 0-row fenced turn_thread UPDATE: turn missing/terminal vs thread row missing.\n */\nexport async function classifyTurnThreadWriteFailure(db: DbOrTrx, keys: TurnKeys, thread_id: string): Promise<never> {\n const state = await loadTurnState(db, keys);\n if (!state) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n if (state.status !== 'running') {\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(state, keys.turn_id));\n }\n throw new SessionStoreInvariantError(`thread ${thread_id} not found in turn ${keys.turn_id}`);\n}\n\nexport async function assertTurnRunning(db: DbOrTrx, keys: TurnKeys): Promise<void> {\n const state = await loadTurnState(db, keys);\n if (!state) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n if (state.status !== 'running') {\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(state, keys.turn_id));\n }\n}\n\ninterface CapabilityAggRow {\n thread_id: string;\n capability_state: Record<string, JsonValue> | null;\n}\n\nasync function assembleTurnRecord(\n db: DbOrTrx,\n args: { session_id: string; turn_id: string },\n): Promise<TurnRecord<TurnCustom> | undefined> {\n const turn = await db\n .selectFrom('turn')\n .select([\n 'session_id',\n 'turn_id',\n 'first_turn_id',\n 'previous_turn_id',\n jsonText<string[]>(sql.ref('ancestor_ids')).as('ancestor_ids'),\n jsonText<TurnInputItem[]>(sql.ref('input')).as('input'),\n jsonText<TurnState>(sql.ref('state')).as('state'),\n jsonText<TurnCheckpoint>(sql.ref('checkpoint')).as('checkpoint'),\n jsonText<Record<string, unknown> | null>(sql.ref('custom')).as('custom'),\n 'created_at',\n 'updated_at',\n ])\n .where('session_id', '=', args.session_id)\n .where('turn_id', '=', args.turn_id)\n .executeTakeFirst();\n\n if (!turn) {\n return undefined;\n }\n\n // LEFT JOIN turn_thread + turn_thread_context ORDER BY pos to assemble context per thread.\n // Empty-context threads emit one row with null pos/append_id from the LEFT JOIN.\n const contextRows = await db\n .selectFrom('turn_thread as tt')\n .leftJoin('turn_thread_context as ttc', join =>\n join\n .on('ttc.session_id', '=', args.session_id)\n .on('ttc.turn_id', '=', args.turn_id)\n .onRef('ttc.thread_id', '=', 'tt.thread_id'),\n )\n .leftJoin('thread_context_log as l', join =>\n join\n .on('l.session_id', '=', args.session_id)\n .onRef('l.thread_id', '=', 'tt.thread_id')\n .onRef('l.append_id', '=', 'ttc.append_id'),\n )\n .select([\n 'tt.thread_id',\n jsonText<TurnThreadCheckpoint>(sql.ref('tt.checkpoint')).as('checkpoint'),\n jsonText<AgentInfo | null>(sql.ref('tt.agent_info')).as('agent_info'),\n jsonText<CurrentContextUsage>(sql.ref('tt.current_context_usage')).as('current_context_usage'),\n jsonText<ContextMessage | null>(sql.ref('l.body')).as('body'),\n 'ttc.pos',\n ])\n .where('tt.session_id', '=', args.session_id)\n .where('tt.turn_id', '=', args.turn_id)\n .orderBy('tt.thread_id')\n .orderBy('ttc.pos')\n .execute();\n\n const capabilityRows: CapabilityAggRow[] = await db\n .selectFrom('thread_capability_state')\n .select([\n 'thread_id',\n sql<Record<string, JsonValue> | null>`json(jsonb_group_object(key, json(state)))`.as('capability_state'),\n ])\n .where('session_id', '=', args.session_id)\n .where('turn_id', '=', args.turn_id)\n .groupBy('thread_id')\n .execute();\n\n const capabilityByThread = new Map<string, Record<string, JsonValue>>();\n for (const row of capabilityRows) {\n if (row.capability_state !== null) {\n capabilityByThread.set(row.thread_id, row.capability_state);\n }\n }\n\n const threads: Record<string, AgentThreadSnapshot> = {};\n const orderedBodies = new Map<string, ContextMessage[]>();\n const threadMeta = new Map<\n string,\n {\n checkpoint: TurnThreadCheckpoint;\n agent_info: AgentInfo | null;\n current_context_usage: CurrentContextUsage;\n }\n >();\n\n for (const row of contextRows) {\n if (!threadMeta.has(row.thread_id)) {\n threadMeta.set(row.thread_id, {\n checkpoint: row.checkpoint,\n agent_info: row.agent_info,\n current_context_usage: row.current_context_usage,\n });\n orderedBodies.set(row.thread_id, []);\n }\n if (row.body !== null) {\n const bodies = orderedBodies.get(row.thread_id);\n if (bodies !== undefined) {\n bodies.push(row.body);\n }\n }\n }\n\n for (const [threadId, meta] of threadMeta) {\n const context = orderedBodies.get(threadId) ?? [];\n const capability_state = capabilityByThread.get(threadId) ?? null;\n\n const snap: AgentThreadSnapshot = {\n thread_id: threadId,\n context,\n current_context_usage: meta.current_context_usage,\n parent: meta.checkpoint.parent,\n agent_info: meta.agent_info,\n completion: meta.checkpoint.completion,\n capability_state,\n };\n threads[threadId] = snap;\n }\n\n const checkpoint = turn.checkpoint;\n const snapshot: TurnSnapshot = {\n threads,\n mcp_servers: checkpoint.mcp_servers,\n sandbox_info: checkpoint.sandbox_info,\n };\n\n return {\n turn_id: turn.turn_id,\n session_id: turn.session_id,\n first_turn_id: turn.first_turn_id,\n ancestor_ids: turn.ancestor_ids,\n previous_turn_id: turn.previous_turn_id,\n state: turn.state,\n input: turn.input,\n snapshot,\n created_at: new Date(turn.created_at),\n updated_at: new Date(turn.updated_at),\n custom: parseTurnCustom(turn.custom),\n };\n}\n\n/**\n * createTurn — IMMEDIATE tx (BEGIN IMMEDIATE covers write locking; no FOR UPDATE/FOR SHARE).\n * Context order lives in turn_thread_context (pos, append_id); no context_ids array.\n */\nexport async function createTurn(db: Kysely<Database>, input: CreateTurnInput): Promise<void> {\n try {\n await db.transaction().execute(async trx => {\n // Step 1: read session tip; no FOR UPDATE (BEGIN IMMEDIATE is the lock).\n const locked = await trx\n .selectFrom('session')\n .select(['last_turn_id'])\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n\n if (!locked) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n // Step 2: bump session tip + optional title coalesce.\n let sessionUpdate = trx\n .updateTable('session')\n .set({\n last_turn_id: input.turn.turn_id,\n updated_at: nowIso(),\n last_activity_timestamp_ms: input.last_activity_timestamp_ms,\n })\n .where('session_id', '=', input.session_id);\n\n if (input.update_session_title_if_not_exist !== null) {\n const titleValue = input.update_session_title_if_not_exist;\n sessionUpdate = sessionUpdate.set({\n title: sql<string>`COALESCE(title, ${titleValue})`,\n });\n }\n\n await sessionUpdate.execute();\n\n const prevTurnId = input.turn.previous_turn_id;\n\n let prevCheckpoint: TurnCheckpoint | null = null;\n const prevThreadRows: {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: AgentInfo | null;\n current_context_usage: CurrentContextUsage;\n context_pos_max: number;\n }[] = [];\n\n if (prevTurnId != null) {\n // Read previous turn + its turn_thread rows in one join.\n const prevRows = await trx\n .selectFrom('turn as t')\n .leftJoin('turn_thread as tt', join =>\n join.onRef('tt.session_id', '=', 't.session_id').onRef('tt.turn_id', '=', 't.turn_id'),\n )\n .leftJoin(\n db\n .selectFrom('turn_thread_context')\n .select(['thread_id', 'turn_id', sql<number>`MAX(pos)`.as('max_pos')])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', prevTurnId)\n .groupBy(['thread_id', 'turn_id'])\n .as('tc_agg'),\n join => join.onRef('tc_agg.thread_id', '=', 'tt.thread_id').onRef('tc_agg.turn_id', '=', 'tt.turn_id'),\n )\n .select([\n jsonText<TurnCheckpoint>(sql.ref('t.checkpoint')).as('turn_checkpoint'),\n jsonText<TurnState>(sql.ref('t.state')).as('turn_state'),\n 'tt.thread_id',\n jsonText<TurnThreadCheckpoint | null>(sql.ref('tt.checkpoint')).as('thread_checkpoint'),\n jsonText<AgentInfo | null>(sql.ref('tt.agent_info')).as('agent_info'),\n jsonText<CurrentContextUsage | null>(sql.ref('tt.current_context_usage')).as('current_context_usage'),\n 'tc_agg.max_pos',\n ])\n .where('t.session_id', '=', input.session_id)\n .where('t.turn_id', '=', prevTurnId)\n .execute();\n\n const first = prevRows[0];\n if (first !== undefined) {\n if (first.turn_state.status === 'running') {\n throw new PreviousTurnRunningError(prevTurnId);\n }\n prevCheckpoint = first.turn_checkpoint;\n\n for (const row of prevRows) {\n if (row.thread_id === null) {\n continue;\n }\n if (row.thread_checkpoint === null || row.current_context_usage === null) {\n throw new SessionStoreInvariantError(`previous turn_thread row for ${row.thread_id} is incomplete`);\n }\n prevThreadRows.push({\n thread_id: row.thread_id,\n checkpoint: row.thread_checkpoint,\n agent_info: row.agent_info,\n current_context_usage: row.current_context_usage,\n context_pos_max: row.max_pos ?? 0,\n });\n }\n }\n }\n\n assertCreateTurnThreadDelta({\n previousThreadIds: new Set(prevThreadRows.map(r => r.thread_id)),\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n const checkpoint: TurnCheckpoint = {\n mcp_servers: input.mcp_servers ?? prevCheckpoint?.mcp_servers ?? null,\n sandbox_info: input.sandbox_info ?? prevCheckpoint?.sandbox_info ?? null,\n };\n\n const now = nowIso();\n\n const turnCustom = input.turn.custom ?? null;\n\n // Step 3: insert turn row.\n await trx\n .insertInto('turn')\n .values({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n first_turn_id: input.turn.first_turn_id,\n previous_turn_id: input.turn.previous_turn_id ?? null,\n ancestor_ids: jsonbBind(input.turn.ancestor_ids),\n input: jsonbBind(input.turn.input),\n state: jsonbBind(input.turn.state),\n checkpoint: jsonbBind(checkpoint),\n custom: turnCustom !== null ? jsonbBind(turnCustom) : null,\n created_at: now,\n updated_at: now,\n })\n .execute();\n\n // Step 4: insert new context log rows.\n const logRows: {\n session_id: string;\n thread_id: string;\n turn_id: string;\n body: RawBuilder<string>;\n created_at: string;\n }[] = [];\n\n for (const append of input.new_context_appends) {\n for (const body of append.context) {\n logRows.push({\n session_id: input.session_id,\n thread_id: append.thread_id,\n turn_id: input.turn.turn_id,\n body: jsonbBind(body),\n created_at: now,\n });\n }\n }\n\n const newIdsByThread = new Map<string, number[]>();\n if (logRows.length > 0) {\n const inserted = await trx\n .insertInto('thread_context_log')\n .values(logRows)\n .returning(['thread_id', 'append_id'])\n .execute();\n for (const row of sortedByAppendId(inserted)) {\n const list = newIdsByThread.get(row.thread_id);\n if (list === undefined) {\n newIdsByThread.set(row.thread_id, [row.append_id]);\n } else {\n list.push(row.append_id);\n }\n }\n }\n\n const appendUsageByThread = new Map<string, CurrentContextUsage>();\n for (const append of input.new_context_appends) {\n if (append.current_context_usage !== null) {\n appendUsageByThread.set(append.thread_id, append.current_context_usage);\n }\n }\n\n // Step 5: insert turn_thread rows for carried-forward and new threads.\n const turnThreadRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n checkpoint: RawBuilder<string>;\n agent_info: RawBuilder<string> | null;\n current_context_usage: RawBuilder<string>;\n updated_at: string;\n }[] = [];\n\n const turnThreadContextRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n pos: number;\n append_id: number;\n }[] = [];\n\n for (const parent of prevThreadRows) {\n const usage = appendUsageByThread.get(parent.thread_id) ?? parent.current_context_usage;\n turnThreadRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: parent.thread_id,\n checkpoint: jsonbBind(parent.checkpoint),\n agent_info: parent.agent_info !== null ? jsonbBind(parent.agent_info) : null,\n current_context_usage: jsonbBind(usage),\n updated_at: now,\n });\n }\n\n // One SELECT for all parent context mappings (not N+1 per thread).\n if (prevTurnId != null && prevThreadRows.length > 0) {\n const parentContextRows = await trx\n .selectFrom('turn_thread_context')\n .select(['thread_id', 'pos', 'append_id'])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', prevTurnId)\n .where(\n 'thread_id',\n 'in',\n prevThreadRows.map(r => r.thread_id),\n )\n .orderBy('thread_id')\n .orderBy('pos')\n .execute();\n\n for (const cr of parentContextRows) {\n turnThreadContextRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: cr.thread_id,\n pos: cr.pos,\n append_id: cr.append_id,\n });\n }\n }\n\n for (const parent of prevThreadRows) {\n const newIds = newIdsByThread.get(parent.thread_id) ?? [];\n const basePos = parent.context_pos_max;\n for (let i = 0; i < newIds.length; i++) {\n const appendId = newIds[i];\n if (appendId !== undefined) {\n turnThreadContextRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: parent.thread_id,\n pos: basePos + i + 1,\n append_id: appendId,\n });\n }\n }\n }\n\n // Step 5b: new threads — fresh turn_thread + mapping rows.\n for (const nt of input.new_threads) {\n const newIds = newIdsByThread.get(nt.thread_id) ?? [];\n const usage = appendUsageByThread.get(nt.thread_id) ?? getEmptyCurrentContextUsage();\n const threadCheckpoint: TurnThreadCheckpoint = {\n parent: nt.parent,\n completion: null,\n };\n turnThreadRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: nt.thread_id,\n checkpoint: jsonbBind(threadCheckpoint),\n agent_info: nt.agent_info !== null ? jsonbBind(nt.agent_info) : null,\n current_context_usage: jsonbBind(usage),\n updated_at: now,\n });\n\n for (let i = 0; i < newIds.length; i++) {\n const appendId = newIds[i];\n if (appendId !== undefined) {\n turnThreadContextRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: nt.thread_id,\n pos: i + 1,\n append_id: appendId,\n });\n }\n }\n }\n\n if (turnThreadRows.length > 0) {\n await trx.insertInto('turn_thread').values(turnThreadRows).execute();\n }\n\n if (turnThreadContextRows.length > 0) {\n await trx.insertInto('turn_thread_context').values(turnThreadContextRows).execute();\n }\n\n // Step 6: insert capability state rows (thread coverage asserted above).\n const capabilityStateRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: RawBuilder<string> | null;\n updated_at: string;\n }[] = [];\n\n for (const capability of input.capability_states) {\n if (capability.capability_state === null) {\n continue;\n }\n for (const [key, state] of Object.entries(capability.capability_state)) {\n capabilityStateRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: capability.thread_id,\n key,\n state: state !== null ? jsonbBind(state) : null,\n updated_at: now,\n });\n }\n }\n\n if (capabilityStateRows.length > 0) {\n await trx.insertInto('thread_capability_state').values(capabilityStateRows).execute();\n }\n });\n } catch (err) {\n if (err instanceof SessionStoreNotFoundError || err instanceof SessionStoreConflictError) {\n throw err;\n }\n if (isUniqueViolation(err)) {\n throw new TurnAlreadyExistsError(input.turn.turn_id, { cause: err });\n }\n throw err;\n }\n}\n\n/**\n * freezeAndGetTurn — cancel if still running, then return the assembled record.\n * Terminal turns are returned unchanged (freeze is a plain read).\n */\nexport async function freezeAndGetTurn(db: Kysely<Database>, input: FreezeAndGetTurnInput): Promise<TurnRecord> {\n return await db.transaction().execute(async trx => {\n const cancelledState: TerminalTurnState = {\n status: 'cancelled',\n reason: input.reason,\n completed_at: nowIso(),\n };\n\n const updateResult = await trx\n .updateTable('turn')\n .set({\n state: jsonbBind(cancelledState),\n updated_at: nowIso(),\n })\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(updateResult.numUpdatedRows) > 0) {\n await trx\n .insertInto('session_event')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: input.turn_done_event.id,\n event: jsonbBind(input.turn_done_event),\n created_at: input.turn_done_event.created_at,\n })\n .execute();\n }\n\n const record = await assembleTurnRecord(trx, input);\n if (!record) {\n throw new TurnNotFoundError(input.turn_id);\n }\n return record;\n });\n}\n\n/**\n * getTurn — deferred read tx so assembleTurnRecord's SELECTs share one snapshot.\n * ImmediateSqliteDriver maps setAccessMode('read only') → BEGIN (not IMMEDIATE).\n */\nexport async function getTurn(db: Kysely<Database>, input: GetTurnInput): Promise<TurnRecord<TurnCustom> | undefined> {\n return db\n .transaction()\n .setAccessMode('read only')\n .execute(trx => assembleTurnRecord(trx, input));\n}\n\n/**\n * listTurns — ORDER BY created_at, turn_id; LIMIT limit+1 OFFSET offset.\n * Returns turn rows only (no snapshot assembly); use getTurn for full TurnRecord.\n */\nexport async function listTurns(db: Kysely<Database>, input: ListTurnsInput): Promise<ListTurnsResult> {\n const rows = await db\n .selectFrom('turn')\n .select([\n 'session_id',\n 'turn_id',\n 'first_turn_id',\n 'previous_turn_id',\n jsonText<string[]>(sql.ref('ancestor_ids')).as('ancestor_ids'),\n jsonText<TurnInputItem[]>(sql.ref('input')).as('input'),\n jsonText<TurnState>(sql.ref('state')).as('state'),\n jsonText<Record<string, unknown> | null>(sql.ref('custom')).as('custom'),\n 'created_at',\n 'updated_at',\n ])\n .where('session_id', '=', input.session_id)\n .orderBy('created_at', 'asc')\n .orderBy('turn_id', 'asc')\n .limit(input.limit + 1)\n .offset(input.offset)\n .execute();\n\n const hasMore = rows.length > input.limit;\n const page = hasMore ? rows.slice(0, input.limit) : rows;\n\n const turns: TurnRecordWithoutSnapshot<TurnCustom>[] = page.map(row => ({\n turn_id: row.turn_id,\n session_id: row.session_id,\n first_turn_id: row.first_turn_id,\n ancestor_ids: row.ancestor_ids,\n previous_turn_id: row.previous_turn_id,\n state: row.state,\n input: row.input,\n created_at: new Date(row.created_at),\n updated_at: new Date(row.updated_at),\n custom: parseTurnCustom(row.custom),\n }));\n\n return {\n turns,\n next_offset: hasMore ? input.offset + input.limit : null,\n };\n}\n\n/**\n * updateTurnState — conditional on state->>'status'='running'.\n * 0 rows → SELECT by PK → missing NotFound, present Conflict (first terminal write wins).\n */\nexport async function updateTurnState(db: Kysely<Database>, input: UpdateTurnStateInput): Promise<void> {\n await db.transaction().execute(async trx => {\n const result = await trx\n .updateTable('turn')\n .set({\n state: jsonbBind(input.state),\n updated_at: nowIso(),\n })\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n const numUpdated = Number(result.numUpdatedRows);\n if (numUpdated === 0) {\n const existing = await trx\n .selectFrom('turn')\n .select([jsonText<TurnState>(sql.ref('state')).as('state')])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .executeTakeFirst();\n\n if (!existing) {\n throw new TurnNotFoundError(input.turn_id);\n }\n throw new TurnNotRunningError(input.turn_id, terminalTurnState(existing.state, input.turn_id));\n }\n\n await trx\n .insertInto('session_event')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: input.turn_done_event.id,\n event: jsonbBind(input.turn_done_event),\n created_at: input.turn_done_event.created_at,\n })\n .execute();\n });\n}\n","import type { PatchThreadCapabilityStateInput } from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport { sql, type Kysely } from 'kysely';\nimport { jsonbBind, nowIso } from '../../sqlExpressions';\nimport type { Database } from '../../types';\nimport { classifyTurnFenceWriteFailure } from './turns';\n\n/**\n * patchThreadCapabilityState — single-statement fenced upsert on the PER-TURN PK.\n * Does NOT bump turn.updated_at.\n * State is bound as SQL NULL when input.state is null (matches Postgres contract).\n */\nexport async function patchThreadCapabilityState(\n db: Kysely<Database>,\n input: PatchThreadCapabilityStateInput,\n): Promise<void> {\n await db.transaction().execute(async trx => {\n // Fence inside IMMEDIATE transaction: verify turn is still running.\n const fenceRow = await trx\n .selectFrom('turn')\n .select(sql`1`.as('one'))\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (!fenceRow) {\n await classifyTurnFenceWriteFailure(trx, input);\n }\n\n const now = nowIso();\n const stateValue = input.state !== null ? jsonbBind(input.state) : null;\n\n await trx\n .insertInto('thread_capability_state')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: input.thread_id,\n key: input.key,\n state: stateValue,\n updated_at: now,\n })\n .onConflict(oc =>\n oc.columns(['session_id', 'turn_id', 'thread_id', 'key']).doUpdateSet({\n state: sql`excluded.state`,\n updated_at: sql`excluded.updated_at`,\n }),\n )\n .execute();\n });\n}\n","import type { PersistedTurnEvent, SessionEventItem } from '@truefoundry/trueforge-core/agent-session/schemas/events';\nimport type { TokenPagination } from '@truefoundry/trueforge-core/agent-session/schemas/pagination';\nimport type {\n AppendToEventsInput,\n ListSessionEventsInput,\n ListTurnEventsInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeOffsetPageToken,\n paginateOffsetRows,\n} from '@truefoundry/trueforge-core/agent-session/store/OffsetPageToken';\nimport {\n decodeSessionEventPageToken,\n paginateSessionEventRows,\n type SessionEventPageCursor,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionEventPageToken';\nimport {\n SessionNotFoundError,\n TurnNotFoundError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport { sql, type Kysely } from 'kysely';\nimport { jsonbBind, jsonText } from '../../sqlExpressions';\nimport type { Database } from '../../types';\nimport { classifyTurnFenceWriteFailure, type TurnKeys } from './turns';\n\nexport async function appendToEvents(db: Kysely<Database>, input: AppendToEventsInput): Promise<void> {\n if (input.events.length === 0) {\n return;\n }\n\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n // Fence check first inside BEGIN IMMEDIATE; then batched insert.\n await db.transaction().execute(async trx => {\n const fenceRow = await trx\n .selectFrom('turn')\n .select(sql`1`.as('one'))\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (!fenceRow) {\n await classifyTurnFenceWriteFailure(trx, keys);\n }\n\n const eventRows = input.events.map(event => ({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: event.id,\n event: jsonbBind(event),\n created_at: event.created_at,\n }));\n\n await trx.insertInto('session_event').values(eventRows).execute();\n });\n}\n\n/**\n * listTurnEvents — one statement: drive from turn, left-join a page of events.\n * Missing turn → 0 rows → TurnNotFoundError. Empty log → one null-event sentinel.\n */\nexport async function listTurnEvents(\n db: Kysely<Database>,\n input: ListTurnEventsInput,\n): Promise<{ data: PersistedTurnEvent[]; pagination: TokenPagination }> {\n const offset = decodeOffsetPageToken(input.page_token);\n const limit = input.limit;\n const eventOrder = input.order === 'desc' ? 'desc' : 'asc';\n\n const rows = await db\n .selectFrom('turn as t')\n .leftJoin(\n eb =>\n eb\n .selectFrom('session_event')\n .select(['session_id', 'turn_id', 'event_id', jsonText<PersistedTurnEvent>(sql.ref('event')).as('event')])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .orderBy('event_id', eventOrder)\n .limit(limit + 1)\n .offset(offset)\n .as('e'),\n join => join.onRef('e.session_id', '=', 't.session_id').onRef('e.turn_id', '=', 't.turn_id'),\n )\n .select(['t.turn_id', 'e.event'])\n .where('t.session_id', '=', input.session_id)\n .where('t.turn_id', '=', input.turn_id)\n .orderBy('e.event_id', eventOrder)\n .execute();\n\n if (rows.length === 0) {\n throw new TurnNotFoundError(input.turn_id);\n }\n\n const events: PersistedTurnEvent[] = [];\n for (const row of rows) {\n if (row.event !== null) {\n events.push(row.event);\n }\n }\n\n return paginateOffsetRows(events, limit, offset);\n}\n\n/** Anchor turn fields needed for chain resolution. */\nexport interface AnchorTurn {\n turn_id: string;\n ancestor_ids: string[];\n}\n\n/**\n * Full chain (oldest first, anchor last). `ancestor_ids` may be only the\n * previous N ancestors, so spill through the oldest ancestor's own window\n * until a root or gap. A missing turn or repeated id ends the walk.\n */\nexport async function resolveAncestorChain(\n db: Kysely<Database>,\n sessionId: string,\n anchor: AnchorTurn,\n): Promise<string[]> {\n const chain = [...anchor.ancestor_ids, anchor.turn_id];\n const seen = new Set(chain);\n let oldestId = chain[0];\n while (oldestId && oldestId !== anchor.turn_id) {\n const oldest = await db\n .selectFrom('turn')\n .select([jsonText<string[]>(sql.ref('ancestor_ids')).as('ancestor_ids')])\n .where('session_id', '=', sessionId)\n .where('turn_id', '=', oldestId)\n .executeTakeFirst();\n if (!oldest) {\n break;\n }\n const older = oldest.ancestor_ids.filter(id => !seen.has(id));\n if (older.length === 0) {\n break;\n }\n chain.unshift(...older);\n for (const id of older) {\n seen.add(id);\n }\n oldestId = older[0];\n }\n return chain;\n}\n\nexport async function listSessionEvents(\n db: Kysely<Database>,\n input: ListSessionEventsInput,\n): Promise<{ data: SessionEventItem[]; pagination: TokenPagination }> {\n const limit = input.limit;\n\n const session = await db\n .selectFrom('session')\n .select('last_turn_id')\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n if (!session) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n const decodedCursor = input.page_token === undefined ? undefined : decodeSessionEventPageToken(input.page_token);\n const lastTurnId = decodedCursor?.last_turn_id ?? input.last_turn_id ?? session.last_turn_id;\n if (lastTurnId === null) {\n return { data: [], pagination: { limit } };\n }\n const cursor: SessionEventPageCursor = {\n last_turn_id: lastTurnId,\n offset: decodedCursor?.offset ?? 0,\n };\n\n const anchor = await db\n .selectFrom('turn')\n .select(['turn_id', jsonText<string[]>(sql.ref('ancestor_ids')).as('ancestor_ids')])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', cursor.last_turn_id)\n .executeTakeFirst();\n if (!anchor) {\n throw new TurnNotFoundError(cursor.last_turn_id);\n }\n\n const chainIds = await resolveAncestorChain(db, input.session_id, {\n turn_id: anchor.turn_id,\n ancestor_ids: anchor.ancestor_ids,\n });\n\n // Bind the ancestor chain as a JSON array; json_each gives (key=index, value=turn_id).\n const chainJson = JSON.stringify(chainIds);\n\n const rows = await db\n .selectFrom(sql<{ key: number; value: string }>`json_each(${chainJson})`.as('c'))\n .innerJoin('session_event as e', join =>\n join.on('e.session_id', '=', input.session_id).on(sql<boolean>`e.turn_id = c.value`),\n )\n .select([sql<string>`c.value`.as('turn_id'), jsonText<SessionEventItem['event']>(sql.ref('e.event')).as('event')])\n .orderBy(sql`c.key`, 'desc')\n .orderBy('e.event_id', 'desc')\n .limit(limit + 1)\n .offset(cursor.offset)\n .execute();\n\n return paginateSessionEventRows(rows, limit, cursor);\n}\n","import { AgentSpecSchema, type AgentSpec, type SessionAgent } from '@truefoundry/trueforge-core/agent-session';\n\n/** Flatten domain agent for SQL session columns (XOR agent_id / agent_spec; optional name snapshot). */\nexport function sessionAgentToColumns(agent: SessionAgent): {\n agent_id: string | null;\n agent_name: string | null;\n agent_spec: AgentSpec | null;\n} {\n if (agent.type === 'reference') {\n return { agent_id: agent.id, agent_name: agent.name, agent_spec: null };\n }\n return { agent_id: null, agent_name: null, agent_spec: agent.spec };\n}\n\n/** Rebuild domain agent from SQL session columns. */\nexport function sessionAgentFromColumns(input: {\n session_id: string;\n agent_id: string | null;\n agent_name: string | null;\n agent_spec: AgentSpec | null;\n}): SessionAgent {\n if (input.agent_id !== null && input.agent_spec === null) {\n return { type: 'reference', id: input.agent_id, name: input.agent_name };\n }\n if (input.agent_id === null && input.agent_spec !== null) {\n // Re-parse so schema defaults apply to inline specs persisted before a config field existed.\n return { type: 'inline', spec: AgentSpecSchema.parse(input.agent_spec) };\n }\n throw new Error(\n `Session ${input.session_id} has invalid agent binding (exactly one of agent_id or agent_spec required)`,\n );\n}\n","import type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport type { SessionRecord } from '@truefoundry/trueforge-core/agent-session/models/SessionRecord';\nimport type {\n CreateSessionInput,\n DeleteSessionInput,\n GetSessionInput,\n ListSessionsInput,\n UpdateSessionInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeSessionListPageToken,\n paginateSessionListRows,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionListPageToken';\nimport {\n SessionAlreadyExistsError,\n SessionNotFoundError,\n SessionStoreInvariantError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport { sql, type Kysely } from 'kysely';\nimport { sessionAgentFromColumns, sessionAgentToColumns } from '../../../sessionAgentColumns';\nimport { isUniqueViolation } from '../../client';\nimport { jsonbBind, jsonText, nowIso } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\ntype SessionCustom = Record<string, never>;\ntype ProtoSessionRecord = SessionRecord<SessionCustom>;\n\nfunction isEmptyCustomRecord(value: Record<string, unknown>): value is SessionCustom {\n return Object.keys(value).length === 0;\n}\n\nfunction parseSessionCustom(value: Record<string, unknown> | null): SessionCustom | null {\n if (value === null) {\n return null;\n }\n if (!isEmptyCustomRecord(value)) {\n throw new SessionStoreInvariantError('non-empty session custom is not supported');\n }\n return value;\n}\n\nfunction mapRowToSessionRecord(row: {\n tenant_id: string;\n session_id: string;\n created_by: string;\n agent_id: string | null;\n agent_name: string | null;\n agent_spec: AgentSpec | null;\n title: string | null;\n last_turn_id: string | null;\n custom: Record<string, unknown> | null;\n created_at: string;\n updated_at: string;\n last_activity_timestamp_ms: number;\n}): ProtoSessionRecord {\n return {\n tenant_id: row.tenant_id,\n session_id: row.session_id,\n created_by: row.created_by,\n agent: sessionAgentFromColumns({\n session_id: row.session_id,\n agent_id: row.agent_id,\n agent_name: row.agent_name,\n agent_spec: row.agent_spec,\n }),\n title: row.title,\n last_turn_id: row.last_turn_id,\n custom: parseSessionCustom(row.custom),\n created_at: new Date(row.created_at),\n updated_at: new Date(row.updated_at),\n last_activity_timestamp_ms: row.last_activity_timestamp_ms,\n };\n}\n\nfunction sessionSelectColumns() {\n return [\n 'tenant_id' as const,\n 'session_id' as const,\n 'created_by' as const,\n 'agent_id' as const,\n 'agent_name' as const,\n jsonText<AgentSpec | null>(sql.ref('agent_spec')).as('agent_spec'),\n 'title' as const,\n 'last_turn_id' as const,\n jsonText<Record<string, unknown> | null>(sql.ref('custom')).as('custom'),\n 'created_at' as const,\n 'updated_at' as const,\n 'last_activity_timestamp_ms' as const,\n ];\n}\n\nexport async function createSession(db: Kysely<Database>, input: CreateSessionInput<SessionCustom>): Promise<void> {\n const columns = sessionAgentToColumns(input.agent);\n const now = nowIso();\n\n try {\n await db\n .insertInto('session')\n .values({\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n created_by: input.created_by,\n agent_id: columns.agent_id,\n agent_name: columns.agent_name,\n agent_spec: columns.agent_spec !== null ? jsonbBind(columns.agent_spec) : null,\n title: null,\n custom: input.custom !== null ? jsonbBind(input.custom) : null,\n created_at: now,\n updated_at: now,\n last_activity_timestamp_ms: Date.now(),\n })\n .execute();\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new SessionAlreadyExistsError(input.session_id, { cause: error });\n }\n throw error;\n }\n}\n\nexport async function deleteSession(db: Kysely<Database>, input: DeleteSessionInput): Promise<void> {\n await db\n .deleteFrom('session')\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .execute();\n}\n\nexport async function getSession(\n db: Kysely<Database>,\n input: GetSessionInput,\n): Promise<ProtoSessionRecord | undefined> {\n const row = await db\n .selectFrom('session')\n .select(sessionSelectColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n\n if (row === undefined) {\n return undefined;\n }\n\n return mapRowToSessionRecord(row);\n}\n\nexport async function updateSession(db: Kysely<Database>, input: UpdateSessionInput<SessionCustom>): Promise<void> {\n const agent = input.agent;\n const title = input.title;\n\n if (agent !== undefined) {\n const existing = await getSession(db, { tenant_id: input.tenant_id, session_id: input.session_id });\n if (existing === undefined) {\n throw new SessionNotFoundError(input.session_id);\n }\n if (existing.agent.type === 'reference') {\n throw new SessionStoreInvariantError(`Session ${input.session_id} is named; agent cannot be updated`);\n }\n }\n\n let qb = db\n .updateTable('session')\n .set({\n updated_at: nowIso(),\n last_activity_timestamp_ms: Date.now(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id);\n\n if (agent !== undefined) {\n qb = qb.set({ agent_spec: jsonbBind(agent.spec) });\n }\n if (title !== undefined) {\n qb = qb.set({ title });\n }\n\n const result = await qb.executeTakeFirst();\n\n const numUpdatedRows = Number(result.numUpdatedRows);\n if (numUpdatedRows === 0) {\n throw new SessionNotFoundError(input.session_id);\n }\n}\n\nexport async function listSessions(\n db: Kysely<Database>,\n input: ListSessionsInput,\n): Promise<{\n data: ProtoSessionRecord[];\n pagination: { next_page_token?: string | undefined; previous_page_token?: string | undefined };\n}> {\n const limit = input.limit;\n const order = input.order ?? 'desc';\n const cursor = decodeSessionListPageToken(input.page_token);\n\n let query = db.selectFrom('session').select(sessionSelectColumns).where('tenant_id', '=', input.tenant_id);\n\n if (input.agent_id !== undefined) {\n query = query.where('agent_id', '=', input.agent_id);\n }\n if (input.created_by !== undefined) {\n query = query.where('created_by', '=', input.created_by);\n }\n if (input.start_timestamp !== undefined) {\n query = query.where('created_at', '>=', input.start_timestamp.toISOString());\n }\n if (input.end_timestamp !== undefined) {\n query = query.where('created_at', '<=', input.end_timestamp.toISOString());\n }\n\n if (cursor) {\n const cursorUpdatedAt = cursor.updated_at;\n const sessionId = cursor.session_id;\n if (order === 'asc') {\n query = query.where(eb =>\n eb.or([\n eb('updated_at', '>', cursorUpdatedAt),\n eb.and([eb('updated_at', '=', cursorUpdatedAt), eb('session_id', '>', sessionId)]),\n ]),\n );\n } else {\n query = query.where(eb =>\n eb.or([\n eb('updated_at', '<', cursorUpdatedAt),\n eb.and([eb('updated_at', '=', cursorUpdatedAt), eb('session_id', '<', sessionId)]),\n ]),\n );\n }\n }\n\n if (order === 'asc') {\n query = query.orderBy('updated_at', 'asc').orderBy('session_id', 'asc');\n } else {\n query = query.orderBy('updated_at', 'desc').orderBy('session_id', 'desc');\n }\n\n const rows = await query.limit(limit + 1).execute();\n // SQLite stores updated_at as ISO text already — use it directly for the keyset cursor.\n const { data: pageRows, pagination } = paginateSessionListRows(rows, limit, row => row.updated_at);\n\n return { data: pageRows.map(mapRowToSessionRecord), pagination };\n}\n","import type {\n AddThreadsInput,\n AppendToThreadContextInput,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n RemoveThreadsInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport type {\n ContextMessage,\n SubAgentCompletionMarker,\n} from '@truefoundry/trueforge-core/core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport { sql, type Kysely, type RawBuilder, type Transaction } from 'kysely';\nimport { jsonbBind, jsonbSet, nowIso } from '../../sqlExpressions';\nimport type { Database, TurnThreadCheckpoint } from '../../types';\nimport { sortedByAppendId } from '../sqlExpressions';\nimport {\n assertTurnRunning,\n classifyTurnFenceWriteFailure,\n classifyTurnThreadWriteFailure,\n type TurnKeys,\n} from './turns';\n\ntype DbOrTrx = Kysely<Database> | Transaction<Database>;\n\n/**\n * addThreads — fenced tx: INSERT log rows, INSERT turn_thread rows,\n * INSERT turn_thread_context rows, INSERT capability rows.\n */\nexport async function addThreads(db: Kysely<Database>, input: AddThreadsInput): Promise<void> {\n await db.transaction().execute(async trx => {\n await assertTurnRunning(trx, {\n session_id: input.session_id,\n turn_id: input.turn_id,\n });\n\n const now = nowIso();\n const logRows: {\n session_id: string;\n thread_id: string;\n turn_id: string;\n body: RawBuilder<string>;\n created_at: string;\n }[] = [];\n const capabilityStateRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: RawBuilder<string> | null;\n updated_at: string;\n }[] = [];\n const turnThreadPlans: {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: RawBuilder<string> | null;\n current_context_usage: CurrentContextUsage;\n }[] = [];\n\n for (const thread of input.threads) {\n const threadCheckpoint: TurnThreadCheckpoint = {\n parent: thread.parent ?? null,\n completion: thread.completion ?? null,\n };\n turnThreadPlans.push({\n thread_id: thread.thread_id,\n checkpoint: threadCheckpoint,\n agent_info: thread.agent_info != null ? jsonbBind(thread.agent_info) : null,\n current_context_usage: thread.current_context_usage,\n });\n\n for (const body of thread.context) {\n logRows.push({\n session_id: input.session_id,\n thread_id: thread.thread_id,\n turn_id: input.turn_id,\n body: jsonbBind(body),\n created_at: now,\n });\n }\n\n const capabilityState = thread.capability_state;\n if (capabilityState != null) {\n for (const key of Object.keys(capabilityState)) {\n const state = capabilityState[key];\n if (state === undefined) {\n throw new Error(\n `capability_state['${key}'] for thread '${thread.thread_id}' is undefined — undefined is banned from capability state`,\n );\n }\n capabilityStateRows.push({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: thread.thread_id,\n key,\n state: state !== null ? jsonbBind(state) : null,\n updated_at: now,\n });\n }\n }\n }\n\n const newIdsByThread = new Map<string, number[]>();\n if (logRows.length > 0) {\n const inserted = await trx\n .insertInto('thread_context_log')\n .values(logRows)\n .returning(['thread_id', 'append_id'])\n .execute();\n for (const row of sortedByAppendId(inserted)) {\n const list = newIdsByThread.get(row.thread_id);\n if (list === undefined) {\n newIdsByThread.set(row.thread_id, [row.append_id]);\n } else {\n list.push(row.append_id);\n }\n }\n }\n\n const turnThreadRows = turnThreadPlans.map(plan => ({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: plan.thread_id,\n checkpoint: jsonbBind(plan.checkpoint),\n agent_info: plan.agent_info,\n current_context_usage: jsonbBind(plan.current_context_usage),\n updated_at: now,\n }));\n\n if (turnThreadRows.length > 0) {\n await trx.insertInto('turn_thread').values(turnThreadRows).execute();\n }\n\n const contextMappingRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n pos: number;\n append_id: number;\n }[] = [];\n\n for (const plan of turnThreadPlans) {\n const newIds = newIdsByThread.get(plan.thread_id) ?? [];\n for (let i = 0; i < newIds.length; i++) {\n const appendId = newIds[i];\n if (appendId !== undefined) {\n contextMappingRows.push({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: plan.thread_id,\n pos: i + 1,\n append_id: appendId,\n });\n }\n }\n }\n\n if (contextMappingRows.length > 0) {\n await trx.insertInto('turn_thread_context').values(contextMappingRows).execute();\n }\n\n if (capabilityStateRows.length > 0) {\n await trx.insertInto('thread_capability_state').values(capabilityStateRows).execute();\n }\n });\n}\n\n/**\n * removeThreads — fenced tx: DELETE this turn's turn_thread rows,\n * turn_thread_context rows, and capability rows.\n * Older turns keep their per-turn maps. Log rows stay (other turns may reference them).\n * Empty thread_ids is a no-op.\n */\nexport async function removeThreads(db: Kysely<Database>, input: RemoveThreadsInput): Promise<void> {\n if (input.thread_ids.length === 0) {\n return;\n }\n\n await db.transaction().execute(async trx => {\n await assertTurnRunning(trx, {\n session_id: input.session_id,\n turn_id: input.turn_id,\n });\n\n await trx\n .deleteFrom('turn_thread_context')\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .execute();\n\n await trx\n .deleteFrom('turn_thread')\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .execute();\n\n await trx\n .deleteFrom('thread_capability_state')\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .execute();\n });\n}\n\nasync function getNextPos(db: DbOrTrx, keys: TurnKeys, thread_id: string): Promise<number> {\n const maxRow = await db\n .selectFrom('turn_thread_context')\n .select([sql<number | null>`MAX(pos)`.as('max_pos')])\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .executeTakeFirst();\n return (maxRow?.max_pos ?? 0) + 1;\n}\n\nfunction completionPatchExpr(completion: SubAgentCompletionMarker | null): RawBuilder<string> {\n if (completion === null) {\n return sql`checkpoint`;\n }\n return jsonbSet(sql.ref('checkpoint'), '$.completion', completion);\n}\n\nfunction usageSetExpr(usage: CurrentContextUsage | null): RawBuilder<string> {\n if (usage === null) {\n return sql`current_context_usage`;\n }\n return sql`coalesce(${jsonbBind(usage)}, current_context_usage)`;\n}\n\nasync function fencedTurnThreadContextUpdate(\n db: Kysely<Database>,\n args: {\n keys: TurnKeys;\n thread_id: string;\n context: ContextMessage[];\n replace_array: boolean;\n current_context_usage: CurrentContextUsage | null;\n completion: SubAgentCompletionMarker | null;\n /** When replace_array, usage is set unconditionally (overwrite contract). */\n usage_unconditional: CurrentContextUsage | null;\n },\n): Promise<void> {\n const { keys, thread_id, context, replace_array } = args;\n\n await db.transaction().execute(async trx => {\n await assertTurnRunning(trx, keys);\n\n const now = nowIso();\n\n if (replace_array) {\n await trx\n .deleteFrom('turn_thread_context')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .execute();\n }\n\n if (context.length > 0) {\n const logRows = context.map(body => ({\n session_id: keys.session_id,\n thread_id,\n turn_id: keys.turn_id,\n body: jsonbBind(body),\n created_at: now,\n }));\n\n const inserted = await trx.insertInto('thread_context_log').values(logRows).returning(['append_id']).execute();\n\n let nextPos = replace_array ? 1 : await getNextPos(trx, keys, thread_id);\n\n const contextMappingRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n pos: number;\n append_id: number;\n }[] = [];\n\n for (const row of sortedByAppendId(inserted)) {\n contextMappingRows.push({\n session_id: keys.session_id,\n turn_id: keys.turn_id,\n thread_id,\n pos: nextPos,\n append_id: row.append_id,\n });\n nextPos++;\n }\n\n if (contextMappingRows.length > 0) {\n await trx.insertInto('turn_thread_context').values(contextMappingRows).execute();\n }\n }\n\n const usageExpr =\n args.usage_unconditional !== null\n ? jsonbBind(args.usage_unconditional)\n : usageSetExpr(args.current_context_usage);\n\n const updateResult = await trx\n .updateTable('turn_thread')\n .set({\n checkpoint: completionPatchExpr(args.completion),\n current_context_usage: usageExpr,\n updated_at: now,\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .executeTakeFirst();\n\n if (Number(updateResult.numUpdatedRows) === 0) {\n await classifyTurnThreadWriteFailure(trx, keys, thread_id);\n }\n });\n}\n\n/**\n * appendToThreadContext — fenced transaction: inserts log rows, appends mapping rows,\n * updates usage (COALESCE: provided wins, else keep), patches completion.\n */\nexport async function appendToThreadContext(db: Kysely<Database>, input: AppendToThreadContextInput): Promise<void> {\n await fencedTurnThreadContextUpdate(db, {\n keys: {\n session_id: input.session_id,\n turn_id: input.turn_id,\n },\n thread_id: input.thread_id,\n context: input.context,\n replace_array: false,\n current_context_usage: input.current_context_usage,\n completion: input.completion,\n usage_unconditional: null,\n });\n}\n\n/**\n * overwriteThreadContext — same fenced shape; context mapping is REPLACED.\n * Old log rows stay — ancestor turns' context mapping may reference them.\n */\nexport async function overwriteThreadContext(db: Kysely<Database>, input: OverwriteThreadContextInput): Promise<void> {\n await fencedTurnThreadContextUpdate(db, {\n keys: {\n session_id: input.session_id,\n turn_id: input.turn_id,\n },\n thread_id: input.event.thread_id,\n context: input.event.context,\n replace_array: true,\n current_context_usage: null,\n completion: null,\n usage_unconditional: input.event.current_context_usage,\n });\n}\n\n/**\n * patchMCPServers — conditional UPDATE fenced on state->>'status'='running'.\n * Shallow merge by server id (Postgres `||`): patched ids replace wholesale.\n */\nexport async function patchMCPServers(db: Kysely<Database>, input: PatchMCPServersInput): Promise<void> {\n const serversById: Record<string, (typeof input.mcp_servers)[number]> = {};\n for (const server of input.mcp_servers) {\n serversById[server.id] = server;\n }\n\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n // jsonb_patch is RFC 7396 (deep); rebuild via json_each so each id's value is replaced.\n const patchJson = JSON.stringify(serversById);\n\n const result = await db\n .updateTable('turn')\n .set({\n checkpoint: sql<string>`jsonb_set(\n checkpoint,\n '$.mcp_servers',\n coalesce((\n SELECT jsonb_group_object(key, jsonb(value))\n FROM (\n SELECT key, value\n FROM json_each(\n CASE WHEN json_type(checkpoint, '$.mcp_servers') = 'object'\n THEN json(jsonb_extract(checkpoint, '$.mcp_servers'))\n ELSE '{}' END\n )\n WHERE key NOT IN (SELECT key FROM json_each(${patchJson}))\n UNION ALL\n SELECT key, value FROM json_each(${patchJson})\n )\n ), jsonb('{}'))\n )`,\n updated_at: nowIso(),\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\n/**\n * patchSandboxInfo — LWW replace via jsonb_set on sandbox_info key.\n */\nexport async function patchSandboxInfo(db: Kysely<Database>, input: PatchSandboxInfoInput): Promise<void> {\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const result = await db\n .updateTable('turn')\n .set({\n checkpoint: jsonbSet(sql.ref('checkpoint'), '$.sandbox_info', input.sandbox_info),\n updated_at: nowIso(),\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n","import type { SessionRecord } from '@truefoundry/trueforge-core/agent-session/models/SessionRecord';\nimport type { TurnRecord } from '@truefoundry/trueforge-core/agent-session/models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '@truefoundry/trueforge-core/agent-session/schemas/events';\nimport type { TokenPagination } from '@truefoundry/trueforge-core/agent-session/schemas/pagination';\nimport type {\n AddThreadsInput,\n AppendToEventsInput,\n AppendToThreadContextInput,\n CreateSessionInput,\n CreateTurnInput,\n DeleteSessionInput,\n FreezeAndGetTurnInput,\n GetSessionInput,\n GetTurnInput,\n ISessionStore,\n ListSessionEventsInput,\n ListSessionsInput,\n ListTurnEventsInput,\n ListTurnsInput,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n PatchThreadCapabilityStateInput,\n RemoveThreadsInput,\n TurnRecordWithoutSnapshot,\n UpdateSessionInput,\n UpdateTurnStateInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeOffsetPageToken,\n encodeOffsetPageToken,\n} from '@truefoundry/trueforge-core/agent-session/store/OffsetPageToken';\nimport type { Kysely } from 'kysely';\nimport type { Database } from '../types';\nimport { patchThreadCapabilityState as patchThreadCapabilityStateQuery } from './queries/capabilities';\nimport {\n appendToEvents as appendToEventsQuery,\n listSessionEvents as listSessionEventsQuery,\n listTurnEvents as listTurnEventsQuery,\n} from './queries/events';\nimport {\n createSession as createSessionQuery,\n deleteSession as deleteSessionQuery,\n getSession as getSessionQuery,\n listSessions as listSessionsQuery,\n updateSession as updateSessionQuery,\n} from './queries/sessions';\nimport {\n addThreads as addThreadsQuery,\n appendToThreadContext as appendToThreadContextQuery,\n overwriteThreadContext as overwriteThreadContextQuery,\n patchMCPServers as patchMCPServersQuery,\n patchSandboxInfo as patchSandboxInfoQuery,\n removeThreads as removeThreadsQuery,\n} from './queries/threads';\nimport type { NewThreadRegistration } from './queries/turns';\nimport {\n createTurn as createTurnQuery,\n freezeAndGetTurn as freezeAndGetTurnQuery,\n getTurn as getTurnQuery,\n listTurns as listTurnsQuery,\n updateTurnState as updateTurnStateQuery,\n} from './queries/turns';\n\ntype SessionCustom = Record<string, never>;\ntype TurnCustom = Record<string, never>;\n\n/**\n * ## Design: append-only context log + per-turn position table\n *\n * Message bodies live in `thread_context_log`, append-only, written exactly\n * once; ids are SQLite AUTOINCREMENT (`append_id`). A turn's context per thread\n * is ordered rows in `turn_thread_context (pos, append_id)` — no array column.\n * Turns share no mutable structure: linear continuation and fork are the same\n * copy path (parent context mapping rows + new mapping rows), overwrite deletes\n * the current mapping and inserts a fresh one, and a still-running ancestor's\n * late appends touch only its OWN rows — structural leaks are impossible.\n *\n * Hard invariants:\n * 1. A turn cannot be used as `previous_turn_id` while it is still `running` —\n * `createTurn` rejects that; callers must `freezeAndGetTurn` first.\n * Tip-equality is NOT required: new roots and concurrent forks from a\n * finished tip can leave more than one turn `running` at once.\n * 2. Every turn-scoped write is fenced on `state->>'status' = 'running'`.\n * 3. Terminal turns are IMMUTABLE — a terminal read is a final read.\n * 4. BEGIN IMMEDIATE provides write locking (no FOR SHARE / FOR UPDATE).\n */\nexport class SqliteSessionStore implements ISessionStore<SessionCustom, TurnCustom> {\n constructor(private readonly db: Kysely<Database>) {}\n\n createSession(input: CreateSessionInput<SessionCustom>): Promise<void> {\n return createSessionQuery(this.db, input);\n }\n\n deleteSession(input: DeleteSessionInput): Promise<void> {\n return deleteSessionQuery(this.db, input);\n }\n\n getSession(input: GetSessionInput): Promise<SessionRecord<SessionCustom> | undefined> {\n return getSessionQuery(this.db, input);\n }\n\n updateSession(input: UpdateSessionInput<SessionCustom>): Promise<void> {\n return updateSessionQuery(this.db, input);\n }\n\n async listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<SessionCustom>[]; pagination: TokenPagination }> {\n const result = await listSessionsQuery(this.db, input);\n return {\n data: result.data,\n pagination: {\n limit: input.limit,\n ...result.pagination,\n },\n };\n }\n\n async createTurn(input: CreateTurnInput<TurnCustom>): Promise<void> {\n await createTurnQuery(this.db, {\n session_id: input.turn.session_id,\n turn: {\n turn_id: input.turn.turn_id,\n first_turn_id: input.turn.first_turn_id,\n previous_turn_id: input.turn.previous_turn_id,\n ancestor_ids: input.turn.ancestor_ids,\n input: input.turn.input,\n state: input.turn.state,\n custom: input.turn.custom,\n },\n new_threads: input.new_threads.map((thread): NewThreadRegistration => ({\n thread_id: thread.thread_id,\n parent: thread.parent,\n agent_info: thread.agent_info,\n })),\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n last_activity_timestamp_ms: Date.now(),\n update_session_title_if_not_exist: input.update_session_title_if_not_exist,\n mcp_servers: null,\n sandbox_info: null,\n });\n }\n\n freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TurnCustom>> {\n return freezeAndGetTurnQuery(this.db, input);\n }\n\n getTurn(input: GetTurnInput): Promise<TurnRecord<TurnCustom> | undefined> {\n return getTurnQuery(this.db, input);\n }\n\n async listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TurnCustom>[]; pagination: TokenPagination }> {\n const offset = decodeOffsetPageToken(input.page_token);\n const result = await listTurnsQuery(this.db, {\n session_id: input.session_id,\n limit: input.limit,\n offset,\n });\n const pagination: TokenPagination = { limit: input.limit };\n if (result.next_offset !== null) {\n pagination.next_page_token = encodeOffsetPageToken(result.next_offset);\n }\n if (offset > 0) {\n pagination.previous_page_token = encodeOffsetPageToken(Math.max(0, offset - input.limit));\n }\n return { data: result.turns, pagination };\n }\n\n updateTurnState(input: UpdateTurnStateInput): Promise<void> {\n return updateTurnStateQuery(this.db, input);\n }\n\n appendToEvents(input: AppendToEventsInput): Promise<void> {\n return appendToEventsQuery(this.db, input);\n }\n\n addThreads(input: AddThreadsInput): Promise<void> {\n return addThreadsQuery(this.db, input);\n }\n\n removeThreads(input: RemoveThreadsInput): Promise<void> {\n return removeThreadsQuery(this.db, input);\n }\n\n appendToThreadContext(input: AppendToThreadContextInput): Promise<void> {\n return appendToThreadContextQuery(this.db, input);\n }\n\n overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void> {\n return overwriteThreadContextQuery(this.db, input);\n }\n\n patchMCPServers(input: PatchMCPServersInput): Promise<void> {\n return patchMCPServersQuery(this.db, input);\n }\n\n patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void> {\n return patchSandboxInfoQuery(this.db, input);\n }\n\n patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void> {\n return patchThreadCapabilityStateQuery(this.db, input);\n }\n\n listTurnEvents(input: ListTurnEventsInput): Promise<{ data: PersistedTurnEvent[]; pagination: TokenPagination }> {\n return listTurnEventsQuery(this.db, input);\n }\n\n listSessionEvents(input: ListSessionEventsInput): Promise<{ data: SessionEventItem[]; pagination: TokenPagination }> {\n return listSessionEventsQuery(this.db, input);\n }\n}\n","import type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport type { Model, ModelProviderManifest } from '../../../schemas/modelProvider';\nimport {\n flattenProviderModels,\n ModelProviderNameConflictError,\n type CreateModelProviderInput,\n type GetModelProviderInput,\n type IModelProviderStore,\n type ModelProviderRecord,\n type UpsertModelProviderInput,\n} from '../../modelProviderStore';\nimport { isUniqueViolation } from '../client';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'model_provider'>) {\n return [\n 'tenant_id' as const,\n 'name' as const,\n jsonText<ModelProviderManifest>(eb.ref('manifest')).as('manifest'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nexport class SqliteModelProviderStore implements IModelProviderStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listProviders(tenantId: string, transaction?: Transaction<Database>): Promise<ModelProviderRecord[]> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('model_provider')\n .select(recordColumns)\n .where('tenant_id', '=', tenantId)\n .orderBy('name')\n .execute();\n }\n\n async getProvider(\n input: GetModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('model_provider')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n /**\n * SQLite has no row-level FOR UPDATE; the required write transaction (BEGIN IMMEDIATE)\n * serializes concurrent writers so RMW of secrets stays consistent.\n */\n async getProviderForUpdate(\n input: GetModelProviderInput,\n transaction: Transaction<Database>,\n ): Promise<ModelProviderRecord | undefined> {\n return await transaction\n .selectFrom('model_provider')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n async createProvider(\n input: CreateModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n try {\n return await db\n .insertInto('model_provider')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new ModelProviderNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertProvider(\n input: UpsertModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n return await db\n .insertInto('model_provider')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: jsonbBind(input.manifest),\n updated_at: timestamp,\n }),\n )\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n }\n\n async listModels(tenantId: string, transaction?: Transaction<Database>): Promise<Model[]> {\n return flattenProviderModels(await this.listProviders(tenantId, transaction));\n }\n}\n","import type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport { ulid } from 'ulid';\nimport type { OAuthClientRecord } from '../../../mcp/auth/types';\nimport type { McpServerManifest } from '../../../schemas/mcpServer';\nimport {\n fromStoredOAuthClientRecord,\n McpServerNameConflictError,\n toStoredOAuthClientRecord,\n type CreateMcpServerInput,\n type GetMcpServerInput,\n type IMcpServerStore,\n type ListMcpServersInput,\n type McpServerRecord,\n type OAuthClient,\n type OAuthServer,\n type UpsertMcpServerInput,\n} from '../../mcpServerStore';\nimport { isUniqueViolation } from '../client';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'mcp_server'>) {\n return [\n 'id' as const,\n 'tenant_id' as const,\n 'name' as const,\n jsonText<McpServerManifest>(eb.ref('manifest')).as('manifest'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nexport class SqliteMcpServerStore implements IMcpServerStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listServers(input: ListMcpServersInput, transaction?: Transaction<Database>): Promise<McpServerRecord[]> {\n if (input.names?.length === 0) {\n return [];\n }\n const db = transaction ?? this.#db;\n let query = db.selectFrom('mcp_server').select(recordColumns).where('tenant_id', '=', input.tenant_id);\n if (input.names !== undefined) {\n query = query.where('name', 'in', [...input.names]);\n }\n return await query.orderBy('name').execute();\n }\n\n async getServer(input: GetMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('mcp_server')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n /**\n * SQLite has no row-level FOR UPDATE; the required write transaction (BEGIN IMMEDIATE)\n * serializes concurrent writers so RMW of header secrets stays consistent.\n */\n async getServerForUpdate(\n input: GetMcpServerInput,\n transaction: Transaction<Database>,\n ): Promise<McpServerRecord | undefined> {\n return await transaction\n .selectFrom('mcp_server')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n async createServer(input: CreateMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n try {\n return await db\n .insertInto('mcp_server')\n .values({\n id: ulid(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n oauth_server: null,\n oauth_client: null,\n created_at: timestamp,\n updated_at: timestamp,\n })\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new McpServerNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertServer(input: UpsertMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n return await db\n .insertInto('mcp_server')\n .values({\n id: ulid(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n oauth_server: null,\n oauth_client: null,\n created_at: timestamp,\n updated_at: timestamp,\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: jsonbBind(input.manifest),\n updated_at: timestamp,\n }),\n )\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n }\n\n async getClient(params: { id: string }, transaction?: Transaction<Database>): Promise<OAuthClientRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('mcp_server')\n .select(eb => [\n jsonText<OAuthServer | null>(eb.ref('oauth_server')).as('oauth_server'),\n jsonText<OAuthClient | null>(eb.ref('oauth_client')).as('oauth_client'),\n ])\n .where('id', '=', params.id)\n .executeTakeFirst();\n if (row?.oauth_server == null || row.oauth_client == null) {\n return undefined;\n }\n return fromStoredOAuthClientRecord({ server: row.oauth_server, client: row.oauth_client });\n }\n\n async saveClient(\n params: { id: string; record: OAuthClientRecord },\n transaction?: Transaction<Database>,\n ): Promise<void> {\n const db = transaction ?? this.#db;\n const stored = toStoredOAuthClientRecord(params.record);\n await db\n .updateTable('mcp_server')\n .set({\n oauth_server: jsonbBind(stored.server),\n oauth_client: jsonbBind(stored.client),\n })\n .where('id', '=', params.id)\n .execute();\n }\n\n async deleteClient(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n const db = transaction ?? this.#db;\n await db\n .updateTable('mcp_server')\n .set({\n oauth_server: null,\n oauth_client: null,\n })\n .where('id', '=', params.id)\n .execute();\n }\n}\n","import { sql, type Kysely } from 'kysely';\nimport type { OAuthPendingAuthorization } from '../../../../mcp/auth/types';\nimport {\n fromStoredOAuthPendingAuthorizationData,\n PENDING_AUTHORIZATION_TTL_MS,\n toStoredOAuthPendingAuthorizationData,\n type OAuthPendingAuthorizationData,\n} from '../../../mcpServerStore';\nimport { isoMsAgo, jsonbBind, jsonText, nowIso } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nexport async function savePendingAuthorization(\n db: Kysely<Database>,\n pending: OAuthPendingAuthorization,\n): Promise<void> {\n const authData = toStoredOAuthPendingAuthorizationData(pending);\n\n await db\n .insertInto('oauth_pending_authorization')\n .values({\n id: pending.state,\n oauth_server_id: pending.id,\n user_id: pending.userRef,\n auth_data: jsonbBind(authData),\n created_at: nowIso(),\n })\n .execute();\n}\n\n/**\n * Single-use claim: DELETE … RETURNING under the TTL filter so only one concurrent\n * callback wins the row.\n */\nexport async function consumePendingAuthorization(\n db: Kysely<Database>,\n params: { state: string },\n): Promise<OAuthPendingAuthorization | undefined> {\n const row = await db\n .deleteFrom('oauth_pending_authorization')\n .where('id', '=', params.state)\n .where('created_at', '>', isoMsAgo(PENDING_AUTHORIZATION_TTL_MS))\n .returning([\n 'id',\n 'oauth_server_id',\n 'user_id',\n jsonText<OAuthPendingAuthorizationData>(sql.ref('auth_data')).as('auth_data'),\n ])\n .executeTakeFirst();\n\n if (row === undefined) {\n return undefined;\n }\n\n return {\n state: row.id,\n id: row.oauth_server_id,\n userRef: row.user_id,\n ...fromStoredOAuthPendingAuthorizationData(row.auth_data),\n };\n}\n\nexport async function deletePendingAuthorizationsForServer(\n db: Kysely<Database>,\n params: { id: string },\n): Promise<void> {\n await db.deleteFrom('oauth_pending_authorization').where('oauth_server_id', '=', params.id).execute();\n}\n","import { sql, type Kysely } from 'kysely';\nimport type { OAuthToken } from '../../../mcpServerStore';\nimport { jsonbBind, jsonText, nowIso } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nexport async function saveToken(\n db: Kysely<Database>,\n params: { id: string; userRef: string; token: OAuthToken },\n): Promise<void> {\n await db\n .insertInto('oauth_token')\n .values({\n oauth_server_id: params.id,\n user_id: params.userRef,\n token: jsonbBind(params.token),\n updated_at: nowIso(),\n })\n .onConflict(oc =>\n oc.columns(['oauth_server_id', 'user_id']).doUpdateSet({\n token: sql`excluded.token`,\n updated_at: sql`excluded.updated_at`,\n }),\n )\n .execute();\n}\n\nexport async function getToken(\n db: Kysely<Database>,\n params: { id: string; userRef: string },\n): Promise<OAuthToken | undefined> {\n const row = await db\n .selectFrom('oauth_token')\n .select(jsonText<OAuthToken>(sql.ref('token')).as('token'))\n .where('oauth_server_id', '=', params.id)\n .where('user_id', '=', params.userRef)\n .executeTakeFirst();\n\n return row === undefined ? undefined : row.token;\n}\n\nexport async function getTokens(\n db: Kysely<Database>,\n params: { ids: string[]; userRef: string },\n): Promise<Map<string, OAuthToken>> {\n if (params.ids.length === 0) {\n return new Map();\n }\n const rows = await db\n .selectFrom('oauth_token')\n .select(['oauth_server_id', jsonText<OAuthToken>(sql.ref('token')).as('token')])\n .where('oauth_server_id', 'in', params.ids)\n .where('user_id', '=', params.userRef)\n .execute();\n\n return new Map(rows.map(row => [row.oauth_server_id, row.token]));\n}\n\nexport async function deleteToken(db: Kysely<Database>, params: { id: string; userRef: string }): Promise<void> {\n await db\n .deleteFrom('oauth_token')\n .where('oauth_server_id', '=', params.id)\n .where('user_id', '=', params.userRef)\n .execute();\n}\n\nexport async function deleteTokensForServer(db: Kysely<Database>, params: { id: string }): Promise<void> {\n await db.deleteFrom('oauth_token').where('oauth_server_id', '=', params.id).execute();\n}\n","import type { Kysely, Transaction } from 'kysely';\nimport type { IOAuthTokenStore, OAuthPendingAuthorization, OAuthToken, OAuthTokenKey } from '../../../mcp/auth/types';\nimport { fromStoredOAuthToken, toStoredOAuthToken } from '../../mcpServerStore';\nimport type { Database } from '../types';\nimport {\n consumePendingAuthorization,\n deletePendingAuthorizationsForServer,\n savePendingAuthorization,\n} from './queries/pendingAuthorization';\nimport { deleteToken, deleteTokensForServer, getToken, getTokens, saveToken } from './queries/token';\n\nexport class SqliteOAuthTokenStore implements IOAuthTokenStore<Transaction<Database>> {\n constructor(private readonly db: Kysely<Database>) {}\n\n savePendingAuthorization(pending: OAuthPendingAuthorization, transaction?: Transaction<Database>): Promise<void> {\n return savePendingAuthorization(transaction ?? this.db, pending);\n }\n\n consumePendingAuthorization(\n params: { state: string },\n transaction?: Transaction<Database>,\n ): Promise<OAuthPendingAuthorization | undefined> {\n return consumePendingAuthorization(transaction ?? this.db, params);\n }\n\n saveToken(params: OAuthTokenKey & { token: OAuthToken }, transaction?: Transaction<Database>): Promise<void> {\n return saveToken(transaction ?? this.db, {\n id: params.id,\n userRef: params.userRef,\n token: toStoredOAuthToken(params.token),\n });\n }\n\n async getToken(params: OAuthTokenKey, transaction?: Transaction<Database>): Promise<OAuthToken | undefined> {\n const stored = await getToken(transaction ?? this.db, params);\n return stored === undefined ? undefined : fromStoredOAuthToken(stored);\n }\n\n async getTokens(\n params: { ids: string[]; userRef: string },\n transaction?: Transaction<Database>,\n ): Promise<Map<string, OAuthToken>> {\n const stored = await getTokens(transaction ?? this.db, params);\n return new Map([...stored].map(([id, token]) => [id, fromStoredOAuthToken(token)]));\n }\n\n deleteToken(params: OAuthTokenKey, transaction?: Transaction<Database>): Promise<void> {\n return deleteToken(transaction ?? this.db, params);\n }\n\n deleteTokensForServer(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n return deleteTokensForServer(transaction ?? this.db, params);\n }\n\n deletePendingAuthorizationsForServer(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n return deletePendingAuthorizationsForServer(transaction ?? this.db, params);\n }\n}\n","import type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport type { SkillManifest } from '../../../schemas/skill';\nimport {\n SkillNameConflictError,\n type CreateSkillInput,\n type GetSkillInput,\n type ISkillStore,\n type ListSkillsInput,\n type SkillRecord,\n type UpsertSkillInput,\n} from '../../skillStore';\nimport { isUniqueViolation } from '../client';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'skill'>) {\n return [\n 'tenant_id' as const,\n 'name' as const,\n jsonText<SkillManifest>(eb.ref('manifest')).as('manifest'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nexport class SqliteSkillStore implements ISkillStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listSkills(input: ListSkillsInput, transaction?: Transaction<Database>): Promise<SkillRecord[]> {\n if (input.names?.length === 0) {\n return [];\n }\n const db = transaction ?? this.#db;\n let query = db.selectFrom('skill').select(recordColumns).where('tenant_id', '=', input.tenant_id);\n if (input.names !== undefined) {\n query = query.where('name', 'in', [...input.names]);\n }\n return await query.orderBy('name').execute();\n }\n\n async getSkill(input: GetSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('skill')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n async createSkill(input: CreateSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n try {\n return await db\n .insertInto('skill')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new SkillNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertSkill(input: UpsertSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n return await db\n .insertInto('skill')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: jsonbBind(input.manifest),\n updated_at: timestamp,\n }),\n )\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n }\n}\n","import type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport type { SandboxBuildMetadata, SandboxProviderManifest } from '../../../schemas/sandboxProvider';\nimport {\n type ISandboxProviderStore,\n type SandboxProviderRecord,\n type UpdateSandboxStatusInput,\n type UpsertSandboxProviderInput,\n} from '../../sandboxProviderStore';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest/build_metadata as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'sandbox_provider'>) {\n return [\n 'tenant_id' as const,\n jsonText<SandboxProviderManifest>(eb.ref('manifest')).as('manifest'),\n 'status' as const,\n 'status_reason' as const,\n jsonText<SandboxBuildMetadata>(eb.ref('build_metadata')).as('build_metadata'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nexport class SqliteSandboxProviderStore implements ISandboxProviderStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async getSandboxProvider(\n tenantId: string,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('sandbox_provider')\n .select(recordColumns)\n .where('tenant_id', '=', tenantId)\n .executeTakeFirst();\n }\n\n /**\n * SQLite has no row-level FOR UPDATE; the required write transaction (BEGIN IMMEDIATE)\n * serializes concurrent writers so RMW of secrets stays consistent.\n */\n async getSandboxProviderForUpdate(\n tenantId: string,\n transaction: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n return await transaction\n .selectFrom('sandbox_provider')\n .select(recordColumns)\n .where('tenant_id', '=', tenantId)\n .executeTakeFirst();\n }\n\n async upsertSandboxProvider(\n input: UpsertSandboxProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n return await db\n .insertInto('sandbox_provider')\n .values({\n tenant_id: input.tenant_id,\n manifest: jsonbBind(input.manifest),\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? jsonbBind(input.build_metadata) : null,\n created_at: timestamp,\n updated_at: timestamp,\n })\n .onConflict(oc =>\n oc.columns(['tenant_id']).doUpdateSet({\n manifest: jsonbBind(input.manifest),\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? jsonbBind(input.build_metadata) : null,\n updated_at: timestamp,\n }),\n )\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n }\n\n async updateSandboxStatus(\n input: UpdateSandboxStatusInput,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .updateTable('sandbox_provider')\n .set({\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? jsonbBind(input.build_metadata) : null,\n updated_at: nowIso(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .returning(recordColumns)\n .executeTakeFirst();\n }\n}\n","import type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport { ulid } from 'ulid';\nimport {\n AgentNameConflictError,\n parseStoredAgentSpec,\n type AgentRecord,\n type CreateAgentInput,\n type DeleteAgentInput,\n type GetAgentInput,\n type IAgentStore,\n type UpdateAgentInput,\n} from '../../agentStore';\nimport { isUniqueViolation } from '../client';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'agent'>) {\n return [\n 'id' as const,\n 'tenant_id' as const,\n 'name' as const,\n jsonText<AgentSpec>(eb.ref('manifest')).as('manifest'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nfunction toRecord(row: {\n id: string;\n tenant_id: string;\n name: AgentRecord['name'];\n manifest: AgentSpec;\n created_at: string;\n updated_at: string;\n}): AgentRecord {\n return { ...row, manifest: parseStoredAgentSpec(row.manifest) };\n}\n\nexport class SqliteAgentStore implements IAgentStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listAgents(tenantId: string, transaction?: Transaction<Database>): Promise<AgentRecord[]> {\n const db = transaction ?? this.#db;\n const rows = await db\n .selectFrom('agent')\n .select(recordColumns)\n .where('tenant_id', '=', tenantId)\n .orderBy('name')\n .execute();\n return rows.map(toRecord);\n }\n\n async getAgent(input: GetAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord | undefined> {\n const db = transaction ?? this.#db;\n let query = db.selectFrom('agent').select(recordColumns).where('tenant_id', '=', input.tenant_id);\n if ('id' in input) {\n query = query.where('id', '=', input.id);\n } else {\n query = query.where('name', '=', input.name);\n }\n const row = await query.executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async createAgent(input: CreateAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n try {\n const row = await db\n .insertInto('agent')\n .values({\n id: ulid().toLowerCase(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new AgentNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async updateAgent(input: UpdateAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .updateTable('agent')\n .set({\n manifest: jsonbBind(input.manifest),\n updated_at: nowIso(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .where('id', '=', input.id)\n .returning(recordColumns)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async deleteAgent(input: DeleteAgentInput, transaction?: Transaction<Database>): Promise<void> {\n const db = transaction ?? this.#db;\n await db.deleteFrom('agent').where('tenant_id', '=', input.tenant_id).where('id', '=', input.id).execute();\n }\n}\n","import { Kysely, PostgresDialect } from 'kysely';\nimport pg, { Pool } from 'pg';\n\nimport type { Database } from './types';\n\nconst INT8_OID = 20;\n/**\n * Postgres OID for `bigint[]` / `_int8`. Scalar int8 parser (OID 20) does NOT cover arrays.\n * Widened setter: node-pg's TypeId enum omits array OIDs.\n */\nconst setTypeParserByOid: (oid: number, parser: (value: string) => unknown) => void = pg.types.setTypeParser.bind(\n pg.types,\n);\n\n/**\n * Parse a Postgres array literal of int8 into number[].\n * Safe below Number.MAX_SAFE_INTEGER (2^53) — same contract as the scalar int8 parser.\n * Identity append_ids stay far below that bound.\n */\nfunction parseInt8Array(value: string): number[] {\n if (value === '{}' || value === '') {\n return [];\n }\n // Plain unquoted numeric elements (bigint[] never needs quotes).\n return value\n .slice(1, -1)\n .split(',')\n .map(element => Number(element));\n}\n\nfunction configurePgTypeParsers(): void {\n pg.types.setTypeParser(INT8_OID, Number);\n setTypeParserByOid(1016, parseInt8Array);\n}\n\nexport function createDb(options: {\n connectionString: string;\n poolMax: number;\n /** Postgres `statement_timeout` in ms. Applied to every pooled connection. */\n statementTimeoutMs: number;\n /** Postgres `idle_in_transaction_session_timeout` in ms. Applied to every pooled connection. */\n idleInTransactionSessionTimeoutMs: number;\n}): Kysely<Database> {\n const { connectionString, poolMax, statementTimeoutMs, idleInTransactionSessionTimeoutMs } = options;\n configurePgTypeParsers();\n return new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new Pool({\n connectionString,\n max: poolMax,\n statement_timeout: statementTimeoutMs,\n idle_in_transaction_session_timeout: idleInTransactionSessionTimeoutMs,\n }),\n }),\n });\n}\n\n/**\n * Match Postgres errors by SQLSTATE without `instanceof DatabaseError`.\n * instanceof breaks silently when two copies of pg-protocol load (version skew / dual CJS+ESM);\n * checking `code` is the conventional node-postgres pattern.\n */\nexport function isPgErrorCode(err: unknown, code: string): boolean {\n if (typeof err !== 'object' || err === null || !('code' in err)) {\n return false;\n }\n return err.code === code;\n}\n\nexport function isUniqueViolation(err: unknown): boolean {\n return isPgErrorCode(err, '23505');\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport type { Kysely } from 'kysely';\nimport { FileMigrationProvider, Migrator } from 'kysely/migration';\n\nimport type { Database } from './postgres/types';\n\n/**\n * Runs all pending Postgres migrations.\n *\n * This module lives at `src/db/` (bundled into `dist/main.js`) so the folder is\n * always `…/postgres/migrations` — source or production.\n */\nexport async function migrateToLatest(db: Kysely<Database>): Promise<void> {\n const migrator = new Migrator({\n db,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(import.meta.dirname, 'postgres', 'migrations'),\n }),\n });\n\n const { error, results } = await migrator.migrateToLatest();\n\n results?.forEach(it => {\n if (it.status === 'Success') {\n console.log(`migration \"${it.migrationName}\" was executed successfully`);\n } else if (it.status === 'Error') {\n console.error(`failed to execute migration \"${it.migrationName}\"`);\n }\n });\n\n if (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error('failed to migrate', { cause: error });\n }\n}\n","/**\n * Primary Redis connection, owned by the server: created and connected at\n * boot, closed last during shutdown. Injected into the request-reply\n * transport (which duplicates it only for its subscriber).\n */\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport { createClient, type RedisClientType } from 'redis';\nimport type { Logger } from 'winston';\n\nexport async function connectRedis(input: { url: string; logger: Logger }): Promise<RedisClientType> {\n const client: RedisClientType = createClient({ url: input.url });\n // Without an 'error' listener node-redis crashes the process on emit;\n // reconnects are automatic, so log and keep running.\n client.on('error', (error: Error) => {\n input.logger.error('[Redis] Client error', extractErrorLogFields(error));\n });\n await client.connect();\n return client;\n}\n","/**\n * Shared Kysely SQL expression helpers for Postgres stores.\n */\nimport { sql, type Expression, type RawBuilder } from 'kysely';\n\n/** Bind a JS value as jsonb (stringified + cast). Required for arrays and for `||` / jsonb_set operands. */\nexport function json<T>(value: T): RawBuilder<T> {\n return sql`${JSON.stringify(value)}::jsonb`;\n}\n\n/**\n * `jsonb_set(target, path, new_value)`.\n * `path` may be a text[] expression (`sql\\`ARRAY['threads', ${id}]\\``) or a literal path\n * expression (`sql\\`'{sandbox_info}'\\`` / `sql\\`'{completion}'\\``).\n */\nexport function jsonbSet<T = unknown>(\n target: Expression<unknown>,\n path: Expression<unknown>,\n newValue: Expression<unknown>,\n): RawBuilder<T> {\n return sql<T>`jsonb_set(${target}, ${path}, ${newValue})`;\n}\n\n/** `now()` timestamptz expression. */\nexport function now(): RawBuilder<Date> {\n return sql<Date>`now()`;\n}\n\nexport function nowMinusMs(ms: number): RawBuilder<Date> {\n return sql<Date>`now() - ${ms}::double precision * interval '1 millisecond'`;\n}\n","/**\n * Session-store-only helpers for Postgres (VALUES / unnest join shapes).\n * Shared JSON/time helpers live in `../sqlExpressions`.\n */\nimport { sql, type AliasedRawBuilder, type Expression } from 'kysely';\n\n/**\n * Typed `(VALUES ...) AS alias(col1, col2, ...)` for use in `.selectFrom(...)`.\n * VALUES params are unknown→text unless cast — pass `sql\\`${n}::bigint\\`` (etc.) for non-text cols.\n * @see https://kysely.dev/docs/recipes/extending-kysely\n */\nexport function values<R extends object, A extends string>(records: R[], alias: A): AliasedRawBuilder<R, A> {\n const first = records[0];\n if (first === undefined) {\n throw new Error('values() requires at least one record');\n }\n const keys = Object.keys(first) as (keyof R & string)[];\n\n const valueTuples = sql.join(records.map(r => sql`(${sql.join(keys.map(k => r[k]))})`));\n\n const wrappedAlias = sql.ref(alias);\n const wrappedColumns = sql.join(keys.map(key => sql.ref(key)));\n const aliasSql = sql`${wrappedAlias}(${wrappedColumns})`;\n\n return sql<R>`(values ${valueTuples})`.as<A>(aliasSql);\n}\n\n/**\n * `unnest(ids::text[]) WITH ORDINALITY AS alias(turn_id, pos)` for `.selectFrom(...)`.\n * Used by listSessionEvents mode-2 (ancestor chain order).\n */\nexport function unnestWithOrdinality<A extends string>(\n ids: string[],\n alias: A,\n): AliasedRawBuilder<{ turn_id: string; pos: number }, A> {\n const wrappedAlias = sql.ref(alias);\n const aliasSql = sql`${wrappedAlias}(turn_id, pos)`;\n return sql<{ turn_id: string; pos: number }>`unnest(${ids}::text[]) WITH ORDINALITY`.as<A>(aliasSql);\n}\n\n/**\n * `LATERAL unnest(array_expr) WITH ORDINALITY AS alias(append_id, pos)` for join use.\n * Kysely 0.29 has no leftJoinLateral builder — this expression is the join RHS.\n * Used by getTurn context assembly so empty-context threads still emit a row.\n */\nexport function lateralUnnestBigintArrayWithOrdinality<A extends string>(\n arrayExpr: Expression<number[] | null>,\n alias: A,\n): AliasedRawBuilder<{ append_id: number; pos: number }, A> {\n const wrappedAlias = sql.ref(alias);\n const aliasSql = sql`${wrappedAlias}(append_id, pos)`;\n return sql<{ append_id: number; pos: number }>`LATERAL unnest(${arrayExpr}) WITH ORDINALITY`.as<A>(aliasSql);\n}\n","import type { TurnRecord, TurnSnapshot } from '@truefoundry/trueforge-core/agent-session/models/TurnRecord';\nimport {\n type TerminalTurnState,\n type TurnInputItem,\n type TurnState,\n} from '@truefoundry/trueforge-core/agent-session/schemas/turn';\nimport { assertCreateTurnThreadDelta } from '@truefoundry/trueforge-core/agent-session/store/assertCreateTurnThreadDelta';\nimport type {\n FreezeAndGetTurnInput,\n TurnRecordWithoutSnapshot,\n UpdateTurnStateInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n PreviousTurnRunningError,\n SessionNotFoundError,\n SessionStoreConflictError,\n SessionStoreInvariantError,\n SessionStoreNotFoundError,\n TurnAlreadyExistsError,\n TurnNotFoundError,\n TurnNotRunningError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport type { CapabilityState, JsonValue } from '@truefoundry/trueforge-core/core/capabilities/AgentCapability';\nimport type { AgentInfo, AgentParent, MCPServerInitInfo } from '@truefoundry/trueforge-core/core/events/schema';\nimport type { AgentThreadSnapshot, ContextMessage } from '@truefoundry/trueforge-core/core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport { getEmptyCurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport type { SandboxInfo } from '@truefoundry/trueforge-core/core/sandbox/Sandbox';\nimport { sql, type Kysely, type QueryCreator, type RawBuilder, type Transaction } from 'kysely';\nimport { isUniqueViolation } from '../../client';\nimport { json } from '../../sqlExpressions';\nimport type { Database, TurnCheckpoint, TurnThreadCheckpoint } from '../../types';\nimport { lateralUnnestBigintArrayWithOrdinality } from '../sqlExpressions';\n\ntype TurnCustom = Record<string, never>;\n\nfunction isEmptyCustomRecord(value: Record<string, unknown>): value is TurnCustom {\n return Object.keys(value).length === 0;\n}\n\nfunction parseTurnCustom(value: Record<string, unknown> | null): TurnCustom | null {\n if (value === null) {\n return null;\n }\n if (!isEmptyCustomRecord(value)) {\n throw new SessionStoreInvariantError('non-empty turn custom is not supported');\n }\n return value;\n}\n\n/** New thread metadata; mutable per-turn data arrives through dedicated fields. */\nexport interface NewThreadRegistration {\n thread_id: string;\n parent: AgentParent | null;\n agent_info: AgentInfo | null;\n}\n\nexport interface TurnKeys {\n session_id: string;\n turn_id: string;\n}\n\nexport interface NewContextAppend {\n thread_id: string;\n context: ContextMessage[];\n current_context_usage: CurrentContextUsage | null;\n}\n\nexport interface CreateTurnTurnFields {\n turn_id: string;\n first_turn_id: string;\n previous_turn_id: string | null;\n ancestor_ids: string[];\n input: TurnInputItem[];\n state: TurnState;\n custom: Record<string, unknown> | null;\n}\n\nexport interface CreateTurnInput {\n session_id: string;\n turn: CreateTurnTurnFields;\n new_threads: NewThreadRegistration[];\n new_context_appends: NewContextAppend[];\n capability_states: {\n thread_id: string;\n capability_state: CapabilityState | null;\n }[];\n last_activity_timestamp_ms: number;\n update_session_title_if_not_exist: string | null;\n mcp_servers: Record<string, MCPServerInitInfo> | null;\n sandbox_info: SandboxInfo | null;\n}\n\nexport interface GetTurnInput {\n session_id: string;\n turn_id: string;\n}\n\nexport interface ListTurnsInput {\n session_id: string;\n limit: number;\n offset: number;\n}\n\nexport interface ListTurnsResult {\n turns: TurnRecordWithoutSnapshot<TurnCustom>[];\n next_offset: number | null;\n}\n\ntype DbOrTrx = Kysely<Database> | Transaction<Database>;\ntype TurnFenceDb = DbOrTrx | QueryCreator<Database>;\n\nfunction terminalTurnState(state: TurnState, turn_id: string): TerminalTurnState {\n switch (state.status) {\n case 'running':\n throw new SessionStoreInvariantError(`expected terminal state for turn ${turn_id}, got running`);\n case 'done':\n case 'cancelled':\n case 'error':\n return state;\n }\n}\n\n/**\n * Locking CTE body for single-statement turn-scoped writes: fence + write in one\n * network call. Under READ COMMITTED, FOR SHARE re-checks the predicate after a\n * lock wait, so a committed freeze empties the fence and the write inserts 0 rows;\n * error classification happens on that rare 0-row path.\n * Multi-statement turn-scoped writes use {@link assertTurnRunning} instead.\n */\nexport function turnRunningFence(db: TurnFenceDb, keys: TurnKeys) {\n return db\n .selectFrom('turn')\n .select(sql`1`.as('one'))\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql`state->>'status'`, '=', 'running')\n .forShare();\n}\n\n/** Classify a 0-row fenced write: missing turn vs frozen/non-running turn. */\nexport async function classifyTurnFenceWriteFailure(db: Kysely<Database>, keys: TurnKeys): Promise<never> {\n const row = await db\n .selectFrom('turn')\n .select('state')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .executeTakeFirst();\n\n if (!row) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(row.state, keys.turn_id));\n}\n\n/**\n * Classify a 0-row fenced turn_thread UPDATE: turn missing/terminal vs thread row missing.\n */\nexport async function classifyTurnThreadWriteFailure(\n db: Kysely<Database>,\n keys: TurnKeys,\n thread_id: string,\n): Promise<never> {\n const row = await db\n .selectFrom('turn')\n .select('state')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .executeTakeFirst();\n\n if (!row) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n if (row.state.status !== 'running') {\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(row.state, keys.turn_id));\n }\n throw new SessionStoreInvariantError(`thread ${thread_id} not found in turn ${keys.turn_id}`);\n}\n\nexport async function assertTurnRunning(db: DbOrTrx, keys: TurnKeys): Promise<void> {\n // SELECT ... FOR SHARE serializes against freezeAndGetTurn's state UPDATE.\n const row = await db\n .selectFrom('turn')\n .select('state')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .forShare()\n .executeTakeFirst();\n\n if (!row) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n if (row.state.status !== 'running') {\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(row.state, keys.turn_id));\n }\n}\n\ninterface CapabilityAggRow {\n thread_id: string;\n capability_state: Record<string, JsonValue> | null;\n}\n\nasync function assembleTurnRecord(\n db: DbOrTrx,\n args: { session_id: string; turn_id: string },\n): Promise<TurnRecord<TurnCustom> | undefined> {\n const turn = await db\n .selectFrom('turn')\n .selectAll()\n .where('session_id', '=', args.session_id)\n .where('turn_id', '=', args.turn_id)\n .executeTakeFirst();\n\n if (!turn) {\n return undefined;\n }\n\n // LEFT JOIN LATERAL unnest so empty-context threads still appear; LEFT JOIN log\n // because a null lateral append_id (empty array) must not drop the turn_thread row.\n const contextRows = await db\n .selectFrom('turn_thread as tt')\n .leftJoin(lateralUnnestBigintArrayWithOrdinality(sql<number[]>`tt.context_ids`, 'c'), join => join.onTrue())\n .leftJoin('thread_context_log as l', join =>\n join\n .on('l.session_id', '=', args.session_id)\n .onRef('l.thread_id', '=', 'tt.thread_id')\n .onRef('l.append_id', '=', 'c.append_id'),\n )\n .select(['tt.thread_id', 'tt.checkpoint', 'tt.agent_info', 'tt.current_context_usage', 'l.body', 'c.pos'])\n .where('tt.session_id', '=', args.session_id)\n .where('tt.turn_id', '=', args.turn_id)\n .orderBy('tt.thread_id')\n .orderBy('c.pos')\n .execute();\n\n const capabilityRows: CapabilityAggRow[] = await db\n .selectFrom('thread_capability_state')\n .select(['thread_id', sql<Record<string, JsonValue> | null>`jsonb_object_agg(key, state)`.as('capability_state')])\n .where('session_id', '=', args.session_id)\n .where('turn_id', '=', args.turn_id)\n .groupBy('thread_id')\n .execute();\n\n const capabilityByThread = new Map<string, Record<string, JsonValue>>();\n for (const row of capabilityRows) {\n if (row.capability_state !== null) {\n capabilityByThread.set(row.thread_id, row.capability_state);\n }\n }\n\n const threads: Record<string, AgentThreadSnapshot> = {};\n const orderedBodies = new Map<string, ContextMessage[]>();\n const threadMeta = new Map<\n string,\n {\n checkpoint: TurnThreadCheckpoint;\n agent_info: AgentInfo | null;\n current_context_usage: CurrentContextUsage;\n }\n >();\n\n for (const row of contextRows) {\n if (!threadMeta.has(row.thread_id)) {\n threadMeta.set(row.thread_id, {\n checkpoint: row.checkpoint,\n agent_info: row.agent_info,\n current_context_usage: row.current_context_usage,\n });\n orderedBodies.set(row.thread_id, []);\n }\n if (row.body !== null) {\n const bodies = orderedBodies.get(row.thread_id);\n if (bodies !== undefined) {\n bodies.push(row.body);\n }\n }\n }\n\n for (const [threadId, meta] of threadMeta) {\n const context = orderedBodies.get(threadId) ?? [];\n const capability_state = capabilityByThread.get(threadId) ?? null;\n\n const snap: AgentThreadSnapshot = {\n thread_id: threadId,\n context,\n current_context_usage: meta.current_context_usage,\n parent: meta.checkpoint.parent,\n agent_info: meta.agent_info,\n completion: meta.checkpoint.completion,\n capability_state,\n };\n threads[threadId] = snap;\n }\n\n const checkpoint: TurnCheckpoint = turn.checkpoint;\n const snapshot: TurnSnapshot = {\n threads,\n mcp_servers: checkpoint.mcp_servers,\n sandbox_info: checkpoint.sandbox_info,\n };\n\n return {\n turn_id: turn.turn_id,\n session_id: turn.session_id,\n first_turn_id: turn.first_turn_id,\n ancestor_ids: turn.ancestor_ids,\n previous_turn_id: turn.previous_turn_id,\n state: turn.state,\n input: turn.input,\n snapshot,\n created_at: turn.created_at,\n updated_at: turn.updated_at,\n custom: parseTurnCustom(turn.custom),\n };\n}\n\ninterface TurnInsertValues {\n session_id: string;\n turn_id: string;\n first_turn_id: string;\n previous_turn_id: string | null;\n ancestor_ids: string[];\n input: RawBuilder<CreateTurnInput['turn']['input']>;\n state: CreateTurnInput['turn']['state'];\n checkpoint: TurnCheckpoint;\n custom: RawBuilder<Record<string, unknown>> | null;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface LogInsertRow {\n session_id: string;\n thread_id: string;\n turn_id: string;\n body: RawBuilder<ContextMessage>;\n created_at: Date;\n}\n\ninterface TurnThreadInsertRow {\n session_id: string;\n turn_id: string;\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: RawBuilder<AgentInfo> | null;\n current_context_usage: CurrentContextUsage;\n context_ids: number[];\n updated_at: Date;\n}\n\ninterface CapabilityStateInsertRow {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: RawBuilder<JsonValue>;\n updated_at: Date;\n}\n\n/**\n * createTurn — READ COMMITTED tx. Fork and linear are THE SAME pointer-copy path:\n * child turn_thread rows copy the parent's arrays and concat new append ids.\n * Tip bump uses SELECT ... FOR UPDATE then UPDATE (safe on PG17; the one-statement\n * CTE tip-bump is PROVEN UNSAFE under EvalPlanQual — a blocked second writer gets\n * the stale pre-commit tip because the CTE keeps the statement snapshot).\n */\nexport async function createTurn(db: Kysely<Database>, input: CreateTurnInput): Promise<void> {\n try {\n await db.transaction().execute(async trx => {\n // step1: lock session tip, bump. Two statements on purpose — see PROVEN-UNSAFE-CTE note above.\n const locked = await trx\n .selectFrom('session')\n .select(['last_turn_id'])\n .where('session_id', '=', input.session_id)\n .forUpdate()\n .executeTakeFirst();\n\n if (!locked) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n await trx\n .updateTable('session')\n .set({\n last_turn_id: input.turn.turn_id,\n updated_at: sql`now()`,\n last_activity_timestamp_ms: input.last_activity_timestamp_ms,\n ...(input.update_session_title_if_not_exist !== null\n ? {\n title: sql`COALESCE(title, ${input.update_session_title_if_not_exist})`,\n }\n : {}),\n })\n .where('session_id', '=', input.session_id)\n .execute();\n\n const prevTurnId = input.turn.previous_turn_id;\n\n // step2: previous turn state + its turn_thread rows (pointer-copy source).\n let prevCheckpoint: TurnCheckpoint | null = null;\n const prevThreadRows: {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: AgentInfo | null;\n current_context_usage: CurrentContextUsage;\n context_ids: number[];\n }[] = [];\n\n if (prevTurnId != null) {\n // One round-trip: previous turn metadata + its turn_thread rows.\n // Unknown previous_turn_id is allowed (relaxed): treat as no inheritance.\n const prevRows = await trx\n .selectFrom('turn as t')\n .leftJoin('turn_thread as tt', join =>\n join.onRef('tt.session_id', '=', 't.session_id').onRef('tt.turn_id', '=', 't.turn_id'),\n )\n .select([\n 't.checkpoint as turn_checkpoint',\n 't.state as turn_state',\n 'tt.thread_id',\n 'tt.checkpoint as thread_checkpoint',\n 'tt.agent_info',\n 'tt.current_context_usage',\n 'tt.context_ids',\n ])\n .where('t.session_id', '=', input.session_id)\n .where('t.turn_id', '=', prevTurnId)\n .execute();\n\n const first = prevRows[0];\n if (first !== undefined) {\n if (first.turn_state.status === 'running') {\n throw new PreviousTurnRunningError(prevTurnId);\n }\n prevCheckpoint = first.turn_checkpoint;\n\n for (const row of prevRows) {\n if (row.thread_id === null) {\n continue;\n }\n if (row.thread_checkpoint === null || row.current_context_usage === null || row.context_ids === null) {\n throw new SessionStoreInvariantError(`previous turn_thread row for ${row.thread_id} is incomplete`);\n }\n prevThreadRows.push({\n thread_id: row.thread_id,\n checkpoint: row.thread_checkpoint,\n agent_info: row.agent_info,\n current_context_usage: row.current_context_usage,\n context_ids: row.context_ids,\n });\n }\n }\n }\n\n assertCreateTurnThreadDelta({\n previousThreadIds: new Set(prevThreadRows.map(r => r.thread_id)),\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n const checkpoint: TurnCheckpoint = {\n mcp_servers: input.mcp_servers ?? prevCheckpoint?.mcp_servers ?? null,\n sandbox_info: input.sandbox_info ?? prevCheckpoint?.sandbox_info ?? null,\n };\n\n const now = new Date();\n\n const turnCustom = input.turn.custom ?? null;\n\n // step3: turn row\n const turnValues: TurnInsertValues = {\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n first_turn_id: input.turn.first_turn_id,\n previous_turn_id: input.turn.previous_turn_id ?? null,\n ancestor_ids: input.turn.ancestor_ids,\n input: json(input.turn.input),\n state: input.turn.state,\n checkpoint,\n custom: turnCustom !== null ? json(turnCustom) : null,\n created_at: now,\n updated_at: now,\n };\n await trx.insertInto('turn').values(turnValues).execute();\n\n // step4: new_context_appends bodies; RETURNING feeds the arrays app-side.\n const logRows: LogInsertRow[] = [];\n for (const append of input.new_context_appends) {\n for (const body of append.context) {\n logRows.push({\n session_id: input.session_id,\n thread_id: append.thread_id,\n turn_id: input.turn.turn_id,\n body: json(body),\n created_at: now,\n });\n }\n }\n\n const newIdsByThread = new Map<string, number[]>();\n if (logRows.length > 0) {\n const inserted = await trx\n .insertInto('thread_context_log')\n .values(logRows)\n .returning(['thread_id', 'append_id'])\n .execute();\n for (const row of inserted) {\n const list = newIdsByThread.get(row.thread_id);\n if (list === undefined) {\n newIdsByThread.set(row.thread_id, [row.append_id]);\n } else {\n list.push(row.append_id);\n }\n }\n }\n\n const appendUsageByThread = new Map<string, CurrentContextUsage>();\n for (const append of input.new_context_appends) {\n if (append.current_context_usage !== null) {\n appendUsageByThread.set(append.thread_id, append.current_context_usage);\n }\n }\n\n // step5: child turn_thread rows — carried = parent || new ids; new = fresh row.\n const turnThreadRows: TurnThreadInsertRow[] = [];\n\n for (const parent of prevThreadRows) {\n const newIds = newIdsByThread.get(parent.thread_id) ?? [];\n const usage = appendUsageByThread.get(parent.thread_id) ?? parent.current_context_usage;\n turnThreadRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: parent.thread_id,\n checkpoint: parent.checkpoint,\n agent_info: parent.agent_info !== null ? json(parent.agent_info) : null,\n current_context_usage: usage,\n context_ids: parent.context_ids.concat(newIds),\n updated_at: now,\n });\n }\n\n for (const nt of input.new_threads) {\n const newIds = newIdsByThread.get(nt.thread_id) ?? [];\n const usage = appendUsageByThread.get(nt.thread_id) ?? getEmptyCurrentContextUsage();\n const threadCheckpoint: TurnThreadCheckpoint = {\n parent: nt.parent,\n completion: null,\n };\n turnThreadRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: nt.thread_id,\n checkpoint: threadCheckpoint,\n agent_info: nt.agent_info !== null ? json(nt.agent_info) : null,\n current_context_usage: usage,\n context_ids: newIds,\n updated_at: now,\n });\n }\n\n if (turnThreadRows.length > 0) {\n await trx.insertInto('turn_thread').values(turnThreadRows).execute();\n }\n\n // Complete per-turn capability maps (thread coverage asserted above).\n const capabilityStateRows: CapabilityStateInsertRow[] = [];\n for (const capability of input.capability_states) {\n if (capability.capability_state === null) {\n continue;\n }\n for (const [key, state] of Object.entries(capability.capability_state)) {\n capabilityStateRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: capability.thread_id,\n key,\n state: json(state),\n updated_at: now,\n });\n }\n }\n\n if (capabilityStateRows.length > 0) {\n await trx.insertInto('thread_capability_state').values(capabilityStateRows).execute();\n }\n });\n } catch (err) {\n if (err instanceof SessionStoreNotFoundError || err instanceof SessionStoreConflictError) {\n throw err;\n }\n if (isUniqueViolation(err)) {\n throw new TurnAlreadyExistsError(input.turn.turn_id, { cause: err });\n }\n throw err;\n }\n}\n\n/**\n * freezeAndGetTurn — cancel if still running (fencing future writes), then return the record.\n * Terminal turns are returned unchanged (freeze is a plain read).\n */\nexport async function freezeAndGetTurn(db: Kysely<Database>, input: FreezeAndGetTurnInput): Promise<TurnRecord> {\n return await db.transaction().execute(async trx => {\n const cancelledState: TerminalTurnState = {\n status: 'cancelled',\n reason: input.reason,\n completed_at: new Date().toISOString(),\n };\n\n // UPDATE waits for in-flight turn-scoped writes (FOR SHARE on this row) to\n // commit; assembly below then includes every committed straggler.\n const updateResult = await trx\n .updateTable('turn')\n .set({\n state: cancelledState,\n updated_at: sql`now()`,\n })\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(updateResult.numUpdatedRows) > 0) {\n await trx\n .insertInto('session_event')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: input.turn_done_event.id,\n event: json(input.turn_done_event),\n created_at: new Date(input.turn_done_event.created_at),\n })\n .execute();\n }\n\n const record = await assembleTurnRecord(trx, input);\n if (!record) {\n throw new TurnNotFoundError(input.turn_id);\n }\n return record;\n });\n}\n\n/**\n * getTurn — read-only REPEATABLE READ tx.\n * Concurrent appends after the first SELECT are invisible to later SELECTs in the same tx.\n */\nexport async function getTurn(db: Kysely<Database>, input: GetTurnInput): Promise<TurnRecord<TurnCustom> | undefined> {\n return await db\n .transaction()\n .setIsolationLevel('repeatable read')\n .execute(async trx => {\n return assembleTurnRecord(trx, input);\n });\n}\n\n/**\n * listTurns — ORDER BY created_at, turn_id; LIMIT limit+1 OFFSET offset; numeric-offset tokens.\n * Returns turn rows only (no snapshot assembly); use getTurn for full TurnRecord.\n */\nexport async function listTurns(db: Kysely<Database>, input: ListTurnsInput): Promise<ListTurnsResult> {\n const rows = await db\n .selectFrom('turn')\n .selectAll()\n .where('session_id', '=', input.session_id)\n .orderBy('created_at', 'asc')\n .orderBy('turn_id', 'asc')\n .limit(input.limit + 1)\n .offset(input.offset)\n .execute();\n\n const hasMore = rows.length > input.limit;\n const page = hasMore ? rows.slice(0, input.limit) : rows;\n\n const turns: TurnRecordWithoutSnapshot<TurnCustom>[] = page.map(row => ({\n turn_id: row.turn_id,\n session_id: row.session_id,\n first_turn_id: row.first_turn_id,\n ancestor_ids: row.ancestor_ids,\n previous_turn_id: row.previous_turn_id,\n state: row.state,\n input: row.input,\n created_at: row.created_at,\n updated_at: row.updated_at,\n custom: parseTurnCustom(row.custom),\n }));\n\n return {\n turns,\n next_offset: hasMore ? input.offset + input.limit : null,\n };\n}\n\n/**\n * updateTurnState — conditional on state->>'status'='running'.\n * 0 rows → SELECT by PK → missing NotFound, present Conflict (first terminal write wins).\n */\nexport async function updateTurnState(db: Kysely<Database>, input: UpdateTurnStateInput): Promise<void> {\n await db.transaction().execute(async trx => {\n const result = await trx\n .updateTable('turn')\n .set({\n state: input.state,\n updated_at: sql`now()`,\n })\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n const numUpdated = Number(result.numUpdatedRows);\n if (numUpdated === 0) {\n const existing = await trx\n .selectFrom('turn')\n .select('state')\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .executeTakeFirst();\n\n if (!existing) {\n throw new TurnNotFoundError(input.turn_id);\n }\n throw new TurnNotRunningError(input.turn_id, terminalTurnState(existing.state, input.turn_id));\n }\n\n await trx\n .insertInto('session_event')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: input.turn_done_event.id,\n event: json(input.turn_done_event),\n created_at: new Date(input.turn_done_event.created_at),\n })\n .execute();\n });\n}\n","import type { PatchThreadCapabilityStateInput } from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport { sql, type Kysely } from 'kysely';\nimport { json } from '../../sqlExpressions';\nimport type { Database } from '../../types';\nimport { values } from '../sqlExpressions';\nimport { classifyTurnFenceWriteFailure, turnRunningFence } from './turns';\n\n/**\n * patchThreadCapabilityState — single-statement fenced upsert on the PER-TURN PK;\n * does NOT bump turn.updated_at.\n */\nexport async function patchThreadCapabilityState(\n db: Kysely<Database>,\n input: PatchThreadCapabilityStateInput,\n): Promise<void> {\n const keys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const rows = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .insertInto('thread_capability_state')\n .columns(['session_id', 'turn_id', 'thread_id', 'key', 'state', 'updated_at'])\n .expression(eb =>\n eb\n .selectFrom(values([{ one: 1 }], 'src'))\n .select([\n sql<string>`${input.session_id}`.as('session_id'),\n sql<string>`${input.turn_id}`.as('turn_id'),\n sql<string>`${input.thread_id}`.as('thread_id'),\n sql<string>`${input.key}`.as('key'),\n json(input.state).as('state'),\n sql<Date>`now()`.as('updated_at'),\n ])\n .where(wb => wb.exists(wb.selectFrom('turn_fence').select(sql`1`.as('one')))),\n )\n .onConflict(oc =>\n oc.columns(['session_id', 'turn_id', 'thread_id', 'key']).doUpdateSet({\n state: sql`excluded.state`,\n updated_at: sql`now()`,\n }),\n )\n .returning('thread_id')\n .execute();\n\n if (rows.length === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n","import type { PersistedTurnEvent, SessionEventItem } from '@truefoundry/trueforge-core/agent-session/schemas/events';\nimport type { TokenPagination } from '@truefoundry/trueforge-core/agent-session/schemas/pagination';\nimport type {\n AppendToEventsInput,\n ListSessionEventsInput,\n ListTurnEventsInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeOffsetPageToken,\n paginateOffsetRows,\n} from '@truefoundry/trueforge-core/agent-session/store/OffsetPageToken';\nimport {\n decodeSessionEventPageToken,\n paginateSessionEventRows,\n type SessionEventPageCursor,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionEventPageToken';\nimport {\n SessionNotFoundError,\n TurnNotFoundError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport type { Kysely } from 'kysely';\nimport { sql } from 'kysely';\nimport { json } from '../../sqlExpressions';\nimport type { Database } from '../../types';\nimport { unnestWithOrdinality, values } from '../sqlExpressions';\nimport { classifyTurnFenceWriteFailure, turnRunningFence } from './turns';\n\nexport async function appendToEvents(db: Kysely<Database>, input: AppendToEventsInput): Promise<void> {\n if (input.events.length === 0) {\n return;\n }\n\n const keys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const eventRows = input.events.map(event => ({\n event_id: event.id,\n event: json(event),\n // VALUES parameters default to text; cast the event's required timestamp.\n created_at: sql<Date>`${event.created_at}::timestamptz`,\n }));\n\n const inserted = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .insertInto('session_event')\n .columns(['session_id', 'turn_id', 'event_id', 'event', 'created_at'])\n .expression(eb =>\n eb\n .selectFrom(values(eventRows, 'ev'))\n .select([\n sql<string>`${input.session_id}`.as('session_id'),\n sql<string>`${input.turn_id}`.as('turn_id'),\n 'ev.event_id',\n 'ev.event',\n 'ev.created_at',\n ])\n .where(wb => wb.exists(wb.selectFrom('turn_fence').select(sql`1`.as('one')))),\n )\n .returning('event_id')\n .execute();\n\n if (inserted.length === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\n/**\n * listTurnEvents — one statement: drive from turn, left-join a page of events.\n * Missing turn → 0 rows → TurnNotFoundError. Empty log → one null-event sentinel.\n */\nexport async function listTurnEvents(\n db: Kysely<Database>,\n input: ListTurnEventsInput,\n): Promise<{ data: PersistedTurnEvent[]; pagination: TokenPagination }> {\n const offset = decodeOffsetPageToken(input.page_token);\n const limit = input.limit;\n const eventOrder = input.order === 'desc' ? 'desc' : 'asc';\n\n const rows = await db\n .selectFrom('turn as t')\n .leftJoin(\n eb =>\n eb\n .selectFrom('session_event')\n .select(['session_id', 'turn_id', 'event_id', 'event'])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .orderBy('event_id', eventOrder)\n .limit(limit + 1)\n .offset(offset)\n .as('e'),\n join => join.onRef('e.session_id', '=', 't.session_id').onRef('e.turn_id', '=', 't.turn_id'),\n )\n .select(['t.turn_id', 'e.event'])\n .where('t.session_id', '=', input.session_id)\n .where('t.turn_id', '=', input.turn_id)\n .orderBy('e.event_id', eventOrder)\n .execute();\n\n if (rows.length === 0) {\n throw new TurnNotFoundError(input.turn_id);\n }\n\n const events: PersistedTurnEvent[] = [];\n for (const row of rows) {\n if (row.event !== null) {\n events.push(row.event);\n }\n }\n\n return paginateOffsetRows(events, limit, offset);\n}\n\nexport async function listSessionEvents(\n db: Kysely<Database>,\n input: ListSessionEventsInput,\n): Promise<{ data: SessionEventItem[]; pagination: TokenPagination }> {\n const limit = input.limit;\n\n const session = await db\n .selectFrom('session')\n .select('last_turn_id')\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n if (!session) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n const decodedCursor = input.page_token === undefined ? undefined : decodeSessionEventPageToken(input.page_token);\n const lastTurnId = decodedCursor?.last_turn_id ?? input.last_turn_id ?? session.last_turn_id;\n if (lastTurnId === null) {\n return { data: [], pagination: { limit } };\n }\n const cursor: SessionEventPageCursor = {\n last_turn_id: lastTurnId,\n offset: decodedCursor?.offset ?? 0,\n };\n\n const anchor = await db\n .selectFrom('turn')\n .select(['turn_id', 'ancestor_ids'])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', cursor.last_turn_id)\n .executeTakeFirst();\n if (!anchor) {\n throw new TurnNotFoundError(cursor.last_turn_id);\n }\n\n const chainIds = await resolveAncestorChain(db, input.session_id, anchor);\n const rows = await db\n .selectFrom(unnestWithOrdinality(chainIds, 'c'))\n .innerJoin('session_event as e', join =>\n join.on('e.session_id', '=', input.session_id).onRef('e.turn_id', '=', 'c.turn_id'),\n )\n .select(['e.turn_id as turn_id', 'e.event as event'])\n .orderBy('c.pos', 'desc')\n .orderBy('e.event_id', 'desc')\n .limit(limit + 1)\n .offset(cursor.offset)\n .execute();\n\n return paginateSessionEventRows(rows, limit, cursor);\n}\n\n/** Anchor turn fields needed for chain resolution. */\nexport interface AnchorTurn {\n turn_id: string;\n ancestor_ids: string[];\n}\n\n/**\n * Full chain (oldest first, anchor last). `ancestor_ids` may be only the\n * previous N ancestors, so spill through the oldest ancestor's own window\n * until a root or gap. A missing turn or repeated id ends the walk.\n */\nexport async function resolveAncestorChain(\n db: Kysely<Database>,\n sessionId: string,\n anchor: AnchorTurn,\n): Promise<string[]> {\n const chain = [...anchor.ancestor_ids, anchor.turn_id];\n const seen = new Set(chain);\n let oldestId = chain[0];\n while (oldestId && oldestId !== anchor.turn_id) {\n const oldest = await db\n .selectFrom('turn')\n .select(['ancestor_ids'])\n .where('session_id', '=', sessionId)\n .where('turn_id', '=', oldestId)\n .executeTakeFirst();\n if (!oldest) {\n break;\n }\n const older = oldest.ancestor_ids.filter(id => !seen.has(id));\n if (older.length === 0) {\n break;\n }\n chain.unshift(...older);\n for (const id of older) {\n seen.add(id);\n }\n oldestId = older[0];\n }\n return chain;\n}\n","import type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport type { SessionRecord } from '@truefoundry/trueforge-core/agent-session/models/SessionRecord';\nimport type {\n CreateSessionInput,\n DeleteSessionInput,\n GetSessionInput,\n ListSessionsInput,\n UpdateSessionInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeSessionListPageToken,\n paginateSessionListRows,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionListPageToken';\nimport {\n SessionAlreadyExistsError,\n SessionNotFoundError,\n SessionStoreInvariantError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport { sql, type Kysely } from 'kysely';\nimport { sessionAgentFromColumns, sessionAgentToColumns } from '../../../sessionAgentColumns';\nimport { json } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nfunction isPgUniqueViolation(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) {\n return false;\n }\n if (!('code' in error)) {\n return false;\n }\n return error.code === '23505';\n}\n\ntype SessionCustom = Record<string, never>;\ntype ProtoSessionRecord = SessionRecord<SessionCustom>;\n\nfunction isEmptyCustomRecord(value: Record<string, unknown>): value is SessionCustom {\n return Object.keys(value).length === 0;\n}\n\nfunction parseSessionCustom(value: Record<string, unknown> | null): SessionCustom | null {\n if (value === null) {\n return null;\n }\n if (!isEmptyCustomRecord(value)) {\n throw new SessionStoreInvariantError('non-empty session custom is not supported');\n }\n return value;\n}\n\nfunction mapRowToSessionRecord(row: {\n tenant_id: string;\n session_id: string;\n created_by: string;\n agent_id: string | null;\n agent_name: string | null;\n agent_spec: AgentSpec | null;\n title: string | null;\n last_turn_id: string | null;\n custom: Record<string, unknown> | null;\n created_at: Date;\n updated_at: Date;\n last_activity_timestamp_ms: number;\n}): ProtoSessionRecord {\n return {\n tenant_id: row.tenant_id,\n session_id: row.session_id,\n created_by: row.created_by,\n agent: sessionAgentFromColumns({\n session_id: row.session_id,\n agent_id: row.agent_id,\n agent_name: row.agent_name,\n agent_spec: row.agent_spec,\n }),\n title: row.title,\n last_turn_id: row.last_turn_id,\n custom: parseSessionCustom(row.custom),\n created_at: row.created_at,\n updated_at: row.updated_at,\n last_activity_timestamp_ms: row.last_activity_timestamp_ms,\n };\n}\n\nexport async function createSession(db: Kysely<Database>, input: CreateSessionInput<SessionCustom>): Promise<void> {\n const columns = sessionAgentToColumns(input.agent);\n const nowMs = Date.now();\n\n try {\n await db\n .insertInto('session')\n .values({\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n created_by: input.created_by,\n agent_id: columns.agent_id,\n agent_name: columns.agent_name,\n agent_spec: columns.agent_spec !== null ? json(columns.agent_spec) : null,\n title: null,\n custom: input.custom !== null ? json(input.custom) : null,\n created_at: new Date(nowMs),\n updated_at: new Date(nowMs),\n last_activity_timestamp_ms: nowMs,\n })\n .execute();\n } catch (error) {\n if (isPgUniqueViolation(error)) {\n throw new SessionAlreadyExistsError(input.session_id, { cause: error });\n }\n throw error;\n }\n}\n\nexport async function deleteSession(db: Kysely<Database>, input: DeleteSessionInput): Promise<void> {\n await db\n .deleteFrom('session')\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .execute();\n}\n\nexport async function getSession(\n db: Kysely<Database>,\n input: GetSessionInput,\n): Promise<ProtoSessionRecord | undefined> {\n const row = await db\n .selectFrom('session')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n\n if (row === undefined) {\n return undefined;\n }\n\n return mapRowToSessionRecord(row);\n}\n\nexport async function updateSession(db: Kysely<Database>, input: UpdateSessionInput<SessionCustom>): Promise<void> {\n const agent = input.agent;\n const title = input.title;\n\n if (agent !== undefined) {\n const existing = await getSession(db, { tenant_id: input.tenant_id, session_id: input.session_id });\n if (existing === undefined) {\n throw new SessionNotFoundError(input.session_id);\n }\n if (existing.agent.type === 'reference') {\n throw new SessionStoreInvariantError(`Session ${input.session_id} is named; agent cannot be updated`);\n }\n }\n\n const result = await db\n .updateTable('session')\n .set({\n updated_at: sql<Date>`now()`,\n last_activity_timestamp_ms: Date.now(),\n })\n .$if(agent !== undefined, qb => {\n if (agent === undefined) {\n return qb;\n }\n return qb.set({ agent_spec: json(agent.spec) });\n })\n .$if(title !== undefined, qb => {\n if (title === undefined) {\n return qb;\n }\n return qb.set({ title });\n })\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n\n const numUpdatedRows = Number(result.numUpdatedRows);\n if (numUpdatedRows === 0) {\n throw new SessionNotFoundError(input.session_id);\n }\n}\n\nexport async function listSessions(\n db: Kysely<Database>,\n input: ListSessionsInput,\n): Promise<{\n data: ProtoSessionRecord[];\n pagination: { next_page_token?: string | undefined; previous_page_token?: string | undefined };\n}> {\n const limit = input.limit;\n const order = input.order ?? 'desc';\n const cursor = decodeSessionListPageToken(input.page_token);\n\n let query = db\n .selectFrom('session')\n .selectAll()\n .select(\n sql<string>`to_char(updated_at AT TIME ZONE 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS.US\"Z\"')`.as('updated_at_cursor'),\n )\n .where('tenant_id', '=', input.tenant_id);\n\n if (input.agent_id !== undefined) {\n query = query.where('agent_id', '=', input.agent_id);\n }\n if (input.created_by !== undefined) {\n query = query.where('created_by', '=', input.created_by);\n }\n if (input.start_timestamp !== undefined) {\n query = query.where('created_at', '>=', input.start_timestamp);\n }\n if (input.end_timestamp !== undefined) {\n query = query.where('created_at', '<=', input.end_timestamp);\n }\n\n if (cursor) {\n const sessionId = cursor.session_id;\n // Bind the cursor string and cast in SQL so microsecond precision is preserved\n // (JS Date would truncate to milliseconds).\n const cursorUpdatedAt = sql<Date>`${cursor.updated_at}::timestamptz`;\n if (order === 'asc') {\n query = query.where(eb =>\n eb.or([\n eb('updated_at', '>', cursorUpdatedAt),\n eb.and([eb('updated_at', '=', cursorUpdatedAt), eb('session_id', '>', sessionId)]),\n ]),\n );\n } else {\n query = query.where(eb =>\n eb.or([\n eb('updated_at', '<', cursorUpdatedAt),\n eb.and([eb('updated_at', '=', cursorUpdatedAt), eb('session_id', '<', sessionId)]),\n ]),\n );\n }\n }\n\n if (order === 'asc') {\n query = query.orderBy('updated_at', 'asc').orderBy('session_id', 'asc');\n } else {\n query = query.orderBy('updated_at', 'desc').orderBy('session_id', 'desc');\n }\n\n const rows = await query.limit(limit + 1).execute();\n const { data: pageRows, pagination } = paginateSessionListRows(rows, limit, row => row.updated_at_cursor);\n\n return { data: pageRows.map(mapRowToSessionRecord), pagination };\n}\n","import type {\n AddThreadsInput,\n AppendToThreadContextInput,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n RemoveThreadsInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport type { JsonValue } from '@truefoundry/trueforge-core/core/capabilities/AgentCapability';\nimport type { AgentInfo } from '@truefoundry/trueforge-core/core/events/schema';\nimport type {\n ContextMessage,\n SubAgentCompletionMarker,\n} from '@truefoundry/trueforge-core/core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport { sql, type Kysely, type RawBuilder, type Transaction } from 'kysely';\nimport { json, jsonbSet } from '../../sqlExpressions';\nimport type { Database, TurnThreadCheckpoint } from '../../types';\nimport { values } from '../sqlExpressions';\nimport {\n assertTurnRunning,\n classifyTurnFenceWriteFailure,\n classifyTurnThreadWriteFailure,\n turnRunningFence,\n type TurnKeys,\n} from './turns';\n\ntype DbOrTrx = Kysely<Database> | Transaction<Database>;\n\ninterface CapabilityStateInsertRow {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: RawBuilder<JsonValue>;\n updated_at: RawBuilder<Date>;\n}\n\n/**\n * addThreads — fenced tx, max 3 batched statements: log INSERT, turn_thread INSERT,\n * capability upsert. No turn.checkpoint touch (threads live in turn_thread).\n */\nexport async function addThreads(db: Kysely<Database>, input: AddThreadsInput): Promise<void> {\n await db.transaction().execute(async trx => {\n await assertTurnRunning(trx, {\n session_id: input.session_id,\n turn_id: input.turn_id,\n });\n\n const now = new Date();\n const logRows: {\n session_id: string;\n thread_id: string;\n turn_id: string;\n body: RawBuilder<ContextMessage>;\n created_at: Date;\n }[] = [];\n const capabilityStateRows: CapabilityStateInsertRow[] = [];\n const turnThreadPlans: {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: RawBuilder<AgentInfo> | null;\n current_context_usage: CurrentContextUsage;\n }[] = [];\n\n for (const thread of input.threads) {\n const threadCheckpoint: TurnThreadCheckpoint = {\n parent: thread.parent ?? null,\n completion: thread.completion ?? null,\n };\n turnThreadPlans.push({\n thread_id: thread.thread_id,\n checkpoint: threadCheckpoint,\n agent_info: thread.agent_info != null ? json(thread.agent_info) : null,\n current_context_usage: thread.current_context_usage,\n });\n\n for (const body of thread.context) {\n logRows.push({\n session_id: input.session_id,\n thread_id: thread.thread_id,\n turn_id: input.turn_id,\n body: json(body),\n created_at: now,\n });\n }\n\n const capabilityState = thread.capability_state;\n if (capabilityState != null) {\n for (const key of Object.keys(capabilityState)) {\n const state = capabilityState[key];\n if (state === undefined) {\n throw new Error(\n `capability_state['${key}'] for thread '${thread.thread_id}' is undefined — undefined is banned from capability state`,\n );\n }\n capabilityStateRows.push({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: thread.thread_id,\n key,\n state: json(state),\n updated_at: sql<Date>`now()`,\n });\n }\n }\n }\n\n const newIdsByThread = new Map<string, number[]>();\n if (logRows.length > 0) {\n const inserted = await trx\n .insertInto('thread_context_log')\n .values(logRows)\n .returning(['thread_id', 'append_id'])\n .execute();\n for (const row of inserted) {\n const list = newIdsByThread.get(row.thread_id);\n if (list === undefined) {\n newIdsByThread.set(row.thread_id, [row.append_id]);\n } else {\n list.push(row.append_id);\n }\n }\n }\n\n const turnThreadRows = turnThreadPlans.map(plan => ({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: plan.thread_id,\n checkpoint: plan.checkpoint,\n agent_info: plan.agent_info,\n current_context_usage: plan.current_context_usage,\n context_ids: newIdsByThread.get(plan.thread_id) ?? [],\n updated_at: now,\n }));\n\n if (turnThreadRows.length > 0) {\n await trx.insertInto('turn_thread').values(turnThreadRows).execute();\n }\n\n if (capabilityStateRows.length > 0) {\n await trx.insertInto('thread_capability_state').values(capabilityStateRows).execute();\n }\n });\n}\n\n/**\n * removeThreads — one statement: fence FOR SHARE + delete turn_thread + capability rows.\n * Older turns keep their maps; log rows stay. Empty thread_ids is a no-op.\n */\nexport async function removeThreads(db: Kysely<Database>, input: RemoveThreadsInput): Promise<void> {\n if (input.thread_ids.length === 0) {\n return;\n }\n\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n const onFence = sql<boolean>`EXISTS (SELECT 1 FROM turn_fence)`;\n\n const fence = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .with('del_cap', qb =>\n qb\n .deleteFrom('thread_capability_state')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .where(onFence),\n )\n .with('del_tt', qb =>\n qb\n .deleteFrom('turn_thread')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .where(onFence),\n )\n .selectFrom('turn_fence')\n .select('one')\n .executeTakeFirst();\n\n if (fence === undefined) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\nfunction completionPatchExpr(completion: SubAgentCompletionMarker | null): RawBuilder<TurnThreadCheckpoint> {\n if (completion === null) {\n return sql<TurnThreadCheckpoint>`checkpoint`;\n }\n return jsonbSet<TurnThreadCheckpoint>(sql`checkpoint`, sql`'{completion}'`, json(completion));\n}\n\nfunction usageSetExpr(usage: CurrentContextUsage | null): RawBuilder<CurrentContextUsage> {\n if (usage === null) {\n return sql`current_context_usage`;\n }\n // COALESCE matches the plan sketch: provided usage wins, else keep column.\n return sql`coalesce(${json(usage)}, current_context_usage)`;\n}\n\nasync function fencedTurnThreadContextUpdate(\n db: Kysely<Database>,\n args: {\n keys: TurnKeys;\n thread_id: string;\n context: ContextMessage[];\n replace_array: boolean;\n current_context_usage: CurrentContextUsage | null;\n completion: SubAgentCompletionMarker | null;\n /** When replace_array, usage is set unconditionally (overwrite contract). */\n usage_unconditional: CurrentContextUsage | null;\n },\n): Promise<void> {\n const { keys, thread_id, context, replace_array } = args;\n\n if (context.length === 0) {\n // No log INSERT — still fence + patch usage/completion / clear-or-keep array.\n const emptyResult = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .updateTable('turn_thread')\n .set({\n context_ids: replace_array ? sql<number[]>`'{}'::bigint[]` : sql<number[]>`context_ids`,\n current_context_usage: args.usage_unconditional ?? usageSetExpr(args.current_context_usage),\n checkpoint: completionPatchExpr(args.completion),\n updated_at: sql`now()`,\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .where(sql<boolean>`EXISTS (SELECT 1 FROM turn_fence)`)\n .executeTakeFirst();\n\n if (Number(emptyResult.numUpdatedRows) === 0) {\n await classifyTurnThreadWriteFailure(db, keys, thread_id);\n }\n return;\n }\n\n const bodyRows = context.map((body, index) => ({\n ord: sql<number>`${index + 1}::int`,\n body: json(body),\n }));\n\n const arrayExpr: RawBuilder<number[]> = replace_array\n ? sql<number[]>`coalesce((SELECT array_agg(append_id ORDER BY append_id) FROM new_rows), '{}'::bigint[])`\n : sql<\n number[]\n >`context_ids || coalesce((SELECT array_agg(append_id ORDER BY append_id) FROM new_rows), '{}'::bigint[])`;\n\n const result = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .with('new_rows', qb =>\n qb\n .insertInto('thread_context_log')\n .columns(['session_id', 'thread_id', 'turn_id', 'body', 'created_at'])\n .expression(eb =>\n eb\n .selectFrom(values(bodyRows, 'b'))\n .select([\n sql<string>`${keys.session_id}`.as('session_id'),\n sql<string>`${thread_id}`.as('thread_id'),\n sql<string>`${keys.turn_id}`.as('turn_id'),\n 'b.body',\n sql<Date>`now()`.as('created_at'),\n ])\n .where(wb => wb.exists(wb.selectFrom('turn_fence').select(sql`1`.as('one'))))\n .orderBy('b.ord'),\n )\n .returning('append_id'),\n )\n .updateTable('turn_thread')\n .set({\n context_ids: arrayExpr,\n current_context_usage: args.usage_unconditional ?? usageSetExpr(args.current_context_usage),\n checkpoint: completionPatchExpr(args.completion),\n updated_at: sql`now()`,\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .where(sql<boolean>`EXISTS (SELECT 1 FROM turn_fence)`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnThreadWriteFailure(db, keys, thread_id);\n }\n}\n\n/**\n * appendToThreadContext — ONE fenced statement: CTE inserts log rows, outer UPDATE\n * concats their ids, stamps usage (COALESCE), and patches completion on the same\n * turn_thread row version.\n */\nexport async function appendToThreadContext(db: Kysely<Database>, input: AppendToThreadContextInput): Promise<void> {\n await fencedTurnThreadContextUpdate(db, {\n keys: {\n session_id: input.session_id,\n turn_id: input.turn_id,\n },\n thread_id: input.thread_id,\n context: input.context,\n replace_array: false,\n current_context_usage: input.current_context_usage,\n completion: input.completion,\n usage_unconditional: null,\n });\n}\n\n/**\n * overwriteThreadContext — same one-statement shape; context_ids is REPLACED.\n * Old log rows stay — ancestor turns' arrays reference them. No lineage minting.\n */\nexport async function overwriteThreadContext(db: Kysely<Database>, input: OverwriteThreadContextInput): Promise<void> {\n await fencedTurnThreadContextUpdate(db, {\n keys: {\n session_id: input.session_id,\n turn_id: input.turn_id,\n },\n thread_id: input.event.thread_id,\n context: input.event.context,\n replace_array: true,\n current_context_usage: null,\n completion: null,\n usage_unconditional: input.event.current_context_usage,\n });\n}\n\n/**\n * patchMCPServers — one-shot conditional UPDATE on the fence row itself\n * (`state->>'status' = 'running'`). No separate FOR SHARE fence CTE.\n * Subscript LHS + expression RHS for shallow merge by server id.\n */\nexport async function patchMCPServers(db: Kysely<Database>, input: PatchMCPServersInput): Promise<void> {\n const serversById: Record<string, (typeof input.mcp_servers)[number]> = {};\n for (const server of input.mcp_servers) {\n serversById[server.id] = server;\n }\n\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const result = await db\n .updateTable('turn')\n .set(\n sql`checkpoint['mcp_servers']`,\n sql`(CASE WHEN jsonb_typeof(checkpoint->'mcp_servers') = 'object'\n THEN checkpoint->'mcp_servers'\n ELSE '{}'::jsonb END) || ${json(serversById)}`,\n )\n .set({ updated_at: sql`now()` })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\n/**\n * patchSandboxInfo — one-shot conditional UPDATE on the fence row itself\n * (`state->>'status' = 'running'`). LWW replace via subscript assignment.\n */\nexport async function patchSandboxInfo(db: Kysely<Database>, input: PatchSandboxInfoInput): Promise<void> {\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const result = await db\n .updateTable('turn')\n .set(sql`checkpoint['sandbox_info']`, json(input.sandbox_info))\n .set({ updated_at: sql`now()` })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\n/** Test helper: read a turn_thread row. */\nexport async function getTurnThread(\n db: DbOrTrx,\n session_id: string,\n turn_id: string,\n thread_id: string,\n): Promise<\n | {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: unknown;\n current_context_usage: CurrentContextUsage;\n context_ids: number[];\n }\n | undefined\n> {\n return await db\n .selectFrom('turn_thread')\n .select(['thread_id', 'checkpoint', 'agent_info', 'current_context_usage', 'context_ids'])\n .where('session_id', '=', session_id)\n .where('turn_id', '=', turn_id)\n .where('thread_id', '=', thread_id)\n .executeTakeFirst();\n}\n","import type { SessionRecord } from '@truefoundry/trueforge-core/agent-session/models/SessionRecord';\nimport type { TurnRecord } from '@truefoundry/trueforge-core/agent-session/models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '@truefoundry/trueforge-core/agent-session/schemas/events';\nimport type { TokenPagination } from '@truefoundry/trueforge-core/agent-session/schemas/pagination';\nimport type {\n AddThreadsInput,\n AppendToEventsInput,\n AppendToThreadContextInput,\n CreateSessionInput,\n CreateTurnInput,\n DeleteSessionInput,\n FreezeAndGetTurnInput,\n GetSessionInput,\n GetTurnInput,\n ISessionStore,\n ListSessionEventsInput,\n ListSessionsInput,\n ListTurnEventsInput,\n ListTurnsInput,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n PatchThreadCapabilityStateInput,\n RemoveThreadsInput,\n TurnRecordWithoutSnapshot,\n UpdateSessionInput,\n UpdateTurnStateInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeOffsetPageToken,\n encodeOffsetPageToken,\n} from '@truefoundry/trueforge-core/agent-session/store/OffsetPageToken';\nimport type { Kysely } from 'kysely';\nimport type { Database } from '../types';\nimport { patchThreadCapabilityState as patchThreadCapabilityStateQuery } from './queries/capabilities';\nimport {\n appendToEvents as appendToEventsQuery,\n listSessionEvents as listSessionEventsQuery,\n listTurnEvents as listTurnEventsQuery,\n} from './queries/events';\nimport {\n createSession as createSessionQuery,\n deleteSession as deleteSessionQuery,\n getSession as getSessionQuery,\n listSessions as listSessionsQuery,\n updateSession as updateSessionQuery,\n} from './queries/sessions';\nimport {\n addThreads as addThreadsQuery,\n appendToThreadContext as appendToThreadContextQuery,\n overwriteThreadContext as overwriteThreadContextQuery,\n patchMCPServers as patchMCPServersQuery,\n patchSandboxInfo as patchSandboxInfoQuery,\n removeThreads as removeThreadsQuery,\n} from './queries/threads';\nimport type { NewThreadRegistration } from './queries/turns';\nimport {\n createTurn as createTurnQuery,\n freezeAndGetTurn as freezeAndGetTurnQuery,\n getTurn as getTurnQuery,\n listTurns as listTurnsQuery,\n updateTurnState as updateTurnStateQuery,\n} from './queries/turns';\n\ntype SessionCustom = Record<string, never>;\ntype TurnCustom = Record<string, never>;\n\n/**\n * ## Design: append-only context log + per-turn id arrays\n *\n * Message bodies live in `thread_context_log`, append-only, written exactly\n * once; ids are store-assigned (`append_id` identity — the delta createTurn\n * interface tells the store what's new, so identity needs no hashing).\n * A turn's context per thread is `turn_thread.context_ids` — the explicit\n * ordered array of log ids. Turns share no mutable structure: linear\n * continuation and fork are the same pointer-copy (`parent_array || new_ids`),\n * overwrite replaces the array, and a still-running ancestor's late appends\n * touch only its OWN rows — structural leaks are impossible by construction.\n *\n * Hard invariants (violations proven by failing tests during prototyping —\n * see the freeze/fence tests):\n * 1. A turn cannot be used as `previous_turn_id` while it is still `running` —\n * `createTurn` rejects that with PreviousTurnRunningError; callers must\n * `freezeAndGetTurn` first (barge-in IS cancellation of that predecessor).\n * Tip-equality is NOT required: new roots and concurrent forks from a\n * finished tip can leave more than one turn `running` at once.\n * 2. Every turn-scoped write is fenced on `state->>'status' = 'running'`.\n * 3. Terminal turns are IMMUTABLE — a terminal read is a final read.\n */\nexport class PostgresSessionStore implements ISessionStore<SessionCustom, TurnCustom> {\n constructor(private readonly db: Kysely<Database>) {}\n\n createSession(input: CreateSessionInput<SessionCustom>): Promise<void> {\n return createSessionQuery(this.db, input);\n }\n\n deleteSession(input: DeleteSessionInput): Promise<void> {\n return deleteSessionQuery(this.db, input);\n }\n\n getSession(input: GetSessionInput): Promise<SessionRecord<SessionCustom> | undefined> {\n return getSessionQuery(this.db, input);\n }\n\n updateSession(input: UpdateSessionInput<SessionCustom>): Promise<void> {\n return updateSessionQuery(this.db, input);\n }\n\n async listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<SessionCustom>[]; pagination: TokenPagination }> {\n const result = await listSessionsQuery(this.db, input);\n return {\n data: result.data,\n pagination: {\n limit: input.limit,\n ...result.pagination,\n },\n };\n }\n\n async createTurn(input: CreateTurnInput<TurnCustom>): Promise<void> {\n await createTurnQuery(this.db, {\n session_id: input.turn.session_id,\n turn: {\n turn_id: input.turn.turn_id,\n first_turn_id: input.turn.first_turn_id,\n previous_turn_id: input.turn.previous_turn_id,\n ancestor_ids: input.turn.ancestor_ids,\n input: input.turn.input,\n state: input.turn.state,\n custom: input.turn.custom,\n },\n new_threads: input.new_threads.map((thread): NewThreadRegistration => ({\n thread_id: thread.thread_id,\n parent: thread.parent,\n agent_info: thread.agent_info,\n })),\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n last_activity_timestamp_ms: Date.now(),\n update_session_title_if_not_exist: input.update_session_title_if_not_exist,\n mcp_servers: null,\n sandbox_info: null,\n });\n }\n\n freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TurnCustom>> {\n return freezeAndGetTurnQuery(this.db, input);\n }\n\n getTurn(input: GetTurnInput): Promise<TurnRecord<TurnCustom> | undefined> {\n return getTurnQuery(this.db, input);\n }\n\n async listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TurnCustom>[]; pagination: TokenPagination }> {\n const offset = decodeOffsetPageToken(input.page_token);\n const result = await listTurnsQuery(this.db, {\n session_id: input.session_id,\n limit: input.limit,\n offset,\n });\n const pagination: TokenPagination = { limit: input.limit };\n if (result.next_offset !== null) {\n pagination.next_page_token = encodeOffsetPageToken(result.next_offset);\n }\n if (offset > 0) {\n pagination.previous_page_token = encodeOffsetPageToken(Math.max(0, offset - input.limit));\n }\n return { data: result.turns, pagination };\n }\n\n updateTurnState(input: UpdateTurnStateInput): Promise<void> {\n return updateTurnStateQuery(this.db, input);\n }\n\n appendToEvents(input: AppendToEventsInput): Promise<void> {\n return appendToEventsQuery(this.db, input);\n }\n\n addThreads(input: AddThreadsInput): Promise<void> {\n return addThreadsQuery(this.db, input);\n }\n\n removeThreads(input: RemoveThreadsInput): Promise<void> {\n return removeThreadsQuery(this.db, input);\n }\n\n appendToThreadContext(input: AppendToThreadContextInput): Promise<void> {\n return appendToThreadContextQuery(this.db, input);\n }\n\n overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void> {\n return overwriteThreadContextQuery(this.db, input);\n }\n\n patchMCPServers(input: PatchMCPServersInput): Promise<void> {\n return patchMCPServersQuery(this.db, input);\n }\n\n patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void> {\n return patchSandboxInfoQuery(this.db, input);\n }\n\n patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void> {\n return patchThreadCapabilityStateQuery(this.db, input);\n }\n\n listTurnEvents(input: ListTurnEventsInput): Promise<{ data: PersistedTurnEvent[]; pagination: TokenPagination }> {\n return listTurnEventsQuery(this.db, input);\n }\n\n listSessionEvents(input: ListSessionEventsInput): Promise<{ data: SessionEventItem[]; pagination: TokenPagination }> {\n return listSessionEventsQuery(this.db, input);\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport type { Model } from '../../../schemas/modelProvider';\nimport {\n flattenProviderModels,\n ModelProviderNameConflictError,\n type CreateModelProviderInput,\n type GetModelProviderInput,\n type IModelProviderStore,\n type ModelProviderRecord,\n type UpsertModelProviderInput,\n} from '../../modelProviderStore';\nimport { isUniqueViolation } from '../client';\nimport { json, now } from '../sqlExpressions';\nimport type { Database, ModelProviderTable } from '../types';\n\nfunction toRecord(row: Selectable<ModelProviderTable>): ModelProviderRecord {\n return {\n tenant_id: row.tenant_id,\n name: row.name,\n manifest: row.manifest,\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresModelProviderStore implements IModelProviderStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listProviders(tenantId: string, transaction?: Transaction<Database>): Promise<ModelProviderRecord[]> {\n const db = transaction ?? this.#db;\n const rows = await db\n .selectFrom('model_provider')\n .selectAll()\n .where('tenant_id', '=', tenantId)\n .orderBy('name')\n .execute();\n return rows.map(toRecord);\n }\n\n async getProvider(\n input: GetModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('model_provider')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async getProviderForUpdate(\n input: GetModelProviderInput,\n transaction: Transaction<Database>,\n ): Promise<ModelProviderRecord | undefined> {\n const row = await transaction\n .selectFrom('model_provider')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .forUpdate()\n .executeTakeFirst();\n return row ? toRecord(row) : undefined;\n }\n\n async createProvider(\n input: CreateModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord> {\n const db = transaction ?? this.#db;\n try {\n const row = await db\n .insertInto('model_provider')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new ModelProviderNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertProvider(\n input: UpsertModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord> {\n const db = transaction ?? this.#db;\n const row = await db\n .insertInto('model_provider')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: json(input.manifest),\n updated_at: now(),\n }),\n )\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n }\n\n async listModels(tenantId: string, transaction?: Transaction<Database>): Promise<Model[]> {\n return flattenProviderModels(await this.listProviders(tenantId, transaction));\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport { ulid } from 'ulid';\nimport type { OAuthClientRecord } from '../../../mcp/auth/types';\nimport {\n fromStoredOAuthClientRecord,\n McpServerNameConflictError,\n toStoredOAuthClientRecord,\n type CreateMcpServerInput,\n type GetMcpServerInput,\n type IMcpServerStore,\n type ListMcpServersInput,\n type McpServerRecord,\n type UpsertMcpServerInput,\n} from '../../mcpServerStore';\nimport { isUniqueViolation } from '../client';\nimport { json, now } from '../sqlExpressions';\nimport type { Database, McpServerTable } from '../types';\n\nfunction toRecord(row: Selectable<McpServerTable>): McpServerRecord {\n return {\n id: row.id,\n tenant_id: row.tenant_id,\n name: row.name,\n manifest: row.manifest,\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresMcpServerStore implements IMcpServerStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listServers(input: ListMcpServersInput, transaction?: Transaction<Database>): Promise<McpServerRecord[]> {\n if (input.names?.length === 0) {\n return [];\n }\n const db = transaction ?? this.#db;\n let query = db.selectFrom('mcp_server').selectAll().where('tenant_id', '=', input.tenant_id);\n if (input.names !== undefined) {\n query = query.where('name', 'in', [...input.names]);\n }\n const rows = await query.orderBy('name').execute();\n return rows.map(toRecord);\n }\n\n async getServer(input: GetMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('mcp_server')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async getServerForUpdate(\n input: GetMcpServerInput,\n transaction: Transaction<Database>,\n ): Promise<McpServerRecord | undefined> {\n const row = await transaction\n .selectFrom('mcp_server')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .forUpdate()\n .executeTakeFirst();\n return row ? toRecord(row) : undefined;\n }\n\n async createServer(input: CreateMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord> {\n const db = transaction ?? this.#db;\n try {\n const row = await db\n .insertInto('mcp_server')\n .values({\n id: ulid(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n oauth_server: null,\n oauth_client: null,\n created_at: now(),\n updated_at: now(),\n })\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new McpServerNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertServer(input: UpsertMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord> {\n const db = transaction ?? this.#db;\n const row = await db\n .insertInto('mcp_server')\n .values({\n id: ulid(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n oauth_server: null,\n oauth_client: null,\n created_at: now(),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: json(input.manifest),\n updated_at: now(),\n }),\n )\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n }\n\n async getClient(params: { id: string }, transaction?: Transaction<Database>): Promise<OAuthClientRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('mcp_server')\n .select(['oauth_server', 'oauth_client'])\n .where('id', '=', params.id)\n .executeTakeFirst();\n if (row?.oauth_server == null || row.oauth_client == null) {\n return undefined;\n }\n return fromStoredOAuthClientRecord({ server: row.oauth_server, client: row.oauth_client });\n }\n\n async saveClient(\n params: { id: string; record: OAuthClientRecord },\n transaction?: Transaction<Database>,\n ): Promise<void> {\n const db = transaction ?? this.#db;\n const stored = toStoredOAuthClientRecord(params.record);\n await db\n .updateTable('mcp_server')\n .set({\n oauth_server: json(stored.server),\n oauth_client: json(stored.client),\n })\n .where('id', '=', params.id)\n .execute();\n }\n\n async deleteClient(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n const db = transaction ?? this.#db;\n await db\n .updateTable('mcp_server')\n .set({\n oauth_server: null,\n oauth_client: null,\n })\n .where('id', '=', params.id)\n .execute();\n }\n}\n","import type { Kysely } from 'kysely';\nimport type { OAuthPendingAuthorization } from '../../../../mcp/auth/types';\nimport {\n fromStoredOAuthPendingAuthorizationData,\n PENDING_AUTHORIZATION_TTL_MS,\n toStoredOAuthPendingAuthorizationData,\n} from '../../../mcpServerStore';\nimport { json, now, nowMinusMs } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nexport async function savePendingAuthorization(\n db: Kysely<Database>,\n pending: OAuthPendingAuthorization,\n): Promise<void> {\n const authData = toStoredOAuthPendingAuthorizationData(pending);\n\n await db\n .insertInto('oauth_pending_authorization')\n .values({\n id: pending.state,\n oauth_server_id: pending.id,\n user_id: pending.userRef,\n auth_data: json(authData),\n created_at: now(),\n })\n .execute();\n}\n\n/**\n * Single-use claim: DELETE … RETURNING under the TTL filter so only one concurrent\n * callback wins the row.\n */\nexport async function consumePendingAuthorization(\n db: Kysely<Database>,\n params: { state: string },\n): Promise<OAuthPendingAuthorization | undefined> {\n const row = await db\n .deleteFrom('oauth_pending_authorization')\n .where('id', '=', params.state)\n .where('created_at', '>', nowMinusMs(PENDING_AUTHORIZATION_TTL_MS))\n .returning(['id', 'oauth_server_id', 'user_id', 'auth_data'])\n .executeTakeFirst();\n\n if (row === undefined) {\n return undefined;\n }\n\n return {\n state: row.id,\n id: row.oauth_server_id,\n userRef: row.user_id,\n ...fromStoredOAuthPendingAuthorizationData(row.auth_data),\n };\n}\n\nexport async function deletePendingAuthorizationsForServer(\n db: Kysely<Database>,\n params: { id: string },\n): Promise<void> {\n await db.deleteFrom('oauth_pending_authorization').where('oauth_server_id', '=', params.id).execute();\n}\n","import { sql, type Kysely } from 'kysely';\nimport type { OAuthToken } from '../../../mcpServerStore';\nimport { json, now } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nexport async function saveToken(\n db: Kysely<Database>,\n params: { id: string; userRef: string; token: OAuthToken },\n): Promise<void> {\n await db\n .insertInto('oauth_token')\n .values({\n oauth_server_id: params.id,\n user_id: params.userRef,\n token: json(params.token),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['oauth_server_id', 'user_id']).doUpdateSet({\n token: sql`excluded.token`,\n updated_at: sql`excluded.updated_at`,\n }),\n )\n .execute();\n}\n\nexport async function getToken(\n db: Kysely<Database>,\n params: { id: string; userRef: string },\n): Promise<OAuthToken | undefined> {\n const row = await db\n .selectFrom('oauth_token')\n .select('token')\n .where('oauth_server_id', '=', params.id)\n .where('user_id', '=', params.userRef)\n .executeTakeFirst();\n\n return row === undefined ? undefined : row.token;\n}\n\nexport async function getTokens(\n db: Kysely<Database>,\n params: { ids: string[]; userRef: string },\n): Promise<Map<string, OAuthToken>> {\n if (params.ids.length === 0) {\n return new Map();\n }\n const rows = await db\n .selectFrom('oauth_token')\n .select(['oauth_server_id', 'token'])\n .where('oauth_server_id', 'in', params.ids)\n .where('user_id', '=', params.userRef)\n .execute();\n\n return new Map(rows.map(row => [row.oauth_server_id, row.token]));\n}\n\nexport async function deleteToken(db: Kysely<Database>, params: { id: string; userRef: string }): Promise<void> {\n await db\n .deleteFrom('oauth_token')\n .where('oauth_server_id', '=', params.id)\n .where('user_id', '=', params.userRef)\n .execute();\n}\n\nexport async function deleteTokensForServer(db: Kysely<Database>, params: { id: string }): Promise<void> {\n await db.deleteFrom('oauth_token').where('oauth_server_id', '=', params.id).execute();\n}\n","import type { Kysely, Transaction } from 'kysely';\nimport type { IOAuthTokenStore, OAuthPendingAuthorization, OAuthToken, OAuthTokenKey } from '../../../mcp/auth/types';\nimport { fromStoredOAuthToken, toStoredOAuthToken } from '../../mcpServerStore';\nimport type { Database } from '../types';\nimport {\n consumePendingAuthorization,\n deletePendingAuthorizationsForServer,\n savePendingAuthorization,\n} from './queries/pendingAuthorization';\nimport { deleteToken, deleteTokensForServer, getToken, getTokens, saveToken } from './queries/token';\n\nexport class PostgresOAuthTokenStore implements IOAuthTokenStore<Transaction<Database>> {\n constructor(private readonly db: Kysely<Database>) {}\n\n savePendingAuthorization(pending: OAuthPendingAuthorization, transaction?: Transaction<Database>): Promise<void> {\n return savePendingAuthorization(transaction ?? this.db, pending);\n }\n\n consumePendingAuthorization(\n params: { state: string },\n transaction?: Transaction<Database>,\n ): Promise<OAuthPendingAuthorization | undefined> {\n return consumePendingAuthorization(transaction ?? this.db, params);\n }\n\n saveToken(params: OAuthTokenKey & { token: OAuthToken }, transaction?: Transaction<Database>): Promise<void> {\n return saveToken(transaction ?? this.db, {\n id: params.id,\n userRef: params.userRef,\n token: toStoredOAuthToken(params.token),\n });\n }\n\n async getToken(params: OAuthTokenKey, transaction?: Transaction<Database>): Promise<OAuthToken | undefined> {\n const stored = await getToken(transaction ?? this.db, params);\n return stored === undefined ? undefined : fromStoredOAuthToken(stored);\n }\n\n async getTokens(\n params: { ids: string[]; userRef: string },\n transaction?: Transaction<Database>,\n ): Promise<Map<string, OAuthToken>> {\n const stored = await getTokens(transaction ?? this.db, params);\n return new Map([...stored].map(([id, token]) => [id, fromStoredOAuthToken(token)]));\n }\n\n deleteToken(params: OAuthTokenKey, transaction?: Transaction<Database>): Promise<void> {\n return deleteToken(transaction ?? this.db, params);\n }\n\n deleteTokensForServer(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n return deleteTokensForServer(transaction ?? this.db, params);\n }\n\n deletePendingAuthorizationsForServer(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n return deletePendingAuthorizationsForServer(transaction ?? this.db, params);\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport {\n SkillNameConflictError,\n type CreateSkillInput,\n type GetSkillInput,\n type ISkillStore,\n type ListSkillsInput,\n type SkillRecord,\n type UpsertSkillInput,\n} from '../../skillStore';\nimport { isUniqueViolation } from '../client';\nimport { json, now } from '../sqlExpressions';\nimport type { Database, SkillTable } from '../types';\n\nfunction toRecord(row: Selectable<SkillTable>): SkillRecord {\n return {\n tenant_id: row.tenant_id,\n name: row.name,\n manifest: row.manifest,\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresSkillStore implements ISkillStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listSkills(input: ListSkillsInput, transaction?: Transaction<Database>): Promise<SkillRecord[]> {\n if (input.names?.length === 0) {\n return [];\n }\n const db = transaction ?? this.#db;\n let query = db.selectFrom('skill').selectAll().where('tenant_id', '=', input.tenant_id);\n if (input.names !== undefined) {\n query = query.where('name', 'in', [...input.names]);\n }\n const rows = await query.orderBy('name').execute();\n return rows.map(toRecord);\n }\n\n async getSkill(input: GetSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('skill')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async createSkill(input: CreateSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord> {\n const db = transaction ?? this.#db;\n try {\n const row = await db\n .insertInto('skill')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new SkillNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertSkill(input: UpsertSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord> {\n const db = transaction ?? this.#db;\n const row = await db\n .insertInto('skill')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: json(input.manifest),\n updated_at: now(),\n }),\n )\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport {\n type ISandboxProviderStore,\n type SandboxProviderRecord,\n type UpdateSandboxStatusInput,\n type UpsertSandboxProviderInput,\n} from '../../sandboxProviderStore';\nimport { json, now } from '../sqlExpressions';\nimport type { Database, SandboxProviderTable } from '../types';\n\nfunction toRecord(row: Selectable<SandboxProviderTable>): SandboxProviderRecord {\n return {\n tenant_id: row.tenant_id,\n manifest: row.manifest,\n status: row.status,\n status_reason: row.status_reason,\n build_metadata: row.build_metadata,\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresSandboxProviderStore implements ISandboxProviderStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async getSandboxProvider(\n tenantId: string,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('sandbox_provider')\n .selectAll()\n .where('tenant_id', '=', tenantId)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async getSandboxProviderForUpdate(\n tenantId: string,\n transaction: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const row = await transaction\n .selectFrom('sandbox_provider')\n .selectAll()\n .where('tenant_id', '=', tenantId)\n .forUpdate()\n .executeTakeFirst();\n return row ? toRecord(row) : undefined;\n }\n\n async upsertSandboxProvider(\n input: UpsertSandboxProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord> {\n const db = transaction ?? this.#db;\n const row = await db\n .insertInto('sandbox_provider')\n .values({\n tenant_id: input.tenant_id,\n manifest: json(input.manifest),\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? json(input.build_metadata) : null,\n created_at: now(),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['tenant_id']).doUpdateSet({\n manifest: json(input.manifest),\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? json(input.build_metadata) : null,\n updated_at: now(),\n }),\n )\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n }\n\n async updateSandboxStatus(\n input: UpdateSandboxStatusInput,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .updateTable('sandbox_provider')\n .set({\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? json(input.build_metadata) : null,\n updated_at: now(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .returningAll()\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport { ulid } from 'ulid';\nimport {\n AgentNameConflictError,\n parseStoredAgentSpec,\n type AgentRecord,\n type CreateAgentInput,\n type DeleteAgentInput,\n type GetAgentInput,\n type IAgentStore,\n type UpdateAgentInput,\n} from '../../agentStore';\nimport { isUniqueViolation } from '../client';\nimport { json, now } from '../sqlExpressions';\nimport type { AgentTable, Database } from '../types';\n\nfunction toRecord(row: Selectable<AgentTable>): AgentRecord {\n return {\n id: row.id,\n tenant_id: row.tenant_id,\n name: row.name,\n manifest: parseStoredAgentSpec(row.manifest),\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresAgentStore implements IAgentStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listAgents(tenantId: string, transaction?: Transaction<Database>): Promise<AgentRecord[]> {\n const db = transaction ?? this.#db;\n const rows = await db.selectFrom('agent').selectAll().where('tenant_id', '=', tenantId).orderBy('name').execute();\n return rows.map(toRecord);\n }\n\n async getAgent(input: GetAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord | undefined> {\n const db = transaction ?? this.#db;\n let query = db.selectFrom('agent').selectAll().where('tenant_id', '=', input.tenant_id);\n if ('id' in input) {\n query = query.where('id', '=', input.id);\n } else {\n query = query.where('name', '=', input.name);\n }\n const row = await query.executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async createAgent(input: CreateAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord> {\n const db = transaction ?? this.#db;\n try {\n const row = await db\n .insertInto('agent')\n .values({\n id: ulid().toLowerCase(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new AgentNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async updateAgent(input: UpdateAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .updateTable('agent')\n .set({\n manifest: json(input.manifest),\n updated_at: now(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .where('id', '=', input.id)\n .returningAll()\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async deleteAgent(input: DeleteAgentInput, transaction?: Transaction<Database>): Promise<void> {\n const db = transaction ?? this.#db;\n await db.deleteFrom('agent').where('tenant_id', '=', input.tenant_id).where('id', '=', input.id).execute();\n }\n}\n","/**\n * Server entry point: validates config, migrates the selected database, wires\n * stores, and starts the HTTP server. Any config, migration, or store error\n * aborts startup.\n *\n * `STANDALONE=true` (default): SQLite, no Redis. `STANDALONE=false`: Postgres + Redis.\n *\n * Config is validated at import time (`./config`). Runtime startup failures\n * (migrate, Redis, listen) are caught below and exit non-zero. SQLite vs\n * Postgres store modules stay dynamic so only the active engine is loaded.\n */\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\n\nlet configuration: typeof import('./config').default;\nlet isOidcConfigured: typeof import('./config').isOidcConfigured;\n\ntry {\n ({ default: configuration, isOidcConfigured } = await import('./config'));\n} catch (error) {\n console.error(\n 'Failed to start server: Failed to load configuration:',\n error instanceof Error ? error.message : error,\n );\n process.exit(1);\n}\n\nimport { serve } from '@hono/node-server';\nimport {\n CancellationReason,\n Sessions,\n type ISessionStore,\n type TurnStreamingEvent,\n} from '@truefoundry/trueforge-core/agent-session';\nimport { RequestReplyExecutor, RequestReplyRouter } from '@truefoundry/trueforge-core/request-reply';\nimport type { Transaction } from 'kysely';\nimport type { RedisClientType } from 'redis';\nimport type { Logger } from 'winston';\n\nimport { createServerApp } from './app';\nimport { initOidc } from './auth/oidc';\nimport { McpCatalog } from './catalog/McpCatalog';\nimport { ModelCatalog } from './catalog/ModelCatalog';\nimport { SandboxCatalog } from './catalog/SandboxCatalog';\nimport { SkillCatalog } from './catalog/SkillCatalog';\nimport { type DistributedServerConfiguration } from './config';\nimport type { IAgentStore } from './db/agentStore';\nimport type { IMcpServerStore } from './db/mcpServerStore';\nimport type { IModelProviderStore } from './db/modelProviderStore';\nimport type { Database as PostgresDatabase } from './db/postgres/types';\nimport type { ISandboxProviderStore } from './db/sandboxProviderStore';\nimport type { ISkillStore } from './db/skillStore';\nimport type { Database as SqliteDatabase } from './db/sqlite/types';\nimport type { WithTransaction } from './db/transaction';\nimport { mountFrontend } from './frontend';\nimport { createServerLogger, shouldColorize } from './logger';\nimport type { IOAuthTokenStore } from './mcp/auth/types';\nimport { PACKAGE_VERSION } from './packageVersion';\nimport { ActiveTurnRegistry } from './runtime/activeTurns';\nimport { EventSubscriptionRegistry } from './runtime/event-subscription';\nimport { printStandaloneStartupBanner } from './startupBanner';\n\n/** Persistence + optional Redis wired for the selected topology. */\ninterface ServerPersistence<TTransaction> {\n sessionStore: ISessionStore;\n modelProviderStore: IModelProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n mcpServerStore: IMcpServerStore<TTransaction>;\n tokenStore: IOAuthTokenStore<TTransaction>;\n skillStore: ISkillStore<TTransaction>;\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n agentStore: IAgentStore<TTransaction>;\n destroyDb: () => Promise<void>;\n redis: RedisClientType | undefined;\n}\n\n/** SQLite stores; Redis unused (executor peering disabled). */\nasync function createStandalonePersistence(options: {\n sqlitePath: string;\n logger: Logger;\n}): Promise<ServerPersistence<Transaction<SqliteDatabase>>> {\n const { sqlitePath, logger } = options;\n await mkdir(path.dirname(sqlitePath), { recursive: true });\n const [{ createSqliteDb }, { migrateSqliteToLatest }, sqliteStores] = await Promise.all([\n import('./db/sqlite/client'),\n import('./db/migrateSqlite'),\n Promise.all([\n import('./db/sqlite/session-store/SqliteSessionStore'),\n import('./db/sqlite/model-provider-store/SqliteModelProviderStore'),\n import('./db/sqlite/mcp-server-store/SqliteMcpServerStore'),\n import('./db/sqlite/token-store/SqliteOAuthTokenStore'),\n import('./db/sqlite/skill-store/SqliteSkillStore'),\n import('./db/sqlite/sandbox-provider-store/SqliteSandboxProviderStore'),\n import('./db/sqlite/agent-store/SqliteAgentStore'),\n ]),\n ]);\n const [\n { SqliteSessionStore },\n { SqliteModelProviderStore },\n { SqliteMcpServerStore },\n { SqliteOAuthTokenStore },\n { SqliteSkillStore },\n { SqliteSandboxProviderStore },\n { SqliteAgentStore },\n ] = sqliteStores;\n\n const db = createSqliteDb(sqlitePath);\n await migrateSqliteToLatest(db);\n logger.info(`Standalone mode: sqlite at ${sqlitePath}`);\n logger.info('Standalone mode: executor peering disabled and Redis unused');\n\n return {\n sessionStore: new SqliteSessionStore(db),\n modelProviderStore: new SqliteModelProviderStore(db),\n withTransaction: callback => db.transaction().execute(callback),\n mcpServerStore: new SqliteMcpServerStore(db),\n tokenStore: new SqliteOAuthTokenStore(db),\n skillStore: new SqliteSkillStore(db),\n sandboxProviderStore: new SqliteSandboxProviderStore(db),\n agentStore: new SqliteAgentStore(db),\n destroyDb: () => db.destroy(),\n redis: undefined,\n };\n}\n\n/** Postgres stores + Redis for executor peering. */\nasync function createDistributedPersistence(options: {\n configuration: DistributedServerConfiguration;\n logger: Logger;\n}): Promise<ServerPersistence<Transaction<PostgresDatabase>>> {\n const { configuration, logger } = options;\n const {\n DATABASE_URL: databaseUrl,\n DATABASE_POOL_MAX: databasePoolMax,\n POSTGRES_STATEMENT_TIMEOUT_MS: statementTimeoutMs,\n POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS: idleInTransactionSessionTimeoutMs,\n REDIS_URL: redisUrl,\n EXECUTOR_ID: executorId,\n } = configuration;\n\n const [{ createDb }, { migrateToLatest }, { connectRedis }, postgresStores] = await Promise.all([\n import('./db/postgres/client'),\n import('./db/migratePostgres'),\n import('./runtime/redis'),\n Promise.all([\n import('./db/postgres/session-store/PostgresSessionStore'),\n import('./db/postgres/model-provider-store/PostgresModelProviderStore'),\n import('./db/postgres/mcp-server-store/PostgresMcpServerStore'),\n import('./db/postgres/token-store/PostgresOAuthTokenStore'),\n import('./db/postgres/skill-store/PostgresSkillStore'),\n import('./db/postgres/sandbox-provider-store/PostgresSandboxProviderStore'),\n import('./db/postgres/agent-store/PostgresAgentStore'),\n ]),\n ]);\n const [\n { PostgresSessionStore },\n { PostgresModelProviderStore },\n { PostgresMcpServerStore },\n { PostgresOAuthTokenStore },\n { PostgresSkillStore },\n { PostgresSandboxProviderStore },\n { PostgresAgentStore },\n ] = postgresStores;\n\n const db = createDb({\n connectionString: databaseUrl,\n poolMax: databasePoolMax,\n statementTimeoutMs,\n idleInTransactionSessionTimeoutMs,\n });\n await migrateToLatest(db);\n logger.info('Distributed mode: postgres');\n logger.info(`Executor id: ${executorId}`);\n\n return {\n sessionStore: new PostgresSessionStore(db),\n modelProviderStore: new PostgresModelProviderStore(db),\n withTransaction: callback => db.transaction().execute(callback),\n mcpServerStore: new PostgresMcpServerStore(db),\n tokenStore: new PostgresOAuthTokenStore(db),\n skillStore: new PostgresSkillStore(db),\n sandboxProviderStore: new PostgresSandboxProviderStore(db),\n agentStore: new PostgresAgentStore(db),\n destroyDb: () => db.destroy(),\n redis: await connectRedis({ url: redisUrl, logger }),\n };\n}\n\n/** Keeps `TTransaction` concrete when wiring a single persistence topology into the app. */\nasync function createServerRuntime<TTransaction>(persistence: ServerPersistence<TTransaction>, logger: Logger) {\n const {\n sessionStore,\n modelProviderStore,\n withTransaction,\n mcpServerStore,\n tokenStore,\n skillStore,\n sandboxProviderStore,\n agentStore,\n destroyDb,\n redis,\n } = persistence;\n\n const activeTurns = new ActiveTurnRegistry();\n const requestReplyRouter = new RequestReplyRouter();\n const eventSubscriptions = new EventSubscriptionRegistry<TurnStreamingEvent>(redis);\n\n const oidc = isOidcConfigured(configuration) ? configuration.OIDC : undefined;\n if (oidc) {\n logger.info('Auth is enabled', { issuer: oidc.OIDC_ISSUER_URL });\n } else {\n logger.warn('Auth is disabled; browser login is off');\n }\n const oidcClient = await initOidc(oidc);\n\n const app = createServerApp({\n modelCatalog: ModelCatalog.load(),\n mcpCatalog: McpCatalog.load(),\n skillCatalog: SkillCatalog.load(),\n sandboxCatalog: SandboxCatalog.load(),\n modelProviderStore,\n withTransaction,\n mcpServerStore,\n tokenStore,\n skillStore,\n sandboxProviderStore,\n agentStore,\n sessionStore,\n sessions: new Sessions({ sessionStore }),\n activeTurns,\n redis,\n requestReplyRouter,\n eventSubscriptions,\n logger,\n oidcClient,\n });\n\n return { activeTurns, app, destroyDb, redis, requestReplyRouter };\n}\n\ntry {\n const logger = createServerLogger({\n level: configuration.LOG_LEVEL,\n standalone: configuration.STANDALONE,\n version: PACKAGE_VERSION,\n });\n\n if (configuration.STANDALONE) {\n printStandaloneStartupBanner({ version: PACKAGE_VERSION, color: shouldColorize() });\n } else {\n logger.info('TrueForge starting', { mode: 'distributed' });\n }\n\n const { activeTurns, app, destroyDb, redis, requestReplyRouter } = configuration.STANDALONE\n ? await createServerRuntime(\n await createStandalonePersistence({ sqlitePath: configuration.SQLITE_PATH, logger }),\n logger,\n )\n : await createServerRuntime(await createDistributedPersistence({ configuration, logger }), logger);\n\n if (mountFrontend(app, configuration.FRONTEND_DIR)) {\n logger.info(`Serving frontend from ${configuration.FRONTEND_DIR}`);\n } else {\n logger.warn(\n `No frontend build at ${configuration.FRONTEND_DIR}: serving the API only. ` +\n 'Run `pnpm --filter frontend build` (and copy via build:frontend-assets) to serve the UI, or `pnpm standalone:dev` / `pnpm dev` for Vite.',\n );\n }\n\n // After createServerApp so every request-reply route is registered before\n // the executor starts consuming messages. The executor needs a dedicated\n // subscriber connection (a subscribed client cannot issue normal commands);\n // this process owns its lifecycle. Connect before init() so init() awaits\n // the initial subscribe + heartbeat — the replica is reachable for peering\n // before the HTTP server starts.\n let requestReplySubscriber: RedisClientType | undefined;\n let requestReplyExecutor: RequestReplyExecutor | undefined;\n if (redis) {\n requestReplySubscriber = redis.duplicate();\n requestReplySubscriber.on('error', (error: Error) => {\n logger.error('[RedisSubscriber] Client error', extractErrorLogFields(error));\n });\n await requestReplySubscriber.connect();\n requestReplyExecutor = new RequestReplyExecutor({\n executorId: configuration.EXECUTOR_ID,\n redis,\n subscriberClient: requestReplySubscriber,\n requestHandler: requestReplyRouter.createRequestHandler(),\n logger,\n options: {\n heartbeatIntervalMs: configuration.REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS,\n replyTtlMs: configuration.REDIS_REQUEST_REPLY_REPLY_TTL_MS,\n },\n });\n await requestReplyExecutor.init();\n }\n\n const server = serve({ fetch: app.fetch, port: configuration.PORT, hostname: configuration.HOST }, info => {\n logger.info(`Agent server listening on http://${configuration.HOST}:${String(info.port)} (docs at /api/v1/docs)`);\n });\n\n server.on('error', (error: unknown) => {\n console.error('Failed to start server:', error instanceof Error ? error.message : error);\n process.exit(1);\n });\n\n // Graceful drain is the safe default for built and direct execution.\n // Development watch mode opts out so tsx can restart without waiting for a drain.\n if (configuration.NODE_ENV !== 'development') {\n let shuttingDown = false;\n const shutdown = async (signal: NodeJS.Signals) => {\n if (shuttingDown) {\n return;\n }\n shuttingDown = true;\n logger.info(`Received ${signal}, draining connections before shutdown`);\n\n // Arm at the start of each shutdown; unref so this timer alone cannot keep the process alive.\n setTimeout(() => {\n logger.warn(`Drain timed out after ${String(configuration.GRACEFUL_TIMEOUT_SECONDS)}s, exiting`);\n process.exit(1);\n }, configuration.GRACEFUL_TIMEOUT_SECONDS * 1000).unref();\n\n const closed = new Promise<void>(resolve => {\n server.close(() => {\n resolve();\n });\n });\n\n // Sets the registry's shutdown reason immediately so late track() (in-flight create-turn still\n // inside session.createTurn) aborts as Abandoned; then drains the registry. await\n // closed covers the gap where the registry is empty before that late track().\n await activeTurns.shutdownAndWait(CancellationReason.Abandoned);\n await closed;\n // Stop serving peer requests (waits for in-flight replies), then close\n // the clients this process owns: the subscriber duplicate and the primary.\n await requestReplyExecutor?.drain();\n await requestReplySubscriber?.close().catch((error: unknown) => {\n logger.warn('[Redis] Error closing subscriber client during shutdown', extractErrorLogFields(error));\n });\n await redis?.close().catch((error: unknown) => {\n logger.warn('[Redis] Error closing client during shutdown', extractErrorLogFields(error));\n });\n await destroyDb();\n process.exit(0);\n };\n process.on('SIGTERM', signal => {\n void shutdown(signal);\n });\n process.on('SIGINT', signal => {\n void shutdown(signal);\n });\n }\n} catch (error) {\n console.error('Failed to start server:', error instanceof Error ? error.message : error);\n process.exit(1);\n}\n","/** The API: resource routers, the OpenAPI document and Swagger UI, all under /api/v1. */\nimport { swaggerUI } from '@hono/swagger-ui';\nimport { OpenAPIHono, z } from '@hono/zod-openapi';\nimport type { ISessionStore, Sessions, TurnStreamingEvent } from '@truefoundry/trueforge-core/agent-session';\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport type { RequestReplyRouter } from '@truefoundry/trueforge-core/request-reply';\nimport type { Context, ErrorHandler, MiddlewareHandler } from 'hono';\nimport { bodyLimit } from 'hono/body-limit';\nimport { HTTPException } from 'hono/http-exception';\nimport type { Configuration } from 'openid-client';\nimport type { RedisClientType } from 'redis';\nimport type { Logger } from 'winston';\nimport { createAgentsRouter } from './apis/agents';\nimport { createAuthRouter } from './apis/auth';\nimport { createCapabilitiesRouter } from './apis/capabilities';\nimport { createCatalogRouter } from './apis/catalog';\nimport { createMcpOAuthRouter } from './apis/mcpOAuth';\nimport { createMcpServersRouter } from './apis/mcpServers';\nimport { createModelsRouter } from './apis/models';\nimport { createSessionsRouter } from './apis/sessions';\nimport { createSettingsRouter } from './apis/settings';\nimport { createAvailableSkillsRouter } from './apis/skills';\nimport { createTurnsRouter } from './apis/turns';\nimport { resolveUserContext } from './auth/identity';\nimport { adminAuthMiddleware, authMiddleware } from './auth/middleware';\nimport type { McpCatalog } from './catalog/McpCatalog';\nimport type { ModelCatalog } from './catalog/ModelCatalog';\nimport type { SandboxCatalog } from './catalog/SandboxCatalog';\nimport type { SkillCatalog } from './catalog/SkillCatalog';\nimport configuration from './config';\nimport type { IAgentStore } from './db/agentStore';\nimport type { IMcpServerStore } from './db/mcpServerStore';\nimport type { IModelProviderStore } from './db/modelProviderStore';\nimport type { ISandboxProviderStore } from './db/sandboxProviderStore';\nimport type { ISkillStore } from './db/skillStore';\nimport type { WithTransaction } from './db/transaction';\nimport type { IOAuthTokenStore } from './mcp/auth/types';\nimport { PACKAGE_VERSION } from './packageVersion';\nimport type { ActiveTurnRegistry } from './runtime/activeTurns';\nimport type { EventSubscriptionRegistry } from './runtime/event-subscription';\nimport { zodErrorResponse, zodValidationHook } from './zodErrorResponse';\n\nconst BEARER_AUTH_SCHEME = 'BearerAuth';\n\n/** Hono bodyLimit wrapper that returns the API error envelope on 413. */\nexport function createRequestBodyLimitMiddleware(maxSize: number): MiddlewareHandler {\n return bodyLimit({\n maxSize,\n onError: c =>\n c.json({ error: { message: `Request body exceeds the maximum size of ${String(maxSize)} bytes` } }, 413),\n });\n}\n\nexport function createAppErrorHandler(params: { logger: Logger }): ErrorHandler {\n return (error, c) => {\n if (error instanceof z.ZodError) {\n return zodErrorResponse(c, error);\n }\n if (error instanceof HTTPException) {\n if (error.status >= 500) {\n params.logger.error('Server API error', {\n status: error.status,\n ...extractErrorLogFields(error),\n });\n }\n return c.json({ error: { message: error.message } }, error.status);\n }\n params.logger.error('Unhandled error', extractErrorLogFields(error));\n return c.json({ error: { message: 'Internal server error' } }, 500);\n };\n}\n\nconst openApiDocConfig = {\n openapi: '3.1.0',\n info: {\n title: 'TrueForge API',\n description:\n 'HTTP API for the TrueForge agent server (`/api/v1`). Interactive docs are served at `/api/v1/docs` ' +\n '(OpenAPI JSON at `/api/v1/openapi.json`).\\n\\n' +\n '**Authentication:** Standalone deployments (no OIDC) accept requests without credentials — middleware ' +\n 'stamps a local default user. When OIDC is configured, protected routes require a valid `id_token` cookie ' +\n 'or `Authorization: Bearer` ID token. There is no built-in API-key scheme; ' +\n 'pass custom headers only if your reverse proxy or IdP layer requires them.\\n\\n' +\n 'Covers DB-backed sessions, the agent registry, settings catalogs, and model/MCP/skill/sandbox providers.',\n version: PACKAGE_VERSION,\n },\n};\n\n/** Registers the Bearer ID-token scheme used by {@link buildOpenApiDocument}. */\nexport function registerOpenApiBearerAuth(app: OpenAPIHono): void {\n app.openAPIRegistry.registerComponent('securitySchemes', BEARER_AUTH_SCHEME, {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n description:\n 'ID token (`Authorization: Bearer <id_token>`). Required on protected routes. ' +\n 'Browser sessions may use the HttpOnly `id_token` cookie instead.',\n });\n}\n\n/**\n * Single source for both the served document and the one the SDK is built from.\n * When `authEnabled`, advertises required Bearer auth on operations that inherit global security.\n */\nexport function buildOpenApiDocument(app: OpenAPIHono, options?: { authEnabled?: boolean }) {\n const authEnabled = options?.authEnabled ?? false;\n if (authEnabled) {\n registerOpenApiBearerAuth(app);\n }\n return app.getOpenAPI31Document({\n ...openApiDocConfig,\n ...(authEnabled ? { security: [{ [BEARER_AUTH_SCHEME]: [] }] } : {}),\n });\n}\n\nfunction routeNotFound(c: Context) {\n return c.json({ error: { message: `Route not found: ${c.req.method} ${c.req.path}` } }, 404);\n}\n\n/** Sub-app shell: `.use('*', authMiddleware)` then child routes — same as gateway routers. */\nfunction withAuth(router: OpenAPIHono): OpenAPIHono {\n const shell = new OpenAPIHono();\n shell.use('*', authMiddleware);\n shell.route('/', router);\n return shell;\n}\n\n/** Admin-only routes: local admin when auth is disabled; with OIDC requires an authenticated admin. */\nfunction withAdminAuth(router: OpenAPIHono): OpenAPIHono {\n const shell = new OpenAPIHono();\n shell.use('*', adminAuthMiddleware);\n shell.route('/', router);\n return shell;\n}\n\nexport interface ServerDeps<TTransaction> {\n modelCatalog: ModelCatalog;\n mcpCatalog: McpCatalog;\n skillCatalog: SkillCatalog;\n sandboxCatalog: SandboxCatalog;\n modelProviderStore: IModelProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n mcpServerStore: IMcpServerStore<TTransaction>;\n tokenStore: IOAuthTokenStore<TTransaction>;\n skillStore: ISkillStore<TTransaction>;\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n agentStore: IAgentStore<TTransaction>;\n sessionStore: ISessionStore;\n sessions: Sessions;\n activeTurns: ActiveTurnRegistry;\n /** Primary Redis client (server-owned); undefined in standalone mode. */\n redis?: RedisClientType | undefined;\n /** Request-reply dispatch table served by this replica's executor. */\n requestReplyRouter: RequestReplyRouter;\n /** Hands out each turn's resumable event stream to the create and subscribe handlers. */\n eventSubscriptions: EventSubscriptionRegistry<TurnStreamingEvent>;\n logger: Logger;\n /** Discovered openid-client configuration; undefined when browser login is disabled. */\n oidcClient: Configuration | undefined;\n}\n\nexport function createServerApp<TTransaction>(deps: ServerDeps<TTransaction>) {\n const app = new OpenAPIHono({ defaultHook: zodValidationHook });\n const authEnabled = deps.oidcClient != null;\n\n app.use('*', createRequestBodyLimitMiddleware(configuration.MAX_REQUEST_BODY_BYTES));\n\n app.get('/healthz', c => c.text('OK!'));\n\n app.route('/api/v1/auth', createAuthRouter({ oidcClient: deps.oidcClient, logger: deps.logger }));\n app.route(\n '/api/v1/capabilities',\n withAuth(\n createCapabilitiesRouter({\n sandboxProviderStore: deps.sandboxProviderStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n }),\n ),\n );\n app.route(\n '/api/v1/models',\n withAuth(\n createModelsRouter({\n modelProviderStore: deps.modelProviderStore,\n withTransaction: deps.withTransaction,\n }),\n ),\n );\n app.route(\n '/api/v1/catalog',\n withAuth(\n createCatalogRouter({\n modelCatalog: deps.modelCatalog,\n mcpCatalog: deps.mcpCatalog,\n skillCatalog: deps.skillCatalog,\n sandboxCatalog: deps.sandboxCatalog,\n }),\n ),\n );\n // Public MCP OAuth callback must be registered before the gated `/mcp-servers` mount so\n // `withAuth` cannot intercept IdP redirects to `/api/v1/mcp-servers/oauth/*`.\n app.route(\n '/api/v1/mcp-servers/oauth',\n createMcpOAuthRouter({\n tokenStore: deps.tokenStore,\n mcpServerStore: deps.mcpServerStore,\n logger: deps.logger,\n }),\n );\n app.route(\n '/api/v1/mcp-servers',\n withAuth(\n createMcpServersRouter({\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n resolveUserContext,\n }),\n ),\n );\n app.route(\n '/api/v1/skills',\n withAuth(\n createAvailableSkillsRouter({\n skillStore: deps.skillStore,\n withTransaction: deps.withTransaction,\n }),\n ),\n );\n app.route(\n '/api/v1/agents',\n withAuth(\n createAgentsRouter({\n agentStore: deps.agentStore,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n withTransaction: deps.withTransaction,\n }),\n ),\n );\n app.route(\n '/api/v1/settings',\n withAdminAuth(\n createSettingsRouter({\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n resolveUserContext,\n }),\n ),\n );\n app.route(\n '/api/v1/sessions',\n withAuth(\n createSessionsRouter({\n sessions: deps.sessions,\n sessionStore: deps.sessionStore,\n activeTurns: deps.activeTurns,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n agentStore: deps.agentStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n redis: deps.redis,\n requestReplyRouter: deps.requestReplyRouter,\n resolveUserContext: resolveUserContext,\n logger: deps.logger,\n }),\n ),\n );\n app.route(\n '/api/v1/sessions',\n withAuth(\n createTurnsRouter({\n sessions: deps.sessions,\n sessionStore: deps.sessionStore,\n activeTurns: deps.activeTurns,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n skillStore: deps.skillStore,\n agentStore: deps.agentStore,\n eventSubscriptions: deps.eventSubscriptions,\n sandboxProviderStore: deps.sandboxProviderStore,\n logger: deps.logger,\n resolveUserContext: resolveUserContext,\n }),\n ),\n );\n\n app.get('/api/v1/docs', swaggerUI({ url: '/api/v1/openapi.json' }));\n app.get('/api/v1/openapi.json', c => c.json(buildOpenApiDocument(app, { authEnabled })));\n\n app.notFound(routeNotFound);\n\n app.onError(createAppErrorHandler({ logger: deps.logger }));\n\n return app;\n}\n","/**\n * DB-backed agent registry API (mounted at /api/v1/agents).\n */\nimport { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport { AgentNameConflictError, type AgentRecord, type IAgentStore } from '../db/agentStore';\nimport type { IMcpServerStore } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport type { WithTransaction } from '../db/transaction';\nimport {\n createAgentRoute,\n deleteAgentRoute,\n getAgentRoute,\n listAgentsRoute,\n putAgentRoute,\n} from '../routes/agentRoutes';\nimport { validateAgentSpec } from '../runtime/sessionResources';\nimport { type Agent, type CreateAgentRequest } from '../schemas/agent';\nimport { TENANT_ID } from './sessions';\n\nexport interface AgentsRouterDeps<TTransaction> {\n agentStore: IAgentStore<TTransaction>;\n modelProviderStore: IModelProviderStore<TTransaction>;\n mcpServerStore: IMcpServerStore<TTransaction>;\n skillStore: ISkillStore<TTransaction>;\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}\n\n/** Wire view: identity columns plus nested manifest. */\nfunction toWireAgent(record: AgentRecord): Agent {\n return {\n id: record.id,\n name: record.name,\n manifest: record.manifest,\n };\n}\n\nasync function validateManifest<TTransaction>({\n spec,\n deps,\n}: {\n spec: AgentSpec;\n deps: AgentsRouterDeps<TTransaction>;\n}): Promise<AgentSpec> {\n await validateAgentSpec({\n spec,\n tenant_id: TENANT_ID,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n });\n return spec;\n}\n\nexport function createAgentsRouter<TTransaction>(deps: AgentsRouterDeps<TTransaction>) {\n const listHandler: RouteHandler<typeof listAgentsRoute> = async c => {\n const records = await deps.agentStore.listAgents(TENANT_ID);\n return c.json({ data: records.map(toWireAgent) }, 200);\n };\n\n const createHandler: RouteHandler<typeof createAgentRoute> = async c => {\n const body: CreateAgentRequest = c.req.valid('json');\n const manifest = await validateManifest({ spec: body.manifest, deps });\n try {\n const record = await deps.agentStore.createAgent({\n tenant_id: TENANT_ID,\n name: body.name,\n manifest,\n });\n return c.json({ data: toWireAgent(record) }, 201);\n } catch (error) {\n if (error instanceof AgentNameConflictError) {\n return c.json({ error: { message: error.message } }, 409);\n }\n throw error;\n }\n };\n\n const getHandler: RouteHandler<typeof getAgentRoute> = async c => {\n const { agent_id: agentId } = c.req.valid('param');\n const record = await deps.agentStore.getAgent({ tenant_id: TENANT_ID, id: agentId });\n if (record === undefined) {\n return c.json({ error: { message: `Agent not found: ${agentId}` } }, 404);\n }\n return c.json({ data: toWireAgent(record) }, 200);\n };\n\n const deleteHandler: RouteHandler<typeof deleteAgentRoute> = async c => {\n const { agent_id: agentId } = c.req.valid('param');\n await deps.agentStore.deleteAgent({ tenant_id: TENANT_ID, id: agentId });\n return c.json({}, 200);\n };\n\n const putHandler: RouteHandler<typeof putAgentRoute> = async c => {\n const { agent_id: agentId } = c.req.valid('param');\n const body = c.req.valid('json');\n const manifest = await validateManifest({ spec: body.manifest, deps });\n const record = await deps.agentStore.updateAgent({\n tenant_id: TENANT_ID,\n id: agentId,\n manifest,\n });\n if (record === undefined) {\n return c.json({ error: { message: `Agent not found: ${agentId}` } }, 404);\n }\n return c.json({ data: toWireAgent(record) }, 200);\n };\n\n const router = new OpenAPIHono();\n router.openapi(listAgentsRoute, listHandler);\n router.openapi(createAgentRoute, createHandler);\n router.openapi(getAgentRoute, getHandler);\n router.openapi(deleteAgentRoute, deleteHandler);\n router.openapi(putAgentRoute, putHandler);\n return router;\n}\n","/**\n * Agent registry route definitions (mounted at /api/v1/agents).\n * Handlers are registered in apis/agents.ts.\n */\nimport { createRoute, z } from '@hono/zod-openapi';\nimport {\n CreateAgentRequestSchema,\n DeleteAgentResponseSchema,\n GetAgentResponseSchema,\n ListAgentsResponseSchema,\n PutAgentRequestSchema,\n} from '../schemas/agent';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\n\nconst AGENTS_TAG = 'Agents';\n\nexport const AgentIdParamsSchema = z.object({\n agent_id: z.string().min(1).max(64).describe('Immutable agent identifier.'),\n});\n\nexport const listAgentsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [AGENTS_TAG],\n summary: 'List agents',\n description: 'All configured agents for the tenant.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListAgentsResponseSchema } },\n description: 'All configured agents.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n\nexport const createAgentRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [AGENTS_TAG],\n summary: 'Create an agent',\n description:\n 'Creates an agent and allocates an immutable id. Fails if `name` is already taken. Name cannot be changed later.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateAgentRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetAgentResponseSchema } },\n description: 'The created agent.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body or unknown model/MCP/skill refs.',\n },\n 409: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'An agent with this name already exists.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'The agent spec is valid but requires a capability this server does not provide (e.g. sandbox or skills).',\n },\n },\n});\n\nexport const getAgentRoute = createRoute({\n method: 'get',\n path: '/{agent_id}',\n tags: [AGENTS_TAG],\n summary: 'Get an agent',\n description: 'Fetch a configured agent by immutable id.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'get',\n request: {\n params: AgentIdParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetAgentResponseSchema } },\n description: 'The agent.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Agent not found.',\n },\n },\n});\n\nexport const deleteAgentRoute = createRoute({\n method: 'delete',\n path: '/{agent_id}',\n tags: [AGENTS_TAG],\n summary: 'Delete an agent',\n description: 'Delete a configured agent by immutable id. Idempotent if already gone.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'delete',\n request: {\n params: AgentIdParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: DeleteAgentResponseSchema } },\n description: 'Agent deleted.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n\nexport const putAgentRoute = createRoute({\n method: 'put',\n path: '/{agent_id}',\n tags: [AGENTS_TAG],\n summary: 'Update an agent',\n description: 'Replaces the manifest for an existing agent keyed by immutable `agent_id`.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'update',\n request: {\n params: AgentIdParamsSchema,\n body: {\n content: { 'application/json': { schema: PutAgentRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetAgentResponseSchema } },\n description: 'The saved agent.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body or unknown model/MCP/skill refs.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Agent not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'The agent spec is valid but requires a capability this server does not provide (e.g. sandbox or skills).',\n },\n },\n});\n","/**\n * Configured agent domain + wire schemas: identity columns plus a nested\n * AgentSpec document (JSON key `manifest`).\n */\nimport { z } from '@hono/zod-openapi';\nimport { AgentSpecSchema } from '@truefoundry/trueforge-core/agent-session';\nimport { NameSchema } from './common';\n\n/** Create body: unique immutable `name` plus manifest. `id` is never client-supplied. */\nexport const CreateAgentRequestSchema = z\n .object({\n name: NameSchema,\n manifest: AgentSpecSchema,\n })\n .strict()\n .openapi('CreateAgentRequest');\n\n/** PUT body: full manifest replacement. Identity is the path `agent_id`. */\nexport const PutAgentRequestSchema = z\n .object({\n manifest: AgentSpecSchema,\n })\n .strict()\n .openapi('PutAgentRequest');\n\n/** List/get/create/update response item: identity columns plus nested manifest. */\nexport const AgentSchema = z\n .object({\n id: z.string().min(1).describe('Immutable server-generated agent identifier.'),\n name: NameSchema,\n manifest: AgentSpecSchema,\n })\n .strict()\n .openapi('Agent');\n\nexport const GetAgentResponseSchema = z.object({ data: AgentSchema }).openapi('GetAgentResponse');\nexport const ListAgentsResponseSchema = z.object({ data: z.array(AgentSchema) }).openapi('ListAgentsResponse');\nexport const DeleteAgentResponseSchema = z.object({}).openapi('DeleteAgentResponse');\n\nexport type CreateAgentRequest = z.infer<typeof CreateAgentRequestSchema>;\nexport type PutAgentRequest = z.infer<typeof PutAgentRequestSchema>;\nexport type Agent = z.infer<typeof AgentSchema>;\n","/**\n * Server-wide shared Zod field schemas and refinements.\n */\nimport { z } from '@hono/zod-openapi';\n\n/**\n * Lowercase name, 2–64 chars: starts with a letter, ends with alphanumeric,\n * may contain \".\", \"_\" or \"-\" in between (aligned with SF model-integration names).\n */\nexport const NameSchema = z\n .string()\n .min(2)\n .max(64)\n .regex(\n /^[a-z](?:[a-z0-9._-]{0,62}[a-z0-9])$/,\n 'must be 2–64 lowercase chars: start with a letter, end with alphanumeric, optionally separated by \".\", \"_\" or \"-\"',\n )\n .openapi('ResourceName');\n\nexport type ResourceName = z.infer<typeof NameSchema>;\n\n/** Adds a validation issue if two entries share a name. */\nexport function uniqueNames(entries: { name: string }[], ctx: z.RefinementCtx): void {\n const seen = new Set<string>();\n for (const entry of entries) {\n if (seen.has(entry.name)) {\n ctx.addIssue({\n code: 'custom',\n message: `Duplicate name \"${entry.name}\" — names must be unique`,\n });\n }\n seen.add(entry.name);\n }\n}\n\n/** Adds a validation issue if two entries share a type. */\nexport function uniqueTypes(entries: { type: string }[], ctx: z.RefinementCtx): void {\n const seen = new Set<string>();\n for (const entry of entries) {\n if (seen.has(entry.type)) {\n ctx.addIssue({\n code: 'custom',\n message: `Duplicate type \"${entry.type}\" — types must be unique`,\n });\n }\n seen.add(entry.type);\n }\n}\n","/** Error response wire schema. */\nimport { z } from '@hono/zod-openapi';\n\nexport const RequestErrorResponseSchema = z\n .object({\n error: z.object({\n message: z.string().describe('Human-readable explanation of the failure.'),\n type: z.string().optional().describe('Optional error category (e.g. validation vs conflict).'),\n code: z\n .string()\n .nullable()\n .optional()\n .describe('Optional machine-readable error code; null when not applicable.'),\n param: z\n .string()\n .nullable()\n .optional()\n .describe('Optional request field that caused the error; null when not field-specific.'),\n }),\n })\n .openapi('RequestErrorResponse');\n\nexport type RequestErrorResponse = z.infer<typeof RequestErrorResponseSchema>;\n","/**\n * Store-backed model/MCP/skill/sandbox resolution for session admit and turns.\n */\nimport type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport {\n Sandbox,\n SkillMounter,\n type AgentTracing,\n type GitSkill,\n type ModelParams,\n type RemoteMcpHeaders,\n type SandboxProvider,\n type VercelAIProviderConfig,\n} from '@truefoundry/trueforge-core/core';\nimport { HTTPException } from 'hono/http-exception';\nimport type { Logger } from 'winston';\nimport configuration from '../config';\nimport type { IMcpServerStore, McpServerRecord } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport { isMcpAuthRequired, resolveMcpAuth } from '../mcp/auth/mcpDcr';\nimport type { IOAuthTokenStore } from '../mcp/auth/types';\nimport { toDaytonaSandboxProvider } from '../sandbox/providerUtils';\nimport { resolveConfiguredMcpRequestHeaders } from '../schemas/mcpServer';\n\nexport interface McpConnection {\n url: string;\n headers: RemoteMcpHeaders;\n}\n\n/** Split `provider/model` FQN. Returns undefined when the shape is not exactly one slash. */\nexport function parseModelFqn(name: string): { providerName: string; modelName: string } | undefined {\n const slash = name.indexOf('/');\n if (slash <= 0 || slash === name.length - 1) {\n return undefined;\n }\n if (name.includes('/', slash + 1)) {\n return undefined;\n }\n return { providerName: name.slice(0, slash), modelName: name.slice(slash + 1) };\n}\n\n/**\n * Load turn-ready model config and defaults for a configured FQN (`provider/model`).\n * Malformed FQN or missing provider/model → HTTPException(422).\n */\nexport async function getModelDetails({\n tenant_id,\n name,\n store,\n}: {\n tenant_id: string;\n name: string;\n store: IModelProviderStore;\n}): Promise<{\n providerConfig: VercelAIProviderConfig;\n defaultModelParams: ModelParams;\n}> {\n const parsed = parseModelFqn(name);\n if (parsed === undefined) {\n throw new HTTPException(422, {\n message: `Model name must be a fully qualified \"provider/model\": ${name}`,\n });\n }\n const provider = await store.getProvider({ tenant_id, name: parsed.providerName });\n if (provider === undefined) {\n throw new HTTPException(422, {\n message: `Unknown model \"${name}\" — provider not configured`,\n });\n }\n const model = provider.manifest.models.find(entry => entry.name === parsed.modelName);\n if (model === undefined) {\n throw new HTTPException(422, {\n message: `Unknown model \"${name}\" — not configured on provider`,\n });\n }\n // Provider types are adapter names, so this assignment is what keeps them so: a type with no\n // `buildLanguageModel` case fails to compile here.\n const { type, base_url } = provider.manifest;\n return {\n providerConfig: {\n provider: { type, name: provider.name },\n model: { id: model.model_id, name: model.name },\n name,\n baseUrl: base_url,\n // Custom providers may omit auth; adapters still require a string.\n apiKey: provider.manifest.auth?.api_key ?? '',\n headers: {},\n },\n defaultModelParams: model.properties.max_output_tokens ? { max_tokens: model.properties.max_output_tokens } : {},\n };\n}\n\nfunction dcrHeadersResolver(params: {\n record: McpServerRecord;\n tokenStore: IOAuthTokenStore;\n mcpServerStore: IMcpServerStore;\n clientName: string;\n userRef: string;\n}): RemoteMcpHeaders {\n const { record, tokenStore, mcpServerStore, clientName, userRef } = params;\n return async () => {\n const result = await resolveMcpAuth({\n tokenStore,\n mcpServerStore,\n serverId: record.id,\n userRef,\n mcpServerUrl: record.manifest.url,\n mcpServerName: record.name,\n clientName,\n });\n if (isMcpAuthRequired(result)) {\n // Wire `id` must match RemoteMCP.id (AgentSpec name), not the DB row ULID —\n // init events, tool-call metadata, and snapshots all key by name.\n return {\n authRequired: {\n servers: [{ id: record.name, name: record.name, auth_url: result.authUrl.href }],\n },\n };\n }\n return { headers: result.headers };\n };\n}\n\n/**\n * Load MCP url + headers for a configured server.\n * DCR uses resolveMcpAuth; header / no-auth use resolveConfiguredMcpRequestHeaders.\n * Returns undefined when the server is not registered — callers choose the response.\n */\nexport async function getMcpConnection({\n tenant_id,\n name,\n store,\n tokenStore,\n clientName,\n userRef,\n}: {\n tenant_id: string;\n name: string;\n store: IMcpServerStore;\n tokenStore: IOAuthTokenStore;\n clientName: string;\n userRef: string;\n}): Promise<McpConnection | undefined> {\n const record = await store.getServer({ tenant_id, name });\n if (record === undefined) {\n return undefined;\n }\n if (record.manifest.auth?.type === 'dcr') {\n return {\n url: record.manifest.url,\n headers: dcrHeadersResolver({\n record,\n tokenStore,\n mcpServerStore: store,\n clientName,\n userRef,\n }),\n };\n }\n return {\n url: record.manifest.url,\n headers: resolveConfiguredMcpRequestHeaders(record.manifest),\n };\n}\n\n/**\n * Expand agent_spec skill names into git mounts from the skill store.\n * Wire url/path/ref/description on the request are ignored — the store row wins.\n * Throws HTTPException(422) if any name is not registered.\n */\nexport async function resolveGitSkills({\n tenant_id,\n skills,\n store,\n}: {\n tenant_id: string;\n skills: readonly { name: string }[];\n store: ISkillStore;\n}): Promise<GitSkill[]> {\n if (skills.length === 0) {\n return [];\n }\n const names = skills.map(skill => skill.name);\n const records = await store.listSkills({ tenant_id, names });\n const byName = new Map(records.map(record => [record.name, record]));\n const resolved: GitSkill[] = [];\n for (const skill of skills) {\n const record = byName.get(skill.name);\n if (record === undefined) {\n throw new HTTPException(422, {\n message: `Unknown skill \"${skill.name}\" — not configured`,\n });\n }\n resolved.push({\n name: record.manifest.name,\n description: record.manifest.description,\n url: record.manifest.url,\n path: record.manifest.path ?? '',\n ref: record.manifest.ref,\n });\n }\n return resolved;\n}\n\n/**\n * Build a runtime SandboxProvider from the configured store row, or undefined\n * when no provider is configured. Builds a fresh Daytona client per call (no network I/O).\n */\nexport async function resolveSandboxProvider({\n tenant_id,\n store,\n logger,\n}: {\n tenant_id: string;\n store: ISandboxProviderStore;\n logger: Logger;\n}): Promise<SandboxProvider | undefined> {\n const record = await store.getSandboxProvider(tenant_id);\n if (record === undefined) {\n return undefined;\n }\n // Clone from the snapshot that was actually built (persisted build_ref), not a name\n // derived from the current image — otherwise an image bump breaks creation until rebuild.\n return toDaytonaSandboxProvider({\n manifest: record.manifest,\n tenant_id,\n logger,\n build_metadata: record.build_metadata,\n });\n}\n\n/**\n * Builds a Sandbox for one turn from a resolved provider and git mounts.\n * `tenantName` must match the name given to DaytonaSandboxProvider (ownership check).\n */\nexport function buildTurnSandbox(input: {\n provider: SandboxProvider;\n logger: Logger;\n gitSkills: readonly GitSkill[];\n fileDownloadEnabled: boolean;\n existingSandboxId?: string | undefined;\n tracing: AgentTracing;\n tenantName: string;\n}): Sandbox {\n const skillMounter = input.gitSkills.length > 0 ? new SkillMounter([...input.gitSkills]) : undefined;\n return new Sandbox({\n provider: input.provider,\n existingSandboxId: input.existingSandboxId,\n fileDownloadEnabled: input.fileDownloadEnabled,\n blockDestructiveToolsInCodeMode: true,\n mcpRequestTimeoutMs: configuration.MCP_REQUEST_TIMEOUT_MS,\n mcpConnectTimeoutMs: configuration.MCP_CONNECT_TIMEOUT_MS,\n // Sandbox reads its tenant from TFY_TENANT_NAME for the ownership check\n // against provider-created sandbox ids (`<tenant>.<uuid>`).\n execExtraEnv: { TFY_TENANT_NAME: input.tenantName },\n ...(skillMounter ? { skillMounter } : {}),\n tracing: input.tracing,\n logger: input.logger,\n });\n}\n\n/**\n * Cross-checks an AgentSpec against configured models / MCP / skills and\n * sandbox capability. Throws HTTPException(422) for semantic failures.\n * Skills are admitted by name only; mounts expand at turn time.\n */\nexport async function validateAgentSpec({\n spec,\n tenant_id,\n modelProviderStore,\n mcpServerStore,\n skillStore,\n sandboxProviderStore,\n}: {\n spec: AgentSpec;\n tenant_id: string;\n modelProviderStore: IModelProviderStore;\n mcpServerStore: IMcpServerStore;\n skillStore: ISkillStore;\n sandboxProviderStore: ISandboxProviderStore;\n}): Promise<void> {\n const parsed = parseModelFqn(spec.model.name);\n if (parsed === undefined) {\n throw new HTTPException(422, {\n message: `Model name must be a fully qualified \"provider/model\": ${spec.model.name}`,\n });\n }\n const provider = await modelProviderStore.getProvider({ tenant_id, name: parsed.providerName });\n if (provider === undefined) {\n throw new HTTPException(422, {\n message: `Unknown model \"${spec.model.name}\" — provider not configured`,\n });\n }\n const model = provider.manifest.models.find(entry => entry.name === parsed.modelName);\n if (model === undefined) {\n throw new HTTPException(422, {\n message: `Unknown model \"${spec.model.name}\" — not configured on provider`,\n });\n }\n const reasoningEffort = spec.model.params?.reasoning_effort;\n if (reasoningEffort !== undefined) {\n const efforts = model.properties.reasoning_efforts;\n if (!efforts?.some(effort => effort === reasoningEffort)) {\n throw new HTTPException(422, {\n message: efforts\n ? `Reasoning effort \"${reasoningEffort}\" is not supported by model \"${spec.model.name}\"`\n : `Model \"${spec.model.name}\" does not support configurable reasoning effort`,\n });\n }\n }\n\n const requestedMcpServers = spec.mcp_servers ?? [];\n if (requestedMcpServers.length > 0) {\n const names = requestedMcpServers.map(server => server.name);\n const configuredNames = new Set(\n (await mcpServerStore.listServers({ tenant_id, names })).map(record => record.name),\n );\n const unknown = requestedMcpServers.find(server => !configuredNames.has(server.name));\n if (unknown !== undefined) {\n throw new HTTPException(422, {\n message: `Unknown MCP server \"${unknown.name}\" — not configured`,\n });\n }\n }\n\n const requestedSkills = spec.skills ?? [];\n if (requestedSkills.length > 0) {\n const names = requestedSkills.map(skill => skill.name);\n const configuredNames = new Set((await skillStore.listSkills({ tenant_id, names })).map(record => record.name));\n const unknown = requestedSkills.find(skill => !configuredNames.has(skill.name));\n if (unknown !== undefined) {\n throw new HTTPException(422, {\n message: `Unknown skill \"${unknown.name}\" — not configured`,\n });\n }\n }\n\n const wantsSandbox = spec.config.sandbox.enabled;\n const hasSkills = requestedSkills.length > 0;\n if (wantsSandbox || hasSkills) {\n const record = await sandboxProviderStore.getSandboxProvider(tenant_id);\n if (record === undefined) {\n throw new HTTPException(422, {\n message: hasSkills\n ? 'skills require a sandbox provider — configure via PUT /settings/sandbox-providers'\n : 'sandbox is enabled but no sandbox provider is configured — PUT /settings/sandbox-providers',\n });\n }\n }\n}\n","import {\n discoverOAuthServerInfo,\n exchangeAuthorization,\n refreshAuthorization,\n registerClient,\n startAuthorization,\n} from '@modelcontextprotocol/sdk/client/auth.js';\nimport { InvalidClientError, InvalidClientMetadataError } from '@modelcontextprotocol/sdk/server/auth/errors.js';\nimport { resourceUrlFromServerUrl } from '@modelcontextprotocol/sdk/shared/auth-utils.js';\nimport type {\n AuthorizationServerMetadata,\n OAuthClientMetadata,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/shared/auth.js';\nimport type { FetchLike } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport { McpConnectionError, McpDcrConfigurationError } from '@truefoundry/trueforge-core/core';\nimport { randomBytes } from 'node:crypto';\nimport {\n isOAuthAccessTokenUsable,\n mcpAuthorizationServerMetadata,\n mcpAuthorizationServerOrigin,\n mcpClientInformation,\n mcpOAuthCallbackUrl,\n oauthTokensToOAuthToken,\n} from './mcpOAuthHelpers';\nimport type {\n IOAuthClientStore,\n IOAuthTokenStore,\n McpAuthRequiredResult,\n OAuthClientRecord,\n OAuthPendingAuthorization,\n ResolveMcpAuthResult,\n} from './types';\n\n/** Per-request timeout for MCP OAuth discovery, DCR, and token HTTP calls. */\nexport const MCP_OAUTH_HTTP_TIMEOUT_MS = 15_000;\n\n/**\n * Abort hung authorization-server HTTP. Merges with any caller `signal` so both can cancel the request.\n * Used by discoverOAuthServerInfo / registerClient / refreshAuthorization / exchangeAuthorization\n * (startAuthorization is local PKCE + URL construction and never calls this).\n */\nconst mcpOAuthFetch: FetchLike = (url, init) => {\n const timeoutSignal = AbortSignal.timeout(MCP_OAUTH_HTTP_TIMEOUT_MS);\n const signal = init?.signal != null ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n return fetch(url, { ...init, signal });\n};\n\nfunction isTimeoutError(error: unknown): boolean {\n return error instanceof Error && error.name === 'TimeoutError';\n}\n\n/** Same status as non-timeout faults; appends a timeout note so the API body is actionable. */\nfunction mcpOAuthConnectionError(message: string, error: unknown, statusCode: number): McpConnectionError {\n let body = message;\n if (isTimeoutError(error)) {\n body = `${message}: timed out after ${String(MCP_OAUTH_HTTP_TIMEOUT_MS / 1000)}s waiting for the authorization server`;\n }\n return new McpConnectionError(body, statusCode, { cause: error });\n}\n\nexport function isMcpAuthRequired(result: ResolveMcpAuthResult): result is McpAuthRequiredResult {\n return 'authUrl' in result;\n}\n\nasync function registerMcpClientWithAuthMethodFallback(params: {\n authorizationServerUrl: string;\n metadata: AuthorizationServerMetadata;\n clientMetadata: OAuthClientMetadata;\n mcpServerName: string;\n authorizationEndpoint: string;\n tokenEndpoint: string;\n}): Promise<OAuthClientRecord> {\n const { authorizationServerUrl, metadata, clientMetadata, mcpServerName, authorizationEndpoint, tokenEndpoint } =\n params;\n let fullInfo;\n try {\n fullInfo = await registerClient(authorizationServerUrl, {\n metadata,\n clientMetadata: { ...clientMetadata, token_endpoint_auth_method: 'client_secret_post' },\n fetchFn: mcpOAuthFetch,\n });\n } catch (firstError: unknown) {\n if (!(firstError instanceof InvalidClientMetadataError)) {\n throw mcpOAuthConnectionError(\n `Failed to dynamically register OAuth client for MCP server '${mcpServerName}'`,\n firstError,\n 424,\n );\n }\n try {\n fullInfo = await registerClient(authorizationServerUrl, {\n metadata,\n clientMetadata,\n fetchFn: mcpOAuthFetch,\n });\n } catch (secondError: unknown) {\n throw mcpOAuthConnectionError(\n `Failed to dynamically register OAuth client for MCP server '${mcpServerName}'`,\n secondError,\n 424,\n );\n }\n }\n if (!fullInfo.client_id) {\n throw new McpConnectionError(\n `Authorization server for MCP server '${mcpServerName}' returned a client response without client_id`,\n 424,\n );\n }\n return {\n server: {\n authorizationEndpoint,\n tokenEndpoint,\n codeChallengeMethodsSupported: metadata.code_challenge_methods_supported ?? null,\n },\n client: {\n clientId: fullInfo.client_id,\n clientSecret: fullInfo.client_secret ?? null,\n },\n };\n}\n\n/**\n * Discovers the MCP server's authorization server, validates DCR + S256 PKCE support, and\n * registers a new OAuth client (RFC 7591). Returns AS endpoints + client credentials for the\n * caller to persist; does not write to the store.\n */\nexport async function createMcpOAuthClient(params: {\n mcpServerUrl: string;\n mcpServerName: string;\n redirectUri: string;\n clientName: string;\n}): Promise<OAuthClientRecord> {\n const { mcpServerUrl, mcpServerName, redirectUri, clientName } = params;\n let discovered: Awaited<ReturnType<typeof discoverOAuthServerInfo>>;\n try {\n discovered = await discoverOAuthServerInfo(mcpServerUrl, { fetchFn: mcpOAuthFetch });\n } catch (error: unknown) {\n throw mcpOAuthConnectionError(\n `Failed to discover OAuth authorization server for MCP server '${mcpServerName}'`,\n error,\n 424,\n );\n }\n const { authorizationServerUrl, authorizationServerMetadata: metadata } = discovered;\n if (!metadata?.registration_endpoint) {\n throw new McpDcrConfigurationError(\n `MCP server '${mcpServerName}' has no DCR support (missing registration_endpoint); auth.type: dcr is misconfigured for this server`,\n );\n }\n if (!metadata.authorization_endpoint || !metadata.token_endpoint) {\n throw new McpDcrConfigurationError(\n `Authorization server for MCP server '${mcpServerName}' is missing authorization_endpoint or token_endpoint`,\n );\n }\n const pkceMethods = metadata.code_challenge_methods_supported;\n if (pkceMethods && !pkceMethods.includes('S256')) {\n throw new McpDcrConfigurationError(\n `Authorization server for MCP server '${mcpServerName}' advertises PKCE methods without S256`,\n );\n }\n return registerMcpClientWithAuthMethodFallback({\n authorizationServerUrl,\n metadata,\n clientMetadata: {\n client_name: clientName,\n redirect_uris: [redirectUri],\n grant_types: ['authorization_code', 'refresh_token'],\n response_types: ['code'],\n },\n mcpServerName,\n authorizationEndpoint: metadata.authorization_endpoint,\n tokenEndpoint: metadata.token_endpoint,\n });\n}\n\n/**\n * Returns the stored OAuth client for `serverId`, or discovers + DCR-registers and persists one.\n * Used from `resolveMcpAuth` only — callers that already hold the client should pass it through.\n */\nexport async function ensureMcpClientRegistered(params: {\n mcpServerStore: IOAuthClientStore;\n serverId: string;\n mcpServerUrl: string;\n mcpServerName: string;\n clientName: string;\n}): Promise<OAuthClientRecord> {\n const existing = await params.mcpServerStore.getClient({ id: params.serverId });\n if (existing) {\n return existing;\n }\n const client = await createMcpOAuthClient({\n mcpServerUrl: params.mcpServerUrl,\n mcpServerName: params.mcpServerName,\n redirectUri: mcpOAuthCallbackUrl(),\n clientName: params.clientName,\n });\n await params.mcpServerStore.saveClient({ id: params.serverId, record: client });\n return client;\n}\n\n/** Builds the AS authorize URL and saves the pending PKCE row. Caller must already have `client`. */\nexport async function buildMcpAuthorizationUrl(params: {\n tokenStore: IOAuthTokenStore;\n client: OAuthClientRecord;\n serverId: string;\n userRef: string;\n mcpServerUrl: string;\n mcpServerName: string;\n redirectUrl?: string;\n}): Promise<URL> {\n const state = randomBytes(32).toString('base64url');\n const redirectUri = mcpOAuthCallbackUrl();\n let started: Awaited<ReturnType<typeof startAuthorization>>;\n try {\n started = await startAuthorization(mcpAuthorizationServerOrigin(params.client.server), {\n metadata: mcpAuthorizationServerMetadata(params.client.server),\n clientInformation: mcpClientInformation(params.client.client),\n redirectUrl: redirectUri,\n resource: resourceUrlFromServerUrl(params.mcpServerUrl),\n state,\n });\n } catch (error: unknown) {\n throw new McpConnectionError(`Failed to start OAuth authorization for MCP server '${params.mcpServerName}'`, 424, {\n cause: error,\n });\n }\n await params.tokenStore.savePendingAuthorization({\n state,\n id: params.serverId,\n userRef: params.userRef,\n mcpServerUrl: params.mcpServerUrl,\n codeVerifier: started.codeVerifier,\n redirectUrl: params.redirectUrl ?? null,\n });\n return started.authorizationUrl;\n}\n\nexport async function resolveMcpAuth(params: {\n tokenStore: IOAuthTokenStore;\n mcpServerStore: IOAuthClientStore;\n serverId: string;\n userRef: string;\n mcpServerUrl: string;\n mcpServerName: string;\n clientName: string;\n redirectUrl?: string;\n}): Promise<ResolveMcpAuthResult> {\n const nowMs = Date.now();\n const tokenKey = { id: params.serverId, userRef: params.userRef };\n const token = await params.tokenStore.getToken(tokenKey);\n if (token && isOAuthAccessTokenUsable(token.expiresAt, nowMs)) {\n return { headers: { Authorization: `Bearer ${token.accessToken}` } };\n }\n const client = await ensureMcpClientRegistered({\n mcpServerStore: params.mcpServerStore,\n serverId: params.serverId,\n mcpServerUrl: params.mcpServerUrl,\n mcpServerName: params.mcpServerName,\n clientName: params.clientName,\n });\n if (token?.refreshToken) {\n try {\n const refreshed = await refreshAuthorization(mcpAuthorizationServerOrigin(client.server), {\n metadata: mcpAuthorizationServerMetadata(client.server),\n clientInformation: mcpClientInformation(client.client),\n refreshToken: token.refreshToken,\n resource: resourceUrlFromServerUrl(params.mcpServerUrl),\n fetchFn: mcpOAuthFetch,\n });\n const saved = oauthTokensToOAuthToken(refreshed, nowMs, token.refreshToken);\n await params.tokenStore.saveToken({ ...tokenKey, token: saved });\n return { headers: { Authorization: `Bearer ${saved.accessToken}` } };\n } catch {\n // Refresh failure falls through to a fresh authorization.\n }\n }\n if (token) {\n await params.tokenStore.deleteToken(tokenKey);\n }\n const authUrl = await buildMcpAuthorizationUrl({\n tokenStore: params.tokenStore,\n client,\n serverId: params.serverId,\n userRef: params.userRef,\n mcpServerUrl: params.mcpServerUrl,\n mcpServerName: params.mcpServerName,\n ...(params.redirectUrl !== undefined ? { redirectUrl: params.redirectUrl } : {}),\n });\n return { authUrl };\n}\n\n/**\n * Exchanges `code` for tokens against an already-claimed `pending` row: the caller claims it with\n * `consumePendingAuthorization` so duplicate callbacks lose the race, and keeps it for its FE\n * landing URL. Route must already reject IdP `error` params. On `invalid_client`, clears the stored\n * client so the next authorize re-registers (per-user tokens are left; there is usually none yet).\n */\nexport async function completeMcpAuthorization<TTransaction>(params: {\n tokenStore: IOAuthTokenStore<TTransaction>;\n mcpServerStore: IOAuthClientStore<TTransaction>;\n pending: OAuthPendingAuthorization;\n code: string;\n}): Promise<void> {\n const nowMs = Date.now();\n const { pending } = params;\n\n const client = await params.mcpServerStore.getClient({ id: pending.id });\n if (!client) {\n throw new McpConnectionError(\n `No OAuth client registered for MCP server id '${pending.id}'; re-run authorize first`,\n 400,\n );\n }\n if (pending.codeVerifier === null) {\n throw new McpConnectionError('Pending authorization is missing PKCE code_verifier; re-run authorize', 400);\n }\n let tokens: OAuthTokens;\n try {\n tokens = await exchangeAuthorization(mcpAuthorizationServerOrigin(client.server), {\n metadata: mcpAuthorizationServerMetadata(client.server),\n clientInformation: mcpClientInformation(client.client),\n authorizationCode: params.code,\n codeVerifier: pending.codeVerifier,\n redirectUri: mcpOAuthCallbackUrl(),\n resource: resourceUrlFromServerUrl(pending.mcpServerUrl),\n fetchFn: mcpOAuthFetch,\n });\n } catch (error: unknown) {\n if (error instanceof InvalidClientError) {\n await params.mcpServerStore.deleteClient({ id: pending.id });\n throw new McpConnectionError('OAuth client registration is invalid; please retry connecting', 400, {\n cause: error,\n });\n }\n throw mcpOAuthConnectionError('OAuth token exchange failed', error, 400);\n }\n await params.tokenStore.saveToken({\n id: pending.id,\n userRef: pending.userRef,\n token: oauthTokensToOAuthToken(tokens, nowMs, null),\n });\n}\n","import type {\n AuthorizationServerMetadata,\n OAuthClientInformationMixed,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/shared/auth.js';\nimport { McpConnectionError } from '@truefoundry/trueforge-core/core';\nimport { getPublicBaseUrl } from '../../config';\nimport type { OAuthClientCredentials, OAuthServerMetadata, OAuthToken } from './types';\n\n/** Fixed OAuth callback path for every MCP server. */\nexport const MCP_OAUTH_CALLBACK_PATH = '/api/v1/mcp-servers/oauth/callback';\n\n/** Fallback TTL when an RFC 6749 token response omits `expires_in`. */\nexport const DEFAULT_MCP_ACCESS_TOKEN_TTL_SECONDS = 3600;\n\n/** Builds the server-owned MCP OAuth callback URL. */\nexport function mcpOAuthCallbackUrl(): string {\n try {\n const publicBaseUrl = getPublicBaseUrl();\n return `${publicBaseUrl}${MCP_OAUTH_CALLBACK_PATH}`;\n } catch (error) {\n throw new McpConnectionError('PUBLIC_BASE_URL is required for MCP OAuth registration but was empty', 500, {\n cause: error,\n });\n }\n}\n\n/** Uses form-body client authentication when a secret is present. */\nexport function mcpClientInformation(client: OAuthClientCredentials): OAuthClientInformationMixed {\n return client.clientSecret !== null\n ? {\n client_id: client.clientId,\n client_secret: client.clientSecret,\n token_endpoint_auth_method: 'client_secret_post',\n }\n : {\n client_id: client.clientId,\n token_endpoint_auth_method: 'none',\n };\n}\n\n/** Reconstructs the metadata required by the MCP SDK authorization helpers. */\nexport function mcpAuthorizationServerMetadata(server: OAuthServerMetadata): AuthorizationServerMetadata {\n return {\n issuer: new URL(server.authorizationEndpoint).origin,\n authorization_endpoint: server.authorizationEndpoint,\n token_endpoint: server.tokenEndpoint,\n response_types_supported: ['code'],\n ...(server.codeChallengeMethodsSupported !== null\n ? { code_challenge_methods_supported: server.codeChallengeMethodsSupported }\n : {}),\n };\n}\n\nexport function mcpAuthorizationServerOrigin(server: OAuthServerMetadata): string {\n return new URL(server.authorizationEndpoint).origin;\n}\n\nexport function oauthTokensToOAuthToken(\n tokens: OAuthTokens,\n nowMs: number,\n fallbackRefreshToken: string | null,\n): OAuthToken {\n const expiresInSeconds = tokens.expires_in ?? DEFAULT_MCP_ACCESS_TOKEN_TTL_SECONDS;\n return {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? fallbackRefreshToken,\n expiresAt: new Date(nowMs + expiresInSeconds * 1000).toISOString(),\n scope: tokens.scope ?? null,\n };\n}\n\n/** True when the expiry parses and is strictly in the future. */\nexport function isOAuthAccessTokenUsable(expiresAtIso: string, nowMs: number): boolean {\n const expiresAtMs = Date.parse(expiresAtIso);\n return !Number.isNaN(expiresAtMs) && expiresAtMs > nowMs;\n}\n\n/** Validates redirect URLs parse as HTTP(S). */\nexport function validateRedirectUris({ redirectUris }: { redirectUris: string[] }): void {\n for (const redirectUri of redirectUris) {\n let parsed: URL;\n try {\n parsed = new URL(redirectUri);\n } catch (error) {\n throw new McpConnectionError(`Invalid redirect URI: ${redirectUri}. Must be a valid URL.`, 400, { cause: error });\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new McpConnectionError(`Invalid redirect URI: ${redirectUri}. Must be a valid URL.`, 400);\n }\n }\n}\n","/** Daytona provider construction + persisted build-status refresh (see checkSnapshotStatus). */\nimport { Daytona, DaytonaError } from '@daytona/sdk';\nimport { DaytonaSandboxProvider, SANDBOX_IMAGE_URI, type SandboxBuild } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport configuration from '../config';\nimport type { ISandboxProviderStore, SandboxProviderRecord } from '../db/sandboxProviderStore';\nimport {\n toDaytonaSandboxProviderInput,\n type SandboxBuildMetadata,\n type SandboxProviderManifest,\n type SandboxStatus,\n} from '../schemas/sandboxProvider';\n\n/** Daytona rejected the credentials (401 unauthorized / 403 forbidden); retrying the same key cannot succeed. */\nexport function isDaytonaAuthError(error: unknown): boolean {\n return error instanceof DaytonaError && (error.statusCode === 401 || error.statusCode === 403);\n}\n\n/**\n * Builds the runtime provider for a stored manifest. No network I/O until a method is called.\n *\n * When `build_metadata` is present, pin both `sandboxImage` and `buildRef` to what was actually\n * built — image bumps in the running binary must not rewrite an existing tenant onto a new\n * snapshot (upgrades are not supported yet). First-time configure omits metadata and uses\n * {@link SANDBOX_IMAGE_URI}.\n */\nexport function toDaytonaSandboxProvider({\n manifest,\n tenant_id,\n logger,\n build_metadata,\n}: {\n manifest: SandboxProviderManifest;\n tenant_id: string;\n logger: Logger;\n build_metadata?: SandboxBuildMetadata | null;\n}): DaytonaSandboxProvider {\n const { apiKey, ...settings } = toDaytonaSandboxProviderInput(manifest);\n return new DaytonaSandboxProvider({\n client: new Daytona({ apiKey }),\n apiKey,\n ...settings,\n tenantName: tenant_id,\n sandboxImage: build_metadata?.['image_uri'] ?? SANDBOX_IMAGE_URI,\n buildRef: build_metadata?.['build_ref'],\n fileMaxBytesForDownload: configuration.SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD,\n logger,\n });\n}\n\n/** Maps a core `SandboxBuild` onto the persisted/wire status shape (metadata passes through). */\nexport function toSandboxStatus(build: SandboxBuild): SandboxStatus {\n return {\n status: build.status,\n status_reason: build.reason,\n build_metadata: build.metadata,\n };\n}\n\nfunction sandboxStatusFromRecord(record: SandboxProviderRecord): SandboxStatus {\n return {\n status: record.status,\n status_reason: record.status_reason,\n build_metadata: record.build_metadata,\n };\n}\n\n// Daytona deactivates idle snapshots after 14 days; revalidate at 13 to stay a day ahead.\nconst READY_REVALIDATE_INTERVAL_MS = 13 * 24 * 60 * 60 * 1000;\n\nexport async function checkSnapshotStatus({\n store,\n tenant_id,\n logger,\n}: {\n store: ISandboxProviderStore;\n tenant_id: string;\n logger: Logger;\n}): Promise<SandboxStatus | undefined> {\n const record = await store.getSandboxProvider(tenant_id);\n if (!record) {\n return undefined;\n }\n\n const persisted = sandboxStatusFromRecord(record);\n\n const readyIsFresh =\n record.status === 'ready' && Date.now() - Date.parse(record.updated_at) < READY_REVALIDATE_INTERVAL_MS;\n if (record.status === 'failed' || readyIsFresh) {\n return persisted;\n }\n\n const provider = toDaytonaSandboxProvider({\n manifest: record.manifest,\n tenant_id,\n logger,\n build_metadata: record.build_metadata,\n });\n let build: SandboxBuild;\n if (record.status === 'ready') {\n // this is because image may have deactivated\n build = await provider.buildImage();\n } else {\n build = await provider.getImageBuildStatus();\n }\n const next = toSandboxStatus(build);\n const updated = await store.updateSandboxStatus({ tenant_id, ...next });\n return updated ? sandboxStatusFromRecord(updated) : next;\n}\n","/**\n * Sandbox-provider domain + wire schemas: configured provider jsonb and OpenAPI\n * request/response shapes. Catalog file schemas live in sandboxCatalog.ts.\n *\n * Singleton per tenant — no identity `name` (unlike model providers / skills).\n */\nimport { z } from '@hono/zod-openapi';\nimport type { DaytonaSandboxProviderOptions } from '@truefoundry/trueforge-core/core';\n\nconst DaytonaSandboxProviderAuthSchema = z\n .object({\n api_key: z\n .string()\n .min(1)\n .describe(\n 'Daytona API key. Responses are redacted; on PUT, a real value sets/rotates and a redacted value keeps the stored key.',\n ),\n })\n .strict()\n .describe('Daytona authentication credentials.')\n .openapi('DaytonaSandboxProviderAuth');\n\n/**\n * Daytona-backed sandbox provider config. Persisted as `sandbox_provider.manifest`.\n * Left unnamed for OpenAPI so `SandboxProviderManifest` (its single-variant alias)\n * is the one emitted component and the response `manifest` field is a plain `$ref`\n * instead of an `allOf` wrapper.\n */\nexport const DaytonaSandboxProviderSchema = z\n .object({\n type: z.literal('daytona').describe('Daytona sandbox provider.'),\n auth: DaytonaSandboxProviderAuthSchema,\n exec_timeout_ms: z.number().int().positive().describe('Default sandbox command exec timeout in milliseconds.'),\n auto_stop_interval_in_minutes: z\n .number()\n .int()\n .nonnegative()\n .describe('Minutes of idle time before Daytona auto-stops the sandbox (0 disables).'),\n auto_archive_interval_in_minutes: z\n .number()\n .int()\n .nonnegative()\n .describe('Minutes before Daytona auto-archives the sandbox (0 disables).'),\n auto_delete_interval_in_minutes: z\n .number()\n .int()\n .nonnegative()\n .describe('Minutes before Daytona auto-deletes the sandbox (0 disables).'),\n })\n .strict();\n\n/**\n * Persisted jsonb: the provider config only (no build status). Single variant today —\n * this alias carries the OpenAPI name so the spec emits one `SandboxProviderManifest` component.\n * Widen to `z.discriminatedUnion('type', [...])` when a second provider ships.\n */\nexport const SandboxProviderManifestSchema = DaytonaSandboxProviderSchema.openapi('SandboxProviderManifest');\n\n/** Named enum so the generated SDK exposes a reusable `SandboxBuildStatus` type. */\nexport const SandboxBuildStatusSchema = z\n .enum(['pending', 'ready', 'failed'])\n .describe('Current build status.')\n .openapi('SandboxBuildStatus');\n\n/** Provider-specific opaque build metadata (string map), persisted alongside the status — not on the wire. */\nexport const SandboxBuildMetadataSchema = z\n .record(z.string(), z.string())\n .describe('Provider-specific build metadata (opaque string map).');\n\n/** Build status persisted and refreshed on read (includes opaque metadata for the provider). */\nexport const SandboxStatusSchema = z\n .object({\n status: SandboxBuildStatusSchema,\n status_reason: z.string().nullable().describe('Human-readable detail for the current status; null when ready.'),\n build_metadata: SandboxBuildMetadataSchema.nullable().describe(\n 'Provider-specific build metadata; null when the provider has none.',\n ),\n })\n .strict();\n\n/** Settings wire item: nested manifest plus build status (no build_metadata). */\nexport const SandboxProviderSchema = z\n .object({\n manifest: SandboxProviderManifestSchema,\n status: SandboxBuildStatusSchema,\n status_reason: z.string().nullable().describe('Human-readable detail for the current status; null when ready.'),\n })\n .strict()\n .openapi('SandboxProvider');\n\nexport const PutSandboxProviderRequestSchema = z\n .object({\n manifest: SandboxProviderManifestSchema,\n })\n .strict()\n .openapi('PutSandboxProviderRequest');\n\nexport const GetSandboxProviderResponseSchema = z\n .object({\n data: SandboxProviderSchema,\n })\n .openapi('GetSandboxProviderResponse');\n\n/** Persisted jsonb — the provider config only (no build status). */\nexport type SandboxProviderManifest = z.infer<typeof SandboxProviderManifestSchema>;\nexport type DaytonaSandboxProvider = z.infer<typeof DaytonaSandboxProviderSchema>;\nexport type SandboxBuildStatus = z.infer<typeof SandboxBuildStatusSchema>;\nexport type SandboxBuildMetadata = z.infer<typeof SandboxBuildMetadataSchema>;\nexport type SandboxStatus = z.infer<typeof SandboxStatusSchema>;\nexport type SandboxProvider = z.infer<typeof SandboxProviderSchema>;\nexport type PutSandboxProviderRequest = z.infer<typeof PutSandboxProviderRequestSchema>;\n\n/** Wire/persisted snake_case → Daytona client credentials + provider settings. */\nexport function toDaytonaSandboxProviderInput(manifest: SandboxProviderManifest): {\n apiKey: string;\n} & Pick<\n DaytonaSandboxProviderOptions,\n 'timeoutMs' | 'autoStopIntervalInMinutes' | 'autoArchiveIntervalInMinutes' | 'autoDeleteIntervalInMinutes'\n> {\n return {\n apiKey: manifest.auth.api_key,\n timeoutMs: manifest.exec_timeout_ms,\n autoStopIntervalInMinutes: manifest.auto_stop_interval_in_minutes,\n autoArchiveIntervalInMinutes: manifest.auto_archive_interval_in_minutes,\n autoDeleteIntervalInMinutes: manifest.auto_delete_interval_in_minutes,\n };\n}\n","/**\n * Configured MCP server domain + wire schemas: the `mcp_server.manifest` JSONB\n * document, admin/chat list projections, and auth_status. Catalog file schemas\n * live in mcpCatalog.ts.\n *\n * Auth: `header` stores shared request headers on the row (settings listTools);\n * turn execution resolves DCR tokens via resolveMcpAuth.\n */\nimport { z } from '@hono/zod-openapi';\nimport type { OAuthToken } from '../mcp/auth/types';\nimport { NameSchema } from './common';\n\n/** Transport/kind of MCP server. Extend when non-remote kinds ship. */\nexport const McpServerTypeSchema = z.enum(['remote']).openapi('McpServerType');\n\nconst McpServerHeaderAuthSchema = z\n .object({\n type: z.literal('header').describe('Authenticate with static HTTP headers.'),\n headers: z\n .record(z.string().min(1), z.string().min(1))\n .refine(headers => Object.keys(headers).length > 0, {\n message: 'must include at least one header',\n })\n .describe(\n 'Request headers for this MCP server. Responses are redacted; on PUT, a real value sets/rotates and a redacted value keeps the stored secret for that header name.',\n ),\n })\n .strict()\n .openapi('McpServerHeaderAuth');\n\n/** OAuth Dynamic Client Registration — stub until authorize/token exchange is wired. */\nconst McpServerDcrAuthSchema = z\n .object({\n type: z.literal('dcr').describe('Authenticate via OAuth Dynamic Client Registration.'),\n })\n .strict()\n .openapi('McpServerDcrAuth');\n\nexport const McpServerManifestAuthSchema = z\n .discriminatedUnion('type', [McpServerHeaderAuthSchema, McpServerDcrAuthSchema])\n .describe('Optional auth settings. Omit when the server needs no credentials.')\n .openapi('McpServerManifestAuth');\n\nexport const McpServerDescriptionSchema = z\n .string()\n .trim()\n .min(1)\n .describe('Concise summary of what this MCP server provides.');\n\n/** Configured MCP server document persisted as `mcp_server.manifest`. */\nexport const McpServerManifestObjectSchema = z\n .object({\n type: McpServerTypeSchema,\n name: NameSchema,\n url: z.url().describe('URL of the remote MCP server.'),\n description: McpServerDescriptionSchema,\n auth: McpServerManifestAuthSchema.optional(),\n })\n .strict();\n\nexport const McpServerManifestSchema = McpServerManifestObjectSchema.openapi('McpServerManifest');\n\nexport const McpAuthStatusSchema = z\n .object({\n status: z\n .enum(['authenticated', 'auth_required', 'not_required'])\n .describe('Current auth state for this MCP server.'),\n authorization_url: z\n .url()\n .optional()\n .describe('When auth is required, this contains the URL to redirect the user to for authorization.'),\n })\n .strict()\n .describe('Current auth state.')\n .openapi('McpAuthStatus');\n\n/** Admin/settings wire view: identity column plus nested manifest and auth_status. */\nexport const ConfiguredMcpServerSchema = z\n .object({\n name: NameSchema,\n manifest: McpServerManifestSchema,\n auth_status: McpAuthStatusSchema,\n })\n .strict()\n .openapi('ConfiguredMcpServer');\n\nexport const CreateMcpServerRequestSchema = z\n .object({\n manifest: McpServerManifestSchema,\n })\n .strict()\n .openapi('CreateMcpServerRequest');\n\nexport const PutMcpServerRequestSchema = z\n .object({\n manifest: McpServerManifestSchema,\n })\n .strict()\n .openapi('PutMcpServerRequest');\n\nexport const GetMcpServerResponseSchema = z.object({ data: ConfiguredMcpServerSchema }).openapi('GetMcpServerResponse');\nexport const ListMcpServersResponseSchema = z\n .object({ data: z.array(ConfiguredMcpServerSchema) })\n .openapi('ListMcpServersResponse');\n\n/** Public auth mechanism for chat/composer (no secrets). */\nexport const McpServerAuthPublicSchema = z\n .discriminatedUnion('type', [\n z.object({ type: z.literal('dcr') }).strict(),\n z.object({ type: z.literal('header') }).strict(),\n ])\n .describe('Auth mechanism when configured (no secrets). Omit when the server needs no credentials.')\n .openapi('McpServerAuthPublic');\n\n/** Chat/composer read view — public fields plus per-user auth_status. */\nexport const McpServerReadEntrySchema = z\n .object({\n name: NameSchema,\n url: z.url().describe('URL of the remote MCP server.'),\n auth: McpServerAuthPublicSchema.optional(),\n auth_status: McpAuthStatusSchema,\n })\n .strict()\n .openapi('McpServerReadEntry');\n\nexport const ListAvailableMcpServersResponseSchema = z\n .object({ data: z.array(McpServerReadEntrySchema) })\n .openapi('ListAvailableMcpServersResponse');\n\nexport type McpServerType = z.infer<typeof McpServerTypeSchema>;\nexport type McpServerManifestAuth = z.infer<typeof McpServerManifestAuthSchema>;\nexport type McpServerManifest = z.infer<typeof McpServerManifestSchema>;\nexport type McpAuthStatus = z.infer<typeof McpAuthStatusSchema>;\nexport type McpServerAuthPublic = z.infer<typeof McpServerAuthPublicSchema>;\nexport type ConfiguredMcpServer = z.infer<typeof ConfiguredMcpServerSchema>;\nexport type CreateMcpServerRequest = z.infer<typeof CreateMcpServerRequestSchema>;\nexport type PutMcpServerRequest = z.infer<typeof PutMcpServerRequestSchema>;\nexport type McpServerReadEntry = z.infer<typeof McpServerReadEntrySchema>;\n\n/**\n * Headers for live MCP calls against a configured server.\n * Only `auth.type === 'header'` contributes. Turn execution uses DCR via\n * resolveMcpAuth instead of this helper.\n */\nexport function resolveConfiguredMcpRequestHeaders(manifest: McpServerManifest): Record<string, string> {\n if (manifest.auth?.type === 'header') {\n return { ...manifest.auth.headers };\n }\n return {};\n}\n\nexport function resolveMcpAuthStatus({\n manifest,\n token,\n}: {\n manifest: McpServerManifest;\n token?: OAuthToken;\n}): McpAuthStatus {\n if (manifest.auth?.type === 'dcr') {\n return token ? { status: 'authenticated' } : { status: 'auth_required' };\n }\n if (manifest.auth?.type === 'header') {\n return { status: 'authenticated' };\n }\n return { status: 'not_required' };\n}\n","/**\n * DB-backed sessions API (mounted at /api/v1/sessions).\n */\nimport { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport type { ISessionStore, SessionHandle, SessionRecord, Sessions } from '@truefoundry/trueforge-core/agent-session';\nimport {\n CancellationReason,\n SessionStoreConflictError,\n SessionStoreInvariantError,\n SessionStoreNotFoundError,\n TurnNotFoundError,\n} from '@truefoundry/trueforge-core/agent-session';\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport {\n redisRequest,\n RequestTimeoutError,\n type RouteHandler as RequestReplyRouteHandler,\n type RequestReplyRouter,\n} from '@truefoundry/trueforge-core/request-reply';\nimport type { RedisClientType } from 'redis';\nimport { ulid } from 'ulid';\nimport type { Logger } from 'winston';\nimport { z } from 'zod';\nimport type { ResolveUserContext } from '../auth/identity';\nimport configuration from '../config';\nimport type { IAgentStore } from '../db/agentStore';\nimport type { IMcpServerStore } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport {\n cancelSessionRoute,\n createSessionRoute,\n deleteSessionRoute,\n getSessionRoute,\n listSessionEventsRoute,\n listSessionsRoute,\n updateSessionRoute,\n} from '../routes/sessionRoutes';\nimport type { ActiveTurnRegistry } from '../runtime/activeTurns';\nimport { executorFromTurnId } from '../runtime/peeringIds';\nimport { validateAgentSpec } from '../runtime/sessionResources';\nimport { isSessionAgentNameRef, type Session } from '../schemas/session';\n\n/** The server is single-tenant; every record lives under one fixed tenant scope. */\nexport const TENANT_ID = 'default';\n\n/** Request-reply path a replica serves to cancel a turn it owns. */\nexport const SESSIONS_CANCEL_PATH = 'sessions/cancel';\n\n/** Wire body of a peer cancel; validated on receipt (it crosses processes via Redis). */\nconst CancelPeerBodySchema = z.object({\n session_id: z.string(),\n turn_id: z.string(),\n reason: z.enum(CancellationReason),\n});\ntype CancelPeerBody = z.infer<typeof CancelPeerBodySchema>;\n\nexport function toWireSession(record: SessionRecord): Session {\n return {\n id: record.session_id,\n agent: record.agent,\n title: record.title,\n created_by: record.created_by,\n created_at: record.created_at.toISOString(),\n updated_at: record.updated_at.toISOString(),\n };\n}\n\nexport interface SessionsRouterDeps {\n sessions: Sessions;\n sessionStore: ISessionStore;\n activeTurns: ActiveTurnRegistry;\n modelProviderStore: IModelProviderStore;\n mcpServerStore: IMcpServerStore;\n skillStore: ISkillStore;\n agentStore: IAgentStore;\n sandboxProviderStore: ISandboxProviderStore;\n redis?: RedisClientType | undefined;\n requestReplyRouter: RequestReplyRouter;\n resolveUserContext: ResolveUserContext;\n logger: Logger;\n}\n\nfunction cancelTurnOnThisExecutor(\n activeTurns: ActiveTurnRegistry,\n input: { sessionId: string; turnId: string; reason: CancellationReason },\n): boolean {\n return activeTurns.cancelIfRunning({\n sessionId: input.sessionId,\n turnId: input.turnId,\n abortReason: input.reason,\n });\n}\n\n/**\n * Peer-facing cancel handler: aborts the turn if it runs in this process.\n * 200 = abort fired, 412 = not running here (treated by callers as a no-op).\n */\nexport function cancelSessionTurnPeerHandler(activeTurns: ActiveTurnRegistry): RequestReplyRouteHandler {\n // Synchronous by nature; the transport expects a Promise and require-await\n // forbids an async fn without awaits.\n return request => {\n const parsed = CancelPeerBodySchema.safeParse(request.body);\n if (!parsed.success) {\n return Promise.resolve({ status: 400, body: { message: 'Invalid sessions/cancel payload' } });\n }\n const found = cancelTurnOnThisExecutor(activeTurns, {\n sessionId: parsed.data.session_id,\n turnId: parsed.data.turn_id,\n reason: parsed.data.reason,\n });\n return Promise.resolve(\n found ? { status: 200, body: {} } : { status: 412, body: { message: 'Turn is not running on this executor' } },\n );\n };\n}\n\n/** A registry to abort in, a session to freeze, durable state to read, and a way to reach peers. */\nexport interface CancelTurnDeps {\n activeTurns: ActiveTurnRegistry;\n session: Pick<SessionHandle, 'session_id' | 'freezeTurn'>;\n sessionStore: Pick<ISessionStore, 'getTurn'>;\n redis?: RedisClientType | undefined;\n logger: Pick<Logger, 'warn'>;\n}\n\n/**\n * Cancels the turn wherever it runs: locally or on the owning peer over Redis\n * request-reply. Callers state the motive; default is a plain client cancel.\n *\n * A confirmed abort (this process, or peer HTTP 200) lets TurnHandle persist\n * the terminal state. If abort cannot be confirmed, this replica freezes the\n * turn in the store so the session is not stuck `running`.\n *\n * Redis timeout and Redis/transport failures are not a clean cancellation —\n * the owning replica may still be executing — but the turn is still frozen.\n * Later writes from that replica lose to first-terminal-write-wins.\n */\nexport async function cancelSessionTurn(\n deps: CancelTurnDeps,\n input: { turnId: string; reason?: CancellationReason },\n): Promise<void> {\n const { turnId, reason = CancellationReason.ClientCancelled } = input;\n const sessionId = deps.session.session_id;\n\n const turn = await deps.sessionStore.getTurn({\n session_id: sessionId,\n turn_id: turnId,\n });\n if (turn?.state.status !== 'running') {\n // Missing or already terminal — nothing to cancel.\n return;\n }\n\n const owner = executorFromTurnId(turnId);\n // Without a Redis client there is no peer to ask, so an id naming another\n // replica falls through to the local lookup and freezes if the run is gone.\n if (owner !== configuration.EXECUTOR_ID && deps.redis) {\n try {\n const reply = await redisRequest<CancelPeerBody>({\n redis: deps.redis,\n executorId: owner,\n path: SESSIONS_CANCEL_PATH,\n request: {\n body: { session_id: sessionId, turn_id: turnId, reason },\n },\n options: {\n replyTimeoutMs: configuration.REDIS_REQUEST_REPLY_TIMEOUT_MS,\n pollIntervalMs: configuration.REDIS_REQUEST_REPLY_POLL_INTERVAL_MS,\n },\n });\n if (reply.status === 200) {\n return;\n }\n } catch (error) {\n const fields = {\n sessionId,\n turnId,\n owner,\n ...extractErrorLogFields(error),\n };\n if (error instanceof RequestTimeoutError) {\n deps.logger.warn('Timed out waiting for owning executor to cancel; freezing the running turn', fields);\n } else {\n deps.logger.warn('Failed to reach owning executor over Redis; freezing the running turn', fields);\n }\n }\n await freezeTurnIgnoringMissing(deps.session, { turnId, reason });\n return;\n }\n\n const aborted = cancelTurnOnThisExecutor(deps.activeTurns, { sessionId, turnId, reason });\n if (!aborted) {\n await freezeTurnIgnoringMissing(deps.session, { turnId, reason });\n }\n}\n\n/** Freeze a running turn; missing turns are a no-op (already gone). */\nasync function freezeTurnIgnoringMissing(\n session: Pick<SessionHandle, 'freezeTurn'>,\n input: { turnId: string; reason: CancellationReason },\n): Promise<void> {\n try {\n await session.freezeTurn({ turn_id: input.turnId, reason: input.reason });\n } catch (error) {\n if (error instanceof TurnNotFoundError) {\n return;\n }\n throw error;\n }\n}\n\nconst FORBIDDEN_SESSION_ACCESS = 'Only the session creator can access this session';\n\nfunction checkSessionAccess({ userRef, createdBy }: { userRef: string; createdBy: string }): boolean {\n return userRef === createdBy;\n}\n\n/** DB-backed sessions (mounted at /api/v1/sessions). */\nexport function createSessionsRouter(deps: SessionsRouterDeps) {\n const createSessionHandler: RouteHandler<typeof createSessionRoute> = async c => {\n const body = c.req.valid('json');\n const sessionId = ulid().toLowerCase();\n\n if (isSessionAgentNameRef(body.agent)) {\n const agent = await deps.agentStore.getAgent({ tenant_id: TENANT_ID, name: body.agent.name });\n if (agent === undefined) {\n return c.json({ error: { message: `Agent not found: ${body.agent.name}` } }, 404);\n }\n const user = deps.resolveUserContext(c);\n const session = await deps.sessions.create({\n tenant_id: TENANT_ID,\n session_id: sessionId,\n created_by: user.userRef,\n agent: { type: 'reference', id: agent.id, name: agent.name },\n });\n return c.json({ data: toWireSession(session.record) }, 201);\n }\n\n await validateAgentSpec({\n spec: body.agent.spec,\n tenant_id: TENANT_ID,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n });\n const user = deps.resolveUserContext(c);\n const session = await deps.sessions.create({\n tenant_id: TENANT_ID,\n session_id: sessionId,\n created_by: user.userRef,\n agent: { type: 'inline', spec: body.agent.spec },\n });\n return c.json({ data: toWireSession(session.record) }, 201);\n };\n\n const getSessionHandler: RouteHandler<typeof getSessionRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const record = await deps.sessionStore.getSession({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!record) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: record.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n return c.json({ data: toWireSession(record) }, 200);\n };\n\n const deleteSessionHandler: RouteHandler<typeof deleteSessionRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const record = await deps.sessionStore.getSession({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!record) {\n // Idempotent delete when already gone.\n return c.body(null, 204);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: record.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n await deps.sessionStore.deleteSession({ tenant_id: TENANT_ID, session_id: sessionId });\n return c.body(null, 204);\n };\n\n const updateSessionHandler: RouteHandler<typeof updateSessionRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const body = c.req.valid('json');\n const existing = await deps.sessionStore.getSession({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!existing) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: existing.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n // Inline sessions may replace their agent; named (reference) sessions\n // cannot — the store rejects that with SessionStoreInvariantError → 422 below.\n if (body.agent !== undefined) {\n await validateAgentSpec({\n spec: body.agent.spec,\n tenant_id: TENANT_ID,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n });\n }\n try {\n await deps.sessionStore.updateSession({\n tenant_id: TENANT_ID,\n session_id: sessionId,\n agent: body.agent === undefined ? undefined : { type: 'inline', spec: body.agent.spec },\n title: undefined,\n });\n } catch (error) {\n if (error instanceof SessionStoreNotFoundError) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (error instanceof SessionStoreInvariantError) {\n return c.json({ error: { message: error.message } }, 422);\n }\n throw error;\n }\n const record = await deps.sessionStore.getSession({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!record) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n return c.json({ data: toWireSession(record) }, 200);\n };\n\n const listSessionsHandler: RouteHandler<typeof listSessionsRoute> = async c => {\n const query = c.req.valid('query');\n const user = deps.resolveUserContext(c);\n try {\n const { data, pagination } = await deps.sessionStore.listSessions({\n agent_id: query.agent_id,\n created_by: user.userRef,\n tenant_id: TENANT_ID,\n limit: query.limit,\n order: query.order,\n page_token: query.page_token,\n start_timestamp: query.start_timestamp,\n end_timestamp: query.end_timestamp,\n });\n return c.json({ data: data.map(toWireSession), pagination }, 200);\n } catch (error) {\n if (error instanceof SessionStoreConflictError) {\n return c.json({ error: { message: error.message } }, 400);\n }\n throw error;\n }\n };\n\n const cancelSessionHandler: RouteHandler<typeof cancelSessionRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: session.record.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n const turnId = session.record.last_turn_id;\n if (!turnId) {\n return c.json({}, 200);\n }\n\n await cancelSessionTurn({ ...deps, session }, { turnId });\n return c.json({}, 200);\n };\n\n const listSessionEventsHandler: RouteHandler<typeof listSessionEventsRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const query = c.req.valid('query');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: session.record.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n try {\n const { data, pagination } = await session.listEvents({\n limit: query.limit,\n page_token: query.page_token,\n last_turn_id: query.last_turn_id,\n });\n return c.json({ data, pagination }, 200);\n } catch (error) {\n if (error instanceof SessionStoreConflictError) {\n return c.json({ error: { message: error.message } }, 400);\n }\n if (error instanceof SessionStoreNotFoundError) {\n return c.json({ error: { message: error.message } }, 404);\n }\n throw error;\n }\n };\n\n const router = new OpenAPIHono();\n router.openapi(createSessionRoute, createSessionHandler);\n router.openapi(getSessionRoute, getSessionHandler);\n router.openapi(deleteSessionRoute, deleteSessionHandler);\n router.openapi(updateSessionRoute, updateSessionHandler);\n router.openapi(listSessionsRoute, listSessionsHandler);\n router.openapi(cancelSessionRoute, cancelSessionHandler);\n router.openapi(listSessionEventsRoute, listSessionEventsHandler);\n deps.requestReplyRouter.registerRoute(SESSIONS_CANCEL_PATH, cancelSessionTurnPeerHandler(deps.activeTurns));\n return router;\n}\n","/**\n * Session route definitions.\n * DB-backed routes mount at /api/v1/sessions.\n * Handlers are registered in apis/sessions.ts.\n */\nimport { createRoute, z } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { ListSessionEventsRequestQuerySchema, ListSessionEventsResponseSchema } from '../schemas/events';\nimport {\n CreateSessionRequestSchema,\n GetSessionResponseSchema,\n ListSessionsRequestQuerySchema,\n ListSessionsResponseSchema,\n UpdateSessionRequestSchema,\n} from '../schemas/session';\nimport { CancelSessionRequestSchema, CancelSessionResponseSchema } from '../schemas/turn';\nimport { TOKEN_PAGINATION } from './fernExtensions';\n\nconst SESSIONS_TAG = 'Sessions';\n\nexport const SessionIdParamsSchema = z.object({\n session_id: z.string().min(1).max(64).describe('Session identifier.'),\n});\n\nexport const createSessionRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [SESSIONS_TAG],\n summary: 'Create a session',\n description:\n 'Create a session with `agent` as either `{ name }` (named registry binding) or `{ spec: AgentSpec }` (inline). Named sessions snapshot the agent name at create and resolve the live agent on each turn. Responses use `{ type: \"reference\", name, id }` or `{ type: \"inline\", spec }`.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateSessionRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetSessionResponseSchema } },\n description: 'Session created.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Named agent not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'The agent spec is valid but references a resource this server does not provide (e.g. model, MCP server, skill, or sandbox).',\n },\n },\n});\n\nexport const getSessionRoute = createRoute({\n method: 'get',\n path: '/{session_id}',\n tags: [SESSIONS_TAG],\n summary: 'Get a session',\n description: 'Fetch a session by ID. Only the session creator (`created_by`) may fetch it.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'get',\n request: {\n params: SessionIdParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSessionResponseSchema } },\n description: 'Session data.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n },\n});\n\nexport const deleteSessionRoute = createRoute({\n method: 'delete',\n path: '/{session_id}',\n tags: [SESSIONS_TAG],\n summary: 'Delete a session',\n description:\n 'Delete a session and all related turns, events, and internal state. Only the session creator (`created_by`) may delete it. Idempotent if already gone.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'delete',\n request: {\n params: SessionIdParamsSchema,\n },\n responses: {\n 204: {\n description: 'Session and all related data deleted.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n },\n});\n\nexport const updateSessionRoute = createRoute({\n method: 'patch',\n path: '/{session_id}',\n tags: [SESSIONS_TAG],\n summary: 'Update a session',\n description:\n 'Update a session by replacing `agent` with `{ spec: AgentSpec }`. Named (reference) sessions reject agent updates. An empty body is a valid no-op that refreshes `updated_at`. Only the session creator (`created_by`) may update it.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'update',\n request: {\n params: SessionIdParamsSchema,\n body: {\n content: { 'application/json': { schema: UpdateSessionRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSessionResponseSchema } },\n description: 'Session updated.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'Named session rejected an agent update, or the agent spec references a resource this server does not provide (e.g. model, MCP server, skill, or sandbox).',\n },\n },\n});\n\nexport const listSessionsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [SESSIONS_TAG],\n summary: 'List sessions',\n description:\n \"List the caller's sessions (newest first by default), token-paginated. Results are scoped to the authenticated identity via the session store's `created_by` filter (not a client query param). Optional `agent_id` filters to sessions bound to that named agent. Pass `page_token` to fetch the next page, keeping the other query params constant.\",\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'list',\n 'x-fern-pagination': TOKEN_PAGINATION,\n request: {\n query: ListSessionsRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListSessionsResponseSchema } },\n description: 'Paginated sessions.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid query parameters or page token.',\n },\n },\n});\n\nexport const cancelSessionRoute = createRoute({\n method: 'post',\n path: '/{session_id}/cancel',\n tags: [SESSIONS_TAG],\n summary: 'Cancel a running turn in a session',\n description: 'Cancel the running last turn for a session. Only the session creator (`created_by`) may cancel.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'cancel',\n request: {\n params: SessionIdParamsSchema,\n body: {\n content: { 'application/json': { schema: CancelSessionRequestSchema } },\n required: false,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: CancelSessionResponseSchema } },\n description: 'Turn cancelled.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n 412: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'Requested action cannot be performed on the session because it is no longer usable, or the executor owning the running turn is unreachable.',\n },\n },\n});\n\nexport const listSessionEventsRoute = createRoute({\n method: 'get',\n path: '/{session_id}/events',\n tags: [SESSIONS_TAG],\n summary: 'List session events',\n description:\n 'List session events as `{ turn_id, event }` across the active turn branch (newest first), including persisted events from a running tip. Each turn contributes turn.created, content events (model.message, tool.call, …), and turn.done when terminal; streaming deltas are not included. Use `page_token` to paginate backward toward older events while retaining the original branch anchor. Only the session creator (`created_by`) may list events.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'list_events',\n 'x-fern-pagination': TOKEN_PAGINATION,\n request: {\n params: SessionIdParamsSchema,\n query: ListSessionEventsRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListSessionEventsResponseSchema } },\n description: 'Paginated session events.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid page token.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n },\n});\n","/**\n * Server event wire schemas: SSE streaming union + list-query envelopes.\n * Lifecycle / persisted event schemas live in agentSession.\n */\nimport { z } from '@hono/zod-openapi';\nimport {\n EventType,\n SessionEventItemSchema,\n TokenPaginationSchema,\n TurnCreatedEventSchema,\n TurnDoneEventSchema,\n} from '@truefoundry/trueforge-core/agent-session';\nimport {\n MCPAuthRequiredEventSchema,\n MCPInitializeEventSchema,\n ModelMessageDeltaEventSchema,\n ModelMessageEventSchema,\n SandboxCreatedEventSchema,\n ThreadCreatedEventSchema,\n ThreadDoneEventSchema,\n ToolApprovalRequiredEventSchema,\n ToolResponseEventSchema,\n ToolResponseRequiredEventSchema,\n} from '@truefoundry/trueforge-core/core';\n\nexport type { TurnCreatedEvent } from '@truefoundry/trueforge-core/agent-session';\nexport { EventType };\n\n/** Live SSE stream for session turns — content events, deltas and lifecycle. */\nexport const TurnStreamingEventSchema = z\n .discriminatedUnion('type', [\n ModelMessageEventSchema,\n ModelMessageDeltaEventSchema,\n ToolResponseEventSchema,\n ThreadCreatedEventSchema,\n ThreadDoneEventSchema,\n MCPAuthRequiredEventSchema,\n MCPInitializeEventSchema,\n SandboxCreatedEventSchema,\n ToolApprovalRequiredEventSchema,\n ToolResponseRequiredEventSchema,\n TurnCreatedEventSchema,\n TurnDoneEventSchema,\n ])\n .openapi('TurnStreamingEvent');\n\n/** Max events per session-events page. */\nexport const SESSION_EVENTS_LIMIT = 100;\n\nexport const ListSessionEventsRequestQuerySchema = z\n .object({\n page_token: z\n .string()\n .optional()\n .describe(\n 'Pagination cursor from `pagination.next_page_token`. It retains the branch anchor turn and returns older events toward the session start.',\n ),\n last_turn_id: z\n .string()\n .optional()\n .describe(\n 'Newest turn in the listing window (initial load only; ignored when `page_token` is set). Lists that turn and its ancestors, newest events first. Omit to use the session last turn.',\n ),\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(SESSION_EVENTS_LIMIT)\n .optional()\n .default(SESSION_EVENTS_LIMIT)\n .describe(\n `Max events per response. Default ${String(SESSION_EVENTS_LIMIT)}, max ${String(SESSION_EVENTS_LIMIT)}.`,\n ),\n })\n .openapi('ListSessionEventsRequestQuery');\n\nexport const ListSessionEventsResponseSchema = z\n .object({\n data: z.array(SessionEventItemSchema),\n pagination: TokenPaginationSchema,\n })\n .openapi('ListSessionEventsResponse');\n\nexport type TurnStreamingEvent = z.infer<typeof TurnStreamingEventSchema>;\n","/** Server session wire schemas. Core Session lives in agentSession. */\nimport { z } from '@hono/zod-openapi';\nimport { AgentSpecSchema, SessionSchema, TokenPaginationSchema } from '@truefoundry/trueforge-core/agent-session';\nimport { NameSchema } from './common';\n\n/** Create arm: bind by unique registry agent name. */\nexport const SessionAgentNameRefSchema = z.object({ name: NameSchema }).strict().openapi('SessionAgentNameRef');\n\n/**\n * Create/update body arm wrapping an AgentSpec.\n * Use AgentSpecSchema (not `.strict()`) so OpenAPI `$ref`s the shared AgentSpec.\n */\nconst SessionAgentSpecBodySchema = z.object({ spec: AgentSpecSchema }).strict().openapi('SessionAgentSpecBody');\n\n/** Create accepts either a unique agent name or `{ spec: AgentSpec }`. */\nexport const CreateSessionAgentSchema = z\n .union([SessionAgentNameRefSchema, SessionAgentSpecBodySchema])\n .openapi('CreateSessionAgent');\n\nexport type CreateSessionAgent = z.infer<typeof CreateSessionAgentSchema>;\nexport type SessionAgentNameRef = z.infer<typeof SessionAgentNameRefSchema>;\nexport type SessionAgentSpecBody = z.infer<typeof SessionAgentSpecBodySchema>;\n\n/** Narrows the create-body union after OpenAPI already accepted either arm. */\nexport function isSessionAgentNameRef(agent: CreateSessionAgent): agent is SessionAgentNameRef {\n return SessionAgentNameRefSchema.safeParse(agent).success;\n}\n\nexport const CreateSessionRequestSchema = z\n .object({\n agent: CreateSessionAgentSchema,\n })\n .strict()\n .openapi('CreateSessionRequest');\n\n/** Only inline sessions may be updated; named (reference) sessions reject agent updates. */\nexport const UpdateSessionRequestSchema = z\n .object({\n agent: SessionAgentSpecBodySchema.optional(),\n })\n .strict()\n .openapi('UpdateSessionRequest');\n\nexport type { Session } from '@truefoundry/trueforge-core/agent-session';\n\nexport const DEFAULT_SESSIONS_LIMIT = 10;\nexport const SESSIONS_MAX_LIMIT = 100;\n\n/** Wire ISO-8601 (RFC 3339, offsets allowed) → Date for the store. */\nconst IsoTimestampQueryParam = z.iso\n .datetime({ offset: true })\n .openapi({ type: 'string', format: 'date-time' })\n .transform(s => new Date(s));\n\nexport const ListSessionsRequestQuerySchema = z\n .object({\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(SESSIONS_MAX_LIMIT)\n .optional()\n .default(DEFAULT_SESSIONS_LIMIT)\n .describe(`Page size. Defaults to ${String(DEFAULT_SESSIONS_LIMIT)}, max ${String(SESSIONS_MAX_LIMIT)}.`),\n order: z\n .enum(['asc', 'desc'])\n .optional()\n .default('desc')\n .describe('Sort sessions by `updated_at`. Defaults to \"desc\".')\n .openapi('ListSessionsOrder'),\n page_token: z\n .string()\n .min(1)\n .optional()\n .describe('Opaque keyset cursor from a previous response `next_page_token`.'),\n start_timestamp: IsoTimestampQueryParam.optional().describe(\n 'Inclusive lower bound on `created_at` (ISO-8601 / RFC 3339).',\n ),\n end_timestamp: IsoTimestampQueryParam.optional().describe(\n 'Inclusive upper bound on `created_at` (ISO-8601 / RFC 3339).',\n ),\n agent_id: z.string().min(1).optional().describe('When set, only sessions bound to this agent id are returned.'),\n })\n .openapi('ListSessionsRequestQuery');\n\nexport const GetSessionResponseSchema = z\n .object({\n data: SessionSchema,\n })\n .openapi('GetSessionResponse');\n\nexport const ListSessionsResponseSchema = z\n .object({\n data: z.array(SessionSchema),\n pagination: TokenPaginationSchema,\n })\n .openapi('ListSessionsResponse');\n","/** Server-only turn wire schemas (SSE resume / cancel / list). Core turn schemas live in agent-session. */\nimport { z } from '@hono/zod-openapi';\nimport { SessionEventSchema, TokenPaginationSchema, TurnSchema } from '@truefoundry/trueforge-core/agent-session';\n\nexport { CreateTurnRequestSchema, TurnSchema } from '@truefoundry/trueforge-core/agent-session';\nexport type { Turn } from '@truefoundry/trueforge-core/agent-session';\n\nexport const SubscribeTurnQuerySchema = z\n .object({\n // Query strings need coerce; map null/'' to undefined first so Number(null)→0\n // cannot silently become a resume cursor (and so OpenAPI does not advertise null).\n after_sequence_number: z.preprocess(\n val => (val === null || val === '' ? undefined : val),\n z.coerce\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\n 'Exclusive resume cursor: replay only events with a sequence number greater than this value. Omit to start from the beginning of the live buffer.',\n ),\n ),\n })\n .openapi('SubscribeTurnQuery');\n\n/** Intentionally empty — cancel takes no body fields. */\nexport const CancelSessionRequestSchema = z\n .object({})\n .describe('Empty request body. Cancel identifies the session via the path only.')\n .openapi('CancelSessionRequest');\n/** Intentionally empty — success is signaled by HTTP 200 with `{}`. */\nexport const CancelSessionResponseSchema = z\n .object({})\n .describe('Empty success body. HTTP 200 means the cancel request was accepted (or nothing was running).')\n .openapi('CancelSessionResponse');\n\nexport const DEFAULT_TURNS_LIMIT = 10;\nexport const TURNS_MAX_LIMIT = 100;\n\nexport const ListTurnsRequestQuerySchema = z\n .object({\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(TURNS_MAX_LIMIT)\n .optional()\n .default(DEFAULT_TURNS_LIMIT)\n .describe(`Page size. Defaults to ${String(DEFAULT_TURNS_LIMIT)}, max ${String(TURNS_MAX_LIMIT)}.`),\n page_token: z.string().optional().describe('Opaque token from a previous response `next_page_token`.'),\n })\n .openapi('ListTurnsRequestQuery');\n\nexport const GetTurnResponseSchema = z\n .object({\n data: TurnSchema,\n })\n .openapi('GetTurnResponse');\n\nexport const ListTurnsResponseSchema = z\n .object({\n data: z.array(TurnSchema),\n pagination: TokenPaginationSchema,\n })\n .openapi('ListTurnsResponse');\n\nexport const DEFAULT_TURN_EVENTS_LIMIT = 25;\nexport const TURN_EVENTS_MAX_LIMIT = 100;\n\nexport const ListTurnEventsRequestQuerySchema = z\n .object({\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(TURN_EVENTS_MAX_LIMIT)\n .optional()\n .default(DEFAULT_TURN_EVENTS_LIMIT)\n .describe(\n `Max events per response. Default ${String(DEFAULT_TURN_EVENTS_LIMIT)}, max ${String(TURN_EVENTS_MAX_LIMIT)}.`,\n ),\n page_token: z.string().optional().describe('Opaque token from a previous response `next_page_token`.'),\n order: z\n .enum(['asc', 'desc'])\n .optional()\n .default('asc')\n .describe('Sort events by insertion order. Defaults to \"asc\".')\n .openapi('ListTurnEventsOrder'),\n })\n .openapi('ListTurnEventsRequestQuery');\n\nexport const ListTurnEventsResponseSchema = z\n .object({\n data: z.array(SessionEventSchema),\n pagination: TokenPaginationSchema,\n })\n .openapi('ListTurnEventsResponse');\n\nexport const DownloadSandboxFileRequestQuerySchema = z\n .object({\n path: z\n .string()\n .min(1)\n .describe(\n \"Absolute path of the file inside the sandbox, as listed in the assistant's `sandbox_artifacts` block.\",\n ),\n })\n .openapi('DownloadSandboxFileRequestQuery');\n","/** Every paginated endpoint on this server shares one opaque-token contract. */\nexport const TOKEN_PAGINATION = {\n cursor: '$request.page_token',\n next_cursor: '$response.pagination.next_page_token',\n results: '$response.data',\n};\n","import { HTTPException } from 'hono/http-exception';\nimport { ulid } from 'ulid';\n\n/**\n * Mints a turn id owned by `executorId`. The server calls this at turn\n * creation (the id is opaque to the session library); `executorFromTurnId`\n * is the matching decoder on the routing path.\n */\nexport function mintPeeredTurnId(executorId: string): string {\n return `${ulid().toLowerCase()}.${executorId}`;\n}\n\n/** Decodes the owning executor; throws 400 for an id outside the grammar. */\nexport function executorFromTurnId(turnId: string): string {\n const parts = turnId.split('.');\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new HTTPException(400, { message: `ID ${turnId} is not a valid turn id` });\n }\n return parts[1];\n}\n","import { OpenAPIHono } from '@hono/zod-openapi';\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport type { Configuration } from 'openid-client';\nimport type { Logger } from 'winston';\nimport { clearAuthCookie, ID_TOKEN_COOKIE, OAUTH_STATE_COOKIE, readOAuthStateCookie } from '../auth/cookies';\nimport { resolveUserContext } from '../auth/identity';\nimport { authMiddleware } from '../auth/middleware';\nimport { buildLoginAuthorization, exchangeAuthorizationCode, getOidcVerify, safeReturnTo } from '../auth/oidc';\nimport { authLoginRoute, authLogoutRoute, meRoute, oAuthCallbackRoute } from '../routes/authRoutes';\nimport type { MeResponse } from '../schemas/auth';\n\n/** Login / OIDC failures land on `/?error=<reason>`. */\nfunction oauthErrorRedirect(reason: string): string {\n return `/?error=${encodeURIComponent(reason)}`;\n}\n\n/**\n * Auth surfaces mounted at /api/v1/auth: login, callback, logout, me.\n * Login, callback, and logout stay public; me requires {@link authMiddleware}.\n */\nexport function createAuthRouter(params: { oidcClient: Configuration | undefined; logger: Logger }) {\n const router = new OpenAPIHono();\n\n router.openapi(authLoginRoute, async c => {\n // TODO: remove this checks once the middleware is implemented\n if (!params.oidcClient) {\n return c.redirect('/', 302);\n }\n\n try {\n const authorizationUrl = await buildLoginAuthorization({\n context: c,\n client: params.oidcClient,\n returnTo: c.req.valid('query').return_to,\n });\n return c.redirect(authorizationUrl, 302);\n } catch (error) {\n params.logger.error('Failed to build login authorization', extractErrorLogFields(error));\n return c.redirect(oauthErrorRedirect('login_failed'), 302);\n }\n });\n\n router.openapi(oAuthCallbackRoute, async c => {\n if (!params.oidcClient) {\n return c.redirect('/', 302);\n }\n\n const query = c.req.valid('query');\n const pending = readOAuthStateCookie({ context: c, logger: params.logger });\n clearAuthCookie({ context: c, name: OAUTH_STATE_COOKIE });\n\n if (pending?.state !== query.state || query.error || !query.code) {\n // Only reflect a non-empty IdP `error_description` when the IdP returned an error.\n // No fallback to the `error` code — blank/missing descriptions use the default.\n // Our own validation failures (state mismatch / missing code) stay generic too.\n const description = query.error_description?.trim();\n const reason = query.error && description ? description : 'login_failed';\n return c.redirect(oauthErrorRedirect(reason), 302);\n }\n\n try {\n await exchangeAuthorizationCode({\n context: c,\n client: params.oidcClient,\n callbackParams: new URL(c.req.url).searchParams,\n codeVerifier: pending.code_verifier,\n state: pending.state,\n });\n return c.redirect(safeReturnTo(pending.return_to), 302);\n } catch (error) {\n params.logger.error('Failed to exchange authorization code', extractErrorLogFields(error));\n const reason = error instanceof Error ? error.message : 'login_failed';\n return c.redirect(oauthErrorRedirect(reason), 302);\n }\n });\n\n router.openapi(authLogoutRoute, c => {\n // Cookie deletion is idempotent, so logout also succeeds when no cookie exists.\n clearAuthCookie({ context: c, name: ID_TOKEN_COOKIE });\n return c.body(null, 204);\n });\n\n const gated = new OpenAPIHono();\n gated.use('*', authMiddleware);\n gated.openapi(meRoute, c => {\n const user = resolveUserContext(c);\n const body: MeResponse = getOidcVerify()\n ? { type: 'oidc-connected', email: user.userRef, role: user.role }\n : { type: 'default', email: user.userRef, role: user.role };\n return c.json(body, 200);\n });\n router.route('/', gated);\n\n return router;\n}\n","import type { Context } from 'hono';\nimport { deleteCookie, getCookie, setCookie } from 'hono/cookie';\nimport type { Logger } from 'winston';\nimport { z } from 'zod';\nimport { getPublicBaseUrl } from '../config';\n\nexport const OAUTH_STATE_COOKIE = 'oauth_state';\nexport const ID_TOKEN_COOKIE = 'id_token';\n\nconst OAuthStateSchema = z.object({\n state: z.string(),\n code_verifier: z.string(),\n return_to: z.string(),\n});\n\nexport type OAuthState = z.infer<typeof OAuthStateSchema>;\n\nfunction getAuthCookieAttributes(): {\n httpOnly: boolean;\n sameSite: 'Lax' | 'Strict' | 'None';\n secure: boolean;\n path: string;\n} {\n return {\n httpOnly: true,\n sameSite: 'Lax' as const,\n secure: getPublicBaseUrl().startsWith('https://'),\n path: '/',\n };\n}\n\nexport function setAuthCookie(params: { context: Context; name: string; value: string; maxAgeSeconds: number }): void {\n setCookie(params.context, params.name, params.value, {\n ...getAuthCookieAttributes(),\n maxAge: params.maxAgeSeconds,\n });\n}\n\nexport function readOAuthStateCookie(params: { context: Context; logger: Logger }): OAuthState | undefined {\n const raw = getCookie(params.context, OAUTH_STATE_COOKIE);\n if (!raw) {\n return undefined;\n }\n try {\n // JSON.parse throws SyntaxError when the cookie value is not JSON.\n const result = OAuthStateSchema.safeParse(JSON.parse(raw));\n if (!result.success) {\n params.logger.warn('oauth_state cookie failed schema validation', { error: result.error.message });\n return undefined;\n }\n return result.data;\n } catch (error) {\n params.logger.warn('oauth_state cookie is not valid JSON', {\n error: error instanceof Error ? error.message : error,\n });\n return undefined;\n }\n}\n\nexport function clearAuthCookie(params: { context: Context; name: string }): void {\n deleteCookie(params.context, params.name, getAuthCookieAttributes());\n}\n\nexport function readIdTokenCookie(params: { context: Context }): string | undefined {\n return getCookie(params.context, ID_TOKEN_COOKIE);\n}\n","import type { Context } from 'hono';\nimport { createRemoteJWKSet, type JWTVerifyGetKey } from 'jose';\nimport {\n authorizationCodeGrant,\n buildAuthorizationUrl,\n calculatePKCECodeChallenge,\n type Configuration,\n discovery,\n randomPKCECodeVerifier,\n randomState,\n} from 'openid-client';\nimport { getPublicBaseUrl, type OIDCConfig } from '../config';\nimport { buildAuthorizationRequestParams } from './claims';\nimport { ID_TOKEN_COOKIE, OAUTH_STATE_COOKIE, setAuthCookie } from './cookies';\n\nconst CALLBACK_PATH = '/api/v1/auth/callback';\nconst OAUTH_STATE_MAX_AGE_SECONDS = 10 * 60;\nconst ID_TOKEN_COOKIE_MAX_AGE_SECONDS = 24 * 60 * 60;\n\n/** JWKS + claim config used by cookie JWT verification when auth is enabled. */\nexport interface OidcVerify {\n jwks: JWTVerifyGetKey;\n issuer: string;\n audience: string;\n oidcConfig: OIDCConfig;\n}\n\n/** Single instance of the OIDC verification. */\nlet oidcVerify: OidcVerify | null = null;\n\n/** Enable cookie JWT verification using the IdP client + claim-mapping config from `initOidc`. */\nexport function enableOidcAuth(params: { client: Configuration; oidcConfig: OIDCConfig }): void {\n const metadata = params.client.serverMetadata();\n if (!metadata.jwks_uri) {\n throw new Error('OIDC discovery did not return jwks_uri; cannot verify ID tokens');\n }\n\n oidcVerify = {\n jwks: createRemoteJWKSet(new URL(metadata.jwks_uri)),\n issuer: metadata.issuer,\n audience: params.client.clientMetadata().client_id,\n oidcConfig: params.oidcConfig,\n };\n}\n\n/** Disable OIDC cookie auth (no IdP / standalone). Protected routes use the default user context. */\nexport function disableOidcAuth(): void {\n oidcVerify = null;\n}\n\n/** Active verification config, or `null` when auth is disabled. */\nexport function getOidcVerify(): OidcVerify | null {\n return oidcVerify;\n}\n\n/** Discover the IdP once at process startup when auth is enabled; wires cookie auth verification. */\nexport async function initOidc(oidc: OIDCConfig | undefined): Promise<Configuration | undefined> {\n if (!oidc) {\n disableOidcAuth();\n return undefined;\n }\n\n const client = await discovery(new URL(oidc.OIDC_ISSUER_URL), oidc.OIDC_CLIENT_ID, oidc.OIDC_CLIENT_SECRET);\n enableOidcAuth({ client, oidcConfig: oidc });\n return client;\n}\n\nfunction authCallbackUrl(): string {\n const publicBaseUrl = getPublicBaseUrl();\n return `${publicBaseUrl}${CALLBACK_PATH}`;\n}\n\n/**\n * Same-origin relative path only.\n * - starts with `/`\n * - not `//…` (open redirect)\n * - not `/api` or `/api/…`\n */\nconst SAFE_RETURN_TO = /^\\/(?!\\/|api(?:\\/|$)).*/;\n\nexport function safeReturnTo(value: string | undefined): string {\n if (value && SAFE_RETURN_TO.test(value)) {\n return value;\n }\n return '/';\n}\n\nexport async function buildLoginAuthorization(params: {\n context: Context;\n client: Configuration;\n returnTo: string | undefined;\n}): Promise<string> {\n const oidcConfig = getOidcVerify()?.oidcConfig;\n if (!oidcConfig) {\n throw new Error(\n 'OIDC claim configuration is unavailable; call initOidc before building a login authorization URL.',\n );\n }\n\n const { scopes, claims } = buildAuthorizationRequestParams(oidcConfig);\n const returnTo = safeReturnTo(params.returnTo);\n const codeVerifier = randomPKCECodeVerifier();\n const state = randomState();\n const authorizationUrl = buildAuthorizationUrl(params.client, {\n redirect_uri: authCallbackUrl(),\n scope: scopes.join(' '),\n claims: JSON.stringify(claims),\n code_challenge: await calculatePKCECodeChallenge(codeVerifier),\n code_challenge_method: 'S256',\n state,\n });\n setAuthCookie({\n context: params.context,\n name: OAUTH_STATE_COOKIE,\n value: JSON.stringify({\n state,\n code_verifier: codeVerifier,\n return_to: returnTo,\n }),\n maxAgeSeconds: OAUTH_STATE_MAX_AGE_SECONDS,\n });\n return authorizationUrl.href;\n}\n\nexport async function exchangeAuthorizationCode(params: {\n context: Context;\n client: Configuration;\n /** Whole IdP response query: openid-client validates `state`, `error` and `iss` from it. */\n callbackParams: URLSearchParams;\n codeVerifier: string;\n state: string;\n}): Promise<void> {\n // Origin and path come from config so redirect_uri matches the one registered with the IdP.\n const callbackUrl = new URL(authCallbackUrl());\n callbackUrl.search = params.callbackParams.toString();\n const tokens = await authorizationCodeGrant(params.client, callbackUrl, {\n pkceCodeVerifier: params.codeVerifier,\n expectedState: params.state,\n });\n const idToken = tokens.id_token;\n if (!idToken) {\n throw new Error('Token response missing id_token');\n }\n setAuthCookie({\n context: params.context,\n name: ID_TOKEN_COOKIE,\n value: idToken,\n maxAgeSeconds: ID_TOKEN_COOKIE_MAX_AGE_SECONDS,\n });\n}\n","import type { OIDCConfig } from '../config';\nimport type { Role, UserContext } from './identity';\n\n/** Raw claims from a decoded ID token; values are untyped until read here. */\nexport type IdTokenClaims = Record<string, unknown>;\n\n/**\n * Normalizes a claim value into a string list to check membership against.\n * OIDC doesn't fix the shape of claims like `groups`/`roles`: most IdPs\n * return an array, some collapse a single membership down to a bare string,\n * and a missing/misconfigured claim mapping can omit it entirely. Anything\n * else (number, object, null) is treated as \"no values\" rather than thrown -\n * a malformed claim should fail a user out of admin, not crash the request.\n */\nexport function claimValues(claim: unknown): string[] {\n if (Array.isArray(claim)) {\n return claim.filter((value): value is string => typeof value === 'string');\n }\n if (typeof claim === 'string') {\n return [claim];\n }\n return [];\n}\n\n/**\n * The stable identity key for this caller. An identity that can't be resolved\n * means the token can't be trusted to identify anyone, so this throws.\n */\nexport function resolveUserRef(claims: IdTokenClaims, config: OIDCConfig): string {\n const value = claims[config.OIDC_USER_REFERENCE_CLAIM];\n if (typeof value !== 'string' || value === '') {\n throw new Error(\n `ID token is missing a non-empty \"${config.OIDC_USER_REFERENCE_CLAIM}\" claim (OIDC_USER_REFERENCE_CLAIM).`,\n );\n }\n return value;\n}\n\n/**\n * Admin iff the configured role claim's values include the configured admin\n * value, exact case-sensitive string match.\n */\nexport function resolveRole(claims: IdTokenClaims, config: OIDCConfig): Role {\n return claimValues(claims[config.OIDC_USER_ROLE_CLAIM]).includes(config.OIDC_ADMIN_ROLE_VALUE) ? 'admin' : 'user';\n}\n\n/** Everything `/callback` (and later `/me`, once sessions are real) needs from a set of claims. */\nexport function toUserContext(claims: IdTokenClaims, config: OIDCConfig): UserContext {\n return {\n userRef: resolveUserRef(claims, config),\n role: resolveRole(claims, config),\n };\n}\n\nexport interface AuthorizationRequestParams {\n scopes: string[];\n /** OIDC `claims` request parameter; pass through as-is. */\n claims: { id_token: Record<string, { essential: true }> };\n}\n\n/**\n * Scopes + `claims` parameter for the authorization request, derived\n * from configured claim names and {@link OIDCConfig.OIDC_SCOPES}.\n * `essential: true` on the role claim makes the IdP reject the\n * login outright if it can't actually produce that claim (e.g. a broken\n * claim mapping) instead of silently omitting it and defaulting the user to\n * non-admin.\n */\nexport function buildAuthorizationRequestParams(config: OIDCConfig): AuthorizationRequestParams {\n return {\n scopes: config.OIDC_SCOPES,\n claims: {\n id_token: {\n [config.OIDC_USER_REFERENCE_CLAIM]: { essential: true },\n [config.OIDC_USER_ROLE_CLAIM]: { essential: true },\n },\n },\n };\n}\n","import type { Context } from 'hono';\nimport { getOidcVerify } from './oidc';\n\nexport type Role = 'admin' | 'user';\n\nexport interface UserContext {\n userRef: string;\n role: Role;\n}\n\n/**\n * Fixed identity when no identity provider is configured (standalone / auth disabled).\n * Stamped onto sessions as `created_by` and used for ownership checks.\n */\nexport const LOCAL_USER_CONTEXT: UserContext = {\n userRef: 'trueforge-default',\n role: 'admin',\n};\n\n/** Auth disabled: always true. Auth enabled: admin role only. */\nexport function isAdmin(user: UserContext): boolean {\n if (!getOidcVerify()) {\n return true;\n }\n return user.role === 'admin';\n}\n\n/** Resolves the caller identity from the request context. Injected on session/turn routers. */\nexport type ResolveUserContext = (c: Context) => UserContext;\n\n/**\n * Caller {@link UserContext} for the current request.\n * Requires auth middleware to have set `c.var.user`.\n */\nexport function resolveUserContext(c: Context): UserContext {\n const uc = c.get('user_context');\n if (uc === undefined) {\n throw new Error('UserContext missing; auth middleware did not run');\n }\n return uc;\n}\n","import type { Context, MiddlewareHandler } from 'hono';\nimport { HTTPException } from 'hono/http-exception';\nimport { jwtVerify } from 'jose';\nimport { toUserContext, type IdTokenClaims } from './claims';\nimport { readIdTokenCookie } from './cookies';\nimport { LOCAL_USER_CONTEXT, isAdmin, type UserContext } from './identity';\nimport { getOidcVerify } from './oidc';\n\ndeclare module 'hono' {\n interface ContextVariableMap {\n user_context?: UserContext;\n }\n}\n\nconst AUTH_HEADER_TYPE = 'Bearer';\n\n/**\n * OIDC ID token from `Authorization: Bearer <jwt>` when present.\n * Case-insensitive scheme; rejects empty credentials. Non-Bearer schemes → undefined\n * so cookie auth can still apply.\n */\nexport function readBearerIdToken(c: Context): string | undefined {\n const header = c.req.header('Authorization')?.trim();\n if (!header) {\n return undefined;\n }\n const prefix = `${AUTH_HEADER_TYPE} `;\n if (!header.toLowerCase().startsWith(prefix.toLowerCase())) {\n return undefined;\n }\n const token = header.slice(prefix.length).trim();\n return token.length > 0 ? token : undefined;\n}\n\n/**\n * Prefer Bearer over the browser cookie when both are sent (explicit API auth wins).\n */\nexport function readIdToken(c: Context): string | undefined {\n return readBearerIdToken(c) ?? readIdTokenCookie({ context: c });\n}\n\n/**\n * Bearer or cookie ID token → {@link UserContext} when auth is enabled and the JWT is valid.\n * Missing/invalid JWT → `undefined`. Claim mapping failures after a successful verify rethrow.\n */\nexport async function resolveAuthUser(c: Context): Promise<UserContext | undefined> {\n const oidcVerify = getOidcVerify();\n if (!oidcVerify) {\n return undefined;\n }\n\n const token = readIdToken(c);\n if (!token) {\n return undefined;\n }\n\n let payload: Awaited<ReturnType<typeof jwtVerify>>['payload'];\n try {\n ({ payload } = await jwtVerify(token, oidcVerify.jwks, {\n issuer: oidcVerify.issuer,\n audience: oidcVerify.audience,\n }));\n } catch {\n return undefined;\n }\n\n const claims: IdTokenClaims = { ...payload };\n return toUserContext(claims, oidcVerify.oidcConfig);\n}\n\n/** Set `c.var.user` and continue, or throw 401. When auth is disabled, sets {@link LOCAL_USER_CONTEXT}. */\nexport const authMiddleware: MiddlewareHandler = async (c, next) => {\n if (!getOidcVerify()) {\n c.set('user_context', LOCAL_USER_CONTEXT);\n return next();\n }\n\n try {\n const user = await resolveAuthUser(c);\n if (!user) {\n throw new HTTPException(401, { message: 'Authentication required' });\n }\n c.set('user_context', user);\n } catch (error) {\n if (error instanceof HTTPException) {\n throw error;\n }\n // Valid JWT but claim mapping failed (e.g. missing user reference claim).\n throw new HTTPException(401, { message: 'Authentication required', cause: error });\n }\n return next();\n};\n\n/** Admin gate: local admin when auth is disabled; when auth is enabled requires an authenticated admin. */\nexport const adminAuthMiddleware: MiddlewareHandler = async (c, next) => {\n if (!getOidcVerify()) {\n c.set('user_context', LOCAL_USER_CONTEXT);\n return next();\n }\n\n try {\n const user = await resolveAuthUser(c);\n if (!user) {\n throw new HTTPException(401, { message: 'Authentication required' });\n }\n if (!isAdmin(user)) {\n throw new HTTPException(403, { message: 'Admin access required' });\n }\n c.set('user_context', user);\n } catch (error) {\n if (error instanceof HTTPException) {\n throw error;\n }\n throw new HTTPException(401, { message: 'Authentication required', cause: error });\n }\n\n return next();\n};\n","/**\n * Auth route definitions (mounted at /api/v1/auth). Handlers in apis/auth.ts.\n *\n * `login`/`callback` are browser-redirect targets, never called by SDK\n * consumers — both carry `x-fern-ignore`, the same convention used for the\n * MCP OAuth callback in mcpOAuthRoutes.ts. `logout` and `me` generate normally.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { AuthLoginQuerySchema, MeResponseSchema, OAuthCallbackQuerySchema } from '../schemas/auth';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\n\nconst AUTH_TAG = 'Auth';\n\nexport const authLoginRoute = createRoute({\n method: 'get',\n path: '/login',\n tags: [AUTH_TAG],\n summary: 'Start the login flow',\n description:\n 'Redirects the browser to the configured identity provider. In local/single-binary mode, redirects straight ' +\n 'back into the app — there is nothing to log into.',\n 'x-fern-ignore': true,\n request: { query: AuthLoginQuerySchema },\n responses: {\n 302: { description: 'Redirect to the IdP authorization endpoint.' },\n },\n});\n\nexport const oAuthCallbackRoute = createRoute({\n method: 'get',\n path: '/callback',\n tags: [AUTH_TAG],\n summary: 'Login callback',\n description:\n 'Browser-redirect target hit by the identity provider after login, never called directly by SDK consumers. ' +\n 'In local/single-binary mode, redirects straight back into the app.',\n 'x-fern-ignore': true,\n request: { query: OAuthCallbackQuerySchema },\n responses: {\n 302: { description: 'Redirect back into the app on success, or to /?error=<reason> on failure.' },\n },\n});\n\nexport const authLogoutRoute = createRoute({\n method: 'post',\n path: '/logout',\n tags: [AUTH_TAG],\n summary: 'Clear the local session',\n description:\n 'Ends the local harness session only — does not hit the IdP end-session endpoint. A no-op in local/single-binary ' +\n 'mode, since there is no real session to clear.',\n 'x-fern-sdk-group-name': ['auth'],\n 'x-fern-sdk-method-name': 'logout',\n responses: {\n 204: { description: 'Session cookie cleared.' },\n },\n});\n\nexport const meRoute = createRoute({\n method: 'get',\n path: '/me',\n tags: [AUTH_TAG],\n summary: 'Current session',\n description:\n 'Returns the authenticated caller identity. When auth is enabled this requires a valid ' +\n '`id_token` cookie or `Authorization: Bearer` ID token (401 otherwise). When auth is disabled, ' +\n 'returns the default identity.',\n 'x-fern-sdk-group-name': ['auth'],\n 'x-fern-sdk-method-name': 'me',\n responses: {\n 200: {\n content: { 'application/json': { schema: MeResponseSchema } },\n description: 'Session type and identity for the current request.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Auth is enabled and the request has no valid cookie or Bearer ID token.',\n },\n },\n});\n","/** Auth wire schemas. */\nimport { z } from '@hono/zod-openapi';\n\nexport const AuthLoginQuerySchema = z.object({\n return_to: z\n .string()\n .optional()\n .describe('Path to return to after login. Must be a same-origin relative path; anything else falls back to \"/\".'),\n});\n\nexport const OAuthCallbackQuerySchema = z.object({\n code: z.string().min(1).optional().describe('Authorization code, present when the user granted consent.'),\n state: z\n .string()\n .min(1)\n .describe('Opaque token; correlates this callback to its pending login. Always present, success or error.'),\n error: z\n .string()\n .optional()\n .describe('Error code from the identity provider, present instead of `code` if the user denied consent.'),\n error_description: z\n .string()\n .optional()\n .describe('Human-readable error detail from the identity provider when `error` is set.'),\n});\n\nexport const OAuthCallbackSuccessSchema = z.object({\n success: z.literal(true).describe('Present when the OAuth callback completed without a redirect_url.'),\n});\n\nexport const MeResponseSchema = z\n .object({\n type: z\n .enum(['default', 'oidc-connected'])\n .describe(\n 'Session kind: `default` when no valid OIDC session; `oidc-connected` after a successful browser login.',\n ),\n email: z.string().describe('User email from the ID token when connected; `\"default\"` when anonymous.'),\n role: z.string().describe('Caller role.'),\n })\n .openapi('MeResponse');\n\nexport type MeResponse = z.infer<typeof MeResponseSchema>;\n","import { OpenAPIHono } from '@hono/zod-openapi';\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport { isAdmin, resolveUserContext } from '../auth/identity';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { WithTransaction } from '../db/transaction';\nimport { getCapabilitiesRoute } from '../routes/capabilityRoutes';\nimport { checkSnapshotStatus } from '../sandbox/providerUtils';\nimport type { SandboxBuildStatus } from '../schemas/sandboxProvider';\nimport { TENANT_ID } from './sessions';\n\n/**\n * Why skills are unavailable, keyed off the sandbox build status.\n * `pending` is transient (retry); everything else (no provider / failed / unknown) reads as not configured.\n */\nfunction skillDisabledReason(status: SandboxBuildStatus | undefined): string {\n if (status === 'pending') {\n return 'Skills run in a sandbox whose image is still being prepared — retry shortly.';\n }\n return 'Skills run in a sandbox, which is not configured.';\n}\n\nexport function createCapabilitiesRouter<TTransaction>(deps: {\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n logger: Logger;\n}) {\n const router = new OpenAPIHono();\n router.openapi(getCapabilitiesRoute, async c => {\n // Sandbox is usable only when a provider is configured AND its image build reports ready.\n // Refresh the persisted status (and re-activate an idle snapshot); fail closed (disabled) if it throws.\n let status: SandboxBuildStatus | undefined;\n try {\n const refreshed = await checkSnapshotStatus({\n store: deps.sandboxProviderStore,\n tenant_id: TENANT_ID,\n logger: deps.logger,\n });\n status = refreshed?.status;\n } catch (error) {\n deps.logger.warn('Sandbox image status check failed; reporting sandbox disabled', extractErrorLogFields(error));\n }\n const sandboxEnabled = status === 'ready';\n const settingsEnabled = isAdmin(resolveUserContext(c));\n return c.json(\n {\n data: {\n sandbox: { enabled: sandboxEnabled },\n skill: sandboxEnabled ? { enabled: true } : { enabled: false, reason: skillDisabledReason(status) },\n settings: { enabled: settingsEnabled },\n },\n },\n 200,\n );\n });\n return router;\n}\n","import { createRoute, z } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\n\nconst GetCapabilitiesResponseSchema = z\n .object({\n data: z.object({\n sandbox: z.object({\n enabled: z.boolean().describe('Whether a sandbox provider is configured for this tenant.'),\n }),\n skill: z.object({\n enabled: z\n .boolean()\n .describe('Whether skills are available. False when sandbox is not enabled (skills require a sandbox).'),\n reason: z.string().optional().describe('Present when skills are disabled. Explains why.'),\n }),\n settings: z.object({\n enabled: z.boolean().describe('Whether the settings UI/API is enabled.'),\n }),\n }),\n })\n .openapi('GetCapabilitiesResponse');\n\nexport const getCapabilitiesRoute = createRoute({\n method: 'get',\n path: '/',\n tags: ['Capabilities'],\n summary: 'Get server capabilities',\n 'x-fern-sdk-group-name': ['server'],\n 'x-fern-sdk-method-name': 'get_capabilities',\n description: 'Report optional runtime capabilities available for this tenant.',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetCapabilitiesResponseSchema } },\n description: 'Server capabilities.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { SUPPORTED_REASONING_EFFORTS } from '@truefoundry/trueforge-core/core';\nimport type { McpCatalog } from '../catalog/McpCatalog';\nimport type { ModelCatalog } from '../catalog/ModelCatalog';\nimport type { SandboxCatalog } from '../catalog/SandboxCatalog';\nimport type { SkillCatalog } from '../catalog/SkillCatalog';\nimport {\n listMcpServerCatalogRoute,\n listModelProviderCatalogRoute,\n listSandboxProviderCatalogRoute,\n listSkillCatalogRoute,\n} from '../routes/catalogRoutes';\nimport type { CatalogModelProvider } from '../schemas/modelCatalog';\n\nexport interface CatalogRouterDeps {\n modelCatalog: ModelCatalog;\n mcpCatalog: McpCatalog;\n skillCatalog: SkillCatalog;\n sandboxCatalog: SandboxCatalog;\n}\n\nexport function createCatalogRouter(deps: CatalogRouterDeps) {\n const listModelProvidersHandler: RouteHandler<typeof listModelProviderCatalogRoute> = c => {\n const loadedProvidersCatalog = deps.modelCatalog.list();\n // make a copy of the loaded providers catalog and add the custom provider sentinel\n const providersCatalog: CatalogModelProvider[] = [...loadedProvidersCatalog];\n providersCatalog.push({\n type: 'custom',\n supported_reasoning_efforts: [...SUPPORTED_REASONING_EFFORTS],\n });\n return c.json({ data: providersCatalog }, 200);\n };\n\n const listMcpServersHandler: RouteHandler<typeof listMcpServerCatalogRoute> = c => {\n return c.json({ data: [...deps.mcpCatalog.list()] }, 200);\n };\n\n const listSkillsHandler: RouteHandler<typeof listSkillCatalogRoute> = c => {\n return c.json({ data: [...deps.skillCatalog.list()] }, 200);\n };\n\n const listSandboxProvidersHandler: RouteHandler<typeof listSandboxProviderCatalogRoute> = c => {\n return c.json({ data: [...deps.sandboxCatalog.list()] }, 200);\n };\n\n const router = new OpenAPIHono();\n router.openapi(listModelProviderCatalogRoute, listModelProvidersHandler);\n router.openapi(listMcpServerCatalogRoute, listMcpServersHandler);\n router.openapi(listSkillCatalogRoute, listSkillsHandler);\n router.openapi(listSandboxProviderCatalogRoute, listSandboxProvidersHandler);\n return router;\n}\n","/**\n * Discovery catalog routes (mounted at /api/v1/catalog).\n * Readable by any authenticated user — not under admin /settings.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { GetMcpServerCatalogResponseSchema } from '../schemas/mcpCatalog';\nimport { GetModelProviderCatalogResponseSchema } from '../schemas/modelCatalog';\nimport { GetSandboxProviderCatalogResponseSchema } from '../schemas/sandboxCatalog';\nimport { GetSkillCatalogResponseSchema } from '../schemas/skillCatalog';\n\nconst CATALOG_TAG = 'Catalog';\n\nexport const listModelProviderCatalogRoute = createRoute({\n method: 'get',\n path: '/model-providers',\n tags: [CATALOG_TAG],\n summary: 'Get the model catalog',\n description:\n 'Shipped model-provider presets (discovery-only). Copy into PUT /settings/model-providers to configure. ' +\n 'Includes a `custom` sentinel with `supported_reasoning_efforts`.',\n 'x-fern-sdk-group-name': ['catalog', 'modelProviders'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetModelProviderCatalogResponseSchema } },\n description: 'Shipped model-provider presets.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Not authenticated.',\n },\n },\n});\n\nexport const listMcpServerCatalogRoute = createRoute({\n method: 'get',\n path: '/mcp-servers',\n tags: [CATALOG_TAG],\n summary: 'Get the MCP catalog',\n description: 'Shipped MCP server presets (discovery-only). Copy into PUT /settings/mcp-servers to configure.',\n 'x-fern-sdk-group-name': ['catalog', 'mcpServers'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetMcpServerCatalogResponseSchema } },\n description: 'Shipped MCP server presets.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Not authenticated.',\n },\n },\n});\n\nexport const listSkillCatalogRoute = createRoute({\n method: 'get',\n path: '/skills',\n tags: [CATALOG_TAG],\n summary: 'Get the skill catalog',\n description: 'Shipped skill presets (discovery-only). Copy into PUT /settings/skills to configure.',\n 'x-fern-sdk-group-name': ['catalog', 'skills'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSkillCatalogResponseSchema } },\n description: 'Shipped skill presets.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Not authenticated.',\n },\n },\n});\n\nexport const listSandboxProviderCatalogRoute = createRoute({\n method: 'get',\n path: '/sandbox-providers',\n tags: [CATALOG_TAG],\n summary: 'Get the sandbox provider catalog',\n description:\n 'Shipped sandbox-provider presets (discovery-only). Copy into PUT /settings/sandbox-providers to configure.',\n 'x-fern-sdk-group-name': ['catalog', 'sandboxProviders'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSandboxProviderCatalogResponseSchema } },\n description: 'Shipped sandbox-provider presets.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Not authenticated.',\n },\n },\n});\n","/**\n * Shipped mcp-catalog.yaml schemas (discovery presets). Separate from\n * configured MCP server manifests in mcpServer.ts.\n */\nimport { z } from '@hono/zod-openapi';\nimport { NameSchema, uniqueNames } from './common';\nimport { McpServerDescriptionSchema, McpServerManifestAuthSchema, McpServerTypeSchema } from './mcpServer';\n\n/** Catalog entry — discovery preset the settings UI copies into a PUT body. */\nexport const CatalogMcpServerSchema = z\n .object({\n type: McpServerTypeSchema,\n name: NameSchema,\n logo: z.url().optional().describe('URL of the MCP server logo asset.'),\n url: z.url().describe('URL of the remote MCP server.'),\n description: McpServerDescriptionSchema,\n auth: McpServerManifestAuthSchema.optional(),\n })\n .strict()\n .openapi('CatalogMcpServer');\n\nexport const McpCatalogFileSchema = z\n .object({\n mcp_servers: z.array(CatalogMcpServerSchema),\n })\n .strict()\n .superRefine((file, ctx) => {\n uniqueNames(file.mcp_servers, ctx);\n });\n\nexport const GetMcpServerCatalogResponseSchema = z\n .object({\n data: z.array(CatalogMcpServerSchema),\n })\n .openapi('GetMcpServerCatalogResponse');\n\nexport type CatalogMcpServer = z.infer<typeof CatalogMcpServerSchema>;\nexport type McpCatalogFile = z.infer<typeof McpCatalogFileSchema>;\n","/**\n * Shipped model-catalog.yaml schemas (discovery presets). Separate from\n * configured provider manifests in modelProvider.ts.\n */\nimport { z } from '@hono/zod-openapi';\nimport { uniqueTypes } from './common';\nimport { ModelEntrySchema, ModelProviderTypeSchema, ReasoningEffortSchema, refineUniqueModels } from './modelProvider';\n\n/**\n * Catalog entry. Well-known types list model presets; `custom` is a sentinel that\n * carries `supported_reasoning_efforts` for the custom-provider settings form.\n */\nexport const CatalogWellKnownModelProviderTypeSchema = ModelProviderTypeSchema.exclude(['custom']).openapi(\n 'CatalogWellKnownModelProviderType',\n);\n\nexport const CatalogWellKnownModelProviderSchema = z\n .object({\n type: CatalogWellKnownModelProviderTypeSchema,\n logo: z.url().optional().describe('URL of the provider logo asset'),\n models: z.array(ModelEntrySchema).describe('Preset models'),\n })\n .strict()\n .openapi('CatalogWellKnownModelProvider');\n\nexport const CatalogCustomModelProviderSchema = z\n .object({\n type: z.literal('custom'),\n supported_reasoning_efforts: z\n .array(ReasoningEffortSchema)\n .describe('Supported reasoning-effort values for this provider'),\n })\n .strict()\n .openapi('CatalogCustomModelProvider');\n\nexport const CatalogModelProviderSchema = z\n .union([CatalogWellKnownModelProviderSchema, CatalogCustomModelProviderSchema])\n .openapi('CatalogModelProvider');\n\nexport const ModelCatalogFileSchema = z\n .object({\n providers: z.array(CatalogWellKnownModelProviderSchema),\n })\n .strict()\n .superRefine((file, ctx) => {\n uniqueTypes(file.providers, ctx);\n for (const provider of file.providers) {\n refineUniqueModels(provider.models, ctx);\n }\n });\n\nexport const GetModelProviderCatalogResponseSchema = z\n .object({\n data: z.array(CatalogModelProviderSchema),\n })\n .openapi('GetModelProviderCatalogResponse');\n\nexport type CatalogWellKnownModelProvider = z.infer<typeof CatalogWellKnownModelProviderSchema>;\nexport type CatalogModelProvider = z.infer<typeof CatalogModelProviderSchema>;\nexport type ModelCatalogFile = z.infer<typeof ModelCatalogFileSchema>;\n","/**\n * Model-provider domain + wire schemas: configured provider manifests (DB jsonb)\n * and OpenAPI request/response shapes. Catalog file schemas live on ModelCatalog.\n */\nimport { z } from '@hono/zod-openapi';\nimport { SUPPORTED_REASONING_EFFORTS, VERCEL_AI_PROVIDER_NAMES } from '@truefoundry/trueforge-core/core';\nimport { NameSchema, uniqueNames, type ResourceName } from './common';\n\n/** Every type the harness has an adapter for; a test asserts each one has a schema below. */\nexport const ModelProviderTypeSchema = z.enum(VERCEL_AI_PROVIDER_NAMES).openapi('ModelProviderType');\n\nexport type ModelProviderType = z.infer<typeof ModelProviderTypeSchema>;\n\nexport const ReasoningEffortSchema = z.enum(SUPPORTED_REASONING_EFFORTS).openapi('ReasoningEffort');\n\nexport type ReasoningEffort = z.infer<typeof ReasoningEffortSchema>;\n\nexport const ModelPropertiesSchema = z\n .object({\n context_length: z.number().int().positive().optional().describe('Maximum context window size in tokens.'),\n max_output_tokens: z.number().int().positive().optional().describe('Maximum output tokens the model can generate.'),\n reasoning_efforts: z\n .array(ReasoningEffortSchema)\n .min(1)\n .optional()\n .describe('Supported reasoning-effort values for this model.'),\n })\n .strict()\n .describe('Optional model capability metadata.')\n .openapi('ModelProperties');\n\nexport const ModelEntrySchema = z\n .object({\n model_id: z.string().min(1).describe('Upstream, provider-specific identifier sent to the provider API.'),\n name: NameSchema,\n properties: ModelPropertiesSchema,\n })\n .strict()\n .openapi('ModelEntry');\n\n/** Adds issues when two models share a `model_id` or a `name`. */\nexport function refineUniqueModels(models: { model_id: string; name: string }[], ctx: z.RefinementCtx): void {\n uniqueNames(models, ctx);\n const seenModelIds = new Set<string>();\n for (const model of models) {\n if (seenModelIds.has(model.model_id)) {\n ctx.addIssue({\n code: 'custom',\n message: `Duplicate model_id \"${model.model_id}\" — model_ids must be unique within a provider`,\n path: ['models'],\n });\n }\n seenModelIds.add(model.model_id);\n }\n}\n\nconst ModelProviderAuthSchema = z\n .object({\n api_key: z\n .string()\n .min(1)\n .describe(\n 'Provider API key. Responses are redacted; on PUT, a real value sets/rotates and a redacted value keeps the stored key.',\n ),\n })\n .strict()\n .describe('Provider authentication credentials.')\n .openapi('ModelProviderAuth');\n\nconst ModelProviderManifestBaseSchema = z\n .object({\n auth: ModelProviderAuthSchema,\n models: z.array(ModelEntrySchema).min(1).describe('Models exposed by this provider (at least one).'),\n })\n .strict();\n\n/**\n * A well-known provider has no name of its own: it is named after its type, which limits a tenant to\n * one of each because the `(tenant_id, name)` primary key replaces the row rather than adding a\n * sibling. `base_url` defaults to the adapter's endpoint and stays overridable.\n */\nfunction wellKnownProviderSchema<Type extends Exclude<ModelProviderType, 'custom'>>({\n type,\n base_url,\n}: {\n type: Type;\n base_url: string;\n}) {\n return ModelProviderManifestBaseSchema.extend({\n type: z.literal(type),\n base_url: z.url().default(base_url).describe(\"Override of the provider's default API base URL.\"),\n }).strict();\n}\n\nconst OpenAiModelProviderSchema = wellKnownProviderSchema({\n type: 'openai',\n base_url: 'https://api.openai.com/v1',\n}).openapi('OpenAIModelProvider');\n\nconst AnthropicModelProviderSchema = wellKnownProviderSchema({\n type: 'anthropic',\n base_url: 'https://api.anthropic.com/v1',\n}).openapi('AnthropicModelProvider');\n\nconst GoogleGeminiModelProviderSchema = wellKnownProviderSchema({\n type: 'google-gemini',\n base_url: 'https://generativelanguage.googleapis.com/v1beta',\n}).openapi('GoogleGeminiModelProvider');\n\nconst FireworksModelProviderSchema = wellKnownProviderSchema({\n type: 'fireworks',\n base_url: 'https://api.fireworks.ai/inference/v1',\n}).openapi('FireworksModelProvider');\n\nconst ZaiModelProviderSchema = wellKnownProviderSchema({\n type: 'zai',\n base_url: 'https://api.z.ai/api/paas/v4',\n}).openapi('ZaiModelProvider');\n\nconst MoonshotModelProviderSchema = wellKnownProviderSchema({\n type: 'moonshot',\n base_url: 'https://api.moonshot.ai/v1',\n}).openapi('MoonshotModelProvider');\n\nconst TogetherAIModelProviderSchema = wellKnownProviderSchema({\n type: 'together',\n base_url: 'https://api.together.xyz/v1',\n}).openapi('TogetherAIModelProvider');\n\nconst AlibabaModelProviderSchema = wellKnownProviderSchema({\n type: 'alibaba',\n base_url: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n}).openapi('AlibabaModelProvider');\n\n/** The one type a caller names, because only it supplies its own endpoint. */\nconst CustomModelProviderSchema = ModelProviderManifestBaseSchema.extend({\n type: z.literal('custom'),\n name: NameSchema,\n base_url: z.url().describe(\"Base URL of the provider's API.\"),\n auth: ModelProviderAuthSchema.optional(),\n})\n .strict()\n .openapi('CustomModelProvider');\n\nexport function refineModelProviderManifest(\n manifest: { models: { model_id: string; name: string }[] },\n ctx: z.RefinementCtx,\n): void {\n refineUniqueModels(manifest.models, ctx);\n}\n\nexport type ModelProperties = z.infer<typeof ModelPropertiesSchema>;\n\n/**\n * Configured provider jsonb (`model_provider.manifest`). Only `custom` carries a name, so the\n * row's key column comes from `modelProviderName` rather than from a field every type repeats.\n */\nconst ModelProviderBodySchema = z\n .discriminatedUnion('type', [\n OpenAiModelProviderSchema,\n AnthropicModelProviderSchema,\n GoogleGeminiModelProviderSchema,\n FireworksModelProviderSchema,\n ZaiModelProviderSchema,\n MoonshotModelProviderSchema,\n TogetherAIModelProviderSchema,\n AlibabaModelProviderSchema,\n CustomModelProviderSchema,\n ])\n .superRefine(refineModelProviderManifest);\n\nexport const ModelProviderManifestSchema = ModelProviderBodySchema.openapi('ModelProviderManifest');\n\n/** The row's key: only `custom` carries a name of its own. */\nexport function modelProviderName(provider: ModelProviderManifest): ResourceName {\n return provider.type === 'custom' ? provider.name : provider.type;\n}\n\n/** Settings wire item: identity column plus nested manifest. */\nexport const ModelProviderSchema = z\n .object({\n name: NameSchema,\n manifest: ModelProviderManifestSchema,\n })\n .strict()\n .openapi('ModelProvider');\n\nexport const CreateModelProviderRequestSchema = z\n .object({\n manifest: ModelProviderManifestSchema,\n })\n .strict()\n .openapi('CreateModelProviderRequest');\n\nexport const PutModelProviderRequestSchema = z\n .object({\n manifest: ModelProviderManifestSchema,\n })\n .strict()\n .openapi('PutModelProviderRequest');\n\nexport const GetModelProviderResponseSchema = z\n .object({\n data: ModelProviderSchema,\n })\n .openapi('GetModelProviderResponse');\n\nexport const ListModelProvidersResponseSchema = z\n .object({\n data: z.array(ModelProviderSchema),\n })\n .openapi('ListModelProvidersResponse');\n\n/** Provider identity on the models list read view. */\nexport const ModelListProviderSchema = z\n .object({\n name: z.string().min(1).describe('Configured provider resource name; matches the FQN prefix of `name`.'),\n })\n .strict()\n .describe('Owning configured provider.')\n .openapi('ModelListProvider');\n\n/** Read view over configured providers: FQN plus explicit provider identity for clients. */\nexport const ModelSchema = z\n .object({\n name: z\n .string()\n .describe('Fully qualified name `provider_name/model_name`, e.g. \"openai/gpt-5-6-sol\". Unique within a tenant.'),\n model_id: z.string().describe('Upstream, provider-specific identifier sent to the provider API.'),\n provider: ModelListProviderSchema,\n properties: ModelPropertiesSchema,\n })\n .strict()\n .openapi('Model');\n\nexport const ListModelsResponseSchema = z\n .object({\n data: z.array(ModelSchema),\n })\n .openapi('ListModelsResponse');\n\nexport type ModelProviderManifest = z.infer<typeof ModelProviderManifestSchema>;\nexport type ModelProvider = z.infer<typeof ModelProviderSchema>;\nexport type CreateModelProviderRequest = z.infer<typeof CreateModelProviderRequestSchema>;\nexport type PutModelProviderRequest = z.infer<typeof PutModelProviderRequestSchema>;\nexport type ModelListProvider = z.infer<typeof ModelListProviderSchema>;\nexport type Model = z.infer<typeof ModelSchema>;\n","/**\n * Shipped sandbox-catalog.yaml schemas (discovery presets). Separate from\n * configured provider manifests in sandboxProvider.ts.\n */\nimport { z } from '@hono/zod-openapi';\nimport { DaytonaSandboxProviderSchema } from './sandboxProvider';\n\n/** Catalog entry: Daytona preset without secrets. */\nexport const CatalogDaytonaSandboxProviderSchema = DaytonaSandboxProviderSchema.omit({ auth: true })\n .strict()\n .openapi('CatalogDaytonaSandboxProvider');\n\n/**\n * Catalog wire type. Single variant today (avoids one-member `oneOf` in OpenAPI).\n * Widen to a discriminated union when a second provider ships.\n */\nexport const CatalogSandboxProviderSchema = CatalogDaytonaSandboxProviderSchema;\n\nexport const SandboxCatalogFileSchema = z\n .object({\n providers: z.array(CatalogSandboxProviderSchema),\n })\n .strict();\n\nexport const GetSandboxProviderCatalogResponseSchema = z\n .object({\n data: z.array(CatalogSandboxProviderSchema),\n })\n .openapi('GetSandboxProviderCatalogResponse');\n\nexport type CatalogDaytonaSandboxProvider = z.infer<typeof CatalogDaytonaSandboxProviderSchema>;\nexport type CatalogSandboxProvider = z.infer<typeof CatalogSandboxProviderSchema>;\nexport type SandboxCatalogFile = z.infer<typeof SandboxCatalogFileSchema>;\n","/**\n * Shipped skill-catalog.yaml schemas (discovery presets). Separate from\n * configured skill manifests in skill.ts.\n */\nimport { z } from '@hono/zod-openapi';\nimport { NameSchema, uniqueNames } from './common';\nimport {\n SkillDescriptionSchema,\n SkillGitPathSchema,\n SkillGitRefSchema,\n SkillGitUrlSchema,\n SkillTypeSchema,\n} from './skill';\n\n/** Catalog entry — discovery preset the settings UI copies into a PUT body. */\nexport const CatalogSkillSchema = z\n .object({\n type: SkillTypeSchema,\n name: NameSchema,\n url: SkillGitUrlSchema,\n path: SkillGitPathSchema.optional(),\n ref: SkillGitRefSchema,\n description: SkillDescriptionSchema,\n })\n .strict()\n .openapi('CatalogSkill');\n\nexport const SkillCatalogFileSchema = z\n .object({\n skills: z.array(CatalogSkillSchema),\n })\n .strict()\n .superRefine((file, ctx) => {\n uniqueNames(file.skills, ctx);\n });\n\nexport const GetSkillCatalogResponseSchema = z\n .object({\n data: z.array(CatalogSkillSchema),\n })\n .openapi('GetSkillCatalogResponse');\n\nexport type CatalogSkill = z.infer<typeof CatalogSkillSchema>;\nexport type SkillCatalogFile = z.infer<typeof SkillCatalogFileSchema>;\n","/**\n * Configured skill domain + wire schemas: the `skill.manifest` JSONB document\n * and admin/chat list projections. Catalog file schemas live in skillCatalog.ts.\n *\n * Git field rules mirror harness git skill mounts (GitHub/GitLab HTTPS url,\n * path/ref constraints) so settings documents stay mount-compatible. Identity\n * uses NameSchema like model providers / MCP servers.\n */\nimport { z } from '@hono/zod-openapi';\nimport { NameSchema } from './common';\n\n/** Kind of skill. Extend when non-git kinds ship. */\nexport const SkillTypeSchema = z.enum(['git']).openapi('SkillType');\n\n// GitHub is exactly owner/repo; GitLab allows subgroups (group[/subgroup...]/project, ≥2 segments).\nconst GIT_URL_REGEX =\n /^https:\\/\\/(github\\.com\\/[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+|gitlab\\.com\\/[A-Za-z0-9._-]+(?:\\/[A-Za-z0-9._-]+)+)(\\/|\\.git)?$/;\nconst GIT_REF_REGEX = /^[A-Za-z0-9._\\-/]+$/;\nconst SKILL_PATH_REGEX = /^[A-Za-z0-9._\\-/]+$/;\nconst hasParentTraversal = (value: string): boolean => value.split('/').includes('..');\n\n/** Shared with catalog presets — GitHub/GitLab HTTPS only. */\nexport const SkillGitUrlSchema = z\n .string()\n .trim()\n .min(1)\n .regex(GIT_URL_REGEX, 'Must be a GitHub or GitLab HTTPS URL')\n .refine(v => !hasParentTraversal(v), 'URL must not contain \"..\" segments')\n .describe('Full HTTPS URL of a GitHub or GitLab repository.');\n\n/** Shared with catalog presets. Omit to use the repository root. */\nexport const SkillGitPathSchema = z\n .string()\n .trim()\n .min(1)\n .regex(SKILL_PATH_REGEX, 'Path may only contain letters, numbers, \".\", \"_\", \"-\", and \"/\"')\n .refine(v => !hasParentTraversal(v), 'Path must not contain \"..\" segments')\n .refine(v => !v.split('/').includes('.'), 'Path must not contain \".\" segments')\n .refine(v => v.replace(/^\\/+|\\/+$/g, '').length > 0, 'Path must reference a subdirectory, not only slashes')\n .describe('Path to the skill directory within the repository. Omit to use the repository root.');\n\n/**\n * Shared with catalog presets. Required on configured skills (no silent HEAD default).\n */\nexport const SkillGitRefSchema = z\n .string()\n .trim()\n .min(1)\n .regex(GIT_REF_REGEX, 'Ref may only contain letters, numbers, \".\", \"_\", \"-\", and \"/\"')\n .refine(v => !hasParentTraversal(v), 'Ref must not contain \"..\" segments')\n .refine(v => v.replace(/^\\/+|\\/+$/g, '').length > 0, 'Ref must not consist only of slashes')\n .describe('Git ref — branch name, tag, or commit SHA.');\n\nexport const SkillDescriptionSchema = z\n .string()\n .trim()\n .min(1)\n .describe('Concise guidance for when the agent should use the skill.');\n\n/** Configured skill document persisted as `skill.manifest`. */\nexport const SkillManifestObjectSchema = z\n .object({\n type: SkillTypeSchema,\n name: NameSchema,\n url: SkillGitUrlSchema,\n path: SkillGitPathSchema.optional(),\n ref: SkillGitRefSchema,\n description: SkillDescriptionSchema,\n })\n .strict();\n\nexport const SkillManifestSchema = SkillManifestObjectSchema.openapi('SkillManifest');\n\n/** Admin/settings wire view: identity column plus nested manifest. */\nexport const ConfiguredSkillSchema = z\n .object({\n name: NameSchema,\n manifest: SkillManifestSchema,\n })\n .strict()\n .openapi('ConfiguredSkill');\n\nexport const CreateSkillRequestSchema = z\n .object({\n manifest: SkillManifestSchema,\n })\n .strict()\n .openapi('CreateSkillRequest');\n\nexport const PutSkillRequestSchema = z\n .object({\n manifest: SkillManifestSchema,\n })\n .strict()\n .openapi('PutSkillRequest');\n\nexport const GetSkillResponseSchema = z.object({ data: ConfiguredSkillSchema }).openapi('GetSkillResponse');\nexport const ListSkillsResponseSchema = z\n .object({ data: z.array(ConfiguredSkillSchema) })\n .openapi('ListSkillsResponse');\n\n/** Chat/composer read view — discovery fields only. */\nexport const SkillReadEntrySchema = z\n .object({\n name: NameSchema,\n description: SkillDescriptionSchema,\n })\n .strict()\n .openapi('SkillReadEntry');\n\nexport const ListAvailableSkillsResponseSchema = z\n .object({ data: z.array(SkillReadEntrySchema) })\n .openapi('ListAvailableSkillsResponse');\n\nexport type SkillType = z.infer<typeof SkillTypeSchema>;\nexport type SkillManifest = z.infer<typeof SkillManifestSchema>;\nexport type ConfiguredSkill = z.infer<typeof ConfiguredSkillSchema>;\nexport type CreateSkillRequest = z.infer<typeof CreateSkillRequestSchema>;\nexport type PutSkillRequest = z.infer<typeof PutSkillRequestSchema>;\nexport type SkillReadEntry = z.infer<typeof SkillReadEntrySchema>;\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { extractErrorLogFields, McpConnectionError } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport { completeMcpAuthorization } from '../mcp/auth/mcpDcr';\nimport type { IOAuthClientStore, IOAuthTokenStore, OAuthPendingAuthorization } from '../mcp/auth/types';\nimport { mcpOAuthCallbackRoute } from '../routes/mcpOAuthRoutes';\n\nexport interface McpOAuthRouterDeps<TTransaction> {\n tokenStore: IOAuthTokenStore<TTransaction>;\n mcpServerStore: IOAuthClientStore<TTransaction>;\n logger: Logger;\n}\n\ntype McpOAuthCallbackContext = Parameters<RouteHandler<typeof mcpOAuthCallbackRoute>>[0];\n\n/** Landing URL with the outcome appended to whatever query params it already carries. */\nfunction callbackLandingUrl(params: { redirectUrl: string; isSuccess: boolean; reason?: string }): string {\n const url = new URL(params.redirectUrl);\n url.searchParams.set('isSuccess', String(params.isSuccess));\n if (params.reason) {\n url.searchParams.set('reason', params.reason);\n }\n return url.href;\n}\n\n/**\n * JSON is the answer whenever there is no landing URL to return to: authorize was called without\n * `redirect_url`, or the pending row that carried it is gone (TTL expired, already redeemed, unknown\n * `state`) — the OAuth callback URL is never a page we send the user to on purpose.\n */\nfunction callbackSuccess(params: { c: McpOAuthCallbackContext; pending: OAuthPendingAuthorization }) {\n const redirectUrl = params.pending.redirectUrl;\n if (redirectUrl) {\n return params.c.redirect(callbackLandingUrl({ redirectUrl, isSuccess: true }), 302);\n }\n return params.c.json({ success: true as const }, 200);\n}\n\nfunction callbackFailure(params: {\n c: McpOAuthCallbackContext;\n pending: OAuthPendingAuthorization | undefined;\n message: string;\n jsonStatus?: 400 | 500;\n}) {\n const redirectUrl = params.pending?.redirectUrl;\n if (redirectUrl) {\n return params.c.redirect(callbackLandingUrl({ redirectUrl, isSuccess: false, reason: params.message }), 302);\n }\n return params.c.json({ error: { message: params.message } }, params.jsonStatus ?? 400);\n}\n\n/** Shared OAuth callback (mounted at /api/v1/mcp-servers/oauth). */\nexport function createMcpOAuthRouter<TTransaction>(deps: McpOAuthRouterDeps<TTransaction>) {\n const callbackHandler: RouteHandler<typeof mcpOAuthCallbackRoute> = async c => {\n const { state, code, error, error_description: errorDescription } = c.req.valid('query');\n\n // Claimed up front: this row carries the FE landing URL every branch below returns to, and\n // claiming it atomically means a duplicate callback loses the race.\n const pending = await deps.tokenStore.consumePendingAuthorization({ state });\n if (!pending) {\n deps.logger.warn('MCP OAuth callback has no pending authorization', { state, error, errorDescription });\n return callbackFailure({ c, pending, message: 'Unknown or expired OAuth state' });\n }\n\n if (error) {\n deps.logger.warn('MCP OAuth callback returned an error', { state, error, errorDescription });\n return callbackFailure({ c, pending, message: error });\n }\n\n if (!code) {\n return callbackFailure({ c, pending, message: 'OAuth callback is missing both `code` and `error`' });\n }\n\n try {\n await completeMcpAuthorization({\n tokenStore: deps.tokenStore,\n mcpServerStore: deps.mcpServerStore,\n pending,\n code,\n });\n } catch (err) {\n // Only a known MCP failure is safe to show the user; anything else gets a generic reason.\n if (err instanceof McpConnectionError) {\n deps.logger.warn('MCP OAuth callback token exchange failed', extractErrorLogFields(err));\n return callbackFailure({ c, pending, message: err.message });\n }\n deps.logger.error('MCP OAuth callback unexpected failure', extractErrorLogFields(err));\n return callbackFailure({ c, pending, message: 'Internal server error', jsonStatus: 500 });\n }\n\n return callbackSuccess({ c, pending });\n };\n\n const router = new OpenAPIHono();\n router.openapi(mcpOAuthCallbackRoute, callbackHandler);\n return router;\n}\n","import { createRoute } from '@hono/zod-openapi';\nimport { OAuthCallbackQuerySchema, OAuthCallbackSuccessSchema } from '../schemas/auth';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\n\nconst MCP_OAUTH_TAG = 'MCP OAuth';\n\nexport const mcpOAuthCallbackRoute = createRoute({\n method: 'get',\n path: '/callback',\n tags: [MCP_OAUTH_TAG],\n summary: 'OAuth callback for MCP authorization',\n description:\n 'Browser redirect target for MCP server OAuth. The authorization server redirects here with `code`/`state` (or `error`). ' +\n 'Exchanges the code for tokens, then either returns JSON or redirects to the `redirect_url` supplied at authorize time. ' +\n 'Not called by the SDK — browsers hit this URL directly.',\n // Browser-redirect target hit directly by the authorization server, never called by SDK.\n 'x-fern-ignore': true,\n request: {\n query: OAuthCallbackQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: OAuthCallbackSuccessSchema } },\n description: 'Token exchanged successfully and no `redirect_url` was given at authorize time.',\n },\n 302: {\n description:\n 'Redirect to the `redirect_url` given at authorize time, with `isSuccess` (and `reason` when it failed) appended to its existing query params.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'IdP `error`, unknown/expired `state`, token exchange failure, or `code`/`error` both missing.',\n },\n 500: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Unexpected failure during token exchange.',\n },\n },\n});\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { extractErrorLogFields, isAuthRequired, McpConnectionError, RemoteMCP } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport type { ResolveUserContext } from '../auth/identity';\nimport configuration from '../config';\nimport { McpServerNameConflictError, type IMcpServerStore, type McpServerRecord } from '../db/mcpServerStore';\nimport type { WithTransaction } from '../db/transaction';\nimport { createMcpOAuthClient, isMcpAuthRequired, resolveMcpAuth } from '../mcp/auth/mcpDcr';\nimport { mcpOAuthCallbackUrl, validateRedirectUris } from '../mcp/auth/mcpOAuthHelpers';\nimport type { IOAuthTokenStore, OAuthClientRecord, OAuthToken } from '../mcp/auth/types';\nimport {\n authorizeMcpServerRoute,\n createMcpServerRoute,\n deleteAuthorizeMcpServerRoute,\n getMcpServerRoute,\n listAvailableMcpServersRoute,\n listMcpServersRoute,\n listMcpServerToolsRoute,\n putMcpServerRoute,\n} from '../routes/mcpServerRoutes';\nimport { getMcpConnection } from '../runtime/sessionResources';\nimport type {\n ConfiguredMcpServer,\n CreateMcpServerRequest,\n McpAuthStatus,\n McpServerManifest,\n McpServerReadEntry,\n PutMcpServerRequest,\n} from '../schemas/mcpServer';\nimport { resolveMcpAuthStatus } from '../schemas/mcpServer';\nimport { MissingStoredSecretError, resolveStoredSecretValue, toRedactedSecretValue } from '../utils/secretRedaction';\nimport { TENANT_ID } from './sessions';\n\nexport interface McpServersRouterDeps<TTransaction> {\n mcpServerStore: IMcpServerStore<TTransaction>;\n tokenStore: IOAuthTokenStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n logger: Logger;\n resolveUserContext: ResolveUserContext;\n}\n\n/** Omits keys whose value is `undefined` so wire objects satisfy JSONValue index signatures. */\nfunction omitUndefinedEntries(obj: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value !== undefined) {\n out[key] = value;\n }\n }\n return out;\n}\n\n/** Settings wire view: redact header secrets; leave DCR / no-auth manifests unchanged. */\nfunction redactMcpServerManifest(manifest: McpServerManifest): McpServerManifest {\n if (manifest.auth?.type !== 'header') {\n return manifest;\n }\n const headers: Record<string, string> = {};\n for (const [name, value] of Object.entries(manifest.auth.headers)) {\n headers[name] = toRedactedSecretValue(value);\n }\n return {\n ...manifest,\n auth: { type: 'header', headers },\n };\n}\n\n/**\n * Strict PUT merge for `auth.type === 'header'`: each header value is always required;\n * redacted values keep the stored secret for the same header name.\n * @throws {MissingStoredSecretError} when keep is requested without a stored header value\n */\nfunction resolveMcpServerManifestForWrite({\n incoming,\n existing,\n}: {\n incoming: McpServerManifest;\n existing: McpServerManifest | undefined;\n}): McpServerManifest {\n if (incoming.auth?.type !== 'header') {\n return incoming;\n }\n const existingHeaders = existing?.auth?.type === 'header' ? existing.auth.headers : undefined;\n const headers: Record<string, string> = {};\n for (const [name, value] of Object.entries(incoming.auth.headers)) {\n headers[name] = resolveStoredSecretValue({\n incoming: value,\n existing: existingHeaders?.[name],\n });\n }\n return {\n ...incoming,\n auth: { type: 'header', headers },\n };\n}\n\n/**\n * `token` is the calling user's DCR access token for this server (keyed by `record.id` +\n * `userRef`), or undefined for header/no-auth servers and DCR servers that have never\n * authorized for this user. Only DCR reads it.\n */\nfunction toConfiguredMcpServer({\n record,\n token,\n}: {\n record: McpServerRecord;\n token: OAuthToken | undefined;\n}): ConfiguredMcpServer {\n return {\n name: record.name,\n manifest: redactMcpServerManifest(record.manifest),\n auth_status: resolveMcpAuthStatus({\n manifest: record.manifest,\n ...(token !== undefined ? { token } : {}),\n }),\n };\n}\n\nfunction toMcpServerReadEntry({\n record,\n token,\n}: {\n record: McpServerRecord;\n token: OAuthToken | undefined;\n}): McpServerReadEntry {\n const authType = record.manifest.auth?.type;\n return {\n name: record.name,\n url: record.manifest.url,\n ...(authType !== undefined ? { auth: { type: authType } } : {}),\n auth_status: resolveMcpAuthStatus({\n manifest: record.manifest,\n ...(token !== undefined ? { token } : {}),\n }),\n };\n}\n\n/** Admin/settings MCP CRUD (mounted at /api/v1/settings/mcp-servers). */\nexport function createSettingsMcpServersRouter<TTransaction>(deps: McpServersRouterDeps<TTransaction>) {\n const listHandler: RouteHandler<typeof listMcpServersRoute> = async c => {\n const userRef = deps.resolveUserContext(c).userRef;\n const records = await deps.mcpServerStore.listServers({ tenant_id: TENANT_ID, names: undefined });\n // Only DCR servers have tokens; batch the lookup for this user.\n const dcrIds = records.filter(record => record.manifest.auth?.type === 'dcr').map(record => record.id);\n const tokens = await deps.tokenStore.getTokens({ ids: dcrIds, userRef });\n return c.json(\n { data: records.map(record => toConfiguredMcpServer({ record, token: tokens.get(record.id) })) },\n 200,\n );\n };\n\n const getHandler: RouteHandler<typeof getMcpServerRoute> = async c => {\n const { name } = c.req.valid('param');\n const userRef = deps.resolveUserContext(c).userRef;\n const record = await deps.mcpServerStore.getServer({ tenant_id: TENANT_ID, name });\n if (!record) {\n return c.json({ error: { message: `MCP server not found: ${name}` } }, 404);\n }\n let token: OAuthToken | undefined;\n if (record.manifest.auth?.type === 'dcr') {\n token = await deps.tokenStore.getToken({ id: record.id, userRef });\n }\n return c.json({ data: toConfiguredMcpServer({ record, token }) }, 200);\n };\n\n const createHandler: RouteHandler<typeof createMcpServerRoute> = async c => {\n const body: CreateMcpServerRequest = c.req.valid('json');\n const incomingManifest = body.manifest;\n\n // DCR finishes before the txn (remote I/O stays out of withTransaction on create).\n let dcrClientToSave: OAuthClientRecord | undefined;\n if (incomingManifest.auth?.type === 'dcr') {\n try {\n dcrClientToSave = await createMcpOAuthClient({\n mcpServerUrl: incomingManifest.url,\n mcpServerName: incomingManifest.name,\n redirectUri: mcpOAuthCallbackUrl(),\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n });\n } catch (error) {\n deps.logger.error(\n `DCR client registration failed for \"${incomingManifest.name}\"; rejecting create`,\n extractErrorLogFields(error),\n );\n const message = error instanceof Error ? error.message : 'Failed to register OAuth client for this MCP server';\n return c.json({ error: { message } }, 422);\n }\n }\n\n let manifest: McpServerManifest;\n try {\n manifest = resolveMcpServerManifestForWrite({\n incoming: incomingManifest,\n existing: undefined,\n });\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'Header secret is required' } }, 400);\n }\n throw error;\n }\n\n try {\n const record = await deps.withTransaction(async transaction => {\n const saved = await deps.mcpServerStore.createServer(\n {\n tenant_id: TENANT_ID,\n name: manifest.name,\n manifest,\n },\n transaction,\n );\n if (dcrClientToSave !== undefined) {\n await deps.mcpServerStore.saveClient({ id: saved.id, record: dcrClientToSave }, transaction);\n }\n return saved;\n });\n\n return c.json({ data: toConfiguredMcpServer({ record, token: undefined }) }, 201);\n } catch (error) {\n if (error instanceof McpServerNameConflictError) {\n return c.json({ error: { message: error.message } }, 409);\n }\n throw error;\n }\n };\n\n const putHandler: RouteHandler<typeof putMcpServerRoute> = async c => {\n const userRef = deps.resolveUserContext(c).userRef;\n const body: PutMcpServerRequest = c.req.valid('json');\n const incomingManifest = body.manifest;\n\n try {\n // Lock → resolve secrets → DCR (if needed) → upsert + saveClient in one txn.\n // Exception: MCP put may run `createMcpOAuthClient` inside the write txn that persists\n // `oauth_server`/`oauth_client` so a failed registration rolls back the server write.\n // Bounded by `MCP_OAUTH_HTTP_TIMEOUT_MS` (15s);\n // must stay under `POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS` (30s).\n const record = await deps.withTransaction(async transaction => {\n const existing = await deps.mcpServerStore.getServerForUpdate(\n { tenant_id: TENANT_ID, name: incomingManifest.name },\n transaction,\n );\n const manifest = resolveMcpServerManifestForWrite({\n incoming: incomingManifest,\n existing: existing?.manifest,\n });\n\n let dcrClientToSave: OAuthClientRecord | undefined;\n const urlChanged =\n existing !== undefined && existing.manifest.url !== manifest.url && manifest.auth?.type === 'dcr';\n if (manifest.auth?.type === 'dcr') {\n const existingClient = existing\n ? await deps.mcpServerStore.getClient({ id: existing.id }, transaction)\n : undefined;\n // Register when: brand-new server, client was cleared (e.g. invalid_client), or MCP URL changed\n // (resource/AS may differ; reuse would keep stale oauth_server/client for the old AS).\n const needsDcr = existingClient === undefined || urlChanged;\n if (needsDcr) {\n dcrClientToSave = await createMcpOAuthClient({\n mcpServerUrl: manifest.url,\n mcpServerName: manifest.name,\n redirectUri: mcpOAuthCallbackUrl(),\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n });\n }\n }\n\n const saved = await deps.mcpServerStore.upsertServer(\n {\n tenant_id: TENANT_ID,\n name: manifest.name,\n manifest,\n },\n transaction,\n );\n if (dcrClientToSave !== undefined) {\n // New DCR registration (create, missing client, or URL change): replace the shared client.\n await deps.mcpServerStore.saveClient({ id: saved.id, record: dcrClientToSave }, transaction);\n }\n if (urlChanged) {\n // URL is the OAuth resource/audience — drop every user's tokens and in-flight authorizes.\n await deps.tokenStore.deleteTokensForServer({ id: saved.id }, transaction);\n await deps.tokenStore.deletePendingAuthorizationsForServer({ id: saved.id }, transaction);\n }\n return saved;\n });\n\n // A re-upsert preserves `id`, so a DCR server may already carry a token from a prior authorize\n // (unless this PUT changed the URL and cleared all tokens above).\n const token =\n record.manifest.auth?.type === 'dcr' ? await deps.tokenStore.getToken({ id: record.id, userRef }) : undefined;\n return c.json({ data: toConfiguredMcpServer({ record, token }) }, 200);\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'Header secret is required' } }, 400);\n }\n if (error instanceof McpConnectionError) {\n deps.logger.error(\n `DCR client registration failed for \"${incomingManifest.name}\"; rejecting upsert`,\n extractErrorLogFields(error),\n );\n return c.json({ error: { message: error.message } }, 422);\n }\n throw error;\n }\n };\n\n const listToolsHandler: RouteHandler<typeof listMcpServerToolsRoute> = async c => {\n const { name } = c.req.valid('param');\n const userRef = deps.resolveUserContext(c).userRef;\n // Same url + header resolution as turn execution (DCR via resolveMcpAuth, header/no-auth static).\n const connection = await getMcpConnection({\n tenant_id: TENANT_ID,\n name,\n store: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n userRef,\n });\n if (connection === undefined) {\n return c.json({ error: { message: `MCP server not found: ${name}` } }, 404);\n }\n const remote = new RemoteMCP({\n id: name,\n name,\n url: connection.url,\n headers: connection.headers,\n requestTimeoutMs: configuration.MCP_REQUEST_TIMEOUT_MS,\n connectTimeoutMs: configuration.MCP_CONNECT_TIMEOUT_MS,\n logger: deps.logger,\n signal: c.req.raw.signal,\n });\n try {\n const response = await remote.listTools();\n if (isAuthRequired(response)) {\n return c.json({ error: { message: `MCP server \"${name}\" requires authentication` } }, 422);\n }\n const data = response.result.tools.map(tool => omitUndefinedEntries({ ...tool }));\n return c.json({ data }, 200);\n } catch (error) {\n if (error instanceof McpConnectionError) {\n deps.logger.warn(`MCP tools/list failed for \"${name}\"`, extractErrorLogFields(error));\n if (error.statusCode === 401) {\n return c.json({ error: { message: error.message } }, 422);\n }\n return c.json({ error: { message: error.message } }, 502);\n }\n throw error;\n }\n };\n\n const router = new OpenAPIHono();\n router.openapi(listMcpServersRoute, listHandler);\n router.openapi(createMcpServerRoute, createHandler);\n router.openapi(putMcpServerRoute, putHandler);\n // `/{name}/tools` before `/{name}` so the tools suffix is not swallowed.\n router.openapi(listMcpServerToolsRoute, listToolsHandler);\n router.openapi(getMcpServerRoute, getHandler);\n return router;\n}\n\n/** List + authorize (mounted at /api/v1/mcp-servers). */\nexport function createMcpServersRouter<TTransaction>(deps: McpServersRouterDeps<TTransaction>) {\n const authorizeHandler: RouteHandler<typeof authorizeMcpServerRoute> = async c => {\n const { name } = c.req.valid('param');\n const { redirect_url: redirectUrl } = c.req.valid('query');\n const userRef = deps.resolveUserContext(c).userRef;\n const record = await deps.mcpServerStore.getServer({ tenant_id: TENANT_ID, name });\n if (!record) {\n return c.json({ error: { message: `MCP server not found: ${name}` } }, 404);\n }\n\n if (record.manifest.auth?.type !== 'dcr') {\n return c.json(resolveMcpAuthStatus({ manifest: record.manifest }), 200);\n }\n\n try {\n if (redirectUrl) {\n validateRedirectUris({ redirectUris: [redirectUrl] });\n }\n // Reuses a usable/refreshable token when present; only builds an auth URL when needed.\n // Client is usually already registered at create/put; concurrent Connect races are harmless\n // (last saveClient wins; rare orphan AS registration).\n const result = await resolveMcpAuth({\n tokenStore: deps.tokenStore,\n mcpServerStore: deps.mcpServerStore,\n serverId: record.id,\n userRef,\n mcpServerUrl: record.manifest.url,\n mcpServerName: record.name,\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n ...(redirectUrl !== undefined ? { redirectUrl } : {}),\n });\n const authStatus: McpAuthStatus = isMcpAuthRequired(result)\n ? { status: 'auth_required', authorization_url: result.authUrl.href }\n : { status: 'authenticated' };\n return c.json(authStatus, 200);\n } catch (error) {\n if (error instanceof McpConnectionError) {\n deps.logger.warn(`MCP authorize failed for \"${name}\"`, extractErrorLogFields(error));\n if (error.statusCode === 400) {\n return c.json({ error: { message: error.message } }, 400);\n }\n if (error.statusCode === 422) {\n return c.json({ error: { message: error.message } }, 422);\n }\n if (error.statusCode === 424) {\n return c.json({ error: { message: error.message } }, 424);\n }\n return c.json({ error: { message: error.message } }, 500);\n }\n deps.logger.error(`MCP authorize unexpected failure for \"${name}\"`, extractErrorLogFields(error));\n return c.json({ error: { message: 'Internal server error' } }, 500);\n }\n };\n\n const deleteAuthorizeHandler: RouteHandler<typeof deleteAuthorizeMcpServerRoute> = async c => {\n const { name } = c.req.valid('param');\n const userRef = deps.resolveUserContext(c).userRef;\n const record = await deps.mcpServerStore.getServer({ tenant_id: TENANT_ID, name });\n if (!record) {\n return c.json({ error: { message: `MCP server not found: ${name}` } }, 404);\n }\n // DCR: drop this user's token only — keep oauth_server / oauth_client so re-authorize can skip DCR.\n // Header / no-auth: no-op.\n if (record.manifest.auth?.type === 'dcr') {\n await deps.tokenStore.deleteToken({ id: record.id, userRef });\n }\n return c.json({ data: toConfiguredMcpServer({ record, token: undefined }) }, 200);\n };\n\n const router = new OpenAPIHono();\n router.openapi(listAvailableMcpServersRoute, async c => {\n const userRef = deps.resolveUserContext(c).userRef;\n const records = await deps.mcpServerStore.listServers({ tenant_id: TENANT_ID, names: undefined });\n const dcrIds = records.filter(record => record.manifest.auth?.type === 'dcr').map(record => record.id);\n const tokens = await deps.tokenStore.getTokens({ ids: dcrIds, userRef });\n return c.json(\n {\n data: records.map(record => toMcpServerReadEntry({ record, token: tokens.get(record.id) })),\n },\n 200,\n );\n });\n router.openapi(authorizeMcpServerRoute, authorizeHandler);\n router.openapi(deleteAuthorizeMcpServerRoute, deleteAuthorizeHandler);\n return router;\n}\n","/**\n * DB-backed MCP server route definitions.\n * Admin routes mount at /api/v1/settings/mcp-servers; the chat list and\n * authorize routes mount at /api/v1/mcp-servers.\n */\nimport { createRoute, z } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport {\n CreateMcpServerRequestSchema,\n GetMcpServerResponseSchema,\n ListAvailableMcpServersResponseSchema,\n ListMcpServersResponseSchema,\n McpAuthStatusSchema,\n PutMcpServerRequestSchema,\n} from '../schemas/mcpServer';\n\nconst MCP_SERVERS_TAG = 'MCP Servers';\n\n/** Chat/composer read view — mounted at /api/v1/mcp-servers (not under settings). */\nexport const listAvailableMcpServersRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [MCP_SERVERS_TAG],\n summary: 'List MCP servers for chat',\n description: 'MCP servers as a slim name/url list for the composer. No auth or auth_status.',\n 'x-fern-sdk-group-name': ['mcpServers'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListAvailableMcpServersResponseSchema } },\n description: 'All MCP servers (chat projection).',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n\nexport const listMcpServersRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [MCP_SERVERS_TAG],\n summary: 'List MCP servers',\n description:\n 'All MCP servers with nested auth_status (settings / admin projection). Header auth values are redacted.',\n 'x-fern-sdk-group-name': ['settings', 'mcpServers'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListMcpServersResponseSchema } },\n description: 'All MCP servers',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the caller is authenticated but not an admin.',\n },\n },\n});\n\nconst McpServerNameParamsSchema = z.object({\n name: z.string().min(1).describe('MCP server name.'),\n});\n\nexport const getMcpServerRoute = createRoute({\n method: 'get',\n path: '/{name}',\n tags: [MCP_SERVERS_TAG],\n summary: 'Get a single MCP server by name',\n description:\n 'A single MCP server by name, with nested auth_status (settings / admin projection). Header auth values are redacted.',\n 'x-fern-sdk-group-name': ['settings', 'mcpServers'],\n 'x-fern-sdk-method-name': 'get',\n request: {\n params: McpServerNameParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetMcpServerResponseSchema } },\n description: 'The MCP server',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'MCP server not found.',\n },\n },\n});\n\nexport const createMcpServerRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [MCP_SERVERS_TAG],\n summary: 'Create an MCP server',\n description:\n 'Creates an MCP server by `name`. Fails if `name` is already taken. Runs DCR registration when `auth.type` is `dcr`. ' +\n 'Header secrets: real value required; redacted with no stored value returns 400.',\n 'x-fern-sdk-group-name': ['settings', 'mcpServers'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateMcpServerRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetMcpServerResponseSchema } },\n description: 'The created MCP server with auth_status',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted header secret with no stored value to keep.',\n },\n 409: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'An MCP server with this name already exists.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The server cannot satisfy `auth.type: dcr` (e.g. it advertises no registration_endpoint).',\n },\n },\n});\n\nexport const putMcpServerRoute = createRoute({\n method: 'put',\n path: '/',\n tags: [MCP_SERVERS_TAG],\n summary: 'Create or replace an MCP server',\n description:\n 'Create or replace by `name`. Does not start DCR or change oauth client columns. ' +\n 'Header secrets: real value sets/rotates; redacted keeps existing (400 if none).',\n 'x-fern-sdk-group-name': ['settings', 'mcpServers'],\n 'x-fern-sdk-method-name': 'upsert',\n request: {\n body: {\n content: { 'application/json': { schema: PutMcpServerRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetMcpServerResponseSchema } },\n description: 'The saved MCP server with auth_status',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted header secret with no stored value to keep.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The server cannot satisfy `auth.type: dcr` (e.g. it advertises no registration_endpoint).',\n },\n },\n});\n\nconst ListMcpServerToolsResponseSchema = z\n .object({\n // TODO: Type tools/list entries to the MCP tool shape (name, description, inputSchema, …) for OpenAPI quality.\n data: z\n .array(z.record(z.string(), z.unknown()))\n .describe('MCP `tools/list` entries, passed through verbatim from the MCP server.'),\n })\n .openapi('ListMcpServerToolsResponse');\n\nexport const listMcpServerToolsRoute = createRoute({\n method: 'get',\n path: '/{name}/tools',\n tags: [MCP_SERVERS_TAG],\n summary: 'List tools of an MCP server',\n 'x-fern-sdk-group-name': ['settings', 'mcpServers'],\n 'x-fern-sdk-method-name': 'list_tools',\n description: 'All tools exposed by the given MCP server (non-paginated), as returned by the MCP `tools/list` call.',\n request: {\n params: McpServerNameParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListMcpServerToolsResponseSchema } },\n description: 'All tools of the MCP server.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Harness session login required.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'MCP server not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The MCP server requires authentication (does not trigger browser OIDC login).',\n },\n 502: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The MCP server could not be reached or returned an error.',\n },\n },\n});\n\nconst McpAuthorizeQuerySchema = z.object({\n redirect_url: z\n .url()\n .optional()\n .describe('Optional FE landing URL the OAuth callback redirects to, with `isSuccess`/`reason` appended.'),\n});\n\nexport const authorizeMcpServerRoute = createRoute({\n method: 'get',\n path: '/{name}/authorize',\n tags: [MCP_SERVERS_TAG],\n summary: 'Start (or short-circuit) the auth flow for an MCP server',\n 'x-fern-sdk-group-name': ['mcpServers'],\n 'x-fern-sdk-method-name': 'authorize',\n description:\n 'For servers without auth returns not_required, and for header credentials returns authenticated ' +\n '(no browser flow). For auth.type dcr, returns authenticated when a usable (or refreshable) token ' +\n 'exists; otherwise runs DCR if needed and returns auth_required with an authorization URL. ' +\n 'Optional redirect_url is where the OAuth callback then redirects the browser; without it the callback returns JSON.',\n request: {\n params: McpServerNameParamsSchema,\n query: McpAuthorizeQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: McpAuthStatusSchema } },\n description: 'Either already authenticated, or an authorization URL to redirect to.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid redirect_url.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'MCP server not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'DCR could not be completed for this server (e.g. it lacks a registration_endpoint).',\n },\n 424: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The authorization server failed dynamic client registration or authorization startup.',\n },\n 500: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Server misconfiguration (e.g. PUBLIC_BASE_URL unset).',\n },\n },\n});\n\nexport const deleteAuthorizeMcpServerRoute = createRoute({\n method: 'delete',\n path: '/{name}/authorize',\n tags: [MCP_SERVERS_TAG],\n summary: 'Disconnect OAuth for an MCP server',\n 'x-fern-sdk-group-name': ['mcpServers'],\n 'x-fern-sdk-method-name': 'delete_authorize',\n description:\n 'For auth.type dcr, deletes the stored OAuth token and returns the server with auth_status ' +\n 'auth_required, keeping the dynamically registered OAuth client so the next authorize can reuse it. ' +\n 'No-op for header or no-auth servers (returns the server unchanged).',\n request: {\n params: McpServerNameParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetMcpServerResponseSchema } },\n description: 'The MCP server after disconnect (auth_required for dcr).',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'MCP server not found.',\n },\n },\n});\n","/**\n * Redact secret strings for settings API responses and detect/merge\n * redacted writebacks so clients can keep stored secrets without resending them.\n */\n\nexport const SECRET_REDACTION = '***REDACTED***';\nconst MIN_LENGTH_FOR_PREFIX_SUFFIX = 10;\n\n/** Response mask: prefix/suffix for longer secrets; full mask when too short to hide. */\nexport function toRedactedSecretValue(secret: string): string {\n if (secret.length < MIN_LENGTH_FOR_PREFIX_SUFFIX) {\n return SECRET_REDACTION;\n }\n return `${secret.slice(0, 3)}-${SECRET_REDACTION}-${secret.slice(-3)}`;\n}\n\n/**\n * True when the client sent a redacted stand-in from a prior GET.\n */\nexport function isRedactedSecretValue(value: string): boolean {\n return value.includes(SECRET_REDACTION);\n}\n\n/**\n * Thrown when a redacted keep is requested but no stored secret exists\n * (create with redacted stand-in, or keep for a missing field/header).\n * Callers map this to a domain-specific 400 message.\n */\nexport class MissingStoredSecretError extends Error {\n constructor() {\n super('Missing stored secret');\n this.name = 'MissingStoredSecretError';\n }\n}\n\n/**\n * Resolve the secret to persist for a strict PUT field (always a non-empty string).\n * Real secrets are stored as-is; redacted stand-ins keep `existing` when present.\n * @throws {MissingStoredSecretError} when keep is requested with no stored secret\n */\nexport function resolveStoredSecretValue({\n incoming,\n existing,\n}: {\n incoming: string;\n existing: string | undefined;\n}): string {\n if (!isRedactedSecretValue(incoming)) {\n return incoming;\n }\n if (existing) {\n return existing;\n }\n throw new MissingStoredSecretError();\n}\n","import { OpenAPIHono } from '@hono/zod-openapi';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { WithTransaction } from '../db/transaction';\nimport { listModelsRoute } from '../routes/modelRoutes';\nimport { TENANT_ID } from './sessions';\n\n/** FQN read view over configured model providers (mounted at /api/v1/models). */\nexport function createModelsRouter<TTransaction>(deps: {\n modelProviderStore: IModelProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}) {\n const router = new OpenAPIHono();\n router.openapi(listModelsRoute, async c =>\n c.json({ data: await deps.modelProviderStore.listModels(TENANT_ID) }, 200),\n );\n return router;\n}\n","import { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { ListModelsResponseSchema } from '../schemas/modelProvider';\n\nexport const listModelsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: ['Models'],\n summary: 'List models',\n 'x-fern-sdk-group-name': ['models'],\n 'x-fern-sdk-method-name': 'list',\n description: 'Models across all configured model providers, addressed by fully qualified name `name/model_name`.',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListModelsResponseSchema } },\n description: 'All models of all configured providers.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n","/**\n * Admin/settings API surface under /api/v1/settings.\n * Sub-routers (model-providers, mcp-servers, skills, sandbox-providers) mount here.\n * Auth is applied at the /api/v1/settings mount boundary in app.ts (admin when auth is enabled).\n */\nimport { OpenAPIHono } from '@hono/zod-openapi';\nimport type { Logger } from 'winston';\nimport type { ResolveUserContext } from '../auth/identity';\nimport type { IMcpServerStore } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport type { WithTransaction } from '../db/transaction';\nimport type { IOAuthTokenStore } from '../mcp/auth/types';\nimport { createSettingsMcpServersRouter } from './mcpServers';\nimport { createModelProvidersRouter } from './modelProviders';\nimport { createSandboxProvidersRouter } from './sandboxProviders';\nimport { createSkillsRouter } from './skills';\n\nexport interface SettingsRouterDeps<TTransaction> {\n modelProviderStore: IModelProviderStore<TTransaction>;\n mcpServerStore: IMcpServerStore<TTransaction>;\n tokenStore: IOAuthTokenStore<TTransaction>;\n skillStore: ISkillStore<TTransaction>;\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n logger: Logger;\n resolveUserContext: ResolveUserContext;\n}\n\nexport function createSettingsRouter<TTransaction>(deps: SettingsRouterDeps<TTransaction>) {\n const router = new OpenAPIHono();\n router.route(\n '/model-providers',\n createModelProvidersRouter({\n modelProviderStore: deps.modelProviderStore,\n withTransaction: deps.withTransaction,\n }),\n );\n router.route(\n '/mcp-servers',\n createSettingsMcpServersRouter({\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n resolveUserContext: deps.resolveUserContext,\n }),\n );\n router.route(\n '/skills',\n createSkillsRouter({\n skillStore: deps.skillStore,\n withTransaction: deps.withTransaction,\n }),\n );\n router.route(\n '/sandbox-providers',\n createSandboxProvidersRouter({\n sandboxProviderStore: deps.sandboxProviderStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n }),\n );\n return router;\n}\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport {\n ModelProviderNameConflictError,\n type IModelProviderStore,\n type ModelProviderRecord,\n} from '../db/modelProviderStore';\nimport type { WithTransaction } from '../db/transaction';\nimport {\n createModelProviderRoute,\n listModelProvidersRoute,\n putModelProviderRoute,\n} from '../routes/modelProviderRoutes';\nimport {\n modelProviderName,\n type CreateModelProviderRequest,\n type ModelProvider,\n type ModelProviderManifest,\n type PutModelProviderRequest,\n} from '../schemas/modelProvider';\nimport { MissingStoredSecretError, resolveStoredSecretValue, toRedactedSecretValue } from '../utils/secretRedaction';\nimport { TENANT_ID } from './sessions';\n\nexport interface ModelProvidersRouterDeps<TTransaction> {\n modelProviderStore: IModelProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}\n\nfunction redactModelProvider(manifest: ModelProviderManifest): ModelProviderManifest {\n if (manifest.auth === undefined) {\n return manifest;\n }\n return {\n ...manifest,\n auth: { api_key: toRedactedSecretValue(manifest.auth.api_key) },\n };\n}\n\nfunction resolveModelProviderManifestForWrite({\n incoming,\n existing,\n}: {\n incoming: ModelProviderManifest;\n existing: ModelProviderManifest | undefined;\n}): ModelProviderManifest {\n if (incoming.auth === undefined) {\n return incoming;\n }\n return {\n ...incoming,\n auth: {\n api_key: resolveStoredSecretValue({\n incoming: incoming.auth.api_key,\n existing: existing?.auth?.api_key,\n }),\n },\n };\n}\n\nfunction toWireProvider(record: ModelProviderRecord): ModelProvider {\n return {\n name: record.name,\n manifest: redactModelProvider(record.manifest),\n };\n}\n\nexport function createModelProvidersRouter<TTransaction>(deps: ModelProvidersRouterDeps<TTransaction>) {\n const listHandler: RouteHandler<typeof listModelProvidersRoute> = async c => {\n const records = await deps.modelProviderStore.listProviders(TENANT_ID);\n return c.json({ data: records.map(toWireProvider) }, 200);\n };\n\n const createHandler: RouteHandler<typeof createModelProviderRoute> = async c => {\n const body: CreateModelProviderRequest = c.req.valid('json');\n const provider = body.manifest;\n const name = modelProviderName(provider);\n try {\n // Create has no prior row; redacted keep resolves to MissingStoredSecretError → 400.\n const manifest = resolveModelProviderManifestForWrite({ incoming: provider, existing: undefined });\n const record = await deps.modelProviderStore.createProvider({ tenant_id: TENANT_ID, name, manifest });\n return c.json({ data: toWireProvider(record) }, 201);\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'API key is required' } }, 400);\n }\n if (error instanceof ModelProviderNameConflictError) {\n return c.json({ error: { message: error.message } }, 409);\n }\n throw error;\n }\n };\n\n const putHandler: RouteHandler<typeof putModelProviderRoute> = async c => {\n const body: PutModelProviderRequest = c.req.valid('json');\n const provider = body.manifest;\n const name = modelProviderName(provider);\n try {\n // Lock → resolve secret from that snapshot → upsert, all in one txn so concurrent keep\n // cannot re-write a secret over a rotate that committed in between.\n const record = await deps.withTransaction(async transaction => {\n const existing = await deps.modelProviderStore.getProviderForUpdate(\n { tenant_id: TENANT_ID, name },\n transaction,\n );\n const manifest = resolveModelProviderManifestForWrite({\n incoming: provider,\n existing: existing?.manifest,\n });\n return deps.modelProviderStore.upsertProvider({ tenant_id: TENANT_ID, name, manifest }, transaction);\n });\n return c.json({ data: toWireProvider(record) }, 200);\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'API key is required' } }, 400);\n }\n throw error;\n }\n };\n\n const router = new OpenAPIHono();\n router.openapi(listModelProvidersRoute, listHandler);\n router.openapi(createModelProviderRoute, createHandler);\n router.openapi(putModelProviderRoute, putHandler);\n return router;\n}\n","/**\n * Model-provider admin route definitions (mounted at /api/v1/settings/model-providers).\n * Discovery catalog lives at GET /api/v1/catalog/model-providers.\n * Handlers are registered in apis/modelProviders.ts.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport {\n CreateModelProviderRequestSchema,\n GetModelProviderResponseSchema,\n ListModelProvidersResponseSchema,\n PutModelProviderRequestSchema,\n} from '../schemas/modelProvider';\n\nconst MODEL_PROVIDERS_TAG = 'Model Providers';\n\nexport const listModelProvidersRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [MODEL_PROVIDERS_TAG],\n summary: 'List configured model providers',\n description: 'All configured providers with nested manifests.',\n 'x-fern-sdk-group-name': ['settings', 'modelProviders'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListModelProvidersResponseSchema } },\n description: 'All configured model providers',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the caller is authenticated but not an admin.',\n },\n },\n});\n\nexport const createModelProviderRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [MODEL_PROVIDERS_TAG],\n summary: 'Create a model provider',\n description:\n 'Creates a provider (models included). Fails if `name` is already taken. Well-known types use `type` as `name` (one each); ' +\n '`custom` is named by the caller. `auth.api_key`: real value required; redacted with no stored secret returns 400.',\n 'x-fern-sdk-group-name': ['settings', 'modelProviders'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateModelProviderRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetModelProviderResponseSchema } },\n description: 'The created provider',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted API key with no stored secret to keep.',\n },\n 409: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'A model provider with this name already exists.',\n },\n },\n});\n\nexport const putModelProviderRoute = createRoute({\n method: 'put',\n path: '/',\n tags: [MODEL_PROVIDERS_TAG],\n summary: 'Create or replace a model provider',\n description:\n 'Create or replace a provider (models included). Well-known types use `type` as `name` (one each); ' +\n '`custom` is named by the caller. `auth.api_key`: real value sets/rotates; redacted keeps existing (400 if none).',\n 'x-fern-sdk-group-name': ['settings', 'modelProviders'],\n 'x-fern-sdk-method-name': 'upsert',\n request: {\n body: {\n content: { 'application/json': { schema: PutModelProviderRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetModelProviderResponseSchema } },\n description: 'The saved provider',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted API key with no stored secret to keep.',\n },\n },\n});\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { withTimeout } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport type { ISandboxProviderStore, SandboxProviderRecord } from '../db/sandboxProviderStore';\nimport type { WithTransaction } from '../db/transaction';\nimport { getSandboxProviderRoute, putSandboxProviderRoute } from '../routes/sandboxProviderRoutes';\nimport {\n checkSnapshotStatus,\n isDaytonaAuthError,\n toDaytonaSandboxProvider,\n toSandboxStatus,\n} from '../sandbox/providerUtils';\nimport type { PutSandboxProviderRequest, SandboxProviderManifest } from '../schemas/sandboxProvider';\nimport { MissingStoredSecretError, resolveStoredSecretValue, toRedactedSecretValue } from '../utils/secretRedaction';\nimport { TENANT_ID } from './sessions';\n\n/** Cap the Daytona register round-trip so a slow/unreachable provider can't hold the request (or DB txn) open. */\nconst BUILD_REQUEST_TIMEOUT_MS = 3_000;\n\nexport interface SandboxProvidersRouterDeps<TTransaction> {\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n logger: Logger;\n}\n\nfunction redactSandboxProvider(manifest: SandboxProviderManifest): SandboxProviderManifest {\n return {\n ...manifest,\n auth: { api_key: toRedactedSecretValue(manifest.auth.api_key) },\n };\n}\n\n/** Admin/settings sandbox provider surface (mounted at /api/v1/settings/sandbox-providers). */\nexport function createSandboxProvidersRouter<TTransaction>(deps: SandboxProvidersRouterDeps<TTransaction>) {\n const getHandler: RouteHandler<typeof getSandboxProviderRoute> = async c => {\n const record = await deps.sandboxProviderStore.getSandboxProvider(TENANT_ID);\n if (record === undefined) {\n return c.json({ error: { message: 'No sandbox provider configured' } }, 404);\n }\n // Refresh the persisted build status (and re-activate an idle snapshot) on every GET.\n const status = await checkSnapshotStatus({\n store: deps.sandboxProviderStore,\n tenant_id: TENANT_ID,\n logger: deps.logger,\n });\n return c.json(\n {\n data: {\n manifest: redactSandboxProvider(record.manifest),\n status: status?.status ?? record.status,\n status_reason: status?.status_reason ?? record.status_reason,\n },\n },\n 200,\n );\n };\n\n const putHandler: RouteHandler<typeof putSandboxProviderRoute> = async c => {\n const body: PutSandboxProviderRequest = c.req.valid('json');\n const incoming = body.manifest;\n const resolveManifest = (existing: SandboxProviderRecord | undefined): SandboxProviderManifest => ({\n ...incoming,\n auth: {\n api_key: resolveStoredSecretValue({\n incoming: incoming.auth.api_key,\n existing: existing?.manifest.auth.api_key,\n }),\n },\n });\n try {\n // NOTE: build (Daytona network I/O) runs inside the transaction for now; the design is being revisited.\n const { manifest, status } = await deps.withTransaction(async transaction => {\n const locked = await deps.sandboxProviderStore.getSandboxProviderForUpdate(TENANT_ID, transaction);\n const resolved = resolveManifest(locked);\n // Pass persisted build_metadata so a settings re-save does not start a new snapshot for a\n // bumped SANDBOX_IMAGE_URI (upgrades are unsupported — first configure has no metadata).\n const provider = toDaytonaSandboxProvider({\n manifest: resolved,\n tenant_id: TENANT_ID,\n logger: deps.logger,\n ...(locked ? { build_metadata: locked.build_metadata } : {}),\n });\n const built = toSandboxStatus(\n await withTimeout(provider.buildImage(), BUILD_REQUEST_TIMEOUT_MS, 'sandbox buildImage'),\n );\n await deps.sandboxProviderStore.upsertSandboxProvider(\n { tenant_id: TENANT_ID, manifest: resolved, ...built },\n transaction,\n );\n return { manifest: resolved, status: built };\n });\n return c.json(\n {\n data: {\n manifest: redactSandboxProvider(manifest),\n status: status.status,\n status_reason: status.status_reason,\n },\n },\n 200,\n );\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'API key is required' } }, 400);\n }\n if (isDaytonaAuthError(error)) {\n return c.json({ error: { message: 'Daytona rejected the API key — check the credentials' } }, 422);\n }\n throw error;\n }\n };\n\n const router = new OpenAPIHono();\n router.openapi(getSandboxProviderRoute, getHandler);\n router.openapi(putSandboxProviderRoute, putHandler);\n return router;\n}\n","/**\n * Sandbox-provider admin route definitions (mounted at /api/v1/settings/sandbox-providers).\n * Discovery catalog lives at GET /api/v1/catalog/sandbox-providers.\n * Handlers are registered in apis/sandboxProviders.ts.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { GetSandboxProviderResponseSchema, PutSandboxProviderRequestSchema } from '../schemas/sandboxProvider';\n\nconst SANDBOX_PROVIDERS_TAG = 'Sandbox Providers';\n\nexport const getSandboxProviderRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [SANDBOX_PROVIDERS_TAG],\n summary: 'Get the configured sandbox provider',\n description: 'The single configured sandbox provider for this tenant. `auth.api_key` is redacted.',\n 'x-fern-sdk-group-name': ['settings', 'sandboxProviders'],\n 'x-fern-sdk-method-name': 'get',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSandboxProviderResponseSchema } },\n description: 'The configured sandbox provider.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'No sandbox provider configured.',\n },\n },\n});\n\nexport const putSandboxProviderRoute = createRoute({\n method: 'put',\n path: '/',\n tags: [SANDBOX_PROVIDERS_TAG],\n summary: 'Create or replace the sandbox provider',\n description:\n 'Upserts the single sandbox provider for this tenant: creates it or replaces its entire configuration. ' +\n '`auth.api_key`: real value sets/rotates; redacted keeps existing (400 if none).',\n 'x-fern-sdk-group-name': ['settings', 'sandboxProviders'],\n 'x-fern-sdk-method-name': 'upsert',\n request: {\n body: {\n content: { 'application/json': { schema: PutSandboxProviderRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSandboxProviderResponseSchema } },\n description: 'The saved sandbox provider.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted API key with no stored secret to keep.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Daytona rejected the provided API key.',\n },\n },\n});\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { SkillNameConflictError, type ISkillStore, type SkillRecord } from '../db/skillStore';\nimport type { WithTransaction } from '../db/transaction';\nimport {\n createSkillRoute,\n listAvailableSkillsRoute,\n listConfiguredSkillsRoute,\n putSkillRoute,\n} from '../routes/skillRoutes';\nimport type { ConfiguredSkill, CreateSkillRequest, PutSkillRequest } from '../schemas/skill';\nimport { TENANT_ID } from './sessions';\n\nexport interface SkillsRouterDeps<TTransaction> {\n skillStore: ISkillStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}\n\n/** Wire view of a stored skill: identity `name` plus nested manifest. */\nfunction toConfiguredSkill(record: SkillRecord): ConfiguredSkill {\n return {\n name: record.name,\n manifest: record.manifest,\n };\n}\n\n/** Admin/settings skills CRUD (mounted at /api/v1/settings/skills). */\nexport function createSkillsRouter<TTransaction>(deps: SkillsRouterDeps<TTransaction>) {\n const listConfiguredHandler: RouteHandler<typeof listConfiguredSkillsRoute> = async c => {\n const records = await deps.skillStore.listSkills({ tenant_id: TENANT_ID, names: undefined });\n return c.json({ data: records.map(toConfiguredSkill) }, 200);\n };\n\n const createHandler: RouteHandler<typeof createSkillRoute> = async c => {\n const body: CreateSkillRequest = c.req.valid('json');\n const manifest = body.manifest;\n try {\n const record = await deps.skillStore.createSkill({\n tenant_id: TENANT_ID,\n name: manifest.name,\n manifest,\n });\n return c.json({ data: toConfiguredSkill(record) }, 201);\n } catch (error) {\n if (error instanceof SkillNameConflictError) {\n return c.json({ error: { message: error.message } }, 409);\n }\n throw error;\n }\n };\n\n const putHandler: RouteHandler<typeof putSkillRoute> = async c => {\n const body: PutSkillRequest = c.req.valid('json');\n const manifest = body.manifest;\n const record = await deps.skillStore.upsertSkill({\n tenant_id: TENANT_ID,\n name: manifest.name,\n manifest,\n });\n return c.json({ data: toConfiguredSkill(record) }, 200);\n };\n\n const router = new OpenAPIHono();\n router.openapi(listConfiguredSkillsRoute, listConfiguredHandler);\n router.openapi(createSkillRoute, createHandler);\n router.openapi(putSkillRoute, putHandler);\n return router;\n}\n\n/** Chat slim list (mounted at /api/v1/skills) — mirrors GET /api/v1/mcp-servers. */\nexport function createAvailableSkillsRouter<TTransaction>(deps: {\n skillStore: ISkillStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}) {\n const router = new OpenAPIHono();\n router.openapi(listAvailableSkillsRoute, async c => {\n const records = await deps.skillStore.listSkills({ tenant_id: TENANT_ID, names: undefined });\n return c.json(\n {\n data: records.map(record => ({\n name: record.name,\n description: record.manifest.description,\n })),\n },\n 200,\n );\n });\n return router;\n}\n","/**\n * DB-backed skill route definitions.\n * Admin routes mount at /api/v1/settings/skills; the chat list mounts at\n * /api/v1/skills.\n * Discovery catalog lives at GET /api/v1/catalog/skills.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport {\n CreateSkillRequestSchema,\n GetSkillResponseSchema,\n ListAvailableSkillsResponseSchema,\n ListSkillsResponseSchema,\n PutSkillRequestSchema,\n} from '../schemas/skill';\n\nconst SKILLS_TAG = 'Skills';\n\n/** Chat/composer read view — mounted at /api/v1/skills (not under settings). */\nexport const listAvailableSkillsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [SKILLS_TAG],\n summary: 'List skills for chat',\n description: 'Configured skills as a slim name/description list for the composer.',\n 'x-fern-sdk-group-name': ['skills'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListAvailableSkillsResponseSchema } },\n description: 'All configured skills (chat projection).',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n\nexport const listConfiguredSkillsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [SKILLS_TAG],\n summary: 'List configured skills',\n description: 'All configured skills with nested manifests (settings / admin projection).',\n 'x-fern-sdk-group-name': ['settings', 'skills'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListSkillsResponseSchema } },\n description: 'All configured skills.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the caller is authenticated but not an admin.',\n },\n },\n});\n\nexport const createSkillRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [SKILLS_TAG],\n summary: 'Create a skill',\n description: 'Creates a skill keyed by `name`. Fails if `name` is already taken.',\n 'x-fern-sdk-group-name': ['settings', 'skills'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateSkillRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetSkillResponseSchema } },\n description: 'The created skill.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n 409: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'A skill with this name already exists.',\n },\n },\n});\n\nexport const putSkillRoute = createRoute({\n method: 'put',\n path: '/',\n tags: [SKILLS_TAG],\n summary: 'Create or replace a skill',\n description: 'Full upsert keyed by `name`: creates the skill or replaces its entire manifest.',\n 'x-fern-sdk-group-name': ['settings', 'skills'],\n 'x-fern-sdk-method-name': 'upsert',\n request: {\n body: {\n content: { 'application/json': { schema: PutSkillRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSkillResponseSchema } },\n description: 'The saved skill.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n },\n});\n","/**\n * DB-backed turns API (mounted at /api/v1/sessions).\n */\nimport { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport type { ISessionStore, Sessions, Turn, TurnStreamingEvent } from '@truefoundry/trueforge-core/agent-session';\nimport {\n CancellationReason,\n EventType,\n SessionStoreConflictError,\n SessionStoreNotFoundError,\n TurnResourceResolver,\n type TurnInputItem,\n type TurnRecordWithoutSnapshot,\n} from '@truefoundry/trueforge-core/agent-session';\nimport {\n AgentHarnessError,\n extractErrorLogFields,\n isAgentInputUserMessage,\n isFileContentPart,\n McpConnectionError,\n SandboxError,\n validateSandboxOwnedByTenant,\n VercelAILLM,\n} from '@truefoundry/trueforge-core/core';\nimport type { Context } from 'hono';\nimport { HTTPException } from 'hono/http-exception';\nimport { streamSSE } from 'hono/streaming';\nimport type { Logger } from 'winston';\nimport type { ResolveUserContext, UserContext } from '../auth/identity';\nimport configuration from '../config';\nimport type { IAgentStore } from '../db/agentStore';\nimport type { IMcpServerStore } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport type { IOAuthTokenStore } from '../mcp/auth/types';\nimport {\n createAndExecuteTurnRoute,\n downloadSandboxFileRoute,\n getTurnRoute,\n listTurnEventsRoute,\n listTurnsRoute,\n subscribeTurnRoute,\n} from '../routes/turnRoutes';\nimport type { ActiveTurnRegistry } from '../runtime/activeTurns';\nimport { StreamGoneError, type EventSubscription, type EventSubscriptionRegistry } from '../runtime/event-subscription';\nimport { mintPeeredTurnId } from '../runtime/peeringIds';\nimport { validateSandboxFilePath } from '../runtime/sandboxFilePath';\nimport {\n buildTurnSandbox,\n getMcpConnection,\n getModelDetails,\n resolveGitSkills,\n resolveSandboxProvider,\n} from '../runtime/sessionResources';\nimport { checkSnapshotStatus } from '../sandbox/providerUtils';\nimport { TENANT_ID } from './sessions';\n\nexport function toWireTurn(record: TurnRecordWithoutSnapshot): Turn {\n return {\n id: record.turn_id,\n session_id: record.session_id,\n previous_turn_id: record.previous_turn_id,\n input: record.input,\n state: record.state,\n created_at: record.created_at.toISOString(),\n };\n}\n\n/**\n * Copies into a standalone ArrayBuffer for the response body: a pooled Buffer's\n * backing store is shared and typed as ArrayBufferLike, which is not a body.\n * Bounded by SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD.\n */\nfunction toArrayBuffer(content: Buffer): ArrayBuffer {\n const buffer = new ArrayBuffer(content.byteLength);\n new Uint8Array(buffer).set(content);\n return buffer;\n}\n\n/**\n * Builds the Content-Disposition telling the browser to save the file under its sandbox name.\n *\n * A sandbox file can be named in any script, but an HTTP header can only carry bytes, so a name\n * like `中文.csv` cannot be written into the header as-is — doing so throws when the response is\n * constructed. RFC 6266's `filename*` exists for this: percent-encode the UTF-8 name so the value\n * stays plain ASCII, and the client decodes it back. Encoding also defuses quotes and newlines,\n * which could otherwise close the value or inject another header.\n */\nexport function toContentDisposition(path: string): string {\n // Trailing separators are dropped so a path ending in `/` still yields its last real segment.\n const fileName = path.split('/').filter(Boolean).pop() ?? 'download';\n // encodeURIComponent covers everything except these four, which RFC 5987 also disallows here.\n const encoded = encodeURIComponent(fileName).replace(\n /['()*]/g,\n char => `%${char.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n return `attachment; filename*=UTF-8''${encoded}`;\n}\n\nexport interface TurnsRouterDeps {\n sessions: Sessions;\n sessionStore: ISessionStore;\n activeTurns: ActiveTurnRegistry;\n modelProviderStore: IModelProviderStore;\n mcpServerStore: IMcpServerStore;\n tokenStore: IOAuthTokenStore;\n skillStore: ISkillStore;\n agentStore: IAgentStore;\n /** Resumable live turn-event transport: create-turn writes, subscribe polls. */\n eventSubscriptions: EventSubscriptionRegistry<TurnStreamingEvent>;\n sandboxProviderStore: ISandboxProviderStore;\n logger: Logger;\n resolveUserContext: ResolveUserContext;\n}\n\n/**\n * Builds the per-turn resolver. Agent / MCP / sandbox / LLM lookups are wired\n * the same way: async factories over the corresponding stores.\n */\nfunction createTurnResolver(deps: {\n mcpServerStore: IMcpServerStore;\n tokenStore: IOAuthTokenStore;\n skillStore: ISkillStore;\n sandboxProviderStore: ISandboxProviderStore;\n agentStore: IAgentStore;\n modelProviderStore: IModelProviderStore;\n logger: Logger;\n signal: AbortSignal;\n userRef: string;\n}): TurnResourceResolver {\n const {\n mcpServerStore,\n tokenStore,\n skillStore,\n sandboxProviderStore,\n agentStore,\n modelProviderStore,\n logger,\n signal,\n userRef,\n } = deps;\n return new TurnResourceResolver({\n llm: async name => {\n const { providerConfig, defaultModelParams } = await getModelDetails({\n tenant_id: TENANT_ID,\n name,\n store: modelProviderStore,\n });\n return {\n modelClient: new VercelAILLM({\n providerConfig,\n logger,\n signal,\n }),\n defaultModelParams,\n };\n },\n mcp: async name => {\n const connection = await getMcpConnection({\n tenant_id: TENANT_ID,\n name,\n store: mcpServerStore,\n tokenStore,\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n userRef,\n });\n if (connection === undefined) {\n throw new HTTPException(422, {\n message: `Unknown MCP server \"${name}\" — not configured`,\n });\n }\n return connection;\n },\n mcpRequestTimeoutMs: configuration.MCP_REQUEST_TIMEOUT_MS,\n mcpConnectTimeoutMs: configuration.MCP_CONNECT_TIMEOUT_MS,\n sandboxProvider: async ({ spec, existingSandboxId, tracing }) => {\n const provider = await resolveSandboxProvider({\n tenant_id: TENANT_ID,\n store: sandboxProviderStore,\n logger,\n });\n if (provider === undefined) {\n throw new HTTPException(422, {\n message: 'no sandbox provider configured — PUT /settings/sandbox-providers',\n });\n }\n // A fresh sandbox is cloned from the release snapshot, so the build must be ready first.\n // Restoring an existing sandbox goes through daytona.get and never touches the snapshot,\n // so reuse skips this gate entirely.\n if (existingSandboxId === undefined) {\n const status = await checkSnapshotStatus({ store: sandboxProviderStore, tenant_id: TENANT_ID, logger });\n if (status?.status !== 'ready') {\n throw new HTTPException(422, {\n message:\n status?.status === 'failed'\n ? `sandbox image build failed (${status.status_reason ?? 'unknown error'})`\n : 'sandbox image is activating — retry shortly',\n });\n }\n }\n const gitSkills = await resolveGitSkills({\n tenant_id: TENANT_ID,\n skills: spec.skills ?? [],\n store: skillStore,\n });\n return buildTurnSandbox({\n provider,\n logger,\n gitSkills,\n fileDownloadEnabled: spec.config.sandbox.file_downloads,\n existingSandboxId,\n tracing,\n tenantName: TENANT_ID,\n });\n },\n agent: async agentId => {\n const record = await agentStore.getAgent({ tenant_id: TENANT_ID, id: agentId });\n if (record === undefined) {\n throw new HTTPException(422, { message: `Agent not found: ${agentId}` });\n }\n return record.manifest;\n },\n logger,\n });\n}\n\nconst MAX_SESSION_TITLE_LENGTH = 50;\n\n/**\n * Derives a session title from the first user message of the first turn. Returns the\n * trimmed text (capped at {@link MAX_SESSION_TITLE_LENGTH}) or `undefined` when no usable\n * text is present (e.g. file-only or tool-approval input).\n */\nexport function deriveSessionTitle(input: TurnInputItem[] | undefined): string | undefined {\n const firstUserMessage = input?.find(isAgentInputUserMessage);\n if (!firstUserMessage) {\n return undefined;\n }\n\n const text =\n typeof firstUserMessage.content === 'string'\n ? firstUserMessage.content\n : firstUserMessage.content\n .filter(part => !isFileContentPart(part))\n .map(part => part.text)\n .join(' ');\n\n const trimmed = text.trim();\n if (!trimmed) {\n return undefined;\n }\n return trimmed.slice(0, MAX_SESSION_TITLE_LENGTH);\n}\n\n/**\n * SSE payload for one turn event. The `id` field carries the per-stream\n * sequence number; the event body itself is not numbered (yield order is\n * persist order, so the transport boundary stamps).\n */\nexport function turnEventSsePayload(event: TurnStreamingEvent, sequenceNumber: number): { id: string; data: string } {\n return {\n id: String(sequenceNumber),\n data: JSON.stringify(event),\n };\n}\n\n/**\n * turn.created arms the active-run TTL, turn.done shortens it to the\n * post-completion drain window; mid-run events leave the TTL untouched.\n */\nexport function streamTTLSecondsFor(event: TurnStreamingEvent): number | undefined {\n if (event.type === EventType.TURN_CREATED) {\n return configuration.TURN_STREAM_TTL_SECONDS;\n }\n if (event.type === EventType.TURN_DONE) {\n return configuration.TURN_STREAM_POST_COMPLETION_TTL_SECONDS;\n }\n return undefined;\n}\n\n/** Redis/in-memory key for one turn's resumable event stream. */\nexport function turnStreamId(tenantId: string, sessionId: string, turnId: string): string {\n return `agent:turn:${tenantId}:${sessionId}:${turnId}:stream`;\n}\n\n/**\n * Dual-write turn events to the resumable subscription registry, then optionally\n * forward each sequenced event (SSE path). Shared by streaming and non-streaming\n * create-turn; the HTTP response lifecycle does not own execution.\n */\nexport async function drainTurnEvents(input: {\n trackedStream: AsyncIterable<TurnStreamingEvent>;\n turnEventStream: EventSubscription<TurnStreamingEvent>;\n sessionId: string;\n turnId: string;\n maxExecutionTimer: NodeJS.Timeout;\n logger: Logger;\n onEvent?: (event: TurnStreamingEvent, sequenceNumber: number) => Promise<void>;\n}): Promise<void> {\n const { trackedStream, turnEventStream, sessionId, turnId, maxExecutionTimer, logger, onEvent } = input;\n try {\n for await (const event of trackedStream) {\n // Dual-write before any client sink so subscribers can resume after disconnect.\n const sequenceNumber = await turnEventStream.put(event, {\n streamTTLSeconds: streamTTLSecondsFor(event),\n });\n await onEvent?.(event, sequenceNumber);\n }\n } catch (error) {\n if (error instanceof SessionStoreNotFoundError) {\n logger.warn('Turn stream ended after session/turn was removed', {\n sessionId,\n turnId,\n ...extractErrorLogFields(error),\n });\n } else {\n logger.error('Unexpected error in turn event drain', {\n sessionId,\n turnId,\n ...extractErrorLogFields(error),\n });\n }\n } finally {\n clearTimeout(maxExecutionTimer);\n }\n}\n\n/**\n * Resume cursor: `Last-Event-ID` header wins over the body value because the\n * header is updated by the SDK on every reconnect to reflect the last delivered\n * event, whereas the body is the original caller-supplied cursor and never\n * changes between reconnect attempts.\n */\nexport function resolveAfterSequenceNumber(c: Context, bodyAfterSequenceNumber?: number): number | undefined {\n const lastEventId = c.req.header('last-event-id');\n if (lastEventId) {\n const sequenceNumber = Number(lastEventId);\n if (!Number.isInteger(sequenceNumber) || sequenceNumber < 0) {\n throw new HTTPException(400, { message: 'Invalid Last-Event-Id header' });\n }\n return sequenceNumber;\n }\n return bodyAfterSequenceNumber;\n}\n\n/** True when `user` is the session creator (`created_by`). */\nfunction checkTurnAccess(user: UserContext, createdBy: string): boolean {\n return createdBy === user.userRef;\n}\n\nconst FORBIDDEN_SESSION_ACCESS = 'Only the session creator can access this session';\nconst FORBIDDEN_CREATE_TURN = 'Only the session creator can create turns';\n\n/** DB-backed turns (mounted at /api/v1/sessions). */\nexport function createTurnsRouter(deps: TurnsRouterDeps) {\n const listTurnsHandler: RouteHandler<typeof listTurnsRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const query = c.req.valid('query');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n try {\n const { data, pagination } = await session.listTurns({\n limit: query.limit,\n page_token: query.page_token,\n });\n return c.json({ data: data.map(toWireTurn), pagination }, 200);\n } catch (error) {\n if (error instanceof SessionStoreConflictError) {\n return c.json({ error: { message: error.message } }, 400);\n }\n throw error;\n }\n };\n\n const getTurnHandler: RouteHandler<typeof getTurnRoute> = async c => {\n const { session_id: sessionId, turn_id: turnId } = c.req.valid('param');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n const turn = await session.getTurn(turnId);\n if (!turn) {\n return c.json({ error: { message: `Turn not found: ${turnId}` } }, 404);\n }\n return c.json({ data: toWireTurn(turn.record) }, 200);\n };\n\n const downloadSandboxFileHandler: RouteHandler<typeof downloadSandboxFileRoute> = async c => {\n const { session_id: sessionId, turn_id: turnId } = c.req.valid('param');\n const { path } = c.req.valid('query');\n\n let sandboxId: string | undefined;\n try {\n // Cheapest first: a malformed path costs no store read and no provider round-trip.\n validateSandboxFilePath(path);\n\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n\n // Loading the turn through the session is also a session-binding check: a turn id from another\n // session cannot be used to reach this session's sandbox.\n const turn = await session.getTurn(turnId);\n if (!turn) {\n return c.json({ error: { message: `Turn not found: ${turnId}` } }, 404);\n }\n sandboxId = turn.record.snapshot.sandbox_info?.sandbox_id;\n if (sandboxId === undefined) {\n return c.json({ error: { message: `Turn has no sandbox: ${turnId}` } }, 412);\n }\n\n const provider = await resolveSandboxProvider({\n tenant_id: TENANT_ID,\n store: deps.sandboxProviderStore,\n logger: deps.logger,\n });\n if (provider === undefined) {\n return c.json({ error: { message: 'No sandbox provider configured' } }, 412);\n }\n\n validateSandboxOwnedByTenant(sandboxId, TENANT_ID);\n // TODO: stream the body instead of buffering the whole file in memory.\n const content = await provider.downloadFile({ sandboxId, path });\n return c.body(toArrayBuffer(content), 200, {\n 'Content-Type': 'application/octet-stream',\n 'Content-Length': String(content.byteLength),\n 'Content-Disposition': toContentDisposition(path),\n 'Cache-Control': 'private, no-store',\n });\n } catch (error) {\n // Every guard and the provider itself raise SandboxError, whose statusCode is the contract.\n if (error instanceof SandboxError) {\n return c.json({ error: { message: error.message } }, error.statusCode);\n }\n deps.logger.error('Sandbox file download failed', {\n ...extractErrorLogFields(error),\n sessionId,\n turnId,\n sandboxId,\n path,\n });\n return c.json({ error: { message: 'Failed to download file from sandbox' } }, 424);\n }\n };\n\n const listTurnEventsHandler: RouteHandler<typeof listTurnEventsRoute> = async c => {\n const { session_id: sessionId, turn_id: turnId } = c.req.valid('param');\n const query = c.req.valid('query');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n const turn = await session.getTurn(turnId);\n if (!turn) {\n return c.json({ error: { message: `Turn not found: ${turnId}` } }, 404);\n }\n try {\n const { data, pagination } = await turn.listEvents({\n limit: query.limit,\n page_token: query.page_token,\n order: query.order,\n });\n return c.json({ data, pagination }, 200);\n } catch (error) {\n if (error instanceof SessionStoreConflictError) {\n return c.json({ error: { message: error.message } }, 400);\n }\n throw error;\n }\n };\n\n const createAndExecuteTurnHandler: RouteHandler<typeof createAndExecuteTurnRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const body = c.req.valid('json');\n\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_CREATE_TURN } }, 403);\n }\n\n const abortController = new AbortController();\n const resolver = createTurnResolver({\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n agentStore: deps.agentStore,\n modelProviderStore: deps.modelProviderStore,\n logger: deps.logger,\n signal: abortController.signal,\n userRef: deps.resolveUserContext(c).userRef,\n });\n\n // First turn only: derive the title from the first user message. The store\n // never overwrites an existing title.\n const title = session.record.last_turn_id ? undefined : deriveSessionTitle(body.input);\n\n let turn;\n try {\n turn = await session.createTurn({\n turn_id: mintPeeredTurnId(configuration.EXECUTOR_ID),\n input: body.input,\n previous_turn_id: body.previous_turn_id,\n signal: abortController.signal,\n resolver,\n update_session_title_if_not_exist: title,\n });\n } catch (error) {\n if (error instanceof SessionStoreNotFoundError) {\n return c.json({ error: { message: error.message } }, 404);\n }\n if (error instanceof AgentHarnessError && !(error instanceof McpConnectionError)) {\n switch (error.code) {\n case 'invalid_file_input':\n return c.json({ error: { message: error.message } }, 400);\n case 'invalid_send_input':\n case 'agent_sandbox_required':\n case 'tool_name_collision':\n return c.json({ error: { message: error.message } }, 422);\n case 'capability_state_error':\n case 'mcp_connection_failed':\n throw error;\n }\n }\n throw error;\n }\n\n const maxExecutionTimer = setTimeout(() => {\n if (!abortController.signal.aborted) {\n abortController.abort(CancellationReason.ServerExecutionTimeout);\n }\n }, configuration.SERVER_EXECUTION_TIMEOUT_SECONDS * 1000);\n maxExecutionTimer.unref();\n\n const trackedStream = deps.activeTurns.track({\n sessionId,\n turnId: turn.id,\n abortController,\n stream: turn.stream(),\n });\n\n // Held for the whole turn; the stream's sequence counter dies with it.\n const turnEventStream = deps.eventSubscriptions.get(turnStreamId(TENANT_ID, sessionId, turn.id));\n const drainInput = {\n trackedStream,\n turnEventStream,\n sessionId,\n turnId: turn.id,\n maxExecutionTimer,\n logger: deps.logger,\n };\n\n // Non-stream: same unawaited drain scheduling as Hono streamSSE's run(cb).\n // Wait until the first dual-write (turn.created) so immediate subscribeToTurn\n // cannot 412 before the resumable stream exists.\n if (!body.stream) {\n const { promise: firstEventDualWritten, resolve: markFirstEventDualWritten } = Promise.withResolvers<undefined>();\n void drainTurnEvents({\n ...drainInput,\n onEvent: () => {\n markFirstEventDualWritten(undefined);\n return Promise.resolve();\n },\n }).finally(() => {\n markFirstEventDualWritten(undefined);\n });\n await firstEventDualWritten;\n return c.json({ data: toWireTurn(turn.record) }, 200);\n }\n\n let shouldWriteToSSEStream = true;\n return streamSSE(c, async stream => {\n stream.onAbort(() => {\n shouldWriteToSSEStream = false;\n });\n await drainTurnEvents({\n ...drainInput,\n onEvent: async (event, sequenceNumber) => {\n if (!stream.closed && !stream.aborted && shouldWriteToSSEStream) {\n try {\n await stream.writeSSE(turnEventSsePayload(event, sequenceNumber));\n } catch (error) {\n deps.logger.error('SSE stream write error', extractErrorLogFields(error));\n shouldWriteToSSEStream = false;\n }\n }\n },\n });\n await stream.close();\n });\n };\n\n const subscribeTurnHandler: RouteHandler<typeof subscribeTurnRoute> = async c => {\n const { session_id: sessionId, turn_id: turnId } = c.req.valid('param');\n const query = c.req.valid('query');\n const afterSequenceNumber = resolveAfterSequenceNumber(c, query.after_sequence_number);\n\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n const turn = await session.getTurn(turnId);\n if (!turn) {\n return c.json({ error: { message: `Turn not found: ${turnId}` } }, 404);\n }\n\n const turnEventStream = deps.eventSubscriptions.get(turnStreamId(TENANT_ID, sessionId, turnId));\n\n // Admission check before SSE headers are sent, so it can still map to HTTP 412.\n try {\n await turnEventStream.assertSubscribable();\n } catch (error) {\n if (error instanceof StreamGoneError) {\n throw new HTTPException(412, { message: error.message, cause: error });\n }\n throw error;\n }\n\n // One lifecycle controller: server-side timeout, client disconnect, and\n // normal teardown all abort it, which ends poll even while it is parked\n // waiting for events.\n const subscribeAbort = new AbortController();\n const timeoutMs = configuration.TURN_SUBSCRIBE_TIMEOUT_MS;\n const timeoutHandler = setTimeout(() => {\n deps.logger.info('Subscribe turn stream server-side timeout reached, closing stream', {\n sessionId,\n turnId,\n afterSequenceNumber,\n timeoutMs,\n });\n subscribeAbort.abort(new Error('subscribe-timeout'));\n }, timeoutMs);\n\n return streamSSE(c, async stream => {\n stream.onAbort(() => {\n subscribeAbort.abort(new Error('client-disconnected'));\n });\n\n const generator = turnEventStream.poll(afterSequenceNumber, { signal: subscribeAbort.signal });\n try {\n for await (const { sequence_number: sequenceNumber, ...event } of generator) {\n await stream.writeSSE(turnEventSsePayload(event, sequenceNumber));\n if (event.type === EventType.TURN_DONE) {\n break;\n }\n }\n } catch (error) {\n if (!subscribeAbort.signal.aborted) {\n deps.logger.error('Unexpected error in turn subscribe SSE loop', extractErrorLogFields(error));\n }\n } finally {\n clearTimeout(timeoutHandler);\n // Poll loops forever by design; aborting releases a parked generator\n // immediately so the return() below settles right away.\n subscribeAbort.abort();\n await generator.return(undefined);\n await stream.close();\n }\n });\n };\n\n const router = new OpenAPIHono();\n router.openapi(createAndExecuteTurnRoute, createAndExecuteTurnHandler);\n router.openapi(listTurnsRoute, listTurnsHandler);\n router.openapi(getTurnRoute, getTurnHandler);\n router.openapi(downloadSandboxFileRoute, downloadSandboxFileHandler);\n router.openapi(listTurnEventsRoute, listTurnEventsHandler);\n router.openapi(subscribeTurnRoute, subscribeTurnHandler);\n return router;\n}\n","/**\n * Turn route definitions.\n * DB-backed routes mount at /api/v1/sessions.\n * Handlers are registered in apis/turns.ts.\n */\nimport { createRoute, z } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { TurnStreamingEventSchema } from '../schemas/events';\nimport {\n CreateTurnRequestSchema,\n DownloadSandboxFileRequestQuerySchema,\n GetTurnResponseSchema,\n ListTurnEventsRequestQuerySchema,\n ListTurnEventsResponseSchema,\n ListTurnsRequestQuerySchema,\n ListTurnsResponseSchema,\n SubscribeTurnQuerySchema,\n} from '../schemas/turn';\nimport { TOKEN_PAGINATION } from './fernExtensions';\nimport { SessionIdParamsSchema } from './sessionRoutes';\n\nconst SESSIONS_TAG = 'Sessions';\n\nexport const TurnIdParamsSchema = SessionIdParamsSchema.extend({\n turn_id: z.string().min(1).describe('Turn identifier.'),\n});\n\nexport const listTurnsRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns',\n tags: [SESSIONS_TAG],\n summary: 'List turns in a session',\n description:\n 'List turns for a session (newest first by default), token-paginated. Only the session creator (`created_by`) may list turns.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'list_turns',\n 'x-fern-pagination': TOKEN_PAGINATION,\n request: {\n params: SessionIdParamsSchema,\n query: ListTurnsRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListTurnsResponseSchema } },\n description: 'Paginated turns.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid page token.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n },\n});\n\nexport const getTurnRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns/{turn_id}',\n tags: [SESSIONS_TAG],\n summary: 'Get a turn',\n description: 'Fetch a single turn by ID. Only the session creator (`created_by`) may fetch it.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'get_turn',\n request: {\n params: TurnIdParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetTurnResponseSchema } },\n description: 'Turn data.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session or turn not found.',\n },\n },\n});\n\nexport const downloadSandboxFileRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns/{turn_id}/download',\n tags: [SESSIONS_TAG],\n summary: 'Download a file from the turn sandbox',\n description:\n \"Download a file from the sandbox this turn ran in. Paths come from the assistant's `sandbox_artifacts` block. Only the session creator (`created_by`) may download.\",\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'download_sandbox_file',\n request: {\n params: TurnIdParamsSchema,\n query: DownloadSandboxFileRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/octet-stream': { schema: z.string().openapi({ format: 'binary' }) } },\n description: 'File contents.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid path, or the path is a directory.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator, or sandbox belongs to another tenant.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session, turn, or file not found.',\n },\n 410: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Sandbox no longer exists.',\n },\n 412: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Turn has no sandbox, or no sandbox provider is configured.',\n },\n 413: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'File exceeds the maximum download size.',\n },\n 424: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Sandbox infrastructure error.',\n },\n },\n});\n\nexport const listTurnEventsRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns/{turn_id}/events',\n tags: [SESSIONS_TAG],\n summary: 'List turn events',\n description:\n 'Paginated persisted events for a turn (insertion order by default). Only the session creator (`created_by`) may list events.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'list_turn_events',\n 'x-fern-pagination': TOKEN_PAGINATION,\n request: {\n params: TurnIdParamsSchema,\n query: ListTurnEventsRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListTurnEventsResponseSchema } },\n description: 'Paginated turn events.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid page token.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session or turn not found.',\n },\n },\n});\n\nexport const createAndExecuteTurnRoute = createRoute({\n method: 'post',\n path: '/{session_id}/turns',\n tags: [SESSIONS_TAG],\n summary: 'Create and execute a turn in a session',\n description: `Create a turn within a session and execute it.\nOnly the session creator (\\`created_by\\`) may create turns.\nWhen \\`stream\\` is true (default), respond with a Server-Sent Events stream of turn events.\nWhen \\`stream\\` is false, return the turn immediately with \\`state.status: \"running\"\\` while execution continues in the background; use get turn or subscribe to observe completion.\nUse \\`previous_turn_id\\` to chain to the session's last turn (defaults to \\`auto\\`); use \\`none\\` for a new root.`,\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'create_turn',\n 'x-fern-streaming': {\n format: 'sse',\n resumable: false,\n 'stream-condition': '$request.stream',\n response: { $ref: '#/components/schemas/GetTurnResponse' },\n 'response-stream': { $ref: '#/components/schemas/TurnStreamingEvent' },\n },\n request: {\n params: SessionIdParamsSchema,\n body: {\n content: { 'application/json': { schema: CreateTurnRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: {\n 'application/json': {\n schema: GetTurnResponseSchema,\n },\n 'text/event-stream': {\n schema: TurnStreamingEventSchema,\n },\n },\n description:\n 'When stream is false: the running turn. When stream is true: Server-Sent Events stream of turn events.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session or prior turn not found.',\n },\n 412: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Requested action cannot be performed on the session because it is no longer usable.',\n },\n 413: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Request body exceeds the configured maximum size (MAX_REQUEST_BODY_BYTES).',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'The request is well-formed but cannot be processed: a referenced resource is missing ' +\n '(named agent, model, MCP server, skill, or sandbox provider), sandbox is required but ' +\n 'unavailable (e.g. file uploads), or the turn input conflicts with current state ' +\n '(e.g. unresolved tool calls or approvals, tool name collision).',\n },\n },\n});\n\nexport const subscribeTurnRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns/{turn_id}/subscribe',\n tags: [SESSIONS_TAG],\n summary: 'Subscribe to a running turn',\n description:\n 'Subscribe to the live SSE stream for a turn. Only the session creator (`created_by`) may subscribe. Pass `after_sequence_number` to resume after a disconnect (exclusive — events after this sequence number are replayed).',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'subscribe_to_turn',\n 'x-fern-streaming': { format: 'sse', resumable: true },\n request: {\n params: TurnIdParamsSchema,\n query: SubscribeTurnQuerySchema,\n },\n responses: {\n 200: {\n content: {\n 'text/event-stream': {\n schema: TurnStreamingEventSchema,\n },\n },\n description: 'Server-Sent Events stream of turn events (deltas and lifecycle).',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid query parameters.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Turn not found.',\n },\n 412: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Cannot subscribe — the live stream no longer exists.',\n },\n },\n});\n","/**\n * Single-process backend mirroring RedisEventSubscription semantics (dense\n * sequences, whole-stream TTL, poll-forever generators, same errors).\n * Resume only works within one replica.\n */\nimport { EventEmitter, once } from 'node:events';\nimport {\n StreamGoneError,\n SUBSCRIBE_STREAM_THRESHOLD_MS,\n type EventSubscription,\n type EventSubscriptionPollOptions,\n type EventSubscriptionPutOptions,\n type SequencedEvent,\n} from '.';\n\ninterface InMemoryStream<T extends object> {\n /** Dense log: the event at index i has sequence_number i + 1 (1-indexed). */\n events: SequencedEvent<T>[];\n /** Undefined = no TTL set yet (mirrors a Redis key without EXPIRE). */\n expiresAtMs?: number | undefined;\n expiryTimer?: NodeJS.Timeout | undefined;\n}\n\n/**\n * Owns the stream logs and their TTLs; the expiry timer is the in-process\n * equivalent of Redis key eviction.\n */\nexport class InMemoryEventStreamStore<T extends object> {\n private readonly streams = new Map<string, InMemoryStream<T>>();\n /** Rings per stream id on append and expiry so parked pollers wake instantly. */\n private readonly changes = new EventEmitter();\n\n constructor() {\n // One listener per parked poller; unlimited concurrent subscribers.\n this.changes.setMaxListeners(0);\n }\n\n append(streamId: string, event: T, streamTTLSeconds?: number): number {\n const stream = this.getLiveStream(streamId) ?? { events: [] };\n this.streams.set(streamId, stream);\n\n const sequenceNumber = stream.events.length + 1;\n // Deep-copy so the log is isolated from caller mutations (mirrors JSON round-trip in Redis).\n stream.events.push({ ...structuredClone(event), sequence_number: sequenceNumber });\n\n if (streamTTLSeconds && streamTTLSeconds > 0) {\n stream.expiresAtMs = Date.now() + streamTTLSeconds * 1_000;\n this.scheduleExpiry(streamId, stream);\n }\n this.changes.emit(streamId);\n return sequenceNumber;\n }\n\n /** Returns the stream if it exists and has not passed its TTL; drops it lazily otherwise. */\n getLiveStream(streamId: string): InMemoryStream<T> | undefined {\n const stream = this.streams.get(streamId);\n if (!stream) {\n return undefined;\n }\n if (stream.expiresAtMs !== undefined && stream.expiresAtMs <= Date.now()) {\n this.dropStream(streamId, stream);\n return undefined;\n }\n return stream;\n }\n\n /**\n * Resolves on the next append/expiry of the stream; rejects when the signal\n * aborts (which also detaches the listener, so abandoned waits do not leak).\n */\n async waitForChange(streamId: string, signal?: AbortSignal): Promise<void> {\n await once(this.changes, streamId, { signal });\n }\n\n /**\n * Evicts a stream: clears its timer, removes it from the map, and wakes any\n * parked pollers so they observe StreamGoneError promptly. Shared by the\n * lazy-expiry path in getLiveStream and the scheduled expiry timer.\n */\n private dropStream(streamId: string, stream: InMemoryStream<T>): void {\n if (stream.expiryTimer) {\n clearTimeout(stream.expiryTimer);\n stream.expiryTimer = undefined;\n }\n if (this.streams.get(streamId) !== stream) {\n return;\n }\n this.streams.delete(streamId);\n this.changes.emit(streamId);\n }\n\n private scheduleExpiry(streamId: string, stream: InMemoryStream<T>): void {\n if (stream.expiryTimer) {\n clearTimeout(stream.expiryTimer);\n }\n if (stream.expiresAtMs === undefined) {\n return;\n }\n stream.expiryTimer = setTimeout(\n () => {\n this.dropStream(streamId, stream);\n },\n Math.max(0, stream.expiresAtMs - Date.now()),\n );\n stream.expiryTimer.unref();\n }\n}\n\n/** Stream-scoped view over the shared store; implements the transport contract. */\nexport class InMemoryEventSubscription<T extends object> implements EventSubscription<T> {\n constructor(\n private readonly store: InMemoryEventStreamStore<T>,\n private readonly streamId: string,\n ) {}\n\n put(event: T, options?: EventSubscriptionPutOptions): Promise<number> {\n return Promise.resolve(this.store.append(this.streamId, event, options?.streamTTLSeconds));\n }\n\n assertSubscribable(): Promise<void> {\n const stream = this.store.getLiveStream(this.streamId);\n if (!stream) {\n throw new StreamGoneError(this.streamId);\n }\n // Expiring within the threshold is treated as already gone, mirroring the Redis backend.\n if (stream.expiresAtMs !== undefined && stream.expiresAtMs - Date.now() < SUBSCRIBE_STREAM_THRESHOLD_MS) {\n throw new StreamGoneError(this.streamId);\n }\n return Promise.resolve();\n }\n\n async *poll(\n afterSequenceNumber?: number,\n options?: EventSubscriptionPollOptions,\n ): AsyncGenerator<SequencedEvent<T>, void, unknown> {\n const signal = options?.signal;\n // 0 and omitted both mean \"from the start\". With 1-indexed sequences stored at\n // index seq-1, \"strictly after N\" starts at array index N.\n let cursor = afterSequenceNumber === undefined || afterSequenceNumber === 0 ? 0 : afterSequenceNumber;\n for (;;) {\n if (signal?.aborted) {\n return;\n }\n const live = this.store.getLiveStream(this.streamId);\n if (!live) {\n throw new StreamGoneError(this.streamId);\n }\n const end = live.events.length;\n if (cursor >= end) {\n try {\n await this.store.waitForChange(this.streamId, signal);\n } catch (error) {\n if (signal?.aborted) {\n return;\n }\n throw error;\n }\n continue;\n }\n // Deep-copy each yielded event so consumers cannot mutate the stored log.\n // Snapshot `end` so appends during yield are left for the next pass.\n while (cursor < end) {\n const event = live.events[cursor];\n if (event === undefined) {\n throw new Error(`Corrupt stream ${this.streamId}: missing event at index ${String(cursor)}`);\n }\n cursor += 1;\n yield structuredClone(event);\n }\n }\n }\n}\n","import { setTimeout as sleep } from 'node:timers/promises';\nimport type { RedisClientType } from 'redis';\nimport {\n StreamGoneError,\n SUBSCRIBE_STREAM_THRESHOLD_MS,\n type EventSubscription,\n type EventSubscriptionPollOptions,\n type EventSubscriptionPutOptions,\n type SequencedEvent,\n} from '.';\n\nconst SUBSCRIBE_STREAM_POLL_ITEMS_COUNT = 100;\n/** Delay between XREAD polls while a stream has no new events (a blocking XREAD would monopolize the shared connection). */\nconst SUBSCRIBE_STREAM_POLL_SLEEP_INTERVAL_MS = 1_000;\n\nfunction sequenceNumberFromEntryId(streamId: string, entryId: string): number {\n const separator = entryId.indexOf('-');\n const raw = separator === -1 ? entryId : entryId.slice(0, separator);\n const sequenceNumber = Number(raw);\n if (!Number.isSafeInteger(sequenceNumber) || sequenceNumber < 0) {\n throw new Error(`Corrupt stream entry ${entryId} on ${streamId}: invalid sequence number`);\n }\n return sequenceNumber;\n}\n\n/**\n * One Redis Stream with locally minted 1-indexed sequence numbers. Assumes a\n * single producer per stream; the counter dies with the instance, the data via key TTL.\n */\nexport class RedisEventSubscription<T extends object> implements EventSubscription<T> {\n private nextSequenceNumber = 1;\n\n constructor(\n private readonly redis: RedisClientType,\n private readonly streamId: string,\n ) {}\n\n async put(event: T, options?: EventSubscriptionPutOptions): Promise<number> {\n const sequenceNumber = this.nextSequenceNumber;\n this.nextSequenceNumber += 1;\n\n const sequencedEvent: SequencedEvent<T> = { ...event, sequence_number: sequenceNumber };\n const multi = this.redis.multi().xAdd(this.streamId, `${String(sequenceNumber)}-1`, {\n data: JSON.stringify(sequencedEvent),\n });\n if (options?.streamTTLSeconds && options.streamTTLSeconds > 0) {\n multi.expire(this.streamId, options.streamTTLSeconds);\n }\n await multi.exec();\n return sequenceNumber;\n }\n\n async assertSubscribable(): Promise<void> {\n const expiresAtMs = await this.redis.pExpireTime(this.streamId);\n if (expiresAtMs === -2) {\n throw new StreamGoneError(this.streamId);\n }\n // Expiring within the threshold is treated as already gone: too little\n // time remains for a subscription to be useful.\n if (expiresAtMs >= 0 && expiresAtMs - Date.now() < SUBSCRIBE_STREAM_THRESHOLD_MS) {\n throw new StreamGoneError(this.streamId);\n }\n }\n\n async *poll(\n afterSequenceNumber?: number,\n options?: EventSubscriptionPollOptions,\n ): AsyncGenerator<SequencedEvent<T>, void, unknown> {\n const signal = options?.signal;\n // 0 and omitted both mean \"from the start\" (sequences are 1-indexed).\n // Entries are `${seq}-1`. XREAD returns IDs greater than `id`, so\n // `${N+1}-0` is an exclusive lower bound just below the next entry.\n let cursor =\n afterSequenceNumber === undefined || afterSequenceNumber === 0 ? '1-0' : `${String(afterSequenceNumber + 1)}-0`;\n for (;;) {\n if (signal?.aborted) {\n return;\n }\n if ((await this.redis.exists(this.streamId)) === 0) {\n throw new StreamGoneError(this.streamId);\n }\n const reply = await this.redis.xRead([{ key: this.streamId, id: cursor }], {\n COUNT: SUBSCRIBE_STREAM_POLL_ITEMS_COUNT,\n });\n const messages = reply?.[0]?.messages ?? [];\n if (messages.length === 0) {\n try {\n await sleep(SUBSCRIBE_STREAM_POLL_SLEEP_INTERVAL_MS, undefined, { signal });\n } catch (error) {\n if (signal?.aborted) {\n return;\n }\n throw error;\n }\n continue;\n }\n\n for (const { id, message } of messages) {\n cursor = id;\n const data = message['data'];\n if (data === undefined) {\n throw new Error(`Corrupt stream entry ${id} on ${this.streamId}: missing data field`);\n }\n\n let event: T;\n try {\n // Own writes read back; trusted without validation, as in the gateway.\n event = JSON.parse(data) as T;\n } catch (error) {\n throw new Error(`Corrupt stream entry ${id} on ${this.streamId}: data is not valid JSON`, {\n cause: error,\n });\n }\n yield { ...event, sequence_number: sequenceNumberFromEntryId(this.streamId, id) };\n }\n }\n }\n}\n","import type { RedisClientType } from 'redis';\nimport { InMemoryEventStreamStore, InMemoryEventSubscription } from './inMemory';\nimport { RedisEventSubscription } from './redis';\n\nexport interface EventSubscriptionPutOptions {\n /** Sets the lifetime of the whole stream after this append. */\n streamTTLSeconds?: number | undefined;\n}\n\nexport type SequencedEvent<T extends object> = T & { sequence_number: number };\n\nexport interface EventSubscriptionPollOptions {\n /** Ends the generator promptly on abort, releasing any parked idle wait. */\n signal?: AbortSignal | undefined;\n}\n\n/**\n * One turn's resumable event stream, obtained from {@link EventSubscriptionRegistry.get}.\n * Per-stream state (e.g. the sequence counter) lives on the instance and is freed with it.\n */\nexport interface EventSubscription<T extends object> {\n /** Appends an event, assigns its sequence number, and returns that number. */\n put(event: T, options?: EventSubscriptionPutOptions): Promise<number>;\n\n /**\n * Subscription admission check, run before SSE headers are sent: rejects with\n * {@link StreamGoneError} when the stream is missing or expires within\n * {@link SUBSCRIBE_STREAM_THRESHOLD_MS}.\n */\n assertSubscribable(): Promise<void>;\n\n /**\n * Yields events strictly after the supplied sequence number.\n * Sequences are 1-indexed; omit or pass 0 to start from the first event.\n */\n poll(\n afterSequenceNumber?: number,\n options?: EventSubscriptionPollOptions,\n ): AsyncGenerator<SequencedEvent<T>, void, unknown>;\n}\n\n/**\n * Hands out stream-scoped {@link EventSubscription}s: Redis-backed when a\n * client is supplied, otherwise views over one shared in-process store.\n */\nexport class EventSubscriptionRegistry<T extends object> {\n /** One store for the whole process so producers and subscribers share streams. */\n private readonly memoryStore = new InMemoryEventStreamStore<T>();\n\n constructor(private readonly redis: RedisClientType | undefined) {}\n\n get(streamId: string): EventSubscription<T> {\n if (this.redis) {\n return new RedisEventSubscription<T>(this.redis, streamId);\n }\n return new InMemoryEventSubscription(this.memoryStore, streamId);\n }\n}\n\n/** Reject new subscriptions when the stream expires within this window. */\nexport const SUBSCRIBE_STREAM_THRESHOLD_MS = 60 * 1_000;\n\n/** The stream expired or was never created (map to HTTP 412). */\nexport class StreamGoneError extends Error {\n readonly code = 'STREAM_GONE' as const;\n\n constructor(readonly streamId: string) {\n super(`Cannot read from stream, stream does not exist anymore: ${streamId}`);\n this.name = 'StreamGoneError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Validation for caller-supplied sandbox download paths. This is an HTTP concern — the harness\n * library only guards its own file operations — so it lives with the route that accepts the path.\n */\nimport { SandboxError, validateNoPathTraversal } from '@truefoundry/trueforge-core/core';\n\nclass SandboxInvalidPathError extends SandboxError {\n readonly statusCode = 400;\n\n constructor({ path, reason }: { path: string; reason: string }) {\n super(`Path ${reason}: ${path}`);\n this.name = 'SandboxInvalidPathError';\n }\n}\n\n/**\n * Past these the kernel rejects the path before any file is opened. PATH_MAX (4096) counts the\n * terminating NUL, so the longest usable path is one byte shorter; NAME_MAX (255) does not.\n */\nconst MAX_PATH_BYTES = 4095;\nconst MAX_SEGMENT_BYTES = 255;\n\n/**\n * Every check a caller-supplied download path must pass before it reaches a provider. Shape\n * violations are caught here because a provider reports them as opaque backend failures,\n * indistinguishable from a real outage.\n */\nexport function validateSandboxFilePath(path: string): void {\n if (!path.startsWith('/')) {\n throw new SandboxInvalidPathError({ path, reason: 'must be absolute' });\n }\n if (path.includes('\\0')) {\n throw new SandboxInvalidPathError({ path, reason: 'must not contain a NUL byte' });\n }\n if (Buffer.byteLength(path) > MAX_PATH_BYTES) {\n throw new SandboxInvalidPathError({ path, reason: `must be at most ${String(MAX_PATH_BYTES)} bytes` });\n }\n if (path.split('/').some(segment => Buffer.byteLength(segment) > MAX_SEGMENT_BYTES)) {\n throw new SandboxInvalidPathError({\n path,\n reason: `must not have a segment longer than ${String(MAX_SEGMENT_BYTES)} bytes`,\n });\n }\n validateNoPathTraversal(path);\n}\n","/**\n * Package version for logs, the OpenAPI document, and the CLI.\n *\n * Read from `package.json` next to this module's package root — the same\n * `src/` vs `dist/` layout as `config.ts` (`import.meta` → parent).\n */\nimport { readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');\n\nfunction readPackageVersion(): string {\n const packageJsonPath = path.join(PACKAGE_ROOT, 'package.json');\n const parsed: unknown = JSON.parse(readFileSync(packageJsonPath, 'utf8'));\n if (typeof parsed !== 'object' || parsed === null || !('version' in parsed)) {\n throw new Error(`${packageJsonPath} is missing a version field`);\n }\n const { version } = parsed;\n if (typeof version !== 'string' || version.length === 0) {\n throw new Error(`${packageJsonPath} version must be a non-empty string`);\n }\n return version;\n}\n\nexport const PACKAGE_VERSION = readPackageVersion();\n","/** Shared Zod → HTTP 400 formatting for OpenAPI validation and thrown ZodError. */\nimport type { Hook } from '@hono/zod-openapi';\nimport { z } from '@hono/zod-openapi';\nimport type { Context } from 'hono';\n\nexport function zodErrorResponse(c: Context, error: z.ZodError) {\n return c.json({ error: { message: z.prettifyError(error) } }, 400);\n}\n\nexport const zodValidationHook: Hook<unknown, object, string, Response | undefined> = (result, c) => {\n if (!result.success) {\n return zodErrorResponse(c, result.error);\n }\n return undefined;\n};\n","/**\n * Shipped MCP catalog (mcp-catalog.yaml): the discovery list of server\n * presets offered by GET /catalog/mcp-servers for the UI to copy into\n * PUT /settings/mcp-servers bodies. Never consulted on writes and never\n * read by the runtime.\n *\n * Default: YAML inlined into `mcpCatalog.gen.ts` at build time. Optional\n * override: `MCP_CATALOG_PATH` (file on disk).\n */\nimport configuration from '../config';\nimport { McpCatalogFileSchema, type CatalogMcpServer } from '../schemas/mcpCatalog';\nimport { loadYamlAtPath, parseYamlString } from './loadYaml';\nimport { shippedMcpCatalogYaml } from './mcpCatalog.gen';\n\nexport class McpCatalog {\n private readonly mcpServers: readonly CatalogMcpServer[];\n\n constructor(mcpServers: readonly CatalogMcpServer[]) {\n this.mcpServers = mcpServers;\n }\n\n /** Loads and validates the catalog. Throws on any error. */\n static load(): McpCatalog {\n if (configuration.MCP_CATALOG_PATH !== undefined) {\n const file = loadYamlAtPath(configuration.MCP_CATALOG_PATH, McpCatalogFileSchema);\n return new McpCatalog(file.mcp_servers);\n }\n const file = parseYamlString(shippedMcpCatalogYaml, McpCatalogFileSchema, 'shipped mcp-catalog');\n return new McpCatalog(file.mcp_servers);\n }\n\n list(): readonly CatalogMcpServer[] {\n return this.mcpServers;\n }\n}\n","/**\n * Reads and validates a YAML config file. Any failure (missing file, invalid\n * YAML, schema violation) throws, so callers fail at startup with a message\n * pointing at the offending file.\n */\nimport fs from 'node:fs';\nimport { parse } from 'yaml';\nimport type { z } from 'zod';\n\n/** Parses and validates YAML text. `label` is used in error messages. */\nexport function parseYamlString<T>(raw: string, schema: z.ZodType<T>, label: string): T {\n let document: unknown;\n try {\n document = parse(raw);\n } catch (error) {\n throw new Error(`Invalid YAML in ${label}: ${error instanceof Error ? error.message : String(error)}`, {\n cause: error,\n });\n }\n\n const result = schema.safeParse(document);\n if (!result.success) {\n const issues = result.error.issues\n .map(issue => ` - ${issue.path.length > 0 ? issue.path.join('.') : '(root)'}: ${issue.message}`)\n .join('\\n');\n throw new Error(`Invalid config in ${label}:\\n${issues}`);\n }\n return result.data;\n}\n\nexport function loadYamlAtPath<T>(filePath: string, schema: z.ZodType<T>): T {\n let raw: string;\n try {\n raw = fs.readFileSync(filePath, 'utf8');\n } catch (error) {\n throw new Error(\n `Failed to read config file ${filePath}: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n\n return parseYamlString(raw, schema, filePath);\n}\n","// AUTO-GENERATED by scripts/generate-catalog.mjs — do not edit.\nexport const shippedMcpCatalogYaml = \"# Shipped MCP catalog: server presets offered by\\n# GET /api/v1/catalog/mcp-servers for the UI to copy into\\n# PUT /api/v1/settings/mcp-servers bodies. Discovery-only — never executed against.\\nmcp_servers:\\n - type: remote\\n name: linear\\n logo: https://assets.production.truefoundry.com/linear.svg\\n url: https://mcp.linear.app/mcp\\n description: Search, read, and create Linear issues.\\n auth:\\n type: dcr\\n - type: remote\\n name: notion\\n logo: https://assets.production.truefoundry.com/notion.svg\\n url: https://mcp.notion.com/mcp\\n description: Search pages, read content, query databases, create pages.\\n auth:\\n type: dcr\\n - type: remote\\n name: sentry\\n logo: https://assets.production.truefoundry.com/sentry.svg\\n url: https://mcp.sentry.dev/mcp\\n description: Search errors, read stack traces, and check releases.\\n auth:\\n type: dcr\\n - type: remote\\n name: deepwiki\\n logo: https://assets.production.truefoundry.com/deepwiki.png\\n url: https://mcp.deepwiki.com/mcp\\n description: Read documentation and ask questions about any public GitHub repository.\\n - type: remote\\n name: exa\\n logo: https://assets.production.truefoundry.com/exa.svg\\n url: https://mcp.exa.ai/mcp\\n description: Search the web, fetch page contents, and find similar pages.\\n - type: remote\\n name: parallel-web\\n logo: https://assets.production.truefoundry.com/parallel-web.svg\\n url: https://search.parallel.ai/mcp\\n description: Search the web and get ranked results with extracted content.\\n - type: remote\\n name: github\\n logo: https://assets.production.truefoundry.com/github.svg\\n url: https://api.githubcopilot.com/mcp/\\n description: Work with issues, pull requests, repository files, and CI status.\\n auth:\\n type: header\\n headers:\\n Authorization: Bearer YOUR_GITHUB_PAT\\n - type: remote\\n name: tavily\\n logo: https://assets.production.truefoundry.com/tavily.svg\\n url: https://mcp.tavily.com/mcp\\n description: Search the web, extract page content, and crawl sites.\\n auth:\\n type: header\\n headers:\\n Authorization: Bearer YOUR_TAVILY_API_KEY\\n - type: remote\\n name: bright-data\\n logo: https://assets.production.truefoundry.com/bright-data.png\\n url: https://mcp.brightdata.com/mcp\\n description: Search the web and scrape pages, including sites behind bot protection.\\n auth:\\n type: header\\n headers:\\n Authorization: Bearer YOUR_BRIGHT_DATA_API_TOKEN\\n - type: remote\\n name: supabase\\n logo: https://assets.production.truefoundry.com/supabase.svg\\n url: https://mcp.supabase.com/mcp\\n description: Run SQL queries, manage tables, and inspect Supabase projects.\\n auth:\\n type: dcr\\n - type: remote\\n name: stripe\\n logo: https://assets.production.truefoundry.com/stripe.svg\\n url: https://mcp.stripe.com\\n description: Create and manage customers, payments, invoices, and subscriptions.\\n auth:\\n type: dcr\\n - type: remote\\n name: confluence\\n logo: https://assets.production.truefoundry.com/confluence.svg\\n url: https://mcp.atlassian.com/v1/mcp\\n description: Search spaces, read pages, and create or update content.\\n auth:\\n type: dcr\\n - type: remote\\n name: jira\\n logo: https://assets.production.truefoundry.com/jira.png\\n url: https://mcp.atlassian.com/v1/mcp\\n description: Search, read, create, and update Jira issues.\\n auth:\\n type: dcr\\n - type: remote\\n name: posthog\\n logo: https://assets.production.truefoundry.com/posthog.svg\\n url: https://mcp.posthog.com/mcp\\n description: Query product analytics, run SQL, and manage feature flags.\\n auth:\\n type: dcr\\n\" as const;\n","/**\n * Shipped model catalog (model-catalog.yaml): the discovery list of provider\n * and model presets offered by GET /catalog/model-providers for the UI to copy\n * into PUT /settings/model-providers bodies. Never consulted on writes and never\n * read by the runtime.\n *\n * Default: YAML inlined into `modelCatalog.gen.ts` at build time. Optional\n * override: `MODEL_CATALOG_PATH` (file on disk).\n */\nimport configuration from '../config';\nimport { ModelCatalogFileSchema, type CatalogWellKnownModelProvider } from '../schemas/modelCatalog';\nimport { loadYamlAtPath, parseYamlString } from './loadYaml';\nimport { shippedModelCatalogYaml } from './modelCatalog.gen';\n\nexport class ModelCatalog {\n private readonly providers: readonly CatalogWellKnownModelProvider[];\n\n constructor(providers: readonly CatalogWellKnownModelProvider[]) {\n this.providers = providers;\n }\n\n /** Loads and validates the catalog. Throws on any error. */\n static load(): ModelCatalog {\n if (configuration.MODEL_CATALOG_PATH !== undefined) {\n const file = loadYamlAtPath(configuration.MODEL_CATALOG_PATH, ModelCatalogFileSchema);\n return new ModelCatalog(file.providers);\n }\n const file = parseYamlString(shippedModelCatalogYaml, ModelCatalogFileSchema, 'shipped model-catalog');\n return new ModelCatalog(file.providers);\n }\n\n list(): readonly CatalogWellKnownModelProvider[] {\n return this.providers;\n }\n}\n","// AUTO-GENERATED by scripts/generate-catalog.mjs — do not edit.\nexport const shippedModelCatalogYaml = \"# Shipped model catalog: provider/model presets offered by\\n# GET /api/v1/catalog/model-providers for the UI to copy into\\n# PUT /api/v1/settings/model-providers bodies. Discovery-only — never executed against.\\nproviders:\\n - type: openai\\n logo: https://assets.production.truefoundry.com/openai.svg\\n models:\\n - model_id: gpt-5.4-mini\\n name: gpt-5-4-mini\\n properties:\\n context_length: 400000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: gpt-5.5\\n name: gpt-5-5\\n properties:\\n context_length: 1050000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: gpt-5.6-luna\\n name: gpt-5-6-luna\\n properties:\\n context_length: 1050000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: gpt-5.6-sol\\n name: gpt-5-6-sol\\n properties:\\n context_length: 1050000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: gpt-5.6-terra\\n name: gpt-5-6-terra\\n properties:\\n context_length: 1050000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: anthropic\\n logo: https://assets.production.truefoundry.com/anthropic.svg\\n models:\\n - model_id: claude-fable-5\\n name: claude-fable-5\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: claude-haiku-4-5\\n name: claude-haiku-4-5\\n properties:\\n context_length: 200000\\n max_output_tokens: 64000\\n - model_id: claude-opus-4-8\\n name: claude-opus-4-8\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: claude-opus-5\\n name: claude-opus-5\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: claude-sonnet-4-6\\n name: claude-sonnet-4-6\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - max\\n - model_id: claude-sonnet-5\\n name: claude-sonnet-5\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: google-gemini\\n logo: https://assets.production.truefoundry.com/google-gemini.svg\\n models:\\n - model_id: gemini-3.1-pro-preview\\n name: gemini-3-1-pro-preview\\n properties:\\n context_length: 1048576\\n max_output_tokens: 65536\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - model_id: gemini-3.6-flash\\n name: gemini-3-6-flash\\n properties:\\n context_length: 1048576\\n max_output_tokens: 65536\\n reasoning_efforts:\\n - minimal\\n - low\\n - medium\\n - high\\n - type: fireworks\\n logo: https://assets.production.truefoundry.com/fireworks.svg\\n models:\\n - model_id: accounts/fireworks/models/deepseek-v4-pro\\n name: deepseek-v4-pro\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: accounts/fireworks/models/glm-5p2\\n name: glm-5p2\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: accounts/fireworks/models/kimi-k2p7-code\\n name: kimi-k2p7-code\\n properties:\\n context_length: 262144\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: accounts/fireworks/models/kimi-k3\\n name: kimi-k3\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: accounts/fireworks/models/minimax-m3\\n name: minimax-m3\\n properties:\\n context_length: 512000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: zai\\n logo: https://assets.production.truefoundry.com/zai.svg\\n models:\\n - model_id: glm-5-turbo\\n name: glm-5-turbo\\n properties:\\n context_length: 200000\\n max_output_tokens: 131072\\n - model_id: glm-5.1\\n name: glm-5-1\\n properties:\\n context_length: 200000\\n max_output_tokens: 131072\\n - model_id: glm-5.2\\n name: glm-5-2\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: moonshot\\n logo: https://assets.production.truefoundry.com/moonshot.png\\n models:\\n - model_id: kimi-k2.7-code\\n name: kimi-k2-7-code\\n properties:\\n context_length: 262144\\n - model_id: kimi-k3\\n name: kimi-k3\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - low\\n - high\\n - max\\n - type: alibaba\\n logo: https://assets.production.truefoundry.com/alibaba.png\\n models:\\n - model_id: qwen3.7-flash\\n name: qwen3-7-flash\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: qwen3.7-max\\n name: qwen3-7-max\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: qwen3.7-plus\\n name: qwen3-7-plus\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: qwen3.8-max\\n name: qwen3-8-max\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: together\\n logo: https://assets.production.truefoundry.com/togetherai.svg\\n models:\\n - model_id: deepseek-ai/DeepSeek-V4-Pro\\n name: deepseek-v4-pro\\n properties:\\n context_length: 512000\\n reasoning_efforts:\\n - high\\n - max\\n - model_id: MiniMaxAI/MiniMax-M3\\n name: minimax-m3\\n properties:\\n context_length: 524288\\n - model_id: moonshotai/Kimi-K2.7-Code\\n name: kimi-k2-7-code\\n properties:\\n context_length: 262144\\n - model_id: moonshotai/Kimi-K3\\n name: kimi-k3\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - max\\n - model_id: Qwen/Qwen3.7-Max\\n name: qwen3-7-max\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: Qwen/Qwen3.7-Plus\\n name: qwen3-7-plus\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: zai-org/GLM-5.2\\n name: glm-5-2\\n properties:\\n context_length: 512000\\n reasoning_efforts:\\n - high\\n - max\\n\" as const;\n","/**\n * Shipped sandbox catalog (sandbox-catalog.yaml): the discovery list of provider\n * presets offered by GET /catalog/sandbox-providers for the UI to copy into\n * PUT /settings/sandbox-providers bodies. Never consulted on writes and never\n * read by the runtime.\n *\n * Default: YAML inlined into `sandboxCatalog.gen.ts` at build time. Optional\n * override: `SANDBOX_CATALOG_PATH` (file on disk).\n */\nimport configuration from '../config';\nimport { SandboxCatalogFileSchema, type CatalogSandboxProvider } from '../schemas/sandboxCatalog';\nimport { loadYamlAtPath, parseYamlString } from './loadYaml';\nimport { shippedSandboxCatalogYaml } from './sandboxCatalog.gen';\n\nexport class SandboxCatalog {\n private readonly providers: readonly CatalogSandboxProvider[];\n\n constructor(providers: readonly CatalogSandboxProvider[]) {\n this.providers = providers;\n }\n\n /** Loads and validates the catalog. Throws on any error. */\n static load(): SandboxCatalog {\n if (configuration.SANDBOX_CATALOG_PATH !== undefined) {\n const file = loadYamlAtPath(configuration.SANDBOX_CATALOG_PATH, SandboxCatalogFileSchema);\n return new SandboxCatalog(file.providers);\n }\n const file = parseYamlString(shippedSandboxCatalogYaml, SandboxCatalogFileSchema, 'shipped sandbox-catalog');\n return new SandboxCatalog(file.providers);\n }\n\n list(): readonly CatalogSandboxProvider[] {\n return this.providers;\n }\n}\n","// AUTO-GENERATED by scripts/generate-catalog.mjs — do not edit.\nexport const shippedSandboxCatalogYaml = \"# Shipped sandbox catalog: provider presets offered by\\n# GET /api/v1/catalog/sandbox-providers for the UI to copy into\\n# PUT /api/v1/settings/sandbox-providers bodies. Discovery-only — never executed against.\\nproviders:\\n - type: daytona\\n exec_timeout_ms: 60000\\n auto_stop_interval_in_minutes: 5\\n auto_archive_interval_in_minutes: 60\\n auto_delete_interval_in_minutes: 7200\\n\" as const;\n","/**\n * Shipped skill catalog (skill-catalog.yaml): the discovery list of skill\n * presets offered by GET /catalog/skills for the UI to copy into\n * PUT /settings/skills bodies. Never consulted on writes and never\n * read by the runtime.\n *\n * Default: YAML inlined into `skillCatalog.gen.ts` at build time. Optional\n * override: `SKILL_CATALOG_PATH` (file on disk).\n */\nimport configuration from '../config';\nimport { SkillCatalogFileSchema, type CatalogSkill } from '../schemas/skillCatalog';\nimport { loadYamlAtPath, parseYamlString } from './loadYaml';\nimport { shippedSkillCatalogYaml } from './skillCatalog.gen';\n\nexport class SkillCatalog {\n private readonly skills: readonly CatalogSkill[];\n\n constructor(skills: readonly CatalogSkill[]) {\n this.skills = skills;\n }\n\n /** Loads and validates the catalog. Throws on any error. */\n static load(): SkillCatalog {\n if (configuration.SKILL_CATALOG_PATH !== undefined) {\n const file = loadYamlAtPath(configuration.SKILL_CATALOG_PATH, SkillCatalogFileSchema);\n return new SkillCatalog(file.skills);\n }\n const file = parseYamlString(shippedSkillCatalogYaml, SkillCatalogFileSchema, 'shipped skill-catalog');\n return new SkillCatalog(file.skills);\n }\n\n list(): readonly CatalogSkill[] {\n return this.skills;\n }\n}\n","// AUTO-GENERATED by scripts/generate-catalog.mjs — do not edit.\nexport const shippedSkillCatalogYaml = \"# Shipped skill catalog: skill presets offered by\\n# GET /api/v1/catalog/skills for the UI to copy into\\n# PUT /api/v1/settings/skills bodies. Discovery-only — never executed against.\\n#\\n# Entries reference upstream skill repos directly (url + path + ref); installing\\n# a preset sparse-clones that subdirectory into the sandbox. Only permissively\\n# licensed skills (Apache-2.0 / MIT) are listed — licenses were verified against\\n# each skill's upstream LICENSE and are noted in the comments below. The schema\\n# stores only {type, name, url, path, ref, description}; license and the MCP a\\n# skill pairs with live in the comments for provenance.\\n#\\n# NOTE: Anthropic's document skills (pdf, docx, pptx, xlsx) are intentionally\\n# excluded — their LICENSE.txt is proprietary (\\\"All rights reserved\\\", usable\\n# only within Anthropic's Services) and forbids extracting/retaining/redistributing\\n# the materials, which a clone-into-sandbox preset would do.\\nskills:\\n # ── Anthropic skills (github.com/anthropics/skills · per-skill LICENSE, all Apache-2.0) ──\\n - type: git\\n name: algorithmic-art\\n url: https://github.com/anthropics/skills\\n path: skills/algorithmic-art\\n ref: main\\n description: Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration.\\n\\n # Agent-builder skills — author skills, MCP servers, and web artifacts.\\n - type: git\\n name: skill-creator\\n url: https://github.com/anthropics/skills\\n path: skills/skill-creator\\n ref: main\\n description: Scaffold, refine, and package new Agent Skills, including SKILL.md structure and evaluation.\\n - type: git\\n name: mcp-builder\\n url: https://github.com/anthropics/skills\\n path: skills/mcp-builder\\n ref: main\\n description: Build Model Context Protocol (MCP) servers — tool definitions, transports, and packaging.\\n - type: git\\n name: web-artifacts-builder\\n url: https://github.com/anthropics/skills\\n path: skills/web-artifacts-builder\\n ref: main\\n description: Build self-contained web artifacts (HTML/JS/CSS) that render as interactive standalone pages.\\n\\n # ── MCP-paired workflow skills (each pairs with the noted MCP connector) ──\\n\\n # tavily-research — pairs with the Tavily retrieval MCP. (tavily-ai/skills · MIT)\\n - type: git\\n name: tavily-research\\n url: https://github.com/tavily-ai/skills\\n path: skills/tavily-research\\n ref: main\\n description: Run structured web research with the Tavily MCP — search, extract, and synthesize sources.\\n\\n # supabase — pairs with the Supabase MCP. (supabase/agent-skills · MIT)\\n - type: git\\n name: supabase\\n url: https://github.com/supabase/agent-skills\\n path: skills/supabase\\n ref: main\\n description: Query and manage a Supabase Postgres database via SQL through the Supabase MCP.\\n\\n # wiki-architect / wiki-qa — pair with DeepWiki / GitHub for repo briefs. (microsoft/skills · MIT)\\n - type: git\\n name: wiki-architect\\n url: https://github.com/microsoft/skills\\n path: .github/plugins/deep-wiki/skills/wiki-architect\\n ref: main\\n description: Plan and structure a repository wiki / brief from a codebase (DeepWiki).\\n - type: git\\n name: wiki-qa\\n url: https://github.com/microsoft/skills\\n path: .github/plugins/deep-wiki/skills/wiki-qa\\n ref: main\\n description: Answer questions about a repository from its generated wiki (DeepWiki); companion to wiki-architect.\\n\\n # openai/skills — per-skill licenses (verified). Apache-2.0 unless noted.\\n # NOTE: this repo is deprecated upstream — plan to re-vendor from openai/plugins\\n # later and update the url/path/ref.\\n # linear — pairs with the Linear MCP. (Apache-2.0)\\n - type: git\\n name: linear\\n url: https://github.com/openai/skills\\n path: skills/.curated/linear\\n ref: main\\n description: Triage and manage Linear issues (create, update, search) via the Linear MCP.\\n # gh-fix-ci — pairs with the GitHub MCP. (Apache-2.0)\\n - type: git\\n name: gh-fix-ci\\n url: https://github.com/openai/skills\\n path: skills/.curated/gh-fix-ci\\n ref: main\\n description: Diagnose and fix failing GitHub CI checks on a pull request via the GitHub MCP.\\n # notion-knowledge-capture — pairs with the Notion MCP. (MIT · Notion Labs, Inc.)\\n - type: git\\n name: notion-knowledge-capture\\n url: https://github.com/openai/skills\\n path: skills/.curated/notion-knowledge-capture\\n ref: main\\n description: Capture and organize knowledge into Notion pages and databases via the Notion MCP.\\n # sentry — pairs with the Sentry MCP. (Apache-2.0)\\n - type: git\\n name: sentry\\n url: https://github.com/openai/skills\\n path: skills/.curated/sentry\\n ref: main\\n description: Investigate and triage Sentry errors and issues via the Sentry MCP.\\n # jupyter-notebook — data analysis (pairs with data/DB MCPs such as Supabase). (Apache-2.0)\\n - type: git\\n name: jupyter-notebook\\n url: https://github.com/openai/skills\\n path: skills/.curated/jupyter-notebook\\n ref: main\\n description: Perform data analysis in Jupyter notebooks — load data, compute, and visualize results.\\n\" as const;\n","/** Serves the built frontend, so one container answers both the UI and the API. */\nimport { serveStatic } from '@hono/node-server/serve-static';\nimport type { OpenAPIHono } from '@hono/zod-openapi';\nimport type { MiddlewareHandler } from 'hono';\nimport { every } from 'hono/combine';\nimport { compress } from 'hono/compress';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\n\n/** Routes the server answers itself; never served from the build. /api covers every version below it. */\nconst SERVER_PATH_PREFIXES = ['/api', '/healthz'];\n\n/** Only Vite's hashed asset names can be cached forever. */\nconst HASHED_ASSET_PREFIX = '/assets/';\nconst IMMUTABLE_CACHE_CONTROL = 'public, max-age=31536000, immutable';\nconst REVALIDATE_CACHE_CONTROL = 'no-cache';\n\nfunction isServerPath(pathname: string): boolean {\n return SERVER_PATH_PREFIXES.some(prefix => pathname === prefix || pathname.startsWith(`${prefix}/`));\n}\n\n/**\n * Must be called after the API routes are registered, so those always win over the static handler.\n * Returns false when `dir` holds no build, leaving the server API-only for UI work behind Vite.\n */\nexport function mountFrontend(app: OpenAPIHono, dir: string): boolean {\n if (!existsSync(path.join(dir, 'index.html'))) {\n return false;\n }\n\n // serveStatic joins `root` with the request path, so an absolute dir is working-directory proof.\n const serveFile = serveStatic({ root: dir, precompressed: true });\n\n const serveWithCacheHeaders: MiddlewareHandler = async (c, next) => {\n const response = await serveFile(c, next);\n // Only when a file was served: a missing asset must not cache its 404.\n if (response instanceof Response) {\n const cacheControl = c.req.path.startsWith(HASHED_ASSET_PREFIX)\n ? IMMUTABLE_CACHE_CONTROL\n : REVALIDATE_CACHE_CONTROL;\n response.headers.set('Cache-Control', cacheControl);\n // compress() below encodes without advertising it, which a shared cache would get wrong.\n response.headers.set('Vary', 'Accept-Encoding');\n }\n return response;\n };\n\n /**\n * compress() skips responses that already carry Content-Encoding, so it only reaches what the build\n * could not precompress: the Monaco workers. It stays behind the isServerPath guard below because\n * compressing an API response would buffer the SSE streams that must flush per event.\n */\n const serveCompressed = every(compress(), serveWithCacheHeaders);\n\n const serveBuild: MiddlewareHandler = async (c, next) => {\n if (isServerPath(c.req.path)) {\n return next();\n }\n if (c.req.method !== 'GET' && c.req.method !== 'HEAD') {\n return next();\n }\n return serveCompressed(c, next);\n };\n\n const serveAppShell = serveStatic({ root: dir, rewriteRequestPath: () => '/index.html', precompressed: true });\n\n /**\n * Client routes (`/sessions/{id}`, `/settings`) have no file on disk, so a\n * deep link only reaches the app when the shell answers the navigation.\n * Runs after `serveBuild`, so real files still win; requests that do not\n * accept HTML keep their 404 rather than getting the shell as a fake asset.\n */\n const serveSpaFallback: MiddlewareHandler = async (c, next) => {\n if (isServerPath(c.req.path)) {\n return next();\n }\n if (c.req.method !== 'GET' && c.req.method !== 'HEAD') {\n return next();\n }\n if (c.req.header('accept')?.includes('text/html') !== true) {\n return next();\n }\n\n const response = await serveAppShell(c, next);\n if (response instanceof Response) {\n response.headers.set('Cache-Control', REVALIDATE_CACHE_CONTROL);\n response.headers.set('Vary', 'Accept-Encoding');\n }\n return response;\n };\n\n app.use('/*', serveBuild);\n app.use('/*', serveSpaFallback);\n\n return true;\n}\n","/**\n * Process logger: human-readable lines in standalone mode, JSON otherwise.\n * Both formats include `version` (defaultMeta) so hosted aggregators can filter.\n */\nimport winston, { type Logger } from 'winston';\n\nconst STANDALONE_META_SKIP = new Set(['level', 'message', 'timestamp', 'version', 'stack', 'splat']);\n\nexport function shouldColorize(): boolean {\n const noColor = process.env['NO_COLOR'];\n if (noColor !== undefined && noColor !== '') {\n return false;\n }\n const forceColor = process.env['FORCE_COLOR'];\n if (forceColor === '0') {\n return false;\n }\n if (forceColor !== undefined && forceColor !== '') {\n return true;\n }\n return process.stderr.isTTY;\n}\n\nfunction standaloneMeta(info: object): string {\n const copied: Record<string, unknown> = { ...info };\n const meta: Record<string, unknown> = {};\n for (const key of Object.keys(copied)) {\n if (STANDALONE_META_SKIP.has(key)) {\n continue;\n }\n meta[key] = copied[key];\n }\n if (Object.keys(meta).length === 0) {\n return '';\n }\n return ` ${JSON.stringify(meta)}`;\n}\n\nfunction standaloneFormat(color: boolean): winston.Logform.Format {\n const parts: winston.Logform.Format[] = [\n winston.format.timestamp({ format: 'HH:mm:ss' }),\n winston.format.errors({ stack: true }),\n ];\n if (color) {\n parts.push(winston.format.colorize({ level: true }));\n }\n parts.push(\n winston.format.printf(info => {\n const extra = standaloneMeta(info);\n const stack = typeof info['stack'] === 'string' ? `\\n${info['stack']}` : '';\n return `${String(info['timestamp'])} ${info.level} ${String(info.message)}${extra}${stack}`;\n }),\n );\n return winston.format.combine(...parts);\n}\n\nfunction jsonFormat(): winston.Logform.Format {\n return winston.format.combine(\n winston.format.timestamp(),\n winston.format.errors({ stack: true }),\n winston.format.json(),\n );\n}\n\nfunction serverLogFormat(options: { standalone: boolean }): winston.Logform.Format {\n if (options.standalone) {\n return standaloneFormat(shouldColorize());\n }\n return jsonFormat();\n}\n\nexport function createServerLogger(options: { level: string; standalone: boolean; version: string }): Logger {\n return winston.createLogger({\n level: options.level,\n defaultMeta: { version: options.version },\n format: serverLogFormat({ standalone: options.standalone }),\n transports: [new winston.transports.Console()],\n });\n}\n","/**\n * In-memory registry of turns executing in this process. Keys are\n * `${sessionId}:${turnId}`. Cancel aborts via AbortController;\n * TurnHandle.stream() writes the terminal state when the signal fires.\n * `track()` owns registration and cleanup around the stream lifecycle.\n */\nimport { CancellationReason } from '@truefoundry/trueforge-core/agent-session';\n\ninterface ActiveTurnRun {\n abortController: AbortController;\n waitUntilCompleted: Promise<void>;\n markCompleted: () => void;\n}\n\nfunction activeTurnKey(sessionId: string, turnId: string): string {\n return `${sessionId}:${turnId}`;\n}\n\nexport class ActiveTurnRegistry {\n private readonly runs = new Map<string, ActiveTurnRun>();\n private alreadyShutDownAbortReason: CancellationReason | undefined;\n\n /**\n * Registers the run immediately, then returns a generator that forwards\n * `stream` and removes the run when the stream completes (or the consumer\n * exits early). If shutdown has already begun, aborts the controller with\n * the shutdown reason so the turn ends as abandoned.\n */\n track<T>(input: {\n sessionId: string;\n turnId: string;\n abortController: AbortController;\n stream: AsyncIterable<T>;\n }): AsyncGenerator<T> {\n const key = activeTurnKey(input.sessionId, input.turnId);\n const { promise: waitUntilCompleted, resolve } = Promise.withResolvers<undefined>();\n const markCompleted = (): void => {\n resolve(undefined);\n };\n const run: ActiveTurnRun = {\n abortController: input.abortController,\n waitUntilCompleted,\n markCompleted,\n };\n this.runs.set(key, run);\n\n // Accepted HTTP may still call track() after shutdownAndWait snapshotted;\n // abort immediately so the turn ends as abandoned instead of running past exit.\n if (this.alreadyShutDownAbortReason !== undefined) {\n if (!input.abortController.signal.aborted) {\n input.abortController.abort(this.alreadyShutDownAbortReason);\n }\n }\n\n const complete = () => {\n run.markCompleted();\n if (this.runs.get(key) === run) {\n this.runs.delete(key);\n }\n };\n async function* tracked(): AsyncGenerator<T> {\n try {\n yield* input.stream;\n } finally {\n complete();\n }\n }\n return tracked();\n }\n\n /**\n * Aborts the given turn if it is running in this process. Returns true when\n * the run was found (already-aborted runs are not re-aborted). Cancelling a\n * turn that is not running is a no-op, mirroring the store's\n * first-terminal-write-wins rule.\n */\n cancelIfRunning(input: { sessionId: string; turnId: string; abortReason: CancellationReason }): boolean {\n const run = this.runs.get(activeTurnKey(input.sessionId, input.turnId));\n if (!run) {\n return false;\n }\n if (!run.abortController.signal.aborted) {\n run.abortController.abort(input.abortReason);\n }\n return true;\n }\n\n /**\n * Enter shutdown mode, abort every run with `abortReason`, and wait until the\n * registry is empty. Late `track()` calls (in-flight HTTP that registered after\n * the first snapshot) are aborted immediately as `abortReason` and included in\n * subsequent wait iterations.\n */\n async shutdownAndWait(abortReason: CancellationReason): Promise<void> {\n this.alreadyShutDownAbortReason = abortReason;\n while (this.runs.size > 0) {\n const pending = Array.from(this.runs.values());\n for (const run of pending) {\n if (!run.abortController.signal.aborted) {\n run.abortController.abort(abortReason);\n }\n }\n await Promise.allSettled(pending.map(run => run.waitUntilCompleted));\n }\n }\n}\n","/**\n * Standalone boot chrome: wordmark, version, and a boxed local-only warning.\n * Printed raw (not through winston) so the art is not prefixed with timestamps.\n */\n\nconst STANDALONE_MODE_DISCLAIMER =\n 'Standalone mode is intended for local use on your own machine. It is not hardened for production or shared internet access — please keep it on localhost. We cannot take responsibility for data loss or unauthorized access if this mode is used beyond that.';\n\n/** ANSI Shadow glyphs used to render `TRUEFORGE`. Each letter is six equal-width rows. */\nconst ANSI_SHADOW: Record<string, readonly string[]> = {\n T: ['████████╗', '╚══██╔══╝', ' ██║ ', ' ██║ ', ' ██║ ', ' ╚═╝ '],\n R: ['██████╗ ', '██╔══██╗', '██████╔╝', '██╔══██╗', '██║ ██║', '╚═╝ ╚═╝'],\n U: ['██╗ ██╗', '██║ ██║', '██║ ██║', '██║ ██║', '╚██████╔╝', ' ╚═════╝ '],\n E: ['███████╗', '██╔════╝', '█████╗ ', '██╔══╝ ', '███████╗', '╚══════╝'],\n F: ['███████╗', '██╔════╝', '█████╗ ', '██╔══╝ ', '██║ ', '╚═╝ '],\n O: [' ██████╗ ', '██╔═══██╗', '██║ ██║', '██║ ██║', '╚██████╔╝', ' ╚═════╝ '],\n G: [' ██████╗ ', '██╔════╝ ', '██║ ███╗', '██║ ██║', '╚██████╔╝', ' ╚═════╝ '],\n};\n\nconst WORDMARK_TEXT = 'TRUEFORGE';\nconst WARNING_INNER_WIDTH = 72;\nconst BRAND_COLOR = '\\x1b[38;5;99m';\nconst YELLOW = '\\x1b[33m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\nfunction glyphFor(ch: string): readonly string[] {\n const glyph = ANSI_SHADOW[ch];\n if (glyph === undefined) {\n throw new Error(`No ASCII glyph for ${JSON.stringify(ch)}`);\n }\n return glyph;\n}\n\nfunction rowOf(glyph: readonly string[], row: number): string {\n const cell = glyph[row];\n if (cell === undefined) {\n throw new Error(`Glyph is missing row ${String(row)}`);\n }\n return cell;\n}\n\nfunction renderTrueForgeWordmark(): string {\n const glyphs: (readonly string[])[] = [];\n for (let i = 0; i < WORDMARK_TEXT.length; i += 1) {\n const ch = WORDMARK_TEXT[i];\n if (ch === undefined) {\n throw new Error(`Missing character at index ${String(i)}`);\n }\n glyphs.push(glyphFor(ch));\n }\n const rowCount = glyphs[0]?.length;\n if (rowCount === undefined) {\n throw new Error('Wordmark text must not be empty');\n }\n const rows: string[] = [];\n for (let row = 0; row < rowCount; row += 1) {\n rows.push(glyphs.map(glyph => rowOf(glyph, row)).join(''));\n }\n return rows.join('\\n');\n}\n\nfunction wrapText(text: string, width: number): string[] {\n const words = text.split(/\\s+/).filter(word => word.length > 0);\n const lines: string[] = [];\n let current = '';\n for (const word of words) {\n if (current.length === 0) {\n if (word.length > width) {\n lines.push(word);\n } else {\n current = word;\n }\n continue;\n }\n const next = `${current} ${word}`;\n if (next.length <= width) {\n current = next;\n } else {\n lines.push(current);\n current = word.length > width ? '' : word;\n if (word.length > width) {\n lines.push(word);\n }\n }\n }\n if (current.length > 0) {\n lines.push(current);\n }\n return lines;\n}\n\nfunction paint(options: { text: string; color: string; enabled: boolean }): string {\n if (!options.enabled) {\n return options.text;\n }\n return `${options.color}${options.text}${RESET}`;\n}\n\nfunction warningBox(message: string): string {\n const label = ' WARNING ';\n const inner = wrapText(message, WARNING_INNER_WIDTH);\n const width = Math.max(WARNING_INNER_WIDTH, ...inner.map(line => line.length), label.length);\n const topPad = width + 1 - label.length;\n const top = `┌─${label}${'─'.repeat(topPad)}┐`;\n const body = inner.map(line => `│ ${line.padEnd(width)} │`);\n const bottom = `└${'─'.repeat(width + 2)}┘`;\n return [top, ...body, bottom].join('\\n');\n}\n\nfunction formatStandaloneStartupBanner(options: { version: string; color: boolean }): {\n wordmark: string;\n warning: string;\n} {\n const { version, color } = options;\n const wordmark = paint({ text: renderTrueForgeWordmark(), color: `${BOLD}${BRAND_COLOR}`, enabled: color });\n const subtitle = paint({ text: ` TrueForge v${version} · standalone`, color: DIM, enabled: color });\n const warning = paint({ text: warningBox(STANDALONE_MODE_DISCLAIMER), color: `${BOLD}${YELLOW}`, enabled: color });\n return { wordmark: `\\n${wordmark}\\n${subtitle}\\n`, warning };\n}\n\nexport function printStandaloneStartupBanner(options: { version: string; color: boolean }): void {\n const { wordmark, warning } = formatStandaloneStartupBanner(options);\n console.log(wordmark);\n console.warn(warning);\n}\n"],"mappings":"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","names":["port","fs","path","path","init_sqlExpressions","SessionStoreConflictError","SessionStoreInvariantError","SessionStoreNotFoundError","TurnNotFoundError","sql","now","init_sqlExpressions","sql","now","SessionNotFoundError","TurnNotFoundError","sql","AgentSpecSchema","SessionNotFoundError","SessionStoreInvariantError","sql","isEmptyCustomRecord","now","sql","now","init_sqlExpressions","decodeOffsetPageToken","ulid","recordColumns","sql","sql","recordColumns","recordColumns","ulid","recordColumns","client_exports","isUniqueViolation","Kysely","init_client","fs","path","FileMigrationProvider","Migrator","extractErrorLogFields","sql","jsonbSet","path","init_sqlExpressions","sql","init_sqlExpressions","assertCreateTurnThreadDelta","PreviousTurnRunningError","SessionNotFoundError","SessionStoreConflictError","SessionStoreInvariantError","SessionStoreNotFoundError","TurnAlreadyExistsError","TurnNotFoundError","TurnNotRunningError","getEmptyCurrentContextUsage","sql","isEmptyCustomRecord","parseTurnCustom","terminalTurnState","classifyTurnFenceWriteFailure","classifyTurnThreadWriteFailure","assertTurnRunning","assembleTurnRecord","createTurn","now","isUniqueViolation","freezeAndGetTurn","getTurn","listTurns","updateTurnState","init_turns","init_client","init_sqlExpressions","sql","patchThreadCapabilityState","classifyTurnFenceWriteFailure","init_capabilities","init_sqlExpressions","init_turns","decodeOffsetPageToken","paginateOffsetRows","decodeSessionEventPageToken","paginateSessionEventRows","SessionNotFoundError","TurnNotFoundError","sql","appendToEvents","classifyTurnFenceWriteFailure","listTurnEvents","listSessionEvents","resolveAncestorChain","init_events","init_sqlExpressions","init_turns","decodeSessionListPageToken","paginateSessionListRows","SessionAlreadyExistsError","SessionNotFoundError","SessionStoreInvariantError","sql","isEmptyCustomRecord","parseSessionCustom","mapRowToSessionRecord","createSession","deleteSession","getSession","updateSession","listSessions","init_sessions","init_sqlExpressions","sql","addThreads","assertTurnRunning","now","removeThreads","classifyTurnFenceWriteFailure","completionPatchExpr","jsonbSet","usageSetExpr","fencedTurnThreadContextUpdate","classifyTurnThreadWriteFailure","appendToThreadContext","overwriteThreadContext","patchMCPServers","patchSandboxInfo","init_threads","init_sqlExpressions","init_turns","decodeOffsetPageToken","encodeOffsetPageToken","init_capabilities","init_events","init_sessions","init_threads","init_turns","createSession","deleteSession","getSession","updateSession","listSessions","createTurn","freezeAndGetTurn","getTurn","listTurns","updateTurnState","appendToEvents","addThreads","removeThreads","appendToThreadContext","overwriteThreadContext","patchMCPServers","patchSandboxInfo","patchThreadCapabilityState","listTurnEvents","listSessionEvents","toRecord","init_client","init_sqlExpressions","isUniqueViolation","ulid","toRecord","init_client","init_sqlExpressions","isUniqueViolation","savePendingAuthorization","consumePendingAuthorization","deletePendingAuthorizationsForServer","init_pendingAuthorization","init_sqlExpressions","sql","saveToken","getToken","getTokens","deleteToken","deleteTokensForServer","init_token","init_sqlExpressions","init_pendingAuthorization","init_token","savePendingAuthorization","consumePendingAuthorization","saveToken","getToken","getTokens","deleteToken","deleteTokensForServer","deletePendingAuthorizationsForServer","toRecord","init_client","init_sqlExpressions","isUniqueViolation","toRecord","init_sqlExpressions","ulid","toRecord","init_client","init_sqlExpressions","isUniqueViolation","extractErrorLogFields","path","CancellationReason","OpenAPIHono","z","extractErrorLogFields","HTTPException","OpenAPIHono","z","z","AgentSpecSchema","z","AgentSpecSchema","z","z","McpConnectionError","McpConnectionError","z","z","z","ulid","z","createRoute","z","z","z","z","AgentSpecSchema","TokenPaginationSchema","z","AgentSpecSchema","TokenPaginationSchema","z","TokenPaginationSchema","TurnSchema","z","createRoute","HTTPException","z","ulid","user","session","OpenAPIHono","OpenAPIHono","extractErrorLogFields","z","HTTPException","oidcVerify","HTTPException","createRoute","z","createRoute","OpenAPIHono","extractErrorLogFields","OpenAPIHono","extractErrorLogFields","createRoute","z","z","createRoute","OpenAPIHono","extractErrorLogFields","OpenAPIHono","SUPPORTED_REASONING_EFFORTS","createRoute","z","z","z","z","z","z","z","z","z","z","z","z","createRoute","SUPPORTED_REASONING_EFFORTS","OpenAPIHono","OpenAPIHono","extractErrorLogFields","McpConnectionError","createRoute","createRoute","McpConnectionError","extractErrorLogFields","OpenAPIHono","OpenAPIHono","extractErrorLogFields","McpConnectionError","createRoute","z","createRoute","z","extractErrorLogFields","McpConnectionError","OpenAPIHono","OpenAPIHono","createRoute","createRoute","OpenAPIHono","OpenAPIHono","OpenAPIHono","createRoute","createRoute","OpenAPIHono","OpenAPIHono","createRoute","createRoute","OpenAPIHono","OpenAPIHono","createRoute","createRoute","OpenAPIHono","OpenAPIHono","OpenAPIHono","CancellationReason","EventType","SessionStoreConflictError","SessionStoreNotFoundError","extractErrorLogFields","McpConnectionError","SandboxError","HTTPException","createRoute","z","SESSIONS_TAG","z","createRoute","path","path","HTTPException","EventType","SessionStoreNotFoundError","extractErrorLogFields","FORBIDDEN_SESSION_ACCESS","SessionStoreConflictError","SandboxError","McpConnectionError","CancellationReason","OpenAPIHono","path","fileURLToPath","PACKAGE_ROOT","z","z","HTTPException","extractErrorLogFields","OpenAPIHono","file","file","file","file","existsSync","path","configuration","isOidcConfigured","path","createSqliteDb","migrateSqliteToLatest","SqliteSessionStore","SqliteModelProviderStore","SqliteMcpServerStore","SqliteOAuthTokenStore","SqliteSkillStore","SqliteSandboxProviderStore","SqliteAgentStore","createDb","migrateToLatest","connectRedis","PostgresSessionStore","PostgresModelProviderStore","PostgresMcpServerStore","PostgresOAuthTokenStore","PostgresSkillStore","PostgresSandboxProviderStore","PostgresAgentStore","extractErrorLogFields","CancellationReason"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/db/agentStore.ts","../src/sandbox/local/sandboxScripts.gen.ts","../src/sandbox/local/schemas/jsonMessage.ts","../src/sandbox/local/core/frame.ts","../src/sandbox/local/core/CodeModeUdsTransport.ts","../src/sandbox/local/core/hostRun.ts","../src/sandbox/local/schemas/xferFileInfo.ts","../src/sandbox/local/provider/LocalSandboxProvider.ts","../src/db/mcpServerStore.ts","../src/db/modelProviderStore.ts","../src/db/skillStore.ts","../src/db/sqlite/client.ts","../src/db/migrateSqlite.ts","../src/db/sqlite/sqlExpressions.ts","../src/db/sqlite/session-store/sqlExpressions.ts","../src/db/sqlite/session-store/queries/turns.ts","../src/db/sqlite/session-store/queries/capabilities.ts","../src/db/sqlite/session-store/queries/events.ts","../src/db/sessionAgentColumns.ts","../src/db/sqlite/session-store/queries/sessions.ts","../src/db/sqlite/session-store/queries/threads.ts","../src/db/sqlite/session-store/SqliteSessionStore.ts","../src/db/sqlite/model-provider-store/SqliteModelProviderStore.ts","../src/db/sqlite/mcp-server-store/SqliteMcpServerStore.ts","../src/db/sqlite/token-store/queries/pendingAuthorization.ts","../src/db/sqlite/token-store/queries/token.ts","../src/db/sqlite/token-store/SqliteOAuthTokenStore.ts","../src/db/sqlite/skill-store/SqliteSkillStore.ts","../src/db/sqlite/sandbox-provider-store/SqliteSandboxProviderStore.ts","../src/db/sqlite/agent-store/SqliteAgentStore.ts","../src/db/postgres/client.ts","../src/db/migratePostgres.ts","../src/runtime/redis.ts","../src/db/postgres/sqlExpressions.ts","../src/db/postgres/session-store/sqlExpressions.ts","../src/db/postgres/session-store/queries/turns.ts","../src/db/postgres/session-store/queries/capabilities.ts","../src/db/postgres/session-store/queries/events.ts","../src/db/postgres/session-store/queries/sessions.ts","../src/db/postgres/session-store/queries/threads.ts","../src/db/postgres/session-store/PostgresSessionStore.ts","../src/db/postgres/model-provider-store/PostgresModelProviderStore.ts","../src/db/postgres/mcp-server-store/PostgresMcpServerStore.ts","../src/db/postgres/token-store/queries/pendingAuthorization.ts","../src/db/postgres/token-store/queries/token.ts","../src/db/postgres/token-store/PostgresOAuthTokenStore.ts","../src/db/postgres/skill-store/PostgresSkillStore.ts","../src/db/postgres/sandbox-provider-store/PostgresSandboxProviderStore.ts","../src/db/postgres/agent-store/PostgresAgentStore.ts","../src/main.ts","../src/sandbox/localLifecycle.ts","../src/sandbox/localRuntime.ts","../src/app.ts","../src/apis/agents.ts","../src/routes/agentRoutes.ts","../src/schemas/agent.ts","../src/schemas/common.ts","../src/schemas/errors.ts","../src/routes/openapiTags.ts","../src/runtime/sessionResources.ts","../src/mcp/auth/mcpDcr.ts","../src/mcp/auth/mcpOAuthHelpers.ts","../src/sandbox/providerUtils.ts","../src/schemas/sandboxProvider.ts","../src/schemas/mcpServer.ts","../src/apis/sessions.ts","../src/routes/sessionRoutes.ts","../src/schemas/events.ts","../src/schemas/session.ts","../src/schemas/turn.ts","../src/routes/fernExtensions.ts","../src/runtime/peeringIds.ts","../src/apis/auth.ts","../src/auth/cookies.ts","../src/auth/oidc.ts","../src/auth/claims.ts","../src/auth/safeReturnTo.ts","../src/auth/identity.ts","../src/auth/middleware.ts","../src/routes/authRoutes.ts","../src/schemas/auth.ts","../src/apis/capabilities.ts","../src/routes/capabilityRoutes.ts","../src/apis/catalog.ts","../src/routes/catalogRoutes.ts","../src/schemas/mcpCatalog.ts","../src/schemas/modelCatalog.ts","../src/schemas/modelProvider.ts","../src/schemas/sandboxCatalog.ts","../src/schemas/skillCatalog.ts","../src/schemas/skill.ts","../src/apis/mcpOAuth.ts","../src/routes/mcpOAuthRoutes.ts","../src/apis/mcpServers.ts","../src/routes/mcpServerRoutes.ts","../src/utils/secretRedaction.ts","../src/apis/models.ts","../src/routes/modelRoutes.ts","../src/apis/settings.ts","../src/apis/modelProviders.ts","../src/routes/modelProviderRoutes.ts","../src/apis/sandboxProviders.ts","../src/routes/sandboxProviderRoutes.ts","../src/apis/skills.ts","../src/routes/skillRoutes.ts","../src/apis/turns.ts","../src/routes/turnRoutes.ts","../src/runtime/event-subscription/inMemory.ts","../src/runtime/event-subscription/redis.ts","../src/runtime/event-subscription/index.ts","../src/runtime/sandboxFilePath.ts","../src/packageVersion.ts","../src/zodErrorResponse.ts","../src/catalog/McpCatalog.ts","../src/catalog/loadYaml.ts","../src/catalog/mcpCatalog.gen.ts","../src/catalog/ModelCatalog.ts","../src/catalog/modelCatalog.gen.ts","../src/catalog/SandboxCatalog.ts","../src/catalog/sandboxCatalog.gen.ts","../src/catalog/SkillCatalog.ts","../src/catalog/skillCatalog.gen.ts","../src/frontend.ts","../src/logger.ts","../src/runtime/activeTurns.ts","../src/startupBanner.ts"],"sourcesContent":["/**\n * Server configuration.\n *\n * Environment variables are read once at module load into a typed\n * `configuration` object exported as default. Any invalid value throws at\n * import time, so a misconfigured server fails fast at boot instead of\n * mid-run.\n *\n * `STANDALONE` is a discriminated mode selector:\n * - `true` (default): SQLite only; no Redis / executor peering.\n * - `false`: Postgres + Redis (defaults to local trueforge credentials /\n * `redis://localhost:6379`).\n */\nimport { existsSync } from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport envPaths from 'env-paths';\n\nconst DEFAULT_PORT = 8790;\n/** Loopback default; container images set HOST=0.0.0.0 so probes and Service traffic reach the process. */\nconst DEFAULT_HOST = 'localhost';\n/** Default HTTP request body ceiling: 30 MB. */\nconst DEFAULT_MAX_REQUEST_BODY_BYTES = 30 * 1024 * 1024;\n/**\n * Package root whether this module runs as `src/config.ts` (tsx) or is bundled\n * into `dist/main.js` / `dist/cli.js` (`import.meta` → `dist/` → parent).\n */\nconst PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');\n/** Turn ids minted by a standalone process; no peer can ever own them. */\nconst LOCAL_EXECUTOR_ID = 'local';\n/** OS-standard data dir for SQLite in standalone mode. */\nconst ENV_PATHS_APP_NAME = 'trueforge';\nconst DEFAULT_POSTGRES_USER = 'trueforge';\nconst DEFAULT_POSTGRES_PASSWORD = 'trueforge';\nconst DEFAULT_POSTGRES_DB = 'trueforge';\nconst DEFAULT_POSTGRES_HOST = 'localhost';\nconst DEFAULT_POSTGRES_PORT = 5432;\nconst DEFAULT_REDIS_URL = 'redis://localhost:6379';\n\nconst DEFAULT_OIDC_USER_REFERENCE_CLAIM = 'sub';\nconst DEFAULT_OIDC_USER_ROLE_CLAIM = 'groups';\nconst DEFAULT_OIDC_ADMIN_ROLE_VALUE = 'admin';\nconst DEFAULT_OIDC_SCOPES = 'openid,profile,email';\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\nexport interface GetEnvOptions {\n defaultValue?: string;\n required?: boolean;\n}\n\nfunction getEnv(key: string, options?: GetEnvOptions): string | undefined {\n const value = process.env[key];\n if (value !== undefined) {\n return value;\n }\n\n // Checking for undefined as value can also be 0 or \"\"\n if (options?.defaultValue !== undefined) {\n return options.defaultValue;\n }\n\n if (options?.required) {\n throw new Error(`Environment variable ${key} is required but was not specified.`);\n }\n\n return undefined;\n}\n\nfunction randomAlphanumeric(length: number): string {\n return Array.from({ length }, () => Math.floor(Math.random() * 36).toString(36)).join('');\n}\n\nfunction parsePort(raw: string | undefined): number {\n if (raw === undefined || raw.trim() === '') {\n return DEFAULT_PORT;\n }\n const port = Number(raw);\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n throw new Error(`Environment variable PORT must be an integer between 1 and 65535, got \"${raw}\"`);\n }\n return port;\n}\n\nexport function parseOidcScopes(raw: string): string[] {\n const scopes = raw\n .split(',')\n .map(part => part.trim())\n .filter(part => part.length > 0);\n if (scopes.length === 0) {\n throw new Error('OIDC_SCOPES must contain at least one scope.');\n }\n return scopes;\n}\n\n/** Parses a positive-integer env var, falling back to `defaultValue` when unset/blank. */\nfunction parsePositiveInt(options: { envKey: string; raw: string | undefined; defaultValue: number }): number {\n const { envKey, raw, defaultValue } = options;\n if (raw === undefined || raw.trim() === '') {\n return defaultValue;\n }\n const value = Number(raw);\n if (!Number.isInteger(value) || value < 1) {\n throw new Error(`Environment variable ${envKey} must be a positive integer, got \"${raw}\"`);\n }\n return value;\n}\n\n/** Parses a boolean env var; anything but `true`/`false` throws instead of reading as `false`. */\nfunction parseBoolean(options: { envKey: string; raw: string | undefined; defaultValue: boolean }): boolean {\n const { envKey, raw, defaultValue } = options;\n if (raw === undefined || raw.trim() === '') {\n return defaultValue;\n }\n const value = raw.trim().toLowerCase();\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n throw new Error(`Environment variable ${envKey} must be \"true\" or \"false\", got \"${raw}\"`);\n}\n\n/**\n * Prefer `dist/_frontend` shipped in the npm tarball (npx / `pnpm start`).\n * Fall back to the monorepo sibling `../frontend/dist` (host-dev before a copy).\n */\nfunction resolveDefaultFrontendDir(): string {\n const packaged = path.join(PACKAGE_ROOT, 'dist', '_frontend');\n if (existsSync(path.join(packaged, 'index.html'))) {\n return packaged;\n }\n return path.join(PACKAGE_ROOT, '..', 'frontend', 'dist');\n}\n\nfunction resolveFrontendDir(): string {\n const override = getEnv('FRONTEND_DIR');\n if (override !== undefined && override.trim() !== '') {\n return path.resolve(override);\n }\n return resolveDefaultFrontendDir();\n}\n\n/** Absolute path from an optional env override; unset/blank → `undefined`. */\nfunction resolveOptionalPathEnv(envKey: string): string | undefined {\n const override = getEnv(envKey);\n if (override === undefined || override.trim() === '') {\n return undefined;\n }\n return path.resolve(override);\n}\n\n/**\n * Absolute SQLite file path for standalone mode.\n * Env: `SQLITE_PATH` (optional). Default: `{env-paths data}/db/db.sqlite`.\n */\nfunction resolveSqlitePath(): string {\n const override = getEnv('SQLITE_PATH');\n if (override !== undefined && override.trim() !== '') {\n return path.resolve(override);\n }\n const paths = envPaths(ENV_PATHS_APP_NAME, { suffix: '' });\n return path.join(paths.data, 'db', 'db.sqlite');\n}\n\n/** Parent for local sandbox roots. Same env-paths data dir as SQLite (`{suffix:''}`). */\nfunction resolveLocalSandboxRootParent(): string {\n return path.join(envPaths(ENV_PATHS_APP_NAME, { suffix: '' }).data, 'sandboxes');\n}\n\n/** Short tmp parent for Code Mode UDS socks (≤65 bytes after realpath). */\nfunction resolveCodeModeSocketParent(): string {\n return path.join(os.tmpdir(), 'tf_cms');\n}\n\n/** Redis peering URL for distributed mode. Env: `REDIS_URL`. */\nfunction resolveRedisUrl(): string {\n const raw = getEnv('REDIS_URL', { defaultValue: DEFAULT_REDIS_URL }) ?? DEFAULT_REDIS_URL;\n if (raw.trim() === '') {\n throw new Error('Environment variable REDIS_URL must be non-empty when STANDALONE=false.');\n }\n return raw;\n}\n\n/** Postgres connection string derived from `POSTGRES_*` for distributed mode. */\nfunction resolvePostgresDatabaseUrl(): string {\n const postgresUser = getEnv('POSTGRES_USER', { defaultValue: DEFAULT_POSTGRES_USER }) ?? DEFAULT_POSTGRES_USER;\n const postgresPassword =\n getEnv('POSTGRES_PASSWORD', { defaultValue: DEFAULT_POSTGRES_PASSWORD }) ?? DEFAULT_POSTGRES_PASSWORD;\n const postgresDb = getEnv('POSTGRES_DB', { defaultValue: DEFAULT_POSTGRES_DB }) ?? DEFAULT_POSTGRES_DB;\n const postgresHost = getEnv('POSTGRES_HOST', { defaultValue: DEFAULT_POSTGRES_HOST }) ?? DEFAULT_POSTGRES_HOST;\n const postgresPort = parsePositiveInt({\n envKey: 'POSTGRES_PORT',\n raw: getEnv('POSTGRES_PORT'),\n defaultValue: DEFAULT_POSTGRES_PORT,\n });\n if (\n postgresUser.trim() === '' ||\n postgresPassword.trim() === '' ||\n postgresDb.trim() === '' ||\n postgresHost.trim() === ''\n ) {\n throw new Error(\n 'POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, and POSTGRES_HOST must be non-empty when STANDALONE=false.',\n );\n }\n return buildPostgresConnectionString({\n user: postgresUser,\n password: postgresPassword,\n host: postgresHost,\n port: postgresPort,\n database: postgresDb,\n });\n}\n\n/** Builds a Postgres connection URL from discrete `POSTGRES_*` parts. */\nfunction buildPostgresConnectionString(parts: {\n user: string;\n password: string;\n host: string;\n port: number;\n database: string;\n}): string {\n return `postgres://${encodeURIComponent(parts.user)}:${encodeURIComponent(parts.password)}@${parts.host}:${String(parts.port)}/${encodeURIComponent(parts.database)}`;\n}\n\nfunction resolveOIDCConfig(): OIDCConfig | undefined {\n const issuerUrl = getEnv('OIDC_ISSUER_URL');\n const clientId = getEnv('OIDC_CLIENT_ID');\n const clientSecret = getEnv('OIDC_CLIENT_SECRET');\n\n if (!issuerUrl && !clientId && !clientSecret) {\n return undefined;\n }\n if (!issuerUrl || !clientId || !clientSecret) {\n throw new Error(\n 'OIDC_ISSUER_URL, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET must all be set together, or all left unset ' +\n '(unset = fixed local admin identity, no IdP).',\n );\n }\n return {\n OIDC_ISSUER_URL: issuerUrl,\n OIDC_CLIENT_ID: clientId,\n OIDC_CLIENT_SECRET: clientSecret,\n OIDC_USER_REFERENCE_CLAIM:\n getEnv('OIDC_USER_REFERENCE_CLAIM', { defaultValue: DEFAULT_OIDC_USER_REFERENCE_CLAIM }) ??\n DEFAULT_OIDC_USER_REFERENCE_CLAIM,\n OIDC_USER_ROLE_CLAIM:\n getEnv('OIDC_USER_ROLE_CLAIM', { defaultValue: DEFAULT_OIDC_USER_ROLE_CLAIM }) ?? DEFAULT_OIDC_USER_ROLE_CLAIM,\n OIDC_ADMIN_ROLE_VALUE:\n getEnv('OIDC_ADMIN_ROLE_VALUE', { defaultValue: DEFAULT_OIDC_ADMIN_ROLE_VALUE }) ?? DEFAULT_OIDC_ADMIN_ROLE_VALUE,\n OIDC_SCOPES: parseOidcScopes(getEnv('OIDC_SCOPES', { defaultValue: DEFAULT_OIDC_SCOPES }) ?? DEFAULT_OIDC_SCOPES),\n };\n}\n\n// ============================================================================\n// CONFIGURATION TYPES\n// ============================================================================\n\nexport interface OIDCConfig {\n /** e.g. an Okta custom authorization server, or an Azure AD tenant's v2.0 endpoint. Env: `OIDC_ISSUER_URL`. */\n OIDC_ISSUER_URL: string;\n /** Client ID for the OIDC client;*/\n OIDC_CLIENT_ID: string;\n /** Client secret for the OIDC client*/\n OIDC_CLIENT_SECRET: string;\n /** Claim to be used as the user reference; e.g. \"sub\" or \"email\"\n * Optional; defaults to \"sub\"\n */\n OIDC_USER_REFERENCE_CLAIM: string;\n /** Claim to be used as the user role; e.g. \"role\" or \"groups\"\n * Optional; defaults to \"groups\"\n */\n OIDC_USER_ROLE_CLAIM: string;\n /** Value of the user role claim that will be used to grant admin access to the server\n * Case sensitive. Optional; defaults to \"admin\"\n */\n OIDC_ADMIN_ROLE_VALUE: string;\n /** Comma-separated OAuth scopes for the authorization request. Env: `OIDC_SCOPES`.\n * Optional; defaults to \"openid,profile,email\". Whitespace around entries is stripped.\n * Okta `groups` claims require the `groups` scope; Azure AD app roles typically omit it.\n */\n OIDC_SCOPES: string[];\n}\n\nexport interface SharedServerConfiguration {\n /** Log level. Env: `LOG_LEVEL`. */\n LOG_LEVEL: string;\n /** Node environment. Env: `NODE_ENV`. */\n NODE_ENV: string | undefined;\n /** HTTP port the server listens on. Env: `PORT`. */\n PORT: number;\n /** HTTP bind address. Env: `HOST`. Default `localhost`; production images use `0.0.0.0`. */\n HOST: string;\n /** Peering identity embedded in the turn ids this process mints; `local` in standalone mode. */\n EXECUTOR_ID: string;\n /**\n * Optional override for the model catalog YAML (discovery presets for\n * GET /catalogs/model-providers). When unset, the catalog inlined at build\n * time is used. Env: `MODEL_CATALOG_PATH`.\n */\n MODEL_CATALOG_PATH: string | undefined;\n /**\n * Optional override for the MCP catalog YAML (discovery presets for\n * GET /catalogs/mcp-servers). When unset, the catalog inlined at build\n * time is used. Env: `MCP_CATALOG_PATH`.\n */\n MCP_CATALOG_PATH: string | undefined;\n /**\n * Optional override for the skill catalog YAML (discovery presets for\n * GET /catalogs/skills). When unset, the catalog inlined at build\n * time is used. Env: `SKILL_CATALOG_PATH`.\n */\n SKILL_CATALOG_PATH: string | undefined;\n /**\n * Optional override for the sandbox catalog YAML (discovery presets for\n * GET /catalogs/sandbox-providers). When unset, the catalog inlined at build\n * time is used. Env: `SANDBOX_CATALOG_PATH`.\n */\n SANDBOX_CATALOG_PATH: string | undefined;\n /**\n * Frontend build served alongside the API; a missing directory leaves the server API-only.\n * Env: `FRONTEND_DIR`. Default: packaged `dist/_frontend` (npx tarball) or\n * monorepo `packages/frontend/dist` — always absolute, independent of CWD.\n */\n FRONTEND_DIR: string;\n /** Max milliseconds for one MCP request. Env: `MCP_REQUEST_TIMEOUT_MS`. Default 4 minutes. */\n MCP_REQUEST_TIMEOUT_MS: number;\n /** Max milliseconds for an MCP transport connection. Env: `MCP_CONNECT_TIMEOUT_MS`. Default 30 seconds. */\n MCP_CONNECT_TIMEOUT_MS: number;\n /**\n * Client name used for Dynamic Client Registration (DCR) of MCP servers.\n * This is the client name shown on authorization-server consent screens.\n * Env: `MCP_DCR_OAUTH_CLIENT_NAME`. Default: \"truefoundry-harness\".\n */\n MCP_DCR_OAUTH_CLIENT_NAME: string;\n /**\n * Max bytes for a single file download out of the sandbox.\n * Env: `SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD`. Default 20 MB (same as gateway).\n */\n SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD: number;\n /**\n * Max bytes for an HTTP request body. Env: `MAX_REQUEST_BODY_BYTES`. Default 30 MB.\n */\n MAX_REQUEST_BODY_BYTES: number;\n /**\n * Max seconds to wait for turn cancellation + connection drain on SIGTERM/SIGINT.\n * Env: `GRACEFUL_TIMEOUT_SECONDS`. Default 30.\n */\n GRACEFUL_TIMEOUT_SECONDS: number;\n /**\n * Max seconds a single turn may execute before it is cancelled with\n * `server-execution-timeout`. Env: `SERVER_EXECUTION_TIMEOUT_SECONDS`. Default 600 (10 minutes).\n */\n SERVER_EXECUTION_TIMEOUT_SECONDS: number;\n /**\n * TTL for a running turn's resumable event stream.\n * Env: `TURN_STREAM_TTL_SECONDS`. Default execution timeout + 300.\n */\n TURN_STREAM_TTL_SECONDS: number;\n /**\n * TTL retained after `turn.done` so subscribers can drain remaining events.\n * Env: `TURN_STREAM_POST_COMPLETION_TTL_SECONDS`. Default 300.\n */\n TURN_STREAM_POST_COMPLETION_TTL_SECONDS: number;\n /**\n * Max ms to keep a turn subscription open.\n * Env: `TURN_SUBSCRIBE_TIMEOUT_MS`. Default 600000.\n */\n TURN_SUBSCRIBE_TIMEOUT_MS: number;\n /**\n * Max ms to wait for a peer executor's reply before failing with 424.\n * Env: `REDIS_REQUEST_REPLY_TIMEOUT_MS`. Default 60000.\n * Only used when a Redis client is wired (distributed mode).\n */\n REDIS_REQUEST_REPLY_TIMEOUT_MS: number;\n /**\n * How often this process refreshes its peering heartbeat key.\n * Env: `REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS`. Default 5000.\n * Only used when a Redis client is wired (distributed mode).\n */\n REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS: number;\n /**\n * TTL for reply values so abandoned reply keys are reclaimed.\n * Env: `REDIS_REQUEST_REPLY_REPLY_TTL_MS`. Default 120000.\n * Only used when a Redis client is wired (distributed mode).\n */\n REDIS_REQUEST_REPLY_REPLY_TTL_MS: number;\n /**\n * Sleep between reply poll attempts while waiting on a peer.\n * Env: `REDIS_REQUEST_REPLY_POLL_INTERVAL_MS`. Default 500.\n * Only used when a Redis client is wired (distributed mode).\n */\n REDIS_REQUEST_REPLY_POLL_INTERVAL_MS: number;\n}\n\nexport type StandaloneServerConfiguration = SharedServerConfiguration & {\n /**\n * Single-process topology: SQLite persistence, no Redis / executor peering.\n * Env: `STANDALONE`. Default: true.\n */\n STANDALONE: true;\n /**\n * Absolute SQLite database file path.\n * Env: `SQLITE_PATH` (optional). Default: env-paths data dir + `db/db.sqlite`.\n */\n SQLITE_PATH: string;\n /**\n * Parent directory for local sandbox roots (ULID children).\n * Derived: `{env-paths data}/sandboxes`.\n */\n LOCAL_SANDBOX_ROOT_PARENT: string;\n /**\n * Parent directory for Code Mode UDS sockets (`tf_cms` under os.tmpdir()).\n * Caller prepares/removes this directory; must stay ≤65 bytes after realpath.\n */\n CODE_MODE_SOCKET_PARENT: string;\n};\n\nexport type DistributedServerConfiguration = SharedServerConfiguration & {\n /**\n * Multi-replica topology: Postgres persistence + Redis executor peering.\n * Env: `STANDALONE`. Default: true (so this branch requires an explicit `false`).\n */\n STANDALONE: false;\n /**\n * Public base URL of this server used as the origin of MCP OAuth and OIDC\n * callbacks. Optional at boot; MCP OAuth and OIDC callback construction fail\n * if empty.\n */\n PUBLIC_BASE_URL: string;\n /**\n * Postgres connection string derived from `POSTGRES_*` (not read from env directly).\n * Form: `postgres://USER:PASSWORD@HOST:PORT/DB` with user/password URL-encoded.\n */\n DATABASE_URL: string;\n /** Max connections in the `pg` Pool. Env: `DATABASE_POOL_MAX`. Default 10. */\n DATABASE_POOL_MAX: number;\n /**\n * Postgres `statement_timeout` for app and migrations (same pool).\n * Env: `POSTGRES_STATEMENT_TIMEOUT_MS`. Default 60000.\n */\n POSTGRES_STATEMENT_TIMEOUT_MS: number;\n /**\n * Postgres `idle_in_transaction_session_timeout` for app and migrations (same pool).\n * Env: `POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS`. Default 60000.\n */\n POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS: number;\n /** Peering URL shared by all replicas. Env: `REDIS_URL`. Default `redis://localhost:6379`. */\n REDIS_URL: string;\n /**\n * OIDC configuration for server authentication.\n * Undefined means browser login is disabled.\n */\n OIDC: OIDCConfig | undefined;\n};\n\nexport type ServerConfiguration = StandaloneServerConfiguration | DistributedServerConfiguration;\n\n// ============================================================================\n// CONFIGURATION VALUES\n// ============================================================================\n\nconst serverExecutionTimeoutSeconds = parsePositiveInt({\n envKey: 'SERVER_EXECUTION_TIMEOUT_SECONDS',\n raw: getEnv('SERVER_EXECUTION_TIMEOUT_SECONDS'),\n defaultValue: 600,\n});\n\nconst standalone = parseBoolean({\n envKey: 'STANDALONE',\n raw: getEnv('STANDALONE'),\n defaultValue: true,\n});\n\nconst port = parsePort(getEnv('PORT'));\nconst host = getEnv('HOST', { defaultValue: DEFAULT_HOST }) ?? DEFAULT_HOST;\n\nconst shared: SharedServerConfiguration = {\n LOG_LEVEL: getEnv('LOG_LEVEL', { defaultValue: 'info' }) ?? 'info',\n NODE_ENV: getEnv('NODE_ENV'),\n PORT: port,\n HOST: host,\n EXECUTOR_ID: standalone ? LOCAL_EXECUTOR_ID : randomAlphanumeric(6),\n MODEL_CATALOG_PATH: resolveOptionalPathEnv('MODEL_CATALOG_PATH'),\n MCP_CATALOG_PATH: resolveOptionalPathEnv('MCP_CATALOG_PATH'),\n SKILL_CATALOG_PATH: resolveOptionalPathEnv('SKILL_CATALOG_PATH'),\n SANDBOX_CATALOG_PATH: resolveOptionalPathEnv('SANDBOX_CATALOG_PATH'),\n FRONTEND_DIR: resolveFrontendDir(),\n\n MCP_REQUEST_TIMEOUT_MS: parsePositiveInt({\n envKey: 'MCP_REQUEST_TIMEOUT_MS',\n raw: getEnv('MCP_REQUEST_TIMEOUT_MS'),\n defaultValue: 4 * 60 * 1000,\n }),\n MCP_CONNECT_TIMEOUT_MS: parsePositiveInt({\n envKey: 'MCP_CONNECT_TIMEOUT_MS',\n raw: getEnv('MCP_CONNECT_TIMEOUT_MS'),\n defaultValue: 30 * 1000,\n }),\n MCP_DCR_OAUTH_CLIENT_NAME:\n getEnv('MCP_DCR_OAUTH_CLIENT_NAME', { defaultValue: 'truefoundry-harness' }) ?? 'truefoundry-harness',\n SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD: parsePositiveInt({\n envKey: 'SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD',\n raw: getEnv('SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD'),\n defaultValue: 20_971_520,\n }),\n MAX_REQUEST_BODY_BYTES: parsePositiveInt({\n envKey: 'MAX_REQUEST_BODY_BYTES',\n raw: getEnv('MAX_REQUEST_BODY_BYTES'),\n defaultValue: DEFAULT_MAX_REQUEST_BODY_BYTES,\n }),\n GRACEFUL_TIMEOUT_SECONDS: parsePositiveInt({\n envKey: 'GRACEFUL_TIMEOUT_SECONDS',\n raw: getEnv('GRACEFUL_TIMEOUT_SECONDS'),\n defaultValue: 30,\n }),\n SERVER_EXECUTION_TIMEOUT_SECONDS: serverExecutionTimeoutSeconds,\n TURN_STREAM_TTL_SECONDS: parsePositiveInt({\n envKey: 'TURN_STREAM_TTL_SECONDS',\n raw: getEnv('TURN_STREAM_TTL_SECONDS'),\n defaultValue: serverExecutionTimeoutSeconds + 300,\n }),\n TURN_STREAM_POST_COMPLETION_TTL_SECONDS: parsePositiveInt({\n envKey: 'TURN_STREAM_POST_COMPLETION_TTL_SECONDS',\n raw: getEnv('TURN_STREAM_POST_COMPLETION_TTL_SECONDS'),\n defaultValue: 300,\n }),\n TURN_SUBSCRIBE_TIMEOUT_MS: parsePositiveInt({\n envKey: 'TURN_SUBSCRIBE_TIMEOUT_MS',\n raw: getEnv('TURN_SUBSCRIBE_TIMEOUT_MS'),\n defaultValue: 600_000,\n }),\n REDIS_REQUEST_REPLY_TIMEOUT_MS: parsePositiveInt({\n envKey: 'REDIS_REQUEST_REPLY_TIMEOUT_MS',\n raw: getEnv('REDIS_REQUEST_REPLY_TIMEOUT_MS'),\n defaultValue: 60_000,\n }),\n REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS: parsePositiveInt({\n envKey: 'REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS',\n raw: getEnv('REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS'),\n defaultValue: 5_000,\n }),\n REDIS_REQUEST_REPLY_REPLY_TTL_MS: parsePositiveInt({\n envKey: 'REDIS_REQUEST_REPLY_REPLY_TTL_MS',\n raw: getEnv('REDIS_REQUEST_REPLY_REPLY_TTL_MS'),\n defaultValue: 120_000,\n }),\n REDIS_REQUEST_REPLY_POLL_INTERVAL_MS: parsePositiveInt({\n envKey: 'REDIS_REQUEST_REPLY_POLL_INTERVAL_MS',\n raw: getEnv('REDIS_REQUEST_REPLY_POLL_INTERVAL_MS'),\n defaultValue: 500,\n }),\n};\n\nconst configuration: ServerConfiguration = standalone\n ? {\n ...shared,\n STANDALONE: true,\n SQLITE_PATH: resolveSqlitePath(),\n LOCAL_SANDBOX_ROOT_PARENT: resolveLocalSandboxRootParent(),\n CODE_MODE_SOCKET_PARENT: resolveCodeModeSocketParent(),\n }\n : {\n ...shared,\n STANDALONE: false,\n PUBLIC_BASE_URL: getEnv('PUBLIC_BASE_URL', { defaultValue: '' }) ?? '',\n DATABASE_URL: resolvePostgresDatabaseUrl(),\n DATABASE_POOL_MAX: parsePositiveInt({\n envKey: 'DATABASE_POOL_MAX',\n raw: getEnv('DATABASE_POOL_MAX'),\n defaultValue: 10,\n }),\n POSTGRES_STATEMENT_TIMEOUT_MS: parsePositiveInt({\n envKey: 'POSTGRES_STATEMENT_TIMEOUT_MS',\n raw: getEnv('POSTGRES_STATEMENT_TIMEOUT_MS'),\n defaultValue: 60_000,\n }),\n POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS: parsePositiveInt({\n envKey: 'POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS',\n raw: getEnv('POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS'),\n defaultValue: 60_000,\n }),\n REDIS_URL: resolveRedisUrl(),\n OIDC: resolveOIDCConfig(),\n };\n\nexport function isOidcConfigured(\n value: ServerConfiguration,\n): value is DistributedServerConfiguration & { OIDC: OIDCConfig } {\n return !value.STANDALONE && value.OIDC !== undefined;\n}\n\n/**\n * Public origin for OAuth callbacks.\n * Standalone → `http://localhost:$PORT`; distributed → `PUBLIC_BASE_URL` (may be `''`).\n */\nexport function getPublicBaseUrl(config: ServerConfiguration = configuration): string {\n if (config.STANDALONE) {\n return `http://localhost:${String(config.PORT)}`;\n }\n if (config.PUBLIC_BASE_URL === '') {\n throw new Error('PUBLIC_BASE_URL is required for OIDC callbacks but was empty');\n }\n return config.PUBLIC_BASE_URL;\n}\n\nexport default configuration;\n","/**\n * DB-backed configured agents: one row per agent per tenant,\n * immutable ULID `id`, unique immutable `name` within a tenant, plus a Zod-validated\n * `AgentSpec` jsonb document.\n * Implementations: PostgresAgentStore and SqliteAgentStore.\n */\nimport { AgentSpecSchema, type AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport type { ResourceName } from '../schemas/common';\n\nexport interface AgentRecord {\n id: string;\n tenant_id: string;\n name: ResourceName;\n manifest: AgentSpec;\n /** ISO-8601 UTC instant. */\n created_at: string;\n /** ISO-8601 UTC instant. */\n updated_at: string;\n}\n\n/**\n * Re-parse persisted manifest JSON so schema defaults (e.g. nested `config`) materialize.\n * Rows written before a config field existed omit it on disk; readers must not assume presence.\n */\nexport function parseStoredAgentSpec(manifest: unknown): AgentSpec {\n return AgentSpecSchema.parse(manifest);\n}\n\n/** Look up by immutable id or unique name within a tenant. */\nexport type GetAgentInput = { tenant_id: string } & ({ id: string } | { name: string });\n\nexport interface CreateAgentInput {\n tenant_id: string;\n name: ResourceName;\n manifest: AgentSpec;\n}\n\n/** Replace manifest for an existing agent keyed by immutable id. */\nexport interface UpdateAgentInput {\n tenant_id: string;\n id: string;\n manifest: AgentSpec;\n}\n\nexport interface DeleteAgentInput {\n tenant_id: string;\n id: string;\n}\n\n/** Unique `(tenant_id, name)` violation on create. */\nexport class AgentNameConflictError extends Error {\n readonly tenant_id: string;\n readonly agent_name: string;\n\n constructor({ tenant_id, name }: { tenant_id: string; name: string }, options?: ErrorOptions) {\n super(`Agent name already exists: ${name}`, options);\n this.name = 'AgentNameConflictError';\n this.tenant_id = tenant_id;\n this.agent_name = name;\n }\n}\n\nexport interface IAgentStore<TTransaction = never> {\n listAgents(tenantId: string, transaction?: TTransaction): Promise<AgentRecord[]>;\n getAgent(input: GetAgentInput, transaction?: TTransaction): Promise<AgentRecord | undefined>;\n /** Inserts a new agent with a generated ULID. Throws AgentNameConflictError on name clash. */\n createAgent(input: CreateAgentInput, transaction?: TTransaction): Promise<AgentRecord>;\n /** Replaces `manifest` for an existing id. Returns undefined if missing. */\n updateAgent(input: UpdateAgentInput, transaction?: TTransaction): Promise<AgentRecord | undefined>;\n /** Deletes by immutable id. Idempotent if already missing. */\n deleteAgent(input: DeleteAgentInput, transaction?: TTransaction): Promise<void>;\n}\n","// AUTO-GENERATED by scripts/generate-local-sandbox-scripts.mjs — do not edit.\nexport const sandboxScripts = {\n mcpClientLocal: \"#!/usr/bin/env python3\\n\\\"\\\"\\\"Code Mode UDS client — same public surface as product mcp_client.py, stdlib only.\\n\\nAuthoritative reference (do not diverge on API/CLI/policy semantics):\\n packages/trueforge-core/src/core/sandbox/scripts/mcp_client.py\\n\\nInlined into TypeScript via scripts/generate-local-sandbox-scripts.mjs\\n(src/sandbox/local/sandboxScripts.gen.ts), same pattern as core sandboxScripts.\\n\\\"\\\"\\\"\\n\\nfrom __future__ import annotations\\n\\nimport argparse\\nimport asyncio\\nimport base64\\nimport json\\nimport logging\\nimport os\\nimport socket\\nimport sys\\nimport time\\nfrom pathlib import Path\\nfrom typing import Any, TypedDict\\n\\nlogger = logging.getLogger(__name__)\\n\\nMAX_MESSAGE_BYTES = 64 * 1024 * 1024\\n_TOOLS_CACHE_TTL_SECONDS = 600\\n\\n\\nclass _ServerConfig(TypedDict):\\n allowed_tools: list[str]\\n\\n\\n_inflight_list_tools: dict[str, asyncio.Task[list[dict[str, Any]]]] = {}\\n\\n_raw_servers = os.environ.get(\\\"TFY_MCP_SERVERS\\\")\\n_servers_map: dict[str, _ServerConfig] = (\\n json.loads(base64.b64decode(_raw_servers).decode()) if _raw_servers else {}\\n)\\n_enable_agent_approvals = os.environ.get(\\\"TFY_ENABLE_AGENT_APPROVALS\\\", \\\"true\\\").lower() == \\\"true\\\"\\n\\n\\ndef _sock_path() -> str:\\n path = os.environ.get(\\\"TFY_MCP_SOCK\\\")\\n if not path:\\n raise RuntimeError(\\\"TFY_MCP_SOCK is not set\\\")\\n return path\\n\\n\\ndef _request_timeout() -> float:\\n return float(os.environ.get(\\\"TFY_CM_REQUEST_TIMEOUT_SECONDS\\\", \\\"60\\\"))\\n\\n\\ndef _check_tool_allowed(server: str, tool_name: str) -> None:\\n server_config = _servers_map.get(server)\\n if server_config is None:\\n raise RuntimeError(f\\\"Access denied: MCP server '{server}' is not available for this agent\\\") from None\\n server_tools = server_config.get(\\\"allowed_tools\\\") or []\\n if len(server_tools) > 0 and tool_name not in server_tools:\\n raise RuntimeError(f\\\"Access denied: tool '{tool_name}' is not enabled on server '{server}'\\\") from None\\n\\n\\ndef _cache_path(server: str) -> Path:\\n return Path(__file__).parent / f\\\"{server}.tools.json\\\"\\n\\n\\ndef _read_tools_cache(server: str) -> list[dict[str, Any]] | None:\\n p = _cache_path(server)\\n if not p.exists():\\n return None\\n try:\\n raw = json.loads(p.read_text(encoding=\\\"utf-8\\\"))\\n if not isinstance(raw, dict):\\n raise ValueError(\\\"cache root must be object\\\")\\n fetched_at = raw.get(\\\"fetched_at\\\")\\n tools = raw.get(\\\"tools\\\")\\n if not isinstance(fetched_at, (int, float)) or not isinstance(tools, list):\\n raise ValueError(\\\"cache shape invalid\\\")\\n if time.time() - float(fetched_at) > _TOOLS_CACHE_TTL_SECONDS:\\n p.unlink(missing_ok=True)\\n return None\\n return [t for t in tools if isinstance(t, dict)]\\n except Exception:\\n logger.exception(\\\"_read_tools_cache\\\")\\n p.unlink(missing_ok=True)\\n return None\\n\\n\\ndef _write_tools_cache(server: str, tools: list[dict[str, Any]]) -> None:\\n try:\\n payload = {\\\"fetched_at\\\": time.time(), \\\"tools\\\": tools}\\n _cache_path(server).write_text(json.dumps(payload), encoding=\\\"utf-8\\\")\\n except Exception:\\n logger.exception(\\\"_write_tools_cache\\\")\\n\\n\\ndef _read_message(sock: socket.socket) -> Any:\\n body = b\\\"\\\"\\n while True:\\n chunk = sock.recv(65536)\\n if not chunk:\\n break\\n body += chunk\\n if len(body) > MAX_MESSAGE_BYTES:\\n raise RuntimeError(f\\\"message exceeds max {MAX_MESSAGE_BYTES} bytes\\\")\\n return json.loads(body.decode(\\\"utf-8\\\"))\\n\\n\\ndef _write_message(sock: socket.socket, value: Any) -> None:\\n sock.sendall(json.dumps(value).encode(\\\"utf-8\\\"))\\n\\n\\ndef _uds_request_sync(payload: dict[str, Any]) -> Any:\\n \\\"\\\"\\\"Connect → JSON request → write-close → JSON reply (no request_id).\\\"\\\"\\\"\\n sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)\\n try:\\n sock.settimeout(_request_timeout())\\n sock.connect(_sock_path())\\n _write_message(sock, payload)\\n sock.shutdown(socket.SHUT_WR)\\n reply = _read_message(sock)\\n finally:\\n sock.close()\\n if not isinstance(reply, dict):\\n raise RuntimeError(f\\\"Code Mode reply is not an object: {reply!r}\\\")\\n ok = reply.get(\\\"ok\\\")\\n if ok is not True:\\n source = reply.get(\\\"source\\\", \\\"internal\\\")\\n error = reply.get(\\\"error\\\", \\\"unknown error\\\")\\n if source == \\\"caller\\\":\\n raise RuntimeError(f\\\"Invalid MCP request: {error}\\\")\\n if source == \\\"transport\\\":\\n raise RuntimeError(f\\\"Code Mode transport error: {error}\\\")\\n raise RuntimeError(f\\\"Internal MCP error: {error}\\\")\\n return reply.get(\\\"result\\\")\\n\\n\\nasync def _uds_request(payload: dict[str, Any]) -> Any:\\n return await asyncio.to_thread(_uds_request_sync, payload)\\n\\n\\nasync def _fetch_tools(server: str) -> list[dict[str, Any]]:\\n result = await _uds_request({\\\"op\\\": \\\"list_tools\\\", \\\"server\\\": server})\\n if not isinstance(result, dict):\\n raise RuntimeError(f\\\"list_tools '{server}' returned unexpected shape: {result!r}\\\") from None\\n tools = result.get(\\\"tools\\\", [])\\n if not isinstance(tools, list):\\n raise RuntimeError(f\\\"list_tools '{server}' tools is not a list: {tools!r}\\\") from None\\n return [t for t in tools if isinstance(t, dict)]\\n\\n\\nasync def _fetch_and_cache_tools(server: str) -> list[dict[str, Any]]:\\n tools = await _fetch_tools(server)\\n _write_tools_cache(server, tools)\\n return tools\\n\\n\\nasync def _get_tools(server: str) -> list[dict[str, Any]]:\\n cached = _read_tools_cache(server)\\n if cached is not None:\\n return cached\\n task = _inflight_list_tools.get(server)\\n if task is None:\\n task = asyncio.create_task(_fetch_and_cache_tools(server))\\n _inflight_list_tools[server] = task\\n task.add_done_callback(lambda _t: _inflight_list_tools.pop(server, None))\\n return await task\\n\\n\\nasync def _get_tool(server: str, tool_name: str) -> dict[str, Any] | None:\\n for t in await _get_tools(server):\\n if t.get(\\\"name\\\") == tool_name:\\n return t\\n return None\\n\\n\\ndef _is_destructive(tool: dict[str, Any]) -> bool:\\n annotations = tool.get(\\\"annotations\\\")\\n if annotations is None:\\n return False\\n if not isinstance(annotations, dict):\\n return False\\n destructive = annotations.get(\\\"destructiveHint\\\")\\n read_only = annotations.get(\\\"readOnlyHint\\\")\\n return bool(destructive) or (not read_only and read_only is not None)\\n\\n\\nasync def _ensure_non_destructive(server: str, tool_name: str) -> None:\\n tool = await _get_tool(server, tool_name)\\n if tool is None:\\n raise RuntimeError(f\\\"Tool '{tool_name}' not found on MCP server '{server}'\\\") from None\\n if _is_destructive(tool):\\n raise RuntimeError(\\n f\\\"Tool '{tool_name}' on MCP server '{server}' is destructive and cannot be called in Code Mode; \\\"\\n f\\\"call it directly so it can go through the user approval flow\\\"\\n ) from None\\n\\n\\ndef _project_call_tool_result(server: str, tool: str, result: Any) -> Any:\\n \\\"\\\"\\\"Project an MCP-wire CallToolResult-shaped object into the user-facing Python value.\\\"\\\"\\\"\\n if not isinstance(result, dict):\\n raise RuntimeError(f\\\"call_tool reply for '{server}/{tool}' is malformed: expected object\\\") from None\\n\\n if result.get(\\\"isError\\\"):\\n content = result.get(\\\"content\\\")\\n text_parts: list[str] = []\\n if isinstance(content, list):\\n for c in content:\\n if isinstance(c, dict) and c.get(\\\"type\\\") == \\\"text\\\":\\n text = c.get(\\\"text\\\")\\n if isinstance(text, str) and text:\\n text_parts.append(text)\\n msg = \\\"; \\\".join(text_parts) if text_parts else \\\"tool returned an error\\\"\\n raise RuntimeError(f\\\"MCP tool error (server={server}, tool={tool}): {msg}\\\") from None\\n\\n if result.get(\\\"structuredContent\\\") is not None:\\n return result[\\\"structuredContent\\\"]\\n\\n content = result.get(\\\"content\\\")\\n if isinstance(content, list) and len(content) == 1:\\n first = content[0]\\n if isinstance(first, dict) and first.get(\\\"type\\\") == \\\"text\\\":\\n text = first.get(\\\"text\\\")\\n if isinstance(text, str) and text:\\n try:\\n return json.loads(text)\\n except Exception:\\n pass\\n if isinstance(content, list) and content:\\n return content\\n return None\\n\\n\\nasync def call_tool(server: str, tool: str, body: dict[str, Any]) -> Any:\\n _check_tool_allowed(server, tool)\\n if _enable_agent_approvals:\\n await _ensure_non_destructive(server, tool)\\n\\n raw = await _uds_request(\\n {\\n \\\"op\\\": \\\"call_tool\\\",\\n \\\"server\\\": server,\\n \\\"tool\\\": tool,\\n \\\"arguments\\\": body,\\n },\\n )\\n return _project_call_tool_result(server, tool, raw)\\n\\n\\n_USAGE = \\\"mcp_client_local.py call-tool <server> <tool> <args-json>\\\"\\n\\n\\ndef _build_arg_parser() -> argparse.ArgumentParser:\\n parser = argparse.ArgumentParser(prog=\\\"mcp_client_local.py\\\", usage=_USAGE)\\n sub = parser.add_subparsers(dest=\\\"cmd\\\", required=True)\\n\\n call_tool_p = sub.add_parser(\\\"call-tool\\\", help=\\\"Invoke an MCP tool\\\")\\n call_tool_p.add_argument(\\\"server\\\")\\n call_tool_p.add_argument(\\\"tool\\\")\\n call_tool_p.add_argument(\\\"args_json\\\", metavar=\\\"args-json\\\", type=json.loads)\\n\\n return parser\\n\\n\\nasync def _main() -> None:\\n args = _build_arg_parser().parse_args()\\n try:\\n if args.cmd == \\\"call-tool\\\":\\n result = await call_tool(args.server, args.tool, args.args_json)\\n print(json.dumps(result, default=str))\\n except RuntimeError as e:\\n sys.exit(str(e))\\n\\n\\nif __name__ == \\\"__main__\\\":\\n asyncio.run(_main())\\n\",\n} as const;\n","/** Code Mode UDS JSON payload after JSON.parse (any JSON value). */\nimport { z } from 'zod';\n\nexport const JsonMessageValueSchema = z.json();\n","/**\n * Code Mode UDS payload: one UTF-8 JSON value per connection.\n * Peer write-close (EOF) delimits the message; no length prefix.\n */\nimport { JsonMessageValueSchema } from '../schemas/jsonMessage.js';\n\nexport const MAX_MESSAGE_BYTES = 64 * 1024 * 1024;\n\nexport function encodeJsonMessage(value: unknown): Buffer {\n return Buffer.from(JSON.stringify(value), 'utf8');\n}\n\n/** Accumulates inbound socket bytes until EOF, then parses JSON. */\nexport class JsonMessageReader {\n #buffer = Buffer.alloc(0);\n readonly #maxBytes: number;\n\n constructor(options: { maxBytes?: number } = {}) {\n this.#maxBytes = options.maxBytes ?? MAX_MESSAGE_BYTES;\n }\n\n push(chunk: Buffer): void {\n if (this.#buffer.length + chunk.length > this.#maxBytes) {\n throw new Error(`message exceeds max ${String(this.#maxBytes)} bytes`);\n }\n this.#buffer = Buffer.concat([this.#buffer, chunk]);\n }\n\n finish(): unknown {\n try {\n return JsonMessageValueSchema.parse(JSON.parse(this.#buffer.toString('utf8')));\n } catch (error) {\n throw new Error('invalid JSON message', { cause: error });\n }\n }\n}\n","/**\n * Handle-scoped Code Mode UDS transport. Listen/accept live for the Sandbox handle lifetime;\n * one UTF-8 JSON request/reply per connection (peer write-close); no request_id.\n *\n * Sockets live under {@link CodeModeUdsTransportOptions.codeModeSocketParentPath} as ULID names.\n * Parent must be mode 0700 (enforced) so other accounts cannot replace the sock inode before\n * connect; after listen the sock is chmod 0600. Same-UID isolation is still SRT path policy:\n * hostRun grants the parent in allowRead (Linux) / allowUnixSockets (macOS), not host /tmp.\n * The caller owns that parent directory's lifetime; this transport unlinks the sock it creates.\n */\nimport type {\n CodeModeClientInstall,\n CodeModeDispatcher,\n CodeModeReply,\n CodeModeRequest,\n CodeModeTransport,\n} from '@truefoundry/trueforge-core/core';\nimport { CodeModeRequestSchema, validateNoPathTraversal } from '@truefoundry/trueforge-core/core';\nimport { chmodSync, existsSync, realpathSync, statSync } from 'node:fs';\nimport { chmod, mkdir, rm, symlink, unlink, writeFile } from 'node:fs/promises';\nimport { createServer, type Server, type Socket } from 'node:net';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\nimport { ulid } from 'ulid';\nimport { sandboxScripts } from '../sandboxScripts.gen.js';\nimport { encodeJsonMessage, JsonMessageReader, MAX_MESSAGE_BYTES } from './frame.js';\n\n/**\n * Max realpath bytes for the sock parent. Full path is `parent/ulid` (26-char name).\n * 63 was too tight after macOS `/private` realpath; 65 leaves headroom under sun_path.\n */\nexport const MAX_CODE_MODE_SOCKET_PARENT_BYTES = 65;\nconst CODE_MODE_SOCKET_PARENT_MODE = 0o700;\nconst CODE_MODE_SOCKET_MODE = 0o600;\n\n/** Install layout for local Code Mode MCP client (sandboxId = absolute sandbox root). */\nexport function localMcpClientRemotePath(sandboxId: string): string {\n return join(sandboxId, 'mcp-client', 'mcp_client.py');\n}\n\n/** Install the local Code Mode MCP client into the sandbox (same layout as Sandbox.init). */\nexport async function installMcpFixture(sandboxRootPath: string): Promise<{ remotePath: string }> {\n const remotePath = localMcpClientRemotePath(sandboxRootPath);\n const binLink = join(dirname(remotePath), 'bin', 'mcp-client');\n await mkdir(dirname(binLink), { recursive: true, mode: 0o700 });\n await writeFile(remotePath, sandboxScripts.mcpClientLocal, { encoding: 'utf8', mode: 0o555 });\n await rm(binLink, { force: true });\n await symlink(remotePath, binLink);\n return { remotePath };\n}\n\nexport interface CodeModeUdsTransportOptions {\n /**\n * Absolute existing directory for Code Mode UDS files (≤65 bytes after realpath, mode 0700).\n * Socket path is `join(parent, ulid)`; sock is chmod 0600 after listen.\n */\n codeModeSocketParentPath: string;\n maxMessageBytes?: number | undefined;\n /** Provider-owned MCP client module path (cwd-relative under the sandbox root). */\n clientRemotePath: (sandboxId: string) => string;\n /** Optional: observe inbound protocol failures (oversized / malformed). */\n onProtocolError?: ((message: string) => void) | undefined;\n}\n\n/** Validate and normalize parent dir for Code Mode socks; enforce mode 0700. */\nexport function assertCodeModeSocketParentPath(path: string): string {\n if (!isAbsolute(path)) {\n throw new Error('codeModeSocketParentPath must be an absolute path');\n }\n validateNoPathTraversal(path);\n const resolved = resolve(path);\n if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {\n throw new Error('codeModeSocketParentPath must be an existing directory');\n }\n // Seatbelt / allowUnixSockets match real paths (/private/var/... on macOS).\n const real = realpathSync(resolved);\n const bytes = Buffer.byteLength(real);\n if (bytes > MAX_CODE_MODE_SOCKET_PARENT_BYTES) {\n throw new Error(\n `codeModeSocketParentPath (${real}) must be at most ${String(MAX_CODE_MODE_SOCKET_PARENT_BYTES)} bytes (got ${String(bytes)})`,\n );\n }\n // Owner-only parent: other accounts cannot rename/replace socks under this dir.\n chmodSync(real, CODE_MODE_SOCKET_PARENT_MODE);\n const mode = statSync(real).mode & 0o777;\n if (mode !== CODE_MODE_SOCKET_PARENT_MODE) {\n throw new Error(`codeModeSocketParentPath must be mode 0700 after chmod (got 0o${mode.toString(8)})`);\n }\n return real;\n}\n\n/**\n * Bind+close a ULID-named sock under `parentPath`. Surfaces ENAMETOOLONG / EINVAL\n * that the byte-length check alone can miss (sun_path, realpath).\n */\nexport async function probeCodeModeUnixSocket(parentPath: string): Promise<{ sockPath: string }> {\n const realParent = assertCodeModeSocketParentPath(parentPath);\n const sockPath = join(realParent, ulid().toLowerCase());\n await unlink(sockPath).catch(() => undefined);\n const server = createServer();\n try {\n await new Promise<void>((resolveListen, reject) => {\n server.once('error', reject);\n server.listen(sockPath, () => {\n server.off('error', reject);\n resolveListen();\n });\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`listen ${sockPath} (${String(Buffer.byteLength(sockPath))} bytes): ${message}`, { cause: error });\n } finally {\n await new Promise<void>(resolveClose => {\n server.close(() => {\n resolveClose();\n });\n });\n await unlink(sockPath).catch(() => undefined);\n }\n return { sockPath };\n}\n\nexport class CodeModeUdsTransport implements CodeModeTransport {\n private readonly codeModeSocketParentPath: string;\n private readonly maxMessageBytes: number;\n private readonly onProtocolError: ((message: string) => void) | undefined;\n private readonly clientRemotePath: (sandboxId: string) => string;\n\n private sessionPromise: Promise<{ env: Record<string, string> }> | undefined;\n private server: Server | undefined;\n private sockPath: string | undefined;\n private dispatcher: CodeModeDispatcher | undefined;\n private cachedEnv: Record<string, string> | undefined;\n\n constructor(options: CodeModeUdsTransportOptions) {\n this.codeModeSocketParentPath = assertCodeModeSocketParentPath(options.codeModeSocketParentPath);\n this.maxMessageBytes = options.maxMessageBytes ?? MAX_MESSAGE_BYTES;\n this.onProtocolError = options.onProtocolError;\n this.clientRemotePath = options.clientRemotePath;\n }\n\n getClientInstall(params: { sandboxId: string }): CodeModeClientInstall {\n return {\n content: sandboxScripts.mcpClientLocal,\n remotePath: this.clientRemotePath(params.sandboxId),\n };\n }\n\n start(params: {\n codeModeDispatcher: CodeModeDispatcher;\n sandboxId: string;\n requestTimeoutSeconds: number;\n }): Promise<{ env: Record<string, string> }> {\n this.dispatcher = params.codeModeDispatcher;\n this.sessionPromise ??= this.listenSession(params).catch((e: unknown) => {\n this.sessionPromise = undefined;\n this.cachedEnv = undefined;\n throw e;\n });\n return this.sessionPromise;\n }\n\n async stop(): Promise<void> {\n const pending = this.sessionPromise;\n this.sessionPromise = undefined;\n this.cachedEnv = undefined;\n if (pending !== undefined) {\n try {\n await pending;\n } catch {\n // Listen failed; nothing to close.\n }\n }\n const server = this.server;\n const sockPath = this.sockPath;\n this.server = undefined;\n this.sockPath = undefined;\n if (server !== undefined) {\n await new Promise<void>(resolveClose => {\n server.close(() => {\n resolveClose();\n });\n });\n }\n if (sockPath !== undefined) {\n await unlink(sockPath).catch(() => undefined);\n }\n }\n\n private async listenSession(params: { requestTimeoutSeconds: number }): Promise<{ env: Record<string, string> }> {\n if (this.server !== undefined && this.cachedEnv !== undefined) {\n return { env: this.cachedEnv };\n }\n\n // Re-check: caller owns the parent dir and may have removed it after construct.\n assertCodeModeSocketParentPath(this.codeModeSocketParentPath);\n\n const sockPath = join(this.codeModeSocketParentPath, ulid().toLowerCase());\n await unlink(sockPath).catch(() => undefined);\n const server = createServer({ allowHalfOpen: true });\n try {\n await new Promise<void>((resolveListen, reject) => {\n server.once('error', reject);\n server.listen(sockPath, () => {\n server.off('error', reject);\n resolveListen();\n });\n });\n // Narrow the listen→chmod window; 0700 parent already blocks other accounts from replace.\n await chmod(sockPath, CODE_MODE_SOCKET_MODE);\n } catch (error) {\n server.close();\n await unlink(sockPath).catch(() => undefined);\n throw error;\n }\n\n this.server = server;\n this.sockPath = sockPath;\n server.on('connection', socket => {\n this.handleConnection(socket);\n });\n\n const env = {\n TFY_MCP_SOCK: sockPath,\n TFY_CM_REQUEST_TIMEOUT_SECONDS: String(params.requestTimeoutSeconds),\n };\n this.cachedEnv = env;\n return { env };\n }\n\n private handleConnection(socket: Socket): void {\n const reader = new JsonMessageReader({ maxBytes: this.maxMessageBytes });\n let settled = false;\n\n socket.on('error', () => undefined);\n\n // Oversized / malformed frames only tear down this connection (and notify\n // onProtocolError). Transport is handle-scoped and does not kill the process group.\n const fail = (message: string): void => {\n if (settled) {\n return;\n }\n settled = true;\n this.onProtocolError?.(message);\n socket.destroy();\n };\n\n socket.on('data', (chunk: Buffer) => {\n try {\n reader.push(chunk);\n } catch (error) {\n fail(error instanceof Error ? error.message : String(error));\n }\n });\n\n socket.on('end', () => {\n if (settled) {\n return;\n }\n settled = true;\n void this.dispatchConnection(socket, reader).catch((error: unknown) => {\n this.onProtocolError?.(error instanceof Error ? error.message : String(error));\n socket.destroy();\n });\n });\n }\n\n private async dispatchConnection(socket: Socket, reader: JsonMessageReader): Promise<void> {\n let request: CodeModeRequest;\n try {\n const parsed = CodeModeRequestSchema.safeParse(reader.finish());\n if (!parsed.success) {\n const reply: CodeModeReply = {\n ok: false,\n error: 'Malformed Code Mode request',\n source: 'caller',\n };\n socket.write(encodeJsonMessage(reply));\n socket.end();\n return;\n }\n request = parsed.data;\n } catch (error) {\n this.onProtocolError?.(error instanceof Error ? error.message : String(error));\n socket.destroy();\n return;\n }\n\n const dispatcher = this.dispatcher;\n if (dispatcher === undefined) {\n const reply: CodeModeReply = {\n ok: false,\n error: 'Code Mode dispatcher is not configured',\n source: 'internal',\n };\n socket.write(encodeJsonMessage(reply));\n socket.end();\n return;\n }\n\n const reply = await dispatcher.dispatch({ request, traceCarrier: {} });\n try {\n socket.write(encodeJsonMessage(reply));\n } finally {\n socket.end();\n }\n }\n}\n","/**\n * Host-side sandboxed exec (in-process supervisor).\n * Only the untrusted command argv is SRT-wrapped. Code Mode UDS is owned by\n * {@link CodeModeUdsTransport} (handle-scoped); pass TFY_MCP_SOCK via `env` when needed.\n *\n * Platform policy (allowRead / AF_UNIX / PATH) uses {@link LocalSandboxPlatform} from\n * {@link initSrt} — the same platform captured by LocalSandboxProvider.isSupported.\n */\nimport { getDefaultWritePaths, SandboxManager } from '@anthropic-ai/sandbox-runtime';\nimport { execFile, spawn, type ChildProcess } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport { realpathSync } from 'node:fs';\nimport { mkdir, rm } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, isAbsolute, join } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execFileAsync = promisify(execFile);\n\n/** SRT ships Linux helpers (e.g. apply-seccomp) under vendor/; the wrapped command must read them. */\n// Package-root resolve (not app-module loading): Jest's CJS transform breaks import.meta.resolve.\nconst SRT_VENDOR = join(\n dirname(createRequire(import.meta.url).resolve('@anthropic-ai/sandbox-runtime/package.json')),\n 'vendor',\n);\n\n/**\n * Cap for buffered stdout+stderr per exec.\n * Sized for base64 of a max-sized download (10 MiB → ~13.3 MiB) plus headroom.\n */\nexport const MAX_OUTPUT_BYTES = 14 * 1024 * 1024;\n\n/** Platforms LocalSandboxProvider / hostRun can run on. */\nexport type LocalSandboxPlatform = 'darwin' | 'linux';\n\n/** Cached from {@link initSrt}; cleared by {@link resetSrt}. Used by session policy helpers after init. */\nlet activePlatform: LocalSandboxPlatform | undefined;\n/** Realpath of the Code Mode UDS parent; Linux allowRead + macOS allowUnixSockets. */\nlet codeModeSocketParentPath: string | undefined;\n\nfunction codeModeSocketParentAllow(): string[] {\n return codeModeSocketParentPath === undefined ? [] : [codeModeSocketParentPath];\n}\n\nfunction requireActivePlatform(): LocalSandboxPlatform {\n if (activePlatform === undefined) {\n throw new Error('SRT platform is not set; call initSrt({ platform }) first');\n }\n return activePlatform;\n}\n\n/** PATH for sandboxed commands — must stay aligned with allowRead exec roots. */\nconst COMMAND_PATH_BY_PLATFORM = {\n // On macOS, prefer Homebrew ahead of `/usr/bin` shims (those need Xcode select\n // paths that we intentionally do not allow-read).\n darwin: '/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin',\n linux: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin',\n} as const satisfies Record<LocalSandboxPlatform, string>;\n\nexport function commandPath(platform: LocalSandboxPlatform): string {\n return COMMAND_PATH_BY_PLATFORM[platform];\n}\n\n/** Cwd-relative venv created at local sandbox init (host `python -m venv`). */\nexport const SANDBOX_VENV_DIR = '.venv';\n\nfunction sandboxVenvPath(sandboxRootPath: string): string {\n return join(sandboxRootPath, SANDBOX_VENV_DIR);\n}\n\n/**\n * HTTPS hosts the SRT proxy may reach. `*.example.com` does not match the apex.\n * Concrete hosts plus wildcards so pip (index + wheel CDN) and git clone work.\n */\nexport const LOCAL_SANDBOX_ALLOWED_DOMAINS = [\n 'pypi.org',\n '*.pypi.org',\n 'pythonhosted.org',\n 'files.pythonhosted.org',\n '*.pythonhosted.org',\n 'github.com',\n 'api.github.com',\n 'codeload.github.com',\n '*.github.com',\n 'githubusercontent.com',\n 'raw.githubusercontent.com',\n 'objects.githubusercontent.com',\n '*.githubusercontent.com',\n] as const;\n\nfunction allowedNetworkDomains(): string[] {\n return [...LOCAL_SANDBOX_ALLOWED_DOMAINS];\n}\n\n/**\n * macOS seatbelt blocks mDNSResponder, so `getaddrinfo(\"localhost\")` fails inside\n * the sandbox. SRT injects `HTTP_PROXY=...@localhost:PORT`; rewrite to 127.0.0.1\n * before outbound tools (pip, curl, …) run.\n */\nexport function darwinSandboxNetworkShellPreamble(): string {\n return [\n 'if [ -n \"${HTTP_PROXY:-}\" ]; then export HTTP_PROXY=\"${HTTP_PROXY//localhost/127.0.0.1}\"; fi',\n 'if [ -n \"${HTTPS_PROXY:-}\" ]; then export HTTPS_PROXY=\"${HTTPS_PROXY//localhost/127.0.0.1}\"; fi',\n 'if [ -n \"${http_proxy:-}\" ]; then export http_proxy=\"${http_proxy//localhost/127.0.0.1}\"; fi',\n 'if [ -n \"${https_proxy:-}\" ]; then export https_proxy=\"${https_proxy//localhost/127.0.0.1}\"; fi',\n 'if [ -n \"${ALL_PROXY:-}\" ]; then export ALL_PROXY=\"${ALL_PROXY//localhost/127.0.0.1}\"; fi',\n 'if [ -n \"${all_proxy:-}\" ]; then export all_proxy=\"${all_proxy//localhost/127.0.0.1}\"; fi',\n 'if [ -n \"${GRPC_PROXY:-}\" ]; then export GRPC_PROXY=\"${GRPC_PROXY//localhost/127.0.0.1}\"; fi',\n 'if [ -n \"${grpc_proxy:-}\" ]; then export grpc_proxy=\"${grpc_proxy//localhost/127.0.0.1}\"; fi',\n ].join('; ');\n}\n\nfunction wrapSandboxCommand(params: { platform: LocalSandboxPlatform; command: string }): string {\n if (params.platform !== 'darwin') {\n return params.command;\n }\n return `${darwinSandboxNetworkShellPreamble()}; ${params.command}`;\n}\n\n/**\n * Host binaries SRT execs outside the wrap (same set as SandboxManager.checkDependencies).\n * Linux: bwrap + socat + rg (deny-path scan). macOS seatbelt takes glob denies, so no rg.\n */\nexport const SRT_HOST_BINARIES_BY_PLATFORM = {\n linux: ['bwrap', 'socat', 'rg'],\n darwin: [],\n} as const satisfies Record<LocalSandboxPlatform, readonly string[]>;\n\nexport function srtHostBinaryNames(platform: LocalSandboxPlatform): readonly string[] {\n return SRT_HOST_BINARIES_BY_PLATFORM[platform];\n}\n\n/** SRT's own host-dep check (bwrap/socat/rg on Linux). Does not require initSrt. */\nexport async function checkSrtHostDependencies(): Promise<{ errors: string[]; warnings: string[] }> {\n const result = await SandboxManager.checkDependenciesAsync();\n return { errors: [...result.errors], warnings: [...result.warnings] };\n}\n\n/**\n * Resolve a command name to an absolute path on the host using the sandbox PATH.\n * Uses `/bin/sh` only as a host bootstrap for `command -v` (not the sandboxed wrap shell).\n */\nexport async function resolveCommandOnHost(params: {\n platform: LocalSandboxPlatform;\n name: string;\n /** Defaults to the sandbox PATH for this platform. Host SRT tools use process PATH. */\n pathEnv?: string | undefined;\n}): Promise<string | undefined> {\n if (!/^[A-Za-z0-9._+-]+$/.test(params.name)) {\n throw new Error(`invalid command name for resolveCommandOnHost: ${params.name}`);\n }\n const pathEnv =\n params.pathEnv !== undefined && params.pathEnv.length > 0 ? params.pathEnv : commandPath(params.platform);\n try {\n const { stdout } = await execFileAsync('/bin/sh', ['-c', `command -v -- ${params.name}`], {\n env: { PATH: pathEnv },\n encoding: 'utf8',\n });\n const resolved = stdout.trim().split(/\\r?\\n/).filter(Boolean).at(-1);\n if (resolved === undefined || resolved.length === 0 || !isAbsolute(resolved)) {\n return undefined;\n }\n return resolved;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Resolve the real interpreter on the host before running it under seatbelt.\n * Apple's `/usr/bin/python3` is an xcode-select stub; python.org / Homebrew\n * leave `sys.executable` as a PATH symlink (`/usr/local/bin/python3`).\n */\nexport async function resolvePythonExecutableOnHost(params: { commandPath: string }): Promise<string | undefined> {\n if (!isAbsolute(params.commandPath)) {\n return undefined;\n }\n try {\n const { stdout } = await execFileAsync(params.commandPath, ['-c', 'import sys; print(sys.executable)'], {\n encoding: 'utf8',\n timeout: 5_000,\n });\n const executable = stdout.trim().split(/\\r?\\n/).filter(Boolean).at(-1);\n if (executable === undefined || executable.length === 0 || !isAbsolute(executable)) {\n return undefined;\n }\n return realpathSync(executable);\n } catch {\n return undefined;\n }\n}\n\nexport interface SessionResult {\n stdoutText: string;\n stderrText: string;\n exitCode: number;\n protocolError: string | undefined;\n timedOut: boolean;\n /** Process-group leader pid of the sandboxed command (Unix). */\n childPid: number | undefined;\n}\n\n/**\n * SRT always unions getDefaultWritePaths() into allowWrite. There is no config\n * flag to disable that. Deny the shared/host defaults (not /dev/*) so they are\n * not usable as cross-sandbox writable storage. denyWrite wins over allowWrite.\n */\nfunction denySharedDefaultWritePaths(): string[] {\n return getDefaultWritePaths().filter(path => !path.startsWith('/dev/'));\n}\n\nconst ALLOW_READ_BY_PLATFORM = {\n darwin: [\n '/opt/homebrew/bin',\n '/usr/local',\n '/usr/bin',\n '/bin',\n '/usr/sbin',\n '/sbin',\n '/usr/lib',\n '/System/Library',\n '/Library',\n '/private/var/db/dyld',\n '/private/var/select',\n '/opt/homebrew',\n '/dev',\n // Darwin `/etc` is a symlink to `/private/etc`. SRT refuses that realpath as\n // \"outside boundary\" and keeps `(subpath \"/etc\")`. Seatbelt still checks the\n // resolved path, so Apple LibreSSL's fopen(`/private/etc/ssl/openssl.cnf`)\n // needs `/private/etc` listed too. Do not use a `[/]etc/**` glob: SRT treats\n // that as cwd-relative (`path.isAbsolute('[/]…')` is false).\n '/etc',\n '/private/etc',\n ],\n linux: [\n '/usr/bin',\n '/bin',\n '/usr/sbin',\n '/sbin',\n '/lib',\n '/lib64',\n '/usr/lib',\n '/usr/lib64',\n '/usr/local',\n '/etc',\n '/dev',\n '/proc',\n '/sys',\n SRT_VENDOR,\n ],\n} as const satisfies Record<LocalSandboxPlatform, readonly string[]>;\n\nexport function platformAllowRead(platform: LocalSandboxPlatform): string[] {\n return [...ALLOW_READ_BY_PLATFORM[platform]];\n}\n\n/**\n * Policy for the untrusted command only (deny-by-default reads).\n * The host (in-process supervisor) is never placed under this policy.\n */\nfunction filesystemPolicy(params: { sandboxRootPath: string; platform: LocalSandboxPlatform }): {\n allowWrite: string[];\n denyWrite: string[];\n denyRead: string[];\n allowRead: string[];\n} {\n return {\n allowWrite: [params.sandboxRootPath],\n denyWrite: denySharedDefaultWritePaths(),\n denyRead: ['/'],\n allowRead: [params.sandboxRootPath, ...codeModeSocketParentAllow(), ...platformAllowRead(params.platform)],\n };\n}\n\n/** Curated env for the sandboxed command — never the full host process.env. */\nfunction commandEnv(params: {\n sandboxRootPath: string;\n platform: LocalSandboxPlatform;\n extra?: Record<string, string>;\n}): Record<string, string> {\n const tmp = join(params.sandboxRootPath, '.tmp');\n const home = join(params.sandboxRootPath, '.home');\n const venvDir = sandboxVenvPath(params.sandboxRootPath);\n const locked = {\n HOME: home,\n TMPDIR: tmp,\n TMP: tmp,\n TEMP: tmp,\n VIRTUAL_ENV: venvDir,\n // Cwd-relative layout dirs (not host-absolute). Absolute paths under\n // `Application Support` break PATH lookup (`mcp-client: command not found`).\n PATH: `${join(SANDBOX_VENV_DIR, 'bin')}:mcp-client/bin:${commandPath(params.platform)}`,\n };\n return {\n ...params.extra,\n ...locked,\n };\n}\n\n/** Session filesystem floor (per-exec customConfig still tightens allowWrite/allowRead). */\nfunction sessionFilesystem(platform: LocalSandboxPlatform): {\n allowWrite: string[];\n denyWrite: string[];\n denyRead: string[];\n allowRead: string[];\n} {\n const allowWrite: string[] = [];\n return {\n allowWrite,\n denyWrite: denySharedDefaultWritePaths(),\n denyRead: ['/'],\n allowRead: [...platformAllowRead(platform), ...codeModeSocketParentAllow()],\n };\n}\n\n/**\n * AF_UNIX policy is session-scoped only (wrap customConfig cannot set it).\n * - Linux: allowAllUnixSockets; pathname connect still needs FS allowRead (bwrap)\n * of the Code Mode socket parent (not host /tmp).\n * - macOS: allowAllUnixSockets does NOT consult allowRead for connect — use\n * allowUnixSockets subpath (sandbox roots + Code Mode parent).\n */\nfunction sessionNetwork(params: { platform: LocalSandboxPlatform; unixSockets?: string[] }):\n | {\n allowedDomains: string[];\n deniedDomains: string[];\n allowAllUnixSockets: true;\n }\n | {\n allowedDomains: string[];\n deniedDomains: string[];\n allowAllUnixSockets: false;\n allowUnixSockets: string[];\n } {\n const allowedDomains = allowedNetworkDomains();\n const deniedDomains: string[] = [];\n if (params.platform === 'linux') {\n return {\n allowedDomains,\n deniedDomains,\n allowAllUnixSockets: true,\n };\n }\n return {\n allowedDomains,\n deniedDomains,\n allowAllUnixSockets: false,\n allowUnixSockets: params.unixSockets ?? [],\n };\n}\n\n/** Active sandbox roots allowed for macOS pathname UDS (seatbelt subpath). */\nconst darwinUnixSocketSandboxRoots = new Set<string>();\n\nfunction darwinUnixSocketPaths(): string[] {\n return [...darwinUnixSocketSandboxRoots, ...codeModeSocketParentAllow()];\n}\n\nfunction syncDarwinUnixSockets(): void {\n // No-op until initSrt: create/remove sandbox may run from tests before initialize.\n if (SandboxManager.getConfig() === undefined) {\n return;\n }\n const platform = requireActivePlatform();\n if (platform !== 'darwin') {\n return;\n }\n SandboxManager.updateConfig(buildSessionConfig(platform));\n}\n\n/** Single source for process-scoped SRT session config (init + sandbox create/remove). */\nfunction buildSessionConfig(platform: LocalSandboxPlatform): {\n network: ReturnType<typeof sessionNetwork>;\n filesystem: ReturnType<typeof sessionFilesystem>;\n} {\n return {\n network: sessionNetwork({ platform, unixSockets: darwinUnixSocketPaths() }),\n filesystem: sessionFilesystem(platform),\n };\n}\n\n/** Create a sandbox directory at `sandboxRootPath` (also the sandbox id). */\nexport async function createSandbox(sandboxRootPath: string): Promise<string> {\n await mkdir(sandboxRootPath, { recursive: true, mode: 0o700 });\n await mkdir(join(sandboxRootPath, '.tmp'), { recursive: true, mode: 0o700 });\n await mkdir(join(sandboxRootPath, '.home'), { recursive: true, mode: 0o700 });\n // Seatbelt allowWrite matches real paths (/private/var/... on macOS).\n const realRoot = realpathSync(sandboxRootPath);\n darwinUnixSocketSandboxRoots.add(realRoot);\n syncDarwinUnixSockets();\n return realRoot;\n}\n\nexport async function removeSandbox(sandboxRootPath: string): Promise<void> {\n darwinUnixSocketSandboxRoots.delete(sandboxRootPath);\n syncDarwinUnixSockets();\n await rm(sandboxRootPath, { recursive: true, force: true });\n}\n\n/**\n * Process-scoped SRT init. Per-exec filesystem policy is applied in\n * {@link runSupervisorSession} via wrapWithSandboxArgv customConfig.\n */\nexport async function initSrt(params: {\n platform: LocalSandboxPlatform;\n /** Dedicated Code Mode UDS parent (realpath); grant this path, not host /tmp. */\n codeModeSocketParentPath?: string | undefined;\n}): Promise<void> {\n activePlatform = params.platform;\n codeModeSocketParentPath =\n params.codeModeSocketParentPath === undefined ? undefined : realpathSync(params.codeModeSocketParentPath);\n await SandboxManager.initialize(buildSessionConfig(params.platform));\n}\n\nexport async function resetSrt(): Promise<void> {\n codeModeSocketParentPath = undefined;\n activePlatform = undefined;\n await SandboxManager.reset();\n}\n\n/** Whether process-scoped SRT session config is already initialized. */\nexport function isSrtInitialized(): boolean {\n return activePlatform !== undefined && SandboxManager.getConfig() !== undefined;\n}\n\n/**\n * Tear down the sandboxed exec and every process in its group.\n * Child is spawned as a process-group leader (`detached: true` on Unix).\n */\nexport function killExecTree(child: ChildProcess | undefined): void {\n if (!child) {\n return;\n }\n const pid = child.pid;\n if (pid !== undefined && process.platform !== 'win32') {\n try {\n process.kill(-pid, 'SIGKILL');\n return;\n } catch {\n // ESRCH if the group is already gone — fall through.\n }\n }\n if (!child.killed) {\n child.kill('SIGKILL');\n }\n}\n\n/**\n * Run one SRT-wrapped command. Code Mode UDS (if any) is supplied via `env.TFY_MCP_SOCK`\n * from {@link CodeModeUdsTransport.start}.\n */\nexport async function runSupervisorSession(params: {\n sandboxRootPath: string;\n command: string;\n /** Absolute shell path used to wrap the command string (from isSupported). */\n shell: string;\n /** Platform policy for allowRead / PATH (from isSupported). */\n platform: LocalSandboxPlatform;\n cwd?: string;\n env?: Record<string, string>;\n /** Optional stdin bytes for the sandboxed command (e.g. upload payload). */\n stdin?: Buffer;\n /** Host-visible pid of the sandboxed process-group leader (after spawn). */\n onChildSpawn?: (pid: number) => void;\n /** Hard wall-clock limit for the sandboxed command; caller must choose deliberately. */\n timeoutMs: number;\n}): Promise<SessionResult> {\n const {\n sandboxRootPath,\n command: rawCommand,\n shell,\n platform,\n cwd = sandboxRootPath,\n env,\n stdin,\n onChildSpawn,\n timeoutMs,\n } = params;\n const command = wrapSandboxCommand({ platform, command: rawCommand });\n\n const wrap = await SandboxManager.wrapWithSandboxArgv(\n command,\n shell,\n {\n filesystem: filesystemPolicy({ sandboxRootPath, platform }),\n network: {\n allowedDomains: allowedNetworkDomains(),\n deniedDomains: [],\n },\n },\n undefined,\n sandboxRootPath,\n { commandId: randomUUID(), commandText: command },\n );\n\n const [argv0, ...argvRest] = wrap.argv;\n if (argv0 === undefined) {\n throw new Error('wrapWithSandboxArgv returned empty argv');\n }\n\n // Curated env only — do not spread wrap.env (it can carry ambient host secrets).\n // Code Mode sock path (TFY_MCP_SOCK) is expected in `env` when the caller starts a transport.\n const childEnv: NodeJS.ProcessEnv = {\n ...commandEnv({ sandboxRootPath, platform, ...(env === undefined ? {} : { extra: env }) }),\n };\n\n const child = spawn(argv0, argvRest, {\n cwd,\n env: childEnv,\n shell: false,\n // Detached process groups break stdin forwarding for upload (`cat` via pipe) under Jest.\n detached: stdin === undefined && process.platform !== 'win32',\n stdio: [stdin === undefined ? 'ignore' : 'pipe', 'pipe', 'pipe'],\n });\n if (child.pid !== undefined) {\n onChildSpawn?.(child.pid);\n }\n if (stdin !== undefined) {\n const stdinStream = child.stdin;\n if (stdinStream === null) {\n killExecTree(child);\n SandboxManager.cleanupAfterCommand();\n throw new Error('stdin unavailable for sandboxed command');\n }\n stdinStream.on('error', () => undefined);\n await new Promise<void>((resolve, reject) => {\n stdinStream.end(stdin, (error?: Error | null) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n let stdoutText = '';\n let stderrText = '';\n let bufferedOutput = 0;\n let protocolError: string | undefined;\n let timedOut = false;\n let closed = false;\n\n const ignoreStreamError = (\n stream:\n | {\n on: (event: 'error', cb: (err: Error) => void) => void;\n }\n | null\n | undefined,\n ): void => {\n stream?.on('error', () => undefined);\n };\n\n const appendOutput = (stream: 'stdout' | 'stderr', chunk: Buffer): void => {\n bufferedOutput += chunk.length;\n if (bufferedOutput > MAX_OUTPUT_BYTES) {\n protocolError = `buffered output exceeded ${String(MAX_OUTPUT_BYTES)} bytes`;\n killExecTree(child);\n return;\n }\n const text = chunk.toString('utf8');\n if (stream === 'stdout') {\n stdoutText += text;\n } else {\n stderrText += text;\n }\n };\n\n ignoreStreamError(child.stdout);\n ignoreStreamError(child.stderr);\n child.stdout?.on('data', (chunk: Buffer) => {\n appendOutput('stdout', chunk);\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n appendOutput('stderr', chunk);\n });\n\n return await new Promise<SessionResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n timedOut = true;\n killExecTree(child);\n }, timeoutMs);\n\n child.on('error', error => {\n if (closed) {\n return;\n }\n closed = true;\n clearTimeout(timer);\n SandboxManager.cleanupAfterCommand();\n reject(error);\n });\n\n child.on('close', code => {\n if (closed) {\n return;\n }\n closed = true;\n clearTimeout(timer);\n SandboxManager.cleanupAfterCommand();\n resolve({\n stdoutText,\n stderrText,\n exitCode: typeof code === 'number' ? code : timedOut ? 1 : 0,\n protocolError,\n timedOut,\n childPid: child.pid,\n });\n });\n });\n}\n","/** `stat` / xfer probe output from sandboxed python. */\nimport { z } from 'zod';\n\nexport const XferFileInfoSchema = z.object({\n size: z.number(),\n isDir: z.boolean(),\n});\nexport type XferFileInfo = z.infer<typeof XferFileInfoSchema>;\n","/**\n * Local SRT SandboxProvider. Code Mode UDS is handle-scoped via {@link CodeModeUdsTransport}.\n */\nimport type {\n CodeModeTransport,\n ExecResult,\n SandboxBuild,\n SandboxExecParams,\n SandboxProvider,\n} from '@truefoundry/trueforge-core/core';\nimport {\n absolutizeRelativeExecEnv,\n SandboxFileNotFoundError,\n SandboxFileTooLargeError,\n SandboxNotAvailableError,\n SandboxPathIsDirectoryError,\n shellEscape,\n validateNoPathTraversal,\n} from '@truefoundry/trueforge-core/core';\nimport { execFile } from 'node:child_process';\nimport { existsSync, realpathSync, statSync } from 'node:fs';\nimport { mkdir, mkdtemp, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport { promisify } from 'node:util';\nimport { ulid } from 'ulid';\nimport type { Logger } from 'winston';\nimport {\n assertCodeModeSocketParentPath,\n CodeModeUdsTransport,\n probeCodeModeUnixSocket,\n} from '../core/CodeModeUdsTransport.js';\nimport {\n checkSrtHostDependencies,\n createSandbox,\n initSrt,\n isSrtInitialized,\n removeSandbox,\n resetSrt,\n resolveCommandOnHost,\n resolvePythonExecutableOnHost,\n runSupervisorSession,\n SANDBOX_VENV_DIR,\n srtHostBinaryNames,\n type LocalSandboxPlatform,\n type SessionResult,\n} from '../core/hostRun.js';\nimport { XferFileInfoSchema, type XferFileInfo } from '../schemas/xferFileInfo.js';\n\nconst execFileAsync = promisify(execFile);\n\nconst DEFAULT_EXEC_TIMEOUT_SECONDS = 60;\nconst DEFAULT_FILE_MAX_BYTES = 10 * 1024 * 1024;\n/** Cap for isSupported shell/Python probes (not general exec). */\nconst SUPPORT_PROBE_TIMEOUT_MS = 5_000;\nconst VENV_CREATE_TIMEOUT_MS = 60_000;\nconst VENV_PIP_TIMEOUT_MS = 120_000;\n/** Same pin as the Daytona image / git_downloader.py PEP 723 header. */\nconst VENV_PYDANTIC_PIN = 'pydantic>=2.0.0,<3.0.0';\n\n/** Command names resolved via `command -v` (PATH from sandbox policy). */\nconst SHELL_CANDIDATES = ['bash', 'sh'] as const;\nconst PYTHON_CANDIDATES = ['python3', 'python'] as const;\n\nexport type { LocalSandboxPlatform };\n\n/** One host/socket/shell/python candidate tried by {@link LocalSandboxProvider.isSupported}. */\nexport interface LocalSandboxSupportProbeAttempt {\n kind: 'host' | 'socket' | 'shell' | 'python';\n name: string;\n resolved: string | undefined;\n executable?: string | undefined;\n exitCode?: number | undefined;\n stdout?: string | undefined;\n stderr?: string | undefined;\n protocolError?: string | undefined;\n timedOut?: boolean | undefined;\n}\n\nexport type LocalSandboxSupportResult =\n | { supported: true; platform: LocalSandboxPlatform; shell: string; python: string }\n | {\n supported: false;\n reason: string;\n platform?: LocalSandboxPlatform | undefined;\n attempts?: readonly LocalSandboxSupportProbeAttempt[] | undefined;\n };\n\nexport function formatLocalSandboxSupportReason(params: {\n summary: string;\n attempts: readonly LocalSandboxSupportProbeAttempt[];\n}): string {\n const details = params.attempts.map(formatLocalSandboxSupportAttempt).join('; ');\n return details.length === 0 ? params.summary : `${params.summary}: ${details}`;\n}\n\nfunction formatLocalSandboxSupportAttempt(attempt: LocalSandboxSupportProbeAttempt): string {\n if (attempt.resolved === undefined) {\n return attempt.kind === 'host' ? `${attempt.name}: not on PATH` : `${attempt.name}: not on sandbox PATH`;\n }\n const parts = [`${attempt.name}: resolved=${attempt.resolved}`];\n if (attempt.executable !== undefined && attempt.executable !== attempt.resolved) {\n parts.push(`executable=${attempt.executable}`);\n }\n if (attempt.protocolError !== undefined) {\n parts.push(`protocolError=${attempt.protocolError}`);\n }\n if (attempt.exitCode !== undefined) {\n parts.push(`exit=${String(attempt.exitCode)}`);\n }\n if (attempt.timedOut === true) {\n parts.push('timedOut');\n }\n if (attempt.stderr !== undefined && attempt.stderr.length > 0) {\n parts.push(`stderr=${JSON.stringify(attempt.stderr)}`);\n }\n if (attempt.stdout !== undefined && attempt.stdout.length > 0) {\n parts.push(`stdout=${JSON.stringify(attempt.stdout)}`);\n }\n return parts.join(' ');\n}\n\nfunction probeAttemptFromSession(params: {\n kind: 'shell' | 'python';\n name: string;\n resolved: string;\n executable?: string | undefined;\n session: SessionResult;\n}): LocalSandboxSupportProbeAttempt {\n return {\n kind: params.kind,\n name: params.name,\n resolved: params.resolved,\n ...(params.executable === undefined ? {} : { executable: params.executable }),\n exitCode: params.session.exitCode,\n stdout: params.session.stdoutText,\n stderr: params.session.stderrText,\n ...(params.session.protocolError === undefined ? {} : { protocolError: params.session.protocolError }),\n timedOut: params.session.timedOut,\n };\n}\n\nfunction unsupported(params: {\n reason: string;\n platform?: LocalSandboxPlatform | undefined;\n attempts?: readonly LocalSandboxSupportProbeAttempt[] | undefined;\n}): Extract<LocalSandboxSupportResult, { supported: false }> {\n return {\n supported: false,\n reason: params.reason,\n ...(params.platform === undefined ? {} : { platform: params.platform }),\n ...(params.attempts === undefined ? {} : { attempts: params.attempts }),\n };\n}\n\ntype LocalSandboxSupported = Extract<LocalSandboxSupportResult, { supported: true }>;\n\nexport interface LocalSandboxProviderOptions {\n /** Absolute parent directory under which each createSandbox makes a ULID child root. */\n sandboxRootPathParent: string;\n /**\n * Absolute existing directory for Code Mode UDS (≤65 bytes after realpath, mode 0700).\n * Caller owns its lifetime. Transport chmod's the parent to 0700 and each sock to 0600 after listen.\n */\n codeModeSocketParentPath: string;\n /** Result of {@link LocalSandboxProvider.isSupported}; must be `{ supported: true }`. */\n support: LocalSandboxSupportResult;\n fileMaxBytesForDownload?: number | undefined;\n defaultExecTimeoutSeconds?: number | undefined;\n logger: Logger;\n}\n\n/** Sandbox-relative path for sandboxed commands (avoids /var vs /private/var seatbelt mismatches). */\nfunction toSandboxRelativePath(params: { sandboxRootPath: string; absolutePath: string }): string {\n const rel = relative(params.sandboxRootPath, params.absolutePath);\n return rel === '' ? '.' : rel;\n}\n\n/** True when `descendant` is a real path strictly inside `ancestor` (not equal, not a sibling prefix). */\nfunction isStrictDescendant(params: { ancestor: string; descendant: string }): boolean {\n const rel = relative(params.ancestor, params.descendant);\n return rel !== '' && rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);\n}\n\nfunction execFileErrorDetail(error: unknown): string {\n if (!(error instanceof Error)) {\n return String(error);\n }\n const parts = [error.message];\n if ('stderr' in error && typeof error.stderr === 'string' && error.stderr.length > 0) {\n parts.push(error.stderr);\n }\n if ('stdout' in error && typeof error.stdout === 'string' && error.stdout.length > 0) {\n parts.push(error.stdout);\n }\n return parts.join(' ');\n}\n\nfunction sessionFailDetail(session: SessionResult): string {\n return [session.protocolError, session.stderrText, session.stdoutText]\n .filter(part => part !== undefined && part.length > 0)\n .join(' ');\n}\n\n/**\n * In-sandbox upload: create parent, re-open a 0555 file from a prior init, write with\n * `/bin/cat` (jail PATH prefers Homebrew; a stale Cellar `cat` is ENOENT).\n */\nexport function localSandboxUploadCommand(remotePath: string): string {\n const parent = dirname(remotePath);\n return [\n `mkdir -p ${shellEscape(parent)}`,\n `{ chmod u+w ${shellEscape(remotePath)} 2>/dev/null || true; }`,\n `/bin/cat > ${shellEscape(remotePath)}`,\n ].join(' && ');\n}\n\nexport class LocalSandboxProvider implements SandboxProvider {\n readonly type = 'local';\n private readonly sandboxRootPathParent: string;\n private readonly codeModeSocketParentPath: string;\n private readonly support: LocalSandboxSupported;\n private readonly fileMaxBytesForDownload: number;\n private readonly defaultExecTimeoutSeconds: number;\n private srtInitialized = false;\n private readonly logger: Logger;\n\n /** Local SRT has no image build step — always ready. */\n private static readonly readyBuild: SandboxBuild = {\n status: 'ready',\n reason: null,\n metadata: null,\n };\n\n /**\n * Probe whether this host can run LocalSandboxProvider\n * (OS + Code Mode UDS listen + SRT host binaries + in-sandbox shell + Python 3).\n * On success, returns platform/shell/python to pass into the constructor as `support`.\n */\n static async isSupported(params?: { codeModeSocketParentPath?: string }): Promise<LocalSandboxSupportResult> {\n if (process.platform !== 'darwin' && process.platform !== 'linux') {\n return unsupported({\n reason: `LocalSandboxProvider supports macOS and Linux only (got ${process.platform})`,\n });\n }\n const platform: LocalSandboxPlatform = process.platform;\n\n let createdSocketParent: string | undefined;\n const socketParentPath = params?.codeModeSocketParentPath;\n try {\n const parentPath = socketParentPath ?? (await mkdtemp(join('/tmp', 'tfc-')));\n if (socketParentPath === undefined) {\n createdSocketParent = parentPath;\n }\n try {\n await probeCodeModeUnixSocket(parentPath);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return unsupported({\n platform,\n attempts: [{ kind: 'socket', name: 'uds', resolved: parentPath, protocolError: message }],\n reason: `Code Mode UDS listen failed: ${message}`,\n });\n }\n } finally {\n if (createdSocketParent !== undefined) {\n await rm(createdSocketParent, { recursive: true, force: true });\n }\n }\n\n const hostPath = process.env['PATH'];\n const hostAttempts: LocalSandboxSupportProbeAttempt[] = [];\n for (const name of srtHostBinaryNames(platform)) {\n const resolved = await resolveCommandOnHost({\n platform,\n name,\n ...(hostPath === undefined || hostPath.length === 0 ? {} : { pathEnv: hostPath }),\n });\n hostAttempts.push({ kind: 'host', name, resolved });\n }\n if (hostAttempts.some(attempt => attempt.resolved === undefined)) {\n const required = srtHostBinaryNames(platform).join(', ');\n return unsupported({\n platform,\n attempts: hostAttempts,\n reason: formatLocalSandboxSupportReason({\n summary: `SRT host dependencies missing (${platform}: ${required})`,\n attempts: hostAttempts,\n }),\n });\n }\n\n const srtDeps = await checkSrtHostDependencies();\n if (srtDeps.errors.length > 0) {\n return unsupported({\n platform,\n attempts: hostAttempts.length === 0 ? undefined : hostAttempts,\n reason: `SRT host dependencies failed: ${srtDeps.errors.join('; ')}`,\n });\n }\n\n const alreadyInitialized = isSrtInitialized();\n let probeRoot: string | undefined;\n const attempts: LocalSandboxSupportProbeAttempt[] = [...hostAttempts];\n const pythonAttempts: LocalSandboxSupportProbeAttempt[] = [];\n\n try {\n if (!alreadyInitialized) {\n await initSrt({\n platform,\n ...(socketParentPath === undefined ? {} : { codeModeSocketParentPath: socketParentPath }),\n });\n }\n\n probeRoot = await createSandbox(await mkdtemp(join(tmpdir(), 'tfy-local-sandbox-support-')));\n\n let shell: string | undefined;\n for (const name of SHELL_CANDIDATES) {\n const resolved = await resolveCommandOnHost({ platform, name });\n if (resolved === undefined) {\n attempts.push({ kind: 'shell', name, resolved: undefined });\n continue;\n }\n const probe = await runSupervisorSession({\n sandboxRootPath: probeRoot,\n platform,\n shell: resolved,\n command: 'echo shell-ok',\n timeoutMs: SUPPORT_PROBE_TIMEOUT_MS,\n });\n const attempt = probeAttemptFromSession({ kind: 'shell', name, resolved, session: probe });\n if (probe.protocolError === undefined && probe.exitCode === 0 && probe.stdoutText.includes('shell-ok')) {\n shell = resolved;\n break;\n }\n attempts.push(attempt);\n }\n if (shell === undefined) {\n return unsupported({\n platform,\n attempts,\n reason: formatLocalSandboxSupportReason({\n summary: 'No usable shell in sandbox (bash or sh via command -v)',\n attempts,\n }),\n });\n }\n\n let python: string | undefined;\n for (const name of PYTHON_CANDIDATES) {\n const resolved = await resolveCommandOnHost({ platform, name });\n if (resolved === undefined) {\n pythonAttempts.push({ kind: 'python', name, resolved: undefined });\n continue;\n }\n // Prefer the host-resolved interpreter so macOS stubs/symlinks are not\n // executed under seatbelt (xcode-select, python.org /usr/local/bin).\n const executable = (await resolvePythonExecutableOnHost({ commandPath: resolved })) ?? resolved;\n const probe = await runSupervisorSession({\n sandboxRootPath: probeRoot,\n platform,\n shell,\n command: `${shellEscape(executable)} -c ${shellEscape(\n 'import sys; raise SystemExit(0 if sys.version_info[0] == 3 else 1)',\n )}`,\n timeoutMs: SUPPORT_PROBE_TIMEOUT_MS,\n });\n const attempt = probeAttemptFromSession({\n kind: 'python',\n name,\n resolved,\n executable,\n session: probe,\n });\n if (probe.protocolError === undefined && probe.exitCode === 0) {\n python = executable;\n break;\n }\n pythonAttempts.push(attempt);\n }\n if (python === undefined) {\n return unsupported({\n platform,\n attempts: pythonAttempts,\n reason: formatLocalSandboxSupportReason({\n summary: 'No usable Python 3 interpreter in sandbox (python3 or python via command -v)',\n attempts: pythonAttempts,\n }),\n });\n }\n\n return { supported: true, platform, shell, python };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n const seen = [...attempts, ...pythonAttempts];\n return unsupported({\n platform,\n attempts: seen.length === 0 ? undefined : seen,\n reason:\n seen.length === 0\n ? message\n : `${message}: ${formatLocalSandboxSupportReason({ summary: 'probe aborted', attempts: seen })}`,\n });\n } finally {\n if (probeRoot !== undefined) {\n await removeSandbox(probeRoot);\n }\n if (!alreadyInitialized) {\n await resetSrt();\n }\n }\n }\n\n constructor(options: LocalSandboxProviderOptions) {\n if (!options.support.supported) {\n throw new Error(`LocalSandboxProvider is not supported: ${options.support.reason}`);\n }\n if (!isAbsolute(options.sandboxRootPathParent)) {\n throw new Error('sandboxRootPathParent must be an absolute path');\n }\n validateNoPathTraversal(options.sandboxRootPathParent);\n const resolvedParent = resolve(options.sandboxRootPathParent);\n this.sandboxRootPathParent =\n existsSync(resolvedParent) && statSync(resolvedParent).isDirectory()\n ? realpathSync(resolvedParent)\n : resolvedParent;\n // Same validation as CodeModeUdsTransport (absolute, exists, ≤65 bytes, realpath).\n this.codeModeSocketParentPath = assertCodeModeSocketParentPath(options.codeModeSocketParentPath);\n this.support = options.support;\n this.fileMaxBytesForDownload = options.fileMaxBytesForDownload ?? DEFAULT_FILE_MAX_BYTES;\n this.defaultExecTimeoutSeconds = options.defaultExecTimeoutSeconds ?? DEFAULT_EXEC_TIMEOUT_SECONDS;\n this.logger = options.logger.child({ module: 'LocalSandboxProvider' });\n }\n\n private pythonC(code: string, relPath: string): string {\n return `${this.support.python} -c ${shellEscape(code)} ${shellEscape(relPath)}`;\n }\n\n private statCommand(relPath: string): string {\n const code = [\n 'import json, os, sys',\n 'p = sys.argv[1]',\n 'st = os.stat(p)',\n 'print(json.dumps({\"size\": st.st_size, \"isDir\": os.path.isdir(p)}))',\n ].join('\\n');\n return this.pythonC(code, relPath);\n }\n\n private base64EncodeCommand(relPath: string): string {\n const code = [\n 'import base64, sys',\n 'p = sys.argv[1]',\n 'sys.stdout.write(base64.b64encode(open(p, \"rb\").read()).decode(\"ascii\"))',\n ].join('\\n');\n return this.pythonC(code, relPath);\n }\n\n buildImage(): Promise<SandboxBuild> {\n return Promise.resolve(LocalSandboxProvider.readyBuild);\n }\n\n getImageBuildStatus(): Promise<SandboxBuild> {\n return Promise.resolve(LocalSandboxProvider.readyBuild);\n }\n\n private async ensureSrt(): Promise<void> {\n if (this.srtInitialized) {\n return;\n }\n await initSrt({\n platform: this.support.platform,\n codeModeSocketParentPath: this.codeModeSocketParentPath,\n });\n this.srtInitialized = true;\n }\n\n /** Missing, non-directory, or not a child of this provider's parent → recreate path in Sandbox. */\n private ensureSandboxRoot(sandboxRootPath: string): void {\n if (!isAbsolute(sandboxRootPath)) {\n throw new SandboxNotAvailableError(sandboxRootPath);\n }\n const resolved = resolve(sandboxRootPath);\n if (!existsSync(resolved) || !statSync(resolved).isDirectory()) {\n throw new SandboxNotAvailableError(sandboxRootPath);\n }\n const parentReal = existsSync(this.sandboxRootPathParent)\n ? realpathSync(this.sandboxRootPathParent)\n : this.sandboxRootPathParent;\n const realRoot = realpathSync(resolved);\n if (!isStrictDescendant({ ancestor: parentReal, descendant: realRoot })) {\n throw new SandboxNotAvailableError(sandboxRootPath);\n }\n }\n\n /**\n * Host `python -m venv` (stdlib only), then sandboxed pip for pydantic.\n * Idempotent: skip create when `.venv/bin/python` exists; skip pip when import works.\n */\n private async ensureVenv(sandboxRootPath: string): Promise<void> {\n const venvDir = join(sandboxRootPath, SANDBOX_VENV_DIR);\n const venvPython = join(venvDir, 'bin', 'python');\n if (!existsSync(venvPython)) {\n try {\n await execFileAsync(this.support.python, ['-m', 'venv', venvDir], { timeout: VENV_CREATE_TIMEOUT_MS });\n } catch (error) {\n throw new Error(`Failed to create sandbox ${SANDBOX_VENV_DIR}: ${execFileErrorDetail(error)}`, {\n cause: error,\n });\n }\n }\n\n const relPython = join(SANDBOX_VENV_DIR, 'bin', 'python');\n const relPip = join(SANDBOX_VENV_DIR, 'bin', 'pip');\n const check = await runSupervisorSession({\n sandboxRootPath,\n platform: this.support.platform,\n shell: this.support.shell,\n command: `${shellEscape(relPython)} -c ${shellEscape('import pydantic')}`,\n timeoutMs: SUPPORT_PROBE_TIMEOUT_MS,\n });\n if (check.protocolError !== undefined) {\n throw new Error(`Sandbox venv pydantic check failed: ${check.protocolError}`);\n }\n if (check.exitCode === 0) {\n return;\n }\n\n const install = await runSupervisorSession({\n sandboxRootPath,\n platform: this.support.platform,\n shell: this.support.shell,\n command: `${shellEscape(relPip)} install --trusted-host pypi.org --trusted-host files.pythonhosted.org ${shellEscape(VENV_PYDANTIC_PIN)}`,\n timeoutMs: VENV_PIP_TIMEOUT_MS,\n });\n if (install.protocolError !== undefined || install.exitCode !== 0 || install.timedOut) {\n throw new Error(\n `Failed to pip install ${VENV_PYDANTIC_PIN} into sandbox ${SANDBOX_VENV_DIR}: ${sessionFailDetail(install)}`,\n );\n }\n }\n\n private resolveInSandboxRoot(sandboxRootPath: string, userPath: string): string {\n validateNoPathTraversal(userPath);\n const resolved = userPath.startsWith('/') ? resolve(userPath) : resolve(sandboxRootPath, userPath);\n const root = resolve(sandboxRootPath);\n if (resolved !== root && !resolved.startsWith(root + sep)) {\n throw new SandboxFileNotFoundError(userPath);\n }\n return resolved;\n }\n\n private async runSandboxCommand(params: {\n sandboxRootPath: string;\n command: string;\n stdin?: Buffer;\n }): Promise<{ exitCode: number; stdoutText: string; stderrText: string }> {\n const session = await runSupervisorSession({\n sandboxRootPath: params.sandboxRootPath,\n platform: this.support.platform,\n shell: this.support.shell,\n command: params.command,\n ...(params.stdin === undefined ? {} : { stdin: params.stdin }),\n timeoutMs: this.defaultExecTimeoutSeconds * 1000,\n });\n if (session.protocolError !== undefined) {\n throw new Error(session.protocolError);\n }\n return {\n exitCode: session.exitCode,\n stdoutText: session.stdoutText,\n stderrText: session.stderrText,\n };\n }\n\n private async getFileInfo(params: {\n sandboxRootPath: string;\n relPath: string;\n userPath: string;\n }): Promise<XferFileInfo> {\n const result = await this.runSandboxCommand({\n sandboxRootPath: params.sandboxRootPath,\n command: this.statCommand(params.relPath),\n });\n if (result.exitCode !== 0) {\n throw new SandboxFileNotFoundError(params.userPath);\n }\n return XferFileInfoSchema.parse(JSON.parse(result.stdoutText.trim()));\n }\n\n async createSandbox(): Promise<{ sandboxId: string }> {\n await this.ensureSrt();\n const sandboxId = await createSandbox(join(this.sandboxRootPathParent, ulid().toLowerCase()));\n this.logger.info('LocalSandboxProvider created sandbox', {\n sandboxId,\n shell: this.support.shell,\n python: this.support.python,\n });\n await mkdir(join(sandboxId, this.getToolResultDumpDir()), { recursive: true, mode: 0o700 });\n await mkdir(join(sandboxId, this.getFileUploadsDir()), { recursive: true, mode: 0o700 });\n await mkdir(join(sandboxId, this.getSkillsDir()), { recursive: true, mode: 0o700 });\n await this.ensureVenv(sandboxId);\n return { sandboxId };\n }\n\n async exec(params: SandboxExecParams): Promise<ExecResult> {\n this.ensureSandboxRoot(params.sandboxId);\n try {\n await this.ensureSrt();\n await this.ensureVenv(params.sandboxId);\n const sandboxRootPath = params.sandboxId;\n const cwd =\n params.cwd === undefined || params.cwd === ''\n ? sandboxRootPath\n : this.resolveInSandboxRoot(sandboxRootPath, params.cwd);\n const timeoutSeconds = params.timeoutSeconds ?? this.defaultExecTimeoutSeconds;\n const env =\n params.env === undefined ? undefined : absolutizeRelativeExecEnv({ root: sandboxRootPath, env: params.env });\n const session = await runSupervisorSession({\n sandboxRootPath,\n platform: this.support.platform,\n shell: this.support.shell,\n command: params.command,\n cwd,\n ...(env === undefined ? {} : { env }),\n timeoutMs: timeoutSeconds * 1000,\n });\n if (session.protocolError !== undefined) {\n return { success: false, error: session.protocolError };\n }\n const result = session.stdoutText + (session.stderrText ? session.stderrText : '');\n return {\n success: true,\n response: { exitCode: session.exitCode, result },\n };\n } catch (error) {\n if (error instanceof SandboxNotAvailableError) {\n throw error;\n }\n const message = error instanceof Error ? error.message : String(error);\n return { success: false, error: message };\n }\n }\n\n getAdditionalInstructions(): string {\n return [\n 'SANDBOX RULES:',\n `- Platform: ${this.support.platform}.`,\n `- Commands run under the sandbox shell: ${this.support.shell}.`,\n '- A Python virtualenv lives at .venv. `python` and `pip` on PATH are that environment; packages you `pip install` persist in this sandbox.',\n '- uploads, skills, and tool-results live in the sandbox working directory.',\n '- ALL file creation and writes MUST stay within the sandbox working directory.',\n '- The Agent must NOT write outside the working directory (including host home and /tmp).',\n ].join('\\n');\n }\n\n // Cwd-relative: SRT cwd is the sandbox root. Init mkdir/ln and the agent prompt must not use\n // host-absolute paths — those contain spaces under macOS Application Support and lose quoting.\n // uploads, skills, tool-results, git_downloader.py, .git-credentials, .venv\n // mcp-client/mcp_client.py\n getToolResultDumpDir(): string {\n return 'tool-results';\n }\n\n getGitCredentialsPath(): string {\n return '.git-credentials';\n }\n\n getFileUploadsDir(): string {\n return 'uploads';\n }\n\n getSkillsDir(): string {\n return 'skills';\n }\n\n getGitDownloaderPath(): string {\n return 'git_downloader.py';\n }\n\n async downloadFile(params: { sandboxId: string; path: string }): Promise<Buffer> {\n this.ensureSandboxRoot(params.sandboxId);\n await this.ensureSrt();\n await this.ensureVenv(params.sandboxId);\n const sandboxRootPath = params.sandboxId;\n const absolutePath = this.resolveInSandboxRoot(sandboxRootPath, params.path);\n const relPath = toSandboxRelativePath({ sandboxRootPath, absolutePath });\n const info = await this.getFileInfo({ sandboxRootPath, relPath, userPath: params.path });\n if (info.isDir) {\n throw new SandboxPathIsDirectoryError(params.path);\n }\n if (info.size > this.fileMaxBytesForDownload) {\n throw new SandboxFileTooLargeError(params.path, info.size, this.fileMaxBytesForDownload);\n }\n const result = await this.runSandboxCommand({\n sandboxRootPath,\n command: this.base64EncodeCommand(relPath),\n });\n if (result.exitCode !== 0) {\n throw new SandboxFileNotFoundError(params.path);\n }\n const buf = Buffer.from(result.stdoutText.trim(), 'base64');\n if (buf.length > this.fileMaxBytesForDownload) {\n throw new SandboxFileTooLargeError(params.path, buf.length, this.fileMaxBytesForDownload);\n }\n return buf;\n }\n\n /** Payload on stdin so large uploads stay off argv. */\n async uploadFile(params: { sandboxId: string; remotePath: string; content: Buffer }): Promise<void> {\n this.ensureSandboxRoot(params.sandboxId);\n await this.ensureSrt();\n await this.ensureVenv(params.sandboxId);\n if (params.content.length > this.fileMaxBytesForDownload) {\n throw new SandboxFileTooLargeError(params.remotePath, params.content.length, this.fileMaxBytesForDownload);\n }\n const sandboxRootPath = params.sandboxId;\n // Resolve for traversal checks, but pass sandbox-relative paths to the shell.\n // Absolute /var/folders/... paths lose quoting under SRT and become mkdir /var.\n const absolutePath = this.resolveInSandboxRoot(sandboxRootPath, params.remotePath);\n const remotePath = toSandboxRelativePath({ sandboxRootPath, absolutePath });\n const result = await this.runSandboxCommand({\n sandboxRootPath,\n command: localSandboxUploadCommand(remotePath),\n stdin: params.content,\n });\n if (result.exitCode !== 0) {\n const detail = [result.stderrText, result.stdoutText].filter(part => part.length > 0).join(' ');\n throw new Error(\n detail.length > 0\n ? `upload ${params.remotePath} failed (exit ${String(result.exitCode)}): ${detail}`\n : `upload ${params.remotePath} failed (exit ${String(result.exitCode)})`,\n );\n }\n }\n\n createCodeModeTransport(): CodeModeTransport {\n return new CodeModeUdsTransport({\n codeModeSocketParentPath: this.codeModeSocketParentPath,\n clientRemotePath: () => join('mcp-client', 'mcp_client.py'),\n });\n }\n\n /** Reset process-scoped SRT for this provider. */\n async dispose(): Promise<void> {\n if (this.srtInitialized) {\n await resetSrt();\n this.srtInitialized = false;\n }\n }\n}\n","/**\n * DB-backed configured MCP servers: one row per server per tenant,\n * identity as columns plus a Zod-validated `McpServerManifest` jsonb document.\n * Implementations: PostgresMcpServerStore and SqliteMcpServerStore.\n *\n * Also owns the DCR registration columns (`oauth_server` / `oauth_client`) via\n * `IOAuthClientStore` — those are not a separate persistence root.\n *\n * OAuth JSONB wire shapes (snake_case) and camelCase ↔ storage mappers live here\n * alongside the store contract — absence is an explicit `| null`, not an optional `?:`.\n */\nimport type {\n OAuthClientRecord as ContractOAuthClientRecord,\n OAuthPendingAuthorization as ContractOAuthPendingAuthorization,\n OAuthToken as ContractOAuthToken,\n IOAuthClientStore,\n} from '../mcp/auth/types';\nimport type { ResourceName } from '../schemas/common';\nimport type { McpServerManifest } from '../schemas/mcpServer';\n\nexport interface McpServerRecord {\n id: string;\n tenant_id: string;\n name: ResourceName;\n manifest: McpServerManifest;\n /** ISO-8601 UTC instant. */\n created_at: string;\n /** ISO-8601 UTC instant. */\n updated_at: string;\n}\n\nexport interface GetMcpServerInput {\n tenant_id: string;\n name: string;\n}\n\nexport interface ListMcpServersInput {\n tenant_id: string;\n /** `undefined` lists all; empty returns `[]` without querying; otherwise `WHERE name IN (...)`. */\n names: readonly string[] | undefined;\n}\n\nexport interface CreateMcpServerInput {\n tenant_id: string;\n name: ResourceName;\n manifest: McpServerManifest;\n}\n\n/** Same shape as create for now; kept as a distinct name for the upsert path. */\nexport type UpsertMcpServerInput = CreateMcpServerInput;\n\n/** Unique `(tenant_id, name)` violation on create. */\nexport class McpServerNameConflictError extends Error {\n readonly tenant_id: string;\n readonly server_name: string;\n\n constructor({ tenant_id, name }: { tenant_id: string; name: string }, options?: ErrorOptions) {\n super(`MCP server name already exists: ${name}`, options);\n this.name = 'McpServerNameConflictError';\n this.tenant_id = tenant_id;\n this.server_name = name;\n }\n}\n\nexport interface IMcpServerStore<TTransaction = never> extends IOAuthClientStore<TTransaction> {\n listServers(input: ListMcpServersInput, transaction?: TTransaction): Promise<McpServerRecord[]>;\n getServer(input: GetMcpServerInput, transaction?: TTransaction): Promise<McpServerRecord | undefined>;\n /**\n * Load one server while holding a row lock for the lifetime of `transaction`.\n * Postgres: `SELECT … FOR UPDATE`. SQLite: plain read under a write txn (BEGIN IMMEDIATE).\n * Required before read-modify-write of header secrets so concurrent keep/rotate cannot interleave.\n */\n getServerForUpdate(input: GetMcpServerInput, transaction: TTransaction): Promise<McpServerRecord | undefined>;\n /** Inserts a new server with a generated ULID. Throws McpServerNameConflictError on name clash. */\n createServer(input: CreateMcpServerInput, transaction?: TTransaction): Promise<McpServerRecord>;\n /**\n * Creates the server or replaces `manifest` (+ `updated_at`) only.\n * Never overwrites `id`, `oauth_server`, or `oauth_client`.\n */\n upsertServer(input: UpsertMcpServerInput, transaction?: TTransaction): Promise<McpServerRecord>;\n}\n\n/**\n * How long a pending authorization stays redeemable — long enough to finish a consent screen,\n * short enough that an abandoned `state` and its PKCE verifier stop being usable. Applied as a\n * `created_at` filter on read by both backends, so no sweep job is needed.\n */\nexport const PENDING_AUTHORIZATION_TTL_MS = 10 * 60 * 1000;\n\n/** RFC 8414 AS metadata cached at DCR time (`mcp_server.oauth_server`). */\nexport interface OAuthServer {\n authorization_endpoint: string;\n token_endpoint: string;\n code_challenge_methods_supported: string[] | null;\n}\n\n/** RFC 7591 DCR response (`mcp_server.oauth_client`). */\nexport interface OAuthClient {\n client_id: string;\n client_secret: string | null;\n}\n\n/** `oauth_pending_authorization.auth_data` JSONB. */\nexport interface OAuthPendingAuthorizationData {\n /** MCP server URL from authorize time — needed by the shared callback for RFC 8707 `resource`. */\n mcp_server_url: string;\n code_verifier: string | null;\n return_to: string | null;\n}\n\n/** `oauth_token.token` JSONB. */\nexport interface OAuthToken {\n access_token: string;\n refresh_token: string | null;\n /** ISO 8601 */\n expires_at: string;\n scope: string | null;\n}\n\nexport function toStoredOAuthToken(token: ContractOAuthToken): OAuthToken {\n return {\n access_token: token.accessToken,\n refresh_token: token.refreshToken,\n expires_at: token.expiresAt,\n scope: token.scope,\n };\n}\n\nexport function fromStoredOAuthToken(stored: OAuthToken): ContractOAuthToken {\n return {\n accessToken: stored.access_token,\n refreshToken: stored.refresh_token,\n expiresAt: stored.expires_at,\n scope: stored.scope,\n };\n}\n\nexport function toStoredOAuthClientRecord(record: ContractOAuthClientRecord): {\n server: OAuthServer;\n client: OAuthClient;\n} {\n return {\n server: {\n authorization_endpoint: record.server.authorizationEndpoint,\n token_endpoint: record.server.tokenEndpoint,\n code_challenge_methods_supported: record.server.codeChallengeMethodsSupported,\n },\n client: {\n client_id: record.client.clientId,\n client_secret: record.client.clientSecret,\n },\n };\n}\n\nexport function fromStoredOAuthClientRecord(params: {\n server: OAuthServer;\n client: OAuthClient;\n}): ContractOAuthClientRecord {\n return {\n server: {\n authorizationEndpoint: params.server.authorization_endpoint,\n tokenEndpoint: params.server.token_endpoint,\n codeChallengeMethodsSupported: params.server.code_challenge_methods_supported,\n },\n client: {\n clientId: params.client.client_id,\n clientSecret: params.client.client_secret,\n },\n };\n}\n\n/** The blob half of a pending authorization; `state`/`id`/`user_id` live in their own columns. */\nexport function toStoredOAuthPendingAuthorizationData(\n pending: ContractOAuthPendingAuthorization,\n): OAuthPendingAuthorizationData {\n return {\n mcp_server_url: pending.mcpServerUrl,\n code_verifier: pending.codeVerifier,\n return_to: pending.returnTo,\n };\n}\n\nexport function fromStoredOAuthPendingAuthorizationData(\n stored: OAuthPendingAuthorizationData,\n): Pick<ContractOAuthPendingAuthorization, 'mcpServerUrl' | 'codeVerifier' | 'returnTo'> {\n return {\n mcpServerUrl: stored.mcp_server_url,\n codeVerifier: stored.code_verifier,\n returnTo: stored.return_to,\n };\n}\n","/**\n * DB-backed configured model providers: one row per provider per tenant,\n * identity as columns plus the Zod-validated `ModelProviderManifest` document as jsonb.\n * Implementations: PostgresModelProviderStore and SqliteModelProviderStore.\n */\nimport type { ResourceName } from '../schemas/common';\nimport type { AvailableModel, ModelProviderManifest } from '../schemas/modelProvider';\n\nexport interface ModelProviderRecord {\n tenant_id: string;\n name: ResourceName;\n manifest: ModelProviderManifest;\n /** ISO-8601 UTC instant. */\n created_at: string;\n /** ISO-8601 UTC instant. */\n updated_at: string;\n}\n\nexport interface GetModelProviderInput {\n tenant_id: string;\n name: string;\n}\n\nexport interface CreateModelProviderInput {\n tenant_id: string;\n /** Derived from the document by `modelProviderName`, never chosen by the caller. */\n name: ResourceName;\n manifest: ModelProviderManifest;\n}\n\n/** Same shape as create for now; kept as a distinct name for the upsert path. */\nexport type UpsertModelProviderInput = CreateModelProviderInput;\n\n/** Unique `(tenant_id, name)` violation on create. */\nexport class ModelProviderNameConflictError extends Error {\n readonly tenant_id: string;\n readonly provider_name: string;\n\n constructor({ tenant_id, name }: { tenant_id: string; name: string }, options?: ErrorOptions) {\n super(`Model provider name already exists: ${name}`, options);\n this.name = 'ModelProviderNameConflictError';\n this.tenant_id = tenant_id;\n this.provider_name = name;\n }\n}\n\nexport interface IModelProviderStore<TTransaction = never> {\n listProviders(tenantId: string, transaction?: TTransaction): Promise<ModelProviderRecord[]>;\n getProvider(input: GetModelProviderInput, transaction?: TTransaction): Promise<ModelProviderRecord | undefined>;\n /**\n * Load one provider while holding a row lock for the lifetime of `transaction`.\n * Postgres: `SELECT … FOR UPDATE`. SQLite: plain read under a write txn (BEGIN IMMEDIATE).\n * Required before read-modify-write of secrets so concurrent keep/rotate cannot interleave.\n */\n getProviderForUpdate(\n input: GetModelProviderInput,\n transaction: TTransaction,\n ): Promise<ModelProviderRecord | undefined>;\n /** Inserts a new provider. Throws ModelProviderNameConflictError on name clash. */\n createProvider(input: CreateModelProviderInput, transaction?: TTransaction): Promise<ModelProviderRecord>;\n /** Single-row write: creates the provider or replaces the whole manifest (models included). */\n upsertProvider(input: UpsertModelProviderInput, transaction?: TTransaction): Promise<ModelProviderRecord>;\n /** Flattens manifests into the FQN read view for GET /models. */\n listModels(tenantId: string, transaction?: TTransaction): Promise<AvailableModel[]>;\n}\n\n/** Application-side flatten shared by both store implementations. */\nexport function flattenProviderModels(records: ModelProviderRecord[]): AvailableModel[] {\n return records.flatMap(record =>\n record.manifest.models.map(model => ({\n name: `${record.name}/${model.name}`,\n model_id: model.model_id,\n provider: { name: record.name },\n properties: model.properties,\n })),\n );\n}\n","/**\n * DB-backed configured skills: one row per skill per tenant,\n * identity as columns plus a Zod-validated `SkillManifest` jsonb document.\n * Implementations: PostgresSkillStore and SqliteSkillStore.\n */\nimport type { ResourceName } from '../schemas/common';\nimport type { SkillManifest } from '../schemas/skill';\n\nexport interface SkillRecord {\n tenant_id: string;\n name: ResourceName;\n manifest: SkillManifest;\n /** ISO-8601 UTC instant. */\n created_at: string;\n /** ISO-8601 UTC instant. */\n updated_at: string;\n}\n\nexport interface GetSkillInput {\n tenant_id: string;\n name: string;\n}\n\nexport interface ListSkillsInput {\n tenant_id: string;\n /** `undefined` lists all; empty returns `[]` without querying; otherwise `WHERE name IN (...)`. */\n names: readonly string[] | undefined;\n}\n\nexport interface CreateSkillInput {\n tenant_id: string;\n name: ResourceName;\n manifest: SkillManifest;\n}\n\n/** Same shape as create for now; kept as a distinct name for the upsert path. */\nexport type UpsertSkillInput = CreateSkillInput;\n\n/** Unique `(tenant_id, name)` violation on create. */\nexport class SkillNameConflictError extends Error {\n readonly tenant_id: string;\n readonly skill_name: string;\n\n constructor({ tenant_id, name }: { tenant_id: string; name: string }, options?: ErrorOptions) {\n super(`Skill name already exists: ${name}`, options);\n this.name = 'SkillNameConflictError';\n this.tenant_id = tenant_id;\n this.skill_name = name;\n }\n}\n\nexport interface ISkillStore<TTransaction = never> {\n listSkills(input: ListSkillsInput, transaction?: TTransaction): Promise<SkillRecord[]>;\n getSkill(input: GetSkillInput, transaction?: TTransaction): Promise<SkillRecord | undefined>;\n /** Inserts a new skill. Throws SkillNameConflictError on name clash. */\n createSkill(input: CreateSkillInput, transaction?: TTransaction): Promise<SkillRecord>;\n /** Single-row write: creates the skill or replaces the whole manifest. */\n upsertSkill(input: UpsertSkillInput, transaction?: TTransaction): Promise<SkillRecord>;\n}\n","import Database from 'better-sqlite3';\nimport {\n CompiledQuery,\n Kysely,\n ParseJSONResultsPlugin,\n SqliteAdapter,\n SqliteDriver,\n SqliteIntrospector,\n SqliteQueryCompiler,\n type DatabaseConnection,\n type Dialect,\n type Driver,\n type QueryCompiler,\n type TransactionSettings,\n} from 'kysely';\n\nimport type { Database as Schema } from './types';\n\n/**\n * Wraps SqliteDriver and maps Kysely access mode onto SQLite begin kinds:\n * - omit / `read only` → deferred BEGIN (matches Postgres default feel)\n * - `read write` → BEGIN IMMEDIATE (RESERVED write lock)\n *\n * Stock SqliteDriver.d.ts omits `settings` on beginTransaction; compose instead of override.\n */\nclass ImmediateSqliteDriver implements Driver {\n readonly #inner: SqliteDriver;\n\n constructor(database: Database.Database) {\n this.#inner = new SqliteDriver({ database });\n }\n\n init(): Promise<void> {\n return this.#inner.init();\n }\n\n acquireConnection(): Promise<DatabaseConnection> {\n return this.#inner.acquireConnection();\n }\n\n async beginTransaction(connection: DatabaseConnection, settings: TransactionSettings): Promise<void> {\n const begin = settings.accessMode === 'read write' ? 'begin immediate' : 'begin';\n await connection.executeQuery(CompiledQuery.raw(begin));\n }\n\n commitTransaction(connection: DatabaseConnection): Promise<void> {\n return this.#inner.commitTransaction(connection);\n }\n\n rollbackTransaction(connection: DatabaseConnection): Promise<void> {\n return this.#inner.rollbackTransaction(connection);\n }\n\n savepoint(\n connection: DatabaseConnection,\n savepointName: string,\n compileQuery: QueryCompiler['compileQuery'],\n ): Promise<void> {\n return this.#inner.savepoint(connection, savepointName, compileQuery);\n }\n\n rollbackToSavepoint(\n connection: DatabaseConnection,\n savepointName: string,\n compileQuery: QueryCompiler['compileQuery'],\n ): Promise<void> {\n return this.#inner.rollbackToSavepoint(connection, savepointName, compileQuery);\n }\n\n releaseSavepoint(\n connection: DatabaseConnection,\n savepointName: string,\n compileQuery: QueryCompiler['compileQuery'],\n ): Promise<void> {\n return this.#inner.releaseSavepoint(connection, savepointName, compileQuery);\n }\n\n releaseConnection(): Promise<void> {\n return this.#inner.releaseConnection();\n }\n\n destroy(): Promise<void> {\n return this.#inner.destroy();\n }\n}\n\nclass ImmediateSqliteDialect implements Dialect {\n readonly #database: Database.Database;\n\n constructor(database: Database.Database) {\n this.#database = database;\n }\n\n createDriver(): Driver {\n return new ImmediateSqliteDriver(this.#database);\n }\n\n createQueryCompiler() {\n return new SqliteQueryCompiler();\n }\n\n createAdapter() {\n return new SqliteAdapter();\n }\n\n createIntrospector(db: Kysely<unknown>) {\n return new SqliteIntrospector(db);\n }\n}\n\nfunction applyPragmas(database: Database.Database): void {\n database.pragma('journal_mode = WAL');\n database.pragma('busy_timeout = 5000');\n database.pragma('synchronous = NORMAL');\n database.pragma('foreign_keys = ON');\n database.pragma('temp_store = MEMORY');\n database.pragma('cache_size = -10240');\n}\n\n/**\n * Result aliases that are `json(...)` projections of JSONB columns.\n * Plain TEXT (title, ids, timestamps) must not be parsed even when they look like JSON.\n */\nconst JSON_RESULT_COLUMNS = new Set([\n 'agent_spec',\n 'custom',\n 'ancestor_ids',\n 'input',\n 'state',\n 'checkpoint',\n 'agent_info',\n 'current_context_usage',\n 'body',\n 'capability_state',\n 'turn_checkpoint',\n 'turn_state',\n 'thread_checkpoint',\n 'event',\n 'manifest',\n 'build_metadata',\n 'oauth_server',\n 'oauth_client',\n 'token',\n 'auth_data',\n]);\n\n/** Top-level row field only — `$[0].\"body\"`, not `$[0].\"body\".\"content\"`. */\nfunction shouldParseJsonResultColumn(_value: string, jsonPath: string): boolean {\n const match = /^\\$\\[\\d+\\]\\.\"([^\"]+)\"$/.exec(jsonPath);\n const column = match?.[1];\n return column !== undefined && JSON_RESULT_COLUMNS.has(column);\n}\n\nexport function createSqliteDb(filename: string): Kysely<Schema> {\n const database = new Database(filename);\n applyPragmas(database);\n return new Kysely<Schema>({\n dialect: new ImmediateSqliteDialect(database),\n // Parse only projected JSON columns once; never re-parse nested string values.\n plugins: [new ParseJSONResultsPlugin({ shouldParse: shouldParseJsonResultColumn })],\n });\n}\n\n/**\n * Match better-sqlite3 unique constraint errors without brittle instanceof checks.\n */\nexport function isUniqueViolation(err: unknown): boolean {\n if (typeof err !== 'object' || err === null || !('code' in err)) {\n return false;\n }\n const code = err.code;\n return code === 'SQLITE_CONSTRAINT_UNIQUE' || code === 'SQLITE_CONSTRAINT_PRIMARYKEY';\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport type { Kysely } from 'kysely';\nimport { FileMigrationProvider, Migrator } from 'kysely/migration';\n\nimport type { Database } from './sqlite/types';\n\n/**\n * Runs all pending SQLite migrations.\n *\n * Used at sqlite startup and by SQLite store tests.\n * Resolves `…/sqlite/migrations` next to this module (source or `dist/`).\n *\n * Kysely does not wrap SQLite migrations in a transaction (`supportsTransactionalDdl`\n * is false). Migrations that need atomicity open `db.transaction()` themselves;\n * `PRAGMA foreign_keys` must stay outside that txn.\n */\nexport async function migrateSqliteToLatest(db: Kysely<Database>): Promise<void> {\n const migrator = new Migrator({\n db,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(import.meta.dirname, 'sqlite', 'migrations'),\n }),\n });\n\n const { error, results } = await migrator.migrateToLatest();\n\n results?.forEach(it => {\n if (it.status === 'Success') {\n console.log(`migration \"${it.migrationName}\" was executed successfully`);\n } else if (it.status === 'Error') {\n console.error(`failed to execute migration \"${it.migrationName}\"`);\n }\n });\n\n if (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error('failed to migrate', { cause: error });\n }\n}\n","/**\n * Shared Kysely SQL expression helpers for SQLite stores.\n * JSON authority: SQLite JSON1 — bind text via jsonb(?); read via json(column).\n * ParseJSONResultsPlugin parses top-level json() columns only (see createSqliteDb).\n */\nimport { sql, type Expression, type RawBuilder } from 'kysely';\n\n/** Bind a JS value as SQLite JSONB BLOB (stringify in JS, convert in SQL). */\nexport function jsonbBind(value: unknown): RawBuilder<string> {\n return sql`jsonb(${JSON.stringify(value)})`;\n}\n\n/**\n * `jsonb_set(column, path, jsonb(?))`.\n * `path` must be a fixed literal from call sites (e.g. `'$.completion'`).\n */\nexport function jsonbSet(column: Expression<unknown>, path: string, value: unknown): RawBuilder<string> {\n return sql`jsonb_set(${column}, ${path}, ${jsonbBind(value)})`;\n}\n\n/**\n * Project a JSONB column to minified text JSON.\n * With ParseJSONResultsPlugin, the result row field is the parsed JS value typed as `T`.\n */\nexport function jsonText<T>(column: Expression<unknown>): RawBuilder<T> {\n return sql<T>`json(${column})`;\n}\n\n/** Current UTC instant as ISO-8601 text for TEXT timestamp columns. */\nexport function nowIso(): string {\n return new Date().toISOString();\n}\n\nexport function isoMsAgo(ms: number): string {\n return new Date(Date.now() - ms).toISOString();\n}\n","/**\n * Session-store-only helpers for SQLite (append_id ordering quirks).\n * Shared JSON/time helpers live in `../sqlExpressions`.\n */\n\n/**\n * SQLite RETURNING row order is unspecified. Multi-row INSERT assigns increasing\n * append_id in VALUES order — sort on that before mapping to pos / per-thread lists.\n */\nexport function sortedByAppendId<T extends { append_id: number }>(rows: readonly T[]): T[] {\n return [...rows].sort((a, b) => a.append_id - b.append_id);\n}\n","import type { TurnRecord, TurnSnapshot } from '@truefoundry/trueforge-core/agent-session/models/TurnRecord';\nimport {\n type TerminalTurnState,\n type TurnInputItem,\n type TurnState,\n} from '@truefoundry/trueforge-core/agent-session/schemas/turn';\nimport { assertCreateTurnThreadDelta } from '@truefoundry/trueforge-core/agent-session/store/assertCreateTurnThreadDelta';\nimport type {\n FreezeAndGetTurnInput,\n TurnRecordWithoutSnapshot,\n UpdateTurnStateInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n PreviousTurnRunningError,\n SessionNotFoundError,\n SessionStoreConflictError,\n SessionStoreInvariantError,\n SessionStoreNotFoundError,\n TurnAlreadyExistsError,\n TurnNotFoundError,\n TurnNotRunningError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport type { CapabilityState, JsonValue } from '@truefoundry/trueforge-core/core/capabilities/AgentCapability';\nimport type { AgentInfo, AgentParent, MCPServerInitInfo } from '@truefoundry/trueforge-core/core/events/schema';\nimport type { AgentThreadSnapshot, ContextMessage } from '@truefoundry/trueforge-core/core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport { getEmptyCurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport type { SandboxInfo } from '@truefoundry/trueforge-core/core/sandbox/Sandbox';\nimport { sql, type Kysely, type RawBuilder, type Transaction } from 'kysely';\nimport { isUniqueViolation } from '../../client';\nimport { jsonbBind, jsonText, nowIso } from '../../sqlExpressions';\nimport type { Database, TurnCheckpoint, TurnThreadCheckpoint } from '../../types';\nimport { sortedByAppendId } from '../sqlExpressions';\n\ntype TurnCustom = Record<string, never>;\n\nfunction isEmptyCustomRecord(value: Record<string, unknown>): value is TurnCustom {\n return Object.keys(value).length === 0;\n}\n\nfunction parseTurnCustom(value: Record<string, unknown> | null): TurnCustom | null {\n if (value === null) {\n return null;\n }\n if (!isEmptyCustomRecord(value)) {\n throw new SessionStoreInvariantError('non-empty turn custom is not supported');\n }\n return value;\n}\n\n/** New thread metadata; mutable per-turn data arrives through dedicated fields. */\nexport interface NewThreadRegistration {\n thread_id: string;\n parent: AgentParent | null;\n agent_info: AgentInfo | null;\n}\n\nexport interface TurnKeys {\n session_id: string;\n turn_id: string;\n}\n\nexport interface NewContextAppend {\n thread_id: string;\n context: ContextMessage[];\n current_context_usage: CurrentContextUsage | null;\n}\n\nexport interface CreateTurnTurnFields {\n turn_id: string;\n first_turn_id: string;\n previous_turn_id: string | null;\n ancestor_ids: string[];\n input: TurnInputItem[];\n state: TurnState;\n custom: Record<string, unknown> | null;\n}\n\nexport interface CreateTurnInput {\n session_id: string;\n turn: CreateTurnTurnFields;\n new_threads: NewThreadRegistration[];\n new_context_appends: NewContextAppend[];\n capability_states: {\n thread_id: string;\n capability_state: CapabilityState | null;\n }[];\n last_activity_timestamp_ms: number;\n update_session_title_if_not_exist: string | null;\n mcp_servers: Record<string, MCPServerInitInfo> | null;\n sandbox_info: SandboxInfo | null;\n}\n\nexport interface GetTurnInput {\n session_id: string;\n turn_id: string;\n}\n\nexport interface ListTurnsInput {\n session_id: string;\n limit: number;\n offset: number;\n}\n\nexport interface ListTurnsResult {\n turns: TurnRecordWithoutSnapshot<TurnCustom>[];\n next_offset: number | null;\n}\n\ntype DbOrTrx = Kysely<Database> | Transaction<Database>;\n\nfunction terminalTurnState(state: TurnState, turn_id: string): TerminalTurnState {\n switch (state.status) {\n case 'running':\n throw new SessionStoreInvariantError(`expected terminal state for turn ${turn_id}, got running`);\n case 'done':\n case 'cancelled':\n case 'error':\n return state;\n }\n}\n\nasync function loadTurnState(db: DbOrTrx, keys: TurnKeys): Promise<TurnState | undefined> {\n const row = await db\n .selectFrom('turn')\n .select([jsonText<TurnState>(sql.ref('state')).as('state')])\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .executeTakeFirst();\n return row?.state;\n}\n\n/** Classify a 0-row fenced write: missing turn vs frozen/non-running turn. */\nexport async function classifyTurnFenceWriteFailure(db: DbOrTrx, keys: TurnKeys): Promise<never> {\n const state = await loadTurnState(db, keys);\n if (!state) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(state, keys.turn_id));\n}\n\n/**\n * Classify a 0-row fenced turn_thread UPDATE: turn missing/terminal vs thread row missing.\n */\nexport async function classifyTurnThreadWriteFailure(db: DbOrTrx, keys: TurnKeys, thread_id: string): Promise<never> {\n const state = await loadTurnState(db, keys);\n if (!state) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n if (state.status !== 'running') {\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(state, keys.turn_id));\n }\n throw new SessionStoreInvariantError(`thread ${thread_id} not found in turn ${keys.turn_id}`);\n}\n\nexport async function assertTurnRunning(db: DbOrTrx, keys: TurnKeys): Promise<void> {\n const state = await loadTurnState(db, keys);\n if (!state) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n if (state.status !== 'running') {\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(state, keys.turn_id));\n }\n}\n\ninterface CapabilityAggRow {\n thread_id: string;\n capability_state: Record<string, JsonValue> | null;\n}\n\nasync function assembleTurnRecord(\n db: DbOrTrx,\n args: { session_id: string; turn_id: string },\n): Promise<TurnRecord<TurnCustom> | undefined> {\n const turn = await db\n .selectFrom('turn')\n .select([\n 'session_id',\n 'turn_id',\n 'first_turn_id',\n 'previous_turn_id',\n jsonText<string[]>(sql.ref('ancestor_ids')).as('ancestor_ids'),\n jsonText<TurnInputItem[]>(sql.ref('input')).as('input'),\n jsonText<TurnState>(sql.ref('state')).as('state'),\n jsonText<TurnCheckpoint>(sql.ref('checkpoint')).as('checkpoint'),\n jsonText<Record<string, unknown> | null>(sql.ref('custom')).as('custom'),\n 'created_at',\n 'updated_at',\n ])\n .where('session_id', '=', args.session_id)\n .where('turn_id', '=', args.turn_id)\n .executeTakeFirst();\n\n if (!turn) {\n return undefined;\n }\n\n // LEFT JOIN turn_thread + turn_thread_context ORDER BY pos to assemble context per thread.\n // Empty-context threads emit one row with null pos/append_id from the LEFT JOIN.\n const contextRows = await db\n .selectFrom('turn_thread as tt')\n .leftJoin('turn_thread_context as ttc', join =>\n join\n .on('ttc.session_id', '=', args.session_id)\n .on('ttc.turn_id', '=', args.turn_id)\n .onRef('ttc.thread_id', '=', 'tt.thread_id'),\n )\n .leftJoin('thread_context_log as l', join =>\n join\n .on('l.session_id', '=', args.session_id)\n .onRef('l.thread_id', '=', 'tt.thread_id')\n .onRef('l.append_id', '=', 'ttc.append_id'),\n )\n .select([\n 'tt.thread_id',\n jsonText<TurnThreadCheckpoint>(sql.ref('tt.checkpoint')).as('checkpoint'),\n jsonText<AgentInfo | null>(sql.ref('tt.agent_info')).as('agent_info'),\n jsonText<CurrentContextUsage>(sql.ref('tt.current_context_usage')).as('current_context_usage'),\n jsonText<ContextMessage | null>(sql.ref('l.body')).as('body'),\n 'ttc.pos',\n ])\n .where('tt.session_id', '=', args.session_id)\n .where('tt.turn_id', '=', args.turn_id)\n .orderBy('tt.thread_id')\n .orderBy('ttc.pos')\n .execute();\n\n const capabilityRows: CapabilityAggRow[] = await db\n .selectFrom('thread_capability_state')\n .select([\n 'thread_id',\n sql<Record<string, JsonValue> | null>`json(jsonb_group_object(key, json(state)))`.as('capability_state'),\n ])\n .where('session_id', '=', args.session_id)\n .where('turn_id', '=', args.turn_id)\n .groupBy('thread_id')\n .execute();\n\n const capabilityByThread = new Map<string, Record<string, JsonValue>>();\n for (const row of capabilityRows) {\n if (row.capability_state !== null) {\n capabilityByThread.set(row.thread_id, row.capability_state);\n }\n }\n\n const threads: Record<string, AgentThreadSnapshot> = {};\n const orderedBodies = new Map<string, ContextMessage[]>();\n const threadMeta = new Map<\n string,\n {\n checkpoint: TurnThreadCheckpoint;\n agent_info: AgentInfo | null;\n current_context_usage: CurrentContextUsage;\n }\n >();\n\n for (const row of contextRows) {\n if (!threadMeta.has(row.thread_id)) {\n threadMeta.set(row.thread_id, {\n checkpoint: row.checkpoint,\n agent_info: row.agent_info,\n current_context_usage: row.current_context_usage,\n });\n orderedBodies.set(row.thread_id, []);\n }\n if (row.body !== null) {\n const bodies = orderedBodies.get(row.thread_id);\n if (bodies !== undefined) {\n bodies.push(row.body);\n }\n }\n }\n\n for (const [threadId, meta] of threadMeta) {\n const context = orderedBodies.get(threadId) ?? [];\n const capability_state = capabilityByThread.get(threadId) ?? null;\n\n const snap: AgentThreadSnapshot = {\n thread_id: threadId,\n context,\n current_context_usage: meta.current_context_usage,\n parent: meta.checkpoint.parent,\n agent_info: meta.agent_info,\n completion: meta.checkpoint.completion,\n capability_state,\n };\n threads[threadId] = snap;\n }\n\n const checkpoint = turn.checkpoint;\n const snapshot: TurnSnapshot = {\n threads,\n mcp_servers: checkpoint.mcp_servers,\n sandbox_info: checkpoint.sandbox_info,\n };\n\n return {\n turn_id: turn.turn_id,\n session_id: turn.session_id,\n first_turn_id: turn.first_turn_id,\n ancestor_ids: turn.ancestor_ids,\n previous_turn_id: turn.previous_turn_id,\n state: turn.state,\n input: turn.input,\n snapshot,\n created_at: new Date(turn.created_at),\n updated_at: new Date(turn.updated_at),\n custom: parseTurnCustom(turn.custom),\n };\n}\n\n/**\n * createTurn — IMMEDIATE tx (BEGIN IMMEDIATE covers write locking; no FOR UPDATE/FOR SHARE).\n * Context order lives in turn_thread_context (pos, append_id); no context_ids array.\n */\nexport async function createTurn(db: Kysely<Database>, input: CreateTurnInput): Promise<void> {\n try {\n await db.transaction().execute(async trx => {\n // Step 1: read session tip; no FOR UPDATE (BEGIN IMMEDIATE is the lock).\n const locked = await trx\n .selectFrom('session')\n .select(['last_turn_id'])\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n\n if (!locked) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n // Step 2: bump session tip + optional title coalesce.\n let sessionUpdate = trx\n .updateTable('session')\n .set({\n last_turn_id: input.turn.turn_id,\n updated_at: nowIso(),\n last_activity_timestamp_ms: input.last_activity_timestamp_ms,\n })\n .where('session_id', '=', input.session_id);\n\n if (input.update_session_title_if_not_exist !== null) {\n const titleValue = input.update_session_title_if_not_exist;\n sessionUpdate = sessionUpdate.set({\n title: sql<string>`COALESCE(title, ${titleValue})`,\n });\n }\n\n await sessionUpdate.execute();\n\n const prevTurnId = input.turn.previous_turn_id;\n\n let prevCheckpoint: TurnCheckpoint | null = null;\n const prevThreadRows: {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: AgentInfo | null;\n current_context_usage: CurrentContextUsage;\n context_pos_max: number;\n }[] = [];\n\n if (prevTurnId != null) {\n // Read previous turn + its turn_thread rows in one join.\n const prevRows = await trx\n .selectFrom('turn as t')\n .leftJoin('turn_thread as tt', join =>\n join.onRef('tt.session_id', '=', 't.session_id').onRef('tt.turn_id', '=', 't.turn_id'),\n )\n .leftJoin(\n db\n .selectFrom('turn_thread_context')\n .select(['thread_id', 'turn_id', sql<number>`MAX(pos)`.as('max_pos')])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', prevTurnId)\n .groupBy(['thread_id', 'turn_id'])\n .as('tc_agg'),\n join => join.onRef('tc_agg.thread_id', '=', 'tt.thread_id').onRef('tc_agg.turn_id', '=', 'tt.turn_id'),\n )\n .select([\n jsonText<TurnCheckpoint>(sql.ref('t.checkpoint')).as('turn_checkpoint'),\n jsonText<TurnState>(sql.ref('t.state')).as('turn_state'),\n 'tt.thread_id',\n jsonText<TurnThreadCheckpoint | null>(sql.ref('tt.checkpoint')).as('thread_checkpoint'),\n jsonText<AgentInfo | null>(sql.ref('tt.agent_info')).as('agent_info'),\n jsonText<CurrentContextUsage | null>(sql.ref('tt.current_context_usage')).as('current_context_usage'),\n 'tc_agg.max_pos',\n ])\n .where('t.session_id', '=', input.session_id)\n .where('t.turn_id', '=', prevTurnId)\n .execute();\n\n const first = prevRows[0];\n if (first !== undefined) {\n if (first.turn_state.status === 'running') {\n throw new PreviousTurnRunningError(prevTurnId);\n }\n prevCheckpoint = first.turn_checkpoint;\n\n for (const row of prevRows) {\n if (row.thread_id === null) {\n continue;\n }\n if (row.thread_checkpoint === null || row.current_context_usage === null) {\n throw new SessionStoreInvariantError(`previous turn_thread row for ${row.thread_id} is incomplete`);\n }\n prevThreadRows.push({\n thread_id: row.thread_id,\n checkpoint: row.thread_checkpoint,\n agent_info: row.agent_info,\n current_context_usage: row.current_context_usage,\n context_pos_max: row.max_pos ?? 0,\n });\n }\n }\n }\n\n assertCreateTurnThreadDelta({\n previousThreadIds: new Set(prevThreadRows.map(r => r.thread_id)),\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n const checkpoint: TurnCheckpoint = {\n mcp_servers: input.mcp_servers ?? prevCheckpoint?.mcp_servers ?? null,\n sandbox_info: input.sandbox_info ?? prevCheckpoint?.sandbox_info ?? null,\n };\n\n const now = nowIso();\n\n const turnCustom = input.turn.custom ?? null;\n\n // Step 3: insert turn row.\n await trx\n .insertInto('turn')\n .values({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n first_turn_id: input.turn.first_turn_id,\n previous_turn_id: input.turn.previous_turn_id ?? null,\n ancestor_ids: jsonbBind(input.turn.ancestor_ids),\n input: jsonbBind(input.turn.input),\n state: jsonbBind(input.turn.state),\n checkpoint: jsonbBind(checkpoint),\n custom: turnCustom !== null ? jsonbBind(turnCustom) : null,\n created_at: now,\n updated_at: now,\n })\n .execute();\n\n // Step 4: insert new context log rows.\n const logRows: {\n session_id: string;\n thread_id: string;\n turn_id: string;\n body: RawBuilder<string>;\n created_at: string;\n }[] = [];\n\n for (const append of input.new_context_appends) {\n for (const body of append.context) {\n logRows.push({\n session_id: input.session_id,\n thread_id: append.thread_id,\n turn_id: input.turn.turn_id,\n body: jsonbBind(body),\n created_at: now,\n });\n }\n }\n\n const newIdsByThread = new Map<string, number[]>();\n if (logRows.length > 0) {\n const inserted = await trx\n .insertInto('thread_context_log')\n .values(logRows)\n .returning(['thread_id', 'append_id'])\n .execute();\n for (const row of sortedByAppendId(inserted)) {\n const list = newIdsByThread.get(row.thread_id);\n if (list === undefined) {\n newIdsByThread.set(row.thread_id, [row.append_id]);\n } else {\n list.push(row.append_id);\n }\n }\n }\n\n const appendUsageByThread = new Map<string, CurrentContextUsage>();\n for (const append of input.new_context_appends) {\n if (append.current_context_usage !== null) {\n appendUsageByThread.set(append.thread_id, append.current_context_usage);\n }\n }\n\n // Step 5: insert turn_thread rows for carried-forward and new threads.\n const turnThreadRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n checkpoint: RawBuilder<string>;\n agent_info: RawBuilder<string> | null;\n current_context_usage: RawBuilder<string>;\n updated_at: string;\n }[] = [];\n\n const turnThreadContextRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n pos: number;\n append_id: number;\n }[] = [];\n\n for (const parent of prevThreadRows) {\n const usage = appendUsageByThread.get(parent.thread_id) ?? parent.current_context_usage;\n turnThreadRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: parent.thread_id,\n checkpoint: jsonbBind(parent.checkpoint),\n agent_info: parent.agent_info !== null ? jsonbBind(parent.agent_info) : null,\n current_context_usage: jsonbBind(usage),\n updated_at: now,\n });\n }\n\n // One SELECT for all parent context mappings (not N+1 per thread).\n if (prevTurnId != null && prevThreadRows.length > 0) {\n const parentContextRows = await trx\n .selectFrom('turn_thread_context')\n .select(['thread_id', 'pos', 'append_id'])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', prevTurnId)\n .where(\n 'thread_id',\n 'in',\n prevThreadRows.map(r => r.thread_id),\n )\n .orderBy('thread_id')\n .orderBy('pos')\n .execute();\n\n for (const cr of parentContextRows) {\n turnThreadContextRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: cr.thread_id,\n pos: cr.pos,\n append_id: cr.append_id,\n });\n }\n }\n\n for (const parent of prevThreadRows) {\n const newIds = newIdsByThread.get(parent.thread_id) ?? [];\n const basePos = parent.context_pos_max;\n for (let i = 0; i < newIds.length; i++) {\n const appendId = newIds[i];\n if (appendId !== undefined) {\n turnThreadContextRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: parent.thread_id,\n pos: basePos + i + 1,\n append_id: appendId,\n });\n }\n }\n }\n\n // Step 5b: new threads — fresh turn_thread + mapping rows.\n for (const nt of input.new_threads) {\n const newIds = newIdsByThread.get(nt.thread_id) ?? [];\n const usage = appendUsageByThread.get(nt.thread_id) ?? getEmptyCurrentContextUsage();\n const threadCheckpoint: TurnThreadCheckpoint = {\n parent: nt.parent,\n completion: null,\n };\n turnThreadRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: nt.thread_id,\n checkpoint: jsonbBind(threadCheckpoint),\n agent_info: nt.agent_info !== null ? jsonbBind(nt.agent_info) : null,\n current_context_usage: jsonbBind(usage),\n updated_at: now,\n });\n\n for (let i = 0; i < newIds.length; i++) {\n const appendId = newIds[i];\n if (appendId !== undefined) {\n turnThreadContextRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: nt.thread_id,\n pos: i + 1,\n append_id: appendId,\n });\n }\n }\n }\n\n if (turnThreadRows.length > 0) {\n await trx.insertInto('turn_thread').values(turnThreadRows).execute();\n }\n\n if (turnThreadContextRows.length > 0) {\n await trx.insertInto('turn_thread_context').values(turnThreadContextRows).execute();\n }\n\n // Step 6: insert capability state rows (thread coverage asserted above).\n const capabilityStateRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: RawBuilder<string> | null;\n updated_at: string;\n }[] = [];\n\n for (const capability of input.capability_states) {\n if (capability.capability_state === null) {\n continue;\n }\n for (const [key, state] of Object.entries(capability.capability_state)) {\n capabilityStateRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: capability.thread_id,\n key,\n state: state !== null ? jsonbBind(state) : null,\n updated_at: now,\n });\n }\n }\n\n if (capabilityStateRows.length > 0) {\n await trx.insertInto('thread_capability_state').values(capabilityStateRows).execute();\n }\n });\n } catch (err) {\n if (err instanceof SessionStoreNotFoundError || err instanceof SessionStoreConflictError) {\n throw err;\n }\n if (isUniqueViolation(err)) {\n throw new TurnAlreadyExistsError(input.turn.turn_id, { cause: err });\n }\n throw err;\n }\n}\n\n/**\n * freezeAndGetTurn — cancel if still running, then return the assembled record.\n * Terminal turns are returned unchanged (freeze is a plain read).\n */\nexport async function freezeAndGetTurn(db: Kysely<Database>, input: FreezeAndGetTurnInput): Promise<TurnRecord> {\n return await db.transaction().execute(async trx => {\n const cancelledState: TerminalTurnState = {\n status: 'cancelled',\n reason: input.reason,\n completed_at: nowIso(),\n };\n\n const updateResult = await trx\n .updateTable('turn')\n .set({\n state: jsonbBind(cancelledState),\n updated_at: nowIso(),\n })\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(updateResult.numUpdatedRows) > 0) {\n await trx\n .insertInto('session_event')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: input.turn_done_event.id,\n event: jsonbBind(input.turn_done_event),\n created_at: input.turn_done_event.created_at,\n })\n .execute();\n }\n\n const record = await assembleTurnRecord(trx, input);\n if (!record) {\n throw new TurnNotFoundError(input.turn_id);\n }\n return record;\n });\n}\n\n/**\n * getTurn — deferred read tx so assembleTurnRecord's SELECTs share one snapshot.\n * ImmediateSqliteDriver maps setAccessMode('read only') → BEGIN (not IMMEDIATE).\n */\nexport async function getTurn(db: Kysely<Database>, input: GetTurnInput): Promise<TurnRecord<TurnCustom> | undefined> {\n return db\n .transaction()\n .setAccessMode('read only')\n .execute(trx => assembleTurnRecord(trx, input));\n}\n\n/**\n * listTurns — ORDER BY created_at, turn_id; LIMIT limit+1 OFFSET offset.\n * Returns turn rows only (no snapshot assembly); use getTurn for full TurnRecord.\n */\nexport async function listTurns(db: Kysely<Database>, input: ListTurnsInput): Promise<ListTurnsResult> {\n const rows = await db\n .selectFrom('turn')\n .select([\n 'session_id',\n 'turn_id',\n 'first_turn_id',\n 'previous_turn_id',\n jsonText<string[]>(sql.ref('ancestor_ids')).as('ancestor_ids'),\n jsonText<TurnInputItem[]>(sql.ref('input')).as('input'),\n jsonText<TurnState>(sql.ref('state')).as('state'),\n jsonText<Record<string, unknown> | null>(sql.ref('custom')).as('custom'),\n 'created_at',\n 'updated_at',\n ])\n .where('session_id', '=', input.session_id)\n .orderBy('created_at', 'asc')\n .orderBy('turn_id', 'asc')\n .limit(input.limit + 1)\n .offset(input.offset)\n .execute();\n\n const hasMore = rows.length > input.limit;\n const page = hasMore ? rows.slice(0, input.limit) : rows;\n\n const turns: TurnRecordWithoutSnapshot<TurnCustom>[] = page.map(row => ({\n turn_id: row.turn_id,\n session_id: row.session_id,\n first_turn_id: row.first_turn_id,\n ancestor_ids: row.ancestor_ids,\n previous_turn_id: row.previous_turn_id,\n state: row.state,\n input: row.input,\n created_at: new Date(row.created_at),\n updated_at: new Date(row.updated_at),\n custom: parseTurnCustom(row.custom),\n }));\n\n return {\n turns,\n next_offset: hasMore ? input.offset + input.limit : null,\n };\n}\n\n/**\n * updateTurnState — conditional on state->>'status'='running'.\n * 0 rows → SELECT by PK → missing NotFound, present Conflict (first terminal write wins).\n */\nexport async function updateTurnState(db: Kysely<Database>, input: UpdateTurnStateInput): Promise<void> {\n await db.transaction().execute(async trx => {\n const result = await trx\n .updateTable('turn')\n .set({\n state: jsonbBind(input.state),\n updated_at: nowIso(),\n })\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n const numUpdated = Number(result.numUpdatedRows);\n if (numUpdated === 0) {\n const existing = await trx\n .selectFrom('turn')\n .select([jsonText<TurnState>(sql.ref('state')).as('state')])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .executeTakeFirst();\n\n if (!existing) {\n throw new TurnNotFoundError(input.turn_id);\n }\n throw new TurnNotRunningError(input.turn_id, terminalTurnState(existing.state, input.turn_id));\n }\n\n await trx\n .insertInto('session_event')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: input.turn_done_event.id,\n event: jsonbBind(input.turn_done_event),\n created_at: input.turn_done_event.created_at,\n })\n .execute();\n });\n}\n","import type { PatchThreadCapabilityStateInput } from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport { sql, type Kysely } from 'kysely';\nimport { jsonbBind, nowIso } from '../../sqlExpressions';\nimport type { Database } from '../../types';\nimport { classifyTurnFenceWriteFailure } from './turns';\n\n/**\n * patchThreadCapabilityState — single-statement fenced upsert on the PER-TURN PK.\n * Does NOT bump turn.updated_at.\n * State is bound as SQL NULL when input.state is null (matches Postgres contract).\n */\nexport async function patchThreadCapabilityState(\n db: Kysely<Database>,\n input: PatchThreadCapabilityStateInput,\n): Promise<void> {\n await db.transaction().execute(async trx => {\n // Fence inside IMMEDIATE transaction: verify turn is still running.\n const fenceRow = await trx\n .selectFrom('turn')\n .select(sql`1`.as('one'))\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (!fenceRow) {\n await classifyTurnFenceWriteFailure(trx, input);\n }\n\n const now = nowIso();\n const stateValue = input.state !== null ? jsonbBind(input.state) : null;\n\n await trx\n .insertInto('thread_capability_state')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: input.thread_id,\n key: input.key,\n state: stateValue,\n updated_at: now,\n })\n .onConflict(oc =>\n oc.columns(['session_id', 'turn_id', 'thread_id', 'key']).doUpdateSet({\n state: sql`excluded.state`,\n updated_at: sql`excluded.updated_at`,\n }),\n )\n .execute();\n });\n}\n","import type { PersistedTurnEvent, SessionEventItem } from '@truefoundry/trueforge-core/agent-session/schemas/events';\nimport type { TokenPagination } from '@truefoundry/trueforge-core/agent-session/schemas/pagination';\nimport type {\n AppendToEventsInput,\n ListSessionEventsInput,\n ListTurnEventsInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeOffsetPageToken,\n paginateOffsetRows,\n} from '@truefoundry/trueforge-core/agent-session/store/OffsetPageToken';\nimport {\n decodeSessionEventPageToken,\n paginateSessionEventRows,\n type SessionEventPageCursor,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionEventPageToken';\nimport {\n SessionNotFoundError,\n TurnNotFoundError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport { sql, type Kysely } from 'kysely';\nimport { jsonbBind, jsonText } from '../../sqlExpressions';\nimport type { Database } from '../../types';\nimport { classifyTurnFenceWriteFailure, type TurnKeys } from './turns';\n\nexport async function appendToEvents(db: Kysely<Database>, input: AppendToEventsInput): Promise<void> {\n if (input.events.length === 0) {\n return;\n }\n\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n // Fence check first inside BEGIN IMMEDIATE; then batched insert.\n await db.transaction().execute(async trx => {\n const fenceRow = await trx\n .selectFrom('turn')\n .select(sql`1`.as('one'))\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (!fenceRow) {\n await classifyTurnFenceWriteFailure(trx, keys);\n }\n\n const eventRows = input.events.map(event => ({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: event.id,\n event: jsonbBind(event),\n created_at: event.created_at,\n }));\n\n await trx.insertInto('session_event').values(eventRows).execute();\n });\n}\n\n/**\n * listTurnEvents — one statement: drive from turn, left-join a page of events.\n * Missing turn → 0 rows → TurnNotFoundError. Empty log → one null-event sentinel.\n */\nexport async function listTurnEvents(\n db: Kysely<Database>,\n input: ListTurnEventsInput,\n): Promise<{ data: PersistedTurnEvent[]; pagination: TokenPagination }> {\n const offset = decodeOffsetPageToken(input.page_token);\n const limit = input.limit;\n const eventOrder = input.order === 'desc' ? 'desc' : 'asc';\n\n const rows = await db\n .selectFrom('turn as t')\n .leftJoin(\n eb =>\n eb\n .selectFrom('session_event')\n .select(['session_id', 'turn_id', 'event_id', jsonText<PersistedTurnEvent>(sql.ref('event')).as('event')])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .orderBy('event_id', eventOrder)\n .limit(limit + 1)\n .offset(offset)\n .as('e'),\n join => join.onRef('e.session_id', '=', 't.session_id').onRef('e.turn_id', '=', 't.turn_id'),\n )\n .select(['t.turn_id', 'e.event'])\n .where('t.session_id', '=', input.session_id)\n .where('t.turn_id', '=', input.turn_id)\n .orderBy('e.event_id', eventOrder)\n .execute();\n\n if (rows.length === 0) {\n throw new TurnNotFoundError(input.turn_id);\n }\n\n const events: PersistedTurnEvent[] = [];\n for (const row of rows) {\n if (row.event !== null) {\n events.push(row.event);\n }\n }\n\n return paginateOffsetRows(events, limit, offset);\n}\n\n/** Anchor turn fields needed for chain resolution. */\nexport interface AnchorTurn {\n turn_id: string;\n ancestor_ids: string[];\n}\n\n/**\n * Full chain (oldest first, anchor last). `ancestor_ids` may be only the\n * previous N ancestors, so spill through the oldest ancestor's own window\n * until a root or gap. A missing turn or repeated id ends the walk.\n */\nexport async function resolveAncestorChain(\n db: Kysely<Database>,\n sessionId: string,\n anchor: AnchorTurn,\n): Promise<string[]> {\n const chain = [...anchor.ancestor_ids, anchor.turn_id];\n const seen = new Set(chain);\n let oldestId = chain[0];\n while (oldestId && oldestId !== anchor.turn_id) {\n const oldest = await db\n .selectFrom('turn')\n .select([jsonText<string[]>(sql.ref('ancestor_ids')).as('ancestor_ids')])\n .where('session_id', '=', sessionId)\n .where('turn_id', '=', oldestId)\n .executeTakeFirst();\n if (!oldest) {\n break;\n }\n const older = oldest.ancestor_ids.filter(id => !seen.has(id));\n if (older.length === 0) {\n break;\n }\n chain.unshift(...older);\n for (const id of older) {\n seen.add(id);\n }\n oldestId = older[0];\n }\n return chain;\n}\n\nexport async function listSessionEvents(\n db: Kysely<Database>,\n input: ListSessionEventsInput,\n): Promise<{ data: SessionEventItem[]; pagination: TokenPagination }> {\n const limit = input.limit;\n\n const session = await db\n .selectFrom('session')\n .select('last_turn_id')\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n if (!session) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n const decodedCursor = input.page_token === undefined ? undefined : decodeSessionEventPageToken(input.page_token);\n const lastTurnId = decodedCursor?.last_turn_id ?? input.last_turn_id ?? session.last_turn_id;\n if (lastTurnId === null) {\n return { data: [], pagination: { limit } };\n }\n const cursor: SessionEventPageCursor = {\n last_turn_id: lastTurnId,\n offset: decodedCursor?.offset ?? 0,\n };\n\n const anchor = await db\n .selectFrom('turn')\n .select(['turn_id', jsonText<string[]>(sql.ref('ancestor_ids')).as('ancestor_ids')])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', cursor.last_turn_id)\n .executeTakeFirst();\n if (!anchor) {\n throw new TurnNotFoundError(cursor.last_turn_id);\n }\n\n const chainIds = await resolveAncestorChain(db, input.session_id, {\n turn_id: anchor.turn_id,\n ancestor_ids: anchor.ancestor_ids,\n });\n\n // Bind the ancestor chain as a JSON array; json_each gives (key=index, value=turn_id).\n const chainJson = JSON.stringify(chainIds);\n\n const rows = await db\n .selectFrom(sql<{ key: number; value: string }>`json_each(${chainJson})`.as('c'))\n .innerJoin('session_event as e', join =>\n join.on('e.session_id', '=', input.session_id).on(sql<boolean>`e.turn_id = c.value`),\n )\n .select([sql<string>`c.value`.as('turn_id'), jsonText<SessionEventItem['event']>(sql.ref('e.event')).as('event')])\n .orderBy(sql`c.key`, 'desc')\n .orderBy('e.event_id', 'desc')\n .limit(limit + 1)\n .offset(cursor.offset)\n .execute();\n\n return paginateSessionEventRows(rows, limit, cursor);\n}\n","import { AgentSpecSchema, type AgentSpec, type SessionAgent } from '@truefoundry/trueforge-core/agent-session';\n\n/** Flatten domain agent for SQL session columns (XOR agent_id / agent_spec; optional name snapshot). */\nexport function sessionAgentToColumns(agent: SessionAgent): {\n agent_id: string | null;\n agent_name: string | null;\n agent_spec: AgentSpec | null;\n} {\n if (agent.type === 'reference') {\n return { agent_id: agent.id, agent_name: agent.name, agent_spec: null };\n }\n return { agent_id: null, agent_name: null, agent_spec: agent.spec };\n}\n\n/** Rebuild domain agent from SQL session columns. */\nexport function sessionAgentFromColumns(input: {\n session_id: string;\n agent_id: string | null;\n agent_name: string | null;\n agent_spec: AgentSpec | null;\n}): SessionAgent {\n if (input.agent_id !== null && input.agent_spec === null) {\n return { type: 'reference', id: input.agent_id, name: input.agent_name };\n }\n if (input.agent_id === null && input.agent_spec !== null) {\n // Re-parse so schema defaults apply to inline specs persisted before a config field existed.\n return { type: 'inline', spec: AgentSpecSchema.parse(input.agent_spec) };\n }\n throw new Error(\n `Session ${input.session_id} has invalid agent binding (exactly one of agent_id or agent_spec required)`,\n );\n}\n","import type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport type { SessionRecord } from '@truefoundry/trueforge-core/agent-session/models/SessionRecord';\nimport type {\n CreateSessionInput,\n DeleteSessionInput,\n GetSessionInput,\n ListSessionsInput,\n UpdateSessionInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeSessionListPageToken,\n paginateSessionListRows,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionListPageToken';\nimport {\n SessionAlreadyExistsError,\n SessionNotFoundError,\n SessionStoreInvariantError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport { sql, type Kysely } from 'kysely';\nimport { sessionAgentFromColumns, sessionAgentToColumns } from '../../../sessionAgentColumns';\nimport { isUniqueViolation } from '../../client';\nimport { jsonbBind, jsonText, nowIso } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\ntype SessionCustom = Record<string, never>;\ntype ProtoSessionRecord = SessionRecord<SessionCustom>;\n\nfunction isEmptyCustomRecord(value: Record<string, unknown>): value is SessionCustom {\n return Object.keys(value).length === 0;\n}\n\nfunction parseSessionCustom(value: Record<string, unknown> | null): SessionCustom | null {\n if (value === null) {\n return null;\n }\n if (!isEmptyCustomRecord(value)) {\n throw new SessionStoreInvariantError('non-empty session custom is not supported');\n }\n return value;\n}\n\nfunction mapRowToSessionRecord(row: {\n tenant_id: string;\n session_id: string;\n created_by: string;\n agent_id: string | null;\n agent_name: string | null;\n agent_spec: AgentSpec | null;\n title: string | null;\n last_turn_id: string | null;\n custom: Record<string, unknown> | null;\n created_at: string;\n updated_at: string;\n last_activity_timestamp_ms: number;\n}): ProtoSessionRecord {\n return {\n tenant_id: row.tenant_id,\n session_id: row.session_id,\n created_by: row.created_by,\n agent: sessionAgentFromColumns({\n session_id: row.session_id,\n agent_id: row.agent_id,\n agent_name: row.agent_name,\n agent_spec: row.agent_spec,\n }),\n title: row.title,\n last_turn_id: row.last_turn_id,\n custom: parseSessionCustom(row.custom),\n created_at: new Date(row.created_at),\n updated_at: new Date(row.updated_at),\n last_activity_timestamp_ms: row.last_activity_timestamp_ms,\n };\n}\n\nfunction sessionSelectColumns() {\n return [\n 'tenant_id' as const,\n 'session_id' as const,\n 'created_by' as const,\n 'agent_id' as const,\n 'agent_name' as const,\n jsonText<AgentSpec | null>(sql.ref('agent_spec')).as('agent_spec'),\n 'title' as const,\n 'last_turn_id' as const,\n jsonText<Record<string, unknown> | null>(sql.ref('custom')).as('custom'),\n 'created_at' as const,\n 'updated_at' as const,\n 'last_activity_timestamp_ms' as const,\n ];\n}\n\nexport async function createSession(db: Kysely<Database>, input: CreateSessionInput<SessionCustom>): Promise<void> {\n const columns = sessionAgentToColumns(input.agent);\n const now = nowIso();\n\n try {\n await db\n .insertInto('session')\n .values({\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n created_by: input.created_by,\n agent_id: columns.agent_id,\n agent_name: columns.agent_name,\n agent_spec: columns.agent_spec !== null ? jsonbBind(columns.agent_spec) : null,\n title: null,\n custom: input.custom !== null ? jsonbBind(input.custom) : null,\n created_at: now,\n updated_at: now,\n last_activity_timestamp_ms: Date.now(),\n })\n .execute();\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new SessionAlreadyExistsError(input.session_id, { cause: error });\n }\n throw error;\n }\n}\n\nexport async function deleteSession(db: Kysely<Database>, input: DeleteSessionInput): Promise<void> {\n await db\n .deleteFrom('session')\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .execute();\n}\n\nexport async function getSession(\n db: Kysely<Database>,\n input: GetSessionInput,\n): Promise<ProtoSessionRecord | undefined> {\n const row = await db\n .selectFrom('session')\n .select(sessionSelectColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n\n if (row === undefined) {\n return undefined;\n }\n\n return mapRowToSessionRecord(row);\n}\n\nexport async function updateSession(db: Kysely<Database>, input: UpdateSessionInput<SessionCustom>): Promise<void> {\n const agent = input.agent;\n const title = input.title;\n\n if (agent !== undefined) {\n const existing = await getSession(db, { tenant_id: input.tenant_id, session_id: input.session_id });\n if (existing === undefined) {\n throw new SessionNotFoundError(input.session_id);\n }\n if (existing.agent.type === 'reference') {\n throw new SessionStoreInvariantError(`Session ${input.session_id} is named; agent cannot be updated`);\n }\n }\n\n let qb = db\n .updateTable('session')\n .set({\n updated_at: nowIso(),\n last_activity_timestamp_ms: Date.now(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id);\n\n if (agent !== undefined) {\n qb = qb.set({ agent_spec: jsonbBind(agent.spec) });\n }\n if (title !== undefined) {\n qb = qb.set({ title });\n }\n\n const result = await qb.executeTakeFirst();\n\n const numUpdatedRows = Number(result.numUpdatedRows);\n if (numUpdatedRows === 0) {\n throw new SessionNotFoundError(input.session_id);\n }\n}\n\nexport async function listSessions(\n db: Kysely<Database>,\n input: ListSessionsInput,\n): Promise<{\n data: ProtoSessionRecord[];\n pagination: { next_page_token?: string | undefined; previous_page_token?: string | undefined };\n}> {\n const limit = input.limit;\n const order = input.order ?? 'desc';\n const cursor = decodeSessionListPageToken(input.page_token);\n\n let query = db.selectFrom('session').select(sessionSelectColumns).where('tenant_id', '=', input.tenant_id);\n\n if (input.agent_id !== undefined) {\n query = query.where('agent_id', '=', input.agent_id);\n }\n if (input.created_by !== undefined) {\n query = query.where('created_by', '=', input.created_by);\n }\n if (input.start_timestamp !== undefined) {\n query = query.where('created_at', '>=', input.start_timestamp.toISOString());\n }\n if (input.end_timestamp !== undefined) {\n query = query.where('created_at', '<=', input.end_timestamp.toISOString());\n }\n\n if (cursor) {\n const cursorUpdatedAt = cursor.updated_at;\n const sessionId = cursor.session_id;\n if (order === 'asc') {\n query = query.where(eb =>\n eb.or([\n eb('updated_at', '>', cursorUpdatedAt),\n eb.and([eb('updated_at', '=', cursorUpdatedAt), eb('session_id', '>', sessionId)]),\n ]),\n );\n } else {\n query = query.where(eb =>\n eb.or([\n eb('updated_at', '<', cursorUpdatedAt),\n eb.and([eb('updated_at', '=', cursorUpdatedAt), eb('session_id', '<', sessionId)]),\n ]),\n );\n }\n }\n\n if (order === 'asc') {\n query = query.orderBy('updated_at', 'asc').orderBy('session_id', 'asc');\n } else {\n query = query.orderBy('updated_at', 'desc').orderBy('session_id', 'desc');\n }\n\n const rows = await query.limit(limit + 1).execute();\n // SQLite stores updated_at as ISO text already — use it directly for the keyset cursor.\n const { data: pageRows, pagination } = paginateSessionListRows(rows, limit, row => row.updated_at);\n\n return { data: pageRows.map(mapRowToSessionRecord), pagination };\n}\n","import type {\n AddThreadsInput,\n AppendToThreadContextInput,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n RemoveThreadsInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport type {\n ContextMessage,\n SubAgentCompletionMarker,\n} from '@truefoundry/trueforge-core/core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport { sql, type Kysely, type RawBuilder, type Transaction } from 'kysely';\nimport { jsonbBind, jsonbSet, nowIso } from '../../sqlExpressions';\nimport type { Database, TurnThreadCheckpoint } from '../../types';\nimport { sortedByAppendId } from '../sqlExpressions';\nimport {\n assertTurnRunning,\n classifyTurnFenceWriteFailure,\n classifyTurnThreadWriteFailure,\n type TurnKeys,\n} from './turns';\n\ntype DbOrTrx = Kysely<Database> | Transaction<Database>;\n\n/**\n * addThreads — fenced tx: INSERT log rows, INSERT turn_thread rows,\n * INSERT turn_thread_context rows, INSERT capability rows.\n */\nexport async function addThreads(db: Kysely<Database>, input: AddThreadsInput): Promise<void> {\n await db.transaction().execute(async trx => {\n await assertTurnRunning(trx, {\n session_id: input.session_id,\n turn_id: input.turn_id,\n });\n\n const now = nowIso();\n const logRows: {\n session_id: string;\n thread_id: string;\n turn_id: string;\n body: RawBuilder<string>;\n created_at: string;\n }[] = [];\n const capabilityStateRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: RawBuilder<string> | null;\n updated_at: string;\n }[] = [];\n const turnThreadPlans: {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: RawBuilder<string> | null;\n current_context_usage: CurrentContextUsage;\n }[] = [];\n\n for (const thread of input.threads) {\n const threadCheckpoint: TurnThreadCheckpoint = {\n parent: thread.parent ?? null,\n completion: thread.completion ?? null,\n };\n turnThreadPlans.push({\n thread_id: thread.thread_id,\n checkpoint: threadCheckpoint,\n agent_info: thread.agent_info != null ? jsonbBind(thread.agent_info) : null,\n current_context_usage: thread.current_context_usage,\n });\n\n for (const body of thread.context) {\n logRows.push({\n session_id: input.session_id,\n thread_id: thread.thread_id,\n turn_id: input.turn_id,\n body: jsonbBind(body),\n created_at: now,\n });\n }\n\n const capabilityState = thread.capability_state;\n if (capabilityState != null) {\n for (const key of Object.keys(capabilityState)) {\n const state = capabilityState[key];\n if (state === undefined) {\n throw new Error(\n `capability_state['${key}'] for thread '${thread.thread_id}' is undefined — undefined is banned from capability state`,\n );\n }\n capabilityStateRows.push({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: thread.thread_id,\n key,\n state: state !== null ? jsonbBind(state) : null,\n updated_at: now,\n });\n }\n }\n }\n\n const newIdsByThread = new Map<string, number[]>();\n if (logRows.length > 0) {\n const inserted = await trx\n .insertInto('thread_context_log')\n .values(logRows)\n .returning(['thread_id', 'append_id'])\n .execute();\n for (const row of sortedByAppendId(inserted)) {\n const list = newIdsByThread.get(row.thread_id);\n if (list === undefined) {\n newIdsByThread.set(row.thread_id, [row.append_id]);\n } else {\n list.push(row.append_id);\n }\n }\n }\n\n const turnThreadRows = turnThreadPlans.map(plan => ({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: plan.thread_id,\n checkpoint: jsonbBind(plan.checkpoint),\n agent_info: plan.agent_info,\n current_context_usage: jsonbBind(plan.current_context_usage),\n updated_at: now,\n }));\n\n if (turnThreadRows.length > 0) {\n await trx.insertInto('turn_thread').values(turnThreadRows).execute();\n }\n\n const contextMappingRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n pos: number;\n append_id: number;\n }[] = [];\n\n for (const plan of turnThreadPlans) {\n const newIds = newIdsByThread.get(plan.thread_id) ?? [];\n for (let i = 0; i < newIds.length; i++) {\n const appendId = newIds[i];\n if (appendId !== undefined) {\n contextMappingRows.push({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: plan.thread_id,\n pos: i + 1,\n append_id: appendId,\n });\n }\n }\n }\n\n if (contextMappingRows.length > 0) {\n await trx.insertInto('turn_thread_context').values(contextMappingRows).execute();\n }\n\n if (capabilityStateRows.length > 0) {\n await trx.insertInto('thread_capability_state').values(capabilityStateRows).execute();\n }\n });\n}\n\n/**\n * removeThreads — fenced tx: DELETE this turn's turn_thread rows,\n * turn_thread_context rows, and capability rows.\n * Older turns keep their per-turn maps. Log rows stay (other turns may reference them).\n * Empty thread_ids is a no-op.\n */\nexport async function removeThreads(db: Kysely<Database>, input: RemoveThreadsInput): Promise<void> {\n if (input.thread_ids.length === 0) {\n return;\n }\n\n await db.transaction().execute(async trx => {\n await assertTurnRunning(trx, {\n session_id: input.session_id,\n turn_id: input.turn_id,\n });\n\n await trx\n .deleteFrom('turn_thread_context')\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .execute();\n\n await trx\n .deleteFrom('turn_thread')\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .execute();\n\n await trx\n .deleteFrom('thread_capability_state')\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .execute();\n });\n}\n\nasync function getNextPos(db: DbOrTrx, keys: TurnKeys, thread_id: string): Promise<number> {\n const maxRow = await db\n .selectFrom('turn_thread_context')\n .select([sql<number | null>`MAX(pos)`.as('max_pos')])\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .executeTakeFirst();\n return (maxRow?.max_pos ?? 0) + 1;\n}\n\nfunction completionPatchExpr(completion: SubAgentCompletionMarker | null): RawBuilder<string> {\n if (completion === null) {\n return sql`checkpoint`;\n }\n return jsonbSet(sql.ref('checkpoint'), '$.completion', completion);\n}\n\nfunction usageSetExpr(usage: CurrentContextUsage | null): RawBuilder<string> {\n if (usage === null) {\n return sql`current_context_usage`;\n }\n return sql`coalesce(${jsonbBind(usage)}, current_context_usage)`;\n}\n\nasync function fencedTurnThreadContextUpdate(\n db: Kysely<Database>,\n args: {\n keys: TurnKeys;\n thread_id: string;\n context: ContextMessage[];\n replace_array: boolean;\n current_context_usage: CurrentContextUsage | null;\n completion: SubAgentCompletionMarker | null;\n /** When replace_array, usage is set unconditionally (overwrite contract). */\n usage_unconditional: CurrentContextUsage | null;\n },\n): Promise<void> {\n const { keys, thread_id, context, replace_array } = args;\n\n await db.transaction().execute(async trx => {\n await assertTurnRunning(trx, keys);\n\n const now = nowIso();\n\n if (replace_array) {\n await trx\n .deleteFrom('turn_thread_context')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .execute();\n }\n\n if (context.length > 0) {\n const logRows = context.map(body => ({\n session_id: keys.session_id,\n thread_id,\n turn_id: keys.turn_id,\n body: jsonbBind(body),\n created_at: now,\n }));\n\n const inserted = await trx.insertInto('thread_context_log').values(logRows).returning(['append_id']).execute();\n\n let nextPos = replace_array ? 1 : await getNextPos(trx, keys, thread_id);\n\n const contextMappingRows: {\n session_id: string;\n turn_id: string;\n thread_id: string;\n pos: number;\n append_id: number;\n }[] = [];\n\n for (const row of sortedByAppendId(inserted)) {\n contextMappingRows.push({\n session_id: keys.session_id,\n turn_id: keys.turn_id,\n thread_id,\n pos: nextPos,\n append_id: row.append_id,\n });\n nextPos++;\n }\n\n if (contextMappingRows.length > 0) {\n await trx.insertInto('turn_thread_context').values(contextMappingRows).execute();\n }\n }\n\n const usageExpr =\n args.usage_unconditional !== null\n ? jsonbBind(args.usage_unconditional)\n : usageSetExpr(args.current_context_usage);\n\n const updateResult = await trx\n .updateTable('turn_thread')\n .set({\n checkpoint: completionPatchExpr(args.completion),\n current_context_usage: usageExpr,\n updated_at: now,\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .executeTakeFirst();\n\n if (Number(updateResult.numUpdatedRows) === 0) {\n await classifyTurnThreadWriteFailure(trx, keys, thread_id);\n }\n });\n}\n\n/**\n * appendToThreadContext — fenced transaction: inserts log rows, appends mapping rows,\n * updates usage (COALESCE: provided wins, else keep), patches completion.\n */\nexport async function appendToThreadContext(db: Kysely<Database>, input: AppendToThreadContextInput): Promise<void> {\n await fencedTurnThreadContextUpdate(db, {\n keys: {\n session_id: input.session_id,\n turn_id: input.turn_id,\n },\n thread_id: input.thread_id,\n context: input.context,\n replace_array: false,\n current_context_usage: input.current_context_usage,\n completion: input.completion,\n usage_unconditional: null,\n });\n}\n\n/**\n * overwriteThreadContext — same fenced shape; context mapping is REPLACED.\n * Old log rows stay — ancestor turns' context mapping may reference them.\n */\nexport async function overwriteThreadContext(db: Kysely<Database>, input: OverwriteThreadContextInput): Promise<void> {\n await fencedTurnThreadContextUpdate(db, {\n keys: {\n session_id: input.session_id,\n turn_id: input.turn_id,\n },\n thread_id: input.event.thread_id,\n context: input.event.context,\n replace_array: true,\n current_context_usage: null,\n completion: null,\n usage_unconditional: input.event.current_context_usage,\n });\n}\n\n/**\n * patchMCPServers — conditional UPDATE fenced on state->>'status'='running'.\n * Shallow merge by server id (Postgres `||`): patched ids replace wholesale.\n */\nexport async function patchMCPServers(db: Kysely<Database>, input: PatchMCPServersInput): Promise<void> {\n const serversById: Record<string, (typeof input.mcp_servers)[number]> = {};\n for (const server of input.mcp_servers) {\n serversById[server.id] = server;\n }\n\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n // jsonb_patch is RFC 7396 (deep); rebuild via json_each so each id's value is replaced.\n const patchJson = JSON.stringify(serversById);\n\n const result = await db\n .updateTable('turn')\n .set({\n checkpoint: sql<string>`jsonb_set(\n checkpoint,\n '$.mcp_servers',\n coalesce((\n SELECT jsonb_group_object(key, jsonb(value))\n FROM (\n SELECT key, value\n FROM json_each(\n CASE WHEN json_type(checkpoint, '$.mcp_servers') = 'object'\n THEN json(jsonb_extract(checkpoint, '$.mcp_servers'))\n ELSE '{}' END\n )\n WHERE key NOT IN (SELECT key FROM json_each(${patchJson}))\n UNION ALL\n SELECT key, value FROM json_each(${patchJson})\n )\n ), jsonb('{}'))\n )`,\n updated_at: nowIso(),\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\n/**\n * patchSandboxInfo — LWW replace via jsonb_set on sandbox_info key.\n */\nexport async function patchSandboxInfo(db: Kysely<Database>, input: PatchSandboxInfoInput): Promise<void> {\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const result = await db\n .updateTable('turn')\n .set({\n checkpoint: jsonbSet(sql.ref('checkpoint'), '$.sandbox_info', input.sandbox_info),\n updated_at: nowIso(),\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n","import type { SessionRecord } from '@truefoundry/trueforge-core/agent-session/models/SessionRecord';\nimport type { TurnRecord } from '@truefoundry/trueforge-core/agent-session/models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '@truefoundry/trueforge-core/agent-session/schemas/events';\nimport type { TokenPagination } from '@truefoundry/trueforge-core/agent-session/schemas/pagination';\nimport type {\n AddThreadsInput,\n AppendToEventsInput,\n AppendToThreadContextInput,\n CreateSessionInput,\n CreateTurnInput,\n DeleteSessionInput,\n FreezeAndGetTurnInput,\n GetSessionInput,\n GetTurnInput,\n ISessionStore,\n ListSessionEventsInput,\n ListSessionsInput,\n ListTurnEventsInput,\n ListTurnsInput,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n PatchThreadCapabilityStateInput,\n RemoveThreadsInput,\n TurnRecordWithoutSnapshot,\n UpdateSessionInput,\n UpdateTurnStateInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeOffsetPageToken,\n encodeOffsetPageToken,\n} from '@truefoundry/trueforge-core/agent-session/store/OffsetPageToken';\nimport type { Kysely } from 'kysely';\nimport type { Database } from '../types';\nimport { patchThreadCapabilityState as patchThreadCapabilityStateQuery } from './queries/capabilities';\nimport {\n appendToEvents as appendToEventsQuery,\n listSessionEvents as listSessionEventsQuery,\n listTurnEvents as listTurnEventsQuery,\n} from './queries/events';\nimport {\n createSession as createSessionQuery,\n deleteSession as deleteSessionQuery,\n getSession as getSessionQuery,\n listSessions as listSessionsQuery,\n updateSession as updateSessionQuery,\n} from './queries/sessions';\nimport {\n addThreads as addThreadsQuery,\n appendToThreadContext as appendToThreadContextQuery,\n overwriteThreadContext as overwriteThreadContextQuery,\n patchMCPServers as patchMCPServersQuery,\n patchSandboxInfo as patchSandboxInfoQuery,\n removeThreads as removeThreadsQuery,\n} from './queries/threads';\nimport type { NewThreadRegistration } from './queries/turns';\nimport {\n createTurn as createTurnQuery,\n freezeAndGetTurn as freezeAndGetTurnQuery,\n getTurn as getTurnQuery,\n listTurns as listTurnsQuery,\n updateTurnState as updateTurnStateQuery,\n} from './queries/turns';\n\ntype SessionCustom = Record<string, never>;\ntype TurnCustom = Record<string, never>;\n\n/**\n * ## Design: append-only context log + per-turn position table\n *\n * Message bodies live in `thread_context_log`, append-only, written exactly\n * once; ids are SQLite AUTOINCREMENT (`append_id`). A turn's context per thread\n * is ordered rows in `turn_thread_context (pos, append_id)` — no array column.\n * Turns share no mutable structure: linear continuation and fork are the same\n * copy path (parent context mapping rows + new mapping rows), overwrite deletes\n * the current mapping and inserts a fresh one, and a still-running ancestor's\n * late appends touch only its OWN rows — structural leaks are impossible.\n *\n * Hard invariants:\n * 1. A turn cannot be used as `previous_turn_id` while it is still `running` —\n * `createTurn` rejects that; callers must `freezeAndGetTurn` first.\n * Tip-equality is NOT required: new roots and concurrent forks from a\n * finished tip can leave more than one turn `running` at once.\n * 2. Every turn-scoped write is fenced on `state->>'status' = 'running'`.\n * 3. Terminal turns are IMMUTABLE — a terminal read is a final read.\n * 4. BEGIN IMMEDIATE provides write locking (no FOR SHARE / FOR UPDATE).\n */\nexport class SqliteSessionStore implements ISessionStore<SessionCustom, TurnCustom> {\n constructor(private readonly db: Kysely<Database>) {}\n\n createSession(input: CreateSessionInput<SessionCustom>): Promise<void> {\n return createSessionQuery(this.db, input);\n }\n\n deleteSession(input: DeleteSessionInput): Promise<void> {\n return deleteSessionQuery(this.db, input);\n }\n\n getSession(input: GetSessionInput): Promise<SessionRecord<SessionCustom> | undefined> {\n return getSessionQuery(this.db, input);\n }\n\n updateSession(input: UpdateSessionInput<SessionCustom>): Promise<void> {\n return updateSessionQuery(this.db, input);\n }\n\n async listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<SessionCustom>[]; pagination: TokenPagination }> {\n const result = await listSessionsQuery(this.db, input);\n return {\n data: result.data,\n pagination: {\n limit: input.limit,\n ...result.pagination,\n },\n };\n }\n\n async createTurn(input: CreateTurnInput<TurnCustom>): Promise<void> {\n await createTurnQuery(this.db, {\n session_id: input.turn.session_id,\n turn: {\n turn_id: input.turn.turn_id,\n first_turn_id: input.turn.first_turn_id,\n previous_turn_id: input.turn.previous_turn_id,\n ancestor_ids: input.turn.ancestor_ids,\n input: input.turn.input,\n state: input.turn.state,\n custom: input.turn.custom,\n },\n new_threads: input.new_threads.map((thread): NewThreadRegistration => ({\n thread_id: thread.thread_id,\n parent: thread.parent,\n agent_info: thread.agent_info,\n })),\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n last_activity_timestamp_ms: Date.now(),\n update_session_title_if_not_exist: input.update_session_title_if_not_exist,\n mcp_servers: null,\n sandbox_info: null,\n });\n }\n\n freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TurnCustom>> {\n return freezeAndGetTurnQuery(this.db, input);\n }\n\n getTurn(input: GetTurnInput): Promise<TurnRecord<TurnCustom> | undefined> {\n return getTurnQuery(this.db, input);\n }\n\n async listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TurnCustom>[]; pagination: TokenPagination }> {\n const offset = decodeOffsetPageToken(input.page_token);\n const result = await listTurnsQuery(this.db, {\n session_id: input.session_id,\n limit: input.limit,\n offset,\n });\n const pagination: TokenPagination = { limit: input.limit };\n if (result.next_offset !== null) {\n pagination.next_page_token = encodeOffsetPageToken(result.next_offset);\n }\n if (offset > 0) {\n pagination.previous_page_token = encodeOffsetPageToken(Math.max(0, offset - input.limit));\n }\n return { data: result.turns, pagination };\n }\n\n updateTurnState(input: UpdateTurnStateInput): Promise<void> {\n return updateTurnStateQuery(this.db, input);\n }\n\n appendToEvents(input: AppendToEventsInput): Promise<void> {\n return appendToEventsQuery(this.db, input);\n }\n\n addThreads(input: AddThreadsInput): Promise<void> {\n return addThreadsQuery(this.db, input);\n }\n\n removeThreads(input: RemoveThreadsInput): Promise<void> {\n return removeThreadsQuery(this.db, input);\n }\n\n appendToThreadContext(input: AppendToThreadContextInput): Promise<void> {\n return appendToThreadContextQuery(this.db, input);\n }\n\n overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void> {\n return overwriteThreadContextQuery(this.db, input);\n }\n\n patchMCPServers(input: PatchMCPServersInput): Promise<void> {\n return patchMCPServersQuery(this.db, input);\n }\n\n patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void> {\n return patchSandboxInfoQuery(this.db, input);\n }\n\n patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void> {\n return patchThreadCapabilityStateQuery(this.db, input);\n }\n\n listTurnEvents(input: ListTurnEventsInput): Promise<{ data: PersistedTurnEvent[]; pagination: TokenPagination }> {\n return listTurnEventsQuery(this.db, input);\n }\n\n listSessionEvents(input: ListSessionEventsInput): Promise<{ data: SessionEventItem[]; pagination: TokenPagination }> {\n return listSessionEventsQuery(this.db, input);\n }\n}\n","import type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport type { AvailableModel, ModelProviderManifest } from '../../../schemas/modelProvider';\nimport {\n flattenProviderModels,\n ModelProviderNameConflictError,\n type CreateModelProviderInput,\n type GetModelProviderInput,\n type IModelProviderStore,\n type ModelProviderRecord,\n type UpsertModelProviderInput,\n} from '../../modelProviderStore';\nimport { isUniqueViolation } from '../client';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'model_provider'>) {\n return [\n 'tenant_id' as const,\n 'name' as const,\n jsonText<ModelProviderManifest>(eb.ref('manifest')).as('manifest'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nexport class SqliteModelProviderStore implements IModelProviderStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listProviders(tenantId: string, transaction?: Transaction<Database>): Promise<ModelProviderRecord[]> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('model_provider')\n .select(recordColumns)\n .where('tenant_id', '=', tenantId)\n .orderBy('name')\n .execute();\n }\n\n async getProvider(\n input: GetModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('model_provider')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n /**\n * SQLite has no row-level FOR UPDATE; the required write transaction (BEGIN IMMEDIATE)\n * serializes concurrent writers so RMW of secrets stays consistent.\n */\n async getProviderForUpdate(\n input: GetModelProviderInput,\n transaction: Transaction<Database>,\n ): Promise<ModelProviderRecord | undefined> {\n return await transaction\n .selectFrom('model_provider')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n async createProvider(\n input: CreateModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n try {\n return await db\n .insertInto('model_provider')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new ModelProviderNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertProvider(\n input: UpsertModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n return await db\n .insertInto('model_provider')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: jsonbBind(input.manifest),\n updated_at: timestamp,\n }),\n )\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n }\n\n async listModels(tenantId: string, transaction?: Transaction<Database>): Promise<AvailableModel[]> {\n return flattenProviderModels(await this.listProviders(tenantId, transaction));\n }\n}\n","import type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport { ulid } from 'ulid';\nimport type { OAuthClientRecord } from '../../../mcp/auth/types';\nimport type { McpServerManifest } from '../../../schemas/mcpServer';\nimport {\n fromStoredOAuthClientRecord,\n McpServerNameConflictError,\n toStoredOAuthClientRecord,\n type CreateMcpServerInput,\n type GetMcpServerInput,\n type IMcpServerStore,\n type ListMcpServersInput,\n type McpServerRecord,\n type OAuthClient,\n type OAuthServer,\n type UpsertMcpServerInput,\n} from '../../mcpServerStore';\nimport { isUniqueViolation } from '../client';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'mcp_server'>) {\n return [\n 'id' as const,\n 'tenant_id' as const,\n 'name' as const,\n jsonText<McpServerManifest>(eb.ref('manifest')).as('manifest'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nexport class SqliteMcpServerStore implements IMcpServerStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listServers(input: ListMcpServersInput, transaction?: Transaction<Database>): Promise<McpServerRecord[]> {\n if (input.names?.length === 0) {\n return [];\n }\n const db = transaction ?? this.#db;\n let query = db.selectFrom('mcp_server').select(recordColumns).where('tenant_id', '=', input.tenant_id);\n if (input.names !== undefined) {\n query = query.where('name', 'in', [...input.names]);\n }\n return await query.orderBy('name').execute();\n }\n\n async getServer(input: GetMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('mcp_server')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n /**\n * SQLite has no row-level FOR UPDATE; the required write transaction (BEGIN IMMEDIATE)\n * serializes concurrent writers so RMW of header secrets stays consistent.\n */\n async getServerForUpdate(\n input: GetMcpServerInput,\n transaction: Transaction<Database>,\n ): Promise<McpServerRecord | undefined> {\n return await transaction\n .selectFrom('mcp_server')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n async createServer(input: CreateMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n try {\n return await db\n .insertInto('mcp_server')\n .values({\n id: ulid(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n oauth_server: null,\n oauth_client: null,\n created_at: timestamp,\n updated_at: timestamp,\n })\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new McpServerNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertServer(input: UpsertMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n return await db\n .insertInto('mcp_server')\n .values({\n id: ulid(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n oauth_server: null,\n oauth_client: null,\n created_at: timestamp,\n updated_at: timestamp,\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: jsonbBind(input.manifest),\n updated_at: timestamp,\n }),\n )\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n }\n\n async getClient(params: { id: string }, transaction?: Transaction<Database>): Promise<OAuthClientRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('mcp_server')\n .select(eb => [\n jsonText<OAuthServer | null>(eb.ref('oauth_server')).as('oauth_server'),\n jsonText<OAuthClient | null>(eb.ref('oauth_client')).as('oauth_client'),\n ])\n .where('id', '=', params.id)\n .executeTakeFirst();\n if (row?.oauth_server == null || row.oauth_client == null) {\n return undefined;\n }\n return fromStoredOAuthClientRecord({ server: row.oauth_server, client: row.oauth_client });\n }\n\n async saveClient(\n params: { id: string; record: OAuthClientRecord },\n transaction?: Transaction<Database>,\n ): Promise<void> {\n const db = transaction ?? this.#db;\n const stored = toStoredOAuthClientRecord(params.record);\n await db\n .updateTable('mcp_server')\n .set({\n oauth_server: jsonbBind(stored.server),\n oauth_client: jsonbBind(stored.client),\n })\n .where('id', '=', params.id)\n .execute();\n }\n\n async deleteClient(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n const db = transaction ?? this.#db;\n await db\n .updateTable('mcp_server')\n .set({\n oauth_server: null,\n oauth_client: null,\n })\n .where('id', '=', params.id)\n .execute();\n }\n}\n","import { sql, type Kysely } from 'kysely';\nimport type { OAuthPendingAuthorization } from '../../../../mcp/auth/types';\nimport {\n fromStoredOAuthPendingAuthorizationData,\n PENDING_AUTHORIZATION_TTL_MS,\n toStoredOAuthPendingAuthorizationData,\n type OAuthPendingAuthorizationData,\n} from '../../../mcpServerStore';\nimport { isoMsAgo, jsonbBind, jsonText, nowIso } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nexport async function savePendingAuthorization(\n db: Kysely<Database>,\n pending: OAuthPendingAuthorization,\n): Promise<void> {\n const authData = toStoredOAuthPendingAuthorizationData(pending);\n\n await db\n .insertInto('oauth_pending_authorization')\n .values({\n id: pending.state,\n oauth_server_id: pending.id,\n user_id: pending.userRef,\n auth_data: jsonbBind(authData),\n created_at: nowIso(),\n })\n .execute();\n}\n\n/**\n * Single-use claim: DELETE … RETURNING under the TTL filter so only one concurrent\n * callback wins the row.\n */\nexport async function consumePendingAuthorization(\n db: Kysely<Database>,\n params: { state: string },\n): Promise<OAuthPendingAuthorization | undefined> {\n const row = await db\n .deleteFrom('oauth_pending_authorization')\n .where('id', '=', params.state)\n .where('created_at', '>', isoMsAgo(PENDING_AUTHORIZATION_TTL_MS))\n .returning([\n 'id',\n 'oauth_server_id',\n 'user_id',\n jsonText<OAuthPendingAuthorizationData>(sql.ref('auth_data')).as('auth_data'),\n ])\n .executeTakeFirst();\n\n if (row === undefined) {\n return undefined;\n }\n\n return {\n state: row.id,\n id: row.oauth_server_id,\n userRef: row.user_id,\n ...fromStoredOAuthPendingAuthorizationData(row.auth_data),\n };\n}\n\nexport async function deletePendingAuthorizationsForServer(\n db: Kysely<Database>,\n params: { id: string },\n): Promise<void> {\n await db.deleteFrom('oauth_pending_authorization').where('oauth_server_id', '=', params.id).execute();\n}\n","import { sql, type Kysely } from 'kysely';\nimport type { OAuthToken } from '../../../mcpServerStore';\nimport { jsonbBind, jsonText, nowIso } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nexport async function saveToken(\n db: Kysely<Database>,\n params: { id: string; userRef: string; token: OAuthToken },\n): Promise<void> {\n await db\n .insertInto('oauth_token')\n .values({\n oauth_server_id: params.id,\n user_id: params.userRef,\n token: jsonbBind(params.token),\n updated_at: nowIso(),\n })\n .onConflict(oc =>\n oc.columns(['oauth_server_id', 'user_id']).doUpdateSet({\n token: sql`excluded.token`,\n updated_at: sql`excluded.updated_at`,\n }),\n )\n .execute();\n}\n\nexport async function getToken(\n db: Kysely<Database>,\n params: { id: string; userRef: string },\n): Promise<OAuthToken | undefined> {\n const row = await db\n .selectFrom('oauth_token')\n .select(jsonText<OAuthToken>(sql.ref('token')).as('token'))\n .where('oauth_server_id', '=', params.id)\n .where('user_id', '=', params.userRef)\n .executeTakeFirst();\n\n return row === undefined ? undefined : row.token;\n}\n\nexport async function getTokens(\n db: Kysely<Database>,\n params: { ids: string[]; userRef: string },\n): Promise<Map<string, OAuthToken>> {\n if (params.ids.length === 0) {\n return new Map();\n }\n const rows = await db\n .selectFrom('oauth_token')\n .select(['oauth_server_id', jsonText<OAuthToken>(sql.ref('token')).as('token')])\n .where('oauth_server_id', 'in', params.ids)\n .where('user_id', '=', params.userRef)\n .execute();\n\n return new Map(rows.map(row => [row.oauth_server_id, row.token]));\n}\n\nexport async function deleteToken(db: Kysely<Database>, params: { id: string; userRef: string }): Promise<void> {\n await db\n .deleteFrom('oauth_token')\n .where('oauth_server_id', '=', params.id)\n .where('user_id', '=', params.userRef)\n .execute();\n}\n\nexport async function deleteTokensForServer(db: Kysely<Database>, params: { id: string }): Promise<void> {\n await db.deleteFrom('oauth_token').where('oauth_server_id', '=', params.id).execute();\n}\n","import type { Kysely, Transaction } from 'kysely';\nimport type { IOAuthTokenStore, OAuthPendingAuthorization, OAuthToken, OAuthTokenKey } from '../../../mcp/auth/types';\nimport { fromStoredOAuthToken, toStoredOAuthToken } from '../../mcpServerStore';\nimport type { Database } from '../types';\nimport {\n consumePendingAuthorization,\n deletePendingAuthorizationsForServer,\n savePendingAuthorization,\n} from './queries/pendingAuthorization';\nimport { deleteToken, deleteTokensForServer, getToken, getTokens, saveToken } from './queries/token';\n\nexport class SqliteOAuthTokenStore implements IOAuthTokenStore<Transaction<Database>> {\n constructor(private readonly db: Kysely<Database>) {}\n\n savePendingAuthorization(pending: OAuthPendingAuthorization, transaction?: Transaction<Database>): Promise<void> {\n return savePendingAuthorization(transaction ?? this.db, pending);\n }\n\n consumePendingAuthorization(\n params: { state: string },\n transaction?: Transaction<Database>,\n ): Promise<OAuthPendingAuthorization | undefined> {\n return consumePendingAuthorization(transaction ?? this.db, params);\n }\n\n saveToken(params: OAuthTokenKey & { token: OAuthToken }, transaction?: Transaction<Database>): Promise<void> {\n return saveToken(transaction ?? this.db, {\n id: params.id,\n userRef: params.userRef,\n token: toStoredOAuthToken(params.token),\n });\n }\n\n async getToken(params: OAuthTokenKey, transaction?: Transaction<Database>): Promise<OAuthToken | undefined> {\n const stored = await getToken(transaction ?? this.db, params);\n return stored === undefined ? undefined : fromStoredOAuthToken(stored);\n }\n\n async getTokens(\n params: { ids: string[]; userRef: string },\n transaction?: Transaction<Database>,\n ): Promise<Map<string, OAuthToken>> {\n const stored = await getTokens(transaction ?? this.db, params);\n return new Map([...stored].map(([id, token]) => [id, fromStoredOAuthToken(token)]));\n }\n\n deleteToken(params: OAuthTokenKey, transaction?: Transaction<Database>): Promise<void> {\n return deleteToken(transaction ?? this.db, params);\n }\n\n deleteTokensForServer(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n return deleteTokensForServer(transaction ?? this.db, params);\n }\n\n deletePendingAuthorizationsForServer(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n return deletePendingAuthorizationsForServer(transaction ?? this.db, params);\n }\n}\n","import type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport type { SkillManifest } from '../../../schemas/skill';\nimport {\n SkillNameConflictError,\n type CreateSkillInput,\n type GetSkillInput,\n type ISkillStore,\n type ListSkillsInput,\n type SkillRecord,\n type UpsertSkillInput,\n} from '../../skillStore';\nimport { isUniqueViolation } from '../client';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'skill'>) {\n return [\n 'tenant_id' as const,\n 'name' as const,\n jsonText<SkillManifest>(eb.ref('manifest')).as('manifest'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nexport class SqliteSkillStore implements ISkillStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listSkills(input: ListSkillsInput, transaction?: Transaction<Database>): Promise<SkillRecord[]> {\n if (input.names?.length === 0) {\n return [];\n }\n const db = transaction ?? this.#db;\n let query = db.selectFrom('skill').select(recordColumns).where('tenant_id', '=', input.tenant_id);\n if (input.names !== undefined) {\n query = query.where('name', 'in', [...input.names]);\n }\n return await query.orderBy('name').execute();\n }\n\n async getSkill(input: GetSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('skill')\n .select(recordColumns)\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n }\n\n async createSkill(input: CreateSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n try {\n return await db\n .insertInto('skill')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new SkillNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertSkill(input: UpsertSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n return await db\n .insertInto('skill')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: jsonbBind(input.manifest),\n updated_at: timestamp,\n }),\n )\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n }\n}\n","import type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport type { SandboxBuildMetadata, SandboxProviderManifest } from '../../../schemas/sandboxProvider';\nimport {\n type ISandboxProviderStore,\n type SandboxProviderRecord,\n type UpdateSandboxStatusInput,\n type UpsertSandboxProviderInput,\n} from '../../sandboxProviderStore';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest/build_metadata as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'sandbox_provider'>) {\n return [\n 'tenant_id' as const,\n jsonText<SandboxProviderManifest>(eb.ref('manifest')).as('manifest'),\n 'status' as const,\n 'status_reason' as const,\n jsonText<SandboxBuildMetadata>(eb.ref('build_metadata')).as('build_metadata'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nexport class SqliteSandboxProviderStore implements ISandboxProviderStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async getSandboxProvider(\n tenantId: string,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .selectFrom('sandbox_provider')\n .select(recordColumns)\n .where('tenant_id', '=', tenantId)\n .executeTakeFirst();\n }\n\n /**\n * SQLite has no row-level FOR UPDATE; the required write transaction (BEGIN IMMEDIATE)\n * serializes concurrent writers so RMW of secrets stays consistent.\n */\n async getSandboxProviderForUpdate(\n tenantId: string,\n transaction: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n return await transaction\n .selectFrom('sandbox_provider')\n .select(recordColumns)\n .where('tenant_id', '=', tenantId)\n .executeTakeFirst();\n }\n\n async upsertSandboxProvider(\n input: UpsertSandboxProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n return await db\n .insertInto('sandbox_provider')\n .values({\n tenant_id: input.tenant_id,\n manifest: jsonbBind(input.manifest),\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? jsonbBind(input.build_metadata) : null,\n created_at: timestamp,\n updated_at: timestamp,\n })\n .onConflict(oc =>\n oc.columns(['tenant_id']).doUpdateSet({\n manifest: jsonbBind(input.manifest),\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? jsonbBind(input.build_metadata) : null,\n updated_at: timestamp,\n }),\n )\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n }\n\n async updateSandboxStatus(\n input: UpdateSandboxStatusInput,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n return await db\n .updateTable('sandbox_provider')\n .set({\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? jsonbBind(input.build_metadata) : null,\n updated_at: nowIso(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .returning(recordColumns)\n .executeTakeFirst();\n }\n}\n","import type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport type { ExpressionBuilder, Kysely, Transaction } from 'kysely';\nimport { ulid } from 'ulid';\nimport {\n AgentNameConflictError,\n parseStoredAgentSpec,\n type AgentRecord,\n type CreateAgentInput,\n type DeleteAgentInput,\n type GetAgentInput,\n type IAgentStore,\n type UpdateAgentInput,\n} from '../../agentStore';\nimport { isUniqueViolation } from '../client';\nimport { jsonbBind, jsonText, nowIso } from '../sqlExpressions';\nimport type { Database } from '../types';\n\n/** Column list projecting the JSONB manifest as parsed JSON (see JSON_RESULT_COLUMNS). */\nfunction recordColumns(eb: ExpressionBuilder<Database, 'agent'>) {\n return [\n 'id' as const,\n 'tenant_id' as const,\n 'name' as const,\n jsonText<AgentSpec>(eb.ref('manifest')).as('manifest'),\n 'created_at' as const,\n 'updated_at' as const,\n ];\n}\n\nfunction toRecord(row: {\n id: string;\n tenant_id: string;\n name: AgentRecord['name'];\n manifest: AgentSpec;\n created_at: string;\n updated_at: string;\n}): AgentRecord {\n return { ...row, manifest: parseStoredAgentSpec(row.manifest) };\n}\n\nexport class SqliteAgentStore implements IAgentStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listAgents(tenantId: string, transaction?: Transaction<Database>): Promise<AgentRecord[]> {\n const db = transaction ?? this.#db;\n const rows = await db\n .selectFrom('agent')\n .select(recordColumns)\n .where('tenant_id', '=', tenantId)\n .orderBy('name')\n .execute();\n return rows.map(toRecord);\n }\n\n async getAgent(input: GetAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord | undefined> {\n const db = transaction ?? this.#db;\n let query = db.selectFrom('agent').select(recordColumns).where('tenant_id', '=', input.tenant_id);\n if ('id' in input) {\n query = query.where('id', '=', input.id);\n } else {\n query = query.where('name', '=', input.name);\n }\n const row = await query.executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async createAgent(input: CreateAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord> {\n const db = transaction ?? this.#db;\n const timestamp = nowIso();\n try {\n const row = await db\n .insertInto('agent')\n .values({\n id: ulid().toLowerCase(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: jsonbBind(input.manifest),\n created_at: timestamp,\n updated_at: timestamp,\n })\n .returning(recordColumns)\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new AgentNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async updateAgent(input: UpdateAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .updateTable('agent')\n .set({\n manifest: jsonbBind(input.manifest),\n updated_at: nowIso(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .where('id', '=', input.id)\n .returning(recordColumns)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async deleteAgent(input: DeleteAgentInput, transaction?: Transaction<Database>): Promise<void> {\n const db = transaction ?? this.#db;\n await db.deleteFrom('agent').where('tenant_id', '=', input.tenant_id).where('id', '=', input.id).execute();\n }\n}\n","import { Kysely, PostgresDialect } from 'kysely';\nimport pg, { Pool } from 'pg';\n\nimport type { Database } from './types';\n\nconst INT8_OID = 20;\n/**\n * Postgres OID for `bigint[]` / `_int8`. Scalar int8 parser (OID 20) does NOT cover arrays.\n * Widened setter: node-pg's TypeId enum omits array OIDs.\n */\nconst setTypeParserByOid: (oid: number, parser: (value: string) => unknown) => void = pg.types.setTypeParser.bind(\n pg.types,\n);\n\n/**\n * Parse a Postgres array literal of int8 into number[].\n * Safe below Number.MAX_SAFE_INTEGER (2^53) — same contract as the scalar int8 parser.\n * Identity append_ids stay far below that bound.\n */\nfunction parseInt8Array(value: string): number[] {\n if (value === '{}' || value === '') {\n return [];\n }\n // Plain unquoted numeric elements (bigint[] never needs quotes).\n return value\n .slice(1, -1)\n .split(',')\n .map(element => Number(element));\n}\n\nfunction configurePgTypeParsers(): void {\n pg.types.setTypeParser(INT8_OID, Number);\n setTypeParserByOid(1016, parseInt8Array);\n}\n\nexport function createDb(options: {\n connectionString: string;\n poolMax: number;\n /** Postgres `statement_timeout` in ms. Applied to every pooled connection. */\n statementTimeoutMs: number;\n /** Postgres `idle_in_transaction_session_timeout` in ms. Applied to every pooled connection. */\n idleInTransactionSessionTimeoutMs: number;\n}): Kysely<Database> {\n const { connectionString, poolMax, statementTimeoutMs, idleInTransactionSessionTimeoutMs } = options;\n configurePgTypeParsers();\n return new Kysely<Database>({\n dialect: new PostgresDialect({\n pool: new Pool({\n connectionString,\n max: poolMax,\n statement_timeout: statementTimeoutMs,\n idle_in_transaction_session_timeout: idleInTransactionSessionTimeoutMs,\n }),\n }),\n });\n}\n\n/**\n * Match Postgres errors by SQLSTATE without `instanceof DatabaseError`.\n * instanceof breaks silently when two copies of pg-protocol load (version skew / dual CJS+ESM);\n * checking `code` is the conventional node-postgres pattern.\n */\nexport function isPgErrorCode(err: unknown, code: string): boolean {\n if (typeof err !== 'object' || err === null || !('code' in err)) {\n return false;\n }\n return err.code === code;\n}\n\nexport function isUniqueViolation(err: unknown): boolean {\n return isPgErrorCode(err, '23505');\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nimport type { Kysely } from 'kysely';\nimport { FileMigrationProvider, Migrator } from 'kysely/migration';\n\nimport type { Database } from './postgres/types';\n\n/**\n * Runs all pending Postgres migrations.\n *\n * This module lives at `src/db/` (bundled into `dist/main.js`) so the folder is\n * always `…/postgres/migrations` — source or production.\n */\nexport async function migrateToLatest(db: Kysely<Database>): Promise<void> {\n const migrator = new Migrator({\n db,\n provider: new FileMigrationProvider({\n fs,\n path,\n migrationFolder: path.join(import.meta.dirname, 'postgres', 'migrations'),\n }),\n });\n\n const { error, results } = await migrator.migrateToLatest();\n\n results?.forEach(it => {\n if (it.status === 'Success') {\n console.log(`migration \"${it.migrationName}\" was executed successfully`);\n } else if (it.status === 'Error') {\n console.error(`failed to execute migration \"${it.migrationName}\"`);\n }\n });\n\n if (error) {\n if (error instanceof Error) {\n throw error;\n }\n throw new Error('failed to migrate', { cause: error });\n }\n}\n","/**\n * Primary Redis connection, owned by the server: created and connected at\n * boot, closed last during shutdown. Injected into the request-reply\n * transport (which duplicates it only for its subscriber).\n */\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport { createClient, type RedisClientType } from 'redis';\nimport type { Logger } from 'winston';\n\nexport async function connectRedis(input: { url: string; logger: Logger }): Promise<RedisClientType> {\n const client: RedisClientType = createClient({ url: input.url });\n // Without an 'error' listener node-redis crashes the process on emit;\n // reconnects are automatic, so log and keep running.\n client.on('error', (error: Error) => {\n input.logger.error('[Redis] Client error', extractErrorLogFields(error));\n });\n await client.connect();\n return client;\n}\n","/**\n * Shared Kysely SQL expression helpers for Postgres stores.\n */\nimport { sql, type Expression, type RawBuilder } from 'kysely';\n\n/** Bind a JS value as jsonb (stringified + cast). Required for arrays and for `||` / jsonb_set operands. */\nexport function json<T>(value: T): RawBuilder<T> {\n return sql`${JSON.stringify(value)}::jsonb`;\n}\n\n/**\n * `jsonb_set(target, path, new_value)`.\n * `path` may be a text[] expression (`sql\\`ARRAY['threads', ${id}]\\``) or a literal path\n * expression (`sql\\`'{sandbox_info}'\\`` / `sql\\`'{completion}'\\``).\n */\nexport function jsonbSet<T = unknown>(\n target: Expression<unknown>,\n path: Expression<unknown>,\n newValue: Expression<unknown>,\n): RawBuilder<T> {\n return sql<T>`jsonb_set(${target}, ${path}, ${newValue})`;\n}\n\n/** `now()` timestamptz expression. */\nexport function now(): RawBuilder<Date> {\n return sql<Date>`now()`;\n}\n\nexport function nowMinusMs(ms: number): RawBuilder<Date> {\n return sql<Date>`now() - ${ms}::double precision * interval '1 millisecond'`;\n}\n","/**\n * Session-store-only helpers for Postgres (VALUES / unnest join shapes).\n * Shared JSON/time helpers live in `../sqlExpressions`.\n */\nimport { sql, type AliasedRawBuilder, type Expression } from 'kysely';\n\n/**\n * Typed `(VALUES ...) AS alias(col1, col2, ...)` for use in `.selectFrom(...)`.\n * VALUES params are unknown→text unless cast — pass `sql\\`${n}::bigint\\`` (etc.) for non-text cols.\n * @see https://kysely.dev/docs/recipes/extending-kysely\n */\nexport function values<R extends object, A extends string>(records: R[], alias: A): AliasedRawBuilder<R, A> {\n const first = records[0];\n if (first === undefined) {\n throw new Error('values() requires at least one record');\n }\n const keys = Object.keys(first) as (keyof R & string)[];\n\n const valueTuples = sql.join(records.map(r => sql`(${sql.join(keys.map(k => r[k]))})`));\n\n const wrappedAlias = sql.ref(alias);\n const wrappedColumns = sql.join(keys.map(key => sql.ref(key)));\n const aliasSql = sql`${wrappedAlias}(${wrappedColumns})`;\n\n return sql<R>`(values ${valueTuples})`.as<A>(aliasSql);\n}\n\n/**\n * `unnest(ids::text[]) WITH ORDINALITY AS alias(turn_id, pos)` for `.selectFrom(...)`.\n * Used by listSessionEvents mode-2 (ancestor chain order).\n */\nexport function unnestWithOrdinality<A extends string>(\n ids: string[],\n alias: A,\n): AliasedRawBuilder<{ turn_id: string; pos: number }, A> {\n const wrappedAlias = sql.ref(alias);\n const aliasSql = sql`${wrappedAlias}(turn_id, pos)`;\n return sql<{ turn_id: string; pos: number }>`unnest(${ids}::text[]) WITH ORDINALITY`.as<A>(aliasSql);\n}\n\n/**\n * `LATERAL unnest(array_expr) WITH ORDINALITY AS alias(append_id, pos)` for join use.\n * Kysely 0.29 has no leftJoinLateral builder — this expression is the join RHS.\n * Used by getTurn context assembly so empty-context threads still emit a row.\n */\nexport function lateralUnnestBigintArrayWithOrdinality<A extends string>(\n arrayExpr: Expression<number[] | null>,\n alias: A,\n): AliasedRawBuilder<{ append_id: number; pos: number }, A> {\n const wrappedAlias = sql.ref(alias);\n const aliasSql = sql`${wrappedAlias}(append_id, pos)`;\n return sql<{ append_id: number; pos: number }>`LATERAL unnest(${arrayExpr}) WITH ORDINALITY`.as<A>(aliasSql);\n}\n","import type { TurnRecord, TurnSnapshot } from '@truefoundry/trueforge-core/agent-session/models/TurnRecord';\nimport {\n type TerminalTurnState,\n type TurnInputItem,\n type TurnState,\n} from '@truefoundry/trueforge-core/agent-session/schemas/turn';\nimport { assertCreateTurnThreadDelta } from '@truefoundry/trueforge-core/agent-session/store/assertCreateTurnThreadDelta';\nimport type {\n FreezeAndGetTurnInput,\n TurnRecordWithoutSnapshot,\n UpdateTurnStateInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n PreviousTurnRunningError,\n SessionNotFoundError,\n SessionStoreConflictError,\n SessionStoreInvariantError,\n SessionStoreNotFoundError,\n TurnAlreadyExistsError,\n TurnNotFoundError,\n TurnNotRunningError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport type { CapabilityState, JsonValue } from '@truefoundry/trueforge-core/core/capabilities/AgentCapability';\nimport type { AgentInfo, AgentParent, MCPServerInitInfo } from '@truefoundry/trueforge-core/core/events/schema';\nimport type { AgentThreadSnapshot, ContextMessage } from '@truefoundry/trueforge-core/core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport { getEmptyCurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport type { SandboxInfo } from '@truefoundry/trueforge-core/core/sandbox/Sandbox';\nimport { sql, type Kysely, type QueryCreator, type RawBuilder, type Transaction } from 'kysely';\nimport { isUniqueViolation } from '../../client';\nimport { json } from '../../sqlExpressions';\nimport type { Database, TurnCheckpoint, TurnThreadCheckpoint } from '../../types';\nimport { lateralUnnestBigintArrayWithOrdinality } from '../sqlExpressions';\n\ntype TurnCustom = Record<string, never>;\n\nfunction isEmptyCustomRecord(value: Record<string, unknown>): value is TurnCustom {\n return Object.keys(value).length === 0;\n}\n\nfunction parseTurnCustom(value: Record<string, unknown> | null): TurnCustom | null {\n if (value === null) {\n return null;\n }\n if (!isEmptyCustomRecord(value)) {\n throw new SessionStoreInvariantError('non-empty turn custom is not supported');\n }\n return value;\n}\n\n/** New thread metadata; mutable per-turn data arrives through dedicated fields. */\nexport interface NewThreadRegistration {\n thread_id: string;\n parent: AgentParent | null;\n agent_info: AgentInfo | null;\n}\n\nexport interface TurnKeys {\n session_id: string;\n turn_id: string;\n}\n\nexport interface NewContextAppend {\n thread_id: string;\n context: ContextMessage[];\n current_context_usage: CurrentContextUsage | null;\n}\n\nexport interface CreateTurnTurnFields {\n turn_id: string;\n first_turn_id: string;\n previous_turn_id: string | null;\n ancestor_ids: string[];\n input: TurnInputItem[];\n state: TurnState;\n custom: Record<string, unknown> | null;\n}\n\nexport interface CreateTurnInput {\n session_id: string;\n turn: CreateTurnTurnFields;\n new_threads: NewThreadRegistration[];\n new_context_appends: NewContextAppend[];\n capability_states: {\n thread_id: string;\n capability_state: CapabilityState | null;\n }[];\n last_activity_timestamp_ms: number;\n update_session_title_if_not_exist: string | null;\n mcp_servers: Record<string, MCPServerInitInfo> | null;\n sandbox_info: SandboxInfo | null;\n}\n\nexport interface GetTurnInput {\n session_id: string;\n turn_id: string;\n}\n\nexport interface ListTurnsInput {\n session_id: string;\n limit: number;\n offset: number;\n}\n\nexport interface ListTurnsResult {\n turns: TurnRecordWithoutSnapshot<TurnCustom>[];\n next_offset: number | null;\n}\n\ntype DbOrTrx = Kysely<Database> | Transaction<Database>;\ntype TurnFenceDb = DbOrTrx | QueryCreator<Database>;\n\nfunction terminalTurnState(state: TurnState, turn_id: string): TerminalTurnState {\n switch (state.status) {\n case 'running':\n throw new SessionStoreInvariantError(`expected terminal state for turn ${turn_id}, got running`);\n case 'done':\n case 'cancelled':\n case 'error':\n return state;\n }\n}\n\n/**\n * Locking CTE body for single-statement turn-scoped writes: fence + write in one\n * network call. Under READ COMMITTED, FOR SHARE re-checks the predicate after a\n * lock wait, so a committed freeze empties the fence and the write inserts 0 rows;\n * error classification happens on that rare 0-row path.\n * Multi-statement turn-scoped writes use {@link assertTurnRunning} instead.\n */\nexport function turnRunningFence(db: TurnFenceDb, keys: TurnKeys) {\n return db\n .selectFrom('turn')\n .select(sql`1`.as('one'))\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql`state->>'status'`, '=', 'running')\n .forShare();\n}\n\n/** Classify a 0-row fenced write: missing turn vs frozen/non-running turn. */\nexport async function classifyTurnFenceWriteFailure(db: Kysely<Database>, keys: TurnKeys): Promise<never> {\n const row = await db\n .selectFrom('turn')\n .select('state')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .executeTakeFirst();\n\n if (!row) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(row.state, keys.turn_id));\n}\n\n/**\n * Classify a 0-row fenced turn_thread UPDATE: turn missing/terminal vs thread row missing.\n */\nexport async function classifyTurnThreadWriteFailure(\n db: Kysely<Database>,\n keys: TurnKeys,\n thread_id: string,\n): Promise<never> {\n const row = await db\n .selectFrom('turn')\n .select('state')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .executeTakeFirst();\n\n if (!row) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n if (row.state.status !== 'running') {\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(row.state, keys.turn_id));\n }\n throw new SessionStoreInvariantError(`thread ${thread_id} not found in turn ${keys.turn_id}`);\n}\n\nexport async function assertTurnRunning(db: DbOrTrx, keys: TurnKeys): Promise<void> {\n // SELECT ... FOR SHARE serializes against freezeAndGetTurn's state UPDATE.\n const row = await db\n .selectFrom('turn')\n .select('state')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .forShare()\n .executeTakeFirst();\n\n if (!row) {\n throw new TurnNotFoundError(keys.turn_id);\n }\n if (row.state.status !== 'running') {\n throw new TurnNotRunningError(keys.turn_id, terminalTurnState(row.state, keys.turn_id));\n }\n}\n\ninterface CapabilityAggRow {\n thread_id: string;\n capability_state: Record<string, JsonValue> | null;\n}\n\nasync function assembleTurnRecord(\n db: DbOrTrx,\n args: { session_id: string; turn_id: string },\n): Promise<TurnRecord<TurnCustom> | undefined> {\n const turn = await db\n .selectFrom('turn')\n .selectAll()\n .where('session_id', '=', args.session_id)\n .where('turn_id', '=', args.turn_id)\n .executeTakeFirst();\n\n if (!turn) {\n return undefined;\n }\n\n // LEFT JOIN LATERAL unnest so empty-context threads still appear; LEFT JOIN log\n // because a null lateral append_id (empty array) must not drop the turn_thread row.\n const contextRows = await db\n .selectFrom('turn_thread as tt')\n .leftJoin(lateralUnnestBigintArrayWithOrdinality(sql<number[]>`tt.context_ids`, 'c'), join => join.onTrue())\n .leftJoin('thread_context_log as l', join =>\n join\n .on('l.session_id', '=', args.session_id)\n .onRef('l.thread_id', '=', 'tt.thread_id')\n .onRef('l.append_id', '=', 'c.append_id'),\n )\n .select(['tt.thread_id', 'tt.checkpoint', 'tt.agent_info', 'tt.current_context_usage', 'l.body', 'c.pos'])\n .where('tt.session_id', '=', args.session_id)\n .where('tt.turn_id', '=', args.turn_id)\n .orderBy('tt.thread_id')\n .orderBy('c.pos')\n .execute();\n\n const capabilityRows: CapabilityAggRow[] = await db\n .selectFrom('thread_capability_state')\n .select(['thread_id', sql<Record<string, JsonValue> | null>`jsonb_object_agg(key, state)`.as('capability_state')])\n .where('session_id', '=', args.session_id)\n .where('turn_id', '=', args.turn_id)\n .groupBy('thread_id')\n .execute();\n\n const capabilityByThread = new Map<string, Record<string, JsonValue>>();\n for (const row of capabilityRows) {\n if (row.capability_state !== null) {\n capabilityByThread.set(row.thread_id, row.capability_state);\n }\n }\n\n const threads: Record<string, AgentThreadSnapshot> = {};\n const orderedBodies = new Map<string, ContextMessage[]>();\n const threadMeta = new Map<\n string,\n {\n checkpoint: TurnThreadCheckpoint;\n agent_info: AgentInfo | null;\n current_context_usage: CurrentContextUsage;\n }\n >();\n\n for (const row of contextRows) {\n if (!threadMeta.has(row.thread_id)) {\n threadMeta.set(row.thread_id, {\n checkpoint: row.checkpoint,\n agent_info: row.agent_info,\n current_context_usage: row.current_context_usage,\n });\n orderedBodies.set(row.thread_id, []);\n }\n if (row.body !== null) {\n const bodies = orderedBodies.get(row.thread_id);\n if (bodies !== undefined) {\n bodies.push(row.body);\n }\n }\n }\n\n for (const [threadId, meta] of threadMeta) {\n const context = orderedBodies.get(threadId) ?? [];\n const capability_state = capabilityByThread.get(threadId) ?? null;\n\n const snap: AgentThreadSnapshot = {\n thread_id: threadId,\n context,\n current_context_usage: meta.current_context_usage,\n parent: meta.checkpoint.parent,\n agent_info: meta.agent_info,\n completion: meta.checkpoint.completion,\n capability_state,\n };\n threads[threadId] = snap;\n }\n\n const checkpoint: TurnCheckpoint = turn.checkpoint;\n const snapshot: TurnSnapshot = {\n threads,\n mcp_servers: checkpoint.mcp_servers,\n sandbox_info: checkpoint.sandbox_info,\n };\n\n return {\n turn_id: turn.turn_id,\n session_id: turn.session_id,\n first_turn_id: turn.first_turn_id,\n ancestor_ids: turn.ancestor_ids,\n previous_turn_id: turn.previous_turn_id,\n state: turn.state,\n input: turn.input,\n snapshot,\n created_at: turn.created_at,\n updated_at: turn.updated_at,\n custom: parseTurnCustom(turn.custom),\n };\n}\n\ninterface TurnInsertValues {\n session_id: string;\n turn_id: string;\n first_turn_id: string;\n previous_turn_id: string | null;\n ancestor_ids: string[];\n input: RawBuilder<CreateTurnInput['turn']['input']>;\n state: CreateTurnInput['turn']['state'];\n checkpoint: TurnCheckpoint;\n custom: RawBuilder<Record<string, unknown>> | null;\n created_at: Date;\n updated_at: Date;\n}\n\ninterface LogInsertRow {\n session_id: string;\n thread_id: string;\n turn_id: string;\n body: RawBuilder<ContextMessage>;\n created_at: Date;\n}\n\ninterface TurnThreadInsertRow {\n session_id: string;\n turn_id: string;\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: RawBuilder<AgentInfo> | null;\n current_context_usage: CurrentContextUsage;\n context_ids: number[];\n updated_at: Date;\n}\n\ninterface CapabilityStateInsertRow {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: RawBuilder<JsonValue>;\n updated_at: Date;\n}\n\n/**\n * createTurn — READ COMMITTED tx. Fork and linear are THE SAME pointer-copy path:\n * child turn_thread rows copy the parent's arrays and concat new append ids.\n * Tip bump uses SELECT ... FOR UPDATE then UPDATE (safe on PG17; the one-statement\n * CTE tip-bump is PROVEN UNSAFE under EvalPlanQual — a blocked second writer gets\n * the stale pre-commit tip because the CTE keeps the statement snapshot).\n */\nexport async function createTurn(db: Kysely<Database>, input: CreateTurnInput): Promise<void> {\n try {\n await db.transaction().execute(async trx => {\n // step1: lock session tip, bump. Two statements on purpose — see PROVEN-UNSAFE-CTE note above.\n const locked = await trx\n .selectFrom('session')\n .select(['last_turn_id'])\n .where('session_id', '=', input.session_id)\n .forUpdate()\n .executeTakeFirst();\n\n if (!locked) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n await trx\n .updateTable('session')\n .set({\n last_turn_id: input.turn.turn_id,\n updated_at: sql`now()`,\n last_activity_timestamp_ms: input.last_activity_timestamp_ms,\n ...(input.update_session_title_if_not_exist !== null\n ? {\n title: sql`COALESCE(title, ${input.update_session_title_if_not_exist})`,\n }\n : {}),\n })\n .where('session_id', '=', input.session_id)\n .execute();\n\n const prevTurnId = input.turn.previous_turn_id;\n\n // step2: previous turn state + its turn_thread rows (pointer-copy source).\n let prevCheckpoint: TurnCheckpoint | null = null;\n const prevThreadRows: {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: AgentInfo | null;\n current_context_usage: CurrentContextUsage;\n context_ids: number[];\n }[] = [];\n\n if (prevTurnId != null) {\n // One round-trip: previous turn metadata + its turn_thread rows.\n // Unknown previous_turn_id is allowed (relaxed): treat as no inheritance.\n const prevRows = await trx\n .selectFrom('turn as t')\n .leftJoin('turn_thread as tt', join =>\n join.onRef('tt.session_id', '=', 't.session_id').onRef('tt.turn_id', '=', 't.turn_id'),\n )\n .select([\n 't.checkpoint as turn_checkpoint',\n 't.state as turn_state',\n 'tt.thread_id',\n 'tt.checkpoint as thread_checkpoint',\n 'tt.agent_info',\n 'tt.current_context_usage',\n 'tt.context_ids',\n ])\n .where('t.session_id', '=', input.session_id)\n .where('t.turn_id', '=', prevTurnId)\n .execute();\n\n const first = prevRows[0];\n if (first !== undefined) {\n if (first.turn_state.status === 'running') {\n throw new PreviousTurnRunningError(prevTurnId);\n }\n prevCheckpoint = first.turn_checkpoint;\n\n for (const row of prevRows) {\n if (row.thread_id === null) {\n continue;\n }\n if (row.thread_checkpoint === null || row.current_context_usage === null || row.context_ids === null) {\n throw new SessionStoreInvariantError(`previous turn_thread row for ${row.thread_id} is incomplete`);\n }\n prevThreadRows.push({\n thread_id: row.thread_id,\n checkpoint: row.thread_checkpoint,\n agent_info: row.agent_info,\n current_context_usage: row.current_context_usage,\n context_ids: row.context_ids,\n });\n }\n }\n }\n\n assertCreateTurnThreadDelta({\n previousThreadIds: new Set(prevThreadRows.map(r => r.thread_id)),\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n const checkpoint: TurnCheckpoint = {\n mcp_servers: input.mcp_servers ?? prevCheckpoint?.mcp_servers ?? null,\n sandbox_info: input.sandbox_info ?? prevCheckpoint?.sandbox_info ?? null,\n };\n\n const now = new Date();\n\n const turnCustom = input.turn.custom ?? null;\n\n // step3: turn row\n const turnValues: TurnInsertValues = {\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n first_turn_id: input.turn.first_turn_id,\n previous_turn_id: input.turn.previous_turn_id ?? null,\n ancestor_ids: input.turn.ancestor_ids,\n input: json(input.turn.input),\n state: input.turn.state,\n checkpoint,\n custom: turnCustom !== null ? json(turnCustom) : null,\n created_at: now,\n updated_at: now,\n };\n await trx.insertInto('turn').values(turnValues).execute();\n\n // step4: new_context_appends bodies; RETURNING feeds the arrays app-side.\n const logRows: LogInsertRow[] = [];\n for (const append of input.new_context_appends) {\n for (const body of append.context) {\n logRows.push({\n session_id: input.session_id,\n thread_id: append.thread_id,\n turn_id: input.turn.turn_id,\n body: json(body),\n created_at: now,\n });\n }\n }\n\n const newIdsByThread = new Map<string, number[]>();\n if (logRows.length > 0) {\n const inserted = await trx\n .insertInto('thread_context_log')\n .values(logRows)\n .returning(['thread_id', 'append_id'])\n .execute();\n for (const row of inserted) {\n const list = newIdsByThread.get(row.thread_id);\n if (list === undefined) {\n newIdsByThread.set(row.thread_id, [row.append_id]);\n } else {\n list.push(row.append_id);\n }\n }\n }\n\n const appendUsageByThread = new Map<string, CurrentContextUsage>();\n for (const append of input.new_context_appends) {\n if (append.current_context_usage !== null) {\n appendUsageByThread.set(append.thread_id, append.current_context_usage);\n }\n }\n\n // step5: child turn_thread rows — carried = parent || new ids; new = fresh row.\n const turnThreadRows: TurnThreadInsertRow[] = [];\n\n for (const parent of prevThreadRows) {\n const newIds = newIdsByThread.get(parent.thread_id) ?? [];\n const usage = appendUsageByThread.get(parent.thread_id) ?? parent.current_context_usage;\n turnThreadRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: parent.thread_id,\n checkpoint: parent.checkpoint,\n agent_info: parent.agent_info !== null ? json(parent.agent_info) : null,\n current_context_usage: usage,\n context_ids: parent.context_ids.concat(newIds),\n updated_at: now,\n });\n }\n\n for (const nt of input.new_threads) {\n const newIds = newIdsByThread.get(nt.thread_id) ?? [];\n const usage = appendUsageByThread.get(nt.thread_id) ?? getEmptyCurrentContextUsage();\n const threadCheckpoint: TurnThreadCheckpoint = {\n parent: nt.parent,\n completion: null,\n };\n turnThreadRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: nt.thread_id,\n checkpoint: threadCheckpoint,\n agent_info: nt.agent_info !== null ? json(nt.agent_info) : null,\n current_context_usage: usage,\n context_ids: newIds,\n updated_at: now,\n });\n }\n\n if (turnThreadRows.length > 0) {\n await trx.insertInto('turn_thread').values(turnThreadRows).execute();\n }\n\n // Complete per-turn capability maps (thread coverage asserted above).\n const capabilityStateRows: CapabilityStateInsertRow[] = [];\n for (const capability of input.capability_states) {\n if (capability.capability_state === null) {\n continue;\n }\n for (const [key, state] of Object.entries(capability.capability_state)) {\n capabilityStateRows.push({\n session_id: input.session_id,\n turn_id: input.turn.turn_id,\n thread_id: capability.thread_id,\n key,\n state: json(state),\n updated_at: now,\n });\n }\n }\n\n if (capabilityStateRows.length > 0) {\n await trx.insertInto('thread_capability_state').values(capabilityStateRows).execute();\n }\n });\n } catch (err) {\n if (err instanceof SessionStoreNotFoundError || err instanceof SessionStoreConflictError) {\n throw err;\n }\n if (isUniqueViolation(err)) {\n throw new TurnAlreadyExistsError(input.turn.turn_id, { cause: err });\n }\n throw err;\n }\n}\n\n/**\n * freezeAndGetTurn — cancel if still running (fencing future writes), then return the record.\n * Terminal turns are returned unchanged (freeze is a plain read).\n */\nexport async function freezeAndGetTurn(db: Kysely<Database>, input: FreezeAndGetTurnInput): Promise<TurnRecord> {\n return await db.transaction().execute(async trx => {\n const cancelledState: TerminalTurnState = {\n status: 'cancelled',\n reason: input.reason,\n completed_at: new Date().toISOString(),\n };\n\n // UPDATE waits for in-flight turn-scoped writes (FOR SHARE on this row) to\n // commit; assembly below then includes every committed straggler.\n const updateResult = await trx\n .updateTable('turn')\n .set({\n state: cancelledState,\n updated_at: sql`now()`,\n })\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(updateResult.numUpdatedRows) > 0) {\n await trx\n .insertInto('session_event')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: input.turn_done_event.id,\n event: json(input.turn_done_event),\n created_at: new Date(input.turn_done_event.created_at),\n })\n .execute();\n }\n\n const record = await assembleTurnRecord(trx, input);\n if (!record) {\n throw new TurnNotFoundError(input.turn_id);\n }\n return record;\n });\n}\n\n/**\n * getTurn — read-only REPEATABLE READ tx.\n * Concurrent appends after the first SELECT are invisible to later SELECTs in the same tx.\n */\nexport async function getTurn(db: Kysely<Database>, input: GetTurnInput): Promise<TurnRecord<TurnCustom> | undefined> {\n return await db\n .transaction()\n .setIsolationLevel('repeatable read')\n .execute(async trx => {\n return assembleTurnRecord(trx, input);\n });\n}\n\n/**\n * listTurns — ORDER BY created_at, turn_id; LIMIT limit+1 OFFSET offset; numeric-offset tokens.\n * Returns turn rows only (no snapshot assembly); use getTurn for full TurnRecord.\n */\nexport async function listTurns(db: Kysely<Database>, input: ListTurnsInput): Promise<ListTurnsResult> {\n const rows = await db\n .selectFrom('turn')\n .selectAll()\n .where('session_id', '=', input.session_id)\n .orderBy('created_at', 'asc')\n .orderBy('turn_id', 'asc')\n .limit(input.limit + 1)\n .offset(input.offset)\n .execute();\n\n const hasMore = rows.length > input.limit;\n const page = hasMore ? rows.slice(0, input.limit) : rows;\n\n const turns: TurnRecordWithoutSnapshot<TurnCustom>[] = page.map(row => ({\n turn_id: row.turn_id,\n session_id: row.session_id,\n first_turn_id: row.first_turn_id,\n ancestor_ids: row.ancestor_ids,\n previous_turn_id: row.previous_turn_id,\n state: row.state,\n input: row.input,\n created_at: row.created_at,\n updated_at: row.updated_at,\n custom: parseTurnCustom(row.custom),\n }));\n\n return {\n turns,\n next_offset: hasMore ? input.offset + input.limit : null,\n };\n}\n\n/**\n * updateTurnState — conditional on state->>'status'='running'.\n * 0 rows → SELECT by PK → missing NotFound, present Conflict (first terminal write wins).\n */\nexport async function updateTurnState(db: Kysely<Database>, input: UpdateTurnStateInput): Promise<void> {\n await db.transaction().execute(async trx => {\n const result = await trx\n .updateTable('turn')\n .set({\n state: input.state,\n updated_at: sql`now()`,\n })\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n const numUpdated = Number(result.numUpdatedRows);\n if (numUpdated === 0) {\n const existing = await trx\n .selectFrom('turn')\n .select('state')\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .executeTakeFirst();\n\n if (!existing) {\n throw new TurnNotFoundError(input.turn_id);\n }\n throw new TurnNotRunningError(input.turn_id, terminalTurnState(existing.state, input.turn_id));\n }\n\n await trx\n .insertInto('session_event')\n .values({\n session_id: input.session_id,\n turn_id: input.turn_id,\n event_id: input.turn_done_event.id,\n event: json(input.turn_done_event),\n created_at: new Date(input.turn_done_event.created_at),\n })\n .execute();\n });\n}\n","import type { PatchThreadCapabilityStateInput } from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport { sql, type Kysely } from 'kysely';\nimport { json } from '../../sqlExpressions';\nimport type { Database } from '../../types';\nimport { values } from '../sqlExpressions';\nimport { classifyTurnFenceWriteFailure, turnRunningFence } from './turns';\n\n/**\n * patchThreadCapabilityState — single-statement fenced upsert on the PER-TURN PK;\n * does NOT bump turn.updated_at.\n */\nexport async function patchThreadCapabilityState(\n db: Kysely<Database>,\n input: PatchThreadCapabilityStateInput,\n): Promise<void> {\n const keys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const rows = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .insertInto('thread_capability_state')\n .columns(['session_id', 'turn_id', 'thread_id', 'key', 'state', 'updated_at'])\n .expression(eb =>\n eb\n .selectFrom(values([{ one: 1 }], 'src'))\n .select([\n sql<string>`${input.session_id}`.as('session_id'),\n sql<string>`${input.turn_id}`.as('turn_id'),\n sql<string>`${input.thread_id}`.as('thread_id'),\n sql<string>`${input.key}`.as('key'),\n json(input.state).as('state'),\n sql<Date>`now()`.as('updated_at'),\n ])\n .where(wb => wb.exists(wb.selectFrom('turn_fence').select(sql`1`.as('one')))),\n )\n .onConflict(oc =>\n oc.columns(['session_id', 'turn_id', 'thread_id', 'key']).doUpdateSet({\n state: sql`excluded.state`,\n updated_at: sql`now()`,\n }),\n )\n .returning('thread_id')\n .execute();\n\n if (rows.length === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n","import type { PersistedTurnEvent, SessionEventItem } from '@truefoundry/trueforge-core/agent-session/schemas/events';\nimport type { TokenPagination } from '@truefoundry/trueforge-core/agent-session/schemas/pagination';\nimport type {\n AppendToEventsInput,\n ListSessionEventsInput,\n ListTurnEventsInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeOffsetPageToken,\n paginateOffsetRows,\n} from '@truefoundry/trueforge-core/agent-session/store/OffsetPageToken';\nimport {\n decodeSessionEventPageToken,\n paginateSessionEventRows,\n type SessionEventPageCursor,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionEventPageToken';\nimport {\n SessionNotFoundError,\n TurnNotFoundError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport type { Kysely } from 'kysely';\nimport { sql } from 'kysely';\nimport { json } from '../../sqlExpressions';\nimport type { Database } from '../../types';\nimport { unnestWithOrdinality, values } from '../sqlExpressions';\nimport { classifyTurnFenceWriteFailure, turnRunningFence } from './turns';\n\nexport async function appendToEvents(db: Kysely<Database>, input: AppendToEventsInput): Promise<void> {\n if (input.events.length === 0) {\n return;\n }\n\n const keys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const eventRows = input.events.map(event => ({\n event_id: event.id,\n event: json(event),\n // VALUES parameters default to text; cast the event's required timestamp.\n created_at: sql<Date>`${event.created_at}::timestamptz`,\n }));\n\n const inserted = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .insertInto('session_event')\n .columns(['session_id', 'turn_id', 'event_id', 'event', 'created_at'])\n .expression(eb =>\n eb\n .selectFrom(values(eventRows, 'ev'))\n .select([\n sql<string>`${input.session_id}`.as('session_id'),\n sql<string>`${input.turn_id}`.as('turn_id'),\n 'ev.event_id',\n 'ev.event',\n 'ev.created_at',\n ])\n .where(wb => wb.exists(wb.selectFrom('turn_fence').select(sql`1`.as('one')))),\n )\n .returning('event_id')\n .execute();\n\n if (inserted.length === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\n/**\n * listTurnEvents — one statement: drive from turn, left-join a page of events.\n * Missing turn → 0 rows → TurnNotFoundError. Empty log → one null-event sentinel.\n */\nexport async function listTurnEvents(\n db: Kysely<Database>,\n input: ListTurnEventsInput,\n): Promise<{ data: PersistedTurnEvent[]; pagination: TokenPagination }> {\n const offset = decodeOffsetPageToken(input.page_token);\n const limit = input.limit;\n const eventOrder = input.order === 'desc' ? 'desc' : 'asc';\n\n const rows = await db\n .selectFrom('turn as t')\n .leftJoin(\n eb =>\n eb\n .selectFrom('session_event')\n .select(['session_id', 'turn_id', 'event_id', 'event'])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', input.turn_id)\n .orderBy('event_id', eventOrder)\n .limit(limit + 1)\n .offset(offset)\n .as('e'),\n join => join.onRef('e.session_id', '=', 't.session_id').onRef('e.turn_id', '=', 't.turn_id'),\n )\n .select(['t.turn_id', 'e.event'])\n .where('t.session_id', '=', input.session_id)\n .where('t.turn_id', '=', input.turn_id)\n .orderBy('e.event_id', eventOrder)\n .execute();\n\n if (rows.length === 0) {\n throw new TurnNotFoundError(input.turn_id);\n }\n\n const events: PersistedTurnEvent[] = [];\n for (const row of rows) {\n if (row.event !== null) {\n events.push(row.event);\n }\n }\n\n return paginateOffsetRows(events, limit, offset);\n}\n\nexport async function listSessionEvents(\n db: Kysely<Database>,\n input: ListSessionEventsInput,\n): Promise<{ data: SessionEventItem[]; pagination: TokenPagination }> {\n const limit = input.limit;\n\n const session = await db\n .selectFrom('session')\n .select('last_turn_id')\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n if (!session) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n const decodedCursor = input.page_token === undefined ? undefined : decodeSessionEventPageToken(input.page_token);\n const lastTurnId = decodedCursor?.last_turn_id ?? input.last_turn_id ?? session.last_turn_id;\n if (lastTurnId === null) {\n return { data: [], pagination: { limit } };\n }\n const cursor: SessionEventPageCursor = {\n last_turn_id: lastTurnId,\n offset: decodedCursor?.offset ?? 0,\n };\n\n const anchor = await db\n .selectFrom('turn')\n .select(['turn_id', 'ancestor_ids'])\n .where('session_id', '=', input.session_id)\n .where('turn_id', '=', cursor.last_turn_id)\n .executeTakeFirst();\n if (!anchor) {\n throw new TurnNotFoundError(cursor.last_turn_id);\n }\n\n const chainIds = await resolveAncestorChain(db, input.session_id, anchor);\n const rows = await db\n .selectFrom(unnestWithOrdinality(chainIds, 'c'))\n .innerJoin('session_event as e', join =>\n join.on('e.session_id', '=', input.session_id).onRef('e.turn_id', '=', 'c.turn_id'),\n )\n .select(['e.turn_id as turn_id', 'e.event as event'])\n .orderBy('c.pos', 'desc')\n .orderBy('e.event_id', 'desc')\n .limit(limit + 1)\n .offset(cursor.offset)\n .execute();\n\n return paginateSessionEventRows(rows, limit, cursor);\n}\n\n/** Anchor turn fields needed for chain resolution. */\nexport interface AnchorTurn {\n turn_id: string;\n ancestor_ids: string[];\n}\n\n/**\n * Full chain (oldest first, anchor last). `ancestor_ids` may be only the\n * previous N ancestors, so spill through the oldest ancestor's own window\n * until a root or gap. A missing turn or repeated id ends the walk.\n */\nexport async function resolveAncestorChain(\n db: Kysely<Database>,\n sessionId: string,\n anchor: AnchorTurn,\n): Promise<string[]> {\n const chain = [...anchor.ancestor_ids, anchor.turn_id];\n const seen = new Set(chain);\n let oldestId = chain[0];\n while (oldestId && oldestId !== anchor.turn_id) {\n const oldest = await db\n .selectFrom('turn')\n .select(['ancestor_ids'])\n .where('session_id', '=', sessionId)\n .where('turn_id', '=', oldestId)\n .executeTakeFirst();\n if (!oldest) {\n break;\n }\n const older = oldest.ancestor_ids.filter(id => !seen.has(id));\n if (older.length === 0) {\n break;\n }\n chain.unshift(...older);\n for (const id of older) {\n seen.add(id);\n }\n oldestId = older[0];\n }\n return chain;\n}\n","import type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport type { SessionRecord } from '@truefoundry/trueforge-core/agent-session/models/SessionRecord';\nimport type {\n CreateSessionInput,\n DeleteSessionInput,\n GetSessionInput,\n ListSessionsInput,\n UpdateSessionInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeSessionListPageToken,\n paginateSessionListRows,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionListPageToken';\nimport {\n SessionAlreadyExistsError,\n SessionNotFoundError,\n SessionStoreInvariantError,\n} from '@truefoundry/trueforge-core/agent-session/store/SessionStoreErrors';\nimport { sql, type Kysely } from 'kysely';\nimport { sessionAgentFromColumns, sessionAgentToColumns } from '../../../sessionAgentColumns';\nimport { json } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nfunction isPgUniqueViolation(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) {\n return false;\n }\n if (!('code' in error)) {\n return false;\n }\n return error.code === '23505';\n}\n\ntype SessionCustom = Record<string, never>;\ntype ProtoSessionRecord = SessionRecord<SessionCustom>;\n\nfunction isEmptyCustomRecord(value: Record<string, unknown>): value is SessionCustom {\n return Object.keys(value).length === 0;\n}\n\nfunction parseSessionCustom(value: Record<string, unknown> | null): SessionCustom | null {\n if (value === null) {\n return null;\n }\n if (!isEmptyCustomRecord(value)) {\n throw new SessionStoreInvariantError('non-empty session custom is not supported');\n }\n return value;\n}\n\nfunction mapRowToSessionRecord(row: {\n tenant_id: string;\n session_id: string;\n created_by: string;\n agent_id: string | null;\n agent_name: string | null;\n agent_spec: AgentSpec | null;\n title: string | null;\n last_turn_id: string | null;\n custom: Record<string, unknown> | null;\n created_at: Date;\n updated_at: Date;\n last_activity_timestamp_ms: number;\n}): ProtoSessionRecord {\n return {\n tenant_id: row.tenant_id,\n session_id: row.session_id,\n created_by: row.created_by,\n agent: sessionAgentFromColumns({\n session_id: row.session_id,\n agent_id: row.agent_id,\n agent_name: row.agent_name,\n agent_spec: row.agent_spec,\n }),\n title: row.title,\n last_turn_id: row.last_turn_id,\n custom: parseSessionCustom(row.custom),\n created_at: row.created_at,\n updated_at: row.updated_at,\n last_activity_timestamp_ms: row.last_activity_timestamp_ms,\n };\n}\n\nexport async function createSession(db: Kysely<Database>, input: CreateSessionInput<SessionCustom>): Promise<void> {\n const columns = sessionAgentToColumns(input.agent);\n const nowMs = Date.now();\n\n try {\n await db\n .insertInto('session')\n .values({\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n created_by: input.created_by,\n agent_id: columns.agent_id,\n agent_name: columns.agent_name,\n agent_spec: columns.agent_spec !== null ? json(columns.agent_spec) : null,\n title: null,\n custom: input.custom !== null ? json(input.custom) : null,\n created_at: new Date(nowMs),\n updated_at: new Date(nowMs),\n last_activity_timestamp_ms: nowMs,\n })\n .execute();\n } catch (error) {\n if (isPgUniqueViolation(error)) {\n throw new SessionAlreadyExistsError(input.session_id, { cause: error });\n }\n throw error;\n }\n}\n\nexport async function deleteSession(db: Kysely<Database>, input: DeleteSessionInput): Promise<void> {\n await db\n .deleteFrom('session')\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .execute();\n}\n\nexport async function getSession(\n db: Kysely<Database>,\n input: GetSessionInput,\n): Promise<ProtoSessionRecord | undefined> {\n const row = await db\n .selectFrom('session')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n\n if (row === undefined) {\n return undefined;\n }\n\n return mapRowToSessionRecord(row);\n}\n\nexport async function updateSession(db: Kysely<Database>, input: UpdateSessionInput<SessionCustom>): Promise<void> {\n const agent = input.agent;\n const title = input.title;\n\n if (agent !== undefined) {\n const existing = await getSession(db, { tenant_id: input.tenant_id, session_id: input.session_id });\n if (existing === undefined) {\n throw new SessionNotFoundError(input.session_id);\n }\n if (existing.agent.type === 'reference') {\n throw new SessionStoreInvariantError(`Session ${input.session_id} is named; agent cannot be updated`);\n }\n }\n\n const result = await db\n .updateTable('session')\n .set({\n updated_at: sql<Date>`now()`,\n last_activity_timestamp_ms: Date.now(),\n })\n .$if(agent !== undefined, qb => {\n if (agent === undefined) {\n return qb;\n }\n return qb.set({ agent_spec: json(agent.spec) });\n })\n .$if(title !== undefined, qb => {\n if (title === undefined) {\n return qb;\n }\n return qb.set({ title });\n })\n .where('tenant_id', '=', input.tenant_id)\n .where('session_id', '=', input.session_id)\n .executeTakeFirst();\n\n const numUpdatedRows = Number(result.numUpdatedRows);\n if (numUpdatedRows === 0) {\n throw new SessionNotFoundError(input.session_id);\n }\n}\n\nexport async function listSessions(\n db: Kysely<Database>,\n input: ListSessionsInput,\n): Promise<{\n data: ProtoSessionRecord[];\n pagination: { next_page_token?: string | undefined; previous_page_token?: string | undefined };\n}> {\n const limit = input.limit;\n const order = input.order ?? 'desc';\n const cursor = decodeSessionListPageToken(input.page_token);\n\n let query = db\n .selectFrom('session')\n .selectAll()\n .select(\n sql<string>`to_char(updated_at AT TIME ZONE 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS.US\"Z\"')`.as('updated_at_cursor'),\n )\n .where('tenant_id', '=', input.tenant_id);\n\n if (input.agent_id !== undefined) {\n query = query.where('agent_id', '=', input.agent_id);\n }\n if (input.created_by !== undefined) {\n query = query.where('created_by', '=', input.created_by);\n }\n if (input.start_timestamp !== undefined) {\n query = query.where('created_at', '>=', input.start_timestamp);\n }\n if (input.end_timestamp !== undefined) {\n query = query.where('created_at', '<=', input.end_timestamp);\n }\n\n if (cursor) {\n const sessionId = cursor.session_id;\n // Bind the cursor string and cast in SQL so microsecond precision is preserved\n // (JS Date would truncate to milliseconds).\n const cursorUpdatedAt = sql<Date>`${cursor.updated_at}::timestamptz`;\n if (order === 'asc') {\n query = query.where(eb =>\n eb.or([\n eb('updated_at', '>', cursorUpdatedAt),\n eb.and([eb('updated_at', '=', cursorUpdatedAt), eb('session_id', '>', sessionId)]),\n ]),\n );\n } else {\n query = query.where(eb =>\n eb.or([\n eb('updated_at', '<', cursorUpdatedAt),\n eb.and([eb('updated_at', '=', cursorUpdatedAt), eb('session_id', '<', sessionId)]),\n ]),\n );\n }\n }\n\n if (order === 'asc') {\n query = query.orderBy('updated_at', 'asc').orderBy('session_id', 'asc');\n } else {\n query = query.orderBy('updated_at', 'desc').orderBy('session_id', 'desc');\n }\n\n const rows = await query.limit(limit + 1).execute();\n const { data: pageRows, pagination } = paginateSessionListRows(rows, limit, row => row.updated_at_cursor);\n\n return { data: pageRows.map(mapRowToSessionRecord), pagination };\n}\n","import type {\n AddThreadsInput,\n AppendToThreadContextInput,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n RemoveThreadsInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport type { JsonValue } from '@truefoundry/trueforge-core/core/capabilities/AgentCapability';\nimport type { AgentInfo } from '@truefoundry/trueforge-core/core/events/schema';\nimport type {\n ContextMessage,\n SubAgentCompletionMarker,\n} from '@truefoundry/trueforge-core/core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '@truefoundry/trueforge-core/core/runtime/contextUsage';\nimport { sql, type Kysely, type RawBuilder, type Transaction } from 'kysely';\nimport { json, jsonbSet } from '../../sqlExpressions';\nimport type { Database, TurnThreadCheckpoint } from '../../types';\nimport { values } from '../sqlExpressions';\nimport {\n assertTurnRunning,\n classifyTurnFenceWriteFailure,\n classifyTurnThreadWriteFailure,\n turnRunningFence,\n type TurnKeys,\n} from './turns';\n\ntype DbOrTrx = Kysely<Database> | Transaction<Database>;\n\ninterface CapabilityStateInsertRow {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: RawBuilder<JsonValue>;\n updated_at: RawBuilder<Date>;\n}\n\n/**\n * addThreads — fenced tx, max 3 batched statements: log INSERT, turn_thread INSERT,\n * capability upsert. No turn.checkpoint touch (threads live in turn_thread).\n */\nexport async function addThreads(db: Kysely<Database>, input: AddThreadsInput): Promise<void> {\n await db.transaction().execute(async trx => {\n await assertTurnRunning(trx, {\n session_id: input.session_id,\n turn_id: input.turn_id,\n });\n\n const now = new Date();\n const logRows: {\n session_id: string;\n thread_id: string;\n turn_id: string;\n body: RawBuilder<ContextMessage>;\n created_at: Date;\n }[] = [];\n const capabilityStateRows: CapabilityStateInsertRow[] = [];\n const turnThreadPlans: {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: RawBuilder<AgentInfo> | null;\n current_context_usage: CurrentContextUsage;\n }[] = [];\n\n for (const thread of input.threads) {\n const threadCheckpoint: TurnThreadCheckpoint = {\n parent: thread.parent ?? null,\n completion: thread.completion ?? null,\n };\n turnThreadPlans.push({\n thread_id: thread.thread_id,\n checkpoint: threadCheckpoint,\n agent_info: thread.agent_info != null ? json(thread.agent_info) : null,\n current_context_usage: thread.current_context_usage,\n });\n\n for (const body of thread.context) {\n logRows.push({\n session_id: input.session_id,\n thread_id: thread.thread_id,\n turn_id: input.turn_id,\n body: json(body),\n created_at: now,\n });\n }\n\n const capabilityState = thread.capability_state;\n if (capabilityState != null) {\n for (const key of Object.keys(capabilityState)) {\n const state = capabilityState[key];\n if (state === undefined) {\n throw new Error(\n `capability_state['${key}'] for thread '${thread.thread_id}' is undefined — undefined is banned from capability state`,\n );\n }\n capabilityStateRows.push({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: thread.thread_id,\n key,\n state: json(state),\n updated_at: sql<Date>`now()`,\n });\n }\n }\n }\n\n const newIdsByThread = new Map<string, number[]>();\n if (logRows.length > 0) {\n const inserted = await trx\n .insertInto('thread_context_log')\n .values(logRows)\n .returning(['thread_id', 'append_id'])\n .execute();\n for (const row of inserted) {\n const list = newIdsByThread.get(row.thread_id);\n if (list === undefined) {\n newIdsByThread.set(row.thread_id, [row.append_id]);\n } else {\n list.push(row.append_id);\n }\n }\n }\n\n const turnThreadRows = turnThreadPlans.map(plan => ({\n session_id: input.session_id,\n turn_id: input.turn_id,\n thread_id: plan.thread_id,\n checkpoint: plan.checkpoint,\n agent_info: plan.agent_info,\n current_context_usage: plan.current_context_usage,\n context_ids: newIdsByThread.get(plan.thread_id) ?? [],\n updated_at: now,\n }));\n\n if (turnThreadRows.length > 0) {\n await trx.insertInto('turn_thread').values(turnThreadRows).execute();\n }\n\n if (capabilityStateRows.length > 0) {\n await trx.insertInto('thread_capability_state').values(capabilityStateRows).execute();\n }\n });\n}\n\n/**\n * removeThreads — one statement: fence FOR SHARE + delete turn_thread + capability rows.\n * Older turns keep their maps; log rows stay. Empty thread_ids is a no-op.\n */\nexport async function removeThreads(db: Kysely<Database>, input: RemoveThreadsInput): Promise<void> {\n if (input.thread_ids.length === 0) {\n return;\n }\n\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n const onFence = sql<boolean>`EXISTS (SELECT 1 FROM turn_fence)`;\n\n const fence = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .with('del_cap', qb =>\n qb\n .deleteFrom('thread_capability_state')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .where(onFence),\n )\n .with('del_tt', qb =>\n qb\n .deleteFrom('turn_thread')\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', 'in', input.thread_ids)\n .where(onFence),\n )\n .selectFrom('turn_fence')\n .select('one')\n .executeTakeFirst();\n\n if (fence === undefined) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\nfunction completionPatchExpr(completion: SubAgentCompletionMarker | null): RawBuilder<TurnThreadCheckpoint> {\n if (completion === null) {\n return sql<TurnThreadCheckpoint>`checkpoint`;\n }\n return jsonbSet<TurnThreadCheckpoint>(sql`checkpoint`, sql`'{completion}'`, json(completion));\n}\n\nfunction usageSetExpr(usage: CurrentContextUsage | null): RawBuilder<CurrentContextUsage> {\n if (usage === null) {\n return sql`current_context_usage`;\n }\n // COALESCE matches the plan sketch: provided usage wins, else keep column.\n return sql`coalesce(${json(usage)}, current_context_usage)`;\n}\n\nasync function fencedTurnThreadContextUpdate(\n db: Kysely<Database>,\n args: {\n keys: TurnKeys;\n thread_id: string;\n context: ContextMessage[];\n replace_array: boolean;\n current_context_usage: CurrentContextUsage | null;\n completion: SubAgentCompletionMarker | null;\n /** When replace_array, usage is set unconditionally (overwrite contract). */\n usage_unconditional: CurrentContextUsage | null;\n },\n): Promise<void> {\n const { keys, thread_id, context, replace_array } = args;\n\n if (context.length === 0) {\n // No log INSERT — still fence + patch usage/completion / clear-or-keep array.\n const emptyResult = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .updateTable('turn_thread')\n .set({\n context_ids: replace_array ? sql<number[]>`'{}'::bigint[]` : sql<number[]>`context_ids`,\n current_context_usage: args.usage_unconditional ?? usageSetExpr(args.current_context_usage),\n checkpoint: completionPatchExpr(args.completion),\n updated_at: sql`now()`,\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .where(sql<boolean>`EXISTS (SELECT 1 FROM turn_fence)`)\n .executeTakeFirst();\n\n if (Number(emptyResult.numUpdatedRows) === 0) {\n await classifyTurnThreadWriteFailure(db, keys, thread_id);\n }\n return;\n }\n\n const bodyRows = context.map((body, index) => ({\n ord: sql<number>`${index + 1}::int`,\n body: json(body),\n }));\n\n const arrayExpr: RawBuilder<number[]> = replace_array\n ? sql<number[]>`coalesce((SELECT array_agg(append_id ORDER BY append_id) FROM new_rows), '{}'::bigint[])`\n : sql<\n number[]\n >`context_ids || coalesce((SELECT array_agg(append_id ORDER BY append_id) FROM new_rows), '{}'::bigint[])`;\n\n const result = await db\n .with('turn_fence', qb => turnRunningFence(qb, keys))\n .with('new_rows', qb =>\n qb\n .insertInto('thread_context_log')\n .columns(['session_id', 'thread_id', 'turn_id', 'body', 'created_at'])\n .expression(eb =>\n eb\n .selectFrom(values(bodyRows, 'b'))\n .select([\n sql<string>`${keys.session_id}`.as('session_id'),\n sql<string>`${thread_id}`.as('thread_id'),\n sql<string>`${keys.turn_id}`.as('turn_id'),\n 'b.body',\n sql<Date>`now()`.as('created_at'),\n ])\n .where(wb => wb.exists(wb.selectFrom('turn_fence').select(sql`1`.as('one'))))\n .orderBy('b.ord'),\n )\n .returning('append_id'),\n )\n .updateTable('turn_thread')\n .set({\n context_ids: arrayExpr,\n current_context_usage: args.usage_unconditional ?? usageSetExpr(args.current_context_usage),\n checkpoint: completionPatchExpr(args.completion),\n updated_at: sql`now()`,\n })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where('thread_id', '=', thread_id)\n .where(sql<boolean>`EXISTS (SELECT 1 FROM turn_fence)`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnThreadWriteFailure(db, keys, thread_id);\n }\n}\n\n/**\n * appendToThreadContext — ONE fenced statement: CTE inserts log rows, outer UPDATE\n * concats their ids, stamps usage (COALESCE), and patches completion on the same\n * turn_thread row version.\n */\nexport async function appendToThreadContext(db: Kysely<Database>, input: AppendToThreadContextInput): Promise<void> {\n await fencedTurnThreadContextUpdate(db, {\n keys: {\n session_id: input.session_id,\n turn_id: input.turn_id,\n },\n thread_id: input.thread_id,\n context: input.context,\n replace_array: false,\n current_context_usage: input.current_context_usage,\n completion: input.completion,\n usage_unconditional: null,\n });\n}\n\n/**\n * overwriteThreadContext — same one-statement shape; context_ids is REPLACED.\n * Old log rows stay — ancestor turns' arrays reference them. No lineage minting.\n */\nexport async function overwriteThreadContext(db: Kysely<Database>, input: OverwriteThreadContextInput): Promise<void> {\n await fencedTurnThreadContextUpdate(db, {\n keys: {\n session_id: input.session_id,\n turn_id: input.turn_id,\n },\n thread_id: input.event.thread_id,\n context: input.event.context,\n replace_array: true,\n current_context_usage: null,\n completion: null,\n usage_unconditional: input.event.current_context_usage,\n });\n}\n\n/**\n * patchMCPServers — one-shot conditional UPDATE on the fence row itself\n * (`state->>'status' = 'running'`). No separate FOR SHARE fence CTE.\n * Subscript LHS + expression RHS for shallow merge by server id.\n */\nexport async function patchMCPServers(db: Kysely<Database>, input: PatchMCPServersInput): Promise<void> {\n const serversById: Record<string, (typeof input.mcp_servers)[number]> = {};\n for (const server of input.mcp_servers) {\n serversById[server.id] = server;\n }\n\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const result = await db\n .updateTable('turn')\n .set(\n sql`checkpoint['mcp_servers']`,\n sql`(CASE WHEN jsonb_typeof(checkpoint->'mcp_servers') = 'object'\n THEN checkpoint->'mcp_servers'\n ELSE '{}'::jsonb END) || ${json(serversById)}`,\n )\n .set({ updated_at: sql`now()` })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\n/**\n * patchSandboxInfo — one-shot conditional UPDATE on the fence row itself\n * (`state->>'status' = 'running'`). LWW replace via subscript assignment.\n */\nexport async function patchSandboxInfo(db: Kysely<Database>, input: PatchSandboxInfoInput): Promise<void> {\n const keys: TurnKeys = {\n session_id: input.session_id,\n turn_id: input.turn_id,\n };\n\n const result = await db\n .updateTable('turn')\n .set(sql`checkpoint['sandbox_info']`, json(input.sandbox_info))\n .set({ updated_at: sql`now()` })\n .where('session_id', '=', keys.session_id)\n .where('turn_id', '=', keys.turn_id)\n .where(sql<boolean>`state->>'status' = 'running'`)\n .executeTakeFirst();\n\n if (Number(result.numUpdatedRows) === 0) {\n await classifyTurnFenceWriteFailure(db, keys);\n }\n}\n\n/** Test helper: read a turn_thread row. */\nexport async function getTurnThread(\n db: DbOrTrx,\n session_id: string,\n turn_id: string,\n thread_id: string,\n): Promise<\n | {\n thread_id: string;\n checkpoint: TurnThreadCheckpoint;\n agent_info: unknown;\n current_context_usage: CurrentContextUsage;\n context_ids: number[];\n }\n | undefined\n> {\n return await db\n .selectFrom('turn_thread')\n .select(['thread_id', 'checkpoint', 'agent_info', 'current_context_usage', 'context_ids'])\n .where('session_id', '=', session_id)\n .where('turn_id', '=', turn_id)\n .where('thread_id', '=', thread_id)\n .executeTakeFirst();\n}\n","import type { SessionRecord } from '@truefoundry/trueforge-core/agent-session/models/SessionRecord';\nimport type { TurnRecord } from '@truefoundry/trueforge-core/agent-session/models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '@truefoundry/trueforge-core/agent-session/schemas/events';\nimport type { TokenPagination } from '@truefoundry/trueforge-core/agent-session/schemas/pagination';\nimport type {\n AddThreadsInput,\n AppendToEventsInput,\n AppendToThreadContextInput,\n CreateSessionInput,\n CreateTurnInput,\n DeleteSessionInput,\n FreezeAndGetTurnInput,\n GetSessionInput,\n GetTurnInput,\n ISessionStore,\n ListSessionEventsInput,\n ListSessionsInput,\n ListTurnEventsInput,\n ListTurnsInput,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n PatchThreadCapabilityStateInput,\n RemoveThreadsInput,\n TurnRecordWithoutSnapshot,\n UpdateSessionInput,\n UpdateTurnStateInput,\n} from '@truefoundry/trueforge-core/agent-session/store/ISessionStore';\nimport {\n decodeOffsetPageToken,\n encodeOffsetPageToken,\n} from '@truefoundry/trueforge-core/agent-session/store/OffsetPageToken';\nimport type { Kysely } from 'kysely';\nimport type { Database } from '../types';\nimport { patchThreadCapabilityState as patchThreadCapabilityStateQuery } from './queries/capabilities';\nimport {\n appendToEvents as appendToEventsQuery,\n listSessionEvents as listSessionEventsQuery,\n listTurnEvents as listTurnEventsQuery,\n} from './queries/events';\nimport {\n createSession as createSessionQuery,\n deleteSession as deleteSessionQuery,\n getSession as getSessionQuery,\n listSessions as listSessionsQuery,\n updateSession as updateSessionQuery,\n} from './queries/sessions';\nimport {\n addThreads as addThreadsQuery,\n appendToThreadContext as appendToThreadContextQuery,\n overwriteThreadContext as overwriteThreadContextQuery,\n patchMCPServers as patchMCPServersQuery,\n patchSandboxInfo as patchSandboxInfoQuery,\n removeThreads as removeThreadsQuery,\n} from './queries/threads';\nimport type { NewThreadRegistration } from './queries/turns';\nimport {\n createTurn as createTurnQuery,\n freezeAndGetTurn as freezeAndGetTurnQuery,\n getTurn as getTurnQuery,\n listTurns as listTurnsQuery,\n updateTurnState as updateTurnStateQuery,\n} from './queries/turns';\n\ntype SessionCustom = Record<string, never>;\ntype TurnCustom = Record<string, never>;\n\n/**\n * ## Design: append-only context log + per-turn id arrays\n *\n * Message bodies live in `thread_context_log`, append-only, written exactly\n * once; ids are store-assigned (`append_id` identity — the delta createTurn\n * interface tells the store what's new, so identity needs no hashing).\n * A turn's context per thread is `turn_thread.context_ids` — the explicit\n * ordered array of log ids. Turns share no mutable structure: linear\n * continuation and fork are the same pointer-copy (`parent_array || new_ids`),\n * overwrite replaces the array, and a still-running ancestor's late appends\n * touch only its OWN rows — structural leaks are impossible by construction.\n *\n * Hard invariants (violations proven by failing tests during prototyping —\n * see the freeze/fence tests):\n * 1. A turn cannot be used as `previous_turn_id` while it is still `running` —\n * `createTurn` rejects that with PreviousTurnRunningError; callers must\n * `freezeAndGetTurn` first (barge-in IS cancellation of that predecessor).\n * Tip-equality is NOT required: new roots and concurrent forks from a\n * finished tip can leave more than one turn `running` at once.\n * 2. Every turn-scoped write is fenced on `state->>'status' = 'running'`.\n * 3. Terminal turns are IMMUTABLE — a terminal read is a final read.\n */\nexport class PostgresSessionStore implements ISessionStore<SessionCustom, TurnCustom> {\n constructor(private readonly db: Kysely<Database>) {}\n\n createSession(input: CreateSessionInput<SessionCustom>): Promise<void> {\n return createSessionQuery(this.db, input);\n }\n\n deleteSession(input: DeleteSessionInput): Promise<void> {\n return deleteSessionQuery(this.db, input);\n }\n\n getSession(input: GetSessionInput): Promise<SessionRecord<SessionCustom> | undefined> {\n return getSessionQuery(this.db, input);\n }\n\n updateSession(input: UpdateSessionInput<SessionCustom>): Promise<void> {\n return updateSessionQuery(this.db, input);\n }\n\n async listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<SessionCustom>[]; pagination: TokenPagination }> {\n const result = await listSessionsQuery(this.db, input);\n return {\n data: result.data,\n pagination: {\n limit: input.limit,\n ...result.pagination,\n },\n };\n }\n\n async createTurn(input: CreateTurnInput<TurnCustom>): Promise<void> {\n await createTurnQuery(this.db, {\n session_id: input.turn.session_id,\n turn: {\n turn_id: input.turn.turn_id,\n first_turn_id: input.turn.first_turn_id,\n previous_turn_id: input.turn.previous_turn_id,\n ancestor_ids: input.turn.ancestor_ids,\n input: input.turn.input,\n state: input.turn.state,\n custom: input.turn.custom,\n },\n new_threads: input.new_threads.map((thread): NewThreadRegistration => ({\n thread_id: thread.thread_id,\n parent: thread.parent,\n agent_info: thread.agent_info,\n })),\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n last_activity_timestamp_ms: Date.now(),\n update_session_title_if_not_exist: input.update_session_title_if_not_exist,\n mcp_servers: null,\n sandbox_info: null,\n });\n }\n\n freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TurnCustom>> {\n return freezeAndGetTurnQuery(this.db, input);\n }\n\n getTurn(input: GetTurnInput): Promise<TurnRecord<TurnCustom> | undefined> {\n return getTurnQuery(this.db, input);\n }\n\n async listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TurnCustom>[]; pagination: TokenPagination }> {\n const offset = decodeOffsetPageToken(input.page_token);\n const result = await listTurnsQuery(this.db, {\n session_id: input.session_id,\n limit: input.limit,\n offset,\n });\n const pagination: TokenPagination = { limit: input.limit };\n if (result.next_offset !== null) {\n pagination.next_page_token = encodeOffsetPageToken(result.next_offset);\n }\n if (offset > 0) {\n pagination.previous_page_token = encodeOffsetPageToken(Math.max(0, offset - input.limit));\n }\n return { data: result.turns, pagination };\n }\n\n updateTurnState(input: UpdateTurnStateInput): Promise<void> {\n return updateTurnStateQuery(this.db, input);\n }\n\n appendToEvents(input: AppendToEventsInput): Promise<void> {\n return appendToEventsQuery(this.db, input);\n }\n\n addThreads(input: AddThreadsInput): Promise<void> {\n return addThreadsQuery(this.db, input);\n }\n\n removeThreads(input: RemoveThreadsInput): Promise<void> {\n return removeThreadsQuery(this.db, input);\n }\n\n appendToThreadContext(input: AppendToThreadContextInput): Promise<void> {\n return appendToThreadContextQuery(this.db, input);\n }\n\n overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void> {\n return overwriteThreadContextQuery(this.db, input);\n }\n\n patchMCPServers(input: PatchMCPServersInput): Promise<void> {\n return patchMCPServersQuery(this.db, input);\n }\n\n patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void> {\n return patchSandboxInfoQuery(this.db, input);\n }\n\n patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void> {\n return patchThreadCapabilityStateQuery(this.db, input);\n }\n\n listTurnEvents(input: ListTurnEventsInput): Promise<{ data: PersistedTurnEvent[]; pagination: TokenPagination }> {\n return listTurnEventsQuery(this.db, input);\n }\n\n listSessionEvents(input: ListSessionEventsInput): Promise<{ data: SessionEventItem[]; pagination: TokenPagination }> {\n return listSessionEventsQuery(this.db, input);\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport type { AvailableModel } from '../../../schemas/modelProvider';\nimport {\n flattenProviderModels,\n ModelProviderNameConflictError,\n type CreateModelProviderInput,\n type GetModelProviderInput,\n type IModelProviderStore,\n type ModelProviderRecord,\n type UpsertModelProviderInput,\n} from '../../modelProviderStore';\nimport { isUniqueViolation } from '../client';\nimport { json, now } from '../sqlExpressions';\nimport type { Database, ModelProviderTable } from '../types';\n\nfunction toRecord(row: Selectable<ModelProviderTable>): ModelProviderRecord {\n return {\n tenant_id: row.tenant_id,\n name: row.name,\n manifest: row.manifest,\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresModelProviderStore implements IModelProviderStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listProviders(tenantId: string, transaction?: Transaction<Database>): Promise<ModelProviderRecord[]> {\n const db = transaction ?? this.#db;\n const rows = await db\n .selectFrom('model_provider')\n .selectAll()\n .where('tenant_id', '=', tenantId)\n .orderBy('name')\n .execute();\n return rows.map(toRecord);\n }\n\n async getProvider(\n input: GetModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('model_provider')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async getProviderForUpdate(\n input: GetModelProviderInput,\n transaction: Transaction<Database>,\n ): Promise<ModelProviderRecord | undefined> {\n const row = await transaction\n .selectFrom('model_provider')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .forUpdate()\n .executeTakeFirst();\n return row ? toRecord(row) : undefined;\n }\n\n async createProvider(\n input: CreateModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord> {\n const db = transaction ?? this.#db;\n try {\n const row = await db\n .insertInto('model_provider')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new ModelProviderNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertProvider(\n input: UpsertModelProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<ModelProviderRecord> {\n const db = transaction ?? this.#db;\n const row = await db\n .insertInto('model_provider')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: json(input.manifest),\n updated_at: now(),\n }),\n )\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n }\n\n async listModels(tenantId: string, transaction?: Transaction<Database>): Promise<AvailableModel[]> {\n return flattenProviderModels(await this.listProviders(tenantId, transaction));\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport { ulid } from 'ulid';\nimport type { OAuthClientRecord } from '../../../mcp/auth/types';\nimport {\n fromStoredOAuthClientRecord,\n McpServerNameConflictError,\n toStoredOAuthClientRecord,\n type CreateMcpServerInput,\n type GetMcpServerInput,\n type IMcpServerStore,\n type ListMcpServersInput,\n type McpServerRecord,\n type UpsertMcpServerInput,\n} from '../../mcpServerStore';\nimport { isUniqueViolation } from '../client';\nimport { json, now } from '../sqlExpressions';\nimport type { Database, McpServerTable } from '../types';\n\nfunction toRecord(row: Selectable<McpServerTable>): McpServerRecord {\n return {\n id: row.id,\n tenant_id: row.tenant_id,\n name: row.name,\n manifest: row.manifest,\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresMcpServerStore implements IMcpServerStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listServers(input: ListMcpServersInput, transaction?: Transaction<Database>): Promise<McpServerRecord[]> {\n if (input.names?.length === 0) {\n return [];\n }\n const db = transaction ?? this.#db;\n let query = db.selectFrom('mcp_server').selectAll().where('tenant_id', '=', input.tenant_id);\n if (input.names !== undefined) {\n query = query.where('name', 'in', [...input.names]);\n }\n const rows = await query.orderBy('name').execute();\n return rows.map(toRecord);\n }\n\n async getServer(input: GetMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('mcp_server')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async getServerForUpdate(\n input: GetMcpServerInput,\n transaction: Transaction<Database>,\n ): Promise<McpServerRecord | undefined> {\n const row = await transaction\n .selectFrom('mcp_server')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .forUpdate()\n .executeTakeFirst();\n return row ? toRecord(row) : undefined;\n }\n\n async createServer(input: CreateMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord> {\n const db = transaction ?? this.#db;\n try {\n const row = await db\n .insertInto('mcp_server')\n .values({\n id: ulid(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n oauth_server: null,\n oauth_client: null,\n created_at: now(),\n updated_at: now(),\n })\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new McpServerNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertServer(input: UpsertMcpServerInput, transaction?: Transaction<Database>): Promise<McpServerRecord> {\n const db = transaction ?? this.#db;\n const row = await db\n .insertInto('mcp_server')\n .values({\n id: ulid(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n oauth_server: null,\n oauth_client: null,\n created_at: now(),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: json(input.manifest),\n updated_at: now(),\n }),\n )\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n }\n\n async getClient(params: { id: string }, transaction?: Transaction<Database>): Promise<OAuthClientRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('mcp_server')\n .select(['oauth_server', 'oauth_client'])\n .where('id', '=', params.id)\n .executeTakeFirst();\n if (row?.oauth_server == null || row.oauth_client == null) {\n return undefined;\n }\n return fromStoredOAuthClientRecord({ server: row.oauth_server, client: row.oauth_client });\n }\n\n async saveClient(\n params: { id: string; record: OAuthClientRecord },\n transaction?: Transaction<Database>,\n ): Promise<void> {\n const db = transaction ?? this.#db;\n const stored = toStoredOAuthClientRecord(params.record);\n await db\n .updateTable('mcp_server')\n .set({\n oauth_server: json(stored.server),\n oauth_client: json(stored.client),\n })\n .where('id', '=', params.id)\n .execute();\n }\n\n async deleteClient(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n const db = transaction ?? this.#db;\n await db\n .updateTable('mcp_server')\n .set({\n oauth_server: null,\n oauth_client: null,\n })\n .where('id', '=', params.id)\n .execute();\n }\n}\n","import type { Kysely } from 'kysely';\nimport type { OAuthPendingAuthorization } from '../../../../mcp/auth/types';\nimport {\n fromStoredOAuthPendingAuthorizationData,\n PENDING_AUTHORIZATION_TTL_MS,\n toStoredOAuthPendingAuthorizationData,\n} from '../../../mcpServerStore';\nimport { json, now, nowMinusMs } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nexport async function savePendingAuthorization(\n db: Kysely<Database>,\n pending: OAuthPendingAuthorization,\n): Promise<void> {\n const authData = toStoredOAuthPendingAuthorizationData(pending);\n\n await db\n .insertInto('oauth_pending_authorization')\n .values({\n id: pending.state,\n oauth_server_id: pending.id,\n user_id: pending.userRef,\n auth_data: json(authData),\n created_at: now(),\n })\n .execute();\n}\n\n/**\n * Single-use claim: DELETE … RETURNING under the TTL filter so only one concurrent\n * callback wins the row.\n */\nexport async function consumePendingAuthorization(\n db: Kysely<Database>,\n params: { state: string },\n): Promise<OAuthPendingAuthorization | undefined> {\n const row = await db\n .deleteFrom('oauth_pending_authorization')\n .where('id', '=', params.state)\n .where('created_at', '>', nowMinusMs(PENDING_AUTHORIZATION_TTL_MS))\n .returning(['id', 'oauth_server_id', 'user_id', 'auth_data'])\n .executeTakeFirst();\n\n if (row === undefined) {\n return undefined;\n }\n\n return {\n state: row.id,\n id: row.oauth_server_id,\n userRef: row.user_id,\n ...fromStoredOAuthPendingAuthorizationData(row.auth_data),\n };\n}\n\nexport async function deletePendingAuthorizationsForServer(\n db: Kysely<Database>,\n params: { id: string },\n): Promise<void> {\n await db.deleteFrom('oauth_pending_authorization').where('oauth_server_id', '=', params.id).execute();\n}\n","import { sql, type Kysely } from 'kysely';\nimport type { OAuthToken } from '../../../mcpServerStore';\nimport { json, now } from '../../sqlExpressions';\nimport type { Database } from '../../types';\n\nexport async function saveToken(\n db: Kysely<Database>,\n params: { id: string; userRef: string; token: OAuthToken },\n): Promise<void> {\n await db\n .insertInto('oauth_token')\n .values({\n oauth_server_id: params.id,\n user_id: params.userRef,\n token: json(params.token),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['oauth_server_id', 'user_id']).doUpdateSet({\n token: sql`excluded.token`,\n updated_at: sql`excluded.updated_at`,\n }),\n )\n .execute();\n}\n\nexport async function getToken(\n db: Kysely<Database>,\n params: { id: string; userRef: string },\n): Promise<OAuthToken | undefined> {\n const row = await db\n .selectFrom('oauth_token')\n .select('token')\n .where('oauth_server_id', '=', params.id)\n .where('user_id', '=', params.userRef)\n .executeTakeFirst();\n\n return row === undefined ? undefined : row.token;\n}\n\nexport async function getTokens(\n db: Kysely<Database>,\n params: { ids: string[]; userRef: string },\n): Promise<Map<string, OAuthToken>> {\n if (params.ids.length === 0) {\n return new Map();\n }\n const rows = await db\n .selectFrom('oauth_token')\n .select(['oauth_server_id', 'token'])\n .where('oauth_server_id', 'in', params.ids)\n .where('user_id', '=', params.userRef)\n .execute();\n\n return new Map(rows.map(row => [row.oauth_server_id, row.token]));\n}\n\nexport async function deleteToken(db: Kysely<Database>, params: { id: string; userRef: string }): Promise<void> {\n await db\n .deleteFrom('oauth_token')\n .where('oauth_server_id', '=', params.id)\n .where('user_id', '=', params.userRef)\n .execute();\n}\n\nexport async function deleteTokensForServer(db: Kysely<Database>, params: { id: string }): Promise<void> {\n await db.deleteFrom('oauth_token').where('oauth_server_id', '=', params.id).execute();\n}\n","import type { Kysely, Transaction } from 'kysely';\nimport type { IOAuthTokenStore, OAuthPendingAuthorization, OAuthToken, OAuthTokenKey } from '../../../mcp/auth/types';\nimport { fromStoredOAuthToken, toStoredOAuthToken } from '../../mcpServerStore';\nimport type { Database } from '../types';\nimport {\n consumePendingAuthorization,\n deletePendingAuthorizationsForServer,\n savePendingAuthorization,\n} from './queries/pendingAuthorization';\nimport { deleteToken, deleteTokensForServer, getToken, getTokens, saveToken } from './queries/token';\n\nexport class PostgresOAuthTokenStore implements IOAuthTokenStore<Transaction<Database>> {\n constructor(private readonly db: Kysely<Database>) {}\n\n savePendingAuthorization(pending: OAuthPendingAuthorization, transaction?: Transaction<Database>): Promise<void> {\n return savePendingAuthorization(transaction ?? this.db, pending);\n }\n\n consumePendingAuthorization(\n params: { state: string },\n transaction?: Transaction<Database>,\n ): Promise<OAuthPendingAuthorization | undefined> {\n return consumePendingAuthorization(transaction ?? this.db, params);\n }\n\n saveToken(params: OAuthTokenKey & { token: OAuthToken }, transaction?: Transaction<Database>): Promise<void> {\n return saveToken(transaction ?? this.db, {\n id: params.id,\n userRef: params.userRef,\n token: toStoredOAuthToken(params.token),\n });\n }\n\n async getToken(params: OAuthTokenKey, transaction?: Transaction<Database>): Promise<OAuthToken | undefined> {\n const stored = await getToken(transaction ?? this.db, params);\n return stored === undefined ? undefined : fromStoredOAuthToken(stored);\n }\n\n async getTokens(\n params: { ids: string[]; userRef: string },\n transaction?: Transaction<Database>,\n ): Promise<Map<string, OAuthToken>> {\n const stored = await getTokens(transaction ?? this.db, params);\n return new Map([...stored].map(([id, token]) => [id, fromStoredOAuthToken(token)]));\n }\n\n deleteToken(params: OAuthTokenKey, transaction?: Transaction<Database>): Promise<void> {\n return deleteToken(transaction ?? this.db, params);\n }\n\n deleteTokensForServer(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n return deleteTokensForServer(transaction ?? this.db, params);\n }\n\n deletePendingAuthorizationsForServer(params: { id: string }, transaction?: Transaction<Database>): Promise<void> {\n return deletePendingAuthorizationsForServer(transaction ?? this.db, params);\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport {\n SkillNameConflictError,\n type CreateSkillInput,\n type GetSkillInput,\n type ISkillStore,\n type ListSkillsInput,\n type SkillRecord,\n type UpsertSkillInput,\n} from '../../skillStore';\nimport { isUniqueViolation } from '../client';\nimport { json, now } from '../sqlExpressions';\nimport type { Database, SkillTable } from '../types';\n\nfunction toRecord(row: Selectable<SkillTable>): SkillRecord {\n return {\n tenant_id: row.tenant_id,\n name: row.name,\n manifest: row.manifest,\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresSkillStore implements ISkillStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listSkills(input: ListSkillsInput, transaction?: Transaction<Database>): Promise<SkillRecord[]> {\n if (input.names?.length === 0) {\n return [];\n }\n const db = transaction ?? this.#db;\n let query = db.selectFrom('skill').selectAll().where('tenant_id', '=', input.tenant_id);\n if (input.names !== undefined) {\n query = query.where('name', 'in', [...input.names]);\n }\n const rows = await query.orderBy('name').execute();\n return rows.map(toRecord);\n }\n\n async getSkill(input: GetSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('skill')\n .selectAll()\n .where('tenant_id', '=', input.tenant_id)\n .where('name', '=', input.name)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async createSkill(input: CreateSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord> {\n const db = transaction ?? this.#db;\n try {\n const row = await db\n .insertInto('skill')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new SkillNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async upsertSkill(input: UpsertSkillInput, transaction?: Transaction<Database>): Promise<SkillRecord> {\n const db = transaction ?? this.#db;\n const row = await db\n .insertInto('skill')\n .values({\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['tenant_id', 'name']).doUpdateSet({\n manifest: json(input.manifest),\n updated_at: now(),\n }),\n )\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport {\n type ISandboxProviderStore,\n type SandboxProviderRecord,\n type UpdateSandboxStatusInput,\n type UpsertSandboxProviderInput,\n} from '../../sandboxProviderStore';\nimport { json, now } from '../sqlExpressions';\nimport type { Database, SandboxProviderTable } from '../types';\n\nfunction toRecord(row: Selectable<SandboxProviderTable>): SandboxProviderRecord {\n return {\n tenant_id: row.tenant_id,\n manifest: row.manifest,\n status: row.status,\n status_reason: row.status_reason,\n build_metadata: row.build_metadata,\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresSandboxProviderStore implements ISandboxProviderStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async getSandboxProvider(\n tenantId: string,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .selectFrom('sandbox_provider')\n .selectAll()\n .where('tenant_id', '=', tenantId)\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async getSandboxProviderForUpdate(\n tenantId: string,\n transaction: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const row = await transaction\n .selectFrom('sandbox_provider')\n .selectAll()\n .where('tenant_id', '=', tenantId)\n .forUpdate()\n .executeTakeFirst();\n return row ? toRecord(row) : undefined;\n }\n\n async upsertSandboxProvider(\n input: UpsertSandboxProviderInput,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord> {\n const db = transaction ?? this.#db;\n const row = await db\n .insertInto('sandbox_provider')\n .values({\n tenant_id: input.tenant_id,\n manifest: json(input.manifest),\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? json(input.build_metadata) : null,\n created_at: now(),\n updated_at: now(),\n })\n .onConflict(oc =>\n oc.columns(['tenant_id']).doUpdateSet({\n manifest: json(input.manifest),\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? json(input.build_metadata) : null,\n updated_at: now(),\n }),\n )\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n }\n\n async updateSandboxStatus(\n input: UpdateSandboxStatusInput,\n transaction?: Transaction<Database>,\n ): Promise<SandboxProviderRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .updateTable('sandbox_provider')\n .set({\n status: input.status,\n status_reason: input.status_reason,\n build_metadata: input.build_metadata !== null ? json(input.build_metadata) : null,\n updated_at: now(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .returningAll()\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n}\n","import type { Kysely, Selectable, Transaction } from 'kysely';\nimport { ulid } from 'ulid';\nimport {\n AgentNameConflictError,\n parseStoredAgentSpec,\n type AgentRecord,\n type CreateAgentInput,\n type DeleteAgentInput,\n type GetAgentInput,\n type IAgentStore,\n type UpdateAgentInput,\n} from '../../agentStore';\nimport { isUniqueViolation } from '../client';\nimport { json, now } from '../sqlExpressions';\nimport type { AgentTable, Database } from '../types';\n\nfunction toRecord(row: Selectable<AgentTable>): AgentRecord {\n return {\n id: row.id,\n tenant_id: row.tenant_id,\n name: row.name,\n manifest: parseStoredAgentSpec(row.manifest),\n created_at: row.created_at.toISOString(),\n updated_at: row.updated_at.toISOString(),\n };\n}\n\nexport class PostgresAgentStore implements IAgentStore<Transaction<Database>> {\n readonly #db: Kysely<Database>;\n\n constructor(db: Kysely<Database>) {\n this.#db = db;\n }\n\n async listAgents(tenantId: string, transaction?: Transaction<Database>): Promise<AgentRecord[]> {\n const db = transaction ?? this.#db;\n const rows = await db.selectFrom('agent').selectAll().where('tenant_id', '=', tenantId).orderBy('name').execute();\n return rows.map(toRecord);\n }\n\n async getAgent(input: GetAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord | undefined> {\n const db = transaction ?? this.#db;\n let query = db.selectFrom('agent').selectAll().where('tenant_id', '=', input.tenant_id);\n if ('id' in input) {\n query = query.where('id', '=', input.id);\n } else {\n query = query.where('name', '=', input.name);\n }\n const row = await query.executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async createAgent(input: CreateAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord> {\n const db = transaction ?? this.#db;\n try {\n const row = await db\n .insertInto('agent')\n .values({\n id: ulid().toLowerCase(),\n tenant_id: input.tenant_id,\n name: input.name,\n manifest: json(input.manifest),\n created_at: now(),\n updated_at: now(),\n })\n .returningAll()\n .executeTakeFirstOrThrow();\n return toRecord(row);\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new AgentNameConflictError({ tenant_id: input.tenant_id, name: input.name }, { cause: error });\n }\n throw error;\n }\n }\n\n async updateAgent(input: UpdateAgentInput, transaction?: Transaction<Database>): Promise<AgentRecord | undefined> {\n const db = transaction ?? this.#db;\n const row = await db\n .updateTable('agent')\n .set({\n manifest: json(input.manifest),\n updated_at: now(),\n })\n .where('tenant_id', '=', input.tenant_id)\n .where('id', '=', input.id)\n .returningAll()\n .executeTakeFirst();\n return row === undefined ? undefined : toRecord(row);\n }\n\n async deleteAgent(input: DeleteAgentInput, transaction?: Transaction<Database>): Promise<void> {\n const db = transaction ?? this.#db;\n await db.deleteFrom('agent').where('tenant_id', '=', input.tenant_id).where('id', '=', input.id).execute();\n }\n}\n","/**\n * Server entry point: validates config, migrates the selected database, wires\n * stores, and starts the HTTP server. Any config, migration, or store error\n * aborts startup.\n *\n * `STANDALONE=true` (default): SQLite, no Redis. `STANDALONE=false`: Postgres + Redis.\n *\n * Config is validated at import time (`./config`). Runtime startup failures\n * (migrate, Redis, listen) are caught below and exit non-zero. SQLite vs\n * Postgres store modules stay dynamic so only the active engine is loaded.\n */\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport { mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport {\n ensureLocalSandboxRootParent,\n prepareCodeModeSocketParent,\n removeCodeModeSocketParent,\n} from './sandbox/localLifecycle';\nimport { setCachedLocalSandboxSupport } from './sandbox/localRuntime';\n\nlet configuration: typeof import('./config').default;\nlet isOidcConfigured: typeof import('./config').isOidcConfigured;\n\ntry {\n ({ default: configuration, isOidcConfigured } = await import('./config'));\n} catch (error) {\n console.error(\n 'Failed to start server: Failed to load configuration:',\n error instanceof Error ? error.message : error,\n );\n process.exit(1);\n}\n\nimport { serve } from '@hono/node-server';\nimport {\n CancellationReason,\n Sessions,\n type ISessionStore,\n type TurnStreamingEvent,\n} from '@truefoundry/trueforge-core/agent-session';\nimport { RequestReplyExecutor, RequestReplyRouter } from '@truefoundry/trueforge-core/request-reply';\nimport type { Transaction } from 'kysely';\nimport type { RedisClientType } from 'redis';\nimport type { Logger } from 'winston';\n\nimport { createServerApp } from './app';\nimport { initOidc } from './auth/oidc';\nimport { McpCatalog } from './catalog/McpCatalog';\nimport { ModelCatalog } from './catalog/ModelCatalog';\nimport { SandboxCatalog } from './catalog/SandboxCatalog';\nimport { SkillCatalog } from './catalog/SkillCatalog';\nimport { type DistributedServerConfiguration } from './config';\nimport type { IAgentStore } from './db/agentStore';\nimport type { IMcpServerStore } from './db/mcpServerStore';\nimport type { IModelProviderStore } from './db/modelProviderStore';\nimport type { Database as PostgresDatabase } from './db/postgres/types';\nimport type { ISandboxProviderStore } from './db/sandboxProviderStore';\nimport type { ISkillStore } from './db/skillStore';\nimport type { Database as SqliteDatabase } from './db/sqlite/types';\nimport type { WithTransaction } from './db/transaction';\nimport { mountFrontend } from './frontend';\nimport { createServerLogger, shouldColorize } from './logger';\nimport type { IOAuthTokenStore } from './mcp/auth/types';\nimport { PACKAGE_VERSION } from './packageVersion';\nimport { ActiveTurnRegistry } from './runtime/activeTurns';\nimport { EventSubscriptionRegistry } from './runtime/event-subscription';\nimport { printStandaloneStartupBanner } from './startupBanner';\n\n/** Persistence + optional Redis wired for the selected topology. */\ninterface ServerPersistence<TTransaction> {\n sessionStore: ISessionStore;\n modelProviderStore: IModelProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n mcpServerStore: IMcpServerStore<TTransaction>;\n tokenStore: IOAuthTokenStore<TTransaction>;\n skillStore: ISkillStore<TTransaction>;\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n agentStore: IAgentStore<TTransaction>;\n destroyDb: () => Promise<void>;\n redis: RedisClientType | undefined;\n}\n\n/** SQLite stores; Redis unused (executor peering disabled). */\nasync function createStandalonePersistence(options: {\n sqlitePath: string;\n logger: Logger;\n}): Promise<ServerPersistence<Transaction<SqliteDatabase>>> {\n const { sqlitePath, logger } = options;\n await mkdir(path.dirname(sqlitePath), { recursive: true });\n const [{ createSqliteDb }, { migrateSqliteToLatest }, sqliteStores] = await Promise.all([\n import('./db/sqlite/client'),\n import('./db/migrateSqlite'),\n Promise.all([\n import('./db/sqlite/session-store/SqliteSessionStore'),\n import('./db/sqlite/model-provider-store/SqliteModelProviderStore'),\n import('./db/sqlite/mcp-server-store/SqliteMcpServerStore'),\n import('./db/sqlite/token-store/SqliteOAuthTokenStore'),\n import('./db/sqlite/skill-store/SqliteSkillStore'),\n import('./db/sqlite/sandbox-provider-store/SqliteSandboxProviderStore'),\n import('./db/sqlite/agent-store/SqliteAgentStore'),\n ]),\n ]);\n const [\n { SqliteSessionStore },\n { SqliteModelProviderStore },\n { SqliteMcpServerStore },\n { SqliteOAuthTokenStore },\n { SqliteSkillStore },\n { SqliteSandboxProviderStore },\n { SqliteAgentStore },\n ] = sqliteStores;\n\n const db = createSqliteDb(sqlitePath);\n await migrateSqliteToLatest(db);\n logger.info(`Standalone mode: sqlite at ${sqlitePath}`);\n logger.info('Standalone mode: executor peering disabled and Redis unused');\n\n return {\n sessionStore: new SqliteSessionStore(db),\n modelProviderStore: new SqliteModelProviderStore(db),\n withTransaction: callback => db.transaction().execute(callback),\n mcpServerStore: new SqliteMcpServerStore(db),\n tokenStore: new SqliteOAuthTokenStore(db),\n skillStore: new SqliteSkillStore(db),\n sandboxProviderStore: new SqliteSandboxProviderStore(db),\n agentStore: new SqliteAgentStore(db),\n destroyDb: () => db.destroy(),\n redis: undefined,\n };\n}\n\n/** Postgres stores + Redis for executor peering. */\nasync function createDistributedPersistence(options: {\n configuration: DistributedServerConfiguration;\n logger: Logger;\n}): Promise<ServerPersistence<Transaction<PostgresDatabase>>> {\n const { configuration, logger } = options;\n const {\n DATABASE_URL: databaseUrl,\n DATABASE_POOL_MAX: databasePoolMax,\n POSTGRES_STATEMENT_TIMEOUT_MS: statementTimeoutMs,\n POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS: idleInTransactionSessionTimeoutMs,\n REDIS_URL: redisUrl,\n EXECUTOR_ID: executorId,\n } = configuration;\n\n const [{ createDb }, { migrateToLatest }, { connectRedis }, postgresStores] = await Promise.all([\n import('./db/postgres/client'),\n import('./db/migratePostgres'),\n import('./runtime/redis'),\n Promise.all([\n import('./db/postgres/session-store/PostgresSessionStore'),\n import('./db/postgres/model-provider-store/PostgresModelProviderStore'),\n import('./db/postgres/mcp-server-store/PostgresMcpServerStore'),\n import('./db/postgres/token-store/PostgresOAuthTokenStore'),\n import('./db/postgres/skill-store/PostgresSkillStore'),\n import('./db/postgres/sandbox-provider-store/PostgresSandboxProviderStore'),\n import('./db/postgres/agent-store/PostgresAgentStore'),\n ]),\n ]);\n const [\n { PostgresSessionStore },\n { PostgresModelProviderStore },\n { PostgresMcpServerStore },\n { PostgresOAuthTokenStore },\n { PostgresSkillStore },\n { PostgresSandboxProviderStore },\n { PostgresAgentStore },\n ] = postgresStores;\n\n const db = createDb({\n connectionString: databaseUrl,\n poolMax: databasePoolMax,\n statementTimeoutMs,\n idleInTransactionSessionTimeoutMs,\n });\n await migrateToLatest(db);\n logger.info('Distributed mode: postgres');\n logger.info(`Executor id: ${executorId}`);\n\n return {\n sessionStore: new PostgresSessionStore(db),\n modelProviderStore: new PostgresModelProviderStore(db),\n withTransaction: callback => db.transaction().execute(callback),\n mcpServerStore: new PostgresMcpServerStore(db),\n tokenStore: new PostgresOAuthTokenStore(db),\n skillStore: new PostgresSkillStore(db),\n sandboxProviderStore: new PostgresSandboxProviderStore(db),\n agentStore: new PostgresAgentStore(db),\n destroyDb: () => db.destroy(),\n redis: await connectRedis({ url: redisUrl, logger }),\n };\n}\n\n/** Keeps `TTransaction` concrete when wiring a single persistence topology into the app. */\nasync function createServerRuntime<TTransaction>(persistence: ServerPersistence<TTransaction>, logger: Logger) {\n const {\n sessionStore,\n modelProviderStore,\n withTransaction,\n mcpServerStore,\n tokenStore,\n skillStore,\n sandboxProviderStore,\n agentStore,\n destroyDb,\n redis,\n } = persistence;\n\n const activeTurns = new ActiveTurnRegistry();\n const requestReplyRouter = new RequestReplyRouter();\n const eventSubscriptions = new EventSubscriptionRegistry<TurnStreamingEvent>(redis);\n\n const oidc = isOidcConfigured(configuration) ? configuration.OIDC : undefined;\n if (oidc) {\n logger.info('Auth is enabled', { issuer: oidc.OIDC_ISSUER_URL });\n } else {\n logger.warn('Auth is disabled; browser login is off');\n }\n const oidcClient = await initOidc(oidc);\n\n const app = createServerApp({\n modelCatalog: ModelCatalog.load(),\n mcpCatalog: McpCatalog.load(),\n skillCatalog: SkillCatalog.load(),\n sandboxCatalog: SandboxCatalog.load(),\n modelProviderStore,\n withTransaction,\n mcpServerStore,\n tokenStore,\n skillStore,\n sandboxProviderStore,\n agentStore,\n sessionStore,\n sessions: new Sessions({ sessionStore }),\n activeTurns,\n redis,\n requestReplyRouter,\n eventSubscriptions,\n logger,\n oidcClient,\n });\n\n return { activeTurns, app, destroyDb, redis, requestReplyRouter };\n}\n\ntry {\n const logger = createServerLogger({\n level: configuration.LOG_LEVEL,\n standalone: configuration.STANDALONE,\n version: PACKAGE_VERSION,\n });\n\n if (configuration.STANDALONE) {\n printStandaloneStartupBanner({ version: PACKAGE_VERSION, color: shouldColorize() });\n await prepareCodeModeSocketParent({ path: configuration.CODE_MODE_SOCKET_PARENT, logger });\n await ensureLocalSandboxRootParent(configuration.LOCAL_SANDBOX_ROOT_PARENT);\n const { LocalSandboxProvider } = await import('./sandbox/local/provider/LocalSandboxProvider');\n const support = await LocalSandboxProvider.isSupported({\n codeModeSocketParentPath: configuration.CODE_MODE_SOCKET_PARENT,\n });\n setCachedLocalSandboxSupport(support);\n if (support.supported) {\n logger.info('Local sandbox fallback is available', {\n platform: support.platform,\n shell: support.shell,\n python: support.python,\n });\n } else {\n logger.warn('Local sandbox fallback is unavailable', {\n reason: support.reason,\n ...(support.platform === undefined ? {} : { platform: support.platform }),\n ...(support.attempts === undefined ? {} : { attempts: support.attempts }),\n });\n }\n } else {\n logger.info('TrueForge starting', { mode: 'distributed' });\n }\n\n const { activeTurns, app, destroyDb, redis, requestReplyRouter } = configuration.STANDALONE\n ? await createServerRuntime(\n await createStandalonePersistence({ sqlitePath: configuration.SQLITE_PATH, logger }),\n logger,\n )\n : await createServerRuntime(await createDistributedPersistence({ configuration, logger }), logger);\n\n if (mountFrontend(app, configuration.FRONTEND_DIR)) {\n logger.info(`Serving frontend from ${configuration.FRONTEND_DIR}`);\n } else {\n logger.warn(\n `No frontend build at ${configuration.FRONTEND_DIR}: serving the API only. ` +\n 'Run `pnpm --filter frontend build` (and copy via build:frontend-assets) to serve the UI, or `pnpm standalone:dev` / `pnpm dev` for Vite.',\n );\n }\n\n // After createServerApp so every request-reply route is registered before\n // the executor starts consuming messages. The executor needs a dedicated\n // subscriber connection (a subscribed client cannot issue normal commands);\n // this process owns its lifecycle. Connect before init() so init() awaits\n // the initial subscribe + heartbeat — the replica is reachable for peering\n // before the HTTP server starts.\n let requestReplySubscriber: RedisClientType | undefined;\n let requestReplyExecutor: RequestReplyExecutor | undefined;\n if (redis) {\n requestReplySubscriber = redis.duplicate();\n requestReplySubscriber.on('error', (error: Error) => {\n logger.error('[RedisSubscriber] Client error', extractErrorLogFields(error));\n });\n await requestReplySubscriber.connect();\n requestReplyExecutor = new RequestReplyExecutor({\n executorId: configuration.EXECUTOR_ID,\n redis,\n subscriberClient: requestReplySubscriber,\n requestHandler: requestReplyRouter.createRequestHandler(),\n logger,\n options: {\n heartbeatIntervalMs: configuration.REDIS_REQUEST_REPLY_HEARTBEAT_INTERVAL_MS,\n replyTtlMs: configuration.REDIS_REQUEST_REPLY_REPLY_TTL_MS,\n },\n });\n await requestReplyExecutor.init();\n }\n\n const server = serve({ fetch: app.fetch, port: configuration.PORT, hostname: configuration.HOST }, info => {\n logger.info(`Agent server listening on http://${configuration.HOST}:${String(info.port)} (docs at /api/v1/docs)`);\n });\n\n server.on('error', (error: unknown) => {\n console.error('Failed to start server:', error instanceof Error ? error.message : error);\n process.exit(1);\n });\n\n // Graceful drain is the safe default for built and direct execution.\n // Development watch mode opts out so tsx can restart without waiting for a drain.\n if (configuration.NODE_ENV !== 'development') {\n let shuttingDown = false;\n const shutdown = async (signal: NodeJS.Signals) => {\n if (shuttingDown) {\n return;\n }\n shuttingDown = true;\n logger.info(`Received ${signal}, draining connections before shutdown`);\n\n // Arm at the start of each shutdown; unref so this timer alone cannot keep the process alive.\n setTimeout(() => {\n logger.warn(`Drain timed out after ${String(configuration.GRACEFUL_TIMEOUT_SECONDS)}s, exiting`);\n process.exit(1);\n }, configuration.GRACEFUL_TIMEOUT_SECONDS * 1000).unref();\n\n const closed = new Promise<void>(resolve => {\n server.close(() => {\n resolve();\n });\n });\n\n // Sets the registry's shutdown reason immediately so late track() (in-flight create-turn still\n // inside session.createTurn) aborts as Abandoned; then drains the registry. await\n // closed covers the gap where the registry is empty before that late track().\n await activeTurns.shutdownAndWait(CancellationReason.Abandoned);\n await closed;\n // Stop serving peer requests (waits for in-flight replies), then close\n // the clients this process owns: the subscriber duplicate and the primary.\n await requestReplyExecutor?.drain();\n await requestReplySubscriber?.close().catch((error: unknown) => {\n logger.warn('[Redis] Error closing subscriber client during shutdown', extractErrorLogFields(error));\n });\n await redis?.close().catch((error: unknown) => {\n logger.warn('[Redis] Error closing client during shutdown', extractErrorLogFields(error));\n });\n if (configuration.STANDALONE) {\n await removeCodeModeSocketParent(configuration.CODE_MODE_SOCKET_PARENT).catch((error: unknown) => {\n logger.warn('Error removing Code Mode socket parent during shutdown', extractErrorLogFields(error));\n });\n }\n await destroyDb();\n process.exit(0);\n };\n process.on('SIGTERM', signal => {\n void shutdown(signal);\n });\n process.on('SIGINT', signal => {\n void shutdown(signal);\n });\n }\n} catch (error) {\n console.error('Failed to start server:', error instanceof Error ? error.message : error);\n process.exit(1);\n}\n","import { existsSync } from 'node:fs';\nimport { mkdir, rm } from 'node:fs/promises';\nimport type { Logger } from 'winston';\n\nconst SOCKET_PARENT_MODE = 0o700;\n\n/** Exists → warn, then rm + mkdir 0700. Reliability path for leftover UDS files (including watch restarts). */\nexport async function prepareCodeModeSocketParent(params: { path: string; logger: Logger }): Promise<void> {\n if (existsSync(params.path)) {\n params.logger.warn('Removing leftover Code Mode socket parent', { path: params.path });\n await rm(params.path, { recursive: true, force: true });\n }\n await mkdir(params.path, { recursive: true, mode: SOCKET_PARENT_MODE });\n}\n\nexport async function removeCodeModeSocketParent(socketParentPath: string): Promise<void> {\n await rm(socketParentPath, { recursive: true, force: true });\n}\n\nexport async function ensureLocalSandboxRootParent(sandboxRootPathParent: string): Promise<void> {\n await mkdir(sandboxRootPathParent, { recursive: true, mode: SOCKET_PARENT_MODE });\n}\n","/**\n * Process-scoped local-sandbox probe cache. `isSupported()` inits SRT and\n * creates a temp sandbox — run once at standalone boot, never per request.\n */\nimport configuration from '../config';\nimport type { LocalSandboxSupportResult } from './local/provider/LocalSandboxProvider';\n\nlet cachedSupport: LocalSandboxSupportResult | undefined;\n\nexport function setCachedLocalSandboxSupport(support: LocalSandboxSupportResult | undefined): void {\n cachedSupport = support;\n}\n\nexport function getCachedLocalSandboxSupport(): LocalSandboxSupportResult | undefined {\n return cachedSupport;\n}\n\n/** Standalone + cached probe succeeded. No DB row required. */\nexport function isLocalSandboxFallbackEnabled(): boolean {\n return configuration.STANDALONE && cachedSupport?.supported === true;\n}\n","/** The API: resource routers, the OpenAPI document and Swagger UI, all under /api/v1. */\nimport { swaggerUI } from '@hono/swagger-ui';\nimport { OpenAPIHono, z } from '@hono/zod-openapi';\nimport type { ISessionStore, Sessions, TurnStreamingEvent } from '@truefoundry/trueforge-core/agent-session';\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport type { RequestReplyRouter } from '@truefoundry/trueforge-core/request-reply';\nimport type { Context, ErrorHandler, MiddlewareHandler } from 'hono';\nimport { bodyLimit } from 'hono/body-limit';\nimport { HTTPException } from 'hono/http-exception';\nimport type { Configuration } from 'openid-client';\nimport type { RedisClientType } from 'redis';\nimport type { Logger } from 'winston';\nimport { createAgentsRouter } from './apis/agents';\nimport { createAuthRouter } from './apis/auth';\nimport { createCapabilitiesRouter } from './apis/capabilities';\nimport { createCatalogRouter } from './apis/catalog';\nimport { createMcpOAuthRouter } from './apis/mcpOAuth';\nimport { createMcpServersRouter } from './apis/mcpServers';\nimport { createModelsRouter } from './apis/models';\nimport { createSessionsRouter } from './apis/sessions';\nimport { createSettingsRouter } from './apis/settings';\nimport { createAvailableSkillsRouter } from './apis/skills';\nimport { createTurnsRouter } from './apis/turns';\nimport { resolveUserContext } from './auth/identity';\nimport { adminAuthMiddleware, authMiddleware } from './auth/middleware';\nimport type { McpCatalog } from './catalog/McpCatalog';\nimport type { ModelCatalog } from './catalog/ModelCatalog';\nimport type { SandboxCatalog } from './catalog/SandboxCatalog';\nimport type { SkillCatalog } from './catalog/SkillCatalog';\nimport configuration from './config';\nimport type { IAgentStore } from './db/agentStore';\nimport type { IMcpServerStore } from './db/mcpServerStore';\nimport type { IModelProviderStore } from './db/modelProviderStore';\nimport type { ISandboxProviderStore } from './db/sandboxProviderStore';\nimport type { ISkillStore } from './db/skillStore';\nimport type { WithTransaction } from './db/transaction';\nimport type { IOAuthTokenStore } from './mcp/auth/types';\nimport { PACKAGE_VERSION } from './packageVersion';\nimport { OPENAPI_DOCUMENT_TAGS } from './routes/openapiTags';\nimport type { ActiveTurnRegistry } from './runtime/activeTurns';\nimport type { EventSubscriptionRegistry } from './runtime/event-subscription';\nimport { zodErrorResponse, zodValidationHook } from './zodErrorResponse';\n\nconst BEARER_AUTH_SCHEME = 'BearerAuth';\n\n/** Hono bodyLimit wrapper that returns the API error envelope on 413. */\nexport function createRequestBodyLimitMiddleware(maxSize: number): MiddlewareHandler {\n return bodyLimit({\n maxSize,\n onError: c =>\n c.json({ error: { message: `Request body exceeds the maximum size of ${String(maxSize)} bytes` } }, 413),\n });\n}\n\nexport function createAppErrorHandler(params: { logger: Logger }): ErrorHandler {\n return (error, c) => {\n if (error instanceof z.ZodError) {\n return zodErrorResponse(c, error);\n }\n if (error instanceof HTTPException) {\n if (error.status >= 500) {\n params.logger.error('Server API error', {\n status: error.status,\n ...extractErrorLogFields(error),\n });\n }\n return c.json({ error: { message: error.message } }, error.status);\n }\n params.logger.error('Unhandled error', extractErrorLogFields(error));\n return c.json({ error: { message: 'Internal server error' } }, 500);\n };\n}\n\nconst openApiDocConfig = {\n openapi: '3.1.0',\n info: {\n title: 'TrueForge API',\n description:\n 'HTTP API for the TrueForge agent server (`/api/v1`). Interactive docs are served at `/api/v1/docs` ' +\n '(OpenAPI JSON at `/api/v1/openapi.json`).\\n\\n' +\n '**Authentication:** Standalone deployments (no OIDC) accept requests without credentials — middleware ' +\n 'stamps a local default user. When OIDC is configured, protected routes require a valid `id_token` cookie ' +\n 'or `Authorization: Bearer` ID token. There is no built-in API-key scheme; ' +\n 'pass custom headers only if your reverse proxy or IdP layer requires them.\\n\\n' +\n 'Covers DB-backed sessions, the agent registry, settings catalogs, and model/MCP/skill/sandbox providers.',\n version: PACKAGE_VERSION,\n },\n tags: OPENAPI_DOCUMENT_TAGS,\n};\n\n/** Registers the Bearer ID-token scheme used by {@link buildOpenApiDocument}. */\nexport function registerOpenApiBearerAuth(app: OpenAPIHono): void {\n app.openAPIRegistry.registerComponent('securitySchemes', BEARER_AUTH_SCHEME, {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n description:\n 'ID token (`Authorization: Bearer <id_token>`). Required on protected routes. ' +\n 'Browser sessions may use the HttpOnly `id_token` cookie instead.',\n });\n}\n\n/**\n * Single source for both the served document and the one the SDK is built from.\n * When `authEnabled`, advertises required Bearer auth on operations that inherit global security.\n */\nexport function buildOpenApiDocument(app: OpenAPIHono, options?: { authEnabled?: boolean }) {\n const authEnabled = options?.authEnabled ?? false;\n if (authEnabled) {\n registerOpenApiBearerAuth(app);\n }\n return app.getOpenAPI31Document({\n ...openApiDocConfig,\n ...(authEnabled ? { security: [{ [BEARER_AUTH_SCHEME]: [] }] } : {}),\n });\n}\n\nfunction routeNotFound(c: Context) {\n return c.json({ error: { message: `Route not found: ${c.req.method} ${c.req.path}` } }, 404);\n}\n\n/** Sub-app shell: `.use('*', authMiddleware)` then child routes — same as gateway routers. */\nfunction withAuth(router: OpenAPIHono): OpenAPIHono {\n const shell = new OpenAPIHono();\n shell.use('*', authMiddleware);\n shell.route('/', router);\n return shell;\n}\n\n/** Admin-only routes: local admin when auth is disabled; with OIDC requires an authenticated admin. */\nfunction withAdminAuth(router: OpenAPIHono): OpenAPIHono {\n const shell = new OpenAPIHono();\n shell.use('*', adminAuthMiddleware);\n shell.route('/', router);\n return shell;\n}\n\nexport interface ServerDeps<TTransaction> {\n modelCatalog: ModelCatalog;\n mcpCatalog: McpCatalog;\n skillCatalog: SkillCatalog;\n sandboxCatalog: SandboxCatalog;\n modelProviderStore: IModelProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n mcpServerStore: IMcpServerStore<TTransaction>;\n tokenStore: IOAuthTokenStore<TTransaction>;\n skillStore: ISkillStore<TTransaction>;\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n agentStore: IAgentStore<TTransaction>;\n sessionStore: ISessionStore;\n sessions: Sessions;\n activeTurns: ActiveTurnRegistry;\n /** Primary Redis client (server-owned); undefined in standalone mode. */\n redis?: RedisClientType | undefined;\n /** Request-reply dispatch table served by this replica's executor. */\n requestReplyRouter: RequestReplyRouter;\n /** Hands out each turn's resumable event stream to the create and subscribe handlers. */\n eventSubscriptions: EventSubscriptionRegistry<TurnStreamingEvent>;\n logger: Logger;\n /** Discovered openid-client configuration; undefined when browser login is disabled. */\n oidcClient: Configuration | undefined;\n}\n\nexport function createServerApp<TTransaction>(deps: ServerDeps<TTransaction>) {\n const app = new OpenAPIHono({ defaultHook: zodValidationHook });\n const authEnabled = deps.oidcClient != null;\n\n app.use('*', createRequestBodyLimitMiddleware(configuration.MAX_REQUEST_BODY_BYTES));\n\n app.get('/healthz', c => c.text('OK!'));\n\n app.route('/api/v1/auth', createAuthRouter({ oidcClient: deps.oidcClient, logger: deps.logger }));\n app.route(\n '/api/v1/capabilities',\n withAuth(\n createCapabilitiesRouter({\n sandboxProviderStore: deps.sandboxProviderStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n }),\n ),\n );\n app.route(\n '/api/v1/models',\n withAuth(\n createModelsRouter({\n modelProviderStore: deps.modelProviderStore,\n withTransaction: deps.withTransaction,\n }),\n ),\n );\n app.route(\n '/api/v1/catalogs',\n withAuth(\n createCatalogRouter({\n modelCatalog: deps.modelCatalog,\n mcpCatalog: deps.mcpCatalog,\n skillCatalog: deps.skillCatalog,\n sandboxCatalog: deps.sandboxCatalog,\n }),\n ),\n );\n // Public MCP OAuth callback must be registered before the gated `/mcp-servers` mount so\n // `withAuth` cannot intercept IdP redirects to `/api/v1/mcp-servers/oauth/*`.\n app.route(\n '/api/v1/mcp-servers/oauth',\n createMcpOAuthRouter({\n tokenStore: deps.tokenStore,\n mcpServerStore: deps.mcpServerStore,\n logger: deps.logger,\n }),\n );\n app.route(\n '/api/v1/mcp-servers',\n withAuth(\n createMcpServersRouter({\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n resolveUserContext,\n }),\n ),\n );\n app.route(\n '/api/v1/skills',\n withAuth(\n createAvailableSkillsRouter({\n skillStore: deps.skillStore,\n withTransaction: deps.withTransaction,\n }),\n ),\n );\n app.route(\n '/api/v1/agents',\n withAuth(\n createAgentsRouter({\n agentStore: deps.agentStore,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n withTransaction: deps.withTransaction,\n }),\n ),\n );\n app.route(\n '/api/v1/settings',\n withAdminAuth(\n createSettingsRouter({\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n resolveUserContext,\n }),\n ),\n );\n app.route(\n '/api/v1/sessions',\n withAuth(\n createSessionsRouter({\n sessions: deps.sessions,\n sessionStore: deps.sessionStore,\n activeTurns: deps.activeTurns,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n agentStore: deps.agentStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n redis: deps.redis,\n requestReplyRouter: deps.requestReplyRouter,\n resolveUserContext: resolveUserContext,\n logger: deps.logger,\n }),\n ),\n );\n app.route(\n '/api/v1/sessions',\n withAuth(\n createTurnsRouter({\n sessions: deps.sessions,\n sessionStore: deps.sessionStore,\n activeTurns: deps.activeTurns,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n skillStore: deps.skillStore,\n agentStore: deps.agentStore,\n eventSubscriptions: deps.eventSubscriptions,\n sandboxProviderStore: deps.sandboxProviderStore,\n logger: deps.logger,\n resolveUserContext: resolveUserContext,\n }),\n ),\n );\n\n app.get('/api/v1/docs', swaggerUI({ url: '/api/v1/openapi.json' }));\n app.get('/api/v1/openapi.json', c => c.json(buildOpenApiDocument(app, { authEnabled })));\n\n app.notFound(routeNotFound);\n\n app.onError(createAppErrorHandler({ logger: deps.logger }));\n\n return app;\n}\n","/**\n * DB-backed agent registry API (mounted at /api/v1/agents).\n */\nimport { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport { AgentNameConflictError, type AgentRecord, type IAgentStore } from '../db/agentStore';\nimport type { IMcpServerStore } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport type { WithTransaction } from '../db/transaction';\nimport {\n createAgentRoute,\n deleteAgentRoute,\n getAgentRoute,\n listAgentsRoute,\n putAgentRoute,\n} from '../routes/agentRoutes';\nimport { validateAgentSpec } from '../runtime/sessionResources';\nimport { type Agent, type CreateAgentRequest } from '../schemas/agent';\nimport { TENANT_ID } from './sessions';\n\nexport interface AgentsRouterDeps<TTransaction> {\n agentStore: IAgentStore<TTransaction>;\n modelProviderStore: IModelProviderStore<TTransaction>;\n mcpServerStore: IMcpServerStore<TTransaction>;\n skillStore: ISkillStore<TTransaction>;\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}\n\n/** Wire view: identity columns plus nested manifest. */\nfunction toWireAgent(record: AgentRecord): Agent {\n return {\n id: record.id,\n name: record.name,\n manifest: record.manifest,\n };\n}\n\nasync function validateManifest<TTransaction>({\n spec,\n deps,\n}: {\n spec: AgentSpec;\n deps: AgentsRouterDeps<TTransaction>;\n}): Promise<AgentSpec> {\n await validateAgentSpec({\n spec,\n tenant_id: TENANT_ID,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n });\n return spec;\n}\n\nexport function createAgentsRouter<TTransaction>(deps: AgentsRouterDeps<TTransaction>) {\n const listHandler: RouteHandler<typeof listAgentsRoute> = async c => {\n const records = await deps.agentStore.listAgents(TENANT_ID);\n return c.json({ data: records.map(toWireAgent) }, 200);\n };\n\n const createHandler: RouteHandler<typeof createAgentRoute> = async c => {\n const body: CreateAgentRequest = c.req.valid('json');\n const manifest = await validateManifest({ spec: body.manifest, deps });\n try {\n const record = await deps.agentStore.createAgent({\n tenant_id: TENANT_ID,\n name: body.name,\n manifest,\n });\n return c.json({ data: toWireAgent(record) }, 201);\n } catch (error) {\n if (error instanceof AgentNameConflictError) {\n return c.json({ error: { message: error.message } }, 409);\n }\n throw error;\n }\n };\n\n const getHandler: RouteHandler<typeof getAgentRoute> = async c => {\n const { agent_id: agentId } = c.req.valid('param');\n const record = await deps.agentStore.getAgent({ tenant_id: TENANT_ID, id: agentId });\n if (record === undefined) {\n return c.json({ error: { message: `Agent not found: ${agentId}` } }, 404);\n }\n return c.json({ data: toWireAgent(record) }, 200);\n };\n\n const deleteHandler: RouteHandler<typeof deleteAgentRoute> = async c => {\n const { agent_id: agentId } = c.req.valid('param');\n await deps.agentStore.deleteAgent({ tenant_id: TENANT_ID, id: agentId });\n return c.json({}, 200);\n };\n\n const putHandler: RouteHandler<typeof putAgentRoute> = async c => {\n const { agent_id: agentId } = c.req.valid('param');\n const body = c.req.valid('json');\n const manifest = await validateManifest({ spec: body.manifest, deps });\n const record = await deps.agentStore.updateAgent({\n tenant_id: TENANT_ID,\n id: agentId,\n manifest,\n });\n if (record === undefined) {\n return c.json({ error: { message: `Agent not found: ${agentId}` } }, 404);\n }\n return c.json({ data: toWireAgent(record) }, 200);\n };\n\n const router = new OpenAPIHono();\n router.openapi(listAgentsRoute, listHandler);\n router.openapi(createAgentRoute, createHandler);\n router.openapi(getAgentRoute, getHandler);\n router.openapi(deleteAgentRoute, deleteHandler);\n router.openapi(putAgentRoute, putHandler);\n return router;\n}\n","/**\n * Agent registry route definitions (mounted at /api/v1/agents).\n * Handlers are registered in apis/agents.ts.\n */\nimport { createRoute, z } from '@hono/zod-openapi';\nimport {\n CreateAgentRequestSchema,\n DeleteAgentResponseSchema,\n GetAgentResponseSchema,\n ListAgentsResponseSchema,\n UpdateAgentRequestSchema,\n} from '../schemas/agent';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { OpenApiTag } from './openapiTags';\n\nexport const AgentIdParamsSchema = z.object({\n agent_id: z.string().min(1).max(64).describe('Immutable agent identifier.'),\n});\n\nexport const listAgentsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.AGENTS],\n summary: 'List agents',\n description: 'All configured agents for the tenant.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListAgentsResponseSchema } },\n description: 'All configured agents.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n\nexport const createAgentRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [OpenApiTag.AGENTS],\n summary: 'Create an agent',\n description:\n 'Creates an agent and allocates an immutable id. Fails if `name` is already taken. Name cannot be changed later.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateAgentRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetAgentResponseSchema } },\n description: 'The created agent.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body or unknown model/MCP/skill refs.',\n },\n 409: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'An agent with this name already exists.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'The agent spec is valid but requires a capability this server does not provide (e.g. sandbox or skills).',\n },\n },\n});\n\nexport const getAgentRoute = createRoute({\n method: 'get',\n path: '/{agent_id}',\n tags: [OpenApiTag.AGENTS],\n summary: 'Get an agent',\n description: 'Fetch a configured agent by immutable id.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'get',\n request: {\n params: AgentIdParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetAgentResponseSchema } },\n description: 'The agent.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Agent not found.',\n },\n },\n});\n\nexport const deleteAgentRoute = createRoute({\n method: 'delete',\n path: '/{agent_id}',\n tags: [OpenApiTag.AGENTS],\n summary: 'Delete an agent',\n description: 'Delete a configured agent by immutable id. Idempotent if already gone.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'delete',\n request: {\n params: AgentIdParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: DeleteAgentResponseSchema } },\n description: 'Agent deleted.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n\nexport const putAgentRoute = createRoute({\n method: 'put',\n path: '/{agent_id}',\n tags: [OpenApiTag.AGENTS],\n summary: 'Update an agent',\n description: 'Replaces the manifest for an existing agent keyed by immutable `agent_id`.',\n 'x-fern-sdk-group-name': ['agents'],\n 'x-fern-sdk-method-name': 'update',\n request: {\n params: AgentIdParamsSchema,\n body: {\n content: { 'application/json': { schema: UpdateAgentRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetAgentResponseSchema } },\n description: 'The saved agent.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body or unknown model/MCP/skill refs.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Agent not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'The agent spec is valid but requires a capability this server does not provide (e.g. sandbox or skills).',\n },\n },\n});\n","/**\n * Configured agent domain + wire schemas: identity columns plus a nested\n * AgentSpec document (JSON key `manifest`).\n */\nimport { z } from '@hono/zod-openapi';\nimport { AgentSpecSchema } from '@truefoundry/trueforge-core/agent-session';\nimport { NameSchema } from './common';\n\n/** Create body: unique immutable `name` plus manifest. `id` is never client-supplied. */\nexport const CreateAgentRequestSchema = z\n .object({\n name: NameSchema,\n manifest: AgentSpecSchema,\n })\n .strict()\n .openapi('CreateAgentRequest');\n\n/** PUT body: full manifest replacement. Identity is the path `agent_id`. */\nexport const UpdateAgentRequestSchema = z\n .object({\n manifest: AgentSpecSchema,\n })\n .strict()\n .openapi('UpdateAgentRequest');\n\n/** List/get/create/update response item: identity columns plus nested manifest. */\nexport const AgentSchema = z\n .object({\n id: z.string().min(1).describe('Immutable server-generated agent identifier.'),\n name: NameSchema,\n manifest: AgentSpecSchema,\n })\n .strict()\n .openapi('Agent');\n\nexport const GetAgentResponseSchema = z.object({ data: AgentSchema }).openapi('GetAgentResponse');\nexport const ListAgentsResponseSchema = z.object({ data: z.array(AgentSchema) }).openapi('ListAgentsResponse');\nexport const DeleteAgentResponseSchema = z.object({}).openapi('DeleteAgentResponse');\n\nexport type CreateAgentRequest = z.infer<typeof CreateAgentRequestSchema>;\nexport type UpdateAgentRequest = z.infer<typeof UpdateAgentRequestSchema>;\nexport type Agent = z.infer<typeof AgentSchema>;\n","/**\n * Server-wide shared Zod field schemas and refinements.\n */\nimport { z } from '@hono/zod-openapi';\n\n/**\n * Lowercase name, 2–64 chars: starts with a letter, ends with alphanumeric,\n * may contain \".\", \"_\" or \"-\" in between (aligned with SF model-integration names).\n */\nexport const NameSchema = z\n .string()\n .min(2)\n .max(64)\n .regex(\n /^[a-z](?:[a-z0-9._-]{0,62}[a-z0-9])$/,\n 'must be 2–64 lowercase chars: start with a letter, end with alphanumeric, optionally separated by \".\", \"_\" or \"-\"',\n )\n .openapi('ResourceName');\n\nexport type ResourceName = z.infer<typeof NameSchema>;\n\n/** Sessions and turns list page size (default = max). */\nexport const PAGE_LIMIT = 25;\n/** Session/turn event list page size (default = max). */\nexport const EVENTS_PAGE_LIMIT = 100;\n\n/** Adds a validation issue if two entries share a name. */\nexport function uniqueNames(entries: { name: string }[], ctx: z.RefinementCtx): void {\n const seen = new Set<string>();\n for (const entry of entries) {\n if (seen.has(entry.name)) {\n ctx.addIssue({\n code: 'custom',\n message: `Duplicate name \"${entry.name}\" — names must be unique`,\n });\n }\n seen.add(entry.name);\n }\n}\n\n/** Adds a validation issue if two entries share a type. */\nexport function uniqueTypes(entries: { type: string }[], ctx: z.RefinementCtx): void {\n const seen = new Set<string>();\n for (const entry of entries) {\n if (seen.has(entry.type)) {\n ctx.addIssue({\n code: 'custom',\n message: `Duplicate type \"${entry.type}\" — types must be unique`,\n });\n }\n seen.add(entry.type);\n }\n}\n","/** Error response wire schema. */\nimport { z } from '@hono/zod-openapi';\n\nexport const RequestErrorResponseSchema = z\n .object({\n error: z.object({\n message: z.string().describe('Human-readable explanation of the failure.'),\n type: z.string().optional().describe('Optional error category (e.g. validation vs conflict).'),\n code: z\n .string()\n .nullable()\n .optional()\n .describe('Optional machine-readable error code; null when not applicable.'),\n param: z\n .string()\n .nullable()\n .optional()\n .describe('Optional request field that caused the error; null when not field-specific.'),\n }),\n })\n .openapi('RequestErrorResponse');\n\nexport type RequestErrorResponse = z.infer<typeof RequestErrorResponseSchema>;\n","/** Mintlify API Reference groups — the only OpenAPI `tags` values. */\nexport enum OpenApiTag {\n AUTH = 'Auth',\n CAPABILITIES = 'Capabilities',\n MODELS = 'Models',\n MCP_SERVERS = 'MCP Servers',\n SKILLS = 'Skills',\n SANDBOXES = 'Sandboxes',\n AGENTS = 'Agents',\n AGENT_SESSIONS = 'Agent Sessions',\n}\n\n/** Document-level tag order for `/api/v1/docs` and Mintlify. */\nexport const OPENAPI_DOCUMENT_TAGS: { name: OpenApiTag }[] = [\n { name: OpenApiTag.AUTH },\n { name: OpenApiTag.CAPABILITIES },\n { name: OpenApiTag.MODELS },\n { name: OpenApiTag.MCP_SERVERS },\n { name: OpenApiTag.SKILLS },\n { name: OpenApiTag.SANDBOXES },\n { name: OpenApiTag.AGENTS },\n { name: OpenApiTag.AGENT_SESSIONS },\n];\n","/**\n * Store-backed model/MCP/skill/sandbox resolution for session admit and turns.\n */\nimport type { AgentSpec } from '@truefoundry/trueforge-core/agent-session';\nimport {\n Sandbox,\n SkillMounter,\n type AgentTracing,\n type GitSkill,\n type ModelParams,\n type RemoteMcpHeaders,\n type SandboxProvider,\n type VercelAIProviderConfig,\n} from '@truefoundry/trueforge-core/core';\nimport { HTTPException } from 'hono/http-exception';\nimport { join } from 'node:path';\nimport type { Logger } from 'winston';\nimport configuration from '../config';\nimport type { IMcpServerStore, McpServerRecord } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport { isMcpAuthRequired, resolveMcpAuth } from '../mcp/auth/mcpDcr';\nimport type { IOAuthTokenStore } from '../mcp/auth/types';\nimport { LocalSandboxProvider } from '../sandbox/local/provider/LocalSandboxProvider';\nimport { getCachedLocalSandboxSupport, isLocalSandboxFallbackEnabled } from '../sandbox/localRuntime';\nimport { toDaytonaSandboxProvider } from '../sandbox/providerUtils';\nimport { resolveConfiguredMcpRequestHeaders } from '../schemas/mcpServer';\n\nexport interface McpConnection {\n url: string;\n headers: RemoteMcpHeaders;\n}\n\n/** Split `provider/model` FQN. Returns undefined when the shape is not exactly one slash. */\nexport function parseModelFqn(name: string): { providerName: string; modelName: string } | undefined {\n const slash = name.indexOf('/');\n if (slash <= 0 || slash === name.length - 1) {\n return undefined;\n }\n if (name.includes('/', slash + 1)) {\n return undefined;\n }\n return { providerName: name.slice(0, slash), modelName: name.slice(slash + 1) };\n}\n\n/**\n * Load turn-ready model config and defaults for a configured FQN (`provider/model`).\n * Malformed FQN or missing provider/model → HTTPException(422).\n */\nexport async function getModelDetails({\n tenant_id,\n name,\n store,\n}: {\n tenant_id: string;\n name: string;\n store: IModelProviderStore;\n}): Promise<{\n providerConfig: VercelAIProviderConfig;\n defaultModelParams: ModelParams;\n}> {\n const parsed = parseModelFqn(name);\n if (parsed === undefined) {\n throw new HTTPException(422, {\n message: `Model name must be a fully qualified \"provider/model\": ${name}`,\n });\n }\n const provider = await store.getProvider({ tenant_id, name: parsed.providerName });\n if (provider === undefined) {\n throw new HTTPException(422, {\n message: `Unknown model \"${name}\" — provider not configured`,\n });\n }\n const model = provider.manifest.models.find(entry => entry.name === parsed.modelName);\n if (model === undefined) {\n throw new HTTPException(422, {\n message: `Unknown model \"${name}\" — not configured on provider`,\n });\n }\n // Provider types are adapter names, so this assignment is what keeps them so: a type with no\n // `buildLanguageModel` case fails to compile here.\n const { type, base_url } = provider.manifest;\n return {\n providerConfig: {\n provider: { type, name: provider.name },\n model: { id: model.model_id, name: model.name },\n name,\n baseUrl: base_url,\n // Custom providers may omit auth; adapters still require a string.\n apiKey: provider.manifest.auth?.api_key ?? '',\n headers: {},\n },\n defaultModelParams: model.properties.max_output_tokens ? { max_tokens: model.properties.max_output_tokens } : {},\n };\n}\n\nfunction dcrHeadersResolver(params: {\n record: McpServerRecord;\n tokenStore: IOAuthTokenStore;\n mcpServerStore: IMcpServerStore;\n clientName: string;\n userRef: string;\n}): RemoteMcpHeaders {\n const { record, tokenStore, mcpServerStore, clientName, userRef } = params;\n return async () => {\n const result = await resolveMcpAuth({\n tokenStore,\n mcpServerStore,\n serverId: record.id,\n userRef,\n mcpServerUrl: record.manifest.url,\n mcpServerName: record.name,\n clientName,\n });\n if (isMcpAuthRequired(result)) {\n // Wire `id` must match RemoteMCP.id (AgentSpec name), not the DB row ULID —\n // init events, tool-call metadata, and snapshots all key by name.\n return {\n authRequired: {\n servers: [{ id: record.name, name: record.name, auth_url: result.authUrl.href }],\n },\n };\n }\n return { headers: result.headers };\n };\n}\n\n/**\n * Load MCP url + headers for a configured server.\n * DCR uses resolveMcpAuth; header / no-auth use resolveConfiguredMcpRequestHeaders.\n * Returns undefined when the server is not registered — callers choose the response.\n */\nexport async function getMcpConnection({\n tenant_id,\n name,\n store,\n tokenStore,\n clientName,\n userRef,\n}: {\n tenant_id: string;\n name: string;\n store: IMcpServerStore;\n tokenStore: IOAuthTokenStore;\n clientName: string;\n userRef: string;\n}): Promise<McpConnection | undefined> {\n const record = await store.getServer({ tenant_id, name });\n if (record === undefined) {\n return undefined;\n }\n if (record.manifest.auth?.type === 'dcr') {\n return {\n url: record.manifest.url,\n headers: dcrHeadersResolver({\n record,\n tokenStore,\n mcpServerStore: store,\n clientName,\n userRef,\n }),\n };\n }\n return {\n url: record.manifest.url,\n headers: resolveConfiguredMcpRequestHeaders(record.manifest),\n };\n}\n\n/**\n * Expand agent_spec skill names into git mounts from the skill store.\n * Wire url/path/ref/description on the request are ignored — the store row wins.\n * Throws HTTPException(422) if any name is not registered.\n */\nexport async function resolveGitSkills({\n tenant_id,\n skills,\n store,\n}: {\n tenant_id: string;\n skills: readonly { name: string }[];\n store: ISkillStore;\n}): Promise<GitSkill[]> {\n if (skills.length === 0) {\n return [];\n }\n const names = skills.map(skill => skill.name);\n const records = await store.listSkills({ tenant_id, names });\n const byName = new Map(records.map(record => [record.name, record]));\n const resolved: GitSkill[] = [];\n for (const skill of skills) {\n const record = byName.get(skill.name);\n if (record === undefined) {\n throw new HTTPException(422, {\n message: `Unknown skill \"${skill.name}\" — not configured`,\n });\n }\n resolved.push({\n name: record.manifest.name,\n description: record.manifest.description,\n url: record.manifest.url,\n path: record.manifest.path ?? '',\n ref: record.manifest.ref,\n });\n }\n return resolved;\n}\n\n/**\n * Build a runtime SandboxProvider from the configured store row, or the\n * in-memory local fallback when standalone + the cached probe is supported.\n * Builds a fresh Daytona client per call (no network I/O).\n */\n/** Single path segment under the sandboxes parent (`_` when sessionId is missing or unsafe). */\nexport function localSandboxSessionSegment(sessionId: string | undefined): string {\n if (sessionId === undefined || sessionId.length === 0 || sessionId.includes('/') || sessionId.includes('..')) {\n return '_';\n }\n return sessionId;\n}\n\nexport async function resolveSandboxProvider({\n tenant_id,\n store,\n logger,\n sessionId,\n}: {\n tenant_id: string;\n store: ISandboxProviderStore;\n logger: Logger;\n sessionId: string;\n}): Promise<SandboxProvider | undefined> {\n const record = await store.getSandboxProvider(tenant_id);\n if (record !== undefined) {\n // Clone from the snapshot that was actually built (persisted build_ref), not a name\n // derived from the current image — otherwise an image bump breaks creation until rebuild.\n return toDaytonaSandboxProvider({\n manifest: record.manifest,\n tenant_id,\n logger,\n build_metadata: record.build_metadata,\n });\n }\n if (!configuration.STANDALONE) {\n return undefined;\n }\n const support = getCachedLocalSandboxSupport();\n if (support?.supported !== true) {\n return undefined;\n }\n return new LocalSandboxProvider({\n sandboxRootPathParent: join(configuration.LOCAL_SANDBOX_ROOT_PARENT, localSandboxSessionSegment(sessionId)),\n codeModeSocketParentPath: configuration.CODE_MODE_SOCKET_PARENT,\n support,\n fileMaxBytesForDownload: configuration.SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD,\n logger,\n });\n}\n\n/**\n * Builds a Sandbox for one turn from a resolved provider and git mounts.\n */\nexport function buildTurnSandbox(input: {\n provider: SandboxProvider;\n logger: Logger;\n gitSkills: readonly GitSkill[];\n fileDownloadEnabled: boolean;\n existingSandboxId?: string | undefined;\n tracing: AgentTracing;\n}): Sandbox {\n const skillMounter = input.gitSkills.length > 0 ? new SkillMounter([...input.gitSkills]) : undefined;\n return new Sandbox({\n provider: input.provider,\n existingSandboxId: input.existingSandboxId,\n fileDownloadEnabled: input.fileDownloadEnabled,\n blockDestructiveToolsInCodeMode: true,\n mcpRequestTimeoutMs: configuration.MCP_REQUEST_TIMEOUT_MS,\n mcpConnectTimeoutMs: configuration.MCP_CONNECT_TIMEOUT_MS,\n ...(skillMounter ? { skillMounter } : {}),\n tracing: input.tracing,\n logger: input.logger,\n });\n}\n\n/**\n * Cross-checks an AgentSpec against configured models / MCP / skills and\n * sandbox capability. Throws HTTPException(422) for semantic failures.\n * Skills are admitted by name only; mounts expand at turn time.\n */\nexport async function validateAgentSpec({\n spec,\n tenant_id,\n modelProviderStore,\n mcpServerStore,\n skillStore,\n sandboxProviderStore,\n}: {\n spec: AgentSpec;\n tenant_id: string;\n modelProviderStore: IModelProviderStore;\n mcpServerStore: IMcpServerStore;\n skillStore: ISkillStore;\n sandboxProviderStore: ISandboxProviderStore;\n}): Promise<void> {\n const parsed = parseModelFqn(spec.model.name);\n if (parsed === undefined) {\n throw new HTTPException(422, {\n message: `Model name must be a fully qualified \"provider/model\": ${spec.model.name}`,\n });\n }\n const provider = await modelProviderStore.getProvider({ tenant_id, name: parsed.providerName });\n if (provider === undefined) {\n throw new HTTPException(422, {\n message: `Unknown model \"${spec.model.name}\" — provider not configured`,\n });\n }\n const model = provider.manifest.models.find(entry => entry.name === parsed.modelName);\n if (model === undefined) {\n throw new HTTPException(422, {\n message: `Unknown model \"${spec.model.name}\" — not configured on provider`,\n });\n }\n const reasoningEffort = spec.model.params?.reasoning_effort;\n if (reasoningEffort !== undefined) {\n const efforts = model.properties.reasoning_efforts;\n if (!efforts?.some(effort => effort === reasoningEffort)) {\n throw new HTTPException(422, {\n message: efforts\n ? `Reasoning effort \"${reasoningEffort}\" is not supported by model \"${spec.model.name}\"`\n : `Model \"${spec.model.name}\" does not support configurable reasoning effort`,\n });\n }\n }\n\n const requestedMcpServers = spec.mcp_servers ?? [];\n if (requestedMcpServers.length > 0) {\n const names = requestedMcpServers.map(server => server.name);\n const configuredNames = new Set(\n (await mcpServerStore.listServers({ tenant_id, names })).map(record => record.name),\n );\n const unknown = requestedMcpServers.find(server => !configuredNames.has(server.name));\n if (unknown !== undefined) {\n throw new HTTPException(422, {\n message: `Unknown MCP server \"${unknown.name}\" — not configured`,\n });\n }\n }\n\n const requestedSkills = spec.skills ?? [];\n if (requestedSkills.length > 0) {\n const names = requestedSkills.map(skill => skill.name);\n const configuredNames = new Set((await skillStore.listSkills({ tenant_id, names })).map(record => record.name));\n const unknown = requestedSkills.find(skill => !configuredNames.has(skill.name));\n if (unknown !== undefined) {\n throw new HTTPException(422, {\n message: `Unknown skill \"${unknown.name}\" — not configured`,\n });\n }\n }\n\n const wantsSandbox = spec.config.sandbox.enabled;\n const hasSkills = requestedSkills.length > 0;\n if (wantsSandbox || hasSkills) {\n const record = await sandboxProviderStore.getSandboxProvider(tenant_id);\n if (record === undefined && !isLocalSandboxFallbackEnabled()) {\n throw new HTTPException(422, {\n message: hasSkills\n ? 'skills require a sandbox provider — configure via PUT /settings/sandbox-providers'\n : 'sandbox is enabled but no sandbox provider is configured — PUT /settings/sandbox-providers',\n });\n }\n }\n}\n","import {\n discoverOAuthServerInfo,\n exchangeAuthorization,\n refreshAuthorization,\n registerClient,\n startAuthorization,\n} from '@modelcontextprotocol/sdk/client/auth.js';\nimport { InvalidClientError, InvalidClientMetadataError } from '@modelcontextprotocol/sdk/server/auth/errors.js';\nimport { resourceUrlFromServerUrl } from '@modelcontextprotocol/sdk/shared/auth-utils.js';\nimport type {\n AuthorizationServerMetadata,\n OAuthClientMetadata,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/shared/auth.js';\nimport type { FetchLike } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport { McpConnectionError, McpDcrConfigurationError } from '@truefoundry/trueforge-core/core';\nimport { randomBytes } from 'node:crypto';\nimport {\n isOAuthAccessTokenUsable,\n mcpAuthorizationServerMetadata,\n mcpAuthorizationServerOrigin,\n mcpClientInformation,\n mcpOAuthCallbackUrl,\n oauthTokensToOAuthToken,\n} from './mcpOAuthHelpers';\nimport type {\n IOAuthClientStore,\n IOAuthTokenStore,\n McpAuthRequiredResult,\n OAuthClientRecord,\n OAuthPendingAuthorization,\n ResolveMcpAuthResult,\n} from './types';\n\n/** Per-request timeout for MCP OAuth discovery, DCR, and token HTTP calls. */\nexport const MCP_OAUTH_HTTP_TIMEOUT_MS = 15_000;\n\n/**\n * Abort hung authorization-server HTTP. Merges with any caller `signal` so both can cancel the request.\n * Used by discoverOAuthServerInfo / registerClient / refreshAuthorization / exchangeAuthorization\n * (startAuthorization is local PKCE + URL construction and never calls this).\n */\nconst mcpOAuthFetch: FetchLike = (url, init) => {\n const timeoutSignal = AbortSignal.timeout(MCP_OAUTH_HTTP_TIMEOUT_MS);\n const signal = init?.signal != null ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;\n return fetch(url, { ...init, signal });\n};\n\nfunction isTimeoutError(error: unknown): boolean {\n return error instanceof Error && error.name === 'TimeoutError';\n}\n\n/** Same status as non-timeout faults; appends a timeout note so the API body is actionable. */\nfunction mcpOAuthConnectionError(message: string, error: unknown, statusCode: number): McpConnectionError {\n let body = message;\n if (isTimeoutError(error)) {\n body = `${message}: timed out after ${String(MCP_OAUTH_HTTP_TIMEOUT_MS / 1000)}s waiting for the authorization server`;\n }\n return new McpConnectionError(body, statusCode, { cause: error });\n}\n\nexport function isMcpAuthRequired(result: ResolveMcpAuthResult): result is McpAuthRequiredResult {\n return 'authUrl' in result;\n}\n\nasync function registerMcpClientWithAuthMethodFallback(params: {\n authorizationServerUrl: string;\n metadata: AuthorizationServerMetadata;\n clientMetadata: OAuthClientMetadata;\n mcpServerName: string;\n authorizationEndpoint: string;\n tokenEndpoint: string;\n}): Promise<OAuthClientRecord> {\n const { authorizationServerUrl, metadata, clientMetadata, mcpServerName, authorizationEndpoint, tokenEndpoint } =\n params;\n let fullInfo;\n try {\n fullInfo = await registerClient(authorizationServerUrl, {\n metadata,\n clientMetadata: { ...clientMetadata, token_endpoint_auth_method: 'client_secret_post' },\n fetchFn: mcpOAuthFetch,\n });\n } catch (firstError: unknown) {\n if (!(firstError instanceof InvalidClientMetadataError)) {\n throw mcpOAuthConnectionError(\n `Failed to dynamically register OAuth client for MCP server '${mcpServerName}'`,\n firstError,\n 424,\n );\n }\n try {\n fullInfo = await registerClient(authorizationServerUrl, {\n metadata,\n clientMetadata,\n fetchFn: mcpOAuthFetch,\n });\n } catch (secondError: unknown) {\n throw mcpOAuthConnectionError(\n `Failed to dynamically register OAuth client for MCP server '${mcpServerName}'`,\n secondError,\n 424,\n );\n }\n }\n if (!fullInfo.client_id) {\n throw new McpConnectionError(\n `Authorization server for MCP server '${mcpServerName}' returned a client response without client_id`,\n 424,\n );\n }\n return {\n server: {\n authorizationEndpoint,\n tokenEndpoint,\n codeChallengeMethodsSupported: metadata.code_challenge_methods_supported ?? null,\n },\n client: {\n clientId: fullInfo.client_id,\n clientSecret: fullInfo.client_secret ?? null,\n },\n };\n}\n\n/**\n * Discovers the MCP server's authorization server, validates DCR + S256 PKCE support, and\n * registers a new OAuth client (RFC 7591). Returns AS endpoints + client credentials for the\n * caller to persist; does not write to the store.\n */\nexport async function createMcpOAuthClient(params: {\n mcpServerUrl: string;\n mcpServerName: string;\n redirectUri: string;\n clientName: string;\n}): Promise<OAuthClientRecord> {\n const { mcpServerUrl, mcpServerName, redirectUri, clientName } = params;\n let discovered: Awaited<ReturnType<typeof discoverOAuthServerInfo>>;\n try {\n discovered = await discoverOAuthServerInfo(mcpServerUrl, { fetchFn: mcpOAuthFetch });\n } catch (error: unknown) {\n throw mcpOAuthConnectionError(\n `Failed to discover OAuth authorization server for MCP server '${mcpServerName}'`,\n error,\n 424,\n );\n }\n const { authorizationServerUrl, authorizationServerMetadata: metadata } = discovered;\n if (!metadata?.registration_endpoint) {\n throw new McpDcrConfigurationError(\n `MCP server '${mcpServerName}' has no DCR support (missing registration_endpoint); auth.type: dcr is misconfigured for this server`,\n );\n }\n if (!metadata.authorization_endpoint || !metadata.token_endpoint) {\n throw new McpDcrConfigurationError(\n `Authorization server for MCP server '${mcpServerName}' is missing authorization_endpoint or token_endpoint`,\n );\n }\n const pkceMethods = metadata.code_challenge_methods_supported;\n if (pkceMethods && !pkceMethods.includes('S256')) {\n throw new McpDcrConfigurationError(\n `Authorization server for MCP server '${mcpServerName}' advertises PKCE methods without S256`,\n );\n }\n return registerMcpClientWithAuthMethodFallback({\n authorizationServerUrl,\n metadata,\n clientMetadata: {\n client_name: clientName,\n redirect_uris: [redirectUri],\n grant_types: ['authorization_code', 'refresh_token'],\n response_types: ['code'],\n },\n mcpServerName,\n authorizationEndpoint: metadata.authorization_endpoint,\n tokenEndpoint: metadata.token_endpoint,\n });\n}\n\n/**\n * Returns the stored OAuth client for `serverId`, or discovers + DCR-registers and persists one.\n * Used from `resolveMcpAuth` only — callers that already hold the client should pass it through.\n */\nexport async function ensureMcpClientRegistered(params: {\n mcpServerStore: IOAuthClientStore;\n serverId: string;\n mcpServerUrl: string;\n mcpServerName: string;\n clientName: string;\n}): Promise<OAuthClientRecord> {\n const existing = await params.mcpServerStore.getClient({ id: params.serverId });\n if (existing) {\n return existing;\n }\n const client = await createMcpOAuthClient({\n mcpServerUrl: params.mcpServerUrl,\n mcpServerName: params.mcpServerName,\n redirectUri: mcpOAuthCallbackUrl(),\n clientName: params.clientName,\n });\n await params.mcpServerStore.saveClient({ id: params.serverId, record: client });\n return client;\n}\n\n/** Builds the AS authorize URL and saves the pending PKCE row. Caller must already have `client`. */\nexport async function buildMcpAuthorizationUrl(params: {\n tokenStore: IOAuthTokenStore;\n client: OAuthClientRecord;\n serverId: string;\n userRef: string;\n mcpServerUrl: string;\n mcpServerName: string;\n returnTo?: string;\n}): Promise<URL> {\n const state = randomBytes(32).toString('base64url');\n const redirectUri = mcpOAuthCallbackUrl();\n let started: Awaited<ReturnType<typeof startAuthorization>>;\n try {\n started = await startAuthorization(mcpAuthorizationServerOrigin(params.client.server), {\n metadata: mcpAuthorizationServerMetadata(params.client.server),\n clientInformation: mcpClientInformation(params.client.client),\n redirectUrl: redirectUri,\n resource: resourceUrlFromServerUrl(params.mcpServerUrl),\n state,\n });\n } catch (error: unknown) {\n throw new McpConnectionError(`Failed to start OAuth authorization for MCP server '${params.mcpServerName}'`, 424, {\n cause: error,\n });\n }\n await params.tokenStore.savePendingAuthorization({\n state,\n id: params.serverId,\n userRef: params.userRef,\n mcpServerUrl: params.mcpServerUrl,\n codeVerifier: started.codeVerifier,\n returnTo: params.returnTo ?? null,\n });\n return started.authorizationUrl;\n}\n\nexport async function resolveMcpAuth(params: {\n tokenStore: IOAuthTokenStore;\n mcpServerStore: IOAuthClientStore;\n serverId: string;\n userRef: string;\n mcpServerUrl: string;\n mcpServerName: string;\n clientName: string;\n returnTo?: string;\n}): Promise<ResolveMcpAuthResult> {\n const nowMs = Date.now();\n const tokenKey = { id: params.serverId, userRef: params.userRef };\n const token = await params.tokenStore.getToken(tokenKey);\n if (token && isOAuthAccessTokenUsable(token.expiresAt, nowMs)) {\n return { headers: { Authorization: `Bearer ${token.accessToken}` } };\n }\n const client = await ensureMcpClientRegistered({\n mcpServerStore: params.mcpServerStore,\n serverId: params.serverId,\n mcpServerUrl: params.mcpServerUrl,\n mcpServerName: params.mcpServerName,\n clientName: params.clientName,\n });\n if (token?.refreshToken) {\n try {\n const refreshed = await refreshAuthorization(mcpAuthorizationServerOrigin(client.server), {\n metadata: mcpAuthorizationServerMetadata(client.server),\n clientInformation: mcpClientInformation(client.client),\n refreshToken: token.refreshToken,\n resource: resourceUrlFromServerUrl(params.mcpServerUrl),\n fetchFn: mcpOAuthFetch,\n });\n const saved = oauthTokensToOAuthToken(refreshed, nowMs, token.refreshToken);\n await params.tokenStore.saveToken({ ...tokenKey, token: saved });\n return { headers: { Authorization: `Bearer ${saved.accessToken}` } };\n } catch {\n // Refresh failure falls through to a fresh authorization.\n }\n }\n if (token) {\n await params.tokenStore.deleteToken(tokenKey);\n }\n const authUrl = await buildMcpAuthorizationUrl({\n tokenStore: params.tokenStore,\n client,\n serverId: params.serverId,\n userRef: params.userRef,\n mcpServerUrl: params.mcpServerUrl,\n mcpServerName: params.mcpServerName,\n ...(params.returnTo !== undefined ? { returnTo: params.returnTo } : {}),\n });\n return { authUrl };\n}\n\n/**\n * Exchanges `code` for tokens against an already-claimed `pending` row: the caller claims it with\n * `consumePendingAuthorization` so duplicate callbacks lose the race, and keeps it for its FE\n * landing URL. Route must already reject IdP `error` params. On `invalid_client`, clears the stored\n * client so the next authorize re-registers (per-user tokens are left; there is usually none yet).\n */\nexport async function completeMcpAuthorization<TTransaction>(params: {\n tokenStore: IOAuthTokenStore<TTransaction>;\n mcpServerStore: IOAuthClientStore<TTransaction>;\n pending: OAuthPendingAuthorization;\n code: string;\n}): Promise<void> {\n const nowMs = Date.now();\n const { pending } = params;\n\n const client = await params.mcpServerStore.getClient({ id: pending.id });\n if (!client) {\n throw new McpConnectionError(\n `No OAuth client registered for MCP server id '${pending.id}'; re-run authorize first`,\n 400,\n );\n }\n if (pending.codeVerifier === null) {\n throw new McpConnectionError('Pending authorization is missing PKCE code_verifier; re-run authorize', 400);\n }\n let tokens: OAuthTokens;\n try {\n tokens = await exchangeAuthorization(mcpAuthorizationServerOrigin(client.server), {\n metadata: mcpAuthorizationServerMetadata(client.server),\n clientInformation: mcpClientInformation(client.client),\n authorizationCode: params.code,\n codeVerifier: pending.codeVerifier,\n redirectUri: mcpOAuthCallbackUrl(),\n resource: resourceUrlFromServerUrl(pending.mcpServerUrl),\n fetchFn: mcpOAuthFetch,\n });\n } catch (error: unknown) {\n if (error instanceof InvalidClientError) {\n await params.mcpServerStore.deleteClient({ id: pending.id });\n throw new McpConnectionError('OAuth client registration is invalid; please retry connecting', 400, {\n cause: error,\n });\n }\n throw mcpOAuthConnectionError('OAuth token exchange failed', error, 400);\n }\n await params.tokenStore.saveToken({\n id: pending.id,\n userRef: pending.userRef,\n token: oauthTokensToOAuthToken(tokens, nowMs, null),\n });\n}\n","import type {\n AuthorizationServerMetadata,\n OAuthClientInformationMixed,\n OAuthTokens,\n} from '@modelcontextprotocol/sdk/shared/auth.js';\nimport { McpConnectionError } from '@truefoundry/trueforge-core/core';\nimport { getPublicBaseUrl } from '../../config';\nimport type { OAuthClientCredentials, OAuthServerMetadata, OAuthToken } from './types';\n\n/** Fixed OAuth callback path for every MCP server. */\nexport const MCP_OAUTH_CALLBACK_PATH = '/api/v1/mcp-servers/oauth/callback';\n\n/** Fallback TTL when an RFC 6749 token response omits `expires_in`. */\nexport const DEFAULT_MCP_ACCESS_TOKEN_TTL_SECONDS = 3600;\n\n/** Builds the server-owned MCP OAuth callback URL. */\nexport function mcpOAuthCallbackUrl(): string {\n try {\n const publicBaseUrl = getPublicBaseUrl();\n return `${publicBaseUrl}${MCP_OAUTH_CALLBACK_PATH}`;\n } catch (error) {\n throw new McpConnectionError('PUBLIC_BASE_URL is required for MCP OAuth registration but was empty', 500, {\n cause: error,\n });\n }\n}\n\n/** Uses form-body client authentication when a secret is present. */\nexport function mcpClientInformation(client: OAuthClientCredentials): OAuthClientInformationMixed {\n return client.clientSecret !== null\n ? {\n client_id: client.clientId,\n client_secret: client.clientSecret,\n token_endpoint_auth_method: 'client_secret_post',\n }\n : {\n client_id: client.clientId,\n token_endpoint_auth_method: 'none',\n };\n}\n\n/** Reconstructs the metadata required by the MCP SDK authorization helpers. */\nexport function mcpAuthorizationServerMetadata(server: OAuthServerMetadata): AuthorizationServerMetadata {\n return {\n issuer: new URL(server.authorizationEndpoint).origin,\n authorization_endpoint: server.authorizationEndpoint,\n token_endpoint: server.tokenEndpoint,\n response_types_supported: ['code'],\n ...(server.codeChallengeMethodsSupported !== null\n ? { code_challenge_methods_supported: server.codeChallengeMethodsSupported }\n : {}),\n };\n}\n\nexport function mcpAuthorizationServerOrigin(server: OAuthServerMetadata): string {\n return new URL(server.authorizationEndpoint).origin;\n}\n\nexport function oauthTokensToOAuthToken(\n tokens: OAuthTokens,\n nowMs: number,\n fallbackRefreshToken: string | null,\n): OAuthToken {\n const expiresInSeconds = tokens.expires_in ?? DEFAULT_MCP_ACCESS_TOKEN_TTL_SECONDS;\n return {\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? fallbackRefreshToken,\n expiresAt: new Date(nowMs + expiresInSeconds * 1000).toISOString(),\n scope: tokens.scope ?? null,\n };\n}\n\n/** True when the expiry parses and is strictly in the future. */\nexport function isOAuthAccessTokenUsable(expiresAtIso: string, nowMs: number): boolean {\n const expiresAtMs = Date.parse(expiresAtIso);\n return !Number.isNaN(expiresAtMs) && expiresAtMs > nowMs;\n}\n","/** Daytona provider construction + persisted build-status refresh (see checkSnapshotStatus). */\nimport { Daytona, DaytonaError } from '@daytona/sdk';\nimport { DaytonaSandboxProvider, SANDBOX_IMAGE_URI, type SandboxBuild } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport configuration from '../config';\nimport type { ISandboxProviderStore, SandboxProviderRecord } from '../db/sandboxProviderStore';\nimport {\n toDaytonaSandboxProviderInput,\n type SandboxBuildMetadata,\n type SandboxProviderManifest,\n type SandboxStatus,\n} from '../schemas/sandboxProvider';\n\n/** Daytona rejected the credentials (401 unauthorized / 403 forbidden); retrying the same key cannot succeed. */\nexport function isDaytonaAuthError(error: unknown): boolean {\n return error instanceof DaytonaError && (error.statusCode === 401 || error.statusCode === 403);\n}\n\n/**\n * Builds the runtime provider for a stored manifest. No network I/O until a method is called.\n *\n * When `build_metadata` is present, pin both `sandboxImage` and `buildRef` to what was actually\n * built — image bumps in the running binary must not rewrite an existing tenant onto a new\n * snapshot (upgrades are not supported yet). First-time configure omits metadata and uses\n * {@link SANDBOX_IMAGE_URI}.\n */\nexport function toDaytonaSandboxProvider({\n manifest,\n tenant_id,\n logger,\n build_metadata,\n}: {\n manifest: SandboxProviderManifest;\n tenant_id: string;\n logger: Logger;\n build_metadata?: SandboxBuildMetadata | null;\n}): DaytonaSandboxProvider {\n const { apiKey, ...settings } = toDaytonaSandboxProviderInput(manifest);\n return new DaytonaSandboxProvider({\n client: new Daytona({ apiKey }),\n apiKey,\n ...settings,\n tenantName: tenant_id,\n sandboxImage: build_metadata?.['image_uri'] ?? SANDBOX_IMAGE_URI,\n buildRef: build_metadata?.['build_ref'],\n fileMaxBytesForDownload: configuration.SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD,\n logger,\n });\n}\n\n/** Maps a core `SandboxBuild` onto the persisted/wire status shape (metadata passes through). */\nexport function toSandboxStatus(build: SandboxBuild): SandboxStatus {\n return {\n status: build.status,\n status_reason: build.reason,\n build_metadata: build.metadata,\n };\n}\n\nfunction sandboxStatusFromRecord(record: SandboxProviderRecord): SandboxStatus {\n return {\n status: record.status,\n status_reason: record.status_reason,\n build_metadata: record.build_metadata,\n };\n}\n\n// Daytona deactivates idle snapshots after 14 days; revalidate at 13 to stay a day ahead.\nconst READY_REVALIDATE_INTERVAL_MS = 13 * 24 * 60 * 60 * 1000;\n\nexport async function checkSnapshotStatus({\n store,\n tenant_id,\n logger,\n}: {\n store: ISandboxProviderStore;\n tenant_id: string;\n logger: Logger;\n}): Promise<SandboxStatus | undefined> {\n const record = await store.getSandboxProvider(tenant_id);\n if (!record) {\n return undefined;\n }\n\n const persisted = sandboxStatusFromRecord(record);\n\n const readyIsFresh =\n record.status === 'ready' && Date.now() - Date.parse(record.updated_at) < READY_REVALIDATE_INTERVAL_MS;\n if (record.status === 'failed' || readyIsFresh) {\n return persisted;\n }\n\n const provider = toDaytonaSandboxProvider({\n manifest: record.manifest,\n tenant_id,\n logger,\n build_metadata: record.build_metadata,\n });\n let build: SandboxBuild;\n if (record.status === 'ready') {\n // this is because image may have deactivated\n build = await provider.buildImage();\n } else {\n build = await provider.getImageBuildStatus();\n }\n const next = toSandboxStatus(build);\n const updated = await store.updateSandboxStatus({ tenant_id, ...next });\n return updated ? sandboxStatusFromRecord(updated) : next;\n}\n","/**\n * Sandbox-provider domain + wire schemas: configured provider jsonb and OpenAPI\n * request/response shapes. Catalog file schemas live in sandboxCatalog.ts.\n *\n * Singleton per tenant — no identity `name` (unlike model providers / skills).\n */\nimport { z } from '@hono/zod-openapi';\nimport type { DaytonaSandboxProviderOptions } from '@truefoundry/trueforge-core/core';\n\nconst DaytonaSandboxProviderAuthSchema = z\n .object({\n api_key: z\n .string()\n .min(1)\n .describe(\n 'Daytona API key. Responses are redacted; on PUT, a real value sets/rotates and a redacted value keeps the stored key.',\n ),\n })\n .strict()\n .describe('Daytona authentication credentials.')\n .openapi('DaytonaSandboxProviderAuth');\n\n/**\n * Daytona-backed sandbox provider config. Persisted as `sandbox_provider.manifest`.\n * Left unnamed for OpenAPI so `SandboxProviderManifest` (its single-variant alias)\n * is the one emitted component and the response `manifest` field is a plain `$ref`\n * instead of an `allOf` wrapper.\n */\nexport const DaytonaSandboxProviderSchema = z\n .object({\n type: z.literal('daytona').describe('Daytona sandbox provider.'),\n auth: DaytonaSandboxProviderAuthSchema,\n exec_timeout_ms: z.number().int().positive().describe('Default sandbox command exec timeout in milliseconds.'),\n auto_stop_interval_in_minutes: z\n .number()\n .int()\n .nonnegative()\n .describe('Minutes of idle time before Daytona auto-stops the sandbox (0 disables).'),\n auto_archive_interval_in_minutes: z\n .number()\n .int()\n .nonnegative()\n .describe('Minutes before Daytona auto-archives the sandbox (0 disables).'),\n auto_delete_interval_in_minutes: z\n .number()\n .int()\n .nonnegative()\n .describe('Minutes before Daytona auto-deletes the sandbox (0 disables).'),\n })\n .strict();\n\n/**\n * Persisted jsonb: the provider config only (no build status). Single variant today —\n * this alias carries the OpenAPI name so the spec emits one `SandboxProviderManifest` component.\n * Widen to `z.discriminatedUnion('type', [...])` when a second provider ships.\n */\nexport const SandboxProviderManifestSchema = DaytonaSandboxProviderSchema.openapi('SandboxProviderManifest');\n\n/** Named enum so the generated SDK exposes a reusable `SandboxBuildStatus` type. */\nexport const SandboxBuildStatusSchema = z\n .enum(['pending', 'ready', 'failed'])\n .describe('Current build status.')\n .openapi('SandboxBuildStatus');\n\n/** Provider-specific opaque build metadata (string map), persisted alongside the status — not on the wire. */\nexport const SandboxBuildMetadataSchema = z\n .record(z.string(), z.string())\n .describe('Provider-specific build metadata (opaque string map).');\n\n/** Build status persisted and refreshed on read (includes opaque metadata for the provider). */\nexport const SandboxStatusSchema = z\n .object({\n status: SandboxBuildStatusSchema,\n status_reason: z.string().nullable().describe('Human-readable detail for the current status; null when ready.'),\n build_metadata: SandboxBuildMetadataSchema.nullable().describe(\n 'Provider-specific build metadata; null when the provider has none.',\n ),\n })\n .strict();\n\n/** Settings wire item: nested manifest plus build status (no build_metadata). */\nexport const ConfiguredSandboxProviderSchema = z\n .object({\n manifest: SandboxProviderManifestSchema,\n status: SandboxBuildStatusSchema,\n status_reason: z.string().nullable().describe('Human-readable detail for the current status; null when ready.'),\n })\n .strict()\n .openapi('ConfiguredSandboxProvider');\n\nexport const UpdateSandboxProviderRequestSchema = z\n .object({\n manifest: SandboxProviderManifestSchema,\n })\n .strict()\n .openapi('UpdateSandboxProviderRequest');\n\nexport const GetSandboxProviderResponseSchema = z\n .object({\n data: ConfiguredSandboxProviderSchema,\n })\n .openapi('GetSandboxProviderResponse');\n\n/** Persisted jsonb — the provider config only (no build status). */\nexport type SandboxProviderManifest = z.infer<typeof SandboxProviderManifestSchema>;\nexport type DaytonaSandboxProvider = z.infer<typeof DaytonaSandboxProviderSchema>;\nexport type SandboxBuildStatus = z.infer<typeof SandboxBuildStatusSchema>;\nexport type SandboxBuildMetadata = z.infer<typeof SandboxBuildMetadataSchema>;\nexport type SandboxStatus = z.infer<typeof SandboxStatusSchema>;\nexport type ConfiguredSandboxProvider = z.infer<typeof ConfiguredSandboxProviderSchema>;\nexport type UpdateSandboxProviderRequest = z.infer<typeof UpdateSandboxProviderRequestSchema>;\n\n/** Wire/persisted snake_case → Daytona client credentials + provider settings. */\nexport function toDaytonaSandboxProviderInput(manifest: SandboxProviderManifest): {\n apiKey: string;\n} & Pick<\n DaytonaSandboxProviderOptions,\n 'timeoutMs' | 'autoStopIntervalInMinutes' | 'autoArchiveIntervalInMinutes' | 'autoDeleteIntervalInMinutes'\n> {\n return {\n apiKey: manifest.auth.api_key,\n timeoutMs: manifest.exec_timeout_ms,\n autoStopIntervalInMinutes: manifest.auto_stop_interval_in_minutes,\n autoArchiveIntervalInMinutes: manifest.auto_archive_interval_in_minutes,\n autoDeleteIntervalInMinutes: manifest.auto_delete_interval_in_minutes,\n };\n}\n","/**\n * Configured MCP server domain + wire schemas: the `mcp_server.manifest` JSONB\n * document, admin/chat list projections, and auth_status. Catalog file schemas\n * live in mcpCatalog.ts.\n *\n * Auth: `header` stores shared request headers on the row.\n * Turn execution resolves DCR tokens via resolveMcpAuth.\n */\nimport { z } from '@hono/zod-openapi';\nimport type { OAuthToken } from '../mcp/auth/types';\nimport { NameSchema } from './common';\n\n/** Transport/kind of MCP server. Extend when non-remote kinds ship. */\nexport const McpServerTypeSchema = z.enum(['remote']).openapi('MCPServerType');\n\nconst McpServerHeaderAuthSchema = z\n .object({\n type: z.literal('header').describe('Authenticate with static HTTP headers.'),\n headers: z\n .record(z.string().min(1), z.string().min(1))\n .refine(headers => Object.keys(headers).length > 0, {\n message: 'must include at least one header',\n })\n .describe(\n 'Request headers for this MCP server. Responses are redacted; on PUT, a real value sets/rotates and a redacted value keeps the stored secret for that header name.',\n ),\n })\n .strict()\n .openapi('MCPServerHeaderAuth');\n\n/** OAuth Dynamic Client Registration — stub until authorize/token exchange is wired. */\nconst McpServerDcrAuthSchema = z\n .object({\n type: z.literal('dcr').describe('Authenticate via OAuth Dynamic Client Registration.'),\n })\n .strict()\n .openapi('MCPServerDcrAuth');\n\nexport const McpServerManifestAuthSchema = z\n .discriminatedUnion('type', [McpServerHeaderAuthSchema, McpServerDcrAuthSchema])\n .describe('Optional auth settings. Omit when the server needs no credentials.')\n .openapi('MCPServerManifestAuth');\n\nexport const McpServerDescriptionSchema = z\n .string()\n .trim()\n .min(1)\n .describe('Concise summary of what this MCP server provides.');\n\n/** Configured MCP server document persisted as `mcp_server.manifest`. */\nexport const McpServerManifestObjectSchema = z\n .object({\n type: McpServerTypeSchema,\n name: NameSchema,\n url: z.url().describe('URL of the remote MCP server.'),\n description: McpServerDescriptionSchema,\n auth: McpServerManifestAuthSchema.optional(),\n })\n .strict();\n\nexport const McpServerManifestSchema = McpServerManifestObjectSchema.openapi('MCPServerManifest');\n\nexport const McpAuthStatusSchema = z\n .object({\n status: z\n .enum(['authenticated', 'auth_required', 'not_required'])\n .describe('Current auth state for this MCP server.'),\n authorization_url: z\n .url()\n .optional()\n .describe('When auth is required, this contains the URL to redirect the user to for authorization.'),\n })\n .strict()\n .describe('Current auth state.')\n .openapi('MCPAuthStatus');\n\n/** Admin/settings wire view: identity column plus nested manifest and auth_status. */\nexport const ConfiguredMcpServerSchema = z\n .object({\n name: NameSchema,\n manifest: McpServerManifestSchema,\n auth_status: McpAuthStatusSchema,\n })\n .strict()\n .openapi('ConfiguredMCPServer');\n\nexport const CreateMcpServerRequestSchema = z\n .object({\n manifest: McpServerManifestSchema,\n })\n .strict()\n .openapi('CreateMCPServerRequest');\n\nexport const UpdateMcpServerRequestSchema = z\n .object({\n manifest: McpServerManifestSchema,\n })\n .strict()\n .openapi('UpdateMCPServerRequest');\n\nexport const GetMcpServerResponseSchema = z.object({ data: ConfiguredMcpServerSchema }).openapi('GetMCPServerResponse');\nexport const ListMcpServersResponseSchema = z\n .object({ data: z.array(ConfiguredMcpServerSchema) })\n .openapi('ListMCPServersResponse');\n\n/** Public auth mechanism for chat/composer (no secrets). */\nexport const McpServerAuthPublicSchema = z\n .discriminatedUnion('type', [\n z.object({ type: z.literal('dcr') }).strict(),\n z.object({ type: z.literal('header') }).strict(),\n ])\n .describe('Auth mechanism when configured (no secrets). Omit when the server needs no credentials.')\n .openapi('MCPServerAuthPublic');\n\n/** Chat/composer read view — public fields plus per-user auth_status. */\nexport const AvailableMcpServerSchema = z\n .object({\n name: NameSchema,\n url: z.url().describe('URL of the remote MCP server.'),\n auth: McpServerAuthPublicSchema.optional(),\n auth_status: McpAuthStatusSchema,\n })\n .strict()\n .openapi('AvailableMCPServer');\n\nexport const ListAvailableMcpServersResponseSchema = z\n .object({ data: z.array(AvailableMcpServerSchema) })\n .openapi('ListAvailableMCPServersResponse');\n\nexport type McpServerType = z.infer<typeof McpServerTypeSchema>;\nexport type McpServerManifestAuth = z.infer<typeof McpServerManifestAuthSchema>;\nexport type McpServerManifest = z.infer<typeof McpServerManifestSchema>;\nexport type McpAuthStatus = z.infer<typeof McpAuthStatusSchema>;\nexport type McpServerAuthPublic = z.infer<typeof McpServerAuthPublicSchema>;\nexport type ConfiguredMcpServer = z.infer<typeof ConfiguredMcpServerSchema>;\nexport type CreateMcpServerRequest = z.infer<typeof CreateMcpServerRequestSchema>;\nexport type UpdateMcpServerRequest = z.infer<typeof UpdateMcpServerRequestSchema>;\nexport type AvailableMcpServer = z.infer<typeof AvailableMcpServerSchema>;\n\n/**\n * Headers for live MCP calls against a configured server.\n * Only `auth.type === 'header'` contributes. Turn execution uses DCR via\n * resolveMcpAuth instead of this helper.\n */\nexport function resolveConfiguredMcpRequestHeaders(manifest: McpServerManifest): Record<string, string> {\n if (manifest.auth?.type === 'header') {\n return { ...manifest.auth.headers };\n }\n return {};\n}\n\nexport function resolveMcpAuthStatus({\n manifest,\n token,\n}: {\n manifest: McpServerManifest;\n token?: OAuthToken;\n}): McpAuthStatus {\n if (manifest.auth?.type === 'dcr') {\n return token ? { status: 'authenticated' } : { status: 'auth_required' };\n }\n if (manifest.auth?.type === 'header') {\n return { status: 'authenticated' };\n }\n return { status: 'not_required' };\n}\n","/**\n * DB-backed sessions API (mounted at /api/v1/sessions).\n */\nimport { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport type { ISessionStore, SessionHandle, SessionRecord, Sessions } from '@truefoundry/trueforge-core/agent-session';\nimport {\n CancellationReason,\n SessionStoreConflictError,\n SessionStoreInvariantError,\n SessionStoreNotFoundError,\n TurnNotFoundError,\n} from '@truefoundry/trueforge-core/agent-session';\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport {\n redisRequest,\n RequestTimeoutError,\n type RouteHandler as RequestReplyRouteHandler,\n type RequestReplyRouter,\n} from '@truefoundry/trueforge-core/request-reply';\nimport type { RedisClientType } from 'redis';\nimport { ulid } from 'ulid';\nimport type { Logger } from 'winston';\nimport { z } from 'zod';\nimport type { ResolveUserContext } from '../auth/identity';\nimport configuration from '../config';\nimport type { IAgentStore } from '../db/agentStore';\nimport type { IMcpServerStore } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport {\n cancelSessionRoute,\n createSessionRoute,\n deleteSessionRoute,\n getSessionRoute,\n listSessionEventsRoute,\n listSessionsRoute,\n updateSessionRoute,\n} from '../routes/sessionRoutes';\nimport type { ActiveTurnRegistry } from '../runtime/activeTurns';\nimport { executorFromTurnId } from '../runtime/peeringIds';\nimport { validateAgentSpec } from '../runtime/sessionResources';\nimport { isSessionAgentNameRef, type Session } from '../schemas/session';\n\n/** The server is single-tenant; every record lives under one fixed tenant scope. */\nexport const TENANT_ID = 'default';\n\n/** Request-reply path a replica serves to cancel a turn it owns. */\nexport const SESSIONS_CANCEL_PATH = 'sessions/cancel';\n\n/** Wire body of a peer cancel; validated on receipt (it crosses processes via Redis). */\nconst CancelPeerBodySchema = z.object({\n session_id: z.string(),\n turn_id: z.string(),\n reason: z.enum(CancellationReason),\n});\ntype CancelPeerBody = z.infer<typeof CancelPeerBodySchema>;\n\nexport function toWireSession(record: SessionRecord): Session {\n return {\n id: record.session_id,\n agent: record.agent,\n title: record.title,\n created_by: record.created_by,\n created_at: record.created_at.toISOString(),\n updated_at: record.updated_at.toISOString(),\n };\n}\n\nexport interface SessionsRouterDeps {\n sessions: Sessions;\n sessionStore: ISessionStore;\n activeTurns: ActiveTurnRegistry;\n modelProviderStore: IModelProviderStore;\n mcpServerStore: IMcpServerStore;\n skillStore: ISkillStore;\n agentStore: IAgentStore;\n sandboxProviderStore: ISandboxProviderStore;\n redis?: RedisClientType | undefined;\n requestReplyRouter: RequestReplyRouter;\n resolveUserContext: ResolveUserContext;\n logger: Logger;\n}\n\nfunction cancelTurnOnThisExecutor(\n activeTurns: ActiveTurnRegistry,\n input: { sessionId: string; turnId: string; reason: CancellationReason },\n): boolean {\n return activeTurns.cancelIfRunning({\n sessionId: input.sessionId,\n turnId: input.turnId,\n abortReason: input.reason,\n });\n}\n\n/**\n * Peer-facing cancel handler: aborts the turn if it runs in this process.\n * 200 = abort fired, 412 = not running here (treated by callers as a no-op).\n */\nexport function cancelSessionTurnPeerHandler(activeTurns: ActiveTurnRegistry): RequestReplyRouteHandler {\n // Synchronous by nature; the transport expects a Promise and require-await\n // forbids an async fn without awaits.\n return request => {\n const parsed = CancelPeerBodySchema.safeParse(request.body);\n if (!parsed.success) {\n return Promise.resolve({ status: 400, body: { message: 'Invalid sessions/cancel payload' } });\n }\n const found = cancelTurnOnThisExecutor(activeTurns, {\n sessionId: parsed.data.session_id,\n turnId: parsed.data.turn_id,\n reason: parsed.data.reason,\n });\n return Promise.resolve(\n found ? { status: 200, body: {} } : { status: 412, body: { message: 'Turn is not running on this executor' } },\n );\n };\n}\n\n/** A registry to abort in, a session to freeze, durable state to read, and a way to reach peers. */\nexport interface CancelTurnDeps {\n activeTurns: ActiveTurnRegistry;\n session: Pick<SessionHandle, 'session_id' | 'freezeTurn'>;\n sessionStore: Pick<ISessionStore, 'getTurn'>;\n redis?: RedisClientType | undefined;\n logger: Pick<Logger, 'warn'>;\n}\n\n/**\n * Cancels the turn wherever it runs: locally or on the owning peer over Redis\n * request-reply. Callers state the motive; default is a plain client cancel.\n *\n * A confirmed abort (this process, or peer HTTP 200) lets TurnHandle persist\n * the terminal state. If abort cannot be confirmed, this replica freezes the\n * turn in the store so the session is not stuck `running`.\n *\n * Redis timeout and Redis/transport failures are not a clean cancellation —\n * the owning replica may still be executing — but the turn is still frozen.\n * Later writes from that replica lose to first-terminal-write-wins.\n */\nexport async function cancelSessionTurn(\n deps: CancelTurnDeps,\n input: { turnId: string; reason?: CancellationReason },\n): Promise<void> {\n const { turnId, reason = CancellationReason.ClientCancelled } = input;\n const sessionId = deps.session.session_id;\n\n const turn = await deps.sessionStore.getTurn({\n session_id: sessionId,\n turn_id: turnId,\n });\n if (turn?.state.status !== 'running') {\n // Missing or already terminal — nothing to cancel.\n return;\n }\n\n const owner = executorFromTurnId(turnId);\n // Without a Redis client there is no peer to ask, so an id naming another\n // replica falls through to the local lookup and freezes if the run is gone.\n if (owner !== configuration.EXECUTOR_ID && deps.redis) {\n try {\n const reply = await redisRequest<CancelPeerBody>({\n redis: deps.redis,\n executorId: owner,\n path: SESSIONS_CANCEL_PATH,\n request: {\n body: { session_id: sessionId, turn_id: turnId, reason },\n },\n options: {\n replyTimeoutMs: configuration.REDIS_REQUEST_REPLY_TIMEOUT_MS,\n pollIntervalMs: configuration.REDIS_REQUEST_REPLY_POLL_INTERVAL_MS,\n },\n });\n if (reply.status === 200) {\n return;\n }\n } catch (error) {\n const fields = {\n sessionId,\n turnId,\n owner,\n ...extractErrorLogFields(error),\n };\n if (error instanceof RequestTimeoutError) {\n deps.logger.warn('Timed out waiting for owning executor to cancel; freezing the running turn', fields);\n } else {\n deps.logger.warn('Failed to reach owning executor over Redis; freezing the running turn', fields);\n }\n }\n await freezeTurnIgnoringMissing(deps.session, { turnId, reason });\n return;\n }\n\n const aborted = cancelTurnOnThisExecutor(deps.activeTurns, { sessionId, turnId, reason });\n if (!aborted) {\n await freezeTurnIgnoringMissing(deps.session, { turnId, reason });\n }\n}\n\n/** Freeze a running turn; missing turns are a no-op (already gone). */\nasync function freezeTurnIgnoringMissing(\n session: Pick<SessionHandle, 'freezeTurn'>,\n input: { turnId: string; reason: CancellationReason },\n): Promise<void> {\n try {\n await session.freezeTurn({ turn_id: input.turnId, reason: input.reason });\n } catch (error) {\n if (error instanceof TurnNotFoundError) {\n return;\n }\n throw error;\n }\n}\n\nconst FORBIDDEN_SESSION_ACCESS = 'Only the session creator can access this session';\n\nfunction checkSessionAccess({ userRef, createdBy }: { userRef: string; createdBy: string }): boolean {\n return userRef === createdBy;\n}\n\n/** DB-backed sessions (mounted at /api/v1/sessions). */\nexport function createSessionsRouter(deps: SessionsRouterDeps) {\n const createSessionHandler: RouteHandler<typeof createSessionRoute> = async c => {\n const body = c.req.valid('json');\n const sessionId = ulid().toLowerCase();\n\n if (isSessionAgentNameRef(body.agent)) {\n const agent = await deps.agentStore.getAgent({ tenant_id: TENANT_ID, name: body.agent.name });\n if (agent === undefined) {\n return c.json({ error: { message: `Agent not found: ${body.agent.name}` } }, 404);\n }\n const user = deps.resolveUserContext(c);\n const session = await deps.sessions.create({\n tenant_id: TENANT_ID,\n session_id: sessionId,\n created_by: user.userRef,\n agent: { type: 'reference', id: agent.id, name: agent.name },\n });\n return c.json({ data: toWireSession(session.record) }, 201);\n }\n\n await validateAgentSpec({\n spec: body.agent.spec,\n tenant_id: TENANT_ID,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n });\n const user = deps.resolveUserContext(c);\n const session = await deps.sessions.create({\n tenant_id: TENANT_ID,\n session_id: sessionId,\n created_by: user.userRef,\n agent: { type: 'inline', spec: body.agent.spec },\n });\n return c.json({ data: toWireSession(session.record) }, 201);\n };\n\n const getSessionHandler: RouteHandler<typeof getSessionRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const record = await deps.sessionStore.getSession({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!record) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: record.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n return c.json({ data: toWireSession(record) }, 200);\n };\n\n const deleteSessionHandler: RouteHandler<typeof deleteSessionRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const record = await deps.sessionStore.getSession({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!record) {\n // Idempotent delete when already gone.\n return c.body(null, 204);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: record.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n await deps.sessionStore.deleteSession({ tenant_id: TENANT_ID, session_id: sessionId });\n return c.body(null, 204);\n };\n\n const updateSessionHandler: RouteHandler<typeof updateSessionRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const body = c.req.valid('json');\n const existing = await deps.sessionStore.getSession({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!existing) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: existing.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n // Inline sessions may replace their agent; named (reference) sessions\n // cannot — the store rejects that with SessionStoreInvariantError → 422 below.\n if (body.agent !== undefined) {\n await validateAgentSpec({\n spec: body.agent.spec,\n tenant_id: TENANT_ID,\n modelProviderStore: deps.modelProviderStore,\n mcpServerStore: deps.mcpServerStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n });\n }\n try {\n await deps.sessionStore.updateSession({\n tenant_id: TENANT_ID,\n session_id: sessionId,\n agent: body.agent === undefined ? undefined : { type: 'inline', spec: body.agent.spec },\n title: undefined,\n });\n } catch (error) {\n if (error instanceof SessionStoreNotFoundError) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (error instanceof SessionStoreInvariantError) {\n return c.json({ error: { message: error.message } }, 422);\n }\n throw error;\n }\n const record = await deps.sessionStore.getSession({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!record) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n return c.json({ data: toWireSession(record) }, 200);\n };\n\n const listSessionsHandler: RouteHandler<typeof listSessionsRoute> = async c => {\n const query = c.req.valid('query');\n const user = deps.resolveUserContext(c);\n try {\n const { data, pagination } = await deps.sessionStore.listSessions({\n agent_id: query.agent_id,\n created_by: user.userRef,\n tenant_id: TENANT_ID,\n limit: query.limit,\n order: query.order,\n page_token: query.page_token,\n start_timestamp: query.start_timestamp,\n end_timestamp: query.end_timestamp,\n });\n return c.json({ data: data.map(toWireSession), pagination }, 200);\n } catch (error) {\n if (error instanceof SessionStoreConflictError) {\n return c.json({ error: { message: error.message } }, 400);\n }\n throw error;\n }\n };\n\n const cancelSessionHandler: RouteHandler<typeof cancelSessionRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: session.record.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n const turnId = session.record.last_turn_id;\n if (!turnId) {\n return c.json({}, 200);\n }\n\n await cancelSessionTurn({ ...deps, session }, { turnId });\n return c.json({}, 200);\n };\n\n const listSessionEventsHandler: RouteHandler<typeof listSessionEventsRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const query = c.req.valid('query');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkSessionAccess({ userRef: deps.resolveUserContext(c).userRef, createdBy: session.record.created_by })) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n try {\n const { data, pagination } = await session.listEvents({\n limit: query.limit,\n page_token: query.page_token,\n last_turn_id: query.last_turn_id,\n });\n return c.json({ data, pagination }, 200);\n } catch (error) {\n if (error instanceof SessionStoreConflictError) {\n return c.json({ error: { message: error.message } }, 400);\n }\n if (error instanceof SessionStoreNotFoundError) {\n return c.json({ error: { message: error.message } }, 404);\n }\n throw error;\n }\n };\n\n const router = new OpenAPIHono();\n router.openapi(createSessionRoute, createSessionHandler);\n router.openapi(getSessionRoute, getSessionHandler);\n router.openapi(deleteSessionRoute, deleteSessionHandler);\n router.openapi(updateSessionRoute, updateSessionHandler);\n router.openapi(listSessionsRoute, listSessionsHandler);\n router.openapi(cancelSessionRoute, cancelSessionHandler);\n router.openapi(listSessionEventsRoute, listSessionEventsHandler);\n deps.requestReplyRouter.registerRoute(SESSIONS_CANCEL_PATH, cancelSessionTurnPeerHandler(deps.activeTurns));\n return router;\n}\n","/**\n * Session route definitions.\n * DB-backed routes mount at /api/v1/sessions.\n * Handlers are registered in apis/sessions.ts.\n */\nimport { createRoute, z } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { ListSessionEventsRequestQuerySchema, ListSessionEventsResponseSchema } from '../schemas/events';\nimport {\n CreateSessionRequestSchema,\n GetSessionResponseSchema,\n ListSessionsRequestQuerySchema,\n ListSessionsResponseSchema,\n UpdateSessionRequestSchema,\n} from '../schemas/session';\nimport { CancelSessionRequestSchema, CancelSessionResponseSchema } from '../schemas/turn';\nimport { TOKEN_PAGINATION } from './fernExtensions';\nimport { OpenApiTag } from './openapiTags';\n\nexport const SessionIdParamsSchema = z.object({\n session_id: z.string().min(1).max(64).describe('Session identifier.'),\n});\n\nexport const createSessionRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'Create a session',\n description:\n 'Create a session with `agent` as either `{ name }` (named registry binding) or `{ spec: AgentSpec }` (inline). Named sessions snapshot the agent name at create and resolve the live agent on each turn. Responses use `{ type: \"reference\", name, id }` or `{ type: \"inline\", spec }`.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateSessionRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetSessionResponseSchema } },\n description: 'Session created.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Named agent not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'The agent spec is valid but references a resource this server does not provide (e.g. model, MCP server, skill, or sandbox).',\n },\n },\n});\n\nexport const getSessionRoute = createRoute({\n method: 'get',\n path: '/{session_id}',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'Get a session',\n description: 'Fetch a session by ID. Only the session creator (`created_by`) may fetch it.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'get',\n request: {\n params: SessionIdParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSessionResponseSchema } },\n description: 'Session data.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n },\n});\n\nexport const deleteSessionRoute = createRoute({\n method: 'delete',\n path: '/{session_id}',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'Delete a session',\n description:\n 'Delete a session and all related turns, events, and internal state. Only the session creator (`created_by`) may delete it. Idempotent if already gone.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'delete',\n request: {\n params: SessionIdParamsSchema,\n },\n responses: {\n 204: {\n description: 'Session and all related data deleted.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n },\n});\n\nexport const updateSessionRoute = createRoute({\n method: 'patch',\n path: '/{session_id}',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'Update a session',\n description:\n 'Update a session by replacing `agent` with `{ spec: AgentSpec }`. Named (reference) sessions reject agent updates. An empty body is a valid no-op that refreshes `updated_at`. Only the session creator (`created_by`) may update it.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'update',\n request: {\n params: SessionIdParamsSchema,\n body: {\n content: { 'application/json': { schema: UpdateSessionRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSessionResponseSchema } },\n description: 'Session updated.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'Named session rejected an agent update, or the agent spec references a resource this server does not provide (e.g. model, MCP server, skill, or sandbox).',\n },\n },\n});\n\nexport const listSessionsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'List sessions',\n description:\n \"List the caller's sessions (newest first by default), token-paginated. Results are scoped to the authenticated identity via the session store's `created_by` filter (not a client query param). Optional `agent_id` filters to sessions bound to that named agent. Pass `page_token` to fetch the next page, keeping the other query params constant.\",\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'list',\n 'x-fern-pagination': TOKEN_PAGINATION,\n request: {\n query: ListSessionsRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListSessionsResponseSchema } },\n description: 'Paginated sessions.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid query parameters or page token.',\n },\n },\n});\n\nexport const cancelSessionRoute = createRoute({\n method: 'post',\n path: '/{session_id}/cancel',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'Cancel a running turn in a session',\n description: 'Cancel the running last turn for a session. Only the session creator (`created_by`) may cancel.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'cancel',\n request: {\n params: SessionIdParamsSchema,\n body: {\n content: { 'application/json': { schema: CancelSessionRequestSchema } },\n required: false,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: CancelSessionResponseSchema } },\n description: 'Turn cancelled.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n 412: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'Requested action cannot be performed on the session because it is no longer usable, or the executor owning the running turn is unreachable.',\n },\n },\n});\n\nexport const listSessionEventsRoute = createRoute({\n method: 'get',\n path: '/{session_id}/events',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'List session events',\n description:\n 'List session events as `{ turn_id, event }` across the active turn branch (newest first), including persisted events from a running tip. Each turn contributes turn.created, content events (model.message, tool.call, …), and turn.done when terminal; streaming deltas are not included. Use `page_token` to paginate backward toward older events while retaining the original branch anchor. Only the session creator (`created_by`) may list events.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'list_events',\n 'x-fern-pagination': TOKEN_PAGINATION,\n request: {\n params: SessionIdParamsSchema,\n query: ListSessionEventsRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListSessionEventsResponseSchema } },\n description: 'Paginated session events.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid page token.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n },\n});\n","/**\n * Server event wire schemas: SSE streaming union + list-query envelopes.\n * Lifecycle / persisted event schemas live in agentSession.\n */\nimport { z } from '@hono/zod-openapi';\nimport {\n EventType,\n SessionEventItemSchema,\n TokenPaginationSchema,\n TurnCreatedEventSchema,\n TurnDoneEventSchema,\n} from '@truefoundry/trueforge-core/agent-session';\nimport {\n MCPAuthRequiredEventSchema,\n MCPInitializeEventSchema,\n ModelMessageDeltaEventSchema,\n ModelMessageEventSchema,\n SandboxCreatedEventSchema,\n ThreadCreatedEventSchema,\n ThreadDoneEventSchema,\n ToolApprovalRequiredEventSchema,\n ToolResponseEventSchema,\n ToolResponseRequiredEventSchema,\n} from '@truefoundry/trueforge-core/core';\nimport { EVENTS_PAGE_LIMIT } from './common';\n\nexport type { TurnCreatedEvent } from '@truefoundry/trueforge-core/agent-session';\nexport { EventType };\n\n/** Live SSE stream for session turns — content events, deltas and lifecycle. */\nexport const TurnStreamingEventSchema = z\n .discriminatedUnion('type', [\n ModelMessageEventSchema,\n ModelMessageDeltaEventSchema,\n ToolResponseEventSchema,\n ThreadCreatedEventSchema,\n ThreadDoneEventSchema,\n MCPAuthRequiredEventSchema,\n MCPInitializeEventSchema,\n SandboxCreatedEventSchema,\n ToolApprovalRequiredEventSchema,\n ToolResponseRequiredEventSchema,\n TurnCreatedEventSchema,\n TurnDoneEventSchema,\n ])\n .openapi('TurnStreamingEvent');\n\nexport const ListSessionEventsRequestQuerySchema = z\n .object({\n page_token: z\n .string()\n .optional()\n .describe(\n 'Pagination cursor from `pagination.next_page_token`. It retains the branch anchor turn and returns older events toward the session start.',\n ),\n last_turn_id: z\n .string()\n .optional()\n .describe(\n 'Newest turn in the listing window (initial load only; ignored when `page_token` is set). Lists that turn and its ancestors, newest events first. Omit to use the session last turn.',\n ),\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(EVENTS_PAGE_LIMIT)\n .optional()\n .default(EVENTS_PAGE_LIMIT)\n .describe(`Page size. Defaults to ${String(EVENTS_PAGE_LIMIT)}, max ${String(EVENTS_PAGE_LIMIT)}.`),\n })\n .openapi('ListSessionEventsRequestQuery');\n\nexport const ListSessionEventsResponseSchema = z\n .object({\n data: z.array(SessionEventItemSchema),\n pagination: TokenPaginationSchema,\n })\n .openapi('ListSessionEventsResponse');\n\nexport type TurnStreamingEvent = z.infer<typeof TurnStreamingEventSchema>;\n","/** Server session wire schemas. Core Session lives in agentSession. */\nimport { z } from '@hono/zod-openapi';\nimport { AgentSpecSchema, SessionSchema, TokenPaginationSchema } from '@truefoundry/trueforge-core/agent-session';\nimport { NameSchema, PAGE_LIMIT } from './common';\n\n/** Create arm: bind by unique registry agent name. */\nexport const SessionAgentNameRefSchema = z.object({ name: NameSchema }).strict().openapi('SessionAgentNameRef');\n\n/**\n * Create/update body arm wrapping an AgentSpec.\n * Use AgentSpecSchema (not `.strict()`) so OpenAPI `$ref`s the shared AgentSpec.\n */\nconst SessionAgentSpecBodySchema = z.object({ spec: AgentSpecSchema }).strict().openapi('SessionAgentSpecBody');\n\n/** Create accepts either a unique agent name or `{ spec: AgentSpec }`. */\nexport const CreateSessionAgentSchema = z\n .union([SessionAgentNameRefSchema, SessionAgentSpecBodySchema])\n .openapi('CreateSessionAgent');\n\nexport type CreateSessionAgent = z.infer<typeof CreateSessionAgentSchema>;\nexport type SessionAgentNameRef = z.infer<typeof SessionAgentNameRefSchema>;\nexport type SessionAgentSpecBody = z.infer<typeof SessionAgentSpecBodySchema>;\n\n/** Narrows the create-body union after OpenAPI already accepted either arm. */\nexport function isSessionAgentNameRef(agent: CreateSessionAgent): agent is SessionAgentNameRef {\n return SessionAgentNameRefSchema.safeParse(agent).success;\n}\n\nexport const CreateSessionRequestSchema = z\n .object({\n agent: CreateSessionAgentSchema,\n })\n .strict()\n .openapi('CreateSessionRequest');\n\n/** Only inline sessions may be updated; named (reference) sessions reject agent updates. */\nexport const UpdateSessionRequestSchema = z\n .object({\n agent: SessionAgentSpecBodySchema.optional(),\n })\n .strict()\n .openapi('UpdateSessionRequest');\n\nexport type { Session } from '@truefoundry/trueforge-core/agent-session';\n\n/** Wire ISO-8601 (RFC 3339, offsets allowed) → Date for the store. */\nconst IsoTimestampQueryParam = z.iso\n .datetime({ offset: true })\n .openapi({ type: 'string', format: 'date-time' })\n .transform(s => new Date(s));\n\nexport const ListSessionsRequestQuerySchema = z\n .object({\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(PAGE_LIMIT)\n .optional()\n .default(PAGE_LIMIT)\n .describe(`Page size. Defaults to ${String(PAGE_LIMIT)}, max ${String(PAGE_LIMIT)}.`),\n order: z\n .enum(['asc', 'desc'])\n .optional()\n .default('desc')\n .describe('Sort sessions by `updated_at`. Defaults to \"desc\".')\n .openapi('ListSessionsOrder'),\n page_token: z\n .string()\n .min(1)\n .optional()\n .describe('Opaque keyset cursor from a previous response `next_page_token`.'),\n start_timestamp: IsoTimestampQueryParam.optional().describe(\n 'Inclusive lower bound on `created_at` (ISO-8601 / RFC 3339).',\n ),\n end_timestamp: IsoTimestampQueryParam.optional().describe(\n 'Inclusive upper bound on `created_at` (ISO-8601 / RFC 3339).',\n ),\n agent_id: z.string().min(1).optional().describe('When set, only sessions bound to this agent id are returned.'),\n })\n .openapi('ListSessionsRequestQuery');\n\nexport const GetSessionResponseSchema = z\n .object({\n data: SessionSchema,\n })\n .openapi('GetSessionResponse');\n\nexport const ListSessionsResponseSchema = z\n .object({\n data: z.array(SessionSchema),\n pagination: TokenPaginationSchema,\n })\n .openapi('ListSessionsResponse');\n","/** Server-only turn wire schemas (SSE resume / cancel / list). Core turn schemas live in agent-session. */\nimport { z } from '@hono/zod-openapi';\nimport { SessionEventSchema, TokenPaginationSchema, TurnSchema } from '@truefoundry/trueforge-core/agent-session';\nimport { EVENTS_PAGE_LIMIT, PAGE_LIMIT } from './common';\n\nexport { CreateTurnRequestSchema, TurnSchema } from '@truefoundry/trueforge-core/agent-session';\nexport type { Turn } from '@truefoundry/trueforge-core/agent-session';\n\nexport const SubscribeTurnQuerySchema = z\n .object({\n // Query strings need coerce; map null/'' to undefined first so Number(null)→0\n // cannot silently become a resume cursor (and so OpenAPI does not advertise null).\n after_sequence_number: z.preprocess(\n val => (val === null || val === '' ? undefined : val),\n z.coerce\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe(\n 'Exclusive resume cursor: replay only events with a sequence number greater than this value. Omit to start from the beginning of the live buffer.',\n ),\n ),\n })\n .openapi('SubscribeTurnQuery');\n\n/** Intentionally empty — cancel takes no body fields. */\nexport const CancelSessionRequestSchema = z\n .object({})\n .describe('Empty request body. Cancel identifies the session via the path only.')\n .openapi('CancelSessionRequest');\n/** Intentionally empty — success is signaled by HTTP 200 with `{}`. */\nexport const CancelSessionResponseSchema = z\n .object({})\n .describe('Empty success body. HTTP 200 means the cancel request was accepted (or nothing was running).')\n .openapi('CancelSessionResponse');\n\nexport const ListTurnsRequestQuerySchema = z\n .object({\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(PAGE_LIMIT)\n .optional()\n .default(PAGE_LIMIT)\n .describe(`Page size. Defaults to ${String(PAGE_LIMIT)}, max ${String(PAGE_LIMIT)}.`),\n page_token: z.string().optional().describe('Opaque token from a previous response `next_page_token`.'),\n })\n .openapi('ListTurnsRequestQuery');\n\nexport const GetTurnResponseSchema = z\n .object({\n data: TurnSchema,\n })\n .openapi('GetTurnResponse');\n\nexport const ListTurnsResponseSchema = z\n .object({\n data: z.array(TurnSchema),\n pagination: TokenPaginationSchema,\n })\n .openapi('ListTurnsResponse');\n\nexport const ListTurnEventsRequestQuerySchema = z\n .object({\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(EVENTS_PAGE_LIMIT)\n .optional()\n .default(EVENTS_PAGE_LIMIT)\n .describe(`Page size. Defaults to ${String(EVENTS_PAGE_LIMIT)}, max ${String(EVENTS_PAGE_LIMIT)}.`),\n page_token: z.string().optional().describe('Opaque token from a previous response `next_page_token`.'),\n order: z\n .enum(['asc', 'desc'])\n .optional()\n .default('asc')\n .describe('Sort events by insertion order. Defaults to \"asc\".')\n .openapi('ListTurnEventsOrder'),\n })\n .openapi('ListTurnEventsRequestQuery');\n\nexport const ListTurnEventsResponseSchema = z\n .object({\n data: z.array(SessionEventSchema),\n pagination: TokenPaginationSchema,\n })\n .openapi('ListTurnEventsResponse');\n\nexport const DownloadSandboxFileRequestQuerySchema = z\n .object({\n path: z\n .string()\n .min(1)\n .describe(\n \"Absolute path of the file inside the sandbox, as listed in the assistant's `sandbox_artifacts` block.\",\n ),\n })\n .openapi('DownloadSandboxFileRequestQuery');\n","/** Every paginated endpoint on this server shares one opaque-token contract. */\nexport const TOKEN_PAGINATION = {\n cursor: '$request.page_token',\n next_cursor: '$response.pagination.next_page_token',\n results: '$response.data',\n};\n","import { HTTPException } from 'hono/http-exception';\nimport { ulid } from 'ulid';\n\n/**\n * Mints a turn id owned by `executorId`. The server calls this at turn\n * creation (the id is opaque to the session library); `executorFromTurnId`\n * is the matching decoder on the routing path.\n */\nexport function mintPeeredTurnId(executorId: string): string {\n return `${ulid().toLowerCase()}.${executorId}`;\n}\n\n/** Decodes the owning executor; throws 400 for an id outside the grammar. */\nexport function executorFromTurnId(turnId: string): string {\n const parts = turnId.split('.');\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new HTTPException(400, { message: `ID ${turnId} is not a valid turn id` });\n }\n return parts[1];\n}\n","import { OpenAPIHono } from '@hono/zod-openapi';\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport type { Configuration } from 'openid-client';\nimport type { Logger } from 'winston';\nimport { clearAuthCookie, ID_TOKEN_COOKIE, OAUTH_STATE_COOKIE, readOAuthStateCookie } from '../auth/cookies';\nimport { resolveUserContext } from '../auth/identity';\nimport { authMiddleware, resolveAuthUser } from '../auth/middleware';\nimport { buildLoginAuthorization, exchangeAuthorizationCode, getOidcVerify } from '../auth/oidc';\nimport { safeReturnTo } from '../auth/safeReturnTo';\nimport { authLoginRoute, authLogoutRoute, meRoute, oAuthCallbackRoute } from '../routes/authRoutes';\nimport type { GetMeResponse } from '../schemas/auth';\n\n/** Login / OIDC failures land on `/?error=<reason>`. */\nfunction oauthErrorRedirect(reason: string): string {\n return `/?error=${encodeURIComponent(reason)}`;\n}\n\n/**\n * Auth surfaces mounted at /api/v1/auth: login, callback, logout, me.\n * Login, callback, and logout stay public; me requires {@link authMiddleware}.\n */\nexport function createAuthRouter(params: { oidcClient: Configuration | undefined; logger: Logger }) {\n const router = new OpenAPIHono();\n\n router.openapi(authLoginRoute, async c => {\n // TODO: remove this checks once the middleware is implemented\n if (!params.oidcClient) {\n return c.redirect('/', 302);\n }\n\n try {\n const authorizationUrl = await buildLoginAuthorization({\n context: c,\n client: params.oidcClient,\n returnTo: c.req.valid('query').return_to,\n });\n return c.redirect(authorizationUrl, 302);\n } catch (error) {\n params.logger.error('Failed to build login authorization', extractErrorLogFields(error));\n return c.redirect(oauthErrorRedirect('login_failed'), 302);\n }\n });\n\n router.openapi(oAuthCallbackRoute, async c => {\n if (!params.oidcClient) {\n return c.redirect('/', 302);\n }\n\n const query = c.req.valid('query');\n const pending = readOAuthStateCookie({ context: c, logger: params.logger });\n clearAuthCookie({ context: c, name: OAUTH_STATE_COOKIE });\n\n if (pending?.state !== query.state || query.error || !query.code) {\n // If already authenticated, redirect home instead of showing an error.\n if (await resolveAuthUser(c)) {\n return c.redirect('/', 302);\n }\n // Only reflect a non-empty IdP `error_description` when the IdP returned an error.\n // No fallback to the `error` code — blank/missing descriptions use the default.\n // Our own validation failures (state mismatch / missing code) stay generic too.\n const description = query.error_description?.trim();\n const reason = query.error && description ? description : 'login_failed';\n return c.redirect(oauthErrorRedirect(reason), 302);\n }\n\n try {\n await exchangeAuthorizationCode({\n context: c,\n client: params.oidcClient,\n callbackParams: new URL(c.req.url).searchParams,\n codeVerifier: pending.code_verifier,\n state: pending.state,\n });\n return c.redirect(safeReturnTo(pending.return_to), 302);\n } catch (error) {\n params.logger.error('Failed to exchange authorization code', extractErrorLogFields(error));\n if (await resolveAuthUser(c)) {\n return c.redirect(safeReturnTo(pending.return_to), 302);\n }\n const reason = error instanceof Error ? error.message : 'login_failed';\n return c.redirect(oauthErrorRedirect(reason), 302);\n }\n });\n\n router.openapi(authLogoutRoute, c => {\n // Cookie deletion is idempotent, so logout also succeeds when no cookie exists.\n clearAuthCookie({ context: c, name: ID_TOKEN_COOKIE });\n return c.body(null, 204);\n });\n\n const gated = new OpenAPIHono();\n gated.use('*', authMiddleware);\n gated.openapi(meRoute, c => {\n const user = resolveUserContext(c);\n const body: GetMeResponse = getOidcVerify()\n ? { type: 'oidc-connected', email: user.userRef, role: user.role }\n : { type: 'default', email: user.userRef, role: user.role };\n return c.json(body, 200);\n });\n router.route('/', gated);\n\n return router;\n}\n","import type { Context } from 'hono';\nimport { deleteCookie, getCookie, setCookie } from 'hono/cookie';\nimport type { Logger } from 'winston';\nimport { z } from 'zod';\nimport { getPublicBaseUrl } from '../config';\n\nexport const OAUTH_STATE_COOKIE = 'oauth_state';\nexport const ID_TOKEN_COOKIE = 'id_token';\n\nconst OAuthStateSchema = z.object({\n state: z.string(),\n code_verifier: z.string(),\n return_to: z.string(),\n});\n\nexport type OAuthState = z.infer<typeof OAuthStateSchema>;\n\nfunction getAuthCookieAttributes(): {\n httpOnly: boolean;\n sameSite: 'Lax' | 'Strict' | 'None';\n secure: boolean;\n path: string;\n} {\n return {\n httpOnly: true,\n sameSite: 'Lax' as const,\n secure: getPublicBaseUrl().startsWith('https://'),\n path: '/',\n };\n}\n\nexport function setAuthCookie(params: { context: Context; name: string; value: string; maxAgeSeconds: number }): void {\n setCookie(params.context, params.name, params.value, {\n ...getAuthCookieAttributes(),\n maxAge: params.maxAgeSeconds,\n });\n}\n\nexport function readOAuthStateCookie(params: { context: Context; logger: Logger }): OAuthState | undefined {\n const raw = getCookie(params.context, OAUTH_STATE_COOKIE);\n if (!raw) {\n return undefined;\n }\n try {\n // JSON.parse throws SyntaxError when the cookie value is not JSON.\n const result = OAuthStateSchema.safeParse(JSON.parse(raw));\n if (!result.success) {\n params.logger.warn('oauth_state cookie failed schema validation', { error: result.error.message });\n return undefined;\n }\n return result.data;\n } catch (error) {\n params.logger.warn('oauth_state cookie is not valid JSON', {\n error: error instanceof Error ? error.message : error,\n });\n return undefined;\n }\n}\n\nexport function clearAuthCookie(params: { context: Context; name: string }): void {\n deleteCookie(params.context, params.name, getAuthCookieAttributes());\n}\n\nexport function readIdTokenCookie(params: { context: Context }): string | undefined {\n return getCookie(params.context, ID_TOKEN_COOKIE);\n}\n","import type { Context } from 'hono';\nimport { createRemoteJWKSet, type JWTVerifyGetKey } from 'jose';\nimport {\n authorizationCodeGrant,\n buildAuthorizationUrl,\n calculatePKCECodeChallenge,\n type Configuration,\n discovery,\n randomPKCECodeVerifier,\n randomState,\n} from 'openid-client';\nimport { getPublicBaseUrl, type OIDCConfig } from '../config';\nimport { buildAuthorizationRequestParams } from './claims';\nimport { ID_TOKEN_COOKIE, OAUTH_STATE_COOKIE, setAuthCookie } from './cookies';\nimport { safeReturnTo } from './safeReturnTo';\n\nconst CALLBACK_PATH = '/api/v1/auth/callback';\nconst OAUTH_STATE_MAX_AGE_SECONDS = 10 * 60;\nconst ID_TOKEN_COOKIE_MAX_AGE_SECONDS = 24 * 60 * 60;\n\n/** JWKS + claim config used by cookie JWT verification when auth is enabled. */\nexport interface OidcVerify {\n jwks: JWTVerifyGetKey;\n issuer: string;\n audience: string;\n oidcConfig: OIDCConfig;\n}\n\n/** Single instance of the OIDC verification. */\nlet oidcVerify: OidcVerify | null = null;\n\n/** Enable cookie JWT verification using the IdP client + claim-mapping config from `initOidc`. */\nexport function enableOidcAuth(params: { client: Configuration; oidcConfig: OIDCConfig }): void {\n const metadata = params.client.serverMetadata();\n if (!metadata.jwks_uri) {\n throw new Error('OIDC discovery did not return jwks_uri; cannot verify ID tokens');\n }\n\n oidcVerify = {\n jwks: createRemoteJWKSet(new URL(metadata.jwks_uri)),\n issuer: metadata.issuer,\n audience: params.client.clientMetadata().client_id,\n oidcConfig: params.oidcConfig,\n };\n}\n\n/** Disable OIDC cookie auth (no IdP / standalone). Protected routes use the default user context. */\nexport function disableOidcAuth(): void {\n oidcVerify = null;\n}\n\n/** Active verification config, or `null` when auth is disabled. */\nexport function getOidcVerify(): OidcVerify | null {\n return oidcVerify;\n}\n\n/** Discover the IdP once at process startup when auth is enabled; wires cookie auth verification. */\nexport async function initOidc(oidc: OIDCConfig | undefined): Promise<Configuration | undefined> {\n if (!oidc) {\n disableOidcAuth();\n return undefined;\n }\n\n const client = await discovery(new URL(oidc.OIDC_ISSUER_URL), oidc.OIDC_CLIENT_ID, oidc.OIDC_CLIENT_SECRET);\n enableOidcAuth({ client, oidcConfig: oidc });\n return client;\n}\n\nfunction authCallbackUrl(): string {\n const publicBaseUrl = getPublicBaseUrl();\n return `${publicBaseUrl}${CALLBACK_PATH}`;\n}\n\nexport async function buildLoginAuthorization(params: {\n context: Context;\n client: Configuration;\n returnTo: string | undefined;\n}): Promise<string> {\n const oidcConfig = getOidcVerify()?.oidcConfig;\n if (!oidcConfig) {\n throw new Error(\n 'OIDC claim configuration is unavailable; call initOidc before building a login authorization URL.',\n );\n }\n\n const { scopes, claims } = buildAuthorizationRequestParams(oidcConfig);\n const returnTo = safeReturnTo(params.returnTo);\n const codeVerifier = randomPKCECodeVerifier();\n const state = randomState();\n const authorizationUrl = buildAuthorizationUrl(params.client, {\n redirect_uri: authCallbackUrl(),\n scope: scopes.join(' '),\n claims: JSON.stringify(claims),\n code_challenge: await calculatePKCECodeChallenge(codeVerifier),\n code_challenge_method: 'S256',\n state,\n });\n setAuthCookie({\n context: params.context,\n name: OAUTH_STATE_COOKIE,\n value: JSON.stringify({\n state,\n code_verifier: codeVerifier,\n return_to: returnTo,\n }),\n maxAgeSeconds: OAUTH_STATE_MAX_AGE_SECONDS,\n });\n return authorizationUrl.href;\n}\n\nexport async function exchangeAuthorizationCode(params: {\n context: Context;\n client: Configuration;\n /** Whole IdP response query: openid-client validates `state`, `error` and `iss` from it. */\n callbackParams: URLSearchParams;\n codeVerifier: string;\n state: string;\n}): Promise<void> {\n // Origin and path come from config so redirect_uri matches the one registered with the IdP.\n const callbackUrl = new URL(authCallbackUrl());\n callbackUrl.search = params.callbackParams.toString();\n const tokens = await authorizationCodeGrant(params.client, callbackUrl, {\n pkceCodeVerifier: params.codeVerifier,\n expectedState: params.state,\n });\n const idToken = tokens.id_token;\n if (!idToken) {\n throw new Error('Token response missing id_token');\n }\n setAuthCookie({\n context: params.context,\n name: ID_TOKEN_COOKIE,\n value: idToken,\n maxAgeSeconds: ID_TOKEN_COOKIE_MAX_AGE_SECONDS,\n });\n}\n","import type { OIDCConfig } from '../config';\nimport type { Role, UserContext } from './identity';\n\n/** Raw claims from a decoded ID token; values are untyped until read here. */\nexport type IdTokenClaims = Record<string, unknown>;\n\n/**\n * Normalizes a claim value into a string list to check membership against.\n * OIDC doesn't fix the shape of claims like `groups`/`roles`: most IdPs\n * return an array, some collapse a single membership down to a bare string,\n * and a missing/misconfigured claim mapping can omit it entirely. Anything\n * else (number, object, null) is treated as \"no values\" rather than thrown -\n * a malformed claim should fail a user out of admin, not crash the request.\n */\nexport function claimValues(claim: unknown): string[] {\n if (Array.isArray(claim)) {\n return claim.filter((value): value is string => typeof value === 'string');\n }\n if (typeof claim === 'string') {\n return [claim];\n }\n return [];\n}\n\n/**\n * The stable identity key for this caller. An identity that can't be resolved\n * means the token can't be trusted to identify anyone, so this throws.\n */\nexport function resolveUserRef(claims: IdTokenClaims, config: OIDCConfig): string {\n const value = claims[config.OIDC_USER_REFERENCE_CLAIM];\n if (typeof value !== 'string' || value === '') {\n throw new Error(\n `ID token is missing a non-empty \"${config.OIDC_USER_REFERENCE_CLAIM}\" claim (OIDC_USER_REFERENCE_CLAIM).`,\n );\n }\n return value;\n}\n\n/**\n * Admin iff the configured role claim's values include the configured admin\n * value, exact case-sensitive string match.\n */\nexport function resolveRole(claims: IdTokenClaims, config: OIDCConfig): Role {\n return claimValues(claims[config.OIDC_USER_ROLE_CLAIM]).includes(config.OIDC_ADMIN_ROLE_VALUE) ? 'admin' : 'user';\n}\n\n/** Everything `/callback` (and later `/me`, once sessions are real) needs from a set of claims. */\nexport function toUserContext(claims: IdTokenClaims, config: OIDCConfig): UserContext {\n return {\n userRef: resolveUserRef(claims, config),\n role: resolveRole(claims, config),\n };\n}\n\nexport interface AuthorizationRequestParams {\n scopes: string[];\n /** OIDC `claims` request parameter; pass through as-is. */\n claims: { id_token: Record<string, { essential: true }> };\n}\n\n/**\n * Scopes + `claims` parameter for the authorization request, derived\n * from configured claim names and {@link OIDCConfig.OIDC_SCOPES}.\n * `essential: true` on the role claim makes the IdP reject the\n * login outright if it can't actually produce that claim (e.g. a broken\n * claim mapping) instead of silently omitting it and defaulting the user to\n * non-admin.\n */\nexport function buildAuthorizationRequestParams(config: OIDCConfig): AuthorizationRequestParams {\n return {\n scopes: config.OIDC_SCOPES,\n claims: {\n id_token: {\n [config.OIDC_USER_REFERENCE_CLAIM]: { essential: true },\n [config.OIDC_USER_ROLE_CLAIM]: { essential: true },\n },\n },\n };\n}\n","/**\n * Same-origin relative path only.\n * - starts with `/`\n * - not `//…` (open redirect)\n * - not `/api` or `/api/…`\n */\nconst SAFE_RETURN_TO = /^\\/(?!\\/|api(?:\\/|$)).*/;\n\nfunction isSafeReturnTo(value: string): boolean {\n return SAFE_RETURN_TO.test(value);\n}\n\n/** Same-origin path, or `/` when missing or unsafe. */\nexport function safeReturnTo(value: string | undefined): string {\n if (value && isSafeReturnTo(value)) {\n return value;\n }\n return '/';\n}\n","import type { Context } from 'hono';\nimport { getOidcVerify } from './oidc';\n\nexport type Role = 'admin' | 'user';\n\nexport interface UserContext {\n userRef: string;\n role: Role;\n}\n\n/**\n * Fixed identity when no identity provider is configured (standalone / auth disabled).\n * Stamped onto sessions as `created_by` and used for ownership checks.\n */\nexport const LOCAL_USER_CONTEXT: UserContext = {\n userRef: 'trueforge-default',\n role: 'admin',\n};\n\n/** Auth disabled: always true. Auth enabled: admin role only. */\nexport function isAdmin(user: UserContext): boolean {\n if (!getOidcVerify()) {\n return true;\n }\n return user.role === 'admin';\n}\n\n/** Resolves the caller identity from the request context. Injected on session/turn routers. */\nexport type ResolveUserContext = (c: Context) => UserContext;\n\n/**\n * Caller {@link UserContext} for the current request.\n * Requires auth middleware to have set `c.var.user`.\n */\nexport function resolveUserContext(c: Context): UserContext {\n const uc = c.get('user_context');\n if (uc === undefined) {\n throw new Error('UserContext missing; auth middleware did not run');\n }\n return uc;\n}\n","import type { Context, MiddlewareHandler } from 'hono';\nimport { HTTPException } from 'hono/http-exception';\nimport { jwtVerify } from 'jose';\nimport { toUserContext, type IdTokenClaims } from './claims';\nimport { readIdTokenCookie } from './cookies';\nimport { LOCAL_USER_CONTEXT, isAdmin, type UserContext } from './identity';\nimport { getOidcVerify } from './oidc';\n\ndeclare module 'hono' {\n interface ContextVariableMap {\n user_context?: UserContext;\n }\n}\n\nconst AUTH_HEADER_TYPE = 'Bearer';\n\n/**\n * OIDC ID token from `Authorization: Bearer <jwt>` when present.\n * Case-insensitive scheme; rejects empty credentials. Non-Bearer schemes → undefined\n * so cookie auth can still apply.\n */\nexport function readBearerIdToken(c: Context): string | undefined {\n const header = c.req.header('Authorization')?.trim();\n if (!header) {\n return undefined;\n }\n const prefix = `${AUTH_HEADER_TYPE} `;\n if (!header.toLowerCase().startsWith(prefix.toLowerCase())) {\n return undefined;\n }\n const token = header.slice(prefix.length).trim();\n return token.length > 0 ? token : undefined;\n}\n\n/**\n * Prefer Bearer over the browser cookie when both are sent (explicit API auth wins).\n */\nexport function readIdToken(c: Context): string | undefined {\n return readBearerIdToken(c) ?? readIdTokenCookie({ context: c });\n}\n\n/**\n * Bearer or cookie ID token → {@link UserContext} when auth is enabled and the JWT is valid.\n * Missing/invalid JWT → `undefined`. Claim mapping failures after a successful verify rethrow.\n */\nexport async function resolveAuthUser(c: Context): Promise<UserContext | undefined> {\n const oidcVerify = getOidcVerify();\n if (!oidcVerify) {\n return undefined;\n }\n\n const token = readIdToken(c);\n if (!token) {\n return undefined;\n }\n\n let payload: Awaited<ReturnType<typeof jwtVerify>>['payload'];\n try {\n ({ payload } = await jwtVerify(token, oidcVerify.jwks, {\n issuer: oidcVerify.issuer,\n audience: oidcVerify.audience,\n }));\n } catch {\n return undefined;\n }\n\n const claims: IdTokenClaims = { ...payload };\n return toUserContext(claims, oidcVerify.oidcConfig);\n}\n\n/** Set `c.var.user` and continue, or throw 401. When auth is disabled, sets {@link LOCAL_USER_CONTEXT}. */\nexport const authMiddleware: MiddlewareHandler = async (c, next) => {\n if (!getOidcVerify()) {\n c.set('user_context', LOCAL_USER_CONTEXT);\n return next();\n }\n\n try {\n const user = await resolveAuthUser(c);\n if (!user) {\n throw new HTTPException(401, { message: 'Authentication required' });\n }\n c.set('user_context', user);\n } catch (error) {\n if (error instanceof HTTPException) {\n throw error;\n }\n // Valid JWT but claim mapping failed (e.g. missing user reference claim).\n throw new HTTPException(401, { message: 'Authentication required', cause: error });\n }\n return next();\n};\n\n/** Admin gate: local admin when auth is disabled; when auth is enabled requires an authenticated admin. */\nexport const adminAuthMiddleware: MiddlewareHandler = async (c, next) => {\n if (!getOidcVerify()) {\n c.set('user_context', LOCAL_USER_CONTEXT);\n return next();\n }\n\n try {\n const user = await resolveAuthUser(c);\n if (!user) {\n throw new HTTPException(401, { message: 'Authentication required' });\n }\n if (!isAdmin(user)) {\n throw new HTTPException(403, { message: 'Admin access required' });\n }\n c.set('user_context', user);\n } catch (error) {\n if (error instanceof HTTPException) {\n throw error;\n }\n throw new HTTPException(401, { message: 'Authentication required', cause: error });\n }\n\n return next();\n};\n","/**\n * Auth route definitions (mounted at /api/v1/auth). Handlers in apis/auth.ts.\n *\n * `login`/`callback`/`logout` are browser-session helpers, never called by SDK\n * consumers — they carry `x-fern-ignore`, the same convention used for the\n * MCP OAuth callback in mcpOAuthRoutes.ts. `me` generates normally.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { AuthLoginQuerySchema, GetMeResponseSchema, OAuthCallbackQuerySchema } from '../schemas/auth';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { OpenApiTag } from './openapiTags';\n\nexport const authLoginRoute = createRoute({\n method: 'get',\n path: '/login',\n tags: [OpenApiTag.AUTH],\n summary: 'Start the login flow',\n description:\n 'Redirects the browser to the configured identity provider. In local/single-binary mode, redirects straight ' +\n 'back into the app — there is nothing to log into.',\n 'x-fern-ignore': true,\n 'x-excluded': true,\n request: { query: AuthLoginQuerySchema },\n responses: {\n 302: { description: 'Redirect to the IdP authorization endpoint.' },\n },\n});\n\nexport const oAuthCallbackRoute = createRoute({\n method: 'get',\n path: '/callback',\n tags: [OpenApiTag.AUTH],\n summary: 'Login callback',\n description:\n 'Browser-redirect target hit by the identity provider after login, never called directly by SDK consumers. ' +\n 'In local/single-binary mode, redirects straight back into the app.',\n 'x-fern-ignore': true,\n 'x-excluded': true,\n request: { query: OAuthCallbackQuerySchema },\n responses: {\n 302: { description: 'Redirect back into the app on success, or to /?error=<reason> on failure.' },\n },\n});\n\nexport const authLogoutRoute = createRoute({\n method: 'post',\n path: '/logout',\n tags: [OpenApiTag.AUTH],\n summary: 'Clear the local session',\n description:\n 'Ends the local harness session only — does not hit the IdP end-session endpoint. A no-op in local/single-binary ' +\n 'mode, since there is no real session to clear.',\n 'x-fern-ignore': true,\n 'x-excluded': true,\n responses: {\n 204: { description: 'Session cookie cleared.' },\n },\n});\n\nexport const meRoute = createRoute({\n method: 'get',\n path: '/me',\n tags: [OpenApiTag.AUTH],\n summary: 'Current session',\n description:\n 'Returns the authenticated caller identity. When auth is enabled this requires a valid ' +\n '`id_token` cookie or `Authorization: Bearer` ID token (401 otherwise). When auth is disabled, ' +\n 'returns the default identity.',\n 'x-fern-sdk-group-name': ['auth'],\n 'x-fern-sdk-method-name': 'me',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetMeResponseSchema } },\n description: 'Session type and identity for the current request.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Auth is enabled and the request has no valid cookie or Bearer ID token.',\n },\n },\n});\n","/** Auth wire schemas. */\nimport { z } from '@hono/zod-openapi';\n\nexport const AuthLoginQuerySchema = z.object({\n return_to: z\n .string()\n .optional()\n .describe('Path to return to after login. Must be a same-origin relative path; anything else falls back to \"/\".'),\n});\n\nexport const OAuthCallbackQuerySchema = z.object({\n code: z.string().min(1).optional().describe('Authorization code, present when the user granted consent.'),\n state: z\n .string()\n .min(1)\n .describe('Opaque token; correlates this callback to its pending login. Always present, success or error.'),\n error: z\n .string()\n .optional()\n .describe('Error code from the identity provider, present instead of `code` if the user denied consent.'),\n error_description: z\n .string()\n .optional()\n .describe('Human-readable error detail from the identity provider when `error` is set.'),\n});\n\nexport const OAuthCallbackSuccessSchema = z.object({\n success: z.literal(true).describe('Present when the OAuth callback completed without a return_to.'),\n});\n\nexport const GetMeResponseSchema = z\n .object({\n type: z\n .enum(['default', 'oidc-connected'])\n .describe(\n 'Session kind: `default` when no valid OIDC session; `oidc-connected` after a successful browser login.',\n ),\n email: z.string().describe('User email from the ID token when connected; `\"default\"` when anonymous.'),\n role: z.string().describe('Caller role.'),\n })\n .openapi('GetMeResponse');\n\nexport type GetMeResponse = z.infer<typeof GetMeResponseSchema>;\n","import { OpenAPIHono } from '@hono/zod-openapi';\nimport { extractErrorLogFields } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport { isAdmin, resolveUserContext } from '../auth/identity';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { WithTransaction } from '../db/transaction';\nimport { getCapabilitiesRoute } from '../routes/capabilityRoutes';\nimport { isLocalSandboxFallbackEnabled } from '../sandbox/localRuntime';\nimport { checkSnapshotStatus } from '../sandbox/providerUtils';\nimport type { SandboxBuildStatus } from '../schemas/sandboxProvider';\nimport { TENANT_ID } from './sessions';\n\n/**\n * Why skills are unavailable, keyed off the sandbox build status.\n * `pending` is transient (retry); everything else (no provider / failed / unknown) reads as not configured.\n */\nfunction skillDisabledReason(status: SandboxBuildStatus | undefined): string {\n if (status === 'pending') {\n return 'Skills run in a sandbox whose image is still being prepared — retry shortly.';\n }\n return 'Skills run in a sandbox, which is not configured.';\n}\n\nexport function createCapabilitiesRouter<TTransaction>(deps: {\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n logger: Logger;\n}) {\n const router = new OpenAPIHono();\n router.openapi(getCapabilitiesRoute, async c => {\n // Sandbox is usable only when a provider is configured AND its image build reports ready.\n // Refresh the persisted status (and re-activate an idle snapshot); fail closed (disabled) if it throws.\n let status: SandboxBuildStatus | undefined;\n try {\n const refreshed = await checkSnapshotStatus({\n store: deps.sandboxProviderStore,\n tenant_id: TENANT_ID,\n logger: deps.logger,\n });\n status = refreshed?.status;\n } catch (error) {\n deps.logger.warn('Sandbox image status check failed; reporting sandbox disabled', extractErrorLogFields(error));\n }\n const sandboxEnabled = status === 'ready' || (status === undefined && isLocalSandboxFallbackEnabled());\n const settingsEnabled = isAdmin(resolveUserContext(c));\n return c.json(\n {\n data: {\n sandbox: { enabled: sandboxEnabled },\n skill: sandboxEnabled ? { enabled: true } : { enabled: false, reason: skillDisabledReason(status) },\n settings: { enabled: settingsEnabled },\n },\n },\n 200,\n );\n });\n return router;\n}\n","import { createRoute, z } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { OpenApiTag } from './openapiTags';\n\nconst SandboxCapabilitySchema = z\n .object({\n enabled: z.boolean().describe('Whether a sandbox provider is configured for this tenant.'),\n })\n .openapi('SandboxCapability');\n\nconst SkillCapabilitySchema = z\n .object({\n enabled: z\n .boolean()\n .describe('Whether skills are available. False when sandbox is not enabled (skills require a sandbox).'),\n reason: z.string().optional().describe('Present when skills are disabled. Explains why.'),\n })\n .openapi('SkillCapability');\n\nconst SettingsCapabilitySchema = z\n .object({\n enabled: z.boolean().describe('Whether the settings UI/API is enabled.'),\n })\n .openapi('SettingsCapability');\n\nconst CapabilitiesDataSchema = z\n .object({\n sandbox: SandboxCapabilitySchema,\n skill: SkillCapabilitySchema,\n settings: SettingsCapabilitySchema,\n })\n .openapi('CapabilitiesData');\n\nconst GetCapabilitiesResponseSchema = z\n .object({\n data: CapabilitiesDataSchema,\n })\n .openapi('GetCapabilitiesResponse');\n\nexport const getCapabilitiesRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.CAPABILITIES],\n summary: 'Get server capabilities',\n 'x-fern-sdk-group-name': ['server'],\n 'x-fern-sdk-method-name': 'get_capabilities',\n description: 'Report optional runtime capabilities available for this tenant.',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetCapabilitiesResponseSchema } },\n description: 'Server capabilities.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { SUPPORTED_REASONING_EFFORTS } from '@truefoundry/trueforge-core/core';\nimport type { McpCatalog } from '../catalog/McpCatalog';\nimport type { ModelCatalog } from '../catalog/ModelCatalog';\nimport type { SandboxCatalog } from '../catalog/SandboxCatalog';\nimport type { SkillCatalog } from '../catalog/SkillCatalog';\nimport {\n listMcpServerCatalogRoute,\n listModelProviderCatalogRoute,\n listSandboxProviderCatalogRoute,\n listSkillCatalogRoute,\n} from '../routes/catalogRoutes';\nimport type { CatalogModelProvider } from '../schemas/modelCatalog';\n\nexport interface CatalogRouterDeps {\n modelCatalog: ModelCatalog;\n mcpCatalog: McpCatalog;\n skillCatalog: SkillCatalog;\n sandboxCatalog: SandboxCatalog;\n}\n\nexport function createCatalogRouter(deps: CatalogRouterDeps) {\n const listModelProvidersHandler: RouteHandler<typeof listModelProviderCatalogRoute> = c => {\n const loadedProvidersCatalog = deps.modelCatalog.list();\n // make a copy of the loaded providers catalog and add the custom provider sentinel\n const providersCatalog: CatalogModelProvider[] = [...loadedProvidersCatalog];\n providersCatalog.push({\n type: 'custom',\n supported_reasoning_efforts: [...SUPPORTED_REASONING_EFFORTS],\n });\n return c.json({ data: providersCatalog }, 200);\n };\n\n const listMcpServersHandler: RouteHandler<typeof listMcpServerCatalogRoute> = c => {\n return c.json({ data: [...deps.mcpCatalog.list()] }, 200);\n };\n\n const listSkillsHandler: RouteHandler<typeof listSkillCatalogRoute> = c => {\n return c.json({ data: [...deps.skillCatalog.list()] }, 200);\n };\n\n const listSandboxProvidersHandler: RouteHandler<typeof listSandboxProviderCatalogRoute> = c => {\n return c.json({ data: [...deps.sandboxCatalog.list()] }, 200);\n };\n\n const router = new OpenAPIHono();\n router.openapi(listModelProviderCatalogRoute, listModelProvidersHandler);\n router.openapi(listMcpServerCatalogRoute, listMcpServersHandler);\n router.openapi(listSkillCatalogRoute, listSkillsHandler);\n router.openapi(listSandboxProviderCatalogRoute, listSandboxProvidersHandler);\n return router;\n}\n","/**\n * Discovery catalog routes (mounted at /api/v1/catalogs).\n * Readable by any authenticated user — not under admin /settings.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { GetMcpServerCatalogResponseSchema } from '../schemas/mcpCatalog';\nimport { GetModelProviderCatalogResponseSchema } from '../schemas/modelCatalog';\nimport { GetSandboxProviderCatalogResponseSchema } from '../schemas/sandboxCatalog';\nimport { GetSkillCatalogResponseSchema } from '../schemas/skillCatalog';\nimport { OpenApiTag } from './openapiTags';\n\nexport const listModelProviderCatalogRoute = createRoute({\n method: 'get',\n path: '/model-providers',\n tags: [OpenApiTag.MODELS],\n summary: 'Get the model catalog',\n description:\n 'Shipped model-provider presets (discovery-only). Copy into PUT /settings/model-providers to configure. ' +\n 'Includes a `custom` sentinel with `supported_reasoning_efforts`.',\n 'x-fern-sdk-group-name': ['catalogs', 'modelProviders'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetModelProviderCatalogResponseSchema } },\n description: 'Shipped model-provider presets.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Not authenticated.',\n },\n },\n});\n\nexport const listMcpServerCatalogRoute = createRoute({\n method: 'get',\n path: '/mcp-servers',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'Get the MCP catalog',\n description: 'Shipped MCP server presets (discovery-only). Copy into PUT /settings/mcp-servers to configure.',\n 'x-fern-sdk-group-name': ['catalogs', 'mcpServers'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetMcpServerCatalogResponseSchema } },\n description: 'Shipped MCP server presets.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Not authenticated.',\n },\n },\n});\n\nexport const listSkillCatalogRoute = createRoute({\n method: 'get',\n path: '/skills',\n tags: [OpenApiTag.SKILLS],\n summary: 'Get the skill catalog',\n description: 'Shipped skill presets (discovery-only). Copy into PUT /settings/skills to configure.',\n 'x-fern-sdk-group-name': ['catalogs', 'skills'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSkillCatalogResponseSchema } },\n description: 'Shipped skill presets.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Not authenticated.',\n },\n },\n});\n\nexport const listSandboxProviderCatalogRoute = createRoute({\n method: 'get',\n path: '/sandbox-providers',\n tags: [OpenApiTag.SANDBOXES],\n summary: 'Get the sandbox provider catalog',\n description:\n 'Shipped sandbox-provider presets (discovery-only). Copy into PUT /settings/sandbox-providers to configure.',\n 'x-fern-sdk-group-name': ['catalogs', 'sandboxProviders'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSandboxProviderCatalogResponseSchema } },\n description: 'Shipped sandbox-provider presets.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Not authenticated.',\n },\n },\n});\n","/**\n * Shipped mcp-catalog.yaml schemas (discovery presets). Separate from\n * configured MCP server manifests in mcpServer.ts.\n */\nimport { z } from '@hono/zod-openapi';\nimport { NameSchema, uniqueNames } from './common';\nimport { McpServerDescriptionSchema, McpServerManifestAuthSchema, McpServerTypeSchema } from './mcpServer';\n\n/** Catalog entry — discovery preset the settings UI copies into a PUT body. */\nexport const CatalogMcpServerSchema = z\n .object({\n type: McpServerTypeSchema,\n name: NameSchema,\n logo: z.url().optional().describe('URL of the MCP server logo asset.'),\n url: z.url().describe('URL of the remote MCP server.'),\n description: McpServerDescriptionSchema,\n auth: McpServerManifestAuthSchema.optional(),\n })\n .strict()\n .openapi('CatalogMCPServer');\n\nexport const McpCatalogFileSchema = z\n .object({\n mcp_servers: z.array(CatalogMcpServerSchema),\n })\n .strict()\n .superRefine((file, ctx) => {\n uniqueNames(file.mcp_servers, ctx);\n });\n\nexport const GetMcpServerCatalogResponseSchema = z\n .object({\n data: z.array(CatalogMcpServerSchema),\n })\n .openapi('GetMCPServerCatalogResponse');\n\nexport type CatalogMcpServer = z.infer<typeof CatalogMcpServerSchema>;\nexport type McpCatalogFile = z.infer<typeof McpCatalogFileSchema>;\n","/**\n * Shipped model-catalog.yaml schemas (discovery presets). Separate from\n * configured provider manifests in modelProvider.ts.\n */\nimport { z } from '@hono/zod-openapi';\nimport { uniqueTypes } from './common';\nimport {\n ConfiguredModelSchema,\n ModelProviderTypeSchema,\n ReasoningEffortSchema,\n refineUniqueModels,\n} from './modelProvider';\n\n/**\n * Catalog entry. Well-known types list model presets; `custom` is a sentinel that\n * carries `supported_reasoning_efforts` for the custom-provider settings form.\n */\nexport const CatalogWellKnownModelProviderTypeSchema = ModelProviderTypeSchema.exclude(['custom']).openapi(\n 'CatalogWellKnownModelProviderType',\n);\n\n/** Same shape as a configured model; named for the catalog view it appears in. */\nexport const CatalogModelSchema = ConfiguredModelSchema.openapi('CatalogModel');\n\nexport const CatalogWellKnownModelProviderSchema = z\n .object({\n type: CatalogWellKnownModelProviderTypeSchema,\n logo: z.url().optional().describe('URL of the provider logo asset'),\n models: z.array(CatalogModelSchema).describe('Preset models'),\n })\n .strict()\n .openapi('CatalogWellKnownModelProvider');\n\nexport const CatalogCustomModelProviderSchema = z\n .object({\n type: z.literal('custom'),\n supported_reasoning_efforts: z\n .array(ReasoningEffortSchema)\n .describe('Supported reasoning-effort values for this provider'),\n })\n .strict()\n .openapi('CatalogCustomModelProvider');\n\nexport const CatalogModelProviderSchema = z\n .union([CatalogWellKnownModelProviderSchema, CatalogCustomModelProviderSchema])\n .openapi('CatalogModelProvider');\n\nexport const ModelCatalogFileSchema = z\n .object({\n providers: z.array(CatalogWellKnownModelProviderSchema),\n })\n .strict()\n .superRefine((file, ctx) => {\n uniqueTypes(file.providers, ctx);\n for (const provider of file.providers) {\n refineUniqueModels(provider.models, ctx);\n }\n });\n\nexport const GetModelProviderCatalogResponseSchema = z\n .object({\n data: z.array(CatalogModelProviderSchema),\n })\n .openapi('GetModelProviderCatalogResponse');\n\nexport type CatalogWellKnownModelProvider = z.infer<typeof CatalogWellKnownModelProviderSchema>;\nexport type CatalogModelProvider = z.infer<typeof CatalogModelProviderSchema>;\nexport type ModelCatalogFile = z.infer<typeof ModelCatalogFileSchema>;\n","/**\n * Model-provider domain + wire schemas: configured provider manifests (DB jsonb)\n * and OpenAPI request/response shapes. Catalog file schemas live on ModelCatalog.\n */\nimport { z } from '@hono/zod-openapi';\nimport { SUPPORTED_REASONING_EFFORTS, VERCEL_AI_PROVIDER_NAMES } from '@truefoundry/trueforge-core/core';\nimport { NameSchema, uniqueNames, type ResourceName } from './common';\n\n/** Every type the harness has an adapter for; a test asserts each one has a schema below. */\nexport const ModelProviderTypeSchema = z.enum(VERCEL_AI_PROVIDER_NAMES).openapi('ModelProviderType');\n\nexport type ModelProviderType = z.infer<typeof ModelProviderTypeSchema>;\n\nexport const ReasoningEffortSchema = z.enum(SUPPORTED_REASONING_EFFORTS).openapi('ReasoningEffort');\n\nexport type ReasoningEffort = z.infer<typeof ReasoningEffortSchema>;\n\nexport const ModelPropertiesSchema = z\n .object({\n context_length: z.number().int().positive().optional().describe('Maximum context window size in tokens.'),\n max_output_tokens: z.number().int().positive().optional().describe('Maximum output tokens the model can generate.'),\n reasoning_efforts: z\n .array(ReasoningEffortSchema)\n .min(1)\n .optional()\n .describe('Supported reasoning-effort values for this model.'),\n })\n .strict()\n .describe('Optional model capability metadata.')\n .openapi('ModelProperties');\n\nexport const ConfiguredModelSchema = z\n .object({\n model_id: z.string().min(1).describe('Upstream, provider-specific identifier sent to the provider API.'),\n name: NameSchema,\n properties: ModelPropertiesSchema,\n })\n .strict()\n .openapi('ConfiguredModel');\n\n/** Adds issues when two models share a `model_id` or a `name`. */\nexport function refineUniqueModels(models: { model_id: string; name: string }[], ctx: z.RefinementCtx): void {\n uniqueNames(models, ctx);\n const seenModelIds = new Set<string>();\n for (const model of models) {\n if (seenModelIds.has(model.model_id)) {\n ctx.addIssue({\n code: 'custom',\n message: `Duplicate model_id \"${model.model_id}\" — model_ids must be unique within a provider`,\n path: ['models'],\n });\n }\n seenModelIds.add(model.model_id);\n }\n}\n\nconst ModelProviderAuthSchema = z\n .object({\n api_key: z\n .string()\n .min(1)\n .describe(\n 'Provider API key. Responses are redacted; on PUT, a real value sets/rotates and a redacted value keeps the stored key.',\n ),\n })\n .strict()\n .describe('Provider authentication credentials.')\n .openapi('ModelProviderAuth');\n\nconst ModelProviderManifestBaseSchema = z\n .object({\n auth: ModelProviderAuthSchema,\n models: z.array(ConfiguredModelSchema).min(1).describe('Models exposed by this provider (at least one).'),\n })\n .strict();\n\n/**\n * A well-known provider has no name of its own: it is named after its type, which limits a tenant to\n * one of each because the `(tenant_id, name)` primary key replaces the row rather than adding a\n * sibling. `base_url` defaults to the adapter's endpoint and stays overridable.\n */\nfunction wellKnownProviderSchema<Type extends Exclude<ModelProviderType, 'custom'>>({\n type,\n base_url,\n}: {\n type: Type;\n base_url: string;\n}) {\n return ModelProviderManifestBaseSchema.extend({\n type: z.literal(type),\n base_url: z.url().default(base_url).describe(\"Override of the provider's default API base URL.\"),\n }).strict();\n}\n\nconst OpenAiModelProviderSchema = wellKnownProviderSchema({\n type: 'openai',\n base_url: 'https://api.openai.com/v1',\n}).openapi('OpenAIModelProvider');\n\nconst AnthropicModelProviderSchema = wellKnownProviderSchema({\n type: 'anthropic',\n base_url: 'https://api.anthropic.com/v1',\n}).openapi('AnthropicModelProvider');\n\nconst GoogleGeminiModelProviderSchema = wellKnownProviderSchema({\n type: 'google-gemini',\n base_url: 'https://generativelanguage.googleapis.com/v1beta',\n}).openapi('GoogleGeminiModelProvider');\n\nconst FireworksModelProviderSchema = wellKnownProviderSchema({\n type: 'fireworks',\n base_url: 'https://api.fireworks.ai/inference/v1',\n}).openapi('FireworksModelProvider');\n\nconst ZaiModelProviderSchema = wellKnownProviderSchema({\n type: 'zai',\n base_url: 'https://api.z.ai/api/paas/v4',\n}).openapi('ZaiModelProvider');\n\nconst MoonshotModelProviderSchema = wellKnownProviderSchema({\n type: 'moonshot',\n base_url: 'https://api.moonshot.ai/v1',\n}).openapi('MoonshotModelProvider');\n\nconst TogetherAIModelProviderSchema = wellKnownProviderSchema({\n type: 'together',\n base_url: 'https://api.together.xyz/v1',\n}).openapi('TogetherAIModelProvider');\n\nconst AlibabaModelProviderSchema = wellKnownProviderSchema({\n type: 'alibaba',\n base_url: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1',\n}).openapi('AlibabaModelProvider');\n\n/** The one type a caller names, because only it supplies its own endpoint. */\nconst CustomModelProviderSchema = ModelProviderManifestBaseSchema.extend({\n type: z.literal('custom'),\n name: NameSchema,\n base_url: z.url().describe(\"Base URL of the provider's API.\"),\n auth: ModelProviderAuthSchema.optional(),\n})\n .strict()\n .openapi('CustomModelProvider');\n\nexport function refineModelProviderManifest(\n manifest: { models: { model_id: string; name: string }[] },\n ctx: z.RefinementCtx,\n): void {\n refineUniqueModels(manifest.models, ctx);\n}\n\nexport type ModelProperties = z.infer<typeof ModelPropertiesSchema>;\n\n/**\n * Configured provider jsonb (`model_provider.manifest`). Only `custom` carries a name, so the\n * row's key column comes from `modelProviderName` rather than from a field every type repeats.\n */\nconst ModelProviderBodySchema = z\n .discriminatedUnion('type', [\n OpenAiModelProviderSchema,\n AnthropicModelProviderSchema,\n GoogleGeminiModelProviderSchema,\n FireworksModelProviderSchema,\n ZaiModelProviderSchema,\n MoonshotModelProviderSchema,\n TogetherAIModelProviderSchema,\n AlibabaModelProviderSchema,\n CustomModelProviderSchema,\n ])\n .superRefine(refineModelProviderManifest);\n\nexport const ModelProviderManifestSchema = ModelProviderBodySchema.openapi('ModelProviderManifest');\n\n/** The row's key: only `custom` carries a name of its own. */\nexport function modelProviderName(provider: ModelProviderManifest): ResourceName {\n return provider.type === 'custom' ? provider.name : provider.type;\n}\n\n/** Settings wire item: identity column plus nested manifest. */\nexport const ConfiguredModelProviderSchema = z\n .object({\n name: NameSchema,\n manifest: ModelProviderManifestSchema,\n })\n .strict()\n .openapi('ConfiguredModelProvider');\n\nexport const CreateModelProviderRequestSchema = z\n .object({\n manifest: ModelProviderManifestSchema,\n })\n .strict()\n .openapi('CreateModelProviderRequest');\n\nexport const UpdateModelProviderRequestSchema = z\n .object({\n manifest: ModelProviderManifestSchema,\n })\n .strict()\n .openapi('UpdateModelProviderRequest');\n\nexport const GetModelProviderResponseSchema = z\n .object({\n data: ConfiguredModelProviderSchema,\n })\n .openapi('GetModelProviderResponse');\n\nexport const ListModelProvidersResponseSchema = z\n .object({\n data: z.array(ConfiguredModelProviderSchema),\n })\n .openapi('ListModelProvidersResponse');\n\n/** Provider identity on the models list read view. */\nexport const AvailableModelProviderSchema = z\n .object({\n name: z.string().min(1).describe('Configured provider resource name; matches the FQN prefix of `name`.'),\n })\n .strict()\n .describe('Owning configured provider.')\n .openapi('AvailableModelProvider');\n\n/** Read view over configured providers: FQN plus explicit provider identity for clients. */\nexport const AvailableModelSchema = z\n .object({\n name: z\n .string()\n .describe('Fully qualified name `provider_name/model_name`, e.g. \"openai/gpt-5-6-sol\". Unique within a tenant.'),\n model_id: z.string().describe('Upstream, provider-specific identifier sent to the provider API.'),\n provider: AvailableModelProviderSchema,\n properties: ModelPropertiesSchema,\n })\n .strict()\n .openapi('AvailableModel');\n\nexport const ListAvailableModelsResponseSchema = z\n .object({\n data: z.array(AvailableModelSchema),\n })\n .openapi('ListAvailableModelsResponse');\n\nexport type ModelProviderManifest = z.infer<typeof ModelProviderManifestSchema>;\nexport type ConfiguredModelProvider = z.infer<typeof ConfiguredModelProviderSchema>;\nexport type CreateModelProviderRequest = z.infer<typeof CreateModelProviderRequestSchema>;\nexport type UpdateModelProviderRequest = z.infer<typeof UpdateModelProviderRequestSchema>;\nexport type AvailableModelProvider = z.infer<typeof AvailableModelProviderSchema>;\nexport type AvailableModel = z.infer<typeof AvailableModelSchema>;\n","/**\n * Shipped sandbox-catalog.yaml schemas (discovery presets). Separate from\n * configured provider manifests in sandboxProvider.ts.\n */\nimport { z } from '@hono/zod-openapi';\nimport { DaytonaSandboxProviderSchema } from './sandboxProvider';\n\n/**\n * Catalog wire type. Single variant today (avoids one-member `oneOf` in OpenAPI).\n * Widen to a discriminated union when a second provider ships.\n */\nexport const CatalogSandboxProviderSchema = DaytonaSandboxProviderSchema.omit({ auth: true })\n .strict()\n .openapi('CatalogSandboxProvider');\n\nexport const SandboxCatalogFileSchema = z\n .object({\n providers: z.array(CatalogSandboxProviderSchema),\n })\n .strict();\n\nexport const GetSandboxProviderCatalogResponseSchema = z\n .object({\n data: z.array(CatalogSandboxProviderSchema),\n })\n .openapi('GetSandboxProviderCatalogResponse');\n\nexport type CatalogSandboxProvider = z.infer<typeof CatalogSandboxProviderSchema>;\nexport type SandboxCatalogFile = z.infer<typeof SandboxCatalogFileSchema>;\n","/**\n * Shipped skill-catalog.yaml schemas (discovery presets). Separate from\n * configured skill manifests in skill.ts.\n */\nimport { z } from '@hono/zod-openapi';\nimport { NameSchema, uniqueNames } from './common';\nimport {\n SkillDescriptionSchema,\n SkillGitPathSchema,\n SkillGitRefSchema,\n SkillGitUrlSchema,\n SkillTypeSchema,\n} from './skill';\n\n/** Catalog entry — discovery preset the settings UI copies into a PUT body. */\nexport const CatalogSkillSchema = z\n .object({\n type: SkillTypeSchema,\n name: NameSchema,\n url: SkillGitUrlSchema,\n path: SkillGitPathSchema.optional(),\n ref: SkillGitRefSchema,\n description: SkillDescriptionSchema,\n })\n .strict()\n .openapi('CatalogSkill');\n\nexport const SkillCatalogFileSchema = z\n .object({\n skills: z.array(CatalogSkillSchema),\n })\n .strict()\n .superRefine((file, ctx) => {\n uniqueNames(file.skills, ctx);\n });\n\nexport const GetSkillCatalogResponseSchema = z\n .object({\n data: z.array(CatalogSkillSchema),\n })\n .openapi('GetSkillCatalogResponse');\n\nexport type CatalogSkill = z.infer<typeof CatalogSkillSchema>;\nexport type SkillCatalogFile = z.infer<typeof SkillCatalogFileSchema>;\n","/**\n * Configured skill domain + wire schemas: the `skill.manifest` JSONB document\n * and admin/chat list projections. Catalog file schemas live in skillCatalog.ts.\n *\n * Git field rules mirror harness git skill mounts (GitHub/GitLab HTTPS url,\n * path/ref constraints) so settings documents stay mount-compatible. Identity\n * uses NameSchema like model providers / MCP servers.\n */\nimport { z } from '@hono/zod-openapi';\nimport { NameSchema } from './common';\n\n/** Kind of skill. Extend when non-git kinds ship. */\nexport const SkillTypeSchema = z.enum(['git']).openapi('SkillType');\n\n// GitHub is exactly owner/repo; GitLab allows subgroups (group[/subgroup...]/project, ≥2 segments).\nconst GIT_URL_REGEX =\n /^https:\\/\\/(github\\.com\\/[A-Za-z0-9._-]+\\/[A-Za-z0-9._-]+|gitlab\\.com\\/[A-Za-z0-9._-]+(?:\\/[A-Za-z0-9._-]+)+)(\\/|\\.git)?$/;\nconst GIT_REF_REGEX = /^[A-Za-z0-9._\\-/]+$/;\nconst SKILL_PATH_REGEX = /^[A-Za-z0-9._\\-/]+$/;\nconst hasParentTraversal = (value: string): boolean => value.split('/').includes('..');\n\n/** Shared with catalog presets — GitHub/GitLab HTTPS only. */\nexport const SkillGitUrlSchema = z\n .string()\n .trim()\n .min(1)\n .regex(GIT_URL_REGEX, 'Must be a GitHub or GitLab HTTPS URL')\n .refine(v => !hasParentTraversal(v), 'URL must not contain \"..\" segments')\n .describe('Full HTTPS URL of a GitHub or GitLab repository.');\n\n/** Shared with catalog presets. Omit to use the repository root. */\nexport const SkillGitPathSchema = z\n .string()\n .trim()\n .min(1)\n .regex(SKILL_PATH_REGEX, 'Path may only contain letters, numbers, \".\", \"_\", \"-\", and \"/\"')\n .refine(v => !hasParentTraversal(v), 'Path must not contain \"..\" segments')\n .refine(v => !v.split('/').includes('.'), 'Path must not contain \".\" segments')\n .refine(v => v.replace(/^\\/+|\\/+$/g, '').length > 0, 'Path must reference a subdirectory, not only slashes')\n .describe('Path to the skill directory within the repository. Omit to use the repository root.');\n\n/**\n * Shared with catalog presets. Required on configured skills (no silent HEAD default).\n */\nexport const SkillGitRefSchema = z\n .string()\n .trim()\n .min(1)\n .regex(GIT_REF_REGEX, 'Ref may only contain letters, numbers, \".\", \"_\", \"-\", and \"/\"')\n .refine(v => !hasParentTraversal(v), 'Ref must not contain \"..\" segments')\n .refine(v => v.replace(/^\\/+|\\/+$/g, '').length > 0, 'Ref must not consist only of slashes')\n .describe('Git ref — branch name, tag, or commit SHA.');\n\nexport const SkillDescriptionSchema = z\n .string()\n .trim()\n .min(1)\n .describe('Concise guidance for when the agent should use the skill.');\n\n/** Configured skill document persisted as `skill.manifest`. */\nexport const SkillManifestObjectSchema = z\n .object({\n type: SkillTypeSchema,\n name: NameSchema,\n url: SkillGitUrlSchema,\n path: SkillGitPathSchema.optional(),\n ref: SkillGitRefSchema,\n description: SkillDescriptionSchema,\n })\n .strict();\n\nexport const SkillManifestSchema = SkillManifestObjectSchema.openapi('SkillManifest');\n\n/** Admin/settings wire view: identity column plus nested manifest. */\nexport const ConfiguredSkillSchema = z\n .object({\n name: NameSchema,\n manifest: SkillManifestSchema,\n })\n .strict()\n .openapi('ConfiguredSkill');\n\nexport const CreateSkillRequestSchema = z\n .object({\n manifest: SkillManifestSchema,\n })\n .strict()\n .openapi('CreateSkillRequest');\n\nexport const UpdateSkillRequestSchema = z\n .object({\n manifest: SkillManifestSchema,\n })\n .strict()\n .openapi('UpdateSkillRequest');\n\nexport const GetSkillResponseSchema = z.object({ data: ConfiguredSkillSchema }).openapi('GetSkillResponse');\nexport const ListSkillsResponseSchema = z\n .object({ data: z.array(ConfiguredSkillSchema) })\n .openapi('ListSkillsResponse');\n\n/** Chat/composer read view — discovery fields only. */\nexport const AvailableSkillSchema = z\n .object({\n name: NameSchema,\n description: SkillDescriptionSchema,\n })\n .strict()\n .openapi('AvailableSkill');\n\nexport const ListAvailableSkillsResponseSchema = z\n .object({ data: z.array(AvailableSkillSchema) })\n .openapi('ListAvailableSkillsResponse');\n\nexport type SkillType = z.infer<typeof SkillTypeSchema>;\nexport type SkillManifest = z.infer<typeof SkillManifestSchema>;\nexport type ConfiguredSkill = z.infer<typeof ConfiguredSkillSchema>;\nexport type CreateSkillRequest = z.infer<typeof CreateSkillRequestSchema>;\nexport type UpdateSkillRequest = z.infer<typeof UpdateSkillRequestSchema>;\nexport type AvailableSkill = z.infer<typeof AvailableSkillSchema>;\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { extractErrorLogFields, McpConnectionError } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport { completeMcpAuthorization } from '../mcp/auth/mcpDcr';\nimport type { IOAuthClientStore, IOAuthTokenStore, OAuthPendingAuthorization } from '../mcp/auth/types';\nimport { mcpOAuthCallbackRoute } from '../routes/mcpOAuthRoutes';\n\nexport interface McpOAuthRouterDeps<TTransaction> {\n tokenStore: IOAuthTokenStore<TTransaction>;\n mcpServerStore: IOAuthClientStore<TTransaction>;\n logger: Logger;\n}\n\ntype McpOAuthCallbackContext = Parameters<RouteHandler<typeof mcpOAuthCallbackRoute>>[0];\n\n/**\n * Landing path with the outcome appended to whatever query params it already carries.\n * `returnTo` is resolved against the callback request URL only so `URL` can parse the\n * relative path; the redirect stays relative (`pathname + search`), so the browser\n * keeps whatever origin it is already on.\n */\nfunction callbackLandingPath(params: {\n c: McpOAuthCallbackContext;\n returnTo: string;\n isSuccess: boolean;\n reason?: string;\n}): string {\n const url = new URL(params.returnTo, params.c.req.url);\n url.searchParams.set('isSuccess', String(params.isSuccess));\n if (params.reason) {\n url.searchParams.set('reason', params.reason);\n }\n return `${url.pathname}${url.search}`;\n}\n\n/**\n * JSON is the answer whenever there is no landing path to return to: authorize was called without\n * `return_to`, or the pending row that carried it is gone (TTL expired, already redeemed, unknown\n * `state`) — the OAuth callback URL is never a page we send the user to on purpose.\n */\nfunction callbackSuccess(params: { c: McpOAuthCallbackContext; pending: OAuthPendingAuthorization }) {\n const returnTo = params.pending.returnTo;\n if (returnTo) {\n return params.c.redirect(callbackLandingPath({ c: params.c, returnTo, isSuccess: true }), 302);\n }\n return params.c.json({ success: true as const }, 200);\n}\n\nfunction callbackFailure(params: {\n c: McpOAuthCallbackContext;\n pending: OAuthPendingAuthorization | undefined;\n message: string;\n jsonStatus?: 400 | 500;\n}) {\n const returnTo = params.pending?.returnTo;\n if (returnTo) {\n return params.c.redirect(\n callbackLandingPath({ c: params.c, returnTo, isSuccess: false, reason: params.message }),\n 302,\n );\n }\n return params.c.json({ error: { message: params.message } }, params.jsonStatus ?? 400);\n}\n\n/** Shared OAuth callback (mounted at /api/v1/mcp-servers/oauth). */\nexport function createMcpOAuthRouter<TTransaction>(deps: McpOAuthRouterDeps<TTransaction>) {\n const callbackHandler: RouteHandler<typeof mcpOAuthCallbackRoute> = async c => {\n const { state, code, error, error_description: errorDescription } = c.req.valid('query');\n\n // Claimed up front: this row carries the FE landing path every branch below returns to, and\n // claiming it atomically means a duplicate callback loses the race.\n const pending = await deps.tokenStore.consumePendingAuthorization({ state });\n if (!pending) {\n deps.logger.warn('MCP OAuth callback has no pending authorization', { state, error, errorDescription });\n return callbackFailure({ c, pending, message: 'Unknown or expired OAuth state' });\n }\n\n if (error) {\n deps.logger.warn('MCP OAuth callback returned an error', { state, error, errorDescription });\n return callbackFailure({ c, pending, message: error });\n }\n\n if (!code) {\n return callbackFailure({ c, pending, message: 'OAuth callback is missing both `code` and `error`' });\n }\n\n try {\n await completeMcpAuthorization({\n tokenStore: deps.tokenStore,\n mcpServerStore: deps.mcpServerStore,\n pending,\n code,\n });\n } catch (err) {\n // Only a known MCP failure is safe to show the user; anything else gets a generic reason.\n if (err instanceof McpConnectionError) {\n deps.logger.warn('MCP OAuth callback token exchange failed', extractErrorLogFields(err));\n return callbackFailure({ c, pending, message: err.message });\n }\n deps.logger.error('MCP OAuth callback unexpected failure', extractErrorLogFields(err));\n return callbackFailure({ c, pending, message: 'Internal server error', jsonStatus: 500 });\n }\n\n return callbackSuccess({ c, pending });\n };\n\n const router = new OpenAPIHono();\n router.openapi(mcpOAuthCallbackRoute, callbackHandler);\n return router;\n}\n","import { createRoute } from '@hono/zod-openapi';\nimport { OAuthCallbackQuerySchema, OAuthCallbackSuccessSchema } from '../schemas/auth';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { OpenApiTag } from './openapiTags';\n\nexport const mcpOAuthCallbackRoute = createRoute({\n method: 'get',\n path: '/callback',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'OAuth callback for MCP authorization',\n description:\n 'Browser redirect target for MCP server OAuth. The authorization server redirects here with `code`/`state` (or `error`). ' +\n 'Exchanges the code for tokens, then either returns JSON or redirects to the `return_to` path supplied at authorize time. ' +\n 'Not called by the SDK — browsers hit this URL directly.',\n // Browser-redirect target hit directly by the authorization server, never called by SDK.\n 'x-fern-ignore': true,\n 'x-excluded': true,\n request: {\n query: OAuthCallbackQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: OAuthCallbackSuccessSchema } },\n description: 'Token exchanged successfully and no `return_to` was given at authorize time.',\n },\n 302: {\n description:\n 'Redirect to the `return_to` path given at authorize time, with `isSuccess` (and `reason` when it failed) appended to its existing query params.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'IdP `error`, unknown/expired `state`, token exchange failure, or `code`/`error` both missing.',\n },\n 500: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Unexpected failure during token exchange.',\n },\n },\n});\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { extractErrorLogFields, isAuthRequired, McpConnectionError, RemoteMCP } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport type { ResolveUserContext } from '../auth/identity';\nimport { safeReturnTo } from '../auth/safeReturnTo';\nimport configuration from '../config';\nimport { McpServerNameConflictError, type IMcpServerStore, type McpServerRecord } from '../db/mcpServerStore';\nimport type { WithTransaction } from '../db/transaction';\nimport { createMcpOAuthClient, isMcpAuthRequired, resolveMcpAuth } from '../mcp/auth/mcpDcr';\nimport { mcpOAuthCallbackUrl } from '../mcp/auth/mcpOAuthHelpers';\nimport type { IOAuthTokenStore, OAuthClientRecord, OAuthToken } from '../mcp/auth/types';\nimport {\n authorizeMcpServerRoute,\n createMcpServerRoute,\n deleteAuthorizationMcpServerRoute,\n getMcpServerRoute,\n listAvailableMcpServersRoute,\n listMcpServersRoute,\n listMcpServerToolsRoute,\n putMcpServerRoute,\n} from '../routes/mcpServerRoutes';\nimport { getMcpConnection } from '../runtime/sessionResources';\nimport type {\n AvailableMcpServer,\n ConfiguredMcpServer,\n CreateMcpServerRequest,\n McpAuthStatus,\n McpServerManifest,\n UpdateMcpServerRequest,\n} from '../schemas/mcpServer';\nimport { resolveMcpAuthStatus } from '../schemas/mcpServer';\nimport { MissingStoredSecretError, resolveStoredSecretValue, toRedactedSecretValue } from '../utils/secretRedaction';\nimport { TENANT_ID } from './sessions';\n\nexport interface McpServersRouterDeps<TTransaction> {\n mcpServerStore: IMcpServerStore<TTransaction>;\n tokenStore: IOAuthTokenStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n logger: Logger;\n resolveUserContext: ResolveUserContext;\n}\n\n/** Omits keys whose value is `undefined` so wire objects satisfy JSONValue index signatures. */\nfunction omitUndefinedEntries(obj: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value !== undefined) {\n out[key] = value;\n }\n }\n return out;\n}\n\n/** Settings wire view: redact header secrets; leave DCR / no-auth manifests unchanged. */\nfunction redactMcpServerManifest(manifest: McpServerManifest): McpServerManifest {\n if (manifest.auth?.type !== 'header') {\n return manifest;\n }\n const headers: Record<string, string> = {};\n for (const [name, value] of Object.entries(manifest.auth.headers)) {\n headers[name] = toRedactedSecretValue(value);\n }\n return {\n ...manifest,\n auth: { type: 'header', headers },\n };\n}\n\n/**\n * Strict PUT merge for `auth.type === 'header'`: each header value is always required;\n * redacted values keep the stored secret for the same header name.\n * @throws {MissingStoredSecretError} when keep is requested without a stored header value\n */\nfunction resolveMcpServerManifestForWrite({\n incoming,\n existing,\n}: {\n incoming: McpServerManifest;\n existing: McpServerManifest | undefined;\n}): McpServerManifest {\n if (incoming.auth?.type !== 'header') {\n return incoming;\n }\n const existingHeaders = existing?.auth?.type === 'header' ? existing.auth.headers : undefined;\n const headers: Record<string, string> = {};\n for (const [name, value] of Object.entries(incoming.auth.headers)) {\n headers[name] = resolveStoredSecretValue({\n incoming: value,\n existing: existingHeaders?.[name],\n });\n }\n return {\n ...incoming,\n auth: { type: 'header', headers },\n };\n}\n\n/**\n * `token` is the calling user's DCR access token for this server (keyed by `record.id` +\n * `userRef`), or undefined for header/no-auth servers and DCR servers that have never\n * authorized for this user. Only DCR reads it.\n */\nfunction toConfiguredMcpServer({\n record,\n token,\n}: {\n record: McpServerRecord;\n token: OAuthToken | undefined;\n}): ConfiguredMcpServer {\n return {\n name: record.name,\n manifest: redactMcpServerManifest(record.manifest),\n auth_status: resolveMcpAuthStatus({\n manifest: record.manifest,\n ...(token !== undefined ? { token } : {}),\n }),\n };\n}\n\nfunction toAvailableMcpServer({\n record,\n token,\n}: {\n record: McpServerRecord;\n token: OAuthToken | undefined;\n}): AvailableMcpServer {\n const authType = record.manifest.auth?.type;\n return {\n name: record.name,\n url: record.manifest.url,\n ...(authType !== undefined ? { auth: { type: authType } } : {}),\n auth_status: resolveMcpAuthStatus({\n manifest: record.manifest,\n ...(token !== undefined ? { token } : {}),\n }),\n };\n}\n\n/** Admin/settings MCP CRUD (mounted at /api/v1/settings/mcp-servers). */\nexport function createSettingsMcpServersRouter<TTransaction>(deps: McpServersRouterDeps<TTransaction>) {\n const listHandler: RouteHandler<typeof listMcpServersRoute> = async c => {\n const userRef = deps.resolveUserContext(c).userRef;\n const records = await deps.mcpServerStore.listServers({ tenant_id: TENANT_ID, names: undefined });\n // Only DCR servers have tokens; batch the lookup for this user.\n const dcrIds = records.filter(record => record.manifest.auth?.type === 'dcr').map(record => record.id);\n const tokens = await deps.tokenStore.getTokens({ ids: dcrIds, userRef });\n return c.json(\n { data: records.map(record => toConfiguredMcpServer({ record, token: tokens.get(record.id) })) },\n 200,\n );\n };\n\n const getHandler: RouteHandler<typeof getMcpServerRoute> = async c => {\n const { name } = c.req.valid('param');\n const userRef = deps.resolveUserContext(c).userRef;\n const record = await deps.mcpServerStore.getServer({ tenant_id: TENANT_ID, name });\n if (!record) {\n return c.json({ error: { message: `MCP server not found: ${name}` } }, 404);\n }\n let token: OAuthToken | undefined;\n if (record.manifest.auth?.type === 'dcr') {\n token = await deps.tokenStore.getToken({ id: record.id, userRef });\n }\n return c.json({ data: toConfiguredMcpServer({ record, token }) }, 200);\n };\n\n const createHandler: RouteHandler<typeof createMcpServerRoute> = async c => {\n const body: CreateMcpServerRequest = c.req.valid('json');\n const incomingManifest = body.manifest;\n\n // DCR finishes before the txn (remote I/O stays out of withTransaction on create).\n let dcrClientToSave: OAuthClientRecord | undefined;\n if (incomingManifest.auth?.type === 'dcr') {\n try {\n dcrClientToSave = await createMcpOAuthClient({\n mcpServerUrl: incomingManifest.url,\n mcpServerName: incomingManifest.name,\n redirectUri: mcpOAuthCallbackUrl(),\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n });\n } catch (error) {\n deps.logger.error(\n `DCR client registration failed for \"${incomingManifest.name}\"; rejecting create`,\n extractErrorLogFields(error),\n );\n const message = error instanceof Error ? error.message : 'Failed to register OAuth client for this MCP server';\n return c.json({ error: { message } }, 422);\n }\n }\n\n let manifest: McpServerManifest;\n try {\n manifest = resolveMcpServerManifestForWrite({\n incoming: incomingManifest,\n existing: undefined,\n });\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'Header secret is required' } }, 400);\n }\n throw error;\n }\n\n try {\n const record = await deps.withTransaction(async transaction => {\n const saved = await deps.mcpServerStore.createServer(\n {\n tenant_id: TENANT_ID,\n name: manifest.name,\n manifest,\n },\n transaction,\n );\n if (dcrClientToSave !== undefined) {\n await deps.mcpServerStore.saveClient({ id: saved.id, record: dcrClientToSave }, transaction);\n }\n return saved;\n });\n\n return c.json({ data: toConfiguredMcpServer({ record, token: undefined }) }, 201);\n } catch (error) {\n if (error instanceof McpServerNameConflictError) {\n return c.json({ error: { message: error.message } }, 409);\n }\n throw error;\n }\n };\n\n const putHandler: RouteHandler<typeof putMcpServerRoute> = async c => {\n const userRef = deps.resolveUserContext(c).userRef;\n const body: UpdateMcpServerRequest = c.req.valid('json');\n const incomingManifest = body.manifest;\n\n try {\n // Lock → resolve secrets → DCR (if needed) → upsert + saveClient in one txn.\n // Exception: MCP put may run `createMcpOAuthClient` inside the write txn that persists\n // `oauth_server`/`oauth_client` so a failed registration rolls back the server write.\n // Bounded by `MCP_OAUTH_HTTP_TIMEOUT_MS` (15s);\n // must stay under `POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT_MS` (30s).\n const record = await deps.withTransaction(async transaction => {\n const existing = await deps.mcpServerStore.getServerForUpdate(\n { tenant_id: TENANT_ID, name: incomingManifest.name },\n transaction,\n );\n const manifest = resolveMcpServerManifestForWrite({\n incoming: incomingManifest,\n existing: existing?.manifest,\n });\n\n let dcrClientToSave: OAuthClientRecord | undefined;\n const urlChanged =\n existing !== undefined && existing.manifest.url !== manifest.url && manifest.auth?.type === 'dcr';\n if (manifest.auth?.type === 'dcr') {\n const existingClient = existing\n ? await deps.mcpServerStore.getClient({ id: existing.id }, transaction)\n : undefined;\n // Register when: brand-new server, client was cleared (e.g. invalid_client), or MCP URL changed\n // (resource/AS may differ; reuse would keep stale oauth_server/client for the old AS).\n const needsDcr = existingClient === undefined || urlChanged;\n if (needsDcr) {\n dcrClientToSave = await createMcpOAuthClient({\n mcpServerUrl: manifest.url,\n mcpServerName: manifest.name,\n redirectUri: mcpOAuthCallbackUrl(),\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n });\n }\n }\n\n const saved = await deps.mcpServerStore.upsertServer(\n {\n tenant_id: TENANT_ID,\n name: manifest.name,\n manifest,\n },\n transaction,\n );\n if (dcrClientToSave !== undefined) {\n // New DCR registration (create, missing client, or URL change): replace the shared client.\n await deps.mcpServerStore.saveClient({ id: saved.id, record: dcrClientToSave }, transaction);\n }\n if (urlChanged) {\n // URL is the OAuth resource/audience — drop every user's tokens and in-flight authorizes.\n await deps.tokenStore.deleteTokensForServer({ id: saved.id }, transaction);\n await deps.tokenStore.deletePendingAuthorizationsForServer({ id: saved.id }, transaction);\n }\n return saved;\n });\n\n // A re-upsert preserves `id`, so a DCR server may already carry a token from a prior authorize\n // (unless this PUT changed the URL and cleared all tokens above).\n const token =\n record.manifest.auth?.type === 'dcr' ? await deps.tokenStore.getToken({ id: record.id, userRef }) : undefined;\n return c.json({ data: toConfiguredMcpServer({ record, token }) }, 200);\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'Header secret is required' } }, 400);\n }\n if (error instanceof McpConnectionError) {\n deps.logger.error(\n `DCR client registration failed for \"${incomingManifest.name}\"; rejecting upsert`,\n extractErrorLogFields(error),\n );\n return c.json({ error: { message: error.message } }, 422);\n }\n throw error;\n }\n };\n\n const router = new OpenAPIHono();\n router.openapi(listMcpServersRoute, listHandler);\n router.openapi(createMcpServerRoute, createHandler);\n router.openapi(putMcpServerRoute, putHandler);\n router.openapi(getMcpServerRoute, getHandler);\n return router;\n}\n\n/** List, tools, and authorize (mounted at /api/v1/mcp-servers). */\nexport function createMcpServersRouter<TTransaction>(deps: McpServersRouterDeps<TTransaction>) {\n const authorizeHandler: RouteHandler<typeof authorizeMcpServerRoute> = async c => {\n const { name } = c.req.valid('param');\n const { return_to: returnTo } = c.req.valid('query');\n const userRef = deps.resolveUserContext(c).userRef;\n const record = await deps.mcpServerStore.getServer({ tenant_id: TENANT_ID, name });\n if (!record) {\n return c.json({ error: { message: `MCP server not found: ${name}` } }, 404);\n }\n\n if (record.manifest.auth?.type !== 'dcr') {\n return c.json(resolveMcpAuthStatus({ manifest: record.manifest }), 200);\n }\n\n if (returnTo && safeReturnTo(returnTo) !== returnTo) {\n return c.json({ error: { message: 'Invalid return_to: must be a same-origin relative path' } }, 400);\n }\n\n try {\n // Reuses a usable/refreshable token when present; only builds an auth URL when needed.\n // Client is usually already registered at create/put; concurrent Connect races are harmless\n // (last saveClient wins; rare orphan AS registration).\n const result = await resolveMcpAuth({\n tokenStore: deps.tokenStore,\n mcpServerStore: deps.mcpServerStore,\n serverId: record.id,\n userRef,\n mcpServerUrl: record.manifest.url,\n mcpServerName: record.name,\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n ...(returnTo !== undefined ? { returnTo } : {}),\n });\n const authStatus: McpAuthStatus = isMcpAuthRequired(result)\n ? { status: 'auth_required', authorization_url: result.authUrl.href }\n : { status: 'authenticated' };\n return c.json(authStatus, 200);\n } catch (error) {\n if (error instanceof McpConnectionError) {\n deps.logger.warn(`MCP authorize failed for \"${name}\"`, extractErrorLogFields(error));\n if (error.statusCode === 400) {\n return c.json({ error: { message: error.message } }, 400);\n }\n if (error.statusCode === 422) {\n return c.json({ error: { message: error.message } }, 422);\n }\n if (error.statusCode === 424) {\n return c.json({ error: { message: error.message } }, 424);\n }\n return c.json({ error: { message: error.message } }, 500);\n }\n deps.logger.error(`MCP authorize unexpected failure for \"${name}\"`, extractErrorLogFields(error));\n return c.json({ error: { message: 'Internal server error' } }, 500);\n }\n };\n\n const listToolsHandler: RouteHandler<typeof listMcpServerToolsRoute> = async c => {\n const { name } = c.req.valid('param');\n const userRef = deps.resolveUserContext(c).userRef;\n // Same url + header resolution as turn execution (DCR via resolveMcpAuth, header/no-auth static).\n const connection = await getMcpConnection({\n tenant_id: TENANT_ID,\n name,\n store: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n userRef,\n });\n if (connection === undefined) {\n return c.json({ error: { message: `MCP server not found: ${name}` } }, 404);\n }\n const remote = new RemoteMCP({\n id: name,\n name,\n url: connection.url,\n headers: connection.headers,\n requestTimeoutMs: configuration.MCP_REQUEST_TIMEOUT_MS,\n connectTimeoutMs: configuration.MCP_CONNECT_TIMEOUT_MS,\n logger: deps.logger,\n signal: c.req.raw.signal,\n });\n try {\n const response = await remote.listTools();\n if (isAuthRequired(response)) {\n return c.json({ error: { message: `MCP server \"${name}\" requires authentication` } }, 422);\n }\n const data = response.result.tools.map(tool => omitUndefinedEntries({ ...tool }));\n return c.json({ data }, 200);\n } catch (error) {\n if (error instanceof McpConnectionError) {\n deps.logger.warn(`MCP tools/list failed for \"${name}\"`, extractErrorLogFields(error));\n if (error.statusCode === 401) {\n return c.json({ error: { message: error.message } }, 422);\n }\n return c.json({ error: { message: error.message } }, 502);\n }\n throw error;\n }\n };\n\n const deleteAuthorizationHandler: RouteHandler<typeof deleteAuthorizationMcpServerRoute> = async c => {\n const { name } = c.req.valid('param');\n const userRef = deps.resolveUserContext(c).userRef;\n const record = await deps.mcpServerStore.getServer({ tenant_id: TENANT_ID, name });\n if (!record) {\n return c.json({ error: { message: `MCP server not found: ${name}` } }, 404);\n }\n // DCR: drop this user's token only — keep oauth_server / oauth_client so re-authorize can skip DCR.\n // Header / no-auth: no-op.\n if (record.manifest.auth?.type === 'dcr') {\n await deps.tokenStore.deleteToken({ id: record.id, userRef });\n }\n return c.json({ data: toConfiguredMcpServer({ record, token: undefined }) }, 200);\n };\n\n const router = new OpenAPIHono();\n router.openapi(listAvailableMcpServersRoute, async c => {\n const userRef = deps.resolveUserContext(c).userRef;\n const records = await deps.mcpServerStore.listServers({ tenant_id: TENANT_ID, names: undefined });\n const dcrIds = records.filter(record => record.manifest.auth?.type === 'dcr').map(record => record.id);\n const tokens = await deps.tokenStore.getTokens({ ids: dcrIds, userRef });\n return c.json(\n {\n data: records.map(record => toAvailableMcpServer({ record, token: tokens.get(record.id) })),\n },\n 200,\n );\n });\n router.openapi(listMcpServerToolsRoute, listToolsHandler);\n router.openapi(authorizeMcpServerRoute, authorizeHandler);\n router.openapi(deleteAuthorizationMcpServerRoute, deleteAuthorizationHandler);\n return router;\n}\n","/**\n * DB-backed MCP server route definitions.\n * Admin routes mount at /api/v1/settings/mcp-servers; the chat list,\n * tools, and authorize routes mount at /api/v1/mcp-servers.\n */\nimport { createRoute, z } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport {\n CreateMcpServerRequestSchema,\n GetMcpServerResponseSchema,\n ListAvailableMcpServersResponseSchema,\n ListMcpServersResponseSchema,\n McpAuthStatusSchema,\n UpdateMcpServerRequestSchema,\n} from '../schemas/mcpServer';\nimport { OpenApiTag } from './openapiTags';\n\n/** Chat/composer read view — mounted at /api/v1/mcp-servers (not under settings). */\nexport const listAvailableMcpServersRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'List MCP servers for chat',\n description: 'MCP servers as a slim name/url list for the composer. No auth or auth_status.',\n 'x-fern-sdk-group-name': ['mcpServers'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListAvailableMcpServersResponseSchema } },\n description: 'All MCP servers (chat projection).',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n\nexport const listMcpServersRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'List MCP servers',\n description:\n 'All MCP servers with nested auth_status (settings / admin projection). Header auth values are redacted.',\n 'x-fern-sdk-group-name': ['settings', 'mcpServers'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListMcpServersResponseSchema } },\n description: 'All MCP servers',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the caller is authenticated but not an admin.',\n },\n },\n});\n\nconst McpServerNameParamsSchema = z.object({\n name: z.string().min(1).describe('MCP server name.'),\n});\n\nexport const getMcpServerRoute = createRoute({\n method: 'get',\n path: '/{name}',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'Get a single MCP server by name',\n description:\n 'A single MCP server by name, with nested auth_status (settings / admin projection). Header auth values are redacted.',\n 'x-fern-sdk-group-name': ['settings', 'mcpServers'],\n 'x-fern-sdk-method-name': 'get',\n request: {\n params: McpServerNameParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetMcpServerResponseSchema } },\n description: 'The MCP server',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'MCP server not found.',\n },\n },\n});\n\nexport const createMcpServerRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'Create an MCP server',\n description:\n 'Creates an MCP server by `name`. Fails if `name` is already taken. Runs DCR registration when `auth.type` is `dcr`. ' +\n 'Header secrets: real value required; redacted with no stored value returns 400.',\n 'x-fern-sdk-group-name': ['settings', 'mcpServers'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateMcpServerRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetMcpServerResponseSchema } },\n description: 'The created MCP server with auth_status',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted header secret with no stored value to keep.',\n },\n 409: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'An MCP server with this name already exists.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The server cannot satisfy `auth.type: dcr` (e.g. it advertises no registration_endpoint).',\n },\n },\n});\n\nexport const putMcpServerRoute = createRoute({\n method: 'put',\n path: '/',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'Create or replace an MCP server',\n description:\n 'Create or replace by `name`. Does not start DCR or change oauth client columns. ' +\n 'Header secrets: real value sets/rotates; redacted keeps existing (400 if none).',\n 'x-fern-sdk-group-name': ['settings', 'mcpServers'],\n 'x-fern-sdk-method-name': 'create_or_update',\n request: {\n body: {\n content: { 'application/json': { schema: UpdateMcpServerRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetMcpServerResponseSchema } },\n description: 'The saved MCP server with auth_status',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted header secret with no stored value to keep.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The server cannot satisfy `auth.type: dcr` (e.g. it advertises no registration_endpoint).',\n },\n },\n});\n\nconst ListMcpServerToolsResponseSchema = z\n .object({\n // TODO: Type tools/list entries to the MCP tool shape (name, description, inputSchema, …) for OpenAPI quality.\n data: z\n .array(z.record(z.string(), z.unknown()))\n .describe('MCP `tools/list` entries, passed through verbatim from the MCP server.'),\n })\n .openapi('ListMCPServerToolsResponse');\n\nexport const listMcpServerToolsRoute = createRoute({\n method: 'get',\n path: '/{name}/tools',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'List tools of an MCP server',\n 'x-fern-sdk-group-name': ['mcpServers'],\n 'x-fern-sdk-method-name': 'list_tools',\n description: 'All tools exposed by the given MCP server (non-paginated), as returned by the MCP `tools/list` call.',\n request: {\n params: McpServerNameParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListMcpServerToolsResponseSchema } },\n description: 'All tools of the MCP server.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'MCP server not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The MCP server requires authentication (does not trigger browser OIDC login).',\n },\n 502: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The MCP server could not be reached or returned an error.',\n },\n },\n});\n\nconst McpAuthorizeQuerySchema = z.object({\n return_to: z\n .string()\n .optional()\n .describe(\n 'Optional path to return to after OAuth. Must be a same-origin relative path; the OAuth callback redirects here with `isSuccess`/`reason` appended.',\n ),\n});\n\nexport const authorizeMcpServerRoute = createRoute({\n method: 'get',\n path: '/{name}/authorize',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'Start (or short-circuit) the auth flow for an MCP server',\n 'x-fern-sdk-group-name': ['mcpServers'],\n 'x-fern-sdk-method-name': 'authorize',\n description:\n 'For servers without auth returns not_required, and for header credentials returns authenticated ' +\n '(no browser flow). For auth.type dcr, returns authenticated when a usable (or refreshable) token ' +\n 'exists; otherwise runs DCR if needed and returns auth_required with an authorization URL. ' +\n 'Optional return_to is where the OAuth callback then redirects the browser; without it the callback returns JSON.',\n request: {\n params: McpServerNameParamsSchema,\n query: McpAuthorizeQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: McpAuthStatusSchema } },\n description: 'Either already authenticated, or an authorization URL to redirect to.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid return_to.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'MCP server not found.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'DCR could not be completed for this server (e.g. it lacks a registration_endpoint).',\n },\n 424: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'The authorization server failed dynamic client registration or authorization startup.',\n },\n 500: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Server misconfiguration (e.g. PUBLIC_BASE_URL unset).',\n },\n },\n});\n\nexport const deleteAuthorizationMcpServerRoute = createRoute({\n method: 'delete',\n path: '/{name}/authorize',\n tags: [OpenApiTag.MCP_SERVERS],\n summary: 'Disconnect OAuth for an MCP server',\n 'x-fern-sdk-group-name': ['mcpServers'],\n 'x-fern-sdk-method-name': 'delete_authorization',\n description:\n 'For auth.type dcr, deletes the stored OAuth token and returns the server with auth_status ' +\n 'auth_required, keeping the dynamically registered OAuth client so the next authorize can reuse it. ' +\n 'No-op for header or no-auth servers (returns the server unchanged).',\n request: {\n params: McpServerNameParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetMcpServerResponseSchema } },\n description: 'The MCP server after disconnect (auth_required for dcr).',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'MCP server not found.',\n },\n },\n});\n","/**\n * Redact secret strings for settings API responses and detect/merge\n * redacted writebacks so clients can keep stored secrets without resending them.\n */\n\nexport const SECRET_REDACTION = '***REDACTED***';\nconst MIN_LENGTH_FOR_PREFIX_SUFFIX = 10;\n\n/** Response mask: prefix/suffix for longer secrets; full mask when too short to hide. */\nexport function toRedactedSecretValue(secret: string): string {\n if (secret.length < MIN_LENGTH_FOR_PREFIX_SUFFIX) {\n return SECRET_REDACTION;\n }\n return `${secret.slice(0, 3)}-${SECRET_REDACTION}-${secret.slice(-3)}`;\n}\n\n/**\n * True when the client sent a redacted stand-in from a prior GET.\n */\nexport function isRedactedSecretValue(value: string): boolean {\n return value.includes(SECRET_REDACTION);\n}\n\n/**\n * Thrown when a redacted keep is requested but no stored secret exists\n * (create with redacted stand-in, or keep for a missing field/header).\n * Callers map this to a domain-specific 400 message.\n */\nexport class MissingStoredSecretError extends Error {\n constructor() {\n super('Missing stored secret');\n this.name = 'MissingStoredSecretError';\n }\n}\n\n/**\n * Resolve the secret to persist for a strict PUT field (always a non-empty string).\n * Real secrets are stored as-is; redacted stand-ins keep `existing` when present.\n * @throws {MissingStoredSecretError} when keep is requested with no stored secret\n */\nexport function resolveStoredSecretValue({\n incoming,\n existing,\n}: {\n incoming: string;\n existing: string | undefined;\n}): string {\n if (!isRedactedSecretValue(incoming)) {\n return incoming;\n }\n if (existing) {\n return existing;\n }\n throw new MissingStoredSecretError();\n}\n","import { OpenAPIHono } from '@hono/zod-openapi';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { WithTransaction } from '../db/transaction';\nimport { listAvailableModelsRoute } from '../routes/modelRoutes';\nimport { TENANT_ID } from './sessions';\n\n/** Chat slim list (mounted at /api/v1/models) — mirrors GET /api/v1/skills. */\nexport function createModelsRouter<TTransaction>(deps: {\n modelProviderStore: IModelProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}) {\n const router = new OpenAPIHono();\n router.openapi(listAvailableModelsRoute, async c =>\n c.json({ data: await deps.modelProviderStore.listModels(TENANT_ID) }, 200),\n );\n return router;\n}\n","import { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { ListAvailableModelsResponseSchema } from '../schemas/modelProvider';\nimport { OpenApiTag } from './openapiTags';\n\n/** Chat/composer read view — mounted at /api/v1/models (not under settings). */\nexport const listAvailableModelsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.MODELS],\n summary: 'List models for chat',\n 'x-fern-sdk-group-name': ['models'],\n 'x-fern-sdk-method-name': 'list',\n description: 'Configured models as a slim FQN list for the composer.',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListAvailableModelsResponseSchema } },\n description: 'All configured models (chat projection).',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n","/**\n * Admin/settings API surface under /api/v1/settings.\n * Sub-routers (model-providers, mcp-servers, skills, sandbox-providers) mount here.\n * Auth is applied at the /api/v1/settings mount boundary in app.ts (admin when auth is enabled).\n */\nimport { OpenAPIHono } from '@hono/zod-openapi';\nimport type { Logger } from 'winston';\nimport type { ResolveUserContext } from '../auth/identity';\nimport type { IMcpServerStore } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport type { WithTransaction } from '../db/transaction';\nimport type { IOAuthTokenStore } from '../mcp/auth/types';\nimport { createSettingsMcpServersRouter } from './mcpServers';\nimport { createModelProvidersRouter } from './modelProviders';\nimport { createSandboxProvidersRouter } from './sandboxProviders';\nimport { createSkillsRouter } from './skills';\n\nexport interface SettingsRouterDeps<TTransaction> {\n modelProviderStore: IModelProviderStore<TTransaction>;\n mcpServerStore: IMcpServerStore<TTransaction>;\n tokenStore: IOAuthTokenStore<TTransaction>;\n skillStore: ISkillStore<TTransaction>;\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n logger: Logger;\n resolveUserContext: ResolveUserContext;\n}\n\nexport function createSettingsRouter<TTransaction>(deps: SettingsRouterDeps<TTransaction>) {\n const router = new OpenAPIHono();\n router.route(\n '/model-providers',\n createModelProvidersRouter({\n modelProviderStore: deps.modelProviderStore,\n withTransaction: deps.withTransaction,\n }),\n );\n router.route(\n '/mcp-servers',\n createSettingsMcpServersRouter({\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n resolveUserContext: deps.resolveUserContext,\n }),\n );\n router.route(\n '/skills',\n createSkillsRouter({\n skillStore: deps.skillStore,\n withTransaction: deps.withTransaction,\n }),\n );\n router.route(\n '/sandbox-providers',\n createSandboxProvidersRouter({\n sandboxProviderStore: deps.sandboxProviderStore,\n withTransaction: deps.withTransaction,\n logger: deps.logger,\n }),\n );\n return router;\n}\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport {\n ModelProviderNameConflictError,\n type IModelProviderStore,\n type ModelProviderRecord,\n} from '../db/modelProviderStore';\nimport type { WithTransaction } from '../db/transaction';\nimport {\n createModelProviderRoute,\n listModelProvidersRoute,\n putModelProviderRoute,\n} from '../routes/modelProviderRoutes';\nimport {\n modelProviderName,\n type ConfiguredModelProvider,\n type CreateModelProviderRequest,\n type ModelProviderManifest,\n type UpdateModelProviderRequest,\n} from '../schemas/modelProvider';\nimport { MissingStoredSecretError, resolveStoredSecretValue, toRedactedSecretValue } from '../utils/secretRedaction';\nimport { TENANT_ID } from './sessions';\n\nexport interface ModelProvidersRouterDeps<TTransaction> {\n modelProviderStore: IModelProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}\n\nfunction redactModelProvider(manifest: ModelProviderManifest): ModelProviderManifest {\n if (manifest.auth === undefined) {\n return manifest;\n }\n return {\n ...manifest,\n auth: { api_key: toRedactedSecretValue(manifest.auth.api_key) },\n };\n}\n\nfunction resolveModelProviderManifestForWrite({\n incoming,\n existing,\n}: {\n incoming: ModelProviderManifest;\n existing: ModelProviderManifest | undefined;\n}): ModelProviderManifest {\n if (incoming.auth === undefined) {\n return incoming;\n }\n return {\n ...incoming,\n auth: {\n api_key: resolveStoredSecretValue({\n incoming: incoming.auth.api_key,\n existing: existing?.auth?.api_key,\n }),\n },\n };\n}\n\nfunction toWireProvider(record: ModelProviderRecord): ConfiguredModelProvider {\n return {\n name: record.name,\n manifest: redactModelProvider(record.manifest),\n };\n}\n\nexport function createModelProvidersRouter<TTransaction>(deps: ModelProvidersRouterDeps<TTransaction>) {\n const listHandler: RouteHandler<typeof listModelProvidersRoute> = async c => {\n const records = await deps.modelProviderStore.listProviders(TENANT_ID);\n return c.json({ data: records.map(toWireProvider) }, 200);\n };\n\n const createHandler: RouteHandler<typeof createModelProviderRoute> = async c => {\n const body: CreateModelProviderRequest = c.req.valid('json');\n const provider = body.manifest;\n const name = modelProviderName(provider);\n try {\n // Create has no prior row; redacted keep resolves to MissingStoredSecretError → 400.\n const manifest = resolveModelProviderManifestForWrite({ incoming: provider, existing: undefined });\n const record = await deps.modelProviderStore.createProvider({ tenant_id: TENANT_ID, name, manifest });\n return c.json({ data: toWireProvider(record) }, 201);\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'API key is required' } }, 400);\n }\n if (error instanceof ModelProviderNameConflictError) {\n return c.json({ error: { message: error.message } }, 409);\n }\n throw error;\n }\n };\n\n const putHandler: RouteHandler<typeof putModelProviderRoute> = async c => {\n const body: UpdateModelProviderRequest = c.req.valid('json');\n const provider = body.manifest;\n const name = modelProviderName(provider);\n try {\n // Lock → resolve secret from that snapshot → upsert, all in one txn so concurrent keep\n // cannot re-write a secret over a rotate that committed in between.\n const record = await deps.withTransaction(async transaction => {\n const existing = await deps.modelProviderStore.getProviderForUpdate(\n { tenant_id: TENANT_ID, name },\n transaction,\n );\n const manifest = resolveModelProviderManifestForWrite({\n incoming: provider,\n existing: existing?.manifest,\n });\n return deps.modelProviderStore.upsertProvider({ tenant_id: TENANT_ID, name, manifest }, transaction);\n });\n return c.json({ data: toWireProvider(record) }, 200);\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'API key is required' } }, 400);\n }\n throw error;\n }\n };\n\n const router = new OpenAPIHono();\n router.openapi(listModelProvidersRoute, listHandler);\n router.openapi(createModelProviderRoute, createHandler);\n router.openapi(putModelProviderRoute, putHandler);\n return router;\n}\n","/**\n * Model-provider admin route definitions (mounted at /api/v1/settings/model-providers).\n * Discovery catalog lives at GET /api/v1/catalogs/model-providers.\n * Handlers are registered in apis/modelProviders.ts.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport {\n CreateModelProviderRequestSchema,\n GetModelProviderResponseSchema,\n ListModelProvidersResponseSchema,\n UpdateModelProviderRequestSchema,\n} from '../schemas/modelProvider';\nimport { OpenApiTag } from './openapiTags';\n\nexport const listModelProvidersRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.MODELS],\n summary: 'List configured model providers',\n description: 'All configured providers with nested manifests.',\n 'x-fern-sdk-group-name': ['settings', 'modelProviders'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListModelProvidersResponseSchema } },\n description: 'All configured model providers',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the caller is authenticated but not an admin.',\n },\n },\n});\n\nexport const createModelProviderRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [OpenApiTag.MODELS],\n summary: 'Create a model provider',\n description:\n 'Creates a provider (models included). Fails if `name` is already taken. Well-known types use `type` as `name` (one each); ' +\n '`custom` is named by the caller. `auth.api_key`: real value required; redacted with no stored secret returns 400.',\n 'x-fern-sdk-group-name': ['settings', 'modelProviders'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateModelProviderRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetModelProviderResponseSchema } },\n description: 'The created provider',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted API key with no stored secret to keep.',\n },\n 409: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'A model provider with this name already exists.',\n },\n },\n});\n\nexport const putModelProviderRoute = createRoute({\n method: 'put',\n path: '/',\n tags: [OpenApiTag.MODELS],\n summary: 'Create or replace a model provider',\n description:\n 'Create or replace a provider (models included). Well-known types use `type` as `name` (one each); ' +\n '`custom` is named by the caller. `auth.api_key`: real value sets/rotates; redacted keeps existing (400 if none).',\n 'x-fern-sdk-group-name': ['settings', 'modelProviders'],\n 'x-fern-sdk-method-name': 'create_or_update',\n request: {\n body: {\n content: { 'application/json': { schema: UpdateModelProviderRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetModelProviderResponseSchema } },\n description: 'The saved provider',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted API key with no stored secret to keep.',\n },\n },\n});\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { withTimeout } from '@truefoundry/trueforge-core/core';\nimport type { Logger } from 'winston';\nimport type { ISandboxProviderStore, SandboxProviderRecord } from '../db/sandboxProviderStore';\nimport type { WithTransaction } from '../db/transaction';\nimport { getSandboxProviderRoute, putSandboxProviderRoute } from '../routes/sandboxProviderRoutes';\nimport {\n checkSnapshotStatus,\n isDaytonaAuthError,\n toDaytonaSandboxProvider,\n toSandboxStatus,\n} from '../sandbox/providerUtils';\nimport type { SandboxProviderManifest, UpdateSandboxProviderRequest } from '../schemas/sandboxProvider';\nimport { MissingStoredSecretError, resolveStoredSecretValue, toRedactedSecretValue } from '../utils/secretRedaction';\nimport { TENANT_ID } from './sessions';\n\n/** Cap the Daytona register round-trip so a slow/unreachable provider can't hold the request (or DB txn) open. */\nconst BUILD_REQUEST_TIMEOUT_MS = 3_000;\n\nexport interface SandboxProvidersRouterDeps<TTransaction> {\n sandboxProviderStore: ISandboxProviderStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n logger: Logger;\n}\n\nfunction redactSandboxProvider(manifest: SandboxProviderManifest): SandboxProviderManifest {\n return {\n ...manifest,\n auth: { api_key: toRedactedSecretValue(manifest.auth.api_key) },\n };\n}\n\n/** Admin/settings sandbox provider surface (mounted at /api/v1/settings/sandbox-providers). */\nexport function createSandboxProvidersRouter<TTransaction>(deps: SandboxProvidersRouterDeps<TTransaction>) {\n const getHandler: RouteHandler<typeof getSandboxProviderRoute> = async c => {\n const record = await deps.sandboxProviderStore.getSandboxProvider(TENANT_ID);\n if (record === undefined) {\n return c.json({ error: { message: 'No sandbox provider configured' } }, 404);\n }\n // Refresh the persisted build status (and re-activate an idle snapshot) on every GET.\n const status = await checkSnapshotStatus({\n store: deps.sandboxProviderStore,\n tenant_id: TENANT_ID,\n logger: deps.logger,\n });\n return c.json(\n {\n data: {\n manifest: redactSandboxProvider(record.manifest),\n status: status?.status ?? record.status,\n status_reason: status?.status_reason ?? record.status_reason,\n },\n },\n 200,\n );\n };\n\n const putHandler: RouteHandler<typeof putSandboxProviderRoute> = async c => {\n const body: UpdateSandboxProviderRequest = c.req.valid('json');\n const incoming = body.manifest;\n const resolveManifest = (existing: SandboxProviderRecord | undefined): SandboxProviderManifest => ({\n ...incoming,\n auth: {\n api_key: resolveStoredSecretValue({\n incoming: incoming.auth.api_key,\n existing: existing?.manifest.auth.api_key,\n }),\n },\n });\n try {\n // NOTE: build (Daytona network I/O) runs inside the transaction for now; the design is being revisited.\n const { manifest, status } = await deps.withTransaction(async transaction => {\n const locked = await deps.sandboxProviderStore.getSandboxProviderForUpdate(TENANT_ID, transaction);\n const resolved = resolveManifest(locked);\n // Pass persisted build_metadata so a settings re-save does not start a new snapshot for a\n // bumped SANDBOX_IMAGE_URI (upgrades are unsupported — first configure has no metadata).\n const provider = toDaytonaSandboxProvider({\n manifest: resolved,\n tenant_id: TENANT_ID,\n logger: deps.logger,\n ...(locked ? { build_metadata: locked.build_metadata } : {}),\n });\n const built = toSandboxStatus(\n await withTimeout(provider.buildImage(), BUILD_REQUEST_TIMEOUT_MS, 'sandbox buildImage'),\n );\n await deps.sandboxProviderStore.upsertSandboxProvider(\n { tenant_id: TENANT_ID, manifest: resolved, ...built },\n transaction,\n );\n return { manifest: resolved, status: built };\n });\n return c.json(\n {\n data: {\n manifest: redactSandboxProvider(manifest),\n status: status.status,\n status_reason: status.status_reason,\n },\n },\n 200,\n );\n } catch (error) {\n if (error instanceof MissingStoredSecretError) {\n return c.json({ error: { message: 'API key is required' } }, 400);\n }\n if (isDaytonaAuthError(error)) {\n return c.json({ error: { message: 'Daytona rejected the API key — check the credentials' } }, 422);\n }\n throw error;\n }\n };\n\n const router = new OpenAPIHono();\n router.openapi(getSandboxProviderRoute, getHandler);\n router.openapi(putSandboxProviderRoute, putHandler);\n return router;\n}\n","/**\n * Sandbox-provider admin route definitions (mounted at /api/v1/settings/sandbox-providers).\n * Discovery catalog lives at GET /api/v1/catalogs/sandbox-providers.\n * Handlers are registered in apis/sandboxProviders.ts.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { GetSandboxProviderResponseSchema, UpdateSandboxProviderRequestSchema } from '../schemas/sandboxProvider';\nimport { OpenApiTag } from './openapiTags';\n\nexport const getSandboxProviderRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.SANDBOXES],\n summary: 'Get the configured sandbox provider',\n description: 'The single configured sandbox provider for this tenant. `auth.api_key` is redacted.',\n 'x-fern-sdk-group-name': ['settings', 'sandboxProviders'],\n 'x-fern-sdk-method-name': 'get',\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSandboxProviderResponseSchema } },\n description: 'The configured sandbox provider.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'No sandbox provider configured.',\n },\n },\n});\n\nexport const putSandboxProviderRoute = createRoute({\n method: 'put',\n path: '/',\n tags: [OpenApiTag.SANDBOXES],\n summary: 'Create or replace the sandbox provider',\n description:\n 'Upserts the single sandbox provider for this tenant: creates it or replaces its entire configuration. ' +\n '`auth.api_key`: real value sets/rotates; redacted keeps existing (400 if none).',\n 'x-fern-sdk-group-name': ['settings', 'sandboxProviders'],\n 'x-fern-sdk-method-name': 'create_or_update',\n request: {\n body: {\n content: { 'application/json': { schema: UpdateSandboxProviderRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSandboxProviderResponseSchema } },\n description: 'The saved sandbox provider.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body, or redacted API key with no stored secret to keep.',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Daytona rejected the provided API key.',\n },\n },\n});\n","import { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport { SkillNameConflictError, type ISkillStore, type SkillRecord } from '../db/skillStore';\nimport type { WithTransaction } from '../db/transaction';\nimport {\n createSkillRoute,\n listAvailableSkillsRoute,\n listConfiguredSkillsRoute,\n putSkillRoute,\n} from '../routes/skillRoutes';\nimport type { ConfiguredSkill, CreateSkillRequest, UpdateSkillRequest } from '../schemas/skill';\nimport { TENANT_ID } from './sessions';\n\nexport interface SkillsRouterDeps<TTransaction> {\n skillStore: ISkillStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}\n\n/** Wire view of a stored skill: identity `name` plus nested manifest. */\nfunction toConfiguredSkill(record: SkillRecord): ConfiguredSkill {\n return {\n name: record.name,\n manifest: record.manifest,\n };\n}\n\n/** Admin/settings skills CRUD (mounted at /api/v1/settings/skills). */\nexport function createSkillsRouter<TTransaction>(deps: SkillsRouterDeps<TTransaction>) {\n const listConfiguredHandler: RouteHandler<typeof listConfiguredSkillsRoute> = async c => {\n const records = await deps.skillStore.listSkills({ tenant_id: TENANT_ID, names: undefined });\n return c.json({ data: records.map(toConfiguredSkill) }, 200);\n };\n\n const createHandler: RouteHandler<typeof createSkillRoute> = async c => {\n const body: CreateSkillRequest = c.req.valid('json');\n const manifest = body.manifest;\n try {\n const record = await deps.skillStore.createSkill({\n tenant_id: TENANT_ID,\n name: manifest.name,\n manifest,\n });\n return c.json({ data: toConfiguredSkill(record) }, 201);\n } catch (error) {\n if (error instanceof SkillNameConflictError) {\n return c.json({ error: { message: error.message } }, 409);\n }\n throw error;\n }\n };\n\n const putHandler: RouteHandler<typeof putSkillRoute> = async c => {\n const body: UpdateSkillRequest = c.req.valid('json');\n const manifest = body.manifest;\n const record = await deps.skillStore.upsertSkill({\n tenant_id: TENANT_ID,\n name: manifest.name,\n manifest,\n });\n return c.json({ data: toConfiguredSkill(record) }, 200);\n };\n\n const router = new OpenAPIHono();\n router.openapi(listConfiguredSkillsRoute, listConfiguredHandler);\n router.openapi(createSkillRoute, createHandler);\n router.openapi(putSkillRoute, putHandler);\n return router;\n}\n\n/** Chat slim list (mounted at /api/v1/skills) — mirrors GET /api/v1/mcp-servers. */\nexport function createAvailableSkillsRouter<TTransaction>(deps: {\n skillStore: ISkillStore<TTransaction>;\n withTransaction: WithTransaction<TTransaction>;\n}) {\n const router = new OpenAPIHono();\n router.openapi(listAvailableSkillsRoute, async c => {\n const records = await deps.skillStore.listSkills({ tenant_id: TENANT_ID, names: undefined });\n return c.json(\n {\n data: records.map(record => ({\n name: record.name,\n description: record.manifest.description,\n })),\n },\n 200,\n );\n });\n return router;\n}\n","/**\n * DB-backed skill route definitions.\n * Admin routes mount at /api/v1/settings/skills; the chat list mounts at\n * /api/v1/skills.\n * Discovery catalog lives at GET /api/v1/catalogs/skills.\n */\nimport { createRoute } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport {\n CreateSkillRequestSchema,\n GetSkillResponseSchema,\n ListAvailableSkillsResponseSchema,\n ListSkillsResponseSchema,\n UpdateSkillRequestSchema,\n} from '../schemas/skill';\nimport { OpenApiTag } from './openapiTags';\n\n/** Chat/composer read view — mounted at /api/v1/skills (not under settings). */\nexport const listAvailableSkillsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.SKILLS],\n summary: 'List skills for chat',\n description: 'Configured skills as a slim name/description list for the composer.',\n 'x-fern-sdk-group-name': ['skills'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListAvailableSkillsResponseSchema } },\n description: 'All configured skills (chat projection).',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n },\n});\n\nexport const listConfiguredSkillsRoute = createRoute({\n method: 'get',\n path: '/',\n tags: [OpenApiTag.SKILLS],\n summary: 'List configured skills',\n description: 'All configured skills with nested manifests (settings / admin projection).',\n 'x-fern-sdk-group-name': ['settings', 'skills'],\n 'x-fern-sdk-method-name': 'list',\n responses: {\n 200: {\n content: { 'application/json': { schema: ListSkillsResponseSchema } },\n description: 'All configured skills.',\n },\n 401: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the request has no valid session cookie.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'OIDC is configured and the caller is authenticated but not an admin.',\n },\n },\n});\n\nexport const createSkillRoute = createRoute({\n method: 'post',\n path: '/',\n tags: [OpenApiTag.SKILLS],\n summary: 'Create a skill',\n description: 'Creates a skill keyed by `name`. Fails if `name` is already taken.',\n 'x-fern-sdk-group-name': ['settings', 'skills'],\n 'x-fern-sdk-method-name': 'create',\n request: {\n body: {\n content: { 'application/json': { schema: CreateSkillRequestSchema } },\n required: true,\n },\n },\n responses: {\n 201: {\n content: { 'application/json': { schema: GetSkillResponseSchema } },\n description: 'The created skill.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n 409: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'A skill with this name already exists.',\n },\n },\n});\n\nexport const putSkillRoute = createRoute({\n method: 'put',\n path: '/',\n tags: [OpenApiTag.SKILLS],\n summary: 'Create or replace a skill',\n description: 'Full upsert keyed by `name`: creates the skill or replaces its entire manifest.',\n 'x-fern-sdk-group-name': ['settings', 'skills'],\n 'x-fern-sdk-method-name': 'create_or_update',\n request: {\n body: {\n content: { 'application/json': { schema: UpdateSkillRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetSkillResponseSchema } },\n description: 'The saved skill.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n },\n});\n","/**\n * DB-backed turns API (mounted at /api/v1/sessions).\n */\nimport { OpenAPIHono, type RouteHandler } from '@hono/zod-openapi';\nimport type { ISessionStore, Sessions, Turn, TurnStreamingEvent } from '@truefoundry/trueforge-core/agent-session';\nimport {\n CancellationReason,\n EventType,\n SessionStoreConflictError,\n SessionStoreNotFoundError,\n TurnResourceResolver,\n type TurnInputItem,\n type TurnRecordWithoutSnapshot,\n} from '@truefoundry/trueforge-core/agent-session';\nimport {\n AgentHarnessError,\n existingSandboxIdForProvider,\n extractErrorLogFields,\n isAgentInputUserMessage,\n isFileContentPart,\n McpConnectionError,\n rawSandboxId,\n SandboxError,\n VercelAILLM,\n} from '@truefoundry/trueforge-core/core';\nimport type { Context } from 'hono';\nimport { HTTPException } from 'hono/http-exception';\nimport { streamSSE } from 'hono/streaming';\nimport type { Logger } from 'winston';\nimport type { ResolveUserContext, UserContext } from '../auth/identity';\nimport configuration from '../config';\nimport type { IAgentStore } from '../db/agentStore';\nimport type { IMcpServerStore } from '../db/mcpServerStore';\nimport type { IModelProviderStore } from '../db/modelProviderStore';\nimport type { ISandboxProviderStore } from '../db/sandboxProviderStore';\nimport type { ISkillStore } from '../db/skillStore';\nimport type { IOAuthTokenStore } from '../mcp/auth/types';\nimport {\n createAndExecuteTurnRoute,\n downloadSandboxFileRoute,\n getTurnRoute,\n listTurnEventsRoute,\n listTurnsRoute,\n subscribeTurnRoute,\n} from '../routes/turnRoutes';\nimport type { ActiveTurnRegistry } from '../runtime/activeTurns';\nimport { StreamGoneError, type EventSubscription, type EventSubscriptionRegistry } from '../runtime/event-subscription';\nimport { mintPeeredTurnId } from '../runtime/peeringIds';\nimport { validateSandboxFilePath } from '../runtime/sandboxFilePath';\nimport {\n buildTurnSandbox,\n getMcpConnection,\n getModelDetails,\n resolveGitSkills,\n resolveSandboxProvider,\n} from '../runtime/sessionResources';\nimport { checkSnapshotStatus } from '../sandbox/providerUtils';\nimport { TENANT_ID } from './sessions';\n\nexport function toWireTurn(record: TurnRecordWithoutSnapshot): Turn {\n return {\n id: record.turn_id,\n session_id: record.session_id,\n previous_turn_id: record.previous_turn_id,\n input: record.input,\n state: record.state,\n created_at: record.created_at.toISOString(),\n };\n}\n\n/**\n * Copies into a standalone ArrayBuffer for the response body: a pooled Buffer's\n * backing store is shared and typed as ArrayBufferLike, which is not a body.\n * Bounded by SANDBOX_FILE_MAX_BYTES_FOR_DOWNLOAD.\n */\nfunction toArrayBuffer(content: Buffer): ArrayBuffer {\n const buffer = new ArrayBuffer(content.byteLength);\n new Uint8Array(buffer).set(content);\n return buffer;\n}\n\n/**\n * Builds the Content-Disposition telling the browser to save the file under its sandbox name.\n *\n * A sandbox file can be named in any script, but an HTTP header can only carry bytes, so a name\n * like `中文.csv` cannot be written into the header as-is — doing so throws when the response is\n * constructed. RFC 6266's `filename*` exists for this: percent-encode the UTF-8 name so the value\n * stays plain ASCII, and the client decodes it back. Encoding also defuses quotes and newlines,\n * which could otherwise close the value or inject another header.\n */\nexport function toContentDisposition(path: string): string {\n // Trailing separators are dropped so a path ending in `/` still yields its last real segment.\n const fileName = path.split('/').filter(Boolean).pop() ?? 'download';\n // encodeURIComponent covers everything except these four, which RFC 5987 also disallows here.\n const encoded = encodeURIComponent(fileName).replace(\n /['()*]/g,\n char => `%${char.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n return `attachment; filename*=UTF-8''${encoded}`;\n}\n\nexport interface TurnsRouterDeps {\n sessions: Sessions;\n sessionStore: ISessionStore;\n activeTurns: ActiveTurnRegistry;\n modelProviderStore: IModelProviderStore;\n mcpServerStore: IMcpServerStore;\n tokenStore: IOAuthTokenStore;\n skillStore: ISkillStore;\n agentStore: IAgentStore;\n /** Resumable live turn-event transport: create-turn writes, subscribe polls. */\n eventSubscriptions: EventSubscriptionRegistry<TurnStreamingEvent>;\n sandboxProviderStore: ISandboxProviderStore;\n logger: Logger;\n resolveUserContext: ResolveUserContext;\n}\n\n/**\n * Builds the per-turn resolver. Agent / MCP / sandbox / LLM lookups are wired\n * the same way: async factories over the corresponding stores.\n */\nfunction createTurnResolver(deps: {\n mcpServerStore: IMcpServerStore;\n tokenStore: IOAuthTokenStore;\n skillStore: ISkillStore;\n sandboxProviderStore: ISandboxProviderStore;\n agentStore: IAgentStore;\n modelProviderStore: IModelProviderStore;\n logger: Logger;\n signal: AbortSignal;\n userRef: string;\n sessionId: string;\n}): TurnResourceResolver {\n const {\n mcpServerStore,\n tokenStore,\n skillStore,\n sandboxProviderStore,\n agentStore,\n modelProviderStore,\n logger,\n signal,\n userRef,\n sessionId,\n } = deps;\n return new TurnResourceResolver({\n llm: async name => {\n const { providerConfig, defaultModelParams } = await getModelDetails({\n tenant_id: TENANT_ID,\n name,\n store: modelProviderStore,\n });\n return {\n modelClient: new VercelAILLM({\n providerConfig,\n logger,\n signal,\n }),\n defaultModelParams,\n };\n },\n mcp: async name => {\n const connection = await getMcpConnection({\n tenant_id: TENANT_ID,\n name,\n store: mcpServerStore,\n tokenStore,\n clientName: configuration.MCP_DCR_OAUTH_CLIENT_NAME,\n userRef,\n });\n if (connection === undefined) {\n throw new HTTPException(422, {\n message: `Unknown MCP server \"${name}\" — not configured`,\n });\n }\n return connection;\n },\n mcpRequestTimeoutMs: configuration.MCP_REQUEST_TIMEOUT_MS,\n mcpConnectTimeoutMs: configuration.MCP_CONNECT_TIMEOUT_MS,\n sandboxProvider: async ({ spec, existingSandboxId, tracing }) => {\n const provider = await resolveSandboxProvider({\n tenant_id: TENANT_ID,\n store: sandboxProviderStore,\n logger,\n sessionId,\n });\n if (provider === undefined) {\n throw new HTTPException(422, {\n message: 'no sandbox provider configured — PUT /settings/sandbox-providers',\n });\n }\n const carriedSandboxId = existingSandboxIdForProvider({\n existingSandboxId,\n currentProviderType: provider.type,\n });\n // A fresh Daytona sandbox is cloned from the release snapshot, so the build must be ready first.\n // Restoring an existing sandbox goes through daytona.get and never touches the snapshot.\n // Local fallback has no image build.\n if (carriedSandboxId === undefined && provider.type !== 'local') {\n const status = await checkSnapshotStatus({ store: sandboxProviderStore, tenant_id: TENANT_ID, logger });\n if (status?.status !== 'ready') {\n throw new HTTPException(422, {\n message:\n status?.status === 'failed'\n ? `sandbox image build failed (${status.status_reason ?? 'unknown error'})`\n : 'sandbox image is activating — retry shortly',\n });\n }\n }\n const gitSkills = await resolveGitSkills({\n tenant_id: TENANT_ID,\n skills: spec.skills ?? [],\n store: skillStore,\n });\n return buildTurnSandbox({\n provider,\n logger,\n gitSkills,\n fileDownloadEnabled: spec.config.sandbox.file_downloads,\n existingSandboxId: carriedSandboxId,\n tracing,\n });\n },\n agent: async agentId => {\n const record = await agentStore.getAgent({ tenant_id: TENANT_ID, id: agentId });\n if (record === undefined) {\n throw new HTTPException(422, { message: `Agent not found: ${agentId}` });\n }\n return record.manifest;\n },\n logger,\n });\n}\n\nconst MAX_SESSION_TITLE_LENGTH = 50;\n\n/**\n * Derives a session title from the first user message of the first turn. Returns the\n * trimmed text (capped at {@link MAX_SESSION_TITLE_LENGTH}) or `undefined` when no usable\n * text is present (e.g. file-only or tool-approval input).\n */\nexport function deriveSessionTitle(input: TurnInputItem[] | undefined): string | undefined {\n const firstUserMessage = input?.find(isAgentInputUserMessage);\n if (!firstUserMessage) {\n return undefined;\n }\n\n const text =\n typeof firstUserMessage.content === 'string'\n ? firstUserMessage.content\n : firstUserMessage.content\n .filter(part => !isFileContentPart(part))\n .map(part => part.text)\n .join(' ');\n\n const trimmed = text.trim();\n if (!trimmed) {\n return undefined;\n }\n return trimmed.slice(0, MAX_SESSION_TITLE_LENGTH);\n}\n\n/**\n * SSE payload for one turn event. The `id` field carries the per-stream\n * sequence number; the event body itself is not numbered (yield order is\n * persist order, so the transport boundary stamps).\n */\nexport function turnEventSsePayload(event: TurnStreamingEvent, sequenceNumber: number): { id: string; data: string } {\n return {\n id: String(sequenceNumber),\n data: JSON.stringify(event),\n };\n}\n\n/**\n * turn.created arms the active-run TTL, turn.done shortens it to the\n * post-completion drain window; mid-run events leave the TTL untouched.\n */\nexport function streamTTLSecondsFor(event: TurnStreamingEvent): number | undefined {\n if (event.type === EventType.TURN_CREATED) {\n return configuration.TURN_STREAM_TTL_SECONDS;\n }\n if (event.type === EventType.TURN_DONE) {\n return configuration.TURN_STREAM_POST_COMPLETION_TTL_SECONDS;\n }\n return undefined;\n}\n\n/** Redis/in-memory key for one turn's resumable event stream. */\nexport function turnStreamId(tenantId: string, sessionId: string, turnId: string): string {\n return `agent:turn:${tenantId}:${sessionId}:${turnId}:stream`;\n}\n\n/**\n * Dual-write turn events to the resumable subscription registry, then optionally\n * forward each sequenced event (SSE path). Shared by streaming and non-streaming\n * create-turn; the HTTP response lifecycle does not own execution.\n */\nexport async function drainTurnEvents(input: {\n trackedStream: AsyncIterable<TurnStreamingEvent>;\n turnEventStream: EventSubscription<TurnStreamingEvent>;\n sessionId: string;\n turnId: string;\n maxExecutionTimer: NodeJS.Timeout;\n logger: Logger;\n onEvent?: (event: TurnStreamingEvent, sequenceNumber: number) => Promise<void>;\n}): Promise<void> {\n const { trackedStream, turnEventStream, sessionId, turnId, maxExecutionTimer, logger, onEvent } = input;\n try {\n for await (const event of trackedStream) {\n // Dual-write before any client sink so subscribers can resume after disconnect.\n const sequenceNumber = await turnEventStream.put(event, {\n streamTTLSeconds: streamTTLSecondsFor(event),\n });\n await onEvent?.(event, sequenceNumber);\n }\n } catch (error) {\n if (error instanceof SessionStoreNotFoundError) {\n logger.warn('Turn stream ended after session/turn was removed', {\n sessionId,\n turnId,\n ...extractErrorLogFields(error),\n });\n } else {\n logger.error('Unexpected error in turn event drain', {\n sessionId,\n turnId,\n ...extractErrorLogFields(error),\n });\n }\n } finally {\n clearTimeout(maxExecutionTimer);\n }\n}\n\n/**\n * Resume cursor: `Last-Event-ID` header wins over the body value because the\n * header is updated by the SDK on every reconnect to reflect the last delivered\n * event, whereas the body is the original caller-supplied cursor and never\n * changes between reconnect attempts.\n */\nexport function resolveAfterSequenceNumber(c: Context, bodyAfterSequenceNumber?: number): number | undefined {\n const lastEventId = c.req.header('last-event-id');\n if (lastEventId) {\n const sequenceNumber = Number(lastEventId);\n if (!Number.isInteger(sequenceNumber) || sequenceNumber < 0) {\n throw new HTTPException(400, { message: 'Invalid Last-Event-Id header' });\n }\n return sequenceNumber;\n }\n return bodyAfterSequenceNumber;\n}\n\n/** True when `user` is the session creator (`created_by`). */\nfunction checkTurnAccess(user: UserContext, createdBy: string): boolean {\n return createdBy === user.userRef;\n}\n\nconst FORBIDDEN_SESSION_ACCESS = 'Only the session creator can access this session';\nconst FORBIDDEN_CREATE_TURN = 'Only the session creator can create turns';\n\n/** DB-backed turns (mounted at /api/v1/sessions). */\nexport function createTurnsRouter(deps: TurnsRouterDeps) {\n const listTurnsHandler: RouteHandler<typeof listTurnsRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const query = c.req.valid('query');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n try {\n const { data, pagination } = await session.listTurns({\n limit: query.limit,\n page_token: query.page_token,\n });\n return c.json({ data: data.map(toWireTurn), pagination }, 200);\n } catch (error) {\n if (error instanceof SessionStoreConflictError) {\n return c.json({ error: { message: error.message } }, 400);\n }\n throw error;\n }\n };\n\n const getTurnHandler: RouteHandler<typeof getTurnRoute> = async c => {\n const { session_id: sessionId, turn_id: turnId } = c.req.valid('param');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n const turn = await session.getTurn(turnId);\n if (!turn) {\n return c.json({ error: { message: `Turn not found: ${turnId}` } }, 404);\n }\n return c.json({ data: toWireTurn(turn.record) }, 200);\n };\n\n const downloadSandboxFileHandler: RouteHandler<typeof downloadSandboxFileRoute> = async c => {\n const { session_id: sessionId, turn_id: turnId } = c.req.valid('param');\n const { path } = c.req.valid('query');\n\n let sandboxId: string | undefined;\n try {\n // Cheapest first: a malformed path costs no store read and no provider round-trip.\n validateSandboxFilePath(path);\n\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n\n // Loading the turn through the session is also a session-binding check: a turn id from another\n // session cannot be used to reach this session's sandbox.\n const turn = await session.getTurn(turnId);\n if (!turn) {\n return c.json({ error: { message: `Turn not found: ${turnId}` } }, 404);\n }\n sandboxId = turn.record.snapshot.sandbox_info?.sandbox_id;\n if (sandboxId === undefined) {\n return c.json({ error: { message: `Turn has no sandbox: ${turnId}` } }, 412);\n }\n\n const provider = await resolveSandboxProvider({\n tenant_id: TENANT_ID,\n store: deps.sandboxProviderStore,\n logger: deps.logger,\n sessionId,\n });\n if (provider === undefined) {\n return c.json({ error: { message: 'No sandbox provider configured' } }, 412);\n }\n\n // TODO: stream the body instead of buffering the whole file in memory.\n const content = await provider.downloadFile({ sandboxId: rawSandboxId(sandboxId), path });\n return c.body(toArrayBuffer(content), 200, {\n 'Content-Type': 'application/octet-stream',\n 'Content-Length': String(content.byteLength),\n 'Content-Disposition': toContentDisposition(path),\n 'Cache-Control': 'private, no-store',\n });\n } catch (error) {\n // Every guard and the provider itself raise SandboxError, whose statusCode is the contract.\n if (error instanceof SandboxError) {\n return c.json({ error: { message: error.message } }, error.statusCode);\n }\n deps.logger.error('Sandbox file download failed', {\n ...extractErrorLogFields(error),\n sessionId,\n turnId,\n sandboxId,\n path,\n });\n return c.json({ error: { message: 'Failed to download file from sandbox' } }, 424);\n }\n };\n\n const listTurnEventsHandler: RouteHandler<typeof listTurnEventsRoute> = async c => {\n const { session_id: sessionId, turn_id: turnId } = c.req.valid('param');\n const query = c.req.valid('query');\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n const turn = await session.getTurn(turnId);\n if (!turn) {\n return c.json({ error: { message: `Turn not found: ${turnId}` } }, 404);\n }\n try {\n const { data, pagination } = await turn.listEvents({\n limit: query.limit,\n page_token: query.page_token,\n order: query.order,\n });\n return c.json({ data, pagination }, 200);\n } catch (error) {\n if (error instanceof SessionStoreConflictError) {\n return c.json({ error: { message: error.message } }, 400);\n }\n throw error;\n }\n };\n\n const createAndExecuteTurnHandler: RouteHandler<typeof createAndExecuteTurnRoute> = async c => {\n const { session_id: sessionId } = c.req.valid('param');\n const body = c.req.valid('json');\n\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_CREATE_TURN } }, 403);\n }\n\n const abortController = new AbortController();\n const resolver = createTurnResolver({\n mcpServerStore: deps.mcpServerStore,\n tokenStore: deps.tokenStore,\n skillStore: deps.skillStore,\n sandboxProviderStore: deps.sandboxProviderStore,\n agentStore: deps.agentStore,\n modelProviderStore: deps.modelProviderStore,\n logger: deps.logger,\n signal: abortController.signal,\n userRef: deps.resolveUserContext(c).userRef,\n sessionId,\n });\n\n // First turn only: derive the title from the first user message. The store\n // never overwrites an existing title.\n const title = session.record.last_turn_id ? undefined : deriveSessionTitle(body.input);\n\n let turn;\n try {\n turn = await session.createTurn({\n turn_id: mintPeeredTurnId(configuration.EXECUTOR_ID),\n input: body.input,\n previous_turn_id: body.previous_turn_id,\n signal: abortController.signal,\n resolver,\n update_session_title_if_not_exist: title,\n });\n } catch (error) {\n if (error instanceof SessionStoreNotFoundError) {\n return c.json({ error: { message: error.message } }, 404);\n }\n if (error instanceof AgentHarnessError && !(error instanceof McpConnectionError)) {\n switch (error.code) {\n case 'invalid_file_input':\n return c.json({ error: { message: error.message } }, 400);\n case 'invalid_send_input':\n case 'agent_sandbox_required':\n case 'tool_name_collision':\n return c.json({ error: { message: error.message } }, 422);\n case 'capability_state_error':\n case 'mcp_connection_failed':\n throw error;\n }\n }\n throw error;\n }\n\n const maxExecutionTimer = setTimeout(() => {\n if (!abortController.signal.aborted) {\n abortController.abort(CancellationReason.ServerExecutionTimeout);\n }\n }, configuration.SERVER_EXECUTION_TIMEOUT_SECONDS * 1000);\n maxExecutionTimer.unref();\n\n const trackedStream = deps.activeTurns.track({\n sessionId,\n turnId: turn.id,\n abortController,\n stream: turn.stream(),\n });\n\n // Held for the whole turn; the stream's sequence counter dies with it.\n const turnEventStream = deps.eventSubscriptions.get(turnStreamId(TENANT_ID, sessionId, turn.id));\n const drainInput = {\n trackedStream,\n turnEventStream,\n sessionId,\n turnId: turn.id,\n maxExecutionTimer,\n logger: deps.logger,\n };\n\n // Non-stream: same unawaited drain scheduling as Hono streamSSE's run(cb).\n // Wait until the first dual-write (turn.created) so immediate subscribeToTurn\n // cannot 412 before the resumable stream exists.\n if (!body.stream) {\n const { promise: firstEventDualWritten, resolve: markFirstEventDualWritten } = Promise.withResolvers<undefined>();\n void drainTurnEvents({\n ...drainInput,\n onEvent: () => {\n markFirstEventDualWritten(undefined);\n return Promise.resolve();\n },\n }).finally(() => {\n markFirstEventDualWritten(undefined);\n });\n await firstEventDualWritten;\n return c.json({ data: toWireTurn(turn.record) }, 200);\n }\n\n let shouldWriteToSSEStream = true;\n return streamSSE(c, async stream => {\n stream.onAbort(() => {\n shouldWriteToSSEStream = false;\n });\n await drainTurnEvents({\n ...drainInput,\n onEvent: async (event, sequenceNumber) => {\n if (!stream.closed && !stream.aborted && shouldWriteToSSEStream) {\n try {\n await stream.writeSSE(turnEventSsePayload(event, sequenceNumber));\n } catch (error) {\n deps.logger.error('SSE stream write error', extractErrorLogFields(error));\n shouldWriteToSSEStream = false;\n }\n }\n },\n });\n await stream.close();\n });\n };\n\n const subscribeTurnHandler: RouteHandler<typeof subscribeTurnRoute> = async c => {\n const { session_id: sessionId, turn_id: turnId } = c.req.valid('param');\n const query = c.req.valid('query');\n const afterSequenceNumber = resolveAfterSequenceNumber(c, query.after_sequence_number);\n\n const session = await deps.sessions.get({ tenant_id: TENANT_ID, session_id: sessionId });\n if (!session) {\n return c.json({ error: { message: `Session not found: ${sessionId}` } }, 404);\n }\n if (!checkTurnAccess(deps.resolveUserContext(c), session.record.created_by)) {\n return c.json({ error: { message: FORBIDDEN_SESSION_ACCESS } }, 403);\n }\n const turn = await session.getTurn(turnId);\n if (!turn) {\n return c.json({ error: { message: `Turn not found: ${turnId}` } }, 404);\n }\n\n const turnEventStream = deps.eventSubscriptions.get(turnStreamId(TENANT_ID, sessionId, turnId));\n\n // Admission check before SSE headers are sent, so it can still map to HTTP 412.\n try {\n await turnEventStream.assertSubscribable();\n } catch (error) {\n if (error instanceof StreamGoneError) {\n throw new HTTPException(412, { message: error.message, cause: error });\n }\n throw error;\n }\n\n // One lifecycle controller: server-side timeout, client disconnect, and\n // normal teardown all abort it, which ends poll even while it is parked\n // waiting for events.\n const subscribeAbort = new AbortController();\n const timeoutMs = configuration.TURN_SUBSCRIBE_TIMEOUT_MS;\n const timeoutHandler = setTimeout(() => {\n deps.logger.info('Subscribe turn stream server-side timeout reached, closing stream', {\n sessionId,\n turnId,\n afterSequenceNumber,\n timeoutMs,\n });\n subscribeAbort.abort(new Error('subscribe-timeout'));\n }, timeoutMs);\n\n return streamSSE(c, async stream => {\n stream.onAbort(() => {\n subscribeAbort.abort(new Error('client-disconnected'));\n });\n\n const generator = turnEventStream.poll(afterSequenceNumber, { signal: subscribeAbort.signal });\n try {\n for await (const { sequence_number: sequenceNumber, ...event } of generator) {\n await stream.writeSSE(turnEventSsePayload(event, sequenceNumber));\n if (event.type === EventType.TURN_DONE) {\n break;\n }\n }\n } catch (error) {\n if (!subscribeAbort.signal.aborted) {\n deps.logger.error('Unexpected error in turn subscribe SSE loop', extractErrorLogFields(error));\n }\n } finally {\n clearTimeout(timeoutHandler);\n // Poll loops forever by design; aborting releases a parked generator\n // immediately so the return() below settles right away.\n subscribeAbort.abort();\n await generator.return(undefined);\n await stream.close();\n }\n });\n };\n\n const router = new OpenAPIHono();\n router.openapi(createAndExecuteTurnRoute, createAndExecuteTurnHandler);\n router.openapi(listTurnsRoute, listTurnsHandler);\n router.openapi(getTurnRoute, getTurnHandler);\n router.openapi(downloadSandboxFileRoute, downloadSandboxFileHandler);\n router.openapi(listTurnEventsRoute, listTurnEventsHandler);\n router.openapi(subscribeTurnRoute, subscribeTurnHandler);\n return router;\n}\n","/**\n * Turn route definitions.\n * DB-backed routes mount at /api/v1/sessions.\n * Handlers are registered in apis/turns.ts.\n */\nimport { createRoute, z } from '@hono/zod-openapi';\nimport { RequestErrorResponseSchema } from '../schemas/errors';\nimport { TurnStreamingEventSchema } from '../schemas/events';\nimport {\n CreateTurnRequestSchema,\n DownloadSandboxFileRequestQuerySchema,\n GetTurnResponseSchema,\n ListTurnEventsRequestQuerySchema,\n ListTurnEventsResponseSchema,\n ListTurnsRequestQuerySchema,\n ListTurnsResponseSchema,\n SubscribeTurnQuerySchema,\n} from '../schemas/turn';\nimport { TOKEN_PAGINATION } from './fernExtensions';\nimport { OpenApiTag } from './openapiTags';\nimport { SessionIdParamsSchema } from './sessionRoutes';\n\nexport const TurnIdParamsSchema = SessionIdParamsSchema.extend({\n turn_id: z.string().min(1).describe('Turn identifier.'),\n});\n\nexport const listTurnsRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'List turns in a session',\n description:\n 'List turns for a session (newest first by default), token-paginated. Only the session creator (`created_by`) may list turns.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'list_turns',\n 'x-fern-pagination': TOKEN_PAGINATION,\n request: {\n params: SessionIdParamsSchema,\n query: ListTurnsRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListTurnsResponseSchema } },\n description: 'Paginated turns.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid page token.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session not found.',\n },\n },\n});\n\nexport const getTurnRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns/{turn_id}',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'Get a turn',\n description: 'Fetch a single turn by ID. Only the session creator (`created_by`) may fetch it.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'get_turn',\n request: {\n params: TurnIdParamsSchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: GetTurnResponseSchema } },\n description: 'Turn data.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session or turn not found.',\n },\n },\n});\n\nexport const downloadSandboxFileRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns/{turn_id}/download-sandbox-file',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'Download a file from the turn sandbox',\n description:\n \"Download a file from the sandbox this turn ran in. Paths come from the assistant's `sandbox_artifacts` block. Only the session creator (`created_by`) may download.\",\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'download_sandbox_file',\n request: {\n params: TurnIdParamsSchema,\n query: DownloadSandboxFileRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/octet-stream': { schema: z.string().openapi({ format: 'binary' }) } },\n description: 'File contents.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid path, or the path is a directory.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session, turn, or file not found.',\n },\n 410: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Sandbox no longer exists.',\n },\n 412: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Turn has no sandbox, or no sandbox provider is configured.',\n },\n 413: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'File exceeds the maximum download size.',\n },\n 424: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Sandbox infrastructure error.',\n },\n },\n});\n\nexport const listTurnEventsRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns/{turn_id}/events',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'List turn events',\n description:\n 'Paginated persisted events for a turn (insertion order by default). Only the session creator (`created_by`) may list events.',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'list_turn_events',\n 'x-fern-pagination': TOKEN_PAGINATION,\n request: {\n params: TurnIdParamsSchema,\n query: ListTurnEventsRequestQuerySchema,\n },\n responses: {\n 200: {\n content: { 'application/json': { schema: ListTurnEventsResponseSchema } },\n description: 'Paginated turn events.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid page token.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session or turn not found.',\n },\n },\n});\n\nexport const createAndExecuteTurnRoute = createRoute({\n method: 'post',\n path: '/{session_id}/turns',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'Create and execute a turn in a session',\n description: `Create a turn within a session and execute it.\nOnly the session creator (\\`created_by\\`) may create turns.\nWhen \\`stream\\` is true (default), respond with a Server-Sent Events stream of turn events.\nWhen \\`stream\\` is false, return the turn immediately with \\`state.status: \"running\"\\` while execution continues in the background; use get turn or subscribe to observe completion.\nUse \\`previous_turn_id\\` to chain to the session's last turn (defaults to \\`auto\\`); use \\`none\\` for a new root.`,\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'create_turn',\n 'x-fern-streaming': {\n format: 'sse',\n resumable: false,\n 'stream-condition': '$request.stream',\n response: { $ref: '#/components/schemas/GetTurnResponse' },\n 'response-stream': { $ref: '#/components/schemas/TurnStreamingEvent' },\n },\n request: {\n params: SessionIdParamsSchema,\n body: {\n content: { 'application/json': { schema: CreateTurnRequestSchema } },\n required: true,\n },\n },\n responses: {\n 200: {\n content: {\n 'application/json': {\n schema: GetTurnResponseSchema,\n },\n 'text/event-stream': {\n schema: TurnStreamingEventSchema,\n },\n },\n description:\n 'When stream is false: the running turn. When stream is true: Server-Sent Events stream of turn events.',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid request body.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Session or prior turn not found.',\n },\n 412: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Requested action cannot be performed on the session because it is no longer usable.',\n },\n 413: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Request body exceeds the configured maximum size (MAX_REQUEST_BODY_BYTES).',\n },\n 422: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description:\n 'The request is well-formed but cannot be processed: a referenced resource is missing ' +\n '(named agent, model, MCP server, skill, or sandbox provider), sandbox is required but ' +\n 'unavailable (e.g. file uploads), or the turn input conflicts with current state ' +\n '(e.g. unresolved tool calls or approvals, tool name collision).',\n },\n },\n});\n\nexport const subscribeTurnRoute = createRoute({\n method: 'get',\n path: '/{session_id}/turns/{turn_id}/subscribe',\n tags: [OpenApiTag.AGENT_SESSIONS],\n summary: 'Subscribe to a running turn',\n description:\n 'Subscribe to the live SSE stream for a turn. Only the session creator (`created_by`) may subscribe. Pass `after_sequence_number` to resume after a disconnect (exclusive — events after this sequence number are replayed).',\n 'x-fern-sdk-group-name': ['sessions'],\n 'x-fern-sdk-method-name': 'subscribe_to_turn',\n 'x-fern-streaming': { format: 'sse', resumable: true },\n request: {\n params: TurnIdParamsSchema,\n query: SubscribeTurnQuerySchema,\n },\n responses: {\n 200: {\n content: {\n 'text/event-stream': {\n schema: TurnStreamingEventSchema,\n },\n },\n description: 'Server-Sent Events stream of turn events (deltas and lifecycle).',\n },\n 400: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Invalid query parameters.',\n },\n 403: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Caller is not the session creator.',\n },\n 404: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Turn not found.',\n },\n 412: {\n content: { 'application/json': { schema: RequestErrorResponseSchema } },\n description: 'Cannot subscribe — the live stream no longer exists.',\n },\n },\n});\n","/**\n * Single-process backend mirroring RedisEventSubscription semantics (dense\n * sequences, whole-stream TTL, poll-forever generators, same errors).\n * Resume only works within one replica.\n */\nimport { EventEmitter, once } from 'node:events';\nimport {\n StreamGoneError,\n SUBSCRIBE_STREAM_THRESHOLD_MS,\n type EventSubscription,\n type EventSubscriptionPollOptions,\n type EventSubscriptionPutOptions,\n type SequencedEvent,\n} from '.';\n\ninterface InMemoryStream<T extends object> {\n /** Dense log: the event at index i has sequence_number i + 1 (1-indexed). */\n events: SequencedEvent<T>[];\n /** Undefined = no TTL set yet (mirrors a Redis key without EXPIRE). */\n expiresAtMs?: number | undefined;\n expiryTimer?: NodeJS.Timeout | undefined;\n}\n\n/**\n * Owns the stream logs and their TTLs; the expiry timer is the in-process\n * equivalent of Redis key eviction.\n */\nexport class InMemoryEventStreamStore<T extends object> {\n private readonly streams = new Map<string, InMemoryStream<T>>();\n /** Rings per stream id on append and expiry so parked pollers wake instantly. */\n private readonly changes = new EventEmitter();\n\n constructor() {\n // One listener per parked poller; unlimited concurrent subscribers.\n this.changes.setMaxListeners(0);\n }\n\n append(streamId: string, event: T, streamTTLSeconds?: number): number {\n const stream = this.getLiveStream(streamId) ?? { events: [] };\n this.streams.set(streamId, stream);\n\n const sequenceNumber = stream.events.length + 1;\n // Deep-copy so the log is isolated from caller mutations (mirrors JSON round-trip in Redis).\n stream.events.push({ ...structuredClone(event), sequence_number: sequenceNumber });\n\n if (streamTTLSeconds && streamTTLSeconds > 0) {\n stream.expiresAtMs = Date.now() + streamTTLSeconds * 1_000;\n this.scheduleExpiry(streamId, stream);\n }\n this.changes.emit(streamId);\n return sequenceNumber;\n }\n\n /** Returns the stream if it exists and has not passed its TTL; drops it lazily otherwise. */\n getLiveStream(streamId: string): InMemoryStream<T> | undefined {\n const stream = this.streams.get(streamId);\n if (!stream) {\n return undefined;\n }\n if (stream.expiresAtMs !== undefined && stream.expiresAtMs <= Date.now()) {\n this.dropStream(streamId, stream);\n return undefined;\n }\n return stream;\n }\n\n /**\n * Resolves on the next append/expiry of the stream; rejects when the signal\n * aborts (which also detaches the listener, so abandoned waits do not leak).\n */\n async waitForChange(streamId: string, signal?: AbortSignal): Promise<void> {\n await once(this.changes, streamId, { signal });\n }\n\n /**\n * Evicts a stream: clears its timer, removes it from the map, and wakes any\n * parked pollers so they observe StreamGoneError promptly. Shared by the\n * lazy-expiry path in getLiveStream and the scheduled expiry timer.\n */\n private dropStream(streamId: string, stream: InMemoryStream<T>): void {\n if (stream.expiryTimer) {\n clearTimeout(stream.expiryTimer);\n stream.expiryTimer = undefined;\n }\n if (this.streams.get(streamId) !== stream) {\n return;\n }\n this.streams.delete(streamId);\n this.changes.emit(streamId);\n }\n\n private scheduleExpiry(streamId: string, stream: InMemoryStream<T>): void {\n if (stream.expiryTimer) {\n clearTimeout(stream.expiryTimer);\n }\n if (stream.expiresAtMs === undefined) {\n return;\n }\n stream.expiryTimer = setTimeout(\n () => {\n this.dropStream(streamId, stream);\n },\n Math.max(0, stream.expiresAtMs - Date.now()),\n );\n stream.expiryTimer.unref();\n }\n}\n\n/** Stream-scoped view over the shared store; implements the transport contract. */\nexport class InMemoryEventSubscription<T extends object> implements EventSubscription<T> {\n constructor(\n private readonly store: InMemoryEventStreamStore<T>,\n private readonly streamId: string,\n ) {}\n\n put(event: T, options?: EventSubscriptionPutOptions): Promise<number> {\n return Promise.resolve(this.store.append(this.streamId, event, options?.streamTTLSeconds));\n }\n\n assertSubscribable(): Promise<void> {\n const stream = this.store.getLiveStream(this.streamId);\n if (!stream) {\n throw new StreamGoneError(this.streamId);\n }\n // Expiring within the threshold is treated as already gone, mirroring the Redis backend.\n if (stream.expiresAtMs !== undefined && stream.expiresAtMs - Date.now() < SUBSCRIBE_STREAM_THRESHOLD_MS) {\n throw new StreamGoneError(this.streamId);\n }\n return Promise.resolve();\n }\n\n async *poll(\n afterSequenceNumber?: number,\n options?: EventSubscriptionPollOptions,\n ): AsyncGenerator<SequencedEvent<T>, void, unknown> {\n const signal = options?.signal;\n // 0 and omitted both mean \"from the start\". With 1-indexed sequences stored at\n // index seq-1, \"strictly after N\" starts at array index N.\n let cursor = afterSequenceNumber === undefined || afterSequenceNumber === 0 ? 0 : afterSequenceNumber;\n for (;;) {\n if (signal?.aborted) {\n return;\n }\n const live = this.store.getLiveStream(this.streamId);\n if (!live) {\n throw new StreamGoneError(this.streamId);\n }\n const end = live.events.length;\n if (cursor >= end) {\n try {\n await this.store.waitForChange(this.streamId, signal);\n } catch (error) {\n if (signal?.aborted) {\n return;\n }\n throw error;\n }\n continue;\n }\n // Deep-copy each yielded event so consumers cannot mutate the stored log.\n // Snapshot `end` so appends during yield are left for the next pass.\n while (cursor < end) {\n const event = live.events[cursor];\n if (event === undefined) {\n throw new Error(`Corrupt stream ${this.streamId}: missing event at index ${String(cursor)}`);\n }\n cursor += 1;\n yield structuredClone(event);\n }\n }\n }\n}\n","import { setTimeout as sleep } from 'node:timers/promises';\nimport type { RedisClientType } from 'redis';\nimport {\n StreamGoneError,\n SUBSCRIBE_STREAM_THRESHOLD_MS,\n type EventSubscription,\n type EventSubscriptionPollOptions,\n type EventSubscriptionPutOptions,\n type SequencedEvent,\n} from '.';\n\nconst SUBSCRIBE_STREAM_POLL_ITEMS_COUNT = 100;\n/** Delay between XREAD polls while a stream has no new events (a blocking XREAD would monopolize the shared connection). */\nconst SUBSCRIBE_STREAM_POLL_SLEEP_INTERVAL_MS = 1_000;\n\nfunction sequenceNumberFromEntryId(streamId: string, entryId: string): number {\n const separator = entryId.indexOf('-');\n const raw = separator === -1 ? entryId : entryId.slice(0, separator);\n const sequenceNumber = Number(raw);\n if (!Number.isSafeInteger(sequenceNumber) || sequenceNumber < 0) {\n throw new Error(`Corrupt stream entry ${entryId} on ${streamId}: invalid sequence number`);\n }\n return sequenceNumber;\n}\n\n/**\n * One Redis Stream with locally minted 1-indexed sequence numbers. Assumes a\n * single producer per stream; the counter dies with the instance, the data via key TTL.\n */\nexport class RedisEventSubscription<T extends object> implements EventSubscription<T> {\n private nextSequenceNumber = 1;\n\n constructor(\n private readonly redis: RedisClientType,\n private readonly streamId: string,\n ) {}\n\n async put(event: T, options?: EventSubscriptionPutOptions): Promise<number> {\n const sequenceNumber = this.nextSequenceNumber;\n this.nextSequenceNumber += 1;\n\n const sequencedEvent: SequencedEvent<T> = { ...event, sequence_number: sequenceNumber };\n const multi = this.redis.multi().xAdd(this.streamId, `${String(sequenceNumber)}-1`, {\n data: JSON.stringify(sequencedEvent),\n });\n if (options?.streamTTLSeconds && options.streamTTLSeconds > 0) {\n multi.expire(this.streamId, options.streamTTLSeconds);\n }\n await multi.exec();\n return sequenceNumber;\n }\n\n async assertSubscribable(): Promise<void> {\n const expiresAtMs = await this.redis.pExpireTime(this.streamId);\n if (expiresAtMs === -2) {\n throw new StreamGoneError(this.streamId);\n }\n // Expiring within the threshold is treated as already gone: too little\n // time remains for a subscription to be useful.\n if (expiresAtMs >= 0 && expiresAtMs - Date.now() < SUBSCRIBE_STREAM_THRESHOLD_MS) {\n throw new StreamGoneError(this.streamId);\n }\n }\n\n async *poll(\n afterSequenceNumber?: number,\n options?: EventSubscriptionPollOptions,\n ): AsyncGenerator<SequencedEvent<T>, void, unknown> {\n const signal = options?.signal;\n // 0 and omitted both mean \"from the start\" (sequences are 1-indexed).\n // Entries are `${seq}-1`. XREAD returns IDs greater than `id`, so\n // `${N+1}-0` is an exclusive lower bound just below the next entry.\n let cursor =\n afterSequenceNumber === undefined || afterSequenceNumber === 0 ? '1-0' : `${String(afterSequenceNumber + 1)}-0`;\n for (;;) {\n if (signal?.aborted) {\n return;\n }\n if ((await this.redis.exists(this.streamId)) === 0) {\n throw new StreamGoneError(this.streamId);\n }\n const reply = await this.redis.xRead([{ key: this.streamId, id: cursor }], {\n COUNT: SUBSCRIBE_STREAM_POLL_ITEMS_COUNT,\n });\n const messages = reply?.[0]?.messages ?? [];\n if (messages.length === 0) {\n try {\n await sleep(SUBSCRIBE_STREAM_POLL_SLEEP_INTERVAL_MS, undefined, { signal });\n } catch (error) {\n if (signal?.aborted) {\n return;\n }\n throw error;\n }\n continue;\n }\n\n for (const { id, message } of messages) {\n cursor = id;\n const data = message['data'];\n if (data === undefined) {\n throw new Error(`Corrupt stream entry ${id} on ${this.streamId}: missing data field`);\n }\n\n let event: T;\n try {\n // Own writes read back; trusted without validation, as in the gateway.\n event = JSON.parse(data) as T;\n } catch (error) {\n throw new Error(`Corrupt stream entry ${id} on ${this.streamId}: data is not valid JSON`, {\n cause: error,\n });\n }\n yield { ...event, sequence_number: sequenceNumberFromEntryId(this.streamId, id) };\n }\n }\n }\n}\n","import type { RedisClientType } from 'redis';\nimport { InMemoryEventStreamStore, InMemoryEventSubscription } from './inMemory';\nimport { RedisEventSubscription } from './redis';\n\nexport interface EventSubscriptionPutOptions {\n /** Sets the lifetime of the whole stream after this append. */\n streamTTLSeconds?: number | undefined;\n}\n\nexport type SequencedEvent<T extends object> = T & { sequence_number: number };\n\nexport interface EventSubscriptionPollOptions {\n /** Ends the generator promptly on abort, releasing any parked idle wait. */\n signal?: AbortSignal | undefined;\n}\n\n/**\n * One turn's resumable event stream, obtained from {@link EventSubscriptionRegistry.get}.\n * Per-stream state (e.g. the sequence counter) lives on the instance and is freed with it.\n */\nexport interface EventSubscription<T extends object> {\n /** Appends an event, assigns its sequence number, and returns that number. */\n put(event: T, options?: EventSubscriptionPutOptions): Promise<number>;\n\n /**\n * Subscription admission check, run before SSE headers are sent: rejects with\n * {@link StreamGoneError} when the stream is missing or expires within\n * {@link SUBSCRIBE_STREAM_THRESHOLD_MS}.\n */\n assertSubscribable(): Promise<void>;\n\n /**\n * Yields events strictly after the supplied sequence number.\n * Sequences are 1-indexed; omit or pass 0 to start from the first event.\n */\n poll(\n afterSequenceNumber?: number,\n options?: EventSubscriptionPollOptions,\n ): AsyncGenerator<SequencedEvent<T>, void, unknown>;\n}\n\n/**\n * Hands out stream-scoped {@link EventSubscription}s: Redis-backed when a\n * client is supplied, otherwise views over one shared in-process store.\n */\nexport class EventSubscriptionRegistry<T extends object> {\n /** One store for the whole process so producers and subscribers share streams. */\n private readonly memoryStore = new InMemoryEventStreamStore<T>();\n\n constructor(private readonly redis: RedisClientType | undefined) {}\n\n get(streamId: string): EventSubscription<T> {\n if (this.redis) {\n return new RedisEventSubscription<T>(this.redis, streamId);\n }\n return new InMemoryEventSubscription(this.memoryStore, streamId);\n }\n}\n\n/** Reject new subscriptions when the stream expires within this window. */\nexport const SUBSCRIBE_STREAM_THRESHOLD_MS = 60 * 1_000;\n\n/** The stream expired or was never created (map to HTTP 412). */\nexport class StreamGoneError extends Error {\n readonly code = 'STREAM_GONE' as const;\n\n constructor(readonly streamId: string) {\n super(`Cannot read from stream, stream does not exist anymore: ${streamId}`);\n this.name = 'StreamGoneError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Validation for caller-supplied sandbox download paths. This is an HTTP concern — the harness\n * library only guards its own file operations — so it lives with the route that accepts the path.\n */\nimport { SandboxError, validateNoPathTraversal } from '@truefoundry/trueforge-core/core';\n\nclass SandboxInvalidPathError extends SandboxError {\n readonly statusCode = 400;\n\n constructor({ path, reason }: { path: string; reason: string }) {\n super(`Path ${reason}: ${path}`);\n this.name = 'SandboxInvalidPathError';\n }\n}\n\n/**\n * Past these the kernel rejects the path before any file is opened. PATH_MAX (4096) counts the\n * terminating NUL, so the longest usable path is one byte shorter; NAME_MAX (255) does not.\n */\nconst MAX_PATH_BYTES = 4095;\nconst MAX_SEGMENT_BYTES = 255;\n\n/**\n * Every check a caller-supplied download path must pass before it reaches a provider. Shape\n * violations are caught here because a provider reports them as opaque backend failures,\n * indistinguishable from a real outage.\n */\nexport function validateSandboxFilePath(path: string): void {\n if (!path.startsWith('/')) {\n throw new SandboxInvalidPathError({ path, reason: 'must be absolute' });\n }\n if (path.includes('\\0')) {\n throw new SandboxInvalidPathError({ path, reason: 'must not contain a NUL byte' });\n }\n if (Buffer.byteLength(path) > MAX_PATH_BYTES) {\n throw new SandboxInvalidPathError({ path, reason: `must be at most ${String(MAX_PATH_BYTES)} bytes` });\n }\n if (path.split('/').some(segment => Buffer.byteLength(segment) > MAX_SEGMENT_BYTES)) {\n throw new SandboxInvalidPathError({\n path,\n reason: `must not have a segment longer than ${String(MAX_SEGMENT_BYTES)} bytes`,\n });\n }\n validateNoPathTraversal(path);\n}\n","/**\n * Package version for logs, the OpenAPI document, and the CLI.\n *\n * Read from `package.json` next to this module's package root — the same\n * `src/` vs `dist/` layout as `config.ts` (`import.meta` → parent).\n */\nimport { readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');\n\nfunction readPackageVersion(): string {\n const packageJsonPath = path.join(PACKAGE_ROOT, 'package.json');\n const parsed: unknown = JSON.parse(readFileSync(packageJsonPath, 'utf8'));\n if (typeof parsed !== 'object' || parsed === null || !('version' in parsed)) {\n throw new Error(`${packageJsonPath} is missing a version field`);\n }\n const { version } = parsed;\n if (typeof version !== 'string' || version.length === 0) {\n throw new Error(`${packageJsonPath} version must be a non-empty string`);\n }\n return version;\n}\n\nexport const PACKAGE_VERSION = readPackageVersion();\n","/** Shared Zod → HTTP 400 formatting for OpenAPI validation and thrown ZodError. */\nimport type { Hook } from '@hono/zod-openapi';\nimport { z } from '@hono/zod-openapi';\nimport type { Context } from 'hono';\n\nexport function zodErrorResponse(c: Context, error: z.ZodError) {\n return c.json({ error: { message: z.prettifyError(error) } }, 400);\n}\n\nexport const zodValidationHook: Hook<unknown, object, string, Response | undefined> = (result, c) => {\n if (!result.success) {\n return zodErrorResponse(c, result.error);\n }\n return undefined;\n};\n","/**\n * Shipped MCP catalog (mcp-catalog.yaml): the discovery list of server\n * presets offered by GET /catalogs/mcp-servers for the UI to copy into\n * PUT /settings/mcp-servers bodies. Never consulted on writes and never\n * read by the runtime.\n *\n * Default: YAML inlined into `mcpCatalog.gen.ts` at build time. Optional\n * override: `MCP_CATALOG_PATH` (file on disk).\n */\nimport configuration from '../config';\nimport { McpCatalogFileSchema, type CatalogMcpServer } from '../schemas/mcpCatalog';\nimport { loadYamlAtPath, parseYamlString } from './loadYaml';\nimport { shippedMcpCatalogYaml } from './mcpCatalog.gen';\n\nexport class McpCatalog {\n private readonly mcpServers: readonly CatalogMcpServer[];\n\n constructor(mcpServers: readonly CatalogMcpServer[]) {\n this.mcpServers = mcpServers;\n }\n\n /** Loads and validates the catalog. Throws on any error. */\n static load(): McpCatalog {\n if (configuration.MCP_CATALOG_PATH !== undefined) {\n const file = loadYamlAtPath(configuration.MCP_CATALOG_PATH, McpCatalogFileSchema);\n return new McpCatalog(file.mcp_servers);\n }\n const file = parseYamlString(shippedMcpCatalogYaml, McpCatalogFileSchema, 'shipped mcp-catalog');\n return new McpCatalog(file.mcp_servers);\n }\n\n list(): readonly CatalogMcpServer[] {\n return this.mcpServers;\n }\n}\n","/**\n * Reads and validates a YAML config file. Any failure (missing file, invalid\n * YAML, schema violation) throws, so callers fail at startup with a message\n * pointing at the offending file.\n */\nimport fs from 'node:fs';\nimport { parse } from 'yaml';\nimport type { z } from 'zod';\n\n/** Parses and validates YAML text. `label` is used in error messages. */\nexport function parseYamlString<T>(raw: string, schema: z.ZodType<T>, label: string): T {\n let document: unknown;\n try {\n document = parse(raw);\n } catch (error) {\n throw new Error(`Invalid YAML in ${label}: ${error instanceof Error ? error.message : String(error)}`, {\n cause: error,\n });\n }\n\n const result = schema.safeParse(document);\n if (!result.success) {\n const issues = result.error.issues\n .map(issue => ` - ${issue.path.length > 0 ? issue.path.join('.') : '(root)'}: ${issue.message}`)\n .join('\\n');\n throw new Error(`Invalid config in ${label}:\\n${issues}`);\n }\n return result.data;\n}\n\nexport function loadYamlAtPath<T>(filePath: string, schema: z.ZodType<T>): T {\n let raw: string;\n try {\n raw = fs.readFileSync(filePath, 'utf8');\n } catch (error) {\n throw new Error(\n `Failed to read config file ${filePath}: ${error instanceof Error ? error.message : String(error)}`,\n { cause: error },\n );\n }\n\n return parseYamlString(raw, schema, filePath);\n}\n","// AUTO-GENERATED by scripts/generate-catalog.mjs — do not edit.\nexport const shippedMcpCatalogYaml = \"# Shipped MCP catalog: server presets offered by\\n# GET /api/v1/catalog/mcp-servers for the UI to copy into\\n# PUT /api/v1/settings/mcp-servers bodies. Discovery-only — never executed against.\\nmcp_servers:\\n - type: remote\\n name: linear\\n logo: https://assets.production.truefoundry.com/linear.svg\\n url: https://mcp.linear.app/mcp\\n description: Search, read, and create Linear issues.\\n auth:\\n type: dcr\\n - type: remote\\n name: notion\\n logo: https://assets.production.truefoundry.com/notion.svg\\n url: https://mcp.notion.com/mcp\\n description: Search pages, read content, query databases, create pages.\\n auth:\\n type: dcr\\n - type: remote\\n name: sentry\\n logo: https://assets.production.truefoundry.com/sentry.svg\\n url: https://mcp.sentry.dev/mcp\\n description: Search errors, read stack traces, and check releases.\\n auth:\\n type: dcr\\n - type: remote\\n name: deepwiki\\n logo: https://assets.production.truefoundry.com/deepwiki.png\\n url: https://mcp.deepwiki.com/mcp\\n description: Read documentation and ask questions about any public GitHub repository.\\n - type: remote\\n name: exa\\n logo: https://assets.production.truefoundry.com/exa.svg\\n url: https://mcp.exa.ai/mcp\\n description: Search the web, fetch page contents, and find similar pages.\\n - type: remote\\n name: parallel-web\\n logo: https://assets.production.truefoundry.com/parallel-web.svg\\n url: https://search.parallel.ai/mcp\\n description: Search the web and get ranked results with extracted content.\\n - type: remote\\n name: github\\n logo: https://assets.production.truefoundry.com/github.svg\\n url: https://api.githubcopilot.com/mcp/\\n description: Work with issues, pull requests, repository files, and CI status.\\n auth:\\n type: header\\n headers:\\n Authorization: Bearer YOUR_GITHUB_PAT\\n - type: remote\\n name: tavily\\n logo: https://assets.production.truefoundry.com/tavily.svg\\n url: https://mcp.tavily.com/mcp\\n description: Search the web, extract page content, and crawl sites.\\n auth:\\n type: header\\n headers:\\n Authorization: Bearer YOUR_TAVILY_API_KEY\\n - type: remote\\n name: bright-data\\n logo: https://assets.production.truefoundry.com/bright-data.png\\n url: https://mcp.brightdata.com/mcp\\n description: Search the web and scrape pages, including sites behind bot protection.\\n auth:\\n type: header\\n headers:\\n Authorization: Bearer YOUR_BRIGHT_DATA_API_TOKEN\\n - type: remote\\n name: supabase\\n logo: https://assets.production.truefoundry.com/supabase.svg\\n url: https://mcp.supabase.com/mcp\\n description: Run SQL queries, manage tables, and inspect Supabase projects.\\n auth:\\n type: dcr\\n - type: remote\\n name: stripe\\n logo: https://assets.production.truefoundry.com/stripe.svg\\n url: https://mcp.stripe.com\\n description: Create and manage customers, payments, invoices, and subscriptions.\\n auth:\\n type: dcr\\n - type: remote\\n name: confluence\\n logo: https://assets.production.truefoundry.com/confluence.svg\\n url: https://mcp.atlassian.com/v1/mcp\\n description: Search spaces, read pages, and create or update content.\\n auth:\\n type: dcr\\n - type: remote\\n name: jira\\n logo: https://assets.production.truefoundry.com/jira.png\\n url: https://mcp.atlassian.com/v1/mcp\\n description: Search, read, create, and update Jira issues.\\n auth:\\n type: dcr\\n - type: remote\\n name: posthog\\n logo: https://assets.production.truefoundry.com/posthog.svg\\n url: https://mcp.posthog.com/mcp\\n description: Query product analytics, run SQL, and manage feature flags.\\n auth:\\n type: dcr\\n\" as const;\n","/**\n * Shipped model catalog (model-catalog.yaml): the discovery list of provider\n * and model presets offered by GET /catalogs/model-providers for the UI to copy\n * into PUT /settings/model-providers bodies. Never consulted on writes and never\n * read by the runtime.\n *\n * Default: YAML inlined into `modelCatalog.gen.ts` at build time. Optional\n * override: `MODEL_CATALOG_PATH` (file on disk).\n */\nimport configuration from '../config';\nimport { ModelCatalogFileSchema, type CatalogWellKnownModelProvider } from '../schemas/modelCatalog';\nimport { loadYamlAtPath, parseYamlString } from './loadYaml';\nimport { shippedModelCatalogYaml } from './modelCatalog.gen';\n\nexport class ModelCatalog {\n private readonly providers: readonly CatalogWellKnownModelProvider[];\n\n constructor(providers: readonly CatalogWellKnownModelProvider[]) {\n this.providers = providers;\n }\n\n /** Loads and validates the catalog. Throws on any error. */\n static load(): ModelCatalog {\n if (configuration.MODEL_CATALOG_PATH !== undefined) {\n const file = loadYamlAtPath(configuration.MODEL_CATALOG_PATH, ModelCatalogFileSchema);\n return new ModelCatalog(file.providers);\n }\n const file = parseYamlString(shippedModelCatalogYaml, ModelCatalogFileSchema, 'shipped model-catalog');\n return new ModelCatalog(file.providers);\n }\n\n list(): readonly CatalogWellKnownModelProvider[] {\n return this.providers;\n }\n}\n","// AUTO-GENERATED by scripts/generate-catalog.mjs — do not edit.\nexport const shippedModelCatalogYaml = \"# Shipped model catalog: provider/model presets offered by\\n# GET /api/v1/catalog/model-providers for the UI to copy into\\n# PUT /api/v1/settings/model-providers bodies. Discovery-only — never executed against.\\nproviders:\\n - type: openai\\n logo: https://assets.production.truefoundry.com/openai.svg\\n models:\\n - model_id: gpt-5.4-mini\\n name: gpt-5-4-mini\\n properties:\\n context_length: 400000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: gpt-5.5\\n name: gpt-5-5\\n properties:\\n context_length: 1050000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: gpt-5.6-luna\\n name: gpt-5-6-luna\\n properties:\\n context_length: 1050000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: gpt-5.6-sol\\n name: gpt-5-6-sol\\n properties:\\n context_length: 1050000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: gpt-5.6-terra\\n name: gpt-5-6-terra\\n properties:\\n context_length: 1050000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: anthropic\\n logo: https://assets.production.truefoundry.com/anthropic.svg\\n models:\\n - model_id: claude-fable-5\\n name: claude-fable-5\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: claude-haiku-4-5\\n name: claude-haiku-4-5\\n properties:\\n context_length: 200000\\n max_output_tokens: 64000\\n - model_id: claude-opus-4-8\\n name: claude-opus-4-8\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: claude-opus-5\\n name: claude-opus-5\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: claude-sonnet-4-6\\n name: claude-sonnet-4-6\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - max\\n - model_id: claude-sonnet-5\\n name: claude-sonnet-5\\n properties:\\n context_length: 1000000\\n max_output_tokens: 128000\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: google-gemini\\n logo: https://assets.production.truefoundry.com/google-gemini.svg\\n models:\\n - model_id: gemini-3.1-pro-preview\\n name: gemini-3-1-pro-preview\\n properties:\\n context_length: 1048576\\n max_output_tokens: 65536\\n reasoning_efforts:\\n - low\\n - medium\\n - high\\n - model_id: gemini-3.6-flash\\n name: gemini-3-6-flash\\n properties:\\n context_length: 1048576\\n max_output_tokens: 65536\\n reasoning_efforts:\\n - minimal\\n - low\\n - medium\\n - high\\n - type: fireworks\\n logo: https://assets.production.truefoundry.com/fireworks.svg\\n models:\\n - model_id: accounts/fireworks/models/deepseek-v4-pro\\n name: deepseek-v4-pro\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: accounts/fireworks/models/glm-5p2\\n name: glm-5p2\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: accounts/fireworks/models/kimi-k2p7-code\\n name: kimi-k2p7-code\\n properties:\\n context_length: 262144\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: accounts/fireworks/models/kimi-k3\\n name: kimi-k3\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - model_id: accounts/fireworks/models/minimax-m3\\n name: minimax-m3\\n properties:\\n context_length: 512000\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: zai\\n logo: https://assets.production.truefoundry.com/zai.svg\\n models:\\n - model_id: glm-5-turbo\\n name: glm-5-turbo\\n properties:\\n context_length: 200000\\n max_output_tokens: 131072\\n - model_id: glm-5.1\\n name: glm-5-1\\n properties:\\n context_length: 200000\\n max_output_tokens: 131072\\n - model_id: glm-5.2\\n name: glm-5-2\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: moonshot\\n logo: https://assets.production.truefoundry.com/moonshot.png\\n models:\\n - model_id: kimi-k2.7-code\\n name: kimi-k2-7-code\\n properties:\\n context_length: 262144\\n - model_id: kimi-k3\\n name: kimi-k3\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - low\\n - high\\n - max\\n - type: alibaba\\n logo: https://assets.production.truefoundry.com/alibaba.png\\n models:\\n - model_id: qwen3.7-flash\\n name: qwen3-7-flash\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: qwen3.7-max\\n name: qwen3-7-max\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: qwen3.7-plus\\n name: qwen3-7-plus\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: qwen3.8-max\\n name: qwen3-8-max\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - max\\n - type: together\\n logo: https://assets.production.truefoundry.com/togetherai.svg\\n models:\\n - model_id: deepseek-ai/DeepSeek-V4-Pro\\n name: deepseek-v4-pro\\n properties:\\n context_length: 512000\\n reasoning_efforts:\\n - high\\n - max\\n - model_id: MiniMaxAI/MiniMax-M3\\n name: minimax-m3\\n properties:\\n context_length: 524288\\n - model_id: moonshotai/Kimi-K2.7-Code\\n name: kimi-k2-7-code\\n properties:\\n context_length: 262144\\n - model_id: moonshotai/Kimi-K3\\n name: kimi-k3\\n properties:\\n context_length: 1048576\\n reasoning_efforts:\\n - none\\n - low\\n - medium\\n - high\\n - max\\n - model_id: Qwen/Qwen3.7-Max\\n name: qwen3-7-max\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: Qwen/Qwen3.7-Plus\\n name: qwen3-7-plus\\n properties:\\n context_length: 1000000\\n max_output_tokens: 131072\\n reasoning_efforts:\\n - none\\n - minimal\\n - low\\n - medium\\n - high\\n - xhigh\\n - model_id: zai-org/GLM-5.2\\n name: glm-5-2\\n properties:\\n context_length: 512000\\n reasoning_efforts:\\n - high\\n - max\\n\" as const;\n","/**\n * Shipped sandbox catalog (sandbox-catalog.yaml): the discovery list of provider\n * presets offered by GET /catalogs/sandbox-providers for the UI to copy into\n * PUT /settings/sandbox-providers bodies. Never consulted on writes and never\n * read by the runtime.\n *\n * Default: YAML inlined into `sandboxCatalog.gen.ts` at build time. Optional\n * override: `SANDBOX_CATALOG_PATH` (file on disk).\n */\nimport configuration from '../config';\nimport { SandboxCatalogFileSchema, type CatalogSandboxProvider } from '../schemas/sandboxCatalog';\nimport { loadYamlAtPath, parseYamlString } from './loadYaml';\nimport { shippedSandboxCatalogYaml } from './sandboxCatalog.gen';\n\nexport class SandboxCatalog {\n private readonly providers: readonly CatalogSandboxProvider[];\n\n constructor(providers: readonly CatalogSandboxProvider[]) {\n this.providers = providers;\n }\n\n /** Loads and validates the catalog. Throws on any error. */\n static load(): SandboxCatalog {\n if (configuration.SANDBOX_CATALOG_PATH !== undefined) {\n const file = loadYamlAtPath(configuration.SANDBOX_CATALOG_PATH, SandboxCatalogFileSchema);\n return new SandboxCatalog(file.providers);\n }\n const file = parseYamlString(shippedSandboxCatalogYaml, SandboxCatalogFileSchema, 'shipped sandbox-catalog');\n return new SandboxCatalog(file.providers);\n }\n\n list(): readonly CatalogSandboxProvider[] {\n return this.providers;\n }\n}\n","// AUTO-GENERATED by scripts/generate-catalog.mjs — do not edit.\nexport const shippedSandboxCatalogYaml = \"# Shipped sandbox catalog: provider presets offered by\\n# GET /api/v1/catalog/sandbox-providers for the UI to copy into\\n# PUT /api/v1/settings/sandbox-providers bodies. Discovery-only — never executed against.\\nproviders:\\n - type: daytona\\n exec_timeout_ms: 60000\\n auto_stop_interval_in_minutes: 5\\n auto_archive_interval_in_minutes: 60\\n auto_delete_interval_in_minutes: 7200\\n\" as const;\n","/**\n * Shipped skill catalog (skill-catalog.yaml): the discovery list of skill\n * presets offered by GET /catalogs/skills for the UI to copy into\n * PUT /settings/skills bodies. Never consulted on writes and never\n * read by the runtime.\n *\n * Default: YAML inlined into `skillCatalog.gen.ts` at build time. Optional\n * override: `SKILL_CATALOG_PATH` (file on disk).\n */\nimport configuration from '../config';\nimport { SkillCatalogFileSchema, type CatalogSkill } from '../schemas/skillCatalog';\nimport { loadYamlAtPath, parseYamlString } from './loadYaml';\nimport { shippedSkillCatalogYaml } from './skillCatalog.gen';\n\nexport class SkillCatalog {\n private readonly skills: readonly CatalogSkill[];\n\n constructor(skills: readonly CatalogSkill[]) {\n this.skills = skills;\n }\n\n /** Loads and validates the catalog. Throws on any error. */\n static load(): SkillCatalog {\n if (configuration.SKILL_CATALOG_PATH !== undefined) {\n const file = loadYamlAtPath(configuration.SKILL_CATALOG_PATH, SkillCatalogFileSchema);\n return new SkillCatalog(file.skills);\n }\n const file = parseYamlString(shippedSkillCatalogYaml, SkillCatalogFileSchema, 'shipped skill-catalog');\n return new SkillCatalog(file.skills);\n }\n\n list(): readonly CatalogSkill[] {\n return this.skills;\n }\n}\n","// AUTO-GENERATED by scripts/generate-catalog.mjs — do not edit.\nexport const shippedSkillCatalogYaml = \"# Shipped skill catalog: skill presets offered by\\n# GET /api/v1/catalog/skills for the UI to copy into\\n# PUT /api/v1/settings/skills bodies. Discovery-only — never executed against.\\n#\\n# Entries reference upstream skill repos directly (url + path + ref); installing\\n# a preset sparse-clones that subdirectory into the sandbox. Only permissively\\n# licensed skills (Apache-2.0 / MIT) are listed — licenses were verified against\\n# each skill's upstream LICENSE and are noted in the comments below. The schema\\n# stores only {type, name, url, path, ref, description}; license and the MCP a\\n# skill pairs with live in the comments for provenance.\\n#\\n# NOTE: Anthropic's document skills (pdf, docx, pptx, xlsx) are intentionally\\n# excluded — their LICENSE.txt is proprietary (\\\"All rights reserved\\\", usable\\n# only within Anthropic's Services) and forbids extracting/retaining/redistributing\\n# the materials, which a clone-into-sandbox preset would do.\\nskills:\\n # ── Anthropic skills (github.com/anthropics/skills · per-skill LICENSE, all Apache-2.0) ──\\n - type: git\\n name: algorithmic-art\\n url: https://github.com/anthropics/skills\\n path: skills/algorithmic-art\\n ref: main\\n description: Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration.\\n\\n # Agent-builder skills — author skills, MCP servers, and web artifacts.\\n - type: git\\n name: skill-creator\\n url: https://github.com/anthropics/skills\\n path: skills/skill-creator\\n ref: main\\n description: Scaffold, refine, and package new Agent Skills, including SKILL.md structure and evaluation.\\n - type: git\\n name: mcp-builder\\n url: https://github.com/anthropics/skills\\n path: skills/mcp-builder\\n ref: main\\n description: Build Model Context Protocol (MCP) servers — tool definitions, transports, and packaging.\\n - type: git\\n name: web-artifacts-builder\\n url: https://github.com/anthropics/skills\\n path: skills/web-artifacts-builder\\n ref: main\\n description: Build self-contained web artifacts (HTML/JS/CSS) that render as interactive standalone pages.\\n\\n # ── MCP-paired workflow skills (each pairs with the noted MCP connector) ──\\n\\n # tavily-research — pairs with the Tavily retrieval MCP. (tavily-ai/skills · MIT)\\n - type: git\\n name: tavily-research\\n url: https://github.com/tavily-ai/skills\\n path: skills/tavily-research\\n ref: main\\n description: Run structured web research with the Tavily MCP — search, extract, and synthesize sources.\\n\\n # supabase — pairs with the Supabase MCP. (supabase/agent-skills · MIT)\\n - type: git\\n name: supabase\\n url: https://github.com/supabase/agent-skills\\n path: skills/supabase\\n ref: main\\n description: Query and manage a Supabase Postgres database via SQL through the Supabase MCP.\\n\\n # wiki-architect / wiki-qa — pair with DeepWiki / GitHub for repo briefs. (microsoft/skills · MIT)\\n - type: git\\n name: wiki-architect\\n url: https://github.com/microsoft/skills\\n path: .github/plugins/deep-wiki/skills/wiki-architect\\n ref: main\\n description: Plan and structure a repository wiki / brief from a codebase (DeepWiki).\\n - type: git\\n name: wiki-qa\\n url: https://github.com/microsoft/skills\\n path: .github/plugins/deep-wiki/skills/wiki-qa\\n ref: main\\n description: Answer questions about a repository from its generated wiki (DeepWiki); companion to wiki-architect.\\n\\n # openai/skills — per-skill licenses (verified). Apache-2.0 unless noted.\\n # NOTE: this repo is deprecated upstream — plan to re-vendor from openai/plugins\\n # later and update the url/path/ref.\\n # linear — pairs with the Linear MCP. (Apache-2.0)\\n - type: git\\n name: linear\\n url: https://github.com/openai/skills\\n path: skills/.curated/linear\\n ref: main\\n description: Triage and manage Linear issues (create, update, search) via the Linear MCP.\\n # gh-fix-ci — pairs with the GitHub MCP. (Apache-2.0)\\n - type: git\\n name: gh-fix-ci\\n url: https://github.com/openai/skills\\n path: skills/.curated/gh-fix-ci\\n ref: main\\n description: Diagnose and fix failing GitHub CI checks on a pull request via the GitHub MCP.\\n # notion-knowledge-capture — pairs with the Notion MCP. (MIT · Notion Labs, Inc.)\\n - type: git\\n name: notion-knowledge-capture\\n url: https://github.com/openai/skills\\n path: skills/.curated/notion-knowledge-capture\\n ref: main\\n description: Capture and organize knowledge into Notion pages and databases via the Notion MCP.\\n # sentry — pairs with the Sentry MCP. (Apache-2.0)\\n - type: git\\n name: sentry\\n url: https://github.com/openai/skills\\n path: skills/.curated/sentry\\n ref: main\\n description: Investigate and triage Sentry errors and issues via the Sentry MCP.\\n # jupyter-notebook — data analysis (pairs with data/DB MCPs such as Supabase). (Apache-2.0)\\n - type: git\\n name: jupyter-notebook\\n url: https://github.com/openai/skills\\n path: skills/.curated/jupyter-notebook\\n ref: main\\n description: Perform data analysis in Jupyter notebooks — load data, compute, and visualize results.\\n\" as const;\n","/** Serves the built frontend, so one container answers both the UI and the API. */\nimport { serveStatic } from '@hono/node-server/serve-static';\nimport type { OpenAPIHono } from '@hono/zod-openapi';\nimport type { MiddlewareHandler } from 'hono';\nimport { every } from 'hono/combine';\nimport { compress } from 'hono/compress';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\n\n/** Routes the server answers itself; never served from the build. /api covers every version below it. */\nconst SERVER_PATH_PREFIXES = ['/api', '/healthz'];\n\n/** Only Vite's hashed asset names can be cached forever. */\nconst HASHED_ASSET_PREFIX = '/assets/';\nconst IMMUTABLE_CACHE_CONTROL = 'public, max-age=31536000, immutable';\nconst REVALIDATE_CACHE_CONTROL = 'no-cache';\n\nfunction isServerPath(pathname: string): boolean {\n return SERVER_PATH_PREFIXES.some(prefix => pathname === prefix || pathname.startsWith(`${prefix}/`));\n}\n\n/**\n * Must be called after the API routes are registered, so those always win over the static handler.\n * Returns false when `dir` holds no build, leaving the server API-only for UI work behind Vite.\n */\nexport function mountFrontend(app: OpenAPIHono, dir: string): boolean {\n if (!existsSync(path.join(dir, 'index.html'))) {\n return false;\n }\n\n // serveStatic joins `root` with the request path, so an absolute dir is working-directory proof.\n const serveFile = serveStatic({ root: dir, precompressed: true });\n\n const serveWithCacheHeaders: MiddlewareHandler = async (c, next) => {\n const response = await serveFile(c, next);\n // Only when a file was served: a missing asset must not cache its 404.\n if (response instanceof Response) {\n const cacheControl = c.req.path.startsWith(HASHED_ASSET_PREFIX)\n ? IMMUTABLE_CACHE_CONTROL\n : REVALIDATE_CACHE_CONTROL;\n response.headers.set('Cache-Control', cacheControl);\n // compress() below encodes without advertising it, which a shared cache would get wrong.\n response.headers.set('Vary', 'Accept-Encoding');\n }\n return response;\n };\n\n /**\n * compress() skips responses that already carry Content-Encoding, so it only reaches what the build\n * could not precompress: the Monaco workers. It stays behind the isServerPath guard below because\n * compressing an API response would buffer the SSE streams that must flush per event.\n */\n const serveCompressed = every(compress(), serveWithCacheHeaders);\n\n const serveBuild: MiddlewareHandler = async (c, next) => {\n if (isServerPath(c.req.path)) {\n return next();\n }\n if (c.req.method !== 'GET' && c.req.method !== 'HEAD') {\n return next();\n }\n return serveCompressed(c, next);\n };\n\n const serveAppShell = serveStatic({ root: dir, rewriteRequestPath: () => '/index.html', precompressed: true });\n\n /**\n * Client routes (`/sessions/{id}`, `/settings`) have no file on disk, so a\n * deep link only reaches the app when the shell answers the navigation.\n * Runs after `serveBuild`, so real files still win; requests that do not\n * accept HTML keep their 404 rather than getting the shell as a fake asset.\n */\n const serveSpaFallback: MiddlewareHandler = async (c, next) => {\n if (isServerPath(c.req.path)) {\n return next();\n }\n if (c.req.method !== 'GET' && c.req.method !== 'HEAD') {\n return next();\n }\n if (c.req.header('accept')?.includes('text/html') !== true) {\n return next();\n }\n\n const response = await serveAppShell(c, next);\n if (response instanceof Response) {\n response.headers.set('Cache-Control', REVALIDATE_CACHE_CONTROL);\n response.headers.set('Vary', 'Accept-Encoding');\n }\n return response;\n };\n\n app.use('/*', serveBuild);\n app.use('/*', serveSpaFallback);\n\n return true;\n}\n","/**\n * Process logger: human-readable lines in standalone mode, JSON otherwise.\n * Both formats include `version` (defaultMeta) so hosted aggregators can filter.\n */\nimport winston, { type Logger } from 'winston';\n\nconst STANDALONE_META_SKIP = new Set(['level', 'message', 'timestamp', 'version', 'stack', 'splat']);\n\nexport function shouldColorize(): boolean {\n const noColor = process.env['NO_COLOR'];\n if (noColor !== undefined && noColor !== '') {\n return false;\n }\n const forceColor = process.env['FORCE_COLOR'];\n if (forceColor === '0') {\n return false;\n }\n if (forceColor !== undefined && forceColor !== '') {\n return true;\n }\n return process.stderr.isTTY;\n}\n\nfunction standaloneMeta(info: object): string {\n const copied: Record<string, unknown> = { ...info };\n const meta: Record<string, unknown> = {};\n for (const key of Object.keys(copied)) {\n if (STANDALONE_META_SKIP.has(key)) {\n continue;\n }\n meta[key] = copied[key];\n }\n if (Object.keys(meta).length === 0) {\n return '';\n }\n return ` ${JSON.stringify(meta)}`;\n}\n\nfunction standaloneFormat(color: boolean): winston.Logform.Format {\n const parts: winston.Logform.Format[] = [\n winston.format.timestamp({ format: 'HH:mm:ss' }),\n winston.format.errors({ stack: true }),\n ];\n if (color) {\n parts.push(winston.format.colorize({ level: true }));\n }\n parts.push(\n winston.format.printf(info => {\n const extra = standaloneMeta(info);\n const stack = typeof info['stack'] === 'string' ? `\\n${info['stack']}` : '';\n return `${String(info['timestamp'])} ${info.level} ${String(info.message)}${extra}${stack}`;\n }),\n );\n return winston.format.combine(...parts);\n}\n\nfunction jsonFormat(): winston.Logform.Format {\n return winston.format.combine(\n winston.format.timestamp(),\n winston.format.errors({ stack: true }),\n winston.format.json(),\n );\n}\n\nfunction serverLogFormat(options: { standalone: boolean }): winston.Logform.Format {\n if (options.standalone) {\n return standaloneFormat(shouldColorize());\n }\n return jsonFormat();\n}\n\nexport function createServerLogger(options: { level: string; standalone: boolean; version: string }): Logger {\n return winston.createLogger({\n level: options.level,\n defaultMeta: { version: options.version },\n format: serverLogFormat({ standalone: options.standalone }),\n transports: [new winston.transports.Console()],\n });\n}\n","/**\n * In-memory registry of turns executing in this process. Keys are\n * `${sessionId}:${turnId}`. Cancel aborts via AbortController;\n * TurnHandle.stream() writes the terminal state when the signal fires.\n * `track()` owns registration and cleanup around the stream lifecycle.\n */\nimport { CancellationReason } from '@truefoundry/trueforge-core/agent-session';\n\ninterface ActiveTurnRun {\n abortController: AbortController;\n waitUntilCompleted: Promise<void>;\n markCompleted: () => void;\n}\n\nfunction activeTurnKey(sessionId: string, turnId: string): string {\n return `${sessionId}:${turnId}`;\n}\n\nexport class ActiveTurnRegistry {\n private readonly runs = new Map<string, ActiveTurnRun>();\n private alreadyShutDownAbortReason: CancellationReason | undefined;\n\n /**\n * Registers the run immediately, then returns a generator that forwards\n * `stream` and removes the run when the stream completes (or the consumer\n * exits early). If shutdown has already begun, aborts the controller with\n * the shutdown reason so the turn ends as abandoned.\n */\n track<T>(input: {\n sessionId: string;\n turnId: string;\n abortController: AbortController;\n stream: AsyncIterable<T>;\n }): AsyncGenerator<T> {\n const key = activeTurnKey(input.sessionId, input.turnId);\n const { promise: waitUntilCompleted, resolve } = Promise.withResolvers<undefined>();\n const markCompleted = (): void => {\n resolve(undefined);\n };\n const run: ActiveTurnRun = {\n abortController: input.abortController,\n waitUntilCompleted,\n markCompleted,\n };\n this.runs.set(key, run);\n\n // Accepted HTTP may still call track() after shutdownAndWait snapshotted;\n // abort immediately so the turn ends as abandoned instead of running past exit.\n if (this.alreadyShutDownAbortReason !== undefined) {\n if (!input.abortController.signal.aborted) {\n input.abortController.abort(this.alreadyShutDownAbortReason);\n }\n }\n\n const complete = () => {\n run.markCompleted();\n if (this.runs.get(key) === run) {\n this.runs.delete(key);\n }\n };\n async function* tracked(): AsyncGenerator<T> {\n try {\n yield* input.stream;\n } finally {\n complete();\n }\n }\n return tracked();\n }\n\n /**\n * Aborts the given turn if it is running in this process. Returns true when\n * the run was found (already-aborted runs are not re-aborted). Cancelling a\n * turn that is not running is a no-op, mirroring the store's\n * first-terminal-write-wins rule.\n */\n cancelIfRunning(input: { sessionId: string; turnId: string; abortReason: CancellationReason }): boolean {\n const run = this.runs.get(activeTurnKey(input.sessionId, input.turnId));\n if (!run) {\n return false;\n }\n if (!run.abortController.signal.aborted) {\n run.abortController.abort(input.abortReason);\n }\n return true;\n }\n\n /**\n * Enter shutdown mode, abort every run with `abortReason`, and wait until the\n * registry is empty. Late `track()` calls (in-flight HTTP that registered after\n * the first snapshot) are aborted immediately as `abortReason` and included in\n * subsequent wait iterations.\n */\n async shutdownAndWait(abortReason: CancellationReason): Promise<void> {\n this.alreadyShutDownAbortReason = abortReason;\n while (this.runs.size > 0) {\n const pending = Array.from(this.runs.values());\n for (const run of pending) {\n if (!run.abortController.signal.aborted) {\n run.abortController.abort(abortReason);\n }\n }\n await Promise.allSettled(pending.map(run => run.waitUntilCompleted));\n }\n }\n}\n","/**\n * Standalone boot chrome: wordmark, version, and a boxed local-only warning.\n * Printed raw (not through winston) so the art is not prefixed with timestamps.\n */\n\nconst STANDALONE_MODE_DISCLAIMER =\n 'Standalone mode is intended for local use on your own machine. It is not hardened for production or shared internet access — please keep it on localhost. We cannot take responsibility for data loss or unauthorized access if this mode is used beyond that.';\n\n/** ANSI Shadow glyphs used to render `TRUEFORGE`. Each letter is six equal-width rows. */\nconst ANSI_SHADOW: Record<string, readonly string[]> = {\n T: ['████████╗', '╚══██╔══╝', ' ██║ ', ' ██║ ', ' ██║ ', ' ╚═╝ '],\n R: ['██████╗ ', '██╔══██╗', '██████╔╝', '██╔══██╗', '██║ ██║', '╚═╝ ╚═╝'],\n U: ['██╗ ██╗', '██║ ██║', '██║ ██║', '██║ ██║', '╚██████╔╝', ' ╚═════╝ '],\n E: ['███████╗', '██╔════╝', '█████╗ ', '██╔══╝ ', '███████╗', '╚══════╝'],\n F: ['███████╗', '██╔════╝', '█████╗ ', '██╔══╝ ', '██║ ', '╚═╝ '],\n O: [' ██████╗ ', '██╔═══██╗', '██║ ██║', '██║ ██║', '╚██████╔╝', ' ╚═════╝ '],\n G: [' ██████╗ ', '██╔════╝ ', '██║ ███╗', '██║ ██║', '╚██████╔╝', ' ╚═════╝ '],\n};\n\nconst WORDMARK_TEXT = 'TRUEFORGE';\nconst WARNING_INNER_WIDTH = 72;\nconst BRAND_COLOR = '\\x1b[38;5;99m';\nconst YELLOW = '\\x1b[33m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\n\nfunction glyphFor(ch: string): readonly string[] {\n const glyph = ANSI_SHADOW[ch];\n if (glyph === undefined) {\n throw new Error(`No ASCII glyph for ${JSON.stringify(ch)}`);\n }\n return glyph;\n}\n\nfunction rowOf(glyph: readonly string[], row: number): string {\n const cell = glyph[row];\n if (cell === undefined) {\n throw new Error(`Glyph is missing row ${String(row)}`);\n }\n return cell;\n}\n\nfunction renderTrueForgeWordmark(): string {\n const glyphs: (readonly string[])[] = [];\n for (let i = 0; i < WORDMARK_TEXT.length; i += 1) {\n const ch = WORDMARK_TEXT[i];\n if (ch === undefined) {\n throw new Error(`Missing character at index ${String(i)}`);\n }\n glyphs.push(glyphFor(ch));\n }\n const rowCount = glyphs[0]?.length;\n if (rowCount === undefined) {\n throw new Error('Wordmark text must not be empty');\n }\n const rows: string[] = [];\n for (let row = 0; row < rowCount; row += 1) {\n rows.push(glyphs.map(glyph => rowOf(glyph, row)).join(''));\n }\n return rows.join('\\n');\n}\n\nfunction wrapText(text: string, width: number): string[] {\n const words = text.split(/\\s+/).filter(word => word.length > 0);\n const lines: string[] = [];\n let current = '';\n for (const word of words) {\n if (current.length === 0) {\n if (word.length > width) {\n lines.push(word);\n } else {\n current = word;\n }\n continue;\n }\n const next = `${current} ${word}`;\n if (next.length <= width) {\n current = next;\n } else {\n lines.push(current);\n current = word.length > width ? '' : word;\n if (word.length > width) {\n lines.push(word);\n }\n }\n }\n if (current.length > 0) {\n lines.push(current);\n }\n return lines;\n}\n\nfunction paint(options: { text: string; color: string; enabled: boolean }): string {\n if (!options.enabled) {\n return options.text;\n }\n return `${options.color}${options.text}${RESET}`;\n}\n\nfunction warningBox(message: string): string {\n const label = ' WARNING ';\n const inner = wrapText(message, WARNING_INNER_WIDTH);\n const width = Math.max(WARNING_INNER_WIDTH, ...inner.map(line => line.length), label.length);\n const topPad = width + 1 - label.length;\n const top = `┌─${label}${'─'.repeat(topPad)}┐`;\n const body = inner.map(line => `│ ${line.padEnd(width)} │`);\n const bottom = `└${'─'.repeat(width + 2)}┘`;\n return [top, ...body, bottom].join('\\n');\n}\n\nfunction formatStandaloneStartupBanner(options: { version: string; color: boolean }): {\n wordmark: string;\n warning: string;\n} {\n const { version, color } = options;\n const wordmark = paint({ text: renderTrueForgeWordmark(), color: `${BOLD}${BRAND_COLOR}`, enabled: color });\n const subtitle = paint({ text: ` TrueForge v${version} · standalone`, color: DIM, enabled: color });\n const warning = paint({ text: warningBox(STANDALONE_MODE_DISCLAIMER), color: `${BOLD}${YELLOW}`, enabled: color });\n return { wordmark: `\\n${wordmark}\\n${subtitle}\\n`, warning };\n}\n\nexport function printStandaloneStartupBanner(options: { version: string; color: boolean }): void {\n const { wordmark, warning } = formatStandaloneStartupBanner(options);\n console.log(wordmark);\n console.warn(warning);\n}\n"],"mappings":"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","names":["existsSync","port","z","existsSync","mkdir","rm","path","reply","realpathSync","mkdir","rm","dirname","isAbsolute","join","path","resolve","z","validateNoPathTraversal","execFile","existsSync","realpathSync","statSync","mkdir","rm","dirname","isAbsolute","join","resolve","promisify","ulid","execFileAsync","fs","path","path","init_sqlExpressions","SessionStoreConflictError","SessionStoreInvariantError","SessionStoreNotFoundError","TurnNotFoundError","sql","join","now","init_sqlExpressions","sql","now","SessionNotFoundError","TurnNotFoundError","sql","join","AgentSpecSchema","SessionNotFoundError","SessionStoreInvariantError","sql","isEmptyCustomRecord","now","sql","now","init_sqlExpressions","decodeOffsetPageToken","ulid","recordColumns","sql","sql","recordColumns","recordColumns","ulid","recordColumns","client_exports","isUniqueViolation","Kysely","init_client","fs","path","FileMigrationProvider","Migrator","extractErrorLogFields","sql","jsonbSet","path","init_sqlExpressions","sql","init_sqlExpressions","assertCreateTurnThreadDelta","PreviousTurnRunningError","SessionNotFoundError","SessionStoreConflictError","SessionStoreInvariantError","SessionStoreNotFoundError","TurnAlreadyExistsError","TurnNotFoundError","TurnNotRunningError","getEmptyCurrentContextUsage","sql","isEmptyCustomRecord","parseTurnCustom","terminalTurnState","classifyTurnFenceWriteFailure","classifyTurnThreadWriteFailure","assertTurnRunning","assembleTurnRecord","join","createTurn","now","isUniqueViolation","freezeAndGetTurn","getTurn","listTurns","updateTurnState","init_turns","init_client","init_sqlExpressions","sql","patchThreadCapabilityState","classifyTurnFenceWriteFailure","init_capabilities","init_sqlExpressions","init_turns","decodeOffsetPageToken","paginateOffsetRows","decodeSessionEventPageToken","paginateSessionEventRows","SessionNotFoundError","TurnNotFoundError","sql","appendToEvents","classifyTurnFenceWriteFailure","listTurnEvents","join","listSessionEvents","resolveAncestorChain","init_events","init_sqlExpressions","init_turns","decodeSessionListPageToken","paginateSessionListRows","SessionAlreadyExistsError","SessionNotFoundError","SessionStoreInvariantError","sql","isEmptyCustomRecord","parseSessionCustom","mapRowToSessionRecord","createSession","deleteSession","getSession","updateSession","listSessions","init_sessions","init_sqlExpressions","sql","addThreads","assertTurnRunning","now","removeThreads","classifyTurnFenceWriteFailure","completionPatchExpr","jsonbSet","usageSetExpr","fencedTurnThreadContextUpdate","classifyTurnThreadWriteFailure","appendToThreadContext","overwriteThreadContext","patchMCPServers","patchSandboxInfo","init_threads","init_sqlExpressions","init_turns","decodeOffsetPageToken","encodeOffsetPageToken","init_capabilities","init_events","init_sessions","init_threads","init_turns","createSession","deleteSession","getSession","updateSession","listSessions","createTurn","freezeAndGetTurn","getTurn","listTurns","updateTurnState","appendToEvents","addThreads","removeThreads","appendToThreadContext","overwriteThreadContext","patchMCPServers","patchSandboxInfo","patchThreadCapabilityState","listTurnEvents","listSessionEvents","toRecord","init_client","init_sqlExpressions","isUniqueViolation","ulid","toRecord","init_client","init_sqlExpressions","isUniqueViolation","savePendingAuthorization","consumePendingAuthorization","deletePendingAuthorizationsForServer","init_pendingAuthorization","init_sqlExpressions","sql","saveToken","getToken","getTokens","deleteToken","deleteTokensForServer","init_token","init_sqlExpressions","init_pendingAuthorization","init_token","savePendingAuthorization","consumePendingAuthorization","saveToken","getToken","getTokens","deleteToken","deleteTokensForServer","deletePendingAuthorizationsForServer","toRecord","init_client","init_sqlExpressions","isUniqueViolation","toRecord","init_sqlExpressions","ulid","toRecord","init_client","init_sqlExpressions","isUniqueViolation","extractErrorLogFields","mkdir","path","CancellationReason","OpenAPIHono","z","extractErrorLogFields","HTTPException","OpenAPIHono","z","z","AgentSpecSchema","z","AgentSpecSchema","z","z","join","McpConnectionError","McpConnectionError","z","z","z","join","ulid","z","createRoute","z","z","z","z","AgentSpecSchema","TokenPaginationSchema","z","AgentSpecSchema","TokenPaginationSchema","z","TokenPaginationSchema","TurnSchema","z","TokenPaginationSchema","z","createRoute","HTTPException","ulid","z","ulid","user","session","OpenAPIHono","OpenAPIHono","extractErrorLogFields","z","HTTPException","oidcVerify","HTTPException","createRoute","z","createRoute","OpenAPIHono","extractErrorLogFields","OpenAPIHono","extractErrorLogFields","createRoute","z","z","createRoute","OpenAPIHono","extractErrorLogFields","OpenAPIHono","SUPPORTED_REASONING_EFFORTS","createRoute","z","z","z","z","z","z","z","z","z","z","z","z","createRoute","SUPPORTED_REASONING_EFFORTS","OpenAPIHono","OpenAPIHono","extractErrorLogFields","McpConnectionError","createRoute","createRoute","McpConnectionError","extractErrorLogFields","OpenAPIHono","OpenAPIHono","extractErrorLogFields","McpConnectionError","createRoute","z","createRoute","z","extractErrorLogFields","McpConnectionError","OpenAPIHono","OpenAPIHono","createRoute","createRoute","OpenAPIHono","OpenAPIHono","OpenAPIHono","createRoute","createRoute","OpenAPIHono","OpenAPIHono","createRoute","createRoute","OpenAPIHono","OpenAPIHono","createRoute","createRoute","OpenAPIHono","OpenAPIHono","OpenAPIHono","CancellationReason","EventType","SessionStoreConflictError","SessionStoreNotFoundError","extractErrorLogFields","McpConnectionError","SandboxError","HTTPException","createRoute","z","z","createRoute","validateNoPathTraversal","path","path","HTTPException","EventType","SessionStoreNotFoundError","extractErrorLogFields","FORBIDDEN_SESSION_ACCESS","SessionStoreConflictError","SandboxError","McpConnectionError","CancellationReason","OpenAPIHono","path","fileURLToPath","PACKAGE_ROOT","z","z","HTTPException","extractErrorLogFields","OpenAPIHono","file","file","file","file","existsSync","path","resolve","configuration","isOidcConfigured","mkdir","path","createSqliteDb","migrateSqliteToLatest","SqliteSessionStore","SqliteModelProviderStore","SqliteMcpServerStore","SqliteOAuthTokenStore","SqliteSkillStore","SqliteSandboxProviderStore","SqliteAgentStore","createDb","migrateToLatest","connectRedis","PostgresSessionStore","PostgresModelProviderStore","PostgresMcpServerStore","PostgresOAuthTokenStore","PostgresSkillStore","PostgresSandboxProviderStore","PostgresAgentStore","LocalSandboxProvider","extractErrorLogFields","resolve","CancellationReason"]}