@lota-sdk/core 0.4.8 → 0.4.10

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 (272) hide show
  1. package/package.json +11 -12
  2. package/src/ai/embedding-cache.ts +96 -22
  3. package/src/ai-gateway/ai-gateway.ts +766 -223
  4. package/src/config/agent-defaults.ts +189 -75
  5. package/src/config/agent-types.ts +54 -4
  6. package/src/config/background-processing.ts +1 -1
  7. package/src/config/constants.ts +8 -2
  8. package/src/config/index.ts +0 -1
  9. package/src/config/logger.ts +299 -19
  10. package/src/config/thread-defaults.ts +40 -20
  11. package/src/create-runtime.ts +200 -449
  12. package/src/db/base.service.ts +52 -28
  13. package/src/db/cursor-pagination.ts +71 -30
  14. package/src/db/memory-query-builder.ts +2 -1
  15. package/src/db/memory-store.helpers.ts +4 -7
  16. package/src/db/memory-store.ts +868 -601
  17. package/src/db/memory.ts +396 -280
  18. package/src/db/record-id.ts +32 -10
  19. package/src/db/schema-fingerprint.ts +30 -12
  20. package/src/db/service-normalization.ts +288 -0
  21. package/src/db/service.ts +912 -779
  22. package/src/db/startup.ts +153 -68
  23. package/src/db/transaction-conflict.ts +15 -0
  24. package/src/effect/awaitable-effect.ts +96 -0
  25. package/src/effect/errors.ts +121 -0
  26. package/src/effect/helpers.ts +123 -0
  27. package/src/effect/index.ts +24 -0
  28. package/src/effect/layers.ts +238 -0
  29. package/src/effect/runtime-ref.ts +25 -0
  30. package/src/effect/runtime.ts +46 -0
  31. package/src/effect/services.ts +61 -0
  32. package/src/effect/zod.ts +43 -0
  33. package/src/embeddings/provider.ts +128 -83
  34. package/src/index.ts +48 -1
  35. package/src/openrouter/direct-provider.ts +11 -35
  36. package/src/queues/autonomous-job.queue.ts +117 -73
  37. package/src/queues/context-compaction.queue.ts +50 -17
  38. package/src/queues/delayed-node-promotion.queue.ts +46 -17
  39. package/src/queues/document-processor.queue.ts +52 -77
  40. package/src/queues/memory-consolidation.queue.ts +47 -32
  41. package/src/queues/organization-learning.queue.ts +26 -4
  42. package/src/queues/plan-agent-heartbeat.queue.ts +71 -24
  43. package/src/queues/plan-scheduler.queue.ts +97 -33
  44. package/src/queues/post-chat-memory.queue.ts +56 -26
  45. package/src/queues/queue-factory.ts +227 -59
  46. package/src/queues/standalone-worker.ts +39 -0
  47. package/src/queues/title-generation.queue.ts +45 -11
  48. package/src/redis/connection.ts +182 -113
  49. package/src/redis/index.ts +6 -8
  50. package/src/redis/org-memory-lock.ts +60 -27
  51. package/src/redis/redis-lease-lock.ts +200 -121
  52. package/src/redis/runtime-connection.ts +20 -0
  53. package/src/redis/stream-context.ts +92 -46
  54. package/src/runtime/agent-identity-overrides.ts +2 -2
  55. package/src/runtime/agent-runtime-policy.ts +5 -2
  56. package/src/runtime/agent-stream-helpers.ts +24 -9
  57. package/src/runtime/chat-run-orchestration.ts +102 -19
  58. package/src/runtime/chat-run-registry.ts +36 -2
  59. package/src/runtime/context-compaction/context-compaction-runtime.ts +107 -0
  60. package/src/runtime/{context-compaction.ts → context-compaction/context-compaction.ts} +161 -94
  61. package/src/runtime/domain-layer.ts +192 -0
  62. package/src/runtime/execution-plan-visibility.ts +2 -2
  63. package/src/runtime/execution-plan.ts +42 -15
  64. package/src/runtime/graph-designer.ts +16 -4
  65. package/src/runtime/helper-model.ts +139 -48
  66. package/src/runtime/index.ts +7 -8
  67. package/src/runtime/indexed-repositories-policy.ts +3 -3
  68. package/src/runtime/{memory-block.ts → memory/memory-block.ts} +50 -36
  69. package/src/runtime/{memory-digest-policy.ts → memory/memory-digest-policy.ts} +1 -1
  70. package/src/runtime/{memory-pipeline.ts → memory/memory-pipeline.ts} +54 -67
  71. package/src/runtime/{memory-prompts-fact.ts → memory/memory-prompts-fact.ts} +2 -2
  72. package/src/runtime/memory/memory-scope.ts +53 -0
  73. package/src/runtime/plugin-resolution.ts +124 -25
  74. package/src/runtime/plugin-types.ts +9 -1
  75. package/src/runtime/post-turn-side-effects.ts +177 -130
  76. package/src/runtime/retrieval-adapters.ts +40 -6
  77. package/src/runtime/runtime-accessors.ts +92 -0
  78. package/src/runtime/runtime-config.ts +150 -61
  79. package/src/runtime/runtime-extensions.ts +23 -25
  80. package/src/runtime/runtime-lifecycle.ts +124 -0
  81. package/src/runtime/runtime-services.ts +386 -0
  82. package/src/runtime/runtime-token.ts +47 -0
  83. package/src/runtime/social-chat/social-chat-agent-runner.ts +159 -0
  84. package/src/runtime/{social-chat-history.ts → social-chat/social-chat-history.ts} +51 -20
  85. package/src/runtime/social-chat/social-chat.ts +630 -0
  86. package/src/runtime/specialist-runner.ts +36 -10
  87. package/src/runtime/team-consultation/team-consultation-orchestrator.ts +433 -0
  88. package/src/runtime/{team-consultation-prompts.ts → team-consultation/team-consultation-prompts.ts} +6 -2
  89. package/src/runtime/thread-chat-helpers.ts +2 -2
  90. package/src/runtime/thread-plan-turn.ts +2 -1
  91. package/src/runtime/thread-turn-context.ts +183 -111
  92. package/src/runtime/turn-lifecycle.ts +93 -27
  93. package/src/services/agent-activity.service.ts +287 -203
  94. package/src/services/agent-executor.service.ts +253 -149
  95. package/src/services/artifact.service.ts +231 -149
  96. package/src/services/attachment.service.ts +171 -115
  97. package/src/services/autonomous-job.service.ts +890 -491
  98. package/src/services/background-work.service.ts +54 -0
  99. package/src/services/chat-run-registry.service.ts +13 -1
  100. package/src/services/context-compaction.service.ts +136 -86
  101. package/src/services/document-chunk.service.ts +151 -88
  102. package/src/services/execution-plan/execution-plan-approval.ts +26 -0
  103. package/src/services/execution-plan/execution-plan-context.ts +29 -0
  104. package/src/services/execution-plan/execution-plan-graph.ts +278 -0
  105. package/src/services/execution-plan/execution-plan-schedule.ts +84 -0
  106. package/src/services/execution-plan/execution-plan-spec.ts +75 -0
  107. package/src/services/execution-plan/execution-plan.service.ts +1041 -0
  108. package/src/services/feedback-loop.service.ts +132 -76
  109. package/src/services/global-orchestrator.service.ts +101 -168
  110. package/src/services/graph-full-routing.ts +193 -0
  111. package/src/services/index.ts +19 -21
  112. package/src/services/institutional-memory.service.ts +213 -125
  113. package/src/services/learned-skill.service.ts +368 -260
  114. package/src/services/memory/memory-conversation.ts +95 -0
  115. package/src/services/memory/memory-errors.ts +27 -0
  116. package/src/services/memory/memory-org-memory.ts +50 -0
  117. package/src/services/memory/memory-preseeded.ts +86 -0
  118. package/src/services/memory/memory-rerank.ts +297 -0
  119. package/src/services/{memory-utils.ts → memory/memory-utils.ts} +6 -5
  120. package/src/services/memory/memory.service.ts +674 -0
  121. package/src/services/memory/rerank.service.ts +201 -0
  122. package/src/services/monitoring-window.service.ts +92 -70
  123. package/src/services/mutating-approval.service.ts +62 -53
  124. package/src/services/node-workspace.service.ts +141 -98
  125. package/src/services/notification.service.ts +29 -16
  126. package/src/services/organization-member.service.ts +120 -66
  127. package/src/services/organization.service.ts +153 -77
  128. package/src/services/ownership-dispatcher.service.ts +456 -263
  129. package/src/services/plan/plan-agent-heartbeat.service.ts +234 -0
  130. package/src/services/plan/plan-agent-query.service.ts +322 -0
  131. package/src/services/{plan-approval.service.ts → plan/plan-approval.service.ts} +45 -22
  132. package/src/services/plan/plan-artifact.service.ts +60 -0
  133. package/src/services/plan/plan-builder.service.ts +76 -0
  134. package/src/services/plan/plan-checkpoint.service.ts +103 -0
  135. package/src/services/{plan-compiler.service.ts → plan/plan-compiler.service.ts} +26 -9
  136. package/src/services/plan/plan-completion-side-effects.ts +169 -0
  137. package/src/services/plan/plan-coordination.service.ts +181 -0
  138. package/src/services/plan/plan-cycle.service.ts +405 -0
  139. package/src/services/plan/plan-deadline.service.ts +533 -0
  140. package/src/services/plan/plan-event-delivery.service.ts +266 -0
  141. package/src/services/plan/plan-executor-context.ts +35 -0
  142. package/src/services/plan/plan-executor-graph.ts +522 -0
  143. package/src/services/plan/plan-executor-helpers.ts +307 -0
  144. package/src/services/plan/plan-executor-persistence.ts +209 -0
  145. package/src/services/plan/plan-executor.service.ts +1737 -0
  146. package/src/services/{plan-helpers.ts → plan/plan-helpers.ts} +1 -1
  147. package/src/services/{plan-run-data.ts → plan/plan-run-data.ts} +4 -4
  148. package/src/services/plan/plan-run-serialization.ts +15 -0
  149. package/src/services/plan/plan-run.service.ts +637 -0
  150. package/src/services/plan/plan-scheduler.service.ts +379 -0
  151. package/src/services/plan/plan-template.service.ts +224 -0
  152. package/src/services/plan/plan-transaction-events.ts +36 -0
  153. package/src/services/plan/plan-validator.service.ts +907 -0
  154. package/src/services/plan/plan-workspace.service.ts +131 -0
  155. package/src/services/plugin-executor.service.ts +102 -68
  156. package/src/services/quality-metrics.service.ts +112 -94
  157. package/src/services/queue-job.service.ts +288 -231
  158. package/src/services/recent-activity-title.service.ts +73 -36
  159. package/src/services/recent-activity.service.ts +274 -259
  160. package/src/services/skill-resolver.service.ts +38 -12
  161. package/src/services/social-chat-history.service.ts +190 -122
  162. package/src/services/system-executor.service.ts +96 -61
  163. package/src/services/thread/thread-active-run.ts +203 -0
  164. package/src/services/thread/thread-bootstrap.ts +385 -0
  165. package/src/services/thread/thread-listing.ts +199 -0
  166. package/src/services/thread/thread-memory-block.ts +130 -0
  167. package/src/services/thread/thread-message.service.ts +379 -0
  168. package/src/services/thread/thread-record-store.ts +155 -0
  169. package/src/services/thread/thread-title.service.ts +74 -0
  170. package/src/services/thread/thread-turn-execution.ts +280 -0
  171. package/src/services/thread/thread-turn-message-context.ts +73 -0
  172. package/src/services/thread/thread-turn-preparation.service.ts +1148 -0
  173. package/src/services/thread/thread-turn-streaming.ts +403 -0
  174. package/src/services/thread/thread-turn-tracing.ts +35 -0
  175. package/src/services/thread/thread-turn.ts +376 -0
  176. package/src/services/thread/thread.service.ts +344 -0
  177. package/src/services/user.service.ts +82 -32
  178. package/src/services/write-intent-validator.service.ts +63 -51
  179. package/src/storage/attachment-parser.ts +69 -27
  180. package/src/storage/attachment-storage.service.ts +334 -275
  181. package/src/storage/generated-document-storage.service.ts +66 -34
  182. package/src/system-agents/agent-result.ts +3 -1
  183. package/src/system-agents/context-compaction.agent.ts +3 -3
  184. package/src/system-agents/delegated-agent-factory.ts +159 -90
  185. package/src/system-agents/helper-agent-options.ts +1 -1
  186. package/src/system-agents/memory-reranker.agent.ts +3 -3
  187. package/src/system-agents/memory.agent.ts +3 -3
  188. package/src/system-agents/recent-activity-title-refiner.agent.ts +3 -3
  189. package/src/system-agents/regular-chat-memory-digest.agent.ts +3 -3
  190. package/src/system-agents/skill-extractor.agent.ts +3 -3
  191. package/src/system-agents/skill-manager.agent.ts +3 -3
  192. package/src/system-agents/thread-router.agent.ts +157 -113
  193. package/src/system-agents/title-generator.agent.ts +3 -3
  194. package/src/tools/execution-plan.tool.ts +241 -171
  195. package/src/tools/fetch-webpage.tool.ts +29 -18
  196. package/src/tools/firecrawl-client.ts +26 -6
  197. package/src/tools/index.ts +1 -0
  198. package/src/tools/memory-block.tool.ts +14 -6
  199. package/src/tools/plan-approval.tool.ts +57 -47
  200. package/src/tools/read-file-parts.tool.ts +44 -33
  201. package/src/tools/remember-memory.tool.ts +65 -45
  202. package/src/tools/search-web.tool.ts +33 -22
  203. package/src/tools/search.tool.ts +41 -29
  204. package/src/tools/team-think.tool.ts +125 -84
  205. package/src/tools/user-questions.tool.ts +4 -3
  206. package/src/tools/web-tool-shared.ts +6 -0
  207. package/src/utils/async.ts +25 -22
  208. package/src/utils/crypto.ts +21 -0
  209. package/src/utils/date-time.ts +40 -1
  210. package/src/utils/errors.ts +111 -20
  211. package/src/utils/hono-error-handler.ts +24 -39
  212. package/src/utils/index.ts +2 -1
  213. package/src/utils/null-proto-record.ts +41 -0
  214. package/src/utils/sse-keepalive.ts +124 -21
  215. package/src/workers/bootstrap.ts +164 -52
  216. package/src/workers/memory-consolidation.worker.ts +325 -237
  217. package/src/workers/organization-learning.worker.ts +50 -16
  218. package/src/workers/regular-chat-memory-digest.helpers.ts +28 -27
  219. package/src/workers/regular-chat-memory-digest.runner.ts +185 -114
  220. package/src/workers/skill-extraction.runner.ts +176 -93
  221. package/src/workers/utils/file-section-chunker.ts +8 -10
  222. package/src/workers/utils/repo-structure-extractor.ts +349 -260
  223. package/src/workers/utils/repomix-file-sections.ts +2 -2
  224. package/src/workers/utils/thread-message-query.ts +97 -38
  225. package/src/workers/worker-utils.ts +74 -31
  226. package/src/config/debug-logger.ts +0 -47
  227. package/src/config/search.ts +0 -3
  228. package/src/redis/connection-accessor.ts +0 -26
  229. package/src/runtime/agent-types.ts +0 -1
  230. package/src/runtime/context-compaction-runtime.ts +0 -87
  231. package/src/runtime/memory-scope.ts +0 -43
  232. package/src/runtime/social-chat-agent-runner.ts +0 -118
  233. package/src/runtime/social-chat.ts +0 -516
  234. package/src/runtime/team-consultation-orchestrator.ts +0 -272
  235. package/src/services/adaptive-playbook.service.ts +0 -152
  236. package/src/services/artifact-provenance.service.ts +0 -172
  237. package/src/services/chat-attachments.service.ts +0 -17
  238. package/src/services/context-compaction-runtime.singleton.ts +0 -13
  239. package/src/services/execution-plan.service.ts +0 -1118
  240. package/src/services/memory.service.ts +0 -914
  241. package/src/services/plan-agent-heartbeat.service.ts +0 -136
  242. package/src/services/plan-agent-query.service.ts +0 -267
  243. package/src/services/plan-artifact.service.ts +0 -50
  244. package/src/services/plan-builder.service.ts +0 -67
  245. package/src/services/plan-checkpoint.service.ts +0 -81
  246. package/src/services/plan-completion-side-effects.ts +0 -80
  247. package/src/services/plan-coordination.service.ts +0 -157
  248. package/src/services/plan-cycle.service.ts +0 -284
  249. package/src/services/plan-deadline.service.ts +0 -430
  250. package/src/services/plan-event-delivery.service.ts +0 -166
  251. package/src/services/plan-executor.service.ts +0 -1950
  252. package/src/services/plan-run.service.ts +0 -515
  253. package/src/services/plan-scheduler.service.ts +0 -240
  254. package/src/services/plan-template.service.ts +0 -177
  255. package/src/services/plan-validator.service.ts +0 -818
  256. package/src/services/plan-workspace.service.ts +0 -83
  257. package/src/services/rerank.service.ts +0 -156
  258. package/src/services/thread-message.service.ts +0 -275
  259. package/src/services/thread-plan-registry.service.ts +0 -22
  260. package/src/services/thread-title.service.ts +0 -39
  261. package/src/services/thread-turn-preparation.service.ts +0 -1147
  262. package/src/services/thread-turn.ts +0 -172
  263. package/src/services/thread.service.ts +0 -869
  264. package/src/utils/env.ts +0 -8
  265. /package/src/runtime/{context-compaction-constants.ts → context-compaction/context-compaction-constants.ts} +0 -0
  266. /package/src/runtime/{memory-format.ts → memory/memory-format.ts} +0 -0
  267. /package/src/runtime/{memory-prompts-parse.ts → memory/memory-prompts-parse.ts} +0 -0
  268. /package/src/runtime/{memory-prompts-update.ts → memory/memory-prompts-update.ts} +0 -0
  269. /package/src/runtime/{social-chat-prompts.ts → social-chat/social-chat-prompts.ts} +0 -0
  270. /package/src/services/{plan-node-spec.ts → plan/plan-node-spec.ts} +0 -0
  271. /package/src/services/{thread-constants.ts → thread/thread-constants.ts} +0 -0
  272. /package/src/services/{thread.types.ts → thread/thread.types.ts} +0 -0
@@ -1,219 +1,56 @@
1
- import type { ChatMessage } from '@lota-sdk/shared'
1
+ import { Effect, ManagedRuntime } from 'effect'
2
+ import type { Subscriber } from 'resumable-stream/ioredis'
2
3
 
3
- import { configureEmbeddingCache } from './ai/embedding-cache'
4
- import { configureAgentFactory, configureAgents } from './config/agent-defaults'
5
- import { configureLotaLogger } from './config/logger'
6
- import { configureThreads } from './config/thread-defaults'
7
- import { ensureRecordId } from './db/record-id'
8
4
  import { computeSchemaFingerprint } from './db/schema-fingerprint'
9
- import { LOTA_SDK_DATABASE_NAME } from './db/sdk-database'
10
- import type { SurrealDBService } from './db/service'
11
- import { SurrealDBService as SurrealDBServiceClass, setDatabaseService } from './db/service'
12
- import { publishDatabaseBootstrap } from './db/startup'
13
- import { TABLES } from './db/tables'
5
+ import { publishDatabaseBootstrapEffect } from './db/startup'
6
+ import {
7
+ buildInfrastructureLayer,
8
+ clearLotaSdkRuntime,
9
+ DatabaseServiceTag as EffectDatabaseService,
10
+ RedisServiceTag as EffectRedisService,
11
+ setLotaSdkRuntime,
12
+ } from './effect'
13
+ import { ConfigurationError, ServiceError } from './effect/errors'
14
+ import { effectTryPromise } from './effect/helpers'
14
15
  import type { RedisConnectionManager } from './redis/connection'
15
- import { createRedisConnectionManager } from './redis/connection'
16
- import { setRedisConnectionManager } from './redis/index'
17
- import { closeSharedSubscriber } from './redis/stream-context'
18
- import type { isApprovalContinuationRequest } from './runtime/approval-continuation'
19
- import { routeThreadChatMessages } from './runtime/chat-request-routing'
20
- import { configureGraphDesigner } from './runtime/graph-designer'
16
+ import { SharedThreadStreamSubscriberTag } from './redis/stream-context'
17
+ import { buildDomainServiceLayer } from './runtime/domain-layer'
21
18
  import type { LotaPlugin, SystemNodeExecutor } from './runtime/plugin-types'
22
- import { configureRuntimeConfig, LOTA_RUNTIME_ENV_KEYS, parseLotaRuntimeConfig } from './runtime/runtime-config'
19
+ import { clearRuntimeModuleAccessors, configureRuntimeModuleAccessors } from './runtime/runtime-accessors'
20
+ import { LOTA_RUNTIME_ENV_KEYS, loadLotaRuntimeConfigFromEnv, parseLotaRuntimeConfig } from './runtime/runtime-config'
23
21
  import type { LotaRuntimeConfig, ResolvedLotaRuntimeConfig } from './runtime/runtime-config'
24
- import { configureRuntimeExtensions } from './runtime/runtime-extensions'
22
+ import {
23
+ createPluginDatabaseConnector,
24
+ createPluginDatabaseDisconnector,
25
+ createRuntimeDisconnect,
26
+ } from './runtime/runtime-lifecycle'
27
+ import { buildRuntimeServiceSurface } from './runtime/runtime-services'
28
+ import type { LotaRuntimeLota, LotaRuntimeServices } from './runtime/runtime-services'
29
+ import { acquireRuntimeTokenEffect, isRuntimeTokenActive, releaseRuntimeToken } from './runtime/runtime-token'
25
30
  import type { LotaRuntimeWorkers } from './runtime/runtime-worker-registry'
26
31
  import { buildRuntimeWorkerRegistry } from './runtime/runtime-worker-registry'
27
- import type { LotaRuntimeSocialChat } from './runtime/social-chat'
28
- import { createSocialChatRuntime } from './runtime/social-chat'
29
- import type { agentActivityService } from './services/agent-activity.service'
30
- import { agentActivityService as agentActivityServiceSingleton } from './services/agent-activity.service'
31
- import type { artifactService } from './services/artifact.service'
32
- import { artifactService as artifactServiceSingleton } from './services/artifact.service'
33
- import type { attachmentService } from './services/attachment.service'
34
- import { attachmentService as attachmentServiceSingleton } from './services/attachment.service'
35
- import type { autonomousJobService } from './services/autonomous-job.service'
36
- import { autonomousJobService as autonomousJobServiceSingleton } from './services/autonomous-job.service'
37
- import type { documentChunkService } from './services/document-chunk.service'
38
- import { documentChunkService as documentChunkServiceSingleton } from './services/document-chunk.service'
39
- import type { executionPlanService } from './services/execution-plan.service'
40
- import { executionPlanService as executionPlanServiceSingleton } from './services/execution-plan.service'
41
- import type { memoryService } from './services/memory.service'
42
- import { memoryService as memoryServiceSingleton } from './services/memory.service'
43
- import type { verifyMutatingApproval } from './services/mutating-approval.service'
44
- import { verifyMutatingApproval as verifyMutatingApprovalSingleton } from './services/mutating-approval.service'
45
- import { configureNotificationService } from './services/notification.service'
46
- import type { organizationMemberService } from './services/organization-member.service'
47
- import { organizationMemberService as organizationMemberServiceSingleton } from './services/organization-member.service'
48
- import type { organizationService } from './services/organization.service'
49
- import { organizationService as organizationServiceSingleton } from './services/organization.service'
50
- import type { planAgentHeartbeatService } from './services/plan-agent-heartbeat.service'
51
- import { planAgentHeartbeatService as planAgentHeartbeatServiceSingleton } from './services/plan-agent-heartbeat.service'
52
- import type { planAgentQueryService } from './services/plan-agent-query.service'
53
- import { planAgentQueryService as planAgentQueryServiceSingleton } from './services/plan-agent-query.service'
54
- import type { planCoordinationService } from './services/plan-coordination.service'
55
- import { planCoordinationService as planCoordinationServiceSingleton } from './services/plan-coordination.service'
56
- import type { planCycleService } from './services/plan-cycle.service'
57
- import { planCycleService as planCycleServiceSingleton } from './services/plan-cycle.service'
58
- import type { planSchedulerService } from './services/plan-scheduler.service'
59
- import { planSchedulerService as planSchedulerServiceSingleton } from './services/plan-scheduler.service'
60
- import type { planTemplateService } from './services/plan-template.service'
61
- import { planTemplateService as planTemplateServiceSingleton } from './services/plan-template.service'
62
- import type { recentActivityTitleService } from './services/recent-activity-title.service'
63
- import { recentActivityTitleService as recentActivityTitleServiceSingleton } from './services/recent-activity-title.service'
64
- import type { recentActivityService } from './services/recent-activity.service'
65
- import { recentActivityService as recentActivityServiceSingleton } from './services/recent-activity.service'
66
- import type { rerankService } from './services/rerank.service'
67
- import { rerankService as rerankServiceSingleton } from './services/rerank.service'
68
- import {
69
- configureSocialChatHistory,
70
- socialChatHistoryService as socialChatHistoryServiceSingleton,
71
- } from './services/social-chat-history.service'
32
+ import type { LotaRuntimeSocialChat } from './runtime/social-chat/social-chat'
33
+ import { createSocialChatRuntime } from './runtime/social-chat/social-chat'
34
+ import { LearnedSkillServiceTag } from './services/learned-skill.service'
35
+ import { MemoryServiceTag } from './services/memory/memory.service'
36
+ import { SocialChatHistoryServiceTag } from './services/social-chat-history.service'
72
37
  import { getBuiltInSystemExecutors } from './services/system-executor.service'
73
- import type { threadMessageService } from './services/thread-message.service'
74
- import { threadMessageService as threadMessageServiceSingleton } from './services/thread-message.service'
75
- import type { threadTitleService } from './services/thread-title.service'
76
- import { threadTitleService as threadTitleServiceSingleton } from './services/thread-title.service'
77
- import type {
78
- createThreadApprovalContinuationStream,
79
- createThreadNativeToolApprovalStream,
80
- createThreadTurnStream,
81
- runThreadTurnInBackground,
82
- triggerPlanNodeTurn,
83
- } from './services/thread-turn'
84
- import {
85
- createThreadApprovalContinuationStream as createThreadApprovalContinuationStreamSingleton,
86
- createThreadNativeToolApprovalStream as createThreadNativeToolApprovalStreamSingleton,
87
- createThreadTurnStream as createThreadTurnStreamSingleton,
88
- isApprovalContinuationRequest as isApprovalContinuationRequestSingleton,
89
- runThreadTurnInBackground as runThreadTurnInBackgroundSingleton,
90
- triggerPlanNodeTurn as triggerPlanNodeTurnSingleton,
91
- } from './services/thread-turn'
92
- import type { threadService } from './services/thread.service'
93
- import { threadService as threadServiceSingleton } from './services/thread.service'
94
- import type { userService } from './services/user.service'
95
- import { userService as userServiceSingleton } from './services/user.service'
96
- import type { generatedDocumentStorageService } from './storage/generated-document-storage.service'
97
- import { generatedDocumentStorageService as generatedDocumentStorageServiceSingleton } from './storage/generated-document-storage.service'
98
-
99
- type ArchiveSdkThread = (
100
- threadId: Parameters<typeof threadServiceSingleton.updateStatus>[0],
101
- status?: 'archived',
102
- ) => ReturnType<typeof threadServiceSingleton.updateStatus>
103
-
104
- type UnarchiveSdkThread = (
105
- threadId: Parameters<typeof threadServiceSingleton.updateStatus>[0],
106
- status?: 'active',
107
- ) => ReturnType<typeof threadServiceSingleton.updateStatus>
108
-
109
- let activeRuntimeToken: symbol | null = null
110
-
111
- function claimRuntimeToken(): symbol {
112
- if (activeRuntimeToken) {
113
- throw new Error('createLotaRuntime() is process-scoped. Disconnect the active runtime before creating another one.')
114
- }
38
+ import { ThreadTurnServiceTag } from './services/thread/thread-turn'
115
39
 
116
- const token = Symbol('lota-runtime')
117
- activeRuntimeToken = token
118
- return token
119
- }
120
-
121
- function releaseRuntimeToken(token: symbol) {
122
- if (activeRuntimeToken === token) {
123
- activeRuntimeToken = null
124
- }
125
- }
40
+ // Re-exported for consumers that reason about the runtime slot without
41
+ // instantiating one (e.g., diagnostic harnesses).
42
+ export { isRuntimeTokenActive }
126
43
 
127
44
  export interface LotaRuntime {
128
- services: {
129
- database: SurrealDBService
130
- redis: RedisConnectionManager
131
- closeRedisConnection: () => Promise<void>
132
- agentActivityService: typeof agentActivityService
133
- artifactService: typeof artifactService
134
- attachmentService: typeof attachmentService
135
- autonomousJobService: typeof autonomousJobService
136
- documentChunkService: typeof documentChunkService
137
- generatedDocumentStorageService: typeof generatedDocumentStorageService
138
- memoryService: typeof memoryService
139
- rerankService: typeof rerankService
140
- verifyMutatingApproval: typeof verifyMutatingApproval
141
- organizationService: typeof organizationService
142
- organizationMemberService: typeof organizationMemberService
143
- userService: typeof userService
144
- recentActivityService: typeof recentActivityService
145
- recentActivityTitleService: typeof recentActivityTitleService
146
- socialChatHistoryService: typeof socialChatHistoryServiceSingleton
147
- executionPlanService: typeof executionPlanService
148
- planTemplateService: typeof planTemplateService
149
- planCoordinationService: typeof planCoordinationService
150
- planSchedulerService: typeof planSchedulerService
151
- planAgentHeartbeatService: typeof planAgentHeartbeatService
152
- planAgentQueryService: typeof planAgentQueryService
153
- planCycleService: typeof planCycleService
154
- threadMessageService: typeof threadMessageService
155
- threadService: typeof threadService
156
- threadTitleService: typeof threadTitleService
157
- createThreadApprovalContinuationStream: typeof createThreadApprovalContinuationStream
158
- createThreadNativeToolApprovalStream: typeof createThreadNativeToolApprovalStream
159
- createThreadTurnStream: typeof createThreadTurnStream
160
- isApprovalContinuationRequest: typeof isApprovalContinuationRequest
161
- runThreadTurnInBackground: typeof runThreadTurnInBackground
162
- triggerPlanNodeTurn: typeof triggerPlanNodeTurn
163
- }
164
- lota: {
165
- organizations: {
166
- create: typeof organizationServiceSingleton.createOrganization
167
- upsert: typeof organizationServiceSingleton.upsertOrganization
168
- get: typeof organizationServiceSingleton.getOrganization
169
- list: typeof organizationServiceSingleton.listOrganizations
170
- update: typeof organizationServiceSingleton.updateOrganization
171
- delete: typeof organizationServiceSingleton.deleteOrganization
172
- }
173
- users: {
174
- upsert: typeof userServiceSingleton.upsertUser
175
- get: typeof userServiceSingleton.getUser
176
- list: typeof userServiceSingleton.listUsers
177
- update: typeof userServiceSingleton.updateUser
178
- delete: typeof userServiceSingleton.deleteUser
179
- }
180
- memberships: {
181
- add: typeof organizationMemberServiceSingleton.addMembership
182
- listForOrganization: typeof organizationMemberServiceSingleton.listMembershipsForOrganization
183
- listForUser: typeof organizationMemberServiceSingleton.listMembershipsForUser
184
- remove: typeof organizationMemberServiceSingleton.removeMembership
185
- isMember: typeof organizationMemberServiceSingleton.isMember
186
- }
187
- threads: {
188
- create: typeof threadServiceSingleton.createThread
189
- list: typeof threadServiceSingleton.listThreads
190
- get: typeof threadServiceSingleton.getThread
191
- update: typeof threadServiceSingleton.updateTitle
192
- archive: ArchiveSdkThread
193
- unarchive: UnarchiveSdkThread
194
- delete: typeof threadServiceSingleton.deleteThread
195
- stop: typeof threadServiceSingleton.stopActiveRun
196
- listMessages: typeof threadMessageServiceSingleton.listMessageHistoryPage
197
- getMessage: (params: { threadId: string; messageId: string }) => Promise<ChatMessage>
198
- sendMessage: (params: {
199
- threadId: string
200
- organizationId: string
201
- userId: string
202
- userName: string
203
- messages: Parameters<typeof routeThreadChatMessages>[0]
204
- }) => Promise<Awaited<ReturnType<typeof createThreadTurnStream>>>
205
- continueApproval: (params: {
206
- threadId: string
207
- organizationId: string
208
- userId: string
209
- userName: string
210
- messages: Parameters<typeof routeThreadChatMessages>[0]
211
- }) => Promise<Awaited<ReturnType<typeof createThreadApprovalContinuationStream>>>
212
- uploadAttachment: typeof attachmentServiceSingleton.uploadThreadAttachment
213
- }
214
- }
45
+ /** Run an Effect as a Promise through the SDK runtime (carries OTLP context). */
46
+ runPromise: <A, E>(effect: Effect.Effect<A, E>, options?: { readonly signal?: AbortSignal }) => Promise<A>
47
+ /** Run an Effect synchronously through the SDK runtime. */
48
+ runSync: <A, E>(effect: Effect.Effect<A, E>) => A
49
+ services: LotaRuntimeServices
50
+ lota: LotaRuntimeLota
215
51
  redis: {
216
52
  manager: RedisConnectionManager
53
+ subscriber: Subscriber
217
54
  getConnection: () => ReturnType<RedisConnectionManager['getConnection']>
218
55
  getConnectionForBullMQ: () => ReturnType<RedisConnectionManager['getConnectionForBullMQ']>
219
56
  closeConnection: () => Promise<void>
@@ -230,253 +67,181 @@ export interface LotaRuntime {
230
67
  disconnect(): Promise<void>
231
68
  }
232
69
 
233
- export async function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntime> {
234
- const runtimeToken = claimRuntimeToken()
70
+ export function createLotaRuntimeFromEnv(
71
+ config: Parameters<typeof loadLotaRuntimeConfigFromEnv>[0],
72
+ options?: Parameters<typeof loadLotaRuntimeConfigFromEnv>[1],
73
+ ): Promise<LotaRuntime> {
74
+ return Effect.runPromise(loadLotaRuntimeConfigFromEnv(config, options)).then((resolvedConfig) =>
75
+ createLotaRuntime(resolvedConfig),
76
+ )
77
+ }
235
78
 
236
- try {
237
- const resolvedConfig = parseLotaRuntimeConfig(config)
238
- const systemExecutors = { ...getBuiltInSystemExecutors(), ...resolvedConfig.systemExecutors }
239
- const runtimeConfig = { ...resolvedConfig, systemExecutors } satisfies ResolvedLotaRuntimeConfig
240
- configureRuntimeConfig(runtimeConfig)
79
+ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntime> {
80
+ let runtimeToken: symbol | null = null
81
+ let effectRuntime: { dispose(): Promise<void> } | null = null
241
82
 
242
- await configureLotaLogger(runtimeConfig.logging.level)
83
+ return Effect.runPromise(
84
+ Effect.gen(function* () {
85
+ // Fail fast if another runtime is already active in this process.
86
+ runtimeToken = yield* acquireRuntimeTokenEffect()
243
87
 
244
- const db = new SurrealDBServiceClass({
245
- url: runtimeConfig.database.url,
246
- namespace: runtimeConfig.database.namespace,
247
- database: LOTA_SDK_DATABASE_NAME,
248
- username: runtimeConfig.database.username,
249
- password: runtimeConfig.database.password,
250
- })
251
- setDatabaseService(db)
88
+ const resolvedConfig = parseLotaRuntimeConfig(config)
89
+ const systemExecutors = { ...getBuiltInSystemExecutors(), ...resolvedConfig.systemExecutors }
90
+ const runtimeConfig = { ...resolvedConfig, systemExecutors } satisfies ResolvedLotaRuntimeConfig
252
91
 
253
- const redisManager = createRedisConnectionManager({ url: runtimeConfig.redis.url })
254
- setRedisConnectionManager(redisManager)
255
- configureEmbeddingCache(redisManager.getConnection(), runtimeConfig.memory.embeddingCacheTtlSeconds)
256
- configureSocialChatHistory({ keyPrefix: runtimeConfig.socialChat?.historyRedisKeyPrefix })
92
+ const socialChatAgentId = runtimeConfig.socialChat?.agentId?.trim() || 'socialChat'
93
+ const socialChatAgentDisplayName = runtimeConfig.socialChat?.agentDisplayName?.trim() || 'Lota'
94
+ if (runtimeConfig.socialChat && !runtimeConfig.agents.roster.includes(socialChatAgentId)) {
95
+ return yield* new ConfigurationError({
96
+ message: `socialChat.agentId must be present in agents.roster: ${socialChatAgentId}`,
97
+ key: 'socialChat.agentId',
98
+ })
99
+ }
100
+ const resolvedAgentDisplayNames = runtimeConfig.socialChat
101
+ ? { ...runtimeConfig.agents.displayNames, [socialChatAgentId]: socialChatAgentDisplayName }
102
+ : runtimeConfig.agents.displayNames
257
103
 
258
- const socialChatAgentId = runtimeConfig.socialChat?.agentId?.trim() || 'socialChat'
259
- const socialChatAgentDisplayName = runtimeConfig.socialChat?.agentDisplayName?.trim() || 'Lota'
260
- if (runtimeConfig.socialChat && !runtimeConfig.agents.roster.includes(socialChatAgentId)) {
261
- throw new Error(`socialChat.agentId must be present in agents.roster: ${socialChatAgentId}`)
262
- }
263
- const agentDisplayNames = runtimeConfig.socialChat
264
- ? { ...runtimeConfig.agents.displayNames, [socialChatAgentId]: socialChatAgentDisplayName }
265
- : runtimeConfig.agents.displayNames
104
+ // ── Infrastructure + domain layer composition ─────────────────────
105
+ const infrastructureLayer = buildInfrastructureLayer(runtimeConfig, { resolvedAgentDisplayNames })
106
+ const fullLayer = buildDomainServiceLayer(infrastructureLayer)
266
107
 
267
- configureAgents({
268
- roster: runtimeConfig.agents.roster,
269
- leadAgentId: runtimeConfig.agents.leadAgentId,
270
- displayNames: agentDisplayNames,
271
- shortDisplayNames: runtimeConfig.agents.shortDisplayNames,
272
- descriptions: runtimeConfig.agents.descriptions,
273
- routerModelId: runtimeConfig.agents.routerModelId,
274
- teamConsultParticipants: runtimeConfig.agents.teamConsultParticipants,
275
- getCoreThreadProfile: runtimeConfig.agents.getCoreThreadProfile,
276
- })
277
- configureAgentFactory({
278
- createAgent: runtimeConfig.agents.createAgent,
279
- buildAgentTools: runtimeConfig.agents.buildAgentTools,
280
- getAgentRuntimeConfig: runtimeConfig.agents.getAgentRuntimeConfig,
281
- pluginRuntime: runtimeConfig.pluginRuntime,
282
- })
283
- configureThreads({ agentRoster: runtimeConfig.agents.roster, config: runtimeConfig.threads })
284
- configureNotificationService(runtimeConfig.notificationService ?? null)
285
- configureRuntimeExtensions({
286
- adapters: runtimeConfig.runtimeAdapters,
287
- turnHooks: runtimeConfig.turnHooks,
288
- toolProviders: (runtimeConfig.toolProviders ?? {}) as never,
289
- extraWorkers: runtimeConfig.extraWorkers,
290
- })
108
+ const managedRuntime = ManagedRuntime.make(fullLayer)
109
+ effectRuntime = managedRuntime
291
110
 
292
- const pluginRuntime = runtimeConfig.pluginRuntime ?? {}
293
- if (runtimeConfig.graphDesigner) {
294
- configureGraphDesigner(runtimeConfig.graphDesigner)
295
- }
111
+ // Eagerly resolve the services the outer entrypoint needs directly.
112
+ const resolvedServices = yield* Effect.tryPromise({
113
+ try: () =>
114
+ managedRuntime.runPromise(
115
+ Effect.gen(function* () {
116
+ return {
117
+ db: yield* EffectDatabaseService,
118
+ redisManager: yield* EffectRedisService,
119
+ sharedSubscriber: yield* SharedThreadStreamSubscriberTag,
120
+ threadTurnService: yield* ThreadTurnServiceTag,
121
+ socialChatHistoryService: yield* SocialChatHistoryServiceTag,
122
+ learnedSkillService: yield* LearnedSkillServiceTag,
123
+ memoryService: yield* MemoryServiceTag,
124
+ }
125
+ }),
126
+ ),
127
+ catch: (error) =>
128
+ new ServiceError({
129
+ message: `Failed to initialize Effect runtime services: ${error instanceof Error ? error.message : String(error)}`,
130
+ cause: error,
131
+ }),
132
+ })
133
+ const {
134
+ db,
135
+ redisManager,
136
+ sharedSubscriber,
137
+ threadTurnService,
138
+ socialChatHistoryService,
139
+ learnedSkillService,
140
+ memoryService,
141
+ } = resolvedServices
296
142
 
297
- const pluginContributions = Object.values(pluginRuntime).map((plugin) => plugin.contributions)
298
- const hostContributionSchemaFiles = pluginContributions.flatMap((plugin) => plugin.schemaFiles)
299
- const schemaFiles = [
300
- ...getBuiltInSchemaFiles(),
301
- ...(runtimeConfig.extraSchemaFiles ?? []),
302
- ...hostContributionSchemaFiles,
303
- ]
304
- const contributionEnvKeys = [...LOTA_RUNTIME_ENV_KEYS, ...pluginContributions.flatMap((plugin) => plugin.envKeys)]
305
- const connectPluginDatabases = createPluginDatabaseConnector(pluginRuntime)
306
- const workers = buildRuntimeWorkerRegistry(runtimeConfig.extraWorkers)
307
- const socialChat = createSocialChatRuntime({
308
- redisClient: redisManager.getConnection(),
309
- socialChat: runtimeConfig.socialChat,
310
- })
143
+ setLotaSdkRuntime(managedRuntime)
144
+ configureRuntimeModuleAccessors({ managedRuntime, runtimeConfig, redisManager })
311
145
 
312
- const lota = {
313
- organizations: {
314
- create: organizationServiceSingleton.createOrganization.bind(organizationServiceSingleton),
315
- upsert: organizationServiceSingleton.upsertOrganization.bind(organizationServiceSingleton),
316
- get: organizationServiceSingleton.getOrganization.bind(organizationServiceSingleton),
317
- list: organizationServiceSingleton.listOrganizations.bind(organizationServiceSingleton),
318
- update: organizationServiceSingleton.updateOrganization.bind(organizationServiceSingleton),
319
- delete: organizationServiceSingleton.deleteOrganization.bind(organizationServiceSingleton),
320
- },
321
- users: {
322
- upsert: userServiceSingleton.upsertUser.bind(userServiceSingleton),
323
- get: userServiceSingleton.getUser.bind(userServiceSingleton),
324
- list: userServiceSingleton.listUsers.bind(userServiceSingleton),
325
- update: userServiceSingleton.updateUser.bind(userServiceSingleton),
326
- delete: userServiceSingleton.deleteUser.bind(userServiceSingleton),
327
- },
328
- memberships: {
329
- add: organizationMemberServiceSingleton.addMembership.bind(organizationMemberServiceSingleton),
330
- listForOrganization: organizationMemberServiceSingleton.listMembershipsForOrganization.bind(
331
- organizationMemberServiceSingleton,
332
- ),
333
- listForUser: organizationMemberServiceSingleton.listMembershipsForUser.bind(organizationMemberServiceSingleton),
334
- remove: organizationMemberServiceSingleton.removeMembership.bind(organizationMemberServiceSingleton),
335
- isMember: organizationMemberServiceSingleton.isMember.bind(organizationMemberServiceSingleton),
336
- },
337
- threads: {
338
- create: threadServiceSingleton.createThread.bind(threadServiceSingleton),
339
- list: threadServiceSingleton.listThreads.bind(threadServiceSingleton),
340
- get: threadServiceSingleton.getThread.bind(threadServiceSingleton),
341
- update: threadServiceSingleton.updateTitle.bind(threadServiceSingleton),
342
- archive: async (threadId, status = 'archived') => await threadServiceSingleton.updateStatus(threadId, status),
343
- unarchive: async (threadId, status = 'active') => await threadServiceSingleton.updateStatus(threadId, status),
344
- delete: threadServiceSingleton.deleteThread.bind(threadServiceSingleton),
345
- stop: threadServiceSingleton.stopActiveRun.bind(threadServiceSingleton),
346
- listMessages: threadMessageServiceSingleton.listMessageHistoryPage.bind(threadMessageServiceSingleton),
347
- getMessage: async ({ threadId, messageId }) => {
348
- const messages = await threadMessageServiceSingleton.listMessages(ensureRecordId(threadId, TABLES.THREAD))
349
- const message = messages.find((candidate) => candidate.id === messageId)
350
- if (!message) {
351
- throw new Error(`Thread message not found: ${messageId}`)
352
- }
353
- return message
354
- },
355
- sendMessage: async ({ threadId, organizationId, userId, userName, messages }) => {
356
- const threadRef = ensureRecordId(threadId, TABLES.THREAD)
357
- const thread = await threadServiceSingleton.getThread(threadRef)
358
- const routed = routeThreadChatMessages(messages)
359
- if (routed.kind !== 'turn') {
360
- throw new Error(routed.kind === 'invalid' ? routed.message : 'Expected a user turn payload.')
361
- }
146
+ // ── Schema + plugin + worker + social-chat composition ────────────
147
+ const pluginRuntime = runtimeConfig.pluginRuntime ?? {}
148
+ const pluginContributions = Object.values(pluginRuntime).map((plugin) => plugin.contributions)
149
+ const hostContributionSchemaFiles = pluginContributions.flatMap((plugin) => plugin.schemaFiles)
150
+ const schemaFiles = [
151
+ ...getBuiltInSchemaFiles(),
152
+ ...(runtimeConfig.extraSchemaFiles ?? []),
153
+ ...hostContributionSchemaFiles,
154
+ ]
155
+ const contributionEnvKeys = [...LOTA_RUNTIME_ENV_KEYS, ...pluginContributions.flatMap((plugin) => plugin.envKeys)]
156
+ const connectedPluginDatabases = new Set<string>()
157
+ const connectPluginDatabases = createPluginDatabaseConnector(
158
+ managedRuntime,
159
+ pluginRuntime,
160
+ connectedPluginDatabases,
161
+ )
162
+ const disconnectPluginDatabases = createPluginDatabaseDisconnector(
163
+ managedRuntime,
164
+ pluginRuntime,
165
+ connectedPluginDatabases,
166
+ )
167
+ const workers = buildRuntimeWorkerRegistry(runtimeConfig.extraWorkers)
168
+ const socialChat = createSocialChatRuntime({
169
+ redisClient: redisManager.getConnection() as unknown as Parameters<
170
+ typeof createSocialChatRuntime
171
+ >[0]['redisClient'],
172
+ socialChat: runtimeConfig.socialChat,
173
+ services: { learnedSkillService, memoryService, socialChatHistoryService },
174
+ })
175
+ const currentContext = yield* Effect.context()
176
+ const runPromiseWithCurrentContext = Effect.runPromiseWith(currentContext)
362
177
 
363
- return createThreadTurnStreamSingleton({
364
- thread,
365
- threadRef,
366
- orgRef: ensureRecordId(organizationId, TABLES.ORGANIZATION),
367
- userRef: ensureRecordId(userId, TABLES.USER),
368
- userName,
369
- inputMessage: routed.inputMessage,
370
- })
371
- },
372
- continueApproval: async ({ threadId, organizationId, userId, userName, messages }) => {
373
- const threadRef = ensureRecordId(threadId, TABLES.THREAD)
374
- const thread = await threadServiceSingleton.getThread(threadRef)
375
- const routed = routeThreadChatMessages(messages)
376
- if (routed.kind !== 'approval-continuation') {
377
- throw new Error(
378
- routed.kind === 'invalid' ? routed.message : 'Expected approval continuation messages payload.',
379
- )
380
- }
178
+ // ── Service surface (eager, plain-property) ───────────────────────
179
+ const { services, lota } = buildRuntimeServiceSurface({
180
+ managedRuntime,
181
+ db,
182
+ redisManager,
183
+ sharedSubscriber,
184
+ threadTurnService,
185
+ socialChatHistoryService,
186
+ })
381
187
 
382
- return createThreadApprovalContinuationStreamSingleton({
383
- thread,
384
- threadRef,
385
- orgRef: ensureRecordId(organizationId, TABLES.ORGANIZATION),
386
- userRef: ensureRecordId(userId, TABLES.USER),
387
- userName,
388
- approvalMessages: routed.approvalMessages,
389
- })
188
+ const disconnect = createRuntimeDisconnect({
189
+ managedRuntime,
190
+ runPromiseWithCurrentContext,
191
+ socialChatShutdown: () => socialChat.shutdown(),
192
+ disconnectPluginDatabases,
193
+ onFinalize: () => {
194
+ clearRuntimeModuleAccessors()
195
+ clearLotaSdkRuntime()
196
+ if (runtimeToken) releaseRuntimeToken(runtimeToken)
390
197
  },
391
- uploadAttachment: attachmentServiceSingleton.uploadThreadAttachment.bind(attachmentServiceSingleton),
392
- },
393
- } satisfies LotaRuntime['lota']
394
-
395
- let disconnected = false
396
-
397
- return {
398
- services: {
399
- database: db,
400
- redis: redisManager,
401
- closeRedisConnection: async () => await redisManager.closeConnection(),
402
- agentActivityService: agentActivityServiceSingleton,
403
- artifactService: artifactServiceSingleton,
404
- attachmentService: attachmentServiceSingleton,
405
- autonomousJobService: autonomousJobServiceSingleton,
406
- documentChunkService: documentChunkServiceSingleton,
407
- generatedDocumentStorageService: generatedDocumentStorageServiceSingleton,
408
- memoryService: memoryServiceSingleton,
409
- rerankService: rerankServiceSingleton,
410
- verifyMutatingApproval: verifyMutatingApprovalSingleton,
411
- organizationService: organizationServiceSingleton,
412
- organizationMemberService: organizationMemberServiceSingleton,
413
- userService: userServiceSingleton,
414
- recentActivityService: recentActivityServiceSingleton,
415
- recentActivityTitleService: recentActivityTitleServiceSingleton,
416
- socialChatHistoryService: socialChatHistoryServiceSingleton,
417
- executionPlanService: executionPlanServiceSingleton,
418
- planTemplateService: planTemplateServiceSingleton,
419
- planCoordinationService: planCoordinationServiceSingleton,
420
- planSchedulerService: planSchedulerServiceSingleton,
421
- planAgentHeartbeatService: planAgentHeartbeatServiceSingleton,
422
- planAgentQueryService: planAgentQueryServiceSingleton,
423
- planCycleService: planCycleServiceSingleton,
424
- threadMessageService: threadMessageServiceSingleton,
425
- threadService: threadServiceSingleton,
426
- threadTitleService: threadTitleServiceSingleton,
427
- createThreadApprovalContinuationStream: createThreadApprovalContinuationStreamSingleton,
428
- createThreadNativeToolApprovalStream: createThreadNativeToolApprovalStreamSingleton,
429
- createThreadTurnStream: createThreadTurnStreamSingleton,
430
- isApprovalContinuationRequest: isApprovalContinuationRequestSingleton,
431
- runThreadTurnInBackground: runThreadTurnInBackgroundSingleton,
432
- triggerPlanNodeTurn: triggerPlanNodeTurnSingleton,
433
- },
434
- lota,
435
- redis: {
436
- manager: redisManager,
437
- getConnection: () => redisManager.getConnection(),
438
- getConnectionForBullMQ: () => redisManager.getConnectionForBullMQ(),
439
- closeConnection: async () => await redisManager.closeConnection(),
440
- },
441
- workers,
442
- socialChat,
443
- schemaFiles,
444
- contributions: { envKeys: [...new Set(contributionEnvKeys)], schemaFiles: hostContributionSchemaFiles },
445
- config: runtimeConfig,
446
- plugins: pluginRuntime,
447
- systemExecutors,
448
- async connectPluginDatabases() {
449
- await connectPluginDatabases()
450
- },
451
- async connect() {
452
- await db.connect()
453
- const bunFiles = schemaFiles.map((schemaFile) =>
454
- schemaFile instanceof URL ? Bun.file(schemaFile.pathname) : Bun.file(schemaFile),
455
- )
456
- await db.applySchema(bunFiles)
457
- const schemaFingerprint = await computeSchemaFingerprint(schemaFiles)
458
- await publishDatabaseBootstrap({ databaseService: db, schemaFingerprint })
459
- },
460
- async disconnect() {
461
- if (disconnected) {
462
- return
463
- }
464
- disconnected = true
198
+ })
465
199
 
466
- try {
467
- await socialChat.shutdown()
468
- await closeSharedSubscriber()
469
- await db.disconnect()
470
- await redisManager.closeConnection()
471
- } finally {
472
- releaseRuntimeToken(runtimeToken)
473
- }
474
- },
200
+ const lotaRuntime: LotaRuntime = {
201
+ runPromise: (effect, options) => managedRuntime.runPromise(effect, options),
202
+ runSync: (effect) => managedRuntime.runSync(effect),
203
+ services,
204
+ lota,
205
+ redis: {
206
+ manager: redisManager,
207
+ subscriber: sharedSubscriber.subscriber,
208
+ getConnection: () => redisManager.getConnection(),
209
+ getConnectionForBullMQ: () => redisManager.getConnectionForBullMQ(),
210
+ closeConnection: () => managedRuntime.runPromise(effectTryPromise(() => redisManager.closeConnection())),
211
+ },
212
+ workers,
213
+ socialChat,
214
+ schemaFiles,
215
+ contributions: { envKeys: [...new Set(contributionEnvKeys)], schemaFiles: hostContributionSchemaFiles },
216
+ config: runtimeConfig,
217
+ plugins: pluginRuntime,
218
+ systemExecutors,
219
+ connectPluginDatabases,
220
+ connect: () =>
221
+ managedRuntime.runPromise(
222
+ Effect.gen(function* () {
223
+ yield* db.connect()
224
+ const bunFiles = schemaFiles.map((schemaFile) =>
225
+ schemaFile instanceof URL ? Bun.file(schemaFile.pathname) : Bun.file(schemaFile),
226
+ )
227
+ yield* db.applySchema(bunFiles)
228
+ const schemaFingerprint = yield* effectTryPromise(() => computeSchemaFingerprint(schemaFiles))
229
+ yield* publishDatabaseBootstrapEffect({ databaseService: db, schemaFingerprint })
230
+ }),
231
+ ),
232
+ disconnect,
233
+ }
234
+ return lotaRuntime
235
+ }),
236
+ ).catch((error) => {
237
+ if (effectRuntime) {
238
+ clearRuntimeModuleAccessors()
239
+ clearLotaSdkRuntime()
240
+ void effectRuntime.dispose().catch(() => undefined)
475
241
  }
476
- } catch (error) {
477
- releaseRuntimeToken(runtimeToken)
242
+ if (runtimeToken) releaseRuntimeToken(runtimeToken)
478
243
  throw error
479
- }
244
+ })
480
245
  }
481
246
 
482
247
  function getBuiltInSchemaFiles(): URL[] {
@@ -495,17 +260,3 @@ function getBuiltInSchemaFiles(): URL[] {
495
260
  new URL('../infrastructure/schema/10_autonomous_job.surql', import.meta.url),
496
261
  ]
497
262
  }
498
-
499
- function createPluginDatabaseConnector(pluginRuntime: Record<string, LotaPlugin>): () => Promise<void> {
500
- return async () => {
501
- for (const plugin of Object.values(pluginRuntime)) {
502
- const services = plugin.services
503
- const connectDatabase = services.connectDatabase
504
- if (typeof connectDatabase !== 'function') {
505
- continue
506
- }
507
-
508
- await Reflect.apply(connectDatabase, services, [])
509
- }
510
- }
511
- }