@mastra/client-js 1.32.1-alpha.2 → 1.33.0-alpha.3

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/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export * from './tools.js';
4
4
  export type { ChannelPlatformInfo, ChannelInstallationInfo, ChannelConnectOAuth, ChannelConnectDeepLink, ChannelConnectImmediate, ChannelConnectResult, } from './resources/channels.js';
5
5
  export type { AgentCardSignatureKeyProviderInput, AgentCardVerificationKey, GetAgentCardOptions, VerifyAgentCardSignatureOptions, } from './resources/a2a.js';
6
6
  export { agentControllerMessageText } from './resources/agent-controller.js';
7
- export type { AgentControllerInfo, AgentControllerMessage, AgentControllerMessageContent, AgentControllerEvent, KnownAgentControllerEvent, OtherAgentControllerEvent, CreateAgentControllerSessionResponse, SubscribeAgentControllerSessionOptions, AgentControllerSubscription, AgentControllerSessionState, AgentControllerSessionSettings, AgentControllerOMProgress, AgentControllerModeInfo, AgentControllerThreadInfo, AgentControllerTaskSnapshot, AgentControllerAvailableModel, AgentControllerWorkspaceStatus, AgentControllerGoalRecord, SendNotificationInput, SendNotificationResult, PlanResume, PermissionPolicy, PermissionRules, ToolCategory, } from './resources/agent-controller.js';
7
+ export type { AgentControllerInfo, MastraDBMessage, MastraMessageContentV2, MastraMessagePart, AgentControllerEvent, KnownAgentControllerEvent, OtherAgentControllerEvent, CreateAgentControllerSessionResponse, AgentControllerRequestOptions, SubscribeAgentControllerSessionOptions, AgentControllerSubscription, AgentControllerSessionState, AgentControllerSessionSettings, AgentControllerOMProgress, AgentControllerModeInfo, AgentControllerThreadInfo, AgentControllerTaskSnapshot, AgentControllerAvailableModel, AgentControllerWorkspaceStatus, AgentControllerGoalRecord, SendNotificationInput, SendNotificationResult, PlanResume, PermissionPolicy, PermissionRules, ToolCategory, } from './resources/agent-controller.js';
8
8
  export { RequestContext } from '@mastra/core/request-context';
9
9
  export type { ObservabilityCollector } from './observability/types.js';
10
10
  export type { UIMessageWithMetadata } from '@mastra/core/agent';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,6BAA6B,EAC7B,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,EACzB,oCAAoC,EACpC,sCAAsC,EACtC,2BAA2B,EAC3B,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,8BAA8B,EAC9B,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,YAAY,GACb,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACxE,YAAY,EACV,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,UAAU,EACV,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,UAAU,EACV,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,UAAU,GACX,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,EACzB,oCAAoC,EACpC,6BAA6B,EAC7B,sCAAsC,EACtC,2BAA2B,EAC3B,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,EAC3B,6BAA6B,EAC7B,8BAA8B,EAC9B,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACtB,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,YAAY,GACb,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACxE,YAAY,EACV,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,UAAU,EACV,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,UAAU,EACV,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,UAAU,GACX,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -6139,6 +6139,19 @@ var Channels = class extends BaseResource {
6139
6139
  };
6140
6140
 
6141
6141
  // src/resources/agent-controller.ts
6142
+ function hydrateMessage(message) {
6143
+ return {
6144
+ ...message,
6145
+ createdAt: message.createdAt instanceof Date ? message.createdAt : new Date(message.createdAt)
6146
+ };
6147
+ }
6148
+ function hydrateEventMessage(event) {
6149
+ if (event.type !== "message_start" && event.type !== "message_update" && event.type !== "message_end") return event;
6150
+ return {
6151
+ ...event,
6152
+ message: hydrateMessage(event.message)
6153
+ };
6154
+ }
6142
6155
  var AgentControllerSession = class extends BaseResource {
6143
6156
  constructor(options, controllerId, resourceId, scope) {
6144
6157
  super(options);
@@ -6174,46 +6187,158 @@ var AgentControllerSession = class extends BaseResource {
6174
6187
  /**
6175
6188
  * Subscribe to this session's event stream (SSE). The assistant's reply to a
6176
6189
  * message arrives here as `message_*` events, not on the sendMessage call.
6190
+ *
6191
+ * The returned promise resolves once the stream is actually established and
6192
+ * rejects when it cannot be. A rejected subscribe leaves nothing running —
6193
+ * `reconnect` governs only re-establishment after an established stream
6194
+ * drops, so callers that want connect-time retry can loop around
6195
+ * `subscribe()` themselves and keep cancellation control.
6177
6196
  */
6178
6197
  async subscribe(options) {
6179
- const response = await this.request(this.url(`${this.base()}/stream`), { stream: true });
6180
- if (!response.body) {
6181
- throw new Error("No response body for agent controller session stream");
6182
- }
6183
- const reader = response.body.getReader();
6184
- const decoder = new TextDecoder();
6198
+ const finiteOr = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
6199
+ const retriesOr = (value, fallback) => value === Infinity || typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
6200
+ const reconnectOptions = options.reconnect === true ? { maxRetries: Infinity, delayMs: 1e3, maxDelayMs: 3e4 } : options.reconnect ? {
6201
+ maxRetries: retriesOr(options.reconnect.maxRetries, Infinity),
6202
+ delayMs: finiteOr(options.reconnect.delayMs, 1e3),
6203
+ maxDelayMs: finiteOr(options.reconnect.maxDelayMs, 3e4)
6204
+ } : null;
6205
+ const backoffDelay = (attempt) => reconnectOptions ? Math.min(reconnectOptions.delayMs * 2 ** (attempt - 1), reconnectOptions.maxDelayMs) : 0;
6185
6206
  let cancelled = false;
6186
- let buffer = "";
6187
- const pump = async () => {
6207
+ let currentReader = null;
6208
+ let reconnectTimer;
6209
+ let delayResolve;
6210
+ const settleDelay = () => {
6211
+ if (reconnectTimer) {
6212
+ clearTimeout(reconnectTimer);
6213
+ reconnectTimer = void 0;
6214
+ }
6215
+ const resolve = delayResolve;
6216
+ delayResolve = void 0;
6217
+ resolve?.();
6218
+ };
6219
+ const delay = (ms) => new Promise((resolve) => {
6220
+ delayResolve = resolve;
6221
+ reconnectTimer = setTimeout(settleDelay, ms);
6222
+ });
6223
+ const requestStream = async () => {
6224
+ const response = await this.request(this.url(`${this.base()}/stream`), { stream: true });
6225
+ if (!response.body) {
6226
+ throw new Error("No response body for agent controller session stream");
6227
+ }
6228
+ return response;
6229
+ };
6230
+ const streamEndedError = () => new Error("Agent controller session stream ended unexpectedly");
6231
+ const findFrameSeparator = (text) => {
6232
+ const candidates = [
6233
+ { index: text.indexOf("\r\n\r\n"), length: 4 },
6234
+ { index: text.indexOf("\n\n"), length: 2 },
6235
+ { index: text.indexOf("\r\r"), length: 2 }
6236
+ ].filter((candidate) => candidate.index !== -1);
6237
+ if (candidates.length === 0) return null;
6238
+ return candidates.reduce((earliest, candidate) => candidate.index < earliest.index ? candidate : earliest);
6239
+ };
6240
+ const pump = async (response) => {
6241
+ const reader = response.body.getReader();
6242
+ currentReader = reader;
6243
+ const decoder = new TextDecoder();
6244
+ let buffer = "";
6188
6245
  try {
6189
6246
  while (!cancelled) {
6190
6247
  const { done, value } = await reader.read();
6191
- if (done) break;
6248
+ if (done) return cancelled ? { kind: "cancelled" } : { kind: "done" };
6192
6249
  buffer += decoder.decode(value, { stream: true });
6193
- let sep;
6194
- while ((sep = buffer.indexOf("\n\n")) !== -1) {
6195
- const frame = buffer.slice(0, sep);
6196
- buffer = buffer.slice(sep + 2);
6197
- for (const line of frame.split("\n")) {
6250
+ let separator;
6251
+ while ((separator = findFrameSeparator(buffer)) !== null) {
6252
+ const frame = buffer.slice(0, separator.index);
6253
+ buffer = buffer.slice(separator.index + separator.length);
6254
+ for (const line of frame.split(/\r\n|\n|\r/)) {
6198
6255
  if (!line.startsWith("data:")) continue;
6199
6256
  const data = line.slice(5).trim();
6200
6257
  if (!data) continue;
6258
+ let event;
6201
6259
  try {
6202
- options.onEvent(JSON.parse(data));
6260
+ event = hydrateEventMessage(JSON.parse(data));
6203
6261
  } catch {
6262
+ continue;
6263
+ }
6264
+ try {
6265
+ options.onEvent(event);
6266
+ } catch (cause) {
6267
+ if (!cancelled) safeOnError(cause);
6268
+ return { kind: "consumer_error" };
6204
6269
  }
6205
6270
  }
6206
6271
  }
6207
6272
  }
6273
+ return { kind: "cancelled" };
6274
+ } catch (error) {
6275
+ return cancelled ? { kind: "cancelled" } : { kind: "transport_error", error };
6276
+ } finally {
6277
+ if (currentReader === reader) currentReader = null;
6278
+ void reader.cancel().catch(() => {
6279
+ });
6280
+ }
6281
+ };
6282
+ const safeOnError = (error) => {
6283
+ try {
6284
+ options.onError?.(error);
6285
+ } catch {
6286
+ }
6287
+ };
6288
+ const reportTerminalError = (result) => {
6289
+ safeOnError(result.kind === "transport_error" ? result.error : streamEndedError());
6290
+ };
6291
+ const pumpSafe = async (response) => {
6292
+ try {
6293
+ return await pump(response);
6208
6294
  } catch (error) {
6209
- if (!cancelled) options.onError?.(error);
6295
+ return cancelled ? { kind: "cancelled" } : { kind: "transport_error", error };
6296
+ }
6297
+ };
6298
+ const firstResponse = await requestStream();
6299
+ const run = async (initial) => {
6300
+ let response = initial;
6301
+ while (!cancelled) {
6302
+ let result = await pumpSafe(response);
6303
+ if (cancelled || result.kind === "cancelled" || result.kind === "consumer_error") return;
6304
+ if (!reconnectOptions) {
6305
+ reportTerminalError(result);
6306
+ return;
6307
+ }
6308
+ let attempts = 0;
6309
+ let reconnectedResponse;
6310
+ while (!reconnectedResponse) {
6311
+ if (attempts >= reconnectOptions.maxRetries) {
6312
+ reportTerminalError(result);
6313
+ return;
6314
+ }
6315
+ attempts++;
6316
+ await delay(backoffDelay(attempts));
6317
+ if (cancelled) return;
6318
+ try {
6319
+ reconnectedResponse = await requestStream();
6320
+ } catch (error) {
6321
+ result = { kind: "transport_error", error };
6322
+ }
6323
+ }
6324
+ if (cancelled) {
6325
+ void reconnectedResponse.body?.cancel().catch(() => {
6326
+ });
6327
+ return;
6328
+ }
6329
+ response = reconnectedResponse;
6330
+ try {
6331
+ options.onReconnect?.();
6332
+ } catch {
6333
+ }
6210
6334
  }
6211
6335
  };
6212
- void pump();
6336
+ void run(firstResponse);
6213
6337
  return {
6214
6338
  unsubscribe: () => {
6215
6339
  cancelled = true;
6216
- void reader.cancel().catch(() => {
6340
+ settleDelay();
6341
+ void currentReader?.cancel().catch(() => {
6217
6342
  });
6218
6343
  }
6219
6344
  };
@@ -6222,12 +6347,18 @@ var AgentControllerSession = class extends BaseResource {
6222
6347
  * Send a user message. The reply streams over `subscribe()`.
6223
6348
  * Pass a structured message to attach files (e.g. pasted images) as base64-encoded data:
6224
6349
  * `sendMessage({ content: 'What is in this image?', files })`.
6350
+ * Pass `options.requestContext` to merge custom context into the run's request context.
6225
6351
  */
6226
- async sendMessage(message) {
6352
+ async sendMessage(message, options) {
6227
6353
  const { content, files } = typeof message === "string" ? { content: message, files: void 0 } : message;
6354
+ const requestContext = parseClientRequestContext(options?.requestContext);
6228
6355
  await this.request(this.url(`${this.base()}/messages`), {
6229
6356
  method: "POST",
6230
- body: { message: content, ...files?.length ? { files } : {} }
6357
+ body: {
6358
+ message: content,
6359
+ ...files?.length ? { files } : {},
6360
+ ...requestContext ? { requestContext } : {}
6361
+ }
6231
6362
  });
6232
6363
  }
6233
6364
  /** Abort the in-flight run for this session. */
@@ -6235,10 +6366,11 @@ var AgentControllerSession = class extends BaseResource {
6235
6366
  await this.request(this.url(`${this.base()}/abort`), { method: "POST" });
6236
6367
  }
6237
6368
  /** Approve or decline a pending tool call (`tool_approval_required`). */
6238
- async approveTool(toolCallId, approved) {
6369
+ async approveTool(toolCallId, approved, options) {
6370
+ const requestContext = parseClientRequestContext(options?.requestContext);
6239
6371
  await this.request(this.url(`${this.base()}/tool-approval`), {
6240
6372
  method: "POST",
6241
- body: { toolCallId, approved }
6373
+ body: { toolCallId, approved, ...requestContext ? { requestContext } : {} }
6242
6374
  });
6243
6375
  }
6244
6376
  /**
@@ -6246,15 +6378,20 @@ var AgentControllerSession = class extends BaseResource {
6246
6378
  * depends on the tool: a string (or string[]) for `ask_user`, "Yes"/"No" for
6247
6379
  * `request_access`, and a {@link PlanResume} for `submit_plan`.
6248
6380
  */
6249
- async respondToToolSuspension(toolCallId, resumeData) {
6381
+ async respondToToolSuspension(toolCallId, resumeData, options) {
6382
+ const requestContext = parseClientRequestContext(options?.requestContext);
6250
6383
  await this.request(this.url(`${this.base()}/tool-suspension`), {
6251
6384
  method: "POST",
6252
- body: { toolCallId, resumeData }
6385
+ body: { toolCallId, resumeData, ...requestContext ? { requestContext } : {} }
6253
6386
  });
6254
6387
  }
6255
6388
  /** Inject a message into the in-flight run without starting a new turn. */
6256
- async steer(message) {
6257
- await this.request(this.url(`${this.base()}/steer`), { method: "POST", body: { message } });
6389
+ async steer(message, options) {
6390
+ const requestContext = parseClientRequestContext(options?.requestContext);
6391
+ await this.request(this.url(`${this.base()}/steer`), {
6392
+ method: "POST",
6393
+ body: { message, ...requestContext ? { requestContext } : {} }
6394
+ });
6258
6395
  }
6259
6396
  /** Get the current mode, model, and thread (for initial UI hydration). */
6260
6397
  state() {
@@ -6330,14 +6467,18 @@ var AgentControllerSession = class extends BaseResource {
6330
6467
  const body = await this.request(
6331
6468
  this.url(`${this.base()}/threads/${encodeURIComponent(threadId)}/messages${params}`)
6332
6469
  );
6333
- return body.messages;
6470
+ return body.messages.map(hydrateMessage);
6334
6471
  }
6335
6472
  /**
6336
6473
  * Queue a follow-up message. If the session is idle it sends immediately;
6337
6474
  * if a run is active it queues for after completion.
6338
6475
  */
6339
- async followUp(message) {
6340
- await this.request(this.url(`${this.base()}/follow-up`), { method: "POST", body: { message } });
6476
+ async followUp(message, options) {
6477
+ const requestContext = parseClientRequestContext(options?.requestContext);
6478
+ await this.request(this.url(`${this.base()}/follow-up`), {
6479
+ method: "POST",
6480
+ body: { message, ...requestContext ? { requestContext } : {} }
6481
+ });
6341
6482
  }
6342
6483
  /** Get the observational memory record for this session's thread. */
6343
6484
  async getOMRecord() {
@@ -6447,7 +6588,7 @@ var AgentController = class extends BaseResource {
6447
6588
  }
6448
6589
  };
6449
6590
  function agentControllerMessageText(message) {
6450
- return message.content.filter((c) => c.type === "text" && typeof c.text === "string").map((c) => c.text).join("");
6591
+ return message.content.parts.filter((p) => p.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
6451
6592
  }
6452
6593
 
6453
6594
  // src/client.ts