@aexhq/sdk 0.40.6 → 0.40.8

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.
Files changed (53) hide show
  1. package/README.md +159 -159
  2. package/dist/_contracts/asset-upload-helper.d.ts +38 -0
  3. package/dist/_contracts/asset-upload-helper.js +111 -0
  4. package/dist/_contracts/internal.d.ts +5 -9
  5. package/dist/_contracts/internal.js +5 -79
  6. package/dist/_contracts/operations.d.ts +9 -2
  7. package/dist/_contracts/operations.js +141 -16
  8. package/dist/_contracts/retry-core.d.ts +27 -0
  9. package/dist/_contracts/retry-core.js +75 -0
  10. package/dist/_contracts/runtime-types.d.ts +6 -0
  11. package/dist/_contracts/stable.d.ts +10 -5
  12. package/dist/_contracts/stable.js +10 -5
  13. package/dist/asset-upload.d.ts +2 -1
  14. package/dist/asset-upload.js +28 -61
  15. package/dist/asset-upload.js.map +1 -1
  16. package/dist/cli.mjs +297 -80
  17. package/dist/cli.mjs.sha256 +1 -1
  18. package/dist/client.d.ts +5 -0
  19. package/dist/client.js +8 -13
  20. package/dist/client.js.map +1 -1
  21. package/dist/retry.js +13 -41
  22. package/dist/retry.js.map +1 -1
  23. package/dist/version.d.ts +1 -1
  24. package/dist/version.js +1 -1
  25. package/docs/authentication.md +125 -125
  26. package/docs/billing.md +118 -118
  27. package/docs/concepts/agent-tools.md +66 -66
  28. package/docs/concepts/composition.md +37 -37
  29. package/docs/concepts/providers-and-runtimes.md +54 -54
  30. package/docs/concepts/runs.md +49 -49
  31. package/docs/concepts/subagents.md +88 -88
  32. package/docs/credentials.md +125 -125
  33. package/docs/defaults.md +64 -64
  34. package/docs/errors.md +196 -196
  35. package/docs/events.md +243 -243
  36. package/docs/limits-and-quotas.md +144 -144
  37. package/docs/limits.md +50 -50
  38. package/docs/mcp.md +44 -44
  39. package/docs/networking.md +163 -163
  40. package/docs/outputs.md +267 -267
  41. package/docs/public-surface.json +77 -77
  42. package/docs/quickstart.md +119 -119
  43. package/docs/release.md +38 -38
  44. package/docs/retries.md +129 -129
  45. package/docs/run-config.md +58 -58
  46. package/docs/run-record.md +55 -55
  47. package/docs/secrets.md +125 -125
  48. package/docs/testing.md +35 -35
  49. package/docs/vision-skills.md +91 -91
  50. package/docs/webhooks.md +127 -127
  51. package/examples/feature-tour.ts +282 -282
  52. package/examples/spike-settle-latency.ts +125 -125
  53. package/package.json +1 -1
package/docs/webhooks.md CHANGED
@@ -1,128 +1,128 @@
1
- ---
2
- title: Webhooks
3
- ---
4
-
5
- # Webhooks
6
-
7
- aex can notify your endpoint when a run finishes. Webhooks are **per-run**: you
8
- pass a callback URL with the submission, and the platform delivers exactly one
9
- `run.finished` event to it when the run reaches its terminal state.
10
-
1
+ ---
2
+ title: Webhooks
3
+ ---
4
+
5
+ # Webhooks
6
+
7
+ aex can notify your endpoint when a run finishes. Webhooks are **per-run**: you
8
+ pass a callback URL with the submission, and the platform delivers exactly one
9
+ `run.finished` event to it when the run reaches its terminal state.
10
+
11
11
  ## Register a callback
12
-
13
- ```ts
14
- import { Aex, Models } from "@aexhq/sdk";
15
-
16
- const aex = new Aex(process.env.AEX_API_KEY!);
17
-
18
- const session = await aex.openSession({
19
- model: Models.CLAUDE_HAIKU_4_5,
20
- webhook: { url: "https://hooks.example.com/aex" },
21
- apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
22
- });
23
- ```
24
-
25
- ```bash
26
- aex run \
27
- --api-key "$AEX_API_KEY" \
28
- --anthropic-api-key "$ANTHROPIC_API_KEY" \
29
- --model claude-haiku-4-5 \
30
- --prompt "Write the report." \
31
- --webhook https://hooks.example.com/aex
32
- ```
33
-
34
- The URL must be `https`. The callback URL is an operational concern, not part
35
- of the submission fingerprint: retrying the same submission with the same
36
- idempotency key but a different callback URL never conflicts.
37
-
38
- ## What gets delivered
39
-
40
- One POST carrying the terminal `run.finished` event, sent at the
41
- settle-consistent barrier — when you receive it, the run record is already
42
- terminal and its outputs are complete and readable. The body is built once at
43
- settle, frozen, and re-sent byte-identical on every retry or manual redelivery:
44
-
45
- ```json
46
- {
47
- "specversion": "1.0",
48
- "id": "<delivery id — matches the webhook-id header>",
49
- "source": "aex",
50
- "type": "run.finished",
51
- "subject": "<the run id>",
52
- "time": "2026-07-02T12:34:56.000Z",
53
- "data": {
54
- "runId": "<the run id>",
55
- "status": "succeeded",
56
- "terminalAt": "2026-07-02T12:34:56.000Z",
57
- "reason": null,
58
- "failureClass": null,
59
- "costTelemetry": { "billedCostUsd": 0.42 }
60
- }
61
- }
62
- ```
63
-
64
- `reason` / `failureClass` carry the failure detail on non-success terminals;
65
- `costTelemetry` is present when the billed cost is known.
66
-
67
- ## Verify deliveries
68
-
69
- Deliveries are signed [Standard Webhooks](https://www.standardwebhooks.com/)
70
- style: HMAC-SHA256 over `` `${webhook-id}.${webhook-timestamp}.${rawBody}` ``,
71
- sent in three headers — `webhook-id` (stable across retries; your dedupe key),
72
- `webhook-timestamp` (unix seconds), and `webhook-signature` (a space-delimited
73
- list of `v1,<base64>` entries).
74
-
75
- The signing key is a per-workspace secret. Reveal it (it is created on first
76
- use) with either surface:
77
-
78
- ```bash
79
- aex webhooks secret --api-key "$AEX_API_KEY" # prints whsec_...
80
- ```
81
-
82
- ```ts
83
- const { whsec } = await aex.webhookSigningSecret();
84
- ```
85
-
86
- Verify inbound requests with the exported `verifyAexWebhook` — pure Web Crypto,
87
- identical under Bun and Node, and interoperable with the `standardwebhooks`
88
- reference library:
89
-
90
- ```ts
91
- import { verifyAexWebhook } from "@aexhq/sdk";
92
-
93
- // In your HTTP handler — use the EXACT raw body bytes, never re-serialize.
94
- const ok = await verifyAexWebhook({
95
- rawBody,
96
- headers: request.headers,
97
- secret: process.env.AEX_WEBHOOK_SECRET! // the whsec_... value
98
- });
99
- if (!ok) return new Response("bad signature", { status: 401 });
100
- ```
101
-
102
- `verifyAexWebhook` rejects stale timestamps (default tolerance 300 seconds) and
103
- compares signatures constant-time. It accepts every `v1` entry in the signature
104
- list, so it is already rotation-ready — but **server-side rotation of the
105
- signing secret is not available yet**: `aex webhooks secret` reveals or creates
106
- the one workspace secret and there is no rotate endpoint today. If your secret
107
- is compromised, contact <support@aex.dev>.
108
-
109
- ## Delivery ledger and redelivery
110
-
111
- Each run keeps a delivery ledger — attempts, last status code, and last error:
112
-
113
- ```ts
114
- const deliveries = await session.webhooks().list();
115
- await session.webhooks().redeliver(deliveries[0]!.id);
116
- ```
117
-
118
- ```bash
119
- aex deliveries <session-id> --api-key "$AEX_API_KEY"
120
- ```
121
-
122
- Redelivery re-sends the frozen payload with the **same** `webhook-id`, so a
123
- consumer that dedupes on `webhook-id` handles retries, redeliveries, and
124
- at-least-once delivery uniformly. An empty ledger means the run carried no
125
- `webhook` or has not reached a terminal state yet.
126
-
127
- For the terminal-event mechanics behind delivery timing, see
128
- [Events](events.md).
12
+
13
+ ```ts
14
+ import { Aex, Models } from "@aexhq/sdk";
15
+
16
+ const aex = new Aex(process.env.AEX_API_KEY!);
17
+
18
+ const session = await aex.openSession({
19
+ model: Models.CLAUDE_HAIKU_4_5,
20
+ webhook: { url: "https://hooks.example.com/aex" },
21
+ apiKeys: { anthropic: process.env.ANTHROPIC_API_KEY! }
22
+ });
23
+ ```
24
+
25
+ ```bash
26
+ aex run \
27
+ --api-key "$AEX_API_KEY" \
28
+ --anthropic-api-key "$ANTHROPIC_API_KEY" \
29
+ --model claude-haiku-4-5 \
30
+ --prompt "Write the report." \
31
+ --webhook https://hooks.example.com/aex
32
+ ```
33
+
34
+ The URL must be `https`. The callback URL is an operational concern, not part
35
+ of the submission fingerprint: retrying the same submission with the same
36
+ idempotency key but a different callback URL never conflicts.
37
+
38
+ ## What gets delivered
39
+
40
+ One POST carrying the terminal `run.finished` event, sent at the
41
+ settle-consistent barrier — when you receive it, the run record is already
42
+ terminal and its outputs are complete and readable. The body is built once at
43
+ settle, frozen, and re-sent byte-identical on every retry or manual redelivery:
44
+
45
+ ```json
46
+ {
47
+ "specversion": "1.0",
48
+ "id": "<delivery id — matches the webhook-id header>",
49
+ "source": "aex",
50
+ "type": "run.finished",
51
+ "subject": "<the run id>",
52
+ "time": "2026-07-02T12:34:56.000Z",
53
+ "data": {
54
+ "runId": "<the run id>",
55
+ "status": "succeeded",
56
+ "terminalAt": "2026-07-02T12:34:56.000Z",
57
+ "reason": null,
58
+ "failureClass": null,
59
+ "costTelemetry": { "billedCostUsd": 0.42 }
60
+ }
61
+ }
62
+ ```
63
+
64
+ `reason` / `failureClass` carry the failure detail on non-success terminals;
65
+ `costTelemetry` is present when the billed cost is known.
66
+
67
+ ## Verify deliveries
68
+
69
+ Deliveries are signed [Standard Webhooks](https://www.standardwebhooks.com/)
70
+ style: HMAC-SHA256 over `` `${webhook-id}.${webhook-timestamp}.${rawBody}` ``,
71
+ sent in three headers — `webhook-id` (stable across retries; your dedupe key),
72
+ `webhook-timestamp` (unix seconds), and `webhook-signature` (a space-delimited
73
+ list of `v1,<base64>` entries).
74
+
75
+ The signing key is a per-workspace secret. Reveal it (it is created on first
76
+ use) with either surface:
77
+
78
+ ```bash
79
+ aex webhooks secret --api-key "$AEX_API_KEY" # prints whsec_...
80
+ ```
81
+
82
+ ```ts
83
+ const { whsec } = await aex.webhookSigningSecret();
84
+ ```
85
+
86
+ Verify inbound requests with the exported `verifyAexWebhook` — pure Web Crypto,
87
+ identical under Bun and Node, and interoperable with the `standardwebhooks`
88
+ reference library:
89
+
90
+ ```ts
91
+ import { verifyAexWebhook } from "@aexhq/sdk";
92
+
93
+ // In your HTTP handler — use the EXACT raw body bytes, never re-serialize.
94
+ const ok = await verifyAexWebhook({
95
+ rawBody,
96
+ headers: request.headers,
97
+ secret: process.env.AEX_WEBHOOK_SECRET! // the whsec_... value
98
+ });
99
+ if (!ok) return new Response("bad signature", { status: 401 });
100
+ ```
101
+
102
+ `verifyAexWebhook` rejects stale timestamps (default tolerance 300 seconds) and
103
+ compares signatures constant-time. It accepts every `v1` entry in the signature
104
+ list, so it is already rotation-ready — but **server-side rotation of the
105
+ signing secret is not available yet**: `aex webhooks secret` reveals or creates
106
+ the one workspace secret and there is no rotate endpoint today. If your secret
107
+ is compromised, contact <support@aex.dev>.
108
+
109
+ ## Delivery ledger and redelivery
110
+
111
+ Each run keeps a delivery ledger — attempts, last status code, and last error:
112
+
113
+ ```ts
114
+ const deliveries = await session.webhooks().list();
115
+ await session.webhooks().redeliver(deliveries[0]!.id);
116
+ ```
117
+
118
+ ```bash
119
+ aex deliveries <session-id> --api-key "$AEX_API_KEY"
120
+ ```
121
+
122
+ Redelivery re-sends the frozen payload with the **same** `webhook-id`, so a
123
+ consumer that dedupes on `webhook-id` handles retries, redeliveries, and
124
+ at-least-once delivery uniformly. An empty ledger means the run carried no
125
+ `webhook` or has not reached a terminal state yet.
126
+
127
+ For the terminal-event mechanics behind delivery timing, see
128
+ [Events](events.md).