@lota-sdk/core 0.4.9 → 0.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/ai/embedding-cache.ts +3 -1
- package/src/ai-gateway/ai-gateway.ts +38 -10
- package/src/config/agent-defaults.ts +22 -9
- package/src/config/agent-types.ts +1 -1
- package/src/config/background-processing.ts +1 -1
- package/src/config/index.ts +0 -1
- package/src/config/logger.ts +20 -7
- package/src/config/thread-defaults.ts +12 -4
- package/src/create-runtime.ts +69 -656
- package/src/db/memory-query-builder.ts +2 -1
- package/src/db/memory-store.ts +29 -20
- package/src/db/memory.ts +188 -195
- package/src/db/service-normalization.ts +97 -64
- package/src/db/service.ts +706 -538
- package/src/db/startup.ts +30 -19
- package/src/effect/awaitable-effect.ts +46 -37
- package/src/effect/helpers.ts +30 -5
- package/src/effect/index.ts +7 -5
- package/src/effect/layers.ts +82 -72
- package/src/effect/runtime.ts +18 -3
- package/src/effect/services.ts +15 -11
- package/src/embeddings/provider.ts +65 -66
- package/src/index.ts +13 -11
- package/src/queues/autonomous-job.queue.ts +59 -71
- package/src/queues/context-compaction.queue.ts +6 -18
- package/src/queues/delayed-node-promotion.queue.ts +9 -17
- package/src/queues/organization-learning.queue.ts +17 -4
- package/src/queues/plan-agent-heartbeat.queue.ts +23 -20
- package/src/queues/plan-scheduler.queue.ts +6 -18
- package/src/queues/post-chat-memory.queue.ts +6 -18
- package/src/queues/queue-factory.ts +128 -50
- package/src/queues/title-generation.queue.ts +6 -17
- package/src/redis/connection.ts +181 -164
- package/src/redis/runtime-connection.ts +13 -3
- package/src/redis/stream-context.ts +17 -9
- package/src/runtime/agent-runtime-policy.ts +1 -1
- package/src/runtime/agent-stream-helpers.ts +15 -11
- package/src/runtime/chat-run-orchestration.ts +1 -1
- package/src/runtime/context-compaction/context-compaction-runtime.ts +1 -1
- package/src/runtime/context-compaction/context-compaction.ts +126 -82
- package/src/runtime/domain-layer.ts +192 -0
- package/src/runtime/graph-designer.ts +15 -7
- package/src/runtime/helper-model.ts +8 -4
- package/src/runtime/index.ts +0 -1
- package/src/runtime/memory/memory-block.ts +19 -9
- package/src/runtime/memory/memory-pipeline.ts +53 -66
- package/src/runtime/memory/memory-scope.ts +33 -29
- package/src/runtime/plugin-resolution.ts +33 -54
- package/src/runtime/post-turn-side-effects.ts +6 -26
- package/src/runtime/retrieval-adapters.ts +4 -4
- package/src/runtime/runtime-accessors.ts +92 -0
- package/src/runtime/runtime-config.ts +3 -3
- package/src/runtime/runtime-extensions.ts +20 -9
- package/src/runtime/runtime-lifecycle.ts +124 -0
- package/src/runtime/runtime-services.ts +386 -0
- package/src/runtime/runtime-token.ts +47 -0
- package/src/runtime/social-chat/social-chat-agent-runner.ts +7 -5
- package/src/runtime/social-chat/social-chat-history.ts +21 -12
- package/src/runtime/social-chat/social-chat.ts +401 -365
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +58 -52
- package/src/runtime/thread-turn-context.ts +21 -27
- package/src/services/agent-activity.service.ts +1 -1
- package/src/services/agent-executor.service.ts +179 -187
- package/src/services/artifact.service.ts +10 -5
- package/src/services/attachment.service.ts +35 -1
- package/src/services/autonomous-job.service.ts +58 -56
- package/src/services/background-work.service.ts +54 -0
- package/src/services/chat-run-registry.service.ts +3 -1
- package/src/services/context-compaction.service.ts +1 -1
- package/src/services/document-chunk.service.ts +8 -17
- package/src/services/execution-plan/execution-plan-graph.ts +74 -52
- package/src/services/execution-plan/execution-plan.service.ts +1 -1
- package/src/services/feedback-loop.service.ts +1 -1
- package/src/services/global-orchestrator.service.ts +33 -10
- package/src/services/graph-full-routing.ts +44 -33
- package/src/services/index.ts +1 -0
- package/src/services/institutional-memory.service.ts +8 -17
- package/src/services/learned-skill.service.ts +38 -35
- package/src/services/memory/memory-errors.ts +27 -0
- package/src/services/memory/memory-org-memory.ts +14 -3
- package/src/services/memory/memory-preseeded.ts +10 -4
- package/src/services/memory/memory-utils.ts +2 -1
- package/src/services/memory/memory.service.ts +26 -44
- package/src/services/memory/rerank.service.ts +3 -11
- package/src/services/monitoring-window.service.ts +1 -1
- package/src/services/mutating-approval.service.ts +1 -1
- package/src/services/node-workspace.service.ts +2 -2
- package/src/services/notification.service.ts +16 -4
- package/src/services/organization-member.service.ts +1 -1
- package/src/services/organization.service.ts +34 -51
- package/src/services/ownership-dispatcher.service.ts +132 -90
- package/src/services/plan/plan-agent-heartbeat.service.ts +1 -1
- package/src/services/plan/plan-agent-query.service.ts +1 -1
- package/src/services/plan/plan-approval.service.ts +52 -48
- package/src/services/plan/plan-artifact.service.ts +2 -2
- package/src/services/plan/plan-builder.service.ts +2 -2
- package/src/services/plan/plan-checkpoint.service.ts +1 -1
- package/src/services/plan/plan-compiler.service.ts +1 -1
- package/src/services/plan/plan-completion-side-effects.ts +18 -24
- package/src/services/plan/plan-coordination.service.ts +1 -1
- package/src/services/plan/plan-cycle.service.ts +171 -164
- package/src/services/plan/plan-deadline.service.ts +290 -304
- package/src/services/plan/plan-event-delivery.service.ts +44 -39
- package/src/services/plan/plan-executor-graph.ts +114 -67
- package/src/services/plan/plan-executor-helpers.ts +60 -75
- package/src/services/plan/plan-executor.service.ts +550 -467
- package/src/services/plan/plan-run.service.ts +12 -19
- package/src/services/plan/plan-scheduler.service.ts +27 -33
- package/src/services/plan/plan-template.service.ts +1 -1
- package/src/services/plan/plan-transaction-events.ts +8 -5
- package/src/services/plan/plan-validator.service.ts +1 -1
- package/src/services/plan/plan-workspace.service.ts +17 -11
- package/src/services/plugin-executor.service.ts +26 -21
- package/src/services/quality-metrics.service.ts +1 -1
- package/src/services/queue-job.service.ts +8 -17
- package/src/services/recent-activity-title.service.ts +17 -9
- package/src/services/recent-activity.service.ts +1 -1
- package/src/services/skill-resolver.service.ts +1 -1
- package/src/services/social-chat-history.service.ts +37 -20
- package/src/services/system-executor.service.ts +25 -20
- package/src/services/thread/thread-bootstrap.ts +26 -10
- package/src/services/thread/thread-listing.ts +2 -1
- package/src/services/thread/thread-memory-block.ts +18 -5
- package/src/services/thread/thread-message.service.ts +24 -8
- package/src/services/thread/thread-title.service.ts +1 -1
- package/src/services/thread/thread-turn-execution.ts +1 -1
- package/src/services/thread/thread-turn-preparation.service.ts +18 -16
- package/src/services/thread/thread-turn-streaming.ts +12 -11
- package/src/services/thread/thread-turn.ts +43 -10
- package/src/services/thread/thread.service.ts +11 -2
- package/src/services/user.service.ts +1 -1
- package/src/services/write-intent-validator.service.ts +1 -1
- package/src/storage/attachment-storage.service.ts +7 -4
- package/src/storage/generated-document-storage.service.ts +1 -1
- package/src/system-agents/context-compaction.agent.ts +1 -1
- package/src/system-agents/helper-agent-options.ts +1 -1
- package/src/system-agents/memory-reranker.agent.ts +1 -1
- package/src/system-agents/memory.agent.ts +1 -1
- package/src/system-agents/recent-activity-title-refiner.agent.ts +1 -1
- package/src/system-agents/regular-chat-memory-digest.agent.ts +1 -1
- package/src/system-agents/skill-extractor.agent.ts +1 -1
- package/src/system-agents/skill-manager.agent.ts +1 -1
- package/src/system-agents/title-generator.agent.ts +1 -1
- package/src/tools/execution-plan.tool.ts +28 -17
- package/src/tools/fetch-webpage.tool.ts +20 -13
- package/src/tools/firecrawl-client.ts +13 -3
- package/src/tools/plan-approval.tool.ts +9 -1
- package/src/tools/search-web.tool.ts +16 -9
- package/src/tools/team-think.tool.ts +2 -2
- package/src/utils/async.ts +15 -6
- package/src/utils/errors.ts +27 -15
- package/src/workers/bootstrap.ts +25 -48
- package/src/workers/organization-learning.worker.ts +1 -1
- package/src/workers/regular-chat-memory-digest.runner.ts +25 -15
- package/src/workers/worker-utils.ts +20 -2
- package/src/config/search.ts +0 -3
- package/src/runtime/agent-types.ts +0 -1
|
@@ -17,6 +17,7 @@ import { ensureRecordId } from '../db/record-id'
|
|
|
17
17
|
import type { SurrealDBService } from '../db/service'
|
|
18
18
|
import { TABLES } from '../db/tables'
|
|
19
19
|
import { BadRequestError, NotFoundError } from '../effect/errors'
|
|
20
|
+
import { makeEffectTryPromiseWithOperation } from '../effect/helpers'
|
|
20
21
|
import { runPromise } from '../effect/runtime'
|
|
21
22
|
import { DatabaseServiceTag } from '../effect/services'
|
|
22
23
|
import { toValidationError } from '../effect/zod'
|
|
@@ -112,27 +113,15 @@ class AgentExecutorError extends Schema.TaggedErrorClass<AgentExecutorError>()('
|
|
|
112
113
|
cause: Schema.Defect,
|
|
113
114
|
}) {}
|
|
114
115
|
|
|
115
|
-
|
|
116
|
+
const tryAgentExecutorPromise = makeEffectTryPromiseWithOperation(
|
|
117
|
+
(operation, message, cause) => new AgentExecutorError({ operation, message, cause }),
|
|
118
|
+
)
|
|
119
|
+
const tryAgentExecutorTask = <A>(
|
|
116
120
|
operation: string,
|
|
117
121
|
message: string,
|
|
118
|
-
|
|
119
|
-
): Effect.Effect<A, AgentExecutorError>
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
const value = thunk()
|
|
123
|
-
if (Effect.isEffect(value)) {
|
|
124
|
-
return value.pipe(Effect.mapError((cause) => new AgentExecutorError({ operation, message, cause })))
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return Effect.tryPromise({
|
|
128
|
-
try: () => Promise.resolve(value),
|
|
129
|
-
catch: (cause) => new AgentExecutorError({ operation, message, cause }),
|
|
130
|
-
})
|
|
131
|
-
} catch (cause) {
|
|
132
|
-
return Effect.fail(new AgentExecutorError({ operation, message, cause }))
|
|
133
|
-
}
|
|
134
|
-
})
|
|
135
|
-
}
|
|
122
|
+
task: () => PromiseLike<A>,
|
|
123
|
+
): Effect.Effect<A, AgentExecutorError> =>
|
|
124
|
+
Effect.tryPromise({ try: task, catch: (cause) => new AgentExecutorError({ operation, message, cause }) })
|
|
136
125
|
|
|
137
126
|
function isAgentExecutorOwner(
|
|
138
127
|
owner: PlanNodeSpec['owner'],
|
|
@@ -190,7 +179,7 @@ function buildWriteIntentTool(params: {
|
|
|
190
179
|
}
|
|
191
180
|
|
|
192
181
|
function createExecuteNode(deps: AgentExecutorDeps) {
|
|
193
|
-
return function
|
|
182
|
+
return Effect.fn('AgentExecutor.executeNode')(function* (params: {
|
|
194
183
|
nodeSpec: PlanNodeSpec
|
|
195
184
|
resolvedInput: Record<string, unknown>
|
|
196
185
|
inputArtifacts: PlanArtifactSubmission[]
|
|
@@ -198,70 +187,70 @@ function createExecuteNode(deps: AgentExecutorDeps) {
|
|
|
198
187
|
executionMode?: ExecutionMode
|
|
199
188
|
schemaRegistry?: PlanSchemaRegistry
|
|
200
189
|
}) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
message: `AgentExecutor cannot execute owner type "${owner.executorType}".`,
|
|
206
|
-
})
|
|
207
|
-
}
|
|
190
|
+
const owner = params.nodeSpec.owner
|
|
191
|
+
if (!isAgentExecutorOwner(owner)) {
|
|
192
|
+
return yield* new BadRequestError({ message: `AgentExecutor cannot execute owner type "${owner.executorType}".` })
|
|
193
|
+
}
|
|
208
194
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
195
|
+
const agentId = owner.ref
|
|
196
|
+
if (!getAgentRoster().includes(agentId)) {
|
|
197
|
+
return yield* new BadRequestError({ message: `Agent executor "${agentId}" is not registered.` })
|
|
198
|
+
}
|
|
213
199
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
200
|
+
const thread = yield* tryAgentExecutorPromise('load-thread', 'Failed to load dispatched thread.', () =>
|
|
201
|
+
deps.db.findOne(TABLES.THREAD, { id: ensureRecordId(params.context.threadId, TABLES.THREAD) }, ThreadSchema),
|
|
202
|
+
).pipe(Effect.withSpan('AgentExecutor.loadThread'))
|
|
203
|
+
if (!thread) {
|
|
204
|
+
return yield* new NotFoundError({
|
|
205
|
+
resource: TABLES.THREAD,
|
|
206
|
+
message: `Thread ${params.context.threadId} not found for dispatched execution.`,
|
|
207
|
+
})
|
|
208
|
+
}
|
|
223
209
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
210
|
+
const organizationRef = ensureRecordId(params.context.organizationId, TABLES.ORGANIZATION)
|
|
211
|
+
const threadRef = ensureRecordId(params.context.threadId, TABLES.THREAD)
|
|
212
|
+
const userRefSource = params.context.userId ?? thread.userId
|
|
213
|
+
if (!userRefSource) {
|
|
214
|
+
return yield* new BadRequestError({
|
|
215
|
+
message: `Thread ${params.context.threadId} is missing a user context for dispatched execution.`,
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
const userRef = ensureRecordId(userRefSource, TABLES.USER)
|
|
219
|
+
const userName = params.context.userName ?? 'User'
|
|
220
|
+
const { linearInstallation, githubInstallation, indexedRepoContext } = yield* Effect.all({
|
|
221
|
+
linearInstallation: tryAgentExecutorTask(
|
|
222
|
+
'get-linear-installation',
|
|
223
|
+
`Failed to load Linear installation for org ${params.context.organizationId}.`,
|
|
224
|
+
() => getLinearInstallationByOrgId(organizationRef),
|
|
225
|
+
),
|
|
226
|
+
githubInstallation: tryAgentExecutorTask(
|
|
227
|
+
'get-github-installation',
|
|
228
|
+
`Failed to load GitHub installation for org ${params.context.organizationId}.`,
|
|
229
|
+
() => getGithubInstallationForOrganization(params.context.organizationId),
|
|
230
|
+
),
|
|
231
|
+
indexedRepoContext: tryAgentExecutorTask(
|
|
232
|
+
'build-indexed-repositories-context',
|
|
233
|
+
`Failed to build indexed repository context for org ${params.context.organizationId}.`,
|
|
234
|
+
() => buildIndexedRepositoriesContext(params.context.organizationId),
|
|
235
|
+
),
|
|
236
|
+
}).pipe(Effect.withSpan('AgentExecutor.loadInstallations'))
|
|
237
|
+
|
|
238
|
+
const mode = params.executionMode ?? 'linear'
|
|
239
|
+
const dispatchMode = thread.type === 'group' ? 'fixedThreadMode' : 'direct'
|
|
240
|
+
const dispatchInstructionSections = [
|
|
241
|
+
buildOwnershipDispatchContextSection({
|
|
242
|
+
node: params.nodeSpec,
|
|
243
|
+
resolvedInput: params.resolvedInput,
|
|
244
|
+
inputArtifacts: params.inputArtifacts,
|
|
245
|
+
upstreamHandoffs: params.context.upstreamHandoffs,
|
|
246
|
+
}),
|
|
247
|
+
]
|
|
262
248
|
|
|
263
|
-
|
|
264
|
-
|
|
249
|
+
const turnHooks = getTurnHooks()
|
|
250
|
+
const agentResolutionValue = yield* tryAgentExecutorPromise(
|
|
251
|
+
'resolve-agent',
|
|
252
|
+
`Failed to resolve agent "${agentId}" for dispatched execution.`,
|
|
253
|
+
() =>
|
|
265
254
|
Promise.resolve(
|
|
266
255
|
turnHooks.resolveAgent?.({
|
|
267
256
|
agentId,
|
|
@@ -278,133 +267,136 @@ function createExecuteNode(deps: AgentExecutorDeps) {
|
|
|
278
267
|
context: null,
|
|
279
268
|
}),
|
|
280
269
|
),
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const agentFactoryConfig = getResolvedAgentFactoryConfig()
|
|
298
|
-
const rawTools = yield* tryAgentExecutorPromise(
|
|
299
|
-
'build-agent-tools',
|
|
300
|
-
`Failed to build agent tools for "${resolvedAgentId}".`,
|
|
301
|
-
() =>
|
|
302
|
-
Promise.resolve(
|
|
303
|
-
agentFactoryConfig.buildAgentTools({
|
|
304
|
-
agentId: resolvedAgentId,
|
|
305
|
-
orgId: organizationRef,
|
|
306
|
-
userId: userRef,
|
|
307
|
-
userName,
|
|
308
|
-
threadId: threadRef,
|
|
309
|
-
orgIdString: params.context.organizationId,
|
|
310
|
-
threadType: thread.type,
|
|
311
|
-
mode: dispatchMode,
|
|
312
|
-
linearInstalled: Boolean(linearInstallation),
|
|
313
|
-
onboardingActive: false,
|
|
314
|
-
githubInstalled: Boolean(githubInstallation),
|
|
315
|
-
provideRepoTool: indexedRepoContext.provideRepoTool,
|
|
316
|
-
defaultRepoSections: indexedRepoContext.defaultSectionsByAgent[resolvedAgentId],
|
|
317
|
-
memoryBlock: '',
|
|
318
|
-
onAppendMemoryBlock: () => undefined,
|
|
319
|
-
availableUploads: [],
|
|
320
|
-
includeExecutionPlanTools: false,
|
|
321
|
-
}),
|
|
322
|
-
),
|
|
323
|
-
)
|
|
324
|
-
const tools = applyToolPolicy(rawTools, params.nodeSpec)
|
|
270
|
+
)
|
|
271
|
+
const agentResolution = isRecord(agentResolutionValue) ? agentResolutionValue : null
|
|
272
|
+
const resolvedAgentId = readOptionalString(agentResolution?.agentId) ?? agentId
|
|
273
|
+
const runtimeConfig = getAgentRuntimeConfig({
|
|
274
|
+
agentId: resolvedAgentId,
|
|
275
|
+
threadType: thread.type,
|
|
276
|
+
mode: dispatchMode,
|
|
277
|
+
onboardingActive: false,
|
|
278
|
+
linearInstalled: Boolean(linearInstallation),
|
|
279
|
+
additionalInstructionSections: mergeInstructionSections(
|
|
280
|
+
dispatchInstructionSections,
|
|
281
|
+
readInstructionSections(agentResolution?.additionalInstructionSections),
|
|
282
|
+
),
|
|
283
|
+
responseGuardSection: buildOwnershipDispatchResponseGuard({ node: params.nodeSpec, executionMode: mode }),
|
|
284
|
+
})
|
|
325
285
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
286
|
+
const agentFactoryConfig = getResolvedAgentFactoryConfig()
|
|
287
|
+
const rawTools = yield* tryAgentExecutorPromise(
|
|
288
|
+
'build-agent-tools',
|
|
289
|
+
`Failed to build agent tools for "${resolvedAgentId}".`,
|
|
290
|
+
() =>
|
|
291
|
+
Promise.resolve(
|
|
292
|
+
agentFactoryConfig.buildAgentTools({
|
|
293
|
+
agentId: resolvedAgentId,
|
|
294
|
+
orgId: organizationRef,
|
|
295
|
+
userId: userRef,
|
|
296
|
+
userName,
|
|
297
|
+
threadId: threadRef,
|
|
298
|
+
orgIdString: params.context.organizationId,
|
|
299
|
+
threadType: thread.type,
|
|
300
|
+
mode: dispatchMode,
|
|
301
|
+
linearInstalled: Boolean(linearInstallation),
|
|
302
|
+
onboardingActive: false,
|
|
303
|
+
githubInstalled: Boolean(githubInstallation),
|
|
304
|
+
provideRepoTool: indexedRepoContext.provideRepoTool,
|
|
305
|
+
defaultRepoSections: indexedRepoContext.defaultSectionsByAgent[resolvedAgentId],
|
|
306
|
+
memoryBlock: '',
|
|
307
|
+
onAppendMemoryBlock: () => undefined,
|
|
308
|
+
availableUploads: [],
|
|
309
|
+
includeExecutionPlanTools: false,
|
|
310
|
+
}),
|
|
311
|
+
),
|
|
312
|
+
)
|
|
313
|
+
const tools = applyToolPolicy(rawTools, params.nodeSpec)
|
|
330
314
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
mode: dispatchMode,
|
|
336
|
-
tools,
|
|
337
|
-
extraInstructions:
|
|
338
|
-
typeof runtimeConfig.extraInstructions === 'string' ? runtimeConfig.extraInstructions : undefined,
|
|
339
|
-
maxRetries: 1,
|
|
340
|
-
stopWhen: [stepCountIs(maxSteps)],
|
|
341
|
-
})
|
|
342
|
-
|
|
343
|
-
const result = yield* tryAgentExecutorPromise(
|
|
344
|
-
'generate-agent-dispatch',
|
|
345
|
-
`Agent "${resolvedAgentId}" failed to generate a dispatch result.`,
|
|
346
|
-
() => agent.generate({ prompt: buildDispatchPrompt(params.nodeSpec) }),
|
|
347
|
-
)
|
|
348
|
-
const outputCandidate = PlanNodeResultSubmissionSchema.safeParse(result.output)
|
|
349
|
-
if (outputCandidate.success) {
|
|
350
|
-
return outputCandidate.data
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
return yield* toValidationError(
|
|
354
|
-
outputCandidate.error,
|
|
355
|
-
`Agent executor "${agentId}" returned an invalid node result`,
|
|
356
|
-
)
|
|
357
|
-
}
|
|
315
|
+
const agentFactory = agentFactoryConfig.createAgent[resolvedAgentId]
|
|
316
|
+
if (!agentFactory) {
|
|
317
|
+
return yield* new BadRequestError({ message: `Agent factory "${resolvedAgentId}" is not registered.` })
|
|
318
|
+
}
|
|
358
319
|
|
|
359
|
-
|
|
360
|
-
nodeSpec: params.nodeSpec,
|
|
361
|
-
resolvedInput: params.resolvedInput,
|
|
362
|
-
inputArtifacts: params.inputArtifacts,
|
|
363
|
-
schemaRegistry: params.schemaRegistry ?? {},
|
|
364
|
-
})
|
|
320
|
+
const maxSteps = typeof runtimeConfig.maxSteps === 'number' ? runtimeConfig.maxSteps : 8
|
|
365
321
|
|
|
366
|
-
|
|
367
|
-
...tools,
|
|
368
|
-
writeIntent: buildWriteIntentTool({
|
|
369
|
-
nodeSpec: params.nodeSpec,
|
|
370
|
-
workspace,
|
|
371
|
-
writeIntentValidatorService: deps.writeIntentValidatorService,
|
|
372
|
-
stageWrite: (intent) => deps.nodeWorkspaceService.stageWrite(workspace, intent, 'validated'),
|
|
373
|
-
}),
|
|
374
|
-
}
|
|
322
|
+
if (mode === 'linear') {
|
|
375
323
|
const agent = agentFactory({
|
|
376
324
|
mode: dispatchMode,
|
|
377
|
-
tools
|
|
325
|
+
tools,
|
|
378
326
|
extraInstructions:
|
|
379
327
|
typeof runtimeConfig.extraInstructions === 'string' ? runtimeConfig.extraInstructions : undefined,
|
|
380
328
|
maxRetries: 1,
|
|
381
329
|
stopWhen: [stepCountIs(maxSteps)],
|
|
382
330
|
})
|
|
383
331
|
|
|
384
|
-
|
|
332
|
+
const result = yield* tryAgentExecutorPromise(
|
|
333
|
+
'generate-agent-dispatch',
|
|
334
|
+
`Agent "${resolvedAgentId}" failed to generate a dispatch result.`,
|
|
335
|
+
() => agent.generate({ prompt: buildDispatchPrompt(params.nodeSpec) }),
|
|
336
|
+
).pipe(Effect.withSpan('AgentExecutor.generateLinearDispatch'))
|
|
337
|
+
const outputCandidate = PlanNodeResultSubmissionSchema.safeParse(result.output)
|
|
338
|
+
if (outputCandidate.success) {
|
|
339
|
+
return outputCandidate.data
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return yield* toValidationError(
|
|
343
|
+
outputCandidate.error,
|
|
344
|
+
`Agent executor "${agentId}" returned an invalid node result`,
|
|
345
|
+
)
|
|
346
|
+
}
|
|
385
347
|
|
|
386
|
-
|
|
348
|
+
const workspace = deps.nodeWorkspaceService.initialize({
|
|
349
|
+
nodeSpec: params.nodeSpec,
|
|
350
|
+
resolvedInput: params.resolvedInput,
|
|
351
|
+
inputArtifacts: params.inputArtifacts,
|
|
352
|
+
schemaRegistry: params.schemaRegistry ?? {},
|
|
353
|
+
})
|
|
387
354
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
deps.nodeWorkspaceService.
|
|
395
|
-
|
|
396
|
-
|
|
355
|
+
const graphTools = {
|
|
356
|
+
...tools,
|
|
357
|
+
writeIntent: buildWriteIntentTool({
|
|
358
|
+
nodeSpec: params.nodeSpec,
|
|
359
|
+
workspace,
|
|
360
|
+
writeIntentValidatorService: deps.writeIntentValidatorService,
|
|
361
|
+
stageWrite: (intent) => deps.nodeWorkspaceService.stageWrite(workspace, intent, 'validated'),
|
|
362
|
+
}),
|
|
363
|
+
}
|
|
364
|
+
const agent = agentFactory({
|
|
365
|
+
mode: dispatchMode,
|
|
366
|
+
tools: graphTools,
|
|
367
|
+
extraInstructions:
|
|
368
|
+
typeof runtimeConfig.extraInstructions === 'string' ? runtimeConfig.extraInstructions : undefined,
|
|
369
|
+
maxRetries: 1,
|
|
370
|
+
stopWhen: [stepCountIs(maxSteps)],
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
yield* tryAgentExecutorPromise(
|
|
374
|
+
'generate-write-intent-dispatch',
|
|
375
|
+
`Agent "${resolvedAgentId}" failed to generate a write-intent dispatch result.`,
|
|
376
|
+
() => agent.generate({ prompt: buildWriteIntentDispatchPrompt(params.nodeSpec) }),
|
|
377
|
+
).pipe(Effect.withSpan('AgentExecutor.generateWriteIntentDispatch'))
|
|
397
378
|
|
|
379
|
+
const finalResult = yield* deps.nodeWorkspaceService.finalize(workspace)
|
|
380
|
+
|
|
381
|
+
if (!finalResult.isComplete) {
|
|
398
382
|
const result: PlanNodeResult = {
|
|
399
383
|
structuredOutput: finalResult.structuredOutput,
|
|
400
384
|
artifacts: finalResult.artifacts,
|
|
401
|
-
notes:
|
|
385
|
+
notes: 'Execution incomplete: missing required deliverables or validation failures.',
|
|
402
386
|
}
|
|
403
|
-
|
|
404
387
|
deps.nodeWorkspaceService.cleanup(workspace)
|
|
405
388
|
return result
|
|
406
|
-
}
|
|
407
|
-
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const result: PlanNodeResult = {
|
|
392
|
+
structuredOutput: finalResult.structuredOutput,
|
|
393
|
+
artifacts: finalResult.artifacts,
|
|
394
|
+
notes: finalResult.notes,
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
deps.nodeWorkspaceService.cleanup(workspace)
|
|
398
|
+
return result
|
|
399
|
+
})
|
|
408
400
|
}
|
|
409
401
|
|
|
410
402
|
interface AgentExecutorDeps {
|
|
@@ -420,7 +412,7 @@ export function makeAgentExecutorService(deps: AgentExecutorDeps) {
|
|
|
420
412
|
export class AgentExecutorServiceTag extends Context.Service<
|
|
421
413
|
AgentExecutorServiceTag,
|
|
422
414
|
ReturnType<typeof makeAgentExecutorService>
|
|
423
|
-
>()('AgentExecutorService') {}
|
|
415
|
+
>()('@lota-sdk/core/AgentExecutorService') {}
|
|
424
416
|
|
|
425
417
|
export const AgentExecutorServiceLive = Layer.effect(
|
|
426
418
|
AgentExecutorServiceTag,
|
|
@@ -15,7 +15,7 @@ import type { SurrealDBService, DatabaseTransaction } from '../db/service'
|
|
|
15
15
|
import { TABLES } from '../db/tables'
|
|
16
16
|
import { ConfigurationError, DatabaseError, NotFoundError } from '../effect/errors'
|
|
17
17
|
import { DatabaseServiceTag } from '../effect/services'
|
|
18
|
-
import { toValidationError } from '../effect/zod'
|
|
18
|
+
import { toValidationError, zodParse } from '../effect/zod'
|
|
19
19
|
import type { makeGeneratedDocumentStorageService } from '../storage/generated-document-storage.service'
|
|
20
20
|
import { GeneratedDocumentStorageServiceTag } from '../storage/generated-document-storage.service'
|
|
21
21
|
import { sha256Hex } from '../utils/crypto'
|
|
@@ -180,7 +180,7 @@ export function makeArtifactService(deps: ArtifactServiceDeps) {
|
|
|
180
180
|
},
|
|
181
181
|
})
|
|
182
182
|
|
|
183
|
-
return ArtifactRecordSchema.array()
|
|
183
|
+
return yield* zodParse(ArtifactRecordSchema.array(), records)
|
|
184
184
|
})
|
|
185
185
|
|
|
186
186
|
const publishArtifactInTransactionEffect = (
|
|
@@ -247,7 +247,7 @@ export function makeArtifactService(deps: ArtifactServiceDeps) {
|
|
|
247
247
|
})
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
const created = ArtifactRecordSchema
|
|
250
|
+
const created = yield* zodParse(ArtifactRecordSchema, createdRecord)
|
|
251
251
|
|
|
252
252
|
const previousActive = existing.find((record) => record.status === 'active')
|
|
253
253
|
if (previousActive) {
|
|
@@ -392,7 +392,12 @@ export function makeArtifactService(deps: ArtifactServiceDeps) {
|
|
|
392
392
|
listBacklinksEffect(artifact),
|
|
393
393
|
])
|
|
394
394
|
|
|
395
|
-
return
|
|
395
|
+
return yield* zodParse(GetArtifactResultSchema, {
|
|
396
|
+
artifact,
|
|
397
|
+
content,
|
|
398
|
+
versions: versions.map(toVersionSummary),
|
|
399
|
+
backlinks,
|
|
400
|
+
})
|
|
396
401
|
})
|
|
397
402
|
|
|
398
403
|
const listBacklinksEffect = (artifact: Pick<ArtifactRecord, 'id' | 'organizationId'>) =>
|
|
@@ -439,7 +444,7 @@ export function makeArtifactService(deps: ArtifactServiceDeps) {
|
|
|
439
444
|
}
|
|
440
445
|
|
|
441
446
|
export class ArtifactServiceTag extends Context.Service<ArtifactServiceTag, ReturnType<typeof makeArtifactService>>()(
|
|
442
|
-
'ArtifactService',
|
|
447
|
+
'@lota-sdk/core/ArtifactService',
|
|
443
448
|
) {}
|
|
444
449
|
|
|
445
450
|
export const ArtifactServiceLive = Layer.effect(
|
|
@@ -67,6 +67,10 @@ export function makeAttachmentService(attachmentStorage: ReturnType<typeof makeA
|
|
|
67
67
|
return runPromise(attachmentStorage.extractStoredAttachmentText({ storageKey, name, contentType }))
|
|
68
68
|
},
|
|
69
69
|
|
|
70
|
+
extractStoredAttachmentTextEffect(params: { storageKey: string; name: string; contentType: string }) {
|
|
71
|
+
return attachmentStorage.extractStoredAttachmentText(params)
|
|
72
|
+
},
|
|
73
|
+
|
|
70
74
|
extractStoredAttachmentPages({
|
|
71
75
|
storageKey,
|
|
72
76
|
name,
|
|
@@ -79,6 +83,10 @@ export function makeAttachmentService(attachmentStorage: ReturnType<typeof makeA
|
|
|
79
83
|
return runPromise(attachmentStorage.extractStoredAttachmentPages({ storageKey, name, contentType }))
|
|
80
84
|
},
|
|
81
85
|
|
|
86
|
+
extractStoredAttachmentPagesEffect(params: { storageKey: string; name: string; contentType: string }) {
|
|
87
|
+
return attachmentStorage.extractStoredAttachmentPages(params)
|
|
88
|
+
},
|
|
89
|
+
|
|
82
90
|
readFilePartsFromUpload({
|
|
83
91
|
upload,
|
|
84
92
|
orgId,
|
|
@@ -129,6 +137,28 @@ export function makeAttachmentService(attachmentStorage: ReturnType<typeof makeA
|
|
|
129
137
|
)
|
|
130
138
|
},
|
|
131
139
|
|
|
140
|
+
writeOrganizationDocumentEffect({
|
|
141
|
+
orgId,
|
|
142
|
+
namespace,
|
|
143
|
+
relativePath,
|
|
144
|
+
content,
|
|
145
|
+
contentType,
|
|
146
|
+
}: {
|
|
147
|
+
orgId: RecordIdRef
|
|
148
|
+
namespace: string
|
|
149
|
+
relativePath: string
|
|
150
|
+
content: string
|
|
151
|
+
contentType: string
|
|
152
|
+
}) {
|
|
153
|
+
return attachmentStorage.writeOrganizationDocument({
|
|
154
|
+
orgId: toOrgId(orgId),
|
|
155
|
+
namespace,
|
|
156
|
+
relativePath,
|
|
157
|
+
content,
|
|
158
|
+
contentType,
|
|
159
|
+
})
|
|
160
|
+
},
|
|
161
|
+
|
|
132
162
|
uploadOrganizationDocument({
|
|
133
163
|
file,
|
|
134
164
|
orgId,
|
|
@@ -156,13 +186,17 @@ export function makeAttachmentService(attachmentStorage: ReturnType<typeof makeA
|
|
|
156
186
|
attachmentStorage.uploadThreadAttachment({ file, orgId: toOrgId(orgId), userId: toUserId(userId) }),
|
|
157
187
|
)
|
|
158
188
|
},
|
|
189
|
+
|
|
190
|
+
uploadThreadAttachmentEffect({ file, orgId, userId }: { file: File; orgId: RecordIdRef; userId: RecordIdRef }) {
|
|
191
|
+
return attachmentStorage.uploadThreadAttachment({ file, orgId: toOrgId(orgId), userId: toUserId(userId) })
|
|
192
|
+
},
|
|
159
193
|
}
|
|
160
194
|
}
|
|
161
195
|
|
|
162
196
|
export class AttachmentServiceTag extends Context.Service<
|
|
163
197
|
AttachmentServiceTag,
|
|
164
198
|
ReturnType<typeof makeAttachmentService>
|
|
165
|
-
>()('AttachmentService') {}
|
|
199
|
+
>()('@lota-sdk/core/AttachmentService') {}
|
|
166
200
|
|
|
167
201
|
export const AttachmentServiceLive = Layer.effect(
|
|
168
202
|
AttachmentServiceTag,
|