@lota-sdk/core 0.4.8 → 0.4.9

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 (259) hide show
  1. package/package.json +11 -12
  2. package/src/ai/embedding-cache.ts +94 -22
  3. package/src/ai-gateway/ai-gateway.ts +738 -223
  4. package/src/config/agent-defaults.ts +176 -75
  5. package/src/config/agent-types.ts +54 -4
  6. package/src/config/constants.ts +8 -2
  7. package/src/config/logger.ts +286 -19
  8. package/src/config/thread-defaults.ts +33 -21
  9. package/src/create-runtime.ts +725 -387
  10. package/src/db/base.service.ts +52 -28
  11. package/src/db/cursor-pagination.ts +71 -30
  12. package/src/db/memory-store.helpers.ts +4 -7
  13. package/src/db/memory-store.ts +856 -598
  14. package/src/db/memory.ts +398 -275
  15. package/src/db/record-id.ts +32 -10
  16. package/src/db/schema-fingerprint.ts +30 -12
  17. package/src/db/service-normalization.ts +255 -0
  18. package/src/db/service.ts +726 -761
  19. package/src/db/startup.ts +140 -66
  20. package/src/db/transaction-conflict.ts +15 -0
  21. package/src/effect/awaitable-effect.ts +87 -0
  22. package/src/effect/errors.ts +121 -0
  23. package/src/effect/helpers.ts +98 -0
  24. package/src/effect/index.ts +22 -0
  25. package/src/effect/layers.ts +228 -0
  26. package/src/effect/runtime-ref.ts +25 -0
  27. package/src/effect/runtime.ts +31 -0
  28. package/src/effect/services.ts +57 -0
  29. package/src/effect/zod.ts +43 -0
  30. package/src/embeddings/provider.ts +122 -76
  31. package/src/index.ts +46 -1
  32. package/src/openrouter/direct-provider.ts +11 -35
  33. package/src/queues/autonomous-job.queue.ts +130 -74
  34. package/src/queues/context-compaction.queue.ts +60 -15
  35. package/src/queues/delayed-node-promotion.queue.ts +52 -15
  36. package/src/queues/document-processor.queue.ts +52 -77
  37. package/src/queues/memory-consolidation.queue.ts +47 -32
  38. package/src/queues/organization-learning.queue.ts +13 -4
  39. package/src/queues/plan-agent-heartbeat.queue.ts +65 -21
  40. package/src/queues/plan-scheduler.queue.ts +107 -31
  41. package/src/queues/post-chat-memory.queue.ts +66 -24
  42. package/src/queues/queue-factory.ts +142 -52
  43. package/src/queues/standalone-worker.ts +39 -0
  44. package/src/queues/title-generation.queue.ts +54 -9
  45. package/src/redis/connection.ts +84 -32
  46. package/src/redis/index.ts +6 -8
  47. package/src/redis/org-memory-lock.ts +60 -27
  48. package/src/redis/redis-lease-lock.ts +200 -121
  49. package/src/redis/runtime-connection.ts +10 -0
  50. package/src/redis/stream-context.ts +84 -46
  51. package/src/runtime/agent-identity-overrides.ts +2 -2
  52. package/src/runtime/agent-runtime-policy.ts +4 -1
  53. package/src/runtime/agent-stream-helpers.ts +20 -9
  54. package/src/runtime/chat-run-orchestration.ts +102 -19
  55. package/src/runtime/chat-run-registry.ts +36 -2
  56. package/src/runtime/context-compaction/context-compaction-runtime.ts +107 -0
  57. package/src/runtime/{context-compaction.ts → context-compaction/context-compaction.ts} +114 -91
  58. package/src/runtime/execution-plan-visibility.ts +2 -2
  59. package/src/runtime/execution-plan.ts +42 -15
  60. package/src/runtime/graph-designer.ts +11 -7
  61. package/src/runtime/helper-model.ts +135 -48
  62. package/src/runtime/index.ts +7 -7
  63. package/src/runtime/indexed-repositories-policy.ts +3 -3
  64. package/src/runtime/{memory-block.ts → memory/memory-block.ts} +40 -36
  65. package/src/runtime/{memory-digest-policy.ts → memory/memory-digest-policy.ts} +1 -1
  66. package/src/runtime/{memory-pipeline.ts → memory/memory-pipeline.ts} +1 -1
  67. package/src/runtime/{memory-prompts-fact.ts → memory/memory-prompts-fact.ts} +2 -2
  68. package/src/runtime/{memory-scope.ts → memory/memory-scope.ts} +12 -6
  69. package/src/runtime/plugin-resolution.ts +144 -24
  70. package/src/runtime/plugin-types.ts +9 -1
  71. package/src/runtime/post-turn-side-effects.ts +197 -130
  72. package/src/runtime/retrieval-adapters.ts +38 -4
  73. package/src/runtime/runtime-config.ts +150 -61
  74. package/src/runtime/runtime-extensions.ts +21 -34
  75. package/src/runtime/social-chat/social-chat-agent-runner.ts +157 -0
  76. package/src/runtime/{social-chat-history.ts → social-chat/social-chat-history.ts} +42 -20
  77. package/src/runtime/social-chat/social-chat.ts +594 -0
  78. package/src/runtime/specialist-runner.ts +36 -10
  79. package/src/runtime/team-consultation/team-consultation-orchestrator.ts +427 -0
  80. package/src/runtime/{team-consultation-prompts.ts → team-consultation/team-consultation-prompts.ts} +6 -2
  81. package/src/runtime/thread-chat-helpers.ts +2 -2
  82. package/src/runtime/thread-plan-turn.ts +2 -1
  83. package/src/runtime/thread-turn-context.ts +172 -94
  84. package/src/runtime/turn-lifecycle.ts +93 -27
  85. package/src/services/agent-activity.service.ts +287 -203
  86. package/src/services/agent-executor.service.ts +329 -217
  87. package/src/services/artifact.service.ts +225 -148
  88. package/src/services/attachment.service.ts +137 -115
  89. package/src/services/autonomous-job.service.ts +888 -491
  90. package/src/services/chat-run-registry.service.ts +11 -1
  91. package/src/services/context-compaction.service.ts +136 -86
  92. package/src/services/document-chunk.service.ts +162 -90
  93. package/src/services/execution-plan/execution-plan-approval.ts +26 -0
  94. package/src/services/execution-plan/execution-plan-context.ts +29 -0
  95. package/src/services/execution-plan/execution-plan-graph.ts +256 -0
  96. package/src/services/execution-plan/execution-plan-schedule.ts +84 -0
  97. package/src/services/execution-plan/execution-plan-spec.ts +75 -0
  98. package/src/services/execution-plan/execution-plan.service.ts +1041 -0
  99. package/src/services/feedback-loop.service.ts +132 -76
  100. package/src/services/global-orchestrator.service.ts +80 -170
  101. package/src/services/graph-full-routing.ts +182 -0
  102. package/src/services/index.ts +18 -21
  103. package/src/services/institutional-memory.service.ts +220 -123
  104. package/src/services/learned-skill.service.ts +364 -259
  105. package/src/services/memory/memory-conversation.ts +95 -0
  106. package/src/services/memory/memory-org-memory.ts +39 -0
  107. package/src/services/memory/memory-preseeded.ts +80 -0
  108. package/src/services/memory/memory-rerank.ts +297 -0
  109. package/src/services/{memory-utils.ts → memory/memory-utils.ts} +5 -5
  110. package/src/services/memory/memory.service.ts +692 -0
  111. package/src/services/memory/rerank.service.ts +209 -0
  112. package/src/services/monitoring-window.service.ts +92 -70
  113. package/src/services/mutating-approval.service.ts +62 -53
  114. package/src/services/node-workspace.service.ts +141 -98
  115. package/src/services/notification.service.ts +17 -16
  116. package/src/services/organization-member.service.ts +120 -66
  117. package/src/services/organization.service.ts +144 -51
  118. package/src/services/ownership-dispatcher.service.ts +415 -264
  119. package/src/services/plan/plan-agent-heartbeat.service.ts +234 -0
  120. package/src/services/plan/plan-agent-query.service.ts +322 -0
  121. package/src/services/plan/plan-approval.service.ts +102 -0
  122. package/src/services/plan/plan-artifact.service.ts +60 -0
  123. package/src/services/plan/plan-builder.service.ts +76 -0
  124. package/src/services/plan/plan-checkpoint.service.ts +103 -0
  125. package/src/services/{plan-compiler.service.ts → plan/plan-compiler.service.ts} +26 -9
  126. package/src/services/plan/plan-completion-side-effects.ts +175 -0
  127. package/src/services/plan/plan-coordination.service.ts +181 -0
  128. package/src/services/plan/plan-cycle.service.ts +398 -0
  129. package/src/services/plan/plan-deadline.service.ts +547 -0
  130. package/src/services/plan/plan-event-delivery.service.ts +261 -0
  131. package/src/services/plan/plan-executor-context.ts +35 -0
  132. package/src/services/plan/plan-executor-graph.ts +475 -0
  133. package/src/services/plan/plan-executor-helpers.ts +322 -0
  134. package/src/services/plan/plan-executor-persistence.ts +209 -0
  135. package/src/services/plan/plan-executor.service.ts +1654 -0
  136. package/src/services/{plan-helpers.ts → plan/plan-helpers.ts} +1 -1
  137. package/src/services/{plan-run-data.ts → plan/plan-run-data.ts} +4 -4
  138. package/src/services/plan/plan-run-serialization.ts +15 -0
  139. package/src/services/plan/plan-run.service.ts +644 -0
  140. package/src/services/plan/plan-scheduler.service.ts +385 -0
  141. package/src/services/plan/plan-template.service.ts +224 -0
  142. package/src/services/plan/plan-transaction-events.ts +33 -0
  143. package/src/services/plan/plan-validator.service.ts +907 -0
  144. package/src/services/plan/plan-workspace.service.ts +125 -0
  145. package/src/services/plugin-executor.service.ts +97 -68
  146. package/src/services/quality-metrics.service.ts +112 -94
  147. package/src/services/queue-job.service.ts +296 -230
  148. package/src/services/recent-activity-title.service.ts +65 -36
  149. package/src/services/recent-activity.service.ts +274 -259
  150. package/src/services/skill-resolver.service.ts +38 -12
  151. package/src/services/social-chat-history.service.ts +176 -125
  152. package/src/services/system-executor.service.ts +91 -61
  153. package/src/services/thread/thread-active-run.ts +203 -0
  154. package/src/services/thread/thread-bootstrap.ts +369 -0
  155. package/src/services/thread/thread-listing.ts +198 -0
  156. package/src/services/thread/thread-memory-block.ts +117 -0
  157. package/src/services/thread/thread-message.service.ts +363 -0
  158. package/src/services/thread/thread-record-store.ts +155 -0
  159. package/src/services/thread/thread-title.service.ts +74 -0
  160. package/src/services/thread/thread-turn-execution.ts +280 -0
  161. package/src/services/thread/thread-turn-message-context.ts +73 -0
  162. package/src/services/thread/thread-turn-preparation.service.ts +1146 -0
  163. package/src/services/thread/thread-turn-streaming.ts +402 -0
  164. package/src/services/thread/thread-turn-tracing.ts +35 -0
  165. package/src/services/thread/thread-turn.ts +343 -0
  166. package/src/services/thread/thread.service.ts +335 -0
  167. package/src/services/user.service.ts +82 -32
  168. package/src/services/write-intent-validator.service.ts +63 -51
  169. package/src/storage/attachment-parser.ts +69 -27
  170. package/src/storage/attachment-storage.service.ts +331 -275
  171. package/src/storage/generated-document-storage.service.ts +66 -34
  172. package/src/system-agents/agent-result.ts +3 -1
  173. package/src/system-agents/context-compaction.agent.ts +2 -2
  174. package/src/system-agents/delegated-agent-factory.ts +159 -90
  175. package/src/system-agents/memory-reranker.agent.ts +2 -2
  176. package/src/system-agents/memory.agent.ts +2 -2
  177. package/src/system-agents/recent-activity-title-refiner.agent.ts +2 -2
  178. package/src/system-agents/regular-chat-memory-digest.agent.ts +2 -2
  179. package/src/system-agents/skill-extractor.agent.ts +2 -2
  180. package/src/system-agents/skill-manager.agent.ts +2 -2
  181. package/src/system-agents/thread-router.agent.ts +157 -113
  182. package/src/system-agents/title-generator.agent.ts +2 -2
  183. package/src/tools/execution-plan.tool.ts +220 -161
  184. package/src/tools/fetch-webpage.tool.ts +21 -17
  185. package/src/tools/firecrawl-client.ts +16 -6
  186. package/src/tools/index.ts +1 -0
  187. package/src/tools/memory-block.tool.ts +14 -6
  188. package/src/tools/plan-approval.tool.ts +49 -47
  189. package/src/tools/read-file-parts.tool.ts +44 -33
  190. package/src/tools/remember-memory.tool.ts +65 -45
  191. package/src/tools/search-web.tool.ts +26 -22
  192. package/src/tools/search.tool.ts +41 -29
  193. package/src/tools/team-think.tool.ts +124 -83
  194. package/src/tools/user-questions.tool.ts +4 -3
  195. package/src/tools/web-tool-shared.ts +6 -0
  196. package/src/utils/async.ts +17 -23
  197. package/src/utils/crypto.ts +21 -0
  198. package/src/utils/date-time.ts +40 -1
  199. package/src/utils/errors.ts +95 -16
  200. package/src/utils/hono-error-handler.ts +24 -39
  201. package/src/utils/index.ts +2 -1
  202. package/src/utils/null-proto-record.ts +41 -0
  203. package/src/utils/sse-keepalive.ts +124 -21
  204. package/src/workers/bootstrap.ts +186 -51
  205. package/src/workers/memory-consolidation.worker.ts +325 -237
  206. package/src/workers/organization-learning.worker.ts +50 -16
  207. package/src/workers/regular-chat-memory-digest.helpers.ts +28 -27
  208. package/src/workers/regular-chat-memory-digest.runner.ts +175 -114
  209. package/src/workers/skill-extraction.runner.ts +176 -93
  210. package/src/workers/utils/file-section-chunker.ts +8 -10
  211. package/src/workers/utils/repo-structure-extractor.ts +349 -260
  212. package/src/workers/utils/repomix-file-sections.ts +2 -2
  213. package/src/workers/utils/thread-message-query.ts +97 -38
  214. package/src/workers/worker-utils.ts +56 -31
  215. package/src/config/debug-logger.ts +0 -47
  216. package/src/redis/connection-accessor.ts +0 -26
  217. package/src/runtime/context-compaction-runtime.ts +0 -87
  218. package/src/runtime/social-chat-agent-runner.ts +0 -118
  219. package/src/runtime/social-chat.ts +0 -516
  220. package/src/runtime/team-consultation-orchestrator.ts +0 -272
  221. package/src/services/adaptive-playbook.service.ts +0 -152
  222. package/src/services/artifact-provenance.service.ts +0 -172
  223. package/src/services/chat-attachments.service.ts +0 -17
  224. package/src/services/context-compaction-runtime.singleton.ts +0 -13
  225. package/src/services/execution-plan.service.ts +0 -1118
  226. package/src/services/memory.service.ts +0 -914
  227. package/src/services/plan-agent-heartbeat.service.ts +0 -136
  228. package/src/services/plan-agent-query.service.ts +0 -267
  229. package/src/services/plan-approval.service.ts +0 -83
  230. package/src/services/plan-artifact.service.ts +0 -50
  231. package/src/services/plan-builder.service.ts +0 -67
  232. package/src/services/plan-checkpoint.service.ts +0 -81
  233. package/src/services/plan-completion-side-effects.ts +0 -80
  234. package/src/services/plan-coordination.service.ts +0 -157
  235. package/src/services/plan-cycle.service.ts +0 -284
  236. package/src/services/plan-deadline.service.ts +0 -430
  237. package/src/services/plan-event-delivery.service.ts +0 -166
  238. package/src/services/plan-executor.service.ts +0 -1950
  239. package/src/services/plan-run.service.ts +0 -515
  240. package/src/services/plan-scheduler.service.ts +0 -240
  241. package/src/services/plan-template.service.ts +0 -177
  242. package/src/services/plan-validator.service.ts +0 -818
  243. package/src/services/plan-workspace.service.ts +0 -83
  244. package/src/services/rerank.service.ts +0 -156
  245. package/src/services/thread-message.service.ts +0 -275
  246. package/src/services/thread-plan-registry.service.ts +0 -22
  247. package/src/services/thread-title.service.ts +0 -39
  248. package/src/services/thread-turn-preparation.service.ts +0 -1147
  249. package/src/services/thread-turn.ts +0 -172
  250. package/src/services/thread.service.ts +0 -869
  251. package/src/utils/env.ts +0 -8
  252. /package/src/runtime/{context-compaction-constants.ts → context-compaction/context-compaction-constants.ts} +0 -0
  253. /package/src/runtime/{memory-format.ts → memory/memory-format.ts} +0 -0
  254. /package/src/runtime/{memory-prompts-parse.ts → memory/memory-prompts-parse.ts} +0 -0
  255. /package/src/runtime/{memory-prompts-update.ts → memory/memory-prompts-update.ts} +0 -0
  256. /package/src/runtime/{social-chat-prompts.ts → social-chat/social-chat-prompts.ts} +0 -0
  257. /package/src/services/{plan-node-spec.ts → plan/plan-node-spec.ts} +0 -0
  258. /package/src/services/{thread-constants.ts → thread/thread-constants.ts} +0 -0
  259. /package/src/services/{thread.types.ts → thread/thread.types.ts} +0 -0
@@ -0,0 +1,261 @@
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
+ function dispatchEventEffect(event: PlanEventRecord) {
191
+ return Effect.gen(function* () {
192
+ const eventId = recordIdToString(event.id, TABLES.PLAN_EVENT)
193
+ const deliveredKey = buildDeliveredKey(eventId)
194
+ const exists = yield* Effect.tryPromise({
195
+ try: () => redis.getConnection().exists(deliveredKey),
196
+ catch: (error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error }),
197
+ })
198
+ if (exists) {
199
+ return
200
+ }
201
+
202
+ yield* deliverEvent(event)
203
+ yield* Effect.tryPromise({
204
+ try: () => redis.getConnection().set(deliveredKey, '1', 'PX', PLAN_EVENT_DELIVERED_TTL_MS),
205
+ catch: (error) => new PlanEventDeliveryError({ message: getErrorMessage(error), cause: error }),
206
+ })
207
+ })
208
+ }
209
+
210
+ function dispatchUndeliveredEventsEffect(runId: string, options?: { limit?: number }) {
211
+ return Effect.gen(function* () {
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
+
225
+ return {
226
+ dispatchEvents(events: PlanEventRecord[]): Promise<void> {
227
+ return runPromise(
228
+ Effect.gen(function* () {
229
+ const runIds = new Set(events.map((event) => recordIdToString(event.runId, TABLES.PLAN_RUN)))
230
+ for (const runId of runIds) {
231
+ yield* dispatchUndeliveredEventsEffect(runId)
232
+ }
233
+ }),
234
+ )
235
+ },
236
+
237
+ dispatchEvent(event: PlanEventRecord): Promise<void> {
238
+ return runPromise(dispatchEventEffect(event))
239
+ },
240
+
241
+ dispatchUndeliveredEvents(runId: string, options?: { limit?: number }): Promise<void> {
242
+ return runPromise(dispatchUndeliveredEventsEffect(runId, options))
243
+ },
244
+ }
245
+ }
246
+
247
+ export class PlanEventDeliveryServiceTag extends Context.Service<
248
+ PlanEventDeliveryServiceTag,
249
+ ReturnType<typeof makePlanEventDeliveryService>
250
+ >()('PlanEventDeliveryService') {}
251
+
252
+ export const PlanEventDeliveryServiceLive = Layer.effect(
253
+ PlanEventDeliveryServiceTag,
254
+ Effect.gen(function* () {
255
+ const db = yield* DatabaseServiceTag
256
+ const redis = yield* RedisServiceTag
257
+ const planRunService = yield* PlanRunServiceTag
258
+ const userService = yield* UserServiceTag
259
+ return makePlanEventDeliveryService({ db, redis, planRunService, userService })
260
+ }),
261
+ )
@@ -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
+ }