@memberjunction/ai-bridge-teams 0.0.1 → 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 +109 -43
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- 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-bridge.d.ts +155 -0
- package/dist/teams-bridge.d.ts.map +1 -0
- package/dist/teams-bridge.js +356 -0
- package/dist/teams-bridge.js.map +1 -0
- package/dist/teams-meeting-controls.d.ts +80 -0
- package/dist/teams-meeting-controls.d.ts.map +1 -0
- package/dist/teams-meeting-controls.js +130 -0
- package/dist/teams-meeting-controls.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/dist/teams-sdk.d.ts +173 -0
- package/dist/teams-sdk.d.ts.map +1 -0
- package/dist/teams-sdk.js +35 -0
- package/dist/teams-sdk.js.map +1 -0
- package/package.json +32 -7
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The injectable **Microsoft Teams calling-bot SDK seam** — the minimal set of operations
|
|
3
|
+
* {@link import('./teams-bridge.js').TeamsBridge} needs from Teams, declared as an interface so the driver
|
|
4
|
+
* builds and unit-tests against an in-memory fake with **no network and no real Teams / Azure
|
|
5
|
+
* Communication Services SDK**.
|
|
6
|
+
*
|
|
7
|
+
* ## Production binding (TODO at deployment)
|
|
8
|
+
* In production this interface is bound to the **Azure Communication Services (ACS) calling-bot** SDK
|
|
9
|
+
* plus the **Microsoft Graph cloud-communications API** (the `/communications/calls` "application-hosted
|
|
10
|
+
* media" bot model) so the bot can join a Teams meeting, pull per-participant PCM audio for diarization,
|
|
11
|
+
* push synthesized audio back, observe roster + raised-hand events, and post to the Teams meeting chat.
|
|
12
|
+
* The named operations map to the SDK as follows:
|
|
13
|
+
* - {@link join} / {@link leave} → the Graph `POST /communications/calls` (join meeting via the join
|
|
14
|
+
* URL / meeting coordinates) and the call's `DELETE` (leave) lifecycle.
|
|
15
|
+
* - {@link sendAudioFrame} → the ACS application-hosted-media outbound audio-socket (the bot's voice in).
|
|
16
|
+
* - {@link onAudioFrame} → the ACS per-participant inbound audio-socket callback (the source of speaker
|
|
17
|
+
* labels for diarization — Teams provides participant attribution on the media stream).
|
|
18
|
+
* - {@link onParticipantJoin} / {@link onParticipantLeave} / {@link getParticipants} → the call's
|
|
19
|
+
* `participants` collection + the `participantsUpdated` change notifications.
|
|
20
|
+
* - {@link onHandRaise} → the meeting's raised-hand signal. ⚠️ Partial: Teams surfaces raised hands in
|
|
21
|
+
* the meeting UI, but a clean per-participant *event* over the calling-bot API is not guaranteed on
|
|
22
|
+
* every tenant/build; the adapter wires it where the platform exposes it and otherwise no-ops.
|
|
23
|
+
* - {@link postChatMessage} → the Graph `POST /chats/{id}/messages` against the meeting's chat thread.
|
|
24
|
+
* - {@link muteParticipant} → the call's `participant:mute` action (requires the bot be an organizer /
|
|
25
|
+
* presenter with the relevant policy).
|
|
26
|
+
* - {@link onMeetingEnded} → the call's `callEnded` / `terminated` status notification.
|
|
27
|
+
*
|
|
28
|
+
* Binding the real SDK is a thin adapter that implements this interface; the driver and its tests do
|
|
29
|
+
* not change. **None of the ACS/Graph SDK types leak into this package.**
|
|
30
|
+
*
|
|
31
|
+
* See `/plans/realtime/realtime-bridges-architecture.md` §3, §8 (Microsoft Teams row) and
|
|
32
|
+
* `/guides/REALTIME_BRIDGES_GUIDE.md`.
|
|
33
|
+
*/
|
|
34
|
+
/** The role a Teams participant holds in the meeting, normalized to the bridge's participant roles. */
|
|
35
|
+
export type TeamsParticipantRole = 'Organizer' | 'Presenter' | 'Attendee';
|
|
36
|
+
/**
|
|
37
|
+
* One Teams meeting participant as the seam reports it. Platform-native and minimal — the driver maps
|
|
38
|
+
* this onto `BridgeParticipantInfo` / `BridgeMeetingParticipant`.
|
|
39
|
+
*/
|
|
40
|
+
export interface TeamsParticipant {
|
|
41
|
+
/** The Teams participant id (the call's participant identity / `id`, stable for their presence). */
|
|
42
|
+
ParticipantId: string;
|
|
43
|
+
/** The participant's display name as Teams reports it. */
|
|
44
|
+
DisplayName?: string;
|
|
45
|
+
/** The participant's meeting role. */
|
|
46
|
+
Role: TeamsParticipantRole;
|
|
47
|
+
/** Whether this participant is the bridge's own bot (so the driver can exclude it from diarization addressing). */
|
|
48
|
+
IsSelf?: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** One frame of raw per-participant audio the seam surfaces for diarization + the agent's "hearing". */
|
|
51
|
+
export interface TeamsAudioFrame {
|
|
52
|
+
/** Raw PCM audio bytes for this frame. */
|
|
53
|
+
Pcm: ArrayBuffer;
|
|
54
|
+
/** The Teams participant id this audio came from (the diarization speaker label). */
|
|
55
|
+
ParticipantId: string;
|
|
56
|
+
/** The participant's display name at capture time, when known. */
|
|
57
|
+
DisplayName?: string;
|
|
58
|
+
/** Optional epoch-ms capture timestamp. */
|
|
59
|
+
TimestampMs?: number;
|
|
60
|
+
}
|
|
61
|
+
/** Arguments to {@link ITeamsMeetingSdk.join} — what the bot needs to get into a Teams meeting. */
|
|
62
|
+
export interface TeamsJoinArgs {
|
|
63
|
+
/** The Teams meeting join URL (the `https://teams.microsoft.com/l/meetup-join/...` link). */
|
|
64
|
+
JoinUrl: string;
|
|
65
|
+
/**
|
|
66
|
+
* The parsed meeting thread id (the chat/conversation id behind the join URL), when resolved
|
|
67
|
+
* upstream. Used for posting to the meeting chat and as a stable meeting coordinate.
|
|
68
|
+
*/
|
|
69
|
+
ThreadId?: string;
|
|
70
|
+
/** The display name the bot appears as in the participant list. */
|
|
71
|
+
BotDisplayName: string;
|
|
72
|
+
/**
|
|
73
|
+
* The OAuth bearer / application token authorizing the bot's Graph + ACS calls. Resolved upstream
|
|
74
|
+
* via MJ's credential system; never inline secrets.
|
|
75
|
+
*/
|
|
76
|
+
AccessToken?: string;
|
|
77
|
+
/** The Azure tenant id the meeting belongs to, when joining cross-tenant. */
|
|
78
|
+
TenantId?: string;
|
|
79
|
+
}
|
|
80
|
+
/** The handles the seam returns after a successful {@link ITeamsMeetingSdk.join}. */
|
|
81
|
+
export interface TeamsJoinResult {
|
|
82
|
+
/** The bot's own participant id in the joined meeting. */
|
|
83
|
+
BotParticipantId: string;
|
|
84
|
+
/** The Teams call id the bot joined (the durable external connection id). */
|
|
85
|
+
CallId: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The minimal Microsoft Teams calling-bot SDK surface the {@link import('./teams-bridge.js').TeamsBridge}
|
|
89
|
+
* depends on. Production binds this to the real ACS calling-bot / Graph cloud-communications API; tests
|
|
90
|
+
* inject a `FakeTeamsSdk`.
|
|
91
|
+
*/
|
|
92
|
+
export interface ITeamsMeetingSdk {
|
|
93
|
+
/**
|
|
94
|
+
* Joins the Teams meeting and brings the bot online. Returns the bot's participant id + the call id.
|
|
95
|
+
*
|
|
96
|
+
* @param args Join parameters (join URL, thread id, bot name, auth).
|
|
97
|
+
* @returns The bot participant + call handles.
|
|
98
|
+
*/
|
|
99
|
+
join(args: TeamsJoinArgs): Promise<TeamsJoinResult>;
|
|
100
|
+
/** Leaves the meeting (terminates the bot's call leg) and releases SDK resources. */
|
|
101
|
+
leave(): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Sends one raw PCM audio frame as the bot's outbound audio (the agent's voice into the meeting),
|
|
104
|
+
* over the ACS application-hosted-media outbound audio socket.
|
|
105
|
+
*
|
|
106
|
+
* @param pcm The PCM audio bytes to send.
|
|
107
|
+
*/
|
|
108
|
+
sendAudioFrame(pcm: ArrayBuffer): void;
|
|
109
|
+
/**
|
|
110
|
+
* Registers a callback for inbound raw per-participant audio frames (what the agent hears, carrying
|
|
111
|
+
* the speaker label for diarization). "Latest handler wins."
|
|
112
|
+
*
|
|
113
|
+
* @param cb Invoked with each inbound audio frame.
|
|
114
|
+
*/
|
|
115
|
+
onAudioFrame(cb: (frame: TeamsAudioFrame) => void): void;
|
|
116
|
+
/**
|
|
117
|
+
* Registers a callback fired when a participant joins. "Latest handler wins."
|
|
118
|
+
*
|
|
119
|
+
* @param cb Invoked with the participant who joined.
|
|
120
|
+
*/
|
|
121
|
+
onParticipantJoin(cb: (participant: TeamsParticipant) => void): void;
|
|
122
|
+
/**
|
|
123
|
+
* Registers a callback fired when a participant leaves. "Latest handler wins."
|
|
124
|
+
*
|
|
125
|
+
* @param cb Invoked with the participant id that left.
|
|
126
|
+
*/
|
|
127
|
+
onParticipantLeave(cb: (participantId: string) => void): void;
|
|
128
|
+
/**
|
|
129
|
+
* Registers a callback for native raised-hand signals. "Latest handler wins."
|
|
130
|
+
*
|
|
131
|
+
* ⚠️ Teams raised-hand is partial over the calling-bot API: a clean per-participant event is not
|
|
132
|
+
* guaranteed on every tenant/build. The adapter wires this where the platform exposes it and the
|
|
133
|
+
* driver tolerates the signal never firing.
|
|
134
|
+
*
|
|
135
|
+
* @param cb Invoked with the participant id and whether the hand is now raised.
|
|
136
|
+
*/
|
|
137
|
+
onHandRaise(cb: (participantId: string, raised: boolean) => void): void;
|
|
138
|
+
/**
|
|
139
|
+
* Returns the current participant roster (including the bot).
|
|
140
|
+
*
|
|
141
|
+
* @returns The current participants.
|
|
142
|
+
*/
|
|
143
|
+
getParticipants(): Promise<TeamsParticipant[]>;
|
|
144
|
+
/**
|
|
145
|
+
* Posts a message to the Teams meeting chat thread (everyone).
|
|
146
|
+
*
|
|
147
|
+
* @param text The chat message text.
|
|
148
|
+
*/
|
|
149
|
+
postChatMessage(text: string): Promise<void>;
|
|
150
|
+
/**
|
|
151
|
+
* Mutes a participant (requires the bot be an organizer/presenter with the relevant policy).
|
|
152
|
+
*
|
|
153
|
+
* @param participantId The participant to mute.
|
|
154
|
+
*/
|
|
155
|
+
muteParticipant(participantId: string): Promise<void>;
|
|
156
|
+
/**
|
|
157
|
+
* Registers a callback fired when the meeting/call ends (organizer ended / call terminated).
|
|
158
|
+
* "Latest handler wins."
|
|
159
|
+
*
|
|
160
|
+
* @param cb Invoked when the meeting has ended.
|
|
161
|
+
*/
|
|
162
|
+
onMeetingEnded(cb: () => void): void;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* A factory that constructs an {@link ITeamsMeetingSdk} for a session — the creation seam (mirroring
|
|
166
|
+
* Gemini's `connectLiveSession`). Production supplies a factory that builds the real ACS calling-bot /
|
|
167
|
+
* Graph adapter from resolved config; tests supply one that returns a `FakeTeamsSdk`.
|
|
168
|
+
*
|
|
169
|
+
* @param config The resolved provider/session configuration (tenant, credential refs already resolved upstream).
|
|
170
|
+
* @returns The Teams SDK instance to drive the meeting with.
|
|
171
|
+
*/
|
|
172
|
+
export type TeamsMeetingSdkFactory = (config?: Record<string, unknown>) => ITeamsMeetingSdk;
|
|
173
|
+
//# sourceMappingURL=teams-sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams-sdk.d.ts","sourceRoot":"","sources":["../src/teams-sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,uGAAuG;AACvG,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,CAAC;AAE1E;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,oGAAoG;IACpG,aAAa,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,mHAAmH;IACnH,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wGAAwG;AACxG,MAAM,WAAW,eAAe;IAC5B,0CAA0C;IAC1C,GAAG,EAAE,WAAW,CAAC;IACjB,qFAAqF;IACrF,aAAa,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,mGAAmG;AACnG,MAAM,WAAW,aAAa;IAC1B,6FAA6F;IAC7F,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qFAAqF;AACrF,MAAM,WAAW,eAAe;IAC5B,0DAA0D;IAC1D,gBAAgB,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAEpD,qFAAqF;IACrF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;OAKG;IACH,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IAEvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI,CAAC;IAEzD;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,gBAAgB,KAAK,IAAI,GAAG,IAAI,CAAC;IAErE;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAE9D;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAExE;;;;OAIG;IACH,eAAe,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAE/C;;;;OAIG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;;;OAIG;IACH,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtD;;;;;OAKG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CACxC;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The injectable **Microsoft Teams calling-bot SDK seam** — the minimal set of operations
|
|
3
|
+
* {@link import('./teams-bridge.js').TeamsBridge} needs from Teams, declared as an interface so the driver
|
|
4
|
+
* builds and unit-tests against an in-memory fake with **no network and no real Teams / Azure
|
|
5
|
+
* Communication Services SDK**.
|
|
6
|
+
*
|
|
7
|
+
* ## Production binding (TODO at deployment)
|
|
8
|
+
* In production this interface is bound to the **Azure Communication Services (ACS) calling-bot** SDK
|
|
9
|
+
* plus the **Microsoft Graph cloud-communications API** (the `/communications/calls` "application-hosted
|
|
10
|
+
* media" bot model) so the bot can join a Teams meeting, pull per-participant PCM audio for diarization,
|
|
11
|
+
* push synthesized audio back, observe roster + raised-hand events, and post to the Teams meeting chat.
|
|
12
|
+
* The named operations map to the SDK as follows:
|
|
13
|
+
* - {@link join} / {@link leave} → the Graph `POST /communications/calls` (join meeting via the join
|
|
14
|
+
* URL / meeting coordinates) and the call's `DELETE` (leave) lifecycle.
|
|
15
|
+
* - {@link sendAudioFrame} → the ACS application-hosted-media outbound audio-socket (the bot's voice in).
|
|
16
|
+
* - {@link onAudioFrame} → the ACS per-participant inbound audio-socket callback (the source of speaker
|
|
17
|
+
* labels for diarization — Teams provides participant attribution on the media stream).
|
|
18
|
+
* - {@link onParticipantJoin} / {@link onParticipantLeave} / {@link getParticipants} → the call's
|
|
19
|
+
* `participants` collection + the `participantsUpdated` change notifications.
|
|
20
|
+
* - {@link onHandRaise} → the meeting's raised-hand signal. ⚠️ Partial: Teams surfaces raised hands in
|
|
21
|
+
* the meeting UI, but a clean per-participant *event* over the calling-bot API is not guaranteed on
|
|
22
|
+
* every tenant/build; the adapter wires it where the platform exposes it and otherwise no-ops.
|
|
23
|
+
* - {@link postChatMessage} → the Graph `POST /chats/{id}/messages` against the meeting's chat thread.
|
|
24
|
+
* - {@link muteParticipant} → the call's `participant:mute` action (requires the bot be an organizer /
|
|
25
|
+
* presenter with the relevant policy).
|
|
26
|
+
* - {@link onMeetingEnded} → the call's `callEnded` / `terminated` status notification.
|
|
27
|
+
*
|
|
28
|
+
* Binding the real SDK is a thin adapter that implements this interface; the driver and its tests do
|
|
29
|
+
* not change. **None of the ACS/Graph SDK types leak into this package.**
|
|
30
|
+
*
|
|
31
|
+
* See `/plans/realtime/realtime-bridges-architecture.md` §3, §8 (Microsoft Teams row) and
|
|
32
|
+
* `/guides/REALTIME_BRIDGES_GUIDE.md`.
|
|
33
|
+
*/
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=teams-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams-sdk.js","sourceRoot":"","sources":["../src/teams-sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ai-bridge-teams",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "5.42.0",
|
|
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
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"/dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"start": "ts-node-dev src/index.ts",
|
|
13
|
+
"build": "tsc && tsc-alias -f",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest"
|
|
16
|
+
},
|
|
17
|
+
"author": "MemberJunction.com",
|
|
18
|
+
"license": "ISC",
|
|
19
|
+
"dependencies": {
|
|
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
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "24.10.11",
|
|
27
|
+
"ts-node-dev": "^2.0.0",
|
|
28
|
+
"typescript": "^5.9.3",
|
|
29
|
+
"vitest": "^4.0.18"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/MemberJunction/MJ"
|
|
34
|
+
}
|
|
10
35
|
}
|