@absolutejs/meeting 0.0.1-beta.4 → 0.0.1-beta.6
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 +1 -1
- package/dist/emitter.d.ts +16 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +68 -35
- package/dist/manifest.d.ts +2 -0
- package/dist/manifest.js +8666 -0
- package/dist/manifest.json +247 -0
- package/dist/meeting.d.ts +18 -1
- package/dist/source.d.ts +52 -1
- package/package.json +18 -4
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
{
|
|
2
|
+
"contract": 1,
|
|
3
|
+
"identity": {
|
|
4
|
+
"accent": "#f97316",
|
|
5
|
+
"category": "voice",
|
|
6
|
+
"description": "Meeting-bot core: join a call through a `MeetingSource` platform adapter (`@absolutejs/meeting-*`), transcribe it live with the `@absolutejs/voice` scribe, and surface diarized turns, the participant roster, and call chat for analysis (deal coaching, summaries, action items). The bot can also speak into the call and post chat where the platform allows.",
|
|
7
|
+
"docsUrl": "https://github.com/absolutejs/meeting",
|
|
8
|
+
"name": "@absolutejs/meeting",
|
|
9
|
+
"tagline": "Put a bot in your meetings — live transcripts and analysis."
|
|
10
|
+
},
|
|
11
|
+
"implements": [
|
|
12
|
+
{
|
|
13
|
+
"contract": "meeting/source",
|
|
14
|
+
"factory": "createBufferMeetingSource",
|
|
15
|
+
"from": "@absolutejs/meeting",
|
|
16
|
+
"settings": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"properties": {
|
|
19
|
+
"chunkMs": {
|
|
20
|
+
"description": "How often a slice of the buffer is emitted, in milliseconds. Default 40.",
|
|
21
|
+
"minimum": 1,
|
|
22
|
+
"title": "Chunk cadence",
|
|
23
|
+
"type": "number"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"title": "In-memory audio buffer (testing without a live platform)",
|
|
28
|
+
"wiring": {
|
|
29
|
+
"code": "createBufferMeetingSource({\n\tchunkMs: ${settings.chunkMs},\n\tformat: { channels: 1, container: 'raw', encoding: 'pcm_s16le', sampleRateHz: 16000 },\n\t// TODO: supply raw PCM matching `format` (e.g. a recorded test fixture).\n\tpcm: new Uint8Array(0)\n})",
|
|
30
|
+
"imports": [
|
|
31
|
+
{
|
|
32
|
+
"from": "@absolutejs/meeting",
|
|
33
|
+
"names": [
|
|
34
|
+
"createBufferMeetingSource"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"settings": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"properties": {
|
|
44
|
+
"languageStrategy": {
|
|
45
|
+
"description": "What languages the calls are in. Auto-detect works for most teams; pin a language for better accuracy in single-language calls.",
|
|
46
|
+
"title": "Meeting languages",
|
|
47
|
+
"anyOf": [
|
|
48
|
+
{
|
|
49
|
+
"type": "object",
|
|
50
|
+
"required": [
|
|
51
|
+
"mode"
|
|
52
|
+
],
|
|
53
|
+
"properties": {
|
|
54
|
+
"allowedLanguages": {
|
|
55
|
+
"type": "array",
|
|
56
|
+
"items": {
|
|
57
|
+
"type": "string"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"mode": {
|
|
61
|
+
"const": "auto-detect",
|
|
62
|
+
"type": "string"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"type": "object",
|
|
68
|
+
"required": [
|
|
69
|
+
"mode",
|
|
70
|
+
"primaryLanguage"
|
|
71
|
+
],
|
|
72
|
+
"properties": {
|
|
73
|
+
"mode": {
|
|
74
|
+
"const": "fixed",
|
|
75
|
+
"type": "string"
|
|
76
|
+
},
|
|
77
|
+
"primaryLanguage": {
|
|
78
|
+
"type": "string"
|
|
79
|
+
},
|
|
80
|
+
"secondaryLanguages": {
|
|
81
|
+
"type": "array",
|
|
82
|
+
"items": {
|
|
83
|
+
"type": "string"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"type": "object",
|
|
90
|
+
"required": [
|
|
91
|
+
"mode",
|
|
92
|
+
"secondaryLanguages"
|
|
93
|
+
],
|
|
94
|
+
"properties": {
|
|
95
|
+
"mode": {
|
|
96
|
+
"const": "allow-switching",
|
|
97
|
+
"type": "string"
|
|
98
|
+
},
|
|
99
|
+
"primaryLanguage": {
|
|
100
|
+
"type": "string"
|
|
101
|
+
},
|
|
102
|
+
"secondaryLanguages": {
|
|
103
|
+
"type": "array",
|
|
104
|
+
"items": {
|
|
105
|
+
"type": "string"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
"phraseHints": {
|
|
113
|
+
"description": "Names, products, and jargon the transcriber should recognize — improves accuracy on words unique to your business.",
|
|
114
|
+
"title": "Vocabulary hints",
|
|
115
|
+
"type": "array",
|
|
116
|
+
"items": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"required": [
|
|
119
|
+
"text"
|
|
120
|
+
],
|
|
121
|
+
"properties": {
|
|
122
|
+
"aliases": {
|
|
123
|
+
"type": "array",
|
|
124
|
+
"items": {
|
|
125
|
+
"type": "string"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"boost": {
|
|
129
|
+
"type": "number"
|
|
130
|
+
},
|
|
131
|
+
"text": {
|
|
132
|
+
"type": "string"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"slots": {
|
|
140
|
+
"source": {
|
|
141
|
+
"configPath": "source",
|
|
142
|
+
"contract": "meeting/source",
|
|
143
|
+
"description": "The platform the bot joins calls on",
|
|
144
|
+
"known": [
|
|
145
|
+
"@absolutejs/meeting-recall",
|
|
146
|
+
"@absolutejs/meeting-discord",
|
|
147
|
+
"@absolutejs/meeting#buffer"
|
|
148
|
+
],
|
|
149
|
+
"required": true
|
|
150
|
+
},
|
|
151
|
+
"stt": {
|
|
152
|
+
"configPath": "stt",
|
|
153
|
+
"contract": "voice/stt",
|
|
154
|
+
"description": "Who turns the call audio into text",
|
|
155
|
+
"known": [
|
|
156
|
+
"@absolutejs/voice-deepgram"
|
|
157
|
+
],
|
|
158
|
+
"required": true
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"wiring": [
|
|
162
|
+
{
|
|
163
|
+
"description": "The bot joins the call via the source adapter; the scribe streams back diarized turns and the final transcript.",
|
|
164
|
+
"id": "default",
|
|
165
|
+
"server": {
|
|
166
|
+
"code": "const meeting = await createMeeting({\n\tlanguageStrategy: ${settings.languageStrategy},\n\tphraseHints: ${settings.phraseHints},\n\tsessionId: crypto.randomUUID(),\n\tsource: ${slot.source},\n\tstt: ${slot.stt}\n});\n\nmeeting.on('turn', ({ turn }) => {\n\t// TODO: stream diarized turns to your analyzer / UI.\n});\nmeeting.on('end', ({ transcript }) => {\n\t// TODO: persist or analyze the full transcript.\n});\n\nawait meeting.start(); // the bot joins the call",
|
|
167
|
+
"imports": [
|
|
168
|
+
{
|
|
169
|
+
"from": "@absolutejs/meeting",
|
|
170
|
+
"names": [
|
|
171
|
+
"createMeeting"
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
"placement": "module-scope"
|
|
176
|
+
},
|
|
177
|
+
"title": "Join a call and transcribe it live"
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
"tools": {
|
|
181
|
+
"leave_meeting": {
|
|
182
|
+
"annotations": {
|
|
183
|
+
"destructiveHint": true,
|
|
184
|
+
"idempotentHint": true
|
|
185
|
+
},
|
|
186
|
+
"description": "Make the bot leave the call, finalize the transcript, and end the session.",
|
|
187
|
+
"input": {
|
|
188
|
+
"type": "object",
|
|
189
|
+
"properties": {
|
|
190
|
+
"reason": {
|
|
191
|
+
"type": "string"
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"kind": "runtime"
|
|
196
|
+
},
|
|
197
|
+
"meeting_participants": {
|
|
198
|
+
"annotations": {
|
|
199
|
+
"readOnlyHint": true
|
|
200
|
+
},
|
|
201
|
+
"description": "List the participants the call platform has reported for this meeting.",
|
|
202
|
+
"input": {
|
|
203
|
+
"type": "object",
|
|
204
|
+
"properties": {}
|
|
205
|
+
},
|
|
206
|
+
"kind": "runtime"
|
|
207
|
+
},
|
|
208
|
+
"meeting_transcript": {
|
|
209
|
+
"annotations": {
|
|
210
|
+
"readOnlyHint": true
|
|
211
|
+
},
|
|
212
|
+
"description": "Read the diarized transcript so far — the most recent turns, each with its speaker and (when known) the resolved participant.",
|
|
213
|
+
"input": {
|
|
214
|
+
"type": "object",
|
|
215
|
+
"properties": {
|
|
216
|
+
"limit": {
|
|
217
|
+
"default": 50,
|
|
218
|
+
"maximum": 200,
|
|
219
|
+
"minimum": 1,
|
|
220
|
+
"type": "integer"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
"kind": "runtime"
|
|
225
|
+
},
|
|
226
|
+
"send_chat_message": {
|
|
227
|
+
"annotations": {
|
|
228
|
+
"openWorldHint": true
|
|
229
|
+
},
|
|
230
|
+
"description": "Post a text message into the call chat as the bot. Fails cleanly when the platform adapter can't write chat (check first: not every source supports it).",
|
|
231
|
+
"input": {
|
|
232
|
+
"type": "object",
|
|
233
|
+
"required": [
|
|
234
|
+
"text"
|
|
235
|
+
],
|
|
236
|
+
"properties": {
|
|
237
|
+
"text": {
|
|
238
|
+
"maxLength": 2000,
|
|
239
|
+
"minLength": 1,
|
|
240
|
+
"type": "string"
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"kind": "runtime"
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
package/dist/meeting.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type STTAdapter, type VoiceLanguageStrategy, type VoiceLexiconEntry, type VoicePhraseHint, type VoiceScribeTurn } from "@absolutejs/voice";
|
|
2
|
-
import type { MeetingParticipant, MeetingSource, SpeakAudio } from "./source";
|
|
2
|
+
import type { ChatMessage, MeetingCapabilities, MeetingParticipant, MeetingSource, SpeakAudio } from "./source";
|
|
3
3
|
export type MeetingTurn = VoiceScribeTurn & {
|
|
4
4
|
/** Resolved participant for this turn, when the source identified speakers. */
|
|
5
5
|
participant?: MeetingParticipant;
|
|
@@ -8,8 +8,15 @@ export type MeetingEventMap = {
|
|
|
8
8
|
turn: {
|
|
9
9
|
turn: MeetingTurn;
|
|
10
10
|
};
|
|
11
|
+
/** Roster update. `status` mirrors the source: "joined"/absent on appear,
|
|
12
|
+
* "left" when a participant leaves the call. */
|
|
11
13
|
participant: {
|
|
12
14
|
participant: MeetingParticipant;
|
|
15
|
+
status?: "joined" | "left";
|
|
16
|
+
};
|
|
17
|
+
/** A text message arrived in the call chat. */
|
|
18
|
+
chat: {
|
|
19
|
+
message: ChatMessage;
|
|
13
20
|
};
|
|
14
21
|
end: {
|
|
15
22
|
reason?: string;
|
|
@@ -34,6 +41,16 @@ export type MeetingSession = {
|
|
|
34
41
|
/** Cut the bot's in-progress speech (barge-in). No-op when the source can't
|
|
35
42
|
* inject/stop audio or nothing is playing. */
|
|
36
43
|
stopSpeaking: () => Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Post a text message INTO the call chat. Delegates to the source; throws if
|
|
46
|
+
* the underlying adapter doesn't implement `sendChat`. `opts.system` is a hint
|
|
47
|
+
* for platforms that distinguish system messages (ignored elsewhere).
|
|
48
|
+
*/
|
|
49
|
+
sendChat: (text: string, opts?: {
|
|
50
|
+
system?: boolean;
|
|
51
|
+
}) => Promise<void>;
|
|
52
|
+
/** What the underlying source can do (speak / chat). */
|
|
53
|
+
readonly capabilities: MeetingCapabilities;
|
|
37
54
|
getTranscript: () => MeetingTurn[];
|
|
38
55
|
getParticipants: () => MeetingParticipant[];
|
|
39
56
|
};
|
package/dist/source.d.ts
CHANGED
|
@@ -7,6 +7,36 @@ export type MeetingParticipant = {
|
|
|
7
7
|
platform?: string;
|
|
8
8
|
metadata?: Record<string, unknown>;
|
|
9
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* A text message in the call's chat. `kind` distinguishes ordinary messages
|
|
12
|
+
* from emoji reactions and platform/system notices; everything but `text` is
|
|
13
|
+
* best-effort and may be absent depending on what the source can report.
|
|
14
|
+
*/
|
|
15
|
+
export type ChatMessage = {
|
|
16
|
+
/** The message body (or reaction emoji / system text). */
|
|
17
|
+
text: string;
|
|
18
|
+
/** What sort of chat event this is. Defaults to a normal "message". */
|
|
19
|
+
kind?: "message" | "reaction" | "system";
|
|
20
|
+
/** Resolved sender, when the source identified them. */
|
|
21
|
+
author?: MeetingParticipant;
|
|
22
|
+
/** Raw platform sender id, even when the full participant isn't resolved. */
|
|
23
|
+
authorId?: string;
|
|
24
|
+
/** Epoch ms the message was sent, when the source reports it. */
|
|
25
|
+
timestamp?: number;
|
|
26
|
+
/** Platform channel/thread id the message belongs to, when applicable. */
|
|
27
|
+
channelId?: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Which in-call outputs a source supports. Mirrors the optional `speak` /
|
|
31
|
+
* `sendChat` members so a consumer can branch on capabilities up front instead
|
|
32
|
+
* of probing for thrown "not implemented" errors.
|
|
33
|
+
*/
|
|
34
|
+
export type MeetingCapabilities = {
|
|
35
|
+
/** The bot can play audio INTO the call (`speak`). */
|
|
36
|
+
canSpeak: boolean;
|
|
37
|
+
/** The bot can post text into the call chat (`sendChat`). */
|
|
38
|
+
canChat: boolean;
|
|
39
|
+
};
|
|
10
40
|
/**
|
|
11
41
|
* Audio the bot wants to play INTO the call. Adapters declare which formats
|
|
12
42
|
* they accept (Recall: mp3; Discord: pcm); a TypeError is the right signal
|
|
@@ -29,9 +59,16 @@ export type MeetingSourceEventMap = {
|
|
|
29
59
|
chunk: AudioChunk;
|
|
30
60
|
participant?: string;
|
|
31
61
|
};
|
|
32
|
-
/** Roster update — someone joined / was identified.
|
|
62
|
+
/** Roster update — someone joined / left / was identified. `status` signals
|
|
63
|
+
* the transition: "joined" (or absent — the historical behavior) when a
|
|
64
|
+
* participant appears/is identified, "left" when they leave the call. */
|
|
33
65
|
participant: {
|
|
34
66
|
participant: MeetingParticipant;
|
|
67
|
+
status?: "joined" | "left";
|
|
68
|
+
};
|
|
69
|
+
/** A text message arrived in the call chat. */
|
|
70
|
+
chat: {
|
|
71
|
+
message: ChatMessage;
|
|
35
72
|
};
|
|
36
73
|
/** The call ended (everyone left, host stopped, etc.). */
|
|
37
74
|
end: {
|
|
@@ -68,4 +105,18 @@ export type MeetingSource = {
|
|
|
68
105
|
* `meeting.stopSpeaking()` then no-ops.
|
|
69
106
|
*/
|
|
70
107
|
stopSpeaking?: () => Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Post a text message INTO the call chat. Optional — adapters that can't write
|
|
110
|
+
* chat simply don't implement it; `meeting.sendChat()` will throw a clear
|
|
111
|
+
* error in that case. `opts.system` is a hint for platforms that distinguish
|
|
112
|
+
* system/announcement messages from ordinary ones (ignored elsewhere).
|
|
113
|
+
*/
|
|
114
|
+
sendChat?: (text: string, opts?: {
|
|
115
|
+
system?: boolean;
|
|
116
|
+
}) => Promise<void>;
|
|
117
|
+
/**
|
|
118
|
+
* What this source can do (speak / chat). Optional — when absent, consumers
|
|
119
|
+
* fall back to probing the presence of `speak` / `sendChat`.
|
|
120
|
+
*/
|
|
121
|
+
readonly capabilities?: MeetingCapabilities;
|
|
71
122
|
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@absolutejs/meeting",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.6",
|
|
4
4
|
"description": "Meeting-bot core for AbsoluteJS — join a call (via a source adapter), transcribe it live with the voice scribe, and surface diarized turns + participants for analysis",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/absolutejs/meeting.git"
|
|
8
8
|
},
|
|
9
|
+
"homepage": "https://github.com/absolutejs/meeting",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/absolutejs/meeting/issues"
|
|
12
|
+
},
|
|
9
13
|
"files": [
|
|
10
14
|
"dist",
|
|
11
15
|
"README.md"
|
|
@@ -16,19 +20,29 @@
|
|
|
16
20
|
".": {
|
|
17
21
|
"import": "./dist/index.js",
|
|
18
22
|
"types": "./dist/index.d.ts"
|
|
19
|
-
}
|
|
23
|
+
},
|
|
24
|
+
"./manifest": {
|
|
25
|
+
"import": "./dist/manifest.js",
|
|
26
|
+
"types": "./dist/manifest.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./manifest.json": "./dist/manifest.json"
|
|
20
29
|
},
|
|
21
30
|
"license": "BSL-1.1",
|
|
22
31
|
"author": "Alex Kahn",
|
|
32
|
+
"absolutejs": {
|
|
33
|
+
"manifestContract": 1
|
|
34
|
+
},
|
|
23
35
|
"scripts": {
|
|
24
|
-
"build": "rm -rf dist && bun build ./src/index.ts --outdir dist --target bun --external @absolutejs/voice && tsc --emitDeclarationOnly --project tsconfig.json",
|
|
36
|
+
"build": "rm -rf dist && bun build ./src/index.ts ./src/manifest.ts --outdir dist --root src --target bun --external @absolutejs/voice && tsc --emitDeclarationOnly --project tsconfig.json && absolute-manifest emit",
|
|
25
37
|
"format": "prettier --write \"./**/*.{js,ts,json,md}\"",
|
|
26
38
|
"release": "bun run format && bun run build && bun publish",
|
|
27
39
|
"test": "bun test",
|
|
28
40
|
"typecheck": "bun run tsc --noEmit"
|
|
29
41
|
},
|
|
30
42
|
"dependencies": {
|
|
31
|
-
"@absolutejs/
|
|
43
|
+
"@absolutejs/manifest": "^0.1.0",
|
|
44
|
+
"@absolutejs/voice": "0.0.22-beta.550",
|
|
45
|
+
"@sinclair/typebox": "^0.34.0"
|
|
32
46
|
},
|
|
33
47
|
"devDependencies": {
|
|
34
48
|
"@types/bun": "1.3.9",
|