@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
|
@@ -33,7 +33,7 @@ import type { RecordIdInput } from '../../db/record-id'
|
|
|
33
33
|
import { ensureRecordId, recordIdToString } from '../../db/record-id'
|
|
34
34
|
import type { SurrealDBService } from '../../db/service'
|
|
35
35
|
import { TABLES } from '../../db/tables'
|
|
36
|
-
import {
|
|
36
|
+
import { makeEffectTryPromiseWithMessage } from '../../effect/helpers'
|
|
37
37
|
import { DatabaseServiceTag } from '../../effect/services'
|
|
38
38
|
import { toIsoDateTimeString, toOptionalIsoDateTimeString } from '../../utils/date-time'
|
|
39
39
|
|
|
@@ -159,7 +159,10 @@ function serializeEvent(event: PlanEventRecord): SerializablePlanEvent {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
class PlanRunServiceError extends Schema.TaggedErrorClass<PlanRunServiceError>()('PlanRunServiceError', {
|
|
163
|
+
message: Schema.String,
|
|
164
|
+
cause: Schema.optional(Schema.Defect),
|
|
165
|
+
}) {}
|
|
163
166
|
|
|
164
167
|
class PlanRunNotFoundError extends Schema.TaggedErrorClass<PlanRunNotFoundError>()('PlanRunNotFoundError', {
|
|
165
168
|
message: Schema.String,
|
|
@@ -172,25 +175,15 @@ class PlanRunSerializationError extends Schema.TaggedErrorClass<PlanRunSerializa
|
|
|
172
175
|
{ message: Schema.String },
|
|
173
176
|
) {}
|
|
174
177
|
|
|
178
|
+
const effectTryPlanRunPromise = makeEffectTryPromiseWithMessage(
|
|
179
|
+
(message, cause) => new PlanRunServiceError({ message, cause }),
|
|
180
|
+
)
|
|
181
|
+
|
|
175
182
|
function tryPlanRunPromise<A>(
|
|
176
183
|
message: string,
|
|
177
|
-
|
|
184
|
+
evaluate: () => PromiseLike<A> | Effect.Effect<A, unknown>,
|
|
178
185
|
): Effect.Effect<A, PlanRunServiceError> {
|
|
179
|
-
return
|
|
180
|
-
try {
|
|
181
|
-
const value = thunk()
|
|
182
|
-
if (Effect.isEffect(value)) {
|
|
183
|
-
return value.pipe(Effect.mapError((cause) => new ServiceError({ message, cause })))
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return Effect.tryPromise({
|
|
187
|
-
try: () => Promise.resolve(value),
|
|
188
|
-
catch: (cause) => new ServiceError({ message, cause }),
|
|
189
|
-
})
|
|
190
|
-
} catch (cause) {
|
|
191
|
-
return Effect.fail(new ServiceError({ message, cause }))
|
|
192
|
-
}
|
|
193
|
-
})
|
|
186
|
+
return effectTryPlanRunPromise(evaluate, message)
|
|
194
187
|
}
|
|
195
188
|
|
|
196
189
|
export function makePlanRunService(db: SurrealDBService) {
|
|
@@ -632,7 +625,7 @@ export function makePlanRunService(db: SurrealDBService) {
|
|
|
632
625
|
}
|
|
633
626
|
|
|
634
627
|
export class PlanRunServiceTag extends Context.Service<PlanRunServiceTag, ReturnType<typeof makePlanRunService>>()(
|
|
635
|
-
'PlanRunService',
|
|
628
|
+
'@lota-sdk/core/PlanRunService',
|
|
636
629
|
) {}
|
|
637
630
|
|
|
638
631
|
export const PlanRunServiceLive = Layer.effect(
|
|
@@ -8,7 +8,7 @@ import { ensureRecordId, recordIdToString } from '../../db/record-id'
|
|
|
8
8
|
import type { SurrealDBService } from '../../db/service'
|
|
9
9
|
import { TABLES } from '../../db/tables'
|
|
10
10
|
import { NotFoundError } from '../../effect/errors'
|
|
11
|
-
import {
|
|
11
|
+
import { makeEffectTryPromiseWithMessage } from '../../effect/helpers'
|
|
12
12
|
import { DatabaseServiceTag } from '../../effect/services'
|
|
13
13
|
import { nowDate, nowEpochMillis, toDatabaseDateTime, unsafeDateFrom } from '../../utils/date-time'
|
|
14
14
|
|
|
@@ -23,12 +23,7 @@ class PlanSchedulerError extends Schema.TaggedErrorClass<PlanSchedulerError>()('
|
|
|
23
23
|
cause: Schema.optional(Schema.Defect),
|
|
24
24
|
}) {}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
evaluate: () => PromiseLike<A> | Effect.Effect<A, unknown>,
|
|
28
|
-
message: string,
|
|
29
|
-
): Effect.Effect<A, PlanSchedulerError> {
|
|
30
|
-
return effectTryPromiseShared(evaluate, (cause) => new PlanSchedulerError({ message, cause }))
|
|
31
|
-
}
|
|
26
|
+
const effectTryPromise = makeEffectTryPromiseWithMessage((message, cause) => new PlanSchedulerError({ message, cause }))
|
|
32
27
|
|
|
33
28
|
function failPlanScheduler(message: string, cause?: unknown): Effect.Effect<never, PlanSchedulerError> {
|
|
34
29
|
return Effect.fail(new PlanSchedulerError({ message, ...(cause === undefined ? {} : { cause }) }))
|
|
@@ -143,13 +138,9 @@ export function makePlanSchedulerService(db: SurrealDBService) {
|
|
|
143
138
|
const isRecurring = schedule.scheduleSpec.type === 'cron' || schedule.scheduleSpec.type === 'monitoring'
|
|
144
139
|
const maxReached = schedule.scheduleSpec.maxFires !== undefined && newFireCount >= schedule.scheduleSpec.maxFires
|
|
145
140
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (isRecurring && !maxReached) {
|
|
150
|
-
nextFireAt = yield* computeNextFireAtEffect(schedule.scheduleSpec, now)
|
|
151
|
-
newStatus = 'active'
|
|
152
|
-
}
|
|
141
|
+
const isActive = isRecurring && !maxReached
|
|
142
|
+
const nextFireAt: Date | null = isActive ? yield* computeNextFireAtEffect(schedule.scheduleSpec, now) : null
|
|
143
|
+
const newStatus: 'active' | 'completed' = isActive ? 'active' : 'completed'
|
|
153
144
|
|
|
154
145
|
yield* effectTryPromise(
|
|
155
146
|
() =>
|
|
@@ -167,7 +158,6 @@ export function makePlanSchedulerService(db: SurrealDBService) {
|
|
|
167
158
|
'Failed to update fired schedule.',
|
|
168
159
|
)
|
|
169
160
|
|
|
170
|
-
let shouldRecoverDeadlineChecks = false
|
|
171
161
|
if (newStatus === 'active') {
|
|
172
162
|
if (!nextFireAt) {
|
|
173
163
|
return yield* new PlanSchedulerError({ message: 'Recurring schedules must resolve a next fire time.' })
|
|
@@ -185,6 +175,7 @@ export function makePlanSchedulerService(db: SurrealDBService) {
|
|
|
185
175
|
|
|
186
176
|
const runId = schedule.runId
|
|
187
177
|
const nodeId = schedule.nodeId
|
|
178
|
+
const promotedNode = Boolean(runId && nodeId)
|
|
188
179
|
if (runId && nodeId) {
|
|
189
180
|
yield* effectTryPromise(
|
|
190
181
|
() =>
|
|
@@ -195,26 +186,29 @@ export function makePlanSchedulerService(db: SurrealDBService) {
|
|
|
195
186
|
}),
|
|
196
187
|
'Failed to promote delayed plan node.',
|
|
197
188
|
)
|
|
198
|
-
shouldRecoverDeadlineChecks = true
|
|
199
189
|
}
|
|
200
190
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
191
|
+
const advancedCycle =
|
|
192
|
+
schedule.planSpecId && !schedule.runId
|
|
193
|
+
? yield* effectTryPromise(
|
|
194
|
+
() =>
|
|
195
|
+
db.findOne(
|
|
196
|
+
TABLES.PLAN_CYCLE,
|
|
197
|
+
{ scheduleId: ensureRecordId(schedule.id, TABLES.PLAN_SCHEDULE) },
|
|
198
|
+
PlanCycleRecordSchema,
|
|
199
|
+
),
|
|
200
|
+
'Failed to load plan cycle for schedule.',
|
|
201
|
+
).pipe(
|
|
202
|
+
Effect.tap((cycle) =>
|
|
203
|
+
cycle
|
|
204
|
+
? effectTryPromise(() => runtimeDeps.advanceCycle(cycle.id), 'Failed to advance plan cycle.')
|
|
205
|
+
: Effect.void,
|
|
206
|
+
),
|
|
207
|
+
Effect.map((cycle) => cycle !== null),
|
|
208
|
+
)
|
|
209
|
+
: false
|
|
216
210
|
|
|
217
|
-
if (
|
|
211
|
+
if (promotedNode || advancedCycle) {
|
|
218
212
|
yield* effectTryPromise(() => runtimeDeps.recoverDeadlineChecks(), 'Failed to recover deadline checks.')
|
|
219
213
|
}
|
|
220
214
|
})
|
|
@@ -374,7 +368,7 @@ export function makePlanSchedulerService(db: SurrealDBService) {
|
|
|
374
368
|
export class PlanSchedulerServiceTag extends Context.Service<
|
|
375
369
|
PlanSchedulerServiceTag,
|
|
376
370
|
ReturnType<typeof makePlanSchedulerService>
|
|
377
|
-
>()('PlanSchedulerService') {}
|
|
371
|
+
>()('@lota-sdk/core/PlanSchedulerService') {}
|
|
378
372
|
|
|
379
373
|
export const PlanSchedulerServiceLive = Layer.effect(
|
|
380
374
|
PlanSchedulerServiceTag,
|
|
@@ -212,7 +212,7 @@ export function makePlanTemplateService(deps: PlanTemplateDeps) {
|
|
|
212
212
|
export class PlanTemplateServiceTag extends Context.Service<
|
|
213
213
|
PlanTemplateServiceTag,
|
|
214
214
|
ReturnType<typeof makePlanTemplateService>
|
|
215
|
-
>()('PlanTemplateService') {}
|
|
215
|
+
>()('@lota-sdk/core/PlanTemplateService') {}
|
|
216
216
|
|
|
217
217
|
export const PlanTemplateServiceLive = Layer.effect(
|
|
218
218
|
PlanTemplateServiceTag,
|
|
@@ -23,11 +23,14 @@ export function withTransactionAndEventsEffect<T, E, R>(params: {
|
|
|
23
23
|
(error) => new PlanTransactionEventsError({ message: 'Failed to run plan transaction.', cause: error }),
|
|
24
24
|
),
|
|
25
25
|
)
|
|
26
|
-
yield*
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
yield* params.planEventDeliveryService
|
|
27
|
+
.dispatchEventsEffect(emittedEvents)
|
|
28
|
+
.pipe(
|
|
29
|
+
Effect.mapError(
|
|
30
|
+
(error) =>
|
|
31
|
+
new PlanTransactionEventsError({ message: 'Failed to dispatch plan transaction events.', cause: error }),
|
|
32
|
+
),
|
|
33
|
+
)
|
|
31
34
|
return result
|
|
32
35
|
})
|
|
33
36
|
}
|
|
@@ -897,7 +897,7 @@ export function makePlanValidatorService(planCoordinationService: ReturnType<typ
|
|
|
897
897
|
export class PlanValidatorServiceTag extends Context.Service<
|
|
898
898
|
PlanValidatorServiceTag,
|
|
899
899
|
ReturnType<typeof makePlanValidatorService>
|
|
900
|
-
>()('PlanValidatorService') {}
|
|
900
|
+
>()('@lota-sdk/core/PlanValidatorService') {}
|
|
901
901
|
|
|
902
902
|
export const PlanValidatorServiceLive = Layer.effect(
|
|
903
903
|
PlanValidatorServiceTag,
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { Context, Effect, Layer, Schema } from 'effect'
|
|
2
2
|
|
|
3
|
+
import { ServiceError } from '../../effect/errors'
|
|
4
|
+
import { makeEffectTryPromiseWithMessage } from '../../effect/helpers'
|
|
3
5
|
import { RedisServiceTag } from '../../effect/services'
|
|
4
6
|
import { toValidationError } from '../../effect/zod'
|
|
5
7
|
import type { RedisConnectionManager } from '../../redis/connection'
|
|
6
8
|
import { nowEpochMillis } from '../../utils/date-time'
|
|
7
9
|
|
|
10
|
+
const tryWorkspacePromise = makeEffectTryPromiseWithMessage((message, cause) => new ServiceError({ message, cause }))
|
|
11
|
+
|
|
8
12
|
const PlanWorkspaceEntrySchema = Schema.Struct({
|
|
9
13
|
value: Schema.Unknown,
|
|
10
14
|
version: Schema.Number,
|
|
@@ -29,10 +33,9 @@ function parsePlanWorkspaceEntryEffect(
|
|
|
29
33
|
fieldKey: string,
|
|
30
34
|
raw: string,
|
|
31
35
|
): Effect.Effect<PlanWorkspaceEntry, ReturnType<typeof toValidationError>> {
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
})
|
|
36
|
+
return Schema.decodeUnknownEffect(PlanWorkspaceEntryJsonSchema)(raw).pipe(
|
|
37
|
+
Effect.mapError((error) => toValidationError(error, `Invalid plan workspace entry JSON for "${fieldKey}"`)),
|
|
38
|
+
)
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
export function makePlanWorkspaceService(redis: RedisConnectionManager) {
|
|
@@ -56,7 +59,10 @@ export function makePlanWorkspaceService(redis: RedisConnectionManager) {
|
|
|
56
59
|
timestamp: nowEpochMillis(),
|
|
57
60
|
}
|
|
58
61
|
const serialized = yield* Schema.encodeEffect(PlanWorkspaceEntryJsonSchema)(entry)
|
|
59
|
-
yield*
|
|
62
|
+
yield* tryWorkspacePromise(
|
|
63
|
+
() => conn.hset(hashKey, fieldKey, serialized),
|
|
64
|
+
'Failed to write plan workspace entry.',
|
|
65
|
+
)
|
|
60
66
|
})
|
|
61
67
|
|
|
62
68
|
const snapshotReadEffect = (params: { runId: string; readerNodeId: string; snapshotSequence?: number }) =>
|
|
@@ -64,7 +70,7 @@ export function makePlanWorkspaceService(redis: RedisConnectionManager) {
|
|
|
64
70
|
const conn = redis.getConnection()
|
|
65
71
|
const hashKey = `${PLAN_WORKSPACE_KEY_PREFIX}${params.runId}`
|
|
66
72
|
const nodePrefix = `${params.readerNodeId}:`
|
|
67
|
-
const all = yield*
|
|
73
|
+
const all = yield* tryWorkspacePromise(() => conn.hgetall(hashKey), 'Failed to read plan workspace snapshot.')
|
|
68
74
|
const result: Record<string, PlanWorkspaceEntry> = {}
|
|
69
75
|
for (const [fieldKey, raw] of Object.entries(all)) {
|
|
70
76
|
if (!fieldKey.startsWith(nodePrefix)) continue
|
|
@@ -83,11 +89,11 @@ export function makePlanWorkspaceService(redis: RedisConnectionManager) {
|
|
|
83
89
|
const hashKey = `${PLAN_WORKSPACE_KEY_PREFIX}${params.runId}`
|
|
84
90
|
const key = params.key
|
|
85
91
|
if (key !== undefined) {
|
|
86
|
-
const raw = yield*
|
|
92
|
+
const raw = yield* tryWorkspacePromise(() => conn.hget(hashKey, key), 'Failed to read plan workspace entry.')
|
|
87
93
|
if (!raw) return {}
|
|
88
94
|
return { [key]: yield* parsePlanWorkspaceEntryEffect(key, raw) }
|
|
89
95
|
}
|
|
90
|
-
const all = yield*
|
|
96
|
+
const all = yield* tryWorkspacePromise(() => conn.hgetall(hashKey), 'Failed to read plan workspace entries.')
|
|
91
97
|
const result: Record<string, PlanWorkspaceEntry> = {}
|
|
92
98
|
for (const [k, v] of Object.entries(all)) {
|
|
93
99
|
result[k] = yield* parsePlanWorkspaceEntryEffect(k, v)
|
|
@@ -97,10 +103,10 @@ export function makePlanWorkspaceService(redis: RedisConnectionManager) {
|
|
|
97
103
|
|
|
98
104
|
const cleanupEffect = (runId: string) =>
|
|
99
105
|
Effect.asVoid(
|
|
100
|
-
|
|
106
|
+
tryWorkspacePromise(() => {
|
|
101
107
|
const conn = redis.getConnection()
|
|
102
108
|
return conn.del(`${PLAN_WORKSPACE_KEY_PREFIX}${runId}`)
|
|
103
|
-
}),
|
|
109
|
+
}, 'Failed to clean up plan workspace.'),
|
|
104
110
|
)
|
|
105
111
|
|
|
106
112
|
return {
|
|
@@ -114,7 +120,7 @@ export function makePlanWorkspaceService(redis: RedisConnectionManager) {
|
|
|
114
120
|
export class PlanWorkspaceServiceTag extends Context.Service<
|
|
115
121
|
PlanWorkspaceServiceTag,
|
|
116
122
|
ReturnType<typeof makePlanWorkspaceService>
|
|
117
|
-
>()('PlanWorkspaceService') {}
|
|
123
|
+
>()('@lota-sdk/core/PlanWorkspaceService') {}
|
|
118
124
|
|
|
119
125
|
export const PlanWorkspaceServiceLive = Layer.effect(
|
|
120
126
|
PlanWorkspaceServiceTag,
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import type { OwnershipDispatchContext, PlanNodeSpec, PluginPlanNodeOwner } 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 tryPluginExecutorPromise = makeEffectTryPromiseWithMessage(
|
|
9
|
+
(message, cause) => new ServiceError({ message, cause }),
|
|
10
|
+
)
|
|
6
11
|
import type { LotaPlugin, PluginNodeExecutionParams } from '../runtime/plugin-types'
|
|
7
12
|
import type { ResolvedLotaRuntimeConfig } from '../runtime/runtime-config'
|
|
8
13
|
import type { PlanValidationIssueInput } from './plan/plan-validator.service'
|
|
@@ -82,28 +87,28 @@ export function makePluginExecutorService(config: ResolvedLotaRuntimeConfig) {
|
|
|
82
87
|
return []
|
|
83
88
|
},
|
|
84
89
|
|
|
85
|
-
executeNode(params: {
|
|
90
|
+
executeNode: Effect.fn('PluginExecutor.executeNode')(function* (params: {
|
|
86
91
|
nodeSpec: PlanNodeSpec
|
|
87
92
|
resolvedInput: Record<string, unknown>
|
|
88
93
|
context: OwnershipDispatchContext
|
|
89
94
|
}) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
95
|
+
const owner = params.nodeSpec.owner
|
|
96
|
+
if (!isPluginOwner(owner)) {
|
|
97
|
+
return yield* new BadRequestError({
|
|
98
|
+
message: `PluginExecutor cannot execute owner type "${owner.executorType}".`,
|
|
99
|
+
})
|
|
100
|
+
}
|
|
97
101
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
const plugin = getPluginRuntime()[owner.ref]
|
|
103
|
+
const nodeExecutor = plugin?.nodeExecutor
|
|
104
|
+
if (!plugin || !nodeExecutor || !nodeExecutor.supportedOperations.includes(owner.operation)) {
|
|
105
|
+
return yield* new BadRequestError({
|
|
106
|
+
message: `Plugin executor ${owner.ref}.${owner.operation} is not registered.`,
|
|
107
|
+
})
|
|
108
|
+
}
|
|
105
109
|
|
|
106
|
-
|
|
110
|
+
return yield* tryPluginExecutorPromise(
|
|
111
|
+
() =>
|
|
107
112
|
nodeExecutor.executeNode(
|
|
108
113
|
buildPluginExecutionParams({
|
|
109
114
|
owner,
|
|
@@ -112,16 +117,16 @@ export function makePluginExecutorService(config: ResolvedLotaRuntimeConfig) {
|
|
|
112
117
|
context: params.context,
|
|
113
118
|
}),
|
|
114
119
|
),
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
},
|
|
120
|
+
`Plugin executor "${owner.ref}.${owner.operation}" failed.`,
|
|
121
|
+
).pipe(Effect.withSpan('PluginExecutor.invoke'))
|
|
122
|
+
}),
|
|
118
123
|
}
|
|
119
124
|
}
|
|
120
125
|
|
|
121
126
|
export class PluginExecutorServiceTag extends Context.Service<
|
|
122
127
|
PluginExecutorServiceTag,
|
|
123
128
|
ReturnType<typeof makePluginExecutorService>
|
|
124
|
-
>()('PluginExecutorService') {}
|
|
129
|
+
>()('@lota-sdk/core/PluginExecutorService') {}
|
|
125
130
|
|
|
126
131
|
export const PluginExecutorServiceLive = Layer.effect(
|
|
127
132
|
PluginExecutorServiceTag,
|
|
@@ -139,7 +139,7 @@ export function makeQualityMetricsService(db: SurrealDBService) {
|
|
|
139
139
|
export class QualityMetricsServiceTag extends Context.Service<
|
|
140
140
|
QualityMetricsServiceTag,
|
|
141
141
|
ReturnType<typeof makeQualityMetricsService>
|
|
142
|
-
>()('QualityMetricsService') {}
|
|
142
|
+
>()('@lota-sdk/core/QualityMetricsService') {}
|
|
143
143
|
|
|
144
144
|
export const QualityMetricsServiceLive = Layer.effect(
|
|
145
145
|
QualityMetricsServiceTag,
|
|
@@ -14,6 +14,7 @@ import type { SurrealDBService } from '../db/service'
|
|
|
14
14
|
import { TABLES } from '../db/tables'
|
|
15
15
|
import { isRetriableTransactionConflict } from '../db/transaction-conflict'
|
|
16
16
|
import { BadRequestError, DatabaseError } from '../effect/errors'
|
|
17
|
+
import { makeEffectTryPromiseWithMessage } from '../effect/helpers'
|
|
17
18
|
import { DatabaseServiceTag } from '../effect/services'
|
|
18
19
|
import { createDeterministicRecordId } from '../utils/crypto'
|
|
19
20
|
import { nowDate, unsafeDateFrom } from '../utils/date-time'
|
|
@@ -184,25 +185,15 @@ function getQueuedStatus(job: TrackedBullJobLike): QueueJobStatus {
|
|
|
184
185
|
return typeof delay === 'number' && delay > 0 ? 'delayed' : 'waiting'
|
|
185
186
|
}
|
|
186
187
|
|
|
188
|
+
const effectTryQueueJobPersistence = makeEffectTryPromiseWithMessage(
|
|
189
|
+
(message, cause) => new DatabaseError({ message, cause }),
|
|
190
|
+
)
|
|
191
|
+
|
|
187
192
|
function tryQueueJobPersistence<A>(
|
|
188
193
|
message: string,
|
|
189
|
-
|
|
194
|
+
evaluate: () => PromiseLike<A> | Effect.Effect<A, unknown>,
|
|
190
195
|
): Effect.Effect<A, DatabaseError> {
|
|
191
|
-
return
|
|
192
|
-
try {
|
|
193
|
-
const value = thunk()
|
|
194
|
-
if (Effect.isEffect(value)) {
|
|
195
|
-
return value.pipe(Effect.mapError((cause) => new DatabaseError({ message, cause })))
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return Effect.tryPromise({
|
|
199
|
-
try: () => Promise.resolve(value),
|
|
200
|
-
catch: (cause: unknown) => new DatabaseError({ message, cause }),
|
|
201
|
-
})
|
|
202
|
-
} catch (cause) {
|
|
203
|
-
return Effect.fail(new DatabaseError({ message, cause }))
|
|
204
|
-
}
|
|
205
|
-
})
|
|
196
|
+
return effectTryQueueJobPersistence(evaluate, message)
|
|
206
197
|
}
|
|
207
198
|
|
|
208
199
|
function withPersistenceRetry<T>(work: Effect.Effect<T, DatabaseError>): Effect.Effect<T, DatabaseError> {
|
|
@@ -456,7 +447,7 @@ export function makeQueueJobService(db: SurrealDBService) {
|
|
|
456
447
|
}
|
|
457
448
|
|
|
458
449
|
export class QueueJobServiceTag extends Context.Service<QueueJobServiceTag, ReturnType<typeof makeQueueJobService>>()(
|
|
459
|
-
'QueueJobService',
|
|
450
|
+
'@lota-sdk/core/QueueJobService',
|
|
460
451
|
) {}
|
|
461
452
|
|
|
462
453
|
export const QueueJobServiceLive = Layer.effect(
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Context, Effect, Layer } from 'effect'
|
|
2
2
|
|
|
3
|
+
import { ServiceError } from '../effect/errors'
|
|
4
|
+
import { makeEffectTryPromiseWithMessage } from '../effect/helpers'
|
|
3
5
|
import type { HelperModelRuntime } from '../runtime/helper-model'
|
|
4
6
|
import { HelperModelTag } from '../runtime/helper-model'
|
|
5
7
|
import { normalizeTitle } from '../runtime/title-helpers'
|
|
@@ -12,6 +14,10 @@ import { RecentActivityServiceTag } from './recent-activity.service'
|
|
|
12
14
|
|
|
13
15
|
const RECENT_ACTIVITY_TITLE_TIMEOUT_MS = 60_000
|
|
14
16
|
|
|
17
|
+
const tryRecentActivityTitlePromise = makeEffectTryPromiseWithMessage(
|
|
18
|
+
(message, cause) => new ServiceError({ message, cause }),
|
|
19
|
+
)
|
|
20
|
+
|
|
15
21
|
function buildRefinementPromptInput(
|
|
16
22
|
candidate: {
|
|
17
23
|
id: string
|
|
@@ -55,14 +61,16 @@ export function makeRecentActivityTitleService(
|
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
const refinedTitle = normalizeTitle(
|
|
58
|
-
yield*
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
yield* tryRecentActivityTitlePromise(
|
|
65
|
+
() =>
|
|
66
|
+
helperModelRuntime.generateHelperText({
|
|
67
|
+
tag: 'recent-activity-title-refinement',
|
|
68
|
+
createAgent: createRecentActivityTitleRefinerAgent,
|
|
69
|
+
defaultSystemPrompt: RECENT_ACTIVITY_TITLE_REFINER_PROMPT,
|
|
70
|
+
timeoutMs: RECENT_ACTIVITY_TITLE_TIMEOUT_MS,
|
|
71
|
+
messages: [{ role: 'user', content: promptInput }],
|
|
72
|
+
}),
|
|
73
|
+
'Failed to generate recent activity title refinement.',
|
|
66
74
|
),
|
|
67
75
|
)
|
|
68
76
|
if (
|
|
@@ -84,7 +92,7 @@ export function makeRecentActivityTitleService(
|
|
|
84
92
|
export class RecentActivityTitleServiceTag extends Context.Service<
|
|
85
93
|
RecentActivityTitleServiceTag,
|
|
86
94
|
ReturnType<typeof makeRecentActivityTitleService>
|
|
87
|
-
>()('RecentActivityTitleService') {}
|
|
95
|
+
>()('@lota-sdk/core/RecentActivityTitleService') {}
|
|
88
96
|
|
|
89
97
|
export const RecentActivityTitleServiceLive = Layer.effect(
|
|
90
98
|
RecentActivityTitleServiceTag,
|
|
@@ -387,7 +387,7 @@ export function makeRecentActivityService(db: SurrealDBService) {
|
|
|
387
387
|
export class RecentActivityServiceTag extends Context.Service<
|
|
388
388
|
RecentActivityServiceTag,
|
|
389
389
|
ReturnType<typeof makeRecentActivityService>
|
|
390
|
-
>()('RecentActivityService') {}
|
|
390
|
+
>()('@lota-sdk/core/RecentActivityService') {}
|
|
391
391
|
|
|
392
392
|
export const RecentActivityServiceLive = Layer.effect(
|
|
393
393
|
RecentActivityServiceTag,
|
|
@@ -33,7 +33,7 @@ export function makeSkillResolverService(deps: {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export class SkillResolverServiceTag extends Context.Service<SkillResolverServiceTag, SkillResolverService>()(
|
|
36
|
-
'SkillResolverService',
|
|
36
|
+
'@lota-sdk/core/SkillResolverService',
|
|
37
37
|
) {}
|
|
38
38
|
|
|
39
39
|
export const SkillResolverServiceLive = Layer.effect(
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { normalizeMessageBatch } from '@lota-sdk/shared'
|
|
2
|
-
import { Context, Effect, Layer } from 'effect'
|
|
2
|
+
import { Context, Effect, Layer, Schema } from 'effect'
|
|
3
3
|
import { z } from 'zod'
|
|
4
4
|
|
|
5
|
+
import { makeEffectTryPromiseWithMessage } from '../effect/helpers'
|
|
5
6
|
import { RedisServiceTag, RuntimeConfigServiceTag } from '../effect/services'
|
|
6
7
|
import type { RedisConnectionManager } from '../redis/connection'
|
|
7
8
|
import type { ResolvedLotaRuntimeConfig } from '../runtime/runtime-config'
|
|
8
9
|
import type { LotaRuntimeBackgroundCursor, LotaRuntimeBackgroundCursorKind } from '../runtime/runtime-extensions'
|
|
9
10
|
|
|
11
|
+
export class SocialChatHistoryError extends Schema.TaggedErrorClass<SocialChatHistoryError>()(
|
|
12
|
+
'SocialChatHistoryError',
|
|
13
|
+
{ message: Schema.String, cause: Schema.optional(Schema.Defect) },
|
|
14
|
+
) {}
|
|
15
|
+
|
|
16
|
+
const tryRedisPromise = makeEffectTryPromiseWithMessage(
|
|
17
|
+
(message, cause) => new SocialChatHistoryError({ message, cause }),
|
|
18
|
+
)
|
|
19
|
+
|
|
10
20
|
const DEFAULT_SOCIAL_CHAT_HISTORY_PREFIX = 'lota:social:history'
|
|
11
21
|
|
|
12
22
|
const SocialChatMessageRoleSchema = z.enum(['user', 'assistant'])
|
|
@@ -57,6 +67,8 @@ const SocialChatHistoryMessageSchema = z.object({
|
|
|
57
67
|
metadata: SocialChatHistoryMetadataSchema.optional(),
|
|
58
68
|
cursor: z.object({ createdAt: z.coerce.date(), id: z.string().trim().min(1) }),
|
|
59
69
|
})
|
|
70
|
+
const SocialChatHistoryCursorSchema = z.object({ createdAt: z.coerce.date(), id: z.string().trim().min(1) })
|
|
71
|
+
const decodeJsonStringEffect = Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)
|
|
60
72
|
|
|
61
73
|
export type SocialChatHistoryPart = z.infer<typeof SocialChatHistoryPartSchema>
|
|
62
74
|
export type SocialChatHistoryMetadata = z.infer<typeof SocialChatHistoryMetadataSchema>
|
|
@@ -101,7 +113,7 @@ export function makeSocialChatHistoryService(
|
|
|
101
113
|
const parseStoredMessageEffect = (value: string | null): Effect.Effect<SocialChatHistoryMessage | null> => {
|
|
102
114
|
if (!value) return Effect.succeed(null)
|
|
103
115
|
|
|
104
|
-
return
|
|
116
|
+
return decodeJsonStringEffect(value).pipe(
|
|
105
117
|
Effect.map((parsed) => {
|
|
106
118
|
const validated = SocialChatHistoryMessageSchema.safeParse(parsed)
|
|
107
119
|
return validated.success ? validated.data : null
|
|
@@ -116,9 +128,9 @@ export function makeSocialChatHistoryService(
|
|
|
116
128
|
const parseCursorEffect = (value: string | null): Effect.Effect<LotaRuntimeBackgroundCursor | null> => {
|
|
117
129
|
if (!value) return Effect.succeed(null)
|
|
118
130
|
|
|
119
|
-
return
|
|
131
|
+
return decodeJsonStringEffect(value).pipe(
|
|
120
132
|
Effect.map((parsed) => {
|
|
121
|
-
const validated =
|
|
133
|
+
const validated = SocialChatHistoryCursorSchema.safeParse(parsed)
|
|
122
134
|
return validated.success ? validated.data : null
|
|
123
135
|
}),
|
|
124
136
|
Effect.catch(() => Effect.succeed(null)),
|
|
@@ -145,19 +157,20 @@ export function makeSocialChatHistoryService(
|
|
|
145
157
|
multi.zadd(workspaceIndexKey(message.workspaceId), score, storageKey)
|
|
146
158
|
}
|
|
147
159
|
|
|
148
|
-
yield*
|
|
160
|
+
yield* tryRedisPromise(() => multi.exec(), 'Failed to upsert social chat messages.')
|
|
149
161
|
return normalizedMessages
|
|
150
162
|
})
|
|
151
163
|
|
|
152
164
|
const listThreadMessagesEffect = (params: { workspaceId: string; threadId: string }) =>
|
|
153
165
|
Effect.gen(function* () {
|
|
154
166
|
const conn = redis.getConnection()
|
|
155
|
-
const storageKeys = yield*
|
|
156
|
-
conn.zrange(threadIndexKey(params.workspaceId, params.threadId), 0, -1),
|
|
167
|
+
const storageKeys = yield* tryRedisPromise(
|
|
168
|
+
() => conn.zrange(threadIndexKey(params.workspaceId, params.threadId), 0, -1),
|
|
169
|
+
'Failed to list thread message keys.',
|
|
157
170
|
)
|
|
158
171
|
if (storageKeys.length === 0) return [] as SocialChatHistoryMessage[]
|
|
159
172
|
|
|
160
|
-
const storedValues = yield*
|
|
173
|
+
const storedValues = yield* tryRedisPromise(() => conn.mget(storageKeys), 'Failed to read thread messages.')
|
|
161
174
|
const parsedMessages = yield* Effect.forEach(storedValues, parseStoredMessageEffect)
|
|
162
175
|
return parsedMessages
|
|
163
176
|
.filter((message): message is SocialChatHistoryMessage => message !== null)
|
|
@@ -175,14 +188,16 @@ export function makeSocialChatHistoryService(
|
|
|
175
188
|
const scoreStart =
|
|
176
189
|
params.cursor?.createdAt.getTime() ??
|
|
177
190
|
(params.onboardingCutoff ? params.onboardingCutoff.getTime() : Number.NEGATIVE_INFINITY)
|
|
178
|
-
const storageKeys = yield*
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
191
|
+
const storageKeys = yield* tryRedisPromise(
|
|
192
|
+
() =>
|
|
193
|
+
params.cursor || params.onboardingCutoff
|
|
194
|
+
? conn.zrangebyscore(indexKey, scoreStart, '+inf')
|
|
195
|
+
: conn.zrange(indexKey, 0, -1),
|
|
196
|
+
'Failed to list workspace message keys.',
|
|
182
197
|
)
|
|
183
198
|
if (storageKeys.length === 0) return [] as SocialChatHistoryMessage[]
|
|
184
199
|
|
|
185
|
-
const storedValues = yield*
|
|
200
|
+
const storedValues = yield* tryRedisPromise(() => conn.mget(storageKeys), 'Failed to read workspace messages.')
|
|
186
201
|
const parsedMessages = yield* Effect.forEach(storedValues, parseStoredMessageEffect)
|
|
187
202
|
return parsedMessages
|
|
188
203
|
.filter((message): message is SocialChatHistoryMessage => message !== null)
|
|
@@ -210,18 +225,20 @@ export function makeSocialChatHistoryService(
|
|
|
210
225
|
}).pipe(Effect.map((messages) => messages.length > 0))
|
|
211
226
|
|
|
212
227
|
const getBackgroundCursorEffect = (kind: LotaRuntimeBackgroundCursorKind, workspaceId: string) =>
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
228
|
+
tryRedisPromise(
|
|
229
|
+
() => redis.getConnection().get(cursorKey(kind, workspaceId)),
|
|
230
|
+
'Failed to read background cursor.',
|
|
231
|
+
).pipe(Effect.flatMap((value) => parseCursorEffect(value)))
|
|
216
232
|
|
|
217
233
|
const setBackgroundCursorEffect = (
|
|
218
234
|
kind: LotaRuntimeBackgroundCursorKind,
|
|
219
235
|
workspaceId: string,
|
|
220
236
|
cursor: LotaRuntimeBackgroundCursor,
|
|
221
237
|
) =>
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
238
|
+
tryRedisPromise(
|
|
239
|
+
() => redis.getConnection().set(cursorKey(kind, workspaceId), serializeCursor(cursor)),
|
|
240
|
+
'Failed to write background cursor.',
|
|
241
|
+
).pipe(Effect.asVoid)
|
|
225
242
|
|
|
226
243
|
return {
|
|
227
244
|
upsertMessages: upsertMessagesEffect,
|
|
@@ -236,7 +253,7 @@ export function makeSocialChatHistoryService(
|
|
|
236
253
|
export class SocialChatHistoryServiceTag extends Context.Service<
|
|
237
254
|
SocialChatHistoryServiceTag,
|
|
238
255
|
ReturnType<typeof makeSocialChatHistoryService>
|
|
239
|
-
>()('SocialChatHistoryService') {}
|
|
256
|
+
>()('@lota-sdk/core/SocialChatHistoryService') {}
|
|
240
257
|
|
|
241
258
|
export const SocialChatHistoryServiceLive = Layer.effect(
|
|
242
259
|
SocialChatHistoryServiceTag,
|