@lota-sdk/core 0.4.10 → 0.4.12
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 +3 -3
- package/src/ai-gateway/ai-gateway.ts +214 -98
- package/src/ai-gateway/index.ts +16 -1
- package/src/config/agent-defaults.ts +4 -120
- package/src/config/logger.ts +18 -34
- package/src/config/model-constants.ts +1 -0
- package/src/config/thread-defaults.ts +1 -18
- package/src/create-runtime.ts +90 -28
- package/src/db/base.service.ts +30 -38
- package/src/db/service.ts +489 -545
- package/src/effect/index.ts +0 -2
- package/src/effect/layers.ts +6 -13
- package/src/embeddings/provider.ts +2 -7
- package/src/index.ts +4 -5
- package/src/queues/autonomous-job.queue.ts +159 -113
- package/src/queues/context-compaction.queue.ts +39 -25
- package/src/queues/delayed-node-promotion.queue.ts +56 -29
- 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 +63 -39
- package/src/queues/plan-agent-heartbeat.queue.ts +104 -79
- package/src/queues/plan-scheduler.queue.ts +100 -84
- package/src/queues/post-chat-memory.queue.ts +55 -33
- package/src/queues/queue-factory.ts +40 -41
- package/src/queues/queues.service.ts +61 -0
- package/src/queues/title-generation.queue.ts +42 -31
- package/src/redis/org-memory-lock.ts +24 -9
- package/src/redis/redis-lease-lock.ts +8 -1
- package/src/runtime/agent-identity-overrides.ts +7 -3
- package/src/runtime/agent-runtime-policy.ts +9 -4
- package/src/runtime/agent-stream-helpers.ts +9 -4
- package/src/runtime/context-compaction/context-compaction-runtime.ts +28 -32
- package/src/runtime/context-compaction/context-compaction.ts +9 -7
- package/src/runtime/domain-layer.ts +15 -4
- package/src/runtime/execution-plan-visibility.ts +5 -2
- package/src/runtime/graph-designer.ts +0 -22
- package/src/runtime/index.ts +2 -0
- package/src/runtime/indexed-repositories-policy.ts +2 -6
- package/src/runtime/live-turn-trace.ts +344 -0
- package/src/runtime/plugin-resolution.ts +29 -12
- package/src/runtime/post-turn-side-effects.ts +139 -141
- package/src/runtime/runtime-config.ts +0 -6
- package/src/runtime/runtime-extensions.ts +0 -54
- package/src/runtime/runtime-lifecycle.ts +4 -4
- package/src/runtime/runtime-services.ts +125 -53
- package/src/runtime/runtime-worker-registry.ts +113 -30
- package/src/runtime/social-chat/social-chat-agent-runner.ts +6 -3
- package/src/runtime/social-chat/social-chat-history.ts +3 -1
- package/src/runtime/social-chat/social-chat.ts +35 -20
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +6 -5
- 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 +7 -47
- package/src/runtime/turn-lifecycle.ts +6 -14
- package/src/services/agent-activity.service.ts +168 -175
- package/src/services/agent-executor.service.ts +35 -16
- package/src/services/attachment.service.ts +4 -70
- package/src/services/autonomous-job.service.ts +53 -61
- package/src/services/context-compaction.service.ts +7 -9
- package/src/services/execution-plan/execution-plan-graph.ts +106 -115
- package/src/services/execution-plan/execution-plan-schedule.ts +1 -15
- package/src/services/execution-plan/execution-plan.service.ts +67 -50
- package/src/services/global-orchestrator.service.ts +18 -7
- package/src/services/graph-full-routing.ts +7 -6
- package/src/services/memory/memory-conversation.ts +10 -5
- package/src/services/memory/memory.service.ts +11 -8
- package/src/services/ownership-dispatcher.service.ts +16 -5
- package/src/services/plan/plan-agent-heartbeat.service.ts +29 -15
- package/src/services/plan/plan-agent-query.service.ts +12 -8
- package/src/services/plan/plan-completion-side-effects.ts +93 -101
- package/src/services/plan/plan-cycle.service.ts +7 -45
- package/src/services/plan/plan-deadline.service.ts +28 -17
- package/src/services/plan/plan-event-delivery.service.ts +47 -40
- package/src/services/plan/plan-executor-context.ts +2 -0
- package/src/services/plan/plan-executor-graph.ts +366 -391
- package/src/services/plan/plan-executor.service.ts +13 -91
- package/src/services/plan/plan-scheduler.service.ts +62 -49
- package/src/services/plan/plan-transaction-events.ts +1 -1
- package/src/services/recent-activity-title.service.ts +6 -2
- package/src/services/thread/thread-bootstrap.ts +11 -9
- package/src/services/thread/thread-message.service.ts +6 -5
- package/src/services/thread/thread-turn-execution.ts +86 -82
- package/src/services/thread/thread-turn-preparation.service.ts +92 -45
- package/src/services/thread/thread-turn-streaming.ts +60 -28
- package/src/services/thread/thread-turn.ts +212 -46
- package/src/services/thread/thread.service.ts +21 -6
- package/src/system-agents/recent-activity-title-refiner.agent.ts +8 -5
- package/src/system-agents/thread-router.agent.ts +23 -20
- package/src/tools/execution-plan.tool.ts +8 -3
- package/src/tools/fetch-webpage.tool.ts +10 -9
- package/src/tools/firecrawl-client.ts +0 -15
- 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 +10 -9
- package/src/tools/search.tool.ts +4 -5
- package/src/tools/team-think.tool.ts +139 -121
- package/src/workers/bootstrap.ts +9 -10
- package/src/workers/memory-consolidation.worker.ts +4 -1
- package/src/workers/organization-learning.worker.ts +15 -2
- package/src/workers/regular-chat-memory-digest.helpers.ts +3 -4
- package/src/workers/regular-chat-memory-digest.runner.ts +21 -14
- package/src/workers/skill-extraction.runner.ts +13 -15
- package/src/workers/worker-utils.ts +6 -18
- package/src/effect/awaitable-effect.ts +0 -96
- package/src/effect/runtime-ref.ts +0 -25
- package/src/effect/runtime.ts +0 -46
- package/src/redis/runtime-connection.ts +0 -20
- package/src/runtime/runtime-accessors.ts +0 -92
- package/src/runtime/runtime-token.ts +0 -47
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { ToolSet } from 'ai'
|
|
2
2
|
|
|
3
3
|
import { ConfigurationError } from '../effect/errors'
|
|
4
|
-
import { resolveLotaService } from '../effect/runtime'
|
|
5
|
-
import { AgentConfigServiceTag, AgentFactoryServiceTag } from '../effect/services'
|
|
6
4
|
import type {
|
|
7
5
|
AgentFactory,
|
|
8
6
|
AgentRuntimeConfigParams,
|
|
@@ -130,125 +128,11 @@ export interface CoreThreadProfile {
|
|
|
130
128
|
instructions: string
|
|
131
129
|
}
|
|
132
130
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
export function configureAgentRuntimeDefaults(params: {
|
|
137
|
-
agentConfig: ResolvedAgentConfig
|
|
138
|
-
agentFactoryConfig: ResolvedAgentFactoryConfig
|
|
139
|
-
}): void {
|
|
140
|
-
currentResolvedAgentConfig = params.agentConfig
|
|
141
|
-
currentResolvedAgentFactoryConfig = params.agentFactoryConfig
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export function clearAgentRuntimeDefaults(): void {
|
|
145
|
-
currentResolvedAgentConfig = null
|
|
146
|
-
currentResolvedAgentFactoryConfig = null
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function resolveAgentConfigFromRuntime(): ResolvedAgentConfig {
|
|
150
|
-
return currentResolvedAgentConfig ?? resolveLotaService(AgentConfigServiceTag)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function resolveAgentFactoryConfigFromRuntime(): ResolvedAgentFactoryConfig {
|
|
154
|
-
return currentResolvedAgentFactoryConfig ?? resolveLotaService(AgentFactoryServiceTag)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export function getResolvedAgentConfig(): ResolvedAgentConfig {
|
|
158
|
-
return resolveAgentConfigFromRuntime()
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function getResolvedAgentFactoryConfig(): ResolvedAgentFactoryConfig {
|
|
162
|
-
return resolveAgentFactoryConfigFromRuntime()
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export function isAgentName(value: unknown): value is string {
|
|
166
|
-
return typeof value === 'string' && resolveAgentConfigFromRuntime().rosterSet.has(value)
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
export function getAgentRoster(): readonly string[] {
|
|
170
|
-
return resolveAgentConfigFromRuntime().roster
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export function getAgentDisplayNames(): Record<string, string> {
|
|
174
|
-
return resolveAgentConfigFromRuntime().displayNames
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export function getAgentShortDisplayNames(): Record<string, string> {
|
|
178
|
-
return resolveAgentConfigFromRuntime().shortDisplayNames
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export function getAgentDescriptions(): Record<string, string> {
|
|
182
|
-
return resolveAgentConfigFromRuntime().descriptions
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function getLeadAgentId(): string {
|
|
186
|
-
return resolveAgentConfigFromRuntime().leadAgentId
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export function getLeadAgentDisplayName(): string {
|
|
190
|
-
const resolved = resolveAgentConfigFromRuntime()
|
|
191
|
-
return resolved.displayNames[resolved.leadAgentId] ?? resolved.leadAgentId
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export function getRouterModelId(): string | undefined {
|
|
195
|
-
return resolveAgentConfigFromRuntime().routerModelId
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
export function getTeamConsultParticipants(): readonly string[] {
|
|
199
|
-
return resolveAgentConfigFromRuntime().teamConsultParticipants
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export function getCoreThreadProfile(coreType: string): CoreThreadProfile {
|
|
203
|
-
return resolveAgentConfigFromRuntime().getCoreThreadProfile(coreType)
|
|
131
|
+
export function isAgentName(agentConfig: ResolvedAgentConfig, value: unknown): value is string {
|
|
132
|
+
return typeof value === 'string' && agentConfig.rosterSet.has(value)
|
|
204
133
|
}
|
|
205
134
|
|
|
206
|
-
export function resolveAgentNameAlias(value: unknown): string | undefined {
|
|
135
|
+
export function resolveAgentNameAlias(agentConfig: ResolvedAgentConfig, value: unknown): string | undefined {
|
|
207
136
|
if (typeof value !== 'string') return undefined
|
|
208
|
-
return
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
export function getCreateAgentRegistry(): AgentFactory {
|
|
212
|
-
return resolveAgentFactoryConfigFromRuntime().createAgent
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
export function buildAgentTools(...args: Parameters<AgentToolBuilder>): ReturnType<AgentToolBuilder> {
|
|
216
|
-
return resolveAgentFactoryConfigFromRuntime().buildAgentTools(...args)
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
export function getAgentRuntimeConfig(
|
|
220
|
-
...args: Parameters<AgentRuntimeConfigProvider>
|
|
221
|
-
): ReturnType<AgentRuntimeConfigProvider> {
|
|
222
|
-
return resolveAgentFactoryConfigFromRuntime().getAgentRuntimeConfig(...args)
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
export function getPluginRuntime(): Record<string, unknown> | undefined {
|
|
226
|
-
return resolveAgentFactoryConfigFromRuntime().pluginRuntime
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const AGENT_MENTION_REGEX = /(^|[^\w])@([a-z][a-z0-9_-]*)\b/gi
|
|
230
|
-
|
|
231
|
-
export interface AgentMentionMatch {
|
|
232
|
-
agent: string
|
|
233
|
-
mention: string
|
|
234
|
-
index: number
|
|
235
|
-
length: number
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export function extractAgentMentions(message: string, agentConfig?: ResolvedAgentConfig): AgentMentionMatch[] {
|
|
239
|
-
const matches: AgentMentionMatch[] = []
|
|
240
|
-
if (!message.trim()) return matches
|
|
241
|
-
|
|
242
|
-
const resolvedConfig = agentConfig ?? resolveAgentConfigFromRuntime()
|
|
243
|
-
const regex = new RegExp(AGENT_MENTION_REGEX)
|
|
244
|
-
for (const rawMatch of message.matchAll(regex)) {
|
|
245
|
-
const prefix = rawMatch[1]
|
|
246
|
-
const rawAgent = rawMatch[2].toLowerCase()
|
|
247
|
-
if (!resolvedConfig.rosterSet.has(rawAgent)) continue
|
|
248
|
-
|
|
249
|
-
const index = rawMatch.index + prefix.length
|
|
250
|
-
matches.push({ agent: rawAgent, mention: `@${rawAgent}`, index, length: rawAgent.length + 1 })
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return matches
|
|
137
|
+
return agentConfig.aliasMap.get(normalizeAgentLookupKey(value))
|
|
254
138
|
}
|
package/src/config/logger.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { Effect, Logger, References } from 'effect'
|
|
2
2
|
|
|
3
|
-
import { getOptionalCurrentRuntime } from '../effect/runtime-ref'
|
|
4
|
-
|
|
5
3
|
const LOG_CATEGORY = 'lota-sdk'
|
|
6
4
|
|
|
7
5
|
export type LotaLogLevel = 'trace' | 'debug' | 'info' | 'warning' | 'error' | 'fatal'
|
|
@@ -46,19 +44,11 @@ function readEnvLogLevel(): LotaLogLevel | null {
|
|
|
46
44
|
return resolveLotaLogLevel(value)
|
|
47
45
|
}
|
|
48
46
|
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
export function configureLotaLogger(logLevel: LotaLogLevel = 'info'): void {
|
|
56
|
-
configuredLogLevel = logLevel
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function getConfiguredLogLevel(): LotaLogLevel {
|
|
60
|
-
return configuredLogLevel
|
|
61
|
-
}
|
|
47
|
+
// Loggers expose a sync `.info(...)` API that must work from both Effect
|
|
48
|
+
// and non-Effect call sites, so the level cannot live in Effect.Config
|
|
49
|
+
// (which requires Effect context to read). Resolve once from the environment
|
|
50
|
+
// at module load; hosts set `LOG_LEVEL` before importing the SDK.
|
|
51
|
+
const configuredLogLevel: LotaLogLevel = readEnvLogLevel() ?? 'info'
|
|
62
52
|
|
|
63
53
|
export function toEffectLogLevel(logLevel: LotaLogLevel): EffectLogLevel {
|
|
64
54
|
switch (logLevel) {
|
|
@@ -215,15 +205,6 @@ function getLogEffect(level: LotaLogLevel, message: string): LotaLogEffect {
|
|
|
215
205
|
}
|
|
216
206
|
}
|
|
217
207
|
|
|
218
|
-
function runStandaloneLogEffect(effect: LotaLogEffect): void {
|
|
219
|
-
Effect.runSync(
|
|
220
|
-
effect.pipe(
|
|
221
|
-
Effect.provide(Logger.layer([Logger.consolePretty()])),
|
|
222
|
-
Effect.provideService(References.MinimumLogLevel, toEffectLogLevel(configuredLogLevel)),
|
|
223
|
-
),
|
|
224
|
-
)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
208
|
function emitConsoleFallback(
|
|
228
209
|
level: LotaLogLevel,
|
|
229
210
|
category: readonly string[],
|
|
@@ -241,6 +222,9 @@ function emitConsoleFallback(
|
|
|
241
222
|
sink(formattedMessage, rest)
|
|
242
223
|
}
|
|
243
224
|
|
|
225
|
+
const standaloneLoggerLayer = Logger.layer([Logger.consolePretty()])
|
|
226
|
+
const standaloneMinLogLevel = toEffectLogLevel(configuredLogLevel)
|
|
227
|
+
|
|
244
228
|
function emit(level: LotaLogLevel, category: readonly string[], message: string, fields?: LogFields): void {
|
|
245
229
|
if (!shouldLog(level)) return
|
|
246
230
|
|
|
@@ -248,17 +232,17 @@ function emit(level: LotaLogLevel, category: readonly string[], message: string,
|
|
|
248
232
|
const annotations = { lotaLogger: category.join(':'), ...buildLogContext(fields) }
|
|
249
233
|
const effect = getLogEffect(level, formattedMessage).pipe(Effect.annotateLogs(annotations))
|
|
250
234
|
|
|
251
|
-
//
|
|
252
|
-
//
|
|
253
|
-
//
|
|
254
|
-
//
|
|
255
|
-
const runtime = getOptionalCurrentRuntime()
|
|
235
|
+
// Loggers run outside any managed runtime: every call provides its own
|
|
236
|
+
// console logger layer and minimum log level so the emit path does not
|
|
237
|
+
// depend on ambient runtime state. Effect-native code paths recover spans
|
|
238
|
+
// and fiber annotations naturally via `Effect.log*`.
|
|
256
239
|
try {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
240
|
+
Effect.runSync(
|
|
241
|
+
effect.pipe(
|
|
242
|
+
Effect.provide(standaloneLoggerLayer),
|
|
243
|
+
Effect.provideService(References.MinimumLogLevel, standaloneMinLogLevel),
|
|
244
|
+
),
|
|
245
|
+
)
|
|
262
246
|
} catch {
|
|
263
247
|
emitConsoleFallback(level, category, formattedMessage, annotations)
|
|
264
248
|
}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { resolveLotaService } from '../effect/runtime'
|
|
2
|
-
import { ThreadConfigServiceTag } from '../effect/services'
|
|
3
|
-
|
|
4
1
|
export interface ThreadBootstrapWelcomeConfig {
|
|
5
2
|
defaultAgentId: string
|
|
6
3
|
buildMessageText: (params: { userName?: string | null }) => string
|
|
@@ -28,16 +25,6 @@ interface ResolvedThreadBootstrapConfig {
|
|
|
28
25
|
|
|
29
26
|
export type { ResolvedThreadBootstrapConfig }
|
|
30
27
|
|
|
31
|
-
let currentThreadBootstrapConfig: ResolvedThreadBootstrapConfig | null = null
|
|
32
|
-
|
|
33
|
-
export function configureThreadRuntimeDefaults(config: ResolvedThreadBootstrapConfig): void {
|
|
34
|
-
currentThreadBootstrapConfig = config
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function clearThreadRuntimeDefaults(): void {
|
|
38
|
-
currentThreadBootstrapConfig = null
|
|
39
|
-
}
|
|
40
|
-
|
|
41
28
|
function normalizeThreadAgentIds(values: readonly string[]): readonly string[] {
|
|
42
29
|
const seen = new Set<string>()
|
|
43
30
|
const deduped: string[] = []
|
|
@@ -80,13 +67,9 @@ export function resolveThreadConfig(params: {
|
|
|
80
67
|
}
|
|
81
68
|
}
|
|
82
69
|
|
|
83
|
-
export function getThreadBootstrapConfig(): ResolvedThreadBootstrapConfig {
|
|
84
|
-
return currentThreadBootstrapConfig ?? resolveLotaService(ThreadConfigServiceTag)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
70
|
export function resolveOnboardingOwnerAgentId(
|
|
88
71
|
defaultLeadAgentId: string,
|
|
89
|
-
config: ResolvedThreadBootstrapConfig
|
|
72
|
+
config: ResolvedThreadBootstrapConfig,
|
|
90
73
|
): string {
|
|
91
74
|
return config.onboardingWelcome?.defaultAgentId ?? defaultLeadAgentId
|
|
92
75
|
}
|
package/src/create-runtime.ts
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
|
+
import type { Fiber } from 'effect'
|
|
1
2
|
import { Effect, ManagedRuntime } from 'effect'
|
|
2
3
|
import type { Subscriber } from 'resumable-stream/ioredis'
|
|
3
4
|
|
|
5
|
+
import { AiGatewayTag, bindAiGatewayRuntime } from './ai-gateway/ai-gateway'
|
|
4
6
|
import { computeSchemaFingerprint } from './db/schema-fingerprint'
|
|
5
7
|
import { publishDatabaseBootstrapEffect } from './db/startup'
|
|
6
8
|
import {
|
|
9
|
+
AgentConfigServiceTag,
|
|
10
|
+
AgentFactoryServiceTag,
|
|
7
11
|
buildInfrastructureLayer,
|
|
8
|
-
clearLotaSdkRuntime,
|
|
9
12
|
DatabaseServiceTag as EffectDatabaseService,
|
|
10
13
|
RedisServiceTag as EffectRedisService,
|
|
11
|
-
|
|
14
|
+
RuntimeAdaptersServiceTag,
|
|
15
|
+
RuntimeConfigServiceTag,
|
|
12
16
|
} from './effect'
|
|
13
17
|
import { ConfigurationError, ServiceError } from './effect/errors'
|
|
14
18
|
import { effectTryPromise } from './effect/helpers'
|
|
19
|
+
import { LotaQueuesServiceTag } from './queues/queues.service'
|
|
15
20
|
import type { RedisConnectionManager } from './redis/connection'
|
|
16
21
|
import { SharedThreadStreamSubscriberTag } from './redis/stream-context'
|
|
17
22
|
import { buildDomainServiceLayer } from './runtime/domain-layer'
|
|
18
23
|
import type { LotaPlugin, SystemNodeExecutor } from './runtime/plugin-types'
|
|
19
|
-
import { clearRuntimeModuleAccessors, configureRuntimeModuleAccessors } from './runtime/runtime-accessors'
|
|
20
24
|
import { LOTA_RUNTIME_ENV_KEYS, loadLotaRuntimeConfigFromEnv, parseLotaRuntimeConfig } from './runtime/runtime-config'
|
|
21
25
|
import type { LotaRuntimeConfig, ResolvedLotaRuntimeConfig } from './runtime/runtime-config'
|
|
22
26
|
import {
|
|
@@ -26,26 +30,34 @@ import {
|
|
|
26
30
|
} from './runtime/runtime-lifecycle'
|
|
27
31
|
import { buildRuntimeServiceSurface } from './runtime/runtime-services'
|
|
28
32
|
import type { LotaRuntimeLota, LotaRuntimeServices } from './runtime/runtime-services'
|
|
29
|
-
import { acquireRuntimeTokenEffect, isRuntimeTokenActive, releaseRuntimeToken } from './runtime/runtime-token'
|
|
30
33
|
import type { LotaRuntimeWorkers } from './runtime/runtime-worker-registry'
|
|
31
34
|
import { buildRuntimeWorkerRegistry } from './runtime/runtime-worker-registry'
|
|
32
35
|
import type { LotaRuntimeSocialChat } from './runtime/social-chat/social-chat'
|
|
33
36
|
import { createSocialChatRuntime } from './runtime/social-chat/social-chat'
|
|
37
|
+
import { AutonomousJobServiceTag } from './services/autonomous-job.service'
|
|
38
|
+
import { ContextCompactionServiceTag } from './services/context-compaction.service'
|
|
34
39
|
import { LearnedSkillServiceTag } from './services/learned-skill.service'
|
|
35
40
|
import { MemoryServiceTag } from './services/memory/memory.service'
|
|
41
|
+
import { PlanAgentHeartbeatServiceTag } from './services/plan/plan-agent-heartbeat.service'
|
|
42
|
+
import { PlanCycleServiceTag } from './services/plan/plan-cycle.service'
|
|
43
|
+
import { PlanDeadlineServiceTag } from './services/plan/plan-deadline.service'
|
|
44
|
+
import { PlanExecutorServiceTag } from './services/plan/plan-executor.service'
|
|
45
|
+
import { PlanSchedulerServiceTag } from './services/plan/plan-scheduler.service'
|
|
46
|
+
import { RecentActivityTitleServiceTag } from './services/recent-activity-title.service'
|
|
36
47
|
import { SocialChatHistoryServiceTag } from './services/social-chat-history.service'
|
|
37
48
|
import { getBuiltInSystemExecutors } from './services/system-executor.service'
|
|
49
|
+
import { ThreadTitleServiceTag } from './services/thread/thread-title.service'
|
|
38
50
|
import { ThreadTurnServiceTag } from './services/thread/thread-turn'
|
|
39
|
-
|
|
40
|
-
// Re-exported for consumers that reason about the runtime slot without
|
|
41
|
-
// instantiating one (e.g., diagnostic harnesses).
|
|
42
|
-
export { isRuntimeTokenActive }
|
|
51
|
+
import { ThreadServiceTag } from './services/thread/thread.service'
|
|
43
52
|
|
|
44
53
|
export interface LotaRuntime {
|
|
45
54
|
/** Run an Effect as a Promise through the SDK runtime (carries OTLP context). */
|
|
46
|
-
runPromise: <A, E>(effect: Effect.Effect<A, E>, options?: { readonly signal?: AbortSignal }) => Promise<A>
|
|
55
|
+
runPromise: <A, E, R>(effect: Effect.Effect<A, E, R>, options?: { readonly signal?: AbortSignal }) => Promise<A>
|
|
47
56
|
/** Run an Effect synchronously through the SDK runtime. */
|
|
48
|
-
runSync: <A, E>(effect: Effect.Effect<A, E>) => A
|
|
57
|
+
runSync: <A, E, R>(effect: Effect.Effect<A, E, R>) => A
|
|
58
|
+
/** Fork an Effect as a Fiber through the SDK runtime (carries OTLP context). */
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
60
|
+
runFork: <A, E, R>(effect: Effect.Effect<A, E, R>) => Fiber.Fiber<A, E | unknown>
|
|
49
61
|
services: LotaRuntimeServices
|
|
50
62
|
lota: LotaRuntimeLota
|
|
51
63
|
redis: {
|
|
@@ -77,14 +89,10 @@ export function createLotaRuntimeFromEnv(
|
|
|
77
89
|
}
|
|
78
90
|
|
|
79
91
|
export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntime> {
|
|
80
|
-
let runtimeToken: symbol | null = null
|
|
81
92
|
let effectRuntime: { dispose(): Promise<void> } | null = null
|
|
82
93
|
|
|
83
94
|
return Effect.runPromise(
|
|
84
95
|
Effect.gen(function* () {
|
|
85
|
-
// Fail fast if another runtime is already active in this process.
|
|
86
|
-
runtimeToken = yield* acquireRuntimeTokenEffect()
|
|
87
|
-
|
|
88
96
|
const resolvedConfig = parseLotaRuntimeConfig(config)
|
|
89
97
|
const systemExecutors = { ...getBuiltInSystemExecutors(), ...resolvedConfig.systemExecutors }
|
|
90
98
|
const runtimeConfig = { ...resolvedConfig, systemExecutors } satisfies ResolvedLotaRuntimeConfig
|
|
@@ -121,6 +129,22 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
|
|
|
121
129
|
socialChatHistoryService: yield* SocialChatHistoryServiceTag,
|
|
122
130
|
learnedSkillService: yield* LearnedSkillServiceTag,
|
|
123
131
|
memoryService: yield* MemoryServiceTag,
|
|
132
|
+
runtimeAdapters: yield* RuntimeAdaptersServiceTag,
|
|
133
|
+
agentConfig: yield* AgentConfigServiceTag,
|
|
134
|
+
agentFactoryConfig: yield* AgentFactoryServiceTag,
|
|
135
|
+
queues: yield* LotaQueuesServiceTag,
|
|
136
|
+
autonomousJobService: yield* AutonomousJobServiceTag,
|
|
137
|
+
contextCompactionService: yield* ContextCompactionServiceTag,
|
|
138
|
+
threadService: yield* ThreadServiceTag,
|
|
139
|
+
planAgentHeartbeatService: yield* PlanAgentHeartbeatServiceTag,
|
|
140
|
+
planSchedulerService: yield* PlanSchedulerServiceTag,
|
|
141
|
+
planDeadlineService: yield* PlanDeadlineServiceTag,
|
|
142
|
+
planExecutorService: yield* PlanExecutorServiceTag,
|
|
143
|
+
planCycleService: yield* PlanCycleServiceTag,
|
|
144
|
+
threadTitleService: yield* ThreadTitleServiceTag,
|
|
145
|
+
recentActivityTitleService: yield* RecentActivityTitleServiceTag,
|
|
146
|
+
aiGateway: yield* AiGatewayTag,
|
|
147
|
+
runtimeConfigService: yield* RuntimeConfigServiceTag,
|
|
124
148
|
}
|
|
125
149
|
}),
|
|
126
150
|
),
|
|
@@ -138,10 +162,32 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
|
|
|
138
162
|
socialChatHistoryService,
|
|
139
163
|
learnedSkillService,
|
|
140
164
|
memoryService,
|
|
165
|
+
runtimeAdapters,
|
|
166
|
+
agentConfig,
|
|
167
|
+
agentFactoryConfig,
|
|
168
|
+
queues,
|
|
169
|
+
autonomousJobService,
|
|
170
|
+
contextCompactionService,
|
|
171
|
+
threadService,
|
|
172
|
+
planAgentHeartbeatService,
|
|
173
|
+
planSchedulerService,
|
|
174
|
+
planDeadlineService,
|
|
175
|
+
planExecutorService,
|
|
176
|
+
planCycleService,
|
|
177
|
+
threadTitleService,
|
|
178
|
+
recentActivityTitleService,
|
|
179
|
+
aiGateway,
|
|
180
|
+
runtimeConfigService,
|
|
141
181
|
} = resolvedServices
|
|
142
182
|
|
|
143
|
-
|
|
144
|
-
|
|
183
|
+
// Seed the AI gateway middleware so wrapGenerate/wrapStream/wrapEmbed
|
|
184
|
+
// edges can run Effects without reaching for an ambient runtime slot.
|
|
185
|
+
bindAiGatewayRuntime({
|
|
186
|
+
gateway: aiGateway,
|
|
187
|
+
runtimeConfig: runtimeConfigService,
|
|
188
|
+
runPromise: (effect) => managedRuntime.runPromise(effect),
|
|
189
|
+
runFork: (effect) => managedRuntime.runFork(effect),
|
|
190
|
+
})
|
|
145
191
|
|
|
146
192
|
// ── Schema + plugin + worker + social-chat composition ────────────
|
|
147
193
|
const pluginRuntime = runtimeConfig.pluginRuntime ?? {}
|
|
@@ -164,13 +210,33 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
|
|
|
164
210
|
pluginRuntime,
|
|
165
211
|
connectedPluginDatabases,
|
|
166
212
|
)
|
|
167
|
-
const workers = buildRuntimeWorkerRegistry(
|
|
213
|
+
const workers = buildRuntimeWorkerRegistry(
|
|
214
|
+
queues,
|
|
215
|
+
{
|
|
216
|
+
databaseService: db,
|
|
217
|
+
threadService,
|
|
218
|
+
contextCompactionService,
|
|
219
|
+
autonomousJobService,
|
|
220
|
+
memoryService,
|
|
221
|
+
planAgentHeartbeatService,
|
|
222
|
+
planSchedulerService,
|
|
223
|
+
planDeadlineService,
|
|
224
|
+
planExecutorService,
|
|
225
|
+
planCycleService,
|
|
226
|
+
threadTitleService,
|
|
227
|
+
recentActivityTitleService,
|
|
228
|
+
redisManager,
|
|
229
|
+
},
|
|
230
|
+
runtimeConfig.extraWorkers,
|
|
231
|
+
)
|
|
168
232
|
const socialChat = createSocialChatRuntime({
|
|
233
|
+
agentConfig,
|
|
234
|
+
agentFactoryConfig,
|
|
169
235
|
redisClient: redisManager.getConnection() as unknown as Parameters<
|
|
170
236
|
typeof createSocialChatRuntime
|
|
171
237
|
>[0]['redisClient'],
|
|
172
238
|
socialChat: runtimeConfig.socialChat,
|
|
173
|
-
services: { learnedSkillService, memoryService, socialChatHistoryService },
|
|
239
|
+
services: { learnedSkillService, memoryService, socialChatHistoryService, runtimeAdapters, queues },
|
|
174
240
|
})
|
|
175
241
|
const currentContext = yield* Effect.context()
|
|
176
242
|
const runPromiseWithCurrentContext = Effect.runPromiseWith(currentContext)
|
|
@@ -190,16 +256,15 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
|
|
|
190
256
|
runPromiseWithCurrentContext,
|
|
191
257
|
socialChatShutdown: () => socialChat.shutdown(),
|
|
192
258
|
disconnectPluginDatabases,
|
|
193
|
-
onFinalize: () => {
|
|
194
|
-
clearRuntimeModuleAccessors()
|
|
195
|
-
clearLotaSdkRuntime()
|
|
196
|
-
if (runtimeToken) releaseRuntimeToken(runtimeToken)
|
|
197
|
-
},
|
|
198
259
|
})
|
|
199
260
|
|
|
200
261
|
const lotaRuntime: LotaRuntime = {
|
|
201
|
-
runPromise: (effect, options
|
|
202
|
-
|
|
262
|
+
runPromise: <A, E, R>(effect: Effect.Effect<A, E, R>, options?: { readonly signal?: AbortSignal }) =>
|
|
263
|
+
managedRuntime.runPromise(effect as unknown as Effect.Effect<A, E, never>, options),
|
|
264
|
+
runSync: <A, E, R>(effect: Effect.Effect<A, E, R>) =>
|
|
265
|
+
managedRuntime.runSync(effect as unknown as Effect.Effect<A, E, never>),
|
|
266
|
+
runFork: <A, E, R>(effect: Effect.Effect<A, E, R>) =>
|
|
267
|
+
managedRuntime.runFork(effect as unknown as Effect.Effect<A, E, never>),
|
|
203
268
|
services,
|
|
204
269
|
lota,
|
|
205
270
|
redis: {
|
|
@@ -235,11 +300,8 @@ export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntim
|
|
|
235
300
|
}),
|
|
236
301
|
).catch((error) => {
|
|
237
302
|
if (effectRuntime) {
|
|
238
|
-
clearRuntimeModuleAccessors()
|
|
239
|
-
clearLotaSdkRuntime()
|
|
240
303
|
void effectRuntime.dispose().catch(() => undefined)
|
|
241
304
|
}
|
|
242
|
-
if (runtimeToken) releaseRuntimeToken(runtimeToken)
|
|
243
305
|
throw error
|
|
244
306
|
})
|
|
245
307
|
}
|
package/src/db/base.service.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Effect } from 'effect'
|
|
2
2
|
import type { z } from 'zod'
|
|
3
3
|
|
|
4
|
-
import type { AwaitableEffect } from '../effect/awaitable-effect'
|
|
5
|
-
import { toAwaitableEffect } from '../effect/awaitable-effect'
|
|
6
4
|
import { NotFoundError } from '../effect/errors'
|
|
7
5
|
import { ensureRecordId } from './record-id'
|
|
8
6
|
import type { SurrealDBService } from './service'
|
|
@@ -16,7 +14,7 @@ export abstract class BaseService<T extends z.ZodType> {
|
|
|
16
14
|
protected readonly databaseService: SurrealDBService,
|
|
17
15
|
) {}
|
|
18
16
|
|
|
19
|
-
findById(id: unknown):
|
|
17
|
+
findById(id: unknown): Effect.Effect<z.infer<T> | null, SurrealDBError, never> {
|
|
20
18
|
return this.databaseService.findOne(
|
|
21
19
|
this.table,
|
|
22
20
|
{ id: ensureRecordId(id as Parameters<typeof ensureRecordId>[0], this.table) },
|
|
@@ -24,61 +22,55 @@ export abstract class BaseService<T extends z.ZodType> {
|
|
|
24
22
|
)
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
getById(id: unknown):
|
|
25
|
+
getById(id: unknown): Effect.Effect<z.infer<T>, SurrealDBError | NotFoundError, never> {
|
|
28
26
|
const { table, databaseService, schema } = this
|
|
29
|
-
return
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
)
|
|
27
|
+
return Effect.gen(function* () {
|
|
28
|
+
const record = yield* databaseService.findOne(
|
|
29
|
+
table,
|
|
30
|
+
{ id: ensureRecordId(id as Parameters<typeof ensureRecordId>[0], table) },
|
|
31
|
+
schema,
|
|
32
|
+
)
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
if (!record) {
|
|
35
|
+
return yield* new NotFoundError({ resource: table, message: `${table} record not found` })
|
|
36
|
+
}
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
)
|
|
38
|
+
return record
|
|
39
|
+
})
|
|
44
40
|
}
|
|
45
41
|
|
|
46
42
|
findAll(
|
|
47
43
|
filter: Record<string, unknown> = {},
|
|
48
44
|
options?: { limit?: number; offset?: number; orderBy?: keyof z.infer<T> & string; orderDir?: 'ASC' | 'DESC' },
|
|
49
|
-
):
|
|
45
|
+
): Effect.Effect<z.infer<T>[], SurrealDBError, never> {
|
|
50
46
|
return this.databaseService.findMany(this.table, filter, this.schema, options)
|
|
51
47
|
}
|
|
52
48
|
|
|
53
|
-
create(data: Record<string, unknown>):
|
|
49
|
+
create(data: Record<string, unknown>): Effect.Effect<z.infer<T>, SurrealDBError, never> {
|
|
54
50
|
return this.databaseService.create(this.table, data, this.schema)
|
|
55
51
|
}
|
|
56
52
|
|
|
57
|
-
update(id: unknown, data: Record<string, unknown>):
|
|
53
|
+
update(id: unknown, data: Record<string, unknown>): Effect.Effect<z.infer<T>, SurrealDBError | NotFoundError, never> {
|
|
58
54
|
const { table, databaseService, schema } = this
|
|
59
|
-
return
|
|
60
|
-
|
|
61
|
-
const updated = yield* databaseService.update(table, id, data, schema)
|
|
55
|
+
return Effect.gen(function* () {
|
|
56
|
+
const updated = yield* databaseService.update(table, id, data, schema)
|
|
62
57
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
if (!updated) {
|
|
59
|
+
return yield* new NotFoundError({ resource: table, message: `${table} record not found` })
|
|
60
|
+
}
|
|
66
61
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
)
|
|
62
|
+
return updated
|
|
63
|
+
})
|
|
70
64
|
}
|
|
71
65
|
|
|
72
|
-
delete(id: unknown):
|
|
66
|
+
delete(id: unknown): Effect.Effect<void, SurrealDBError | NotFoundError, never> {
|
|
73
67
|
const { table, databaseService } = this
|
|
74
|
-
return
|
|
75
|
-
|
|
76
|
-
const deleted = yield* databaseService.deleteById(table, id)
|
|
68
|
+
return Effect.gen(function* () {
|
|
69
|
+
const deleted = yield* databaseService.deleteById(table, id)
|
|
77
70
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
)
|
|
71
|
+
if (!deleted) {
|
|
72
|
+
return yield* new NotFoundError({ resource: table, message: `${table} record not found` })
|
|
73
|
+
}
|
|
74
|
+
})
|
|
83
75
|
}
|
|
84
76
|
}
|