Forráskód Böngészése

Merge pull request #655 from ding113/dev

release:v0.5.1
Ding 2 hete
szülő
commit
39bc5e880a
100 módosított fájl, 5324 hozzáadás és 170 törlés
  1. 18 7
      .env.example
  2. 2 0
      .gitignore
  3. 1 1
      VERSION
  4. 67 0
      drizzle/0056_tidy_quasar.sql
  5. 2890 0
      drizzle/meta/0056_snapshot.json
  6. 7 0
      drizzle/meta/_journal.json
  7. 1 0
      messages/en/common.json
  8. 13 3
      messages/en/customs.json
  9. 222 11
      messages/en/dashboard.json
  10. 6 0
      messages/en/errors.json
  11. 2 2
      messages/en/myUsage.json
  12. 43 0
      messages/en/provider-chain.json
  13. 7 1
      messages/en/settings/clientVersions.json
  14. 1 0
      messages/en/settings/data.json
  15. 5 0
      messages/en/settings/index.ts
  16. 2 0
      messages/en/settings/notifications.json
  17. 43 0
      messages/en/settings/providers/batchEdit.json
  18. 8 1
      messages/en/settings/providers/form/common.json
  19. 1 0
      messages/en/settings/providers/form/key.json
  20. 1 1
      messages/en/settings/providers/form/name.json
  21. 15 0
      messages/en/settings/providers/form/quickPaste.json
  22. 29 8
      messages/en/settings/providers/form/sections.json
  23. 3 1
      messages/en/settings/providers/form/success.json
  24. 1 1
      messages/en/settings/providers/form/url.json
  25. 12 1
      messages/en/settings/providers/form/urlPreview.json
  26. 57 1
      messages/en/settings/providers/strings.json
  27. 1 0
      messages/ja/common.json
  28. 13 3
      messages/ja/customs.json
  29. 288 11
      messages/ja/dashboard.json
  30. 6 0
      messages/ja/errors.json
  31. 2 2
      messages/ja/myUsage.json
  32. 43 0
      messages/ja/provider-chain.json
  33. 7 1
      messages/ja/settings/clientVersions.json
  34. 1 0
      messages/ja/settings/data.json
  35. 5 0
      messages/ja/settings/index.ts
  36. 2 0
      messages/ja/settings/notifications.json
  37. 43 0
      messages/ja/settings/providers/batchEdit.json
  38. 8 1
      messages/ja/settings/providers/form/common.json
  39. 1 0
      messages/ja/settings/providers/form/key.json
  40. 1 1
      messages/ja/settings/providers/form/name.json
  41. 15 0
      messages/ja/settings/providers/form/quickPaste.json
  42. 30 8
      messages/ja/settings/providers/form/sections.json
  43. 3 1
      messages/ja/settings/providers/form/success.json
  44. 1 1
      messages/ja/settings/providers/form/url.json
  45. 12 1
      messages/ja/settings/providers/form/urlPreview.json
  46. 57 1
      messages/ja/settings/providers/strings.json
  47. 1 0
      messages/ru/common.json
  48. 13 3
      messages/ru/customs.json
  49. 233 19
      messages/ru/dashboard.json
  50. 6 0
      messages/ru/errors.json
  51. 2 2
      messages/ru/myUsage.json
  52. 43 0
      messages/ru/provider-chain.json
  53. 7 1
      messages/ru/settings/clientVersions.json
  54. 1 0
      messages/ru/settings/data.json
  55. 5 0
      messages/ru/settings/index.ts
  56. 2 0
      messages/ru/settings/notifications.json
  57. 43 0
      messages/ru/settings/providers/batchEdit.json
  58. 8 1
      messages/ru/settings/providers/form/common.json
  59. 1 0
      messages/ru/settings/providers/form/key.json
  60. 1 1
      messages/ru/settings/providers/form/name.json
  61. 15 0
      messages/ru/settings/providers/form/quickPaste.json
  62. 31 9
      messages/ru/settings/providers/form/sections.json
  63. 3 1
      messages/ru/settings/providers/form/success.json
  64. 1 1
      messages/ru/settings/providers/form/url.json
  65. 12 1
      messages/ru/settings/providers/form/urlPreview.json
  66. 57 1
      messages/ru/settings/providers/strings.json
  67. 1 0
      messages/zh-CN/common.json
  68. 13 3
      messages/zh-CN/customs.json
  69. 222 11
      messages/zh-CN/dashboard.json
  70. 6 0
      messages/zh-CN/errors.json
  71. 2 2
      messages/zh-CN/myUsage.json
  72. 43 0
      messages/zh-CN/provider-chain.json
  73. 7 1
      messages/zh-CN/settings/clientVersions.json
  74. 1 0
      messages/zh-CN/settings/data.json
  75. 5 0
      messages/zh-CN/settings/index.ts
  76. 2 0
      messages/zh-CN/settings/notifications.json
  77. 43 0
      messages/zh-CN/settings/providers/batchEdit.json
  78. 8 1
      messages/zh-CN/settings/providers/form/common.json
  79. 1 0
      messages/zh-CN/settings/providers/form/key.json
  80. 1 1
      messages/zh-CN/settings/providers/form/name.json
  81. 15 0
      messages/zh-CN/settings/providers/form/quickPaste.json
  82. 30 9
      messages/zh-CN/settings/providers/form/sections.json
  83. 3 1
      messages/zh-CN/settings/providers/form/success.json
  84. 1 1
      messages/zh-CN/settings/providers/form/url.json
  85. 12 1
      messages/zh-CN/settings/providers/form/urlPreview.json
  86. 57 1
      messages/zh-CN/settings/providers/strings.json
  87. 1 0
      messages/zh-TW/common.json
  88. 13 3
      messages/zh-TW/customs.json
  89. 237 20
      messages/zh-TW/dashboard.json
  90. 6 0
      messages/zh-TW/errors.json
  91. 2 2
      messages/zh-TW/myUsage.json
  92. 43 0
      messages/zh-TW/provider-chain.json
  93. 7 1
      messages/zh-TW/settings/clientVersions.json
  94. 1 0
      messages/zh-TW/settings/data.json
  95. 5 0
      messages/zh-TW/settings/index.ts
  96. 2 0
      messages/zh-TW/settings/notifications.json
  97. 43 0
      messages/zh-TW/settings/providers/batchEdit.json
  98. 8 1
      messages/zh-TW/settings/providers/form/common.json
  99. 1 0
      messages/zh-TW/settings/providers/form/key.json
  100. 1 1
      messages/zh-TW/settings/providers/form/name.json

+ 18 - 7
.env.example

@@ -60,8 +60,10 @@ REDIS_TLS_REJECT_UNAUTHORIZED=true      # 是否验证 Redis TLS 证书(默认
 
 
 # Session 配置
 # Session 配置
 SESSION_TTL=300                         # Session 过期时间(秒,默认 300 = 5 分钟)
 SESSION_TTL=300                         # Session 过期时间(秒,默认 300 = 5 分钟)
-STORE_SESSION_MESSAGES=false            # 是否存储请求 messages 到 Redis(用于实时监控页面查看详情,默认:false)
-                                        # 警告:启用后会增加 Redis 内存使用,且可能包含敏感信息
+STORE_SESSION_MESSAGES=false            # 会话消息存储模式(默认:false)
+                                        # - false:存储请求/响应体但对 message 内容脱敏 [REDACTED]
+                                        # - true:原样存储 message 内容(注意隐私和存储空间影响)
+                                        # 警告:启用后会增加 Redis/DB 存储空间,且包含敏感信息
 
 
 # 熔断器配置
 # 熔断器配置
 # 功能说明:控制网络错误是否计入熔断器失败计数
 # 功能说明:控制网络错误是否计入熔断器失败计数
@@ -119,8 +121,17 @@ ENABLE_SMART_PROBING=false
 PROBE_INTERVAL_MS=30000
 PROBE_INTERVAL_MS=30000
 PROBE_TIMEOUT_MS=5000
 PROBE_TIMEOUT_MS=5000
 
 
-# 多提供商类型支持(实验性功能)
-# - false (默认):仅支持 Claude、Codex类型供应商
-# - true:支持 Gemini CLI、OpenAI Compatible 等其他类型
-# 警告:其他类型功能仍在开发中,暂不建议启用
-ENABLE_MULTI_PROVIDER_TYPES=false
+# Provider Endpoint Probing (always enabled)
+# 功能说明:每 10 秒探测所有启用端点的速度与连通性,并刷新端点选择排序。
+# 注意:没有 ENABLE 开关,默认启用;可通过下列参数调优。
+ENDPOINT_PROBE_INTERVAL_MS=10000
+ENDPOINT_PROBE_TIMEOUT_MS=5000
+ENDPOINT_PROBE_CONCURRENCY=10
+ENDPOINT_PROBE_CYCLE_JITTER_MS=1000
+ENDPOINT_PROBE_LOCK_TTL_MS=30000
+
+# 探测日志保留与清理
+# - 所有探测结果(成功/失败)均记录到历史表
+# - 自动清理任务每 24 小时运行,删除过期记录
+ENDPOINT_PROBE_LOG_RETENTION_DAYS=1
+ENDPOINT_PROBE_LOG_CLEANUP_BATCH_SIZE=10000

+ 2 - 0
.gitignore

@@ -89,3 +89,5 @@ docs-site/node_modules/
 
 
 # local scratch
 # local scratch
 tmp/
 tmp/
+.trae/
+.sisyphus

+ 1 - 1
VERSION

@@ -1 +1 @@
-0.4.3
+0.5.0

+ 67 - 0
drizzle/0056_tidy_quasar.sql

@@ -0,0 +1,67 @@
+CREATE TABLE IF NOT EXISTS "provider_endpoint_probe_logs" (
+	"id" serial PRIMARY KEY NOT NULL,
+	"endpoint_id" integer NOT NULL,
+	"source" varchar(20) DEFAULT 'scheduled' NOT NULL,
+	"ok" boolean NOT NULL,
+	"status_code" integer,
+	"latency_ms" integer,
+	"error_type" varchar(64),
+	"error_message" text,
+	"created_at" timestamp with time zone DEFAULT now()
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "provider_endpoints" (
+	"id" serial PRIMARY KEY NOT NULL,
+	"vendor_id" integer NOT NULL,
+	"provider_type" varchar(20) DEFAULT 'claude' NOT NULL,
+	"url" text NOT NULL,
+	"label" varchar(200),
+	"sort_order" integer DEFAULT 0 NOT NULL,
+	"is_enabled" boolean DEFAULT true NOT NULL,
+	"last_probed_at" timestamp with time zone,
+	"last_probe_ok" boolean,
+	"last_probe_status_code" integer,
+	"last_probe_latency_ms" integer,
+	"last_probe_error_type" varchar(64),
+	"last_probe_error_message" text,
+	"created_at" timestamp with time zone DEFAULT now(),
+	"updated_at" timestamp with time zone DEFAULT now(),
+	"deleted_at" timestamp with time zone
+);
+--> statement-breakpoint
+CREATE TABLE IF NOT EXISTS "provider_vendors" (
+	"id" serial PRIMARY KEY NOT NULL,
+	"website_domain" varchar(255) NOT NULL,
+	"display_name" varchar(200),
+	"website_url" text,
+	"favicon_url" text,
+	"created_at" timestamp with time zone DEFAULT now(),
+	"updated_at" timestamp with time zone DEFAULT now()
+);
+--> statement-breakpoint
+ALTER TABLE "providers" ADD COLUMN IF NOT EXISTS "provider_vendor_id" integer;--> statement-breakpoint
+DO $$ BEGIN
+  ALTER TABLE "provider_endpoint_probe_logs" ADD CONSTRAINT "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk" FOREIGN KEY ("endpoint_id") REFERENCES "public"."provider_endpoints"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+  WHEN duplicate_object THEN NULL;
+END $$;--> statement-breakpoint
+DO $$ BEGIN
+  ALTER TABLE "provider_endpoints" ADD CONSTRAINT "provider_endpoints_vendor_id_provider_vendors_id_fk" FOREIGN KEY ("vendor_id") REFERENCES "public"."provider_vendors"("id") ON DELETE cascade ON UPDATE no action;
+EXCEPTION
+  WHEN duplicate_object THEN NULL;
+END $$;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_provider_endpoint_probe_logs_endpoint_created_at" ON "provider_endpoint_probe_logs" USING btree ("endpoint_id","created_at" DESC NULLS LAST);--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_provider_endpoint_probe_logs_created_at" ON "provider_endpoint_probe_logs" USING btree ("created_at");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "uniq_provider_endpoints_vendor_type_url" ON "provider_endpoints" USING btree ("vendor_id","provider_type","url");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_provider_endpoints_vendor_type" ON "provider_endpoints" USING btree ("vendor_id","provider_type") WHERE "provider_endpoints"."deleted_at" IS NULL;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_provider_endpoints_enabled" ON "provider_endpoints" USING btree ("is_enabled","vendor_id","provider_type") WHERE "provider_endpoints"."deleted_at" IS NULL;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_provider_endpoints_created_at" ON "provider_endpoints" USING btree ("created_at");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_provider_endpoints_deleted_at" ON "provider_endpoints" USING btree ("deleted_at");--> statement-breakpoint
+CREATE UNIQUE INDEX IF NOT EXISTS "uniq_provider_vendors_website_domain" ON "provider_vendors" USING btree ("website_domain");--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_provider_vendors_created_at" ON "provider_vendors" USING btree ("created_at");--> statement-breakpoint
+DO $$ BEGIN
+  ALTER TABLE "providers" ADD CONSTRAINT "providers_provider_vendor_id_provider_vendors_id_fk" FOREIGN KEY ("provider_vendor_id") REFERENCES "public"."provider_vendors"("id") ON DELETE restrict ON UPDATE no action;
+EXCEPTION
+  WHEN duplicate_object THEN NULL;
+END $$;--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "idx_providers_vendor_type" ON "providers" USING btree ("provider_vendor_id","provider_type") WHERE "providers"."deleted_at" IS NULL;

+ 2890 - 0
drizzle/meta/0056_snapshot.json

@@ -0,0 +1,2890 @@
+{
+  "id": "75eef188-0cac-4ae8-9deb-9b0db4f046c2",
+  "prevId": "b40c930a-4001-4403-90b9-652a5878893c",
+  "version": "7",
+  "dialect": "postgresql",
+  "tables": {
+    "public.error_rules": {
+      "name": "error_rules",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "pattern": {
+          "name": "pattern",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'regex'"
+        },
+        "category": {
+          "name": "category",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_response": {
+          "name": "override_response",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "override_status_code": {
+          "name": "override_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "is_default": {
+          "name": "is_default",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_error_rules_enabled": {
+          "name": "idx_error_rules_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "unique_pattern": {
+          "name": "unique_pattern",
+          "columns": [
+            {
+              "expression": "pattern",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_category": {
+          "name": "idx_category",
+          "columns": [
+            {
+              "expression": "category",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_match_type": {
+          "name": "idx_match_type",
+          "columns": [
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.keys": {
+      "name": "keys",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "can_login_web_ui": {
+          "name": "can_login_web_ui",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_keys_user_id": {
+          "name": "idx_keys_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_created_at": {
+          "name": "idx_keys_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_keys_deleted_at": {
+          "name": "idx_keys_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.message_request": {
+      "name": "message_request",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "provider_id": {
+          "name": "provider_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "user_id": {
+          "name": "user_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "model": {
+          "name": "model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "duration_ms": {
+          "name": "duration_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_usd": {
+          "name": "cost_usd",
+          "type": "numeric(21, 15)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0'"
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "session_id": {
+          "name": "session_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "request_sequence": {
+          "name": "request_sequence",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1
+        },
+        "provider_chain": {
+          "name": "provider_chain",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "api_type": {
+          "name": "api_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "endpoint": {
+          "name": "endpoint",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "original_model": {
+          "name": "original_model",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "input_tokens": {
+          "name": "input_tokens",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "output_tokens": {
+          "name": "output_tokens",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "ttfb_ms": {
+          "name": "ttfb_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_input_tokens": {
+          "name": "cache_creation_input_tokens",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_read_input_tokens": {
+          "name": "cache_read_input_tokens",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_5m_input_tokens": {
+          "name": "cache_creation_5m_input_tokens",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_creation_1h_input_tokens": {
+          "name": "cache_creation_1h_input_tokens",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_applied": {
+          "name": "cache_ttl_applied",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_applied": {
+          "name": "context_1m_applied",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "special_settings": {
+          "name": "special_settings",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_stack": {
+          "name": "error_stack",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_cause": {
+          "name": "error_cause",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_by": {
+          "name": "blocked_by",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "blocked_reason": {
+          "name": "blocked_reason",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "user_agent": {
+          "name": "user_agent",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "messages_count": {
+          "name": "messages_count",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_message_request_user_date_cost": {
+          "name": "idx_message_request_user_date_cost",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "cost_usd",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_query": {
+          "name": "idx_message_request_user_query",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id": {
+          "name": "idx_message_request_session_id",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_id_prefix": {
+          "name": "idx_message_request_session_id_prefix",
+          "columns": [
+            {
+              "expression": "\"session_id\" varchar_pattern_ops",
+              "asc": true,
+              "isExpression": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL AND (\"message_request\".\"blocked_by\" IS NULL OR \"message_request\".\"blocked_by\" <> 'warmup')",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_session_seq": {
+          "name": "idx_message_request_session_seq",
+          "columns": [
+            {
+              "expression": "session_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "request_sequence",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_endpoint": {
+          "name": "idx_message_request_endpoint",
+          "columns": [
+            {
+              "expression": "endpoint",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_blocked_by": {
+          "name": "idx_message_request_blocked_by",
+          "columns": [
+            {
+              "expression": "blocked_by",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"message_request\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_provider_id": {
+          "name": "idx_message_request_provider_id",
+          "columns": [
+            {
+              "expression": "provider_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_user_id": {
+          "name": "idx_message_request_user_id",
+          "columns": [
+            {
+              "expression": "user_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_key": {
+          "name": "idx_message_request_key",
+          "columns": [
+            {
+              "expression": "key",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_created_at": {
+          "name": "idx_message_request_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_message_request_deleted_at": {
+          "name": "idx_message_request_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.model_prices": {
+      "name": "model_prices",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "model_name": {
+          "name": "model_name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "price_data": {
+          "name": "price_data",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'litellm'"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_model_prices_latest": {
+          "name": "idx_model_prices_latest",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_model_name": {
+          "name": "idx_model_prices_model_name",
+          "columns": [
+            {
+              "expression": "model_name",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_created_at": {
+          "name": "idx_model_prices_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_model_prices_source": {
+          "name": "idx_model_prices_source",
+          "columns": [
+            {
+              "expression": "source",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_settings": {
+      "name": "notification_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "enabled": {
+          "name": "enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "use_legacy_mode": {
+          "name": "use_legacy_mode",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_enabled": {
+          "name": "circuit_breaker_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "circuit_breaker_webhook": {
+          "name": "circuit_breaker_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_enabled": {
+          "name": "daily_leaderboard_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "daily_leaderboard_webhook": {
+          "name": "daily_leaderboard_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_leaderboard_time": {
+          "name": "daily_leaderboard_time",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'09:00'"
+        },
+        "daily_leaderboard_top_n": {
+          "name": "daily_leaderboard_top_n",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "cost_alert_enabled": {
+          "name": "cost_alert_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "cost_alert_webhook": {
+          "name": "cost_alert_webhook",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cost_alert_threshold": {
+          "name": "cost_alert_threshold",
+          "type": "numeric(5, 2)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0.80'"
+        },
+        "cost_alert_check_interval": {
+          "name": "cost_alert_check_interval",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 60
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.notification_target_bindings": {
+      "name": "notification_target_bindings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "notification_type": {
+          "name": "notification_type",
+          "type": "notification_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "target_id": {
+          "name": "target_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "schedule_cron": {
+          "name": "schedule_cron",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "schedule_timezone": {
+          "name": "schedule_timezone",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'Asia/Shanghai'"
+        },
+        "template_override": {
+          "name": "template_override",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "unique_notification_target_binding": {
+          "name": "unique_notification_target_binding",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_type": {
+          "name": "idx_notification_bindings_type",
+          "columns": [
+            {
+              "expression": "notification_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_notification_bindings_target": {
+          "name": "idx_notification_bindings_target",
+          "columns": [
+            {
+              "expression": "target_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "notification_target_bindings_target_id_webhook_targets_id_fk": {
+          "name": "notification_target_bindings_target_id_webhook_targets_id_fk",
+          "tableFrom": "notification_target_bindings",
+          "tableTo": "webhook_targets",
+          "columnsFrom": [
+            "target_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoint_probe_logs": {
+      "name": "provider_endpoint_probe_logs",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "endpoint_id": {
+          "name": "endpoint_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "source": {
+          "name": "source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'scheduled'"
+        },
+        "ok": {
+          "name": "ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "status_code": {
+          "name": "status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "latency_ms": {
+          "name": "latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_type": {
+          "name": "error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "error_message": {
+          "name": "error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_provider_endpoint_probe_logs_endpoint_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_endpoint_created_at",
+          "columns": [
+            {
+              "expression": "endpoint_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": false,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoint_probe_logs_created_at": {
+          "name": "idx_provider_endpoint_probe_logs_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk": {
+          "name": "provider_endpoint_probe_logs_endpoint_id_provider_endpoints_id_fk",
+          "tableFrom": "provider_endpoint_probe_logs",
+          "tableTo": "provider_endpoints",
+          "columnsFrom": [
+            "endpoint_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_endpoints": {
+      "name": "provider_endpoints",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "vendor_id": {
+          "name": "vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "url": {
+          "name": "url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "label": {
+          "name": "label",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "sort_order": {
+          "name": "sort_order",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_probed_at": {
+          "name": "last_probed_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_ok": {
+          "name": "last_probe_ok",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_status_code": {
+          "name": "last_probe_status_code",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_latency_ms": {
+          "name": "last_probe_latency_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_type": {
+          "name": "last_probe_error_type",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_probe_error_message": {
+          "name": "last_probe_error_message",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "uniq_provider_endpoints_vendor_type_url": {
+          "name": "uniq_provider_endpoints_vendor_type_url",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "url",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_vendor_type": {
+          "name": "idx_provider_endpoints_vendor_type",
+          "columns": [
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_enabled": {
+          "name": "idx_provider_endpoints_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"provider_endpoints\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_created_at": {
+          "name": "idx_provider_endpoints_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_endpoints_deleted_at": {
+          "name": "idx_provider_endpoints_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "provider_endpoints_vendor_id_provider_vendors_id_fk": {
+          "name": "provider_endpoints_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "provider_endpoints",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "cascade",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.provider_vendors": {
+      "name": "provider_vendors",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "website_domain": {
+          "name": "website_domain",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "display_name": {
+          "name": "display_name",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "uniq_provider_vendors_website_domain": {
+          "name": "uniq_provider_vendors_website_domain",
+          "columns": [
+            {
+              "expression": "website_domain",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": true,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_provider_vendors_created_at": {
+          "name": "idx_provider_vendors_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.providers": {
+      "name": "providers",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "url": {
+          "name": "url",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "key": {
+          "name": "key",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_vendor_id": {
+          "name": "provider_vendor_id",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "weight": {
+          "name": "weight",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 1
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "cost_multiplier": {
+          "name": "cost_multiplier",
+          "type": "numeric(10, 4)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'1.0'"
+        },
+        "group_tag": {
+          "name": "group_tag",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'claude'"
+        },
+        "preserve_client_ip": {
+          "name": "preserve_client_ip",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "model_redirects": {
+          "name": "model_redirects",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'null'::jsonb"
+        },
+        "join_claude_pool": {
+          "name": "join_claude_pool",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "codex_instructions_strategy": {
+          "name": "codex_instructions_strategy",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'auto'"
+        },
+        "mcp_passthrough_type": {
+          "name": "mcp_passthrough_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'none'"
+        },
+        "mcp_passthrough_url": {
+          "name": "mcp_passthrough_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_daily_usd": {
+          "name": "limit_daily_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "total_cost_reset_at": {
+          "name": "total_cost_reset_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "max_retry_attempts": {
+          "name": "max_retry_attempts",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "circuit_breaker_failure_threshold": {
+          "name": "circuit_breaker_failure_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 5
+        },
+        "circuit_breaker_open_duration": {
+          "name": "circuit_breaker_open_duration",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 1800000
+        },
+        "circuit_breaker_half_open_success_threshold": {
+          "name": "circuit_breaker_half_open_success_threshold",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 2
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "first_byte_timeout_streaming_ms": {
+          "name": "first_byte_timeout_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "streaming_idle_timeout_ms": {
+          "name": "streaming_idle_timeout_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "request_timeout_non_streaming_ms": {
+          "name": "request_timeout_non_streaming_ms",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "website_url": {
+          "name": "website_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "favicon_url": {
+          "name": "favicon_url",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "cache_ttl_preference": {
+          "name": "cache_ttl_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "context_1m_preference": {
+          "name": "context_1m_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_effort_preference": {
+          "name": "codex_reasoning_effort_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_reasoning_summary_preference": {
+          "name": "codex_reasoning_summary_preference",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_text_verbosity_preference": {
+          "name": "codex_text_verbosity_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "codex_parallel_tool_calls_preference": {
+          "name": "codex_parallel_tool_calls_preference",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "tpm": {
+          "name": "tpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpm": {
+          "name": "rpm",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "rpd": {
+          "name": "rpd",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "cc": {
+          "name": "cc",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 0
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_providers_enabled_priority": {
+          "name": "idx_providers_enabled_priority",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "weight",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_group": {
+          "name": "idx_providers_group",
+          "columns": [
+            {
+              "expression": "group_tag",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_created_at": {
+          "name": "idx_providers_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_deleted_at": {
+          "name": "idx_providers_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_providers_vendor_type": {
+          "name": "idx_providers_vendor_type",
+          "columns": [
+            {
+              "expression": "provider_vendor_id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "provider_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"providers\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {
+        "providers_provider_vendor_id_provider_vendors_id_fk": {
+          "name": "providers_provider_vendor_id_provider_vendors_id_fk",
+          "tableFrom": "providers",
+          "tableTo": "provider_vendors",
+          "columnsFrom": [
+            "provider_vendor_id"
+          ],
+          "columnsTo": [
+            "id"
+          ],
+          "onDelete": "restrict",
+          "onUpdate": "no action"
+        }
+      },
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.request_filters": {
+      "name": "request_filters",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "scope": {
+          "name": "scope",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "action": {
+          "name": "action",
+          "type": "varchar(30)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "target": {
+          "name": "target",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "replacement": {
+          "name": "replacement",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "priority": {
+          "name": "priority",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": true,
+          "default": 0
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "binding_type": {
+          "name": "binding_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'global'"
+        },
+        "provider_ids": {
+          "name": "provider_ids",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "group_tags": {
+          "name": "group_tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_request_filters_enabled": {
+          "name": "idx_request_filters_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "priority",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_scope": {
+          "name": "idx_request_filters_scope",
+          "columns": [
+            {
+              "expression": "scope",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_action": {
+          "name": "idx_request_filters_action",
+          "columns": [
+            {
+              "expression": "action",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_request_filters_binding": {
+          "name": "idx_request_filters_binding",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "binding_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.sensitive_words": {
+      "name": "sensitive_words",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "word": {
+          "name": "word",
+          "type": "varchar(255)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "match_type": {
+          "name": "match_type",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'contains'"
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {
+        "idx_sensitive_words_enabled": {
+          "name": "idx_sensitive_words_enabled",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "match_type",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_sensitive_words_created_at": {
+          "name": "idx_sensitive_words_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.system_settings": {
+      "name": "system_settings",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "site_title": {
+          "name": "site_title",
+          "type": "varchar(128)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'Claude Code Hub'"
+        },
+        "allow_global_usage_view": {
+          "name": "allow_global_usage_view",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "currency_display": {
+          "name": "currency_display",
+          "type": "varchar(10)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'USD'"
+        },
+        "billing_model_source": {
+          "name": "billing_model_source",
+          "type": "varchar(20)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'original'"
+        },
+        "enable_auto_cleanup": {
+          "name": "enable_auto_cleanup",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "cleanup_retention_days": {
+          "name": "cleanup_retention_days",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 30
+        },
+        "cleanup_schedule": {
+          "name": "cleanup_schedule",
+          "type": "varchar(50)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'0 2 * * *'"
+        },
+        "cleanup_batch_size": {
+          "name": "cleanup_batch_size",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false,
+          "default": 10000
+        },
+        "enable_client_version_check": {
+          "name": "enable_client_version_check",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "verbose_provider_error": {
+          "name": "verbose_provider_error",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_http2": {
+          "name": "enable_http2",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "intercept_anthropic_warmup_requests": {
+          "name": "intercept_anthropic_warmup_requests",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": false
+        },
+        "enable_thinking_signature_rectifier": {
+          "name": "enable_thinking_signature_rectifier",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_codex_session_id_completion": {
+          "name": "enable_codex_session_id_completion",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "enable_response_fixer": {
+          "name": "enable_response_fixer",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "response_fixer_config": {
+          "name": "response_fixer_config",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'{\"fixTruncatedJson\":true,\"fixSseFormat\":true,\"fixEncoding\":true,\"maxJsonDepth\":200,\"maxFixSize\":1048576}'::jsonb"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.users": {
+      "name": "users",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "description": {
+          "name": "description",
+          "type": "text",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "role": {
+          "name": "role",
+          "type": "varchar",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'user'"
+        },
+        "rpm_limit": {
+          "name": "rpm_limit",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_limit_usd": {
+          "name": "daily_limit_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "provider_group": {
+          "name": "provider_group",
+          "type": "varchar(200)",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'default'"
+        },
+        "tags": {
+          "name": "tags",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "limit_5h_usd": {
+          "name": "limit_5h_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_weekly_usd": {
+          "name": "limit_weekly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_monthly_usd": {
+          "name": "limit_monthly_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_total_usd": {
+          "name": "limit_total_usd",
+          "type": "numeric(10, 2)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "limit_concurrent_sessions": {
+          "name": "limit_concurrent_sessions",
+          "type": "integer",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "daily_reset_mode": {
+          "name": "daily_reset_mode",
+          "type": "daily_reset_mode",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'fixed'"
+        },
+        "daily_reset_time": {
+          "name": "daily_reset_time",
+          "type": "varchar(5)",
+          "primaryKey": false,
+          "notNull": true,
+          "default": "'00:00'"
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "expires_at": {
+          "name": "expires_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "allowed_clients": {
+          "name": "allowed_clients",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "allowed_models": {
+          "name": "allowed_models",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "'[]'::jsonb"
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "deleted_at": {
+          "name": "deleted_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        }
+      },
+      "indexes": {
+        "idx_users_active_role_sort": {
+          "name": "idx_users_active_role_sort",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "role",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "id",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_enabled_expires_at": {
+          "name": "idx_users_enabled_expires_at",
+          "columns": [
+            {
+              "expression": "is_enabled",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            },
+            {
+              "expression": "expires_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "where": "\"users\".\"deleted_at\" IS NULL",
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_created_at": {
+          "name": "idx_users_created_at",
+          "columns": [
+            {
+              "expression": "created_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        },
+        "idx_users_deleted_at": {
+          "name": "idx_users_deleted_at",
+          "columns": [
+            {
+              "expression": "deleted_at",
+              "isExpression": false,
+              "asc": true,
+              "nulls": "last"
+            }
+          ],
+          "isUnique": false,
+          "concurrently": false,
+          "method": "btree",
+          "with": {}
+        }
+      },
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    },
+    "public.webhook_targets": {
+      "name": "webhook_targets",
+      "schema": "",
+      "columns": {
+        "id": {
+          "name": "id",
+          "type": "serial",
+          "primaryKey": true,
+          "notNull": true
+        },
+        "name": {
+          "name": "name",
+          "type": "varchar(100)",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "provider_type": {
+          "name": "provider_type",
+          "type": "webhook_provider_type",
+          "typeSchema": "public",
+          "primaryKey": false,
+          "notNull": true
+        },
+        "webhook_url": {
+          "name": "webhook_url",
+          "type": "varchar(1024)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_bot_token": {
+          "name": "telegram_bot_token",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "telegram_chat_id": {
+          "name": "telegram_chat_id",
+          "type": "varchar(64)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "dingtalk_secret": {
+          "name": "dingtalk_secret",
+          "type": "varchar(256)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_template": {
+          "name": "custom_template",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "custom_headers": {
+          "name": "custom_headers",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_url": {
+          "name": "proxy_url",
+          "type": "varchar(512)",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "proxy_fallback_to_direct": {
+          "name": "proxy_fallback_to_direct",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": false,
+          "default": false
+        },
+        "is_enabled": {
+          "name": "is_enabled",
+          "type": "boolean",
+          "primaryKey": false,
+          "notNull": true,
+          "default": true
+        },
+        "last_test_at": {
+          "name": "last_test_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "last_test_result": {
+          "name": "last_test_result",
+          "type": "jsonb",
+          "primaryKey": false,
+          "notNull": false
+        },
+        "created_at": {
+          "name": "created_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        },
+        "updated_at": {
+          "name": "updated_at",
+          "type": "timestamp with time zone",
+          "primaryKey": false,
+          "notNull": false,
+          "default": "now()"
+        }
+      },
+      "indexes": {},
+      "foreignKeys": {},
+      "compositePrimaryKeys": {},
+      "uniqueConstraints": {},
+      "policies": {},
+      "checkConstraints": {},
+      "isRLSEnabled": false
+    }
+  },
+  "enums": {
+    "public.daily_reset_mode": {
+      "name": "daily_reset_mode",
+      "schema": "public",
+      "values": [
+        "fixed",
+        "rolling"
+      ]
+    },
+    "public.notification_type": {
+      "name": "notification_type",
+      "schema": "public",
+      "values": [
+        "circuit_breaker",
+        "daily_leaderboard",
+        "cost_alert"
+      ]
+    },
+    "public.webhook_provider_type": {
+      "name": "webhook_provider_type",
+      "schema": "public",
+      "values": [
+        "wechat",
+        "feishu",
+        "dingtalk",
+        "telegram",
+        "custom"
+      ]
+    }
+  },
+  "schemas": {},
+  "sequences": {},
+  "roles": {},
+  "policies": {},
+  "views": {},
+  "_meta": {
+    "columns": {},
+    "schemas": {},
+    "tables": {}
+  }
+}

+ 7 - 0
drizzle/meta/_journal.json

@@ -393,6 +393,13 @@
       "when": 1768443427816,
       "when": 1768443427816,
       "tag": "0055_neat_stepford_cuckoos",
       "tag": "0055_neat_stepford_cuckoos",
       "breakpoints": true
       "breakpoints": true
+    },
+    {
+      "idx": 56,
+      "version": "7",
+      "when": 1769008812140,
+      "tag": "0056_tidy_quasar",
+      "breakpoints": true
     }
     }
   ]
   ]
 }
 }

+ 1 - 0
messages/en/common.json

@@ -4,6 +4,7 @@
   "delete": "Delete",
   "delete": "Delete",
   "confirm": "Confirm",
   "confirm": "Confirm",
   "edit": "Edit",
   "edit": "Edit",
+  "status": "Status",
   "create": "Create",
   "create": "Create",
   "close": "Close",
   "close": "Close",
   "back": "Back",
   "back": "Back",

+ 13 - 3
messages/en/customs.json

@@ -26,16 +26,26 @@
     "viewRelease": "View Release"
     "viewRelease": "View Release"
   },
   },
   "metrics": {
   "metrics": {
-    "concurrent": "Concurrent",
+    "concurrent": "Active Sessions",
     "todayRequests": "Today's Requests",
     "todayRequests": "Today's Requests",
     "todayCost": "Today's Cost",
     "todayCost": "Today's Cost",
     "avgResponse": "Average Response Time",
     "avgResponse": "Average Response Time",
-    "viewDetails": "View Details"
+    "viewDetails": "View Details",
+    "rpm": "RPM",
+    "vsYesterday": "vs Yesterday"
   },
   },
   "activeSessions": {
   "activeSessions": {
     "title": "Active Sessions",
     "title": "Active Sessions",
     "summary": "{count} sessions in the last {minutes} minutes",
     "summary": "{count} sessions in the last {minutes} minutes",
     "empty": "No active sessions",
     "empty": "No active sessions",
-    "viewAll": "View All"
+    "viewAll": "View All",
+    "loading": "Loading...",
+    "unknownUser": "unknown",
+    "status": {
+      "inProgressTooltip": "Session has active requests being processed",
+      "initializingTooltip": "Session is initializing with its first request",
+      "idleTooltip": "Session is idle with no active requests",
+      "errorTooltip": "Session encountered an error during processing"
+    }
   }
   }
 }
 }

+ 222 - 11
messages/en/dashboard.json

@@ -21,7 +21,8 @@
     "usersQuotas": "User Quota Statistics",
     "usersQuotas": "User Quota Statistics",
     "keysQuotas": "Key Quota Statistics",
     "keysQuotas": "Key Quota Statistics",
     "providersQuotas": "Provider Quota Statistics",
     "providersQuotas": "Provider Quota Statistics",
-    "filterCriteria": "Filter Criteria"
+    "filterCriteria": "Filter Criteria",
+    "filterCriteriaDescription": "Narrow down logs by time, user, provider, and more"
   },
   },
   "description": {
   "description": {
     "viewApiCallLogs": "View API call logs and usage statistics",
     "viewApiCallLogs": "View API call logs and usage statistics",
@@ -93,7 +94,28 @@
       "export": "Export",
       "export": "Export",
       "exporting": "Exporting...",
       "exporting": "Exporting...",
       "exportSuccess": "Export completed successfully",
       "exportSuccess": "Export completed successfully",
-      "exportError": "Export failed"
+      "exportError": "Export failed",
+      "quickFilters": {
+        "today": "Today",
+        "thisWeek": "This Week",
+        "errorsOnly": "Errors Only",
+        "showRetries": "With Retries"
+      },
+      "activeFilters": {
+        "title": "Active Filters",
+        "remove": "Remove filter",
+        "clearAll": "Clear all"
+      },
+      "groups": {
+        "time": "Time Range",
+        "timeDesc": "Filter by date and time",
+        "identity": "Identity",
+        "identityDesc": "Filter by user and key",
+        "request": "Request",
+        "requestDesc": "Filter by provider, model, endpoint",
+        "status": "Status",
+        "statusDesc": "Filter by status code and retry"
+      }
     },
     },
     "columns": {
     "columns": {
       "time": "Time",
       "time": "Time",
@@ -116,9 +138,7 @@
     },
     },
     "stats": {
     "stats": {
       "title": "Statistics Summary",
       "title": "Statistics Summary",
-      "description": "Click to view aggregated statistics for the current filters",
-      "expand": "Expand",
-      "collapse": "Collapse",
+      "description": "Aggregated statistics for the current filters",
       "totalRequests": "Total Requests",
       "totalRequests": "Total Requests",
       "totalAmount": "Total Consumption",
       "totalAmount": "Total Consumption",
       "totalTokens": "Total Tokens",
       "totalTokens": "Total Tokens",
@@ -144,7 +164,8 @@
       "noMoreData": "All records loaded",
       "noMoreData": "All records loaded",
       "scrollToTop": "Back to top",
       "scrollToTop": "Back to top",
       "hideProviderColumn": "Hide Provider Column",
       "hideProviderColumn": "Hide Provider Column",
-      "showProviderColumn": "Show Provider Column"
+      "showProviderColumn": "Show Provider Column",
+      "columnVisibility": "Column Visibility"
     },
     },
     "actions": {
     "actions": {
       "refresh": "Refresh",
       "refresh": "Refresh",
@@ -161,12 +182,27 @@
     },
     },
     "details": {
     "details": {
       "title": "Request Details",
       "title": "Request Details",
-      "statusTitle": "Request Details - Status Code {status}",
+      "statusTitle": "Status: {status}",
       "inProgress": "In Progress",
       "inProgress": "In Progress",
       "unknown": "Unknown",
       "unknown": "Unknown",
       "success": "Request completed successfully",
       "success": "Request completed successfully",
       "error": "Request failed, here are the detailed error messages and provider decision chain",
       "error": "Request failed, here are the detailed error messages and provider decision chain",
       "processing": "Request is in progress, not yet completed",
       "processing": "Request is in progress, not yet completed",
+      "tabs": {
+        "summary": "Summary",
+        "logicTrace": "Logic Trace",
+        "performance": "Performance",
+        "metadata": "Metadata"
+      },
+      "summary": {
+        "keyMetrics": "Key Metrics",
+        "totalCost": "Total Cost",
+        "totalTokens": "Total Tokens",
+        "duration": "Duration",
+        "outputRate": "Output Rate",
+        "viewFullError": "View full error",
+        "viewSession": "View Session"
+      },
       "specialSettings": {
       "specialSettings": {
         "title": "Special settings"
         "title": "Special settings"
       },
       },
@@ -224,13 +260,72 @@
         "circuitOpen": "Circuit Breaker Open"
         "circuitOpen": "Circuit Breaker Open"
       },
       },
       "billingDetails": {
       "billingDetails": {
-        "title": "Billing Details"
+        "title": "Billing Details",
+        "input": "Input",
+        "output": "Output",
+        "cacheWrite5m": "Cache Write (5m)",
+        "cacheWrite1h": "Cache Write (1h)",
+        "cacheRead": "Cache Read",
+        "cacheTtl": "Cache TTL",
+        "multiplier": "Provider Multiplier",
+        "totalCost": "Total Cost",
+        "context1m": "1M Context",
+        "context1mPricing": "Input 2x >200k, Output 1.5x >200k"
       },
       },
       "performance": {
       "performance": {
         "title": "Performance",
         "title": "Performance",
         "ttfb": "TTFB",
         "ttfb": "TTFB",
         "duration": "Total Duration",
         "duration": "Total Duration",
         "outputRate": "Output Rate"
         "outputRate": "Output Rate"
+      },
+      "performanceTab": {
+        "noPerformanceData": "No performance data available",
+        "ttfbGauge": "Time to First Byte",
+        "outputRateGauge": "Output Rate",
+        "latencyBreakdown": "Latency Breakdown",
+        "generationTime": "Generation Time",
+        "assessment": {
+          "excellent": "Excellent",
+          "good": "Good",
+          "warning": "Warning",
+          "poor": "Poor"
+        },
+        "thresholds": {
+          "ttfbGood": "TTFB < 1s",
+          "ttfbWarning": "TTFB 1-2s",
+          "ttfbPoor": "TTFB > 3s"
+        }
+      },
+      "metadata": {
+        "noMetadata": "No metadata available",
+        "sessionInfo": "Session Info",
+        "clientInfo": "Client Info",
+        "billingInfo": "Billing Info",
+        "technicalTimeline": "Technical Timeline",
+        "copyTimeline": "Copy Timeline"
+      },
+      "logicTrace": {
+        "title": "Decision Chain",
+        "noDecisionData": "No decision data available",
+        "providersCount": "{count} providers",
+        "healthyCount": "{count} healthy",
+        "initialSelection": "Initial Selection",
+        "healthCheck": "Health Check",
+        "prioritySelection": "Priority Selection",
+        "attemptProvider": "Attempt: {provider}",
+        "retryAttempt": "Retry #{number}",
+        "sessionReuse": "Session Reuse",
+        "sessionReuseDesc": "Reusing provider from session cache",
+        "sessionReuseTitle": "Session Binding",
+        "sessionReuseSelection": "Session Reuse Selection",
+        "sessionReuseSelectionDesc": "Provider selected from session cache",
+        "sessionInfo": "Session Information",
+        "sessionIdLabel": "Session ID",
+        "requestSequence": "Request Sequence",
+        "sessionAge": "Session Age",
+        "reusedProvider": "Reused Provider",
+        "executeRequest": "Execute Request",
+        "cacheOptimizationHint": "Session reuse optimizes performance by maintaining provider affinity within the same conversation, reducing selection overhead and improving cache hit rates."
       }
       }
     },
     },
     "providerChain": {
     "providerChain": {
@@ -934,6 +1029,17 @@
     "title": "Provider Availability Monitor",
     "title": "Provider Availability Monitor",
     "description": "Real-time monitoring of provider availability and performance metrics",
     "description": "Real-time monitoring of provider availability and performance metrics",
     "nav": "Availability Monitor",
     "nav": "Availability Monitor",
+    "tabs": {
+      "provider": "Provider Availability",
+      "endpoint": "Endpoint Health"
+    },
+    "overview": {
+      "systemAvailability": "System Availability",
+      "avgLatency": "Avg Latency",
+      "errorRate": "Error Rate",
+      "activeProbes": "Active Probes",
+      "load": "Load"
+    },
     "status": {
     "status": {
       "green": "Healthy",
       "green": "Healthy",
       "red": "Unhealthy",
       "red": "Unhealthy",
@@ -957,6 +1063,11 @@
     },
     },
     "timeRange": {
     "timeRange": {
       "label": "Time Range",
       "label": "Time Range",
+      "15min": "15 min",
+      "1h": "1 hour",
+      "6h": "6 hours",
+      "24h": "24 hours",
+      "7d": "7 days",
       "last15min": "Last 15 minutes",
       "last15min": "Last 15 minutes",
       "last1h": "Last 1 hour",
       "last1h": "Last 1 hour",
       "last6h": "Last 6 hours",
       "last6h": "Last 6 hours",
@@ -1007,7 +1118,13 @@
       "autoRefresh": "Auto Refresh",
       "autoRefresh": "Auto Refresh",
       "stopAutoRefresh": "Stop Auto Refresh",
       "stopAutoRefresh": "Stop Auto Refresh",
       "viewDetails": "View Details",
       "viewDetails": "View Details",
-      "testProvider": "Test Provider"
+      "testProvider": "Test Provider",
+      "retry": "Retry",
+      "probeNow": "Probe Now",
+      "probing": "Probing...",
+      "probeAll": "Probe All",
+      "probeSuccess": "Probe successful",
+      "probeFailed": "Probe failed"
     },
     },
     "states": {
     "states": {
       "loading": "Loading...",
       "loading": "Loading...",
@@ -1037,6 +1154,84 @@
       "noData": "No Data",
       "noData": "No Data",
       "noRequests": "No Requests"
       "noRequests": "No Requests"
     },
     },
+    "probeHistory": {
+      "title": "Endpoint Probe History",
+      "description": "View probe logs and manually trigger probes for specific endpoints",
+      "selectVendor": "Select Vendor",
+      "selectType": "Select Provider Type",
+      "selectEndpoint": "Select Endpoint",
+      "noEndpoints": "No endpoints found",
+      "probeNow": "Probe Now",
+      "probing": "Probing...",
+      "columns": {
+        "time": "Time",
+        "method": "Method",
+        "status": "Status",
+        "latency": "Latency",
+        "error": "Error"
+      },
+      "success": "Success",
+      "manual": "Manual Probe",
+      "auto": "Auto Probe",
+      "probeSuccess": "Probe successful",
+      "probeFailed": "Probe failed"
+    },
+    "laneChart": {
+      "title": "Provider Availability Timeline",
+      "noData": "No data available",
+      "requests": "{count} requests",
+      "availability": "{value}% available",
+      "noRequests": "No requests",
+      "denseData": "Dense",
+      "sparseData": "Sparse",
+      "latency": "Latency"
+    },
+    "latencyChart": {
+      "title": "Latency Distribution",
+      "p50": "P50",
+      "p95": "P95",
+      "p99": "P99",
+      "noData": "No latency data available"
+    },
+    "latencyCurve": {
+      "title": "Latency Trend",
+      "noData": "No latency data available",
+      "avg": "Avg",
+      "min": "Min",
+      "max": "Max",
+      "latency": "Latency"
+    },
+    "terminal": {
+      "title": "Probe Logs",
+      "live": "LIVE",
+      "download": "Download logs",
+      "noLogs": "No probe logs available",
+      "manual": "MANUAL",
+      "auto": "AUTO",
+      "filterPlaceholder": "Filter logs..."
+    },
+    "probeGrid": {
+      "title": "Endpoint Status",
+      "noEndpoints": "No endpoints configured",
+      "lastProbe": "Last probe",
+      "status": {
+        "unknown": "Unknown",
+        "healthy": "Healthy",
+        "unhealthy": "Unhealthy"
+      }
+    },
+    "endpoint": {
+      "selectVendor": "Select vendor",
+      "selectType": "Select type"
+    },
+    "confidence": {
+      "low": "Low",
+      "medium": "Medium",
+      "high": "High",
+      "lowTooltip": "Less than {count} requests. Data may not be representative.",
+      "mediumTooltip": "Moderate request volume. Data is reasonably reliable.",
+      "highTooltip": "High request volume. Data is reliable."
+    },
     "toast": {
     "toast": {
       "refreshSuccess": "Availability data refreshed",
       "refreshSuccess": "Availability data refreshed",
       "refreshFailed": "Refresh failed, please retry"
       "refreshFailed": "Refresh failed, please retry"
@@ -1203,8 +1398,23 @@
       "columns": {
       "columns": {
         "model": "Model",
         "model": "Model",
         "calls": "Calls",
         "calls": "Calls",
+        "tokens": "Tokens",
         "cost": "Cost"
         "cost": "Cost"
       },
       },
+      "modal": {
+        "requests": "Requests",
+        "totalTokens": "Total Tokens",
+        "cost": "Cost",
+        "inputTokens": "Input Tokens",
+        "outputTokens": "Output Tokens",
+        "cacheWrite": "Cache Write",
+        "cacheRead": "Cache Read",
+        "cacheHitRate": "Cache Hit Rate",
+        "cacheTokens": "Cache Tokens",
+        "performanceHigh": "High",
+        "performanceMedium": "Medium",
+        "performanceLow": "Low"
+      },
       "noData": "No usage records today",
       "noData": "No usage records today",
       "totalCalls": "Total Calls",
       "totalCalls": "Total Calls",
       "totalCost": "Total Cost"
       "totalCost": "Total Cost"
@@ -1350,7 +1560,7 @@
           "limitDaily": "Daily Limit (USD)",
           "limitDaily": "Daily Limit (USD)",
           "limitWeekly": "Weekly Limit (USD)",
           "limitWeekly": "Weekly Limit (USD)",
           "limitMonthly": "Monthly Limit (USD)",
           "limitMonthly": "Monthly Limit (USD)",
-          "canLoginWebUi": "Allow Web UI Login",
+          "canLoginWebUi": "Independent Personal Usage Page",
           "keyEnabled": "Key Enabled Status"
           "keyEnabled": "Key Enabled Status"
         },
         },
         "placeholders": {
         "placeholders": {
@@ -1555,7 +1765,8 @@
       "clickToEnableUser": "Click to enable user",
       "clickToEnableUser": "Click to enable user",
       "operationFailed": "Operation failed",
       "operationFailed": "Operation failed",
       "deleteFailed": "Delete failed",
       "deleteFailed": "Delete failed",
-      "deleteSuccess": "Delete successful"
+      "deleteSuccess": "Delete successful",
+      "daysLeft": "{days, plural, =0 {Expires today} =1 {1 day left} other {# days left}}"
     },
     },
     "userEditSection": {
     "userEditSection": {
       "sections": {
       "sections": {

+ 6 - 0
messages/en/errors.json

@@ -74,6 +74,12 @@
   "UPDATE_KEY_FAILED": "Failed to update key, please try again later",
   "UPDATE_KEY_FAILED": "Failed to update key, please try again later",
   "DELETE_KEY_FAILED": "Failed to delete key, please try again later",
   "DELETE_KEY_FAILED": "Failed to delete key, please try again later",
   "CANNOT_DISABLE_LAST_KEY": "Cannot disable the last active key. Users must have at least one enabled key",
   "CANNOT_DISABLE_LAST_KEY": "Cannot disable the last active key. Users must have at least one enabled key",
+  "KEY_LIMIT_5H_EXCEEDS_USER_LIMIT": "Key 5-hour limit ({keyLimit}) cannot exceed user limit ({userLimit})",
+  "KEY_LIMIT_DAILY_EXCEEDS_USER_LIMIT": "Key daily limit ({keyLimit}) cannot exceed user limit ({userLimit})",
+  "KEY_LIMIT_WEEKLY_EXCEEDS_USER_LIMIT": "Key weekly limit ({keyLimit}) cannot exceed user limit ({userLimit})",
+  "KEY_LIMIT_MONTHLY_EXCEEDS_USER_LIMIT": "Key monthly limit ({keyLimit}) cannot exceed user limit ({userLimit})",
+  "KEY_LIMIT_TOTAL_EXCEEDS_USER_LIMIT": "Key total limit ({keyLimit}) cannot exceed user limit ({userLimit})",
+  "KEY_LIMIT_CONCURRENT_EXCEEDS_USER_LIMIT": "Key concurrent session limit ({keyLimit}) cannot exceed user limit ({userLimit})",
   "NO_DEFAULT_GROUP_PERMISSION": "No permission to use default group. You don't have a Key with default group",
   "NO_DEFAULT_GROUP_PERMISSION": "No permission to use default group. You don't have a Key with default group",
   "NO_GROUP_PERMISSION": "No permission to use the following groups: {groups}"
   "NO_GROUP_PERMISSION": "No permission to use the following groups: {groups}"
 }
 }

+ 2 - 2
messages/en/myUsage.json

@@ -78,7 +78,7 @@
     "inheritedFromUser": "Inherited from User"
     "inheritedFromUser": "Inherited from User"
   },
   },
   "stats": {
   "stats": {
-    "title": "Statistics Summary",
+    "title": "Key Statistics",
     "autoRefresh": "Auto refresh every {seconds}s",
     "autoRefresh": "Auto refresh every {seconds}s",
     "totalRequests": "Total Requests",
     "totalRequests": "Total Requests",
     "totalCost": "Total Cost",
     "totalCost": "Total Cost",
@@ -116,7 +116,7 @@
     "noRestrictions": "No restrictions"
     "noRestrictions": "No restrictions"
   },
   },
   "quotaCollapsible": {
   "quotaCollapsible": {
-    "title": "Quota Usage",
+    "title": "User Quota Usage",
     "daily": "Daily",
     "daily": "Daily",
     "monthly": "Monthly",
     "monthly": "Monthly",
     "total": "Total"
     "total": "Total"

+ 43 - 0
messages/en/provider-chain.json

@@ -39,6 +39,48 @@
     "http2Fallback": "HTTP/2 Fallback",
     "http2Fallback": "HTTP/2 Fallback",
     "clientError": "Client Error"
     "clientError": "Client Error"
   },
   },
+  "reasons": {
+    "request_success": "Success",
+    "retry_success": "Retry Success",
+    "retry_failed": "Retry Failed",
+    "system_error": "System Error",
+    "client_error_non_retryable": "Client Error",
+    "concurrent_limit_failed": "Concurrent Limit",
+    "http2_fallback": "HTTP/2 Fallback",
+    "session_reuse": "Session Reuse",
+    "initial_selection": "Initial Selection"
+  },
+  "filterReasons": {
+    "rate_limited": "Rate Limited",
+    "circuit_open": "Circuit Open",
+    "disabled": "Disabled",
+    "model_not_supported": "Model Not Supported",
+    "group_mismatch": "Group Mismatch",
+    "health_check_failed": "Health Check Failed"
+  },
+  "details": {
+    "selectionMethod": "Selection",
+    "attemptNumber": "Attempt",
+    "endpoint": "Endpoint",
+    "config": "Configuration",
+    "priority": "Priority",
+    "weight": "Weight",
+    "costMultiplier": "Cost",
+    "groupTag": "Group",
+    "circuitBreaker": "Circuit Breaker",
+    "circuitDisabled": "Disabled",
+    "failures": "failures",
+    "modelRedirect": "Model Redirect",
+    "error": "Error",
+    "errorDetails": "Error Details",
+    "decisionContext": "Decision Context",
+    "beforeHealthCheck": "Before Health Check",
+    "afterHealthCheck": "After Health Check",
+    "filteredProviders": "Filtered Providers",
+    "priorityLevels": "Priority Levels",
+    "candidates": "Candidates"
+  },
+  "technicalTimeline": "Technical Timeline",
   "timeline": {
   "timeline": {
     "sessionReuse": "Session Reuse",
     "sessionReuse": "Session Reuse",
     "sessionReuseSelection": "Session Reuse - Provider Selection",
     "sessionReuseSelection": "Session Reuse - Provider Selection",
@@ -87,6 +129,7 @@
     "status": "Status",
     "status": "Status",
     "alreadyBroken": "Circuit already broken",
     "alreadyBroken": "Circuit already broken",
     "circuitTriggered": "Warning: Circuit breaker triggered",
     "circuitTriggered": "Warning: Circuit breaker triggered",
+    "circuitDisabled": "Circuit Breaker Disabled",
     "errorDetails": "Error Details",
     "errorDetails": "Error Details",
     "systemError": "Network/System Error",
     "systemError": "Network/System Error",
     "systemErrorFailed": "Network/System Error (Attempt {attempt})",
     "systemErrorFailed": "Network/System Error (Attempt {attempt})",

+ 7 - 1
messages/en/settings/clientVersions.json

@@ -38,7 +38,13 @@
     "unknown": "Unknown",
     "unknown": "Unknown",
     "user": "User",
     "user": "User",
     "usersCount": "{count} users",
     "usersCount": "{count} users",
-    "version": "Current Version"
+    "version": "Current Version",
+    "stats": {
+      "clientTypes": "Client Types",
+      "totalUsers": "Total Users",
+      "withGA": "With GA Version",
+      "coverage": "GA Coverage"
+    }
   },
   },
   "title": "Client Update Reminder",
   "title": "Client Update Reminder",
   "toggle": {
   "toggle": {

+ 1 - 0
messages/en/settings/data.json

@@ -123,6 +123,7 @@
   },
   },
   "status": {
   "status": {
     "connected": "Database connected",
     "connected": "Database connected",
+    "connectionUnavailable": "Database connection unavailable, please check database service status",
     "error": "Failed to get database status",
     "error": "Failed to get database status",
     "loading": "Loading...",
     "loading": "Loading...",
     "retry": "Retry",
     "retry": "Retry",

+ 5 - 0
messages/en/settings/index.ts

@@ -13,6 +13,7 @@ import sensitiveWords from "./sensitiveWords.json";
 import strings from "./strings.json";
 import strings from "./strings.json";
 
 
 import providersAutoSort from "./providers/autoSort.json";
 import providersAutoSort from "./providers/autoSort.json";
+import providersBatchEdit from "./providers/batchEdit.json";
 import providersFilter from "./providers/filter.json";
 import providersFilter from "./providers/filter.json";
 import providersGuide from "./providers/guide.json";
 import providersGuide from "./providers/guide.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
@@ -37,6 +38,7 @@ import providersFormModelSelect from "./providers/form/modelSelect.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
+import providersFormQuickPaste from "./providers/form/quickPaste.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormSuccess from "./providers/form/success.json";
 import providersFormSuccess from "./providers/form/success.json";
@@ -47,6 +49,7 @@ import providersFormWebsiteUrl from "./providers/form/websiteUrl.json";
 
 
 const providersForm = {
 const providersForm = {
   ...providersFormStrings,
   ...providersFormStrings,
+  ...providersFormCommon,
   apiTest: providersFormApiTest,
   apiTest: providersFormApiTest,
   buttons: providersFormButtons,
   buttons: providersFormButtons,
   common: providersFormCommon,
   common: providersFormCommon,
@@ -60,6 +63,7 @@ const providersForm = {
   name: providersFormName,
   name: providersFormName,
   providerTypes: providersFormProviderTypes,
   providerTypes: providersFormProviderTypes,
   proxyTest: providersFormProxyTest,
   proxyTest: providersFormProxyTest,
+  quickPaste: providersFormQuickPaste,
   sections: providersFormSections,
   sections: providersFormSections,
   success: providersFormSuccess,
   success: providersFormSuccess,
   title: providersFormTitle,
   title: providersFormTitle,
@@ -71,6 +75,7 @@ const providersForm = {
 const providers = {
 const providers = {
   ...providersStrings,
   ...providersStrings,
   autoSort: providersAutoSort,
   autoSort: providersAutoSort,
+  batchEdit: providersBatchEdit,
   filter: providersFilter,
   filter: providersFilter,
   form: providersForm,
   form: providersForm,
   guide: providersGuide,
   guide: providersGuide,

+ 2 - 0
messages/en/settings/notifications.json

@@ -69,6 +69,8 @@
   "global": {
   "global": {
     "description": "Enable or disable all push notification features",
     "description": "Enable or disable all push notification features",
     "enable": "Enable Push Notifications",
     "enable": "Enable Push Notifications",
+    "off": "Off",
+    "on": "On",
     "legacyModeDescription": "You are using legacy single-URL notifications. Create a push target to switch to multi-target mode.",
     "legacyModeDescription": "You are using legacy single-URL notifications. Create a push target to switch to multi-target mode.",
     "legacyModeTitle": "Legacy Mode",
     "legacyModeTitle": "Legacy Mode",
     "title": "Notification Master Switch"
     "title": "Notification Master Switch"

+ 43 - 0
messages/en/settings/providers/batchEdit.json

@@ -0,0 +1,43 @@
+{
+  "enterMode": "Batch Edit",
+  "exitMode": "Exit",
+  "selectAll": "Select All",
+  "invertSelection": "Invert",
+  "selectedCount": "{count} selected",
+  "editSelected": "Edit Selected",
+  "actions": {
+    "edit": "Edit",
+    "delete": "Delete",
+    "resetCircuit": "Reset Circuit"
+  },
+  "dialog": {
+    "editTitle": "Batch Edit Providers",
+    "editDesc": "Changes will apply to {count} providers",
+    "deleteTitle": "Delete Providers",
+    "deleteDesc": "Permanently delete {count} providers?",
+    "resetCircuitTitle": "Reset Circuit Breakers",
+    "resetCircuitDesc": "Reset circuit breaker for {count} providers?",
+    "next": "Next",
+    "noFieldEnabled": "Please enable at least one field to update"
+  },
+  "fields": {
+    "isEnabled": "Status",
+    "priority": "Priority",
+    "weight": "Weight",
+    "costMultiplier": "Cost Multiplier",
+    "groupTag": "Group Tag"
+  },
+  "confirm": {
+    "title": "Confirm Operation",
+    "cancel": "Cancel",
+    "confirm": "Confirm",
+    "goBack": "Go Back",
+    "processing": "Processing..."
+  },
+  "toast": {
+    "updated": "Updated {count} providers",
+    "deleted": "Deleted {count} providers",
+    "circuitReset": "Reset {count} circuit breakers",
+    "failed": "Operation failed: {error}"
+  }
+}

+ 8 - 1
messages/en/settings/providers/form/common.json

@@ -1,3 +1,10 @@
 {
 {
-  "core": "Core"
+  "core": "Core",
+  "tabs": {
+    "basic": "Basic",
+    "routing": "Routing",
+    "limits": "Limits",
+    "network": "Network",
+    "testing": "Testing"
+  }
 }
 }

+ 1 - 0
messages/en/settings/providers/form/key.json

@@ -1,6 +1,7 @@
 {
 {
   "currentKey": "Current key: {key}",
   "currentKey": "Current key: {key}",
   "label": "API Key",
   "label": "API Key",
+  "labelEdit": "API Key (Leave empty to keep unchanged)",
   "leaveEmpty": "(Leave empty to keep unchanged)",
   "leaveEmpty": "(Leave empty to keep unchanged)",
   "leaveEmptyDesc": "Leave empty to keep existing key",
   "leaveEmptyDesc": "Leave empty to keep existing key",
   "placeholder": "Enter API Key"
   "placeholder": "Enter API Key"

+ 1 - 1
messages/en/settings/providers/form/name.json

@@ -1,4 +1,4 @@
 {
 {
-  "label": "Provider Name *",
+  "label": "Provider Name",
   "placeholder": "e.g. Zhipu"
   "placeholder": "e.g. Zhipu"
 }
 }

+ 15 - 0
messages/en/settings/providers/form/quickPaste.json

@@ -0,0 +1,15 @@
+{
+  "button": "Quick Paste",
+  "title": "Quick Paste Provider Info",
+  "description": "Paste text containing provider details (URL, API key, etc.) and we'll extract the information automatically.",
+  "placeholder": "Paste provider configuration text here...",
+  "preview": "Detected Information",
+  "type": "Type",
+  "name": "Name",
+  "url": "URL",
+  "key": "API Key",
+  "notFound": "Not detected",
+  "parseError": "Could not parse provider information from the text",
+  "cancel": "Cancel",
+  "confirm": "Apply"
+}

+ 29 - 8
messages/en/settings/providers/form/sections.json

@@ -1,4 +1,18 @@
 {
 {
+  "basic": {
+    "identity": {
+      "title": "Provider Identity",
+      "desc": "Set a unique name to identify this provider"
+    },
+    "endpoint": {
+      "title": "API Endpoint",
+      "desc": "Configure the base URL for API requests"
+    },
+    "auth": {
+      "title": "Authentication",
+      "desc": "Provide your API key for authentication"
+    }
+  },
   "apiTest": {
   "apiTest": {
     "desc": "Validate whether the selected provider type and model respond correctly. Defaults to the routing configuration unless overridden.",
     "desc": "Validate whether the selected provider type and model respond correctly. Defaults to the routing configuration unless overridden.",
     "summary": "Verify provider & model connectivity",
     "summary": "Verify provider & model connectivity",
@@ -10,7 +24,8 @@
     "failureThreshold": {
     "failureThreshold": {
       "desc": "Number of consecutive failures to trigger break",
       "desc": "Number of consecutive failures to trigger break",
       "label": "Failure Threshold",
       "label": "Failure Threshold",
-      "placeholder": "5"
+      "placeholder": "5",
+      "warning": "Setting to 0 disables the circuit breaker - use with caution"
     },
     },
     "maxRetryAttempts": {
     "maxRetryAttempts": {
       "desc": "Total tries (including the first call) before switching providers. Leave empty to use the system default.",
       "desc": "Total tries (including the first call) before switching providers. Leave empty to use the system default.",
@@ -129,6 +144,7 @@
     "dailyResetTime": {
     "dailyResetTime": {
       "label": "Daily Reset Time (HH:mm)"
       "label": "Daily Reset Time (HH:mm)"
     },
     },
+    "desc": "Configure spending limits to control costs across different time windows",
     "limit5h": {
     "limit5h": {
       "label": "5h Spend Limit (USD)",
       "label": "5h Spend Limit (USD)",
       "placeholder": "Leave empty for unlimited"
       "placeholder": "Leave empty for unlimited"
@@ -164,6 +180,11 @@
     },
     },
     "title": "Rate Limit"
     "title": "Rate Limit"
   },
   },
+  "limits": {
+    "timeBased": "Time-based Limits",
+    "dailyReset": "Daily Reset Settings",
+    "otherLimits": "Other Limits"
+  },
   "routing": {
   "routing": {
     "cacheTtl": {
     "cacheTtl": {
       "desc": "Force prompt cache TTL; only affects requests with cache_control.",
       "desc": "Force prompt cache TTL; only affects requests with cache_control.",
@@ -263,7 +284,7 @@
         "placeholder": "1.0"
         "placeholder": "1.0"
       },
       },
       "group": {
       "group": {
-        "desc": "Group tag. Only users whose providerGroup matches can use this provider. Example: set to \"premium\" to serve users with providerGroup=\"premium\" only",
+        "desc": "Group tag. Select from list or type a new name and press Enter to create (max 50 chars). Only users whose providerGroup matches can use this provider.",
         "label": "Provider Group",
         "label": "Provider Group",
         "placeholder": "e.g. premium, economy"
         "placeholder": "e.g. premium, economy"
       },
       },
@@ -291,21 +312,21 @@
     "disableHint": "Set to 0 to disable the timeout (for canary rollback scenarios only, not recommended)",
     "disableHint": "Set to 0 to disable the timeout (for canary rollback scenarios only, not recommended)",
     "nonStreamingTotal": {
     "nonStreamingTotal": {
       "core": "true",
       "core": "true",
-      "desc": "Non-streaming request total timeout, range 60-1200 seconds, default 600 seconds (10 minutes)",
+      "desc": "Non-streaming request total timeout, range 60-1200 seconds, enter 0 to disable (default: no limit)",
       "label": "Non-streaming Total Timeout (seconds)",
       "label": "Non-streaming Total Timeout (seconds)",
-      "placeholder": "600"
+      "placeholder": "0"
     },
     },
     "streamingFirstByte": {
     "streamingFirstByte": {
       "core": "true",
       "core": "true",
-      "desc": "Streaming request first byte timeout, range 1-120 seconds, default 30 seconds",
+      "desc": "Streaming request first byte timeout, range 1-180 seconds, enter 0 to disable (default: no limit)",
       "label": "Streaming First Byte Timeout (seconds)",
       "label": "Streaming First Byte Timeout (seconds)",
-      "placeholder": "30"
+      "placeholder": "0"
     },
     },
     "streamingIdle": {
     "streamingIdle": {
       "core": "true",
       "core": "true",
-      "desc": "Streaming request idle timeout, range 60-600 seconds, enter 0 to disable (prevent mid-stream stalling)",
+      "desc": "Streaming request idle timeout, range 60-600 seconds, enter 0 to disable (default: no limit)",
       "label": "Streaming Idle Timeout (seconds)",
       "label": "Streaming Idle Timeout (seconds)",
-      "placeholder": "60"
+      "placeholder": "0"
     },
     },
     "summary": "First byte: {streaming}s | Stream interval: {idle}s | Non-streaming: {nonStreaming}s",
     "summary": "First byte: {streaming}s | Stream interval: {idle}s | Non-streaming: {nonStreaming}s",
     "title": "Timeout Configuration"
     "title": "Timeout Configuration"

+ 3 - 1
messages/en/settings/providers/form/success.json

@@ -1,4 +1,6 @@
 {
 {
   "created": "Provider added successfully",
   "created": "Provider added successfully",
-  "createdDesc": "Provider \"{name}\" has been added"
+  "createdDesc": "Provider \"{name}\" has been added",
+  "updated": "Provider updated successfully",
+  "updatedDesc": "Provider \"{name}\" has been updated"
 }
 }

+ 1 - 1
messages/en/settings/providers/form/url.json

@@ -1,4 +1,4 @@
 {
 {
-  "label": "API Address *",
+  "label": "API Address",
   "placeholder": "e.g. https://open.bigmodel.cn/api/anthropic"
   "placeholder": "e.g. https://open.bigmodel.cn/api/anthropic"
 }
 }

+ 12 - 1
messages/en/settings/providers/form/urlPreview.json

@@ -5,5 +5,16 @@
   "duplicatePath": "Duplicate path detected",
   "duplicatePath": "Duplicate path detected",
   "invalidUrl": "Invalid URL format",
   "invalidUrl": "Invalid URL format",
   "invalidUrlDesc": "Please enter a valid HTTP/HTTPS address",
   "invalidUrlDesc": "Please enter a valid HTTP/HTTPS address",
-  "title": "URL Concatenation Preview"
+  "title": "URL Concatenation Preview",
+  "endpoints": {
+    "claudeMessages": "Claude Messages",
+    "claudeCountTokens": "Claude Count Tokens",
+    "codexResponses": "Codex Responses",
+    "openaiChatCompletions": "OpenAI Chat Completions",
+    "openaiModels": "OpenAI Models",
+    "geminiGenerateContent": "Gemini Generate Content",
+    "geminiStreamContent": "Gemini Stream Content",
+    "geminiCliGenerate": "Gemini CLI Generate",
+    "geminiCliStream": "Gemini CLI Stream"
+  }
 }
 }

+ 57 - 1
messages/en/settings/providers/strings.json

@@ -43,5 +43,61 @@
   "toggleSuccessDesc": "Provider \"{name}\" status updated",
   "toggleSuccessDesc": "Provider \"{name}\" status updated",
   "updateFailed": "Failed to update provider",
   "updateFailed": "Failed to update provider",
   "viewKey": "View Complete API Key",
   "viewKey": "View Complete API Key",
-  "viewKeyDesc": "Please keep it safe and don't share it with others"
+  "viewKeyDesc": "Please keep it safe and don't share it with others",
+  "viewMode": "View Mode",
+  "viewModeList": "List",
+  "viewModeVendor": "Vendor",
+  "endpoints": "Endpoints",
+  "manualProbe": "Probe",
+  "addEndpoint": "Add Endpoint",
+  "lastProbed": "Last Probed",
+  "latency": "Latency",
+  "status": "Status",
+  "vendorKeys": "API Keys",
+  "addVendorKey": "Add API Key",
+  "addVendorKeyDesc": "Add an API key for this vendor (no API URL required).",
+  "addVendorKeySuccess": "API key added",
+  "addVendorKeyFailed": "Failed to add API key",
+  "probeSuccess": "Probe Successful",
+  "probeFailed": "Probe Failed",
+  "manualCircuitOpen": "Manually Open Circuit",
+  "manualCircuitClose": "Close Circuit",
+  "circuitStatus": "Circuit Status",
+  "vendorTypeCircuit": "Vendor Type Circuit",
+  "vendorFallbackName": "Vendor #{id}",
+  "orphanedProviders": "Unknown Vendor",
+  "vendorTypeCircuitUpdated": "Vendor type circuit updated",
+  "noEndpoints": "No endpoints configured",
+  "noEndpointsDesc": "Add an endpoint to enable failover routing",
+  "columnUrl": "URL",
+  "columnActions": "Actions",
+  "confirmDeleteEndpoint": "Are you sure you want to delete this endpoint?",
+  "endpointAddSuccess": "Endpoint added successfully",
+  "endpointAddFailed": "Failed to add endpoint",
+  "endpointUpdateSuccess": "Endpoint updated successfully",
+  "endpointUpdateFailed": "Failed to update endpoint",
+  "endpointDeleteSuccess": "Endpoint deleted successfully",
+  "endpointDeleteFailed": "Failed to delete endpoint",
+  "probeOk": "OK",
+  "probeError": "Error",
+  "addEndpointDesc": "Add a new {providerType} endpoint for this vendor.",
+  "endpointUrlLabel": "URL",
+  "endpointUrlPlaceholder": "https://api.example.com/v1",
+  "endpointLabelOptional": "Label (optional)",
+  "endpointLabelPlaceholder": "Production endpoint",
+  "editEndpoint": "Edit Endpoint",
+  "editVendor": "Edit Vendor",
+  "vendorName": "Vendor Name",
+  "vendorWebsite": "Website URL",
+  "vendorWebsitePlaceholder": "https://example.com",
+  "vendorOfficial": "Official",
+  "deleteVendor": "Delete Vendor",
+  "deleteVendorConfirmTitle": "Delete Vendor?",
+  "deleteVendorDoubleConfirmTitle": "Confirm deletion?",
+  "deleteVendorConfirmDesc": "This will permanently delete the vendor \"{name}\" and all its associated API keys and endpoints.",
+  "deleteVendorDoubleConfirmDesc": "This action is irreversible. Please confirm you want to wipe out everything related to \"{name}\".",
+  "vendorUpdateSuccess": "Vendor updated successfully",
+  "vendorUpdateFailed": "Failed to update vendor",
+  "vendorDeleteSuccess": "Vendor deleted successfully",
+  "vendorDeleteFailed": "Failed to delete vendor"
 }
 }

+ 1 - 0
messages/ja/common.json

@@ -4,6 +4,7 @@
   "delete": "削除",
   "delete": "削除",
   "confirm": "確認",
   "confirm": "確認",
   "edit": "編集",
   "edit": "編集",
+  "status": "ステータス",
   "create": "作成",
   "create": "作成",
   "close": "閉じる",
   "close": "閉じる",
   "back": "戻る",
   "back": "戻る",

+ 13 - 3
messages/ja/customs.json

@@ -26,16 +26,26 @@
     "viewRelease": "リリースを表示"
     "viewRelease": "リリースを表示"
   },
   },
   "metrics": {
   "metrics": {
-    "concurrent": "同時実行",
+    "concurrent": "アクティブセッション数",
     "todayRequests": "本日のリクエスト",
     "todayRequests": "本日のリクエスト",
     "todayCost": "本日のコスト",
     "todayCost": "本日のコスト",
     "avgResponse": "平均応答時間",
     "avgResponse": "平均応答時間",
-    "viewDetails": "詳細を表示"
+    "viewDetails": "詳細を表示",
+    "rpm": "RPM",
+    "vsYesterday": "前日同時間帯比"
   },
   },
   "activeSessions": {
   "activeSessions": {
     "title": "アクティブなセッション",
     "title": "アクティブなセッション",
     "summary": "過去{minutes}分間の{count}個のセッション",
     "summary": "過去{minutes}分間の{count}個のセッション",
     "empty": "アクティブなセッションがありません",
     "empty": "アクティブなセッションがありません",
-    "viewAll": "すべて表示"
+    "viewAll": "すべて表示",
+    "loading": "読み込み中...",
+    "unknownUser": "不明",
+    "status": {
+      "inProgressTooltip": "セッションはアクティブなリクエストを処理中です",
+      "initializingTooltip": "セッションは最初のリクエストで初期化中です",
+      "idleTooltip": "セッションはアイドル状態で、アクティブなリクエストはありません",
+      "errorTooltip": "セッション処理中にエラーが発生しました"
+    }
   }
   }
 }
 }

+ 288 - 11
messages/ja/dashboard.json

@@ -21,7 +21,8 @@
     "keysQuotas": "キー クォータ統計",
     "keysQuotas": "キー クォータ統計",
     "providersQuotas": "プロバイダー クォータ統計",
     "providersQuotas": "プロバイダー クォータ統計",
     "usageLogsDescription": "API 呼び出しログと使用統計を表示します",
     "usageLogsDescription": "API 呼び出しログと使用統計を表示します",
-    "filterCriteria": "フィルター条件"
+    "filterCriteria": "フィルター条件",
+    "filterCriteriaDescription": "時間、ユーザー、プロバイダーなどでログを絞り込む"
   },
   },
   "description": {
   "description": {
     "viewApiCallLogs": "API 呼び出しログと使用統計を表示します",
     "viewApiCallLogs": "API 呼び出しログと使用統計を表示します",
@@ -93,7 +94,28 @@
       "export": "エクスポート",
       "export": "エクスポート",
       "exporting": "エクスポート中...",
       "exporting": "エクスポート中...",
       "exportSuccess": "エクスポートが完了しました",
       "exportSuccess": "エクスポートが完了しました",
-      "exportError": "エクスポートに失敗しました"
+      "exportError": "エクスポートに失敗しました",
+      "quickFilters": {
+        "today": "今日",
+        "thisWeek": "今週",
+        "errorsOnly": "エラーのみ",
+        "showRetries": "リトライあり"
+      },
+      "activeFilters": {
+        "title": "有効なフィルター",
+        "remove": "フィルターを削除",
+        "clearAll": "すべてクリア"
+      },
+      "groups": {
+        "time": "時間範囲",
+        "timeDesc": "日付と時間でフィルター",
+        "identity": "ID情報",
+        "identityDesc": "ユーザーとキーでフィルター",
+        "request": "リクエスト",
+        "requestDesc": "プロバイダー、モデル、エンドポイントでフィルター",
+        "status": "ステータス",
+        "statusDesc": "ステータスコードとリトライでフィルター"
+      }
     },
     },
     "columns": {
     "columns": {
       "time": "時間",
       "time": "時間",
@@ -116,9 +138,7 @@
     },
     },
     "stats": {
     "stats": {
       "title": "統計サマリー",
       "title": "統計サマリー",
-      "description": "クリックして現在のフィルター条件の集計統計を表示",
-      "expand": "展開",
-      "collapse": "折りたたむ",
+      "description": "現在のフィルター条件の集計統計",
       "totalAmount": "総消費金額",
       "totalAmount": "総消費金額",
       "totalTokens": "総トークン数",
       "totalTokens": "総トークン数",
       "cacheTokens": "キャッシュトークン",
       "cacheTokens": "キャッシュトークン",
@@ -144,7 +164,8 @@
       "noMoreData": "すべてのレコードを読み込みました",
       "noMoreData": "すべてのレコードを読み込みました",
       "scrollToTop": "トップへ戻る",
       "scrollToTop": "トップへ戻る",
       "hideProviderColumn": "プロバイダー列を非表示",
       "hideProviderColumn": "プロバイダー列を非表示",
-      "showProviderColumn": "プロバイダー列を表示"
+      "showProviderColumn": "プロバイダー列を表示",
+      "columnVisibility": "列の表示/非表示"
     },
     },
     "actions": {
     "actions": {
       "refresh": "更新",
       "refresh": "更新",
@@ -161,12 +182,27 @@
     },
     },
     "details": {
     "details": {
       "title": "リクエスト詳細",
       "title": "リクエスト詳細",
-      "statusTitle": "リクエスト詳細 - ステータスコード {status}",
+      "statusTitle": "ステータス: {status}",
       "inProgress": "処理中",
       "inProgress": "処理中",
       "unknown": "不明",
       "unknown": "不明",
       "success": "リクエストが正常に完了しました",
       "success": "リクエストが正常に完了しました",
       "error": "リクエスト失敗、詳細なエラー情報とプロバイダー決定チェーンは以下の通りです",
       "error": "リクエスト失敗、詳細なエラー情報とプロバイダー決定チェーンは以下の通りです",
       "processing": "リクエストは処理中であり、まだ完了していません",
       "processing": "リクエストは処理中であり、まだ完了していません",
+      "tabs": {
+        "summary": "概要",
+        "logicTrace": "決定チェーン",
+        "performance": "パフォーマンス",
+        "metadata": "メタデータ"
+      },
+      "summary": {
+        "keyMetrics": "主要指標",
+        "totalCost": "総コスト",
+        "totalTokens": "総トークン数",
+        "duration": "所要時間",
+        "outputRate": "出力速度",
+        "viewFullError": "完全なエラーを表示",
+        "viewSession": "セッションを表示"
+      },
       "specialSettings": {
       "specialSettings": {
         "title": "特殊設定"
         "title": "特殊設定"
       },
       },
@@ -207,6 +243,7 @@
         "billingRedirected": "課金: 実際"
         "billingRedirected": "課金: 実際"
       },
       },
       "errorMessage": "エラーメッセージ",
       "errorMessage": "エラーメッセージ",
+      "filteredProviders": "フィルタされたプロバイダー",
       "providerChain": {
       "providerChain": {
         "title": "プロバイダー決定チェーンタイムライン",
         "title": "プロバイダー決定チェーンタイムライン",
         "totalDuration": "合計所要時間: {duration}ms"
         "totalDuration": "合計所要時間: {duration}ms"
@@ -223,13 +260,72 @@
         "circuitOpen": "サーキットブレーカー開放"
         "circuitOpen": "サーキットブレーカー開放"
       },
       },
       "billingDetails": {
       "billingDetails": {
-        "title": "課金詳細"
+        "title": "課金詳細",
+        "input": "入力",
+        "output": "出力",
+        "cacheWrite5m": "キャッシュ書き込み (5m)",
+        "cacheWrite1h": "キャッシュ書き込み (1h)",
+        "cacheRead": "キャッシュ読み取り",
+        "cacheTtl": "キャッシュ TTL",
+        "multiplier": "プロバイダー倍率",
+        "totalCost": "総コスト",
+        "context1m": "1M コンテキスト",
+        "context1mPricing": "入力 2x >200k, 出力 1.5x >200k"
       },
       },
       "performance": {
       "performance": {
         "title": "パフォーマンス",
         "title": "パフォーマンス",
         "ttfb": "TTFB",
         "ttfb": "TTFB",
         "duration": "総所要時間",
         "duration": "総所要時間",
         "outputRate": "出力速度"
         "outputRate": "出力速度"
+      },
+      "performanceTab": {
+        "noPerformanceData": "パフォーマンスデータがありません",
+        "ttfbGauge": "初バイト到達時間",
+        "outputRateGauge": "出力速度",
+        "latencyBreakdown": "レイテンシ内訳",
+        "generationTime": "生成時間",
+        "assessment": {
+          "excellent": "優秀",
+          "good": "良好",
+          "warning": "警告",
+          "poor": "不良"
+        },
+        "thresholds": {
+          "ttfbGood": "TTFB < 1s",
+          "ttfbWarning": "TTFB 1-2s",
+          "ttfbPoor": "TTFB > 3s"
+        }
+      },
+      "metadata": {
+        "noMetadata": "メタデータがありません",
+        "sessionInfo": "セッション情報",
+        "clientInfo": "クライアント情報",
+        "billingInfo": "課金情報",
+        "technicalTimeline": "技術タイムライン",
+        "copyTimeline": "タイムラインをコピー"
+      },
+      "logicTrace": {
+        "title": "決定チェーン",
+        "noDecisionData": "決定データがありません",
+        "providersCount": "{count} プロバイダー",
+        "healthyCount": "{count} 健全",
+        "initialSelection": "初期選択",
+        "healthCheck": "ヘルスチェック",
+        "prioritySelection": "優先度選択",
+        "attemptProvider": "試行: {provider}",
+        "retryAttempt": "再試行 #{number}",
+        "sessionReuse": "セッション再利用",
+        "sessionReuseDesc": "セッションキャッシュからプロバイダーを再利用",
+        "sessionReuseTitle": "セッションバインディング",
+        "sessionReuseSelection": "セッション再利用選択",
+        "sessionReuseSelectionDesc": "セッションキャッシュからプロバイダーを選択",
+        "sessionInfo": "セッション情報",
+        "sessionIdLabel": "セッション ID",
+        "requestSequence": "リクエスト番号",
+        "sessionAge": "セッション経過時間",
+        "reusedProvider": "再利用プロバイダー",
+        "executeRequest": "リクエスト実行",
+        "cacheOptimizationHint": "セッション再利用は、同じ会話内でプロバイダーの親和性を維持することでパフォーマンスを最適化し、選択オーバーヘッドを削減してキャッシュヒット率を向上させます。"
       }
       }
     },
     },
     "providerChain": {
     "providerChain": {
@@ -920,6 +1016,82 @@
     "title": "プロバイダー可用性モニター",
     "title": "プロバイダー可用性モニター",
     "description": "プロバイダーの可用性とパフォーマンス指標をリアルタイムで監視",
     "description": "プロバイダーの可用性とパフォーマンス指標をリアルタイムで監視",
     "nav": "可用性モニター",
     "nav": "可用性モニター",
+    "tabs": {
+      "provider": "プロバイダー可用性",
+      "endpoint": "エンドポイント健全性"
+    },
+    "overview": {
+      "systemAvailability": "システム可用性",
+      "avgLatency": "平均遅延",
+      "errorRate": "エラー率",
+      "activeProbes": "アクティブプローブ",
+      "load": "負荷"
+    },
+    "timeRange": {
+      "15min": "15分",
+      "1h": "1時間",
+      "6h": "6時間",
+      "24h": "24時間",
+      "7d": "7日"
+    },
+    "laneChart": {
+      "title": "プロバイダー可用性タイムライン",
+      "noData": "データがありません",
+      "requests": "{count} リクエスト",
+      "availability": "{value}% 可用",
+      "noRequests": "リクエストなし"
+    },
+    "latencyChart": {
+      "title": "遅延分布",
+      "p50": "P50",
+      "p95": "P95",
+      "p99": "P99",
+      "noData": "遅延データがありません"
+    },
+    "latencyCurve": {
+      "title": "遅延トレンド",
+      "noData": "遅延データがありません",
+      "avg": "平均",
+      "min": "最小",
+      "max": "最大",
+      "latency": "遅延"
+    },
+    "terminal": {
+      "title": "プローブログ",
+      "live": "LIVE",
+      "download": "ログをダウンロード",
+      "noLogs": "プローブログがありません",
+      "manual": "手動",
+      "auto": "自動",
+      "filterPlaceholder": "ログをフィルター..."
+    },
+    "probeGrid": {
+      "noEndpoints": "エンドポイントが設定されていません",
+      "lastProbe": "最終プローブ",
+      "status": {
+        "unknown": "不明",
+        "healthy": "正常",
+        "unhealthy": "異常"
+      }
+    },
+    "endpoint": {
+      "selectVendor": "ベンダーを選択",
+      "selectType": "タイプを選択"
+    },
+    "confidence": {
+      "low": "低",
+      "medium": "中",
+      "high": "高",
+      "lowTooltip": "{count} 件未満のリクエスト。データが代表的でない可能性があります。",
+      "mediumTooltip": "中程度のリクエスト量。データは比較的信頼できます。",
+      "highTooltip": "高いリクエスト量。データは信頼できます。"
+    },
+    "actions": {
+      "probeNow": "今すぐプローブ",
+      "probing": "プローブ中...",
+      "probeSuccess": "プローブ成功",
+      "probeFailed": "プローブ失敗"
+    },
     "status": {
     "status": {
       "green": "正常(OK)",
       "green": "正常(OK)",
       "red": "異常",
       "red": "異常",
@@ -943,6 +1115,11 @@
     },
     },
     "timeRange": {
     "timeRange": {
       "label": "時間範囲",
       "label": "時間範囲",
+      "15min": "15分",
+      "1h": "1時間",
+      "6h": "6時間",
+      "24h": "24時間",
+      "7d": "7日間",
       "last15min": "過去15分",
       "last15min": "過去15分",
       "last1h": "過去1時間",
       "last1h": "過去1時間",
       "last6h": "過去6時間",
       "last6h": "過去6時間",
@@ -993,7 +1170,13 @@
       "autoRefresh": "自動更新",
       "autoRefresh": "自動更新",
       "stopAutoRefresh": "自動更新を停止",
       "stopAutoRefresh": "自動更新を停止",
       "viewDetails": "詳細を表示",
       "viewDetails": "詳細を表示",
-      "testProvider": "プロバイダーをテスト"
+      "testProvider": "プロバイダーをテスト",
+      "retry": "再試行",
+      "probeNow": "今すぐプローブ",
+      "probing": "プローブ中...",
+      "probeAll": "すべてプローブ",
+      "probeSuccess": "プローブ成功",
+      "probeFailed": "プローブ失敗"
     },
     },
     "states": {
     "states": {
       "loading": "読み込み中...",
       "loading": "読み込み中...",
@@ -1023,6 +1206,84 @@
       "noData": "データなし",
       "noData": "データなし",
       "noRequests": "リクエストなし"
       "noRequests": "リクエストなし"
     },
     },
+    "probeHistory": {
+      "title": "エンドポイントプローブ履歴",
+      "description": "プローブログを確認し、特定のエンドポイントを手動でプローブできます",
+      "selectVendor": "ベンダーを選択",
+      "selectType": "プロバイダー種別を選択",
+      "selectEndpoint": "エンドポイントを選択",
+      "noEndpoints": "エンドポイントが見つかりません",
+      "probeNow": "今すぐプローブ",
+      "probing": "プローブ中...",
+      "columns": {
+        "time": "時間",
+        "method": "方法",
+        "status": "ステータス",
+        "latency": "レイテンシ",
+        "error": "エラー"
+      },
+      "success": "成功",
+      "manual": "手動プローブ",
+      "auto": "自動プローブ",
+      "probeSuccess": "プローブ成功",
+      "probeFailed": "プローブ失敗"
+    },
+    "laneChart": {
+      "title": "プロバイダー可用性タイムライン",
+      "noData": "データなし",
+      "requests": "{count} リクエスト",
+      "availability": "可用性 {value}%",
+      "noRequests": "リクエストなし",
+      "denseData": "高密度",
+      "sparseData": "低密度",
+      "latency": "レイテンシ"
+    },
+    "latencyChart": {
+      "title": "レイテンシ分布",
+      "p50": "P50",
+      "p95": "P95",
+      "p99": "P99",
+      "noData": "レイテンシデータなし"
+    },
+    "latencyCurve": {
+      "title": "レイテンシトレンド",
+      "noData": "レイテンシデータなし",
+      "avg": "平均",
+      "min": "最小",
+      "max": "最大",
+      "latency": "レイテンシ"
+    },
+    "terminal": {
+      "title": "プローブログ",
+      "live": "ライブ",
+      "download": "ログをダウンロード",
+      "noLogs": "プローブログなし",
+      "manual": "手動",
+      "auto": "自動",
+      "filterPlaceholder": "ログをフィルター..."
+    },
+    "probeGrid": {
+      "title": "エンドポイントステータス",
+      "noEndpoints": "エンドポイント未設定",
+      "lastProbe": "最終プローブ",
+      "status": {
+        "unknown": "不明",
+        "healthy": "正常",
+        "unhealthy": "異常"
+      }
+    },
+    "endpoint": {
+      "selectVendor": "ベンダーを選択",
+      "selectType": "タイプを選択"
+    },
+    "confidence": {
+      "low": "低",
+      "medium": "中",
+      "high": "高",
+      "lowTooltip": "リクエスト数が {count} 未満です。データが代表的でない可能性があります。",
+      "mediumTooltip": "リクエスト量は適度です。データは比較的信頼できます。",
+      "highTooltip": "リクエスト量が十分です。データは信頼できます。"
+    },
     "toast": {
     "toast": {
       "refreshSuccess": "可用性データを更新しました",
       "refreshSuccess": "可用性データを更新しました",
       "refreshFailed": "更新に失敗しました。再試行してください"
       "refreshFailed": "更新に失敗しました。再試行してください"
@@ -1184,8 +1445,23 @@
       "columns": {
       "columns": {
         "model": "モデル",
         "model": "モデル",
         "calls": "呼び出し回数",
         "calls": "呼び出し回数",
+        "tokens": "トークン",
         "cost": "消費金額"
         "cost": "消費金額"
       },
       },
+      "modal": {
+        "requests": "リクエスト",
+        "totalTokens": "トークン合計",
+        "cost": "コスト",
+        "inputTokens": "入力トークン",
+        "outputTokens": "出力トークン",
+        "cacheWrite": "キャッシュ書込",
+        "cacheRead": "キャッシュ読取",
+        "cacheHitRate": "キャッシュヒット率",
+        "cacheTokens": "キャッシュトークン",
+        "performanceHigh": "高",
+        "performanceMedium": "中",
+        "performanceLow": "低"
+      },
       "noData": "本日の使用記録はありません",
       "noData": "本日の使用記録はありません",
       "totalCalls": "総呼び出し数",
       "totalCalls": "総呼び出し数",
       "totalCost": "総消費"
       "totalCost": "総消費"
@@ -1327,7 +1603,7 @@
           "limitDaily": "日次上限 (USD)",
           "limitDaily": "日次上限 (USD)",
           "limitWeekly": "週次上限 (USD)",
           "limitWeekly": "週次上限 (USD)",
           "limitMonthly": "月次上限 (USD)",
           "limitMonthly": "月次上限 (USD)",
-          "canLoginWebUi": "Web UI へのログインを許可",
+          "canLoginWebUi": "独立した個人使用量ページ",
           "keyEnabled": "キー有効状態"
           "keyEnabled": "キー有効状態"
         },
         },
         "placeholders": {
         "placeholders": {
@@ -1490,7 +1766,8 @@
       "clickToEnableUser": "クリックしてユーザーを有効化",
       "clickToEnableUser": "クリックしてユーザーを有効化",
       "operationFailed": "操作に失敗しました",
       "operationFailed": "操作に失敗しました",
       "deleteFailed": "削除に失敗しました",
       "deleteFailed": "削除に失敗しました",
-      "deleteSuccess": "削除しました"
+      "deleteSuccess": "削除しました",
+      "daysLeft": "{days, plural, =0 {本日期限} =1 {残り1日} other {残り#日}}"
     },
     },
     "userEditSection": {
     "userEditSection": {
       "sections": {
       "sections": {

+ 6 - 0
messages/ja/errors.json

@@ -63,6 +63,12 @@
   "UPDATE_KEY_FAILED": "キーの更新に失敗しました。後でもう一度お試しください",
   "UPDATE_KEY_FAILED": "キーの更新に失敗しました。後でもう一度お試しください",
   "DELETE_KEY_FAILED": "キーの削除に失敗しました。後でもう一度お試しください",
   "DELETE_KEY_FAILED": "キーの削除に失敗しました。後でもう一度お試しください",
   "CANNOT_DISABLE_LAST_KEY": "最後のアクティブなキーを無効にすることはできません。ユーザーには少なくとも1つの有効なキーが必要です",
   "CANNOT_DISABLE_LAST_KEY": "最後のアクティブなキーを無効にすることはできません。ユーザーには少なくとも1つの有効なキーが必要です",
+  "KEY_LIMIT_5H_EXCEEDS_USER_LIMIT": "キーの5時間上限({keyLimit})はユーザー上限({userLimit})を超えられません",
+  "KEY_LIMIT_DAILY_EXCEEDS_USER_LIMIT": "キーの日次上限({keyLimit})はユーザー上限({userLimit})を超えられません",
+  "KEY_LIMIT_WEEKLY_EXCEEDS_USER_LIMIT": "キーの週次上限({keyLimit})はユーザー上限({userLimit})を超えられません",
+  "KEY_LIMIT_MONTHLY_EXCEEDS_USER_LIMIT": "キーの月次上限({keyLimit})はユーザー上限({userLimit})を超えられません",
+  "KEY_LIMIT_TOTAL_EXCEEDS_USER_LIMIT": "キーの総上限({keyLimit})はユーザー上限({userLimit})を超えられません",
+  "KEY_LIMIT_CONCURRENT_EXCEEDS_USER_LIMIT": "キーの同時セッション上限({keyLimit})はユーザー上限({userLimit})を超えられません",
   "EXPIRES_AT_FIELD": "有効期限",
   "EXPIRES_AT_FIELD": "有効期限",
   "EXPIRES_AT_MUST_BE_FUTURE": "有効期限は将来の日付である必要があります",
   "EXPIRES_AT_MUST_BE_FUTURE": "有効期限は将来の日付である必要があります",
   "EXPIRES_AT_TOO_FAR": "有効期限は10年を超えることはできません",
   "EXPIRES_AT_TOO_FAR": "有効期限は10年を超えることはできません",

+ 2 - 2
messages/ja/myUsage.json

@@ -78,7 +78,7 @@
     "inheritedFromUser": "ユーザーから継承"
     "inheritedFromUser": "ユーザーから継承"
   },
   },
   "stats": {
   "stats": {
-    "title": "統計サマリー",
+    "title": "キー統計",
     "autoRefresh": "{seconds}秒ごとに自動更新",
     "autoRefresh": "{seconds}秒ごとに自動更新",
     "totalRequests": "リクエスト総数",
     "totalRequests": "リクエスト総数",
     "totalCost": "総コスト",
     "totalCost": "総コスト",
@@ -116,7 +116,7 @@
     "noRestrictions": "制限なし"
     "noRestrictions": "制限なし"
   },
   },
   "quotaCollapsible": {
   "quotaCollapsible": {
-    "title": "クォータ使用状況",
+    "title": "ユーザークォータ使用状況",
     "daily": "日次",
     "daily": "日次",
     "monthly": "月次",
     "monthly": "月次",
     "total": "合計"
     "total": "合計"

+ 43 - 0
messages/ja/provider-chain.json

@@ -39,6 +39,48 @@
     "http2Fallback": "HTTP/2 フォールバック",
     "http2Fallback": "HTTP/2 フォールバック",
     "clientError": "クライアントエラー"
     "clientError": "クライアントエラー"
   },
   },
+  "reasons": {
+    "request_success": "成功",
+    "retry_success": "リトライ成功",
+    "retry_failed": "リトライ失敗",
+    "system_error": "システムエラー",
+    "client_error_non_retryable": "クライアントエラー",
+    "concurrent_limit_failed": "同時実行制限",
+    "http2_fallback": "HTTP/2 フォールバック",
+    "session_reuse": "セッション再利用",
+    "initial_selection": "初期選択"
+  },
+  "filterReasons": {
+    "rate_limited": "レート制限",
+    "circuit_open": "サーキットオープン",
+    "disabled": "無効",
+    "model_not_supported": "モデル非対応",
+    "group_mismatch": "グループ不一致",
+    "health_check_failed": "ヘルスチェック失敗"
+  },
+  "details": {
+    "selectionMethod": "選択方法",
+    "attemptNumber": "試行回数",
+    "endpoint": "エンドポイント",
+    "config": "設定",
+    "priority": "優先度",
+    "weight": "重み",
+    "costMultiplier": "コスト倍率",
+    "groupTag": "グループタグ",
+    "circuitBreaker": "サーキットブレーカー",
+    "circuitDisabled": "無効",
+    "failures": "回失敗",
+    "modelRedirect": "モデルリダイレクト",
+    "error": "エラー",
+    "errorDetails": "エラー詳細",
+    "decisionContext": "決定コンテキスト",
+    "beforeHealthCheck": "ヘルスチェック前",
+    "afterHealthCheck": "ヘルスチェック後",
+    "filteredProviders": "フィルタされたプロバイダー",
+    "priorityLevels": "優先度レベル",
+    "candidates": "候補プロバイダー"
+  },
+  "technicalTimeline": "技術タイムライン",
   "timeline": {
   "timeline": {
     "sessionReuse": "セッション再利用",
     "sessionReuse": "セッション再利用",
     "sessionReuseSelection": "セッション再利用 - プロバイダー選択",
     "sessionReuseSelection": "セッション再利用 - プロバイダー選択",
@@ -87,6 +129,7 @@
     "status": "状態",
     "status": "状態",
     "alreadyBroken": "すでに遮断済み",
     "alreadyBroken": "すでに遮断済み",
     "circuitTriggered": "警告:サーキットブレーカーが作動しました",
     "circuitTriggered": "警告:サーキットブレーカーが作動しました",
+    "circuitDisabled": "サーキットブレーカー無効",
     "errorDetails": "エラー詳細",
     "errorDetails": "エラー詳細",
     "systemError": "システムエラー",
     "systemError": "システムエラー",
     "systemErrorFailed": "システムエラー(試行{attempt})",
     "systemErrorFailed": "システムエラー(試行{attempt})",

+ 7 - 1
messages/ja/settings/clientVersions.json

@@ -38,7 +38,13 @@
     "unknown": "不明",
     "unknown": "不明",
     "user": "ユーザー",
     "user": "ユーザー",
     "usersCount": "{count}名のユーザー",
     "usersCount": "{count}名のユーザー",
-    "version": "現在のバージョン"
+    "version": "現在のバージョン",
+    "stats": {
+      "clientTypes": "クライアントタイプ",
+      "totalUsers": "ユーザー総数",
+      "withGA": "GA版あり",
+      "coverage": "GAカバレッジ"
+    }
   },
   },
   "title": "クライアント更新リマインダー",
   "title": "クライアント更新リマインダー",
   "toggle": {
   "toggle": {

+ 1 - 0
messages/ja/settings/data.json

@@ -123,6 +123,7 @@
   },
   },
   "status": {
   "status": {
     "connected": "データベース接続正常",
     "connected": "データベース接続正常",
+    "connectionUnavailable": "データベース接続が利用できません。データベースサービスの状態を確認してください",
     "error": "データベースステータスの取得に失敗しました",
     "error": "データベースステータスの取得に失敗しました",
     "loading": "読み込み中...",
     "loading": "読み込み中...",
     "retry": "再試行",
     "retry": "再試行",

+ 5 - 0
messages/ja/settings/index.ts

@@ -13,6 +13,7 @@ import sensitiveWords from "./sensitiveWords.json";
 import strings from "./strings.json";
 import strings from "./strings.json";
 
 
 import providersAutoSort from "./providers/autoSort.json";
 import providersAutoSort from "./providers/autoSort.json";
+import providersBatchEdit from "./providers/batchEdit.json";
 import providersFilter from "./providers/filter.json";
 import providersFilter from "./providers/filter.json";
 import providersGuide from "./providers/guide.json";
 import providersGuide from "./providers/guide.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
@@ -37,6 +38,7 @@ import providersFormModelSelect from "./providers/form/modelSelect.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
+import providersFormQuickPaste from "./providers/form/quickPaste.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormSuccess from "./providers/form/success.json";
 import providersFormSuccess from "./providers/form/success.json";
@@ -47,6 +49,7 @@ import providersFormWebsiteUrl from "./providers/form/websiteUrl.json";
 
 
 const providersForm = {
 const providersForm = {
   ...providersFormStrings,
   ...providersFormStrings,
+  ...providersFormCommon,
   apiTest: providersFormApiTest,
   apiTest: providersFormApiTest,
   buttons: providersFormButtons,
   buttons: providersFormButtons,
   common: providersFormCommon,
   common: providersFormCommon,
@@ -60,6 +63,7 @@ const providersForm = {
   name: providersFormName,
   name: providersFormName,
   providerTypes: providersFormProviderTypes,
   providerTypes: providersFormProviderTypes,
   proxyTest: providersFormProxyTest,
   proxyTest: providersFormProxyTest,
+  quickPaste: providersFormQuickPaste,
   sections: providersFormSections,
   sections: providersFormSections,
   success: providersFormSuccess,
   success: providersFormSuccess,
   title: providersFormTitle,
   title: providersFormTitle,
@@ -71,6 +75,7 @@ const providersForm = {
 const providers = {
 const providers = {
   ...providersStrings,
   ...providersStrings,
   autoSort: providersAutoSort,
   autoSort: providersAutoSort,
+  batchEdit: providersBatchEdit,
   filter: providersFilter,
   filter: providersFilter,
   form: providersForm,
   form: providersForm,
   guide: providersGuide,
   guide: providersGuide,

+ 2 - 0
messages/ja/settings/notifications.json

@@ -69,6 +69,8 @@
   "global": {
   "global": {
     "description": "すべてのプッシュ通知機能を有効または無効にする",
     "description": "すべてのプッシュ通知機能を有効または無効にする",
     "enable": "プッシュ通知を有効にする",
     "enable": "プッシュ通知を有効にする",
+    "off": "オフ",
+    "on": "オン",
     "legacyModeDescription": "現在は旧来の単一URL通知設定を使用しています。プッシュ先を作成するとマルチターゲットモードに切り替わります。",
     "legacyModeDescription": "現在は旧来の単一URL通知設定を使用しています。プッシュ先を作成するとマルチターゲットモードに切り替わります。",
     "legacyModeTitle": "互換モード",
     "legacyModeTitle": "互換モード",
     "title": "通知マスタースイッチ"
     "title": "通知マスタースイッチ"

+ 43 - 0
messages/ja/settings/providers/batchEdit.json

@@ -0,0 +1,43 @@
+{
+  "enterMode": "一括編集",
+  "exitMode": "終了",
+  "selectAll": "全選択",
+  "invertSelection": "反転",
+  "selectedCount": "{count} 件選択中",
+  "editSelected": "選択項目を編集",
+  "actions": {
+    "edit": "編集",
+    "delete": "削除",
+    "resetCircuit": "サーキット リセット"
+  },
+  "dialog": {
+    "editTitle": "プロバイダーの一括編集",
+    "editDesc": "{count} 件のプロバイダーに変更が適用されます",
+    "deleteTitle": "プロバイダーの削除",
+    "deleteDesc": "{count} 件のプロバイダーを完全に削除しますか?",
+    "resetCircuitTitle": "サーキットブレーカーのリセット",
+    "resetCircuitDesc": "{count} 件のプロバイダーのサーキットブレーカーをリセットしますか?",
+    "next": "次へ",
+    "noFieldEnabled": "更新するフィールドを少なくとも1つ有効にしてください"
+  },
+  "fields": {
+    "isEnabled": "ステータス",
+    "priority": "優先度",
+    "weight": "重み",
+    "costMultiplier": "価格倍率",
+    "groupTag": "グループタグ"
+  },
+  "confirm": {
+    "title": "操作の確認",
+    "cancel": "キャンセル",
+    "confirm": "確認",
+    "goBack": "戻る",
+    "processing": "処理中..."
+  },
+  "toast": {
+    "updated": "{count} 件のプロバイダーを更新しました",
+    "deleted": "{count} 件のプロバイダーを削除しました",
+    "circuitReset": "{count} 件のサーキットブレーカーをリセットしました",
+    "failed": "操作に失敗しました: {error}"
+  }
+}

+ 8 - 1
messages/ja/settings/providers/form/common.json

@@ -1,3 +1,10 @@
 {
 {
-  "core": "コア"
+  "core": "コア",
+  "tabs": {
+    "basic": "基本情報",
+    "routing": "ルーティング",
+    "limits": "制限",
+    "network": "ネットワーク",
+    "testing": "テスト"
+  }
 }
 }

+ 1 - 0
messages/ja/settings/providers/form/key.json

@@ -1,6 +1,7 @@
 {
 {
   "currentKey": "現在のキー: {key}",
   "currentKey": "現在のキー: {key}",
   "label": "API キー",
   "label": "API キー",
+  "labelEdit": "API キー(空欄のままにすると変更しません)",
   "leaveEmpty": "(空欄のままにすると変更しません)",
   "leaveEmpty": "(空欄のままにすると変更しません)",
   "leaveEmptyDesc": "空欄のままにすると既存のキーを保持します",
   "leaveEmptyDesc": "空欄のままにすると既存のキーを保持します",
   "placeholder": "API キーを入力"
   "placeholder": "API キーを入力"

+ 1 - 1
messages/ja/settings/providers/form/name.json

@@ -1,4 +1,4 @@
 {
 {
-  "label": "プロバイダー名 *",
+  "label": "プロバイダー名",
   "placeholder": "例: Zhipu"
   "placeholder": "例: Zhipu"
 }
 }

+ 15 - 0
messages/ja/settings/providers/form/quickPaste.json

@@ -0,0 +1,15 @@
+{
+  "button": "クイック貼り付け",
+  "title": "クイック貼り付け",
+  "description": "プロバイダー情報(URL、APIキーなど)を含むテキストを貼り付けると、自動的に抽出されます。",
+  "placeholder": "ここにプロバイダー設定テキストを貼り付けてください...",
+  "preview": "検出された情報",
+  "type": "タイプ",
+  "name": "名前",
+  "url": "URL",
+  "key": "APIキー",
+  "notFound": "検出されませんでした",
+  "parseError": "テキストからプロバイダー情報を解析できませんでした",
+  "cancel": "キャンセル",
+  "confirm": "適用"
+}

+ 30 - 8
messages/ja/settings/providers/form/sections.json

@@ -1,4 +1,18 @@
 {
 {
+  "basic": {
+    "identity": {
+      "title": "プロバイダー識別",
+      "desc": "このプロバイダーを識別する一意の名前を設定"
+    },
+    "endpoint": {
+      "title": "API エンドポイント",
+      "desc": "API リクエストのベース URL を設定"
+    },
+    "auth": {
+      "title": "認証",
+      "desc": "認証用の API キーを入力"
+    }
+  },
   "apiTest": {
   "apiTest": {
     "desc": "プロバイダーのモデルが利用可能かをテストします。既定ではルーティング設定で選択したプロバイダー種別に従います。",
     "desc": "プロバイダーのモデルが利用可能かをテストします。既定ではルーティング設定で選択したプロバイダー種別に従います。",
     "summary": "プロバイダーとモデルの接続性を確認",
     "summary": "プロバイダーとモデルの接続性を確認",
@@ -10,7 +24,8 @@
     "failureThreshold": {
     "failureThreshold": {
       "desc": "何回連続失敗でブレークするか",
       "desc": "何回連続失敗でブレークするか",
       "label": "失敗しきい値(回)",
       "label": "失敗しきい値(回)",
-      "placeholder": "5"
+      "placeholder": "5",
+      "warning": "0に設定するとサーキットブレーカーが無効になります - 慎重に使用してください"
     },
     },
     "maxRetryAttempts": {
     "maxRetryAttempts": {
       "desc": "初回呼び出しを含め、同一プロバイダーで試行する上限。超えると他のプロバイダーへ切り替えます。未入力の場合はデフォルト値を使用。",
       "desc": "初回呼び出しを含め、同一プロバイダーで試行する上限。超えると他のプロバイダーへ切り替えます。未入力の場合はデフォルト値を使用。",
@@ -115,6 +130,8 @@
     }
     }
   },
   },
   "rateLimit": {
   "rateLimit": {
+    "title": "レート制限",
+    "desc": "異なる時間枠での消費制限を設定してコストを管理します",
     "dailyResetMode": {
     "dailyResetMode": {
       "desc": {
       "desc": {
         "fixed": "毎日決まった時刻にクォータをリセット",
         "fixed": "毎日決まった時刻にクォータをリセット",
@@ -164,6 +181,11 @@
     },
     },
     "title": "レート制限"
     "title": "レート制限"
   },
   },
+  "limits": {
+    "timeBased": "時間ベースの制限",
+    "dailyReset": "日次リセット設定",
+    "otherLimits": "その他の制限"
+  },
   "routing": {
   "routing": {
     "cacheTtl": {
     "cacheTtl": {
       "desc": "プロンプトキャッシュのTTLを強制設定。cache_controlを含むリクエストにのみ適用されます。",
       "desc": "プロンプトキャッシュのTTLを強制設定。cache_controlを含むリクエストにのみ適用されます。",
@@ -263,7 +285,7 @@
         "placeholder": "1.0"
         "placeholder": "1.0"
       },
       },
       "group": {
       "group": {
-        "desc": "グループタグ。ユーザーの providerGroup が一致する場合のみ利用可能。例: \"premium\" に設定すると providerGroup=\"premium\" のユーザーのみ対象",
+        "desc": "グループタグ。リストから選択するか、新しい名前を入力して Enter で作成(最大50文字)。providerGroup が一致するユーザーのみがこのプロバイダーを使用できます。",
         "label": "プロバイダーグループ",
         "label": "プロバイダーグループ",
         "placeholder": "例: premium, economy"
         "placeholder": "例: premium, economy"
       },
       },
@@ -291,21 +313,21 @@
     "disableHint": "0に設定するとタイムアウトを無効にします(カナリアロールバックシナリオのみ、非推奨)",
     "disableHint": "0に設定するとタイムアウトを無効にします(カナリアロールバックシナリオのみ、非推奨)",
     "nonStreamingTotal": {
     "nonStreamingTotal": {
       "core": "true",
       "core": "true",
-      "desc": "非ストリーミングリクエストの総タイムアウト、範囲60~1200秒、デフォルト600秒(10分)",
+      "desc": "非ストリーミングリクエストの総タイムアウト、範囲60~1200秒、0で無効化(デフォルト: 無制限)",
       "label": "非ストリーミング総タイムアウト(秒)",
       "label": "非ストリーミング総タイムアウト(秒)",
-      "placeholder": "600"
+      "placeholder": "0"
     },
     },
     "streamingFirstByte": {
     "streamingFirstByte": {
       "core": "true",
       "core": "true",
-      "desc": "ストリーミングリクエストの初バイトタイムアウト、範囲1~120秒、デフォルト30秒",
+      "desc": "ストリーミングリクエストの初バイトタイムアウト、範囲1~180秒、0で無効化(デフォルト: 無制限)",
       "label": "ストリーミング初バイトタイムアウト(秒)",
       "label": "ストリーミング初バイトタイムアウト(秒)",
-      "placeholder": "30"
+      "placeholder": "0"
     },
     },
     "streamingIdle": {
     "streamingIdle": {
       "core": "true",
       "core": "true",
-      "desc": "ストリーミングリクエストのアイドルタイムアウト、範囲60~600秒、0で無効化(途中停止防止)",
+      "desc": "ストリーミングリクエストのアイドルタイムアウト、範囲60~600秒、0で無効化(デフォルト: 無制限)",
       "label": "ストリーミングアイドルタイムアウト(秒)",
       "label": "ストリーミングアイドルタイムアウト(秒)",
-      "placeholder": "60"
+      "placeholder": "0"
     },
     },
     "summary": "初回バイト: {streaming}s | ストリーム間隔: {idle}s | 非ストリーミング: {nonStreaming}s",
     "summary": "初回バイト: {streaming}s | ストリーム間隔: {idle}s | 非ストリーミング: {nonStreaming}s",
     "title": "タイムアウト設定"
     "title": "タイムアウト設定"

+ 3 - 1
messages/ja/settings/providers/form/success.json

@@ -1,4 +1,6 @@
 {
 {
   "created": "プロバイダーを追加しました",
   "created": "プロバイダーを追加しました",
-  "createdDesc": "「{name}」を追加しました"
+  "createdDesc": "「{name}」を追加しました",
+  "updated": "プロバイダーを更新しました",
+  "updatedDesc": "「{name}」を更新しました"
 }
 }

+ 1 - 1
messages/ja/settings/providers/form/url.json

@@ -1,4 +1,4 @@
 {
 {
-  "label": "API アドレス *",
+  "label": "API アドレス",
   "placeholder": "例: https://open.bigmodel.cn/api/anthropic"
   "placeholder": "例: https://open.bigmodel.cn/api/anthropic"
 }
 }

+ 12 - 1
messages/ja/settings/providers/form/urlPreview.json

@@ -5,5 +5,16 @@
   "duplicatePath": "重複パス検出",
   "duplicatePath": "重複パス検出",
   "invalidUrl": "無効なURL形式",
   "invalidUrl": "無効なURL形式",
   "invalidUrlDesc": "有効なHTTP/HTTPSアドレスを入力してください",
   "invalidUrlDesc": "有効なHTTP/HTTPSアドレスを入力してください",
-  "title": "URL結合プレビュー"
+  "title": "URL結合プレビュー",
+  "endpoints": {
+    "claudeMessages": "Claude メッセージ",
+    "claudeCountTokens": "Claude トークン数",
+    "codexResponses": "Codex Responses",
+    "openaiChatCompletions": "OpenAI Chat Completions",
+    "openaiModels": "OpenAI Models",
+    "geminiGenerateContent": "Gemini Generate Content",
+    "geminiStreamContent": "Gemini Stream Content",
+    "geminiCliGenerate": "Gemini CLI Generate",
+    "geminiCliStream": "Gemini CLI Stream"
+  }
 }
 }

+ 57 - 1
messages/ja/settings/providers/strings.json

@@ -43,5 +43,61 @@
   "toggleSuccessDesc": "プロバイダー「{name}」の状態を更新しました",
   "toggleSuccessDesc": "プロバイダー「{name}」の状態を更新しました",
   "updateFailed": "プロバイダーの更新に失敗しました",
   "updateFailed": "プロバイダーの更新に失敗しました",
   "viewKey": "完全な API キーを表示",
   "viewKey": "完全な API キーを表示",
-  "viewKeyDesc": "安全に保管し、他人に共有しないでください"
+  "viewKeyDesc": "安全に保管し、他人に共有しないでください",
+  "viewMode": "表示モード",
+  "viewModeList": "リスト",
+  "viewModeVendor": "ベンダー",
+  "endpoints": "エンドポイント",
+  "manualProbe": "テスト",
+  "addEndpoint": "エンドポイントを追加",
+  "lastProbed": "最終テスト",
+  "latency": "レイテンシ",
+  "status": "状態",
+  "vendorKeys": "API キー",
+  "addVendorKey": "API キーを追加",
+  "addVendorKeyDesc": "このベンダーに API キーを追加します (API URL の入力は不要です)。",
+  "addVendorKeySuccess": "API キーを追加しました",
+  "addVendorKeyFailed": "API キーの追加に失敗しました",
+  "probeSuccess": "テスト成功",
+  "probeFailed": "テスト失敗",
+  "manualCircuitOpen": "手動で回路を開く",
+  "manualCircuitClose": "回路を閉じる",
+  "circuitStatus": "回路状態",
+  "vendorTypeCircuit": "ベンダー種別回路",
+  "vendorFallbackName": "ベンダー #{id}",
+  "orphanedProviders": "不明なベンダー",
+  "vendorTypeCircuitUpdated": "ベンダータイプサーキットが更新されました",
+  "noEndpoints": "エンドポイントが設定されていません",
+  "noEndpointsDesc": "フェイルオーバーを有効にするにはエンドポイントを追加してください",
+  "columnUrl": "URL",
+  "columnActions": "操作",
+  "confirmDeleteEndpoint": "このエンドポイントを削除してもよろしいですか?",
+  "endpointAddSuccess": "エンドポイントを追加しました",
+  "endpointAddFailed": "エンドポイントの追加に失敗しました",
+  "endpointUpdateSuccess": "エンドポイントを更新しました",
+  "endpointUpdateFailed": "エンドポイントの更新に失敗しました",
+  "endpointDeleteSuccess": "エンドポイントを削除しました",
+  "endpointDeleteFailed": "エンドポイントの削除に失敗しました",
+  "probeOk": "OK",
+  "probeError": "エラー",
+  "addEndpointDesc": "このベンダーに {providerType} エンドポイントを追加します。",
+  "endpointUrlLabel": "URL",
+  "endpointUrlPlaceholder": "https://api.example.com/v1",
+  "endpointLabelOptional": "ラベル (任意)",
+  "endpointLabelPlaceholder": "本番環境",
+  "editEndpoint": "エンドポイントを編集",
+  "editVendor": "ベンダーを編集",
+  "vendorName": "ベンダー名",
+  "vendorWebsite": "Webサイト URL",
+  "vendorWebsitePlaceholder": "https://example.com",
+  "vendorOfficial": "公式",
+  "deleteVendor": "ベンダーを削除",
+  "deleteVendorConfirmTitle": "ベンダーを削除しますか?",
+  "deleteVendorDoubleConfirmTitle": "削除を確定しますか?",
+  "deleteVendorConfirmDesc": "ベンダー「{name}」と関連する API キーおよびエンドポイントをすべて永久に削除します。",
+  "deleteVendorDoubleConfirmDesc": "この操作は元に戻せません。「{name}」に関するすべてのデータを削除してよいか確認してください。",
+  "vendorUpdateSuccess": "ベンダーを更新しました",
+  "vendorUpdateFailed": "ベンダーの更新に失敗しました",
+  "vendorDeleteSuccess": "ベンダーを削除しました",
+  "vendorDeleteFailed": "ベンダーの削除に失敗しました"
 }
 }

+ 1 - 0
messages/ru/common.json

@@ -4,6 +4,7 @@
   "delete": "Удалить",
   "delete": "Удалить",
   "confirm": "Подтвердить",
   "confirm": "Подтвердить",
   "edit": "Редактировать",
   "edit": "Редактировать",
+  "status": "Статус",
   "create": "Создать",
   "create": "Создать",
   "close": "Закрыть",
   "close": "Закрыть",
   "back": "Назад",
   "back": "Назад",

+ 13 - 3
messages/ru/customs.json

@@ -26,16 +26,26 @@
     "viewRelease": "Просмотр релиза"
     "viewRelease": "Просмотр релиза"
   },
   },
   "metrics": {
   "metrics": {
-    "concurrent": "Одновременно",
+    "concurrent": "Активные сессии",
     "todayRequests": "Запросы сегодня",
     "todayRequests": "Запросы сегодня",
     "todayCost": "Стоимость сегодня",
     "todayCost": "Стоимость сегодня",
     "avgResponse": "Среднее время ответа",
     "avgResponse": "Среднее время ответа",
-    "viewDetails": "Просмотр деталей"
+    "viewDetails": "Просмотр деталей",
+    "rpm": "RPM",
+    "vsYesterday": "к вчера"
   },
   },
   "activeSessions": {
   "activeSessions": {
     "title": "Активные сеансы",
     "title": "Активные сеансы",
     "summary": "{count} сеансов в последние {minutes} минут",
     "summary": "{count} сеансов в последние {minutes} минут",
     "empty": "Нет активных сеансов",
     "empty": "Нет активных сеансов",
-    "viewAll": "Просмотреть все"
+    "viewAll": "Просмотреть все",
+    "loading": "Загрузка...",
+    "unknownUser": "неизвестно",
+    "status": {
+      "inProgressTooltip": "Сеанс обрабатывает активные запросы",
+      "initializingTooltip": "Сеанс инициализируется с первым запросом",
+      "idleTooltip": "Сеанс простаивает, нет активных запросов",
+      "errorTooltip": "Во время обработки сеанса произошла ошибка"
+    }
   }
   }
 }
 }

+ 233 - 19
messages/ru/dashboard.json

@@ -21,7 +21,8 @@
     "keysQuotas": "Статистика квот ключей",
     "keysQuotas": "Статистика квот ключей",
     "providersQuotas": "Статистика квот поставщиков",
     "providersQuotas": "Статистика квот поставщиков",
     "usageLogsDescription": "Просмотр журналов вызовов API и статистики использования",
     "usageLogsDescription": "Просмотр журналов вызовов API и статистики использования",
-    "filterCriteria": "Критерии фильтрации"
+    "filterCriteria": "Критерии фильтрации",
+    "filterCriteriaDescription": "Фильтруйте журналы по времени, пользователю, поставщику и другим параметрам"
   },
   },
   "description": {
   "description": {
     "viewApiCallLogs": "Просмотр журналов вызовов API и статистики использования",
     "viewApiCallLogs": "Просмотр журналов вызовов API и статистики использования",
@@ -93,7 +94,28 @@
       "export": "Экспорт",
       "export": "Экспорт",
       "exporting": "Экспорт...",
       "exporting": "Экспорт...",
       "exportSuccess": "Экспорт завершен",
       "exportSuccess": "Экспорт завершен",
-      "exportError": "Ошибка экспорта"
+      "exportError": "Ошибка экспорта",
+      "quickFilters": {
+        "today": "Сегодня",
+        "thisWeek": "Эта неделя",
+        "errorsOnly": "Только ошибки",
+        "showRetries": "С ретраями"
+      },
+      "activeFilters": {
+        "title": "Активные фильтры",
+        "remove": "Удалить фильтр",
+        "clearAll": "Очистить все"
+      },
+      "groups": {
+        "time": "Период времени",
+        "timeDesc": "Фильтр по дате и времени",
+        "identity": "Идентификация",
+        "identityDesc": "Фильтр по пользователю и ключу",
+        "request": "Запрос",
+        "requestDesc": "Фильтр по поставщику, модели, эндпоинту",
+        "status": "Статус",
+        "statusDesc": "Фильтр по коду состояния и ретраям"
+      }
     },
     },
     "columns": {
     "columns": {
       "time": "Время",
       "time": "Время",
@@ -116,9 +138,7 @@
     },
     },
     "stats": {
     "stats": {
       "title": "Сводка статистики",
       "title": "Сводка статистики",
-      "description": "Нажмите для просмотра агрегированной статистики по текущим фильтрам",
-      "expand": "Развернуть",
-      "collapse": "Свернуть",
+      "description": "Агрегированная статистика по текущим фильтрам",
       "totalAmount": "Общая сумма расходов",
       "totalAmount": "Общая сумма расходов",
       "totalTokens": "Общее количество токенов",
       "totalTokens": "Общее количество токенов",
       "cacheTokens": "Токены кэша",
       "cacheTokens": "Токены кэша",
@@ -144,7 +164,8 @@
       "noMoreData": "Все записи загружены",
       "noMoreData": "Все записи загружены",
       "scrollToTop": "Наверх",
       "scrollToTop": "Наверх",
       "hideProviderColumn": "Скрыть столбец провайдера",
       "hideProviderColumn": "Скрыть столбец провайдера",
-      "showProviderColumn": "Показать столбец провайдера"
+      "showProviderColumn": "Показать столбец провайдера",
+      "columnVisibility": "Видимость столбцов"
     },
     },
     "actions": {
     "actions": {
       "refresh": "Обновить",
       "refresh": "Обновить",
@@ -161,12 +182,27 @@
     },
     },
     "details": {
     "details": {
       "title": "Детали запроса",
       "title": "Детали запроса",
-      "statusTitle": "Детали запроса - код состояния {status}",
+      "statusTitle": "Статус: {status}",
       "inProgress": "В процессе",
       "inProgress": "В процессе",
       "unknown": "Неизвестно",
       "unknown": "Неизвестно",
       "success": "Запрос успешно выполнен",
       "success": "Запрос успешно выполнен",
       "error": "Запрос не выполнен, ниже подробная информация об ошибке и цепочке решений поставщика",
       "error": "Запрос не выполнен, ниже подробная информация об ошибке и цепочке решений поставщика",
       "processing": "Запрос находится в процессе выполнения и еще не завершен",
       "processing": "Запрос находится в процессе выполнения и еще не завершен",
+      "tabs": {
+        "summary": "Обзор",
+        "logicTrace": "Цепочка решений",
+        "performance": "Производительность",
+        "metadata": "Метаданные"
+      },
+      "summary": {
+        "keyMetrics": "Ключевые показатели",
+        "totalCost": "Общая стоимость",
+        "totalTokens": "Всего токенов",
+        "duration": "Длительность",
+        "outputRate": "Скорость вывода",
+        "viewFullError": "Показать полную ошибку",
+        "viewSession": "Просмотр сеанса"
+      },
       "specialSettings": {
       "specialSettings": {
         "title": "Особые настройки"
         "title": "Особые настройки"
       },
       },
@@ -207,6 +243,7 @@
         "billingRedirected": "оплата: факт."
         "billingRedirected": "оплата: факт."
       },
       },
       "errorMessage": "Сообщение об ошибке",
       "errorMessage": "Сообщение об ошибке",
+      "filteredProviders": "Отфильтрованные поставщики",
       "providerChain": {
       "providerChain": {
         "title": "Хронология цепочки решений поставщика",
         "title": "Хронология цепочки решений поставщика",
         "totalDuration": "Общая продолжительность: {duration}мс"
         "totalDuration": "Общая продолжительность: {duration}мс"
@@ -223,13 +260,72 @@
         "circuitOpen": "Размыкатель цепи открыт"
         "circuitOpen": "Размыкатель цепи открыт"
       },
       },
       "billingDetails": {
       "billingDetails": {
-        "title": "Детали биллинга"
+        "title": "Детали биллинга",
+        "input": "Входные",
+        "output": "Выходные",
+        "cacheWrite5m": "Запись кэша (5m)",
+        "cacheWrite1h": "Запись кэша (1h)",
+        "cacheRead": "Чтение кэша",
+        "cacheTtl": "TTL кэша",
+        "multiplier": "Множитель поставщика",
+        "totalCost": "Общая стоимость",
+        "context1m": "1M контекст",
+        "context1mPricing": "Вход 2x >200k, Выход 1.5x >200k"
       },
       },
       "performance": {
       "performance": {
         "title": "Производительность",
         "title": "Производительность",
         "ttfb": "TTFB",
         "ttfb": "TTFB",
         "duration": "Общее время",
         "duration": "Общее время",
         "outputRate": "Скорость вывода"
         "outputRate": "Скорость вывода"
+      },
+      "performanceTab": {
+        "noPerformanceData": "Нет данных о производительности",
+        "ttfbGauge": "Время до первого байта",
+        "outputRateGauge": "Скорость вывода",
+        "latencyBreakdown": "Разбивка задержки",
+        "generationTime": "Время генерации",
+        "assessment": {
+          "excellent": "Отлично",
+          "good": "Хорошо",
+          "warning": "Предупреждение",
+          "poor": "Плохо"
+        },
+        "thresholds": {
+          "ttfbGood": "TTFB < 1с",
+          "ttfbWarning": "TTFB 1-2с",
+          "ttfbPoor": "TTFB > 3с"
+        }
+      },
+      "metadata": {
+        "noMetadata": "Нет метаданных",
+        "sessionInfo": "Информация о сеансе",
+        "clientInfo": "Информация о клиенте",
+        "billingInfo": "Информация о биллинге",
+        "technicalTimeline": "Техническая хронология",
+        "copyTimeline": "Копировать хронологию"
+      },
+      "logicTrace": {
+        "title": "Цепочка решений",
+        "noDecisionData": "Нет данных о решениях",
+        "providersCount": "{count} поставщиков",
+        "healthyCount": "{count} исправных",
+        "initialSelection": "Начальный выбор",
+        "healthCheck": "Проверка работоспособности",
+        "prioritySelection": "Выбор по приоритету",
+        "attemptProvider": "Попытка: {provider}",
+        "retryAttempt": "Повтор #{number}",
+        "sessionReuse": "Повторное использование сессии",
+        "sessionReuseDesc": "Провайдер из кэша сессии",
+        "sessionReuseTitle": "Привязка сессии",
+        "sessionReuseSelection": "Выбор с повторным использованием сессии",
+        "sessionReuseSelectionDesc": "Провайдер выбран из кэша сессии",
+        "sessionInfo": "Информация о сессии",
+        "sessionIdLabel": "ID сессии",
+        "requestSequence": "Номер запроса",
+        "sessionAge": "Возраст сессии",
+        "reusedProvider": "Повторно используемый провайдер",
+        "executeRequest": "Выполнить запрос",
+        "cacheOptimizationHint": "Повторное использование сессии оптимизирует производительность, поддерживая привязку к провайдеру в рамках одного разговора, снижая накладные расходы на выбор и повышая частоту попаданий в кэш."
       }
       }
     },
     },
     "providerChain": {
     "providerChain": {
@@ -922,6 +1018,95 @@
     "title": "Мониторинг доступности провайдеров",
     "title": "Мониторинг доступности провайдеров",
     "description": "Мониторинг доступности и показателей производительности провайдеров в реальном времени",
     "description": "Мониторинг доступности и показателей производительности провайдеров в реальном времени",
     "nav": "Мониторинг доступности",
     "nav": "Мониторинг доступности",
+    "tabs": {
+      "provider": "Доступность провайдеров",
+      "endpoint": "Здоровье эндпоинтов"
+    },
+    "overview": {
+      "systemAvailability": "Доступность системы",
+      "avgLatency": "Средняя задержка",
+      "errorRate": "Коэффициент ошибок",
+      "activeProbes": "Активные проверки",
+      "load": "Нагрузка"
+    },
+    "timeRange": {
+      "label": "Временной диапазон",
+      "15min": "15 мин",
+      "1h": "1 час",
+      "6h": "6 часов",
+      "24h": "24 часа",
+      "7d": "7 дней",
+      "last15min": "Последние 15 минут",
+      "last1h": "Последний час",
+      "last6h": "Последние 6 часов",
+      "last24h": "Последние 24 часа",
+      "last7d": "7д",
+      "custom": "Настраиваемый"
+    },
+    "laneChart": {
+      "title": "Хронология доступности провайдеров",
+      "noData": "Нет данных",
+      "requests": "{count} запросов",
+      "availability": "{value}% доступно",
+      "noRequests": "Нет запросов",
+      "denseData": "Плотные",
+      "sparseData": "Разреженные",
+      "latency": "Задержка"
+    },
+    "latencyChart": {
+      "title": "Распределение задержки",
+      "p50": "P50",
+      "p95": "P95",
+      "p99": "P99",
+      "noData": "Нет данных о задержке"
+    },
+    "latencyCurve": {
+      "title": "Тренд задержки",
+      "noData": "Нет данных о задержке",
+      "avg": "Средн.",
+      "min": "Мин.",
+      "max": "Макс.",
+      "latency": "Задержка"
+    },
+    "terminal": {
+      "title": "Журнал проверок",
+      "live": "LIVE",
+      "download": "Скачать журнал",
+      "noLogs": "Нет журналов проверок",
+      "manual": "Ручная",
+      "auto": "Авто",
+      "filterPlaceholder": "Фильтр журналов..."
+    },
+    "probeGrid": {
+      "title": "Статус эндпоинтов",
+      "noEndpoints": "Эндпоинты не настроены",
+      "lastProbe": "Последняя проверка",
+      "status": {
+        "unknown": "Неизвестно",
+        "healthy": "Здоров",
+        "unhealthy": "Нездоров"
+      }
+    },
+    "endpoint": {
+      "selectVendor": "Выберите вендора",
+      "selectType": "Выберите тип"
+    },
+    "confidence": {
+      "low": "Низкая",
+      "medium": "Средняя",
+      "high": "Высокая",
+      "lowTooltip": "Менее {count} запросов. Данные могут быть нерепрезентативными.",
+      "mediumTooltip": "Умеренный объём запросов. Данные достаточно надёжны.",
+      "highTooltip": "Высокий объём запросов. Данные надёжны."
+    },
+    "actions": {
+      "retry": "Повторить",
+      "probeNow": "Проверить сейчас",
+      "probing": "Проверка...",
+      "probeAll": "Проверить все",
+      "probeSuccess": "Проверка успешна",
+      "probeFailed": "Проверка не удалась"
+    },
     "status": {
     "status": {
       "green": "Здоров",
       "green": "Здоров",
       "red": "Недоступен",
       "red": "Недоступен",
@@ -943,15 +1128,6 @@
       "lastRequest": "Последний запрос",
       "lastRequest": "Последний запрос",
       "requestCount": "Кол-во запросов"
       "requestCount": "Кол-во запросов"
     },
     },
-    "timeRange": {
-      "label": "Временной диапазон",
-      "last15min": "Последние 15 минут",
-      "last1h": "Последний час",
-      "last6h": "Последние 6 часов",
-      "last24h": "Последние 24 часа",
-      "last7d": "7д",
-      "custom": "Настраиваемый"
-    },
     "filters": {
     "filters": {
       "provider": "Провайдер",
       "provider": "Провайдер",
       "allProviders": "Все провайдеры",
       "allProviders": "Все провайдеры",
@@ -1025,6 +1201,28 @@
       "noData": "Нет данных",
       "noData": "Нет данных",
       "noRequests": "Нет запросов"
       "noRequests": "Нет запросов"
     },
     },
+    "probeHistory": {
+      "title": "История проверок эндпоинтов",
+      "description": "Просмотр журналов проверок и запуск ручной проверки для конкретного эндпоинта",
+      "selectVendor": "Выберите вендора",
+      "selectType": "Выберите тип провайдера",
+      "selectEndpoint": "Выберите эндпоинт",
+      "noEndpoints": "Эндпоинты не найдены",
+      "probeNow": "Проверить",
+      "probing": "Проверяем...",
+      "columns": {
+        "time": "Время",
+        "method": "Метод",
+        "status": "Статус",
+        "latency": "Задержка",
+        "error": "Ошибка"
+      },
+      "success": "Успех",
+      "manual": "Ручная проверка",
+      "auto": "Автоматическая проверка",
+      "probeSuccess": "Проверка успешна",
+      "probeFailed": "Проверка не удалась"
+    },
     "toast": {
     "toast": {
       "refreshSuccess": "Данные о доступности обновлены",
       "refreshSuccess": "Данные о доступности обновлены",
       "refreshFailed": "Обновление не удалось, попробуйте снова"
       "refreshFailed": "Обновление не удалось, попробуйте снова"
@@ -1191,8 +1389,23 @@
       "columns": {
       "columns": {
         "model": "Модель",
         "model": "Модель",
         "calls": "Вызовы",
         "calls": "Вызовы",
+        "tokens": "Токены",
         "cost": "Стоимость"
         "cost": "Стоимость"
       },
       },
+      "modal": {
+        "requests": "Запросов",
+        "totalTokens": "Всего токенов",
+        "cost": "Стоимость",
+        "inputTokens": "Входные токены",
+        "outputTokens": "Выходные токены",
+        "cacheWrite": "Запись кэша",
+        "cacheRead": "Чтение кэша",
+        "cacheHitRate": "Попадание кэша",
+        "cacheTokens": "Токены кэша",
+        "performanceHigh": "Высокий",
+        "performanceMedium": "Средний",
+        "performanceLow": "Низкий"
+      },
       "noData": "Нет записей использования за сегодня",
       "noData": "Нет записей использования за сегодня",
       "totalCalls": "Всего вызовов",
       "totalCalls": "Всего вызовов",
       "totalCost": "Общий расход"
       "totalCost": "Общий расход"
@@ -1338,7 +1551,7 @@
           "limitDaily": "Дневной лимит (USD)",
           "limitDaily": "Дневной лимит (USD)",
           "limitWeekly": "Недельный лимит (USD)",
           "limitWeekly": "Недельный лимит (USD)",
           "limitMonthly": "Месячный лимит (USD)",
           "limitMonthly": "Месячный лимит (USD)",
-          "canLoginWebUi": "Разрешить вход в Web UI",
+          "canLoginWebUi": "Независимая страница использования",
           "keyEnabled": "Статус ключа"
           "keyEnabled": "Статус ключа"
         },
         },
         "placeholders": {
         "placeholders": {
@@ -1543,7 +1756,8 @@
       "clickToEnableUser": "Нажмите, чтобы включить пользователя",
       "clickToEnableUser": "Нажмите, чтобы включить пользователя",
       "operationFailed": "Операция не удалась",
       "operationFailed": "Операция не удалась",
       "deleteFailed": "Не удалось удалить",
       "deleteFailed": "Не удалось удалить",
-      "deleteSuccess": "Удаление успешно"
+      "deleteSuccess": "Удаление успешно",
+      "daysLeft": "{days, plural, =0 {Истекает сегодня} =1 {Остался 1 день} few {Осталось # дня} many {Осталось # дней} other {Осталось # дней}}"
     },
     },
     "userEditSection": {
     "userEditSection": {
       "sections": {
       "sections": {

+ 6 - 0
messages/ru/errors.json

@@ -63,6 +63,12 @@
   "UPDATE_KEY_FAILED": "Не удалось обновить ключ, попробуйте позже",
   "UPDATE_KEY_FAILED": "Не удалось обновить ключ, попробуйте позже",
   "DELETE_KEY_FAILED": "Не удалось удалить ключ, попробуйте позже",
   "DELETE_KEY_FAILED": "Не удалось удалить ключ, попробуйте позже",
   "CANNOT_DISABLE_LAST_KEY": "Невозможно отключить последний активный ключ. У пользователя должен быть хотя бы один включенный ключ",
   "CANNOT_DISABLE_LAST_KEY": "Невозможно отключить последний активный ключ. У пользователя должен быть хотя бы один включенный ключ",
+  "KEY_LIMIT_5H_EXCEEDS_USER_LIMIT": "Лимит ключа на 5 часов ({keyLimit}) не может превышать лимит пользователя ({userLimit})",
+  "KEY_LIMIT_DAILY_EXCEEDS_USER_LIMIT": "Дневной лимит ключа ({keyLimit}) не может превышать лимит пользователя ({userLimit})",
+  "KEY_LIMIT_WEEKLY_EXCEEDS_USER_LIMIT": "Недельный лимит ключа ({keyLimit}) не может превышать лимит пользователя ({userLimit})",
+  "KEY_LIMIT_MONTHLY_EXCEEDS_USER_LIMIT": "Месячный лимит ключа ({keyLimit}) не может превышать лимит пользователя ({userLimit})",
+  "KEY_LIMIT_TOTAL_EXCEEDS_USER_LIMIT": "Общий лимит ключа ({keyLimit}) не может превышать лимит пользователя ({userLimit})",
+  "KEY_LIMIT_CONCURRENT_EXCEEDS_USER_LIMIT": "Лимит одновременных сессий ключа ({keyLimit}) не может превышать лимит пользователя ({userLimit})",
   "EXPIRES_AT_FIELD": "Дата истечения",
   "EXPIRES_AT_FIELD": "Дата истечения",
   "EXPIRES_AT_MUST_BE_FUTURE": "Дата истечения должна быть в будущем",
   "EXPIRES_AT_MUST_BE_FUTURE": "Дата истечения должна быть в будущем",
   "EXPIRES_AT_TOO_FAR": "Дата истечения не может превышать 10 лет",
   "EXPIRES_AT_TOO_FAR": "Дата истечения не может превышать 10 лет",

+ 2 - 2
messages/ru/myUsage.json

@@ -78,7 +78,7 @@
     "inheritedFromUser": "Наследовано от пользователя"
     "inheritedFromUser": "Наследовано от пользователя"
   },
   },
   "stats": {
   "stats": {
-    "title": "Сводка статистики",
+    "title": "Статистика ключа",
     "autoRefresh": "Автообновление каждые {seconds}с",
     "autoRefresh": "Автообновление каждые {seconds}с",
     "totalRequests": "Всего запросов",
     "totalRequests": "Всего запросов",
     "totalCost": "Общая стоимость",
     "totalCost": "Общая стоимость",
@@ -116,7 +116,7 @@
     "noRestrictions": "Без ограничений"
     "noRestrictions": "Без ограничений"
   },
   },
   "quotaCollapsible": {
   "quotaCollapsible": {
-    "title": "Использование квоты",
+    "title": "Квота пользователя",
     "daily": "День",
     "daily": "День",
     "monthly": "Месяц",
     "monthly": "Месяц",
     "total": "Всего"
     "total": "Всего"

+ 43 - 0
messages/ru/provider-chain.json

@@ -39,6 +39,48 @@
     "http2Fallback": "Откат HTTP/2",
     "http2Fallback": "Откат HTTP/2",
     "clientError": "Ошибка клиента"
     "clientError": "Ошибка клиента"
   },
   },
+  "reasons": {
+    "request_success": "Успешно",
+    "retry_success": "Повтор успешен",
+    "retry_failed": "Повтор не удался",
+    "system_error": "Системная ошибка",
+    "client_error_non_retryable": "Ошибка клиента",
+    "concurrent_limit_failed": "Лимит параллельных запросов",
+    "http2_fallback": "Откат HTTP/2",
+    "session_reuse": "Повторное использование сессии",
+    "initial_selection": "Первоначальный выбор"
+  },
+  "filterReasons": {
+    "rate_limited": "Ограничение скорости",
+    "circuit_open": "Автомат открыт",
+    "disabled": "Отключен",
+    "model_not_supported": "Модель не поддерживается",
+    "group_mismatch": "Несоответствие группы",
+    "health_check_failed": "Проверка состояния не пройдена"
+  },
+  "details": {
+    "selectionMethod": "Метод выбора",
+    "attemptNumber": "Номер попытки",
+    "endpoint": "Конечная точка",
+    "config": "Конфигурация",
+    "priority": "Приоритет",
+    "weight": "Вес",
+    "costMultiplier": "Множитель стоимости",
+    "groupTag": "Тег группы",
+    "circuitBreaker": "Автомат защиты",
+    "circuitDisabled": "Отключен",
+    "failures": "ошибок",
+    "modelRedirect": "Перенаправление модели",
+    "error": "Ошибка",
+    "errorDetails": "Детали ошибки",
+    "decisionContext": "Контекст решения",
+    "beforeHealthCheck": "До проверки состояния",
+    "afterHealthCheck": "После проверки состояния",
+    "filteredProviders": "Отфильтрованные провайдеры",
+    "priorityLevels": "Уровни приоритета",
+    "candidates": "Кандидаты провайдеров"
+  },
+  "technicalTimeline": "Техническая временная шкала",
   "timeline": {
   "timeline": {
     "sessionReuse": "Повторное использование сессии",
     "sessionReuse": "Повторное использование сессии",
     "sessionReuseSelection": "Повторное использование сессии - Выбор провайдера",
     "sessionReuseSelection": "Повторное использование сессии - Выбор провайдера",
@@ -87,6 +129,7 @@
     "status": "Состояние",
     "status": "Состояние",
     "alreadyBroken": "Уже сработал",
     "alreadyBroken": "Уже сработал",
     "circuitTriggered": "Предупреждение: Автомат защиты сработал",
     "circuitTriggered": "Предупреждение: Автомат защиты сработал",
+    "circuitDisabled": "Автомат защиты отключен",
     "errorDetails": "Детали ошибки",
     "errorDetails": "Детали ошибки",
     "systemError": "Системная ошибка",
     "systemError": "Системная ошибка",
     "systemErrorFailed": "Системная ошибка (Попытка {attempt})",
     "systemErrorFailed": "Системная ошибка (Попытка {attempt})",

+ 7 - 1
messages/ru/settings/clientVersions.json

@@ -38,7 +38,13 @@
     "unknown": "Неизвестно",
     "unknown": "Неизвестно",
     "user": "Пользователь",
     "user": "Пользователь",
     "usersCount": "{count} пользователей",
     "usersCount": "{count} пользователей",
-    "version": "Текущая версия"
+    "version": "Текущая версия",
+    "stats": {
+      "clientTypes": "Типы клиентов",
+      "totalUsers": "Всего пользователей",
+      "withGA": "С GA версией",
+      "coverage": "Покрытие GA"
+    }
   },
   },
   "title": "Напоминание об обновлении клиента",
   "title": "Напоминание об обновлении клиента",
   "toggle": {
   "toggle": {

+ 1 - 0
messages/ru/settings/data.json

@@ -123,6 +123,7 @@
   },
   },
   "status": {
   "status": {
     "connected": "База данных подключена",
     "connected": "База данных подключена",
+    "connectionUnavailable": "Подключение к базе данных недоступно, проверьте состояние сервиса базы данных",
     "error": "Не удалось получить статус базы данных",
     "error": "Не удалось получить статус базы данных",
     "loading": "Загрузка...",
     "loading": "Загрузка...",
     "retry": "Повторить",
     "retry": "Повторить",

+ 5 - 0
messages/ru/settings/index.ts

@@ -13,6 +13,7 @@ import sensitiveWords from "./sensitiveWords.json";
 import strings from "./strings.json";
 import strings from "./strings.json";
 
 
 import providersAutoSort from "./providers/autoSort.json";
 import providersAutoSort from "./providers/autoSort.json";
+import providersBatchEdit from "./providers/batchEdit.json";
 import providersFilter from "./providers/filter.json";
 import providersFilter from "./providers/filter.json";
 import providersGuide from "./providers/guide.json";
 import providersGuide from "./providers/guide.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
@@ -37,6 +38,7 @@ import providersFormModelSelect from "./providers/form/modelSelect.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
+import providersFormQuickPaste from "./providers/form/quickPaste.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormSuccess from "./providers/form/success.json";
 import providersFormSuccess from "./providers/form/success.json";
@@ -47,6 +49,7 @@ import providersFormWebsiteUrl from "./providers/form/websiteUrl.json";
 
 
 const providersForm = {
 const providersForm = {
   ...providersFormStrings,
   ...providersFormStrings,
+  ...providersFormCommon,
   apiTest: providersFormApiTest,
   apiTest: providersFormApiTest,
   buttons: providersFormButtons,
   buttons: providersFormButtons,
   common: providersFormCommon,
   common: providersFormCommon,
@@ -60,6 +63,7 @@ const providersForm = {
   name: providersFormName,
   name: providersFormName,
   providerTypes: providersFormProviderTypes,
   providerTypes: providersFormProviderTypes,
   proxyTest: providersFormProxyTest,
   proxyTest: providersFormProxyTest,
+  quickPaste: providersFormQuickPaste,
   sections: providersFormSections,
   sections: providersFormSections,
   success: providersFormSuccess,
   success: providersFormSuccess,
   title: providersFormTitle,
   title: providersFormTitle,
@@ -71,6 +75,7 @@ const providersForm = {
 const providers = {
 const providers = {
   ...providersStrings,
   ...providersStrings,
   autoSort: providersAutoSort,
   autoSort: providersAutoSort,
+  batchEdit: providersBatchEdit,
   filter: providersFilter,
   filter: providersFilter,
   form: providersForm,
   form: providersForm,
   guide: providersGuide,
   guide: providersGuide,

+ 2 - 0
messages/ru/settings/notifications.json

@@ -69,6 +69,8 @@
   "global": {
   "global": {
     "description": "Включить или отключить все функции push-уведомлений",
     "description": "Включить или отключить все функции push-уведомлений",
     "enable": "Включить push-уведомления",
     "enable": "Включить push-уведомления",
+    "off": "Выкл",
+    "on": "Вкл",
     "legacyModeDescription": "Сейчас используется устаревшая схема уведомлений с одним URL. Создайте цель отправки, чтобы перейти на режим с несколькими целями.",
     "legacyModeDescription": "Сейчас используется устаревшая схема уведомлений с одним URL. Создайте цель отправки, чтобы перейти на режим с несколькими целями.",
     "legacyModeTitle": "Режим совместимости",
     "legacyModeTitle": "Режим совместимости",
     "title": "Главный переключатель уведомлений"
     "title": "Главный переключатель уведомлений"

+ 43 - 0
messages/ru/settings/providers/batchEdit.json

@@ -0,0 +1,43 @@
+{
+  "enterMode": "Массовое редактирование",
+  "exitMode": "Выход",
+  "selectAll": "Выбрать все",
+  "invertSelection": "Инвертировать",
+  "selectedCount": "Выбрано: {count}",
+  "editSelected": "Редактировать выбранные",
+  "actions": {
+    "edit": "Редактировать",
+    "delete": "Удалить",
+    "resetCircuit": "Сбросить прерыватель"
+  },
+  "dialog": {
+    "editTitle": "Массовое редактирование поставщиков",
+    "editDesc": "Изменения будут применены к {count} поставщикам",
+    "deleteTitle": "Удалить поставщиков",
+    "deleteDesc": "Удалить {count} поставщиков навсегда?",
+    "resetCircuitTitle": "Сбросить прерыватели",
+    "resetCircuitDesc": "Сбросить прерыватель для {count} поставщиков?",
+    "next": "Далее",
+    "noFieldEnabled": "Пожалуйста, включите хотя бы одно поле для обновления"
+  },
+  "fields": {
+    "isEnabled": "Статус",
+    "priority": "Приоритет",
+    "weight": "Вес",
+    "costMultiplier": "Множитель стоимости",
+    "groupTag": "Тег группы"
+  },
+  "confirm": {
+    "title": "Подтвердите операцию",
+    "cancel": "Отмена",
+    "confirm": "Подтвердить",
+    "goBack": "Назад",
+    "processing": "Обработка..."
+  },
+  "toast": {
+    "updated": "Обновлено поставщиков: {count}",
+    "deleted": "Удалено поставщиков: {count}",
+    "circuitReset": "Сброшено прерывателей: {count}",
+    "failed": "Операция не удалась: {error}"
+  }
+}

+ 8 - 1
messages/ru/settings/providers/form/common.json

@@ -1,3 +1,10 @@
 {
 {
-  "core": "Основная"
+  "core": "Основная",
+  "tabs": {
+    "basic": "Основные",
+    "routing": "Маршрутизация",
+    "limits": "Лимиты",
+    "network": "Сеть",
+    "testing": "Тестирование"
+  }
 }
 }

+ 1 - 0
messages/ru/settings/providers/form/key.json

@@ -1,6 +1,7 @@
 {
 {
   "currentKey": "Текущий ключ: {key}",
   "currentKey": "Текущий ключ: {key}",
   "label": "API ключ",
   "label": "API ключ",
+  "labelEdit": "API ключ (Оставьте пустым, чтобы не менять)",
   "leaveEmpty": "(Оставьте пустым, чтобы не менять)",
   "leaveEmpty": "(Оставьте пустым, чтобы не менять)",
   "leaveEmptyDesc": "Пустое значение — без изменений",
   "leaveEmptyDesc": "Пустое значение — без изменений",
   "placeholder": "Введите API ключ"
   "placeholder": "Введите API ключ"

+ 1 - 1
messages/ru/settings/providers/form/name.json

@@ -1,4 +1,4 @@
 {
 {
-  "label": "Имя провайдера *",
+  "label": "Имя провайдера",
   "placeholder": "например: Zhipu"
   "placeholder": "например: Zhipu"
 }
 }

+ 15 - 0
messages/ru/settings/providers/form/quickPaste.json

@@ -0,0 +1,15 @@
+{
+  "button": "Быстрая вставка",
+  "title": "Быстрая вставка",
+  "description": "Вставьте текст с информацией о провайдере (URL, API-ключ и т.д.) для автоматического извлечения.",
+  "placeholder": "Вставьте текст конфигурации провайдера здесь...",
+  "preview": "Обнаруженная информация",
+  "type": "Тип",
+  "name": "Название",
+  "url": "URL",
+  "key": "API-ключ",
+  "notFound": "Не обнаружено",
+  "parseError": "Не удалось извлечь информацию о провайдере из текста",
+  "cancel": "Отмена",
+  "confirm": "Применить"
+}

+ 31 - 9
messages/ru/settings/providers/form/sections.json

@@ -1,4 +1,18 @@
 {
 {
+  "basic": {
+    "identity": {
+      "title": "Идентификация провайдера",
+      "desc": "Укажите уникальное имя для идентификации этого провайдера"
+    },
+    "endpoint": {
+      "title": "API Endpoint",
+      "desc": "Настройте базовый URL для API запросов"
+    },
+    "auth": {
+      "title": "Аутентификация",
+      "desc": "Укажите API ключ для аутентификации"
+    }
+  },
   "apiTest": {
   "apiTest": {
     "desc": "Проверяет доступность модели у провайдера. По умолчанию соответствует типу провайдера, выбранному в настройках маршрутизации.",
     "desc": "Проверяет доступность модели у провайдера. По умолчанию соответствует типу провайдера, выбранному в настройках маршрутизации.",
     "summary": "Проверка связности провайдера и модели",
     "summary": "Проверка связности провайдера и модели",
@@ -10,7 +24,8 @@
     "failureThreshold": {
     "failureThreshold": {
       "desc": "Сколько подряд неудач для срабатывания",
       "desc": "Сколько подряд неудач для срабатывания",
       "label": "Порог неудач",
       "label": "Порог неудач",
-      "placeholder": "5"
+      "placeholder": "5",
+      "warning": "Значение 0 отключает предохранитель - используйте с осторожностью"
     },
     },
     "maxRetryAttempts": {
     "maxRetryAttempts": {
       "desc": "Общее число попыток (включая первую) перед переключением на другого провайдера. Оставьте пустым для значения по умолчанию.",
       "desc": "Общее число попыток (включая первую) перед переключением на другого провайдера. Оставьте пустым для значения по умолчанию.",
@@ -115,6 +130,8 @@
     }
     }
   },
   },
   "rateLimit": {
   "rateLimit": {
+    "title": "Ограничения",
+    "desc": "Настройка лимитов расходов для контроля затрат в разных временных окнах",
     "dailyResetMode": {
     "dailyResetMode": {
       "desc": {
       "desc": {
         "fixed": "Сбрасывать квоту каждый день в фиксированное время",
         "fixed": "Сбрасывать квоту каждый день в фиксированное время",
@@ -164,6 +181,11 @@
     },
     },
     "title": "Ограничения"
     "title": "Ограничения"
   },
   },
+  "limits": {
+    "timeBased": "Временные ограничения",
+    "dailyReset": "Настройки ежедневного сброса",
+    "otherLimits": "Другие ограничения"
+  },
   "routing": {
   "routing": {
     "cacheTtl": {
     "cacheTtl": {
       "desc": "Принудительно задать TTL кэша промптов; влияет только на запросы с cache_control.",
       "desc": "Принудительно задать TTL кэша промптов; влияет только на запросы с cache_control.",
@@ -263,9 +285,9 @@
         "placeholder": "1.0"
         "placeholder": "1.0"
       },
       },
       "group": {
       "group": {
-        "desc": "Метка группы. Пользователь может использовать провайдера только если его providerGroup совпадает. Пример: значение \"premium\" — только для пользователей с providerGroup=\"premium\"",
+        "desc": "Тег группы. Выберите из списка или введите новое имя и нажмите Enter для создания (макс. 50 символов). Только пользователи с соответствующим providerGroup могут использовать этого провайдера.",
         "label": "Группа провайдера",
         "label": "Группа провайдера",
-        "placeholder": "например: premium, economy"
+        "placeholder": "напр. premium, economy"
       },
       },
       "priority": {
       "priority": {
         "desc": "Меньше — выше приоритет (0 — наивысший). Система выбирает только из провайдеров с максимальным приоритетом. Рекомендации: основной=0, резерв=1, аварийный=2",
         "desc": "Меньше — выше приоритет (0 — наивысший). Система выбирает только из провайдеров с максимальным приоритетом. Рекомендации: основной=0, резерв=1, аварийный=2",
@@ -291,21 +313,21 @@
     "disableHint": "Установите 0 для отключения тайм-аута (только для сценариев отката канарейки, не рекомендуется)",
     "disableHint": "Установите 0 для отключения тайм-аута (только для сценариев отката канарейки, не рекомендуется)",
     "nonStreamingTotal": {
     "nonStreamingTotal": {
       "core": "true",
       "core": "true",
-      "desc": "Полный тайм-аут непотоковой передачи, диапазон 60-1200 секунд, значение по умолчанию 600 секунд (10 минут)",
+      "desc": "Полный тайм-аут непотоковой передачи, диапазон 60-1200 секунд, 0 для отключения (по умолчанию: без ограничений)",
       "label": "Полный тайм-аут непотоковой передачи (секунды)",
       "label": "Полный тайм-аут непотоковой передачи (секунды)",
-      "placeholder": "600"
+      "placeholder": "0"
     },
     },
     "streamingFirstByte": {
     "streamingFirstByte": {
       "core": "true",
       "core": "true",
-      "desc": "Тайм-аут первого байта потоковой передачи, диапазон 1-120 секунд, значение по умолчанию 30 секунд",
+      "desc": "Тайм-аут первого байта потоковой передачи, диапазон 1-180 секунд, 0 для отключения (по умолчанию: без ограничений)",
       "label": "Тайм-аут первого байта потока (секунды)",
       "label": "Тайм-аут первого байта потока (секунды)",
-      "placeholder": "30"
+      "placeholder": "0"
     },
     },
     "streamingIdle": {
     "streamingIdle": {
       "core": "true",
       "core": "true",
-      "desc": "Тайм-аут простоя потоковой передачи, диапазон 60-600 секунд, введите 0 для отключения (предотвращение застревания)",
+      "desc": "Тайм-аут простоя потоковой передачи, диапазон 60-600 секунд, 0 для отключения (по умолчанию: без ограничений)",
       "label": "Тайм-аут простоя потока (секунды)",
       "label": "Тайм-аут простоя потока (секунды)",
-      "placeholder": "60"
+      "placeholder": "0"
     },
     },
     "summary": "1 байт: {streaming}с | поток: {idle}с | не поток: {nonStreaming}с",
     "summary": "1 байт: {streaming}с | поток: {idle}с | не поток: {nonStreaming}с",
     "title": "Конфигурация тайм-аута"
     "title": "Конфигурация тайм-аута"

+ 3 - 1
messages/ru/settings/providers/form/success.json

@@ -1,4 +1,6 @@
 {
 {
   "created": "Провайдер успешно добавлен",
   "created": "Провайдер успешно добавлен",
-  "createdDesc": "Провайдер «{name}» добавлен"
+  "createdDesc": "Провайдер «{name}» добавлен",
+  "updated": "Провайдер успешно обновлен",
+  "updatedDesc": "Провайдер «{name}» обновлен"
 }
 }

+ 1 - 1
messages/ru/settings/providers/form/url.json

@@ -1,4 +1,4 @@
 {
 {
-  "label": "Адрес API *",
+  "label": "Адрес API",
   "placeholder": "например: https://open.bigmodel.cn/api/anthropic"
   "placeholder": "например: https://open.bigmodel.cn/api/anthropic"
 }
 }

+ 12 - 1
messages/ru/settings/providers/form/urlPreview.json

@@ -5,5 +5,16 @@
   "duplicatePath": "Обнаружен дублирующийся путь",
   "duplicatePath": "Обнаружен дублирующийся путь",
   "invalidUrl": "Неверный формат URL",
   "invalidUrl": "Неверный формат URL",
   "invalidUrlDesc": "Пожалуйста, введите действительный HTTP/HTTPS адрес",
   "invalidUrlDesc": "Пожалуйста, введите действительный HTTP/HTTPS адрес",
-  "title": "Предварительный просмотр URL"
+  "title": "Предварительный просмотр URL",
+  "endpoints": {
+    "claudeMessages": "Claude Messages",
+    "claudeCountTokens": "Claude Count Tokens",
+    "codexResponses": "Codex Responses",
+    "openaiChatCompletions": "OpenAI Chat Completions",
+    "openaiModels": "OpenAI Models",
+    "geminiGenerateContent": "Gemini Generate Content",
+    "geminiStreamContent": "Gemini Stream Content",
+    "geminiCliGenerate": "Gemini CLI Generate",
+    "geminiCliStream": "Gemini CLI Stream"
+  }
 }
 }

+ 57 - 1
messages/ru/settings/providers/strings.json

@@ -43,5 +43,61 @@
   "toggleSuccessDesc": "Статус поставщика \"{name}\" обновлен",
   "toggleSuccessDesc": "Статус поставщика \"{name}\" обновлен",
   "updateFailed": "Не удалось обновить поставщика",
   "updateFailed": "Не удалось обновить поставщика",
   "viewKey": "Просмотреть полный API ключ",
   "viewKey": "Просмотреть полный API ключ",
-  "viewKeyDesc": "Пожалуйста, храните бережно и не раскрывайте другим"
+  "viewKeyDesc": "Пожалуйста, храните бережно и не раскрывайте другим",
+  "viewMode": "Режим просмотра",
+  "viewModeList": "Список",
+  "viewModeVendor": "Вендор",
+  "endpoints": "Эндпоинты",
+  "manualProbe": "Проверка",
+  "addEndpoint": "Добавить эндпоинт",
+  "lastProbed": "Последняя проверка",
+  "latency": "Задержка",
+  "status": "Статус",
+  "vendorKeys": "API ключи",
+  "addVendorKey": "Добавить API ключ",
+  "addVendorKeyDesc": "Добавьте API ключ для этого вендора (URL API вводить не нужно).",
+  "addVendorKeySuccess": "API ключ добавлен",
+  "addVendorKeyFailed": "Не удалось добавить API ключ",
+  "probeSuccess": "Проверка успешна",
+  "probeFailed": "Проверка не удалась",
+  "manualCircuitOpen": "Открыть цепь вручную",
+  "manualCircuitClose": "Закрыть цепь",
+  "circuitStatus": "Состояние цепи",
+  "vendorTypeCircuit": "Цепь по типу провайдера",
+  "vendorFallbackName": "Поставщик #{id}",
+  "orphanedProviders": "Неизвестный поставщик",
+  "vendorTypeCircuitUpdated": "Цепь типа поставщика обновлена",
+  "noEndpoints": "Эндпоинты не настроены",
+  "noEndpointsDesc": "Добавьте эндпоинт, чтобы включить маршрутизацию с отказоустойчивостью",
+  "columnUrl": "URL",
+  "columnActions": "Действия",
+  "confirmDeleteEndpoint": "Вы уверены, что хотите удалить этот эндпоинт?",
+  "endpointAddSuccess": "Эндпоинт добавлен",
+  "endpointAddFailed": "Не удалось добавить эндпоинт",
+  "endpointUpdateSuccess": "Эндпоинт обновлён",
+  "endpointUpdateFailed": "Не удалось обновить эндпоинт",
+  "endpointDeleteSuccess": "Эндпоинт удалён",
+  "endpointDeleteFailed": "Не удалось удалить эндпоинт",
+  "probeOk": "OK",
+  "probeError": "Ошибка",
+  "addEndpointDesc": "Добавьте новый эндпоинт {providerType} для этого вендора.",
+  "endpointUrlLabel": "URL",
+  "endpointUrlPlaceholder": "https://api.example.com/v1",
+  "endpointLabelOptional": "Метка (необязательно)",
+  "endpointLabelPlaceholder": "Продакшн",
+  "editEndpoint": "Редактировать эндпоинт",
+  "editVendor": "Редактировать вендора",
+  "vendorName": "Название вендора",
+  "vendorWebsite": "URL сайта",
+  "vendorWebsitePlaceholder": "https://example.com",
+  "vendorOfficial": "Официальный",
+  "deleteVendor": "Удалить вендора",
+  "deleteVendorConfirmTitle": "Удалить вендора?",
+  "deleteVendorDoubleConfirmTitle": "Подтвердить удаление?",
+  "deleteVendorConfirmDesc": "Это навсегда удалит вендора \"{name}\" и все связанные с ним API ключи и эндпоинты.",
+  "deleteVendorDoubleConfirmDesc": "Это действие необратимо. Подтвердите, что хотите удалить всё, связанное с \"{name}\".",
+  "vendorUpdateSuccess": "Вендор обновлён",
+  "vendorUpdateFailed": "Не удалось обновить вендора",
+  "vendorDeleteSuccess": "Вендор удалён",
+  "vendorDeleteFailed": "Не удалось удалить вендора"
 }
 }

+ 1 - 0
messages/zh-CN/common.json

@@ -4,6 +4,7 @@
   "delete": "删除",
   "delete": "删除",
   "confirm": "确认",
   "confirm": "确认",
   "edit": "编辑",
   "edit": "编辑",
+  "status": "状态",
   "create": "创建",
   "create": "创建",
   "close": "关闭",
   "close": "关闭",
   "back": "返回",
   "back": "返回",

+ 13 - 3
messages/zh-CN/customs.json

@@ -26,16 +26,26 @@
     "viewRelease": "查看发布"
     "viewRelease": "查看发布"
   },
   },
   "metrics": {
   "metrics": {
-    "concurrent": "并发数",
+    "concurrent": "活跃 Session 数",
     "todayRequests": "今日请求",
     "todayRequests": "今日请求",
     "todayCost": "今日消费",
     "todayCost": "今日消费",
     "avgResponse": "平均响应时间",
     "avgResponse": "平均响应时间",
-    "viewDetails": "查看详情"
+    "viewDetails": "查看详情",
+    "rpm": "RPM",
+    "vsYesterday": "较昨日同期"
   },
   },
   "activeSessions": {
   "activeSessions": {
     "title": "活跃 Session",
     "title": "活跃 Session",
     "summary": "{count} 个 Session,{minutes} 分钟内",
     "summary": "{count} 个 Session,{minutes} 分钟内",
     "empty": "暂无活跃 Session",
     "empty": "暂无活跃 Session",
-    "viewAll": "查看全部"
+    "viewAll": "查看全部",
+    "loading": "加载中...",
+    "unknownUser": "未知",
+    "status": {
+      "inProgressTooltip": "会话正在处理活跃请求",
+      "initializingTooltip": "会话正在初始化首个请求",
+      "idleTooltip": "会话空闲,无活跃请求",
+      "errorTooltip": "会话处理过程中发生错误"
+    }
   }
   }
 }
 }

+ 222 - 11
messages/zh-CN/dashboard.json

@@ -21,7 +21,8 @@
     "usersQuotas": "用户限额统计",
     "usersQuotas": "用户限额统计",
     "keysQuotas": "密钥限额统计",
     "keysQuotas": "密钥限额统计",
     "providersQuotas": "供应商限额统计",
     "providersQuotas": "供应商限额统计",
-    "filterCriteria": "筛选条件"
+    "filterCriteria": "筛选条件",
+    "filterCriteriaDescription": "按时间、用户、供应商等条件缩小日志范围"
   },
   },
   "description": {
   "description": {
     "viewApiCallLogs": "查看 API 调用日志和使用统计",
     "viewApiCallLogs": "查看 API 调用日志和使用统计",
@@ -93,7 +94,28 @@
       "export": "导出",
       "export": "导出",
       "exporting": "导出中...",
       "exporting": "导出中...",
       "exportSuccess": "导出成功",
       "exportSuccess": "导出成功",
-      "exportError": "导出失败"
+      "exportError": "导出失败",
+      "quickFilters": {
+        "today": "今天",
+        "thisWeek": "本周",
+        "errorsOnly": "仅错误",
+        "showRetries": "有重试"
+      },
+      "activeFilters": {
+        "title": "已激活筛选",
+        "remove": "移除筛选",
+        "clearAll": "清除全部"
+      },
+      "groups": {
+        "time": "时间范围",
+        "timeDesc": "按日期和时间筛选",
+        "identity": "身份信息",
+        "identityDesc": "按用户和密钥筛选",
+        "request": "请求参数",
+        "requestDesc": "按供应商、模型、端点筛选",
+        "status": "状态信息",
+        "statusDesc": "按状态码和重试次数筛选"
+      }
     },
     },
     "columns": {
     "columns": {
       "time": "时间",
       "time": "时间",
@@ -116,9 +138,7 @@
     },
     },
     "stats": {
     "stats": {
       "title": "统计汇总",
       "title": "统计汇总",
-      "description": "点击展开查看当前筛选条件下的聚合统计",
-      "expand": "展开",
-      "collapse": "收起",
+      "description": "当前筛选条件下的聚合统计",
       "totalRequests": "总请求数",
       "totalRequests": "总请求数",
       "totalAmount": "总消耗金额",
       "totalAmount": "总消耗金额",
       "totalTokens": "总 Token 数",
       "totalTokens": "总 Token 数",
@@ -144,7 +164,8 @@
       "noMoreData": "已加载全部记录",
       "noMoreData": "已加载全部记录",
       "scrollToTop": "回到顶部",
       "scrollToTop": "回到顶部",
       "hideProviderColumn": "隐藏供应商列",
       "hideProviderColumn": "隐藏供应商列",
-      "showProviderColumn": "显示供应商列"
+      "showProviderColumn": "显示供应商列",
+      "columnVisibility": "显示/隐藏列"
     },
     },
     "actions": {
     "actions": {
       "refresh": "刷新",
       "refresh": "刷新",
@@ -161,12 +182,27 @@
     },
     },
     "details": {
     "details": {
       "title": "请求详情",
       "title": "请求详情",
-      "statusTitle": "请求详情 - 状态码 {status}",
+      "statusTitle": "状态: {status}",
       "inProgress": "请求中",
       "inProgress": "请求中",
       "unknown": "未知",
       "unknown": "未知",
       "success": "请求成功完成",
       "success": "请求成功完成",
       "error": "请求失败,以下是详细的错误信息和供应商决策链",
       "error": "请求失败,以下是详细的错误信息和供应商决策链",
       "processing": "请求正在进行中,尚未完成",
       "processing": "请求正在进行中,尚未完成",
+      "tabs": {
+        "summary": "概览",
+        "logicTrace": "决策链",
+        "performance": "性能",
+        "metadata": "元数据"
+      },
+      "summary": {
+        "keyMetrics": "关键指标",
+        "totalCost": "总费用",
+        "totalTokens": "总令牌数",
+        "duration": "耗时",
+        "outputRate": "输出速率",
+        "viewFullError": "查看完整错误",
+        "viewSession": "查看会话"
+      },
       "specialSettings": {
       "specialSettings": {
         "title": "特殊设置"
         "title": "特殊设置"
       },
       },
@@ -224,13 +260,72 @@
         "circuitOpen": "熔断器打开"
         "circuitOpen": "熔断器打开"
       },
       },
       "billingDetails": {
       "billingDetails": {
-        "title": "计费详情"
+        "title": "计费详情",
+        "input": "输入",
+        "output": "输出",
+        "cacheWrite5m": "缓存写入 (5m)",
+        "cacheWrite1h": "缓存写入 (1h)",
+        "cacheRead": "缓存读取",
+        "cacheTtl": "缓存 TTL",
+        "multiplier": "供应商倍率",
+        "totalCost": "总费用",
+        "context1m": "1M 上下文",
+        "context1mPricing": "输入 2x >200k, 输出 1.5x >200k"
       },
       },
       "performance": {
       "performance": {
         "title": "性能数据",
         "title": "性能数据",
         "ttfb": "首字节时间(TTFB)",
         "ttfb": "首字节时间(TTFB)",
         "duration": "总耗时",
         "duration": "总耗时",
         "outputRate": "输出速率"
         "outputRate": "输出速率"
+      },
+      "performanceTab": {
+        "noPerformanceData": "暂无性能数据",
+        "ttfbGauge": "首字节时间",
+        "outputRateGauge": "输出速率",
+        "latencyBreakdown": "延迟分解",
+        "generationTime": "生成时间",
+        "assessment": {
+          "excellent": "优秀",
+          "good": "良好",
+          "warning": "警告",
+          "poor": "较差"
+        },
+        "thresholds": {
+          "ttfbGood": "TTFB < 1s",
+          "ttfbWarning": "TTFB 1-2s",
+          "ttfbPoor": "TTFB > 3s"
+        }
+      },
+      "metadata": {
+        "noMetadata": "暂无元数据",
+        "sessionInfo": "会话信息",
+        "clientInfo": "客户端信息",
+        "billingInfo": "计费信息",
+        "technicalTimeline": "技术时间线",
+        "copyTimeline": "复制时间线"
+      },
+      "logicTrace": {
+        "title": "决策链",
+        "noDecisionData": "暂无决策数据",
+        "providersCount": "{count} 个供应商",
+        "healthyCount": "{count} 个健康",
+        "initialSelection": "初始选择",
+        "healthCheck": "健康检查",
+        "prioritySelection": "优先级选择",
+        "attemptProvider": "尝试: {provider}",
+        "retryAttempt": "重试 #{number}",
+        "sessionReuse": "会话复用",
+        "sessionReuseDesc": "从会话缓存复用供应商",
+        "sessionReuseTitle": "会话绑定",
+        "sessionReuseSelection": "会话复用选择",
+        "sessionReuseSelectionDesc": "从会话缓存中选择供应商",
+        "sessionInfo": "会话信息",
+        "sessionIdLabel": "会话 ID",
+        "requestSequence": "请求序号",
+        "sessionAge": "会话年龄",
+        "reusedProvider": "复用的供应商",
+        "executeRequest": "执行请求",
+        "cacheOptimizationHint": "会话复用通过在同一对话中保持供应商亲和性来优化性能,减少选择开销并提高缓存命中率。"
       }
       }
     },
     },
     "providerChain": {
     "providerChain": {
@@ -1039,6 +1134,17 @@
     "title": "供应商可用性监控",
     "title": "供应商可用性监控",
     "description": "实时监控供应商的可用性状态和性能指标",
     "description": "实时监控供应商的可用性状态和性能指标",
     "nav": "可用性监控",
     "nav": "可用性监控",
+    "tabs": {
+      "provider": "供应商可用性",
+      "endpoint": "端点健康"
+    },
+    "overview": {
+      "systemAvailability": "系统可用性",
+      "avgLatency": "平均延迟",
+      "errorRate": "错误率",
+      "activeProbes": "活跃探测",
+      "load": "负载"
+    },
     "status": {
     "status": {
       "green": "正常",
       "green": "正常",
       "red": "异常",
       "red": "异常",
@@ -1062,6 +1168,11 @@
     },
     },
     "timeRange": {
     "timeRange": {
       "label": "时间范围",
       "label": "时间范围",
+      "15min": "15 分钟",
+      "1h": "1 小时",
+      "6h": "6 小时",
+      "24h": "24 小时",
+      "7d": "7 天",
       "last15min": "最近 15 分钟",
       "last15min": "最近 15 分钟",
       "last1h": "最近 1 小时",
       "last1h": "最近 1 小时",
       "last6h": "最近 6 小时",
       "last6h": "最近 6 小时",
@@ -1112,7 +1223,13 @@
       "autoRefresh": "自动刷新",
       "autoRefresh": "自动刷新",
       "stopAutoRefresh": "停止自动刷新",
       "stopAutoRefresh": "停止自动刷新",
       "viewDetails": "查看详情",
       "viewDetails": "查看详情",
-      "testProvider": "测试供应商"
+      "testProvider": "测试供应商",
+      "retry": "重试",
+      "probeNow": "立即探测",
+      "probing": "探测中...",
+      "probeAll": "探测全部",
+      "probeSuccess": "探测成功",
+      "probeFailed": "探测失败"
     },
     },
     "states": {
     "states": {
       "loading": "加载中...",
       "loading": "加载中...",
@@ -1142,6 +1259,84 @@
       "noData": "无数据",
       "noData": "无数据",
       "noRequests": "无请求"
       "noRequests": "无请求"
     },
     },
+    "probeHistory": {
+      "title": "端点探测历史",
+      "description": "查看探测日志并手动触发特定端点的探测",
+      "selectVendor": "选择供应商",
+      "selectType": "选择供应商类型",
+      "selectEndpoint": "选择端点",
+      "noEndpoints": "未找到端点",
+      "probeNow": "立即探测",
+      "probing": "探测中...",
+      "columns": {
+        "time": "时间",
+        "method": "方法",
+        "status": "状态码",
+        "latency": "延迟",
+        "error": "错误信息"
+      },
+      "success": "成功",
+      "manual": "手动探测",
+      "auto": "自动探测",
+      "probeSuccess": "探测成功",
+      "probeFailed": "探测失败"
+    },
+    "laneChart": {
+      "title": "供应商可用性时间线",
+      "noData": "暂无数据",
+      "requests": "{count} 个请求",
+      "availability": "可用性 {value}%",
+      "noRequests": "无请求",
+      "denseData": "密集",
+      "sparseData": "稀疏",
+      "latency": "延迟"
+    },
+    "latencyChart": {
+      "title": "延迟分布",
+      "p50": "P50",
+      "p95": "P95",
+      "p99": "P99",
+      "noData": "暂无延迟数据"
+    },
+    "latencyCurve": {
+      "title": "延迟趋势",
+      "noData": "暂无延迟数据",
+      "avg": "平均",
+      "min": "最小",
+      "max": "最大",
+      "latency": "延迟"
+    },
+    "terminal": {
+      "title": "探测日志",
+      "live": "实时",
+      "download": "下载日志",
+      "noLogs": "暂无探测日志",
+      "manual": "手动",
+      "auto": "自动",
+      "filterPlaceholder": "筛选日志..."
+    },
+    "probeGrid": {
+      "title": "端点状态",
+      "noEndpoints": "未配置端点",
+      "lastProbe": "最后探测",
+      "status": {
+        "unknown": "未知",
+        "healthy": "健康",
+        "unhealthy": "异常"
+      }
+    },
+    "endpoint": {
+      "selectVendor": "选择供应商",
+      "selectType": "选择类型"
+    },
+    "confidence": {
+      "low": "低",
+      "medium": "中",
+      "high": "高",
+      "lowTooltip": "请求数少于 {count},数据可能不具代表性。",
+      "mediumTooltip": "请求量适中,数据较为可靠。",
+      "highTooltip": "请求量充足,数据可靠。"
+    },
     "toast": {
     "toast": {
       "refreshSuccess": "可用性数据已刷新",
       "refreshSuccess": "可用性数据已刷新",
       "refreshFailed": "刷新失败,请重试"
       "refreshFailed": "刷新失败,请重试"
@@ -1204,8 +1399,23 @@
       "columns": {
       "columns": {
         "model": "模型",
         "model": "模型",
         "calls": "调用次数",
         "calls": "调用次数",
+        "tokens": "Token数",
         "cost": "消费金额"
         "cost": "消费金额"
       },
       },
+      "modal": {
+        "requests": "请求",
+        "totalTokens": "总Token",
+        "cost": "费用",
+        "inputTokens": "输入Token",
+        "outputTokens": "输出Token",
+        "cacheWrite": "缓存写入",
+        "cacheRead": "缓存读取",
+        "cacheHitRate": "缓存命中率",
+        "cacheTokens": "缓存Token",
+        "performanceHigh": "高",
+        "performanceMedium": "中",
+        "performanceLow": "低"
+      },
       "noData": "今日暂无使用记录",
       "noData": "今日暂无使用记录",
       "totalCalls": "总调用",
       "totalCalls": "总调用",
       "totalCost": "总消费"
       "totalCost": "总消费"
@@ -1351,7 +1561,7 @@
           "limitDaily": "每日限额 (USD)",
           "limitDaily": "每日限额 (USD)",
           "limitWeekly": "周限额 (USD)",
           "limitWeekly": "周限额 (USD)",
           "limitMonthly": "月限额 (USD)",
           "limitMonthly": "月限额 (USD)",
-          "canLoginWebUi": "允许登录 Web UI",
+          "canLoginWebUi": "独立个人用量页面",
           "keyEnabled": "Key 启用状态"
           "keyEnabled": "Key 启用状态"
         },
         },
         "placeholders": {
         "placeholders": {
@@ -1514,7 +1724,8 @@
       "clickToEnableUser": "点击启用用户",
       "clickToEnableUser": "点击启用用户",
       "operationFailed": "操作失败",
       "operationFailed": "操作失败",
       "deleteFailed": "删除失败",
       "deleteFailed": "删除失败",
-      "deleteSuccess": "删除成功"
+      "deleteSuccess": "删除成功",
+      "daysLeft": "{days, plural, =0 {今天到期} =1 {剩余1天} other {剩余#天}}"
     },
     },
     "userEditSection": {
     "userEditSection": {
       "sections": {
       "sections": {

+ 6 - 0
messages/zh-CN/errors.json

@@ -73,6 +73,12 @@
   "UPDATE_KEY_FAILED": "更新密钥失败,请稍后重试",
   "UPDATE_KEY_FAILED": "更新密钥失败,请稍后重试",
   "DELETE_KEY_FAILED": "删除密钥失败,请稍后重试",
   "DELETE_KEY_FAILED": "删除密钥失败,请稍后重试",
   "CANNOT_DISABLE_LAST_KEY": "无法禁用最后一个可用密钥,用户至少需要保留一个启用的密钥",
   "CANNOT_DISABLE_LAST_KEY": "无法禁用最后一个可用密钥,用户至少需要保留一个启用的密钥",
+  "KEY_LIMIT_5H_EXCEEDS_USER_LIMIT": "Key的5小时消费上限({keyLimit})不能超过用户限额({userLimit})",
+  "KEY_LIMIT_DAILY_EXCEEDS_USER_LIMIT": "Key的日消费上限({keyLimit})不能超过用户限额({userLimit})",
+  "KEY_LIMIT_WEEKLY_EXCEEDS_USER_LIMIT": "Key的周消费上限({keyLimit})不能超过用户限额({userLimit})",
+  "KEY_LIMIT_MONTHLY_EXCEEDS_USER_LIMIT": "Key的月消费上限({keyLimit})不能超过用户限额({userLimit})",
+  "KEY_LIMIT_TOTAL_EXCEEDS_USER_LIMIT": "Key的总消费上限({keyLimit})不能超过用户限额({userLimit})",
+  "KEY_LIMIT_CONCURRENT_EXCEEDS_USER_LIMIT": "Key的并发Session上限({keyLimit})不能超过用户限额({userLimit})",
   "NO_DEFAULT_GROUP_PERMISSION": "无权使用 default 分组,您当前没有 default 分组的 Key",
   "NO_DEFAULT_GROUP_PERMISSION": "无权使用 default 分组,您当前没有 default 分组的 Key",
   "NO_GROUP_PERMISSION": "无权使用以下分组: {groups}"
   "NO_GROUP_PERMISSION": "无权使用以下分组: {groups}"
 }
 }

+ 2 - 2
messages/zh-CN/myUsage.json

@@ -78,7 +78,7 @@
     "inheritedFromUser": "继承自用户"
     "inheritedFromUser": "继承自用户"
   },
   },
   "stats": {
   "stats": {
-    "title": "统计摘要",
+    "title": "密钥统计",
     "autoRefresh": "每{seconds}秒自动刷新",
     "autoRefresh": "每{seconds}秒自动刷新",
     "totalRequests": "总请求数",
     "totalRequests": "总请求数",
     "totalCost": "总费用",
     "totalCost": "总费用",
@@ -116,7 +116,7 @@
     "noRestrictions": "无限制"
     "noRestrictions": "无限制"
   },
   },
   "quotaCollapsible": {
   "quotaCollapsible": {
-    "title": "配额使用",
+    "title": "用户配额使用",
     "daily": "日",
     "daily": "日",
     "monthly": "月",
     "monthly": "月",
     "total": "总计"
     "total": "总计"

+ 43 - 0
messages/zh-CN/provider-chain.json

@@ -39,6 +39,48 @@
     "http2Fallback": "HTTP/2 回退",
     "http2Fallback": "HTTP/2 回退",
     "clientError": "客户端错误"
     "clientError": "客户端错误"
   },
   },
+  "reasons": {
+    "request_success": "成功",
+    "retry_success": "重试成功",
+    "retry_failed": "重试失败",
+    "system_error": "系统错误",
+    "client_error_non_retryable": "客户端错误",
+    "concurrent_limit_failed": "并发限制",
+    "http2_fallback": "HTTP/2 回退",
+    "session_reuse": "会话复用",
+    "initial_selection": "首次选择"
+  },
+  "filterReasons": {
+    "rate_limited": "速率限制",
+    "circuit_open": "熔断器打开",
+    "disabled": "已禁用",
+    "model_not_supported": "不支持该模型",
+    "group_mismatch": "分组不匹配",
+    "health_check_failed": "健康检查失败"
+  },
+  "details": {
+    "selectionMethod": "选择方式",
+    "attemptNumber": "尝试次数",
+    "endpoint": "端点",
+    "config": "配置",
+    "priority": "优先级",
+    "weight": "权重",
+    "costMultiplier": "成本倍数",
+    "groupTag": "分组标签",
+    "circuitBreaker": "熔断器",
+    "circuitDisabled": "已禁用",
+    "failures": "次失败",
+    "modelRedirect": "模型重定向",
+    "error": "错误",
+    "errorDetails": "错误详情",
+    "decisionContext": "决策上下文",
+    "beforeHealthCheck": "健康检查前",
+    "afterHealthCheck": "健康检查后",
+    "filteredProviders": "被过滤供应商",
+    "priorityLevels": "优先级层级",
+    "candidates": "候选供应商"
+  },
+  "technicalTimeline": "技术时间线",
   "timeline": {
   "timeline": {
     "sessionReuse": "会话复用",
     "sessionReuse": "会话复用",
     "sessionReuseSelection": "会话复用选择供应商",
     "sessionReuseSelection": "会话复用选择供应商",
@@ -87,6 +129,7 @@
     "status": "状态",
     "status": "状态",
     "alreadyBroken": "已触发熔断",
     "alreadyBroken": "已触发熔断",
     "circuitTriggered": "警告:已触发熔断",
     "circuitTriggered": "警告:已触发熔断",
+    "circuitDisabled": "熔断器已禁用",
     "errorDetails": "错误详情",
     "errorDetails": "错误详情",
     "systemError": "网络/系统错误",
     "systemError": "网络/系统错误",
     "systemErrorFailed": "网络/系统错误(第 {attempt} 次尝试)",
     "systemErrorFailed": "网络/系统错误(第 {attempt} 次尝试)",

+ 7 - 1
messages/zh-CN/settings/clientVersions.json

@@ -46,6 +46,12 @@
     "noUsers": "暂无用户数据",
     "noUsers": "暂无用户数据",
     "latest": "最新",
     "latest": "最新",
     "needsUpgrade": "需升级",
     "needsUpgrade": "需升级",
-    "unknown": "未知"
+    "unknown": "未知",
+    "stats": {
+      "clientTypes": "客户端类型",
+      "totalUsers": "用户总数",
+      "withGA": "有 GA 版本",
+      "coverage": "GA 覆盖率"
+    }
   }
   }
 }
 }

+ 1 - 0
messages/zh-CN/settings/data.json

@@ -4,6 +4,7 @@
   "status": {
   "status": {
     "loading": "加载中...",
     "loading": "加载中...",
     "error": "获取数据库状态失败",
     "error": "获取数据库状态失败",
+    "connectionUnavailable": "数据库连接不可用,请检查数据库服务状态",
     "retry": "重试",
     "retry": "重试",
     "connected": "数据库连接正常",
     "connected": "数据库连接正常",
     "unavailable": "数据库不可用",
     "unavailable": "数据库不可用",

+ 5 - 0
messages/zh-CN/settings/index.ts

@@ -13,6 +13,7 @@ import sensitiveWords from "./sensitiveWords.json";
 import strings from "./strings.json";
 import strings from "./strings.json";
 
 
 import providersAutoSort from "./providers/autoSort.json";
 import providersAutoSort from "./providers/autoSort.json";
+import providersBatchEdit from "./providers/batchEdit.json";
 import providersFilter from "./providers/filter.json";
 import providersFilter from "./providers/filter.json";
 import providersGuide from "./providers/guide.json";
 import providersGuide from "./providers/guide.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
@@ -37,6 +38,7 @@ import providersFormModelSelect from "./providers/form/modelSelect.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
+import providersFormQuickPaste from "./providers/form/quickPaste.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormSuccess from "./providers/form/success.json";
 import providersFormSuccess from "./providers/form/success.json";
@@ -47,6 +49,7 @@ import providersFormWebsiteUrl from "./providers/form/websiteUrl.json";
 
 
 const providersForm = {
 const providersForm = {
   ...providersFormStrings,
   ...providersFormStrings,
+  ...providersFormCommon,
   apiTest: providersFormApiTest,
   apiTest: providersFormApiTest,
   buttons: providersFormButtons,
   buttons: providersFormButtons,
   common: providersFormCommon,
   common: providersFormCommon,
@@ -60,6 +63,7 @@ const providersForm = {
   name: providersFormName,
   name: providersFormName,
   providerTypes: providersFormProviderTypes,
   providerTypes: providersFormProviderTypes,
   proxyTest: providersFormProxyTest,
   proxyTest: providersFormProxyTest,
+  quickPaste: providersFormQuickPaste,
   sections: providersFormSections,
   sections: providersFormSections,
   success: providersFormSuccess,
   success: providersFormSuccess,
   title: providersFormTitle,
   title: providersFormTitle,
@@ -71,6 +75,7 @@ const providersForm = {
 const providers = {
 const providers = {
   ...providersStrings,
   ...providersStrings,
   autoSort: providersAutoSort,
   autoSort: providersAutoSort,
+  batchEdit: providersBatchEdit,
   filter: providersFilter,
   filter: providersFilter,
   form: providersForm,
   form: providersForm,
   guide: providersGuide,
   guide: providersGuide,

+ 2 - 0
messages/zh-CN/settings/notifications.json

@@ -5,6 +5,8 @@
     "title": "通知总开关",
     "title": "通知总开关",
     "description": "启用或禁用所有消息推送功能",
     "description": "启用或禁用所有消息推送功能",
     "enable": "启用消息推送",
     "enable": "启用消息推送",
+    "on": "已开启",
+    "off": "已关闭",
     "legacyModeTitle": "兼容模式",
     "legacyModeTitle": "兼容模式",
     "legacyModeDescription": "当前使用旧版单 URL 推送配置。创建推送目标后将自动切换到多目标模式。"
     "legacyModeDescription": "当前使用旧版单 URL 推送配置。创建推送目标后将自动切换到多目标模式。"
   },
   },

+ 43 - 0
messages/zh-CN/settings/providers/batchEdit.json

@@ -0,0 +1,43 @@
+{
+  "enterMode": "批量编辑",
+  "exitMode": "退出",
+  "selectAll": "全选",
+  "invertSelection": "反选",
+  "selectedCount": "已选 {count} 项",
+  "editSelected": "编辑选中项",
+  "actions": {
+    "edit": "编辑",
+    "delete": "删除",
+    "resetCircuit": "重置熔断"
+  },
+  "dialog": {
+    "editTitle": "批量编辑供应商",
+    "editDesc": "修改将应用于 {count} 个供应商",
+    "deleteTitle": "删除供应商",
+    "deleteDesc": "确定永久删除 {count} 个供应商?",
+    "resetCircuitTitle": "重置熔断器",
+    "resetCircuitDesc": "确定重置 {count} 个供应商的熔断器?",
+    "next": "下一步",
+    "noFieldEnabled": "请至少启用一个要更新的字段"
+  },
+  "fields": {
+    "isEnabled": "状态",
+    "priority": "优先级",
+    "weight": "权重",
+    "costMultiplier": "价格倍率",
+    "groupTag": "分组标签"
+  },
+  "confirm": {
+    "title": "确认操作",
+    "cancel": "取消",
+    "confirm": "确认",
+    "goBack": "返回",
+    "processing": "处理中..."
+  },
+  "toast": {
+    "updated": "已更新 {count} 个供应商",
+    "deleted": "已删除 {count} 个供应商",
+    "circuitReset": "已重置 {count} 个熔断器",
+    "failed": "操作失败: {error}"
+  }
+}

+ 8 - 1
messages/zh-CN/settings/providers/form/common.json

@@ -1,3 +1,10 @@
 {
 {
-  "core": "核心"
+  "core": "核心",
+  "tabs": {
+    "basic": "基础信息",
+    "routing": "路由",
+    "limits": "限制",
+    "network": "网络",
+    "testing": "测试"
+  }
 }
 }

+ 1 - 0
messages/zh-CN/settings/providers/form/key.json

@@ -1,5 +1,6 @@
 {
 {
   "label": "API 密钥",
   "label": "API 密钥",
+  "labelEdit": "API 密钥(留空不更改)",
   "leaveEmpty": "(留空不更改)",
   "leaveEmpty": "(留空不更改)",
   "placeholder": "输入 API 密钥",
   "placeholder": "输入 API 密钥",
   "leaveEmptyDesc": "留空则不更改密钥",
   "leaveEmptyDesc": "留空则不更改密钥",

+ 1 - 1
messages/zh-CN/settings/providers/form/name.json

@@ -1,4 +1,4 @@
 {
 {
-  "label": "服务商名称 *",
+  "label": "服务商名称",
   "placeholder": "例如: 智谱"
   "placeholder": "例如: 智谱"
 }
 }

+ 15 - 0
messages/zh-CN/settings/providers/form/quickPaste.json

@@ -0,0 +1,15 @@
+{
+  "button": "快速粘贴",
+  "title": "快速粘贴",
+  "description": "粘贴包含供应商信息的文本(URL、API 密钥等),系统将自动提取。",
+  "placeholder": "在此粘贴供应商配置文本...",
+  "preview": "检测到的信息",
+  "type": "类型",
+  "name": "名称",
+  "url": "URL",
+  "key": "API 密钥",
+  "notFound": "未检测到",
+  "parseError": "无法从文本中解析供应商信息",
+  "cancel": "取消",
+  "confirm": "应用"
+}

+ 30 - 9
messages/zh-CN/settings/providers/form/sections.json

@@ -1,4 +1,18 @@
 {
 {
+  "basic": {
+    "identity": {
+      "title": "供应商身份",
+      "desc": "设置唯一名称以标识此供应商"
+    },
+    "endpoint": {
+      "title": "API 端点",
+      "desc": "配置 API 请求的基础 URL"
+    },
+    "auth": {
+      "title": "身份认证",
+      "desc": "提供用于认证的 API 密钥"
+    }
+  },
   "routing": {
   "routing": {
     "title": "路由配置",
     "title": "路由配置",
     "summary": {
     "summary": {
@@ -55,8 +69,8 @@
       },
       },
       "group": {
       "group": {
         "label": "供应商分组",
         "label": "供应商分组",
-        "placeholder": "输入分组标签",
-        "desc": "供应商分组标签(支持多个,逗号分隔)。只有用户的 providerGroup 与此值匹配时,该用户才能使用此供应商。留空=对所有用户开放"
+        "placeholder": "例如 premium, economy",
+        "desc": "分组标签。从列表选择或输入新名称后按 Enter 创建(最多50字符)。只有 providerGroup 匹配的用户才能使用此供应商。"
       }
       }
     },
     },
     "cacheTtl": {
     "cacheTtl": {
@@ -123,6 +137,7 @@
   },
   },
   "rateLimit": {
   "rateLimit": {
     "title": "限流配置",
     "title": "限流配置",
+    "desc": "配置不同时间窗口的消费限制以控制成本",
     "summary": {
     "summary": {
       "fiveHour": "5h: {amount}",
       "fiveHour": "5h: {amount}",
       "daily": "日: {amount} (重置 {resetTime})",
       "daily": "日: {amount} (重置 {resetTime})",
@@ -171,6 +186,11 @@
       "placeholder": "0 表示无限制"
       "placeholder": "0 表示无限制"
     }
     }
   },
   },
+  "limits": {
+    "timeBased": "时间维度限制",
+    "dailyReset": "每日重置设置",
+    "otherLimits": "其他限制"
+  },
   "circuitBreaker": {
   "circuitBreaker": {
     "title": "熔断器配置",
     "title": "熔断器配置",
     "summary": "{failureThreshold} 次失败 / {openDuration} 分钟熔断 / {successThreshold} 次成功恢复 / 每个供应商最多 {maxRetryAttempts} 次尝试",
     "summary": "{failureThreshold} 次失败 / {openDuration} 分钟熔断 / {successThreshold} 次成功恢复 / 每个供应商最多 {maxRetryAttempts} 次尝试",
@@ -178,7 +198,8 @@
     "failureThreshold": {
     "failureThreshold": {
       "label": "失败阈值(次)",
       "label": "失败阈值(次)",
       "placeholder": "5",
       "placeholder": "5",
-      "desc": "连续失败多少次后触发熔断"
+      "desc": "连续失败多少次后触发熔断",
+      "warning": "设为 0 将禁用熔断器 - 请谨慎使用"
     },
     },
     "openDuration": {
     "openDuration": {
       "label": "熔断时长(分钟)",
       "label": "熔断时长(分钟)",
@@ -225,20 +246,20 @@
     "desc": "配置请求超时时间,0 表示禁用超时",
     "desc": "配置请求超时时间,0 表示禁用超时",
     "streamingFirstByte": {
     "streamingFirstByte": {
       "label": "流式首字节超时(秒)",
       "label": "流式首字节超时(秒)",
-      "placeholder": "30",
-      "desc": "流式请求首字节超时,范围 1-120 秒,默认 30 秒",
+      "placeholder": "0",
+      "desc": "流式请求首字节超时,范围 1-180 秒,填 0 禁用(默认不限制)",
       "core": "true"
       "core": "true"
     },
     },
     "streamingIdle": {
     "streamingIdle": {
       "label": "流式静默期超时(秒)",
       "label": "流式静默期超时(秒)",
-      "placeholder": "60",
-      "desc": "流式请求静默期超时,范围 60-600 秒,填 0 禁用(防止中途卡住)",
+      "placeholder": "0",
+      "desc": "流式请求静默期超时,范围 60-600 秒,填 0 禁用(默认不限制)",
       "core": "true"
       "core": "true"
     },
     },
     "nonStreamingTotal": {
     "nonStreamingTotal": {
       "label": "非流式总超时(秒)",
       "label": "非流式总超时(秒)",
-      "placeholder": "600",
-      "desc": "非流式请求总超时,范围 60-1200 秒,默认 600 秒(10 分钟)",
+      "placeholder": "0",
+      "desc": "非流式请求总超时,范围 60-1200 秒,填 0 禁用(默认不限制)",
       "core": "true"
       "core": "true"
     },
     },
     "disableHint": "设为 0 表示禁用该超时(仅用于灰度回退场景,不推荐)"
     "disableHint": "设为 0 表示禁用该超时(仅用于灰度回退场景,不推荐)"

+ 3 - 1
messages/zh-CN/settings/providers/form/success.json

@@ -1,4 +1,6 @@
 {
 {
   "created": "添加服务商成功",
   "created": "添加服务商成功",
-  "createdDesc": "服务商 \"{name}\" 已添加"
+  "createdDesc": "服务商 \"{name}\" 已添加",
+  "updated": "更新服务商成功",
+  "updatedDesc": "服务商 \"{name}\" 已更新"
 }
 }

+ 1 - 1
messages/zh-CN/settings/providers/form/url.json

@@ -1,4 +1,4 @@
 {
 {
-  "label": "API 地址 *",
+  "label": "API 地址",
   "placeholder": "例如: https://open.bigmodel.cn/api/anthropic"
   "placeholder": "例如: https://open.bigmodel.cn/api/anthropic"
 }
 }

+ 12 - 1
messages/zh-CN/settings/providers/form/urlPreview.json

@@ -5,5 +5,16 @@
   "duplicatePath": "检测到重复路径",
   "duplicatePath": "检测到重复路径",
   "copy": "复制",
   "copy": "复制",
   "copySuccess": "已复制 {name} 到剪贴板",
   "copySuccess": "已复制 {name} 到剪贴板",
-  "copyFailed": "复制失败"
+  "copyFailed": "复制失败",
+  "endpoints": {
+    "claudeMessages": "Claude 消息",
+    "claudeCountTokens": "Claude 统计 Token",
+    "codexResponses": "Codex Responses",
+    "openaiChatCompletions": "OpenAI Chat Completions",
+    "openaiModels": "OpenAI Models",
+    "geminiGenerateContent": "Gemini 生成内容",
+    "geminiStreamContent": "Gemini 流式内容",
+    "geminiCliGenerate": "Gemini CLI 生成",
+    "geminiCliStream": "Gemini CLI 流式"
+  }
 }
 }

+ 57 - 1
messages/zh-CN/settings/providers/strings.json

@@ -43,5 +43,61 @@
   "keyLoading": "加载中...",
   "keyLoading": "加载中...",
   "resetCircuit": "熔断器已重置",
   "resetCircuit": "熔断器已重置",
   "resetCircuitDesc": "供应商 \"{name}\" 的熔断状态已解除",
   "resetCircuitDesc": "供应商 \"{name}\" 的熔断状态已解除",
-  "resetCircuitFailed": "重置熔断器失败"
+  "resetCircuitFailed": "重置熔断器失败",
+  "viewMode": "视图模式",
+  "viewModeList": "列表",
+  "viewModeVendor": "服务商",
+  "endpoints": "服务端点",
+  "manualProbe": "测速",
+  "addEndpoint": "添加端点",
+  "lastProbed": "上次测速",
+  "latency": "延迟",
+  "status": "状态",
+  "vendorKeys": "API 密钥",
+  "addVendorKey": "新增密钥",
+  "addVendorKeyDesc": "为该服务商新增一条 API 密钥(无需填写 API 地址)。",
+  "addVendorKeySuccess": "密钥添加成功",
+  "addVendorKeyFailed": "密钥添加失败",
+  "probeSuccess": "测速成功",
+  "probeFailed": "测速失败",
+  "manualCircuitOpen": "手动开启熔断",
+  "manualCircuitClose": "关闭熔断",
+  "circuitStatus": "熔断状态",
+  "vendorTypeCircuit": "服务商类型熔断",
+  "vendorFallbackName": "服务商 #{id}",
+  "orphanedProviders": "未知服务商",
+  "vendorTypeCircuitUpdated": "已更新服务商类型熔断器",
+  "noEndpoints": "暂无端点配置",
+  "noEndpointsDesc": "添加端点以启用故障切换路由",
+  "columnUrl": "URL",
+  "columnActions": "操作",
+  "confirmDeleteEndpoint": "确定要删除此端点吗?",
+  "endpointAddSuccess": "端点添加成功",
+  "endpointAddFailed": "添加端点失败",
+  "endpointUpdateSuccess": "端点更新成功",
+  "endpointUpdateFailed": "更新端点失败",
+  "endpointDeleteSuccess": "端点删除成功",
+  "endpointDeleteFailed": "删除端点失败",
+  "probeOk": "正常",
+  "probeError": "异常",
+  "addEndpointDesc": "为该服务商添加一个新的 {providerType} 端点。",
+  "endpointUrlLabel": "URL",
+  "endpointUrlPlaceholder": "https://api.example.com/v1",
+  "endpointLabelOptional": "标签(可选)",
+  "endpointLabelPlaceholder": "生产环境",
+  "editEndpoint": "编辑端点",
+  "editVendor": "编辑服务商",
+  "vendorName": "服务商名称",
+  "vendorWebsite": "官网地址",
+  "vendorWebsitePlaceholder": "https://example.com",
+  "vendorOfficial": "官方",
+  "deleteVendor": "删除服务商",
+  "deleteVendorConfirmTitle": "删除服务商?",
+  "deleteVendorDoubleConfirmTitle": "再次确认删除?",
+  "deleteVendorConfirmDesc": "此操作将永久删除服务商 \"{name}\" 及其所有 API 密钥和端点。",
+  "deleteVendorDoubleConfirmDesc": "该操作不可恢复。请确认你要删除与 \"{name}\" 相关的所有内容。",
+  "vendorUpdateSuccess": "服务商更新成功",
+  "vendorUpdateFailed": "更新服务商失败",
+  "vendorDeleteSuccess": "服务商删除成功",
+  "vendorDeleteFailed": "删除服务商失败"
 }
 }

+ 1 - 0
messages/zh-TW/common.json

@@ -4,6 +4,7 @@
   "delete": "刪除",
   "delete": "刪除",
   "confirm": "確認",
   "confirm": "確認",
   "edit": "編輯",
   "edit": "編輯",
+  "status": "狀態",
   "create": "建立",
   "create": "建立",
   "close": "關閉",
   "close": "關閉",
   "back": "返回",
   "back": "返回",

+ 13 - 3
messages/zh-TW/customs.json

@@ -26,16 +26,26 @@
     "viewRelease": "查看發佈"
     "viewRelease": "查看發佈"
   },
   },
   "metrics": {
   "metrics": {
-    "concurrent": "並發數",
+    "concurrent": "活躍 Session 數",
     "todayRequests": "今日請求",
     "todayRequests": "今日請求",
     "todayCost": "今日消費",
     "todayCost": "今日消費",
     "avgResponse": "平均回應時間",
     "avgResponse": "平均回應時間",
-    "viewDetails": "查看詳情"
+    "viewDetails": "查看詳情",
+    "rpm": "RPM",
+    "vsYesterday": "較昨日同期"
   },
   },
   "activeSessions": {
   "activeSessions": {
     "title": "活躍 Session",
     "title": "活躍 Session",
     "summary": "{count} 個 Session,{minutes} 分鐘內",
     "summary": "{count} 個 Session,{minutes} 分鐘內",
     "empty": "暫無活躍 Session",
     "empty": "暫無活躍 Session",
-    "viewAll": "查看全部"
+    "viewAll": "查看全部",
+    "loading": "載入中...",
+    "unknownUser": "未知",
+    "status": {
+      "inProgressTooltip": "會話正在處理活躍請求",
+      "initializingTooltip": "會話正在初始化首個請求",
+      "idleTooltip": "會話閒置,無活躍請求",
+      "errorTooltip": "會話處理過程中發生錯誤"
+    }
   }
   }
 }
 }

+ 237 - 20
messages/zh-TW/dashboard.json

@@ -21,7 +21,8 @@
     "keysQuotas": "密鑰額度統計",
     "keysQuotas": "密鑰額度統計",
     "providersQuotas": "供應商額度統計",
     "providersQuotas": "供應商額度統計",
     "usageLogsDescription": "查看 API 調用日誌和使用統計",
     "usageLogsDescription": "查看 API 調用日誌和使用統計",
-    "filterCriteria": "篩選條件"
+    "filterCriteria": "篩選條件",
+    "filterCriteriaDescription": "依時間、用戶、供應商等條件縮小日誌範圍"
   },
   },
   "description": {
   "description": {
     "viewApiCallLogs": "查看 API 呼叫日誌和使用統計",
     "viewApiCallLogs": "查看 API 呼叫日誌和使用統計",
@@ -93,7 +94,28 @@
       "export": "匯出",
       "export": "匯出",
       "exporting": "匯出中...",
       "exporting": "匯出中...",
       "exportSuccess": "匯出成功",
       "exportSuccess": "匯出成功",
-      "exportError": "匯出失敗"
+      "exportError": "匯出失敗",
+      "quickFilters": {
+        "today": "今天",
+        "thisWeek": "本週",
+        "errorsOnly": "僅錯誤",
+        "showRetries": "有重試"
+      },
+      "activeFilters": {
+        "title": "已啟用篩選",
+        "remove": "移除篩選",
+        "clearAll": "清除全部"
+      },
+      "groups": {
+        "time": "時間範圍",
+        "timeDesc": "依日期與時間篩選",
+        "identity": "身分資訊",
+        "identityDesc": "依使用者與金鑰篩選",
+        "request": "請求參數",
+        "requestDesc": "依供應商、模型、端點篩選",
+        "status": "狀態資訊",
+        "statusDesc": "依狀態碼與重試次數篩選"
+      }
     },
     },
     "columns": {
     "columns": {
       "time": "時間",
       "time": "時間",
@@ -116,9 +138,7 @@
     },
     },
     "stats": {
     "stats": {
       "title": "統計匯總",
       "title": "統計匯總",
-      "description": "點擊展開查看當前篩選條件下的彙總統計",
-      "expand": "展開",
-      "collapse": "收合",
+      "description": "當前篩選條件下的彙總統計",
       "totalAmount": "總消耗金額",
       "totalAmount": "總消耗金額",
       "totalTokens": "總 Token 數",
       "totalTokens": "總 Token 數",
       "cacheTokens": "快取 Token",
       "cacheTokens": "快取 Token",
@@ -144,7 +164,8 @@
       "noMoreData": "已載入全部記錄",
       "noMoreData": "已載入全部記錄",
       "scrollToTop": "回到頂端",
       "scrollToTop": "回到頂端",
       "hideProviderColumn": "隱藏供應商欄",
       "hideProviderColumn": "隱藏供應商欄",
-      "showProviderColumn": "顯示供應商欄"
+      "showProviderColumn": "顯示供應商欄",
+      "columnVisibility": "顯示/隱藏欄位"
     },
     },
     "actions": {
     "actions": {
       "refresh": "重新整理",
       "refresh": "重新整理",
@@ -161,12 +182,27 @@
     },
     },
     "details": {
     "details": {
       "title": "請求詳情",
       "title": "請求詳情",
-      "statusTitle": "請求詳情 - 狀態碼 {status}",
+      "statusTitle": "狀態: {status}",
       "inProgress": "請求中",
       "inProgress": "請求中",
       "unknown": "未知狀態",
       "unknown": "未知狀態",
       "success": "請求成功完成",
       "success": "請求成功完成",
       "error": "請求失敗,以下是詳細的錯誤訊息和供應商決策鏈",
       "error": "請求失敗,以下是詳細的錯誤訊息和供應商決策鏈",
       "processing": "請求正在進行中,尚未完成",
       "processing": "請求正在進行中,尚未完成",
+      "tabs": {
+        "summary": "概覽",
+        "logicTrace": "決策鏈",
+        "performance": "效能",
+        "metadata": "中繼資料"
+      },
+      "summary": {
+        "keyMetrics": "關鍵指標",
+        "totalCost": "總費用",
+        "totalTokens": "總令牌數",
+        "duration": "耗時",
+        "outputRate": "輸出速率",
+        "viewFullError": "查看完整錯誤",
+        "viewSession": "查看工作階段"
+      },
       "specialSettings": {
       "specialSettings": {
         "title": "特殊設定"
         "title": "特殊設定"
       },
       },
@@ -224,13 +260,72 @@
         "circuitOpen": "斷路器開啟"
         "circuitOpen": "斷路器開啟"
       },
       },
       "billingDetails": {
       "billingDetails": {
-        "title": "計費詳情"
+        "title": "計費詳情",
+        "input": "輸入",
+        "output": "輸出",
+        "cacheWrite5m": "快取寫入(5m)",
+        "cacheWrite1h": "快取寫入(1h)",
+        "cacheRead": "快取讀取",
+        "cacheTtl": "快取 TTL",
+        "multiplier": "供應商倍率",
+        "totalCost": "總費用",
+        "context1m": "1M 上下文",
+        "context1mPricing": "輸入 2x >200k, 輸出 1.5x >200k"
       },
       },
       "performance": {
       "performance": {
         "title": "效能資料",
         "title": "效能資料",
         "ttfb": "首字節時間(TTFB)",
         "ttfb": "首字節時間(TTFB)",
         "duration": "總耗時",
         "duration": "總耗時",
         "outputRate": "輸出速率"
         "outputRate": "輸出速率"
+      },
+      "performanceTab": {
+        "noPerformanceData": "暫無效能資料",
+        "ttfbGauge": "首字節時間",
+        "outputRateGauge": "輸出速率",
+        "latencyBreakdown": "延遲分解",
+        "generationTime": "生成時間",
+        "assessment": {
+          "excellent": "優秀",
+          "good": "良好",
+          "warning": "警告",
+          "poor": "較差"
+        },
+        "thresholds": {
+          "ttfbGood": "TTFB < 1s",
+          "ttfbWarning": "TTFB 1-2s",
+          "ttfbPoor": "TTFB > 3s"
+        }
+      },
+      "metadata": {
+        "noMetadata": "暫無中繼資料",
+        "sessionInfo": "工作階段資訊",
+        "clientInfo": "用戶端資訊",
+        "billingInfo": "計費資訊",
+        "technicalTimeline": "技術時間軸",
+        "copyTimeline": "複製時間軸"
+      },
+      "logicTrace": {
+        "title": "決策鏈",
+        "noDecisionData": "暫無決策資料",
+        "providersCount": "{count} 個供應商",
+        "healthyCount": "{count} 個健康",
+        "initialSelection": "初始選擇",
+        "healthCheck": "健康檢查",
+        "prioritySelection": "優先順序選擇",
+        "attemptProvider": "嘗試: {provider}",
+        "retryAttempt": "重試 #{number}",
+        "sessionReuse": "會話複用",
+        "sessionReuseDesc": "從會話快取複用供應商",
+        "sessionReuseTitle": "會話綁定",
+        "sessionReuseSelection": "會話複用選擇",
+        "sessionReuseSelectionDesc": "從會話快取中選擇供應商",
+        "sessionInfo": "會話資訊",
+        "sessionIdLabel": "會話 ID",
+        "requestSequence": "請求序號",
+        "sessionAge": "會話年齡",
+        "reusedProvider": "複用的供應商",
+        "executeRequest": "執行請求",
+        "cacheOptimizationHint": "會話複用通過在同一對話中保持供應商親和性來優化效能,減少選擇開銷並提高快取命中率。"
       }
       }
     },
     },
     "providerChain": {
     "providerChain": {
@@ -920,6 +1015,93 @@
     "title": "供應商可用性監控",
     "title": "供應商可用性監控",
     "description": "即時監控供應商的可用性狀態和效能指標",
     "description": "即時監控供應商的可用性狀態和效能指標",
     "nav": "可用性監控",
     "nav": "可用性監控",
+    "tabs": {
+      "provider": "供應商可用性",
+      "endpoint": "端點健康"
+    },
+    "overview": {
+      "systemAvailability": "系統可用性",
+      "avgLatency": "平均延遲",
+      "errorRate": "錯誤率",
+      "activeProbes": "活躍探測",
+      "load": "負載"
+    },
+    "timeRange": {
+      "label": "時間範圍",
+      "15min": "15 分鐘",
+      "1h": "1 小時",
+      "6h": "6 小時",
+      "24h": "24 小時",
+      "7d": "7 天",
+      "last15min": "最近 15 分鐘",
+      "last1h": "最近 1 小時",
+      "last6h": "最近 6 小時",
+      "last24h": "最近 24 小時",
+      "last7d": "近 7 天",
+      "custom": "自訂"
+    },
+    "laneChart": {
+      "title": "供應商可用性時間軸",
+      "noData": "暫無資料",
+      "requests": "{count} 個請求",
+      "availability": "可用性 {value}%",
+      "noRequests": "無請求",
+      "denseData": "密集",
+      "sparseData": "稀疏",
+      "latency": "延遲"
+    },
+    "latencyChart": {
+      "title": "延遲分佈",
+      "p50": "P50",
+      "p95": "P95",
+      "p99": "P99",
+      "noData": "暫無延遲資料"
+    },
+    "latencyCurve": {
+      "title": "延遲趨勢",
+      "noData": "暫無延遲資料",
+      "avg": "平均",
+      "min": "最小",
+      "max": "最大",
+      "latency": "延遲"
+    },
+    "terminal": {
+      "title": "探測日誌",
+      "live": "即時",
+      "download": "下載日誌",
+      "noLogs": "暫無探測日誌",
+      "manual": "手動",
+      "auto": "自動",
+      "filterPlaceholder": "篩選日誌..."
+    },
+    "probeGrid": {
+      "title": "端點狀態",
+      "noEndpoints": "未設定端點",
+      "lastProbe": "最後探測",
+      "status": {
+        "unknown": "未知",
+        "healthy": "健康",
+        "unhealthy": "異常"
+      }
+    },
+    "endpoint": {
+      "selectVendor": "選擇供應商",
+      "selectType": "選擇類型"
+    },
+    "confidence": {
+      "low": "低",
+      "medium": "中",
+      "high": "高",
+      "lowTooltip": "請求數少於 {count},資料可能不具代表性。",
+      "mediumTooltip": "請求量適中,資料較為可靠。",
+      "highTooltip": "請求量充足,資料可靠。"
+    },
+    "actions": {
+      "probeNow": "立即探測",
+      "probing": "探測中...",
+      "probeSuccess": "探測成功",
+      "probeFailed": "探測失敗"
+    },
     "status": {
     "status": {
       "green": "良好",
       "green": "良好",
       "red": "異常",
       "red": "異常",
@@ -941,15 +1123,6 @@
       "lastRequest": "最後請求",
       "lastRequest": "最後請求",
       "requestCount": "請求數"
       "requestCount": "請求數"
     },
     },
-    "timeRange": {
-      "label": "時間範圍",
-      "last15min": "最近 15 分鐘",
-      "last1h": "最近 1 小時",
-      "last6h": "最近 6 小時",
-      "last24h": "最近 24 小時",
-      "last7d": "近 7 天",
-      "custom": "自訂"
-    },
     "filters": {
     "filters": {
       "provider": "供應商",
       "provider": "供應商",
       "allProviders": "全部供應商",
       "allProviders": "全部供應商",
@@ -993,7 +1166,13 @@
       "autoRefresh": "自動重新整理",
       "autoRefresh": "自動重新整理",
       "stopAutoRefresh": "停止自動重新整理",
       "stopAutoRefresh": "停止自動重新整理",
       "viewDetails": "檢視詳情",
       "viewDetails": "檢視詳情",
-      "testProvider": "測試供應商"
+      "testProvider": "測試供應商",
+      "retry": "重試",
+      "probeNow": "立即探測",
+      "probing": "探測中...",
+      "probeAll": "探測全部",
+      "probeSuccess": "探測成功",
+      "probeFailed": "探測失敗"
     },
     },
     "states": {
     "states": {
       "loading": "載入中...",
       "loading": "載入中...",
@@ -1023,6 +1202,28 @@
       "noData": "無資料",
       "noData": "無資料",
       "noRequests": "無請求"
       "noRequests": "無請求"
     },
     },
+    "probeHistory": {
+      "title": "端點探測歷史",
+      "description": "查看探測日誌並手動觸發特定端點的探測",
+      "selectVendor": "選擇供應商",
+      "selectType": "選擇供應商類型",
+      "selectEndpoint": "選擇端點",
+      "noEndpoints": "未找到端點",
+      "probeNow": "立即探測",
+      "probing": "探測中...",
+      "columns": {
+        "time": "時間",
+        "method": "方法",
+        "status": "狀態碼",
+        "latency": "延遲",
+        "error": "錯誤訊息"
+      },
+      "success": "成功",
+      "manual": "手動探測",
+      "auto": "自動探測",
+      "probeSuccess": "探測成功",
+      "probeFailed": "探測失敗"
+    },
     "toast": {
     "toast": {
       "refreshSuccess": "可用性資料已重新整理",
       "refreshSuccess": "可用性資料已重新整理",
       "refreshFailed": "重新整理失敗,請重試"
       "refreshFailed": "重新整理失敗,請重試"
@@ -1189,8 +1390,23 @@
       "columns": {
       "columns": {
         "model": "Model",
         "model": "Model",
         "calls": "呼叫次數",
         "calls": "呼叫次數",
+        "tokens": "Token",
         "cost": "消費金額"
         "cost": "消費金額"
       },
       },
+      "modal": {
+        "requests": "請求",
+        "totalTokens": "總Token",
+        "cost": "費用",
+        "inputTokens": "輸入Token",
+        "outputTokens": "輸出Token",
+        "cacheWrite": "快取寫入",
+        "cacheRead": "快取讀取",
+        "cacheHitRate": "快取命中率",
+        "cacheTokens": "快取Token",
+        "performanceHigh": "高",
+        "performanceMedium": "中",
+        "performanceLow": "低"
+      },
       "noData": "今日暫無使用記錄",
       "noData": "今日暫無使用記錄",
       "totalCalls": "今日總呼叫",
       "totalCalls": "今日總呼叫",
       "totalCost": "今日總消費"
       "totalCost": "今日總消費"
@@ -1336,7 +1552,7 @@
           "limitDaily": "每日限額(USD)",
           "limitDaily": "每日限額(USD)",
           "limitWeekly": "週限額(USD)",
           "limitWeekly": "週限額(USD)",
           "limitMonthly": "月限額(USD)",
           "limitMonthly": "月限額(USD)",
-          "canLoginWebUi": "允許登入 Web UI",
+          "canLoginWebUi": "獨立個人用量頁面",
           "keyEnabled": "Key 啟用狀態"
           "keyEnabled": "Key 啟用狀態"
         },
         },
         "placeholders": {
         "placeholders": {
@@ -1499,7 +1715,8 @@
       "clickToEnableUser": "點擊啟用使用者",
       "clickToEnableUser": "點擊啟用使用者",
       "operationFailed": "操作失敗",
       "operationFailed": "操作失敗",
       "deleteFailed": "刪除失敗",
       "deleteFailed": "刪除失敗",
-      "deleteSuccess": "刪除成功"
+      "deleteSuccess": "刪除成功",
+      "daysLeft": "{days, plural, =0 {今天到期} =1 {剩餘1天} other {剩餘#天}}"
     },
     },
     "userEditSection": {
     "userEditSection": {
       "sections": {
       "sections": {

+ 6 - 0
messages/zh-TW/errors.json

@@ -63,6 +63,12 @@
   "UPDATE_KEY_FAILED": "更新金鑰失敗,請稍後重試",
   "UPDATE_KEY_FAILED": "更新金鑰失敗,請稍後重試",
   "DELETE_KEY_FAILED": "刪除金鑰失敗,請稍後重試",
   "DELETE_KEY_FAILED": "刪除金鑰失敗,請稍後重試",
   "CANNOT_DISABLE_LAST_KEY": "無法禁用最後一個可用金鑰,使用者至少需要保留一個啟用的金鑰",
   "CANNOT_DISABLE_LAST_KEY": "無法禁用最後一個可用金鑰,使用者至少需要保留一個啟用的金鑰",
+  "KEY_LIMIT_5H_EXCEEDS_USER_LIMIT": "Key 的 5 小時消費上限({keyLimit})不能超過使用者限額({userLimit})",
+  "KEY_LIMIT_DAILY_EXCEEDS_USER_LIMIT": "Key 的每日消費上限({keyLimit})不能超過使用者限額({userLimit})",
+  "KEY_LIMIT_WEEKLY_EXCEEDS_USER_LIMIT": "Key 的每週消費上限({keyLimit})不能超過使用者限額({userLimit})",
+  "KEY_LIMIT_MONTHLY_EXCEEDS_USER_LIMIT": "Key 的每月消費上限({keyLimit})不能超過使用者限額({userLimit})",
+  "KEY_LIMIT_TOTAL_EXCEEDS_USER_LIMIT": "Key 的總消費上限({keyLimit})不能超過使用者限額({userLimit})",
+  "KEY_LIMIT_CONCURRENT_EXCEEDS_USER_LIMIT": "Key 的並發 Session 上限({keyLimit})不能超過使用者限額({userLimit})",
   "EXPIRES_AT_FIELD": "過期時間",
   "EXPIRES_AT_FIELD": "過期時間",
   "EXPIRES_AT_MUST_BE_FUTURE": "過期時間必須是未來時間",
   "EXPIRES_AT_MUST_BE_FUTURE": "過期時間必須是未來時間",
   "EXPIRES_AT_TOO_FAR": "過期時間不能超過10年",
   "EXPIRES_AT_TOO_FAR": "過期時間不能超過10年",

+ 2 - 2
messages/zh-TW/myUsage.json

@@ -78,7 +78,7 @@
     "inheritedFromUser": "繼承自使用者"
     "inheritedFromUser": "繼承自使用者"
   },
   },
   "stats": {
   "stats": {
-    "title": "統計摘要",
+    "title": "金鑰統計",
     "autoRefresh": "每{seconds}秒自動刷新",
     "autoRefresh": "每{seconds}秒自動刷新",
     "totalRequests": "總請求數",
     "totalRequests": "總請求數",
     "totalCost": "總費用",
     "totalCost": "總費用",
@@ -116,7 +116,7 @@
     "noRestrictions": "無限制"
     "noRestrictions": "無限制"
   },
   },
   "quotaCollapsible": {
   "quotaCollapsible": {
-    "title": "配額使用",
+    "title": "用戶配額使用",
     "daily": "每日",
     "daily": "每日",
     "monthly": "每月",
     "monthly": "每月",
     "total": "總計"
     "total": "總計"

+ 43 - 0
messages/zh-TW/provider-chain.json

@@ -39,6 +39,48 @@
     "http2Fallback": "HTTP/2 回退",
     "http2Fallback": "HTTP/2 回退",
     "clientError": "客戶端錯誤"
     "clientError": "客戶端錯誤"
   },
   },
+  "reasons": {
+    "request_success": "成功",
+    "retry_success": "重試成功",
+    "retry_failed": "重試失敗",
+    "system_error": "系統錯誤",
+    "client_error_non_retryable": "客戶端錯誤",
+    "concurrent_limit_failed": "並發限制",
+    "http2_fallback": "HTTP/2 回退",
+    "session_reuse": "會話複用",
+    "initial_selection": "首次選擇"
+  },
+  "filterReasons": {
+    "rate_limited": "速率限制",
+    "circuit_open": "熔斷器開啟",
+    "disabled": "已停用",
+    "model_not_supported": "不支援該模型",
+    "group_mismatch": "分組不匹配",
+    "health_check_failed": "健康檢查失敗"
+  },
+  "details": {
+    "selectionMethod": "選擇方式",
+    "attemptNumber": "嘗試次數",
+    "endpoint": "端點",
+    "config": "配置",
+    "priority": "優先級",
+    "weight": "權重",
+    "costMultiplier": "成本倍數",
+    "groupTag": "分組標籤",
+    "circuitBreaker": "熔斷器",
+    "circuitDisabled": "已停用",
+    "failures": "次失敗",
+    "modelRedirect": "模型重定向",
+    "error": "錯誤",
+    "errorDetails": "錯誤詳情",
+    "decisionContext": "決策上下文",
+    "beforeHealthCheck": "健康檢查前",
+    "afterHealthCheck": "健康檢查後",
+    "filteredProviders": "被過濾供應商",
+    "priorityLevels": "優先級層級",
+    "candidates": "候選供應商"
+  },
+  "technicalTimeline": "技術時間線",
   "timeline": {
   "timeline": {
     "sessionReuse": "會話複用",
     "sessionReuse": "會話複用",
     "sessionReuseSelection": "會話複用選擇供應商",
     "sessionReuseSelection": "會話複用選擇供應商",
@@ -87,6 +129,7 @@
     "status": "狀態",
     "status": "狀態",
     "alreadyBroken": "已觸發熔斷",
     "alreadyBroken": "已觸發熔斷",
     "circuitTriggered": "警告:已觸發熔斷",
     "circuitTriggered": "警告:已觸發熔斷",
+    "circuitDisabled": "熔斷器已停用",
     "errorDetails": "錯誤詳情",
     "errorDetails": "錯誤詳情",
     "systemError": "系統錯誤",
     "systemError": "系統錯誤",
     "systemErrorFailed": "系統錯誤(第 {attempt} 次嘗試)",
     "systemErrorFailed": "系統錯誤(第 {attempt} 次嘗試)",

+ 7 - 1
messages/zh-TW/settings/clientVersions.json

@@ -38,7 +38,13 @@
     "unknown": "不明",
     "unknown": "不明",
     "user": "用戶",
     "user": "用戶",
     "usersCount": "{count} 位用戶",
     "usersCount": "{count} 位用戶",
-    "version": "目前版本"
+    "version": "目前版本",
+    "stats": {
+      "clientTypes": "用戶端類型",
+      "totalUsers": "用戶總數",
+      "withGA": "有 GA 版本",
+      "coverage": "GA 覆蓋率"
+    }
   },
   },
   "title": "用戶端升級提醒",
   "title": "用戶端升級提醒",
   "toggle": {
   "toggle": {

+ 1 - 0
messages/zh-TW/settings/data.json

@@ -123,6 +123,7 @@
   },
   },
   "status": {
   "status": {
     "connected": "資料庫連線正常",
     "connected": "資料庫連線正常",
+    "connectionUnavailable": "資料庫連線不可用,請檢查資料庫服務狀態",
     "error": "取得資料庫狀態失敗",
     "error": "取得資料庫狀態失敗",
     "loading": "載入中...",
     "loading": "載入中...",
     "retry": "重試",
     "retry": "重試",

+ 5 - 0
messages/zh-TW/settings/index.ts

@@ -13,6 +13,7 @@ import sensitiveWords from "./sensitiveWords.json";
 import strings from "./strings.json";
 import strings from "./strings.json";
 
 
 import providersAutoSort from "./providers/autoSort.json";
 import providersAutoSort from "./providers/autoSort.json";
+import providersBatchEdit from "./providers/batchEdit.json";
 import providersFilter from "./providers/filter.json";
 import providersFilter from "./providers/filter.json";
 import providersGuide from "./providers/guide.json";
 import providersGuide from "./providers/guide.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
 import providersInlineEdit from "./providers/inlineEdit.json";
@@ -37,6 +38,7 @@ import providersFormModelSelect from "./providers/form/modelSelect.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormName from "./providers/form/name.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProviderTypes from "./providers/form/providerTypes.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
 import providersFormProxyTest from "./providers/form/proxyTest.json";
+import providersFormQuickPaste from "./providers/form/quickPaste.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormSections from "./providers/form/sections.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormStrings from "./providers/form/strings.json";
 import providersFormSuccess from "./providers/form/success.json";
 import providersFormSuccess from "./providers/form/success.json";
@@ -47,6 +49,7 @@ import providersFormWebsiteUrl from "./providers/form/websiteUrl.json";
 
 
 const providersForm = {
 const providersForm = {
   ...providersFormStrings,
   ...providersFormStrings,
+  ...providersFormCommon,
   apiTest: providersFormApiTest,
   apiTest: providersFormApiTest,
   buttons: providersFormButtons,
   buttons: providersFormButtons,
   common: providersFormCommon,
   common: providersFormCommon,
@@ -60,6 +63,7 @@ const providersForm = {
   name: providersFormName,
   name: providersFormName,
   providerTypes: providersFormProviderTypes,
   providerTypes: providersFormProviderTypes,
   proxyTest: providersFormProxyTest,
   proxyTest: providersFormProxyTest,
+  quickPaste: providersFormQuickPaste,
   sections: providersFormSections,
   sections: providersFormSections,
   success: providersFormSuccess,
   success: providersFormSuccess,
   title: providersFormTitle,
   title: providersFormTitle,
@@ -71,6 +75,7 @@ const providersForm = {
 const providers = {
 const providers = {
   ...providersStrings,
   ...providersStrings,
   autoSort: providersAutoSort,
   autoSort: providersAutoSort,
+  batchEdit: providersBatchEdit,
   filter: providersFilter,
   filter: providersFilter,
   form: providersForm,
   form: providersForm,
   guide: providersGuide,
   guide: providersGuide,

+ 2 - 0
messages/zh-TW/settings/notifications.json

@@ -69,6 +69,8 @@
   "global": {
   "global": {
     "description": "啟用或停用所有訊息推送功能",
     "description": "啟用或停用所有訊息推送功能",
     "enable": "啟用訊息推送",
     "enable": "啟用訊息推送",
+    "off": "已關閉",
+    "on": "已開啟",
     "legacyModeDescription": "目前使用舊版單一 URL 推送設定。建立推送目標後將自動切換為多目標模式。",
     "legacyModeDescription": "目前使用舊版單一 URL 推送設定。建立推送目標後將自動切換為多目標模式。",
     "legacyModeTitle": "相容模式",
     "legacyModeTitle": "相容模式",
     "title": "通知總開關"
     "title": "通知總開關"

+ 43 - 0
messages/zh-TW/settings/providers/batchEdit.json

@@ -0,0 +1,43 @@
+{
+  "enterMode": "批次編輯",
+  "exitMode": "退出",
+  "selectAll": "全選",
+  "invertSelection": "反選",
+  "selectedCount": "已選 {count} 項",
+  "editSelected": "編輯選中項",
+  "actions": {
+    "edit": "編輯",
+    "delete": "刪除",
+    "resetCircuit": "重置熔斷"
+  },
+  "dialog": {
+    "editTitle": "批次編輯供應商",
+    "editDesc": "修改將應用於 {count} 個供應商",
+    "deleteTitle": "刪除供應商",
+    "deleteDesc": "確定永久刪除 {count} 個供應商?",
+    "resetCircuitTitle": "重置熔斷器",
+    "resetCircuitDesc": "確定重置 {count} 個供應商的熔斷器?",
+    "next": "下一步",
+    "noFieldEnabled": "請至少啟用一個要更新的欄位"
+  },
+  "fields": {
+    "isEnabled": "狀態",
+    "priority": "優先級",
+    "weight": "權重",
+    "costMultiplier": "價格倍率",
+    "groupTag": "分組標籤"
+  },
+  "confirm": {
+    "title": "確認操作",
+    "cancel": "取消",
+    "confirm": "確認",
+    "goBack": "返回",
+    "processing": "處理中..."
+  },
+  "toast": {
+    "updated": "已更新 {count} 個供應商",
+    "deleted": "已刪除 {count} 個供應商",
+    "circuitReset": "已重置 {count} 個熔斷器",
+    "failed": "操作失敗: {error}"
+  }
+}

+ 8 - 1
messages/zh-TW/settings/providers/form/common.json

@@ -1,3 +1,10 @@
 {
 {
-  "core": "核心設定"
+  "core": "核心設定",
+  "tabs": {
+    "basic": "基本資訊",
+    "routing": "路由",
+    "limits": "限制",
+    "network": "網路",
+    "testing": "測試"
+  }
 }
 }

+ 1 - 0
messages/zh-TW/settings/providers/form/key.json

@@ -1,6 +1,7 @@
 {
 {
   "currentKey": "當前金鑰:{key}",
   "currentKey": "當前金鑰:{key}",
   "label": "API 金鑰",
   "label": "API 金鑰",
+  "labelEdit": "API 金鑰(留空不變更)",
   "leaveEmpty": "(留空不變更)",
   "leaveEmpty": "(留空不變更)",
   "leaveEmptyDesc": "留空則不變更金鑰",
   "leaveEmptyDesc": "留空則不變更金鑰",
   "placeholder": "輸入 API 金鑰"
   "placeholder": "輸入 API 金鑰"

+ 1 - 1
messages/zh-TW/settings/providers/form/name.json

@@ -1,4 +1,4 @@
 {
 {
-  "label": "供應商名稱 *",
+  "label": "供應商名稱",
   "placeholder": "例如:智譜"
   "placeholder": "例如:智譜"
 }
 }

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott