@animalabs/agent-framework 0.13.0 → 0.15.0
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/dist/src/agent.d.ts +10 -0
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +39 -0
- package/dist/src/agent.js.map +1 -1
- package/dist/src/framework.d.ts +36 -6
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +451 -83
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +55 -1
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +41 -1
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/gate/index.d.ts +1 -1
- package/dist/src/gate/index.d.ts.map +1 -1
- package/dist/src/gate/index.js +1 -1
- package/dist/src/gate/index.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/modules/history/index.d.ts +69 -0
- package/dist/src/modules/history/index.d.ts.map +1 -0
- package/dist/src/modules/history/index.js +519 -0
- package/dist/src/modules/history/index.js.map +1 -0
- package/dist/src/modules/history/search-regex-worker.d.ts +23 -0
- package/dist/src/modules/history/search-regex-worker.d.ts.map +1 -0
- package/dist/src/modules/history/search-regex-worker.js +57 -0
- package/dist/src/modules/history/search-regex-worker.js.map +1 -0
- package/dist/src/modules/index.d.ts +1 -0
- package/dist/src/modules/index.d.ts.map +1 -1
- package/dist/src/modules/index.js +1 -0
- package/dist/src/modules/index.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +42 -1
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/types.d.ts +5 -0
- package/dist/src/modules/workspace/types.d.ts.map +1 -1
- package/dist/src/modules/workspace/types.js.map +1 -1
- package/dist/src/tool-image-ledger.d.ts +175 -0
- package/dist/src/tool-image-ledger.d.ts.map +1 -0
- package/dist/src/tool-image-ledger.js +257 -0
- package/dist/src/tool-image-ledger.js.map +1 -0
- package/dist/src/tool-result-history.d.ts +15 -2
- package/dist/src/tool-result-history.d.ts.map +1 -1
- package/dist/src/tool-result-history.js +16 -9
- package/dist/src/tool-result-history.js.map +1 -1
- package/dist/src/types/agent.d.ts +10 -0
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +4 -0
- package/dist/src/types/trace.d.ts.map +1 -1
- package/dist/test/event-gate.test.js +84 -1
- package/dist/test/event-gate.test.js.map +1 -1
- package/dist/test/history-module.test.d.ts +2 -0
- package/dist/test/history-module.test.d.ts.map +1 -0
- package/dist/test/history-module.test.js +449 -0
- package/dist/test/history-module.test.js.map +1 -0
- package/dist/test/kv-unified-open-flight-retry.test.d.ts +2 -0
- package/dist/test/kv-unified-open-flight-retry.test.d.ts.map +1 -0
- package/dist/test/kv-unified-open-flight-retry.test.js +189 -0
- package/dist/test/kv-unified-open-flight-retry.test.js.map +1 -0
- package/dist/test/kv-unified-wiring.test.js +39 -0
- package/dist/test/kv-unified-wiring.test.js.map +1 -1
- package/dist/test/puppet-tool-call.test.js +114 -1
- package/dist/test/puppet-tool-call.test.js.map +1 -1
- package/dist/test/puppet-turn-reservation.test.d.ts +2 -0
- package/dist/test/puppet-turn-reservation.test.d.ts.map +1 -0
- package/dist/test/puppet-turn-reservation.test.js +139 -0
- package/dist/test/puppet-turn-reservation.test.js.map +1 -0
- package/dist/test/save-recent-image.test.d.ts +26 -0
- package/dist/test/save-recent-image.test.d.ts.map +1 -0
- package/dist/test/save-recent-image.test.js +736 -0
- package/dist/test/save-recent-image.test.js.map +1 -0
- package/dist/test/tool-result-spill.test.js +114 -0
- package/dist/test/tool-result-spill.test.js.map +1 -1
- package/dist/test/turn-trigger-provenance.test.js +17 -0
- package/dist/test/turn-trigger-provenance.test.js.map +1 -1
- package/dist/test/workspace-read-text.test.d.ts +2 -0
- package/dist/test/workspace-read-text.test.d.ts.map +1 -0
- package/dist/test/workspace-read-text.test.js +101 -0
- package/dist/test/workspace-read-text.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/agent.ts +41 -0
- package/src/framework.ts +519 -95
- package/src/gate/event-gate.ts +71 -3
- package/src/gate/index.ts +1 -1
- package/src/index.ts +1 -1
- package/src/modules/history/index.ts +613 -0
- package/src/modules/history/search-regex-worker.ts +76 -0
- package/src/modules/index.ts +2 -0
- package/src/modules/workspace/index.ts +42 -1
- package/src/modules/workspace/types.ts +5 -0
- package/src/tool-image-ledger.ts +334 -0
- package/src/tool-result-history.ts +30 -9
- package/src/types/agent.ts +10 -0
- package/src/types/trace.ts +4 -0
package/src/gate/event-gate.ts
CHANGED
|
@@ -78,6 +78,37 @@ interface PendingEvent {
|
|
|
78
78
|
* metadata carries one — batched-wake lines render this instead of the raw
|
|
79
79
|
* composite channel id. */
|
|
80
80
|
channelLabel?: string;
|
|
81
|
+
/** Author id of the event (discord snowflake etc.), when the metadata carries
|
|
82
|
+
* one — a debounced wake names the newest such author as its counterparty. */
|
|
83
|
+
authorId?: string;
|
|
84
|
+
/** MCPL server id the event came from — the namespace for the counterparty
|
|
85
|
+
* (`<serverId>:user:<id>`), same as the direct channel-incoming path. */
|
|
86
|
+
serverId?: string;
|
|
87
|
+
/** `chat:addressed` (mention / reply-to-bot / DM): an addressed event outranks
|
|
88
|
+
* newer ambient chatter when a batched wake picks its provenance — the same
|
|
89
|
+
* rule the framework applies to the turn's speech locus. */
|
|
90
|
+
addressed: boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Where a gate-requested wake came from, handed to the framework alongside the
|
|
95
|
+
* reason so the turn's InferenceRequest can carry it (host telemetry stamps
|
|
96
|
+
* "who woke the agent" from it). Ids only, never content or display names.
|
|
97
|
+
*/
|
|
98
|
+
export interface WakeProvenance {
|
|
99
|
+
/** Composite channel id of the chosen event — telemetry only, never a
|
|
100
|
+
* speech locus. Omitted for `mcpl:push-event` events, whose channel ids
|
|
101
|
+
* are raw server ids (unroutable and a second spelling of the same
|
|
102
|
+
* channel); the framework derives the composite id on the direct path. */
|
|
103
|
+
channelId?: string;
|
|
104
|
+
/** Server-namespaced author id: `<serverId>:user:<id>` (falls back to the
|
|
105
|
+
* channel id's first segment only when the event carried no server id). */
|
|
106
|
+
counterparty?: string;
|
|
107
|
+
/** True when the chosen event was `chat:addressed`. */
|
|
108
|
+
addressed?: boolean;
|
|
109
|
+
/** Timestamp (ms) of the chosen event, so a consumer coalescing several
|
|
110
|
+
* requests can order by event recency, not by flush order. */
|
|
111
|
+
at?: number;
|
|
81
112
|
}
|
|
82
113
|
|
|
83
114
|
interface DebounceState {
|
|
@@ -149,6 +180,34 @@ function isMetadataTruthy(value: unknown): boolean {
|
|
|
149
180
|
return Boolean(value);
|
|
150
181
|
}
|
|
151
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Provenance of a batched wake: the newest ADDRESSED channel-bearing event
|
|
185
|
+
* wins (mention / reply / DM outranks newer ambient chatter — the framework's
|
|
186
|
+
* own locus rule); else the newest channel-bearing event. Channel, author and
|
|
187
|
+
* addressed all come from that one event, so they can never disagree.
|
|
188
|
+
*/
|
|
189
|
+
export function wakeProvenance(events: PendingEvent[]): WakeProvenance | undefined {
|
|
190
|
+
let newest: PendingEvent | undefined;
|
|
191
|
+
let newestAddressed: PendingEvent | undefined;
|
|
192
|
+
for (const e of events) {
|
|
193
|
+
if (!e.channelId && !e.authorId) continue;
|
|
194
|
+
if (!newest || e.timestamp >= newest.timestamp) newest = e;
|
|
195
|
+
if (e.addressed && (!newestAddressed || e.timestamp >= newestAddressed.timestamp)) newestAddressed = e;
|
|
196
|
+
}
|
|
197
|
+
const pick = newestAddressed ?? newest;
|
|
198
|
+
if (!pick) return undefined;
|
|
199
|
+
// push-event channel ids are the adapter's raw ids (a Discord snowflake):
|
|
200
|
+
// not a composite channel id, so not reported as one
|
|
201
|
+
const channelId = pick.channelId && pick.eventType !== 'mcpl:push-event' ? pick.channelId : undefined;
|
|
202
|
+
const ns = pick.serverId || (pick.channelId ? pick.channelId.split(':')[0] : '') || 'channel';
|
|
203
|
+
return {
|
|
204
|
+
...(channelId ? { channelId } : {}),
|
|
205
|
+
...(pick.authorId ? { counterparty: `${ns}:user:${pick.authorId}` } : {}),
|
|
206
|
+
...(pick.addressed ? { addressed: true } : {}),
|
|
207
|
+
at: pick.timestamp,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
152
211
|
/** Compact, log-friendly serialization of a GateBehavior. */
|
|
153
212
|
function formatBehavior(b: import('./types.js').GateBehavior): string {
|
|
154
213
|
if (typeof b === 'string') return b;
|
|
@@ -522,7 +581,7 @@ export class EventGate {
|
|
|
522
581
|
/** Registry agent to deliver into; absent = primary (historical). */
|
|
523
582
|
forAgent?: string,
|
|
524
583
|
) => unknown;
|
|
525
|
-
private requestInferenceFn: (agentName: string, reason: string, source: string) => void;
|
|
584
|
+
private requestInferenceFn: (agentName: string, reason: string, source: string, provenance?: WakeProvenance) => void;
|
|
526
585
|
private getAgentNamesFn: () => string[];
|
|
527
586
|
/** Clock injection — keeps the new rate_limit / passive_sample paths
|
|
528
587
|
* testable without monkey-patching Date.now globally. */
|
|
@@ -539,7 +598,7 @@ export class EventGate {
|
|
|
539
598
|
metadata?: Record<string, unknown>,
|
|
540
599
|
forAgent?: string,
|
|
541
600
|
) => unknown;
|
|
542
|
-
requestInference: (agentName: string, reason: string, source: string) => void;
|
|
601
|
+
requestInference: (agentName: string, reason: string, source: string, provenance?: WakeProvenance) => void;
|
|
543
602
|
getAgentNames: () => string[];
|
|
544
603
|
/** Optional clock — defaults to Date.now. Tests inject for deterministic time. */
|
|
545
604
|
now?: () => number;
|
|
@@ -1385,6 +1444,9 @@ export class EventGate {
|
|
|
1385
1444
|
typeof info.metadata?.channelName === 'string' && info.metadata.channelName
|
|
1386
1445
|
? (info.metadata.channelName as string)
|
|
1387
1446
|
: undefined,
|
|
1447
|
+
authorId: this.extractAuthorId(info.metadata) ?? undefined,
|
|
1448
|
+
serverId: info.serverId || undefined,
|
|
1449
|
+
addressed: Array.isArray(info.tags) && info.tags.includes('chat:addressed'),
|
|
1388
1450
|
};
|
|
1389
1451
|
|
|
1390
1452
|
const existing = this.debounceTimers.get(policy.name);
|
|
@@ -1472,8 +1534,14 @@ export class EventGate {
|
|
|
1472
1534
|
policies: policyNames,
|
|
1473
1535
|
});
|
|
1474
1536
|
|
|
1537
|
+
// Provenance of the batched wake (telemetry: who/where woke the agent):
|
|
1538
|
+
// the newest ADDRESSED event first, else the newest event naming a
|
|
1539
|
+
// channel or an author; channel + author + addressed from that ONE
|
|
1540
|
+
// event. It does not set the turn's speech locus — the framework keeps
|
|
1541
|
+
// its own routing rule for that.
|
|
1542
|
+
const provenance = wakeProvenance(events);
|
|
1475
1543
|
for (const agentName of this.getAgentNamesFn()) {
|
|
1476
|
-
this.requestInferenceFn(agentName, 'gate:debounce', 'gate');
|
|
1544
|
+
this.requestInferenceFn(agentName, 'gate:debounce', 'gate', provenance);
|
|
1477
1545
|
}
|
|
1478
1546
|
}
|
|
1479
1547
|
|
package/src/gate/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -76,7 +76,7 @@ export type {
|
|
|
76
76
|
export type { SessionUsage, AgentUsage, SessionUsageSnapshot, UsageUpdatedEvent } from './usage/index.js';
|
|
77
77
|
|
|
78
78
|
// EventGate
|
|
79
|
-
export { EventGate } from './gate/index.js';
|
|
79
|
+
export { EventGate, type WakeProvenance } from './gate/index.js';
|
|
80
80
|
export type { GateConfig, GateOptions, GatePolicy, GatePolicyMatch, GateBehavior } from './gate/index.js';
|
|
81
81
|
|
|
82
82
|
// MCPL channel registry (exposed for modules that need channel-level operations)
|