Skip to content

Commit a8663a6

Browse files
committed
map types
1 parent 8ca3200 commit a8663a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+545
-524
lines changed

packages/agents-core/package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,26 @@
1818
"scripts": {
1919
"generate-version": "printf \"// This file is auto-generated during build\\nexport const PACKAGE_VERSION = \\\"%s\\\";\\n\" \"$npm_package_version\" > src/version.ts",
2020
"prebuild": "pnpm run generate-version",
21-
"build": "BROWSERSLIST_ENV=modern microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react src/index.ts",
22-
"clean": "rm -rf ./dist",
23-
"dev": "pnpm run clean && pnpm run generate-version && BROWSERSLIST_ENV=development microbundle --jsx React.createElement --jsxFragment React.Fragment --jsxImportSource react src/index.ts -w -f modern",
21+
"build": "BROWSERSLIST_ENV=modern microbundle src/index.ts",
22+
"clean": "rm -rf ./dist ./src/version.ts",
23+
"dev": "pnpm run clean && pnpm run generate-version && BROWSERSLIST_ENV=development microbundle src/index.ts -w -f modern",
2424
"lint": "pnpm run lint:ts && pnpm run lint:es && pnpm run lint:prettier",
2525
"lint:ts": "tsc --noEmit --skipLibCheck",
2626
"lint:es": "pnpm exec eslint .",
2727
"lint:prettier": "prettier 'src/**/*.ts' --check",
2828
"prepublishOnly": "pnpm run build",
29-
"test": "vitest"
29+
"test": "vitest",
30+
"check-types": "tsc --noEmit"
3031
},
3132
"keywords": [],
3233
"author": "ElevenLabs",
3334
"license": "MIT",
3435
"devDependencies": {
35-
"@types/node-wav": "^0.0.3",
36+
"@elevenlabs/typescript-config": "workspace:*",
3637
"@vitest/browser": "^3.0.5",
3738
"eslint": "^9.8.0",
3839
"microbundle": "^0.15.1",
3940
"mock-socket": "^9.3.1",
40-
"node-wav": "^0.0.2",
4141
"playwright": "^1.54.1",
4242
"typescript": "^5.5.4",
4343
"vitest": "^3.0.5"
@@ -48,6 +48,7 @@
4848
"directory": "packages/client"
4949
},
5050
"dependencies": {
51+
"@elevenlabs/types": "workspace:*",
5152
"livekit-client": "^2.11.4"
5253
}
5354
}

packages/agents-core/src/BaseConversation.ts

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type {
44
OnDisconnectCallback,
55
SessionConfig,
66
FormatConfig,
7-
} from "./utils/BaseConnection";
7+
} from './utils/BaseConnection';
88
import type {
99
AgentAudioEvent,
1010
AgentResponseEvent,
@@ -14,18 +14,19 @@ import type {
1414
InterruptionEvent,
1515
UserTranscriptionEvent,
1616
VadScoreEvent,
17-
} from "./utils/events";
18-
import type { InputConfig } from "./utils/input";
17+
} from './utils/events';
18+
import type { InputConfig } from './utils/input';
19+
import { FeedbackScore } from './utils/events';
1920

20-
export type Role = "user" | "ai";
21+
export type Role = 'user' | 'ai';
2122

22-
export type Mode = "speaking" | "listening";
23+
export type Mode = 'speaking' | 'listening';
2324

2425
export type Status =
25-
| "connecting"
26-
| "connected"
27-
| "disconnecting"
28-
| "disconnected";
26+
| 'connecting'
27+
| 'connected'
28+
| 'disconnecting'
29+
| 'disconnected';
2930

3031
export type Options = SessionConfig &
3132
Callbacks &
@@ -42,7 +43,7 @@ export type ClientToolsConfig = {
4243
clientTools: Record<
4344
string,
4445
(
45-
parameters: any
46+
parameters: any,
4647
) => Promise<string | number | void> | string | number | void
4748
>;
4849
};
@@ -59,7 +60,7 @@ export type Callbacks = {
5960
onStatusChange?: (prop: { status: Status }) => void;
6061
onCanSendFeedbackChange?: (prop: { canSendFeedback: boolean }) => void;
6162
onUnhandledClientToolCall?: (
62-
params: ClientToolCallEvent["client_tool_call"]
63+
params: ClientToolCallEvent['client_tool_call'],
6364
) => void;
6465
onVadScore?: (props: { vadScore: number }) => void;
6566
};
@@ -68,8 +69,8 @@ const EMPTY_FREQUENCY_DATA = new Uint8Array(0);
6869

6970
export class BaseConversation {
7071
protected lastInterruptTimestamp = 0;
71-
protected mode: Mode = "listening";
72-
protected status: Status = "connecting";
72+
protected mode: Mode = 'listening';
73+
protected status: Status = 'connecting';
7374
protected volume = 1;
7475
protected currentEventId = 1;
7576
protected lastFeedbackEventId = 0;
@@ -93,26 +94,26 @@ export class BaseConversation {
9394

9495
protected constructor(
9596
protected readonly options: Options,
96-
protected readonly connection: BaseConnection
97+
protected readonly connection: BaseConnection,
9798
) {
9899
if (this.options.onConnect) {
99100
this.options.onConnect({ conversationId: connection.conversationId });
100101
}
101102
this.connection.onMessage(this.onMessage);
102103
this.connection.onDisconnect(this.endSessionWithDetails);
103104
this.connection.onModeChange(mode => this.updateMode(mode));
104-
this.updateStatus("connected");
105+
this.updateStatus('connected');
105106
}
106107

107108
public endSession() {
108-
return this.endSessionWithDetails({ reason: "user" });
109+
return this.endSessionWithDetails({ reason: 'user' });
109110
}
110111

111112
private endSessionWithDetails = async (details: DisconnectionDetails) => {
112-
if (this.status !== "connected" && this.status !== "connecting") return;
113-
this.updateStatus("disconnecting");
113+
if (this.status !== 'connected' && this.status !== 'connecting') return;
114+
this.updateStatus('disconnecting');
114115
await this.handleEndSession();
115-
this.updateStatus("disconnected");
116+
this.updateStatus('disconnected');
116117
if (this.options.onDisconnect) {
117118
this.options.onDisconnect(details);
118119
}
@@ -159,7 +160,7 @@ export class BaseConversation {
159160
protected handleAgentResponse(event: AgentResponseEvent) {
160161
if (this.options.onMessage) {
161162
this.options.onMessage({
162-
source: "ai",
163+
source: 'ai',
163164
message: event.agent_response_event.agent_response,
164165
});
165166
}
@@ -168,18 +169,18 @@ export class BaseConversation {
168169
protected handleUserTranscript(event: UserTranscriptionEvent) {
169170
if (this.options.onMessage) {
170171
this.options.onMessage({
171-
source: "user",
172+
source: 'user',
172173
message: event.user_transcription_event.user_transcript,
173174
});
174175
}
175176
}
176177

177178
protected handleTentativeAgentResponse(
178-
event: InternalTentativeAgentResponseEvent
179+
event: InternalTentativeAgentResponseEvent,
179180
) {
180181
if (this.options.onDebug) {
181182
this.options.onDebug({
182-
type: "tentative_agent_response",
183+
type: 'tentative_agent_response',
183184
response:
184185
event.tentative_agent_response_internal_event
185186
.tentative_agent_response,
@@ -199,21 +200,21 @@ export class BaseConversation {
199200
if (
200201
Object.prototype.hasOwnProperty.call(
201202
this.options.clientTools,
202-
event.client_tool_call.tool_name
203+
event.client_tool_call.tool_name,
203204
)
204205
) {
205206
try {
206207
const result =
207208
(await this.options.clientTools[event.client_tool_call.tool_name](
208-
event.client_tool_call.parameters
209-
)) ?? "Client tool execution successful."; // default client-tool call response
209+
event.client_tool_call.parameters,
210+
)) ?? 'Client tool execution successful.'; // default client-tool call response
210211

211212
// The API expects result to be a string, so we need to convert it if it's not already a string
212213
const formattedResult =
213-
typeof result === "object" ? JSON.stringify(result) : String(result);
214+
typeof result === 'object' ? JSON.stringify(result) : String(result);
214215

215216
this.connection.sendMessage({
216-
type: "client_tool_result",
217+
type: 'client_tool_result',
217218
tool_call_id: event.client_tool_call.tool_call_id,
218219
result: formattedResult,
219220
is_error: false,
@@ -223,10 +224,10 @@ export class BaseConversation {
223224
`Client tool execution failed with following error: ${(e as Error)?.message}`,
224225
{
225226
clientToolName: event.client_tool_call.tool_name,
226-
}
227+
},
227228
);
228229
this.connection.sendMessage({
229-
type: "client_tool_result",
230+
type: 'client_tool_result',
230231
tool_call_id: event.client_tool_call.tool_call_id,
231232
result: `Client tool execution failed: ${(e as Error)?.message}`,
232233
is_error: true,
@@ -243,10 +244,10 @@ export class BaseConversation {
243244
`Client tool with name ${event.client_tool_call.tool_name} is not defined on client`,
244245
{
245246
clientToolName: event.client_tool_call.tool_name,
246-
}
247+
},
247248
);
248249
this.connection.sendMessage({
249-
type: "client_tool_result",
250+
type: 'client_tool_result',
250251
tool_call_id: event.client_tool_call.tool_call_id,
251252
result: `Client tool with name ${event.client_tool_call.tool_name} is not defined on client`,
252253
is_error: true,
@@ -258,23 +259,23 @@ export class BaseConversation {
258259

259260
private onMessage = async (parsedEvent: IncomingSocketEvent) => {
260261
switch (parsedEvent.type) {
261-
case "interruption": {
262+
case 'interruption': {
262263
this.handleInterruption(parsedEvent);
263264
return;
264265
}
265-
case "agent_response": {
266+
case 'agent_response': {
266267
this.handleAgentResponse(parsedEvent);
267268
return;
268269
}
269-
case "user_transcript": {
270+
case 'user_transcript': {
270271
this.handleUserTranscript(parsedEvent);
271272
return;
272273
}
273-
case "internal_tentative_agent_response": {
274+
case 'internal_tentative_agent_response': {
274275
this.handleTentativeAgentResponse(parsedEvent);
275276
return;
276277
}
277-
case "client_tool_call": {
278+
case 'client_tool_call': {
278279
try {
279280
await this.handleClientToolCall(parsedEvent);
280281
} catch (error) {
@@ -283,24 +284,24 @@ export class BaseConversation {
283284
{
284285
clientToolName: parsedEvent.client_tool_call.tool_name,
285286
toolCallId: parsedEvent.client_tool_call.tool_call_id,
286-
}
287+
},
287288
);
288289
}
289290
return;
290291
}
291-
case "audio": {
292+
case 'audio': {
292293
this.handleAudio(parsedEvent);
293294
return;
294295
}
295296

296-
case "vad_score": {
297+
case 'vad_score': {
297298
this.handleVadScore(parsedEvent);
298299
return;
299300
}
300301

301-
case "ping": {
302+
case 'ping': {
302303
this.connection.sendMessage({
303-
type: "pong",
304+
type: 'pong',
304305
event_id: parsedEvent.ping_event.event_id,
305306
});
306307
// parsedEvent.ping_event.ping_ms can be used on client side, for example
@@ -330,7 +331,7 @@ export class BaseConversation {
330331
}
331332

332333
public isOpen() {
333-
return this.status === "connected";
334+
return this.status === 'connected';
334335
}
335336

336337
public setVolume = ({ volume }: { volume: number }) => {
@@ -360,16 +361,16 @@ export class BaseConversation {
360361
public sendFeedback(like: boolean) {
361362
if (!this.canSendFeedback) {
362363
console.warn(
363-
this.lastFeedbackEventId === 0
364-
? "Cannot send feedback: the conversation has not started yet."
365-
: "Cannot send feedback: feedback has already been sent for the current response."
364+
this.lastFeedbackEventId === this.currentEventId
365+
? 'Cannot send feedback: feedback has already been sent for the current response.'
366+
: 'Cannot send feedback: no response has been received yet.',
366367
);
367368
return;
368369
}
369370

370371
this.connection.sendMessage({
371-
type: "feedback",
372-
score: like ? "like" : "dislike",
372+
type: 'feedback',
373+
score: like ? FeedbackScore.LIKE : FeedbackScore.DISLIKE,
373374
event_id: this.currentEventId,
374375
});
375376
this.lastFeedbackEventId = this.currentEventId;
@@ -378,27 +379,27 @@ export class BaseConversation {
378379

379380
public sendContextualUpdate(text: string) {
380381
this.connection.sendMessage({
381-
type: "contextual_update",
382+
type: 'contextual_update',
382383
text,
383384
});
384385
}
385386

386387
public sendUserMessage(text: string) {
387388
this.connection.sendMessage({
388-
type: "user_message",
389+
type: 'user_message',
389390
text,
390391
});
391392
}
392393

393394
public sendUserActivity() {
394395
this.connection.sendMessage({
395-
type: "user_activity",
396+
type: 'user_activity',
396397
});
397398
}
398399

399400
public sendMCPToolApprovalResult(toolCallId: string, isApproved: boolean) {
400401
this.connection.sendMessage({
401-
type: "mcp_tool_approval_result",
402+
type: 'mcp_tool_approval_result',
402403
tool_call_id: toolCallId,
403404
is_approved: isApproved,
404405
});

0 commit comments

Comments
 (0)