@agentforge-io/core 2.2.1 → 2.2.2
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.
|
@@ -310,6 +310,18 @@ class OrchestratorService {
|
|
|
310
310
|
content: assembled || '(member completed silently — no textual response)',
|
|
311
311
|
});
|
|
312
312
|
}
|
|
313
|
+
// Defensive: when the model returned `tool_use` as stop_reason
|
|
314
|
+
// but every emitted block was a non-tool_use block (or pointed
|
|
315
|
+
// at a delegate_to_* whose subAgent is no longer in our list),
|
|
316
|
+
// `toolResults` ends up empty. Appending `{role:'user', content:
|
|
317
|
+
// []}` makes Anthropic reject the next turn with "messages.N:
|
|
318
|
+
// user messages must have non-empty content" (400). Break out
|
|
319
|
+
// gracefully and let whatever text the model already emitted
|
|
320
|
+
// serve as the final answer.
|
|
321
|
+
if (toolResults.length === 0) {
|
|
322
|
+
this.logger.warn(`Orchestrator "${agent.id}" reported tool_use but produced no resolvable delegation tool calls. Closing the turn.`);
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
313
325
|
// Feed the tool results back into the orchestrator's next loop.
|
|
314
326
|
currentMessages = [
|
|
315
327
|
...currentMessages,
|
|
@@ -386,9 +398,23 @@ class OrchestratorService {
|
|
|
386
398
|
toolResults.push({
|
|
387
399
|
type: 'tool_result',
|
|
388
400
|
tool_use_id: block.id,
|
|
389
|
-
content
|
|
401
|
+
// Anthropic rejects empty tool_result content as part of
|
|
402
|
+
// the "non-empty content" rule. Substitute a sentinel
|
|
403
|
+
// when the sub-agent finished without text.
|
|
404
|
+
content: subResult.content || '(member completed silently — no textual response)',
|
|
390
405
|
});
|
|
391
406
|
}
|
|
407
|
+
// Same defensive break as the stream path — if tool_use was
|
|
408
|
+
// signalled but we resolved zero delegation calls, don't
|
|
409
|
+
// append `{role:'user', content:[]}` (Anthropic 400).
|
|
410
|
+
if (toolResults.length === 0) {
|
|
411
|
+
this.logger.warn(`Orchestrator "${orchestrator.id}" reported tool_use but produced no resolvable delegation tool calls. Closing the turn.`);
|
|
412
|
+
finalContent = response.content
|
|
413
|
+
.filter((b) => b.type === 'text')
|
|
414
|
+
.map((b) => b.text)
|
|
415
|
+
.join('');
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
392
418
|
currentMessages = [...currentMessages, { role: 'user', content: toolResults }];
|
|
393
419
|
}
|
|
394
420
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentforge-io/core",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "Framework-free AI runtime SDK. Owns: agent loop (Anthropic), conversations, tools, streaming, agent-job queue, SdkHooks. Identity, billing, infra (email/uploads/secrets) live in the host's modules — not here.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|