@aexhq/sdk 0.15.2 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -8
- package/dist/_contracts/index.d.ts +2 -0
- package/dist/_contracts/index.js +2 -0
- package/dist/_contracts/internal.d.ts +2 -0
- package/dist/_contracts/internal.js +2 -0
- package/dist/_contracts/managed-key.d.ts +3 -2
- package/dist/_contracts/models.d.ts +33 -0
- package/dist/_contracts/models.js +59 -0
- package/dist/_contracts/post-hook.d.ts +28 -0
- package/dist/_contracts/post-hook.js +68 -0
- package/dist/_contracts/proxy-protocol.d.ts +14 -18
- package/dist/_contracts/proxy-protocol.js +16 -15
- package/dist/_contracts/run-config.d.ts +15 -17
- package/dist/_contracts/run-config.js +17 -19
- package/dist/_contracts/run-unit.d.ts +4 -4
- package/dist/_contracts/run-unit.js +17 -6
- package/dist/_contracts/submission.d.ts +12 -4
- package/dist/_contracts/submission.js +9 -9
- package/dist/cli.mjs +164 -46
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +12 -2
- package/dist/client.js +8 -0
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/proxy-endpoint.d.ts +1 -3
- package/dist/proxy-endpoint.js +2 -6
- package/dist/proxy-endpoint.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/cleanup.md +3 -1
- package/docs/credentials.md +3 -3
- package/docs/outputs.md +3 -1
- package/docs/provider-runtime-capabilities.md +1 -1
- package/docs/quickstart.md +17 -7
- package/docs/run-config.md +12 -7
- package/docs/skills.md +102 -117
- package/docs/testing.md +9 -4
- package/package.json +2 -2
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* detail response stays bounded). The archive zip carries the bytes.
|
|
21
21
|
*/
|
|
22
22
|
import { parseMcpServerRef, parseSkillRef } from "./run-config.js";
|
|
23
|
+
import { RunModels, parseRunModel } from "./models.js";
|
|
23
24
|
import { PLATFORM_PACKAGE_ECOSYSTEMS } from "./submission.js";
|
|
24
25
|
// ---------------------------------------------------------------------------
|
|
25
26
|
// Submission parser
|
|
@@ -29,10 +30,10 @@ import { PLATFORM_PACKAGE_ECOSYSTEMS } from "./submission.js";
|
|
|
29
30
|
* submission. Never throws on minor unknown keys so we can
|
|
30
31
|
* forward-compat with worker-side enrichment.
|
|
31
32
|
*
|
|
32
|
-
* Returns a typed shape even for malformed snapshots
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
33
|
+
* Returns a typed shape even for malformed snapshots by falling back to the
|
|
34
|
+
* default public model and empty collection defaults, because the dashboard
|
|
35
|
+
* must still render *something* for a buggy historical row rather than 500ing
|
|
36
|
+
* the whole detail page.
|
|
36
37
|
*/
|
|
37
38
|
export function parseRunUnitSubmission(input) {
|
|
38
39
|
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
@@ -52,7 +53,7 @@ function parseFlatProjection(value) {
|
|
|
52
53
|
const allowedDirs = toOptionalStringArray(outputsRaw.allowedDirs);
|
|
53
54
|
const deniedDirs = toOptionalStringArray(outputsRaw.deniedDirs);
|
|
54
55
|
const submission = {
|
|
55
|
-
model:
|
|
56
|
+
model: coerceRunUnitModel(submissionRaw.model),
|
|
56
57
|
...(typeof submissionRaw.system === "string" ? { system: submissionRaw.system } : {}),
|
|
57
58
|
prompt: toStringArray(submissionRaw.prompt),
|
|
58
59
|
skills: toSkillRefArray(submissionRaw.skills),
|
|
@@ -87,7 +88,7 @@ function fallbackFlat() {
|
|
|
87
88
|
return {
|
|
88
89
|
kind: "submission",
|
|
89
90
|
submission: {
|
|
90
|
-
model:
|
|
91
|
+
model: RunModels.CLAUDE_HAIKU_4_5,
|
|
91
92
|
prompt: [],
|
|
92
93
|
skills: [],
|
|
93
94
|
agentsMd: [],
|
|
@@ -104,6 +105,16 @@ function fallbackFlat() {
|
|
|
104
105
|
function isRecord(value) {
|
|
105
106
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
106
107
|
}
|
|
108
|
+
function coerceRunUnitModel(value) {
|
|
109
|
+
if (typeof value !== "string")
|
|
110
|
+
return RunModels.CLAUDE_HAIKU_4_5;
|
|
111
|
+
try {
|
|
112
|
+
return parseRunModel(value, "run unit submission.model");
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return RunModels.CLAUDE_HAIKU_4_5;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
107
118
|
function isJsonRecord(value) {
|
|
108
119
|
return isRecord(value);
|
|
109
120
|
}
|
|
@@ -2,6 +2,8 @@ import { PROXY_ENDPOINT_DEFAULTS, type ProxyAuthShape, type ProxyMethod, type Pr
|
|
|
2
2
|
export { PROXY_ENDPOINT_DEFAULTS };
|
|
3
3
|
import type { AgentsMdRef, FileRef, McpServerRef, SkillRef } from "./run-config.js";
|
|
4
4
|
import { type RuntimeSize } from "./runtime-sizes.js";
|
|
5
|
+
import { type PlatformPostHook, type PlatformPostHookInput } from "./post-hook.js";
|
|
6
|
+
import { type RunModel } from "./models.js";
|
|
5
7
|
import { type RuntimeSecurityProfileName } from "./runtime-security-profile.js";
|
|
6
8
|
import { type CredentialMode, type ManagedKeyPolicyV1 } from "./managed-key.js";
|
|
7
9
|
export type JsonPrimitive = string | number | boolean | null;
|
|
@@ -188,8 +190,6 @@ export interface PlatformProxyEndpoint {
|
|
|
188
190
|
readonly maxRequestBytes?: number;
|
|
189
191
|
readonly maxResponseBytes?: number;
|
|
190
192
|
readonly timeoutMs?: number;
|
|
191
|
-
readonly perCallBudget?: number;
|
|
192
|
-
readonly responseByteBudget?: number;
|
|
193
193
|
}
|
|
194
194
|
export declare const SECRETS_KEY = "secrets";
|
|
195
195
|
export declare const PROXY_ENDPOINT_NAME_PATTERN: RegExp;
|
|
@@ -228,7 +228,7 @@ export declare function optionalPositiveInt(input: unknown, field: string): numb
|
|
|
228
228
|
* into `run_skill_snapshots`), provider refs pass through unchanged.
|
|
229
229
|
*/
|
|
230
230
|
export interface PlatformSubmission {
|
|
231
|
-
readonly model:
|
|
231
|
+
readonly model: RunModel;
|
|
232
232
|
readonly system?: string;
|
|
233
233
|
readonly prompt: readonly string[];
|
|
234
234
|
readonly skills: readonly SkillRef[];
|
|
@@ -335,6 +335,13 @@ export interface PlatformRunSubmissionRequest {
|
|
|
335
335
|
* terminal wait window and self-kill deadline.
|
|
336
336
|
*/
|
|
337
337
|
readonly timeoutMs?: number;
|
|
338
|
+
/**
|
|
339
|
+
* Optional post-agent-run verifier. Parsed from the public `postHook`
|
|
340
|
+
* duration/string shape into fixed runner budgets. The runner executes it
|
|
341
|
+
* after a successful agent process and sends failures back through the model
|
|
342
|
+
* for repair until this budget is exhausted.
|
|
343
|
+
*/
|
|
344
|
+
readonly postHook?: PlatformPostHook;
|
|
338
345
|
}
|
|
339
346
|
/**
|
|
340
347
|
* Wire shape posted by the SDK and CLI. `workspaceId` is **omitted by
|
|
@@ -349,7 +356,7 @@ export interface PlatformRunSubmissionRequest {
|
|
|
349
356
|
* {@link DEFAULT_RUN_PROVIDER} (`anthropic`). The parser fills it in
|
|
350
357
|
* before the value enters the run snapshot.
|
|
351
358
|
*/
|
|
352
|
-
export type PlatformRunSubmissionInput = Omit<PlatformRunSubmissionRequest, "workspaceId" | "credentialMode" | "provider" | "runtime" | "timeoutMs"> & {
|
|
359
|
+
export type PlatformRunSubmissionInput = Omit<PlatformRunSubmissionRequest, "workspaceId" | "credentialMode" | "provider" | "runtime" | "timeoutMs" | "postHook"> & {
|
|
353
360
|
readonly workspaceId?: string;
|
|
354
361
|
readonly credentialMode?: CredentialMode;
|
|
355
362
|
readonly provider?: RunProvider;
|
|
@@ -365,6 +372,7 @@ export type PlatformRunSubmissionInput = Omit<PlatformRunSubmissionRequest, "wor
|
|
|
365
372
|
* {@link PlatformRunSubmissionRequest.timeoutMs}. Absent ⇒ 1h default.
|
|
366
373
|
*/
|
|
367
374
|
readonly timeout?: string;
|
|
375
|
+
readonly postHook?: PlatformPostHookInput;
|
|
368
376
|
};
|
|
369
377
|
export interface ParseRunSubmissionOptions {
|
|
370
378
|
readonly managedKeyPolicy?: ManagedKeyPolicyV1;
|
|
@@ -6,6 +6,8 @@ import { authShapeHeaderName, PROXY_ALLOWED_METHODS, PROXY_ENDPOINT_DEFAULTS, PR
|
|
|
6
6
|
export { PROXY_ENDPOINT_DEFAULTS };
|
|
7
7
|
import { parseAssetRefFields, parseMcpServerRef, parseSkillRef } from "./run-config.js";
|
|
8
8
|
import { parseRunTimeout, parseRuntimeSize } from "./runtime-sizes.js";
|
|
9
|
+
import { parsePostHook } from "./post-hook.js";
|
|
10
|
+
import { assertRunModelMatchesProvider, parseRunModel } from "./models.js";
|
|
9
11
|
import { parseRuntimeSecurityProfile } from "./runtime-security-profile.js";
|
|
10
12
|
import { assertManagedKeyAdmissionAllowed, parseCredentialMode } from "./managed-key.js";
|
|
11
13
|
/**
|
|
@@ -323,9 +325,7 @@ function parseProxyEndpoint(input, path) {
|
|
|
323
325
|
"responseMode",
|
|
324
326
|
"maxRequestBytes",
|
|
325
327
|
"maxResponseBytes",
|
|
326
|
-
"timeoutMs"
|
|
327
|
-
"perCallBudget",
|
|
328
|
-
"responseByteBudget"
|
|
328
|
+
"timeoutMs"
|
|
329
329
|
]);
|
|
330
330
|
for (const key of Object.keys(value)) {
|
|
331
331
|
if (!allowed.has(key)) {
|
|
@@ -348,8 +348,6 @@ function parseProxyEndpoint(input, path) {
|
|
|
348
348
|
const maxRequestBytes = optionalPositiveInt(value.maxRequestBytes, `${path}.maxRequestBytes`);
|
|
349
349
|
const maxResponseBytes = optionalPositiveInt(value.maxResponseBytes, `${path}.maxResponseBytes`);
|
|
350
350
|
const timeoutMs = optionalPositiveInt(value.timeoutMs, `${path}.timeoutMs`);
|
|
351
|
-
const perCallBudget = optionalPositiveInt(value.perCallBudget, `${path}.perCallBudget`);
|
|
352
|
-
const responseByteBudget = optionalPositiveInt(value.responseByteBudget, `${path}.responseByteBudget`);
|
|
353
351
|
return {
|
|
354
352
|
name,
|
|
355
353
|
baseUrl,
|
|
@@ -360,9 +358,7 @@ function parseProxyEndpoint(input, path) {
|
|
|
360
358
|
...(responseMode ? { responseMode } : {}),
|
|
361
359
|
...(maxRequestBytes !== undefined ? { maxRequestBytes } : {}),
|
|
362
360
|
...(maxResponseBytes !== undefined ? { maxResponseBytes } : {}),
|
|
363
|
-
...(timeoutMs !== undefined ? { timeoutMs } : {})
|
|
364
|
-
...(perCallBudget !== undefined ? { perCallBudget } : {}),
|
|
365
|
-
...(responseByteBudget !== undefined ? { responseByteBudget } : {})
|
|
361
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {})
|
|
366
362
|
};
|
|
367
363
|
}
|
|
368
364
|
function parseProxyBaseUrl(input, field) {
|
|
@@ -788,6 +784,7 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
788
784
|
"submission",
|
|
789
785
|
"runtimeSize",
|
|
790
786
|
"timeout",
|
|
787
|
+
"postHook",
|
|
791
788
|
"proxyEndpoints",
|
|
792
789
|
SECRETS_KEY
|
|
793
790
|
]);
|
|
@@ -821,11 +818,13 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
821
818
|
}
|
|
822
819
|
const runtimeSize = parseRuntimeSize(value.runtimeSize);
|
|
823
820
|
const timeoutMs = parseRunTimeout(value.timeout);
|
|
821
|
+
const postHook = parsePostHook(value.postHook, "submission.postHook");
|
|
824
822
|
const proxyEndpoints = parseProxyEndpoints(value.proxyEndpoints);
|
|
825
823
|
const secrets = parseInlineSecrets(value.secrets);
|
|
826
824
|
enforceCredentialSecretPolicy(credentialMode, secrets);
|
|
827
825
|
crossValidateProxyEndpointsAndAuth(proxyEndpoints, secrets.proxyEndpointAuth);
|
|
828
826
|
const submission = parseSubmission(value.submission);
|
|
827
|
+
assertRunModelMatchesProvider(provider, submission.model);
|
|
829
828
|
// mcpServers names must agree across the submission half and the
|
|
830
829
|
// secrets half — every secrets.mcpServers[i].name MUST resolve to a
|
|
831
830
|
// submission.mcpServers entry (no orphan secrets) AND the URL must
|
|
@@ -867,6 +866,7 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
867
866
|
submission,
|
|
868
867
|
...(runtimeSize ? { runtimeSize } : {}),
|
|
869
868
|
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
869
|
+
...(postHook !== undefined ? { postHook } : {}),
|
|
870
870
|
...(proxyEndpoints ? { proxyEndpoints } : {}),
|
|
871
871
|
secrets
|
|
872
872
|
};
|
|
@@ -933,7 +933,7 @@ export function parseSubmission(input) {
|
|
|
933
933
|
throw new Error(`submission.${key} is not an allowed field; permitted: ${[...allowed].join(", ")}`);
|
|
934
934
|
}
|
|
935
935
|
}
|
|
936
|
-
const model =
|
|
936
|
+
const model = parseRunModel(value.model, "submission.model");
|
|
937
937
|
const system = optionalString(value.system, "submission.system");
|
|
938
938
|
const prompt = parsePrompt(value.prompt);
|
|
939
939
|
const skills = parseSkills(value.skills);
|
package/dist/cli.mjs
CHANGED
|
@@ -15,8 +15,6 @@ var PROXY_PROTOCOL_HEADER = "x-aex-proxy-protocol";
|
|
|
15
15
|
var PROXY_RESP_STATUS_HEADER = "x-aex-proxy-status";
|
|
16
16
|
var PROXY_RESP_MODE_HEADER = "x-aex-proxy-effective-mode";
|
|
17
17
|
var PROXY_RESP_TRUNCATED_HEADER = "x-aex-proxy-truncated";
|
|
18
|
-
var PROXY_RESP_REMAINING_CALLS_HEADER = "x-aex-proxy-remaining-calls";
|
|
19
|
-
var PROXY_RESP_REMAINING_BYTES_HEADER = "x-aex-proxy-remaining-bytes";
|
|
20
18
|
var PROXY_RESP_UPSTREAM_HEADERS_HEADER = "x-aex-proxy-upstream-headers";
|
|
21
19
|
var PROXY_METHOD_HEADER = "x-aex-method";
|
|
22
20
|
var PROXY_PATH_HEADER = "x-aex-path";
|
|
@@ -28,10 +26,10 @@ var PROXY_ENDPOINT_DEFAULTS = {
|
|
|
28
26
|
allowHeaders: [],
|
|
29
27
|
responseMode: "headers_only",
|
|
30
28
|
maxRequestBytes: 64 * 1024,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
// Unlimited (0). The request body is buffered to enforce its cap, so that
|
|
30
|
+
// stays finite; the response is streamed, so it does not need one.
|
|
31
|
+
maxResponseBytes: 0,
|
|
32
|
+
timeoutMs: 1e4
|
|
35
33
|
};
|
|
36
34
|
|
|
37
35
|
// ../contracts/dist/provider-support.js
|
|
@@ -121,6 +119,52 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
121
119
|
}
|
|
122
120
|
};
|
|
123
121
|
|
|
122
|
+
// ../contracts/dist/models.js
|
|
123
|
+
var RUN_MODELS = [
|
|
124
|
+
"claude-haiku-4-5",
|
|
125
|
+
"claude-3-5-haiku-latest",
|
|
126
|
+
"claude-3-5-sonnet-latest",
|
|
127
|
+
"deepseek-chat",
|
|
128
|
+
"gpt-4.1",
|
|
129
|
+
"gpt-4o-mini",
|
|
130
|
+
"gemini-2.0-flash",
|
|
131
|
+
"gemini-2.5-flash",
|
|
132
|
+
"mistral-large-latest",
|
|
133
|
+
"mistral-small-latest"
|
|
134
|
+
];
|
|
135
|
+
var RunModels = {
|
|
136
|
+
CLAUDE_HAIKU_4_5: "claude-haiku-4-5",
|
|
137
|
+
CLAUDE_3_5_HAIKU_LATEST: "claude-3-5-haiku-latest",
|
|
138
|
+
CLAUDE_3_5_SONNET_LATEST: "claude-3-5-sonnet-latest",
|
|
139
|
+
DEEPSEEK_CHAT: "deepseek-chat",
|
|
140
|
+
GPT_4_1: "gpt-4.1",
|
|
141
|
+
GPT_4O_MINI: "gpt-4o-mini",
|
|
142
|
+
GEMINI_2_0_FLASH: "gemini-2.0-flash",
|
|
143
|
+
GEMINI_2_5_FLASH: "gemini-2.5-flash",
|
|
144
|
+
MISTRAL_LARGE_LATEST: "mistral-large-latest",
|
|
145
|
+
MISTRAL_SMALL_LATEST: "mistral-small-latest"
|
|
146
|
+
};
|
|
147
|
+
var RUN_MODELS_BY_PROVIDER = {
|
|
148
|
+
anthropic: [
|
|
149
|
+
RunModels.CLAUDE_HAIKU_4_5,
|
|
150
|
+
RunModels.CLAUDE_3_5_HAIKU_LATEST,
|
|
151
|
+
RunModels.CLAUDE_3_5_SONNET_LATEST
|
|
152
|
+
],
|
|
153
|
+
deepseek: [RunModels.DEEPSEEK_CHAT],
|
|
154
|
+
openai: [RunModels.GPT_4_1, RunModels.GPT_4O_MINI],
|
|
155
|
+
gemini: [RunModels.GEMINI_2_0_FLASH, RunModels.GEMINI_2_5_FLASH],
|
|
156
|
+
mistral: [RunModels.MISTRAL_LARGE_LATEST, RunModels.MISTRAL_SMALL_LATEST]
|
|
157
|
+
};
|
|
158
|
+
function isRunModel(input) {
|
|
159
|
+
return typeof input === "string" && RUN_MODELS.includes(input);
|
|
160
|
+
}
|
|
161
|
+
function parseRunModel(input, field = "submission.model") {
|
|
162
|
+
if (!isRunModel(input)) {
|
|
163
|
+
throw new Error(`${field} must be one of: ${RUN_MODELS.join(", ")}`);
|
|
164
|
+
}
|
|
165
|
+
return input;
|
|
166
|
+
}
|
|
167
|
+
|
|
124
168
|
// ../contracts/dist/status.js
|
|
125
169
|
var TERMINAL_RUN_STATUSES = [
|
|
126
170
|
"succeeded",
|
|
@@ -133,15 +177,113 @@ var TERMINAL_RUN_STATUSES = [
|
|
|
133
177
|
];
|
|
134
178
|
var terminalRunStatuses = new Set(TERMINAL_RUN_STATUSES);
|
|
135
179
|
|
|
180
|
+
// ../contracts/dist/runtime-sizes.js
|
|
181
|
+
var RUNTIME_SIZE_PRESETS = {
|
|
182
|
+
"shared-1x-256mb": { cpus: 1, memoryMb: 256 },
|
|
183
|
+
"shared-1x-512mb": { cpus: 1, memoryMb: 512 },
|
|
184
|
+
"shared-1x-1gb": { cpus: 1, memoryMb: 1024 },
|
|
185
|
+
"shared-1x-2gb": { cpus: 1, memoryMb: 2048 },
|
|
186
|
+
"shared-2x-512mb": { cpus: 2, memoryMb: 512 },
|
|
187
|
+
"shared-2x-1gb": { cpus: 2, memoryMb: 1024 },
|
|
188
|
+
"shared-2x-2gb": { cpus: 2, memoryMb: 2048 },
|
|
189
|
+
"shared-2x-4gb": { cpus: 2, memoryMb: 4096 },
|
|
190
|
+
"shared-4x-1gb": { cpus: 4, memoryMb: 1024 },
|
|
191
|
+
"shared-4x-2gb": { cpus: 4, memoryMb: 2048 },
|
|
192
|
+
"shared-4x-4gb": { cpus: 4, memoryMb: 4096 },
|
|
193
|
+
"shared-4x-8gb": { cpus: 4, memoryMb: 8192 },
|
|
194
|
+
"shared-8x-2gb": { cpus: 8, memoryMb: 2048 },
|
|
195
|
+
"shared-8x-4gb": { cpus: 8, memoryMb: 4096 },
|
|
196
|
+
"shared-8x-8gb": { cpus: 8, memoryMb: 8192 },
|
|
197
|
+
"shared-8x-16gb": { cpus: 8, memoryMb: 16384 }
|
|
198
|
+
};
|
|
199
|
+
var RUNTIME_SIZES = Object.keys(RUNTIME_SIZE_PRESETS);
|
|
200
|
+
var DEFAULT_RUN_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
201
|
+
var MAX_RUN_TIMEOUT_MS = 6 * 60 * 60 * 1e3;
|
|
202
|
+
var MIN_RUN_TIMEOUT_MS = 60 * 1e3;
|
|
203
|
+
var DURATION_PATTERN = /^(\d+(?:\.\d+)?)(ms|s|m|h)?$/;
|
|
204
|
+
function parseDurationToMs(input) {
|
|
205
|
+
const match = DURATION_PATTERN.exec(input.trim());
|
|
206
|
+
if (!match) {
|
|
207
|
+
throw new Error(`invalid duration ${JSON.stringify(input)} (expected e.g. "1h", "90m", "30s", "500ms", or a bare ms integer)`);
|
|
208
|
+
}
|
|
209
|
+
const value = Number(match[1]);
|
|
210
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
211
|
+
throw new Error(`invalid duration ${JSON.stringify(input)} (must be a non-negative number)`);
|
|
212
|
+
}
|
|
213
|
+
const unit = match[2] ?? "ms";
|
|
214
|
+
const factor = unit === "h" ? 36e5 : unit === "m" ? 6e4 : unit === "s" ? 1e3 : 1;
|
|
215
|
+
return Math.round(value * factor);
|
|
216
|
+
}
|
|
217
|
+
var RUN_PROCESS_KILL_GRACE_MS = 60 * 1e3;
|
|
218
|
+
var RUN_TERMINAL_GRACE_MS = 90 * 1e3;
|
|
219
|
+
|
|
220
|
+
// ../contracts/dist/post-hook.js
|
|
221
|
+
var DEFAULT_POST_HOOK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
222
|
+
var DEFAULT_POST_HOOK_MAX_TURNS = 10;
|
|
223
|
+
function parsePostHook(input, path = "postHook") {
|
|
224
|
+
if (input === void 0 || input === null) {
|
|
225
|
+
return void 0;
|
|
226
|
+
}
|
|
227
|
+
const value = requirePostHookRecord(input, path);
|
|
228
|
+
const allowed = /* @__PURE__ */ new Set(["command", "timeout", "maxTurns", "maxChars"]);
|
|
229
|
+
for (const key of Object.keys(value)) {
|
|
230
|
+
if (!allowed.has(key)) {
|
|
231
|
+
throw new Error(`${path}.${key} is not an allowed field; permitted: command, timeout, maxTurns, maxChars`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (typeof value.command !== "string") {
|
|
235
|
+
throw new Error(`${path}.command must be a string`);
|
|
236
|
+
}
|
|
237
|
+
if (value.command.trim().length === 0) {
|
|
238
|
+
return void 0;
|
|
239
|
+
}
|
|
240
|
+
const timeoutMs = parsePostHookTimeout(value.timeout, `${path}.timeout`);
|
|
241
|
+
const maxTurns = parseNonNegativeInteger(value.maxTurns, `${path}.maxTurns`, DEFAULT_POST_HOOK_MAX_TURNS);
|
|
242
|
+
const maxChars = value.maxChars === null ? null : parseNonNegativeInteger(value.maxChars, `${path}.maxChars`, null);
|
|
243
|
+
return {
|
|
244
|
+
command: value.command,
|
|
245
|
+
timeoutMs,
|
|
246
|
+
maxTurns,
|
|
247
|
+
maxChars
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function parsePostHookTimeout(input, path) {
|
|
251
|
+
if (input === void 0) {
|
|
252
|
+
return DEFAULT_POST_HOOK_TIMEOUT_MS;
|
|
253
|
+
}
|
|
254
|
+
if (typeof input !== "string") {
|
|
255
|
+
throw new Error(`${path} must be a duration string (e.g. "5m", "30s"); got ${JSON.stringify(input)}`);
|
|
256
|
+
}
|
|
257
|
+
const ms = parseDurationToMs(input);
|
|
258
|
+
if (ms <= 0) {
|
|
259
|
+
throw new Error(`${path} must be greater than 0ms; got ${ms}ms`);
|
|
260
|
+
}
|
|
261
|
+
return ms;
|
|
262
|
+
}
|
|
263
|
+
function parseNonNegativeInteger(input, path, defaultValue) {
|
|
264
|
+
if (input === void 0) {
|
|
265
|
+
return defaultValue;
|
|
266
|
+
}
|
|
267
|
+
if (typeof input !== "number" || !Number.isSafeInteger(input) || input < 0) {
|
|
268
|
+
throw new Error(`${path} must be a non-negative integer`);
|
|
269
|
+
}
|
|
270
|
+
return input;
|
|
271
|
+
}
|
|
272
|
+
function requirePostHookRecord(input, path) {
|
|
273
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
274
|
+
throw new Error(`${path} must be an object`);
|
|
275
|
+
}
|
|
276
|
+
return input;
|
|
277
|
+
}
|
|
278
|
+
|
|
136
279
|
// ../contracts/dist/run-config.js
|
|
137
280
|
var SKILL_BUNDLE_LIMITS = {
|
|
138
281
|
/** Compressed (.zip) ceiling. */
|
|
139
282
|
maxCompressedBytes: 10 * 1024 * 1024,
|
|
140
283
|
/**
|
|
141
|
-
* Hard ceiling for the direct-to-storage
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* limit; objects above this would need S3 multipart, which is out of scope.
|
|
284
|
+
* Hard ceiling for the direct-to-storage upload path. Bytes never transit the
|
|
285
|
+
* hosted API, so its memory/request-payload limits do not cap accepted
|
|
286
|
+
* bundles; objects above this product cap are rejected before upload.
|
|
145
287
|
*/
|
|
146
288
|
maxBytes: 2 * 1024 * 1024 * 1024,
|
|
147
289
|
/** Sum of uncompressed file sizes. */
|
|
@@ -448,6 +590,7 @@ function parseRunRequestConfig(input) {
|
|
|
448
590
|
"environment",
|
|
449
591
|
"runtimeSize",
|
|
450
592
|
"timeout",
|
|
593
|
+
"postHook",
|
|
451
594
|
"proxyEndpoints",
|
|
452
595
|
"metadata"
|
|
453
596
|
]);
|
|
@@ -456,10 +599,7 @@ function parseRunRequestConfig(input) {
|
|
|
456
599
|
throw new Error(`run request config contains unexpected field: ${key}`);
|
|
457
600
|
}
|
|
458
601
|
}
|
|
459
|
-
const model = record.model;
|
|
460
|
-
if (typeof model !== "string" || model.length === 0) {
|
|
461
|
-
throw new Error("run request config model must be a non-empty string");
|
|
462
|
-
}
|
|
602
|
+
const model = parseRunModel(record.model, "run request config model");
|
|
463
603
|
const system = record.system;
|
|
464
604
|
if (system !== void 0 && typeof system !== "string") {
|
|
465
605
|
throw new Error("run request config system, when provided, must be a string");
|
|
@@ -467,6 +607,7 @@ function parseRunRequestConfig(input) {
|
|
|
467
607
|
const prompt = parseRunRequestConfigPrompt(record.prompt);
|
|
468
608
|
const skills = parseRunRequestConfigSkills(record.skills);
|
|
469
609
|
const mcpServers = parseRunRequestConfigMcpServers(record.mcpServers);
|
|
610
|
+
const postHook = parsePostHook(record.postHook, "run request config postHook");
|
|
470
611
|
return {
|
|
471
612
|
model,
|
|
472
613
|
...system !== void 0 ? { system } : {},
|
|
@@ -480,6 +621,7 @@ function parseRunRequestConfig(input) {
|
|
|
480
621
|
...record.environment !== void 0 ? { environment: record.environment } : {},
|
|
481
622
|
...record.runtimeSize !== void 0 ? { runtimeSize: record.runtimeSize } : {},
|
|
482
623
|
...record.timeout !== void 0 ? { timeout: record.timeout } : {},
|
|
624
|
+
...postHook !== void 0 ? { postHook: record.postHook } : {},
|
|
483
625
|
...record.proxyEndpoints !== void 0 ? { proxyEndpoints: record.proxyEndpoints } : {},
|
|
484
626
|
...record.metadata !== void 0 ? { metadata: record.metadata } : {}
|
|
485
627
|
};
|
|
@@ -534,32 +676,6 @@ function parseRunRequestConfigMcpServers(value) {
|
|
|
534
676
|
});
|
|
535
677
|
}
|
|
536
678
|
|
|
537
|
-
// ../contracts/dist/runtime-sizes.js
|
|
538
|
-
var RUNTIME_SIZE_PRESETS = {
|
|
539
|
-
"shared-1x-256mb": { cpus: 1, memoryMb: 256 },
|
|
540
|
-
"shared-1x-512mb": { cpus: 1, memoryMb: 512 },
|
|
541
|
-
"shared-1x-1gb": { cpus: 1, memoryMb: 1024 },
|
|
542
|
-
"shared-1x-2gb": { cpus: 1, memoryMb: 2048 },
|
|
543
|
-
"shared-2x-512mb": { cpus: 2, memoryMb: 512 },
|
|
544
|
-
"shared-2x-1gb": { cpus: 2, memoryMb: 1024 },
|
|
545
|
-
"shared-2x-2gb": { cpus: 2, memoryMb: 2048 },
|
|
546
|
-
"shared-2x-4gb": { cpus: 2, memoryMb: 4096 },
|
|
547
|
-
"shared-4x-1gb": { cpus: 4, memoryMb: 1024 },
|
|
548
|
-
"shared-4x-2gb": { cpus: 4, memoryMb: 2048 },
|
|
549
|
-
"shared-4x-4gb": { cpus: 4, memoryMb: 4096 },
|
|
550
|
-
"shared-4x-8gb": { cpus: 4, memoryMb: 8192 },
|
|
551
|
-
"shared-8x-2gb": { cpus: 8, memoryMb: 2048 },
|
|
552
|
-
"shared-8x-4gb": { cpus: 8, memoryMb: 4096 },
|
|
553
|
-
"shared-8x-8gb": { cpus: 8, memoryMb: 8192 },
|
|
554
|
-
"shared-8x-16gb": { cpus: 8, memoryMb: 16384 }
|
|
555
|
-
};
|
|
556
|
-
var RUNTIME_SIZES = Object.keys(RUNTIME_SIZE_PRESETS);
|
|
557
|
-
var DEFAULT_RUN_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
558
|
-
var MAX_RUN_TIMEOUT_MS = 6 * 60 * 60 * 1e3;
|
|
559
|
-
var MIN_RUN_TIMEOUT_MS = 60 * 1e3;
|
|
560
|
-
var RUN_PROCESS_KILL_GRACE_MS = 60 * 1e3;
|
|
561
|
-
var RUN_TERMINAL_GRACE_MS = 90 * 1e3;
|
|
562
|
-
|
|
563
679
|
// ../contracts/dist/runtime-security-profile.js
|
|
564
680
|
var RUNTIME_SECURITY_PROFILE_CONFIG = Object.freeze({
|
|
565
681
|
strict: Object.freeze({
|
|
@@ -2642,7 +2758,7 @@ async function printProxyHelp(io2) {
|
|
|
2642
2758
|
if (manifest && manifest.endpoints.length > 0) {
|
|
2643
2759
|
io2.stdout("Declared endpoints:\n");
|
|
2644
2760
|
for (const ep of manifest.endpoints) {
|
|
2645
|
-
io2.stdout(` \u2022 ${ep.name}: ${ep.allowMethods.join(",")} ${ep.allowPathPrefixes.join(",")} (mode=${ep.responseMode}
|
|
2761
|
+
io2.stdout(` \u2022 ${ep.name}: ${ep.allowMethods.join(",")} ${ep.allowPathPrefixes.join(",")} (mode=${ep.responseMode})
|
|
2646
2762
|
`);
|
|
2647
2763
|
}
|
|
2648
2764
|
}
|
|
@@ -2801,8 +2917,6 @@ function emitError(io2, body) {
|
|
|
2801
2917
|
async function readStreamedEnvelope(response, endpointName) {
|
|
2802
2918
|
const effectiveResponseMode = response.headers.get(PROXY_RESP_MODE_HEADER) ?? "headers_only";
|
|
2803
2919
|
const upstreamStatus = Number.parseInt(response.headers.get(PROXY_RESP_STATUS_HEADER) ?? "0", 10);
|
|
2804
|
-
const remainingCalls = Number.parseInt(response.headers.get(PROXY_RESP_REMAINING_CALLS_HEADER) ?? "0", 10);
|
|
2805
|
-
const remainingResponseBytes = Number.parseInt(response.headers.get(PROXY_RESP_REMAINING_BYTES_HEADER) ?? "0", 10);
|
|
2806
2920
|
let upstreamHeaders = {};
|
|
2807
2921
|
const rawHeaders = response.headers.get(PROXY_RESP_UPSTREAM_HEADERS_HEADER);
|
|
2808
2922
|
if (rawHeaders) {
|
|
@@ -2825,8 +2939,6 @@ async function readStreamedEnvelope(response, endpointName) {
|
|
|
2825
2939
|
// isn't carried back); the effective mode is authoritative for the
|
|
2826
2940
|
// agent and matches what v1 surfaced for an un-clamped call.
|
|
2827
2941
|
modeClamped: false,
|
|
2828
|
-
remainingCalls,
|
|
2829
|
-
remainingResponseBytes,
|
|
2830
2942
|
...effectiveResponseMode === "full" && bytes.byteLength > 0 ? { upstreamBodyBase64: Buffer.from(bytes).toString("base64") } : {},
|
|
2831
2943
|
...truncatedRaw === "true" ? { truncated: true } : {}
|
|
2832
2944
|
};
|
|
@@ -3058,6 +3170,11 @@ async function runRunCmd(io2, argv) {
|
|
|
3058
3170
|
io2.stderr("--model is required when --config is not provided\n");
|
|
3059
3171
|
return USAGE_ERR;
|
|
3060
3172
|
}
|
|
3173
|
+
if (!RUN_MODELS.includes(modelFlag.value)) {
|
|
3174
|
+
io2.stderr(`--model must be one of: ${RUN_MODELS.join(", ")} (got: ${modelFlag.value})
|
|
3175
|
+
`);
|
|
3176
|
+
return USAGE_ERR;
|
|
3177
|
+
}
|
|
3061
3178
|
if (promptFlags.values.length === 0) {
|
|
3062
3179
|
io2.stderr("--prompt is required (repeatable)\n");
|
|
3063
3180
|
return USAGE_ERR;
|
|
@@ -3186,6 +3303,7 @@ async function runRunCmd(io2, argv) {
|
|
|
3186
3303
|
secrets,
|
|
3187
3304
|
...runtimeSizeFlag.value ? { runtimeSize: runtimeSizeFlag.value } : runConfig.runtimeSize ? { runtimeSize: runConfig.runtimeSize } : {},
|
|
3188
3305
|
...runTimeoutFlag.value ? { timeout: runTimeoutFlag.value } : runConfig.timeout ? { timeout: runConfig.timeout } : {},
|
|
3306
|
+
...runConfig.postHook ? { postHook: runConfig.postHook } : {},
|
|
3189
3307
|
...proxyEndpoints.length > 0 ? { proxyEndpoints } : {}
|
|
3190
3308
|
};
|
|
3191
3309
|
const http = makeHttpClient(io2, common.flags);
|
|
@@ -4080,7 +4198,7 @@ Protocol version: ${manifest.protocolVersion}
|
|
|
4080
4198
|
io2.stdout(" aex wait <run-id> [--timeout 8m] [--interval 2s] --api-token T\n");
|
|
4081
4199
|
io2.stdout(" aex events <run-id> [--follow] [--timeout 8m] --api-token T\n");
|
|
4082
4200
|
io2.stdout(" aex outputs <run-id> --api-token T\n");
|
|
4083
|
-
io2.stdout(" aex download <run-id> [--out path] --api-token T\n");
|
|
4201
|
+
io2.stdout(" aex download <run-id> [--only outputs|events|metadata] [--out path] --api-token T\n");
|
|
4084
4202
|
io2.stdout(" aex cancel <run-id> --api-token T\n");
|
|
4085
4203
|
io2.stdout(" aex delete <run-id> --api-token T\n");
|
|
4086
4204
|
io2.stdout(" aex delete-asset <assetId|hash> --api-token T\n");
|
package/dist/cli.mjs.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
0867878a9456f95c87fe93ca1aac5879b7c44ab5f3d1c7f110c8cab2259540a3 cli.mjs
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HttpClient, type AexEvent, type AgentsMdRecord, type CredentialMode, type DebugSink, type FetchLike, type FileRecord, type Output, type OutputMode, type PlatformEnvironmentInput, type PlatformSubmission, type PlatformInlineSecrets, type PlatformProxyEndpoint, type PlatformProxyEndpointAuth, type Run, type RunEvent, type RunProvider, type RunUnit, type RuntimeSize, type RuntimeKind, type SignedOutputLink, type Skill as SkillRecord, type WhoAmI } from "./_contracts/index.js";
|
|
1
|
+
import { HttpClient, type AexEvent, type AgentsMdRecord, type CredentialMode, type DebugSink, type FetchLike, type FileRecord, type Output, type OutputMode, type PlatformEnvironmentInput, type PlatformSubmission, type PlatformInlineSecrets, type PlatformProxyEndpoint, type PlatformProxyEndpointAuth, type PlatformPostHookInput, type Run, type RunModel, type RunEvent, type RunProvider, type RunUnit, type RuntimeSize, type RuntimeKind, type SignedOutputLink, type Skill as SkillRecord, type WhoAmI } from "./_contracts/index.js";
|
|
2
2
|
import { AgentsMd } from "./agents-md.js";
|
|
3
3
|
import { type UploadedAsset } from "./asset-upload.js";
|
|
4
4
|
import { File } from "./file.js";
|
|
@@ -66,7 +66,11 @@ export interface SubmitRunOptions {
|
|
|
66
66
|
* is no longer accepted.
|
|
67
67
|
*/
|
|
68
68
|
readonly runtime?: RuntimeKind;
|
|
69
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Closed public model id. Prefer {@link RunModels}, e.g.
|
|
71
|
+
* `RunModels.CLAUDE_HAIKU_4_5`.
|
|
72
|
+
*/
|
|
73
|
+
readonly model: RunModel;
|
|
70
74
|
readonly system?: string;
|
|
71
75
|
readonly prompt: string | readonly string[];
|
|
72
76
|
readonly skills?: readonly Skill[];
|
|
@@ -86,6 +90,12 @@ export interface SubmitRunOptions {
|
|
|
86
90
|
* [1m, 6h]; omit for the 1h default. Applies to both runtimes.
|
|
87
91
|
*/
|
|
88
92
|
readonly timeout?: string;
|
|
93
|
+
/**
|
|
94
|
+
* Command to run after the agent process exits successfully. A non-zero exit
|
|
95
|
+
* or timeout is sent back to the model as a repair prompt until `maxTurns`
|
|
96
|
+
* is exhausted. Empty commands are treated as omitted.
|
|
97
|
+
*/
|
|
98
|
+
readonly postHook?: PlatformPostHookInput;
|
|
89
99
|
readonly proxyEndpoints?: readonly ProxyEndpoint[];
|
|
90
100
|
/**
|
|
91
101
|
* Output capture policy for the run's output files.
|
package/dist/client.js
CHANGED
|
@@ -320,6 +320,7 @@ export class AgentExecutor {
|
|
|
320
320
|
...(mergedMcpSecrets.length > 0 ? { mcpServers: mergedMcpSecrets } : {}),
|
|
321
321
|
...(mergedProxyAuth.length > 0 ? { proxyEndpointAuth: mergedProxyAuth } : {})
|
|
322
322
|
};
|
|
323
|
+
const postHook = postHookForWire(options.postHook);
|
|
323
324
|
const request = {
|
|
324
325
|
idempotencyKey: options.idempotencyKey ?? generateIdempotencyKey(),
|
|
325
326
|
// Always include `provider` on the wire so dashboard / proxy
|
|
@@ -335,6 +336,7 @@ export class AgentExecutor {
|
|
|
335
336
|
submission,
|
|
336
337
|
...(options.runtimeSize ? { runtimeSize: options.runtimeSize } : {}),
|
|
337
338
|
...(options.timeout ? { timeout: options.timeout } : {}),
|
|
339
|
+
...(postHook ? { postHook } : {}),
|
|
338
340
|
secrets,
|
|
339
341
|
...(proxyEndpointDeclarations.length > 0
|
|
340
342
|
? { proxyEndpoints: proxyEndpointDeclarations }
|
|
@@ -633,6 +635,12 @@ function normalisePrompt(input) {
|
|
|
633
635
|
}
|
|
634
636
|
return [...input];
|
|
635
637
|
}
|
|
638
|
+
function postHookForWire(input) {
|
|
639
|
+
if (input === undefined || typeof input.command !== "string" || input.command.trim().length === 0) {
|
|
640
|
+
return undefined;
|
|
641
|
+
}
|
|
642
|
+
return input;
|
|
643
|
+
}
|
|
636
644
|
/** Walk Skill[], eagerly upload drafts as assets, and return plain asset refs. */
|
|
637
645
|
async function prepareSkills(skills, uploader) {
|
|
638
646
|
const refs = [];
|