plugin-agent-orchestrator 1.0.5 → 1.0.6

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.
@@ -212,7 +212,7 @@ ${context}` : `Task: ${task}`;
212
212
  }
213
213
  }
214
214
  async function logDelegation(ctx, plugin, data) {
215
- var _a, _b, _c, _d, _e;
215
+ var _a, _b, _c, _d;
216
216
  try {
217
217
  const logsRepo = plugin.db.getRepository("orchestratorLogs");
218
218
  if (!logsRepo) return;
@@ -221,13 +221,13 @@ async function logDelegation(ctx, plugin, data) {
221
221
  leaderUsername: data.leaderUsername,
222
222
  subAgentUsername: data.subAgentUsername,
223
223
  toolName: `delegate_to_${data.subAgentUsername}`,
224
- task: data.task.substring(0, 2e3),
225
- result: data.result.substring(0, 5e3),
224
+ task: (data.task || "").substring(0, 2e3),
225
+ result: (data.result || "").substring(0, 5e3),
226
226
  status: data.status,
227
227
  depth: data.depth,
228
228
  durationMs: data.durationMs,
229
- error: (_a = data.error) == null ? void 0 : _a.substring(0, 2e3),
230
- userId: ((_c = (_b = ctx.auth) == null ? void 0 : _b.user) == null ? void 0 : _c.id) || ((_e = (_d = ctx.state) == null ? void 0 : _d.currentUser) == null ? void 0 : _e.id)
229
+ error: (data.error || "").substring(0, 2e3),
230
+ userId: ((_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id) || ((_d = (_c = ctx.state) == null ? void 0 : _c.currentUser) == null ? void 0 : _d.id)
231
231
  }
232
232
  });
233
233
  } catch (e) {
@@ -235,25 +235,28 @@ async function logDelegation(ctx, plugin, data) {
235
235
  }
236
236
  }
237
237
  async function executeAgent(executor, systemPrompt, task, signal) {
238
- const streamOptions = { recursionLimit: 50, streamMode: "messages" };
238
+ const config = { recursionLimit: 50 };
239
239
  if (signal) {
240
- streamOptions.signal = signal;
240
+ config.signal = signal;
241
241
  }
242
- const stream = await executor.stream(
242
+ const finalState = await executor.invoke(
243
243
  {
244
244
  messages: [new import_messages.SystemMessage(systemPrompt), new import_messages.HumanMessage(task)]
245
245
  },
246
- streamOptions
246
+ config
247
247
  );
248
- let aiContentCache = "";
249
- for await (const chunk of stream) {
250
- if (signal == null ? void 0 : signal.aborted) break;
251
- const [message] = chunk;
252
- if (message.getType() === "ai" && message.content) {
253
- aiContentCache += message.content.toString();
254
- }
248
+ const messages = (finalState == null ? void 0 : finalState.messages) || [];
249
+ const lastAIMessage = [...messages].reverse().find((m) => m.getType() === "ai");
250
+ if (!lastAIMessage || !lastAIMessage.content) {
251
+ return "";
252
+ }
253
+ if (typeof lastAIMessage.content === "string") {
254
+ return lastAIMessage.content;
255
+ }
256
+ if (Array.isArray(lastAIMessage.content)) {
257
+ return lastAIMessage.content.map((c) => c.text || JSON.stringify(c)).join("\n");
255
258
  }
256
- return aiContentCache || "";
259
+ return String(lastAIMessage.content);
257
260
  }
258
261
  function createTimeout(ms, agentName, abortController) {
259
262
  return new Promise(
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName.zh-CN": "代理协调器",
5
5
  "displayName.vi-VN": "Điều phối Agent",
6
6
  "description": "Hierarchical Multi-Agent orchestration for NocoBase AI Employees. Enables Leader agents to delegate tasks to Sub-Agent employees without modifying core plugin-ai.",
7
- "version": "1.0.5",
7
+ "version": "1.0.6",
8
8
  "license": "Apache-2.0",
9
9
  "main": "dist/server/index.js",
10
10
  "keywords": [
@@ -322,12 +322,12 @@ async function logDelegation(
322
322
  leaderUsername: data.leaderUsername,
323
323
  subAgentUsername: data.subAgentUsername,
324
324
  toolName: `delegate_to_${data.subAgentUsername}`,
325
- task: data.task.substring(0, 2000),
326
- result: data.result.substring(0, 5000),
325
+ task: (data.task || '').substring(0, 2000),
326
+ result: (data.result || '').substring(0, 5000),
327
327
  status: data.status,
328
328
  depth: data.depth,
329
329
  durationMs: data.durationMs,
330
- error: data.error?.substring(0, 2000),
330
+ error: (data.error || '').substring(0, 2000),
331
331
  userId: ctx.auth?.user?.id || ctx.state?.currentUser?.id,
332
332
  },
333
333
  });
@@ -338,8 +338,8 @@ async function logDelegation(
338
338
 
339
339
  /**
340
340
  * Execute the agent and extract the final AI message content.
341
- * Uses stream mode to collect all chunks, similar to plugin-sub-agent.
342
- * Accepts an AbortSignal so the stream can be cancelled on timeout.
341
+ * Uses executor.invoke to get the final state cleanly, avoiding chunk parsing issues.
342
+ * Accepts an AbortSignal so the execution can be cancelled on timeout.
343
343
  */
344
344
  async function executeAgent(
345
345
  executor: any,
@@ -347,31 +347,39 @@ async function executeAgent(
347
347
  task: string,
348
348
  signal?: AbortSignal,
349
349
  ): Promise<string> {
350
- const streamOptions: any = { recursionLimit: 50, streamMode: 'messages' };
350
+ const config: any = { recursionLimit: 50 };
351
351
  if (signal) {
352
- streamOptions.signal = signal;
352
+ config.signal = signal;
353
353
  }
354
354
 
355
- const stream = await executor.stream(
355
+ const finalState = await executor.invoke(
356
356
  {
357
357
  messages: [new SystemMessage(systemPrompt), new HumanMessage(task)],
358
358
  },
359
- streamOptions,
359
+ config,
360
360
  );
361
361
 
362
- let aiContentCache = '';
362
+ // finalState.messages contains the entire conversation history of this delegation
363
+ const messages = finalState?.messages || [];
364
+
365
+ // Find the last AI message in the chain
366
+ const lastAIMessage = [...messages].reverse().find(m => m.getType() === 'ai');
363
367
 
364
- for await (const chunk of stream) {
365
- // Check abort between chunks
366
- if (signal?.aborted) break;
368
+ if (!lastAIMessage || !lastAIMessage.content) {
369
+ return '';
370
+ }
367
371
 
368
- const [message] = chunk;
369
- if (message.getType() === 'ai' && message.content) {
370
- aiContentCache += message.content.toString();
371
- }
372
+ if (typeof lastAIMessage.content === 'string') {
373
+ return lastAIMessage.content;
374
+ }
375
+
376
+ if (Array.isArray(lastAIMessage.content)) {
377
+ return lastAIMessage.content
378
+ .map((c: any) => c.text || JSON.stringify(c))
379
+ .join('\n');
372
380
  }
373
381
 
374
- return aiContentCache || '';
382
+ return String(lastAIMessage.content);
375
383
  }
376
384
 
377
385
  /**