@forklaunch/core 3.2.1 → 3.4.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/bin/gateway-mock/routes/payments-context.mjs +260 -0
- package/bin/gateway-mock/routes/payments.mjs +94 -1
- package/lib/agent/agent.d.ts +26 -0
- package/lib/agent/agent.d.ts.map +1 -0
- package/lib/agent/continuation.d.ts +29 -0
- package/lib/agent/continuation.d.ts.map +1 -0
- package/lib/agent/index.d.ts +8 -0
- package/lib/agent/index.d.ts.map +1 -0
- package/lib/agent/index.js +1049 -0
- package/lib/agent/index.js.map +1 -0
- package/lib/agent/index.mjs +1005 -0
- package/lib/agent/index.mjs.map +1 -0
- package/lib/agent/sources.d.ts +27 -0
- package/lib/agent/sources.d.ts.map +1 -0
- package/lib/agent/tools.d.ts +39 -0
- package/lib/agent/tools.d.ts.map +1 -0
- package/lib/agent/types.d.ts +130 -0
- package/lib/agent/types.d.ts.map +1 -0
- package/lib/http/bindRuntimeAuth.d.ts +53 -0
- package/lib/http/bindRuntimeAuth.d.ts.map +1 -0
- package/lib/http/bindRuntimeAuth.test.d.ts +2 -0
- package/lib/http/bindRuntimeAuth.test.d.ts.map +1 -0
- package/lib/http/index.d.ts +3 -0
- package/lib/http/index.d.ts.map +1 -1
- package/lib/http/index.js +487 -114
- package/lib/http/index.js.map +1 -1
- package/lib/http/index.mjs +484 -114
- package/lib/http/index.mjs.map +1 -1
- package/lib/http/localModelGatewayClient.d.ts +27 -0
- package/lib/http/localModelGatewayClient.d.ts.map +1 -0
- package/lib/http/mcpGenerator/mcpGenerator.d.ts.map +1 -1
- package/lib/http/middleware/internal/validationDiagnostic.d.ts +3 -0
- package/lib/http/middleware/internal/validationDiagnostic.d.ts.map +1 -0
- package/lib/http/middleware/request/auth.middleware.d.ts +0 -11
- package/lib/http/middleware/request/auth.middleware.d.ts.map +1 -1
- package/lib/http/middleware/request/parse.middleware.d.ts.map +1 -1
- package/lib/http/middleware/response/enrichExpressLikeSend.middleware.d.ts.map +1 -1
- package/lib/http/middleware/response/parse.middleware.d.ts.map +1 -1
- package/lib/http/modelGatewayClient.d.ts.map +1 -1
- package/lib/http/modelStream.d.ts +4 -0
- package/lib/http/modelStream.d.ts.map +1 -0
- package/lib/http/openApiV3Generator/openApiV3Generator.d.ts.map +1 -1
- package/lib/http/paymentsClient.d.ts +55 -1
- package/lib/http/paymentsClient.d.ts.map +1 -1
- package/lib/http/previewModelGatewayClient.d.ts +5 -1
- package/lib/http/previewModelGatewayClient.d.ts.map +1 -1
- package/lib/http/registerDelegatedSurface.d.ts +28 -0
- package/lib/http/registerDelegatedSurface.d.ts.map +1 -0
- package/lib/http/registerDelegatedSurface.test.d.ts +2 -0
- package/lib/http/registerDelegatedSurface.test.d.ts.map +1 -0
- package/lib/http/router/discriminateBody.d.ts +2 -1
- package/lib/http/router/discriminateBody.d.ts.map +1 -1
- package/lib/http/router/expressLikeRouter.d.ts.map +1 -1
- package/lib/ws/asyncApiV3Generator/asyncApiV3Generator.d.ts.map +1 -1
- package/lib/ws/index.js +94 -8
- package/lib/ws/index.js.map +1 -1
- package/lib/ws/index.mjs +94 -8
- package/lib/ws/index.mjs.map +1 -1
- package/package.json +12 -5
package/lib/http/index.js
CHANGED
|
@@ -66,10 +66,12 @@ __export(http_exports, {
|
|
|
66
66
|
auditComplianceAccess: () => auditComplianceAccess,
|
|
67
67
|
auditEnabled: () => auditEnabled,
|
|
68
68
|
auditEventType: () => auditEventType,
|
|
69
|
+
bindRuntimeAuth: () => bindRuntimeAuth,
|
|
69
70
|
createContext: () => createContext,
|
|
70
71
|
createEmailClient: () => createEmailClient,
|
|
71
72
|
createHmacToken: () => createHmacToken,
|
|
72
73
|
createInstanceGatewayTransport: () => createInstanceGatewayTransport,
|
|
74
|
+
createLocalModelGatewayClient: () => createLocalModelGatewayClient,
|
|
73
75
|
createModelGatewayClient: () => createModelGatewayClient,
|
|
74
76
|
createPaymentsClient: () => createPaymentsClient,
|
|
75
77
|
createPreviewModelGatewayClient: () => createPreviewModelGatewayClient,
|
|
@@ -119,6 +121,7 @@ __export(http_exports, {
|
|
|
119
121
|
put: () => put,
|
|
120
122
|
recordMetric: () => recordMetric,
|
|
121
123
|
recordRequestAudit: () => recordRequestAudit,
|
|
124
|
+
registerDelegatedSurface: () => registerDelegatedSurface,
|
|
122
125
|
resetProcessHandlersForTesting: () => resetProcessHandlersForTesting,
|
|
123
126
|
signPlatformEvent: () => signPlatformEvent,
|
|
124
127
|
smsSegments: () => smsSegments,
|
|
@@ -134,6 +137,68 @@ __export(http_exports, {
|
|
|
134
137
|
});
|
|
135
138
|
module.exports = __toCommonJS(http_exports);
|
|
136
139
|
|
|
140
|
+
// src/http/bindRuntimeAuth.ts
|
|
141
|
+
function bindRuntimeAuth(details, binding) {
|
|
142
|
+
const policy = { ...details.auth };
|
|
143
|
+
const keys = Object.keys(binding);
|
|
144
|
+
const credentials = { ...binding };
|
|
145
|
+
const invalid = () => {
|
|
146
|
+
throw new Error("Invalid runtime authentication binding");
|
|
147
|
+
};
|
|
148
|
+
const allowedPolicy = policy.scheme === "jwt" ? [
|
|
149
|
+
"scheme",
|
|
150
|
+
"headerName",
|
|
151
|
+
"tokenPrefix",
|
|
152
|
+
"sessionSchema",
|
|
153
|
+
"allowedRoles",
|
|
154
|
+
"allowedPermissions"
|
|
155
|
+
] : ["scheme", "headerName", "tokenPrefix"];
|
|
156
|
+
if (Object.keys(policy).some((key) => !allowedPolicy.includes(key)))
|
|
157
|
+
invalid();
|
|
158
|
+
for (const key of ["headerName", "tokenPrefix"]) {
|
|
159
|
+
if (policy[key] !== void 0 && (typeof policy[key] !== "string" || !policy[key]))
|
|
160
|
+
invalid();
|
|
161
|
+
}
|
|
162
|
+
if (policy.scheme === "jwt" && policy.allowedRoles === void 0 && policy.allowedPermissions === void 0)
|
|
163
|
+
invalid();
|
|
164
|
+
let authentication;
|
|
165
|
+
if (policy.scheme === "jwt") {
|
|
166
|
+
if (keys.some(
|
|
167
|
+
(key) => !["jwksPublicKeyUrl", "signatureKey", "decodeResource"].includes(key)
|
|
168
|
+
))
|
|
169
|
+
invalid();
|
|
170
|
+
const keyFields = keys.filter((key) => key !== "decodeResource");
|
|
171
|
+
if (keyFields.length !== 1 || typeof credentials[keyFields[0]] !== "string" || !credentials[keyFields[0]])
|
|
172
|
+
invalid();
|
|
173
|
+
const decodeResource = credentials.decodeResource;
|
|
174
|
+
if (decodeResource !== void 0 && typeof decodeResource !== "function")
|
|
175
|
+
invalid();
|
|
176
|
+
delete credentials.decodeResource;
|
|
177
|
+
authentication = {
|
|
178
|
+
jwt: credentials,
|
|
179
|
+
...decodeResource === void 0 ? {} : { decodeResource }
|
|
180
|
+
};
|
|
181
|
+
} else if (policy.scheme === "hmac") {
|
|
182
|
+
if (keys.length !== 1 || keys[0] !== "secretKeys" || !credentials.secretKeys || typeof credentials.secretKeys !== "object" || Array.isArray(credentials.secretKeys) || Object.keys(credentials.secretKeys).length === 0 || Object.values(credentials.secretKeys).some(
|
|
183
|
+
(key) => typeof key !== "string" || !key
|
|
184
|
+
))
|
|
185
|
+
invalid();
|
|
186
|
+
authentication = { hmac: credentials };
|
|
187
|
+
} else {
|
|
188
|
+
return invalid();
|
|
189
|
+
}
|
|
190
|
+
delete policy.scheme;
|
|
191
|
+
for (const key of ["allowedRoles", "allowedPermissions"]) {
|
|
192
|
+
if (policy[key] !== void 0) {
|
|
193
|
+
const values = policy[key];
|
|
194
|
+
if (!Array.isArray(values) || values.some((value) => typeof value !== "string"))
|
|
195
|
+
invalid();
|
|
196
|
+
policy[key] = new Set(values);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return { ...details, auth: { ...policy, ...authentication } };
|
|
200
|
+
}
|
|
201
|
+
|
|
137
202
|
// src/http/middleware/request/cors.middleware.ts
|
|
138
203
|
var import_cors = __toESM(require("cors"));
|
|
139
204
|
function cors(corsOptions) {
|
|
@@ -594,7 +659,7 @@ function createContext(schemaValidator) {
|
|
|
594
659
|
}
|
|
595
660
|
|
|
596
661
|
// src/http/router/discriminateBody.ts
|
|
597
|
-
function discriminateBody(schemaValidator, body) {
|
|
662
|
+
function discriminateBody(schemaValidator, body, inputProjection) {
|
|
598
663
|
if (body == null) {
|
|
599
664
|
return void 0;
|
|
600
665
|
}
|
|
@@ -644,7 +709,7 @@ function discriminateBody(schemaValidator, body) {
|
|
|
644
709
|
parserType: "text",
|
|
645
710
|
schema: maybeTypedBody
|
|
646
711
|
};
|
|
647
|
-
} else if (schemaValidator.openapi(maybeTypedBody).format === "binary") {
|
|
712
|
+
} else if ((inputProjection ?? schemaValidator.openapi(maybeTypedBody)).format === "binary") {
|
|
648
713
|
return {
|
|
649
714
|
contentType: "application/octet-stream",
|
|
650
715
|
parserType: "file",
|
|
@@ -1074,15 +1139,23 @@ async function checkAuthorizationToken(req, authorizationMethod, authorizationTo
|
|
|
1074
1139
|
if (!parsedKeyId || !parsedTimestamp || !parsedNonce || !parsedSignature) {
|
|
1075
1140
|
return invalidAuthorizationTokenFormat;
|
|
1076
1141
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1142
|
+
let verificationResult = false;
|
|
1143
|
+
const signedPaths = hmacSignedPaths(req);
|
|
1144
|
+
for (const path of signedPaths) {
|
|
1145
|
+
verificationResult = Boolean(await auth.verificationFunction({
|
|
1146
|
+
method: req?.method ?? "",
|
|
1147
|
+
path,
|
|
1148
|
+
body: req?._rawBody ?? req?.body,
|
|
1149
|
+
timestamp: new Date(parsedTimestamp),
|
|
1150
|
+
nonce: parsedNonce,
|
|
1151
|
+
signature: parsedSignature,
|
|
1152
|
+
secretKey: collapsedAuthorizationMethod.hmac.secretKeys[parsedKeyId]
|
|
1153
|
+
}));
|
|
1154
|
+
if (verificationResult) {
|
|
1155
|
+
if (path !== signedPaths[0]) warnMountRelativeHmacPath();
|
|
1156
|
+
break;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1086
1159
|
if (!verificationResult) {
|
|
1087
1160
|
return invalidAuthorizationSignature;
|
|
1088
1161
|
}
|
|
@@ -1249,6 +1322,25 @@ async function checkAuthorizationToken(req, authorizationMethod, authorizationTo
|
|
|
1249
1322
|
}
|
|
1250
1323
|
}
|
|
1251
1324
|
}
|
|
1325
|
+
function acceptMountRelativeHmacPaths() {
|
|
1326
|
+
const value = typeof process === "undefined" ? void 0 : process.env?.HMAC_ACCEPT_MOUNT_RELATIVE_PATHS;
|
|
1327
|
+
return value == null || !["false", "0"].includes(value.trim().toLowerCase());
|
|
1328
|
+
}
|
|
1329
|
+
var warnedMountRelativeHmacPath = false;
|
|
1330
|
+
function warnMountRelativeHmacPath() {
|
|
1331
|
+
if (warnedMountRelativeHmacPath) return;
|
|
1332
|
+
warnedMountRelativeHmacPath = true;
|
|
1333
|
+
console.warn(
|
|
1334
|
+
"Accepted an HMAC signature over the router-relative path. Sign the full request path instead; set HMAC_ACCEPT_MOUNT_RELATIVE_PATHS=false to reject the deprecated form."
|
|
1335
|
+
);
|
|
1336
|
+
}
|
|
1337
|
+
function hmacSignedPaths(req) {
|
|
1338
|
+
const relative = req?.path ?? "";
|
|
1339
|
+
const wire = (req?.originalUrl ?? req?.url ?? relative).split("?")[0] || relative;
|
|
1340
|
+
const paths = [wire];
|
|
1341
|
+
if (relative !== wire && acceptMountRelativeHmacPaths()) paths.push(relative);
|
|
1342
|
+
return paths;
|
|
1343
|
+
}
|
|
1252
1344
|
async function parseRequestAuth(req, res, next) {
|
|
1253
1345
|
const access = req.contractDetails.access;
|
|
1254
1346
|
if (access === "public") {
|
|
@@ -1482,6 +1574,21 @@ function isRequestShape(maybeResponseShape) {
|
|
|
1482
1574
|
return maybeResponseShape != null && ("body" in maybeResponseShape || "query" in maybeResponseShape || "params" in maybeResponseShape || "headers" in maybeResponseShape);
|
|
1483
1575
|
}
|
|
1484
1576
|
|
|
1577
|
+
// src/http/middleware/internal/validationDiagnostic.ts
|
|
1578
|
+
var sendingDiagnostics = /* @__PURE__ */ new WeakSet();
|
|
1579
|
+
function isValidationDiagnostic(response) {
|
|
1580
|
+
return sendingDiagnostics.has(response);
|
|
1581
|
+
}
|
|
1582
|
+
function sendValidationDiagnostic(response, send) {
|
|
1583
|
+
const alreadySending = sendingDiagnostics.has(response);
|
|
1584
|
+
sendingDiagnostics.add(response);
|
|
1585
|
+
try {
|
|
1586
|
+
return send();
|
|
1587
|
+
} finally {
|
|
1588
|
+
if (!alreadySending) sendingDiagnostics.delete(response);
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1485
1592
|
// src/http/middleware/request/parse.middleware.ts
|
|
1486
1593
|
function parse(req, res, next) {
|
|
1487
1594
|
const globalOptions = req._globalOptions?.();
|
|
@@ -1563,14 +1670,13 @@ function parse(req, res, next) {
|
|
|
1563
1670
|
default:
|
|
1564
1671
|
case void 0:
|
|
1565
1672
|
case "error":
|
|
1566
|
-
res.type("
|
|
1673
|
+
res.type("text/plain");
|
|
1567
1674
|
res.status(400);
|
|
1568
1675
|
if (hasSend(res)) {
|
|
1569
|
-
|
|
1570
|
-
`${collectedParseErrors ?? (0, import_validator2.prettyPrintParseErrors)(parsedRequest.errors, "Request")}
|
|
1676
|
+
const diagnostic = `${collectedParseErrors ?? (0, import_validator2.prettyPrintParseErrors)(parsedRequest.errors, "Request")}
|
|
1571
1677
|
|
|
1572
|
-
Correlation id: ${req.context.correlationId ?? "No correlation ID"}
|
|
1573
|
-
);
|
|
1678
|
+
Correlation id: ${req.context.correlationId ?? "No correlation ID"}`;
|
|
1679
|
+
sendValidationDiagnostic(res, () => res.send(diagnostic));
|
|
1574
1680
|
} else {
|
|
1575
1681
|
next?.(new Error("Request is not sendable."));
|
|
1576
1682
|
}
|
|
@@ -1979,13 +2085,25 @@ var ForklaunchExpressLikeRouter = class _ForklaunchExpressLikeRouter {
|
|
|
1979
2085
|
span: void 0
|
|
1980
2086
|
},
|
|
1981
2087
|
_rawBody: void 0,
|
|
1982
|
-
_parsedVersions: void 0
|
|
2088
|
+
_parsedVersions: void 0,
|
|
2089
|
+
// hyper-express's content parser reads the body through its Request's
|
|
2090
|
+
// body readers; serve the body the call was given.
|
|
2091
|
+
buffer: async () => Buffer.from(
|
|
2092
|
+
typeof req.body === "string" ? req.body : JSON.stringify(req.body)
|
|
2093
|
+
),
|
|
2094
|
+
json: async () => req.body,
|
|
2095
|
+
text: async () => typeof req.body === "string" ? req.body : JSON.stringify(req.body)
|
|
1983
2096
|
};
|
|
1984
2097
|
const res = {
|
|
1985
2098
|
statusCode: 200,
|
|
2099
|
+
// hyper-express's response enrichment reads the status and headers
|
|
2100
|
+
// from these fields, which its own Response keeps.
|
|
2101
|
+
_status_code: 200,
|
|
2102
|
+
_headers: responseHeaders,
|
|
1986
2103
|
status: (code) => {
|
|
1987
2104
|
statusCode = code;
|
|
1988
2105
|
res.statusCode = code;
|
|
2106
|
+
res._status_code = code;
|
|
1989
2107
|
return res;
|
|
1990
2108
|
},
|
|
1991
2109
|
send: (message) => {
|
|
@@ -2005,6 +2123,8 @@ var ForklaunchExpressLikeRouter = class _ForklaunchExpressLikeRouter {
|
|
|
2005
2123
|
return res;
|
|
2006
2124
|
},
|
|
2007
2125
|
getHeader: (key) => responseHeaders[key],
|
|
2126
|
+
getHeaders: () => ({ ...responseHeaders }),
|
|
2127
|
+
locals: {},
|
|
2008
2128
|
type: (contentType) => {
|
|
2009
2129
|
responseHeaders["content-type"] = contentType;
|
|
2010
2130
|
return res;
|
|
@@ -2023,31 +2143,59 @@ var ForklaunchExpressLikeRouter = class _ForklaunchExpressLikeRouter {
|
|
|
2023
2143
|
version
|
|
2024
2144
|
};
|
|
2025
2145
|
const executeMiddlewares = request?.executeMiddlewares ?? false;
|
|
2146
|
+
const cHandler = controllerHandler;
|
|
2026
2147
|
if (executeMiddlewares && middlewares.length > 0) {
|
|
2027
|
-
const
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2148
|
+
const chain = middlewares;
|
|
2149
|
+
await new Promise((resolve, reject) => {
|
|
2150
|
+
let settled = false;
|
|
2151
|
+
let responded = false;
|
|
2152
|
+
let controllerStarted = false;
|
|
2153
|
+
const finish = (error) => {
|
|
2154
|
+
if (settled) return;
|
|
2155
|
+
settled = true;
|
|
2156
|
+
if (error) reject(error);
|
|
2157
|
+
else resolve();
|
|
2158
|
+
};
|
|
2159
|
+
res.on("finish", () => {
|
|
2160
|
+
responded = true;
|
|
2161
|
+
if (!controllerStarted) finish();
|
|
2162
|
+
});
|
|
2163
|
+
const run = async (index) => {
|
|
2164
|
+
try {
|
|
2165
|
+
if (index === chain.length) {
|
|
2166
|
+
controllerStarted = true;
|
|
2167
|
+
await cHandler(req, res, (err) => {
|
|
2168
|
+
if (err) {
|
|
2169
|
+
throw err;
|
|
2170
|
+
}
|
|
2171
|
+
});
|
|
2172
|
+
finish();
|
|
2173
|
+
return;
|
|
2034
2174
|
}
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2175
|
+
let calledNext = false;
|
|
2176
|
+
await chain[index](req, res, (err) => {
|
|
2177
|
+
calledNext = true;
|
|
2178
|
+
if (err) {
|
|
2179
|
+
throw err;
|
|
2180
|
+
}
|
|
2181
|
+
return run(index + 1);
|
|
2182
|
+
});
|
|
2183
|
+
if (!calledNext && chain[index].length < 3 && !responded) {
|
|
2184
|
+
await run(index + 1);
|
|
2185
|
+
}
|
|
2186
|
+
} catch (error) {
|
|
2187
|
+
finish(error);
|
|
2041
2188
|
}
|
|
2042
|
-
}
|
|
2043
|
-
|
|
2189
|
+
};
|
|
2190
|
+
void run(0);
|
|
2191
|
+
});
|
|
2192
|
+
} else {
|
|
2193
|
+
await cHandler(req, res, (err) => {
|
|
2194
|
+
if (err) {
|
|
2195
|
+
throw err;
|
|
2196
|
+
}
|
|
2197
|
+
});
|
|
2044
2198
|
}
|
|
2045
|
-
const cHandler = controllerHandler;
|
|
2046
|
-
await cHandler(req, res, (err) => {
|
|
2047
|
-
if (err) {
|
|
2048
|
-
throw err;
|
|
2049
|
-
}
|
|
2050
|
-
});
|
|
2051
2199
|
return {
|
|
2052
2200
|
code: Number(statusCode),
|
|
2053
2201
|
response: responseMessage,
|
|
@@ -2831,12 +2979,55 @@ function signPlatformEvent(params) {
|
|
|
2831
2979
|
});
|
|
2832
2980
|
}
|
|
2833
2981
|
|
|
2982
|
+
// src/http/modelStream.ts
|
|
2983
|
+
async function* readModelStream(response) {
|
|
2984
|
+
const reader = response.body?.getReader();
|
|
2985
|
+
if (!reader)
|
|
2986
|
+
throw new ModelGatewayRequestError(502, "The model stream is empty.");
|
|
2987
|
+
const decoder = new TextDecoder();
|
|
2988
|
+
let buffer = "", bytes = 0;
|
|
2989
|
+
try {
|
|
2990
|
+
for (; ; ) {
|
|
2991
|
+
const part = await reader.read();
|
|
2992
|
+
if (part.done) break;
|
|
2993
|
+
bytes += part.value.byteLength;
|
|
2994
|
+
if (bytes > 512e3) throw new Error("oversized");
|
|
2995
|
+
buffer += decoder.decode(part.value, { stream: true });
|
|
2996
|
+
let match;
|
|
2997
|
+
while (match = buffer.match(/\r?\n\r?\n/)) {
|
|
2998
|
+
const event = buffer.slice(0, match.index);
|
|
2999
|
+
buffer = buffer.slice(match.index + match[0].length);
|
|
3000
|
+
const data = event.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
|
|
3001
|
+
if (!data) continue;
|
|
3002
|
+
if (data === "[DONE]") return;
|
|
3003
|
+
const value = JSON.parse(data);
|
|
3004
|
+
if (value.error || !Array.isArray(value.choices))
|
|
3005
|
+
throw new Error("invalid");
|
|
3006
|
+
yield value;
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
throw new Error("interrupted");
|
|
3010
|
+
} catch {
|
|
3011
|
+
throw new ModelGatewayRequestError(
|
|
3012
|
+
502,
|
|
3013
|
+
"The model stream was interrupted. No automatic retry was sent."
|
|
3014
|
+
);
|
|
3015
|
+
} finally {
|
|
3016
|
+
await reader.cancel().catch(() => {
|
|
3017
|
+
});
|
|
3018
|
+
reader.releaseLock();
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
|
|
2834
3022
|
// src/http/modelGatewayClient.ts
|
|
2835
3023
|
var ModelGatewayRequestError = class extends InstanceGatewayRequestError {
|
|
2836
3024
|
name = "ModelGatewayRequestError";
|
|
2837
3025
|
};
|
|
2838
3026
|
function createModelGatewayClient(options2 = {}) {
|
|
2839
|
-
const transport = createInstanceGatewayTransport(
|
|
3027
|
+
const transport = createInstanceGatewayTransport(
|
|
3028
|
+
options2,
|
|
3029
|
+
"The model gateway"
|
|
3030
|
+
);
|
|
2840
3031
|
async function send(method, route, body, signal) {
|
|
2841
3032
|
try {
|
|
2842
3033
|
return await transport.request(method, route, body, { signal });
|
|
@@ -2872,42 +3063,12 @@ function createModelGatewayClient(options2 = {}) {
|
|
|
2872
3063
|
request,
|
|
2873
3064
|
streamOptions.signal
|
|
2874
3065
|
);
|
|
2875
|
-
|
|
2876
|
-
for await (const data of sseData(response.body)) {
|
|
2877
|
-
if (data === "[DONE]") return;
|
|
2878
|
-
try {
|
|
2879
|
-
yield JSON.parse(data);
|
|
2880
|
-
} catch {
|
|
2881
|
-
}
|
|
2882
|
-
}
|
|
3066
|
+
yield* readModelStream(response);
|
|
2883
3067
|
}
|
|
2884
3068
|
}
|
|
2885
3069
|
}
|
|
2886
3070
|
};
|
|
2887
3071
|
}
|
|
2888
|
-
async function* sseData(stream) {
|
|
2889
|
-
const decoder = new TextDecoder();
|
|
2890
|
-
let buffer = "";
|
|
2891
|
-
const reader = stream.getReader();
|
|
2892
|
-
try {
|
|
2893
|
-
for (; ; ) {
|
|
2894
|
-
const { value, done } = await reader.read();
|
|
2895
|
-
if (done) break;
|
|
2896
|
-
buffer += decoder.decode(value, { stream: true });
|
|
2897
|
-
let boundary;
|
|
2898
|
-
while ((boundary = buffer.search(/\r?\n\r?\n/)) !== -1) {
|
|
2899
|
-
const event = buffer.slice(0, boundary);
|
|
2900
|
-
buffer = buffer.slice(boundary).replace(/^\r?\n\r?\n/, "");
|
|
2901
|
-
const data = event.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
|
|
2902
|
-
if (data) yield data;
|
|
2903
|
-
}
|
|
2904
|
-
}
|
|
2905
|
-
const tail = buffer.trim();
|
|
2906
|
-
if (tail.startsWith("data:")) yield tail.slice(5).trimStart();
|
|
2907
|
-
} finally {
|
|
2908
|
-
reader.releaseLock();
|
|
2909
|
-
}
|
|
2910
|
-
}
|
|
2911
3072
|
|
|
2912
3073
|
// src/http/previewModelGatewayClient.ts
|
|
2913
3074
|
function record(value) {
|
|
@@ -2963,9 +3124,9 @@ function createPreviewModelGatewayClient(options2 = {}) {
|
|
|
2963
3124
|
options2,
|
|
2964
3125
|
"The local preview model gateway"
|
|
2965
3126
|
);
|
|
2966
|
-
async function send(method, route, body) {
|
|
3127
|
+
async function send(method, route, body, signal) {
|
|
2967
3128
|
try {
|
|
2968
|
-
return await transport.request(method, route, body);
|
|
3129
|
+
return await transport.request(method, route, body, { signal });
|
|
2969
3130
|
} catch (error) {
|
|
2970
3131
|
if (error instanceof InstanceGatewayRequestError)
|
|
2971
3132
|
throw new ModelGatewayRequestError(
|
|
@@ -2983,6 +3144,15 @@ function createPreviewModelGatewayClient(options2 = {}) {
|
|
|
2983
3144
|
},
|
|
2984
3145
|
chat: {
|
|
2985
3146
|
completions: {
|
|
3147
|
+
async *stream(request, options3 = {}) {
|
|
3148
|
+
const response = await send(
|
|
3149
|
+
"POST",
|
|
3150
|
+
"/models/chat/completions",
|
|
3151
|
+
{ ...request, stream: true },
|
|
3152
|
+
options3.signal
|
|
3153
|
+
);
|
|
3154
|
+
yield* readModelStream(response);
|
|
3155
|
+
},
|
|
2986
3156
|
async create(request) {
|
|
2987
3157
|
return await (await send(
|
|
2988
3158
|
"POST",
|
|
@@ -3517,6 +3687,19 @@ function createPaymentsClient(options2 = {}) {
|
|
|
3517
3687
|
},
|
|
3518
3688
|
status() {
|
|
3519
3689
|
return call("GET", "/payments/status");
|
|
3690
|
+
},
|
|
3691
|
+
payouts(params = {}) {
|
|
3692
|
+
const { limit } = params;
|
|
3693
|
+
if (limit !== void 0 && (!Number.isInteger(limit) || limit < 1 || limit > 50)) {
|
|
3694
|
+
throw new TypeError("limit must be a whole number from 1 to 50");
|
|
3695
|
+
}
|
|
3696
|
+
return call(
|
|
3697
|
+
"GET",
|
|
3698
|
+
limit === void 0 ? "/payments/payouts" : `/payments/payouts?limit=${limit}`
|
|
3699
|
+
);
|
|
3700
|
+
},
|
|
3701
|
+
dashboardLink() {
|
|
3702
|
+
return call("POST", "/payments/dashboard-link", {});
|
|
3520
3703
|
}
|
|
3521
3704
|
};
|
|
3522
3705
|
}
|
|
@@ -3536,7 +3719,7 @@ function loadStripe() {
|
|
|
3536
3719
|
function stripeGatewayFetch(settings, fetchImpl = fetch) {
|
|
3537
3720
|
const base = new URL(settings.gatewayUrl);
|
|
3538
3721
|
const basePath = base.pathname.replace(/\/+$/, "");
|
|
3539
|
-
|
|
3722
|
+
const signedFetch = async (input, init = {}) => {
|
|
3540
3723
|
const original = new URL(
|
|
3541
3724
|
typeof input === "string" || input instanceof URL ? input : input.url
|
|
3542
3725
|
);
|
|
@@ -3576,6 +3759,13 @@ function stripeGatewayFetch(settings, fetchImpl = fetch) {
|
|
|
3576
3759
|
}
|
|
3577
3760
|
);
|
|
3578
3761
|
};
|
|
3762
|
+
const preconnect = Reflect.get(fetchImpl, "preconnect");
|
|
3763
|
+
if (typeof preconnect === "function") {
|
|
3764
|
+
Object.defineProperty(signedFetch, "preconnect", {
|
|
3765
|
+
value: (_input, options2) => Reflect.apply(preconnect, fetchImpl, [base.origin, options2])
|
|
3766
|
+
});
|
|
3767
|
+
}
|
|
3768
|
+
return signedFetch;
|
|
3579
3769
|
}
|
|
3580
3770
|
function createStripeClient(options2 = {}) {
|
|
3581
3771
|
const StripeClass = options2.Stripe ?? loadStripe();
|
|
@@ -3594,8 +3784,8 @@ function createStripeClient(options2 = {}) {
|
|
|
3594
3784
|
return new StripeClass(options2.apiKey, options2.config);
|
|
3595
3785
|
}
|
|
3596
3786
|
const settings = instanceGatewaySettings(options2, "Payments");
|
|
3597
|
-
const
|
|
3598
|
-
const protocol =
|
|
3787
|
+
const gateway2 = new URL(settings.gatewayUrl);
|
|
3788
|
+
const protocol = gateway2.protocol === "http:" ? "http" : "https";
|
|
3599
3789
|
return new StripeClass(
|
|
3600
3790
|
// No key: the authenticator below replaces it, and the gateway holds the
|
|
3601
3791
|
// real one. (stripe-node accepts an authenticator in place of a key.)
|
|
@@ -3603,8 +3793,8 @@ function createStripeClient(options2 = {}) {
|
|
|
3603
3793
|
{
|
|
3604
3794
|
maxNetworkRetries: 2,
|
|
3605
3795
|
...options2.config,
|
|
3606
|
-
host:
|
|
3607
|
-
port:
|
|
3796
|
+
host: gateway2.hostname,
|
|
3797
|
+
port: gateway2.port || (protocol === "http" ? 80 : 443),
|
|
3608
3798
|
protocol,
|
|
3609
3799
|
telemetry: false,
|
|
3610
3800
|
// The signed fetch sets `authorization`; nothing else may.
|
|
@@ -4808,10 +4998,10 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, appli
|
|
|
4808
4998
|
let bodySchema;
|
|
4809
4999
|
let responsesSchemas;
|
|
4810
5000
|
if (route.contractDetails.versions) {
|
|
4811
|
-
const version2 = route.contractDetails.versions[index];
|
|
5001
|
+
const version2 = Object.values(route.contractDetails.versions)[index];
|
|
5002
|
+
responsesSchemas = version2.responses;
|
|
4812
5003
|
if (version2.body && schemaValidator.parse(inputSchema, args).ok) {
|
|
4813
5004
|
bodySchema = version2.body;
|
|
4814
|
-
responsesSchemas = version2.responses;
|
|
4815
5005
|
}
|
|
4816
5006
|
} else {
|
|
4817
5007
|
bodySchema = route.contractDetails.body;
|
|
@@ -4822,7 +5012,7 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, appli
|
|
|
4822
5012
|
if (discriminatedBody) {
|
|
4823
5013
|
switch (discriminatedBody.parserType) {
|
|
4824
5014
|
case "json": {
|
|
4825
|
-
parsedBody =
|
|
5015
|
+
parsedBody = body === void 0 ? void 0 : JSON.stringify(body);
|
|
4826
5016
|
break;
|
|
4827
5017
|
}
|
|
4828
5018
|
case "text": {
|
|
@@ -4888,11 +5078,11 @@ function generateMcpServer(schemaValidator, protocol, host, port, version, appli
|
|
|
4888
5078
|
).toString();
|
|
4889
5079
|
url += queryString ? `?${queryString}` : "";
|
|
4890
5080
|
}
|
|
4891
|
-
const response = await fetch(
|
|
5081
|
+
const response = await fetch(url, {
|
|
4892
5082
|
method: route.method.toUpperCase(),
|
|
4893
5083
|
headers: {
|
|
4894
5084
|
...headers,
|
|
4895
|
-
...discriminatedBody?.contentType != "multipart/form-data" ? {
|
|
5085
|
+
...discriminatedBody?.contentType != "multipart/form-data" && (contentType ?? discriminatedBody?.contentType) !== void 0 ? {
|
|
4896
5086
|
"Content-Type": contentType ?? discriminatedBody?.contentType
|
|
4897
5087
|
} : {}
|
|
4898
5088
|
},
|
|
@@ -4970,7 +5160,12 @@ function isResponseCompiledSchema(schema) {
|
|
|
4970
5160
|
}
|
|
4971
5161
|
|
|
4972
5162
|
// src/http/middleware/response/parse.middleware.ts
|
|
5163
|
+
var sendingValidationError = /* @__PURE__ */ new WeakSet();
|
|
4973
5164
|
function parse2(req, res, next) {
|
|
5165
|
+
if (sendingValidationError.has(res)) {
|
|
5166
|
+
next?.();
|
|
5167
|
+
return;
|
|
5168
|
+
}
|
|
4974
5169
|
let headers;
|
|
4975
5170
|
let responses;
|
|
4976
5171
|
const globalOptions = req._globalOptions?.();
|
|
@@ -5013,15 +5208,35 @@ function parse2(req, res, next) {
|
|
|
5013
5208
|
responses = responseSchemas.responses;
|
|
5014
5209
|
}
|
|
5015
5210
|
const statusCode = Number(res.statusCode);
|
|
5016
|
-
const
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5211
|
+
const defaultErrorStatus = [400, 401, 404, 403, 500].includes(statusCode);
|
|
5212
|
+
const missingResponseSchema = !defaultErrorStatus && !Object.prototype.hasOwnProperty.call(responses, statusCode);
|
|
5213
|
+
if (missingResponseSchema && collapsedOptions !== "warning") {
|
|
5214
|
+
throw new Error(`Undocumented response status ${statusCode}`);
|
|
5215
|
+
}
|
|
5216
|
+
const declaredResponse = responses?.[statusCode];
|
|
5217
|
+
const defaultErrorResponse = () => {
|
|
5218
|
+
try {
|
|
5219
|
+
return schemaValidator.parse(
|
|
5220
|
+
schemaValidator.union([schemaValidator.string, declaredResponse]),
|
|
5221
|
+
res.bodyData
|
|
5222
|
+
);
|
|
5223
|
+
} catch (error) {
|
|
5224
|
+
if (declaredResponse === void 0) throw error;
|
|
5225
|
+
const declared = schemaValidator.parse(declaredResponse, res.bodyData);
|
|
5226
|
+
if (declared.ok) return declared;
|
|
5227
|
+
const message = schemaValidator.parse(
|
|
5228
|
+
schemaValidator.string,
|
|
5229
|
+
res.bodyData
|
|
5230
|
+
);
|
|
5231
|
+
return message.ok ? message : declared;
|
|
5232
|
+
}
|
|
5233
|
+
};
|
|
5234
|
+
const parsedResponse = missingResponseSchema ? { ok: true } : defaultErrorStatus ? defaultErrorResponse() : schemaValidator.parse(declaredResponse, res.bodyData);
|
|
5020
5235
|
const parsedHeaders = schemaValidator.parse(
|
|
5021
5236
|
headers ?? schemaValidator.unknown,
|
|
5022
5237
|
res.getHeaders()
|
|
5023
5238
|
);
|
|
5024
|
-
const parseErrors = [];
|
|
5239
|
+
const parseErrors = missingResponseSchema ? [`Response: Undocumented response status ${statusCode}`] : [];
|
|
5025
5240
|
if (!parsedHeaders.ok) {
|
|
5026
5241
|
const headerErrors = (0, import_validator3.prettyPrintParseErrors)(parsedHeaders.errors, "Header");
|
|
5027
5242
|
if (headerErrors) {
|
|
@@ -5038,21 +5253,26 @@ function parse2(req, res, next) {
|
|
|
5038
5253
|
}
|
|
5039
5254
|
}
|
|
5040
5255
|
if (parseErrors.length > 0) {
|
|
5041
|
-
switch (
|
|
5256
|
+
switch (collapsedOptions) {
|
|
5042
5257
|
default:
|
|
5043
5258
|
case void 0:
|
|
5044
5259
|
case "error":
|
|
5045
5260
|
res.type("text/plain");
|
|
5046
5261
|
res.status(500);
|
|
5047
5262
|
if (hasSend(res)) {
|
|
5048
|
-
|
|
5049
|
-
|
|
5263
|
+
sendingValidationError.add(res);
|
|
5264
|
+
try {
|
|
5265
|
+
res.send(
|
|
5266
|
+
`Invalid response:
|
|
5050
5267
|
${parseErrors.join(
|
|
5051
|
-
|
|
5052
|
-
|
|
5268
|
+
"\n\n"
|
|
5269
|
+
)}
|
|
5053
5270
|
|
|
5054
5271
|
Correlation id: ${req.context.correlationId ?? "No correlation ID"}`
|
|
5055
|
-
|
|
5272
|
+
);
|
|
5273
|
+
} finally {
|
|
5274
|
+
sendingValidationError.delete(res);
|
|
5275
|
+
}
|
|
5056
5276
|
} else {
|
|
5057
5277
|
next?.(new Error("Response is not sendable."));
|
|
5058
5278
|
}
|
|
@@ -5063,8 +5283,6 @@ Correlation id: ${req.context.correlationId ?? "No correlation ID"}`
|
|
|
5063
5283
|
${parseErrors.join("\n\n")}`
|
|
5064
5284
|
);
|
|
5065
5285
|
break;
|
|
5066
|
-
case "none":
|
|
5067
|
-
break;
|
|
5068
5286
|
}
|
|
5069
5287
|
}
|
|
5070
5288
|
next?.();
|
|
@@ -5106,6 +5324,10 @@ function enrichExpressLikeSend(instance, req, res, originalOperation, originalSe
|
|
|
5106
5324
|
originalSend.call(instance, data);
|
|
5107
5325
|
return;
|
|
5108
5326
|
}
|
|
5327
|
+
if (typeof data === "string" && isValidationDiagnostic(res)) {
|
|
5328
|
+
originalSend.call(instance, data);
|
|
5329
|
+
return;
|
|
5330
|
+
}
|
|
5109
5331
|
let responses;
|
|
5110
5332
|
if (req.contractDetails.responses == null && (req.contractDetails.versions == null || Object.values(req.contractDetails.versions).some(
|
|
5111
5333
|
(version) => version?.responses == null
|
|
@@ -5115,7 +5337,7 @@ function enrichExpressLikeSend(instance, req, res, originalOperation, originalSe
|
|
|
5115
5337
|
if (req.contractDetails.responses != null) {
|
|
5116
5338
|
responses = req.contractDetails.responses;
|
|
5117
5339
|
} else {
|
|
5118
|
-
responses = req.contractDetails.versions[req.version]
|
|
5340
|
+
responses = req.contractDetails.versions[req.version]?.responses ?? {};
|
|
5119
5341
|
}
|
|
5120
5342
|
}
|
|
5121
5343
|
const responseBodies = discriminateResponseBodies(
|
|
@@ -5337,7 +5559,16 @@ function generateOperationObject(schemaValidator, path, method, controllerName,
|
|
|
5337
5559
|
for (const key in discriminatedResponseBodiesResult) {
|
|
5338
5560
|
coercedResponses[key] = {
|
|
5339
5561
|
description: httpStatusCodes_default[key],
|
|
5340
|
-
|
|
5562
|
+
// Undefined/void represent no response body, not a JSON null payload.
|
|
5563
|
+
// Check the schema kind rather than its OpenAPI projection: null and
|
|
5564
|
+
// nullish also project to null but still admit an actual JSON body.
|
|
5565
|
+
content: schemaValidator.undefined !== void 0 && typedSchemaValidator.isInstanceOf(
|
|
5566
|
+
discriminatedResponseBodiesResult[key].schema,
|
|
5567
|
+
schemaValidator.undefined
|
|
5568
|
+
) || schemaValidator.void !== void 0 && typedSchemaValidator.isInstanceOf(
|
|
5569
|
+
discriminatedResponseBodiesResult[key].schema,
|
|
5570
|
+
schemaValidator.void
|
|
5571
|
+
) ? void 0 : contentResolver(
|
|
5341
5572
|
schemaValidator,
|
|
5342
5573
|
discriminatedResponseBodiesResult[key].schema,
|
|
5343
5574
|
discriminatedResponseBodiesResult[key].contentType
|
|
@@ -5373,15 +5604,21 @@ function generateOperationObject(schemaValidator, path, method, controllerName,
|
|
|
5373
5604
|
operationObject.parameters?.push({
|
|
5374
5605
|
name: key,
|
|
5375
5606
|
in: "path",
|
|
5607
|
+
required: true,
|
|
5376
5608
|
schema: typedSchemaValidator.openapi(params[key])
|
|
5377
5609
|
});
|
|
5378
5610
|
}
|
|
5379
5611
|
}
|
|
5380
|
-
const
|
|
5612
|
+
const adapter = schemaValidator;
|
|
5613
|
+
const bareProjection = body && adapter.isSchema(body) ? adapter.openapiRequestBody?.(body) : void 0;
|
|
5614
|
+
const discriminatedBodyResult = body ? discriminateBody(schemaValidator, body, bareProjection?.schema) : null;
|
|
5381
5615
|
if (discriminatedBodyResult) {
|
|
5616
|
+
const projection = bareProjection ?? adapter.openapiRequestBody?.(discriminatedBodyResult.schema);
|
|
5382
5617
|
operationObject.requestBody = {
|
|
5383
|
-
required: true,
|
|
5384
|
-
content:
|
|
5618
|
+
required: projection?.required ?? true,
|
|
5619
|
+
content: projection ? {
|
|
5620
|
+
[discriminatedBodyResult.contentType]: { schema: projection.schema }
|
|
5621
|
+
} : contentResolver(
|
|
5385
5622
|
schemaValidator,
|
|
5386
5623
|
discriminatedBodyResult.schema,
|
|
5387
5624
|
discriminatedBodyResult.contentType
|
|
@@ -5416,25 +5653,14 @@ function generateOperationObject(schemaValidator, path, method, controllerName,
|
|
|
5416
5653
|
content: contentResolver(schemaValidator, schemaValidator.string)
|
|
5417
5654
|
};
|
|
5418
5655
|
if ("basic" in auth) {
|
|
5419
|
-
operationObject.security = [
|
|
5420
|
-
{
|
|
5421
|
-
basic: Array.from(
|
|
5422
|
-
"allowedPermissions" in auth && auth.allowedPermissions instanceof Set ? auth.allowedPermissions.values() : []
|
|
5423
|
-
)
|
|
5424
|
-
}
|
|
5425
|
-
];
|
|
5656
|
+
operationObject.security = [{ basic: [] }];
|
|
5426
5657
|
securitySchemes["basic"] = {
|
|
5427
5658
|
type: "http",
|
|
5428
5659
|
scheme: "basic"
|
|
5429
5660
|
};
|
|
5430
5661
|
} else if (auth) {
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
[auth.headerName !== "Authorization" ? "bearer" : "apiKey"]: Array.from(
|
|
5434
|
-
"allowedPermissions" in auth && auth.allowedPermissions instanceof Set ? auth.allowedPermissions.values() : []
|
|
5435
|
-
)
|
|
5436
|
-
}
|
|
5437
|
-
];
|
|
5662
|
+
const schemeName = auth.headerName || "Authorization";
|
|
5663
|
+
operationObject.security = [{ [schemeName]: [] }];
|
|
5438
5664
|
if (auth.headerName && auth.headerName !== "Authorization") {
|
|
5439
5665
|
securitySchemes[auth.headerName] = {
|
|
5440
5666
|
type: "apiKey",
|
|
@@ -5665,6 +5891,150 @@ var RateLimiter = class {
|
|
|
5665
5891
|
return READ_METHODS.has(method.toUpperCase()) ? "read" : "write";
|
|
5666
5892
|
}
|
|
5667
5893
|
};
|
|
5894
|
+
|
|
5895
|
+
// src/http/registerDelegatedSurface.ts
|
|
5896
|
+
function registerDelegatedSurface(surface, mount, register) {
|
|
5897
|
+
if (!surface.id || !surface.provider || surface.coverage !== "provider-owned" || !surface.client.package || !surface.client.export || surface.runtime.basePath !== "runtime-resolved" || typeof surface.runtime.openApi !== "boolean" || !Array.isArray(surface.callbacks) || surface.callbacks.some(
|
|
5898
|
+
(callback) => typeof callback !== "string" || !callback.startsWith("/")
|
|
5899
|
+
)) {
|
|
5900
|
+
throw new Error("Invalid delegated HTTP surface descriptor");
|
|
5901
|
+
}
|
|
5902
|
+
const paths = Array.isArray(mount.paths) ? mount.paths : [mount.paths];
|
|
5903
|
+
if (mount.basePath !== "" && !mount.basePath.startsWith("/") || paths.length === 0 || paths.some(
|
|
5904
|
+
(path) => !path.startsWith("/") || mount.basePath !== "" && !path.startsWith(mount.basePath + "/")
|
|
5905
|
+
)) {
|
|
5906
|
+
throw new Error("Invalid delegated HTTP surface mount");
|
|
5907
|
+
}
|
|
5908
|
+
return register(mount);
|
|
5909
|
+
}
|
|
5910
|
+
|
|
5911
|
+
// src/http/localModelGatewayClient.ts
|
|
5912
|
+
var import_node_child_process = require("child_process");
|
|
5913
|
+
var import_node_util = require("util");
|
|
5914
|
+
var execute = (0, import_node_util.promisify)(import_node_child_process.execFile);
|
|
5915
|
+
var gateway = "https://studio-orchestrator.forklaunch.com/studio-orchestrator/desktop-runtime-model-gateway";
|
|
5916
|
+
function validate(value) {
|
|
5917
|
+
if (!value || !/^[a-f0-9]{64}$/.test(value.grantId) || !/^[a-f0-9]{64}$/.test(value.capability) || value.gatewayBaseUrl !== `${gateway}/${value.grantId}/v1` || value.scope !== "local-runtime" || !Number.isSafeInteger(value.expiresAt) || value.expiresAt <= Date.now() || value.expiresAt > Date.now() + 9e5 || !/^[A-Za-z0-9._-]{1,128}$/.test(value.model) || !Number.isInteger(value.maxCalls) || value.maxCalls < 1 || value.maxCalls > 20 || !Number.isInteger(value.maxUnits) || value.maxUnits < 1 || value.maxUnits > 1e5) {
|
|
5918
|
+
throw new Error(
|
|
5919
|
+
"Invalid local model connection. No model request was sent."
|
|
5920
|
+
);
|
|
5921
|
+
}
|
|
5922
|
+
return value;
|
|
5923
|
+
}
|
|
5924
|
+
function createLocalModelGatewayClient(options2 = {}) {
|
|
5925
|
+
if (process.env.FORKLAUNCH_API_KEY === void 0 && !options2.credentialProvider && process.env.FORKLAUNCH_LOCAL_MODEL_RELAY === "1") {
|
|
5926
|
+
return createPreviewModelGatewayClient({ fetch: options2.fetch });
|
|
5927
|
+
}
|
|
5928
|
+
const applicationId = options2.applicationId ?? process.env.FORKLAUNCH_APPLICATION_ID;
|
|
5929
|
+
const model = options2.model ?? process.env.AGENT_MODEL;
|
|
5930
|
+
if (applicationId && !/^[a-f0-9-]{36}$/i.test(applicationId)) {
|
|
5931
|
+
throw new Error(
|
|
5932
|
+
"FORKLAUNCH_APPLICATION_ID must be a saved application UUID."
|
|
5933
|
+
);
|
|
5934
|
+
}
|
|
5935
|
+
const provider = options2.credentialProvider ?? (async () => {
|
|
5936
|
+
const args = ["model", "credential", "--json"];
|
|
5937
|
+
if (applicationId) args.push("--application-id", applicationId);
|
|
5938
|
+
if (model) args.push("--model", model);
|
|
5939
|
+
try {
|
|
5940
|
+
const { stdout } = await execute("forklaunch", args, {
|
|
5941
|
+
timeout: 35e3,
|
|
5942
|
+
maxBuffer: 65536,
|
|
5943
|
+
windowsHide: true
|
|
5944
|
+
});
|
|
5945
|
+
return JSON.parse(stdout);
|
|
5946
|
+
} catch {
|
|
5947
|
+
throw new Error(
|
|
5948
|
+
"Could not connect the local agent. Run forklaunch login, check app access, and use a CLI that supports model credential."
|
|
5949
|
+
);
|
|
5950
|
+
}
|
|
5951
|
+
});
|
|
5952
|
+
const optionsFetch = options2.fetch ?? fetch;
|
|
5953
|
+
let pending;
|
|
5954
|
+
let credential;
|
|
5955
|
+
async function connection() {
|
|
5956
|
+
if (credential && credential.expiresAt > Date.now()) return credential;
|
|
5957
|
+
pending ??= provider().then(validate).then((value) => credential = value).finally(() => {
|
|
5958
|
+
pending = void 0;
|
|
5959
|
+
});
|
|
5960
|
+
return pending;
|
|
5961
|
+
}
|
|
5962
|
+
return {
|
|
5963
|
+
async models() {
|
|
5964
|
+
const c = await connection();
|
|
5965
|
+
return {
|
|
5966
|
+
models: [{ id: c.model }],
|
|
5967
|
+
preview: {
|
|
5968
|
+
expiresAt: c.expiresAt,
|
|
5969
|
+
maxCalls: c.maxCalls,
|
|
5970
|
+
maxUnits: c.maxUnits
|
|
5971
|
+
}
|
|
5972
|
+
};
|
|
5973
|
+
},
|
|
5974
|
+
chat: {
|
|
5975
|
+
completions: {
|
|
5976
|
+
async *stream(request, options3 = {}) {
|
|
5977
|
+
const c = await connection();
|
|
5978
|
+
if (request.model !== c.model)
|
|
5979
|
+
throw new ModelGatewayRequestError(
|
|
5980
|
+
400,
|
|
5981
|
+
"Choose the model authorized for this local session."
|
|
5982
|
+
);
|
|
5983
|
+
const response = await optionsFetch(
|
|
5984
|
+
`${c.gatewayBaseUrl}/chat/completions`,
|
|
5985
|
+
{
|
|
5986
|
+
method: "POST",
|
|
5987
|
+
redirect: "error",
|
|
5988
|
+
signal: options3.signal ? AbortSignal.any([options3.signal, AbortSignal.timeout(6e4)]) : AbortSignal.timeout(6e4),
|
|
5989
|
+
headers: {
|
|
5990
|
+
authorization: `Bearer ${c.capability}`,
|
|
5991
|
+
"content-type": "application/json"
|
|
5992
|
+
},
|
|
5993
|
+
body: JSON.stringify({ ...request, stream: true })
|
|
5994
|
+
}
|
|
5995
|
+
);
|
|
5996
|
+
if (!response.ok) {
|
|
5997
|
+
await response.body?.cancel();
|
|
5998
|
+
throw new ModelGatewayRequestError(
|
|
5999
|
+
response.status,
|
|
6000
|
+
"The local model stream was refused. No automatic retry was sent."
|
|
6001
|
+
);
|
|
6002
|
+
}
|
|
6003
|
+
yield* readModelStream(response);
|
|
6004
|
+
},
|
|
6005
|
+
async create(request) {
|
|
6006
|
+
const c = await connection();
|
|
6007
|
+
if (request.model !== c.model)
|
|
6008
|
+
throw new ModelGatewayRequestError(
|
|
6009
|
+
400,
|
|
6010
|
+
"Choose the model authorized for this local session."
|
|
6011
|
+
);
|
|
6012
|
+
const response = await (options2.fetch ?? fetch)(
|
|
6013
|
+
`${c.gatewayBaseUrl}/chat/completions`,
|
|
6014
|
+
{
|
|
6015
|
+
method: "POST",
|
|
6016
|
+
redirect: "error",
|
|
6017
|
+
signal: AbortSignal.timeout(6e4),
|
|
6018
|
+
headers: {
|
|
6019
|
+
authorization: `Bearer ${c.capability}`,
|
|
6020
|
+
"content-type": "application/json"
|
|
6021
|
+
},
|
|
6022
|
+
body: JSON.stringify({ ...request, stream: false })
|
|
6023
|
+
}
|
|
6024
|
+
);
|
|
6025
|
+
if (!response.ok) {
|
|
6026
|
+
await response.body?.cancel();
|
|
6027
|
+
throw new ModelGatewayRequestError(
|
|
6028
|
+
response.status,
|
|
6029
|
+
"The local model request was refused or failed. No automatic retry was sent."
|
|
6030
|
+
);
|
|
6031
|
+
}
|
|
6032
|
+
return response.json();
|
|
6033
|
+
}
|
|
6034
|
+
}
|
|
6035
|
+
}
|
|
6036
|
+
};
|
|
6037
|
+
}
|
|
5668
6038
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5669
6039
|
0 && (module.exports = {
|
|
5670
6040
|
ATTR_API_NAME,
|
|
@@ -5703,10 +6073,12 @@ var RateLimiter = class {
|
|
|
5703
6073
|
auditComplianceAccess,
|
|
5704
6074
|
auditEnabled,
|
|
5705
6075
|
auditEventType,
|
|
6076
|
+
bindRuntimeAuth,
|
|
5706
6077
|
createContext,
|
|
5707
6078
|
createEmailClient,
|
|
5708
6079
|
createHmacToken,
|
|
5709
6080
|
createInstanceGatewayTransport,
|
|
6081
|
+
createLocalModelGatewayClient,
|
|
5710
6082
|
createModelGatewayClient,
|
|
5711
6083
|
createPaymentsClient,
|
|
5712
6084
|
createPreviewModelGatewayClient,
|
|
@@ -5756,6 +6128,7 @@ var RateLimiter = class {
|
|
|
5756
6128
|
put,
|
|
5757
6129
|
recordMetric,
|
|
5758
6130
|
recordRequestAudit,
|
|
6131
|
+
registerDelegatedSurface,
|
|
5759
6132
|
resetProcessHandlersForTesting,
|
|
5760
6133
|
signPlatformEvent,
|
|
5761
6134
|
smsSegments,
|