@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
|
@@ -8,22 +8,34 @@ import {
|
|
|
8
8
|
} from '@lota-sdk/shared'
|
|
9
9
|
import { Effect } from 'effect'
|
|
10
10
|
import { RecordId } from 'surrealdb'
|
|
11
|
+
import type { z } from 'zod'
|
|
11
12
|
|
|
12
13
|
import type { RecordIdInput } from '../../db/record-id'
|
|
13
14
|
import { ensureRecordId, recordIdToString } from '../../db/record-id'
|
|
14
15
|
import type { DatabaseTransaction } from '../../db/service'
|
|
15
16
|
import { TABLES } from '../../db/tables'
|
|
16
|
-
import {
|
|
17
|
+
import { ServiceError } from '../../effect/errors'
|
|
17
18
|
import { nowDate } from '../../utils/date-time'
|
|
18
19
|
import type { CompiledPlanNode } from '../plan/plan-compiler.service'
|
|
19
20
|
import type { syncRunGraph } from '../plan/plan-executor-graph'
|
|
20
21
|
import { toRunData } from '../plan/plan-run-data'
|
|
21
22
|
|
|
23
|
+
function parseRowOrFail<TSchema extends z.ZodTypeAny>(
|
|
24
|
+
schema: TSchema,
|
|
25
|
+
value: unknown,
|
|
26
|
+
operation: string,
|
|
27
|
+
): Effect.Effect<z.infer<TSchema>, ServiceError> {
|
|
28
|
+
return Effect.try({
|
|
29
|
+
try: () => schema.parse(value) as z.infer<TSchema>,
|
|
30
|
+
catch: (cause) => new ServiceError({ message: `Failed to parse row for ${operation}.`, cause }),
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
22
34
|
type SyncRunGraphParams = Parameters<typeof syncRunGraph>[1]
|
|
23
|
-
type SyncRunGraphResult =
|
|
35
|
+
type SyncRunGraphResult = ReturnType<typeof syncRunGraph>
|
|
24
36
|
|
|
25
37
|
interface ExecutionPlanGraphExecutor {
|
|
26
|
-
syncRunGraph(params: SyncRunGraphParams):
|
|
38
|
+
syncRunGraph(params: SyncRunGraphParams): SyncRunGraphResult
|
|
27
39
|
}
|
|
28
40
|
|
|
29
41
|
function buildNodeSpecCreateContent(compiledNode: CompiledPlanNode, planSpecId: RecordIdInput) {
|
|
@@ -86,7 +98,7 @@ function createNodeSpecs(tx: DatabaseTransaction, planSpecId: RecordIdInput, nod
|
|
|
86
98
|
.create(nodeSpecId)
|
|
87
99
|
.content(buildNodeSpecCreateContent(compiledNode, planSpecId))
|
|
88
100
|
.output('after')
|
|
89
|
-
createdRecords.push(PlanNodeSpecRecordSchema
|
|
101
|
+
createdRecords.push(yield* parseRowOrFail(PlanNodeSpecRecordSchema, created, 'createNodeSpecs'))
|
|
90
102
|
}
|
|
91
103
|
|
|
92
104
|
return createdRecords
|
|
@@ -109,7 +121,7 @@ function createNodeRuns(
|
|
|
109
121
|
.create(nodeRunId)
|
|
110
122
|
.content(buildNodeRunCreateContent(runId, planSpecId, nodeSpec))
|
|
111
123
|
.output('after')
|
|
112
|
-
createdNodeRuns.push(PlanNodeRunSchema
|
|
124
|
+
createdNodeRuns.push(yield* parseRowOrFail(PlanNodeRunSchema, created, 'createNodeRuns'))
|
|
113
125
|
}
|
|
114
126
|
|
|
115
127
|
return createdNodeRuns
|
|
@@ -135,122 +147,123 @@ export function createInitializedRunGraph(params: {
|
|
|
135
147
|
runPatch?: { replacedRunId?: RecordIdInput }
|
|
136
148
|
planExecutor: ExecutionPlanGraphExecutor
|
|
137
149
|
}) {
|
|
138
|
-
return
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
.output('after'),
|
|
160
|
-
)
|
|
150
|
+
return Effect.gen(function* () {
|
|
151
|
+
const nodeSpecs = yield* createNodeSpecs(params.tx, params.spec.id, params.nodes)
|
|
152
|
+
const runRaw = yield* params.tx
|
|
153
|
+
.create(ensureRecordId(params.runId, TABLES.PLAN_RUN))
|
|
154
|
+
.content({
|
|
155
|
+
planSpecId: ensureRecordId(params.spec.id, TABLES.PLAN_SPEC),
|
|
156
|
+
organizationId: ensureRecordId(params.organizationId, TABLES.ORGANIZATION),
|
|
157
|
+
threadId: ensureRecordId(params.threadId, TABLES.THREAD),
|
|
158
|
+
...(params.sourceThreadId ? { sourceThreadId: ensureRecordId(params.sourceThreadId, TABLES.THREAD) } : {}),
|
|
159
|
+
leadAgentId: params.leadAgentId,
|
|
160
|
+
...(params.createdByAgentId ? { createdByAgentId: params.createdByAgentId } : {}),
|
|
161
|
+
status: params.requireApproval ? 'pending-approval' : 'running',
|
|
162
|
+
readyNodeIds: [],
|
|
163
|
+
failureCount: 0,
|
|
164
|
+
...(params.runPatch?.replacedRunId
|
|
165
|
+
? { replacedRunId: ensureRecordId(params.runPatch.replacedRunId, TABLES.PLAN_RUN) }
|
|
166
|
+
: {}),
|
|
167
|
+
...(params.requireApproval ? {} : { startedAt: nowDate() }),
|
|
168
|
+
})
|
|
169
|
+
.output('after')
|
|
170
|
+
const run = yield* parseRowOrFail(PlanRunSchema, runRaw, 'createInitializedRunGraph:run')
|
|
161
171
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
const nodeRuns = yield* createNodeRuns(params.tx, run.id, params.spec.id, nodeSpecs)
|
|
173
|
+
const synced = params.requireApproval
|
|
174
|
+
? { run, nodeRuns }
|
|
175
|
+
: yield* params.planExecutor.syncRunGraph({
|
|
176
|
+
tx: params.tx,
|
|
177
|
+
run,
|
|
178
|
+
spec: params.spec,
|
|
179
|
+
nodeSpecs,
|
|
180
|
+
nodeRuns,
|
|
181
|
+
artifacts: [],
|
|
182
|
+
emittedBy: params.leadAgentId,
|
|
183
|
+
capturedEvents: params.emittedEvents,
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
const event = yield* params.tx
|
|
187
|
+
.create(new RecordId(TABLES.PLAN_EVENT, Bun.randomUUIDv7()))
|
|
188
|
+
.content({
|
|
189
|
+
planSpecId: ensureRecordId(params.spec.id, TABLES.PLAN_SPEC),
|
|
190
|
+
runId: ensureRecordId(synced.run.id, TABLES.PLAN_RUN),
|
|
191
|
+
eventType: params.createdEventType,
|
|
192
|
+
message: params.createdEventMessage,
|
|
193
|
+
emittedBy: params.leadAgentId,
|
|
194
|
+
detail: { ...params.createdEventDetail, nodeCount: nodeSpecs.length },
|
|
195
|
+
})
|
|
196
|
+
.output('after')
|
|
197
|
+
params.emittedEvents.push(yield* parseRowOrFail(PlanEventSchema, event, 'createInitializedRunGraph:createdEvent'))
|
|
177
198
|
|
|
178
|
-
|
|
199
|
+
if (params.requireApproval) {
|
|
200
|
+
const pendingApprovalEvent = yield* params.tx
|
|
179
201
|
.create(new RecordId(TABLES.PLAN_EVENT, Bun.randomUUIDv7()))
|
|
180
202
|
.content({
|
|
181
203
|
planSpecId: ensureRecordId(params.spec.id, TABLES.PLAN_SPEC),
|
|
182
204
|
runId: ensureRecordId(synced.run.id, TABLES.PLAN_RUN),
|
|
183
|
-
eventType:
|
|
184
|
-
|
|
205
|
+
eventType: 'plan-pending-approval',
|
|
206
|
+
toStatus: synced.run.status,
|
|
207
|
+
message: `Execution plan "${params.spec.title}" is pending approval.`,
|
|
185
208
|
emittedBy: params.leadAgentId,
|
|
186
209
|
detail: { ...params.createdEventDetail, nodeCount: nodeSpecs.length },
|
|
187
210
|
})
|
|
188
211
|
.output('after')
|
|
189
|
-
params.emittedEvents.push(
|
|
190
|
-
|
|
191
|
-
if (params.requireApproval) {
|
|
192
|
-
const pendingApprovalEvent = yield* params.tx
|
|
193
|
-
.create(new RecordId(TABLES.PLAN_EVENT, Bun.randomUUIDv7()))
|
|
194
|
-
.content({
|
|
195
|
-
planSpecId: ensureRecordId(params.spec.id, TABLES.PLAN_SPEC),
|
|
196
|
-
runId: ensureRecordId(synced.run.id, TABLES.PLAN_RUN),
|
|
197
|
-
eventType: 'plan-pending-approval',
|
|
198
|
-
toStatus: synced.run.status,
|
|
199
|
-
message: `Execution plan "${params.spec.title}" is pending approval.`,
|
|
200
|
-
emittedBy: params.leadAgentId,
|
|
201
|
-
detail: { ...params.createdEventDetail, nodeCount: nodeSpecs.length },
|
|
202
|
-
})
|
|
203
|
-
.output('after')
|
|
204
|
-
params.emittedEvents.push(PlanEventSchema.parse(pendingApprovalEvent))
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const checkpoint = PlanCheckpointSchema.parse(
|
|
208
|
-
yield* params.tx
|
|
209
|
-
.create(new RecordId(TABLES.PLAN_CHECKPOINT, Bun.randomUUIDv7()))
|
|
210
|
-
.content({
|
|
211
|
-
runId: ensureRecordId(synced.run.id, TABLES.PLAN_RUN),
|
|
212
|
-
sequence: 1,
|
|
213
|
-
runStatus: synced.run.status,
|
|
214
|
-
readyNodeIds: [...synced.run.readyNodeIds],
|
|
215
|
-
activeNodeIds: synced.run.currentNodeId ? [synced.run.currentNodeId] : [],
|
|
216
|
-
artifactIds: [],
|
|
217
|
-
lastCompletedNodeIds: synced.nodeRuns
|
|
218
|
-
.filter((nodeRun) => nodeRun.status === 'completed' || nodeRun.status === 'partial')
|
|
219
|
-
.map((nodeRun) => nodeRun.nodeId),
|
|
220
|
-
snapshot: {
|
|
221
|
-
reason: params.checkpointReason,
|
|
222
|
-
currentNodeId: synced.run.currentNodeId,
|
|
223
|
-
waitingNodeId: synced.run.waitingNodeId,
|
|
224
|
-
readyNodeIds: synced.run.readyNodeIds,
|
|
225
|
-
},
|
|
226
|
-
})
|
|
227
|
-
.output('after'),
|
|
212
|
+
params.emittedEvents.push(
|
|
213
|
+
yield* parseRowOrFail(PlanEventSchema, pendingApprovalEvent, 'createInitializedRunGraph:pendingApprovalEvent'),
|
|
228
214
|
)
|
|
215
|
+
}
|
|
229
216
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
217
|
+
const checkpointRaw = yield* params.tx
|
|
218
|
+
.create(new RecordId(TABLES.PLAN_CHECKPOINT, Bun.randomUUIDv7()))
|
|
219
|
+
.content({
|
|
220
|
+
runId: ensureRecordId(synced.run.id, TABLES.PLAN_RUN),
|
|
221
|
+
sequence: 1,
|
|
222
|
+
runStatus: synced.run.status,
|
|
223
|
+
readyNodeIds: [...synced.run.readyNodeIds],
|
|
224
|
+
activeNodeIds: synced.run.currentNodeId ? [synced.run.currentNodeId] : [],
|
|
225
|
+
artifactIds: [],
|
|
226
|
+
lastCompletedNodeIds: synced.nodeRuns
|
|
227
|
+
.filter((nodeRun) => nodeRun.status === 'completed' || nodeRun.status === 'partial')
|
|
228
|
+
.map((nodeRun) => nodeRun.nodeId),
|
|
229
|
+
snapshot: {
|
|
230
|
+
reason: params.checkpointReason,
|
|
231
|
+
currentNodeId: synced.run.currentNodeId,
|
|
232
|
+
waitingNodeId: synced.run.waitingNodeId,
|
|
233
|
+
readyNodeIds: synced.run.readyNodeIds,
|
|
234
|
+
},
|
|
235
|
+
})
|
|
236
|
+
.output('after')
|
|
237
|
+
const checkpoint = yield* parseRowOrFail(
|
|
238
|
+
PlanCheckpointSchema,
|
|
239
|
+
checkpointRaw,
|
|
240
|
+
'createInitializedRunGraph:checkpoint',
|
|
241
|
+
)
|
|
236
242
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
eventType: 'checkpoint-saved',
|
|
243
|
-
message: 'Saved checkpoint 1.',
|
|
244
|
-
emittedBy: 'system',
|
|
245
|
-
detail: {
|
|
246
|
-
checkpointId: recordIdToString(checkpoint.id, TABLES.PLAN_CHECKPOINT),
|
|
247
|
-
reason: params.checkpointReason,
|
|
248
|
-
},
|
|
249
|
-
})
|
|
250
|
-
.output('after')
|
|
251
|
-
params.emittedEvents.push(PlanEventSchema.parse(checkpointEvent))
|
|
243
|
+
const updatedRunRaw = yield* params.tx
|
|
244
|
+
.update(ensureRecordId(synced.run.id, TABLES.PLAN_RUN))
|
|
245
|
+
.content(toRunData(synced.run, { lastCheckpointId: checkpoint.id }))
|
|
246
|
+
.output('after')
|
|
247
|
+
const updatedRun = yield* parseRowOrFail(PlanRunSchema, updatedRunRaw, 'createInitializedRunGraph:updatedRun')
|
|
252
248
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
249
|
+
const checkpointEvent = yield* params.tx
|
|
250
|
+
.create(new RecordId(TABLES.PLAN_EVENT, Bun.randomUUIDv7()))
|
|
251
|
+
.content({
|
|
252
|
+
planSpecId: ensureRecordId(params.spec.id, TABLES.PLAN_SPEC),
|
|
253
|
+
runId: ensureRecordId(updatedRun.id, TABLES.PLAN_RUN),
|
|
254
|
+
eventType: 'checkpoint-saved',
|
|
255
|
+
message: 'Saved checkpoint 1.',
|
|
256
|
+
emittedBy: 'system',
|
|
257
|
+
detail: {
|
|
258
|
+
checkpointId: recordIdToString(checkpoint.id, TABLES.PLAN_CHECKPOINT),
|
|
259
|
+
reason: params.checkpointReason,
|
|
260
|
+
},
|
|
261
|
+
})
|
|
262
|
+
.output('after')
|
|
263
|
+
params.emittedEvents.push(
|
|
264
|
+
yield* parseRowOrFail(PlanEventSchema, checkpointEvent, 'createInitializedRunGraph:checkpointEvent'),
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
return updatedRun
|
|
268
|
+
})
|
|
256
269
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { PlanRunRecord } from '@lota-sdk/shared'
|
|
2
1
|
import { PlanRunSchema } from '@lota-sdk/shared'
|
|
3
2
|
import { Schema, Effect } from 'effect'
|
|
4
3
|
|
|
@@ -6,7 +5,6 @@ import type { RecordIdInput } from '../../db/record-id'
|
|
|
6
5
|
import { ensureRecordId } from '../../db/record-id'
|
|
7
6
|
import type { SurrealDBService } from '../../db/service'
|
|
8
7
|
import { TABLES } from '../../db/tables'
|
|
9
|
-
import { runPromise } from '../../effect/runtime'
|
|
10
8
|
import { toDatabaseDateTime } from '../../utils/date-time'
|
|
11
9
|
import { toRunData } from '../plan/plan-run-data'
|
|
12
10
|
import type { makePlanRunService } from '../plan/plan-run.service'
|
|
@@ -21,7 +19,7 @@ function toPlanScheduleAttachError(operation: string, cause: unknown) {
|
|
|
21
19
|
return new PlanScheduleAttachError({ cause: `${operation}: ${detail}` })
|
|
22
20
|
}
|
|
23
21
|
|
|
24
|
-
function
|
|
22
|
+
export function attachPlanScheduleIfNeeded(params: {
|
|
25
23
|
db: SurrealDBService
|
|
26
24
|
planRunService: ReturnType<typeof makePlanRunService>
|
|
27
25
|
planSchedulerService: ReturnType<typeof makePlanSchedulerService>
|
|
@@ -70,15 +68,3 @@ function attachPlanScheduleIfNeededEffect(params: {
|
|
|
70
68
|
return updatedRun ?? run
|
|
71
69
|
})
|
|
72
70
|
}
|
|
73
|
-
|
|
74
|
-
export function attachPlanScheduleIfNeeded(params: {
|
|
75
|
-
db: SurrealDBService
|
|
76
|
-
planRunService: ReturnType<typeof makePlanRunService>
|
|
77
|
-
planSchedulerService: ReturnType<typeof makePlanSchedulerService>
|
|
78
|
-
organizationId: RecordIdInput
|
|
79
|
-
threadId: RecordIdInput
|
|
80
|
-
runId: RecordIdInput
|
|
81
|
-
planSpecId: RecordIdInput
|
|
82
|
-
}): Promise<PlanRunRecord> {
|
|
83
|
-
return runPromise(attachPlanScheduleIfNeededEffect(params))
|
|
84
|
-
}
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
import { PlanDraftSchema, PlanRunSchema, PlanSpecSchema } from '@lota-sdk/shared'
|
|
11
11
|
import { Context, Schema, Effect, Layer, Match } from 'effect'
|
|
12
12
|
import { RecordId } from 'surrealdb'
|
|
13
|
+
import type { z } from 'zod'
|
|
13
14
|
|
|
14
15
|
import type { RecordIdInput } from '../../db/record-id'
|
|
15
16
|
import { ensureRecordId, recordIdToString } from '../../db/record-id'
|
|
@@ -84,6 +85,17 @@ const effectTryPromise = makeEffectTryPromiseWithMessage(
|
|
|
84
85
|
(message, cause) => new ExecutionPlanServiceError({ message, cause }),
|
|
85
86
|
)
|
|
86
87
|
|
|
88
|
+
function parseRowEffect<TSchema extends z.ZodTypeAny>(
|
|
89
|
+
schema: TSchema,
|
|
90
|
+
value: unknown,
|
|
91
|
+
label: string,
|
|
92
|
+
): Effect.Effect<z.infer<TSchema>, ExecutionPlanServiceError> {
|
|
93
|
+
return Effect.try({
|
|
94
|
+
try: () => schema.parse(value) as z.infer<TSchema>,
|
|
95
|
+
catch: (cause) => new ExecutionPlanServiceError({ message: `Failed to parse ${label}.`, cause }),
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
87
99
|
function toSerializablePlanEffect(
|
|
88
100
|
deps: ExecutionPlanDeps,
|
|
89
101
|
run: PlanRunRecord,
|
|
@@ -285,7 +297,8 @@ function createPlanEffect(
|
|
|
285
297
|
const databaseService = deps.db
|
|
286
298
|
const requireApproval =
|
|
287
299
|
params.requireApproval ?? hasCrossThreadSourceContext(params.sourceThreadId, params.threadId)
|
|
288
|
-
const
|
|
300
|
+
const parsedDraft = yield* parseRowEffect(PlanDraftSchema, params.input, 'plan draft input')
|
|
301
|
+
const preparedDraft = deps.planBuilder.prepareDraft(parsedDraft)
|
|
289
302
|
const validation = deps.planValidator.validateDraft(preparedDraft)
|
|
290
303
|
if (validation.blocking.length > 0) {
|
|
291
304
|
return yield* new BadRequestError({
|
|
@@ -319,7 +332,7 @@ function createPlanEffect(
|
|
|
319
332
|
.output('after'),
|
|
320
333
|
'Failed to create execution plan spec.',
|
|
321
334
|
)
|
|
322
|
-
const spec = PlanSpecSchema
|
|
335
|
+
const spec = yield* parseRowEffect(PlanSpecSchema, createdSpec, 'created plan spec')
|
|
323
336
|
|
|
324
337
|
yield* effectTryPromise(
|
|
325
338
|
() =>
|
|
@@ -391,7 +404,8 @@ function replacePlanEffect(
|
|
|
391
404
|
|
|
392
405
|
const activeSpec = yield* deps.planRun.getPlanSpecById(activeRun.planSpecId)
|
|
393
406
|
const { runId: _runId, reason: _reason, requireApproval: requestedRequireApproval, ...draftInput } = params.input
|
|
394
|
-
const
|
|
407
|
+
const parsedDraft = yield* parseRowEffect(PlanDraftSchema, draftInput, 'plan draft replacement input')
|
|
408
|
+
const preparedDraft = deps.planBuilder.prepareDraft(parsedDraft)
|
|
395
409
|
const validation = deps.planValidator.validateDraft(preparedDraft)
|
|
396
410
|
if (validation.blocking.length > 0) {
|
|
397
411
|
return yield* new BadRequestError({
|
|
@@ -419,7 +433,7 @@ function replacePlanEffect(
|
|
|
419
433
|
.output('after'),
|
|
420
434
|
'Failed to update superseded execution plan spec.',
|
|
421
435
|
)
|
|
422
|
-
const supersededSpec = PlanSpecSchema
|
|
436
|
+
const supersededSpec = yield* parseRowEffect(PlanSpecSchema, updatedSpec, 'superseded plan spec')
|
|
423
437
|
|
|
424
438
|
const updatedRun = yield* effectTryPromise(
|
|
425
439
|
() =>
|
|
@@ -437,7 +451,7 @@ function replacePlanEffect(
|
|
|
437
451
|
.output('after'),
|
|
438
452
|
'Failed to abort previous execution run.',
|
|
439
453
|
)
|
|
440
|
-
const abortedRun = PlanRunSchema
|
|
454
|
+
const abortedRun = yield* parseRowEffect(PlanRunSchema, updatedRun, 'aborted plan run')
|
|
441
455
|
|
|
442
456
|
const createdSpec = yield* effectTryPromise(
|
|
443
457
|
() =>
|
|
@@ -456,7 +470,7 @@ function replacePlanEffect(
|
|
|
456
470
|
.output('after'),
|
|
457
471
|
'Failed to create replacement execution plan spec.',
|
|
458
472
|
)
|
|
459
|
-
const spec = PlanSpecSchema
|
|
473
|
+
const spec = yield* parseRowEffect(PlanSpecSchema, createdSpec, 'replacement plan spec')
|
|
460
474
|
|
|
461
475
|
yield* effectTryPromise(
|
|
462
476
|
() =>
|
|
@@ -523,18 +537,19 @@ function submitPlanTurnResultEffect(
|
|
|
523
537
|
},
|
|
524
538
|
) {
|
|
525
539
|
return Effect.gen(function* () {
|
|
526
|
-
const result = yield*
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
540
|
+
const result = yield* deps.planExecutor
|
|
541
|
+
.submitNodeResult({
|
|
542
|
+
threadId: params.threadId,
|
|
543
|
+
runId: params.runId,
|
|
544
|
+
nodeId: params.nodeId,
|
|
545
|
+
emittedBy: params.emittedBy,
|
|
546
|
+
result: params.input,
|
|
547
|
+
})
|
|
548
|
+
.pipe(
|
|
549
|
+
Effect.mapError(
|
|
550
|
+
(cause) => new ExecutionPlanServiceError({ message: 'Failed to submit execution plan node result.', cause }),
|
|
551
|
+
),
|
|
552
|
+
)
|
|
538
553
|
|
|
539
554
|
const plan = yield* finalizePlanSnapshotEffect(deps, { runId: params.runId, emittedBy: params.emittedBy })
|
|
540
555
|
return buildExecutionPlanToolResult({
|
|
@@ -550,15 +565,13 @@ function resumeRunEffect(
|
|
|
550
565
|
params: { threadId: RecordIdInput; emittedBy: string; input: { runId: string } },
|
|
551
566
|
) {
|
|
552
567
|
return Effect.gen(function* () {
|
|
553
|
-
const result = yield*
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
catch: (cause) => new ExecutionPlanServiceError({ message: 'Failed to resume execution run.', cause }),
|
|
561
|
-
})
|
|
568
|
+
const result = yield* deps.planExecutor
|
|
569
|
+
.resumeRun({ threadId: params.threadId, runId: params.input.runId, emittedBy: params.emittedBy })
|
|
570
|
+
.pipe(
|
|
571
|
+
Effect.mapError(
|
|
572
|
+
(cause) => new ExecutionPlanServiceError({ message: 'Failed to resume execution run.', cause }),
|
|
573
|
+
),
|
|
574
|
+
)
|
|
562
575
|
|
|
563
576
|
const plan = yield* finalizePlanSnapshotEffect(deps, { runId: params.input.runId, emittedBy: params.emittedBy })
|
|
564
577
|
return buildExecutionPlanToolResult({
|
|
@@ -609,7 +622,7 @@ function approvePlanEffect(
|
|
|
609
622
|
.output('after'),
|
|
610
623
|
'Failed to activate execution run.',
|
|
611
624
|
)
|
|
612
|
-
const activatedRun = PlanRunSchema
|
|
625
|
+
const activatedRun = yield* parseRowEffect(PlanRunSchema, updatedRun, 'activated plan run')
|
|
613
626
|
|
|
614
627
|
const synced = yield* effectTryPromise(
|
|
615
628
|
() =>
|
|
@@ -729,7 +742,7 @@ function rejectPlanEffect(
|
|
|
729
742
|
.output('after'),
|
|
730
743
|
'Failed to abort execution run.',
|
|
731
744
|
)
|
|
732
|
-
const rejectedRun = PlanRunSchema
|
|
745
|
+
const rejectedRun = yield* parseRowEffect(PlanRunSchema, updatedRun, 'rejected plan run')
|
|
733
746
|
|
|
734
747
|
yield* emitEvent({
|
|
735
748
|
tx,
|
|
@@ -778,17 +791,19 @@ function respondToApprovalEffect(
|
|
|
778
791
|
const run = yield* deps.planRun.getActiveRunRecord(params.threadId)
|
|
779
792
|
if (!run) return null
|
|
780
793
|
|
|
781
|
-
const plan = yield*
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
794
|
+
const plan = yield* deps.planExecutor
|
|
795
|
+
.submitHumanNodeResponse({
|
|
796
|
+
threadId: params.threadId,
|
|
797
|
+
approvalId: params.input.approvalId,
|
|
798
|
+
respondedBy: params.emittedBy,
|
|
799
|
+
response: params.input.response,
|
|
800
|
+
approvalMessageId: params.input.approvalMessageId,
|
|
801
|
+
})
|
|
802
|
+
.pipe(
|
|
803
|
+
Effect.mapError(
|
|
804
|
+
(cause) => new ExecutionPlanServiceError({ message: 'Failed to submit human approval response.', cause }),
|
|
805
|
+
),
|
|
806
|
+
)
|
|
792
807
|
if (!plan) return null
|
|
793
808
|
|
|
794
809
|
return yield* finalizePlanSnapshotEffect(deps, { runId: run.id, emittedBy: params.emittedBy })
|
|
@@ -825,16 +840,18 @@ function applyHumanInputFromUserMessageEffect(
|
|
|
825
840
|
)
|
|
826
841
|
if (!response) return null
|
|
827
842
|
|
|
828
|
-
const plan = yield*
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
843
|
+
const plan = yield* deps.planExecutor
|
|
844
|
+
.submitHumanNodeResponse({
|
|
845
|
+
threadId: params.threadId,
|
|
846
|
+
respondedBy: params.respondedBy,
|
|
847
|
+
response,
|
|
848
|
+
approvalMessageId: params.message.id,
|
|
849
|
+
})
|
|
850
|
+
.pipe(
|
|
851
|
+
Effect.mapError(
|
|
852
|
+
(cause) => new ExecutionPlanServiceError({ message: 'Failed to submit human node response.', cause }),
|
|
853
|
+
),
|
|
854
|
+
)
|
|
838
855
|
if (!plan) return null
|
|
839
856
|
|
|
840
857
|
return yield* finalizePlanSnapshotEffect(deps, { runId: run.id, emittedBy: params.respondedBy })
|
|
@@ -1010,7 +1027,7 @@ export function makeExecutionPlanService(deps: ExecutionPlanDeps) {
|
|
|
1010
1027
|
export class ExecutionPlanServiceTag extends Context.Service<
|
|
1011
1028
|
ExecutionPlanServiceTag,
|
|
1012
1029
|
ReturnType<typeof makeExecutionPlanService>
|
|
1013
|
-
>()('ExecutionPlanService') {}
|
|
1030
|
+
>()('@lota-sdk/core/ExecutionPlanService') {}
|
|
1014
1031
|
|
|
1015
1032
|
export const ExecutionPlanServiceLive = Layer.effect(
|
|
1016
1033
|
ExecutionPlanServiceTag,
|
|
@@ -141,7 +141,7 @@ export function makeFeedbackLoopService(planRunService: ReturnType<typeof makePl
|
|
|
141
141
|
export class FeedbackLoopServiceTag extends Context.Service<
|
|
142
142
|
FeedbackLoopServiceTag,
|
|
143
143
|
ReturnType<typeof makeFeedbackLoopService>
|
|
144
|
-
>()('FeedbackLoopService') {}
|
|
144
|
+
>()('@lota-sdk/core/FeedbackLoopService') {}
|
|
145
145
|
|
|
146
146
|
export const FeedbackLoopServiceLive = Layer.effect(
|
|
147
147
|
FeedbackLoopServiceTag,
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ConvergenceState,
|
|
3
|
+
ExecutionMode,
|
|
4
|
+
PlanNodeResultSubmission,
|
|
5
|
+
PlanNodeRunRecord,
|
|
6
|
+
PlanNodeSpecRecord,
|
|
7
|
+
PlanRunRecord,
|
|
8
|
+
PlanSpecRecord,
|
|
9
|
+
} from '@lota-sdk/shared'
|
|
2
10
|
import { Context, Effect, Layer } from 'effect'
|
|
3
11
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
12
|
+
import type { ResolvedAgentConfig } from '../config/agent-defaults'
|
|
13
|
+
import { AgentConfigServiceTag } from '../effect/services'
|
|
14
|
+
import type { PlanAgentHeartbeatQueueRuntime } from '../queues/plan-agent-heartbeat.queue'
|
|
15
|
+
import { LotaQueuesServiceTag } from '../queues/queues.service'
|
|
6
16
|
import { routeGraphFullEffect } from './graph-full-routing'
|
|
7
|
-
import type {
|
|
17
|
+
import type { OwnershipDispatcherService } from './ownership-dispatcher.service'
|
|
8
18
|
import { OwnershipDispatcherServiceTag } from './ownership-dispatcher.service'
|
|
9
19
|
import type { makePlanExecutorService } from './plan/plan-executor.service'
|
|
10
20
|
import { PlanExecutorServiceTag } from './plan/plan-executor.service'
|
|
@@ -48,20 +58,36 @@ function decideRerouteAction(params: {
|
|
|
48
58
|
}
|
|
49
59
|
|
|
50
60
|
interface GlobalOrchestratorDeps {
|
|
51
|
-
|
|
61
|
+
agentConfig: ResolvedAgentConfig
|
|
62
|
+
ownershipDispatcherService: Pick<OwnershipDispatcherService, 'dispatchReadyNode'>
|
|
52
63
|
planExecutorService: ReturnType<typeof makePlanExecutorService>
|
|
53
64
|
planRunService: ReturnType<typeof makePlanRunService>
|
|
65
|
+
planAgentHeartbeatQueue: PlanAgentHeartbeatQueueRuntime
|
|
54
66
|
}
|
|
55
67
|
|
|
68
|
+
type DispatchReadyNodeParams = {
|
|
69
|
+
run: PlanRunRecord
|
|
70
|
+
nodeSpecRecord: PlanNodeSpecRecord
|
|
71
|
+
nodeRun: PlanNodeRunRecord
|
|
72
|
+
spec: PlanSpecRecord
|
|
73
|
+
executionModeOverride?: ExecutionMode
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
type DispatchReadyNode = (params: DispatchReadyNodeParams) => Effect.Effect<PlanNodeResultSubmission, unknown, never>
|
|
77
|
+
|
|
56
78
|
export function makeGlobalOrchestratorService(deps: GlobalOrchestratorDeps) {
|
|
79
|
+
const dispatchReadyNode: DispatchReadyNode = (params) => deps.ownershipDispatcherService.dispatchReadyNode(params)
|
|
80
|
+
|
|
57
81
|
return {
|
|
58
82
|
detectConvergence,
|
|
59
83
|
decideRerouteAction,
|
|
60
84
|
routeGraphFull: (params: { threadId: string; runId: string }) =>
|
|
61
85
|
routeGraphFullEffect(params, {
|
|
62
|
-
|
|
86
|
+
agentConfig: deps.agentConfig,
|
|
87
|
+
dispatchReadyNode,
|
|
63
88
|
planExecutorService: deps.planExecutorService,
|
|
64
89
|
planRunService: deps.planRunService,
|
|
90
|
+
planAgentHeartbeatQueue: deps.planAgentHeartbeatQueue,
|
|
65
91
|
}),
|
|
66
92
|
}
|
|
67
93
|
}
|
|
@@ -69,22 +95,30 @@ export function makeGlobalOrchestratorService(deps: GlobalOrchestratorDeps) {
|
|
|
69
95
|
export class GlobalOrchestratorServiceTag extends Context.Service<
|
|
70
96
|
GlobalOrchestratorServiceTag,
|
|
71
97
|
ReturnType<typeof makeGlobalOrchestratorService>
|
|
72
|
-
>()('GlobalOrchestratorService') {}
|
|
98
|
+
>()('@lota-sdk/core/GlobalOrchestratorService') {}
|
|
73
99
|
|
|
74
100
|
export const GlobalOrchestratorServiceLive = Layer.effect(
|
|
75
101
|
GlobalOrchestratorServiceTag,
|
|
76
102
|
Effect.gen(function* () {
|
|
103
|
+
const agentConfig = yield* AgentConfigServiceTag
|
|
77
104
|
const ownershipDispatcherService = yield* OwnershipDispatcherServiceTag
|
|
78
105
|
const planExecutorService = yield* PlanExecutorServiceTag
|
|
79
106
|
const planRunService = yield* PlanRunServiceTag
|
|
80
|
-
|
|
107
|
+
const queues = yield* LotaQueuesServiceTag
|
|
108
|
+
return makeGlobalOrchestratorService({
|
|
109
|
+
agentConfig,
|
|
110
|
+
ownershipDispatcherService,
|
|
111
|
+
planExecutorService,
|
|
112
|
+
planRunService,
|
|
113
|
+
planAgentHeartbeatQueue: queues.planAgentHeartbeat,
|
|
114
|
+
})
|
|
81
115
|
}),
|
|
82
116
|
)
|
|
83
117
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return
|
|
90
|
-
}
|
|
118
|
+
export const routeGraphFull = Effect.fn('GlobalOrchestrator.routeGraphFull')(function* (params: {
|
|
119
|
+
threadId: string
|
|
120
|
+
runId: string
|
|
121
|
+
}) {
|
|
122
|
+
const globalOrchestratorService = yield* GlobalOrchestratorServiceTag
|
|
123
|
+
return yield* globalOrchestratorService.routeGraphFull(params)
|
|
124
|
+
})
|