@aexhq/sdk 0.40.14 → 0.40.16
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/dist/_contracts/asset-upload-helper.d.ts +2 -2
- package/dist/_contracts/asset-upload-helper.js +2 -2
- package/dist/_contracts/http.d.ts +3 -2
- package/dist/_contracts/http.js +15 -4
- package/dist/cli.mjs +17 -6
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/concepts/subagents.md +10 -7
- package/docs/defaults.md +5 -2
- package/docs/limits-and-quotas.md +8 -3
- package/package.json +1 -1
|
@@ -9,10 +9,10 @@ export interface AssetUploadResponse {
|
|
|
9
9
|
}
|
|
10
10
|
/** Minimal fetch shape for direct-to-storage PUT requests. */
|
|
11
11
|
export type AssetFetch = (input: string, init?: RequestInit) => Promise<AssetUploadResponse>;
|
|
12
|
-
export declare const DIRECT_UPLOAD_MAX_ATTEMPTS =
|
|
12
|
+
export declare const DIRECT_UPLOAD_MAX_ATTEMPTS = 5;
|
|
13
13
|
export declare const DIRECT_UPLOAD_INITIAL_DELAY_MS = 500;
|
|
14
14
|
export declare const DIRECT_UPLOAD_MAX_DELAY_MS = 5000;
|
|
15
|
-
export declare const DIRECT_UPLOAD_MAX_ELAPSED_MS =
|
|
15
|
+
export declare const DIRECT_UPLOAD_MAX_ELAPSED_MS = 60000;
|
|
16
16
|
export type AssetUploadSleep = (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
17
17
|
export interface AssetUploadRetryOptions {
|
|
18
18
|
readonly maxAttempts?: number;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { extractErrorCode, redactUrl } from "./sdk-errors.js";
|
|
2
2
|
import { abortableSleep, computeRetryDelayMs, parseRetryAfterMs } from "./retry-core.js";
|
|
3
|
-
export const DIRECT_UPLOAD_MAX_ATTEMPTS =
|
|
3
|
+
export const DIRECT_UPLOAD_MAX_ATTEMPTS = 5;
|
|
4
4
|
export const DIRECT_UPLOAD_INITIAL_DELAY_MS = 500;
|
|
5
5
|
export const DIRECT_UPLOAD_MAX_DELAY_MS = 5_000;
|
|
6
|
-
export const DIRECT_UPLOAD_MAX_ELAPSED_MS =
|
|
6
|
+
export const DIRECT_UPLOAD_MAX_ELAPSED_MS = 60_000;
|
|
7
7
|
export async function putDirectUploadWithRetry(fetchImpl, uploadUrl, init, options = {}) {
|
|
8
8
|
const config = resolveAssetUploadRetryConfig(options);
|
|
9
9
|
const sleep = options.sleep ?? abortableSleep;
|
|
@@ -19,9 +19,10 @@ export interface HttpClientOptions {
|
|
|
19
19
|
/** When set, every request emits a redacted one-line trace here. */
|
|
20
20
|
readonly debug?: DebugSink;
|
|
21
21
|
/**
|
|
22
|
-
* Retry transient transport failures for idempotent
|
|
22
|
+
* Retry transient transport failures for idempotent requests.
|
|
23
23
|
* Disabled by default; host CLIs enable this so a single dropped API
|
|
24
|
-
* connection does not fail read-only commands
|
|
24
|
+
* connection does not fail read-only commands or billable writes carrying
|
|
25
|
+
* an `Idempotency-Key`.
|
|
25
26
|
*/
|
|
26
27
|
readonly retryTransientGets?: boolean | TransientGetRetryOptions;
|
|
27
28
|
}
|
package/dist/_contracts/http.js
CHANGED
|
@@ -55,7 +55,7 @@ export class HttpClient {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
const method = methodOf(init.method);
|
|
58
|
-
const retry =
|
|
58
|
+
const retry = retryForRequest(method, headers, this.#retryTransientGets);
|
|
59
59
|
const requestStartedMs = Date.now();
|
|
60
60
|
for (let attempt = 1; attempt <= retry.maxAttempts; attempt += 1) {
|
|
61
61
|
const startedMs = Date.now();
|
|
@@ -93,7 +93,7 @@ export class HttpClient {
|
|
|
93
93
|
...normalizeHeaders(init.headers)
|
|
94
94
|
};
|
|
95
95
|
const method = methodOf(init.method);
|
|
96
|
-
const retry =
|
|
96
|
+
const retry = retryForRequest(method, headers, this.#retryTransientGets);
|
|
97
97
|
const requestStartedMs = Date.now();
|
|
98
98
|
for (let attempt = 1; attempt <= retry.maxAttempts; attempt += 1) {
|
|
99
99
|
const startedMs = Date.now();
|
|
@@ -152,12 +152,23 @@ function resolveTransientGetRetry(retry) {
|
|
|
152
152
|
function methodOf(method) {
|
|
153
153
|
return (method ?? "GET").toUpperCase();
|
|
154
154
|
}
|
|
155
|
-
function
|
|
156
|
-
if (!retry || (method
|
|
155
|
+
function retryForRequest(method, headers, retry) {
|
|
156
|
+
if (!retry || (!isMethodIdempotent(method) && !hasIdempotencyKey(headers))) {
|
|
157
157
|
return { ...DEFAULT_TRANSIENT_GET_RETRY, maxAttempts: 1 };
|
|
158
158
|
}
|
|
159
159
|
return retry;
|
|
160
160
|
}
|
|
161
|
+
function isMethodIdempotent(method) {
|
|
162
|
+
return method === "GET" || method === "HEAD";
|
|
163
|
+
}
|
|
164
|
+
function hasIdempotencyKey(headers) {
|
|
165
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
166
|
+
if (name.toLowerCase() === "idempotency-key" && value.trim().length > 0) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
161
172
|
function shouldRetryTransientRead(err, retry, attempt) {
|
|
162
173
|
return attempt < retry.maxAttempts && transientReadErrorCode(err) !== undefined;
|
|
163
174
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -2190,7 +2190,7 @@ var HttpClient = class {
|
|
|
2190
2190
|
}
|
|
2191
2191
|
}
|
|
2192
2192
|
const method = methodOf(init.method);
|
|
2193
|
-
const retry =
|
|
2193
|
+
const retry = retryForRequest(method, headers, this.#retryTransientGets);
|
|
2194
2194
|
const requestStartedMs = Date.now();
|
|
2195
2195
|
for (let attempt = 1; attempt <= retry.maxAttempts; attempt += 1) {
|
|
2196
2196
|
const startedMs = Date.now();
|
|
@@ -2227,7 +2227,7 @@ var HttpClient = class {
|
|
|
2227
2227
|
...normalizeHeaders(init.headers)
|
|
2228
2228
|
};
|
|
2229
2229
|
const method = methodOf(init.method);
|
|
2230
|
-
const retry =
|
|
2230
|
+
const retry = retryForRequest(method, headers, this.#retryTransientGets);
|
|
2231
2231
|
const requestStartedMs = Date.now();
|
|
2232
2232
|
for (let attempt = 1; attempt <= retry.maxAttempts; attempt += 1) {
|
|
2233
2233
|
const startedMs = Date.now();
|
|
@@ -2285,12 +2285,23 @@ function resolveTransientGetRetry(retry) {
|
|
|
2285
2285
|
function methodOf(method) {
|
|
2286
2286
|
return (method ?? "GET").toUpperCase();
|
|
2287
2287
|
}
|
|
2288
|
-
function
|
|
2289
|
-
if (!retry || method
|
|
2288
|
+
function retryForRequest(method, headers, retry) {
|
|
2289
|
+
if (!retry || !isMethodIdempotent(method) && !hasIdempotencyKey(headers)) {
|
|
2290
2290
|
return { ...DEFAULT_TRANSIENT_GET_RETRY, maxAttempts: 1 };
|
|
2291
2291
|
}
|
|
2292
2292
|
return retry;
|
|
2293
2293
|
}
|
|
2294
|
+
function isMethodIdempotent(method) {
|
|
2295
|
+
return method === "GET" || method === "HEAD";
|
|
2296
|
+
}
|
|
2297
|
+
function hasIdempotencyKey(headers) {
|
|
2298
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
2299
|
+
if (name.toLowerCase() === "idempotency-key" && value.trim().length > 0) {
|
|
2300
|
+
return true;
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
return false;
|
|
2304
|
+
}
|
|
2294
2305
|
function shouldRetryTransientRead(err2, retry, attempt) {
|
|
2295
2306
|
return attempt < retry.maxAttempts && transientReadErrorCode(err2) !== void 0;
|
|
2296
2307
|
}
|
|
@@ -4786,10 +4797,10 @@ function makeAbortError() {
|
|
|
4786
4797
|
}
|
|
4787
4798
|
|
|
4788
4799
|
// ../contracts/dist/asset-upload-helper.js
|
|
4789
|
-
var DIRECT_UPLOAD_MAX_ATTEMPTS =
|
|
4800
|
+
var DIRECT_UPLOAD_MAX_ATTEMPTS = 5;
|
|
4790
4801
|
var DIRECT_UPLOAD_INITIAL_DELAY_MS = 500;
|
|
4791
4802
|
var DIRECT_UPLOAD_MAX_DELAY_MS = 5e3;
|
|
4792
|
-
var DIRECT_UPLOAD_MAX_ELAPSED_MS =
|
|
4803
|
+
var DIRECT_UPLOAD_MAX_ELAPSED_MS = 6e4;
|
|
4793
4804
|
async function putDirectUploadWithRetry(fetchImpl, uploadUrl, init, options = {}) {
|
|
4794
4805
|
const config = resolveAssetUploadRetryConfig(options);
|
|
4795
4806
|
const sleep5 = options.sleep ?? abortableSleep;
|
package/dist/cli.mjs.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
6a03ce618806a3cbd18663d4a1187106b1c6fecd4256e5f78d043b7480967505 cli.mjs
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -29,17 +29,20 @@ error). See [Credentials](../credentials.md).
|
|
|
29
29
|
|
|
30
30
|
## Depth and breadth limits
|
|
31
31
|
|
|
32
|
-
Delegation is bounded by
|
|
32
|
+
Delegation is bounded by server-enforced lineage budgets. The runtime is
|
|
33
|
+
designed for broad fan-out, across hundreds and even thousands of concurrent
|
|
34
|
+
child agents per root, and for high levels of recursive subagent depth. Exact
|
|
35
|
+
operational limits are platform-managed and may change as the runtime scales.
|
|
33
36
|
|
|
34
|
-
| Limit |
|
|
37
|
+
| Limit | Runtime posture | Behavior at the limit |
|
|
35
38
|
| --- | --- | --- |
|
|
36
|
-
| Max
|
|
37
|
-
| Concurrent children per lineage root |
|
|
39
|
+
| Max recursive subagent depth | Supports high levels of nested delegation, bounded server-side. | A further spawn is rejected with a `depth_exceeded` tool error (the parent keeps running). |
|
|
40
|
+
| Concurrent children per lineage root | Designed to scale across hundreds, even thousands, of live descendants, bounded server-side. | Further spawns are refused until a child settles. |
|
|
38
41
|
|
|
39
42
|
The whole descendant subtree of one root shares a single depth and breadth
|
|
40
43
|
budget, enforced server-side at every level — a grandchild spawn counts against
|
|
41
|
-
the same root budget as a direct child.
|
|
42
|
-
|
|
44
|
+
the same root budget as a direct child. These budgets are not public per-session
|
|
45
|
+
dials today.
|
|
43
46
|
|
|
44
47
|
## Where children run: `in-process` vs `container`
|
|
45
48
|
|
|
@@ -84,5 +87,5 @@ Every child — in-process or container — is a first-class run record:
|
|
|
84
87
|
- Turn delegation off for a run by cherry-picking builtins without `subagent`
|
|
85
88
|
(see [Agent tools](agent-tools.md)) or setting `includeBuiltinTools: false`.
|
|
86
89
|
- A per-session spend cap (`overrides.maxSpendUsd`) bounds the parent's spend.
|
|
87
|
-
- The depth/breadth
|
|
90
|
+
- The depth/breadth budgets above are platform-managed and are not settable
|
|
88
91
|
per-session today.
|
package/docs/defaults.md
CHANGED
|
@@ -48,10 +48,13 @@ For the hard ceilings and who can raise them, see
|
|
|
48
48
|
|
|
49
49
|
## Subagents
|
|
50
50
|
|
|
51
|
+
Subagent breadth and depth are platform-managed budgets rather than fixed public
|
|
52
|
+
numeric entitlements; exact operational values may change as capacity evolves.
|
|
53
|
+
|
|
51
54
|
| Option | Default | How to override | Source |
|
|
52
55
|
| --- | --- | --- | --- |
|
|
53
|
-
| Concurrent child runs per lineage root |
|
|
54
|
-
| Max subagent depth |
|
|
56
|
+
| Concurrent child runs per lineage root | Platform-managed; designed to scale across hundreds, even thousands, of live child agents. | No public per-run override; contact support for unusually large workloads. | `RUN_DEFAULT_MAX_CONCURRENT_CHILD_RUNS` |
|
|
57
|
+
| Max subagent depth | Platform-managed; supports high recursive subagent depth. | No public per-run override. | `RUN_MAX_PUBLIC_SUBAGENT_DEPTH` |
|
|
55
58
|
|
|
56
59
|
## Workspace
|
|
57
60
|
|
|
@@ -58,10 +58,15 @@ silently lost.
|
|
|
58
58
|
|
|
59
59
|
### Subagents (per run lineage)
|
|
60
60
|
|
|
61
|
+
Subagent lineage bounds are enforced server-side but are intentionally not
|
|
62
|
+
advertised as fixed public ceilings because capacity can change. The runtime
|
|
63
|
+
posture is high fan-out and high recursive depth; exact admission is governed
|
|
64
|
+
by the platform at spawn time.
|
|
65
|
+
|
|
61
66
|
| Limit | Value | Source | Raisable? | Constant |
|
|
62
67
|
| --- | --- | --- | --- | --- |
|
|
63
|
-
| Max subagent depth (`subagent` tool) |
|
|
64
|
-
| Concurrent child runs per lineage root |
|
|
68
|
+
| Max subagent depth (`subagent` tool) | High recursive subagent depth, bounded server-side. | aex policy | No public per-run override (subagents run in-process) | `RUN_MAX_PUBLIC_SUBAGENT_DEPTH` |
|
|
69
|
+
| Concurrent child runs per lineage root | Designed to scale across hundreds, even thousands, of live child agents, bounded server-side. | aex policy | No public per-run override (subagents run in-process) | `RUN_DEFAULT_MAX_CONCURRENT_CHILD_RUNS` |
|
|
65
70
|
|
|
66
71
|
### Retention (per run)
|
|
67
72
|
|
|
@@ -98,7 +103,7 @@ A few behaviours are worth knowing before you rely on the filesystem or RAM:
|
|
|
98
103
|
| Limit | Value | Source | Raisable? | Constant |
|
|
99
104
|
| --- | --- | --- | --- | --- |
|
|
100
105
|
| Workspace storage cap | 500 GB (decimal; admins uncapped — not a customer entitlement) | Workspace default | Per-plane via env `AEX_WORKSPACE_STORAGE_CAP_BYTES` | `WORKSPACE_DEFAULT_STORAGE_CAP_BYTES` |
|
|
101
|
-
| Max concurrent runs per workspace | Plan-based: **5** live (non-terminal) root runs on the free plan, **50** on Pro, **200** on Team; hard platform ceiling **200**. One more submit past the cap fails with `429 workspace_concurrency_exceeded` (see [Errors](errors.md)). Subagent children are governed separately by the per-lineage
|
|
106
|
+
| Max concurrent runs per workspace | Plan-based: **5** live (non-terminal) root runs on the free plan, **50** on Pro, **200** on Team; hard platform ceiling **200**. One more submit past the cap fails with `429 workspace_concurrency_exceeded` (see [Errors](errors.md)). Subagent children are governed separately by the platform-managed per-lineage budgets above. Read your effective cap from `aex.whoami().limits.maxConcurrentRuns`. | Workspace default (per plan) | Per-plan (upgrade) or per-workspace override (contact support), clamped to the 200 ceiling | `PLANS[planKey].maxConcurrentRuns` / `WORKSPACE_MAX_CONCURRENT_RUNS_CEILING` |
|
|
102
107
|
| Monthly workspace spend cap | **$250** per rolling UTC calendar month by default; `0` = unlimited. A submit past the cap fails with `402 workspace_spend_cap_exceeded` (see [Errors](errors.md)). | Workspace default | Per-workspace override (contact support) | `WORKSPACE_DEFAULT_SPEND_CAP_USD` |
|
|
103
108
|
| Skill bundle max compressed size (`.zip`) | 10 GiB (enforced at upload by the SDK and re-enforced server-side) | aex policy | No (hard ceiling) | `SKILL_BUNDLE_LIMITS.maxCompressedBytes` |
|
|
104
109
|
| Skill bundle max decompressed size (sum of uncompressed file sizes) | 50 MB | aex policy | No (hard ceiling) | `SKILL_BUNDLE_LIMITS.maxDecompressedBytes` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aexhq/sdk",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.16",
|
|
4
4
|
"description": "TypeScript SDK for running autonomous agent sessions across providers (Anthropic, OpenAI, DeepSeek, Gemini, Mistral) behind one interface.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|