@aexhq/sdk 0.35.0 → 0.36.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 +16 -15
- package/dist/_contracts/index.d.ts +3 -4
- package/dist/_contracts/index.js +1 -4
- package/dist/_contracts/operations.d.ts +2 -1
- package/dist/_contracts/operations.js +10 -0
- package/dist/_contracts/run-config.d.ts +1 -3
- package/dist/_contracts/run-config.js +2 -7
- package/dist/_contracts/run-trace.d.ts +0 -86
- package/dist/_contracts/run-trace.js +1 -184
- package/dist/_contracts/run-unit.d.ts +2 -25
- package/dist/_contracts/run-unit.js +1 -2
- package/dist/_contracts/runtime-manifest.d.ts +1 -1
- package/dist/_contracts/runtime-security-profile.d.ts +0 -2
- package/dist/_contracts/runtime-security-profile.js +0 -9
- package/dist/_contracts/runtime-types.d.ts +25 -4
- package/dist/_contracts/stable.d.ts +1 -1
- package/dist/_contracts/stable.js +1 -1
- package/dist/_contracts/submission.d.ts +4 -72
- package/dist/_contracts/submission.js +5 -472
- package/dist/cli.mjs +20 -442
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +30 -25
- package/dist/client.js +251 -66
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +7 -15
- package/dist/index.js +5 -17
- package/dist/index.js.map +1 -1
- package/dist/secret.d.ts +2 -2
- package/dist/secret.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/concepts/composition.md +8 -14
- package/docs/credentials.md +59 -101
- package/docs/defaults.md +0 -8
- package/docs/events.md +8 -9
- package/docs/limits-and-quotas.md +1 -4
- package/docs/limits.md +2 -6
- package/docs/mcp.md +4 -5
- package/docs/networking.md +6 -16
- package/docs/outputs.md +0 -4
- package/docs/public-surface.json +3 -3
- package/docs/quickstart.md +3 -7
- package/docs/run-config.md +6 -3
- package/docs/secrets.md +1 -1
- package/docs/skills.md +3 -3
- package/docs/vision-skills.md +52 -101
- package/examples/feature-tour.ts +4 -21
- package/package.json +1 -1
- package/dist/_contracts/proxy-protocol.d.ts +0 -305
- package/dist/_contracts/proxy-protocol.js +0 -297
- package/dist/_contracts/proxy-validation.d.ts +0 -19
- package/dist/_contracts/proxy-validation.js +0 -51
- package/dist/data-tools.d.ts +0 -82
- package/dist/data-tools.js +0 -251
- package/dist/data-tools.js.map +0 -1
- package/dist/proxy-endpoint.d.ts +0 -131
- package/dist/proxy-endpoint.js +0 -144
- package/dist/proxy-endpoint.js.map +0 -1
- package/examples/chat-corpus.ts +0 -84
package/dist/cli.mjs
CHANGED
|
@@ -10,34 +10,6 @@ import { readFile, writeFile, readdir, stat, mkdir, chmod, rm } from "node:fs/pr
|
|
|
10
10
|
import { resolve as resolvePath4, join, dirname as dirname2 } from "node:path";
|
|
11
11
|
import { homedir } from "node:os";
|
|
12
12
|
|
|
13
|
-
// ../contracts/dist/proxy-protocol.js
|
|
14
|
-
var PROXY_PROTOCOL_VERSION_V2 = "2";
|
|
15
|
-
var PROXY_PROTOCOL_HEADER = "x-aex-proxy-protocol";
|
|
16
|
-
var PROXY_RESP_STATUS_HEADER = "x-aex-proxy-status";
|
|
17
|
-
var PROXY_RESP_MODE_HEADER = "x-aex-proxy-effective-mode";
|
|
18
|
-
var PROXY_RESP_TRUNCATED_HEADER = "x-aex-proxy-truncated";
|
|
19
|
-
var PROXY_RESP_UPSTREAM_HEADERS_HEADER = "x-aex-proxy-upstream-headers";
|
|
20
|
-
var PROXY_METHOD_HEADER = "x-aex-method";
|
|
21
|
-
var PROXY_PATH_HEADER = "x-aex-path";
|
|
22
|
-
var PROXY_QUERY_HEADER = "x-aex-query";
|
|
23
|
-
var PROXY_HEADERS_HEADER = "x-aex-headers";
|
|
24
|
-
var PROXY_RESPONSE_MODE_HEADER = "x-aex-response-mode";
|
|
25
|
-
var PROXY_RESPONSE_MODES = ["status_only", "headers_only", "full"];
|
|
26
|
-
var PROXY_ENDPOINT_DEFAULTS = {
|
|
27
|
-
allowHeaders: [],
|
|
28
|
-
responseMode: "headers_only",
|
|
29
|
-
// 10 MiB. The body is buffered in the hosted API to enforce this cap, while the
|
|
30
|
-
// launch default fits practical multimodal/tool POSTs without every endpoint
|
|
31
|
-
// needing an override.
|
|
32
|
-
maxRequestBytes: 10 * 1024 * 1024,
|
|
33
|
-
// Unlimited (0). The request body is buffered to enforce its cap, so that
|
|
34
|
-
// stays finite; the response is streamed, so it does not need one.
|
|
35
|
-
maxResponseBytes: 0,
|
|
36
|
-
// 5 minutes. Long-running upstream tool/model calls should not fail under a
|
|
37
|
-
// development-oriented 10s ceiling; endpoints can still set a smaller value.
|
|
38
|
-
timeoutMs: 5 * 60 * 1e3
|
|
39
|
-
};
|
|
40
|
-
|
|
41
13
|
// ../contracts/dist/provider-support.js
|
|
42
14
|
var COMMON_DOCS = [
|
|
43
15
|
{ label: "Secrets", href: "secrets.md" },
|
|
@@ -392,7 +364,6 @@ function parseRunRequestConfig(input) {
|
|
|
392
364
|
"environment",
|
|
393
365
|
"runtimeSize",
|
|
394
366
|
"timeout",
|
|
395
|
-
"proxyEndpoints",
|
|
396
367
|
"metadata"
|
|
397
368
|
]);
|
|
398
369
|
for (const key of Object.keys(record)) {
|
|
@@ -412,14 +383,13 @@ function parseRunRequestConfig(input) {
|
|
|
412
383
|
...system !== void 0 ? { system } : {},
|
|
413
384
|
prompt,
|
|
414
385
|
...mcpServers !== void 0 ? { mcpServers } : {},
|
|
415
|
-
// environment /
|
|
416
|
-
//
|
|
386
|
+
// environment / metadata: passed through as-is — the BFF revalidates
|
|
387
|
+
// them via `parseRunSubmissionRequest`,
|
|
417
388
|
// so duplicating the heavyweight parsers here would mean two sources
|
|
418
389
|
// of truth. The CLI surfaces structural errors at submission time.
|
|
419
390
|
...record.environment !== void 0 ? { environment: record.environment } : {},
|
|
420
391
|
...record.runtimeSize !== void 0 ? { runtimeSize: record.runtimeSize } : {},
|
|
421
392
|
...record.timeout !== void 0 ? { timeout: record.timeout } : {},
|
|
422
|
-
...record.proxyEndpoints !== void 0 ? { proxyEndpoints: record.proxyEndpoints } : {},
|
|
423
393
|
...record.metadata !== void 0 ? { metadata: record.metadata } : {}
|
|
424
394
|
};
|
|
425
395
|
}
|
|
@@ -489,7 +459,6 @@ var RUNTIME_SECURITY_PROFILE_CONFIG = Object.freeze({
|
|
|
489
459
|
allowOpenNetworking: false,
|
|
490
460
|
allowRuntimePackages: false,
|
|
491
461
|
allowCustomerEnvVars: true,
|
|
492
|
-
allowProxyEndpoints: true,
|
|
493
462
|
allowMcpServers: true
|
|
494
463
|
}),
|
|
495
464
|
standard: Object.freeze({
|
|
@@ -498,7 +467,6 @@ var RUNTIME_SECURITY_PROFILE_CONFIG = Object.freeze({
|
|
|
498
467
|
allowOpenNetworking: true,
|
|
499
468
|
allowRuntimePackages: true,
|
|
500
469
|
allowCustomerEnvVars: true,
|
|
501
|
-
allowProxyEndpoints: true,
|
|
502
470
|
allowMcpServers: true
|
|
503
471
|
}),
|
|
504
472
|
developer: Object.freeze({
|
|
@@ -507,7 +475,6 @@ var RUNTIME_SECURITY_PROFILE_CONFIG = Object.freeze({
|
|
|
507
475
|
allowOpenNetworking: true,
|
|
508
476
|
allowRuntimePackages: true,
|
|
509
477
|
allowCustomerEnvVars: true,
|
|
510
|
-
allowProxyEndpoints: true,
|
|
511
478
|
allowMcpServers: true
|
|
512
479
|
})
|
|
513
480
|
});
|
|
@@ -524,9 +491,6 @@ var RUN_PROVIDERS = [
|
|
|
524
491
|
"doubao-cn"
|
|
525
492
|
];
|
|
526
493
|
var DEFAULT_RUN_PROVIDER = "anthropic";
|
|
527
|
-
var MIN_REDACTION_TARGET_BYTES = 4;
|
|
528
|
-
var MIN_PROXY_SECRET_BYTES = 8;
|
|
529
|
-
var _MIN_PROXY_SECRET_BYTES_OK = MIN_PROXY_SECRET_BYTES >= MIN_REDACTION_TARGET_BYTES;
|
|
530
494
|
var BUILTIN_TOOL_NAMES = [
|
|
531
495
|
"bash",
|
|
532
496
|
"read_file",
|
|
@@ -1400,6 +1364,7 @@ __export(operations_exports, {
|
|
|
1400
1364
|
listRuns: () => listRuns,
|
|
1401
1365
|
listSecrets: () => listSecrets,
|
|
1402
1366
|
listSessionEvents: () => listSessionEvents,
|
|
1367
|
+
listSessionMessages: () => listSessionMessages,
|
|
1403
1368
|
listSessionOutputs: () => listSessionOutputs,
|
|
1404
1369
|
listSessions: () => listSessions,
|
|
1405
1370
|
normalizeOutputLinkExpiresIn: () => normalizeOutputLinkExpiresIn,
|
|
@@ -2188,6 +2153,16 @@ async function sendSessionMessage(http, sessionId, request, options) {
|
|
|
2188
2153
|
body: JSON.stringify(request)
|
|
2189
2154
|
});
|
|
2190
2155
|
}
|
|
2156
|
+
async function listSessionMessages(http, sessionId, query) {
|
|
2157
|
+
const params = {};
|
|
2158
|
+
if (query?.limit !== void 0)
|
|
2159
|
+
params.limit = String(query.limit);
|
|
2160
|
+
if (query?.cursor !== void 0)
|
|
2161
|
+
params.cursor = query.cursor;
|
|
2162
|
+
if (query?.since !== void 0)
|
|
2163
|
+
params.since = query.since;
|
|
2164
|
+
return http.request(`/api/sessions/${encodeURIComponent(sessionId)}/messages`, {}, params);
|
|
2165
|
+
}
|
|
2191
2166
|
async function suspendSession(http, sessionId, options) {
|
|
2192
2167
|
const headers = idempotencyHeaders(options);
|
|
2193
2168
|
return http.request(`/api/sessions/${encodeURIComponent(sessionId)}/suspend`, { method: "POST", ...headers ? { headers } : {} });
|
|
@@ -2800,34 +2775,8 @@ async function uploadWorkspaceAsset(http, input) {
|
|
|
2800
2775
|
});
|
|
2801
2776
|
}
|
|
2802
2777
|
|
|
2803
|
-
// ../contracts/dist/proxy-validation.js
|
|
2804
|
-
function validateProxyAuth(endpoints, auth) {
|
|
2805
|
-
const authList = auth ?? [];
|
|
2806
|
-
const endpointNames = new Set(endpoints.map((e) => e.name));
|
|
2807
|
-
const authNames = /* @__PURE__ */ new Set();
|
|
2808
|
-
for (const entry of authList) {
|
|
2809
|
-
if (authNames.has(entry.name)) {
|
|
2810
|
-
throw new Error(`secrets.proxyEndpointAuth contains duplicate name '${entry.name}'`);
|
|
2811
|
-
}
|
|
2812
|
-
authNames.add(entry.name);
|
|
2813
|
-
if (!endpointNames.has(entry.name)) {
|
|
2814
|
-
throw new Error(`secrets.proxyEndpointAuth[].name='${entry.name}' has no matching proxyEndpoints[].name`);
|
|
2815
|
-
}
|
|
2816
|
-
}
|
|
2817
|
-
for (const endpoint of endpoints) {
|
|
2818
|
-
const match = authList.find((a) => a.name === endpoint.name);
|
|
2819
|
-
if (!match) {
|
|
2820
|
-
throw new Error(`proxyEndpoints[].name='${endpoint.name}' is missing a matching secrets.proxyEndpointAuth entry`);
|
|
2821
|
-
}
|
|
2822
|
-
if (match.value.type !== endpoint.authShape.type) {
|
|
2823
|
-
throw new Error(`secrets.proxyEndpointAuth[name='${endpoint.name}'].value.type='${match.value.type}' does not match proxyEndpoints[name='${endpoint.name}'].authShape.type='${endpoint.authShape.type}'`);
|
|
2824
|
-
}
|
|
2825
|
-
}
|
|
2826
|
-
}
|
|
2827
|
-
|
|
2828
2778
|
// dist/internal.js
|
|
2829
2779
|
var AEX_INDEX_PATH = "/mnt/session/uploads/aex/index.json";
|
|
2830
|
-
var AEX_RUN_TOKEN_PATH = "/mnt/session/uploads/aex/run-token";
|
|
2831
2780
|
|
|
2832
2781
|
// dist/host/common.js
|
|
2833
2782
|
var SUCCESS = { code: 0 };
|
|
@@ -2986,7 +2935,7 @@ async function refuseInsideManagedRun(io2, verb) {
|
|
|
2986
2935
|
try {
|
|
2987
2936
|
await io2.readFile(AEX_INDEX_PATH);
|
|
2988
2937
|
io2.stderr(`\`aex ${verb}\` is a host command and cannot run inside a managed run container.
|
|
2989
|
-
|
|
2938
|
+
Make HTTP calls from your code and pass credentials through secrets.
|
|
2990
2939
|
`);
|
|
2991
2940
|
return true;
|
|
2992
2941
|
} catch (err2) {
|
|
@@ -3171,285 +3120,6 @@ async function runOutputsSyncCmd(io2, dirs) {
|
|
|
3171
3120
|
return SUCCESS;
|
|
3172
3121
|
}
|
|
3173
3122
|
|
|
3174
|
-
// dist/proxy.js
|
|
3175
|
-
function parseProxyFlags(rest) {
|
|
3176
|
-
let endpointName = null;
|
|
3177
|
-
let method = "GET";
|
|
3178
|
-
let path = "/";
|
|
3179
|
-
let query = null;
|
|
3180
|
-
const headers = /* @__PURE__ */ new Map();
|
|
3181
|
-
let dataSpec = null;
|
|
3182
|
-
let responseMode = null;
|
|
3183
|
-
let showHelp = false;
|
|
3184
|
-
for (let i2 = 0; i2 < rest.length; i2++) {
|
|
3185
|
-
const arg = rest[i2];
|
|
3186
|
-
if (arg === "--help" || arg === "-h") {
|
|
3187
|
-
showHelp = true;
|
|
3188
|
-
continue;
|
|
3189
|
-
}
|
|
3190
|
-
if (arg === "--method") {
|
|
3191
|
-
method = expect(rest, ++i2, "--method");
|
|
3192
|
-
continue;
|
|
3193
|
-
}
|
|
3194
|
-
if (arg === "--path") {
|
|
3195
|
-
path = expect(rest, ++i2, "--path");
|
|
3196
|
-
continue;
|
|
3197
|
-
}
|
|
3198
|
-
if (arg === "--query") {
|
|
3199
|
-
query = expect(rest, ++i2, "--query");
|
|
3200
|
-
continue;
|
|
3201
|
-
}
|
|
3202
|
-
if (arg === "--header") {
|
|
3203
|
-
const kv = expect(rest, ++i2, "--header");
|
|
3204
|
-
const eq = kv.indexOf("=");
|
|
3205
|
-
if (eq <= 0)
|
|
3206
|
-
return { ok: false, reason: "--header must be in the form KEY=VALUE" };
|
|
3207
|
-
headers.set(kv.slice(0, eq).toLowerCase(), kv.slice(eq + 1));
|
|
3208
|
-
continue;
|
|
3209
|
-
}
|
|
3210
|
-
if (arg === "--data") {
|
|
3211
|
-
dataSpec = expect(rest, ++i2, "--data");
|
|
3212
|
-
continue;
|
|
3213
|
-
}
|
|
3214
|
-
if (arg === "--response-mode") {
|
|
3215
|
-
responseMode = expect(rest, ++i2, "--response-mode");
|
|
3216
|
-
continue;
|
|
3217
|
-
}
|
|
3218
|
-
if (arg.startsWith("--")) {
|
|
3219
|
-
return { ok: false, reason: `unknown flag: ${arg}` };
|
|
3220
|
-
}
|
|
3221
|
-
if (endpointName === null) {
|
|
3222
|
-
endpointName = arg;
|
|
3223
|
-
continue;
|
|
3224
|
-
}
|
|
3225
|
-
return { ok: false, reason: `unexpected positional argument: ${arg}` };
|
|
3226
|
-
}
|
|
3227
|
-
return { ok: true, flags: { endpointName, method, path, query, headers, dataSpec, responseMode, showHelp } };
|
|
3228
|
-
}
|
|
3229
|
-
function expect(arr, idx, flag) {
|
|
3230
|
-
const v = arr[idx];
|
|
3231
|
-
if (v === void 0) {
|
|
3232
|
-
throw new CliUsageError(`${flag} requires a value`);
|
|
3233
|
-
}
|
|
3234
|
-
return v;
|
|
3235
|
-
}
|
|
3236
|
-
var CliUsageError = class extends Error {
|
|
3237
|
-
};
|
|
3238
|
-
async function printProxyHelp(io2) {
|
|
3239
|
-
io2.stdout("aex proxy \u2014 call an upstream HTTP endpoint via the managed proxy.\n\n");
|
|
3240
|
-
io2.stdout("Usage:\n");
|
|
3241
|
-
io2.stdout(" aex proxy <endpoint-name> [flags]\n\n");
|
|
3242
|
-
io2.stdout("Flags:\n");
|
|
3243
|
-
io2.stdout(" --method <verb> HTTP method (default: GET)\n");
|
|
3244
|
-
io2.stdout(" --path <path> Caller-supplied path; must match policy prefixes\n");
|
|
3245
|
-
io2.stdout(` --query <json> JSON object of query parameters (e.g. '{"q":"x"}')
|
|
3246
|
-
`);
|
|
3247
|
-
io2.stdout(" --header K=V Add a caller header (repeatable)\n");
|
|
3248
|
-
io2.stdout(" --data <value> Request body. Use '-' for stdin, '@<file>' for file content\n");
|
|
3249
|
-
io2.stdout(" --response-mode <mode> status_only | headers_only | full (may only narrow policy)\n");
|
|
3250
|
-
io2.stdout(" --help Show this message\n\n");
|
|
3251
|
-
const manifest = await tryReadManifest(io2);
|
|
3252
|
-
if (manifest && manifest.endpoints.length > 0) {
|
|
3253
|
-
io2.stdout("Declared endpoints:\n");
|
|
3254
|
-
for (const ep of manifest.endpoints) {
|
|
3255
|
-
io2.stdout(` \u2022 ${formatProxyEndpointSummary(ep)}
|
|
3256
|
-
`);
|
|
3257
|
-
}
|
|
3258
|
-
}
|
|
3259
|
-
return SUCCESS;
|
|
3260
|
-
}
|
|
3261
|
-
function formatProxyEndpointSummary(ep) {
|
|
3262
|
-
const retry = ep.retry ? `, retry=${ep.retry.maxAttempts}x ${ep.retry.retryOnMethods.join("/")} ${ep.retry.retryOnStatuses.join("/")} delay=${ep.retry.initialDelayMs}-${ep.retry.maxDelayMs}ms jitter=${ep.retry.jitter}${ep.retry.respectRetryAfter ? " retry-after" : ""}` : "";
|
|
3263
|
-
return `${ep.name}: ${ep.allowMethods.join(",")} ${ep.allowPathPrefixes.join(",")} (mode=${ep.responseMode}${retry})`;
|
|
3264
|
-
}
|
|
3265
|
-
async function runProxy(io2, rest) {
|
|
3266
|
-
let parsed;
|
|
3267
|
-
try {
|
|
3268
|
-
parsed = parseProxyFlags(rest);
|
|
3269
|
-
} catch (err2) {
|
|
3270
|
-
if (err2 instanceof CliUsageError) {
|
|
3271
|
-
io2.stderr(`${err2.message}
|
|
3272
|
-
`);
|
|
3273
|
-
return USAGE_ERR;
|
|
3274
|
-
}
|
|
3275
|
-
throw err2;
|
|
3276
|
-
}
|
|
3277
|
-
if (!parsed.ok) {
|
|
3278
|
-
io2.stderr(`${parsed.reason}
|
|
3279
|
-
`);
|
|
3280
|
-
return USAGE_ERR;
|
|
3281
|
-
}
|
|
3282
|
-
const f = parsed.flags;
|
|
3283
|
-
if (f.showHelp) {
|
|
3284
|
-
return await printProxyHelp(io2);
|
|
3285
|
-
}
|
|
3286
|
-
if (!f.endpointName) {
|
|
3287
|
-
io2.stderr("missing endpoint-name\n");
|
|
3288
|
-
io2.stderr("usage: aex proxy <endpoint-name> [flags]\n");
|
|
3289
|
-
return USAGE_ERR;
|
|
3290
|
-
}
|
|
3291
|
-
if (f.responseMode && !PROXY_RESPONSE_MODES.includes(f.responseMode)) {
|
|
3292
|
-
io2.stderr(`--response-mode must be one of: ${PROXY_RESPONSE_MODES.join(", ")}
|
|
3293
|
-
`);
|
|
3294
|
-
return USAGE_ERR;
|
|
3295
|
-
}
|
|
3296
|
-
const manifest = await tryReadManifest(io2);
|
|
3297
|
-
if (!manifest) {
|
|
3298
|
-
emitError(io2, {
|
|
3299
|
-
error: "internal_error",
|
|
3300
|
-
message: "manifest not mounted; this CLI must run inside an aex-managed run"
|
|
3301
|
-
});
|
|
3302
|
-
return RUNTIME_ERR;
|
|
3303
|
-
}
|
|
3304
|
-
if (!manifest.proxyBaseUrl) {
|
|
3305
|
-
emitError(io2, {
|
|
3306
|
-
error: "endpoint_not_found",
|
|
3307
|
-
message: "this run has no proxy endpoints declared",
|
|
3308
|
-
endpointName: f.endpointName
|
|
3309
|
-
});
|
|
3310
|
-
return RUNTIME_ERR;
|
|
3311
|
-
}
|
|
3312
|
-
let token;
|
|
3313
|
-
try {
|
|
3314
|
-
token = (await io2.readFile(AEX_RUN_TOKEN_PATH)).trim();
|
|
3315
|
-
} catch {
|
|
3316
|
-
emitError(io2, {
|
|
3317
|
-
error: "unauthorized",
|
|
3318
|
-
message: "run token file missing; this run has no proxy bearer"
|
|
3319
|
-
});
|
|
3320
|
-
return RUNTIME_ERR;
|
|
3321
|
-
}
|
|
3322
|
-
if (!token) {
|
|
3323
|
-
emitError(io2, { error: "unauthorized", message: "run token is empty" });
|
|
3324
|
-
return RUNTIME_ERR;
|
|
3325
|
-
}
|
|
3326
|
-
let body;
|
|
3327
|
-
if (f.dataSpec !== null) {
|
|
3328
|
-
try {
|
|
3329
|
-
body = await resolveBody(io2, f.dataSpec);
|
|
3330
|
-
} catch (err2) {
|
|
3331
|
-
io2.stderr(`failed to read request body: ${err2.message}
|
|
3332
|
-
`);
|
|
3333
|
-
return RUNTIME_ERR;
|
|
3334
|
-
}
|
|
3335
|
-
}
|
|
3336
|
-
const url = `${manifest.proxyBaseUrl.replace(/\/+$/, "")}/${encodeURIComponent(f.endpointName)}`;
|
|
3337
|
-
const requestHeaders = new Headers();
|
|
3338
|
-
requestHeaders.set("authorization", `Bearer ${token}`);
|
|
3339
|
-
requestHeaders.set(PROXY_PROTOCOL_HEADER, PROXY_PROTOCOL_VERSION_V2);
|
|
3340
|
-
requestHeaders.set(PROXY_METHOD_HEADER, f.method.toUpperCase());
|
|
3341
|
-
requestHeaders.set(PROXY_PATH_HEADER, f.path);
|
|
3342
|
-
if (f.query) {
|
|
3343
|
-
requestHeaders.set(PROXY_QUERY_HEADER, f.query);
|
|
3344
|
-
}
|
|
3345
|
-
if (f.headers.size > 0) {
|
|
3346
|
-
requestHeaders.set(PROXY_HEADERS_HEADER, JSON.stringify(Object.fromEntries(f.headers)));
|
|
3347
|
-
}
|
|
3348
|
-
if (f.responseMode) {
|
|
3349
|
-
requestHeaders.set(PROXY_RESPONSE_MODE_HEADER, f.responseMode);
|
|
3350
|
-
}
|
|
3351
|
-
if (body !== void 0) {
|
|
3352
|
-
requestHeaders.set("content-length", String(body.byteLength));
|
|
3353
|
-
}
|
|
3354
|
-
const init = {
|
|
3355
|
-
method: "POST",
|
|
3356
|
-
headers: requestHeaders,
|
|
3357
|
-
redirect: "manual"
|
|
3358
|
-
};
|
|
3359
|
-
if (body !== void 0) {
|
|
3360
|
-
init.body = body;
|
|
3361
|
-
}
|
|
3362
|
-
let response;
|
|
3363
|
-
try {
|
|
3364
|
-
response = await io2.fetchImpl(url, init);
|
|
3365
|
-
} catch (err2) {
|
|
3366
|
-
emitError(io2, {
|
|
3367
|
-
error: "upstream_error",
|
|
3368
|
-
message: `proxy request failed: ${err2.message}`,
|
|
3369
|
-
endpointName: f.endpointName
|
|
3370
|
-
});
|
|
3371
|
-
return RUNTIME_ERR;
|
|
3372
|
-
}
|
|
3373
|
-
if (response.headers.get(PROXY_RESP_STATUS_HEADER) !== null) {
|
|
3374
|
-
const envelope = await readStreamedEnvelope(response, f.endpointName);
|
|
3375
|
-
io2.stdout(JSON.stringify(envelope) + "\n");
|
|
3376
|
-
return SUCCESS;
|
|
3377
|
-
}
|
|
3378
|
-
const text = await response.text();
|
|
3379
|
-
let parsedBody;
|
|
3380
|
-
try {
|
|
3381
|
-
parsedBody = text ? JSON.parse(text) : {};
|
|
3382
|
-
} catch {
|
|
3383
|
-
const snippet = text.slice(0, 200).replace(/\s+/g, " ").trim();
|
|
3384
|
-
emitError(io2, {
|
|
3385
|
-
error: "internal_error",
|
|
3386
|
-
message: `proxy returned non-JSON response (HTTP ${response.status}, body=${JSON.stringify(snippet)})`,
|
|
3387
|
-
endpointName: f.endpointName
|
|
3388
|
-
});
|
|
3389
|
-
return RUNTIME_ERR;
|
|
3390
|
-
}
|
|
3391
|
-
if (!response.ok) {
|
|
3392
|
-
io2.stderr(JSON.stringify(parsedBody) + "\n");
|
|
3393
|
-
return RUNTIME_ERR;
|
|
3394
|
-
}
|
|
3395
|
-
io2.stdout(JSON.stringify(parsedBody) + "\n");
|
|
3396
|
-
return SUCCESS;
|
|
3397
|
-
}
|
|
3398
|
-
async function resolveBody(io2, spec) {
|
|
3399
|
-
if (spec === "-") {
|
|
3400
|
-
const data = await io2.readFile("/dev/stdin");
|
|
3401
|
-
return new Uint8Array(Buffer.from(data, "utf8"));
|
|
3402
|
-
}
|
|
3403
|
-
if (spec.startsWith("@")) {
|
|
3404
|
-
const path = spec.slice(1);
|
|
3405
|
-
if (!path)
|
|
3406
|
-
throw new Error("--data @<file> requires a path");
|
|
3407
|
-
const data = await io2.readFile(path);
|
|
3408
|
-
return new Uint8Array(Buffer.from(data, "utf8"));
|
|
3409
|
-
}
|
|
3410
|
-
return new Uint8Array(Buffer.from(spec, "utf8"));
|
|
3411
|
-
}
|
|
3412
|
-
function emitError(io2, body) {
|
|
3413
|
-
io2.stderr(JSON.stringify(body) + "\n");
|
|
3414
|
-
}
|
|
3415
|
-
async function readStreamedEnvelope(response, endpointName) {
|
|
3416
|
-
const effectiveResponseMode = response.headers.get(PROXY_RESP_MODE_HEADER) ?? "headers_only";
|
|
3417
|
-
const upstreamStatus = Number.parseInt(response.headers.get(PROXY_RESP_STATUS_HEADER) ?? "0", 10);
|
|
3418
|
-
let upstreamHeaders = {};
|
|
3419
|
-
const rawHeaders = response.headers.get(PROXY_RESP_UPSTREAM_HEADERS_HEADER);
|
|
3420
|
-
if (rawHeaders) {
|
|
3421
|
-
try {
|
|
3422
|
-
const parsed = JSON.parse(rawHeaders);
|
|
3423
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3424
|
-
upstreamHeaders = parsed;
|
|
3425
|
-
}
|
|
3426
|
-
} catch {
|
|
3427
|
-
}
|
|
3428
|
-
}
|
|
3429
|
-
const truncatedRaw = response.headers.get(PROXY_RESP_TRUNCATED_HEADER);
|
|
3430
|
-
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
3431
|
-
return {
|
|
3432
|
-
endpointName,
|
|
3433
|
-
upstreamStatus,
|
|
3434
|
-
upstreamHeaders,
|
|
3435
|
-
effectiveResponseMode,
|
|
3436
|
-
// The streamed path can't echo the request-side clamp decision (it
|
|
3437
|
-
// isn't carried back); the effective mode is authoritative for the
|
|
3438
|
-
// agent and matches what v1 surfaced for an un-clamped call.
|
|
3439
|
-
modeClamped: false,
|
|
3440
|
-
...effectiveResponseMode === "full" && bytes.byteLength > 0 ? { upstreamBodyBase64: Buffer.from(bytes).toString("base64") } : {},
|
|
3441
|
-
...truncatedRaw === "true" ? { truncated: true } : {}
|
|
3442
|
-
};
|
|
3443
|
-
}
|
|
3444
|
-
async function tryReadManifest(io2) {
|
|
3445
|
-
try {
|
|
3446
|
-
const raw = await io2.readFile(AEX_INDEX_PATH);
|
|
3447
|
-
return JSON.parse(raw);
|
|
3448
|
-
} catch {
|
|
3449
|
-
return null;
|
|
3450
|
-
}
|
|
3451
|
-
}
|
|
3452
|
-
|
|
3453
3123
|
// dist/host/run-cmd.js
|
|
3454
3124
|
import { resolve as resolvePath } from "node:path";
|
|
3455
3125
|
var DEFAULT_SESSION_IDLE_TTL = "3m";
|
|
@@ -3616,6 +3286,10 @@ async function runRunCmd(io2, argv) {
|
|
|
3616
3286
|
return USAGE_ERR;
|
|
3617
3287
|
}
|
|
3618
3288
|
rest = proxyAuthFlags.remaining;
|
|
3289
|
+
if (proxyEndpointFlags.values.length > 0 || Object.keys(proxyAuthFlags.entries).length > 0) {
|
|
3290
|
+
io2.stderr("--proxy-endpoint and --proxy-auth are no longer supported; make HTTP calls from your code and pass credentials via secrets.\n");
|
|
3291
|
+
return USAGE_ERR;
|
|
3292
|
+
}
|
|
3619
3293
|
const positional = rest.filter((a) => !a.startsWith("--"));
|
|
3620
3294
|
const unknownFlags = rest.filter((a) => a.startsWith("--"));
|
|
3621
3295
|
if (unknownFlags.length > 0) {
|
|
@@ -3727,35 +3401,6 @@ async function runRunCmd(io2, argv) {
|
|
|
3727
3401
|
for (const name of mcpHeaderBag.keys()) {
|
|
3728
3402
|
if (!mcpServersForSubmission.some((m) => m.name === name)) {
|
|
3729
3403
|
io2.stderr(`--mcp-auth ${name}: no matching --mcp / mcpServers entry declared
|
|
3730
|
-
`);
|
|
3731
|
-
return USAGE_ERR;
|
|
3732
|
-
}
|
|
3733
|
-
}
|
|
3734
|
-
let proxyEndpoints = runConfig.proxyEndpoints ?? [];
|
|
3735
|
-
if (proxyEndpointFlags.values.length > 0) {
|
|
3736
|
-
try {
|
|
3737
|
-
proxyEndpoints = proxyEndpointFlags.values.map((raw, i2) => parseJsonOrThrow(raw, `--proxy-endpoint[${i2}]`));
|
|
3738
|
-
} catch (err2) {
|
|
3739
|
-
io2.stderr(`${err2.message}
|
|
3740
|
-
`);
|
|
3741
|
-
return USAGE_ERR;
|
|
3742
|
-
}
|
|
3743
|
-
}
|
|
3744
|
-
const proxyAuth = [];
|
|
3745
|
-
for (const [name, spec] of Object.entries(proxyAuthFlags.entries)) {
|
|
3746
|
-
const parsed = parseProxyAuth(spec);
|
|
3747
|
-
if (!parsed.ok) {
|
|
3748
|
-
io2.stderr(`--proxy-auth ${name}: ${parsed.reason}
|
|
3749
|
-
`);
|
|
3750
|
-
return USAGE_ERR;
|
|
3751
|
-
}
|
|
3752
|
-
proxyAuth.push({ name, value: parsed.value });
|
|
3753
|
-
}
|
|
3754
|
-
if (proxyEndpoints.length > 0) {
|
|
3755
|
-
try {
|
|
3756
|
-
validateProxyAuth(proxyEndpoints, proxyAuth);
|
|
3757
|
-
} catch (err2) {
|
|
3758
|
-
io2.stderr(`proxy auth validation failed: ${err2.message}
|
|
3759
3404
|
`);
|
|
3760
3405
|
return USAGE_ERR;
|
|
3761
3406
|
}
|
|
@@ -3774,8 +3419,7 @@ async function runRunCmd(io2, argv) {
|
|
|
3774
3419
|
const hasAdditionalProviderKeys = Object.keys(providerKeyValues).some((p) => p !== provider);
|
|
3775
3420
|
const secrets = {
|
|
3776
3421
|
apiKeys: hasAdditionalProviderKeys ? providerKeyValues : { [provider]: providerKeyValues[provider] },
|
|
3777
|
-
...mcpServerSecrets.length > 0 ? { mcpServers: mcpServerSecrets } : {}
|
|
3778
|
-
...proxyAuth.length > 0 ? { proxyEndpointAuth: proxyAuth } : {}
|
|
3422
|
+
...mcpServerSecrets.length > 0 ? { mcpServers: mcpServerSecrets } : {}
|
|
3779
3423
|
};
|
|
3780
3424
|
const request = {
|
|
3781
3425
|
provider,
|
|
@@ -3784,8 +3428,7 @@ async function runRunCmd(io2, argv) {
|
|
|
3784
3428
|
retention: { idleTtl: DEFAULT_SESSION_IDLE_TTL },
|
|
3785
3429
|
...runtimeSizeFlag.value ? { runtimeSize: runtimeSizeFlag.value } : runConfig.runtimeSize ? { runtimeSize: runConfig.runtimeSize } : {},
|
|
3786
3430
|
...runTimeoutFlag.value ? { timeout: runTimeoutFlag.value } : runConfig.timeout ? { timeout: runConfig.timeout } : {},
|
|
3787
|
-
...webhookFlag.value ? { webhook: { url: webhookFlag.value } } : {}
|
|
3788
|
-
...proxyEndpoints.length > 0 ? { proxyEndpoints } : {}
|
|
3431
|
+
...webhookFlag.value ? { webhook: { url: webhookFlag.value } } : {}
|
|
3789
3432
|
};
|
|
3790
3433
|
const createKey = idempotency.value ?? generateIdempotencyKey();
|
|
3791
3434
|
const messageKey = `${createKey}:message`;
|
|
@@ -3864,47 +3507,6 @@ async function runRunCmd(io2, argv) {
|
|
|
3864
3507
|
return RUNTIME_ERR;
|
|
3865
3508
|
}
|
|
3866
3509
|
}
|
|
3867
|
-
function parseProxyAuth(spec) {
|
|
3868
|
-
const idx = spec.indexOf(":");
|
|
3869
|
-
if (idx <= 0) {
|
|
3870
|
-
return { ok: false, reason: `expected '<type>:<value>' (got: ${spec})` };
|
|
3871
|
-
}
|
|
3872
|
-
const type = spec.slice(0, idx);
|
|
3873
|
-
const restValue = spec.slice(idx + 1);
|
|
3874
|
-
switch (type) {
|
|
3875
|
-
case "bearer":
|
|
3876
|
-
if (!restValue)
|
|
3877
|
-
return { ok: false, reason: "bearer requires a token value" };
|
|
3878
|
-
return { ok: true, value: { type: "bearer", token: restValue } };
|
|
3879
|
-
case "header":
|
|
3880
|
-
if (!restValue)
|
|
3881
|
-
return { ok: false, reason: "header requires a value" };
|
|
3882
|
-
return { ok: true, value: { type: "header", value: restValue } };
|
|
3883
|
-
case "query":
|
|
3884
|
-
if (!restValue)
|
|
3885
|
-
return { ok: false, reason: "query requires a value" };
|
|
3886
|
-
return { ok: true, value: { type: "query", value: restValue } };
|
|
3887
|
-
case "basic": {
|
|
3888
|
-
const sep = restValue.indexOf(":");
|
|
3889
|
-
if (sep <= 0 || sep >= restValue.length - 1) {
|
|
3890
|
-
return { ok: false, reason: "basic requires <username>:<password>" };
|
|
3891
|
-
}
|
|
3892
|
-
return {
|
|
3893
|
-
ok: true,
|
|
3894
|
-
value: { type: "basic", username: restValue.slice(0, sep), password: restValue.slice(sep + 1) }
|
|
3895
|
-
};
|
|
3896
|
-
}
|
|
3897
|
-
default:
|
|
3898
|
-
return { ok: false, reason: `unknown auth type '${type}' (expected bearer|basic|header|query)` };
|
|
3899
|
-
}
|
|
3900
|
-
}
|
|
3901
|
-
function parseJsonOrThrow(raw, label) {
|
|
3902
|
-
try {
|
|
3903
|
-
return JSON.parse(raw);
|
|
3904
|
-
} catch (err2) {
|
|
3905
|
-
throw new Error(`${label} is not valid JSON: ${err2.message}`);
|
|
3906
|
-
}
|
|
3907
|
-
}
|
|
3908
3510
|
function stripMcpHeadersForParsing(input) {
|
|
3909
3511
|
const mcpHeaders = /* @__PURE__ */ new Map();
|
|
3910
3512
|
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
@@ -5725,8 +5327,6 @@ async function dispatch(io2, args) {
|
|
|
5725
5327
|
const sub = args[0];
|
|
5726
5328
|
const rest = args.slice(1);
|
|
5727
5329
|
switch (sub) {
|
|
5728
|
-
case "proxy":
|
|
5729
|
-
return runProxy(io2, rest);
|
|
5730
5330
|
case "run":
|
|
5731
5331
|
return runRunCmd(io2, rest);
|
|
5732
5332
|
case "status":
|
|
@@ -5782,26 +5382,6 @@ async function dispatch(io2, args) {
|
|
|
5782
5382
|
}
|
|
5783
5383
|
}
|
|
5784
5384
|
async function printGlobalHelp(io2) {
|
|
5785
|
-
const manifest = await tryReadManifest(io2);
|
|
5786
|
-
if (manifest) {
|
|
5787
|
-
io2.stdout("aex \u2014 in-container CLI for managed run sessions\n\n");
|
|
5788
|
-
io2.stdout("Usage:\n");
|
|
5789
|
-
io2.stdout(" aex proxy <endpoint-name> [flags]\n");
|
|
5790
|
-
io2.stdout(" aex proxy --help\n\n");
|
|
5791
|
-
if (manifest.endpoints.length === 0) {
|
|
5792
|
-
io2.stdout("This run declared no proxy endpoints.\n");
|
|
5793
|
-
} else {
|
|
5794
|
-
io2.stdout("Declared proxy endpoints for this run:\n");
|
|
5795
|
-
for (const ep of manifest.endpoints) {
|
|
5796
|
-
io2.stdout(` \u2022 ${formatProxyEndpointSummary(ep)}
|
|
5797
|
-
`);
|
|
5798
|
-
}
|
|
5799
|
-
}
|
|
5800
|
-
io2.stdout(`
|
|
5801
|
-
Protocol version: ${manifest.protocolVersion}
|
|
5802
|
-
`);
|
|
5803
|
-
return SUCCESS;
|
|
5804
|
-
}
|
|
5805
5385
|
io2.stdout("aex \u2014 unified CLI for the aex platform (mirrors the SDK 1:1)\n\n");
|
|
5806
5386
|
io2.stdout("Usage:\n");
|
|
5807
5387
|
io2.stdout(" aex run --config <run.json> --<provider>-api-key K --api-token T [flags]\n");
|
|
@@ -5846,8 +5426,6 @@ Protocol version: ${manifest.protocolVersion}
|
|
|
5846
5426
|
io2.stdout(" --mcp name=url MCP server entry (repeatable)\n");
|
|
5847
5427
|
io2.stdout(" --mcp-auth name=Hdr:Val Auth header on the matching --mcp; routed into vaulted secrets (repeatable)\n");
|
|
5848
5428
|
io2.stdout(" --metadata key=value Submission metadata entry (repeatable)\n");
|
|
5849
|
-
io2.stdout(" --proxy-endpoint '<json>' PlatformProxyEndpoint JSON (repeatable)\n");
|
|
5850
|
-
io2.stdout(" --proxy-auth name=<spec> bearer:tok | basic:u:p | header:v | query:v (repeatable)\n");
|
|
5851
5429
|
io2.stdout(" --runtime-size <size> managed runtime preset\n");
|
|
5852
5430
|
io2.stdout(" --run-timeout <dur> Server-side run deadline (e.g. 1h); distinct from --timeout\n");
|
|
5853
5431
|
io2.stdout(" --idempotency-key <key> Optional; defaults to a fresh UUID\n");
|
package/dist/cli.mjs.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
07c9307bf82f025b845d4495eb41039ac3f684c4a75244af85871809206bf704 cli.mjs
|