@mastra/client-js 1.47.0-alpha.4 → 1.47.0-alpha.5

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.cjs CHANGED
@@ -365,6 +365,33 @@ function buildTenancyQuery(tenancy) {
365
365
  const queryString = searchParams.toString();
366
366
  return queryString ? `?${queryString}` : "";
367
367
  }
368
+ /**
369
+ * Merges multiple optional abort signals into one. Returns `undefined` when no
370
+ * signals are provided, the single signal when only one is provided, and a
371
+ * combined signal otherwise. Uses `AbortSignal.any` when available and falls
372
+ * back to a manual listener merge for runtimes that lack it.
373
+ */
374
+ function mergeAbortSignals(...signals) {
375
+ const defined = signals.filter((signal) => signal !== void 0);
376
+ if (defined.length === 0) return void 0;
377
+ if (defined.length === 1) return defined[0];
378
+ if (typeof AbortSignal.any === "function") return AbortSignal.any(defined);
379
+ const controller = new AbortController();
380
+ const alreadyAborted = defined.find((signal) => signal.aborted);
381
+ if (alreadyAborted) {
382
+ controller.abort(alreadyAborted.reason);
383
+ return controller.signal;
384
+ }
385
+ const cleanup = () => {
386
+ for (const signal of defined) signal.removeEventListener("abort", onAbort);
387
+ };
388
+ function onAbort() {
389
+ cleanup();
390
+ controller.abort(this.reason);
391
+ }
392
+ for (const signal of defined) signal.addEventListener("abort", onAbort);
393
+ return controller.signal;
394
+ }
368
395
  //#endregion
369
396
  //#region src/utils/client-tool-model-output.ts
370
397
  /**
@@ -559,43 +586,61 @@ var BaseResource = class {
559
586
  */
560
587
  async request(path, options = {}) {
561
588
  let lastError = null;
562
- const { baseUrl, retries = 3, backoffMs = 100, maxBackoffMs = 1e3, headers = {}, credentials, fetch: customFetch } = this.options;
589
+ const { baseUrl, retries: defaultRetries = 3, backoffMs = 100, maxBackoffMs = 1e3, headers = {}, credentials, fetch: customFetch } = this.options;
590
+ const { retries: requestRetries, ...fetchOptions } = options;
591
+ const retries = requestRetries ?? defaultRetries;
592
+ if (!Number.isSafeInteger(retries) || retries < 0) throw new RangeError("retries must be a non-negative safe integer");
593
+ const signal = mergeAbortSignals(this.options.abortSignal, fetchOptions.signal);
563
594
  const fetchFn = customFetch || fetch;
564
595
  let delay = backoffMs;
565
596
  const fullPath = `${this.apiPrefix}${path}`;
566
- for (let attempt = 0; attempt <= retries; attempt++) try {
567
- const response = await fetchFn(`${baseUrl.replace(/\/$/, "")}${fullPath}`, {
568
- ...options,
569
- headers: {
570
- ...options.body && !(options.body instanceof FormData) && (options.method === "POST" || options.method === "PUT" || options.method === "PATCH" || options.method === "DELETE") ? { "content-type": "application/json" } : {},
571
- ...headers,
572
- ...options.headers
573
- },
574
- signal: this.options.abortSignal,
575
- credentials: options.credentials ?? credentials,
576
- body: options.body instanceof FormData ? options.body : options.body ? JSON.stringify(options.body) : void 0
577
- });
578
- if (!response.ok) {
579
- const errorBody = await response.text();
580
- let parsedBody;
581
- let errorMessage = `HTTP error! status: ${response.status}`;
582
- try {
583
- parsedBody = JSON.parse(errorBody);
584
- errorMessage += ` - ${JSON.stringify(parsedBody)}`;
585
- } catch {
586
- if (errorBody) errorMessage += ` - ${errorBody}`;
597
+ for (let attempt = 0; attempt <= retries; attempt++) {
598
+ if (signal?.aborted) throw signal.reason ?? new DOMException("This operation was aborted", "AbortError");
599
+ try {
600
+ const response = await fetchFn(`${baseUrl.replace(/\/$/, "")}${fullPath}`, {
601
+ ...fetchOptions,
602
+ headers: {
603
+ ...fetchOptions.body && !(fetchOptions.body instanceof FormData) && (fetchOptions.method === "POST" || fetchOptions.method === "PUT" || fetchOptions.method === "PATCH" || fetchOptions.method === "DELETE") ? { "content-type": "application/json" } : {},
604
+ ...headers,
605
+ ...fetchOptions.headers
606
+ },
607
+ signal,
608
+ credentials: fetchOptions.credentials ?? credentials,
609
+ body: fetchOptions.body instanceof FormData ? fetchOptions.body : fetchOptions.body ? JSON.stringify(fetchOptions.body) : void 0
610
+ });
611
+ if (!response.ok) {
612
+ const errorBody = await response.text();
613
+ let parsedBody;
614
+ let errorMessage = `HTTP error! status: ${response.status}`;
615
+ try {
616
+ parsedBody = JSON.parse(errorBody);
617
+ errorMessage += ` - ${JSON.stringify(parsedBody)}`;
618
+ } catch {
619
+ if (errorBody) errorMessage += ` - ${errorBody}`;
620
+ }
621
+ throw new MastraClientError(response.status, response.statusText, errorMessage, parsedBody);
587
622
  }
588
- throw new MastraClientError(response.status, response.statusText, errorMessage, parsedBody);
623
+ if (options.stream) return response;
624
+ return await response.json();
625
+ } catch (error) {
626
+ lastError = error;
627
+ if (signal?.aborted || error?.name === "AbortError") throw error;
628
+ const status = error.status;
629
+ if (status !== void 0 && status >= 400 && status < 500) throw error;
630
+ if (attempt === retries) break;
631
+ await new Promise((resolve, reject) => {
632
+ const timer = setTimeout(() => {
633
+ signal?.removeEventListener("abort", onAbort);
634
+ resolve();
635
+ }, delay);
636
+ const onAbort = () => {
637
+ clearTimeout(timer);
638
+ reject(signal?.reason ?? new DOMException("This operation was aborted", "AbortError"));
639
+ };
640
+ signal?.addEventListener("abort", onAbort, { once: true });
641
+ });
642
+ delay = Math.min(delay * 2, maxBackoffMs);
589
643
  }
590
- if (options.stream) return response;
591
- return await response.json();
592
- } catch (error) {
593
- lastError = error;
594
- const status = error.status;
595
- if (status !== void 0 && status >= 400 && status < 500) throw error;
596
- if (attempt === retries) break;
597
- await new Promise((resolve) => setTimeout(resolve, delay));
598
- delay = Math.min(delay * 2, maxBackoffMs);
599
644
  }
600
645
  throw lastError || /* @__PURE__ */ new Error("Request failed");
601
646
  }
@@ -1325,8 +1370,10 @@ var Agent = class extends BaseResource {
1325
1370
  return this.request(`/stored/agents/${encodeURIComponent(this.agentId)}/versions/compare?${queryParams.toString()}${contextString ? `&${contextString.slice(1)}` : ""}`);
1326
1371
  }
1327
1372
  async generateLegacy(params) {
1373
+ const { abortSignal: perCallSignal, ...bodyParams } = params;
1374
+ const abortSignal = mergeAbortSignals(this.options.abortSignal, perCallSignal);
1328
1375
  const processedParams = {
1329
- ...params,
1376
+ ...bodyParams,
1330
1377
  output: params.output ? zodToJsonSchema(params.output) : void 0,
1331
1378
  experimental_output: params.experimental_output ? zodToJsonSchema(params.experimental_output) : void 0,
1332
1379
  requestContext: parseClientRequestContext(params.requestContext),
@@ -1335,9 +1382,11 @@ var Agent = class extends BaseResource {
1335
1382
  const { resourceId, threadId, requestContext } = processedParams;
1336
1383
  const response = await this.request(`/agents/${this.agentId}/generate-legacy`, {
1337
1384
  method: "POST",
1338
- body: processedParams
1385
+ body: processedParams,
1386
+ signal: abortSignal
1339
1387
  });
1340
1388
  if (response.finishReason === "tool-calls") {
1389
+ if (abortSignal?.aborted) throw abortSignal.reason ?? new DOMException("This operation was aborted", "AbortError");
1341
1390
  const toolCalls = response.toolCalls;
1342
1391
  if (!toolCalls || !Array.isArray(toolCalls)) return response;
1343
1392
  for (const toolCall of toolCalls) {
@@ -1386,8 +1435,10 @@ var Agent = class extends BaseResource {
1386
1435
  messages
1387
1436
  };
1388
1437
  const resolvedClientTools = params.clientToolsResolver?.() ?? params.clientTools;
1438
+ const abortSignal = mergeAbortSignals(this.options.abortSignal, params.abortSignal);
1389
1439
  const processedParams = {
1390
1440
  ...params,
1441
+ abortSignal: void 0,
1391
1442
  requestContext: parseClientRequestContext(params.requestContext),
1392
1443
  clientTools: processClientTools(resolvedClientTools),
1393
1444
  structuredOutput: params.structuredOutput ? {
@@ -1401,20 +1452,24 @@ var Agent = class extends BaseResource {
1401
1452
  const threadId = typeof thread === "string" ? thread : thread?.id;
1402
1453
  const response = await this.request(`/agents/${this.agentId}/generate`, {
1403
1454
  method: "POST",
1404
- body: processedParams
1405
- });
1406
- if (response.finishReason === "tool-calls") return executeToolCallAndRespond({
1407
- response,
1408
- params: {
1409
- ...params,
1410
- clientTools: resolvedClientTools
1411
- },
1412
- agentId: this.agentId,
1413
- resourceId,
1414
- threadId,
1415
- requestContext,
1416
- respondFn: this.generate.bind(this)
1455
+ body: processedParams,
1456
+ signal: abortSignal
1417
1457
  });
1458
+ if (response.finishReason === "tool-calls") {
1459
+ if (abortSignal?.aborted) throw abortSignal.reason ?? new DOMException("This operation was aborted", "AbortError");
1460
+ return executeToolCallAndRespond({
1461
+ response,
1462
+ params: {
1463
+ ...params,
1464
+ clientTools: resolvedClientTools
1465
+ },
1466
+ agentId: this.agentId,
1467
+ resourceId,
1468
+ threadId,
1469
+ requestContext,
1470
+ respondFn: this.generate.bind(this)
1471
+ });
1472
+ }
1418
1473
  return response;
1419
1474
  }
1420
1475
  async processChatResponse({ stream, update, onToolCall, onFinish, getCurrentDate = () => /* @__PURE__ */ new Date(), lastMessage }) {
@@ -1650,7 +1705,7 @@ var Agent = class extends BaseResource {
1650
1705
  throw new Error(error);
1651
1706
  }
1652
1707
  });
1653
- onFinish?.({
1708
+ await onFinish?.({
1654
1709
  message,
1655
1710
  finishReason,
1656
1711
  usage
@@ -1669,8 +1724,22 @@ var Agent = class extends BaseResource {
1669
1724
  requestContext: parseClientRequestContext(params.requestContext),
1670
1725
  clientTools: processClientTools(params.clientToolsResolver?.() ?? params.clientTools)
1671
1726
  };
1672
- const { readable, writable } = new TransformStream();
1673
- const response = await this.processStreamResponseLegacy(processedParams, writable);
1727
+ const { readable: innerReadable, writable } = new TransformStream();
1728
+ const abortController = new AbortController();
1729
+ const signal = mergeAbortSignals(abortController.signal, params.abortSignal, this.options.abortSignal);
1730
+ const innerReader = innerReadable.getReader();
1731
+ const readable = new ReadableStream({
1732
+ async pull(controller) {
1733
+ const { done, value } = await innerReader.read();
1734
+ if (done) controller.close();
1735
+ else controller.enqueue(value);
1736
+ },
1737
+ cancel(reason) {
1738
+ abortController.abort(reason);
1739
+ return innerReader.cancel(reason).catch(() => {});
1740
+ }
1741
+ });
1742
+ const response = await this.processStreamResponseLegacy(processedParams, writable, signal);
1674
1743
  const streamResponse = new Response(readable, {
1675
1744
  status: response.status,
1676
1745
  statusText: response.statusText,
@@ -1911,29 +1980,63 @@ var Agent = class extends BaseResource {
1911
1980
  }
1912
1981
  }
1913
1982
  });
1914
- onFinish?.({
1983
+ await onFinish?.({
1915
1984
  message,
1916
1985
  finishReason,
1917
1986
  usage
1918
1987
  });
1919
1988
  }
1920
- async processStreamResponse(processedParams, controller, route = "stream") {
1989
+ /**
1990
+ * Creates the consumer-facing stream for the streaming methods. Cancelling the
1991
+ * returned stream (or aborting `externalSignal`) aborts the underlying request
1992
+ * and stops any client-tool continuations.
1993
+ */
1994
+ createCancellableStream(externalSignal) {
1995
+ const abortController = new AbortController();
1996
+ let readableController;
1997
+ return {
1998
+ readable: new ReadableStream({
1999
+ start(controller) {
2000
+ readableController = controller;
2001
+ },
2002
+ cancel(reason) {
2003
+ abortController.abort(reason);
2004
+ }
2005
+ }),
2006
+ controller: readableController,
2007
+ signal: mergeAbortSignals(abortController.signal, externalSignal, this.options.abortSignal)
2008
+ };
2009
+ }
2010
+ async processStreamResponse(processedParams, controller, route = "stream", signal) {
1921
2011
  const { memory } = processedParams ?? {};
1922
2012
  const { resource, thread } = memory ?? {};
1923
2013
  const threadId = processedParams.threadId ?? (typeof thread === "string" ? thread : thread?.id);
1924
2014
  const resourceId = processedParams.resourceId ?? resource;
1925
- let requestBody = processedParams;
2015
+ const { abortSignal: _abortSignal, ...serializableParams } = processedParams;
2016
+ let requestBody = serializableParams;
1926
2017
  if (route === "resume-stream") {
1927
- const { messages: _messages, ...resumeStreamBody } = processedParams;
2018
+ const { messages: _messages, ...resumeStreamBody } = serializableParams;
1928
2019
  requestBody = resumeStreamBody;
1929
2020
  }
1930
2021
  const requestPath = route === "stream" && this.routeOverrides?.stream ? this.routeOverrides.stream : `/agents/${this.agentId}/${route}`;
1931
2022
  const response = await this.request(requestPath, {
1932
2023
  method: "POST",
1933
2024
  body: requestBody,
1934
- stream: true
2025
+ stream: true,
2026
+ signal
1935
2027
  });
1936
2028
  if (!response.body) throw new Error("No response body");
2029
+ const isAborted = () => Boolean(signal?.aborted);
2030
+ const isAbortError = (error) => isAborted() || error?.name === "AbortError";
2031
+ const safeClose = () => {
2032
+ try {
2033
+ controller.close();
2034
+ } catch {}
2035
+ };
2036
+ const safeEnqueue = (chunk) => {
2037
+ if (isAborted()) return;
2038
+ controller.enqueue(chunk);
2039
+ };
1937
2040
  try {
1938
2041
  let messages = [];
1939
2042
  let streamRunId = processedParams.runId;
@@ -1945,7 +2048,7 @@ var Agent = class extends BaseResource {
1945
2048
  const lines = pendingText.split("\n\n");
1946
2049
  pendingText = isFinal ? "" : lines.pop() ?? "";
1947
2050
  const readableLines = lines.filter((line) => line.trim() !== "[DONE]" && line.trim() !== "data: [DONE]").join("\n\n");
1948
- if (readableLines) controller.enqueue(new TextEncoder().encode(`${readableLines}\n\n`));
2051
+ if (readableLines) safeEnqueue(new TextEncoder().encode(`${readableLines}\n\n`));
1949
2052
  };
1950
2053
  const pipePromise = streamForController.pipeTo(new WritableStream({
1951
2054
  async write(chunk) {
@@ -1953,26 +2056,32 @@ var Agent = class extends BaseResource {
1953
2056
  enqueueReadableText(decoder.decode(chunk, { stream: true }));
1954
2057
  } catch (error) {
1955
2058
  console.error("Error enqueueing to controller:", error);
1956
- controller.enqueue(chunk);
2059
+ safeEnqueue(chunk);
1957
2060
  }
1958
2061
  },
1959
2062
  close() {
1960
2063
  enqueueReadableText(decoder.decode(), true);
1961
2064
  }
1962
- })).catch((error) => {
1963
- console.error("Error piping to controller:", error);
2065
+ }), { signal }).catch((error) => {
2066
+ if (!isAbortError(error)) console.error("Error piping to controller:", error);
2067
+ safeClose();
2068
+ });
2069
+ const onAbort = () => {
1964
2070
  try {
1965
- controller.close();
2071
+ controller.error(signal?.reason);
1966
2072
  } catch {}
1967
- });
2073
+ };
2074
+ signal?.addEventListener("abort", onAbort, { once: true });
2075
+ const processingStream = signal ? streamForProcessing.pipeThrough(new TransformStream(), { signal }) : streamForProcessing;
1968
2076
  this.processChatResponse_vNext({
1969
- stream: streamForProcessing,
2077
+ stream: processingStream,
1970
2078
  update: ({ message }) => {
1971
2079
  const existingIndex = messages.findIndex((m) => m.id === message.id);
1972
2080
  if (existingIndex !== -1) messages[existingIndex] = message;
1973
2081
  else messages.push(message);
1974
2082
  },
1975
2083
  onFinish: async ({ finishReason, message }) => {
2084
+ if (isAborted()) return;
1976
2085
  if (finishReason === "tool-calls") {
1977
2086
  const toolInvocationsById = /* @__PURE__ */ new Map();
1978
2087
  for (const part of message?.parts ?? []) {
@@ -1999,6 +2108,7 @@ var Agent = class extends BaseResource {
1999
2108
  const syntheticChunks = [];
2000
2109
  const toolResultContents = [];
2001
2110
  for (const toolCall of executableToolCalls) {
2111
+ if (isAborted()) return;
2002
2112
  const clientTool = processedParams.clientTools?.[toolCall.toolName];
2003
2113
  const runId = streamRunId ?? toolCall.toolCallId;
2004
2114
  let result;
@@ -2066,6 +2176,7 @@ var Agent = class extends BaseResource {
2066
2176
  try {
2067
2177
  await pipePromise;
2068
2178
  } catch {}
2179
+ if (isAborted()) return;
2069
2180
  for (const synthetic of syntheticChunks) try {
2070
2181
  const errorForSerialization = synthetic.type === "tool-error" ? synthetic.payload.error : void 0;
2071
2182
  const serializedError = errorForSerialization instanceof Error ? {
@@ -2081,7 +2192,7 @@ var Agent = class extends BaseResource {
2081
2192
  }
2082
2193
  } : synthetic;
2083
2194
  const sseLine = `data: ${JSON.stringify(payloadForWire)}\n\n`;
2084
- controller.enqueue(new TextEncoder().encode(sseLine));
2195
+ safeEnqueue(new TextEncoder().encode(sseLine));
2085
2196
  } catch (enqueueErr) {
2086
2197
  console.error("Failed to enqueue synthetic tool-result chunk:", enqueueErr);
2087
2198
  }
@@ -2095,22 +2206,23 @@ var Agent = class extends BaseResource {
2095
2206
  toolResultMessage
2096
2207
  ];
2097
2208
  const recursionRoute = route === "resume-stream" ? "stream" : route === "resume-stream-until-idle" ? "stream-until-idle" : route;
2209
+ if (isAborted()) return;
2098
2210
  try {
2099
2211
  await this.processStreamResponse({
2100
2212
  ...processedParams,
2101
2213
  messages: updatedMessages,
2102
2214
  clientTools: processClientTools(processedParams.clientToolsResolver?.() ?? processedParams.clientTools)
2103
- }, controller, recursionRoute);
2215
+ }, controller, recursionRoute, signal);
2104
2216
  } catch (error) {
2105
- console.error("Error processing recursive stream response:", error);
2217
+ if (!isAbortError(error)) console.error("Error processing recursive stream response:", error);
2106
2218
  }
2107
2219
  } else {
2108
2220
  await pipePromise;
2109
- controller.close();
2221
+ safeClose();
2110
2222
  }
2111
2223
  } else {
2112
2224
  await pipePromise;
2113
- controller.close();
2225
+ safeClose();
2114
2226
  }
2115
2227
  },
2116
2228
  onStreamChunk: (chunk) => {
@@ -2118,14 +2230,16 @@ var Agent = class extends BaseResource {
2118
2230
  },
2119
2231
  lastMessage: void 0
2120
2232
  }).catch(async (error) => {
2121
- console.error("Error processing stream response:", error);
2233
+ if (!isAbortError(error)) console.error("Error processing stream response:", error);
2122
2234
  try {
2123
2235
  await pipePromise;
2124
- controller.close();
2125
2236
  } catch {}
2237
+ safeClose();
2238
+ }).finally(() => {
2239
+ signal?.removeEventListener("abort", onAbort);
2126
2240
  });
2127
2241
  } catch (error) {
2128
- console.error("Error processing stream response:", error);
2242
+ if (!isAbortError(error)) console.error("Error processing stream response:", error);
2129
2243
  }
2130
2244
  return response;
2131
2245
  }
@@ -2222,11 +2336,8 @@ var Agent = class extends BaseResource {
2222
2336
  clientTools: processClientTools(params.clientToolsResolver?.() ?? params.clientTools),
2223
2337
  structuredOutput
2224
2338
  };
2225
- let readableController;
2226
- const readable = new ReadableStream({ start(controller) {
2227
- readableController = controller;
2228
- } });
2229
- const response = await this.processStreamResponse(processedParams, readableController);
2339
+ const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
2340
+ const response = await this.processStreamResponse(processedParams, readableController, "stream", signal);
2230
2341
  const streamResponse = new Response(readable, {
2231
2342
  status: response.status,
2232
2343
  statusText: response.statusText,
@@ -2256,11 +2367,8 @@ var Agent = class extends BaseResource {
2256
2367
  clientTools: processClientTools(params.clientToolsResolver?.() ?? params.clientTools),
2257
2368
  structuredOutput
2258
2369
  };
2259
- let readableController;
2260
- const readable = new ReadableStream({ start(controller) {
2261
- readableController = controller;
2262
- } });
2263
- const response = await this.processStreamResponse(processedParams, readableController, "stream-until-idle");
2370
+ const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
2371
+ const response = await this.processStreamResponse(processedParams, readableController, "stream-until-idle", signal);
2264
2372
  const streamResponse = new Response(readable, {
2265
2373
  status: response.status,
2266
2374
  statusText: response.statusText,
@@ -2300,11 +2408,8 @@ var Agent = class extends BaseResource {
2300
2408
  ...rest,
2301
2409
  requestContext: parseClientRequestContext(requestContext)
2302
2410
  };
2303
- let readableController;
2304
- const readable = new ReadableStream({ start(controller) {
2305
- readableController = controller;
2306
- } });
2307
- const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call");
2411
+ const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
2412
+ const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call", signal);
2308
2413
  const streamResponse = new Response(readable, {
2309
2414
  status: response.status,
2310
2415
  statusText: response.statusText,
@@ -2334,11 +2439,8 @@ var Agent = class extends BaseResource {
2334
2439
  ...rest,
2335
2440
  requestContext: parseClientRequestContext(requestContext)
2336
2441
  };
2337
- let readableController;
2338
- const readable = new ReadableStream({ start(controller) {
2339
- readableController = controller;
2340
- } });
2341
- const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call");
2442
+ const { readable, controller: readableController, signal } = this.createCancellableStream(params.abortSignal);
2443
+ const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call", signal);
2342
2444
  const streamResponse = new Response(readable, {
2343
2445
  status: response.status,
2344
2446
  statusText: response.statusText,
@@ -2408,11 +2510,8 @@ var Agent = class extends BaseResource {
2408
2510
  schema: (0, _mastra_schema_compat_schema.standardSchemaToJSONSchema)((0, _mastra_schema_compat_schema.toStandardSchema)(options.structuredOutput.schema))
2409
2511
  } : void 0
2410
2512
  };
2411
- let readableController;
2412
- const readable = new ReadableStream({ start(controller) {
2413
- readableController = controller;
2414
- } });
2415
- const response = await this.processStreamResponse(processedParams, readableController, "resume-stream");
2513
+ const { readable, controller: readableController, signal } = this.createCancellableStream(options.abortSignal);
2514
+ const response = await this.processStreamResponse(processedParams, readableController, "resume-stream", signal);
2416
2515
  const streamResponse = new Response(readable, {
2417
2516
  status: response.status,
2418
2517
  statusText: response.statusText,
@@ -2471,11 +2570,8 @@ var Agent = class extends BaseResource {
2471
2570
  schema: (0, _mastra_schema_compat_schema.standardSchemaToJSONSchema)((0, _mastra_schema_compat_schema.toStandardSchema)(options.structuredOutput.schema))
2472
2571
  } : void 0
2473
2572
  };
2474
- let readableController;
2475
- const readable = new ReadableStream({ start(controller) {
2476
- readableController = controller;
2477
- } });
2478
- const response = await this.processStreamResponse(processedParams, readableController, "resume-stream-until-idle");
2573
+ const { readable, controller: readableController, signal } = this.createCancellableStream(options.abortSignal);
2574
+ const response = await this.processStreamResponse(processedParams, readableController, "resume-stream-until-idle", signal);
2479
2575
  const streamResponse = new Response(readable, {
2480
2576
  status: response.status,
2481
2577
  statusText: response.statusText,
@@ -2520,32 +2616,41 @@ var Agent = class extends BaseResource {
2520
2616
  /**
2521
2617
  * Processes the stream response and handles tool calls
2522
2618
  */
2523
- async processStreamResponseLegacy(processedParams, writable) {
2619
+ async processStreamResponseLegacy(processedParams, writable, signal) {
2524
2620
  const { memory } = processedParams ?? {};
2525
2621
  const { resource, thread } = memory ?? {};
2526
2622
  const threadId = processedParams.threadId ?? (typeof thread === "string" ? thread : thread?.id);
2527
2623
  const resourceId = processedParams.resourceId ?? resource;
2624
+ const { abortSignal: _abortSignal, ...bodyParams } = processedParams ?? {};
2625
+ const isAborted = () => signal?.aborted === true;
2626
+ const isAbortError = (error) => isAborted() || error?.name === "AbortError";
2528
2627
  const response = await this.request(this.routeOverrides?.stream ?? `/agents/${this.agentId}/stream-legacy`, {
2529
2628
  method: "POST",
2530
- body: processedParams,
2531
- stream: true
2629
+ body: bodyParams,
2630
+ stream: true,
2631
+ signal
2532
2632
  });
2533
2633
  if (!response.body) throw new Error("No response body");
2534
2634
  try {
2535
2635
  let toolCalls = [];
2536
2636
  let messages = [];
2537
2637
  const [streamForWritable, streamForProcessing] = response.body.tee();
2538
- streamForWritable.pipeTo(writable, { preventClose: true }).catch((error) => {
2539
- console.error("Error piping to writable stream:", error);
2638
+ streamForWritable.pipeTo(writable, {
2639
+ preventClose: true,
2640
+ signal
2641
+ }).catch((error) => {
2642
+ if (!isAbortError(error)) console.error("Error piping to writable stream:", error);
2540
2643
  });
2644
+ const processingStream = signal ? streamForProcessing.pipeThrough(new TransformStream(), { signal }) : streamForProcessing;
2541
2645
  this.processChatResponse({
2542
- stream: streamForProcessing,
2646
+ stream: processingStream,
2543
2647
  update: ({ message }) => {
2544
2648
  const existingIndex = messages.findIndex((m) => m.id === message.id);
2545
2649
  if (existingIndex !== -1) messages[existingIndex] = message;
2546
2650
  else messages.push(message);
2547
2651
  },
2548
2652
  onFinish: async ({ finishReason, message }) => {
2653
+ if (isAborted()) return;
2549
2654
  if (finishReason === "tool-calls") {
2550
2655
  const toolCall = [...message?.parts ?? []].reverse().find((part) => part.type === "tool-invocation")?.toolInvocation;
2551
2656
  if (toolCall) {
@@ -2577,6 +2682,7 @@ var Agent = class extends BaseResource {
2577
2682
  }
2578
2683
  }
2579
2684
  });
2685
+ if (isAborted()) return;
2580
2686
  const writer = writable.getWriter();
2581
2687
  try {
2582
2688
  await writer.write(new TextEncoder().encode("a:" + JSON.stringify({
@@ -2606,21 +2712,21 @@ var Agent = class extends BaseResource {
2606
2712
  ...processedParams,
2607
2713
  clientTools: processClientTools(processedParams.clientToolsResolver?.() ?? processedParams.clientTools),
2608
2714
  messages: updatedMessages
2609
- }, writable).catch((error) => {
2610
- console.error("Error processing stream response:", error);
2715
+ }, writable, signal).catch((error) => {
2716
+ if (!isAbortError(error)) console.error("Error processing stream response:", error);
2611
2717
  });
2612
2718
  }
2613
2719
  }
2614
2720
  } else setTimeout(() => {
2615
- writable.close();
2721
+ writable.close().catch(() => {});
2616
2722
  }, 0);
2617
2723
  },
2618
2724
  lastMessage: void 0
2619
2725
  }).catch((error) => {
2620
- console.error("Error processing stream response:", error);
2726
+ if (!isAbortError(error)) console.error("Error processing stream response:", error);
2621
2727
  });
2622
2728
  } catch (error) {
2623
- console.error("Error processing stream response:", error);
2729
+ if (!isAbortError(error)) console.error("Error processing stream response:", error);
2624
2730
  }
2625
2731
  return response;
2626
2732
  }
@@ -4413,6 +4519,24 @@ var Observability = class extends BaseResource {
4413
4519
  body: params
4414
4520
  });
4415
4521
  }
4522
+ /** Returns canonical and observed fields available to the advanced trace-query grammar. */
4523
+ getTraceQueryFields(params, options) {
4524
+ return this.request("/observability/traces/query/fields", {
4525
+ method: "POST",
4526
+ body: params,
4527
+ retries: 0,
4528
+ signal: options?.signal
4529
+ });
4530
+ }
4531
+ /** Returns bounded string suggestions for one eligible trace-query field. */
4532
+ getTraceQueryValues(params, options) {
4533
+ return this.request("/observability/traces/query/values", {
4534
+ method: "POST",
4535
+ body: params,
4536
+ retries: 0,
4537
+ signal: options?.signal
4538
+ });
4539
+ }
4416
4540
  /**
4417
4541
  * Queries thread identities using eligible-trace and cross-trace predicates.
4418
4542
  *
@@ -6991,6 +7115,14 @@ var MastraClient = class extends BaseResource {
6991
7115
  queryTraces(params) {
6992
7116
  return this.observability.queryTraces(params);
6993
7117
  }
7118
+ /** Returns canonical and observed fields available to the advanced trace-query grammar. */
7119
+ getTraceQueryFields(params, options) {
7120
+ return this.observability.getTraceQueryFields(params, options);
7121
+ }
7122
+ /** Returns bounded string suggestions for one eligible trace-query field. */
7123
+ getTraceQueryValues(params, options) {
7124
+ return this.observability.getTraceQueryValues(params, options);
7125
+ }
6994
7126
  /** Queries thread identities using eligible-trace and cross-trace predicates. */
6995
7127
  queryTraceThreads(params) {
6996
7128
  return this.observability.queryTraceThreads(params);