mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-05-06 11:22:48 +08:00
feat(openclaw): add agents.defaults config support
- Add types for default model config (primary + fallbacks) - Add types for model catalog/allowlist with aliases - Extend OpenClawModelEntry with cost and contextWindow fields - Add Tauri commands: get/set_openclaw_default_model, get/set_openclaw_model_catalog - Create frontend API (src/lib/api/openclaw.ts) - Add suggestedDefaults to provider presets with model metadata - Add i18n translations (zh/en/ja) for openclawConfig.*
This commit is contained in:
@@ -342,3 +342,38 @@ pub fn get_openclaw_live_provider_ids() -> Result<Vec<String>, String> {
|
||||
.map(|providers| providers.keys().cloned().collect())
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OpenClaw Agents Configuration Commands
|
||||
// ============================================================================
|
||||
|
||||
/// 获取 OpenClaw 默认模型配置(agents.defaults.model)
|
||||
#[tauri::command]
|
||||
pub fn get_openclaw_default_model(
|
||||
) -> Result<Option<crate::openclaw_config::OpenClawDefaultModel>, String> {
|
||||
crate::openclaw_config::get_default_model().map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// 设置 OpenClaw 默认模型配置(agents.defaults.model)
|
||||
#[tauri::command]
|
||||
pub fn set_openclaw_default_model(
|
||||
model: crate::openclaw_config::OpenClawDefaultModel,
|
||||
) -> Result<(), String> {
|
||||
crate::openclaw_config::set_default_model(&model).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// 获取 OpenClaw 模型目录/允许列表(agents.defaults.models)
|
||||
#[tauri::command]
|
||||
pub fn get_openclaw_model_catalog(
|
||||
) -> Result<Option<std::collections::HashMap<String, crate::openclaw_config::OpenClawModelCatalogEntry>>, String>
|
||||
{
|
||||
crate::openclaw_config::get_model_catalog().map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// 设置 OpenClaw 模型目录/允许列表(agents.defaults.models)
|
||||
#[tauri::command]
|
||||
pub fn set_openclaw_model_catalog(
|
||||
catalog: std::collections::HashMap<String, crate::openclaw_config::OpenClawModelCatalogEntry>,
|
||||
) -> Result<(), String> {
|
||||
crate::openclaw_config::set_model_catalog(&catalog).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
@@ -1007,6 +1007,10 @@ pub fn run() {
|
||||
// OpenClaw specific
|
||||
commands::import_openclaw_providers_from_live,
|
||||
commands::get_openclaw_live_provider_ids,
|
||||
commands::get_openclaw_default_model,
|
||||
commands::set_openclaw_default_model,
|
||||
commands::get_openclaw_model_catalog,
|
||||
commands::set_openclaw_model_catalog,
|
||||
// Global upstream proxy
|
||||
commands::get_global_proxy_url,
|
||||
commands::set_global_proxy_url,
|
||||
|
||||
@@ -42,6 +42,7 @@ use crate::settings::get_openclaw_override_dir;
|
||||
use indexmap::IndexMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{json, Map, Value};
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
// ============================================================================
|
||||
@@ -101,6 +102,7 @@ pub struct OpenClawProviderConfig {
|
||||
|
||||
/// OpenClaw 模型条目
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct OpenClawModelEntry {
|
||||
/// 模型 ID
|
||||
pub id: String,
|
||||
@@ -109,11 +111,92 @@ pub struct OpenClawModelEntry {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub name: Option<String>,
|
||||
|
||||
/// 其他自定义字段
|
||||
/// 模型别名(用于快捷引用)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub alias: Option<String>,
|
||||
|
||||
/// 模型成本(输入/输出价格)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub cost: Option<OpenClawModelCost>,
|
||||
|
||||
/// 上下文窗口大小
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub context_window: Option<u32>,
|
||||
|
||||
/// 其他自定义字段(保留未知字段)
|
||||
#[serde(flatten)]
|
||||
pub extra: Map<String, Value>,
|
||||
}
|
||||
|
||||
/// OpenClaw 模型成本配置
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OpenClawModelCost {
|
||||
/// 输入价格(每百万 token)
|
||||
pub input: f64,
|
||||
|
||||
/// 输出价格(每百万 token)
|
||||
pub output: f64,
|
||||
|
||||
/// 其他自定义字段(保留未知字段)
|
||||
#[serde(flatten)]
|
||||
pub other: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
/// OpenClaw 默认模型配置(agents.defaults.model)
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OpenClawDefaultModel {
|
||||
/// 主模型 ID(格式:provider/model)
|
||||
pub primary: String,
|
||||
|
||||
/// 回退模型列表
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub fallbacks: Vec<String>,
|
||||
|
||||
/// 其他自定义字段(保留未知字段)
|
||||
#[serde(flatten)]
|
||||
pub other: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
/// OpenClaw 模型目录条目(agents.defaults.models 中的值)
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OpenClawModelCatalogEntry {
|
||||
/// 模型别名(用于 UI 显示)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub alias: Option<String>,
|
||||
|
||||
/// 其他自定义字段(保留未知字段)
|
||||
#[serde(flatten)]
|
||||
pub other: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
/// OpenClaw agents.defaults 配置
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OpenClawAgentsDefaults {
|
||||
/// 默认模型配置
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub model: Option<OpenClawDefaultModel>,
|
||||
|
||||
/// 模型目录/允许列表(键为 provider/model 格式)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub models: Option<HashMap<String, OpenClawModelCatalogEntry>>,
|
||||
|
||||
/// 其他自定义字段(保留未知字段)
|
||||
#[serde(flatten)]
|
||||
pub other: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
/// OpenClaw agents 顶层配置
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OpenClawAgents {
|
||||
/// 默认配置
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub defaults: Option<OpenClawAgentsDefaults>,
|
||||
|
||||
/// 其他自定义字段(保留未知字段)
|
||||
#[serde(flatten)]
|
||||
pub other: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Core Read/Write Functions
|
||||
// ============================================================================
|
||||
@@ -254,3 +337,86 @@ pub fn set_typed_provider(id: &str, config: &OpenClawProviderConfig) -> Result<(
|
||||
let value = serde_json::to_value(config).map_err(|e| AppError::JsonSerialize { source: e })?;
|
||||
set_provider(id, value)
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Agents Configuration Functions
|
||||
// ============================================================================
|
||||
|
||||
/// 读取默认模型配置(agents.defaults.model)
|
||||
pub fn get_default_model() -> Result<Option<OpenClawDefaultModel>, AppError> {
|
||||
let config = read_openclaw_config()?;
|
||||
|
||||
let Some(model_value) = config
|
||||
.get("agents")
|
||||
.and_then(|a| a.get("defaults"))
|
||||
.and_then(|d| d.get("model"))
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let model = serde_json::from_value(model_value.clone())
|
||||
.map_err(|e| AppError::Config(format!("Failed to parse agents.defaults.model: {e}")))?;
|
||||
|
||||
Ok(Some(model))
|
||||
}
|
||||
|
||||
/// 设置默认模型配置(agents.defaults.model)
|
||||
pub fn set_default_model(model: &OpenClawDefaultModel) -> Result<(), AppError> {
|
||||
let mut config = read_openclaw_config()?;
|
||||
|
||||
// Ensure agents.defaults path exists, preserving unknown fields
|
||||
ensure_agents_defaults_path(&mut config);
|
||||
|
||||
let model_value =
|
||||
serde_json::to_value(model).map_err(|e| AppError::JsonSerialize { source: e })?;
|
||||
|
||||
config["agents"]["defaults"]["model"] = model_value;
|
||||
|
||||
write_openclaw_config(&config)
|
||||
}
|
||||
|
||||
/// 读取模型目录/允许列表(agents.defaults.models)
|
||||
pub fn get_model_catalog() -> Result<Option<HashMap<String, OpenClawModelCatalogEntry>>, AppError> {
|
||||
let config = read_openclaw_config()?;
|
||||
|
||||
let Some(models_value) = config
|
||||
.get("agents")
|
||||
.and_then(|a| a.get("defaults"))
|
||||
.and_then(|d| d.get("models"))
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let catalog = serde_json::from_value(models_value.clone())
|
||||
.map_err(|e| AppError::Config(format!("Failed to parse agents.defaults.models: {e}")))?;
|
||||
|
||||
Ok(Some(catalog))
|
||||
}
|
||||
|
||||
/// 设置模型目录/允许列表(agents.defaults.models)
|
||||
pub fn set_model_catalog(
|
||||
catalog: &HashMap<String, OpenClawModelCatalogEntry>,
|
||||
) -> Result<(), AppError> {
|
||||
let mut config = read_openclaw_config()?;
|
||||
|
||||
// Ensure agents.defaults path exists, preserving unknown fields
|
||||
ensure_agents_defaults_path(&mut config);
|
||||
|
||||
let catalog_value =
|
||||
serde_json::to_value(catalog).map_err(|e| AppError::JsonSerialize { source: e })?;
|
||||
|
||||
config["agents"]["defaults"]["models"] = catalog_value;
|
||||
|
||||
write_openclaw_config(&config)
|
||||
}
|
||||
|
||||
/// Ensure the `agents.defaults` path exists in the config,
|
||||
/// preserving any existing unknown fields.
|
||||
fn ensure_agents_defaults_path(config: &mut Value) {
|
||||
if config.get("agents").is_none() {
|
||||
config["agents"] = json!({});
|
||||
}
|
||||
if config["agents"].get("defaults").is_none() {
|
||||
config["agents"]["defaults"] = json!({});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,21 @@
|
||||
* OpenClaw provider presets configuration
|
||||
* OpenClaw uses models.providers structure with custom provider configs
|
||||
*/
|
||||
import type { ProviderCategory, OpenClawProviderConfig } from "../types";
|
||||
import type {
|
||||
ProviderCategory,
|
||||
OpenClawProviderConfig,
|
||||
OpenClawDefaultModel,
|
||||
} from "../types";
|
||||
import type { PresetTheme, TemplateValueConfig } from "./claudeProviderPresets";
|
||||
|
||||
/** Suggested default model configuration for a preset */
|
||||
export interface OpenClawSuggestedDefaults {
|
||||
/** Default model config to apply (agents.defaults.model) */
|
||||
model?: OpenClawDefaultModel;
|
||||
/** Model catalog entries to add (agents.defaults.models) */
|
||||
modelCatalog?: Record<string, { alias?: string }>;
|
||||
}
|
||||
|
||||
export interface OpenClawProviderPreset {
|
||||
name: string;
|
||||
websiteUrl: string;
|
||||
@@ -25,6 +37,8 @@ export interface OpenClawProviderPreset {
|
||||
iconColor?: string;
|
||||
/** Mark as custom template (for UI distinction) */
|
||||
isCustomTemplate?: boolean;
|
||||
/** Suggested default model configuration */
|
||||
suggestedDefaults?: OpenClawSuggestedDefaults;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,8 +64,18 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
apiKey: "",
|
||||
api: "openai-completions",
|
||||
models: [
|
||||
{ id: "deepseek-chat", name: "DeepSeek V3.2" },
|
||||
{ id: "deepseek-reasoner", name: "DeepSeek R1" },
|
||||
{
|
||||
id: "deepseek-chat",
|
||||
name: "DeepSeek V3.2",
|
||||
contextWindow: 64000,
|
||||
cost: { input: 0.0005, output: 0.002 },
|
||||
},
|
||||
{
|
||||
id: "deepseek-reasoner",
|
||||
name: "DeepSeek R1",
|
||||
contextWindow: 64000,
|
||||
cost: { input: 0.0005, output: 0.002 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "cn_official",
|
||||
@@ -64,6 +88,16 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: {
|
||||
primary: "deepseek/deepseek-chat",
|
||||
fallbacks: ["deepseek/deepseek-reasoner"],
|
||||
},
|
||||
modelCatalog: {
|
||||
"deepseek/deepseek-chat": { alias: "DeepSeek" },
|
||||
"deepseek/deepseek-reasoner": { alias: "R1" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Zhipu GLM",
|
||||
@@ -73,7 +107,14 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
baseUrl: "https://open.bigmodel.cn/api/paas/v4",
|
||||
apiKey: "",
|
||||
api: "openai-completions",
|
||||
models: [{ id: "glm-4.7", name: "GLM-4.7" }],
|
||||
models: [
|
||||
{
|
||||
id: "glm-4.7",
|
||||
name: "GLM-4.7",
|
||||
contextWindow: 128000,
|
||||
cost: { input: 0.001, output: 0.001 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "cn_official",
|
||||
isPartner: true,
|
||||
@@ -93,6 +134,10 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: { primary: "zhipu/glm-4.7" },
|
||||
modelCatalog: { "zhipu/glm-4.7": { alias: "GLM" } },
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Qwen Coder",
|
||||
@@ -102,7 +147,14 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
||||
apiKey: "",
|
||||
api: "openai-completions",
|
||||
models: [{ id: "qwen3-max", name: "Qwen3 Max" }],
|
||||
models: [
|
||||
{
|
||||
id: "qwen3-max",
|
||||
name: "Qwen3 Max",
|
||||
contextWindow: 32000,
|
||||
cost: { input: 0.002, output: 0.006 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "cn_official",
|
||||
icon: "qwen",
|
||||
@@ -120,6 +172,10 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: { primary: "qwen/qwen3-max" },
|
||||
modelCatalog: { "qwen/qwen3-max": { alias: "Qwen" } },
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Kimi k2.5",
|
||||
@@ -129,7 +185,14 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
baseUrl: "https://api.moonshot.cn/v1",
|
||||
apiKey: "",
|
||||
api: "openai-completions",
|
||||
models: [{ id: "kimi-k2.5", name: "Kimi K2.5" }],
|
||||
models: [
|
||||
{
|
||||
id: "kimi-k2.5",
|
||||
name: "Kimi K2.5",
|
||||
contextWindow: 131072,
|
||||
cost: { input: 0.002, output: 0.006 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "cn_official",
|
||||
icon: "kimi",
|
||||
@@ -147,6 +210,10 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: { primary: "kimi/kimi-k2.5" },
|
||||
modelCatalog: { "kimi/kimi-k2.5": { alias: "Kimi" } },
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MiniMax",
|
||||
@@ -156,7 +223,14 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
baseUrl: "https://api.minimaxi.com/v1",
|
||||
apiKey: "",
|
||||
api: "openai-completions",
|
||||
models: [{ id: "MiniMax-M2.1", name: "MiniMax M2.1" }],
|
||||
models: [
|
||||
{
|
||||
id: "MiniMax-M2.1",
|
||||
name: "MiniMax M2.1",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 0.001, output: 0.004 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "cn_official",
|
||||
isPartner: true,
|
||||
@@ -174,6 +248,10 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: { primary: "minimax/MiniMax-M2.1" },
|
||||
modelCatalog: { "minimax/MiniMax-M2.1": { alias: "MiniMax" } },
|
||||
},
|
||||
},
|
||||
|
||||
// ========== Aggregators ==========
|
||||
@@ -186,8 +264,18 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
apiKey: "",
|
||||
api: "anthropic",
|
||||
models: [
|
||||
{ id: "claude-sonnet-4-5-20250929", name: "Claude Sonnet 4.5" },
|
||||
{ id: "claude-opus-4-5-20251101", name: "Claude Opus 4.5" },
|
||||
{
|
||||
id: "claude-sonnet-4-5-20250929",
|
||||
name: "Claude Sonnet 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 3, output: 15 },
|
||||
},
|
||||
{
|
||||
id: "claude-opus-4-5-20251101",
|
||||
name: "Claude Opus 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 15, output: 75 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "aggregator",
|
||||
@@ -200,6 +288,16 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: {
|
||||
primary: "aihubmix/claude-sonnet-4-5-20250929",
|
||||
fallbacks: ["aihubmix/claude-opus-4-5-20251101"],
|
||||
},
|
||||
modelCatalog: {
|
||||
"aihubmix/claude-sonnet-4-5-20250929": { alias: "Sonnet" },
|
||||
"aihubmix/claude-opus-4-5-20251101": { alias: "Opus" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DMXAPI",
|
||||
@@ -210,8 +308,18 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
apiKey: "",
|
||||
api: "anthropic",
|
||||
models: [
|
||||
{ id: "claude-sonnet-4-5-20250929", name: "Claude Sonnet 4.5" },
|
||||
{ id: "claude-opus-4-5-20251101", name: "Claude Opus 4.5" },
|
||||
{
|
||||
id: "claude-sonnet-4-5-20250929",
|
||||
name: "Claude Sonnet 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 3, output: 15 },
|
||||
},
|
||||
{
|
||||
id: "claude-opus-4-5-20251101",
|
||||
name: "Claude Opus 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 15, output: 75 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "aggregator",
|
||||
@@ -224,6 +332,16 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: {
|
||||
primary: "dmxapi/claude-sonnet-4-5-20250929",
|
||||
fallbacks: ["dmxapi/claude-opus-4-5-20251101"],
|
||||
},
|
||||
modelCatalog: {
|
||||
"dmxapi/claude-sonnet-4-5-20250929": { alias: "Sonnet" },
|
||||
"dmxapi/claude-opus-4-5-20251101": { alias: "Opus" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "OpenRouter",
|
||||
@@ -234,8 +352,18 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
apiKey: "",
|
||||
api: "openai-completions",
|
||||
models: [
|
||||
{ id: "anthropic/claude-sonnet-4.5", name: "Claude Sonnet 4.5" },
|
||||
{ id: "anthropic/claude-opus-4.5", name: "Claude Opus 4.5" },
|
||||
{
|
||||
id: "anthropic/claude-sonnet-4.5",
|
||||
name: "Claude Sonnet 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 3, output: 15 },
|
||||
},
|
||||
{
|
||||
id: "anthropic/claude-opus-4.5",
|
||||
name: "Claude Opus 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 15, output: 75 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "aggregator",
|
||||
@@ -248,6 +376,16 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: {
|
||||
primary: "openrouter/anthropic/claude-sonnet-4.5",
|
||||
fallbacks: ["openrouter/anthropic/claude-opus-4.5"],
|
||||
},
|
||||
modelCatalog: {
|
||||
"openrouter/anthropic/claude-sonnet-4.5": { alias: "Sonnet" },
|
||||
"openrouter/anthropic/claude-opus-4.5": { alias: "Opus" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ModelScope",
|
||||
@@ -257,7 +395,14 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
baseUrl: "https://api-inference.modelscope.cn/v1",
|
||||
apiKey: "",
|
||||
api: "openai-completions",
|
||||
models: [{ id: "ZhipuAI/GLM-4.7", name: "GLM-4.7" }],
|
||||
models: [
|
||||
{
|
||||
id: "ZhipuAI/GLM-4.7",
|
||||
name: "GLM-4.7",
|
||||
contextWindow: 128000,
|
||||
cost: { input: 0.001, output: 0.001 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "aggregator",
|
||||
icon: "modelscope",
|
||||
@@ -275,6 +420,10 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: { primary: "modelscope/ZhipuAI/GLM-4.7" },
|
||||
modelCatalog: { "modelscope/ZhipuAI/GLM-4.7": { alias: "GLM" } },
|
||||
},
|
||||
},
|
||||
|
||||
// ========== Third Party Partners ==========
|
||||
@@ -287,8 +436,18 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
apiKey: "",
|
||||
api: "anthropic",
|
||||
models: [
|
||||
{ id: "claude-sonnet-4-5-20250929", name: "Claude Sonnet 4.5" },
|
||||
{ id: "claude-opus-4-5-20251101", name: "Claude Opus 4.5" },
|
||||
{
|
||||
id: "claude-sonnet-4-5-20250929",
|
||||
name: "Claude Sonnet 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 3, output: 15 },
|
||||
},
|
||||
{
|
||||
id: "claude-opus-4-5-20251101",
|
||||
name: "Claude Opus 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 15, output: 75 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "third_party",
|
||||
@@ -302,6 +461,16 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: {
|
||||
primary: "packycode/claude-sonnet-4-5-20250929",
|
||||
fallbacks: ["packycode/claude-opus-4-5-20251101"],
|
||||
},
|
||||
modelCatalog: {
|
||||
"packycode/claude-sonnet-4-5-20250929": { alias: "Sonnet" },
|
||||
"packycode/claude-opus-4-5-20251101": { alias: "Opus" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Cubence",
|
||||
@@ -312,8 +481,18 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
apiKey: "",
|
||||
api: "anthropic",
|
||||
models: [
|
||||
{ id: "claude-sonnet-4-5-20250929", name: "Claude Sonnet 4.5" },
|
||||
{ id: "claude-opus-4-5-20251101", name: "Claude Opus 4.5" },
|
||||
{
|
||||
id: "claude-sonnet-4-5-20250929",
|
||||
name: "Claude Sonnet 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 3, output: 15 },
|
||||
},
|
||||
{
|
||||
id: "claude-opus-4-5-20251101",
|
||||
name: "Claude Opus 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 15, output: 75 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "third_party",
|
||||
@@ -328,6 +507,16 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: {
|
||||
primary: "cubence/claude-sonnet-4-5-20250929",
|
||||
fallbacks: ["cubence/claude-opus-4-5-20251101"],
|
||||
},
|
||||
modelCatalog: {
|
||||
"cubence/claude-sonnet-4-5-20250929": { alias: "Sonnet" },
|
||||
"cubence/claude-opus-4-5-20251101": { alias: "Opus" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AIGoCode",
|
||||
@@ -338,8 +527,18 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
apiKey: "",
|
||||
api: "anthropic",
|
||||
models: [
|
||||
{ id: "claude-sonnet-4-5-20250929", name: "Claude Sonnet 4.5" },
|
||||
{ id: "claude-opus-4-5-20251101", name: "Claude Opus 4.5" },
|
||||
{
|
||||
id: "claude-sonnet-4-5-20250929",
|
||||
name: "Claude Sonnet 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 3, output: 15 },
|
||||
},
|
||||
{
|
||||
id: "claude-opus-4-5-20251101",
|
||||
name: "Claude Opus 4.5",
|
||||
contextWindow: 200000,
|
||||
cost: { input: 15, output: 75 },
|
||||
},
|
||||
],
|
||||
},
|
||||
category: "third_party",
|
||||
@@ -354,6 +553,16 @@ export const openclawProviderPresets: OpenClawProviderPreset[] = [
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
suggestedDefaults: {
|
||||
model: {
|
||||
primary: "aigocode/claude-sonnet-4-5-20250929",
|
||||
fallbacks: ["aigocode/claude-opus-4-5-20251101"],
|
||||
},
|
||||
modelCatalog: {
|
||||
"aigocode/claude-sonnet-4-5-20250929": { alias: "Sonnet" },
|
||||
"aigocode/claude-opus-4-5-20251101": { alias: "Opus" },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// ========== Custom Template ==========
|
||||
|
||||
@@ -1745,5 +1745,34 @@
|
||||
"unspecifiedHigh": "Uncategorized high-effort task category for tasks that don't fit other categories with large workload. Defaults to Claude Opus 4.6 max variant.",
|
||||
"writing": "Writing category for documentation, prose and technical writing. Defaults to Gemini 3 Flash fast generation model."
|
||||
}
|
||||
},
|
||||
"openclawConfig": {
|
||||
"defaultModel": {
|
||||
"title": "Default Model",
|
||||
"description": "Configure the default primary model and fallback models for OpenClaw",
|
||||
"primary": "Primary Model",
|
||||
"primaryPlaceholder": "e.g., deepseek/deepseek-chat",
|
||||
"fallbacks": "Fallback Models",
|
||||
"fallbacksPlaceholder": "e.g., openrouter/anthropic/claude-sonnet-4.5",
|
||||
"addFallback": "Add Fallback Model",
|
||||
"saved": "Default model configuration saved",
|
||||
"saveFailed": "Failed to save default model"
|
||||
},
|
||||
"modelCatalog": {
|
||||
"title": "Model Catalog",
|
||||
"description": "Configure model aliases and allowlist",
|
||||
"modelId": "Model ID",
|
||||
"modelIdPlaceholder": "e.g., deepseek/deepseek-chat",
|
||||
"alias": "Alias",
|
||||
"aliasPlaceholder": "e.g., DeepSeek",
|
||||
"addEntry": "Add Model",
|
||||
"removeEntry": "Remove",
|
||||
"saved": "Model catalog saved",
|
||||
"saveFailed": "Failed to save model catalog",
|
||||
"empty": "No model catalog entries",
|
||||
"emptyHint": "Add models to the catalog to configure aliases"
|
||||
},
|
||||
"suggestedDefaults": "Apply Suggested Defaults",
|
||||
"suggestedDefaultsHint": "Use this preset's recommended default model configuration"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1726,5 +1726,34 @@
|
||||
"unspecifiedHigh": "未分類の高作業量タスクカテゴリ。他のカテゴリに該当せず作業量が大きいタスクに適用。デフォルトで Claude Opus 4.6 の max バリアントを使用。",
|
||||
"writing": "ライティングカテゴリ。ドキュメント、散文、技術文書に特化。デフォルトで Gemini 3 Flash 高速生成モデルを使用。"
|
||||
}
|
||||
},
|
||||
"openclawConfig": {
|
||||
"defaultModel": {
|
||||
"title": "デフォルトモデル",
|
||||
"description": "OpenClaw のデフォルトのプライマリモデルとフォールバックモデルを設定します",
|
||||
"primary": "プライマリモデル",
|
||||
"primaryPlaceholder": "例: deepseek/deepseek-chat",
|
||||
"fallbacks": "フォールバックモデル",
|
||||
"fallbacksPlaceholder": "例: openrouter/anthropic/claude-sonnet-4.5",
|
||||
"addFallback": "フォールバックモデルを追加",
|
||||
"saved": "デフォルトモデル設定を保存しました",
|
||||
"saveFailed": "デフォルトモデルの保存に失敗しました"
|
||||
},
|
||||
"modelCatalog": {
|
||||
"title": "モデルカタログ",
|
||||
"description": "モデルのエイリアスと許可リストを設定します",
|
||||
"modelId": "モデル ID",
|
||||
"modelIdPlaceholder": "例: deepseek/deepseek-chat",
|
||||
"alias": "エイリアス",
|
||||
"aliasPlaceholder": "例: DeepSeek",
|
||||
"addEntry": "モデルを追加",
|
||||
"removeEntry": "削除",
|
||||
"saved": "モデルカタログを保存しました",
|
||||
"saveFailed": "モデルカタログの保存に失敗しました",
|
||||
"empty": "モデルカタログエントリがありません",
|
||||
"emptyHint": "エイリアスを設定するにはカタログにモデルを追加してください"
|
||||
},
|
||||
"suggestedDefaults": "推奨デフォルト設定を適用",
|
||||
"suggestedDefaultsHint": "このプリセットの推奨デフォルトモデル設定を使用します"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1745,5 +1745,34 @@
|
||||
"unspecifiedHigh": "未归类高工作量任务类别,适用于不适合其他类别且工作量较大的任务,默认使用 Claude Opus 4.6 的最大变体。",
|
||||
"writing": "写作类别,专注于文档、散文和技术写作,默认使用 Gemini 3 Flash 快速生成模型。"
|
||||
}
|
||||
},
|
||||
"openclawConfig": {
|
||||
"defaultModel": {
|
||||
"title": "默认模型",
|
||||
"description": "配置 OpenClaw 的默认主模型和回退模型",
|
||||
"primary": "主模型",
|
||||
"primaryPlaceholder": "例如: deepseek/deepseek-chat",
|
||||
"fallbacks": "回退模型",
|
||||
"fallbacksPlaceholder": "例如: openrouter/anthropic/claude-sonnet-4.5",
|
||||
"addFallback": "添加回退模型",
|
||||
"saved": "默认模型配置已保存",
|
||||
"saveFailed": "保存默认模型失败"
|
||||
},
|
||||
"modelCatalog": {
|
||||
"title": "模型目录",
|
||||
"description": "配置可用模型的别名和允许列表",
|
||||
"modelId": "模型 ID",
|
||||
"modelIdPlaceholder": "例如: deepseek/deepseek-chat",
|
||||
"alias": "别名",
|
||||
"aliasPlaceholder": "例如: DeepSeek",
|
||||
"addEntry": "添加模型",
|
||||
"removeEntry": "移除",
|
||||
"saved": "模型目录已保存",
|
||||
"saveFailed": "保存模型目录失败",
|
||||
"empty": "暂无模型目录配置",
|
||||
"emptyHint": "添加模型到目录以配置别名"
|
||||
},
|
||||
"suggestedDefaults": "应用建议默认配置",
|
||||
"suggestedDefaultsHint": "使用此预设推荐的默认模型配置"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import type {
|
||||
OpenClawDefaultModel,
|
||||
OpenClawModelCatalogEntry,
|
||||
} from "@/types";
|
||||
|
||||
/**
|
||||
* OpenClaw agents configuration API
|
||||
*
|
||||
* Manages agents.defaults configuration in ~/.openclaw/openclaw.json
|
||||
*/
|
||||
export const openclawApi = {
|
||||
/**
|
||||
* Get default model configuration (agents.defaults.model)
|
||||
*/
|
||||
async getDefaultModel(): Promise<OpenClawDefaultModel | null> {
|
||||
return await invoke("get_openclaw_default_model");
|
||||
},
|
||||
|
||||
/**
|
||||
* Set default model configuration (agents.defaults.model)
|
||||
*/
|
||||
async setDefaultModel(model: OpenClawDefaultModel): Promise<void> {
|
||||
return await invoke("set_openclaw_default_model", { model });
|
||||
},
|
||||
|
||||
/**
|
||||
* Get model catalog/allowlist (agents.defaults.models)
|
||||
*/
|
||||
async getModelCatalog(): Promise<Record<
|
||||
string,
|
||||
OpenClawModelCatalogEntry
|
||||
> | null> {
|
||||
return await invoke("get_openclaw_model_catalog");
|
||||
},
|
||||
|
||||
/**
|
||||
* Set model catalog/allowlist (agents.defaults.models)
|
||||
*/
|
||||
async setModelCatalog(
|
||||
catalog: Record<string, OpenClawModelCatalogEntry>,
|
||||
): Promise<void> {
|
||||
return await invoke("set_openclaw_model_catalog", { catalog });
|
||||
},
|
||||
|
||||
/**
|
||||
* Import providers from live config (openclaw.json) to database
|
||||
*/
|
||||
async importProvidersFromLive(): Promise<number> {
|
||||
return await invoke("import_openclaw_providers_from_live");
|
||||
},
|
||||
|
||||
/**
|
||||
* Get provider IDs that exist in live config (openclaw.json)
|
||||
*/
|
||||
async getLiveProviderIds(): Promise<string[]> {
|
||||
return await invoke("get_openclaw_live_provider_ids");
|
||||
},
|
||||
};
|
||||
@@ -434,6 +434,20 @@ export interface OpenCodeMcpServerSpec {
|
||||
export interface OpenClawModel {
|
||||
id: string;
|
||||
name: string;
|
||||
alias?: string;
|
||||
cost?: { input: number; output: number };
|
||||
contextWindow?: number;
|
||||
}
|
||||
|
||||
// OpenClaw 默认模型配置(agents.defaults.model)
|
||||
export interface OpenClawDefaultModel {
|
||||
primary: string;
|
||||
fallbacks?: string[];
|
||||
}
|
||||
|
||||
// OpenClaw 模型目录条目(agents.defaults.models 中的值)
|
||||
export interface OpenClawModelCatalogEntry {
|
||||
alias?: string;
|
||||
}
|
||||
|
||||
// OpenClaw 供应商配置(settings_config 结构)
|
||||
|
||||
Reference in New Issue
Block a user