@mastra/client-js 1.22.0-alpha.5 → 1.22.0-alpha.6
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 +20 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-agents-signals.md +18 -2
- package/dist/docs/references/reference-client-js-agents.md +19 -2
- package/dist/index.cjs +201 -148
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +201 -148
- package/dist/index.js.map +1 -1
- package/dist/resources/agent.d.ts +19 -0
- package/dist/resources/agent.d.ts.map +1 -1
- package/dist/route-types.generated.d.ts +76 -0
- package/dist/route-types.generated.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -857,173 +857,216 @@ var Agent = class extends BaseResource {
|
|
|
857
857
|
throw new Error("No response body");
|
|
858
858
|
}
|
|
859
859
|
const agent = this;
|
|
860
|
+
streamResponse.abort = async () => (await agent.abortThread({ resourceId, threadId })).aborted;
|
|
861
|
+
let unsubscribed = false;
|
|
862
|
+
let processAbortController;
|
|
863
|
+
let processStarted = false;
|
|
864
|
+
streamResponse.unsubscribe = () => {
|
|
865
|
+
if (unsubscribed) return;
|
|
866
|
+
unsubscribed = true;
|
|
867
|
+
processAbortController?.abort();
|
|
868
|
+
if (!processStarted) {
|
|
869
|
+
void streamResponse.body?.cancel().catch(() => {
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
};
|
|
860
873
|
streamResponse.processDataStream = async ({ onChunk, reconnect }) => {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
if (!pendingToolCalls?.length) {
|
|
885
|
-
agent.deleteSignalRuntimeOptions(runId);
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
const activeRuntimeOptions = agent.getSignalRuntimeOptions({ runId, resourceId, threadId });
|
|
889
|
-
const activeClientTools = activeRuntimeOptions?.clientTools;
|
|
890
|
-
if (!activeClientTools) {
|
|
891
|
-
agent.deleteSignalRuntimeOptions(runId);
|
|
892
|
-
return;
|
|
893
|
-
}
|
|
894
|
-
const activeRequestContext = activeRuntimeOptions.requestContext;
|
|
895
|
-
const processedClientTools = processClientTools(activeClientTools);
|
|
896
|
-
const processedRequestContext = parseClientRequestContext(activeRequestContext);
|
|
897
|
-
const toolResultMessages = [];
|
|
898
|
-
for (const toolCall of pendingToolCalls) {
|
|
899
|
-
const clientTool = activeClientTools[toolCall.toolName];
|
|
900
|
-
if (!clientTool || typeof clientTool.execute !== "function") continue;
|
|
901
|
-
let result;
|
|
902
|
-
let observability;
|
|
903
|
-
try {
|
|
904
|
-
const execution = await executeClientToolWithObservability({
|
|
905
|
-
clientTool,
|
|
906
|
-
args: toolCall.args,
|
|
907
|
-
toolName: toolCall.toolName,
|
|
908
|
-
parentContext: toolCall.observability,
|
|
909
|
-
executeContext: {
|
|
910
|
-
requestContext: activeRequestContext,
|
|
911
|
-
tracingContext: { currentSpan: void 0 },
|
|
912
|
-
agent: {
|
|
913
|
-
agentId: agent.agentId,
|
|
914
|
-
messages: finishPayload.payload?.messages?.nonUser ?? [],
|
|
915
|
-
toolCallId: toolCall.toolCallId,
|
|
916
|
-
suspend: async () => {
|
|
917
|
-
},
|
|
918
|
-
threadId,
|
|
919
|
-
resourceId
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
});
|
|
923
|
-
result = execution.result;
|
|
924
|
-
observability = execution.observability;
|
|
925
|
-
} catch (error) {
|
|
926
|
-
result = { error: String(error) };
|
|
874
|
+
if (unsubscribed) return;
|
|
875
|
+
processStarted = true;
|
|
876
|
+
processAbortController = new AbortController();
|
|
877
|
+
const abortProcessStream = () => processAbortController?.abort();
|
|
878
|
+
const isClosed = () => unsubscribed || processAbortController?.signal.aborted || this.options.abortSignal?.aborted;
|
|
879
|
+
if (this.options.abortSignal?.aborted) {
|
|
880
|
+
abortProcessStream();
|
|
881
|
+
} else {
|
|
882
|
+
this.options.abortSignal?.addEventListener("abort", abortProcessStream, { once: true });
|
|
883
|
+
}
|
|
884
|
+
try {
|
|
885
|
+
const pendingToolCallsByRunId = /* @__PURE__ */ new Map();
|
|
886
|
+
const handleSubscribedChunk = async (chunk) => {
|
|
887
|
+
if (chunk.type === "tool-call") {
|
|
888
|
+
const payload = chunk.payload;
|
|
889
|
+
const toolCallId = payload?.toolCallId;
|
|
890
|
+
const toolName = payload?.toolName;
|
|
891
|
+
const runId2 = chunk.runId;
|
|
892
|
+
if (!toolCallId || !toolName || !runId2) return;
|
|
893
|
+
const pendingToolCalls2 = pendingToolCallsByRunId.get(runId2) ?? [];
|
|
894
|
+
pendingToolCalls2.push({ toolCallId, toolName, args: payload.args, observability: payload.observability });
|
|
895
|
+
pendingToolCallsByRunId.set(runId2, pendingToolCalls2);
|
|
896
|
+
return;
|
|
927
897
|
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
toolResultContent.__mastraObservability = observability;
|
|
898
|
+
if (chunk.type !== "finish") return;
|
|
899
|
+
const runId = chunk.runId;
|
|
900
|
+
const finishPayload = chunk;
|
|
901
|
+
if (!runId) return;
|
|
902
|
+
if (finishPayload.payload?.stepResult?.reason !== "tool-calls") {
|
|
903
|
+
agent.deleteSignalRuntimeOptions(runId);
|
|
904
|
+
return;
|
|
936
905
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
toolResultMessages.push({
|
|
943
|
-
role: "tool",
|
|
944
|
-
content: [toolResultContent]
|
|
945
|
-
});
|
|
946
|
-
}
|
|
947
|
-
if (toolResultMessages.length === 0) {
|
|
948
|
-
agent.deleteSignalRuntimeOptions(runId);
|
|
949
|
-
return;
|
|
950
|
-
}
|
|
951
|
-
try {
|
|
952
|
-
const continuation = await agent.streamUntilIdle(
|
|
953
|
-
[...finishPayload.payload?.messages?.nonUser ?? [], ...toolResultMessages],
|
|
954
|
-
{
|
|
955
|
-
...activeRuntimeOptions,
|
|
956
|
-
runId: v4(),
|
|
957
|
-
requestContext: processedRequestContext,
|
|
958
|
-
memory: threadId ? { thread: threadId, resource: resourceId } : void 0,
|
|
959
|
-
clientTools: processedClientTools
|
|
960
|
-
}
|
|
961
|
-
);
|
|
962
|
-
try {
|
|
963
|
-
void continuation.body?.cancel?.();
|
|
964
|
-
} catch {
|
|
906
|
+
const pendingToolCalls = pendingToolCallsByRunId.get(runId);
|
|
907
|
+
pendingToolCallsByRunId.delete(runId);
|
|
908
|
+
if (!pendingToolCalls?.length) {
|
|
909
|
+
agent.deleteSignalRuntimeOptions(runId);
|
|
910
|
+
return;
|
|
965
911
|
}
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
};
|
|
972
|
-
const reconnectOptions = reconnect === true ? { maxRetries: Infinity, delayMs: 1e3 } : reconnect ? { maxRetries: reconnect.maxRetries ?? Infinity, delayMs: reconnect.delayMs ?? 1e3 } : null;
|
|
973
|
-
let response = streamResponse;
|
|
974
|
-
let attempts = 0;
|
|
975
|
-
const onChunkErrorSentinel = /* @__PURE__ */ Symbol("onChunkErrorSentinel");
|
|
976
|
-
const guardedOnChunk = async (chunk) => {
|
|
977
|
-
try {
|
|
978
|
-
await onChunk(chunk);
|
|
979
|
-
await handleSubscribedChunk(chunk);
|
|
980
|
-
} catch (cause) {
|
|
981
|
-
throw { [onChunkErrorSentinel]: true, cause };
|
|
982
|
-
}
|
|
983
|
-
};
|
|
984
|
-
while (true) {
|
|
985
|
-
if (!response.body) {
|
|
986
|
-
throw new Error("No response body");
|
|
987
|
-
}
|
|
988
|
-
try {
|
|
989
|
-
await processMastraStream({
|
|
990
|
-
stream: response.body,
|
|
991
|
-
onChunk: guardedOnChunk,
|
|
992
|
-
signal: this.options.abortSignal
|
|
993
|
-
});
|
|
994
|
-
} catch (error) {
|
|
995
|
-
if (typeof error === "object" && error !== null && error[onChunkErrorSentinel]) {
|
|
996
|
-
throw error.cause;
|
|
912
|
+
const activeRuntimeOptions = agent.getSignalRuntimeOptions({ runId, resourceId, threadId });
|
|
913
|
+
const activeClientTools = activeRuntimeOptions?.clientTools;
|
|
914
|
+
if (!activeClientTools) {
|
|
915
|
+
agent.deleteSignalRuntimeOptions(runId);
|
|
916
|
+
return;
|
|
997
917
|
}
|
|
998
|
-
|
|
999
|
-
|
|
918
|
+
const activeRequestContext = activeRuntimeOptions.requestContext;
|
|
919
|
+
const processedClientTools = processClientTools(activeClientTools);
|
|
920
|
+
const processedRequestContext = parseClientRequestContext(activeRequestContext);
|
|
921
|
+
const toolResultMessages = [];
|
|
922
|
+
for (const toolCall of pendingToolCalls) {
|
|
923
|
+
const clientTool = activeClientTools[toolCall.toolName];
|
|
924
|
+
if (!clientTool || typeof clientTool.execute !== "function") continue;
|
|
925
|
+
let result;
|
|
926
|
+
let observability;
|
|
927
|
+
try {
|
|
928
|
+
const execution = await executeClientToolWithObservability({
|
|
929
|
+
clientTool,
|
|
930
|
+
args: toolCall.args,
|
|
931
|
+
toolName: toolCall.toolName,
|
|
932
|
+
parentContext: toolCall.observability,
|
|
933
|
+
executeContext: {
|
|
934
|
+
requestContext: activeRequestContext,
|
|
935
|
+
tracingContext: { currentSpan: void 0 },
|
|
936
|
+
agent: {
|
|
937
|
+
agentId: agent.agentId,
|
|
938
|
+
messages: finishPayload.payload?.messages?.nonUser ?? [],
|
|
939
|
+
toolCallId: toolCall.toolCallId,
|
|
940
|
+
suspend: async () => {
|
|
941
|
+
},
|
|
942
|
+
threadId,
|
|
943
|
+
resourceId
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
});
|
|
947
|
+
result = execution.result;
|
|
948
|
+
observability = execution.observability;
|
|
949
|
+
} catch (error) {
|
|
950
|
+
result = { error: String(error) };
|
|
951
|
+
}
|
|
952
|
+
const toolResultContent = {
|
|
953
|
+
type: "tool-result",
|
|
954
|
+
toolCallId: toolCall.toolCallId,
|
|
955
|
+
toolName: toolCall.toolName,
|
|
956
|
+
result
|
|
957
|
+
};
|
|
958
|
+
if (observability) {
|
|
959
|
+
toolResultContent.__mastraObservability = observability;
|
|
960
|
+
}
|
|
961
|
+
await onChunk({
|
|
962
|
+
type: "tool-result",
|
|
963
|
+
runId,
|
|
964
|
+
payload: toolResultContent
|
|
965
|
+
});
|
|
966
|
+
toolResultMessages.push({
|
|
967
|
+
role: "tool",
|
|
968
|
+
content: [toolResultContent]
|
|
969
|
+
});
|
|
1000
970
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
|
-
while (attempts < reconnectOptions.maxRetries) {
|
|
1006
|
-
attempts++;
|
|
1007
|
-
if (this.options.abortSignal?.aborted) {
|
|
971
|
+
if (toolResultMessages.length === 0) {
|
|
972
|
+
agent.deleteSignalRuntimeOptions(runId);
|
|
1008
973
|
return;
|
|
1009
974
|
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
975
|
+
try {
|
|
976
|
+
const continuation = await agent.streamUntilIdle(
|
|
977
|
+
[...finishPayload.payload?.messages?.nonUser ?? [], ...toolResultMessages],
|
|
978
|
+
{
|
|
979
|
+
...activeRuntimeOptions,
|
|
980
|
+
runId: v4(),
|
|
981
|
+
requestContext: processedRequestContext,
|
|
982
|
+
memory: threadId ? { thread: threadId, resource: resourceId } : void 0,
|
|
983
|
+
clientTools: processedClientTools
|
|
984
|
+
}
|
|
985
|
+
);
|
|
986
|
+
try {
|
|
987
|
+
void continuation.body?.cancel?.();
|
|
988
|
+
} catch {
|
|
989
|
+
}
|
|
990
|
+
} catch (error) {
|
|
991
|
+
console.error("Error running client-tool continuation:", error);
|
|
992
|
+
} finally {
|
|
993
|
+
agent.deleteSignalRuntimeOptions(runId);
|
|
1013
994
|
}
|
|
995
|
+
};
|
|
996
|
+
const reconnectOptions = reconnect === true ? { maxRetries: Infinity, delayMs: 1e3 } : reconnect ? { maxRetries: reconnect.maxRetries ?? Infinity, delayMs: reconnect.delayMs ?? 1e3 } : null;
|
|
997
|
+
let response = streamResponse;
|
|
998
|
+
let attempts = 0;
|
|
999
|
+
const onChunkErrorSentinel = /* @__PURE__ */ Symbol("onChunkErrorSentinel");
|
|
1000
|
+
const guardedOnChunk = async (chunk) => {
|
|
1014
1001
|
try {
|
|
1015
|
-
|
|
1016
|
-
|
|
1002
|
+
await onChunk(chunk);
|
|
1003
|
+
await handleSubscribedChunk(chunk);
|
|
1004
|
+
} catch (cause) {
|
|
1005
|
+
throw { [onChunkErrorSentinel]: true, cause };
|
|
1006
|
+
}
|
|
1007
|
+
};
|
|
1008
|
+
while (true) {
|
|
1009
|
+
if (!response.body) {
|
|
1010
|
+
throw new Error("No response body");
|
|
1011
|
+
}
|
|
1012
|
+
try {
|
|
1013
|
+
await processMastraStream({
|
|
1014
|
+
stream: response.body,
|
|
1015
|
+
onChunk: guardedOnChunk,
|
|
1016
|
+
signal: processAbortController.signal
|
|
1017
|
+
});
|
|
1017
1018
|
} catch (error) {
|
|
1018
|
-
if (
|
|
1019
|
+
if (typeof error === "object" && error !== null && error[onChunkErrorSentinel]) {
|
|
1020
|
+
throw error.cause;
|
|
1021
|
+
}
|
|
1022
|
+
if (!reconnectOptions || isClosed() || attempts >= reconnectOptions.maxRetries) {
|
|
1023
|
+
if (isClosed()) return;
|
|
1019
1024
|
throw error;
|
|
1020
1025
|
}
|
|
1021
1026
|
}
|
|
1027
|
+
if (!reconnectOptions || isClosed() || attempts >= reconnectOptions.maxRetries) {
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
while (attempts < reconnectOptions.maxRetries) {
|
|
1031
|
+
attempts++;
|
|
1032
|
+
if (isClosed()) {
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
await new Promise((resolve) => setTimeout(resolve, reconnectOptions.delayMs));
|
|
1036
|
+
if (isClosed()) {
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
try {
|
|
1040
|
+
response = await requestSubscription();
|
|
1041
|
+
break;
|
|
1042
|
+
} catch (error) {
|
|
1043
|
+
if (isClosed() || attempts >= reconnectOptions.maxRetries) {
|
|
1044
|
+
if (isClosed()) return;
|
|
1045
|
+
throw error;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
} finally {
|
|
1051
|
+
this.options.abortSignal?.removeEventListener("abort", abortProcessStream);
|
|
1052
|
+
if (processAbortController?.signal.aborted) {
|
|
1053
|
+
unsubscribed = true;
|
|
1022
1054
|
}
|
|
1055
|
+
processAbortController = void 0;
|
|
1023
1056
|
}
|
|
1024
1057
|
};
|
|
1025
1058
|
return streamResponse;
|
|
1026
1059
|
}
|
|
1060
|
+
/**
|
|
1061
|
+
* @experimental Agent signals are experimental and may change in a future release.
|
|
1062
|
+
*/
|
|
1063
|
+
async abortThread(params) {
|
|
1064
|
+
const { resourceId, threadId } = params;
|
|
1065
|
+
return this.request(`/agents/${this.agentId}/threads/abort`, {
|
|
1066
|
+
method: "POST",
|
|
1067
|
+
body: { resourceId, threadId }
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1027
1070
|
/**
|
|
1028
1071
|
* Clones this agent to a new stored agent in the database
|
|
1029
1072
|
* @param params - Clone parameters including optional newId, newName, metadata, authorId, and requestContext
|
|
@@ -2215,6 +2258,16 @@ var Agent = class extends BaseResource {
|
|
|
2215
2258
|
};
|
|
2216
2259
|
return streamResponse;
|
|
2217
2260
|
}
|
|
2261
|
+
async sendToolApproval(params) {
|
|
2262
|
+
const { requestContext, ...rest } = params;
|
|
2263
|
+
return this.request(
|
|
2264
|
+
`/agents/${this.agentId}/send-tool-approval`,
|
|
2265
|
+
{
|
|
2266
|
+
method: "POST",
|
|
2267
|
+
body: { ...rest, requestContext: parseClientRequestContext(requestContext) }
|
|
2268
|
+
}
|
|
2269
|
+
);
|
|
2270
|
+
}
|
|
2218
2271
|
async declineToolCall(params) {
|
|
2219
2272
|
const { requestContext, ...rest } = params;
|
|
2220
2273
|
const processedParams = { ...rest, requestContext: parseClientRequestContext(requestContext) };
|