@memberjunction/ai-agents 5.40.2 → 5.41.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/README.md +45 -0
- package/dist/AgentRunner.d.ts +5 -2
- package/dist/AgentRunner.d.ts.map +1 -1
- package/dist/AgentRunner.js +14 -4
- package/dist/AgentRunner.js.map +1 -1
- package/dist/MemoryWriteManager.d.ts +188 -0
- package/dist/MemoryWriteManager.d.ts.map +1 -0
- package/dist/MemoryWriteManager.js +299 -0
- package/dist/MemoryWriteManager.js.map +1 -0
- package/dist/agent-context-injector.d.ts +29 -0
- package/dist/agent-context-injector.d.ts.map +1 -1
- package/dist/agent-context-injector.js +90 -32
- package/dist/agent-context-injector.js.map +1 -1
- package/dist/agent-memory-context-builder.d.ts +100 -0
- package/dist/agent-memory-context-builder.d.ts.map +1 -0
- package/dist/agent-memory-context-builder.js +172 -0
- package/dist/agent-memory-context-builder.js.map +1 -0
- package/dist/agent-types/index.d.ts +1 -0
- package/dist/agent-types/index.d.ts.map +1 -1
- package/dist/agent-types/index.js +1 -0
- package/dist/agent-types/index.js.map +1 -1
- package/dist/agent-types/loop-agent-response-type.d.ts +12 -1
- package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-response-type.js.map +1 -1
- package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.js +4 -0
- package/dist/agent-types/loop-agent-type.js.map +1 -1
- package/dist/agent-types/realtime-agent-type.d.ts +146 -0
- package/dist/agent-types/realtime-agent-type.d.ts.map +1 -0
- package/dist/agent-types/realtime-agent-type.js +176 -0
- package/dist/agent-types/realtime-agent-type.js.map +1 -0
- package/dist/base-agent.d.ts +365 -24
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +995 -175
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/memory-manager-agent.d.ts +55 -2
- package/dist/memory-manager-agent.d.ts.map +1 -1
- package/dist/memory-manager-agent.js +261 -62
- package/dist/memory-manager-agent.js.map +1 -1
- package/dist/realtime/meeting-controls-channel-server.d.ts +198 -0
- package/dist/realtime/meeting-controls-channel-server.d.ts.map +1 -0
- package/dist/realtime/meeting-controls-channel-server.js +319 -0
- package/dist/realtime/meeting-controls-channel-server.js.map +1 -0
- package/dist/realtime/meeting-controls-state.d.ts +191 -0
- package/dist/realtime/meeting-controls-state.d.ts.map +1 -0
- package/dist/realtime/meeting-controls-state.js +219 -0
- package/dist/realtime/meeting-controls-state.js.map +1 -0
- package/dist/realtime/realtime-channel-server-host.d.ts +166 -0
- package/dist/realtime/realtime-channel-server-host.d.ts.map +1 -0
- package/dist/realtime/realtime-channel-server-host.js +378 -0
- package/dist/realtime/realtime-channel-server-host.js.map +1 -0
- package/dist/realtime/realtime-client-session-service.d.ts +884 -0
- package/dist/realtime/realtime-client-session-service.d.ts.map +1 -0
- package/dist/realtime/realtime-client-session-service.js +1401 -0
- package/dist/realtime/realtime-client-session-service.js.map +1 -0
- package/dist/realtime/realtime-coagent-config.d.ts +202 -0
- package/dist/realtime/realtime-coagent-config.d.ts.map +1 -0
- package/dist/realtime/realtime-coagent-config.js +334 -0
- package/dist/realtime/realtime-coagent-config.js.map +1 -0
- package/dist/realtime/realtime-narration.d.ts +67 -0
- package/dist/realtime/realtime-narration.d.ts.map +1 -0
- package/dist/realtime/realtime-narration.js +127 -0
- package/dist/realtime/realtime-narration.js.map +1 -0
- package/dist/realtime/realtime-session-runner.d.ts +383 -0
- package/dist/realtime/realtime-session-runner.d.ts.map +1 -0
- package/dist/realtime/realtime-session-runner.js +532 -0
- package/dist/realtime/realtime-session-runner.js.map +1 -0
- package/dist/realtime/realtime-tool-broker.d.ts +279 -0
- package/dist/realtime/realtime-tool-broker.d.ts.map +1 -0
- package/dist/realtime/realtime-tool-broker.js +184 -0
- package/dist/realtime/realtime-tool-broker.js.map +1 -0
- package/dist/realtime/whiteboard-channel-server.d.ts +50 -0
- package/dist/realtime/whiteboard-channel-server.d.ts.map +1 -0
- package/dist/realtime/whiteboard-channel-server.js +85 -0
- package/dist/realtime/whiteboard-channel-server.js.map +1 -0
- package/package.json +17 -17
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The **Meeting Controls** server-side channel — a SERVER-ONLY interactive channel
|
|
3
|
+
* (no Angular client surface) that turns a realtime agent into a meeting **facilitator**.
|
|
4
|
+
*
|
|
5
|
+
* It contributes a facilitator tool vocabulary the agent invokes server-side (`RaiseHand`,
|
|
6
|
+
* `LowerHand`, `CallOnParticipant`, `MuteParticipant`, `SetTimer`) and feeds back the perception that
|
|
7
|
+
* makes facilitation possible: the ordered **hand-raise queue** (who raised, in order, how long
|
|
8
|
+
* they've waited), **who is speaking**, the **roster**, and the agenda **timer** (elapsed / remaining).
|
|
9
|
+
* With that intel an agent can call on people in order, enforce time, and move the agenda — all
|
|
10
|
+
* through one channel's tools + perception.
|
|
11
|
+
*
|
|
12
|
+
* The channel has **no platform code**: the signals (roster / speaking / hand-raise) arrive from an
|
|
13
|
+
* INJECTED {@link IMeetingControlsEventSource} that each bridge driver adapts from its native
|
|
14
|
+
* participant/event stream. The queue + timer logic is the pure, fully unit-testable
|
|
15
|
+
* {@link MeetingControlsState}. This is the §4b "bridge contributes a channel" pattern realized as an
|
|
16
|
+
* MJ channel: dynamic tool vocabulary + perception, routed through the same channel plane as the
|
|
17
|
+
* MJ-native whiteboard.
|
|
18
|
+
*
|
|
19
|
+
* @module @memberjunction/ai-agents
|
|
20
|
+
* @author MemberJunction.com
|
|
21
|
+
*/
|
|
22
|
+
import { BaseRealtimeChannelServer, RealtimeToolDefinition, ServerChannelToolResult } from '@memberjunction/ai';
|
|
23
|
+
import { MeetingControlsState, MeetingControlsClock, MeetingParticipant } from './meeting-controls-state.js';
|
|
24
|
+
/** The channel name — matches the (seedable) `MJ: AI Agent Channels` row's `Name`. */
|
|
25
|
+
export declare const MEETING_CONTROLS_CHANNEL_NAME = "Meeting Controls";
|
|
26
|
+
/**
|
|
27
|
+
* The shared name prefix of every Meeting Controls tool. The host routes any tool call beginning with
|
|
28
|
+
* this prefix back to this channel's {@link MeetingControlsChannelServer.ExecuteServerTool}.
|
|
29
|
+
*/
|
|
30
|
+
export declare const MEETING_CONTROLS_TOOL_PREFIX = "MeetingControls_";
|
|
31
|
+
/**
|
|
32
|
+
* The capability the channel gates `MuteParticipant` on. The injected event source advertises which
|
|
33
|
+
* facilitator actions the platform supports; muting is the only gated one (raising/lowering a hand,
|
|
34
|
+
* calling on, and timers are channel-internal and always available).
|
|
35
|
+
*/
|
|
36
|
+
export type MeetingControlsCapability = 'Mute';
|
|
37
|
+
/**
|
|
38
|
+
* The signaling/perception + action surface a bridge driver supplies to the Meeting Controls channel.
|
|
39
|
+
*
|
|
40
|
+
* The channel SUBSCRIBES to the three perception streams and the channel maps the agent's tool calls
|
|
41
|
+
* back onto {@link MuteParticipant} (the one action that must reach the platform). Everything else
|
|
42
|
+
* (the queue, the timer, who is speaking) is maintained inside {@link MeetingControlsState} from these
|
|
43
|
+
* streams. Each bridge driver implements this by adapting its native participant/event stream — the
|
|
44
|
+
* channel itself never names a platform.
|
|
45
|
+
*
|
|
46
|
+
* All `On*` registrations are "latest handler wins" (one channel instance per session).
|
|
47
|
+
*/
|
|
48
|
+
export interface IMeetingControlsEventSource {
|
|
49
|
+
/**
|
|
50
|
+
* Registers a handler for roster changes. The channel rebuilds its roster from each snapshot and
|
|
51
|
+
* prunes departed participants from the queue / speaking / mute state.
|
|
52
|
+
*
|
|
53
|
+
* @param handler Invoked with the full current roster on every change.
|
|
54
|
+
*/
|
|
55
|
+
OnRosterChange(handler: (participants: MeetingParticipant[]) => void): void;
|
|
56
|
+
/**
|
|
57
|
+
* Registers a handler for diarized speaking changes — the set of participant ids currently
|
|
58
|
+
* speaking.
|
|
59
|
+
*
|
|
60
|
+
* @param handler Invoked with the speaking participant ids on every change.
|
|
61
|
+
*/
|
|
62
|
+
OnSpeakingChange(handler: (participantIds: string[]) => void): void;
|
|
63
|
+
/**
|
|
64
|
+
* Registers a handler for hand-raise/lower signals the PLATFORM surfaces (e.g. a participant uses
|
|
65
|
+
* Zoom's native "raise hand"). `raised = true` enqueues, `false` dequeues — mirroring the agent's
|
|
66
|
+
* own `RaiseHand`/`LowerHand` tools so platform-raised and agent-raised hands share one queue.
|
|
67
|
+
*
|
|
68
|
+
* @param handler Invoked with the participant id and whether the hand is now raised.
|
|
69
|
+
*/
|
|
70
|
+
OnHandRaiseChange(handler: (participantId: string, raised: boolean) => void): void;
|
|
71
|
+
/**
|
|
72
|
+
* Mutes a participant on the platform (the actuation behind the agent's `MuteParticipant` tool).
|
|
73
|
+
* Capability-gated by {@link Capabilities}; the channel checks the capability before calling this.
|
|
74
|
+
*
|
|
75
|
+
* @param participantId The participant to mute.
|
|
76
|
+
* @returns A promise resolving once the mute request has been issued.
|
|
77
|
+
*/
|
|
78
|
+
MuteParticipant(participantId: string): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* The facilitator capabilities this platform supports (e.g. `['Mute']`). The channel gates the
|
|
81
|
+
* `MuteParticipant` tool on `'Mute'` being present; absent capabilities make the corresponding
|
|
82
|
+
* tool return a structured "not supported" result instead of calling the source.
|
|
83
|
+
*/
|
|
84
|
+
readonly Capabilities: ReadonlyArray<MeetingControlsCapability>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Dependencies injected into a {@link MeetingControlsChannelServer} — the platform event source and an
|
|
88
|
+
* optional deterministic clock. Injected (rather than resolved) so the channel is fully unit-testable
|
|
89
|
+
* with a fake source and a controllable clock, and so the platform wiring is the driver's concern.
|
|
90
|
+
*/
|
|
91
|
+
export interface MeetingControlsChannelDeps {
|
|
92
|
+
/** The bridge-supplied perception/action surface. */
|
|
93
|
+
EventSource: IMeetingControlsEventSource;
|
|
94
|
+
/** Optional clock for the queue/timer math (defaults to `Date.now`). */
|
|
95
|
+
Clock?: MeetingControlsClock;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Server-only Meeting Controls channel — the facilitator surface. ONE instance per session.
|
|
99
|
+
*
|
|
100
|
+
* Unlike the whiteboard (resolved from the registry by the host via a parameterless ClassFactory
|
|
101
|
+
* construction), this channel needs a per-session {@link IMeetingControlsEventSource} from the bridge,
|
|
102
|
+
* so a bridge driver constructs it directly with {@link MeetingControlsChannelDeps} and hands it to
|
|
103
|
+
* the host's per-session plugin set. It has **no client surface** — the contract's
|
|
104
|
+
* `GetServerToolDefinitions` / `ExecuteServerTool` are the entire interface; there is no
|
|
105
|
+
* `GetSurfaceComponent` on the server half at all.
|
|
106
|
+
*
|
|
107
|
+
* Registered under {@link MEETING_CONTROLS_CHANNEL_NAME} so a seeded registry row can resolve a
|
|
108
|
+
* default (event-source-less) instance for discovery; a real session always injects the driver's
|
|
109
|
+
* event source.
|
|
110
|
+
*/
|
|
111
|
+
export declare class MeetingControlsChannelServer extends BaseRealtimeChannelServer {
|
|
112
|
+
/** The pure facilitator state (queue / speaking / roster / mute / timer). */
|
|
113
|
+
private readonly state;
|
|
114
|
+
/** The injected platform event source, or `null` for a registry-resolved discovery instance. */
|
|
115
|
+
private readonly eventSource;
|
|
116
|
+
/**
|
|
117
|
+
* @param deps Optional per-session dependencies. Omitted only for a registry-resolved discovery
|
|
118
|
+
* instance (the host's ClassFactory path) — such an instance maintains no live state and
|
|
119
|
+
* contributes its tool vocabulary but cannot actuate platform mutes.
|
|
120
|
+
*/
|
|
121
|
+
constructor(deps?: MeetingControlsChannelDeps);
|
|
122
|
+
/** @inheritdoc */
|
|
123
|
+
get ChannelName(): string;
|
|
124
|
+
/** @inheritdoc */
|
|
125
|
+
get ToolNamePrefix(): string;
|
|
126
|
+
/** Read-only access to the live facilitator state (for the channel's own perception + tests). */
|
|
127
|
+
get State(): MeetingControlsState;
|
|
128
|
+
/**
|
|
129
|
+
* Subscribes the injected event source's perception streams into {@link MeetingControlsState} and
|
|
130
|
+
* emits an initial perception snapshot. A discovery instance (no event source) is inert.
|
|
131
|
+
*/
|
|
132
|
+
OnSessionStarted(): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* The facilitator tool vocabulary. `MuteParticipant` is included only when the platform advertises
|
|
135
|
+
* the `'Mute'` capability — so the contributed tool set is **runtime-computed** from the connected
|
|
136
|
+
* platform's abilities (the §4b dynamic-tool point), not a fixed constant.
|
|
137
|
+
*
|
|
138
|
+
* @returns The contributed server-executed tool definitions.
|
|
139
|
+
*/
|
|
140
|
+
GetServerToolDefinitions(): RealtimeToolDefinition[];
|
|
141
|
+
/**
|
|
142
|
+
* Executes one facilitator tool and returns the result (the model narrates it). Tool dispatch is
|
|
143
|
+
* by the bare tool name (after the {@link MEETING_CONTROLS_TOOL_PREFIX}). Never throws — bad args
|
|
144
|
+
* or an unknown tool resolve to a structured failure result.
|
|
145
|
+
*
|
|
146
|
+
* @param toolName The full tool name (prefixed).
|
|
147
|
+
* @param argsJson The raw arguments JSON.
|
|
148
|
+
* @returns The execution result.
|
|
149
|
+
*/
|
|
150
|
+
ExecuteServerTool(toolName: string, argsJson: string): Promise<ServerChannelToolResult>;
|
|
151
|
+
/** `RaiseHand(participantId)` — enqueue a participant; emits perception on a real change. */
|
|
152
|
+
private execRaiseHand;
|
|
153
|
+
/** `LowerHand(participantId)` — dequeue a participant. */
|
|
154
|
+
private execLowerHand;
|
|
155
|
+
/** `CallOnParticipant(participantId?)` — call on a specific person or the front of the queue. */
|
|
156
|
+
private execCallOn;
|
|
157
|
+
/** `MuteParticipant(participantId)` — capability-gated; actuates the platform mute. */
|
|
158
|
+
private execMute;
|
|
159
|
+
/** `SetTimer(seconds)` — start/clear the agenda timer. */
|
|
160
|
+
private execSetTimer;
|
|
161
|
+
/**
|
|
162
|
+
* Serializes the current facilitator state and feeds it to the model as a background context note
|
|
163
|
+
* (no spoken reply forced). No-op when the host context supplies no perception sink (provider
|
|
164
|
+
* can't inject mid-session, or no live session yet).
|
|
165
|
+
*
|
|
166
|
+
* @param reason A short label for the change that triggered the perception (logging only).
|
|
167
|
+
*/
|
|
168
|
+
private emitPerception;
|
|
169
|
+
/** Whether the platform advertises mute support. */
|
|
170
|
+
private muteSupported;
|
|
171
|
+
/** Builds one tool definition with the prefixed name. */
|
|
172
|
+
private tool;
|
|
173
|
+
/** JSON schema for a `{ participantId }` tool; `required` controls whether the id is mandatory. */
|
|
174
|
+
private participantSchema;
|
|
175
|
+
/** JSON schema for the `SetTimer` tool. */
|
|
176
|
+
private setTimerSchema;
|
|
177
|
+
/** Parses a participant-targeting tool's args, tolerating malformed JSON. */
|
|
178
|
+
private parseParticipantArgs;
|
|
179
|
+
/** Parses the `SetTimer` tool's args, tolerating malformed JSON. */
|
|
180
|
+
private parseSetTimerArgs;
|
|
181
|
+
/** Returns the required `participantId` or `null` when absent/blank. */
|
|
182
|
+
private requireParticipantId;
|
|
183
|
+
/** A standard "missing participantId" failure result for a tool. */
|
|
184
|
+
private missingParticipant;
|
|
185
|
+
/** A participant's display name, falling back to their id. */
|
|
186
|
+
private name;
|
|
187
|
+
/** 1-based queue position of a participant (0 when not queued). */
|
|
188
|
+
private queuePosition;
|
|
189
|
+
/** Parses JSON into `T`, returning an empty object on any error (channels never throw on bad args). */
|
|
190
|
+
private safeParse;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Tree-shaking prevention for {@link MeetingControlsChannelServer}'s `@RegisterClass` registration.
|
|
194
|
+
* Call from a static code path so the registration is never eliminated by the bundler — mirroring
|
|
195
|
+
* every other `Load…()` in the realtime stack.
|
|
196
|
+
*/
|
|
197
|
+
export declare function LoadMeetingControlsChannelServer(): void;
|
|
198
|
+
//# sourceMappingURL=meeting-controls-channel-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meeting-controls-channel-server.d.ts","sourceRoot":"","sources":["../../src/realtime/meeting-controls-channel-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACH,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EAE1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACH,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EACrB,MAAM,0BAA0B,CAAC;AAElC,sFAAsF;AACtF,eAAO,MAAM,6BAA6B,qBAAqB,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,MAAM,WAAW,2BAA2B;IACxC;;;;;OAKG;IACH,cAAc,CAAC,OAAO,EAAE,CAAC,YAAY,EAAE,kBAAkB,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAE5E;;;;;OAKG;IACH,gBAAgB,CAAC,OAAO,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAEpE;;;;;;OAMG;IACH,iBAAiB,CAAC,OAAO,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAEnF;;;;;;OAMG;IACH,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtD;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,yBAAyB,CAAC,CAAC;CACnE;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACvC,qDAAqD;IACrD,WAAW,EAAE,2BAA2B,CAAC;IAEzC,wEAAwE;IACxE,KAAK,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAYD;;;;;;;;;;;;;GAaG;AACH,qBACa,4BAA6B,SAAQ,yBAAyB;IACvE,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAE7C,gGAAgG;IAChG,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IAEjE;;;;OAIG;gBACS,IAAI,CAAC,EAAE,0BAA0B;IAM7C,kBAAkB;IAClB,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,kBAAkB;IAClB,IAAoB,cAAc,IAAI,MAAM,CAE3C;IAED,iGAAiG;IACjG,IAAW,KAAK,IAAI,oBAAoB,CAEvC;IAID;;;OAGG;IACmB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBvD;;;;;;OAMG;IACa,wBAAwB,IAAI,sBAAsB,EAAE;IAiBpE;;;;;;;;OAQG;IACmB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAsB7G,6FAA6F;IAC7F,OAAO,CAAC,aAAa;IAerB,0DAA0D;IAC1D,OAAO,CAAC,aAAa;IAYrB,iGAAiG;IACjG,OAAO,CAAC,UAAU;IAUlB,uFAAuF;YACzE,QAAQ;IAqBtB,0DAA0D;IAC1D,OAAO,CAAC,YAAY;IAYpB;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAetB,oDAAoD;IACpD,OAAO,CAAC,aAAa;IAIrB,yDAAyD;IACzD,OAAO,CAAC,IAAI;IAIZ,mGAAmG;IACnG,OAAO,CAAC,iBAAiB;IAWzB,2CAA2C;IAC3C,OAAO,CAAC,cAAc;IAQtB,6EAA6E;IAC7E,OAAO,CAAC,oBAAoB;IAI5B,oEAAoE;IACpE,OAAO,CAAC,iBAAiB;IAIzB,wEAAwE;IACxE,OAAO,CAAC,oBAAoB;IAK5B,oEAAoE;IACpE,OAAO,CAAC,kBAAkB;IAI1B,8DAA8D;IAC9D,OAAO,CAAC,IAAI;IAIZ,mEAAmE;IACnE,OAAO,CAAC,aAAa;IAIrB,uGAAuG;IACvG,OAAO,CAAC,SAAS;CAQpB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The **Meeting Controls** server-side channel — a SERVER-ONLY interactive channel
|
|
3
|
+
* (no Angular client surface) that turns a realtime agent into a meeting **facilitator**.
|
|
4
|
+
*
|
|
5
|
+
* It contributes a facilitator tool vocabulary the agent invokes server-side (`RaiseHand`,
|
|
6
|
+
* `LowerHand`, `CallOnParticipant`, `MuteParticipant`, `SetTimer`) and feeds back the perception that
|
|
7
|
+
* makes facilitation possible: the ordered **hand-raise queue** (who raised, in order, how long
|
|
8
|
+
* they've waited), **who is speaking**, the **roster**, and the agenda **timer** (elapsed / remaining).
|
|
9
|
+
* With that intel an agent can call on people in order, enforce time, and move the agenda — all
|
|
10
|
+
* through one channel's tools + perception.
|
|
11
|
+
*
|
|
12
|
+
* The channel has **no platform code**: the signals (roster / speaking / hand-raise) arrive from an
|
|
13
|
+
* INJECTED {@link IMeetingControlsEventSource} that each bridge driver adapts from its native
|
|
14
|
+
* participant/event stream. The queue + timer logic is the pure, fully unit-testable
|
|
15
|
+
* {@link MeetingControlsState}. This is the §4b "bridge contributes a channel" pattern realized as an
|
|
16
|
+
* MJ channel: dynamic tool vocabulary + perception, routed through the same channel plane as the
|
|
17
|
+
* MJ-native whiteboard.
|
|
18
|
+
*
|
|
19
|
+
* @module @memberjunction/ai-agents
|
|
20
|
+
* @author MemberJunction.com
|
|
21
|
+
*/
|
|
22
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
23
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
24
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
25
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
26
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
27
|
+
};
|
|
28
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
29
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
30
|
+
};
|
|
31
|
+
import { BaseRealtimeChannelServer, } from '@memberjunction/ai';
|
|
32
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
33
|
+
import { LogError } from '@memberjunction/core';
|
|
34
|
+
import { MeetingControlsState, } from './meeting-controls-state.js';
|
|
35
|
+
/** The channel name — matches the (seedable) `MJ: AI Agent Channels` row's `Name`. */
|
|
36
|
+
export const MEETING_CONTROLS_CHANNEL_NAME = 'Meeting Controls';
|
|
37
|
+
/**
|
|
38
|
+
* The shared name prefix of every Meeting Controls tool. The host routes any tool call beginning with
|
|
39
|
+
* this prefix back to this channel's {@link MeetingControlsChannelServer.ExecuteServerTool}.
|
|
40
|
+
*/
|
|
41
|
+
export const MEETING_CONTROLS_TOOL_PREFIX = 'MeetingControls_';
|
|
42
|
+
/**
|
|
43
|
+
* Server-only Meeting Controls channel — the facilitator surface. ONE instance per session.
|
|
44
|
+
*
|
|
45
|
+
* Unlike the whiteboard (resolved from the registry by the host via a parameterless ClassFactory
|
|
46
|
+
* construction), this channel needs a per-session {@link IMeetingControlsEventSource} from the bridge,
|
|
47
|
+
* so a bridge driver constructs it directly with {@link MeetingControlsChannelDeps} and hands it to
|
|
48
|
+
* the host's per-session plugin set. It has **no client surface** — the contract's
|
|
49
|
+
* `GetServerToolDefinitions` / `ExecuteServerTool` are the entire interface; there is no
|
|
50
|
+
* `GetSurfaceComponent` on the server half at all.
|
|
51
|
+
*
|
|
52
|
+
* Registered under {@link MEETING_CONTROLS_CHANNEL_NAME} so a seeded registry row can resolve a
|
|
53
|
+
* default (event-source-less) instance for discovery; a real session always injects the driver's
|
|
54
|
+
* event source.
|
|
55
|
+
*/
|
|
56
|
+
let MeetingControlsChannelServer = class MeetingControlsChannelServer extends BaseRealtimeChannelServer {
|
|
57
|
+
/**
|
|
58
|
+
* @param deps Optional per-session dependencies. Omitted only for a registry-resolved discovery
|
|
59
|
+
* instance (the host's ClassFactory path) — such an instance maintains no live state and
|
|
60
|
+
* contributes its tool vocabulary but cannot actuate platform mutes.
|
|
61
|
+
*/
|
|
62
|
+
constructor(deps) {
|
|
63
|
+
super();
|
|
64
|
+
this.state = new MeetingControlsState(deps?.Clock);
|
|
65
|
+
this.eventSource = deps?.EventSource ?? null;
|
|
66
|
+
}
|
|
67
|
+
/** @inheritdoc */
|
|
68
|
+
get ChannelName() {
|
|
69
|
+
return MEETING_CONTROLS_CHANNEL_NAME;
|
|
70
|
+
}
|
|
71
|
+
/** @inheritdoc */
|
|
72
|
+
get ToolNamePrefix() {
|
|
73
|
+
return MEETING_CONTROLS_TOOL_PREFIX;
|
|
74
|
+
}
|
|
75
|
+
/** Read-only access to the live facilitator state (for the channel's own perception + tests). */
|
|
76
|
+
get State() {
|
|
77
|
+
return this.state;
|
|
78
|
+
}
|
|
79
|
+
// ── Lifecycle: subscribe the bridge event source ────────────────────────────────
|
|
80
|
+
/**
|
|
81
|
+
* Subscribes the injected event source's perception streams into {@link MeetingControlsState} and
|
|
82
|
+
* emits an initial perception snapshot. A discovery instance (no event source) is inert.
|
|
83
|
+
*/
|
|
84
|
+
async OnSessionStarted() {
|
|
85
|
+
if (!this.eventSource) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this.eventSource.OnRosterChange((participants) => {
|
|
89
|
+
this.state.SetRoster(participants);
|
|
90
|
+
this.emitPerception('roster changed');
|
|
91
|
+
});
|
|
92
|
+
this.eventSource.OnSpeakingChange((ids) => {
|
|
93
|
+
this.state.SetSpeaking(ids);
|
|
94
|
+
this.emitPerception('speaking changed');
|
|
95
|
+
});
|
|
96
|
+
this.eventSource.OnHandRaiseChange((participantId, raised) => {
|
|
97
|
+
const changed = raised ? this.state.RaiseHand(participantId) : this.state.LowerHand(participantId);
|
|
98
|
+
if (changed) {
|
|
99
|
+
this.emitPerception(raised ? 'hand raised' : 'hand lowered');
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// ── Dynamic tool vocabulary ─────────────────────────────────────────────────────
|
|
104
|
+
/**
|
|
105
|
+
* The facilitator tool vocabulary. `MuteParticipant` is included only when the platform advertises
|
|
106
|
+
* the `'Mute'` capability — so the contributed tool set is **runtime-computed** from the connected
|
|
107
|
+
* platform's abilities (the §4b dynamic-tool point), not a fixed constant.
|
|
108
|
+
*
|
|
109
|
+
* @returns The contributed server-executed tool definitions.
|
|
110
|
+
*/
|
|
111
|
+
GetServerToolDefinitions() {
|
|
112
|
+
const tools = [
|
|
113
|
+
this.tool('RaiseHand', 'Add a participant to the hand-raise queue (e.g. on their spoken request to speak).', this.participantSchema()),
|
|
114
|
+
this.tool('LowerHand', 'Remove a participant from the hand-raise queue.', this.participantSchema()),
|
|
115
|
+
this.tool('CallOnParticipant', 'Call on a participant so they may speak, lowering their hand. Omit participantId to call on the next person in the queue.', this.participantSchema(false)),
|
|
116
|
+
this.tool('SetTimer', 'Start an agenda/meeting timer for the given number of seconds (0 clears it).', this.setTimerSchema()),
|
|
117
|
+
];
|
|
118
|
+
if (this.muteSupported()) {
|
|
119
|
+
tools.push(this.tool('MuteParticipant', 'Mute a participant on the platform.', this.participantSchema()));
|
|
120
|
+
}
|
|
121
|
+
return tools;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Executes one facilitator tool and returns the result (the model narrates it). Tool dispatch is
|
|
125
|
+
* by the bare tool name (after the {@link MEETING_CONTROLS_TOOL_PREFIX}). Never throws — bad args
|
|
126
|
+
* or an unknown tool resolve to a structured failure result.
|
|
127
|
+
*
|
|
128
|
+
* @param toolName The full tool name (prefixed).
|
|
129
|
+
* @param argsJson The raw arguments JSON.
|
|
130
|
+
* @returns The execution result.
|
|
131
|
+
*/
|
|
132
|
+
async ExecuteServerTool(toolName, argsJson) {
|
|
133
|
+
const bare = toolName.startsWith(MEETING_CONTROLS_TOOL_PREFIX)
|
|
134
|
+
? toolName.slice(MEETING_CONTROLS_TOOL_PREFIX.length)
|
|
135
|
+
: toolName;
|
|
136
|
+
switch (bare) {
|
|
137
|
+
case 'RaiseHand':
|
|
138
|
+
return this.execRaiseHand(argsJson);
|
|
139
|
+
case 'LowerHand':
|
|
140
|
+
return this.execLowerHand(argsJson);
|
|
141
|
+
case 'CallOnParticipant':
|
|
142
|
+
return this.execCallOn(argsJson);
|
|
143
|
+
case 'MuteParticipant':
|
|
144
|
+
return this.execMute(argsJson);
|
|
145
|
+
case 'SetTimer':
|
|
146
|
+
return this.execSetTimer(argsJson);
|
|
147
|
+
default:
|
|
148
|
+
return { Success: false, Output: `Unknown Meeting Controls tool '${toolName}'.` };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// ── Tool implementations ────────────────────────────────────────────────────────
|
|
152
|
+
/** `RaiseHand(participantId)` — enqueue a participant; emits perception on a real change. */
|
|
153
|
+
execRaiseHand(argsJson) {
|
|
154
|
+
const id = this.requireParticipantId(argsJson);
|
|
155
|
+
if (!id) {
|
|
156
|
+
return this.missingParticipant('RaiseHand');
|
|
157
|
+
}
|
|
158
|
+
if (!this.state.GetParticipant(id)) {
|
|
159
|
+
return { Success: false, Output: `Participant '${id}' is not on the roster.` };
|
|
160
|
+
}
|
|
161
|
+
const changed = this.state.RaiseHand(id);
|
|
162
|
+
if (changed) {
|
|
163
|
+
this.emitPerception('hand raised');
|
|
164
|
+
}
|
|
165
|
+
return { Success: true, Output: changed ? `Hand raised for ${this.name(id)} (queue position ${this.queuePosition(id)}).` : `${this.name(id)} already has a hand raised.` };
|
|
166
|
+
}
|
|
167
|
+
/** `LowerHand(participantId)` — dequeue a participant. */
|
|
168
|
+
execLowerHand(argsJson) {
|
|
169
|
+
const id = this.requireParticipantId(argsJson);
|
|
170
|
+
if (!id) {
|
|
171
|
+
return this.missingParticipant('LowerHand');
|
|
172
|
+
}
|
|
173
|
+
const changed = this.state.LowerHand(id);
|
|
174
|
+
if (changed) {
|
|
175
|
+
this.emitPerception('hand lowered');
|
|
176
|
+
}
|
|
177
|
+
return { Success: true, Output: changed ? `Lowered ${this.name(id)}'s hand.` : `${this.name(id)} had no raised hand.` };
|
|
178
|
+
}
|
|
179
|
+
/** `CallOnParticipant(participantId?)` — call on a specific person or the front of the queue. */
|
|
180
|
+
execCallOn(argsJson) {
|
|
181
|
+
const id = this.parseParticipantArgs(argsJson).participantId;
|
|
182
|
+
const called = this.state.CallOn(id);
|
|
183
|
+
if (!called) {
|
|
184
|
+
return { Success: false, Output: id ? `${this.name(id)} is not in the hand-raise queue.` : 'No one is in the hand-raise queue to call on.' };
|
|
185
|
+
}
|
|
186
|
+
this.emitPerception('called on participant');
|
|
187
|
+
return { Success: true, Output: `Calling on ${called.DisplayName ?? this.name(called.ParticipantId)}.` };
|
|
188
|
+
}
|
|
189
|
+
/** `MuteParticipant(participantId)` — capability-gated; actuates the platform mute. */
|
|
190
|
+
async execMute(argsJson) {
|
|
191
|
+
if (!this.muteSupported()) {
|
|
192
|
+
return { Success: false, Output: 'Muting participants is not supported on this platform.' };
|
|
193
|
+
}
|
|
194
|
+
const id = this.requireParticipantId(argsJson);
|
|
195
|
+
if (!id) {
|
|
196
|
+
return this.missingParticipant('MuteParticipant');
|
|
197
|
+
}
|
|
198
|
+
if (!this.state.GetParticipant(id)) {
|
|
199
|
+
return { Success: false, Output: `Participant '${id}' is not on the roster.` };
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
await this.eventSource?.MuteParticipant(id);
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
return { Success: false, Output: `Failed to mute ${this.name(id)}: ${error instanceof Error ? error.message : String(error)}` };
|
|
206
|
+
}
|
|
207
|
+
this.state.MarkMuted(id);
|
|
208
|
+
this.emitPerception('participant muted');
|
|
209
|
+
return { Success: true, Output: `Muted ${this.name(id)}.` };
|
|
210
|
+
}
|
|
211
|
+
/** `SetTimer(seconds)` — start/clear the agenda timer. */
|
|
212
|
+
execSetTimer(argsJson) {
|
|
213
|
+
const seconds = this.parseSetTimerArgs(argsJson).seconds;
|
|
214
|
+
if (seconds == null || !Number.isFinite(seconds) || seconds < 0) {
|
|
215
|
+
return { Success: false, Output: "SetTimer requires a non-negative 'seconds' value." };
|
|
216
|
+
}
|
|
217
|
+
this.state.SetTimer(seconds);
|
|
218
|
+
this.emitPerception('timer set');
|
|
219
|
+
return { Success: true, Output: seconds > 0 ? `Timer set for ${seconds} seconds.` : 'Timer cleared.' };
|
|
220
|
+
}
|
|
221
|
+
// ── Perception ──────────────────────────────────────────────────────────────────
|
|
222
|
+
/**
|
|
223
|
+
* Serializes the current facilitator state and feeds it to the model as a background context note
|
|
224
|
+
* (no spoken reply forced). No-op when the host context supplies no perception sink (provider
|
|
225
|
+
* can't inject mid-session, or no live session yet).
|
|
226
|
+
*
|
|
227
|
+
* @param reason A short label for the change that triggered the perception (logging only).
|
|
228
|
+
*/
|
|
229
|
+
emitPerception(reason) {
|
|
230
|
+
const sink = this.Context?.SendContextNote;
|
|
231
|
+
if (!sink) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
const payload = JSON.stringify(this.state.BuildPerception());
|
|
236
|
+
sink.call(this.Context, `[meeting-controls: ${reason}] ${payload}`);
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
LogError(`[MeetingControlsChannelServer] perception emit failed (${reason}): ${error instanceof Error ? error.message : String(error)}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// ── Helpers ─────────────────────────────────────────────────────────────────────
|
|
243
|
+
/** Whether the platform advertises mute support. */
|
|
244
|
+
muteSupported() {
|
|
245
|
+
return this.eventSource?.Capabilities.includes('Mute') ?? false;
|
|
246
|
+
}
|
|
247
|
+
/** Builds one tool definition with the prefixed name. */
|
|
248
|
+
tool(bareName, description, parametersSchema) {
|
|
249
|
+
return { Name: `${MEETING_CONTROLS_TOOL_PREFIX}${bareName}`, Description: description, ParametersSchema: parametersSchema };
|
|
250
|
+
}
|
|
251
|
+
/** JSON schema for a `{ participantId }` tool; `required` controls whether the id is mandatory. */
|
|
252
|
+
participantSchema(required = true) {
|
|
253
|
+
const schema = {
|
|
254
|
+
type: 'object',
|
|
255
|
+
properties: { participantId: { type: 'string', description: 'The platform participant id this tool targets.' } },
|
|
256
|
+
};
|
|
257
|
+
if (required) {
|
|
258
|
+
schema.required = ['participantId'];
|
|
259
|
+
}
|
|
260
|
+
return schema;
|
|
261
|
+
}
|
|
262
|
+
/** JSON schema for the `SetTimer` tool. */
|
|
263
|
+
setTimerSchema() {
|
|
264
|
+
return {
|
|
265
|
+
type: 'object',
|
|
266
|
+
properties: { seconds: { type: 'number', description: 'Timer duration in seconds; 0 clears the timer.' } },
|
|
267
|
+
required: ['seconds'],
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/** Parses a participant-targeting tool's args, tolerating malformed JSON. */
|
|
271
|
+
parseParticipantArgs(argsJson) {
|
|
272
|
+
return this.safeParse(argsJson);
|
|
273
|
+
}
|
|
274
|
+
/** Parses the `SetTimer` tool's args, tolerating malformed JSON. */
|
|
275
|
+
parseSetTimerArgs(argsJson) {
|
|
276
|
+
return this.safeParse(argsJson);
|
|
277
|
+
}
|
|
278
|
+
/** Returns the required `participantId` or `null` when absent/blank. */
|
|
279
|
+
requireParticipantId(argsJson) {
|
|
280
|
+
const id = this.parseParticipantArgs(argsJson).participantId;
|
|
281
|
+
return typeof id === 'string' && id.trim().length > 0 ? id : null;
|
|
282
|
+
}
|
|
283
|
+
/** A standard "missing participantId" failure result for a tool. */
|
|
284
|
+
missingParticipant(tool) {
|
|
285
|
+
return { Success: false, Output: `${tool} requires a 'participantId'.` };
|
|
286
|
+
}
|
|
287
|
+
/** A participant's display name, falling back to their id. */
|
|
288
|
+
name(participantId) {
|
|
289
|
+
return this.state.GetParticipant(participantId)?.DisplayName ?? participantId;
|
|
290
|
+
}
|
|
291
|
+
/** 1-based queue position of a participant (0 when not queued). */
|
|
292
|
+
queuePosition(participantId) {
|
|
293
|
+
return this.state.GetHandRaiseQueue().findIndex((e) => e.ParticipantId === participantId) + 1;
|
|
294
|
+
}
|
|
295
|
+
/** Parses JSON into `T`, returning an empty object on any error (channels never throw on bad args). */
|
|
296
|
+
safeParse(json) {
|
|
297
|
+
try {
|
|
298
|
+
const parsed = JSON.parse(json);
|
|
299
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
return {};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
MeetingControlsChannelServer = __decorate([
|
|
307
|
+
RegisterClass(BaseRealtimeChannelServer, 'MeetingControlsChannelServer'),
|
|
308
|
+
__metadata("design:paramtypes", [Object])
|
|
309
|
+
], MeetingControlsChannelServer);
|
|
310
|
+
export { MeetingControlsChannelServer };
|
|
311
|
+
/**
|
|
312
|
+
* Tree-shaking prevention for {@link MeetingControlsChannelServer}'s `@RegisterClass` registration.
|
|
313
|
+
* Call from a static code path so the registration is never eliminated by the bundler — mirroring
|
|
314
|
+
* every other `Load…()` in the realtime stack.
|
|
315
|
+
*/
|
|
316
|
+
export function LoadMeetingControlsChannelServer() {
|
|
317
|
+
// no-op — the import + call create a static reference bundlers cannot eliminate
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=meeting-controls-channel-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meeting-controls-channel-server.js","sourceRoot":"","sources":["../../src/realtime/meeting-controls-channel-server.ts"],"names":[],"mappings":"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"}
|