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