@mastra/client-js 1.21.0-alpha.7 → 1.21.0-alpha.8
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 +49 -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 +21 -0
- package/dist/docs/references/reference-client-js-agents.md +5 -2
- package/dist/index.cjs +274 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +274 -15
- package/dist/index.js.map +1 -1
- package/dist/resources/agent.d.ts +8 -4
- package/dist/resources/agent.d.ts.map +1 -1
- package/dist/route-types.generated.d.ts +779 -4
- package/dist/route-types.generated.d.ts.map +1 -1
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/process-mastra-stream.d.ts +2 -2
- package/dist/utils/process-mastra-stream.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -494,6 +494,24 @@ var BaseResource = class {
|
|
|
494
494
|
};
|
|
495
495
|
|
|
496
496
|
// src/resources/agent.ts
|
|
497
|
+
var SIGNAL_RUNTIME_OPTIONS_TTL_MS = 5 * 60 * 1e3;
|
|
498
|
+
var signalRuntimeOptionsByRunId = /* @__PURE__ */ new Map();
|
|
499
|
+
var latestSignalRuntimeOptionsByThread = /* @__PURE__ */ new Map();
|
|
500
|
+
var createSignalRuntimeOptionsEntry = (store, key, streamOptions) => {
|
|
501
|
+
const timeout = setTimeout(() => store.delete(key), SIGNAL_RUNTIME_OPTIONS_TTL_MS);
|
|
502
|
+
timeout.unref?.();
|
|
503
|
+
return { streamOptions, timeout };
|
|
504
|
+
};
|
|
505
|
+
var setSignalRuntimeOptionsEntry = (store, key, streamOptions) => {
|
|
506
|
+
const existing = store.get(key);
|
|
507
|
+
if (existing) clearTimeout(existing.timeout);
|
|
508
|
+
store.set(key, createSignalRuntimeOptionsEntry(store, key, streamOptions));
|
|
509
|
+
};
|
|
510
|
+
var deleteSignalRuntimeOptionsEntry = (store, key) => {
|
|
511
|
+
const existing = store.get(key);
|
|
512
|
+
if (existing) clearTimeout(existing.timeout);
|
|
513
|
+
store.delete(key);
|
|
514
|
+
};
|
|
497
515
|
var noopClientToolObserve = {
|
|
498
516
|
async span(_name, fn) {
|
|
499
517
|
return fn();
|
|
@@ -691,6 +709,52 @@ var Agent = class extends BaseResource {
|
|
|
691
709
|
const queryString = searchParams.toString();
|
|
692
710
|
return queryString ? `${delimiter}${queryString}` : "";
|
|
693
711
|
}
|
|
712
|
+
getSignalRuntimeRunKey(runId) {
|
|
713
|
+
return `${this.options.baseUrl}|${this.apiPrefix}|${this.agentId}|${runId}`;
|
|
714
|
+
}
|
|
715
|
+
getSignalRuntimeThreadKey({
|
|
716
|
+
resourceId,
|
|
717
|
+
threadId
|
|
718
|
+
}) {
|
|
719
|
+
if (!threadId) return void 0;
|
|
720
|
+
return `${this.options.baseUrl}|${this.apiPrefix}|${this.agentId}|${resourceId ?? ""}|${threadId}`;
|
|
721
|
+
}
|
|
722
|
+
setSignalRuntimeOptions({
|
|
723
|
+
runId,
|
|
724
|
+
resourceId,
|
|
725
|
+
threadId,
|
|
726
|
+
streamOptions
|
|
727
|
+
}) {
|
|
728
|
+
const threadKey = this.getSignalRuntimeThreadKey({ resourceId, threadId });
|
|
729
|
+
if (runId) {
|
|
730
|
+
setSignalRuntimeOptionsEntry(signalRuntimeOptionsByRunId, this.getSignalRuntimeRunKey(runId), streamOptions);
|
|
731
|
+
if (threadKey) deleteSignalRuntimeOptionsEntry(latestSignalRuntimeOptionsByThread, threadKey);
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
if (threadKey) {
|
|
735
|
+
setSignalRuntimeOptionsEntry(latestSignalRuntimeOptionsByThread, threadKey, streamOptions);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
getSignalRuntimeOptions({
|
|
739
|
+
runId,
|
|
740
|
+
resourceId,
|
|
741
|
+
threadId
|
|
742
|
+
}) {
|
|
743
|
+
if (runId) {
|
|
744
|
+
const runOptions = signalRuntimeOptionsByRunId.get(this.getSignalRuntimeRunKey(runId));
|
|
745
|
+
if (runOptions) return runOptions.streamOptions;
|
|
746
|
+
}
|
|
747
|
+
const threadKey = this.getSignalRuntimeThreadKey({ resourceId, threadId });
|
|
748
|
+
return threadKey ? latestSignalRuntimeOptionsByThread.get(threadKey)?.streamOptions : void 0;
|
|
749
|
+
}
|
|
750
|
+
deleteSignalRuntimeOptions(runId) {
|
|
751
|
+
if (!runId) return;
|
|
752
|
+
deleteSignalRuntimeOptionsEntry(signalRuntimeOptionsByRunId, this.getSignalRuntimeRunKey(runId));
|
|
753
|
+
}
|
|
754
|
+
deleteLatestSignalRuntimeOptions({ resourceId, threadId }) {
|
|
755
|
+
const threadKey = this.getSignalRuntimeThreadKey({ resourceId, threadId });
|
|
756
|
+
if (threadKey) deleteSignalRuntimeOptionsEntry(latestSignalRuntimeOptionsByThread, threadKey);
|
|
757
|
+
}
|
|
694
758
|
/**
|
|
695
759
|
* Retrieves details about the agent
|
|
696
760
|
* @param requestContext - Optional request context to pass as query parameter
|
|
@@ -736,32 +800,227 @@ var Agent = class extends BaseResource {
|
|
|
736
800
|
/**
|
|
737
801
|
* @experimental Agent signals are experimental and may change in a future release.
|
|
738
802
|
*/
|
|
739
|
-
sendSignal(params) {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
803
|
+
async sendSignal(params) {
|
|
804
|
+
const streamOptions = params.ifIdle?.streamOptions;
|
|
805
|
+
if (streamOptions) {
|
|
806
|
+
this.setSignalRuntimeOptions({
|
|
807
|
+
resourceId: params.resourceId,
|
|
808
|
+
threadId: params.threadId,
|
|
809
|
+
streamOptions
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
const body = params.ifIdle?.streamOptions ? {
|
|
813
|
+
...params,
|
|
814
|
+
ifIdle: {
|
|
815
|
+
...params.ifIdle,
|
|
816
|
+
streamOptions: {
|
|
817
|
+
...params.ifIdle.streamOptions,
|
|
818
|
+
requestContext: parseClientRequestContext(params.ifIdle.streamOptions.requestContext),
|
|
819
|
+
clientTools: processClientTools(params.ifIdle.streamOptions.clientTools)
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
} : params;
|
|
823
|
+
let response;
|
|
824
|
+
try {
|
|
825
|
+
response = await this.request(`/agents/${this.agentId}/signals`, {
|
|
826
|
+
method: "POST",
|
|
827
|
+
body
|
|
828
|
+
});
|
|
829
|
+
} catch (error) {
|
|
830
|
+
if (streamOptions) {
|
|
831
|
+
this.deleteLatestSignalRuntimeOptions({ resourceId: params.resourceId, threadId: params.threadId });
|
|
832
|
+
}
|
|
833
|
+
throw error;
|
|
834
|
+
}
|
|
835
|
+
if (streamOptions) {
|
|
836
|
+
this.setSignalRuntimeOptions({
|
|
837
|
+
runId: response.runId,
|
|
838
|
+
resourceId: params.resourceId,
|
|
839
|
+
threadId: params.threadId,
|
|
840
|
+
streamOptions
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
return response;
|
|
744
844
|
}
|
|
745
845
|
/**
|
|
746
846
|
* @experimental Agent signals are experimental and may change in a future release.
|
|
747
847
|
*/
|
|
748
848
|
async subscribeToThread(params) {
|
|
749
|
-
const
|
|
849
|
+
const { resourceId, threadId } = params;
|
|
850
|
+
const requestSubscription = () => this.request(`/agents/${this.agentId}/threads/subscribe`, {
|
|
750
851
|
method: "POST",
|
|
751
|
-
body:
|
|
852
|
+
body: { resourceId, threadId },
|
|
752
853
|
stream: true
|
|
753
854
|
});
|
|
855
|
+
const streamResponse = await requestSubscription();
|
|
754
856
|
if (!streamResponse.body) {
|
|
755
857
|
throw new Error("No response body");
|
|
756
858
|
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
859
|
+
const agent = this;
|
|
860
|
+
streamResponse.processDataStream = async ({ onChunk, reconnect }) => {
|
|
861
|
+
const pendingToolCallsByRunId = /* @__PURE__ */ new Map();
|
|
862
|
+
const handleSubscribedChunk = async (chunk) => {
|
|
863
|
+
if (chunk.type === "tool-call") {
|
|
864
|
+
const payload = chunk.payload;
|
|
865
|
+
const toolCallId = payload?.toolCallId;
|
|
866
|
+
const toolName = payload?.toolName;
|
|
867
|
+
const runId2 = chunk.runId;
|
|
868
|
+
if (!toolCallId || !toolName || !runId2) return;
|
|
869
|
+
const pendingToolCalls2 = pendingToolCallsByRunId.get(runId2) ?? [];
|
|
870
|
+
pendingToolCalls2.push({ toolCallId, toolName, args: payload.args, observability: payload.observability });
|
|
871
|
+
pendingToolCallsByRunId.set(runId2, pendingToolCalls2);
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
if (chunk.type !== "finish") return;
|
|
875
|
+
const runId = chunk.runId;
|
|
876
|
+
const finishPayload = chunk;
|
|
877
|
+
if (!runId) return;
|
|
878
|
+
if (finishPayload.payload?.stepResult?.reason !== "tool-calls") {
|
|
879
|
+
agent.deleteSignalRuntimeOptions(runId);
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
const pendingToolCalls = pendingToolCallsByRunId.get(runId);
|
|
883
|
+
pendingToolCallsByRunId.delete(runId);
|
|
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) };
|
|
927
|
+
}
|
|
928
|
+
const toolResultContent = {
|
|
929
|
+
type: "tool-result",
|
|
930
|
+
toolCallId: toolCall.toolCallId,
|
|
931
|
+
toolName: toolCall.toolName,
|
|
932
|
+
result
|
|
933
|
+
};
|
|
934
|
+
if (observability) {
|
|
935
|
+
toolResultContent.__mastraObservability = observability;
|
|
936
|
+
}
|
|
937
|
+
await onChunk({
|
|
938
|
+
type: "tool-result",
|
|
939
|
+
runId,
|
|
940
|
+
payload: toolResultContent
|
|
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 {
|
|
965
|
+
}
|
|
966
|
+
} catch (error) {
|
|
967
|
+
console.error("Error running client-tool continuation:", error);
|
|
968
|
+
} finally {
|
|
969
|
+
agent.deleteSignalRuntimeOptions(runId);
|
|
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;
|
|
997
|
+
}
|
|
998
|
+
if (!reconnectOptions || this.options.abortSignal?.aborted || attempts >= reconnectOptions.maxRetries) {
|
|
999
|
+
throw error;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
if (!reconnectOptions || this.options.abortSignal?.aborted || attempts >= reconnectOptions.maxRetries) {
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
while (attempts < reconnectOptions.maxRetries) {
|
|
1006
|
+
attempts++;
|
|
1007
|
+
if (this.options.abortSignal?.aborted) {
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
await new Promise((resolve) => setTimeout(resolve, reconnectOptions.delayMs));
|
|
1011
|
+
if (this.options.abortSignal?.aborted) {
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
try {
|
|
1015
|
+
response = await requestSubscription();
|
|
1016
|
+
break;
|
|
1017
|
+
} catch (error) {
|
|
1018
|
+
if (this.options.abortSignal?.aborted || attempts >= reconnectOptions.maxRetries) {
|
|
1019
|
+
throw error;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
765
1024
|
};
|
|
766
1025
|
return streamResponse;
|
|
767
1026
|
}
|