@iqai/adk 0.2.5 → 0.3.1
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/CHANGELOG.md +30 -0
- package/README.md +3 -1
- package/dist/index.d.mts +96 -60
- package/dist/index.d.ts +96 -60
- package/dist/index.js +446 -163
- package/dist/index.mjs +404 -121
- package/package.json +1 -3
package/dist/index.mjs
CHANGED
|
@@ -30,98 +30,269 @@ import chalk from "chalk";
|
|
|
30
30
|
function isDebugEnabled() {
|
|
31
31
|
return process.env.NODE_ENV === "development" || process.env.ADK_DEBUG === "true";
|
|
32
32
|
}
|
|
33
|
-
var Logger;
|
|
33
|
+
var LOG_LEVELS, Logger;
|
|
34
34
|
var init_logger = __esm({
|
|
35
35
|
"src/logger/index.ts"() {
|
|
36
|
+
LOG_LEVELS = {
|
|
37
|
+
debug: { icon: "\u{1F41B}", color: chalk.blue, method: console.log },
|
|
38
|
+
info: { icon: "\u2139\uFE0F", color: chalk.cyan, method: console.debug },
|
|
39
|
+
warn: { icon: "\u{1F6A7}", color: chalk.yellow, method: console.warn },
|
|
40
|
+
error: { icon: "\u274C", color: chalk.red, method: console.error }
|
|
41
|
+
};
|
|
36
42
|
Logger = class {
|
|
37
43
|
name;
|
|
38
44
|
isDebugEnabled = isDebugEnabled();
|
|
39
45
|
constructor({ name }) {
|
|
40
46
|
this.name = name;
|
|
41
47
|
}
|
|
42
|
-
colorize(message) {
|
|
43
|
-
return chalk.blue(message);
|
|
44
|
-
}
|
|
45
48
|
debug(message, ...args) {
|
|
46
49
|
if (this.isDebugEnabled) {
|
|
47
|
-
|
|
48
|
-
console.log(
|
|
49
|
-
this.colorize(`[${time}] \u{1F41B} [${this.name}] ${message}`),
|
|
50
|
-
...args
|
|
51
|
-
);
|
|
50
|
+
this.log("debug", message, ...args);
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
53
|
info(message, ...args) {
|
|
55
|
-
|
|
56
|
-
console.debug(
|
|
57
|
-
this.colorize(`[${time}] \u2139\uFE0F [${this.name}] ${message}`),
|
|
58
|
-
...args
|
|
59
|
-
);
|
|
54
|
+
this.log("info", message, ...args);
|
|
60
55
|
}
|
|
61
56
|
warn(message, ...args) {
|
|
62
|
-
|
|
63
|
-
console.warn(
|
|
64
|
-
this.colorize(`[${time}] \u{1F6A7} [${this.name}] ${message}`),
|
|
65
|
-
...args
|
|
66
|
-
);
|
|
57
|
+
this.log("warn", message, ...args);
|
|
67
58
|
}
|
|
68
59
|
error(message, ...args) {
|
|
60
|
+
this.log("error", message, ...args);
|
|
61
|
+
}
|
|
62
|
+
log(level, message, ...args) {
|
|
63
|
+
const { icon, color, method } = LOG_LEVELS[level];
|
|
69
64
|
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
66
|
+
const forceBoxes = process.env.ADK_FORCE_BOXES === "true";
|
|
67
|
+
const { meta, otherArgs } = this.extractMeta(args);
|
|
68
|
+
const lines = this.formatArgs(otherArgs, level === "error");
|
|
69
|
+
if (meta.suggestion) lines.unshift(`\u2022 Suggestion: ${meta.suggestion}`);
|
|
70
|
+
if (meta.context && Object.keys(meta.context).length) {
|
|
71
|
+
const contextStr = Object.entries(meta.context).map(([k, v]) => `${k}=${this.stringify(v)}`).join(" ");
|
|
72
|
+
lines.unshift(`\u2022 Context: ${contextStr}`);
|
|
73
|
+
}
|
|
74
|
+
if (isProd && !forceBoxes) {
|
|
75
|
+
const header = `[${time}] ${icon} [${this.name}] ${message}`;
|
|
76
|
+
const output = lines.length ? [header, ...lines].join("\n") : header;
|
|
77
|
+
method(color(output));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (level === "warn" || level === "error") {
|
|
81
|
+
const box = this.formatBox({
|
|
82
|
+
title: `${icon} ${this.capitalize(level)} @ ${time} (${this.name})`,
|
|
83
|
+
description: message,
|
|
84
|
+
lines,
|
|
85
|
+
color
|
|
86
|
+
});
|
|
87
|
+
method(box);
|
|
88
|
+
} else {
|
|
89
|
+
const header = `[${time}] ${icon} [${this.name}] ${message}`;
|
|
90
|
+
const output = lines.length ? [header, ...lines].join("\n") : header;
|
|
91
|
+
method(color(output));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
extractMeta(args) {
|
|
95
|
+
const meta = {};
|
|
96
|
+
const otherArgs = [];
|
|
97
|
+
let metaFound = false;
|
|
98
|
+
for (const arg of args) {
|
|
99
|
+
if (!arg) continue;
|
|
100
|
+
if (!metaFound && typeof arg === "object" && !(arg instanceof Error) && ("suggestion" in arg || "context" in arg)) {
|
|
101
|
+
meta.suggestion = arg.suggestion;
|
|
102
|
+
meta.context = arg.context;
|
|
103
|
+
metaFound = true;
|
|
104
|
+
} else {
|
|
105
|
+
otherArgs.push(arg);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return { meta, otherArgs };
|
|
109
|
+
}
|
|
110
|
+
formatArgs(args, includeStack = false) {
|
|
111
|
+
const lines = [];
|
|
112
|
+
const maxFrames = Number(process.env.ADK_ERROR_STACK_FRAMES || 8);
|
|
113
|
+
for (const arg of args) {
|
|
114
|
+
if (!arg) continue;
|
|
115
|
+
if (arg instanceof Error) {
|
|
116
|
+
lines.push(`\u2022 ${arg.name}: ${arg.message}`);
|
|
117
|
+
if (includeStack && arg.stack) {
|
|
118
|
+
const frames = this.parseStackFrames(arg.stack, maxFrames);
|
|
119
|
+
if (frames.length) {
|
|
120
|
+
lines.push("\u2022 Stack:", ...frames);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
lines.push(`\u2022 ${this.stringify(arg)}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return lines;
|
|
128
|
+
}
|
|
129
|
+
parseStackFrames(stack, maxFrames) {
|
|
130
|
+
const frames = stack.split(/\n/).slice(1).map((f) => f.trim()).filter(Boolean).slice(0, maxFrames);
|
|
131
|
+
const result = frames.map((frame) => {
|
|
132
|
+
const cleaned = frame.replace(/^at\s+/, "").replace(process.cwd(), ".");
|
|
133
|
+
return ` \u21B3 ${cleaned}`;
|
|
134
|
+
});
|
|
135
|
+
const totalFrames = stack.split(/\n/).length - 1;
|
|
136
|
+
if (totalFrames > maxFrames) {
|
|
137
|
+
result.push(` \u21B3 \u2026 ${totalFrames - maxFrames} more frames`);
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
stringify(value) {
|
|
142
|
+
if (typeof value === "string") return value;
|
|
143
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
144
|
+
return String(value);
|
|
145
|
+
if (value === null || value === void 0) return String(value);
|
|
146
|
+
try {
|
|
147
|
+
return JSON.stringify(value);
|
|
148
|
+
} catch {
|
|
149
|
+
return String(value);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
capitalize(str) {
|
|
153
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
154
|
+
}
|
|
155
|
+
formatBox(params) {
|
|
156
|
+
const {
|
|
157
|
+
title,
|
|
158
|
+
description,
|
|
159
|
+
lines = [],
|
|
160
|
+
width = 60,
|
|
161
|
+
maxWidthPct = 0.9,
|
|
162
|
+
color = chalk.yellow,
|
|
163
|
+
pad = 1,
|
|
164
|
+
borderChar = "\u2500"
|
|
165
|
+
} = params;
|
|
166
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
167
|
+
const forceBoxes = process.env.ADK_FORCE_BOXES === "true";
|
|
168
|
+
if (isProd && !forceBoxes) {
|
|
169
|
+
return [`${title}: ${description}`, ...lines].join("\n");
|
|
170
|
+
}
|
|
171
|
+
const termWidth = process.stdout.columns || 80;
|
|
172
|
+
const maxWidth = Math.floor(termWidth * maxWidthPct);
|
|
173
|
+
const contentWidth = Math.max(
|
|
174
|
+
width,
|
|
175
|
+
title.length + 2,
|
|
176
|
+
description.length,
|
|
177
|
+
...lines.map((l) => l.length)
|
|
73
178
|
);
|
|
179
|
+
const innerWidth = Math.min(contentWidth + pad * 2, maxWidth - 2);
|
|
180
|
+
const horizontal = borderChar.repeat(innerWidth + 2);
|
|
181
|
+
const top = `\u250C${horizontal}\u2510`;
|
|
182
|
+
const separator = `\u251C${horizontal}\u2524`;
|
|
183
|
+
const bottom = `\u2514${horizontal}\u2518`;
|
|
184
|
+
const padLine = (text) => {
|
|
185
|
+
const maxContent = innerWidth - pad * 2;
|
|
186
|
+
const truncated = text.length > maxContent ? `${text.slice(0, maxContent - 1)}\u2026` : text;
|
|
187
|
+
const padded = " ".repeat(pad) + truncated;
|
|
188
|
+
return padded + " ".repeat(innerWidth - padded.length);
|
|
189
|
+
};
|
|
190
|
+
const content = [
|
|
191
|
+
top,
|
|
192
|
+
`\u2502 ${padLine(title)} \u2502`,
|
|
193
|
+
separator,
|
|
194
|
+
`\u2502 ${padLine(description)} \u2502`,
|
|
195
|
+
...lines.map((line) => `\u2502 ${padLine(line)} \u2502`),
|
|
196
|
+
bottom
|
|
197
|
+
];
|
|
198
|
+
return `
|
|
199
|
+
${content.map((line) => color(line)).join("\n")}`;
|
|
74
200
|
}
|
|
75
201
|
/**
|
|
76
|
-
*
|
|
77
|
-
* Uses vertical layout for better readability and respects debug settings.
|
|
202
|
+
* Structured warning with code, suggestion, context.
|
|
78
203
|
*/
|
|
204
|
+
warnStructured(warning, opts = {}) {
|
|
205
|
+
const format = opts.format || process.env.ADK_WARN_FORMAT || "pretty";
|
|
206
|
+
const verbose = opts.verbose || process.env.ADK_AGENT_BUILDER_WARN === "verbose";
|
|
207
|
+
const timestamp = warning.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
208
|
+
const severity = warning.severity || "warn";
|
|
209
|
+
if (format === "json") {
|
|
210
|
+
this.warn(
|
|
211
|
+
JSON.stringify({
|
|
212
|
+
level: severity,
|
|
213
|
+
source: this.name,
|
|
214
|
+
timestamp,
|
|
215
|
+
...warning
|
|
216
|
+
})
|
|
217
|
+
);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const { icon } = LOG_LEVELS[severity] || LOG_LEVELS.warn;
|
|
221
|
+
const base = `${icon} ${warning.code} ${warning.message}`;
|
|
222
|
+
const parts = [base];
|
|
223
|
+
if (warning.suggestion) {
|
|
224
|
+
parts.push(` \u2022 Suggestion: ${warning.suggestion}`);
|
|
225
|
+
}
|
|
226
|
+
if (verbose && warning.context && Object.keys(warning.context).length) {
|
|
227
|
+
const contextStr = Object.entries(warning.context).map(([k, v]) => `${k}=${this.stringify(v)}`).join(" ");
|
|
228
|
+
parts.push(` \u2022 Context: ${contextStr}`);
|
|
229
|
+
}
|
|
230
|
+
if (format === "pretty") {
|
|
231
|
+
this.warn(parts.join("\n"));
|
|
232
|
+
} else {
|
|
233
|
+
const textParts = [`[${warning.code}] ${warning.message}`];
|
|
234
|
+
if (warning.suggestion) textParts.push(` -> ${warning.suggestion}`);
|
|
235
|
+
if (verbose && warning.context && Object.keys(warning.context).length) {
|
|
236
|
+
const contextStr = Object.entries(warning.context).map(([k, v]) => `${k}=${this.stringify(v)}`).join(" ");
|
|
237
|
+
textParts.push(` \u2022 Context: ${contextStr}`);
|
|
238
|
+
}
|
|
239
|
+
this.warn(textParts.join("\n"));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
79
242
|
debugStructured(title, data) {
|
|
80
243
|
if (!this.isDebugEnabled) return;
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
console.log(this.colorize(`\u2502 ${title.padEnd(contentWidth)} \u2502`));
|
|
89
|
-
console.log(this.colorize(middleBorder));
|
|
90
|
-
Object.entries(data).forEach(([key, value]) => {
|
|
91
|
-
const formattedKey = key.padEnd(20);
|
|
92
|
-
const formattedValue = String(value);
|
|
93
|
-
const availableValueSpace = contentWidth - 20 - 2;
|
|
94
|
-
const truncatedValue = formattedValue.length > availableValueSpace ? `${formattedValue.substring(0, availableValueSpace - 3)}...` : formattedValue;
|
|
95
|
-
const content = `${formattedKey}: ${truncatedValue}`;
|
|
96
|
-
const paddedContent = content.padEnd(contentWidth);
|
|
97
|
-
console.log(this.colorize(`\u2502 ${paddedContent} \u2502`));
|
|
244
|
+
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
245
|
+
const lines = this.objectToLines(data);
|
|
246
|
+
const box = this.formatBox({
|
|
247
|
+
title: `\u{1F41B} Debug @ ${time} (${this.name})`,
|
|
248
|
+
description: title,
|
|
249
|
+
lines,
|
|
250
|
+
color: chalk.blue
|
|
98
251
|
});
|
|
99
|
-
console.log(
|
|
252
|
+
console.log(box);
|
|
100
253
|
}
|
|
101
|
-
/**
|
|
102
|
-
* Logs array data in a compact, readable format.
|
|
103
|
-
*/
|
|
104
254
|
debugArray(title, items) {
|
|
105
255
|
if (!this.isDebugEnabled) return;
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
256
|
+
const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
257
|
+
const lines = this.arrayToLines(items);
|
|
258
|
+
const box = this.formatBox({
|
|
259
|
+
title: `\u{1F41B} Debug List @ ${time} (${this.name})`,
|
|
260
|
+
description: title,
|
|
261
|
+
lines,
|
|
262
|
+
color: chalk.blue,
|
|
263
|
+
width: 78,
|
|
264
|
+
maxWidthPct: 0.95
|
|
265
|
+
});
|
|
266
|
+
console.log(box);
|
|
267
|
+
}
|
|
268
|
+
objectToLines(obj) {
|
|
269
|
+
const entries = Object.entries(obj || {});
|
|
270
|
+
if (!entries.length) return ["(empty)"];
|
|
271
|
+
const keyWidth = Math.min(
|
|
272
|
+
30,
|
|
273
|
+
Math.max(6, ...entries.map(([k]) => k.length))
|
|
274
|
+
);
|
|
275
|
+
return entries.slice(0, 200).map(([k, v]) => {
|
|
276
|
+
const value = this.stringify(v);
|
|
277
|
+
const truncated = value.length > 140 ? `${value.slice(0, 139)}\u2026` : value;
|
|
278
|
+
return `${k.padEnd(keyWidth)}: ${truncated}`;
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
arrayToLines(items) {
|
|
282
|
+
if (!items.length) return ["(empty list)"];
|
|
283
|
+
const maxItems = 50;
|
|
284
|
+
const lines = items.slice(0, maxItems).map((obj, i) => {
|
|
285
|
+
const props = Object.entries(obj).map(([k, v]) => {
|
|
286
|
+
const value = this.stringify(v);
|
|
287
|
+
const truncated = value.length > 160 ? `${value.slice(0, 159)}\u2026` : value;
|
|
288
|
+
return `${k}=${truncated}`;
|
|
289
|
+
}).join(" \u2022 ");
|
|
290
|
+
return `[${i + 1}] ${props}`;
|
|
123
291
|
});
|
|
124
|
-
|
|
292
|
+
if (items.length > maxItems) {
|
|
293
|
+
lines.push(`\u2026 ${items.length - maxItems} more items omitted`);
|
|
294
|
+
}
|
|
295
|
+
return lines;
|
|
125
296
|
}
|
|
126
297
|
};
|
|
127
298
|
}
|
|
@@ -9291,37 +9462,29 @@ async function* mergeAgentRun(agentRuns) {
|
|
|
9291
9462
|
if (agentRuns.length === 0) {
|
|
9292
9463
|
return;
|
|
9293
9464
|
}
|
|
9294
|
-
const
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9465
|
+
const nextFor = (gen, index) => gen.next().then((result) => ({ index, result })).catch((error) => ({
|
|
9466
|
+
index,
|
|
9467
|
+
result: { done: true, value: void 0 },
|
|
9468
|
+
error
|
|
9469
|
+
}));
|
|
9470
|
+
const entries = agentRuns.map((gen, i) => ({ index: i, promise: nextFor(gen, i) }));
|
|
9471
|
+
const activePromises = () => entries.filter((e) => !!e).map((e) => e.promise);
|
|
9472
|
+
while (true) {
|
|
9473
|
+
const currentActivePromises = activePromises();
|
|
9474
|
+
if (currentActivePromises.length === 0) {
|
|
9475
|
+
break;
|
|
9300
9476
|
}
|
|
9301
|
-
|
|
9302
|
-
let pendingPromises = [...promises];
|
|
9303
|
-
while (pendingPromises.length > 0) {
|
|
9304
|
-
const { index, result, error } = await Promise.race(pendingPromises);
|
|
9305
|
-
pendingPromises = pendingPromises.filter((_, i) => i !== index);
|
|
9477
|
+
const { index, result, error } = await Promise.race(currentActivePromises);
|
|
9306
9478
|
if (error) {
|
|
9307
9479
|
console.error(`Error in parallel agent ${index}:`, error);
|
|
9480
|
+
entries[index] = void 0;
|
|
9308
9481
|
continue;
|
|
9309
9482
|
}
|
|
9310
9483
|
if (!result.done) {
|
|
9311
9484
|
yield result.value;
|
|
9312
|
-
|
|
9313
|
-
|
|
9314
|
-
|
|
9315
|
-
return { index, result: nextResult };
|
|
9316
|
-
} catch (nextError) {
|
|
9317
|
-
return {
|
|
9318
|
-
index,
|
|
9319
|
-
result: { done: true, value: void 0 },
|
|
9320
|
-
error: nextError
|
|
9321
|
-
};
|
|
9322
|
-
}
|
|
9323
|
-
})();
|
|
9324
|
-
pendingPromises.push(nextPromise);
|
|
9485
|
+
entries[index] = { index, promise: nextFor(agentRuns[index], index) };
|
|
9486
|
+
} else {
|
|
9487
|
+
entries[index] = void 0;
|
|
9325
9488
|
}
|
|
9326
9489
|
}
|
|
9327
9490
|
}
|
|
@@ -10480,8 +10643,20 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10480
10643
|
// If provided, reuse directly
|
|
10481
10644
|
definitionLocked = false;
|
|
10482
10645
|
// Lock further definition mutation after withAgent
|
|
10483
|
-
warnedMethods = /* @__PURE__ */ new Set();
|
|
10484
10646
|
logger = new Logger({ name: "AgentBuilder" });
|
|
10647
|
+
/**
|
|
10648
|
+
* Warn (once per method) if the definition has been locked by withAgent().
|
|
10649
|
+
*/
|
|
10650
|
+
warnIfLocked(method) {
|
|
10651
|
+
if (!this.definitionLocked) return;
|
|
10652
|
+
this.logger.warn(
|
|
10653
|
+
`AgentBuilder: ${method}() ignored because builder is locked by withAgent()`,
|
|
10654
|
+
{
|
|
10655
|
+
suggestion: "Configure model/tools/etc. before calling withAgent(), or avoid withAgent() if you intend to mutate afterwards.",
|
|
10656
|
+
context: { method, agentName: this.config.name }
|
|
10657
|
+
}
|
|
10658
|
+
);
|
|
10659
|
+
}
|
|
10485
10660
|
/**
|
|
10486
10661
|
* Private constructor - use static create() method
|
|
10487
10662
|
*/
|
|
@@ -10541,6 +10716,16 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10541
10716
|
}
|
|
10542
10717
|
withOutputSchema(schema) {
|
|
10543
10718
|
this.warnIfLocked("withOutputSchema");
|
|
10719
|
+
if (this.agentType === "sequential" || this.agentType === "parallel") {
|
|
10720
|
+
const msg = "Output schemas cannot be applied to sequential or parallel agents. Define output schemas on each sub-agent instead.";
|
|
10721
|
+
this.logger.error(msg, {
|
|
10722
|
+
suggestion: "Apply outputSchema to each sub-agent individually.",
|
|
10723
|
+
context: {
|
|
10724
|
+
agentType: this.agentType
|
|
10725
|
+
}
|
|
10726
|
+
});
|
|
10727
|
+
throw new Error(msg);
|
|
10728
|
+
}
|
|
10544
10729
|
this.config.outputSchema = schema;
|
|
10545
10730
|
return this;
|
|
10546
10731
|
}
|
|
@@ -10581,6 +10766,16 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10581
10766
|
*/
|
|
10582
10767
|
withOutputKey(outputKey) {
|
|
10583
10768
|
this.warnIfLocked("withOutputKey");
|
|
10769
|
+
if (this.agentType === "sequential" || this.agentType === "parallel") {
|
|
10770
|
+
this.logger.warn(
|
|
10771
|
+
"AgentBuilder: outputKey ignored for sequential/parallel aggregator",
|
|
10772
|
+
{
|
|
10773
|
+
suggestion: "Set outputKey on each sub-agent instead.",
|
|
10774
|
+
context: { attemptedOutputKey: outputKey, agentType: this.agentType }
|
|
10775
|
+
}
|
|
10776
|
+
);
|
|
10777
|
+
return this;
|
|
10778
|
+
}
|
|
10584
10779
|
this.config.outputKey = outputKey;
|
|
10585
10780
|
return this;
|
|
10586
10781
|
}
|
|
@@ -10632,9 +10827,37 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10632
10827
|
* @returns This builder instance for chaining
|
|
10633
10828
|
*/
|
|
10634
10829
|
asSequential(subAgents) {
|
|
10635
|
-
this.
|
|
10830
|
+
if (this.definitionLocked) {
|
|
10831
|
+
this.logger.warn(
|
|
10832
|
+
"AgentBuilder: asSequential() ignored; builder locked by withAgent()",
|
|
10833
|
+
{
|
|
10834
|
+
suggestion: "Call asSequential() before withAgent().",
|
|
10835
|
+
context: { agentName: this.config.name }
|
|
10836
|
+
}
|
|
10837
|
+
);
|
|
10838
|
+
return this;
|
|
10839
|
+
}
|
|
10636
10840
|
this.agentType = "sequential";
|
|
10637
10841
|
this.config.subAgents = subAgents;
|
|
10842
|
+
if (this.config.outputKey) {
|
|
10843
|
+
this.logger.warn(
|
|
10844
|
+
"AgentBuilder: outputKey ignored for sequential agent aggregator; removed",
|
|
10845
|
+
{
|
|
10846
|
+
suggestion: "Assign outputKey on individual sub-agents if needed.",
|
|
10847
|
+
context: { previousValue: this.config.outputKey }
|
|
10848
|
+
}
|
|
10849
|
+
);
|
|
10850
|
+
this.config.outputKey = void 0;
|
|
10851
|
+
}
|
|
10852
|
+
if (this.config.outputSchema) {
|
|
10853
|
+
this.logger.warn(
|
|
10854
|
+
"AgentBuilder: outputSchema cannot be applied to sequential aggregator; removed",
|
|
10855
|
+
{
|
|
10856
|
+
suggestion: "Apply schemas to sub-agents individually."
|
|
10857
|
+
}
|
|
10858
|
+
);
|
|
10859
|
+
this.config.outputSchema = void 0;
|
|
10860
|
+
}
|
|
10638
10861
|
return this;
|
|
10639
10862
|
}
|
|
10640
10863
|
/**
|
|
@@ -10643,9 +10866,37 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10643
10866
|
* @returns This builder instance for chaining
|
|
10644
10867
|
*/
|
|
10645
10868
|
asParallel(subAgents) {
|
|
10646
|
-
this.
|
|
10869
|
+
if (this.definitionLocked) {
|
|
10870
|
+
this.logger.warn(
|
|
10871
|
+
"AgentBuilder: asParallel() ignored; builder locked by withAgent()",
|
|
10872
|
+
{
|
|
10873
|
+
suggestion: "Call asParallel() before withAgent().",
|
|
10874
|
+
context: { agentName: this.config.name }
|
|
10875
|
+
}
|
|
10876
|
+
);
|
|
10877
|
+
return this;
|
|
10878
|
+
}
|
|
10647
10879
|
this.agentType = "parallel";
|
|
10648
10880
|
this.config.subAgents = subAgents;
|
|
10881
|
+
if (this.config.outputKey) {
|
|
10882
|
+
this.logger.warn(
|
|
10883
|
+
"AgentBuilder: outputKey ignored for parallel agent aggregator; removed",
|
|
10884
|
+
{
|
|
10885
|
+
suggestion: "Assign outputKey on individual sub-agents if needed.",
|
|
10886
|
+
context: { previousValue: this.config.outputKey }
|
|
10887
|
+
}
|
|
10888
|
+
);
|
|
10889
|
+
this.config.outputKey = void 0;
|
|
10890
|
+
}
|
|
10891
|
+
if (this.config.outputSchema) {
|
|
10892
|
+
this.logger.warn(
|
|
10893
|
+
"AgentBuilder: outputSchema cannot be applied to parallel aggregator; removed",
|
|
10894
|
+
{
|
|
10895
|
+
suggestion: "Apply schemas to sub-agents individually."
|
|
10896
|
+
}
|
|
10897
|
+
);
|
|
10898
|
+
this.config.outputSchema = void 0;
|
|
10899
|
+
}
|
|
10649
10900
|
return this;
|
|
10650
10901
|
}
|
|
10651
10902
|
/**
|
|
@@ -10698,9 +10949,11 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10698
10949
|
*/
|
|
10699
10950
|
withSession(session) {
|
|
10700
10951
|
if (!this.sessionService) {
|
|
10701
|
-
|
|
10702
|
-
|
|
10703
|
-
|
|
10952
|
+
const msg = "Session service must be configured before using withSession(). Call withSessionService() first, or use withQuickSession() for in-memory sessions.";
|
|
10953
|
+
this.logger.error(msg, {
|
|
10954
|
+
suggestion: "Invoke withSessionService() prior to withSession()."
|
|
10955
|
+
});
|
|
10956
|
+
throw new Error(msg);
|
|
10704
10957
|
}
|
|
10705
10958
|
this.sessionOptions = {
|
|
10706
10959
|
...this.sessionOptions,
|
|
@@ -10771,7 +11024,12 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10771
11024
|
const baseRunner = new Runner(runnerConfig);
|
|
10772
11025
|
runner = this.createEnhancedRunner(baseRunner, session);
|
|
10773
11026
|
}
|
|
10774
|
-
return {
|
|
11027
|
+
return {
|
|
11028
|
+
agent,
|
|
11029
|
+
runner,
|
|
11030
|
+
session,
|
|
11031
|
+
sessionService: this.sessionService
|
|
11032
|
+
};
|
|
10775
11033
|
}
|
|
10776
11034
|
/**
|
|
10777
11035
|
* Type-safe build method for agents with output schemas
|
|
@@ -10799,7 +11057,11 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10799
11057
|
switch (this.agentType) {
|
|
10800
11058
|
case "llm": {
|
|
10801
11059
|
if (!this.config.model) {
|
|
10802
|
-
|
|
11060
|
+
const msg = "Model is required for LLM agent";
|
|
11061
|
+
this.logger.error(msg, {
|
|
11062
|
+
suggestion: "Call withModel() before build()."
|
|
11063
|
+
});
|
|
11064
|
+
throw new Error(msg);
|
|
10803
11065
|
}
|
|
10804
11066
|
const model = this.config.model;
|
|
10805
11067
|
return new LlmAgent({
|
|
@@ -10823,7 +11085,11 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10823
11085
|
}
|
|
10824
11086
|
case "sequential":
|
|
10825
11087
|
if (!this.config.subAgents || !Array.isArray(this.config.subAgents) || this.config.subAgents.length === 0) {
|
|
10826
|
-
|
|
11088
|
+
const msg = "Sub-agents required for sequential agent";
|
|
11089
|
+
this.logger.error(msg, {
|
|
11090
|
+
suggestion: "Provide at least one sub-agent."
|
|
11091
|
+
});
|
|
11092
|
+
throw new Error(msg);
|
|
10827
11093
|
}
|
|
10828
11094
|
return new SequentialAgent({
|
|
10829
11095
|
name: this.config.name,
|
|
@@ -10832,7 +11098,11 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10832
11098
|
});
|
|
10833
11099
|
case "parallel":
|
|
10834
11100
|
if (!this.config.subAgents || !Array.isArray(this.config.subAgents) || this.config.subAgents.length === 0) {
|
|
10835
|
-
|
|
11101
|
+
const msg = "Sub-agents required for parallel agent";
|
|
11102
|
+
this.logger.error(msg, {
|
|
11103
|
+
suggestion: "Provide at least one sub-agent."
|
|
11104
|
+
});
|
|
11105
|
+
throw new Error(msg);
|
|
10836
11106
|
}
|
|
10837
11107
|
return new ParallelAgent({
|
|
10838
11108
|
name: this.config.name,
|
|
@@ -10841,7 +11111,11 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10841
11111
|
});
|
|
10842
11112
|
case "loop":
|
|
10843
11113
|
if (!this.config.subAgents || !Array.isArray(this.config.subAgents) || this.config.subAgents.length === 0) {
|
|
10844
|
-
|
|
11114
|
+
const msg = "Sub-agents required for loop agent";
|
|
11115
|
+
this.logger.error(msg, {
|
|
11116
|
+
suggestion: "Provide at least one sub-agent."
|
|
11117
|
+
});
|
|
11118
|
+
throw new Error(msg);
|
|
10845
11119
|
}
|
|
10846
11120
|
return new LoopAgent({
|
|
10847
11121
|
name: this.config.name,
|
|
@@ -10851,7 +11125,11 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10851
11125
|
});
|
|
10852
11126
|
case "langgraph":
|
|
10853
11127
|
if (!this.config.nodes || !Array.isArray(this.config.nodes) || this.config.nodes.length === 0 || !this.config.rootNode || typeof this.config.rootNode !== "string") {
|
|
10854
|
-
|
|
11128
|
+
const msg = "Nodes and root node required for LangGraph agent";
|
|
11129
|
+
this.logger.error(msg, {
|
|
11130
|
+
suggestion: "Provide nodes[] and a valid rootNode string."
|
|
11131
|
+
});
|
|
11132
|
+
throw new Error(msg);
|
|
10855
11133
|
}
|
|
10856
11134
|
return new LangGraphAgent({
|
|
10857
11135
|
name: this.config.name,
|
|
@@ -10885,11 +11163,16 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10885
11163
|
createEnhancedRunner(baseRunner, session) {
|
|
10886
11164
|
const sessionOptions = this.sessionOptions;
|
|
10887
11165
|
const outputSchema = this.config.outputSchema;
|
|
11166
|
+
const agentType = this.agentType;
|
|
11167
|
+
const isMulti = agentType === "parallel" || agentType === "sequential";
|
|
11168
|
+
const subAgentNames = this.config.subAgents?.map((a) => a.name) || [];
|
|
10888
11169
|
return {
|
|
10889
11170
|
__outputSchema: outputSchema,
|
|
10890
11171
|
async ask(message) {
|
|
10891
11172
|
const newMessage = typeof message === "string" ? { parts: [{ text: message }] } : typeof message === "object" && "contents" in message ? { parts: message.contents[message.contents.length - 1].parts } : message;
|
|
10892
|
-
let
|
|
11173
|
+
let combinedResponse = "";
|
|
11174
|
+
const perAgentBuffers = {};
|
|
11175
|
+
const authors = /* @__PURE__ */ new Set();
|
|
10893
11176
|
if (!sessionOptions?.userId) {
|
|
10894
11177
|
throw new Error("Session configuration is required");
|
|
10895
11178
|
}
|
|
@@ -10903,45 +11186,45 @@ var AgentBuilder = class _AgentBuilder {
|
|
|
10903
11186
|
(part) => (part && typeof part === "object" && "text" in part ? part.text : "") || ""
|
|
10904
11187
|
).join("");
|
|
10905
11188
|
if (content) {
|
|
10906
|
-
|
|
11189
|
+
combinedResponse += content;
|
|
11190
|
+
const author = event.author || "";
|
|
11191
|
+
if (author && author !== "user") {
|
|
11192
|
+
authors.add(author);
|
|
11193
|
+
perAgentBuffers[author] = (perAgentBuffers[author] || "") + content;
|
|
11194
|
+
}
|
|
10907
11195
|
}
|
|
10908
11196
|
}
|
|
10909
11197
|
}
|
|
11198
|
+
if (isMulti) {
|
|
11199
|
+
return subAgentNames.map((name) => ({
|
|
11200
|
+
agent: name,
|
|
11201
|
+
response: (perAgentBuffers[name] || "").trim()
|
|
11202
|
+
}));
|
|
11203
|
+
}
|
|
10910
11204
|
if (outputSchema) {
|
|
10911
11205
|
try {
|
|
10912
|
-
const parsed = JSON.parse(
|
|
11206
|
+
const parsed = JSON.parse(combinedResponse);
|
|
10913
11207
|
return outputSchema.parse(parsed);
|
|
10914
11208
|
} catch (parseError) {
|
|
10915
11209
|
try {
|
|
10916
|
-
return outputSchema.parse(
|
|
11210
|
+
return outputSchema.parse(combinedResponse);
|
|
10917
11211
|
} catch (validationError) {
|
|
10918
|
-
|
|
11212
|
+
throw new Error(
|
|
11213
|
+
`Failed to parse and validate LLM output against the schema.
|
|
11214
|
+
JSON parse error: ${parseError instanceof Error ? parseError.message : String(parseError)}
|
|
11215
|
+
Zod validation error: ${validationError instanceof Error ? validationError.message : String(validationError)}
|
|
11216
|
+
Raw output: "${combinedResponse}"`
|
|
11217
|
+
);
|
|
10919
11218
|
}
|
|
10920
11219
|
}
|
|
10921
11220
|
}
|
|
10922
|
-
return
|
|
11221
|
+
return combinedResponse.trim();
|
|
10923
11222
|
},
|
|
10924
11223
|
runAsync(params) {
|
|
10925
11224
|
return baseRunner.runAsync(params);
|
|
10926
11225
|
}
|
|
10927
11226
|
};
|
|
10928
11227
|
}
|
|
10929
|
-
/**
|
|
10930
|
-
* Warn (once per method) if the definition has been locked by withAgent().
|
|
10931
|
-
*/
|
|
10932
|
-
warnIfLocked(method) {
|
|
10933
|
-
if (!this.definitionLocked) return;
|
|
10934
|
-
if (this.warnedMethods.has(method)) return;
|
|
10935
|
-
this.warnedMethods.add(method);
|
|
10936
|
-
if (process.env.NODE_ENV !== "production") {
|
|
10937
|
-
const msg = `AgentBuilder: attempted to call ${method} after withAgent(); ignoring. (Wrap the agent first OR configure before withAgent).`;
|
|
10938
|
-
if (this.logger && typeof this.logger.warn === "function") {
|
|
10939
|
-
this.logger.warn(msg);
|
|
10940
|
-
} else {
|
|
10941
|
-
console.warn(msg);
|
|
10942
|
-
}
|
|
10943
|
-
}
|
|
10944
|
-
}
|
|
10945
11228
|
};
|
|
10946
11229
|
|
|
10947
11230
|
// src/memory/index.ts
|