@animalabs/agent-framework 0.11.0 → 0.13.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 +11 -1
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +60 -4
- package/dist/src/agent.js.map +1 -1
- package/dist/src/framework.d.ts +72 -1
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +873 -123
- package/dist/src/framework.js.map +1 -1
- package/dist/src/gate/event-gate.d.ts +7 -1
- package/dist/src/gate/event-gate.d.ts.map +1 -1
- package/dist/src/gate/event-gate.js +15 -1
- package/dist/src/gate/event-gate.js.map +1 -1
- package/dist/src/kv-unified-wire.d.ts +16 -0
- package/dist/src/kv-unified-wire.d.ts.map +1 -0
- package/dist/src/kv-unified-wire.js +2 -0
- package/dist/src/kv-unified-wire.js.map +1 -0
- package/dist/src/mcpl/channel-registry.d.ts +84 -1
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
- package/dist/src/mcpl/channel-registry.js +188 -5
- package/dist/src/mcpl/channel-registry.js.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -1
- package/dist/src/mcpl/hook-orchestrator.js +28 -2
- package/dist/src/mcpl/hook-orchestrator.js.map +1 -1
- package/dist/src/mcpl/push-handler.d.ts +6 -1
- package/dist/src/mcpl/push-handler.d.ts.map +1 -1
- package/dist/src/mcpl/push-handler.js +29 -2
- package/dist/src/mcpl/push-handler.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +59 -0
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -0
- package/dist/src/mcpl/reference-fetcher.js +240 -0
- package/dist/src/mcpl/reference-fetcher.js.map +1 -0
- package/dist/src/mcpl/references.d.ts +125 -0
- package/dist/src/mcpl/references.d.ts.map +1 -0
- package/dist/src/mcpl/references.js +262 -0
- package/dist/src/mcpl/references.js.map +1 -0
- package/dist/src/mcpl/types.d.ts +32 -0
- package/dist/src/mcpl/types.d.ts.map +1 -1
- package/dist/src/mcpl/types.js.map +1 -1
- package/dist/src/modules/index.d.ts +2 -1
- package/dist/src/modules/index.d.ts.map +1 -1
- package/dist/src/modules/index.js +1 -1
- package/dist/src/modules/index.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts +125 -2
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +354 -58
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/types.d.ts +7 -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-result-history.d.ts.map +1 -1
- package/dist/src/tool-result-history.js +14 -0
- package/dist/src/tool-result-history.js.map +1 -1
- package/dist/src/tool-wrapper-prose-guard.d.ts +8 -0
- package/dist/src/tool-wrapper-prose-guard.d.ts.map +1 -0
- package/dist/src/tool-wrapper-prose-guard.js +37 -0
- package/dist/src/tool-wrapper-prose-guard.js.map +1 -0
- package/dist/src/tune-out/coordinator.d.ts +144 -0
- package/dist/src/tune-out/coordinator.d.ts.map +1 -0
- package/dist/src/tune-out/coordinator.js +444 -0
- package/dist/src/tune-out/coordinator.js.map +1 -0
- package/dist/src/tune-out/tools.d.ts +43 -0
- package/dist/src/tune-out/tools.d.ts.map +1 -0
- package/dist/src/tune-out/tools.js +93 -0
- package/dist/src/tune-out/tools.js.map +1 -0
- package/dist/src/types/agent.d.ts +15 -0
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/framework.d.ts +6 -0
- package/dist/src/types/framework.d.ts.map +1 -1
- package/dist/src/usage-accounting.d.ts +5 -0
- package/dist/src/usage-accounting.d.ts.map +1 -0
- package/dist/src/usage-accounting.js +11 -0
- package/dist/src/usage-accounting.js.map +1 -0
- package/dist/test/channel-incoming-targeting.test.d.ts +2 -0
- package/dist/test/channel-incoming-targeting.test.d.ts.map +1 -0
- package/dist/test/channel-incoming-targeting.test.js +81 -0
- package/dist/test/channel-incoming-targeting.test.js.map +1 -0
- package/dist/test/conversation-routing.test.js +39 -0
- package/dist/test/conversation-routing.test.js.map +1 -1
- package/dist/test/kv-unified-wiring.test.d.ts +2 -0
- package/dist/test/kv-unified-wiring.test.d.ts.map +1 -0
- package/dist/test/kv-unified-wiring.test.js +56 -0
- package/dist/test/kv-unified-wiring.test.js.map +1 -0
- package/dist/test/mcpl-push-convert.test.d.ts +2 -0
- package/dist/test/mcpl-push-convert.test.d.ts.map +1 -0
- package/dist/test/mcpl-push-convert.test.js +42 -0
- package/dist/test/mcpl-push-convert.test.js.map +1 -0
- package/dist/test/mcpl-reference-fetcher.test.d.ts +2 -0
- package/dist/test/mcpl-reference-fetcher.test.d.ts.map +1 -0
- package/dist/test/mcpl-reference-fetcher.test.js +199 -0
- package/dist/test/mcpl-reference-fetcher.test.js.map +1 -0
- package/dist/test/per-agent-delivery.test.d.ts +2 -0
- package/dist/test/per-agent-delivery.test.d.ts.map +1 -0
- package/dist/test/per-agent-delivery.test.js +108 -0
- package/dist/test/per-agent-delivery.test.js.map +1 -0
- package/dist/test/present-while-acting.test.js +64 -0
- package/dist/test/present-while-acting.test.js.map +1 -1
- package/dist/test/tool-result-history.test.js +78 -0
- package/dist/test/tool-result-history.test.js.map +1 -1
- package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts +2 -0
- package/dist/test/tool-wrapper-prose-guard-integration.test.d.ts.map +1 -0
- package/dist/test/tool-wrapper-prose-guard-integration.test.js +485 -0
- package/dist/test/tool-wrapper-prose-guard-integration.test.js.map +1 -0
- package/dist/test/tool-wrapper-prose-guard.test.d.ts +2 -0
- package/dist/test/tool-wrapper-prose-guard.test.d.ts.map +1 -0
- package/dist/test/tool-wrapper-prose-guard.test.js +34 -0
- package/dist/test/tool-wrapper-prose-guard.test.js.map +1 -0
- package/dist/test/tune-out-e2e.test.d.ts +2 -0
- package/dist/test/tune-out-e2e.test.d.ts.map +1 -0
- package/dist/test/tune-out-e2e.test.js +142 -0
- package/dist/test/tune-out-e2e.test.js.map +1 -0
- package/dist/test/tune-out-gate-composition.test.d.ts +2 -0
- package/dist/test/tune-out-gate-composition.test.d.ts.map +1 -0
- package/dist/test/tune-out-gate-composition.test.js +221 -0
- package/dist/test/tune-out-gate-composition.test.js.map +1 -0
- package/dist/test/tune-out-lifecycle.test.d.ts +2 -0
- package/dist/test/tune-out-lifecycle.test.d.ts.map +1 -0
- package/dist/test/tune-out-lifecycle.test.js +121 -0
- package/dist/test/tune-out-lifecycle.test.js.map +1 -0
- package/dist/test/turn-trigger-provenance.test.d.ts +2 -0
- package/dist/test/turn-trigger-provenance.test.d.ts.map +1 -0
- package/dist/test/turn-trigger-provenance.test.js +85 -0
- package/dist/test/turn-trigger-provenance.test.js.map +1 -0
- package/dist/test/usage-accounting.test.d.ts +2 -0
- package/dist/test/usage-accounting.test.d.ts.map +1 -0
- package/dist/test/usage-accounting.test.js +13 -0
- package/dist/test/usage-accounting.test.js.map +1 -0
- package/dist/test/workspace-branch-continuation.test.d.ts +15 -0
- package/dist/test/workspace-branch-continuation.test.d.ts.map +1 -0
- package/dist/test/workspace-branch-continuation.test.js +183 -0
- package/dist/test/workspace-branch-continuation.test.js.map +1 -0
- package/dist/test/workspace-read-file-from-disk.test.d.ts +17 -0
- package/dist/test/workspace-read-file-from-disk.test.d.ts.map +1 -0
- package/dist/test/workspace-read-file-from-disk.test.js +174 -0
- package/dist/test/workspace-read-file-from-disk.test.js.map +1 -0
- package/dist/test/workspace-read-image.test.js +8 -0
- package/dist/test/workspace-read-image.test.js.map +1 -1
- package/dist/test/workspace-restore-order.test.js +1 -1
- package/dist/test/workspace-restore-order.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/agent.ts +77 -4
- package/src/framework.ts +953 -128
- package/src/gate/event-gate.ts +28 -3
- package/src/kv-unified-wire.ts +12 -0
- package/src/mcpl/channel-registry.ts +264 -8
- package/src/mcpl/hook-orchestrator.ts +29 -2
- package/src/mcpl/push-handler.ts +30 -2
- package/src/mcpl/reference-fetcher.ts +240 -0
- package/src/mcpl/references.ts +292 -0
- package/src/mcpl/types.ts +29 -0
- package/src/modules/index.ts +2 -1
- package/src/modules/workspace/index.ts +425 -66
- package/src/modules/workspace/types.ts +7 -0
- package/src/tool-result-history.ts +11 -0
- package/src/tool-wrapper-prose-guard.ts +38 -0
- package/src/tune-out/coordinator.ts +548 -0
- package/src/tune-out/tools.ts +129 -0
- package/src/types/agent.ts +16 -0
- package/src/types/framework.ts +7 -0
- package/src/usage-accounting.ts +8 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TuneOutCoordinator (issue #77) — the host-side machinery between a
|
|
3
|
+
* tuned-out channel and the subconscious resident.
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities: classify diverted traffic (stamp everything, wake on
|
|
6
|
+
* addressed), acknowledge suppressed mentions deterministically, run the
|
|
7
|
+
* per-channel summary cadence, count wakes durably with max-wakes
|
|
8
|
+
* auto-cancel, and deliver the cancel dump.
|
|
9
|
+
*
|
|
10
|
+
* Voice doctrine ("no words in models' mouths"): everything the resident
|
|
11
|
+
* reads from the subconscious is the subconscious's verbatim text under its
|
|
12
|
+
* own participant name. Host-authored framing is system-styled and never
|
|
13
|
+
* voiced: `<tuned-out-backlog …>` wraps raw diverted messages (the
|
|
14
|
+
* <backscroll> precedent), and `[Tune-out: …]` bracket notices carry
|
|
15
|
+
* lifecycle facts (the [Gate: …] precedent).
|
|
16
|
+
*/
|
|
17
|
+
import type { ContentBlock } from '@animalabs/membrane';
|
|
18
|
+
import type { StoredMessage } from '@animalabs/context-manager';
|
|
19
|
+
import type { ChannelRegistry, TuneOutParams } from '../mcpl/channel-registry.js';
|
|
20
|
+
import type { McplServerRegistry } from '../mcpl/server-registry.js';
|
|
21
|
+
/** Defaults for tune_out tool params. */
|
|
22
|
+
export declare const TUNE_OUT_DEFAULTS: {
|
|
23
|
+
readonly cadenceSeconds: 1800;
|
|
24
|
+
readonly backlogCap: 200;
|
|
25
|
+
readonly maxWakes: 5;
|
|
26
|
+
};
|
|
27
|
+
export interface TuneOutFrameworkHooks {
|
|
28
|
+
/** Deliver a message into an agent's window (per-agent seam). */
|
|
29
|
+
addMessage: (participant: string, content: ContentBlock[], metadata?: Record<string, unknown>, forAgent?: string) => string;
|
|
30
|
+
/** Queue an inference request for an agent. */
|
|
31
|
+
requestInference: (agentName: string, reason: string, source: string) => void;
|
|
32
|
+
/** The subconscious's registry/participant name. */
|
|
33
|
+
subconsciousName: () => string | null;
|
|
34
|
+
/** The primary resident's registry name. */
|
|
35
|
+
primaryName: () => string | null;
|
|
36
|
+
/** Read the primary's stored messages (shared slot, unfiltered). */
|
|
37
|
+
getStoredMessages: () => StoredMessage[];
|
|
38
|
+
/** Current chronicle head sequence (window anchor for new epochs). */
|
|
39
|
+
currentSequence: () => number;
|
|
40
|
+
/** Move the subconscious window anchor (never forward past active epochs). */
|
|
41
|
+
setSubconsciousAnchor: (sequence: number) => void;
|
|
42
|
+
/** True when a channel is bound to a conversation-fork agent. */
|
|
43
|
+
isForkBound: (channelId: string) => boolean;
|
|
44
|
+
/** Gate privileged-users list (#77: privileged authors wake, like mentions). */
|
|
45
|
+
isPrivilegedAuthor: (authorId: string | null | undefined) => boolean;
|
|
46
|
+
/** speak_in_channel master switch (recipe-side, canary-gated). */
|
|
47
|
+
allowChannelSpeech: () => boolean;
|
|
48
|
+
emitTrace: (event: {
|
|
49
|
+
type: string;
|
|
50
|
+
[key: string]: unknown;
|
|
51
|
+
}) => void;
|
|
52
|
+
}
|
|
53
|
+
export declare class TuneOutCoordinator {
|
|
54
|
+
private readonly channelRegistry;
|
|
55
|
+
private readonly serverRegistry;
|
|
56
|
+
private readonly hooks;
|
|
57
|
+
private cadenceTimers;
|
|
58
|
+
/** Duration-expiry timers (params.expiresAtMs); cleared on any cancel. */
|
|
59
|
+
private expiryTimers;
|
|
60
|
+
/** Channels with a wake invocation pending inside the coalescing window. */
|
|
61
|
+
private pendingWakes;
|
|
62
|
+
/** Diverted-message tallies since the last subconscious invocation, per channel key. */
|
|
63
|
+
private divertedSinceInvocation;
|
|
64
|
+
constructor(channelRegistry: ChannelRegistry, serverRegistry: McplServerRegistry, hooks: TuneOutFrameworkHooks);
|
|
65
|
+
private key;
|
|
66
|
+
/** Restart cadence + expiry timers and re-anchor after a process restart. */
|
|
67
|
+
resumeActiveEpochs(): void;
|
|
68
|
+
private armExpiry;
|
|
69
|
+
private listActive;
|
|
70
|
+
enter(serverId: string, channelId: string, opts: {
|
|
71
|
+
cadenceSeconds?: number;
|
|
72
|
+
backlogCap?: number;
|
|
73
|
+
maxWakes?: number;
|
|
74
|
+
durationSeconds?: number;
|
|
75
|
+
}, source: string): {
|
|
76
|
+
ok: true;
|
|
77
|
+
params: TuneOutParams;
|
|
78
|
+
} | {
|
|
79
|
+
ok: false;
|
|
80
|
+
error: string;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* End a tune-out: durable flip, system-framed backlog dump into the
|
|
84
|
+
* resident's window (capped), lifecycle notice, one wake for the
|
|
85
|
+
* resident. `subconsciousNote` is the subconscious's own text (from its
|
|
86
|
+
* cancel_tuneout call) — delivered verbatim under its name, never
|
|
87
|
+
* synthesized here.
|
|
88
|
+
*/
|
|
89
|
+
cancel(serverId: string, channelId: string, source: string, reason: string, subconsciousNote?: string): {
|
|
90
|
+
ok: true;
|
|
91
|
+
} | {
|
|
92
|
+
ok: false;
|
|
93
|
+
error: string;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Consulted by the framework for every incoming channel message BEFORE
|
|
97
|
+
* storage. Null = channel not tuned out (proceed normally). Otherwise the
|
|
98
|
+
* caller stamps `metadata.tuneOut = { epochId }`, stores the message
|
|
99
|
+
* without waking the residents, and this coordinator has already handled
|
|
100
|
+
* wake bookkeeping (coalesced subconscious invocation, durable count,
|
|
101
|
+
* suppression ack, possible auto-cancel).
|
|
102
|
+
*/
|
|
103
|
+
onIncoming(serverId: string, channelId: string, messageId: string, tags: string[] | undefined, authorId?: string, gatePass?: boolean): {
|
|
104
|
+
epochId: string;
|
|
105
|
+
} | null;
|
|
106
|
+
private acknowledgeSuppressed;
|
|
107
|
+
private startCadence;
|
|
108
|
+
private stopCadence;
|
|
109
|
+
private scheduleWakeInvocation;
|
|
110
|
+
/**
|
|
111
|
+
* One subconscious turn: a system-framed trigger notice (bracket style —
|
|
112
|
+
* what happened, never what to say) plus standing dispositions, then an
|
|
113
|
+
* inference request. The merged view supplies the actual traffic.
|
|
114
|
+
*/
|
|
115
|
+
private invokeSubconscious;
|
|
116
|
+
private dispositionsCache;
|
|
117
|
+
private get dispositionsStateId();
|
|
118
|
+
/**
|
|
119
|
+
* The dispositions as a fixed system-position ContextInjection for the
|
|
120
|
+
* subconscious's compiles (antra: deliver changes, never let them wash
|
|
121
|
+
* away — it has no long-term memory, so they must not live in window
|
|
122
|
+
* content). Bytes change only when a disposition changes: KV-friendly.
|
|
123
|
+
*/
|
|
124
|
+
getDispositionsInjection(): {
|
|
125
|
+
namespace: string;
|
|
126
|
+
position: 'system';
|
|
127
|
+
content: Array<{
|
|
128
|
+
type: 'text';
|
|
129
|
+
text: string;
|
|
130
|
+
}>;
|
|
131
|
+
} | null;
|
|
132
|
+
private readDispositions;
|
|
133
|
+
noteDisposition(key: string, text: string): void;
|
|
134
|
+
handleSubconsciousTool(name: string, input: Record<string, unknown>): Promise<{
|
|
135
|
+
success: boolean;
|
|
136
|
+
data?: unknown;
|
|
137
|
+
error?: string;
|
|
138
|
+
isError?: boolean;
|
|
139
|
+
}>;
|
|
140
|
+
private findByChannel;
|
|
141
|
+
/** Stop all timers (framework shutdown). */
|
|
142
|
+
stop(): void;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../../../src/tune-out/coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TuneOutCoordinator (issue #77) — the host-side machinery between a
|
|
3
|
+
* tuned-out channel and the subconscious resident.
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities: classify diverted traffic (stamp everything, wake on
|
|
6
|
+
* addressed), acknowledge suppressed mentions deterministically, run the
|
|
7
|
+
* per-channel summary cadence, count wakes durably with max-wakes
|
|
8
|
+
* auto-cancel, and deliver the cancel dump.
|
|
9
|
+
*
|
|
10
|
+
* Voice doctrine ("no words in models' mouths"): everything the resident
|
|
11
|
+
* reads from the subconscious is the subconscious's verbatim text under its
|
|
12
|
+
* own participant name. Host-authored framing is system-styled and never
|
|
13
|
+
* voiced: `<tuned-out-backlog …>` wraps raw diverted messages (the
|
|
14
|
+
* <backscroll> precedent), and `[Tune-out: …]` bracket notices carry
|
|
15
|
+
* lifecycle facts (the [Gate: …] precedent).
|
|
16
|
+
*/
|
|
17
|
+
import { randomUUID } from 'node:crypto';
|
|
18
|
+
import { CapabilityGrant } from '../mcpl/capability-grant.js';
|
|
19
|
+
/** Defaults for tune_out tool params. */
|
|
20
|
+
export const TUNE_OUT_DEFAULTS = {
|
|
21
|
+
cadenceSeconds: 1800,
|
|
22
|
+
backlogCap: 200,
|
|
23
|
+
maxWakes: 5,
|
|
24
|
+
};
|
|
25
|
+
/** Coalescing window for wake invocations: a mention storm becomes one
|
|
26
|
+
* subconscious turn, and max-wakes counts invocations, not messages. */
|
|
27
|
+
const WAKE_COALESCE_MS = 2_000;
|
|
28
|
+
export class TuneOutCoordinator {
|
|
29
|
+
channelRegistry;
|
|
30
|
+
serverRegistry;
|
|
31
|
+
hooks;
|
|
32
|
+
cadenceTimers = new Map();
|
|
33
|
+
/** Duration-expiry timers (params.expiresAtMs); cleared on any cancel. */
|
|
34
|
+
expiryTimers = new Map();
|
|
35
|
+
/** Channels with a wake invocation pending inside the coalescing window. */
|
|
36
|
+
pendingWakes = new Map();
|
|
37
|
+
/** Diverted-message tallies since the last subconscious invocation, per channel key. */
|
|
38
|
+
divertedSinceInvocation = new Map();
|
|
39
|
+
constructor(channelRegistry, serverRegistry, hooks) {
|
|
40
|
+
this.channelRegistry = channelRegistry;
|
|
41
|
+
this.serverRegistry = serverRegistry;
|
|
42
|
+
this.hooks = hooks;
|
|
43
|
+
}
|
|
44
|
+
key(serverId, channelId) {
|
|
45
|
+
return `${serverId}\0${channelId}`;
|
|
46
|
+
}
|
|
47
|
+
/** Restart cadence + expiry timers and re-anchor after a process restart. */
|
|
48
|
+
resumeActiveEpochs() {
|
|
49
|
+
let oldestAnchor = null;
|
|
50
|
+
for (const { serverId, channelId, params } of this.listActive()) {
|
|
51
|
+
// An epoch whose deadline passed while the process was down cancels
|
|
52
|
+
// immediately — the resident gets their backlog on the schedule they
|
|
53
|
+
// committed to, not whenever the host happened to restart.
|
|
54
|
+
if (params.expiresAtMs !== undefined && params.expiresAtMs <= Date.now()) {
|
|
55
|
+
this.cancel(serverId, channelId, 'duration', 'duration elapsed');
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
this.startCadence(serverId, channelId, params.cadenceSeconds);
|
|
59
|
+
this.armExpiry(serverId, channelId, params);
|
|
60
|
+
if (oldestAnchor === null || params.startedAtSequence < oldestAnchor) {
|
|
61
|
+
oldestAnchor = params.startedAtSequence;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (oldestAnchor !== null) {
|
|
65
|
+
this.hooks.setSubconsciousAnchor(oldestAnchor);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
armExpiry(serverId, channelId, params) {
|
|
69
|
+
if (params.expiresAtMs === undefined)
|
|
70
|
+
return;
|
|
71
|
+
const key = this.key(serverId, channelId);
|
|
72
|
+
const existing = this.expiryTimers.get(key);
|
|
73
|
+
if (existing)
|
|
74
|
+
clearTimeout(existing);
|
|
75
|
+
const remaining = Math.max(0, params.expiresAtMs - Date.now());
|
|
76
|
+
this.expiryTimers.set(key, setTimeout(() => {
|
|
77
|
+
this.expiryTimers.delete(key);
|
|
78
|
+
this.cancel(serverId, channelId, 'duration', 'duration elapsed');
|
|
79
|
+
}, remaining));
|
|
80
|
+
}
|
|
81
|
+
listActive() {
|
|
82
|
+
const active = [];
|
|
83
|
+
for (const entry of this.channelRegistry.listChannelsRaw()) {
|
|
84
|
+
const state = this.channelRegistry.getTuneOutState(entry.serverId, entry.descriptor.id);
|
|
85
|
+
if (state) {
|
|
86
|
+
active.push({ serverId: entry.serverId, channelId: entry.descriptor.id, params: state.params });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return active;
|
|
90
|
+
}
|
|
91
|
+
// ==========================================================================
|
|
92
|
+
// Enter / cancel
|
|
93
|
+
// ==========================================================================
|
|
94
|
+
enter(serverId, channelId, opts, source) {
|
|
95
|
+
if (!this.hooks.subconsciousName()) {
|
|
96
|
+
return { ok: false, error: 'tune-out requires the subconscious resident (framework config `subconscious`)' };
|
|
97
|
+
}
|
|
98
|
+
if (this.hooks.isForkBound(channelId)) {
|
|
99
|
+
return { ok: false, error: `channel ${channelId} is bound to a conversation fork; tune-out and fork routing are mutually exclusive` };
|
|
100
|
+
}
|
|
101
|
+
if (this.channelRegistry.getTuneOutState(serverId, channelId)) {
|
|
102
|
+
return { ok: false, error: `channel ${channelId} is already tuned out (cancel first to change params)` };
|
|
103
|
+
}
|
|
104
|
+
const params = {
|
|
105
|
+
epochId: randomUUID(),
|
|
106
|
+
cadenceSeconds: Math.max(30, opts.cadenceSeconds ?? TUNE_OUT_DEFAULTS.cadenceSeconds),
|
|
107
|
+
backlogCap: Math.max(0, opts.backlogCap ?? TUNE_OUT_DEFAULTS.backlogCap),
|
|
108
|
+
maxWakes: Math.max(1, opts.maxWakes ?? TUNE_OUT_DEFAULTS.maxWakes),
|
|
109
|
+
startedAtSequence: this.hooks.currentSequence(),
|
|
110
|
+
...(opts.durationSeconds !== undefined
|
|
111
|
+
? { expiresAtMs: Date.now() + Math.max(60, opts.durationSeconds) * 1000 }
|
|
112
|
+
: {}),
|
|
113
|
+
};
|
|
114
|
+
this.channelRegistry.enterTuneOut(serverId, channelId, params, source);
|
|
115
|
+
this.armExpiry(serverId, channelId, params);
|
|
116
|
+
// Window anchor: start of the OLDEST active tune-out. Never move the
|
|
117
|
+
// anchor forward here — an older active epoch owns it.
|
|
118
|
+
const oldest = this.listActive().reduce((min, e) => Math.min(min, e.params.startedAtSequence), params.startedAtSequence);
|
|
119
|
+
this.hooks.setSubconsciousAnchor(oldest);
|
|
120
|
+
this.divertedSinceInvocation.set(this.key(serverId, channelId), 0);
|
|
121
|
+
this.startCadence(serverId, channelId, params.cadenceSeconds);
|
|
122
|
+
this.hooks.emitTrace({ type: 'tune-out:entered', serverId, channelId, epochId: params.epochId });
|
|
123
|
+
return { ok: true, params };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* End a tune-out: durable flip, system-framed backlog dump into the
|
|
127
|
+
* resident's window (capped), lifecycle notice, one wake for the
|
|
128
|
+
* resident. `subconsciousNote` is the subconscious's own text (from its
|
|
129
|
+
* cancel_tuneout call) — delivered verbatim under its name, never
|
|
130
|
+
* synthesized here.
|
|
131
|
+
*/
|
|
132
|
+
cancel(serverId, channelId, source, reason, subconsciousNote) {
|
|
133
|
+
const ended = this.channelRegistry.cancelTuneOut(serverId, channelId, 'open', source);
|
|
134
|
+
if (!ended) {
|
|
135
|
+
return { ok: false, error: `channel ${channelId} is not tuned out` };
|
|
136
|
+
}
|
|
137
|
+
this.stopCadence(serverId, channelId);
|
|
138
|
+
const expiry = this.expiryTimers.get(this.key(serverId, channelId));
|
|
139
|
+
if (expiry) {
|
|
140
|
+
clearTimeout(expiry);
|
|
141
|
+
this.expiryTimers.delete(this.key(serverId, channelId));
|
|
142
|
+
}
|
|
143
|
+
const pending = this.pendingWakes.get(this.key(serverId, channelId));
|
|
144
|
+
if (pending) {
|
|
145
|
+
clearTimeout(pending.timer);
|
|
146
|
+
this.pendingWakes.delete(this.key(serverId, channelId));
|
|
147
|
+
}
|
|
148
|
+
this.divertedSinceInvocation.delete(this.key(serverId, channelId));
|
|
149
|
+
// Backlog: every message stamped with this epoch, oldest first.
|
|
150
|
+
const epochId = ended.params.epochId;
|
|
151
|
+
const backlog = this.hooks.getStoredMessages().filter((m) => m.metadata?.tuneOut?.epochId === epochId);
|
|
152
|
+
const cap = ended.params.backlogCap;
|
|
153
|
+
const shown = cap > 0 ? backlog.slice(-cap) : [];
|
|
154
|
+
const truncated = backlog.length - shown.length;
|
|
155
|
+
const lines = shown.map((m) => {
|
|
156
|
+
const author = m.metadata?.author?.name ?? m.participant;
|
|
157
|
+
const text = m.content
|
|
158
|
+
.filter((b) => b.type === 'text')
|
|
159
|
+
.map((b) => b.text)
|
|
160
|
+
.join('\n');
|
|
161
|
+
return `${author}: ${text}`;
|
|
162
|
+
});
|
|
163
|
+
const attrs = [
|
|
164
|
+
`channel="${channelId}"`,
|
|
165
|
+
`messages=${backlog.length}`,
|
|
166
|
+
...(truncated > 0 ? [`truncated=${truncated} (oldest; fetch_history covers the rest)`] : []),
|
|
167
|
+
];
|
|
168
|
+
const dump = `<tuned-out-backlog ${attrs.join(' ')}>\n${lines.join('\n')}\n</tuned-out-backlog>`;
|
|
169
|
+
// Host-framed system artifacts — never voiced as anyone.
|
|
170
|
+
this.hooks.addMessage('user', [{ type: 'text', text: `[Tune-out: ${channelId} cancelled — ${reason}, ${ended.wakeCount} wake${ended.wakeCount === 1 ? '' : 's'}]\n\n${dump}` }], { system: true, kind: 'tune-out-cancel', channelId, epochId });
|
|
171
|
+
// The subconscious's own words, under its own name, verbatim.
|
|
172
|
+
const subName = this.hooks.subconsciousName();
|
|
173
|
+
if (subconsciousNote && subName) {
|
|
174
|
+
this.hooks.addMessage(subName, [{ type: 'text', text: subconsciousNote }], { kind: 'subconscious-note', channelId, epochId });
|
|
175
|
+
}
|
|
176
|
+
const primary = this.hooks.primaryName();
|
|
177
|
+
if (primary) {
|
|
178
|
+
this.hooks.requestInference(primary, `tune-out cancelled (${reason})`, 'tune-out');
|
|
179
|
+
}
|
|
180
|
+
// The subconscious gets one cancel turn of its own (unless it initiated
|
|
181
|
+
// the cancel — its note already carries its words): the issue's cancel
|
|
182
|
+
// shape is dump + a report from the subconscious, and when the cap
|
|
183
|
+
// truncated the raw dump, its summary is what covers the tail.
|
|
184
|
+
if (source !== 'subconscious' && subName) {
|
|
185
|
+
const truncNote = truncated > 0
|
|
186
|
+
? ` ${truncated} of ${backlog.length} diverted messages were above the cap and not delivered raw.`
|
|
187
|
+
: '';
|
|
188
|
+
this.hooks.addMessage('user', [{ type: 'text', text: `[Tune-out cancelled: ${channelId} — ${reason}.${truncNote}]` }], { system: true, kind: 'tune-out-cancel-report', channelId }, subName);
|
|
189
|
+
this.hooks.requestInference(subName, `tune-out cancelled: ${channelId}`, 'tune-out');
|
|
190
|
+
}
|
|
191
|
+
this.hooks.emitTrace({ type: 'tune-out:cancelled', serverId, channelId, epochId, reason, wakeCount: ended.wakeCount });
|
|
192
|
+
return { ok: true };
|
|
193
|
+
}
|
|
194
|
+
// ==========================================================================
|
|
195
|
+
// Ingestion: divert, stamp, classify
|
|
196
|
+
// ==========================================================================
|
|
197
|
+
/**
|
|
198
|
+
* Consulted by the framework for every incoming channel message BEFORE
|
|
199
|
+
* storage. Null = channel not tuned out (proceed normally). Otherwise the
|
|
200
|
+
* caller stamps `metadata.tuneOut = { epochId }`, stores the message
|
|
201
|
+
* without waking the residents, and this coordinator has already handled
|
|
202
|
+
* wake bookkeeping (coalesced subconscious invocation, durable count,
|
|
203
|
+
* suppression ack, possible auto-cancel).
|
|
204
|
+
*/
|
|
205
|
+
onIncoming(serverId, channelId, messageId, tags, authorId, gatePass = true) {
|
|
206
|
+
const state = this.channelRegistry.getTuneOutState(serverId, channelId);
|
|
207
|
+
if (!state)
|
|
208
|
+
return null;
|
|
209
|
+
const key = this.key(serverId, channelId);
|
|
210
|
+
this.divertedSinceInvocation.set(key, (this.divertedSinceInvocation.get(key) ?? 0) + 1);
|
|
211
|
+
// Wake classification: the resident's wake gate composes as a
|
|
212
|
+
// PRECONDITION (antra, #tuneout-talk: the subconscious is affected BY
|
|
213
|
+
// main's wake gate, it does not replace it) — an event the gate would
|
|
214
|
+
// suppress for the resident (muted author, rate-limit) must not wake
|
|
215
|
+
// the subconscious either; it diverts silently into the backlog and
|
|
216
|
+
// surfaces in cadence summaries. On top of the gate: addressed
|
|
217
|
+
// mentions and gate-privileged authors wake, per the issue.
|
|
218
|
+
const addressed = Array.isArray(tags) && tags.includes('chat:addressed');
|
|
219
|
+
const privileged = this.hooks.isPrivilegedAuthor(authorId);
|
|
220
|
+
if (gatePass && addressed) {
|
|
221
|
+
// The mention-er always gets a deterministic signal, independent of
|
|
222
|
+
// what the subconscious later decides (grant-gated; decline
|
|
223
|
+
// precedent). Gate-suppressed mentions get NO reaction: main would
|
|
224
|
+
// not have signaled either, and reacting would leak the resident's
|
|
225
|
+
// standing mute to its subject.
|
|
226
|
+
void this.acknowledgeSuppressed(serverId, channelId, messageId);
|
|
227
|
+
}
|
|
228
|
+
if (gatePass && (addressed || privileged)) {
|
|
229
|
+
this.scheduleWakeInvocation(serverId, channelId);
|
|
230
|
+
}
|
|
231
|
+
return { epochId: state.params.epochId };
|
|
232
|
+
}
|
|
233
|
+
async acknowledgeSuppressed(serverId, channelId, messageId) {
|
|
234
|
+
try {
|
|
235
|
+
const server = this.serverRegistry.getServer(serverId);
|
|
236
|
+
if (!server || !CapabilityGrant.of(server).has('channels.acknowledge'))
|
|
237
|
+
return;
|
|
238
|
+
await server.sendChannelsAcknowledge({
|
|
239
|
+
channelId,
|
|
240
|
+
messageId,
|
|
241
|
+
intent: 'suppressed-tuned-out',
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
this.hooks.emitTrace({
|
|
246
|
+
type: 'tune-out:ack-failed',
|
|
247
|
+
serverId,
|
|
248
|
+
channelId,
|
|
249
|
+
error: err.message,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// ==========================================================================
|
|
254
|
+
// Subconscious invocation (cadence + coalesced wakes)
|
|
255
|
+
// ==========================================================================
|
|
256
|
+
startCadence(serverId, channelId, cadenceSeconds) {
|
|
257
|
+
this.stopCadence(serverId, channelId);
|
|
258
|
+
const key = this.key(serverId, channelId);
|
|
259
|
+
const tick = () => {
|
|
260
|
+
const state = this.channelRegistry.getTuneOutState(serverId, channelId);
|
|
261
|
+
if (!state)
|
|
262
|
+
return; // cancelled meanwhile
|
|
263
|
+
const diverted = this.divertedSinceInvocation.get(key) ?? 0;
|
|
264
|
+
// An empty period needs no turn at all — skip silently.
|
|
265
|
+
if (diverted > 0) {
|
|
266
|
+
this.invokeSubconscious(serverId, channelId, 'cadence', diverted);
|
|
267
|
+
}
|
|
268
|
+
this.cadenceTimers.set(key, setTimeout(tick, cadenceSeconds * 1000));
|
|
269
|
+
};
|
|
270
|
+
this.cadenceTimers.set(key, setTimeout(tick, cadenceSeconds * 1000));
|
|
271
|
+
}
|
|
272
|
+
stopCadence(serverId, channelId) {
|
|
273
|
+
const key = this.key(serverId, channelId);
|
|
274
|
+
const timer = this.cadenceTimers.get(key);
|
|
275
|
+
if (timer)
|
|
276
|
+
clearTimeout(timer);
|
|
277
|
+
this.cadenceTimers.delete(key);
|
|
278
|
+
}
|
|
279
|
+
scheduleWakeInvocation(serverId, channelId) {
|
|
280
|
+
const key = this.key(serverId, channelId);
|
|
281
|
+
const pending = this.pendingWakes.get(key);
|
|
282
|
+
if (pending) {
|
|
283
|
+
pending.count++;
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const timer = setTimeout(() => {
|
|
287
|
+
const entry = this.pendingWakes.get(key);
|
|
288
|
+
this.pendingWakes.delete(key);
|
|
289
|
+
// Count ONE durable wake per coalesced invocation.
|
|
290
|
+
const counted = this.channelRegistry.recordTuneOutWake(serverId, channelId);
|
|
291
|
+
if (!counted)
|
|
292
|
+
return; // cancelled inside the window
|
|
293
|
+
if (counted.wakeCount > counted.params.maxWakes) {
|
|
294
|
+
this.cancel(serverId, channelId, 'tune-out-max-wakes', `wake budget exhausted (${counted.params.maxWakes})`);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
this.invokeSubconscious(serverId, channelId, 'wake', entry?.count ?? 1);
|
|
298
|
+
}, WAKE_COALESCE_MS);
|
|
299
|
+
this.pendingWakes.set(key, { count: 1, timer });
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* One subconscious turn: a system-framed trigger notice (bracket style —
|
|
303
|
+
* what happened, never what to say) plus standing dispositions, then an
|
|
304
|
+
* inference request. The merged view supplies the actual traffic.
|
|
305
|
+
*/
|
|
306
|
+
invokeSubconscious(serverId, channelId, trigger, count) {
|
|
307
|
+
const subName = this.hooks.subconsciousName();
|
|
308
|
+
if (!subName)
|
|
309
|
+
return;
|
|
310
|
+
const key = this.key(serverId, channelId);
|
|
311
|
+
this.divertedSinceInvocation.set(key, 0);
|
|
312
|
+
const notice = trigger === 'wake'
|
|
313
|
+
? `[Tune-out wake: ${channelId} — ${count} addressed message${count === 1 ? '' : 's'}]`
|
|
314
|
+
: `[Tune-out cadence: ${channelId} — ${count} diverted message${count === 1 ? '' : 's'} since your last look]`;
|
|
315
|
+
this.hooks.addMessage('user', [{ type: 'text', text: notice }], { system: true, kind: `tune-out-${trigger}`, channelId }, subName);
|
|
316
|
+
this.hooks.requestInference(subName, `tune-out ${trigger}: ${channelId}`, 'tune-out');
|
|
317
|
+
}
|
|
318
|
+
// ==========================================================================
|
|
319
|
+
// Dispositions (standing notes, snapshot slot)
|
|
320
|
+
// ==========================================================================
|
|
321
|
+
dispositionsCache = null;
|
|
322
|
+
get dispositionsStateId() {
|
|
323
|
+
return `subconscious/${this.hooks.primaryName() ?? 'default'}/dispositions`;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* The dispositions as a fixed system-position ContextInjection for the
|
|
327
|
+
* subconscious's compiles (antra: deliver changes, never let them wash
|
|
328
|
+
* away — it has no long-term memory, so they must not live in window
|
|
329
|
+
* content). Bytes change only when a disposition changes: KV-friendly.
|
|
330
|
+
*/
|
|
331
|
+
getDispositionsInjection() {
|
|
332
|
+
const dispositions = this.readDispositions();
|
|
333
|
+
const entries = Object.entries(dispositions);
|
|
334
|
+
if (entries.length === 0)
|
|
335
|
+
return null;
|
|
336
|
+
return {
|
|
337
|
+
namespace: 'dispositions',
|
|
338
|
+
position: 'system',
|
|
339
|
+
content: [{
|
|
340
|
+
type: 'text',
|
|
341
|
+
text: `[Standing dispositions]\n${entries.map(([k, v]) => `- ${k}: ${v}`).join('\n')}`,
|
|
342
|
+
}],
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
readDispositions() {
|
|
346
|
+
if (this.dispositionsCache)
|
|
347
|
+
return this.dispositionsCache;
|
|
348
|
+
try {
|
|
349
|
+
const raw = this.channelRegistry.readCoordinatorState(this.dispositionsStateId);
|
|
350
|
+
this.dispositionsCache = (raw && typeof raw === 'object') ? raw : {};
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
this.dispositionsCache = {};
|
|
354
|
+
}
|
|
355
|
+
return this.dispositionsCache;
|
|
356
|
+
}
|
|
357
|
+
noteDisposition(key, text) {
|
|
358
|
+
const dispositions = { ...this.readDispositions() };
|
|
359
|
+
if (text === '') {
|
|
360
|
+
delete dispositions[key];
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
dispositions[key] = text;
|
|
364
|
+
}
|
|
365
|
+
this.dispositionsCache = dispositions;
|
|
366
|
+
this.channelRegistry.writeCoordinatorState(this.dispositionsStateId, dispositions);
|
|
367
|
+
}
|
|
368
|
+
// ==========================================================================
|
|
369
|
+
// Subconscious tool dispatch
|
|
370
|
+
// ==========================================================================
|
|
371
|
+
async handleSubconsciousTool(name, input) {
|
|
372
|
+
switch (name) {
|
|
373
|
+
case 'deliver_summary': {
|
|
374
|
+
const text = String(input.text ?? '').trim();
|
|
375
|
+
const channelId = String(input.channelId ?? '');
|
|
376
|
+
if (!text)
|
|
377
|
+
return { success: false, error: 'empty summary', isError: false };
|
|
378
|
+
const subName = this.hooks.subconsciousName();
|
|
379
|
+
if (!subName)
|
|
380
|
+
return { success: false, error: 'subconscious not configured', isError: true };
|
|
381
|
+
// Verbatim, under its own participant name, into the resident's window.
|
|
382
|
+
this.hooks.addMessage(subName, [{ type: 'text', text }], {
|
|
383
|
+
kind: 'subconscious-summary',
|
|
384
|
+
channelId,
|
|
385
|
+
});
|
|
386
|
+
return { success: true, data: { delivered: true } };
|
|
387
|
+
}
|
|
388
|
+
case 'cancel_tuneout': {
|
|
389
|
+
const channelId = String(input.channelId ?? '');
|
|
390
|
+
const located = this.findByChannel(channelId);
|
|
391
|
+
if (!located)
|
|
392
|
+
return { success: false, error: `channel ${channelId} is not tuned out`, isError: false };
|
|
393
|
+
const note = typeof input.text === 'string' && input.text.trim() ? input.text.trim() : undefined;
|
|
394
|
+
const result = this.cancel(located.serverId, channelId, 'subconscious', 'subconscious judgment', note);
|
|
395
|
+
return result.ok
|
|
396
|
+
? { success: true, data: { cancelled: true } }
|
|
397
|
+
: { success: false, error: result.error, isError: false };
|
|
398
|
+
}
|
|
399
|
+
case 'note_disposition': {
|
|
400
|
+
const key = String(input.key ?? '').trim();
|
|
401
|
+
if (!key)
|
|
402
|
+
return { success: false, error: 'key required', isError: false };
|
|
403
|
+
this.noteDisposition(key, String(input.text ?? ''));
|
|
404
|
+
return { success: true, data: { noted: key } };
|
|
405
|
+
}
|
|
406
|
+
case 'speak_in_channel': {
|
|
407
|
+
if (!this.hooks.allowChannelSpeech()) {
|
|
408
|
+
return {
|
|
409
|
+
success: false,
|
|
410
|
+
isError: false,
|
|
411
|
+
error: 'channel speech is disabled for the subconscious (recipe: subconscious.allowChannelSpeech)',
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
const channelId = String(input.channelId ?? '');
|
|
415
|
+
const text = String(input.text ?? '').trim();
|
|
416
|
+
if (!text)
|
|
417
|
+
return { success: false, error: 'empty message', isError: false };
|
|
418
|
+
return this.channelRegistry.publishForAgent(channelId, text, this.hooks.subconsciousName() ?? 'Subconscious');
|
|
419
|
+
}
|
|
420
|
+
default:
|
|
421
|
+
return { success: false, error: `unknown subconscious tool: ${name}`, isError: true };
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
findByChannel(channelId) {
|
|
425
|
+
for (const entry of this.listActive()) {
|
|
426
|
+
if (entry.channelId === channelId)
|
|
427
|
+
return { serverId: entry.serverId };
|
|
428
|
+
}
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
/** Stop all timers (framework shutdown). */
|
|
432
|
+
stop() {
|
|
433
|
+
for (const timer of this.cadenceTimers.values())
|
|
434
|
+
clearTimeout(timer);
|
|
435
|
+
this.cadenceTimers.clear();
|
|
436
|
+
for (const timer of this.expiryTimers.values())
|
|
437
|
+
clearTimeout(timer);
|
|
438
|
+
this.expiryTimers.clear();
|
|
439
|
+
for (const { timer } of this.pendingWakes.values())
|
|
440
|
+
clearTimeout(timer);
|
|
441
|
+
this.pendingWakes.clear();
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
//# sourceMappingURL=coordinator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../../src/tune-out/coordinator.ts"],"names":[],"mappings":"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"}
|