@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
@@ -0,0 +1,266 @@
1
+ import type { PlanEventRecord } from '@lota-sdk/shared'
2
+ import { Context, Schema, Effect, Layer } from 'effect'
3
+
4
+ import { ensureRecordId, recordIdToString } from '../../db/record-id'
5
+ import type { SurrealDBService } from '../../db/service'
6
+ import { TABLES } from '../../db/tables'
7
+ import { runPromise } from '../../effect/runtime'
8
+ import { DatabaseServiceTag, RedisServiceTag } from '../../effect/services'
9
+ import type { RedisConnectionManager } from '../../redis/connection'
10
+ import { resolvePlanNodeExecutionVisibility } from '../../runtime/execution-plan-visibility'
11
+ import { getRuntimeAdapters } from '../../runtime/runtime-extensions'
12
+ import type { LotaRuntimePlanEventEnvelope } from '../../runtime/runtime-extensions'
13
+ import { getErrorMessage } from '../../utils/errors'
14
+ import { ThreadSchema } from '../thread/thread.types'
15
+ import type { makeUserService } from '../user.service'
16
+ import { UserServiceTag } from '../user.service'
17
+ import type { makePlanRunService } from './plan-run.service'
18
+ import { PlanRunServiceTag } from './plan-run.service'
19
+
20
+ const PLAN_EVENT_DELIVERED_TTL_MS = 7 * 24 * 60 * 60 * 1000
21
+
22
+ class PlanEventDeliveryError extends Schema.TaggedErrorClass<PlanEventDeliveryError>()('PlanEventDeliveryError', {
23
+ message: Schema.String,
24
+ cause: Schema.optional(Schema.Defect),
25
+ }) {}
26
+
27
+ function buildDeliveredKey(eventId: string): string {
28
+ return `plan-event:delivered:${eventId}`
29
+ }
30
+
31
+ function dispatchAdapterEvent(envelope: LotaRuntimePlanEventEnvelope) {
32
+ const adapter = getRuntimeAdapters().planEventAdapter
33
+ if (!adapter) {
34
+ return Effect.void
35
+ }
36
+
37
+ return Effect.tryPromise({
38
+ try: () => adapter.onPlanEvent(envelope),
39
+ catch: (error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error }),
40
+ })
41
+ }
42
+
43
+ function resolveWakeTarget(
44
+ envelope: LotaRuntimePlanEventEnvelope,
45
+ nodeSpecsById: Map<string, NonNullable<LotaRuntimePlanEventEnvelope['nodeSpec']>>,
46
+ ): { nodeId: string; agentId: string; reason: string } | null {
47
+ const currentNodeId = envelope.run.currentNodeId ?? envelope.event.nodeId
48
+ if (!currentNodeId) {
49
+ return null
50
+ }
51
+
52
+ const effectiveNodeSpec =
53
+ (envelope.event.nodeId === currentNodeId ? envelope.nodeSpec : undefined) ?? nodeSpecsById.get(currentNodeId)
54
+ if (!effectiveNodeSpec || effectiveNodeSpec.owner.executorType !== 'agent') {
55
+ return null
56
+ }
57
+
58
+ const isVisible = resolvePlanNodeExecutionVisibility(envelope.spec, effectiveNodeSpec) === 'visible'
59
+ if (!isVisible) {
60
+ return null
61
+ }
62
+
63
+ const supportedEventTypes = new Set([
64
+ 'node-ready',
65
+ 'node-unblocked',
66
+ 'approval-resolved',
67
+ 'run-resumed',
68
+ 'deadline-warning',
69
+ 'escalation-triggered',
70
+ ])
71
+ if (!supportedEventTypes.has(envelope.event.eventType)) {
72
+ return null
73
+ }
74
+
75
+ return { nodeId: currentNodeId, agentId: effectiveNodeSpec.owner.ref, reason: envelope.event.eventType }
76
+ }
77
+
78
+ function enqueueWakeIfNeeded(
79
+ envelope: LotaRuntimePlanEventEnvelope,
80
+ nodeSpecsById: Map<string, NonNullable<LotaRuntimePlanEventEnvelope['nodeSpec']>>,
81
+ ) {
82
+ return Effect.gen(function* () {
83
+ const wakeTarget = resolveWakeTarget(envelope, nodeSpecsById)
84
+ if (!wakeTarget) {
85
+ return
86
+ }
87
+
88
+ const { enqueuePlanAgentHeartbeatWake } = yield* Effect.tryPromise({
89
+ try: () => import('../../queues/plan-agent-heartbeat.queue'),
90
+ catch: (error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error }),
91
+ })
92
+ yield* Effect.tryPromise({
93
+ try: () =>
94
+ enqueuePlanAgentHeartbeatWake({
95
+ organizationId: envelope.organizationId,
96
+ threadId: envelope.threadId,
97
+ runId: envelope.runId,
98
+ nodeId: wakeTarget.nodeId,
99
+ agentId: wakeTarget.agentId,
100
+ reason: wakeTarget.reason,
101
+ }),
102
+ catch: (error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error }),
103
+ })
104
+ })
105
+ }
106
+
107
+ interface PlanEventDeliveryDeps {
108
+ db: SurrealDBService
109
+ redis: RedisConnectionManager
110
+ planRunService: ReturnType<typeof makePlanRunService>
111
+ userService: ReturnType<typeof makeUserService>
112
+ }
113
+
114
+ export function makePlanEventDeliveryService(deps: PlanEventDeliveryDeps) {
115
+ const { db, redis, planRunService, userService } = deps
116
+
117
+ function deliverEvent(event: PlanEventRecord) {
118
+ return Effect.gen(function* () {
119
+ const run = yield* planRunService
120
+ .getRunById(event.runId)
121
+ .pipe(Effect.mapError((error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error })))
122
+ const [spec, nodeSpecs, nodeRuns, thread] = yield* Effect.all([
123
+ planRunService
124
+ .getPlanSpecById(run.planSpecId)
125
+ .pipe(
126
+ Effect.mapError((error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error })),
127
+ ),
128
+ planRunService
129
+ .listNodeSpecs(run.planSpecId)
130
+ .pipe(
131
+ Effect.mapError((error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error })),
132
+ ),
133
+ planRunService
134
+ .listNodeRuns(run.id)
135
+ .pipe(
136
+ Effect.mapError((error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error })),
137
+ ),
138
+ db
139
+ .findOne(TABLES.THREAD, { id: ensureRecordId(run.threadId, TABLES.THREAD) }, ThreadSchema)
140
+ .pipe(
141
+ Effect.mapError((error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error })),
142
+ ),
143
+ ])
144
+
145
+ const nodeSpecsById = new Map(nodeSpecs.map((nodeSpec) => [nodeSpec.nodeId, nodeSpec]))
146
+ const nodeRunsById = new Map(nodeRuns.map((nodeRun) => [nodeRun.nodeId, nodeRun]))
147
+ const organizationId = recordIdToString(run.organizationId, TABLES.ORGANIZATION)
148
+ const threadId = recordIdToString(run.threadId, TABLES.THREAD)
149
+ const runIdString = recordIdToString(run.id, TABLES.PLAN_RUN)
150
+ const planSpecId = recordIdToString(spec.id, TABLES.PLAN_SPEC)
151
+ const userId = thread?.userId
152
+ ? recordIdToString(ensureRecordId(thread.userId, TABLES.USER), TABLES.USER)
153
+ : undefined
154
+ const userName =
155
+ userId === undefined
156
+ ? undefined
157
+ : yield* Effect.orElseSucceed(
158
+ Effect.map(
159
+ userService
160
+ .getUser(userId)
161
+ .pipe(
162
+ Effect.mapError(
163
+ (error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error }),
164
+ ),
165
+ ),
166
+ (user) => user.name,
167
+ ),
168
+ () => undefined,
169
+ )
170
+
171
+ const envelope: LotaRuntimePlanEventEnvelope = {
172
+ event,
173
+ spec,
174
+ run,
175
+ ...(event.nodeId ? { nodeSpec: nodeSpecsById.get(event.nodeId) } : {}),
176
+ ...(event.nodeId ? { nodeRun: nodeRunsById.get(event.nodeId) } : {}),
177
+ organizationId,
178
+ threadId,
179
+ runId: runIdString,
180
+ planSpecId,
181
+ ...(userId ? { userId } : {}),
182
+ ...(userName ? { userName } : {}),
183
+ }
184
+
185
+ yield* dispatchAdapterEvent(envelope)
186
+ yield* enqueueWakeIfNeeded(envelope, nodeSpecsById)
187
+ })
188
+ }
189
+
190
+ const dispatchEventEffect = Effect.fn('PlanEventDelivery.dispatchEvent')(function* (event: PlanEventRecord) {
191
+ const eventId = recordIdToString(event.id, TABLES.PLAN_EVENT)
192
+ const deliveredKey = buildDeliveredKey(eventId)
193
+ const exists = yield* Effect.tryPromise({
194
+ try: () => redis.getConnection().exists(deliveredKey),
195
+ catch: (error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error }),
196
+ })
197
+ if (exists) {
198
+ return
199
+ }
200
+
201
+ yield* deliverEvent(event)
202
+ yield* Effect.tryPromise({
203
+ try: () => redis.getConnection().set(deliveredKey, '1', 'PX', PLAN_EVENT_DELIVERED_TTL_MS),
204
+ catch: (error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error }),
205
+ })
206
+ })
207
+
208
+ const dispatchUndeliveredEventsEffect = Effect.fn('PlanEventDelivery.dispatchUndeliveredEvents')(function* (
209
+ runId: string,
210
+ options?: { limit?: number },
211
+ ) {
212
+ const run = yield* planRunService
213
+ .getRunById(runId)
214
+ .pipe(Effect.mapError((error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error })))
215
+ const events = yield* planRunService
216
+ .listEvents(run.id, options?.limit ?? 200)
217
+ .pipe(Effect.mapError((error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error })))
218
+
219
+ for (const event of events) {
220
+ yield* dispatchEventEffect(event)
221
+ }
222
+ })
223
+
224
+ const dispatchEventsEffect = Effect.fn('PlanEventDelivery.dispatchEvents')(function* (events: PlanEventRecord[]) {
225
+ const runIds = new Set(events.map((event) => recordIdToString(event.runId, TABLES.PLAN_RUN)))
226
+ for (const runId of runIds) {
227
+ yield* dispatchUndeliveredEventsEffect(runId)
228
+ }
229
+ })
230
+
231
+ return {
232
+ dispatchEvents(events: PlanEventRecord[]): Promise<void> {
233
+ return runPromise(dispatchEventsEffect(events))
234
+ },
235
+
236
+ dispatchEventsEffect,
237
+
238
+ dispatchEvent(event: PlanEventRecord): Promise<void> {
239
+ return runPromise(dispatchEventEffect(event))
240
+ },
241
+
242
+ dispatchEventEffect,
243
+
244
+ dispatchUndeliveredEvents(runId: string, options?: { limit?: number }): Promise<void> {
245
+ return runPromise(dispatchUndeliveredEventsEffect(runId, options))
246
+ },
247
+
248
+ dispatchUndeliveredEventsEffect,
249
+ }
250
+ }
251
+
252
+ export class PlanEventDeliveryServiceTag extends Context.Service<
253
+ PlanEventDeliveryServiceTag,
254
+ ReturnType<typeof makePlanEventDeliveryService>
255
+ >()('@lota-sdk/core/PlanEventDeliveryService') {}
256
+
257
+ export const PlanEventDeliveryServiceLive = Layer.effect(
258
+ PlanEventDeliveryServiceTag,
259
+ Effect.gen(function* () {
260
+ const db = yield* DatabaseServiceTag
261
+ const redis = yield* RedisServiceTag
262
+ const planRunService = yield* PlanRunServiceTag
263
+ const userService = yield* UserServiceTag
264
+ return makePlanEventDeliveryService({ db, redis, planRunService, userService })
265
+ }),
266
+ )
@@ -0,0 +1,35 @@
1
+ import type { Context } from 'effect'
2
+
3
+ import type { SurrealDBService } from '../../db/service'
4
+ import type { makeGeneratedDocumentStorageService } from '../../storage/generated-document-storage.service'
5
+ import type { makeArtifactService } from '../artifact.service'
6
+ import type { FeedbackLoopServiceTag } from '../feedback-loop.service'
7
+ import type { InstitutionalMemoryServiceTag } from '../institutional-memory.service'
8
+ import type { QualityMetricsServiceTag } from '../quality-metrics.service'
9
+ import type { makePlanApprovalService } from './plan-approval.service'
10
+ import type { makePlanArtifactService } from './plan-artifact.service'
11
+ import type { makePlanCheckpointService } from './plan-checkpoint.service'
12
+ import type { makePlanCompletionSideEffects } from './plan-completion-side-effects'
13
+ import type { makePlanCoordinationService } from './plan-coordination.service'
14
+ import type { makePlanEventDeliveryService } from './plan-event-delivery.service'
15
+ import type { makePlanRunService } from './plan-run.service'
16
+ import type { makePlanSchedulerService } from './plan-scheduler.service'
17
+ import type { makePlanValidatorService } from './plan-validator.service'
18
+
19
+ export interface PlanExecutorContext {
20
+ databaseService: SurrealDBService
21
+ generatedDocumentStorageService: ReturnType<typeof makeGeneratedDocumentStorageService>
22
+ artifactService: ReturnType<typeof makeArtifactService>
23
+ feedbackLoopService: Context.Service.Shape<typeof FeedbackLoopServiceTag>
24
+ institutionalMemoryService: Context.Service.Shape<typeof InstitutionalMemoryServiceTag>
25
+ planApprovalService: ReturnType<typeof makePlanApprovalService>
26
+ planArtifactService: ReturnType<typeof makePlanArtifactService>
27
+ planCheckpointService: ReturnType<typeof makePlanCheckpointService>
28
+ planCoordinationService: ReturnType<typeof makePlanCoordinationService>
29
+ planEventDeliveryService: ReturnType<typeof makePlanEventDeliveryService>
30
+ planRunService: ReturnType<typeof makePlanRunService>
31
+ planSchedulerService: ReturnType<typeof makePlanSchedulerService>
32
+ planValidatorService: ReturnType<typeof makePlanValidatorService>
33
+ qualityMetricsService: Context.Service.Shape<typeof QualityMetricsServiceTag>
34
+ planCompletionSideEffects: ReturnType<typeof makePlanCompletionSideEffects>
35
+ }