@animalabs/agent-framework 0.6.4 → 0.6.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animalabs/agent-framework",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "Multi-agent framework with pluggable modules, persistent state, and concurrent tool execution",
5
5
  "repository": {
6
6
  "type": "git",
package/src/agent.ts CHANGED
@@ -340,6 +340,28 @@ export class Agent {
340
340
 
341
341
  let { messages, systemInjections } = await this.compileWithInjections(budget, injections);
342
342
 
343
+ // Sanitize: strip empty/whitespace text blocks and drop messages left with
344
+ // no content. The Anthropic API rejects empty text blocks with 400
345
+ // "messages: text content blocks must be non-empty"; when such a block
346
+ // reaches a live activation request the agent cannot complete ANY turn
347
+ // ([inference-failed] on every attempt) until the offending message ages
348
+ // out of the window. Empty text blocks occur naturally: tool-only turns,
349
+ // delivery-failure placeholders, silent/skip turns. Non-text blocks pass
350
+ // through unchanged, so tool pairing is unaffected. (Field-observed
351
+ // 2026-07-10 on a resident agent: one empty block muted the agent's live
352
+ // path entirely; twin of context-manager's stripEmptyTextBlocks on the
353
+ // compression path.)
354
+ messages = messages
355
+ .map((m) => ({
356
+ ...m,
357
+ content: m.content.filter(
358
+ // typeof guard is deliberate runtime defense: history loaded from
359
+ // disk can carry a non-string `text` despite what the types claim.
360
+ (b: ContentBlock) => !(b.type === "text" && (typeof b.text !== "string" || b.text.trim() === "")),
361
+ ),
362
+ }))
363
+ .filter((m) => m.content.length > 0);
364
+
343
365
  // Safety: ensure messages don't end with an assistant message.
344
366
  // Some models reject trailing assistant messages ("prefill not supported"),
345
367
  // and after context compression a stale assistant turn can end up last.