@lota-sdk/core 0.4.13 → 0.4.15
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 +4 -4
- package/src/ai/embedding-cache.ts +17 -11
- package/src/ai-gateway/ai-gateway.ts +164 -94
- package/src/ai-gateway/index.ts +4 -1
- package/src/config/agent-defaults.ts +2 -2
- package/src/config/agent-types.ts +1 -1
- package/src/config/constants.ts +1 -1
- package/src/create-runtime.ts +259 -200
- package/src/db/cursor-pagination.ts +2 -9
- package/src/db/memory-store.ts +194 -175
- package/src/db/memory.ts +125 -71
- package/src/db/schema-fingerprint.ts +5 -4
- package/src/db/service-normalization.ts +4 -3
- package/src/db/service.ts +3 -2
- package/src/db/startup.ts +15 -16
- package/src/effect/errors.ts +161 -21
- package/src/effect/index.ts +0 -1
- package/src/embeddings/provider.ts +15 -7
- package/src/queues/autonomous-job.queue.ts +10 -22
- package/src/queues/delayed-node-promotion.queue.ts +8 -14
- package/src/queues/document-processor.queue.ts +13 -4
- package/src/queues/memory-consolidation.queue.ts +26 -14
- package/src/queues/plan-agent-heartbeat.queue.ts +48 -31
- package/src/queues/plan-scheduler.queue.ts +37 -15
- package/src/queues/queue-factory.ts +59 -35
- package/src/queues/standalone-worker.ts +3 -2
- package/src/redis/connection.ts +10 -3
- package/src/redis/org-memory-lock.ts +1 -1
- package/src/redis/redis-lease-lock.ts +5 -5
- package/src/redis/stream-context.ts +1 -1
- package/src/runtime/chat-message.ts +64 -1
- package/src/runtime/chat-run-orchestration.ts +33 -20
- package/src/runtime/context-compaction/context-compaction-runtime.ts +14 -7
- package/src/runtime/context-compaction/context-compaction.ts +78 -66
- package/src/runtime/domain-layer.ts +19 -13
- package/src/runtime/execution-plan.ts +7 -3
- package/src/runtime/memory/memory-block.ts +3 -9
- package/src/runtime/memory/memory-scope.ts +3 -1
- package/src/runtime/plugin-resolution.ts +2 -1
- package/src/runtime/post-turn-side-effects.ts +6 -5
- package/src/runtime/retrieval-adapters.ts +8 -20
- package/src/runtime/runtime-config.ts +3 -9
- package/src/runtime/runtime-extensions.ts +2 -4
- package/src/runtime/runtime-lifecycle.ts +56 -16
- package/src/runtime/runtime-services.ts +180 -102
- package/src/runtime/runtime-worker-registry.ts +3 -1
- package/src/runtime/social-chat/social-chat-agent-runner.ts +1 -1
- package/src/runtime/social-chat/social-chat-history.ts +21 -18
- package/src/runtime/social-chat/social-chat.ts +356 -223
- package/src/runtime/specialist-runner.ts +3 -1
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +3 -2
- package/src/runtime/thread-turn-context.ts +142 -102
- package/src/runtime/turn-lifecycle.ts +15 -46
- package/src/services/agent-activity.service.ts +1 -1
- package/src/services/agent-executor.service.ts +107 -77
- package/src/services/autonomous-job.service.ts +354 -293
- package/src/services/background-work.service.ts +3 -3
- package/src/services/context-compaction.service.ts +7 -2
- package/src/services/document-chunk.service.ts +50 -32
- package/src/services/execution-plan/execution-plan-schedule.ts +5 -3
- package/src/services/execution-plan/execution-plan.service.ts +162 -179
- package/src/services/feedback-loop.service.ts +5 -4
- package/src/services/graph-full-routing.ts +37 -36
- package/src/services/institutional-memory.service.ts +28 -30
- package/src/services/learned-skill.service.ts +107 -72
- package/src/services/memory/memory-errors.ts +4 -23
- package/src/services/memory/memory-org-memory.ts +10 -5
- package/src/services/memory/memory-rerank.ts +18 -6
- package/src/services/memory/memory.service.ts +170 -111
- package/src/services/memory/rerank.service.ts +29 -20
- package/src/services/organization-member.service.ts +1 -1
- package/src/services/organization.service.ts +69 -75
- package/src/services/ownership-dispatcher.service.ts +40 -39
- package/src/services/plan/plan-agent-heartbeat.service.ts +22 -24
- package/src/services/plan/plan-agent-query.service.ts +39 -31
- package/src/services/plan/plan-completion-side-effects.ts +13 -17
- package/src/services/plan/plan-coordination.service.ts +2 -1
- package/src/services/plan/plan-cycle.service.ts +6 -5
- package/src/services/plan/plan-deadline.service.ts +57 -54
- package/src/services/plan/plan-event-delivery.service.ts +5 -4
- package/src/services/plan/plan-executor-graph.ts +18 -15
- package/src/services/plan/plan-executor.service.ts +235 -262
- package/src/services/plan/plan-run.service.ts +169 -93
- package/src/services/plan/plan-scheduler.service.ts +192 -202
- package/src/services/plan/plan-template.service.ts +1 -1
- package/src/services/plan/plan-transaction-events.ts +1 -1
- package/src/services/plan/plan-workspace.service.ts +23 -14
- package/src/services/plugin-executor.service.ts +5 -9
- package/src/services/queue-job.service.ts +117 -59
- package/src/services/recent-activity-title.service.ts +13 -12
- package/src/services/recent-activity.service.ts +6 -1
- package/src/services/social-chat-history.service.ts +29 -25
- package/src/services/system-executor.service.ts +5 -9
- package/src/services/thread/thread-active-run.ts +2 -2
- package/src/services/thread/thread-listing.ts +61 -57
- package/src/services/thread/thread-memory-block.ts +73 -48
- package/src/services/thread/thread-message.service.ts +76 -65
- package/src/services/thread/thread-record-store.ts +8 -8
- package/src/services/thread/thread-title.service.ts +10 -4
- package/src/services/thread/thread-turn-execution.ts +43 -45
- package/src/services/thread/thread-turn-preparation.service.ts +257 -135
- package/src/services/thread/thread-turn-streaming.ts +83 -92
- package/src/services/thread/thread-turn.ts +18 -16
- package/src/services/thread/thread.service.ts +135 -100
- package/src/services/user.service.ts +45 -48
- package/src/storage/attachment-parser.ts +6 -2
- package/src/storage/attachment-storage.service.ts +5 -6
- package/src/storage/generated-document-storage.service.ts +1 -1
- package/src/system-agents/context-compaction.agent.ts +10 -9
- package/src/system-agents/delegated-agent-factory.ts +30 -6
- package/src/system-agents/memory-reranker.agent.ts +10 -9
- package/src/system-agents/memory.agent.ts +10 -9
- package/src/system-agents/recent-activity-title-refiner.agent.ts +13 -15
- package/src/system-agents/regular-chat-memory-digest.agent.ts +13 -12
- package/src/system-agents/skill-extractor.agent.ts +13 -12
- package/src/system-agents/skill-manager.agent.ts +13 -12
- package/src/system-agents/thread-router.agent.ts +11 -7
- package/src/system-agents/title-generator.agent.ts +13 -12
- package/src/tools/fetch-webpage.tool.ts +13 -13
- package/src/tools/memory-block.tool.ts +3 -1
- package/src/tools/plan-approval.tool.ts +4 -2
- package/src/tools/read-file-parts.tool.ts +10 -4
- package/src/tools/remember-memory.tool.ts +3 -1
- package/src/tools/research-topic.tool.ts +9 -5
- package/src/tools/search-web.tool.ts +16 -16
- package/src/tools/search.tool.ts +20 -5
- package/src/tools/team-think.tool.ts +61 -38
- package/src/utils/async.ts +5 -5
- package/src/utils/errors.ts +19 -18
- package/src/utils/sse-keepalive.ts +28 -25
- package/src/workers/bootstrap.ts +75 -11
- package/src/workers/memory-consolidation.worker.ts +82 -91
- package/src/workers/organization-learning.worker.ts +14 -4
- package/src/workers/regular-chat-memory-digest.runner.ts +105 -67
- package/src/workers/skill-extraction.runner.ts +97 -61
- package/src/workers/utils/repo-structure-extractor.ts +13 -8
- package/src/workers/utils/thread-message-query.ts +24 -24
- package/src/workers/worker-utils.ts +23 -4
- package/src/effect/helpers.ts +0 -123
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Schema, Effect } from 'effect'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import type { AiGatewayModels } from '../../ai-gateway/ai-gateway'
|
|
4
|
+
import { makeContextCompactionAgentFactory } from '../../system-agents/context-compaction.agent'
|
|
4
5
|
import type { GenerateHelperStructuredParams, GenerateHelperTextParams } from '../helper-model'
|
|
5
6
|
import {
|
|
6
7
|
buildContextCompactionPrompt,
|
|
@@ -29,12 +30,13 @@ interface HelperModelRuntime {
|
|
|
29
30
|
|
|
30
31
|
interface CreateContextCompactionRuntimeDeps {
|
|
31
32
|
helperModelRuntime: HelperModelRuntime
|
|
33
|
+
aiGatewayModels: AiGatewayModels
|
|
32
34
|
now?: () => number
|
|
33
35
|
randomId?: () => string
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
class ContextCompactionRuntimeError extends Schema.TaggedErrorClass<ContextCompactionRuntimeError>()(
|
|
37
|
-
'ContextCompactionRuntimeError',
|
|
39
|
+
'@lota-sdk/core/ContextCompactionRuntimeError',
|
|
38
40
|
{ message: Schema.String, cause: Schema.Defect },
|
|
39
41
|
) {}
|
|
40
42
|
|
|
@@ -48,11 +50,15 @@ function tryContextCompactionPromise<A>(
|
|
|
48
50
|
})
|
|
49
51
|
}
|
|
50
52
|
|
|
51
|
-
function runContextCompacterEffect(
|
|
53
|
+
function runContextCompacterEffect(
|
|
54
|
+
helperModelRuntime: HelperModelRuntime,
|
|
55
|
+
aiGatewayModels: AiGatewayModels,
|
|
56
|
+
params: ContextCompactionRunnerParams,
|
|
57
|
+
) {
|
|
52
58
|
return tryContextCompactionPromise('Failed to compact runtime context.', () =>
|
|
53
59
|
helperModelRuntime.generateHelperStructured({
|
|
54
60
|
tag: 'context-compaction',
|
|
55
|
-
createAgent:
|
|
61
|
+
createAgent: makeContextCompactionAgentFactory(aiGatewayModels),
|
|
56
62
|
messages: [
|
|
57
63
|
{
|
|
58
64
|
role: 'user',
|
|
@@ -69,10 +75,11 @@ function runContextCompacterEffect(helperModelRuntime: HelperModelRuntime, param
|
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
export function createWiredContextCompactionRuntime(deps: CreateContextCompactionRuntimeDeps) {
|
|
72
|
-
const { helperModelRuntime } = deps
|
|
78
|
+
const { helperModelRuntime, aiGatewayModels } = deps
|
|
79
|
+
const createAgent = makeContextCompactionAgentFactory(aiGatewayModels)
|
|
73
80
|
|
|
74
81
|
const runtime = createContextCompactionRuntime({
|
|
75
|
-
runCompacter: (params) => runContextCompacterEffect(helperModelRuntime, params),
|
|
82
|
+
runCompacter: (params) => runContextCompacterEffect(helperModelRuntime, aiGatewayModels, params),
|
|
76
83
|
now: deps.now,
|
|
77
84
|
randomId: deps.randomId,
|
|
78
85
|
thresholdRatio: CONTEXT_COMPACTION_THRESHOLD_RATIO,
|
|
@@ -92,7 +99,7 @@ export function createWiredContextCompactionRuntime(deps: CreateContextCompactio
|
|
|
92
99
|
return tryContextCompactionPromise('Failed to compact memory block summary.', () =>
|
|
93
100
|
helperModelRuntime.generateHelperText({
|
|
94
101
|
tag: 'memory-block-compaction',
|
|
95
|
-
createAgent
|
|
102
|
+
createAgent,
|
|
96
103
|
messages: [{ role: 'user', content: buildMemoryBlockCompactionPrompt({ previousSummary, newEntriesText }) }],
|
|
97
104
|
maxOutputTokens: CONTEXT_COMPACTION_MAX_OUTPUT_TOKENS,
|
|
98
105
|
}),
|
|
@@ -2,7 +2,7 @@ import type { ChatMessage } from '@lota-sdk/shared'
|
|
|
2
2
|
import { Duration, Effect, Schedule, Schema } from 'effect'
|
|
3
3
|
import { z } from 'zod'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { ERROR_TAGS } from '../../effect/errors'
|
|
6
6
|
import { nowEpochMillis } from '../../utils/date-time'
|
|
7
7
|
import {
|
|
8
8
|
CHARS_PER_TOKEN_ESTIMATE,
|
|
@@ -60,12 +60,12 @@ export interface ContextCompactionRunnerParams {
|
|
|
60
60
|
transcript: string
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
class CompactionError extends Schema.TaggedErrorClass<CompactionError>()(
|
|
63
|
+
class CompactionError extends Schema.TaggedErrorClass<CompactionError>()(ERROR_TAGS.CompactionError, {
|
|
64
64
|
message: Schema.String,
|
|
65
65
|
cause: Schema.optional(Schema.Defect),
|
|
66
66
|
}) {}
|
|
67
67
|
|
|
68
|
-
class CompactionParseError extends Schema.TaggedErrorClass<CompactionParseError>()(
|
|
68
|
+
class CompactionParseError extends Schema.TaggedErrorClass<CompactionParseError>()(ERROR_TAGS.CompactionParseError, {
|
|
69
69
|
message: Schema.String,
|
|
70
70
|
cause: Schema.optional(Schema.Defect),
|
|
71
71
|
}) {}
|
|
@@ -88,9 +88,11 @@ export interface CompactionOutput {
|
|
|
88
88
|
summary: string
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
type ContextCompactionRunnerError = { readonly _tag: string; readonly message?: string }
|
|
92
|
+
|
|
91
93
|
export type ContextCompactionRunner = (
|
|
92
94
|
params: ContextCompactionRunnerParams,
|
|
93
|
-
) => Effect.Effect<CompactionOutput,
|
|
95
|
+
) => Effect.Effect<CompactionOutput, ContextCompactionRunnerError, never>
|
|
94
96
|
|
|
95
97
|
export interface CreateContextCompactionRuntimeOptions {
|
|
96
98
|
runCompacter: ContextCompactionRunner
|
|
@@ -342,22 +344,29 @@ export function createContextCompactionRuntime(
|
|
|
342
344
|
const chunks = splitByCharBudget(params.newMessages, compactionChunkMaxChars)
|
|
343
345
|
const initialSummary = normalizeSummary(params.previousSummary)
|
|
344
346
|
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
347
|
+
const stepSummary = (state: {
|
|
348
|
+
summary: string
|
|
349
|
+
index: number
|
|
350
|
+
}): Effect.Effect<{ summary: string; index: number }, CompactionError> =>
|
|
351
|
+
state.index >= chunks.length
|
|
352
|
+
? Effect.succeed(state)
|
|
353
|
+
: Effect.gen(function* () {
|
|
351
354
|
const chunk = chunks[state.index]
|
|
352
355
|
const transcript = toCompactionTranscript(chunk)
|
|
353
356
|
const output = yield* options.runCompacter({ previousSummary: state.summary, chunk, transcript }).pipe(
|
|
354
|
-
Effect.mapError(
|
|
357
|
+
Effect.mapError(
|
|
358
|
+
(error) =>
|
|
359
|
+
new CompactionError({
|
|
360
|
+
message: error.message ?? `Context compaction runner failed with ${error._tag}.`,
|
|
361
|
+
cause: error,
|
|
362
|
+
}),
|
|
363
|
+
),
|
|
355
364
|
Effect.retry(COMPACTION_RUNNER_RETRY_OPTIONS),
|
|
356
365
|
)
|
|
357
|
-
return { summary: normalizeSummary(output.summary), index: state.index + 1 }
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
)
|
|
366
|
+
return yield* stepSummary({ summary: normalizeSummary(output.summary), index: state.index + 1 })
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
const finalSummary = yield* stepSummary({ summary: initialSummary, index: 0 })
|
|
361
370
|
|
|
362
371
|
return { summary: finalSummary.summary }
|
|
363
372
|
})
|
|
@@ -419,59 +428,62 @@ export function createContextCompactionRuntime(
|
|
|
419
428
|
done: false,
|
|
420
429
|
}
|
|
421
430
|
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
Effect.gen(function* () {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
431
|
+
const stepHistory = (state: CompactionLoopState): Effect.Effect<CompactionLoopState, CompactionError> =>
|
|
432
|
+
state.done
|
|
433
|
+
? Effect.succeed(state)
|
|
434
|
+
: Effect.gen(function* () {
|
|
435
|
+
const assessment = shouldCompactHistory({
|
|
436
|
+
summaryText: state.summaryText,
|
|
437
|
+
liveMessages: state.remainingMessages,
|
|
438
|
+
contextSize: params.contextSize,
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
if (!assessment.shouldCompact) {
|
|
442
|
+
return { ...state, estimatedTokens: assessment.estimatedTokens, done: true }
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const boundary = Math.max(0, state.remainingMessages.length - params.tailMessageCount)
|
|
446
|
+
if (boundary <= 0) {
|
|
447
|
+
return { ...state, estimatedTokens: assessment.estimatedTokens, done: true }
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const candidatePrefix = state.remainingMessages.slice(0, boundary)
|
|
451
|
+
const messagesToCompact = candidatePrefix.filter((message) => !readIsCompacted(message))
|
|
452
|
+
const contextMessages = messagesToCompact
|
|
453
|
+
.map(toContextMessageFromChatMessage)
|
|
454
|
+
.filter((message) => compactWhitespace(message.text).length > 0)
|
|
455
|
+
const sourceText = toCompactionTranscript(contextMessages)
|
|
456
|
+
|
|
457
|
+
if (!compactWhitespace(sourceText)) {
|
|
458
|
+
return { ...state, estimatedTokens: assessment.estimatedTokens, done: true }
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const compacted = yield* compactContextMessagesEffect({
|
|
462
|
+
previousSummary: state.summaryText,
|
|
463
|
+
newMessages: contextMessages,
|
|
464
|
+
})
|
|
465
|
+
const rolledSummary = yield* rollupSummaryIfOversizedEffect(normalizeSummary(compacted.summary))
|
|
466
|
+
|
|
467
|
+
if (rolledSummary.length >= sourceText.length) {
|
|
468
|
+
return yield* new CompactionError({
|
|
469
|
+
message: 'Compaction summary is not shorter than compacted source',
|
|
470
|
+
})
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
return yield* stepHistory({
|
|
474
|
+
summaryText: rolledSummary,
|
|
475
|
+
remainingMessages: state.remainingMessages.slice(boundary),
|
|
476
|
+
compactedMessages: [
|
|
477
|
+
...state.compactedMessages,
|
|
478
|
+
...candidatePrefix.map((message) => markMessageCompacted(message, now)),
|
|
479
|
+
],
|
|
480
|
+
lastCompactedMessageId: candidatePrefix.at(-1)?.id ?? state.lastCompactedMessageId,
|
|
481
|
+
estimatedTokens: assessment.estimatedTokens,
|
|
482
|
+
done: false,
|
|
483
|
+
})
|
|
430
484
|
})
|
|
431
485
|
|
|
432
|
-
|
|
433
|
-
return { ...state, estimatedTokens: assessment.estimatedTokens, done: true }
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
const boundary = Math.max(0, state.remainingMessages.length - params.tailMessageCount)
|
|
437
|
-
if (boundary <= 0) {
|
|
438
|
-
return { ...state, estimatedTokens: assessment.estimatedTokens, done: true }
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
const candidatePrefix = state.remainingMessages.slice(0, boundary)
|
|
442
|
-
const messagesToCompact = candidatePrefix.filter((message) => !readIsCompacted(message))
|
|
443
|
-
const contextMessages = messagesToCompact
|
|
444
|
-
.map(toContextMessageFromChatMessage)
|
|
445
|
-
.filter((message) => compactWhitespace(message.text).length > 0)
|
|
446
|
-
const sourceText = toCompactionTranscript(contextMessages)
|
|
447
|
-
|
|
448
|
-
if (!compactWhitespace(sourceText)) {
|
|
449
|
-
return { ...state, estimatedTokens: assessment.estimatedTokens, done: true }
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
const compacted = yield* compactContextMessagesEffect({
|
|
453
|
-
previousSummary: state.summaryText,
|
|
454
|
-
newMessages: contextMessages,
|
|
455
|
-
})
|
|
456
|
-
const rolledSummary = yield* rollupSummaryIfOversizedEffect(normalizeSummary(compacted.summary))
|
|
457
|
-
|
|
458
|
-
if (rolledSummary.length >= sourceText.length) {
|
|
459
|
-
return yield* new CompactionError({ message: 'Compaction summary is not shorter than compacted source' })
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
return {
|
|
463
|
-
summaryText: rolledSummary,
|
|
464
|
-
remainingMessages: state.remainingMessages.slice(boundary),
|
|
465
|
-
compactedMessages: [
|
|
466
|
-
...state.compactedMessages,
|
|
467
|
-
...candidatePrefix.map((message) => markMessageCompacted(message, now)),
|
|
468
|
-
],
|
|
469
|
-
lastCompactedMessageId: candidatePrefix.at(-1)?.id ?? state.lastCompactedMessageId,
|
|
470
|
-
estimatedTokens: assessment.estimatedTokens,
|
|
471
|
-
done: false,
|
|
472
|
-
}
|
|
473
|
-
}),
|
|
474
|
-
})
|
|
486
|
+
const finalState = yield* stepHistory(initialState)
|
|
475
487
|
|
|
476
488
|
return buildExitResult(finalState)
|
|
477
489
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Builds the domain-service Layer tree for `createLotaRuntime`.
|
|
3
3
|
*
|
|
4
|
-
* The services form a
|
|
4
|
+
* The services form a tiered dependency graph on top of the infrastructure
|
|
5
5
|
* layer (config, logging, database, redis, agents, threads, extensions).
|
|
6
6
|
* Each tier is provided with the accumulated context of earlier tiers so
|
|
7
7
|
* every service resolves cleanly when the ManagedRuntime eagerly loads them.
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import type { Layer as LayerType } from 'effect'
|
|
11
11
|
import { Layer } from 'effect'
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import type { AiGatewayModelsTag, AiGatewayTag, RuntimeBridgeTag } from '../ai-gateway/ai-gateway'
|
|
14
14
|
import { EmbeddingCacheLive } from '../ai/embedding-cache'
|
|
15
15
|
import type { buildInfrastructureLayer } from '../effect/layers'
|
|
16
16
|
import { LotaQueuesLive } from '../queues/queues.service'
|
|
@@ -85,12 +85,18 @@ function provide<A, E, R extends RCtx, RCtx, E2>(
|
|
|
85
85
|
|
|
86
86
|
type InfrastructureLayer = ReturnType<typeof buildInfrastructureLayer>
|
|
87
87
|
|
|
88
|
+
type BridgeLayer = LayerType.Layer<AiGatewayTag | AiGatewayModelsTag | RuntimeBridgeTag, never, never>
|
|
89
|
+
|
|
88
90
|
/**
|
|
89
91
|
* Compose the domain service layer tree on top of the supplied infrastructure
|
|
90
|
-
* layer.
|
|
91
|
-
*
|
|
92
|
+
* layer. `bridgeLayer` provides `AiGatewayModelsTag` and `RuntimeBridgeTag`
|
|
93
|
+
* — these are constructed at the host boundary (`createLotaRuntime`) via
|
|
94
|
+
* `Deferred` because they reference the `ManagedRuntime` that is being built.
|
|
95
|
+
* They are threaded into the domain context so service layers that need them
|
|
96
|
+
* can `yield*` the tags directly instead of prop-drilling `runPromise`.
|
|
92
97
|
*/
|
|
93
|
-
export function buildDomainServiceLayer(infrastructureLayer: InfrastructureLayer) {
|
|
98
|
+
export function buildDomainServiceLayer(infrastructureLayer: InfrastructureLayer, bridgeLayer: BridgeLayer) {
|
|
99
|
+
const baseCtx = Layer.mergeAll(infrastructureLayer, bridgeLayer)
|
|
94
100
|
const tier0 = provide(
|
|
95
101
|
Layer.mergeAll(
|
|
96
102
|
BackgroundWorkServiceLive,
|
|
@@ -103,11 +109,11 @@ export function buildDomainServiceLayer(infrastructureLayer: InfrastructureLayer
|
|
|
103
109
|
PlanBuilderServiceLive,
|
|
104
110
|
WriteIntentValidatorServiceLive,
|
|
105
111
|
),
|
|
106
|
-
|
|
112
|
+
baseCtx,
|
|
107
113
|
)
|
|
108
114
|
const ctx0 = Layer.mergeAll(
|
|
109
|
-
|
|
110
|
-
provide(Layer.mergeAll(
|
|
115
|
+
baseCtx,
|
|
116
|
+
provide(Layer.mergeAll(EmbeddingCacheLive, FirecrawlLive, HelperModelLive), baseCtx),
|
|
111
117
|
tier0,
|
|
112
118
|
)
|
|
113
119
|
|
|
@@ -178,10 +184,7 @@ export function buildDomainServiceLayer(infrastructureLayer: InfrastructureLayer
|
|
|
178
184
|
const tier5 = provide(PlanExecutorServiceLive, ctx4)
|
|
179
185
|
const ctx5 = Layer.mergeAll(ctx4, tier5)
|
|
180
186
|
|
|
181
|
-
const tier6 = provide(
|
|
182
|
-
Layer.mergeAll(OwnershipDispatcherServiceLive, PlanAgentHeartbeatServiceLive, PlanDeadlineServiceLive),
|
|
183
|
-
ctx5,
|
|
184
|
-
)
|
|
187
|
+
const tier6 = provide(Layer.mergeAll(OwnershipDispatcherServiceLive, PlanDeadlineServiceLive), ctx5)
|
|
185
188
|
const ctx6 = Layer.mergeAll(ctx5, tier6)
|
|
186
189
|
|
|
187
190
|
const tier7 = provide(Layer.mergeAll(ExecutionPlanServiceLive, GlobalOrchestratorServiceLive), ctx6)
|
|
@@ -199,5 +202,8 @@ export function buildDomainServiceLayer(infrastructureLayer: InfrastructureLayer
|
|
|
199
202
|
const ctx8 = Layer.mergeAll(ctx7, tier8)
|
|
200
203
|
|
|
201
204
|
const tier9 = provide(Layer.mergeAll(PlanCycleServiceLive, ThreadTurnServiceLive), ctx8)
|
|
202
|
-
|
|
205
|
+
const ctx9 = Layer.mergeAll(ctx8, tier9)
|
|
206
|
+
|
|
207
|
+
const tier10 = provide(PlanAgentHeartbeatServiceLive, ctx9)
|
|
208
|
+
return Layer.mergeAll(ctx9, tier10)
|
|
203
209
|
}
|
|
@@ -26,7 +26,7 @@ function formatExecutionPlansForPrompt(plans: SerializableExecutionPlan[]): stri
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export class ExecutionPlanCacheError extends Schema.TaggedErrorClass<ExecutionPlanCacheError>()(
|
|
29
|
-
'ExecutionPlanCacheError',
|
|
29
|
+
'@lota-sdk/core/ExecutionPlanCacheError',
|
|
30
30
|
{ message: Schema.String, cause: Schema.Defect },
|
|
31
31
|
) {}
|
|
32
32
|
|
|
@@ -42,7 +42,11 @@ export function buildExecutionPlanInstructionSections(plans: SerializableExecuti
|
|
|
42
42
|
export function createExecutionPlanInstructionSectionCache(params: {
|
|
43
43
|
disabled?: boolean
|
|
44
44
|
loadPlansEffect: () => Effect.Effect<SerializableExecutionPlan[], ExecutionPlanCacheError>
|
|
45
|
+
/** Promise adapter used by the `getPlans()` / `getSections()` Promise API.
|
|
46
|
+
* Required so this module never reaches for an ambient `Effect.runPromise`. */
|
|
47
|
+
runPromise: <A, E>(effect: Effect.Effect<A, E>) => Promise<A>
|
|
45
48
|
}) {
|
|
49
|
+
const runPromise = params.runPromise
|
|
46
50
|
const [getPlansCachedEffect, invalidatePlansEffect] = Effect.runSync(
|
|
47
51
|
Effect.cachedInvalidateWithTTL(
|
|
48
52
|
Effect.suspend(() => (params.disabled ? Effect.succeed([]) : params.loadPlansEffect())),
|
|
@@ -75,10 +79,10 @@ export function createExecutionPlanInstructionSectionCache(params: {
|
|
|
75
79
|
getPlansEffect,
|
|
76
80
|
getSectionsEffect,
|
|
77
81
|
getPlans() {
|
|
78
|
-
return
|
|
82
|
+
return runPromise(getPlansEffect())
|
|
79
83
|
},
|
|
80
84
|
getSections() {
|
|
81
|
-
return
|
|
85
|
+
return runPromise(getSectionsEffect())
|
|
82
86
|
},
|
|
83
87
|
}
|
|
84
88
|
}
|
|
@@ -5,7 +5,7 @@ import { nowDate } from '../../utils/date-time'
|
|
|
5
5
|
import { compactWhitespace } from '../../utils/string'
|
|
6
6
|
|
|
7
7
|
export class MemoryBlockCompactError extends Schema.TaggedErrorClass<MemoryBlockCompactError>()(
|
|
8
|
-
'MemoryBlockCompactError',
|
|
8
|
+
'@lota-sdk/core/MemoryBlockCompactError',
|
|
9
9
|
{ message: Schema.String, cause: Schema.Defect },
|
|
10
10
|
) {}
|
|
11
11
|
|
|
@@ -65,7 +65,7 @@ export interface CompactMemoryBlockEntriesParams {
|
|
|
65
65
|
compact: (params: {
|
|
66
66
|
previousSummary: string
|
|
67
67
|
newEntriesText: string
|
|
68
|
-
}) =>
|
|
68
|
+
}) => Effect.Effect<string, MemoryBlockCompactError>
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
export interface CompactMemoryBlockEntriesResult {
|
|
@@ -119,13 +119,7 @@ export function compactMemoryBlockEntries(
|
|
|
119
119
|
while (entries.length >= params.triggerEntries) {
|
|
120
120
|
const chunk = entries.slice(0, params.chunkEntries)
|
|
121
121
|
const compactParams = { previousSummary: summary, newEntriesText: toMemoryBlockEntriesSource(chunk) }
|
|
122
|
-
const
|
|
123
|
-
const raw = yield* Effect.isEffect(value)
|
|
124
|
-
? value
|
|
125
|
-
: Effect.tryPromise({
|
|
126
|
-
try: () => Promise.resolve(value),
|
|
127
|
-
catch: (cause) => new MemoryBlockCompactError({ message: 'compact callback failed', cause }),
|
|
128
|
-
})
|
|
122
|
+
const raw = yield* params.compact(compactParams)
|
|
129
123
|
const nextSummary = raw.trim()
|
|
130
124
|
|
|
131
125
|
if (!nextSummary) {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Effect, Schema } from 'effect'
|
|
2
2
|
|
|
3
|
+
import { ERROR_TAGS } from '../../effect/errors'
|
|
4
|
+
|
|
3
5
|
export const ORG_SCOPE_PREFIX = 'org'
|
|
4
6
|
|
|
5
7
|
const SCOPE_ID_MAX_LENGTH = 255
|
|
6
8
|
const SCOPE_PREFIX_REGEX = /^[a-z][a-z0-9_]*$/
|
|
7
9
|
|
|
8
|
-
export class MemoryScopeError extends Schema.TaggedErrorClass<MemoryScopeError>()(
|
|
10
|
+
export class MemoryScopeError extends Schema.TaggedErrorClass<MemoryScopeError>()(ERROR_TAGS.MemoryScopeError, {
|
|
9
11
|
message: Schema.String,
|
|
10
12
|
}) {}
|
|
11
13
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Schema, Effect } from 'effect'
|
|
2
2
|
|
|
3
3
|
import type { RecordIdRef } from '../db/record-id'
|
|
4
|
+
import { ERROR_TAGS } from '../effect/errors'
|
|
4
5
|
import type { LotaRuntimeAdapters, LotaRuntimeIndexedRepositoriesContext } from './runtime-extensions'
|
|
5
6
|
|
|
6
7
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
7
8
|
return typeof value === 'object' && value !== null
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
class PluginResolutionError extends Schema.TaggedErrorClass<PluginResolutionError>()(
|
|
11
|
+
class PluginResolutionError extends Schema.TaggedErrorClass<PluginResolutionError>()(ERROR_TAGS.PluginResolutionError, {
|
|
11
12
|
stage: Schema.Literals([
|
|
12
13
|
'configuration',
|
|
13
14
|
'linear-installation',
|
|
@@ -3,6 +3,7 @@ import { Schema, Effect } from 'effect'
|
|
|
3
3
|
|
|
4
4
|
import type { ResolvedAgentConfig } from '../config/agent-defaults'
|
|
5
5
|
import type { RecordIdRef } from '../db/record-id'
|
|
6
|
+
import { ERROR_TAGS } from '../effect/errors'
|
|
6
7
|
import { AgentConfigServiceTag, RuntimeAdaptersServiceTag } from '../effect/services'
|
|
7
8
|
import { LotaQueuesServiceTag } from '../queues/queues.service'
|
|
8
9
|
import { RecentActivityServiceTag } from '../services/recent-activity.service'
|
|
@@ -27,10 +28,10 @@ import {
|
|
|
27
28
|
toHistoryMessages,
|
|
28
29
|
} from './thread-chat-helpers'
|
|
29
30
|
|
|
30
|
-
class PostTurnSideEffectsError extends Schema.TaggedErrorClass<PostTurnSideEffectsError>()(
|
|
31
|
-
|
|
32
|
-
cause: Schema.Defect,
|
|
33
|
-
|
|
31
|
+
class PostTurnSideEffectsError extends Schema.TaggedErrorClass<PostTurnSideEffectsError>()(
|
|
32
|
+
ERROR_TAGS.PostTurnSideEffectsError,
|
|
33
|
+
{ message: Schema.String, cause: Schema.Defect },
|
|
34
|
+
) {}
|
|
34
35
|
|
|
35
36
|
function tryPostTurnSideEffect<A>(
|
|
36
37
|
message: string,
|
|
@@ -214,7 +215,7 @@ export const runPostTurnSideEffects = Effect.fn('PostTurnSideEffects.run')(funct
|
|
|
214
215
|
() => {
|
|
215
216
|
const enqueuePostChatOrgAction = runtimeAdapters.enqueuePostChatOrgAction
|
|
216
217
|
if (!enqueuePostChatOrgAction) {
|
|
217
|
-
return
|
|
218
|
+
return Promise.resolve()
|
|
218
219
|
}
|
|
219
220
|
|
|
220
221
|
const sourceCreatedAt = referenceUserMessage.metadata?.createdAt ?? nowEpochMillis()
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Schema, Effect } from 'effect'
|
|
2
2
|
|
|
3
|
+
import { ERROR_TAGS } from '../effect/errors'
|
|
4
|
+
|
|
3
5
|
interface ScopedRetrievalTask<TCandidate, E = never> {
|
|
4
6
|
scopeTag: string
|
|
5
|
-
retrieve: () =>
|
|
7
|
+
retrieve: () => Effect.Effect<TCandidate[], E>
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
interface ScopedRetrievalResult<TCandidate> {
|
|
@@ -10,7 +12,7 @@ interface ScopedRetrievalResult<TCandidate> {
|
|
|
10
12
|
candidates: TCandidate[]
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
class ScopedRetrievalError extends Schema.TaggedErrorClass<ScopedRetrievalError>()(
|
|
15
|
+
class ScopedRetrievalError extends Schema.TaggedErrorClass<ScopedRetrievalError>()(ERROR_TAGS.ScopedRetrievalError, {
|
|
14
16
|
scopeTag: Schema.String,
|
|
15
17
|
message: Schema.String,
|
|
16
18
|
cause: Schema.Defect,
|
|
@@ -26,24 +28,10 @@ export function executeScopedRetrieval<TCandidate, E>(
|
|
|
26
28
|
return Effect.forEach(
|
|
27
29
|
tasks,
|
|
28
30
|
(task) =>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return result.pipe(
|
|
34
|
-
Effect.mapError((cause) => toScopedRetrievalError(task.scopeTag, cause)),
|
|
35
|
-
Effect.map((candidates) => ({ scopeTag: task.scopeTag, candidates })),
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return Effect.tryPromise({
|
|
40
|
-
try: () => result,
|
|
41
|
-
catch: (cause) => toScopedRetrievalError(task.scopeTag, cause),
|
|
42
|
-
}).pipe(Effect.map((candidates) => ({ scopeTag: task.scopeTag, candidates })))
|
|
43
|
-
} catch (cause) {
|
|
44
|
-
return Effect.fail(toScopedRetrievalError(task.scopeTag, cause))
|
|
45
|
-
}
|
|
46
|
-
}),
|
|
31
|
+
task.retrieve().pipe(
|
|
32
|
+
Effect.mapError((cause) => toScopedRetrievalError(task.scopeTag, cause)),
|
|
33
|
+
Effect.map((candidates) => ({ scopeTag: task.scopeTag, candidates })),
|
|
34
|
+
),
|
|
47
35
|
{ concurrency: 'unbounded' },
|
|
48
36
|
)
|
|
49
37
|
}
|
|
@@ -105,16 +105,10 @@ export interface LotaRuntimeSocialChatConfig {
|
|
|
105
105
|
slack?: LotaSocialChatSlackConfig
|
|
106
106
|
historyRedisKeyPrefix?: string
|
|
107
107
|
stateRedisKeyPrefix?: string
|
|
108
|
-
resolveContext: (
|
|
109
|
-
|
|
110
|
-
) => LotaSocialChatResolvedContext | Promise<LotaSocialChatResolvedContext>
|
|
111
|
-
buildAgentTools: (params: BuildSocialChatAgentToolsParams) => ToolSet | Promise<ToolSet>
|
|
108
|
+
resolveContext: (params: LotaSocialChatResolveContextParams) => Promise<LotaSocialChatResolvedContext>
|
|
109
|
+
buildAgentTools: (params: BuildSocialChatAgentToolsParams) => Promise<ToolSet>
|
|
112
110
|
getConsultParticipants?:
|
|
113
|
-
| ((params: {
|
|
114
|
-
workspaceId: RecordIdRef
|
|
115
|
-
workspaceIdString: string
|
|
116
|
-
platform: 'slack'
|
|
117
|
-
}) => string[] | Promise<string[]>)
|
|
111
|
+
| ((params: { workspaceId: RecordIdRef; workspaceIdString: string; platform: 'slack' }) => Promise<string[]>)
|
|
118
112
|
| undefined
|
|
119
113
|
}
|
|
120
114
|
|
|
@@ -35,12 +35,10 @@ export interface LotaRuntimeProfileProjection {
|
|
|
35
35
|
|
|
36
36
|
export interface LotaRuntimeWorkspaceProvider {
|
|
37
37
|
getWorkspace(workspaceId: RecordIdRef): Promise<Record<string, unknown>>
|
|
38
|
-
getLifecycleState?(
|
|
39
|
-
workspace: Record<string, unknown>,
|
|
40
|
-
): Promise<LotaRuntimeWorkspaceLifecycleState> | LotaRuntimeWorkspaceLifecycleState
|
|
38
|
+
getLifecycleState?(workspace: Record<string, unknown>): Promise<LotaRuntimeWorkspaceLifecycleState>
|
|
41
39
|
readProfileProjectionState?(
|
|
42
40
|
workspace: Record<string, unknown>,
|
|
43
|
-
): Promise<LotaRuntimeWorkspaceProjectionState | undefined>
|
|
41
|
+
): Promise<LotaRuntimeWorkspaceProjectionState | undefined>
|
|
44
42
|
buildPromptSummary?(workspaceId: RecordIdRef): Promise<string | undefined>
|
|
45
43
|
listRecentDomainEvents?(workspaceId: RecordIdRef, limit?: number): Promise<Array<Record<string, unknown>>>
|
|
46
44
|
hasActiveKnowledgeSources?(workspaceId: string): Promise<boolean>
|