@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.
- package/package.json +2 -2
- package/src/ai/embedding-cache.ts +3 -1
- package/src/ai-gateway/ai-gateway.ts +38 -10
- package/src/config/agent-defaults.ts +22 -9
- package/src/config/agent-types.ts +1 -1
- package/src/config/background-processing.ts +1 -1
- package/src/config/index.ts +0 -1
- package/src/config/logger.ts +20 -7
- package/src/config/thread-defaults.ts +12 -4
- package/src/create-runtime.ts +69 -656
- package/src/db/memory-query-builder.ts +2 -1
- package/src/db/memory-store.ts +29 -20
- package/src/db/memory.ts +188 -195
- package/src/db/service-normalization.ts +97 -64
- package/src/db/service.ts +706 -538
- package/src/db/startup.ts +30 -19
- package/src/effect/awaitable-effect.ts +46 -37
- package/src/effect/helpers.ts +30 -5
- package/src/effect/index.ts +7 -5
- package/src/effect/layers.ts +82 -72
- package/src/effect/runtime.ts +18 -3
- package/src/effect/services.ts +15 -11
- package/src/embeddings/provider.ts +65 -66
- package/src/index.ts +13 -11
- package/src/queues/autonomous-job.queue.ts +59 -71
- package/src/queues/context-compaction.queue.ts +6 -18
- package/src/queues/delayed-node-promotion.queue.ts +9 -17
- package/src/queues/organization-learning.queue.ts +17 -4
- package/src/queues/plan-agent-heartbeat.queue.ts +23 -20
- package/src/queues/plan-scheduler.queue.ts +6 -18
- package/src/queues/post-chat-memory.queue.ts +6 -18
- package/src/queues/queue-factory.ts +128 -50
- package/src/queues/title-generation.queue.ts +6 -17
- package/src/redis/connection.ts +181 -164
- package/src/redis/runtime-connection.ts +13 -3
- package/src/redis/stream-context.ts +17 -9
- package/src/runtime/agent-runtime-policy.ts +1 -1
- package/src/runtime/agent-stream-helpers.ts +15 -11
- package/src/runtime/chat-run-orchestration.ts +1 -1
- package/src/runtime/context-compaction/context-compaction-runtime.ts +1 -1
- package/src/runtime/context-compaction/context-compaction.ts +126 -82
- package/src/runtime/domain-layer.ts +192 -0
- package/src/runtime/graph-designer.ts +15 -7
- package/src/runtime/helper-model.ts +8 -4
- package/src/runtime/index.ts +0 -1
- package/src/runtime/memory/memory-block.ts +19 -9
- package/src/runtime/memory/memory-pipeline.ts +53 -66
- package/src/runtime/memory/memory-scope.ts +33 -29
- package/src/runtime/plugin-resolution.ts +33 -54
- package/src/runtime/post-turn-side-effects.ts +6 -26
- package/src/runtime/retrieval-adapters.ts +4 -4
- package/src/runtime/runtime-accessors.ts +92 -0
- package/src/runtime/runtime-config.ts +3 -3
- package/src/runtime/runtime-extensions.ts +20 -9
- package/src/runtime/runtime-lifecycle.ts +124 -0
- package/src/runtime/runtime-services.ts +386 -0
- package/src/runtime/runtime-token.ts +47 -0
- package/src/runtime/social-chat/social-chat-agent-runner.ts +7 -5
- package/src/runtime/social-chat/social-chat-history.ts +21 -12
- package/src/runtime/social-chat/social-chat.ts +401 -365
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +58 -52
- package/src/runtime/thread-turn-context.ts +21 -27
- package/src/services/agent-activity.service.ts +1 -1
- package/src/services/agent-executor.service.ts +179 -187
- package/src/services/artifact.service.ts +10 -5
- package/src/services/attachment.service.ts +35 -1
- package/src/services/autonomous-job.service.ts +58 -56
- package/src/services/background-work.service.ts +54 -0
- package/src/services/chat-run-registry.service.ts +3 -1
- package/src/services/context-compaction.service.ts +1 -1
- package/src/services/document-chunk.service.ts +8 -17
- package/src/services/execution-plan/execution-plan-graph.ts +74 -52
- package/src/services/execution-plan/execution-plan.service.ts +1 -1
- package/src/services/feedback-loop.service.ts +1 -1
- package/src/services/global-orchestrator.service.ts +33 -10
- package/src/services/graph-full-routing.ts +44 -33
- package/src/services/index.ts +1 -0
- package/src/services/institutional-memory.service.ts +8 -17
- package/src/services/learned-skill.service.ts +38 -35
- package/src/services/memory/memory-errors.ts +27 -0
- package/src/services/memory/memory-org-memory.ts +14 -3
- package/src/services/memory/memory-preseeded.ts +10 -4
- package/src/services/memory/memory-utils.ts +2 -1
- package/src/services/memory/memory.service.ts +26 -44
- package/src/services/memory/rerank.service.ts +3 -11
- package/src/services/monitoring-window.service.ts +1 -1
- package/src/services/mutating-approval.service.ts +1 -1
- package/src/services/node-workspace.service.ts +2 -2
- package/src/services/notification.service.ts +16 -4
- package/src/services/organization-member.service.ts +1 -1
- package/src/services/organization.service.ts +34 -51
- package/src/services/ownership-dispatcher.service.ts +132 -90
- package/src/services/plan/plan-agent-heartbeat.service.ts +1 -1
- package/src/services/plan/plan-agent-query.service.ts +1 -1
- package/src/services/plan/plan-approval.service.ts +52 -48
- package/src/services/plan/plan-artifact.service.ts +2 -2
- package/src/services/plan/plan-builder.service.ts +2 -2
- package/src/services/plan/plan-checkpoint.service.ts +1 -1
- package/src/services/plan/plan-compiler.service.ts +1 -1
- package/src/services/plan/plan-completion-side-effects.ts +18 -24
- package/src/services/plan/plan-coordination.service.ts +1 -1
- package/src/services/plan/plan-cycle.service.ts +171 -164
- package/src/services/plan/plan-deadline.service.ts +290 -304
- package/src/services/plan/plan-event-delivery.service.ts +44 -39
- package/src/services/plan/plan-executor-graph.ts +114 -67
- package/src/services/plan/plan-executor-helpers.ts +60 -75
- package/src/services/plan/plan-executor.service.ts +550 -467
- package/src/services/plan/plan-run.service.ts +12 -19
- package/src/services/plan/plan-scheduler.service.ts +27 -33
- package/src/services/plan/plan-template.service.ts +1 -1
- package/src/services/plan/plan-transaction-events.ts +8 -5
- package/src/services/plan/plan-validator.service.ts +1 -1
- package/src/services/plan/plan-workspace.service.ts +17 -11
- package/src/services/plugin-executor.service.ts +26 -21
- package/src/services/quality-metrics.service.ts +1 -1
- package/src/services/queue-job.service.ts +8 -17
- package/src/services/recent-activity-title.service.ts +17 -9
- package/src/services/recent-activity.service.ts +1 -1
- package/src/services/skill-resolver.service.ts +1 -1
- package/src/services/social-chat-history.service.ts +37 -20
- package/src/services/system-executor.service.ts +25 -20
- package/src/services/thread/thread-bootstrap.ts +26 -10
- package/src/services/thread/thread-listing.ts +2 -1
- package/src/services/thread/thread-memory-block.ts +18 -5
- package/src/services/thread/thread-message.service.ts +24 -8
- package/src/services/thread/thread-title.service.ts +1 -1
- package/src/services/thread/thread-turn-execution.ts +1 -1
- package/src/services/thread/thread-turn-preparation.service.ts +18 -16
- package/src/services/thread/thread-turn-streaming.ts +12 -11
- package/src/services/thread/thread-turn.ts +43 -10
- package/src/services/thread/thread.service.ts +11 -2
- package/src/services/user.service.ts +1 -1
- package/src/services/write-intent-validator.service.ts +1 -1
- package/src/storage/attachment-storage.service.ts +7 -4
- package/src/storage/generated-document-storage.service.ts +1 -1
- package/src/system-agents/context-compaction.agent.ts +1 -1
- package/src/system-agents/helper-agent-options.ts +1 -1
- package/src/system-agents/memory-reranker.agent.ts +1 -1
- package/src/system-agents/memory.agent.ts +1 -1
- package/src/system-agents/recent-activity-title-refiner.agent.ts +1 -1
- package/src/system-agents/regular-chat-memory-digest.agent.ts +1 -1
- package/src/system-agents/skill-extractor.agent.ts +1 -1
- package/src/system-agents/skill-manager.agent.ts +1 -1
- package/src/system-agents/title-generator.agent.ts +1 -1
- package/src/tools/execution-plan.tool.ts +28 -17
- package/src/tools/fetch-webpage.tool.ts +20 -13
- package/src/tools/firecrawl-client.ts +13 -3
- package/src/tools/plan-approval.tool.ts +9 -1
- package/src/tools/search-web.tool.ts +16 -9
- package/src/tools/team-think.tool.ts +2 -2
- package/src/utils/async.ts +15 -6
- package/src/utils/errors.ts +27 -15
- package/src/workers/bootstrap.ts +25 -48
- package/src/workers/organization-learning.worker.ts +1 -1
- package/src/workers/regular-chat-memory-digest.runner.ts +25 -15
- package/src/workers/worker-utils.ts +20 -2
- package/src/config/search.ts +0 -3
- package/src/runtime/agent-types.ts +0 -1
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { OwnershipDispatchContext, PlanNodeResult, PlanNodeSpec, SystemPlanNodeOwner } from '@lota-sdk/shared'
|
|
2
2
|
import { Context, Effect, Layer } from 'effect'
|
|
3
3
|
|
|
4
|
-
import { BadRequestError } from '../effect/errors'
|
|
4
|
+
import { BadRequestError, ServiceError } from '../effect/errors'
|
|
5
|
+
import { makeEffectTryPromiseWithMessage } from '../effect/helpers'
|
|
5
6
|
import { RuntimeConfigServiceTag } from '../effect/services'
|
|
7
|
+
|
|
8
|
+
const trySystemExecutorPromise = makeEffectTryPromiseWithMessage(
|
|
9
|
+
(message, cause) => new ServiceError({ message, cause }),
|
|
10
|
+
)
|
|
6
11
|
import type { SystemNodeExecutor, PluginNodeExecutionParams } from '../runtime/plugin-types'
|
|
7
12
|
import type { ResolvedLotaRuntimeConfig } from '../runtime/runtime-config'
|
|
8
13
|
import type { PlanValidationIssueInput } from './plan/plan-validator.service'
|
|
@@ -86,27 +91,27 @@ export function makeSystemExecutorService(config: ResolvedLotaRuntimeConfig) {
|
|
|
86
91
|
return []
|
|
87
92
|
},
|
|
88
93
|
|
|
89
|
-
executeNode(params: {
|
|
94
|
+
executeNode: Effect.fn('SystemExecutor.executeNode')(function* (params: {
|
|
90
95
|
nodeSpec: PlanNodeSpec
|
|
91
96
|
resolvedInput: Record<string, unknown>
|
|
92
97
|
context: OwnershipDispatchContext
|
|
93
98
|
}) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
99
|
+
const owner = params.nodeSpec.owner
|
|
100
|
+
if (!isSystemOwner(owner)) {
|
|
101
|
+
return yield* new BadRequestError({
|
|
102
|
+
message: `SystemExecutor cannot execute owner type "${owner.executorType}".`,
|
|
103
|
+
})
|
|
104
|
+
}
|
|
101
105
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
const executor = getSystemExecutors()[owner.ref]
|
|
107
|
+
if (!executor || !executor.supportedOperations.includes(owner.operation)) {
|
|
108
|
+
return yield* new BadRequestError({
|
|
109
|
+
message: `System executor ${owner.ref}.${owner.operation} is not registered.`,
|
|
110
|
+
})
|
|
111
|
+
}
|
|
108
112
|
|
|
109
|
-
|
|
113
|
+
return yield* trySystemExecutorPromise(
|
|
114
|
+
() =>
|
|
110
115
|
executor.executeNode(
|
|
111
116
|
buildSystemExecutionParams({
|
|
112
117
|
owner,
|
|
@@ -115,16 +120,16 @@ export function makeSystemExecutorService(config: ResolvedLotaRuntimeConfig) {
|
|
|
115
120
|
context: params.context,
|
|
116
121
|
}),
|
|
117
122
|
),
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
},
|
|
123
|
+
`System executor "${owner.ref}.${owner.operation}" failed.`,
|
|
124
|
+
).pipe(Effect.withSpan('SystemExecutor.invoke'))
|
|
125
|
+
}),
|
|
121
126
|
}
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
export class SystemExecutorServiceTag extends Context.Service<
|
|
125
130
|
SystemExecutorServiceTag,
|
|
126
131
|
ReturnType<typeof makeSystemExecutorService>
|
|
127
|
-
>()('SystemExecutorService') {}
|
|
132
|
+
>()('@lota-sdk/core/SystemExecutorService') {}
|
|
128
133
|
|
|
129
134
|
export const SystemExecutorServiceLive = Layer.effect(
|
|
130
135
|
SystemExecutorServiceTag,
|
|
@@ -8,6 +8,7 @@ import type { RecordIdRef } from '../../db/record-id'
|
|
|
8
8
|
import { ensureRecordId, recordIdToString } from '../../db/record-id'
|
|
9
9
|
import { TABLES } from '../../db/tables'
|
|
10
10
|
import { BadRequestError, DatabaseError } from '../../effect/errors'
|
|
11
|
+
import type { LockAcquisitionError, LockLostError, NotFoundError, RedisError, ServiceError } from '../../effect/errors'
|
|
11
12
|
import type { RedisConnectionManager } from '../../redis/connection'
|
|
12
13
|
import { withLeaseLock } from '../../redis/redis-lease-lock'
|
|
13
14
|
import type { makeThreadMessageService } from './thread-message.service'
|
|
@@ -31,7 +32,22 @@ function haveSameMembers(left: string[], right: string[]): boolean {
|
|
|
31
32
|
return left.length === right.length && left.every((value, index) => value === right[index])
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
type
|
|
35
|
+
type ThreadNormalizationError = BadRequestError | ServiceError
|
|
36
|
+
type ThreadBootstrapError =
|
|
37
|
+
| BadRequestError
|
|
38
|
+
| DatabaseError
|
|
39
|
+
| LockAcquisitionError
|
|
40
|
+
| LockLostError
|
|
41
|
+
| NotFoundError
|
|
42
|
+
| RedisError
|
|
43
|
+
| ServiceError
|
|
44
|
+
|
|
45
|
+
type NormalizedThreadFactory = (thread: ThreadRecord) => Effect.Effect<NormalizedThread, ThreadNormalizationError>
|
|
46
|
+
type DuplicateCreateErrorLike = { cause?: unknown; message?: unknown }
|
|
47
|
+
|
|
48
|
+
function isDuplicateCreateErrorLike(value: unknown): value is DuplicateCreateErrorLike {
|
|
49
|
+
return (typeof value === 'object' || typeof value === 'function') && value !== null
|
|
50
|
+
}
|
|
35
51
|
|
|
36
52
|
export function createThreadBootstrapHelpers(deps: {
|
|
37
53
|
threadStore: ThreadRecordStore
|
|
@@ -85,26 +101,26 @@ export function createThreadBootstrapHelpers(deps: {
|
|
|
85
101
|
const seen = new Set<unknown>()
|
|
86
102
|
let current = error
|
|
87
103
|
|
|
88
|
-
while ((
|
|
104
|
+
while (isDuplicateCreateErrorLike(current) && !seen.has(current)) {
|
|
89
105
|
seen.add(current)
|
|
90
|
-
|
|
91
|
-
if (typeof message === 'string' && message.includes('already contains')) {
|
|
106
|
+
if (typeof current.message === 'string' && current.message.includes('already contains')) {
|
|
92
107
|
return true
|
|
93
108
|
}
|
|
94
|
-
current =
|
|
109
|
+
current = current.cause
|
|
95
110
|
}
|
|
96
111
|
|
|
97
112
|
return false
|
|
98
113
|
}
|
|
99
114
|
|
|
100
|
-
const normalizeThreadEffect = (thread: ThreadRecord) =>
|
|
115
|
+
const normalizeThreadEffect = (thread: ThreadRecord): Effect.Effect<NormalizedThread, ThreadNormalizationError> =>
|
|
116
|
+
deps.normalizeThread(thread)
|
|
101
117
|
|
|
102
118
|
const getOrCreateDefaultEffect = (
|
|
103
119
|
orgId: RecordIdRef,
|
|
104
120
|
userId: RecordIdRef,
|
|
105
121
|
agentId: string,
|
|
106
122
|
config?: { title?: string; nameGenerated?: boolean },
|
|
107
|
-
) => {
|
|
123
|
+
): Effect.Effect<{ created: boolean; record: ThreadRecord }, DatabaseError | NotFoundError> => {
|
|
108
124
|
const lookup = { type: 'default' as const, organizationId: orgId, userId, agentId }
|
|
109
125
|
|
|
110
126
|
return Effect.gen(function* () {
|
|
@@ -150,7 +166,7 @@ export function createThreadBootstrapHelpers(deps: {
|
|
|
150
166
|
userId: RecordIdRef,
|
|
151
167
|
threadType: string,
|
|
152
168
|
config: { members: string[]; title: string; nameGenerated?: boolean },
|
|
153
|
-
) => {
|
|
169
|
+
): Effect.Effect<{ created: boolean; record: ThreadRecord }, DatabaseError | NotFoundError> => {
|
|
154
170
|
const lookup = { type: 'thread' as const, organizationId: orgId, userId, threadType }
|
|
155
171
|
|
|
156
172
|
return Effect.gen(function* () {
|
|
@@ -199,7 +215,7 @@ export function createThreadBootstrapHelpers(deps: {
|
|
|
199
215
|
threadType?: string
|
|
200
216
|
members?: string[]
|
|
201
217
|
title?: string
|
|
202
|
-
}) =>
|
|
218
|
+
}): Effect.Effect<NormalizedThread, ThreadBootstrapError> =>
|
|
203
219
|
Effect.gen(function* () {
|
|
204
220
|
switch (input.type) {
|
|
205
221
|
case 'default':
|
|
@@ -262,7 +278,7 @@ export function createThreadBootstrapHelpers(deps: {
|
|
|
262
278
|
userId: RecordIdRef,
|
|
263
279
|
orgId: RecordIdRef,
|
|
264
280
|
options?: { onboardStatus?: string; userName?: string | null },
|
|
265
|
-
) => {
|
|
281
|
+
): Effect.Effect<void, ThreadBootstrapError> => {
|
|
266
282
|
const bootstrapConfig = getThreadBootstrapConfig()
|
|
267
283
|
|
|
268
284
|
return withLeaseLock(
|
|
@@ -5,6 +5,7 @@ import { BoundQuery } from 'surrealdb'
|
|
|
5
5
|
import type { RecordIdRef } from '../../db/record-id'
|
|
6
6
|
import type { SurrealDBService } from '../../db/service'
|
|
7
7
|
import { TABLES } from '../../db/tables'
|
|
8
|
+
import type { BadRequestError, ServiceError } from '../../effect/errors'
|
|
8
9
|
import { makeEffectTryPromiseWithMessage } from '../../effect/helpers'
|
|
9
10
|
import { ThreadSchema } from './thread.types'
|
|
10
11
|
import type { NormalizedThread, ThreadRecord } from './thread.types'
|
|
@@ -38,7 +39,7 @@ export function createThreadListingHelpers(deps: {
|
|
|
38
39
|
normalizeThreads(
|
|
39
40
|
threads: ThreadRecord[],
|
|
40
41
|
options?: { checkLease?: boolean },
|
|
41
|
-
): Effect.Effect<NormalizedThread[],
|
|
42
|
+
): Effect.Effect<NormalizedThread[], BadRequestError | ServiceError>
|
|
42
43
|
}) {
|
|
43
44
|
class ThreadListingError extends Schema.TaggedErrorClass<ThreadListingError>()('ThreadListingError', {
|
|
44
45
|
message: Schema.String,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Context } from 'effect'
|
|
1
2
|
import { Schema, Effect } from 'effect'
|
|
2
3
|
|
|
3
4
|
import { serverLogger } from '../../config/logger'
|
|
@@ -9,16 +10,19 @@ import {
|
|
|
9
10
|
appendToMemoryBlock,
|
|
10
11
|
compactMemoryBlockEntries,
|
|
11
12
|
formatPersistedMemoryBlockForPrompt,
|
|
13
|
+
MemoryBlockCompactError,
|
|
12
14
|
parseMemoryBlock,
|
|
13
15
|
serializeMemoryBlock,
|
|
14
16
|
} from '../../runtime/memory/memory-block'
|
|
17
|
+
import type { BackgroundWorkService } from '../background-work.service'
|
|
18
|
+
import type { makeContextCompactionService } from '../context-compaction.service'
|
|
15
19
|
import { MEMORY_BLOCK_COMPACTION_CHUNK_ENTRIES, MEMORY_BLOCK_COMPACTION_TRIGGER_ENTRIES } from './thread-constants'
|
|
16
20
|
import type { ThreadRecordStore } from './thread-record-store'
|
|
17
21
|
import type { ThreadRecord } from './thread.types'
|
|
18
22
|
|
|
19
|
-
type ContextCompactionServiceLike =
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
type ContextCompactionServiceLike = Pick<ReturnType<typeof makeContextCompactionService>, 'compactMemoryBlock'>
|
|
24
|
+
|
|
25
|
+
type BackgroundWorker = Context.Service.Shape<typeof BackgroundWorkService>
|
|
22
26
|
|
|
23
27
|
class ThreadMemoryBlockError extends Schema.TaggedErrorClass<ThreadMemoryBlockError>()('ThreadMemoryBlockError', {
|
|
24
28
|
message: Schema.String,
|
|
@@ -39,6 +43,7 @@ export function formatMemoryBlockForPrompt(thread: Pick<ThreadRecord, 'memoryBlo
|
|
|
39
43
|
export function createThreadMemoryBlockHelpers(deps: {
|
|
40
44
|
threadStore: ThreadRecordStore
|
|
41
45
|
contextCompactionService: ContextCompactionServiceLike
|
|
46
|
+
background: BackgroundWorker
|
|
42
47
|
}) {
|
|
43
48
|
function appendMemoryBlock(threadId: RecordIdRef, entry: string): Effect.Effect<string, ThreadMemoryBlockError> {
|
|
44
49
|
return Effect.gen(function* () {
|
|
@@ -63,7 +68,7 @@ export function createThreadMemoryBlockHelpers(deps: {
|
|
|
63
68
|
)
|
|
64
69
|
|
|
65
70
|
if (updatedEntries.length >= MEMORY_BLOCK_COMPACTION_TRIGGER_ENTRIES) {
|
|
66
|
-
yield*
|
|
71
|
+
yield* deps.background.run(
|
|
67
72
|
compactMemoryBlock(threadRef).pipe(
|
|
68
73
|
Effect.catch((error: unknown) =>
|
|
69
74
|
Effect.sync(() => {
|
|
@@ -71,6 +76,7 @@ export function createThreadMemoryBlockHelpers(deps: {
|
|
|
71
76
|
}),
|
|
72
77
|
),
|
|
73
78
|
),
|
|
79
|
+
'thread-memory-block.compactMemoryBlock',
|
|
74
80
|
)
|
|
75
81
|
}
|
|
76
82
|
|
|
@@ -93,7 +99,14 @@ export function createThreadMemoryBlockHelpers(deps: {
|
|
|
93
99
|
entries: parseMemoryBlock(thread.memoryBlock),
|
|
94
100
|
triggerEntries: MEMORY_BLOCK_COMPACTION_TRIGGER_ENTRIES,
|
|
95
101
|
chunkEntries: MEMORY_BLOCK_COMPACTION_CHUNK_ENTRIES,
|
|
96
|
-
compact: (params) =>
|
|
102
|
+
compact: (params) =>
|
|
103
|
+
deps.contextCompactionService
|
|
104
|
+
.compactMemoryBlock(params)
|
|
105
|
+
.pipe(
|
|
106
|
+
Effect.mapError(
|
|
107
|
+
(cause) => new MemoryBlockCompactError({ message: 'compact callback failed', cause }),
|
|
108
|
+
),
|
|
109
|
+
),
|
|
97
110
|
}),
|
|
98
111
|
`Failed to compact memory block for thread ${threadIdString}`,
|
|
99
112
|
)
|
|
@@ -3,6 +3,7 @@ import type { ChatMessage } from '@lota-sdk/shared'
|
|
|
3
3
|
import { Context, Effect, Layer } from 'effect'
|
|
4
4
|
import { RecordId, surql } from 'surrealdb'
|
|
5
5
|
import { z } from 'zod'
|
|
6
|
+
import type { ZodTypeAny } from 'zod'
|
|
6
7
|
|
|
7
8
|
import { getAgentDisplayNames } from '../../config/agent-defaults'
|
|
8
9
|
import { CursorRowSchema, listMessageHistoryPageEffect } from '../../db/cursor-pagination'
|
|
@@ -21,6 +22,17 @@ import { nowEpochMillis, unsafeDateFrom } from '../../utils/date-time'
|
|
|
21
22
|
|
|
22
23
|
const ThreadMessageExistingRowSchema = z.object({ id: recordIdSchema, createdAt: z.coerce.date() })
|
|
23
24
|
|
|
25
|
+
function parseRowOrFail<TSchema extends ZodTypeAny>(
|
|
26
|
+
schema: TSchema,
|
|
27
|
+
value: unknown,
|
|
28
|
+
operation: string,
|
|
29
|
+
): Effect.Effect<z.infer<TSchema>, ServiceError> {
|
|
30
|
+
return Effect.try({
|
|
31
|
+
try: () => schema.parse(value) as z.infer<TSchema>,
|
|
32
|
+
catch: (cause) => new ServiceError({ message: `Failed to parse row for ${operation}.`, cause }),
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
24
36
|
function toMessageId(value: string | RecordIdRef): string {
|
|
25
37
|
return recordIdToString(value, TABLES.THREAD_MESSAGE)
|
|
26
38
|
}
|
|
@@ -160,7 +172,10 @@ export function makeThreadMessageService(db: SurrealDBService) {
|
|
|
160
172
|
`),
|
|
161
173
|
'Failed to list thread messages.',
|
|
162
174
|
).pipe(
|
|
163
|
-
Effect.
|
|
175
|
+
Effect.flatMap((rows) =>
|
|
176
|
+
Effect.forEach(rows, (row) => parseRowOrFail(ThreadMessageRowSchema, row, 'listMessages')),
|
|
177
|
+
),
|
|
178
|
+
Effect.map((rows) => rows.map((row) => toChatMessage(row))),
|
|
164
179
|
)
|
|
165
180
|
},
|
|
166
181
|
listMessagesEffect(threadId: RecordIdRef) {
|
|
@@ -210,7 +225,10 @@ export function makeThreadMessageService(db: SurrealDBService) {
|
|
|
210
225
|
`),
|
|
211
226
|
'Failed to list thread messages after cursor.',
|
|
212
227
|
)
|
|
213
|
-
|
|
228
|
+
const parsedRows = yield* Effect.forEach(rows, (row) =>
|
|
229
|
+
parseRowOrFail(ThreadMessageRowSchema, row, 'listMessagesAfterCursor'),
|
|
230
|
+
)
|
|
231
|
+
return parsedRows.map((row) => toChatMessage(row))
|
|
214
232
|
})
|
|
215
233
|
},
|
|
216
234
|
listMessagesAfterCursorEffect(threadId: RecordIdRef, afterMessageId?: string) {
|
|
@@ -229,12 +247,10 @@ export function makeThreadMessageService(db: SurrealDBService) {
|
|
|
229
247
|
`),
|
|
230
248
|
'Failed to list recent thread messages.',
|
|
231
249
|
).pipe(
|
|
232
|
-
Effect.
|
|
233
|
-
rows
|
|
234
|
-
.map((row) => ThreadMessageRowSchema.parse(row))
|
|
235
|
-
.reverse()
|
|
236
|
-
.map((row) => toChatMessage(row)),
|
|
250
|
+
Effect.flatMap((rows) =>
|
|
251
|
+
Effect.forEach(rows, (row) => parseRowOrFail(ThreadMessageRowSchema, row, 'listRecentMessages')),
|
|
237
252
|
),
|
|
253
|
+
Effect.map((rows) => rows.reverse().map((row) => toChatMessage(row))),
|
|
238
254
|
)
|
|
239
255
|
},
|
|
240
256
|
listRecentMessagesEffect(threadId: RecordIdRef, limit: number) {
|
|
@@ -352,7 +368,7 @@ export function makeThreadMessageService(db: SurrealDBService) {
|
|
|
352
368
|
export class ThreadMessageServiceTag extends Context.Service<
|
|
353
369
|
ThreadMessageServiceTag,
|
|
354
370
|
ReturnType<typeof makeThreadMessageService>
|
|
355
|
-
>()('ThreadMessageService') {}
|
|
371
|
+
>()('@lota-sdk/core/ThreadMessageService') {}
|
|
356
372
|
|
|
357
373
|
export const ThreadMessageServiceLive = Layer.effect(
|
|
358
374
|
ThreadMessageServiceTag,
|
|
@@ -62,7 +62,7 @@ export function makeThreadTitleService(
|
|
|
62
62
|
export class ThreadTitleServiceTag extends Context.Service<
|
|
63
63
|
ThreadTitleServiceTag,
|
|
64
64
|
ReturnType<typeof makeThreadTitleService>
|
|
65
|
-
>()('ThreadTitleService') {}
|
|
65
|
+
>()('@lota-sdk/core/ThreadTitleService') {}
|
|
66
66
|
|
|
67
67
|
export const ThreadTitleServiceLive = Layer.effect(
|
|
68
68
|
ThreadTitleServiceTag,
|
|
@@ -142,7 +142,7 @@ export function createThreadTurnVisibleAgentRunner<TBuildTurnToolParams>(
|
|
|
142
142
|
aiLogger.error`Agent run failed (agent=${agentId}): ${error}`
|
|
143
143
|
},
|
|
144
144
|
recordAbort: (error: unknown) => {
|
|
145
|
-
aiLogger.
|
|
145
|
+
aiLogger.debug`Agent run aborted (agent=${agentId}): ${error instanceof Error ? error.message : String(error)}`
|
|
146
146
|
},
|
|
147
147
|
})
|
|
148
148
|
|
|
@@ -570,20 +570,22 @@ const prepareThreadRunCoreEffect = Effect.fn('ThreadTurnPreparation.prepareThrea
|
|
|
570
570
|
return Effect.succeed(preSeededMemoriesByAgent.get(agentId))
|
|
571
571
|
}
|
|
572
572
|
|
|
573
|
-
return
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
573
|
+
return memoryService
|
|
574
|
+
.getTopMemories({ orgId: orgIdString, agentName: agentId, limit: PRESEEDED_MEMORY_LOOKUP_LIMIT })
|
|
575
|
+
.pipe(
|
|
576
|
+
Effect.tap((preSeededMemories) =>
|
|
577
|
+
Effect.sync(() => {
|
|
578
|
+
preSeededMemoriesByAgent.set(agentId, preSeededMemories)
|
|
579
|
+
}),
|
|
580
|
+
),
|
|
581
|
+
Effect.mapError(
|
|
582
|
+
(error) =>
|
|
583
|
+
new ThreadTurnStreamingError({
|
|
584
|
+
message: `Failed to load pre-seeded memories for ${agentId}.`,
|
|
585
|
+
cause: error,
|
|
586
|
+
}),
|
|
587
|
+
),
|
|
588
|
+
)
|
|
587
589
|
}
|
|
588
590
|
|
|
589
591
|
const learnedSkillsByAgent = new Map<string, string | undefined>()
|
|
@@ -1083,7 +1085,7 @@ export function makeThreadTurnPreparationService(deps: ThreadTurnPreparationDeps
|
|
|
1083
1085
|
randomId: () => Bun.randomUUIDv7(),
|
|
1084
1086
|
}),
|
|
1085
1087
|
}
|
|
1086
|
-
const annotateTurnSpans = <A, E>(params: ThreadRunCoreParams, effect: Effect.Effect<A, E>) =>
|
|
1088
|
+
const annotateTurnSpans = <A, E, R>(params: ThreadRunCoreParams, effect: Effect.Effect<A, E, R>) =>
|
|
1087
1089
|
effect.pipe(
|
|
1088
1090
|
Effect.annotateSpans(
|
|
1089
1091
|
compactSpanAttributes({
|
|
@@ -1116,7 +1118,7 @@ export function makeThreadTurnPreparationService(deps: ThreadTurnPreparationDeps
|
|
|
1116
1118
|
export class ThreadTurnPreparationServiceTag extends Context.Service<
|
|
1117
1119
|
ThreadTurnPreparationServiceTag,
|
|
1118
1120
|
ReturnType<typeof makeThreadTurnPreparationService>
|
|
1119
|
-
>()('ThreadTurnPreparationService') {}
|
|
1121
|
+
>()('@lota-sdk/core/ThreadTurnPreparationService') {}
|
|
1120
1122
|
|
|
1121
1123
|
export const ThreadTurnPreparationServiceLive = Layer.effect(
|
|
1122
1124
|
ThreadTurnPreparationServiceTag,
|
|
@@ -7,7 +7,7 @@ import { Effect, Ref, Schema, Stream } from 'effect'
|
|
|
7
7
|
import { getAgentRuntimeConfig, getResolvedAgentFactoryConfig } from '../../config/agent-defaults'
|
|
8
8
|
import { aiLogger } from '../../config/logger'
|
|
9
9
|
import type { RecordIdRef } from '../../db/record-id'
|
|
10
|
-
import { effectTryMaybeAsync,
|
|
10
|
+
import { effectTryMaybeAsync, makeEffectTryPromiseWithMessage } from '../../effect/helpers'
|
|
11
11
|
import { runPromise } from '../../effect/runtime'
|
|
12
12
|
import {
|
|
13
13
|
readRuntimeAgentIdentityOverrides,
|
|
@@ -44,12 +44,9 @@ export class ThreadTurnStreamingError extends Schema.TaggedErrorClass<ThreadTurn
|
|
|
44
44
|
{ message: Schema.String, cause: Schema.optional(Schema.Defect) },
|
|
45
45
|
) {}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
): Effect.Effect<A, ThreadTurnStreamingError> {
|
|
51
|
-
return effectTryPromiseShared(evaluate, (error) => new ThreadTurnStreamingError({ message, cause: error }))
|
|
52
|
-
}
|
|
47
|
+
const effectTryPromise = makeEffectTryPromiseWithMessage(
|
|
48
|
+
(message, cause) => new ThreadTurnStreamingError({ message, cause }),
|
|
49
|
+
)
|
|
53
50
|
|
|
54
51
|
function effectFromMaybeEffect<A>(
|
|
55
52
|
evaluate: () => A | PromiseLike<A> | Effect.Effect<A, ThreadTurnStreamingError>,
|
|
@@ -93,7 +90,9 @@ function isTextTokenChunkType(chunkType: string | undefined): boolean {
|
|
|
93
90
|
return chunkType === 'text-delta'
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
function buildFallbackResponseMessage(
|
|
93
|
+
function buildFallbackResponseMessage(
|
|
94
|
+
result: ToolLoopGenerateResult,
|
|
95
|
+
): Effect.Effect<ChatMessage, ThreadTurnStreamingError> {
|
|
97
96
|
const parts: ChatMessage['parts'] = []
|
|
98
97
|
|
|
99
98
|
for (const step of result.steps ?? []) {
|
|
@@ -114,10 +113,12 @@ function buildFallbackResponseMessage(result: ToolLoopGenerateResult): ChatMessa
|
|
|
114
113
|
}
|
|
115
114
|
|
|
116
115
|
if (parts.length === 0) {
|
|
117
|
-
|
|
116
|
+
return Effect.fail(
|
|
117
|
+
new ThreadTurnStreamingError({ message: 'Agent generate fallback did not produce any response parts.' }),
|
|
118
|
+
)
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
return { id: Bun.randomUUIDv7(), role: 'assistant', parts }
|
|
121
|
+
return Effect.succeed({ id: Bun.randomUUIDv7(), role: 'assistant', parts })
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
export interface StreamAgentResponseContext {
|
|
@@ -287,7 +288,7 @@ const streamAgentResponseEffect = Effect.fn('ThreadTurnStreaming.streamAgentResp
|
|
|
287
288
|
aiLogger.warn`Agent stream failed for ${resolvedAgentId}; falling back to generate: ${cause.message}`
|
|
288
289
|
}),
|
|
289
290
|
),
|
|
290
|
-
Effect.
|
|
291
|
+
Effect.flatMap((result) => buildFallbackResponseMessage(result as ToolLoopGenerateResult)),
|
|
291
292
|
)
|
|
292
293
|
|
|
293
294
|
const result = yield* effectTryPromise(
|
|
@@ -6,7 +6,6 @@ import { ensureRecordId, recordIdToString } from '../../db/record-id'
|
|
|
6
6
|
import { TABLES } from '../../db/tables'
|
|
7
7
|
import { BadRequestError } from '../../effect/errors'
|
|
8
8
|
import { runPromise } from '../../effect/runtime'
|
|
9
|
-
import { getCurrentRuntime } from '../../effect/runtime-ref'
|
|
10
9
|
import { hasApprovalRespondedParts, isApprovalContinuationRequest } from '../../runtime/approval-continuation'
|
|
11
10
|
import { shouldPlanNodeUseVisibleTurn } from '../../runtime/execution-plan-visibility'
|
|
12
11
|
import { wrapResponseWithKeepalive } from '../../utils/sse-keepalive'
|
|
@@ -299,7 +298,7 @@ export function makeThreadTurnService(deps: ThreadTurnDeps) {
|
|
|
299
298
|
export class ThreadTurnServiceTag extends Context.Service<
|
|
300
299
|
ThreadTurnServiceTag,
|
|
301
300
|
ReturnType<typeof makeThreadTurnService>
|
|
302
|
-
>()('ThreadTurnService') {}
|
|
301
|
+
>()('@lota-sdk/core/ThreadTurnService') {}
|
|
303
302
|
|
|
304
303
|
export const ThreadTurnServiceLive = Layer.effect(
|
|
305
304
|
ThreadTurnServiceTag,
|
|
@@ -313,24 +312,58 @@ export const ThreadTurnServiceLive = Layer.effect(
|
|
|
313
312
|
}),
|
|
314
313
|
)
|
|
315
314
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
315
|
+
const createThreadApprovalContinuationStreamWithRuntime = Effect.fn(
|
|
316
|
+
'ThreadTurn.createApprovalContinuationStreamWithRuntime',
|
|
317
|
+
)(function* (params: ThreadApprovalContinuationParams) {
|
|
318
|
+
const threadTurnService = yield* ThreadTurnServiceTag
|
|
319
|
+
return yield* threadTurnService.createThreadApprovalContinuationStream(params)
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
const createThreadNativeToolApprovalStreamWithRuntime = Effect.fn(
|
|
323
|
+
'ThreadTurn.createNativeToolApprovalStreamWithRuntime',
|
|
324
|
+
)(function* (params: ThreadApprovalContinuationParams) {
|
|
325
|
+
const threadTurnService = yield* ThreadTurnServiceTag
|
|
326
|
+
return yield* threadTurnService.createThreadNativeToolApprovalStream(params)
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
const createThreadTurnStreamWithRuntime = Effect.fn('ThreadTurn.createThreadTurnStreamWithRuntime')(function* (
|
|
330
|
+
params: ThreadTurnParams,
|
|
331
|
+
) {
|
|
332
|
+
const threadTurnService = yield* ThreadTurnServiceTag
|
|
333
|
+
return yield* threadTurnService.createThreadTurnStream(params)
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
const runThreadTurnInBackgroundWithRuntime = Effect.fn('ThreadTurn.runThreadTurnInBackgroundWithRuntime')(function* (
|
|
337
|
+
params: ThreadTurnParams,
|
|
338
|
+
) {
|
|
339
|
+
const threadTurnService = yield* ThreadTurnServiceTag
|
|
340
|
+
return yield* threadTurnService.runThreadTurnInBackground(params)
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
const triggerPlanNodeTurnWithRuntime = Effect.fn('ThreadTurn.triggerPlanNodeTurnWithRuntime')(function* (params: {
|
|
344
|
+
runId: string
|
|
345
|
+
nodeId: string
|
|
346
|
+
abortSignal?: AbortSignal
|
|
347
|
+
streamId?: string
|
|
348
|
+
}) {
|
|
349
|
+
const threadTurnService = yield* ThreadTurnServiceTag
|
|
350
|
+
return yield* threadTurnService.triggerPlanNodeTurn(params)
|
|
351
|
+
})
|
|
319
352
|
|
|
320
353
|
export function createThreadApprovalContinuationStream(params: ThreadApprovalContinuationParams) {
|
|
321
|
-
return runPromise(
|
|
354
|
+
return runPromise(createThreadApprovalContinuationStreamWithRuntime(params))
|
|
322
355
|
}
|
|
323
356
|
|
|
324
357
|
export function createThreadNativeToolApprovalStream(params: ThreadApprovalContinuationParams) {
|
|
325
|
-
return runPromise(
|
|
358
|
+
return runPromise(createThreadNativeToolApprovalStreamWithRuntime(params))
|
|
326
359
|
}
|
|
327
360
|
|
|
328
361
|
export function createThreadTurnStream(params: ThreadTurnParams) {
|
|
329
|
-
return runPromise(
|
|
362
|
+
return runPromise(createThreadTurnStreamWithRuntime(params))
|
|
330
363
|
}
|
|
331
364
|
|
|
332
365
|
export function runThreadTurnInBackground(params: ThreadTurnParams): Promise<PreparedThreadTurnResult> {
|
|
333
|
-
return runPromise(
|
|
366
|
+
return runPromise(runThreadTurnInBackgroundWithRuntime(params))
|
|
334
367
|
}
|
|
335
368
|
|
|
336
369
|
export function triggerPlanNodeTurn(params: {
|
|
@@ -339,5 +372,5 @@ export function triggerPlanNodeTurn(params: {
|
|
|
339
372
|
abortSignal?: AbortSignal
|
|
340
373
|
streamId?: string
|
|
341
374
|
}): Promise<PreparedThreadTurnResult> {
|
|
342
|
-
return runPromise(
|
|
375
|
+
return runPromise(triggerPlanNodeTurnWithRuntime(params))
|
|
343
376
|
}
|
|
@@ -13,6 +13,7 @@ import { DatabaseServiceTag, RedisServiceTag } from '../../effect/services'
|
|
|
13
13
|
import type { RedisConnectionManager } from '../../redis/connection'
|
|
14
14
|
import { CompactionCoordinationTag } from '../../runtime/chat-run-orchestration'
|
|
15
15
|
import { toIsoDateTimeString } from '../../utils/date-time'
|
|
16
|
+
import { BackgroundWorkService } from '../background-work.service'
|
|
16
17
|
import { ChatRunRegistryTag } from '../chat-run-registry.service'
|
|
17
18
|
import { ContextCompactionServiceTag } from '../context-compaction.service'
|
|
18
19
|
import type { makeContextCompactionService } from '../context-compaction.service'
|
|
@@ -68,6 +69,7 @@ interface ThreadServiceDeps {
|
|
|
68
69
|
threadMessageService: ReturnType<typeof makeThreadMessageService>
|
|
69
70
|
contextCompactionService: ReturnType<typeof makeContextCompactionService>
|
|
70
71
|
compactionCoordination: CompactionCoordination
|
|
72
|
+
background: Context.Service.Shape<typeof BackgroundWorkService>
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
export function makeThreadService(deps: ThreadServiceDeps) {
|
|
@@ -115,7 +117,7 @@ export function makeThreadService(deps: ThreadServiceDeps) {
|
|
|
115
117
|
normalizeRecordIdStringEffect(thread.userId, TABLES.USER),
|
|
116
118
|
normalizeRecordIdStringEffect(thread.organizationId, TABLES.ORGANIZATION),
|
|
117
119
|
])
|
|
118
|
-
|
|
120
|
+
const candidate = {
|
|
119
121
|
id,
|
|
120
122
|
userId,
|
|
121
123
|
organizationId,
|
|
@@ -131,6 +133,10 @@ export function makeThreadService(deps: ThreadServiceDeps) {
|
|
|
131
133
|
members: thread.members,
|
|
132
134
|
createdAt: toIsoDateTimeString(thread.createdAt),
|
|
133
135
|
updatedAt: toIsoDateTimeString(thread.updatedAt),
|
|
136
|
+
}
|
|
137
|
+
return yield* Effect.try({
|
|
138
|
+
try: () => NormalizedThreadSchema.parse(candidate),
|
|
139
|
+
catch: (cause) => new ServiceError({ message: 'Failed to parse normalized thread.', cause }),
|
|
134
140
|
})
|
|
135
141
|
})
|
|
136
142
|
}
|
|
@@ -154,6 +160,7 @@ export function makeThreadService(deps: ThreadServiceDeps) {
|
|
|
154
160
|
const memory = createThreadMemoryBlockHelpers({
|
|
155
161
|
threadStore,
|
|
156
162
|
contextCompactionService: { compactMemoryBlock: deps.contextCompactionService.compactMemoryBlock },
|
|
163
|
+
background: deps.background,
|
|
157
164
|
})
|
|
158
165
|
|
|
159
166
|
function getById(threadId: RecordIdRef) {
|
|
@@ -311,7 +318,7 @@ export function makeThreadService(deps: ThreadServiceDeps) {
|
|
|
311
318
|
}
|
|
312
319
|
|
|
313
320
|
export class ThreadServiceTag extends Context.Service<ThreadServiceTag, ReturnType<typeof makeThreadService>>()(
|
|
314
|
-
'ThreadService',
|
|
321
|
+
'@lota-sdk/core/ThreadService',
|
|
315
322
|
) {}
|
|
316
323
|
|
|
317
324
|
export const ThreadServiceLive = Layer.effect(
|
|
@@ -323,6 +330,7 @@ export const ThreadServiceLive = Layer.effect(
|
|
|
323
330
|
const threadMessageService = yield* ThreadMessageServiceTag
|
|
324
331
|
const contextCompactionService = yield* ContextCompactionServiceTag
|
|
325
332
|
const compactionCoordination = yield* CompactionCoordinationTag
|
|
333
|
+
const background = yield* BackgroundWorkService
|
|
326
334
|
return makeThreadService({
|
|
327
335
|
db,
|
|
328
336
|
redis,
|
|
@@ -330,6 +338,7 @@ export const ThreadServiceLive = Layer.effect(
|
|
|
330
338
|
threadMessageService,
|
|
331
339
|
contextCompactionService,
|
|
332
340
|
compactionCoordination,
|
|
341
|
+
background,
|
|
333
342
|
})
|
|
334
343
|
}),
|
|
335
344
|
)
|
|
@@ -94,7 +94,7 @@ export function makeUserService(db: SurrealDBService) {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
export class UserServiceTag extends Context.Service<UserServiceTag, ReturnType<typeof makeUserService>>()(
|
|
97
|
-
'UserService',
|
|
97
|
+
'@lota-sdk/core/UserService',
|
|
98
98
|
) {}
|
|
99
99
|
|
|
100
100
|
export const UserServiceLive = Layer.effect(
|
|
@@ -85,7 +85,7 @@ export function makeWriteIntentValidatorService() {
|
|
|
85
85
|
export class WriteIntentValidatorServiceTag extends Context.Service<
|
|
86
86
|
WriteIntentValidatorServiceTag,
|
|
87
87
|
ReturnType<typeof makeWriteIntentValidatorService>
|
|
88
|
-
>()('WriteIntentValidatorService') {}
|
|
88
|
+
>()('@lota-sdk/core/WriteIntentValidatorService') {}
|
|
89
89
|
|
|
90
90
|
export const WriteIntentValidatorServiceLive = Layer.succeed(
|
|
91
91
|
WriteIntentValidatorServiceTag,
|