@aexhq/sdk 0.46.5-canary → 0.51.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.
Files changed (346) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +38 -0
  3. package/README.md +54 -29
  4. package/dist/client/aex.d.ts +33 -0
  5. package/dist/client/aex.js +108 -0
  6. package/dist/client/aex.js.map +1 -0
  7. package/dist/client/credentials.d.ts +25 -0
  8. package/dist/client/credentials.js +97 -0
  9. package/dist/client/credentials.js.map +1 -0
  10. package/dist/client/routing.d.ts +7 -0
  11. package/dist/client/routing.js +29 -0
  12. package/dist/client/routing.js.map +1 -0
  13. package/dist/downloads/download.d.ts +18 -0
  14. package/dist/downloads/download.js +67 -0
  15. package/dist/downloads/download.js.map +1 -0
  16. package/dist/generated/errors.d.ts +12 -0
  17. package/dist/generated/errors.js +82 -0
  18. package/dist/generated/errors.js.map +1 -0
  19. package/dist/generated/models.d.ts +1392 -0
  20. package/dist/generated/models.js +62 -0
  21. package/dist/generated/models.js.map +1 -0
  22. package/dist/generated/resources.d.ts +710 -0
  23. package/dist/generated/resources.js +582 -0
  24. package/dist/generated/resources.js.map +1 -0
  25. package/dist/generated/routes.d.ts +44 -0
  26. package/dist/generated/routes.js +1905 -0
  27. package/dist/generated/routes.js.map +1 -0
  28. package/dist/index.d.ts +21 -50
  29. package/dist/index.js +14 -62
  30. package/dist/index.js.map +1 -1
  31. package/dist/node/session-file-limits.d.ts +4 -0
  32. package/dist/node/session-file-limits.js +7 -0
  33. package/dist/node/session-file-limits.js.map +1 -0
  34. package/dist/node/session-files.d.ts +80 -0
  35. package/dist/node/session-files.js +254 -0
  36. package/dist/node/session-files.js.map +1 -0
  37. package/dist/observations/stream.d.ts +1 -0
  38. package/dist/observations/stream.js +18 -0
  39. package/dist/observations/stream.js.map +1 -0
  40. package/dist/transport/errors.d.ts +60 -0
  41. package/dist/transport/errors.js +107 -0
  42. package/dist/transport/errors.js.map +1 -0
  43. package/dist/transport/pagination.d.ts +8 -0
  44. package/dist/transport/pagination.js +34 -0
  45. package/dist/transport/pagination.js.map +1 -0
  46. package/dist/transport/retry.d.ts +21 -0
  47. package/dist/transport/retry.js +37 -0
  48. package/dist/transport/retry.js.map +1 -0
  49. package/dist/transport/transport.d.ts +25 -0
  50. package/dist/transport/transport.js +33 -0
  51. package/dist/transport/transport.js.map +1 -0
  52. package/package.json +67 -30
  53. package/dist/_contracts/account-operations.d.ts +0 -101
  54. package/dist/_contracts/account-operations.js +0 -242
  55. package/dist/_contracts/account-types.d.ts +0 -461
  56. package/dist/_contracts/account-types.js +0 -1
  57. package/dist/_contracts/api-key.d.ts +0 -61
  58. package/dist/_contracts/api-key.js +0 -101
  59. package/dist/_contracts/api-routes.d.ts +0 -20
  60. package/dist/_contracts/api-routes.js +0 -109
  61. package/dist/_contracts/archive-limits.d.ts +0 -3
  62. package/dist/_contracts/archive-limits.js +0 -23
  63. package/dist/_contracts/asset-authoring.d.ts +0 -22
  64. package/dist/_contracts/asset-authoring.js +0 -106
  65. package/dist/_contracts/asset-bundle.d.ts +0 -64
  66. package/dist/_contracts/asset-bundle.js +0 -263
  67. package/dist/_contracts/asset-upload-helper.d.ts +0 -31
  68. package/dist/_contracts/asset-upload-helper.js +0 -84
  69. package/dist/_contracts/billing-admission.d.ts +0 -29
  70. package/dist/_contracts/billing-admission.js +0 -28
  71. package/dist/_contracts/bundle-manifest.d.ts +0 -89
  72. package/dist/_contracts/bundle-manifest.js +0 -158
  73. package/dist/_contracts/canonical-sha256.d.ts +0 -8
  74. package/dist/_contracts/canonical-sha256.js +0 -8
  75. package/dist/_contracts/connection-ticket.d.ts +0 -22
  76. package/dist/_contracts/connection-ticket.js +0 -54
  77. package/dist/_contracts/continuation-event.d.ts +0 -31
  78. package/dist/_contracts/continuation-event.js +0 -6
  79. package/dist/_contracts/contract-parse-error.d.ts +0 -12
  80. package/dist/_contracts/contract-parse-error.js +0 -51
  81. package/dist/_contracts/error-codes.d.ts +0 -26
  82. package/dist/_contracts/error-codes.js +0 -116
  83. package/dist/_contracts/error-factory.d.ts +0 -32
  84. package/dist/_contracts/error-factory.js +0 -174
  85. package/dist/_contracts/event-envelope.d.ts +0 -471
  86. package/dist/_contracts/event-envelope.js +0 -501
  87. package/dist/_contracts/event-stream-client.d.ts +0 -122
  88. package/dist/_contracts/event-stream-client.js +0 -445
  89. package/dist/_contracts/event-view.d.ts +0 -44
  90. package/dist/_contracts/event-view.js +0 -69
  91. package/dist/_contracts/failure-class.d.ts +0 -29
  92. package/dist/_contracts/failure-class.js +0 -73
  93. package/dist/_contracts/http.d.ts +0 -135
  94. package/dist/_contracts/http.js +0 -434
  95. package/dist/_contracts/ids.d.ts +0 -66
  96. package/dist/_contracts/ids.js +0 -119
  97. package/dist/_contracts/index.d.ts +0 -42
  98. package/dist/_contracts/index.js +0 -52
  99. package/dist/_contracts/internal.d.ts +0 -55
  100. package/dist/_contracts/internal.js +0 -113
  101. package/dist/_contracts/models.d.ts +0 -30
  102. package/dist/_contracts/models.js +0 -28
  103. package/dist/_contracts/operation-core.d.ts +0 -36
  104. package/dist/_contracts/operation-core.js +0 -70
  105. package/dist/_contracts/operations.d.ts +0 -218
  106. package/dist/_contracts/operations.js +0 -1496
  107. package/dist/_contracts/otlp-projection.d.ts +0 -78
  108. package/dist/_contracts/otlp-projection.js +0 -171
  109. package/dist/_contracts/post-hook.d.ts +0 -31
  110. package/dist/_contracts/post-hook.js +0 -61
  111. package/dist/_contracts/provider-fault.d.ts +0 -34
  112. package/dist/_contracts/provider-fault.js +0 -68
  113. package/dist/_contracts/retry-core.d.ts +0 -29
  114. package/dist/_contracts/retry-core.js +0 -79
  115. package/dist/_contracts/runner-event.d.ts +0 -117
  116. package/dist/_contracts/runner-event.js +0 -172
  117. package/dist/_contracts/runtime-kind.d.ts +0 -60
  118. package/dist/_contracts/runtime-kind.js +0 -70
  119. package/dist/_contracts/runtime-manifest.d.ts +0 -121
  120. package/dist/_contracts/runtime-manifest.js +0 -83
  121. package/dist/_contracts/runtime-security-profile.d.ts +0 -26
  122. package/dist/_contracts/runtime-security-profile.js +0 -73
  123. package/dist/_contracts/runtime-sizes.d.ts +0 -104
  124. package/dist/_contracts/runtime-sizes.js +0 -111
  125. package/dist/_contracts/runtime-types.d.ts +0 -618
  126. package/dist/_contracts/runtime-types.js +0 -58
  127. package/dist/_contracts/schemas/asset-bundle.d.ts +0 -70
  128. package/dist/_contracts/schemas/asset-bundle.js +0 -107
  129. package/dist/_contracts/schemas/asset-ref.d.ts +0 -61
  130. package/dist/_contracts/schemas/asset-ref.js +0 -118
  131. package/dist/_contracts/schemas/bundle-manifest.d.ts +0 -66
  132. package/dist/_contracts/schemas/bundle-manifest.js +0 -77
  133. package/dist/_contracts/schemas/index.d.ts +0 -32
  134. package/dist/_contracts/schemas/index.js +0 -30
  135. package/dist/_contracts/schemas/mcp-server.d.ts +0 -99
  136. package/dist/_contracts/schemas/mcp-server.js +0 -209
  137. package/dist/_contracts/schemas/models.d.ts +0 -29
  138. package/dist/_contracts/schemas/models.js +0 -51
  139. package/dist/_contracts/schemas/numeric.d.ts +0 -18
  140. package/dist/_contracts/schemas/numeric.js +0 -28
  141. package/dist/_contracts/schemas/post-hook.d.ts +0 -45
  142. package/dist/_contracts/schemas/post-hook.js +0 -68
  143. package/dist/_contracts/schemas/response-assets.d.ts +0 -75
  144. package/dist/_contracts/schemas/response-assets.js +0 -81
  145. package/dist/_contracts/schemas/response-billing.d.ts +0 -208
  146. package/dist/_contracts/schemas/response-billing.js +0 -139
  147. package/dist/_contracts/schemas/response-common.d.ts +0 -132
  148. package/dist/_contracts/schemas/response-common.js +0 -162
  149. package/dist/_contracts/schemas/response-identity.d.ts +0 -648
  150. package/dist/_contracts/schemas/response-identity.js +0 -131
  151. package/dist/_contracts/schemas/response-mcp-servers.d.ts +0 -51
  152. package/dist/_contracts/schemas/response-mcp-servers.js +0 -32
  153. package/dist/_contracts/schemas/response-secrets.d.ts +0 -50
  154. package/dist/_contracts/schemas/response-secrets.js +0 -32
  155. package/dist/_contracts/schemas/response-sessions-internal.d.ts +0 -200
  156. package/dist/_contracts/schemas/response-sessions-internal.js +0 -142
  157. package/dist/_contracts/schemas/response-sessions.d.ts +0 -1598
  158. package/dist/_contracts/schemas/response-sessions.js +0 -377
  159. package/dist/_contracts/schemas/response-webhooks.d.ts +0 -76
  160. package/dist/_contracts/schemas/response-webhooks.js +0 -42
  161. package/dist/_contracts/schemas/response-workspace.d.ts +0 -225
  162. package/dist/_contracts/schemas/response-workspace.js +0 -99
  163. package/dist/_contracts/schemas/runtime-kind.d.ts +0 -31
  164. package/dist/_contracts/schemas/runtime-kind.js +0 -29
  165. package/dist/_contracts/schemas/runtime-security-profile.d.ts +0 -28
  166. package/dist/_contracts/schemas/runtime-security-profile.js +0 -26
  167. package/dist/_contracts/schemas/runtime-sizes.d.ts +0 -70
  168. package/dist/_contracts/schemas/runtime-sizes.js +0 -127
  169. package/dist/_contracts/schemas/session-limits.d.ts +0 -34
  170. package/dist/_contracts/schemas/session-limits.js +0 -39
  171. package/dist/_contracts/schemas/session-machine.d.ts +0 -23
  172. package/dist/_contracts/schemas/session-machine.js +0 -24
  173. package/dist/_contracts/schemas/session-request-config.d.ts +0 -58
  174. package/dist/_contracts/schemas/session-request-config.js +0 -134
  175. package/dist/_contracts/schemas/session-webhook.d.ts +0 -11
  176. package/dist/_contracts/schemas/session-webhook.js +0 -38
  177. package/dist/_contracts/schemas/side-effect-audit.d.ts +0 -98
  178. package/dist/_contracts/schemas/side-effect-audit.js +0 -102
  179. package/dist/_contracts/schemas/submission-assets.d.ts +0 -117
  180. package/dist/_contracts/schemas/submission-assets.js +0 -147
  181. package/dist/_contracts/schemas/submission-body.d.ts +0 -251
  182. package/dist/_contracts/schemas/submission-body.js +0 -378
  183. package/dist/_contracts/schemas/submission-environment.d.ts +0 -79
  184. package/dist/_contracts/schemas/submission-environment.js +0 -179
  185. package/dist/_contracts/schemas/submission-request.d.ts +0 -158
  186. package/dist/_contracts/schemas/submission-request.js +0 -49
  187. package/dist/_contracts/schemas/submission-secrets.d.ts +0 -47
  188. package/dist/_contracts/schemas/submission-secrets.js +0 -108
  189. package/dist/_contracts/schemas/wire.d.ts +0 -118
  190. package/dist/_contracts/schemas/wire.js +0 -171
  191. package/dist/_contracts/schemas/workspace-resources.d.ts +0 -50
  192. package/dist/_contracts/schemas/workspace-resources.js +0 -87
  193. package/dist/_contracts/sdk-errors.d.ts +0 -212
  194. package/dist/_contracts/sdk-errors.js +0 -313
  195. package/dist/_contracts/sdk-secrets.d.ts +0 -67
  196. package/dist/_contracts/sdk-secrets.js +0 -427
  197. package/dist/_contracts/session-archive.d.ts +0 -16
  198. package/dist/_contracts/session-archive.js +0 -92
  199. package/dist/_contracts/session-artifacts.d.ts +0 -189
  200. package/dist/_contracts/session-artifacts.js +0 -264
  201. package/dist/_contracts/session-config.d.ts +0 -373
  202. package/dist/_contracts/session-config.js +0 -562
  203. package/dist/_contracts/session-cost-types.d.ts +0 -211
  204. package/dist/_contracts/session-cost-types.js +0 -69
  205. package/dist/_contracts/session-cost.d.ts +0 -8
  206. package/dist/_contracts/session-cost.js +0 -582
  207. package/dist/_contracts/session-custody.d.ts +0 -165
  208. package/dist/_contracts/session-custody.js +0 -345
  209. package/dist/_contracts/session-file-query.d.ts +0 -14
  210. package/dist/_contracts/session-file-query.js +0 -178
  211. package/dist/_contracts/session-record.d.ts +0 -112
  212. package/dist/_contracts/session-record.js +0 -165
  213. package/dist/_contracts/session-retention.d.ts +0 -201
  214. package/dist/_contracts/session-retention.js +0 -450
  215. package/dist/_contracts/side-effect-audit.d.ts +0 -126
  216. package/dist/_contracts/side-effect-audit.js +0 -520
  217. package/dist/_contracts/sse.d.ts +0 -74
  218. package/dist/_contracts/sse.js +0 -227
  219. package/dist/_contracts/stable.d.ts +0 -45
  220. package/dist/_contracts/stable.js +0 -62
  221. package/dist/_contracts/status.d.ts +0 -25
  222. package/dist/_contracts/status.js +0 -57
  223. package/dist/_contracts/submission-limits.d.ts +0 -61
  224. package/dist/_contracts/submission-limits.js +0 -60
  225. package/dist/_contracts/submission.d.ts +0 -547
  226. package/dist/_contracts/submission.js +0 -812
  227. package/dist/_contracts/suggest.d.ts +0 -15
  228. package/dist/_contracts/suggest.js +0 -53
  229. package/dist/_contracts/testing/response-bindings.d.ts +0 -45
  230. package/dist/_contracts/testing/response-bindings.js +0 -256
  231. package/dist/_contracts/testing/wire-conformance-entry.d.ts +0 -10
  232. package/dist/_contracts/testing/wire-conformance-entry.js +0 -8
  233. package/dist/_contracts/testing/wire-conformance.d.ts +0 -169
  234. package/dist/_contracts/testing/wire-conformance.js +0 -276
  235. package/dist/_contracts/turn-trace.d.ts +0 -28
  236. package/dist/_contracts/turn-trace.js +0 -1
  237. package/dist/_contracts/unknown-field-error.d.ts +0 -13
  238. package/dist/_contracts/unknown-field-error.js +0 -21
  239. package/dist/_contracts/value-guards.d.ts +0 -20
  240. package/dist/_contracts/value-guards.js +0 -34
  241. package/dist/_contracts/webhook-verify.d.ts +0 -34
  242. package/dist/_contracts/webhook-verify.js +0 -93
  243. package/dist/_contracts/wire-observer.d.ts +0 -49
  244. package/dist/_contracts/wire-observer.js +0 -34
  245. package/dist/_contracts/workflow-status.d.ts +0 -7
  246. package/dist/_contracts/workflow-status.js +0 -43
  247. package/dist/_contracts/workspace-resources.d.ts +0 -98
  248. package/dist/_contracts/workspace-resources.js +0 -39
  249. package/dist/archive-limits.d.ts +0 -1
  250. package/dist/archive-limits.js +0 -2
  251. package/dist/archive-limits.js.map +0 -1
  252. package/dist/asset-upload.d.ts +0 -47
  253. package/dist/asset-upload.js +0 -269
  254. package/dist/asset-upload.js.map +0 -1
  255. package/dist/bundle.d.ts +0 -9
  256. package/dist/bundle.js +0 -20
  257. package/dist/bundle.js.map +0 -1
  258. package/dist/canonical-zip.d.ts +0 -68
  259. package/dist/canonical-zip.js +0 -355
  260. package/dist/canonical-zip.js.map +0 -1
  261. package/dist/cli.mjs +0 -12048
  262. package/dist/cli.mjs.sha256 +0 -1
  263. package/dist/client-types.d.ts +0 -192
  264. package/dist/client-types.js +0 -2
  265. package/dist/client-types.js.map +0 -1
  266. package/dist/client.d.ts +0 -464
  267. package/dist/client.js +0 -1207
  268. package/dist/client.js.map +0 -1
  269. package/dist/event-projection.d.ts +0 -22
  270. package/dist/event-projection.js +0 -380
  271. package/dist/event-projection.js.map +0 -1
  272. package/dist/fetch-archive.d.ts +0 -16
  273. package/dist/fetch-archive.js +0 -252
  274. package/dist/fetch-archive.js.map +0 -1
  275. package/dist/file.d.ts +0 -96
  276. package/dist/file.js +0 -272
  277. package/dist/file.js.map +0 -1
  278. package/dist/instructions.d.ts +0 -20
  279. package/dist/instructions.js +0 -40
  280. package/dist/instructions.js.map +0 -1
  281. package/dist/legacy-session-provider-fault.d.ts +0 -7
  282. package/dist/legacy-session-provider-fault.js +0 -38
  283. package/dist/legacy-session-provider-fault.js.map +0 -1
  284. package/dist/mcp-server.d.ts +0 -84
  285. package/dist/mcp-server.js +0 -117
  286. package/dist/mcp-server.js.map +0 -1
  287. package/dist/node-fs.d.ts +0 -29
  288. package/dist/node-fs.js +0 -19
  289. package/dist/node-fs.js.map +0 -1
  290. package/dist/node-walk.d.ts +0 -69
  291. package/dist/node-walk.js +0 -151
  292. package/dist/node-walk.js.map +0 -1
  293. package/dist/path-basename.d.ts +0 -5
  294. package/dist/path-basename.js +0 -9
  295. package/dist/path-basename.js.map +0 -1
  296. package/dist/retry.d.ts +0 -70
  297. package/dist/retry.js +0 -155
  298. package/dist/retry.js.map +0 -1
  299. package/dist/secret.d.ts +0 -65
  300. package/dist/secret.js +0 -110
  301. package/dist/secret.js.map +0 -1
  302. package/dist/session-validate.d.ts +0 -100
  303. package/dist/session-validate.js +0 -303
  304. package/dist/session-validate.js.map +0 -1
  305. package/dist/skill.d.ts +0 -99
  306. package/dist/skill.js +0 -169
  307. package/dist/skill.js.map +0 -1
  308. package/dist/submission-wire.d.ts +0 -13
  309. package/dist/submission-wire.js +0 -69
  310. package/dist/submission-wire.js.map +0 -1
  311. package/dist/tool.d.ts +0 -41
  312. package/dist/tool.js +0 -76
  313. package/dist/tool.js.map +0 -1
  314. package/dist/version.d.ts +0 -9
  315. package/dist/version.js +0 -10
  316. package/dist/version.js.map +0 -1
  317. package/docs/authentication.md +0 -125
  318. package/docs/billing.md +0 -164
  319. package/docs/cleanup.md +0 -27
  320. package/docs/concepts/agent-tools.md +0 -47
  321. package/docs/concepts/composition.md +0 -60
  322. package/docs/concepts/providers-and-runtimes.md +0 -121
  323. package/docs/concepts/sessions.md +0 -51
  324. package/docs/concepts/subagents.md +0 -35
  325. package/docs/credentials.md +0 -116
  326. package/docs/defaults.md +0 -51
  327. package/docs/errors.md +0 -258
  328. package/docs/events.md +0 -143
  329. package/docs/files.md +0 -130
  330. package/docs/limits-and-quotas.md +0 -114
  331. package/docs/limits.md +0 -51
  332. package/docs/mcp.md +0 -47
  333. package/docs/networking.md +0 -114
  334. package/docs/provider-runtime-capabilities.md +0 -32
  335. package/docs/public-surface.json +0 -73
  336. package/docs/quickstart.md +0 -135
  337. package/docs/release.md +0 -44
  338. package/docs/retries.md +0 -108
  339. package/docs/secrets.md +0 -141
  340. package/docs/session-config.md +0 -51
  341. package/docs/session-record.md +0 -58
  342. package/docs/skills.md +0 -65
  343. package/docs/telemetry.md +0 -66
  344. package/docs/testing.md +0 -35
  345. package/docs/vision-skills.md +0 -94
  346. package/docs/webhooks.md +0 -143
package/dist/client.js DELETED
@@ -1,1207 +0,0 @@
1
- import { CredentialValidationError, HttpClient, PLANE_BASE_URLS, SessionStateError, SecretString, asAexEventView, asAexStreamEventView, isReplayableEvent, tryParseApiKey, parseModelSlug, resolveBuiltinToolNames, streamCoordinatorEvents, parseSessionLimits, parseApprovalGate, parseResponseFormat, parseRuntimeSize, parseRuntimeKind, parseSessionTimeout, parseSessionWebhook } from "./_contracts/index.js";
2
- import { hasRunTerminalType, operations } from "./_contracts/internal.js";
3
- import { uploadAsset, uploadAssetMultipart } from "./asset-upload.js";
4
- import { AexRateLimitError, isThrottleFault, resolveRetryConfig } from "./retry.js";
5
- import { legacySessionProviderFault } from "./legacy-session-provider-fault.js";
6
- import { splitSecretEnv } from "./secret.js";
7
- import { assertRunCheckpoint, assertSessionCommittedAfterRun, buildTurnResult, isSessionRunTerminalEvent, messageFromWire, PROGRESSING_SESSION_STATUSES, projectAssistantMessages, terminalCheckpointId, terminalSessionStatusFromEvents, turnTraceFromEvents } from "./event-projection.js";
8
- import { assertStartSessionOptions, assertSupportedSessionFields, assertSupportedSessionSendOptions, configError, normaliseSessionInput, validatedSessionConfig } from "./session-validate.js";
9
- import { fileCaptureForWire, mergeMcpServers, sessionEnvironmentForWire, sessionRetentionForWire } from "./submission-wire.js";
10
- export class SessionRunStream {
11
- #stream;
12
- #events = [];
13
- #waiters = new Set();
14
- #outcome;
15
- #pump;
16
- #hasIterator = false;
17
- constructor(stream) {
18
- this.#stream = stream;
19
- }
20
- #start() {
21
- this.#pump ??= this.#drain();
22
- return this.#pump;
23
- }
24
- async #drain() {
25
- const generator = this.#stream();
26
- try {
27
- let next = await generator.next();
28
- while (!next.done) {
29
- this.#events.push(next.value);
30
- this.#notify();
31
- next = await generator.next();
32
- }
33
- this.#outcome = { ok: true, value: next.value };
34
- this.#notify();
35
- return next.value;
36
- }
37
- catch (error) {
38
- this.#outcome = { ok: false, error };
39
- this.#notify();
40
- throw error;
41
- }
42
- }
43
- #notify() {
44
- for (const resolve of this.#waiters)
45
- resolve();
46
- this.#waiters.clear();
47
- }
48
- [Symbol.asyncIterator]() {
49
- let cursor = this.#hasIterator ? this.#events.length : 0;
50
- this.#hasIterator = true;
51
- void this.#start().catch(() => { });
52
- // Deliberately do NOT forward `return()`: `break`-ing out of a
53
- // `for await` loop must not close the in-flight turn — `finished()` can
54
- // still drain it to completion afterwards.
55
- return {
56
- next: async () => {
57
- while (true) {
58
- if (cursor < this.#events.length) {
59
- return { done: false, value: this.#events[cursor++] };
60
- }
61
- if (this.#outcome !== undefined) {
62
- if (!this.#outcome.ok)
63
- throw this.#outcome.error;
64
- return { done: true, value: undefined };
65
- }
66
- await new Promise((resolve) => this.#waiters.add(resolve));
67
- }
68
- },
69
- return: async () => ({ done: true, value: undefined })
70
- };
71
- }
72
- finished() {
73
- return this.#start();
74
- }
75
- }
76
- const internalSessionSenders = new WeakMap();
77
- function sendSessionInternal(session, input, options = {}) {
78
- const sender = internalSessionSenders.get(session);
79
- if (sender === undefined) {
80
- throw new Error("Aex: invalid session handle");
81
- }
82
- return sender(normaliseSessionInput(input, "session.messages.send", "input"), options);
83
- }
84
- export class SessionHandle {
85
- #http;
86
- #fetch;
87
- #session;
88
- messages;
89
- events;
90
- otel;
91
- files;
92
- webhooks;
93
- /** The last message sent on this handle, for `session.messages.replayLast()`. */
94
- #lastSend;
95
- constructor(http, session, fetch) {
96
- this.#http = http;
97
- this.#session = session;
98
- this.#fetch = fetch;
99
- const id = session.id;
100
- this.messages = sessionMessages(http, id, (input, options = {}) => {
101
- assertSupportedSessionSendOptions(options, "session.messages.send");
102
- return sendSessionInternal(this, input, options);
103
- }, (options = {}) => {
104
- assertSupportedSessionSendOptions(options, "session.messages.replayLast");
105
- const last = this.#lastSend;
106
- if (last === undefined) {
107
- throw new SessionStateError("session.messages.replayLast: no message has been sent on this session yet");
108
- }
109
- return sendSessionInternal(this, last.input, {
110
- ...options,
111
- idempotencyKey: options.idempotencyKey ?? last.idempotencyKey
112
- });
113
- });
114
- this.events = sessionEvents(http, id);
115
- this.otel = sessionOtel(http, id);
116
- this.files = sessionFiles(http, id, fetch);
117
- this.webhooks = {
118
- list: () => operations.getSessionWebhookDeliveries(http, id),
119
- redeliver: (deliveryId) => operations.redeliverSessionWebhook(http, id, deliveryId)
120
- };
121
- internalSessionSenders.set(this, (input, options = {}) => new SessionRunStream(() => this.#send(input, options)));
122
- }
123
- get id() {
124
- return this.#session.id;
125
- }
126
- get record() {
127
- return this.#session;
128
- }
129
- async *#send(input, options) {
130
- const idempotencyKey = operations.resolveIdempotencyKey(options.idempotencyKey);
131
- this.#lastSend = { input, idempotencyKey };
132
- const accepted = await operations.sendSessionMessage(this.#http, this.id, { input }, { idempotencyKey });
133
- this.#session = accepted.session;
134
- const run = accepted.run;
135
- const eventCursor = accepted.eventCursor ?? run.eventCursor ?? 0;
136
- const streamEvents = [];
137
- for await (const event of streamSessionRunEvents(this.#http, this.id, run, {
138
- ...options,
139
- from: eventCursor
140
- })) {
141
- streamEvents.push(event);
142
- yield event;
143
- }
144
- const events = streamEvents.filter(isDurableEventView);
145
- // RUN_FINISHED/RUN_ERROR is the consistency barrier: all reads below must
146
- // already observe the same committed run and checkpoint.
147
- const read = terminalSessionStatusFromEvents(events, run.runId);
148
- this.#session = await operations.getSession(this.#http, this.id);
149
- assertSessionCommittedAfterRun(this.#session, run, read);
150
- const checkpointId = terminalCheckpointId(events, run.runId);
151
- const snapshot = checkpointId === undefined
152
- ? undefined
153
- : await operations.listSessionFiles(this.#http, this.id, { checkpointId });
154
- if (snapshot !== undefined) {
155
- assertRunCheckpoint(events, run.runId, snapshot.revision);
156
- }
157
- const messages = projectAssistantMessages(events);
158
- return buildTurnResult(this.id, this.#session, run, events, snapshot?.files ?? [], snapshot?.revision, messages, read);
159
- }
160
- async suspend() {
161
- const accepted = await operations.suspendSession(this.#http, this.id);
162
- this.#session = accepted.session;
163
- return accepted;
164
- }
165
- async cancel() {
166
- const accepted = await operations.cancelSession(this.#http, this.id);
167
- this.#session = accepted.session;
168
- return accepted;
169
- }
170
- async resume() {
171
- const accepted = await operations.resumeSession(this.#http, this.id);
172
- this.#session = accepted.session;
173
- return accepted;
174
- }
175
- async delete() {
176
- const accepted = await operations.deleteSession(this.#http, this.id);
177
- if (accepted && typeof accepted === "object" && "session" in accepted) {
178
- this.#session = accepted.session;
179
- }
180
- }
181
- /**
182
- * Request the HITL write-gate: park this session `awaiting_approval` before
183
- * its next gated action. Imperative counterpart to the declarative
184
- * `approvalGate` submission option. Resume with {@link approve} / reject with
185
- * {@link deny}.
186
- */
187
- async requestApproval() {
188
- const accepted = await operations.requestApproval(this.#http, this.id);
189
- this.#session = accepted.session;
190
- return accepted;
191
- }
192
- /** Approve an `awaiting_approval` session so the held turn resumes (→ running). */
193
- async approve() {
194
- const accepted = await operations.approveSession(this.#http, this.id);
195
- this.#session = accepted.session;
196
- return accepted;
197
- }
198
- /** Deny an `awaiting_approval` session; its run is cancelled and the session returns to `idle`. */
199
- async deny() {
200
- const accepted = await operations.denySession(this.#http, this.id);
201
- this.#session = accepted.session;
202
- return accepted;
203
- }
204
- /**
205
- * Enumerate this session's subagent CHILD sessions (`GET /api/sessions/:id/children`). Each is
206
- * a read-only {@link ChildSessionHandle} with observable events, checkpointed
207
- * files, descendants, lineage, and lifecycle state.
208
- */
209
- async children() {
210
- const refs = await operations.listSessionChildren(this.#http, this.id);
211
- return refs.map((ref) => new ChildSessionHandle(this.#http, ref, this.#fetch));
212
- }
213
- /** Re-read the session record from the server and store it as the current record. */
214
- async refresh() {
215
- this.#session = await operations.getSession(this.#http, this.id);
216
- return this.#session;
217
- }
218
- /**
219
- * Download EVERYTHING public about this session as one zip, assembled
220
- * client-side from the public read endpoints. Organised into `metadata/`,
221
- * `events/`, and `files/` folders, plus a `manifest.json`. Pass `to` to
222
- * also write the bytes to a file path while still returning them.
223
- */
224
- async download(options) {
225
- return writeOptionalFile(await operations.download(this.#http, this.id), options?.to);
226
- }
227
- /** Download only the session record (the `metadata` namespace) as a zip. */
228
- async downloadMetadata(options) {
229
- return writeOptionalFile(await operations.downloadMetadata(this.#http, this.id), options?.to);
230
- }
231
- }
232
- export class SessionClient {
233
- #http;
234
- #fetch;
235
- #buildCreateRequest;
236
- constructor(http, buildCreateRequest, fetch) {
237
- this.#http = http;
238
- this.#buildCreateRequest = buildCreateRequest;
239
- this.#fetch = fetch;
240
- }
241
- async create(options) {
242
- const request = await this.#buildCreateRequest(options);
243
- const session = await operations.createSession(this.#http, request, { idempotencyKey: operations.resolveIdempotencyKey(options.idempotencyKey) });
244
- return new SessionHandle(this.#http, session, this.#fetch);
245
- }
246
- async open(sessionId) {
247
- return new SessionHandle(this.#http, await operations.getSession(this.#http, sessionId), this.#fetch);
248
- }
249
- get(sessionId) {
250
- return operations.getSession(this.#http, sessionId);
251
- }
252
- async delete(sessionId) {
253
- await operations.deleteSession(this.#http, sessionId);
254
- }
255
- list(query) {
256
- return operations.listSessions(this.#http, query);
257
- }
258
- }
259
- /**
260
- * Read-only observation handle for a lineage-discoverable subagent child.
261
- * Child ids address events, checkpointed files, and descendants. They are not
262
- * top-level resumable sessions, so this handle deliberately has no get, send,
263
- * cancel, suspend, resume, or delete controls.
264
- */
265
- export class ChildSessionHandle {
266
- #http;
267
- #fetch;
268
- #ref;
269
- events;
270
- files;
271
- constructor(http, ref, fetch) {
272
- this.#http = http;
273
- this.#ref = ref;
274
- this.#fetch = fetch;
275
- this.events = childSessionEventsAccessor(http, ref);
276
- this.files = sessionFiles(http, ref.id, fetch);
277
- }
278
- get id() {
279
- return this.#ref.id;
280
- }
281
- get parentSessionId() {
282
- return this.#ref.parentSessionId;
283
- }
284
- get depth() {
285
- return this.#ref.depth;
286
- }
287
- /** The lifecycle status captured by the parent lineage read. */
288
- get status() {
289
- return this.#ref.status;
290
- }
291
- get ref() {
292
- return this.#ref;
293
- }
294
- /** This child's own subagent children (recursive lineage). */
295
- async children() {
296
- const refs = await operations.listSessionChildren(this.#http, this.id);
297
- return refs.map((ref) => new ChildSessionHandle(this.#http, ref, this.#fetch));
298
- }
299
- }
300
- /** Session-record events accessor (list + polling stream) used by {@link ChildSessionHandle}. */
301
- function childSessionEventsAccessor(http, ref) {
302
- return {
303
- iterate: (options) => iterateSessionEventViews(http, ref.id, options ?? {}),
304
- list: async () => (await operations.listSessionEvents(http, ref.id)).map(asAexEventView),
305
- stream: (options) => streamChildSessionEventsPolling(http, ref, options ?? {})
306
- };
307
- }
308
- async function* iterateSessionEventViews(http, id, options) {
309
- for await (const event of operations.iterateSessionEvents(http, id, options)) {
310
- yield asAexEventView(event);
311
- }
312
- }
313
- /** One snapshot-polling engine shared by root and child session event streams. */
314
- async function* pollSessionEventViews(http, id, options, resolvePolling) {
315
- const from = validateStreamEventsFrom(options.from);
316
- if (options.signal?.aborted)
317
- return;
318
- const seenIds = new Set();
319
- const intervalMs = options.intervalMs ?? 1_000;
320
- const signal = options.signal;
321
- const { boundedRunlessSnapshot, isTerminal } = await resolvePolling(from);
322
- while (!signal?.aborted) {
323
- const events = await operations.listSessionEvents(http, id);
324
- let terminalSeen = false;
325
- for (const event of events) {
326
- if (event.sequence >= from && !seenIds.has(event.id)) {
327
- seenIds.add(event.id);
328
- yield asAexEventView(event);
329
- }
330
- if (isTerminal(event))
331
- terminalSeen = true;
332
- }
333
- if (terminalSeen || boundedRunlessSnapshot)
334
- return;
335
- // `sleep` rejects on abort — treat that as a graceful stop.
336
- try {
337
- await sleep(intervalMs, signal);
338
- }
339
- catch {
340
- return;
341
- }
342
- }
343
- }
344
- /**
345
- * Poll a child session's events until a committed RUN terminal is visible, the
346
- * signal aborts, or the caller breaks the iterator.
347
- */
348
- function streamChildSessionEventsPolling(http, ref, options) {
349
- return pollSessionEventViews(http, ref.id, options, (from) => {
350
- const progressing = PROGRESSING_SESSION_STATUSES.has(ref.status);
351
- const targetRunId = progressing ? undefined : ref.lastRun?.runId;
352
- const priorRunId = progressing ? ref.lastRun?.runId : undefined;
353
- return {
354
- boundedRunlessSnapshot: !progressing && targetRunId === undefined,
355
- isTerminal: targetRunId !== undefined
356
- ? (event) => isSessionRunTerminalEvent(event, targetRunId)
357
- : (event) => hasRunTerminalType(event) && event.sequence >= from && event.runId !== priorRunId
358
- };
359
- });
360
- }
361
- async function* streamSessionRunEvents(http, sessionId, run, options) {
362
- const first = await operations.getSessionCoordinatorTicket(http, sessionId);
363
- for await (const event of streamCoordinatorEvents({
364
- wsUrl: first.wsUrl,
365
- from: options.from ?? 0,
366
- fetchTicket: async () => (await operations.getSessionCoordinatorTicket(http, sessionId)).ticket,
367
- isTerminal: (event) => isSessionRunTerminalEvent(event, run.runId),
368
- ...(options.signal ? { signal: options.signal } : {}),
369
- ...(options.webSocketFactory ? { webSocketFactory: options.webSocketFactory } : {}),
370
- ...(options.idleTimeoutMs !== undefined ? { idleTimeoutMs: options.idleTimeoutMs } : {}),
371
- ...(options.pingIntervalMs !== undefined ? { pingIntervalMs: options.pingIntervalMs } : {})
372
- })) {
373
- if (event.runId !== run.runId)
374
- continue;
375
- yield asAexStreamEventView(event);
376
- }
377
- }
378
- function isDurableEventView(event) {
379
- return isReplayableEvent(event);
380
- }
381
- /**
382
- * Poll the session's event snapshots until a durable run terminal, the signal
383
- * aborts, or the caller breaks the iterator, deduping by event id. Yields the
384
- * one canonical guard-bearing {@link AexEventView} (same shape as every other
385
- * event surface). Module-level so `SessionHandle.events` can hand it to its
386
- * accessor object literal.
387
- */
388
- function streamSessionEventsPolling(http, id, options) {
389
- return pollSessionEventViews(http, id, options, async (from) => {
390
- const initial = await operations.getSession(http, id);
391
- const targetRunId = initial.currentRun?.runId ?? initial.lastRun?.runId;
392
- return {
393
- boundedRunlessSnapshot: targetRunId === undefined && !PROGRESSING_SESSION_STATUSES.has(initial.status),
394
- isTerminal: targetRunId === undefined
395
- ? (event) => hasRunTerminalType(event) && event.sequence >= from
396
- : (event) => isSessionRunTerminalEvent(event, targetRunId)
397
- };
398
- });
399
- }
400
- /**
401
- * Stream the unified {@link AexEvent} envelope live over the session's
402
- * coordinator WebSocket. The ticket is re-minted on each (re)connect so a long
403
- * session never outlives it. Module-level so `SessionHandle.events` can hand
404
- * it to its accessor object literal.
405
- */
406
- async function* streamSessionEnvelopes(http, id, options) {
407
- const first = await operations.getSessionCoordinatorTicket(http, id);
408
- for await (const event of streamCoordinatorEvents({
409
- wsUrl: first.wsUrl,
410
- from: options.from ?? 0,
411
- fetchTicket: async () => (await operations.getSessionCoordinatorTicket(http, id)).ticket,
412
- isTerminal: hasRunTerminalType,
413
- ...(options.signal ? { signal: options.signal } : {}),
414
- ...(options.idleTimeoutMs !== undefined ? { idleTimeoutMs: options.idleTimeoutMs } : {}),
415
- ...(options.pingIntervalMs !== undefined ? { pingIntervalMs: options.pingIntervalMs } : {}),
416
- ...(options.eventQuietRecheckMs !== undefined ? { eventQuietRecheckMs: options.eventQuietRecheckMs } : {})
417
- })) {
418
- yield asAexStreamEventView(event);
419
- }
420
- }
421
- /**
422
- * Download captured files. No selector → the full files namespace as a
423
- * zip; a selector → one file's raw bytes. Module-level so
424
- * `SessionHandle.files` can hand it to its accessor object literal.
425
- */
426
- async function downloadSessionFile(http, id, selector, options) {
427
- // One selector-resolution path: contracts resolve every selector against the
428
- // authoritative checkpoint, then download and verify the committed bytes.
429
- const transferOptions = {
430
- ...(options?.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),
431
- ...(options?.checkpointId !== undefined ? { checkpointId: options.checkpointId } : {})
432
- };
433
- const bytes = selector === undefined
434
- ? await operations.downloadSessionFiles(http, id, transferOptions)
435
- : (await operations.downloadSessionFile(http, id, selector, transferOptions)).bytes;
436
- return writeOptionalFile(bytes, options?.to);
437
- }
438
- /**
439
- * Build the files accessor for a session id. Shared by
440
- * `SessionHandle.files` and child-session handles, so both expose the identical
441
- * rich {@link SessionFiles} surface.
442
- */
443
- function sessionFiles(http, id, fetchLike) {
444
- const list = (query) => operations.listSessionFiles(http, id, query);
445
- return {
446
- list,
447
- last: async () => (await list()).files.at(-1),
448
- first: async () => (await list()).files[0],
449
- read: (selector, options) => operations.readSessionFileText(http, id, selector, options),
450
- find: (query) => operations.findSessionFiles(http, id, query),
451
- findOne: (query) => operations.findSessionFile(http, id, query),
452
- link: (selectorOrQuery, options) => operations.sessionFileLink(http, id, selectorOrQuery, options),
453
- fetch: async (selectorOrQuery, options) => {
454
- const link = await operations.sessionFileLink(http, id, selectorOrQuery, options);
455
- return (fetchLike ?? globalThis.fetch)(link.url);
456
- },
457
- download: (selector, options) => downloadSessionFile(http, id, selector, options)
458
- };
459
- }
460
- function sessionMessages(http, id, send, replayLast) {
461
- const list = () => listAllSessionMessages(http, id);
462
- return {
463
- send,
464
- replayLast,
465
- list,
466
- last: async () => (await list()).at(-1),
467
- first: async () => (await list())[0]
468
- };
469
- }
470
- const LIST_MESSAGES_PAGE_BUDGET = 1000;
471
- async function listAllSessionMessages(http, id) {
472
- const messages = [];
473
- const seenCursors = new Set();
474
- let cursor;
475
- for (let pageIndex = 0; pageIndex < LIST_MESSAGES_PAGE_BUDGET; pageIndex += 1) {
476
- const page = await operations.listSessionMessages(http, id, cursor === undefined ? undefined : { cursor });
477
- messages.push(...page.messages.map(messageFromWire));
478
- if (page.nextCursor === undefined)
479
- return messages;
480
- if (typeof page.nextCursor !== "string" || page.nextCursor.length === 0) {
481
- throw new SessionStateError("session messages response contains an invalid nextCursor", { sessionId: id });
482
- }
483
- if (seenCursors.has(page.nextCursor)) {
484
- throw new SessionStateError("session messages pagination repeated a cursor", {
485
- sessionId: id,
486
- cursor: page.nextCursor
487
- });
488
- }
489
- seenCursors.add(page.nextCursor);
490
- cursor = page.nextCursor;
491
- }
492
- throw new SessionStateError("session messages pagination exceeded its page budget", {
493
- sessionId: id,
494
- pageBudget: LIST_MESSAGES_PAGE_BUDGET
495
- });
496
- }
497
- function sessionEvents(http, id) {
498
- const iterate = (options) => iterateSessionEventViews(http, id, options ?? {});
499
- const list = async () => (await operations.listSessionEvents(http, id)).map(asAexEventView);
500
- return {
501
- iterate,
502
- list,
503
- last: async () => {
504
- let last;
505
- for await (const event of iterate())
506
- last = event;
507
- return last;
508
- },
509
- first: async () => {
510
- for await (const event of iterate())
511
- return event;
512
- return undefined;
513
- },
514
- stream: (options) => streamSessionEventsPolling(http, id, options ?? {}),
515
- streamEnvelopes: (options) => streamSessionEnvelopes(http, id, options ?? {}),
516
- archiveLink: (options) => operations.eventArchiveLink(http, id, options),
517
- download: async (options) => writeOptionalFile(await operations.downloadEvents(http, id), options?.to)
518
- };
519
- }
520
- function sessionOtel(http, id) {
521
- return {
522
- traces: () => operations.iterateSessionOtlpPages(http, id, "traces"),
523
- logs: () => operations.iterateSessionOtlpPages(http, id, "logs")
524
- };
525
- }
526
- function validateStreamEventsFrom(value) {
527
- if (value === undefined)
528
- return 0;
529
- if (!Number.isSafeInteger(value) || value < 0) {
530
- throw configError("session.events.stream", "from", "from must be a non-negative safe integer");
531
- }
532
- return value;
533
- }
534
- /**
535
- * Workspace secret management exposed under `client.workspace.secrets`.
536
- *
537
- * Lifecycle parity with assets: a `Secret.value(...)` is per-session and
538
- * gone at terminal; `set` persists a named, searchable workspace secret you can `get` (metadata),
539
- * `rotate`, `list`, and `delete`. The identity is the `name`; the value rotates
540
- * under that stable name.
541
- *
542
- * Values are write-only through the public SDK: `set`/`rotate` send the value in
543
- * the request BODY (never the URL); `get`/`list` return metadata only.
544
- */
545
- export class SecretsClient {
546
- #http;
547
- constructor(http) {
548
- this.#http = http;
549
- }
550
- /** Create a named workspace secret. Accepts a raw string or a `SecretString`. */
551
- set(args) {
552
- return operations.createSecret(this.#http, { name: args.name, value: unwrapSecretValue(args.value) });
553
- }
554
- /** List workspace secret metadata (searchable by name). Never returns values. */
555
- list() {
556
- return operations.listSecrets(this.#http);
557
- }
558
- /** Metadata for one workspace secret by name. Never returns the value. */
559
- get(name) {
560
- return operations.getSecret(this.#http, name);
561
- }
562
- /** Replace the value of an existing workspace secret; bumps its version. */
563
- rotate(args) {
564
- return operations.rotateSecret(this.#http, { name: args.name, value: unwrapSecretValue(args.value) });
565
- }
566
- delete(name) {
567
- return operations.deleteSecret(this.#http, name);
568
- }
569
- }
570
- /** Accept a raw string or a `SecretString`; return the raw value for the wire. */
571
- function unwrapSecretValue(value) {
572
- const raw = value instanceof SecretString ? value.unwrap() : value;
573
- if (typeof raw !== "string" || !raw) {
574
- throw new Error("secrets: value must be a non-empty string");
575
- }
576
- return raw;
577
- }
578
- function wrapNewWorkspace(wire) {
579
- return {
580
- workspaceId: wire.workspaceId,
581
- apiKey: new SecretString(wire.apiKey, "workspace api key"),
582
- ...(typeof wire.slug === "string" ? { slug: wire.slug } : {}),
583
- ...(typeof wire.orgId === "string" ? { orgId: wire.orgId } : {})
584
- };
585
- }
586
- function wrapNewApiKey(wire) {
587
- return {
588
- id: wire.id,
589
- apiKey: new SecretString(wire.apiKey, "api key"),
590
- ...(typeof wire.name === "string" ? { name: wire.name } : {}),
591
- ...(typeof wire.kind === "string" ? { kind: wire.kind } : {}),
592
- ...(typeof wire.workspaceId === "string" ? { workspaceId: wire.workspaceId } : {}),
593
- ...(Array.isArray(wire.scopes) ? { scopes: wire.scopes } : {})
594
- };
595
- }
596
- /**
597
- * Control-plane management of the ORGS the account principal belongs to. Reached
598
- * with an account credential (PAT / device session), NOT a data-plane workspace
599
- * key. An org owns workspaces and is the billing / roles / cap boundary.
600
- *
601
- * Naming: `client.orgs` (plural) is a collection across the account, mirroring
602
- * `client.sessions` / `client.workspaces`.
603
- */
604
- export class OrgsClient {
605
- #http;
606
- constructor(http) {
607
- this.#http = http;
608
- }
609
- /** Create an org; the caller becomes its admin. */
610
- create(args) {
611
- return operations.createOrg(this.#http, args);
612
- }
613
- /** List the orgs the caller belongs to. */
614
- list() {
615
- return operations.listOrgs(this.#http);
616
- }
617
- /** List an org's members (pending invites appear with `status: "pending"`). */
618
- members(orgId) {
619
- return operations.listOrgMembers(this.#http, orgId);
620
- }
621
- /** Invite an email to the org at a role (`member` by default). */
622
- invite(orgId, args) {
623
- return operations.createOrgInvite(this.#http, orgId, args);
624
- }
625
- }
626
- /**
627
- * Control-plane management of WORKSPACES across the account's orgs. This is the
628
- * PLURAL collection (`client.workspaces`) — distinct from the SINGULAR
629
- * `client.workspace`, which is the data-plane context bound to the current key
630
- * (its files/skills/tools/instructions/secrets). Creating a workspace returns
631
- * its first workspace-scoped key ONCE.
632
- */
633
- export class WorkspacesClient {
634
- #http;
635
- constructor(http) {
636
- this.#http = http;
637
- }
638
- /**
639
- * Create a workspace under an org and reveal its first workspace-scoped API
640
- * key ONCE (wrapped in a redacted {@link SecretString}). The free tier caps at
641
- * 3 workspaces per org.
642
- */
643
- async create(args) {
644
- return wrapNewWorkspace(await operations.createWorkspace(this.#http, args));
645
- }
646
- /** List the workspaces the caller can manage across their orgs. */
647
- list() {
648
- return operations.listWorkspaces(this.#http);
649
- }
650
- /** Delete a workspace by id. Idempotent. */
651
- delete(workspaceId) {
652
- return operations.deleteWorkspace(this.#http, workspaceId);
653
- }
654
- }
655
- /**
656
- * Control-plane management of API KEYS — both data-plane workspace keys and
657
- * account PATs. Creating a key reveals its value ONCE (wrapped in a redacted
658
- * {@link SecretString}); list/delete operate on metadata only.
659
- */
660
- export class KeysClient {
661
- #http;
662
- constructor(http) {
663
- this.#http = http;
664
- }
665
- /**
666
- * Mint an API key and reveal its value ONCE. Pass `workspaceId` for a
667
- * data-plane workspace key, or `account: true` for an account PAT. A PAT
668
- * cannot mint another PAT (anti-escalation, enforced server-side).
669
- */
670
- async create(args = {}) {
671
- return wrapNewApiKey(await operations.createApiKey(this.#http, args));
672
- }
673
- /** List API keys (metadata only; never values). */
674
- list() {
675
- return operations.listApiKeys(this.#http);
676
- }
677
- /** Revoke/delete an API key by id. Idempotent. */
678
- delete(keyId) {
679
- return operations.deleteApiKey(this.#http, keyId);
680
- }
681
- }
682
- /**
683
- * Unified user-facing client for aex. The same class powers the published
684
- * `@aexhq/sdk` SDK and, under the hood, the bundled `aex` CLI. All remote
685
- * operations use the hosted aex API and operate on durable session records.
686
- *
687
- * The SDK never asks the caller for a workspace id — workspace identity
688
- * is derived server-side from the API key on every request. Use
689
- * `client.whoami()` if you want to introspect which workspace the
690
- * token resolves to.
691
- */
692
- export class Aex {
693
- #http;
694
- #debug;
695
- /** The same fetch the HttpClient uses, threaded into direct asset uploads. */
696
- #fetch;
697
- #assetRetry;
698
- /**
699
- * The SINGULAR data-plane context bound to the current key: this workspace's
700
- * files, skills, tools, instructions, and secrets. (Contrast {@link workspaces},
701
- * the plural control-plane collection.)
702
- */
703
- workspace;
704
- sessions;
705
- /** Control-plane: the orgs the account principal belongs to (roles/members/invites). */
706
- orgs;
707
- /**
708
- * Control-plane: manage WORKSPACES across your orgs (create/list/delete). The
709
- * PLURAL collection — not to be confused with {@link workspace} (singular), the
710
- * data-plane context of the current key.
711
- */
712
- workspaces;
713
- /** Control-plane: manage API keys — workspace keys and account PATs (create/list/delete). */
714
- keys;
715
- constructor(options, overrides = {}) {
716
- const resolved = typeof options === "string" ? { ...overrides, apiKey: options } : options;
717
- const apiKey = resolved.apiKey;
718
- if (!apiKey) {
719
- // Typed so a caller catching AexError (the SDK's error base) catches a
720
- // missing credential too, instead of a bare Error slipping the taxonomy.
721
- throw new CredentialValidationError("Aex: apiKey is required");
722
- }
723
- // Self-describing key ⇒ plane-aware routing, checked ZERO-network in the
724
- // constructor: derive the baseUrl from the key's plane when omitted, and
725
- // fail fast on a plane/baseUrl mismatch instead of a bare 401 after a full
726
- // round-trip. A non-self-describing key (no `aex_` shape) skips this and keeps
727
- // the HttpClient default.
728
- const baseUrl = resolveBaseUrlForKey(apiKey, resolved.baseUrl);
729
- // The transport applies the ONE shared retry policy — `HTTP_RETRY_POLICY`
730
- // from `@aexhq/contracts`, the same object the `aex` CLI hands its own
731
- // HttpClient — so an `aex` command and an SDK call react identically to a
732
- // 429. The raw `#fetch` below stays unwrapped for object-storage traffic.
733
- // Asset uploads apply the same resolved policy in their transfer helper;
734
- // `session.files.fetch()` intentionally returns the raw one-shot response.
735
- const baseFetch = resolved.fetch ?? ((input, init) => fetch(input, init));
736
- this.#debug = resolved.debug
737
- ? typeof resolved.debug === "function"
738
- ? resolved.debug
739
- : (line) => console.error(line)
740
- : undefined;
741
- this.#assetRetry = resolved.retry === false
742
- ? { maxAttempts: 1 }
743
- : resolveRetryConfig(resolved.retry);
744
- this.#http = new HttpClient({
745
- ...(baseUrl ? { baseUrl } : {}),
746
- apiKey,
747
- fetch: baseFetch,
748
- retry: resolved.retry === false ? false : resolveRetryConfig(resolved.retry),
749
- // Opt-in local diagnostics: emit a redacted per-request trace to
750
- // stderr. Uploads nothing. A caller wanting a custom sink can pass
751
- // a function instead of `true`.
752
- ...(this.#debug ? { debug: this.#debug } : {})
753
- });
754
- this.#fetch = resolved.fetch;
755
- this.workspace = new WorkspaceClient(this.#http, {
756
- upload: (args) => this.#uploadAsset(args),
757
- uploadStream: (args) => this.#uploadAssetStream(args)
758
- });
759
- this.sessions = new SessionClient(this.#http, (options) => this.#buildSessionCreateRequest(options), this.#fetch);
760
- this.orgs = new OrgsClient(this.#http);
761
- this.workspaces = new WorkspacesClient(this.#http);
762
- this.keys = new KeysClient(this.#http);
763
- }
764
- /**
765
- * Internal: materialize raw bytes to the content-addressable asset store
766
- * (`/api/assets/presign` -> PUT -> `/api/assets/finalize`). Used by the session-create
767
- * prepare step to upload draft skill / tool / instructions / file bundles so
768
- * the wire submission carries only plain `kind:"asset"` refs (skills resolve
769
- * to name-only `kind:"skill"` refs after their bytes upload).
770
- * NOT part of the public API.
771
- */
772
- async #uploadAsset(args) {
773
- return uploadAsset({
774
- http: this.#http,
775
- bytes: args.bytes,
776
- hash: args.hash,
777
- ...(args.contentType ? { contentType: args.contentType } : {}),
778
- retry: this.#assetRetry,
779
- ...(this.#fetch ? { fetch: this.#fetch } : {})
780
- });
781
- }
782
- /**
783
- * Internal: materialize a LARGE draft (a `File.fromPath` over the streaming
784
- * threshold) to the content store via the two-pass streaming multipart flow —
785
- * hash the deterministic canonical-zip stream, presign by hash (dedup still
786
- * short-circuits), then upload it in parts. Bounded memory (one entry + one
787
- * part). NOT part of the public API.
788
- */
789
- async #uploadAssetStream(args) {
790
- return uploadAssetMultipart({
791
- http: this.#http,
792
- drive: args.drive,
793
- ...(args.contentType ? { contentType: args.contentType } : {}),
794
- retry: this.#assetRetry,
795
- ...(this.#fetch ? { fetch: this.#fetch } : {})
796
- });
797
- }
798
- /**
799
- * Convenience one-shot on top of the canonical session API:
800
- * open a session, send `message` as the first run, stream through its durable
801
- * terminal event, then return the collected text,
802
- * events, files, and session record. The returned `sessionId` is the session id,
803
- * so callers can resume later with `aex.sessions.open(sessionId)`.
804
- */
805
- async start(options, opts = {}) {
806
- if (!options || typeof options !== "object" || Array.isArray(options)) {
807
- throw configError("Aex.start", "options", "options are required");
808
- }
809
- assertStartSessionOptions(opts, "Aex.start");
810
- const scopedSignal = scopedAbortSignal(opts.timeoutMs);
811
- try {
812
- const { message, deleteAfter, messageIdempotencyKey, stream, ...createOptions } = options;
813
- assertSupportedSessionFields(options, "Aex.start", true);
814
- const input = normaliseSessionInput(message, "Aex.start", "message");
815
- assertSupportedSessionSendOptions(stream, "Aex.start stream", false);
816
- const sendOptions = {
817
- ...(stream ?? {}),
818
- ...(scopedSignal?.signal ? { signal: scopedSignal.signal } : {}),
819
- ...(opts.webSocketFactory ? { webSocketFactory: opts.webSocketFactory } : {}),
820
- ...(opts.idleTimeoutMs !== undefined ? { idleTimeoutMs: opts.idleTimeoutMs } : {}),
821
- ...(opts.pingIntervalMs !== undefined ? { pingIntervalMs: opts.pingIntervalMs } : {})
822
- };
823
- // Derive the message key from the create key (like the CLI) so a retried
824
- // session with the same `idempotencyKey` de-duplicates BOTH the create and the
825
- // billable turn server-side — never a duplicate billable session turn (sdk-dx-3).
826
- const createKey = operations.resolveIdempotencyKey(createOptions.idempotencyKey);
827
- const messageKey = messageIdempotencyKey !== undefined
828
- ? operations.resolveIdempotencyKey(messageIdempotencyKey)
829
- : operations.deriveMessageIdempotencyKey(createKey);
830
- const session = await this.sessions.create({ ...createOptions, idempotencyKey: createKey });
831
- // One terminal boundary: RUN_FINISHED/RUN_ERROR carries the run outcome,
832
- // cost, and usage. `start()` only reshapes the same finished result.
833
- let turnResult;
834
- try {
835
- turnResult = await sendSessionInternal(session, input, { ...sendOptions, idempotencyKey: messageKey }).finished();
836
- }
837
- catch (err) {
838
- if (scopedSignal?.signal.aborted) {
839
- // The client-side wait budget expired. Throw rather than returning a
840
- // misleading partial result; the session continues server-side.
841
- throw new SessionStateError(`Aex.start: timed out after ${opts.timeoutMs}ms waiting for run completion in session ${session.id}; the session ` +
842
- `continues server-side — cancel via session.cancel() or reopen with aex.sessions.open(${JSON.stringify(session.id)})`);
843
- }
844
- throw err;
845
- }
846
- const sessionId = turnResult.sessionId;
847
- if (deleteAfter) {
848
- await session.delete();
849
- }
850
- const sessionState = turnResult.session;
851
- const trace = turnTraceFromEvents(turnResult.events);
852
- const outcome = turnResult.outcome;
853
- const { outcome: _untypedOutcome, ...baseResult } = turnResult;
854
- const result = {
855
- ...baseResult,
856
- trace,
857
- ...(outcome !== undefined ? { outcome } : {})
858
- };
859
- if (opts.throwOnFailure && !turnResult.ok) {
860
- // A turn that failed because the upstream provider throttled us surfaces
861
- // as a structured, non-leaky AexRateLimitError carrying the provider
862
- // fault, so callers can branch on `isRateLimited(err)` and replay.
863
- const throttle = throttleFromSession(sessionState, this.#debug);
864
- if (throttle) {
865
- throw new AexRateLimitError({
866
- status: throttle.status ?? 429,
867
- attempts: 1,
868
- source: "provider",
869
- providerFault: throttle,
870
- ...(throttle.retryAfterMs !== undefined ? { retryAfterMs: throttle.retryAfterMs } : {})
871
- });
872
- }
873
- throw new SessionStateError(`Aex.start: session ${sessionId} ended ${turnResult.status}${turnResult.error ? `: ${turnResult.error}` : ""}`, { sessionId, status: turnResult.status });
874
- }
875
- return result;
876
- }
877
- finally {
878
- scopedSignal?.clear();
879
- }
880
- }
881
- async #buildSessionCreateRequest(options) {
882
- if (!options || typeof options !== "object" || Array.isArray(options)) {
883
- throw configError("aex.sessions.create", "options", "options are required");
884
- }
885
- assertSupportedSessionFields(options, "aex.sessions.create", false);
886
- // Model is REQUIRED and validated as a gateway `creator/model` slug string.
887
- // This is a structural boundary gate only — a well-formed slug the gateway
888
- // catalog doesn't yet serve is allowed through (the server arbitrates), so a
889
- // slightly-old SDK can still run a newly-launched model.
890
- if (typeof options.model !== "string" || !options.model) {
891
- throw configError("aex.sessions.create", "model", "model is required");
892
- }
893
- const selectedModel = options.model;
894
- validatedSessionConfig("aex.sessions.create", "model", "model must be a gateway model slug of the form \"creator/model\"", () => parseModelSlug(selectedModel), { kind: "scalar", rejectedValues: [selectedModel] });
895
- // Fast client-side validation via the contract parsers (the SSoT). runtimeSize
896
- // and timeout are STABLE closed sets whose invalid values the create endpoint
897
- // otherwise SILENTLY defaults (no error ever — pre-launch edge-sweep F11/F12);
898
- // reject them synchronously with a typed error instead. webhook shape is
899
- // re-checked here for a fast local fail (the server enforces it too). Model is
900
- // deliberately NOT hard-rejected here to preserve forward-compat with models
901
- // added server-side before an SDK upgrade (an unknown model still fails on the
902
- // server).
903
- const runtimeSize = options.runtime?.size;
904
- validatedSessionConfig("aex.sessions.create", "runtime.size", "runtime.size must be a supported size preset", () => parseRuntimeSize(runtimeSize), { kind: "scalar", rejectedValues: [runtimeSize] });
905
- const runtimeKind = options.runtime?.kind;
906
- validatedSessionConfig("aex.sessions.create", "runtime.kind", "runtime.kind must be one of: container, spot_container, lambda", () => parseRuntimeKind(runtimeKind), { kind: "scalar", rejectedValues: [runtimeKind] });
907
- const sessionTimeout = options.overrides?.timeout;
908
- validatedSessionConfig("aex.sessions.create", "overrides.timeout", "overrides.timeout must be a supported duration", () => parseSessionTimeout(sessionTimeout), { kind: "scalar", rejectedValues: [sessionTimeout] });
909
- if (options.webhook !== undefined) {
910
- validatedSessionConfig("aex.sessions.create", "webhook.url", "webhook.url must be a valid HTTPS URL", () => parseSessionWebhook(options.webhook), { kind: "redacted" });
911
- }
912
- if (options.responseFormat !== undefined) {
913
- validatedSessionConfig("aex.sessions.create", "responseFormat", "responseFormat is invalid", () => parseResponseFormat(options.responseFormat), { kind: "redacted" });
914
- }
915
- if (options.approvalGate !== undefined) {
916
- validatedSessionConfig("aex.sessions.create", "approvalGate", "approvalGate is invalid", () => parseApprovalGate(options.approvalGate), { kind: "redacted" });
917
- }
918
- const splitEnvironmentSecrets = validatedSessionConfig("aex.sessions.create", "environment.secrets", "environment.secrets is invalid", () => splitSecretEnv(options.environment?.secrets), { kind: "redacted" });
919
- const secretEnvDeclarations = splitEnvironmentSecrets.declarations;
920
- const envSecretValues = splitEnvironmentSecrets.values;
921
- let limits;
922
- const limitsInput = {};
923
- if (options.overrides?.maxSpendUsd !== undefined) {
924
- const maxSpendUsd = options.overrides.maxSpendUsd;
925
- validatedSessionConfig("aex.sessions.create", "overrides.maxSpendUsd", "overrides.maxSpendUsd must be valid", () => parseSessionLimits({ maxSpendUsd }), { kind: "scalar", rejectedValues: [maxSpendUsd] });
926
- limitsInput.maxSpendUsd = maxSpendUsd;
927
- }
928
- if (options.overrides?.maxTurns !== undefined) {
929
- const maxTurns = options.overrides.maxTurns;
930
- validatedSessionConfig("aex.sessions.create", "overrides.maxTurns", "overrides.maxTurns must be valid", () => parseSessionLimits({ maxTurns }), { kind: "scalar", rejectedValues: [maxTurns] });
931
- limitsInput.maxTurns = maxTurns;
932
- }
933
- limits = parseSessionLimits(Object.keys(limitsInput).length > 0 ? limitsInput : undefined);
934
- const { submissionMcpServers, mergedMcpSecrets } = mergeMcpServers(options.mcpServers ?? [], []);
935
- const fileCapture = validatedSessionConfig("aex.sessions.create", "fileCapture", "fileCapture is invalid", () => fileCaptureForWire(options.fileCapture), { kind: "redacted" });
936
- const environment = validatedSessionConfig("aex.sessions.create", "environment", "environment is invalid", () => sessionEnvironmentForWire(options.environment), { kind: "redacted" });
937
- let builtinTools = options.builtinTools ?? "default";
938
- if (Array.isArray(builtinTools)) {
939
- const selectedBuiltinTools = builtinTools;
940
- builtinTools = validatedSessionConfig("aex.sessions.create", "builtinTools", "builtinTools contains an unsupported tool name", () => resolveBuiltinToolNames(selectedBuiltinTools), { kind: "scalar", rejectedValues: selectedBuiltinTools });
941
- }
942
- const submission = {
943
- model: options.model,
944
- ...(options.system ? { system: options.system } : {}),
945
- assets: {
946
- files: options.assets?.files ?? [],
947
- skills: options.assets?.skills ?? [],
948
- tools: options.assets?.tools ?? [],
949
- instructions: options.assets?.instructions ?? []
950
- },
951
- builtinTools,
952
- mcpServers: submissionMcpServers,
953
- ...(Object.keys(secretEnvDeclarations).length > 0 ? { secretEnv: secretEnvDeclarations } : {}),
954
- ...(environment ? { environment: environment } : {}),
955
- ...(options.metadata ? { metadata: options.metadata } : {}),
956
- ...(fileCapture ? { fileCapture } : {}),
957
- ...(options.outputMode !== undefined ? { outputMode: options.outputMode } : {}),
958
- ...(options.responseFormat !== undefined ? { responseFormat: options.responseFormat } : {}),
959
- ...(options.approvalGate !== undefined ? { approvalGate: options.approvalGate } : {})
960
- };
961
- const secrets = {
962
- ...(mergedMcpSecrets.length > 0 ? { mcpServers: mergedMcpSecrets } : {}),
963
- ...(Object.keys(envSecretValues).length > 0 ? { envSecrets: envSecretValues } : {})
964
- };
965
- const retention = sessionRetentionForWire(options);
966
- return {
967
- submission,
968
- ...(options.runtime?.size ? { runtimeSize: options.runtime.size } : {}),
969
- ...(options.runtime?.kind ? { runtimeKind: options.runtime.kind } : {}),
970
- ...(options.overrides?.timeout ? { timeout: options.overrides.timeout } : {}),
971
- ...(limits ? { limits } : {}),
972
- retention,
973
- // Operational/delivery concern — sibling of secrets, NOT part of the
974
- // hashed submission. Delivered at the committed RUN terminal.
975
- ...(options.webhook ? { webhook: options.webhook } : {}),
976
- secrets
977
- };
978
- }
979
- whoami() {
980
- return operations.whoami(this.#http);
981
- }
982
- /** Read prepaid balance, current-period allowances, recharge settings, and card state. */
983
- billing() {
984
- return operations.getBilling(this.#http);
985
- }
986
- /** Buy prepaid credit through hosted checkout; first use also saves the card. */
987
- billingTopup(request, options) {
988
- return operations.createBillingTopupCheckout(this.#http, request, options);
989
- }
990
- /** Set the separately consented, off-by-default auto-recharge authority. */
991
- billingAutoTopup(request) {
992
- return operations.updateBillingAutoTopup(this.#http, request);
993
- }
994
- /** Create a hosted billing-portal session. */
995
- billingPortal(request = {}, options) {
996
- return operations.createBillingPortal(this.#http, request, options);
997
- }
998
- /** Read recent signed credit-ledger rows, newest first. */
999
- billingLedger(query) {
1000
- return operations.getBillingLedger(this.#http, query);
1001
- }
1002
- /**
1003
- * Reveal the workspace webhook signing secret (creating one on first use) —
1004
- * the `whsec_<base64>` value `verifyAexWebhook` takes as `secret`. Backed by
1005
- * `POST /api/webhook/signing-secret`; repeat calls return the SAME value (the
1006
- * hosted API does not rotate it). Treat the reveal as sensitive: never log it.
1007
- */
1008
- webhookSigningSecret() {
1009
- return operations.getWebhookSigningSecret(this.#http);
1010
- }
1011
- }
1012
- /**
1013
- * Resolve the effective `baseUrl` from a self-describing API key (ZERO-network):
1014
- * - non-self-describing key: return the caller's `baseUrl`
1015
- * unchanged (HttpClient falls back to the prd default).
1016
- * - `baseUrl` omitted: DERIVE it from the key's plane.
1017
- * - `baseUrl` supplied but its plane DISAGREES with the key's plane: throw
1018
- * {@link CredentialValidationError} BEFORE any request.
1019
- */
1020
- function resolveBaseUrlForKey(apiKey, baseUrl) {
1021
- const parsed = tryParseApiKey(apiKey);
1022
- if (parsed === null)
1023
- return baseUrl;
1024
- const planeUrl = PLANE_BASE_URLS[parsed.plane];
1025
- if (baseUrl === undefined) {
1026
- return planeUrl;
1027
- }
1028
- const canonicalPlane = baseUrl === PLANE_BASE_URLS.dev ? "dev" : baseUrl === PLANE_BASE_URLS.prd ? "prd" : undefined;
1029
- if (canonicalPlane !== undefined && canonicalPlane !== parsed.plane) {
1030
- throw new CredentialValidationError(`Aex: this API key is for the ${parsed.plane} plane but baseUrl targets the ${canonicalPlane} plane (${baseUrl}) — ` +
1031
- `pass the ${parsed.plane} plane baseUrl, or omit baseUrl to auto-route.`, { plane: parsed.plane, baseUrl });
1032
- }
1033
- return baseUrl;
1034
- }
1035
- function scopedAbortSignal(timeoutMs) {
1036
- if (timeoutMs === undefined) {
1037
- return undefined;
1038
- }
1039
- const controller = new AbortController();
1040
- const timer = setTimeout(() => controller.abort(), Math.max(0, timeoutMs));
1041
- return {
1042
- signal: controller.signal,
1043
- clear() {
1044
- clearTimeout(timer);
1045
- }
1046
- };
1047
- }
1048
- async function writeOptionalFile(bytes, to) {
1049
- if (to !== undefined) {
1050
- const { writeFile } = await import("node:fs/promises");
1051
- await writeFile(to, bytes);
1052
- }
1053
- return bytes;
1054
- }
1055
- function sleep(ms, signal) {
1056
- return new Promise((resolve, reject) => {
1057
- if (signal?.aborted) {
1058
- reject(new Error("aborted"));
1059
- return;
1060
- }
1061
- const timer = setTimeout(() => {
1062
- signal?.removeEventListener("abort", onAbort);
1063
- resolve();
1064
- }, ms);
1065
- const onAbort = () => {
1066
- clearTimeout(timer);
1067
- reject(new Error("aborted"));
1068
- };
1069
- signal?.addEventListener("abort", onAbort, { once: true });
1070
- });
1071
- }
1072
- /**
1073
- * Extract a throttle-class {@link ProviderFault} from a failed session record.
1074
- * Reads the contract-owned structured field. Only when that field is absent,
1075
- * the narrow historical adapter may recognize an exact legacy terminal.
1076
- */
1077
- function throttleFromSession(session, debug) {
1078
- const fault = session.providerFault ?? legacySessionProviderFault(session, debug);
1079
- return fault && isThrottleFault(fault) ? fault : undefined;
1080
- }
1081
- export class WorkspaceFilesClient {
1082
- http;
1083
- publisher;
1084
- constructor(http, publisher) {
1085
- this.http = http;
1086
- this.publisher = publisher;
1087
- }
1088
- async publish(file) {
1089
- const bundle = file._takeDraftBundle();
1090
- const stream = file._takeDraftStream();
1091
- if (!bundle && !stream)
1092
- throw new Error("workspace.files.publish requires a draft File");
1093
- const uploaded = bundle
1094
- ? await this.publisher.upload({ bytes: bundle.bytes, hash: bundle.contentHash, contentType: "application/zip" })
1095
- : await this.publisher.uploadStream({ drive: stream.drive, contentType: "application/zip" });
1096
- return operations.publishWorkspaceFile(this.http, {
1097
- assetId: uploaded.assetId,
1098
- contentHash: uploaded.contentHash,
1099
- sizeBytes: uploaded.sizeBytes,
1100
- contentType: uploaded.contentType,
1101
- name: bundle?.name ?? stream.name,
1102
- mountPath: bundle?.mountPath ?? stream.mountPath
1103
- });
1104
- }
1105
- list(query) {
1106
- return operations.listWorkspaceFiles(this.http, query);
1107
- }
1108
- get(resourceId, version) { return operations.getWorkspaceFile(this.http, resourceId, version); }
1109
- delete(resourceId) { return operations.deleteWorkspaceFile(this.http, resourceId); }
1110
- }
1111
- export class WorkspaceSkillsClient {
1112
- http;
1113
- publisher;
1114
- constructor(http, publisher) {
1115
- this.http = http;
1116
- this.publisher = publisher;
1117
- }
1118
- async publish(skill) {
1119
- const bundle = skill._takeDraftBundle();
1120
- if (!bundle)
1121
- throw new Error("workspace.skills.publish requires a draft Skill");
1122
- const uploaded = await this.publisher.upload({ bytes: bundle.bytes, hash: bundle.contentHash, contentType: "application/zip" });
1123
- return operations.publishWorkspaceSkill(this.http, {
1124
- assetId: uploaded.assetId,
1125
- contentHash: uploaded.contentHash,
1126
- sizeBytes: uploaded.sizeBytes,
1127
- contentType: uploaded.contentType,
1128
- name: bundle.name,
1129
- description: bundle.description
1130
- });
1131
- }
1132
- list(query) {
1133
- return operations.listWorkspaceSkills(this.http, query);
1134
- }
1135
- get(resourceId, version) { return operations.getWorkspaceSkill(this.http, resourceId, version); }
1136
- delete(resourceId) { return operations.deleteWorkspaceSkill(this.http, resourceId); }
1137
- }
1138
- export class WorkspaceToolsClient {
1139
- http;
1140
- publisher;
1141
- constructor(http, publisher) {
1142
- this.http = http;
1143
- this.publisher = publisher;
1144
- }
1145
- async publish(tool) {
1146
- const bundle = tool._takeDraftBundle();
1147
- if (!bundle)
1148
- throw new Error("workspace.tools.publish requires a draft Tool");
1149
- const uploaded = await this.publisher.upload({ bytes: bundle.bytes, hash: bundle.contentHash, contentType: "application/zip" });
1150
- return operations.publishWorkspaceTool(this.http, {
1151
- assetId: uploaded.assetId,
1152
- contentHash: uploaded.contentHash,
1153
- sizeBytes: uploaded.sizeBytes,
1154
- contentType: uploaded.contentType,
1155
- name: bundle.ref.name,
1156
- description: bundle.ref.description,
1157
- input_schema: bundle.ref.input_schema,
1158
- entry: bundle.ref.entry
1159
- });
1160
- }
1161
- list(query) {
1162
- return operations.listWorkspaceTools(this.http, query);
1163
- }
1164
- get(resourceId, version) { return operations.getWorkspaceTool(this.http, resourceId, version); }
1165
- delete(resourceId) { return operations.deleteWorkspaceTool(this.http, resourceId); }
1166
- }
1167
- export class WorkspaceInstructionsClient {
1168
- http;
1169
- publisher;
1170
- constructor(http, publisher) {
1171
- this.http = http;
1172
- this.publisher = publisher;
1173
- }
1174
- async publish(instructions) {
1175
- const bundle = instructions._takeDraftBundle();
1176
- if (!bundle)
1177
- throw new Error("workspace.instructions.publish requires draft instructions");
1178
- const uploaded = await this.publisher.upload({ bytes: bundle.bytes, hash: bundle.contentHash, contentType: "application/zip" });
1179
- return operations.publishWorkspaceInstruction(this.http, {
1180
- assetId: uploaded.assetId,
1181
- contentHash: uploaded.contentHash,
1182
- sizeBytes: uploaded.sizeBytes,
1183
- contentType: uploaded.contentType,
1184
- name: bundle.name
1185
- });
1186
- }
1187
- list(query) {
1188
- return operations.listWorkspaceInstructions(this.http, query);
1189
- }
1190
- get(resourceId, version) { return operations.getWorkspaceInstruction(this.http, resourceId, version); }
1191
- delete(resourceId) { return operations.deleteWorkspaceInstruction(this.http, resourceId); }
1192
- }
1193
- export class WorkspaceClient {
1194
- files;
1195
- skills;
1196
- tools;
1197
- instructions;
1198
- secrets;
1199
- constructor(http, publisher) {
1200
- this.files = new WorkspaceFilesClient(http, publisher);
1201
- this.skills = new WorkspaceSkillsClient(http, publisher);
1202
- this.tools = new WorkspaceToolsClient(http, publisher);
1203
- this.instructions = new WorkspaceInstructionsClient(http, publisher);
1204
- this.secrets = new SecretsClient(http);
1205
- }
1206
- }
1207
- //# sourceMappingURL=client.js.map