@lota-sdk/core 0.4.9 → 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 (182) hide show
  1. package/package.json +2 -2
  2. package/src/ai/embedding-cache.ts +3 -1
  3. package/src/ai-gateway/ai-gateway.ts +164 -82
  4. package/src/ai-gateway/index.ts +16 -1
  5. package/src/config/agent-defaults.ts +4 -107
  6. package/src/config/agent-types.ts +1 -1
  7. package/src/config/background-processing.ts +1 -1
  8. package/src/config/index.ts +0 -1
  9. package/src/config/logger.ts +22 -25
  10. package/src/config/thread-defaults.ts +1 -10
  11. package/src/create-runtime.ts +145 -670
  12. package/src/db/base.service.ts +30 -38
  13. package/src/db/memory-query-builder.ts +2 -1
  14. package/src/db/memory-store.ts +29 -20
  15. package/src/db/memory.ts +188 -195
  16. package/src/db/service-normalization.ts +97 -64
  17. package/src/db/service.ts +496 -384
  18. package/src/db/startup.ts +30 -19
  19. package/src/effect/helpers.ts +30 -5
  20. package/src/effect/index.ts +7 -7
  21. package/src/effect/layers.ts +75 -72
  22. package/src/effect/services.ts +15 -11
  23. package/src/embeddings/provider.ts +65 -71
  24. package/src/index.ts +13 -12
  25. package/src/queues/autonomous-job.queue.ts +177 -143
  26. package/src/queues/context-compaction.queue.ts +41 -39
  27. package/src/queues/delayed-node-promotion.queue.ts +61 -42
  28. package/src/queues/document-processor.queue.ts +5 -3
  29. package/src/queues/index.ts +1 -0
  30. package/src/queues/memory-consolidation.queue.ts +79 -53
  31. package/src/queues/organization-learning.queue.ts +70 -33
  32. package/src/queues/plan-agent-heartbeat.queue.ts +111 -83
  33. package/src/queues/plan-scheduler.queue.ts +101 -97
  34. package/src/queues/post-chat-memory.queue.ts +56 -46
  35. package/src/queues/queue-factory.ts +146 -69
  36. package/src/queues/queues.service.ts +61 -0
  37. package/src/queues/title-generation.queue.ts +44 -44
  38. package/src/redis/connection.ts +181 -164
  39. package/src/redis/org-memory-lock.ts +24 -9
  40. package/src/redis/redis-lease-lock.ts +8 -1
  41. package/src/redis/stream-context.ts +17 -9
  42. package/src/runtime/agent-identity-overrides.ts +7 -3
  43. package/src/runtime/agent-runtime-policy.ts +10 -5
  44. package/src/runtime/agent-stream-helpers.ts +24 -15
  45. package/src/runtime/chat-run-orchestration.ts +1 -1
  46. package/src/runtime/context-compaction/context-compaction-runtime.ts +28 -32
  47. package/src/runtime/context-compaction/context-compaction.ts +131 -85
  48. package/src/runtime/domain-layer.ts +203 -0
  49. package/src/runtime/execution-plan-visibility.ts +5 -2
  50. package/src/runtime/graph-designer.ts +0 -14
  51. package/src/runtime/helper-model.ts +8 -4
  52. package/src/runtime/index.ts +1 -1
  53. package/src/runtime/indexed-repositories-policy.ts +2 -6
  54. package/src/runtime/memory/memory-block.ts +19 -9
  55. package/src/runtime/memory/memory-pipeline.ts +53 -66
  56. package/src/runtime/memory/memory-scope.ts +33 -29
  57. package/src/runtime/plugin-resolution.ts +58 -62
  58. package/src/runtime/post-turn-side-effects.ts +139 -161
  59. package/src/runtime/retrieval-adapters.ts +4 -4
  60. package/src/runtime/runtime-config.ts +3 -9
  61. package/src/runtime/runtime-extensions.ts +0 -43
  62. package/src/runtime/runtime-lifecycle.ts +124 -0
  63. package/src/runtime/runtime-services.ts +455 -0
  64. package/src/runtime/runtime-worker-registry.ts +113 -30
  65. package/src/runtime/social-chat/social-chat-agent-runner.ts +13 -8
  66. package/src/runtime/social-chat/social-chat-history.ts +24 -13
  67. package/src/runtime/social-chat/social-chat.ts +420 -369
  68. package/src/runtime/team-consultation/team-consultation-orchestrator.ts +64 -57
  69. package/src/runtime/team-consultation/team-consultation-prompts.ts +11 -6
  70. package/src/runtime/thread-chat-helpers.ts +18 -9
  71. package/src/runtime/thread-turn-context.ts +28 -74
  72. package/src/runtime/turn-lifecycle.ts +6 -14
  73. package/src/services/agent-activity.service.ts +169 -176
  74. package/src/services/agent-executor.service.ts +207 -196
  75. package/src/services/artifact.service.ts +10 -5
  76. package/src/services/attachment.service.ts +16 -48
  77. package/src/services/autonomous-job.service.ts +81 -87
  78. package/src/services/background-work.service.ts +54 -0
  79. package/src/services/chat-run-registry.service.ts +3 -1
  80. package/src/services/context-compaction.service.ts +8 -10
  81. package/src/services/document-chunk.service.ts +8 -17
  82. package/src/services/execution-plan/execution-plan-graph.ts +122 -109
  83. package/src/services/execution-plan/execution-plan-schedule.ts +1 -15
  84. package/src/services/execution-plan/execution-plan.service.ts +68 -51
  85. package/src/services/feedback-loop.service.ts +1 -1
  86. package/src/services/global-orchestrator.service.ts +49 -15
  87. package/src/services/graph-full-routing.ts +49 -37
  88. package/src/services/index.ts +1 -0
  89. package/src/services/institutional-memory.service.ts +8 -17
  90. package/src/services/learned-skill.service.ts +38 -35
  91. package/src/services/memory/memory-conversation.ts +10 -5
  92. package/src/services/memory/memory-errors.ts +27 -0
  93. package/src/services/memory/memory-org-memory.ts +14 -3
  94. package/src/services/memory/memory-preseeded.ts +10 -4
  95. package/src/services/memory/memory-utils.ts +2 -1
  96. package/src/services/memory/memory.service.ts +37 -52
  97. package/src/services/memory/rerank.service.ts +3 -11
  98. package/src/services/monitoring-window.service.ts +1 -1
  99. package/src/services/mutating-approval.service.ts +1 -1
  100. package/src/services/node-workspace.service.ts +2 -2
  101. package/src/services/notification.service.ts +16 -4
  102. package/src/services/organization-member.service.ts +1 -1
  103. package/src/services/organization.service.ts +34 -51
  104. package/src/services/ownership-dispatcher.service.ts +148 -95
  105. package/src/services/plan/plan-agent-heartbeat.service.ts +30 -16
  106. package/src/services/plan/plan-agent-query.service.ts +13 -9
  107. package/src/services/plan/plan-approval.service.ts +52 -48
  108. package/src/services/plan/plan-artifact.service.ts +2 -2
  109. package/src/services/plan/plan-builder.service.ts +2 -2
  110. package/src/services/plan/plan-checkpoint.service.ts +1 -1
  111. package/src/services/plan/plan-compiler.service.ts +1 -1
  112. package/src/services/plan/plan-completion-side-effects.ts +99 -113
  113. package/src/services/plan/plan-coordination.service.ts +1 -1
  114. package/src/services/plan/plan-cycle.service.ts +171 -202
  115. package/src/services/plan/plan-deadline.service.ts +304 -307
  116. package/src/services/plan/plan-event-delivery.service.ts +84 -72
  117. package/src/services/plan/plan-executor-context.ts +2 -0
  118. package/src/services/plan/plan-executor-graph.ts +375 -353
  119. package/src/services/plan/plan-executor-helpers.ts +60 -75
  120. package/src/services/plan/plan-executor.service.ts +494 -489
  121. package/src/services/plan/plan-run.service.ts +12 -19
  122. package/src/services/plan/plan-scheduler.service.ts +89 -82
  123. package/src/services/plan/plan-template.service.ts +1 -1
  124. package/src/services/plan/plan-transaction-events.ts +8 -5
  125. package/src/services/plan/plan-validator.service.ts +1 -1
  126. package/src/services/plan/plan-workspace.service.ts +17 -11
  127. package/src/services/plugin-executor.service.ts +26 -21
  128. package/src/services/quality-metrics.service.ts +1 -1
  129. package/src/services/queue-job.service.ts +8 -17
  130. package/src/services/recent-activity-title.service.ts +22 -10
  131. package/src/services/recent-activity.service.ts +1 -1
  132. package/src/services/skill-resolver.service.ts +1 -1
  133. package/src/services/social-chat-history.service.ts +37 -20
  134. package/src/services/system-executor.service.ts +25 -20
  135. package/src/services/thread/thread-bootstrap.ts +37 -19
  136. package/src/services/thread/thread-listing.ts +2 -1
  137. package/src/services/thread/thread-memory-block.ts +18 -5
  138. package/src/services/thread/thread-message.service.ts +30 -13
  139. package/src/services/thread/thread-title.service.ts +1 -1
  140. package/src/services/thread/thread-turn-execution.ts +87 -83
  141. package/src/services/thread/thread-turn-preparation.service.ts +65 -40
  142. package/src/services/thread/thread-turn-streaming.ts +32 -36
  143. package/src/services/thread/thread-turn.ts +43 -29
  144. package/src/services/thread/thread.service.ts +32 -8
  145. package/src/services/user.service.ts +1 -1
  146. package/src/services/write-intent-validator.service.ts +1 -1
  147. package/src/storage/attachment-storage.service.ts +7 -4
  148. package/src/storage/generated-document-storage.service.ts +1 -1
  149. package/src/system-agents/context-compaction.agent.ts +1 -1
  150. package/src/system-agents/helper-agent-options.ts +1 -1
  151. package/src/system-agents/memory-reranker.agent.ts +1 -1
  152. package/src/system-agents/memory.agent.ts +1 -1
  153. package/src/system-agents/recent-activity-title-refiner.agent.ts +9 -6
  154. package/src/system-agents/regular-chat-memory-digest.agent.ts +1 -1
  155. package/src/system-agents/skill-extractor.agent.ts +1 -1
  156. package/src/system-agents/skill-manager.agent.ts +1 -1
  157. package/src/system-agents/thread-router.agent.ts +23 -20
  158. package/src/system-agents/title-generator.agent.ts +1 -1
  159. package/src/tools/execution-plan.tool.ts +36 -20
  160. package/src/tools/fetch-webpage.tool.ts +30 -22
  161. package/src/tools/firecrawl-client.ts +1 -6
  162. package/src/tools/plan-approval.tool.ts +9 -1
  163. package/src/tools/remember-memory.tool.ts +3 -6
  164. package/src/tools/research-topic.tool.ts +12 -3
  165. package/src/tools/search-web.tool.ts +26 -18
  166. package/src/tools/search.tool.ts +4 -5
  167. package/src/tools/team-think.tool.ts +139 -121
  168. package/src/utils/async.ts +15 -6
  169. package/src/utils/errors.ts +27 -15
  170. package/src/workers/bootstrap.ts +34 -58
  171. package/src/workers/memory-consolidation.worker.ts +4 -1
  172. package/src/workers/organization-learning.worker.ts +16 -3
  173. package/src/workers/regular-chat-memory-digest.helpers.ts +3 -4
  174. package/src/workers/regular-chat-memory-digest.runner.ts +46 -29
  175. package/src/workers/skill-extraction.runner.ts +13 -15
  176. package/src/workers/worker-utils.ts +14 -8
  177. package/src/config/search.ts +0 -3
  178. package/src/effect/awaitable-effect.ts +0 -87
  179. package/src/effect/runtime-ref.ts +0 -25
  180. package/src/effect/runtime.ts +0 -31
  181. package/src/redis/runtime-connection.ts +0 -10
  182. package/src/runtime/agent-types.ts +0 -1
@@ -1,5 +1,6 @@
1
1
  import { Context, Schema, Effect, Layer } from 'effect'
2
2
 
3
+ import type { ResolvedAgentConfig } from '../../config/agent-defaults'
3
4
  import { aiLogger } from '../../config/logger'
4
5
  import type { Memory } from '../../db/memory'
5
6
  import { isUniqueIndexConflict } from '../../db/memory-store.helpers'
@@ -12,7 +13,7 @@ import type {
12
13
  MemoryType,
13
14
  RelationType,
14
15
  } from '../../db/memory-types'
15
- import { DatabaseServiceTag, RuntimeConfigServiceTag } from '../../effect/services'
16
+ import { AgentConfigServiceTag, DatabaseServiceTag, RuntimeConfigServiceTag } from '../../effect/services'
16
17
  import { withOrgMemoryLockEffect } from '../../redis/org-memory-lock'
17
18
  import type { HelperModelRuntime } from '../../runtime/helper-model'
18
19
  import { HelperModelTag } from '../../runtime/helper-model'
@@ -24,6 +25,9 @@ import {
24
25
  } from '../../runtime/retrieval-adapters'
25
26
  import type { ResolvedLotaRuntimeConfig } from '../../runtime/runtime-config'
26
27
  import { clampImportance, compactWhitespace } from '../../utils/string'
28
+ import { BackgroundWorkService } from '../background-work.service'
29
+ import type { MemoryServiceError } from './memory-errors'
30
+ import { tryMemoryPromise as memoryTryPromise } from './memory-errors'
27
31
  import type { MemoryRerankOutput } from './memory-rerank'
28
32
  import { formatMemoryResults, formatRerankedResults, getCandidateLimit } from './memory-utils'
29
33
  export type { MemoryRerankOutput } from './memory-rerank'
@@ -48,36 +52,10 @@ const ONBOARDING_MEMORY_EXTRACTION_PROMPT =
48
52
  const DIRECT_MEMORY_ASSESSMENT_PROMPT =
49
53
  'The user is submitting a direct memory candidate. Keep the wording faithful. Return one fact only when the statement is durable enough for memory; otherwise return no facts.'
50
54
 
51
- class MemoryServiceError extends Schema.TaggedErrorClass<MemoryServiceError>()('MemoryServiceError', {
52
- message: Schema.String,
53
- cause: Schema.Defect,
54
- }) {}
55
-
56
55
  class InvalidAgentNameError extends Schema.TaggedErrorClass<InvalidAgentNameError>()('InvalidAgentNameError', {
57
56
  agentName: Schema.String,
58
57
  }) {}
59
58
 
60
- function memoryTryPromise<A>(
61
- message: string,
62
- thunk: () => PromiseLike<A> | Effect.Effect<A, unknown>,
63
- ): Effect.Effect<A, MemoryServiceError> {
64
- return Effect.suspend(() => {
65
- try {
66
- const value = thunk()
67
- if (Effect.isEffect(value)) {
68
- return value.pipe(Effect.mapError((cause) => new MemoryServiceError({ message, cause })))
69
- }
70
-
71
- return Effect.tryPromise({
72
- try: () => Promise.resolve(value),
73
- catch: (cause) => new MemoryServiceError({ message, cause }),
74
- })
75
- } catch (cause) {
76
- return Effect.fail(new MemoryServiceError({ message, cause }))
77
- }
78
- })
79
- }
80
-
81
59
  type EffectSuccess<T> = T extends Effect.Effect<infer A, infer _E, infer _R> ? A : Awaited<T>
82
60
 
83
61
  function searchMemoriesEffect({
@@ -200,17 +178,18 @@ interface MemoryServiceDeps {
200
178
  rerankService: ReturnType<typeof makeRerankService>
201
179
  helperModelRuntime: HelperModelRuntime
202
180
  orgMemoryCache: OrgMemoryCache
181
+ agentConfig: ResolvedAgentConfig
203
182
  }
204
183
 
205
184
  export function createMemoryService(deps: MemoryServiceDeps) {
206
- const { runtimeConfig, helperModelRuntime, orgMemoryCache } = deps
185
+ const { runtimeConfig, helperModelRuntime, orgMemoryCache, agentConfig } = deps
207
186
  const resolveRerankService = () => deps.rerankService
208
187
  const service = {
209
188
  searchOrganizationMemories: Effect.fn('MemoryService.searchOrganizationMemories')(function* (
210
189
  orgId: string,
211
190
  query: string,
212
191
  ) {
213
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
192
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
214
193
  aiLogger.debug`Organization memory search requested (orgId: ${orgId}, scopeId: ${orgScopeId}, queryLength: ${query.length})`
215
194
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
216
195
  const results = yield* searchMemoriesEffect({
@@ -228,7 +207,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
228
207
 
229
208
  getStaleMemories(orgId: string) {
230
209
  return Effect.gen(function* () {
231
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
210
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
232
211
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
233
212
  return yield* memoryTryPromise('Failed to load stale memories.', () => memory.getStaleMemories(orgScopeId))
234
213
  }).pipe(
@@ -250,7 +229,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
250
229
  query: string,
251
230
  options?: { fastMode?: boolean; limit?: number },
252
231
  ) {
253
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
232
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
254
233
  aiLogger.debug`searchOrganizationMemoriesRaw - orgId: "${orgId}", scopeId: "${orgScopeId}"`
255
234
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
256
235
  const fastMode = options?.fastMode ?? true
@@ -274,12 +253,12 @@ export function createMemoryService(deps: MemoryServiceDeps) {
274
253
  agentName: string,
275
254
  query: string,
276
255
  ) {
277
- if (!isRoutableAgentName(agentName)) {
256
+ if (!isRoutableAgentName(agentConfig, agentName)) {
278
257
  aiLogger.debug`Agent memory search skipped - invalid agentName: ${agentName}`
279
258
  return 'No stored memories.'
280
259
  }
281
260
 
282
- const scoped = agentScopeId(orgId, agentName)
261
+ const scoped = yield* agentScopeId(orgId, agentName)
283
262
  aiLogger.debug`Agent memory search requested (orgId: ${orgId}, agentName: ${agentName}, scopeId: ${scoped}, queryLength: ${query.length})`
284
263
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
285
264
  const results = yield* searchMemoriesEffect({
@@ -305,8 +284,9 @@ export function createMemoryService(deps: MemoryServiceDeps) {
305
284
  }) {
306
285
  const { orgId, ...listOptions } = params
307
286
  const orgMemory = yield* getOrgMemory(orgMemoryCache, orgId)
287
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
308
288
  return yield* memoryTryPromise('Failed to list organization memory records.', () =>
309
- orgMemory.list({ scopeId: scopeId(ORG_SCOPE_PREFIX, orgId), ...listOptions }),
289
+ orgMemory.list({ scopeId: orgScopeId, ...listOptions }),
310
290
  )
311
291
  }),
312
292
 
@@ -334,7 +314,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
334
314
  }) {
335
315
  const limit = Math.min(runtimeConfig.memory.searchK, MAX_MEMORY_RESULTS_PER_SCOPE)
336
316
  const candidateLimit = fastMode ? limit : getCandidateLimit(limit)
337
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
317
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
338
318
  const orgMemory = yield* getOrgMemory(orgMemoryCache, orgId)
339
319
 
340
320
  const retrievalTasks = [
@@ -351,8 +331,8 @@ export function createMemoryService(deps: MemoryServiceDeps) {
351
331
  },
352
332
  ]
353
333
 
354
- if (isRoutableAgentName(agentName)) {
355
- const agentScoped = agentScopeId(orgId, agentName)
334
+ if (isRoutableAgentName(agentConfig, agentName)) {
335
+ const agentScoped = yield* agentScopeId(orgId, agentName)
356
336
  retrievalTasks.push({
357
337
  scopeTag: `agent:${agentName}`,
358
338
  retrieve: () =>
@@ -367,7 +347,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
367
347
  }
368
348
 
369
349
  const results = yield* memoryTryPromise('Failed to execute scoped memory retrieval.', () =>
370
- executeScopedRetrieval<MemorySearchResult>(retrievalTasks),
350
+ executeScopedRetrieval(retrievalTasks),
371
351
  )
372
352
  const totalCandidates = countScopedRetrievalCandidates(results)
373
353
  aiLogger.debug`Batched memory search candidates (scopes: ${results.length}, total: ${totalCandidates})`
@@ -409,9 +389,10 @@ export function createMemoryService(deps: MemoryServiceDeps) {
409
389
  }) {
410
390
  return Effect.gen(function* () {
411
391
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
392
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
412
393
  return yield* memoryTryPromise('Failed to create organization memory.', () =>
413
394
  memory.insert(content, {
414
- scopeId: scopeId(ORG_SCOPE_PREFIX, orgId),
395
+ scopeId: orgScopeId,
415
396
  memoryType,
416
397
  importance: importance ?? 1,
417
398
  durability,
@@ -421,8 +402,8 @@ export function createMemoryService(deps: MemoryServiceDeps) {
421
402
  }).pipe(
422
403
  Effect.withSpan('MemoryService.createOrganizationMemory'),
423
404
  Effect.tap(() =>
424
- Effect.sync(() => {
425
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
405
+ Effect.gen(function* () {
406
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
426
407
  aiLogger.debug`createOrganizationMemory - orgId: "${orgId}", scopeId: "${orgScopeId}", content preview: "${content.slice(0, 50)}"`
427
408
  }),
428
409
  ),
@@ -470,12 +451,12 @@ export function createMemoryService(deps: MemoryServiceDeps) {
470
451
  metadata?: Record<string, unknown>
471
452
  importance?: number
472
453
  }) {
473
- if (!isRoutableAgentName(agentName)) {
454
+ if (!isRoutableAgentName(agentConfig, agentName)) {
474
455
  return Effect.fail(new InvalidAgentNameError({ agentName }))
475
456
  }
476
457
 
477
- const scoped = agentScopeId(orgId, agentName)
478
458
  return Effect.gen(function* () {
459
+ const scoped = yield* agentScopeId(orgId, agentName)
479
460
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
480
461
  return yield* memoryTryPromise('Failed to create agent memory.', () =>
481
462
  memory.insert(content, {
@@ -548,17 +529,19 @@ export function createMemoryService(deps: MemoryServiceDeps) {
548
529
  if (params.facts.length === 0) return
549
530
 
550
531
  const orgMemory = yield* getOrgMemory(orgMemoryCache, params.orgId)
532
+ const orgScopeIdValue = yield* scopeId(ORG_SCOPE_PREFIX, params.orgId)
551
533
  const scopes: AddOptions[] = [
552
534
  {
553
- scopeId: scopeId(ORG_SCOPE_PREFIX, params.orgId),
535
+ scopeId: orgScopeIdValue,
554
536
  memoryType: ORG_MEMORY_TYPE,
555
537
  metadata: { orgId: params.orgId, source: params.source, ...params.sourceMetadata },
556
538
  },
557
539
  ]
558
540
 
559
- for (const scopedAgentName of resolveAgentScopeNames(undefined, params.agentNames ?? [])) {
541
+ for (const scopedAgentName of resolveAgentScopeNames(agentConfig, undefined, params.agentNames ?? [])) {
542
+ const agentScopedValue = yield* agentScopeId(params.orgId, scopedAgentName)
560
543
  scopes.push({
561
- scopeId: agentScopeId(params.orgId, scopedAgentName),
544
+ scopeId: agentScopedValue,
562
545
  memoryType: ORG_MEMORY_TYPE,
563
546
  metadata: {
564
547
  orgId: params.orgId,
@@ -621,7 +604,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
621
604
  return
622
605
  }
623
606
 
624
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
607
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
625
608
  aiLogger.debug`addConversationMemories - orgId: "${orgId}", scopeId: "${orgScopeId}", sourceId: ${sourceId ?? 'none'}`
626
609
 
627
610
  const onboardingActive = onboardStatus !== undefined && onboardStatus !== 'completed'
@@ -638,8 +621,8 @@ export function createMemoryService(deps: MemoryServiceDeps) {
638
621
  },
639
622
  ]
640
623
 
641
- for (const scopedAgentName of resolveAgentScopeNames(agentName, agentNames)) {
642
- const agentId = agentScopeId(orgId, scopedAgentName)
624
+ for (const scopedAgentName of resolveAgentScopeNames(agentConfig, agentName, agentNames)) {
625
+ const agentId = yield* agentScopeId(orgId, scopedAgentName)
643
626
  scopes.push({
644
627
  scopeId: agentId,
645
628
  memoryType: ORG_MEMORY_TYPE,
@@ -676,7 +659,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
676
659
  }
677
660
 
678
661
  export class MemoryServiceTag extends Context.Service<MemoryServiceTag, ReturnType<typeof createMemoryService>>()(
679
- 'MemoryService',
662
+ '@lota-sdk/core/MemoryService',
680
663
  ) {}
681
664
 
682
665
  export const MemoryServiceLive = Layer.effect(
@@ -686,7 +669,9 @@ export const MemoryServiceLive = Layer.effect(
686
669
  const runtimeConfig = yield* RuntimeConfigServiceTag
687
670
  const rerankService = yield* RerankServiceTag
688
671
  const helperModelRuntime = yield* HelperModelTag
689
- const orgMemoryCache = yield* makeOrgMemoryCache({ db, runtimeConfig, helperModelRuntime })
690
- return createMemoryService({ runtimeConfig, rerankService, helperModelRuntime, orgMemoryCache })
672
+ const background = yield* BackgroundWorkService
673
+ const agentConfig = yield* AgentConfigServiceTag
674
+ const orgMemoryCache = yield* makeOrgMemoryCache({ db, runtimeConfig, helperModelRuntime, background })
675
+ return createMemoryService({ runtimeConfig, rerankService, helperModelRuntime, orgMemoryCache, agentConfig })
691
676
  }),
692
677
  )
@@ -3,6 +3,7 @@ import * as Schema from 'effect/Schema'
3
3
  import { z } from 'zod'
4
4
 
5
5
  import { OPENROUTER_FAST_RERANK_MODEL_ID } from '../../config/model-constants'
6
+ import { makeEffectTryPromiseWithOperation } from '../../effect/helpers'
6
7
  import { RuntimeConfigServiceTag } from '../../effect/services'
7
8
  import { toValidationError } from '../../effect/zod'
8
9
  import { normalizeDirectOpenRouterModelId, resolveOpenRouterApiKey } from '../../openrouter/direct-provider'
@@ -20,16 +21,7 @@ function toRerankServiceError(operation: string, message: string, cause: unknown
20
21
  return new RerankServiceError({ operation, message, cause })
21
22
  }
22
23
 
23
- function tryRerankPromise<A>(
24
- operation: string,
25
- message: string,
26
- thunk: () => PromiseLike<A> | A,
27
- ): Effect.Effect<A, RerankServiceError> {
28
- return Effect.tryPromise({
29
- try: () => Promise.resolve(thunk()),
30
- catch: (cause) => toRerankServiceError(operation, message, cause),
31
- })
32
- }
24
+ const tryRerankPromise = makeEffectTryPromiseWithOperation(toRerankServiceError)
33
25
 
34
26
  const RerankResponseSchema = z
35
27
  .object({
@@ -197,7 +189,7 @@ export function makeRerankService(config: ResolvedLotaRuntimeConfig) {
197
189
  }
198
190
 
199
191
  export class RerankServiceTag extends Context.Service<RerankServiceTag, ReturnType<typeof makeRerankService>>()(
200
- 'RerankService',
192
+ '@lota-sdk/core/RerankService',
201
193
  ) {}
202
194
 
203
195
  export const RerankServiceLive = Layer.effect(
@@ -97,7 +97,7 @@ export function makeMonitoringWindowService(planSchedulerService: ReturnType<typ
97
97
  export class MonitoringWindowServiceTag extends Context.Service<
98
98
  MonitoringWindowServiceTag,
99
99
  ReturnType<typeof makeMonitoringWindowService>
100
- >()('MonitoringWindowService') {}
100
+ >()('@lota-sdk/core/MonitoringWindowService') {}
101
101
 
102
102
  export const MonitoringWindowServiceLive = Layer.effect(
103
103
  MonitoringWindowServiceTag,
@@ -105,7 +105,7 @@ export function makeMutatingApprovalService(threadMessageService: ReturnType<typ
105
105
  export class MutatingApprovalServiceTag extends Context.Service<
106
106
  MutatingApprovalServiceTag,
107
107
  ReturnType<typeof makeMutatingApprovalService>
108
- >()('MutatingApprovalService') {}
108
+ >()('@lota-sdk/core/MutatingApprovalService') {}
109
109
 
110
110
  export const MutatingApprovalServiceLive = Layer.effect(
111
111
  MutatingApprovalServiceTag,
@@ -194,6 +194,6 @@ export const nodeWorkspaceService = makeNodeWorkspaceService()
194
194
  export class NodeWorkspaceServiceTag extends Context.Service<
195
195
  NodeWorkspaceServiceTag,
196
196
  ReturnType<typeof makeNodeWorkspaceService>
197
- >()('NodeWorkspaceService') {}
197
+ >()('@lota-sdk/core/NodeWorkspaceService') {}
198
198
 
199
- export const NodeWorkspaceServiceLive = Layer.succeed(NodeWorkspaceServiceTag, nodeWorkspaceService)
199
+ export const NodeWorkspaceServiceLive = Layer.sync(NodeWorkspaceServiceTag, () => makeNodeWorkspaceService())
@@ -1,5 +1,5 @@
1
1
  import type { NotificationSeverity } from '@lota-sdk/shared'
2
- import { Context, Layer } from 'effect'
2
+ import { Context, Effect, Layer } from 'effect'
3
3
 
4
4
  export interface NotificationPayload {
5
5
  organizationId: string
@@ -17,9 +17,12 @@ export interface NotificationService {
17
17
  notify(payload: NotificationPayload): Promise<void>
18
18
  remind(payload: NotificationPayload): Promise<void>
19
19
  escalate(payload: NotificationPayload): Promise<void>
20
+ notifyEffect?(payload: NotificationPayload): Effect.Effect<void, never>
21
+ remindEffect?(payload: NotificationPayload): Effect.Effect<void, never>
22
+ escalateEffect?(payload: NotificationPayload): Effect.Effect<void, never>
20
23
  }
21
24
 
22
- export function makeNotificationService(): NotificationService {
25
+ export function makeNotificationService(): Required<NotificationService> {
23
26
  return {
24
27
  notify(_payload: NotificationPayload): Promise<void> {
25
28
  return Promise.resolve()
@@ -30,11 +33,20 @@ export function makeNotificationService(): NotificationService {
30
33
  escalate(_payload: NotificationPayload): Promise<void> {
31
34
  return Promise.resolve()
32
35
  },
36
+ notifyEffect(_payload: NotificationPayload): Effect.Effect<void, never> {
37
+ return Effect.void
38
+ },
39
+ remindEffect(_payload: NotificationPayload): Effect.Effect<void, never> {
40
+ return Effect.void
41
+ },
42
+ escalateEffect(_payload: NotificationPayload): Effect.Effect<void, never> {
43
+ return Effect.void
44
+ },
33
45
  }
34
46
  }
35
47
 
36
48
  export class NotificationServiceTag extends Context.Service<NotificationServiceTag, NotificationService>()(
37
- 'NotificationService',
49
+ '@lota-sdk/core/NotificationService',
38
50
  ) {}
39
51
 
40
- export const NotificationServiceLive = Layer.succeed(NotificationServiceTag, makeNotificationService())
52
+ export const NotificationServiceLive = Layer.sync(NotificationServiceTag, () => makeNotificationService())
@@ -164,7 +164,7 @@ export function makeOrganizationMemberService(db: SurrealDBService) {
164
164
  export class OrganizationMemberServiceTag extends Context.Service<
165
165
  OrganizationMemberServiceTag,
166
166
  ReturnType<typeof makeOrganizationMemberService>
167
- >()('OrganizationMemberService') {}
167
+ >()('@lota-sdk/core/OrganizationMemberService') {}
168
168
 
169
169
  export const OrganizationMemberServiceLive = Layer.effect(
170
170
  OrganizationMemberServiceTag,
@@ -1,6 +1,6 @@
1
- import { recordIdSchema, recordIdStringSchema } from '@lota-sdk/shared'
1
+ import { sdkOrganizationRecordSchema, sdkOrganizationSchema } from '@lota-sdk/shared'
2
+ import type { SdkOrganization, SdkOrganizationRecord } from '@lota-sdk/shared'
2
3
  import { Context, Schema, Effect, Layer } from 'effect'
3
- import { z } from 'zod'
4
4
 
5
5
  import { ensureRecordId, recordIdToString } from '../db/record-id'
6
6
  import type { RecordIdInput, RecordIdRef } from '../db/record-id'
@@ -10,30 +10,7 @@ import { NotFoundError } from '../effect/errors'
10
10
  import { DatabaseServiceTag } from '../effect/services'
11
11
  import { toIsoDateTimeString, toOptionalIsoDateTimeString } from '../utils/date-time'
12
12
 
13
- const organizationRecordSchema = z.object({
14
- id: recordIdSchema,
15
- name: z.string(),
16
- regularChatDigestLastThreadCursorCreatedAt: z.coerce.date().optional(),
17
- regularChatDigestLastThreadCursorId: z.string().optional(),
18
- skillExtractionLastCursorId: z.string().optional(),
19
- skillExtractionLastCursorCreatedAt: z.coerce.date().optional(),
20
- createdAt: z.coerce.date(),
21
- updatedAt: z.coerce.date(),
22
- })
23
-
24
- const sdkOrganizationSchema = z.object({
25
- id: recordIdStringSchema,
26
- name: z.string(),
27
- regularChatDigestLastThreadCursorCreatedAt: z.iso.datetime().nullable().optional(),
28
- regularChatDigestLastThreadCursorId: z.string().nullable().optional(),
29
- skillExtractionLastCursorId: z.string().nullable().optional(),
30
- skillExtractionLastCursorCreatedAt: z.iso.datetime().nullable().optional(),
31
- createdAt: z.iso.datetime(),
32
- updatedAt: z.iso.datetime(),
33
- })
34
-
35
- export type SdkOrganizationRecord = z.infer<typeof organizationRecordSchema>
36
- export type SdkOrganization = z.infer<typeof sdkOrganizationSchema>
13
+ export type { SdkOrganization, SdkOrganizationRecord }
37
14
 
38
15
  interface BackgroundCursor {
39
16
  createdAt: Date
@@ -49,18 +26,22 @@ function toOptionalCursorTimestamp(value: unknown): string | null {
49
26
  return toOptionalIsoDateTimeString(value) ?? null
50
27
  }
51
28
 
52
- function toPublic(record: SdkOrganizationRecord): SdkOrganization {
53
- return sdkOrganizationSchema.parse({
54
- id: recordIdToString(ensureRecordId(record.id as RecordIdInput, TABLES.ORGANIZATION), TABLES.ORGANIZATION),
55
- name: record.name,
56
- regularChatDigestLastThreadCursorCreatedAt: toOptionalCursorTimestamp(
57
- record.regularChatDigestLastThreadCursorCreatedAt,
58
- ),
59
- regularChatDigestLastThreadCursorId: record.regularChatDigestLastThreadCursorId ?? null,
60
- skillExtractionLastCursorId: record.skillExtractionLastCursorId ?? null,
61
- skillExtractionLastCursorCreatedAt: toOptionalCursorTimestamp(record.skillExtractionLastCursorCreatedAt),
62
- createdAt: toIsoDateTimeString(record.createdAt),
63
- updatedAt: toIsoDateTimeString(record.updatedAt),
29
+ function toPublicEffect(record: SdkOrganizationRecord): Effect.Effect<SdkOrganization, OrganizationServiceError> {
30
+ return Effect.try({
31
+ try: () =>
32
+ sdkOrganizationSchema.parse({
33
+ id: recordIdToString(ensureRecordId(record.id as RecordIdInput, TABLES.ORGANIZATION), TABLES.ORGANIZATION),
34
+ name: record.name,
35
+ regularChatDigestLastThreadCursorCreatedAt: toOptionalCursorTimestamp(
36
+ record.regularChatDigestLastThreadCursorCreatedAt,
37
+ ),
38
+ regularChatDigestLastThreadCursorId: record.regularChatDigestLastThreadCursorId ?? null,
39
+ skillExtractionLastCursorId: record.skillExtractionLastCursorId ?? null,
40
+ skillExtractionLastCursorCreatedAt: toOptionalCursorTimestamp(record.skillExtractionLastCursorCreatedAt),
41
+ createdAt: toIsoDateTimeString(record.createdAt),
42
+ updatedAt: toIsoDateTimeString(record.updatedAt),
43
+ }),
44
+ catch: (cause) => toOrganizationServiceError('toPublic', cause),
64
45
  })
65
46
  }
66
47
 
@@ -78,26 +59,26 @@ function toOrganizationServiceError(operation: string, cause: unknown): Organiza
78
59
 
79
60
  export function makeOrganizationService(db: SurrealDBService) {
80
61
  function createOrganization(params: { name: string }) {
81
- return db.create(TABLES.ORGANIZATION, { name: params.name }, organizationRecordSchema).pipe(
62
+ return db.create(TABLES.ORGANIZATION, { name: params.name }, sdkOrganizationRecordSchema).pipe(
82
63
  Effect.mapError((cause) => toOrganizationServiceError('createOrganization', cause)),
83
- Effect.map(toPublic),
64
+ Effect.flatMap(toPublicEffect),
84
65
  )
85
66
  }
86
67
 
87
68
  function upsertOrganization(params: { id: RecordIdInput; name: string }) {
88
69
  const organizationRef = ensureRecordId(params.id, TABLES.ORGANIZATION)
89
- return db.upsert(TABLES.ORGANIZATION, organizationRef, { name: params.name }, organizationRecordSchema).pipe(
70
+ return db.upsert(TABLES.ORGANIZATION, organizationRef, { name: params.name }, sdkOrganizationRecordSchema).pipe(
90
71
  Effect.mapError((cause) => toOrganizationServiceError('upsertOrganization', cause)),
91
- Effect.map(toPublic),
72
+ Effect.flatMap(toPublicEffect),
92
73
  )
93
74
  }
94
75
 
95
76
  function listOrganizations() {
96
77
  return db
97
- .findMany(TABLES.ORGANIZATION, {}, organizationRecordSchema, { orderBy: 'createdAt', orderDir: 'ASC' })
78
+ .findMany(TABLES.ORGANIZATION, {}, sdkOrganizationRecordSchema, { orderBy: 'createdAt', orderDir: 'ASC' })
98
79
  .pipe(
99
80
  Effect.mapError((cause) => toOrganizationServiceError('listOrganizations', cause)),
100
- Effect.map((records) => records.map(toPublic)),
81
+ Effect.flatMap((records) => Effect.forEach(records, toPublicEffect)),
101
82
  )
102
83
  }
103
84
 
@@ -106,7 +87,7 @@ export function makeOrganizationService(db: SurrealDBService) {
106
87
  .findOne(
107
88
  TABLES.ORGANIZATION,
108
89
  { id: ensureRecordId(organizationId, TABLES.ORGANIZATION) },
109
- organizationRecordSchema,
90
+ sdkOrganizationRecordSchema,
110
91
  )
111
92
  .pipe(
112
93
  Effect.mapError((cause) => toOrganizationServiceError('getOrganizationRecord', cause)),
@@ -117,7 +98,9 @@ export function makeOrganizationService(db: SurrealDBService) {
117
98
  }
118
99
 
119
100
  function getOrganization(organizationId: RecordIdInput) {
120
- return getOrganizationRecord(ensureRecordId(organizationId, TABLES.ORGANIZATION)).pipe(Effect.map(toPublic))
101
+ return getOrganizationRecord(ensureRecordId(organizationId, TABLES.ORGANIZATION)).pipe(
102
+ Effect.flatMap(toPublicEffect),
103
+ )
121
104
  }
122
105
 
123
106
  function updateOrganization(organizationId: RecordIdInput, params: { name: string }) {
@@ -126,14 +109,14 @@ export function makeOrganizationService(db: SurrealDBService) {
126
109
  TABLES.ORGANIZATION,
127
110
  ensureRecordId(organizationId, TABLES.ORGANIZATION),
128
111
  { name: params.name },
129
- organizationRecordSchema,
112
+ sdkOrganizationRecordSchema,
130
113
  )
131
114
  .pipe(
132
115
  Effect.mapError((cause) => toOrganizationServiceError('updateOrganization', cause)),
133
116
  Effect.flatMap((updated) =>
134
117
  updated ? Effect.succeed(updated) : Effect.fail(organizationNotFoundError(organizationId)),
135
118
  ),
136
- Effect.map(toPublic),
119
+ Effect.flatMap(toPublicEffect),
137
120
  )
138
121
  }
139
122
 
@@ -161,7 +144,7 @@ export function makeOrganizationService(db: SurrealDBService) {
161
144
  regularChatDigestLastThreadCursorCreatedAt: cursor.createdAt,
162
145
  regularChatDigestLastThreadCursorId: cursor.id,
163
146
  },
164
- organizationRecordSchema,
147
+ sdkOrganizationRecordSchema,
165
148
  )
166
149
  .pipe(
167
150
  Effect.mapError((cause) => toOrganizationServiceError('updateRegularChatDigestCursor', cause)),
@@ -175,7 +158,7 @@ export function makeOrganizationService(db: SurrealDBService) {
175
158
  TABLES.ORGANIZATION,
176
159
  ensureRecordId(organizationId, TABLES.ORGANIZATION),
177
160
  { skillExtractionLastCursorCreatedAt: cursor.createdAt, skillExtractionLastCursorId: cursor.id },
178
- organizationRecordSchema,
161
+ sdkOrganizationRecordSchema,
179
162
  )
180
163
  .pipe(
181
164
  Effect.mapError((cause) => toOrganizationServiceError('updateSkillExtractionCursor', cause)),
@@ -199,7 +182,7 @@ export function makeOrganizationService(db: SurrealDBService) {
199
182
  export class OrganizationServiceTag extends Context.Service<
200
183
  OrganizationServiceTag,
201
184
  ReturnType<typeof makeOrganizationService>
202
- >()('OrganizationService') {}
185
+ >()('@lota-sdk/core/OrganizationService') {}
203
186
 
204
187
  export const OrganizationServiceLive = Layer.effect(
205
188
  OrganizationServiceTag,