) =>
setForm((f) => ({ ...f, [key]: e.target.value }))
const handleSave = async () => {
@@ -125,6 +131,9 @@ export function EditModelSheet({
: undefined,
thinking_level: form.thinkingLevel || undefined,
extra_headers: form.extraHeaders.trim() ? JSON.parse(form.extraHeaders.trim()) : undefined,
+ extra_body: form.extraBody.trim()
+ ? JSON.parse(form.extraBody.trim())
+ : {},
})
if (setAsDefault && !model.is_default) {
await setDefaultModel(model.model_name)
@@ -298,6 +307,14 @@ export function EditModelSheet({
value={form.extraHeaders}
onChange={setField("extraHeaders")}
placeholder='{"X-My-Header": "value"}'
+ label={t("models.field.extraBody")}
+ hint={t("models.field.extraBodyHint")}
+ >
+
diff --git a/web/frontend/src/components/models/model-card.tsx b/web/frontend/src/components/models/model-card.tsx
index 316e05e4d..319cb11a3 100644
--- a/web/frontend/src/components/models/model-card.tsx
+++ b/web/frontend/src/components/models/model-card.tsx
@@ -28,7 +28,7 @@ export function ModelCard({
}: ModelCardProps) {
const { t } = useTranslation()
const isOAuth = model.auth_method === "oauth"
- const canSetDefault = model.configured && !model.is_default
+ const canSetDefault = model.configured && !model.is_default && !model.is_virtual
return (
)}
+ {model.is_virtual && (
+
+ {t("models.badge.virtual")}
+
+ )}
diff --git a/web/frontend/src/i18n/locales/en.json b/web/frontend/src/i18n/locales/en.json
index fc196194e..cf6cdf0f0 100644
--- a/web/frontend/src/i18n/locales/en.json
+++ b/web/frontend/src/i18n/locales/en.json
@@ -154,7 +154,8 @@
"unconfigured": "Not configured"
},
"badge": {
- "default": "Default"
+ "default": "Default",
+ "virtual": "Virtual"
},
"action": {
"edit": "Edit API key",
@@ -211,6 +212,8 @@
"maxTokensFieldHint": "Override the request field name for max tokens, e.g. max_completion_tokens.",
"extraHeaders": "Extra Headers",
"extraHeadersHint": "Custom HTTP headers in JSON format, e.g. {\"X-My-Header\": \"value\"}"
+ "extraBody": "Extra Body",
+ "extraBodyHint": "Additional JSON fields to inject into the request body, e.g. {\"reasoning_split\": true}."
},
"edit": {
"title": "Configure {{name}}",
@@ -434,6 +437,13 @@
"custom_allow_patterns": "Command Whitelist",
"custom_allow_patterns_hint": "Add extra command-allow rules, one regular expression per line. A command matching any rule here skips blacklist matching, but other safety limits still apply.",
"custom_patterns_placeholder": "^rm\\s+-rf\\b\n^git\\s+push\\b",
+ "pattern_detector_title": "Pattern Detection Tool",
+ "pattern_detector_hint": "Enter a command to test if it matches any blacklist or whitelist patterns.",
+ "pattern_detector_input_placeholder": "Enter a command to test, e.g., rm -rf /tmp",
+ "pattern_detector_test_button": "Test",
+ "pattern_detector_result_allowed": "Allowed (matches whitelist)",
+ "pattern_detector_result_blocked": "Blocked (matches blacklist)",
+ "pattern_detector_result_no_match": "No match (will use default rules)",
"allow_shell_execution": "Allow Scheduled Commands",
"allow_shell_execution_hint": "Allow scheduled tasks to run commands by default. When disabled, users must pass command_confirm=true to schedule a command task.",
"cron_exec_timeout": "Scheduled Command Timeout (minutes)",
diff --git a/web/frontend/src/i18n/locales/zh.json b/web/frontend/src/i18n/locales/zh.json
index 69ca939cb..7eb14e983 100644
--- a/web/frontend/src/i18n/locales/zh.json
+++ b/web/frontend/src/i18n/locales/zh.json
@@ -154,7 +154,8 @@
"unconfigured": "未配置"
},
"badge": {
- "default": "默认"
+ "default": "默认",
+ "virtual": "虚拟"
},
"action": {
"edit": "编辑 API Key",
@@ -208,7 +209,9 @@
"thinkingLevel": "思考级别",
"thinkingLevelHint": "扩展思考预算:off、low、medium、high、xhigh、adaptive。",
"maxTokensField": "Max Tokens 字段名",
- "maxTokensFieldHint": "覆盖请求中 max_tokens 的字段名,例如 max_completion_tokens。"
+ "maxTokensFieldHint": "覆盖请求中 max_tokens 的字段名,例如 max_completion_tokens。",
+ "extraBody": "Extra Body",
+ "extraBodyHint": "要注入到请求体中的额外 JSON 字段,例如 {\"reasoning_split\": true}。"
},
"edit": {
"title": "配置 {{name}}",
@@ -432,6 +435,13 @@
"custom_allow_patterns": "命令白名单",
"custom_allow_patterns_hint": "用于补充额外的命令放行规则,每行一个正则表达式。命中任意一条规则的命令会跳过黑名单检查,但仍受其他安全限制约束。",
"custom_patterns_placeholder": "^rm\\s+-rf\\b\n^git\\s+push\\b",
+ "pattern_detector_title": "规则检测工具",
+ "pattern_detector_hint": "输入命令以检测其是否匹配黑名单或白名单规则。",
+ "pattern_detector_input_placeholder": "输入要检测的命令,例如 rm -rf /tmp",
+ "pattern_detector_test_button": "检测",
+ "pattern_detector_result_allowed": "允许(匹配白名单)",
+ "pattern_detector_result_blocked": "阻止(匹配黑名单)",
+ "pattern_detector_result_no_match": "无匹配(将使用默认规则)",
"allow_shell_execution": "允许定时任务运行命令",
"allow_shell_execution_hint": "开启后,定时任务默认允许运行命令。关闭后,必须显式传入 command_confirm=true 才能创建运行命令的定时任务。",
"cron_exec_timeout": "定时命令超时(分钟)",