@animalabs/agent-framework 0.6.3 → 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.
Files changed (66) hide show
  1. package/README.md +5 -0
  2. package/dist/src/agent.d.ts +3 -1
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +27 -2
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/framework.d.ts +46 -1
  7. package/dist/src/framework.d.ts.map +1 -1
  8. package/dist/src/framework.js +280 -146
  9. package/dist/src/framework.js.map +1 -1
  10. package/dist/src/index.d.ts +1 -0
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js +1 -0
  13. package/dist/src/index.js.map +1 -1
  14. package/dist/src/modules/discord/index.d.ts +1 -0
  15. package/dist/src/modules/discord/index.d.ts.map +1 -1
  16. package/dist/src/modules/discord/index.js +4 -1
  17. package/dist/src/modules/discord/index.js.map +1 -1
  18. package/dist/src/modules/discord/types.d.ts +2 -0
  19. package/dist/src/modules/discord/types.d.ts.map +1 -1
  20. package/dist/src/modules/health/index.d.ts +2 -0
  21. package/dist/src/modules/health/index.d.ts.map +1 -1
  22. package/dist/src/modules/health/index.js +15 -4
  23. package/dist/src/modules/health/index.js.map +1 -1
  24. package/dist/src/timezone.d.ts +14 -0
  25. package/dist/src/timezone.d.ts.map +1 -0
  26. package/dist/src/timezone.js +74 -0
  27. package/dist/src/timezone.js.map +1 -0
  28. package/dist/src/types/agent.d.ts +5 -2
  29. package/dist/src/types/agent.d.ts.map +1 -1
  30. package/dist/src/types/framework.d.ts +15 -0
  31. package/dist/src/types/framework.d.ts.map +1 -1
  32. package/dist/test/activation-request-sanitize.test.d.ts +2 -0
  33. package/dist/test/activation-request-sanitize.test.d.ts.map +1 -0
  34. package/dist/test/activation-request-sanitize.test.js +89 -0
  35. package/dist/test/activation-request-sanitize.test.js.map +1 -0
  36. package/dist/test/agent-cache-ttl.test.js +18 -2
  37. package/dist/test/agent-cache-ttl.test.js.map +1 -1
  38. package/dist/test/ephemeral-settle.test.d.ts +2 -0
  39. package/dist/test/ephemeral-settle.test.d.ts.map +1 -0
  40. package/dist/test/ephemeral-settle.test.js +351 -0
  41. package/dist/test/ephemeral-settle.test.js.map +1 -0
  42. package/dist/test/health-snapshot.test.d.ts +2 -0
  43. package/dist/test/health-snapshot.test.d.ts.map +1 -0
  44. package/dist/test/health-snapshot.test.js +74 -0
  45. package/dist/test/health-snapshot.test.js.map +1 -0
  46. package/dist/test/maintenance-timer.test.js +49 -0
  47. package/dist/test/maintenance-timer.test.js.map +1 -1
  48. package/dist/test/overbudget-drain-breaker.test.d.ts +2 -0
  49. package/dist/test/overbudget-drain-breaker.test.d.ts.map +1 -0
  50. package/dist/test/overbudget-drain-breaker.test.js +157 -0
  51. package/dist/test/overbudget-drain-breaker.test.js.map +1 -0
  52. package/dist/test/timezone.test.d.ts +2 -0
  53. package/dist/test/timezone.test.d.ts.map +1 -0
  54. package/dist/test/timezone.test.js +18 -0
  55. package/dist/test/timezone.test.js.map +1 -0
  56. package/dist/tsconfig.tsbuildinfo +1 -1
  57. package/package.json +1 -1
  58. package/src/agent.ts +30 -3
  59. package/src/framework.ts +313 -146
  60. package/src/index.ts +1 -0
  61. package/src/modules/discord/index.ts +4 -1
  62. package/src/modules/discord/types.ts +3 -0
  63. package/src/modules/health/index.ts +20 -4
  64. package/src/timezone.ts +90 -0
  65. package/src/types/agent.ts +6 -2
  66. package/src/types/framework.ts +17 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animalabs/agent-framework",
3
- "version": "0.6.3",
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
@@ -47,7 +47,9 @@ export class Agent {
47
47
  /** Refusal auto-rewind policy (see AgentConfig.refusalHandling). */
48
48
  readonly refusalHandling: AgentConfig['refusalHandling'];
49
49
  /** Prompt-cache TTL forwarded to the provider (see AgentConfig.cacheTtl). */
50
- readonly cacheTtl: AgentConfig['cacheTtl'];
50
+ readonly cacheTtl: NonNullable<AgentConfig['cacheTtl']>;
51
+ /** Provider-specific request parameters forwarded unchanged by Membrane. */
52
+ readonly providerParams?: Record<string, unknown>;
51
53
 
52
54
  private _state: AgentState = { status: 'idle' };
53
55
  private _inferenceStartedAt = 0;
@@ -75,7 +77,8 @@ export class Agent {
75
77
  this.temperature = config.temperature;
76
78
  this.thinking = config.thinking;
77
79
  this.refusalHandling = config.refusalHandling;
78
- this.cacheTtl = config.cacheTtl;
80
+ this.cacheTtl = config.cacheTtl ?? '1h';
81
+ this.providerParams = config.providerParams;
79
82
  this.maxStreamTokens = config.maxStreamTokens ?? 150_000;
80
83
  this.contextBudgetTokens = config.contextBudgetTokens;
81
84
  this.contextManager = contextManager;
@@ -217,6 +220,7 @@ export class Agent {
217
220
  ...(this.thinking !== undefined && { thinking: this.thinking }),
218
221
  },
219
222
  tools: tools.length > 0 ? tools : undefined,
223
+ ...(this.providerParams && { providerParams: this.providerParams }),
220
224
  assistantParticipant: this.name,
221
225
  };
222
226
 
@@ -336,6 +340,28 @@ export class Agent {
336
340
 
337
341
  let { messages, systemInjections } = await this.compileWithInjections(budget, injections);
338
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
+
339
365
  // Safety: ensure messages don't end with an assistant message.
340
366
  // Some models reject trailing assistant messages ("prefill not supported"),
341
367
  // and after context compression a stale assistant turn can end up last.
@@ -357,7 +383,8 @@ export class Agent {
357
383
  },
358
384
  tools: availableTools.length > 0 ? availableTools : undefined,
359
385
  promptCaching: true,
360
- ...(this.cacheTtl !== undefined && { cacheTtl: this.cacheTtl }),
386
+ cacheTtl: this.cacheTtl,
387
+ ...(this.providerParams && { providerParams: this.providerParams }),
361
388
  assistantParticipant: this.name,
362
389
  };
363
390
  }