diff --git a/src/features/authFiles/components/AuthFilesPrefixProxyEditorModal.tsx b/src/features/authFiles/components/AuthFilesPrefixProxyEditorModal.tsx
index 4a1c8b7..8e811c9 100644
--- a/src/features/authFiles/components/AuthFilesPrefixProxyEditorModal.tsx
+++ b/src/features/authFiles/components/AuthFilesPrefixProxyEditorModal.tsx
@@ -138,6 +138,18 @@ export function AuthFilesPrefixProxyEditorModal(props: AuthFilesPrefixProxyEdito
/>
{t('auth_files.excluded_models_hint')}
+
+
+
(null);
- const prefixProxyUpdatedText = buildPrefixProxyUpdatedText(prefixProxyEditor);
+ let prefixProxyUpdatedText = '';
+ try {
+ prefixProxyUpdatedText = buildPrefixProxyUpdatedText(prefixProxyEditor);
+ } catch {
+ // Catch JSON parsing errors during render so the UI doesn't crash.
+ }
+
const prefixProxyDirty =
Boolean(prefixProxyEditor?.json) &&
Boolean(prefixProxyEditor?.originalText) &&
- prefixProxyUpdatedText !== prefixProxyEditor?.originalText;
+ (prefixProxyUpdatedText === '' || prefixProxyUpdatedText !== prefixProxyEditor?.originalText);
const closePrefixProxyEditor = () => {
setPrefixProxyEditor(null);
@@ -162,6 +185,7 @@ export function useAuthFilesPrefixProxyEditor(
websockets: false,
note: '',
noteTouched: false,
+ headersText: '',
});
try {
@@ -213,6 +237,11 @@ export function useAuthFilesPrefixProxyEditor(
const disableCoolingValue = parseDisableCoolingValue(json.disable_cooling);
const websocketsValue = readCodexAuthFileWebsockets(json);
const note = typeof json.note === 'string' ? json.note : '';
+ const headers = json.headers;
+ let headersText = '';
+ if (headers && typeof headers === 'object') {
+ headersText = JSON.stringify(headers, null, 2);
+ }
setPrefixProxyEditor((prev) => {
if (!prev || prev.fileName !== name) return prev;
@@ -231,6 +260,7 @@ export function useAuthFilesPrefixProxyEditor(
websockets: websocketsValue,
note,
noteTouched: false,
+ headersText,
error: null,
};
});
@@ -256,6 +286,7 @@ export function useAuthFilesPrefixProxyEditor(
if (field === 'excludedModelsText') return { ...prev, excludedModelsText: String(value) };
if (field === 'disableCooling') return { ...prev, disableCooling: String(value) };
if (field === 'note') return { ...prev, note: String(value), noteTouched: true };
+ if (field === 'headersText') return { ...prev, headersText: String(value) };
return { ...prev, websockets: Boolean(value) };
});
};
@@ -265,7 +296,15 @@ export function useAuthFilesPrefixProxyEditor(
if (!prefixProxyDirty) return;
const name = prefixProxyEditor.fileName;
- const payload = prefixProxyUpdatedText;
+ let payload = '';
+ try {
+ payload = buildPrefixProxyUpdatedText(prefixProxyEditor);
+ } catch (err: unknown) {
+ const errorMessage = err instanceof Error ? err.message : 'Invalid format';
+ showNotification(errorMessage, 'error');
+ return;
+ }
+
const fileSize = new Blob([payload]).size;
if (fileSize > MAX_AUTH_FILE_SIZE) {
showNotification(
diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json
index a584ae9..0a97499 100644
--- a/src/i18n/locales/en.json
+++ b/src/i18n/locales/en.json
@@ -597,6 +597,9 @@
"note_placeholder": "Enter a note, e.g.: John's account",
"note_hint": "Optional. Used to describe the purpose or owner of this credential; leave empty to omit.",
"note_display": "Note",
+ "headers_label": "Custom Headers (headers)",
+ "headers_placeholder": "{\n \"Header-Name\": \"value\"\n}",
+ "headers_hint": "Enter custom HTTP headers as a JSON object, e.g., {\"X-My-Header\": \"value\"}",
"prefix_proxy_invalid_json": "This auth file is not a JSON object, so fields cannot be edited.",
"prefix_proxy_saved_success": "Updated auth file \"{{name}}\" successfully",
"quota_refresh_success": "Quota refreshed for \"{{name}}\"",
diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json
index bb2ce2b..48bcd16 100644
--- a/src/i18n/locales/zh-CN.json
+++ b/src/i18n/locales/zh-CN.json
@@ -597,6 +597,9 @@
"note_placeholder": "输入备注信息,例如:张三的账号",
"note_hint": "可选,用于标记凭证用途或归属;留空则不写入。",
"note_display": "备注",
+ "headers_label": "自定义请求头(headers)",
+ "headers_placeholder": "{\n \"Header-Name\": \"value\"\n}",
+ "headers_hint": "以 JSON 对象格式输入自定义 HTTP 请求头,例如:{\"X-My-Header\": \"value\"}",
"prefix_proxy_invalid_json": "该认证文件不是 JSON 对象,无法编辑字段。",
"prefix_proxy_saved_success": "已更新认证文件 \"{{name}}\"",
"quota_refresh_success": "已刷新 \"{{name}}\" 的额度",