@mastra/client-js 1.56.0-alpha.10 → 1.56.0-alpha.11

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.
@@ -3,7 +3,7 @@ name: mastra-client-js
3
3
  description: Documentation for @mastra/client-js. Use when working with @mastra/client-js APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/client-js"
6
- version: "1.56.0-alpha.10"
6
+ version: "1.56.0-alpha.11"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.56.0-alpha.10",
2
+ "version": "1.56.0-alpha.11",
3
3
  "package": "@mastra/client-js",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
16
16
  }
17
17
  return to;
18
18
  };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
20
20
  value: mod,
21
21
  enumerable: true
22
22
  }) : target, mod));
@@ -83,15 +83,16 @@ function attributesToOtlp(attrs) {
83
83
  key,
84
84
  value: { boolValue: raw }
85
85
  });
86
- else if (typeof raw === "number") if (Number.isInteger(raw)) out.push({
87
- key,
88
- value: { intValue: raw }
89
- });
90
- else out.push({
91
- key,
92
- value: { doubleValue: raw }
93
- });
94
- else try {
86
+ else if (typeof raw === "number") {
87
+ if (Number.isInteger(raw)) out.push({
88
+ key,
89
+ value: { intValue: raw }
90
+ });
91
+ else out.push({
92
+ key,
93
+ value: { doubleValue: raw }
94
+ });
95
+ } else try {
95
96
  out.push({
96
97
  key,
97
98
  value: { stringValue: JSON.stringify(raw) }
@@ -686,7 +687,6 @@ function fixJson(input) {
686
687
  stack.pop();
687
688
  stack.push(swapState);
688
689
  stack.push("INSIDE_ARRAY_START");
689
- break;
690
690
  }
691
691
  }
692
692
  function processAfterObjectValue(char, i) {
@@ -698,7 +698,6 @@ function fixJson(input) {
698
698
  case "}":
699
699
  lastValidIndex = i;
700
700
  stack.pop();
701
- break;
702
701
  }
703
702
  }
704
703
  function processAfterArrayValue(char, i) {
@@ -710,7 +709,6 @@ function fixJson(input) {
710
709
  case "]":
711
710
  lastValidIndex = i;
712
711
  stack.pop();
713
- break;
714
712
  }
715
713
  }
716
714
  for (let i = 0; i < input.length; i++) {
@@ -728,7 +726,6 @@ function fixJson(input) {
728
726
  case "}":
729
727
  lastValidIndex = i;
730
728
  stack.pop();
731
- break;
732
729
  }
733
730
  break;
734
731
  case "INSIDE_OBJECT_AFTER_COMMA":
@@ -736,7 +733,6 @@ function fixJson(input) {
736
733
  case "\"":
737
734
  stack.pop();
738
735
  stack.push("INSIDE_OBJECT_KEY");
739
- break;
740
736
  }
741
737
  break;
742
738
  case "INSIDE_OBJECT_KEY":
@@ -744,7 +740,6 @@ function fixJson(input) {
744
740
  case "\"":
745
741
  stack.pop();
746
742
  stack.push("INSIDE_OBJECT_AFTER_KEY");
747
- break;
748
743
  }
749
744
  break;
750
745
  case "INSIDE_OBJECT_AFTER_KEY":
@@ -752,7 +747,6 @@ function fixJson(input) {
752
747
  case ":":
753
748
  stack.pop();
754
749
  stack.push("INSIDE_OBJECT_BEFORE_VALUE");
755
- break;
756
750
  }
757
751
  break;
758
752
  case "INSIDE_OBJECT_BEFORE_VALUE":
@@ -782,7 +776,6 @@ function fixJson(input) {
782
776
  default:
783
777
  lastValidIndex = i;
784
778
  processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
785
- break;
786
779
  }
787
780
  break;
788
781
  case "INSIDE_ARRAY_AFTER_VALUE":
@@ -795,9 +788,7 @@ function fixJson(input) {
795
788
  lastValidIndex = i;
796
789
  stack.pop();
797
790
  break;
798
- default:
799
- lastValidIndex = i;
800
- break;
791
+ default: lastValidIndex = i;
801
792
  }
802
793
  break;
803
794
  case "INSIDE_ARRAY_AFTER_COMMA":
@@ -838,9 +829,7 @@ function fixJson(input) {
838
829
  stack.pop();
839
830
  if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") processAfterArrayValue(char, i);
840
831
  break;
841
- default:
842
- stack.pop();
843
- break;
832
+ default: stack.pop();
844
833
  }
845
834
  break;
846
835
  case "INSIDE_LITERAL": {
@@ -1249,8 +1238,16 @@ var BaseResource = class {
1249
1238
  };
1250
1239
  //#endregion
1251
1240
  //#region src/resources/agent.ts
1252
- const SIGNAL_RUNTIME_OPTIONS_TTL_MS = 300 * 1e3;
1241
+ const SIGNAL_RUNTIME_OPTIONS_TTL_MS = 3e5;
1253
1242
  const signalRuntimeOptionsByRunId = /* @__PURE__ */ new Map();
1243
+ /**
1244
+ * Client tools a resume request can execute, keyed by run. The stream that stayed open from
1245
+ * before the suspension must not run those tools again, but it must run any resumed client tool
1246
+ * the resume request cannot execute (a server-side approve sends no client tools). Held until the
1247
+ * last stream of the run closes, which is after the resume request returns.
1248
+ */
1249
+ const resumingClientToolNamesByRunKey = /* @__PURE__ */ new Map();
1250
+ const openStreamCountByRunKey = /* @__PURE__ */ new Map();
1254
1251
  const latestSignalRuntimeOptionsByThread = /* @__PURE__ */ new Map();
1255
1252
  const createSignalRuntimeOptionsEntry = (store, key, streamOptions) => {
1256
1253
  const timeout = setTimeout(() => store.delete(key), SIGNAL_RUNTIME_OPTIONS_TTL_MS);
@@ -1443,6 +1440,49 @@ var Agent = class extends BaseResource {
1443
1440
  getSignalRuntimeRunKey(runId) {
1444
1441
  return `${this.options.baseUrl}|${this.apiPrefix}|${this.agentId}|${runId}`;
1445
1442
  }
1443
+ /**
1444
+ * Records that `runId` is being resumed by a request that can execute these client tools, so the
1445
+ * stream that is still open from before the suspension skips them. Released when the last stream
1446
+ * of the run closes, which is after this request returns.
1447
+ */
1448
+ holdResumingClientTools(runId, clientTools) {
1449
+ const names = Object.entries(clientTools ?? {}).filter(([, tool]) => typeof tool.execute === "function").map(([name]) => name);
1450
+ if (names.length === 0) return () => {};
1451
+ const key = this.getSignalRuntimeRunKey(runId);
1452
+ const held = resumingClientToolNamesByRunKey.get(key) ?? /* @__PURE__ */ new Map();
1453
+ for (const name of names) held.set(name, (held.get(name) ?? 0) + 1);
1454
+ resumingClientToolNamesByRunKey.set(key, held);
1455
+ let released = false;
1456
+ return ({ force = false } = {}) => {
1457
+ if (released || !force && openStreamCountByRunKey.has(key)) return;
1458
+ released = true;
1459
+ const current = resumingClientToolNamesByRunKey.get(key);
1460
+ if (!current) return;
1461
+ for (const name of names) {
1462
+ const count = (current.get(name) ?? 1) - 1;
1463
+ if (count > 0) current.set(name, count);
1464
+ else current.delete(name);
1465
+ }
1466
+ if (current.size === 0) resumingClientToolNamesByRunKey.delete(key);
1467
+ };
1468
+ }
1469
+ /** Drops the held tool names when the last stream of the run closes. */
1470
+ trackOpenStream(runId) {
1471
+ const key = this.getSignalRuntimeRunKey(runId);
1472
+ openStreamCountByRunKey.set(key, (openStreamCountByRunKey.get(key) ?? 0) + 1);
1473
+ let released = false;
1474
+ return () => {
1475
+ if (released) return;
1476
+ released = true;
1477
+ const remaining = (openStreamCountByRunKey.get(key) ?? 1) - 1;
1478
+ if (remaining > 0) {
1479
+ openStreamCountByRunKey.set(key, remaining);
1480
+ return;
1481
+ }
1482
+ openStreamCountByRunKey.delete(key);
1483
+ resumingClientToolNamesByRunKey.delete(key);
1484
+ };
1485
+ }
1446
1486
  getSignalRuntimeThreadKey({ resourceId, threadId }) {
1447
1487
  if (!threadId) return void 0;
1448
1488
  return `${this.options.baseUrl}|${this.apiPrefix}|${this.agentId}|${resourceId ?? ""}|${threadId}`;
@@ -2580,7 +2620,6 @@ var Agent = class extends BaseResource {
2580
2620
  case "finish":
2581
2621
  finishReason = chunk.payload?.stepResult?.reason ?? finishReason;
2582
2622
  if (chunk.payload?.usage != null) usage = chunk.payload.usage;
2583
- break;
2584
2623
  }
2585
2624
  }
2586
2625
  });
@@ -2645,6 +2684,9 @@ var Agent = class extends BaseResource {
2645
2684
  let messages = [];
2646
2685
  let streamRunId = processedParams.runId;
2647
2686
  let finishedHistory;
2687
+ let suspended = false;
2688
+ const resumedToolCallIds = /* @__PURE__ */ new Set();
2689
+ const releaseOpenStream = streamRunId ? this.trackOpenStream(streamRunId) : () => {};
2648
2690
  const [streamForController, streamForProcessing] = response.body.tee();
2649
2691
  const decoder = new TextDecoder();
2650
2692
  let pendingText = "";
@@ -2713,6 +2755,9 @@ var Agent = class extends BaseResource {
2713
2755
  });
2714
2756
  }
2715
2757
  const executableToolCalls = [...toolInvocationsById.values()].filter((toolCall) => {
2758
+ if (resumedToolCallIds.has(toolCall.toolCallId)) {
2759
+ if ((streamRunId ? resumingClientToolNamesByRunKey.get(this.getSignalRuntimeRunKey(streamRunId)) : void 0)?.has(toolCall.toolName)) return false;
2760
+ }
2716
2761
  const clientTool = processedParams.clientTools?.[toolCall.toolName];
2717
2762
  return Boolean(clientTool?.execute);
2718
2763
  });
@@ -2839,6 +2884,12 @@ var Agent = class extends BaseResource {
2839
2884
  },
2840
2885
  onStreamChunk: (chunk) => {
2841
2886
  if (!streamRunId && typeof chunk.runId === "string") streamRunId = chunk.runId;
2887
+ if (chunk.type === "tool-call-approval" || chunk.type === "tool-call-suspended") suspended = true;
2888
+ else if (suspended && chunk.type === "tool-call" && typeof chunk.payload?.toolCallId === "string") {
2889
+ const toolName = chunk.payload.toolName;
2890
+ const held = streamRunId ? resumingClientToolNamesByRunKey.get(this.getSignalRuntimeRunKey(streamRunId)) : void 0;
2891
+ if (typeof toolName === "string" && held?.has(toolName)) resumedToolCallIds.add(chunk.payload.toolCallId);
2892
+ }
2842
2893
  },
2843
2894
  lastMessage: void 0
2844
2895
  }).catch(async (error) => {
@@ -2849,6 +2900,7 @@ var Agent = class extends BaseResource {
2849
2900
  safeClose();
2850
2901
  }).finally(() => {
2851
2902
  signal?.removeEventListener("abort", onAbort);
2903
+ releaseOpenStream();
2852
2904
  });
2853
2905
  } catch (error) {
2854
2906
  if (!isAbortError(error)) console.error("Error processing stream response:", error);
@@ -3016,13 +3068,18 @@ var Agent = class extends BaseResource {
3016
3068
  }
3017
3069
  async approveToolCall(params) {
3018
3070
  const { requestContext, ...rest } = params;
3071
+ const executableClientTools = params.clientToolsResolver?.() ?? params.clientTools;
3072
+ const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
3019
3073
  const processedParams = {
3020
3074
  ...rest,
3021
3075
  requestContext: parseClientRequestContext(requestContext),
3022
- clientTools: processClientTools(params.clientToolsResolver?.() ?? params.clientTools)
3076
+ clientTools: processClientTools(executableClientTools)
3023
3077
  };
3024
3078
  const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
3025
- const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call", signal);
3079
+ const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call", signal).catch((error) => {
3080
+ releaseHold({ force: true });
3081
+ throw error;
3082
+ });
3026
3083
  const streamResponse = new Response(readable, {
3027
3084
  status: response.status,
3028
3085
  statusText: response.statusText,
@@ -3048,13 +3105,18 @@ var Agent = class extends BaseResource {
3048
3105
  }
3049
3106
  async declineToolCall(params) {
3050
3107
  const { requestContext, ...rest } = params;
3108
+ const executableClientTools = params.clientToolsResolver?.() ?? params.clientTools;
3109
+ const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
3051
3110
  const processedParams = {
3052
3111
  ...rest,
3053
3112
  requestContext: parseClientRequestContext(requestContext),
3054
- clientTools: processClientTools(params.clientToolsResolver?.() ?? params.clientTools)
3113
+ clientTools: processClientTools(executableClientTools)
3055
3114
  };
3056
3115
  const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
3057
- const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call", signal);
3116
+ const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call", signal).catch((error) => {
3117
+ releaseHold({ force: true });
3118
+ throw error;
3119
+ });
3058
3120
  const streamResponse = new Response(readable, {
3059
3121
  status: response.status,
3060
3122
  statusText: response.statusText,
@@ -3114,18 +3176,23 @@ var Agent = class extends BaseResource {
3114
3176
  * Used to continue execution after a suspension point (e.g., workflow suspend within an agent).
3115
3177
  */
3116
3178
  async resumeStream(resumeData, options) {
3179
+ const executableClientTools = options.clientToolsResolver?.() ?? options.clientTools;
3180
+ const releaseHold = this.holdResumingClientTools(options.runId, executableClientTools);
3117
3181
  const processedParams = {
3118
3182
  ...options,
3119
3183
  resumeData,
3120
3184
  requestContext: parseClientRequestContext(options.requestContext),
3121
- clientTools: processClientTools(options.clientToolsResolver?.() ?? options.clientTools),
3185
+ clientTools: processClientTools(executableClientTools),
3122
3186
  structuredOutput: options.structuredOutput ? {
3123
3187
  ...options.structuredOutput,
3124
3188
  schema: (0, _mastra_schema_compat_schema.standardSchemaToJSONSchema)((0, _mastra_schema_compat_schema.toStandardSchema)(options.structuredOutput.schema))
3125
3189
  } : void 0
3126
3190
  };
3127
3191
  const { readable, controller: readableController, signal } = this.createCancellableStream(options.abortSignal);
3128
- const response = await this.processStreamResponse(processedParams, readableController, "resume-stream", signal);
3192
+ const response = await this.processStreamResponse(processedParams, readableController, "resume-stream", signal).catch((error) => {
3193
+ releaseHold({ force: true });
3194
+ throw error;
3195
+ });
3129
3196
  const streamResponse = new Response(readable, {
3130
3197
  status: response.status,
3131
3198
  statusText: response.statusText,
@@ -3178,18 +3245,23 @@ var Agent = class extends BaseResource {
3178
3245
  * Used to continue execution after a suspension point (e.g., workflow suspend within an agent).
3179
3246
  */
3180
3247
  async resumeStreamUntilIdle(resumeData, options) {
3248
+ const executableClientTools = options.clientToolsResolver?.() ?? options.clientTools;
3249
+ const releaseHold = this.holdResumingClientTools(options.runId, executableClientTools);
3181
3250
  const processedParams = {
3182
3251
  ...options,
3183
3252
  resumeData,
3184
3253
  requestContext: parseClientRequestContext(options.requestContext),
3185
- clientTools: processClientTools(options.clientToolsResolver?.() ?? options.clientTools),
3254
+ clientTools: processClientTools(executableClientTools),
3186
3255
  structuredOutput: options.structuredOutput ? {
3187
3256
  ...options.structuredOutput,
3188
3257
  schema: (0, _mastra_schema_compat_schema.standardSchemaToJSONSchema)((0, _mastra_schema_compat_schema.toStandardSchema)(options.structuredOutput.schema))
3189
3258
  } : void 0
3190
3259
  };
3191
3260
  const { readable, controller: readableController, signal } = this.createCancellableStream(options.abortSignal);
3192
- const response = await this.processStreamResponse(processedParams, readableController, "resume-stream-until-idle", signal);
3261
+ const response = await this.processStreamResponse(processedParams, readableController, "resume-stream-until-idle", signal).catch((error) => {
3262
+ releaseHold({ force: true });
3263
+ throw error;
3264
+ });
3193
3265
  const streamResponse = new Response(readable, {
3194
3266
  status: response.status,
3195
3267
  statusText: response.statusText,
@@ -3209,20 +3281,32 @@ var Agent = class extends BaseResource {
3209
3281
  */
3210
3282
  async approveToolCallGenerate(params) {
3211
3283
  const { requestContext, clientTools, clientToolsResolver, memory, ...rest } = params;
3212
- const response = await this.request(`/agents/${this.agentId}/approve-tool-call-generate`, {
3213
- method: "POST",
3214
- body: {
3215
- ...rest,
3216
- requestContext: parseClientRequestContext(requestContext),
3217
- clientTools: processClientTools(clientToolsResolver?.() ?? clientTools)
3218
- }
3219
- });
3220
- return this.continueResumedGenerate(response, {
3221
- requestContext,
3222
- clientTools,
3223
- clientToolsResolver,
3224
- memory
3225
- });
3284
+ const executableClientTools = clientToolsResolver?.() ?? clientTools;
3285
+ const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
3286
+ let response;
3287
+ try {
3288
+ response = await this.request(`/agents/${this.agentId}/approve-tool-call-generate`, {
3289
+ method: "POST",
3290
+ body: {
3291
+ ...rest,
3292
+ requestContext: parseClientRequestContext(requestContext),
3293
+ clientTools: processClientTools(executableClientTools)
3294
+ }
3295
+ });
3296
+ } catch (error) {
3297
+ releaseHold({ force: true });
3298
+ throw error;
3299
+ }
3300
+ try {
3301
+ return await this.continueResumedGenerate(response, {
3302
+ requestContext,
3303
+ clientTools: executableClientTools,
3304
+ clientToolsResolver,
3305
+ memory
3306
+ });
3307
+ } finally {
3308
+ releaseHold();
3309
+ }
3226
3310
  }
3227
3311
  /**
3228
3312
  * Declines a pending tool call and returns the complete response (non-streaming).
@@ -3230,20 +3314,32 @@ var Agent = class extends BaseResource {
3230
3314
  */
3231
3315
  async declineToolCallGenerate(params) {
3232
3316
  const { requestContext, clientTools, clientToolsResolver, memory, ...rest } = params;
3233
- const response = await this.request(`/agents/${this.agentId}/decline-tool-call-generate`, {
3234
- method: "POST",
3235
- body: {
3236
- ...rest,
3237
- requestContext: parseClientRequestContext(requestContext),
3238
- clientTools: processClientTools(clientToolsResolver?.() ?? clientTools)
3239
- }
3240
- });
3241
- return this.continueResumedGenerate(response, {
3242
- requestContext,
3243
- clientTools,
3244
- clientToolsResolver,
3245
- memory
3246
- });
3317
+ const executableClientTools = clientToolsResolver?.() ?? clientTools;
3318
+ const releaseHold = this.holdResumingClientTools(rest.runId, executableClientTools);
3319
+ let response;
3320
+ try {
3321
+ response = await this.request(`/agents/${this.agentId}/decline-tool-call-generate`, {
3322
+ method: "POST",
3323
+ body: {
3324
+ ...rest,
3325
+ requestContext: parseClientRequestContext(requestContext),
3326
+ clientTools: processClientTools(executableClientTools)
3327
+ }
3328
+ });
3329
+ } catch (error) {
3330
+ releaseHold({ force: true });
3331
+ throw error;
3332
+ }
3333
+ try {
3334
+ return await this.continueResumedGenerate(response, {
3335
+ requestContext,
3336
+ clientTools: executableClientTools,
3337
+ clientToolsResolver,
3338
+ memory
3339
+ });
3340
+ } finally {
3341
+ releaseHold();
3342
+ }
3247
3343
  }
3248
3344
  /**
3249
3345
  * Runs executable client tools the model called after an approval decision and continues on
@@ -4468,7 +4564,8 @@ async function verifyAgentCardSignatureIfPresent(agentCard, options) {
4468
4564
  index
4469
4565
  });
4470
4566
  if (!verificationKey) throw new Error("No verification key was provided for Agent Card signature verification");
4471
- await (0, jose.compactVerify)(compactJws, await importVerificationKey(verificationKey, protectedHeader.alg), { algorithms: allowedAlgorithms });
4567
+ const importedKey = await importVerificationKey(verificationKey, protectedHeader.alg);
4568
+ await (0, jose.compactVerify)(compactJws, importedKey, { algorithms: allowedAlgorithms });
4472
4569
  return agentCard;
4473
4570
  } catch (error) {
4474
4571
  verificationErrors.push(error instanceof Error ? error.message : "Unknown verification failure");
@@ -7720,8 +7817,10 @@ var MastraClient = class extends BaseResource {
7720
7817
  if (logLevel) searchParams.set("logLevel", logLevel);
7721
7818
  if (page !== void 0) searchParams.set("page", String(page));
7722
7819
  if (perPage !== void 0) searchParams.set("perPage", String(perPage));
7723
- if (_filters) if (Array.isArray(_filters)) for (const filter of _filters) searchParams.append("filters", filter);
7724
- else searchParams.set("filters", _filters);
7820
+ if (_filters) {
7821
+ if (Array.isArray(_filters)) for (const filter of _filters) searchParams.append("filters", filter);
7822
+ else searchParams.set("filters", _filters);
7823
+ }
7725
7824
  if (searchParams.size) return this.request(`/logs?${searchParams}`);
7726
7825
  else return this.request(`/logs`);
7727
7826
  }
@@ -7741,8 +7840,10 @@ var MastraClient = class extends BaseResource {
7741
7840
  if (logLevel) searchParams.set("logLevel", logLevel);
7742
7841
  if (page !== void 0) searchParams.set("page", String(page));
7743
7842
  if (perPage !== void 0) searchParams.set("perPage", String(perPage));
7744
- if (_filters) if (Array.isArray(_filters)) for (const filter of _filters) searchParams.append("filters", filter);
7745
- else searchParams.set("filters", _filters);
7843
+ if (_filters) {
7844
+ if (Array.isArray(_filters)) for (const filter of _filters) searchParams.append("filters", filter);
7845
+ else searchParams.set("filters", _filters);
7846
+ }
7746
7847
  if (searchParams.size) return this.request(`/logs/${runId}?${searchParams}`);
7747
7848
  else return this.request(`/logs/${runId}`);
7748
7849
  }