@animalabs/agent-framework 0.6.6 → 0.6.8

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 (117) hide show
  1. package/README.md +78 -0
  2. package/dist/src/agent.d.ts +5 -1
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +35 -1
  5. package/dist/src/agent.js.map +1 -1
  6. package/dist/src/api/mcp-server.js +0 -0
  7. package/dist/src/api/server.d.ts.map +1 -1
  8. package/dist/src/api/server.js +7 -2
  9. package/dist/src/api/server.js.map +1 -1
  10. package/dist/src/framework.d.ts +91 -3
  11. package/dist/src/framework.d.ts.map +1 -1
  12. package/dist/src/framework.js +988 -82
  13. package/dist/src/framework.js.map +1 -1
  14. package/dist/src/gate/event-gate.d.ts.map +1 -1
  15. package/dist/src/gate/event-gate.js +9 -2
  16. package/dist/src/gate/event-gate.js.map +1 -1
  17. package/dist/src/index.d.ts +4 -0
  18. package/dist/src/index.d.ts.map +1 -1
  19. package/dist/src/index.js +3 -0
  20. package/dist/src/index.js.map +1 -1
  21. package/dist/src/mcpl/channel-registry.d.ts +3 -1
  22. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  23. package/dist/src/mcpl/channel-registry.js +29 -15
  24. package/dist/src/mcpl/channel-registry.js.map +1 -1
  25. package/dist/src/mcpl/server-connection.d.ts +36 -3
  26. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  27. package/dist/src/mcpl/server-connection.js +142 -28
  28. package/dist/src/mcpl/server-connection.js.map +1 -1
  29. package/dist/src/modules/workspace/index.d.ts +12 -1
  30. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  31. package/dist/src/modules/workspace/index.js +661 -2
  32. package/dist/src/modules/workspace/index.js.map +1 -1
  33. package/dist/src/modules/workspace/types.d.ts +4 -0
  34. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  35. package/dist/src/modules/workspace/types.js.map +1 -1
  36. package/dist/src/recovery/discord-awareness-outbox.d.ts +99 -0
  37. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -0
  38. package/dist/src/recovery/discord-awareness-outbox.js +334 -0
  39. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -0
  40. package/dist/src/recovery/offline-branch.d.ts +45 -0
  41. package/dist/src/recovery/offline-branch.d.ts.map +1 -0
  42. package/dist/src/recovery/offline-branch.js +362 -0
  43. package/dist/src/recovery/offline-branch.js.map +1 -0
  44. package/dist/src/recovery/recover-cli.d.ts +3 -0
  45. package/dist/src/recovery/recover-cli.d.ts.map +1 -0
  46. package/dist/src/recovery/recover-cli.js +129 -0
  47. package/dist/src/recovery/recover-cli.js.map +1 -0
  48. package/dist/src/types/agent.d.ts +10 -0
  49. package/dist/src/types/agent.d.ts.map +1 -1
  50. package/dist/src/types/framework.d.ts +14 -0
  51. package/dist/src/types/framework.d.ts.map +1 -1
  52. package/dist/src/types/module.d.ts +31 -0
  53. package/dist/src/types/module.d.ts.map +1 -1
  54. package/dist/src/types/trace.d.ts +2 -0
  55. package/dist/src/types/trace.d.ts.map +1 -1
  56. package/dist/test/agent-runtime-settings.test.js +200 -93
  57. package/dist/test/agent-runtime-settings.test.js.map +1 -1
  58. package/dist/test/busy-agent-scheduler.test.d.ts +2 -0
  59. package/dist/test/busy-agent-scheduler.test.d.ts.map +1 -0
  60. package/dist/test/busy-agent-scheduler.test.js +62 -0
  61. package/dist/test/busy-agent-scheduler.test.js.map +1 -0
  62. package/dist/test/channel-lifecycle-provenance.test.d.ts +2 -0
  63. package/dist/test/channel-lifecycle-provenance.test.d.ts.map +1 -0
  64. package/dist/test/channel-lifecycle-provenance.test.js +47 -0
  65. package/dist/test/channel-lifecycle-provenance.test.js.map +1 -0
  66. package/dist/test/discord-awareness-outbox.test.d.ts +2 -0
  67. package/dist/test/discord-awareness-outbox.test.d.ts.map +1 -0
  68. package/dist/test/discord-awareness-outbox.test.js +248 -0
  69. package/dist/test/discord-awareness-outbox.test.js.map +1 -0
  70. package/dist/test/maintenance-timer.test.js +100 -0
  71. package/dist/test/maintenance-timer.test.js.map +1 -1
  72. package/dist/test/mcpl-awareness-barrier.test.d.ts +2 -0
  73. package/dist/test/mcpl-awareness-barrier.test.d.ts.map +1 -0
  74. package/dist/test/mcpl-awareness-barrier.test.js +618 -0
  75. package/dist/test/mcpl-awareness-barrier.test.js.map +1 -0
  76. package/dist/test/mcpl-reconnect-reregistration.test.js +22 -3
  77. package/dist/test/mcpl-reconnect-reregistration.test.js.map +1 -1
  78. package/dist/test/mcpl-request-timeout.test.js +15 -0
  79. package/dist/test/mcpl-request-timeout.test.js.map +1 -1
  80. package/dist/test/offline-recovery-branch.test.d.ts +2 -0
  81. package/dist/test/offline-recovery-branch.test.d.ts.map +1 -0
  82. package/dist/test/offline-recovery-branch.test.js +226 -0
  83. package/dist/test/offline-recovery-branch.test.js.map +1 -0
  84. package/dist/test/present-while-acting.test.d.ts +3 -2
  85. package/dist/test/present-while-acting.test.d.ts.map +1 -1
  86. package/dist/test/present-while-acting.test.js +31 -3
  87. package/dist/test/present-while-acting.test.js.map +1 -1
  88. package/dist/test/refusal-single-call.test.d.ts +2 -0
  89. package/dist/test/refusal-single-call.test.d.ts.map +1 -0
  90. package/dist/test/refusal-single-call.test.js +177 -0
  91. package/dist/test/refusal-single-call.test.js.map +1 -0
  92. package/dist/test/same-round-think-policy.test.d.ts +2 -0
  93. package/dist/test/same-round-think-policy.test.d.ts.map +1 -0
  94. package/dist/test/same-round-think-policy.test.js +853 -0
  95. package/dist/test/same-round-think-policy.test.js.map +1 -0
  96. package/dist/test/workspace-read-image.test.d.ts +2 -0
  97. package/dist/test/workspace-read-image.test.d.ts.map +1 -0
  98. package/dist/test/workspace-read-image.test.js +518 -0
  99. package/dist/test/workspace-read-image.test.js.map +1 -0
  100. package/dist/tsconfig.tsbuildinfo +1 -1
  101. package/package.json +5 -3
  102. package/src/agent.ts +39 -2
  103. package/src/api/server.ts +8 -2
  104. package/src/framework.ts +1180 -79
  105. package/src/gate/event-gate.ts +15 -3
  106. package/src/index.ts +20 -0
  107. package/src/mcpl/channel-registry.ts +31 -16
  108. package/src/mcpl/server-connection.ts +163 -28
  109. package/src/modules/workspace/index.ts +759 -2
  110. package/src/modules/workspace/types.ts +5 -0
  111. package/src/recovery/discord-awareness-outbox.ts +459 -0
  112. package/src/recovery/offline-branch.ts +510 -0
  113. package/src/recovery/recover-cli.ts +130 -0
  114. package/src/types/agent.ts +14 -0
  115. package/src/types/framework.ts +17 -0
  116. package/src/types/module.ts +33 -0
  117. package/src/types/trace.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animalabs/agent-framework",
3
- "version": "0.6.6",
3
+ "version": "0.6.8",
4
4
  "description": "Multi-agent framework with pluggable modules, persistent state, and concurrent tool execution",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,10 +21,12 @@
21
21
  "src"
22
22
  ],
23
23
  "bin": {
24
- "agent-framework-mcp": "./dist/src/api/mcp-server.js"
24
+ "agent-framework-mcp": "./dist/src/api/mcp-server.js",
25
+ "agent-framework-recover": "./dist/src/recovery/recover-cli.js"
25
26
  },
26
27
  "scripts": {
27
28
  "build": "tsc",
29
+ "postbuild": "node -e \"const fs=require('node:fs'); for (const p of ['dist/src/api/mcp-server.js','dist/src/recovery/recover-cli.js']) fs.chmodSync(p, 0o755)\"",
28
30
  "dev": "tsc --watch",
29
31
  "clean": "rm -rf dist",
30
32
  "typecheck": "tsc --noEmit",
@@ -44,7 +46,7 @@
44
46
  "license": "MIT",
45
47
  "dependencies": {
46
48
  "@animalabs/chronicle": "^0.2.2",
47
- "@animalabs/context-manager": "^0.5.11",
49
+ "@animalabs/context-manager": "^0.5.13",
48
50
  "@animalabs/membrane": "^0.5.73",
49
51
  "chokidar": "^4.0.3",
50
52
  "discord.js": "^14.25.1",
package/src/agent.ts CHANGED
@@ -17,6 +17,8 @@ import type {
17
17
  import type {
18
18
  AgentConfig,
19
19
  AgentState,
20
+ SameRoundThinkTextPolicy,
21
+ SameRoundThinkTextPolicySource,
20
22
  PendingToolCall,
21
23
  CompletedToolCall,
22
24
  ToolCallId,
@@ -33,6 +35,7 @@ import type {
33
35
 
34
36
  const DEFAULT_CONTEXT_BUDGET_TOKENS = 100_000;
35
37
  const DEFAULT_TRANSITION_PACE_TOKENS = 16_000;
38
+ const DEFAULT_SAME_ROUND_THINK_TEXT_POLICY: SameRoundThinkTextPolicy = 'public';
36
39
 
37
40
  /**
38
41
  * An agent wraps a context manager and manages inference state.
@@ -63,6 +66,7 @@ export class Agent {
63
66
  readonly cacheTtl: NonNullable<AgentConfig['cacheTtl']>;
64
67
  /** Provider-specific request parameters forwarded unchanged by Membrane. */
65
68
  readonly providerParams?: Record<string, unknown>;
69
+ readonly sameRoundThinkTextPolicy: AgentConfig['sameRoundThinkTextPolicy'];
66
70
 
67
71
  private _state: AgentState = { status: 'idle' };
68
72
  private _inferenceStartedAt = 0;
@@ -76,6 +80,7 @@ export class Agent {
76
80
  private readonly configuredContextBudgetTokens?: number;
77
81
  private readonly configuredTailTokens?: number;
78
82
  private readonly configuredTransitionPaceTokens?: number;
83
+ private readonly configuredSameRoundThinkTextPolicy?: SameRoundThinkTextPolicy;
79
84
  private contextBudgetTargetTokens?: number;
80
85
  private runtimeSettingsOverrides: AgentRuntimeSettingsOverrides = {};
81
86
  private contextManager: ContextManager;
@@ -97,6 +102,7 @@ export class Agent {
97
102
  this.refusalHandling = config.refusalHandling;
98
103
  this.cacheTtl = config.cacheTtl ?? '1h';
99
104
  this.providerParams = config.providerParams;
105
+ this.sameRoundThinkTextPolicy = config.sameRoundThinkTextPolicy;
100
106
  this.maxStreamTokens = config.maxStreamTokens ?? 150_000;
101
107
  this.contextBudgetTokens = config.contextBudgetTokens;
102
108
  this.configuredContextBudgetTokens = config.contextBudgetTokens;
@@ -105,6 +111,7 @@ export class Agent {
105
111
  const hot = this.getHotContextSettings();
106
112
  this.configuredTailTokens = hot?.tailTokens;
107
113
  this.configuredTransitionPaceTokens = hot?.transitionPaceTokens;
114
+ this.configuredSameRoundThinkTextPolicy = config.sameRoundThinkTextPolicy;
108
115
  }
109
116
 
110
117
  /**
@@ -202,6 +209,8 @@ export class Agent {
202
209
  ...(hot?.transitionPaceTokens !== undefined
203
210
  ? { transitionPaceTokens: hot.transitionPaceTokens }
204
211
  : {}),
212
+ sameRoundThinkTextPolicy: this.getEffectiveSameRoundThinkTextPolicy(),
213
+ sameRoundThinkTextPolicySource: this.getSameRoundThinkTextPolicySource(),
205
214
  transition: this.contextBudgetTargetTokens === undefined
206
215
  ? 'stable'
207
216
  : hot?.blocked
@@ -219,6 +228,22 @@ export class Agent {
219
228
  return { ...this.runtimeSettingsOverrides };
220
229
  }
221
230
 
231
+ getEffectiveSameRoundThinkTextPolicy(): SameRoundThinkTextPolicy {
232
+ return this.runtimeSettingsOverrides.sameRoundThinkTextPolicy
233
+ ?? this.configuredSameRoundThinkTextPolicy
234
+ ?? DEFAULT_SAME_ROUND_THINK_TEXT_POLICY;
235
+ }
236
+
237
+ getSameRoundThinkTextPolicySource(): SameRoundThinkTextPolicySource {
238
+ if (this.runtimeSettingsOverrides.sameRoundThinkTextPolicy !== undefined) {
239
+ return 'runtime_override';
240
+ }
241
+ if (this.configuredSameRoundThinkTextPolicy !== undefined) {
242
+ return 'recipe';
243
+ }
244
+ return 'compatibility_default';
245
+ }
246
+
222
247
  updateRuntimeSettings(patch: AgentRuntimeSettingsPatch): AgentRuntimeSettingsSnapshot {
223
248
  this.validateRuntimeSettingsPatch(patch);
224
249
  let nextContextBudget = this.contextBudgetTokens;
@@ -263,13 +288,17 @@ export class Agent {
263
288
  this.runtimeSettingsOverrides.transitionPaceTokens = DEFAULT_TRANSITION_PACE_TOKENS;
264
289
  }
265
290
  for (const [key, value] of Object.entries(patch)) {
266
- if (value !== undefined) (this.runtimeSettingsOverrides as Record<string, number>)[key] = value;
291
+ if (key === 'sameRoundThinkTextPolicy') continue;
292
+ if (value !== undefined) (this.runtimeSettingsOverrides as Record<string, unknown>)[key] = value;
293
+ }
294
+ if (patch.sameRoundThinkTextPolicy !== undefined) {
295
+ this.runtimeSettingsOverrides.sameRoundThinkTextPolicy = patch.sameRoundThinkTextPolicy;
267
296
  }
268
297
  return this.getRuntimeSettings();
269
298
  }
270
299
 
271
300
  resetRuntimeSettings(keys?: Array<keyof AgentRuntimeSettingsPatch>): AgentRuntimeSettingsSnapshot {
272
- const reset = new Set(keys ?? ['contextBudgetTokens', 'tailTokens', 'transitionPaceTokens']);
301
+ const reset = new Set(keys ?? ['contextBudgetTokens', 'tailTokens', 'transitionPaceTokens', 'sameRoundThinkTextPolicy']);
273
302
  let nextContextBudget = this.contextBudgetTokens;
274
303
  let nextContextTarget = this.contextBudgetTargetTokens;
275
304
  const hotPatch: {
@@ -312,6 +341,9 @@ export class Agent {
312
341
  if (reset.has('transitionPaceTokens')) {
313
342
  delete this.runtimeSettingsOverrides.transitionPaceTokens;
314
343
  }
344
+ if (reset.has('sameRoundThinkTextPolicy')) {
345
+ delete this.runtimeSettingsOverrides.sameRoundThinkTextPolicy;
346
+ }
315
347
  return this.getRuntimeSettings();
316
348
  }
317
349
 
@@ -348,6 +380,11 @@ export class Agent {
348
380
  (!Number.isSafeInteger(patch.transitionPaceTokens) || patch.transitionPaceTokens <= 0)) {
349
381
  throw new Error('transitionPaceTokens must be a positive safe integer');
350
382
  }
383
+ if (patch.sameRoundThinkTextPolicy !== undefined &&
384
+ patch.sameRoundThinkTextPolicy !== 'public' &&
385
+ patch.sameRoundThinkTextPolicy !== 'private') {
386
+ throw new Error("sameRoundThinkTextPolicy must be 'public' or 'private'");
387
+ }
351
388
  if ((patch.tailTokens !== undefined || patch.transitionPaceTokens !== undefined) &&
352
389
  !this.getHotContextSettings()) {
353
390
  throw new Error('The active context strategy does not support live tail/transition settings');
package/src/api/server.ts CHANGED
@@ -468,6 +468,10 @@ export class ApiServer {
468
468
  store.switchBranch(params.name);
469
469
  this.currentBranch = params.name;
470
470
 
471
+ // Reversible Discord awareness markers are part of the branch projection.
472
+ // Do not acknowledge the switch until add/remove operations were attempted.
473
+ await this.framework.syncDiscordAwarenessMarkers();
474
+
471
475
  // Materialize config files from the new branch
472
476
  const ws = this.framework.getModule('workspace');
473
477
  if (ws && 'materializeMount' in ws) {
@@ -511,7 +515,7 @@ export class ApiServer {
511
515
  // Undo/Redo Commands
512
516
  // ==========================================================================
513
517
 
514
- private cmdUndo(params: { agentName: string }): unknown {
518
+ private async cmdUndo(params: { agentName: string }): Promise<unknown> {
515
519
  if (!params.agentName) {
516
520
  throw new Error('agentName is required');
517
521
  }
@@ -520,6 +524,7 @@ export class ApiServer {
520
524
 
521
525
  if (result.undone) {
522
526
  this.currentBranch = result.toBranch!;
527
+ await this.framework.syncDiscordAwarenessMarkers();
523
528
  this.broadcast('branch:switched', {
524
529
  from: result.fromBranch,
525
530
  to: result.toBranch,
@@ -530,7 +535,7 @@ export class ApiServer {
530
535
  return result;
531
536
  }
532
537
 
533
- private cmdRedo(params: { agentName: string }): unknown {
538
+ private async cmdRedo(params: { agentName: string }): Promise<unknown> {
534
539
  if (!params.agentName) {
535
540
  throw new Error('agentName is required');
536
541
  }
@@ -539,6 +544,7 @@ export class ApiServer {
539
544
 
540
545
  if (result.redone) {
541
546
  this.currentBranch = result.toBranch!;
547
+ await this.framework.syncDiscordAwarenessMarkers();
542
548
  this.broadcast('branch:switched', {
543
549
  from: result.fromBranch,
544
550
  to: result.toBranch,