@meshagent/meshagent-agents 0.49.1 → 0.51.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/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## [0.51.0]
2
+ - Refactored the chat UI to split input from feed, simplifying thread and dataset views and removing suggestion-driven behavior.
3
+ - Updated the JavaScript entrypoint and related tests to match the slimmer chat experience.
4
+
5
+ ## [0.50.1]
6
+ - Stability
7
+
8
+ ## [0.50.0]
9
+ - Chat clients now support per-turn LLM authorization providers, and websocket chat tokens are optional for `auth=none` deployments.
10
+ - The typed client gained `connectLlm`, optional access-subject IDs, service-account principals, room and service enabled flags, `llm_quota_manager`, and the `router` project settings document.
11
+ - Chat-thread constructors now take a chat client instead of requiring a room client, which is a breaking signature change for callers.
12
+ - The Tailwind chat package was updated to `tailwindcss` 4.3.3, and the chat and thread UI was refactored for more reliable optimistic streaming plus richer attachment and thread handling.
13
+
1
14
  ## [0.49.1]
2
15
  - Stability
3
16
 
package/README.md CHANGED
@@ -123,7 +123,7 @@ import { WebSocketChatClient } from "@meshagent/meshagent-agents";
123
123
 
124
124
  const chat = new WebSocketChatClient({
125
125
  url: new URL("wss://example.test/messages"),
126
- token: participantToken,
126
+ token: participantToken, // Omit for a websocket-auth=none channel.
127
127
  participantName: "user@example.com",
128
128
  });
129
129
 
@@ -111,6 +111,17 @@ export declare class ToolChoice {
111
111
  static fromJson(json: JsonMap): ToolChoice;
112
112
  toJson(): JsonMap;
113
113
  }
114
+ export declare class LlmAuthorization {
115
+ readonly token: string;
116
+ readonly expiresAt: Date;
117
+ constructor({ token, expiresAt }: {
118
+ token: string;
119
+ expiresAt: Date;
120
+ });
121
+ get isExpired(): boolean;
122
+ static fromJson(json: JsonMap): LlmAuthorization;
123
+ toJson(): JsonMap;
124
+ }
114
125
  export declare class TurnMcpConfig {
115
126
  readonly servers: JsonMap[];
116
127
  constructor({ servers }?: {
@@ -381,6 +392,7 @@ export interface StartThread extends AgentMessage {
381
392
  readonly clientToolkits?: ClientToolkitDescription[];
382
393
  readonly toolkits?: Record<string, TurnToolkitConfig>;
383
394
  readonly toolChoice?: ToolChoice;
395
+ readonly llmAuthorization?: LlmAuthorization;
384
396
  }
385
397
  type StartThreadArguments = {
386
398
  messageId?: string;
@@ -398,6 +410,7 @@ type StartThreadArguments = {
398
410
  clientToolkits?: ClientToolkitDescription[];
399
411
  toolkits?: Record<string, TurnToolkitConfig>;
400
412
  toolChoice?: ToolChoice;
413
+ llmAuthorization?: LlmAuthorization;
401
414
  };
402
415
  export interface TurnStart extends AgentThreadMessage {
403
416
  readonly turnId?: string;
@@ -412,6 +425,7 @@ export interface TurnStart extends AgentThreadMessage {
412
425
  readonly clientToolkits?: ClientToolkitDescription[];
413
426
  readonly toolkits?: Record<string, TurnToolkitConfig>;
414
427
  readonly toolChoice?: ToolChoice;
428
+ readonly llmAuthorization?: LlmAuthorization;
415
429
  }
416
430
  type TurnStartArguments = {
417
431
  threadId: string;
@@ -429,6 +443,7 @@ type TurnStartArguments = {
429
443
  clientToolkits?: ClientToolkitDescription[];
430
444
  toolkits?: Record<string, TurnToolkitConfig>;
431
445
  toolChoice?: ToolChoice;
446
+ llmAuthorization?: LlmAuthorization;
432
447
  };
433
448
  export interface TurnSteer extends AgentThreadMessage {
434
449
  readonly turnId: string;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.agentFileContentEndedType = exports.agentFileContentDeltaType = exports.agentFileContentStartedType = exports.agentTextContentEndedType = exports.agentTextContentDeltaType = exports.agentTextContentStartedType = exports.agentReasoningContentEndedType = exports.agentReasoningContentDeltaType = exports.agentReasoningContentStartedType = exports.agentTurnEndedType = exports.agentTurnStartedType = exports.agentTurnSteerRejectedType = exports.agentTurnSteeredType = exports.agentTurnSteerAcceptedType = exports.agentTurnInterruptedType = exports.agentTurnInterruptAcceptedType = exports.agentTurnStartRejectedType = exports.agentTurnStartAcceptedType = exports.agentThreadClearedType = exports.agentModelChangedType = exports.agentModelChangeType = exports.agentModelsResponseType = exports.agentModelsRequestType = exports.agentCapabilitiesResponseType = exports.agentCapabilitiesRequestType = exports.agentThreadDeletedType = exports.agentThreadUpdatedType = exports.agentThreadCreatedType = exports.agentThreadListedType = exports.agentThreadUnwatchType = exports.agentThreadWatchType = exports.agentThreadListType = exports.agentThreadRenameType = exports.agentThreadDeleteType = exports.agentParticipantDisconnectType = exports.agentParticipantConnectType = exports.agentMessagesInjectType = exports.agentThreadCloseType = exports.agentThreadOpenType = exports.agentThreadStartRejectedType = exports.agentThreadLoadedType = exports.agentThreadStartedType = exports.agentThreadStartType = exports.agentRealtimeAudioCommitType = exports.agentRealtimeAudioChunkType = exports.agentThreadClearType = exports.agentTurnInterruptType = exports.agentTurnSteerType = exports.agentTurnStartType = exports.agentRoomMessageType = void 0;
4
- exports.AgentContextWindowUsage = exports.AgentGeneratedAudio = exports.AgentGeneratedImage = exports.AgentToolCallLogLine = exports.AgentRealtimeConnectionInfo = exports.AgentThreadListEntry = exports.AgentProviderInfo = exports.AgentModelInfo = exports.ToolkitCapabilities = exports.ToolkitToolCapabilities = exports.AgentError = exports.AgentAudioFormat = exports.TurnToolkitConfig = exports.ClientToolkitDescription = exports.TurnMcpConfig = exports.ToolChoice = exports.AgentFileContent = exports.agentClientToolCallResponseType = exports.agentSecretResponseType = exports.agentToolRejectType = exports.agentToolApproveType = exports.agentUsageUpdatedType = exports.agentContextCompactedType = exports.agentAudioInputSpeechEndedType = exports.agentAudioInputSpeechStartedType = exports.agentAudioTranscriptionFailedType = exports.agentAudioTranscriptionCompletedType = exports.agentAudioTranscriptionDeltaType = exports.agentAudioTranscriptionStartedType = exports.agentAudioGenerationFailedType = exports.agentAudioGenerationCompletedType = exports.agentAudioGenerationDeltaType = exports.agentAudioGenerationStartedType = exports.agentImageGenerationFailedType = exports.agentImageGenerationCompletedType = exports.agentImageGenerationPartialType = exports.agentImageGenerationStartedType = exports.agentThreadEventType = exports.agentConnectionStatusType = exports.agentThreadStatusType = exports.agentSecretRequestedType = exports.agentClientToolCallCancelledType = exports.agentClientToolCallRequestedType = exports.agentToolCallApprovalRequestedType = exports.agentToolCallEndedType = exports.agentToolCallLogDeltaType = exports.agentToolCallArgumentsDeltaType = exports.agentToolCallStartedType = exports.agentToolCallInProgressType = exports.agentToolCallPendingType = void 0;
5
- exports.AgentFileContentStarted = exports.AgentTextContentEnded = exports.AgentTextContentDelta = exports.AgentTextContentStarted = exports.AgentReasoningContentEnded = exports.AgentReasoningContentDelta = exports.AgentReasoningContentStarted = exports.ThreadStartRejected = exports.ThreadLoaded = exports.ThreadStarted = exports.TurnEnded = exports.TurnStarted = exports.TurnSteerRejected = exports.TurnSteered = exports.TurnSteerAccepted = exports.TurnInterrupted = exports.TurnInterruptAccepted = exports.TurnStartRejected = exports.TurnStartAccepted = exports.ThreadCleared = exports.AgentModelChanged = exports.ChangeModel = exports.ModelsResponse = exports.ModelsRequest = exports.CapabilitiesResponse = exports.CapabilitiesRequest = exports.ThreadDeleted = exports.ThreadUpdated = exports.ThreadCreated = exports.ThreadsListed = exports.UnwatchThreads = exports.WatchThreads = exports.ListThreads = exports.RenameThread = exports.DeleteThread = exports.ParticipantDisconnect = exports.ParticipantConnect = exports.InjectMessages = exports.CloseThread = exports.OpenThread = exports.ClearThread = exports.AgentRealtimeAudioCommit = exports.AgentRealtimeAudioChunk = exports.TurnInterrupt = exports.TurnSteer = exports.TurnStart = exports.StartThread = exports.AgentLLMMessage = exports.AgentThreadMessage = exports.AgentMessage = void 0;
6
- exports.AgentClientToolCallResponse = exports.AgentSecretResponse = exports.RejectAgentToolCall = exports.ApproveAgentToolCall = exports.AgentUsageUpdated = exports.AgentContextCompacted = exports.AgentAudioInputSpeechEnded = exports.AgentAudioInputSpeechStarted = exports.AgentAudioTranscriptionFailed = exports.AgentAudioTranscriptionCompleted = exports.AgentAudioTranscriptionDelta = exports.AgentAudioTranscriptionStarted = exports.AgentAudioGenerationFailed = exports.AgentAudioGenerationCompleted = exports.AgentAudioGenerationDelta = exports.AgentAudioGenerationStarted = exports.AgentImageGenerationFailed = exports.AgentImageGenerationCompleted = exports.AgentImageGenerationPartial = exports.AgentImageGenerationStarted = exports.AgentThreadEvent = exports.AgentConnectionStatus = exports.AgentThreadStatus = exports.AgentClientToolCallCancelled = exports.AgentClientToolCallRequested = exports.AgentSecretRequested = exports.AgentToolCallApprovalRequested = exports.AgentToolCallEnded = exports.AgentToolCallLogDelta = exports.AgentToolCallArgumentsDelta = exports.AgentToolCallStarted = exports.AgentToolCallInProgress = exports.AgentToolCallPending = exports.AgentFileContentEnded = exports.AgentFileContentDelta = void 0;
4
+ exports.AgentGeneratedAudio = exports.AgentGeneratedImage = exports.AgentToolCallLogLine = exports.AgentRealtimeConnectionInfo = exports.AgentThreadListEntry = exports.AgentProviderInfo = exports.AgentModelInfo = exports.ToolkitCapabilities = exports.ToolkitToolCapabilities = exports.AgentError = exports.AgentAudioFormat = exports.TurnToolkitConfig = exports.ClientToolkitDescription = exports.TurnMcpConfig = exports.LlmAuthorization = exports.ToolChoice = exports.AgentFileContent = exports.agentClientToolCallResponseType = exports.agentSecretResponseType = exports.agentToolRejectType = exports.agentToolApproveType = exports.agentUsageUpdatedType = exports.agentContextCompactedType = exports.agentAudioInputSpeechEndedType = exports.agentAudioInputSpeechStartedType = exports.agentAudioTranscriptionFailedType = exports.agentAudioTranscriptionCompletedType = exports.agentAudioTranscriptionDeltaType = exports.agentAudioTranscriptionStartedType = exports.agentAudioGenerationFailedType = exports.agentAudioGenerationCompletedType = exports.agentAudioGenerationDeltaType = exports.agentAudioGenerationStartedType = exports.agentImageGenerationFailedType = exports.agentImageGenerationCompletedType = exports.agentImageGenerationPartialType = exports.agentImageGenerationStartedType = exports.agentThreadEventType = exports.agentConnectionStatusType = exports.agentThreadStatusType = exports.agentSecretRequestedType = exports.agentClientToolCallCancelledType = exports.agentClientToolCallRequestedType = exports.agentToolCallApprovalRequestedType = exports.agentToolCallEndedType = exports.agentToolCallLogDeltaType = exports.agentToolCallArgumentsDeltaType = exports.agentToolCallStartedType = exports.agentToolCallInProgressType = exports.agentToolCallPendingType = void 0;
5
+ exports.AgentTextContentEnded = exports.AgentTextContentDelta = exports.AgentTextContentStarted = exports.AgentReasoningContentEnded = exports.AgentReasoningContentDelta = exports.AgentReasoningContentStarted = exports.ThreadStartRejected = exports.ThreadLoaded = exports.ThreadStarted = exports.TurnEnded = exports.TurnStarted = exports.TurnSteerRejected = exports.TurnSteered = exports.TurnSteerAccepted = exports.TurnInterrupted = exports.TurnInterruptAccepted = exports.TurnStartRejected = exports.TurnStartAccepted = exports.ThreadCleared = exports.AgentModelChanged = exports.ChangeModel = exports.ModelsResponse = exports.ModelsRequest = exports.CapabilitiesResponse = exports.CapabilitiesRequest = exports.ThreadDeleted = exports.ThreadUpdated = exports.ThreadCreated = exports.ThreadsListed = exports.UnwatchThreads = exports.WatchThreads = exports.ListThreads = exports.RenameThread = exports.DeleteThread = exports.ParticipantDisconnect = exports.ParticipantConnect = exports.InjectMessages = exports.CloseThread = exports.OpenThread = exports.ClearThread = exports.AgentRealtimeAudioCommit = exports.AgentRealtimeAudioChunk = exports.TurnInterrupt = exports.TurnSteer = exports.TurnStart = exports.StartThread = exports.AgentLLMMessage = exports.AgentThreadMessage = exports.AgentMessage = exports.AgentContextWindowUsage = void 0;
6
+ exports.AgentClientToolCallResponse = exports.AgentSecretResponse = exports.RejectAgentToolCall = exports.ApproveAgentToolCall = exports.AgentUsageUpdated = exports.AgentContextCompacted = exports.AgentAudioInputSpeechEnded = exports.AgentAudioInputSpeechStarted = exports.AgentAudioTranscriptionFailed = exports.AgentAudioTranscriptionCompleted = exports.AgentAudioTranscriptionDelta = exports.AgentAudioTranscriptionStarted = exports.AgentAudioGenerationFailed = exports.AgentAudioGenerationCompleted = exports.AgentAudioGenerationDelta = exports.AgentAudioGenerationStarted = exports.AgentImageGenerationFailed = exports.AgentImageGenerationCompleted = exports.AgentImageGenerationPartial = exports.AgentImageGenerationStarted = exports.AgentThreadEvent = exports.AgentConnectionStatus = exports.AgentThreadStatus = exports.AgentClientToolCallCancelled = exports.AgentClientToolCallRequested = exports.AgentSecretRequested = exports.AgentToolCallApprovalRequested = exports.AgentToolCallEnded = exports.AgentToolCallLogDelta = exports.AgentToolCallArgumentsDelta = exports.AgentToolCallStarted = exports.AgentToolCallInProgress = exports.AgentToolCallPending = exports.AgentFileContentEnded = exports.AgentFileContentDelta = exports.AgentFileContentStarted = void 0;
7
7
  exports.agentInputContent = agentInputContent;
8
8
  const meshagent_1 = require("@meshagent/meshagent");
9
9
  const uuid_1 = require("uuid");
@@ -333,6 +333,26 @@ class ToolChoice {
333
333
  }
334
334
  }
335
335
  exports.ToolChoice = ToolChoice;
336
+ class LlmAuthorization {
337
+ constructor({ token, expiresAt }) {
338
+ this.token = token;
339
+ this.expiresAt = expiresAt;
340
+ }
341
+ get isExpired() {
342
+ return this.expiresAt.getTime() <= Date.now();
343
+ }
344
+ static fromJson(json) {
345
+ const expiresAt = new Date(requiredString(json, "expires_at"));
346
+ if (Number.isNaN(expiresAt.getTime())) {
347
+ throw new TypeError("LLM authorization expires_at must be an ISO timestamp");
348
+ }
349
+ return new LlmAuthorization({ token: requiredString(json, "token"), expiresAt });
350
+ }
351
+ toJson() {
352
+ return { token: this.token, expires_at: this.expiresAt.toISOString() };
353
+ }
354
+ }
355
+ exports.LlmAuthorization = LlmAuthorization;
336
356
  class TurnMcpConfig {
337
357
  constructor({ servers = [] } = {}) {
338
358
  this.servers = servers;
@@ -1022,6 +1042,7 @@ const turnOptions = [
1022
1042
  objList("clientToolkits", "client_toolkits", ClientToolkitDescription.fromJson),
1023
1043
  { prop: "toolkits", json: "toolkits", from: toolkitsOrNull, to: toolkitsToJson },
1024
1044
  obj("toolChoice", "tool_choice", ToolChoice.fromJson),
1045
+ obj("llmAuthorization", "llm_authorization", LlmAuthorization.fromJson),
1025
1046
  ];
1026
1047
  const contentPart = [s("turnId", "turn_id", true), s("itemId", "item_id", true)];
1027
1048
  const responsePart = [...contentPart, s("responseId"), i("contentIndex")];
@@ -1057,6 +1078,7 @@ exports.StartThread = makeMessageClass("StartThread", {
1057
1078
  objList("clientToolkits", "client_toolkits", ClientToolkitDescription.fromJson),
1058
1079
  { prop: "toolkits", json: "toolkits", from: toolkitsOrNull, to: toolkitsToJson },
1059
1080
  obj("toolChoice", "tool_choice", ToolChoice.fromJson),
1081
+ obj("llmAuthorization", "llm_authorization", LlmAuthorization.fromJson),
1060
1082
  ],
1061
1083
  });
1062
1084
  exports.TurnStart = makeMessageClass("TurnStart", { type: exports.agentTurnStartType, base: "thread", fields: turnOptions });
@@ -1,6 +1,6 @@
1
1
  import { MessagingStream, RemoteParticipant } from "@meshagent/meshagent";
2
2
  import type { RoomClient, Content } from "@meshagent/meshagent";
3
- import { AgentMessage, AgentFileContent, ThreadCreated, AgentConnectionStatus } from "./agent-messages.js";
3
+ import { AgentMessage, AgentFileContent, LlmAuthorization, ThreadCreated, AgentConnectionStatus } from "./agent-messages.js";
4
4
  import type { AgentPayload, ClientToolkitDescription } from "./agent-messages.js";
5
5
  import { ChangeEmitter } from "./change-emitter.js";
6
6
  type JsonMap = Record<string, any>;
@@ -92,18 +92,26 @@ export declare class PendingThreadStartCandidate {
92
92
  });
93
93
  }
94
94
  export type ThreadCreatedPendingStartMatcher = (message: InstanceType<typeof ThreadCreated>, candidates: PendingThreadStartCandidate[]) => string | undefined;
95
+ export interface LlmAuthorizationRequest {
96
+ threadId?: string;
97
+ provider?: string;
98
+ model?: string;
99
+ }
100
+ export type LlmAuthorizationProvider = (request: LlmAuthorizationRequest) => Promise<LlmAuthorization | undefined>;
95
101
  export declare abstract class BaseChatClient extends ChangeEmitter {
96
102
  readonly threadCreatedPendingStartMatcher?: ThreadCreatedPendingStartMatcher;
97
103
  readonly deduplicateClientToolRequests: boolean;
104
+ readonly llmAuthorizationProvider?: LlmAuthorizationProvider;
98
105
  private readonly sessionsByPath;
99
106
  private readonly pendingStartRequests;
100
107
  private readonly pendingSessionEventsByPath;
101
108
  private readonly eventQueue;
102
109
  private readonly claimedClientToolRequests;
103
110
  private _connectionStatus?;
104
- constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests, }?: {
111
+ constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests, llmAuthorizationProvider, }?: {
105
112
  threadCreatedPendingStartMatcher?: ThreadCreatedPendingStartMatcher;
106
113
  deduplicateClientToolRequests?: boolean;
114
+ llmAuthorizationProvider?: LlmAuthorizationProvider;
107
115
  });
108
116
  get events(): AsyncIterable<AgentMessageEvent>;
109
117
  get connectionStatus(): InstanceType<typeof AgentConnectionStatus> | undefined;
@@ -186,11 +194,12 @@ export declare class BaseMessagingChatClient extends BaseChatClient {
186
194
  private waitingForParticipant;
187
195
  private roomAbortController?;
188
196
  private messagingListenersAttached;
189
- constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests, }: {
197
+ constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests, llmAuthorizationProvider, }: {
190
198
  room: RoomClient;
191
199
  agentName?: string;
192
200
  threadCreatedPendingStartMatcher?: ThreadCreatedPendingStartMatcher;
193
201
  deduplicateClientToolRequests?: boolean;
202
+ llmAuthorizationProvider?: LlmAuthorizationProvider;
194
203
  });
195
204
  localParticipantName(): string | undefined;
196
205
  localParticipantId(): string | undefined;
@@ -216,7 +225,7 @@ export declare class BaseMessagingChatClient extends BaseChatClient {
216
225
  }
217
226
  export declare class WebSocketChatClient extends BaseChatClient {
218
227
  readonly url: URL;
219
- readonly token: string;
228
+ readonly token?: string;
220
229
  readonly participantName?: string;
221
230
  readonly protocols: string[];
222
231
  readonly reconnect: boolean;
@@ -232,14 +241,15 @@ export declare class WebSocketChatClient extends BaseChatClient {
232
241
  private reconnectAttempts;
233
242
  private reconnectTimer?;
234
243
  private assignedParticipantId?;
235
- constructor({ url, token, participantName, protocols, reconnect, reconnectInitialDelay, reconnectMaxDelay, }: {
244
+ constructor({ url, token, participantName, protocols, reconnect, reconnectInitialDelay, reconnectMaxDelay, llmAuthorizationProvider, }: {
236
245
  url: URL;
237
- token: string;
246
+ token?: string;
238
247
  participantName?: string;
239
248
  protocols?: string[];
240
249
  reconnect?: boolean;
241
250
  reconnectInitialDelay?: number;
242
251
  reconnectMaxDelay?: number;
252
+ llmAuthorizationProvider?: LlmAuthorizationProvider;
243
253
  });
244
254
  get isConnected(): boolean;
245
255
  localParticipantName(): string | undefined;
@@ -179,7 +179,7 @@ class EventQueue {
179
179
  }
180
180
  }
181
181
  class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
182
- constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests = false, } = {}) {
182
+ constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests = false, llmAuthorizationProvider, } = {}) {
183
183
  super();
184
184
  this.sessionsByPath = new Map();
185
185
  this.pendingStartRequests = new Map();
@@ -188,6 +188,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
188
188
  this.claimedClientToolRequests = new Set();
189
189
  this.threadCreatedPendingStartMatcher = threadCreatedPendingStartMatcher;
190
190
  this.deduplicateClientToolRequests = deduplicateClientToolRequests;
191
+ this.llmAuthorizationProvider = llmAuthorizationProvider;
191
192
  }
192
193
  get events() {
193
194
  return this.eventQueue.stream;
@@ -243,6 +244,13 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
243
244
  cleanParticipantName(value) {
244
245
  return nonEmptyTrimmed(value);
245
246
  }
247
+ async resolveLlmAuthorization(request) {
248
+ const authorization = await this.llmAuthorizationProvider?.(request);
249
+ if (authorization?.isExpired === true) {
250
+ throw new Error("LLM authorization callback returned an expired token.");
251
+ }
252
+ return authorization;
253
+ }
246
254
  openThread(threadPath, { load = true, sinceTurn, reloadIfOpen = false, } = {}) {
247
255
  const normalized = threadPath.trim();
248
256
  if (normalized === "") {
@@ -269,6 +277,9 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
269
277
  async startThread({ messageId, message, attachments, name, backend, provider, model, voice, outputModalities, realtimeProtocol, senderName, clientToolkits, omitContent = false, }) {
270
278
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? (0, uuid_1.v4)() : messageId.trim();
271
279
  const resolvedSenderName = this.cleanParticipantName(senderName) ?? this.localParticipantName();
280
+ const llmAuthorization = this.llmAuthorizationProvider == null
281
+ ? undefined
282
+ : await this.resolveLlmAuthorization({ provider, model });
272
283
  const payload = new agent_messages_js_1.StartThread({
273
284
  messageId: resolvedMessageId,
274
285
  content: omitContent ? undefined : (0, agent_messages_js_1.agentInputContent)({ text: message, attachments }),
@@ -281,6 +292,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
281
292
  realtimeProtocol: nonEmptyTrimmed(realtimeProtocol),
282
293
  senderName: resolvedSenderName,
283
294
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
295
+ llmAuthorization,
284
296
  });
285
297
  const completer = new meshagent_1.Completer();
286
298
  this.pendingStartRequests.set(resolvedMessageId, { request: payload, completer });
@@ -329,6 +341,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
329
341
  clientToolkits: payload.clientToolkits,
330
342
  toolkits: payload.toolkits,
331
343
  toolChoice: payload.toolChoice,
344
+ llmAuthorization: payload.llmAuthorization,
332
345
  });
333
346
  }
334
347
  drainPendingSessionEvents(threadPath, session) {
@@ -482,8 +495,8 @@ function participantWaitAbortedError(reason) {
482
495
  return error;
483
496
  }
484
497
  class BaseMessagingChatClient extends BaseChatClient {
485
- constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests = true, }) {
486
- super({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests });
498
+ constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests = true, llmAuthorizationProvider, }) {
499
+ super({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests, llmAuthorizationProvider });
487
500
  this.pendingParticipantWaits = new Map();
488
501
  this.started = false;
489
502
  this.hasConnected = false;
@@ -728,8 +741,8 @@ class BaseMessagingChatClient extends BaseChatClient {
728
741
  }
729
742
  exports.BaseMessagingChatClient = BaseMessagingChatClient;
730
743
  class WebSocketChatClient extends BaseChatClient {
731
- constructor({ url, token, participantName, protocols = ["meshagent-msgpack"], reconnect = true, reconnectInitialDelay = 1000, reconnectMaxDelay = 10000, }) {
732
- super({ deduplicateClientToolRequests: true });
744
+ constructor({ url, token, participantName, protocols = ["meshagent-msgpack"], reconnect = true, reconnectInitialDelay = 1000, reconnectMaxDelay = 10000, llmAuthorizationProvider, }) {
745
+ super({ deduplicateClientToolRequests: true, llmAuthorizationProvider });
733
746
  this.started = false;
734
747
  this.stopping = false;
735
748
  this.connecting = false;
@@ -956,7 +969,7 @@ class WebSocketChatClient extends BaseChatClient {
956
969
  resolved.push(normalized);
957
970
  }
958
971
  }
959
- const normalizedToken = this.token.trim();
972
+ const normalizedToken = this.token?.trim() ?? "";
960
973
  if (normalizedToken !== "") {
961
974
  resolved.push(`meshagent-agent.${normalizedToken}`);
962
975
  }
@@ -1228,6 +1241,9 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1228
1241
  }
1229
1242
  async sendText({ messageId, text, attachments, steer = false, turnId, backend, provider, model, voice, outputModalities, senderName, clientToolkits, }) {
1230
1243
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? (0, uuid_1.v4)() : messageId.trim();
1244
+ const llmAuthorization = steer || this.client.llmAuthorizationProvider == null
1245
+ ? undefined
1246
+ : await this.client.resolveLlmAuthorization({ threadId: this.threadPath, provider, model });
1231
1247
  const payload = steer
1232
1248
  ? new agent_messages_js_1.TurnSteer({
1233
1249
  threadId: this.threadPath,
@@ -1247,6 +1263,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1247
1263
  voice: nonEmptyTrimmed(voice),
1248
1264
  outputModalities: outputModalities != null && outputModalities.length > 0 ? outputModalities : undefined,
1249
1265
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
1266
+ llmAuthorization,
1250
1267
  });
1251
1268
  this.localAgentMessageIds.add(resolvedMessageId);
1252
1269
  this.pendingLocalInputMessageIds.add(resolvedMessageId);
@@ -1270,6 +1287,11 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1270
1287
  }
1271
1288
  async commitRealtimeAudio({ turnId, backend, provider, model, voice, outputModalities, }) {
1272
1289
  const messageId = (0, uuid_1.v4)();
1290
+ const llmAuthorization = await this.client.resolveLlmAuthorization({
1291
+ threadId: this.threadPath,
1292
+ provider,
1293
+ model,
1294
+ });
1273
1295
  await this.client.sendAgentMessage(new agent_messages_js_1.AgentRealtimeAudioCommit({
1274
1296
  threadId: this.threadPath,
1275
1297
  messageId,
@@ -1284,6 +1306,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1284
1306
  model: nonEmptyTrimmed(model),
1285
1307
  voice: nonEmptyTrimmed(voice),
1286
1308
  outputModalities: outputModalities != null && outputModalities.length > 0 ? outputModalities : undefined,
1309
+ llmAuthorization,
1287
1310
  }));
1288
1311
  return messageId;
1289
1312
  }
@@ -111,6 +111,17 @@ export declare class ToolChoice {
111
111
  static fromJson(json: JsonMap): ToolChoice;
112
112
  toJson(): JsonMap;
113
113
  }
114
+ export declare class LlmAuthorization {
115
+ readonly token: string;
116
+ readonly expiresAt: Date;
117
+ constructor({ token, expiresAt }: {
118
+ token: string;
119
+ expiresAt: Date;
120
+ });
121
+ get isExpired(): boolean;
122
+ static fromJson(json: JsonMap): LlmAuthorization;
123
+ toJson(): JsonMap;
124
+ }
114
125
  export declare class TurnMcpConfig {
115
126
  readonly servers: JsonMap[];
116
127
  constructor({ servers }?: {
@@ -381,6 +392,7 @@ export interface StartThread extends AgentMessage {
381
392
  readonly clientToolkits?: ClientToolkitDescription[];
382
393
  readonly toolkits?: Record<string, TurnToolkitConfig>;
383
394
  readonly toolChoice?: ToolChoice;
395
+ readonly llmAuthorization?: LlmAuthorization;
384
396
  }
385
397
  type StartThreadArguments = {
386
398
  messageId?: string;
@@ -398,6 +410,7 @@ type StartThreadArguments = {
398
410
  clientToolkits?: ClientToolkitDescription[];
399
411
  toolkits?: Record<string, TurnToolkitConfig>;
400
412
  toolChoice?: ToolChoice;
413
+ llmAuthorization?: LlmAuthorization;
401
414
  };
402
415
  export interface TurnStart extends AgentThreadMessage {
403
416
  readonly turnId?: string;
@@ -412,6 +425,7 @@ export interface TurnStart extends AgentThreadMessage {
412
425
  readonly clientToolkits?: ClientToolkitDescription[];
413
426
  readonly toolkits?: Record<string, TurnToolkitConfig>;
414
427
  readonly toolChoice?: ToolChoice;
428
+ readonly llmAuthorization?: LlmAuthorization;
415
429
  }
416
430
  type TurnStartArguments = {
417
431
  threadId: string;
@@ -429,6 +443,7 @@ type TurnStartArguments = {
429
443
  clientToolkits?: ClientToolkitDescription[];
430
444
  toolkits?: Record<string, TurnToolkitConfig>;
431
445
  toolChoice?: ToolChoice;
446
+ llmAuthorization?: LlmAuthorization;
432
447
  };
433
448
  export interface TurnSteer extends AgentThreadMessage {
434
449
  readonly turnId: string;
@@ -324,6 +324,25 @@ export class ToolChoice {
324
324
  return { toolkit_name: this.toolkitName, tool_name: this.toolName };
325
325
  }
326
326
  }
327
+ export class LlmAuthorization {
328
+ constructor({ token, expiresAt }) {
329
+ this.token = token;
330
+ this.expiresAt = expiresAt;
331
+ }
332
+ get isExpired() {
333
+ return this.expiresAt.getTime() <= Date.now();
334
+ }
335
+ static fromJson(json) {
336
+ const expiresAt = new Date(requiredString(json, "expires_at"));
337
+ if (Number.isNaN(expiresAt.getTime())) {
338
+ throw new TypeError("LLM authorization expires_at must be an ISO timestamp");
339
+ }
340
+ return new LlmAuthorization({ token: requiredString(json, "token"), expiresAt });
341
+ }
342
+ toJson() {
343
+ return { token: this.token, expires_at: this.expiresAt.toISOString() };
344
+ }
345
+ }
327
346
  export class TurnMcpConfig {
328
347
  constructor({ servers = [] } = {}) {
329
348
  this.servers = servers;
@@ -995,6 +1014,7 @@ const turnOptions = [
995
1014
  objList("clientToolkits", "client_toolkits", ClientToolkitDescription.fromJson),
996
1015
  { prop: "toolkits", json: "toolkits", from: toolkitsOrNull, to: toolkitsToJson },
997
1016
  obj("toolChoice", "tool_choice", ToolChoice.fromJson),
1017
+ obj("llmAuthorization", "llm_authorization", LlmAuthorization.fromJson),
998
1018
  ];
999
1019
  const contentPart = [s("turnId", "turn_id", true), s("itemId", "item_id", true)];
1000
1020
  const responsePart = [...contentPart, s("responseId"), i("contentIndex")];
@@ -1030,6 +1050,7 @@ export const StartThread = makeMessageClass("StartThread", {
1030
1050
  objList("clientToolkits", "client_toolkits", ClientToolkitDescription.fromJson),
1031
1051
  { prop: "toolkits", json: "toolkits", from: toolkitsOrNull, to: toolkitsToJson },
1032
1052
  obj("toolChoice", "tool_choice", ToolChoice.fromJson),
1053
+ obj("llmAuthorization", "llm_authorization", LlmAuthorization.fromJson),
1033
1054
  ],
1034
1055
  });
1035
1056
  export const TurnStart = makeMessageClass("TurnStart", { type: agentTurnStartType, base: "thread", fields: turnOptions });
@@ -1,6 +1,6 @@
1
1
  import { MessagingStream, RemoteParticipant } from "@meshagent/meshagent";
2
2
  import type { RoomClient, Content } from "@meshagent/meshagent";
3
- import { AgentMessage, AgentFileContent, ThreadCreated, AgentConnectionStatus } from "./agent-messages.js";
3
+ import { AgentMessage, AgentFileContent, LlmAuthorization, ThreadCreated, AgentConnectionStatus } from "./agent-messages.js";
4
4
  import type { AgentPayload, ClientToolkitDescription } from "./agent-messages.js";
5
5
  import { ChangeEmitter } from "./change-emitter.js";
6
6
  type JsonMap = Record<string, any>;
@@ -92,18 +92,26 @@ export declare class PendingThreadStartCandidate {
92
92
  });
93
93
  }
94
94
  export type ThreadCreatedPendingStartMatcher = (message: InstanceType<typeof ThreadCreated>, candidates: PendingThreadStartCandidate[]) => string | undefined;
95
+ export interface LlmAuthorizationRequest {
96
+ threadId?: string;
97
+ provider?: string;
98
+ model?: string;
99
+ }
100
+ export type LlmAuthorizationProvider = (request: LlmAuthorizationRequest) => Promise<LlmAuthorization | undefined>;
95
101
  export declare abstract class BaseChatClient extends ChangeEmitter {
96
102
  readonly threadCreatedPendingStartMatcher?: ThreadCreatedPendingStartMatcher;
97
103
  readonly deduplicateClientToolRequests: boolean;
104
+ readonly llmAuthorizationProvider?: LlmAuthorizationProvider;
98
105
  private readonly sessionsByPath;
99
106
  private readonly pendingStartRequests;
100
107
  private readonly pendingSessionEventsByPath;
101
108
  private readonly eventQueue;
102
109
  private readonly claimedClientToolRequests;
103
110
  private _connectionStatus?;
104
- constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests, }?: {
111
+ constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests, llmAuthorizationProvider, }?: {
105
112
  threadCreatedPendingStartMatcher?: ThreadCreatedPendingStartMatcher;
106
113
  deduplicateClientToolRequests?: boolean;
114
+ llmAuthorizationProvider?: LlmAuthorizationProvider;
107
115
  });
108
116
  get events(): AsyncIterable<AgentMessageEvent>;
109
117
  get connectionStatus(): InstanceType<typeof AgentConnectionStatus> | undefined;
@@ -186,11 +194,12 @@ export declare class BaseMessagingChatClient extends BaseChatClient {
186
194
  private waitingForParticipant;
187
195
  private roomAbortController?;
188
196
  private messagingListenersAttached;
189
- constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests, }: {
197
+ constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests, llmAuthorizationProvider, }: {
190
198
  room: RoomClient;
191
199
  agentName?: string;
192
200
  threadCreatedPendingStartMatcher?: ThreadCreatedPendingStartMatcher;
193
201
  deduplicateClientToolRequests?: boolean;
202
+ llmAuthorizationProvider?: LlmAuthorizationProvider;
194
203
  });
195
204
  localParticipantName(): string | undefined;
196
205
  localParticipantId(): string | undefined;
@@ -216,7 +225,7 @@ export declare class BaseMessagingChatClient extends BaseChatClient {
216
225
  }
217
226
  export declare class WebSocketChatClient extends BaseChatClient {
218
227
  readonly url: URL;
219
- readonly token: string;
228
+ readonly token?: string;
220
229
  readonly participantName?: string;
221
230
  readonly protocols: string[];
222
231
  readonly reconnect: boolean;
@@ -232,14 +241,15 @@ export declare class WebSocketChatClient extends BaseChatClient {
232
241
  private reconnectAttempts;
233
242
  private reconnectTimer?;
234
243
  private assignedParticipantId?;
235
- constructor({ url, token, participantName, protocols, reconnect, reconnectInitialDelay, reconnectMaxDelay, }: {
244
+ constructor({ url, token, participantName, protocols, reconnect, reconnectInitialDelay, reconnectMaxDelay, llmAuthorizationProvider, }: {
236
245
  url: URL;
237
- token: string;
246
+ token?: string;
238
247
  participantName?: string;
239
248
  protocols?: string[];
240
249
  reconnect?: boolean;
241
250
  reconnectInitialDelay?: number;
242
251
  reconnectMaxDelay?: number;
252
+ llmAuthorizationProvider?: LlmAuthorizationProvider;
243
253
  });
244
254
  get isConnected(): boolean;
245
255
  localParticipantName(): string | undefined;
@@ -168,7 +168,7 @@ class EventQueue {
168
168
  }
169
169
  }
170
170
  export class BaseChatClient extends ChangeEmitter {
171
- constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests = false, } = {}) {
171
+ constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests = false, llmAuthorizationProvider, } = {}) {
172
172
  super();
173
173
  this.sessionsByPath = new Map();
174
174
  this.pendingStartRequests = new Map();
@@ -177,6 +177,7 @@ export class BaseChatClient extends ChangeEmitter {
177
177
  this.claimedClientToolRequests = new Set();
178
178
  this.threadCreatedPendingStartMatcher = threadCreatedPendingStartMatcher;
179
179
  this.deduplicateClientToolRequests = deduplicateClientToolRequests;
180
+ this.llmAuthorizationProvider = llmAuthorizationProvider;
180
181
  }
181
182
  get events() {
182
183
  return this.eventQueue.stream;
@@ -232,6 +233,13 @@ export class BaseChatClient extends ChangeEmitter {
232
233
  cleanParticipantName(value) {
233
234
  return nonEmptyTrimmed(value);
234
235
  }
236
+ async resolveLlmAuthorization(request) {
237
+ const authorization = await this.llmAuthorizationProvider?.(request);
238
+ if (authorization?.isExpired === true) {
239
+ throw new Error("LLM authorization callback returned an expired token.");
240
+ }
241
+ return authorization;
242
+ }
235
243
  openThread(threadPath, { load = true, sinceTurn, reloadIfOpen = false, } = {}) {
236
244
  const normalized = threadPath.trim();
237
245
  if (normalized === "") {
@@ -258,6 +266,9 @@ export class BaseChatClient extends ChangeEmitter {
258
266
  async startThread({ messageId, message, attachments, name, backend, provider, model, voice, outputModalities, realtimeProtocol, senderName, clientToolkits, omitContent = false, }) {
259
267
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? uuidv4() : messageId.trim();
260
268
  const resolvedSenderName = this.cleanParticipantName(senderName) ?? this.localParticipantName();
269
+ const llmAuthorization = this.llmAuthorizationProvider == null
270
+ ? undefined
271
+ : await this.resolveLlmAuthorization({ provider, model });
261
272
  const payload = new StartThread({
262
273
  messageId: resolvedMessageId,
263
274
  content: omitContent ? undefined : agentInputContent({ text: message, attachments }),
@@ -270,6 +281,7 @@ export class BaseChatClient extends ChangeEmitter {
270
281
  realtimeProtocol: nonEmptyTrimmed(realtimeProtocol),
271
282
  senderName: resolvedSenderName,
272
283
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
284
+ llmAuthorization,
273
285
  });
274
286
  const completer = new Completer();
275
287
  this.pendingStartRequests.set(resolvedMessageId, { request: payload, completer });
@@ -318,6 +330,7 @@ export class BaseChatClient extends ChangeEmitter {
318
330
  clientToolkits: payload.clientToolkits,
319
331
  toolkits: payload.toolkits,
320
332
  toolChoice: payload.toolChoice,
333
+ llmAuthorization: payload.llmAuthorization,
321
334
  });
322
335
  }
323
336
  drainPendingSessionEvents(threadPath, session) {
@@ -468,8 +481,8 @@ function participantWaitAbortedError(reason) {
468
481
  return error;
469
482
  }
470
483
  export class BaseMessagingChatClient extends BaseChatClient {
471
- constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests = true, }) {
472
- super({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests });
484
+ constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests = true, llmAuthorizationProvider, }) {
485
+ super({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests, llmAuthorizationProvider });
473
486
  this.pendingParticipantWaits = new Map();
474
487
  this.started = false;
475
488
  this.hasConnected = false;
@@ -713,8 +726,8 @@ export class BaseMessagingChatClient extends BaseChatClient {
713
726
  }
714
727
  }
715
728
  export class WebSocketChatClient extends BaseChatClient {
716
- constructor({ url, token, participantName, protocols = ["meshagent-msgpack"], reconnect = true, reconnectInitialDelay = 1000, reconnectMaxDelay = 10000, }) {
717
- super({ deduplicateClientToolRequests: true });
729
+ constructor({ url, token, participantName, protocols = ["meshagent-msgpack"], reconnect = true, reconnectInitialDelay = 1000, reconnectMaxDelay = 10000, llmAuthorizationProvider, }) {
730
+ super({ deduplicateClientToolRequests: true, llmAuthorizationProvider });
718
731
  this.started = false;
719
732
  this.stopping = false;
720
733
  this.connecting = false;
@@ -941,7 +954,7 @@ export class WebSocketChatClient extends BaseChatClient {
941
954
  resolved.push(normalized);
942
955
  }
943
956
  }
944
- const normalizedToken = this.token.trim();
957
+ const normalizedToken = this.token?.trim() ?? "";
945
958
  if (normalizedToken !== "") {
946
959
  resolved.push(`meshagent-agent.${normalizedToken}`);
947
960
  }
@@ -1211,6 +1224,9 @@ export class ChatThreadSession extends ChangeEmitter {
1211
1224
  }
1212
1225
  async sendText({ messageId, text, attachments, steer = false, turnId, backend, provider, model, voice, outputModalities, senderName, clientToolkits, }) {
1213
1226
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? uuidv4() : messageId.trim();
1227
+ const llmAuthorization = steer || this.client.llmAuthorizationProvider == null
1228
+ ? undefined
1229
+ : await this.client.resolveLlmAuthorization({ threadId: this.threadPath, provider, model });
1214
1230
  const payload = steer
1215
1231
  ? new TurnSteer({
1216
1232
  threadId: this.threadPath,
@@ -1230,6 +1246,7 @@ export class ChatThreadSession extends ChangeEmitter {
1230
1246
  voice: nonEmptyTrimmed(voice),
1231
1247
  outputModalities: outputModalities != null && outputModalities.length > 0 ? outputModalities : undefined,
1232
1248
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
1249
+ llmAuthorization,
1233
1250
  });
1234
1251
  this.localAgentMessageIds.add(resolvedMessageId);
1235
1252
  this.pendingLocalInputMessageIds.add(resolvedMessageId);
@@ -1253,6 +1270,11 @@ export class ChatThreadSession extends ChangeEmitter {
1253
1270
  }
1254
1271
  async commitRealtimeAudio({ turnId, backend, provider, model, voice, outputModalities, }) {
1255
1272
  const messageId = uuidv4();
1273
+ const llmAuthorization = await this.client.resolveLlmAuthorization({
1274
+ threadId: this.threadPath,
1275
+ provider,
1276
+ model,
1277
+ });
1256
1278
  await this.client.sendAgentMessage(new AgentRealtimeAudioCommit({
1257
1279
  threadId: this.threadPath,
1258
1280
  messageId,
@@ -1267,6 +1289,7 @@ export class ChatThreadSession extends ChangeEmitter {
1267
1289
  model: nonEmptyTrimmed(model),
1268
1290
  voice: nonEmptyTrimmed(voice),
1269
1291
  outputModalities: outputModalities != null && outputModalities.length > 0 ? outputModalities : undefined,
1292
+ llmAuthorization,
1270
1293
  }));
1271
1294
  return messageId;
1272
1295
  }
@@ -111,6 +111,17 @@ export declare class ToolChoice {
111
111
  static fromJson(json: JsonMap): ToolChoice;
112
112
  toJson(): JsonMap;
113
113
  }
114
+ export declare class LlmAuthorization {
115
+ readonly token: string;
116
+ readonly expiresAt: Date;
117
+ constructor({ token, expiresAt }: {
118
+ token: string;
119
+ expiresAt: Date;
120
+ });
121
+ get isExpired(): boolean;
122
+ static fromJson(json: JsonMap): LlmAuthorization;
123
+ toJson(): JsonMap;
124
+ }
114
125
  export declare class TurnMcpConfig {
115
126
  readonly servers: JsonMap[];
116
127
  constructor({ servers }?: {
@@ -381,6 +392,7 @@ export interface StartThread extends AgentMessage {
381
392
  readonly clientToolkits?: ClientToolkitDescription[];
382
393
  readonly toolkits?: Record<string, TurnToolkitConfig>;
383
394
  readonly toolChoice?: ToolChoice;
395
+ readonly llmAuthorization?: LlmAuthorization;
384
396
  }
385
397
  type StartThreadArguments = {
386
398
  messageId?: string;
@@ -398,6 +410,7 @@ type StartThreadArguments = {
398
410
  clientToolkits?: ClientToolkitDescription[];
399
411
  toolkits?: Record<string, TurnToolkitConfig>;
400
412
  toolChoice?: ToolChoice;
413
+ llmAuthorization?: LlmAuthorization;
401
414
  };
402
415
  export interface TurnStart extends AgentThreadMessage {
403
416
  readonly turnId?: string;
@@ -412,6 +425,7 @@ export interface TurnStart extends AgentThreadMessage {
412
425
  readonly clientToolkits?: ClientToolkitDescription[];
413
426
  readonly toolkits?: Record<string, TurnToolkitConfig>;
414
427
  readonly toolChoice?: ToolChoice;
428
+ readonly llmAuthorization?: LlmAuthorization;
415
429
  }
416
430
  type TurnStartArguments = {
417
431
  threadId: string;
@@ -429,6 +443,7 @@ type TurnStartArguments = {
429
443
  clientToolkits?: ClientToolkitDescription[];
430
444
  toolkits?: Record<string, TurnToolkitConfig>;
431
445
  toolChoice?: ToolChoice;
446
+ llmAuthorization?: LlmAuthorization;
432
447
  };
433
448
  export interface TurnSteer extends AgentThreadMessage {
434
449
  readonly turnId: string;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.agentFileContentEndedType = exports.agentFileContentDeltaType = exports.agentFileContentStartedType = exports.agentTextContentEndedType = exports.agentTextContentDeltaType = exports.agentTextContentStartedType = exports.agentReasoningContentEndedType = exports.agentReasoningContentDeltaType = exports.agentReasoningContentStartedType = exports.agentTurnEndedType = exports.agentTurnStartedType = exports.agentTurnSteerRejectedType = exports.agentTurnSteeredType = exports.agentTurnSteerAcceptedType = exports.agentTurnInterruptedType = exports.agentTurnInterruptAcceptedType = exports.agentTurnStartRejectedType = exports.agentTurnStartAcceptedType = exports.agentThreadClearedType = exports.agentModelChangedType = exports.agentModelChangeType = exports.agentModelsResponseType = exports.agentModelsRequestType = exports.agentCapabilitiesResponseType = exports.agentCapabilitiesRequestType = exports.agentThreadDeletedType = exports.agentThreadUpdatedType = exports.agentThreadCreatedType = exports.agentThreadListedType = exports.agentThreadUnwatchType = exports.agentThreadWatchType = exports.agentThreadListType = exports.agentThreadRenameType = exports.agentThreadDeleteType = exports.agentParticipantDisconnectType = exports.agentParticipantConnectType = exports.agentMessagesInjectType = exports.agentThreadCloseType = exports.agentThreadOpenType = exports.agentThreadStartRejectedType = exports.agentThreadLoadedType = exports.agentThreadStartedType = exports.agentThreadStartType = exports.agentRealtimeAudioCommitType = exports.agentRealtimeAudioChunkType = exports.agentThreadClearType = exports.agentTurnInterruptType = exports.agentTurnSteerType = exports.agentTurnStartType = exports.agentRoomMessageType = void 0;
4
- exports.AgentContextWindowUsage = exports.AgentGeneratedAudio = exports.AgentGeneratedImage = exports.AgentToolCallLogLine = exports.AgentRealtimeConnectionInfo = exports.AgentThreadListEntry = exports.AgentProviderInfo = exports.AgentModelInfo = exports.ToolkitCapabilities = exports.ToolkitToolCapabilities = exports.AgentError = exports.AgentAudioFormat = exports.TurnToolkitConfig = exports.ClientToolkitDescription = exports.TurnMcpConfig = exports.ToolChoice = exports.AgentFileContent = exports.agentClientToolCallResponseType = exports.agentSecretResponseType = exports.agentToolRejectType = exports.agentToolApproveType = exports.agentUsageUpdatedType = exports.agentContextCompactedType = exports.agentAudioInputSpeechEndedType = exports.agentAudioInputSpeechStartedType = exports.agentAudioTranscriptionFailedType = exports.agentAudioTranscriptionCompletedType = exports.agentAudioTranscriptionDeltaType = exports.agentAudioTranscriptionStartedType = exports.agentAudioGenerationFailedType = exports.agentAudioGenerationCompletedType = exports.agentAudioGenerationDeltaType = exports.agentAudioGenerationStartedType = exports.agentImageGenerationFailedType = exports.agentImageGenerationCompletedType = exports.agentImageGenerationPartialType = exports.agentImageGenerationStartedType = exports.agentThreadEventType = exports.agentConnectionStatusType = exports.agentThreadStatusType = exports.agentSecretRequestedType = exports.agentClientToolCallCancelledType = exports.agentClientToolCallRequestedType = exports.agentToolCallApprovalRequestedType = exports.agentToolCallEndedType = exports.agentToolCallLogDeltaType = exports.agentToolCallArgumentsDeltaType = exports.agentToolCallStartedType = exports.agentToolCallInProgressType = exports.agentToolCallPendingType = void 0;
5
- exports.AgentFileContentStarted = exports.AgentTextContentEnded = exports.AgentTextContentDelta = exports.AgentTextContentStarted = exports.AgentReasoningContentEnded = exports.AgentReasoningContentDelta = exports.AgentReasoningContentStarted = exports.ThreadStartRejected = exports.ThreadLoaded = exports.ThreadStarted = exports.TurnEnded = exports.TurnStarted = exports.TurnSteerRejected = exports.TurnSteered = exports.TurnSteerAccepted = exports.TurnInterrupted = exports.TurnInterruptAccepted = exports.TurnStartRejected = exports.TurnStartAccepted = exports.ThreadCleared = exports.AgentModelChanged = exports.ChangeModel = exports.ModelsResponse = exports.ModelsRequest = exports.CapabilitiesResponse = exports.CapabilitiesRequest = exports.ThreadDeleted = exports.ThreadUpdated = exports.ThreadCreated = exports.ThreadsListed = exports.UnwatchThreads = exports.WatchThreads = exports.ListThreads = exports.RenameThread = exports.DeleteThread = exports.ParticipantDisconnect = exports.ParticipantConnect = exports.InjectMessages = exports.CloseThread = exports.OpenThread = exports.ClearThread = exports.AgentRealtimeAudioCommit = exports.AgentRealtimeAudioChunk = exports.TurnInterrupt = exports.TurnSteer = exports.TurnStart = exports.StartThread = exports.AgentLLMMessage = exports.AgentThreadMessage = exports.AgentMessage = void 0;
6
- exports.AgentClientToolCallResponse = exports.AgentSecretResponse = exports.RejectAgentToolCall = exports.ApproveAgentToolCall = exports.AgentUsageUpdated = exports.AgentContextCompacted = exports.AgentAudioInputSpeechEnded = exports.AgentAudioInputSpeechStarted = exports.AgentAudioTranscriptionFailed = exports.AgentAudioTranscriptionCompleted = exports.AgentAudioTranscriptionDelta = exports.AgentAudioTranscriptionStarted = exports.AgentAudioGenerationFailed = exports.AgentAudioGenerationCompleted = exports.AgentAudioGenerationDelta = exports.AgentAudioGenerationStarted = exports.AgentImageGenerationFailed = exports.AgentImageGenerationCompleted = exports.AgentImageGenerationPartial = exports.AgentImageGenerationStarted = exports.AgentThreadEvent = exports.AgentConnectionStatus = exports.AgentThreadStatus = exports.AgentClientToolCallCancelled = exports.AgentClientToolCallRequested = exports.AgentSecretRequested = exports.AgentToolCallApprovalRequested = exports.AgentToolCallEnded = exports.AgentToolCallLogDelta = exports.AgentToolCallArgumentsDelta = exports.AgentToolCallStarted = exports.AgentToolCallInProgress = exports.AgentToolCallPending = exports.AgentFileContentEnded = exports.AgentFileContentDelta = void 0;
4
+ exports.AgentGeneratedAudio = exports.AgentGeneratedImage = exports.AgentToolCallLogLine = exports.AgentRealtimeConnectionInfo = exports.AgentThreadListEntry = exports.AgentProviderInfo = exports.AgentModelInfo = exports.ToolkitCapabilities = exports.ToolkitToolCapabilities = exports.AgentError = exports.AgentAudioFormat = exports.TurnToolkitConfig = exports.ClientToolkitDescription = exports.TurnMcpConfig = exports.LlmAuthorization = exports.ToolChoice = exports.AgentFileContent = exports.agentClientToolCallResponseType = exports.agentSecretResponseType = exports.agentToolRejectType = exports.agentToolApproveType = exports.agentUsageUpdatedType = exports.agentContextCompactedType = exports.agentAudioInputSpeechEndedType = exports.agentAudioInputSpeechStartedType = exports.agentAudioTranscriptionFailedType = exports.agentAudioTranscriptionCompletedType = exports.agentAudioTranscriptionDeltaType = exports.agentAudioTranscriptionStartedType = exports.agentAudioGenerationFailedType = exports.agentAudioGenerationCompletedType = exports.agentAudioGenerationDeltaType = exports.agentAudioGenerationStartedType = exports.agentImageGenerationFailedType = exports.agentImageGenerationCompletedType = exports.agentImageGenerationPartialType = exports.agentImageGenerationStartedType = exports.agentThreadEventType = exports.agentConnectionStatusType = exports.agentThreadStatusType = exports.agentSecretRequestedType = exports.agentClientToolCallCancelledType = exports.agentClientToolCallRequestedType = exports.agentToolCallApprovalRequestedType = exports.agentToolCallEndedType = exports.agentToolCallLogDeltaType = exports.agentToolCallArgumentsDeltaType = exports.agentToolCallStartedType = exports.agentToolCallInProgressType = exports.agentToolCallPendingType = void 0;
5
+ exports.AgentTextContentEnded = exports.AgentTextContentDelta = exports.AgentTextContentStarted = exports.AgentReasoningContentEnded = exports.AgentReasoningContentDelta = exports.AgentReasoningContentStarted = exports.ThreadStartRejected = exports.ThreadLoaded = exports.ThreadStarted = exports.TurnEnded = exports.TurnStarted = exports.TurnSteerRejected = exports.TurnSteered = exports.TurnSteerAccepted = exports.TurnInterrupted = exports.TurnInterruptAccepted = exports.TurnStartRejected = exports.TurnStartAccepted = exports.ThreadCleared = exports.AgentModelChanged = exports.ChangeModel = exports.ModelsResponse = exports.ModelsRequest = exports.CapabilitiesResponse = exports.CapabilitiesRequest = exports.ThreadDeleted = exports.ThreadUpdated = exports.ThreadCreated = exports.ThreadsListed = exports.UnwatchThreads = exports.WatchThreads = exports.ListThreads = exports.RenameThread = exports.DeleteThread = exports.ParticipantDisconnect = exports.ParticipantConnect = exports.InjectMessages = exports.CloseThread = exports.OpenThread = exports.ClearThread = exports.AgentRealtimeAudioCommit = exports.AgentRealtimeAudioChunk = exports.TurnInterrupt = exports.TurnSteer = exports.TurnStart = exports.StartThread = exports.AgentLLMMessage = exports.AgentThreadMessage = exports.AgentMessage = exports.AgentContextWindowUsage = void 0;
6
+ exports.AgentClientToolCallResponse = exports.AgentSecretResponse = exports.RejectAgentToolCall = exports.ApproveAgentToolCall = exports.AgentUsageUpdated = exports.AgentContextCompacted = exports.AgentAudioInputSpeechEnded = exports.AgentAudioInputSpeechStarted = exports.AgentAudioTranscriptionFailed = exports.AgentAudioTranscriptionCompleted = exports.AgentAudioTranscriptionDelta = exports.AgentAudioTranscriptionStarted = exports.AgentAudioGenerationFailed = exports.AgentAudioGenerationCompleted = exports.AgentAudioGenerationDelta = exports.AgentAudioGenerationStarted = exports.AgentImageGenerationFailed = exports.AgentImageGenerationCompleted = exports.AgentImageGenerationPartial = exports.AgentImageGenerationStarted = exports.AgentThreadEvent = exports.AgentConnectionStatus = exports.AgentThreadStatus = exports.AgentClientToolCallCancelled = exports.AgentClientToolCallRequested = exports.AgentSecretRequested = exports.AgentToolCallApprovalRequested = exports.AgentToolCallEnded = exports.AgentToolCallLogDelta = exports.AgentToolCallArgumentsDelta = exports.AgentToolCallStarted = exports.AgentToolCallInProgress = exports.AgentToolCallPending = exports.AgentFileContentEnded = exports.AgentFileContentDelta = exports.AgentFileContentStarted = void 0;
7
7
  exports.agentInputContent = agentInputContent;
8
8
  const meshagent_1 = require("@meshagent/meshagent");
9
9
  const uuid_1 = require("uuid");
@@ -333,6 +333,26 @@ class ToolChoice {
333
333
  }
334
334
  }
335
335
  exports.ToolChoice = ToolChoice;
336
+ class LlmAuthorization {
337
+ constructor({ token, expiresAt }) {
338
+ this.token = token;
339
+ this.expiresAt = expiresAt;
340
+ }
341
+ get isExpired() {
342
+ return this.expiresAt.getTime() <= Date.now();
343
+ }
344
+ static fromJson(json) {
345
+ const expiresAt = new Date(requiredString(json, "expires_at"));
346
+ if (Number.isNaN(expiresAt.getTime())) {
347
+ throw new TypeError("LLM authorization expires_at must be an ISO timestamp");
348
+ }
349
+ return new LlmAuthorization({ token: requiredString(json, "token"), expiresAt });
350
+ }
351
+ toJson() {
352
+ return { token: this.token, expires_at: this.expiresAt.toISOString() };
353
+ }
354
+ }
355
+ exports.LlmAuthorization = LlmAuthorization;
336
356
  class TurnMcpConfig {
337
357
  constructor({ servers = [] } = {}) {
338
358
  this.servers = servers;
@@ -1022,6 +1042,7 @@ const turnOptions = [
1022
1042
  objList("clientToolkits", "client_toolkits", ClientToolkitDescription.fromJson),
1023
1043
  { prop: "toolkits", json: "toolkits", from: toolkitsOrNull, to: toolkitsToJson },
1024
1044
  obj("toolChoice", "tool_choice", ToolChoice.fromJson),
1045
+ obj("llmAuthorization", "llm_authorization", LlmAuthorization.fromJson),
1025
1046
  ];
1026
1047
  const contentPart = [s("turnId", "turn_id", true), s("itemId", "item_id", true)];
1027
1048
  const responsePart = [...contentPart, s("responseId"), i("contentIndex")];
@@ -1057,6 +1078,7 @@ exports.StartThread = makeMessageClass("StartThread", {
1057
1078
  objList("clientToolkits", "client_toolkits", ClientToolkitDescription.fromJson),
1058
1079
  { prop: "toolkits", json: "toolkits", from: toolkitsOrNull, to: toolkitsToJson },
1059
1080
  obj("toolChoice", "tool_choice", ToolChoice.fromJson),
1081
+ obj("llmAuthorization", "llm_authorization", LlmAuthorization.fromJson),
1060
1082
  ],
1061
1083
  });
1062
1084
  exports.TurnStart = makeMessageClass("TurnStart", { type: exports.agentTurnStartType, base: "thread", fields: turnOptions });
@@ -1,6 +1,6 @@
1
1
  import { MessagingStream, RemoteParticipant } from "@meshagent/meshagent";
2
2
  import type { RoomClient, Content } from "@meshagent/meshagent";
3
- import { AgentMessage, AgentFileContent, ThreadCreated, AgentConnectionStatus } from "./agent-messages.js";
3
+ import { AgentMessage, AgentFileContent, LlmAuthorization, ThreadCreated, AgentConnectionStatus } from "./agent-messages.js";
4
4
  import type { AgentPayload, ClientToolkitDescription } from "./agent-messages.js";
5
5
  import { ChangeEmitter } from "./change-emitter.js";
6
6
  type JsonMap = Record<string, any>;
@@ -92,18 +92,26 @@ export declare class PendingThreadStartCandidate {
92
92
  });
93
93
  }
94
94
  export type ThreadCreatedPendingStartMatcher = (message: InstanceType<typeof ThreadCreated>, candidates: PendingThreadStartCandidate[]) => string | undefined;
95
+ export interface LlmAuthorizationRequest {
96
+ threadId?: string;
97
+ provider?: string;
98
+ model?: string;
99
+ }
100
+ export type LlmAuthorizationProvider = (request: LlmAuthorizationRequest) => Promise<LlmAuthorization | undefined>;
95
101
  export declare abstract class BaseChatClient extends ChangeEmitter {
96
102
  readonly threadCreatedPendingStartMatcher?: ThreadCreatedPendingStartMatcher;
97
103
  readonly deduplicateClientToolRequests: boolean;
104
+ readonly llmAuthorizationProvider?: LlmAuthorizationProvider;
98
105
  private readonly sessionsByPath;
99
106
  private readonly pendingStartRequests;
100
107
  private readonly pendingSessionEventsByPath;
101
108
  private readonly eventQueue;
102
109
  private readonly claimedClientToolRequests;
103
110
  private _connectionStatus?;
104
- constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests, }?: {
111
+ constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests, llmAuthorizationProvider, }?: {
105
112
  threadCreatedPendingStartMatcher?: ThreadCreatedPendingStartMatcher;
106
113
  deduplicateClientToolRequests?: boolean;
114
+ llmAuthorizationProvider?: LlmAuthorizationProvider;
107
115
  });
108
116
  get events(): AsyncIterable<AgentMessageEvent>;
109
117
  get connectionStatus(): InstanceType<typeof AgentConnectionStatus> | undefined;
@@ -186,11 +194,12 @@ export declare class BaseMessagingChatClient extends BaseChatClient {
186
194
  private waitingForParticipant;
187
195
  private roomAbortController?;
188
196
  private messagingListenersAttached;
189
- constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests, }: {
197
+ constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests, llmAuthorizationProvider, }: {
190
198
  room: RoomClient;
191
199
  agentName?: string;
192
200
  threadCreatedPendingStartMatcher?: ThreadCreatedPendingStartMatcher;
193
201
  deduplicateClientToolRequests?: boolean;
202
+ llmAuthorizationProvider?: LlmAuthorizationProvider;
194
203
  });
195
204
  localParticipantName(): string | undefined;
196
205
  localParticipantId(): string | undefined;
@@ -216,7 +225,7 @@ export declare class BaseMessagingChatClient extends BaseChatClient {
216
225
  }
217
226
  export declare class WebSocketChatClient extends BaseChatClient {
218
227
  readonly url: URL;
219
- readonly token: string;
228
+ readonly token?: string;
220
229
  readonly participantName?: string;
221
230
  readonly protocols: string[];
222
231
  readonly reconnect: boolean;
@@ -232,14 +241,15 @@ export declare class WebSocketChatClient extends BaseChatClient {
232
241
  private reconnectAttempts;
233
242
  private reconnectTimer?;
234
243
  private assignedParticipantId?;
235
- constructor({ url, token, participantName, protocols, reconnect, reconnectInitialDelay, reconnectMaxDelay, }: {
244
+ constructor({ url, token, participantName, protocols, reconnect, reconnectInitialDelay, reconnectMaxDelay, llmAuthorizationProvider, }: {
236
245
  url: URL;
237
- token: string;
246
+ token?: string;
238
247
  participantName?: string;
239
248
  protocols?: string[];
240
249
  reconnect?: boolean;
241
250
  reconnectInitialDelay?: number;
242
251
  reconnectMaxDelay?: number;
252
+ llmAuthorizationProvider?: LlmAuthorizationProvider;
243
253
  });
244
254
  get isConnected(): boolean;
245
255
  localParticipantName(): string | undefined;
@@ -179,7 +179,7 @@ class EventQueue {
179
179
  }
180
180
  }
181
181
  class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
182
- constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests = false, } = {}) {
182
+ constructor({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests = false, llmAuthorizationProvider, } = {}) {
183
183
  super();
184
184
  this.sessionsByPath = new Map();
185
185
  this.pendingStartRequests = new Map();
@@ -188,6 +188,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
188
188
  this.claimedClientToolRequests = new Set();
189
189
  this.threadCreatedPendingStartMatcher = threadCreatedPendingStartMatcher;
190
190
  this.deduplicateClientToolRequests = deduplicateClientToolRequests;
191
+ this.llmAuthorizationProvider = llmAuthorizationProvider;
191
192
  }
192
193
  get events() {
193
194
  return this.eventQueue.stream;
@@ -243,6 +244,13 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
243
244
  cleanParticipantName(value) {
244
245
  return nonEmptyTrimmed(value);
245
246
  }
247
+ async resolveLlmAuthorization(request) {
248
+ const authorization = await this.llmAuthorizationProvider?.(request);
249
+ if (authorization?.isExpired === true) {
250
+ throw new Error("LLM authorization callback returned an expired token.");
251
+ }
252
+ return authorization;
253
+ }
246
254
  openThread(threadPath, { load = true, sinceTurn, reloadIfOpen = false, } = {}) {
247
255
  const normalized = threadPath.trim();
248
256
  if (normalized === "") {
@@ -269,6 +277,9 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
269
277
  async startThread({ messageId, message, attachments, name, backend, provider, model, voice, outputModalities, realtimeProtocol, senderName, clientToolkits, omitContent = false, }) {
270
278
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? (0, uuid_1.v4)() : messageId.trim();
271
279
  const resolvedSenderName = this.cleanParticipantName(senderName) ?? this.localParticipantName();
280
+ const llmAuthorization = this.llmAuthorizationProvider == null
281
+ ? undefined
282
+ : await this.resolveLlmAuthorization({ provider, model });
272
283
  const payload = new agent_messages_js_1.StartThread({
273
284
  messageId: resolvedMessageId,
274
285
  content: omitContent ? undefined : (0, agent_messages_js_1.agentInputContent)({ text: message, attachments }),
@@ -281,6 +292,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
281
292
  realtimeProtocol: nonEmptyTrimmed(realtimeProtocol),
282
293
  senderName: resolvedSenderName,
283
294
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
295
+ llmAuthorization,
284
296
  });
285
297
  const completer = new meshagent_1.Completer();
286
298
  this.pendingStartRequests.set(resolvedMessageId, { request: payload, completer });
@@ -329,6 +341,7 @@ class BaseChatClient extends change_emitter_js_1.ChangeEmitter {
329
341
  clientToolkits: payload.clientToolkits,
330
342
  toolkits: payload.toolkits,
331
343
  toolChoice: payload.toolChoice,
344
+ llmAuthorization: payload.llmAuthorization,
332
345
  });
333
346
  }
334
347
  drainPendingSessionEvents(threadPath, session) {
@@ -482,8 +495,8 @@ function participantWaitAbortedError(reason) {
482
495
  return error;
483
496
  }
484
497
  class BaseMessagingChatClient extends BaseChatClient {
485
- constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests = true, }) {
486
- super({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests });
498
+ constructor({ room, agentName, threadCreatedPendingStartMatcher, deduplicateClientToolRequests = true, llmAuthorizationProvider, }) {
499
+ super({ threadCreatedPendingStartMatcher, deduplicateClientToolRequests, llmAuthorizationProvider });
487
500
  this.pendingParticipantWaits = new Map();
488
501
  this.started = false;
489
502
  this.hasConnected = false;
@@ -728,8 +741,8 @@ class BaseMessagingChatClient extends BaseChatClient {
728
741
  }
729
742
  exports.BaseMessagingChatClient = BaseMessagingChatClient;
730
743
  class WebSocketChatClient extends BaseChatClient {
731
- constructor({ url, token, participantName, protocols = ["meshagent-msgpack"], reconnect = true, reconnectInitialDelay = 1000, reconnectMaxDelay = 10000, }) {
732
- super({ deduplicateClientToolRequests: true });
744
+ constructor({ url, token, participantName, protocols = ["meshagent-msgpack"], reconnect = true, reconnectInitialDelay = 1000, reconnectMaxDelay = 10000, llmAuthorizationProvider, }) {
745
+ super({ deduplicateClientToolRequests: true, llmAuthorizationProvider });
733
746
  this.started = false;
734
747
  this.stopping = false;
735
748
  this.connecting = false;
@@ -956,7 +969,7 @@ class WebSocketChatClient extends BaseChatClient {
956
969
  resolved.push(normalized);
957
970
  }
958
971
  }
959
- const normalizedToken = this.token.trim();
972
+ const normalizedToken = this.token?.trim() ?? "";
960
973
  if (normalizedToken !== "") {
961
974
  resolved.push(`meshagent-agent.${normalizedToken}`);
962
975
  }
@@ -1228,6 +1241,9 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1228
1241
  }
1229
1242
  async sendText({ messageId, text, attachments, steer = false, turnId, backend, provider, model, voice, outputModalities, senderName, clientToolkits, }) {
1230
1243
  const resolvedMessageId = messageId == null || messageId.trim() === "" ? (0, uuid_1.v4)() : messageId.trim();
1244
+ const llmAuthorization = steer || this.client.llmAuthorizationProvider == null
1245
+ ? undefined
1246
+ : await this.client.resolveLlmAuthorization({ threadId: this.threadPath, provider, model });
1231
1247
  const payload = steer
1232
1248
  ? new agent_messages_js_1.TurnSteer({
1233
1249
  threadId: this.threadPath,
@@ -1247,6 +1263,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1247
1263
  voice: nonEmptyTrimmed(voice),
1248
1264
  outputModalities: outputModalities != null && outputModalities.length > 0 ? outputModalities : undefined,
1249
1265
  clientToolkits: clientToolkits != null && clientToolkits.length > 0 ? clientToolkits : undefined,
1266
+ llmAuthorization,
1250
1267
  });
1251
1268
  this.localAgentMessageIds.add(resolvedMessageId);
1252
1269
  this.pendingLocalInputMessageIds.add(resolvedMessageId);
@@ -1270,6 +1287,11 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1270
1287
  }
1271
1288
  async commitRealtimeAudio({ turnId, backend, provider, model, voice, outputModalities, }) {
1272
1289
  const messageId = (0, uuid_1.v4)();
1290
+ const llmAuthorization = await this.client.resolveLlmAuthorization({
1291
+ threadId: this.threadPath,
1292
+ provider,
1293
+ model,
1294
+ });
1273
1295
  await this.client.sendAgentMessage(new agent_messages_js_1.AgentRealtimeAudioCommit({
1274
1296
  threadId: this.threadPath,
1275
1297
  messageId,
@@ -1284,6 +1306,7 @@ class ChatThreadSession extends change_emitter_js_1.ChangeEmitter {
1284
1306
  model: nonEmptyTrimmed(model),
1285
1307
  voice: nonEmptyTrimmed(voice),
1286
1308
  outputModalities: outputModalities != null && outputModalities.length > 0 ? outputModalities : undefined,
1309
+ llmAuthorization,
1287
1310
  }));
1288
1311
  return messageId;
1289
1312
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshagent/meshagent-agents",
3
- "version": "0.49.1",
3
+ "version": "0.51.0",
4
4
  "description": "Agent chat sessions and clients for Meshagent TypeScript applications.",
5
5
  "homepage": "https://github.com/meshagent/meshagent-agents-ts",
6
6
  "scripts": {
@@ -50,7 +50,7 @@
50
50
  "ws": "^8.21.1"
51
51
  },
52
52
  "dependencies": {
53
- "@meshagent/meshagent": "^0.49.1",
53
+ "@meshagent/meshagent": "^0.51.0",
54
54
  "@msgpack/msgpack": "^3.1.3",
55
55
  "apache-arrow": "^21.0.0",
56
56
  "isomorphic-ws": "^5.0.0",