@aexhq/sdk 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,17 +21,28 @@ bun add @aexhq/sdk
21
21
  ## First Run
22
22
 
23
23
  ```ts
24
- import { AgentExecutor, Models, Providers } from "@aexhq/sdk";
24
+ import { AgentExecutor, Models } from "@aexhq/sdk";
25
25
 
26
- const aex = new AgentExecutor({
27
- apiToken: process.env.AEX_API_TOKEN!
26
+ const aex = new AgentExecutor({ apiToken: process.env.AEX_API_TOKEN! });
27
+
28
+ // run() submits, waits for the run to settle, and returns the result —
29
+ // no manual poll loop. `provider` is derived from the model.
30
+ const { text, ok } = await aex.run({
31
+ model: Models.CLAUDE_HAIKU_4_5,
32
+ apiKey: process.env.ANTHROPIC_API_KEY!,
33
+ prompt: "Summarize this repo."
28
34
  });
29
35
 
36
+ console.log(ok, text);
37
+ ```
38
+
39
+ Need the run id, live events, or downloads? Use `submit` + `stream` + `wait`:
40
+
41
+ ```ts
30
42
  const runId = await aex.submit({
31
- provider: Providers.ANTHROPIC,
32
43
  model: Models.CLAUDE_HAIKU_4_5,
33
- prompt: "Write the report and save outputs.",
34
- secrets: { apiKey: process.env.ANTHROPIC_API_KEY! }
44
+ apiKey: process.env.ANTHROPIC_API_KEY!,
45
+ prompt: "Write the report and save outputs."
35
46
  });
36
47
 
37
48
  for await (const event of aex.stream(runId)) {
@@ -44,6 +55,17 @@ console.log(run.status);
44
55
  await aex.download(runId, { to: "./run.zip" });
45
56
  ```
46
57
 
58
+ For multiple providers (e.g. subagents on a different model family), pass a
59
+ `credentials` map instead of `apiKey`:
60
+
61
+ ```ts
62
+ await aex.run({
63
+ model: Models.CLAUDE_HAIKU_4_5,
64
+ credentials: { anthropic: process.env.ANTHROPIC_API_KEY!, openai: process.env.OPENAI_API_KEY! },
65
+ prompt: "Delegate research to a subagent."
66
+ });
67
+ ```
68
+
47
69
  The same request can run from the CLI:
48
70
 
49
71
  ```bash
@@ -55,6 +77,57 @@ aex run \
55
77
  --follow
56
78
  ```
57
79
 
80
+ ## CLI: login, discovery, typed errors
81
+
82
+ Stop re-passing `--api-token` on every command — log in once and the token (plus
83
+ your default `--aex-url`) is persisted to a `0600` config file
84
+ (`$XDG_CONFIG_HOME/aex/config.json` or `~/.config/aex/config.json`; `%APPDATA%\aex\config.json`
85
+ on Windows). An explicit `--api-token` flag always overrides the stored one.
86
+
87
+ ```bash
88
+ aex login --api-token "$AEX_API_TOKEN" [--aex-url https://api.aex.dev]
89
+ aex whoami # no --api-token needed after login
90
+ aex auth status # show the resolved config (the token value is never printed)
91
+ aex logout # clear the stored token
92
+ ```
93
+
94
+ Discover the closed sets the platform accepts — no token, no network (human table
95
+ by default, machine JSON under `--json`):
96
+
97
+ ```bash
98
+ aex models list # canonical models + their default provider
99
+ aex providers list # providers + the models each serves
100
+ aex tools list # builtin tools (default vs opt-in, e.g. notebook_edit)
101
+ aex runtime-sizes list # managed runtime presets (cpus / memory / default)
102
+ ```
103
+
104
+ Errors are typed and actionable. Every `submit()` config-validation failure throws
105
+ a `RunConfigValidationError` (`err.code === "RUN_CONFIG_INVALID"`) you can `catch`
106
+ by code; CLI failures print a JSON envelope carrying the HTTP `status`, a one-line
107
+ `remedy`, and the `runId` where known, and a wrong `--model`/`--provider`/
108
+ `--runtime-size`/`--region` gets a "did you mean?" suggestion.
109
+
110
+ ## Chat over a corpus of runs
111
+
112
+ Turn a selected set of runs into a read-only chat. `createCorpusTools(client, { runIds })`
113
+ returns vendor-neutral, corpus-scoped read tools (`list_runs` / `get_run` /
114
+ `list_outputs` / `read_output` / `search_outputs`) — every tool refuses a run
115
+ outside the corpus. Drive them with any LLM; `examples/chat-corpus.ts` shows the
116
+ direct-Claude loop (`@anthropic-ai/sdk`), and the CLI ships it as a one-shot
117
+ command (BYOK; the importable SDK stays LLM-vendor-free):
118
+
119
+ ```bash
120
+ aex chat --run run_<A> --run run_<B> \
121
+ --anthropic-api-key "$ANTHROPIC_API_KEY" \
122
+ --model claude-opus-4-8 \
123
+ --prompt "Across these runs, which produced a report.md and what's its headline finding?" \
124
+ --api-token "$AEX_API_TOKEN"
125
+ ```
126
+
127
+ `AgentExecutor.searchOutputs({ runIds, filename, extension, contentType, limit })`
128
+ finds output files across runs and returns references (no bytes) you then
129
+ `readOutputText`.
130
+
58
131
  ## Feature Areas
59
132
 
60
133
  - **Agent runtime:** managed autonomous runs with filesystem read/edit, grep/glob/head/tail, open web fetch/search defaults, optional notebook tools, and post-hook repair.
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Type-narrowing guards over the loose {@link RunEvent} `listEvents` shape.
3
+ *
4
+ * The envelope guards in `event-envelope.ts` operate on the coordinator
5
+ * {@link import("./event-envelope.js").AexEvent} and return a plain `boolean`.
6
+ * These mirror the same AG-UI discriminants but operate on the {@link RunEvent}
7
+ * snapshot shape returned by `listEvents` / `RunResult.events` and NARROW
8
+ * `event.data` to the fields that event type carries, so a consumer reads
9
+ * `event.data.text` (etc.) without a manual cast.
10
+ *
11
+ * They are DISCRIMINANT-only at runtime (they test `event.type`), matching the
12
+ * envelope guards: the narrowed `data` shape is a typing convenience, not a deep
13
+ * runtime validation. Parse/verify the payload fields before trusting them when
14
+ * the producer is untrusted.
15
+ *
16
+ * The parameter is the minimal `{ type }` discriminant both the {@link RunEvent}
17
+ * snapshot and the coordinator `AexEvent` envelope satisfy, so the guards accept
18
+ * either shape while narrowing to the {@link RunEvent}-typed payloads.
19
+ */
20
+ import type { RunEvent } from "./runtime-types.js";
21
+ /** A `TEXT_MESSAGE_CONTENT` run event with its assistant-text payload narrowed. */
22
+ export interface TextMessageRunEvent extends RunEvent {
23
+ readonly type: "TEXT_MESSAGE_CONTENT";
24
+ readonly data: {
25
+ readonly text: string;
26
+ readonly messageId?: string;
27
+ };
28
+ }
29
+ /** A `TOOL_CALL_START` run event with the tool-call id/name/args narrowed. */
30
+ export interface ToolCallStartRunEvent extends RunEvent {
31
+ readonly type: "TOOL_CALL_START";
32
+ readonly data: {
33
+ readonly id: string;
34
+ readonly name: string;
35
+ readonly arguments?: Record<string, unknown>;
36
+ };
37
+ }
38
+ /** A `TOOL_CALL_RESULT` run event with the correlating id + result narrowed. */
39
+ export interface ToolCallResultRunEvent extends RunEvent {
40
+ readonly type: "TOOL_CALL_RESULT";
41
+ readonly data: {
42
+ readonly id: string;
43
+ readonly content?: unknown;
44
+ readonly isError?: boolean;
45
+ };
46
+ }
47
+ /** A terminal `RUN_FINISHED` run event. */
48
+ export interface RunFinishedRunEvent extends RunEvent {
49
+ readonly type: "RUN_FINISHED";
50
+ readonly data: Record<string, unknown>;
51
+ }
52
+ /** True for an assistant text event; narrows `event.data.text` to `string`. */
53
+ export declare function isTextMessage(event: {
54
+ readonly type: string;
55
+ }): event is TextMessageRunEvent;
56
+ /** True for a tool-call start event; narrows `event.data` to `{ id, name }`. */
57
+ export declare function isToolCallStart(event: {
58
+ readonly type: string;
59
+ }): event is ToolCallStartRunEvent;
60
+ /** True for a tool-call result event; narrows `event.data` to `{ id, content }`. */
61
+ export declare function isToolCallResult(event: {
62
+ readonly type: string;
63
+ }): event is ToolCallResultRunEvent;
64
+ /** True for the terminal success event; narrows `event.data` to a record. */
65
+ export declare function isRunFinished(event: {
66
+ readonly type: string;
67
+ }): event is RunFinishedRunEvent;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Type-narrowing guards over the loose {@link RunEvent} `listEvents` shape.
3
+ *
4
+ * The envelope guards in `event-envelope.ts` operate on the coordinator
5
+ * {@link import("./event-envelope.js").AexEvent} and return a plain `boolean`.
6
+ * These mirror the same AG-UI discriminants but operate on the {@link RunEvent}
7
+ * snapshot shape returned by `listEvents` / `RunResult.events` and NARROW
8
+ * `event.data` to the fields that event type carries, so a consumer reads
9
+ * `event.data.text` (etc.) without a manual cast.
10
+ *
11
+ * They are DISCRIMINANT-only at runtime (they test `event.type`), matching the
12
+ * envelope guards: the narrowed `data` shape is a typing convenience, not a deep
13
+ * runtime validation. Parse/verify the payload fields before trusting them when
14
+ * the producer is untrusted.
15
+ *
16
+ * The parameter is the minimal `{ type }` discriminant both the {@link RunEvent}
17
+ * snapshot and the coordinator `AexEvent` envelope satisfy, so the guards accept
18
+ * either shape while narrowing to the {@link RunEvent}-typed payloads.
19
+ */
20
+ /** True for an assistant text event; narrows `event.data.text` to `string`. */
21
+ export function isTextMessage(event) {
22
+ return event.type === "TEXT_MESSAGE_CONTENT";
23
+ }
24
+ /** True for a tool-call start event; narrows `event.data` to `{ id, name }`. */
25
+ export function isToolCallStart(event) {
26
+ return event.type === "TOOL_CALL_START";
27
+ }
28
+ /** True for a tool-call result event; narrows `event.data` to `{ id, content }`. */
29
+ export function isToolCallResult(event) {
30
+ return event.type === "TOOL_CALL_RESULT";
31
+ }
32
+ /** True for the terminal success event; narrows `event.data` to a record. */
33
+ export function isRunFinished(event) {
34
+ return event.type === "RUN_FINISHED";
35
+ }
36
+ //# sourceMappingURL=event-guards.js.map
@@ -29,3 +29,5 @@ export * from "./run-artifacts.js";
29
29
  export * as operations from "./operations.js";
30
30
  export * from "./proxy-validation.js";
31
31
  export * from "./sse.js";
32
+ export { isRunFinished, isTextMessage, isToolCallResult, isToolCallStart } from "./event-guards.js";
33
+ export type { RunFinishedRunEvent, TextMessageRunEvent, ToolCallResultRunEvent, ToolCallStartRunEvent } from "./event-guards.js";
@@ -29,4 +29,10 @@ export * from "./run-artifacts.js";
29
29
  export * as operations from "./operations.js";
30
30
  export * from "./proxy-validation.js";
31
31
  export * from "./sse.js";
32
+ // Explicit re-export (shadows the same-named `AexEvent` guards from
33
+ // `event-envelope.js`): the public `is*` guards narrow the loose `RunEvent`
34
+ // snapshot shape `listEvents` returns. An `AexEvent` is assignable to `RunEvent`,
35
+ // so envelope consumers keep working; the envelope-typed guards stay reachable
36
+ // via the direct `event-envelope.js` module.
37
+ export { isRunFinished, isTextMessage, isToolCallResult, isToolCallStart } from "./event-guards.js";
32
38
  //# sourceMappingURL=index.js.map
@@ -96,6 +96,13 @@ export declare function decodeToolCalls(events: readonly TraceEvent[]): readonly
96
96
  * `totalTokens` is the sum of input + output tokens. Pure.
97
97
  */
98
98
  export declare function summarizeRunUsage(events: readonly TraceEvent[]): UsageSummary;
99
+ /**
100
+ * The run's final assistant text: every `TEXT_MESSAGE_CONTENT` block in stream
101
+ * order, concatenated. The one-line "what did the agent say" accessor over
102
+ * {@link decodeAssistantText} (buffered mode yields whole messages, stream mode
103
+ * yields token deltas — both concatenate correctly). Pure.
104
+ */
105
+ export declare function textOf(events: readonly TraceEvent[]): string;
99
106
  /** Decode the assistant text blocks (`TEXT_MESSAGE_CONTENT`) in stream order. Pure. */
100
107
  export declare function decodeAssistantText(events: readonly TraceEvent[]): readonly AssistantTextEntry[];
101
108
  /**
@@ -123,6 +123,15 @@ export function summarizeRunUsage(events) {
123
123
  totalTokens: totals.inputTokens + totals.outputTokens
124
124
  };
125
125
  }
126
+ /**
127
+ * The run's final assistant text: every `TEXT_MESSAGE_CONTENT` block in stream
128
+ * order, concatenated. The one-line "what did the agent say" accessor over
129
+ * {@link decodeAssistantText} (buffered mode yields whole messages, stream mode
130
+ * yields token deltas — both concatenate correctly). Pure.
131
+ */
132
+ export function textOf(events) {
133
+ return decodeAssistantText(events).map((entry) => entry.text).join("");
134
+ }
126
135
  /** Decode the assistant text blocks (`TEXT_MESSAGE_CONTENT`) in stream order. Pure. */
127
136
  export function decodeAssistantText(events) {
128
137
  const out = [];
@@ -79,6 +79,37 @@ export interface RunListPage {
79
79
  readonly runs: readonly RunSummary[];
80
80
  readonly nextCursor?: string;
81
81
  }
82
+ /**
83
+ * Cross-run output search query (`AgentExecutor.searchOutputs`). Restrict to a
84
+ * corpus with `runIds`; filter by filename substring / extension / content type.
85
+ * The MVP composes this client-side (per-run `listOutputs` + filter) — a future
86
+ * server-side `GET /api/outputs/search` can back the same contract with a real
87
+ * cross-run index, body-only swap.
88
+ */
89
+ export interface OutputSearchQuery {
90
+ /** Restrict the search to these runs (the chat corpus allow-list). */
91
+ readonly runIds?: readonly string[];
92
+ /** Case-insensitive substring match on the output filename. */
93
+ readonly filename?: string;
94
+ /** File extension, with or without a leading dot. Case-insensitive. */
95
+ readonly extension?: string;
96
+ /** Exact content type or a prefix wildcard such as `image/*`. */
97
+ readonly contentType?: string;
98
+ /** Cap the number of hits returned (default 100). */
99
+ readonly limit?: number;
100
+ }
101
+ /** One output-search hit — a reference only (no bytes); read with `readOutputText`. */
102
+ export interface OutputSearchHit {
103
+ readonly runId: string;
104
+ readonly outputId: string;
105
+ readonly filename?: string;
106
+ readonly sizeBytes?: number;
107
+ readonly contentType?: string;
108
+ }
109
+ /** A page of output-search hits. */
110
+ export interface OutputSearchPage {
111
+ readonly hits: readonly OutputSearchHit[];
112
+ }
82
113
  /**
83
114
  * A run event as recorded by the dashboard. Includes the `type` field
84
115
  * that the `is*Event` type guards narrow on plus any provider payload.
@@ -143,7 +143,7 @@ export declare const Providers: {
143
143
  * each region to co-located managed Postgres, object storage, run-state
144
144
  * placement, and sandbox backing.
145
145
  *
146
- * eu-west → London (Western Europe; hard EU data residency)
146
+ * eu-west → London (Western Europe)
147
147
  * us-west → N. California (Western North America)
148
148
  * ap-northeast → Seoul (Northeast Asia)
149
149
  *
@@ -154,7 +154,7 @@ export declare const REGIONS: readonly ["eu-west", "us-west", "ap-northeast"];
154
154
  export type Region = (typeof REGIONS)[number];
155
155
  /** Symbol-style accessors for the closed region set — e.g. `Regions.EU_WEST`. */
156
156
  export declare const Regions: {
157
- /** Western Europe — London. Hard EU data residency. */
157
+ /** Western Europe — London. */
158
158
  readonly EU_WEST: "eu-west";
159
159
  /** Western North America — N. California. */
160
160
  readonly US_WEST: "us-west";
@@ -324,6 +324,11 @@ export declare function requireString(input: unknown, field: string): string;
324
324
  export declare function optionalString(input: unknown, field: string): string | undefined;
325
325
  export declare function optionalEnum<const T extends readonly string[]>(input: unknown, field: string, allowed: T): T[number] | undefined;
326
326
  export declare function optionalPositiveInt(input: unknown, field: string): number | undefined;
327
+ /**
328
+ * A finite positive NUMBER (fractional allowed — e.g. a USD amount like `2.5`), or
329
+ * undefined when absent. Rejects non-numbers, NaN/Infinity, and `<= 0`.
330
+ */
331
+ export declare function optionalPositiveNumber(input: unknown, field: string): number | undefined;
327
332
  /**
328
333
  * Wire-level submission posted to /api/runs in the flat surface. The
329
334
  * `prompt` is always an array internally so the worker, the audit log,
@@ -517,6 +522,15 @@ export interface RunWebhookSpec {
517
522
  export interface RunLimits {
518
523
  readonly maxConcurrentChildRuns?: number;
519
524
  readonly maxSubagentDepth?: number;
525
+ /**
526
+ * Per-run spend cap in USD (defense-in-depth). The platform converts it to a
527
+ * wall-clock budget (priced compute is wall-time; BYOK provider tokens cost the
528
+ * platform nothing) and kills the run once it would out-spend the cap. A
529
+ * positive number; omitted ⇒ unbounded per-run (only the run's wall-clock
530
+ * `timeout` + the per-workspace spend cap apply). Only shape/positivity are
531
+ * validated here.
532
+ */
533
+ readonly maxSpendUsd?: number;
520
534
  }
521
535
  /**
522
536
  * Wire shape posted by the SDK and CLI. `workspaceId` is **omitted by
@@ -120,7 +120,7 @@ export const Providers = {
120
120
  * each region to co-located managed Postgres, object storage, run-state
121
121
  * placement, and sandbox backing.
122
122
  *
123
- * eu-west → London (Western Europe; hard EU data residency)
123
+ * eu-west → London (Western Europe)
124
124
  * us-west → N. California (Western North America)
125
125
  * ap-northeast → Seoul (Northeast Asia)
126
126
  *
@@ -130,7 +130,7 @@ export const Providers = {
130
130
  export const REGIONS = ["eu-west", "us-west", "ap-northeast"];
131
131
  /** Symbol-style accessors for the closed region set — e.g. `Regions.EU_WEST`. */
132
132
  export const Regions = {
133
- /** Western Europe — London. Hard EU data residency. */
133
+ /** Western Europe — London. */
134
134
  EU_WEST: "eu-west",
135
135
  /** Western North America — N. California. */
136
136
  US_WEST: "us-west",
@@ -997,6 +997,19 @@ export function optionalPositiveInt(input, field) {
997
997
  }
998
998
  return input;
999
999
  }
1000
+ /**
1001
+ * A finite positive NUMBER (fractional allowed — e.g. a USD amount like `2.5`), or
1002
+ * undefined when absent. Rejects non-numbers, NaN/Infinity, and `<= 0`.
1003
+ */
1004
+ export function optionalPositiveNumber(input, field) {
1005
+ if (input === undefined) {
1006
+ return undefined;
1007
+ }
1008
+ if (typeof input !== "number" || !Number.isFinite(input) || input <= 0) {
1009
+ throw new Error(`${field} must be a positive finite number`);
1010
+ }
1011
+ return input;
1012
+ }
1000
1013
  function parseOptionalBoundedInt(input, field, min, max) {
1001
1014
  if (input === undefined) {
1002
1015
  return undefined;
@@ -1198,7 +1211,7 @@ export function parseRunLimits(input) {
1198
1211
  return undefined;
1199
1212
  }
1200
1213
  const value = requireRecord(input, "limits");
1201
- const allowed = new Set(["maxConcurrentChildRuns", "maxSubagentDepth"]);
1214
+ const allowed = new Set(["maxConcurrentChildRuns", "maxSubagentDepth", "maxSpendUsd"]);
1202
1215
  for (const key of Object.keys(value)) {
1203
1216
  if (!allowed.has(key)) {
1204
1217
  throw new Error(`limits.${key} is not an allowed field; permitted: ${[...allowed].join(", ")}`);
@@ -1206,15 +1219,20 @@ export function parseRunLimits(input) {
1206
1219
  }
1207
1220
  const maxConcurrentChildRuns = optionalPositiveInt(value.maxConcurrentChildRuns, "limits.maxConcurrentChildRuns");
1208
1221
  const maxSubagentDepth = optionalPositiveInt(value.maxSubagentDepth, "limits.maxSubagentDepth");
1222
+ // maxSpendUsd is a USD amount (may be fractional, e.g. $2.50) so it is a positive
1223
+ // NUMBER, not a positive int. Clamping to the workspace/platform ceiling is the
1224
+ // resolver's job; here we only enforce shape + positivity.
1225
+ const maxSpendUsd = optionalPositiveNumber(value.maxSpendUsd, "limits.maxSpendUsd");
1209
1226
  // Collapse an all-absent override (e.g. `limits: {}`) to `undefined` so it never
1210
1227
  // lands an empty object on the request — matches sibling parsers (parseRunWebhook,
1211
1228
  // parseEnvironment). The resolver supplies platform defaults for absent fields.
1212
- if (maxConcurrentChildRuns === undefined && maxSubagentDepth === undefined) {
1229
+ if (maxConcurrentChildRuns === undefined && maxSubagentDepth === undefined && maxSpendUsd === undefined) {
1213
1230
  return undefined;
1214
1231
  }
1215
1232
  return {
1216
1233
  ...(maxConcurrentChildRuns !== undefined ? { maxConcurrentChildRuns } : {}),
1217
- ...(maxSubagentDepth !== undefined ? { maxSubagentDepth } : {})
1234
+ ...(maxSubagentDepth !== undefined ? { maxSubagentDepth } : {}),
1235
+ ...(maxSpendUsd !== undefined ? { maxSpendUsd } : {})
1218
1236
  };
1219
1237
  }
1220
1238
  export function parseRegion(input) {
@@ -15,7 +15,10 @@ export declare class AgentsMd {
15
15
  constructor(ref: AgentsMdRef | DraftAgentsMdRef, zipBytes?: Uint8Array);
16
16
  get ref(): AgentsMdRef | DraftAgentsMdRef;
17
17
  get isDraft(): boolean;
18
- get isConsumed(): boolean;
18
+ /** Internal: the asset id resolved on a prior submit, or undefined. */
19
+ get _cachedAssetId(): string | undefined;
20
+ /** Internal: remember the asset id resolved for this draft's bytes. */
21
+ _rememberAsset(assetId: string): void;
19
22
  /**
20
23
  * Build a draft AgentsMd from a markdown string. The SDK zips the
21
24
  * content under the canonical filename `AGENTS.md` so the hash is a
package/dist/agents-md.js CHANGED
@@ -15,7 +15,8 @@ import { strToU8, zipSync } from "fflate";
15
15
  export class AgentsMd {
16
16
  #ref;
17
17
  #zipBytes;
18
- #consumed = false;
18
+ /** Asset id cached after the first submit, so reuse skips a re-upload. */
19
+ #assetId;
19
20
  constructor(ref, zipBytes) {
20
21
  this.#ref = ref;
21
22
  this.#zipBytes = zipBytes;
@@ -24,10 +25,15 @@ export class AgentsMd {
24
25
  return this.#ref;
25
26
  }
26
27
  get isDraft() {
27
- return this.#ref.kind === "draft" && !this.#consumed;
28
+ return this.#ref.kind === "draft";
28
29
  }
29
- get isConsumed() {
30
- return this.#consumed;
30
+ /** Internal: the asset id resolved on a prior submit, or undefined. */
31
+ get _cachedAssetId() {
32
+ return this.#assetId;
33
+ }
34
+ /** Internal: remember the asset id resolved for this draft's bytes. */
35
+ _rememberAsset(assetId) {
36
+ this.#assetId = assetId;
31
37
  }
32
38
  /**
33
39
  * Build a draft AgentsMd from a markdown string. The SDK zips the
@@ -56,14 +62,9 @@ export class AgentsMd {
56
62
  * `client.submit` can upload it as an asset.
57
63
  */
58
64
  _takeDraftBundle() {
59
- if (this.#consumed) {
60
- throw new Error("AgentsMd: cannot reuse a consumed AgentsMd in submit. Build a fresh one " +
61
- "via AgentsMd.fromContent(...) / AgentsMd.fromPath(...) per submit call.");
62
- }
63
65
  if (this.#ref.kind !== "draft" || !this.#zipBytes) {
64
66
  return undefined;
65
67
  }
66
- this.#consumed = true;
67
68
  return {
68
69
  name: this.#ref.name,
69
70
  contentHash: this.#ref.contentHash,
@@ -1 +1 @@
1
- {"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../src/agents-md.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../src/agents-md.ts"],"names":[],"mappings":"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"}