|
4 | 4 | import { AccessToken } from 'livekit-server-sdk'; |
5 | 5 | import { WebSocket } from 'ws'; |
6 | 6 | import { APIConnectionError, APIStatusError } from '../_exceptions.js'; |
| 7 | +import { getJobContext } from '../job.js'; |
| 8 | +import { version } from '../version.js'; |
7 | 9 |
|
8 | 10 | export type AnyString = string & NonNullable<unknown>; |
9 | 11 |
|
@@ -46,13 +48,38 @@ export async function createAccessToken( |
46 | 48 | return await token.toJwt(); |
47 | 49 | } |
48 | 50 |
|
| 51 | +/** |
| 52 | + * Build metadata headers for inference requests. |
| 53 | + * Includes SDK version/platform, and optionally room/job IDs from the current job context. |
| 54 | + */ |
| 55 | +export function buildMetadataHeaders(): Record<string, string> { |
| 56 | + const headers: Record<string, string> = { |
| 57 | + 'User-Agent': `livekit-agents-js/${version} (node ${process.version})`, |
| 58 | + }; |
| 59 | + |
| 60 | + try { |
| 61 | + const ctx = getJobContext(); |
| 62 | + const roomSid = ctx.job.room?.sid; |
| 63 | + if (roomSid) { |
| 64 | + headers['X-LiveKit-Room-Id'] = roomSid; |
| 65 | + } |
| 66 | + if (ctx.job.id) { |
| 67 | + headers['X-LiveKit-Job-Id'] = ctx.job.id; |
| 68 | + } |
| 69 | + } catch { |
| 70 | + // No job context available — standalone inference usage |
| 71 | + } |
| 72 | + |
| 73 | + return headers; |
| 74 | +} |
| 75 | + |
49 | 76 | export async function connectWs( |
50 | 77 | url: string, |
51 | 78 | headers: Record<string, string>, |
52 | 79 | timeoutMs: number, |
53 | 80 | ): Promise<WebSocket> { |
54 | 81 | return new Promise<WebSocket>((resolve, reject) => { |
55 | | - const socket = new WebSocket(url, { headers: headers }); |
| 82 | + const socket = new WebSocket(url, { headers: { ...buildMetadataHeaders(), ...headers } }); |
56 | 83 |
|
57 | 84 | const timeout = setTimeout(() => { |
58 | 85 | reject(new APIConnectionError({ message: 'Timeout connecting to LiveKit WebSocket' })); |
|
0 commit comments