@aexhq/sdk 0.45.2-canary → 1.0.0-canary

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.
@@ -1,10 +1,9 @@
1
- export * from "./provider-support.js";
2
1
  export * from "./provider-fault.js";
3
2
  export * from "./models.js";
4
3
  export { SESSION_LIFECYCLE_STATUSES, SESSION_STATUSES, SESSION_TERMINAL_OUTCOMES, isTerminalSessionStatus } from "./status.js";
5
4
  export type { SessionLifecycleStatus, SessionStatus, SessionTerminalOutcome } from "./status.js";
6
- export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, DEFAULT_PROVIDER, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, Providers, RESPONSE_FORMAT_KINDS, PROVIDERS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, SKILLS_TOOL_DEFINITION, SKILLS_TOOL_NAME, STREAMABLE_SHAPES, assertStreamableOutputMode, crossValidateSecretEnvAndValues, isStreamableProvider, packageInstallString, parseApprovalGate, parseInlineSecrets, parseResponseFormat, parseSessionLimits, parseProviderName, parseSessionWebhook, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
7
- export type { ApprovalGate, BuiltinToolName, JsonPrimitive, JsonValue, OutputMode, PlatformEnvironment, PlatformEnvironmentInput, PlatformInlineSecrets, PlatformInjectionConfig, PlatformMcpServerSecret, PlatformNetworking, PlatformFileCaptureConfig, PlatformPackage, PlatformPackageEcosystem, PlatformPackageInput, PlatformSecretEnvEntry, PlatformSubmission, ResponseFormat, ResponseFormatKind, SessionLimits, ProviderName, SessionWebhookSpec, StreamableShape } from "./submission.js";
5
+ export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, RESPONSE_FORMAT_KINDS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, SKILLS_TOOL_DEFINITION, SKILLS_TOOL_NAME, crossValidateSecretEnvAndValues, packageInstallString, parseApprovalGate, parseInlineSecrets, parseResponseFormat, parseSessionLimits, parseSessionWebhook, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
6
+ export type { ApprovalGate, BuiltinToolName, JsonPrimitive, JsonValue, OutputMode, PlatformEnvironment, PlatformEnvironmentInput, PlatformInlineSecrets, PlatformInjectionConfig, PlatformMcpServerSecret, PlatformNetworking, PlatformFileCaptureConfig, PlatformPackage, PlatformPackageEcosystem, PlatformPackageInput, PlatformSecretEnvEntry, PlatformSubmission, ResponseFormat, ResponseFormatKind, SessionLimits, ProviderName, SessionWebhookSpec } from "./submission.js";
8
7
  export * from "./runtime-sizes.js";
9
8
  export * from "./runtime-kind.js";
10
9
  export * from "./runner-event.js";
@@ -1,8 +1,7 @@
1
- export * from "./provider-support.js";
2
1
  export * from "./provider-fault.js";
3
2
  export * from "./models.js";
4
3
  export { SESSION_LIFECYCLE_STATUSES, SESSION_STATUSES, SESSION_TERMINAL_OUTCOMES, isTerminalSessionStatus } from "./status.js";
5
- export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, DEFAULT_PROVIDER, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, Providers, RESPONSE_FORMAT_KINDS, PROVIDERS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, SKILLS_TOOL_DEFINITION, SKILLS_TOOL_NAME, STREAMABLE_SHAPES, assertStreamableOutputMode, crossValidateSecretEnvAndValues, isStreamableProvider, packageInstallString, parseApprovalGate, parseInlineSecrets, parseResponseFormat, parseSessionLimits, parseProviderName, parseSessionWebhook, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
4
+ export { AEX_RESERVED_ENV_PREFIX, BUILTIN_TOOL_NAMES, BuiltinTools, DEFAULT_BUILTIN_TOOLS, DEFAULT_OUTPUT_MODE, ENV_VARS_MAX_ENTRIES, ENV_VARS_MAX_TOTAL_BYTES, ENV_VARS_MAX_VALUE_BYTES, OUTPUT_MODES, PLATFORM_PACKAGE_ECOSYSTEMS, RESPONSE_FORMAT_KINDS, SECRETS_KEY, SECRET_ENV_NAME_PATTERN, SECRET_HANDLE_PATTERN, SKILLS_TOOL_DEFINITION, SKILLS_TOOL_NAME, crossValidateSecretEnvAndValues, packageInstallString, parseApprovalGate, parseInlineSecrets, parseResponseFormat, parseSessionLimits, parseSessionWebhook, parseSubmission, resolveBuiltinToolNames } from "./submission.js";
6
5
  export * from "./runtime-sizes.js";
7
6
  export * from "./runtime-kind.js";
8
7
  export * from "./runner-event.js";
@@ -1,160 +1,29 @@
1
- import type { ProviderName } from "./submission.js";
2
1
  /**
3
- * Source of truth for the closed model set: each canonical model id maps to the
4
- * upstream providers that can serve it and the **provider-native** model string
5
- * each one expects.
2
+ * Public model ids are plain **Vercel AI Gateway `creator/model` slug strings**.
6
3
  *
7
- * `Models.*` / `SUPPORTED_MODELS` are aex's own **canonical, provider-neutral**
8
- * identifiers — they are NOT the strings sent to a provider. The platform
9
- * translates a `(canonical model, provider)` pair to the native id via
10
- * {@link resolveProviderModelId} when it builds the session's session manifest. The
11
- * same canonical model can therefore be served by more than one provider (e.g.
12
- * `gpt-4o-mini` via `openai` *or* `openrouter`), with a different native string
13
- * per provider.
14
- *
15
- * Ordering matters: the **first** provider listed for a model is its default
16
- * (see {@link providerForModel}) — list the native vendor before `openrouter`.
17
- * Additions belong here first so SDK types, CLI validation, docs examples, and
18
- * platform parsing all move together.
19
- */
20
- export declare const MODEL_PROVIDER_IDS: {
21
- readonly "claude-haiku-4-5": {
22
- readonly anthropic: "claude-haiku-4-5";
23
- };
24
- readonly "claude-3-5-haiku-latest": {
25
- readonly anthropic: "claude-3-5-haiku-latest";
26
- };
27
- readonly "claude-3-5-sonnet-latest": {
28
- readonly anthropic: "claude-3-5-sonnet-latest";
29
- };
30
- readonly "claude-sonnet-4-6": {
31
- readonly anthropic: "claude-sonnet-4-6";
32
- };
33
- readonly "deepseek-v4-flash": {
34
- readonly deepseek: "deepseek-v4-flash";
35
- };
36
- readonly "deepseek-v4-pro": {
37
- readonly deepseek: "deepseek-v4-pro";
38
- };
39
- readonly "gpt-4.1": {
40
- readonly openai: "gpt-4.1";
41
- };
42
- readonly "gpt-4o-mini": {
43
- readonly openai: "gpt-4o-mini";
44
- readonly openrouter: "openai/gpt-4o-mini";
45
- };
46
- readonly "gpt-4o": {
47
- readonly openrouter: "openai/gpt-4o";
48
- };
49
- readonly "gemini-2.0-flash": {
50
- readonly openrouter: "google/gemini-2.0-flash-001";
51
- };
52
- readonly "gemini-2.5-flash": {
53
- readonly gemini: "gemini-2.5-flash";
54
- };
55
- readonly "mistral-large-latest": {
56
- readonly mistral: "mistral-large-latest";
57
- };
58
- readonly "mistral-small-latest": {
59
- readonly mistral: "mistral-small-latest";
60
- };
61
- readonly "doubao-seed-pro": {
62
- readonly doubao: "doubao-seed-1-8-251228";
63
- };
64
- readonly "doubao-seed-flash": {
65
- readonly doubao: "doubao-seed-1-6-flash-250828";
66
- };
67
- };
68
- /**
69
- * Closed set of canonical model ids accepted by the public session-submission
70
- * schema. Derived from {@link MODEL_PROVIDER_IDS} so the two never drift.
71
- */
72
- export type ModelName = keyof typeof MODEL_PROVIDER_IDS;
73
- export declare const SUPPORTED_MODELS: readonly ModelName[];
74
- /**
75
- * Symbol-style accessors for the closed model set. Prefer these over raw
76
- * strings so an invalid token is a compile error, not a runtime 400 — e.g.
77
- * `Models.CLAUDE_HAIKU_4_5`. These are aex's **canonical** ids, not the native
78
- * strings sent upstream; the platform translates them per provider (see
79
- * {@link MODEL_PROVIDER_IDS} / {@link resolveProviderModelId}). When a model is
80
- * served by more than one provider, pair it with an explicit {@link Providers}
81
- * value; otherwise the single (default) provider is used.
82
- */
83
- export declare const Models: {
84
- /** Claude Haiku 4.5 — Anthropic. */
85
- readonly CLAUDE_HAIKU_4_5: "claude-haiku-4-5";
86
- /** Claude 3.5 Haiku (latest) — Anthropic. */
87
- readonly CLAUDE_3_5_HAIKU_LATEST: "claude-3-5-haiku-latest";
88
- /** Claude 3.5 Sonnet (latest) — Anthropic. */
89
- readonly CLAUDE_3_5_SONNET_LATEST: "claude-3-5-sonnet-latest";
90
- /** Claude Sonnet 4.6 — Anthropic (1M context, reasoning-capable). */
91
- readonly CLAUDE_SONNET_4_6: "claude-sonnet-4-6";
92
- /** DeepSeek V4 Flash — DeepSeek (non-thinking, fast). */
93
- readonly DEEPSEEK_V4_FLASH: "deepseek-v4-flash";
94
- /** DeepSeek V4 Pro — DeepSeek (reasoning-heavy). */
95
- readonly DEEPSEEK_V4_PRO: "deepseek-v4-pro";
96
- /** GPT-4.1 — OpenAI. */
97
- readonly GPT_4_1: "gpt-4.1";
98
- /** GPT-4o mini — OpenAI, or via OpenRouter (`provider: Providers.OPENROUTER`). */
99
- readonly GPT_4O_MINI: "gpt-4o-mini";
100
- /** GPT-4o — via OpenRouter (`provider: Providers.OPENROUTER`). */
101
- readonly GPT_4O: "gpt-4o";
102
- /** Gemini 2.0 Flash — via OpenRouter (`provider: Providers.OPENROUTER`). */
103
- readonly GEMINI_2_0_FLASH: "gemini-2.0-flash";
104
- /** Gemini 2.5 Flash — Gemini. */
105
- readonly GEMINI_2_5_FLASH: "gemini-2.5-flash";
106
- /** Mistral Large (latest) — Mistral. */
107
- readonly MISTRAL_LARGE_LATEST: "mistral-large-latest";
108
- /** Mistral Small (latest) — Mistral. */
109
- readonly MISTRAL_SMALL_LATEST: "mistral-small-latest";
110
- /**
111
- * Doubao Seed 1.8 — ByteDance, via the international BytePlus gateway.
112
- */
113
- readonly DOUBAO_SEED_PRO: "doubao-seed-pro";
114
- /**
115
- * Doubao Seed 1.6 Flash — ByteDance, via BytePlus (fast/cheap).
116
- */
117
- readonly DOUBAO_SEED_FLASH: "doubao-seed-flash";
118
- };
119
- /**
120
- * Provider → canonical models that provider can serve. Derived from
121
- * {@link MODEL_PROVIDER_IDS}; every provider currently serves at least one
122
- * model, so all {@link ProviderName} keys are present.
123
- */
124
- export declare const SUPPORTED_MODELS_BY_PROVIDER: Readonly<Record<ProviderName, readonly ModelName[]>>;
125
- /**
126
- * All upstream providers that can serve a model id, in declaration order.
127
- * Returns `[]` for an unknown model.
128
- */
129
- export declare function providersForModel(model: string): readonly ProviderName[];
130
- /**
131
- * The default upstream provider for a model id — the first provider declared
132
- * for it in {@link MODEL_PROVIDER_IDS}. Returns `undefined` when the input is
133
- * not a known {@link ModelName} (so the SDK can fall back to the default and let
134
- * the server reject the model).
135
- */
136
- export declare function providerForModel(model: string): ProviderName | undefined;
137
- /**
138
- * Translate a canonical model id + provider into the provider-native model
139
- * string the upstream API expects (e.g. `("gpt-4o-mini", "openrouter")` →
140
- * `"openai/gpt-4o-mini"`). Throws when the provider does not serve the model.
141
- */
142
- export declare function resolveProviderModelId(model: string, provider: ProviderName): string;
143
- /**
144
- * The single model→provider resolver shared by the SDK and the CLI, wrapping
145
- * {@link providersForModel} with the forward-compat unknown-model allowance:
146
- *
147
- * - `provider` given: it is honored. If `model` is a KNOWN id, the provider
148
- * must serve it (else throw). If `model` is UNKNOWN, it is allowed through
149
- * so a slightly-old client can still run a newly-launched model (the server
150
- * arbitrates).
151
- * - `provider` omitted: a known model resolves to its DEFAULT provider (first
152
- * declared). An UNKNOWN model with no provider throws a `did you mean?`
153
- * hint — you must name a provider to run a model this client doesn't know.
154
- *
155
- * Returns the resolved {@link ProviderName}.
156
- */
157
- export declare function resolveModelProvider(model: string, provider?: ProviderName): ProviderName;
158
- export declare function isModelName(input: unknown): input is ModelName;
159
- export declare function parseModelName(input: unknown, field?: string): ModelName;
160
- export declare function assertModelNameMatchesProvider(provider: ProviderName, model: ModelName, field?: string): void;
4
+ * There is no closed model set and no provider concept: a customer names any
5
+ * slug the managed gateway catalog serves (e.g. `anthropic/claude-haiku-4-5`,
6
+ * `deepseek/deepseek-v4-flash`) and the platform routes it through the single
7
+ * managed gateway key. Adding a catalog model is a ZERO-code change — the slug
8
+ * just works. The boundary validation is purely structural (see
9
+ * {@link parseModelSlug}); an unknown-but-well-formed slug is allowed through so
10
+ * a slightly-old client can still run a newly-launched model (the gateway
11
+ * arbitrates at submit time).
12
+ */
13
+ export type ModelName = string;
14
+ /**
15
+ * Structural gateway model-slug shape: a lowercase `creator`, a `/`, then the
16
+ * model segment. Matches Vercel AI Gateway `creator/model` slugs
17
+ * (e.g. `anthropic/claude-sonnet-4-6`, `openai/gpt-4.1`, `x-ai/grok-2`).
18
+ */
19
+ export declare const MODEL_SLUG_PATTERN: RegExp;
20
+ /** True when `input` is a structurally valid `creator/model` gateway slug. */
21
+ export declare function isModelSlug(input: unknown): input is string;
22
+ /**
23
+ * Validate a public model id as a gateway `creator/model` slug string. This is
24
+ * a boundary shape gate ONLY — it does not consult a catalog, so a well-formed
25
+ * slug the running client does not recognize is accepted (the gateway rejects a
26
+ * truly-absent model at submit time). Throws a {@link import("./contract-parse-error.js").ContractParseError}
27
+ * with `field` context on a malformed value.
28
+ */
29
+ export declare function parseModelSlug(input: unknown, field?: string): string;
@@ -1,196 +1,32 @@
1
- import { suggest } from "./suggest.js";
2
1
  import { rethrowContractParseError } from "./contract-parse-error.js";
3
2
  /**
4
- * Source of truth for the closed model set: each canonical model id maps to the
5
- * upstream providers that can serve it and the **provider-native** model string
6
- * each one expects.
7
- *
8
- * `Models.*` / `SUPPORTED_MODELS` are aex's own **canonical, provider-neutral**
9
- * identifiers — they are NOT the strings sent to a provider. The platform
10
- * translates a `(canonical model, provider)` pair to the native id via
11
- * {@link resolveProviderModelId} when it builds the session's session manifest. The
12
- * same canonical model can therefore be served by more than one provider (e.g.
13
- * `gpt-4o-mini` via `openai` *or* `openrouter`), with a different native string
14
- * per provider.
15
- *
16
- * Ordering matters: the **first** provider listed for a model is its default
17
- * (see {@link providerForModel}) — list the native vendor before `openrouter`.
18
- * Additions belong here first so SDK types, CLI validation, docs examples, and
19
- * platform parsing all move together.
3
+ * Structural gateway model-slug shape: a lowercase `creator`, a `/`, then the
4
+ * model segment. Matches Vercel AI Gateway `creator/model` slugs
5
+ * (e.g. `anthropic/claude-sonnet-4-6`, `openai/gpt-4.1`, `x-ai/grok-2`).
20
6
  */
21
- export const MODEL_PROVIDER_IDS = {
22
- "claude-haiku-4-5": { anthropic: "claude-haiku-4-5" },
23
- "claude-3-5-haiku-latest": { anthropic: "claude-3-5-haiku-latest" },
24
- "claude-3-5-sonnet-latest": { anthropic: "claude-3-5-sonnet-latest" },
25
- "claude-sonnet-4-6": { anthropic: "claude-sonnet-4-6" },
26
- "deepseek-v4-flash": { deepseek: "deepseek-v4-flash" },
27
- "deepseek-v4-pro": { deepseek: "deepseek-v4-pro" },
28
- "gpt-4.1": { openai: "gpt-4.1" },
29
- "gpt-4o-mini": { openai: "gpt-4o-mini", openrouter: "openai/gpt-4o-mini" },
30
- "gpt-4o": { openrouter: "openai/gpt-4o" },
31
- "gemini-2.0-flash": { openrouter: "google/gemini-2.0-flash-001" },
32
- "gemini-2.5-flash": { gemini: "gemini-2.5-flash" },
33
- "mistral-large-latest": { mistral: "mistral-large-latest" },
34
- "mistral-small-latest": { mistral: "mistral-small-latest" },
35
- // Doubao (ByteDance) via the official international BytePlus ModelArk API.
36
- // Ark accepts the API-format model NAME directly in the chat-completions
37
- // `model` field (no `ep-…` inference-endpoint id).
38
- // pro — Doubao Seed 1.8 (flagship, 256K context).
39
- // flash — Doubao Seed 1.6 Flash (fast/cheap, 256K context).
40
- "doubao-seed-pro": { doubao: "doubao-seed-1-8-251228" },
41
- "doubao-seed-flash": { doubao: "doubao-seed-1-6-flash-250828" }
42
- };
43
- export const SUPPORTED_MODELS = Object.keys(MODEL_PROVIDER_IDS);
44
- /**
45
- * Symbol-style accessors for the closed model set. Prefer these over raw
46
- * strings so an invalid token is a compile error, not a runtime 400 — e.g.
47
- * `Models.CLAUDE_HAIKU_4_5`. These are aex's **canonical** ids, not the native
48
- * strings sent upstream; the platform translates them per provider (see
49
- * {@link MODEL_PROVIDER_IDS} / {@link resolveProviderModelId}). When a model is
50
- * served by more than one provider, pair it with an explicit {@link Providers}
51
- * value; otherwise the single (default) provider is used.
52
- */
53
- export const Models = {
54
- /** Claude Haiku 4.5 — Anthropic. */
55
- CLAUDE_HAIKU_4_5: "claude-haiku-4-5",
56
- /** Claude 3.5 Haiku (latest) — Anthropic. */
57
- CLAUDE_3_5_HAIKU_LATEST: "claude-3-5-haiku-latest",
58
- /** Claude 3.5 Sonnet (latest) — Anthropic. */
59
- CLAUDE_3_5_SONNET_LATEST: "claude-3-5-sonnet-latest",
60
- /** Claude Sonnet 4.6 — Anthropic (1M context, reasoning-capable). */
61
- CLAUDE_SONNET_4_6: "claude-sonnet-4-6",
62
- /** DeepSeek V4 Flash — DeepSeek (non-thinking, fast). */
63
- DEEPSEEK_V4_FLASH: "deepseek-v4-flash",
64
- /** DeepSeek V4 Pro — DeepSeek (reasoning-heavy). */
65
- DEEPSEEK_V4_PRO: "deepseek-v4-pro",
66
- /** GPT-4.1 — OpenAI. */
67
- GPT_4_1: "gpt-4.1",
68
- /** GPT-4o mini — OpenAI, or via OpenRouter (`provider: Providers.OPENROUTER`). */
69
- GPT_4O_MINI: "gpt-4o-mini",
70
- /** GPT-4o — via OpenRouter (`provider: Providers.OPENROUTER`). */
71
- GPT_4O: "gpt-4o",
72
- /** Gemini 2.0 Flash — via OpenRouter (`provider: Providers.OPENROUTER`). */
73
- GEMINI_2_0_FLASH: "gemini-2.0-flash",
74
- /** Gemini 2.5 Flash — Gemini. */
75
- GEMINI_2_5_FLASH: "gemini-2.5-flash",
76
- /** Mistral Large (latest) — Mistral. */
77
- MISTRAL_LARGE_LATEST: "mistral-large-latest",
78
- /** Mistral Small (latest) — Mistral. */
79
- MISTRAL_SMALL_LATEST: "mistral-small-latest",
80
- /**
81
- * Doubao Seed 1.8 — ByteDance, via the international BytePlus gateway.
82
- */
83
- DOUBAO_SEED_PRO: "doubao-seed-pro",
84
- /**
85
- * Doubao Seed 1.6 Flash — ByteDance, via BytePlus (fast/cheap).
86
- */
87
- DOUBAO_SEED_FLASH: "doubao-seed-flash"
88
- };
89
- /**
90
- * Per-model provider lists, in declaration order. Derived from
91
- * {@link MODEL_PROVIDER_IDS} so the two never drift.
92
- */
93
- const PROVIDERS_BY_MODEL = (() => {
94
- const map = {};
95
- for (const [model, providers] of Object.entries(MODEL_PROVIDER_IDS)) {
96
- map[model] = Object.keys(providers);
97
- }
98
- return map;
99
- })();
100
- /**
101
- * Provider → canonical models that provider can serve. Derived from
102
- * {@link MODEL_PROVIDER_IDS}; every provider currently serves at least one
103
- * model, so all {@link ProviderName} keys are present.
104
- */
105
- export const SUPPORTED_MODELS_BY_PROVIDER = (() => {
106
- const map = {};
107
- for (const [model, providers] of Object.entries(MODEL_PROVIDER_IDS)) {
108
- for (const provider of Object.keys(providers)) {
109
- (map[provider] ??= []).push(model);
110
- }
111
- }
112
- return map;
113
- })();
114
- /**
115
- * All upstream providers that can serve a model id, in declaration order.
116
- * Returns `[]` for an unknown model.
117
- */
118
- export function providersForModel(model) {
119
- return PROVIDERS_BY_MODEL[model] ?? [];
120
- }
121
- /**
122
- * The default upstream provider for a model id — the first provider declared
123
- * for it in {@link MODEL_PROVIDER_IDS}. Returns `undefined` when the input is
124
- * not a known {@link ModelName} (so the SDK can fall back to the default and let
125
- * the server reject the model).
126
- */
127
- export function providerForModel(model) {
128
- return providersForModel(model)[0];
7
+ export const MODEL_SLUG_PATTERN = /^[a-z0-9-]+\/[A-Za-z0-9._:-]+$/;
8
+ /** True when `input` is a structurally valid `creator/model` gateway slug. */
9
+ export function isModelSlug(input) {
10
+ return typeof input === "string" && MODEL_SLUG_PATTERN.test(input);
129
11
  }
130
12
  /**
131
- * Translate a canonical model id + provider into the provider-native model
132
- * string the upstream API expects (e.g. `("gpt-4o-mini", "openrouter")`
133
- * `"openai/gpt-4o-mini"`). Throws when the provider does not serve the model.
13
+ * Validate a public model id as a gateway `creator/model` slug string. This is
14
+ * a boundary shape gate ONLY it does not consult a catalog, so a well-formed
15
+ * slug the running client does not recognize is accepted (the gateway rejects a
16
+ * truly-absent model at submit time). Throws a {@link import("./contract-parse-error.js").ContractParseError}
17
+ * with `field` context on a malformed value.
134
18
  */
135
- export function resolveProviderModelId(model, provider) {
136
- const entry = MODEL_PROVIDER_IDS[model];
137
- const native = entry?.[provider];
138
- if (native === undefined) {
139
- throw new Error(`resolveProviderModelId: model ${JSON.stringify(model)} is not available for provider ${JSON.stringify(provider)}; ` +
140
- `available: ${providersForModel(model).join(", ") || "(none)"}`);
141
- }
142
- return native;
143
- }
144
- /**
145
- * The single model→provider resolver shared by the SDK and the CLI, wrapping
146
- * {@link providersForModel} with the forward-compat unknown-model allowance:
147
- *
148
- * - `provider` given: it is honored. If `model` is a KNOWN id, the provider
149
- * must serve it (else throw). If `model` is UNKNOWN, it is allowed through
150
- * so a slightly-old client can still run a newly-launched model (the server
151
- * arbitrates).
152
- * - `provider` omitted: a known model resolves to its DEFAULT provider (first
153
- * declared). An UNKNOWN model with no provider throws a `did you mean?`
154
- * hint — you must name a provider to run a model this client doesn't know.
155
- *
156
- * Returns the resolved {@link ProviderName}.
157
- */
158
- export function resolveModelProvider(model, provider) {
159
- const providers = providersForModel(model);
160
- if (provider !== undefined) {
161
- if (providers.length > 0 && !providers.includes(provider)) {
162
- throw new Error(`model ${JSON.stringify(model)} is not available for provider ${provider}; ` +
163
- `available: ${providers.join(", ")}`);
164
- }
165
- return provider;
166
- }
167
- const inferred = providers[0];
168
- if (inferred === undefined) {
169
- const hint = suggest(model, SUPPORTED_MODELS);
170
- throw new Error(`${JSON.stringify(model)} is not a known model id` +
171
- (hint ? ` (did you mean ${JSON.stringify(hint)}?)` : "") +
172
- "; pass provider explicitly to run it");
173
- }
174
- return inferred;
175
- }
176
- export function isModelName(input) {
177
- return typeof input === "string" && SUPPORTED_MODELS.includes(input);
178
- }
179
- export function parseModelName(input, field = "submission.model") {
19
+ export function parseModelSlug(input, field = "submission.model") {
180
20
  try {
181
- if (!isModelName(input)) {
182
- throw new Error(`${field} must be one of: ${SUPPORTED_MODELS.join(", ")}`);
21
+ if (typeof input !== "string" || input.length === 0) {
22
+ throw new Error(`${field} must be a non-empty gateway model slug string ("creator/model")`);
23
+ }
24
+ if (!MODEL_SLUG_PATTERN.test(input)) {
25
+ throw new Error(`${field} must be a gateway model slug of the form "creator/model" matching ${MODEL_SLUG_PATTERN.source} (got ${JSON.stringify(input)})`);
183
26
  }
184
27
  return input;
185
28
  }
186
29
  catch (error) {
187
- rethrowContractParseError(error, "parseModelName");
188
- }
189
- }
190
- export function assertModelNameMatchesProvider(provider, model, field = "submission.model") {
191
- const providers = providersForModel(model);
192
- if (!providers.includes(provider)) {
193
- throw new Error(`${field} ${JSON.stringify(model)} is not supported for provider ${provider}; ` +
194
- `expected one of: ${providers.join(", ")}`);
30
+ rethrowContractParseError(error, "parseModelSlug");
195
31
  }
196
32
  }
@@ -3,7 +3,7 @@ import type { RuntimeSize } from "./runtime-sizes.js";
3
3
  import type { RuntimeKind } from "./runtime-kind.js";
4
4
  import type { SessionCostProviderUsage } from "./session-cost.js";
5
5
  import type { ProviderFault } from "./provider-fault.js";
6
- import type { PlatformInlineSecrets, PlatformSubmission, ProviderName, SessionLimits, SessionWebhookSpec } from "./submission.js";
6
+ import type { PlatformInlineSecrets, PlatformSubmission, SessionLimits, SessionWebhookSpec } from "./submission.js";
7
7
  /** Public run phases. Internal finalization remains behind the consistency barrier. */
8
8
  export declare const SESSION_RUN_PHASES: readonly ["queued", "starting", "running", "finished", "error"];
9
9
  export type SessionRunPhase = (typeof SESSION_RUN_PHASES)[number];
@@ -114,7 +114,6 @@ export type SessionSubmission = Omit<PlatformSubmission, "prompt"> & {
114
114
  readonly prompt?: readonly string[];
115
115
  };
116
116
  export interface SessionCreateRequest {
117
- readonly provider: ProviderName;
118
117
  readonly submission: SessionSubmission;
119
118
  readonly runtimeSize?: RuntimeSize;
120
119
  readonly runtimeKind?: RuntimeKind;
@@ -30,7 +30,7 @@
30
30
  * boundary.
31
31
  */
32
32
  import { rethrowContractParseError, withContractParseError } from "./contract-parse-error.js";
33
- import { parseModelName } from "./models.js";
33
+ import { parseModelSlug } from "./models.js";
34
34
  import { assertAllowedKeys, defineAllowedKeys } from "./allowed-keys.js";
35
35
  // ---------------------------------------------------------------------------
36
36
  // Skill ID + name format
@@ -630,7 +630,7 @@ export function parseSessionRequestConfig(input) {
630
630
  const record = input;
631
631
  const allowed = defineAllowedKeys()("model", "system", "prompt", "mcpServers", "environment", "runtimeSize", "timeout", "metadata");
632
632
  assertAllowedKeys(record, allowed, (key) => new Error(`session request config contains unexpected field: ${key}`));
633
- const model = parseModelName(record.model, "session request config model");
633
+ const model = parseModelSlug(record.model, "session request config model");
634
634
  const system = record.system;
635
635
  if (system !== undefined && typeof system !== "string") {
636
636
  throw new Error("session request config system, when provided, must be a string");
@@ -96,58 +96,27 @@ export interface PlatformPackageInput {
96
96
  */
97
97
  export declare function packageInstallString(pkg: PlatformPackage): string;
98
98
  /**
99
- * Submission-time provider selector. Aex exposes one customer interface
100
- * for every provider. All new submissions execute through the managed
101
- * runtime; provider selection only decides which upstream model route
102
- * the managed provider-proxy uses.
103
- */
104
- export declare const PROVIDERS: readonly ["anthropic", "deepseek", "openai", "gemini", "mistral", "openrouter", "doubao"];
105
- export type ProviderName = (typeof PROVIDERS)[number];
106
- export declare const DEFAULT_PROVIDER: ProviderName;
107
- /**
108
- * Symbol-style accessors for the closed provider set. Prefer these over raw
109
- * strings so an invalid token is a compile error, not a runtime 400 — e.g.
110
- * `Providers.DEEPSEEK`. The same model id can route through different upstream
111
- * providers (official vs OpenRouter, etc.), so `provider` is a first-class
112
- * submission field; name it explicitly with one of these constants rather than
113
- * relying on the model alone to determine routing.
114
- *
115
- * Every value mirrors {@link PROVIDERS} exactly; a unit test asserts
116
- * `Object.values(Providers)` deep-equals `PROVIDERS` so the two can never
117
- * drift.
118
- */
119
- export declare const Providers: {
120
- /** Anthropic — Claude models. */
121
- readonly ANTHROPIC: "anthropic";
122
- /** DeepSeek. */
123
- readonly DEEPSEEK: "deepseek";
124
- /** OpenAI — GPT models. */
125
- readonly OPENAI: "openai";
126
- /** Google Gemini. */
127
- readonly GEMINI: "gemini";
128
- /** Mistral. */
129
- readonly MISTRAL: "mistral";
130
- /** OpenRouter — OpenAI-compatible aggregator routing to many upstream models. */
131
- readonly OPENROUTER: "openrouter";
132
- /** Doubao (ByteDance) via the official international BytePlus ModelArk gateway. */
133
- readonly DOUBAO: "doubao";
134
- };
99
+ * A serving-provider label. Under the managed Vercel AI Gateway there is NO
100
+ * public provider selector and no closed provider set routing is the
101
+ * gateway's job. This thin alias survives only because telemetry / cost /
102
+ * custody records still carry the *serving provider string* reported by the
103
+ * gateway's generation info (e.g. `"anthropic"`, `"deepseek"`); it is an open
104
+ * string, never a customer input.
105
+ */
106
+ export type ProviderName = string;
135
107
  export interface PlatformMcpServerSecret {
136
108
  readonly name: string;
137
109
  readonly url: string;
138
110
  readonly headers?: Record<string, string>;
139
111
  }
140
112
  /**
141
- * Per-session inline secrets bundle. `apiKeys` holds the BYOK provider keys, keyed
142
- * by {@link ProviderName}. A session REQUIRES a key for its own `provider`; it MAY
143
- * carry keys for additional providers so a subagent spawned with a
144
- * different-family model inherits them server-side from the vault (the keys
145
- * never transit the container). `mcpServers` credentials are cross-provider
146
- * (an MCP credential is the same secret whichever model is driving the MCP
147
- * client).
113
+ * Per-session inline secrets bundle. Under managed gateway keys the customer
114
+ * supplies NO provider API keys the platform's single managed gateway key
115
+ * routes all model traffic. This bundle carries only non-LLM secret material:
116
+ * `mcpServers` credentials (an MCP credential is the same secret whichever
117
+ * model is driving the MCP client) and per-session `envSecrets`.
148
118
  */
149
119
  export interface PlatformInlineSecrets {
150
- readonly apiKeys?: Partial<Record<ProviderName, string>>;
151
120
  readonly mcpServers?: readonly PlatformMcpServerSecret[];
152
121
  /**
153
122
  * Per-session env-var secret VALUES, keyed by env name. Each entry pairs with a
@@ -239,10 +208,8 @@ export interface PlatformSubmission {
239
208
  /**
240
209
  * Assistant-output granularity. `buffered` (the default) emits one event per
241
210
  * assistant message; `stream` emits the agent's per-token text deltas as they
242
- * arrive, THEN a final coalesced block. Streaming is CAPABILITY-GATED: it is
243
- * only honored for a streamable provider (see {@link STREAMABLE_SHAPES}) and a
244
- * `stream` mode on a non-streamable provider is rejected at parse
245
- * ({@link assertStreamableOutputMode}) — no silent downgrade.
211
+ * arrive, THEN a final coalesced block. Every model streams through the
212
+ * managed gateway, so `stream` is honored for ALL models.
246
213
  */
247
214
  readonly outputMode?: OutputMode;
248
215
  /**
@@ -303,12 +270,6 @@ export interface PlatformInjectionConfig {
303
270
  export interface PlatformSessionSubmissionRequest {
304
271
  readonly workspaceId: string;
305
272
  readonly idempotencyKey: string;
306
- /**
307
- * Provider selector. Always populated after parsing — absent on the
308
- * wire means {@link DEFAULT_PROVIDER}. All providers are dispatched
309
- * through the managed runtime.
310
- */
311
- readonly provider: ProviderName;
312
273
  readonly submission: PlatformSubmission;
313
274
  readonly secrets: PlatformInlineSecrets;
314
275
  /**
@@ -417,9 +378,8 @@ export interface SessionMachine {
417
378
  * This type remains available from `@aexhq/contracts/internal` for platform
418
379
  * consumers and is intentionally absent from the public contracts barrel.
419
380
  */
420
- export type PlatformSessionSubmissionInput = Omit<PlatformSessionSubmissionRequest, "workspaceId" | "provider" | "timeoutMs"> & {
381
+ export type PlatformSessionSubmissionInput = Omit<PlatformSessionSubmissionRequest, "workspaceId" | "timeoutMs"> & {
421
382
  readonly workspaceId?: string;
422
- readonly provider?: ProviderName;
423
383
  /**
424
384
  * Session deadline as a human duration string (`"1h"`, `"90m"`, `"30s"`).
425
385
  * Parsed + bounded to [1m, 8h] server-side into
@@ -475,43 +435,11 @@ export declare function sessionBudgetLimits(limits: SessionLimits | undefined):
475
435
  * shape is validated here — capacity selection is a runtime concern.
476
436
  */
477
437
  export declare function parseSessionMachine(input: unknown): SessionMachine | undefined;
478
- export declare function parseProviderName(input: unknown): ProviderName;
479
- /**
480
- * Cross-check the supplied secrets bundle against the credential mode. BYOK
481
- * requires `secrets.apiKeys[provider]` (the key for the session's own `provider`).
482
- * Additional provider keys are optional (validated for shape only) so the session
483
- * can supply keys for the other providers its subagents may use. MCP / proxy
484
- * endpoint auth carry across providers and are not checked here.
485
- *
486
- * A CHILD session (`inheritsFromParent`) is exempt from the own-key requirement: it
487
- * inherits its provider keys server-side from the parent's vaulted bundle, so
488
- * it need not carry any of its own. The server still verifies, at admission,
489
- * that the parent actually holds a key for the child's provider.
490
- */
491
- export declare function enforceCredentialSecretPolicy(secrets: PlatformInlineSecrets, provider: ProviderName, opts?: {
492
- readonly inheritsFromParent?: boolean;
493
- }): void;
494
438
  export declare function parseSubmission(input: unknown): PlatformSubmission;
495
439
  /** Assistant-output granularity values. Buffered is the platform default. */
496
440
  export declare const OUTPUT_MODES: readonly ["buffered", "stream"];
497
441
  export type OutputMode = (typeof OUTPUT_MODES)[number];
498
442
  export declare const DEFAULT_OUTPUT_MODE: OutputMode;
499
- /**
500
- * The provider wire-SHAPES that have a real per-token streaming producer. This
501
- * const is the contracts-side SSoT, pinned EQUAL to the platform's shape SSoT by
502
- * a cross-repo parity test so streaming can never be promised for a shape
503
- * nothing feeds.
504
- */
505
- export declare const STREAMABLE_SHAPES: readonly ["anthropic", "openai_chat"];
506
- export type StreamableShape = (typeof STREAMABLE_SHAPES)[number];
507
- /** True when a provider has a streaming producer wired (a {@link STREAMABLE_SHAPES} shape). */
508
- export declare function isStreamableProvider(provider: ProviderName): boolean;
509
- /**
510
- * Fail-closed streaming gate: `outputMode:'stream'` on a NON-streamable provider
511
- * throws (a HARD reject — no silent downgrade to buffered). Called by
512
- * {@link parseSessionSubmissionRequest} once mode + provider are both known.
513
- */
514
- export declare function assertStreamableOutputMode(outputMode: OutputMode | undefined, provider: ProviderName): void;
515
443
  /** Response-format kinds: free-form `text` (default) or provider-native `json_schema`. */
516
444
  export declare const RESPONSE_FORMAT_KINDS: readonly ["text", "json_schema"];
517
445
  export type ResponseFormatKind = (typeof RESPONSE_FORMAT_KINDS)[number];