@lota-sdk/core 0.4.9 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/ai/embedding-cache.ts +3 -1
- package/src/ai-gateway/ai-gateway.ts +164 -82
- package/src/ai-gateway/index.ts +16 -1
- package/src/config/agent-defaults.ts +4 -107
- 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 +22 -25
- package/src/config/thread-defaults.ts +1 -10
- package/src/create-runtime.ts +145 -670
- package/src/db/base.service.ts +30 -38
- 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 +496 -384
- package/src/db/startup.ts +30 -19
- package/src/effect/helpers.ts +30 -5
- package/src/effect/index.ts +7 -7
- package/src/effect/layers.ts +75 -72
- package/src/effect/services.ts +15 -11
- package/src/embeddings/provider.ts +65 -71
- package/src/index.ts +13 -12
- package/src/queues/autonomous-job.queue.ts +177 -143
- package/src/queues/context-compaction.queue.ts +41 -39
- package/src/queues/delayed-node-promotion.queue.ts +61 -42
- package/src/queues/document-processor.queue.ts +5 -3
- package/src/queues/index.ts +1 -0
- package/src/queues/memory-consolidation.queue.ts +79 -53
- package/src/queues/organization-learning.queue.ts +70 -33
- package/src/queues/plan-agent-heartbeat.queue.ts +111 -83
- package/src/queues/plan-scheduler.queue.ts +101 -97
- package/src/queues/post-chat-memory.queue.ts +56 -46
- package/src/queues/queue-factory.ts +146 -69
- package/src/queues/queues.service.ts +61 -0
- package/src/queues/title-generation.queue.ts +44 -44
- package/src/redis/connection.ts +181 -164
- package/src/redis/org-memory-lock.ts +24 -9
- package/src/redis/redis-lease-lock.ts +8 -1
- package/src/redis/stream-context.ts +17 -9
- package/src/runtime/agent-identity-overrides.ts +7 -3
- package/src/runtime/agent-runtime-policy.ts +10 -5
- package/src/runtime/agent-stream-helpers.ts +24 -15
- package/src/runtime/chat-run-orchestration.ts +1 -1
- package/src/runtime/context-compaction/context-compaction-runtime.ts +28 -32
- package/src/runtime/context-compaction/context-compaction.ts +131 -85
- package/src/runtime/domain-layer.ts +203 -0
- package/src/runtime/execution-plan-visibility.ts +5 -2
- package/src/runtime/graph-designer.ts +0 -14
- package/src/runtime/helper-model.ts +8 -4
- package/src/runtime/index.ts +1 -1
- package/src/runtime/indexed-repositories-policy.ts +2 -6
- 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 +58 -62
- package/src/runtime/post-turn-side-effects.ts +139 -161
- package/src/runtime/retrieval-adapters.ts +4 -4
- package/src/runtime/runtime-config.ts +3 -9
- package/src/runtime/runtime-extensions.ts +0 -43
- package/src/runtime/runtime-lifecycle.ts +124 -0
- package/src/runtime/runtime-services.ts +455 -0
- package/src/runtime/runtime-worker-registry.ts +113 -30
- package/src/runtime/social-chat/social-chat-agent-runner.ts +13 -8
- package/src/runtime/social-chat/social-chat-history.ts +24 -13
- package/src/runtime/social-chat/social-chat.ts +420 -369
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +64 -57
- package/src/runtime/team-consultation/team-consultation-prompts.ts +11 -6
- package/src/runtime/thread-chat-helpers.ts +18 -9
- package/src/runtime/thread-turn-context.ts +28 -74
- package/src/runtime/turn-lifecycle.ts +6 -14
- package/src/services/agent-activity.service.ts +169 -176
- package/src/services/agent-executor.service.ts +207 -196
- package/src/services/artifact.service.ts +10 -5
- package/src/services/attachment.service.ts +16 -48
- package/src/services/autonomous-job.service.ts +81 -87
- 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 +8 -10
- package/src/services/document-chunk.service.ts +8 -17
- package/src/services/execution-plan/execution-plan-graph.ts +122 -109
- package/src/services/execution-plan/execution-plan-schedule.ts +1 -15
- package/src/services/execution-plan/execution-plan.service.ts +68 -51
- package/src/services/feedback-loop.service.ts +1 -1
- package/src/services/global-orchestrator.service.ts +49 -15
- package/src/services/graph-full-routing.ts +49 -37
- 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-conversation.ts +10 -5
- 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 +37 -52
- 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 +148 -95
- package/src/services/plan/plan-agent-heartbeat.service.ts +30 -16
- package/src/services/plan/plan-agent-query.service.ts +13 -9
- 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 +99 -113
- package/src/services/plan/plan-coordination.service.ts +1 -1
- package/src/services/plan/plan-cycle.service.ts +171 -202
- package/src/services/plan/plan-deadline.service.ts +304 -307
- package/src/services/plan/plan-event-delivery.service.ts +84 -72
- package/src/services/plan/plan-executor-context.ts +2 -0
- package/src/services/plan/plan-executor-graph.ts +375 -353
- package/src/services/plan/plan-executor-helpers.ts +60 -75
- package/src/services/plan/plan-executor.service.ts +494 -489
- package/src/services/plan/plan-run.service.ts +12 -19
- package/src/services/plan/plan-scheduler.service.ts +89 -82
- 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 +22 -10
- 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 +37 -19
- 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 +30 -13
- package/src/services/thread/thread-title.service.ts +1 -1
- package/src/services/thread/thread-turn-execution.ts +87 -83
- package/src/services/thread/thread-turn-preparation.service.ts +65 -40
- package/src/services/thread/thread-turn-streaming.ts +32 -36
- package/src/services/thread/thread-turn.ts +43 -29
- package/src/services/thread/thread.service.ts +32 -8
- 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 +9 -6
- 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/thread-router.agent.ts +23 -20
- package/src/system-agents/title-generator.agent.ts +1 -1
- package/src/tools/execution-plan.tool.ts +36 -20
- package/src/tools/fetch-webpage.tool.ts +30 -22
- package/src/tools/firecrawl-client.ts +1 -6
- package/src/tools/plan-approval.tool.ts +9 -1
- package/src/tools/remember-memory.tool.ts +3 -6
- package/src/tools/research-topic.tool.ts +12 -3
- package/src/tools/search-web.tool.ts +26 -18
- package/src/tools/search.tool.ts +4 -5
- package/src/tools/team-think.tool.ts +139 -121
- package/src/utils/async.ts +15 -6
- package/src/utils/errors.ts +27 -15
- package/src/workers/bootstrap.ts +34 -58
- package/src/workers/memory-consolidation.worker.ts +4 -1
- package/src/workers/organization-learning.worker.ts +16 -3
- package/src/workers/regular-chat-memory-digest.helpers.ts +3 -4
- package/src/workers/regular-chat-memory-digest.runner.ts +46 -29
- package/src/workers/skill-extraction.runner.ts +13 -15
- package/src/workers/worker-utils.ts +14 -8
- package/src/config/search.ts +0 -3
- package/src/effect/awaitable-effect.ts +0 -87
- package/src/effect/runtime-ref.ts +0 -25
- package/src/effect/runtime.ts +0 -31
- package/src/redis/runtime-connection.ts +0 -10
- package/src/runtime/agent-types.ts +0 -1
|
@@ -22,7 +22,7 @@ import type {
|
|
|
22
22
|
UpdateAutonomousJobInput,
|
|
23
23
|
} from '@lota-sdk/shared'
|
|
24
24
|
import type { Job } from 'bullmq'
|
|
25
|
-
import { Context, Cron, Schema, Effect, Layer } from 'effect'
|
|
25
|
+
import { Context, Cron, Schema, Effect, Layer, Ref } from 'effect'
|
|
26
26
|
import { BoundQuery, RecordId } from 'surrealdb'
|
|
27
27
|
import { z } from 'zod'
|
|
28
28
|
|
|
@@ -32,7 +32,8 @@ import type { SurrealDBService } from '../db/service'
|
|
|
32
32
|
import { TABLES } from '../db/tables'
|
|
33
33
|
import { makeEffectTryPromiseWithMessage } from '../effect/helpers'
|
|
34
34
|
import { DatabaseServiceTag, RuntimeConfigServiceTag } from '../effect/services'
|
|
35
|
-
import type { AutonomousJobQueuePayload } from '../queues/autonomous-job.queue'
|
|
35
|
+
import type { AutonomousJobQueuePayload, AutonomousJobQueueRuntime } from '../queues/autonomous-job.queue'
|
|
36
|
+
import { LotaQueuesServiceTag } from '../queues/queues.service'
|
|
36
37
|
import type { ResolvedLotaRuntimeConfig } from '../runtime/runtime-config'
|
|
37
38
|
import { extractMessageText } from '../runtime/thread-chat-helpers'
|
|
38
39
|
import { buildAutonomousAtJobId, encodeBullmqId } from '../utils/autonomous-job-ids'
|
|
@@ -49,12 +50,8 @@ import { ExecutionPlanServiceTag } from './execution-plan/execution-plan.service
|
|
|
49
50
|
import type { makeQueueJobService } from './queue-job.service'
|
|
50
51
|
import { QueueJobServiceTag } from './queue-job.service'
|
|
51
52
|
import type { PreparedThreadTurnResult } from './thread/thread-turn'
|
|
52
|
-
import type { ThreadTurnParams } from './thread/thread-turn-preparation.service'
|
|
53
53
|
import type { makeThreadService } from './thread/thread.service'
|
|
54
54
|
import { ThreadServiceTag } from './thread/thread.service'
|
|
55
|
-
// runThreadTurnInBackground is imported dynamically below
|
|
56
|
-
|
|
57
|
-
type ThreadTurnModule = { runThreadTurnInBackground(params: ThreadTurnParams): Promise<PreparedThreadTurnResult> }
|
|
58
55
|
|
|
59
56
|
const AUTONOMOUS_JOB_QUEUE_NAME = 'autonomous-job'
|
|
60
57
|
|
|
@@ -312,27 +309,22 @@ function getRunRowEffect(
|
|
|
312
309
|
})
|
|
313
310
|
}
|
|
314
311
|
|
|
315
|
-
function unscheduleRowEffect(
|
|
312
|
+
function unscheduleRowEffect(
|
|
313
|
+
deps: AutonomousJobDeps,
|
|
314
|
+
row: AutonomousJobRow,
|
|
315
|
+
): Effect.Effect<void, AutonomousJobServiceError> {
|
|
316
316
|
if (row.schedule.kind === 'at') {
|
|
317
317
|
return Effect.gen(function* () {
|
|
318
|
-
const { removeAutonomousAtJob } = yield* effectTryPromise(
|
|
319
|
-
() => import('../queues/autonomous-job.queue'),
|
|
320
|
-
'Failed to load autonomous job queue helpers.',
|
|
321
|
-
)
|
|
322
318
|
yield* effectTryPromise(
|
|
323
|
-
() => removeAutonomousAtJob(recordIdToString(row.id, TABLES.AUTONOMOUS_JOB)),
|
|
319
|
+
() => deps.autonomousJobQueue.removeAutonomousAtJob(recordIdToString(row.id, TABLES.AUTONOMOUS_JOB)),
|
|
324
320
|
'Failed to remove autonomous at-job.',
|
|
325
321
|
)
|
|
326
322
|
})
|
|
327
323
|
}
|
|
328
324
|
|
|
329
325
|
return Effect.gen(function* () {
|
|
330
|
-
const { removeAutonomousJobScheduler } = yield* effectTryPromise(
|
|
331
|
-
() => import('../queues/autonomous-job.queue'),
|
|
332
|
-
'Failed to load autonomous job queue helpers.',
|
|
333
|
-
)
|
|
334
326
|
yield* effectTryPromise(
|
|
335
|
-
() => removeAutonomousJobScheduler(recordIdToString(row.id, TABLES.AUTONOMOUS_JOB)),
|
|
327
|
+
() => deps.autonomousJobQueue.removeAutonomousJobScheduler(recordIdToString(row.id, TABLES.AUTONOMOUS_JOB)),
|
|
336
328
|
'Failed to remove autonomous job scheduler.',
|
|
337
329
|
)
|
|
338
330
|
})
|
|
@@ -386,14 +378,9 @@ function scheduleRowEffect(
|
|
|
386
378
|
})
|
|
387
379
|
: createRunRowEffect(deps, { autonomousJobId: row.id, threadId: row.threadId })
|
|
388
380
|
|
|
389
|
-
const { enqueueAutonomousJobRun } = yield* effectTryPromise(
|
|
390
|
-
() => import('../queues/autonomous-job.queue'),
|
|
391
|
-
'Failed to load autonomous job queue helpers.',
|
|
392
|
-
)
|
|
393
|
-
|
|
394
381
|
const enqueueResult = yield* effectTryPromise(
|
|
395
382
|
() =>
|
|
396
|
-
enqueueAutonomousJobRun({
|
|
383
|
+
deps.autonomousJobQueue.enqueueAutonomousJobRun({
|
|
397
384
|
payload: {
|
|
398
385
|
autonomousJobId: jobId,
|
|
399
386
|
autonomousJobRunId: recordIdToString(queuedRun.id, TABLES.AUTONOMOUS_JOB_RUN),
|
|
@@ -428,13 +415,9 @@ function scheduleRowEffect(
|
|
|
428
415
|
} else {
|
|
429
416
|
const recurringSchedule = row.schedule
|
|
430
417
|
return Effect.gen(function* () {
|
|
431
|
-
const { upsertAutonomousJobScheduler } = yield* effectTryPromise(
|
|
432
|
-
() => import('../queues/autonomous-job.queue'),
|
|
433
|
-
'Failed to load autonomous job queue helpers.',
|
|
434
|
-
)
|
|
435
|
-
|
|
436
418
|
yield* effectTryPromise(
|
|
437
|
-
() =>
|
|
419
|
+
() =>
|
|
420
|
+
deps.autonomousJobQueue.upsertAutonomousJobScheduler({ autonomousJobId: jobId, schedule: recurringSchedule }),
|
|
438
421
|
'Failed to upsert autonomous job scheduler.',
|
|
439
422
|
)
|
|
440
423
|
|
|
@@ -564,7 +547,7 @@ function updateEffect(
|
|
|
564
547
|
return Effect.gen(function* () {
|
|
565
548
|
const parsed = UpdateAutonomousJobInputSchema.parse(input)
|
|
566
549
|
const existing = yield* getRowEffect(deps, jobId)
|
|
567
|
-
yield* unscheduleRowEffect(existing)
|
|
550
|
+
yield* unscheduleRowEffect(deps, existing)
|
|
568
551
|
const nextTitle = parsed.title
|
|
569
552
|
if (typeof nextTitle === 'string' && compactWhitespace(nextTitle) !== compactWhitespace(existing.title)) {
|
|
570
553
|
const title = nextTitle
|
|
@@ -616,7 +599,7 @@ function pauseEffect(
|
|
|
616
599
|
): Effect.Effect<AutonomousJob, AutonomousJobServiceError> {
|
|
617
600
|
return Effect.gen(function* () {
|
|
618
601
|
const row = yield* getRowEffect(deps, jobId)
|
|
619
|
-
yield* unscheduleRowEffect(row)
|
|
602
|
+
yield* unscheduleRowEffect(deps, row)
|
|
620
603
|
yield* effectTryPromise(
|
|
621
604
|
() =>
|
|
622
605
|
deps.db.update(
|
|
@@ -667,14 +650,10 @@ function runNowEffect(
|
|
|
667
650
|
return Effect.gen(function* () {
|
|
668
651
|
const row = yield* getRowEffect(deps, jobId)
|
|
669
652
|
const queuedRun = yield* createRunRowEffect(deps, { autonomousJobId: row.id, threadId: row.threadId })
|
|
670
|
-
const { enqueueAutonomousJobRun } = yield* effectTryPromise(
|
|
671
|
-
() => import('../queues/autonomous-job.queue'),
|
|
672
|
-
'Failed to load autonomous job queue helpers.',
|
|
673
|
-
)
|
|
674
653
|
|
|
675
654
|
const enqueueResult = yield* effectTryPromise(
|
|
676
655
|
() =>
|
|
677
|
-
enqueueAutonomousJobRun({
|
|
656
|
+
deps.autonomousJobQueue.enqueueAutonomousJobRun({
|
|
678
657
|
payload: {
|
|
679
658
|
autonomousJobId: recordIdToString(row.id, TABLES.AUTONOMOUS_JOB),
|
|
680
659
|
autonomousJobRunId: recordIdToString(queuedRun.id, TABLES.AUTONOMOUS_JOB_RUN),
|
|
@@ -710,7 +689,7 @@ function cancelEffect(
|
|
|
710
689
|
): Effect.Effect<AutonomousJob, AutonomousJobServiceError> {
|
|
711
690
|
return Effect.gen(function* () {
|
|
712
691
|
const row = yield* getRowEffect(deps, jobId)
|
|
713
|
-
yield* unscheduleRowEffect(row)
|
|
692
|
+
yield* unscheduleRowEffect(deps, row)
|
|
714
693
|
yield* effectTryPromise(
|
|
715
694
|
() =>
|
|
716
695
|
deps.db.update(
|
|
@@ -923,7 +902,7 @@ function failQueuedRunEffect(
|
|
|
923
902
|
)
|
|
924
903
|
|
|
925
904
|
if (autoPause || terminalOneShot) {
|
|
926
|
-
yield* unscheduleRowEffect(currentJobRow)
|
|
905
|
+
yield* unscheduleRowEffect(deps, currentJobRow)
|
|
927
906
|
}
|
|
928
907
|
|
|
929
908
|
yield* effectTryPromise(
|
|
@@ -967,39 +946,41 @@ function failQueuedRunEffect(
|
|
|
967
946
|
function executeQueuedRunEffect(
|
|
968
947
|
deps: AutonomousJobDeps,
|
|
969
948
|
job: Job<AutonomousJobQueuePayload>,
|
|
970
|
-
): Effect.Effect<{ status: string; summary?: string }, AutonomousJobServiceError> {
|
|
971
|
-
let autonomousJobRow: AutonomousJobRow | null = null
|
|
972
|
-
let runRow: AutonomousJobRunRow | null = null
|
|
973
|
-
|
|
949
|
+
): Effect.Effect<{ status: string; summary?: string }, AutonomousJobServiceError, unknown> {
|
|
974
950
|
return Effect.gen(function* () {
|
|
975
|
-
yield*
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
951
|
+
const autonomousJobRowRef = yield* Ref.make<AutonomousJobRow | null>(null)
|
|
952
|
+
const runRowRef = yield* Ref.make<AutonomousJobRunRow | null>(null)
|
|
953
|
+
|
|
954
|
+
return yield* Effect.gen(function* () {
|
|
955
|
+
yield* effectTryPromise(() => deps.db.connect(), 'Failed to connect to autonomous job database.')
|
|
956
|
+
const currentJobRow = yield* getRowEffect(deps, job.data.autonomousJobId)
|
|
957
|
+
yield* Ref.set(autonomousJobRowRef, currentJobRow)
|
|
958
|
+
const { queueJobId, runRow: initialRunRow } = yield* getOrCreateQueuedRunRowEffect(deps, job, currentJobRow)
|
|
959
|
+
|
|
960
|
+
yield* Ref.set(runRowRef, initialRunRow)
|
|
961
|
+
if (currentJobRow.status !== 'active' && job.data.trigger === 'scheduled') {
|
|
962
|
+
return { status: 'skipped' }
|
|
963
|
+
}
|
|
984
964
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
965
|
+
const currentRunRow = yield* markQueuedRunRunningEffect(deps, initialRunRow, queueJobId)
|
|
966
|
+
yield* Ref.set(runRowRef, currentRunRow)
|
|
967
|
+
const inputMessage = buildSyntheticUserMessage(currentJobRow.prompt)
|
|
988
968
|
|
|
989
|
-
|
|
990
|
-
deps.thread
|
|
969
|
+
const thread = yield* deps.thread
|
|
991
970
|
.getThread(currentJobRow.threadId)
|
|
992
971
|
.pipe(
|
|
993
972
|
Effect.mapError(
|
|
994
973
|
(cause) => new AutonomousJobServiceError({ message: 'Failed to load autonomous job thread.', cause }),
|
|
995
974
|
),
|
|
996
|
-
)
|
|
997
|
-
effectTryPromise<ThreadTurnModule>(() => import('./thread/thread-turn'), 'Failed to load thread turn runtime.'),
|
|
998
|
-
])
|
|
975
|
+
)
|
|
999
976
|
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
977
|
+
const turnModule = yield* Effect.tryPromise({
|
|
978
|
+
try: () => import('./thread/thread-turn'),
|
|
979
|
+
catch: (cause) => new AutonomousJobServiceError({ message: 'Failed to load thread turn runtime.', cause }),
|
|
980
|
+
})
|
|
981
|
+
|
|
982
|
+
const turnResult = yield* turnModule
|
|
983
|
+
.runThreadTurnInBackground({
|
|
1003
984
|
thread,
|
|
1004
985
|
threadRef: ensureRecordId(currentJobRow.threadId, TABLES.THREAD),
|
|
1005
986
|
orgRef: ensureRecordId(currentJobRow.organizationId, TABLES.ORGANIZATION),
|
|
@@ -1007,31 +988,35 @@ function executeQueuedRunEffect(
|
|
|
1007
988
|
userName: currentJobRow.ownerUserName,
|
|
1008
989
|
agentIdOverride: currentJobRow.agentId,
|
|
1009
990
|
inputMessage,
|
|
1010
|
-
})
|
|
1011
|
-
|
|
1012
|
-
|
|
991
|
+
})
|
|
992
|
+
.pipe(
|
|
993
|
+
Effect.mapError(
|
|
994
|
+
(cause) => new AutonomousJobServiceError({ message: 'Failed to run autonomous job thread turn.', cause }),
|
|
995
|
+
),
|
|
996
|
+
)
|
|
1013
997
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
998
|
+
const activePlan = yield* deps.executionPlan
|
|
999
|
+
.getActivePlanForThread(currentJobRow.threadId)
|
|
1000
|
+
.pipe(
|
|
1001
|
+
Effect.mapError(
|
|
1002
|
+
(cause) => new AutonomousJobServiceError({ message: 'Failed to load active execution plan.', cause }),
|
|
1003
|
+
),
|
|
1004
|
+
)
|
|
1021
1005
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1006
|
+
return yield* completeQueuedRunEffect(deps, { job, currentJobRow, currentRunRow, turnResult, activePlan })
|
|
1007
|
+
}).pipe(
|
|
1008
|
+
Effect.catch((error: unknown) =>
|
|
1009
|
+
Effect.gen(function* () {
|
|
1010
|
+
const currentJobRow = yield* Ref.get(autonomousJobRowRef)
|
|
1011
|
+
const currentRunRow = yield* Ref.get(runRowRef)
|
|
1012
|
+
if (!currentJobRow || !currentRunRow) {
|
|
1013
|
+
return yield* new AutonomousJobServiceError({ message: 'Failed to execute autonomous job.', cause: error })
|
|
1014
|
+
}
|
|
1015
|
+
return yield* failQueuedRunEffect(deps, { job, currentJobRow, currentRunRow, error })
|
|
1016
|
+
}),
|
|
1017
|
+
),
|
|
1018
|
+
)
|
|
1019
|
+
})
|
|
1035
1020
|
}
|
|
1036
1021
|
|
|
1037
1022
|
function createAutonomousJobService(deps: AutonomousJobDeps) {
|
|
@@ -1059,6 +1044,7 @@ interface AutonomousJobDeps {
|
|
|
1059
1044
|
executionPlan: ReturnType<typeof makeExecutionPlanService>
|
|
1060
1045
|
queueJob: ReturnType<typeof makeQueueJobService>
|
|
1061
1046
|
thread: ReturnType<typeof makeThreadService>
|
|
1047
|
+
autonomousJobQueue: AutonomousJobQueueRuntime
|
|
1062
1048
|
}
|
|
1063
1049
|
|
|
1064
1050
|
export function makeAutonomousJobService(deps: AutonomousJobDeps) {
|
|
@@ -1068,7 +1054,7 @@ export function makeAutonomousJobService(deps: AutonomousJobDeps) {
|
|
|
1068
1054
|
export class AutonomousJobServiceTag extends Context.Service<
|
|
1069
1055
|
AutonomousJobServiceTag,
|
|
1070
1056
|
ReturnType<typeof makeAutonomousJobService>
|
|
1071
|
-
>()('AutonomousJobService') {}
|
|
1057
|
+
>()('@lota-sdk/core/AutonomousJobService') {}
|
|
1072
1058
|
|
|
1073
1059
|
export const AutonomousJobServiceLive = Layer.effect(
|
|
1074
1060
|
AutonomousJobServiceTag,
|
|
@@ -1078,6 +1064,14 @@ export const AutonomousJobServiceLive = Layer.effect(
|
|
|
1078
1064
|
const executionPlan = yield* ExecutionPlanServiceTag
|
|
1079
1065
|
const queueJob = yield* QueueJobServiceTag
|
|
1080
1066
|
const thread = yield* ThreadServiceTag
|
|
1081
|
-
|
|
1067
|
+
const queues = yield* LotaQueuesServiceTag
|
|
1068
|
+
return makeAutonomousJobService({
|
|
1069
|
+
db,
|
|
1070
|
+
config,
|
|
1071
|
+
executionPlan,
|
|
1072
|
+
queueJob,
|
|
1073
|
+
thread,
|
|
1074
|
+
autonomousJobQueue: queues.autonomousJob,
|
|
1075
|
+
})
|
|
1082
1076
|
}),
|
|
1083
1077
|
)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Context, Effect, FiberSet, Layer, Schema } from 'effect'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tagged error for the BackgroundWorkService surface. The service itself
|
|
5
|
+
* never returns this — it's reserved for future API extensions.
|
|
6
|
+
*/
|
|
7
|
+
export class BackgroundWorkError extends Schema.TaggedErrorClass<BackgroundWorkError>()(
|
|
8
|
+
'@lota-sdk/core/BackgroundWorkError',
|
|
9
|
+
{ message: Schema.String, cause: Schema.optional(Schema.Defect) },
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Supervised fire-and-forget fork pool.
|
|
14
|
+
*
|
|
15
|
+
* `run` schedules an effect on a process-wide FiberSet that is interrupted
|
|
16
|
+
* when the runtime scope closes — replaces ad-hoc `Effect.runFork`,
|
|
17
|
+
* `Effect.runForkWith`, and `Effect.forkDetach` call sites that would
|
|
18
|
+
* otherwise leak fibers across shutdown.
|
|
19
|
+
*
|
|
20
|
+
* Both methods accept any `Effect.Effect<A, E>`; failures are logged via
|
|
21
|
+
* `Effect.logError` and never propagate to the caller. `runForget` ignores
|
|
22
|
+
* both the result and the cause — use it for best-effort metrics, cache
|
|
23
|
+
* touches, and other strictly cosmetic side effects.
|
|
24
|
+
*/
|
|
25
|
+
export class BackgroundWorkService extends Context.Service<
|
|
26
|
+
BackgroundWorkService,
|
|
27
|
+
{
|
|
28
|
+
readonly run: <A, E>(effect: Effect.Effect<A, E>, label?: string) => Effect.Effect<void>
|
|
29
|
+
readonly runForget: <A, E>(effect: Effect.Effect<A, E>, label?: string) => Effect.Effect<void>
|
|
30
|
+
}
|
|
31
|
+
>()('@lota-sdk/core/BackgroundWorkService') {}
|
|
32
|
+
|
|
33
|
+
export const BackgroundWorkServiceLive = Layer.effect(
|
|
34
|
+
BackgroundWorkService,
|
|
35
|
+
Effect.gen(function* () {
|
|
36
|
+
const set = yield* FiberSet.make<unknown, unknown>()
|
|
37
|
+
|
|
38
|
+
const run = <A, E>(effect: Effect.Effect<A, E>, label?: string): Effect.Effect<void> =>
|
|
39
|
+
Effect.asVoid(
|
|
40
|
+
FiberSet.run(
|
|
41
|
+
set,
|
|
42
|
+
effect.pipe(
|
|
43
|
+
Effect.withLogSpan(label ?? 'background'),
|
|
44
|
+
Effect.catchCause((cause) => Effect.logError(cause)),
|
|
45
|
+
),
|
|
46
|
+
),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
const runForget = <A, E>(effect: Effect.Effect<A, E>, label?: string): Effect.Effect<void> =>
|
|
50
|
+
Effect.asVoid(FiberSet.run(set, effect.pipe(Effect.withLogSpan(label ?? 'background-forget'), Effect.ignore)))
|
|
51
|
+
|
|
52
|
+
return { run, runForget } as const
|
|
53
|
+
}),
|
|
54
|
+
)
|
|
@@ -2,7 +2,9 @@ import { Context, Effect, FiberMap, Layer } from 'effect'
|
|
|
2
2
|
|
|
3
3
|
import { ChatRunRegistry } from '../runtime/chat-run-registry'
|
|
4
4
|
|
|
5
|
-
export class ChatRunRegistryTag extends Context.Service<ChatRunRegistryTag, ChatRunRegistry>()(
|
|
5
|
+
export class ChatRunRegistryTag extends Context.Service<ChatRunRegistryTag, ChatRunRegistry>()(
|
|
6
|
+
'@lota-sdk/core/ChatRunRegistry',
|
|
7
|
+
) {}
|
|
6
8
|
|
|
7
9
|
export const ChatRunRegistryLive = Layer.effect(
|
|
8
10
|
ChatRunRegistryTag,
|
|
@@ -77,14 +77,12 @@ export function makeContextCompactionService(deps: ContextCompactionDeps) {
|
|
|
77
77
|
typeof thread.lastCompactedMessageId === 'string' ? thread.lastCompactedMessageId : undefined,
|
|
78
78
|
)
|
|
79
79
|
|
|
80
|
-
const result = yield*
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}),
|
|
87
|
-
)
|
|
80
|
+
const result = yield* contextCompactionRuntime.compactHistory({
|
|
81
|
+
summaryText: typeof thread.compactionSummary === 'string' ? thread.compactionSummary : '',
|
|
82
|
+
liveMessages,
|
|
83
|
+
tailMessageCount: THREAD_RAW_TAIL_MESSAGES,
|
|
84
|
+
contextSize: params.contextSize,
|
|
85
|
+
})
|
|
88
86
|
|
|
89
87
|
if (!result.compacted || !result.lastCompactedMessageId) {
|
|
90
88
|
return { compacted: false }
|
|
@@ -122,7 +120,7 @@ export function makeContextCompactionService(deps: ContextCompactionDeps) {
|
|
|
122
120
|
})
|
|
123
121
|
|
|
124
122
|
const compactMemoryBlockEffect = (params: { previousSummary: string; newEntriesText: string }) =>
|
|
125
|
-
|
|
123
|
+
contextCompactionRuntime.compactMemoryBlockSummary(params)
|
|
126
124
|
|
|
127
125
|
return {
|
|
128
126
|
createSummaryMessage(summaryText: string) {
|
|
@@ -146,7 +144,7 @@ export function makeContextCompactionService(deps: ContextCompactionDeps) {
|
|
|
146
144
|
export class ContextCompactionServiceTag extends Context.Service<
|
|
147
145
|
ContextCompactionServiceTag,
|
|
148
146
|
ReturnType<typeof makeContextCompactionService>
|
|
149
|
-
>()('ContextCompactionService') {}
|
|
147
|
+
>()('@lota-sdk/core/ContextCompactionService') {}
|
|
150
148
|
|
|
151
149
|
export const ContextCompactionServiceLive = Layer.effect(
|
|
152
150
|
ContextCompactionServiceTag,
|
|
@@ -2,6 +2,7 @@ import { Context, Schema, Effect, Layer } from 'effect'
|
|
|
2
2
|
|
|
3
3
|
import { chunkMarkdownDocument, chunkPagedDocument, chunkPlainTextDocument } from '../document/org-document-chunking'
|
|
4
4
|
import type { ParsedDocumentChunk } from '../document/org-document-chunking'
|
|
5
|
+
import { makeEffectTryPromiseWithMessage } from '../effect/helpers'
|
|
5
6
|
import { RuntimeConfigServiceTag } from '../effect/services'
|
|
6
7
|
import { ProviderEmbeddings } from '../embeddings/provider'
|
|
7
8
|
import { sha256Hex } from '../utils/crypto'
|
|
@@ -71,25 +72,15 @@ class DocumentChunkServiceError extends Schema.TaggedErrorClass<DocumentChunkSer
|
|
|
71
72
|
{ message: Schema.String, cause: Schema.Defect },
|
|
72
73
|
) {}
|
|
73
74
|
|
|
75
|
+
const effectTryDocumentChunkPromise = makeEffectTryPromiseWithMessage(
|
|
76
|
+
(message, cause) => new DocumentChunkServiceError({ message, cause }),
|
|
77
|
+
)
|
|
78
|
+
|
|
74
79
|
function tryDocumentChunkPromise<A>(
|
|
75
80
|
message: string,
|
|
76
|
-
|
|
81
|
+
evaluate: () => PromiseLike<A> | Effect.Effect<A, unknown>,
|
|
77
82
|
): Effect.Effect<A, DocumentChunkServiceError> {
|
|
78
|
-
return
|
|
79
|
-
try {
|
|
80
|
-
const value = thunk()
|
|
81
|
-
if (Effect.isEffect(value)) {
|
|
82
|
-
return value.pipe(Effect.mapError((cause) => new DocumentChunkServiceError({ message, cause })))
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return Effect.tryPromise({
|
|
86
|
-
try: () => Promise.resolve(value),
|
|
87
|
-
catch: (cause) => new DocumentChunkServiceError({ message, cause }),
|
|
88
|
-
})
|
|
89
|
-
} catch (cause) {
|
|
90
|
-
return Effect.fail(new DocumentChunkServiceError({ message, cause }))
|
|
91
|
-
}
|
|
92
|
-
})
|
|
83
|
+
return effectTryDocumentChunkPromise(evaluate, message)
|
|
93
84
|
}
|
|
94
85
|
|
|
95
86
|
export function makeDocumentChunkService(embeddings: DocumentChunkEmbeddings): DocumentChunkService {
|
|
@@ -200,7 +191,7 @@ export function makeDocumentChunkService(embeddings: DocumentChunkEmbeddings): D
|
|
|
200
191
|
}
|
|
201
192
|
|
|
202
193
|
export class DocumentChunkServiceTag extends Context.Service<DocumentChunkServiceTag, DocumentChunkService>()(
|
|
203
|
-
'DocumentChunkService',
|
|
194
|
+
'@lota-sdk/core/DocumentChunkService',
|
|
204
195
|
) {}
|
|
205
196
|
|
|
206
197
|
export const DocumentChunkServiceLive = Layer.effect(
|