@agent-native/core 0.202.0 → 0.202.1-nightly-20261007011022
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/agent/actions/list-model-providers.d.ts +2 -0
- package/dist/agent/actions/list-model-providers.js +32 -5
- package/dist/agent/actions/manage-provider-models.d.ts +1 -0
- package/dist/agent/engine/builder-engine.d.ts +1 -1
- package/dist/agent/engine/builtin.js +1 -1
- package/dist/agent/engine/index.d.ts +1 -1
- package/dist/agent/engine/index.js +1 -1
- package/dist/agent/engine/registry.d.ts +2 -0
- package/dist/agent/engine/registry.js +63 -47
- package/dist/agent/model-config.d.ts +6 -6
- package/dist/agent/model-config.js +7 -11
- package/dist/agent/model-version.d.ts +3 -0
- package/dist/agent/model-version.js +67 -0
- package/dist/agent/provider-model-selection.d.ts +6 -1
- package/dist/agent/provider-model-selection.js +131 -13
- package/dist/automation/index.d.ts +1 -1
- package/dist/cli/create.d.ts +2 -1
- package/dist/cli/create.js +17 -4
- package/dist/cli/template-sync.js +2 -1
- package/dist/cli/workspacify.d.ts +1 -0
- package/dist/cli/workspacify.js +4 -0
- package/dist/client/app-config.d.ts +1 -0
- package/dist/client/app-config.js +19 -0
- package/dist/client/chat/agentkit-protocol.js +122 -16
- package/dist/client/chat/runtime.js +943 -50
- package/dist/client/chat-model-groups.d.ts +1 -0
- package/dist/client/chat-model-groups.js +1 -0
- package/dist/client/use-chat-models.js +47 -6
- package/dist/deploy/build.js +23 -9
- package/dist/email-catalog/redact-body.js +1 -1
- package/dist/jobs/actions/manage-recurring-job.d.ts +1 -1
- package/dist/jobs/background-automation-runner.d.ts +3 -1
- package/dist/jobs/background-automation-runner.js +15 -8
- package/dist/jobs/scheduler.js +1 -1
- package/dist/mcp/build-server.d.ts +0 -1
- package/dist/mcp/build-server.js +10 -59
- package/dist/observability/routes.d.ts +6 -6
- package/dist/onboarding/app-profile-data.d.ts +10 -0
- package/dist/onboarding/app-profile-data.js +423 -0
- package/dist/onboarding/app-profile.d.ts +1 -7
- package/dist/onboarding/app-profile.js +5 -422
- package/dist/onboarding/index.d.ts +1 -0
- package/dist/onboarding/index.js +1 -0
- package/dist/org/handlers.d.ts +1 -1
- package/dist/org/index.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +2 -2
- package/dist/provider-api/actions/provider-api.d.ts +10 -10
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/scripts/agent-engines/manage-agent-engine.js +1 -1
- package/dist/scripts/agent-engines/set-agent-engine.js +1 -1
- package/dist/secrets/routes.d.ts +11 -11
- package/dist/server/action-routes.js +1 -0
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/app-origin-config.d.ts +2 -0
- package/dist/server/app-origin-config.js +4 -0
- package/dist/server/auth.js +43 -1
- package/dist/server/better-auth-instance.js +7 -12
- package/dist/server/email-auth-links.d.ts +11 -0
- package/dist/server/email-auth-links.js +126 -0
- package/dist/server/fusion-app.js +11 -1
- package/dist/shared/agent-chat-context.d.ts +3 -3
- package/dist/shared/agent-chat-context.js +2 -2
- package/dist/shared/auth-copy.d.ts +3 -0
- package/dist/shared/auth-copy.js +33 -0
- package/dist/shared/design-system-agent-context.d.ts +5 -0
- package/dist/shared/design-system-agent-context.js +37 -8
- package/dist/shared/index.d.ts +1 -1
- package/dist/triggers/actions/manage-automation.d.ts +7 -7
- package/dist/triggers/condition-evaluator.d.ts +21 -5
- package/dist/triggers/condition-evaluator.js +113 -59
- package/dist/triggers/dispatcher.js +39 -21
- package/dist/vite/client.js +10 -0
- package/docs/content/durable-resume.mdx +9 -3
- package/package.json +5 -3
|
@@ -29,6 +29,8 @@ export interface ModelProviderKey {
|
|
|
29
29
|
export interface ModelProviderEntry {
|
|
30
30
|
provider: AgentProviderId;
|
|
31
31
|
label: string;
|
|
32
|
+
/** A usable deployment fallback when no saved key at the default-model scope takes precedence. */
|
|
33
|
+
deploymentConfigured: boolean;
|
|
32
34
|
/** The organization's key, or null when it has none. */
|
|
33
35
|
org: ModelProviderKey | null;
|
|
34
36
|
/** The caller's own key, or null when they have none. */
|
|
@@ -7,6 +7,8 @@ import { readAppSecrets, } from "../../secrets/storage.js";
|
|
|
7
7
|
import { readProviderCredentialRejections } from "../../server/credential-provider.js";
|
|
8
8
|
import { isPersonalProviderKeyUseRestricted, readOrgMemberRole, } from "../../server/personal-provider-key-policy.js";
|
|
9
9
|
import { readDefaultAgentEngineSettingDetailed, resolveDefaultAgentEngineAuthority, } from "../default-agent-engine.js";
|
|
10
|
+
import { registerBuiltinEngines } from "../engine/builtin.js";
|
|
11
|
+
import { getAgentEngineEntry, isDeploymentEngineUsableForRequest, } from "../engine/registry.js";
|
|
10
12
|
function providerKeyNames() {
|
|
11
13
|
return AGENT_PROVIDER_CATALOG.map((option) => {
|
|
12
14
|
if (option.id === "ollama") {
|
|
@@ -49,8 +51,12 @@ async function readScopeKeys(scope, scopeId, reveal) {
|
|
|
49
51
|
const sources = storedRowsFor(scope, scopeId);
|
|
50
52
|
const reads = await Promise.all(sources.map((source) => readAppSecrets({ keys, ...source })));
|
|
51
53
|
const found = [];
|
|
54
|
+
const endpointProviders = new Set();
|
|
52
55
|
for (const entry of names) {
|
|
53
56
|
for (const [index, rows] of reads.entries()) {
|
|
57
|
+
if (entry.endpoint && firstPresent(rows, [entry.endpoint])) {
|
|
58
|
+
endpointProviders.add(entry.option.id);
|
|
59
|
+
}
|
|
54
60
|
const row = firstPresent(rows, entry.primary);
|
|
55
61
|
if (!row)
|
|
56
62
|
continue;
|
|
@@ -98,7 +104,7 @@ async function readScopeKeys(scope, scopeId, reveal) {
|
|
|
98
104
|
...(legacy ? { legacyWorkspaceRow: true } : {}),
|
|
99
105
|
});
|
|
100
106
|
}
|
|
101
|
-
return result;
|
|
107
|
+
return { keys: result, endpointProviders };
|
|
102
108
|
}
|
|
103
109
|
export default defineAction({
|
|
104
110
|
description: "List the model providers on Settings › Model: for each provider (OpenRouter, Ollama, Anthropic, OpenAI, Google Gemini, Groq, Mistral, Cohere), the organization's key and the caller's personal key, masked, with the endpoint URL saved for Ollama or an OpenAI-compatible gateway and when the provider rejected the key (rejectedAt: chats that use it stop until someone replaces it). Members see only that an organization key exists, not its mask. A key in a legacy workspace row (the organization's, or the caller's pre-organization solo row) lists at the scope chats resolve it as, marked legacyWorkspaceRow; removing the provider at that scope deletes it. Also returns whether the caller can manage organization providers, whether personal API keys are restricted for them (their personal keys are then stored but unused), and the stored default model. Builder.io connections come from the Builder.io status, not here. Never returns a key value. Related: get-provider-models and manage-provider-models (which models each provider shows), manage-agent-engine (the default model), manage-provider-key-policy (Restrict personal API keys), preview-secret-removal (what removing a key stops).",
|
|
@@ -112,17 +118,37 @@ export default defineAction({
|
|
|
112
118
|
const orgId = ctx?.orgId?.trim() || null;
|
|
113
119
|
const role = orgId ? await readOrgMemberRole(orgId, email) : null;
|
|
114
120
|
const manages = orgId ? canManageOrg(role) : false;
|
|
115
|
-
|
|
121
|
+
registerBuiltinEngines();
|
|
122
|
+
const [personal, org, restricted, defaultRead, authority, deploymentStates,] = await Promise.all([
|
|
116
123
|
readScopeKeys("user", email, true),
|
|
117
124
|
orgId
|
|
118
125
|
? readScopeKeys("org", orgId, manages)
|
|
119
|
-
: Promise.resolve(
|
|
126
|
+
: Promise.resolve({
|
|
127
|
+
keys: new Map(),
|
|
128
|
+
endpointProviders: new Set(),
|
|
129
|
+
}),
|
|
120
130
|
orgId
|
|
121
131
|
? isPersonalProviderKeyUseRestricted({ email, orgId, role })
|
|
122
132
|
: Promise.resolve(false),
|
|
123
133
|
readDefaultAgentEngineSettingDetailed({ userEmail: email, orgId }),
|
|
124
134
|
resolveDefaultAgentEngineAuthority({ userEmail: email, orgId }),
|
|
135
|
+
Promise.all(AGENT_PROVIDER_CATALOG.map(async (option) => {
|
|
136
|
+
const engine = getAgentEngineEntry(option.engine);
|
|
137
|
+
return [
|
|
138
|
+
option.id,
|
|
139
|
+
engine ? await isDeploymentEngineUsableForRequest(engine) : false,
|
|
140
|
+
];
|
|
141
|
+
})),
|
|
125
142
|
]);
|
|
143
|
+
const deploymentConfigured = new Map(deploymentStates.map(([provider, configured]) => {
|
|
144
|
+
const defaultScope = orgId ? org : personal;
|
|
145
|
+
return [
|
|
146
|
+
provider,
|
|
147
|
+
configured &&
|
|
148
|
+
!defaultScope.keys.has(provider) &&
|
|
149
|
+
!defaultScope.endpointProviders.has(provider),
|
|
150
|
+
];
|
|
151
|
+
}));
|
|
126
152
|
const stored = defaultRead.value;
|
|
127
153
|
const engine = typeof stored?.engine === "string" && stored.engine.trim()
|
|
128
154
|
? stored.engine.trim()
|
|
@@ -134,8 +160,9 @@ export default defineAction({
|
|
|
134
160
|
providers: AGENT_PROVIDER_CATALOG.map((option) => ({
|
|
135
161
|
provider: option.id,
|
|
136
162
|
label: option.label,
|
|
137
|
-
|
|
138
|
-
|
|
163
|
+
deploymentConfigured: deploymentConfigured.get(option.id) ?? false,
|
|
164
|
+
org: org.keys.get(option.id) ?? null,
|
|
165
|
+
personal: personal.keys.get(option.id) ?? null,
|
|
139
166
|
})),
|
|
140
167
|
hasOrganization: !!orgId,
|
|
141
168
|
canManageOrg: manages,
|
|
@@ -8,6 +8,7 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
8
8
|
provider: ProviderModelSelectionProvider;
|
|
9
9
|
scope: ProviderModelSelectionScope;
|
|
10
10
|
models: string[] | null;
|
|
11
|
+
preserveCustomModels?: boolean;
|
|
11
12
|
updatedAt?: number;
|
|
12
13
|
updatedBy?: string;
|
|
13
14
|
recommendedModels: string[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type BuilderGatewayLane } from "../../server/credential-provider.js";
|
|
2
2
|
import type { AgentEngine, EngineCapabilities } from "./types.js";
|
|
3
3
|
export declare const BUILDER_CAPABILITIES: EngineCapabilities;
|
|
4
|
-
export declare const BUILDER_SUPPORTED_MODELS: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "grok-code-fast", "qwen3-coder", "kimi-k2-5", "deepseek-v4-pro", "deepseek-v3-1", "z-ai-glm-4-5", "z-ai-glm-5-1"];
|
|
4
|
+
export declare const BUILDER_SUPPORTED_MODELS: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6.1-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "grok-code-fast", "qwen3-coder", "kimi-k2-5", "deepseek-v4-pro", "deepseek-v3-1", "z-ai-glm-4-5", "z-ai-glm-5-1"];
|
|
5
5
|
export declare const BUILDER_MODEL_UNAUTHORIZED_ERROR_CODE = "builder_model_unauthorized";
|
|
6
6
|
/**
|
|
7
7
|
* A truncated stream, not a rejected request: the client continues the partial
|
|
@@ -30,7 +30,7 @@ const providerLabels = {
|
|
|
30
30
|
const providerDescriptions = {
|
|
31
31
|
anthropic: "Claude models through the Vercel AI SDK. Supports thinking and caching via AI SDK providerOptions.",
|
|
32
32
|
openai: "OpenAI GPT models via the Vercel AI SDK. Requires OPENAI_API_KEY.",
|
|
33
|
-
openrouter: "300+ models from Anthropic, OpenAI, Google, Z.ai, and more routed through a single endpoint. Use model IDs like 'anthropic/claude-sonnet-5.5', 'openai/gpt-6-sol', or 'z-ai/glm-5.2'. Requires OPENROUTER_API_KEY.",
|
|
33
|
+
openrouter: "300+ models from Anthropic, OpenAI, Google, Z.ai, and more routed through a single endpoint. Use model IDs like 'anthropic/claude-sonnet-5.5', 'openai/gpt-6.1-sol', or 'z-ai/glm-5.2'. Requires OPENROUTER_API_KEY.",
|
|
34
34
|
google: "Google Gemini models via the Vercel AI SDK. Requires GOOGLE_GENERATIVE_AI_API_KEY.",
|
|
35
35
|
groq: "Groq LPU inference via the Vercel AI SDK. Requires GROQ_API_KEY.",
|
|
36
36
|
mistral: "Mistral models via the Vercel AI SDK. Requires MISTRAL_API_KEY.",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { AgentEngine, EngineCapabilities, EngineTool, EngineMessage, EngineContentPart, EngineTextPart, EngineImagePart, EngineToolCallPart, EngineToolResultPart, EngineThinkingPart, EngineEvent, EngineStreamOptions, } from "./types.js";
|
|
2
|
-
export { registerAgentEngine, getAgentEngineEntry, listAgentEngines, resolveEngine, explicitEngineName, getConfiguredEngineNameForRequest, getStoredModelForEngine, normalizeModelForEngine, resolveDelegatedRunModel, resolveEngineAcceptsCustomModels, resolveEnginePreservesCustomModels, type NormalizeModelOptions, detectEngineFromEnv, detectEngineFromEnvForRequest, detectEngineFromUserSecrets, isAgentEngineSettingConfigured, isAgentEnginePackageInstalled, isStoredEngineUsable, isStoredEngineUsableForRequest, isResolvedEngineUsableForRequest, type AgentEngineEntry, type ResolveEngineConfig, } from "./registry.js";
|
|
2
|
+
export { registerAgentEngine, getAgentEngineEntry, listAgentEngines, resolveEngine, explicitEngineName, getConfiguredEngineNameForRequest, getStoredModelForEngine, normalizeModelForEngine, resolveDelegatedRunModel, resolveEngineAcceptsCustomModels, resolveEnginePreservesCustomModels, type NormalizeModelOptions, detectEngineFromEnv, detectEngineFromEnvForRequest, detectEngineFromUserSecrets, isAgentEngineSettingConfigured, isAgentEnginePackageInstalled, isDeploymentEngineUsableForRequest, isStoredEngineUsable, isStoredEngineUsableForRequest, isResolvedEngineUsableForRequest, type AgentEngineEntry, type ResolveEngineConfig, } from "./registry.js";
|
|
3
3
|
export { readDefaultAgentEngineSetting, readDefaultAgentEngineSettingDetailed, type DefaultAgentEngineRead, type DefaultAgentEngineSource, } from "../default-agent-engine.js";
|
|
4
4
|
export { createBuilderEngine, BUILDER_DEFAULT_MODEL, BUILDER_SUPPORTED_MODELS, BUILDER_CAPABILITIES, } from "./builder-engine.js";
|
|
5
5
|
export { createAnthropicEngine, ANTHROPIC_DEFAULT_MODEL, ANTHROPIC_SUPPORTED_MODELS, ANTHROPIC_CAPABILITIES, } from "./anthropic-engine.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { registerAgentEngine, getAgentEngineEntry, listAgentEngines, resolveEngine, explicitEngineName, getConfiguredEngineNameForRequest, getStoredModelForEngine, normalizeModelForEngine, resolveDelegatedRunModel, resolveEngineAcceptsCustomModels, resolveEnginePreservesCustomModels, detectEngineFromEnv, detectEngineFromEnvForRequest, detectEngineFromUserSecrets, isAgentEngineSettingConfigured, isAgentEnginePackageInstalled, isStoredEngineUsable, isStoredEngineUsableForRequest, isResolvedEngineUsableForRequest, } from "./registry.js";
|
|
1
|
+
export { registerAgentEngine, getAgentEngineEntry, listAgentEngines, resolveEngine, explicitEngineName, getConfiguredEngineNameForRequest, getStoredModelForEngine, normalizeModelForEngine, resolveDelegatedRunModel, resolveEngineAcceptsCustomModels, resolveEnginePreservesCustomModels, detectEngineFromEnv, detectEngineFromEnvForRequest, detectEngineFromUserSecrets, isAgentEngineSettingConfigured, isAgentEnginePackageInstalled, isDeploymentEngineUsableForRequest, isStoredEngineUsable, isStoredEngineUsableForRequest, isResolvedEngineUsableForRequest, } from "./registry.js";
|
|
2
2
|
export { readDefaultAgentEngineSetting, readDefaultAgentEngineSettingDetailed, } from "../default-agent-engine.js";
|
|
3
3
|
export { createBuilderEngine, BUILDER_DEFAULT_MODEL, BUILDER_SUPPORTED_MODELS, BUILDER_CAPABILITIES, } from "./builder-engine.js";
|
|
4
4
|
export { createAnthropicEngine, ANTHROPIC_DEFAULT_MODEL, ANTHROPIC_SUPPORTED_MODELS, ANTHROPIC_CAPABILITIES, } from "./anthropic-engine.js";
|
|
@@ -42,6 +42,8 @@ export declare function resolveDelegatedRunModel(engine: ModelResolvableEngine,
|
|
|
42
42
|
export declare function resolveEnginePreservesCustomModels(entry: Pick<AgentEngineEntry, "name">): Promise<boolean>;
|
|
43
43
|
export declare function resolveEngineAcceptsCustomModels(entry: Pick<AgentEngineEntry, "acceptsCustomModels">): Promise<boolean>;
|
|
44
44
|
export declare function detectEngineFromEnv(): AgentEngineEntry | null;
|
|
45
|
+
/** Whether a deployment credential can serve this engine for the current request. */
|
|
46
|
+
export declare function isDeploymentEngineUsableForRequest(entry: AgentEngineEntry): Promise<boolean>;
|
|
45
47
|
export declare function detectEngineFromEnvForRequest(): Promise<AgentEngineEntry | null>;
|
|
46
48
|
/**
|
|
47
49
|
* Detect a usable engine from the current request user's accessible
|
|
@@ -11,6 +11,7 @@ import { getAgentAppModelDefaultForCurrentRequest } from "../app-model-defaults.
|
|
|
11
11
|
import { CHATGPT_SUBSCRIPTION_ENGINE_NAME } from "../chatgpt-subscription-contract.js";
|
|
12
12
|
import { readDefaultAgentEngineSetting } from "../default-agent-engine.js";
|
|
13
13
|
import { BUILDER_CLAUDE_SONNET_MODEL_ID, CLAUDE_SONNET_MODEL_ID, } from "../model-config.js";
|
|
14
|
+
import { findLatestSupportedVersionMatch, isNewerVersionedModel, upgradeModelToLatestSupportedVersion, } from "../model-version.js";
|
|
14
15
|
import { createProviderEndpointFetch } from "./ai-sdk-engine.js";
|
|
15
16
|
import { AI_SDK_ANTHROPIC_DEFAULT_BASE_URL, OLLAMA_DEFAULT_BASE_URL, OLLAMA_BASE_URL_ENV_VAR, OPENAI_BASE_URL_ENV_VAR, OPENAI_DEFAULT_BASE_URL, isCustomOpenAiBaseUrl, } from "./openai-compatible-endpoint.js";
|
|
16
17
|
import { isLocalNetworkOllamaEndpoint, validateProviderBaseUrl, } from "./provider-endpoint-validation.js";
|
|
@@ -128,50 +129,6 @@ export function isAgentEnginePackageInstalled(entry) {
|
|
|
128
129
|
.filter((name) => Boolean(name)) ?? [];
|
|
129
130
|
return packageNames.every(canResolvePackage);
|
|
130
131
|
}
|
|
131
|
-
function parseVersionedModelId(model) {
|
|
132
|
-
const match = /^(?<family>.+?)[-.](?<version>\d+(?:[-.]\d+)*)(?<suffix>(?:[-.][a-z][a-z0-9]*)*)$/i.exec(model.trim().toLowerCase());
|
|
133
|
-
const groups = match?.groups;
|
|
134
|
-
if (!groups?.family || !groups.version)
|
|
135
|
-
return null;
|
|
136
|
-
const version = groups.version.split(/[-.]/).map((part) => Number(part));
|
|
137
|
-
if (version.some((part) => !Number.isSafeInteger(part)))
|
|
138
|
-
return null;
|
|
139
|
-
return {
|
|
140
|
-
family: groups.family,
|
|
141
|
-
version,
|
|
142
|
-
suffix: groups.suffix ?? "",
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
function compareModelVersions(left, right) {
|
|
146
|
-
const length = Math.max(left.length, right.length);
|
|
147
|
-
for (let index = 0; index < length; index += 1) {
|
|
148
|
-
const delta = (left[index] ?? 0) - (right[index] ?? 0);
|
|
149
|
-
if (delta !== 0)
|
|
150
|
-
return delta;
|
|
151
|
-
}
|
|
152
|
-
return 0;
|
|
153
|
-
}
|
|
154
|
-
function findLatestSupportedVersionMatch(candidate, supportedModels) {
|
|
155
|
-
const parsedCandidate = parseVersionedModelId(candidate);
|
|
156
|
-
if (!parsedCandidate)
|
|
157
|
-
return undefined;
|
|
158
|
-
let best;
|
|
159
|
-
for (const supportedModel of supportedModels) {
|
|
160
|
-
const parsedSupported = parseVersionedModelId(supportedModel);
|
|
161
|
-
if (!parsedSupported)
|
|
162
|
-
continue;
|
|
163
|
-
if (parsedSupported.family !== parsedCandidate.family)
|
|
164
|
-
continue;
|
|
165
|
-
if (parsedSupported.suffix !== parsedCandidate.suffix)
|
|
166
|
-
continue;
|
|
167
|
-
if (best &&
|
|
168
|
-
compareModelVersions(parsedSupported.version, best.version) <= 0) {
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
|
-
best = { model: supportedModel, version: parsedSupported.version };
|
|
172
|
-
}
|
|
173
|
-
return best?.model;
|
|
174
|
-
}
|
|
175
132
|
export function normalizeModelForEngine(engine, model, options = {}) {
|
|
176
133
|
const candidate = typeof model === "string" ? model.trim() : "";
|
|
177
134
|
if (!candidate)
|
|
@@ -179,9 +136,12 @@ export function normalizeModelForEngine(engine, model, options = {}) {
|
|
|
179
136
|
if (engine.preserveCustomModels || options.preserveCustomModels) {
|
|
180
137
|
return candidate;
|
|
181
138
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
139
|
+
const upgradedModel = upgradeModelToLatestSupportedVersion(candidate, engine.supportedModels);
|
|
140
|
+
if (upgradedModel)
|
|
141
|
+
return upgradedModel;
|
|
142
|
+
if (candidate === "auto" ||
|
|
143
|
+
engine.supportedModels.includes(candidate) ||
|
|
144
|
+
engine.supportedModels.length === 0) {
|
|
185
145
|
return candidate;
|
|
186
146
|
}
|
|
187
147
|
if (engine.acceptsCustomModels || options.acceptsCustomModels) {
|
|
@@ -191,6 +151,9 @@ export function normalizeModelForEngine(engine, model, options = {}) {
|
|
|
191
151
|
: candidate;
|
|
192
152
|
}
|
|
193
153
|
const versionMatch = findLatestSupportedVersionMatch(candidate, engine.supportedModels);
|
|
154
|
+
if (versionMatch && isNewerVersionedModel(candidate, versionMatch)) {
|
|
155
|
+
return versionMatch;
|
|
156
|
+
}
|
|
194
157
|
if (versionMatch)
|
|
195
158
|
return versionMatch;
|
|
196
159
|
return engine.defaultModel;
|
|
@@ -336,6 +299,59 @@ async function usableEnvCredentialMatch(entry) {
|
|
|
336
299
|
}
|
|
337
300
|
return null;
|
|
338
301
|
}
|
|
302
|
+
/** Whether a deployment credential can serve this engine for the current request. */
|
|
303
|
+
export async function isDeploymentEngineUsableForRequest(entry) {
|
|
304
|
+
if (!isAgentEnginePackageInstalled(entry))
|
|
305
|
+
return false;
|
|
306
|
+
if (entry.name === "ai-sdk:ollama") {
|
|
307
|
+
return isDeploymentProviderEndpointUsable(entry);
|
|
308
|
+
}
|
|
309
|
+
for (const set of envCredentialSetsForEntry(entry)) {
|
|
310
|
+
if (!set.envVars.every((key) => canUseDeployCredentialFallbackForRequest(key) &&
|
|
311
|
+
!!readDeployCredentialEnv(key))) {
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (await isEnvCredentialSetUsable(set)) {
|
|
315
|
+
return isDeploymentProviderEndpointUsable(entry);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
async function isDeploymentProviderEndpointUsable(entry) {
|
|
321
|
+
const endpointConfig = entry.name === "ai-sdk:ollama"
|
|
322
|
+
? {
|
|
323
|
+
envVar: OLLAMA_BASE_URL_ENV_VAR,
|
|
324
|
+
provider: "Ollama",
|
|
325
|
+
required: true,
|
|
326
|
+
isOllama: true,
|
|
327
|
+
}
|
|
328
|
+
: entry.name === "ai-sdk:openai"
|
|
329
|
+
? {
|
|
330
|
+
envVar: OPENAI_BASE_URL_ENV_VAR,
|
|
331
|
+
provider: "OpenAI",
|
|
332
|
+
required: false,
|
|
333
|
+
isOllama: false,
|
|
334
|
+
}
|
|
335
|
+
: undefined;
|
|
336
|
+
if (!endpointConfig)
|
|
337
|
+
return true;
|
|
338
|
+
const endpoint = canUseDeployCredentialFallbackForRequest(endpointConfig.envVar)
|
|
339
|
+
? readDeployCredentialEnv(endpointConfig.envVar)
|
|
340
|
+
: undefined;
|
|
341
|
+
if (!endpoint)
|
|
342
|
+
return !endpointConfig.required;
|
|
343
|
+
try {
|
|
344
|
+
await validateProviderBaseUrl(endpoint, {
|
|
345
|
+
allowPrivate: true,
|
|
346
|
+
isOllama: endpointConfig.isOllama,
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
console.warn(`[agent-engine] Invalid deployment ${endpointConfig.provider} endpoint; provider unavailable.`, { error: error instanceof Error ? error.message : String(error) });
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
339
355
|
export async function detectEngineFromEnvForRequest() {
|
|
340
356
|
const preferByo = getAppConfig().agent.preferBringYourOwnKey;
|
|
341
357
|
const matches = [];
|
|
@@ -21,7 +21,7 @@ export declare const BUILDER_CLAUDE_SONNET_MODEL_LABEL = "Claude Sonnet 5";
|
|
|
21
21
|
export declare const AGENT_MODEL_CONFIG: {
|
|
22
22
|
readonly builder: {
|
|
23
23
|
readonly defaultModel: "gpt-6-luna";
|
|
24
|
-
readonly supportedModels: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "grok-code-fast", "qwen3-coder", "kimi-k2-5", "deepseek-v4-pro", "deepseek-v3-1", "z-ai-glm-4-5", "z-ai-glm-5-1"];
|
|
24
|
+
readonly supportedModels: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6.1-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "grok-code-fast", "qwen3-coder", "kimi-k2-5", "deepseek-v4-pro", "deepseek-v3-1", "z-ai-glm-4-5", "z-ai-glm-5-1"];
|
|
25
25
|
};
|
|
26
26
|
readonly anthropic: {
|
|
27
27
|
readonly defaultModel: "claude-sonnet-5-5";
|
|
@@ -34,11 +34,11 @@ export declare const AGENT_MODEL_CONFIG: {
|
|
|
34
34
|
};
|
|
35
35
|
readonly openai: {
|
|
36
36
|
readonly defaultModel: "gpt-6-luna";
|
|
37
|
-
readonly supportedModels: readonly ["gpt-6-luna", "gpt-5.6-
|
|
37
|
+
readonly supportedModels: readonly ["gpt-6-luna", "gpt-5.6-terra", "gpt-6.1-sol"];
|
|
38
38
|
};
|
|
39
39
|
readonly openrouter: {
|
|
40
40
|
readonly defaultModel: string;
|
|
41
|
-
readonly supportedModels: readonly ["openai/gpt-6-luna", "openai/gpt-5.6-
|
|
41
|
+
readonly supportedModels: readonly ["openai/gpt-6-luna", "openai/gpt-5.6-terra", "openai/gpt-6.1-sol", "openai/gpt-6-astra", "openai/gpt-6-astra-pro", "anthropic/claude-sonnet-5.5", "anthropic/claude-opus-5.5", "anthropic/claude-opus-4.8", "anthropic/claude-fable-5", "anthropic/claude-fable-5.1", "google/gemini-3.8-flash", "qwen/qwen3.8-max-0902", "meta/muse-spark-1.3", "inception/mercury-2.5", "z-ai/glm-5.2"];
|
|
42
42
|
};
|
|
43
43
|
readonly google: {
|
|
44
44
|
readonly defaultModel: "gemini-3.8-flash";
|
|
@@ -64,7 +64,7 @@ export declare const AGENT_MODEL_CONFIG: {
|
|
|
64
64
|
};
|
|
65
65
|
export declare const BUILDER_MODEL_CONFIG: {
|
|
66
66
|
readonly defaultModel: "gpt-6-luna";
|
|
67
|
-
readonly supportedModels: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "grok-code-fast", "qwen3-coder", "kimi-k2-5", "deepseek-v4-pro", "deepseek-v3-1", "z-ai-glm-4-5", "z-ai-glm-5-1"];
|
|
67
|
+
readonly supportedModels: readonly ["auto", "claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5-5", "gpt-5-4", "gpt-5-5", "gpt-5-4-mini", "gpt-5-1-codex-mini", "gpt-6.1-sol", "gpt-5-6-terra", "gpt-6-luna", "gemini-3-1-pro", "gemini-3-8-flash", "gemini-3-5-flash-lite", "gemini-3-1-flash-lite", "grok-code-fast", "qwen3-coder", "kimi-k2-5", "deepseek-v4-pro", "deepseek-v3-1", "z-ai-glm-4-5", "z-ai-glm-5-1"];
|
|
68
68
|
};
|
|
69
69
|
export declare const ANTHROPIC_MODEL_CONFIG: {
|
|
70
70
|
readonly defaultModel: "claude-sonnet-5-5";
|
|
@@ -77,11 +77,11 @@ export declare const AI_SDK_MODEL_CONFIG: {
|
|
|
77
77
|
};
|
|
78
78
|
readonly openai: {
|
|
79
79
|
readonly defaultModel: "gpt-6-luna";
|
|
80
|
-
readonly supportedModels: readonly ["gpt-6-luna", "gpt-5.6-
|
|
80
|
+
readonly supportedModels: readonly ["gpt-6-luna", "gpt-5.6-terra", "gpt-6.1-sol"];
|
|
81
81
|
};
|
|
82
82
|
readonly openrouter: {
|
|
83
83
|
readonly defaultModel: string;
|
|
84
|
-
readonly supportedModels: readonly ["openai/gpt-6-luna", "openai/gpt-5.6-
|
|
84
|
+
readonly supportedModels: readonly ["openai/gpt-6-luna", "openai/gpt-5.6-terra", "openai/gpt-6.1-sol", "openai/gpt-6-astra", "openai/gpt-6-astra-pro", "anthropic/claude-sonnet-5.5", "anthropic/claude-opus-5.5", "anthropic/claude-opus-4.8", "anthropic/claude-fable-5", "anthropic/claude-fable-5.1", "google/gemini-3.8-flash", "qwen/qwen3.8-max-0902", "meta/muse-spark-1.3", "inception/mercury-2.5", "z-ai/glm-5.2"];
|
|
85
85
|
};
|
|
86
86
|
readonly google: {
|
|
87
87
|
readonly defaultModel: "gemini-3.8-flash";
|
|
@@ -24,11 +24,13 @@ const MODEL_CONTEXT_WINDOWS = {
|
|
|
24
24
|
"openai/gpt-5.6-sol": 1_050_000,
|
|
25
25
|
"openai/gpt-5.6-terra": 1_050_000,
|
|
26
26
|
"openai/gpt-5.6-luna": 1_050_000,
|
|
27
|
+
"openai/gpt-6.1-sol": 1_050_000,
|
|
27
28
|
"openai/gpt-6-sol": 1_050_000,
|
|
28
29
|
"openai/gpt-6-luna": 1_050_000,
|
|
29
30
|
"google/gemini-2.5-flash": 1_048_576,
|
|
30
31
|
"z-ai/glm-5.2": 1_048_576,
|
|
31
32
|
"gpt-6-sol": 1_050_000,
|
|
33
|
+
"gpt-6.1-sol": 1_050_000,
|
|
32
34
|
"gpt-6-luna": 1_050_000,
|
|
33
35
|
"gpt-5.6-sol": 1_050_000,
|
|
34
36
|
"gpt-5.6-terra": 1_050_000,
|
|
@@ -97,9 +99,11 @@ const MODEL_MAX_OUTPUT_TOKENS = {
|
|
|
97
99
|
"openai/gpt-5.6-sol": 40_000,
|
|
98
100
|
"openai/gpt-5.6-terra": 40_000,
|
|
99
101
|
"openai/gpt-5.6-luna": 128_000,
|
|
102
|
+
"openai/gpt-6.1-sol": 128_000,
|
|
100
103
|
"openai/gpt-6-sol": 128_000,
|
|
101
104
|
"openai/gpt-6-luna": 128_000,
|
|
102
105
|
"gpt-6-sol": 128_000,
|
|
106
|
+
"gpt-6.1-sol": 128_000,
|
|
103
107
|
"gpt-6-luna": 128_000,
|
|
104
108
|
"gpt-5.6-sol": 40_000,
|
|
105
109
|
"gpt-5.6-terra": 40_000,
|
|
@@ -163,7 +167,7 @@ export const AGENT_MODEL_CONFIG = {
|
|
|
163
167
|
"gpt-5-5",
|
|
164
168
|
"gpt-5-4-mini",
|
|
165
169
|
"gpt-5-1-codex-mini",
|
|
166
|
-
"gpt-6-sol",
|
|
170
|
+
"gpt-6.1-sol",
|
|
167
171
|
"gpt-5-6-terra",
|
|
168
172
|
"gpt-6-luna",
|
|
169
173
|
"gemini-3-1-pro",
|
|
@@ -202,22 +206,14 @@ export const AGENT_MODEL_CONFIG = {
|
|
|
202
206
|
},
|
|
203
207
|
openai: {
|
|
204
208
|
defaultModel: FRAMEWORK_DEFAULT_OPENAI_MODEL,
|
|
205
|
-
supportedModels: [
|
|
206
|
-
"gpt-6-luna",
|
|
207
|
-
"gpt-5.6-luna",
|
|
208
|
-
"gpt-5.6-terra",
|
|
209
|
-
"gpt-5.6-sol",
|
|
210
|
-
"gpt-6-sol",
|
|
211
|
-
],
|
|
209
|
+
supportedModels: ["gpt-6-luna", "gpt-5.6-terra", "gpt-6.1-sol"],
|
|
212
210
|
},
|
|
213
211
|
openrouter: {
|
|
214
212
|
defaultModel: FRAMEWORK_DEFAULT_OPENROUTER_MODEL,
|
|
215
213
|
supportedModels: [
|
|
216
214
|
"openai/gpt-6-luna",
|
|
217
|
-
"openai/gpt-5.6-luna",
|
|
218
215
|
"openai/gpt-5.6-terra",
|
|
219
|
-
"openai/gpt-
|
|
220
|
-
"openai/gpt-6-sol",
|
|
216
|
+
"openai/gpt-6.1-sol",
|
|
221
217
|
"openai/gpt-6-astra",
|
|
222
218
|
"openai/gpt-6-astra-pro",
|
|
223
219
|
OPENROUTER_CLAUDE_SONNET_MODEL_ID,
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function findLatestSupportedVersionMatch(candidate: string, supportedModels: readonly string[]): string | undefined;
|
|
2
|
+
export declare function isNewerVersionedModel(candidate: string, newerModel: string): boolean;
|
|
3
|
+
export declare function upgradeModelToLatestSupportedVersion(candidate: string, supportedModels: readonly string[]): string | undefined;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const UPGRADEABLE_GPT_TIERS = new Set(["-sol", "-terra", "-luna"]);
|
|
2
|
+
function parseVersionedModelId(model) {
|
|
3
|
+
const match = /^(?<family>.+?)[-.](?<version>\d+(?:[-.]\d+)*)(?<suffix>(?:[-.][a-z][a-z0-9]*)*)$/i.exec(model.trim().toLowerCase());
|
|
4
|
+
const groups = match?.groups;
|
|
5
|
+
if (!groups?.family || !groups.version)
|
|
6
|
+
return null;
|
|
7
|
+
const version = groups.version.split(/[-.]/).map((part) => Number(part));
|
|
8
|
+
if (version.some((part) => !Number.isSafeInteger(part)))
|
|
9
|
+
return null;
|
|
10
|
+
return {
|
|
11
|
+
family: groups.family,
|
|
12
|
+
version,
|
|
13
|
+
suffix: groups.suffix ?? "",
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function compareModelVersions(left, right) {
|
|
17
|
+
const length = Math.max(left.length, right.length);
|
|
18
|
+
for (let index = 0; index < length; index += 1) {
|
|
19
|
+
const delta = (left[index] ?? 0) - (right[index] ?? 0);
|
|
20
|
+
if (delta !== 0)
|
|
21
|
+
return delta;
|
|
22
|
+
}
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
export function findLatestSupportedVersionMatch(candidate, supportedModels) {
|
|
26
|
+
const parsedCandidate = parseVersionedModelId(candidate);
|
|
27
|
+
if (!parsedCandidate)
|
|
28
|
+
return undefined;
|
|
29
|
+
let best;
|
|
30
|
+
for (const supportedModel of supportedModels) {
|
|
31
|
+
const parsedSupported = parseVersionedModelId(supportedModel);
|
|
32
|
+
if (!parsedSupported)
|
|
33
|
+
continue;
|
|
34
|
+
if (parsedSupported.family !== parsedCandidate.family)
|
|
35
|
+
continue;
|
|
36
|
+
if (parsedSupported.suffix !== parsedCandidate.suffix)
|
|
37
|
+
continue;
|
|
38
|
+
if (best &&
|
|
39
|
+
compareModelVersions(parsedSupported.version, best.version) <= 0) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
best = { model: supportedModel, version: parsedSupported.version };
|
|
43
|
+
}
|
|
44
|
+
return best?.model;
|
|
45
|
+
}
|
|
46
|
+
export function isNewerVersionedModel(candidate, newerModel) {
|
|
47
|
+
const current = parseVersionedModelId(candidate);
|
|
48
|
+
const newer = parseVersionedModelId(newerModel);
|
|
49
|
+
return (current !== null &&
|
|
50
|
+
newer !== null &&
|
|
51
|
+
current.family === newer.family &&
|
|
52
|
+
current.suffix === newer.suffix &&
|
|
53
|
+
compareModelVersions(newer.version, current.version) > 0);
|
|
54
|
+
}
|
|
55
|
+
export function upgradeModelToLatestSupportedVersion(candidate, supportedModels) {
|
|
56
|
+
const parsedCandidate = parseVersionedModelId(candidate);
|
|
57
|
+
if (!parsedCandidate ||
|
|
58
|
+
(parsedCandidate.family !== "gpt" &&
|
|
59
|
+
parsedCandidate.family !== "openai/gpt") ||
|
|
60
|
+
!UPGRADEABLE_GPT_TIERS.has(parsedCandidate.suffix)) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
const latest = findLatestSupportedVersionMatch(candidate, supportedModels);
|
|
64
|
+
return latest && isNewerVersionedModel(candidate, latest)
|
|
65
|
+
? latest
|
|
66
|
+
: undefined;
|
|
67
|
+
}
|
|
@@ -26,6 +26,7 @@ export interface ProviderModelSelectionRow {
|
|
|
26
26
|
provider: ProviderModelSelectionProvider;
|
|
27
27
|
scope: ProviderModelSelectionScope;
|
|
28
28
|
models: string[] | null;
|
|
29
|
+
preserveCustomModels?: boolean;
|
|
29
30
|
updatedAt?: number;
|
|
30
31
|
updatedBy?: string;
|
|
31
32
|
}
|
|
@@ -37,11 +38,13 @@ export type EffectiveProviderModelSelection = {
|
|
|
37
38
|
state: "default";
|
|
38
39
|
provider: ProviderModelSelectionProvider;
|
|
39
40
|
scope: ProviderModelSelectionScope;
|
|
41
|
+
preserveCustomModels?: boolean;
|
|
40
42
|
} | {
|
|
41
43
|
state: "selected";
|
|
42
44
|
provider: ProviderModelSelectionProvider;
|
|
43
45
|
scope: ProviderModelSelectionScope;
|
|
44
46
|
models: string[];
|
|
47
|
+
preserveCustomModels?: boolean;
|
|
45
48
|
} | {
|
|
46
49
|
state: "unreadable";
|
|
47
50
|
provider: ProviderModelSelectionProvider;
|
|
@@ -67,7 +70,9 @@ export declare function recommendedProviderModels(provider: ProviderModelSelecti
|
|
|
67
70
|
* only routes its own catalog, so ids outside it are refused rather than
|
|
68
71
|
* stored as choices the gateway would silently swap for its default.
|
|
69
72
|
*/
|
|
70
|
-
export declare function normalizeSelectedModels(provider: ProviderModelSelectionProvider, models: readonly unknown[]
|
|
73
|
+
export declare function normalizeSelectedModels(provider: ProviderModelSelectionProvider, models: readonly unknown[], options?: {
|
|
74
|
+
preserveCustomModels?: boolean;
|
|
75
|
+
}): string[];
|
|
71
76
|
/** Read one scope's row. Throws when the store can't be read. */
|
|
72
77
|
export declare function readProviderModelSelection(ctx: ProviderModelSelectionContext, provider: ProviderModelSelectionProvider, scope: ProviderModelSelectionScope): Promise<ProviderModelSelectionRow>;
|
|
73
78
|
/**
|