@mastra/client-js 0.1.23-alpha.0 → 0.2.0-alpha.1
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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +24 -0
- package/dist/index.cjs +83 -85
- package/dist/index.d.cts +73 -78
- package/dist/index.d.ts +73 -78
- package/dist/index.js +83 -85
- package/package.json +6 -5
- package/src/client.ts +20 -21
- package/src/resources/agent.ts +4 -3
- package/src/resources/index.ts +2 -2
- package/src/resources/{vnext-workflow.ts → legacy-workflow.ts} +124 -143
- package/src/resources/tool.ts +4 -3
- package/src/resources/workflow.ts +121 -109
- package/src/types.ts +21 -18
- package/src/utils/index.ts +11 -0
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import type { RuntimeContext } from '@mastra/core/runtime-context';
|
|
1
2
|
import type {
|
|
2
|
-
GetWorkflowResponse,
|
|
3
3
|
ClientOptions,
|
|
4
|
-
|
|
4
|
+
GetWorkflowResponse,
|
|
5
5
|
GetWorkflowRunsResponse,
|
|
6
6
|
GetWorkflowRunsParams,
|
|
7
|
+
WorkflowRunResult,
|
|
8
|
+
WorkflowWatchResult,
|
|
7
9
|
} from '../types';
|
|
8
10
|
|
|
11
|
+
import { parseClientRuntimeContext } from '../utils';
|
|
9
12
|
import { BaseResource } from './base';
|
|
10
13
|
|
|
11
14
|
const RECORD_SEPARATOR = '\x1E';
|
|
@@ -18,6 +21,77 @@ export class Workflow extends BaseResource {
|
|
|
18
21
|
super(options);
|
|
19
22
|
}
|
|
20
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Creates an async generator that processes a readable stream and yields workflow records
|
|
26
|
+
* separated by the Record Separator character (\x1E)
|
|
27
|
+
*
|
|
28
|
+
* @param stream - The readable stream to process
|
|
29
|
+
* @returns An async generator that yields parsed records
|
|
30
|
+
*/
|
|
31
|
+
private async *streamProcessor(stream: ReadableStream): AsyncGenerator<WorkflowWatchResult, void, unknown> {
|
|
32
|
+
const reader = stream.getReader();
|
|
33
|
+
|
|
34
|
+
// Track if we've finished reading from the stream
|
|
35
|
+
let doneReading = false;
|
|
36
|
+
// Buffer to accumulate partial chunks
|
|
37
|
+
let buffer = '';
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
while (!doneReading) {
|
|
41
|
+
// Read the next chunk from the stream
|
|
42
|
+
const { done, value } = await reader.read();
|
|
43
|
+
doneReading = done;
|
|
44
|
+
|
|
45
|
+
// Skip processing if we're done and there's no value
|
|
46
|
+
if (done && !value) continue;
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
// Decode binary data to text
|
|
50
|
+
const decoded = value ? new TextDecoder().decode(value) : '';
|
|
51
|
+
|
|
52
|
+
// Split the combined buffer and new data by record separator
|
|
53
|
+
const chunks = (buffer + decoded).split(RECORD_SEPARATOR);
|
|
54
|
+
|
|
55
|
+
// The last chunk might be incomplete, so save it for the next iteration
|
|
56
|
+
buffer = chunks.pop() || '';
|
|
57
|
+
|
|
58
|
+
// Process complete chunks
|
|
59
|
+
for (const chunk of chunks) {
|
|
60
|
+
if (chunk) {
|
|
61
|
+
// Only process non-empty chunks
|
|
62
|
+
if (typeof chunk === 'string') {
|
|
63
|
+
try {
|
|
64
|
+
const parsedChunk = JSON.parse(chunk);
|
|
65
|
+
yield parsedChunk;
|
|
66
|
+
} catch {
|
|
67
|
+
// Silently ignore parsing errors to maintain stream processing
|
|
68
|
+
// This allows the stream to continue even if one record is malformed
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
// Silently ignore parsing errors to maintain stream processing
|
|
75
|
+
// This allows the stream to continue even if one record is malformed
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Process any remaining data in the buffer after stream is done
|
|
80
|
+
if (buffer) {
|
|
81
|
+
try {
|
|
82
|
+
yield JSON.parse(buffer);
|
|
83
|
+
} catch {
|
|
84
|
+
// Ignore parsing error for final chunk
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
} finally {
|
|
88
|
+
// Always ensure we clean up the reader
|
|
89
|
+
reader.cancel().catch(() => {
|
|
90
|
+
// Ignore cancel errors
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
21
95
|
/**
|
|
22
96
|
* Retrieves details about the workflow
|
|
23
97
|
* @returns Promise containing workflow details including steps and graphs
|
|
@@ -56,22 +130,10 @@ export class Workflow extends BaseResource {
|
|
|
56
130
|
}
|
|
57
131
|
}
|
|
58
132
|
|
|
59
|
-
/**
|
|
60
|
-
* @deprecated Use `startAsync` instead
|
|
61
|
-
* Executes the workflow with the provided parameters
|
|
62
|
-
* @param params - Parameters required for workflow execution
|
|
63
|
-
* @returns Promise containing the workflow execution results
|
|
64
|
-
*/
|
|
65
|
-
execute(params: Record<string, any>): Promise<WorkflowRunResult> {
|
|
66
|
-
return this.request(`/api/workflows/${this.workflowId}/execute`, {
|
|
67
|
-
method: 'POST',
|
|
68
|
-
body: params,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
|
|
72
133
|
/**
|
|
73
134
|
* Creates a new workflow run
|
|
74
|
-
* @
|
|
135
|
+
* @param params - Optional object containing the optional runId
|
|
136
|
+
* @returns Promise containing the runId of the created run
|
|
75
137
|
*/
|
|
76
138
|
createRun(params?: { runId?: string }): Promise<{ runId: string }> {
|
|
77
139
|
const searchParams = new URLSearchParams();
|
|
@@ -80,158 +142,108 @@ export class Workflow extends BaseResource {
|
|
|
80
142
|
searchParams.set('runId', params.runId);
|
|
81
143
|
}
|
|
82
144
|
|
|
83
|
-
return this.request(`/api/workflows/${this.workflowId}/
|
|
145
|
+
return this.request(`/api/workflows/${this.workflowId}/create-run?${searchParams.toString()}`, {
|
|
84
146
|
method: 'POST',
|
|
85
147
|
});
|
|
86
148
|
}
|
|
87
149
|
|
|
88
150
|
/**
|
|
89
151
|
* Starts a workflow run synchronously without waiting for the workflow to complete
|
|
90
|
-
* @param params - Object containing the runId and
|
|
152
|
+
* @param params - Object containing the runId, inputData and runtimeContext
|
|
91
153
|
* @returns Promise containing success message
|
|
92
154
|
*/
|
|
93
|
-
start(params: {
|
|
155
|
+
start(params: {
|
|
156
|
+
runId: string;
|
|
157
|
+
inputData: Record<string, any>;
|
|
158
|
+
runtimeContext?: RuntimeContext | Record<string, any>;
|
|
159
|
+
}): Promise<{ message: string }> {
|
|
160
|
+
const runtimeContext = parseClientRuntimeContext(params.runtimeContext);
|
|
94
161
|
return this.request(`/api/workflows/${this.workflowId}/start?runId=${params.runId}`, {
|
|
95
162
|
method: 'POST',
|
|
96
|
-
body: params?.
|
|
163
|
+
body: { inputData: params?.inputData, runtimeContext },
|
|
97
164
|
});
|
|
98
165
|
}
|
|
99
166
|
|
|
100
167
|
/**
|
|
101
168
|
* Resumes a suspended workflow step synchronously without waiting for the workflow to complete
|
|
102
|
-
* @param
|
|
103
|
-
* @
|
|
104
|
-
* @param context - Context to resume the workflow with
|
|
105
|
-
* @returns Promise containing the workflow resume results
|
|
169
|
+
* @param params - Object containing the runId, step, resumeData and runtimeContext
|
|
170
|
+
* @returns Promise containing success message
|
|
106
171
|
*/
|
|
107
172
|
resume({
|
|
108
|
-
|
|
173
|
+
step,
|
|
109
174
|
runId,
|
|
110
|
-
|
|
175
|
+
resumeData,
|
|
176
|
+
...rest
|
|
111
177
|
}: {
|
|
112
|
-
|
|
178
|
+
step: string | string[];
|
|
113
179
|
runId: string;
|
|
114
|
-
|
|
180
|
+
resumeData?: Record<string, any>;
|
|
181
|
+
runtimeContext?: RuntimeContext | Record<string, any>;
|
|
115
182
|
}): Promise<{ message: string }> {
|
|
183
|
+
const runtimeContext = parseClientRuntimeContext(rest.runtimeContext);
|
|
116
184
|
return this.request(`/api/workflows/${this.workflowId}/resume?runId=${runId}`, {
|
|
117
185
|
method: 'POST',
|
|
186
|
+
stream: true,
|
|
118
187
|
body: {
|
|
119
|
-
|
|
120
|
-
|
|
188
|
+
step,
|
|
189
|
+
resumeData,
|
|
190
|
+
runtimeContext,
|
|
121
191
|
},
|
|
122
192
|
});
|
|
123
193
|
}
|
|
124
194
|
|
|
125
195
|
/**
|
|
126
196
|
* Starts a workflow run asynchronously and returns a promise that resolves when the workflow is complete
|
|
127
|
-
* @param params - Object containing the optional runId and
|
|
197
|
+
* @param params - Object containing the optional runId, inputData and runtimeContext
|
|
128
198
|
* @returns Promise containing the workflow execution results
|
|
129
199
|
*/
|
|
130
|
-
startAsync(params: {
|
|
200
|
+
startAsync(params: {
|
|
201
|
+
runId?: string;
|
|
202
|
+
inputData: Record<string, any>;
|
|
203
|
+
runtimeContext?: RuntimeContext | Record<string, any>;
|
|
204
|
+
}): Promise<WorkflowRunResult> {
|
|
131
205
|
const searchParams = new URLSearchParams();
|
|
132
206
|
|
|
133
207
|
if (!!params?.runId) {
|
|
134
208
|
searchParams.set('runId', params.runId);
|
|
135
209
|
}
|
|
136
210
|
|
|
211
|
+
const runtimeContext = parseClientRuntimeContext(params.runtimeContext);
|
|
212
|
+
|
|
137
213
|
return this.request(`/api/workflows/${this.workflowId}/start-async?${searchParams.toString()}`, {
|
|
138
214
|
method: 'POST',
|
|
139
|
-
body: params
|
|
215
|
+
body: { inputData: params.inputData, runtimeContext },
|
|
140
216
|
});
|
|
141
217
|
}
|
|
142
218
|
|
|
143
219
|
/**
|
|
144
220
|
* Resumes a suspended workflow step asynchronously and returns a promise that resolves when the workflow is complete
|
|
145
|
-
* @param params - Object containing the runId,
|
|
221
|
+
* @param params - Object containing the runId, step, resumeData and runtimeContext
|
|
146
222
|
* @returns Promise containing the workflow resume results
|
|
147
223
|
*/
|
|
148
|
-
resumeAsync(params: {
|
|
224
|
+
resumeAsync(params: {
|
|
225
|
+
runId: string;
|
|
226
|
+
step: string | string[];
|
|
227
|
+
resumeData?: Record<string, any>;
|
|
228
|
+
runtimeContext?: RuntimeContext | Record<string, any>;
|
|
229
|
+
}): Promise<WorkflowRunResult> {
|
|
230
|
+
const runtimeContext = parseClientRuntimeContext(params.runtimeContext);
|
|
149
231
|
return this.request(`/api/workflows/${this.workflowId}/resume-async?runId=${params.runId}`, {
|
|
150
232
|
method: 'POST',
|
|
151
233
|
body: {
|
|
152
|
-
|
|
153
|
-
|
|
234
|
+
step: params.step,
|
|
235
|
+
resumeData: params.resumeData,
|
|
236
|
+
runtimeContext,
|
|
154
237
|
},
|
|
155
238
|
});
|
|
156
239
|
}
|
|
157
240
|
|
|
158
|
-
/**
|
|
159
|
-
* Creates an async generator that processes a readable stream and yields records
|
|
160
|
-
* separated by the Record Separator character (\x1E)
|
|
161
|
-
*
|
|
162
|
-
* @param stream - The readable stream to process
|
|
163
|
-
* @returns An async generator that yields parsed records
|
|
164
|
-
*/
|
|
165
|
-
private async *streamProcessor(stream: ReadableStream): AsyncGenerator<WorkflowRunResult, void, unknown> {
|
|
166
|
-
const reader = stream.getReader();
|
|
167
|
-
|
|
168
|
-
// Track if we've finished reading from the stream
|
|
169
|
-
let doneReading = false;
|
|
170
|
-
// Buffer to accumulate partial chunks
|
|
171
|
-
let buffer = '';
|
|
172
|
-
|
|
173
|
-
try {
|
|
174
|
-
while (!doneReading) {
|
|
175
|
-
// Read the next chunk from the stream
|
|
176
|
-
const { done, value } = await reader.read();
|
|
177
|
-
doneReading = done;
|
|
178
|
-
|
|
179
|
-
// Skip processing if we're done and there's no value
|
|
180
|
-
if (done && !value) continue;
|
|
181
|
-
|
|
182
|
-
try {
|
|
183
|
-
// Decode binary data to text
|
|
184
|
-
const decoded = value ? new TextDecoder().decode(value) : '';
|
|
185
|
-
|
|
186
|
-
// Split the combined buffer and new data by record separator
|
|
187
|
-
const chunks = (buffer + decoded).split(RECORD_SEPARATOR);
|
|
188
|
-
|
|
189
|
-
// The last chunk might be incomplete, so save it for the next iteration
|
|
190
|
-
buffer = chunks.pop() || '';
|
|
191
|
-
|
|
192
|
-
// Process complete chunks
|
|
193
|
-
for (const chunk of chunks) {
|
|
194
|
-
if (chunk) {
|
|
195
|
-
// Only process non-empty chunks
|
|
196
|
-
if (typeof chunk === 'string') {
|
|
197
|
-
try {
|
|
198
|
-
const parsedChunk = JSON.parse(chunk);
|
|
199
|
-
yield parsedChunk;
|
|
200
|
-
} catch {
|
|
201
|
-
// Silently ignore parsing errors to maintain stream processing
|
|
202
|
-
// This allows the stream to continue even if one record is malformed
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
} catch {
|
|
208
|
-
// Silently ignore parsing errors to maintain stream processing
|
|
209
|
-
// This allows the stream to continue even if one record is malformed
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Process any remaining data in the buffer after stream is done
|
|
214
|
-
if (buffer) {
|
|
215
|
-
try {
|
|
216
|
-
yield JSON.parse(buffer);
|
|
217
|
-
} catch {
|
|
218
|
-
// Ignore parsing error for final chunk
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
} finally {
|
|
222
|
-
// Always ensure we clean up the reader
|
|
223
|
-
reader.cancel().catch(() => {
|
|
224
|
-
// Ignore cancel errors
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
241
|
/**
|
|
230
242
|
* Watches workflow transitions in real-time
|
|
231
243
|
* @param runId - Optional run ID to filter the watch stream
|
|
232
244
|
* @returns AsyncGenerator that yields parsed records from the workflow watch stream
|
|
233
245
|
*/
|
|
234
|
-
async watch({ runId }: { runId?: string }, onRecord: (record:
|
|
246
|
+
async watch({ runId }: { runId?: string }, onRecord: (record: WorkflowWatchResult) => void) {
|
|
235
247
|
const response: Response = await this.request(`/api/workflows/${this.workflowId}/watch?runId=${runId}`, {
|
|
236
248
|
stream: true,
|
|
237
249
|
});
|
package/src/types.ts
CHANGED
|
@@ -3,19 +3,21 @@ import type {
|
|
|
3
3
|
AiMessageType,
|
|
4
4
|
CoreMessage,
|
|
5
5
|
QueryResult,
|
|
6
|
-
StepAction,
|
|
7
|
-
StepGraph,
|
|
8
6
|
StorageThreadType,
|
|
9
|
-
BaseLogMessage,
|
|
10
|
-
WorkflowRunResult as CoreWorkflowRunResult,
|
|
11
|
-
VNextWorkflowRuns,
|
|
12
7
|
WorkflowRuns,
|
|
8
|
+
LegacyWorkflowRuns,
|
|
13
9
|
} from '@mastra/core';
|
|
10
|
+
import type { BaseLogMessage } from '@mastra/core/logger';
|
|
14
11
|
|
|
15
12
|
import type { AgentGenerateOptions, AgentStreamOptions } from '@mastra/core/agent';
|
|
16
|
-
import type { RuntimeContext } from '@mastra/core/runtime-context';
|
|
17
13
|
import type { ServerInfo } from '@mastra/core/mcp';
|
|
18
|
-
import type {
|
|
14
|
+
import type { RuntimeContext } from '@mastra/core/runtime-context';
|
|
15
|
+
import type { Workflow, WatchEvent, WorkflowResult } from '@mastra/core/workflows';
|
|
16
|
+
import type {
|
|
17
|
+
StepAction,
|
|
18
|
+
StepGraph,
|
|
19
|
+
LegacyWorkflowRunResult as CoreLegacyWorkflowRunResult,
|
|
20
|
+
} from '@mastra/core/workflows/legacy';
|
|
19
21
|
import type { JSONSchema7 } from 'json-schema';
|
|
20
22
|
import type { ZodSchema } from 'zod';
|
|
21
23
|
|
|
@@ -64,14 +66,14 @@ export type GenerateParams<T extends JSONSchema7 | ZodSchema | undefined = undef
|
|
|
64
66
|
messages: string | string[] | CoreMessage[] | AiMessageType[];
|
|
65
67
|
output?: T;
|
|
66
68
|
experimental_output?: T;
|
|
67
|
-
runtimeContext?: RuntimeContext
|
|
69
|
+
runtimeContext?: RuntimeContext | Record<string, any>;
|
|
68
70
|
} & WithoutMethods<Omit<AgentGenerateOptions<T>, 'output' | 'experimental_output' | 'runtimeContext'>>;
|
|
69
71
|
|
|
70
72
|
export type StreamParams<T extends JSONSchema7 | ZodSchema | undefined = undefined> = {
|
|
71
73
|
messages: string | string[] | CoreMessage[] | AiMessageType[];
|
|
72
74
|
output?: T;
|
|
73
75
|
experimental_output?: T;
|
|
74
|
-
runtimeContext?: RuntimeContext
|
|
76
|
+
runtimeContext?: RuntimeContext | Record<string, any>;
|
|
75
77
|
} & WithoutMethods<Omit<AgentStreamOptions<T>, 'output' | 'experimental_output' | 'runtimeContext'>>;
|
|
76
78
|
|
|
77
79
|
export interface GetEvalsByAgentIdResponse extends GetAgentResponse {
|
|
@@ -88,7 +90,7 @@ export interface GetToolResponse {
|
|
|
88
90
|
outputSchema: string;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
export interface
|
|
93
|
+
export interface GetLegacyWorkflowResponse {
|
|
92
94
|
name: string;
|
|
93
95
|
triggerSchema: string;
|
|
94
96
|
steps: Record<string, StepAction<any, any, any, any>>;
|
|
@@ -105,19 +107,20 @@ export interface GetWorkflowRunsParams {
|
|
|
105
107
|
resourceId?: string;
|
|
106
108
|
}
|
|
107
109
|
|
|
108
|
-
export type
|
|
110
|
+
export type GetLegacyWorkflowRunsResponse = LegacyWorkflowRuns;
|
|
109
111
|
|
|
110
|
-
export type
|
|
112
|
+
export type GetWorkflowRunsResponse = WorkflowRuns;
|
|
111
113
|
|
|
112
|
-
export type
|
|
114
|
+
export type LegacyWorkflowRunResult = {
|
|
113
115
|
activePaths: Record<string, { status: string; suspendPayload?: any; stepPath: string[] }>;
|
|
114
|
-
results:
|
|
116
|
+
results: CoreLegacyWorkflowRunResult<any, any, any>['results'];
|
|
115
117
|
timestamp: number;
|
|
116
118
|
runId: string;
|
|
117
119
|
};
|
|
118
120
|
|
|
119
|
-
export interface
|
|
121
|
+
export interface GetWorkflowResponse {
|
|
120
122
|
name: string;
|
|
123
|
+
description?: string;
|
|
121
124
|
steps: {
|
|
122
125
|
[key: string]: {
|
|
123
126
|
id: string;
|
|
@@ -128,14 +131,14 @@ export interface GetVNextWorkflowResponse {
|
|
|
128
131
|
suspendSchema: string;
|
|
129
132
|
};
|
|
130
133
|
};
|
|
131
|
-
stepGraph:
|
|
134
|
+
stepGraph: Workflow['serializedStepGraph'];
|
|
132
135
|
inputSchema: string;
|
|
133
136
|
outputSchema: string;
|
|
134
137
|
}
|
|
135
138
|
|
|
136
|
-
export type
|
|
139
|
+
export type WorkflowWatchResult = WatchEvent & { runId: string };
|
|
137
140
|
|
|
138
|
-
export type
|
|
141
|
+
export type WorkflowRunResult = WorkflowResult<any, any>;
|
|
139
142
|
export interface UpsertVectorParams {
|
|
140
143
|
indexName: string;
|
|
141
144
|
vectors: number[][];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RuntimeContext } from '@mastra/core/runtime-context';
|
|
2
|
+
|
|
3
|
+
export function parseClientRuntimeContext(runtimeContext?: RuntimeContext | Record<string, any>) {
|
|
4
|
+
if (runtimeContext) {
|
|
5
|
+
if (runtimeContext instanceof RuntimeContext) {
|
|
6
|
+
return Object.fromEntries(runtimeContext.entries());
|
|
7
|
+
}
|
|
8
|
+
return runtimeContext;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|