@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.
Files changed (80) hide show
  1. package/README.md +45 -0
  2. package/dist/AgentRunner.d.ts +5 -2
  3. package/dist/AgentRunner.d.ts.map +1 -1
  4. package/dist/AgentRunner.js +14 -4
  5. package/dist/AgentRunner.js.map +1 -1
  6. package/dist/MemoryWriteManager.d.ts +188 -0
  7. package/dist/MemoryWriteManager.d.ts.map +1 -0
  8. package/dist/MemoryWriteManager.js +299 -0
  9. package/dist/MemoryWriteManager.js.map +1 -0
  10. package/dist/agent-context-injector.d.ts +29 -0
  11. package/dist/agent-context-injector.d.ts.map +1 -1
  12. package/dist/agent-context-injector.js +90 -32
  13. package/dist/agent-context-injector.js.map +1 -1
  14. package/dist/agent-memory-context-builder.d.ts +100 -0
  15. package/dist/agent-memory-context-builder.d.ts.map +1 -0
  16. package/dist/agent-memory-context-builder.js +172 -0
  17. package/dist/agent-memory-context-builder.js.map +1 -0
  18. package/dist/agent-types/index.d.ts +1 -0
  19. package/dist/agent-types/index.d.ts.map +1 -1
  20. package/dist/agent-types/index.js +1 -0
  21. package/dist/agent-types/index.js.map +1 -1
  22. package/dist/agent-types/loop-agent-response-type.d.ts +12 -1
  23. package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
  24. package/dist/agent-types/loop-agent-response-type.js.map +1 -1
  25. package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
  26. package/dist/agent-types/loop-agent-type.js +4 -0
  27. package/dist/agent-types/loop-agent-type.js.map +1 -1
  28. package/dist/agent-types/realtime-agent-type.d.ts +146 -0
  29. package/dist/agent-types/realtime-agent-type.d.ts.map +1 -0
  30. package/dist/agent-types/realtime-agent-type.js +176 -0
  31. package/dist/agent-types/realtime-agent-type.js.map +1 -0
  32. package/dist/base-agent.d.ts +365 -24
  33. package/dist/base-agent.d.ts.map +1 -1
  34. package/dist/base-agent.js +995 -175
  35. package/dist/base-agent.js.map +1 -1
  36. package/dist/index.d.ts +11 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +15 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/memory-manager-agent.d.ts +55 -2
  41. package/dist/memory-manager-agent.d.ts.map +1 -1
  42. package/dist/memory-manager-agent.js +261 -62
  43. package/dist/memory-manager-agent.js.map +1 -1
  44. package/dist/realtime/meeting-controls-channel-server.d.ts +198 -0
  45. package/dist/realtime/meeting-controls-channel-server.d.ts.map +1 -0
  46. package/dist/realtime/meeting-controls-channel-server.js +319 -0
  47. package/dist/realtime/meeting-controls-channel-server.js.map +1 -0
  48. package/dist/realtime/meeting-controls-state.d.ts +191 -0
  49. package/dist/realtime/meeting-controls-state.d.ts.map +1 -0
  50. package/dist/realtime/meeting-controls-state.js +219 -0
  51. package/dist/realtime/meeting-controls-state.js.map +1 -0
  52. package/dist/realtime/realtime-channel-server-host.d.ts +166 -0
  53. package/dist/realtime/realtime-channel-server-host.d.ts.map +1 -0
  54. package/dist/realtime/realtime-channel-server-host.js +378 -0
  55. package/dist/realtime/realtime-channel-server-host.js.map +1 -0
  56. package/dist/realtime/realtime-client-session-service.d.ts +884 -0
  57. package/dist/realtime/realtime-client-session-service.d.ts.map +1 -0
  58. package/dist/realtime/realtime-client-session-service.js +1401 -0
  59. package/dist/realtime/realtime-client-session-service.js.map +1 -0
  60. package/dist/realtime/realtime-coagent-config.d.ts +202 -0
  61. package/dist/realtime/realtime-coagent-config.d.ts.map +1 -0
  62. package/dist/realtime/realtime-coagent-config.js +334 -0
  63. package/dist/realtime/realtime-coagent-config.js.map +1 -0
  64. package/dist/realtime/realtime-narration.d.ts +67 -0
  65. package/dist/realtime/realtime-narration.d.ts.map +1 -0
  66. package/dist/realtime/realtime-narration.js +127 -0
  67. package/dist/realtime/realtime-narration.js.map +1 -0
  68. package/dist/realtime/realtime-session-runner.d.ts +383 -0
  69. package/dist/realtime/realtime-session-runner.d.ts.map +1 -0
  70. package/dist/realtime/realtime-session-runner.js +532 -0
  71. package/dist/realtime/realtime-session-runner.js.map +1 -0
  72. package/dist/realtime/realtime-tool-broker.d.ts +279 -0
  73. package/dist/realtime/realtime-tool-broker.d.ts.map +1 -0
  74. package/dist/realtime/realtime-tool-broker.js +184 -0
  75. package/dist/realtime/realtime-tool-broker.js.map +1 -0
  76. package/dist/realtime/whiteboard-channel-server.d.ts +50 -0
  77. package/dist/realtime/whiteboard-channel-server.d.ts.map +1 -0
  78. package/dist/realtime/whiteboard-channel-server.js +85 -0
  79. package/dist/realtime/whiteboard-channel-server.js.map +1 -0
  80. package/package.json +17 -17
@@ -0,0 +1,279 @@
1
+ /**
2
+ * @fileoverview Topology-agnostic broker that executes a single realtime tool call server-side.
3
+ *
4
+ * The {@link RealtimeToolBroker} owns the *tool-execution* half of a realtime session: given a
5
+ * provider {@link RealtimeToolCall}, it routes the call (the stable `invoke-target-agent` tool →
6
+ * delegate to the target agent; every other tool → an injected tool executor), owns the per-call
7
+ * {@link AbortController} so barge-in can cancel an in-flight delegated run, and serializes the
8
+ * success/error result into the exact JSON the model expects as a `tool_response`.
9
+ *
10
+ * **Why factor this out.** Both audio topologies must execute a realtime tool call *identically*:
11
+ * the **server-bridged** path ({@link RealtimeSessionRunner}, where the provider socket lives on the
12
+ * server) and the **client-direct** path (where the browser owns the socket and relays tool calls
13
+ * back to a server resolver). Keeping one broker guarantees the two paths produce byte-for-byte
14
+ * identical tool results, including structured errors for spoken-error-handling. The broker is the
15
+ * single tool-execution path both topologies share.
16
+ *
17
+ * **Dependency injection.** Every collaborator that would otherwise pull in `BaseAgent`, metadata,
18
+ * or the database is injected via {@link RealtimeToolBrokerDeps}, keeping the broker fully
19
+ * unit-testable against mocks.
20
+ *
21
+ * @module @memberjunction/ai-agents
22
+ * @author MemberJunction.com
23
+ */
24
+ import { RealtimeToolCall } from '@memberjunction/ai';
25
+ import { AgentExecutionProgressCallback } from '@memberjunction/ai-core-plus';
26
+ /**
27
+ * The stable name of the primary tool every Realtime Co-Agent registers with the realtime provider.
28
+ *
29
+ * Per the plan's design rule, the realtime-registered tool set is **target-independent**: the
30
+ * co-agent always exposes this single `invoke-target-agent` tool, and the specific target is a
31
+ * runtime parameter passed *inside* the call — never a different tool per target. This keeps the
32
+ * provider contract identical across targets (and is what lets a pre-provisioned, fixed-tool
33
+ * provider like Eleven Labs fit the same model later).
34
+ */
35
+ export declare const INVOKE_TARGET_AGENT_TOOL_NAME = "invoke-target-agent";
36
+ /**
37
+ * A request to delegate work to the target agent, derived from an `invoke-target-agent` tool call.
38
+ */
39
+ export interface DelegateToTargetRequest {
40
+ /** The provider-assigned call ID, used to correlate the eventual tool result. */
41
+ CallID: string;
42
+ /**
43
+ * The raw arguments JSON string the model emitted for the call (e.g. the natural-language
44
+ * request to hand to the target agent). The delegate parses this into the target's expected
45
+ * input shape.
46
+ */
47
+ Arguments: string;
48
+ /**
49
+ * Abort signal owned by the broker for this specific delegated call. On barge-in
50
+ * ({@link RealtimeToolBroker.AbortInFlight}), the broker aborts the controller behind this
51
+ * signal so a stale delegated result is never narrated into a conversation that has moved on.
52
+ */
53
+ AbortSignal: AbortSignal;
54
+ /**
55
+ * Optional progress callback the CALLER wants threaded into the delegated agent run's
56
+ * `onProgress` (in addition to any host-level callback the delegate already wires). The
57
+ * server-bridged {@link import('./realtime-session-runner.js').RealtimeSessionRunner} supplies
58
+ * this so it can narrate the delegated run's progress over the live provider socket
59
+ * (`SendContextNote` / `RequestSpokenUpdate`). Delegates that run agents should invoke it
60
+ * alongside their own progress plumbing; delegates without progress support may ignore it.
61
+ */
62
+ OnProgress?: AgentExecutionProgressCallback;
63
+ }
64
+ /**
65
+ * One artifact a delegated target-agent run produced, surfaced to the transport layer (and into
66
+ * the serialized tool result as `artifacts: [{ artifactId, artifactVersionId, name }]`) so the
67
+ * client call overlay can open it in an artifact tab while the model narrates the outcome.
68
+ */
69
+ export interface DelegatedRunArtifact {
70
+ /** The `MJ: Artifacts` row id. */
71
+ ArtifactID: string;
72
+ /** The `MJ: Artifact Versions` row id of the version this run produced. */
73
+ ArtifactVersionID: string;
74
+ /** The artifact's display name (tab title in the call overlay). */
75
+ Name: string;
76
+ }
77
+ /**
78
+ * The result of a delegated target-agent run, fed back to the realtime model as a tool response.
79
+ */
80
+ export interface DelegatedResult {
81
+ /** The provider call ID this result corresponds to. */
82
+ CallID: string;
83
+ /** Whether the delegated run completed successfully. */
84
+ Success: boolean;
85
+ /**
86
+ * The textual outcome to narrate (on success) or the error to surface (on failure). The
87
+ * driver feeds this back to the model as the `tool_response` so it can speak the outcome.
88
+ */
89
+ Output: string;
90
+ /**
91
+ * When the delegated run paused awaiting user feedback (an interactive target agent, e.g.
92
+ * Query Builder confirming a task graph), this carries the paused run's id so the transport
93
+ * layer can persist it and resume the SAME run on the user's next answer (rather than starting
94
+ * a fresh run). Absent when the run completed (or failed) without pausing. The {@link Output} in
95
+ * this case is the agent's clarifying QUESTION, and {@link Success} is `true` (a valid
96
+ * intermediate outcome).
97
+ */
98
+ PausedRunID?: string;
99
+ /**
100
+ * ID of the delegated target-agent run (`MJ: AI Agent Runs`), when one was created. Serialized
101
+ * into the tool result as `runId` so client developer tooling (the call overlay's dev links)
102
+ * can open the underlying run record. Absent when the delegation failed before a run existed.
103
+ */
104
+ RunID?: string;
105
+ /**
106
+ * Artifacts the delegated run produced (when artifact creation is enabled for the target and
107
+ * the run returned a payload). Serialized into the tool result as `artifacts` so the call
108
+ * overlay can auto-open them in artifact tabs. Absent/empty when the run produced none.
109
+ */
110
+ Artifacts?: DelegatedRunArtifact[];
111
+ }
112
+ /**
113
+ * A non-target tool call routed to the injected {@link RealtimeToolBrokerDeps.ExecuteTool} handler.
114
+ * This is any tool other than `invoke-target-agent` (e.g. a UI/control tool such as `ShowChart`, or
115
+ * a fast server/client tool the co-agent was given directly).
116
+ */
117
+ export interface ToolExecutionResult {
118
+ /** The provider call ID this result corresponds to. */
119
+ CallID: string;
120
+ /** Whether the tool executed successfully. */
121
+ Success: boolean;
122
+ /** The textual result to feed back to the model as the tool response. */
123
+ Output: string;
124
+ }
125
+ /**
126
+ * Verbose-aware status logging callback.
127
+ */
128
+ export type RealtimeStatusLogger = (message: string, verboseOnly?: boolean) => void;
129
+ /**
130
+ * Error logging callback.
131
+ */
132
+ export type RealtimeErrorLogger = (error: Error | string) => void;
133
+ /**
134
+ * The serialized outcome of executing a realtime tool call.
135
+ *
136
+ * {@link RealtimeToolBroker.ExecuteToolCall} returns this so the *transport* layer (server-bridged
137
+ * session or client-direct resolver) can feed {@link ExecutedToolCall.ResultJson} back to the model
138
+ * (e.g. via `IRealtimeSession.SendToolResult`) without knowing anything about how the result was
139
+ * produced.
140
+ */
141
+ export interface ExecutedToolCall {
142
+ /**
143
+ * The JSON-stringified tool result, shaped exactly as the model expects: `{ success, output }`
144
+ * on success or `{ success: false, error }` on failure (consistent structured errors so the
145
+ * model can narrate the failure — spoken-error-handling).
146
+ */
147
+ ResultJson: string;
148
+ /** Whether the tool/delegation completed successfully. */
149
+ Success: boolean;
150
+ /**
151
+ * When the delegated target-agent run paused awaiting user feedback, this surfaces the paused
152
+ * run's id (propagated from {@link DelegatedResult.PausedRunID}) so the transport layer can
153
+ * persist it and resume that run on the user's next answer. Absent for non-delegation tools and
154
+ * for delegated runs that completed without pausing.
155
+ */
156
+ PausedRunID?: string;
157
+ /**
158
+ * ID of the delegated target-agent run (propagated from {@link DelegatedResult.RunID}) — also
159
+ * embedded in {@link ResultJson} as `runId`. Absent for non-delegation tools and for
160
+ * delegations that failed before a run was created.
161
+ */
162
+ RunID?: string;
163
+ /**
164
+ * Artifacts the delegated run produced (propagated from {@link DelegatedResult.Artifacts}) —
165
+ * also embedded in {@link ResultJson} as `artifacts: [{ artifactId, artifactVersionId, name }]`.
166
+ * Absent for non-delegation tools and for delegations that produced no artifacts.
167
+ */
168
+ Artifacts?: DelegatedRunArtifact[];
169
+ }
170
+ /**
171
+ * The injected collaborators the broker needs to execute a tool call.
172
+ *
173
+ * Each member is a seam that decouples the broker from `BaseAgent`/metadata/DB so it can be
174
+ * exercised with mocks. In production, the {@link RealtimeSessionRunner} (and, in P5b, the
175
+ * client-direct server resolver) constructs these from `BaseAgent`-backed implementations.
176
+ */
177
+ export interface RealtimeToolBrokerDeps {
178
+ /**
179
+ * Runs the target agent for an `invoke-target-agent` tool call. The broker creates and owns a
180
+ * fresh {@link AbortController} per delegated call and passes its signal in via
181
+ * {@link DelegateToTargetRequest.AbortSignal}; barge-in aborts it. In production this is backed
182
+ * by `BaseAgent.ExecuteSubAgent` (top-level target only — sub-agents are not exposed).
183
+ */
184
+ DelegateToTarget: (request: DelegateToTargetRequest) => Promise<DelegatedResult>;
185
+ /**
186
+ * Executes a non-target tool call (any tool other than `invoke-target-agent`). In production
187
+ * this routes to the co-agent's server/client/UI tool execution under the session's context
188
+ * user.
189
+ */
190
+ ExecuteTool: (call: RealtimeToolCall) => Promise<ToolExecutionResult>;
191
+ /** Optional verbose-aware status logger. */
192
+ LogStatus?: RealtimeStatusLogger;
193
+ /** Optional error logger. */
194
+ LogError?: RealtimeErrorLogger;
195
+ }
196
+ /**
197
+ * Executes a single realtime tool call server-side, identically across both audio topologies.
198
+ *
199
+ * Construct with a {@link RealtimeToolBrokerDeps}, then call {@link ExecuteToolCall} per provider
200
+ * tool call. The broker routes the call, owns the abort controller for an in-flight delegated run,
201
+ * and returns the serialized {@link ExecutedToolCall} the transport layer relays back to the model.
202
+ */
203
+ export declare class RealtimeToolBroker {
204
+ private deps;
205
+ /** The abort controller for the currently in-flight delegated run, if any. */
206
+ private currentDelegationController;
207
+ /**
208
+ * @param deps The injected collaborators that execute tool calls.
209
+ */
210
+ constructor(deps: RealtimeToolBrokerDeps);
211
+ /**
212
+ * Executes a realtime tool call and returns its serialized result.
213
+ *
214
+ * Routes `invoke-target-agent` → {@link RealtimeToolBrokerDeps.DelegateToTarget} (creating and
215
+ * owning a per-call {@link AbortController} so {@link AbortInFlight} can cancel it on barge-in),
216
+ * and every other tool → {@link RealtimeToolBrokerDeps.ExecuteTool}. Always resolves with an
217
+ * {@link ExecutedToolCall} — failures are serialized as structured errors rather than thrown, so
218
+ * the model always receives a consistent `tool_response`.
219
+ *
220
+ * @param call The tool-call request emitted by the model.
221
+ * @returns The serialized result the transport layer relays back to the model.
222
+ */
223
+ ExecuteToolCall(call: RealtimeToolCall): Promise<ExecutedToolCall>;
224
+ /**
225
+ * Aborts the in-flight delegated run's controller (if any).
226
+ *
227
+ * Called by the transport layer on barge-in so a stale delegated result is never narrated into a
228
+ * conversation that has moved on. Safe no-op when no delegation is in flight.
229
+ */
230
+ AbortInFlight(): void;
231
+ /**
232
+ * Delegates an `invoke-target-agent` call to the target agent, owning a fresh
233
+ * {@link AbortController} so {@link AbortInFlight} can cancel the in-flight run on barge-in.
234
+ *
235
+ * @param call The `invoke-target-agent` tool call.
236
+ * @returns The serialized delegation result (or structured error).
237
+ */
238
+ private runInvokeTarget;
239
+ /**
240
+ * Routes a non-target tool call to the injected tool executor.
241
+ *
242
+ * @param call The tool call (any tool other than `invoke-target-agent`).
243
+ * @returns The serialized tool result (or structured error).
244
+ */
245
+ private runOtherTool;
246
+ /**
247
+ * Serializes a successful tool/delegation outcome to the model's expected `tool_response` shape.
248
+ *
249
+ * @param success Whether the tool/delegation completed successfully.
250
+ * @param output The textual outcome (narration on success, error text on failure).
251
+ * @param pausedRunID When the delegated run paused awaiting feedback, the paused run's id to
252
+ * surface for resumption. Omitted for completed runs and non-delegation tools.
253
+ * @param runID ID of the delegated agent run, when one was created. Embedded in the JSON as
254
+ * `runId` so the client overlay's developer tooling can link to the run record. Omitted for
255
+ * non-delegation tools.
256
+ * @param artifacts Artifacts the delegated run produced. Embedded in the JSON as
257
+ * `artifacts: [{ artifactId, artifactVersionId, name }]` so the client overlay can open
258
+ * them in artifact tabs. Omitted when absent or empty.
259
+ * @returns The serialized result.
260
+ */
261
+ private serializeResult;
262
+ /**
263
+ * Serializes a thrown error to a structured error `tool_response` so the model can narrate the
264
+ * failure (consistent with the plan's spoken-error-handling) rather than leaving the call
265
+ * unanswered.
266
+ *
267
+ * @param error The thrown error or message.
268
+ * @returns The serialized error result (always `Success: false`).
269
+ */
270
+ private serializeError;
271
+ /**
272
+ * Logs an error via the injected logger (if any), prefixed with the failing operation.
273
+ *
274
+ * @param error The thrown error or message.
275
+ * @param operation A short description of what was being attempted.
276
+ */
277
+ private logError;
278
+ }
279
+ //# sourceMappingURL=realtime-tool-broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-tool-broker.d.ts","sourceRoot":"","sources":["../../src/realtime/realtime-tool-broker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * @fileoverview Topology-agnostic broker that executes a single realtime tool call server-side.
3
+ *
4
+ * The {@link RealtimeToolBroker} owns the *tool-execution* half of a realtime session: given a
5
+ * provider {@link RealtimeToolCall}, it routes the call (the stable `invoke-target-agent` tool →
6
+ * delegate to the target agent; every other tool → an injected tool executor), owns the per-call
7
+ * {@link AbortController} so barge-in can cancel an in-flight delegated run, and serializes the
8
+ * success/error result into the exact JSON the model expects as a `tool_response`.
9
+ *
10
+ * **Why factor this out.** Both audio topologies must execute a realtime tool call *identically*:
11
+ * the **server-bridged** path ({@link RealtimeSessionRunner}, where the provider socket lives on the
12
+ * server) and the **client-direct** path (where the browser owns the socket and relays tool calls
13
+ * back to a server resolver). Keeping one broker guarantees the two paths produce byte-for-byte
14
+ * identical tool results, including structured errors for spoken-error-handling. The broker is the
15
+ * single tool-execution path both topologies share.
16
+ *
17
+ * **Dependency injection.** Every collaborator that would otherwise pull in `BaseAgent`, metadata,
18
+ * or the database is injected via {@link RealtimeToolBrokerDeps}, keeping the broker fully
19
+ * unit-testable against mocks.
20
+ *
21
+ * @module @memberjunction/ai-agents
22
+ * @author MemberJunction.com
23
+ */
24
+ /**
25
+ * The stable name of the primary tool every Realtime Co-Agent registers with the realtime provider.
26
+ *
27
+ * Per the plan's design rule, the realtime-registered tool set is **target-independent**: the
28
+ * co-agent always exposes this single `invoke-target-agent` tool, and the specific target is a
29
+ * runtime parameter passed *inside* the call — never a different tool per target. This keeps the
30
+ * provider contract identical across targets (and is what lets a pre-provisioned, fixed-tool
31
+ * provider like Eleven Labs fit the same model later).
32
+ */
33
+ export const INVOKE_TARGET_AGENT_TOOL_NAME = 'invoke-target-agent';
34
+ /**
35
+ * Executes a single realtime tool call server-side, identically across both audio topologies.
36
+ *
37
+ * Construct with a {@link RealtimeToolBrokerDeps}, then call {@link ExecuteToolCall} per provider
38
+ * tool call. The broker routes the call, owns the abort controller for an in-flight delegated run,
39
+ * and returns the serialized {@link ExecutedToolCall} the transport layer relays back to the model.
40
+ */
41
+ export class RealtimeToolBroker {
42
+ /**
43
+ * @param deps The injected collaborators that execute tool calls.
44
+ */
45
+ constructor(deps) {
46
+ /** The abort controller for the currently in-flight delegated run, if any. */
47
+ this.currentDelegationController = null;
48
+ this.deps = deps;
49
+ }
50
+ /**
51
+ * Executes a realtime tool call and returns its serialized result.
52
+ *
53
+ * Routes `invoke-target-agent` → {@link RealtimeToolBrokerDeps.DelegateToTarget} (creating and
54
+ * owning a per-call {@link AbortController} so {@link AbortInFlight} can cancel it on barge-in),
55
+ * and every other tool → {@link RealtimeToolBrokerDeps.ExecuteTool}. Always resolves with an
56
+ * {@link ExecutedToolCall} — failures are serialized as structured errors rather than thrown, so
57
+ * the model always receives a consistent `tool_response`.
58
+ *
59
+ * @param call The tool-call request emitted by the model.
60
+ * @returns The serialized result the transport layer relays back to the model.
61
+ */
62
+ async ExecuteToolCall(call) {
63
+ if (call.ToolName === INVOKE_TARGET_AGENT_TOOL_NAME) {
64
+ return this.runInvokeTarget(call);
65
+ }
66
+ return this.runOtherTool(call);
67
+ }
68
+ /**
69
+ * Aborts the in-flight delegated run's controller (if any).
70
+ *
71
+ * Called by the transport layer on barge-in so a stale delegated result is never narrated into a
72
+ * conversation that has moved on. Safe no-op when no delegation is in flight.
73
+ */
74
+ AbortInFlight() {
75
+ if (this.currentDelegationController) {
76
+ this.currentDelegationController.abort();
77
+ this.currentDelegationController = null;
78
+ }
79
+ }
80
+ /**
81
+ * Delegates an `invoke-target-agent` call to the target agent, owning a fresh
82
+ * {@link AbortController} so {@link AbortInFlight} can cancel the in-flight run on barge-in.
83
+ *
84
+ * @param call The `invoke-target-agent` tool call.
85
+ * @returns The serialized delegation result (or structured error).
86
+ */
87
+ async runInvokeTarget(call) {
88
+ const controller = new AbortController();
89
+ this.currentDelegationController = controller;
90
+ try {
91
+ const result = await this.deps.DelegateToTarget({
92
+ CallID: call.CallID,
93
+ Arguments: call.Arguments,
94
+ AbortSignal: controller.signal
95
+ });
96
+ return this.serializeResult(result.Success, result.Output, result.PausedRunID, result.RunID, result.Artifacts);
97
+ }
98
+ catch (error) {
99
+ this.logError(error, 'delegating to target agent');
100
+ return this.serializeError(error);
101
+ }
102
+ finally {
103
+ // Only clear if this is still the active controller (a later delegation may have replaced it).
104
+ if (this.currentDelegationController === controller) {
105
+ this.currentDelegationController = null;
106
+ }
107
+ }
108
+ }
109
+ /**
110
+ * Routes a non-target tool call to the injected tool executor.
111
+ *
112
+ * @param call The tool call (any tool other than `invoke-target-agent`).
113
+ * @returns The serialized tool result (or structured error).
114
+ */
115
+ async runOtherTool(call) {
116
+ try {
117
+ const result = await this.deps.ExecuteTool(call);
118
+ return this.serializeResult(result.Success, result.Output);
119
+ }
120
+ catch (error) {
121
+ this.logError(error, `executing tool '${call.ToolName}'`);
122
+ return this.serializeError(error);
123
+ }
124
+ }
125
+ /**
126
+ * Serializes a successful tool/delegation outcome to the model's expected `tool_response` shape.
127
+ *
128
+ * @param success Whether the tool/delegation completed successfully.
129
+ * @param output The textual outcome (narration on success, error text on failure).
130
+ * @param pausedRunID When the delegated run paused awaiting feedback, the paused run's id to
131
+ * surface for resumption. Omitted for completed runs and non-delegation tools.
132
+ * @param runID ID of the delegated agent run, when one was created. Embedded in the JSON as
133
+ * `runId` so the client overlay's developer tooling can link to the run record. Omitted for
134
+ * non-delegation tools.
135
+ * @param artifacts Artifacts the delegated run produced. Embedded in the JSON as
136
+ * `artifacts: [{ artifactId, artifactVersionId, name }]` so the client overlay can open
137
+ * them in artifact tabs. Omitted when absent or empty.
138
+ * @returns The serialized result.
139
+ */
140
+ serializeResult(success, output, pausedRunID, runID, artifacts) {
141
+ const payload = { success, output };
142
+ if (runID) {
143
+ payload.runId = runID;
144
+ }
145
+ const hasArtifacts = artifacts != null && artifacts.length > 0;
146
+ if (hasArtifacts) {
147
+ payload.artifacts = artifacts.map(a => ({
148
+ artifactId: a.ArtifactID,
149
+ artifactVersionId: a.ArtifactVersionID,
150
+ name: a.Name
151
+ }));
152
+ }
153
+ return {
154
+ ResultJson: JSON.stringify(payload),
155
+ Success: success,
156
+ PausedRunID: pausedRunID,
157
+ RunID: runID,
158
+ Artifacts: hasArtifacts ? artifacts : undefined
159
+ };
160
+ }
161
+ /**
162
+ * Serializes a thrown error to a structured error `tool_response` so the model can narrate the
163
+ * failure (consistent with the plan's spoken-error-handling) rather than leaving the call
164
+ * unanswered.
165
+ *
166
+ * @param error The thrown error or message.
167
+ * @returns The serialized error result (always `Success: false`).
168
+ */
169
+ serializeError(error) {
170
+ const message = error instanceof Error ? error.message : String(error);
171
+ return { ResultJson: JSON.stringify({ success: false, error: message }), Success: false };
172
+ }
173
+ /**
174
+ * Logs an error via the injected logger (if any), prefixed with the failing operation.
175
+ *
176
+ * @param error The thrown error or message.
177
+ * @param operation A short description of what was being attempted.
178
+ */
179
+ logError(error, operation) {
180
+ const message = error instanceof Error ? error.message : String(error);
181
+ this.deps.LogError?.(`RealtimeToolBroker error while ${operation}: ${message}`);
182
+ }
183
+ }
184
+ //# sourceMappingURL=realtime-tool-broker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-tool-broker.js","sourceRoot":"","sources":["../../src/realtime/realtime-tool-broker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @fileoverview Server-side channel plugin for the live Whiteboard — the reference
3
+ * `BaseRealtimeChannelServer` implementation, paired with the browser's
4
+ * `RealtimeWhiteboardChannel` client plugin through the seeded `MJ: AI Agent Channels` row
5
+ * (`Name: 'Whiteboard'`, `ServerPluginClass: 'WhiteboardChannelServer'`,
6
+ * `ClientPluginClass: 'RealtimeWhiteboardChannel'`).
7
+ *
8
+ * Deliberately small and honest about its job: the whiteboard executes entirely client-side, so
9
+ * the server half's real value is guarding the **persisted state of record** — the
10
+ * `MJ: AI Agent Session Channels.Config` blob a future resume rehydrates through the client
11
+ * plugin's `RestoreState`. This plugin validates that every save the client lands is parseable
12
+ * board JSON (flagging corrupt payloads loudly instead of discovering them at the next resume)
13
+ * and normalizes valid payloads to a canonical compact serialization.
14
+ *
15
+ * @module @memberjunction/ai-agents
16
+ * @author MemberJunction.com
17
+ */
18
+ import { BaseRealtimeChannelServer } from '@memberjunction/ai';
19
+ /**
20
+ * Server half of the Whiteboard interactive channel. One instance per realtime session (created
21
+ * by `RealtimeChannelServerHost` from the channel registry — never construct directly).
22
+ *
23
+ * Behavior on each landed state save ({@link OnChannelStateSave}):
24
+ * - payload parses to a JSON **object** → persist the canonical compact re-serialization
25
+ * (`JSON.stringify(parsed)`), or the original when already canonical;
26
+ * - payload is malformed JSON or a non-object (array/primitive) → log loudly and keep the
27
+ * original unchanged — persistence is never blocked, and the client's `RestoreState` contract
28
+ * is tolerant of bad payloads, so flag-don't-drop is the safe posture.
29
+ */
30
+ export declare class WhiteboardChannelServer extends BaseRealtimeChannelServer {
31
+ /** Matches the seeded `MJ: AI Agent Channels` row's `Name`. */
32
+ get ChannelName(): string;
33
+ /**
34
+ * Validates + canonicalizes a landed board-state save (see the class doc for the contract).
35
+ *
36
+ * @param stateJson The serialized board scene the client submitted.
37
+ * @returns The compact canonical JSON when the payload is a valid object and differs from the
38
+ * input; `null` (= keep the original) otherwise.
39
+ */
40
+ OnChannelStateSave(stateJson: string): Promise<string | null>;
41
+ /** Flags a corrupt board payload — kept loud so it is caught before the next resume, not at it. */
42
+ private logInvalidState;
43
+ }
44
+ /**
45
+ * Tree-shaking prevention for {@link WhiteboardChannelServer}'s `@RegisterClass` registration.
46
+ * Called from a static code path in the server host (MJServer's `agentSessions` module) so the
47
+ * registration always executes — mirroring every other `Load...()` in the realtime stack.
48
+ */
49
+ export declare function LoadWhiteboardChannelServer(): void;
50
+ //# sourceMappingURL=whiteboard-channel-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whiteboard-channel-server.d.ts","sourceRoot":"","sources":["../../src/realtime/whiteboard-channel-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAI/D;;;;;;;;;;GAUG;AACH,qBACa,uBAAwB,SAAQ,yBAAyB;IAClE,+DAA+D;IAC/D,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED;;;;;;OAMG;IACmB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAgBnF,mGAAmG;IACnG,OAAO,CAAC,eAAe;CAO1B;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAElD"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @fileoverview Server-side channel plugin for the live Whiteboard — the reference
3
+ * `BaseRealtimeChannelServer` implementation, paired with the browser's
4
+ * `RealtimeWhiteboardChannel` client plugin through the seeded `MJ: AI Agent Channels` row
5
+ * (`Name: 'Whiteboard'`, `ServerPluginClass: 'WhiteboardChannelServer'`,
6
+ * `ClientPluginClass: 'RealtimeWhiteboardChannel'`).
7
+ *
8
+ * Deliberately small and honest about its job: the whiteboard executes entirely client-side, so
9
+ * the server half's real value is guarding the **persisted state of record** — the
10
+ * `MJ: AI Agent Session Channels.Config` blob a future resume rehydrates through the client
11
+ * plugin's `RestoreState`. This plugin validates that every save the client lands is parseable
12
+ * board JSON (flagging corrupt payloads loudly instead of discovering them at the next resume)
13
+ * and normalizes valid payloads to a canonical compact serialization.
14
+ *
15
+ * @module @memberjunction/ai-agents
16
+ * @author MemberJunction.com
17
+ */
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ 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;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ import { BaseRealtimeChannelServer } from '@memberjunction/ai';
25
+ import { RegisterClass } from '@memberjunction/global';
26
+ import { LogError } from '@memberjunction/core';
27
+ /**
28
+ * Server half of the Whiteboard interactive channel. One instance per realtime session (created
29
+ * by `RealtimeChannelServerHost` from the channel registry — never construct directly).
30
+ *
31
+ * Behavior on each landed state save ({@link OnChannelStateSave}):
32
+ * - payload parses to a JSON **object** → persist the canonical compact re-serialization
33
+ * (`JSON.stringify(parsed)`), or the original when already canonical;
34
+ * - payload is malformed JSON or a non-object (array/primitive) → log loudly and keep the
35
+ * original unchanged — persistence is never blocked, and the client's `RestoreState` contract
36
+ * is tolerant of bad payloads, so flag-don't-drop is the safe posture.
37
+ */
38
+ let WhiteboardChannelServer = class WhiteboardChannelServer extends BaseRealtimeChannelServer {
39
+ /** Matches the seeded `MJ: AI Agent Channels` row's `Name`. */
40
+ get ChannelName() {
41
+ return 'Whiteboard';
42
+ }
43
+ /**
44
+ * Validates + canonicalizes a landed board-state save (see the class doc for the contract).
45
+ *
46
+ * @param stateJson The serialized board scene the client submitted.
47
+ * @returns The compact canonical JSON when the payload is a valid object and differs from the
48
+ * input; `null` (= keep the original) otherwise.
49
+ */
50
+ async OnChannelStateSave(stateJson) {
51
+ let parsed;
52
+ try {
53
+ parsed = JSON.parse(stateJson);
54
+ }
55
+ catch {
56
+ this.logInvalidState('is not valid JSON');
57
+ return null;
58
+ }
59
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
60
+ this.logInvalidState('is not a JSON object');
61
+ return null;
62
+ }
63
+ const canonical = JSON.stringify(parsed);
64
+ return canonical === stateJson ? null : canonical;
65
+ }
66
+ /** Flags a corrupt board payload — kept loud so it is caught before the next resume, not at it. */
67
+ logInvalidState(problem) {
68
+ const sessionID = this.Context?.AgentSessionID ?? 'unknown';
69
+ LogError(`[WhiteboardChannelServer] Board state save for session ${sessionID} ${problem} — ` +
70
+ 'persisting the payload unchanged; a future resume will start with a fresh board.');
71
+ }
72
+ };
73
+ WhiteboardChannelServer = __decorate([
74
+ RegisterClass(BaseRealtimeChannelServer, 'WhiteboardChannelServer')
75
+ ], WhiteboardChannelServer);
76
+ export { WhiteboardChannelServer };
77
+ /**
78
+ * Tree-shaking prevention for {@link WhiteboardChannelServer}'s `@RegisterClass` registration.
79
+ * Called from a static code path in the server host (MJServer's `agentSessions` module) so the
80
+ * registration always executes — mirroring every other `Load...()` in the realtime stack.
81
+ */
82
+ export function LoadWhiteboardChannelServer() {
83
+ // no-op — the import + call create a static reference bundlers cannot eliminate
84
+ }
85
+ //# sourceMappingURL=whiteboard-channel-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whiteboard-channel-server.js","sourceRoot":"","sources":["../../src/realtime/whiteboard-channel-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;;;;;;;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD;;;;;;;;;;GAUG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,yBAAyB;IAClE,+DAA+D;IAC/D,IAAW,WAAW;QAClB,OAAO,YAAY,CAAC;IACxB,CAAC;IAED;;;;;;OAMG;IACa,KAAK,CAAC,kBAAkB,CAAC,SAAiB;QACtD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACL,IAAI,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;YAC1C,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACzE,IAAI,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC;YAC7C,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACzC,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,CAAC;IAED,mGAAmG;IAC3F,eAAe,CAAC,OAAe;QACnC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,cAAc,IAAI,SAAS,CAAC;QAC5D,QAAQ,CACJ,0DAA0D,SAAS,IAAI,OAAO,KAAK;YAC/E,kFAAkF,CACzF,CAAC;IACN,CAAC;CACJ,CAAA;AArCY,uBAAuB;IADnC,aAAa,CAAC,yBAAyB,EAAE,yBAAyB,CAAC;GACvD,uBAAuB,CAqCnC;;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B;IACvC,gFAAgF;AACpF,CAAC"}