@animalabs/agent-framework 0.6.5 → 0.6.7

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 (155) hide show
  1. package/README.md +78 -0
  2. package/dist/src/agent.d.ts +56 -2
  3. package/dist/src/agent.d.ts.map +1 -1
  4. package/dist/src/agent.js +372 -57
  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/canonical-json.d.ts +2 -0
  11. package/dist/src/canonical-json.d.ts.map +1 -0
  12. package/dist/src/canonical-json.js +23 -0
  13. package/dist/src/canonical-json.js.map +1 -0
  14. package/dist/src/framework.d.ts +160 -2
  15. package/dist/src/framework.d.ts.map +1 -1
  16. package/dist/src/framework.js +3098 -167
  17. package/dist/src/framework.js.map +1 -1
  18. package/dist/src/gate/event-gate.d.ts.map +1 -1
  19. package/dist/src/gate/event-gate.js +34 -4
  20. package/dist/src/gate/event-gate.js.map +1 -1
  21. package/dist/src/index.d.ts +4 -0
  22. package/dist/src/index.d.ts.map +1 -1
  23. package/dist/src/index.js +3 -0
  24. package/dist/src/index.js.map +1 -1
  25. package/dist/src/mcpl/channel-registry.d.ts +36 -15
  26. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  27. package/dist/src/mcpl/channel-registry.js +322 -76
  28. package/dist/src/mcpl/channel-registry.js.map +1 -1
  29. package/dist/src/mcpl/push-handler.d.ts +1 -0
  30. package/dist/src/mcpl/push-handler.d.ts.map +1 -1
  31. package/dist/src/mcpl/push-handler.js +1 -0
  32. package/dist/src/mcpl/push-handler.js.map +1 -1
  33. package/dist/src/mcpl/server-connection.d.ts +39 -4
  34. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  35. package/dist/src/mcpl/server-connection.js +146 -28
  36. package/dist/src/mcpl/server-connection.js.map +1 -1
  37. package/dist/src/mcpl/types.d.ts +43 -12
  38. package/dist/src/mcpl/types.d.ts.map +1 -1
  39. package/dist/src/mcpl/types.js +1 -0
  40. package/dist/src/mcpl/types.js.map +1 -1
  41. package/dist/src/modules/workspace/index.d.ts +12 -1
  42. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  43. package/dist/src/modules/workspace/index.js +661 -2
  44. package/dist/src/modules/workspace/index.js.map +1 -1
  45. package/dist/src/modules/workspace/types.d.ts +4 -0
  46. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  47. package/dist/src/modules/workspace/types.js.map +1 -1
  48. package/dist/src/recovery/discord-awareness-outbox.d.ts +99 -0
  49. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -0
  50. package/dist/src/recovery/discord-awareness-outbox.js +334 -0
  51. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -0
  52. package/dist/src/recovery/offline-branch.d.ts +45 -0
  53. package/dist/src/recovery/offline-branch.d.ts.map +1 -0
  54. package/dist/src/recovery/offline-branch.js +362 -0
  55. package/dist/src/recovery/offline-branch.js.map +1 -0
  56. package/dist/src/recovery/recover-cli.d.ts +3 -0
  57. package/dist/src/recovery/recover-cli.d.ts.map +1 -0
  58. package/dist/src/recovery/recover-cli.js +129 -0
  59. package/dist/src/recovery/recover-cli.js.map +1 -0
  60. package/dist/src/types/agent.d.ts +37 -0
  61. package/dist/src/types/agent.d.ts.map +1 -1
  62. package/dist/src/types/events.d.ts +1 -0
  63. package/dist/src/types/events.d.ts.map +1 -1
  64. package/dist/src/types/framework.d.ts +14 -0
  65. package/dist/src/types/framework.d.ts.map +1 -1
  66. package/dist/src/types/module.d.ts +31 -0
  67. package/dist/src/types/module.d.ts.map +1 -1
  68. package/dist/src/types/trace.d.ts +4 -0
  69. package/dist/src/types/trace.d.ts.map +1 -1
  70. package/dist/test/agent-runtime-settings.test.d.ts +2 -0
  71. package/dist/test/agent-runtime-settings.test.d.ts.map +1 -0
  72. package/dist/test/agent-runtime-settings.test.js +227 -0
  73. package/dist/test/agent-runtime-settings.test.js.map +1 -0
  74. package/dist/test/busy-agent-scheduler.test.d.ts +2 -0
  75. package/dist/test/busy-agent-scheduler.test.d.ts.map +1 -0
  76. package/dist/test/busy-agent-scheduler.test.js +62 -0
  77. package/dist/test/busy-agent-scheduler.test.js.map +1 -0
  78. package/dist/test/channel-lifecycle-provenance.test.d.ts +2 -0
  79. package/dist/test/channel-lifecycle-provenance.test.d.ts.map +1 -0
  80. package/dist/test/channel-lifecycle-provenance.test.js +47 -0
  81. package/dist/test/channel-lifecycle-provenance.test.js.map +1 -0
  82. package/dist/test/channel-registry-routing.test.js +5 -4
  83. package/dist/test/channel-registry-routing.test.js.map +1 -1
  84. package/dist/test/conversation-fork-injection-scoping.test.js +12 -1
  85. package/dist/test/conversation-fork-injection-scoping.test.js.map +1 -1
  86. package/dist/test/discord-awareness-outbox.test.d.ts +2 -0
  87. package/dist/test/discord-awareness-outbox.test.d.ts.map +1 -0
  88. package/dist/test/discord-awareness-outbox.test.js +248 -0
  89. package/dist/test/discord-awareness-outbox.test.js.map +1 -0
  90. package/dist/test/event-gate.test.js +21 -1
  91. package/dist/test/event-gate.test.js.map +1 -1
  92. package/dist/test/helpers/mock-membrane.d.ts +13 -1
  93. package/dist/test/helpers/mock-membrane.d.ts.map +1 -1
  94. package/dist/test/helpers/mock-membrane.js +9 -2
  95. package/dist/test/helpers/mock-membrane.js.map +1 -1
  96. package/dist/test/maintenance-timer.test.js +103 -1
  97. package/dist/test/maintenance-timer.test.js.map +1 -1
  98. package/dist/test/mcpl-awareness-barrier.test.d.ts +2 -0
  99. package/dist/test/mcpl-awareness-barrier.test.d.ts.map +1 -0
  100. package/dist/test/mcpl-awareness-barrier.test.js +845 -0
  101. package/dist/test/mcpl-awareness-barrier.test.js.map +1 -0
  102. package/dist/test/mcpl-gate-roundtrip.test.js +138 -6
  103. package/dist/test/mcpl-gate-roundtrip.test.js.map +1 -1
  104. package/dist/test/mcpl-reconnect-reregistration.test.js +22 -3
  105. package/dist/test/mcpl-reconnect-reregistration.test.js.map +1 -1
  106. package/dist/test/mcpl-request-timeout.test.js +15 -0
  107. package/dist/test/mcpl-request-timeout.test.js.map +1 -1
  108. package/dist/test/offline-recovery-branch.test.d.ts +2 -0
  109. package/dist/test/offline-recovery-branch.test.d.ts.map +1 -0
  110. package/dist/test/offline-recovery-branch.test.js +226 -0
  111. package/dist/test/offline-recovery-branch.test.js.map +1 -0
  112. package/dist/test/present-while-acting.test.d.ts +19 -0
  113. package/dist/test/present-while-acting.test.d.ts.map +1 -0
  114. package/dist/test/present-while-acting.test.js +295 -0
  115. package/dist/test/present-while-acting.test.js.map +1 -0
  116. package/dist/test/primary-summary-refusal-fallback-integration.test.d.ts +2 -0
  117. package/dist/test/primary-summary-refusal-fallback-integration.test.d.ts.map +1 -0
  118. package/dist/test/primary-summary-refusal-fallback-integration.test.js +1955 -0
  119. package/dist/test/primary-summary-refusal-fallback-integration.test.js.map +1 -0
  120. package/dist/test/primary-summary-refusal-fallback.test.d.ts +2 -0
  121. package/dist/test/primary-summary-refusal-fallback.test.d.ts.map +1 -0
  122. package/dist/test/primary-summary-refusal-fallback.test.js +753 -0
  123. package/dist/test/primary-summary-refusal-fallback.test.js.map +1 -0
  124. package/dist/test/same-round-think-policy.test.d.ts +2 -0
  125. package/dist/test/same-round-think-policy.test.d.ts.map +1 -0
  126. package/dist/test/same-round-think-policy.test.js +853 -0
  127. package/dist/test/same-round-think-policy.test.js.map +1 -0
  128. package/dist/test/trunk-channel-routing.test.js +38 -0
  129. package/dist/test/trunk-channel-routing.test.js.map +1 -1
  130. package/dist/test/workspace-read-image.test.d.ts +2 -0
  131. package/dist/test/workspace-read-image.test.d.ts.map +1 -0
  132. package/dist/test/workspace-read-image.test.js +518 -0
  133. package/dist/test/workspace-read-image.test.js.map +1 -0
  134. package/dist/tsconfig.tsbuildinfo +1 -1
  135. package/package.json +6 -4
  136. package/src/agent.ts +485 -63
  137. package/src/api/server.ts +8 -2
  138. package/src/canonical-json.ts +22 -0
  139. package/src/framework.ts +4096 -304
  140. package/src/gate/event-gate.ts +50 -4
  141. package/src/index.ts +20 -0
  142. package/src/mcpl/channel-registry.ts +396 -85
  143. package/src/mcpl/push-handler.ts +2 -0
  144. package/src/mcpl/server-connection.ts +173 -28
  145. package/src/mcpl/types.ts +49 -12
  146. package/src/modules/workspace/index.ts +759 -2
  147. package/src/modules/workspace/types.ts +5 -0
  148. package/src/recovery/discord-awareness-outbox.ts +459 -0
  149. package/src/recovery/offline-branch.ts +510 -0
  150. package/src/recovery/recover-cli.ts +130 -0
  151. package/src/types/agent.ts +44 -0
  152. package/src/types/events.ts +1 -1
  153. package/src/types/framework.ts +17 -0
  154. package/src/types/module.ts +33 -0
  155. package/src/types/trace.ts +4 -0
@@ -65,6 +65,17 @@ interface PendingEvent {
65
65
  content: string;
66
66
  eventType: string;
67
67
  timestamp: number;
68
+ /** The framework stores MCPL event content in the context window AT ARRIVAL
69
+ * (channel-incoming and push-event both addMessage before the gate decides
70
+ * anything). For those, the debounced wake must NOT re-quote the content —
71
+ * a [Gate:] copy delivered minutes later reads as a fresh, stale duplicate
72
+ * of a message the agent may have long since handled. */
73
+ inContext: boolean;
74
+ channelId?: string;
75
+ /** Human-readable channel name (e.g. Discord channel name) when the event's
76
+ * metadata carries one — batched-wake lines render this instead of the raw
77
+ * composite channel id. */
78
+ channelLabel?: string;
68
79
  }
69
80
 
70
81
  interface DebounceState {
@@ -1020,6 +1031,12 @@ export class EventGate {
1020
1031
  : info.content,
1021
1032
  eventType: info.eventType,
1022
1033
  timestamp: Date.now(),
1034
+ inContext: info.eventType === 'mcpl:channel-incoming' || info.eventType === 'mcpl:push-event',
1035
+ channelId: info.channelId || undefined,
1036
+ channelLabel:
1037
+ typeof info.metadata?.channelName === 'string' && info.metadata.channelName
1038
+ ? (info.metadata.channelName as string)
1039
+ : undefined,
1023
1040
  };
1024
1041
 
1025
1042
  const existing = this.debounceTimers.get(policy.name);
@@ -1067,11 +1084,40 @@ export class EventGate {
1067
1084
  if (events.length === 0) return;
1068
1085
 
1069
1086
  const policyNames = [...new Set(events.map(e => e.policyName))];
1070
- const lines = events
1071
- .map(e => `- [${e.policyName}] (${e.eventType}): ${e.content}`)
1072
- .join('\n');
1073
1087
 
1074
- const text = `[Gate: ${events.length} event${events.length > 1 ? 's' : ''} matched]\n\n${lines}`;
1088
+ // Events whose content the framework already stored at arrival (MCPL
1089
+ // channel-incoming / push-event) get a compact REFERENCE — re-quoting
1090
+ // them here would inject a duplicate copy of the message minutes after
1091
+ // the fact, reading as fresh input the agent may have already handled.
1092
+ // Only events with no context entry of their own carry their content.
1093
+ const quoted = events.filter(e => !e.inContext);
1094
+ const referenced = events.filter(e => e.inContext);
1095
+
1096
+ const lines: string[] = quoted.map(e => `- [${e.policyName}] (${e.eventType}): ${e.content}`);
1097
+ if (referenced.length > 0) {
1098
+ const byChannel = new Map<string, { count: number; oldest: number; label?: string }>();
1099
+ for (const e of referenced) {
1100
+ const key = e.channelId ?? '(unknown channel)';
1101
+ const entry = byChannel.get(key) ?? { count: 0, oldest: e.timestamp, label: e.channelLabel };
1102
+ entry.count += 1;
1103
+ entry.oldest = Math.min(entry.oldest, e.timestamp);
1104
+ entry.label = entry.label ?? e.channelLabel;
1105
+ byChannel.set(key, entry);
1106
+ }
1107
+ for (const [channelId, { count, oldest, label }] of byChannel) {
1108
+ // Prefer the human-readable name; keep the id parenthesized so the
1109
+ // agent can still address tools that want the composite id.
1110
+ const channel = label ? `#${label} (${channelId})` : channelId;
1111
+ const age = Math.round((Date.now() - oldest) / 1000);
1112
+ lines.push(
1113
+ `- ${count} message${count > 1 ? 's' : ''} in ${channel} ` +
1114
+ `(oldest ~${age}s ago) — already shown above at arrival; this is a ` +
1115
+ `batched wake, not new content`,
1116
+ );
1117
+ }
1118
+ }
1119
+
1120
+ const text = `[Gate: ${events.length} event${events.length > 1 ? 's' : ''} matched]\n\n${lines.join('\n')}`;
1075
1121
 
1076
1122
  this.addMessageFn('user', [{ type: 'text', text }], {
1077
1123
  source: 'gate:debounce',
package/src/index.ts CHANGED
@@ -91,3 +91,23 @@ export type { ContextManager, ContextStrategy, TokenBudget } from '@animalabs/co
91
91
  export { PassthroughStrategy, AutobiographicalStrategy, KnowledgeStrategy } from '@animalabs/context-manager';
92
92
  export type { KnowledgeConfig, PhaseType } from '@animalabs/context-manager';
93
93
  export type { Membrane, NormalizedMessage, NormalizedRequest, ContentBlock } from '@animalabs/membrane';
94
+
95
+ // Offline outage recovery and branch-independent Discord awareness markers
96
+ export {
97
+ DiscordAwarenessOutbox,
98
+ DEFAULT_DISCORD_AWARENESS_EMOJI,
99
+ defaultDiscordAwarenessOutboxPath,
100
+ extractDiscordAwarenessRefs,
101
+ } from './recovery/discord-awareness-outbox.js';
102
+ export type {
103
+ DiscordAwarenessBatch,
104
+ DiscordAwarenessEntry,
105
+ DiscordAwarenessOperation,
106
+ DiscordAwarenessRef,
107
+ DiscordSuppressionInterval,
108
+ } from './recovery/discord-awareness-outbox.js';
109
+ export { createOfflineRecoveryBranch } from './recovery/offline-branch.js';
110
+ export type {
111
+ OfflineRecoveryBranchOptions,
112
+ OfflineRecoveryBranchResult,
113
+ } from './recovery/offline-branch.js';