@mastra/client-js 1.57.0-alpha.0 → 1.57.0-alpha.2
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/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-client-js-agent-controller.md +1 -1
- package/dist/docs/references/reference-client-js-agents.md +17 -1
- package/dist/docs/references/reference-client-js-datasets.md +1 -1
- package/dist/index.cjs +130 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +130 -24
- package/dist/index.js.map +1 -1
- package/dist/resources/agent.d.ts +10 -3
- package/dist/resources/agent.d.ts.map +1 -1
- package/dist/route-types.generated.d.ts +76 -41
- package/dist/route-types.generated.d.ts.map +1 -1
- package/dist/utils/process-mastra-stream.d.ts.map +1 -1
- package/dist/utils/sse-event-splitter.d.ts +3 -0
- package/dist/utils/sse-event-splitter.d.ts.map +1 -0
- package/package.json +8 -8
package/dist/docs/SKILL.md
CHANGED
|
@@ -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.57.0-alpha.
|
|
6
|
+
version: "1.57.0-alpha.2"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## When to use
|
|
@@ -177,7 +177,7 @@ Switches the active mode.
|
|
|
177
177
|
|
|
178
178
|
### `switchModel(modelId, options?)`
|
|
179
179
|
|
|
180
|
-
Switches the session's active model and persists it as the current model for the active thread
|
|
180
|
+
Switches the session's active model and persists it as the current model for the active thread, independently of mode changes. Pass `{ thinkingLevel }` as the second argument to apply and persist a thinking level with the model.
|
|
181
181
|
|
|
182
182
|
```typescript
|
|
183
183
|
await session.switchModel('anthropic/claude-sonnet-5-5', {
|
|
@@ -351,6 +351,22 @@ const { messages, initialHistoryPagination } = useChat({
|
|
|
351
351
|
|
|
352
352
|
The subscription also exposes `abort(options?)` and `unsubscribe()`. `await subscription.abort({ clearPendingSignals: true })` requests an abort and clears pending signals without closing the subscription. Omit the flag to preserve pending input. `unsubscribe()` closes the subscription without aborting the run.
|
|
353
353
|
|
|
354
|
+
### `abortRun(runId)`
|
|
355
|
+
|
|
356
|
+
Requests cancellation of a durable run by its ID, including a run without a memory thread. Cancelling the response body or aborting the client-wide `abortSignal` only disconnects the observer from durable execution. A per-call `abortSignal` passed to a streaming method requests cancellation for you. Use `abortRun()` to stop a run without that signal.
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
const runId = crypto.randomUUID()
|
|
360
|
+
const response = await agent.stream('Research this topic', { runId })
|
|
361
|
+
|
|
362
|
+
// When the user chooses Stop:
|
|
363
|
+
const { aborted } = await agent.abortRun(runId)
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**runId** (`string`): ID of the durable run to cancel.
|
|
367
|
+
|
|
368
|
+
Returns `{ aborted: boolean }`. A remote abort request is asynchronous, so `true` doesn't confirm that the worker has stopped. Unknown or completed runs return `false`. This method requires a durable agent and Agent execution permission. Run ownership checks apply. Runs with memory threads also require `memory:write` permission when fine-grained authorization is enabled. Non-durable agents return HTTP 501.
|
|
369
|
+
|
|
354
370
|
### `abortThread()`
|
|
355
371
|
|
|
356
372
|
Requests cancellation of the thread's active run. Set `clearPendingSignals: true` to clear pending signals before aborting.
|
|
@@ -748,7 +764,7 @@ response.processDataStream({
|
|
|
748
764
|
|
|
749
765
|
### Shape client tool output for the model
|
|
750
766
|
|
|
751
|
-
Client tools support `toModelOutput` to control what the model receives, including multimodal content such as images. Because client tools execute locally, the mapping also runs on the client after `execute` completes. The transformed output
|
|
767
|
+
Client tools support `toModelOutput` to control what the model receives, including multimodal content such as images. Because client tools execute locally, the mapping also runs on the client after `execute` completes. The client sends both the transformed output and the raw result back to the server, keeping the raw result available for storage and application logic.
|
|
752
768
|
|
|
753
769
|
```typescript
|
|
754
770
|
const screenshotTool = createTool({
|
|
@@ -130,7 +130,7 @@ Submitting to an experiment that has a target returns a `400`. Submitting after
|
|
|
130
130
|
|
|
131
131
|
## finalizeExperiment()
|
|
132
132
|
|
|
133
|
-
Marks a caller-driven experiment completed. The server
|
|
133
|
+
Marks a caller-driven experiment completed. The server handles bookkeeping for the caller by computing per-item counts from the persisted result rows: `succeededCount` (at least one attempt without an error), `failedCount` (every attempt errored), and `skippedCount` (never submitted). Idempotent: finalizing an already-completed experiment returns the stored record.
|
|
134
134
|
|
|
135
135
|
**datasetId** (`string`): ID of the dataset the experiment runs against.
|
|
136
136
|
|
package/dist/index.cjs
CHANGED
|
@@ -1080,11 +1080,51 @@ function processClientTools(clientTools) {
|
|
|
1080
1080
|
}));
|
|
1081
1081
|
}
|
|
1082
1082
|
//#endregion
|
|
1083
|
+
//#region src/utils/sse-event-splitter.ts
|
|
1084
|
+
/** Split SSE events without rescanning or copying an unfinished event on each read. */
|
|
1085
|
+
function createSseEventSplitter() {
|
|
1086
|
+
let parts = [];
|
|
1087
|
+
let pendingNewline = false;
|
|
1088
|
+
return (text, isFinal = false) => {
|
|
1089
|
+
const events = [];
|
|
1090
|
+
let start = 0;
|
|
1091
|
+
if (text) {
|
|
1092
|
+
if (pendingNewline) {
|
|
1093
|
+
if (text.startsWith("\n")) {
|
|
1094
|
+
events.push(parts.join(""));
|
|
1095
|
+
parts = [];
|
|
1096
|
+
start = 1;
|
|
1097
|
+
} else parts.push("\n");
|
|
1098
|
+
pendingNewline = false;
|
|
1099
|
+
}
|
|
1100
|
+
let separator;
|
|
1101
|
+
while ((separator = text.indexOf("\n\n", start)) !== -1) {
|
|
1102
|
+
parts.push(text.slice(start, separator));
|
|
1103
|
+
events.push(parts.join(""));
|
|
1104
|
+
parts = [];
|
|
1105
|
+
start = separator + 2;
|
|
1106
|
+
}
|
|
1107
|
+
if (start < text.length) {
|
|
1108
|
+
pendingNewline = text.endsWith("\n");
|
|
1109
|
+
const end = pendingNewline ? text.length - 1 : text.length;
|
|
1110
|
+
if (start < end) parts.push(text.slice(start, end));
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
if (isFinal) {
|
|
1114
|
+
if (pendingNewline) parts.push("\n");
|
|
1115
|
+
events.push(parts.join(""));
|
|
1116
|
+
parts = [];
|
|
1117
|
+
pendingNewline = false;
|
|
1118
|
+
}
|
|
1119
|
+
return events;
|
|
1120
|
+
};
|
|
1121
|
+
}
|
|
1122
|
+
//#endregion
|
|
1083
1123
|
//#region src/utils/process-mastra-stream.ts
|
|
1084
1124
|
async function sharedProcessMastraStream({ stream, onChunk, signal }) {
|
|
1085
1125
|
const reader = stream.getReader();
|
|
1086
1126
|
const decoder = new TextDecoder();
|
|
1087
|
-
|
|
1127
|
+
const splitEvents = createSseEventSplitter();
|
|
1088
1128
|
const abort = () => void reader.cancel();
|
|
1089
1129
|
if (signal?.aborted) abort();
|
|
1090
1130
|
else signal?.addEventListener("abort", abort, { once: true });
|
|
@@ -1092,9 +1132,7 @@ async function sharedProcessMastraStream({ stream, onChunk, signal }) {
|
|
|
1092
1132
|
while (true) {
|
|
1093
1133
|
const { done, value } = await reader.read();
|
|
1094
1134
|
if (done) break;
|
|
1095
|
-
|
|
1096
|
-
const lines = buffer.split("\n\n");
|
|
1097
|
-
buffer = lines.pop() || "";
|
|
1135
|
+
const lines = splitEvents(decoder.decode(value, { stream: true }));
|
|
1098
1136
|
for (const line of lines) if (line.startsWith("data: ")) {
|
|
1099
1137
|
const data = line.slice(6);
|
|
1100
1138
|
if (data === "[DONE]") return;
|
|
@@ -1894,10 +1932,18 @@ var Agent = class extends BaseResource {
|
|
|
1894
1932
|
};
|
|
1895
1933
|
return streamResponse;
|
|
1896
1934
|
}
|
|
1897
|
-
|
|
1935
|
+
/** Stops execution of a run, including runs without a memory thread. */
|
|
1936
|
+
async abortRun(runId, options) {
|
|
1937
|
+
return this.request(`/agents/${this.agentId}/runs/${encodeURIComponent(runId)}/abort`, {
|
|
1938
|
+
method: "POST",
|
|
1939
|
+
signal: options?.signal
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1942
|
+
async abortThread(params, options) {
|
|
1898
1943
|
const { resourceId, threadId, clearPendingSignals, expectedRunId } = params;
|
|
1899
1944
|
return this.request(`/agents/${this.agentId}/threads/abort`, {
|
|
1900
1945
|
method: "POST",
|
|
1946
|
+
signal: options?.signal,
|
|
1901
1947
|
body: {
|
|
1902
1948
|
resourceId,
|
|
1903
1949
|
threadId,
|
|
@@ -2631,10 +2677,11 @@ var Agent = class extends BaseResource {
|
|
|
2631
2677
|
}
|
|
2632
2678
|
/**
|
|
2633
2679
|
* Creates the consumer-facing stream for the streaming methods. Cancelling the
|
|
2634
|
-
* returned stream
|
|
2635
|
-
*
|
|
2680
|
+
* returned stream or the client-wide signal detaches the HTTP observer and
|
|
2681
|
+
* stops any client-tool continuations. Per-call execution cancellation is
|
|
2682
|
+
* handled separately by processStreamResponse.
|
|
2636
2683
|
*/
|
|
2637
|
-
createCancellableStream(
|
|
2684
|
+
createCancellableStream() {
|
|
2638
2685
|
const abortController = new AbortController();
|
|
2639
2686
|
let readableController;
|
|
2640
2687
|
return {
|
|
@@ -2647,10 +2694,63 @@ var Agent = class extends BaseResource {
|
|
|
2647
2694
|
}
|
|
2648
2695
|
}),
|
|
2649
2696
|
controller: readableController,
|
|
2650
|
-
signal: mergeAbortSignals(abortController.signal,
|
|
2697
|
+
signal: mergeAbortSignals(abortController.signal, this.options.abortSignal)
|
|
2651
2698
|
};
|
|
2652
2699
|
}
|
|
2653
2700
|
async processStreamResponse(processedParams, controller, route = "stream", signal) {
|
|
2701
|
+
const suppliedRunId = processedParams.runId;
|
|
2702
|
+
processedParams = {
|
|
2703
|
+
...processedParams,
|
|
2704
|
+
runId: processedParams.runId ?? (0, _lukeed_uuid.v4)()
|
|
2705
|
+
};
|
|
2706
|
+
const callerSignal = processedParams.abortSignal;
|
|
2707
|
+
callerSignal?.throwIfAborted();
|
|
2708
|
+
const transportAbort = new AbortController();
|
|
2709
|
+
const cancellationAbort = new AbortController();
|
|
2710
|
+
const detachSignal = signal;
|
|
2711
|
+
signal = mergeAbortSignals(detachSignal, transportAbort.signal);
|
|
2712
|
+
let cancellationTimer;
|
|
2713
|
+
const stopCancellation = () => cancellationAbort.abort();
|
|
2714
|
+
const cancelExecution = () => {
|
|
2715
|
+
cancellationTimer = setTimeout(() => cancellationAbort.abort(/* @__PURE__ */ new Error("Agent run cancellation was not acknowledged")), 1e4);
|
|
2716
|
+
(async () => {
|
|
2717
|
+
try {
|
|
2718
|
+
while (true) {
|
|
2719
|
+
cancellationAbort.signal.throwIfAborted();
|
|
2720
|
+
if ((await this.abortRun(processedParams.runId, { signal: cancellationAbort.signal })).aborted) return;
|
|
2721
|
+
await new Promise((resolve, reject) => {
|
|
2722
|
+
const onAbort = () => {
|
|
2723
|
+
clearTimeout(timer);
|
|
2724
|
+
reject(cancellationAbort.signal.reason);
|
|
2725
|
+
};
|
|
2726
|
+
const timer = setTimeout(() => {
|
|
2727
|
+
cancellationAbort.signal.removeEventListener("abort", onAbort);
|
|
2728
|
+
resolve();
|
|
2729
|
+
}, 100);
|
|
2730
|
+
cancellationAbort.signal.addEventListener("abort", onAbort, { once: true });
|
|
2731
|
+
if (cancellationAbort.signal.aborted) onAbort();
|
|
2732
|
+
});
|
|
2733
|
+
}
|
|
2734
|
+
} catch (error) {
|
|
2735
|
+
if (!cancellationAbort.signal.aborted && !(error instanceof Error && "status" in error && (error.status === 404 || error.status === 501))) try {
|
|
2736
|
+
controller.error(error);
|
|
2737
|
+
} catch {}
|
|
2738
|
+
} finally {
|
|
2739
|
+
clearTimeout(cancellationTimer);
|
|
2740
|
+
transportAbort.abort(callerSignal?.reason);
|
|
2741
|
+
}
|
|
2742
|
+
})();
|
|
2743
|
+
};
|
|
2744
|
+
const cleanupCancellation = () => {
|
|
2745
|
+
callerSignal?.removeEventListener("abort", cancelExecution);
|
|
2746
|
+
detachSignal?.removeEventListener("abort", stopCancellation);
|
|
2747
|
+
clearTimeout(cancellationTimer);
|
|
2748
|
+
stopCancellation();
|
|
2749
|
+
};
|
|
2750
|
+
detachSignal?.addEventListener("abort", stopCancellation, { once: true });
|
|
2751
|
+
if (detachSignal?.aborted) stopCancellation();
|
|
2752
|
+
callerSignal?.addEventListener("abort", cancelExecution, { once: true });
|
|
2753
|
+
if (callerSignal?.aborted) cancelExecution();
|
|
2654
2754
|
const { memory } = processedParams ?? {};
|
|
2655
2755
|
const { resource, thread } = memory ?? {};
|
|
2656
2756
|
const threadId = processedParams.threadId ?? (typeof thread === "string" ? thread : thread?.id);
|
|
@@ -2667,9 +2767,15 @@ var Agent = class extends BaseResource {
|
|
|
2667
2767
|
body: requestBody,
|
|
2668
2768
|
stream: true,
|
|
2669
2769
|
signal
|
|
2770
|
+
}).catch((error) => {
|
|
2771
|
+
cleanupCancellation();
|
|
2772
|
+
throw error;
|
|
2670
2773
|
});
|
|
2671
|
-
if (!response.body)
|
|
2672
|
-
|
|
2774
|
+
if (!response.body) {
|
|
2775
|
+
cleanupCancellation();
|
|
2776
|
+
throw new Error("No response body");
|
|
2777
|
+
}
|
|
2778
|
+
const isAborted = () => Boolean(signal?.aborted || callerSignal?.aborted);
|
|
2673
2779
|
const isAbortError = (error) => isAborted() || error?.name === "AbortError";
|
|
2674
2780
|
const safeClose = () => {
|
|
2675
2781
|
try {
|
|
@@ -2682,18 +2788,16 @@ var Agent = class extends BaseResource {
|
|
|
2682
2788
|
};
|
|
2683
2789
|
try {
|
|
2684
2790
|
let messages = [];
|
|
2685
|
-
let streamRunId =
|
|
2791
|
+
let streamRunId = suppliedRunId;
|
|
2686
2792
|
let finishedHistory;
|
|
2687
2793
|
let suspended = false;
|
|
2688
2794
|
const resumedToolCallIds = /* @__PURE__ */ new Set();
|
|
2689
2795
|
const releaseOpenStream = streamRunId ? this.trackOpenStream(streamRunId) : () => {};
|
|
2690
2796
|
const [streamForController, streamForProcessing] = response.body.tee();
|
|
2691
2797
|
const decoder = new TextDecoder();
|
|
2692
|
-
|
|
2798
|
+
const splitEvents = createSseEventSplitter();
|
|
2693
2799
|
const enqueueReadableText = (text, isFinal = false) => {
|
|
2694
|
-
|
|
2695
|
-
const lines = pendingText.split("\n\n");
|
|
2696
|
-
pendingText = isFinal ? "" : lines.pop() ?? "";
|
|
2800
|
+
const lines = splitEvents(text, isFinal);
|
|
2697
2801
|
for (const line of lines) {
|
|
2698
2802
|
if (!line.startsWith("data: ") || !line.includes("\"type\":\"finish\"")) continue;
|
|
2699
2803
|
try {
|
|
@@ -2900,10 +3004,12 @@ var Agent = class extends BaseResource {
|
|
|
2900
3004
|
} catch {}
|
|
2901
3005
|
safeClose();
|
|
2902
3006
|
}).finally(() => {
|
|
3007
|
+
cleanupCancellation();
|
|
2903
3008
|
signal?.removeEventListener("abort", onAbort);
|
|
2904
3009
|
releaseOpenStream();
|
|
2905
3010
|
});
|
|
2906
3011
|
} catch (error) {
|
|
3012
|
+
cleanupCancellation();
|
|
2907
3013
|
if (!isAbortError(error)) console.error("Error processing stream response:", error);
|
|
2908
3014
|
}
|
|
2909
3015
|
return response;
|
|
@@ -3001,7 +3107,7 @@ var Agent = class extends BaseResource {
|
|
|
3001
3107
|
clientTools: processClientTools(params.clientToolsResolver?.() ?? params.clientTools),
|
|
3002
3108
|
structuredOutput
|
|
3003
3109
|
};
|
|
3004
|
-
const { readable, controller: readableController, signal } = this.createCancellableStream(
|
|
3110
|
+
const { readable, controller: readableController, signal } = this.createCancellableStream();
|
|
3005
3111
|
const response = await this.processStreamResponse(processedParams, readableController, "stream", signal);
|
|
3006
3112
|
const streamResponse = new Response(readable, {
|
|
3007
3113
|
status: response.status,
|
|
@@ -3032,7 +3138,7 @@ var Agent = class extends BaseResource {
|
|
|
3032
3138
|
clientTools: processClientTools(params.clientToolsResolver?.() ?? params.clientTools),
|
|
3033
3139
|
structuredOutput
|
|
3034
3140
|
};
|
|
3035
|
-
const { readable, controller: readableController, signal } = this.createCancellableStream(
|
|
3141
|
+
const { readable, controller: readableController, signal } = this.createCancellableStream();
|
|
3036
3142
|
const response = await this.processStreamResponse(processedParams, readableController, "stream-until-idle", signal);
|
|
3037
3143
|
const streamResponse = new Response(readable, {
|
|
3038
3144
|
status: response.status,
|
|
@@ -3076,7 +3182,7 @@ var Agent = class extends BaseResource {
|
|
|
3076
3182
|
requestContext: parseClientRequestContext(requestContext),
|
|
3077
3183
|
clientTools: processClientTools(executableClientTools)
|
|
3078
3184
|
};
|
|
3079
|
-
const { readable, controller: readableController, signal } = this.createCancellableStream(
|
|
3185
|
+
const { readable, controller: readableController, signal } = this.createCancellableStream();
|
|
3080
3186
|
const response = await this.processStreamResponse(processedParams, readableController, "approve-tool-call", signal).catch((error) => {
|
|
3081
3187
|
releaseHold({ force: true });
|
|
3082
3188
|
throw error;
|
|
@@ -3113,7 +3219,7 @@ var Agent = class extends BaseResource {
|
|
|
3113
3219
|
requestContext: parseClientRequestContext(requestContext),
|
|
3114
3220
|
clientTools: processClientTools(executableClientTools)
|
|
3115
3221
|
};
|
|
3116
|
-
const { readable, controller: readableController, signal } = this.createCancellableStream(
|
|
3222
|
+
const { readable, controller: readableController, signal } = this.createCancellableStream();
|
|
3117
3223
|
const response = await this.processStreamResponse(processedParams, readableController, "decline-tool-call", signal).catch((error) => {
|
|
3118
3224
|
releaseHold({ force: true });
|
|
3119
3225
|
throw error;
|
|
@@ -3189,7 +3295,7 @@ var Agent = class extends BaseResource {
|
|
|
3189
3295
|
schema: (0, _mastra_schema_compat_schema.standardSchemaToJSONSchema)((0, _mastra_schema_compat_schema.toStandardSchema)(options.structuredOutput.schema))
|
|
3190
3296
|
} : void 0
|
|
3191
3297
|
};
|
|
3192
|
-
const { readable, controller: readableController, signal } = this.createCancellableStream(
|
|
3298
|
+
const { readable, controller: readableController, signal } = this.createCancellableStream();
|
|
3193
3299
|
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream", signal).catch((error) => {
|
|
3194
3300
|
releaseHold({ force: true });
|
|
3195
3301
|
throw error;
|
|
@@ -3258,7 +3364,7 @@ var Agent = class extends BaseResource {
|
|
|
3258
3364
|
schema: (0, _mastra_schema_compat_schema.standardSchemaToJSONSchema)((0, _mastra_schema_compat_schema.toStandardSchema)(options.structuredOutput.schema))
|
|
3259
3365
|
} : void 0
|
|
3260
3366
|
};
|
|
3261
|
-
const { readable, controller: readableController, signal } = this.createCancellableStream(
|
|
3367
|
+
const { readable, controller: readableController, signal } = this.createCancellableStream();
|
|
3262
3368
|
const response = await this.processStreamResponse(processedParams, readableController, "resume-stream-until-idle", signal).catch((error) => {
|
|
3263
3369
|
releaseHold({ force: true });
|
|
3264
3370
|
throw error;
|
|
@@ -4416,7 +4522,7 @@ var Workflow = class extends BaseResource {
|
|
|
4416
4522
|
*/
|
|
4417
4523
|
async createRun(params) {
|
|
4418
4524
|
const searchParams = new URLSearchParams();
|
|
4419
|
-
if (
|
|
4525
|
+
if (params?.runId) searchParams.set("runId", params.runId);
|
|
4420
4526
|
const res = await this.request(`/workflows/${this.workflowId}/create-run?${searchParams.toString()}`, {
|
|
4421
4527
|
method: "POST",
|
|
4422
4528
|
body: {
|
|
@@ -4974,7 +5080,7 @@ var AgentBuilder = class extends BaseResource {
|
|
|
4974
5080
|
*/
|
|
4975
5081
|
async createRun(params) {
|
|
4976
5082
|
const searchParams = new URLSearchParams();
|
|
4977
|
-
if (
|
|
5083
|
+
if (params?.runId) searchParams.set("runId", params.runId);
|
|
4978
5084
|
const url = `/agent-builder/${this.actionId}/create-run${searchParams.toString() ? `?${searchParams.toString()}` : ""}`;
|
|
4979
5085
|
return this.request(url, { method: "POST" });
|
|
4980
5086
|
}
|