@aexhq/sdk 0.34.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 +62 -95
- package/dist/_contracts/submission.js +59 -482
- package/dist/cli.mjs +99 -442
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +49 -25
- package/dist/client.js +341 -70
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +9 -15
- package/dist/index.js +11 -17
- package/dist/index.js.map +1 -1
- package/dist/retry.d.ts +162 -0
- package/dist/retry.js +320 -0
- package/dist/retry.js.map +1 -0
- 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/retries.md +129 -0
- 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 +284 -0
- 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/retry.js
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in transport resilience for the aex SDK.
|
|
3
|
+
*
|
|
4
|
+
* Every BFF-bound request the SDK makes goes through one {@link FetchLike}. This
|
|
5
|
+
* module wraps that fetch so a transient failure — an HTTP 429 (rate limited),
|
|
6
|
+
* a 500/502/503/504 (server hiccup), a 529 (upstream overloaded), or a network
|
|
7
|
+
* error — is retried with BOUNDED exponential backoff + full jitter, honoring
|
|
8
|
+
* the server's `Retry-After` header when present. Non-retryable 4xx responses
|
|
9
|
+
* (400/401/403/404/…) fail fast — retrying them only wastes the caller's time.
|
|
10
|
+
*
|
|
11
|
+
* Retries are SAFE to enable by default because the billable submits
|
|
12
|
+
* (`createSession` / `sendSessionMessage`) carry a stable `Idempotency-Key`
|
|
13
|
+
* header: re-sending the identical request de-duplicates server-side, so a retry
|
|
14
|
+
* never creates a duplicate billable turn.
|
|
15
|
+
*
|
|
16
|
+
* When retries are exhausted on a rate-limit / overloaded status the wrapper
|
|
17
|
+
* surfaces an {@link AexRateLimitError} — a structured, non-leaky throttle error
|
|
18
|
+
* carrying the parsed `retryAfterMs`, the attempt count, and (when the runtime
|
|
19
|
+
* supplies it) an upstream {@link ProviderFault}. All other exhausted retries
|
|
20
|
+
* fall through to the transport's usual `AexApiError` / network rejection.
|
|
21
|
+
*/
|
|
22
|
+
import { AexApiError } from "./_contracts/index.js";
|
|
23
|
+
/**
|
|
24
|
+
* HTTP statuses that are transient and worth retrying. The billable submits
|
|
25
|
+
* carry an idempotency key, so re-issuing them is safe. Everything not in this
|
|
26
|
+
* set (400/401/403/404/409/422/…) is a definitive client error and fails fast.
|
|
27
|
+
*/
|
|
28
|
+
export const RETRYABLE_STATUS = [429, 500, 502, 503, 504, 529];
|
|
29
|
+
/**
|
|
30
|
+
* The subset of {@link RETRYABLE_STATUS} the platform / upstream provider uses to
|
|
31
|
+
* say "slow down": 429 rate-limit, 503 unavailable, 529 overloaded. When retries
|
|
32
|
+
* for one of these run out, the wrapper raises an {@link AexRateLimitError}.
|
|
33
|
+
*/
|
|
34
|
+
export const RATE_LIMIT_STATUS = [429, 503, 529];
|
|
35
|
+
const DEFAULT_RETRY = {
|
|
36
|
+
maxAttempts: 4,
|
|
37
|
+
initialDelayMs: 500,
|
|
38
|
+
maxDelayMs: 20_000,
|
|
39
|
+
maxElapsedMs: 120_000
|
|
40
|
+
};
|
|
41
|
+
/** Resolve caller options over the defaults, clamping to sane bounds. */
|
|
42
|
+
export function resolveRetryConfig(options) {
|
|
43
|
+
const maxAttempts = Math.max(1, Math.floor(options?.maxAttempts ?? DEFAULT_RETRY.maxAttempts));
|
|
44
|
+
const initialDelayMs = Math.max(0, options?.initialDelayMs ?? DEFAULT_RETRY.initialDelayMs);
|
|
45
|
+
const maxDelayMs = Math.max(initialDelayMs, options?.maxDelayMs ?? DEFAULT_RETRY.maxDelayMs);
|
|
46
|
+
const maxElapsedMs = Math.max(0, options?.maxElapsedMs ?? DEFAULT_RETRY.maxElapsedMs);
|
|
47
|
+
return { maxAttempts, initialDelayMs, maxDelayMs, maxElapsedMs };
|
|
48
|
+
}
|
|
49
|
+
export function isRetryableStatus(status) {
|
|
50
|
+
return RETRYABLE_STATUS.includes(status);
|
|
51
|
+
}
|
|
52
|
+
export function isRateLimitStatus(status) {
|
|
53
|
+
return RATE_LIMIT_STATUS.includes(status);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Parse an HTTP `Retry-After` header into milliseconds. Per RFC 7231 the value
|
|
57
|
+
* is either a non-negative integer number of seconds or an HTTP-date; both are
|
|
58
|
+
* handled. Returns `undefined` for a missing or unparseable value.
|
|
59
|
+
*/
|
|
60
|
+
export function parseRetryAfterMs(headerValue, now = Date.now()) {
|
|
61
|
+
if (headerValue === null || headerValue === undefined)
|
|
62
|
+
return undefined;
|
|
63
|
+
const trimmed = headerValue.trim();
|
|
64
|
+
if (trimmed.length === 0)
|
|
65
|
+
return undefined;
|
|
66
|
+
if (/^\d+$/.test(trimmed)) {
|
|
67
|
+
return Number(trimmed) * 1000;
|
|
68
|
+
}
|
|
69
|
+
const dateMs = Date.parse(trimmed);
|
|
70
|
+
if (!Number.isNaN(dateMs)) {
|
|
71
|
+
return Math.max(0, dateMs - now);
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Full-jitter exponential backoff (AWS-style): the nominal wait doubles per
|
|
77
|
+
* retry up to `maxDelayMs`, and the actual wait is a uniform sample in
|
|
78
|
+
* `[0, nominal]` to de-correlate concurrent clients. `attemptNumber` is the
|
|
79
|
+
* 1-based number of the attempt that just failed.
|
|
80
|
+
*/
|
|
81
|
+
export function computeBackoffDelayMs(config, attemptNumber, random) {
|
|
82
|
+
const exponent = Math.max(0, attemptNumber - 1);
|
|
83
|
+
const nominal = Math.min(config.maxDelayMs, config.initialDelayMs * 2 ** exponent);
|
|
84
|
+
return Math.round(random() * nominal);
|
|
85
|
+
}
|
|
86
|
+
/** Combine the server's `Retry-After` (a floor) with our jittered backoff. */
|
|
87
|
+
function nextDelayMs(config, attemptNumber, random, retryAfterMs) {
|
|
88
|
+
const backoff = computeBackoffDelayMs(config, attemptNumber, random);
|
|
89
|
+
return retryAfterMs === undefined ? backoff : Math.max(retryAfterMs, backoff);
|
|
90
|
+
}
|
|
91
|
+
const THROTTLE_KINDS = new Set(["rate_limit", "overloaded", "quota_exceeded"]);
|
|
92
|
+
/** True when a {@link ProviderFault} represents a "back off and retry" signal. */
|
|
93
|
+
export function isThrottleFault(fault) {
|
|
94
|
+
return THROTTLE_KINDS.has(fault.kind);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Structured throttle error. Extends {@link AexApiError} so existing
|
|
98
|
+
* `catch (err instanceof AexApiError)` sites keep working, while callers that
|
|
99
|
+
* want the details narrow with {@link isRateLimited} and read `retryAfterMs`,
|
|
100
|
+
* `attempts`, `source`, and `providerFault`. The `message` is a fixed,
|
|
101
|
+
* non-leaky summary — it never echoes the raw error body (which is still
|
|
102
|
+
* available, redacted, on `.body`).
|
|
103
|
+
*/
|
|
104
|
+
export class AexRateLimitError extends AexApiError {
|
|
105
|
+
/** Milliseconds the server/provider asked us to wait, when known. */
|
|
106
|
+
retryAfterMs;
|
|
107
|
+
/** How many attempts were made before giving up. */
|
|
108
|
+
attempts;
|
|
109
|
+
/** Whether the throttle came from the aex API plane or the upstream provider. */
|
|
110
|
+
source;
|
|
111
|
+
/** The upstream provider fault, when the throttle originated there. */
|
|
112
|
+
providerFault;
|
|
113
|
+
constructor(args) {
|
|
114
|
+
super(args.status, args.message ?? defaultThrottleMessage(args), args.body);
|
|
115
|
+
this.attempts = args.attempts;
|
|
116
|
+
this.source = args.source ?? "api";
|
|
117
|
+
if (args.retryAfterMs !== undefined)
|
|
118
|
+
this.retryAfterMs = args.retryAfterMs;
|
|
119
|
+
if (args.providerFault !== undefined)
|
|
120
|
+
this.providerFault = args.providerFault;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Type guard for {@link AexRateLimitError}. */
|
|
124
|
+
export function isRateLimited(err) {
|
|
125
|
+
return err instanceof AexRateLimitError;
|
|
126
|
+
}
|
|
127
|
+
function defaultThrottleMessage(args) {
|
|
128
|
+
const who = args.source === "provider" ? "upstream provider" : "aex API";
|
|
129
|
+
const label = args.status === 529 ? "overloaded" : "rate limit reached";
|
|
130
|
+
const attempts = `${args.attempts} attempt${args.attempts === 1 ? "" : "s"}`;
|
|
131
|
+
const wait = args.retryAfterMs !== undefined
|
|
132
|
+
? `; retry after ~${Math.ceil(args.retryAfterMs / 1000)}s`
|
|
133
|
+
: "";
|
|
134
|
+
return `${who} ${label} (HTTP ${args.status}) after ${attempts}${wait}`;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Best-effort parse of an unknown value into a {@link ProviderFault}. Tolerant
|
|
138
|
+
* of two shapes so the SDK consumes the runtime fault the moment it starts
|
|
139
|
+
* emitting one, without a contracts change:
|
|
140
|
+
*
|
|
141
|
+
* 1. The canonical `{ provider?, kind, status?, retryAfterMs?, message? }`
|
|
142
|
+
* (optionally nested under a `providerFault` key), OR
|
|
143
|
+
* 2. A raw upstream error `{ type: "rate_limit_error" | "overloaded_error"
|
|
144
|
+
* | ..., message?, retry_after? | retryAfter? }` — `type` maps to `kind`
|
|
145
|
+
* and `retry_after` (seconds) maps to `retryAfterMs`.
|
|
146
|
+
*
|
|
147
|
+
* Returns `undefined` when the value carries no recognizable fault.
|
|
148
|
+
*/
|
|
149
|
+
export function parseProviderFault(value) {
|
|
150
|
+
if (value === null || typeof value !== "object")
|
|
151
|
+
return undefined;
|
|
152
|
+
const record = value;
|
|
153
|
+
const nested = record.providerFault ?? record.provider_fault;
|
|
154
|
+
if (nested !== undefined && nested !== value) {
|
|
155
|
+
const fromNested = parseProviderFault(nested);
|
|
156
|
+
if (fromNested)
|
|
157
|
+
return fromNested;
|
|
158
|
+
}
|
|
159
|
+
const kind = coerceFaultKind(record.kind ?? record.type ?? record.code);
|
|
160
|
+
if (kind === undefined)
|
|
161
|
+
return undefined;
|
|
162
|
+
const provider = typeof record.provider === "string" ? record.provider : undefined;
|
|
163
|
+
const status = coerceStatus(record.status ?? record.statusCode ?? record.httpStatus);
|
|
164
|
+
const retryAfterMs = coerceRetryAfterMs(record.retryAfterMs ?? record.retry_after_ms ?? record.retryAfter ?? record.retry_after);
|
|
165
|
+
const message = typeof record.message === "string" ? record.message : undefined;
|
|
166
|
+
return {
|
|
167
|
+
kind,
|
|
168
|
+
...(provider !== undefined ? { provider } : {}),
|
|
169
|
+
...(status !== undefined ? { status } : {}),
|
|
170
|
+
...(retryAfterMs !== undefined ? { retryAfterMs } : {}),
|
|
171
|
+
...(message !== undefined ? { message } : {})
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function coerceFaultKind(raw) {
|
|
175
|
+
if (typeof raw !== "string")
|
|
176
|
+
return undefined;
|
|
177
|
+
const value = raw.toLowerCase();
|
|
178
|
+
if (value.includes("rate_limit") || value.includes("rate limit") || value === "429")
|
|
179
|
+
return "rate_limit";
|
|
180
|
+
if (value.includes("overload") || value === "529")
|
|
181
|
+
return "overloaded";
|
|
182
|
+
if (value.includes("quota") || value.includes("insufficient"))
|
|
183
|
+
return "quota_exceeded";
|
|
184
|
+
if (value.includes("provider_error") || value.includes("provider error") || value.includes("api_error")) {
|
|
185
|
+
return "provider_error";
|
|
186
|
+
}
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
function coerceStatus(raw) {
|
|
190
|
+
if (typeof raw === "number" && Number.isFinite(raw))
|
|
191
|
+
return raw;
|
|
192
|
+
if (typeof raw === "string" && /^\d+$/.test(raw.trim()))
|
|
193
|
+
return Number(raw.trim());
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
/** Accept a ms number, a `<digits>` string, or seconds under a `retry_after` alias. */
|
|
197
|
+
function coerceRetryAfterMs(raw) {
|
|
198
|
+
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
199
|
+
// Heuristic: small integers are seconds (the upstream convention), large
|
|
200
|
+
// ones are already milliseconds.
|
|
201
|
+
return raw > 0 && raw < 1000 ? raw * 1000 : raw;
|
|
202
|
+
}
|
|
203
|
+
if (typeof raw === "string" && /^\d+$/.test(raw.trim())) {
|
|
204
|
+
const n = Number(raw.trim());
|
|
205
|
+
return n > 0 && n < 1000 ? n * 1000 : n;
|
|
206
|
+
}
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
const defaultSleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
210
|
+
if (signal?.aborted) {
|
|
211
|
+
reject(signal.reason instanceof Error ? signal.reason : new DOMException("Aborted", "AbortError"));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const timer = setTimeout(() => {
|
|
215
|
+
signal?.removeEventListener("abort", onAbort);
|
|
216
|
+
resolve();
|
|
217
|
+
}, ms);
|
|
218
|
+
const onAbort = () => {
|
|
219
|
+
clearTimeout(timer);
|
|
220
|
+
reject(signal?.reason instanceof Error ? signal.reason : new DOMException("Aborted", "AbortError"));
|
|
221
|
+
};
|
|
222
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
223
|
+
});
|
|
224
|
+
function isAbortError(err) {
|
|
225
|
+
return err instanceof Error && err.name === "AbortError";
|
|
226
|
+
}
|
|
227
|
+
async function drain(response) {
|
|
228
|
+
try {
|
|
229
|
+
if (response.body && typeof response.body.cancel === "function") {
|
|
230
|
+
await response.body.cancel();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
await response.text();
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
// Draining is best-effort; a discarded retryable response never surfaces.
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
async function readBodyForError(response) {
|
|
240
|
+
try {
|
|
241
|
+
const text = await response.text();
|
|
242
|
+
if (text.length === 0)
|
|
243
|
+
return {};
|
|
244
|
+
try {
|
|
245
|
+
return JSON.parse(text);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
return { raw: text };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return {};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Wrap a {@link FetchLike} with the bounded-retry loop. `retry === false`
|
|
257
|
+
* disables the layer entirely (the input fetch is returned unchanged). Otherwise
|
|
258
|
+
* the returned fetch retries transient failures per {@link RetryOptions} and, on
|
|
259
|
+
* an exhausted rate-limit/overloaded status, throws {@link AexRateLimitError}.
|
|
260
|
+
*/
|
|
261
|
+
export function withRetry(fetchImpl, retry, deps = {}) {
|
|
262
|
+
if (retry === false)
|
|
263
|
+
return fetchImpl;
|
|
264
|
+
const config = resolveRetryConfig(retry);
|
|
265
|
+
const sleep = deps.sleep ?? defaultSleep;
|
|
266
|
+
const random = deps.random ?? Math.random;
|
|
267
|
+
const now = deps.now ?? Date.now;
|
|
268
|
+
return async (input, init) => {
|
|
269
|
+
const startedAt = now();
|
|
270
|
+
const signal = init?.signal ?? undefined;
|
|
271
|
+
let attempt = 0;
|
|
272
|
+
for (;;) {
|
|
273
|
+
attempt += 1;
|
|
274
|
+
let response;
|
|
275
|
+
try {
|
|
276
|
+
response = await fetchImpl(input, init);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
// A caller-initiated abort is terminal, never transient.
|
|
280
|
+
if (isAbortError(err))
|
|
281
|
+
throw err;
|
|
282
|
+
if (attempt >= config.maxAttempts)
|
|
283
|
+
throw err;
|
|
284
|
+
const delay = computeBackoffDelayMs(config, attempt, random);
|
|
285
|
+
if (now() - startedAt + delay > config.maxElapsedMs)
|
|
286
|
+
throw err;
|
|
287
|
+
await sleep(delay, signal ?? undefined);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
// Success or a definitive (non-retryable) response — hand straight back so
|
|
291
|
+
// the transport reads/throws exactly as it does without the retry layer.
|
|
292
|
+
if (!isRetryableStatus(response.status)) {
|
|
293
|
+
return response;
|
|
294
|
+
}
|
|
295
|
+
const retryAfterMs = parseRetryAfterMs(response.headers.get("retry-after"), now());
|
|
296
|
+
const willRetry = attempt < config.maxAttempts &&
|
|
297
|
+
now() - startedAt + nextDelayMs(config, attempt, random, retryAfterMs) <= config.maxElapsedMs;
|
|
298
|
+
if (willRetry) {
|
|
299
|
+
await drain(response);
|
|
300
|
+
await sleep(nextDelayMs(config, attempt, random, retryAfterMs), signal ?? undefined);
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
// Retries exhausted (or budget spent). A rate-limit/overloaded status
|
|
304
|
+
// becomes a structured throttle error; any other transient status falls
|
|
305
|
+
// through to the transport's normal AexApiError.
|
|
306
|
+
if (isRateLimitStatus(response.status)) {
|
|
307
|
+
const body = await readBodyForError(response);
|
|
308
|
+
throw new AexRateLimitError({
|
|
309
|
+
status: response.status,
|
|
310
|
+
attempts: attempt,
|
|
311
|
+
source: "api",
|
|
312
|
+
...(retryAfterMs !== undefined ? { retryAfterMs } : {}),
|
|
313
|
+
body
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
return response;
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
|
package/dist/secret.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type SecretEnvSubmissionEntry = {
|
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
14
|
* Minimal client surface `secret.upload` needs to promote an ephemeral secret
|
|
15
|
-
* into the workspace store. `
|
|
15
|
+
* into the workspace store. `Aex` satisfies it via its `secrets`
|
|
16
16
|
* client; defined structurally here so `secret.ts` does not import `client.ts`
|
|
17
17
|
* (which would be circular — `client.ts` imports `Secret`). Mirrors
|
|
18
18
|
* {@link SkillUploader}.
|
|
@@ -88,7 +88,7 @@ export declare class Secret {
|
|
|
88
88
|
/**
|
|
89
89
|
* Split `secretEnv: Record<envName, Secret>` into the value-free declarations
|
|
90
90
|
* (`submission.secretEnv`) and the per-run vaulted values
|
|
91
|
-
* (`secrets.envSecrets`).
|
|
91
|
+
* (`secrets.envSecrets`). Secret declarations ride
|
|
92
92
|
* the hashed submission, ephemeral values ride the secrets channel
|
|
93
93
|
* (hash-excluded). Refs contribute only a declaration.
|
|
94
94
|
*
|
package/dist/secret.js
CHANGED
|
@@ -116,7 +116,7 @@ export class Secret {
|
|
|
116
116
|
/**
|
|
117
117
|
* Split `secretEnv: Record<envName, Secret>` into the value-free declarations
|
|
118
118
|
* (`submission.secretEnv`) and the per-run vaulted values
|
|
119
|
-
* (`secrets.envSecrets`).
|
|
119
|
+
* (`secrets.envSecrets`). Secret declarations ride
|
|
120
120
|
* the hashed submission, ephemeral values ride the secrets channel
|
|
121
121
|
* (hash-excluded). Refs contribute only a declaration.
|
|
122
122
|
*
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -14,11 +14,11 @@ runtime before the first agent turn.
|
|
|
14
14
|
| Agent instructions | `AgentsMd.fromPath`, `AgentsMd.fromContent` |
|
|
15
15
|
| Reference files and folders | `File.fromPath`, `File.fromBytes` |
|
|
16
16
|
| Remote tools | `McpServer.remote`, `McpServer.fromId` |
|
|
17
|
-
| Credentialed HTTP APIs | `ProxyEndpoint.none`, `bearer`, `basic`, `header`, `query` |
|
|
18
17
|
| Non-secret runtime settings | `environment.variables`, `environment.packages`, `environment.networking` |
|
|
18
|
+
| Runtime secrets for your code | `Secret.value`, `Secret.ref`, `environment.secrets` |
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
|
-
import { AgentsMd, File, McpServer, Models,
|
|
21
|
+
import { AgentsMd, File, McpServer, Models, Secret, Tools } from "@aexhq/sdk";
|
|
22
22
|
|
|
23
23
|
await aex.run({
|
|
24
24
|
model: Models.CLAUDE_HAIKU_4_5,
|
|
@@ -27,20 +27,14 @@ await aex.run({
|
|
|
27
27
|
files: [await File.fromPath("./input")],
|
|
28
28
|
tools: [await Tools.fromSkillDir("./skills/report-writer", { name: "report-writer" })],
|
|
29
29
|
mcpServers: [McpServer.remote({ name: "github", url: "https://example.com/mcp" })],
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
token: process.env.INTERNAL_API_TOKEN!,
|
|
35
|
-
allowMethods: ["GET"],
|
|
36
|
-
allowPathPrefixes: ["/v1/"]
|
|
37
|
-
})
|
|
38
|
-
],
|
|
30
|
+
environment: {
|
|
31
|
+
secrets: { INTERNAL_API_TOKEN: Secret.value(process.env.INTERNAL_API_TOKEN!) },
|
|
32
|
+
networking: { mode: "limited", allowedHosts: ["api.example.com"] }
|
|
33
|
+
},
|
|
39
34
|
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
40
35
|
});
|
|
41
36
|
```
|
|
42
37
|
|
|
43
38
|
Secrets stay out of reusable configs. Provider keys go in the top-level `apiKeys`
|
|
44
|
-
map;
|
|
45
|
-
|
|
46
|
-
server-side, so they never live in a shareable config object.
|
|
39
|
+
map; reusable or per-run values for your own code go in `environment.secrets`.
|
|
40
|
+
Your code then makes normal HTTP calls with the standard client for that service.
|
package/docs/credentials.md
CHANGED
|
@@ -4,142 +4,100 @@ title: Credentials
|
|
|
4
4
|
|
|
5
5
|
# Credentials
|
|
6
6
|
|
|
7
|
-
aex
|
|
8
|
-
credentials. Reusable env secrets are documented separately in
|
|
9
|
-
[Secrets](secrets.md).
|
|
7
|
+
aex uses explicit, per-session credentials:
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
- `AEX_API_TOKEN` authenticates the SDK or CLI to aex.
|
|
10
|
+
- `apiKeys` carries BYOK provider keys for the model provider.
|
|
11
|
+
- `McpServer.remote(..., { headers })` carries MCP auth when a remote MCP server needs it.
|
|
12
|
+
- `environment.secrets` carries runtime secrets for your own code.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
key for it. Keys are supplied per-provider so a session can also hold keys for the
|
|
15
|
-
**other** providers its subagents may use:
|
|
14
|
+
Secrets never belong in reusable run config, files, prompts, or examples.
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
## Provider keys
|
|
17
|
+
|
|
18
|
+
A session selects one upstream provider and must carry a BYOK key for it. Include
|
|
19
|
+
additional provider keys only when subagents may use those providers.
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
const result = await aex.run({
|
|
23
|
+
model: Models.CLAUDE_HAIKU_4_5,
|
|
24
|
+
message: "Write a short report and save it as a file.",
|
|
25
|
+
apiKeys: {
|
|
26
|
+
anthropic: process.env.ANTHROPIC_API_KEY!
|
|
27
|
+
}
|
|
28
|
+
});
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
container. If the parent holds no key for the child's provider, the child is
|
|
32
|
-
rejected with `parent_missing_provider_key`.
|
|
33
|
-
|
|
34
|
-
MCP credential types:
|
|
35
|
-
|
|
36
|
-
- `static_bearer`;
|
|
37
|
-
- `oauth_access_token`.
|
|
31
|
+
Provider keys are used by the managed runtime for model calls. They are not saved
|
|
32
|
+
as client defaults.
|
|
38
33
|
|
|
39
|
-
|
|
34
|
+
## Runtime secrets
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
For managed-runtime runs, aex injects the matching BYOK provider key at the hosted provider-proxy. Provider-side sessions and data remain subject to the selected provider account's retention and deletion policies.
|
|
46
|
-
|
|
47
|
-
## Proxy endpoints (per-run custom HTTP credentials)
|
|
48
|
-
|
|
49
|
-
Some skills need to call non-MCP HTTP services (e.g. Stripe, internal APIs). Embedding the credential in the skill content puts the raw secret on disk in the agent container and in the model's context — both prompt-injection-readable.
|
|
50
|
-
|
|
51
|
-
The platform's managed HTTP proxy is the agent-first alternative. Declare each endpoint with a `ProxyEndpoint.*` constructor: the instance carries the non-secret **policy** (hashed for idempotency) and its **auth token** together at the call site. The SDK splits the token into the vaulted secrets channel server-side (not hashed, so key rotation does not collapse onto a stale run), and the raw credential value never enters the container.
|
|
36
|
+
Use `environment.secrets` for credentials your code needs at runtime. The value
|
|
37
|
+
can be ephemeral with `Secret.value(...)` or a workspace secret reference with
|
|
38
|
+
`Secret.ref(...)`.
|
|
52
39
|
|
|
53
40
|
```ts
|
|
54
|
-
import { Aex, Models,
|
|
41
|
+
import { Aex, Models, Secret } from "@aexhq/sdk";
|
|
55
42
|
|
|
56
|
-
const aex = new Aex({
|
|
57
|
-
apiToken: "ant_..."
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const stripe = ProxyEndpoint.bearer({
|
|
61
|
-
name: "stripe",
|
|
62
|
-
baseUrl: "https://api.stripe.com",
|
|
63
|
-
token: process.env.STRIPE_API_KEY!,
|
|
64
|
-
allowMethods: ["GET", "POST"],
|
|
65
|
-
allowPathPrefixes: ["/v1/charges", "/v1/refunds"],
|
|
66
|
-
maxRequestBytes: 65_536,
|
|
67
|
-
maxResponseBytes: 65_536,
|
|
68
|
-
timeoutMs: 10_000,
|
|
69
|
-
responseMode: "headers_only",
|
|
70
|
-
retry: {
|
|
71
|
-
maxAttempts: 3,
|
|
72
|
-
initialDelayMs: 250,
|
|
73
|
-
maxDelayMs: 5000,
|
|
74
|
-
jitter: "full",
|
|
75
|
-
retryOnStatuses: [408, 425, 429, 500, 502, 503, 504],
|
|
76
|
-
retryOnMethods: ["GET", "HEAD"],
|
|
77
|
-
respectRetryAfter: true
|
|
78
|
-
}
|
|
79
|
-
});
|
|
43
|
+
const aex = new Aex({ apiToken: process.env.AEX_API_TOKEN! });
|
|
80
44
|
|
|
81
45
|
await aex.run({
|
|
82
46
|
model: Models.CLAUDE_HAIKU_4_5,
|
|
83
|
-
message: "
|
|
84
|
-
|
|
47
|
+
message: "Call https://api.example.com/v1/status with INTERNAL_API_TOKEN and summarize it.",
|
|
48
|
+
environment: {
|
|
49
|
+
secrets: {
|
|
50
|
+
INTERNAL_API_TOKEN: Secret.value(process.env.INTERNAL_API_TOKEN!)
|
|
51
|
+
},
|
|
52
|
+
networking: {
|
|
53
|
+
mode: "limited",
|
|
54
|
+
allowedHosts: ["api.example.com"]
|
|
55
|
+
}
|
|
56
|
+
},
|
|
85
57
|
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
86
58
|
});
|
|
87
59
|
```
|
|
88
60
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
Inside the run container, every session has the platform CLI mounted at `/mnt/session/uploads/aex/aex` (a Bun-compatible ESM bundle) and a manifest at `/mnt/session/uploads/aex/index.json` describing the declared endpoints. The skill invokes the CLI through `bun` (the mount has no execute permission so direct invocation fails with `bad interpreter: Permission denied`):
|
|
61
|
+
Inside the run, use normal HTTP code for the service:
|
|
92
62
|
|
|
93
63
|
```bash
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
--response-mode headers_only
|
|
64
|
+
curl -sS \
|
|
65
|
+
-H "Authorization: Bearer $INTERNAL_API_TOKEN" \
|
|
66
|
+
https://api.example.com/v1/status
|
|
98
67
|
```
|
|
99
68
|
|
|
100
|
-
|
|
69
|
+
## Workspace secrets
|
|
101
70
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
#### Keyless upstreams (`authShape: { type: "none" }`)
|
|
105
|
-
|
|
106
|
-
For public APIs that take no credential (Wikimedia Commons, Internet Archive, Library of Congress, NASA Images, NARA, GDELT, etc.), declare the endpoint with `ProxyEndpoint.none(...)` — it produces only a declaration, no auth token:
|
|
71
|
+
Store reusable values once, then reference them by name:
|
|
107
72
|
|
|
108
73
|
```ts
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
name: "wikimedia",
|
|
113
|
-
baseUrl: "https://commons.wikimedia.org",
|
|
114
|
-
allowMethods: ["GET"],
|
|
115
|
-
allowPathPrefixes: ["/wiki/", "/w/api.php"]
|
|
74
|
+
await aex.secrets.set({
|
|
75
|
+
name: "internal-api-token",
|
|
76
|
+
value: process.env.INTERNAL_API_TOKEN!
|
|
116
77
|
});
|
|
117
78
|
|
|
118
79
|
await aex.run({
|
|
119
80
|
model: Models.CLAUDE_HAIKU_4_5,
|
|
120
|
-
message: "
|
|
121
|
-
|
|
81
|
+
message: "Use INTERNAL_API_TOKEN for the status request.",
|
|
82
|
+
environment: {
|
|
83
|
+
secrets: {
|
|
84
|
+
INTERNAL_API_TOKEN: Secret.ref("internal-api-token")
|
|
85
|
+
}
|
|
86
|
+
},
|
|
122
87
|
apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
|
|
123
88
|
});
|
|
124
89
|
```
|
|
125
90
|
|
|
126
|
-
|
|
91
|
+
Secret reads return metadata only; they never return the stored value.
|
|
127
92
|
|
|
128
|
-
|
|
93
|
+
## Networking
|
|
129
94
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Networking
|
|
133
|
-
the platform host must appear in `allowed_hosts`. aex injects it
|
|
134
|
-
automatically; for advance validation use:
|
|
135
|
-
|
|
136
|
-
```ts
|
|
137
|
-
const allowedHosts = buildPlatformAllowedHosts({
|
|
138
|
-
baseUrl: "https://api.aex.dev",
|
|
139
|
-
extraHosts: ["api.stripe.com"]
|
|
140
|
-
});
|
|
141
|
-
```
|
|
95
|
+
Networking is open by default. Use `environment.networking.mode: "limited"` with
|
|
96
|
+
`allowedHosts` when you want a run to reach only named public hosts. See
|
|
97
|
+
[Networking](networking.md).
|
|
142
98
|
|
|
143
|
-
|
|
99
|
+
## Explicit call-site rule
|
|
144
100
|
|
|
145
|
-
There is no `defaultSecrets` and no client-held secret state.
|
|
101
|
+
There is no `defaultSecrets` and no client-held secret state. Each
|
|
102
|
+
`openSession(...)` or `run(...)` call should show the provider keys, MCP auth, and
|
|
103
|
+
runtime secrets needed for that call.
|
package/docs/defaults.md
CHANGED
|
@@ -39,14 +39,6 @@ For the hard ceilings and who can raise them, see
|
|
|
39
39
|
| MCP connect timeout (register + initialize + discover) | 30 seconds | Per-port via `connectTimeoutMs`. | `RUN_DEFAULT_MCP_CONNECT_TIMEOUT_MS` |
|
|
40
40
|
| MCP `tools/call` timeout | 30 minutes | Per-port via `callTimeoutMs`. | `RUN_DEFAULT_MCP_CALL_TIMEOUT_MS` |
|
|
41
41
|
|
|
42
|
-
## Proxy endpoints
|
|
43
|
-
|
|
44
|
-
| Option | Default | How to override | Source |
|
|
45
|
-
| --- | --- | --- | --- |
|
|
46
|
-
| `maxRequestBytes` | 10 MiB | Per-endpoint via the endpoint's `maxRequestBytes`. | `REQUEST_PROXY_DEFAULT_MAX_REQUEST_BYTES` |
|
|
47
|
-
| `maxResponseBytes` | `0` (unlimited — the response is streamed unbuffered) | Per-endpoint via the endpoint's `maxResponseBytes`. | `REQUEST_PROXY_DEFAULT_MAX_RESPONSE_BYTES` |
|
|
48
|
-
| `timeoutMs` (upstream) | 5 minutes | Per-endpoint via the endpoint's `timeoutMs`. | `REQUEST_PROXY_DEFAULT_TIMEOUT_MS` |
|
|
49
|
-
|
|
50
42
|
## Links (signed URLs and tickets)
|
|
51
43
|
|
|
52
44
|
| Option | Default | How to override | Source |
|