@aexhq/sdk 0.19.0 → 0.20.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.
@@ -62,6 +62,14 @@ export declare const MODEL_PROVIDER_IDS: {
62
62
  readonly "mistral-small-latest": {
63
63
  readonly mistral: "mistral-small-latest";
64
64
  };
65
+ readonly "doubao-seed-pro": {
66
+ readonly doubao: "doubao-seed-1-8-251228";
67
+ readonly "doubao-cn": "doubao-seed-1-8-251228";
68
+ };
69
+ readonly "doubao-seed-flash": {
70
+ readonly doubao: "doubao-seed-1-6-flash-250828";
71
+ readonly "doubao-cn": "doubao-seed-1-6-flash-250828";
72
+ };
65
73
  };
66
74
  /**
67
75
  * Closed set of canonical model ids accepted by the public run-submission
@@ -116,6 +124,18 @@ export declare const Models: {
116
124
  readonly MISTRAL_LARGE_LATEST: "mistral-large-latest";
117
125
  /** Mistral Small (latest) — Mistral. */
118
126
  readonly MISTRAL_SMALL_LATEST: "mistral-small-latest";
127
+ /**
128
+ * Doubao Seed 1.8 — ByteDance, via the official Ark API. Default routes
129
+ * through the international BytePlus gateway (`Providers.DOUBAO`); pair with
130
+ * `Providers.DOUBAO_CN` for the China Volcengine gateway.
131
+ */
132
+ readonly DOUBAO_SEED_PRO: "doubao-seed-pro";
133
+ /**
134
+ * Doubao Seed 1.6 Flash — ByteDance, via the official Ark API (fast/cheap).
135
+ * Default `Providers.DOUBAO` (international); pair with `Providers.DOUBAO_CN`
136
+ * for China.
137
+ */
138
+ readonly DOUBAO_SEED_FLASH: "doubao-seed-flash";
119
139
  };
120
140
  /**
121
141
  * Back-compat alias for {@link Models}. Existing imports of `RunModels`
@@ -159,6 +179,18 @@ export declare const RunModels: {
159
179
  readonly MISTRAL_LARGE_LATEST: "mistral-large-latest";
160
180
  /** Mistral Small (latest) — Mistral. */
161
181
  readonly MISTRAL_SMALL_LATEST: "mistral-small-latest";
182
+ /**
183
+ * Doubao Seed 1.8 — ByteDance, via the official Ark API. Default routes
184
+ * through the international BytePlus gateway (`Providers.DOUBAO`); pair with
185
+ * `Providers.DOUBAO_CN` for the China Volcengine gateway.
186
+ */
187
+ readonly DOUBAO_SEED_PRO: "doubao-seed-pro";
188
+ /**
189
+ * Doubao Seed 1.6 Flash — ByteDance, via the official Ark API (fast/cheap).
190
+ * Default `Providers.DOUBAO` (international); pair with `Providers.DOUBAO_CN`
191
+ * for China.
192
+ */
193
+ readonly DOUBAO_SEED_FLASH: "doubao-seed-flash";
162
194
  };
163
195
  /**
164
196
  * Provider → canonical models that provider can serve. Derived from
@@ -30,7 +30,21 @@ export const MODEL_PROVIDER_IDS = {
30
30
  "gemini-2.0-flash": { gemini: "gemini-2.0-flash", openrouter: "google/gemini-2.0-flash-001" },
31
31
  "gemini-2.5-flash": { gemini: "gemini-2.5-flash" },
32
32
  "mistral-large-latest": { mistral: "mistral-large-latest" },
33
- "mistral-small-latest": { mistral: "mistral-small-latest" }
33
+ "mistral-small-latest": { mistral: "mistral-small-latest" },
34
+ // Doubao (ByteDance) via the official Ark API. Served by both the
35
+ // international BytePlus ModelArk gateway (`doubao`, the default) and the
36
+ // China Volcengine Ark gateway (`doubao-cn`). Ark accepts the API-format
37
+ // model NAME directly in the chat-completions `model` field (no `ep-…`
38
+ // inference-endpoint id). The native strings are the same Ark catalog ids on
39
+ // both gateways; BytePlus per-account availability is confirmed at live-verify
40
+ // (both providers ship `live-unverified` until then — provider-support.ts).
41
+ // pro — Doubao Seed 1.8 (flagship, 256K context).
42
+ // flash — Doubao Seed 1.6 Flash (fast/cheap, 256K context).
43
+ "doubao-seed-pro": { doubao: "doubao-seed-1-8-251228", "doubao-cn": "doubao-seed-1-8-251228" },
44
+ "doubao-seed-flash": {
45
+ doubao: "doubao-seed-1-6-flash-250828",
46
+ "doubao-cn": "doubao-seed-1-6-flash-250828"
47
+ }
34
48
  };
35
49
  export const RUN_MODELS = Object.keys(MODEL_PROVIDER_IDS);
36
50
  /**
@@ -79,7 +93,19 @@ export const Models = {
79
93
  /** Mistral Large (latest) — Mistral. */
80
94
  MISTRAL_LARGE_LATEST: "mistral-large-latest",
81
95
  /** Mistral Small (latest) — Mistral. */
82
- MISTRAL_SMALL_LATEST: "mistral-small-latest"
96
+ MISTRAL_SMALL_LATEST: "mistral-small-latest",
97
+ /**
98
+ * Doubao Seed 1.8 — ByteDance, via the official Ark API. Default routes
99
+ * through the international BytePlus gateway (`Providers.DOUBAO`); pair with
100
+ * `Providers.DOUBAO_CN` for the China Volcengine gateway.
101
+ */
102
+ DOUBAO_SEED_PRO: "doubao-seed-pro",
103
+ /**
104
+ * Doubao Seed 1.6 Flash — ByteDance, via the official Ark API (fast/cheap).
105
+ * Default `Providers.DOUBAO` (international); pair with `Providers.DOUBAO_CN`
106
+ * for China.
107
+ */
108
+ DOUBAO_SEED_FLASH: "doubao-seed-flash"
83
109
  };
84
110
  /**
85
111
  * Back-compat alias for {@link Models}. Existing imports of `RunModels`
@@ -1,6 +1,6 @@
1
1
  import type { HttpClient } from "./http.js";
2
2
  import type { RunUnit } from "./run-unit.js";
3
- import type { AgentsMdRecord, FileRecord, Output, OutputFileDownload, OutputFileSelector, Run, RunEvent, SignedOutputLink, Skill, WhoAmI } from "./runtime-types.js";
3
+ import type { AgentsMdRecord, FileRecord, Output, OutputFileDownload, OutputFileSelector, Run, RunEvent, SecretRecord, SecretReveal, SignedOutputLink, Skill, WhoAmI } from "./runtime-types.js";
4
4
  import type { PlatformRunSubmissionInput } from "./submission.js";
5
5
  /**
6
6
  * The single source of truth for SDK<->BFF transport. The SDK class
@@ -207,6 +207,22 @@ export declare function createFile(http: HttpClient, args: {
207
207
  export declare function listFiles(http: HttpClient): Promise<readonly FileRecord[]>;
208
208
  export declare function getFile(http: HttpClient, fileId: string): Promise<FileRecord>;
209
209
  export declare function deleteFile(http: HttpClient, fileId: string): Promise<void>;
210
+ /** Create a named workspace secret. The value travels in the body. */
211
+ export declare function createSecret(http: HttpClient, args: {
212
+ readonly name: string;
213
+ readonly value: string;
214
+ }): Promise<SecretRecord>;
215
+ export declare function listSecrets(http: HttpClient): Promise<readonly SecretRecord[]>;
216
+ /** Metadata for one workspace secret by name. Never returns the value. */
217
+ export declare function getSecret(http: HttpClient, name: string): Promise<SecretRecord>;
218
+ /** Audited value read — the only path that returns a workspace secret value. */
219
+ export declare function revealSecret(http: HttpClient, name: string): Promise<SecretReveal>;
220
+ /** Replace the value of an existing workspace secret; bumps its version. */
221
+ export declare function rotateSecret(http: HttpClient, args: {
222
+ readonly name: string;
223
+ readonly value: string;
224
+ }): Promise<SecretRecord>;
225
+ export declare function deleteSecret(http: HttpClient, name: string): Promise<void>;
210
226
  export interface AssetUploadResult {
211
227
  readonly assetId: string;
212
228
  readonly contentHash: string;
@@ -541,6 +541,56 @@ function unwrapFile(result) {
541
541
  }
542
542
  return result;
543
543
  }
544
+ // ===========================================================================
545
+ // Workspace secret operations
546
+ //
547
+ // Value-bearing requests (create/rotate) carry the value in the JSON BODY,
548
+ // never the URL/query, so it never lands in logs or the request line. Reads
549
+ // split by sensitivity: `getSecret`/`listSecrets` return METADATA only;
550
+ // `revealSecret` is the audited value read (POST so it's a logged action).
551
+ // ===========================================================================
552
+ /** Create a named workspace secret. The value travels in the body. */
553
+ export async function createSecret(http, args) {
554
+ const result = await http.request("/api/secrets", {
555
+ method: "POST",
556
+ body: JSON.stringify({ name: args.name, value: args.value })
557
+ });
558
+ return unwrapSecret(result);
559
+ }
560
+ export async function listSecrets(http) {
561
+ const result = await http.request("/api/secrets");
562
+ if (Array.isArray(result)) {
563
+ return result;
564
+ }
565
+ return result.secrets;
566
+ }
567
+ /** Metadata for one workspace secret by name. Never returns the value. */
568
+ export async function getSecret(http, name) {
569
+ const result = await http.request(`/api/secrets/${encodeURIComponent(name)}`);
570
+ return unwrapSecret(result);
571
+ }
572
+ /** Audited value read — the only path that returns a workspace secret value. */
573
+ export async function revealSecret(http, name) {
574
+ return http.request(`/api/secrets/${encodeURIComponent(name)}/reveal`, {
575
+ method: "POST"
576
+ });
577
+ }
578
+ /** Replace the value of an existing workspace secret; bumps its version. */
579
+ export async function rotateSecret(http, args) {
580
+ const result = await http.request(`/api/secrets/${encodeURIComponent(args.name)}/rotate`, { method: "POST", body: JSON.stringify({ value: args.value }) });
581
+ return unwrapSecret(result);
582
+ }
583
+ export async function deleteSecret(http, name) {
584
+ await http.request(`/api/secrets/${encodeURIComponent(name)}`, {
585
+ method: "DELETE"
586
+ });
587
+ }
588
+ function unwrapSecret(result) {
589
+ if (result && typeof result === "object" && "secret" in result) {
590
+ return result.secret;
591
+ }
592
+ return result;
593
+ }
544
594
  function unwrapSkill(result) {
545
595
  if (result && typeof result === "object" && "skill" in result) {
546
596
  return result.skill;
@@ -256,5 +256,73 @@ export declare const PROVIDER_PUBLIC_SUPPORT: {
256
256
  }];
257
257
  };
258
258
  };
259
+ readonly doubao: {
260
+ readonly displayName: "Doubao";
261
+ readonly status: "live-unverified";
262
+ readonly docsAnchor: "doubao";
263
+ readonly docs: readonly [{
264
+ readonly label: "Credentials";
265
+ readonly href: "credentials.md";
266
+ }, {
267
+ readonly label: "Events";
268
+ readonly href: "events.md";
269
+ }];
270
+ readonly evidence: readonly [{
271
+ readonly label: "Submission parser and routing parity";
272
+ readonly href: "../../contracts/test/submission.test.ts";
273
+ }, {
274
+ readonly label: "Runtime support validator";
275
+ readonly href: "../../contracts/test/runtime-support.test.ts";
276
+ }, {
277
+ readonly label: "Generated matrix freshness";
278
+ readonly href: "../../../scripts/validate/capability-matrix.test.ts";
279
+ }];
280
+ readonly runtimeEvidence: {
281
+ readonly managed: readonly [{
282
+ readonly label: "Submission parser and routing parity";
283
+ readonly href: "../../contracts/test/submission.test.ts";
284
+ }, {
285
+ readonly label: "Runtime support validator";
286
+ readonly href: "../../contracts/test/runtime-support.test.ts";
287
+ }, {
288
+ readonly label: "Generated matrix freshness";
289
+ readonly href: "../../../scripts/validate/capability-matrix.test.ts";
290
+ }];
291
+ };
292
+ };
293
+ readonly "doubao-cn": {
294
+ readonly displayName: "Doubao (China)";
295
+ readonly status: "live-unverified";
296
+ readonly docsAnchor: "doubao-cn";
297
+ readonly docs: readonly [{
298
+ readonly label: "Credentials";
299
+ readonly href: "credentials.md";
300
+ }, {
301
+ readonly label: "Events";
302
+ readonly href: "events.md";
303
+ }];
304
+ readonly evidence: readonly [{
305
+ readonly label: "Submission parser and routing parity";
306
+ readonly href: "../../contracts/test/submission.test.ts";
307
+ }, {
308
+ readonly label: "Runtime support validator";
309
+ readonly href: "../../contracts/test/runtime-support.test.ts";
310
+ }, {
311
+ readonly label: "Generated matrix freshness";
312
+ readonly href: "../../../scripts/validate/capability-matrix.test.ts";
313
+ }];
314
+ readonly runtimeEvidence: {
315
+ readonly managed: readonly [{
316
+ readonly label: "Submission parser and routing parity";
317
+ readonly href: "../../contracts/test/submission.test.ts";
318
+ }, {
319
+ readonly label: "Runtime support validator";
320
+ readonly href: "../../contracts/test/runtime-support.test.ts";
321
+ }, {
322
+ readonly label: "Generated matrix freshness";
323
+ readonly href: "../../../scripts/validate/capability-matrix.test.ts";
324
+ }];
325
+ };
326
+ };
259
327
  };
260
328
  export declare function providerPublicSupport(provider: RunProvider): ProviderPublicSupport;
@@ -109,6 +109,34 @@ export const PROVIDER_PUBLIC_SUPPORT = {
109
109
  runtimeEvidence: {
110
110
  managed: COMMON_EVIDENCE
111
111
  }
112
+ },
113
+ // Doubao (ByteDance) via the official Ark API — international BytePlus gateway.
114
+ // Wired + parser/routing-verified but not yet proven against a live BytePlus
115
+ // account, so `live-unverified`. Promote to `supported` (and swap COMMON_EVIDENCE
116
+ // for a DOUBAO_MANAGED_EVIDENCE pointer to live-sdk-doubao.test.ts) once the
117
+ // live run passes.
118
+ doubao: {
119
+ displayName: "Doubao",
120
+ status: "live-unverified",
121
+ docsAnchor: "doubao",
122
+ docs: COMMON_DOCS,
123
+ evidence: COMMON_EVIDENCE,
124
+ runtimeEvidence: {
125
+ managed: COMMON_EVIDENCE
126
+ }
127
+ },
128
+ // Doubao (ByteDance) via the official Ark API — China Volcengine gateway.
129
+ // Same wiring as `doubao`; additionally gated on CF Worker egress reaching the
130
+ // Beijing host (see apps/egress-probe). `live-unverified` until proven live.
131
+ "doubao-cn": {
132
+ displayName: "Doubao (China)",
133
+ status: "live-unverified",
134
+ docsAnchor: "doubao-cn",
135
+ docs: COMMON_DOCS,
136
+ evidence: COMMON_EVIDENCE,
137
+ runtimeEvidence: {
138
+ managed: COMMON_EVIDENCE
139
+ }
112
140
  }
113
141
  };
114
142
  export function providerPublicSupport(provider) {
@@ -92,6 +92,21 @@ export interface RunCostManagedKeyBudgetTelemetry {
92
92
  readonly chargedCreditUnits?: number;
93
93
  readonly releasedCreditUnits?: number;
94
94
  }
95
+ /**
96
+ * The basis for a {@link RunCostTelemetry.billedCostUsd}: an honest marker of
97
+ * whether the figure is a settle-time ESTIMATE or has been RECONCILED against
98
+ * authoritative actuals. Deliberately carries NO rate-card version or unit
99
+ * rates — the platform's public-safe convention treats `rateCard`/`margin` as
100
+ * private tokens (run-cost.test.ts privateCostFieldPattern), so the version the
101
+ * figure was derived under stays internal (recorded only in the platform's
102
+ * internal raw-usage export).
103
+ */
104
+ export declare const RUN_COST_BASIS_STATUSES: readonly ["estimated", "reconciled"];
105
+ export type RunCostBasisStatus = (typeof RUN_COST_BASIS_STATUSES)[number];
106
+ export interface RunCostBasis {
107
+ readonly currency: "USD";
108
+ readonly status: RunCostBasisStatus;
109
+ }
95
110
  export interface RunCostTelemetry {
96
111
  readonly schemaVersion: typeof RUN_COST_TELEMETRY_SCHEMA_VERSION;
97
112
  readonly runId?: string;
@@ -108,6 +123,18 @@ export interface RunCostTelemetry {
108
123
  readonly storage?: RunCostStorageTelemetry;
109
124
  readonly proxy?: RunCostProxyTelemetry;
110
125
  readonly managedKey?: RunCostManagedKeyBudgetTelemetry;
126
+ /**
127
+ * Customer-facing AEX cost of serving this run, USD — a REPORTED ESTIMATE,
128
+ * not a charge (telemetry/showback only; no invoicing or credit deduction).
129
+ * = rawCostUsd × marginMultiplier (margin currently a global 1.0). EXCLUDES
130
+ * the customer's BYOK provider spend. The raw (pre-margin) figure is kept
131
+ * internal and never appears on this public-safe shape. A plain number, so it
132
+ * passes the run-record public-safe archive scan. Absent when the run incurred
133
+ * no priced AEX usage.
134
+ */
135
+ readonly billedCostUsd?: number;
136
+ /** Currency + estimate/reconciled basis for {@link billedCostUsd}. */
137
+ readonly costBasis?: RunCostBasis;
111
138
  }
112
139
  export type RunCostTelemetryInput = Omit<RunCostTelemetry, "schemaVersion">;
113
140
  export interface RunCostTelemetryFromUsageSamplesInput {
@@ -96,6 +96,16 @@ const RUN_USAGE_SAMPLE_METRIC_UNITS = {
96
96
  "managed_key.charged_credit_units": "credit_unit",
97
97
  "managed_key.released_credit_units": "credit_unit"
98
98
  };
99
+ /**
100
+ * The basis for a {@link RunCostTelemetry.billedCostUsd}: an honest marker of
101
+ * whether the figure is a settle-time ESTIMATE or has been RECONCILED against
102
+ * authoritative actuals. Deliberately carries NO rate-card version or unit
103
+ * rates — the platform's public-safe convention treats `rateCard`/`margin` as
104
+ * private tokens (run-cost.test.ts privateCostFieldPattern), so the version the
105
+ * figure was derived under stays internal (recorded only in the platform's
106
+ * internal raw-usage export).
107
+ */
108
+ export const RUN_COST_BASIS_STATUSES = ["estimated", "reconciled"];
99
109
  export function buildRunUsageSample(input) {
100
110
  const metric = normalizeUsageSampleMetric(input.metric);
101
111
  const expectedUnit = RUN_USAGE_SAMPLE_METRIC_UNITS[metric];
@@ -134,7 +144,9 @@ export function buildRunCostTelemetry(input) {
134
144
  ...(input.providerUsage ? { providerUsage: input.providerUsage.map(normalizeProviderUsage) } : {}),
135
145
  ...(input.storage ? { storage: normalizeStorage(input.storage) } : {}),
136
146
  ...(input.proxy ? { proxy: normalizeProxy(input.proxy) } : {}),
137
- ...(input.managedKey ? { managedKey: normalizeManagedKey(input.managedKey) } : {})
147
+ ...(input.managedKey ? { managedKey: normalizeManagedKey(input.managedKey) } : {}),
148
+ ...(input.billedCostUsd !== undefined ? { billedCostUsd: nonNegativeFinite(input.billedCostUsd, "billedCostUsd") } : {}),
149
+ ...(input.costBasis ? { costBasis: normalizeCostBasis(input.costBasis) } : {})
138
150
  });
139
151
  }
140
152
  export function buildRunCostTelemetryFromUsageSamples(input) {
@@ -318,6 +330,11 @@ export function mergeRunCostTelemetry(base, next) {
318
330
  const storage = sumStorage(base.storage, patch.storage);
319
331
  const proxy = sumProxy(base.proxy, patch.proxy);
320
332
  const managedKey = mergeManagedKey(base.managedKey, patch.managedKey);
333
+ // Derived cost fields are LAST-WRITER-WINS (a re-derivation supersedes the
334
+ // prior estimate), not summed — they are projections of the whole sample set,
335
+ // not additive metrics.
336
+ const billedCostUsd = patch.billedCostUsd ?? base.billedCostUsd;
337
+ const costBasis = patch.costBasis ?? base.costBasis;
321
338
  if (runId)
322
339
  merged.runId = runId;
323
340
  if (provider)
@@ -346,6 +363,10 @@ export function mergeRunCostTelemetry(base, next) {
346
363
  merged.proxy = proxy;
347
364
  if (managedKey)
348
365
  merged.managedKey = managedKey;
366
+ if (billedCostUsd !== undefined)
367
+ merged.billedCostUsd = billedCostUsd;
368
+ if (costBasis)
369
+ merged.costBasis = costBasis;
349
370
  return buildRunCostTelemetry(merged);
350
371
  }
351
372
  function normalizeDurations(input) {
@@ -470,6 +491,18 @@ function normalizeSummaryStatus(input) {
470
491
  }
471
492
  return input;
472
493
  }
494
+ function normalizeCostBasis(input) {
495
+ if (!input || typeof input !== "object") {
496
+ throw new Error("run cost basis must be an object");
497
+ }
498
+ if (input.currency !== "USD") {
499
+ throw new Error(`run cost basis currency ${String(input.currency)} is not supported`);
500
+ }
501
+ if (!isStringIn(input.status, RUN_COST_BASIS_STATUSES)) {
502
+ throw new Error(`run cost basis status ${String(input.status)} is not supported`);
503
+ }
504
+ return Object.freeze({ currency: "USD", status: input.status });
505
+ }
473
506
  function addProviderUsage(usageByKey, input, sample, field) {
474
507
  const provider = sample.provider ?? input.provider;
475
508
  if (!provider) {
@@ -210,3 +210,35 @@ export interface FileRecord {
210
210
  readonly deletedAt?: string | null;
211
211
  readonly [key: string]: unknown;
212
212
  }
213
+ /**
214
+ * Wire-level record for a workspace secret as returned by the BFF.
215
+ *
216
+ * Workspace secrets share the lifecycle SEMANTIC of skills/files: a
217
+ * `Secret.value(...)` is per-run and gone at terminal; PROMOTING it (or
218
+ * `aex.secrets.set`) persists a named, searchable workspace secret. The
219
+ * identity is the `name` (the handle a `Secret.ref` points at); the value
220
+ * rotates under that stable name, bumping `version`.
221
+ *
222
+ * This record is METADATA ONLY — it never carries the secret value. The value
223
+ * is write-only on create/rotate and readable solely via the audited
224
+ * {@link SecretReveal} path.
225
+ */
226
+ export interface SecretRecord {
227
+ readonly id: string;
228
+ readonly name: string;
229
+ readonly version: number;
230
+ readonly state: "ready";
231
+ readonly createdAt?: string;
232
+ readonly updatedAt?: string;
233
+ readonly deletedAt?: string | null;
234
+ readonly [key: string]: unknown;
235
+ }
236
+ /**
237
+ * Value-bearing result of an audited `aex.secrets.reveal`. The ONLY wire shape
238
+ * that carries a workspace secret value back to the caller. Reveal is a logged
239
+ * action (POST, not GET) so a value read is always attributable.
240
+ */
241
+ export interface SecretReveal {
242
+ readonly name: string;
243
+ readonly value: string;
244
+ }
@@ -105,7 +105,7 @@ export declare function packageInstallString(pkg: PlatformPackage): string;
105
105
  * runtime; provider selection only decides which upstream model route
106
106
  * the managed provider-proxy uses.
107
107
  */
108
- export declare const RUN_PROVIDERS: readonly ["anthropic", "deepseek", "openai", "gemini", "mistral", "openrouter"];
108
+ export declare const RUN_PROVIDERS: readonly ["anthropic", "deepseek", "openai", "gemini", "mistral", "openrouter", "doubao", "doubao-cn"];
109
109
  export type RunProvider = (typeof RUN_PROVIDERS)[number];
110
110
  export declare const DEFAULT_RUN_PROVIDER: RunProvider;
111
111
  /**
@@ -133,6 +133,10 @@ export declare const Providers: {
133
133
  readonly MISTRAL: "mistral";
134
134
  /** OpenRouter — OpenAI-compatible aggregator routing to many upstream models. */
135
135
  readonly OPENROUTER: "openrouter";
136
+ /** Doubao (ByteDance) via the official international BytePlus ModelArk gateway. */
137
+ readonly DOUBAO: "doubao";
138
+ /** Doubao (ByteDance) via the official China Volcengine Ark gateway. */
139
+ readonly DOUBAO_CN: "doubao-cn";
136
140
  };
137
141
  /**
138
142
  * Customer-facing runtime selector. Optional on the wire; absent resolves
@@ -194,6 +198,15 @@ export interface PlatformInlineSecrets {
194
198
  readonly apiKey?: string;
195
199
  readonly mcpServers?: readonly PlatformMcpServerSecret[];
196
200
  readonly proxyEndpointAuth?: readonly PlatformProxyEndpointAuth[];
201
+ /**
202
+ * Per-run env-var secret VALUES, keyed by env name. Each entry pairs with a
203
+ * `submission.secretEnv[<envName>] = { ephemeral: true }` declaration. Lives
204
+ * in the secrets channel so it is vaulted and excluded from the idempotency
205
+ * hash; the runtime injects it as the named env var and it is deleted at the
206
+ * run's terminal. Workspace `{ ref }` bindings resolve server-side and never
207
+ * appear here.
208
+ */
209
+ readonly envSecrets?: Readonly<Record<string, string>>;
197
210
  }
198
211
  /**
199
212
  * Per-run named HTTP proxy endpoint. The `authShape` describes how the
@@ -219,6 +232,21 @@ export interface PlatformProxyEndpoint {
219
232
  readonly retry?: ProxyRetryPolicy;
220
233
  }
221
234
  export declare const SECRETS_KEY = "secrets";
235
+ /** POSIX-style env var name a `secretEnv` entry binds to (e.g. `SERPER_API_KEY`). */
236
+ export declare const SECRET_ENV_NAME_PATTERN: RegExp;
237
+ /** Workspace secret handle a `secretEnv` ref points at (and the name `secret.upload` persists to). */
238
+ export declare const SECRET_HANDLE_PATTERN: RegExp;
239
+ /**
240
+ * One `submission.secretEnv` entry — VALUE-FREE, so it rides the (hashed)
241
+ * submission safely. `{ ref }` resolves a workspace secret server-side;
242
+ * `{ ephemeral: true }` pairs with a `secrets.envSecrets[<envName>]` value
243
+ * (per-run, vaulted, deleted at the run's terminal).
244
+ */
245
+ export type PlatformSecretEnvEntry = {
246
+ readonly ref: string;
247
+ } | {
248
+ readonly ephemeral: true;
249
+ };
222
250
  export declare const PROXY_ENDPOINT_NAME_PATTERN: RegExp;
223
251
  export declare const RESERVED_PROXY_ENDPOINT_NAMES: Set<string>;
224
252
  export declare const deniedSecretFields: Set<string>;
@@ -228,6 +256,16 @@ export declare function parseProxyMethods(input: unknown, field: string): readon
228
256
  export declare function parseProxyPathPrefixes(input: unknown, field: string): readonly string[];
229
257
  export declare function parseProxyAllowedHeaders(input: unknown, field: string, authShape: ProxyAuthShape): readonly string[] | undefined;
230
258
  export declare function crossValidateProxyEndpointsAndAuth(endpoints: readonly PlatformProxyEndpoint[] | undefined, auth: readonly PlatformProxyEndpointAuth[] | undefined): void;
259
+ /**
260
+ * Cross-check `submission.secretEnv` declarations against `secrets.envSecrets`
261
+ * values. Mirrors {@link crossValidateProxyEndpointsAndAuth}:
262
+ *
263
+ * - `{ ephemeral: true }` MUST have a matching `secrets.envSecrets` value.
264
+ * - `{ ref }` MUST NOT supply a value (the value lives in the workspace store).
265
+ * - every `secrets.envSecrets` value MUST have a matching `{ ephemeral: true }`
266
+ * declaration (no orphan values that would never be injected).
267
+ */
268
+ export declare function crossValidateSecretEnvAndValues(secretEnv: Readonly<Record<string, PlatformSecretEnvEntry>> | undefined, envSecrets: Readonly<Record<string, string>> | undefined): void;
231
269
  export declare function parseInlineSecrets(input: unknown): PlatformInlineSecrets;
232
270
  /**
233
271
  * The proxy body-redactor refuses to mask any derived target string shorter
@@ -263,6 +301,15 @@ export interface PlatformSubmission {
263
301
  readonly agentsMd: readonly AgentsMdRef[];
264
302
  readonly files: readonly FileRef[];
265
303
  readonly mcpServers: readonly McpServerRef[];
304
+ /**
305
+ * Env-var secret bindings — VALUE-FREE declarations keyed by env name. Each
306
+ * value is `{ ref }` (resolve a workspace secret server-side) or
307
+ * `{ ephemeral: true }` (value supplied in `secrets.envSecrets`, vaulted and
308
+ * deleted at terminal). The runtime injects the resolved value as the named
309
+ * env var. Lifecycle parity with skills/files: per-run by default, persisted
310
+ * only when promoted to the workspace store.
311
+ */
312
+ readonly secretEnv?: Readonly<Record<string, PlatformSecretEnvEntry>>;
266
313
  readonly environment?: PlatformEnvironment;
267
314
  readonly securityProfile?: RuntimeSecurityProfileName;
268
315
  readonly metadata?: Record<string, JsonValue>;
@@ -369,6 +416,15 @@ export interface PlatformRunSubmissionRequest {
369
416
  * for repair until this budget is exhausted.
370
417
  */
371
418
  readonly postHook?: PlatformPostHook;
419
+ /**
420
+ * Lineage parent (agent-session §9). When present the server admits this
421
+ * run as a CHILD of `parentRunId`: it walks the parent's lineage, enforces
422
+ * the max-subagent-depth + per-root concurrency caps, and persists
423
+ * `parent_run_id` + a server-derived `depth`. The client may name a parent
424
+ * but NEVER the depth — depth is computed server-side from the parent row,
425
+ * so a forged value cannot bypass the cap.
426
+ */
427
+ readonly parentRunId?: string;
372
428
  }
373
429
  /**
374
430
  * Wire shape posted by the SDK and CLI. `workspaceId` is **omitted by