fix: 接入 dsflash-go model catalog
This commit is contained in:
@@ -9,7 +9,7 @@ export interface BackendProfileSpec {
|
||||
transport: "stdio";
|
||||
command: "codex app-server --listen stdio://";
|
||||
status: "registered";
|
||||
requiredSecretKeys: ["auth.json", "config.toml"];
|
||||
requiredSecretKeys: readonly string[];
|
||||
defaultSecretName: string;
|
||||
profileIsolation: "profile-scoped-codex-home";
|
||||
description: string;
|
||||
@@ -59,7 +59,7 @@ const builtinBackendProfileSpecs: readonly BackendProfileSpec[] = [
|
||||
transport: "stdio",
|
||||
command: "codex app-server --listen stdio://",
|
||||
status: "registered",
|
||||
requiredSecretKeys: ["auth.json", "config.toml"],
|
||||
requiredSecretKeys: ["auth.json", "config.toml", "model-catalog.json"],
|
||||
defaultSecretName: "agentrun-v01-provider-dsflash-go",
|
||||
profileIsolation: "profile-scoped-codex-home",
|
||||
description: "DeepSeek V4 Flash profile through OpenCode Zen Go Moon Bridge",
|
||||
@@ -142,7 +142,7 @@ export function backendCapabilities(): JsonRecord[] {
|
||||
return builtinBackendProfileSpecs.map(backendCapability);
|
||||
}
|
||||
|
||||
export function backendCapabilitiesSqlValues(profiles?: readonly BackendProfile[]): string {
|
||||
export function backendCapabilitiesSqlValues(profiles?: readonly BackendProfile[], options: { requiredSecretKeysByProfile?: Record<string, readonly string[]> } = {}): string {
|
||||
const specs = profiles
|
||||
? profiles.map((profile) => {
|
||||
const spec = backendProfileSpec(profile);
|
||||
@@ -151,13 +151,14 @@ export function backendCapabilitiesSqlValues(profiles?: readonly BackendProfile[
|
||||
})
|
||||
: builtinBackendProfileSpecs;
|
||||
return specs.map((spec) => {
|
||||
const requiredSecretKeys = options.requiredSecretKeysByProfile?.[spec.profile] ?? spec.requiredSecretKeys;
|
||||
const capabilities = JSON.stringify({
|
||||
backendKind: spec.backendKind,
|
||||
protocol: spec.protocol,
|
||||
transport: spec.transport,
|
||||
command: spec.command,
|
||||
requiredSecretKeys: spec.requiredSecretKeys,
|
||||
defaultSecretRef: { name: spec.defaultSecretName, keys: spec.requiredSecretKeys },
|
||||
requiredSecretKeys,
|
||||
defaultSecretRef: { name: spec.defaultSecretName, keys: requiredSecretKeys },
|
||||
profileIsolation: spec.profileIsolation,
|
||||
description: spec.description,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import type { JsonRecord } from "./types.js";
|
||||
|
||||
export const dsflashGoModelSlug = "deepseek-v4-flash";
|
||||
export const dsflashGoModelCatalogFile = "model-catalog.json";
|
||||
export const dsflashGoRuntimeModelCatalogPath = "/home/agentrun/.codex-dsflash-go/model-catalog.json";
|
||||
|
||||
const dsflashGoModelCatalog: JsonRecord = {
|
||||
models: [
|
||||
{
|
||||
slug: dsflashGoModelSlug,
|
||||
display_name: "DeepSeek V4 Flash via OpenCode Zen Go",
|
||||
description: "DeepSeek V4 Flash exposed to Codex through OpenCode Zen Go and a Responses-compatible Moon Bridge profile.",
|
||||
default_reasoning_level: "xhigh",
|
||||
supported_reasoning_levels: [
|
||||
{ effort: "low", description: "Fast responses with lighter reasoning" },
|
||||
{ effort: "medium", description: "Balanced reasoning" },
|
||||
{ effort: "high", description: "Deep reasoning" },
|
||||
{ effort: "xhigh", description: "Maximum reasoning" },
|
||||
],
|
||||
shell_type: "shell_command",
|
||||
visibility: "list",
|
||||
supported_in_api: true,
|
||||
priority: 0,
|
||||
additional_speed_tiers: [],
|
||||
service_tiers: [],
|
||||
availability_nux: null,
|
||||
upgrade: null,
|
||||
base_instructions: "You are Codex, a coding agent based on DeepSeek V4 Flash. You and the user share one workspace, and your job is to collaborate with them until their goal is genuinely handled.",
|
||||
model_messages: {},
|
||||
supports_reasoning_summaries: true,
|
||||
default_reasoning_summary: "auto",
|
||||
support_verbosity: false,
|
||||
apply_patch_tool_type: "freeform",
|
||||
web_search_tool_type: "text_and_image",
|
||||
truncation_policy: { mode: "tokens", limit: 10000 },
|
||||
supports_parallel_tool_calls: true,
|
||||
supports_image_detail_original: false,
|
||||
context_window: 1_000_000,
|
||||
max_context_window: 1_000_000,
|
||||
auto_compact_token_limit: 900_000,
|
||||
effective_context_window_percent: 95,
|
||||
experimental_supported_tools: [],
|
||||
input_modalities: ["text"],
|
||||
supports_search_tool: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export function dsflashGoModelCatalogJson(): string {
|
||||
return `${JSON.stringify(dsflashGoModelCatalog, null, 2)}\n`;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ export type FailureKind =
|
||||
| "provider-auth-failed"
|
||||
| "provider-rate-limited"
|
||||
| "provider-invalid-tool-call"
|
||||
| "provider-compact-unsupported"
|
||||
| "provider-unavailable"
|
||||
| "infra-failed"
|
||||
| "session-store-evicted"
|
||||
|
||||
@@ -185,18 +185,16 @@ export function validateExecutionPolicy(record: JsonRecord): ExecutionPolicy {
|
||||
if (typeof timeout !== "number" || !Number.isFinite(timeout) || timeout <= 0) throw new AgentRunError("schema-invalid", "executionPolicy.timeoutMs must be a positive number", { httpStatus: 400 });
|
||||
const secretScope = asRecord(record.secretScope ?? {}, "executionPolicy.secretScope");
|
||||
if (secretScope.allowCredentialEcho !== undefined && secretScope.allowCredentialEcho !== false) throw new AgentRunError("tenant-policy-denied", "allowCredentialEcho must be false", { httpStatus: 403 });
|
||||
const providerCredentials = Array.isArray(secretScope.providerCredentials) ? secretScope.providerCredentials : [];
|
||||
for (const credential of providerCredentials) {
|
||||
const rawProviderCredentials = Array.isArray(secretScope.providerCredentials) ? secretScope.providerCredentials : [];
|
||||
const providerCredentials: NonNullable<ExecutionPolicy["secretScope"]["providerCredentials"]> = [];
|
||||
for (const credential of rawProviderCredentials) {
|
||||
const item = asRecord(credential, "providerCredential");
|
||||
const profile = typeof item.profile === "string" ? item.profile.trim() : "";
|
||||
if (profile.length === 0) throw new AgentRunError("schema-invalid", "provider credential profile is required", { httpStatus: 400 });
|
||||
if (!isBackendProfile(profile)) throw new AgentRunError("schema-invalid", `provider credential profile ${profile} must be a lowercase slug`, { httpStatus: 400, details: { pattern: backendProfilePatternText } });
|
||||
const secretRef = asRecord(item.secretRef, "providerCredential.secretRef");
|
||||
if (typeof secretRef.name !== "string" || secretRef.name.length === 0) throw new AgentRunError("schema-invalid", "provider credential secretRef.name is required", { httpStatus: 400 });
|
||||
const keys = Array.isArray(secretRef.keys) ? secretRef.keys : [];
|
||||
for (const requiredKey of backendProfileSpec(profile)?.requiredSecretKeys ?? []) {
|
||||
if (!keys.includes(requiredKey)) throw new AgentRunError("schema-invalid", `provider credential ${profile} secretRef.keys must include ${requiredKey}`, { httpStatus: 400 });
|
||||
}
|
||||
const secretRef = validateSecretRef(asRecord(item.secretRef, "providerCredential.secretRef"));
|
||||
const keys = [...new Set([...(secretRef.keys ?? []), ...(backendProfileSpec(profile)?.requiredSecretKeys ?? [])])];
|
||||
providerCredentials.push({ profile, secretRef: { ...secretRef, ...(keys.length > 0 ? { keys } : {}) } });
|
||||
}
|
||||
const toolCredentials = validateToolCredentials(secretScope.toolCredentials);
|
||||
const secretScopeResult: ExecutionPolicy["secretScope"] = { allowCredentialEcho: false };
|
||||
|
||||
Reference in New Issue
Block a user