@memberjunction/conversations-runtime 0.0.1 → 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 +99 -43
- package/dist/ConversationsRuntime.d.ts +193 -0
- package/dist/ConversationsRuntime.d.ts.map +1 -0
- package/dist/ConversationsRuntime.js +268 -0
- package/dist/ConversationsRuntime.js.map +1 -0
- package/dist/adapters/IActiveTaskTracker.d.ts +49 -0
- package/dist/adapters/IActiveTaskTracker.d.ts.map +1 -0
- package/dist/adapters/IActiveTaskTracker.js +26 -0
- package/dist/adapters/IActiveTaskTracker.js.map +1 -0
- package/dist/adapters/INotificationAdapter.d.ts +60 -0
- package/dist/adapters/INotificationAdapter.d.ts.map +1 -0
- package/dist/adapters/INotificationAdapter.js +45 -0
- package/dist/adapters/INotificationAdapter.js.map +1 -0
- package/dist/adapters/ISessionsAdapter.d.ts +124 -0
- package/dist/adapters/ISessionsAdapter.d.ts.map +1 -0
- package/dist/adapters/ISessionsAdapter.js +44 -0
- package/dist/adapters/ISessionsAdapter.js.map +1 -0
- package/dist/agent-runner/ConversationAgentRunner.d.ts +121 -0
- package/dist/agent-runner/ConversationAgentRunner.d.ts.map +1 -0
- package/dist/agent-runner/ConversationAgentRunner.js +191 -0
- package/dist/agent-runner/ConversationAgentRunner.js.map +1 -0
- package/dist/bridge/ConversationBridge.d.ts +93 -0
- package/dist/bridge/ConversationBridge.d.ts.map +1 -0
- package/dist/bridge/ConversationBridge.js +105 -0
- package/dist/bridge/ConversationBridge.js.map +1 -0
- package/dist/context/IConversationsRuntimeContext.d.ts +29 -0
- package/dist/context/IConversationsRuntimeContext.d.ts.map +1 -0
- package/dist/context/IConversationsRuntimeContext.js +21 -0
- package/dist/context/IConversationsRuntimeContext.js.map +1 -0
- package/dist/default-agent/DefaultAgentResolver.d.ts +87 -0
- package/dist/default-agent/DefaultAgentResolver.d.ts.map +1 -0
- package/dist/default-agent/DefaultAgentResolver.js +103 -0
- package/dist/default-agent/DefaultAgentResolver.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/mentions/MentionParser.d.ts +109 -0
- package/dist/mentions/MentionParser.d.ts.map +1 -0
- package/dist/mentions/MentionParser.js +276 -0
- package/dist/mentions/MentionParser.js.map +1 -0
- package/dist/sessions/SessionsObserver.d.ts +87 -0
- package/dist/sessions/SessionsObserver.d.ts.map +1 -0
- package/dist/sessions/SessionsObserver.js +103 -0
- package/dist/sessions/SessionsObserver.js.map +1 -0
- package/dist/streaming/ConversationStreaming.d.ts +169 -0
- package/dist/streaming/ConversationStreaming.d.ts.map +1 -0
- package/dist/streaming/ConversationStreaming.js +355 -0
- package/dist/streaming/ConversationStreaming.js.map +1 -0
- package/package.json +33 -7
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Active-task tracker adapter — boundary between the runtime's
|
|
3
|
+
* streaming layer and the host's task-tracking UI.
|
|
4
|
+
*
|
|
5
|
+
* `ConversationStreaming` needs to remove a tracked task when its agent run
|
|
6
|
+
* completes (so the "agent is working…" spinner in the conversation list
|
|
7
|
+
* clears). The host's task store — Angular's `ActiveTasksService`, a Redux
|
|
8
|
+
* slice in a React app, anything else — implements this minimal contract.
|
|
9
|
+
*
|
|
10
|
+
* The default {@link NoOpActiveTaskTracker} does nothing, which is fine for
|
|
11
|
+
* server-side / headless callers that don't render a task list.
|
|
12
|
+
*
|
|
13
|
+
* @module @memberjunction/conversations-runtime
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Minimal contract the streaming layer needs from a task tracker.
|
|
17
|
+
*
|
|
18
|
+
* Kept deliberately narrow — only `RemoveByAgentRunId` is consumed by
|
|
19
|
+
* `ConversationStreaming` today. The host's broader task UI (Angular's
|
|
20
|
+
* `ActiveTasksService` has ~16 methods + multiple observables) stays in
|
|
21
|
+
* the widget; only the methods the runtime calls are exposed here.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Angular host bootstrap
|
|
26
|
+
* runtime.UseActiveTaskTracker({
|
|
27
|
+
* RemoveByAgentRunId: (id) => inject(ActiveTasksService).removeByAgentRunId(id),
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export interface IActiveTaskTracker {
|
|
32
|
+
/**
|
|
33
|
+
* Remove a tracked task when its agent run completes.
|
|
34
|
+
*
|
|
35
|
+
* @param agentRunId The `MJ: AI Agent Runs` ID whose task should be cleared.
|
|
36
|
+
* @returns `true` if a task was found and removed, `false` if nothing matched.
|
|
37
|
+
*/
|
|
38
|
+
RemoveByAgentRunId(agentRunId: string): boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Default {@link IActiveTaskTracker} that does nothing. Used when no tracker has
|
|
42
|
+
* been registered — fine for headless / server-side consumers that don't render
|
|
43
|
+
* task UI. Returns `false` from `RemoveByAgentRunId` to signal "nothing was
|
|
44
|
+
* tracked," which is the truthful answer in a no-op world.
|
|
45
|
+
*/
|
|
46
|
+
export declare class NoOpActiveTaskTracker implements IActiveTaskTracker {
|
|
47
|
+
RemoveByAgentRunId(_agentRunId: string): boolean;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=IActiveTaskTracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IActiveTaskTracker.d.ts","sourceRoot":"","sources":["../../src/adapters/IActiveTaskTracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;;OAKG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;CACnD;AAED;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,kBAAkB;IACrD,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;CAG1D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Active-task tracker adapter — boundary between the runtime's
|
|
3
|
+
* streaming layer and the host's task-tracking UI.
|
|
4
|
+
*
|
|
5
|
+
* `ConversationStreaming` needs to remove a tracked task when its agent run
|
|
6
|
+
* completes (so the "agent is working…" spinner in the conversation list
|
|
7
|
+
* clears). The host's task store — Angular's `ActiveTasksService`, a Redux
|
|
8
|
+
* slice in a React app, anything else — implements this minimal contract.
|
|
9
|
+
*
|
|
10
|
+
* The default {@link NoOpActiveTaskTracker} does nothing, which is fine for
|
|
11
|
+
* server-side / headless callers that don't render a task list.
|
|
12
|
+
*
|
|
13
|
+
* @module @memberjunction/conversations-runtime
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Default {@link IActiveTaskTracker} that does nothing. Used when no tracker has
|
|
17
|
+
* been registered — fine for headless / server-side consumers that don't render
|
|
18
|
+
* task UI. Returns `false` from `RemoveByAgentRunId` to signal "nothing was
|
|
19
|
+
* tracked," which is the truthful answer in a no-op world.
|
|
20
|
+
*/
|
|
21
|
+
export class NoOpActiveTaskTracker {
|
|
22
|
+
RemoveByAgentRunId(_agentRunId) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=IActiveTaskTracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IActiveTaskTracker.js","sourceRoot":"","sources":["../../src/adapters/IActiveTaskTracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA4BH;;;;;GAKG;AACH,MAAM,OAAO,qBAAqB;IACvB,kBAAkB,CAAC,WAAmB;QACzC,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Notification adapter — boundary between the runtime and the host's
|
|
3
|
+
* notification UI.
|
|
4
|
+
*
|
|
5
|
+
* The runtime needs to surface user-facing messages ("Sage agent not found",
|
|
6
|
+
* "Agent execution failed", etc.) but must NOT depend on any specific UI library.
|
|
7
|
+
* Consumers supply an adapter that bridges to whatever notification system the host
|
|
8
|
+
* uses — Angular's `MJNotificationService`, a React toaster, a Node logger, etc.
|
|
9
|
+
*
|
|
10
|
+
* Default (when no adapter is registered): {@link ConsoleNotificationAdapter} logs
|
|
11
|
+
* to the console. That keeps the runtime usable out of the box without requiring
|
|
12
|
+
* every consumer to wire something up.
|
|
13
|
+
*
|
|
14
|
+
* @module @memberjunction/conversations-runtime
|
|
15
|
+
*/
|
|
16
|
+
/** Severity level for a notification — maps cleanly to most toaster systems. */
|
|
17
|
+
export type NotificationLevel = 'info' | 'success' | 'warning' | 'error';
|
|
18
|
+
/**
|
|
19
|
+
* Boundary the runtime calls to surface a user-facing message.
|
|
20
|
+
*
|
|
21
|
+
* Apps supply an implementation that bridges to their UI toaster (Angular's
|
|
22
|
+
* `MJNotificationService.CreateSimpleNotification`, a custom React/Vue system,
|
|
23
|
+
* server-side log sink, etc.) via {@link ConversationsRuntime.UseNotificationAdapter}.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Angular host bootstrap
|
|
28
|
+
* runtime.UseNotificationAdapter({
|
|
29
|
+
* Notify: (level, message, ttlMs) => {
|
|
30
|
+
* const style = level === 'warning' ? 'warn' : level; // map names
|
|
31
|
+
* MJNotificationService.Instance.CreateSimpleNotification(message, style, ttlMs ?? 5000);
|
|
32
|
+
* },
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export interface INotificationAdapter {
|
|
37
|
+
/**
|
|
38
|
+
* Surface a notification to the user.
|
|
39
|
+
*
|
|
40
|
+
* @param level Severity of the notification.
|
|
41
|
+
* @param message Human-readable text to display.
|
|
42
|
+
* @param ttlMs Optional duration in milliseconds. When omitted, the host decides
|
|
43
|
+
* (typically 5 seconds for non-error, longer for errors).
|
|
44
|
+
*/
|
|
45
|
+
Notify(level: NotificationLevel, message: string, ttlMs?: number): void;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Default {@link INotificationAdapter} that logs to the console. Used when no adapter
|
|
49
|
+
* has been registered, so the runtime never silently swallows messages.
|
|
50
|
+
*
|
|
51
|
+
* - `info` and `success` → `console.log`
|
|
52
|
+
* - `warning` → `console.warn`
|
|
53
|
+
* - `error` → `console.error`
|
|
54
|
+
*
|
|
55
|
+
* Replace with a UI-backed adapter at host bootstrap for production use.
|
|
56
|
+
*/
|
|
57
|
+
export declare class ConsoleNotificationAdapter implements INotificationAdapter {
|
|
58
|
+
Notify(level: NotificationLevel, message: string, ttlMs?: number): void;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=INotificationAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"INotificationAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/INotificationAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEzE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,oBAAoB;IACjC;;;;;;;OAOG;IACH,MAAM,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3E;AAED;;;;;;;;;GASG;AACH,qBAAa,0BAA2B,YAAW,oBAAoB;IAC5D,MAAM,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;CAiBjF"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Notification adapter — boundary between the runtime and the host's
|
|
3
|
+
* notification UI.
|
|
4
|
+
*
|
|
5
|
+
* The runtime needs to surface user-facing messages ("Sage agent not found",
|
|
6
|
+
* "Agent execution failed", etc.) but must NOT depend on any specific UI library.
|
|
7
|
+
* Consumers supply an adapter that bridges to whatever notification system the host
|
|
8
|
+
* uses — Angular's `MJNotificationService`, a React toaster, a Node logger, etc.
|
|
9
|
+
*
|
|
10
|
+
* Default (when no adapter is registered): {@link ConsoleNotificationAdapter} logs
|
|
11
|
+
* to the console. That keeps the runtime usable out of the box without requiring
|
|
12
|
+
* every consumer to wire something up.
|
|
13
|
+
*
|
|
14
|
+
* @module @memberjunction/conversations-runtime
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Default {@link INotificationAdapter} that logs to the console. Used when no adapter
|
|
18
|
+
* has been registered, so the runtime never silently swallows messages.
|
|
19
|
+
*
|
|
20
|
+
* - `info` and `success` → `console.log`
|
|
21
|
+
* - `warning` → `console.warn`
|
|
22
|
+
* - `error` → `console.error`
|
|
23
|
+
*
|
|
24
|
+
* Replace with a UI-backed adapter at host bootstrap for production use.
|
|
25
|
+
*/
|
|
26
|
+
export class ConsoleNotificationAdapter {
|
|
27
|
+
Notify(level, message, ttlMs) {
|
|
28
|
+
const ttlNote = ttlMs ? ` (ttl=${ttlMs}ms)` : '';
|
|
29
|
+
const prefixed = `[conversations-runtime] ${message}${ttlNote}`;
|
|
30
|
+
switch (level) {
|
|
31
|
+
case 'error':
|
|
32
|
+
console.error(prefixed);
|
|
33
|
+
return;
|
|
34
|
+
case 'warning':
|
|
35
|
+
console.warn(prefixed);
|
|
36
|
+
return;
|
|
37
|
+
case 'success':
|
|
38
|
+
case 'info':
|
|
39
|
+
default:
|
|
40
|
+
console.log(prefixed);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=INotificationAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"INotificationAdapter.js","sourceRoot":"","sources":["../../src/adapters/INotificationAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAmCH;;;;;;;;;GASG;AACH,MAAM,OAAO,0BAA0B;IAC5B,MAAM,CAAC,KAAwB,EAAE,OAAe,EAAE,KAAc;QACnE,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,2BAA2B,OAAO,GAAG,OAAO,EAAE,CAAC;QAChE,QAAQ,KAAK,EAAE,CAAC;YACZ,KAAK,OAAO;gBACR,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACxB,OAAO;YACX,KAAK,SAAS;gBACV,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvB,OAAO;YACX,KAAK,SAAS,CAAC;YACf,KAAK,MAAM,CAAC;YACZ;gBACI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACtB,OAAO;QACf,CAAC;IACL,CAAC;CACJ"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Sessions adapter — boundary between the runtime and the host's
|
|
3
|
+
* realtime sessions infrastructure (PR #2787 — `MJ: AI Agent Sessions` + Channels).
|
|
4
|
+
*
|
|
5
|
+
* The runtime needs to surface session lifecycle events (a Voice / Realtime
|
|
6
|
+
* co-agent session started, a channel within it opened or closed, the session
|
|
7
|
+
* ended) without depending on any specific UI library or session implementation.
|
|
8
|
+
* Hosts implement this adapter to bridge their internal session source
|
|
9
|
+
* (Angular's `RealtimeSessionService` today; future server-bridged voice host,
|
|
10
|
+
* video-only host, etc.) into a single push stream the runtime exposes.
|
|
11
|
+
*
|
|
12
|
+
* Default (when no adapter is registered): {@link NoOpSessionsAdapter} emits
|
|
13
|
+
* nothing. Headless consumers still work — the
|
|
14
|
+
* {@link ../sessions/SessionsObserver.SessionsObserver} sub-component subscribes,
|
|
15
|
+
* sees no events, and the rest of the runtime is unaffected.
|
|
16
|
+
*
|
|
17
|
+
* **Multi-source-capable by design.** An adapter implementation can merge
|
|
18
|
+
* multiple internal services (voice + future video + future server-bridged
|
|
19
|
+
* realtime) into one observable. The runtime never sees the underlying services.
|
|
20
|
+
*
|
|
21
|
+
* **Scope cut — server-only events.** Server-side session closes (janitor
|
|
22
|
+
* sweep / shutdown) that happen while the user's tab is gone do NOT flow
|
|
23
|
+
* through this adapter today. Live-session orchestration only; admin/observability
|
|
24
|
+
* tooling polls the entity for those.
|
|
25
|
+
*
|
|
26
|
+
* @module @memberjunction/conversations-runtime
|
|
27
|
+
*/
|
|
28
|
+
import { Observable } from 'rxjs';
|
|
29
|
+
/**
|
|
30
|
+
* Per-channel state surfaced for `session-channel` events.
|
|
31
|
+
*
|
|
32
|
+
* **Why only two values?** `RealtimeSessionService`'s only channel observable is
|
|
33
|
+
* `ActiveChannels$` (the full plugin set), which fires once on resolve and again
|
|
34
|
+
* with `[]` on teardown. There's no `opening` / `closing` transition observable
|
|
35
|
+
* at the channel-plugin level today. Narrowing here is honest about what's
|
|
36
|
+
* observable; widening later is non-breaking (consumers handling
|
|
37
|
+
* `'open' | 'closed'` still type-check against `'opening' | 'open' | 'closing'
|
|
38
|
+
* | 'closed'`).
|
|
39
|
+
*/
|
|
40
|
+
export type SessionChannelState = 'open' | 'closed';
|
|
41
|
+
/**
|
|
42
|
+
* Why a session ended.
|
|
43
|
+
*
|
|
44
|
+
* **Three values, not four.** The server-side `AIAgentSession.CloseReason`
|
|
45
|
+
* column has four (`Explicit | Janitor | Shutdown | Error`), but only two are
|
|
46
|
+
* distinguishable client-side (`explicit` = user called `EndVoiceSession`;
|
|
47
|
+
* `error` = teardown ran from a catch block). `'unknown'` covers any other
|
|
48
|
+
* client-observable end path. Janitor/shutdown happen out-of-process and never
|
|
49
|
+
* reach the runtime — see the module-level scope cut.
|
|
50
|
+
*/
|
|
51
|
+
export type SessionEndReason = 'explicit' | 'error' | 'unknown';
|
|
52
|
+
/**
|
|
53
|
+
* One lifecycle event surfaced by an {@link ISessionsAdapter}.
|
|
54
|
+
*
|
|
55
|
+
* Mirrors `MJ: AI Agent Sessions` lifecycle at a deliberately generic level —
|
|
56
|
+
* no voice/transcript/model fields — so future channel modalities (video,
|
|
57
|
+
* screen-share, code editor, etc.) emit the same shape.
|
|
58
|
+
*/
|
|
59
|
+
export type SessionLifecycleEvent = {
|
|
60
|
+
kind: 'session-started';
|
|
61
|
+
sessionId: string;
|
|
62
|
+
channelKinds: string[];
|
|
63
|
+
} | {
|
|
64
|
+
kind: 'session-channel';
|
|
65
|
+
sessionId: string;
|
|
66
|
+
channelKind: string;
|
|
67
|
+
state: SessionChannelState;
|
|
68
|
+
} | {
|
|
69
|
+
kind: 'session-ended';
|
|
70
|
+
sessionId: string;
|
|
71
|
+
reason: SessionEndReason;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Boundary the runtime subscribes to for session lifecycle.
|
|
75
|
+
*
|
|
76
|
+
* Hosts supply an implementation that pushes events from their realtime
|
|
77
|
+
* session source — the Angular host's `RealtimeSessionsAdapter` bridges
|
|
78
|
+
* `RealtimeSessionService`'s `SessionStarted$` / `ActiveChannels$` / `SessionEnded$`
|
|
79
|
+
* observables; a Node CLI or React app would write a different implementation.
|
|
80
|
+
*
|
|
81
|
+
* **Single-observable contract.** One `SessionLifecycle$` stream carries all
|
|
82
|
+
* three event kinds (a discriminated union). Subscribers narrow with the `kind`
|
|
83
|
+
* tag.
|
|
84
|
+
*
|
|
85
|
+
* @example Angular host bootstrap
|
|
86
|
+
* ```typescript
|
|
87
|
+
* runtime.UseSessionsAdapter(new RealtimeSessionsAdapter(voiceSessionService));
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @example Multi-source adapter (future)
|
|
91
|
+
* ```typescript
|
|
92
|
+
* // When a future video session service ships, merge it with voice — the
|
|
93
|
+
* // runtime contract doesn't change.
|
|
94
|
+
* class MultiModalSessionsAdapter implements ISessionsAdapter {
|
|
95
|
+
* public readonly SessionLifecycle$ = merge(
|
|
96
|
+
* this.voice.SessionLifecycle$,
|
|
97
|
+
* this.video.SessionLifecycle$,
|
|
98
|
+
* );
|
|
99
|
+
* constructor(private voice: RealtimeSessionsAdapter, private video: VideoSessionsAdapter) {}
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export interface ISessionsAdapter {
|
|
104
|
+
/**
|
|
105
|
+
* Push stream of session lifecycle events. Subscribers are typically the
|
|
106
|
+
* runtime's `SessionsObserver`, which re-broadcasts to widget consumers
|
|
107
|
+
* via `ConversationsRuntime.Instance.Sessions.SessionLifecycle$`.
|
|
108
|
+
*/
|
|
109
|
+
readonly SessionLifecycle$: Observable<SessionLifecycleEvent>;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Default {@link ISessionsAdapter} for headless / non-Angular consumers. Emits
|
|
113
|
+
* nothing — the runtime's `SessionsObserver` still constructs and exposes its
|
|
114
|
+
* observable; subscribers just never receive events until a real adapter is
|
|
115
|
+
* registered.
|
|
116
|
+
*
|
|
117
|
+
* Existence of this default is a deliberate maintainability call: the runtime
|
|
118
|
+
* is usable out-of-the-box without forcing every consumer to wire up sessions
|
|
119
|
+
* infrastructure they may not have.
|
|
120
|
+
*/
|
|
121
|
+
export declare class NoOpSessionsAdapter implements ISessionsAdapter {
|
|
122
|
+
readonly SessionLifecycle$: Observable<SessionLifecycleEvent>;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=ISessionsAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISessionsAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/ISessionsAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAS,UAAU,EAAE,MAAM,MAAM,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAC3B;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,GAC/F;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC;CACjE;AAED;;;;;;;;;GASG;AACH,qBAAa,mBAAoB,YAAW,gBAAgB;IACxD,SAAgB,iBAAiB,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAS;CAChF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Sessions adapter — boundary between the runtime and the host's
|
|
3
|
+
* realtime sessions infrastructure (PR #2787 — `MJ: AI Agent Sessions` + Channels).
|
|
4
|
+
*
|
|
5
|
+
* The runtime needs to surface session lifecycle events (a Voice / Realtime
|
|
6
|
+
* co-agent session started, a channel within it opened or closed, the session
|
|
7
|
+
* ended) without depending on any specific UI library or session implementation.
|
|
8
|
+
* Hosts implement this adapter to bridge their internal session source
|
|
9
|
+
* (Angular's `RealtimeSessionService` today; future server-bridged voice host,
|
|
10
|
+
* video-only host, etc.) into a single push stream the runtime exposes.
|
|
11
|
+
*
|
|
12
|
+
* Default (when no adapter is registered): {@link NoOpSessionsAdapter} emits
|
|
13
|
+
* nothing. Headless consumers still work — the
|
|
14
|
+
* {@link ../sessions/SessionsObserver.SessionsObserver} sub-component subscribes,
|
|
15
|
+
* sees no events, and the rest of the runtime is unaffected.
|
|
16
|
+
*
|
|
17
|
+
* **Multi-source-capable by design.** An adapter implementation can merge
|
|
18
|
+
* multiple internal services (voice + future video + future server-bridged
|
|
19
|
+
* realtime) into one observable. The runtime never sees the underlying services.
|
|
20
|
+
*
|
|
21
|
+
* **Scope cut — server-only events.** Server-side session closes (janitor
|
|
22
|
+
* sweep / shutdown) that happen while the user's tab is gone do NOT flow
|
|
23
|
+
* through this adapter today. Live-session orchestration only; admin/observability
|
|
24
|
+
* tooling polls the entity for those.
|
|
25
|
+
*
|
|
26
|
+
* @module @memberjunction/conversations-runtime
|
|
27
|
+
*/
|
|
28
|
+
import { EMPTY } from 'rxjs';
|
|
29
|
+
/**
|
|
30
|
+
* Default {@link ISessionsAdapter} for headless / non-Angular consumers. Emits
|
|
31
|
+
* nothing — the runtime's `SessionsObserver` still constructs and exposes its
|
|
32
|
+
* observable; subscribers just never receive events until a real adapter is
|
|
33
|
+
* registered.
|
|
34
|
+
*
|
|
35
|
+
* Existence of this default is a deliberate maintainability call: the runtime
|
|
36
|
+
* is usable out-of-the-box without forcing every consumer to wire up sessions
|
|
37
|
+
* infrastructure they may not have.
|
|
38
|
+
*/
|
|
39
|
+
export class NoOpSessionsAdapter {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.SessionLifecycle$ = EMPTY;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=ISessionsAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ISessionsAdapter.js","sourceRoot":"","sources":["../../src/adapters/ISessionsAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,KAAK,EAAc,MAAM,MAAM,CAAC;AA8EzC;;;;;;;;;GASG;AACH,MAAM,OAAO,mBAAmB;IAAhC;QACoB,sBAAiB,GAAsC,KAAK,CAAC;IACjF,CAAC;CAAA"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Pure-TypeScript agent-run pipeline for conversations.
|
|
3
|
+
*
|
|
4
|
+
* Ported from `@memberjunction/ng-conversations/src/lib/services/conversation-agent.service.ts`,
|
|
5
|
+
* scoped to the core `processMessage` flow. The Angular service's other helpers
|
|
6
|
+
* (intent checking, sub-agent invocation, artifact lookup, configuration-preset
|
|
7
|
+
* lookup) stay in the widget for now and can move in a follow-up — they aren't
|
|
8
|
+
* needed to invoke an agent end-to-end.
|
|
9
|
+
*
|
|
10
|
+
* Replaces three Angular bindings from the original:
|
|
11
|
+
* - `MJNotificationService.Instance.CreateSimpleNotification(...)` →
|
|
12
|
+
* {@link IConversationsRuntimeContext.Notification}.
|
|
13
|
+
* - `AgentClientService` (Angular wrapper over `AgentClientSession`) →
|
|
14
|
+
* `AgentClientSession` used directly (already pure-TS).
|
|
15
|
+
* - Hardcoded `Agents.find(a => a.Name === 'Sage')` → {@link DefaultAgentResolver}.
|
|
16
|
+
*
|
|
17
|
+
* @module @memberjunction/conversations-runtime
|
|
18
|
+
*/
|
|
19
|
+
import { Observable } from 'rxjs';
|
|
20
|
+
import { IMetadataProvider } from '@memberjunction/core';
|
|
21
|
+
import { ClientToolRegistry } from '@memberjunction/ai-agent-client';
|
|
22
|
+
import { AgentExecutionProgressCallback, ExecuteAgentResult } from '@memberjunction/ai-core-plus';
|
|
23
|
+
import { MJConversationDetailEntity } from '@memberjunction/core-entities';
|
|
24
|
+
import { IConversationsRuntimeContext } from '../context/IConversationsRuntimeContext.js';
|
|
25
|
+
import { DefaultAgentResolver } from '../default-agent/DefaultAgentResolver.js';
|
|
26
|
+
/**
|
|
27
|
+
* Inputs to {@link ConversationAgentRunner.processMessage}. Replaces the original
|
|
28
|
+
* service's positional parameter list with a typed struct so call sites don't
|
|
29
|
+
* silently break when fields are added or reordered.
|
|
30
|
+
*/
|
|
31
|
+
export interface ProcessMessageInput {
|
|
32
|
+
/** The conversation this message belongs to. */
|
|
33
|
+
conversationId: string;
|
|
34
|
+
/** The just-sent user message (used for `latestMessageId` plumbing). */
|
|
35
|
+
message: MJConversationDetailEntity;
|
|
36
|
+
/**
|
|
37
|
+
* The `MJ: Conversation Details` row that tracks this agent run on the
|
|
38
|
+
* server. Required for the optimized `RunAIAgentFromConversationDetail` path,
|
|
39
|
+
* which loads conversation history server-side.
|
|
40
|
+
*/
|
|
41
|
+
conversationDetailId: string;
|
|
42
|
+
/**
|
|
43
|
+
* Application context to inject into the agent's system prompt. Used by
|
|
44
|
+
* embedders (Form Builder cockpit, Component Studio AI Assistant, future LXP)
|
|
45
|
+
* to ground the agent in their UI state.
|
|
46
|
+
*/
|
|
47
|
+
appContext?: Record<string, unknown> | null;
|
|
48
|
+
/**
|
|
49
|
+
* Optional progress callback. Mirrors the original service's signature —
|
|
50
|
+
* embedders forward this through to the widget's progress UI.
|
|
51
|
+
*/
|
|
52
|
+
onProgress?: AgentExecutionProgressCallback;
|
|
53
|
+
/**
|
|
54
|
+
* Optional explicit agent ID. When set, wins over the {@link DefaultAgentResolver}
|
|
55
|
+
* chain. Mirrors the widget's `[DefaultAgentId]` input.
|
|
56
|
+
*/
|
|
57
|
+
explicitAgentId?: string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Application context for default-agent resolution. App-scoped Application
|
|
60
|
+
* Settings beat the global default.
|
|
61
|
+
*/
|
|
62
|
+
applicationId?: string | null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Core agent-run orchestrator. Wraps {@link AgentClientSession.RunAgentFromConversationDetail}
|
|
66
|
+
* with conversation-aware glue: default-agent resolution, permission-filtered
|
|
67
|
+
* candidate list for Sage's routing decisions, processing-state observable, and
|
|
68
|
+
* adapter-routed user notifications.
|
|
69
|
+
*
|
|
70
|
+
* Usually accessed via `ConversationsRuntime.Instance.AgentRunner`.
|
|
71
|
+
*/
|
|
72
|
+
export declare class ConversationAgentRunner {
|
|
73
|
+
private readonly context;
|
|
74
|
+
private readonly resolver;
|
|
75
|
+
private readonly session;
|
|
76
|
+
private readonly _isProcessing$;
|
|
77
|
+
private _provider;
|
|
78
|
+
/** Emits `true` while an agent run is in flight, `false` otherwise. */
|
|
79
|
+
readonly isProcessing$: Observable<boolean>;
|
|
80
|
+
/**
|
|
81
|
+
* @param context Runtime context — used for notifications. Read on each call
|
|
82
|
+
* so adapter swaps after construction are picked up immediately.
|
|
83
|
+
* @param toolRegistry Shared `ClientToolRegistry` — the runner's internal
|
|
84
|
+
* `AgentClientSession` uses this so tools registered on
|
|
85
|
+
* `ConversationsRuntime.Tools` are visible to the agent.
|
|
86
|
+
* @param resolver The runtime's `DefaultAgentResolver` — used to pick the
|
|
87
|
+
* conversation manager agent when no explicit ID is supplied.
|
|
88
|
+
*/
|
|
89
|
+
constructor(context: IConversationsRuntimeContext, toolRegistry: ClientToolRegistry, resolver: DefaultAgentResolver);
|
|
90
|
+
/**
|
|
91
|
+
* Metadata provider — falls back to `Metadata.Provider` when unset. Setting
|
|
92
|
+
* this forwards the provider to the internal `AgentClientSession` so GraphQL
|
|
93
|
+
* calls target the right server in multi-provider scenarios.
|
|
94
|
+
*/
|
|
95
|
+
get Provider(): IMetadataProvider;
|
|
96
|
+
set Provider(value: IMetadataProvider | null);
|
|
97
|
+
/**
|
|
98
|
+
* Process a user message through the default conversation manager agent. Mirrors
|
|
99
|
+
* the original service's `processMessage(...)` flow, but with the three Angular
|
|
100
|
+
* deps replaced (notification adapter, default-agent resolver, direct
|
|
101
|
+
* `AgentClientSession`).
|
|
102
|
+
*
|
|
103
|
+
* @returns The agent's `ExecuteAgentResult`, or `null` if the agent failed and
|
|
104
|
+
* a notification was surfaced.
|
|
105
|
+
*/
|
|
106
|
+
processMessage(input: ProcessMessageInput): Promise<ExecuteAgentResult | null>;
|
|
107
|
+
/**
|
|
108
|
+
* Resolve the agent that should handle this turn — explicit ID wins, then the
|
|
109
|
+
* Application Settings chain, then the Sage code-const fallback. Surfaces a
|
|
110
|
+
* notification on failure rather than throwing, so the caller (UI thread)
|
|
111
|
+
* sees a friendly message.
|
|
112
|
+
*/
|
|
113
|
+
private resolveAgent;
|
|
114
|
+
/**
|
|
115
|
+
* Filter agents by the user's `run` permission. Identical to the original
|
|
116
|
+
* service's helper — fails closed on per-agent error so we never expose an
|
|
117
|
+
* agent the user shouldn't see.
|
|
118
|
+
*/
|
|
119
|
+
private filterAgentsByPermissions;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=ConversationAgentRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConversationAgentRunner.d.ts","sourceRoot":"","sources":["../../src/agent-runner/ConversationAgentRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAmB,UAAU,EAAE,MAAM,MAAM,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAsB,MAAM,sBAAsB,CAAC;AAE7E,OAAO,EAEH,kBAAkB,EAErB,MAAM,iCAAiC,CAAC;AAKzC,OAAO,EACH,8BAA8B,EAC9B,kBAAkB,EAErB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AACvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAE7E;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAChC,gDAAgD;IAChD,cAAc,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,OAAO,EAAE,0BAA0B,CAAC;IACpC;;;;OAIG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5C;;;OAGG;IACH,UAAU,CAAC,EAAE,8BAA8B,CAAC;IAC5C;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,qBAAa,uBAAuB;IAkB5B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAnB7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuC;IACtE,OAAO,CAAC,SAAS,CAAkC;IAEnD,uEAAuE;IACvE,SAAgB,aAAa,EAAE,UAAU,CAAC,OAAO,CAAC,CAAsC;IAExF;;;;;;;;OAQG;gBAEkB,OAAO,EAAE,4BAA4B,EACtD,YAAY,EAAE,kBAAkB,EACf,QAAQ,EAAE,oBAAoB;IAKnD;;;;OAIG;IACH,IAAW,QAAQ,IAAI,iBAAiB,CAEvC;IACD,IAAW,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,EAGlD;IAED;;;;;;;;OAQG;IACU,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAgG3F;;;;;OAKG;YACW,YAAY;IAkB1B;;;;OAIG;YACW,yBAAyB;CAyB1C"}
|