@memberjunction/ai-agents 5.41.0 → 5.42.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 +8 -0
- package/dist/base-agent.d.ts +57 -51
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +227 -187
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/memory-manager-agent.d.ts +44 -2
- package/dist/memory-manager-agent.d.ts.map +1 -1
- package/dist/memory-manager-agent.js +133 -100
- package/dist/memory-manager-agent.js.map +1 -1
- package/dist/realtime/bridge-realtime-session-factory.d.ts +111 -0
- package/dist/realtime/bridge-realtime-session-factory.d.ts.map +1 -0
- package/dist/realtime/bridge-realtime-session-factory.js +163 -0
- package/dist/realtime/bridge-realtime-session-factory.js.map +1 -0
- package/dist/realtime/bridge-room-transcript-sink.d.ts +58 -0
- package/dist/realtime/bridge-room-transcript-sink.d.ts.map +1 -0
- package/dist/realtime/bridge-room-transcript-sink.js +127 -0
- package/dist/realtime/bridge-room-transcript-sink.js.map +1 -0
- package/dist/realtime/realtime-client-session-service.d.ts +148 -6
- package/dist/realtime/realtime-client-session-service.d.ts.map +1 -1
- package/dist/realtime/realtime-client-session-service.js +241 -35
- package/dist/realtime/realtime-client-session-service.js.map +1 -1
- package/dist/realtime/realtime-coagent-config.d.ts +63 -7
- package/dist/realtime/realtime-coagent-config.d.ts.map +1 -1
- package/dist/realtime/realtime-coagent-config.js +82 -8
- package/dist/realtime/realtime-coagent-config.js.map +1 -1
- package/dist/realtime/realtime-tool-broker.d.ts +15 -0
- package/dist/realtime/realtime-tool-broker.d.ts.map +1 -1
- package/dist/realtime/realtime-tool-broker.js +22 -0
- package/dist/realtime/realtime-tool-broker.js.map +1 -1
- package/package.json +17 -17
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `CreateBridgeRealtimeSession` — the **provider-agnostic** server-side factory that turns an
|
|
3
|
+
* agent reference into a live {@link IRealtimeSession} for a Realtime Bridge. Given an agent id (or name)
|
|
4
|
+
* + a context user + a metadata provider, it:
|
|
5
|
+
* 1. resolves the `MJ: AI Agents` entity from the {@link AIEngine} cache,
|
|
6
|
+
* 2. instantiates the correct {@link BaseAgent} subclass via the `ClassFactory` (the same path
|
|
7
|
+
* `AgentRunner` uses), and
|
|
8
|
+
* 3. calls {@link BaseAgent.StartBridgeRealtimeSession} to open the raw model session.
|
|
9
|
+
*
|
|
10
|
+
* This is the seam every bridge needs — `LiveKitAgentRoomCoordinator.SetSessionFactory`, and the
|
|
11
|
+
* (forthcoming) Teams/Zoom harnesses, all bind THIS one function. It deliberately lives in
|
|
12
|
+
* `@memberjunction/ai-agents` (which owns the agent + realtime-model lifecycle) and depends on NO bridge
|
|
13
|
+
* package, so a bridge package never has to reach back into the agent runtime — the consumer binds the
|
|
14
|
+
* factory at startup instead.
|
|
15
|
+
*
|
|
16
|
+
* @module @memberjunction/ai-agents
|
|
17
|
+
* @author MemberJunction.com
|
|
18
|
+
*/
|
|
19
|
+
import { BaseRealtimeModel, GetAIAPIKey } from '@memberjunction/ai';
|
|
20
|
+
import { Metadata } from '@memberjunction/core';
|
|
21
|
+
import { MJGlobal, UUIDsEqual } from '@memberjunction/global';
|
|
22
|
+
import { AIEngine } from '@memberjunction/aiengine';
|
|
23
|
+
import { BaseAgent } from '../base-agent.js';
|
|
24
|
+
import { RealtimeClientSessionService } from './realtime-client-session-service.js';
|
|
25
|
+
/**
|
|
26
|
+
* Opens a raw {@link IRealtimeSession} for the agent named in `ctx`. Bind this onto a bridge's
|
|
27
|
+
* session-factory seam (e.g. `LiveKitAgentRoomCoordinator.Instance.SetSessionFactory(CreateBridgeRealtimeSession)`).
|
|
28
|
+
*
|
|
29
|
+
* @param ctx The bridge session context (agent id/name + user + provider).
|
|
30
|
+
* @returns The live realtime session to hand to `AIBridgeEngine.StartBridgeSession`.
|
|
31
|
+
* @throws When the agent can't be resolved, has no DriverClass, the driver can't be instantiated, or no
|
|
32
|
+
* usable Realtime model is configured (surfaced from {@link BaseAgent.StartBridgeRealtimeSession}).
|
|
33
|
+
*/
|
|
34
|
+
export async function CreateBridgeRealtimeSession(ctx) {
|
|
35
|
+
const provider = ctx.MetadataProvider ?? Metadata.Provider;
|
|
36
|
+
await AIEngine.Instance.Config(false, ctx.ContextUser, provider);
|
|
37
|
+
const agent = resolveAgentEntity(ctx);
|
|
38
|
+
if (!agent) {
|
|
39
|
+
throw new Error(`CreateBridgeRealtimeSession: no agent found for AgentID='${ctx.AgentID ?? ''}' / ` +
|
|
40
|
+
`AgentName='${ctx.AgentName ?? ''}'. Ensure the agent exists and the engine is configured.`);
|
|
41
|
+
}
|
|
42
|
+
// Instantiate the right BaseAgent subclass exactly as AgentRunner does (agent DriverClass, else its type's).
|
|
43
|
+
const agentType = AIEngine.Instance.AgentTypes.find((t) => UUIDsEqual(t.ID, agent.TypeID));
|
|
44
|
+
const driverClass = agent.DriverClass || agentType?.DriverClass;
|
|
45
|
+
if (!driverClass) {
|
|
46
|
+
throw new Error(`CreateBridgeRealtimeSession: agent '${agent.Name}' has no DriverClass (and its type none either).`);
|
|
47
|
+
}
|
|
48
|
+
const instance = MJGlobal.Instance.ClassFactory.CreateInstance(BaseAgent, driverClass);
|
|
49
|
+
if (!instance) {
|
|
50
|
+
throw new Error(`CreateBridgeRealtimeSession: ClassFactory could not create a BaseAgent for DriverClass '${driverClass}'.`);
|
|
51
|
+
}
|
|
52
|
+
return instance.StartBridgeRealtimeSession({
|
|
53
|
+
agent,
|
|
54
|
+
contextUser: ctx.ContextUser,
|
|
55
|
+
provider,
|
|
56
|
+
// A fresh bridge session starts with no prior turns; memory context degrades gracefully to empty.
|
|
57
|
+
conversationMessages: [],
|
|
58
|
+
// Realtime extras ride params.data: the TARGET agent the co-agent voices via `invoke-target-agent`
|
|
59
|
+
// (without it the co-agent stays idle), plus optional per-session dev overrides for the model/voice
|
|
60
|
+
// so two agents in the same room can sound distinct. Omitted keys are simply absent.
|
|
61
|
+
data: buildRealtimeData(ctx),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Builds the `params.data` bag from the bridge context — the realtime extras BaseAgent reads at session
|
|
66
|
+
* start. Returns `undefined` when nothing is set so the param stays cleanly absent.
|
|
67
|
+
*/
|
|
68
|
+
function buildRealtimeData(ctx) {
|
|
69
|
+
const data = {};
|
|
70
|
+
if (ctx.TargetAgentID) {
|
|
71
|
+
data.targetAgentID = ctx.TargetAgentID;
|
|
72
|
+
}
|
|
73
|
+
if (ctx.AgentSessionID && ctx.AgentSessionID.trim().length > 0) {
|
|
74
|
+
// Drives the co-agent observability run's session grouping (see WireBridgeRealtimeSession).
|
|
75
|
+
data.agentSessionId = ctx.AgentSessionID.trim();
|
|
76
|
+
}
|
|
77
|
+
if (ctx.RealtimeModelID && ctx.RealtimeModelID.trim().length > 0) {
|
|
78
|
+
data.realtimeModelID = ctx.RealtimeModelID.trim();
|
|
79
|
+
}
|
|
80
|
+
if (ctx.RealtimeVoice && ctx.RealtimeVoice.trim().length > 0) {
|
|
81
|
+
data.realtimeVoice = ctx.RealtimeVoice.trim();
|
|
82
|
+
}
|
|
83
|
+
if (ctx.MeetingMode === true) {
|
|
84
|
+
data.realtimeMeetingMode = true;
|
|
85
|
+
}
|
|
86
|
+
if (ctx.SelfNames && ctx.SelfNames.length > 0) {
|
|
87
|
+
data.realtimeSelfNames = ctx.SelfNames;
|
|
88
|
+
}
|
|
89
|
+
return Object.keys(data).length > 0 ? data : undefined;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The bridge-engine session-run finalizer (matches `BridgeSessionRunFinalizer` in
|
|
93
|
+
* `@memberjunction/ai-bridge-server`). Bind this onto `AIBridgeEngine.SetSessionRunFinalizer(...)` at
|
|
94
|
+
* startup so a bridge reaped WITHOUT a live session (a prior-boot orphan, a cross-host teardown) still
|
|
95
|
+
* finalizes its co-agent observability run — the only path where the `Close()`-wrapped finalizer can't run.
|
|
96
|
+
* Lives here (in ai-agents, which owns the realtime runtime) so the engine stays decoupled from it.
|
|
97
|
+
*
|
|
98
|
+
* @param agentSessionID The reaped session's id.
|
|
99
|
+
* @param success Whether to mark the run(s) `Completed` (true) or `Failed` (false).
|
|
100
|
+
* @param contextUser The user the writes run as (required — skipped without it).
|
|
101
|
+
* @param provider The metadata provider (required — skipped without it).
|
|
102
|
+
*/
|
|
103
|
+
export async function FinalizeBridgeCoAgentRuns(agentSessionID, success, contextUser, provider) {
|
|
104
|
+
if (!contextUser || !provider) {
|
|
105
|
+
return; // a server-side finalize needs a user + provider; a later reap with context catches it
|
|
106
|
+
}
|
|
107
|
+
await new RealtimeClientSessionService().FinalizeCoAgentRunsBySession(agentSessionID, success, contextUser, provider);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Enumerates the active Realtime models with each driver's supported voices — the source for the dev
|
|
111
|
+
* model/voice picker. Only models with an Active vendor + resolvable API key + ClassFactory driver are
|
|
112
|
+
* returned (a model you can't actually run isn't worth offering). Voices come from the driver
|
|
113
|
+
* ({@link BaseRealtimeModel.SupportedVoices}) — the near-term, driver-owned source of truth.
|
|
114
|
+
*
|
|
115
|
+
* @param contextUser The user the engine config runs as (server-side).
|
|
116
|
+
* @param provider The request-scoped metadata provider (multi-provider safe).
|
|
117
|
+
* @returns Active realtime models, each with its driver's voices.
|
|
118
|
+
*/
|
|
119
|
+
export async function GetRealtimeModelVoices(contextUser, provider) {
|
|
120
|
+
await AIEngine.Instance.Config(false, contextUser, provider);
|
|
121
|
+
const isRealtime = (t) => typeof t === 'string' && t.trim().toLowerCase() === 'realtime';
|
|
122
|
+
const models = AIEngine.Instance.Models
|
|
123
|
+
.filter((m) => m.IsActive && isRealtime(m.AIModelType))
|
|
124
|
+
.sort((a, b) => (b.PowerRank ?? 0) - (a.PowerRank ?? 0));
|
|
125
|
+
const out = [];
|
|
126
|
+
for (const model of models) {
|
|
127
|
+
const driverClass = resolveRealtimeDriverClass(model.ID);
|
|
128
|
+
if (!driverClass) {
|
|
129
|
+
continue; // no active vendor with a resolvable key — not runnable, so omit
|
|
130
|
+
}
|
|
131
|
+
const instance = MJGlobal.Instance.ClassFactory.CreateInstance(BaseRealtimeModel, driverClass, GetAIAPIKey(driverClass));
|
|
132
|
+
out.push({ ModelID: model.ID, ModelName: model.Name ?? '', Voices: instance?.SupportedVoices ?? [] });
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
/** The DriverClass of the highest-priority Active vendor (with a resolvable API key) for a model, or null. */
|
|
137
|
+
function resolveRealtimeDriverClass(modelID) {
|
|
138
|
+
const vendors = AIEngine.Instance.ModelVendors
|
|
139
|
+
.filter((mv) => UUIDsEqual(mv.ModelID, modelID) && mv.Status === 'Active' && mv.DriverClass != null)
|
|
140
|
+
.sort((a, b) => (b.Priority ?? 0) - (a.Priority ?? 0));
|
|
141
|
+
for (const v of vendors) {
|
|
142
|
+
if (GetAIAPIKey(v.DriverClass)) {
|
|
143
|
+
return v.DriverClass;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
/** Resolves the agent entity from the engine cache by id (preferred), then by case-insensitive name. */
|
|
149
|
+
function resolveAgentEntity(ctx) {
|
|
150
|
+
const agents = AIEngine.Instance.Agents;
|
|
151
|
+
if (ctx.AgentID) {
|
|
152
|
+
const byId = agents.find((a) => UUIDsEqual(a.ID, ctx.AgentID));
|
|
153
|
+
if (byId) {
|
|
154
|
+
return byId;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (ctx.AgentName) {
|
|
158
|
+
const wanted = ctx.AgentName.trim().toLowerCase();
|
|
159
|
+
return agents.find((a) => a.Name?.trim().toLowerCase() === wanted);
|
|
160
|
+
}
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=bridge-realtime-session-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-realtime-session-factory.js","sourceRoot":"","sources":["../../src/realtime/bridge-realtime-session-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `CreateBridgeRoomTranscriptSink` — the app-layer implementation of the bridge engine's
|
|
3
|
+
* transcript sink. Persists a **unified per-room meeting transcript** into `MJ: Conversations` (one
|
|
4
|
+
* "Meeting Room" conversation per LiveKit room, keyed by the room's external id) + `MJ: Conversation Details`
|
|
5
|
+
* (one row per final utterance). The bridge engine elects ONE scribe per room and feeds its final transcript
|
|
6
|
+
* lines here, so the room records a single copy — not N (one per agent).
|
|
7
|
+
*
|
|
8
|
+
* Lives in `@memberjunction/ai-agents` (which owns the realtime/Conversations knowledge), NOT the bridge
|
|
9
|
+
* engine — the engine only emits neutral lines + the `(ConversationType, ApplicationScope, ...)` choices come
|
|
10
|
+
* from the binding site (the MJServer resolver), so nothing about "Meeting Room" or app scoping leaks into
|
|
11
|
+
* the generic engine. See `plans/realtime/realtime-session-lifecycle-and-followups.md` §5.
|
|
12
|
+
*
|
|
13
|
+
* @module @memberjunction/ai-agents
|
|
14
|
+
* @author MemberJunction.com
|
|
15
|
+
*/
|
|
16
|
+
import { IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
17
|
+
/** The conversation `ApplicationScope` values (mirrors the entity union). `'Application'` hides it from the main chat list. */
|
|
18
|
+
export type ConversationApplicationScope = 'Global' | 'Both' | 'Application';
|
|
19
|
+
/** Options that shape the room conversation — supplied by the binding site so the engine stays generic. */
|
|
20
|
+
export interface BridgeRoomTranscriptSinkOptions {
|
|
21
|
+
/** The `MJ: Conversations.Type` to stamp (e.g. `'Meeting Room'`) — the semantic label for room transcripts. */
|
|
22
|
+
ConversationType: string;
|
|
23
|
+
/** Scope of the room conversation. `'Application'` keeps it OUT of the normal chat list. Default `'Application'`. */
|
|
24
|
+
ApplicationScope?: ConversationApplicationScope;
|
|
25
|
+
/** Optional owning application id (e.g. the Meet app) so its surface can list its rooms. */
|
|
26
|
+
ApplicationID?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* One transcript line the engine emits (structurally matches `BridgeTranscriptLine` in
|
|
30
|
+
* `@memberjunction/ai-bridge-server`; mirrored here to avoid a package dependency, resolved structurally at
|
|
31
|
+
* the resolver binding site).
|
|
32
|
+
*/
|
|
33
|
+
export interface BridgeTranscriptLineInput {
|
|
34
|
+
/** The room grouping (driver external connection id) — one room = one unified transcript. */
|
|
35
|
+
RoomKey: string;
|
|
36
|
+
/** The scribe's agent-session id (attribution for its own speech). */
|
|
37
|
+
AgentSessionID: string;
|
|
38
|
+
/** The scribe's agent id, when known. */
|
|
39
|
+
AgentID?: string;
|
|
40
|
+
/** `true` for the scribe's OWN speech, `false` for anything it heard. */
|
|
41
|
+
IsAgentSpeech: boolean;
|
|
42
|
+
/** The speaker's participant id (the scribe's own bot id for its speech; absent for heard speech). */
|
|
43
|
+
SpeakerParticipantID?: string;
|
|
44
|
+
/** The final transcript text. */
|
|
45
|
+
Text: string;
|
|
46
|
+
}
|
|
47
|
+
/** The sink signature (matches the engine's `BridgeTranscriptSink`). */
|
|
48
|
+
export type BridgeRoomTranscriptSink = (line: BridgeTranscriptLineInput, contextUser?: UserInfo, provider?: IMetadataProvider) => Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Builds a {@link BridgeRoomTranscriptSink}. Bind the result onto `AIBridgeEngine.SetTranscriptSink(...)` at
|
|
51
|
+
* startup. Internally caches the room→conversation mapping (lazy get-or-create), dedupes concurrent creates
|
|
52
|
+
* per room, and serializes detail writes per conversation so transcript order is preserved.
|
|
53
|
+
*
|
|
54
|
+
* @param options The room-conversation shape (`Type`, scope, optional app id).
|
|
55
|
+
* @returns The sink function.
|
|
56
|
+
*/
|
|
57
|
+
export declare function CreateBridgeRoomTranscriptSink(options: BridgeRoomTranscriptSinkOptions): BridgeRoomTranscriptSink;
|
|
58
|
+
//# sourceMappingURL=bridge-room-transcript-sink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-room-transcript-sink.d.ts","sourceRoot":"","sources":["../../src/realtime/bridge-room-transcript-sink.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAgC,MAAM,sBAAsB,CAAC;AAGjG,+HAA+H;AAC/H,MAAM,MAAM,4BAA4B,GAAG,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;AAE7E,2GAA2G;AAC3G,MAAM,WAAW,+BAA+B;IAC5C,+GAA+G;IAC/G,gBAAgB,EAAE,MAAM,CAAC;IACzB,qHAAqH;IACrH,gBAAgB,CAAC,EAAE,4BAA4B,CAAC;IAChD,4FAA4F;IAC5F,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACtC,6FAA6F;IAC7F,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,aAAa,EAAE,OAAO,CAAC;IACvB,sGAAsG;IACtG,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,wEAAwE;AACxE,MAAM,MAAM,wBAAwB,GAAG,CACnC,IAAI,EAAE,yBAAyB,EAC/B,WAAW,CAAC,EAAE,QAAQ,EACtB,QAAQ,CAAC,EAAE,iBAAiB,KAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;AAKnB;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,+BAA+B,GAAG,wBAAwB,CAsBjH"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `CreateBridgeRoomTranscriptSink` — the app-layer implementation of the bridge engine's
|
|
3
|
+
* transcript sink. Persists a **unified per-room meeting transcript** into `MJ: Conversations` (one
|
|
4
|
+
* "Meeting Room" conversation per LiveKit room, keyed by the room's external id) + `MJ: Conversation Details`
|
|
5
|
+
* (one row per final utterance). The bridge engine elects ONE scribe per room and feeds its final transcript
|
|
6
|
+
* lines here, so the room records a single copy — not N (one per agent).
|
|
7
|
+
*
|
|
8
|
+
* Lives in `@memberjunction/ai-agents` (which owns the realtime/Conversations knowledge), NOT the bridge
|
|
9
|
+
* engine — the engine only emits neutral lines + the `(ConversationType, ApplicationScope, ...)` choices come
|
|
10
|
+
* from the binding site (the MJServer resolver), so nothing about "Meeting Room" or app scoping leaks into
|
|
11
|
+
* the generic engine. See `plans/realtime/realtime-session-lifecycle-and-followups.md` §5.
|
|
12
|
+
*
|
|
13
|
+
* @module @memberjunction/ai-agents
|
|
14
|
+
* @author MemberJunction.com
|
|
15
|
+
*/
|
|
16
|
+
import { RunView, LogError, LogStatus } from '@memberjunction/core';
|
|
17
|
+
const CONVERSATION_ENTITY = 'MJ: Conversations';
|
|
18
|
+
const CONVERSATION_DETAIL_ENTITY = 'MJ: Conversation Details';
|
|
19
|
+
/**
|
|
20
|
+
* Builds a {@link BridgeRoomTranscriptSink}. Bind the result onto `AIBridgeEngine.SetTranscriptSink(...)` at
|
|
21
|
+
* startup. Internally caches the room→conversation mapping (lazy get-or-create), dedupes concurrent creates
|
|
22
|
+
* per room, and serializes detail writes per conversation so transcript order is preserved.
|
|
23
|
+
*
|
|
24
|
+
* @param options The room-conversation shape (`Type`, scope, optional app id).
|
|
25
|
+
* @returns The sink function.
|
|
26
|
+
*/
|
|
27
|
+
export function CreateBridgeRoomTranscriptSink(options) {
|
|
28
|
+
const scope = options.ApplicationScope ?? 'Application';
|
|
29
|
+
/** roomKey(lower) → resolved ConversationID (populated once get-or-create settles). */
|
|
30
|
+
const roomToConversation = new Map();
|
|
31
|
+
/** roomKey(lower) → in-flight get-or-create promise (dedupes concurrent first lines for a room). */
|
|
32
|
+
const ensureInFlight = new Map();
|
|
33
|
+
/** ConversationID → serial write chain (preserves detail ordering, error-isolated). */
|
|
34
|
+
const writeChains = new Map();
|
|
35
|
+
return async (line, contextUser, provider) => {
|
|
36
|
+
if (!contextUser || !provider) {
|
|
37
|
+
return; // a server-side write needs a user + provider; nothing to do without them
|
|
38
|
+
}
|
|
39
|
+
const conversationID = await ensureRoomConversation(line.RoomKey, options.ConversationType, scope, options.ApplicationID, roomToConversation, ensureInFlight, contextUser, provider);
|
|
40
|
+
if (!conversationID) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const prior = writeChains.get(conversationID) ?? Promise.resolve();
|
|
44
|
+
const next = prior.then(() => writeTranscriptDetail(conversationID, line, contextUser, provider));
|
|
45
|
+
writeChains.set(conversationID, next.then(() => undefined, () => undefined));
|
|
46
|
+
await next;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** Resolves (cache → existing row → create) the room's `MJ: Conversations` id, deduping concurrent creates. */
|
|
50
|
+
async function ensureRoomConversation(roomKey, conversationType, scope, applicationID, cache, inFlight, contextUser, provider) {
|
|
51
|
+
const key = roomKey.trim().toLowerCase();
|
|
52
|
+
const cached = cache.get(key);
|
|
53
|
+
if (cached) {
|
|
54
|
+
return cached;
|
|
55
|
+
}
|
|
56
|
+
const pending = inFlight.get(key);
|
|
57
|
+
if (pending) {
|
|
58
|
+
return pending;
|
|
59
|
+
}
|
|
60
|
+
const task = resolveOrCreateConversation(roomKey, conversationType, scope, applicationID, contextUser, provider)
|
|
61
|
+
.then((id) => {
|
|
62
|
+
if (id) {
|
|
63
|
+
cache.set(key, id);
|
|
64
|
+
}
|
|
65
|
+
return id;
|
|
66
|
+
})
|
|
67
|
+
.finally(() => inFlight.delete(key));
|
|
68
|
+
inFlight.set(key, task);
|
|
69
|
+
return task;
|
|
70
|
+
}
|
|
71
|
+
/** Finds an existing non-archived room conversation by `ExternalID` + `Type`, else creates one. */
|
|
72
|
+
async function resolveOrCreateConversation(roomKey, conversationType, scope, applicationID, contextUser, provider) {
|
|
73
|
+
const rv = new RunView();
|
|
74
|
+
const found = await rv.RunView({
|
|
75
|
+
EntityName: CONVERSATION_ENTITY,
|
|
76
|
+
ExtraFilter: `ExternalID='${escapeSql(roomKey)}' AND Type='${escapeSql(conversationType)}' AND (IsArchived IS NULL OR IsArchived=0)`,
|
|
77
|
+
Fields: ['ID'],
|
|
78
|
+
OrderBy: '__mj_CreatedAt DESC',
|
|
79
|
+
MaxRows: 1,
|
|
80
|
+
ResultType: 'simple',
|
|
81
|
+
}, contextUser);
|
|
82
|
+
if (found.Success && found.Results.length > 0) {
|
|
83
|
+
return found.Results[0].ID;
|
|
84
|
+
}
|
|
85
|
+
const conversation = await provider.GetEntityObject(CONVERSATION_ENTITY, contextUser);
|
|
86
|
+
conversation.NewRecord();
|
|
87
|
+
conversation.UserID = contextUser.ID;
|
|
88
|
+
conversation.Name = `Meeting Room ${roomKey}`;
|
|
89
|
+
conversation.Type = conversationType;
|
|
90
|
+
conversation.ExternalID = roomKey;
|
|
91
|
+
conversation.ApplicationScope = scope;
|
|
92
|
+
if (applicationID) {
|
|
93
|
+
conversation.ApplicationID = applicationID;
|
|
94
|
+
}
|
|
95
|
+
if (await conversation.Save()) {
|
|
96
|
+
LogStatus(`CreateBridgeRoomTranscriptSink: created '${conversationType}' conversation ${conversation.ID} for room ${roomKey}.`);
|
|
97
|
+
return conversation.ID;
|
|
98
|
+
}
|
|
99
|
+
LogError(`CreateBridgeRoomTranscriptSink: failed to create room conversation: ${conversation.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
/** Writes one `MJ: Conversation Details` row for a transcript line (Role mapped; agent speech attributed). */
|
|
103
|
+
async function writeTranscriptDetail(conversationID, line, contextUser, provider) {
|
|
104
|
+
const detail = await provider.GetEntityObject(CONVERSATION_DETAIL_ENTITY, contextUser);
|
|
105
|
+
detail.NewRecord();
|
|
106
|
+
detail.ConversationID = conversationID;
|
|
107
|
+
// The scribe's own speech is the agent ('AI'); everything it heard (humans + other agents) is 'User'.
|
|
108
|
+
detail.Role = line.IsAgentSpeech ? 'AI' : 'User';
|
|
109
|
+
detail.Message = line.Text;
|
|
110
|
+
if (line.SpeakerParticipantID) {
|
|
111
|
+
detail.ExternalID = line.SpeakerParticipantID;
|
|
112
|
+
}
|
|
113
|
+
if (line.IsAgentSpeech) {
|
|
114
|
+
detail.AgentSessionID = line.AgentSessionID;
|
|
115
|
+
if (line.AgentID) {
|
|
116
|
+
detail.AgentID = line.AgentID;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (!(await detail.Save())) {
|
|
120
|
+
LogError(`CreateBridgeRoomTranscriptSink: failed to write transcript detail: ${detail.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Escapes single quotes for safe embedding in an `ExtraFilter` literal. */
|
|
124
|
+
function escapeSql(value) {
|
|
125
|
+
return value.replace(/'/g, "''");
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=bridge-room-transcript-sink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-room-transcript-sink.js","sourceRoot":"","sources":["../../src/realtime/bridge-room-transcript-sink.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* @author MemberJunction.com
|
|
31
31
|
*/
|
|
32
32
|
import { UserInfo, IMetadataProvider } from '@memberjunction/core';
|
|
33
|
-
import { BaseRealtimeModel, ChatMessage, ClientRealtimeSessionConfig, JSONObject, RealtimeSessionParams, RealtimeToolCall, RealtimeToolDefinition } from '@memberjunction/ai';
|
|
33
|
+
import { BaseRealtimeModel, ChatMessage, ClientRealtimeSessionConfig, IRealtimeSession, JSONObject, RealtimeSessionParams, RealtimeToolCall, RealtimeToolDefinition } from '@memberjunction/ai';
|
|
34
34
|
import { MJAIAgentEntityExtended, MJAIModelEntityExtended, MJAIAgentRunEntityExtended, AgentExecutionProgressCallback, ExecuteAgentResult } from '@memberjunction/ai-core-plus';
|
|
35
35
|
import { RealtimeToolBroker, DelegateToTargetRequest, DelegatedResult, DelegatedRunArtifact, ToolExecutionResult } from './realtime-tool-broker.js';
|
|
36
36
|
import { RealtimeCoAgentConfig } from './realtime-coagent-config.js';
|
|
@@ -88,6 +88,22 @@ export interface PrepareClientSessionInput {
|
|
|
88
88
|
* trusts the input. Malformed JSON is tolerated (it simply contributes nothing to the merge).
|
|
89
89
|
*/
|
|
90
90
|
ConfigOverridesJson?: string;
|
|
91
|
+
/**
|
|
92
|
+
* **Multi-agent meeting mode.** When `true`, the agent joins as one of several voices in a shared
|
|
93
|
+
* room: its model's **blind auto-response is disabled** (the session Config carries
|
|
94
|
+
* `disableAutoResponse`, which providers translate to e.g. OpenAI `turn_detection.create_response=false`)
|
|
95
|
+
* and a meeting-aware clause is added to the prompt so it **hears everything but speaks only when
|
|
96
|
+
* addressed**. The bridge becomes the sole speech trigger (gated by its turn policy). Absent/`false`
|
|
97
|
+
* = a 1:1 call with the model's normal auto-response. See
|
|
98
|
+
* `plans/realtime/multi-agent-meeting-turn-taking.md`.
|
|
99
|
+
*/
|
|
100
|
+
DisableAutoResponse?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* The names the meeting-aware prompt tells the agent it answers to (its own display name + aliases).
|
|
103
|
+
* Used ONLY to phrase the "you are addressed when someone says one of these" guidance; the actual
|
|
104
|
+
* addressing GATE is the bridge's `RegexAddressedMatcher`. Ignored unless {@link DisableAutoResponse}.
|
|
105
|
+
*/
|
|
106
|
+
SelfNames?: string[];
|
|
91
107
|
}
|
|
92
108
|
/**
|
|
93
109
|
* Result of {@link RealtimeClientSessionService.PrepareClientSession}.
|
|
@@ -221,6 +237,41 @@ export interface RealtimeModelResolution {
|
|
|
221
237
|
*/
|
|
222
238
|
DriverClass?: string;
|
|
223
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Output of {@link RealtimeClientSessionService.PrepareRealtimeSessionParams} — the host-agnostic prep that
|
|
242
|
+
* every realtime surface consumes before opening a session its own way. Carries the assembled
|
|
243
|
+
* {@link RealtimeSessionParams} plus the resolved co-agent / model / effective config the openers need.
|
|
244
|
+
*/
|
|
245
|
+
export interface RealtimeSessionParamsPrep {
|
|
246
|
+
/** Whether prep succeeded. When false, only {@link ErrorMessage} is set. */
|
|
247
|
+
Success: boolean;
|
|
248
|
+
/** Failure reason (present only when {@link Success} is false). */
|
|
249
|
+
ErrorMessage?: string;
|
|
250
|
+
/** The resolved co-agent (the Realtime-type agent that does the voicing). */
|
|
251
|
+
CoAgent?: MJAIAgentEntityExtended;
|
|
252
|
+
/** The resolved realtime model + identifiers. */
|
|
253
|
+
Resolution?: RealtimeModelResolution;
|
|
254
|
+
/** The effective config from the full precedence cascade (type-default < co-agent < target < override). */
|
|
255
|
+
EffectiveConfig?: RealtimeCoAgentConfig;
|
|
256
|
+
/** The assembled session params (TARGET-identity prompt, stable tools incl. invoke-target, voice, memory). */
|
|
257
|
+
SessionParams?: RealtimeSessionParams;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* The runtime handle returned by {@link RealtimeClientSessionService.WireBridgeRealtimeSession} — the
|
|
261
|
+
* server long-lived (bridged) counterpart to what `PrepareClientSession` returns for the browser. The
|
|
262
|
+
* bridge holds this for the life of the session: the observability run ids (for nesting + correlation)
|
|
263
|
+
* and an **idempotent** {@link Finalize} the bridge MUST call on teardown so the co-agent run + prompt
|
|
264
|
+
* run don't dangle in `Running`. Finalize also runs automatically when the session's `Close()` is invoked
|
|
265
|
+
* or the connection drops — calling it again is a safe no-op.
|
|
266
|
+
*/
|
|
267
|
+
export interface BridgeRealtimeRuntime {
|
|
268
|
+
/** The `MJ: AI Agent Runs` row id created for this voice session (delegated runs nest under it). */
|
|
269
|
+
CoAgentRunID?: string;
|
|
270
|
+
/** The `MJ: AI Prompt Runs` row id for the session's system prompt. */
|
|
271
|
+
PromptRunID?: string;
|
|
272
|
+
/** Finalizes the co-agent + prompt run. Idempotent; safe to call from multiple teardown paths. */
|
|
273
|
+
Finalize: (success: boolean) => Promise<void>;
|
|
274
|
+
}
|
|
224
275
|
/**
|
|
225
276
|
* Outcome of resolving the realtime model for a session: either a usable {@link RealtimeModelResolution}
|
|
226
277
|
* or a specific, human-readable failure reason (used for explicit preferred-model failures, where the
|
|
@@ -302,16 +353,72 @@ export declare class RealtimeClientSessionService {
|
|
|
302
353
|
*/
|
|
303
354
|
PrepareClientSession(input: PrepareClientSessionInput, contextUser: UserInfo, provider: IMetadataProvider): Promise<RealtimeClientSessionPrepResult>;
|
|
304
355
|
/**
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
356
|
+
* Wires a **server long-lived (bridged)** realtime session onto the SAME core machinery the
|
|
357
|
+
* client-direct path uses — so a LiveKit (or future Zoom/Teams) agent does real work and is tracked
|
|
358
|
+
* identically, with **zero host-local re-implementation**. This is the Phase 2 counterpart to
|
|
359
|
+
* {@link PrepareClientSession}: the browser relays tool calls back over GraphQL to `ExecuteRelayedTool`,
|
|
360
|
+
* whereas here the server holds the live {@link IRealtimeSession} and we wire its `OnToolCall` directly to
|
|
361
|
+
* the SAME {@link ExecuteRelayedTool} (so `invoke-target-agent` runs the target via `AgentRunner`, nests
|
|
362
|
+
* under the co-agent run, supports barge-in cancel + paused-run resume — all of it, for free).
|
|
363
|
+
*
|
|
364
|
+
* Responsibilities, in order:
|
|
365
|
+
* 1. Create the co-agent observability run (+ prompt run + step) so the voice session shows up in the
|
|
366
|
+
* agent-run timeline and delegated runs nest under it (best-effort; a failure just omits the ids).
|
|
367
|
+
* 2. Wire `session.OnToolCall` → `ExecuteRelayedTool` → `session.SendToolResult`.
|
|
368
|
+
* 3. Guarantee finalize-once: wrap `session.Close()` and listen for an unexpected drop (`OnClose`), both
|
|
369
|
+
* routed through one idempotent finalizer. The bridge teardown calls `Close()`, so the run finalizes
|
|
370
|
+
* on graceful end; a dropped socket finalizes via `OnClose`.
|
|
371
|
+
*
|
|
372
|
+
* @param session The live realtime session the bridge owns (from `model.StartSession`).
|
|
373
|
+
* @param input The same prep input used to build the session (carries AgentSessionID, TargetAgentID, …).
|
|
374
|
+
* @param prep The successful {@link PrepareRealtimeSessionParams} result (CoAgent + Resolution).
|
|
375
|
+
* @param contextUser The calling user (threaded into observability + delegated runs).
|
|
376
|
+
* @param provider The request-scoped metadata provider.
|
|
377
|
+
* @returns A {@link BridgeRealtimeRuntime} the bridge holds for the session lifetime.
|
|
378
|
+
*/
|
|
379
|
+
WireBridgeRealtimeSession(session: IRealtimeSession, input: PrepareClientSessionInput, prep: RealtimeSessionParamsPrep, contextUser: UserInfo, provider: IMetadataProvider): Promise<BridgeRealtimeRuntime>;
|
|
380
|
+
/**
|
|
381
|
+
* Degenerate {@link BridgeRealtimeRuntime} for the rare case wiring is attempted without a resolved
|
|
382
|
+
* co-agent: answer every tool call with a clear "not available" error and a no-op finalize. Keeps the
|
|
383
|
+
* bridge from hanging on a tool call when prep was incomplete.
|
|
384
|
+
*/
|
|
385
|
+
private wireBridgeFallbackRuntime;
|
|
386
|
+
/**
|
|
387
|
+
* **The single source of truth for realtime session prep.** Builds the {@link RealtimeSessionParams}
|
|
388
|
+
* for a co-agent voicing a target: resolves the co-agent, the effective config via the full precedence
|
|
389
|
+
* cascade (type-default < co-agent < **target** < runtime override), the realtime model, then assembles
|
|
390
|
+
* the companion system prompt (**first-person as the TARGET** — this is what gives every host the right
|
|
391
|
+
* identity), the stable tool set (**always including `invoke-target-agent`**), voice, and memory.
|
|
392
|
+
*
|
|
393
|
+
* EVERY realtime host consumes this — native chat via {@link PrepareClientSession} → `CreateClientSession`,
|
|
394
|
+
* and the server-bridged hosts (LiveKit, future Zoom/Teams) via `StartSession`. Hosts differ ONLY in how
|
|
395
|
+
* they OPEN the session and their media transport; identity/precedence/prompt/tools live here, once. Do
|
|
396
|
+
* NOT re-implement this in a host. See `plans/realtime/realtime-core-host-convergence.md`.
|
|
397
|
+
*
|
|
398
|
+
* Pure-ish and side-effect-free (no session opened, no observability run created) — those are the
|
|
399
|
+
* opener's concern. Never throws — returns `Success: false` on failure.
|
|
400
|
+
*
|
|
401
|
+
* @param input The co-agent/target/session inputs (the runtime override rides `ConfigOverridesJson`).
|
|
402
|
+
* @param contextUser The calling user (threaded to metadata + memory retrieval).
|
|
403
|
+
* @param provider The request-scoped metadata provider.
|
|
404
|
+
* @returns The prep result: `Success` + co-agent/resolution/effective-config/session-params, or `Success: false`.
|
|
405
|
+
*/
|
|
406
|
+
PrepareRealtimeSessionParams(input: PrepareClientSessionInput, contextUser: UserInfo, provider: IMetadataProvider): Promise<RealtimeSessionParamsPrep>;
|
|
407
|
+
/**
|
|
408
|
+
* Resolves the EFFECTIVE realtime configuration via the surface-agnostic precedence cascade:
|
|
409
|
+
* agent-TYPE `DefaultConfiguration` (base) < **co-agent** `TypeConfiguration` < **target agent**
|
|
410
|
+
* `TypeConfiguration` < (pre-authorized) runtime override — deep-merged per key and normalized.
|
|
411
|
+
* The target layer is what makes a voiced agent (Sage, Marketing Agent, …) carry its own voice/model
|
|
412
|
+
* regardless of host. Tolerant end-to-end: malformed layers contribute nothing and an unloaded metadata
|
|
413
|
+
* cache yields no type defaults. See `plans/realtime/realtime-core-host-convergence.md`.
|
|
309
414
|
*
|
|
310
415
|
* @param coAgent The resolved co-agent.
|
|
311
416
|
* @param overridesJson The pre-authorized runtime override layer, when present.
|
|
417
|
+
* @param targetAgent The TARGET agent being voiced, when distinct from the co-agent — contributes the
|
|
418
|
+
* per-voiced-agent layer (above the co-agent, below the runtime override). Omit when there is none.
|
|
312
419
|
* @returns The normalized effective configuration (possibly empty, never `null`).
|
|
313
420
|
*/
|
|
314
|
-
protected resolveEffectiveConfig(coAgent: MJAIAgentEntityExtended, overridesJson?: string): RealtimeCoAgentConfig;
|
|
421
|
+
protected resolveEffectiveConfig(coAgent: MJAIAgentEntityExtended, overridesJson?: string, targetAgent?: MJAIAgentEntityExtended | null): RealtimeCoAgentConfig;
|
|
315
422
|
/**
|
|
316
423
|
* Reads the co-agent's TYPE-level `DefaultConfiguration` from {@link AIEngine}'s cached agent
|
|
317
424
|
* types. **Overridable seam**; tolerant — an absent type or unloaded cache returns `null`.
|
|
@@ -378,6 +485,29 @@ export declare class RealtimeClientSessionService {
|
|
|
378
485
|
* @param coAgentRunStepID The co-agent run's single `MJ: AI Agent Run Steps` row id, or `null` to skip.
|
|
379
486
|
*/
|
|
380
487
|
FinalizeCoAgentRun(coAgentRunID: string | null, promptRunID: string | null, contextUser: UserInfo, provider: IMetadataProvider, success?: boolean, coAgentRunStepID?: string | null): Promise<void>;
|
|
488
|
+
/**
|
|
489
|
+
* Finalizes the **co-agent observability run(s)** for an agent session that were left `Running` because
|
|
490
|
+
* the session was reaped WITHOUT a live in-memory handle — a prior-boot orphan or a cross-host teardown,
|
|
491
|
+
* where the `Close()`-wrapped finalizer never ran. This is the by-`AgentSessionID` analogue of
|
|
492
|
+
* {@link FinalizeCoAgentRun}: the same-process path already knows its run ids (no query), but here that
|
|
493
|
+
* state died with the prior process, so we locate the session's TOP-LEVEL co-agent run (delegated target
|
|
494
|
+
* runs nest under it and finalize on their own runner) and finalize it + its prompt run + step via the
|
|
495
|
+
* same idempotent helpers. A clean teardown already marked them `Completed`, so this finds nothing.
|
|
496
|
+
*
|
|
497
|
+
* `MJ: AI Agent Runs` is a high-volume transactional table no engine caches, so a narrow ids-only query
|
|
498
|
+
* is the right tool (not a cache reuse). Tolerant — never throws.
|
|
499
|
+
*
|
|
500
|
+
* @param agentSessionID The agent session whose dangling co-agent runs to finalize.
|
|
501
|
+
* @param success Mark them `Completed` (true) or `Failed` (false).
|
|
502
|
+
* @param contextUser The user the writes run as.
|
|
503
|
+
* @param provider The request-scoped metadata provider.
|
|
504
|
+
* @returns The number of co-agent runs finalized (0 when none were dangling).
|
|
505
|
+
*/
|
|
506
|
+
FinalizeCoAgentRunsBySession(agentSessionID: string, success: boolean, contextUser: UserInfo, provider: IMetadataProvider): Promise<number>;
|
|
507
|
+
/** Finds the still-`Running` prompt-run + run-step ids for a co-agent run (orphan finalize path). */
|
|
508
|
+
private findCoAgentChildLogIds;
|
|
509
|
+
/** Escapes single quotes for safe embedding in an `ExtraFilter` literal. */
|
|
510
|
+
private escapeSqlLiteral;
|
|
381
511
|
/** Loads + finalizes the co-agent `AIAgentRun` if still `Running`. Tolerant: logs, never throws. */
|
|
382
512
|
private finalizeAgentRun;
|
|
383
513
|
/**
|
|
@@ -658,6 +788,18 @@ export declare class RealtimeClientSessionService {
|
|
|
658
788
|
* @returns The concatenated system prompt (never empty — the framing is always present).
|
|
659
789
|
*/
|
|
660
790
|
protected buildCompanionSystemPrompt(input: PrepareClientSessionInput, coAgent: MJAIAgentEntityExtended, contextUser: UserInfo, provider: IMetadataProvider, effectiveConfig?: RealtimeCoAgentConfig): Promise<string>;
|
|
791
|
+
/**
|
|
792
|
+
* Builds the **meeting-mode** discipline clause — present only for a multi-agent meeting session
|
|
793
|
+
* ({@link PrepareClientSessionInput.DisableAutoResponse}). It tells the agent to hear the whole
|
|
794
|
+
* conversation but speak only when addressed (named) or clearly called on, and never to talk over
|
|
795
|
+
* others. This is the *prompt* half of "hear always, speak selectively"; the enforcement half is the
|
|
796
|
+
* model's disabled auto-response + the bridge's addressing gate. Empty for a 1:1 call (prompt unchanged).
|
|
797
|
+
* See `plans/realtime/multi-agent-meeting-turn-taking.md`.
|
|
798
|
+
*
|
|
799
|
+
* @param input The prepare-session input (carries the meeting flag + self names).
|
|
800
|
+
* @returns The meeting clause, or `''` for a non-meeting session.
|
|
801
|
+
*/
|
|
802
|
+
protected buildMeetingFraming(input: PrepareClientSessionInput): string;
|
|
661
803
|
/**
|
|
662
804
|
* Builds the "interactive-surface tools" exception clause appended to the co-agent framing when
|
|
663
805
|
* the client supplied channel tools (browser_*, Whiteboard_*, …) as ExtraTools. Without it the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime-client-session-service.d.ts","sourceRoot":"","sources":["../../src/realtime/realtime-client-session-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,EAAE,QAAQ,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"realtime-client-session-service.d.ts","sourceRoot":"","sources":["../../src/realtime/realtime-client-session-service.ts"],"names":[],"mappings":"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"}
|