@lota-sdk/core 0.4.9 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) 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 +38 -10
  4. package/src/config/agent-defaults.ts +22 -9
  5. package/src/config/agent-types.ts +1 -1
  6. package/src/config/background-processing.ts +1 -1
  7. package/src/config/index.ts +0 -1
  8. package/src/config/logger.ts +20 -7
  9. package/src/config/thread-defaults.ts +12 -4
  10. package/src/create-runtime.ts +69 -656
  11. package/src/db/memory-query-builder.ts +2 -1
  12. package/src/db/memory-store.ts +29 -20
  13. package/src/db/memory.ts +188 -195
  14. package/src/db/service-normalization.ts +97 -64
  15. package/src/db/service.ts +706 -538
  16. package/src/db/startup.ts +30 -19
  17. package/src/effect/awaitable-effect.ts +46 -37
  18. package/src/effect/helpers.ts +30 -5
  19. package/src/effect/index.ts +7 -5
  20. package/src/effect/layers.ts +82 -72
  21. package/src/effect/runtime.ts +18 -3
  22. package/src/effect/services.ts +15 -11
  23. package/src/embeddings/provider.ts +65 -66
  24. package/src/index.ts +13 -11
  25. package/src/queues/autonomous-job.queue.ts +59 -71
  26. package/src/queues/context-compaction.queue.ts +6 -18
  27. package/src/queues/delayed-node-promotion.queue.ts +9 -17
  28. package/src/queues/organization-learning.queue.ts +17 -4
  29. package/src/queues/plan-agent-heartbeat.queue.ts +23 -20
  30. package/src/queues/plan-scheduler.queue.ts +6 -18
  31. package/src/queues/post-chat-memory.queue.ts +6 -18
  32. package/src/queues/queue-factory.ts +128 -50
  33. package/src/queues/title-generation.queue.ts +6 -17
  34. package/src/redis/connection.ts +181 -164
  35. package/src/redis/runtime-connection.ts +13 -3
  36. package/src/redis/stream-context.ts +17 -9
  37. package/src/runtime/agent-runtime-policy.ts +1 -1
  38. package/src/runtime/agent-stream-helpers.ts +15 -11
  39. package/src/runtime/chat-run-orchestration.ts +1 -1
  40. package/src/runtime/context-compaction/context-compaction-runtime.ts +1 -1
  41. package/src/runtime/context-compaction/context-compaction.ts +126 -82
  42. package/src/runtime/domain-layer.ts +192 -0
  43. package/src/runtime/graph-designer.ts +15 -7
  44. package/src/runtime/helper-model.ts +8 -4
  45. package/src/runtime/index.ts +0 -1
  46. package/src/runtime/memory/memory-block.ts +19 -9
  47. package/src/runtime/memory/memory-pipeline.ts +53 -66
  48. package/src/runtime/memory/memory-scope.ts +33 -29
  49. package/src/runtime/plugin-resolution.ts +33 -54
  50. package/src/runtime/post-turn-side-effects.ts +6 -26
  51. package/src/runtime/retrieval-adapters.ts +4 -4
  52. package/src/runtime/runtime-accessors.ts +92 -0
  53. package/src/runtime/runtime-config.ts +3 -3
  54. package/src/runtime/runtime-extensions.ts +20 -9
  55. package/src/runtime/runtime-lifecycle.ts +124 -0
  56. package/src/runtime/runtime-services.ts +386 -0
  57. package/src/runtime/runtime-token.ts +47 -0
  58. package/src/runtime/social-chat/social-chat-agent-runner.ts +7 -5
  59. package/src/runtime/social-chat/social-chat-history.ts +21 -12
  60. package/src/runtime/social-chat/social-chat.ts +401 -365
  61. package/src/runtime/team-consultation/team-consultation-orchestrator.ts +58 -52
  62. package/src/runtime/thread-turn-context.ts +21 -27
  63. package/src/services/agent-activity.service.ts +1 -1
  64. package/src/services/agent-executor.service.ts +179 -187
  65. package/src/services/artifact.service.ts +10 -5
  66. package/src/services/attachment.service.ts +35 -1
  67. package/src/services/autonomous-job.service.ts +58 -56
  68. package/src/services/background-work.service.ts +54 -0
  69. package/src/services/chat-run-registry.service.ts +3 -1
  70. package/src/services/context-compaction.service.ts +1 -1
  71. package/src/services/document-chunk.service.ts +8 -17
  72. package/src/services/execution-plan/execution-plan-graph.ts +74 -52
  73. package/src/services/execution-plan/execution-plan.service.ts +1 -1
  74. package/src/services/feedback-loop.service.ts +1 -1
  75. package/src/services/global-orchestrator.service.ts +33 -10
  76. package/src/services/graph-full-routing.ts +44 -33
  77. package/src/services/index.ts +1 -0
  78. package/src/services/institutional-memory.service.ts +8 -17
  79. package/src/services/learned-skill.service.ts +38 -35
  80. package/src/services/memory/memory-errors.ts +27 -0
  81. package/src/services/memory/memory-org-memory.ts +14 -3
  82. package/src/services/memory/memory-preseeded.ts +10 -4
  83. package/src/services/memory/memory-utils.ts +2 -1
  84. package/src/services/memory/memory.service.ts +26 -44
  85. package/src/services/memory/rerank.service.ts +3 -11
  86. package/src/services/monitoring-window.service.ts +1 -1
  87. package/src/services/mutating-approval.service.ts +1 -1
  88. package/src/services/node-workspace.service.ts +2 -2
  89. package/src/services/notification.service.ts +16 -4
  90. package/src/services/organization-member.service.ts +1 -1
  91. package/src/services/organization.service.ts +34 -51
  92. package/src/services/ownership-dispatcher.service.ts +132 -90
  93. package/src/services/plan/plan-agent-heartbeat.service.ts +1 -1
  94. package/src/services/plan/plan-agent-query.service.ts +1 -1
  95. package/src/services/plan/plan-approval.service.ts +52 -48
  96. package/src/services/plan/plan-artifact.service.ts +2 -2
  97. package/src/services/plan/plan-builder.service.ts +2 -2
  98. package/src/services/plan/plan-checkpoint.service.ts +1 -1
  99. package/src/services/plan/plan-compiler.service.ts +1 -1
  100. package/src/services/plan/plan-completion-side-effects.ts +18 -24
  101. package/src/services/plan/plan-coordination.service.ts +1 -1
  102. package/src/services/plan/plan-cycle.service.ts +171 -164
  103. package/src/services/plan/plan-deadline.service.ts +290 -304
  104. package/src/services/plan/plan-event-delivery.service.ts +44 -39
  105. package/src/services/plan/plan-executor-graph.ts +114 -67
  106. package/src/services/plan/plan-executor-helpers.ts +60 -75
  107. package/src/services/plan/plan-executor.service.ts +550 -467
  108. package/src/services/plan/plan-run.service.ts +12 -19
  109. package/src/services/plan/plan-scheduler.service.ts +27 -33
  110. package/src/services/plan/plan-template.service.ts +1 -1
  111. package/src/services/plan/plan-transaction-events.ts +8 -5
  112. package/src/services/plan/plan-validator.service.ts +1 -1
  113. package/src/services/plan/plan-workspace.service.ts +17 -11
  114. package/src/services/plugin-executor.service.ts +26 -21
  115. package/src/services/quality-metrics.service.ts +1 -1
  116. package/src/services/queue-job.service.ts +8 -17
  117. package/src/services/recent-activity-title.service.ts +17 -9
  118. package/src/services/recent-activity.service.ts +1 -1
  119. package/src/services/skill-resolver.service.ts +1 -1
  120. package/src/services/social-chat-history.service.ts +37 -20
  121. package/src/services/system-executor.service.ts +25 -20
  122. package/src/services/thread/thread-bootstrap.ts +26 -10
  123. package/src/services/thread/thread-listing.ts +2 -1
  124. package/src/services/thread/thread-memory-block.ts +18 -5
  125. package/src/services/thread/thread-message.service.ts +24 -8
  126. package/src/services/thread/thread-title.service.ts +1 -1
  127. package/src/services/thread/thread-turn-execution.ts +1 -1
  128. package/src/services/thread/thread-turn-preparation.service.ts +18 -16
  129. package/src/services/thread/thread-turn-streaming.ts +12 -11
  130. package/src/services/thread/thread-turn.ts +43 -10
  131. package/src/services/thread/thread.service.ts +11 -2
  132. package/src/services/user.service.ts +1 -1
  133. package/src/services/write-intent-validator.service.ts +1 -1
  134. package/src/storage/attachment-storage.service.ts +7 -4
  135. package/src/storage/generated-document-storage.service.ts +1 -1
  136. package/src/system-agents/context-compaction.agent.ts +1 -1
  137. package/src/system-agents/helper-agent-options.ts +1 -1
  138. package/src/system-agents/memory-reranker.agent.ts +1 -1
  139. package/src/system-agents/memory.agent.ts +1 -1
  140. package/src/system-agents/recent-activity-title-refiner.agent.ts +1 -1
  141. package/src/system-agents/regular-chat-memory-digest.agent.ts +1 -1
  142. package/src/system-agents/skill-extractor.agent.ts +1 -1
  143. package/src/system-agents/skill-manager.agent.ts +1 -1
  144. package/src/system-agents/title-generator.agent.ts +1 -1
  145. package/src/tools/execution-plan.tool.ts +28 -17
  146. package/src/tools/fetch-webpage.tool.ts +20 -13
  147. package/src/tools/firecrawl-client.ts +13 -3
  148. package/src/tools/plan-approval.tool.ts +9 -1
  149. package/src/tools/search-web.tool.ts +16 -9
  150. package/src/tools/team-think.tool.ts +2 -2
  151. package/src/utils/async.ts +15 -6
  152. package/src/utils/errors.ts +27 -15
  153. package/src/workers/bootstrap.ts +25 -48
  154. package/src/workers/organization-learning.worker.ts +1 -1
  155. package/src/workers/regular-chat-memory-digest.runner.ts +25 -15
  156. package/src/workers/worker-utils.ts +20 -2
  157. package/src/config/search.ts +0 -3
  158. package/src/runtime/agent-types.ts +0 -1
@@ -24,6 +24,9 @@ import {
24
24
  } from '../../runtime/retrieval-adapters'
25
25
  import type { ResolvedLotaRuntimeConfig } from '../../runtime/runtime-config'
26
26
  import { clampImportance, compactWhitespace } from '../../utils/string'
27
+ import { BackgroundWorkService } from '../background-work.service'
28
+ import type { MemoryServiceError } from './memory-errors'
29
+ import { tryMemoryPromise as memoryTryPromise } from './memory-errors'
27
30
  import type { MemoryRerankOutput } from './memory-rerank'
28
31
  import { formatMemoryResults, formatRerankedResults, getCandidateLimit } from './memory-utils'
29
32
  export type { MemoryRerankOutput } from './memory-rerank'
@@ -48,36 +51,10 @@ const ONBOARDING_MEMORY_EXTRACTION_PROMPT =
48
51
  const DIRECT_MEMORY_ASSESSMENT_PROMPT =
49
52
  '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
53
 
51
- class MemoryServiceError extends Schema.TaggedErrorClass<MemoryServiceError>()('MemoryServiceError', {
52
- message: Schema.String,
53
- cause: Schema.Defect,
54
- }) {}
55
-
56
54
  class InvalidAgentNameError extends Schema.TaggedErrorClass<InvalidAgentNameError>()('InvalidAgentNameError', {
57
55
  agentName: Schema.String,
58
56
  }) {}
59
57
 
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
58
  type EffectSuccess<T> = T extends Effect.Effect<infer A, infer _E, infer _R> ? A : Awaited<T>
82
59
 
83
60
  function searchMemoriesEffect({
@@ -210,7 +187,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
210
187
  orgId: string,
211
188
  query: string,
212
189
  ) {
213
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
190
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
214
191
  aiLogger.debug`Organization memory search requested (orgId: ${orgId}, scopeId: ${orgScopeId}, queryLength: ${query.length})`
215
192
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
216
193
  const results = yield* searchMemoriesEffect({
@@ -228,7 +205,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
228
205
 
229
206
  getStaleMemories(orgId: string) {
230
207
  return Effect.gen(function* () {
231
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
208
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
232
209
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
233
210
  return yield* memoryTryPromise('Failed to load stale memories.', () => memory.getStaleMemories(orgScopeId))
234
211
  }).pipe(
@@ -250,7 +227,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
250
227
  query: string,
251
228
  options?: { fastMode?: boolean; limit?: number },
252
229
  ) {
253
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
230
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
254
231
  aiLogger.debug`searchOrganizationMemoriesRaw - orgId: "${orgId}", scopeId: "${orgScopeId}"`
255
232
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
256
233
  const fastMode = options?.fastMode ?? true
@@ -279,7 +256,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
279
256
  return 'No stored memories.'
280
257
  }
281
258
 
282
- const scoped = agentScopeId(orgId, agentName)
259
+ const scoped = yield* agentScopeId(orgId, agentName)
283
260
  aiLogger.debug`Agent memory search requested (orgId: ${orgId}, agentName: ${agentName}, scopeId: ${scoped}, queryLength: ${query.length})`
284
261
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
285
262
  const results = yield* searchMemoriesEffect({
@@ -305,8 +282,9 @@ export function createMemoryService(deps: MemoryServiceDeps) {
305
282
  }) {
306
283
  const { orgId, ...listOptions } = params
307
284
  const orgMemory = yield* getOrgMemory(orgMemoryCache, orgId)
285
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
308
286
  return yield* memoryTryPromise('Failed to list organization memory records.', () =>
309
- orgMemory.list({ scopeId: scopeId(ORG_SCOPE_PREFIX, orgId), ...listOptions }),
287
+ orgMemory.list({ scopeId: orgScopeId, ...listOptions }),
310
288
  )
311
289
  }),
312
290
 
@@ -334,7 +312,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
334
312
  }) {
335
313
  const limit = Math.min(runtimeConfig.memory.searchK, MAX_MEMORY_RESULTS_PER_SCOPE)
336
314
  const candidateLimit = fastMode ? limit : getCandidateLimit(limit)
337
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
315
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
338
316
  const orgMemory = yield* getOrgMemory(orgMemoryCache, orgId)
339
317
 
340
318
  const retrievalTasks = [
@@ -352,7 +330,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
352
330
  ]
353
331
 
354
332
  if (isRoutableAgentName(agentName)) {
355
- const agentScoped = agentScopeId(orgId, agentName)
333
+ const agentScoped = yield* agentScopeId(orgId, agentName)
356
334
  retrievalTasks.push({
357
335
  scopeTag: `agent:${agentName}`,
358
336
  retrieve: () =>
@@ -367,7 +345,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
367
345
  }
368
346
 
369
347
  const results = yield* memoryTryPromise('Failed to execute scoped memory retrieval.', () =>
370
- executeScopedRetrieval<MemorySearchResult>(retrievalTasks),
348
+ executeScopedRetrieval(retrievalTasks),
371
349
  )
372
350
  const totalCandidates = countScopedRetrievalCandidates(results)
373
351
  aiLogger.debug`Batched memory search candidates (scopes: ${results.length}, total: ${totalCandidates})`
@@ -409,9 +387,10 @@ export function createMemoryService(deps: MemoryServiceDeps) {
409
387
  }) {
410
388
  return Effect.gen(function* () {
411
389
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
390
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
412
391
  return yield* memoryTryPromise('Failed to create organization memory.', () =>
413
392
  memory.insert(content, {
414
- scopeId: scopeId(ORG_SCOPE_PREFIX, orgId),
393
+ scopeId: orgScopeId,
415
394
  memoryType,
416
395
  importance: importance ?? 1,
417
396
  durability,
@@ -421,8 +400,8 @@ export function createMemoryService(deps: MemoryServiceDeps) {
421
400
  }).pipe(
422
401
  Effect.withSpan('MemoryService.createOrganizationMemory'),
423
402
  Effect.tap(() =>
424
- Effect.sync(() => {
425
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
403
+ Effect.gen(function* () {
404
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
426
405
  aiLogger.debug`createOrganizationMemory - orgId: "${orgId}", scopeId: "${orgScopeId}", content preview: "${content.slice(0, 50)}"`
427
406
  }),
428
407
  ),
@@ -474,8 +453,8 @@ export function createMemoryService(deps: MemoryServiceDeps) {
474
453
  return Effect.fail(new InvalidAgentNameError({ agentName }))
475
454
  }
476
455
 
477
- const scoped = agentScopeId(orgId, agentName)
478
456
  return Effect.gen(function* () {
457
+ const scoped = yield* agentScopeId(orgId, agentName)
479
458
  const memory = yield* getOrgMemory(orgMemoryCache, orgId)
480
459
  return yield* memoryTryPromise('Failed to create agent memory.', () =>
481
460
  memory.insert(content, {
@@ -548,17 +527,19 @@ export function createMemoryService(deps: MemoryServiceDeps) {
548
527
  if (params.facts.length === 0) return
549
528
 
550
529
  const orgMemory = yield* getOrgMemory(orgMemoryCache, params.orgId)
530
+ const orgScopeIdValue = yield* scopeId(ORG_SCOPE_PREFIX, params.orgId)
551
531
  const scopes: AddOptions[] = [
552
532
  {
553
- scopeId: scopeId(ORG_SCOPE_PREFIX, params.orgId),
533
+ scopeId: orgScopeIdValue,
554
534
  memoryType: ORG_MEMORY_TYPE,
555
535
  metadata: { orgId: params.orgId, source: params.source, ...params.sourceMetadata },
556
536
  },
557
537
  ]
558
538
 
559
539
  for (const scopedAgentName of resolveAgentScopeNames(undefined, params.agentNames ?? [])) {
540
+ const agentScopedValue = yield* agentScopeId(params.orgId, scopedAgentName)
560
541
  scopes.push({
561
- scopeId: agentScopeId(params.orgId, scopedAgentName),
542
+ scopeId: agentScopedValue,
562
543
  memoryType: ORG_MEMORY_TYPE,
563
544
  metadata: {
564
545
  orgId: params.orgId,
@@ -621,7 +602,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
621
602
  return
622
603
  }
623
604
 
624
- const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
605
+ const orgScopeId = yield* scopeId(ORG_SCOPE_PREFIX, orgId)
625
606
  aiLogger.debug`addConversationMemories - orgId: "${orgId}", scopeId: "${orgScopeId}", sourceId: ${sourceId ?? 'none'}`
626
607
 
627
608
  const onboardingActive = onboardStatus !== undefined && onboardStatus !== 'completed'
@@ -639,7 +620,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
639
620
  ]
640
621
 
641
622
  for (const scopedAgentName of resolveAgentScopeNames(agentName, agentNames)) {
642
- const agentId = agentScopeId(orgId, scopedAgentName)
623
+ const agentId = yield* agentScopeId(orgId, scopedAgentName)
643
624
  scopes.push({
644
625
  scopeId: agentId,
645
626
  memoryType: ORG_MEMORY_TYPE,
@@ -676,7 +657,7 @@ export function createMemoryService(deps: MemoryServiceDeps) {
676
657
  }
677
658
 
678
659
  export class MemoryServiceTag extends Context.Service<MemoryServiceTag, ReturnType<typeof createMemoryService>>()(
679
- 'MemoryService',
660
+ '@lota-sdk/core/MemoryService',
680
661
  ) {}
681
662
 
682
663
  export const MemoryServiceLive = Layer.effect(
@@ -686,7 +667,8 @@ export const MemoryServiceLive = Layer.effect(
686
667
  const runtimeConfig = yield* RuntimeConfigServiceTag
687
668
  const rerankService = yield* RerankServiceTag
688
669
  const helperModelRuntime = yield* HelperModelTag
689
- const orgMemoryCache = yield* makeOrgMemoryCache({ db, runtimeConfig, helperModelRuntime })
670
+ const background = yield* BackgroundWorkService
671
+ const orgMemoryCache = yield* makeOrgMemoryCache({ db, runtimeConfig, helperModelRuntime, background })
690
672
  return createMemoryService({ runtimeConfig, rerankService, helperModelRuntime, orgMemoryCache })
691
673
  }),
692
674
  )
@@ -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,