@modelrelay/sdk 1.42.0 → 2.1.0
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/README.md +14 -46
- package/dist/api-DZpC1zuz.d.cts +4691 -0
- package/dist/api-DZpC1zuz.d.ts +4691 -0
- package/dist/api-D_hE36Ps.d.cts +4535 -0
- package/dist/api-D_hE36Ps.d.ts +4535 -0
- package/dist/api-Dz9HcUTt.d.cts +4522 -0
- package/dist/api-Dz9HcUTt.d.ts +4522 -0
- package/dist/billing/index.d.cts +3 -3
- package/dist/billing/index.d.ts +3 -3
- package/dist/chunk-AZD5EKLV.js +1133 -0
- package/dist/chunk-CYGWZYYJ.js +1194 -0
- package/dist/chunk-MXXJDLGU.js +1194 -0
- package/dist/chunk-R6O6UQYM.js +1133 -0
- package/dist/chunk-SCOP57J4.js +1194 -0
- package/dist/index.cjs +225 -2970
- package/dist/index.d.cts +101 -2090
- package/dist/index.d.ts +101 -2090
- package/dist/index.js +231 -2894
- package/dist/node.cjs +8 -9
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js +8 -9
- package/dist/tools-CvfwPjC5.d.cts +1098 -0
- package/dist/tools-CvfwPjC5.d.ts +1098 -0
- package/dist/tools-DUYHZdZP.d.cts +982 -0
- package/dist/tools-DUYHZdZP.d.ts +982 -0
- package/dist/tools-bCt1QwNk.d.cts +998 -0
- package/dist/tools-bCt1QwNk.d.ts +998 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -34,8 +34,6 @@ __export(index_exports, {
|
|
|
34
34
|
AuthClient: () => AuthClient,
|
|
35
35
|
BillingProviders: () => BillingProviders,
|
|
36
36
|
BindingTargetError: () => BindingTargetError,
|
|
37
|
-
Chain: () => Chain,
|
|
38
|
-
ChainBuilder: () => ChainBuilder,
|
|
39
37
|
ConfigError: () => ConfigError,
|
|
40
38
|
ContentPartTypes: () => ContentPartTypes,
|
|
41
39
|
CustomerResponsesClient: () => CustomerResponsesClient,
|
|
@@ -46,7 +44,6 @@ __export(index_exports, {
|
|
|
46
44
|
DEFAULT_CONNECT_TIMEOUT_MS: () => DEFAULT_CONNECT_TIMEOUT_MS,
|
|
47
45
|
DEFAULT_REQUEST_TIMEOUT_MS: () => DEFAULT_REQUEST_TIMEOUT_MS,
|
|
48
46
|
ErrorCodes: () => ErrorCodes,
|
|
49
|
-
FrontendTokenProvider: () => FrontendTokenProvider,
|
|
50
47
|
ImagesClient: () => ImagesClient,
|
|
51
48
|
InputItemTypes: () => InputItemTypes,
|
|
52
49
|
JoinOutput: () => JoinOutput,
|
|
@@ -58,29 +55,21 @@ __export(index_exports, {
|
|
|
58
55
|
LLMInputPath: () => LLMInputPath,
|
|
59
56
|
LLMInputSystemText: () => LLMInputSystemText,
|
|
60
57
|
LLMInputUserText: () => LLMInputUserText,
|
|
61
|
-
LLMNodeBuilder: () => LLMNodeBuilder,
|
|
62
58
|
LLMOutput: () => LLMOutput,
|
|
63
59
|
LLMOutputContentItemPath: () => LLMOutputContentItemPath,
|
|
64
60
|
LLMOutputContentPath: () => LLMOutputContentPath,
|
|
65
61
|
LLMOutputPath: () => LLMOutputPath,
|
|
66
62
|
LLMOutputText: () => LLMOutputText,
|
|
67
|
-
LLMStep: () => LLMStep,
|
|
68
63
|
LLM_TEXT_OUTPUT: () => LLM_TEXT_OUTPUT,
|
|
69
64
|
LLM_USER_MESSAGE_TEXT: () => LLM_USER_MESSAGE_TEXT,
|
|
70
65
|
LocalSession: () => LocalSession,
|
|
71
66
|
MapFanoutInputError: () => MapFanoutInputError,
|
|
72
|
-
MapItem: () => MapItem,
|
|
73
|
-
MapReduce: () => MapReduce,
|
|
74
|
-
MapReduceBuilder: () => MapReduceBuilder,
|
|
75
67
|
MemorySessionStore: () => MemorySessionStore,
|
|
76
68
|
MessageRoles: () => MessageRoles,
|
|
77
69
|
ModelRelay: () => ModelRelay,
|
|
78
70
|
ModelRelayError: () => ModelRelayError,
|
|
79
|
-
OIDCExchangeTokenProvider: () => OIDCExchangeTokenProvider,
|
|
80
71
|
OutputFormatTypes: () => OutputFormatTypes,
|
|
81
72
|
OutputItemTypes: () => OutputItemTypes,
|
|
82
|
-
Parallel: () => Parallel,
|
|
83
|
-
ParallelBuilder: () => ParallelBuilder,
|
|
84
73
|
PathEscapeError: () => PathEscapeError,
|
|
85
74
|
ResponsesClient: () => ResponsesClient,
|
|
86
75
|
ResponsesStream: () => ResponsesStream,
|
|
@@ -103,15 +92,13 @@ __export(index_exports, {
|
|
|
103
92
|
ToolRegistry: () => ToolRegistry,
|
|
104
93
|
ToolRunner: () => ToolRunner,
|
|
105
94
|
ToolTypes: () => ToolTypes,
|
|
106
|
-
TransformJSONNodeBuilder: () => TransformJSONNodeBuilder,
|
|
107
95
|
TransportError: () => TransportError,
|
|
108
96
|
WORKFLOWS_COMPILE_PATH: () => WORKFLOWS_COMPILE_PATH,
|
|
109
97
|
WebToolIntents: () => WebToolIntents,
|
|
110
|
-
Workflow: () => Workflow,
|
|
111
|
-
WorkflowBuilderV0: () => WorkflowBuilderV0,
|
|
112
98
|
WorkflowBuilderV1: () => WorkflowBuilderV1,
|
|
113
99
|
WorkflowKinds: () => WorkflowKinds,
|
|
114
|
-
WorkflowNodeTypes: () =>
|
|
100
|
+
WorkflowNodeTypes: () => WorkflowNodeTypesV1,
|
|
101
|
+
WorkflowNodeTypesV1: () => WorkflowNodeTypesV1,
|
|
115
102
|
WorkflowValidationError: () => WorkflowValidationError,
|
|
116
103
|
WorkflowsClient: () => WorkflowsClient,
|
|
117
104
|
asModelId: () => asModelId,
|
|
@@ -147,17 +134,10 @@ __export(index_exports, {
|
|
|
147
134
|
getRetryableErrors: () => getRetryableErrors,
|
|
148
135
|
hasRetryableErrors: () => hasRetryableErrors,
|
|
149
136
|
hasToolCalls: () => hasToolCalls,
|
|
150
|
-
isAutoProvisionDisabled: () => isAutoProvisionDisabled,
|
|
151
|
-
isAutoProvisionMisconfigured: () => isAutoProvisionMisconfigured,
|
|
152
|
-
isEmailRequired: () => isEmailRequired,
|
|
153
|
-
isIdentityRequired: () => isIdentityRequired,
|
|
154
|
-
isProvisioningError: () => isProvisioningError,
|
|
155
|
-
isPublishableKey: () => isPublishableKey,
|
|
156
137
|
isSecretKey: () => isSecretKey,
|
|
157
138
|
mergeMetrics: () => mergeMetrics,
|
|
158
139
|
mergeTrace: () => mergeTrace,
|
|
159
140
|
modelToString: () => modelToString,
|
|
160
|
-
newWorkflow: () => newWorkflow,
|
|
161
141
|
normalizeModelId: () => normalizeModelId,
|
|
162
142
|
normalizeStopReason: () => normalizeStopReason,
|
|
163
143
|
outputFormatFromZod: () => outputFormatFromZod,
|
|
@@ -166,34 +146,23 @@ __export(index_exports, {
|
|
|
166
146
|
parseNodeId: () => parseNodeId,
|
|
167
147
|
parseOutputName: () => parseOutputName,
|
|
168
148
|
parsePlanHash: () => parsePlanHash,
|
|
169
|
-
parsePublishableKey: () => parsePublishableKey,
|
|
170
149
|
parseRunId: () => parseRunId,
|
|
171
150
|
parseSecretKey: () => parseSecretKey,
|
|
172
151
|
parseToolArgs: () => parseToolArgs,
|
|
173
152
|
parseToolArgsRaw: () => parseToolArgsRaw,
|
|
174
|
-
pollOAuthDeviceToken: () => pollOAuthDeviceToken,
|
|
175
|
-
pollUntil: () => pollUntil,
|
|
176
153
|
respondToToolCall: () => respondToToolCall,
|
|
177
|
-
runOAuthDeviceFlowForIDToken: () => runOAuthDeviceFlowForIDToken,
|
|
178
|
-
startOAuthDeviceAuthorization: () => startOAuthDeviceAuthorization,
|
|
179
154
|
stopReasonToString: () => stopReasonToString,
|
|
180
155
|
toolChoiceAuto: () => toolChoiceAuto,
|
|
181
156
|
toolChoiceNone: () => toolChoiceNone,
|
|
182
157
|
toolChoiceRequired: () => toolChoiceRequired,
|
|
183
158
|
toolResultMessage: () => toolResultMessage,
|
|
184
159
|
transformJSONMerge: () => transformJSONMerge,
|
|
185
|
-
transformJSONMergeV1: () => transformJSONMergeV1,
|
|
186
160
|
transformJSONObject: () => transformJSONObject,
|
|
187
|
-
transformJSONObjectV1: () => transformJSONObjectV1,
|
|
188
161
|
transformJSONValue: () => transformJSONValue,
|
|
189
|
-
transformJSONValueV1: () => transformJSONValueV1,
|
|
190
162
|
tryParseToolArgs: () => tryParseToolArgs,
|
|
191
163
|
validateWithZod: () => validateWithZod,
|
|
192
164
|
workflow: () => workflow_exports,
|
|
193
|
-
workflowV0: () => workflowV0,
|
|
194
|
-
workflowV0Schema: () => workflow_v0_schema_default,
|
|
195
165
|
workflowV1: () => workflowV1,
|
|
196
|
-
workflowV1Schema: () => workflow_v1_schema_default,
|
|
197
166
|
zodToJsonSchema: () => zodToJsonSchema
|
|
198
167
|
});
|
|
199
168
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -210,15 +179,7 @@ var ErrorCodes = {
|
|
|
210
179
|
SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE",
|
|
211
180
|
INVALID_INPUT: "INVALID_INPUT",
|
|
212
181
|
PAYMENT_REQUIRED: "PAYMENT_REQUIRED",
|
|
213
|
-
METHOD_NOT_ALLOWED: "METHOD_NOT_ALLOWED"
|
|
214
|
-
/** Identity provider + subject required for identity-based auth. */
|
|
215
|
-
IDENTITY_REQUIRED: "IDENTITY_REQUIRED",
|
|
216
|
-
/** Auto-provision disabled for the project. */
|
|
217
|
-
AUTO_PROVISION_DISABLED: "AUTO_PROVISION_DISABLED",
|
|
218
|
-
/** Auto-provision tier misconfigured for the project. */
|
|
219
|
-
AUTO_PROVISION_MISCONFIGURED: "AUTO_PROVISION_MISCONFIGURED",
|
|
220
|
-
/** Email required for auto-provisioning a new customer. */
|
|
221
|
-
EMAIL_REQUIRED: "EMAIL_REQUIRED"
|
|
182
|
+
METHOD_NOT_ALLOWED: "METHOD_NOT_ALLOWED"
|
|
222
183
|
};
|
|
223
184
|
var ModelRelayError = class extends Error {
|
|
224
185
|
constructor(message, opts) {
|
|
@@ -306,39 +267,6 @@ var APIError = class extends ModelRelayError {
|
|
|
306
267
|
isUnavailable() {
|
|
307
268
|
return this.code === ErrorCodes.SERVICE_UNAVAILABLE;
|
|
308
269
|
}
|
|
309
|
-
/**
|
|
310
|
-
* Returns true if the error indicates identity is missing/invalid for identity-based auth.
|
|
311
|
-
*/
|
|
312
|
-
isIdentityRequired() {
|
|
313
|
-
return this.code === ErrorCodes.IDENTITY_REQUIRED;
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Returns true if auto-provisioning is disabled for the project.
|
|
317
|
-
* To resolve: configure customer auto-provisioning on the project (select a default tier).
|
|
318
|
-
*/
|
|
319
|
-
isAutoProvisionDisabled() {
|
|
320
|
-
return this.code === ErrorCodes.AUTO_PROVISION_DISABLED;
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Returns true if email is required for auto-provisioning a new customer.
|
|
324
|
-
* To resolve: provide the 'email' field in your frontend token request.
|
|
325
|
-
*/
|
|
326
|
-
isEmailRequired() {
|
|
327
|
-
return this.code === ErrorCodes.EMAIL_REQUIRED;
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Returns true if auto-provisioning is misconfigured for the project.
|
|
331
|
-
* To resolve: ensure the configured auto-provision tier exists and belongs to the project.
|
|
332
|
-
*/
|
|
333
|
-
isAutoProvisionMisconfigured() {
|
|
334
|
-
return this.code === ErrorCodes.AUTO_PROVISION_MISCONFIGURED;
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Returns true if this is a customer provisioning error (identity not found + auto-provision disabled/misconfigured, or email required).
|
|
338
|
-
*/
|
|
339
|
-
isProvisioningError() {
|
|
340
|
-
return this.isAutoProvisionDisabled() || this.isAutoProvisionMisconfigured() || this.isEmailRequired();
|
|
341
|
-
}
|
|
342
270
|
};
|
|
343
271
|
var WorkflowValidationError = class extends ModelRelayError {
|
|
344
272
|
constructor(opts) {
|
|
@@ -375,21 +303,6 @@ var PathEscapeError = class extends ModelRelayError {
|
|
|
375
303
|
this.resolvedPath = opts.resolvedPath;
|
|
376
304
|
}
|
|
377
305
|
};
|
|
378
|
-
function isEmailRequired(err) {
|
|
379
|
-
return err instanceof APIError && err.isEmailRequired();
|
|
380
|
-
}
|
|
381
|
-
function isIdentityRequired(err) {
|
|
382
|
-
return err instanceof APIError && err.isIdentityRequired();
|
|
383
|
-
}
|
|
384
|
-
function isAutoProvisionDisabled(err) {
|
|
385
|
-
return err instanceof APIError && err.isAutoProvisionDisabled();
|
|
386
|
-
}
|
|
387
|
-
function isAutoProvisionMisconfigured(err) {
|
|
388
|
-
return err instanceof APIError && err.isAutoProvisionMisconfigured();
|
|
389
|
-
}
|
|
390
|
-
function isProvisioningError(err) {
|
|
391
|
-
return err instanceof APIError && err.isProvisioningError();
|
|
392
|
-
}
|
|
393
306
|
async function parseErrorResponse(response, retries) {
|
|
394
307
|
const requestId = response.headers.get("X-ModelRelay-Request-Id") || response.headers.get("X-Request-Id") || void 0;
|
|
395
308
|
const fallbackMessage = response.statusText || "Request failed";
|
|
@@ -474,33 +387,21 @@ async function parseErrorResponse(response, retries) {
|
|
|
474
387
|
}
|
|
475
388
|
|
|
476
389
|
// src/api_keys.ts
|
|
477
|
-
var PUBLISHABLE_PREFIX = "mr_pk_";
|
|
478
390
|
var SECRET_PREFIX = "mr_sk_";
|
|
479
391
|
function keyKindHint(raw) {
|
|
480
392
|
const value = raw?.trim?.() ? raw.trim() : "";
|
|
481
|
-
if (value.startsWith(PUBLISHABLE_PREFIX)) return "publishable";
|
|
482
393
|
if (value.startsWith(SECRET_PREFIX)) return "secret";
|
|
483
394
|
return "unknown";
|
|
484
395
|
}
|
|
485
396
|
function parseApiKey(raw) {
|
|
486
397
|
const value = raw?.trim?.() ? raw.trim() : "";
|
|
487
|
-
if (value.startsWith(PUBLISHABLE_PREFIX) && value.length > PUBLISHABLE_PREFIX.length) {
|
|
488
|
-
return value;
|
|
489
|
-
}
|
|
490
398
|
if (value.startsWith(SECRET_PREFIX) && value.length > SECRET_PREFIX.length) {
|
|
491
399
|
return value;
|
|
492
400
|
}
|
|
493
|
-
throw new ConfigError("Invalid API key format (expected
|
|
401
|
+
throw new ConfigError("Invalid API key format (expected mr_sk_*)", {
|
|
494
402
|
keyKind: keyKindHint(raw)
|
|
495
403
|
});
|
|
496
404
|
}
|
|
497
|
-
function parsePublishableKey(raw) {
|
|
498
|
-
const key = parseApiKey(raw);
|
|
499
|
-
if (!isPublishableKey(key)) {
|
|
500
|
-
throw new ConfigError("Publishable key required (expected mr_pk_*)", { keyKind: keyKindHint(raw) });
|
|
501
|
-
}
|
|
502
|
-
return key;
|
|
503
|
-
}
|
|
504
405
|
function parseSecretKey(raw) {
|
|
505
406
|
const key = parseApiKey(raw);
|
|
506
407
|
if (!isSecretKey(key)) {
|
|
@@ -508,9 +409,6 @@ function parseSecretKey(raw) {
|
|
|
508
409
|
}
|
|
509
410
|
return key;
|
|
510
411
|
}
|
|
511
|
-
function isPublishableKey(key) {
|
|
512
|
-
return key.startsWith(PUBLISHABLE_PREFIX);
|
|
513
|
-
}
|
|
514
412
|
function isSecretKey(key) {
|
|
515
413
|
return key.startsWith(SECRET_PREFIX);
|
|
516
414
|
}
|
|
@@ -518,7 +416,7 @@ function isSecretKey(key) {
|
|
|
518
416
|
// package.json
|
|
519
417
|
var package_default = {
|
|
520
418
|
name: "@modelrelay/sdk",
|
|
521
|
-
version: "1.
|
|
419
|
+
version: "2.1.0",
|
|
522
420
|
description: "TypeScript SDK for the ModelRelay API",
|
|
523
421
|
type: "module",
|
|
524
422
|
main: "dist/index.cjs",
|
|
@@ -723,102 +621,15 @@ function createAccessTokenAuth(accessToken) {
|
|
|
723
621
|
}
|
|
724
622
|
var AuthClient = class {
|
|
725
623
|
constructor(http, cfg) {
|
|
726
|
-
this.cachedFrontend = /* @__PURE__ */ new Map();
|
|
727
624
|
this.http = http;
|
|
728
625
|
this.apiKey = cfg.apiKey ? parseApiKey(cfg.apiKey) : void 0;
|
|
729
|
-
this.apiKeyIsPublishable = this.apiKey ? isPublishableKey(this.apiKey) : false;
|
|
730
626
|
this.accessToken = cfg.accessToken;
|
|
731
|
-
this.customer = cfg.customer;
|
|
732
627
|
this.tokenProvider = cfg.tokenProvider;
|
|
733
628
|
}
|
|
734
|
-
/**
|
|
735
|
-
* Exchange a publishable key for a short-lived frontend token for an existing customer.
|
|
736
|
-
* Tokens are cached until they are close to expiry.
|
|
737
|
-
*
|
|
738
|
-
* Use this method when the customer already exists in the system.
|
|
739
|
-
* For auto-provisioning new customers, use frontendTokenAutoProvision instead.
|
|
740
|
-
*/
|
|
741
|
-
async frontendToken(request) {
|
|
742
|
-
if (!request.publishableKey?.trim()) {
|
|
743
|
-
throw new ConfigError("publishableKey is required");
|
|
744
|
-
}
|
|
745
|
-
if (!request.identityProvider?.trim()) {
|
|
746
|
-
throw new ConfigError("identityProvider is required");
|
|
747
|
-
}
|
|
748
|
-
if (!request.identitySubject?.trim()) {
|
|
749
|
-
throw new ConfigError("identitySubject is required");
|
|
750
|
-
}
|
|
751
|
-
return this.sendFrontendTokenRequest(request);
|
|
752
|
-
}
|
|
753
|
-
/**
|
|
754
|
-
* Exchange a publishable key for a frontend token, creating the customer if needed.
|
|
755
|
-
* The customer will be auto-provisioned on the project's free tier.
|
|
756
|
-
* Tokens are cached until they are close to expiry.
|
|
757
|
-
*
|
|
758
|
-
* Use this method when the customer may not exist and should be created automatically.
|
|
759
|
-
* The email is required for auto-provisioning.
|
|
760
|
-
*/
|
|
761
|
-
async frontendTokenAutoProvision(request) {
|
|
762
|
-
if (!request.publishableKey?.trim()) {
|
|
763
|
-
throw new ConfigError("publishableKey is required");
|
|
764
|
-
}
|
|
765
|
-
if (!request.identityProvider?.trim()) {
|
|
766
|
-
throw new ConfigError("identityProvider is required");
|
|
767
|
-
}
|
|
768
|
-
if (!request.identitySubject?.trim()) {
|
|
769
|
-
throw new ConfigError("identitySubject is required");
|
|
770
|
-
}
|
|
771
|
-
if (!request.email?.trim()) {
|
|
772
|
-
throw new ConfigError("email is required for auto-provisioning");
|
|
773
|
-
}
|
|
774
|
-
return this.sendFrontendTokenRequest(request);
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Internal method to send frontend token requests.
|
|
778
|
-
*/
|
|
779
|
-
async sendFrontendTokenRequest(request) {
|
|
780
|
-
const { publishableKey, identityProvider, identitySubject, deviceId, ttlSeconds } = request;
|
|
781
|
-
const email = "email" in request ? request.email : void 0;
|
|
782
|
-
const cacheKey = `${publishableKey}:${identityProvider}:${identitySubject}:${deviceId || ""}`;
|
|
783
|
-
const cached = this.cachedFrontend.get(cacheKey);
|
|
784
|
-
if (cached && isTokenReusable(cached)) {
|
|
785
|
-
return cached;
|
|
786
|
-
}
|
|
787
|
-
const payload = {
|
|
788
|
-
publishable_key: publishableKey,
|
|
789
|
-
identity_provider: identityProvider,
|
|
790
|
-
identity_subject: identitySubject
|
|
791
|
-
};
|
|
792
|
-
if (deviceId) {
|
|
793
|
-
payload.device_id = deviceId;
|
|
794
|
-
}
|
|
795
|
-
if (typeof ttlSeconds === "number" && ttlSeconds > 0) {
|
|
796
|
-
payload.ttl_seconds = ttlSeconds;
|
|
797
|
-
}
|
|
798
|
-
if (email) {
|
|
799
|
-
payload.email = email;
|
|
800
|
-
}
|
|
801
|
-
const response = await this.http.json(
|
|
802
|
-
"/auth/frontend-token",
|
|
803
|
-
{
|
|
804
|
-
method: "POST",
|
|
805
|
-
body: payload
|
|
806
|
-
}
|
|
807
|
-
);
|
|
808
|
-
const token = normalizeFrontendToken(response, {
|
|
809
|
-
publishableKey,
|
|
810
|
-
deviceId,
|
|
811
|
-
identityProvider,
|
|
812
|
-
identitySubject
|
|
813
|
-
});
|
|
814
|
-
this.cachedFrontend.set(cacheKey, token);
|
|
815
|
-
return token;
|
|
816
|
-
}
|
|
817
629
|
/**
|
|
818
630
|
* Determine the correct auth headers for /responses.
|
|
819
|
-
* Publishable keys are automatically exchanged for frontend tokens.
|
|
820
631
|
*/
|
|
821
|
-
async authForResponses(
|
|
632
|
+
async authForResponses() {
|
|
822
633
|
if (this.accessToken) {
|
|
823
634
|
return createAccessTokenAuth(this.accessToken);
|
|
824
635
|
}
|
|
@@ -832,32 +643,6 @@ var AuthClient = class {
|
|
|
832
643
|
if (!this.apiKey) {
|
|
833
644
|
throw new ConfigError("API key or token is required");
|
|
834
645
|
}
|
|
835
|
-
if (this.apiKeyIsPublishable) {
|
|
836
|
-
const publishableKey = this.apiKey;
|
|
837
|
-
const identityProvider = overrides?.provider || this.customer?.provider;
|
|
838
|
-
const identitySubject = overrides?.subject || this.customer?.subject;
|
|
839
|
-
const deviceId = overrides?.deviceId || this.customer?.deviceId;
|
|
840
|
-
const ttlSeconds = overrides?.ttlSeconds ?? this.customer?.ttlSeconds;
|
|
841
|
-
const email = overrides?.email || this.customer?.email;
|
|
842
|
-
if (!identityProvider || !identitySubject) {
|
|
843
|
-
throw new ConfigError("identity provider + subject are required to mint a frontend token");
|
|
844
|
-
}
|
|
845
|
-
const token = email ? await this.frontendTokenAutoProvision({
|
|
846
|
-
publishableKey,
|
|
847
|
-
identityProvider,
|
|
848
|
-
identitySubject,
|
|
849
|
-
email,
|
|
850
|
-
deviceId,
|
|
851
|
-
ttlSeconds
|
|
852
|
-
}) : await this.frontendToken({
|
|
853
|
-
publishableKey,
|
|
854
|
-
identityProvider,
|
|
855
|
-
identitySubject,
|
|
856
|
-
deviceId,
|
|
857
|
-
ttlSeconds
|
|
858
|
-
});
|
|
859
|
-
return createAccessTokenAuth(token.token);
|
|
860
|
-
}
|
|
861
646
|
return createApiKeyAuth(this.apiKey);
|
|
862
647
|
}
|
|
863
648
|
/**
|
|
@@ -872,7 +657,7 @@ var AuthClient = class {
|
|
|
872
657
|
if (request.ttlSeconds !== void 0 && request.ttlSeconds < 0) {
|
|
873
658
|
throw new ConfigError("ttlSeconds must be non-negative when provided");
|
|
874
659
|
}
|
|
875
|
-
if (!this.apiKey
|
|
660
|
+
if (!this.apiKey) {
|
|
876
661
|
throw new ConfigError("Secret API key is required to mint customer tokens");
|
|
877
662
|
}
|
|
878
663
|
const payload = {};
|
|
@@ -897,44 +682,54 @@ var AuthClient = class {
|
|
|
897
682
|
tokenType: apiResp.token_type,
|
|
898
683
|
projectId: apiResp.project_id,
|
|
899
684
|
customerId: apiResp.customer_id,
|
|
685
|
+
billingProfileId: apiResp.billing_profile_id,
|
|
900
686
|
customerExternalId: apiResp.customer_external_id,
|
|
901
687
|
tierCode: apiResp.tier_code ? asTierCode(apiResp.tier_code) : void 0
|
|
902
688
|
};
|
|
903
689
|
}
|
|
904
690
|
/**
|
|
905
|
-
*
|
|
691
|
+
* Get or create a customer and mint a bearer token.
|
|
692
|
+
*
|
|
693
|
+
* This is a convenience method that:
|
|
694
|
+
* 1. Upserts the customer (creates if not exists)
|
|
695
|
+
* 2. Mints a customer-scoped bearer token
|
|
696
|
+
*
|
|
697
|
+
* Use this when you want to ensure the customer exists before minting a token,
|
|
698
|
+
* without needing to handle 404 errors from customerToken().
|
|
699
|
+
*
|
|
700
|
+
* Requires a secret key.
|
|
906
701
|
*/
|
|
907
|
-
async
|
|
908
|
-
const
|
|
909
|
-
|
|
910
|
-
|
|
702
|
+
async getOrCreateCustomerToken(request) {
|
|
703
|
+
const externalId = request.externalId?.trim();
|
|
704
|
+
const email = request.email?.trim();
|
|
705
|
+
if (!externalId) {
|
|
706
|
+
throw new ConfigError("externalId is required");
|
|
707
|
+
}
|
|
708
|
+
if (!email) {
|
|
709
|
+
throw new ConfigError("email is required");
|
|
911
710
|
}
|
|
912
711
|
if (!this.apiKey) {
|
|
913
|
-
throw new ConfigError("API key is required
|
|
712
|
+
throw new ConfigError("Secret API key is required to get or create customer tokens");
|
|
914
713
|
}
|
|
915
|
-
const
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
714
|
+
const upsertPayload = {
|
|
715
|
+
external_id: externalId,
|
|
716
|
+
email
|
|
717
|
+
};
|
|
718
|
+
if (request.metadata) {
|
|
719
|
+
upsertPayload.metadata = request.metadata;
|
|
919
720
|
}
|
|
920
|
-
|
|
921
|
-
method: "
|
|
922
|
-
body:
|
|
721
|
+
await this.http.json("/customers", {
|
|
722
|
+
method: "PUT",
|
|
723
|
+
body: upsertPayload,
|
|
923
724
|
apiKey: this.apiKey
|
|
924
725
|
});
|
|
925
|
-
return {
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
tokenType: apiResp.token_type,
|
|
930
|
-
projectId: apiResp.project_id,
|
|
931
|
-
customerId: apiResp.customer_id,
|
|
932
|
-
customerExternalId: apiResp.customer_external_id,
|
|
933
|
-
tierCode: apiResp.tier_code ? asTierCode(apiResp.tier_code) : void 0
|
|
934
|
-
};
|
|
726
|
+
return this.customerToken({
|
|
727
|
+
customerExternalId: externalId,
|
|
728
|
+
ttlSeconds: request.ttlSeconds
|
|
729
|
+
});
|
|
935
730
|
}
|
|
936
731
|
/**
|
|
937
|
-
* Billing calls accept either bearer tokens or API keys
|
|
732
|
+
* Billing calls accept either bearer tokens or API keys.
|
|
938
733
|
*/
|
|
939
734
|
authForBilling() {
|
|
940
735
|
if (this.accessToken) {
|
|
@@ -945,207 +740,7 @@ var AuthClient = class {
|
|
|
945
740
|
}
|
|
946
741
|
return createApiKeyAuth(this.apiKey);
|
|
947
742
|
}
|
|
948
|
-
/**
|
|
949
|
-
* Start a device authorization flow (RFC 8628).
|
|
950
|
-
*
|
|
951
|
-
* @param request - Optional request options
|
|
952
|
-
* @param request.provider - Set to "github" to use GitHub's native device flow
|
|
953
|
-
*
|
|
954
|
-
* @example Wrapped flow (default)
|
|
955
|
-
* ```typescript
|
|
956
|
-
* const auth = await client.auth.deviceStart();
|
|
957
|
-
* console.log(`Go to ${auth.verificationUri} and enter code: ${auth.userCode}`);
|
|
958
|
-
* ```
|
|
959
|
-
*
|
|
960
|
-
* @example Native GitHub flow
|
|
961
|
-
* ```typescript
|
|
962
|
-
* const auth = await client.auth.deviceStart({ provider: "github" });
|
|
963
|
-
* // verificationUri will be "https://github.com/login/device"
|
|
964
|
-
* console.log(`Go to ${auth.verificationUri} and enter code: ${auth.userCode}`);
|
|
965
|
-
* ```
|
|
966
|
-
*/
|
|
967
|
-
async deviceStart(request) {
|
|
968
|
-
if (!this.apiKey) {
|
|
969
|
-
throw new ConfigError("API key is required to start device flow");
|
|
970
|
-
}
|
|
971
|
-
const params = new URLSearchParams();
|
|
972
|
-
if (request?.provider) {
|
|
973
|
-
params.set("provider", request.provider);
|
|
974
|
-
}
|
|
975
|
-
const queryString = params.toString();
|
|
976
|
-
const path = queryString ? `/auth/device/start?${queryString}` : "/auth/device/start";
|
|
977
|
-
const apiResp = await this.http.json(path, {
|
|
978
|
-
method: "POST",
|
|
979
|
-
apiKey: this.apiKey
|
|
980
|
-
});
|
|
981
|
-
return {
|
|
982
|
-
deviceCode: apiResp.device_code,
|
|
983
|
-
userCode: apiResp.user_code,
|
|
984
|
-
verificationUri: apiResp.verification_uri,
|
|
985
|
-
verificationUriComplete: apiResp.verification_uri_complete,
|
|
986
|
-
expiresAt: new Date(Date.now() + apiResp.expires_in * 1e3),
|
|
987
|
-
interval: apiResp.interval
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
/**
|
|
991
|
-
* Poll the device token endpoint for authorization completion.
|
|
992
|
-
*
|
|
993
|
-
* Returns a discriminated union:
|
|
994
|
-
* - `{ status: "approved", token }` - User authorized, token available
|
|
995
|
-
* - `{ status: "pending", pending }` - User hasn't authorized yet, keep polling
|
|
996
|
-
* - `{ status: "error", error }` - Authorization failed (expired, denied, etc.)
|
|
997
|
-
*
|
|
998
|
-
* @param deviceCode - The device code from deviceStart()
|
|
999
|
-
*
|
|
1000
|
-
* @example
|
|
1001
|
-
* ```typescript
|
|
1002
|
-
* const auth = await client.auth.deviceStart({ provider: "github" });
|
|
1003
|
-
* console.log(`Go to ${auth.verificationUri} and enter: ${auth.userCode}`);
|
|
1004
|
-
*
|
|
1005
|
-
* let interval = auth.interval;
|
|
1006
|
-
* while (true) {
|
|
1007
|
-
* await sleep(interval * 1000);
|
|
1008
|
-
* const result = await client.auth.deviceToken(auth.deviceCode);
|
|
1009
|
-
*
|
|
1010
|
-
* if (result.status === "approved") {
|
|
1011
|
-
* console.log("Token:", result.token.token);
|
|
1012
|
-
* break;
|
|
1013
|
-
* } else if (result.status === "pending") {
|
|
1014
|
-
* if (result.pending.interval) interval = result.pending.interval;
|
|
1015
|
-
* continue;
|
|
1016
|
-
* } else {
|
|
1017
|
-
* throw new Error(`Authorization failed: ${result.error}`);
|
|
1018
|
-
* }
|
|
1019
|
-
* }
|
|
1020
|
-
* ```
|
|
1021
|
-
*/
|
|
1022
|
-
async deviceToken(deviceCode) {
|
|
1023
|
-
if (!this.apiKey) {
|
|
1024
|
-
throw new ConfigError("API key is required to poll device token");
|
|
1025
|
-
}
|
|
1026
|
-
if (!deviceCode?.trim()) {
|
|
1027
|
-
throw new ConfigError("deviceCode is required");
|
|
1028
|
-
}
|
|
1029
|
-
try {
|
|
1030
|
-
const apiResp = await this.http.json("/auth/device/token", {
|
|
1031
|
-
method: "POST",
|
|
1032
|
-
body: { device_code: deviceCode },
|
|
1033
|
-
apiKey: this.apiKey
|
|
1034
|
-
});
|
|
1035
|
-
return {
|
|
1036
|
-
status: "approved",
|
|
1037
|
-
token: {
|
|
1038
|
-
token: apiResp.token,
|
|
1039
|
-
expiresAt: new Date(apiResp.expires_at),
|
|
1040
|
-
expiresIn: apiResp.expires_in,
|
|
1041
|
-
tokenType: "Bearer",
|
|
1042
|
-
projectId: apiResp.project_id,
|
|
1043
|
-
customerId: apiResp.customer_id,
|
|
1044
|
-
customerExternalId: apiResp.customer_external_id,
|
|
1045
|
-
tierCode: apiResp.tier_code ? asTierCode(apiResp.tier_code) : void 0
|
|
1046
|
-
}
|
|
1047
|
-
};
|
|
1048
|
-
} catch (err) {
|
|
1049
|
-
if (err instanceof APIError && err.status === 400) {
|
|
1050
|
-
const data = err.data;
|
|
1051
|
-
const errorCode = data?.error || err.code || "unknown";
|
|
1052
|
-
if (errorCode === "authorization_pending" || errorCode === "slow_down") {
|
|
1053
|
-
return {
|
|
1054
|
-
status: "pending",
|
|
1055
|
-
pending: {
|
|
1056
|
-
error: errorCode,
|
|
1057
|
-
errorDescription: data?.error_description,
|
|
1058
|
-
interval: data?.interval
|
|
1059
|
-
}
|
|
1060
|
-
};
|
|
1061
|
-
}
|
|
1062
|
-
return {
|
|
1063
|
-
status: "error",
|
|
1064
|
-
error: errorCode,
|
|
1065
|
-
errorDescription: data?.error_description || err.message
|
|
1066
|
-
};
|
|
1067
|
-
}
|
|
1068
|
-
throw err;
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
/**
|
|
1072
|
-
* Start an OAuth flow for customer authentication.
|
|
1073
|
-
*
|
|
1074
|
-
* This initiates the OAuth redirect flow where users authenticate with
|
|
1075
|
-
* GitHub or Google and are redirected back to your application with a
|
|
1076
|
-
* customer token.
|
|
1077
|
-
*
|
|
1078
|
-
* @param request - OAuth start parameters
|
|
1079
|
-
* @param request.projectId - The project ID to authenticate against
|
|
1080
|
-
* @param request.provider - OAuth provider: "github" or "google"
|
|
1081
|
-
* @param request.redirectUri - Where to redirect after OAuth. Must be in project's whitelist.
|
|
1082
|
-
* @returns Promise with the redirect URL
|
|
1083
|
-
*
|
|
1084
|
-
* @example
|
|
1085
|
-
* ```typescript
|
|
1086
|
-
* const { redirectUrl } = await client.auth.oauthStart({
|
|
1087
|
-
* projectId: "your-project-id",
|
|
1088
|
-
* provider: "github",
|
|
1089
|
-
* redirectUri: "https://your-app.com/auth/callback",
|
|
1090
|
-
* });
|
|
1091
|
-
*
|
|
1092
|
-
* // Redirect user to the OAuth provider
|
|
1093
|
-
* window.location.href = redirectUrl;
|
|
1094
|
-
*
|
|
1095
|
-
* // After OAuth, your callback receives a POST with:
|
|
1096
|
-
* // token, token_type, expires_at, expires_in, project_id, customer_id, customer_external_id, tier_code
|
|
1097
|
-
* ```
|
|
1098
|
-
*/
|
|
1099
|
-
async oauthStart(request) {
|
|
1100
|
-
if (!request.projectId?.trim()) {
|
|
1101
|
-
throw new ConfigError("projectId is required");
|
|
1102
|
-
}
|
|
1103
|
-
if (!request.provider?.trim()) {
|
|
1104
|
-
throw new ConfigError("provider is required");
|
|
1105
|
-
}
|
|
1106
|
-
if (!request.redirectUri?.trim()) {
|
|
1107
|
-
throw new ConfigError("redirectUri is required");
|
|
1108
|
-
}
|
|
1109
|
-
const apiResp = await this.http.json(
|
|
1110
|
-
"/auth/customer/oauth/start",
|
|
1111
|
-
{
|
|
1112
|
-
method: "POST",
|
|
1113
|
-
body: {
|
|
1114
|
-
project_id: request.projectId,
|
|
1115
|
-
provider: request.provider,
|
|
1116
|
-
redirect_uri: request.redirectUri
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
);
|
|
1120
|
-
return {
|
|
1121
|
-
redirectUrl: apiResp.redirect_url
|
|
1122
|
-
};
|
|
1123
|
-
}
|
|
1124
743
|
};
|
|
1125
|
-
function normalizeFrontendToken(payload, meta) {
|
|
1126
|
-
return {
|
|
1127
|
-
token: payload.token,
|
|
1128
|
-
expiresAt: new Date(payload.expires_at),
|
|
1129
|
-
expiresIn: payload.expires_in,
|
|
1130
|
-
tokenType: payload.token_type,
|
|
1131
|
-
keyId: payload.key_id,
|
|
1132
|
-
sessionId: payload.session_id,
|
|
1133
|
-
projectId: payload.project_id,
|
|
1134
|
-
customerId: payload.customer_id,
|
|
1135
|
-
customerExternalId: payload.customer_external_id,
|
|
1136
|
-
tierCode: payload.tier_code,
|
|
1137
|
-
publishableKey: meta.publishableKey,
|
|
1138
|
-
deviceId: meta.deviceId,
|
|
1139
|
-
identityProvider: meta.identityProvider,
|
|
1140
|
-
identitySubject: meta.identitySubject
|
|
1141
|
-
};
|
|
1142
|
-
}
|
|
1143
|
-
function isTokenReusable(token) {
|
|
1144
|
-
if (!token.token) {
|
|
1145
|
-
return false;
|
|
1146
|
-
}
|
|
1147
|
-
return token.expiresAt.getTime() - Date.now() > 6e4;
|
|
1148
|
-
}
|
|
1149
744
|
|
|
1150
745
|
// src/tools.ts
|
|
1151
746
|
function createUserMessage(content) {
|
|
@@ -2850,7 +2445,7 @@ var ResponsesClient = class {
|
|
|
2850
2445
|
* import { z } from 'zod';
|
|
2851
2446
|
*
|
|
2852
2447
|
* const review = await client.responses.object({
|
|
2853
|
-
* model: 'claude-sonnet-4-
|
|
2448
|
+
* model: 'claude-sonnet-4-5',
|
|
2854
2449
|
* schema: z.object({
|
|
2855
2450
|
* vulnerabilities: z.array(z.string()),
|
|
2856
2451
|
* riskLevel: z.enum(['low', 'medium', 'high']),
|
|
@@ -2907,7 +2502,7 @@ var ResponsesClient = class {
|
|
|
2907
2502
|
* @example
|
|
2908
2503
|
* ```typescript
|
|
2909
2504
|
* const result = await client.responses.objectWithMetadata({
|
|
2910
|
-
* model: 'claude-sonnet-4-
|
|
2505
|
+
* model: 'claude-sonnet-4-5',
|
|
2911
2506
|
* schema: ReviewSchema,
|
|
2912
2507
|
* prompt: 'Review this code...',
|
|
2913
2508
|
* });
|
|
@@ -3316,7 +2911,6 @@ var ResponsesClient = class {
|
|
|
3316
2911
|
|
|
3317
2912
|
// src/runs_request.ts
|
|
3318
2913
|
var RUNS_PATH = "/runs";
|
|
3319
|
-
var WORKFLOW_V0_SCHEMA_PATH = "/schemas/workflow_v0.schema.json";
|
|
3320
2914
|
var RUN_EVENT_V0_SCHEMA_PATH = "/schemas/run_event_v0.schema.json";
|
|
3321
2915
|
function runByIdPath(runId) {
|
|
3322
2916
|
return `${RUNS_PATH}/${encodeURIComponent(runId)}`;
|
|
@@ -3374,14 +2968,8 @@ function parseOutputName(raw) {
|
|
|
3374
2968
|
|
|
3375
2969
|
// src/runs_types.ts
|
|
3376
2970
|
var WorkflowKinds = {
|
|
3377
|
-
WorkflowV0: "workflow.v0",
|
|
3378
2971
|
WorkflowV1: "workflow.v1"
|
|
3379
2972
|
};
|
|
3380
|
-
var WorkflowNodeTypes = {
|
|
3381
|
-
LLMResponses: "llm.responses",
|
|
3382
|
-
JoinAll: "join.all",
|
|
3383
|
-
TransformJSON: "transform.json"
|
|
3384
|
-
};
|
|
3385
2973
|
var WorkflowNodeTypesV1 = {
|
|
3386
2974
|
LLMResponses: "llm.responses",
|
|
3387
2975
|
RouteSwitch: "route.switch",
|
|
@@ -3770,22 +3358,6 @@ var RunsClient = class {
|
|
|
3770
3358
|
});
|
|
3771
3359
|
return { ...out, run_id: parseRunId(out.run_id), plan_hash: parsePlanHash(out.plan_hash) };
|
|
3772
3360
|
}
|
|
3773
|
-
async schemaV0(options = {}) {
|
|
3774
|
-
const metrics = mergeMetrics(this.metrics, options.metrics);
|
|
3775
|
-
const trace = mergeTrace(this.trace, options.trace);
|
|
3776
|
-
return this.http.json(WORKFLOW_V0_SCHEMA_PATH, {
|
|
3777
|
-
method: "GET",
|
|
3778
|
-
headers: options.headers,
|
|
3779
|
-
signal: options.signal,
|
|
3780
|
-
timeoutMs: options.timeoutMs,
|
|
3781
|
-
connectTimeoutMs: options.connectTimeoutMs,
|
|
3782
|
-
retry: options.retry,
|
|
3783
|
-
metrics,
|
|
3784
|
-
trace,
|
|
3785
|
-
context: { method: "GET", path: WORKFLOW_V0_SCHEMA_PATH },
|
|
3786
|
-
accept: "application/schema+json"
|
|
3787
|
-
});
|
|
3788
|
-
}
|
|
3789
3361
|
async runEventSchemaV0(options = {}) {
|
|
3790
3362
|
const metrics = mergeMetrics(this.metrics, options.metrics);
|
|
3791
3363
|
const trace = mergeTrace(this.trace, options.trace);
|
|
@@ -3960,65 +3532,6 @@ var WorkflowsClient = class {
|
|
|
3960
3532
|
this.metrics = cfg.metrics;
|
|
3961
3533
|
this.trace = cfg.trace;
|
|
3962
3534
|
}
|
|
3963
|
-
async compileV0(spec, options = {}) {
|
|
3964
|
-
const metrics = mergeMetrics(this.metrics, options.metrics);
|
|
3965
|
-
const trace = mergeTrace(this.trace, options.trace);
|
|
3966
|
-
const authHeaders = await this.auth.authForResponses();
|
|
3967
|
-
const headers = { ...options.headers || {} };
|
|
3968
|
-
const customerId = options.customerId?.trim();
|
|
3969
|
-
if (customerId) {
|
|
3970
|
-
headers[CUSTOMER_ID_HEADER] = customerId;
|
|
3971
|
-
}
|
|
3972
|
-
try {
|
|
3973
|
-
const out = await this.http.json(
|
|
3974
|
-
WORKFLOWS_COMPILE_PATH,
|
|
3975
|
-
{
|
|
3976
|
-
method: "POST",
|
|
3977
|
-
headers,
|
|
3978
|
-
body: spec,
|
|
3979
|
-
signal: options.signal,
|
|
3980
|
-
apiKey: authHeaders.apiKey,
|
|
3981
|
-
accessToken: authHeaders.accessToken,
|
|
3982
|
-
timeoutMs: options.timeoutMs,
|
|
3983
|
-
connectTimeoutMs: options.connectTimeoutMs,
|
|
3984
|
-
retry: options.retry,
|
|
3985
|
-
metrics,
|
|
3986
|
-
trace,
|
|
3987
|
-
context: { method: "POST", path: WORKFLOWS_COMPILE_PATH }
|
|
3988
|
-
}
|
|
3989
|
-
);
|
|
3990
|
-
return {
|
|
3991
|
-
ok: true,
|
|
3992
|
-
plan_json: out.plan_json,
|
|
3993
|
-
plan_hash: parsePlanHash(out.plan_hash)
|
|
3994
|
-
};
|
|
3995
|
-
} catch (err) {
|
|
3996
|
-
if (err instanceof WorkflowValidationError) {
|
|
3997
|
-
return { ok: false, error_type: "validation_error", issues: err.issues };
|
|
3998
|
-
}
|
|
3999
|
-
if (err instanceof APIError) {
|
|
4000
|
-
return {
|
|
4001
|
-
ok: false,
|
|
4002
|
-
error_type: "internal_error",
|
|
4003
|
-
status: err.status ?? 0,
|
|
4004
|
-
message: err.message,
|
|
4005
|
-
code: err.code,
|
|
4006
|
-
requestId: err.requestId
|
|
4007
|
-
};
|
|
4008
|
-
}
|
|
4009
|
-
if (err instanceof ModelRelayError && err.category === "api") {
|
|
4010
|
-
return {
|
|
4011
|
-
ok: false,
|
|
4012
|
-
error_type: "internal_error",
|
|
4013
|
-
status: err.status ?? 0,
|
|
4014
|
-
message: err.message,
|
|
4015
|
-
code: err.code,
|
|
4016
|
-
requestId: err.requestId
|
|
4017
|
-
};
|
|
4018
|
-
}
|
|
4019
|
-
throw err;
|
|
4020
|
-
}
|
|
4021
|
-
}
|
|
4022
3535
|
async compileV1(spec, options = {}) {
|
|
4023
3536
|
const metrics = mergeMetrics(this.metrics, options.metrics);
|
|
4024
3537
|
const trace = mergeTrace(this.trace, options.trace);
|
|
@@ -4524,7 +4037,7 @@ var LocalSession = class _LocalSession {
|
|
|
4524
4037
|
const input = await this.buildInput(options);
|
|
4525
4038
|
const tools = mergeTools(this.defaultTools, options.tools);
|
|
4526
4039
|
const spec = {
|
|
4527
|
-
kind: "workflow.
|
|
4040
|
+
kind: "workflow.v1",
|
|
4528
4041
|
name: `session-${this.id}-turn-${this.nextSeq}`,
|
|
4529
4042
|
nodes: [
|
|
4530
4043
|
{
|
|
@@ -4837,21 +4350,34 @@ function mergeTools(defaults, overrides) {
|
|
|
4837
4350
|
}
|
|
4838
4351
|
return Array.from(merged.values());
|
|
4839
4352
|
}
|
|
4353
|
+
function isOutputMessage(item) {
|
|
4354
|
+
return typeof item === "object" && item !== null && "type" in item && typeof item.type === "string";
|
|
4355
|
+
}
|
|
4356
|
+
function isContentPiece(c) {
|
|
4357
|
+
return typeof c === "object" && c !== null && "type" in c && typeof c.type === "string";
|
|
4358
|
+
}
|
|
4359
|
+
function hasOutputArray(obj) {
|
|
4360
|
+
return "output" in obj && Array.isArray(obj.output);
|
|
4361
|
+
}
|
|
4362
|
+
function hasContentArray(obj) {
|
|
4363
|
+
return "content" in obj && Array.isArray(obj.content);
|
|
4364
|
+
}
|
|
4840
4365
|
function extractTextOutput(outputs) {
|
|
4841
4366
|
const result = outputs.result;
|
|
4842
4367
|
if (typeof result === "string") return result;
|
|
4843
4368
|
if (result && typeof result === "object") {
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4369
|
+
if (hasOutputArray(result)) {
|
|
4370
|
+
const textParts = result.output.filter(
|
|
4371
|
+
(item) => isOutputMessage(item) && item.type === "message" && item.role === "assistant"
|
|
4372
|
+
).flatMap(
|
|
4373
|
+
(item) => (item.content || []).filter((c) => isContentPiece(c) && c.type === "text").map((c) => c.text ?? "")
|
|
4374
|
+
).filter((text) => text.length > 0);
|
|
4849
4375
|
if (textParts.length > 0) {
|
|
4850
4376
|
return textParts.join("\n");
|
|
4851
4377
|
}
|
|
4852
4378
|
}
|
|
4853
|
-
if (
|
|
4854
|
-
const textParts =
|
|
4379
|
+
if (hasContentArray(result)) {
|
|
4380
|
+
const textParts = result.content.filter((c) => isContentPiece(c) && c.type === "text").map((c) => c.text ?? "").filter((text) => text.length > 0);
|
|
4855
4381
|
if (textParts.length > 0) {
|
|
4856
4382
|
return textParts.join("\n");
|
|
4857
4383
|
}
|
|
@@ -4883,7 +4409,7 @@ var RemoteSession = class _RemoteSession {
|
|
|
4883
4409
|
this.http = http;
|
|
4884
4410
|
this.id = asSessionId(sessionData.id);
|
|
4885
4411
|
this.metadata = sessionData.metadata;
|
|
4886
|
-
this.
|
|
4412
|
+
this.customerId = sessionData.customer_id || options.customerId;
|
|
4887
4413
|
this.createdAt = new Date(sessionData.created_at);
|
|
4888
4414
|
this.updatedAt = new Date(sessionData.updated_at);
|
|
4889
4415
|
this.toolRegistry = options.toolRegistry;
|
|
@@ -4915,7 +4441,7 @@ var RemoteSession = class _RemoteSession {
|
|
|
4915
4441
|
const response = await http.request("/sessions", {
|
|
4916
4442
|
method: "POST",
|
|
4917
4443
|
body: {
|
|
4918
|
-
|
|
4444
|
+
customer_id: options.customerId,
|
|
4919
4445
|
metadata: options.metadata || {}
|
|
4920
4446
|
}
|
|
4921
4447
|
});
|
|
@@ -4951,7 +4477,7 @@ var RemoteSession = class _RemoteSession {
|
|
|
4951
4477
|
const params = new URLSearchParams();
|
|
4952
4478
|
if (options.limit) params.set("limit", String(options.limit));
|
|
4953
4479
|
if (options.offset) params.set("offset", String(options.offset));
|
|
4954
|
-
if (options.
|
|
4480
|
+
if (options.customerId) params.set("customer_id", options.customerId);
|
|
4955
4481
|
const response = await http.request(
|
|
4956
4482
|
`/sessions${params.toString() ? `?${params.toString()}` : ""}`,
|
|
4957
4483
|
{ method: "GET" }
|
|
@@ -5004,7 +4530,7 @@ var RemoteSession = class _RemoteSession {
|
|
|
5004
4530
|
const input = await this.buildInput(options);
|
|
5005
4531
|
const tools = mergeTools2(this.defaultTools, options.tools);
|
|
5006
4532
|
const spec = {
|
|
5007
|
-
kind: "workflow.
|
|
4533
|
+
kind: "workflow.v1",
|
|
5008
4534
|
name: `session-${this.id}-turn-${this.nextSeq}`,
|
|
5009
4535
|
nodes: [
|
|
5010
4536
|
{
|
|
@@ -5024,7 +4550,7 @@ var RemoteSession = class _RemoteSession {
|
|
|
5024
4550
|
outputs: [{ name: "result", from: "main" }]
|
|
5025
4551
|
};
|
|
5026
4552
|
const run = await this.client.runs.create(spec, {
|
|
5027
|
-
customerId: options.customerId || this.
|
|
4553
|
+
customerId: options.customerId || this.customerId,
|
|
5028
4554
|
sessionId: String(this.id)
|
|
5029
4555
|
});
|
|
5030
4556
|
this.currentRunId = run.run_id;
|
|
@@ -5486,7 +5012,7 @@ var SessionsClient = class {
|
|
|
5486
5012
|
/**
|
|
5487
5013
|
* List remote sessions.
|
|
5488
5014
|
*
|
|
5489
|
-
* @param options - List options (limit, cursor,
|
|
5015
|
+
* @param options - List options (limit, cursor, customerId)
|
|
5490
5016
|
* @returns Paginated list of session summaries
|
|
5491
5017
|
*
|
|
5492
5018
|
* @example
|
|
@@ -5501,13 +5027,13 @@ var SessionsClient = class {
|
|
|
5501
5027
|
return RemoteSession.list(this.modelRelay, {
|
|
5502
5028
|
limit: options.limit,
|
|
5503
5029
|
offset: options.cursor ? parseInt(options.cursor, 10) : void 0,
|
|
5504
|
-
|
|
5030
|
+
customerId: options.customerId
|
|
5505
5031
|
});
|
|
5506
5032
|
}
|
|
5507
5033
|
/**
|
|
5508
5034
|
* Delete a remote session.
|
|
5509
5035
|
*
|
|
5510
|
-
* Requires a secret key
|
|
5036
|
+
* Requires a secret key.
|
|
5511
5037
|
*
|
|
5512
5038
|
* @param sessionId - ID of the session to delete
|
|
5513
5039
|
*
|
|
@@ -5533,11 +5059,12 @@ var TiersClient = class {
|
|
|
5533
5059
|
this.http = http;
|
|
5534
5060
|
this.apiKey = cfg.apiKey ? parseApiKey(cfg.apiKey) : void 0;
|
|
5535
5061
|
this.hasSecretKey = this.apiKey ? isSecretKey(this.apiKey) : false;
|
|
5062
|
+
this.hasAccessToken = !!cfg.accessToken?.trim();
|
|
5536
5063
|
}
|
|
5537
|
-
|
|
5538
|
-
if (!this.apiKey) {
|
|
5064
|
+
ensureAuth() {
|
|
5065
|
+
if (!this.apiKey && !this.hasAccessToken) {
|
|
5539
5066
|
throw new ConfigError(
|
|
5540
|
-
"API key (
|
|
5067
|
+
"API key (mr_sk_*) or bearer token required for tier operations"
|
|
5541
5068
|
);
|
|
5542
5069
|
}
|
|
5543
5070
|
}
|
|
@@ -5552,7 +5079,7 @@ var TiersClient = class {
|
|
|
5552
5079
|
* List all tiers in the project.
|
|
5553
5080
|
*/
|
|
5554
5081
|
async list() {
|
|
5555
|
-
this.
|
|
5082
|
+
this.ensureAuth();
|
|
5556
5083
|
const response = await this.http.json("/tiers", {
|
|
5557
5084
|
method: "GET",
|
|
5558
5085
|
apiKey: this.apiKey
|
|
@@ -5563,7 +5090,7 @@ var TiersClient = class {
|
|
|
5563
5090
|
* Get a tier by ID.
|
|
5564
5091
|
*/
|
|
5565
5092
|
async get(tierId) {
|
|
5566
|
-
this.
|
|
5093
|
+
this.ensureAuth();
|
|
5567
5094
|
if (!tierId?.trim()) {
|
|
5568
5095
|
throw new ConfigError("tierId is required");
|
|
5569
5096
|
}
|
|
@@ -5578,8 +5105,8 @@ var TiersClient = class {
|
|
|
5578
5105
|
*
|
|
5579
5106
|
* This enables users to subscribe before authenticating. Stripe collects
|
|
5580
5107
|
* the customer's email during checkout. After checkout completes, a
|
|
5581
|
-
* customer record is created with the email from Stripe.
|
|
5582
|
-
* can
|
|
5108
|
+
* customer record is created with the email from Stripe. Your backend
|
|
5109
|
+
* can map it to your app user and mint customer tokens as needed.
|
|
5583
5110
|
*
|
|
5584
5111
|
* Requires a secret key (mr_sk_*).
|
|
5585
5112
|
*
|
|
@@ -6022,47 +5549,6 @@ function isReusable(token) {
|
|
|
6022
5549
|
}
|
|
6023
5550
|
return token.expiresAt.getTime() - Date.now() > 6e4;
|
|
6024
5551
|
}
|
|
6025
|
-
var FrontendTokenProvider = class {
|
|
6026
|
-
constructor(cfg) {
|
|
6027
|
-
const publishableKey = parsePublishableKey(cfg.publishableKey);
|
|
6028
|
-
const http = new HTTPClient({
|
|
6029
|
-
baseUrl: cfg.baseUrl || DEFAULT_BASE_URL,
|
|
6030
|
-
fetchImpl: cfg.fetch,
|
|
6031
|
-
clientHeader: cfg.clientHeader || DEFAULT_CLIENT_HEADER,
|
|
6032
|
-
apiKey: publishableKey
|
|
6033
|
-
});
|
|
6034
|
-
this.publishableKey = publishableKey;
|
|
6035
|
-
this.customer = cfg.customer;
|
|
6036
|
-
this.auth = new AuthClient(http, { apiKey: publishableKey, customer: cfg.customer });
|
|
6037
|
-
}
|
|
6038
|
-
async getToken() {
|
|
6039
|
-
if (!this.customer?.provider || !this.customer?.subject) {
|
|
6040
|
-
throw new ConfigError("customer.provider and customer.subject are required");
|
|
6041
|
-
}
|
|
6042
|
-
const reqBase = {
|
|
6043
|
-
publishableKey: this.publishableKey,
|
|
6044
|
-
identityProvider: this.customer.provider,
|
|
6045
|
-
identitySubject: this.customer.subject,
|
|
6046
|
-
deviceId: this.customer.deviceId,
|
|
6047
|
-
ttlSeconds: this.customer.ttlSeconds
|
|
6048
|
-
};
|
|
6049
|
-
let token;
|
|
6050
|
-
if (this.customer.email) {
|
|
6051
|
-
const req = {
|
|
6052
|
-
...reqBase,
|
|
6053
|
-
email: this.customer.email
|
|
6054
|
-
};
|
|
6055
|
-
token = await this.auth.frontendTokenAutoProvision(req);
|
|
6056
|
-
} else {
|
|
6057
|
-
const req = reqBase;
|
|
6058
|
-
token = await this.auth.frontendToken(req);
|
|
6059
|
-
}
|
|
6060
|
-
if (!token.token) {
|
|
6061
|
-
throw new ConfigError("frontend token exchange returned an empty token");
|
|
6062
|
-
}
|
|
6063
|
-
return token.token;
|
|
6064
|
-
}
|
|
6065
|
-
};
|
|
6066
5552
|
var CustomerTokenProvider = class {
|
|
6067
5553
|
constructor(cfg) {
|
|
6068
5554
|
const key = parseSecretKey(cfg.secretKey);
|
|
@@ -6084,242 +5570,6 @@ var CustomerTokenProvider = class {
|
|
|
6084
5570
|
return token.token;
|
|
6085
5571
|
}
|
|
6086
5572
|
};
|
|
6087
|
-
var OIDCExchangeTokenProvider = class {
|
|
6088
|
-
constructor(cfg) {
|
|
6089
|
-
const apiKey = parseApiKey(cfg.apiKey);
|
|
6090
|
-
const http = new HTTPClient({
|
|
6091
|
-
baseUrl: cfg.baseUrl || DEFAULT_BASE_URL,
|
|
6092
|
-
fetchImpl: cfg.fetch,
|
|
6093
|
-
clientHeader: cfg.clientHeader || DEFAULT_CLIENT_HEADER,
|
|
6094
|
-
apiKey
|
|
6095
|
-
});
|
|
6096
|
-
this.auth = new AuthClient(http, { apiKey });
|
|
6097
|
-
this.idTokenProvider = cfg.idTokenProvider;
|
|
6098
|
-
this.request = { idToken: "", projectId: cfg.projectId };
|
|
6099
|
-
}
|
|
6100
|
-
async getToken() {
|
|
6101
|
-
if (this.cached && isReusable(this.cached)) {
|
|
6102
|
-
return this.cached.token;
|
|
6103
|
-
}
|
|
6104
|
-
const idToken = (await this.idTokenProvider())?.trim();
|
|
6105
|
-
if (!idToken) {
|
|
6106
|
-
throw new ConfigError("idTokenProvider returned an empty id_token");
|
|
6107
|
-
}
|
|
6108
|
-
const token = await this.auth.oidcExchange({ ...this.request, idToken });
|
|
6109
|
-
this.cached = token;
|
|
6110
|
-
return token.token;
|
|
6111
|
-
}
|
|
6112
|
-
};
|
|
6113
|
-
|
|
6114
|
-
// src/device_flow.ts
|
|
6115
|
-
async function pollUntil(opts) {
|
|
6116
|
-
let intervalMs = Math.max(1, opts.intervalMs);
|
|
6117
|
-
let attempt = 0;
|
|
6118
|
-
while (true) {
|
|
6119
|
-
if (opts.deadline && Date.now() >= opts.deadline.getTime()) {
|
|
6120
|
-
throw opts.onTimeout?.() ?? new TransportError("polling timed out", { kind: "timeout" });
|
|
6121
|
-
}
|
|
6122
|
-
const result = await opts.poll(attempt);
|
|
6123
|
-
if (result.done) {
|
|
6124
|
-
return result.value;
|
|
6125
|
-
}
|
|
6126
|
-
const delay = Math.max(1, result.retryAfterMs ?? intervalMs);
|
|
6127
|
-
intervalMs = delay;
|
|
6128
|
-
await sleep(delay, opts.signal);
|
|
6129
|
-
attempt += 1;
|
|
6130
|
-
}
|
|
6131
|
-
}
|
|
6132
|
-
async function startOAuthDeviceAuthorization(req) {
|
|
6133
|
-
const deviceAuthorizationEndpoint = req.deviceAuthorizationEndpoint?.trim();
|
|
6134
|
-
if (!deviceAuthorizationEndpoint) {
|
|
6135
|
-
throw new ConfigError("deviceAuthorizationEndpoint is required");
|
|
6136
|
-
}
|
|
6137
|
-
const clientId = req.clientId?.trim();
|
|
6138
|
-
if (!clientId) {
|
|
6139
|
-
throw new ConfigError("clientId is required");
|
|
6140
|
-
}
|
|
6141
|
-
const form = new URLSearchParams();
|
|
6142
|
-
form.set("client_id", clientId);
|
|
6143
|
-
if (req.scope?.trim()) {
|
|
6144
|
-
form.set("scope", req.scope.trim());
|
|
6145
|
-
}
|
|
6146
|
-
if (req.audience?.trim()) {
|
|
6147
|
-
form.set("audience", req.audience.trim());
|
|
6148
|
-
}
|
|
6149
|
-
const payload = await postOAuthForm(deviceAuthorizationEndpoint, form, {
|
|
6150
|
-
fetch: req.fetch,
|
|
6151
|
-
signal: req.signal
|
|
6152
|
-
});
|
|
6153
|
-
const deviceCode = String(payload.device_code || "").trim();
|
|
6154
|
-
const userCode = String(payload.user_code || "").trim();
|
|
6155
|
-
const verificationUri = String(payload.verification_uri || payload.verification_uri_complete || "").trim();
|
|
6156
|
-
const verificationUriComplete = String(payload.verification_uri_complete || "").trim() || void 0;
|
|
6157
|
-
const expiresIn = Number(payload.expires_in || 0);
|
|
6158
|
-
const intervalSeconds = Math.max(1, Number(payload.interval || 5));
|
|
6159
|
-
if (!deviceCode || !userCode || !verificationUri || !expiresIn) {
|
|
6160
|
-
throw new TransportError("oauth device authorization returned an invalid response", {
|
|
6161
|
-
kind: "request",
|
|
6162
|
-
cause: payload
|
|
6163
|
-
});
|
|
6164
|
-
}
|
|
6165
|
-
return {
|
|
6166
|
-
deviceCode,
|
|
6167
|
-
userCode,
|
|
6168
|
-
verificationUri,
|
|
6169
|
-
verificationUriComplete,
|
|
6170
|
-
expiresAt: new Date(Date.now() + expiresIn * 1e3),
|
|
6171
|
-
intervalSeconds
|
|
6172
|
-
};
|
|
6173
|
-
}
|
|
6174
|
-
async function pollOAuthDeviceToken(req) {
|
|
6175
|
-
const tokenEndpoint = req.tokenEndpoint?.trim();
|
|
6176
|
-
if (!tokenEndpoint) {
|
|
6177
|
-
throw new ConfigError("tokenEndpoint is required");
|
|
6178
|
-
}
|
|
6179
|
-
const clientId = req.clientId?.trim();
|
|
6180
|
-
if (!clientId) {
|
|
6181
|
-
throw new ConfigError("clientId is required");
|
|
6182
|
-
}
|
|
6183
|
-
const deviceCode = req.deviceCode?.trim();
|
|
6184
|
-
if (!deviceCode) {
|
|
6185
|
-
throw new ConfigError("deviceCode is required");
|
|
6186
|
-
}
|
|
6187
|
-
const deadline = req.deadline ?? new Date(Date.now() + 10 * 60 * 1e3);
|
|
6188
|
-
let intervalMs = Math.max(1, req.intervalSeconds ?? 5) * 1e3;
|
|
6189
|
-
return pollUntil({
|
|
6190
|
-
intervalMs,
|
|
6191
|
-
deadline,
|
|
6192
|
-
signal: req.signal,
|
|
6193
|
-
onTimeout: () => new TransportError("oauth device flow timed out", { kind: "timeout" }),
|
|
6194
|
-
poll: async () => {
|
|
6195
|
-
const form = new URLSearchParams();
|
|
6196
|
-
form.set("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
|
|
6197
|
-
form.set("device_code", deviceCode);
|
|
6198
|
-
form.set("client_id", clientId);
|
|
6199
|
-
const payload = await postOAuthForm(tokenEndpoint, form, {
|
|
6200
|
-
fetch: req.fetch,
|
|
6201
|
-
signal: req.signal,
|
|
6202
|
-
allowErrorPayload: true
|
|
6203
|
-
});
|
|
6204
|
-
const err = String(payload.error || "").trim();
|
|
6205
|
-
if (err) {
|
|
6206
|
-
switch (err) {
|
|
6207
|
-
case "authorization_pending":
|
|
6208
|
-
return { done: false };
|
|
6209
|
-
case "slow_down":
|
|
6210
|
-
intervalMs += 5e3;
|
|
6211
|
-
return { done: false, retryAfterMs: intervalMs };
|
|
6212
|
-
case "expired_token":
|
|
6213
|
-
case "access_denied":
|
|
6214
|
-
case "invalid_grant":
|
|
6215
|
-
throw new TransportError(`oauth device flow failed: ${err}`, {
|
|
6216
|
-
kind: "request",
|
|
6217
|
-
cause: payload
|
|
6218
|
-
});
|
|
6219
|
-
default:
|
|
6220
|
-
throw new TransportError(`oauth device flow error: ${err}`, {
|
|
6221
|
-
kind: "request",
|
|
6222
|
-
cause: payload
|
|
6223
|
-
});
|
|
6224
|
-
}
|
|
6225
|
-
}
|
|
6226
|
-
const accessToken = String(payload.access_token || "").trim() || void 0;
|
|
6227
|
-
const idToken = String(payload.id_token || "").trim() || void 0;
|
|
6228
|
-
const refreshToken = String(payload.refresh_token || "").trim() || void 0;
|
|
6229
|
-
const tokenType = String(payload.token_type || "").trim() || void 0;
|
|
6230
|
-
const scope = String(payload.scope || "").trim() || void 0;
|
|
6231
|
-
const expiresIn = payload.expires_in !== void 0 ? Number(payload.expires_in) : void 0;
|
|
6232
|
-
const expiresAt = typeof expiresIn === "number" && Number.isFinite(expiresIn) && expiresIn > 0 ? new Date(Date.now() + expiresIn * 1e3) : void 0;
|
|
6233
|
-
if (!accessToken && !idToken) {
|
|
6234
|
-
throw new TransportError("oauth device flow returned an invalid token response", {
|
|
6235
|
-
kind: "request",
|
|
6236
|
-
cause: payload
|
|
6237
|
-
});
|
|
6238
|
-
}
|
|
6239
|
-
return { done: true, value: { accessToken, idToken, refreshToken, tokenType, scope, expiresAt } };
|
|
6240
|
-
}
|
|
6241
|
-
});
|
|
6242
|
-
}
|
|
6243
|
-
async function runOAuthDeviceFlowForIDToken(cfg) {
|
|
6244
|
-
const auth = await startOAuthDeviceAuthorization({
|
|
6245
|
-
deviceAuthorizationEndpoint: cfg.deviceAuthorizationEndpoint,
|
|
6246
|
-
clientId: cfg.clientId,
|
|
6247
|
-
scope: cfg.scope,
|
|
6248
|
-
audience: cfg.audience,
|
|
6249
|
-
fetch: cfg.fetch,
|
|
6250
|
-
signal: cfg.signal
|
|
6251
|
-
});
|
|
6252
|
-
await cfg.onUserCode(auth);
|
|
6253
|
-
const token = await pollOAuthDeviceToken({
|
|
6254
|
-
tokenEndpoint: cfg.tokenEndpoint,
|
|
6255
|
-
clientId: cfg.clientId,
|
|
6256
|
-
deviceCode: auth.deviceCode,
|
|
6257
|
-
intervalSeconds: auth.intervalSeconds,
|
|
6258
|
-
deadline: auth.expiresAt,
|
|
6259
|
-
fetch: cfg.fetch,
|
|
6260
|
-
signal: cfg.signal
|
|
6261
|
-
});
|
|
6262
|
-
if (!token.idToken) {
|
|
6263
|
-
throw new TransportError("oauth device flow did not return an id_token", {
|
|
6264
|
-
kind: "request",
|
|
6265
|
-
cause: token
|
|
6266
|
-
});
|
|
6267
|
-
}
|
|
6268
|
-
return token.idToken;
|
|
6269
|
-
}
|
|
6270
|
-
async function postOAuthForm(url, form, opts) {
|
|
6271
|
-
const fetchFn = opts.fetch ?? globalThis.fetch;
|
|
6272
|
-
if (!fetchFn) {
|
|
6273
|
-
throw new ConfigError("fetch is not available; provide a fetch implementation");
|
|
6274
|
-
}
|
|
6275
|
-
let resp;
|
|
6276
|
-
try {
|
|
6277
|
-
resp = await fetchFn(url, {
|
|
6278
|
-
method: "POST",
|
|
6279
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
6280
|
-
body: form.toString(),
|
|
6281
|
-
signal: opts.signal
|
|
6282
|
-
});
|
|
6283
|
-
} catch (cause) {
|
|
6284
|
-
throw new TransportError("oauth request failed", { kind: "request", cause });
|
|
6285
|
-
}
|
|
6286
|
-
let json;
|
|
6287
|
-
try {
|
|
6288
|
-
json = await resp.json();
|
|
6289
|
-
} catch (cause) {
|
|
6290
|
-
throw new TransportError("oauth response was not valid JSON", { kind: "request", cause });
|
|
6291
|
-
}
|
|
6292
|
-
if (!resp.ok && !opts.allowErrorPayload) {
|
|
6293
|
-
throw new TransportError(`oauth request failed (${resp.status})`, {
|
|
6294
|
-
kind: "request",
|
|
6295
|
-
cause: json
|
|
6296
|
-
});
|
|
6297
|
-
}
|
|
6298
|
-
return json || {};
|
|
6299
|
-
}
|
|
6300
|
-
async function sleep(ms, signal) {
|
|
6301
|
-
if (!ms || ms <= 0) {
|
|
6302
|
-
return;
|
|
6303
|
-
}
|
|
6304
|
-
if (!signal) {
|
|
6305
|
-
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
6306
|
-
return;
|
|
6307
|
-
}
|
|
6308
|
-
if (signal.aborted) {
|
|
6309
|
-
throw new TransportError("oauth device flow aborted", { kind: "request" });
|
|
6310
|
-
}
|
|
6311
|
-
await new Promise((resolve, reject) => {
|
|
6312
|
-
const onAbort = () => {
|
|
6313
|
-
signal.removeEventListener("abort", onAbort);
|
|
6314
|
-
reject(new TransportError("oauth device flow aborted", { kind: "request" }));
|
|
6315
|
-
};
|
|
6316
|
-
signal.addEventListener("abort", onAbort);
|
|
6317
|
-
setTimeout(() => {
|
|
6318
|
-
signal.removeEventListener("abort", onAbort);
|
|
6319
|
-
resolve();
|
|
6320
|
-
}, ms);
|
|
6321
|
-
});
|
|
6322
|
-
}
|
|
6323
5573
|
|
|
6324
5574
|
// src/json_path.ts
|
|
6325
5575
|
var LLMOutputPath = class {
|
|
@@ -6457,9 +5707,6 @@ function transformJSONObject(object) {
|
|
|
6457
5707
|
function transformJSONMerge(merge) {
|
|
6458
5708
|
return { merge: merge.slice() };
|
|
6459
5709
|
}
|
|
6460
|
-
var transformJSONValueV1 = transformJSONValue;
|
|
6461
|
-
var transformJSONObjectV1 = transformJSONObject;
|
|
6462
|
-
var transformJSONMergeV1 = transformJSONMerge;
|
|
6463
5710
|
function wireRequest(req) {
|
|
6464
5711
|
const raw = req;
|
|
6465
5712
|
if (raw && typeof raw === "object") {
|
|
@@ -6513,2142 +5760,191 @@ function validateInputPointer(pointer, input) {
|
|
|
6513
5760
|
}
|
|
6514
5761
|
if (match[2] !== void 0) {
|
|
6515
5762
|
const contentIndex = parseInt(match[2], 10);
|
|
6516
|
-
const msg = input[msgIndex];
|
|
6517
|
-
if (contentIndex >= msg.content.length) {
|
|
6518
|
-
return `targets ${pointer} but message ${msgIndex} only has ${msg.content.length} content blocks (indices 0-${msg.content.length - 1})`;
|
|
6519
|
-
}
|
|
6520
|
-
}
|
|
6521
|
-
return void 0;
|
|
6522
|
-
}
|
|
6523
|
-
function validateMapFanoutInput(nodeId, input) {
|
|
6524
|
-
const subnode = input.subnode;
|
|
6525
|
-
if ((subnode.type === WorkflowNodeTypesV1.LLMResponses || subnode.type === WorkflowNodeTypesV1.RouteSwitch) && subnode.input.bindings && subnode.input.bindings.length > 0) {
|
|
6526
|
-
throw new MapFanoutInputError(nodeId, "map.fanout subnode bindings are not allowed");
|
|
6527
|
-
}
|
|
6528
|
-
if (subnode.type !== WorkflowNodeTypesV1.TransformJSON) {
|
|
6529
|
-
return;
|
|
6530
|
-
}
|
|
6531
|
-
if (input.item_bindings && input.item_bindings.length > 0) {
|
|
6532
|
-
throw new MapFanoutInputError(
|
|
6533
|
-
nodeId,
|
|
6534
|
-
"map.fanout transform.json subnode cannot use item_bindings"
|
|
6535
|
-
);
|
|
6536
|
-
}
|
|
6537
|
-
const hasObject = !!subnode.input.object && Object.keys(subnode.input.object).length > 0;
|
|
6538
|
-
const hasMerge = !!subnode.input.merge && subnode.input.merge.length > 0;
|
|
6539
|
-
if (hasObject === hasMerge) {
|
|
6540
|
-
throw new MapFanoutInputError(
|
|
6541
|
-
nodeId,
|
|
6542
|
-
"map.fanout transform.json must provide exactly one of object or merge"
|
|
6543
|
-
);
|
|
6544
|
-
}
|
|
6545
|
-
if (hasObject) {
|
|
6546
|
-
for (const [key, value] of Object.entries(subnode.input.object ?? {})) {
|
|
6547
|
-
if (!key.trim()) continue;
|
|
6548
|
-
if (String(value.from) !== "item") {
|
|
6549
|
-
throw new MapFanoutInputError(
|
|
6550
|
-
nodeId,
|
|
6551
|
-
`map.fanout transform.json object.${key}.from must be "item"`
|
|
6552
|
-
);
|
|
6553
|
-
}
|
|
6554
|
-
}
|
|
6555
|
-
}
|
|
6556
|
-
if (hasMerge) {
|
|
6557
|
-
for (const [index, value] of (subnode.input.merge ?? []).entries()) {
|
|
6558
|
-
if (String(value.from) !== "item") {
|
|
6559
|
-
throw new MapFanoutInputError(
|
|
6560
|
-
nodeId,
|
|
6561
|
-
`map.fanout transform.json merge[${index}].from must be "item"`
|
|
6562
|
-
);
|
|
6563
|
-
}
|
|
6564
|
-
}
|
|
6565
|
-
}
|
|
6566
|
-
}
|
|
6567
|
-
var WorkflowBuilderV0 = class _WorkflowBuilderV0 {
|
|
6568
|
-
constructor(state = { nodes: [], edges: [], outputs: [] }) {
|
|
6569
|
-
this.state = state;
|
|
6570
|
-
}
|
|
6571
|
-
static new() {
|
|
6572
|
-
return new _WorkflowBuilderV0();
|
|
6573
|
-
}
|
|
6574
|
-
with(patch) {
|
|
6575
|
-
return new _WorkflowBuilderV0({
|
|
6576
|
-
...this.state,
|
|
6577
|
-
...patch
|
|
6578
|
-
});
|
|
6579
|
-
}
|
|
6580
|
-
name(name) {
|
|
6581
|
-
return this.with({ name: name.trim() || void 0 });
|
|
6582
|
-
}
|
|
6583
|
-
execution(execution) {
|
|
6584
|
-
return this.with({ execution });
|
|
6585
|
-
}
|
|
6586
|
-
node(node) {
|
|
6587
|
-
return this.with({ nodes: [...this.state.nodes, node] });
|
|
6588
|
-
}
|
|
6589
|
-
llmResponses(id, request, options = {}) {
|
|
6590
|
-
const wiredRequest = wireRequest(request);
|
|
6591
|
-
if (options.bindings) {
|
|
6592
|
-
validateBindingTargets(id, wiredRequest.input, options.bindings);
|
|
6593
|
-
}
|
|
6594
|
-
const input = {
|
|
6595
|
-
request: wiredRequest,
|
|
6596
|
-
...options.stream === void 0 ? {} : { stream: options.stream },
|
|
6597
|
-
...options.toolExecution === void 0 ? {} : { tool_execution: { mode: options.toolExecution } },
|
|
6598
|
-
...options.toolLimits === void 0 ? {} : { tool_limits: { ...options.toolLimits } },
|
|
6599
|
-
...options.bindings === void 0 ? {} : { bindings: options.bindings.slice() }
|
|
6600
|
-
};
|
|
6601
|
-
return this.node({
|
|
6602
|
-
id,
|
|
6603
|
-
type: WorkflowNodeTypes.LLMResponses,
|
|
6604
|
-
input
|
|
6605
|
-
});
|
|
6606
|
-
}
|
|
6607
|
-
joinAll(id) {
|
|
6608
|
-
return this.node({ id, type: WorkflowNodeTypes.JoinAll });
|
|
6609
|
-
}
|
|
6610
|
-
transformJSON(id, input) {
|
|
6611
|
-
return this.node({ id, type: WorkflowNodeTypes.TransformJSON, input });
|
|
6612
|
-
}
|
|
6613
|
-
edge(from, to) {
|
|
6614
|
-
return this.with({ edges: [...this.state.edges, { from, to }] });
|
|
6615
|
-
}
|
|
6616
|
-
output(name, from, pointer) {
|
|
6617
|
-
return this.with({
|
|
6618
|
-
outputs: [
|
|
6619
|
-
...this.state.outputs,
|
|
6620
|
-
{ name, from, ...pointer ? { pointer } : {} }
|
|
6621
|
-
]
|
|
6622
|
-
});
|
|
6623
|
-
}
|
|
6624
|
-
build() {
|
|
6625
|
-
const edges = this.state.edges.slice().sort((a, b) => {
|
|
6626
|
-
const af = String(a.from);
|
|
6627
|
-
const bf = String(b.from);
|
|
6628
|
-
if (af < bf) return -1;
|
|
6629
|
-
if (af > bf) return 1;
|
|
6630
|
-
const at = String(a.to);
|
|
6631
|
-
const bt = String(b.to);
|
|
6632
|
-
if (at < bt) return -1;
|
|
6633
|
-
if (at > bt) return 1;
|
|
6634
|
-
return 0;
|
|
6635
|
-
});
|
|
6636
|
-
const outputs = this.state.outputs.slice().sort((a, b) => {
|
|
6637
|
-
const an = String(a.name);
|
|
6638
|
-
const bn = String(b.name);
|
|
6639
|
-
if (an < bn) return -1;
|
|
6640
|
-
if (an > bn) return 1;
|
|
6641
|
-
const af = String(a.from);
|
|
6642
|
-
const bf = String(b.from);
|
|
6643
|
-
if (af < bf) return -1;
|
|
6644
|
-
if (af > bf) return 1;
|
|
6645
|
-
const ap = a.pointer ?? "";
|
|
6646
|
-
const bp = b.pointer ?? "";
|
|
6647
|
-
if (ap < bp) return -1;
|
|
6648
|
-
if (ap > bp) return 1;
|
|
6649
|
-
return 0;
|
|
6650
|
-
});
|
|
6651
|
-
return {
|
|
6652
|
-
kind: WorkflowKinds.WorkflowV0,
|
|
6653
|
-
...this.state.name ? { name: this.state.name } : {},
|
|
6654
|
-
...this.state.execution ? { execution: this.state.execution } : {},
|
|
6655
|
-
nodes: this.state.nodes.slice(),
|
|
6656
|
-
...edges.length ? { edges } : {},
|
|
6657
|
-
outputs
|
|
6658
|
-
};
|
|
6659
|
-
}
|
|
6660
|
-
};
|
|
6661
|
-
function workflowV0() {
|
|
6662
|
-
return WorkflowBuilderV0.new();
|
|
6663
|
-
}
|
|
6664
|
-
var WorkflowBuilderV1 = class _WorkflowBuilderV1 {
|
|
6665
|
-
constructor(state = { nodes: [], edges: [], outputs: [] }) {
|
|
6666
|
-
this.state = state;
|
|
6667
|
-
}
|
|
6668
|
-
static new() {
|
|
6669
|
-
return new _WorkflowBuilderV1();
|
|
6670
|
-
}
|
|
6671
|
-
with(patch) {
|
|
6672
|
-
return new _WorkflowBuilderV1({
|
|
6673
|
-
...this.state,
|
|
6674
|
-
...patch
|
|
6675
|
-
});
|
|
6676
|
-
}
|
|
6677
|
-
name(name) {
|
|
6678
|
-
return this.with({ name: name.trim() || void 0 });
|
|
6679
|
-
}
|
|
6680
|
-
execution(execution) {
|
|
6681
|
-
return this.with({ execution });
|
|
6682
|
-
}
|
|
6683
|
-
node(node) {
|
|
6684
|
-
return this.with({ nodes: [...this.state.nodes, node] });
|
|
6685
|
-
}
|
|
6686
|
-
llmResponses(id, request, options = {}) {
|
|
6687
|
-
const wiredRequest = wireRequest(request);
|
|
6688
|
-
if (options.bindings) {
|
|
6689
|
-
validateBindingTargets(id, wiredRequest.input, options.bindings);
|
|
6690
|
-
}
|
|
6691
|
-
const input = {
|
|
6692
|
-
request: wiredRequest,
|
|
6693
|
-
...options.stream === void 0 ? {} : { stream: options.stream },
|
|
6694
|
-
...options.toolExecution === void 0 ? {} : { tool_execution: { mode: options.toolExecution } },
|
|
6695
|
-
...options.toolLimits === void 0 ? {} : { tool_limits: { ...options.toolLimits } },
|
|
6696
|
-
...options.bindings === void 0 ? {} : { bindings: options.bindings.slice() }
|
|
6697
|
-
};
|
|
6698
|
-
return this.node({
|
|
6699
|
-
id,
|
|
6700
|
-
type: WorkflowNodeTypesV1.LLMResponses,
|
|
6701
|
-
input
|
|
6702
|
-
});
|
|
6703
|
-
}
|
|
6704
|
-
routeSwitch(id, request, options = {}) {
|
|
6705
|
-
const wiredRequest = wireRequest(request);
|
|
6706
|
-
if (options.bindings) {
|
|
6707
|
-
validateBindingTargets(id, wiredRequest.input, options.bindings);
|
|
6708
|
-
}
|
|
6709
|
-
const input = {
|
|
6710
|
-
request: wiredRequest,
|
|
6711
|
-
...options.stream === void 0 ? {} : { stream: options.stream },
|
|
6712
|
-
...options.toolExecution === void 0 ? {} : { tool_execution: { mode: options.toolExecution } },
|
|
6713
|
-
...options.toolLimits === void 0 ? {} : { tool_limits: { ...options.toolLimits } },
|
|
6714
|
-
...options.bindings === void 0 ? {} : { bindings: options.bindings.slice() }
|
|
6715
|
-
};
|
|
6716
|
-
return this.node({
|
|
6717
|
-
id,
|
|
6718
|
-
type: WorkflowNodeTypesV1.RouteSwitch,
|
|
6719
|
-
input
|
|
6720
|
-
});
|
|
6721
|
-
}
|
|
6722
|
-
joinAll(id) {
|
|
6723
|
-
return this.node({ id, type: WorkflowNodeTypesV1.JoinAll });
|
|
6724
|
-
}
|
|
6725
|
-
joinAny(id, input) {
|
|
6726
|
-
return this.node({
|
|
6727
|
-
id,
|
|
6728
|
-
type: WorkflowNodeTypesV1.JoinAny,
|
|
6729
|
-
...input ? { input } : {}
|
|
6730
|
-
});
|
|
6731
|
-
}
|
|
6732
|
-
joinCollect(id, input) {
|
|
6733
|
-
return this.node({ id, type: WorkflowNodeTypesV1.JoinCollect, input });
|
|
6734
|
-
}
|
|
6735
|
-
transformJSON(id, input) {
|
|
6736
|
-
return this.node({ id, type: WorkflowNodeTypesV1.TransformJSON, input });
|
|
6737
|
-
}
|
|
6738
|
-
mapFanout(id, input) {
|
|
6739
|
-
validateMapFanoutInput(id, input);
|
|
6740
|
-
return this.node({ id, type: WorkflowNodeTypesV1.MapFanout, input });
|
|
6741
|
-
}
|
|
6742
|
-
edge(from, to, when) {
|
|
6743
|
-
return this.with({
|
|
6744
|
-
edges: [...this.state.edges, { from, to, ...when ? { when } : {} }]
|
|
6745
|
-
});
|
|
6746
|
-
}
|
|
6747
|
-
output(name, from, pointer) {
|
|
6748
|
-
return this.with({
|
|
6749
|
-
outputs: [
|
|
6750
|
-
...this.state.outputs,
|
|
6751
|
-
{ name, from, ...pointer ? { pointer } : {} }
|
|
6752
|
-
]
|
|
6753
|
-
});
|
|
6754
|
-
}
|
|
6755
|
-
build() {
|
|
6756
|
-
const edges = this.state.edges.slice().sort((a, b) => {
|
|
6757
|
-
const af = String(a.from);
|
|
6758
|
-
const bf = String(b.from);
|
|
6759
|
-
if (af < bf) return -1;
|
|
6760
|
-
if (af > bf) return 1;
|
|
6761
|
-
const at = String(a.to);
|
|
6762
|
-
const bt = String(b.to);
|
|
6763
|
-
if (at < bt) return -1;
|
|
6764
|
-
if (at > bt) return 1;
|
|
6765
|
-
const aw = a.when ? JSON.stringify(a.when) : "";
|
|
6766
|
-
const bw = b.when ? JSON.stringify(b.when) : "";
|
|
6767
|
-
if (aw < bw) return -1;
|
|
6768
|
-
if (aw > bw) return 1;
|
|
6769
|
-
return 0;
|
|
6770
|
-
});
|
|
6771
|
-
const outputs = this.state.outputs.slice().sort((a, b) => {
|
|
6772
|
-
const an = String(a.name);
|
|
6773
|
-
const bn = String(b.name);
|
|
6774
|
-
if (an < bn) return -1;
|
|
6775
|
-
if (an > bn) return 1;
|
|
6776
|
-
const af = String(a.from);
|
|
6777
|
-
const bf = String(b.from);
|
|
6778
|
-
if (af < bf) return -1;
|
|
6779
|
-
if (af > bf) return 1;
|
|
6780
|
-
const ap = a.pointer ?? "";
|
|
6781
|
-
const bp = b.pointer ?? "";
|
|
6782
|
-
if (ap < bp) return -1;
|
|
6783
|
-
if (ap > bp) return 1;
|
|
6784
|
-
return 0;
|
|
6785
|
-
});
|
|
6786
|
-
return {
|
|
6787
|
-
kind: WorkflowKinds.WorkflowV1,
|
|
6788
|
-
...this.state.name ? { name: this.state.name } : {},
|
|
6789
|
-
...this.state.execution ? { execution: this.state.execution } : {},
|
|
6790
|
-
nodes: this.state.nodes.slice(),
|
|
6791
|
-
...edges.length ? { edges } : {},
|
|
6792
|
-
outputs
|
|
6793
|
-
};
|
|
6794
|
-
}
|
|
6795
|
-
};
|
|
6796
|
-
function workflowV1() {
|
|
6797
|
-
return WorkflowBuilderV1.new();
|
|
6798
|
-
}
|
|
6799
|
-
var Workflow = class _Workflow {
|
|
6800
|
-
constructor(name) {
|
|
6801
|
-
this._nodes = [];
|
|
6802
|
-
this._edges = /* @__PURE__ */ new Set();
|
|
6803
|
-
this._outputs = [];
|
|
6804
|
-
this._pendingNode = null;
|
|
6805
|
-
this._name = name?.trim() || void 0;
|
|
6806
|
-
}
|
|
6807
|
-
/**
|
|
6808
|
-
* Create a new workflow builder with the given name.
|
|
6809
|
-
*/
|
|
6810
|
-
static create(name) {
|
|
6811
|
-
return new _Workflow(name);
|
|
6812
|
-
}
|
|
6813
|
-
/**
|
|
6814
|
-
* Set the workflow execution configuration.
|
|
6815
|
-
*/
|
|
6816
|
-
execution(exec) {
|
|
6817
|
-
this.flushPendingNode();
|
|
6818
|
-
this._execution = exec;
|
|
6819
|
-
return this;
|
|
6820
|
-
}
|
|
6821
|
-
/**
|
|
6822
|
-
* Add an LLM responses node and return a node builder for configuration.
|
|
6823
|
-
*/
|
|
6824
|
-
addLLMNode(id, request) {
|
|
6825
|
-
this.flushPendingNode();
|
|
6826
|
-
this._pendingNode = {
|
|
6827
|
-
id,
|
|
6828
|
-
request: wireRequest(request),
|
|
6829
|
-
bindings: []
|
|
6830
|
-
};
|
|
6831
|
-
return new LLMNodeBuilder(this);
|
|
6832
|
-
}
|
|
6833
|
-
/**
|
|
6834
|
-
* Add a join.all node that waits for all incoming edges.
|
|
6835
|
-
*/
|
|
6836
|
-
addJoinAllNode(id) {
|
|
6837
|
-
this.flushPendingNode();
|
|
6838
|
-
this._nodes.push({ id, type: WorkflowNodeTypes.JoinAll });
|
|
6839
|
-
return this;
|
|
6840
|
-
}
|
|
6841
|
-
/**
|
|
6842
|
-
* Add a transform.json node and return a builder for configuration.
|
|
6843
|
-
*/
|
|
6844
|
-
addTransformJSONNode(id) {
|
|
6845
|
-
this.flushPendingNode();
|
|
6846
|
-
return new TransformJSONNodeBuilder(this, id);
|
|
6847
|
-
}
|
|
6848
|
-
/**
|
|
6849
|
-
* Add an output reference extracting the full node output.
|
|
6850
|
-
*/
|
|
6851
|
-
output(name, from, pointer) {
|
|
6852
|
-
this.flushPendingNode();
|
|
6853
|
-
this._outputs.push({ name, from, ...pointer ? { pointer } : {} });
|
|
6854
|
-
return this;
|
|
6855
|
-
}
|
|
6856
|
-
/**
|
|
6857
|
-
* Add an output reference extracting text content from an LLM response.
|
|
6858
|
-
* This is a convenience method that uses the LLM_TEXT_OUTPUT pointer.
|
|
6859
|
-
*/
|
|
6860
|
-
outputText(name, from) {
|
|
6861
|
-
return this.output(name, from, LLM_TEXT_OUTPUT);
|
|
6862
|
-
}
|
|
6863
|
-
/**
|
|
6864
|
-
* Explicitly add an edge between nodes.
|
|
6865
|
-
* Note: edges are automatically inferred from bindings, so this is rarely needed.
|
|
6866
|
-
*/
|
|
6867
|
-
edge(from, to) {
|
|
6868
|
-
this.flushPendingNode();
|
|
6869
|
-
this._edges.add(`${from}->${to}`);
|
|
6870
|
-
return this;
|
|
6871
|
-
}
|
|
6872
|
-
/**
|
|
6873
|
-
* Build the workflow specification.
|
|
6874
|
-
*/
|
|
6875
|
-
build() {
|
|
6876
|
-
this.flushPendingNode();
|
|
6877
|
-
const edges = Array.from(this._edges).map((key) => {
|
|
6878
|
-
const [from, to] = key.split("->");
|
|
6879
|
-
return { from, to };
|
|
6880
|
-
}).sort((a, b) => {
|
|
6881
|
-
const af = String(a.from);
|
|
6882
|
-
const bf = String(b.from);
|
|
6883
|
-
if (af < bf) return -1;
|
|
6884
|
-
if (af > bf) return 1;
|
|
6885
|
-
const at = String(a.to);
|
|
6886
|
-
const bt = String(b.to);
|
|
6887
|
-
if (at < bt) return -1;
|
|
6888
|
-
if (at > bt) return 1;
|
|
6889
|
-
return 0;
|
|
6890
|
-
});
|
|
6891
|
-
const outputs = this._outputs.slice().sort((a, b) => {
|
|
6892
|
-
const an = String(a.name);
|
|
6893
|
-
const bn = String(b.name);
|
|
6894
|
-
if (an < bn) return -1;
|
|
6895
|
-
if (an > bn) return 1;
|
|
6896
|
-
const af = String(a.from);
|
|
6897
|
-
const bf = String(b.from);
|
|
6898
|
-
if (af < bf) return -1;
|
|
6899
|
-
if (af > bf) return 1;
|
|
6900
|
-
const ap = a.pointer ?? "";
|
|
6901
|
-
const bp = b.pointer ?? "";
|
|
6902
|
-
if (ap < bp) return -1;
|
|
6903
|
-
if (ap > bp) return 1;
|
|
6904
|
-
return 0;
|
|
6905
|
-
});
|
|
6906
|
-
return {
|
|
6907
|
-
kind: WorkflowKinds.WorkflowV0,
|
|
6908
|
-
...this._name ? { name: this._name } : {},
|
|
6909
|
-
...this._execution ? { execution: this._execution } : {},
|
|
6910
|
-
nodes: this._nodes.slice(),
|
|
6911
|
-
...edges.length ? { edges } : {},
|
|
6912
|
-
outputs
|
|
6913
|
-
};
|
|
6914
|
-
}
|
|
6915
|
-
/** @internal */
|
|
6916
|
-
_getPendingNode() {
|
|
6917
|
-
return this._pendingNode;
|
|
6918
|
-
}
|
|
6919
|
-
/** @internal */
|
|
6920
|
-
_addEdge(from, to) {
|
|
6921
|
-
this._edges.add(`${from}->${to}`);
|
|
6922
|
-
}
|
|
6923
|
-
/** @internal */
|
|
6924
|
-
_addNode(node) {
|
|
6925
|
-
this._nodes.push(node);
|
|
6926
|
-
}
|
|
6927
|
-
flushPendingNode() {
|
|
6928
|
-
const pending = this._pendingNode;
|
|
6929
|
-
if (!pending) return;
|
|
6930
|
-
this._pendingNode = null;
|
|
6931
|
-
if (pending.bindings.length > 0) {
|
|
6932
|
-
validateBindingTargets(pending.id, pending.request.input, pending.bindings);
|
|
6933
|
-
}
|
|
6934
|
-
const input = {
|
|
6935
|
-
id: pending.id,
|
|
6936
|
-
type: WorkflowNodeTypes.LLMResponses,
|
|
6937
|
-
input: {
|
|
6938
|
-
request: pending.request,
|
|
6939
|
-
...pending.stream !== void 0 ? { stream: pending.stream } : {},
|
|
6940
|
-
...pending.toolExecution ? { tool_execution: { mode: pending.toolExecution } } : {},
|
|
6941
|
-
...pending.toolLimits ? { tool_limits: pending.toolLimits } : {},
|
|
6942
|
-
...pending.bindings.length ? { bindings: pending.bindings } : {}
|
|
6943
|
-
}
|
|
6944
|
-
};
|
|
6945
|
-
this._nodes.push(input);
|
|
6946
|
-
for (const binding of pending.bindings) {
|
|
6947
|
-
this._edges.add(`${binding.from}->${pending.id}`);
|
|
6948
|
-
}
|
|
6949
|
-
}
|
|
6950
|
-
};
|
|
6951
|
-
var LLMNodeBuilder = class {
|
|
6952
|
-
constructor(workflow) {
|
|
6953
|
-
this.workflow = workflow;
|
|
6954
|
-
}
|
|
6955
|
-
/**
|
|
6956
|
-
* Enable or disable streaming for this node.
|
|
6957
|
-
*/
|
|
6958
|
-
stream(enabled) {
|
|
6959
|
-
const pending = this.workflow._getPendingNode();
|
|
6960
|
-
if (pending) {
|
|
6961
|
-
pending.stream = enabled;
|
|
6962
|
-
}
|
|
6963
|
-
return this;
|
|
6964
|
-
}
|
|
6965
|
-
/**
|
|
6966
|
-
* Add a binding from another LLM node's text output to this node's user message.
|
|
6967
|
-
* This is the most common binding pattern: LLM text → user message with json_string encoding.
|
|
6968
|
-
* The edge from the source node is automatically inferred.
|
|
6969
|
-
*/
|
|
6970
|
-
bindTextFrom(from) {
|
|
6971
|
-
return this.bindFromTo(from, LLM_TEXT_OUTPUT, LLM_USER_MESSAGE_TEXT, "json_string");
|
|
6972
|
-
}
|
|
6973
|
-
/**
|
|
6974
|
-
* Add a binding from another node's output to this node's user message text.
|
|
6975
|
-
* Use bindTextFrom for the common case of binding LLM text output.
|
|
6976
|
-
* The edge from the source node is automatically inferred.
|
|
6977
|
-
*/
|
|
6978
|
-
bindFrom(from, pointer) {
|
|
6979
|
-
return this.bindFromTo(from, pointer, LLM_USER_MESSAGE_TEXT, "json_string");
|
|
6980
|
-
}
|
|
6981
|
-
/**
|
|
6982
|
-
* Add a full binding with explicit source/destination pointers and encoding.
|
|
6983
|
-
* The edge from the source node is automatically inferred.
|
|
6984
|
-
*/
|
|
6985
|
-
bindFromTo(from, fromPointer, toPointer, encoding) {
|
|
6986
|
-
const pending = this.workflow._getPendingNode();
|
|
6987
|
-
if (pending) {
|
|
6988
|
-
pending.bindings.push({
|
|
6989
|
-
from,
|
|
6990
|
-
...fromPointer ? { pointer: fromPointer } : {},
|
|
6991
|
-
to: toPointer,
|
|
6992
|
-
...encoding ? { encoding } : {}
|
|
6993
|
-
});
|
|
6994
|
-
}
|
|
6995
|
-
return this;
|
|
6996
|
-
}
|
|
6997
|
-
/**
|
|
6998
|
-
* Add a binding that replaces a {{placeholder}} in the prompt text.
|
|
6999
|
-
* This is useful when the prompt contains placeholder markers like {{tier_data}}.
|
|
7000
|
-
* The edge from the source node is automatically inferred.
|
|
7001
|
-
*/
|
|
7002
|
-
bindToPlaceholder(from, fromPointer, placeholder) {
|
|
7003
|
-
const pending = this.workflow._getPendingNode();
|
|
7004
|
-
if (pending) {
|
|
7005
|
-
pending.bindings.push({
|
|
7006
|
-
from,
|
|
7007
|
-
...fromPointer ? { pointer: fromPointer } : {},
|
|
7008
|
-
to_placeholder: placeholder,
|
|
7009
|
-
encoding: "json_string"
|
|
7010
|
-
});
|
|
7011
|
-
}
|
|
7012
|
-
return this;
|
|
7013
|
-
}
|
|
7014
|
-
/**
|
|
7015
|
-
* Add a binding from an LLM node's text output to a placeholder.
|
|
7016
|
-
* This is the most common placeholder binding: LLM text → {{placeholder}}.
|
|
7017
|
-
* The edge from the source node is automatically inferred.
|
|
7018
|
-
*/
|
|
7019
|
-
bindTextToPlaceholder(from, placeholder) {
|
|
7020
|
-
return this.bindToPlaceholder(from, LLM_TEXT_OUTPUT, placeholder);
|
|
7021
|
-
}
|
|
7022
|
-
/**
|
|
7023
|
-
* Set the tool execution mode (server or client).
|
|
7024
|
-
*/
|
|
7025
|
-
toolExecution(mode) {
|
|
7026
|
-
const pending = this.workflow._getPendingNode();
|
|
7027
|
-
if (pending) {
|
|
7028
|
-
pending.toolExecution = mode;
|
|
7029
|
-
}
|
|
7030
|
-
return this;
|
|
7031
|
-
}
|
|
7032
|
-
/**
|
|
7033
|
-
* Set the tool execution limits.
|
|
7034
|
-
*/
|
|
7035
|
-
toolLimits(limits) {
|
|
7036
|
-
const pending = this.workflow._getPendingNode();
|
|
7037
|
-
if (pending) {
|
|
7038
|
-
pending.toolLimits = limits;
|
|
7039
|
-
}
|
|
7040
|
-
return this;
|
|
7041
|
-
}
|
|
7042
|
-
// Workflow methods for chaining back
|
|
7043
|
-
addLLMNode(id, request) {
|
|
7044
|
-
return this.workflow.addLLMNode(id, request);
|
|
7045
|
-
}
|
|
7046
|
-
addJoinAllNode(id) {
|
|
7047
|
-
return this.workflow.addJoinAllNode(id);
|
|
7048
|
-
}
|
|
7049
|
-
addTransformJSONNode(id) {
|
|
7050
|
-
return this.workflow.addTransformJSONNode(id);
|
|
7051
|
-
}
|
|
7052
|
-
edge(from, to) {
|
|
7053
|
-
return this.workflow.edge(from, to);
|
|
7054
|
-
}
|
|
7055
|
-
output(name, from, pointer) {
|
|
7056
|
-
return this.workflow.output(name, from, pointer);
|
|
7057
|
-
}
|
|
7058
|
-
outputText(name, from) {
|
|
7059
|
-
return this.workflow.outputText(name, from);
|
|
7060
|
-
}
|
|
7061
|
-
execution(exec) {
|
|
7062
|
-
return this.workflow.execution(exec);
|
|
7063
|
-
}
|
|
7064
|
-
build() {
|
|
7065
|
-
return this.workflow.build();
|
|
7066
|
-
}
|
|
7067
|
-
};
|
|
7068
|
-
var TransformJSONNodeBuilder = class {
|
|
7069
|
-
constructor(workflow, id) {
|
|
7070
|
-
this.workflow = workflow;
|
|
7071
|
-
this.id = id;
|
|
7072
|
-
}
|
|
7073
|
-
/**
|
|
7074
|
-
* Set the object transformation with field mappings.
|
|
7075
|
-
*/
|
|
7076
|
-
object(fields) {
|
|
7077
|
-
this._object = fields;
|
|
7078
|
-
return this;
|
|
7079
|
-
}
|
|
7080
|
-
/**
|
|
7081
|
-
* Set the merge transformation with source references.
|
|
7082
|
-
*/
|
|
7083
|
-
merge(items) {
|
|
7084
|
-
this._merge = items;
|
|
7085
|
-
return this;
|
|
7086
|
-
}
|
|
7087
|
-
finalize() {
|
|
7088
|
-
const input = {};
|
|
7089
|
-
if (this._object) input.object = this._object;
|
|
7090
|
-
if (this._merge) input.merge = this._merge;
|
|
7091
|
-
this.workflow._addNode({
|
|
7092
|
-
id: this.id,
|
|
7093
|
-
type: WorkflowNodeTypes.TransformJSON,
|
|
7094
|
-
input
|
|
7095
|
-
});
|
|
7096
|
-
if (this._object) {
|
|
7097
|
-
for (const ref of Object.values(this._object)) {
|
|
7098
|
-
this.workflow._addEdge(ref.from, this.id);
|
|
7099
|
-
}
|
|
7100
|
-
}
|
|
7101
|
-
if (this._merge) {
|
|
7102
|
-
for (const ref of this._merge) {
|
|
7103
|
-
this.workflow._addEdge(ref.from, this.id);
|
|
7104
|
-
}
|
|
7105
|
-
}
|
|
7106
|
-
}
|
|
7107
|
-
// Workflow methods for chaining back
|
|
7108
|
-
addLLMNode(id, request) {
|
|
7109
|
-
this.finalize();
|
|
7110
|
-
return this.workflow.addLLMNode(id, request);
|
|
7111
|
-
}
|
|
7112
|
-
addJoinAllNode(id) {
|
|
7113
|
-
this.finalize();
|
|
7114
|
-
return this.workflow.addJoinAllNode(id);
|
|
7115
|
-
}
|
|
7116
|
-
edge(from, to) {
|
|
7117
|
-
this.finalize();
|
|
7118
|
-
return this.workflow.edge(from, to);
|
|
7119
|
-
}
|
|
7120
|
-
output(name, from, pointer) {
|
|
7121
|
-
this.finalize();
|
|
7122
|
-
return this.workflow.output(name, from, pointer);
|
|
7123
|
-
}
|
|
7124
|
-
execution(exec) {
|
|
7125
|
-
this.finalize();
|
|
7126
|
-
return this.workflow.execution(exec);
|
|
7127
|
-
}
|
|
7128
|
-
build() {
|
|
7129
|
-
this.finalize();
|
|
7130
|
-
return this.workflow.build();
|
|
7131
|
-
}
|
|
7132
|
-
};
|
|
7133
|
-
function newWorkflow(name) {
|
|
7134
|
-
return Workflow.create(name);
|
|
7135
|
-
}
|
|
7136
|
-
|
|
7137
|
-
// src/workflow_v0.schema.json
|
|
7138
|
-
var workflow_v0_schema_default = {
|
|
7139
|
-
$id: "https://modelrelay.ai/schemas/workflow_v0.schema.json",
|
|
7140
|
-
$schema: "http://json-schema.org/draft-07/schema#",
|
|
7141
|
-
additionalProperties: false,
|
|
7142
|
-
definitions: {
|
|
7143
|
-
edge: {
|
|
7144
|
-
additionalProperties: false,
|
|
7145
|
-
properties: {
|
|
7146
|
-
from: {
|
|
7147
|
-
minLength: 1,
|
|
7148
|
-
type: "string"
|
|
7149
|
-
},
|
|
7150
|
-
to: {
|
|
7151
|
-
minLength: 1,
|
|
7152
|
-
type: "string"
|
|
7153
|
-
}
|
|
7154
|
-
},
|
|
7155
|
-
required: [
|
|
7156
|
-
"from",
|
|
7157
|
-
"to"
|
|
7158
|
-
],
|
|
7159
|
-
type: "object"
|
|
7160
|
-
},
|
|
7161
|
-
llmResponsesBinding: {
|
|
7162
|
-
additionalProperties: false,
|
|
7163
|
-
oneOf: [
|
|
7164
|
-
{
|
|
7165
|
-
required: [
|
|
7166
|
-
"to"
|
|
7167
|
-
]
|
|
7168
|
-
},
|
|
7169
|
-
{
|
|
7170
|
-
required: [
|
|
7171
|
-
"to_placeholder"
|
|
7172
|
-
]
|
|
7173
|
-
}
|
|
7174
|
-
],
|
|
7175
|
-
properties: {
|
|
7176
|
-
encoding: {
|
|
7177
|
-
enum: [
|
|
7178
|
-
"json",
|
|
7179
|
-
"json_string"
|
|
7180
|
-
],
|
|
7181
|
-
type: "string"
|
|
7182
|
-
},
|
|
7183
|
-
from: {
|
|
7184
|
-
minLength: 1,
|
|
7185
|
-
type: "string"
|
|
7186
|
-
},
|
|
7187
|
-
pointer: {
|
|
7188
|
-
pattern: "^(/.*)?$",
|
|
7189
|
-
type: "string"
|
|
7190
|
-
},
|
|
7191
|
-
to: {
|
|
7192
|
-
pattern: "^/.*$",
|
|
7193
|
-
type: "string"
|
|
7194
|
-
},
|
|
7195
|
-
to_placeholder: {
|
|
7196
|
-
minLength: 1,
|
|
7197
|
-
type: "string"
|
|
7198
|
-
}
|
|
7199
|
-
},
|
|
7200
|
-
required: [
|
|
7201
|
-
"from"
|
|
7202
|
-
],
|
|
7203
|
-
type: "object"
|
|
7204
|
-
},
|
|
7205
|
-
node: {
|
|
7206
|
-
additionalProperties: false,
|
|
7207
|
-
oneOf: [
|
|
7208
|
-
{
|
|
7209
|
-
allOf: [
|
|
7210
|
-
{
|
|
7211
|
-
properties: {
|
|
7212
|
-
input: {
|
|
7213
|
-
properties: {
|
|
7214
|
-
bindings: {
|
|
7215
|
-
items: {
|
|
7216
|
-
$ref: "#/definitions/llmResponsesBinding"
|
|
7217
|
-
},
|
|
7218
|
-
type: "array"
|
|
7219
|
-
},
|
|
7220
|
-
request: {
|
|
7221
|
-
type: "object"
|
|
7222
|
-
},
|
|
7223
|
-
stream: {
|
|
7224
|
-
type: "boolean"
|
|
7225
|
-
},
|
|
7226
|
-
tool_execution: {
|
|
7227
|
-
additionalProperties: false,
|
|
7228
|
-
properties: {
|
|
7229
|
-
mode: {
|
|
7230
|
-
default: "server",
|
|
7231
|
-
enum: [
|
|
7232
|
-
"server",
|
|
7233
|
-
"client"
|
|
7234
|
-
],
|
|
7235
|
-
type: "string"
|
|
7236
|
-
}
|
|
7237
|
-
},
|
|
7238
|
-
required: [
|
|
7239
|
-
"mode"
|
|
7240
|
-
],
|
|
7241
|
-
type: "object"
|
|
7242
|
-
},
|
|
7243
|
-
tool_limits: {
|
|
7244
|
-
additionalProperties: false,
|
|
7245
|
-
properties: {
|
|
7246
|
-
max_llm_calls: {
|
|
7247
|
-
default: 8,
|
|
7248
|
-
maximum: 64,
|
|
7249
|
-
minimum: 1,
|
|
7250
|
-
type: "integer"
|
|
7251
|
-
},
|
|
7252
|
-
max_tool_calls_per_step: {
|
|
7253
|
-
default: 16,
|
|
7254
|
-
maximum: 64,
|
|
7255
|
-
minimum: 1,
|
|
7256
|
-
type: "integer"
|
|
7257
|
-
},
|
|
7258
|
-
wait_ttl_ms: {
|
|
7259
|
-
default: 9e5,
|
|
7260
|
-
maximum: 864e5,
|
|
7261
|
-
minimum: 1,
|
|
7262
|
-
type: "integer"
|
|
7263
|
-
}
|
|
7264
|
-
},
|
|
7265
|
-
type: "object"
|
|
7266
|
-
}
|
|
7267
|
-
},
|
|
7268
|
-
required: [
|
|
7269
|
-
"request"
|
|
7270
|
-
],
|
|
7271
|
-
type: "object"
|
|
7272
|
-
}
|
|
7273
|
-
}
|
|
7274
|
-
}
|
|
7275
|
-
],
|
|
7276
|
-
properties: {
|
|
7277
|
-
type: {
|
|
7278
|
-
const: "llm.responses"
|
|
7279
|
-
}
|
|
7280
|
-
},
|
|
7281
|
-
required: [
|
|
7282
|
-
"input"
|
|
7283
|
-
]
|
|
7284
|
-
},
|
|
7285
|
-
{
|
|
7286
|
-
properties: {
|
|
7287
|
-
type: {
|
|
7288
|
-
const: "join.all"
|
|
7289
|
-
}
|
|
7290
|
-
}
|
|
7291
|
-
},
|
|
7292
|
-
{
|
|
7293
|
-
allOf: [
|
|
7294
|
-
{
|
|
7295
|
-
properties: {
|
|
7296
|
-
input: {
|
|
7297
|
-
additionalProperties: false,
|
|
7298
|
-
oneOf: [
|
|
7299
|
-
{
|
|
7300
|
-
not: {
|
|
7301
|
-
required: [
|
|
7302
|
-
"merge"
|
|
7303
|
-
]
|
|
7304
|
-
},
|
|
7305
|
-
required: [
|
|
7306
|
-
"object"
|
|
7307
|
-
]
|
|
7308
|
-
},
|
|
7309
|
-
{
|
|
7310
|
-
not: {
|
|
7311
|
-
required: [
|
|
7312
|
-
"object"
|
|
7313
|
-
]
|
|
7314
|
-
},
|
|
7315
|
-
required: [
|
|
7316
|
-
"merge"
|
|
7317
|
-
]
|
|
7318
|
-
}
|
|
7319
|
-
],
|
|
7320
|
-
properties: {
|
|
7321
|
-
merge: {
|
|
7322
|
-
items: {
|
|
7323
|
-
$ref: "#/definitions/transformValue"
|
|
7324
|
-
},
|
|
7325
|
-
minItems: 1,
|
|
7326
|
-
type: "array"
|
|
7327
|
-
},
|
|
7328
|
-
object: {
|
|
7329
|
-
additionalProperties: {
|
|
7330
|
-
$ref: "#/definitions/transformValue"
|
|
7331
|
-
},
|
|
7332
|
-
minProperties: 1,
|
|
7333
|
-
type: "object"
|
|
7334
|
-
}
|
|
7335
|
-
},
|
|
7336
|
-
type: "object"
|
|
7337
|
-
}
|
|
7338
|
-
}
|
|
7339
|
-
}
|
|
7340
|
-
],
|
|
7341
|
-
properties: {
|
|
7342
|
-
type: {
|
|
7343
|
-
const: "transform.json"
|
|
7344
|
-
}
|
|
7345
|
-
},
|
|
7346
|
-
required: [
|
|
7347
|
-
"input"
|
|
7348
|
-
]
|
|
7349
|
-
}
|
|
7350
|
-
],
|
|
7351
|
-
properties: {
|
|
7352
|
-
id: {
|
|
7353
|
-
minLength: 1,
|
|
7354
|
-
type: "string"
|
|
7355
|
-
},
|
|
7356
|
-
input: {},
|
|
7357
|
-
type: {
|
|
7358
|
-
enum: [
|
|
7359
|
-
"llm.responses",
|
|
7360
|
-
"join.all",
|
|
7361
|
-
"transform.json"
|
|
7362
|
-
],
|
|
7363
|
-
type: "string"
|
|
7364
|
-
}
|
|
7365
|
-
},
|
|
7366
|
-
required: [
|
|
7367
|
-
"id",
|
|
7368
|
-
"type"
|
|
7369
|
-
],
|
|
7370
|
-
type: "object"
|
|
7371
|
-
},
|
|
7372
|
-
output: {
|
|
7373
|
-
additionalProperties: false,
|
|
7374
|
-
properties: {
|
|
7375
|
-
from: {
|
|
7376
|
-
minLength: 1,
|
|
7377
|
-
type: "string"
|
|
7378
|
-
},
|
|
7379
|
-
name: {
|
|
7380
|
-
minLength: 1,
|
|
7381
|
-
type: "string"
|
|
7382
|
-
},
|
|
7383
|
-
pointer: {
|
|
7384
|
-
pattern: "^(/.*)?$",
|
|
7385
|
-
type: "string"
|
|
7386
|
-
}
|
|
7387
|
-
},
|
|
7388
|
-
required: [
|
|
7389
|
-
"name",
|
|
7390
|
-
"from"
|
|
7391
|
-
],
|
|
7392
|
-
type: "object"
|
|
7393
|
-
},
|
|
7394
|
-
transformValue: {
|
|
7395
|
-
additionalProperties: false,
|
|
7396
|
-
properties: {
|
|
7397
|
-
from: {
|
|
7398
|
-
minLength: 1,
|
|
7399
|
-
type: "string"
|
|
7400
|
-
},
|
|
7401
|
-
pointer: {
|
|
7402
|
-
pattern: "^(/.*)?$",
|
|
7403
|
-
type: "string"
|
|
7404
|
-
}
|
|
7405
|
-
},
|
|
7406
|
-
required: [
|
|
7407
|
-
"from"
|
|
7408
|
-
],
|
|
7409
|
-
type: "object"
|
|
7410
|
-
}
|
|
7411
|
-
},
|
|
7412
|
-
properties: {
|
|
7413
|
-
edges: {
|
|
7414
|
-
items: {
|
|
7415
|
-
$ref: "#/definitions/edge"
|
|
7416
|
-
},
|
|
7417
|
-
type: "array"
|
|
7418
|
-
},
|
|
7419
|
-
execution: {
|
|
7420
|
-
additionalProperties: false,
|
|
7421
|
-
properties: {
|
|
7422
|
-
max_parallelism: {
|
|
7423
|
-
minimum: 1,
|
|
7424
|
-
type: "integer"
|
|
7425
|
-
},
|
|
7426
|
-
node_timeout_ms: {
|
|
7427
|
-
minimum: 1,
|
|
7428
|
-
type: "integer"
|
|
7429
|
-
},
|
|
7430
|
-
run_timeout_ms: {
|
|
7431
|
-
minimum: 1,
|
|
7432
|
-
type: "integer"
|
|
7433
|
-
}
|
|
7434
|
-
},
|
|
7435
|
-
type: "object"
|
|
7436
|
-
},
|
|
7437
|
-
kind: {
|
|
7438
|
-
const: "workflow.v0",
|
|
7439
|
-
type: "string"
|
|
7440
|
-
},
|
|
7441
|
-
name: {
|
|
7442
|
-
type: "string"
|
|
7443
|
-
},
|
|
7444
|
-
nodes: {
|
|
7445
|
-
items: {
|
|
7446
|
-
$ref: "#/definitions/node"
|
|
7447
|
-
},
|
|
7448
|
-
minItems: 1,
|
|
7449
|
-
type: "array"
|
|
7450
|
-
},
|
|
7451
|
-
outputs: {
|
|
7452
|
-
items: {
|
|
7453
|
-
$ref: "#/definitions/output"
|
|
7454
|
-
},
|
|
7455
|
-
minItems: 1,
|
|
7456
|
-
type: "array"
|
|
7457
|
-
}
|
|
7458
|
-
},
|
|
7459
|
-
required: [
|
|
7460
|
-
"kind",
|
|
7461
|
-
"nodes",
|
|
7462
|
-
"outputs"
|
|
7463
|
-
],
|
|
7464
|
-
title: "ModelRelay workflow.v0",
|
|
7465
|
-
type: "object"
|
|
7466
|
-
};
|
|
7467
|
-
|
|
7468
|
-
// src/workflow_v1.schema.json
|
|
7469
|
-
var workflow_v1_schema_default = {
|
|
7470
|
-
$id: "https://modelrelay.ai/schemas/workflow_v1.schema.json",
|
|
7471
|
-
$schema: "http://json-schema.org/draft-07/schema#",
|
|
7472
|
-
additionalProperties: false,
|
|
7473
|
-
definitions: {
|
|
7474
|
-
condition: {
|
|
7475
|
-
additionalProperties: false,
|
|
7476
|
-
properties: {
|
|
7477
|
-
op: {
|
|
7478
|
-
enum: [
|
|
7479
|
-
"equals",
|
|
7480
|
-
"matches",
|
|
7481
|
-
"exists"
|
|
7482
|
-
],
|
|
7483
|
-
type: "string"
|
|
7484
|
-
},
|
|
7485
|
-
path: {
|
|
7486
|
-
pattern: "^\\$.*$",
|
|
7487
|
-
type: "string"
|
|
7488
|
-
},
|
|
7489
|
-
source: {
|
|
7490
|
-
enum: [
|
|
7491
|
-
"node_output",
|
|
7492
|
-
"node_status"
|
|
7493
|
-
],
|
|
7494
|
-
type: "string"
|
|
7495
|
-
},
|
|
7496
|
-
value: {}
|
|
7497
|
-
},
|
|
7498
|
-
required: [
|
|
7499
|
-
"source",
|
|
7500
|
-
"op"
|
|
7501
|
-
],
|
|
7502
|
-
type: "object"
|
|
7503
|
-
},
|
|
7504
|
-
edge: {
|
|
7505
|
-
additionalProperties: false,
|
|
7506
|
-
properties: {
|
|
7507
|
-
from: {
|
|
7508
|
-
minLength: 1,
|
|
7509
|
-
type: "string"
|
|
7510
|
-
},
|
|
7511
|
-
to: {
|
|
7512
|
-
minLength: 1,
|
|
7513
|
-
type: "string"
|
|
7514
|
-
},
|
|
7515
|
-
when: {
|
|
7516
|
-
$ref: "#/definitions/condition"
|
|
7517
|
-
}
|
|
7518
|
-
},
|
|
7519
|
-
required: [
|
|
7520
|
-
"from",
|
|
7521
|
-
"to"
|
|
7522
|
-
],
|
|
7523
|
-
type: "object"
|
|
7524
|
-
},
|
|
7525
|
-
fragmentBindInput: {
|
|
7526
|
-
additionalProperties: false,
|
|
7527
|
-
oneOf: [
|
|
7528
|
-
{
|
|
7529
|
-
required: [
|
|
7530
|
-
"from_node"
|
|
7531
|
-
]
|
|
7532
|
-
},
|
|
7533
|
-
{
|
|
7534
|
-
required: [
|
|
7535
|
-
"from_input"
|
|
7536
|
-
]
|
|
7537
|
-
}
|
|
7538
|
-
],
|
|
7539
|
-
properties: {
|
|
7540
|
-
from_input: {
|
|
7541
|
-
minLength: 1,
|
|
7542
|
-
type: "string"
|
|
7543
|
-
},
|
|
7544
|
-
from_node: {
|
|
7545
|
-
minLength: 1,
|
|
7546
|
-
type: "string"
|
|
7547
|
-
},
|
|
7548
|
-
pointer: {
|
|
7549
|
-
pattern: "^(/.*)?$",
|
|
7550
|
-
type: "string"
|
|
7551
|
-
}
|
|
7552
|
-
},
|
|
7553
|
-
type: "object"
|
|
7554
|
-
},
|
|
7555
|
-
fragmentDef: {
|
|
7556
|
-
additionalProperties: false,
|
|
7557
|
-
properties: {
|
|
7558
|
-
edges: {
|
|
7559
|
-
items: {
|
|
7560
|
-
$ref: "#/definitions/edge"
|
|
7561
|
-
},
|
|
7562
|
-
type: "array"
|
|
7563
|
-
},
|
|
7564
|
-
inputs: {
|
|
7565
|
-
items: {
|
|
7566
|
-
$ref: "#/definitions/fragmentInput"
|
|
7567
|
-
},
|
|
7568
|
-
type: "array"
|
|
7569
|
-
},
|
|
7570
|
-
nodes: {
|
|
7571
|
-
items: {
|
|
7572
|
-
$ref: "#/definitions/node"
|
|
7573
|
-
},
|
|
7574
|
-
minItems: 1,
|
|
7575
|
-
type: "array"
|
|
7576
|
-
},
|
|
7577
|
-
outputs: {
|
|
7578
|
-
items: {
|
|
7579
|
-
$ref: "#/definitions/fragmentOutput"
|
|
7580
|
-
},
|
|
7581
|
-
minItems: 1,
|
|
7582
|
-
type: "array"
|
|
7583
|
-
}
|
|
7584
|
-
},
|
|
7585
|
-
required: [
|
|
7586
|
-
"outputs",
|
|
7587
|
-
"nodes"
|
|
7588
|
-
],
|
|
7589
|
-
type: "object"
|
|
7590
|
-
},
|
|
7591
|
-
fragmentInput: {
|
|
7592
|
-
additionalProperties: false,
|
|
7593
|
-
properties: {
|
|
7594
|
-
name: {
|
|
7595
|
-
minLength: 1,
|
|
7596
|
-
type: "string"
|
|
7597
|
-
},
|
|
7598
|
-
type: {
|
|
7599
|
-
type: "string"
|
|
7600
|
-
}
|
|
7601
|
-
},
|
|
7602
|
-
required: [
|
|
7603
|
-
"name"
|
|
7604
|
-
],
|
|
7605
|
-
type: "object"
|
|
7606
|
-
},
|
|
7607
|
-
fragmentOutput: {
|
|
7608
|
-
additionalProperties: false,
|
|
7609
|
-
properties: {
|
|
7610
|
-
from_node: {
|
|
7611
|
-
minLength: 1,
|
|
7612
|
-
type: "string"
|
|
7613
|
-
},
|
|
7614
|
-
name: {
|
|
7615
|
-
minLength: 1,
|
|
7616
|
-
type: "string"
|
|
7617
|
-
},
|
|
7618
|
-
pointer: {
|
|
7619
|
-
pattern: "^(/.*)?$",
|
|
7620
|
-
type: "string"
|
|
7621
|
-
}
|
|
7622
|
-
},
|
|
7623
|
-
required: [
|
|
7624
|
-
"name",
|
|
7625
|
-
"from_node"
|
|
7626
|
-
],
|
|
7627
|
-
type: "object"
|
|
7628
|
-
},
|
|
7629
|
-
llmResponsesBinding: {
|
|
7630
|
-
additionalProperties: false,
|
|
7631
|
-
oneOf: [
|
|
7632
|
-
{
|
|
7633
|
-
required: [
|
|
7634
|
-
"to"
|
|
7635
|
-
]
|
|
7636
|
-
},
|
|
7637
|
-
{
|
|
7638
|
-
required: [
|
|
7639
|
-
"to_placeholder"
|
|
7640
|
-
]
|
|
7641
|
-
}
|
|
7642
|
-
],
|
|
7643
|
-
properties: {
|
|
7644
|
-
encoding: {
|
|
7645
|
-
enum: [
|
|
7646
|
-
"json",
|
|
7647
|
-
"json_string"
|
|
7648
|
-
],
|
|
7649
|
-
type: "string"
|
|
7650
|
-
},
|
|
7651
|
-
from: {
|
|
7652
|
-
minLength: 1,
|
|
7653
|
-
type: "string"
|
|
7654
|
-
},
|
|
7655
|
-
pointer: {
|
|
7656
|
-
pattern: "^(/.*)?$",
|
|
7657
|
-
type: "string"
|
|
7658
|
-
},
|
|
7659
|
-
to: {
|
|
7660
|
-
pattern: "^/.*$",
|
|
7661
|
-
type: "string"
|
|
7662
|
-
},
|
|
7663
|
-
to_placeholder: {
|
|
7664
|
-
minLength: 1,
|
|
7665
|
-
type: "string"
|
|
7666
|
-
}
|
|
7667
|
-
},
|
|
7668
|
-
required: [
|
|
7669
|
-
"from"
|
|
7670
|
-
],
|
|
7671
|
-
type: "object"
|
|
7672
|
-
},
|
|
7673
|
-
mapFanoutItemBinding: {
|
|
7674
|
-
additionalProperties: false,
|
|
7675
|
-
oneOf: [
|
|
7676
|
-
{
|
|
7677
|
-
required: [
|
|
7678
|
-
"to"
|
|
7679
|
-
]
|
|
7680
|
-
},
|
|
7681
|
-
{
|
|
7682
|
-
required: [
|
|
7683
|
-
"to_placeholder"
|
|
7684
|
-
]
|
|
7685
|
-
}
|
|
7686
|
-
],
|
|
7687
|
-
properties: {
|
|
7688
|
-
encoding: {
|
|
7689
|
-
enum: [
|
|
7690
|
-
"json",
|
|
7691
|
-
"json_string"
|
|
7692
|
-
],
|
|
7693
|
-
type: "string"
|
|
7694
|
-
},
|
|
7695
|
-
path: {
|
|
7696
|
-
pattern: "^(/.*)?$",
|
|
7697
|
-
type: "string"
|
|
7698
|
-
},
|
|
7699
|
-
to: {
|
|
7700
|
-
pattern: "^/.*$",
|
|
7701
|
-
type: "string"
|
|
7702
|
-
},
|
|
7703
|
-
to_placeholder: {
|
|
7704
|
-
minLength: 1,
|
|
7705
|
-
type: "string"
|
|
7706
|
-
}
|
|
7707
|
-
},
|
|
7708
|
-
type: "object"
|
|
7709
|
-
},
|
|
7710
|
-
node: {
|
|
7711
|
-
additionalProperties: false,
|
|
7712
|
-
oneOf: [
|
|
7713
|
-
{
|
|
7714
|
-
allOf: [
|
|
7715
|
-
{
|
|
7716
|
-
properties: {
|
|
7717
|
-
input: {
|
|
7718
|
-
properties: {
|
|
7719
|
-
bindings: {
|
|
7720
|
-
items: {
|
|
7721
|
-
$ref: "#/definitions/llmResponsesBinding"
|
|
7722
|
-
},
|
|
7723
|
-
type: "array"
|
|
7724
|
-
},
|
|
7725
|
-
request: {
|
|
7726
|
-
type: "object"
|
|
7727
|
-
},
|
|
7728
|
-
stream: {
|
|
7729
|
-
type: "boolean"
|
|
7730
|
-
},
|
|
7731
|
-
tool_execution: {
|
|
7732
|
-
additionalProperties: false,
|
|
7733
|
-
properties: {
|
|
7734
|
-
mode: {
|
|
7735
|
-
default: "server",
|
|
7736
|
-
enum: [
|
|
7737
|
-
"server",
|
|
7738
|
-
"client"
|
|
7739
|
-
],
|
|
7740
|
-
type: "string"
|
|
7741
|
-
}
|
|
7742
|
-
},
|
|
7743
|
-
required: [
|
|
7744
|
-
"mode"
|
|
7745
|
-
],
|
|
7746
|
-
type: "object"
|
|
7747
|
-
},
|
|
7748
|
-
tool_limits: {
|
|
7749
|
-
additionalProperties: false,
|
|
7750
|
-
properties: {
|
|
7751
|
-
max_llm_calls: {
|
|
7752
|
-
default: 8,
|
|
7753
|
-
maximum: 64,
|
|
7754
|
-
minimum: 1,
|
|
7755
|
-
type: "integer"
|
|
7756
|
-
},
|
|
7757
|
-
max_tool_calls_per_step: {
|
|
7758
|
-
default: 16,
|
|
7759
|
-
maximum: 64,
|
|
7760
|
-
minimum: 1,
|
|
7761
|
-
type: "integer"
|
|
7762
|
-
},
|
|
7763
|
-
wait_ttl_ms: {
|
|
7764
|
-
default: 9e5,
|
|
7765
|
-
maximum: 864e5,
|
|
7766
|
-
minimum: 1,
|
|
7767
|
-
type: "integer"
|
|
7768
|
-
}
|
|
7769
|
-
},
|
|
7770
|
-
type: "object"
|
|
7771
|
-
}
|
|
7772
|
-
},
|
|
7773
|
-
required: [
|
|
7774
|
-
"request"
|
|
7775
|
-
],
|
|
7776
|
-
type: "object"
|
|
7777
|
-
}
|
|
7778
|
-
}
|
|
7779
|
-
}
|
|
7780
|
-
],
|
|
7781
|
-
properties: {
|
|
7782
|
-
type: {
|
|
7783
|
-
const: "llm.responses"
|
|
7784
|
-
}
|
|
7785
|
-
},
|
|
7786
|
-
required: [
|
|
7787
|
-
"input"
|
|
7788
|
-
]
|
|
7789
|
-
},
|
|
7790
|
-
{
|
|
7791
|
-
allOf: [
|
|
7792
|
-
{
|
|
7793
|
-
properties: {
|
|
7794
|
-
input: {
|
|
7795
|
-
properties: {
|
|
7796
|
-
bindings: {
|
|
7797
|
-
items: {
|
|
7798
|
-
$ref: "#/definitions/llmResponsesBinding"
|
|
7799
|
-
},
|
|
7800
|
-
type: "array"
|
|
7801
|
-
},
|
|
7802
|
-
request: {
|
|
7803
|
-
type: "object"
|
|
7804
|
-
},
|
|
7805
|
-
stream: {
|
|
7806
|
-
type: "boolean"
|
|
7807
|
-
},
|
|
7808
|
-
tool_execution: {
|
|
7809
|
-
additionalProperties: false,
|
|
7810
|
-
properties: {
|
|
7811
|
-
mode: {
|
|
7812
|
-
default: "server",
|
|
7813
|
-
enum: [
|
|
7814
|
-
"server",
|
|
7815
|
-
"client"
|
|
7816
|
-
],
|
|
7817
|
-
type: "string"
|
|
7818
|
-
}
|
|
7819
|
-
},
|
|
7820
|
-
required: [
|
|
7821
|
-
"mode"
|
|
7822
|
-
],
|
|
7823
|
-
type: "object"
|
|
7824
|
-
},
|
|
7825
|
-
tool_limits: {
|
|
7826
|
-
additionalProperties: false,
|
|
7827
|
-
properties: {
|
|
7828
|
-
max_llm_calls: {
|
|
7829
|
-
default: 8,
|
|
7830
|
-
maximum: 64,
|
|
7831
|
-
minimum: 1,
|
|
7832
|
-
type: "integer"
|
|
7833
|
-
},
|
|
7834
|
-
max_tool_calls_per_step: {
|
|
7835
|
-
default: 16,
|
|
7836
|
-
maximum: 64,
|
|
7837
|
-
minimum: 1,
|
|
7838
|
-
type: "integer"
|
|
7839
|
-
},
|
|
7840
|
-
wait_ttl_ms: {
|
|
7841
|
-
default: 9e5,
|
|
7842
|
-
maximum: 864e5,
|
|
7843
|
-
minimum: 1,
|
|
7844
|
-
type: "integer"
|
|
7845
|
-
}
|
|
7846
|
-
},
|
|
7847
|
-
type: "object"
|
|
7848
|
-
}
|
|
7849
|
-
},
|
|
7850
|
-
required: [
|
|
7851
|
-
"request"
|
|
7852
|
-
],
|
|
7853
|
-
type: "object"
|
|
7854
|
-
}
|
|
7855
|
-
}
|
|
7856
|
-
}
|
|
7857
|
-
],
|
|
7858
|
-
properties: {
|
|
7859
|
-
type: {
|
|
7860
|
-
const: "route.switch"
|
|
7861
|
-
}
|
|
7862
|
-
},
|
|
7863
|
-
required: [
|
|
7864
|
-
"input"
|
|
7865
|
-
]
|
|
7866
|
-
},
|
|
7867
|
-
{
|
|
7868
|
-
properties: {
|
|
7869
|
-
type: {
|
|
7870
|
-
const: "join.all"
|
|
7871
|
-
}
|
|
7872
|
-
}
|
|
7873
|
-
},
|
|
7874
|
-
{
|
|
7875
|
-
allOf: [
|
|
7876
|
-
{
|
|
7877
|
-
properties: {
|
|
7878
|
-
input: {
|
|
7879
|
-
additionalProperties: false,
|
|
7880
|
-
properties: {
|
|
7881
|
-
predicate: {
|
|
7882
|
-
$ref: "#/definitions/condition"
|
|
7883
|
-
}
|
|
7884
|
-
},
|
|
7885
|
-
type: "object"
|
|
7886
|
-
}
|
|
7887
|
-
}
|
|
7888
|
-
}
|
|
7889
|
-
],
|
|
7890
|
-
properties: {
|
|
7891
|
-
type: {
|
|
7892
|
-
const: "join.any"
|
|
7893
|
-
}
|
|
7894
|
-
}
|
|
7895
|
-
},
|
|
7896
|
-
{
|
|
7897
|
-
allOf: [
|
|
7898
|
-
{
|
|
7899
|
-
properties: {
|
|
7900
|
-
input: {
|
|
7901
|
-
additionalProperties: false,
|
|
7902
|
-
properties: {
|
|
7903
|
-
limit: {
|
|
7904
|
-
minimum: 1,
|
|
7905
|
-
type: "integer"
|
|
7906
|
-
},
|
|
7907
|
-
predicate: {
|
|
7908
|
-
$ref: "#/definitions/condition"
|
|
7909
|
-
},
|
|
7910
|
-
timeout_ms: {
|
|
7911
|
-
minimum: 1,
|
|
7912
|
-
type: "integer"
|
|
7913
|
-
}
|
|
7914
|
-
},
|
|
7915
|
-
type: "object"
|
|
7916
|
-
}
|
|
7917
|
-
}
|
|
7918
|
-
}
|
|
7919
|
-
],
|
|
7920
|
-
properties: {
|
|
7921
|
-
type: {
|
|
7922
|
-
const: "join.collect"
|
|
7923
|
-
}
|
|
7924
|
-
},
|
|
7925
|
-
required: [
|
|
7926
|
-
"input"
|
|
7927
|
-
]
|
|
7928
|
-
},
|
|
7929
|
-
{
|
|
7930
|
-
allOf: [
|
|
7931
|
-
{
|
|
7932
|
-
properties: {
|
|
7933
|
-
input: {
|
|
7934
|
-
additionalProperties: false,
|
|
7935
|
-
oneOf: [
|
|
7936
|
-
{
|
|
7937
|
-
not: {
|
|
7938
|
-
required: [
|
|
7939
|
-
"merge"
|
|
7940
|
-
]
|
|
7941
|
-
},
|
|
7942
|
-
required: [
|
|
7943
|
-
"object"
|
|
7944
|
-
]
|
|
7945
|
-
},
|
|
7946
|
-
{
|
|
7947
|
-
not: {
|
|
7948
|
-
required: [
|
|
7949
|
-
"object"
|
|
7950
|
-
]
|
|
7951
|
-
},
|
|
7952
|
-
required: [
|
|
7953
|
-
"merge"
|
|
7954
|
-
]
|
|
7955
|
-
}
|
|
7956
|
-
],
|
|
7957
|
-
properties: {
|
|
7958
|
-
merge: {
|
|
7959
|
-
items: {
|
|
7960
|
-
$ref: "#/definitions/transformValue"
|
|
7961
|
-
},
|
|
7962
|
-
minItems: 1,
|
|
7963
|
-
type: "array"
|
|
7964
|
-
},
|
|
7965
|
-
object: {
|
|
7966
|
-
additionalProperties: {
|
|
7967
|
-
$ref: "#/definitions/transformValue"
|
|
7968
|
-
},
|
|
7969
|
-
minProperties: 1,
|
|
7970
|
-
type: "object"
|
|
7971
|
-
}
|
|
7972
|
-
},
|
|
7973
|
-
type: "object"
|
|
7974
|
-
}
|
|
7975
|
-
}
|
|
7976
|
-
}
|
|
7977
|
-
],
|
|
7978
|
-
properties: {
|
|
7979
|
-
type: {
|
|
7980
|
-
const: "transform.json"
|
|
7981
|
-
}
|
|
7982
|
-
},
|
|
7983
|
-
required: [
|
|
7984
|
-
"input"
|
|
7985
|
-
]
|
|
7986
|
-
},
|
|
7987
|
-
{
|
|
7988
|
-
allOf: [
|
|
7989
|
-
{
|
|
7990
|
-
properties: {
|
|
7991
|
-
input: {
|
|
7992
|
-
additionalProperties: false,
|
|
7993
|
-
properties: {
|
|
7994
|
-
item_bindings: {
|
|
7995
|
-
items: {
|
|
7996
|
-
$ref: "#/definitions/mapFanoutItemBinding"
|
|
7997
|
-
},
|
|
7998
|
-
type: "array"
|
|
7999
|
-
},
|
|
8000
|
-
items: {
|
|
8001
|
-
additionalProperties: false,
|
|
8002
|
-
properties: {
|
|
8003
|
-
from: {
|
|
8004
|
-
minLength: 1,
|
|
8005
|
-
type: "string"
|
|
8006
|
-
},
|
|
8007
|
-
path: {
|
|
8008
|
-
pattern: "^(/.*)?$",
|
|
8009
|
-
type: "string"
|
|
8010
|
-
},
|
|
8011
|
-
pointer: {
|
|
8012
|
-
pattern: "^(/.*)?$",
|
|
8013
|
-
type: "string"
|
|
8014
|
-
}
|
|
8015
|
-
},
|
|
8016
|
-
required: [
|
|
8017
|
-
"from"
|
|
8018
|
-
],
|
|
8019
|
-
type: "object"
|
|
8020
|
-
},
|
|
8021
|
-
max_parallelism: {
|
|
8022
|
-
minimum: 1,
|
|
8023
|
-
type: "integer"
|
|
8024
|
-
},
|
|
8025
|
-
subnode: {
|
|
8026
|
-
additionalProperties: false,
|
|
8027
|
-
properties: {
|
|
8028
|
-
id: {
|
|
8029
|
-
minLength: 1,
|
|
8030
|
-
type: "string"
|
|
8031
|
-
},
|
|
8032
|
-
input: {},
|
|
8033
|
-
type: {
|
|
8034
|
-
enum: [
|
|
8035
|
-
"llm.responses",
|
|
8036
|
-
"route.switch",
|
|
8037
|
-
"transform.json"
|
|
8038
|
-
],
|
|
8039
|
-
type: "string"
|
|
8040
|
-
}
|
|
8041
|
-
},
|
|
8042
|
-
required: [
|
|
8043
|
-
"id",
|
|
8044
|
-
"type"
|
|
8045
|
-
],
|
|
8046
|
-
type: "object"
|
|
8047
|
-
}
|
|
8048
|
-
},
|
|
8049
|
-
required: [
|
|
8050
|
-
"items",
|
|
8051
|
-
"subnode"
|
|
8052
|
-
],
|
|
8053
|
-
type: "object"
|
|
8054
|
-
}
|
|
8055
|
-
}
|
|
8056
|
-
}
|
|
8057
|
-
],
|
|
8058
|
-
properties: {
|
|
8059
|
-
type: {
|
|
8060
|
-
const: "map.fanout"
|
|
8061
|
-
}
|
|
8062
|
-
},
|
|
8063
|
-
required: [
|
|
8064
|
-
"input"
|
|
8065
|
-
]
|
|
8066
|
-
},
|
|
8067
|
-
{
|
|
8068
|
-
allOf: [
|
|
8069
|
-
{
|
|
8070
|
-
properties: {
|
|
8071
|
-
input: {
|
|
8072
|
-
additionalProperties: false,
|
|
8073
|
-
properties: {
|
|
8074
|
-
bind_inputs: {
|
|
8075
|
-
additionalProperties: {
|
|
8076
|
-
$ref: "#/definitions/fragmentBindInput"
|
|
8077
|
-
},
|
|
8078
|
-
type: "object"
|
|
8079
|
-
},
|
|
8080
|
-
ref: {
|
|
8081
|
-
minLength: 1,
|
|
8082
|
-
type: "string"
|
|
8083
|
-
}
|
|
8084
|
-
},
|
|
8085
|
-
required: [
|
|
8086
|
-
"ref"
|
|
8087
|
-
],
|
|
8088
|
-
type: "object"
|
|
8089
|
-
}
|
|
8090
|
-
}
|
|
8091
|
-
}
|
|
8092
|
-
],
|
|
8093
|
-
properties: {
|
|
8094
|
-
type: {
|
|
8095
|
-
const: "fragment"
|
|
8096
|
-
}
|
|
8097
|
-
},
|
|
8098
|
-
required: [
|
|
8099
|
-
"input"
|
|
8100
|
-
]
|
|
8101
|
-
}
|
|
8102
|
-
],
|
|
8103
|
-
properties: {
|
|
8104
|
-
id: {
|
|
8105
|
-
minLength: 1,
|
|
8106
|
-
type: "string"
|
|
8107
|
-
},
|
|
8108
|
-
input: {},
|
|
8109
|
-
type: {
|
|
8110
|
-
enum: [
|
|
8111
|
-
"llm.responses",
|
|
8112
|
-
"route.switch",
|
|
8113
|
-
"join.all",
|
|
8114
|
-
"join.any",
|
|
8115
|
-
"join.collect",
|
|
8116
|
-
"transform.json",
|
|
8117
|
-
"map.fanout",
|
|
8118
|
-
"fragment"
|
|
8119
|
-
],
|
|
8120
|
-
type: "string"
|
|
8121
|
-
}
|
|
8122
|
-
},
|
|
8123
|
-
required: [
|
|
8124
|
-
"id",
|
|
8125
|
-
"type"
|
|
8126
|
-
],
|
|
8127
|
-
type: "object"
|
|
8128
|
-
},
|
|
8129
|
-
output: {
|
|
8130
|
-
additionalProperties: false,
|
|
8131
|
-
properties: {
|
|
8132
|
-
from: {
|
|
8133
|
-
minLength: 1,
|
|
8134
|
-
type: "string"
|
|
8135
|
-
},
|
|
8136
|
-
name: {
|
|
8137
|
-
minLength: 1,
|
|
8138
|
-
type: "string"
|
|
8139
|
-
},
|
|
8140
|
-
output: {
|
|
8141
|
-
minLength: 1,
|
|
8142
|
-
type: "string"
|
|
8143
|
-
},
|
|
8144
|
-
pointer: {
|
|
8145
|
-
pattern: "^(/.*)?$",
|
|
8146
|
-
type: "string"
|
|
8147
|
-
}
|
|
8148
|
-
},
|
|
8149
|
-
required: [
|
|
8150
|
-
"name",
|
|
8151
|
-
"from"
|
|
8152
|
-
],
|
|
8153
|
-
type: "object"
|
|
8154
|
-
},
|
|
8155
|
-
transformValue: {
|
|
8156
|
-
additionalProperties: false,
|
|
8157
|
-
properties: {
|
|
8158
|
-
from: {
|
|
8159
|
-
minLength: 1,
|
|
8160
|
-
type: "string"
|
|
8161
|
-
},
|
|
8162
|
-
pointer: {
|
|
8163
|
-
pattern: "^(/.*)?$",
|
|
8164
|
-
type: "string"
|
|
8165
|
-
}
|
|
8166
|
-
},
|
|
8167
|
-
required: [
|
|
8168
|
-
"from"
|
|
8169
|
-
],
|
|
8170
|
-
type: "object"
|
|
8171
|
-
}
|
|
8172
|
-
},
|
|
8173
|
-
properties: {
|
|
8174
|
-
edges: {
|
|
8175
|
-
items: {
|
|
8176
|
-
$ref: "#/definitions/edge"
|
|
8177
|
-
},
|
|
8178
|
-
type: "array"
|
|
8179
|
-
},
|
|
8180
|
-
execution: {
|
|
8181
|
-
additionalProperties: false,
|
|
8182
|
-
properties: {
|
|
8183
|
-
max_parallelism: {
|
|
8184
|
-
minimum: 1,
|
|
8185
|
-
type: "integer"
|
|
8186
|
-
},
|
|
8187
|
-
node_timeout_ms: {
|
|
8188
|
-
minimum: 1,
|
|
8189
|
-
type: "integer"
|
|
8190
|
-
},
|
|
8191
|
-
run_timeout_ms: {
|
|
8192
|
-
minimum: 1,
|
|
8193
|
-
type: "integer"
|
|
8194
|
-
}
|
|
8195
|
-
},
|
|
8196
|
-
type: "object"
|
|
8197
|
-
},
|
|
8198
|
-
fragments: {
|
|
8199
|
-
additionalProperties: {
|
|
8200
|
-
$ref: "#/definitions/fragmentDef"
|
|
8201
|
-
},
|
|
8202
|
-
type: "object"
|
|
8203
|
-
},
|
|
8204
|
-
kind: {
|
|
8205
|
-
const: "workflow.v1",
|
|
8206
|
-
type: "string"
|
|
8207
|
-
},
|
|
8208
|
-
name: {
|
|
8209
|
-
type: "string"
|
|
8210
|
-
},
|
|
8211
|
-
nodes: {
|
|
8212
|
-
items: {
|
|
8213
|
-
$ref: "#/definitions/node"
|
|
8214
|
-
},
|
|
8215
|
-
minItems: 1,
|
|
8216
|
-
type: "array"
|
|
8217
|
-
},
|
|
8218
|
-
outputs: {
|
|
8219
|
-
items: {
|
|
8220
|
-
$ref: "#/definitions/output"
|
|
8221
|
-
},
|
|
8222
|
-
minItems: 1,
|
|
8223
|
-
type: "array"
|
|
8224
|
-
}
|
|
8225
|
-
},
|
|
8226
|
-
required: [
|
|
8227
|
-
"kind",
|
|
8228
|
-
"nodes",
|
|
8229
|
-
"outputs"
|
|
8230
|
-
],
|
|
8231
|
-
title: "ModelRelay workflow.v1",
|
|
8232
|
-
type: "object"
|
|
8233
|
-
};
|
|
8234
|
-
|
|
8235
|
-
// src/workflow_patterns.ts
|
|
8236
|
-
var LLM_TEXT_OUTPUT_INTERNAL = "/output/0/content/0/text";
|
|
8237
|
-
var LLM_USER_MESSAGE_TEXT_INTERNAL = "/input/1/content/0/text";
|
|
8238
|
-
function wireRequest2(req) {
|
|
8239
|
-
const raw = req;
|
|
8240
|
-
if (raw && typeof raw === "object") {
|
|
8241
|
-
if ("input" in raw) {
|
|
8242
|
-
return req;
|
|
8243
|
-
}
|
|
8244
|
-
if ("body" in raw) {
|
|
8245
|
-
return raw.body ?? {};
|
|
5763
|
+
const msg = input[msgIndex];
|
|
5764
|
+
if (contentIndex >= msg.content.length) {
|
|
5765
|
+
return `targets ${pointer} but message ${msgIndex} only has ${msg.content.length} content blocks (indices 0-${msg.content.length - 1})`;
|
|
8246
5766
|
}
|
|
8247
5767
|
}
|
|
8248
|
-
return
|
|
8249
|
-
}
|
|
8250
|
-
function sortEdges(edges) {
|
|
8251
|
-
return edges.slice().sort((a, b) => {
|
|
8252
|
-
const af = String(a.from);
|
|
8253
|
-
const bf = String(b.from);
|
|
8254
|
-
if (af < bf) return -1;
|
|
8255
|
-
if (af > bf) return 1;
|
|
8256
|
-
const at = String(a.to);
|
|
8257
|
-
const bt = String(b.to);
|
|
8258
|
-
if (at < bt) return -1;
|
|
8259
|
-
if (at > bt) return 1;
|
|
8260
|
-
return 0;
|
|
8261
|
-
});
|
|
8262
|
-
}
|
|
8263
|
-
function sortOutputs(outputs) {
|
|
8264
|
-
return outputs.slice().sort((a, b) => {
|
|
8265
|
-
const an = String(a.name);
|
|
8266
|
-
const bn = String(b.name);
|
|
8267
|
-
if (an < bn) return -1;
|
|
8268
|
-
if (an > bn) return 1;
|
|
8269
|
-
const af = String(a.from);
|
|
8270
|
-
const bf = String(b.from);
|
|
8271
|
-
if (af < bf) return -1;
|
|
8272
|
-
if (af > bf) return 1;
|
|
8273
|
-
const ap = a.pointer ?? "";
|
|
8274
|
-
const bp = b.pointer ?? "";
|
|
8275
|
-
if (ap < bp) return -1;
|
|
8276
|
-
if (ap > bp) return 1;
|
|
8277
|
-
return 0;
|
|
8278
|
-
});
|
|
8279
|
-
}
|
|
8280
|
-
function LLMStep(id, request) {
|
|
8281
|
-
const config = {
|
|
8282
|
-
id,
|
|
8283
|
-
request: wireRequest2(request),
|
|
8284
|
-
stream: false
|
|
8285
|
-
};
|
|
8286
|
-
return {
|
|
8287
|
-
...config,
|
|
8288
|
-
withStream() {
|
|
8289
|
-
return { ...config, stream: true };
|
|
8290
|
-
}
|
|
8291
|
-
};
|
|
5768
|
+
return void 0;
|
|
8292
5769
|
}
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
static create(name, steps) {
|
|
8298
|
-
return new _ChainBuilder({ name, steps, outputs: [] });
|
|
5770
|
+
function validateMapFanoutInput(nodeId, input) {
|
|
5771
|
+
const subnode = input.subnode;
|
|
5772
|
+
if ((subnode.type === WorkflowNodeTypesV1.LLMResponses || subnode.type === WorkflowNodeTypesV1.RouteSwitch) && subnode.input.bindings && subnode.input.bindings.length > 0) {
|
|
5773
|
+
throw new MapFanoutInputError(nodeId, "map.fanout subnode bindings are not allowed");
|
|
8299
5774
|
}
|
|
8300
|
-
|
|
8301
|
-
return
|
|
5775
|
+
if (subnode.type !== WorkflowNodeTypesV1.TransformJSON) {
|
|
5776
|
+
return;
|
|
8302
5777
|
}
|
|
8303
|
-
|
|
8304
|
-
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
5778
|
+
if (input.item_bindings && input.item_bindings.length > 0) {
|
|
5779
|
+
throw new MapFanoutInputError(
|
|
5780
|
+
nodeId,
|
|
5781
|
+
"map.fanout transform.json subnode cannot use item_bindings"
|
|
5782
|
+
);
|
|
8308
5783
|
}
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
|
|
8315
|
-
|
|
8316
|
-
{
|
|
8317
|
-
name,
|
|
8318
|
-
from,
|
|
8319
|
-
pointer: LLM_TEXT_OUTPUT_INTERNAL
|
|
8320
|
-
}
|
|
8321
|
-
]
|
|
8322
|
-
});
|
|
5784
|
+
const hasObject = !!subnode.input.object && Object.keys(subnode.input.object).length > 0;
|
|
5785
|
+
const hasMerge = !!subnode.input.merge && subnode.input.merge.length > 0;
|
|
5786
|
+
if (hasObject === hasMerge) {
|
|
5787
|
+
throw new MapFanoutInputError(
|
|
5788
|
+
nodeId,
|
|
5789
|
+
"map.fanout transform.json must provide exactly one of object or merge"
|
|
5790
|
+
);
|
|
8323
5791
|
}
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
|
|
8328
|
-
|
|
8329
|
-
|
|
5792
|
+
if (hasObject) {
|
|
5793
|
+
for (const [key, value] of Object.entries(subnode.input.object ?? {})) {
|
|
5794
|
+
if (!key.trim()) continue;
|
|
5795
|
+
if (String(value.from) !== "item") {
|
|
5796
|
+
throw new MapFanoutInputError(
|
|
5797
|
+
nodeId,
|
|
5798
|
+
`map.fanout transform.json object.${key}.from must be "item"`
|
|
5799
|
+
);
|
|
5800
|
+
}
|
|
8330
5801
|
}
|
|
8331
|
-
return this.output(name, this.state.steps[this.state.steps.length - 1].id);
|
|
8332
5802
|
}
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
}
|
|
8341
|
-
const nodes = [];
|
|
8342
|
-
const edges = [];
|
|
8343
|
-
for (let i = 0; i < this.state.steps.length; i++) {
|
|
8344
|
-
const step = this.state.steps[i];
|
|
8345
|
-
const bindings = [];
|
|
8346
|
-
if (i > 0) {
|
|
8347
|
-
const prevId = this.state.steps[i - 1].id;
|
|
8348
|
-
bindings.push({
|
|
8349
|
-
from: prevId,
|
|
8350
|
-
pointer: LLM_TEXT_OUTPUT_INTERNAL,
|
|
8351
|
-
to: LLM_USER_MESSAGE_TEXT_INTERNAL,
|
|
8352
|
-
encoding: "json_string"
|
|
8353
|
-
});
|
|
8354
|
-
edges.push({ from: prevId, to: step.id });
|
|
5803
|
+
if (hasMerge) {
|
|
5804
|
+
for (const [index, value] of (subnode.input.merge ?? []).entries()) {
|
|
5805
|
+
if (String(value.from) !== "item") {
|
|
5806
|
+
throw new MapFanoutInputError(
|
|
5807
|
+
nodeId,
|
|
5808
|
+
`map.fanout transform.json merge[${index}].from must be "item"`
|
|
5809
|
+
);
|
|
8355
5810
|
}
|
|
8356
|
-
const input = {
|
|
8357
|
-
id: step.id,
|
|
8358
|
-
type: WorkflowNodeTypes.LLMResponses,
|
|
8359
|
-
input: {
|
|
8360
|
-
request: step.request,
|
|
8361
|
-
...step.stream ? { stream: true } : {},
|
|
8362
|
-
...bindings.length > 0 ? { bindings } : {}
|
|
8363
|
-
}
|
|
8364
|
-
};
|
|
8365
|
-
nodes.push(input);
|
|
8366
5811
|
}
|
|
8367
|
-
return {
|
|
8368
|
-
kind: WorkflowKinds.WorkflowV0,
|
|
8369
|
-
name: this.state.name,
|
|
8370
|
-
...this.state.execution ? { execution: this.state.execution } : {},
|
|
8371
|
-
nodes,
|
|
8372
|
-
...edges.length > 0 ? { edges: sortEdges(edges) } : {},
|
|
8373
|
-
outputs: sortOutputs(this.state.outputs)
|
|
8374
|
-
};
|
|
8375
5812
|
}
|
|
8376
|
-
};
|
|
8377
|
-
function Chain(name, steps) {
|
|
8378
|
-
return ChainBuilder.create(name, steps);
|
|
8379
5813
|
}
|
|
8380
|
-
var
|
|
8381
|
-
constructor(state) {
|
|
5814
|
+
var WorkflowBuilderV1 = class _WorkflowBuilderV1 {
|
|
5815
|
+
constructor(state = { nodes: [], edges: [], outputs: [] }) {
|
|
8382
5816
|
this.state = state;
|
|
8383
5817
|
}
|
|
8384
|
-
static
|
|
8385
|
-
return new
|
|
5818
|
+
static new() {
|
|
5819
|
+
return new _WorkflowBuilderV1();
|
|
8386
5820
|
}
|
|
8387
5821
|
with(patch) {
|
|
8388
|
-
return new
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
* Sets the workflow execution configuration.
|
|
8392
|
-
*/
|
|
8393
|
-
execution(exec) {
|
|
8394
|
-
return this.with({ execution: exec });
|
|
8395
|
-
}
|
|
8396
|
-
/**
|
|
8397
|
-
* Adds a join node that waits for all parallel steps,
|
|
8398
|
-
* followed by an aggregator LLM node that receives the combined output.
|
|
8399
|
-
* The join node ID is automatically generated as "<id>_join".
|
|
8400
|
-
*/
|
|
8401
|
-
aggregate(id, request) {
|
|
8402
|
-
return this.with({
|
|
8403
|
-
aggregate: {
|
|
8404
|
-
id,
|
|
8405
|
-
request: wireRequest2(request),
|
|
8406
|
-
stream: false
|
|
8407
|
-
}
|
|
5822
|
+
return new _WorkflowBuilderV1({
|
|
5823
|
+
...this.state,
|
|
5824
|
+
...patch
|
|
8408
5825
|
});
|
|
8409
5826
|
}
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
*/
|
|
8413
|
-
aggregateWithStream(id, request) {
|
|
8414
|
-
return this.with({
|
|
8415
|
-
aggregate: {
|
|
8416
|
-
id,
|
|
8417
|
-
request: wireRequest2(request),
|
|
8418
|
-
stream: true
|
|
8419
|
-
}
|
|
8420
|
-
});
|
|
5827
|
+
name(name) {
|
|
5828
|
+
return this.with({ name: name.trim() || void 0 });
|
|
8421
5829
|
}
|
|
8422
|
-
|
|
8423
|
-
|
|
8424
|
-
*/
|
|
8425
|
-
output(name, from) {
|
|
8426
|
-
return this.with({
|
|
8427
|
-
outputs: [
|
|
8428
|
-
...this.state.outputs,
|
|
8429
|
-
{
|
|
8430
|
-
name,
|
|
8431
|
-
from,
|
|
8432
|
-
pointer: LLM_TEXT_OUTPUT_INTERNAL
|
|
8433
|
-
}
|
|
8434
|
-
]
|
|
8435
|
-
});
|
|
5830
|
+
execution(execution) {
|
|
5831
|
+
return this.with({ execution });
|
|
8436
5832
|
}
|
|
8437
|
-
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
if (
|
|
8443
|
-
|
|
8444
|
-
}
|
|
8445
|
-
const nodes = [];
|
|
8446
|
-
const edges = [];
|
|
8447
|
-
for (const step of this.state.steps) {
|
|
8448
|
-
const input = {
|
|
8449
|
-
id: step.id,
|
|
8450
|
-
type: WorkflowNodeTypes.LLMResponses,
|
|
8451
|
-
input: {
|
|
8452
|
-
request: step.request,
|
|
8453
|
-
...step.stream ? { stream: true } : {}
|
|
8454
|
-
}
|
|
8455
|
-
};
|
|
8456
|
-
nodes.push(input);
|
|
8457
|
-
}
|
|
8458
|
-
if (this.state.aggregate) {
|
|
8459
|
-
const joinId = `${this.state.aggregate.id}_join`;
|
|
8460
|
-
nodes.push({ id: joinId, type: WorkflowNodeTypes.JoinAll });
|
|
8461
|
-
for (const step of this.state.steps) {
|
|
8462
|
-
edges.push({ from: step.id, to: joinId });
|
|
8463
|
-
}
|
|
8464
|
-
const aggInput = {
|
|
8465
|
-
id: this.state.aggregate.id,
|
|
8466
|
-
type: WorkflowNodeTypes.LLMResponses,
|
|
8467
|
-
input: {
|
|
8468
|
-
request: this.state.aggregate.request,
|
|
8469
|
-
...this.state.aggregate.stream ? { stream: true } : {},
|
|
8470
|
-
bindings: [
|
|
8471
|
-
{
|
|
8472
|
-
from: joinId,
|
|
8473
|
-
// Empty pointer = full join output
|
|
8474
|
-
to: LLM_USER_MESSAGE_TEXT_INTERNAL,
|
|
8475
|
-
encoding: "json_string"
|
|
8476
|
-
}
|
|
8477
|
-
]
|
|
8478
|
-
}
|
|
8479
|
-
};
|
|
8480
|
-
nodes.push(aggInput);
|
|
8481
|
-
edges.push({ from: joinId, to: this.state.aggregate.id });
|
|
5833
|
+
node(node) {
|
|
5834
|
+
return this.with({ nodes: [...this.state.nodes, node] });
|
|
5835
|
+
}
|
|
5836
|
+
llmResponses(id, request, options = {}) {
|
|
5837
|
+
const wiredRequest = wireRequest(request);
|
|
5838
|
+
if (options.bindings) {
|
|
5839
|
+
validateBindingTargets(id, wiredRequest.input, options.bindings);
|
|
8482
5840
|
}
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
...
|
|
8487
|
-
|
|
8488
|
-
...
|
|
8489
|
-
outputs: sortOutputs(this.state.outputs)
|
|
5841
|
+
const input = {
|
|
5842
|
+
request: wiredRequest,
|
|
5843
|
+
...options.stream === void 0 ? {} : { stream: options.stream },
|
|
5844
|
+
...options.toolExecution === void 0 ? {} : { tool_execution: { mode: options.toolExecution } },
|
|
5845
|
+
...options.toolLimits === void 0 ? {} : { tool_limits: { ...options.toolLimits } },
|
|
5846
|
+
...options.bindings === void 0 ? {} : { bindings: options.bindings.slice() }
|
|
8490
5847
|
};
|
|
5848
|
+
return this.node({
|
|
5849
|
+
id,
|
|
5850
|
+
type: WorkflowNodeTypesV1.LLMResponses,
|
|
5851
|
+
input
|
|
5852
|
+
});
|
|
8491
5853
|
}
|
|
8492
|
-
}
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
function MapItem(id, request) {
|
|
8497
|
-
const config = {
|
|
8498
|
-
id,
|
|
8499
|
-
request: wireRequest2(request),
|
|
8500
|
-
stream: false
|
|
8501
|
-
};
|
|
8502
|
-
return {
|
|
8503
|
-
...config,
|
|
8504
|
-
withStream() {
|
|
8505
|
-
return { ...config, stream: true };
|
|
5854
|
+
routeSwitch(id, request, options = {}) {
|
|
5855
|
+
const wiredRequest = wireRequest(request);
|
|
5856
|
+
if (options.bindings) {
|
|
5857
|
+
validateBindingTargets(id, wiredRequest.input, options.bindings);
|
|
8506
5858
|
}
|
|
8507
|
-
|
|
8508
|
-
|
|
8509
|
-
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
|
|
8514
|
-
return
|
|
5859
|
+
const input = {
|
|
5860
|
+
request: wiredRequest,
|
|
5861
|
+
...options.stream === void 0 ? {} : { stream: options.stream },
|
|
5862
|
+
...options.toolExecution === void 0 ? {} : { tool_execution: { mode: options.toolExecution } },
|
|
5863
|
+
...options.toolLimits === void 0 ? {} : { tool_limits: { ...options.toolLimits } },
|
|
5864
|
+
...options.bindings === void 0 ? {} : { bindings: options.bindings.slice() }
|
|
5865
|
+
};
|
|
5866
|
+
return this.node({
|
|
5867
|
+
id,
|
|
5868
|
+
type: WorkflowNodeTypesV1.RouteSwitch,
|
|
5869
|
+
input
|
|
5870
|
+
});
|
|
8515
5871
|
}
|
|
8516
|
-
|
|
8517
|
-
return
|
|
5872
|
+
joinAll(id) {
|
|
5873
|
+
return this.node({ id, type: WorkflowNodeTypesV1.JoinAll });
|
|
8518
5874
|
}
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
return this.with({
|
|
8525
|
-
items: [...this.state.items, { id, request: wireRequest2(request), stream: false }]
|
|
5875
|
+
joinAny(id, input) {
|
|
5876
|
+
return this.node({
|
|
5877
|
+
id,
|
|
5878
|
+
type: WorkflowNodeTypesV1.JoinAny,
|
|
5879
|
+
...input ? { input } : {}
|
|
8526
5880
|
});
|
|
8527
5881
|
}
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
*/
|
|
8531
|
-
itemWithStream(id, request) {
|
|
8532
|
-
return this.with({
|
|
8533
|
-
items: [...this.state.items, { id, request: wireRequest2(request), stream: true }]
|
|
8534
|
-
});
|
|
5882
|
+
joinCollect(id, input) {
|
|
5883
|
+
return this.node({ id, type: WorkflowNodeTypesV1.JoinCollect, input });
|
|
8535
5884
|
}
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
*/
|
|
8539
|
-
execution(exec) {
|
|
8540
|
-
return this.with({ execution: exec });
|
|
5885
|
+
transformJSON(id, input) {
|
|
5886
|
+
return this.node({ id, type: WorkflowNodeTypesV1.TransformJSON, input });
|
|
8541
5887
|
}
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
* The join node ID is automatically generated as "<id>_join".
|
|
8546
|
-
*/
|
|
8547
|
-
reduce(id, request) {
|
|
8548
|
-
return this.with({
|
|
8549
|
-
reducer: {
|
|
8550
|
-
id,
|
|
8551
|
-
request: wireRequest2(request),
|
|
8552
|
-
stream: false
|
|
8553
|
-
}
|
|
8554
|
-
});
|
|
5888
|
+
mapFanout(id, input) {
|
|
5889
|
+
validateMapFanoutInput(id, input);
|
|
5890
|
+
return this.node({ id, type: WorkflowNodeTypesV1.MapFanout, input });
|
|
8555
5891
|
}
|
|
8556
|
-
|
|
8557
|
-
* Like reduce() but enables streaming on the reducer node.
|
|
8558
|
-
*/
|
|
8559
|
-
reduceWithStream(id, request) {
|
|
5892
|
+
edge(from, to, when) {
|
|
8560
5893
|
return this.with({
|
|
8561
|
-
|
|
8562
|
-
id,
|
|
8563
|
-
request: wireRequest2(request),
|
|
8564
|
-
stream: true
|
|
8565
|
-
}
|
|
5894
|
+
edges: [...this.state.edges, { from, to, ...when ? { when } : {} }]
|
|
8566
5895
|
});
|
|
8567
5896
|
}
|
|
8568
|
-
|
|
8569
|
-
* Adds an output reference from a specific node.
|
|
8570
|
-
* Typically used to output from the reducer node.
|
|
8571
|
-
*/
|
|
8572
|
-
output(name, from) {
|
|
5897
|
+
output(name, from, pointer) {
|
|
8573
5898
|
return this.with({
|
|
8574
5899
|
outputs: [
|
|
8575
5900
|
...this.state.outputs,
|
|
8576
|
-
{
|
|
8577
|
-
name,
|
|
8578
|
-
from,
|
|
8579
|
-
pointer: LLM_TEXT_OUTPUT_INTERNAL
|
|
8580
|
-
}
|
|
5901
|
+
{ name, from, ...pointer ? { pointer } : {} }
|
|
8581
5902
|
]
|
|
8582
5903
|
});
|
|
8583
5904
|
}
|
|
8584
|
-
/**
|
|
8585
|
-
* Builds and returns the compiled workflow spec.
|
|
8586
|
-
* @throws Error if no items are provided or no reducer is configured
|
|
8587
|
-
*/
|
|
8588
5905
|
build() {
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
8596
|
-
|
|
8597
|
-
if (
|
|
8598
|
-
|
|
8599
|
-
|
|
8600
|
-
if (
|
|
8601
|
-
|
|
8602
|
-
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
const
|
|
8610
|
-
const
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
8619
|
-
edges.push({ from: mapperId, to: joinId });
|
|
8620
|
-
}
|
|
8621
|
-
nodes.push({ id: joinId, type: WorkflowNodeTypes.JoinAll });
|
|
8622
|
-
const reducerInput = {
|
|
8623
|
-
id: this.state.reducer.id,
|
|
8624
|
-
type: WorkflowNodeTypes.LLMResponses,
|
|
8625
|
-
input: {
|
|
8626
|
-
request: this.state.reducer.request,
|
|
8627
|
-
...this.state.reducer.stream ? { stream: true } : {},
|
|
8628
|
-
bindings: [
|
|
8629
|
-
{
|
|
8630
|
-
from: joinId,
|
|
8631
|
-
// Empty pointer = full join output
|
|
8632
|
-
to: LLM_USER_MESSAGE_TEXT_INTERNAL,
|
|
8633
|
-
encoding: "json_string"
|
|
8634
|
-
}
|
|
8635
|
-
]
|
|
8636
|
-
}
|
|
8637
|
-
};
|
|
8638
|
-
nodes.push(reducerInput);
|
|
8639
|
-
edges.push({ from: joinId, to: this.state.reducer.id });
|
|
5906
|
+
const edges = this.state.edges.slice().sort((a, b) => {
|
|
5907
|
+
const af = String(a.from);
|
|
5908
|
+
const bf = String(b.from);
|
|
5909
|
+
if (af < bf) return -1;
|
|
5910
|
+
if (af > bf) return 1;
|
|
5911
|
+
const at = String(a.to);
|
|
5912
|
+
const bt = String(b.to);
|
|
5913
|
+
if (at < bt) return -1;
|
|
5914
|
+
if (at > bt) return 1;
|
|
5915
|
+
const aw = a.when ? JSON.stringify(a.when) : "";
|
|
5916
|
+
const bw = b.when ? JSON.stringify(b.when) : "";
|
|
5917
|
+
if (aw < bw) return -1;
|
|
5918
|
+
if (aw > bw) return 1;
|
|
5919
|
+
return 0;
|
|
5920
|
+
});
|
|
5921
|
+
const outputs = this.state.outputs.slice().sort((a, b) => {
|
|
5922
|
+
const an = String(a.name);
|
|
5923
|
+
const bn = String(b.name);
|
|
5924
|
+
if (an < bn) return -1;
|
|
5925
|
+
if (an > bn) return 1;
|
|
5926
|
+
const af = String(a.from);
|
|
5927
|
+
const bf = String(b.from);
|
|
5928
|
+
if (af < bf) return -1;
|
|
5929
|
+
if (af > bf) return 1;
|
|
5930
|
+
const ap = a.pointer ?? "";
|
|
5931
|
+
const bp = b.pointer ?? "";
|
|
5932
|
+
if (ap < bp) return -1;
|
|
5933
|
+
if (ap > bp) return 1;
|
|
5934
|
+
return 0;
|
|
5935
|
+
});
|
|
8640
5936
|
return {
|
|
8641
|
-
kind: WorkflowKinds.
|
|
8642
|
-
name: this.state.name,
|
|
5937
|
+
kind: WorkflowKinds.WorkflowV1,
|
|
5938
|
+
...this.state.name ? { name: this.state.name } : {},
|
|
8643
5939
|
...this.state.execution ? { execution: this.state.execution } : {},
|
|
8644
|
-
nodes,
|
|
8645
|
-
...edges.length
|
|
8646
|
-
outputs
|
|
5940
|
+
nodes: this.state.nodes.slice(),
|
|
5941
|
+
...edges.length ? { edges } : {},
|
|
5942
|
+
outputs
|
|
8647
5943
|
};
|
|
8648
5944
|
}
|
|
8649
5945
|
};
|
|
8650
|
-
function
|
|
8651
|
-
return
|
|
5946
|
+
function workflowV1() {
|
|
5947
|
+
return WorkflowBuilderV1.new();
|
|
8652
5948
|
}
|
|
8653
5949
|
|
|
8654
5950
|
// src/testing.ts
|
|
@@ -8872,14 +6168,13 @@ __export(workflow_exports, {
|
|
|
8872
6168
|
BindingBuilder: () => BindingBuilder,
|
|
8873
6169
|
BindingEncodings: () => BindingEncodings,
|
|
8874
6170
|
FanoutReduceV1: () => FanoutReduceV1,
|
|
8875
|
-
KindV0: () => KindV0,
|
|
8876
6171
|
KindV1: () => KindV1,
|
|
8877
6172
|
LLM_TEXT_OUTPUT: () => LLM_TEXT_OUTPUT,
|
|
8878
6173
|
LLM_USER_MESSAGE_TEXT: () => LLM_USER_MESSAGE_TEXT,
|
|
8879
|
-
NodeTypes: () => NodeTypes,
|
|
8880
6174
|
NodeTypesV1: () => NodeTypesV1,
|
|
8881
6175
|
RouterV1: () => RouterV1,
|
|
8882
6176
|
ToolExecutionModes: () => ToolExecutionModes,
|
|
6177
|
+
WorkflowBuilderV1: () => WorkflowBuilderV1,
|
|
8883
6178
|
bindFrom: () => bindFrom,
|
|
8884
6179
|
bindToPlaceholder: () => bindToPlaceholder,
|
|
8885
6180
|
bindToPointer: () => bindToPointer,
|
|
@@ -8892,7 +6187,8 @@ __export(workflow_exports, {
|
|
|
8892
6187
|
whenOutputMatches: () => whenOutputMatches,
|
|
8893
6188
|
whenStatusEquals: () => whenStatusEquals,
|
|
8894
6189
|
whenStatusExists: () => whenStatusExists,
|
|
8895
|
-
whenStatusMatches: () => whenStatusMatches
|
|
6190
|
+
whenStatusMatches: () => whenStatusMatches,
|
|
6191
|
+
workflowV1: () => workflowV1
|
|
8896
6192
|
});
|
|
8897
6193
|
|
|
8898
6194
|
// src/workflow/helpers_v1.ts
|
|
@@ -8984,7 +6280,7 @@ var BindingBuilder = class {
|
|
|
8984
6280
|
};
|
|
8985
6281
|
|
|
8986
6282
|
// src/workflow/patterns_v1.ts
|
|
8987
|
-
function
|
|
6283
|
+
function wireRequest2(req) {
|
|
8988
6284
|
const raw = req;
|
|
8989
6285
|
if (raw && typeof raw === "object") {
|
|
8990
6286
|
if ("input" in raw) {
|
|
@@ -9077,7 +6373,7 @@ var FanoutReduceV1 = class {
|
|
|
9077
6373
|
encoding: "json_string"
|
|
9078
6374
|
}
|
|
9079
6375
|
];
|
|
9080
|
-
const mapperRequest =
|
|
6376
|
+
const mapperRequest = wireRequest2(mapper);
|
|
9081
6377
|
builder = builder.mapFanout(fanoutId, {
|
|
9082
6378
|
items: { from: generatorId, path: itemsPath },
|
|
9083
6379
|
item_bindings: itemBindings,
|
|
@@ -9106,13 +6402,7 @@ var FanoutReduceV1 = class {
|
|
|
9106
6402
|
};
|
|
9107
6403
|
|
|
9108
6404
|
// src/workflow/index.ts
|
|
9109
|
-
var KindV0 = WorkflowKinds.WorkflowV0;
|
|
9110
6405
|
var KindV1 = WorkflowKinds.WorkflowV1;
|
|
9111
|
-
var NodeTypes = {
|
|
9112
|
-
LLMResponses: WorkflowNodeTypes.LLMResponses,
|
|
9113
|
-
JoinAll: WorkflowNodeTypes.JoinAll,
|
|
9114
|
-
TransformJSON: WorkflowNodeTypes.TransformJSON
|
|
9115
|
-
};
|
|
9116
6406
|
var NodeTypesV1 = {
|
|
9117
6407
|
LLMResponses: WorkflowNodeTypesV1.LLMResponses,
|
|
9118
6408
|
RouteSwitch: WorkflowNodeTypesV1.RouteSwitch,
|
|
@@ -9136,9 +6426,6 @@ var ModelRelay = class _ModelRelay {
|
|
|
9136
6426
|
static fromSecretKey(secretKey, options = {}) {
|
|
9137
6427
|
return new _ModelRelay({ ...options, key: parseSecretKey(secretKey) });
|
|
9138
6428
|
}
|
|
9139
|
-
static fromPublishableKey(publishableKey, options = {}) {
|
|
9140
|
-
return new _ModelRelay({ ...options, key: parsePublishableKey(publishableKey) });
|
|
9141
|
-
}
|
|
9142
6429
|
static fromApiKey(apiKey, options = {}) {
|
|
9143
6430
|
return new _ModelRelay({ ...options, key: parseApiKey(apiKey) });
|
|
9144
6431
|
}
|
|
@@ -9167,7 +6454,6 @@ var ModelRelay = class _ModelRelay {
|
|
|
9167
6454
|
const auth = new AuthClient(this.http, {
|
|
9168
6455
|
apiKey,
|
|
9169
6456
|
accessToken,
|
|
9170
|
-
customer: cfg.customer,
|
|
9171
6457
|
tokenProvider
|
|
9172
6458
|
});
|
|
9173
6459
|
this.auth = auth;
|
|
@@ -9185,7 +6471,7 @@ var ModelRelay = class _ModelRelay {
|
|
|
9185
6471
|
});
|
|
9186
6472
|
this.images = new ImagesClient(this.http, auth);
|
|
9187
6473
|
this.sessions = new SessionsClient(this, this.http, auth);
|
|
9188
|
-
this.tiers = new TiersClient(this.http, { apiKey });
|
|
6474
|
+
this.tiers = new TiersClient(this.http, { apiKey, accessToken });
|
|
9189
6475
|
}
|
|
9190
6476
|
forCustomer(customerId) {
|
|
9191
6477
|
return new CustomerScopedModelRelay(this.responses, customerId, this.baseUrl);
|
|
@@ -9201,8 +6487,6 @@ function resolveBaseUrl(override) {
|
|
|
9201
6487
|
AuthClient,
|
|
9202
6488
|
BillingProviders,
|
|
9203
6489
|
BindingTargetError,
|
|
9204
|
-
Chain,
|
|
9205
|
-
ChainBuilder,
|
|
9206
6490
|
ConfigError,
|
|
9207
6491
|
ContentPartTypes,
|
|
9208
6492
|
CustomerResponsesClient,
|
|
@@ -9213,7 +6497,6 @@ function resolveBaseUrl(override) {
|
|
|
9213
6497
|
DEFAULT_CONNECT_TIMEOUT_MS,
|
|
9214
6498
|
DEFAULT_REQUEST_TIMEOUT_MS,
|
|
9215
6499
|
ErrorCodes,
|
|
9216
|
-
FrontendTokenProvider,
|
|
9217
6500
|
ImagesClient,
|
|
9218
6501
|
InputItemTypes,
|
|
9219
6502
|
JoinOutput,
|
|
@@ -9225,29 +6508,21 @@ function resolveBaseUrl(override) {
|
|
|
9225
6508
|
LLMInputPath,
|
|
9226
6509
|
LLMInputSystemText,
|
|
9227
6510
|
LLMInputUserText,
|
|
9228
|
-
LLMNodeBuilder,
|
|
9229
6511
|
LLMOutput,
|
|
9230
6512
|
LLMOutputContentItemPath,
|
|
9231
6513
|
LLMOutputContentPath,
|
|
9232
6514
|
LLMOutputPath,
|
|
9233
6515
|
LLMOutputText,
|
|
9234
|
-
LLMStep,
|
|
9235
6516
|
LLM_TEXT_OUTPUT,
|
|
9236
6517
|
LLM_USER_MESSAGE_TEXT,
|
|
9237
6518
|
LocalSession,
|
|
9238
6519
|
MapFanoutInputError,
|
|
9239
|
-
MapItem,
|
|
9240
|
-
MapReduce,
|
|
9241
|
-
MapReduceBuilder,
|
|
9242
6520
|
MemorySessionStore,
|
|
9243
6521
|
MessageRoles,
|
|
9244
6522
|
ModelRelay,
|
|
9245
6523
|
ModelRelayError,
|
|
9246
|
-
OIDCExchangeTokenProvider,
|
|
9247
6524
|
OutputFormatTypes,
|
|
9248
6525
|
OutputItemTypes,
|
|
9249
|
-
Parallel,
|
|
9250
|
-
ParallelBuilder,
|
|
9251
6526
|
PathEscapeError,
|
|
9252
6527
|
ResponsesClient,
|
|
9253
6528
|
ResponsesStream,
|
|
@@ -9270,15 +6545,13 @@ function resolveBaseUrl(override) {
|
|
|
9270
6545
|
ToolRegistry,
|
|
9271
6546
|
ToolRunner,
|
|
9272
6547
|
ToolTypes,
|
|
9273
|
-
TransformJSONNodeBuilder,
|
|
9274
6548
|
TransportError,
|
|
9275
6549
|
WORKFLOWS_COMPILE_PATH,
|
|
9276
6550
|
WebToolIntents,
|
|
9277
|
-
Workflow,
|
|
9278
|
-
WorkflowBuilderV0,
|
|
9279
6551
|
WorkflowBuilderV1,
|
|
9280
6552
|
WorkflowKinds,
|
|
9281
6553
|
WorkflowNodeTypes,
|
|
6554
|
+
WorkflowNodeTypesV1,
|
|
9282
6555
|
WorkflowValidationError,
|
|
9283
6556
|
WorkflowsClient,
|
|
9284
6557
|
asModelId,
|
|
@@ -9314,17 +6587,10 @@ function resolveBaseUrl(override) {
|
|
|
9314
6587
|
getRetryableErrors,
|
|
9315
6588
|
hasRetryableErrors,
|
|
9316
6589
|
hasToolCalls,
|
|
9317
|
-
isAutoProvisionDisabled,
|
|
9318
|
-
isAutoProvisionMisconfigured,
|
|
9319
|
-
isEmailRequired,
|
|
9320
|
-
isIdentityRequired,
|
|
9321
|
-
isProvisioningError,
|
|
9322
|
-
isPublishableKey,
|
|
9323
6590
|
isSecretKey,
|
|
9324
6591
|
mergeMetrics,
|
|
9325
6592
|
mergeTrace,
|
|
9326
6593
|
modelToString,
|
|
9327
|
-
newWorkflow,
|
|
9328
6594
|
normalizeModelId,
|
|
9329
6595
|
normalizeStopReason,
|
|
9330
6596
|
outputFormatFromZod,
|
|
@@ -9333,33 +6599,22 @@ function resolveBaseUrl(override) {
|
|
|
9333
6599
|
parseNodeId,
|
|
9334
6600
|
parseOutputName,
|
|
9335
6601
|
parsePlanHash,
|
|
9336
|
-
parsePublishableKey,
|
|
9337
6602
|
parseRunId,
|
|
9338
6603
|
parseSecretKey,
|
|
9339
6604
|
parseToolArgs,
|
|
9340
6605
|
parseToolArgsRaw,
|
|
9341
|
-
pollOAuthDeviceToken,
|
|
9342
|
-
pollUntil,
|
|
9343
6606
|
respondToToolCall,
|
|
9344
|
-
runOAuthDeviceFlowForIDToken,
|
|
9345
|
-
startOAuthDeviceAuthorization,
|
|
9346
6607
|
stopReasonToString,
|
|
9347
6608
|
toolChoiceAuto,
|
|
9348
6609
|
toolChoiceNone,
|
|
9349
6610
|
toolChoiceRequired,
|
|
9350
6611
|
toolResultMessage,
|
|
9351
6612
|
transformJSONMerge,
|
|
9352
|
-
transformJSONMergeV1,
|
|
9353
6613
|
transformJSONObject,
|
|
9354
|
-
transformJSONObjectV1,
|
|
9355
6614
|
transformJSONValue,
|
|
9356
|
-
transformJSONValueV1,
|
|
9357
6615
|
tryParseToolArgs,
|
|
9358
6616
|
validateWithZod,
|
|
9359
6617
|
workflow,
|
|
9360
|
-
workflowV0,
|
|
9361
|
-
workflowV0Schema,
|
|
9362
6618
|
workflowV1,
|
|
9363
|
-
workflowV1Schema,
|
|
9364
6619
|
zodToJsonSchema
|
|
9365
6620
|
});
|