@lota-sdk/core 0.4.8 → 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 +11 -12
- package/src/ai/embedding-cache.ts +96 -22
- package/src/ai-gateway/ai-gateway.ts +766 -223
- package/src/config/agent-defaults.ts +189 -75
- package/src/config/agent-types.ts +54 -4
- package/src/config/background-processing.ts +1 -1
- package/src/config/constants.ts +8 -2
- package/src/config/index.ts +0 -1
- package/src/config/logger.ts +299 -19
- package/src/config/thread-defaults.ts +40 -20
- package/src/create-runtime.ts +200 -449
- package/src/db/base.service.ts +52 -28
- package/src/db/cursor-pagination.ts +71 -30
- package/src/db/memory-query-builder.ts +2 -1
- package/src/db/memory-store.helpers.ts +4 -7
- package/src/db/memory-store.ts +868 -601
- package/src/db/memory.ts +396 -280
- package/src/db/record-id.ts +32 -10
- package/src/db/schema-fingerprint.ts +30 -12
- package/src/db/service-normalization.ts +288 -0
- package/src/db/service.ts +912 -779
- package/src/db/startup.ts +153 -68
- package/src/db/transaction-conflict.ts +15 -0
- package/src/effect/awaitable-effect.ts +96 -0
- package/src/effect/errors.ts +121 -0
- package/src/effect/helpers.ts +123 -0
- package/src/effect/index.ts +24 -0
- package/src/effect/layers.ts +238 -0
- package/src/effect/runtime-ref.ts +25 -0
- package/src/effect/runtime.ts +46 -0
- package/src/effect/services.ts +61 -0
- package/src/effect/zod.ts +43 -0
- package/src/embeddings/provider.ts +128 -83
- package/src/index.ts +48 -1
- package/src/openrouter/direct-provider.ts +11 -35
- package/src/queues/autonomous-job.queue.ts +117 -73
- package/src/queues/context-compaction.queue.ts +50 -17
- package/src/queues/delayed-node-promotion.queue.ts +46 -17
- package/src/queues/document-processor.queue.ts +52 -77
- package/src/queues/memory-consolidation.queue.ts +47 -32
- package/src/queues/organization-learning.queue.ts +26 -4
- package/src/queues/plan-agent-heartbeat.queue.ts +71 -24
- package/src/queues/plan-scheduler.queue.ts +97 -33
- package/src/queues/post-chat-memory.queue.ts +56 -26
- package/src/queues/queue-factory.ts +227 -59
- package/src/queues/standalone-worker.ts +39 -0
- package/src/queues/title-generation.queue.ts +45 -11
- package/src/redis/connection.ts +182 -113
- package/src/redis/index.ts +6 -8
- package/src/redis/org-memory-lock.ts +60 -27
- package/src/redis/redis-lease-lock.ts +200 -121
- package/src/redis/runtime-connection.ts +20 -0
- package/src/redis/stream-context.ts +92 -46
- package/src/runtime/agent-identity-overrides.ts +2 -2
- package/src/runtime/agent-runtime-policy.ts +5 -2
- package/src/runtime/agent-stream-helpers.ts +24 -9
- package/src/runtime/chat-run-orchestration.ts +102 -19
- package/src/runtime/chat-run-registry.ts +36 -2
- package/src/runtime/context-compaction/context-compaction-runtime.ts +107 -0
- package/src/runtime/{context-compaction.ts → context-compaction/context-compaction.ts} +161 -94
- package/src/runtime/domain-layer.ts +192 -0
- package/src/runtime/execution-plan-visibility.ts +2 -2
- package/src/runtime/execution-plan.ts +42 -15
- package/src/runtime/graph-designer.ts +16 -4
- package/src/runtime/helper-model.ts +139 -48
- package/src/runtime/index.ts +7 -8
- package/src/runtime/indexed-repositories-policy.ts +3 -3
- package/src/runtime/{memory-block.ts → memory/memory-block.ts} +50 -36
- package/src/runtime/{memory-digest-policy.ts → memory/memory-digest-policy.ts} +1 -1
- package/src/runtime/{memory-pipeline.ts → memory/memory-pipeline.ts} +54 -67
- package/src/runtime/{memory-prompts-fact.ts → memory/memory-prompts-fact.ts} +2 -2
- package/src/runtime/memory/memory-scope.ts +53 -0
- package/src/runtime/plugin-resolution.ts +124 -25
- package/src/runtime/plugin-types.ts +9 -1
- package/src/runtime/post-turn-side-effects.ts +177 -130
- package/src/runtime/retrieval-adapters.ts +40 -6
- package/src/runtime/runtime-accessors.ts +92 -0
- package/src/runtime/runtime-config.ts +150 -61
- package/src/runtime/runtime-extensions.ts +23 -25
- 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 +159 -0
- package/src/runtime/{social-chat-history.ts → social-chat/social-chat-history.ts} +51 -20
- package/src/runtime/social-chat/social-chat.ts +630 -0
- package/src/runtime/specialist-runner.ts +36 -10
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +433 -0
- package/src/runtime/{team-consultation-prompts.ts → team-consultation/team-consultation-prompts.ts} +6 -2
- package/src/runtime/thread-chat-helpers.ts +2 -2
- package/src/runtime/thread-plan-turn.ts +2 -1
- package/src/runtime/thread-turn-context.ts +183 -111
- package/src/runtime/turn-lifecycle.ts +93 -27
- package/src/services/agent-activity.service.ts +287 -203
- package/src/services/agent-executor.service.ts +253 -149
- package/src/services/artifact.service.ts +231 -149
- package/src/services/attachment.service.ts +171 -115
- package/src/services/autonomous-job.service.ts +890 -491
- package/src/services/background-work.service.ts +54 -0
- package/src/services/chat-run-registry.service.ts +13 -1
- package/src/services/context-compaction.service.ts +136 -86
- package/src/services/document-chunk.service.ts +151 -88
- package/src/services/execution-plan/execution-plan-approval.ts +26 -0
- package/src/services/execution-plan/execution-plan-context.ts +29 -0
- package/src/services/execution-plan/execution-plan-graph.ts +278 -0
- package/src/services/execution-plan/execution-plan-schedule.ts +84 -0
- package/src/services/execution-plan/execution-plan-spec.ts +75 -0
- package/src/services/execution-plan/execution-plan.service.ts +1041 -0
- package/src/services/feedback-loop.service.ts +132 -76
- package/src/services/global-orchestrator.service.ts +101 -168
- package/src/services/graph-full-routing.ts +193 -0
- package/src/services/index.ts +19 -21
- package/src/services/institutional-memory.service.ts +213 -125
- package/src/services/learned-skill.service.ts +368 -260
- package/src/services/memory/memory-conversation.ts +95 -0
- package/src/services/memory/memory-errors.ts +27 -0
- package/src/services/memory/memory-org-memory.ts +50 -0
- package/src/services/memory/memory-preseeded.ts +86 -0
- package/src/services/memory/memory-rerank.ts +297 -0
- package/src/services/{memory-utils.ts → memory/memory-utils.ts} +6 -5
- package/src/services/memory/memory.service.ts +674 -0
- package/src/services/memory/rerank.service.ts +201 -0
- package/src/services/monitoring-window.service.ts +92 -70
- package/src/services/mutating-approval.service.ts +62 -53
- package/src/services/node-workspace.service.ts +141 -98
- package/src/services/notification.service.ts +29 -16
- package/src/services/organization-member.service.ts +120 -66
- package/src/services/organization.service.ts +153 -77
- package/src/services/ownership-dispatcher.service.ts +456 -263
- package/src/services/plan/plan-agent-heartbeat.service.ts +234 -0
- package/src/services/plan/plan-agent-query.service.ts +322 -0
- package/src/services/{plan-approval.service.ts → plan/plan-approval.service.ts} +45 -22
- package/src/services/plan/plan-artifact.service.ts +60 -0
- package/src/services/plan/plan-builder.service.ts +76 -0
- package/src/services/plan/plan-checkpoint.service.ts +103 -0
- package/src/services/{plan-compiler.service.ts → plan/plan-compiler.service.ts} +26 -9
- package/src/services/plan/plan-completion-side-effects.ts +169 -0
- package/src/services/plan/plan-coordination.service.ts +181 -0
- package/src/services/plan/plan-cycle.service.ts +405 -0
- package/src/services/plan/plan-deadline.service.ts +533 -0
- package/src/services/plan/plan-event-delivery.service.ts +266 -0
- package/src/services/plan/plan-executor-context.ts +35 -0
- package/src/services/plan/plan-executor-graph.ts +522 -0
- package/src/services/plan/plan-executor-helpers.ts +307 -0
- package/src/services/plan/plan-executor-persistence.ts +209 -0
- package/src/services/plan/plan-executor.service.ts +1737 -0
- package/src/services/{plan-helpers.ts → plan/plan-helpers.ts} +1 -1
- package/src/services/{plan-run-data.ts → plan/plan-run-data.ts} +4 -4
- package/src/services/plan/plan-run-serialization.ts +15 -0
- package/src/services/plan/plan-run.service.ts +637 -0
- package/src/services/plan/plan-scheduler.service.ts +379 -0
- package/src/services/plan/plan-template.service.ts +224 -0
- package/src/services/plan/plan-transaction-events.ts +36 -0
- package/src/services/plan/plan-validator.service.ts +907 -0
- package/src/services/plan/plan-workspace.service.ts +131 -0
- package/src/services/plugin-executor.service.ts +102 -68
- package/src/services/quality-metrics.service.ts +112 -94
- package/src/services/queue-job.service.ts +288 -231
- package/src/services/recent-activity-title.service.ts +73 -36
- package/src/services/recent-activity.service.ts +274 -259
- package/src/services/skill-resolver.service.ts +38 -12
- package/src/services/social-chat-history.service.ts +190 -122
- package/src/services/system-executor.service.ts +96 -61
- package/src/services/thread/thread-active-run.ts +203 -0
- package/src/services/thread/thread-bootstrap.ts +385 -0
- package/src/services/thread/thread-listing.ts +199 -0
- package/src/services/thread/thread-memory-block.ts +130 -0
- package/src/services/thread/thread-message.service.ts +379 -0
- package/src/services/thread/thread-record-store.ts +155 -0
- package/src/services/thread/thread-title.service.ts +74 -0
- package/src/services/thread/thread-turn-execution.ts +280 -0
- package/src/services/thread/thread-turn-message-context.ts +73 -0
- package/src/services/thread/thread-turn-preparation.service.ts +1148 -0
- package/src/services/thread/thread-turn-streaming.ts +403 -0
- package/src/services/thread/thread-turn-tracing.ts +35 -0
- package/src/services/thread/thread-turn.ts +376 -0
- package/src/services/thread/thread.service.ts +344 -0
- package/src/services/user.service.ts +82 -32
- package/src/services/write-intent-validator.service.ts +63 -51
- package/src/storage/attachment-parser.ts +69 -27
- package/src/storage/attachment-storage.service.ts +334 -275
- package/src/storage/generated-document-storage.service.ts +66 -34
- package/src/system-agents/agent-result.ts +3 -1
- package/src/system-agents/context-compaction.agent.ts +3 -3
- package/src/system-agents/delegated-agent-factory.ts +159 -90
- package/src/system-agents/helper-agent-options.ts +1 -1
- package/src/system-agents/memory-reranker.agent.ts +3 -3
- package/src/system-agents/memory.agent.ts +3 -3
- package/src/system-agents/recent-activity-title-refiner.agent.ts +3 -3
- package/src/system-agents/regular-chat-memory-digest.agent.ts +3 -3
- package/src/system-agents/skill-extractor.agent.ts +3 -3
- package/src/system-agents/skill-manager.agent.ts +3 -3
- package/src/system-agents/thread-router.agent.ts +157 -113
- package/src/system-agents/title-generator.agent.ts +3 -3
- package/src/tools/execution-plan.tool.ts +241 -171
- package/src/tools/fetch-webpage.tool.ts +29 -18
- package/src/tools/firecrawl-client.ts +26 -6
- package/src/tools/index.ts +1 -0
- package/src/tools/memory-block.tool.ts +14 -6
- package/src/tools/plan-approval.tool.ts +57 -47
- package/src/tools/read-file-parts.tool.ts +44 -33
- package/src/tools/remember-memory.tool.ts +65 -45
- package/src/tools/search-web.tool.ts +33 -22
- package/src/tools/search.tool.ts +41 -29
- package/src/tools/team-think.tool.ts +125 -84
- package/src/tools/user-questions.tool.ts +4 -3
- package/src/tools/web-tool-shared.ts +6 -0
- package/src/utils/async.ts +25 -22
- package/src/utils/crypto.ts +21 -0
- package/src/utils/date-time.ts +40 -1
- package/src/utils/errors.ts +111 -20
- package/src/utils/hono-error-handler.ts +24 -39
- package/src/utils/index.ts +2 -1
- package/src/utils/null-proto-record.ts +41 -0
- package/src/utils/sse-keepalive.ts +124 -21
- package/src/workers/bootstrap.ts +164 -52
- package/src/workers/memory-consolidation.worker.ts +325 -237
- package/src/workers/organization-learning.worker.ts +50 -16
- package/src/workers/regular-chat-memory-digest.helpers.ts +28 -27
- package/src/workers/regular-chat-memory-digest.runner.ts +185 -114
- package/src/workers/skill-extraction.runner.ts +176 -93
- package/src/workers/utils/file-section-chunker.ts +8 -10
- package/src/workers/utils/repo-structure-extractor.ts +349 -260
- package/src/workers/utils/repomix-file-sections.ts +2 -2
- package/src/workers/utils/thread-message-query.ts +97 -38
- package/src/workers/worker-utils.ts +74 -31
- package/src/config/debug-logger.ts +0 -47
- package/src/config/search.ts +0 -3
- package/src/redis/connection-accessor.ts +0 -26
- package/src/runtime/agent-types.ts +0 -1
- package/src/runtime/context-compaction-runtime.ts +0 -87
- package/src/runtime/memory-scope.ts +0 -43
- package/src/runtime/social-chat-agent-runner.ts +0 -118
- package/src/runtime/social-chat.ts +0 -516
- package/src/runtime/team-consultation-orchestrator.ts +0 -272
- package/src/services/adaptive-playbook.service.ts +0 -152
- package/src/services/artifact-provenance.service.ts +0 -172
- package/src/services/chat-attachments.service.ts +0 -17
- package/src/services/context-compaction-runtime.singleton.ts +0 -13
- package/src/services/execution-plan.service.ts +0 -1118
- package/src/services/memory.service.ts +0 -914
- package/src/services/plan-agent-heartbeat.service.ts +0 -136
- package/src/services/plan-agent-query.service.ts +0 -267
- package/src/services/plan-artifact.service.ts +0 -50
- package/src/services/plan-builder.service.ts +0 -67
- package/src/services/plan-checkpoint.service.ts +0 -81
- package/src/services/plan-completion-side-effects.ts +0 -80
- package/src/services/plan-coordination.service.ts +0 -157
- package/src/services/plan-cycle.service.ts +0 -284
- package/src/services/plan-deadline.service.ts +0 -430
- package/src/services/plan-event-delivery.service.ts +0 -166
- package/src/services/plan-executor.service.ts +0 -1950
- package/src/services/plan-run.service.ts +0 -515
- package/src/services/plan-scheduler.service.ts +0 -240
- package/src/services/plan-template.service.ts +0 -177
- package/src/services/plan-validator.service.ts +0 -818
- package/src/services/plan-workspace.service.ts +0 -83
- package/src/services/rerank.service.ts +0 -156
- package/src/services/thread-message.service.ts +0 -275
- package/src/services/thread-plan-registry.service.ts +0 -22
- package/src/services/thread-title.service.ts +0 -39
- package/src/services/thread-turn-preparation.service.ts +0 -1147
- package/src/services/thread-turn.ts +0 -172
- package/src/services/thread.service.ts +0 -869
- package/src/utils/env.ts +0 -8
- /package/src/runtime/{context-compaction-constants.ts → context-compaction/context-compaction-constants.ts} +0 -0
- /package/src/runtime/{memory-format.ts → memory/memory-format.ts} +0 -0
- /package/src/runtime/{memory-prompts-parse.ts → memory/memory-prompts-parse.ts} +0 -0
- /package/src/runtime/{memory-prompts-update.ts → memory/memory-prompts-update.ts} +0 -0
- /package/src/runtime/{social-chat-prompts.ts → social-chat/social-chat-prompts.ts} +0 -0
- /package/src/services/{plan-node-spec.ts → plan/plan-node-spec.ts} +0 -0
- /package/src/services/{thread-constants.ts → thread/thread-constants.ts} +0 -0
- /package/src/services/{thread.types.ts → thread/thread.types.ts} +0 -0
|
@@ -9,12 +9,18 @@ import type {
|
|
|
9
9
|
} from '@lota-sdk/shared'
|
|
10
10
|
import { PlanNodeResultSubmissionSchema, WriteIntentSchema } from '@lota-sdk/shared'
|
|
11
11
|
import { stepCountIs, tool } from 'ai'
|
|
12
|
-
import type {
|
|
12
|
+
import type { ToolSet } from 'ai'
|
|
13
|
+
import { Context, Schema, Effect, Layer } from 'effect'
|
|
13
14
|
|
|
14
|
-
import {
|
|
15
|
+
import { getAgentRoster, getAgentRuntimeConfig, getResolvedAgentFactoryConfig } from '../config/agent-defaults'
|
|
15
16
|
import { ensureRecordId } from '../db/record-id'
|
|
16
|
-
import {
|
|
17
|
+
import type { SurrealDBService } from '../db/service'
|
|
17
18
|
import { TABLES } from '../db/tables'
|
|
19
|
+
import { BadRequestError, NotFoundError } from '../effect/errors'
|
|
20
|
+
import { makeEffectTryPromiseWithOperation } from '../effect/helpers'
|
|
21
|
+
import { runPromise } from '../effect/runtime'
|
|
22
|
+
import { DatabaseServiceTag } from '../effect/services'
|
|
23
|
+
import { toValidationError } from '../effect/zod'
|
|
18
24
|
import {
|
|
19
25
|
OWNERSHIP_DISPATCH_BLOCKED_TOOL_NAMES,
|
|
20
26
|
buildCompletionCheckStructuredOutputHints,
|
|
@@ -22,13 +28,24 @@ import {
|
|
|
22
28
|
buildOwnershipDispatchResponseGuard,
|
|
23
29
|
} from '../runtime/agent-runtime-policy'
|
|
24
30
|
import { mergeInstructionSections } from '../runtime/instruction-sections'
|
|
25
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
buildIndexedRepositoriesContext,
|
|
33
|
+
getGithubInstallationForOrganization,
|
|
34
|
+
getLinearInstallationByOrgId,
|
|
35
|
+
} from '../runtime/plugin-resolution'
|
|
26
36
|
import { getTurnHooks } from '../runtime/runtime-extensions'
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import type {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
37
|
+
import { readInstructionSections, readOptionalString } from '../runtime/thread-chat-helpers'
|
|
38
|
+
import { nowDate } from '../utils/date-time'
|
|
39
|
+
import type { makeNodeWorkspaceService } from './node-workspace.service'
|
|
40
|
+
import { NodeWorkspaceServiceTag } from './node-workspace.service'
|
|
41
|
+
import type { PlanValidationIssueInput } from './plan/plan-validator.service'
|
|
42
|
+
import { ThreadSchema } from './thread/thread.types'
|
|
43
|
+
import type { makeWriteIntentValidatorService } from './write-intent-validator.service'
|
|
44
|
+
import { WriteIntentValidatorServiceTag } from './write-intent-validator.service'
|
|
45
|
+
|
|
46
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
47
|
+
return typeof value === 'object' && value !== null
|
|
48
|
+
}
|
|
32
49
|
|
|
33
50
|
function applyToolPolicy(tools: ToolSet, nodeSpec: PlanNodeSpec): ToolSet {
|
|
34
51
|
const blockedToolNames = new Set([...OWNERSHIP_DISPATCH_BLOCKED_TOOL_NAMES, ...nodeSpec.toolPolicy.deny])
|
|
@@ -74,79 +91,151 @@ export function buildWriteIntentDispatchPrompt(nodeSpec: PlanNodeSpec): string {
|
|
|
74
91
|
|
|
75
92
|
const MAX_SELF_CORRECTION_RETRIES = 3
|
|
76
93
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
]
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return []
|
|
94
|
+
function validateOwner(agentId: string, nodeId: string): PlanValidationIssueInput[] {
|
|
95
|
+
if (!getAgentRoster().includes(agentId)) {
|
|
96
|
+
return [
|
|
97
|
+
{
|
|
98
|
+
severity: 'blocking',
|
|
99
|
+
code: 'agent_executor_missing',
|
|
100
|
+
message: `Node "${nodeId}" references unknown agent executor "${agentId}".`,
|
|
101
|
+
nodeId,
|
|
102
|
+
detail: { agentId },
|
|
103
|
+
},
|
|
104
|
+
]
|
|
92
105
|
}
|
|
93
106
|
|
|
94
|
-
|
|
107
|
+
return []
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
class AgentExecutorError extends Schema.TaggedErrorClass<AgentExecutorError>()('AgentExecutorError', {
|
|
111
|
+
operation: Schema.String,
|
|
112
|
+
message: Schema.String,
|
|
113
|
+
cause: Schema.Defect,
|
|
114
|
+
}) {}
|
|
115
|
+
|
|
116
|
+
const tryAgentExecutorPromise = makeEffectTryPromiseWithOperation(
|
|
117
|
+
(operation, message, cause) => new AgentExecutorError({ operation, message, cause }),
|
|
118
|
+
)
|
|
119
|
+
const tryAgentExecutorTask = <A>(
|
|
120
|
+
operation: string,
|
|
121
|
+
message: string,
|
|
122
|
+
task: () => PromiseLike<A>,
|
|
123
|
+
): Effect.Effect<A, AgentExecutorError> =>
|
|
124
|
+
Effect.tryPromise({ try: task, catch: (cause) => new AgentExecutorError({ operation, message, cause }) })
|
|
125
|
+
|
|
126
|
+
function isAgentExecutorOwner(
|
|
127
|
+
owner: PlanNodeSpec['owner'],
|
|
128
|
+
): owner is Extract<PlanNodeSpec['owner'], { executorType: 'agent' }> {
|
|
129
|
+
return owner.executorType === 'agent'
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function buildWriteIntentTool(params: {
|
|
133
|
+
nodeSpec: PlanNodeSpec
|
|
134
|
+
workspace: ReturnType<ReturnType<typeof makeNodeWorkspaceService>['initialize']>
|
|
135
|
+
writeIntentValidatorService: ReturnType<typeof makeWriteIntentValidatorService>
|
|
136
|
+
stageWrite: (intent: WriteIntent) => Effect.Effect<void, BadRequestError>
|
|
137
|
+
}) {
|
|
138
|
+
return tool({
|
|
139
|
+
description:
|
|
140
|
+
'Write a validated artifact or structured output field. Call this for each deliverable. If validation fails, correct your payload and try again.',
|
|
141
|
+
inputSchema: WriteIntentSchema,
|
|
142
|
+
execute: (intent: WriteIntent) =>
|
|
143
|
+
runPromise(
|
|
144
|
+
Effect.gen(function* () {
|
|
145
|
+
const correctionCount = params.workspace.sys.correctionCounts.get(intent.targetPath) ?? 0
|
|
146
|
+
|
|
147
|
+
const validation = params.writeIntentValidatorService.validate({
|
|
148
|
+
intent,
|
|
149
|
+
nodeSpec: params.nodeSpec,
|
|
150
|
+
schemaRegistry: params.workspace.ctx.schemaRegistry,
|
|
151
|
+
existingDeliverables: params.workspace.deliverables,
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
if (validation.issues.length > 0) {
|
|
155
|
+
if (correctionCount >= MAX_SELF_CORRECTION_RETRIES) {
|
|
156
|
+
return yield* new BadRequestError({
|
|
157
|
+
message: `Write validation failed for "${intent.targetPath}" after ${MAX_SELF_CORRECTION_RETRIES} retries: ${validation.issues.map((i) => i.message).join(', ')}`,
|
|
158
|
+
})
|
|
159
|
+
}
|
|
160
|
+
params.workspace.sys.correctionCounts.set(intent.targetPath, correctionCount + 1)
|
|
161
|
+
params.workspace.sys.writeLog.push({
|
|
162
|
+
targetPath: intent.targetPath,
|
|
163
|
+
action: intent.action,
|
|
164
|
+
timestamp: nowDate(),
|
|
165
|
+
result: 'rejected',
|
|
166
|
+
})
|
|
167
|
+
return {
|
|
168
|
+
status: 'validation_failed',
|
|
169
|
+
error: { targetPath: intent.targetPath, action: intent.action, issues: validation.issues },
|
|
170
|
+
hint: `Correct and re-emit. Attempt ${correctionCount + 1}/${MAX_SELF_CORRECTION_RETRIES}.`,
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
yield* params.stageWrite(intent)
|
|
175
|
+
return { status: 'accepted', message: `Write to "${intent.targetPath}" validated and staged.` }
|
|
176
|
+
}),
|
|
177
|
+
),
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function createExecuteNode(deps: AgentExecutorDeps) {
|
|
182
|
+
return Effect.fn('AgentExecutor.executeNode')(function* (params: {
|
|
95
183
|
nodeSpec: PlanNodeSpec
|
|
96
184
|
resolvedInput: Record<string, unknown>
|
|
97
185
|
inputArtifacts: PlanArtifactSubmission[]
|
|
98
186
|
context: OwnershipDispatchContext
|
|
99
187
|
executionMode?: ExecutionMode
|
|
100
188
|
schemaRegistry?: PlanSchemaRegistry
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
|
|
189
|
+
}) {
|
|
190
|
+
const owner = params.nodeSpec.owner
|
|
191
|
+
if (!isAgentExecutorOwner(owner)) {
|
|
192
|
+
return yield* new BadRequestError({ message: `AgentExecutor cannot execute owner type "${owner.executorType}".` })
|
|
104
193
|
}
|
|
105
194
|
|
|
106
|
-
const agentId =
|
|
107
|
-
if (!
|
|
108
|
-
|
|
195
|
+
const agentId = owner.ref
|
|
196
|
+
if (!getAgentRoster().includes(agentId)) {
|
|
197
|
+
return yield* new BadRequestError({ message: `Agent executor "${agentId}" is not registered.` })
|
|
109
198
|
}
|
|
110
199
|
|
|
111
|
-
const thread =
|
|
112
|
-
TABLES.THREAD,
|
|
113
|
-
|
|
114
|
-
ThreadSchema,
|
|
115
|
-
)
|
|
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'))
|
|
116
203
|
if (!thread) {
|
|
117
|
-
|
|
204
|
+
return yield* new NotFoundError({
|
|
205
|
+
resource: TABLES.THREAD,
|
|
206
|
+
message: `Thread ${params.context.threadId} not found for dispatched execution.`,
|
|
207
|
+
})
|
|
118
208
|
}
|
|
119
209
|
|
|
120
210
|
const organizationRef = ensureRecordId(params.context.organizationId, TABLES.ORGANIZATION)
|
|
121
211
|
const threadRef = ensureRecordId(params.context.threadId, TABLES.THREAD)
|
|
122
212
|
const userRefSource = params.context.userId ?? thread.userId
|
|
123
213
|
if (!userRefSource) {
|
|
124
|
-
|
|
214
|
+
return yield* new BadRequestError({
|
|
215
|
+
message: `Thread ${params.context.threadId} is missing a user context for dispatched execution.`,
|
|
216
|
+
})
|
|
125
217
|
}
|
|
126
218
|
const userRef = ensureRecordId(userRefSource, TABLES.USER)
|
|
127
219
|
const userName = params.context.userName ?? 'User'
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
buildIndexedRepositoriesContext(params.context.organizationId),
|
|
146
|
-
])
|
|
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'))
|
|
147
237
|
|
|
148
238
|
const mode = params.executionMode ?? 'linear'
|
|
149
|
-
|
|
150
239
|
const dispatchMode = thread.type === 'group' ? 'fixedThreadMode' : 'direct'
|
|
151
240
|
const dispatchInstructionSections = [
|
|
152
241
|
buildOwnershipDispatchContextSection({
|
|
@@ -156,23 +245,30 @@ class AgentExecutorService {
|
|
|
156
245
|
upstreamHandoffs: params.context.upstreamHandoffs,
|
|
157
246
|
}),
|
|
158
247
|
]
|
|
248
|
+
|
|
159
249
|
const turnHooks = getTurnHooks()
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
250
|
+
const agentResolutionValue = yield* tryAgentExecutorPromise(
|
|
251
|
+
'resolve-agent',
|
|
252
|
+
`Failed to resolve agent "${agentId}" for dispatched execution.`,
|
|
253
|
+
() =>
|
|
254
|
+
Promise.resolve(
|
|
255
|
+
turnHooks.resolveAgent?.({
|
|
256
|
+
agentId,
|
|
257
|
+
mode: dispatchMode,
|
|
258
|
+
thread,
|
|
259
|
+
threadRef,
|
|
260
|
+
orgRef: organizationRef,
|
|
261
|
+
userRef,
|
|
262
|
+
userName,
|
|
263
|
+
onboardingActive: false,
|
|
264
|
+
linearInstalled: Boolean(linearInstallation),
|
|
265
|
+
githubInstalled: Boolean(githubInstallation),
|
|
266
|
+
additionalInstructionSections: dispatchInstructionSections,
|
|
267
|
+
context: null,
|
|
268
|
+
}),
|
|
269
|
+
),
|
|
175
270
|
)
|
|
271
|
+
const agentResolution = isRecord(agentResolutionValue) ? agentResolutionValue : null
|
|
176
272
|
const resolvedAgentId = readOptionalString(agentResolution?.agentId) ?? agentId
|
|
177
273
|
const runtimeConfig = getAgentRuntimeConfig({
|
|
178
274
|
agentId: resolvedAgentId,
|
|
@@ -185,32 +281,40 @@ class AgentExecutorService {
|
|
|
185
281
|
readInstructionSections(agentResolution?.additionalInstructionSections),
|
|
186
282
|
),
|
|
187
283
|
responseGuardSection: buildOwnershipDispatchResponseGuard({ node: params.nodeSpec, executionMode: mode }),
|
|
188
|
-
})
|
|
284
|
+
})
|
|
189
285
|
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
+
)
|
|
209
313
|
const tools = applyToolPolicy(rawTools, params.nodeSpec)
|
|
210
314
|
|
|
211
|
-
const agentFactory = createAgent[resolvedAgentId]
|
|
315
|
+
const agentFactory = agentFactoryConfig.createAgent[resolvedAgentId]
|
|
212
316
|
if (!agentFactory) {
|
|
213
|
-
|
|
317
|
+
return yield* new BadRequestError({ message: `Agent factory "${resolvedAgentId}" is not registered.` })
|
|
214
318
|
}
|
|
215
319
|
|
|
216
320
|
const maxSteps = typeof runtimeConfig.maxSteps === 'number' ? runtimeConfig.maxSteps : 8
|
|
@@ -223,67 +327,40 @@ class AgentExecutorService {
|
|
|
223
327
|
typeof runtimeConfig.extraInstructions === 'string' ? runtimeConfig.extraInstructions : undefined,
|
|
224
328
|
maxRetries: 1,
|
|
225
329
|
stopWhen: [stepCountIs(maxSteps)],
|
|
226
|
-
})
|
|
330
|
+
})
|
|
227
331
|
|
|
228
|
-
const result =
|
|
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'))
|
|
229
337
|
const outputCandidate = PlanNodeResultSubmissionSchema.safeParse(result.output)
|
|
230
338
|
if (outputCandidate.success) {
|
|
231
339
|
return outputCandidate.data
|
|
232
340
|
}
|
|
233
341
|
|
|
234
|
-
|
|
342
|
+
return yield* toValidationError(
|
|
343
|
+
outputCandidate.error,
|
|
344
|
+
`Agent executor "${agentId}" returned an invalid node result`,
|
|
345
|
+
)
|
|
235
346
|
}
|
|
236
347
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
const workspace = nodeWorkspaceService.initialize({
|
|
348
|
+
const workspace = deps.nodeWorkspaceService.initialize({
|
|
240
349
|
nodeSpec: params.nodeSpec,
|
|
241
350
|
resolvedInput: params.resolvedInput,
|
|
242
351
|
inputArtifacts: params.inputArtifacts,
|
|
243
352
|
schemaRegistry: params.schemaRegistry ?? {},
|
|
244
353
|
})
|
|
245
354
|
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
nodeSpec: params.nodeSpec,
|
|
256
|
-
schemaRegistry: workspace.ctx.schemaRegistry,
|
|
257
|
-
existingDeliverables: workspace.deliverables,
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
if (validation.issues.length > 0) {
|
|
261
|
-
if (correctionCount >= MAX_SELF_CORRECTION_RETRIES) {
|
|
262
|
-
throw new Error(
|
|
263
|
-
`Write validation failed for "${intent.targetPath}" after ${MAX_SELF_CORRECTION_RETRIES} retries: ${validation.issues.map((i) => i.message).join(', ')}`,
|
|
264
|
-
)
|
|
265
|
-
}
|
|
266
|
-
workspace.sys.correctionCounts.set(intent.targetPath, correctionCount + 1)
|
|
267
|
-
workspace.sys.writeLog.push({
|
|
268
|
-
targetPath: intent.targetPath,
|
|
269
|
-
action: intent.action,
|
|
270
|
-
timestamp: new Date(),
|
|
271
|
-
result: 'rejected',
|
|
272
|
-
})
|
|
273
|
-
return {
|
|
274
|
-
status: 'validation_failed',
|
|
275
|
-
error: { targetPath: intent.targetPath, action: intent.action, issues: validation.issues },
|
|
276
|
-
hint: `Correct and re-emit. Attempt ${correctionCount + 1}/${MAX_SELF_CORRECTION_RETRIES}.`,
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
nodeWorkspaceService.stageWrite(workspace, intent, 'validated')
|
|
281
|
-
return { status: 'accepted', message: `Write to "${intent.targetPath}" validated and staged.` }
|
|
282
|
-
},
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
const graphTools = { ...tools, writeIntent: writeIntentTool }
|
|
286
|
-
|
|
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
|
+
}
|
|
287
364
|
const agent = agentFactory({
|
|
288
365
|
mode: dispatchMode,
|
|
289
366
|
tools: graphTools,
|
|
@@ -291,11 +368,15 @@ class AgentExecutorService {
|
|
|
291
368
|
typeof runtimeConfig.extraInstructions === 'string' ? runtimeConfig.extraInstructions : undefined,
|
|
292
369
|
maxRetries: 1,
|
|
293
370
|
stopWhen: [stepCountIs(maxSteps)],
|
|
294
|
-
})
|
|
371
|
+
})
|
|
295
372
|
|
|
296
|
-
|
|
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'))
|
|
297
378
|
|
|
298
|
-
const finalResult = nodeWorkspaceService.finalize(workspace)
|
|
379
|
+
const finalResult = yield* deps.nodeWorkspaceService.finalize(workspace)
|
|
299
380
|
|
|
300
381
|
if (!finalResult.isComplete) {
|
|
301
382
|
const result: PlanNodeResult = {
|
|
@@ -303,7 +384,7 @@ class AgentExecutorService {
|
|
|
303
384
|
artifacts: finalResult.artifacts,
|
|
304
385
|
notes: 'Execution incomplete: missing required deliverables or validation failures.',
|
|
305
386
|
}
|
|
306
|
-
nodeWorkspaceService.cleanup(workspace)
|
|
387
|
+
deps.nodeWorkspaceService.cleanup(workspace)
|
|
307
388
|
return result
|
|
308
389
|
}
|
|
309
390
|
|
|
@@ -313,9 +394,32 @@ class AgentExecutorService {
|
|
|
313
394
|
notes: finalResult.notes,
|
|
314
395
|
}
|
|
315
396
|
|
|
316
|
-
nodeWorkspaceService.cleanup(workspace)
|
|
397
|
+
deps.nodeWorkspaceService.cleanup(workspace)
|
|
317
398
|
return result
|
|
318
|
-
}
|
|
399
|
+
})
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
interface AgentExecutorDeps {
|
|
403
|
+
db: SurrealDBService
|
|
404
|
+
nodeWorkspaceService: ReturnType<typeof makeNodeWorkspaceService>
|
|
405
|
+
writeIntentValidatorService: ReturnType<typeof makeWriteIntentValidatorService>
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export function makeAgentExecutorService(deps: AgentExecutorDeps) {
|
|
409
|
+
return { validateOwner, executeNode: createExecuteNode(deps) }
|
|
319
410
|
}
|
|
320
411
|
|
|
321
|
-
export
|
|
412
|
+
export class AgentExecutorServiceTag extends Context.Service<
|
|
413
|
+
AgentExecutorServiceTag,
|
|
414
|
+
ReturnType<typeof makeAgentExecutorService>
|
|
415
|
+
>()('@lota-sdk/core/AgentExecutorService') {}
|
|
416
|
+
|
|
417
|
+
export const AgentExecutorServiceLive = Layer.effect(
|
|
418
|
+
AgentExecutorServiceTag,
|
|
419
|
+
Effect.gen(function* () {
|
|
420
|
+
const db = yield* DatabaseServiceTag
|
|
421
|
+
const nodeWorkspaceService = yield* NodeWorkspaceServiceTag
|
|
422
|
+
const writeIntentValidatorService = yield* WriteIntentValidatorServiceTag
|
|
423
|
+
return makeAgentExecutorService({ db, nodeWorkspaceService, writeIntentValidatorService })
|
|
424
|
+
}),
|
|
425
|
+
)
|