@botbotgo/agent-harness 0.0.95 → 0.0.96

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.
@@ -0,0 +1,94 @@
1
+ # agent-harness feature: schema version for this declarative config object.
2
+ apiVersion: agent-harness/v1alpha1
3
+ # agent-harness feature: catalog of reusable runtime entry profiles layered on workflow resources.
4
+ kind: RuntimeProfiles
5
+ spec:
6
+ - id: coding-runtime
7
+ workflowRef: langgraph-workflow/coding-loop
8
+ defaults:
9
+ approvalPolicy: safe-default
10
+ memoryPolicy: project-facts-only
11
+ directAnswerFirst: false
12
+ watchGithubActionsAfterPush: true
13
+ allowPushToMaster: false
14
+ closeGithubIssueOnSuccess: false
15
+ requiredAgents:
16
+ - coderAgent
17
+ optionalAgents:
18
+ - verifierAgent
19
+ - id: personal-assistant
20
+ workflowRef: langgraph-workflow/assistant-loop
21
+ defaults:
22
+ approvalPolicy: human-before-side-effects
23
+ memoryPolicy: user-preferences-and-routines
24
+ directAnswerFirst: true
25
+ persistDurableMemory: true
26
+ optionalAgents:
27
+ - defaultResearchAgent
28
+ - defaultWritingAgent
29
+ - defaultSchedulingAgent
30
+ - defaultWorkerAgent
31
+ - id: research-runtime
32
+ workflowRef: langgraph-workflow/research-loop
33
+ defaults:
34
+ approvalPolicy: minimal
35
+ memoryPolicy: report-summary-only
36
+ requireSourceGrounding: true
37
+ requireCoverageReview: true
38
+ requiredAgents:
39
+ - gathererAgent
40
+ - analystAgent
41
+ optionalAgents:
42
+ - synthesizerAgent
43
+ - id: approval-review-runtime
44
+ workflowRef: langgraph-workflow/approval-review-loop
45
+ defaults:
46
+ approvalPolicy: always-required
47
+ memoryPolicy: none
48
+ executeAfterApproval: true
49
+ auditTrail: full
50
+ requiredAgents:
51
+ - preparerAgent
52
+ optionalAgents:
53
+ - reviewerAgent
54
+ - id: claw-style-assistant
55
+ workflowRef: langgraph-workflow/assistant-loop
56
+ defaults:
57
+ approvalPolicy: human-before-side-effects
58
+ memoryPolicy: user-preferences-and-stable-context
59
+ channelFirst: true
60
+ attachmentAware: true
61
+ sessionMemory: thread-scoped
62
+ optionalAgents:
63
+ - defaultWorkerAgent
64
+ - id: chat-operator
65
+ workflowRef: langgraph-workflow/chat-router-loop
66
+ defaults:
67
+ approvalPolicy: route-dependent
68
+ memoryPolicy: thread-only
69
+ directAnswerFirst: true
70
+ optionalAgents:
71
+ - codingAgent
72
+ - researchAgent
73
+ - assistantAgent
74
+ - approvalAgent
75
+ - id: copilot-sidecar
76
+ workflowRef: langgraph-workflow/coding-lite-loop
77
+ defaults:
78
+ approvalPolicy: no-push
79
+ memoryPolicy: repo-context-only
80
+ directAnswerFirst: false
81
+ allowRepositoryEdits: true
82
+ allowPushToMaster: false
83
+ runIntegrationVerification: false
84
+ requiredAgents:
85
+ - coderAgent
86
+ - id: task-delegation-hub
87
+ workflowRef: langgraph-workflow/delegation-loop
88
+ defaults:
89
+ approvalPolicy: worker-dependent
90
+ memoryPolicy: task-summary-only
91
+ routingStrategy: planner-first
92
+ reviewerEnabled: true
93
+ optionalAgents:
94
+ - defaultWorkerFallback
@@ -320,10 +320,81 @@ export type RunResult = {
320
320
  artifacts?: ArtifactRecord[];
321
321
  metadata?: Record<string, unknown>;
322
322
  };
323
- export type RunListeners = {
323
+ export type NormalizedUpstreamEvent = {
324
+ kind: "text-delta";
325
+ source: "model" | "state";
326
+ text: string;
327
+ ns?: string[];
328
+ nodeName?: string;
329
+ } | {
330
+ kind: "reasoning-delta";
331
+ text: string;
332
+ ns?: string[];
333
+ nodeName?: string;
334
+ } | {
335
+ kind: "tool-start";
336
+ toolName: string;
337
+ input?: unknown;
338
+ ns?: string[];
339
+ nodeName?: string;
340
+ } | {
341
+ kind: "tool-end";
342
+ toolName: string;
343
+ output?: unknown;
344
+ isError?: boolean;
345
+ ns?: string[];
346
+ nodeName?: string;
347
+ } | {
348
+ kind: "agent-step";
349
+ label: string;
350
+ ns?: string[];
351
+ nodeName?: string;
352
+ } | {
353
+ kind: "interrupt";
354
+ interrupt: unknown;
355
+ ns?: string[];
356
+ nodeName?: string;
357
+ } | {
358
+ kind: "run-event";
359
+ eventName: string;
360
+ data?: Record<string, unknown>;
361
+ ns?: string[];
362
+ nodeName?: string;
363
+ };
364
+ export type CompatibleStreamPart = {
365
+ type: "messages";
366
+ ns: string[];
367
+ data: [unknown, Record<string, unknown>];
368
+ } | {
369
+ type: "updates";
370
+ ns: string[];
371
+ data: Record<string, unknown>;
372
+ } | {
373
+ type: "custom";
374
+ ns: string[];
375
+ data: unknown;
376
+ };
377
+ export type UpstreamRuntimeEvent = {
378
+ format: "langgraph-v2";
379
+ /** @deprecated Prefer streamPart plus raw/event/name/data/ns for upstream-aligned consumption. */
380
+ normalized: NormalizedUpstreamEvent;
381
+ streamPart: CompatibleStreamPart;
382
+ raw: unknown;
383
+ event?: string;
384
+ name?: string;
385
+ runType?: string;
386
+ data?: Record<string, unknown>;
387
+ metadata?: Record<string, unknown>;
388
+ tags?: string[];
389
+ ns?: string[];
390
+ };
391
+ export type RuntimeListeners = {
392
+ onEvent?: (event: HarnessEvent) => void | Promise<void>;
393
+ };
394
+ export type FrontendStreamListeners = {
324
395
  onChunk?: (chunk: string) => void | Promise<void>;
325
396
  onContentBlocks?: (blocks: unknown[]) => void | Promise<void>;
326
- onEvent?: (event: HarnessEvent) => void | Promise<void>;
397
+ onUpstreamEvent?: (event: UpstreamRuntimeEvent) => void | Promise<void>;
327
398
  onReasoning?: (chunk: string) => void | Promise<void>;
328
399
  onStep?: (step: string) => void | Promise<void>;
329
400
  onToolResult?: (item: {
@@ -332,6 +403,7 @@ export type RunListeners = {
332
403
  isError?: boolean;
333
404
  }) => void | Promise<void>;
334
405
  };
406
+ export type RunListeners = RuntimeListeners & FrontendStreamListeners;
335
407
  export type MessageContentPart = {
336
408
  type: "text";
337
409
  text: string;
@@ -353,6 +425,8 @@ export type RunStartOptions = {
353
425
  priority?: number;
354
426
  invocation?: InvocationEnvelope;
355
427
  listeners?: RunListeners;
428
+ runtimeListeners?: RuntimeListeners;
429
+ frontendListeners?: FrontendStreamListeners;
356
430
  };
357
431
  export type RunDecisionOptions = {
358
432
  threadId: string;
@@ -361,11 +435,19 @@ export type RunDecisionOptions = {
361
435
  decision: "approve" | "edit" | "reject";
362
436
  editedInput?: Record<string, unknown>;
363
437
  listeners?: RunListeners;
438
+ runtimeListeners?: RuntimeListeners;
439
+ frontendListeners?: FrontendStreamListeners;
364
440
  };
365
441
  export type RunOptions = RunStartOptions | RunDecisionOptions;
366
442
  export type HarnessStreamItem = {
367
443
  type: "event";
368
444
  event: HarnessEvent;
445
+ } | {
446
+ type: "upstream-event";
447
+ threadId: string;
448
+ runId: string;
449
+ agentId: string;
450
+ event: UpstreamRuntimeEvent;
369
451
  } | {
370
452
  type: "result";
371
453
  result: RunResult;
@@ -1 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.94";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.95";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.94";
1
+ export const AGENT_HARNESS_VERSION = "0.0.95";
@@ -13,7 +13,7 @@ import { tools as openAIProviderTools } from "@langchain/openai";
13
13
  import { createAgent, humanInTheLoopMiddleware, initChatModel } from "langchain";
14
14
  import { z } from "zod";
15
15
  import { extractEmptyAssistantMessageFailure, extractContentBlocks, extractOutputContent, extractReasoningText, extractToolFallbackContext, extractVisibleOutput, salvageToolArgs, isLikelyToolArgsObject, isToolCallParseFailure, STRICT_TOOL_JSON_INSTRUCTION, sanitizeVisibleText, tryParseJson, wrapResolvedModel, } from "./parsing/output-parsing.js";
16
- import { computeIncrementalOutput, extractAgentStep, extractInterruptPayload, extractReasoningStreamOutput, extractStateStreamOutput, extractVisibleStreamOutput, extractTerminalStreamOutput, extractToolResult, normalizeTerminalOutputKey, readStreamDelta, } from "./parsing/stream-event-parsing.js";
16
+ import { computeIncrementalOutput, extractAgentStep, extractInterruptPayload, normalizeUpstreamRuntimeEvent, extractReasoningStreamOutput, extractStateStreamOutput, extractVisibleStreamOutput, extractTerminalStreamOutput, extractToolResult, normalizeTerminalOutputKey, readStreamDelta, } from "./parsing/stream-event-parsing.js";
17
17
  import { wrapToolForExecution } from "./tool-hitl.js";
18
18
  import { resolveDeclaredMiddleware } from "./declared-middleware.js";
19
19
  import { extractMessageText, normalizeMessageContent } from "../utils/message-content.js";
@@ -1333,13 +1333,13 @@ export class AgentRuntimeAdapter {
1333
1333
  .map((edge) => this.normalizeLangGraphWorkflowEdge(edge))
1334
1334
  .filter((edge) => edge !== null);
1335
1335
  }
1336
- shouldFollowLangGraphEdge(edge, state, executorResult) {
1336
+ shouldFollowLangGraphEdge(edge, state, currentResult) {
1337
1337
  const condition = edge.when?.toLowerCase().trim();
1338
1338
  if (!condition || condition === "always") {
1339
1339
  return true;
1340
1340
  }
1341
1341
  const review = state.review?.toLowerCase() ?? "";
1342
- const hasResult = Boolean(executorResult);
1342
+ const hasResult = Boolean(currentResult);
1343
1343
  switch (condition) {
1344
1344
  case "has_plan":
1345
1345
  return Boolean(state.plan?.trim());
@@ -1365,9 +1365,9 @@ export class AgentRuntimeAdapter {
1365
1365
  return false;
1366
1366
  }
1367
1367
  }
1368
- listLangGraphWorkflowNextNodes(workflow, nodeId, state, executorResult) {
1368
+ listLangGraphWorkflowNextNodes(workflow, nodeId, state, currentResult) {
1369
1369
  return this.listLangGraphWorkflowEdges(workflow)
1370
- .filter((edge) => edge.from === nodeId && this.shouldFollowLangGraphEdge(edge, state, executorResult))
1370
+ .filter((edge) => edge.from === nodeId && this.shouldFollowLangGraphEdge(edge, state, currentResult))
1371
1371
  .map((edge) => edge.to);
1372
1372
  }
1373
1373
  extractInvocationRequestText(request) {
@@ -1631,7 +1631,7 @@ export class AgentRuntimeAdapter {
1631
1631
  `User request:\n${userInputText}`,
1632
1632
  ...(workflowState.plan ? ["", `Workflow plan:\n${workflowState.plan}`] : []),
1633
1633
  ...(workflowState.review ? ["", `Workflow review:\n${workflowState.review}`] : []),
1634
- ...(activeResult ? ["", `Current executor result:\n${extractVisibleOutput(activeResult) || JSON.stringify(activeResult, null, 2)}`] : []),
1634
+ ...(activeResult ? ["", `Current result:\n${extractVisibleOutput(activeResult) || JSON.stringify(activeResult, null, 2)}`] : []),
1635
1635
  "",
1636
1636
  "Complete the delegated subagent work and return concise results.",
1637
1637
  ].join("\n");
@@ -1746,7 +1746,7 @@ export class AgentRuntimeAdapter {
1746
1746
  workflowState.review = await this.invokeWorkflowNodeModel(reviewerModel, reviewerPrompt, [
1747
1747
  `User request:\n${userInputText}`,
1748
1748
  "",
1749
- `Executor result:\n${extractVisibleOutput(activeResult) || JSON.stringify(activeResult, null, 2)}`,
1749
+ `Current result:\n${extractVisibleOutput(activeResult) || JSON.stringify(activeResult, null, 2)}`,
1750
1750
  ].join("\n"));
1751
1751
  }
1752
1752
  else if ((nodeRole === "finalizer" || nodeRole === "final") && activeResult) {
@@ -1988,7 +1988,7 @@ export class AgentRuntimeAdapter {
1988
1988
  workflowState.review = await this.invokeWorkflowNodeModel(reviewerModel, reviewerPrompt, [
1989
1989
  `User request:\n${userInputText}`,
1990
1990
  "",
1991
- `Executor result:\n${extractVisibleOutput(activeResult) || JSON.stringify(activeResult, null, 2)}`,
1991
+ `Current result:\n${extractVisibleOutput(activeResult) || JSON.stringify(activeResult, null, 2)}`,
1992
1992
  ].join("\n"));
1993
1993
  if (workflowState.review) {
1994
1994
  yield { kind: "reasoning", content: workflowState.review };
@@ -2541,6 +2541,7 @@ export class AgentRuntimeAdapter {
2541
2541
  const seenTerminalOutputs = new Set();
2542
2542
  let lastStep = "";
2543
2543
  for await (const event of this.iterateWithTimeout(events, streamIdleTimeoutMs, "agent streamEvents", streamDeadlineAt, invokeTimeoutMs)) {
2544
+ yield { kind: "upstream-event", event: normalizeUpstreamRuntimeEvent(event) };
2544
2545
  const interruptPayload = extractInterruptPayload(event);
2545
2546
  if (interruptPayload) {
2546
2547
  yield { kind: "interrupt", content: interruptPayload };
@@ -118,6 +118,7 @@ export declare class AgentHarnessRuntime {
118
118
  private acquireRunSlot;
119
119
  private dropPendingRunSlot;
120
120
  private dispatchRunListeners;
121
+ private resolveRunListeners;
121
122
  run(options: RunOptions): Promise<RunResult>;
122
123
  streamEvents(options: RunStartOptions): AsyncGenerator<HarnessStreamItem>;
123
124
  resume(options: ResumeOptions): Promise<RunResult>;
@@ -2,6 +2,7 @@ import { AUTO_AGENT_ID } from "../contracts/types.js";
2
2
  import { SqlitePersistence } from "../persistence/sqlite-store.js";
3
3
  import { createPersistentId } from "../utils/id.js";
4
4
  import { AGENT_INTERRUPT_SENTINEL_PREFIX, AgentRuntimeAdapter, RuntimeOperationTimeoutError } from "./agent-runtime-adapter.js";
5
+ import { normalizeUpstreamRuntimeEvent } from "./parsing/stream-event-parsing.js";
5
6
  import { createResourceBackendResolver, createResourceToolResolver } from "../resource/resource.js";
6
7
  import { EventBus } from "./event-bus.js";
7
8
  import { PolicyEngine } from "./policy-engine.js";
@@ -1031,6 +1032,10 @@ export class AgentHarnessRuntime {
1031
1032
  await this.notifyListener(listeners.onEvent, item.event);
1032
1033
  continue;
1033
1034
  }
1035
+ if (item.type === "upstream-event") {
1036
+ await this.notifyListener(listeners.onUpstreamEvent, item.event);
1037
+ continue;
1038
+ }
1034
1039
  if (item.type === "result") {
1035
1040
  latestResult = item.result;
1036
1041
  continue;
@@ -1084,6 +1089,19 @@ export class AgentHarnessRuntime {
1084
1089
  pendingActionId: thread.pendingDecision?.pendingActionId,
1085
1090
  };
1086
1091
  }
1092
+ resolveRunListeners(options) {
1093
+ const runtimeListeners = "runtimeListeners" in options ? options.runtimeListeners : undefined;
1094
+ const frontendListeners = "frontendListeners" in options ? options.frontendListeners : undefined;
1095
+ const listeners = options.listeners;
1096
+ if (!listeners && !runtimeListeners && !frontendListeners) {
1097
+ return undefined;
1098
+ }
1099
+ return {
1100
+ ...(runtimeListeners ?? {}),
1101
+ ...(frontendListeners ?? {}),
1102
+ ...(listeners ?? {}),
1103
+ };
1104
+ }
1087
1105
  async run(options) {
1088
1106
  if (this.isDecisionRun(options)) {
1089
1107
  const resumeOptions = {
@@ -1095,8 +1113,9 @@ export class AgentHarnessRuntime {
1095
1113
  };
1096
1114
  return this.resume(resumeOptions);
1097
1115
  }
1098
- if (options.listeners) {
1099
- return this.dispatchRunListeners(this.streamEvents(options), options.listeners);
1116
+ const resolvedListeners = this.resolveRunListeners(options);
1117
+ if (resolvedListeners) {
1118
+ return this.dispatchRunListeners(this.streamEvents(options), resolvedListeners);
1100
1119
  }
1101
1120
  const invocation = this.normalizeInvocationEnvelope(options);
1102
1121
  const selectedAgentId = await this.resolveSelectedAgentId(options.input, options.agentId, options.threadId);
@@ -1191,6 +1210,18 @@ export class AgentHarnessRuntime {
1191
1210
  ? { kind: "interrupt", content: chunk.slice(AGENT_INTERRUPT_SENTINEL_PREFIX.length) }
1192
1211
  : { kind: "content", content: chunk }
1193
1212
  : chunk;
1213
+ if (normalizedChunk.kind === "upstream-event") {
1214
+ yield {
1215
+ type: "upstream-event",
1216
+ threadId,
1217
+ runId,
1218
+ agentId: selectedAgentId,
1219
+ event: normalizedChunk.event.format === "langgraph-v2"
1220
+ ? normalizedChunk.event
1221
+ : normalizeUpstreamRuntimeEvent(normalizedChunk.event.raw ?? normalizedChunk.event),
1222
+ };
1223
+ continue;
1224
+ }
1194
1225
  if (normalizedChunk.kind === "interrupt") {
1195
1226
  const checkpointRef = `checkpoints/${threadId}/${runId}/cp-1`;
1196
1227
  const waitingEvent = await this.setRunStateAndEmit(threadId, runId, 6, "waiting_for_approval", {
@@ -27,135 +27,135 @@ export function resolveLangGraphPresetWorkflow(presetName, options = {}) {
27
27
  return undefined;
28
28
  case "react":
29
29
  return {
30
- entryNode: "executor",
30
+ entryNode: "step1",
31
31
  nodes: [
32
- { id: "executor", kind: "agent" },
32
+ { id: "step1", kind: "agent" },
33
33
  ],
34
34
  edges: [],
35
35
  };
36
36
  case "prompt-chaining":
37
37
  case "plan-execute":
38
38
  return {
39
- entryNode: "planner",
39
+ entryNode: "step1",
40
40
  nodes: [
41
- { id: "planner", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
42
- { id: "executor", kind: "agent" },
43
- { id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
41
+ { id: "step1", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
42
+ { id: "step2", kind: "agent" },
43
+ { id: "step3", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
44
44
  ],
45
45
  edges: [
46
- { from: "planner", to: "executor" },
47
- { from: "executor", to: "finalizer", when: "has_result" },
46
+ { from: "step1", to: "step2" },
47
+ { from: "step2", to: "step3", when: "has_result" },
48
48
  ],
49
49
  };
50
50
  case "routing": {
51
51
  const agent = requireAgent("routing", options);
52
52
  return {
53
- entryNode: "planner",
53
+ entryNode: "step1",
54
54
  nodes: [
55
- { id: "planner", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
56
- { id: "worker", kind: "agent", agent },
57
- { id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
55
+ { id: "step1", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
56
+ { id: "step2", kind: "agent", agent },
57
+ { id: "step3", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
58
58
  ],
59
59
  edges: [
60
- { from: "planner", to: "worker" },
61
- { from: "worker", to: "finalizer", when: "has_result" },
60
+ { from: "step1", to: "step2" },
61
+ { from: "step2", to: "step3", when: "has_result" },
62
62
  ],
63
63
  };
64
64
  }
65
65
  case "parallelization": {
66
66
  const agent = requireAgent("parallelization", options);
67
67
  return {
68
- entryNode: "planner",
68
+ entryNode: "step1",
69
69
  nodes: [
70
- { id: "planner", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
71
- { id: "worker", kind: "agent", agent },
72
- { id: "reviewer", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
73
- { id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
70
+ { id: "step1", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
71
+ { id: "step2", kind: "agent", agent },
72
+ { id: "step3", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
73
+ { id: "step4", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
74
74
  ],
75
75
  edges: [
76
- { from: "planner", to: "worker" },
77
- { from: "worker", to: "reviewer", when: "has_result" },
78
- { from: "reviewer", to: "finalizer", when: "review_ok" },
76
+ { from: "step1", to: "step2" },
77
+ { from: "step2", to: "step3", when: "has_result" },
78
+ { from: "step3", to: "step4", when: "review_ok" },
79
79
  ],
80
80
  };
81
81
  }
82
82
  case "review-loop":
83
83
  return {
84
- entryNode: "planner",
84
+ entryNode: "step1",
85
85
  nodes: [
86
- { id: "planner", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
87
- { id: "executor", kind: "agent" },
88
- { id: "reviewer", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
89
- { id: "replanner", kind: "llm", role: "replanner", prompt: DEFAULT_REPLANNER_PROMPT },
90
- { id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
86
+ { id: "step1", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
87
+ { id: "step2", kind: "agent" },
88
+ { id: "step3", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
89
+ { id: "step4", kind: "llm", role: "replanner", prompt: DEFAULT_REPLANNER_PROMPT },
90
+ { id: "step5", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
91
91
  ],
92
92
  edges: [
93
- { from: "planner", to: "executor" },
94
- { from: "executor", to: "reviewer", when: "has_result" },
95
- { from: "reviewer", to: "finalizer", when: "review_ok" },
96
- { from: "reviewer", to: "replanner", when: "review_incomplete" },
97
- { from: "replanner", to: "executor", when: "has_plan" },
93
+ { from: "step1", to: "step2" },
94
+ { from: "step2", to: "step3", when: "has_result" },
95
+ { from: "step3", to: "step5", when: "review_ok" },
96
+ { from: "step3", to: "step4", when: "review_incomplete" },
97
+ { from: "step4", to: "step2", when: "has_plan" },
98
98
  ],
99
99
  };
100
100
  case "evaluator-optimizer":
101
101
  return {
102
- entryNode: "executor",
102
+ entryNode: "step1",
103
103
  nodes: [
104
- { id: "executor", kind: "agent" },
105
- { id: "reviewer", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
106
- { id: "replanner", kind: "llm", role: "replanner", prompt: DEFAULT_REPLANNER_PROMPT },
107
- { id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
104
+ { id: "step1", kind: "agent" },
105
+ { id: "step2", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
106
+ { id: "step3", kind: "llm", role: "replanner", prompt: DEFAULT_REPLANNER_PROMPT },
107
+ { id: "step4", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
108
108
  ],
109
109
  edges: [
110
- { from: "executor", to: "reviewer", when: "has_result" },
111
- { from: "reviewer", to: "finalizer", when: "review_ok" },
112
- { from: "reviewer", to: "replanner", when: "review_incomplete" },
113
- { from: "replanner", to: "executor", when: "has_plan" },
110
+ { from: "step1", to: "step2", when: "has_result" },
111
+ { from: "step2", to: "step4", when: "review_ok" },
112
+ { from: "step2", to: "step3", when: "review_incomplete" },
113
+ { from: "step3", to: "step1", when: "has_plan" },
114
114
  ],
115
115
  };
116
116
  case "approval-gate":
117
117
  return {
118
- entryNode: "planner",
118
+ entryNode: "step1",
119
119
  nodes: [
120
- { id: "planner", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
121
- { id: "approval", kind: "approval" },
122
- { id: "executor", kind: "agent" },
123
- { id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
120
+ { id: "step1", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
121
+ { id: "step2", kind: "approval" },
122
+ { id: "step3", kind: "agent" },
123
+ { id: "step4", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
124
124
  ],
125
125
  edges: [
126
- { from: "planner", to: "approval" },
127
- { from: "approval", to: "executor", when: "approval_approved" },
128
- { from: "approval", to: "executor", when: "approval_edited" },
129
- { from: "executor", to: "finalizer", when: "has_result" },
126
+ { from: "step1", to: "step2" },
127
+ { from: "step2", to: "step3", when: "approval_approved" },
128
+ { from: "step2", to: "step3", when: "approval_edited" },
129
+ { from: "step3", to: "step4", when: "has_result" },
130
130
  ],
131
131
  };
132
132
  case "handoff": {
133
133
  const agent = requireAgent("handoff", options);
134
134
  return {
135
- entryNode: "worker",
135
+ entryNode: "step1",
136
136
  nodes: [
137
- { id: "worker", kind: "agent", agent },
138
- { id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
137
+ { id: "step1", kind: "agent", agent },
138
+ { id: "step2", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
139
139
  ],
140
140
  edges: [
141
- { from: "worker", to: "finalizer", when: "has_result" },
141
+ { from: "step1", to: "step2", when: "has_result" },
142
142
  ],
143
143
  };
144
144
  }
145
145
  case "orchestrator-workers": {
146
146
  const agent = requireAgent("orchestrator-workers", options);
147
147
  return {
148
- entryNode: "planner",
148
+ entryNode: "step1",
149
149
  nodes: [
150
- { id: "planner", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
151
- { id: "worker", kind: "agent", agent },
152
- { id: "reviewer", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
153
- { id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
150
+ { id: "step1", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
151
+ { id: "step2", kind: "agent", agent },
152
+ { id: "step3", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
153
+ { id: "step4", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
154
154
  ],
155
155
  edges: [
156
- { from: "planner", to: "worker" },
157
- { from: "worker", to: "reviewer", when: "has_result" },
158
- { from: "reviewer", to: "finalizer", when: "review_ok" },
156
+ { from: "step1", to: "step2" },
157
+ { from: "step2", to: "step3", when: "has_result" },
158
+ { from: "step3", to: "step4", when: "review_ok" },
159
159
  ],
160
160
  };
161
161
  }