@lota-sdk/core 0.4.10 → 0.4.11

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 (108) hide show
  1. package/package.json +2 -2
  2. package/src/ai-gateway/ai-gateway.ts +149 -95
  3. package/src/ai-gateway/index.ts +16 -1
  4. package/src/config/agent-defaults.ts +4 -120
  5. package/src/config/logger.ts +18 -34
  6. package/src/config/thread-defaults.ts +1 -18
  7. package/src/create-runtime.ts +90 -28
  8. package/src/db/base.service.ts +30 -38
  9. package/src/db/service.ts +489 -545
  10. package/src/effect/index.ts +0 -2
  11. package/src/effect/layers.ts +6 -13
  12. package/src/embeddings/provider.ts +2 -7
  13. package/src/index.ts +4 -5
  14. package/src/queues/autonomous-job.queue.ts +159 -113
  15. package/src/queues/context-compaction.queue.ts +39 -25
  16. package/src/queues/delayed-node-promotion.queue.ts +56 -29
  17. package/src/queues/document-processor.queue.ts +5 -3
  18. package/src/queues/index.ts +1 -0
  19. package/src/queues/memory-consolidation.queue.ts +79 -53
  20. package/src/queues/organization-learning.queue.ts +63 -39
  21. package/src/queues/plan-agent-heartbeat.queue.ts +104 -79
  22. package/src/queues/plan-scheduler.queue.ts +100 -84
  23. package/src/queues/post-chat-memory.queue.ts +55 -33
  24. package/src/queues/queue-factory.ts +40 -41
  25. package/src/queues/queues.service.ts +61 -0
  26. package/src/queues/title-generation.queue.ts +42 -31
  27. package/src/redis/org-memory-lock.ts +24 -9
  28. package/src/redis/redis-lease-lock.ts +8 -1
  29. package/src/runtime/agent-identity-overrides.ts +7 -3
  30. package/src/runtime/agent-runtime-policy.ts +9 -4
  31. package/src/runtime/agent-stream-helpers.ts +9 -4
  32. package/src/runtime/context-compaction/context-compaction-runtime.ts +28 -32
  33. package/src/runtime/context-compaction/context-compaction.ts +9 -7
  34. package/src/runtime/domain-layer.ts +15 -4
  35. package/src/runtime/execution-plan-visibility.ts +5 -2
  36. package/src/runtime/graph-designer.ts +0 -22
  37. package/src/runtime/index.ts +1 -0
  38. package/src/runtime/indexed-repositories-policy.ts +2 -6
  39. package/src/runtime/plugin-resolution.ts +29 -12
  40. package/src/runtime/post-turn-side-effects.ts +139 -141
  41. package/src/runtime/runtime-config.ts +0 -6
  42. package/src/runtime/runtime-extensions.ts +0 -54
  43. package/src/runtime/runtime-lifecycle.ts +4 -4
  44. package/src/runtime/runtime-services.ts +122 -53
  45. package/src/runtime/runtime-worker-registry.ts +113 -30
  46. package/src/runtime/social-chat/social-chat-agent-runner.ts +6 -3
  47. package/src/runtime/social-chat/social-chat-history.ts +3 -1
  48. package/src/runtime/social-chat/social-chat.ts +35 -20
  49. package/src/runtime/team-consultation/team-consultation-orchestrator.ts +6 -5
  50. package/src/runtime/team-consultation/team-consultation-prompts.ts +11 -6
  51. package/src/runtime/thread-chat-helpers.ts +18 -9
  52. package/src/runtime/thread-turn-context.ts +7 -47
  53. package/src/runtime/turn-lifecycle.ts +6 -14
  54. package/src/services/agent-activity.service.ts +168 -175
  55. package/src/services/agent-executor.service.ts +35 -16
  56. package/src/services/attachment.service.ts +4 -70
  57. package/src/services/autonomous-job.service.ts +53 -61
  58. package/src/services/context-compaction.service.ts +7 -9
  59. package/src/services/execution-plan/execution-plan-graph.ts +106 -115
  60. package/src/services/execution-plan/execution-plan-schedule.ts +1 -15
  61. package/src/services/execution-plan/execution-plan.service.ts +67 -50
  62. package/src/services/global-orchestrator.service.ts +18 -7
  63. package/src/services/graph-full-routing.ts +7 -6
  64. package/src/services/memory/memory-conversation.ts +10 -5
  65. package/src/services/memory/memory.service.ts +11 -8
  66. package/src/services/ownership-dispatcher.service.ts +16 -5
  67. package/src/services/plan/plan-agent-heartbeat.service.ts +29 -15
  68. package/src/services/plan/plan-agent-query.service.ts +12 -8
  69. package/src/services/plan/plan-completion-side-effects.ts +93 -101
  70. package/src/services/plan/plan-cycle.service.ts +7 -45
  71. package/src/services/plan/plan-deadline.service.ts +28 -17
  72. package/src/services/plan/plan-event-delivery.service.ts +47 -40
  73. package/src/services/plan/plan-executor-context.ts +2 -0
  74. package/src/services/plan/plan-executor-graph.ts +366 -391
  75. package/src/services/plan/plan-executor.service.ts +13 -91
  76. package/src/services/plan/plan-scheduler.service.ts +62 -49
  77. package/src/services/plan/plan-transaction-events.ts +1 -1
  78. package/src/services/recent-activity-title.service.ts +6 -2
  79. package/src/services/thread/thread-bootstrap.ts +11 -9
  80. package/src/services/thread/thread-message.service.ts +6 -5
  81. package/src/services/thread/thread-turn-execution.ts +86 -82
  82. package/src/services/thread/thread-turn-preparation.service.ts +47 -24
  83. package/src/services/thread/thread-turn-streaming.ts +20 -25
  84. package/src/services/thread/thread-turn.ts +25 -44
  85. package/src/services/thread/thread.service.ts +21 -6
  86. package/src/system-agents/recent-activity-title-refiner.agent.ts +8 -5
  87. package/src/system-agents/thread-router.agent.ts +23 -20
  88. package/src/tools/execution-plan.tool.ts +8 -3
  89. package/src/tools/fetch-webpage.tool.ts +10 -9
  90. package/src/tools/firecrawl-client.ts +0 -15
  91. package/src/tools/remember-memory.tool.ts +3 -6
  92. package/src/tools/research-topic.tool.ts +12 -3
  93. package/src/tools/search-web.tool.ts +10 -9
  94. package/src/tools/search.tool.ts +4 -5
  95. package/src/tools/team-think.tool.ts +139 -121
  96. package/src/workers/bootstrap.ts +9 -10
  97. package/src/workers/memory-consolidation.worker.ts +4 -1
  98. package/src/workers/organization-learning.worker.ts +15 -2
  99. package/src/workers/regular-chat-memory-digest.helpers.ts +3 -4
  100. package/src/workers/regular-chat-memory-digest.runner.ts +21 -14
  101. package/src/workers/skill-extraction.runner.ts +13 -15
  102. package/src/workers/worker-utils.ts +6 -18
  103. package/src/effect/awaitable-effect.ts +0 -96
  104. package/src/effect/runtime-ref.ts +0 -25
  105. package/src/effect/runtime.ts +0 -46
  106. package/src/redis/runtime-connection.ts +0 -20
  107. package/src/runtime/runtime-accessors.ts +0 -92
  108. package/src/runtime/runtime-token.ts +0 -47
@@ -1,7 +1,5 @@
1
1
  import { Effect, Logger, References } from 'effect'
2
2
 
3
- import { getOptionalCurrentRuntime } from '../effect/runtime-ref'
4
-
5
3
  const LOG_CATEGORY = 'lota-sdk'
6
4
 
7
5
  export type LotaLogLevel = 'trace' | 'debug' | 'info' | 'warning' | 'error' | 'fatal'
@@ -46,19 +44,11 @@ function readEnvLogLevel(): LotaLogLevel | null {
46
44
  return resolveLotaLogLevel(value)
47
45
  }
48
46
 
49
- // Module-level cache: loggers expose a sync `.info(...)` API that must work
50
- // from both Effect and non-Effect call sites, so the level cannot live in
51
- // Effect.Config (which requires Effect context to read). `configureLotaLogger`
52
- // is called once from `buildInfrastructureLayer` with the resolved value.
53
- let configuredLogLevel: LotaLogLevel = readEnvLogLevel() ?? 'info'
54
-
55
- export function configureLotaLogger(logLevel: LotaLogLevel = 'info'): void {
56
- configuredLogLevel = logLevel
57
- }
58
-
59
- export function getConfiguredLogLevel(): LotaLogLevel {
60
- return configuredLogLevel
61
- }
47
+ // Loggers expose a sync `.info(...)` API that must work from both Effect
48
+ // and non-Effect call sites, so the level cannot live in Effect.Config
49
+ // (which requires Effect context to read). Resolve once from the environment
50
+ // at module load; hosts set `LOG_LEVEL` before importing the SDK.
51
+ const configuredLogLevel: LotaLogLevel = readEnvLogLevel() ?? 'info'
62
52
 
63
53
  export function toEffectLogLevel(logLevel: LotaLogLevel): EffectLogLevel {
64
54
  switch (logLevel) {
@@ -215,15 +205,6 @@ function getLogEffect(level: LotaLogLevel, message: string): LotaLogEffect {
215
205
  }
216
206
  }
217
207
 
218
- function runStandaloneLogEffect(effect: LotaLogEffect): void {
219
- Effect.runSync(
220
- effect.pipe(
221
- Effect.provide(Logger.layer([Logger.consolePretty()])),
222
- Effect.provideService(References.MinimumLogLevel, toEffectLogLevel(configuredLogLevel)),
223
- ),
224
- )
225
- }
226
-
227
208
  function emitConsoleFallback(
228
209
  level: LotaLogLevel,
229
210
  category: readonly string[],
@@ -241,6 +222,9 @@ function emitConsoleFallback(
241
222
  sink(formattedMessage, rest)
242
223
  }
243
224
 
225
+ const standaloneLoggerLayer = Logger.layer([Logger.consolePretty()])
226
+ const standaloneMinLogLevel = toEffectLogLevel(configuredLogLevel)
227
+
244
228
  function emit(level: LotaLogLevel, category: readonly string[], message: string, fields?: LogFields): void {
245
229
  if (!shouldLog(level)) return
246
230
 
@@ -248,17 +232,17 @@ function emit(level: LotaLogLevel, category: readonly string[], message: string,
248
232
  const annotations = { lotaLogger: category.join(':'), ...buildLogContext(fields) }
249
233
  const effect = getLogEffect(level, formattedMessage).pipe(Effect.annotateLogs(annotations))
250
234
 
251
- // Route through the seated managed runtime so log timestamps stay on the
252
- // caller's fiber and inherit its span/log annotations. Pre-bootstrap (no
253
- // runtime seated) uses the standalone Effect logger so output stays
254
- // consistent with post-bootstrap formatting.
255
- const runtime = getOptionalCurrentRuntime()
235
+ // Loggers run outside any managed runtime: every call provides its own
236
+ // console logger layer and minimum log level so the emit path does not
237
+ // depend on ambient runtime state. Effect-native code paths recover spans
238
+ // and fiber annotations naturally via `Effect.log*`.
256
239
  try {
257
- if (runtime) {
258
- runtime.runFork(effect)
259
- } else {
260
- runStandaloneLogEffect(effect)
261
- }
240
+ Effect.runSync(
241
+ effect.pipe(
242
+ Effect.provide(standaloneLoggerLayer),
243
+ Effect.provideService(References.MinimumLogLevel, standaloneMinLogLevel),
244
+ ),
245
+ )
262
246
  } catch {
263
247
  emitConsoleFallback(level, category, formattedMessage, annotations)
264
248
  }
@@ -1,6 +1,3 @@
1
- import { resolveLotaService } from '../effect/runtime'
2
- import { ThreadConfigServiceTag } from '../effect/services'
3
-
4
1
  export interface ThreadBootstrapWelcomeConfig {
5
2
  defaultAgentId: string
6
3
  buildMessageText: (params: { userName?: string | null }) => string
@@ -28,16 +25,6 @@ interface ResolvedThreadBootstrapConfig {
28
25
 
29
26
  export type { ResolvedThreadBootstrapConfig }
30
27
 
31
- let currentThreadBootstrapConfig: ResolvedThreadBootstrapConfig | null = null
32
-
33
- export function configureThreadRuntimeDefaults(config: ResolvedThreadBootstrapConfig): void {
34
- currentThreadBootstrapConfig = config
35
- }
36
-
37
- export function clearThreadRuntimeDefaults(): void {
38
- currentThreadBootstrapConfig = null
39
- }
40
-
41
28
  function normalizeThreadAgentIds(values: readonly string[]): readonly string[] {
42
29
  const seen = new Set<string>()
43
30
  const deduped: string[] = []
@@ -80,13 +67,9 @@ export function resolveThreadConfig(params: {
80
67
  }
81
68
  }
82
69
 
83
- export function getThreadBootstrapConfig(): ResolvedThreadBootstrapConfig {
84
- return currentThreadBootstrapConfig ?? resolveLotaService(ThreadConfigServiceTag)
85
- }
86
-
87
70
  export function resolveOnboardingOwnerAgentId(
88
71
  defaultLeadAgentId: string,
89
- config: ResolvedThreadBootstrapConfig = getThreadBootstrapConfig(),
72
+ config: ResolvedThreadBootstrapConfig,
90
73
  ): string {
91
74
  return config.onboardingWelcome?.defaultAgentId ?? defaultLeadAgentId
92
75
  }
@@ -1,22 +1,26 @@
1
+ import type { Fiber } from 'effect'
1
2
  import { Effect, ManagedRuntime } from 'effect'
2
3
  import type { Subscriber } from 'resumable-stream/ioredis'
3
4
 
5
+ import { AiGatewayTag, bindAiGatewayRuntime } from './ai-gateway/ai-gateway'
4
6
  import { computeSchemaFingerprint } from './db/schema-fingerprint'
5
7
  import { publishDatabaseBootstrapEffect } from './db/startup'
6
8
  import {
9
+ AgentConfigServiceTag,
10
+ AgentFactoryServiceTag,
7
11
  buildInfrastructureLayer,
8
- clearLotaSdkRuntime,
9
12
  DatabaseServiceTag as EffectDatabaseService,
10
13
  RedisServiceTag as EffectRedisService,
11
- setLotaSdkRuntime,
14
+ RuntimeAdaptersServiceTag,
15
+ RuntimeConfigServiceTag,
12
16
  } from './effect'
13
17
  import { ConfigurationError, ServiceError } from './effect/errors'
14
18
  import { effectTryPromise } from './effect/helpers'
19
+ import { LotaQueuesServiceTag } from './queues/queues.service'
15
20
  import type { RedisConnectionManager } from './redis/connection'
16
21
  import { SharedThreadStreamSubscriberTag } from './redis/stream-context'
17
22
  import { buildDomainServiceLayer } from './runtime/domain-layer'
18
23
  import type { LotaPlugin, SystemNodeExecutor } from './runtime/plugin-types'
19
- import { clearRuntimeModuleAccessors, configureRuntimeModuleAccessors } from './runtime/runtime-accessors'
20
24
  import { LOTA_RUNTIME_ENV_KEYS, loadLotaRuntimeConfigFromEnv, parseLotaRuntimeConfig } from './runtime/runtime-config'
21
25
  import type { LotaRuntimeConfig, ResolvedLotaRuntimeConfig } from './runtime/runtime-config'
22
26
  import {
@@ -26,26 +30,34 @@ import {
26
30
  } from './runtime/runtime-lifecycle'
27
31
  import { buildRuntimeServiceSurface } from './runtime/runtime-services'
28
32
  import type { LotaRuntimeLota, LotaRuntimeServices } from './runtime/runtime-services'
29
- import { acquireRuntimeTokenEffect, isRuntimeTokenActive, releaseRuntimeToken } from './runtime/runtime-token'
30
33
  import type { LotaRuntimeWorkers } from './runtime/runtime-worker-registry'
31
34
  import { buildRuntimeWorkerRegistry } from './runtime/runtime-worker-registry'
32
35
  import type { LotaRuntimeSocialChat } from './runtime/social-chat/social-chat'
33
36
  import { createSocialChatRuntime } from './runtime/social-chat/social-chat'
37
+ import { AutonomousJobServiceTag } from './services/autonomous-job.service'
38
+ import { ContextCompactionServiceTag } from './services/context-compaction.service'
34
39
  import { LearnedSkillServiceTag } from './services/learned-skill.service'
35
40
  import { MemoryServiceTag } from './services/memory/memory.service'
41
+ import { PlanAgentHeartbeatServiceTag } from './services/plan/plan-agent-heartbeat.service'
42
+ import { PlanCycleServiceTag } from './services/plan/plan-cycle.service'
43
+ import { PlanDeadlineServiceTag } from './services/plan/plan-deadline.service'
44
+ import { PlanExecutorServiceTag } from './services/plan/plan-executor.service'
45
+ import { PlanSchedulerServiceTag } from './services/plan/plan-scheduler.service'
46
+ import { RecentActivityTitleServiceTag } from './services/recent-activity-title.service'
36
47
  import { SocialChatHistoryServiceTag } from './services/social-chat-history.service'
37
48
  import { getBuiltInSystemExecutors } from './services/system-executor.service'
49
+ import { ThreadTitleServiceTag } from './services/thread/thread-title.service'
38
50
  import { ThreadTurnServiceTag } from './services/thread/thread-turn'
39
-
40
- // Re-exported for consumers that reason about the runtime slot without
41
- // instantiating one (e.g., diagnostic harnesses).
42
- export { isRuntimeTokenActive }
51
+ import { ThreadServiceTag } from './services/thread/thread.service'
43
52
 
44
53
  export interface LotaRuntime {
45
54
  /** 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>
55
+ runPromise: <A, E, R>(effect: Effect.Effect<A, E, R>, options?: { readonly signal?: AbortSignal }) => Promise<A>
47
56
  /** Run an Effect synchronously through the SDK runtime. */
48
- runSync: <A, E>(effect: Effect.Effect<A, E>) => A
57
+ runSync: <A, E, R>(effect: Effect.Effect<A, E, R>) => A
58
+ /** Fork an Effect as a Fiber through the SDK runtime (carries OTLP context). */
59
+ // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
60
+ runFork: <A, E, R>(effect: Effect.Effect<A, E, R>) => Fiber.Fiber<A, E | unknown>
49
61
  services: LotaRuntimeServices
50
62
  lota: LotaRuntimeLota
51
63
  redis: {
@@ -77,14 +89,10 @@ export function createLotaRuntimeFromEnv(
77
89
  }
78
90
 
79
91
  export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntime> {
80
- let runtimeToken: symbol | null = null
81
92
  let effectRuntime: { dispose(): Promise<void> } | null = null
82
93
 
83
94
  return Effect.runPromise(
84
95
  Effect.gen(function* () {
85
- // Fail fast if another runtime is already active in this process.
86
- runtimeToken = yield* acquireRuntimeTokenEffect()
87
-
88
96
  const resolvedConfig = parseLotaRuntimeConfig(config)
89
97
  const systemExecutors = { ...getBuiltInSystemExecutors(), ...resolvedConfig.systemExecutors }
90
98
  const runtimeConfig = { ...resolvedConfig, systemExecutors } satisfies ResolvedLotaRuntimeConfig
@@ -121,6 +129,22 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
121
129
  socialChatHistoryService: yield* SocialChatHistoryServiceTag,
122
130
  learnedSkillService: yield* LearnedSkillServiceTag,
123
131
  memoryService: yield* MemoryServiceTag,
132
+ runtimeAdapters: yield* RuntimeAdaptersServiceTag,
133
+ agentConfig: yield* AgentConfigServiceTag,
134
+ agentFactoryConfig: yield* AgentFactoryServiceTag,
135
+ queues: yield* LotaQueuesServiceTag,
136
+ autonomousJobService: yield* AutonomousJobServiceTag,
137
+ contextCompactionService: yield* ContextCompactionServiceTag,
138
+ threadService: yield* ThreadServiceTag,
139
+ planAgentHeartbeatService: yield* PlanAgentHeartbeatServiceTag,
140
+ planSchedulerService: yield* PlanSchedulerServiceTag,
141
+ planDeadlineService: yield* PlanDeadlineServiceTag,
142
+ planExecutorService: yield* PlanExecutorServiceTag,
143
+ planCycleService: yield* PlanCycleServiceTag,
144
+ threadTitleService: yield* ThreadTitleServiceTag,
145
+ recentActivityTitleService: yield* RecentActivityTitleServiceTag,
146
+ aiGateway: yield* AiGatewayTag,
147
+ runtimeConfigService: yield* RuntimeConfigServiceTag,
124
148
  }
125
149
  }),
126
150
  ),
@@ -138,10 +162,32 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
138
162
  socialChatHistoryService,
139
163
  learnedSkillService,
140
164
  memoryService,
165
+ runtimeAdapters,
166
+ agentConfig,
167
+ agentFactoryConfig,
168
+ queues,
169
+ autonomousJobService,
170
+ contextCompactionService,
171
+ threadService,
172
+ planAgentHeartbeatService,
173
+ planSchedulerService,
174
+ planDeadlineService,
175
+ planExecutorService,
176
+ planCycleService,
177
+ threadTitleService,
178
+ recentActivityTitleService,
179
+ aiGateway,
180
+ runtimeConfigService,
141
181
  } = resolvedServices
142
182
 
143
- setLotaSdkRuntime(managedRuntime)
144
- configureRuntimeModuleAccessors({ managedRuntime, runtimeConfig, redisManager })
183
+ // Seed the AI gateway middleware so wrapGenerate/wrapStream/wrapEmbed
184
+ // edges can run Effects without reaching for an ambient runtime slot.
185
+ bindAiGatewayRuntime({
186
+ gateway: aiGateway,
187
+ runtimeConfig: runtimeConfigService,
188
+ runPromise: (effect) => managedRuntime.runPromise(effect),
189
+ runFork: (effect) => managedRuntime.runFork(effect),
190
+ })
145
191
 
146
192
  // ── Schema + plugin + worker + social-chat composition ────────────
147
193
  const pluginRuntime = runtimeConfig.pluginRuntime ?? {}
@@ -164,13 +210,33 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
164
210
  pluginRuntime,
165
211
  connectedPluginDatabases,
166
212
  )
167
- const workers = buildRuntimeWorkerRegistry(runtimeConfig.extraWorkers)
213
+ const workers = buildRuntimeWorkerRegistry(
214
+ queues,
215
+ {
216
+ databaseService: db,
217
+ threadService,
218
+ contextCompactionService,
219
+ autonomousJobService,
220
+ memoryService,
221
+ planAgentHeartbeatService,
222
+ planSchedulerService,
223
+ planDeadlineService,
224
+ planExecutorService,
225
+ planCycleService,
226
+ threadTitleService,
227
+ recentActivityTitleService,
228
+ redisManager,
229
+ },
230
+ runtimeConfig.extraWorkers,
231
+ )
168
232
  const socialChat = createSocialChatRuntime({
233
+ agentConfig,
234
+ agentFactoryConfig,
169
235
  redisClient: redisManager.getConnection() as unknown as Parameters<
170
236
  typeof createSocialChatRuntime
171
237
  >[0]['redisClient'],
172
238
  socialChat: runtimeConfig.socialChat,
173
- services: { learnedSkillService, memoryService, socialChatHistoryService },
239
+ services: { learnedSkillService, memoryService, socialChatHistoryService, runtimeAdapters, queues },
174
240
  })
175
241
  const currentContext = yield* Effect.context()
176
242
  const runPromiseWithCurrentContext = Effect.runPromiseWith(currentContext)
@@ -190,16 +256,15 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
190
256
  runPromiseWithCurrentContext,
191
257
  socialChatShutdown: () => socialChat.shutdown(),
192
258
  disconnectPluginDatabases,
193
- onFinalize: () => {
194
- clearRuntimeModuleAccessors()
195
- clearLotaSdkRuntime()
196
- if (runtimeToken) releaseRuntimeToken(runtimeToken)
197
- },
198
259
  })
199
260
 
200
261
  const lotaRuntime: LotaRuntime = {
201
- runPromise: (effect, options) => managedRuntime.runPromise(effect, options),
202
- runSync: (effect) => managedRuntime.runSync(effect),
262
+ runPromise: <A, E, R>(effect: Effect.Effect<A, E, R>, options?: { readonly signal?: AbortSignal }) =>
263
+ managedRuntime.runPromise(effect as unknown as Effect.Effect<A, E, never>, options),
264
+ runSync: <A, E, R>(effect: Effect.Effect<A, E, R>) =>
265
+ managedRuntime.runSync(effect as unknown as Effect.Effect<A, E, never>),
266
+ runFork: <A, E, R>(effect: Effect.Effect<A, E, R>) =>
267
+ managedRuntime.runFork(effect as unknown as Effect.Effect<A, E, never>),
203
268
  services,
204
269
  lota,
205
270
  redis: {
@@ -235,11 +300,8 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
235
300
  }),
236
301
  ).catch((error) => {
237
302
  if (effectRuntime) {
238
- clearRuntimeModuleAccessors()
239
- clearLotaSdkRuntime()
240
303
  void effectRuntime.dispose().catch(() => undefined)
241
304
  }
242
- if (runtimeToken) releaseRuntimeToken(runtimeToken)
243
305
  throw error
244
306
  })
245
307
  }
@@ -1,8 +1,6 @@
1
1
  import { Effect } from 'effect'
2
2
  import type { z } from 'zod'
3
3
 
4
- import type { AwaitableEffect } from '../effect/awaitable-effect'
5
- import { toAwaitableEffect } from '../effect/awaitable-effect'
6
4
  import { NotFoundError } from '../effect/errors'
7
5
  import { ensureRecordId } from './record-id'
8
6
  import type { SurrealDBService } from './service'
@@ -16,7 +14,7 @@ export abstract class BaseService<T extends z.ZodType> {
16
14
  protected readonly databaseService: SurrealDBService,
17
15
  ) {}
18
16
 
19
- findById(id: unknown): AwaitableEffect<z.infer<T> | null, SurrealDBError> {
17
+ findById(id: unknown): Effect.Effect<z.infer<T> | null, SurrealDBError, never> {
20
18
  return this.databaseService.findOne(
21
19
  this.table,
22
20
  { id: ensureRecordId(id as Parameters<typeof ensureRecordId>[0], this.table) },
@@ -24,61 +22,55 @@ export abstract class BaseService<T extends z.ZodType> {
24
22
  )
25
23
  }
26
24
 
27
- getById(id: unknown): AwaitableEffect<z.infer<T>, SurrealDBError | NotFoundError> {
25
+ getById(id: unknown): Effect.Effect<z.infer<T>, SurrealDBError | NotFoundError, never> {
28
26
  const { table, databaseService, schema } = this
29
- return toAwaitableEffect(
30
- Effect.gen(function* () {
31
- const record = yield* databaseService.findOne(
32
- table,
33
- { id: ensureRecordId(id as Parameters<typeof ensureRecordId>[0], table) },
34
- schema,
35
- )
27
+ return Effect.gen(function* () {
28
+ const record = yield* databaseService.findOne(
29
+ table,
30
+ { id: ensureRecordId(id as Parameters<typeof ensureRecordId>[0], table) },
31
+ schema,
32
+ )
36
33
 
37
- if (!record) {
38
- return yield* new NotFoundError({ resource: table, message: `${table} record not found` })
39
- }
34
+ if (!record) {
35
+ return yield* new NotFoundError({ resource: table, message: `${table} record not found` })
36
+ }
40
37
 
41
- return record
42
- }),
43
- )
38
+ return record
39
+ })
44
40
  }
45
41
 
46
42
  findAll(
47
43
  filter: Record<string, unknown> = {},
48
44
  options?: { limit?: number; offset?: number; orderBy?: keyof z.infer<T> & string; orderDir?: 'ASC' | 'DESC' },
49
- ): AwaitableEffect<z.infer<T>[], SurrealDBError> {
45
+ ): Effect.Effect<z.infer<T>[], SurrealDBError, never> {
50
46
  return this.databaseService.findMany(this.table, filter, this.schema, options)
51
47
  }
52
48
 
53
- create(data: Record<string, unknown>): AwaitableEffect<z.infer<T>, SurrealDBError> {
49
+ create(data: Record<string, unknown>): Effect.Effect<z.infer<T>, SurrealDBError, never> {
54
50
  return this.databaseService.create(this.table, data, this.schema)
55
51
  }
56
52
 
57
- update(id: unknown, data: Record<string, unknown>): AwaitableEffect<z.infer<T>, SurrealDBError | NotFoundError> {
53
+ update(id: unknown, data: Record<string, unknown>): Effect.Effect<z.infer<T>, SurrealDBError | NotFoundError, never> {
58
54
  const { table, databaseService, schema } = this
59
- return toAwaitableEffect(
60
- Effect.gen(function* () {
61
- const updated = yield* databaseService.update(table, id, data, schema)
55
+ return Effect.gen(function* () {
56
+ const updated = yield* databaseService.update(table, id, data, schema)
62
57
 
63
- if (!updated) {
64
- return yield* new NotFoundError({ resource: table, message: `${table} record not found` })
65
- }
58
+ if (!updated) {
59
+ return yield* new NotFoundError({ resource: table, message: `${table} record not found` })
60
+ }
66
61
 
67
- return updated
68
- }),
69
- )
62
+ return updated
63
+ })
70
64
  }
71
65
 
72
- delete(id: unknown): AwaitableEffect<void, SurrealDBError | NotFoundError> {
66
+ delete(id: unknown): Effect.Effect<void, SurrealDBError | NotFoundError, never> {
73
67
  const { table, databaseService } = this
74
- return toAwaitableEffect(
75
- Effect.gen(function* () {
76
- const deleted = yield* databaseService.deleteById(table, id)
68
+ return Effect.gen(function* () {
69
+ const deleted = yield* databaseService.deleteById(table, id)
77
70
 
78
- if (!deleted) {
79
- return yield* new NotFoundError({ resource: table, message: `${table} record not found` })
80
- }
81
- }),
82
- )
71
+ if (!deleted) {
72
+ return yield* new NotFoundError({ resource: table, message: `${table} record not found` })
73
+ }
74
+ })
83
75
  }
84
76
  }