@memberjunction/ai-bridge-teams 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/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/register-native.d.ts +19 -0
- package/dist/register-native.d.ts.map +1 -0
- package/dist/register-native.js +32 -0
- package/dist/register-native.js.map +1 -0
- package/dist/teams-native-sdk.d.ts +291 -0
- package/dist/teams-native-sdk.d.ts.map +1 -0
- package/dist/teams-native-sdk.js +320 -0
- package/dist/teams-native-sdk.js.map +1 -0
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
export * from './teams-sdk.js';
|
|
2
2
|
export * from './teams-meeting-controls.js';
|
|
3
3
|
export * from './teams-bridge.js';
|
|
4
|
+
export * from './teams-native-sdk.js';
|
|
5
|
+
export * from './register-native.js';
|
|
4
6
|
import { LoadTeamsBridge } from './teams-bridge.js';
|
|
7
|
+
import { RegisterTeamsNativeSdk } from './register-native.js';
|
|
5
8
|
// Static reference so bundlers cannot tree-shake the @RegisterClass(BaseRealtimeBridge, 'TeamsBridge')
|
|
6
9
|
// registration. Calling the no-op here keeps the driver resolvable by the engine's ClassFactory.
|
|
7
10
|
LoadTeamsBridge();
|
|
11
|
+
// Register Teams's native two-way SDK binding so the engine auto-binds it at StartBridgeSession.
|
|
12
|
+
RegisterTeamsNativeSdk();
|
|
8
13
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAElC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,uGAAuG;AACvG,iGAAiG;AACjG,eAAe,EAAE,CAAC;AAClB,iGAAiG;AACjG,sBAAsB,EAAE,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Registers the Teams **native two-way** SDK binding into the {@link BridgeNativeSdkRegistry}
|
|
3
|
+
* so `AIBridgeEngine.StartBridgeSession` auto-binds it onto a resolved `TeamsBridge` before connect — no
|
|
4
|
+
* per-deployment wiring needed. The typed downcast + `SetSdkFactory` stay confined here (where the concrete
|
|
5
|
+
* `TeamsBridge` type is known), keeping the engine seam free of provider types.
|
|
6
|
+
*
|
|
7
|
+
* A host can still override per-session via `StartBridgeSessionParams.BindSdk` — e.g. to use a different
|
|
8
|
+
* Teams binding instead of the native two-way default.
|
|
9
|
+
*
|
|
10
|
+
* @module @memberjunction/ai-bridge-teams
|
|
11
|
+
* @author MemberJunction.com
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Registers Teams's native two-way binding. Idempotent (latest-wins in the registry), and invoked from the
|
|
15
|
+
* package `index.ts` so merely importing `@memberjunction/ai-bridge-teams` wires the default binding. Also
|
|
16
|
+
* exported as a tree-shake-safe no-op-returning function callers can reference to force-retain the module.
|
|
17
|
+
*/
|
|
18
|
+
export declare function RegisterTeamsNativeSdk(): void;
|
|
19
|
+
//# sourceMappingURL=register-native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-native.d.ts","sourceRoot":"","sources":["../src/register-native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAO7C"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Registers the Teams **native two-way** SDK binding into the {@link BridgeNativeSdkRegistry}
|
|
3
|
+
* so `AIBridgeEngine.StartBridgeSession` auto-binds it onto a resolved `TeamsBridge` before connect — no
|
|
4
|
+
* per-deployment wiring needed. The typed downcast + `SetSdkFactory` stay confined here (where the concrete
|
|
5
|
+
* `TeamsBridge` type is known), keeping the engine seam free of provider types.
|
|
6
|
+
*
|
|
7
|
+
* A host can still override per-session via `StartBridgeSessionParams.BindSdk` — e.g. to use a different
|
|
8
|
+
* Teams binding instead of the native two-way default.
|
|
9
|
+
*
|
|
10
|
+
* @module @memberjunction/ai-bridge-teams
|
|
11
|
+
* @author MemberJunction.com
|
|
12
|
+
*/
|
|
13
|
+
import { BridgeNativeSdkRegistry } from '@memberjunction/ai-bridge-base';
|
|
14
|
+
import { BindTeamsNative } from './teams-native-sdk.js';
|
|
15
|
+
/** The `MJ: AI Bridge Providers.DriverClass` value the Teams provider row carries. */
|
|
16
|
+
const TEAMS_DRIVER_CLASS = 'TeamsBridge';
|
|
17
|
+
/**
|
|
18
|
+
* Registers Teams's native two-way binding. Idempotent (latest-wins in the registry), and invoked from the
|
|
19
|
+
* package `index.ts` so merely importing `@memberjunction/ai-bridge-teams` wires the default binding. Also
|
|
20
|
+
* exported as a tree-shake-safe no-op-returning function callers can reference to force-retain the module.
|
|
21
|
+
*/
|
|
22
|
+
export function RegisterTeamsNativeSdk() {
|
|
23
|
+
BridgeNativeSdkRegistry.Instance.Register(TEAMS_DRIVER_CLASS, (driver) => {
|
|
24
|
+
// Safe downcast: the registry is keyed by DriverClass, so the engine only ever applies this to the
|
|
25
|
+
// TeamsBridge it resolved for 'TeamsBridge'. BindTeamsNative() defaults to the lazy native loader,
|
|
26
|
+
// which reads NativeModuleSpecifier from the per-session Configuration.
|
|
27
|
+
driver.SetSdkFactory(BindTeamsNative());
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
// Register on import (mirrors the LoadTeamsBridge() tree-shake pattern in index.ts).
|
|
31
|
+
RegisterTeamsNativeSdk();
|
|
32
|
+
//# sourceMappingURL=register-native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-native.js","sourceRoot":"","sources":["../src/register-native.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,uBAAuB,EAAsB,MAAM,gCAAgC,CAAC;AAE7F,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,sFAAsF;AACtF,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,sBAAsB;IAClC,uBAAuB,CAAC,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,MAA0B,EAAE,EAAE;QACzF,mGAAmG;QACnG,mGAAmG;QACnG,wEAAwE;QACvE,MAAsB,CAAC,aAAa,CAAC,eAAe,EAAE,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACP,CAAC;AAED,qFAAqF;AACrF,sBAAsB,EAAE,CAAC"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `TeamsNativeMeetingSdk` — a **real, two-way** {@link ITeamsMeetingSdk} binding over a
|
|
3
|
+
* native **Microsoft Teams real-time-media / calling-bot addon** (the application-hosted-media bot build).
|
|
4
|
+
* Unlike a receive-only or stub binding, this adapter gives the agent a **voice**: {@link sendAudioFrame}
|
|
5
|
+
* forwards the agent's synthesized PCM to the native client's outbound audio-socket **send** path, and the
|
|
6
|
+
* host controls (chat / mute) actually act.
|
|
7
|
+
*
|
|
8
|
+
* ## Why a native binding
|
|
9
|
+
* Pushing audio *into* a Teams meeting and observing per-participant inbound audio requires the
|
|
10
|
+
* application-hosted-media bot model (Azure Communication Services calling-bot + Microsoft Graph
|
|
11
|
+
* cloud-communications API). The native addon exposes both the outbound audio **send** path (the bot's
|
|
12
|
+
* voice) and the per-participant inbound raw-audio receive callback, so a single binding carries
|
|
13
|
+
* **bidirectional** audio. This is the binding a two-way "agent talks in the meeting" deployment uses.
|
|
14
|
+
*
|
|
15
|
+
* ## The native module seam (no SDK types leak)
|
|
16
|
+
* The ACS/Graph calling-bot media stack has **no single official Node real-time-media package** that fits
|
|
17
|
+
* this seam; deployments wrap it as a N-API addon or a local sidecar process exposing the small
|
|
18
|
+
* {@link NativeMeetingModule} surface declared below. This adapter depends ONLY on that structural surface
|
|
19
|
+
* — none of the ACS/Graph SDK's real types leak into the package, and the module is loaded **lazily**
|
|
20
|
+
* behind an injectable {@link NativeModuleLoader} so `@memberjunction/ai-bridge-teams` builds and
|
|
21
|
+
* unit-tests with **no addon and no network**. Tests inject a fake module; production points
|
|
22
|
+
* {@link TeamsNativeSdkConfig.NativeModuleSpecifier} at the real addon.
|
|
23
|
+
*
|
|
24
|
+
* ## Entitlements + auth (deployment responsibility)
|
|
25
|
+
* The native bot needs the Graph cloud-communications **application-hosted media** permissions and joins
|
|
26
|
+
* with an OAuth bearer / application token (the bot's identity in the tenant) — resolved **upstream** (MJ
|
|
27
|
+
* credential system / provider `Configuration`) and **never inlined**. See the package README's
|
|
28
|
+
* "Native two-way audio" section.
|
|
29
|
+
*
|
|
30
|
+
* Every spot where the native addon's exact surface is assumed carries a `// VERIFY against the native
|
|
31
|
+
* Teams real-time-media addon` note so a live test can confirm it.
|
|
32
|
+
*
|
|
33
|
+
* @module @memberjunction/ai-bridge-teams
|
|
34
|
+
* @author MemberJunction.com
|
|
35
|
+
*/
|
|
36
|
+
import { ITeamsMeetingSdk, TeamsAudioFrame, TeamsJoinArgs, TeamsJoinResult, TeamsParticipant, TeamsParticipantRole } from './teams-sdk.js';
|
|
37
|
+
/**
|
|
38
|
+
* Copies arbitrary PCM input (`Uint8Array` view or standalone `ArrayBuffer`) into a fresh, exactly-sized
|
|
39
|
+
* `ArrayBuffer`. Copying (rather than aliasing) protects the bridge from a native buffer the addon may
|
|
40
|
+
* recycle for the next frame, and respects a `Uint8Array`'s byteOffset/byteLength window.
|
|
41
|
+
*/
|
|
42
|
+
export declare function toPcmArrayBuffer(data: Uint8Array | ArrayBuffer): ArrayBuffer;
|
|
43
|
+
/** One raw per-participant audio frame the native addon surfaces (inbound hearing + diarization). */
|
|
44
|
+
export interface NativeAudioFrame {
|
|
45
|
+
/** Raw PCM bytes for this frame (`Uint8Array` view or standalone `ArrayBuffer`). */
|
|
46
|
+
data: Uint8Array | ArrayBuffer;
|
|
47
|
+
/** The Teams participant id that produced the audio (the diarization speaker label). */
|
|
48
|
+
participantId: string | number;
|
|
49
|
+
/** The participant's display name at capture time, when the addon provides it. */
|
|
50
|
+
displayName?: string;
|
|
51
|
+
/** Optional epoch-ms capture timestamp. */
|
|
52
|
+
timestampMs?: number;
|
|
53
|
+
}
|
|
54
|
+
/** One participant as the native addon reports it. Mapped onto {@link TeamsParticipant}. */
|
|
55
|
+
export interface NativeParticipant {
|
|
56
|
+
/** The native participant id. */
|
|
57
|
+
participantId: string | number;
|
|
58
|
+
/** The participant's display name. */
|
|
59
|
+
displayName?: string;
|
|
60
|
+
/** The participant's role as the addon reports it (`organizer` / `presenter` / `attendee`). */
|
|
61
|
+
role?: string;
|
|
62
|
+
/** Whether this participant is the bot itself. */
|
|
63
|
+
isSelf?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** The arguments the native addon's `join()` accepts. Mirrors {@link TeamsJoinArgs} plus raw-audio opts. */
|
|
66
|
+
export interface NativeJoinArgs {
|
|
67
|
+
/** The Teams meeting join URL (the `https://teams.microsoft.com/l/meetup-join/...` link). */
|
|
68
|
+
joinUrl: string;
|
|
69
|
+
/** The parsed meeting thread id (chat/conversation id behind the join URL), when resolved upstream. */
|
|
70
|
+
threadId?: string;
|
|
71
|
+
/** The bot's display name in the participant list. */
|
|
72
|
+
displayName: string;
|
|
73
|
+
/** The OAuth bearer / application token authorizing the bot's Graph + ACS calls (resolved upstream; never inline). */
|
|
74
|
+
accessToken?: string;
|
|
75
|
+
/** The Azure tenant id the meeting belongs to, when joining cross-tenant. */
|
|
76
|
+
tenantId?: string;
|
|
77
|
+
/** Raw-audio sample rate the bot sends/receives (Hz), when the addon needs it told. */
|
|
78
|
+
sampleRate?: number;
|
|
79
|
+
/** Raw-audio channel count, when the addon needs it told. */
|
|
80
|
+
channels?: number;
|
|
81
|
+
}
|
|
82
|
+
/** What the native addon's `join()` resolves to. */
|
|
83
|
+
export interface NativeJoinResult {
|
|
84
|
+
/** The bot's own participant id in the joined meeting. */
|
|
85
|
+
botParticipantId: string | number;
|
|
86
|
+
/** The Teams call id the bot joined (the durable external connection id). */
|
|
87
|
+
callId: string;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The live native-meeting client the addon hands back. The surface closely mirrors {@link ITeamsMeetingSdk}
|
|
91
|
+
* but in the addon's own (lower-cased) vocabulary; this adapter maps between the two. VERIFY against the
|
|
92
|
+
* native Teams real-time-media addon.
|
|
93
|
+
*/
|
|
94
|
+
export interface NativeMeetingClient {
|
|
95
|
+
/** Joins the meeting (async — the native join handshake is network-bound). */
|
|
96
|
+
join(args: NativeJoinArgs): Promise<NativeJoinResult>;
|
|
97
|
+
/** Leaves the meeting and releases native resources. */
|
|
98
|
+
leave(): Promise<void>;
|
|
99
|
+
/** Sends one raw PCM frame as the bot's outbound audio (the outbound audio-socket — the agent's voice). */
|
|
100
|
+
sendAudioFrame(pcm: ArrayBuffer): void;
|
|
101
|
+
/** Registers the inbound per-participant raw-audio callback. "Latest handler wins." */
|
|
102
|
+
onAudioFrame(cb: (frame: NativeAudioFrame) => void): void;
|
|
103
|
+
/** Registers the participant-join callback. */
|
|
104
|
+
onParticipantJoin(cb: (participant: NativeParticipant) => void): void;
|
|
105
|
+
/** Registers the participant-leave callback (id of the participant that left). */
|
|
106
|
+
onParticipantLeave(cb: (participantId: string | number) => void): void;
|
|
107
|
+
/** Registers the native hand-raise/lower callback (⚠️ partial on Teams). */
|
|
108
|
+
onHandRaise(cb: (participantId: string | number, raised: boolean) => void): void;
|
|
109
|
+
/** Returns the current participant roster (including the bot). */
|
|
110
|
+
getParticipants(): Promise<NativeParticipant[]>;
|
|
111
|
+
/** Posts a message to the Teams meeting chat thread (everyone). */
|
|
112
|
+
postChatMessage(text: string): Promise<void>;
|
|
113
|
+
/** Mutes a participant (requires the bot be organizer/presenter with the relevant policy). */
|
|
114
|
+
muteParticipant(participantId: string | number): Promise<void>;
|
|
115
|
+
/** Registers the meeting-ended callback. */
|
|
116
|
+
onMeetingEnded(cb: () => void): void;
|
|
117
|
+
}
|
|
118
|
+
/** The native addon module surface — a factory that constructs a {@link NativeMeetingClient}. */
|
|
119
|
+
export interface NativeMeetingModule {
|
|
120
|
+
/**
|
|
121
|
+
* Constructs a native meeting client from resolved options (credentials already resolved upstream).
|
|
122
|
+
* VERIFY against the native Teams real-time-media addon (`createClient` vs a `Client` constructor).
|
|
123
|
+
*/
|
|
124
|
+
createClient(options: NativeClientOptions): NativeMeetingClient;
|
|
125
|
+
}
|
|
126
|
+
/** Options passed to {@link NativeMeetingModule.createClient}. Credentials are resolved upstream. */
|
|
127
|
+
export interface NativeClientOptions {
|
|
128
|
+
/** The bot's Azure AD application (client) id (resolved upstream). */
|
|
129
|
+
AppId?: string;
|
|
130
|
+
/** The Azure tenant id the bot operates in (resolved upstream). */
|
|
131
|
+
TenantId?: string;
|
|
132
|
+
/** A pre-resolved OAuth bearer / application token, when the deployment computes it out-of-band. */
|
|
133
|
+
AccessToken?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Resolved configuration for {@link TeamsNativeMeetingSdk}. Credentials resolve **upstream** (MJ credential
|
|
137
|
+
* system / provider `Configuration`) — this object carries already-resolved values; **never inline
|
|
138
|
+
* secrets** at a call site.
|
|
139
|
+
*/
|
|
140
|
+
export interface TeamsNativeSdkConfig {
|
|
141
|
+
/** The bot's Azure AD application (client) id (resolved upstream). */
|
|
142
|
+
AppId?: string;
|
|
143
|
+
/** The Azure tenant id the bot operates in (resolved upstream). */
|
|
144
|
+
TenantId?: string;
|
|
145
|
+
/** A pre-resolved OAuth bearer / application token, when the deployment computes it out-of-band. */
|
|
146
|
+
AccessToken?: string;
|
|
147
|
+
/** The bot's display name (defaults applied by the bridge when absent). */
|
|
148
|
+
BotDisplayName?: string;
|
|
149
|
+
/** Raw-audio sample rate (Hz) the bot sends/receives. */
|
|
150
|
+
SampleRate?: number;
|
|
151
|
+
/** Raw-audio channel count. */
|
|
152
|
+
Channels?: number;
|
|
153
|
+
/**
|
|
154
|
+
* The module specifier of the native Teams real-time-media addon/sidecar to load (e.g. an internal
|
|
155
|
+
* N-API addon package name or an absolute path to a sidecar entry). Required in production; tests
|
|
156
|
+
* inject a loader.
|
|
157
|
+
*/
|
|
158
|
+
NativeModuleSpecifier?: string;
|
|
159
|
+
}
|
|
160
|
+
/** Normalizes the addon's free-form role string onto the bridge's {@link TeamsParticipantRole}. */
|
|
161
|
+
export declare function mapNativeRole(role?: string): TeamsParticipantRole;
|
|
162
|
+
/**
|
|
163
|
+
* **Pure mapping** of one native participant onto the bridge's {@link TeamsParticipant}. Isolated from the
|
|
164
|
+
* addon and from I/O so it is unit-tested directly.
|
|
165
|
+
*/
|
|
166
|
+
export declare function mapNativeParticipant(p: NativeParticipant): TeamsParticipant;
|
|
167
|
+
/**
|
|
168
|
+
* **Pure mapping** of one native inbound audio frame onto the bridge's diarized {@link TeamsAudioFrame}.
|
|
169
|
+
* Copies the PCM (see {@link toPcmArrayBuffer}) and resolves the speaker label. Isolated for direct testing.
|
|
170
|
+
*/
|
|
171
|
+
export declare function mapNativeAudioFrame(frame: NativeAudioFrame): TeamsAudioFrame;
|
|
172
|
+
/**
|
|
173
|
+
* The injectable loader for the native Teams real-time-media addon — overridable so unit tests supply a
|
|
174
|
+
* fake module with no addon and no network. Production leaves it as {@link defaultNativeLoader}, which
|
|
175
|
+
* lazily imports the configured {@link TeamsNativeSdkConfig.NativeModuleSpecifier}.
|
|
176
|
+
*/
|
|
177
|
+
export type NativeModuleLoader = (specifier: string) => Promise<NativeMeetingModule>;
|
|
178
|
+
/**
|
|
179
|
+
* Lazily loads the native Teams real-time-media addon at the given specifier (category: runtime plugin
|
|
180
|
+
* discovery from config — the addon path is deployment-supplied and not known at build time). Throws a
|
|
181
|
+
* precise, actionable error when it can't be loaded so a misconfigured deployment fails loudly, not
|
|
182
|
+
* silently.
|
|
183
|
+
*
|
|
184
|
+
* VERIFY against the native Teams real-time-media addon: the module's default/namespace interop + that it
|
|
185
|
+
* exposes `createClient`.
|
|
186
|
+
*/
|
|
187
|
+
export declare const defaultNativeLoader: NativeModuleLoader;
|
|
188
|
+
/**
|
|
189
|
+
* A **real, two-way** {@link ITeamsMeetingSdk} over the native Teams real-time-media addon (outbound audio
|
|
190
|
+
* send + per-participant inbound receive).
|
|
191
|
+
*
|
|
192
|
+
* Gives the agent both **hearing** (per-participant inbound audio → diarized {@link TeamsAudioFrame}s) and
|
|
193
|
+
* a **voice** ({@link sendAudioFrame} → the native outbound audio-socket), plus working host controls
|
|
194
|
+
* (chat / mute) and roster/hand-raise events. Construct via {@link BindTeamsNative} (the factory the
|
|
195
|
+
* bridge's `SetSdkFactory` wants), not directly, so config resolution + the lazy loader wire consistently.
|
|
196
|
+
*/
|
|
197
|
+
export declare class TeamsNativeMeetingSdk implements ITeamsMeetingSdk {
|
|
198
|
+
/** Resolved config (credentials + raw-audio + the native module specifier). */
|
|
199
|
+
private readonly config;
|
|
200
|
+
/** The native-addon module loader (overridable for tests). */
|
|
201
|
+
private readonly loadModule;
|
|
202
|
+
/** The live native client once {@link join} succeeds. */
|
|
203
|
+
private client;
|
|
204
|
+
/** The inbound per-participant audio handler registered by the bridge. */
|
|
205
|
+
private audioHandler?;
|
|
206
|
+
/** The participant-join handler. */
|
|
207
|
+
private joinHandler?;
|
|
208
|
+
/** The participant-leave handler. */
|
|
209
|
+
private leaveHandler?;
|
|
210
|
+
/** The hand-raise handler. */
|
|
211
|
+
private handRaiseHandler?;
|
|
212
|
+
/** The meeting-ended handler. */
|
|
213
|
+
private endedHandler?;
|
|
214
|
+
/**
|
|
215
|
+
* @param config Resolved credentials + raw-audio opts + the native module specifier.
|
|
216
|
+
* @param loadModule The native-addon loader (defaults to the lazy specifier loader).
|
|
217
|
+
*/
|
|
218
|
+
constructor(config: TeamsNativeSdkConfig, loadModule?: NativeModuleLoader);
|
|
219
|
+
/**
|
|
220
|
+
* Loads the native addon, constructs a client, wires its callbacks, and joins the meeting with the
|
|
221
|
+
* resolved bot token. Brings BOTH hearing and the agent's voice online.
|
|
222
|
+
*
|
|
223
|
+
* @param args The bridge's join args (join URL, thread id, bot name, auth).
|
|
224
|
+
* @returns The bot/call identifiers.
|
|
225
|
+
* @throws When the native module specifier is missing or the addon can't be loaded.
|
|
226
|
+
*/
|
|
227
|
+
join(args: TeamsJoinArgs): Promise<TeamsJoinResult>;
|
|
228
|
+
/** Leaves the meeting and releases the native client. Tolerant of teardown errors. */
|
|
229
|
+
leave(): Promise<void>;
|
|
230
|
+
/**
|
|
231
|
+
* Sends one raw PCM frame as the bot's outbound audio — **the agent's real voice into the meeting**,
|
|
232
|
+
* via the native outbound audio-socket. No-ops (without throwing) before {@link join} so an early
|
|
233
|
+
* model frame never crashes the session.
|
|
234
|
+
*
|
|
235
|
+
* @param pcm The PCM audio bytes to speak into the meeting.
|
|
236
|
+
*/
|
|
237
|
+
sendAudioFrame(pcm: ArrayBuffer): void;
|
|
238
|
+
/** Registers the inbound per-participant audio handler (the diarized hearing path). */
|
|
239
|
+
onAudioFrame(cb: (frame: TeamsAudioFrame) => void): void;
|
|
240
|
+
/** Registers the participant-join handler. */
|
|
241
|
+
onParticipantJoin(cb: (participant: TeamsParticipant) => void): void;
|
|
242
|
+
/** Registers the participant-leave handler. */
|
|
243
|
+
onParticipantLeave(cb: (participantId: string) => void): void;
|
|
244
|
+
/** Registers the native hand-raise/lower handler (⚠️ partial on Teams; tolerant of never firing). */
|
|
245
|
+
onHandRaise(cb: (participantId: string, raised: boolean) => void): void;
|
|
246
|
+
/** Returns the current roster from the native client, mapped to {@link TeamsParticipant}. */
|
|
247
|
+
getParticipants(): Promise<TeamsParticipant[]>;
|
|
248
|
+
/** Registers the meeting-ended handler. */
|
|
249
|
+
onMeetingEnded(cb: () => void): void;
|
|
250
|
+
/**
|
|
251
|
+
* Posts a message to the Teams meeting chat via the native client. No-ops (without throwing) before
|
|
252
|
+
* {@link join}.
|
|
253
|
+
*
|
|
254
|
+
* @param text The chat message text.
|
|
255
|
+
*/
|
|
256
|
+
postChatMessage(text: string): Promise<void>;
|
|
257
|
+
/**
|
|
258
|
+
* Mutes a participant via the native host control (requires the bot be organizer/presenter). No-ops
|
|
259
|
+
* (without throwing) before {@link join}.
|
|
260
|
+
*
|
|
261
|
+
* @param participantId The participant to mute.
|
|
262
|
+
*/
|
|
263
|
+
muteParticipant(participantId: string): Promise<void>;
|
|
264
|
+
/** Wires the native client's callbacks to this adapter's handlers, mapping native shapes to the seam. */
|
|
265
|
+
private wireClient;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Builds the {@link import('./teams-sdk.js').TeamsMeetingSdkFactory}-shaped factory that constructs a
|
|
269
|
+
* {@link TeamsNativeMeetingSdk} from the bridge's per-session `Configuration`. Pass the result to
|
|
270
|
+
* `TeamsBridge.SetSdkFactory(...)` so a deployment activates **two-way native Teams audio** without code
|
|
271
|
+
* changes to the driver.
|
|
272
|
+
*
|
|
273
|
+
* Reads bot credentials / token + raw-audio opts + the native module specifier out of the config map the
|
|
274
|
+
* engine passes at connect (credentials resolved upstream — **never inline secrets**).
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* // Where bridge drivers are configured (creds already resolved from the MJ credential system):
|
|
278
|
+
* bridge.SetSdkFactory(BindTeamsNative());
|
|
279
|
+
*
|
|
280
|
+
* @param loadModule Optional native-addon loader override (tests inject a fake; production omits it).
|
|
281
|
+
* @returns A factory `(config) => TeamsNativeMeetingSdk`.
|
|
282
|
+
*/
|
|
283
|
+
export declare function BindTeamsNative(loadModule?: NativeModuleLoader): (config?: Record<string, unknown>) => TeamsNativeMeetingSdk;
|
|
284
|
+
/**
|
|
285
|
+
* Extracts a {@link TeamsNativeSdkConfig} from the engine's loosely-typed `Configuration` map without ever
|
|
286
|
+
* widening to `any`. Each field is read + type-checked individually so a malformed config yields a clean,
|
|
287
|
+
* partially-resolved object (and {@link TeamsNativeMeetingSdk.join} then throws a precise error if the
|
|
288
|
+
* required specifier is absent) rather than a half-typed blob.
|
|
289
|
+
*/
|
|
290
|
+
export declare function readNativeConfig(config?: Record<string, unknown>): TeamsNativeSdkConfig;
|
|
291
|
+
//# sourceMappingURL=teams-native-sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams-native-sdk.d.ts","sourceRoot":"","sources":["../src/teams-native-sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview `TeamsNativeMeetingSdk` — a **real, two-way** {@link ITeamsMeetingSdk} binding over a
|
|
3
|
+
* native **Microsoft Teams real-time-media / calling-bot addon** (the application-hosted-media bot build).
|
|
4
|
+
* Unlike a receive-only or stub binding, this adapter gives the agent a **voice**: {@link sendAudioFrame}
|
|
5
|
+
* forwards the agent's synthesized PCM to the native client's outbound audio-socket **send** path, and the
|
|
6
|
+
* host controls (chat / mute) actually act.
|
|
7
|
+
*
|
|
8
|
+
* ## Why a native binding
|
|
9
|
+
* Pushing audio *into* a Teams meeting and observing per-participant inbound audio requires the
|
|
10
|
+
* application-hosted-media bot model (Azure Communication Services calling-bot + Microsoft Graph
|
|
11
|
+
* cloud-communications API). The native addon exposes both the outbound audio **send** path (the bot's
|
|
12
|
+
* voice) and the per-participant inbound raw-audio receive callback, so a single binding carries
|
|
13
|
+
* **bidirectional** audio. This is the binding a two-way "agent talks in the meeting" deployment uses.
|
|
14
|
+
*
|
|
15
|
+
* ## The native module seam (no SDK types leak)
|
|
16
|
+
* The ACS/Graph calling-bot media stack has **no single official Node real-time-media package** that fits
|
|
17
|
+
* this seam; deployments wrap it as a N-API addon or a local sidecar process exposing the small
|
|
18
|
+
* {@link NativeMeetingModule} surface declared below. This adapter depends ONLY on that structural surface
|
|
19
|
+
* — none of the ACS/Graph SDK's real types leak into the package, and the module is loaded **lazily**
|
|
20
|
+
* behind an injectable {@link NativeModuleLoader} so `@memberjunction/ai-bridge-teams` builds and
|
|
21
|
+
* unit-tests with **no addon and no network**. Tests inject a fake module; production points
|
|
22
|
+
* {@link TeamsNativeSdkConfig.NativeModuleSpecifier} at the real addon.
|
|
23
|
+
*
|
|
24
|
+
* ## Entitlements + auth (deployment responsibility)
|
|
25
|
+
* The native bot needs the Graph cloud-communications **application-hosted media** permissions and joins
|
|
26
|
+
* with an OAuth bearer / application token (the bot's identity in the tenant) — resolved **upstream** (MJ
|
|
27
|
+
* credential system / provider `Configuration`) and **never inlined**. See the package README's
|
|
28
|
+
* "Native two-way audio" section.
|
|
29
|
+
*
|
|
30
|
+
* Every spot where the native addon's exact surface is assumed carries a `// VERIFY against the native
|
|
31
|
+
* Teams real-time-media addon` note so a live test can confirm it.
|
|
32
|
+
*
|
|
33
|
+
* @module @memberjunction/ai-bridge-teams
|
|
34
|
+
* @author MemberJunction.com
|
|
35
|
+
*/
|
|
36
|
+
import { LogError } from '@memberjunction/core';
|
|
37
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
// Local PCM-coercion helper. The Teams package has no existing `toArrayBuffer`
|
|
39
|
+
// export (unlike Zoom, which reuses its RTMS binding's), so we define a
|
|
40
|
+
// non-colliding local one (`toPcmArrayBuffer`) to avoid clashing under index.ts's
|
|
41
|
+
// `export *`.
|
|
42
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
43
|
+
/**
|
|
44
|
+
* Copies arbitrary PCM input (`Uint8Array` view or standalone `ArrayBuffer`) into a fresh, exactly-sized
|
|
45
|
+
* `ArrayBuffer`. Copying (rather than aliasing) protects the bridge from a native buffer the addon may
|
|
46
|
+
* recycle for the next frame, and respects a `Uint8Array`'s byteOffset/byteLength window.
|
|
47
|
+
*/
|
|
48
|
+
export function toPcmArrayBuffer(data) {
|
|
49
|
+
if (data instanceof ArrayBuffer) {
|
|
50
|
+
return data.slice(0);
|
|
51
|
+
}
|
|
52
|
+
const out = new ArrayBuffer(data.byteLength);
|
|
53
|
+
new Uint8Array(out).set(data);
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
/** Normalizes the addon's free-form role string onto the bridge's {@link TeamsParticipantRole}. */
|
|
57
|
+
export function mapNativeRole(role) {
|
|
58
|
+
switch ((role ?? '').trim().toLowerCase()) {
|
|
59
|
+
case 'organizer':
|
|
60
|
+
return 'Organizer';
|
|
61
|
+
case 'presenter':
|
|
62
|
+
case 'co-organizer':
|
|
63
|
+
case 'coorganizer':
|
|
64
|
+
return 'Presenter';
|
|
65
|
+
default:
|
|
66
|
+
return 'Attendee';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* **Pure mapping** of one native participant onto the bridge's {@link TeamsParticipant}. Isolated from the
|
|
71
|
+
* addon and from I/O so it is unit-tested directly.
|
|
72
|
+
*/
|
|
73
|
+
export function mapNativeParticipant(p) {
|
|
74
|
+
return {
|
|
75
|
+
ParticipantId: String(p.participantId),
|
|
76
|
+
DisplayName: p.displayName,
|
|
77
|
+
Role: mapNativeRole(p.role),
|
|
78
|
+
IsSelf: p.isSelf,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* **Pure mapping** of one native inbound audio frame onto the bridge's diarized {@link TeamsAudioFrame}.
|
|
83
|
+
* Copies the PCM (see {@link toPcmArrayBuffer}) and resolves the speaker label. Isolated for direct testing.
|
|
84
|
+
*/
|
|
85
|
+
export function mapNativeAudioFrame(frame) {
|
|
86
|
+
return {
|
|
87
|
+
Pcm: toPcmArrayBuffer(frame.data),
|
|
88
|
+
ParticipantId: String(frame.participantId),
|
|
89
|
+
DisplayName: frame.displayName,
|
|
90
|
+
TimestampMs: typeof frame.timestampMs === 'number' ? frame.timestampMs : Date.now(),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Structural guard: a value is a {@link NativeMeetingModule} when it exposes a `createClient` function. */
|
|
94
|
+
function isNativeModule(value) {
|
|
95
|
+
return (value != null &&
|
|
96
|
+
typeof value === 'object' &&
|
|
97
|
+
typeof value.createClient === 'function');
|
|
98
|
+
}
|
|
99
|
+
/** Unwraps a `{ default }` interop wrapper (CJS-with-default), returning the inner value or the input. */
|
|
100
|
+
function unwrapDefault(mod) {
|
|
101
|
+
if (mod && typeof mod === 'object' && 'default' in mod) {
|
|
102
|
+
const inner = mod.default;
|
|
103
|
+
if (isNativeModule(inner)) {
|
|
104
|
+
return inner;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return mod;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Lazily loads the native Teams real-time-media addon at the given specifier (category: runtime plugin
|
|
111
|
+
* discovery from config — the addon path is deployment-supplied and not known at build time). Throws a
|
|
112
|
+
* precise, actionable error when it can't be loaded so a misconfigured deployment fails loudly, not
|
|
113
|
+
* silently.
|
|
114
|
+
*
|
|
115
|
+
* VERIFY against the native Teams real-time-media addon: the module's default/namespace interop + that it
|
|
116
|
+
* exposes `createClient`.
|
|
117
|
+
*/
|
|
118
|
+
export const defaultNativeLoader = async (specifier) => {
|
|
119
|
+
try {
|
|
120
|
+
const mod = await import(/* @vite-ignore */ specifier);
|
|
121
|
+
const resolved = unwrapDefault(mod);
|
|
122
|
+
if (!isNativeModule(resolved)) {
|
|
123
|
+
throw new Error('resolved module has no createClient() factory');
|
|
124
|
+
}
|
|
125
|
+
return resolved;
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
129
|
+
throw new Error(`TeamsNativeMeetingSdk could not load the native Teams real-time-media addon at '${specifier}'. ` +
|
|
130
|
+
'Build/install the native Teams calling-bot addon (the ACS application-hosted-media build, with ' +
|
|
131
|
+
'Graph cloud-communications permissions) and set TeamsNativeSdkConfig.NativeModuleSpecifier to it. ' +
|
|
132
|
+
`Underlying error: ${message}`);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* A **real, two-way** {@link ITeamsMeetingSdk} over the native Teams real-time-media addon (outbound audio
|
|
137
|
+
* send + per-participant inbound receive).
|
|
138
|
+
*
|
|
139
|
+
* Gives the agent both **hearing** (per-participant inbound audio → diarized {@link TeamsAudioFrame}s) and
|
|
140
|
+
* a **voice** ({@link sendAudioFrame} → the native outbound audio-socket), plus working host controls
|
|
141
|
+
* (chat / mute) and roster/hand-raise events. Construct via {@link BindTeamsNative} (the factory the
|
|
142
|
+
* bridge's `SetSdkFactory` wants), not directly, so config resolution + the lazy loader wire consistently.
|
|
143
|
+
*/
|
|
144
|
+
export class TeamsNativeMeetingSdk {
|
|
145
|
+
/**
|
|
146
|
+
* @param config Resolved credentials + raw-audio opts + the native module specifier.
|
|
147
|
+
* @param loadModule The native-addon loader (defaults to the lazy specifier loader).
|
|
148
|
+
*/
|
|
149
|
+
constructor(config, loadModule = defaultNativeLoader) {
|
|
150
|
+
/** The live native client once {@link join} succeeds. */
|
|
151
|
+
this.client = null;
|
|
152
|
+
this.config = config;
|
|
153
|
+
this.loadModule = loadModule;
|
|
154
|
+
}
|
|
155
|
+
// ── ITeamsMeetingSdk — lifecycle ─────────────────────────────────────────────────
|
|
156
|
+
/**
|
|
157
|
+
* Loads the native addon, constructs a client, wires its callbacks, and joins the meeting with the
|
|
158
|
+
* resolved bot token. Brings BOTH hearing and the agent's voice online.
|
|
159
|
+
*
|
|
160
|
+
* @param args The bridge's join args (join URL, thread id, bot name, auth).
|
|
161
|
+
* @returns The bot/call identifiers.
|
|
162
|
+
* @throws When the native module specifier is missing or the addon can't be loaded.
|
|
163
|
+
*/
|
|
164
|
+
async join(args) {
|
|
165
|
+
const specifier = this.config.NativeModuleSpecifier;
|
|
166
|
+
if (!specifier) {
|
|
167
|
+
throw new Error('TeamsNativeMeetingSdk.join: no NativeModuleSpecifier configured. Set it to the native Teams ' +
|
|
168
|
+
'real-time-media bot addon (ACS application-hosted-media build) in the session Configuration. ' +
|
|
169
|
+
'See the README.');
|
|
170
|
+
}
|
|
171
|
+
const mod = await this.loadModule(specifier);
|
|
172
|
+
const client = mod.createClient({
|
|
173
|
+
AppId: this.config.AppId,
|
|
174
|
+
TenantId: this.config.TenantId,
|
|
175
|
+
AccessToken: this.config.AccessToken,
|
|
176
|
+
});
|
|
177
|
+
this.wireClient(client);
|
|
178
|
+
const result = await client.join({
|
|
179
|
+
joinUrl: args.JoinUrl,
|
|
180
|
+
threadId: args.ThreadId,
|
|
181
|
+
displayName: args.BotDisplayName || this.config.BotDisplayName || 'AI Agent',
|
|
182
|
+
accessToken: args.AccessToken ?? this.config.AccessToken,
|
|
183
|
+
tenantId: args.TenantId ?? this.config.TenantId,
|
|
184
|
+
sampleRate: this.config.SampleRate,
|
|
185
|
+
channels: this.config.Channels,
|
|
186
|
+
});
|
|
187
|
+
this.client = client;
|
|
188
|
+
return {
|
|
189
|
+
BotParticipantId: String(result.botParticipantId),
|
|
190
|
+
CallId: result.callId || args.ThreadId || args.JoinUrl,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/** Leaves the meeting and releases the native client. Tolerant of teardown errors. */
|
|
194
|
+
async leave() {
|
|
195
|
+
const client = this.client;
|
|
196
|
+
this.client = null;
|
|
197
|
+
if (client) {
|
|
198
|
+
try {
|
|
199
|
+
await client.leave();
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
LogError(`[TeamsNativeMeetingSdk] leave() failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// ── ITeamsMeetingSdk — two-way audio (real) ──────────────────────────────────────
|
|
207
|
+
/**
|
|
208
|
+
* Sends one raw PCM frame as the bot's outbound audio — **the agent's real voice into the meeting**,
|
|
209
|
+
* via the native outbound audio-socket. No-ops (without throwing) before {@link join} so an early
|
|
210
|
+
* model frame never crashes the session.
|
|
211
|
+
*
|
|
212
|
+
* @param pcm The PCM audio bytes to speak into the meeting.
|
|
213
|
+
*/
|
|
214
|
+
sendAudioFrame(pcm) {
|
|
215
|
+
this.client?.sendAudioFrame(pcm);
|
|
216
|
+
}
|
|
217
|
+
/** Registers the inbound per-participant audio handler (the diarized hearing path). */
|
|
218
|
+
onAudioFrame(cb) {
|
|
219
|
+
this.audioHandler = cb;
|
|
220
|
+
}
|
|
221
|
+
// ── ITeamsMeetingSdk — roster + signals ──────────────────────────────────────────
|
|
222
|
+
/** Registers the participant-join handler. */
|
|
223
|
+
onParticipantJoin(cb) {
|
|
224
|
+
this.joinHandler = cb;
|
|
225
|
+
}
|
|
226
|
+
/** Registers the participant-leave handler. */
|
|
227
|
+
onParticipantLeave(cb) {
|
|
228
|
+
this.leaveHandler = cb;
|
|
229
|
+
}
|
|
230
|
+
/** Registers the native hand-raise/lower handler (⚠️ partial on Teams; tolerant of never firing). */
|
|
231
|
+
onHandRaise(cb) {
|
|
232
|
+
this.handRaiseHandler = cb;
|
|
233
|
+
}
|
|
234
|
+
/** Returns the current roster from the native client, mapped to {@link TeamsParticipant}. */
|
|
235
|
+
async getParticipants() {
|
|
236
|
+
if (!this.client) {
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
const natives = await this.client.getParticipants();
|
|
240
|
+
return natives.map(mapNativeParticipant);
|
|
241
|
+
}
|
|
242
|
+
/** Registers the meeting-ended handler. */
|
|
243
|
+
onMeetingEnded(cb) {
|
|
244
|
+
this.endedHandler = cb;
|
|
245
|
+
}
|
|
246
|
+
// ── ITeamsMeetingSdk — host controls (real) ──────────────────────────────────────
|
|
247
|
+
/**
|
|
248
|
+
* Posts a message to the Teams meeting chat via the native client. No-ops (without throwing) before
|
|
249
|
+
* {@link join}.
|
|
250
|
+
*
|
|
251
|
+
* @param text The chat message text.
|
|
252
|
+
*/
|
|
253
|
+
async postChatMessage(text) {
|
|
254
|
+
await this.client?.postChatMessage(text);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Mutes a participant via the native host control (requires the bot be organizer/presenter). No-ops
|
|
258
|
+
* (without throwing) before {@link join}.
|
|
259
|
+
*
|
|
260
|
+
* @param participantId The participant to mute.
|
|
261
|
+
*/
|
|
262
|
+
async muteParticipant(participantId) {
|
|
263
|
+
await this.client?.muteParticipant(participantId);
|
|
264
|
+
}
|
|
265
|
+
// ── internals ────────────────────────────────────────────────────────────────────
|
|
266
|
+
/** Wires the native client's callbacks to this adapter's handlers, mapping native shapes to the seam. */
|
|
267
|
+
wireClient(client) {
|
|
268
|
+
client.onAudioFrame((frame) => this.audioHandler?.(mapNativeAudioFrame(frame)));
|
|
269
|
+
client.onParticipantJoin((p) => this.joinHandler?.(mapNativeParticipant(p)));
|
|
270
|
+
client.onParticipantLeave((id) => this.leaveHandler?.(String(id)));
|
|
271
|
+
client.onHandRaise((id, raised) => this.handRaiseHandler?.(String(id), raised));
|
|
272
|
+
client.onMeetingEnded(() => this.endedHandler?.());
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Builds the {@link import('./teams-sdk.js').TeamsMeetingSdkFactory}-shaped factory that constructs a
|
|
277
|
+
* {@link TeamsNativeMeetingSdk} from the bridge's per-session `Configuration`. Pass the result to
|
|
278
|
+
* `TeamsBridge.SetSdkFactory(...)` so a deployment activates **two-way native Teams audio** without code
|
|
279
|
+
* changes to the driver.
|
|
280
|
+
*
|
|
281
|
+
* Reads bot credentials / token + raw-audio opts + the native module specifier out of the config map the
|
|
282
|
+
* engine passes at connect (credentials resolved upstream — **never inline secrets**).
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* // Where bridge drivers are configured (creds already resolved from the MJ credential system):
|
|
286
|
+
* bridge.SetSdkFactory(BindTeamsNative());
|
|
287
|
+
*
|
|
288
|
+
* @param loadModule Optional native-addon loader override (tests inject a fake; production omits it).
|
|
289
|
+
* @returns A factory `(config) => TeamsNativeMeetingSdk`.
|
|
290
|
+
*/
|
|
291
|
+
export function BindTeamsNative(loadModule = defaultNativeLoader) {
|
|
292
|
+
return (config) => new TeamsNativeMeetingSdk(readNativeConfig(config), loadModule);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Extracts a {@link TeamsNativeSdkConfig} from the engine's loosely-typed `Configuration` map without ever
|
|
296
|
+
* widening to `any`. Each field is read + type-checked individually so a malformed config yields a clean,
|
|
297
|
+
* partially-resolved object (and {@link TeamsNativeMeetingSdk.join} then throws a precise error if the
|
|
298
|
+
* required specifier is absent) rather than a half-typed blob.
|
|
299
|
+
*/
|
|
300
|
+
export function readNativeConfig(config) {
|
|
301
|
+
const cfg = config ?? {};
|
|
302
|
+
return {
|
|
303
|
+
AppId: readString(cfg.AppId),
|
|
304
|
+
TenantId: readString(cfg.TenantId),
|
|
305
|
+
AccessToken: readString(cfg.AccessToken),
|
|
306
|
+
BotDisplayName: readString(cfg.BotDisplayName),
|
|
307
|
+
SampleRate: readNumber(cfg.SampleRate),
|
|
308
|
+
Channels: readNumber(cfg.Channels),
|
|
309
|
+
NativeModuleSpecifier: readString(cfg.NativeModuleSpecifier),
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
/** Reads a value as a non-empty string, or `undefined`. */
|
|
313
|
+
function readString(value) {
|
|
314
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
315
|
+
}
|
|
316
|
+
/** Reads a value as a finite number, or `undefined`. */
|
|
317
|
+
function readNumber(value) {
|
|
318
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=teams-native-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams-native-sdk.js","sourceRoot":"","sources":["../src/teams-native-sdk.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ai-bridge-teams",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.42.0",
|
|
5
5
|
"description": "MemberJunction: Microsoft Teams Realtime Bridge driver. Connects the realtime agent engine to a Teams meeting (audio in/out, diarized roster, participant mute, Teams meeting chat) via an injectable Teams calling-bot SDK seam (Azure Communication Services / Microsoft Graph cloud-communications), and contributes a Meeting Controls facilitator channel.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"author": "MemberJunction.com",
|
|
18
18
|
"license": "ISC",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@memberjunction/core": "5.
|
|
21
|
-
"@memberjunction/global": "5.
|
|
22
|
-
"@memberjunction/core-entities": "5.
|
|
23
|
-
"@memberjunction/ai-bridge-base": "5.
|
|
20
|
+
"@memberjunction/core": "5.42.0",
|
|
21
|
+
"@memberjunction/global": "5.42.0",
|
|
22
|
+
"@memberjunction/core-entities": "5.42.0",
|
|
23
|
+
"@memberjunction/ai-bridge-base": "5.42.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/node": "24.10.11",
|