@lota-sdk/core 0.4.10 → 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-gateway/ai-gateway.ts +149 -95
- 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/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 +1 -0
- package/src/runtime/indexed-repositories-policy.ts +2 -6
- 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 +122 -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 +47 -24
- package/src/services/thread/thread-turn-streaming.ts +20 -25
- package/src/services/thread/thread-turn.ts +25 -44
- 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
|
@@ -5,22 +5,9 @@ import { Effect } from 'effect'
|
|
|
5
5
|
import type { Context } from 'effect'
|
|
6
6
|
|
|
7
7
|
import { chatLogger } from '../config/logger'
|
|
8
|
-
import {
|
|
9
|
-
import { QueueJobServiceTag } from '../services/queue-job.service'
|
|
8
|
+
import type { QueueJobServiceTag } from '../services/queue-job.service'
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export function configureQueueJobService(service: Context.Service.Shape<typeof QueueJobServiceTag>): void {
|
|
14
|
-
currentQueueJobService = service
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function clearQueueJobService(): void {
|
|
18
|
-
currentQueueJobService = null
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function getQueueJobService(): Context.Service.Shape<typeof QueueJobServiceTag> {
|
|
22
|
-
return currentQueueJobService ?? resolveLotaService(QueueJobServiceTag)
|
|
23
|
-
}
|
|
10
|
+
export type QueueJobService = Context.Service.Shape<typeof QueueJobServiceTag>
|
|
24
11
|
|
|
25
12
|
export const DEFAULT_JOB_RETENTION = { removeOnComplete: true, removeOnFail: { age: 24 * 60 * 60, count: 200 } }
|
|
26
13
|
export const LOW_JOB_RETENTION = { removeOnComplete: true, removeOnFail: { age: 6 * 60 * 60, count: 50 } }
|
|
@@ -98,6 +85,7 @@ export const createWorkerShutdown = (worker: Worker, name: string, logger: typeo
|
|
|
98
85
|
export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike, TResult = void>(
|
|
99
86
|
queueName: string,
|
|
100
87
|
processor: (job: TJob) => Promise<TResult>,
|
|
88
|
+
queueJobService: QueueJobService,
|
|
101
89
|
): (job: TJob) => Promise<TResult> {
|
|
102
90
|
return (job: TJob) => {
|
|
103
91
|
const trackedJob = {
|
|
@@ -117,7 +105,7 @@ export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike, TR
|
|
|
117
105
|
return Effect.runPromise(
|
|
118
106
|
Effect.catch(
|
|
119
107
|
Effect.gen(function* () {
|
|
120
|
-
yield* Effect.catch(
|
|
108
|
+
yield* Effect.catch(queueJobService.markAttemptStarted(trackedJob), (error) =>
|
|
121
109
|
Effect.sync(() => {
|
|
122
110
|
logPersistenceError('start', error)
|
|
123
111
|
}),
|
|
@@ -125,7 +113,7 @@ export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike, TR
|
|
|
125
113
|
|
|
126
114
|
const result = yield* Effect.tryPromise(() => processor(job))
|
|
127
115
|
|
|
128
|
-
yield* Effect.catch(
|
|
116
|
+
yield* Effect.catch(queueJobService.markAttemptCompleted(trackedJob, result), (error) =>
|
|
129
117
|
Effect.sync(() => {
|
|
130
118
|
logPersistenceError('completion', error)
|
|
131
119
|
}),
|
|
@@ -135,7 +123,7 @@ export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike, TR
|
|
|
135
123
|
}),
|
|
136
124
|
(error) =>
|
|
137
125
|
Effect.gen(function* () {
|
|
138
|
-
yield* Effect.catch(
|
|
126
|
+
yield* Effect.catch(queueJobService.markAttemptFailed(trackedJob, error), (persistenceError) =>
|
|
139
127
|
Effect.sync(() => {
|
|
140
128
|
logPersistenceError('failure', persistenceError)
|
|
141
129
|
}),
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect'
|
|
2
|
-
|
|
3
|
-
export type AwaitableEffect<A, E> = Effect.Effect<A, E, never> & Promise<A>
|
|
4
|
-
|
|
5
|
-
export type AwaitableValue<T> = T extends (...args: infer TArgs) => Effect.Effect<infer A, infer E, never>
|
|
6
|
-
? (...args: TArgs) => AwaitableEffect<A, E>
|
|
7
|
-
: T extends (...args: infer TArgs) => infer TResult
|
|
8
|
-
? (...args: TArgs) => TResult
|
|
9
|
-
: T
|
|
10
|
-
|
|
11
|
-
type AwaitableServiceMethods<T> = {
|
|
12
|
-
[K in keyof T]: AwaitableValue<T[K]>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type AwaitableService<T> = AwaitableServiceMethods<T>
|
|
16
|
-
|
|
17
|
-
export type MaybeAwaitableService<T extends object> = T | AwaitableService<T>
|
|
18
|
-
|
|
19
|
-
type AwaitableEffectOptions = { runPromise?: <A, E>(effect: Effect.Effect<A, E, never>) => Promise<A> }
|
|
20
|
-
|
|
21
|
-
type Callable = (...args: Array<unknown>) => unknown
|
|
22
|
-
|
|
23
|
-
function isCallable(value: unknown): value is Callable {
|
|
24
|
-
return typeof value === 'function'
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function isRuntimeEffect(value: unknown): value is Effect.Effect<unknown, never, never> {
|
|
28
|
-
return Effect.isEffect(value)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Wraps an Effect so it can be `await`-ed as if it were a Promise, while still
|
|
33
|
-
* passing `Effect.isEffect` checks and exposing the underlying Effect properties.
|
|
34
|
-
*
|
|
35
|
-
* Implementation: returns a `Proxy` around the Effect that only intercepts the
|
|
36
|
-
* PromiseLike methods (`then`/`catch`/`finally`) plus `Symbol.toStringTag`. The
|
|
37
|
-
* Promise is created lazily on first `await` and cached for the wrapper's
|
|
38
|
-
* lifetime so repeated awaits share a result. The original Effect object is
|
|
39
|
-
* never mutated.
|
|
40
|
-
*/
|
|
41
|
-
export function toAwaitableEffect<A, E>(
|
|
42
|
-
effect: Effect.Effect<A, E, never>,
|
|
43
|
-
options?: AwaitableEffectOptions,
|
|
44
|
-
): AwaitableEffect<A, E> {
|
|
45
|
-
const runPromise = options?.runPromise ?? Effect.runPromise
|
|
46
|
-
let cachedPromise: Promise<A> | undefined
|
|
47
|
-
const getPromise = (): Promise<A> => (cachedPromise ??= runPromise(effect))
|
|
48
|
-
|
|
49
|
-
const then: Promise<A>['then'] = (onFulfilled, onRejected) => getPromise().then(onFulfilled, onRejected)
|
|
50
|
-
const catchMethod: Promise<A>['catch'] = (onRejected) => getPromise().catch(onRejected)
|
|
51
|
-
const finallyMethod: Promise<A>['finally'] = (onFinally) => getPromise().finally(onFinally)
|
|
52
|
-
|
|
53
|
-
return new Proxy(effect as object, {
|
|
54
|
-
get(target, property, receiver) {
|
|
55
|
-
if (property === 'then') return then
|
|
56
|
-
if (property === 'catch') return catchMethod
|
|
57
|
-
if (property === 'finally') return finallyMethod
|
|
58
|
-
if (property === Symbol.toStringTag) return 'Promise'
|
|
59
|
-
return Reflect.get(target, property, receiver) as unknown
|
|
60
|
-
},
|
|
61
|
-
}) as AwaitableEffect<A, E>
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Returns a proxy over a service whose Effect-returning methods are
|
|
66
|
-
* transparently wrapped with `toAwaitableEffect`. Non-Effect return values
|
|
67
|
-
* pass through untouched.
|
|
68
|
-
*/
|
|
69
|
-
export function toAwaitableService<T extends object>(
|
|
70
|
-
service: T,
|
|
71
|
-
options?: AwaitableEffectOptions,
|
|
72
|
-
): AwaitableService<T> {
|
|
73
|
-
const wrappedMethods = new Map<PropertyKey, Callable>()
|
|
74
|
-
|
|
75
|
-
return new Proxy(service, {
|
|
76
|
-
get(target, property, receiver) {
|
|
77
|
-
const value = Reflect.get(target, property, receiver)
|
|
78
|
-
if (!isCallable(value)) {
|
|
79
|
-
return value
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const existing = wrappedMethods.get(property)
|
|
83
|
-
if (existing) {
|
|
84
|
-
return existing
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const wrapped: Callable = (...args) => {
|
|
88
|
-
const result = value.apply(target, args)
|
|
89
|
-
return isRuntimeEffect(result) ? toAwaitableEffect(result, options) : result
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
wrappedMethods.set(property, wrapped)
|
|
93
|
-
return wrapped
|
|
94
|
-
},
|
|
95
|
-
}) as AwaitableService<T>
|
|
96
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { ManagedRuntime } from 'effect'
|
|
2
|
-
|
|
3
|
-
// eslint-disable-next-line typescript-eslint/no-explicit-any -- ManagedRuntime is contravariant in R; `any` is the only valid wildcard
|
|
4
|
-
type SdkManagedRuntime = ManagedRuntime.ManagedRuntime<any, any>
|
|
5
|
-
|
|
6
|
-
let currentRuntime: SdkManagedRuntime | null = null
|
|
7
|
-
|
|
8
|
-
export function setCurrentRuntime<R, E>(runtime: ManagedRuntime.ManagedRuntime<R, E>): void {
|
|
9
|
-
currentRuntime = runtime as SdkManagedRuntime
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function clearCurrentRuntime(): void {
|
|
13
|
-
currentRuntime = null
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function getCurrentRuntime(): SdkManagedRuntime {
|
|
17
|
-
if (!currentRuntime) {
|
|
18
|
-
throw new Error('Lota Effect runtime is not configured. Call createLotaRuntime() first.')
|
|
19
|
-
}
|
|
20
|
-
return currentRuntime
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function getOptionalCurrentRuntime(): SdkManagedRuntime | null {
|
|
24
|
-
return currentRuntime
|
|
25
|
-
}
|
package/src/effect/runtime.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect'
|
|
2
|
-
import type { Context, ManagedRuntime } from 'effect'
|
|
3
|
-
|
|
4
|
-
import { clearCurrentRuntime, getCurrentRuntime, getOptionalCurrentRuntime, setCurrentRuntime } from './runtime-ref'
|
|
5
|
-
|
|
6
|
-
export function setLotaSdkRuntime<R, E>(runtime: ManagedRuntime.ManagedRuntime<R, E>): void {
|
|
7
|
-
setCurrentRuntime(runtime)
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function clearLotaSdkRuntime(): void {
|
|
11
|
-
clearCurrentRuntime()
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function getOptionalLotaSdkRuntime() {
|
|
15
|
-
return getOptionalCurrentRuntime()
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** Returns the current managed runtime or throws. */
|
|
19
|
-
export function getLotaSdkRuntime() {
|
|
20
|
-
return getCurrentRuntime()
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function resolveLotaService<I, T>(tag: Context.Key<I, T>): T {
|
|
24
|
-
return getCurrentRuntime().runSync(Effect.service(tag))
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function resolveOptionalLotaService<I, T>(tag: Context.Key<I, T>): T | null {
|
|
28
|
-
const runtime = getOptionalCurrentRuntime()
|
|
29
|
-
return runtime ? runtime.runSync(Effect.service(tag)) : null
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function runPromiseWithOptionalLotaRuntime<A, E>(effect: Effect.Effect<A, E, never>): Promise<A> {
|
|
33
|
-
const runtime = getOptionalCurrentRuntime()
|
|
34
|
-
return runtime ? runtime.runPromise(effect) : Effect.runPromise(effect)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Run an effect as a Promise using the current managed runtime's context.
|
|
39
|
-
* The runtime must be initialized via `createLotaRuntime()` before any call.
|
|
40
|
-
*/
|
|
41
|
-
export function runPromise<A, E, R>(
|
|
42
|
-
effect: Effect.Effect<A, E, R>,
|
|
43
|
-
options?: { readonly signal?: AbortSignal },
|
|
44
|
-
): Promise<A> {
|
|
45
|
-
return getCurrentRuntime().runPromise(effect, options)
|
|
46
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type IORedis from 'ioredis'
|
|
2
|
-
|
|
3
|
-
import { resolveLotaService } from '../effect/runtime'
|
|
4
|
-
import { RedisServiceTag } from '../effect/services'
|
|
5
|
-
import type { RedisConnectionManager } from './connection'
|
|
6
|
-
|
|
7
|
-
let currentRedisManager: RedisConnectionManager | null = null
|
|
8
|
-
|
|
9
|
-
export function configureRuntimeRedisManager(redisManager: RedisConnectionManager): void {
|
|
10
|
-
currentRedisManager = redisManager
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function clearRuntimeRedisManager(): void {
|
|
14
|
-
currentRedisManager = null
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function getRuntimeRedisConnection(): IORedis {
|
|
18
|
-
const redis = currentRedisManager ?? resolveLotaService(RedisServiceTag)
|
|
19
|
-
return redis.getConnection()
|
|
20
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Installs and tears down the SDK's module-level runtime accessors.
|
|
3
|
-
*
|
|
4
|
-
* Several SDK modules expose `configure*`/`clear*` pairs so host code can read
|
|
5
|
-
* runtime-resolved services synchronously (AI gateway, agent defaults,
|
|
6
|
-
* firecrawl, graph designer, queue jobs, runtime extensions, redis, thread
|
|
7
|
-
* defaults). `createLotaRuntime` wires them once at boot and clears them on
|
|
8
|
-
* disconnect; this module keeps both phases in a single place so they stay
|
|
9
|
-
* symmetric.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import type { Context, ManagedRuntime } from 'effect'
|
|
13
|
-
import { Effect } from 'effect'
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
AiGatewayTag,
|
|
17
|
-
clearAiGatewayRuntimeAccessors,
|
|
18
|
-
configureAiGatewayRuntimeAccessors,
|
|
19
|
-
} from '../ai-gateway/ai-gateway'
|
|
20
|
-
import { clearAgentRuntimeDefaults, configureAgentRuntimeDefaults } from '../config/agent-defaults'
|
|
21
|
-
import { clearThreadRuntimeDefaults, configureThreadRuntimeDefaults } from '../config/thread-defaults'
|
|
22
|
-
import {
|
|
23
|
-
AgentConfigServiceTag,
|
|
24
|
-
AgentFactoryServiceTag,
|
|
25
|
-
RuntimeAdaptersServiceTag,
|
|
26
|
-
RuntimeWorkerExtensionsServiceTag,
|
|
27
|
-
ThreadConfigServiceTag,
|
|
28
|
-
ToolProvidersServiceTag,
|
|
29
|
-
TurnHooksServiceTag,
|
|
30
|
-
} from '../effect'
|
|
31
|
-
import type { RedisConnectionManager } from '../redis/connection'
|
|
32
|
-
import { clearRuntimeRedisManager, configureRuntimeRedisManager } from '../redis/runtime-connection'
|
|
33
|
-
import { QueueJobServiceTag } from '../services/queue-job.service'
|
|
34
|
-
import { FirecrawlTag, clearFirecrawlClient, configureFirecrawlClient } from '../tools/firecrawl-client'
|
|
35
|
-
import { clearQueueJobService, configureQueueJobService } from '../workers/worker-utils'
|
|
36
|
-
import { clearGraphDesigner, configureGraphDesigner } from './graph-designer'
|
|
37
|
-
import type { ResolvedLotaRuntimeConfig } from './runtime-config'
|
|
38
|
-
import { clearRuntimeExtensionsAccessors, configureRuntimeExtensionsAccessors } from './runtime-extensions'
|
|
39
|
-
|
|
40
|
-
// eslint-disable-next-line typescript-eslint/no-explicit-any -- ManagedRuntime is contravariant in R; `any` is the only valid wildcard
|
|
41
|
-
type SdkManagedRuntime = ManagedRuntime.ManagedRuntime<any, any>
|
|
42
|
-
|
|
43
|
-
interface ConfigureRuntimeAccessorsInput {
|
|
44
|
-
managedRuntime: SdkManagedRuntime
|
|
45
|
-
runtimeConfig: ResolvedLotaRuntimeConfig
|
|
46
|
-
redisManager: RedisConnectionManager
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Resolve every service the SDK exposes through module-level accessors and
|
|
51
|
-
* install them. Must be called after `setLotaSdkRuntime(managedRuntime)`.
|
|
52
|
-
*/
|
|
53
|
-
export function configureRuntimeModuleAccessors(input: ConfigureRuntimeAccessorsInput): void {
|
|
54
|
-
const { managedRuntime, runtimeConfig, redisManager } = input
|
|
55
|
-
const resolve = <I, T>(tag: Context.Key<I, T>): T =>
|
|
56
|
-
// We know every tag is provided by the managed runtime; the cast bridges
|
|
57
|
-
// the erased service-set carried by `SdkManagedRuntime`.
|
|
58
|
-
managedRuntime.runSync(Effect.service(tag) as Effect.Effect<T, never, never>)
|
|
59
|
-
|
|
60
|
-
configureAiGatewayRuntimeAccessors({ aiGateway: resolve(AiGatewayTag), runtimeConfig })
|
|
61
|
-
configureAgentRuntimeDefaults({
|
|
62
|
-
agentConfig: resolve(AgentConfigServiceTag),
|
|
63
|
-
agentFactoryConfig: resolve(AgentFactoryServiceTag),
|
|
64
|
-
})
|
|
65
|
-
configureThreadRuntimeDefaults(resolve(ThreadConfigServiceTag))
|
|
66
|
-
configureRuntimeExtensionsAccessors({
|
|
67
|
-
adapters: resolve(RuntimeAdaptersServiceTag),
|
|
68
|
-
turnHooks: resolve(TurnHooksServiceTag),
|
|
69
|
-
toolProviders: resolve(ToolProvidersServiceTag),
|
|
70
|
-
extraWorkers: resolve(RuntimeWorkerExtensionsServiceTag),
|
|
71
|
-
})
|
|
72
|
-
configureFirecrawlClient(resolve(FirecrawlTag))
|
|
73
|
-
configureQueueJobService(resolve(QueueJobServiceTag))
|
|
74
|
-
configureRuntimeRedisManager(redisManager)
|
|
75
|
-
configureGraphDesigner(runtimeConfig.graphDesigner)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Clears every module-level accessor installed by
|
|
80
|
-
* `configureRuntimeModuleAccessors`. Always safe to call (idempotent per clear
|
|
81
|
-
* function).
|
|
82
|
-
*/
|
|
83
|
-
export function clearRuntimeModuleAccessors(): void {
|
|
84
|
-
clearAiGatewayRuntimeAccessors()
|
|
85
|
-
clearAgentRuntimeDefaults()
|
|
86
|
-
clearFirecrawlClient()
|
|
87
|
-
clearGraphDesigner()
|
|
88
|
-
clearQueueJobService()
|
|
89
|
-
clearRuntimeExtensionsAccessors()
|
|
90
|
-
clearRuntimeRedisManager()
|
|
91
|
-
clearThreadRuntimeDefaults()
|
|
92
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Single-slot runtime token. `createLotaRuntime()` claims the slot on success
|
|
3
|
-
* and releases it on disconnect, enforcing the "one runtime per process"
|
|
4
|
-
* invariant. Kept as a small, typed module so the guard is trivially testable
|
|
5
|
-
* and stays out of the main entrypoint.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { Effect } from 'effect'
|
|
9
|
-
|
|
10
|
-
import { ConfigurationError } from '../effect/errors'
|
|
11
|
-
|
|
12
|
-
let activeToken: symbol | null = null
|
|
13
|
-
|
|
14
|
-
function buildConflictError(): ConfigurationError {
|
|
15
|
-
return new ConfigurationError({
|
|
16
|
-
message: 'createLotaRuntime() is process-scoped. Disconnect the active runtime before creating another one.',
|
|
17
|
-
})
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Claim the process-wide runtime slot. Fails with `ConfigurationError` if it
|
|
22
|
-
* is already held. Preferred inside `Effect.gen` so the failure is expressed
|
|
23
|
-
* through the typed error channel instead of a thrown value.
|
|
24
|
-
*/
|
|
25
|
-
export function acquireRuntimeTokenEffect(): Effect.Effect<symbol, ConfigurationError> {
|
|
26
|
-
return Effect.suspend(() => {
|
|
27
|
-
if (activeToken) {
|
|
28
|
-
return Effect.fail(buildConflictError())
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const token = Symbol('lota-runtime')
|
|
32
|
-
activeToken = token
|
|
33
|
-
return Effect.succeed(token)
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Release the slot only if the caller holds the current token. */
|
|
38
|
-
export function releaseRuntimeToken(token: symbol): void {
|
|
39
|
-
if (activeToken === token) {
|
|
40
|
-
activeToken = null
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Diagnostic: whether a runtime is currently active in this process. */
|
|
45
|
-
export function isRuntimeTokenActive(): boolean {
|
|
46
|
-
return activeToken !== null
|
|
47
|
-
}
|