@aexhq/sdk 0.19.0 → 0.21.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/dist/_contracts/models.d.ts +32 -0
- package/dist/_contracts/models.js +28 -2
- package/dist/_contracts/operations.d.ts +17 -1
- package/dist/_contracts/operations.js +50 -0
- package/dist/_contracts/provider-support.d.ts +68 -0
- package/dist/_contracts/provider-support.js +28 -0
- package/dist/_contracts/run-cost.d.ts +27 -0
- package/dist/_contracts/run-cost.js +34 -1
- package/dist/_contracts/run-custody.js +94 -3
- package/dist/_contracts/runtime-types.d.ts +32 -0
- package/dist/_contracts/submission.d.ts +57 -1
- package/dist/_contracts/submission.js +103 -4
- package/dist/cli.mjs +165 -5
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +79 -1
- package/dist/client.js +80 -2
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/secret.d.ts +102 -0
- package/dist/secret.js +148 -0
- package/dist/secret.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/provider-runtime-capabilities.md +23 -1
- package/package.json +2 -2
|
@@ -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
|
|
@@ -80,7 +80,9 @@ export const RUN_PROVIDERS = [
|
|
|
80
80
|
"openai",
|
|
81
81
|
"gemini",
|
|
82
82
|
"mistral",
|
|
83
|
-
"openrouter"
|
|
83
|
+
"openrouter",
|
|
84
|
+
"doubao",
|
|
85
|
+
"doubao-cn"
|
|
84
86
|
];
|
|
85
87
|
export const DEFAULT_RUN_PROVIDER = "anthropic";
|
|
86
88
|
/**
|
|
@@ -107,7 +109,11 @@ export const Providers = {
|
|
|
107
109
|
/** Mistral. */
|
|
108
110
|
MISTRAL: "mistral",
|
|
109
111
|
/** OpenRouter — OpenAI-compatible aggregator routing to many upstream models. */
|
|
110
|
-
OPENROUTER: "openrouter"
|
|
112
|
+
OPENROUTER: "openrouter",
|
|
113
|
+
/** Doubao (ByteDance) via the official international BytePlus ModelArk gateway. */
|
|
114
|
+
DOUBAO: "doubao",
|
|
115
|
+
/** Doubao (ByteDance) via the official China Volcengine Ark gateway. */
|
|
116
|
+
DOUBAO_CN: "doubao-cn"
|
|
111
117
|
};
|
|
112
118
|
/**
|
|
113
119
|
* Customer-facing runtime selector. Optional on the wire; absent resolves
|
|
@@ -126,6 +132,10 @@ export function checkRuntimeSupported(provider, runtime) {
|
|
|
126
132
|
return { ok: true };
|
|
127
133
|
}
|
|
128
134
|
export const SECRETS_KEY = "secrets";
|
|
135
|
+
/** POSIX-style env var name a `secretEnv` entry binds to (e.g. `SERPER_API_KEY`). */
|
|
136
|
+
export const SECRET_ENV_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
|
|
137
|
+
/** Workspace secret handle a `secretEnv` ref points at (and the name `secret.upload` persists to). */
|
|
138
|
+
export const SECRET_HANDLE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
129
139
|
export const PROXY_ENDPOINT_NAME_PATTERN = /^[a-z][a-z0-9_-]{0,62}$/;
|
|
130
140
|
export const RESERVED_PROXY_ENDPOINT_NAMES = new Set(["proxy", "aex", "internal", "admin"]);
|
|
131
141
|
/**
|
|
@@ -633,9 +643,40 @@ export function crossValidateProxyEndpointsAndAuth(endpoints, auth) {
|
|
|
633
643
|
}
|
|
634
644
|
}
|
|
635
645
|
}
|
|
646
|
+
/**
|
|
647
|
+
* Cross-check `submission.secretEnv` declarations against `secrets.envSecrets`
|
|
648
|
+
* values. Mirrors {@link crossValidateProxyEndpointsAndAuth}:
|
|
649
|
+
*
|
|
650
|
+
* - `{ ephemeral: true }` MUST have a matching `secrets.envSecrets` value.
|
|
651
|
+
* - `{ ref }` MUST NOT supply a value (the value lives in the workspace store).
|
|
652
|
+
* - every `secrets.envSecrets` value MUST have a matching `{ ephemeral: true }`
|
|
653
|
+
* declaration (no orphan values that would never be injected).
|
|
654
|
+
*/
|
|
655
|
+
export function crossValidateSecretEnvAndValues(secretEnv, envSecrets) {
|
|
656
|
+
const declarations = secretEnv ?? {};
|
|
657
|
+
const values = envSecrets ?? {};
|
|
658
|
+
for (const [envName, entry] of Object.entries(declarations)) {
|
|
659
|
+
const hasValue = Object.prototype.hasOwnProperty.call(values, envName);
|
|
660
|
+
if ("ref" in entry) {
|
|
661
|
+
if (hasValue) {
|
|
662
|
+
throw new Error(`submission.secretEnv[${envName}] is a workspace ref and must not supply a value in secrets.envSecrets[${envName}]; the value resolves server-side`);
|
|
663
|
+
}
|
|
664
|
+
continue;
|
|
665
|
+
}
|
|
666
|
+
if (!hasValue) {
|
|
667
|
+
throw new Error(`submission.secretEnv[${envName}] is ephemeral but has no matching secrets.envSecrets[${envName}] value`);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
for (const envName of Object.keys(values)) {
|
|
671
|
+
const entry = declarations[envName];
|
|
672
|
+
if (!entry || !("ephemeral" in entry)) {
|
|
673
|
+
throw new Error(`secrets.envSecrets[${envName}] has no matching submission.secretEnv[${envName}] ephemeral declaration`);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
636
677
|
export function parseInlineSecrets(input) {
|
|
637
678
|
const value = requireRecord(input, "secrets");
|
|
638
|
-
const allowedTopLevel = new Set(["apiKey", "mcpServers", "proxyEndpointAuth"]);
|
|
679
|
+
const allowedTopLevel = new Set(["apiKey", "mcpServers", "proxyEndpointAuth", "envSecrets"]);
|
|
639
680
|
for (const key of Object.keys(value)) {
|
|
640
681
|
if (key.startsWith("__aex_")) {
|
|
641
682
|
// Platform-internal namespace (e.g. __aex_proxy_token). The BFF
|
|
@@ -651,12 +692,30 @@ export function parseInlineSecrets(input) {
|
|
|
651
692
|
const apiKey = value.apiKey !== undefined ? requireString(value.apiKey, "secrets.apiKey") : undefined;
|
|
652
693
|
const mcpServers = parseMcpServerSecrets(value.mcpServers);
|
|
653
694
|
const proxyEndpointAuth = parseProxyEndpointAuth(value.proxyEndpointAuth);
|
|
695
|
+
const envSecrets = parseEnvSecrets(value.envSecrets);
|
|
654
696
|
return {
|
|
655
697
|
...(apiKey !== undefined ? { apiKey } : {}),
|
|
656
698
|
...(mcpServers ? { mcpServers } : {}),
|
|
657
|
-
...(proxyEndpointAuth ? { proxyEndpointAuth } : {})
|
|
699
|
+
...(proxyEndpointAuth ? { proxyEndpointAuth } : {}),
|
|
700
|
+
...(envSecrets ? { envSecrets } : {})
|
|
658
701
|
};
|
|
659
702
|
}
|
|
703
|
+
function parseEnvSecrets(input) {
|
|
704
|
+
if (input === undefined || input === null)
|
|
705
|
+
return undefined;
|
|
706
|
+
const value = requireRecord(input, "secrets.envSecrets");
|
|
707
|
+
const out = {};
|
|
708
|
+
for (const [envName, entry] of Object.entries(value)) {
|
|
709
|
+
if (!SECRET_ENV_NAME_PATTERN.test(envName)) {
|
|
710
|
+
throw new Error(`secrets.envSecrets key "${envName}" must be a valid env var name matching ${SECRET_ENV_NAME_PATTERN.source}`);
|
|
711
|
+
}
|
|
712
|
+
if (typeof entry !== "string" || entry.length === 0) {
|
|
713
|
+
throw new Error(`secrets.envSecrets.${envName} must be a non-empty string`);
|
|
714
|
+
}
|
|
715
|
+
out[envName] = entry;
|
|
716
|
+
}
|
|
717
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
718
|
+
}
|
|
660
719
|
function parseMcpServerSecrets(input) {
|
|
661
720
|
if (input === undefined) {
|
|
662
721
|
return undefined;
|
|
@@ -917,6 +976,7 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
917
976
|
"timeout",
|
|
918
977
|
"postHook",
|
|
919
978
|
"proxyEndpoints",
|
|
979
|
+
"parentRunId",
|
|
920
980
|
SECRETS_KEY
|
|
921
981
|
]);
|
|
922
982
|
for (const key of Object.keys(value)) {
|
|
@@ -949,6 +1009,9 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
949
1009
|
}
|
|
950
1010
|
const runtimeSize = parseRuntimeSize(value.runtimeSize);
|
|
951
1011
|
const timeoutMs = parseRunTimeout(value.timeout);
|
|
1012
|
+
// Lineage parent only. `depth` is NEVER accepted from the wire — the server
|
|
1013
|
+
// derives it from the parent row (a forged depth must not bypass the cap).
|
|
1014
|
+
const parentRunId = optionalString(value.parentRunId, "submission.parentRunId");
|
|
952
1015
|
const postHook = parsePostHook(value.postHook, "submission.postHook");
|
|
953
1016
|
const proxyEndpoints = parseProxyEndpoints(value.proxyEndpoints);
|
|
954
1017
|
const secrets = parseInlineSecrets(value.secrets);
|
|
@@ -956,6 +1019,7 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
956
1019
|
crossValidateProxyEndpointsAndAuth(proxyEndpoints, secrets.proxyEndpointAuth);
|
|
957
1020
|
const submission = parseSubmission(value.submission);
|
|
958
1021
|
assertRunModelMatchesProvider(provider, submission.model);
|
|
1022
|
+
crossValidateSecretEnvAndValues(submission.secretEnv, secrets.envSecrets);
|
|
959
1023
|
// mcpServers names must agree across the submission half and the
|
|
960
1024
|
// secrets half — every secrets.mcpServers[i].name MUST resolve to a
|
|
961
1025
|
// submission.mcpServers entry (no orphan secrets) AND the URL must
|
|
@@ -999,6 +1063,7 @@ export function parseRunSubmissionRequest(input, options = {}) {
|
|
|
999
1063
|
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
1000
1064
|
...(postHook !== undefined ? { postHook } : {}),
|
|
1001
1065
|
...(proxyEndpoints ? { proxyEndpoints } : {}),
|
|
1066
|
+
...(parentRunId !== undefined ? { parentRunId } : {}),
|
|
1002
1067
|
secrets
|
|
1003
1068
|
};
|
|
1004
1069
|
}
|
|
@@ -1051,6 +1116,7 @@ export function parseSubmission(input) {
|
|
|
1051
1116
|
"agentsMd",
|
|
1052
1117
|
"files",
|
|
1053
1118
|
"mcpServers",
|
|
1119
|
+
"secretEnv",
|
|
1054
1120
|
"environment",
|
|
1055
1121
|
"securityProfile",
|
|
1056
1122
|
"metadata",
|
|
@@ -1071,6 +1137,7 @@ export function parseSubmission(input) {
|
|
|
1071
1137
|
const agentsMd = parseAgentsMd(value.agentsMd);
|
|
1072
1138
|
const files = parseFiles(value.files);
|
|
1073
1139
|
const mcpServers = parseMcpServers(value.mcpServers);
|
|
1140
|
+
const secretEnv = parseSecretEnv(value.secretEnv);
|
|
1074
1141
|
const environment = parseEnvironment(value.environment);
|
|
1075
1142
|
const securityProfile = parseRuntimeSecurityProfile(value.securityProfile);
|
|
1076
1143
|
const metadata = optionalJsonRecord(value.metadata, "submission.metadata");
|
|
@@ -1086,6 +1153,7 @@ export function parseSubmission(input) {
|
|
|
1086
1153
|
agentsMd,
|
|
1087
1154
|
files,
|
|
1088
1155
|
mcpServers,
|
|
1156
|
+
...(secretEnv ? { secretEnv } : {}),
|
|
1089
1157
|
...(environment ? { environment } : {}),
|
|
1090
1158
|
...(securityProfile ? { securityProfile } : {}),
|
|
1091
1159
|
...(metadata ? { metadata } : {}),
|
|
@@ -1095,6 +1163,37 @@ export function parseSubmission(input) {
|
|
|
1095
1163
|
...(platform ? { platform } : {})
|
|
1096
1164
|
};
|
|
1097
1165
|
}
|
|
1166
|
+
function parseSecretEnv(input) {
|
|
1167
|
+
if (input === undefined || input === null)
|
|
1168
|
+
return undefined;
|
|
1169
|
+
const value = requireRecord(input, "submission.secretEnv");
|
|
1170
|
+
const out = {};
|
|
1171
|
+
for (const [envName, entry] of Object.entries(value)) {
|
|
1172
|
+
if (!SECRET_ENV_NAME_PATTERN.test(envName)) {
|
|
1173
|
+
throw new Error(`submission.secretEnv key "${envName}" must be a valid env var name matching ${SECRET_ENV_NAME_PATTERN.source}`);
|
|
1174
|
+
}
|
|
1175
|
+
const path = `submission.secretEnv.${envName}`;
|
|
1176
|
+
const record = requireRecord(entry, path);
|
|
1177
|
+
const keys = Object.keys(record);
|
|
1178
|
+
if (keys.length !== 1 || (!("ref" in record) && !("ephemeral" in record))) {
|
|
1179
|
+
throw new Error(`${path} must be exactly one of { ref } or { ephemeral: true }`);
|
|
1180
|
+
}
|
|
1181
|
+
if ("ref" in record) {
|
|
1182
|
+
const handle = requireString(record.ref, `${path}.ref`);
|
|
1183
|
+
if (!SECRET_HANDLE_PATTERN.test(handle)) {
|
|
1184
|
+
throw new Error(`${path}.ref handle must match ${SECRET_HANDLE_PATTERN.source}`);
|
|
1185
|
+
}
|
|
1186
|
+
out[envName] = { ref: handle };
|
|
1187
|
+
}
|
|
1188
|
+
else {
|
|
1189
|
+
if (record.ephemeral !== true) {
|
|
1190
|
+
throw new Error(`${path}.ephemeral must be the literal true`);
|
|
1191
|
+
}
|
|
1192
|
+
out[envName] = { ephemeral: true };
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
1196
|
+
}
|
|
1098
1197
|
function parsePlatformConfig(input) {
|
|
1099
1198
|
if (input === undefined || input === null)
|
|
1100
1199
|
return undefined;
|
package/dist/cli.mjs
CHANGED
|
@@ -126,6 +126,34 @@ var PROVIDER_PUBLIC_SUPPORT = {
|
|
|
126
126
|
runtimeEvidence: {
|
|
127
127
|
managed: COMMON_EVIDENCE
|
|
128
128
|
}
|
|
129
|
+
},
|
|
130
|
+
// Doubao (ByteDance) via the official Ark API — international BytePlus gateway.
|
|
131
|
+
// Wired + parser/routing-verified but not yet proven against a live BytePlus
|
|
132
|
+
// account, so `live-unverified`. Promote to `supported` (and swap COMMON_EVIDENCE
|
|
133
|
+
// for a DOUBAO_MANAGED_EVIDENCE pointer to live-sdk-doubao.test.ts) once the
|
|
134
|
+
// live run passes.
|
|
135
|
+
doubao: {
|
|
136
|
+
displayName: "Doubao",
|
|
137
|
+
status: "live-unverified",
|
|
138
|
+
docsAnchor: "doubao",
|
|
139
|
+
docs: COMMON_DOCS,
|
|
140
|
+
evidence: COMMON_EVIDENCE,
|
|
141
|
+
runtimeEvidence: {
|
|
142
|
+
managed: COMMON_EVIDENCE
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
// Doubao (ByteDance) via the official Ark API — China Volcengine gateway.
|
|
146
|
+
// Same wiring as `doubao`; additionally gated on CF Worker egress reaching the
|
|
147
|
+
// Beijing host (see apps/egress-probe). `live-unverified` until proven live.
|
|
148
|
+
"doubao-cn": {
|
|
149
|
+
displayName: "Doubao (China)",
|
|
150
|
+
status: "live-unverified",
|
|
151
|
+
docsAnchor: "doubao-cn",
|
|
152
|
+
docs: COMMON_DOCS,
|
|
153
|
+
evidence: COMMON_EVIDENCE,
|
|
154
|
+
runtimeEvidence: {
|
|
155
|
+
managed: COMMON_EVIDENCE
|
|
156
|
+
}
|
|
129
157
|
}
|
|
130
158
|
};
|
|
131
159
|
|
|
@@ -144,7 +172,21 @@ var MODEL_PROVIDER_IDS = {
|
|
|
144
172
|
"gemini-2.0-flash": { gemini: "gemini-2.0-flash", openrouter: "google/gemini-2.0-flash-001" },
|
|
145
173
|
"gemini-2.5-flash": { gemini: "gemini-2.5-flash" },
|
|
146
174
|
"mistral-large-latest": { mistral: "mistral-large-latest" },
|
|
147
|
-
"mistral-small-latest": { mistral: "mistral-small-latest" }
|
|
175
|
+
"mistral-small-latest": { mistral: "mistral-small-latest" },
|
|
176
|
+
// Doubao (ByteDance) via the official Ark API. Served by both the
|
|
177
|
+
// international BytePlus ModelArk gateway (`doubao`, the default) and the
|
|
178
|
+
// China Volcengine Ark gateway (`doubao-cn`). Ark accepts the API-format
|
|
179
|
+
// model NAME directly in the chat-completions `model` field (no `ep-…`
|
|
180
|
+
// inference-endpoint id). The native strings are the same Ark catalog ids on
|
|
181
|
+
// both gateways; BytePlus per-account availability is confirmed at live-verify
|
|
182
|
+
// (both providers ship `live-unverified` until then — provider-support.ts).
|
|
183
|
+
// pro — Doubao Seed 1.8 (flagship, 256K context).
|
|
184
|
+
// flash — Doubao Seed 1.6 Flash (fast/cheap, 256K context).
|
|
185
|
+
"doubao-seed-pro": { doubao: "doubao-seed-1-8-251228", "doubao-cn": "doubao-seed-1-8-251228" },
|
|
186
|
+
"doubao-seed-flash": {
|
|
187
|
+
doubao: "doubao-seed-1-6-flash-250828",
|
|
188
|
+
"doubao-cn": "doubao-seed-1-6-flash-250828"
|
|
189
|
+
}
|
|
148
190
|
};
|
|
149
191
|
var RUN_MODELS = Object.keys(MODEL_PROVIDER_IDS);
|
|
150
192
|
var PROVIDERS_BY_MODEL = (() => {
|
|
@@ -743,7 +785,9 @@ var RUN_PROVIDERS = [
|
|
|
743
785
|
"openai",
|
|
744
786
|
"gemini",
|
|
745
787
|
"mistral",
|
|
746
|
-
"openrouter"
|
|
788
|
+
"openrouter",
|
|
789
|
+
"doubao",
|
|
790
|
+
"doubao-cn"
|
|
747
791
|
];
|
|
748
792
|
var DEFAULT_RUN_PROVIDER = "anthropic";
|
|
749
793
|
var RUNTIME_KINDS = ["managed"];
|
|
@@ -794,7 +838,7 @@ function visitCustodyValue(input, path, findings) {
|
|
|
794
838
|
}
|
|
795
839
|
function scanStringValue(value, path, findings) {
|
|
796
840
|
for (const pattern of forbiddenStringPatterns) {
|
|
797
|
-
if (pattern
|
|
841
|
+
if (matchesForbiddenPattern(pattern, value)) {
|
|
798
842
|
findings.push(Object.freeze({
|
|
799
843
|
path,
|
|
800
844
|
reason: pattern.reason,
|
|
@@ -803,11 +847,32 @@ function scanStringValue(value, path, findings) {
|
|
|
803
847
|
}
|
|
804
848
|
}
|
|
805
849
|
}
|
|
850
|
+
function matchesForbiddenPattern(pattern, value) {
|
|
851
|
+
if (!pattern.accept) {
|
|
852
|
+
return pattern.regex.test(value);
|
|
853
|
+
}
|
|
854
|
+
const scan = pattern.regex.global ? pattern.regex : new RegExp(pattern.regex.source, `${pattern.regex.flags}g`);
|
|
855
|
+
scan.lastIndex = 0;
|
|
856
|
+
let match;
|
|
857
|
+
while ((match = scan.exec(value)) !== null) {
|
|
858
|
+
if (pattern.accept(match[0])) {
|
|
859
|
+
return true;
|
|
860
|
+
}
|
|
861
|
+
if (match.index === scan.lastIndex) {
|
|
862
|
+
scan.lastIndex++;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
806
867
|
var forbiddenStringPatterns = Object.freeze([
|
|
807
868
|
{ reason: "bearer_token", regex: /\bBearer\s+[A-Za-z0-9._~+/=-]{8,}/i },
|
|
808
869
|
{
|
|
809
870
|
reason: "provider_key",
|
|
810
|
-
|
|
871
|
+
// Prefixed provider keys (`sk-…`, Slack `xox*-…`, Google `AIza…`). The bare
|
|
872
|
+
// `sk-` body is intentionally generic so an unrecognised vendor's `sk-` key
|
|
873
|
+
// (e.g. DeepSeek `sk-<hex>`, OpenRouter `sk-or-…`) is still caught by shape,
|
|
874
|
+
// not left to the narrowed entropy catch-all below.
|
|
875
|
+
regex: /\b(?:sk-[A-Za-z0-9_-]{16,}|xox[baprs]-[A-Za-z0-9-]{8,}|AIza[A-Za-z0-9_-]{8,})/i
|
|
811
876
|
},
|
|
812
877
|
{ reason: "signed_url", regex: /[?&](?:X-Amz-Signature|X-Amz-Credential|X-Amz-Algorithm|AWSAccessKeyId)=/i },
|
|
813
878
|
{ reason: "object_store_key", regex: /(^|[\s"'`])(?:runs|assets)\/[^?<#\s"'`]+/i },
|
|
@@ -816,8 +881,59 @@ var forbiddenStringPatterns = Object.freeze([
|
|
|
816
881
|
reason: "private_resource_handle",
|
|
817
882
|
regex: /\b(?:machine|session|agent|file|skill|env|resource|handle|token_hash|bearer_hash)[_:-][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/i
|
|
818
883
|
},
|
|
819
|
-
{
|
|
884
|
+
{
|
|
885
|
+
reason: "high_entropy_token",
|
|
886
|
+
// Catch-all for an unrecognised opaque secret blob. The candidate run
|
|
887
|
+
// EXCLUDES `_` (so `SCREAMING_SNAKE` env names and `slug_with_words` URL
|
|
888
|
+
// segments split instead of fusing into a phantom 40-char run — the live
|
|
889
|
+
// false positive was `ted_season_2_peacock_official_discussion_thread` in
|
|
890
|
+
// web-search result text and a fetched URL), and the `accept` predicate
|
|
891
|
+
// vetoes content-addressed hashes (md5/sha1/sha256 digests — the platform's
|
|
892
|
+
// OWN asset filenames) and low-entropy / single-class runs so only genuine
|
|
893
|
+
// opaque secrets remain. Slash-bearing secrets (signed URLs, connection
|
|
894
|
+
// strings, `Bearer …`) are covered by the named patterns above.
|
|
895
|
+
regex: /\b[A-Za-z0-9-]{40,}\b/,
|
|
896
|
+
accept: isHighEntropySecretRun
|
|
897
|
+
}
|
|
820
898
|
]);
|
|
899
|
+
var CONTENT_HASH_RUN = /^(?:[0-9a-f]{32}|[0-9a-f]{40}|[0-9a-f]{64})$/i;
|
|
900
|
+
function isHighEntropySecretRun(run) {
|
|
901
|
+
if (CONTENT_HASH_RUN.test(run)) {
|
|
902
|
+
return false;
|
|
903
|
+
}
|
|
904
|
+
if (!/[A-Za-z]/.test(run) || !/\d/.test(run)) {
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
if (highEntropyCharClassCount(run) < 2) {
|
|
908
|
+
return false;
|
|
909
|
+
}
|
|
910
|
+
return highEntropyShannonBits(run) >= 3;
|
|
911
|
+
}
|
|
912
|
+
function highEntropyCharClassCount(value) {
|
|
913
|
+
let count = 0;
|
|
914
|
+
if (/[a-z]/.test(value))
|
|
915
|
+
count++;
|
|
916
|
+
if (/[A-Z]/.test(value))
|
|
917
|
+
count++;
|
|
918
|
+
if (/[0-9]/.test(value))
|
|
919
|
+
count++;
|
|
920
|
+
return count;
|
|
921
|
+
}
|
|
922
|
+
function highEntropyShannonBits(value) {
|
|
923
|
+
if (value.length === 0) {
|
|
924
|
+
return 0;
|
|
925
|
+
}
|
|
926
|
+
const counts = /* @__PURE__ */ new Map();
|
|
927
|
+
for (const char of value) {
|
|
928
|
+
counts.set(char, (counts.get(char) ?? 0) + 1);
|
|
929
|
+
}
|
|
930
|
+
let bits = 0;
|
|
931
|
+
for (const count of counts.values()) {
|
|
932
|
+
const p = count / value.length;
|
|
933
|
+
bits -= p * Math.log2(p);
|
|
934
|
+
}
|
|
935
|
+
return bits;
|
|
936
|
+
}
|
|
821
937
|
function isForbiddenCustodyFieldName(key) {
|
|
822
938
|
return /^(apiKey|secretValue|bearerHash|signedUrl|objectStoreKey|objectKey|vaultId|providerResponseBody|responseBody|privateResourceHandle|resourceHandle|rawBody)$/i.test(key);
|
|
823
939
|
}
|
|
@@ -1246,11 +1362,13 @@ __export(operations_exports, {
|
|
|
1246
1362
|
createAgentsMd: () => createAgentsMd,
|
|
1247
1363
|
createFile: () => createFile,
|
|
1248
1364
|
createOutputLink: () => createOutputLink,
|
|
1365
|
+
createSecret: () => createSecret,
|
|
1249
1366
|
createSkillBundle: () => createSkillBundle,
|
|
1250
1367
|
createSkillBundleDirect: () => createSkillBundleDirect,
|
|
1251
1368
|
deleteAgentsMd: () => deleteAgentsMd,
|
|
1252
1369
|
deleteFile: () => deleteFile,
|
|
1253
1370
|
deleteRun: () => deleteRun,
|
|
1371
|
+
deleteSecret: () => deleteSecret,
|
|
1254
1372
|
deleteSkill: () => deleteSkill,
|
|
1255
1373
|
deleteWorkspaceAsset: () => deleteWorkspaceAsset,
|
|
1256
1374
|
download: () => download,
|
|
@@ -1265,13 +1383,17 @@ __export(operations_exports, {
|
|
|
1265
1383
|
getFile: () => getFile,
|
|
1266
1384
|
getRun: () => getRun,
|
|
1267
1385
|
getRunUnit: () => getRunUnit,
|
|
1386
|
+
getSecret: () => getSecret,
|
|
1268
1387
|
getSkill: () => getSkill,
|
|
1269
1388
|
listAgentsMd: () => listAgentsMd,
|
|
1270
1389
|
listFiles: () => listFiles,
|
|
1271
1390
|
listOutputs: () => listOutputs,
|
|
1272
1391
|
listRunEvents: () => listRunEvents,
|
|
1392
|
+
listSecrets: () => listSecrets,
|
|
1273
1393
|
listSkills: () => listSkills,
|
|
1274
1394
|
resolveOutputFileSelector: () => resolveOutputFileSelector,
|
|
1395
|
+
revealSecret: () => revealSecret,
|
|
1396
|
+
rotateSecret: () => rotateSecret,
|
|
1275
1397
|
submitRun: () => submitRun,
|
|
1276
1398
|
submitRunMultipart: () => submitRunMultipart,
|
|
1277
1399
|
uploadWorkspaceAsset: () => uploadWorkspaceAsset,
|
|
@@ -2380,6 +2502,44 @@ function unwrapFile(result) {
|
|
|
2380
2502
|
}
|
|
2381
2503
|
return result;
|
|
2382
2504
|
}
|
|
2505
|
+
async function createSecret(http, args) {
|
|
2506
|
+
const result = await http.request("/api/secrets", {
|
|
2507
|
+
method: "POST",
|
|
2508
|
+
body: JSON.stringify({ name: args.name, value: args.value })
|
|
2509
|
+
});
|
|
2510
|
+
return unwrapSecret(result);
|
|
2511
|
+
}
|
|
2512
|
+
async function listSecrets(http) {
|
|
2513
|
+
const result = await http.request("/api/secrets");
|
|
2514
|
+
if (Array.isArray(result)) {
|
|
2515
|
+
return result;
|
|
2516
|
+
}
|
|
2517
|
+
return result.secrets;
|
|
2518
|
+
}
|
|
2519
|
+
async function getSecret(http, name) {
|
|
2520
|
+
const result = await http.request(`/api/secrets/${encodeURIComponent(name)}`);
|
|
2521
|
+
return unwrapSecret(result);
|
|
2522
|
+
}
|
|
2523
|
+
async function revealSecret(http, name) {
|
|
2524
|
+
return http.request(`/api/secrets/${encodeURIComponent(name)}/reveal`, {
|
|
2525
|
+
method: "POST"
|
|
2526
|
+
});
|
|
2527
|
+
}
|
|
2528
|
+
async function rotateSecret(http, args) {
|
|
2529
|
+
const result = await http.request(`/api/secrets/${encodeURIComponent(args.name)}/rotate`, { method: "POST", body: JSON.stringify({ value: args.value }) });
|
|
2530
|
+
return unwrapSecret(result);
|
|
2531
|
+
}
|
|
2532
|
+
async function deleteSecret(http, name) {
|
|
2533
|
+
await http.request(`/api/secrets/${encodeURIComponent(name)}`, {
|
|
2534
|
+
method: "DELETE"
|
|
2535
|
+
});
|
|
2536
|
+
}
|
|
2537
|
+
function unwrapSecret(result) {
|
|
2538
|
+
if (result && typeof result === "object" && "secret" in result) {
|
|
2539
|
+
return result.secret;
|
|
2540
|
+
}
|
|
2541
|
+
return result;
|
|
2542
|
+
}
|
|
2383
2543
|
function unwrapSkill(result) {
|
|
2384
2544
|
if (result && typeof result === "object" && "skill" in result) {
|
|
2385
2545
|
return result.skill;
|
package/dist/cli.mjs.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
d05e5e074b577553d20fa3680f834b7941fe0cb7692c0a743975fcf36c4ec9b5 cli.mjs
|
package/dist/client.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { HttpClient, type AexEvent, type AgentsMdRecord, type CredentialMode, type DebugSink, type FetchLike, type FileRecord, type Output, type OutputMode, type PlatformEnvironmentInput, type PlatformSubmission, type PlatformInlineSecrets, type PlatformProxyEndpoint, type PlatformProxyEndpointAuth, type PlatformPostHookInput, type Run, type RunModel, type RunEvent, type RunProvider, type RunUnit, type Builtin, type RuntimeSize, type RuntimeKind, type SignedOutputLink, type Skill as SkillRecord, type WhoAmI } from "./_contracts/index.js";
|
|
1
|
+
import { HttpClient, SecretString, type AexEvent, type AgentsMdRecord, type CredentialMode, type DebugSink, type FetchLike, type FileRecord, type Output, type OutputMode, type PlatformEnvironmentInput, type PlatformSubmission, type PlatformInlineSecrets, type PlatformProxyEndpoint, type PlatformProxyEndpointAuth, type PlatformPostHookInput, type Run, type RunModel, type RunEvent, type RunProvider, type SecretRecord, type SecretReveal, type RunUnit, type Builtin, type RuntimeSize, type RuntimeKind, type SignedOutputLink, type Skill as SkillRecord, type WhoAmI } from "./_contracts/index.js";
|
|
2
2
|
import { AgentsMd } from "./agents-md.js";
|
|
3
3
|
import { type UploadedAsset } from "./asset-upload.js";
|
|
4
4
|
import { File } from "./file.js";
|
|
5
5
|
import { McpServer } from "./mcp-server.js";
|
|
6
6
|
import { ProxyEndpoint } from "./proxy-endpoint.js";
|
|
7
|
+
import { Secret } from "./secret.js";
|
|
7
8
|
import { Skill } from "./skill.js";
|
|
8
9
|
export interface AgentExecutorOptions {
|
|
9
10
|
/** Workspace-scoped SDK API token. */
|
|
@@ -85,6 +86,16 @@ export interface SubmitOptions {
|
|
|
85
86
|
readonly agentsMd?: readonly AgentsMd[];
|
|
86
87
|
readonly files?: readonly File[];
|
|
87
88
|
readonly mcpServers?: readonly McpServer[];
|
|
89
|
+
/**
|
|
90
|
+
* Env-var secrets, keyed by env name. Each value is a {@link Secret}:
|
|
91
|
+
* `Secret.value(v)` (ephemeral per-run — vaulted at submit, deleted at the
|
|
92
|
+
* run's terminal) or `Secret.ref(handle)` (a persisted workspace secret,
|
|
93
|
+
* resolved server-side). The SDK splits these into value-free declarations on
|
|
94
|
+
* the hashed submission and ephemeral values into the vaulted secrets channel,
|
|
95
|
+
* so a value never enters the run snapshot or the idempotency hash. The
|
|
96
|
+
* runtime injects each as the named env var.
|
|
97
|
+
*/
|
|
98
|
+
readonly secretEnv?: Readonly<Record<string, Secret>>;
|
|
88
99
|
readonly environment?: PlatformEnvironmentInput;
|
|
89
100
|
readonly metadata?: PlatformSubmission["metadata"];
|
|
90
101
|
/**
|
|
@@ -148,6 +159,14 @@ export interface SubmitOptions {
|
|
|
148
159
|
readonly outputMode?: OutputMode;
|
|
149
160
|
readonly secrets: PlatformInlineSecrets;
|
|
150
161
|
readonly idempotencyKey?: string;
|
|
162
|
+
/**
|
|
163
|
+
* Lineage parent (agent-session §9). When set, the server admits this run as
|
|
164
|
+
* a CHILD of `parentRunId` (same workspace required), enforcing the
|
|
165
|
+
* max-subagent-depth + per-root concurrency caps and persisting the lineage.
|
|
166
|
+
* The depth is always derived server-side from the parent row — clients name
|
|
167
|
+
* the parent, never the depth.
|
|
168
|
+
*/
|
|
169
|
+
readonly parentRunId?: string;
|
|
151
170
|
readonly signal?: AbortSignal;
|
|
152
171
|
}
|
|
153
172
|
/** @deprecated Renamed to {@link SubmitOptions}. Kept for one release. */
|
|
@@ -287,6 +306,52 @@ export declare class FilesClient {
|
|
|
287
306
|
readonly bytes: Uint8Array;
|
|
288
307
|
}): Promise<FileRecord>;
|
|
289
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Workspace secret management exposed under `client.secrets`, mirroring
|
|
311
|
+
* `client.skills` / `client.files`.
|
|
312
|
+
*
|
|
313
|
+
* Lifecycle parity with assets/skills: a `Secret.value(...)` is per-run and
|
|
314
|
+
* gone at terminal; `set` (or promoting an ephemeral via `secret.upload`)
|
|
315
|
+
* persists a named, searchable workspace secret you can `get` (metadata),
|
|
316
|
+
* `reveal` (audited value), `rotate`, `list`, and `delete`. The identity is the
|
|
317
|
+
* `name`; the value rotates under that stable name.
|
|
318
|
+
*
|
|
319
|
+
* Values are write-only: `set`/`rotate` send the value in the request BODY (never
|
|
320
|
+
* the URL); `get`/`list` return metadata only; `reveal` is the explicit audited
|
|
321
|
+
* value read.
|
|
322
|
+
*/
|
|
323
|
+
export declare class SecretsClient {
|
|
324
|
+
#private;
|
|
325
|
+
constructor(http: HttpClient);
|
|
326
|
+
/** Create a named workspace secret. Accepts a raw string or a `SecretString`. */
|
|
327
|
+
set(args: {
|
|
328
|
+
readonly name: string;
|
|
329
|
+
readonly value: string | SecretString;
|
|
330
|
+
}): Promise<SecretRecord>;
|
|
331
|
+
/** List workspace secret metadata (searchable by name). Never returns values. */
|
|
332
|
+
list(): Promise<readonly SecretRecord[]>;
|
|
333
|
+
/** Metadata for one workspace secret by name. Never returns the value. */
|
|
334
|
+
get(name: string): Promise<SecretRecord>;
|
|
335
|
+
/** Audited value read — the only path that returns a workspace secret value. */
|
|
336
|
+
reveal(name: string): Promise<SecretReveal>;
|
|
337
|
+
/** Replace the value of an existing workspace secret; bumps its version. */
|
|
338
|
+
rotate(args: {
|
|
339
|
+
readonly name: string;
|
|
340
|
+
readonly value: string | SecretString;
|
|
341
|
+
}): Promise<SecretRecord>;
|
|
342
|
+
delete(name: string): Promise<void>;
|
|
343
|
+
/**
|
|
344
|
+
* Internal: create a workspace secret from an ephemeral `Secret.value(...)`
|
|
345
|
+
* being promoted via `secret.upload(client, { name })`. NOT part of the
|
|
346
|
+
* public API — callers use `set`.
|
|
347
|
+
*/
|
|
348
|
+
_createWorkspaceSecret(args: {
|
|
349
|
+
readonly name: string;
|
|
350
|
+
readonly value: string;
|
|
351
|
+
}): Promise<{
|
|
352
|
+
readonly name: string;
|
|
353
|
+
}>;
|
|
354
|
+
}
|
|
290
355
|
/**
|
|
291
356
|
* Unified user-facing client for the aex platform. The same class
|
|
292
357
|
* powers the published `@aexhq/sdk` SDK and (under the hood) every host-side
|
|
@@ -303,6 +368,7 @@ export declare class AgentExecutor {
|
|
|
303
368
|
readonly skills: SkillsClient;
|
|
304
369
|
readonly agentsMd: AgentsMdClient;
|
|
305
370
|
readonly files: FilesClient;
|
|
371
|
+
readonly secrets: SecretsClient;
|
|
306
372
|
constructor(options: AgentExecutorOptions);
|
|
307
373
|
/**
|
|
308
374
|
* Internal: forwards to `SkillsClient._uploadSkillBundle`. NOT part of
|
|
@@ -338,6 +404,18 @@ export declare class AgentExecutor {
|
|
|
338
404
|
readonly name: string;
|
|
339
405
|
readonly bytes: Uint8Array;
|
|
340
406
|
}): Promise<FileRecord>;
|
|
407
|
+
/**
|
|
408
|
+
* Internal: satisfies the `SecretUploader` surface so a
|
|
409
|
+
* `Secret.value(...).upload(client, { name })` promotes an ephemeral secret
|
|
410
|
+
* into the workspace store. Forwarded to `SecretsClient._createWorkspaceSecret`.
|
|
411
|
+
* NOT part of the public API.
|
|
412
|
+
*/
|
|
413
|
+
_createWorkspaceSecret(args: {
|
|
414
|
+
readonly name: string;
|
|
415
|
+
readonly value: string;
|
|
416
|
+
}): Promise<{
|
|
417
|
+
readonly name: string;
|
|
418
|
+
}>;
|
|
341
419
|
/**
|
|
342
420
|
* Internal: materialize raw bytes to the content-addressable asset store
|
|
343
421
|
* (`/assets/presign` → PUT → `/assets/finalize`). Used by `Skill.upload(this)`
|