@botbotgo/agent-harness 0.0.93 → 0.0.95
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/README.md +34 -4
- package/README.zh.md +32 -2
- package/dist/config/workflows/langgraph-workflows.yaml +79 -53
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/agent-runtime-adapter.d.ts +2 -1
- package/dist/runtime/agent-runtime-adapter.js +314 -212
- package/dist/runtime/langgraph-presets.d.ts +4 -2
- package/dist/runtime/langgraph-presets.js +45 -45
- package/dist/runtime/langgraph-profiles.d.ts +6 -0
- package/dist/runtime/langgraph-profiles.js +206 -0
- package/dist/workspace/agent-binding-compiler.js +33 -4
- package/package.json +1 -1
|
@@ -2,7 +2,9 @@ type LangGraphPresetNode = {
|
|
|
2
2
|
id: string;
|
|
3
3
|
kind: string;
|
|
4
4
|
prompt?: string;
|
|
5
|
-
|
|
5
|
+
role?: string;
|
|
6
|
+
agent?: string;
|
|
7
|
+
tool?: string;
|
|
6
8
|
};
|
|
7
9
|
type LangGraphPresetEdge = {
|
|
8
10
|
from: string;
|
|
@@ -16,7 +18,7 @@ export type LangGraphPresetWorkflow = {
|
|
|
16
18
|
};
|
|
17
19
|
export type LangGraphPresetName = "react" | "prompt-chaining" | "routing" | "parallelization" | "plan-execute" | "review-loop" | "evaluator-optimizer" | "approval-gate" | "handoff" | "orchestrator-workers";
|
|
18
20
|
type LangGraphPresetOptions = {
|
|
19
|
-
|
|
21
|
+
agent?: string;
|
|
20
22
|
};
|
|
21
23
|
export declare const SUPPORTED_LANGGRAPH_PRESETS: LangGraphPresetName[];
|
|
22
24
|
export declare function resolveLangGraphPresetWorkflow(presetName: string | undefined, options?: LangGraphPresetOptions): LangGraphPresetWorkflow | undefined;
|
|
@@ -14,11 +14,11 @@ export const SUPPORTED_LANGGRAPH_PRESETS = [
|
|
|
14
14
|
"handoff",
|
|
15
15
|
"orchestrator-workers",
|
|
16
16
|
];
|
|
17
|
-
function
|
|
18
|
-
if (typeof options.
|
|
19
|
-
return options.
|
|
17
|
+
function requireAgent(preset, options) {
|
|
18
|
+
if (typeof options.agent === "string" && options.agent.trim()) {
|
|
19
|
+
return options.agent.trim();
|
|
20
20
|
}
|
|
21
|
-
throw new Error(`LangGraph preset ${preset} requires config.
|
|
21
|
+
throw new Error(`LangGraph preset ${preset} requires config.agent`);
|
|
22
22
|
}
|
|
23
23
|
export function resolveLangGraphPresetWorkflow(presetName, options = {}) {
|
|
24
24
|
switch (presetName) {
|
|
@@ -29,7 +29,7 @@ export function resolveLangGraphPresetWorkflow(presetName, options = {}) {
|
|
|
29
29
|
return {
|
|
30
30
|
entryNode: "executor",
|
|
31
31
|
nodes: [
|
|
32
|
-
{ id: "executor", kind: "
|
|
32
|
+
{ id: "executor", kind: "agent" },
|
|
33
33
|
],
|
|
34
34
|
edges: [],
|
|
35
35
|
};
|
|
@@ -38,9 +38,9 @@ export function resolveLangGraphPresetWorkflow(presetName, options = {}) {
|
|
|
38
38
|
return {
|
|
39
39
|
entryNode: "planner",
|
|
40
40
|
nodes: [
|
|
41
|
-
{ id: "planner", kind: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
42
|
-
{ id: "executor", kind: "
|
|
43
|
-
{ id: "finalizer", kind: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
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 },
|
|
44
44
|
],
|
|
45
45
|
edges: [
|
|
46
46
|
{ from: "planner", to: "executor" },
|
|
@@ -48,33 +48,33 @@ export function resolveLangGraphPresetWorkflow(presetName, options = {}) {
|
|
|
48
48
|
],
|
|
49
49
|
};
|
|
50
50
|
case "routing": {
|
|
51
|
-
const
|
|
51
|
+
const agent = requireAgent("routing", options);
|
|
52
52
|
return {
|
|
53
53
|
entryNode: "planner",
|
|
54
54
|
nodes: [
|
|
55
|
-
{ id: "planner", kind: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
56
|
-
{ id: "
|
|
57
|
-
{ id: "finalizer", kind: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
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 },
|
|
58
58
|
],
|
|
59
59
|
edges: [
|
|
60
|
-
{ from: "planner", to: "
|
|
61
|
-
{ from: "
|
|
60
|
+
{ from: "planner", to: "worker" },
|
|
61
|
+
{ from: "worker", to: "finalizer", when: "has_result" },
|
|
62
62
|
],
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
case "parallelization": {
|
|
66
|
-
const
|
|
66
|
+
const agent = requireAgent("parallelization", options);
|
|
67
67
|
return {
|
|
68
68
|
entryNode: "planner",
|
|
69
69
|
nodes: [
|
|
70
|
-
{ id: "planner", kind: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
71
|
-
{ id: "
|
|
72
|
-
{ id: "reviewer", kind: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
|
|
73
|
-
{ id: "finalizer", kind: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
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 },
|
|
74
74
|
],
|
|
75
75
|
edges: [
|
|
76
|
-
{ from: "planner", to: "
|
|
77
|
-
{ from: "
|
|
76
|
+
{ from: "planner", to: "worker" },
|
|
77
|
+
{ from: "worker", to: "reviewer", when: "has_result" },
|
|
78
78
|
{ from: "reviewer", to: "finalizer", when: "review_ok" },
|
|
79
79
|
],
|
|
80
80
|
};
|
|
@@ -83,11 +83,11 @@ export function resolveLangGraphPresetWorkflow(presetName, options = {}) {
|
|
|
83
83
|
return {
|
|
84
84
|
entryNode: "planner",
|
|
85
85
|
nodes: [
|
|
86
|
-
{ id: "planner", kind: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
87
|
-
{ id: "executor", kind: "
|
|
88
|
-
{ id: "reviewer", kind: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
|
|
89
|
-
{ id: "replanner", kind: "replanner", prompt: DEFAULT_REPLANNER_PROMPT },
|
|
90
|
-
{ id: "finalizer", kind: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
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 },
|
|
91
91
|
],
|
|
92
92
|
edges: [
|
|
93
93
|
{ from: "planner", to: "executor" },
|
|
@@ -101,10 +101,10 @@ export function resolveLangGraphPresetWorkflow(presetName, options = {}) {
|
|
|
101
101
|
return {
|
|
102
102
|
entryNode: "executor",
|
|
103
103
|
nodes: [
|
|
104
|
-
{ id: "executor", kind: "
|
|
105
|
-
{ id: "reviewer", kind: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
|
|
106
|
-
{ id: "replanner", kind: "replanner", prompt: DEFAULT_REPLANNER_PROMPT },
|
|
107
|
-
{ id: "finalizer", kind: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
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 },
|
|
108
108
|
],
|
|
109
109
|
edges: [
|
|
110
110
|
{ from: "executor", to: "reviewer", when: "has_result" },
|
|
@@ -117,10 +117,10 @@ export function resolveLangGraphPresetWorkflow(presetName, options = {}) {
|
|
|
117
117
|
return {
|
|
118
118
|
entryNode: "planner",
|
|
119
119
|
nodes: [
|
|
120
|
-
{ id: "planner", kind: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
120
|
+
{ id: "planner", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
121
121
|
{ id: "approval", kind: "approval" },
|
|
122
|
-
{ id: "executor", kind: "
|
|
123
|
-
{ id: "finalizer", kind: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
122
|
+
{ id: "executor", kind: "agent" },
|
|
123
|
+
{ id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
124
124
|
],
|
|
125
125
|
edges: [
|
|
126
126
|
{ from: "planner", to: "approval" },
|
|
@@ -130,31 +130,31 @@ export function resolveLangGraphPresetWorkflow(presetName, options = {}) {
|
|
|
130
130
|
],
|
|
131
131
|
};
|
|
132
132
|
case "handoff": {
|
|
133
|
-
const
|
|
133
|
+
const agent = requireAgent("handoff", options);
|
|
134
134
|
return {
|
|
135
|
-
entryNode: "
|
|
135
|
+
entryNode: "worker",
|
|
136
136
|
nodes: [
|
|
137
|
-
{ id: "
|
|
138
|
-
{ id: "finalizer", kind: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
137
|
+
{ id: "worker", kind: "agent", agent },
|
|
138
|
+
{ id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
139
139
|
],
|
|
140
140
|
edges: [
|
|
141
|
-
{ from: "
|
|
141
|
+
{ from: "worker", to: "finalizer", when: "has_result" },
|
|
142
142
|
],
|
|
143
143
|
};
|
|
144
144
|
}
|
|
145
145
|
case "orchestrator-workers": {
|
|
146
|
-
const
|
|
146
|
+
const agent = requireAgent("orchestrator-workers", options);
|
|
147
147
|
return {
|
|
148
148
|
entryNode: "planner",
|
|
149
149
|
nodes: [
|
|
150
|
-
{ id: "planner", kind: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
151
|
-
{ id: "
|
|
152
|
-
{ id: "reviewer", kind: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
|
|
153
|
-
{ id: "finalizer", kind: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
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 },
|
|
154
154
|
],
|
|
155
155
|
edges: [
|
|
156
|
-
{ from: "planner", to: "
|
|
157
|
-
{ from: "
|
|
156
|
+
{ from: "planner", to: "worker" },
|
|
157
|
+
{ from: "worker", to: "reviewer", when: "has_result" },
|
|
158
158
|
{ from: "reviewer", to: "finalizer", when: "review_ok" },
|
|
159
159
|
],
|
|
160
160
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LangGraphPresetWorkflow } from "./langgraph-presets.js";
|
|
2
|
+
export type LangGraphProfileName = "coding-runtime" | "personal-assistant" | "research-runtime" | "approval-review-runtime" | "claw-style-assistant" | "chat-operator" | "copilot-sidecar" | "task-delegation-hub";
|
|
3
|
+
type LangGraphProfileOptions = Record<string, unknown>;
|
|
4
|
+
export declare const SUPPORTED_LANGGRAPH_PROFILES: LangGraphProfileName[];
|
|
5
|
+
export declare function resolveLangGraphProfileWorkflow(profileName: string | undefined, options?: LangGraphProfileOptions): LangGraphPresetWorkflow | undefined;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
const DEFAULT_PLANNER_PROMPT = "You are the workflow planner. Produce a concise execution plan for the user request before execution starts.";
|
|
2
|
+
const DEFAULT_REVIEWER_PROMPT = "Review the current result, call out missing verification or obvious gaps, and state whether the work looks sufficient.";
|
|
3
|
+
const DEFAULT_FINALIZER_PROMPT = "Rewrite the current result into a concise user-facing final answer. Preserve facts and caveats.";
|
|
4
|
+
const DEFAULT_REPLANNER_PROMPT = "Refine the plan based on the reviewer feedback and current result. Return only the updated plan.";
|
|
5
|
+
export const SUPPORTED_LANGGRAPH_PROFILES = [
|
|
6
|
+
"coding-runtime",
|
|
7
|
+
"personal-assistant",
|
|
8
|
+
"research-runtime",
|
|
9
|
+
"approval-review-runtime",
|
|
10
|
+
"claw-style-assistant",
|
|
11
|
+
"chat-operator",
|
|
12
|
+
"copilot-sidecar",
|
|
13
|
+
"task-delegation-hub",
|
|
14
|
+
];
|
|
15
|
+
function readStringOption(options, key) {
|
|
16
|
+
const value = options[key];
|
|
17
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
18
|
+
}
|
|
19
|
+
function requireAgentOption(profile, options, key) {
|
|
20
|
+
const value = readStringOption(options, key);
|
|
21
|
+
if (value) {
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
throw new Error(`LangGraph profile ${profile} requires with.${key}`);
|
|
25
|
+
}
|
|
26
|
+
function buildCodingRuntimeWorkflow(options) {
|
|
27
|
+
const coderAgent = requireAgentOption("coding-runtime", options, "coderAgent");
|
|
28
|
+
const verifierAgent = readStringOption(options, "verifierAgent");
|
|
29
|
+
const needsVerification = Boolean(verifierAgent) || options.runIntegrationVerification === true;
|
|
30
|
+
return {
|
|
31
|
+
entryNode: "planner",
|
|
32
|
+
nodes: [
|
|
33
|
+
{ id: "planner", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
34
|
+
{ id: "coder", kind: "agent", agent: coderAgent },
|
|
35
|
+
{ id: "reviewer", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
|
|
36
|
+
{ id: "replanner", kind: "llm", role: "replanner", prompt: DEFAULT_REPLANNER_PROMPT },
|
|
37
|
+
...(needsVerification
|
|
38
|
+
? [{ id: "approval", kind: "approval" }, { id: "verifier", kind: "agent", agent: verifierAgent ?? coderAgent }]
|
|
39
|
+
: []),
|
|
40
|
+
{ id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
41
|
+
],
|
|
42
|
+
edges: [
|
|
43
|
+
{ from: "planner", to: "coder" },
|
|
44
|
+
{ from: "coder", to: "reviewer", when: "has_result" },
|
|
45
|
+
{ from: "reviewer", to: needsVerification ? "approval" : "finalizer", when: "review_ok" },
|
|
46
|
+
{ from: "reviewer", to: "replanner", when: "review_incomplete" },
|
|
47
|
+
{ from: "replanner", to: "coder", when: "has_plan" },
|
|
48
|
+
...(needsVerification
|
|
49
|
+
? [
|
|
50
|
+
{ from: "approval", to: "verifier", when: "approval_approved" },
|
|
51
|
+
{ from: "approval", to: "verifier", when: "approval_edited" },
|
|
52
|
+
{ from: "verifier", to: "finalizer", when: "has_result" },
|
|
53
|
+
]
|
|
54
|
+
: []),
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function buildAssistantWorkflow(options) {
|
|
59
|
+
const worker = readStringOption(options, "defaultWorkerAgent") ??
|
|
60
|
+
readStringOption(options, "defaultResearchAgent") ??
|
|
61
|
+
readStringOption(options, "defaultWritingAgent") ??
|
|
62
|
+
readStringOption(options, "defaultSchedulingAgent");
|
|
63
|
+
return {
|
|
64
|
+
entryNode: "intake",
|
|
65
|
+
nodes: [
|
|
66
|
+
{ id: "intake", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
67
|
+
...(worker ? [{ id: "worker", kind: "agent", agent: worker }] : [{ id: "lookup", kind: "tool", tool: "repo_inventory" }]),
|
|
68
|
+
{ id: "reviewer", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
|
|
69
|
+
{ id: "approval", kind: "approval" },
|
|
70
|
+
{ id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
71
|
+
],
|
|
72
|
+
edges: [
|
|
73
|
+
{ from: "intake", to: worker ? "worker" : "lookup" },
|
|
74
|
+
{ from: worker ? "worker" : "lookup", to: "reviewer", when: "has_result" },
|
|
75
|
+
{ from: "reviewer", to: "approval", when: "review_incomplete" },
|
|
76
|
+
{ from: "reviewer", to: "finalizer", when: "review_ok" },
|
|
77
|
+
{ from: "approval", to: "finalizer", when: "approval_approved" },
|
|
78
|
+
{ from: "approval", to: "finalizer", when: "approval_edited" },
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function buildResearchWorkflow(options) {
|
|
83
|
+
const gathererAgent = requireAgentOption("research-runtime", options, "gathererAgent");
|
|
84
|
+
const analystAgent = requireAgentOption("research-runtime", options, "analystAgent");
|
|
85
|
+
const synthesizerAgent = readStringOption(options, "synthesizerAgent");
|
|
86
|
+
return {
|
|
87
|
+
entryNode: "planner",
|
|
88
|
+
nodes: [
|
|
89
|
+
{ id: "planner", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
90
|
+
{ id: "gatherer", kind: "agent", agent: gathererAgent },
|
|
91
|
+
{ id: "coverage-review", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
|
|
92
|
+
{ id: "analyst", kind: "agent", agent: analystAgent },
|
|
93
|
+
...(synthesizerAgent ? [{ id: "synthesizer", kind: "agent", agent: synthesizerAgent }] : []),
|
|
94
|
+
{ id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
95
|
+
],
|
|
96
|
+
edges: [
|
|
97
|
+
{ from: "planner", to: "gatherer" },
|
|
98
|
+
{ from: "gatherer", to: "coverage-review", when: "has_result" },
|
|
99
|
+
{ from: "coverage-review", to: "analyst", when: "review_ok" },
|
|
100
|
+
{ from: "coverage-review", to: "gatherer", when: "review_incomplete" },
|
|
101
|
+
{ from: "analyst", to: synthesizerAgent ? "synthesizer" : "finalizer", when: "has_result" },
|
|
102
|
+
...(synthesizerAgent ? [{ from: "synthesizer", to: "finalizer", when: "has_result" }] : []),
|
|
103
|
+
],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function buildApprovalReviewWorkflow(options) {
|
|
107
|
+
const preparerAgent = requireAgentOption("approval-review-runtime", options, "preparerAgent");
|
|
108
|
+
const reviewerAgent = readStringOption(options, "reviewerAgent");
|
|
109
|
+
return {
|
|
110
|
+
entryNode: "scope",
|
|
111
|
+
nodes: [
|
|
112
|
+
{ id: "scope", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
113
|
+
{ id: "preparer", kind: "agent", agent: preparerAgent },
|
|
114
|
+
...(reviewerAgent ? [{ id: "reviewer-agent", kind: "agent", agent: reviewerAgent }] : [{ id: "risk-review", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT }]),
|
|
115
|
+
{ id: "approval", kind: "approval" },
|
|
116
|
+
{ id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
117
|
+
],
|
|
118
|
+
edges: [
|
|
119
|
+
{ from: "scope", to: "preparer" },
|
|
120
|
+
{ from: "preparer", to: reviewerAgent ? "reviewer-agent" : "risk-review", when: "has_result" },
|
|
121
|
+
{ from: reviewerAgent ? "reviewer-agent" : "risk-review", to: "approval", when: "has_result" },
|
|
122
|
+
{ from: "approval", to: "finalizer", when: "approval_approved" },
|
|
123
|
+
{ from: "approval", to: "finalizer", when: "approval_edited" },
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function buildChatOperatorWorkflow(options) {
|
|
128
|
+
const routedAgent = readStringOption(options, "assistantAgent") ??
|
|
129
|
+
readStringOption(options, "researchAgent") ??
|
|
130
|
+
readStringOption(options, "codingAgent") ??
|
|
131
|
+
readStringOption(options, "approvalAgent");
|
|
132
|
+
if (!routedAgent) {
|
|
133
|
+
throw new Error("LangGraph profile chat-operator requires at least one target agent in with.assistantAgent, with.researchAgent, with.codingAgent, or with.approvalAgent");
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
entryNode: "router",
|
|
137
|
+
nodes: [
|
|
138
|
+
{ id: "router", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
139
|
+
{ id: "worker", kind: "agent", agent: routedAgent },
|
|
140
|
+
{ id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
141
|
+
],
|
|
142
|
+
edges: [
|
|
143
|
+
{ from: "router", to: "worker" },
|
|
144
|
+
{ from: "worker", to: "finalizer", when: "has_result" },
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function buildCopilotSidecarWorkflow(options) {
|
|
149
|
+
const coderAgent = requireAgentOption("copilot-sidecar", options, "coderAgent");
|
|
150
|
+
return {
|
|
151
|
+
entryNode: "intake",
|
|
152
|
+
nodes: [
|
|
153
|
+
{ id: "intake", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
154
|
+
{ id: "coder", kind: "agent", agent: coderAgent },
|
|
155
|
+
{ id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
156
|
+
],
|
|
157
|
+
edges: [
|
|
158
|
+
{ from: "intake", to: "coder" },
|
|
159
|
+
{ from: "coder", to: "finalizer", when: "has_result" },
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function buildDelegationHubWorkflow(options) {
|
|
164
|
+
const workerAgent = readStringOption(options, "defaultWorkerFallback");
|
|
165
|
+
if (!workerAgent) {
|
|
166
|
+
throw new Error("LangGraph profile task-delegation-hub requires with.defaultWorkerFallback");
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
entryNode: "router",
|
|
170
|
+
nodes: [
|
|
171
|
+
{ id: "router", kind: "llm", role: "planner", prompt: DEFAULT_PLANNER_PROMPT },
|
|
172
|
+
{ id: "worker", kind: "agent", agent: workerAgent },
|
|
173
|
+
{ id: "reviewer", kind: "llm", role: "reviewer", prompt: DEFAULT_REVIEWER_PROMPT },
|
|
174
|
+
{ id: "finalizer", kind: "llm", role: "finalizer", prompt: DEFAULT_FINALIZER_PROMPT },
|
|
175
|
+
],
|
|
176
|
+
edges: [
|
|
177
|
+
{ from: "router", to: "worker" },
|
|
178
|
+
{ from: "worker", to: "reviewer", when: "has_result" },
|
|
179
|
+
{ from: "reviewer", to: "finalizer", when: "review_ok" },
|
|
180
|
+
],
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
export function resolveLangGraphProfileWorkflow(profileName, options = {}) {
|
|
184
|
+
switch (profileName) {
|
|
185
|
+
case undefined:
|
|
186
|
+
case "":
|
|
187
|
+
return undefined;
|
|
188
|
+
case "coding-runtime":
|
|
189
|
+
return buildCodingRuntimeWorkflow(options);
|
|
190
|
+
case "personal-assistant":
|
|
191
|
+
case "claw-style-assistant":
|
|
192
|
+
return buildAssistantWorkflow(options);
|
|
193
|
+
case "research-runtime":
|
|
194
|
+
return buildResearchWorkflow(options);
|
|
195
|
+
case "approval-review-runtime":
|
|
196
|
+
return buildApprovalReviewWorkflow(options);
|
|
197
|
+
case "chat-operator":
|
|
198
|
+
return buildChatOperatorWorkflow(options);
|
|
199
|
+
case "copilot-sidecar":
|
|
200
|
+
return buildCopilotSidecarWorkflow(options);
|
|
201
|
+
case "task-delegation-hub":
|
|
202
|
+
return buildDelegationHubWorkflow(options);
|
|
203
|
+
default:
|
|
204
|
+
throw new Error(`Unsupported LangGraph profile ${String(profileName)}. Supported profiles: ${SUPPORTED_LANGGRAPH_PROFILES.join(", ")}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
@@ -245,6 +245,22 @@ function resolveLangGraphWorkflowConfig(agent, refs) {
|
|
|
245
245
|
if (agent.executionMode !== "langgraph") {
|
|
246
246
|
return undefined;
|
|
247
247
|
}
|
|
248
|
+
const profile = typeof agent.langchainAgentConfig?.profile === "string" && agent.langchainAgentConfig.profile.trim()
|
|
249
|
+
? agent.langchainAgentConfig.profile.trim()
|
|
250
|
+
: typeof agent.langchainAgentConfig?.passthrough === "object" &&
|
|
251
|
+
agent.langchainAgentConfig.passthrough &&
|
|
252
|
+
typeof agent.langchainAgentConfig.passthrough.profile === "string" &&
|
|
253
|
+
agent.langchainAgentConfig.passthrough.profile.trim()
|
|
254
|
+
? agent.langchainAgentConfig.passthrough.profile.trim()
|
|
255
|
+
: undefined;
|
|
256
|
+
const profileWith = typeof agent.langchainAgentConfig?.with === "object" && agent.langchainAgentConfig.with
|
|
257
|
+
? { ...agent.langchainAgentConfig.with }
|
|
258
|
+
: typeof agent.langchainAgentConfig?.passthrough === "object" &&
|
|
259
|
+
agent.langchainAgentConfig.passthrough &&
|
|
260
|
+
typeof agent.langchainAgentConfig.passthrough.with === "object" &&
|
|
261
|
+
agent.langchainAgentConfig.passthrough.with
|
|
262
|
+
? { ...agent.langchainAgentConfig.passthrough.with }
|
|
263
|
+
: undefined;
|
|
248
264
|
const preset = typeof agent.langchainAgentConfig?.preset === "string" && agent.langchainAgentConfig.preset.trim()
|
|
249
265
|
? agent.langchainAgentConfig.preset.trim()
|
|
250
266
|
: typeof agent.langchainAgentConfig?.passthrough === "object" &&
|
|
@@ -269,15 +285,22 @@ function resolveLangGraphWorkflowConfig(agent, refs) {
|
|
|
269
285
|
? agent.langchainAgentConfig.passthrough.langgraph
|
|
270
286
|
: undefined;
|
|
271
287
|
if (!workflowConfig) {
|
|
272
|
-
return preset ? { preset } : undefined;
|
|
288
|
+
return profile || preset ? { ...(profile ? { profile } : {}), ...(profileWith ? { with: profileWith } : {}), ...(preset ? { preset } : {}) } : undefined;
|
|
273
289
|
}
|
|
274
290
|
if (isRefConfig(workflowConfig)) {
|
|
275
291
|
return {
|
|
276
292
|
config: materializeWorkspaceObjectConfig(refs, workflowConfig.ref, ["langgraph-workflow"], `Agent ${agent.id} workflow`),
|
|
293
|
+
...(profile ? { profile } : {}),
|
|
294
|
+
...(profileWith ? { with: profileWith } : {}),
|
|
277
295
|
...(preset ? { preset } : {}),
|
|
278
296
|
};
|
|
279
297
|
}
|
|
280
|
-
return {
|
|
298
|
+
return {
|
|
299
|
+
config: workflowConfig,
|
|
300
|
+
...(profile ? { profile } : {}),
|
|
301
|
+
...(profileWith ? { with: profileWith } : {}),
|
|
302
|
+
...(preset ? { preset } : {}),
|
|
303
|
+
};
|
|
281
304
|
}
|
|
282
305
|
function resolveRuntimeModelRefs(agent, refs) {
|
|
283
306
|
const merged = {
|
|
@@ -341,8 +364,12 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
|
|
|
341
364
|
},
|
|
342
365
|
};
|
|
343
366
|
if (agent.executionMode !== "deepagent") {
|
|
344
|
-
const langGraphPassthrough = agent.executionMode === "langgraph"
|
|
345
|
-
? {
|
|
367
|
+
const langGraphPassthrough = agent.executionMode === "langgraph"
|
|
368
|
+
? {
|
|
369
|
+
...(langGraphWorkflow?.profile ? { profile: langGraphWorkflow.profile } : {}),
|
|
370
|
+
...(langGraphWorkflow?.with ? { with: langGraphWorkflow.with } : {}),
|
|
371
|
+
...(langGraphWorkflow?.config ? { workflow: langGraphWorkflow.config } : {}),
|
|
372
|
+
}
|
|
346
373
|
: undefined;
|
|
347
374
|
const langchainAgentParams = {
|
|
348
375
|
model: compiledAgentModel,
|
|
@@ -383,6 +410,8 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
|
|
|
383
410
|
adapter: {
|
|
384
411
|
kind: agent.executionMode === "langgraph" ? "langgraph" : "langchain-v1",
|
|
385
412
|
config: {
|
|
413
|
+
...(agent.executionMode === "langgraph" && langGraphWorkflow?.profile ? { profile: langGraphWorkflow.profile } : {}),
|
|
414
|
+
...(agent.executionMode === "langgraph" && langGraphWorkflow?.with ? { with: langGraphWorkflow.with } : {}),
|
|
386
415
|
...(agent.executionMode === "langgraph" && langGraphWorkflow?.preset ? { preset: langGraphWorkflow.preset } : {}),
|
|
387
416
|
...(agent.executionMode === "langgraph" && langGraphWorkflow?.config ? { workflow: langGraphWorkflow.config } : {}),
|
|
388
417
|
params: langchainAgentParams,
|