@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/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
- const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
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
- const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
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
- const time = (/* @__PURE__ */ new Date()).toLocaleTimeString();
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
- console.error(
71
- this.colorize(`[${time}] \u274C [${this.name}] ${message}`),
72
- ...args
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
- * Logs structured data in a visually appealing table format.
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 terminalWidth = process.stdout.columns || 60;
82
- const width = Math.min(terminalWidth, 100);
83
- const contentWidth = width - 4;
84
- const topBorder = `\u250C${"\u2500".repeat(width - 2)}\u2510`;
85
- const bottomBorder = `\u2514${"\u2500".repeat(width - 2)}\u2518`;
86
- const middleBorder = `\u251C${"\u2500".repeat(width - 2)}\u2524`;
87
- console.log(this.colorize(topBorder));
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(this.colorize(bottomBorder));
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 terminalWidth = process.stdout.columns || 78;
107
- const width = Math.min(terminalWidth, 120);
108
- const contentWidth = width - 4;
109
- const topBorder = `\u250C${"\u2500".repeat(width - 2)}\u2510`;
110
- const bottomBorder = `\u2514${"\u2500".repeat(width - 2)}\u2518`;
111
- const middleBorder = `\u251C${"\u2500".repeat(width - 2)}\u2524`;
112
- console.log(this.colorize(topBorder));
113
- console.log(this.colorize(`\u2502 ${title.padEnd(contentWidth)} \u2502`));
114
- console.log(this.colorize(middleBorder));
115
- items.forEach((item, index) => {
116
- const itemStr = Object.entries(item).map(([k, v]) => `${k}: ${v}`).join(" \u2022 ");
117
- const indexPart = `[${index + 1}] `;
118
- const availableSpace = contentWidth - indexPart.length;
119
- const truncatedItem = itemStr.length > availableSpace ? `${itemStr.substring(0, availableSpace - 3)}...` : itemStr;
120
- const content = `${indexPart}${truncatedItem}`;
121
- const paddedContent = content.padEnd(contentWidth);
122
- console.log(this.colorize(`\u2502 ${paddedContent} \u2502`));
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
- console.log(this.colorize(bottomBorder));
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 promises = agentRuns.map(async (generator, index) => {
9295
- try {
9296
- const result = await generator.next();
9297
- return { index, result };
9298
- } catch (error) {
9299
- return { index, result: { done: true, value: void 0 }, error };
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
- const nextPromise = (async () => {
9313
- try {
9314
- const nextResult = await agentRuns[index].next();
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.warnIfLocked("asSequential");
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.warnIfLocked("asParallel");
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
- throw new Error(
10702
- "Session service must be configured before using withSession(). Call withSessionService() first, or use withQuickSession() for in-memory sessions."
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 { agent, runner, session };
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
- throw new Error("Model is required for LLM agent");
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
- throw new Error("Sub-agents required for sequential agent");
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
- throw new Error("Sub-agents required for parallel agent");
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
- throw new Error("Sub-agents required for loop agent");
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
- throw new Error("Nodes and root node required for LangGraph agent");
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 response = "";
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
- response += content;
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(response);
11206
+ const parsed = JSON.parse(combinedResponse);
10913
11207
  return outputSchema.parse(parsed);
10914
11208
  } catch (parseError) {
10915
11209
  try {
10916
- return outputSchema.parse(response);
11210
+ return outputSchema.parse(combinedResponse);
10917
11211
  } catch (validationError) {
10918
- return response.trim();
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 response.trim();
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