@lynn123411/dsh-a6api 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -3
- package/lib/client.js +2154 -284
- package/lib/client.js.map +4 -4
- package/lib/index.js +1317 -639
- package/lib/index.js.map +4 -4
- package/lib/types/client/components/A6ApiSidebarCard.d.ts +18 -0
- package/lib/types/client/components/ModelCatalogPanel.d.ts +11 -0
- package/lib/types/client/components/PricePill.d.ts +12 -0
- package/lib/types/client/store.d.ts +92 -2
- package/lib/types/index.d.ts +3 -3
- package/lib/types/server/a6api-client.d.ts +32 -6
- package/lib/types/server/catalog.d.ts +43 -4
- package/lib/types/server/probe.d.ts +2 -0
- package/lib/types/server/sync.d.ts +28 -9
- package/lib/types/types.d.ts +71 -5
- package/package.json +1 -1
package/lib/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/server/catalog.ts", "../src/server/a6api-client.ts", "../src/server/probe.ts", "../src/server/sync.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { A6ApiModelMeta } from '../types.js';\n\nexport const A6API_CATALOG: Record<string, A6ApiModelMeta> = {\n // --- OpenAI Series ---\n 'gpt-5.6-sol': {\n id: 'gpt-5.6-sol',\n name: 'GPT-5.6 Sol',\n brand: 'OpenAI',\n contextWindow: 1048576,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n reasoningEfforts: { off: '', low: 'low', medium: 'medium', high: 'high' },\n officialPriceMicros: { input: 4000000, output: 20000000, cacheRead: 400000, cacheWrite: 5000000 },\n },\n 'gpt-5.6-terra': {\n id: 'gpt-5.6-terra',\n name: 'GPT-5.6 Terra',\n brand: 'OpenAI',\n contextWindow: 1048576,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n reasoningEfforts: { off: '', low: 'low', medium: 'medium', high: 'high' },\n officialPriceMicros: { input: 4000000, output: 20000000, cacheRead: 400000, cacheWrite: 5000000 },\n },\n 'gpt-5.6-luna': {\n id: 'gpt-5.6-luna',\n name: 'GPT-5.6 Luna',\n brand: 'OpenAI',\n contextWindow: 524288,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n reasoningEfforts: { off: '', low: 'low', medium: 'medium', high: 'high' },\n officialPriceMicros: { input: 2000000, output: 10000000, cacheRead: 200000, cacheWrite: 2500000 },\n },\n 'gpt-5.6': {\n id: 'gpt-5.6',\n name: 'GPT-5.6',\n brand: 'OpenAI',\n contextWindow: 1048576,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n reasoningEfforts: { off: '', low: 'low', medium: 'medium', high: 'high' },\n officialPriceMicros: { input: 4000000, output: 20000000, cacheRead: 400000, cacheWrite: 5000000 },\n },\n 'gpt-5.5': {\n id: 'gpt-5.5',\n name: 'GPT-5.5',\n brand: 'OpenAI',\n contextWindow: 1048576,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n reasoningEfforts: { off: '', low: 'low', medium: 'medium', high: 'high' },\n officialPriceMicros: { input: 3000000, output: 15000000, cacheRead: 300000, cacheWrite: 3750000 },\n },\n 'gpt-5.4': {\n id: 'gpt-5.4',\n name: 'GPT-5.4',\n brand: 'OpenAI',\n contextWindow: 524288,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n reasoningEfforts: { off: '', low: 'low', medium: 'medium', high: 'high' },\n officialPriceMicros: { input: 2500000, output: 10000000, cacheRead: 250000, cacheWrite: 3000000 },\n },\n 'gpt-5.4-mini': {\n id: 'gpt-5.4-mini',\n name: 'GPT-5.4 Mini',\n brand: 'OpenAI',\n contextWindow: 262144,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n reasoningEfforts: { off: '', low: 'low', medium: 'medium', high: 'high' },\n officialPriceMicros: { input: 150000, output: 600000, cacheRead: 75000, cacheWrite: 150000 },\n },\n 'gpt-5.3-codex': {\n id: 'gpt-5.3-codex',\n name: 'GPT-5.3 Codex',\n brand: 'OpenAI',\n contextWindow: 262144,\n maxTokens: 32768,\n modalities: ['text'],\n officialPriceMicros: { input: 2000000, output: 8000000, cacheRead: 200000, cacheWrite: 2000000 },\n },\n 'gpt-5.3-codex-spark': {\n id: 'gpt-5.3-codex-spark',\n name: 'GPT-5.3 Codex Spark',\n brand: 'OpenAI',\n contextWindow: 262144,\n maxTokens: 16384,\n modalities: ['text'],\n officialPriceMicros: { input: 1000000, output: 4000000, cacheRead: 100000, cacheWrite: 1000000 },\n },\n 'gpt-5.2': {\n id: 'gpt-5.2',\n name: 'GPT-5.2',\n brand: 'OpenAI',\n contextWindow: 262144,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 2000000, output: 8000000, cacheRead: 200000, cacheWrite: 2000000 },\n },\n 'gpt-4o': {\n id: 'gpt-4o',\n name: 'GPT-4o',\n brand: 'OpenAI',\n contextWindow: 128000,\n maxTokens: 16384,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 2500000, output: 10000000, cacheRead: 1250000, cacheWrite: 2500000 },\n },\n 'gpt-4o-mini': {\n id: 'gpt-4o-mini',\n name: 'GPT-4o Mini',\n brand: 'OpenAI',\n contextWindow: 128000,\n maxTokens: 16384,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 150000, output: 600000, cacheRead: 75000, cacheWrite: 150000 },\n },\n\n // --- Anthropic Claude Series ---\n 'claude-opus-5': {\n id: 'claude-opus-5',\n name: 'Claude Opus 5',\n brand: 'Anthropic',\n contextWindow: 200000,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n thinkingFormat: 'anthropic',\n officialPriceMicros: { input: 15000000, output: 75000000, cacheRead: 1500000, cacheWrite: 18750000 },\n },\n 'claude-sonnet-5': {\n id: 'claude-sonnet-5',\n name: 'Claude Sonnet 5',\n brand: 'Anthropic',\n contextWindow: 200000,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n thinkingFormat: 'anthropic',\n officialPriceMicros: { input: 3000000, output: 15000000, cacheRead: 300000, cacheWrite: 3750000 },\n },\n 'claude-fable-5': {\n id: 'claude-fable-5',\n name: 'Claude Fable 5',\n brand: 'Anthropic',\n contextWindow: 200000,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 3000000, output: 15000000, cacheRead: 300000, cacheWrite: 3750000 },\n },\n 'claude-opus-4-8': {\n id: 'claude-opus-4-8',\n name: 'Claude Opus 4.8',\n brand: 'Anthropic',\n contextWindow: 200000,\n maxTokens: 16384,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 15000000, output: 75000000, cacheRead: 1500000, cacheWrite: 18750000 },\n },\n 'claude-opus-4-7': {\n id: 'claude-opus-4-7',\n name: 'Claude Opus 4.7',\n brand: 'Anthropic',\n contextWindow: 200000,\n maxTokens: 16384,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 15000000, output: 75000000, cacheRead: 1500000, cacheWrite: 18750000 },\n },\n 'claude-opus-4-6': {\n id: 'claude-opus-4-6',\n name: 'Claude Opus 4.6',\n brand: 'Anthropic',\n contextWindow: 200000,\n maxTokens: 16384,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 15000000, output: 75000000, cacheRead: 1500000, cacheWrite: 18750000 },\n },\n 'claude-sonnet-4-6': {\n id: 'claude-sonnet-4-6',\n name: 'Claude Sonnet 4.6',\n brand: 'Anthropic',\n contextWindow: 200000,\n maxTokens: 16384,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 3000000, output: 15000000, cacheRead: 300000, cacheWrite: 3750000 },\n },\n 'claude-haiku-4-5': {\n id: 'claude-haiku-4-5',\n name: 'Claude Haiku 4.5',\n brand: 'Anthropic',\n contextWindow: 200000,\n maxTokens: 8192,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 250000, output: 1250000, cacheRead: 25000, cacheWrite: 312500 },\n },\n\n // --- DeepSeek Series ---\n 'deepseek-v4-pro': {\n id: 'deepseek-v4-pro',\n name: 'DeepSeek V4 Pro',\n brand: 'DeepSeek',\n contextWindow: 131072,\n maxTokens: 32768,\n modalities: ['text'],\n thinkingFormat: 'deepseek',\n officialPriceMicros: { input: 550000, output: 2190000, cacheRead: 140000, cacheWrite: 550000 },\n },\n 'deepseek-v4-flash': {\n id: 'deepseek-v4-flash',\n name: 'DeepSeek V4 Flash',\n brand: 'DeepSeek',\n contextWindow: 131072,\n maxTokens: 16384,\n modalities: ['text'],\n officialPriceMicros: { input: 140000, output: 280000, cacheRead: 14000, cacheWrite: 140000 },\n },\n 'DeepSeek-V4-Flash-0731': {\n id: 'DeepSeek-V4-Flash-0731',\n name: 'DeepSeek V4 Flash (0731)',\n brand: 'DeepSeek',\n contextWindow: 131072,\n maxTokens: 16384,\n modalities: ['text'],\n officialPriceMicros: { input: 140000, output: 280000, cacheRead: 14000, cacheWrite: 140000 },\n },\n 'deepseek-v4-pro-0813': {\n id: 'deepseek-v4-pro-0813',\n name: 'DeepSeek V4 Pro (0813)',\n brand: 'DeepSeek',\n contextWindow: 131072,\n maxTokens: 32768,\n modalities: ['text'],\n thinkingFormat: 'deepseek',\n officialPriceMicros: { input: 550000, output: 2190000, cacheRead: 140000, cacheWrite: 550000 },\n },\n 'deepseek-v4-flash-vision-exp': {\n id: 'deepseek-v4-flash-vision-exp',\n name: 'DeepSeek V4 Flash Vision Exp',\n brand: 'DeepSeek',\n contextWindow: 131072,\n maxTokens: 16384,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 140000, output: 280000, cacheRead: 14000, cacheWrite: 140000 },\n },\n 'deepseek-chat': {\n id: 'deepseek-chat',\n name: 'DeepSeek Chat',\n brand: 'DeepSeek',\n contextWindow: 65536,\n maxTokens: 8192,\n modalities: ['text'],\n officialPriceMicros: { input: 140000, output: 280000, cacheRead: 14000, cacheWrite: 140000 },\n },\n 'deepseek-reasoner': {\n id: 'deepseek-reasoner',\n name: 'DeepSeek Reasoner',\n brand: 'DeepSeek',\n contextWindow: 65536,\n maxTokens: 16384,\n modalities: ['text'],\n thinkingFormat: 'deepseek',\n officialPriceMicros: { input: 550000, output: 2190000, cacheRead: 140000, cacheWrite: 550000 },\n },\n\n // --- Google Gemini Series ---\n 'gemini-3.7-flash': {\n id: 'gemini-3.7-flash',\n name: 'Gemini 3.7 Flash',\n brand: 'Google',\n contextWindow: 1048576,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n reasoningEfforts: { off: '', low: 'low', medium: 'medium', high: 'high' },\n officialPriceMicros: { input: 100000, output: 400000, cacheRead: 25000, cacheWrite: 100000 },\n },\n 'gemini-3.6-flash': {\n id: 'gemini-3.6-flash',\n name: 'Gemini 3.6 Flash',\n brand: 'Google',\n contextWindow: 1048576,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 100000, output: 400000, cacheRead: 25000, cacheWrite: 100000 },\n },\n 'gemini-3.5-flash': {\n id: 'gemini-3.5-flash',\n name: 'Gemini 3.5 Flash',\n brand: 'Google',\n contextWindow: 1048576,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 75000, output: 300000, cacheRead: 18750, cacheWrite: 75000 },\n },\n 'gemini-3.5-flash-high': {\n id: 'gemini-3.5-flash-high',\n name: 'Gemini 3.5 Flash High',\n brand: 'Google',\n contextWindow: 1048576,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n reasoningEfforts: { high: 'high' },\n officialPriceMicros: { input: 75000, output: 300000, cacheRead: 18750, cacheWrite: 75000 },\n },\n 'gemini-3.1-pro-preview': {\n id: 'gemini-3.1-pro-preview',\n name: 'Gemini 3.1 Pro Preview',\n brand: 'Google',\n contextWindow: 2097152,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 1250000, output: 5000000, cacheRead: 312500, cacheWrite: 1250000 },\n },\n 'gemini-3.1-flash-lite-preview': {\n id: 'gemini-3.1-flash-lite-preview',\n name: 'Gemini 3.1 Flash Lite Preview',\n brand: 'Google',\n contextWindow: 1048576,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 75000, output: 300000, cacheRead: 18750, cacheWrite: 75000 },\n },\n 'gemini-2.5-pro': {\n id: 'gemini-2.5-pro',\n name: 'Gemini 2.5 Pro',\n brand: 'Google',\n contextWindow: 2097152,\n maxTokens: 65536,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 1250000, output: 5000000, cacheRead: 312500, cacheWrite: 1250000 },\n },\n 'gemini-2.5-flash': {\n id: 'gemini-2.5-flash',\n name: 'Gemini 2.5 Flash',\n brand: 'Google',\n contextWindow: 1048576,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 75000, output: 300000, cacheRead: 18750, cacheWrite: 75000 },\n },\n\n // --- xAI Grok Series ---\n 'grok-4.6': {\n id: 'grok-4.6',\n name: 'Grok 4.6',\n brand: 'xAI',\n contextWindow: 262144,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n reasoningEfforts: { off: '', high: 'high' },\n officialPriceMicros: { input: 2000000, output: 10000000, cacheRead: 200000, cacheWrite: 2500000 },\n },\n 'grok-4.5': {\n id: 'grok-4.5',\n name: 'Grok 4.5',\n brand: 'xAI',\n contextWindow: 131072,\n maxTokens: 16384,\n modalities: ['text', 'image'],\n officialPriceMicros: { input: 2000000, output: 10000000, cacheRead: 200000, cacheWrite: 2500000 },\n },\n 'grok-4.3': {\n id: 'grok-4.3',\n name: 'Grok 4.3',\n brand: 'xAI',\n contextWindow: 131072,\n maxTokens: 16384,\n modalities: ['text'],\n officialPriceMicros: { input: 2000000, output: 10000000, cacheRead: 200000, cacheWrite: 2500000 },\n },\n\n // --- Zhipu GLM Series ---\n 'glm-5.3': {\n id: 'glm-5.3',\n name: 'GLM 5.3',\n brand: 'Zhipu',\n contextWindow: 131072,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n thinkingFormat: 'deepseek',\n officialPriceMicros: { input: 1000000, output: 4000000, cacheRead: 200000, cacheWrite: 1000000 },\n },\n 'glm-5.3-flash': {\n id: 'glm-5.3-flash',\n name: 'GLM 5.3 Flash',\n brand: 'Zhipu',\n contextWindow: 131072,\n maxTokens: 16384,\n modalities: ['text'],\n officialPriceMicros: { input: 100000, output: 200000, cacheRead: 10000, cacheWrite: 100000 },\n },\n 'glm-5.2': {\n id: 'glm-5.2',\n name: 'GLM 5.2',\n brand: 'Zhipu',\n contextWindow: 131072,\n maxTokens: 16384,\n modalities: ['text'],\n officialPriceMicros: { input: 1000000, output: 4000000, cacheRead: 200000, cacheWrite: 1000000 },\n },\n\n // --- Moonshot Kimi Series ---\n 'kimi-k3': {\n id: 'kimi-k3',\n name: 'Kimi K3',\n brand: 'Moonshot',\n contextWindow: 262144,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n thinkingFormat: 'deepseek',\n officialPriceMicros: { input: 1500000, output: 6000000, cacheRead: 300000, cacheWrite: 1500000 },\n },\n 'kimi-k2.7-code': {\n id: 'kimi-k2.7-code',\n name: 'Kimi K2.7 Code',\n brand: 'Moonshot',\n contextWindow: 262144,\n maxTokens: 32768,\n modalities: ['text'],\n officialPriceMicros: { input: 1000000, output: 4000000, cacheRead: 200000, cacheWrite: 1000000 },\n },\n\n // --- Alibaba Qwen Series ---\n 'qwen3.8-max': {\n id: 'qwen3.8-max',\n name: 'Qwen 3.8 Max',\n brand: 'Alibaba',\n contextWindow: 1048576,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n thinkingFormat: 'deepseek',\n officialPriceMicros: { input: 2000000, output: 8000000, cacheRead: 400000, cacheWrite: 2000000 },\n },\n 'qwen3.8-flash': {\n id: 'qwen3.8-flash',\n name: 'Qwen 3.8 Flash',\n brand: 'Alibaba',\n contextWindow: 1048576,\n maxTokens: 16384,\n modalities: ['text'],\n officialPriceMicros: { input: 100000, output: 300000, cacheRead: 20000, cacheWrite: 100000 },\n },\n 'qwen3.7-max': {\n id: 'qwen3.7-max',\n name: 'Qwen 3.7 Max',\n brand: 'Alibaba',\n contextWindow: 1048576,\n maxTokens: 32768,\n modalities: ['text', 'image'],\n thinkingFormat: 'deepseek',\n officialPriceMicros: { input: 2000000, output: 8000000, cacheRead: 400000, cacheWrite: 2000000 },\n },\n\n // --- MiniMax Series ---\n 'minimax-m3': {\n id: 'minimax-m3',\n name: 'MiniMax M3',\n brand: 'MiniMax',\n contextWindow: 1048576,\n maxTokens: 32768,\n modalities: ['text'],\n officialPriceMicros: { input: 1000000, output: 4000000, cacheRead: 200000, cacheWrite: 1000000 },\n },\n};\n\n/** Infer Brand from model name if not in catalog. */\nexport function inferBrand(modelId: string): string {\n const m = modelId.toLowerCase();\n if (m.startsWith('gpt') || m.startsWith('o1') || m.startsWith('o3') || m.startsWith('chatgpt')) return 'OpenAI';\n if (m.startsWith('claude')) return 'Anthropic';\n if (m.startsWith('gemini') || m.startsWith('google') || m.startsWith('imagen')) return 'Google';\n if (m.startsWith('deepseek')) return 'DeepSeek';\n if (m.startsWith('grok')) return 'xAI';\n if (m.startsWith('glm') || m.startsWith('zhipu') || m.startsWith('cog')) return 'Zhipu';\n if (m.startsWith('kimi') || m.startsWith('moonshot')) return 'Moonshot';\n if (m.startsWith('qwen')) return 'Alibaba';\n if (m.startsWith('minimax')) return 'MiniMax';\n if (m.startsWith('mimo') || m.startsWith('xiaomi')) return 'Xiaomi';\n if (m.startsWith('hunyuan') || m.startsWith('tencent') || m.startsWith('hy')) return 'Tencent';\n return 'Other';\n}\n\n/** Resolve metadata for any model ID, falling back to safe defaults. */\nexport function resolveModelMeta(modelId: string): A6ApiModelMeta {\n if (A6API_CATALOG[modelId]) {\n return A6API_CATALOG[modelId];\n }\n // Case-insensitive lookup\n const lowerId = modelId.toLowerCase();\n for (const [k, v] of Object.entries(A6API_CATALOG)) {\n if (k.toLowerCase() === lowerId) {\n return v;\n }\n }\n const brand = inferBrand(modelId);\n const isVision = lowerId.includes('vision') || lowerId.includes('vl') || lowerId.includes('image');\n const hasReasoning = lowerId.includes('think') || lowerId.includes('reason') || lowerId.includes('pro') || lowerId.includes('sol');\n\n return {\n id: modelId,\n name: modelId,\n brand,\n contextWindow: 262144,\n maxTokens: 32768,\n modalities: isVision ? ['text', 'image'] : ['text'],\n ...(hasReasoning ? { thinkingFormat: 'deepseek' } : {}),\n };\n}\n", "import type { BalanceInfo, MerchantChannelInfo, OfficialPrices, ApiRoutingLogItem } from '../types.js';\nimport { resolveModelMeta } from './catalog.js';\n\n/** Normalize Base URL removing trailing slashes */\nexport function cleanBaseUrl(url: string): string {\n if (!url) return 'https://api.a6api.com';\n return url.trim().replace(/\\/+$/, '');\n}\n\n/** Format relative time */\nexport function formatRelativeTime(timestampSec: number): string {\n if (!timestampSec || timestampSec <= 0) return '\u521A\u521A';\n const now = Math.floor(Date.now() / 1000);\n const diff = now - timestampSec;\n if (diff < 0) return '\u521A\u521A';\n if (diff < 60) return '\u521A\u521A';\n if (diff < 3600) return `${Math.floor(diff / 60)} \u5206\u949F\u524D`;\n if (diff < 86400) return `${Math.floor(diff / 3600)} \u5C0F\u65F6\u524D`;\n return `${Math.floor(diff / 86400)} \u5929\u524D`;\n}\n\n/** Format CNY Price */\nexport function formatCnyPrice(micros: number, exchangeRate = 6.7209): string {\n if (micros === undefined || micros === null) return '\u2014';\n if (micros === 0) return '\u00A50';\n const usd = micros / 1_000_000;\n const cny = usd * exchangeRate;\n if (cny < 0.0001) return `\u00A5${cny.toFixed(6)}`;\n if (cny < 0.01) return `\u00A5${cny.toFixed(4)}`;\n if (cny < 1) return `\u00A5${cny.toFixed(4)}`;\n return `\u00A5${cny.toFixed(3)}`;\n}\n\nexport function buildWebHeaders(userId?: string, sessionCookie?: string): Record<string, string> {\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',\n };\n const uid = userId ? String(userId).trim() : '';\n if (uid) {\n headers['New-Api-User'] = uid;\n }\n if (sessionCookie && sessionCookie.trim()) {\n const raw = sessionCookie.trim();\n if (raw.startsWith('session=')) {\n headers['Cookie'] = raw;\n } else if (raw.includes(';')) {\n headers['Cookie'] = raw;\n } else {\n // Set both Authorization (for System Access Token) and Cookie fallback\n headers['Authorization'] = raw;\n headers['Cookie'] = `session=${raw}`;\n }\n }\n return headers;\n}\n\n/** Fetch User Balance (Real Account Balance Only) */\nexport async function fetchBalance(\n baseURL: string,\n apiKey: string,\n userId?: string,\n sessionCookie?: string,\n): Promise<BalanceInfo | null> {\n const cleanUrl = cleanBaseUrl(baseURL);\n\n let hasAccountAuth = false;\n let accountBalanceUsd = 0;\n let accountBalanceFormatted = '\u672A\u8FDE\u63A5';\n let accountBalanceCnyFormatted = '';\n let username: string | undefined;\n let responseUserId: string | number | undefined = userId;\n let usedUsd = 0;\n let requestCount = 0;\n\n // 1. Fetch real account balance from Web Console API\n if (userId || sessionCookie) {\n const candidates = ['https://a6api.com/api/user/self', `${cleanUrl}/api/user/self`];\n const uniqueCandidates = [...new Set(candidates)];\n\n for (const url of uniqueCandidates) {\n try {\n const res = await fetch(url, {\n headers: buildWebHeaders(userId, sessionCookie),\n signal: AbortSignal.timeout(6000),\n });\n if (res.ok) {\n const json = await res.json();\n if (json?.data && json.data.quota !== undefined) {\n const quota = Number(json.data.quota || 0);\n const rawUsed = Number(json.data.used_quota || 0);\n const usd = Number((quota / 500000).toFixed(4));\n const cny = Number((usd * 6.7209).toFixed(2));\n const used = Number((rawUsed / 500000).toFixed(4));\n\n hasAccountAuth = true;\n accountBalanceUsd = usd;\n accountBalanceFormatted = `$${usd.toFixed(2)}`;\n accountBalanceCnyFormatted = `\u2248 \u00A5${cny.toFixed(2)}`;\n usedUsd = used;\n requestCount = Number(json.data.request_count || 0);\n username = json.data.username || json.data.display_name || undefined;\n if (json.data.id) responseUserId = json.data.id;\n break;\n }\n }\n } catch {\n // continue candidate\n }\n }\n }\n\n // 2. If only API Key is present, query usage for consumed statistics if auth is not yet connected\n if (!hasAccountAuth && apiKey && apiKey.trim()) {\n try {\n const usageRes = await fetch(`${cleanUrl}/v1/dashboard/billing/usage?start_date=2024-01-01&end_date=2030-12-31`, {\n headers: {\n Authorization: `Bearer ${apiKey.trim()}`,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(6000),\n }).catch(() => null);\n\n if (usageRes && usageRes.ok) {\n const usageJson = await usageRes.json();\n usedUsd = Number(usageJson?.total_usage || 0);\n }\n } catch {}\n }\n\n if (!hasAccountAuth && (!apiKey || !apiKey.trim()) && (!userId || !userId.trim())) {\n return null;\n }\n\n return {\n hasAccountAuth,\n accountBalanceUsd,\n accountBalanceFormatted,\n accountBalanceCnyFormatted,\n usedUsd,\n usedFormatted: `$${usedUsd.toFixed(2)}`,\n requestCount,\n username,\n userId: responseUserId,\n isLow: hasAccountAuth ? accountBalanceUsd < 0.5 : false,\n updatedAt: Date.now(),\n };\n}\n\n/** Fetch Token Allowed Models */\nexport async function fetchTokenModels(baseURL: string, apiKey: string): Promise<string[]> {\n const cleanUrl = cleanBaseUrl(baseURL);\n if (!apiKey || !apiKey.trim()) return [];\n\n const endpoints = [`${cleanUrl}/v1/models`, `${cleanUrl}/models`];\n let lastErr = null;\n\n for (const url of endpoints) {\n try {\n const res = await fetch(url, {\n headers: {\n Authorization: `Bearer ${apiKey.trim()}`,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(8000),\n });\n if (res.ok) {\n const json = await res.json();\n if (Array.isArray(json?.data)) {\n return json.data.map((m: any) => String(m.id || m.name)).filter(Boolean);\n }\n }\n } catch (err) {\n lastErr = err;\n }\n }\n\n if (lastErr) {\n console.warn('[dsh-a6api] fetchTokenModels failed:', lastErr);\n }\n return [];\n}\n\n/** Fetch Recent User Routing Logs */\nexport async function fetchRecentLogs(\n userId?: string,\n sessionCookie?: string,\n limit = 30,\n): Promise<ApiRoutingLogItem[]> {\n if (!userId && !sessionCookie) return [];\n try {\n const res = await fetch(`https://a6api.com/api/log/self?p=1&page_size=${limit}&type=0`, {\n headers: buildWebHeaders(userId, sessionCookie),\n signal: AbortSignal.timeout(8000),\n });\n if (res.ok) {\n const json = await res.json();\n if (Array.isArray(json?.data?.items)) {\n return json.data.items.map((it: any) => {\n const rawQuota = Number(it.quota || 0);\n const costUsd = rawQuota / 500000;\n let costFormatted = '$0.00';\n if (costUsd > 0) {\n if (costUsd < 0.0001) costFormatted = `$${costUsd.toFixed(6)}`;\n else if (costUsd < 0.01) costFormatted = `$${costUsd.toFixed(4)}`;\n else costFormatted = `$${costUsd.toFixed(4)}`;\n }\n\n const rawChannel = Number(it.channel || 0);\n let channelId: number | undefined = rawChannel > 0 ? rawChannel : undefined;\n if (!channelId && it.other) {\n try {\n const otherObj = JSON.parse(it.other);\n if (otherObj.actual_channel_id && Number(otherObj.actual_channel_id) > 0) {\n channelId = Number(otherObj.actual_channel_id);\n } else if (otherObj.billed_channel_id && Number(otherObj.billed_channel_id) > 0) {\n channelId = Number(otherObj.billed_channel_id);\n }\n } catch {}\n }\n\n const isError =\n it.type !== 2 ||\n (it.other && (\n it.other.includes('\"request_final_status\":\"failed\"') ||\n it.other.includes('\"request_final_status\":\"error\"') ||\n it.other.includes('\"request_final_status\":\"upstream_error\"')\n )) ||\n Boolean(it.content && it.content.startsWith('status_code='));\n\n return {\n id: it.id || it.request_id || String(Math.random()),\n created_at: Number(it.created_at || Date.now() / 1000),\n model_name: it.model_name || it.marketplace_model_name || '',\n channel: channelId,\n channel_name: it.channel_name || (channelId ? `\u5546\u6237 #${channelId}` : undefined),\n prompt_tokens: Number(it.prompt_tokens || 0),\n completion_tokens: Number(it.completion_tokens || 0),\n use_time: Number(it.use_time || 0),\n quota: rawQuota,\n cost_usd: costUsd,\n cost_formatted: costFormatted,\n token_name: it.token_name || 'API',\n status: isError ? ('error' as const) : ('success' as const),\n other: it.other,\n raw: it,\n };\n });\n }\n }\n } catch (err) {\n console.warn('[dsh-a6api] fetchRecentLogs error:', err);\n }\n return [];\n}\n\n/** Fetch Channel Card details from A6API Marketplace */\nexport async function fetchChannelDetails(\n channelId: number,\n userId?: string,\n sessionCookie?: string,\n targetModelName?: string,\n logSnapshot?: any,\n): Promise<MerchantChannelInfo | null> {\n if (!channelId) return null;\n const targetName = targetModelName || '';\n const meta = resolveModelMeta(targetName);\n\n try {\n const res = await fetch(\n `https://a6api.com/api/marketplace/channels/search?channel_id=${channelId}&view=list&page=1&page_size=20`,\n {\n headers: buildWebHeaders(userId, sessionCookie),\n signal: AbortSignal.timeout(8000),\n },\n );\n if (res.ok) {\n const json = await res.json();\n const items: any[] = json?.data?.items || [];\n if (items.length > 0) {\n // Find match for targetModelName if provided, otherwise first item\n const item =\n (targetName\n ? items.find((it) => it.model_name?.toLowerCase() === targetName.toLowerCase())\n : null) || items[0];\n\n const rate = Number(item.realtime_ratio_exchange_rate || 6.7209);\n const inMicros = Number(item.input_price_micros || 0);\n const outMicros = Number(item.output_price_micros || 0);\n const cacheReadMicros = Number(item.cache_read_price_micros || 0);\n const cacheWriteMicros = Number(item.cache_write_price_micros || 0);\n\n // Parse Smart Routing Labels\n const labels: string[] = [];\n if (item.authenticity_guaranteed) {\n const badge = item.authenticity_guarantee_badge_key;\n if (badge === 'gold') labels.push('\u4FDD\u771F \u00B7 \u91D1\u6807');\n else if (badge === 'silver') labels.push('\u4FDD\u771F \u00B7 \u94F6\u6807');\n else if (badge === 'bronze') labels.push('\u4FDD\u771F \u00B7 \u94DC\u6807');\n else labels.push('\u4FDD\u771F');\n }\n if (Array.isArray(item.smart_routing_labels)) {\n for (const l of item.smart_routing_labels) {\n if (l === 'stable' && !labels.includes('\u7A33\u5B9A')) labels.push('\u7A33\u5B9A');\n if (l === 'cheap' && !labels.includes('\u4F4E\u4EF7')) labels.push('\u4F4E\u4EF7');\n if (l === 'fast' && !labels.includes('\u9AD8\u901F')) labels.push('\u9AD8\u901F');\n if (l === 'quality' && !labels.includes('\u9AD8\u8D28')) labels.push('\u9AD8\u8D28');\n }\n }\n if (labels.length === 0) {\n labels.push('\u7A33\u5B9A', '\u4F4E\u4EF7', '\u9AD8\u901F', '\u9AD8\u8D28');\n }\n\n // Official Prices\n let official_price: OfficialPrices | undefined;\n if (item.official_price && item.official_price.input_price_micros !== undefined) {\n const offIn = Number(item.official_price.input_price_micros || 0);\n const offOut = Number(item.official_price.output_price_micros || 0);\n const offCR = Number(item.official_price.cache_read_price_micros || 0);\n const offCW = Number(item.official_price.cache_write_price_micros || 0);\n official_price = {\n input_price_micros: offIn,\n output_price_micros: offOut,\n cache_read_price_micros: offCR,\n cache_write_price_micros: offCW,\n input_cny: formatCnyPrice(offIn, rate),\n output_cny: formatCnyPrice(offOut, rate),\n cache_read_cny: formatCnyPrice(offCR, rate),\n cache_write_cny: formatCnyPrice(offCW, rate),\n };\n } else if (meta.officialPriceMicros) {\n const offIn = meta.officialPriceMicros.input;\n const offOut = meta.officialPriceMicros.output;\n const offCR = meta.officialPriceMicros.cacheRead;\n const offCW = meta.officialPriceMicros.cacheWrite;\n official_price = {\n input_price_micros: offIn,\n output_price_micros: offOut,\n cache_read_price_micros: offCR,\n cache_write_price_micros: offCW,\n input_cny: formatCnyPrice(offIn, rate),\n output_cny: formatCnyPrice(offOut, rate),\n cache_read_cny: formatCnyPrice(offCR, rate),\n cache_write_cny: formatCnyPrice(offCW, rate),\n };\n }\n\n const successRate24h =\n item.success_rate_24h !== undefined ? Number(item.success_rate_24h) / 100 : 99.3;\n const recentSuccessRate =\n item.recent_success_rate !== undefined ? Number(item.recent_success_rate) / 100 : 100;\n const cacheHitRate =\n item.cache_hit_rate_24h !== undefined ? Number(item.cache_hit_rate_24h) / 100 : 72.0;\n const lastSuccessAt = Number(item.last_success_at || item.last_test_time || 0);\n\n const ratioCny = Number(item.realtime_ratio_cny || (inMicros / 1000000) * rate || 0.0341);\n const ratioFormatted = ratioCny.toFixed(4);\n\n return {\n listing_id: item.listing_id,\n channel_id: item.channel_id,\n channel_name: item.channel_name || `\u5546\u6237 #${channelId}`,\n supplier_name: item.supplier_name || item.supplier_nickname || 'GPT\u4F4E\u4EF7',\n supplier_id: item.supplier_id || 290,\n model_name: item.model_name || targetName,\n brand: item.brand || meta.brand || 'OpenAI',\n description: item.description || '\u9AD8\u5E76\u53D1 \u4E3B\u6253\u4FBF\u5B9C \u7A33\u5B9A',\n charge_type: item.charge_type || 'per_token',\n charge_type_text: item.charge_type === 'per_token' ? '\u6309\u91CF' : '\u6309\u91CF',\n sample_count: Number(item.sample_count || 100),\n sample_count_text: `\u8FD1 ${item.sample_count || 100} \u6B21\u6837\u672C`,\n input_price_micros: inMicros,\n output_price_micros: outMicros,\n cache_read_price_micros: cacheReadMicros,\n cache_write_price_micros: cacheWriteMicros,\n input_price_cny: formatCnyPrice(inMicros, rate),\n output_price_cny: formatCnyPrice(outMicros, rate),\n cache_read_price_cny: formatCnyPrice(cacheReadMicros, rate),\n cache_write_price_cny: formatCnyPrice(cacheWriteMicros, rate),\n official_price,\n realtime_ratio_cny: ratioCny,\n realtime_ratio_formatted: ratioFormatted,\n recent_success_rate_pct: recentSuccessRate,\n success_rate_24h_pct: successRate24h,\n success_rate_7d_pct: item.success_rate_7d !== undefined ? Number(item.success_rate_7d) / 100 : undefined,\n success_buckets: Array.isArray(item.success_buckets) ? item.success_buckets : undefined,\n b24: Array.isArray(item.b24) ? item.b24 : undefined,\n b7d: Array.isArray(item.b7d) ? item.b7d : undefined,\n sr_24h_state: item.sr_24h_state || 'rate',\n sr_7d_state: item.sr_7d_state || 'no_data',\n p50_ttft_ms: Number(item.p50_ttft_ms || 2273),\n recent_p50_ms: Number(item.recent_p50_ms || item.last_test_response_ms || 2340),\n cache_hit_rate_pct: cacheHitRate,\n labels,\n last_success_at: lastSuccessAt,\n last_success_text: formatRelativeTime(lastSuccessAt),\n authenticity_guaranteed: Boolean(item.authenticity_guaranteed),\n authenticity_badge: item.authenticity_guarantee_badge_key,\n is_pinned: Boolean(item.pin_status === 'pinned' || item.is_pinned),\n user_channel_disabled: Boolean(item.user_channel_disabled),\n supplier_channel_disabled: Boolean(item.supplier_channel_disabled),\n raw: item,\n };\n }\n }\n } catch (err) {\n console.warn('[dsh-a6api] fetchChannelDetails error:', err);\n }\n\n // Fallback if we have log snapshot info\n if (logSnapshot) {\n const rate = 6.7209;\n const inMicros = Number(logSnapshot.marketplace_price_input_micros || 20300);\n const outMicros = Number(logSnapshot.marketplace_price_output_micros || 101502);\n const cacheReadMicros = Number(logSnapshot.marketplace_price_cache_read_micros || 2030);\n const cacheWriteMicros = Number(logSnapshot.marketplace_price_cache_write_micros || 25375);\n\n let official_price: OfficialPrices | undefined;\n if (meta.officialPriceMicros) {\n const offIn = meta.officialPriceMicros.input;\n const offOut = meta.officialPriceMicros.output;\n const offCR = meta.officialPriceMicros.cacheRead;\n const offCW = meta.officialPriceMicros.cacheWrite;\n official_price = {\n input_price_micros: offIn,\n output_price_micros: offOut,\n cache_read_price_micros: offCR,\n cache_write_price_micros: offCW,\n input_cny: formatCnyPrice(offIn, rate),\n output_cny: formatCnyPrice(offOut, rate),\n cache_read_cny: formatCnyPrice(offCR, rate),\n cache_write_cny: formatCnyPrice(offCW, rate),\n };\n }\n\n const ratioCny = Number((inMicros / 1000000) * rate || 0.0341);\n\n return {\n listing_id: logSnapshot.marketplace_listing_id,\n channel_id: channelId,\n channel_name: logSnapshot.channel_name || `\u5546\u6237 #${channelId}`,\n supplier_name: logSnapshot.supplier_nickname || logSnapshot.channel_name || 'GPT\u4F4E\u4EF7',\n supplier_id: 290,\n model_name: targetName || logSnapshot.model_name || '',\n brand: meta.brand || 'OpenAI',\n description: '\u9AD8\u5E76\u53D1 \u4E3B\u6253\u4FBF\u5B9C \u7A33\u5B9A',\n charge_type: 'per_token',\n charge_type_text: '\u6309\u91CF',\n sample_count: 100,\n sample_count_text: '\u8FD1 100 \u6B21\u6837\u672C',\n input_price_micros: inMicros,\n output_price_micros: outMicros,\n cache_read_price_micros: cacheReadMicros,\n cache_write_price_micros: cacheWriteMicros,\n input_price_cny: formatCnyPrice(inMicros, rate),\n output_price_cny: formatCnyPrice(outMicros, rate),\n cache_read_price_cny: formatCnyPrice(cacheReadMicros, rate),\n cache_write_price_cny: formatCnyPrice(cacheWriteMicros, rate),\n official_price,\n realtime_ratio_cny: ratioCny,\n realtime_ratio_formatted: ratioCny.toFixed(4),\n recent_success_rate_pct: 100,\n success_rate_24h_pct: 99.3,\n recent_p50_ms: Number(logSnapshot.use_time ? logSnapshot.use_time * 1000 : 2340),\n p50_ttft_ms: 2273,\n cache_hit_rate_pct: 72.0,\n labels: ['\u7A33\u5B9A', '\u4F4E\u4EF7', '\u9AD8\u901F', '\u9AD8\u8D28'],\n last_success_at: Math.floor(Date.now() / 1000),\n last_success_text: '\u521A\u521A',\n authenticity_guaranteed: false,\n is_pinned: false,\n user_channel_disabled: false,\n };\n }\n\n return null;\n}\n/** \u8F7B\u91CF\u62C9\u53D6\u4EF7\u683C\u6CE2\u52A8\u6761\u6570\uFF08\u4EC5 pending/unseen\uFF09 */\nexport async function fetchPriceFluctuation(\n userId?: string,\n sessionCookie?: string,\n accessToken?: string,\n): Promise<{ pendingCount: number; unseenCount: number; totalCount: number; notices?: any[]; authError?: boolean }> {\n const token = (accessToken || sessionCookie || '').trim();\n const uid = (userId || '').trim();\n if (!uid && !token) {\n return { pendingCount: 0, unseenCount: 0, totalCount: 0, authError: false };\n }\n const headers = buildWebHeaders(uid || undefined, token || undefined);\n const url = 'https://a6api.com/api/marketplace/price-notices';\n try {\n const res = await fetch(url, { headers, signal: AbortSignal.timeout(8000) });\n if (res.status === 401 || res.status === 403) {\n console.warn('[dsh-a6api] fetchPriceFluctuation auth failed', res.status);\n return { pendingCount: 0, unseenCount: 0, totalCount: 0, authError: true };\n }\n if (!res.ok) {\n console.warn('[dsh-a6api] fetchPriceFluctuation HTTP', res.status);\n return { pendingCount: 0, unseenCount: 0, totalCount: 0 };\n }\n const json: any = await res.json().catch(() => null);\n if (!json) return { pendingCount: 0, unseenCount: 0, totalCount: 0 };\n if (json.success === false) return { pendingCount: 0, unseenCount: 0, totalCount: 0 };\n\n // \u517C\u5BB9\u591A\u79CD\u8FD4\u56DE\u5F62\u6001\n let arr: any[] = [];\n if (Array.isArray(json)) arr = json;\n else if (Array.isArray(json.data)) arr = json.data;\n else if (Array.isArray(json.data?.notices)) arr = json.data.notices;\n else if (Array.isArray(json.data?.items)) arr = json.data.items;\n else if (Array.isArray(json.notices)) arr = json.notices;\n else if (Array.isArray(json.items)) arr = json.items;\n\n // \u533A\u5206\u201C\u5B57\u6BB5\u7F3A\u5931\u201D vs \u201C\u663E\u5F0F\u4E3A 0\u201D\u2014\u2014\u4EC5\u7F3A\u5931\u65F6\u624D\u515C\u5E95\n const pickWithPresent = (keys: string[]): { value: number; present: boolean } => {\n for (const k of keys) {\n const v = json?.data?.[k] ?? json?.[k];\n if (v !== undefined && v !== null) {\n const n = Number(v);\n if (!Number.isNaN(n)) return { value: n, present: true };\n }\n }\n return { value: 0, present: false };\n };\n const pendingPick = pickWithPresent(['pendingCount', 'pending_count', 'pending', 'openCount']);\n const unseenPick = pickWithPresent(['unseenCount', 'unseen_count', 'unseen', 'has_unseen_count']);\n let pending = pendingPick.value;\n let unseen = unseenPick.value;\n const total = arr.length;\n\n // \u4EC5\u5728\u8BA1\u6570\u952E\u7F3A\u5931\u65F6\u624D\u4ECE\u6570\u7EC4\u515C\u5E95\uFF0C\u907F\u514D\u8986\u76D6 API \u663E\u5F0F 0\n if (!pendingPick.present && arr.length > 0) {\n const counted = arr.filter((n: any) => {\n const s = String(n.state || n.status || '').toLowerCase();\n return s === 'open' || s === 'pending' || n.pending === true;\n }).length;\n // \u4EC5\u5F53\u6570\u7EC4\u6709\u53EF\u8BC6\u522B\u7684 state \u65F6\u624D\u7528 counted\uFF0C\u5426\u5219\u4FDD\u6301 0\uFF08\u4E0D\u731C\u6D4B\uFF09\n const hasState = arr.some((n: any) => n.state !== undefined || n.status !== undefined);\n if (hasState) pending = counted;\n // \u82E5\u65E0 state \u5B57\u6BB5\u4E14 pending \u7F3A\u5931\uFF0C\u4FDD\u6301 0\uFF0C\u4E0D\u518D\u9000\u5316\u4E3A total\n }\n if (!unseenPick.present && arr.length > 0) {\n unseen = arr.filter((n: any) => n.has_unseen === true || n.hasUnseen === true || n.unseen === true || n.is_unread === true).length;\n }\n\n // \u8C03\u8BD5\u65E5\u5FD7\u5DF2\u79FB\u9664\uFF08\u907F\u514D\u672A\u8131\u654F\u900F\u4F20\uFF09\uFF1B\u5982\u9700\u672C\u5730\u8C03\u8BD5\u53EF\u4E34\u65F6\u5F00\u542F DEBUG \u73AF\u5883\u53D8\u91CF\n // if (process.env.DEBUG) console.log('[dsh-a6api] price fluctuation sample', arr[0]);\n\n return { pendingCount: pending, unseenCount: unseen, totalCount: total, notices: arr };\n } catch (err) {\n console.warn('[dsh-a6api] fetchPriceFluctuation error', err);\n return { pendingCount: 0, unseenCount: 0, totalCount: 0 };\n }\n}\n", "import { cleanBaseUrl, fetchChannelDetails, fetchRecentLogs } from './a6api-client.js';\nimport type { ApiRoutingLogItem, MerchantChannelInfo } from '../types.js';\n\nexport interface ProbeResult {\n modelName: string;\n success: boolean;\n channelId?: number;\n channelName?: string;\n merchant?: MerchantChannelInfo | null;\n error?: string;\n durationMs?: number;\n}\n\n/** Delay helper */\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n/** Probe a single model by sending a 1-token prompt and querying logs */\nexport async function probeSingleModel(\n baseURL: string,\n apiKey: string,\n userId?: string,\n accessToken?: string,\n modelName?: string,\n): Promise<ProbeResult> {\n const targetModel = modelName || '';\n const cleanUrl = cleanBaseUrl(baseURL);\n if (!apiKey) {\n return { modelName: targetModel, success: false, error: '\u672A\u914D\u7F6E API Key' };\n }\n\n const startTime = Date.now();\n let requestOk = false;\n let requestError = '';\n\n try {\n const res = await fetch(`${cleanUrl}/v1/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey.trim()}`,\n },\n body: JSON.stringify({\n model: targetModel,\n messages: [{ role: 'user', content: '1' }],\n max_tokens: 1,\n }),\n // \u63A8\u7406\u6A21\u578B(\u5982 grok-4.6)\u5B9E\u6D4B\u5355\u6B21\u54CD\u5E94\u53EF\u8FBE 40-90s+,\u9608\u503C\u8FC7\u77ED\u4F1A\u88AB\u9891\u7E41\u6390\u65AD\u5BFC\u81F4\u63A2\u6D4B\u5931\u8D25\n signal: AbortSignal.timeout(180000),\n });\n\n if (res.ok) {\n requestOk = true;\n } else {\n const errText = await res.text();\n requestError = `HTTP ${res.status}: ${errText.slice(0, 150)}`;\n }\n } catch (err: any) {\n const raw = err?.message || String(err);\n // \u8D85\u65F6\u9519\u8BEF\u82F1\u6587\u539F\u6587\u5BF9\u7528\u6237\u4E0D\u53CB\u597D,\u8F6C\u4E3A\u4E2D\u6587\u63D0\u793A\n if (raw.includes('aborted due to timeout') || err?.name === 'TimeoutError') {\n requestError = '\u63A2\u6D4B\u8D85\u65F6(\u9608\u503C180\u79D2) \u2014 \u63A8\u7406\u6A21\u578B\u54CD\u5E94\u8F83\u6162,\u5DF2\u4FDD\u7559\u4E0A\u6B21\u5546\u6237\u6570\u636E,\u8BF7\u7A0D\u540E\u91CD\u8BD5';\n } else {\n requestError = raw;\n }\n }\n\n const durationMs = Date.now() - startTime;\n\n // \u4EC5\u8BF7\u6C42\u6210\u529F\u540E\u67E5\u65E5\u5FD7,\u5931\u8D25\u65F6\u76F4\u63A5\u8FD4\u56DE\u9519\u8BEF(\u4E0D\u5728\u5361\u7247\u4E0A\u56DE\u9000\u5C55\u793A\u5386\u53F2\u5546\u6237)\n if (requestOk && (userId || accessToken)) {\n // Wait slightly for gateway log writing (\u6162\u6A21\u578B\u8BF7\u6C42\u671F\u95F4\u65E5\u5FD7\u5DF2\u843D\u76D8,\u5FEB\u6A21\u578B\u9700\u8981\u7B49\u5F85)\n await sleep(1200);\n try {\n const logs = await fetchRecentLogs(userId, accessToken, 15);\n const minTimestamp = Math.floor(startTime / 1000) - 10;\n // Find recent log entry for this model\n const log =\n logs.find(\n (it) =>\n it.model_name?.toLowerCase() === targetModel.toLowerCase() &&\n Number(it.created_at || 0) >= minTimestamp,\n ) || logs.find((it) => it.model_name?.toLowerCase() === targetModel.toLowerCase());\n\n if (log && log.channel) {\n const channelId = Number(log.channel);\n let logSnapshot: any = null;\n if (log.other) {\n try {\n logSnapshot = { ...JSON.parse(log.other), channel_name: log.channel_name, model_name: log.model_name };\n } catch {}\n }\n const merchant = await fetchChannelDetails(channelId, userId, accessToken, targetModel, logSnapshot);\n return {\n modelName: targetModel,\n success: true,\n channelId,\n channelName: log.channel_name,\n merchant,\n durationMs,\n };\n }\n } catch (err: any) {\n console.warn(`[dsh-a6api] Log lookup error for ${targetModel}:`, err);\n }\n }\n\n return {\n modelName: targetModel,\n success: requestOk,\n durationMs,\n error: requestOk ? undefined : requestError,\n };\n}\n\n/** Pre-populate merchant cards from recent logs without triggering live probe */\nexport async function getKnownMerchantsFromLogs(\n userId?: string,\n accessToken?: string,\n modelNames: string[] = [],\n logs?: ApiRoutingLogItem[],\n): Promise<Record<string, MerchantChannelInfo>> {\n if ((!userId && !accessToken) || modelNames.length === 0) return {};\n\n const result: Record<string, MerchantChannelInfo> = {};\n try {\n const items = logs !== undefined ? logs : await fetchRecentLogs(userId, accessToken, 50);\n // \u9632\u5FA1\u6027\u6392\u5E8F\uFF1A\u4E0E /state \u7684 lastRoutedMap \u4FDD\u6301\u4E00\u81F4\n const sorted = items.slice().sort((a: any, b: any) => (Number(b.created_at) || 0) - (Number(a.created_at) || 0));\n const modelToLog = new Map<string, any>();\n\n for (const log of sorted) {\n const mName = log.model_name;\n const chId = Number(log.channel);\n if (mName && chId && !modelToLog.has(mName.toLowerCase())) {\n modelToLog.set(mName.toLowerCase(), log);\n }\n }\n\n const matchedEntries: { modelName: string; log: any }[] = [];\n for (const name of modelNames) {\n const log = modelToLog.get(name.toLowerCase());\n if (log) {\n matchedEntries.push({ modelName: name, log });\n }\n }\n\n // Fetch details with concurrency limit 4\n for (let i = 0; i < matchedEntries.length; i += 4) {\n const batch = matchedEntries.slice(i, i + 4);\n await Promise.all(\n batch.map(async ({ modelName, log }) => {\n try {\n const channelId = Number(log.channel);\n let logSnapshot: any = null;\n if (log.other) {\n try {\n logSnapshot = { ...JSON.parse(log.other), channel_name: log.channel_name, model_name: log.model_name };\n } catch {}\n }\n const card = await fetchChannelDetails(channelId, userId, accessToken, modelName, logSnapshot);\n if (card) {\n result[modelName] = card;\n }\n } catch {\n // ignore\n }\n }),\n );\n }\n } catch (err) {\n console.warn('[dsh-a6api] getKnownMerchantsFromLogs error:', err);\n }\n\n return result;\n}\n", "import * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { resolveModelMeta } from './catalog.js';\nimport type { A6ApiConfig } from '../types.js';\n\nexport const A6API_CRED_REF = 'A6API_API_KEY';\n\n/** \u539F\u5B50\u5199\u5165\uFF1A\u5148\u5199\u4E34\u65F6\u6587\u4EF6\uFF080600/0644\uFF09\u518D rename\uFF0C\u907F\u514D\u5D29\u6E83\u622A\u65AD\u4E0E\u6743\u9650\u4F4D\u6CC4\u9732 */\nasync function atomicWriteFile(filePath: string, content: string, mode = 0o600): Promise<void> {\n const dir = path.dirname(filePath);\n await fsp.mkdir(dir, { recursive: true });\n const tmpPath = path.join(dir, `.${path.basename(filePath)}.${process.pid}.${Date.now()}.tmp`);\n await fsp.writeFile(tmpPath, content, { mode });\n await fsp.rename(tmpPath, filePath);\n}\n\nfunction dshHome(): string {\n return process.env.DSH_HOME || path.join(os.homedir(), '.dsh');\n}\n\nfunction configFile(): string {\n return path.join(dshHome(), 'dsh-a6api-config.json');\n}\n\nfunction credentialsFile(): string {\n return path.join(dshHome(), '.credentials.yaml');\n}\n\nfunction settingsFile(): string {\n return path.join(dshHome(), 'settings.yaml');\n}\n\n/** Read plugin dedicated config */\nexport async function readPluginConfig(): Promise<A6ApiConfig> {\n const filePath = configFile();\n let raw = '';\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n // try reading default credential if exists\n const apiKey = (await readCredentialKey(A6API_CRED_REF)) || '';\n return {\n baseURL: 'https://api.a6api.com',\n apiKey,\n userId: '',\n activeModels: [],\n };\n }\n\n try {\n const parsed = JSON.parse(raw);\n const apiKey = parsed.apiKey || (await readCredentialKey(A6API_CRED_REF)) || '';\n const accessToken = parsed.accessToken || parsed.systemAccessToken || parsed.sessionCookie || '';\n return {\n baseURL: parsed.baseURL || 'https://api.a6api.com',\n apiKey,\n accessToken,\n userId: parsed.userId || '',\n sessionCookie: accessToken,\n activeModels: Array.isArray(parsed.activeModels) ? parsed.activeModels : [],\n customBaseURL: parsed.customBaseURL,\n };\n } catch {\n return {\n baseURL: 'https://api.a6api.com',\n apiKey: '',\n accessToken: '',\n userId: '',\n activeModels: [],\n };\n }\n}\n\n/** Save plugin dedicated config\uFF08\u5BC6\u94A5\u5355\u4E00\u771F\u76F8\u6E90\u5728 ~/.dsh/.credentials.yaml\uFF0C\u914D\u7F6E JSON \u4E0D\u518D\u5197\u4F59\u660E\u6587\uFF09 */\nexport async function savePluginConfig(config: A6ApiConfig): Promise<void> {\n const filePath = configFile();\n const { apiKey: _apiKey, ...safeConfig } = config;\n await atomicWriteFile(filePath, JSON.stringify(safeConfig, null, 2));\n\n // Also sync credential\n if (config.apiKey && config.apiKey.trim()) {\n await writeCredentialKey(A6API_CRED_REF, config.apiKey.trim());\n }\n}\n\n/** Read a key from .credentials.yaml */\nexport async function readCredentialKey(refKey: string): Promise<string | null> {\n try {\n const yaml = await fsp.readFile(credentialsFile(), 'utf8');\n let inRefs = false;\n for (const line of yaml.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (indent === 0) {\n inRefs = trimmed.startsWith('refs:');\n continue;\n }\n if (!inRefs) continue;\n const m = /^([A-Za-z0-9_.\\-]+):\\s*(.*)$/.exec(trimmed);\n if (m && m[1] === refKey) {\n let val = m[2].trim();\n if ((val.startsWith('\"') && val.endsWith('\"')) || (val.startsWith(\"'\") && val.endsWith(\"'\"))) {\n val = val.slice(1, -1);\n }\n return val;\n }\n }\n } catch {}\n return null;\n}\n\n/** Write/update a key in .credentials.yaml */\nexport async function writeCredentialKey(refKey: string, value: string): Promise<void> {\n const cFile = credentialsFile();\n let yaml = '';\n try {\n yaml = await fsp.readFile(cFile, 'utf8');\n } catch {\n yaml = 'version: 1\\nrefs:\\n';\n }\n\n const lines = yaml.split(/\\r?\\n/);\n let inRefs = false;\n let refsLineIdx = -1;\n let found = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (indent === 0) {\n if (trimmed.startsWith('refs:')) {\n inRefs = true;\n refsLineIdx = i;\n } else {\n inRefs = false;\n }\n continue;\n }\n if (inRefs) {\n const m = /^([A-Za-z0-9_.\\-]+):/.exec(trimmed);\n if (m && m[1] === refKey) {\n lines[i] = ` ${refKey}: ${JSON.stringify(value)}`;\n found = true;\n break;\n }\n }\n }\n\n if (!found) {\n if (refsLineIdx >= 0) {\n lines.splice(refsLineIdx + 1, 0, ` ${refKey}: ${JSON.stringify(value)}`);\n } else {\n lines.push('refs:', ` ${refKey}: ${JSON.stringify(value)}`);\n }\n }\n\n await atomicWriteFile(cFile, lines.join('\\n'), 0o600);\n}\n\n/** Sync active models to DSH settings.yaml under llm-pi-ai.providers.a6api */\nexport async function syncToDshSettings(baseURL: string, modelIds: string[]): Promise<void> {\n const sFile = settingsFile();\n let yaml = '';\n try {\n yaml = await fsp.readFile(sFile, 'utf8');\n } catch {\n yaml = 'llm-pi-ai:\\n providers:\\n';\n }\n\n // Build the YAML block for models\n const modelEntries = modelIds.map((id) => {\n const meta = resolveModelMeta(id);\n const lines = [\n ` - id: ${meta.id}`,\n ` name: ${meta.name}`,\n ` contextWindow: ${meta.contextWindow}`,\n ` maxTokens: ${meta.maxTokens}`,\n ` input:`,\n ...meta.modalities.map((m) => ` - ${m}`),\n ];\n if (meta.reasoningEfforts) {\n lines.push(` reasoningEfforts:`);\n for (const [k, v] of Object.entries(meta.reasoningEfforts)) {\n if (v) lines.push(` ${k}: ${v}`);\n }\n }\n return lines.join('\\n');\n });\n\n // Ensure OpenAI compatible endpoints in DSH settings.yaml have the /v1 suffix\n const dshBaseUrl = baseURL.endsWith('/v1') ? baseURL : `${baseURL.replace(/\\/+$/, '')}/v1`;\n\n const a6apiBlockLines = [\n ` a6api:`,\n ` displayName: A6API`,\n ` apiKeyEnv: ${A6API_CRED_REF}`,\n ` api: openai-completions`,\n ` baseURL: ${dshBaseUrl}`,\n ` models:`,\n ...(modelEntries.length > 0 ? modelEntries : [` []`]),\n ];\n\n // Look for `llm-pi-ai:` -> `providers:` -> `a6api:`\n const lines = yaml.split(/\\r?\\n/);\n let inLlm = false;\n let inProviders = false;\n let inA6 = false;\n let a6Start = -1;\n let a6End = -1;\n let providersLineIdx = -1;\n let llmLineIdx = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n\n if (indent === 0) {\n inLlm = trimmed.startsWith('llm-pi-ai:');\n if (inLlm) llmLineIdx = i;\n inProviders = false;\n inA6 = false;\n continue;\n }\n\n if (inLlm && indent === 2 && trimmed.startsWith('providers:')) {\n inProviders = true;\n providersLineIdx = i;\n inA6 = false;\n continue;\n }\n\n if (inProviders && indent === 4) {\n if (trimmed.startsWith('a6api:')) {\n inA6 = true;\n a6Start = i;\n a6End = i + 1;\n } else {\n if (inA6) {\n a6End = i;\n inA6 = false;\n }\n }\n continue;\n }\n\n if (inA6 && indent > 4) {\n a6End = i + 1;\n } else if (inA6 && indent <= 4) {\n a6End = i;\n inA6 = false;\n }\n }\n\n if (a6Start >= 0) {\n // Replace existing a6api block\n lines.splice(a6Start, a6End - a6Start, ...a6apiBlockLines);\n } else if (providersLineIdx >= 0) {\n // Insert under providers:\n lines.splice(providersLineIdx + 1, 0, ...a6apiBlockLines);\n } else if (llmLineIdx >= 0) {\n // Insert providers: then a6api\n lines.splice(llmLineIdx + 1, 0, ` providers:`, ...a6apiBlockLines);\n } else {\n // Insert llm-pi-ai: providers: a6api\n lines.push(`llm-pi-ai:`, ` providers:`, ...a6apiBlockLines);\n }\n\n await atomicWriteFile(sFile, lines.join('\\n'), 0o644);\n}\n\n/** Get currently configured model IDs in DSH settings for a6api */\nexport async function getDshConfiguredModels(): Promise<string[]> {\n try {\n const yaml = await fsp.readFile(settingsFile(), 'utf8');\n const lines = yaml.split(/\\r?\\n/);\n let inA6 = false;\n let inModels = false;\n const modelIds: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (indent === 4 && trimmed.startsWith('a6api:')) {\n inA6 = true;\n inModels = false;\n continue;\n }\n if (inA6 && indent <= 4 && !trimmed.startsWith('a6api:')) {\n inA6 = false;\n inModels = false;\n }\n if (inA6 && indent === 6 && trimmed.startsWith('models:')) {\n inModels = true;\n continue;\n }\n if (inModels && indent === 8 && trimmed.startsWith('- id:')) {\n const id = trimmed.replace(/^- id:\\s*/, '').trim();\n if (id) modelIds.push(id);\n }\n }\n return modelIds;\n } catch {\n return [];\n }\n}\n", "import { fetchBalance, fetchTokenModels, fetchRecentLogs, fetchPriceFluctuation, formatRelativeTime } from './server/a6api-client.js';\nimport { getKnownMerchantsFromLogs, probeSingleModel } from './server/probe.js';\nimport { resolveModelMeta } from './server/catalog.js';\nimport {\n getDshConfiguredModels,\n readPluginConfig,\n savePluginConfig,\n syncToDshSettings,\n} from './server/sync.js';\nimport type { A6ApiConfig, A6ApiStateResponse, MerchantChannelInfo, ModelCardData } from './types.js';\n\nexport const name = '@lynn123411/dsh-a6api';\nexport const inject = ['webServer'];\n\nexport {\n fetchBalance,\n fetchTokenModels,\n fetchRecentLogs,\n fetchChannelDetails,\n} from './server/a6api-client.js';\nexport { probeSingleModel, getKnownMerchantsFromLogs } from './server/probe.js';\nexport { resolveModelMeta, A6API_CATALOG } from './server/catalog.js';\nexport { readPluginConfig, savePluginConfig, syncToDshSettings } from './server/sync.js';\n\nconst PREFIX = '/api/dsh-a6api';\n\n/** \u5BA2\u6237\u7AEF\u8131\u654F\u5360\u4F4D\u7B26\uFF1A\u670D\u52A1\u7AEF\u7EDD\u4E0D\u56DE\u4F20\u771F\u5B9E\u5BC6\u94A5 */\nconst MASK = '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022';\n\n/** \u8131\u654F\u914D\u7F6E\uFF1AAPI Key / \u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C / userId \u4EC5\u4EE5\u5360\u4F4D\u7B26\u5F62\u5F0F\u4E0B\u53D1\uFF0C\u771F\u5B9E\u503C\u53EA\u5B58\u5728\u4E8E\u670D\u52A1\u7AEF */\nfunction maskConfig(c: A6ApiConfig): A6ApiConfig {\n return {\n ...c,\n apiKey: c.apiKey ? MASK : '',\n accessToken: c.accessToken || c.sessionCookie ? MASK : '',\n sessionCookie: '',\n userId: c.userId ? MASK : '',\n hasApiKey: Boolean(c.apiKey),\n hasToken: Boolean(c.accessToken || c.sessionCookie),\n };\n}\n\nfunction sendJson(res: any, status: number, body: any) {\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'no-cache',\n // \u4E0D\u8BBE access-control-allow-origin\uFF1A\u4EC5\u5141\u8BB8\u540C\u6E90\u8C03\u7528\uFF0C\u963B\u65AD\u8DE8\u7AD9\u8BFB\u53D6\u4E0E CSRF \u9884\u68C0\n });\n res.end(JSON.stringify(body));\n}\n\nfunction readBody(req: any): Promise<string> {\n return new Promise((resolve, reject) => {\n let data = '';\n req.on('data', (chunk: any) => {\n data += chunk;\n if (data.length > 2 * 1024 * 1024) {\n req.destroy();\n reject(new Error('Body too large'));\n }\n });\n req.on('end', () => resolve(data.trim()));\n req.on('error', reject);\n });\n}\n\nasync function parseJsonBody(req: any): Promise<any> {\n const text = await readBody(req);\n if (!text) return {};\n try {\n return JSON.parse(text);\n } catch {\n throw new Error('Invalid JSON body');\n }\n}\n\n// In-memory cache for merchant cards to avoid duplicate log calls\nconst merchantCardCache = new Map<string, { card: MerchantChannelInfo; at: number }>();\n/** \u5361\u7247\u7F13\u5B58\u6709\u6548\u671F:\u8FC7\u671F\u540E /state \u4ECE\u6700\u65B0\u65E5\u5FD7\u91CD\u65B0\u63A8\u5BFC,\u907F\u514D\u6C38\u8FDC\u5C55\u793A\u9648\u65E7\u5546\u6237 */\nconst MERCHANT_CARD_TTL_MS = 15 * 60 * 1000;\n\nexport function apply(ctx: any): void {\n // Register Web API routes\n const webServer = ctx.webServer || (ctx.get ? ctx.get('webServer') : null);\n if (webServer && typeof webServer.register === 'function') {\n ctx.effect(() => {\n const unregister = webServer.register({\n kind: 'prefix',\n path: PREFIX,\n handler: async (req: any, res: any) => {\n const url = new URL(req.url || '/', 'http://localhost');\n const pathname = url.pathname.replace(PREFIX, '') || '/';\n\n // CORS preflight\uFF1A\u540C\u6E90\u7B56\u7565\u4E0B\u65E0\u9700\u653E\u884C\u8DE8\u6E90\uFF08\u79FB\u9664 ACAO \u540E\u8DE8\u6E90\u9884\u68C0\u5929\u7136\u5931\u8D25\uFF09\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n return res.end();\n }\n\n try {\n // GET /state\n if (pathname === '/state' && (req.method === 'GET' || req.method === 'HEAD')) {\n const config = await readPluginConfig();\n const token = config.accessToken || config.sessionCookie || '';\n const balance = await fetchBalance(config.baseURL, config.apiKey, config.userId, token);\n \n // Auto-persist discovered userId\n if (balance?.userId && String(balance.userId) !== config.userId) {\n config.userId = String(balance.userId);\n await savePluginConfig(config);\n }\n\n const dshConfiguredModels = await getDshConfiguredModels();\n\n // Fetch allowed model IDs for this token\n let modelIds: string[] = [];\n if (config.apiKey) {\n modelIds = await fetchTokenModels(config.baseURL, config.apiKey);\n }\n\n // Fallback to active/configured models if token query returned empty\n if (modelIds.length === 0) {\n modelIds = [\n ...new Set([\n ...config.activeModels,\n ...dshConfiguredModels,\n 'gpt-5.6-sol',\n 'gpt-5.6-terra',\n 'gpt-5.6-luna',\n 'claude-fable-5',\n 'claude-opus-5',\n 'grok-4.6',\n ]),\n ];\n }\n\n // \u4E00\u6B21\u62C9\u53D6\u65E5\u5FD7(\u63A5\u53E3\u5B9E\u6D4B\u4E0A\u9650 100 \u6761),\u540C\u4E00\u4EFD\u6570\u636E\u7528\u4E8E: \u2460\u5546\u6237\u5361\u7247\u9884\u586B\u5145 \u2461\u8DEF\u7531\u5FEB\u7167\u65F6\u6548\u6620\u5C04 \u2462Account \u9875\u6700\u8FD1\u660E\u7EC6\n const allLogs = await fetchRecentLogs(config.userId, token, 100);\n // \u9632\u5FA1\u6027\u6392\u5E8F\uFF1A\u4F9D\u8D56\u201C\u6700\u65B0\u5728\u524D\u201D\uFF0C\u82E5\u7F51\u5173\u6392\u5E8F\u53D8\u66F4\u4ECD\u80FD\u6B63\u786E\u53D6\u9996\u6761\n allLogs.sort((a, b) => (Number(b.created_at) || 0) - (Number(a.created_at) || 0));\n\n // Match known merchant cards from recent logs if not yet in cache (with 10s total timeout to avoid /state hang)\n if (config.userId || token) {\n const missing = modelIds.filter((m) => {\n const entry = merchantCardCache.get(m.toLowerCase());\n return !entry || Date.now() - entry.at >= MERCHANT_CARD_TTL_MS;\n });\n if (missing.length > 0) {\n let found: Record<string, MerchantChannelInfo> = {};\n try {\n found = await Promise.race([\n getKnownMerchantsFromLogs(config.userId, token, missing, allLogs),\n new Promise<Record<string, MerchantChannelInfo>>((resolve) => setTimeout(() => resolve({}), 10000)),\n ]);\n } catch {\n found = {};\n }\n for (const [mName, card] of Object.entries(found)) {\n merchantCardCache.set(mName.toLowerCase(), { card, at: Date.now() });\n }\n }\n }\n\n // \u8DEF\u7531\u5FEB\u7167\u65F6\u6548: \u6BCF\u4E2A\u6A21\u578B\u6700\u65B0\u4E00\u6761\u300C\u5E26 channel \u7684\u8C03\u7528\u65E5\u5FD7\u300D\u65F6\u95F4 \u2014\u2014 \u4E0E\u9884\u586B\u5145\u5361\u7247\u5546\u6237\u6570\u636E\u540C\u4E00\u6761\u89C4\u5219(\u53D6\u6700\u65B0\u547D\u4E2D\u5546\u6237\u8DEF\u7531\u7684\u8BF7\u6C42)\n const lastRoutedMap = new Map<string, number>();\n for (const log of allLogs) {\n const mName = log.model_name;\n const chId = Number(log.channel);\n const ts = Number(log.created_at) || 0;\n if (mName && chId > 0 && ts > 0 && !lastRoutedMap.has(mName.toLowerCase())) {\n lastRoutedMap.set(mName.toLowerCase(), ts);\n }\n }\n\n const dshSet = new Set(dshConfiguredModels);\n const models: ModelCardData[] = modelIds.map((mId) => {\n const meta = resolveModelMeta(mId);\n const cacheEntry = merchantCardCache.get(mId.toLowerCase());\n const cachedCard =\n cacheEntry && Date.now() - cacheEntry.at < MERCHANT_CARD_TTL_MS\n ? cacheEntry.card\n : undefined;\n const routedAt = lastRoutedMap.get(mId.toLowerCase());\n return {\n model_name: mId,\n brand: meta.brand,\n contextWindow: meta.contextWindow,\n maxTokens: meta.maxTokens,\n modalities: meta.modalities,\n hasReasoning: Boolean(meta.reasoningEfforts || meta.thinkingFormat),\n inDsh: dshSet.has(mId),\n merchant: cachedCard,\n probeStatus: cachedCard ? 'success' : 'idle',\n lastRoutedAt: routedAt,\n lastRoutedText: routedAt ? formatRelativeTime(routedAt) : undefined,\n };\n });\n\n // Account \u9875\u660E\u7EC6\u4FDD\u6301\u539F\u6709\u7A97\u53E3 (20 \u6761)\n const recentLogs = allLogs.slice(0, 20);\n\n const response: A6ApiStateResponse = {\n config: maskConfig(config),\n balance,\n models,\n dshConfiguredModels,\n recentLogs,\n };\n return sendJson(res, 200, { ok: true, data: response });\n }\n\n // POST /config\n if (pathname === '/config' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const current = await readPluginConfig();\n const rawToken =\n body.accessToken !== undefined && body.accessToken !== MASK\n ? body.accessToken\n : body.sessionCookie !== undefined && body.sessionCookie !== MASK\n ? body.sessionCookie\n : (current.accessToken || current.sessionCookie || '');\n const newApiKey =\n body.apiKey !== undefined && body.apiKey !== MASK ? body.apiKey : current.apiKey;\n\n const updated: A6ApiConfig = {\n baseURL: body.baseURL !== undefined ? body.baseURL : current.baseURL,\n apiKey: newApiKey,\n accessToken: rawToken,\n sessionCookie: rawToken,\n userId: body.userId !== undefined ? body.userId : current.userId,\n activeModels: Array.isArray(body.activeModels) ? body.activeModels : current.activeModels,\n customBaseURL: body.customBaseURL !== undefined ? body.customBaseURL : current.customBaseURL,\n };\n\n // Validate access token and auto-fetch balance & userId\n const balance = await fetchBalance(updated.baseURL, updated.apiKey, updated.userId, updated.accessToken);\n if (balance?.userId) {\n updated.userId = String(balance.userId);\n }\n\n await savePluginConfig(updated);\n\n // If active models exist, sync to DSH settings as well\n if (updated.activeModels.length > 0) {\n await syncToDshSettings(updated.baseURL, updated.activeModels);\n }\n return sendJson(res, 200, { ok: true, config: maskConfig(updated), balance });\n }\n\n // GET /balance\n if (pathname === '/balance' && (req.method === 'GET' || req.method === 'HEAD')) {\n const config = await readPluginConfig();\n const token = config.accessToken || config.sessionCookie || '';\n const balance = await fetchBalance(config.baseURL, config.apiKey, config.userId, token);\n const recentLogs = await fetchRecentLogs(config.userId, token, 20);\n return sendJson(res, 200, { ok: true, balance, recentLogs });\n }\n\n // GET /logs\n if (pathname === '/logs' && (req.method === 'GET' || req.method === 'HEAD')) {\n const config = await readPluginConfig();\n const token = config.accessToken || config.sessionCookie || '';\n const recentLogs = await fetchRecentLogs(config.userId, token, 30);\n return sendJson(res, 200, { ok: true, logs: recentLogs });\n }\n\n // POST /probe\n if (pathname === '/probe' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const config = await readPluginConfig();\n const token = config.accessToken || config.sessionCookie || '';\n const modelName = body.modelName;\n\n if (modelName && modelName !== 'all') {\n const result = await probeSingleModel(config.baseURL, config.apiKey, config.userId, token, modelName);\n if (result.merchant) {\n merchantCardCache.set(modelName.toLowerCase(), { card: result.merchant, at: Date.now() });\n }\n return sendJson(res, 200, { ok: true, result });\n }\n\n // Probe all models in token\n let modelIds: string[] = body.modelNames;\n if (!Array.isArray(modelIds) || modelIds.length === 0) {\n modelIds = await fetchTokenModels(config.baseURL, config.apiKey);\n }\n if (modelIds.length === 0) {\n modelIds = config.activeModels;\n }\n\n const results = [];\n for (const m of modelIds) {\n const r = await probeSingleModel(config.baseURL, config.apiKey, config.userId, token, m);\n if (r.merchant) {\n merchantCardCache.set(m.toLowerCase(), { card: r.merchant, at: Date.now() });\n }\n results.push(r);\n }\n\n return sendJson(res, 200, { ok: true, results });\n }\n\n // POST /sync-models\n if (pathname === '/sync-models' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const config = await readPluginConfig();\n const modelIds = Array.isArray(body.modelIds) ? body.modelIds : [];\n const baseURL = body.baseURL || config.baseURL;\n\n config.activeModels = modelIds;\n config.baseURL = baseURL;\n await savePluginConfig(config);\n await syncToDshSettings(baseURL, modelIds);\n\n const dshConfiguredModels = await getDshConfiguredModels();\n return sendJson(res, 200, { ok: true, dshConfiguredModels });\n }\n\n // GET /price-fluctuation \u2014 \u8F7B\u91CF\u4EF7\u683C\u6CE2\u52A8\u6761\u6570\uFF08\u5F85\u5904\u7406 n\uFF09\uFF0C\u4EC5\u56DE\u4F20\u8BA1\u6570\n if (pathname === '/price-fluctuation' && (req.method === 'GET' || req.method === 'HEAD')) {\n const config = await readPluginConfig();\n const token = config.accessToken || config.sessionCookie || '';\n if (!token || !config.userId) {\n return sendJson(res, 200, { ok: true, data: { pendingCount: 0, unseenCount: 0, totalCount: 0, hasAuth: false, authError: false, updatedAt: Date.now() } });\n }\n const result = await fetchPriceFluctuation(config.userId, token, token);\n const { notices, ...counts } = result as any;\n // 401/403 \u65F6 authError=true\uFF0C\u5BA2\u6237\u7AEF\u53EF\u533A\u5206\u201C\u672A\u914D\u7F6E\u201D\u4E0E\u201C\u5931\u6548\u201D\n const hasAuth = !counts.authError;\n return sendJson(res, 200, { ok: true, data: { pendingCount: counts.pendingCount, unseenCount: counts.unseenCount, totalCount: counts.totalCount, hasAuth, authError: Boolean(counts.authError), updatedAt: Date.now() } });\n }\n\n return sendJson(res, 404, { ok: false, error: 'Not found' });\n } catch (err: any) {\n console.error('[dsh-a6api] API error:', err);\n return sendJson(res, 500, { ok: false, error: err?.message || String(err) });\n }\n },\n });\n\n return () => {\n if (typeof unregister === 'function') unregister();\n };\n }, 'dsh-a6api: web API router');\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["name", "lines"]
|
|
3
|
+
"sources": ["../src/server/catalog.ts", "../src/server/a6api-client.ts", "../src/server/probe.ts", "../src/server/sync.ts", "../src/types.ts", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import fs from 'node:fs';\nimport fsp from 'node:fs/promises';\nimport path from 'node:path';\nimport os from 'node:os';\nimport type { A6ApiModelMeta, CatalogModelEntry } from '../types.js';\n\n/**\n * \u6A21\u578B\u76EE\u5F55\uFF08\u8FD0\u884C\u65F6\u6570\u636E\uFF0C\u53D6\u4EE3\u65E7\u7684\u9759\u6001 A6API_CATALOG\uFF09\u3002\n *\n * - \u6301\u4E45\u5316\uFF1A`$DSH_HOME/dsh-a6api-catalog.json`\uFF08\u7ED3\u6784 `{ version: 1, entries: [...] }`\uFF09\uFF0C\n * \u521D\u59CB\u4E3A\u7A7A\uFF1B\u300C\u6A21\u578B\u76EE\u5F55\u300D\u9875\u4ECE A6API \u5E02\u573A\u62C9\u53D6\u6A21\u578B ID\u3001\u4ECE OpenRouter \u67E5\u8BE2\u53C2\u6570\u540E\u5EFA\u7ACB\u3002\n * - \u6761\u76EE\u5B57\u6BB5 = DSH settings.yaml \u7684 llm-pi-ai \u539F\u751F\u6A21\u578B\u5B57\u6BB5\uFF08id/name/contextWindow/\n * maxTokens/input/reasoningEfforts\uFF09\uFF0C\u5916\u52A0\u5185\u90E8\u9644\u5E26\u7684 brand\uFF08\u6765\u81EA A6API \u5E02\u573A\u6E20\u9053\uFF0C\n * \u4EC5\u7528\u4E8E\u53EF\u7528\u6A21\u578B\u5361\u7247\u5C55\u793A\uFF0C\u4E0D\u5199\u5165 settings.yaml\uFF09\u3002\n * - \u76EE\u5F55\u4E3A\u552F\u4E00\u53C2\u6570\u771F\u76F8\u6E90\uFF1A\u300C\u53EF\u7528\u6A21\u578B\u300D\u9875\u5199\u5165 settings.yaml \u65F6\u4ECE\u6B64\u53D6\u5B57\u6BB5\uFF0C\u7F3A\u5219\u7701\u7565\n * \uFF08\u7531 llm-pi-ai \u9ED8\u8BA4\u503C\u515C\u5E95\uFF09\uFF0C\u4E0D\u518D\u6709\u4EFB\u4F55\u5185\u7F6E\u624B\u5199\u9ED8\u8BA4\u53C2\u6570\u3002\n */\n\nconst CATALOG_VERSION = 1;\n\nfunction dshHome(): string {\n return process.env.DSH_HOME || path.join(os.homedir(), '.dsh');\n}\n\nexport function catalogFile(): string {\n return path.join(dshHome(), 'dsh-a6api-catalog.json');\n}\n\n/** \u8FDB\u7A0B\u5185\u7F13\u5B58\uFF1AresolveModelMeta \u7B49\u540C\u6B65\u8DEF\u5F84\u76F4\u63A5\u8BFB\u5185\u5B58 */\nlet catalogCache: CatalogModelEntry[] | null = null;\n\nfunction ensureLoaded(): CatalogModelEntry[] {\n if (catalogCache) return catalogCache;\n try {\n const raw = fs.readFileSync(catalogFile(), 'utf8');\n const j = JSON.parse(raw);\n // \u5F62\u72B6\u8FC7\u6EE4\uFF1A\u8DF3\u8FC7\u65E0\u5B57\u7B26\u4E32 id \u7684\u635F\u574F\u6761\u76EE\uFF0C\u907F\u514D getCatalogEntry \u7684 .toLowerCase() \u629B\u9519\u62D6\u57AE /state\n catalogCache = Array.isArray(j?.entries)\n ? j.entries.filter((e: any) => e && typeof e.id === 'string')\n : [];\n } catch {\n catalogCache = [];\n }\n const loaded = catalogCache as CatalogModelEntry[];\n return loaded;\n}\n\nexport function getCatalog(): CatalogModelEntry[] {\n return ensureLoaded();\n}\n\nexport function getCatalogEntry(id: string): CatalogModelEntry | undefined {\n const t = id.toLowerCase();\n return ensureLoaded().find((e) => e.id.toLowerCase() === t);\n}\n\n/**\n * \u76EE\u5F55\u5199\u64CD\u4F5C\u4E32\u884C\u961F\u5217\uFF1Afetch-models / query-openrouter / update / clear \u5171\u4EAB\u540C\u4E00\u5199\u94FE\uFF0C\n * \u907F\u514D\u8BFB-\u6539-\u5199\u4EA4\u9519\u4E22\u66F4\u65B0\uFF08\u5982\u300C\u7F16\u8F91\u4FDD\u5B58\u300D\u4E0E\u300C\u4E00\u952E\u67E5\u8BE2\u300D\u5E76\u53D1\u65F6\u540E\u5199\u8005\u8986\u76D6\u5148\u5199\u8005\uFF09\u3002\n */\nlet writeChain: Promise<void> = Promise.resolve();\n\nfunction enqueueWrite(fn: () => Promise<void>): Promise<void> {\n const next = writeChain.then(fn, fn);\n writeChain = next.then(\n () => {},\n () => {},\n );\n return next;\n}\n\n/** \u539F\u5B50\u5199\u76D8\uFF08tmp+rename\uFF09\u6210\u529F\u540E\u624D\u66F4\u65B0\u5185\u5B58\u7F13\u5B58\uFF1B\u5199\u5931\u8D25\u65F6\u7F13\u5B58\u4FDD\u6301\u4E0E\u78C1\u76D8\u4E00\u81F4\u7684\u65E7\u503C */\nasync function writeCatalog(entries: CatalogModelEntry[]): Promise<void> {\n const file = catalogFile();\n await fsp.mkdir(path.dirname(file), { recursive: true });\n const tmp = `${file}.tmp`;\n await fsp.writeFile(tmp, JSON.stringify({ version: CATALOG_VERSION, entries }, null, 2), {\n encoding: 'utf8',\n mode: 0o644,\n });\n await fsp.rename(tmp, file);\n catalogCache = entries;\n}\n\n/** \u5408\u5E76\u65B0\u589E\u6761\u76EE\uFF08\u4E0D\u8986\u76D6\u5DF2\u6709\u6761\u76EE\u7684\u65E2\u6709\u5B57\u6BB5\uFF1B\u4EC5\u8865\u7F3A\u5931\u5B57\u6BB5\uFF0C\u53C2\u6570\u4EE5\u7528\u6237\u5DF2\u4FDD\u5B58/\u67E5\u8BE2\u5230\u7684\u4E3A\u51C6\uFF09\u3002\n * undefined \u5B57\u6BB5\u4E0D\u53C2\u4E0E\u5408\u5E76\uFF08\u907F\u514D\u8986\u76D6\u5DF2\u6709\u503C\uFF09\uFF1B\u6309\u5C0F\u5199 id \u53BB\u91CD\uFF08\u4FDD\u7559\u9996\u4E2A casing\uFF0C\u907F\u514D\u5927\u5C0F\u5199\u5E7D\u7075\u91CD\u590D\uFF09\u3002 */\nexport async function upsertCatalogEntries(entries: CatalogModelEntry[]): Promise<void> {\n await enqueueWrite(async () => {\n const cur = ensureLoaded();\n const map = new Map<string, CatalogModelEntry>();\n for (const e of cur) map.set(e.id.toLowerCase(), e);\n for (const e of entries) {\n const clean = Object.fromEntries(Object.entries(e).filter(([, v]) => v !== undefined)) as CatalogModelEntry;\n const key = clean.id.toLowerCase();\n const prev = map.get(key);\n map.set(key, prev ? { ...prev, ...clean } : clean);\n }\n await writeCatalog([...map.values()]);\n });\n}\n\n/** \u6E05\u7A7A\u76EE\u5F55\uFF08\u91CD\u65B0\u4ECE A6API \u62C9\u53D6/OpenRouter \u586B\u5145\u524D\u4F7F\u7528\uFF09\u3002settings.yaml \u5DF2\u542F\u7528\u6761\u76EE\u4E0D\u53D7\u5F71\u54CD */\nexport async function clearCatalog(): Promise<void> {\n await enqueueWrite(async () => {\n await writeCatalog([]);\n });\n}\n\n/** \u5168\u91CF\u66FF\u6362\u5F0F\u66F4\u65B0\u5355\u4E2A\u6761\u76EE\uFF08\u6A21\u578B\u76EE\u5F55\u9875\u4FDD\u5B58\u4FEE\u6539\u7528\uFF09\uFF1Bpatch \u4E2D\u503C\u4E3A null \u7684\u5B57\u6BB5 = \u5220\u9664\u8BE5\u5B57\u6BB5\u3002\u8FD4\u56DE\u66F4\u65B0\u540E\u7684\u6761\u76EE */\nexport async function updateCatalogEntry(\n id: string,\n patch: Partial<Omit<CatalogModelEntry, 'id'>>,\n): Promise<CatalogModelEntry | null> {\n let result: CatalogModelEntry | null = null;\n await enqueueWrite(async () => {\n const cur = ensureLoaded();\n const idx = cur.findIndex((e) => e.id.toLowerCase() === id.toLowerCase());\n if (idx < 0) return;\n const next: CatalogModelEntry = { ...cur[idx], ...patch, id: cur[idx].id, updatedAt: Date.now() };\n for (const k of Object.keys(patch)) {\n if ((patch as any)[k] === null) delete (next as any)[k];\n }\n const list = cur.slice();\n list[idx] = next;\n await writeCatalog(list);\n result = next;\n });\n return result;\n}\n\n// ===== \u54C1\u724C\u5F52\u4E00\u5316\uFF08\u5E02\u573A\u6E20\u9053\u8FD4\u56DE\u7684\u539F\u59CB\u54C1\u724C \u2192 \u5361\u7247\u5C55\u793A\u98CE\u683C\uFF09 =====\n\nconst BRAND_NORMALIZE: Record<string, string> = {\n meituan: 'MeiTuan',\n tencent: 'Tencent',\n xiaomi: 'Xiaomi',\n openai: 'OpenAI',\n anthropic: 'Anthropic',\n google: 'Google',\n deepseek: 'DeepSeek',\n zhipu: 'Zhipu',\n moonshot: 'Moonshot',\n alibaba: 'Alibaba',\n minimax: 'MiniMax',\n};\n\nfunction normalizeBrand(raw: string): string {\n const k = String(raw || '').toLowerCase();\n return BRAND_NORMALIZE[k] || raw || 'Other';\n}\n\n/** \u4ECE A6API \u6A21\u578B\u540D\u63A8\u65AD\u54C1\u724C\uFF08\u76EE\u5F55\u65E0\u6570\u636E\u65F6\u7684\u5C55\u793A\u515C\u5E95\uFF0C\u4E0E\u65E7\u884C\u4E3A\u4E00\u81F4\uFF09 */\nexport function inferBrand(modelId: string): string {\n const m = modelId.toLowerCase();\n if (m.startsWith('gpt') || m.startsWith('o1') || m.startsWith('o3') || m.startsWith('chatgpt')) return 'OpenAI';\n if (m.startsWith('claude')) return 'Anthropic';\n if (m.startsWith('gemini') || m.startsWith('google') || m.startsWith('imagen')) return 'Google';\n if (m.startsWith('deepseek')) return 'DeepSeek';\n if (m.startsWith('grok')) return 'xAI';\n if (m.startsWith('glm') || m.startsWith('zhipu') || m.startsWith('cog')) return 'Zhipu';\n if (m.startsWith('kimi') || m.startsWith('moonshot')) return 'Moonshot';\n if (m.startsWith('qwen')) return 'Alibaba';\n if (m.startsWith('minimax')) return 'MiniMax';\n if (m.startsWith('mimo') || m.startsWith('xiaomi')) return 'Xiaomi';\n if (m.startsWith('hunyuan') || m.startsWith('tencent') || m.startsWith('hy')) return 'Tencent';\n return 'Other';\n}\n\n/**\n * \u9ED8\u8BA4\u63A8\u7406\u6863\u4F4D\uFF1ADSH llm-pi-ai \u652F\u6301\u7684\u5168\u90E8\u601D\u8003\u6863\u4F4D\uFF08THINKING_LEVELS\uFF09\uFF0C\n * wire \u503C\u53D6\u6863\u4F4D\u540D\u672C\u8EAB\uFF08identity\uFF09\uFF0C`off` \u65E0 wire \u503C\uFF08null = \u53D1\u9001\u65F6\u4E0D\u5E26\u601D\u8003\u53C2\u6570\uFF09\u3002\n * \u65B0\u83B7\u53D6\u7684\u5E02\u573A\u6A21\u578B\u9ED8\u8BA4\u58F0\u660E\u5168\u90E8\u6863\u4F4D\uFF0C\u7528\u6237\u53EF\u81EA\u884C\u4FEE\u6539\u3002\n */\nexport const DEFAULT_REASONING_EFFORTS: Record<string, string | null> = {\n off: null,\n minimal: 'minimal',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'xhigh',\n max: 'max',\n};\n\n/**\n * \u89E3\u6790\u6A21\u578B\u5143\u4FE1\u606F\uFF08\u540C\u6B65\uFF09\uFF1A\u76EE\u5F55\u6570\u636E\u4F18\u5148\uFF0C\u7F3A\u5931\u65F6\u8FD4\u56DE\u5C55\u793A\u515C\u5E95\u503C\u3002\n * \u6CE8\u610F\uFF1A\u5199 settings.yaml \u65F6\u4E0D\u8981\u7528\u6B64\u51FD\u6570\u7684\u515C\u5E95\u503C\u2014\u2014\u7F3A\u5B57\u6BB5\u5E94\u7701\u7565\uFF08\u89C1 buildA6apiBlock\uFF09\u3002\n */\nexport function resolveModelMeta(modelId: string): A6ApiModelMeta {\n const entry = getCatalogEntry(modelId);\n if (entry) {\n return {\n id: entry.id,\n name: entry.name || entry.id,\n brand: entry.brand || inferBrand(entry.id),\n contextWindow: entry.contextWindow ?? 262144,\n maxTokens: entry.maxTokens ?? 32768,\n modalities: entry.input && entry.input.length > 0 ? [...entry.input] : ['text'],\n ...(entry.reasoningEfforts && typeof entry.reasoningEfforts === 'object' && Object.keys(entry.reasoningEfforts).length > 0\n ? {\n reasoningEfforts: Object.fromEntries(\n Object.entries(entry.reasoningEfforts).filter(([, v]) => v !== null && v !== undefined),\n ) as Record<string, string>,\n }\n : {}),\n };\n }\n const lowerId = modelId.toLowerCase();\n const isVision = lowerId.includes('vision') || lowerId.includes('vl') || lowerId.includes('image');\n const hasReasoning = lowerId.includes('think') || lowerId.includes('reason') || lowerId.includes('pro') || lowerId.includes('sol');\n return {\n id: modelId,\n name: modelId,\n brand: inferBrand(modelId),\n contextWindow: 262144,\n maxTokens: 32768,\n modalities: isVision ? ['text', 'image'] : ['text'],\n ...(hasReasoning ? { thinkingFormat: 'deepseek' } : {}),\n };\n}\n\n// ===== A6API \u5E02\u573A\u5168\u91CF\u6A21\u578B\u62C9\u53D6\uFF08\u7FFB\u9875 channels/search\uFF0C\u5E26 Web \u4F1A\u8BDD\u9274\u6743\uFF09 =====\n\nconst MARKET_SEARCH = 'https://a6api.com/api/marketplace/channels/search';\nconst PAGE_SIZE = 500;\nconst CONCURRENCY = 6;\n\nfunction buildWebHeaders(userId?: string, accessToken?: string): Record<string, string> {\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',\n };\n const uid = userId ? String(userId).trim() : '';\n const token = accessToken ? String(accessToken).trim() : '';\n if (uid) headers['New-Api-User'] = uid;\n if (token) {\n headers['Authorization'] = token;\n headers['Cookie'] = `session=${token}`;\n }\n return headers;\n}\n\n/**\n * \u62C9\u53D6 A6API \u5E02\u573A\u652F\u6301\u7684\u5168\u90E8\u6A21\u578B ID\uFF08\u542B\u54C1\u724C\uFF09\u3002\n * \u4E0D\u6392\u9664\u4EFB\u4F55\u6A21\u578B\uFF08\u56FE\u50CF\u751F\u6210\u7B49\u4E00\u5E76\u6536\u5F55\uFF0C\u53C2\u6570\u7531 OpenRouter \u67E5\u8BE2\u51B3\u5B9A\u80FD\u5426\u586B\u5145\uFF09\u3002\n */\nexport async function fetchMarketplaceModels(\n userId?: string,\n accessToken?: string,\n): Promise<{ models: { id: string; brand?: string; reasoningEfforts: Record<string, string | null> }[]; failedPages: number }> {\n if (!userId && !accessToken) {\n throw new Error('\u9700\u5148\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\u624D\u80FD\u83B7\u53D6\u5E02\u573A\u6A21\u578B');\n }\n const headers = buildWebHeaders(userId, accessToken);\n const first = await (async () => {\n const res = await fetch(`${MARKET_SEARCH}?view=list&page=1&page_size=${PAGE_SIZE}`, {\n headers,\n signal: AbortSignal.timeout(15000),\n });\n if (!res.ok) throw new Error(`A6API \u5E02\u573A\u63A5\u53E3 HTTP ${res.status}`);\n return res.json();\n })();\n const total = Number(first?.data?.total || 0);\n const pages = Math.max(1, Math.ceil(total / PAGE_SIZE));\n const all: any[] = [...(first?.data?.items || [])];\n let failedPages = 0;\n let idx = 2;\n const worker = async () => {\n while (idx <= pages) {\n const p = idx++;\n try {\n const res = await fetch(`${MARKET_SEARCH}?view=list&page=${p}&page_size=${PAGE_SIZE}`, {\n headers,\n signal: AbortSignal.timeout(15000),\n });\n const j = await res.json();\n all.push(...(j?.data?.items || []));\n } catch (err: any) {\n failedPages++;\n console.warn('[dsh-a6api] fetchMarketplaceModels page', p, 'failed:', err?.message || err);\n }\n }\n };\n await Promise.all(Array.from({ length: CONCURRENCY }, () => worker()));\n\n const byModel = new Map<string, { id: string; brand?: string; reasoningEfforts: Record<string, string | null> }>();\n for (const it of all) {\n const name = it?.model_name;\n if (!name) continue;\n if (!byModel.has(name)) {\n byModel.set(name, {\n id: String(name),\n brand: normalizeBrand(it?.brand),\n // \u9ED8\u8BA4\u58F0\u660E DSH \u5168\u90E8\u601D\u8003\u6863\u4F4D\uFF08\u7528\u6237\u53EF\u4FEE\u6539\uFF1Bupsert \u4EC5\u8865\u7F3A\u5931\u5B57\u6BB5\uFF0C\u5DF2\u6709\u81EA\u5B9A\u4E49\u4E0D\u53D7\u5F71\u54CD\uFF09\n reasoningEfforts: { ...DEFAULT_REASONING_EFFORTS },\n });\n }\n }\n const models = [...byModel.values()].sort((a, b) => a.id.localeCompare(b.id));\n return { models, failedPages };\n}\n\n// ===== OpenRouter \u6A21\u578B\u53C2\u6570\u67E5\u8BE2\uFF08\u516C\u5F00 /api/v1/models\uFF0C\u8FDB\u7A0B\u5185\u7F13\u5B58 1h\uFF09 =====\n\nconst OPENROUTER_URL = 'https://openrouter.ai/api/v1/models';\nconst OR_TTL_MS = 60 * 60 * 1000;\n\nlet orCache: { at: number; models: any[] } | null = null;\n\nasync function getOpenRouterModels(): Promise<any[]> {\n if (orCache && Date.now() - orCache.at < OR_TTL_MS) return orCache.models;\n try {\n const res = await fetch(OPENROUTER_URL, {\n headers: { Accept: 'application/json', 'User-Agent': 'Mozilla/5.0' },\n signal: AbortSignal.timeout(20000),\n });\n if (!res.ok) throw new Error(`OpenRouter HTTP ${res.status}`);\n const j: any = await res.json();\n if (!Array.isArray(j?.data)) throw new Error('OpenRouter \u8FD4\u56DE\u683C\u5F0F\u5F02\u5E38');\n orCache = { at: Date.now(), models: j.data };\n return orCache.models;\n } catch (err) {\n // \u62C9\u53D6\u5931\u8D25\uFF1A\u5B58\u5728\u8FC7\u671F\u7F13\u5B58\u65F6\u964D\u7EA7\u7528\u65E7\u6570\u636E\uFF08stale \u515C\u5E95\uFF09\uFF0C\u5426\u5219\u4E0A\u629B\n if (orCache) return orCache.models;\n throw err;\n }\n}\n\nconst tailOf = (s: string): string => String(s).split('/').pop() || '';\n\n/** \u5339\u914D\u7B56\u7565\uFF1Atail \u7CBE\u786E \u2192 \u5F52\u4E00\u5316\uFF08. _ \u7A7A\u683C \u2192 -\uFF09\u2192 \u5265\u79BB\u65E5\u671F/\u7248\u672C\u540E\u7F00 \u2192 \u5305\u542B\u3002\u8FD4\u56DE null = \u67E5\u65E0 */\nfunction matchOpenRouter(models: any[], target: string): any | null {\n const t = target.toLowerCase();\n const tTail = tailOf(t);\n const norm = (s: string) => s.toLowerCase().replace(/[\\s_.]+/g, '-');\n\n const byTail = models.find((m) => tailOf(String(m.id)).toLowerCase() === tTail);\n if (byTail) return byTail;\n\n const nTail = norm(tTail);\n const byNorm = models.find((m) => norm(tailOf(String(m.id))) === nTail);\n if (byNorm) return byNorm;\n\n // \u5265\u79BB\u65E5\u671F/\u7248\u672C\u540E\u7F00\uFF1A-2025-12-11 / -20251001 / -0309 / -0.1 \u7B49\uFF0C\u518D\u7CBE\u786E\u5339\u914D\n const stripped = tTail.replace(/-(?:\\d{4}-\\d{2}-\\d{2}|\\d{8}|-\\d{2,4}|\\d\\.\\d+)$/, '');\n if (stripped && stripped !== tTail) {\n const byStripped = models.find((m) => tailOf(String(m.id)).toLowerCase() === stripped);\n if (byStripped) return byStripped;\n }\n\n // \u5305\u542B\u5339\u914D\uFF08\u6700\u540E\u624B\u6BB5\uFF09\uFF1A\u4EC5\u63A5\u53D7\u300C-\u300D\u5206\u6BB5\u5B8C\u6574\u5305\u542B target \u7684\u6761\u76EE\uFF0C\n // \u907F\u514D 'gpt-4o' \u8BEF\u547D\u4E2D 'gpt-4o-mini' \u4E4B\u7C7B\u7684\u524D\u7F00\u5305\u542B\n const tSeg = t.split('/').pop() || t;\n return (\n models.find((m) => {\n const id = String(m.id).toLowerCase();\n if (!id.includes(t)) return false;\n const tailSeg = id.split('/').pop() || '';\n return tailSeg === t || tailSeg.split('-').includes(tSeg);\n }) || null\n );\n}\n\n/** \u8F93\u5165\u6A21\u6001\uFF1A\u53EA\u53D6 architecture.input_modalities\uFF08\u8F93\u51FA\u6A21\u6001\u4E0D\u58F0\u660E\u4E3A\u8F93\u5165\uFF0C\u907F\u514D\u6587\u751F\u56FE\u6A21\u578B\u88AB\u8BEF\u6807 image \u8F93\u5165\uFF09 */\nfunction orModalities(m: any): ('text' | 'image')[] {\n const set = new Set<'text' | 'image'>();\n const input: string[] = m?.architecture?.input_modalities || [];\n for (const mod of input) {\n const k = String(mod).toLowerCase();\n if (k === 'text') set.add('text');\n else if (k === 'image') set.add('image');\n }\n return [...set];\n}\n\nexport interface OrQueryResult {\n updated: CatalogModelEntry[];\n notFound: string[];\n}\n\n/**\n * \u5BF9\u4E00\u6279\u6A21\u578B ID \u67E5\u8BE2 OpenRouter \u5E76\u586B\u5145\u76EE\u5F55\uFF08\u80FD\u67E5\u5230\u7684\u586B\u5145\uFF0C\u67E5\u4E0D\u5230\u7684\u4FDD\u6301\u7A7A\u53C2\u6570\u5B57\u6BB5\uFF09\u3002\n * \u8FD4\u56DE\u66F4\u65B0\u7EDF\u8BA1\uFF1Aupdated \u4E3A\u672C\u6B21\u586B\u5145/\u53D8\u66F4\u7684\u6761\u76EE\uFF0CnotFound \u4E3A\u67E5\u65E0\u7684 ID\u3002\n */\nexport async function queryOpenRouter(ids: string[]): Promise<OrQueryResult> {\n const uniq = [...new Set(ids.map((s) => String(s).trim()).filter(Boolean))];\n if (uniq.length === 0) return { updated: [], notFound: [] };\n const models = await getOpenRouterModels();\n const updated: CatalogModelEntry[] = [];\n const notFound: string[] = [];\n\n for (const id of uniq) {\n const hit = matchOpenRouter(models, id);\n if (!hit) {\n notFound.push(id);\n continue;\n }\n const patch: Partial<Omit<CatalogModelEntry, 'id'>> = {\n updatedAt: Date.now(),\n };\n const ctx = hit.context_length ?? hit.top_provider?.context_length;\n if (ctx != null && Number(ctx) > 0) patch.contextWindow = Number(ctx);\n const maxOut = hit.top_provider?.max_completion_tokens ?? hit.max_completion_tokens;\n if (maxOut != null && Number(maxOut) > 0) patch.maxTokens = Number(maxOut);\n const mods = orModalities(hit);\n if (mods.length > 0) patch.input = mods;\n // name \u4EC5\u5141\u8BB8\u7528\u6237\u624B\u52A8\u586B\u5199\uFF1A\u4E0D\u4ECE\u6B64\u5904\u586B\u5145\uFF08\u7528\u6237\u672A\u586B\u5219\u4FDD\u6301\u4E3A\u7A7A\uFF0C\u5199 settings.yaml \u65F6\u7701\u7565\uFF09\n updated.push({ id, ...patch });\n }\n\n if (updated.length > 0) {\n await upsertCatalogEntries(updated);\n }\n return { updated, notFound };\n}\n", "import type { BalanceInfo, MerchantChannelInfo, OfficialPrices, ApiRoutingLogItem, MarketplacePin, A6ApiTokenItem } from '../types.js';\nimport { resolveModelMeta } from './catalog.js';\n\n/** Normalize Base URL removing trailing slashes */\nexport function cleanBaseUrl(url: string): string {\n if (!url) return 'https://api.a6api.com';\n return url.trim().replace(/\\/+$/, '');\n}\n\n/** Format relative time */\nexport function formatRelativeTime(timestampSec: number): string {\n if (!timestampSec || timestampSec <= 0) return '\u521A\u521A';\n const now = Math.floor(Date.now() / 1000);\n const diff = now - timestampSec;\n if (diff < 0) return '\u521A\u521A';\n if (diff < 60) return '\u521A\u521A';\n if (diff < 3600) return `${Math.floor(diff / 60)} \u5206\u949F\u524D`;\n if (diff < 86400) return `${Math.floor(diff / 3600)} \u5C0F\u65F6\u524D`;\n return `${Math.floor(diff / 86400)} \u5929\u524D`;\n}\n\n/** Format CNY Price */\nexport function formatCnyPrice(micros: number, exchangeRate = 6.7209): string {\n if (micros === undefined || micros === null) return '\u2014';\n if (micros === 0) return '\u00A50';\n const usd = micros / 1_000_000;\n const cny = usd * exchangeRate;\n if (cny < 0.0001) return `\u00A5${cny.toFixed(6)}`;\n if (cny < 0.01) return `\u00A5${cny.toFixed(4)}`;\n if (cny < 1) return `\u00A5${cny.toFixed(4)}`;\n return `\u00A5${cny.toFixed(3)}`;\n}\n\nexport function buildWebHeaders(userId?: string, accessToken?: string): Record<string, string> {\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',\n };\n const uid = userId ? String(userId).trim() : '';\n if (uid) {\n headers['New-Api-User'] = uid;\n }\n if (accessToken && accessToken.trim()) {\n const raw = accessToken.trim();\n if (raw.startsWith('session=')) {\n headers['Cookie'] = raw;\n } else if (raw.includes(';')) {\n headers['Cookie'] = raw;\n } else {\n // Set both Authorization (for System Access Token) and Cookie fallback\n headers['Authorization'] = raw;\n headers['Cookie'] = `session=${raw}`;\n }\n }\n return headers;\n}\n\n/** Fetch User Balance (Real Account Balance Only) */\nexport async function fetchBalance(\n baseURL: string,\n apiKey: string,\n userId?: string,\n accessToken?: string,\n): Promise<BalanceInfo | null> {\n const cleanUrl = cleanBaseUrl(baseURL);\n\n let hasAccountAuth = false;\n let accountBalanceUsd = 0;\n let accountBalanceFormatted = '\u672A\u8FDE\u63A5';\n let accountBalanceCnyFormatted = '';\n let username: string | undefined;\n let responseUserId: string | number | undefined = userId;\n let usedUsd = 0;\n let requestCount = 0;\n\n // 1. Fetch real account balance from Web Console API\n if (userId || accessToken) {\n const candidates = ['https://a6api.com/api/user/self', `${cleanUrl}/api/user/self`];\n const uniqueCandidates = [...new Set(candidates)];\n\n for (const url of uniqueCandidates) {\n try {\n const res = await fetch(url, {\n headers: buildWebHeaders(userId, accessToken),\n signal: AbortSignal.timeout(6000),\n });\n if (res.ok) {\n const json = await res.json();\n if (json?.data && json.data.quota !== undefined) {\n const quota = Number(json.data.quota || 0);\n const rawUsed = Number(json.data.used_quota || 0);\n const usd = Number((quota / 500000).toFixed(4));\n const cny = Number((usd * 6.7209).toFixed(2));\n const used = Number((rawUsed / 500000).toFixed(4));\n\n hasAccountAuth = true;\n accountBalanceUsd = usd;\n accountBalanceFormatted = `$${usd.toFixed(2)}`;\n accountBalanceCnyFormatted = `\u2248 \u00A5${cny.toFixed(2)}`;\n usedUsd = used;\n requestCount = Number(json.data.request_count || 0);\n username = json.data.username || json.data.display_name || undefined;\n if (json.data.id) responseUserId = json.data.id;\n break;\n }\n }\n } catch {\n // continue candidate\n }\n }\n }\n\n // 2. If only API Key is present, query usage for consumed statistics if auth is not yet connected\n if (!hasAccountAuth && apiKey && apiKey.trim()) {\n try {\n const usageRes = await fetch(`${cleanUrl}/v1/dashboard/billing/usage?start_date=2024-01-01&end_date=2030-12-31`, {\n headers: {\n Authorization: `Bearer ${apiKey.trim()}`,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(6000),\n }).catch(() => null);\n\n if (usageRes && usageRes.ok) {\n const usageJson = await usageRes.json();\n usedUsd = Number(usageJson?.total_usage || 0);\n }\n } catch {}\n }\n\n if (!hasAccountAuth && (!apiKey || !apiKey.trim()) && (!userId || !userId.trim())) {\n return null;\n }\n\n return {\n hasAccountAuth,\n accountBalanceUsd,\n accountBalanceFormatted,\n accountBalanceCnyFormatted,\n usedUsd,\n usedFormatted: `$${usedUsd.toFixed(2)}`,\n requestCount,\n username,\n userId: responseUserId,\n isLow: hasAccountAuth ? accountBalanceUsd < 0.5 : false,\n updatedAt: Date.now(),\n };\n}\n\n/** Fetch Token Allowed Models */\nexport async function fetchTokenModels(baseURL: string, apiKey: string): Promise<string[]> {\n const cleanUrl = cleanBaseUrl(baseURL);\n if (!apiKey || !apiKey.trim()) return [];\n\n const endpoints = [`${cleanUrl}/v1/models`, `${cleanUrl}/models`];\n let lastErr = null;\n\n for (const url of endpoints) {\n try {\n const res = await fetch(url, {\n headers: {\n Authorization: `Bearer ${apiKey.trim()}`,\n Accept: 'application/json',\n },\n signal: AbortSignal.timeout(8000),\n });\n if (res.ok) {\n const json = await res.json();\n if (Array.isArray(json?.data)) {\n return json.data.map((m: any) => String(m.id || m.name)).filter(Boolean);\n }\n }\n } catch (err) {\n lastErr = err;\n }\n }\n\n if (lastErr) {\n console.warn('[dsh-a6api] fetchTokenModels failed:', lastErr);\n }\n return [];\n}\n\n/** Fetch Recent User Routing Logs */\nexport async function fetchRecentLogs(\n userId?: string,\n accessToken?: string,\n limit = 30,\n): Promise<ApiRoutingLogItem[]> {\n if (!userId && !accessToken) return [];\n try {\n const res = await fetch(`https://a6api.com/api/log/self?p=1&page_size=${limit}&type=0`, {\n headers: buildWebHeaders(userId, accessToken),\n signal: AbortSignal.timeout(8000),\n });\n if (res.ok) {\n const json = await res.json();\n if (Array.isArray(json?.data?.items)) {\n return json.data.items.map((it: any) => {\n const rawQuota = Number(it.quota || 0);\n const costUsd = rawQuota / 500000;\n let costFormatted = '$0.00';\n if (costUsd > 0) {\n if (costUsd < 0.0001) costFormatted = `$${costUsd.toFixed(6)}`;\n else if (costUsd < 0.01) costFormatted = `$${costUsd.toFixed(4)}`;\n else costFormatted = `$${costUsd.toFixed(4)}`;\n }\n\n const rawChannel = Number(it.channel || 0);\n let channelId: number | undefined = rawChannel > 0 ? rawChannel : undefined;\n if (!channelId && it.other) {\n try {\n const otherObj = JSON.parse(it.other);\n if (otherObj.actual_channel_id && Number(otherObj.actual_channel_id) > 0) {\n channelId = Number(otherObj.actual_channel_id);\n } else if (otherObj.billed_channel_id && Number(otherObj.billed_channel_id) > 0) {\n channelId = Number(otherObj.billed_channel_id);\n }\n } catch {}\n }\n\n const isError =\n it.type !== 2 ||\n (it.other && (\n it.other.includes('\"request_final_status\":\"failed\"') ||\n it.other.includes('\"request_final_status\":\"error\"') ||\n it.other.includes('\"request_final_status\":\"upstream_error\"')\n )) ||\n Boolean(it.content && it.content.startsWith('status_code='));\n\n return {\n id: it.id || it.request_id || String(Math.random()),\n created_at: Number(it.created_at || Date.now() / 1000),\n model_name: it.model_name || it.marketplace_model_name || '',\n channel: channelId,\n channel_name: it.channel_name || (channelId ? `\u5546\u6237 #${channelId}` : undefined),\n token_id: it.token_id !== undefined && it.token_id !== null ? Number(it.token_id) : undefined,\n prompt_tokens: Number(it.prompt_tokens || 0),\n completion_tokens: Number(it.completion_tokens || 0),\n use_time: Number(it.use_time || 0),\n quota: rawQuota,\n cost_usd: costUsd,\n cost_formatted: costFormatted,\n token_name: it.token_name || 'API',\n status: isError ? ('error' as const) : ('success' as const),\n other: it.other,\n raw: it,\n };\n });\n }\n }\n } catch (err) {\n console.warn('[dsh-a6api] fetchRecentLogs error:', err);\n }\n return [];\n}\n\n/** Fetch Channel Card details from A6API Marketplace */\nexport async function fetchChannelDetails(\n channelId: number,\n userId?: string,\n accessToken?: string,\n targetModelName?: string,\n logSnapshot?: any,\n): Promise<MerchantChannelInfo | null> {\n if (!channelId) return null;\n const targetName = targetModelName || '';\n const meta = resolveModelMeta(targetName);\n\n try {\n const res = await fetch(\n `https://a6api.com/api/marketplace/channels/search?channel_id=${channelId}&view=list&page=1&page_size=20`,\n {\n headers: buildWebHeaders(userId, accessToken),\n signal: AbortSignal.timeout(8000),\n },\n );\n if (res.ok) {\n const json = await res.json();\n const items: any[] = json?.data?.items || [];\n if (items.length > 0) {\n // Find match for targetModelName if provided, otherwise first item\n const item =\n (targetName\n ? items.find((it) => it.model_name?.toLowerCase() === targetName.toLowerCase())\n : null) || items[0];\n\n const rate = Number(item.realtime_ratio_exchange_rate || 6.7209);\n const inMicros = Number(item.input_price_micros || 0);\n const outMicros = Number(item.output_price_micros || 0);\n const cacheReadMicros = Number(item.cache_read_price_micros || 0);\n const cacheWriteMicros = Number(item.cache_write_price_micros || 0);\n\n // Parse Smart Routing Labels\n const labels: string[] = [];\n if (item.authenticity_guaranteed) {\n const badge = item.authenticity_guarantee_badge_key;\n if (badge === 'gold') labels.push('\u4FDD\u771F \u00B7 \u91D1\u6807');\n else if (badge === 'silver') labels.push('\u4FDD\u771F \u00B7 \u94F6\u6807');\n else if (badge === 'bronze') labels.push('\u4FDD\u771F \u00B7 \u94DC\u6807');\n else labels.push('\u4FDD\u771F');\n }\n if (Array.isArray(item.smart_routing_labels)) {\n for (const l of item.smart_routing_labels) {\n if (l === 'stable' && !labels.includes('\u7A33\u5B9A')) labels.push('\u7A33\u5B9A');\n if (l === 'cheap' && !labels.includes('\u4F4E\u4EF7')) labels.push('\u4F4E\u4EF7');\n if (l === 'fast' && !labels.includes('\u9AD8\u901F')) labels.push('\u9AD8\u901F');\n if (l === 'quality' && !labels.includes('\u9AD8\u8D28')) labels.push('\u9AD8\u8D28');\n }\n }\n if (labels.length === 0) {\n labels.push('\u7A33\u5B9A', '\u4F4E\u4EF7', '\u9AD8\u901F', '\u9AD8\u8D28');\n }\n\n // Official Prices\n let official_price: OfficialPrices | undefined;\n if (item.official_price && item.official_price.input_price_micros !== undefined) {\n const offIn = Number(item.official_price.input_price_micros || 0);\n const offOut = Number(item.official_price.output_price_micros || 0);\n const offCR = Number(item.official_price.cache_read_price_micros || 0);\n const offCW = Number(item.official_price.cache_write_price_micros || 0);\n official_price = {\n input_price_micros: offIn,\n output_price_micros: offOut,\n cache_read_price_micros: offCR,\n cache_write_price_micros: offCW,\n input_cny: formatCnyPrice(offIn, rate),\n output_cny: formatCnyPrice(offOut, rate),\n cache_read_cny: formatCnyPrice(offCR, rate),\n cache_write_cny: formatCnyPrice(offCW, rate),\n };\n } else if (meta.officialPriceMicros) {\n const offIn = meta.officialPriceMicros.input;\n const offOut = meta.officialPriceMicros.output;\n const offCR = meta.officialPriceMicros.cacheRead;\n const offCW = meta.officialPriceMicros.cacheWrite;\n official_price = {\n input_price_micros: offIn,\n output_price_micros: offOut,\n cache_read_price_micros: offCR,\n cache_write_price_micros: offCW,\n input_cny: formatCnyPrice(offIn, rate),\n output_cny: formatCnyPrice(offOut, rate),\n cache_read_cny: formatCnyPrice(offCR, rate),\n cache_write_cny: formatCnyPrice(offCW, rate),\n };\n }\n\n const successRate24h =\n item.success_rate_24h !== undefined ? Number(item.success_rate_24h) / 100 : 99.3;\n const recentSuccessRate =\n item.recent_success_rate !== undefined ? Number(item.recent_success_rate) / 100 : 100;\n const cacheHitRate =\n item.cache_hit_rate_24h !== undefined ? Number(item.cache_hit_rate_24h) / 100 : 72.0;\n const lastSuccessAt = Number(item.last_success_at || item.last_test_time || 0);\n\n const ratioCny = Number(item.realtime_ratio_cny || (inMicros / 1000000) * rate || 0.0341);\n const ratioFormatted = ratioCny.toFixed(4);\n\n return {\n listing_id: item.listing_id,\n // \u5F52\u4E00\u5316\u4E3A\u6570\u5B57\uFF0C\u907F\u514D\u5B98\u65B9\u8FD4\u56DE\u5B57\u7B26\u4E32 channel_id \u5BFC\u81F4\u4E25\u683C\u76F8\u7B49\u6BD4\u8F83\u5931\u6548\uFF08\u63A5\u7BA1/\u56FA\u5B9A\u5224\u5B9A\u4F9D\u8D56\uFF09\n channel_id: item.channel_id !== undefined && item.channel_id !== null ? Number(item.channel_id) : channelId,\n channel_name: item.channel_name || `\u5546\u6237 #${channelId}`,\n supplier_name: item.supplier_name || item.supplier_nickname || 'GPT\u4F4E\u4EF7',\n supplier_id: item.supplier_id || 290,\n model_name: item.model_name || targetName,\n brand: item.brand || meta.brand || 'OpenAI',\n description: item.description || '\u9AD8\u5E76\u53D1 \u4E3B\u6253\u4FBF\u5B9C \u7A33\u5B9A',\n charge_type: item.charge_type || 'per_token',\n charge_type_text: item.charge_type === 'per_token' ? '\u6309\u91CF' : '\u6309\u91CF',\n sample_count: Number(item.sample_count || 100),\n sample_count_text: `\u8FD1 ${item.sample_count || 100} \u6B21\u6837\u672C`,\n input_price_micros: inMicros,\n output_price_micros: outMicros,\n cache_read_price_micros: cacheReadMicros,\n cache_write_price_micros: cacheWriteMicros,\n input_price_cny: formatCnyPrice(inMicros, rate),\n output_price_cny: formatCnyPrice(outMicros, rate),\n cache_read_price_cny: formatCnyPrice(cacheReadMicros, rate),\n cache_write_price_cny: formatCnyPrice(cacheWriteMicros, rate),\n official_price,\n realtime_ratio_cny: ratioCny,\n realtime_ratio_formatted: ratioFormatted,\n recent_success_rate_pct: recentSuccessRate,\n success_rate_24h_pct: successRate24h,\n success_rate_7d_pct: item.success_rate_7d !== undefined ? Number(item.success_rate_7d) / 100 : undefined,\n success_buckets: Array.isArray(item.success_buckets) ? item.success_buckets : undefined,\n b24: Array.isArray(item.b24) ? item.b24 : undefined,\n b7d: Array.isArray(item.b7d) ? item.b7d : undefined,\n sr_24h_state: item.sr_24h_state || 'rate',\n sr_7d_state: item.sr_7d_state || 'no_data',\n p50_ttft_ms: Number(item.p50_ttft_ms || 2273),\n recent_p50_ms: Number(item.recent_p50_ms || item.last_test_response_ms || 2340),\n cache_hit_rate_pct: cacheHitRate,\n labels,\n last_success_at: lastSuccessAt,\n last_success_text: formatRelativeTime(lastSuccessAt),\n authenticity_guaranteed: Boolean(item.authenticity_guaranteed),\n authenticity_badge: item.authenticity_guarantee_badge_key,\n // \u5B98\u65B9\u56FA\u5B9A\u72B6\u6001\u503C\u662F pin_here / pin_elsewhere\uFF08\u65E9\u671F\u4EE3\u7801\u8BEF\u7528 'pinned'\uFF0C\u5DF2\u4FEE\u6B63\uFF09\n is_pinned: item.pin_status === 'pin_here' || item.route_status === 'pin_here',\n pin_status: typeof item.pin_status === 'string' ? item.pin_status : undefined,\n user_channel_disabled: Boolean(item.user_channel_disabled || item.route_status === 'user_disabled'),\n supplier_channel_disabled: Boolean(item.supplier_channel_disabled),\n raw: item,\n };\n }\n }\n } catch (err) {\n console.warn('[dsh-a6api] fetchChannelDetails error:', err);\n }\n\n // Fallback if we have log snapshot info\n if (logSnapshot) {\n const rate = 6.7209;\n const inMicros = Number(logSnapshot.marketplace_price_input_micros || 20300);\n const outMicros = Number(logSnapshot.marketplace_price_output_micros || 101502);\n const cacheReadMicros = Number(logSnapshot.marketplace_price_cache_read_micros || 2030);\n const cacheWriteMicros = Number(logSnapshot.marketplace_price_cache_write_micros || 25375);\n\n let official_price: OfficialPrices | undefined;\n if (meta.officialPriceMicros) {\n const offIn = meta.officialPriceMicros.input;\n const offOut = meta.officialPriceMicros.output;\n const offCR = meta.officialPriceMicros.cacheRead;\n const offCW = meta.officialPriceMicros.cacheWrite;\n official_price = {\n input_price_micros: offIn,\n output_price_micros: offOut,\n cache_read_price_micros: offCR,\n cache_write_price_micros: offCW,\n input_cny: formatCnyPrice(offIn, rate),\n output_cny: formatCnyPrice(offOut, rate),\n cache_read_cny: formatCnyPrice(offCR, rate),\n cache_write_cny: formatCnyPrice(offCW, rate),\n };\n }\n\n const ratioCny = Number((inMicros / 1000000) * rate || 0.0341);\n\n return {\n listing_id: logSnapshot.marketplace_listing_id,\n channel_id: channelId,\n channel_name: logSnapshot.channel_name || `\u5546\u6237 #${channelId}`,\n supplier_name: logSnapshot.supplier_nickname || logSnapshot.channel_name || 'GPT\u4F4E\u4EF7',\n supplier_id: 290,\n model_name: targetName || logSnapshot.model_name || '',\n brand: meta.brand || 'OpenAI',\n description: '\u9AD8\u5E76\u53D1 \u4E3B\u6253\u4FBF\u5B9C \u7A33\u5B9A',\n charge_type: 'per_token',\n charge_type_text: '\u6309\u91CF',\n sample_count: 100,\n sample_count_text: '\u8FD1 100 \u6B21\u6837\u672C',\n input_price_micros: inMicros,\n output_price_micros: outMicros,\n cache_read_price_micros: cacheReadMicros,\n cache_write_price_micros: cacheWriteMicros,\n input_price_cny: formatCnyPrice(inMicros, rate),\n output_price_cny: formatCnyPrice(outMicros, rate),\n cache_read_price_cny: formatCnyPrice(cacheReadMicros, rate),\n cache_write_price_cny: formatCnyPrice(cacheWriteMicros, rate),\n official_price,\n realtime_ratio_cny: ratioCny,\n realtime_ratio_formatted: ratioCny.toFixed(4),\n recent_success_rate_pct: 100,\n success_rate_24h_pct: 99.3,\n recent_p50_ms: Number(logSnapshot.use_time ? logSnapshot.use_time * 1000 : 2340),\n p50_ttft_ms: 2273,\n cache_hit_rate_pct: 72.0,\n labels: ['\u7A33\u5B9A', '\u4F4E\u4EF7', '\u9AD8\u901F', '\u9AD8\u8D28'],\n last_success_at: Math.floor(Date.now() / 1000),\n last_success_text: '\u521A\u521A',\n authenticity_guaranteed: false,\n is_pinned: false,\n user_channel_disabled: false,\n };\n }\n\n return null;\n}\n/** \u8F7B\u91CF\u62C9\u53D6\u4EF7\u683C\u6CE2\u52A8\u6761\u6570\uFF08\u4EC5 pending/unseen\uFF09 */\nexport async function fetchPriceFluctuation(\n userId?: string,\n accessToken?: string,\n): Promise<{ pendingCount: number; unseenCount: number; totalCount: number; notices?: any[]; authError?: boolean }> {\n const token = (accessToken || '').trim();\n const uid = (userId || '').trim();\n if (!uid && !token) {\n return { pendingCount: 0, unseenCount: 0, totalCount: 0, authError: false };\n }\n const headers = buildWebHeaders(uid || undefined, token || undefined);\n const url = 'https://a6api.com/api/marketplace/price-notices';\n try {\n const res = await fetch(url, { headers, signal: AbortSignal.timeout(8000) });\n if (res.status === 401 || res.status === 403) {\n console.warn('[dsh-a6api] fetchPriceFluctuation auth failed', res.status);\n return { pendingCount: 0, unseenCount: 0, totalCount: 0, authError: true };\n }\n if (!res.ok) {\n console.warn('[dsh-a6api] fetchPriceFluctuation HTTP', res.status);\n return { pendingCount: 0, unseenCount: 0, totalCount: 0 };\n }\n const json: any = await res.json().catch(() => null);\n if (!json) return { pendingCount: 0, unseenCount: 0, totalCount: 0 };\n if (json.success === false) return { pendingCount: 0, unseenCount: 0, totalCount: 0 };\n\n // \u517C\u5BB9\u591A\u79CD\u8FD4\u56DE\u5F62\u6001\n let arr: any[] = [];\n if (Array.isArray(json)) arr = json;\n else if (Array.isArray(json.data)) arr = json.data;\n else if (Array.isArray(json.data?.notices)) arr = json.data.notices;\n else if (Array.isArray(json.data?.items)) arr = json.data.items;\n else if (Array.isArray(json.notices)) arr = json.notices;\n else if (Array.isArray(json.items)) arr = json.items;\n\n // \u533A\u5206\u201C\u5B57\u6BB5\u7F3A\u5931\u201D vs \u201C\u663E\u5F0F\u4E3A 0\u201D\u2014\u2014\u4EC5\u7F3A\u5931\u65F6\u624D\u515C\u5E95\n const pickWithPresent = (keys: string[]): { value: number; present: boolean } => {\n for (const k of keys) {\n const v = json?.data?.[k] ?? json?.[k];\n if (v !== undefined && v !== null) {\n const n = Number(v);\n if (!Number.isNaN(n)) return { value: n, present: true };\n }\n }\n return { value: 0, present: false };\n };\n const pendingPick = pickWithPresent(['pendingCount', 'pending_count', 'pending', 'openCount']);\n const unseenPick = pickWithPresent(['unseenCount', 'unseen_count', 'unseen', 'has_unseen_count']);\n let pending = pendingPick.value;\n let unseen = unseenPick.value;\n const total = arr.length;\n\n // \u4EC5\u5728\u8BA1\u6570\u952E\u7F3A\u5931\u65F6\u624D\u4ECE\u6570\u7EC4\u515C\u5E95\uFF0C\u907F\u514D\u8986\u76D6 API \u663E\u5F0F 0\n if (!pendingPick.present && arr.length > 0) {\n const counted = arr.filter((n: any) => {\n const s = String(n.state || n.status || '').toLowerCase();\n return s === 'open' || s === 'pending' || n.pending === true;\n }).length;\n // \u4EC5\u5F53\u6570\u7EC4\u6709\u53EF\u8BC6\u522B\u7684 state \u65F6\u624D\u7528 counted\uFF0C\u5426\u5219\u4FDD\u6301 0\uFF08\u4E0D\u731C\u6D4B\uFF09\n const hasState = arr.some((n: any) => n.state !== undefined || n.status !== undefined);\n if (hasState) pending = counted;\n // \u82E5\u65E0 state \u5B57\u6BB5\u4E14 pending \u7F3A\u5931\uFF0C\u4FDD\u6301 0\uFF0C\u4E0D\u518D\u9000\u5316\u4E3A total\n }\n if (!unseenPick.present && arr.length > 0) {\n unseen = arr.filter((n: any) => n.has_unseen === true || n.hasUnseen === true || n.unseen === true || n.is_unread === true).length;\n }\n\n // \u8C03\u8BD5\u65E5\u5FD7\u5DF2\u79FB\u9664\uFF08\u907F\u514D\u672A\u8131\u654F\u900F\u4F20\uFF09\uFF1B\u5982\u9700\u672C\u5730\u8C03\u8BD5\u53EF\u4E34\u65F6\u5F00\u542F DEBUG \u73AF\u5883\u53D8\u91CF\n // if (process.env.DEBUG) console.log('[dsh-a6api] price fluctuation sample', arr[0]);\n\n return { pendingCount: pending, unseenCount: unseen, totalCount: total, notices: arr };\n } catch (err) {\n console.warn('[dsh-a6api] fetchPriceFluctuation error', err);\n return { pendingCount: 0, unseenCount: 0, totalCount: 0 };\n }\n}\n\n/* ============================================================================\n * \u56FA\u5B9A / \u53D6\u6D88\u56FA\u5B9A / \u7981\u7528 \u4E00\u65CF\u63A5\u53E3\uFF08\u5E73\u53F0\u4FA7\uFF0CWeb \u4F1A\u8BDD\u9274\u6743\uFF0C\u4E0E\u5E02\u573A\u4EF7\u683C\u6CE2\u52A8\u540C\u51ED\u636E\uFF09\n * ========================================================================== */\n\ninterface MarketplaceActionResult {\n ok: boolean;\n message?: string;\n data?: any;\n}\n\n/** \u517C\u5BB9\u591A\u79CD\u8FD4\u56DE\u5F62\u6001\uFF1A{success,message} / {data:{success,message}} */\nfunction parseMarketplaceResult(json: any): MarketplaceActionResult {\n if (!json) return { ok: false, message: '\u7A7A\u54CD\u5E94' };\n const top = json.success === false ? json : null;\n const inner = json.data && json.data.success === false ? json.data : null;\n if (top) return { ok: false, message: top.message || '\u64CD\u4F5C\u5931\u8D25' };\n if (inner) return { ok: false, message: inner.message || '\u64CD\u4F5C\u5931\u8D25' };\n return { ok: true, data: json.data };\n}\n\n/** \u63D0\u53D6\u6570\u7EC4\u5B57\u6BB5\uFF1A\u517C\u5BB9 data / data.data / data.items / data.data.items \u56DB\u79CD\u5F62\u6001 */\nfunction extractArray(json: any): any[] {\n if (!json) return [];\n if (Array.isArray(json)) return json;\n if (Array.isArray(json.data)) return json.data;\n if (json.data && Array.isArray(json.data.data)) return json.data.data;\n if (json.data && Array.isArray(json.data.items)) return json.data.items;\n if (json.data && json.data.data && Array.isArray(json.data.data.items)) return json.data.data.items;\n return [];\n}\n\n/** GET /api/marketplace/pins \u2014 \u5F53\u524D\u8D26\u53F7\u5168\u90E8\u56FA\u5B9A\u8BB0\u5F55\uFF08\u5361\u7247\u72B6\u6001\u8DDF\u968F\u5B98\u7F51\u7684\u771F\u76F8\u6E90\uFF09 */\nexport async function fetchMarketplacePins(\n userId?: string,\n accessToken?: string,\n): Promise<MarketplacePin[]> {\n if (!userId && !accessToken) return [];\n try {\n const res = await fetch('https://a6api.com/api/marketplace/pins', {\n headers: buildWebHeaders(userId, accessToken),\n signal: AbortSignal.timeout(8000),\n });\n if (!res.ok) {\n console.warn('[dsh-a6api] fetchMarketplacePins HTTP', res.status);\n return [];\n }\n const json: any = await res.json().catch(() => null);\n if (!json || json.success === false) return [];\n return extractArray(json)\n .filter((it: any) => it && it.model_name)\n .map((it: any) => ({\n id: it.id !== undefined ? Number(it.id) : undefined,\n token_id: Number(it.token_id || 0),\n token_name: it.token_name || undefined,\n model_name: String(it.model_name),\n channel_id: it.channel_id !== undefined && Number(it.channel_id) > 0 ? Number(it.channel_id) : undefined,\n channel_name: it.channel_name || undefined,\n supplier_name: it.supplier_name || undefined,\n supplier_nickname: it.supplier_nickname || undefined,\n fallback_to_smart_routing: it.fallback_to_smart_routing !== undefined ? Boolean(it.fallback_to_smart_routing) : undefined,\n created_at: it.created_at !== undefined ? Number(it.created_at) : undefined,\n // \u4E0D\u4E0B\u53D1 raw\uFF1A\u5BA2\u6237\u7AEF 60s \u8F6E\u8BE2\u7528 JSON \u5BF9\u6BD4\u5224\u65AD\u53D8\u5316\uFF0Craw \u542B\u6613\u53D8\u5B57\u6BB5\u4F1A\u5BFC\u81F4\u8BEF\u5224\u6574\u9875\u5237\u65B0\n }));\n } catch (err) {\n console.warn('[dsh-a6api] fetchMarketplacePins error:', err);\n return [];\n }\n}\n\n/** GET /api/token/?p=1&size=100 \u2014 \u4EE4\u724C\u5217\u8868\uFF08\u7528\u4E8E\u628A API Key \u89E3\u6790\u4E3A token_id\uFF09 */\nexport async function fetchTokens(\n userId?: string,\n accessToken?: string,\n): Promise<A6ApiTokenItem[]> {\n if (!userId && !accessToken) return [];\n try {\n const res = await fetch('https://a6api.com/api/token/?p=1&size=100', {\n headers: buildWebHeaders(userId, accessToken),\n signal: AbortSignal.timeout(8000),\n });\n if (!res.ok) return [];\n const json: any = await res.json().catch(() => null);\n if (!json || json.success === false) return [];\n return extractArray(json)\n .filter((it: any) => it && Number(it.id) > 0)\n .map((it: any) => ({\n id: Number(it.id),\n name: it.name || undefined,\n key: typeof it.key === 'string' ? it.key : undefined,\n status: it.status !== undefined ? Number(it.status) : undefined,\n raw: it,\n }));\n } catch (err) {\n console.warn('[dsh-a6api] fetchTokens error:', err);\n return [];\n }\n}\n\n/** \u53CB\u597D\u5316\u52A8\u4F5C\u7C7B\u63A5\u53E3\u9519\u8BEF\uFF08\u8D85\u65F6\u82F1\u6587\u539F\u6587\u8F6C\u4E2D\u6587\uFF0C\u4E0E probe.ts \u540C\u98CE\u683C\uFF09 */\nfunction friendlyActionError(err: any): string {\n const raw = err?.message || String(err);\n if (raw.includes('aborted due to timeout') || err?.name === 'TimeoutError') {\n return '\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5';\n }\n return raw;\n}\n\n/** POST /api/marketplace/pin \u2014 \u628A\u67D0\u6A21\u578B\u7684\u6D41\u91CF\u56FA\u5B9A\u5230\u6307\u5B9A\u6E20\u9053\uFF08\u7ED1\u5B9A\u4EE4\u724C\uFF09 */\nexport async function marketplacePin(\n userId: string | undefined,\n accessToken: string | undefined,\n payload: {\n token_id: number;\n channel_id: number;\n model_name: string;\n fallback_to_smart_routing: boolean;\n },\n): Promise<MarketplaceActionResult> {\n try {\n const res = await fetch('https://a6api.com/api/marketplace/pin', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...buildWebHeaders(userId, accessToken),\n },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(10000),\n });\n const json: any = await res.json().catch(() => null);\n const result = parseMarketplaceResult(json);\n if (!res.ok && !json) return { ok: false, message: `HTTP ${res.status}` };\n return result;\n } catch (err: any) {\n console.warn('[dsh-a6api] marketplacePin error:', err);\n return { ok: false, message: friendlyActionError(err) };\n }\n}\n\n/** POST /api/marketplace/unpin \u2014 \u53D6\u6D88\u67D0\u6A21\u578B\u7684\u56FA\u5B9A */\nexport async function marketplaceUnpin(\n userId: string | undefined,\n accessToken: string | undefined,\n payload: { token_id: number; model_name: string },\n): Promise<MarketplaceActionResult> {\n try {\n const res = await fetch('https://a6api.com/api/marketplace/unpin', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...buildWebHeaders(userId, accessToken),\n },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(10000),\n });\n const json: any = await res.json().catch(() => null);\n if (!res.ok && !json) return { ok: false, message: `HTTP ${res.status}` };\n return parseMarketplaceResult(json);\n } catch (err: any) {\n console.warn('[dsh-a6api] marketplaceUnpin error:', err);\n return { ok: false, message: friendlyActionError(err) };\n }\n}\n\n/** POST /api/marketplace/channels/:id/disable?model= \u2014 \u7981\u7528\u67D0\u6E20\u9053\u5BF9\u8BE5\u6A21\u578B\u7684\u670D\u52A1 */\nexport async function marketplaceDisableChannel(\n userId: string | undefined,\n accessToken: string | undefined,\n channelId: number,\n model: string,\n): Promise<MarketplaceActionResult> {\n try {\n const res = await fetch(\n `https://a6api.com/api/marketplace/channels/${channelId}/disable?model=${encodeURIComponent(model)}`,\n {\n method: 'POST',\n headers: buildWebHeaders(userId, accessToken),\n signal: AbortSignal.timeout(10000),\n },\n );\n const json: any = await res.json().catch(() => null);\n if (!res.ok && !json) return { ok: false, message: `HTTP ${res.status}` };\n return parseMarketplaceResult(json);\n } catch (err: any) {\n console.warn('[dsh-a6api] marketplaceDisableChannel error:', err);\n return { ok: false, message: friendlyActionError(err) };\n }\n}\n\n/** POST /api/marketplace/channels/:id/restore?model= \u2014 \u6062\u590D\u88AB\u7981\u7528\u7684\u6E20\u9053 */\nexport async function marketplaceRestoreChannel(\n userId: string | undefined,\n accessToken: string | undefined,\n channelId: number,\n model: string,\n): Promise<MarketplaceActionResult> {\n try {\n const res = await fetch(\n `https://a6api.com/api/marketplace/channels/${channelId}/restore?model=${encodeURIComponent(model)}`,\n {\n method: 'POST',\n headers: buildWebHeaders(userId, accessToken),\n signal: AbortSignal.timeout(10000),\n },\n );\n const json: any = await res.json().catch(() => null);\n if (!res.ok && !json) return { ok: false, message: `HTTP ${res.status}` };\n return parseMarketplaceResult(json);\n } catch (err: any) {\n console.warn('[dsh-a6api] marketplaceRestoreChannel error:', err);\n return { ok: false, message: friendlyActionError(err) };\n }\n}\n", "import { cleanBaseUrl, fetchChannelDetails, fetchRecentLogs } from './a6api-client.js';\nimport type { ApiRoutingLogItem, MerchantChannelInfo } from '../types.js';\n\nexport interface ProbeResult {\n modelName: string;\n success: boolean;\n channelId?: number;\n channelName?: string;\n /** \u8BE5\u6B21\u8BF7\u6C42\u5B9E\u9645\u4F7F\u7528\u7684\u4EE4\u724C ID\uFF08\u7528\u4E8E\u56FA\u5B9A/\u7981\u7528\u6309\u4EE4\u724C\u7ED1\u5B9A\uFF09 */\n tokenId?: number;\n merchant?: MerchantChannelInfo | null;\n error?: string;\n durationMs?: number;\n}\n\n/** Delay helper */\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\n/** Probe a single model by sending a 1-token prompt and querying logs */\nexport async function probeSingleModel(\n baseURL: string,\n apiKey: string,\n userId?: string,\n accessToken?: string,\n modelName?: string,\n): Promise<ProbeResult> {\n const targetModel = modelName || '';\n const cleanUrl = cleanBaseUrl(baseURL);\n if (!apiKey) {\n return { modelName: targetModel, success: false, error: '\u672A\u914D\u7F6E API Key' };\n }\n\n const startTime = Date.now();\n let requestOk = false;\n let requestError = '';\n\n try {\n const res = await fetch(`${cleanUrl}/v1/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey.trim()}`,\n },\n body: JSON.stringify({\n model: targetModel,\n messages: [{ role: 'user', content: '1' }],\n max_tokens: 1,\n }),\n // \u63A8\u7406\u6A21\u578B(\u5982 grok-4.6)\u5B9E\u6D4B\u5355\u6B21\u54CD\u5E94\u53EF\u8FBE 40-90s+,\u9608\u503C\u8FC7\u77ED\u4F1A\u88AB\u9891\u7E41\u6390\u65AD\u5BFC\u81F4\u63A2\u6D4B\u5931\u8D25\n signal: AbortSignal.timeout(180000),\n });\n\n if (res.ok) {\n requestOk = true;\n } else {\n const errText = await res.text();\n requestError = `HTTP ${res.status}: ${errText.slice(0, 150)}`;\n }\n } catch (err: any) {\n const raw = err?.message || String(err);\n // \u8D85\u65F6\u9519\u8BEF\u82F1\u6587\u539F\u6587\u5BF9\u7528\u6237\u4E0D\u53CB\u597D,\u8F6C\u4E3A\u4E2D\u6587\u63D0\u793A\n if (raw.includes('aborted due to timeout') || err?.name === 'TimeoutError') {\n requestError = '\u63A2\u6D4B\u8D85\u65F6(\u9608\u503C180\u79D2) \u2014 \u63A8\u7406\u6A21\u578B\u54CD\u5E94\u8F83\u6162,\u5DF2\u4FDD\u7559\u4E0A\u6B21\u5546\u6237\u6570\u636E,\u8BF7\u7A0D\u540E\u91CD\u8BD5';\n } else {\n requestError = raw;\n }\n }\n\n const durationMs = Date.now() - startTime;\n\n // \u4EC5\u8BF7\u6C42\u6210\u529F\u540E\u67E5\u65E5\u5FD7,\u5931\u8D25\u65F6\u76F4\u63A5\u8FD4\u56DE\u9519\u8BEF(\u4E0D\u5728\u5361\u7247\u4E0A\u56DE\u9000\u5C55\u793A\u5386\u53F2\u5546\u6237)\n if (requestOk && (userId || accessToken)) {\n // Wait slightly for gateway log writing (\u6162\u6A21\u578B\u8BF7\u6C42\u671F\u95F4\u65E5\u5FD7\u5DF2\u843D\u76D8,\u5FEB\u6A21\u578B\u9700\u8981\u7B49\u5F85)\n await sleep(1200);\n try {\n const logs = await fetchRecentLogs(userId, accessToken, 15);\n const minTimestamp = Math.floor(startTime / 1000) - 10;\n // Find recent log entry for this model\n const log =\n logs.find(\n (it) =>\n it.model_name?.toLowerCase() === targetModel.toLowerCase() &&\n Number(it.created_at || 0) >= minTimestamp,\n ) || logs.find((it) => it.model_name?.toLowerCase() === targetModel.toLowerCase());\n\n if (log && log.channel) {\n const channelId = Number(log.channel);\n let logSnapshot: any = null;\n if (log.other) {\n try {\n logSnapshot = { ...JSON.parse(log.other), channel_name: log.channel_name, model_name: log.model_name };\n } catch {}\n }\n const merchant = await fetchChannelDetails(channelId, userId, accessToken, targetModel, logSnapshot);\n return {\n modelName: targetModel,\n success: true,\n channelId,\n channelName: log.channel_name,\n // \u8BE5\u6B21\u8BF7\u6C42\u7531 API Key \u53D1\u8D77\uFF0C\u65E5\u5FD7\u4E2D\u8BB0\u5F55\u7684 token_id \u5373\u8BE5 Key \u7684\u4EE4\u724C ID\n tokenId: log.token_id !== undefined && Number(log.token_id) > 0 ? Number(log.token_id) : undefined,\n merchant,\n durationMs,\n };\n }\n } catch (err: any) {\n console.warn(`[dsh-a6api] Log lookup error for ${targetModel}:`, err);\n }\n }\n\n return {\n modelName: targetModel,\n success: requestOk,\n durationMs,\n error: requestOk ? undefined : requestError,\n };\n}\n\n/** Pre-populate merchant cards from recent logs without triggering live probe */\nexport async function getKnownMerchantsFromLogs(\n userId?: string,\n accessToken?: string,\n modelNames: string[] = [],\n logs?: ApiRoutingLogItem[],\n): Promise<Record<string, MerchantChannelInfo>> {\n if ((!userId && !accessToken) || modelNames.length === 0) return {};\n\n const result: Record<string, MerchantChannelInfo> = {};\n try {\n const items = logs !== undefined ? logs : await fetchRecentLogs(userId, accessToken, 50);\n // \u9632\u5FA1\u6027\u6392\u5E8F\uFF1A\u4E0E /state \u7684 lastRoutedMap \u4FDD\u6301\u4E00\u81F4\n const sorted = items.slice().sort((a: any, b: any) => (Number(b.created_at) || 0) - (Number(a.created_at) || 0));\n const modelToLog = new Map<string, any>();\n\n for (const log of sorted) {\n const mName = log.model_name;\n const chId = Number(log.channel);\n if (mName && chId && !modelToLog.has(mName.toLowerCase())) {\n modelToLog.set(mName.toLowerCase(), log);\n }\n }\n\n const matchedEntries: { modelName: string; log: any }[] = [];\n for (const name of modelNames) {\n const log = modelToLog.get(name.toLowerCase());\n if (log) {\n matchedEntries.push({ modelName: name, log });\n }\n }\n\n // Fetch details with concurrency limit 4\n for (let i = 0; i < matchedEntries.length; i += 4) {\n const batch = matchedEntries.slice(i, i + 4);\n await Promise.all(\n batch.map(async ({ modelName, log }) => {\n try {\n const channelId = Number(log.channel);\n let logSnapshot: any = null;\n if (log.other) {\n try {\n logSnapshot = { ...JSON.parse(log.other), channel_name: log.channel_name, model_name: log.model_name };\n } catch {}\n }\n const card = await fetchChannelDetails(channelId, userId, accessToken, modelName, logSnapshot);\n if (card) {\n result[modelName] = card;\n }\n } catch {\n // ignore\n }\n }),\n );\n }\n } catch (err) {\n console.warn('[dsh-a6api] getKnownMerchantsFromLogs error:', err);\n }\n\n return result;\n}\n", "import * as fs from 'node:fs';\nimport * as fsp from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { getCatalogEntry } from './catalog.js';\nimport type { A6ApiConfig } from '../types.js';\n\n/**\n * DSH \u539F\u751F\u914D\u7F6E\u6574\u5408\uFF08\u6D88\u9664\u63D2\u4EF6\u72EC\u7ACB\u914D\u7F6E\u6587\u4EF6 dsh-a6api-config.json\uFF09\uFF1A\n * - \u51ED\u636E\uFF08API Key / \u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C / userId\uFF09\u2192 ~/.dsh/.credentials.yaml\uFF08refs\uFF0C0600\uFF09\n * - \u975E\u673A\u5BC6\u72B6\u6001\uFF08baseURL / \u6A21\u578B\u5217\u8868\uFF09\u2192 ~/.dsh/settings.yaml \u7684 llm-pi-ai.providers.a6api \u5757\n * - \u8BFB\u5199\u4F18\u5148\u8D70 DSH \u539F\u751F\u7F1D ctx.credentials / ctx.settings\uFF08env \u4F18\u5148\u8BED\u4E49\u3001\u4E32\u884C\u5199\u961F\u5217\u3001schema \u6821\u9A8C\u3001\n * \u70ED\u53D1\u5E03\uFF09\uFF1B\u539F\u751F\u670D\u52A1\u7F3A\u5931\u6216\u5199\u5165\u5931\u8D25\u65F6\u56DE\u9000\u5230\u76F4\u63A5\u8BFB\u5199\u4E24\u4E2A\u6587\u4EF6\uFF08\u683C\u5F0F\u4E0E DSH \u539F\u751F\u4E00\u81F4\uFF09\u3002\n * - \u65E7\u7248\u72EC\u7ACB\u914D\u7F6E\u6587\u4EF6\u5728\u542F\u52A8\u65F6\u81EA\u52A8\u8FC1\u79FB\uFF08\u53EA\u586B\u7A7A\u4E0D\u8986\u76D6\uFF09\u5E76\u5F52\u6863\u4E3A dsh-a6api-config.json.bak\u3002\n */\n\nexport const A6API_CRED_REF = 'A6API_API_KEY';\nexport const A6API_TOKEN_REF = 'A6API_ACCESS_TOKEN';\nexport const A6API_USER_REF = 'A6API_USER_ID';\n\nconst SETTINGS_NS = 'llm-pi-ai';\nconst PROVIDER_KEY = 'a6api';\nconst DEFAULT_BASE_URL = 'https://api.a6api.com';\nconst LEGACY_CONFIG_NAME = 'dsh-a6api-config.json';\n\n/** \u539F\u5B50\u5199\u5165\uFF1A\u5148\u5199\u4E34\u65F6\u6587\u4EF6\uFF080600/0644\uFF09\u518D rename\uFF0C\u907F\u514D\u5D29\u6E83\u622A\u65AD\u4E0E\u6743\u9650\u4F4D\u6CC4\u9732 */\nasync function atomicWriteFile(filePath: string, content: string, mode = 0o600): Promise<void> {\n const dir = path.dirname(filePath);\n await fsp.mkdir(dir, { recursive: true });\n const tmpPath = path.join(dir, `.${path.basename(filePath)}.${process.pid}.${Date.now()}.tmp`);\n await fsp.writeFile(tmpPath, content, { mode });\n await fsp.rename(tmpPath, filePath);\n}\n\nfunction dshHome(): string {\n return process.env.DSH_HOME || path.join(os.homedir(), '.dsh');\n}\n\nfunction legacyConfigFile(): string {\n return path.join(dshHome(), LEGACY_CONFIG_NAME);\n}\n\nfunction credentialsFile(): string {\n return path.join(dshHome(), '.credentials.yaml');\n}\n\nfunction settingsFile(): string {\n return path.join(dshHome(), 'settings.yaml');\n}\n\n/** \u53EF\u9009\u5730\u53D6 DSH \u539F\u751F\u670D\u52A1\uFF1B\u7F3A\u5931\u65F6\u8FD4\u56DE undefined\uFF08\u8C03\u7528\u65B9\u56DE\u9000\u5230\u6587\u4EF6\u76F4\u8BFB\u5199\uFF09 */\nfunction getCredentials(ctx: any) {\n try {\n if (ctx && typeof ctx.get === 'function') return ctx.get('credentials');\n } catch {}\n return undefined;\n}\n\nfunction getSettings(ctx: any) {\n try {\n if (ctx && typeof ctx.get === 'function') return ctx.get('settings');\n } catch {}\n return undefined;\n}\n\n/** \u53BB\u6389 OpenAI \u517C\u5BB9\u7AEF\u70B9\u7684 /v1 \u540E\u7F00\uFF0C\u8FD8\u539F\u63D2\u4EF6 API \u8C03\u7528\u6240\u7528\u7684\u88F8\u5730\u5740 */\nfunction stripV1(baseURL: string): string {\n return baseURL.replace(/\\/v1\\/?$/, '');\n}\n\n// ===== .credentials.yaml \u624B\u5199\u8BFB\u5199\uFF08\u539F\u751F\u7F1D\u7F3A\u5931\u65F6\u7684\u515C\u5E95\uFF0C\u683C\u5F0F\u4E0E DSH \u4E00\u81F4\uFF1Aversion:1 + refs\uFF09 =====\n\n/** Read a key from .credentials.yaml */\nexport async function readCredentialKey(refKey: string): Promise<string | null> {\n try {\n const yaml = await fsp.readFile(credentialsFile(), 'utf8');\n let inRefs = false;\n for (const line of yaml.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (indent === 0) {\n inRefs = trimmed.startsWith('refs:');\n continue;\n }\n if (!inRefs) continue;\n const m = /^([A-Za-z0-9_.\\-]+):\\s*(.*)$/.exec(trimmed);\n if (m && m[1] === refKey) {\n let val = m[2].trim();\n if ((val.startsWith('\"') && val.endsWith('\"')) || (val.startsWith(\"'\") && val.endsWith(\"'\"))) {\n val = val.slice(1, -1);\n }\n return val || null;\n }\n }\n } catch {}\n return null;\n}\n\n/**\n * Write/update a key in .credentials.yaml\u3002\n * DSH credentials-local \u5BF9\u7A7A ref \u503C\u6574\u4F53\u62D2\u6536\u6587\u6863\uFF08parseRefs \u629B\u9519\uFF09\uFF0C\u56E0\u6B64\n * \u7A7A\u4E32/undefined = \u5220\u9664\u8BE5\u952E\u884C\uFF08\u4E0E\u539F\u751F unset \u8BED\u4E49\u4E00\u81F4\uFF09\uFF0C\u7EDD\u4E0D\u5199\u5165\u7A7A\u503C\u3002\n */\nexport async function writeCredentialKey(refKey: string, value: string): Promise<void> {\n const cFile = credentialsFile();\n let yaml = '';\n try {\n yaml = await fsp.readFile(cFile, 'utf8');\n } catch {\n yaml = 'version: 1\\nrefs:\\n';\n }\n\n const lines = yaml.split(/\\r?\\n/);\n let inRefs = false;\n let refsLineIdx = -1;\n let foundIdx = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (indent === 0) {\n if (trimmed.startsWith('refs:')) {\n inRefs = true;\n refsLineIdx = i;\n } else {\n inRefs = false;\n }\n continue;\n }\n if (inRefs) {\n const m = /^([A-Za-z0-9_.\\-]+):/.exec(trimmed);\n if (m && m[1] === refKey) {\n foundIdx = i;\n break;\n }\n }\n }\n\n if (value === '') {\n // \u5220\u9664\u8BED\u4E49\uFF1A\u79FB\u9664\u8BE5\u952E\u884C\uFF08refs \u4E0B\u65E0\u5176\u4ED6\u952E\u65F6\u4FDD\u7559\u7A7A\u7684 refs: \u9AA8\u67B6\uFF0C\u662F\u5408\u6CD5\u7A7A\u5B58\u50A8\uFF09\n if (foundIdx >= 0) lines.splice(foundIdx, 1);\n } else {\n if (foundIdx >= 0) {\n lines[foundIdx] = ` ${refKey}: ${JSON.stringify(value)}`;\n } else {\n if (refsLineIdx >= 0) {\n lines.splice(refsLineIdx + 1, 0, ` ${refKey}: ${JSON.stringify(value)}`);\n } else {\n lines.push('refs:', ` ${refKey}: ${JSON.stringify(value)}`);\n }\n }\n }\n\n await atomicWriteFile(cFile, lines.join('\\n'), 0o600);\n}\n\n// ===== settings.yaml \u624B\u5199\u8BFB\u5199\uFF08\u539F\u751F\u7F1D\u7F3A\u5931/\u5199\u5165\u5931\u8D25\u65F6\u7684\u515C\u5E95\uFF09 =====\n\n/** \u89E3\u6790 settings.yaml \u4E2D llm-pi-ai.providers.a6api \u5757\u7684\u6A21\u578B ID \u5217\u8868 */\nasync function readRawConfiguredModels(): Promise<string[]> {\n try {\n const yaml = await fsp.readFile(settingsFile(), 'utf8');\n const lines = yaml.split(/\\r?\\n/);\n let inA6 = false;\n let inModels = false;\n const modelIds: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (indent === 4 && trimmed.startsWith('a6api:')) {\n inA6 = true;\n inModels = false;\n continue;\n }\n if (inA6 && indent <= 4 && !trimmed.startsWith('a6api:')) {\n inA6 = false;\n inModels = false;\n }\n if (inA6 && indent === 6 && trimmed.startsWith('models:')) {\n inModels = true;\n continue;\n }\n if (inModels && indent === 8 && trimmed.startsWith('- id:')) {\n const id = trimmed.replace(/^- id:\\s*/, '').trim();\n if (id) modelIds.push(id);\n }\n }\n return modelIds;\n } catch {\n return [];\n }\n}\n\n/** \u89E3\u6790 settings.yaml \u4E2D a6api \u5757\u7684 baseURL\uFF08\u542B /v1 \u540E\u7F00\uFF09 */\nasync function readRawA6apiBaseURL(): Promise<string> {\n try {\n const yaml = await fsp.readFile(settingsFile(), 'utf8');\n let inA6 = false;\n for (const line of yaml.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n if (indent === 4 && trimmed.startsWith('a6api:')) {\n inA6 = true;\n continue;\n }\n if (inA6 && indent <= 4 && !trimmed.startsWith('a6api:')) inA6 = false;\n if (inA6 && indent === 6 && trimmed.startsWith('baseURL:')) {\n return trimmed.replace(/^baseURL:\\s*/, '').trim().replace(/^[\"']|[\"']$/g, '');\n }\n }\n } catch {}\n return '';\n}\n\n/** \u5B9A\u4F4D settings.yaml \u4E2D `llm-pi-ai:` -> `providers:` -> `a6api:` \u7684\u884C\u533A\u95F4\uFF08\u4F9B\u5199\u5165/\u79FB\u9664\u5171\u7528\uFF09 */\nfunction scanA6apiBlockRange(lines: string[]): {\n a6Start: number;\n a6End: number;\n providersLineIdx: number;\n llmLineIdx: number;\n} {\n let inLlm = false;\n let inProviders = false;\n let inA6 = false;\n let a6Start = -1;\n let a6End = -1;\n let providersLineIdx = -1;\n let llmLineIdx = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const indent = line.match(/^\\s*/)?.[0].length ?? 0;\n\n if (indent === 0) {\n inLlm = trimmed.startsWith('llm-pi-ai:');\n if (inLlm) llmLineIdx = i;\n inProviders = false;\n inA6 = false;\n continue;\n }\n\n if (inLlm && indent === 2 && trimmed.startsWith('providers:')) {\n inProviders = true;\n providersLineIdx = i;\n inA6 = false;\n continue;\n }\n\n if (inProviders && indent === 4) {\n if (trimmed.startsWith('a6api:')) {\n inA6 = true;\n a6Start = i;\n a6End = i + 1;\n } else {\n if (inA6) {\n a6End = i;\n inA6 = false;\n }\n }\n continue;\n }\n\n if (inA6 && indent > 4) {\n a6End = i + 1;\n } else if (inA6 && indent <= 4) {\n a6End = i;\n inA6 = false;\n }\n }\n\n return { a6Start, a6End, providersLineIdx, llmLineIdx };\n}\n\n/** \u88F8\u5199 a6api \u63D0\u4F9B\u5546\u5757\u5230 settings.yaml\uFF08\u539F\u751F\u7F1D\u5199\u5165\u5931\u8D25\u65F6\u7684\u515C\u5E95\uFF0C\u683C\u5F0F\u4E0E DSH \u539F\u751F\u4E00\u81F4\uFF09\u3002\n * \u6CE8\u610F\uFF1A\u4EC5\u4EE5\u975E\u7A7A\u6A21\u578B\u5217\u8868\u8C03\u7528\uFF08\u7A7A\u5217\u8868\u8D70\u79FB\u9664\u8DEF\u5F84\uFF09\uFF1B\u6574\u5757\u66FF\u6362\u4F1A\u4E22\u5F03\u7528\u6237\u5728\u5757\u5185\u624B\u5DE5\u6DFB\u52A0\u7684\n * \u5176\u4ED6\u5B57\u6BB5\uFF08\u5982 compat\uFF09\uFF0C\u4E0E\u539F\u751F update \u7684 merge \u8BED\u4E49\u6709\u5DEE\u5F02\uFF0C\u5C5E\u515C\u5E95\u8DEF\u5F84\u7684\u5DF2\u77E5\u53D6\u820D\u3002 */\nasync function writeRawA6apiBlock(baseURL: string, modelIds: string[]): Promise<void> {\n const sFile = settingsFile();\n let yaml = '';\n try {\n yaml = await fsp.readFile(sFile, 'utf8');\n } catch {\n yaml = 'llm-pi-ai:\\n providers:\\n';\n }\n\n const modelEntries = modelIds.map((id) => {\n // \u53C2\u6570\u4EE5\u76EE\u5F55\u4E3A\u51C6\uFF1A\u6709\u5219\u5199\u5165\uFF0C\u7F3A\u5219\u7701\u7565\uFF08llm-pi-ai \u7528\u9ED8\u8BA4\u503C\u515C\u5E95\uFF09\uFF0C\u7EDD\u4E0D\u5199\u63A8\u65AD\u503C\n const entry = getCatalogEntry(id);\n const lines = [` - id: ${id}`];\n // name \u7528 JSON \u53CC\u5F15\u53F7\u5E8F\u5217\u5316\uFF08\u9632 YAML \u6CE8\u5165\uFF1A\u5192\u53F7/#/\u6362\u884C\uFF09\uFF0C\u5E76\u53BB\u9664\u6362\u884C\n if (entry?.name) lines.push(` name: ${JSON.stringify(String(entry.name).replace(/\\r?\\n/g, ' '))}`);\n if (entry?.contextWindow != null) lines.push(` contextWindow: ${entry.contextWindow}`);\n if (entry?.maxTokens != null) lines.push(` maxTokens: ${entry.maxTokens}`);\n if (entry?.input && entry.input.length > 0) {\n lines.push(` input:`);\n for (const m of entry.input) lines.push(` - ${m}`);\n }\n if (entry?.reasoningEfforts && typeof entry.reasoningEfforts === 'object') {\n lines.push(` reasoningEfforts:`);\n for (const [k, v] of Object.entries(entry.reasoningEfforts)) {\n // null \u503C\u8F93\u51FA valueless \u952E\uFF08\u5982 `off: `\uFF0CDSH \u89E3\u6790\u4E3A supported-send-nothing\uFF0C\u4E0E native \u8DEF\u5F84\u8BED\u4E49\u4E00\u81F4\uFF09\n lines.push(v ? ` ${k}: ${v}` : ` ${k}: `);\n }\n }\n return lines.join('\\n');\n });\n\n // Ensure OpenAI compatible endpoints in DSH settings.yaml have the /v1 suffix\n const dshBaseUrl = baseURL.endsWith('/v1') ? baseURL : `${baseURL.replace(/\\/+$/, '')}/v1`;\n\n const a6apiBlockLines = [\n ` a6api:`,\n ` displayName: A6API`,\n ` apiKeyEnv: ${A6API_CRED_REF}`,\n ` api: openai-completions`,\n ` baseURL: ${dshBaseUrl}`,\n ` models:`,\n ...modelEntries,\n ];\n\n const lines = yaml.split(/\\r?\\n/);\n const { a6Start, a6End, providersLineIdx, llmLineIdx } = scanA6apiBlockRange(lines);\n\n if (a6Start >= 0) {\n // Replace existing a6api block\n lines.splice(a6Start, a6End - a6Start, ...a6apiBlockLines);\n } else if (providersLineIdx >= 0) {\n // Insert under providers:\n lines.splice(providersLineIdx + 1, 0, ...a6apiBlockLines);\n } else if (llmLineIdx >= 0) {\n // Insert providers: then a6api\n lines.splice(llmLineIdx + 1, 0, ` providers:`, ...a6apiBlockLines);\n } else {\n // Insert llm-pi-ai: providers: a6api\n lines.push(`llm-pi-ai:`, ` providers:`, ...a6apiBlockLines);\n }\n\n await atomicWriteFile(sFile, lines.join('\\n'), 0o644);\n}\n\n/**\n * \u88F8\u5199\u79FB\u9664 a6api \u5757\uFF08\u539F\u751F\u7F1D\u7F3A\u5931/\u5931\u8D25\u65F6\u7684\u515C\u5E95\uFF09\u3002\n * DSH schema \u5BF9\u624B\u5199\u8DEF\u7531\u65E0\u5408\u6CD5\u7684\u96F6\u6A21\u578B\u8868\u793A\uFF0C\u7A7A\u6A21\u578B\u5217\u8868 = \u79FB\u9664\u6574\u4E2A\u5757\uFF1B\n * \u5757\u79FB\u9664\u540E\u987A\u5E26\u6E05\u7406\u7A7A\u58F3\uFF08providers/llm-pi-ai \u4E0B\u65E0\u5176\u4ED6\u952E\u65F6\u4E00\u5E76\u5220\u9664\uFF09\uFF0C\u4FDD\u6301 YAML \u5408\u6CD5\u3002\n */\nasync function removeRawA6apiBlock(): Promise<void> {\n const sFile = settingsFile();\n let yaml = '';\n try {\n yaml = await fsp.readFile(sFile, 'utf8');\n } catch {\n return; // \u65E0\u6587\u4EF6\u6216\u4E0D\u53EF\u8BFB\uFF0C\u65E0\u4E8B\u53EF\u505A\n }\n\n const lines = yaml.split(/\\r?\\n/);\n const { a6Start, a6End, providersLineIdx, llmLineIdx } = scanA6apiBlockRange(lines);\n if (a6Start < 0) return;\n\n lines.splice(a6Start, a6End - a6Start);\n\n // \u6E05\u7406\u7A7A\u58F3\uFF1Aproviders \u4E0B\u65E0\u5176\u4ED6 indent-4 provider \u952E \u2192 \u79FB\u9664 providers \u884C\uFF1Bllm-pi-ai \u4E0B\u65E0\u5176\u4ED6 indent-2 \u952E \u2192 \u79FB\u9664 llm-pi-ai \u884C\n if (providersLineIdx >= 0) {\n let hasProvider = false;\n for (let i = providersLineIdx + 1; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const indent = lines[i].match(/^\\s*/)?.[0].length ?? 0;\n if (indent <= 2) break;\n if (indent === 4) {\n hasProvider = true;\n break;\n }\n }\n if (!hasProvider) lines.splice(providersLineIdx, 1);\n }\n if (llmLineIdx >= 0) {\n let hasLlmKey = false;\n for (let i = llmLineIdx + 1; i < lines.length; i++) {\n const trimmed = lines[i].trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const indent = lines[i].match(/^\\s*/)?.[0].length ?? 0;\n if (indent === 0) break;\n if (indent === 2) {\n hasLlmKey = true;\n break;\n }\n }\n if (!hasLlmKey) lines.splice(llmLineIdx, 1);\n }\n\n await atomicWriteFile(sFile, lines.join('\\n'), 0o644);\n}\n\n// ===== \u65E7\u7248\u72EC\u7ACB\u914D\u7F6E\u6587\u4EF6\uFF08dsh-a6api-config.json\uFF09\u8BFB\u53D6\u4E0E\u89C4\u8303\u5316 =====\n\n/** \u65E7\u5B57\u6BB5\u522B\u540D\u6536\u655B\uFF1AaccessToken / systemAccessToken / sessionCookie \u662F\u540C\u4E00\u4E2A\u51ED\u636E\u7684\u5386\u4EE3\u547D\u540D */\nfunction normalizeLegacy(parsed: any): {\n baseURL: string;\n apiKey: string;\n accessToken: string;\n userId: string;\n activeModels: string[];\n} {\n return {\n apiKey: typeof parsed?.apiKey === 'string' ? parsed.apiKey : '',\n accessToken: String(parsed?.accessToken || parsed?.systemAccessToken || parsed?.sessionCookie || ''),\n userId: String(parsed?.userId || ''),\n baseURL: typeof parsed?.baseURL === 'string' && parsed.baseURL ? parsed.baseURL : DEFAULT_BASE_URL,\n activeModels: Array.isArray(parsed?.activeModels) ? parsed.activeModels.filter((m: any) => typeof m === 'string') : [],\n };\n}\n\n/** \u65E7\u6587\u4EF6\u8BFB\u53D6\uFF08\u8FC1\u79FB\u672A\u5B8C\u6210/\u5931\u8D25\u65F6\u7684\u672B\u7EA7\u515C\u5E95\uFF1B\u522B\u540D\u53EA\u5728\u8BFB\u53D6\u94FE\u4E0A\u5B58\u5728\uFF09 */\nasync function readLegacyConfig(): Promise<A6ApiConfig | null> {\n try {\n const raw = await fsp.readFile(legacyConfigFile(), 'utf8');\n const legacy = normalizeLegacy(JSON.parse(raw));\n return {\n baseURL: legacy.baseURL,\n apiKey: legacy.apiKey,\n accessToken: legacy.accessToken || undefined,\n userId: legacy.userId || undefined,\n activeModels: legacy.activeModels,\n };\n } catch {\n return null;\n }\n}\n\n/** \u6784\u5EFA llm-pi-ai.providers.a6api \u5757\uFF08\u4E0E DSH \u539F\u751F schema \u517C\u5BB9\uFF1Aopenai-completions + /v1 \u7AEF\u70B9\uFF09\u3002\n * \u53C2\u6570\u6765\u81EA\u6A21\u578B\u76EE\u5F55\uFF08getCatalogEntry\uFF09\uFF1A\u6709\u5219\u5199\u5165\uFF0C\u7F3A\u5219\u7701\u7565\u8BE5\u5B57\u6BB5\uFF08llm-pi-ai \u9ED8\u8BA4\u503C\u515C\u5E95\uFF09\u3002 */\nfunction buildA6apiBlock(baseURL: string, modelIds: string[]): Record<string, any> {\n const models = modelIds.map((id) => {\n const entry = getCatalogEntry(id);\n const m: Record<string, any> = { id };\n if (entry?.name) m.name = entry.name;\n if (entry?.contextWindow != null) m.contextWindow = entry.contextWindow;\n if (entry?.maxTokens != null) m.maxTokens = entry.maxTokens;\n if (entry?.input && entry.input.length > 0) m.input = [...entry.input];\n if (entry?.reasoningEfforts !== undefined && entry.reasoningEfforts !== null) {\n m.reasoningEfforts = entry.reasoningEfforts;\n }\n return m;\n });\n return {\n displayName: 'A6API',\n apiKeyEnv: A6API_CRED_REF,\n api: 'openai-completions',\n baseURL: baseURL.endsWith('/v1') ? baseURL : `${baseURL.replace(/\\/+$/, '')}/v1`,\n models,\n };\n}\n\nexport interface ConfigAccess {\n /** \u89E6\u53D1\uFF08\u5E76\u7B49\u5F85\uFF09\u65E7\u914D\u7F6E\u6587\u4EF6\u7684\u81EA\u52A8\u8FC1\u79FB\uFF1B\u5E42\u7B49\uFF0C\u8FDB\u7A0B\u5185\u53EA\u6267\u884C\u4E00\u6B21\uFF0C\u5931\u8D25\u4E0D\u963B\u585E */\n ensureMigrated(): Promise<void>;\n /** \u8BFB\u53D6\u5F53\u524D\u914D\u7F6E\uFF1A\u539F\u751F\u7F1D\u4F18\u5148\uFF0C\u9010\u7EA7\u515C\u5E95\u5230\u65E7\u6587\u4EF6 */\n readConfig(): Promise<A6ApiConfig>;\n /** \u5199\u5165\u51ED\u636E\u5B57\u6BB5\uFF08\u7A7A\u4E32 = \u6E05\u9664\uFF0C\u8D70 unset\uFF09\uFF1Bsettings \u540C\u6B65\u8BF7\u7528 syncModels */\n writeConfig(parts: Partial<Pick<A6ApiConfig, 'apiKey' | 'accessToken' | 'userId'>>): Promise<void>;\n /** \u628A\u6A21\u578B\u5217\u8868\uFF08\u4E0E baseURL\uFF09\u540C\u6B65\u8FDB DSH settings.yaml \u7684 llm-pi-ai.providers.a6api \u5757 */\n syncModels(baseURL: string, modelIds: string[]): Promise<void>;\n /** \u5F53\u524D DSH \u5DF2\u914D\u7F6E\u7684 a6api \u6A21\u578B ID \u5217\u8868 */\n getDshConfiguredModels(): Promise<string[]>;\n}\n\nexport function createConfigAccess(ctx: any): ConfigAccess {\n let migration: Promise<void> | null = null;\n\n const ensureMigrated = (): Promise<void> => {\n if (!migration) {\n migration = doMigrate().catch((err: any) => {\n // \u8FC1\u79FB\u5931\u8D25\u4E0D\u963B\u585E\uFF1A\u4FDD\u7559\u65E7\u6587\u4EF6\uFF0CreadConfig \u7684\u672B\u7EA7\u515C\u5E95\u7EE7\u7EED\u5DE5\u4F5C\uFF0C\u4E0B\u6B21\u542F\u52A8\u91CD\u8BD5\n console.warn('[dsh-a6api] \u65E7\u914D\u7F6E\u8FC1\u79FB\u5931\u8D25\uFF08\u4FDD\u7559\u65E7\u6587\u4EF6\u8BFB\u53D6\u515C\u5E95\uFF09:', err?.message || err);\n });\n }\n return migration;\n };\n\n /** \u8BFB\u4E00\u4E2A\u51ED\u636E ref\uFF1A\u539F\u751F resolve\uFF08env \u4F18\u5148\uFF09\u2192 \u6587\u4EF6\u76F4\u8BFB\u515C\u5E95 */\n const resolveRef = async (creds: any, ref: string): Promise<string> => {\n try {\n if (creds && typeof creds.resolve === 'function') {\n const r = await creds.resolve(ref);\n return r && typeof r.value === 'string' ? r.value : '';\n }\n } catch (err: any) {\n console.warn(`[dsh-a6api] credentials.resolve(${ref}) failed:`, err?.message || err);\n }\n return (await readCredentialKey(ref)) || '';\n };\n\n /** \u8BFB llm-pi-ai.providers.a6api \u5757\uFF1A\u539F\u751F settings.get \u4F18\u5148 */\n const readA6apiBlock = async (\n settings: any,\n ): Promise<{ baseURL?: string; models: string[] } | null> => {\n try {\n if (settings && typeof settings.get === 'function') {\n const llm = settings.get(SETTINGS_NS);\n const block = llm && llm.providers ? llm.providers[PROVIDER_KEY] : undefined;\n if (block && typeof block === 'object') {\n return {\n baseURL: typeof block.baseURL === 'string' ? block.baseURL : undefined,\n models: Array.isArray(block.models)\n ? block.models\n .map((m: any) => (typeof m === 'string' ? m : m && typeof m.id === 'string' ? m.id : ''))\n .filter(Boolean)\n : [],\n };\n }\n }\n } catch (err: any) {\n console.warn('[dsh-a6api] settings.get(llm-pi-ai) failed:', err?.message || err);\n }\n return null;\n };\n\n const readConfig = async (): Promise<A6ApiConfig> => {\n await ensureMigrated();\n const creds = getCredentials(ctx);\n const settings = getSettings(ctx);\n\n // \u51ED\u636E\uFF1A\u539F\u751F resolve\uFF08env \u4F18\u5148\uFF09\u2192 \u6587\u4EF6\u76F4\u8BFB\u515C\u5E95\n const apiKey = await resolveRef(creds, A6API_CRED_REF);\n const accessToken = await resolveRef(creds, A6API_TOKEN_REF);\n const userId = await resolveRef(creds, A6API_USER_REF);\n\n // \u975E\u673A\u5BC6\u72B6\u6001\uFF1Allm-pi-ai.providers.a6api \u5757\uFF08\u539F\u751F\u89E3\u6790\u4F18\u5148\uFF0C\u88F8\u8BFB\u515C\u5E95\uFF09\n let baseURL = DEFAULT_BASE_URL;\n let activeModels: string[] = [];\n const block = await readA6apiBlock(settings);\n if (block) {\n if (block.baseURL) baseURL = stripV1(block.baseURL) || DEFAULT_BASE_URL;\n activeModels = block.models;\n } else {\n const rawBase = await readRawA6apiBaseURL();\n if (rawBase) baseURL = stripV1(rawBase) || DEFAULT_BASE_URL;\n activeModels = await readRawConfiguredModels();\n }\n\n // \u672B\u7EA7\u515C\u5E95\uFF1A\u539F\u751F\u51ED\u636E\u4E3A\u7A7A\u4E14\u65E7\u6587\u4EF6\u4ECD\u5728\uFF08\u8FC1\u79FB\u672A\u5B8C\u6210\u6216\u5931\u8D25\uFF09\u2192 \u65E7\u6587\u4EF6\u53EA\u586B\u7A7A\u5B57\u6BB5\uFF0C\n // \u975E\u673A\u5BC6\u72B6\u6001\u59CB\u7EC8\u4EE5\u539F\u751F settings \u4E3A\u51C6\uFF08\u907F\u514D\u65E7\u503C\u906E\u853D\u7528\u6237\u8FC1\u79FB\u5931\u8D25\u540E\u65B0\u6539\u7684\u8282\u70B9/\u6A21\u578B\uFF09\n if (!apiKey && !accessToken && fs.existsSync(legacyConfigFile())) {\n const legacy = await readLegacyConfig();\n if (legacy) {\n return {\n baseURL: baseURL || legacy.baseURL,\n apiKey: apiKey || legacy.apiKey,\n accessToken: accessToken || legacy.accessToken,\n userId: userId || legacy.userId,\n activeModels: activeModels.length > 0 ? activeModels : legacy.activeModels,\n };\n }\n }\n\n return { baseURL, apiKey, accessToken, userId, activeModels };\n };\n\n const writeConfig = async (\n parts: Partial<Pick<A6ApiConfig, 'apiKey' | 'accessToken' | 'userId'>>,\n ): Promise<void> => {\n // \u5148\u7B49\u8FC1\u79FB\u5B8C\u6210\uFF0C\u907F\u514D fillRef \u7684\u300C\u8BFB\u2192\u5199\u300D\u4E24\u6B65\u628A\u8FC1\u79FB\u503C\u8986\u76D6\u7528\u6237\u521A\u5199\u5165\u7684\u65B0\u503C\n await ensureMigrated();\n const creds = getCredentials(ctx);\n const entries: Array<[string, string | undefined]> = [\n [A6API_CRED_REF, parts.apiKey],\n [A6API_TOKEN_REF, parts.accessToken],\n [A6API_USER_REF, parts.userId],\n ];\n for (const [ref, value] of entries) {\n if (value === undefined) continue;\n const v = value.trim();\n try {\n if (creds && typeof creds.set === 'function' && typeof creds.unset === 'function') {\n if (v) await creds.set(ref, v);\n else await creds.unset(ref);\n } else {\n // \u515C\u5E95\u8DEF\u5F84\uFF1AwriteCredentialKey \u5BF9\u7A7A\u4E32\u6267\u884C\u5220\u9664\uFF08DSH credentials-local \u62D2\u6536\u7A7A ref \u503C\uFF09\n await writeCredentialKey(ref, v);\n }\n } catch (err: any) {\n // env \u906E\u853D\uFF08assertUnshadowed\uFF09\u7B49\u573A\u666F\uFF1A\u8DF3\u8FC7\u5199\u5165\uFF0Cenv \u503C\u4F18\u5148\u7B26\u5408 DSH \u539F\u751F\u8BED\u4E49\n console.warn(`[dsh-a6api] \u5199\u5165\u51ED\u636E ${ref} \u5931\u8D25\uFF08\u5DF2\u8DF3\u8FC7\uFF09:`, err?.message || err);\n }\n }\n };\n\n const syncModels = async (baseURL: string, modelIds: string[]): Promise<void> => {\n const settings = getSettings(ctx);\n if (modelIds.length === 0) {\n // DSH \u786C\u7EA6\u675F\uFF1Allm-pi-ai \u5BF9\u624B\u5199\u8DEF\u7531\uFF08a6api \u4E0D\u5728\u5185\u7F6E catalog\uFF09\u4E0D\u5B58\u5728\u5408\u6CD5\u7684\u300C\u96F6\u6A21\u578B\u300D\u8868\u793A\uFF0C\n // assertServiceable \u4F1A\u62D2\u7EDD models: []\uFF08\"resolves no models...\"\uFF09\uFF0C\u5199\u76D8\u5C06\u6BD2\u5316\u4E0B\u6B21\u542F\u52A8\u3002\n // \u7A7A\u5217\u8868 = \u79FB\u9664\u6574\u4E2A a6api \u5757\uFF08\u8DEF\u7531\u4ECE DSH \u6D88\u5931\uFF1BbaseURL \u968F\u5757\u4E00\u5E76\u79FB\u9664\uFF0C\u5C5E schema \u7EA6\u675F\u4E0B\u7684\u5FC5\u7136\uFF09\u3002\n if (settings && typeof settings.mutate === 'function') {\n try {\n await settings.mutate(SETTINGS_NS, [{ op: 'unset', path: ['providers', PROVIDER_KEY] }]);\n return;\n } catch (err: any) {\n console.warn('[dsh-a6api] settings.mutate(llm-pi-ai) \u79FB\u9664 a6api \u5757\u5931\u8D25\uFF0C\u56DE\u9000\u88F8\u5199 settings.yaml:', err?.message || err);\n }\n }\n await removeRawA6apiBlock();\n return;\n }\n\n const block = buildA6apiBlock(baseURL, modelIds);\n if (settings && typeof settings.update === 'function') {\n try {\n // \u539F\u751F\u7F1D\uFF1A\u547D\u540D\u7A7A\u95F4\u4E32\u884C\u5199\u961F\u5217 + schema \u6821\u9A8C + \u70ED\u53D1\u5E03\uFF08\u5408\u5E76\u8BED\u4E49\uFF0C\u4E0D\u5F71\u54CD\u5176\u4ED6 provider\uFF09\n await settings.update(SETTINGS_NS, { providers: { [PROVIDER_KEY]: block } });\n return;\n } catch (err: any) {\n console.warn('[dsh-a6api] settings.update(llm-pi-ai) \u5931\u8D25\uFF0C\u56DE\u9000\u88F8\u5199 settings.yaml:', err?.message || err);\n }\n }\n await writeRawA6apiBlock(baseURL, modelIds);\n };\n\n const getDshConfiguredModels = async (): Promise<string[]> => {\n const block = await readA6apiBlock(getSettings(ctx));\n if (block) return block.models;\n return readRawConfiguredModels();\n };\n\n /** \u53EA\u586B\u7A7A\uFF1A\u8FC1\u79FB\u503C\u4EC5\u5728\u5F53\u524D\u65E0\u8BE5 ref\uFF08\u542B env \u8986\u76D6\uFF09\u65F6\u5199\u5165\uFF1B\u8FD4\u56DE false = \u5199\u5165\u5931\u8D25\uFF08\u9700\u4FDD\u7559\u65E7\u6587\u4EF6\uFF09 */\n const fillRef = async (creds: any, ref: string, value: string): Promise<boolean> => {\n if (!value) return true; // \u65E0\u503C\u53EF\u8FC1 = \u65E0\u9700\u5199 = \u89C6\u4E3A\u6210\u529F\n try {\n const current = await resolveRef(creds, ref);\n if (current) return true; // \u5DF2\u6709\u503C\uFF08\u542B env \u8986\u76D6\uFF09\uFF0C\u65E0\u9700\u5199\n if (creds && typeof creds.set === 'function') await creds.set(ref, value);\n else await writeCredentialKey(ref, value);\n return true;\n } catch (err: any) {\n console.warn(`[dsh-a6api] \u8FC1\u79FB ${ref} \u5931\u8D25\uFF08\u8DF3\u8FC7\uFF0C\u4FDD\u7559\u65E7\u6587\u4EF6\uFF09:`, err?.message || err);\n return false;\n }\n };\n\n const archiveLegacy = async (filePath: string): Promise<void> => {\n try {\n await fsp.rename(filePath, `${filePath}.bak`);\n console.log('[dsh-a6api] \u65E7\u914D\u7F6E\u5DF2\u8FC1\u79FB\u81F3 DSH \u539F\u751F\u914D\u7F6E\u5E76\u5F52\u6863: dsh-a6api-config.json.bak');\n } catch (err: any) {\n console.warn('[dsh-a6api] \u65E7\u914D\u7F6E\u5F52\u6863\u5931\u8D25\uFF08\u8FC1\u79FB\u503C\u5DF2\u5199\u5165\uFF0C\u65E7\u6587\u4EF6\u4FDD\u7559\uFF0C\u4E0B\u6B21\u542F\u52A8\u91CD\u8BD5\uFF09:', err?.message || err);\n }\n };\n\n const doMigrate = async (): Promise<void> => {\n const filePath = legacyConfigFile();\n let raw = '';\n try {\n raw = await fsp.readFile(filePath, 'utf8');\n } catch {\n return; // \u65E0\u65E7\u6587\u4EF6\uFF0C\u65E0\u4E8B\u53EF\u505A\n }\n\n let parsed: any;\n try {\n parsed = JSON.parse(raw);\n } catch (err: any) {\n console.warn('[dsh-a6api] \u65E7\u914D\u7F6E\u6587\u4EF6\u635F\u574F\uFF0C\u8DF3\u8FC7\u8FC1\u79FB\u5E76\u5F52\u6863:', err?.message || err);\n await archiveLegacy(filePath);\n return;\n }\n\n const legacy = normalizeLegacy(parsed);\n const creds = getCredentials(ctx);\n\n // \u51ED\u636E\uFF1A\u53EA\u586B\u7A7A\u4E0D\u8986\u76D6\uFF08\u5F53\u524D\u5DF2\u6709\u503C\u6216 env \u8986\u76D6\u5219\u4E0D\u52A8\uFF09\uFF1B\n // \u4EFB\u4E00\u5199\u5165\u5931\u8D25 \u2192 \u4E0D\u5F52\u6863\uFF08\u51B3\u7B56\uFF1A\u5168\u90E8\u5199\u6210\u529F\u540E\u624D\u5F52\u6863\uFF09\uFF0C\u4FDD\u7559\u65E7\u6587\u4EF6\u8BFB\u53D6\u515C\u5E95\u4E0E\u4E0B\u6B21\u542F\u52A8\u91CD\u8BD5\u3002\n // \u987A\u5E8F\u6267\u884C\uFF1A\u515C\u5E95\u8DEF\u5F84 writeCredentialKey \u662F\u8BFB-\u6539-\u5199\u540C\u4E00\u6587\u4EF6\uFF0C\u5E76\u53D1\u4F1A\u4E92\u76F8\u8986\u76D6\u3002\n const fillResults = [\n await fillRef(creds, A6API_CRED_REF, legacy.apiKey),\n await fillRef(creds, A6API_TOKEN_REF, legacy.accessToken),\n await fillRef(creds, A6API_USER_REF, legacy.userId),\n ];\n if (fillResults.some((ok) => !ok)) {\n console.warn('[dsh-a6api] \u51ED\u636E\u8FC1\u79FB\u672A\u5168\u90E8\u6210\u529F\uFF0C\u8DF3\u8FC7\u5F52\u6863\uFF0C\u4FDD\u7559\u65E7\u6587\u4EF6\u8BFB\u53D6\u515C\u5E95\uFF08\u4E0B\u6B21\u542F\u52A8\u91CD\u8BD5\uFF09');\n return;\n }\n\n // settings\uFF1A\u4EC5\u5F53 a6api \u5757\u4E0D\u5B58\u5728\u65F6\u56DE\u586B\uFF08\u7EDD\u4E0D\u8986\u76D6\u7528\u6237\u5F53\u524D\u7684 settings.yaml\uFF09\n const block = await readA6apiBlock(getSettings(ctx));\n const blockExists = Boolean(block) || (await readRawConfiguredModels()).length > 0;\n if (!blockExists && legacy.activeModels.length > 0) {\n await syncModels(legacy.baseURL, legacy.activeModels);\n }\n\n await archiveLegacy(filePath);\n };\n\n return { ensureMigrated, readConfig, writeConfig, syncModels, getDshConfiguredModels };\n}\n", "export interface A6ApiConfig {\n baseURL: string;\n apiKey: string;\n accessToken?: string;\n userId?: string;\n activeModels: string[];\n /** \u670D\u52A1\u7AEF\u8131\u654F\u4E0B\u53D1\uFF1A\u662F\u5426\u5DF2\u914D\u7F6E API Key\uFF08\u771F\u5B9E\u5BC6\u94A5\u7EDD\u4E0D\u56DE\u4F20\u5BA2\u6237\u7AEF\uFF09 */\n hasApiKey?: boolean;\n /** \u670D\u52A1\u7AEF\u8131\u654F\u4E0B\u53D1\uFF1A\u662F\u5426\u5DF2\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C */\n hasToken?: boolean;\n}\n\n/**\n * \u6A21\u578B\u76EE\u5F55\u6761\u76EE\uFF08settings.yaml \u7684 llm-pi-ai \u539F\u751F\u6A21\u578B\u5B57\u6BB5 + \u5185\u90E8 brand\uFF09\u3002\n * \u53EF\u9009\u5B57\u6BB5\u7F3A\u7701 = \u53C2\u6570\u672A\u83B7\u53D6/\u672A\u586B\u5199\uFF0C\u5199 settings.yaml \u65F6\u7701\u7565\u8BE5\u5B57\u6BB5\uFF08llm-pi-ai \u9ED8\u8BA4\u503C\u515C\u5E95\uFF09\u3002\n */\nexport interface CatalogModelEntry {\n id: string;\n name?: string;\n contextWindow?: number;\n maxTokens?: number;\n input?: ('text' | 'image')[];\n /** false = \u660E\u786E\u975E\u63A8\u7406\u6A21\u578B\uFF1Bdict = \u6863\u4F4D \u2192 wire \u503C\uFF08\u503C\u53EF\u4E3A null\uFF0C\u540C llm-pi-ai \u8BED\u4E49\uFF09 */\n reasoningEfforts?: Record<string, string | null> | false;\n /** \u4EC5\u63D2\u4EF6\u5185\u90E8\u4F7F\u7528\uFF1A\u54C1\u724C\u6765\u81EA A6API \u5E02\u573A\u6E20\u9053\uFF0C\u4E0D\u5199\u5165 settings.yaml */\n brand?: string;\n /** \u6700\u8FD1\u4E00\u6B21 OpenRouter \u67E5\u8BE2/\u4EBA\u5DE5\u4FEE\u6539\u65F6\u95F4 */\n updatedAt?: number;\n}\n\n/** DSH llm-pi-ai \u652F\u6301\u7684\u5B8C\u6574\u601D\u8003\u6863\u4F4D\uFF08THINKING_LEVELS\uFF0C\u4E0E dsh-llm-pi-ai \u6E90\u7801\u4E00\u81F4\uFF09 */\nexport const THINKING_LEVEL_KEYS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const;\n\nexport type ReasoningEffortsValue = Record<string, string | null> | false;\n\n/**\n * \u6821\u9A8C reasoningEfforts\uFF08DSH llm-pi-ai \u8BED\u4E49\uFF0C\u670D\u52A1\u7AEF\u4E0E\u5BA2\u6237\u7AEF\u5171\u7528\uFF09\uFF1A\n * - false = \u975E\u63A8\u7406\u6A21\u578B\uFF0C\u5408\u6CD5\n * - \u952E\u5FC5\u987B \u2208 THINKING_LEVEL_KEYS\uFF1B\u503C\u5FC5\u987B\u975E\u7A7A\u5B57\u7B26\u4E32\uFF0C\u4EC5 off \u5141\u8BB8 null\n * - \u7A7A\u5B57\u5178\u3001\u4EC5 off \u65E0\u5176\u4ED6\u6863\u4F4D\u5747\u975E\u6CD5\n */\nexport function validateReasoningEfforts(\n value: unknown,\n): { ok: true; value: ReasoningEffortsValue } | { ok: false; error: string } {\n if (value === false) return { ok: true, value: false };\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return { ok: false, error: 'reasoningEfforts \u5FC5\u987B\u662F\u6863\u4F4D\u5B57\u5178\u6216 false' };\n }\n const dict = value as Record<string, unknown>;\n const keys = Object.keys(dict);\n if (keys.length === 0) return { ok: false, error: 'reasoningEfforts \u4E0D\u80FD\u4E3A\u7A7A\u5B57\u5178' };\n const out: Record<string, string | null> = {};\n for (const k of keys) {\n if (!(THINKING_LEVEL_KEYS as readonly string[]).includes(k)) {\n return { ok: false, error: `reasoningEfforts \u952E \"${k}\" \u4E0D\u662F DSH \u652F\u6301\u7684\u6863\u4F4D\uFF08off/minimal/low/medium/high/xhigh/max\uFF09` };\n }\n const v = dict[k];\n if (v === null) {\n if (k !== 'off') {\n return { ok: false, error: `reasoningEfforts.${k} \u5FC5\u987B\u63D0\u4F9B wire \u503C\uFF0C\u4EC5 off \u5141\u8BB8\u7559\u7A7A` };\n }\n out[k] = null;\n } else if (typeof v === 'string' && v.length > 0) {\n out[k] = v;\n } else {\n return { ok: false, error: `reasoningEfforts.${k} \u7684\u503C\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\u6216 null` };\n }\n }\n if (!keys.some((k) => k !== 'off')) {\n return { ok: false, error: 'reasoningEfforts \u9664 off \u5916\u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u601D\u8003\u6863\u4F4D\uFF08\u975E\u63A8\u7406\u6A21\u578B\u8BF7\u7528 false\uFF09' };\n }\n return { ok: true, value: out };\n}\n\nexport interface A6ApiModelMeta {\n id: string;\n name: string;\n brand: string;\n contextWindow: number;\n maxTokens: number;\n modalities: ('text' | 'image')[];\n reasoningEfforts?: Record<string, string>;\n thinkingFormat?: string;\n officialPriceMicros?: {\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n };\n}\n\nexport interface OfficialPrices {\n input_cny: string;\n output_cny: string;\n cache_read_cny: string;\n cache_write_cny: string;\n input_price_micros?: number;\n output_price_micros?: number;\n cache_read_price_micros?: number;\n cache_write_price_micros?: number;\n}\n\nexport interface SuccessBucketItem {\n sample_count?: number;\n success_count?: number;\n success_rate: number;\n}\n\nexport interface Bucket24hItem {\n s?: number;\n k?: number;\n r: number;\n t?: number;\n d?: number;\n f?: number;\n c?: number;\n}\n\nexport interface Bucket7dItem {\n s?: number;\n k?: number;\n r?: number;\n t?: number;\n d?: number;\n f?: number;\n c?: number;\n}\n\nexport interface MerchantChannelInfo {\n listing_id?: number;\n channel_id: number;\n channel_name: string;\n supplier_name: string;\n supplier_id?: number;\n model_name: string;\n brand: string;\n description: string;\n charge_type?: string;\n charge_type_text?: string;\n sample_count?: number;\n sample_count_text?: string;\n input_price_micros: number;\n output_price_micros: number;\n cache_read_price_micros: number;\n cache_write_price_micros: number;\n input_price_cny: string;\n output_price_cny: string;\n cache_read_price_cny: string;\n cache_write_price_cny: string;\n official_price?: OfficialPrices;\n realtime_ratio_cny: number;\n realtime_ratio_formatted: string;\n recent_success_rate_pct: number;\n success_rate_24h_pct: number;\n success_rate_7d_pct?: number;\n success_buckets?: SuccessBucketItem[];\n b24?: Bucket24hItem[];\n b7d?: Bucket7dItem[];\n sr_24h_state?: string;\n sr_7d_state?: string;\n p50_ttft_ms?: number;\n recent_p50_ms: number;\n cache_hit_rate_pct: number;\n labels: string[];\n last_success_at: number;\n last_success_text: string;\n authenticity_guaranteed: boolean;\n authenticity_badge?: string;\n is_pinned?: boolean;\n /** \u5B98\u65B9\u6E20\u9053\u641C\u7D22\u8FD4\u56DE\u7684\u56FA\u5B9A\u72B6\u6001\uFF1Apin_here / pin_elsewhere / undefined */\n pin_status?: string;\n user_channel_disabled?: boolean;\n supplier_channel_disabled?: boolean;\n raw?: any;\n}\n\n/** \u5E73\u53F0\u4FA7\u56FA\u5B9A\u8BB0\u5F55\uFF08GET /api/marketplace/pins\uFF09 */\nexport interface MarketplacePin {\n id?: number;\n token_id: number;\n token_name?: string;\n model_name: string;\n channel_id?: number;\n channel_name?: string;\n supplier_name?: string;\n supplier_nickname?: string;\n /** \u5F02\u5E38\u65F6\u662F\u5426\u81EA\u52A8\u5207\u6362\u667A\u80FD\u4F18\u9009\uFF08false = \u4E25\u683C\u56FA\u5B9A\uFF09 */\n fallback_to_smart_routing?: boolean;\n created_at?: number;\n raw?: any;\n}\n\n/** \u4EE4\u724C\u5217\u8868\u6761\u76EE\uFF08GET /api/token/\uFF0C\u7528\u4E8E\u628A API Key \u89E3\u6790\u4E3A token_id\uFF09 */\nexport interface A6ApiTokenItem {\n id: number;\n name?: string;\n key?: string;\n status?: number;\n raw?: any;\n}\n\nexport interface ModelCardData {\n model_name: string;\n brand: string;\n contextWindow: number;\n maxTokens: number;\n modalities: ('text' | 'image')[];\n hasReasoning: boolean;\n inDsh: boolean;\n merchant?: MerchantChannelInfo;\n probeStatus: 'idle' | 'queued' | 'probing' | 'success' | 'error';\n probeError?: string;\n probeLatencyMs?: number;\n lastProbedAt?: number;\n /** \u8DEF\u7531\u5FEB\u7167\u65F6\u6548\uFF1A\u8BE5\u6A21\u578B\u6700\u65B0\u4E00\u6761\u300C\u5E26 channel \u7684\u8C03\u7528\u65E5\u5FD7\u300D\u65F6\u95F4\uFF08\u79D2\uFF09\uFF0C\u5373\u5361\u7247\u5546\u6237\u6570\u636E\u6765\u6E90\u8BF7\u6C42\u7684\u65F6\u523B */\n lastRoutedAt?: number;\n /** \u670D\u52A1\u7AEF\u7B97\u597D\u7684\u76F8\u5BF9\u65F6\u95F4\u6587\u6848\uFF08\u5982\u300C3 \u5C0F\u65F6\u524D\u300D\uFF09\uFF0C\u65E0\u8BB0\u5F55\u65F6\u5BA2\u6237\u7AEF\u663E\u793A\u300C\u4ECE\u672A\u8DEF\u7531\u300D */\n lastRoutedText?: string;\n /** \u5E73\u53F0\u56FA\u5B9A\u72B6\u6001\uFF08\u6309\u5F53\u524D API Key \u4EE4\u724C\uFF09\uFF1A\u56FA\u5B9A\u5230\u5361\u7247\u5546\u5BB6 / \u56FA\u5B9A\u5230\u5176\u4ED6\u5546\u5BB6 / \u672A\u56FA\u5B9A */\n pinStatus?: 'pin_here' | 'pin_elsewhere';\n /** \u56FA\u5B9A\u7684\u6E20\u9053 ID\uFF08pin_elsewhere \u65F6\u7528\u4E8E\u5C55\u793A\u56FA\u5B9A\u5230\u4E86\u54EA\u5BB6\uFF09 */\n pinnedChannelId?: number;\n pinnedSupplierName?: string;\n pinnedFallback?: boolean;\n /** \u8BE5\u6A21\u578B\u5BF9\u5E94\u7684\u56FA\u5B9A\u8BB0\u5F55\u662F\u5426\u5C5E\u4E8E\u5F53\u524D API Key \u4EE4\u724C\uFF08false \u65F6\u4EC5\u4F5C\u53C2\u8003\u5C55\u793A\uFF09 */\n pinTokenMatched?: boolean;\n}\n\nexport interface BalanceInfo {\n hasAccountAuth: boolean;\n accountBalanceUsd: number;\n accountBalanceFormatted: string;\n accountBalanceCnyFormatted: string;\n usedUsd: number;\n usedFormatted: string;\n requestCount: number;\n username?: string;\n userId?: string | number;\n isLow: boolean;\n updatedAt: number;\n}\n\nexport interface ApiRoutingLogItem {\n id: number | string;\n created_at: number;\n model_name: string;\n channel?: number | string;\n channel_name?: string;\n /** \u53D1\u8D77\u8BE5\u8BF7\u6C42\u7684\u4EE4\u724C ID\uFF08\u7528\u4E8E\u628A API Key \u89E3\u6790\u4E3A\u56FA\u5B9A/\u7981\u7528\u6240\u9700\u7684 token_id\uFF09 */\n token_id?: number;\n prompt_tokens?: number;\n completion_tokens?: number;\n use_time?: number;\n quota?: number;\n cost_usd?: number;\n cost_formatted?: string;\n token_name?: string;\n status: 'success' | 'error';\n other?: string;\n raw?: any;\n}\n\nexport interface A6ApiStateResponse {\n config: A6ApiConfig;\n balance: BalanceInfo | null;\n models: ModelCardData[];\n dshConfiguredModels: string[];\n recentLogs?: ApiRoutingLogItem[];\n /** \u5E73\u53F0\u56FA\u5B9A\u8BB0\u5F55\u5217\u8868\uFF08\u7528\u4E8E\u5361\u7247\u72B6\u6001\u8DDF\u968F\u5B98\u7F51\uFF09 */\n pins?: MarketplacePin[];\n}\n// \u4EF7\u683C\u6CE2\u52A8\u80F6\u56CA\uFF08\u8F7B\u91CF\u76D1\u542C\uFF09\nexport interface PriceFluctuationState {\n pendingCount: number;\n unseenCount: number;\n totalCount: number;\n updatedAt: number | null;\n hasAuth?: boolean;\n authError?: boolean;\n}\n", "import { fetchBalance, fetchTokenModels, fetchRecentLogs, fetchPriceFluctuation, formatRelativeTime, fetchMarketplacePins, fetchTokens, fetchChannelDetails, marketplacePin, marketplaceUnpin, marketplaceDisableChannel, marketplaceRestoreChannel } from './server/a6api-client.js';\nimport { getKnownMerchantsFromLogs, probeSingleModel } from './server/probe.js';\nimport { resolveModelMeta, getCatalog, upsertCatalogEntries, clearCatalog, queryOpenRouter, fetchMarketplaceModels, updateCatalogEntry } from './server/catalog.js';\nimport { createConfigAccess } from './server/sync.js';\nimport type { A6ApiConfig, A6ApiStateResponse, MarketplacePin, MerchantChannelInfo, ModelCardData } from './types.js';\nimport { validateReasoningEfforts } from './types.js';\n\nexport const name = '@lynn123411/dsh-a6api';\nexport const inject = ['webServer'];\n\nexport {\n fetchBalance,\n fetchTokenModels,\n fetchRecentLogs,\n fetchChannelDetails,\n fetchMarketplacePins,\n} from './server/a6api-client.js';\nexport { probeSingleModel, getKnownMerchantsFromLogs } from './server/probe.js';\nexport {\n resolveModelMeta,\n inferBrand,\n getCatalog,\n getCatalogEntry,\n clearCatalog,\n queryOpenRouter,\n fetchMarketplaceModels,\n updateCatalogEntry,\n} from './server/catalog.js';\nexport { createConfigAccess, A6API_CRED_REF, A6API_TOKEN_REF, A6API_USER_REF } from './server/sync.js';\n\nconst PREFIX = '/api/dsh-a6api';\n\n/** \u5BA2\u6237\u7AEF\u8131\u654F\u5360\u4F4D\u7B26\uFF1A\u670D\u52A1\u7AEF\u7EDD\u4E0D\u56DE\u4F20\u771F\u5B9E\u5BC6\u94A5 */\nconst MASK = '\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022';\n\n/** \u8131\u654F\u914D\u7F6E\uFF1AAPI Key / \u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C / userId \u4EC5\u4EE5\u5360\u4F4D\u7B26\u5F62\u5F0F\u4E0B\u53D1\uFF0C\u771F\u5B9E\u503C\u53EA\u5B58\u5728\u4E8E\u670D\u52A1\u7AEF */\nfunction maskConfig(c: A6ApiConfig): A6ApiConfig {\n return {\n ...c,\n apiKey: c.apiKey ? MASK : '',\n accessToken: c.accessToken ? MASK : '',\n userId: c.userId ? MASK : '',\n hasApiKey: Boolean(c.apiKey),\n hasToken: Boolean(c.accessToken),\n };\n}\n\nfunction sendJson(res: any, status: number, body: any) {\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'no-cache',\n // \u4E0D\u8BBE access-control-allow-origin\uFF1A\u4EC5\u5141\u8BB8\u540C\u6E90\u8C03\u7528\uFF0C\u963B\u65AD\u8DE8\u7AD9\u8BFB\u53D6\u4E0E CSRF \u9884\u68C0\n });\n res.end(JSON.stringify(body));\n}\n\nfunction readBody(req: any): Promise<string> {\n return new Promise((resolve, reject) => {\n let data = '';\n req.on('data', (chunk: any) => {\n data += chunk;\n if (data.length > 2 * 1024 * 1024) {\n req.destroy();\n reject(new Error('Body too large'));\n }\n });\n req.on('end', () => resolve(data.trim()));\n req.on('error', reject);\n });\n}\n\nasync function parseJsonBody(req: any): Promise<any> {\n const text = await readBody(req);\n if (!text) return {};\n try {\n return JSON.parse(text);\n } catch {\n throw new Error('Invalid JSON body');\n }\n}\n\n// In-memory cache for merchant cards to avoid duplicate log calls\nconst merchantCardCache = new Map<string, { card: MerchantChannelInfo; at: number }>();\n/** \u5361\u7247\u7F13\u5B58\u6709\u6548\u671F:\u8FC7\u671F\u540E /state \u4ECE\u6700\u65B0\u65E5\u5FD7\u91CD\u65B0\u63A8\u5BFC,\u907F\u514D\u6C38\u8FDC\u5C55\u793A\u9648\u65E7\u5546\u6237 */\nconst MERCHANT_CARD_TTL_MS = 15 * 60 * 1000;\n\n/** \u4EE4\u724C\u89E3\u6790\u7ED3\u679C\u7F13\u5B58\uFF08\u907F\u514D /state \u6BCF\u6B21\u91CD\u590D\u8C03\u4EE4\u724C\u5217\u8868\uFF09 */\nlet tokenResolveCache: { tokenId: number; at: number } | null = null;\nconst TOKEN_RESOLVE_TTL_MS = 10 * 60 * 1000;\n\n/**\n * \u628A\u914D\u7F6E\u7684 API Key \u89E3\u6790\u4E3A\u5E73\u53F0 token_id\uFF08\u56FA\u5B9A/\u53D6\u6D88\u56FA\u5B9A/\u7981\u7528\u6309\u4EE4\u724C\u7ED1\u5B9A\uFF09\u3002\n * \u89E3\u6790\u94FE\uFF1A\u5185\u5B58\u7F13\u5B58\uFF08TTL\uFF09\u2192 \u4EE4\u724C\u5217\u8868\u6309 key \u7CBE\u786E\u5339\u914D \u2192 \u552F\u4E00\u4EE4\u724C\u515C\u5E95\u3002\n * \u8FD4\u56DE null \u8868\u793A\u65E0\u6CD5\u89E3\u6790\uFF08\u8C03\u7528\u65B9\u53EF\u518D\u7528\u300C\u63A2\u6D4B\u65E5\u5FD7 token_id\u300D\u515C\u5E95\uFF09\u3002\n * \u8BF4\u660E\uFF1AtokenId \u662F\u6D3E\u751F\u6570\u636E\uFF0C\u4E0D\u518D\u6301\u4E45\u5316\uFF1B\u6BCF\u6B21\u8FDB\u7A0B\u51B7\u542F\u52A8\u540E\u9996\u6B21\u56FA\u5B9A/\u53D6\u6D88\u56FA\u5B9A\u591A\u4E00\u6B21\u4EE4\u724C\u5217\u8868\u8BF7\u6C42\u3002\n */\nasync function resolveTokenId(config: A6ApiConfig): Promise<number | null> {\n if (tokenResolveCache && Date.now() - tokenResolveCache.at < TOKEN_RESOLVE_TTL_MS) {\n return tokenResolveCache.tokenId;\n }\n const token = config.accessToken || '';\n if (!config.userId || !token) return null;\n try {\n const tokens = await fetchTokens(config.userId, token);\n let tokenId: number | null = null;\n const key = (config.apiKey || '').trim();\n if (key) {\n const hit = tokens.find((t) => t.key && t.key === key);\n if (hit) tokenId = hit.id;\n }\n if (!tokenId && tokens.length === 1) tokenId = tokens[0].id;\n if (tokenId && tokenId > 0) {\n tokenResolveCache = { tokenId, at: Date.now() };\n return tokenId;\n }\n } catch (err) {\n console.warn('[dsh-a6api] resolveTokenId error:', err);\n }\n return null;\n}\n\n/** \u53D6\u5F53\u524D Web \u4F1A\u8BDD\u51ED\u636E\uFF08\u56FA\u5B9A\u65CF\u63A5\u53E3\u9274\u6743\uFF0C\u4E0E\u5E02\u573A\u4EF7\u683C\u6CE2\u52A8\u540C\u6E90\uFF09 */\nfunction webAuthOf(config: A6ApiConfig): { userId?: string; token?: string } {\n return { userId: config.userId || undefined, token: config.accessToken || undefined };\n}\n\n/** \u4ECE\u7F13\u5B58\u53D6\u6A21\u578B\u5546\u5BB6\u5361\u7247\uFF08TTL \u5185\u6709\u6548\uFF09 */\nfunction cachedMerchantOf(modelName: string): MerchantChannelInfo | undefined {\n const entry = merchantCardCache.get(modelName.toLowerCase());\n return entry && Date.now() - entry.at < MERCHANT_CARD_TTL_MS ? entry.card : undefined;\n}\n\n/** \u628A\u56FA\u5B9A\u8BB0\u5F55\u53E0\u52A0\u5230\u6A21\u578B\u5361\u7247\u4E0A\uFF08pin_here / pin_elsewhere / \u7981\u7528\u7B49\u5C55\u793A\u5B57\u6BB5\uFF09 */\nfunction overlayPinsOnModels(models: ModelCardData[], pins: MarketplacePin[], tokenId?: number | null): ModelCardData[] {\n const byModel = new Map<string, MarketplacePin[]>();\n for (const p of pins) {\n const key = (p.model_name || '').toLowerCase();\n if (!key) continue;\n const list = byModel.get(key);\n if (list) list.push(p);\n else byModel.set(key, [p]);\n }\n return models.map((m) => {\n const list = byModel.get(m.model_name.toLowerCase());\n if (!list || list.length === 0) return m;\n // \u4F18\u5148\u53D6\u5F53\u524D\u4EE4\u724C\u7684\u56FA\u5B9A\u8BB0\u5F55\uFF1B\u89E3\u6790\u4E0D\u51FA\u4EE4\u724C\u65F6\u9000\u800C\u53D6\u4EFB\u610F\u4E00\u6761\uFF08\u6807\u6CE8\u672A\u5339\u914D\uFF09\n const pick =\n (tokenId ? list.find((p) => Number(p.token_id) === tokenId) : undefined) || list[0];\n const cardChannel = m.merchant?.channel_id;\n const pinChannel = pick.channel_id;\n return {\n ...m,\n // Number() \u5F52\u4E00\u5316\uFF1A\u5B98\u65B9\u63A5\u53E3\u53EF\u80FD\u8FD4\u56DE\u5B57\u7B26\u4E32\u6E20\u9053 ID\uFF0C\u4E25\u683C\u76F8\u7B49\u4F1A\u8BEF\u5224\n pinStatus: pinChannel\n ? cardChannel && Number(cardChannel) === Number(pinChannel)\n ? 'pin_here'\n : 'pin_elsewhere'\n : undefined,\n pinnedChannelId: pinChannel,\n pinnedSupplierName: pick.supplier_nickname || pick.supplier_name,\n pinnedFallback: pick.fallback_to_smart_routing,\n pinTokenMatched: Boolean(tokenId && Number(pick.token_id) === tokenId),\n };\n });\n}\n\nexport function apply(ctx: any): void {\n // DSH \u539F\u751F\u914D\u7F6E\u8BBF\u95EE\u5668\uFF1A\u542F\u52A8\u5373\u89E6\u53D1\u65E7\u914D\u7F6E\u6587\u4EF6\u81EA\u52A8\u8FC1\u79FB\uFF08\u5E42\u7B49\uFF0C\u9996\u6B21\u8BFB\u53D6\u4F1A\u7B49\u5F85\u5176\u5B8C\u6210\uFF09\n const configAccess = createConfigAccess(ctx);\n void configAccess.ensureMigrated();\n\n // Register Web API routes\n const webServer = ctx.webServer || (ctx.get ? ctx.get('webServer') : null);\n if (webServer && typeof webServer.register === 'function') {\n ctx.effect(() => {\n const unregister = webServer.register({\n kind: 'prefix',\n path: PREFIX,\n handler: async (req: any, res: any) => {\n const url = new URL(req.url || '/', 'http://localhost');\n const pathname = url.pathname.replace(PREFIX, '') || '/';\n\n // CORS preflight\uFF1A\u540C\u6E90\u7B56\u7565\u4E0B\u65E0\u9700\u653E\u884C\u8DE8\u6E90\uFF08\u79FB\u9664 ACAO \u540E\u8DE8\u6E90\u9884\u68C0\u5929\u7136\u5931\u8D25\uFF09\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n return res.end();\n }\n\n // CSRF \u9762\uFF1A\u540C\u6E90 POST \u4E00\u5F8B\u8981\u6C42 JSON Content-Type\uFF08\u8DE8\u7AD9\u8868\u5355\u65E0\u6CD5\u4F2A\u9020\u8BE5\u5934\uFF09\uFF1B\n // \u5BA2\u6237\u7AEF\u5168\u90E8 POST \u5DF2\u5E26 application/json\uFF08\u542B\u65E0 body \u7684 fetch-models/clear\uFF09\n if (req.method === 'POST' && !String(req.headers['content-type'] || '').toLowerCase().includes('application/json')) {\n return sendJson(res, 415, { ok: false, error: 'Content-Type must be application/json' });\n }\n\n try {\n // GET /state\n if (pathname === '/state' && (req.method === 'GET' || req.method === 'HEAD')) {\n const config = await configAccess.readConfig();\n const token = config.accessToken || '';\n // \u5E76\u884C\u62C9\u53D6\u4E92\u76F8\u72EC\u7ACB\u7684\u4E0A\u6E38\u6570\u636E\uFF1A\u4F59\u989D / \u672C\u5730\u914D\u7F6E\u6A21\u578B / \u4EE4\u724C\u6A21\u578B\u5217\u8868 / \u6700\u8FD1\u65E5\u5FD7 / \u5E73\u53F0\u56FA\u5B9A\u8BB0\u5F55\u3002\n // \u539F\u4E32\u884C 5 \u6B21\u4E0A\u6E38 RTT \u2192 1 \u6B21\uFF0C\u51B7\u8DEF\u5F84 3~10s \u2192 \u7EA6 1~2s\uFF08\u542F\u52A8\u9884\u70ED + 60s \u8F6E\u8BE2\u4F9D\u8D56\u6B64\u63D0\u901F\uFF09\u3002\n // \u9519\u8BEF\u8BED\u4E49\u4E0E\u539F\u5148\u4E00\u81F4\uFF1A\u4F59\u989D/\u6A21\u578B\u5217\u8868/\u65E5\u5FD7\u5931\u8D25\u5219\u6574\u4F53 500\uFF0C\u56FA\u5B9A\u8BB0\u5F55\u5931\u8D25\u964D\u7EA7\u4E3A\u7A7A\u3002\n const [balance, dshConfiguredModels, modelIdsRaw, allLogs, pins] = await Promise.all([\n fetchBalance(config.baseURL, config.apiKey, config.userId, token),\n configAccess.getDshConfiguredModels(),\n config.apiKey ? fetchTokenModels(config.baseURL, config.apiKey) : Promise.resolve([] as string[]),\n fetchRecentLogs(config.userId, token, 100),\n config.userId && token\n ? fetchMarketplacePins(config.userId, token).catch(() => [] as MarketplacePin[])\n : Promise.resolve([] as MarketplacePin[]),\n ]);\n\n // Auto-persist discovered userId\n if (balance?.userId && String(balance.userId) !== config.userId) {\n // \u8D26\u53F7\u53D8\u5316\uFF1A\u65E7 tokenId \u4E0D\u518D\u5BF9\u5E94\u5F53\u524D\u8D26\u53F7\uFF0C\u4F5C\u5E9F\u5E76\u91CD\u7F6E\u89E3\u6790\u7F13\u5B58\n tokenResolveCache = null;\n config.userId = String(balance.userId);\n await configAccess.writeConfig({ userId: config.userId });\n }\n\n // Fallback to DSH-configured / default models if token query returned empty\n let modelIds = modelIdsRaw;\n if (modelIds.length === 0) {\n modelIds = [\n ...new Set([\n ...dshConfiguredModels,\n 'gpt-5.6-sol',\n 'gpt-5.6-terra',\n 'gpt-5.6-luna',\n 'claude-fable-5',\n 'claude-opus-5',\n 'grok-4.6',\n ]),\n ];\n }\n\n // \u4E00\u6B21\u62C9\u53D6\u65E5\u5FD7(\u63A5\u53E3\u5B9E\u6D4B\u4E0A\u9650 100 \u6761),\u540C\u4E00\u4EFD\u6570\u636E\u7528\u4E8E: \u2460\u5546\u6237\u5361\u7247\u9884\u586B\u5145 \u2461\u8DEF\u7531\u5FEB\u7167\u65F6\u6548\u6620\u5C04 \u2462Account \u9875\u6700\u8FD1\u660E\u7EC6\n // \u9632\u5FA1\u6027\u6392\u5E8F\uFF1A\u4F9D\u8D56\u201C\u6700\u65B0\u5728\u524D\u201D\uFF0C\u82E5\u7F51\u5173\u6392\u5E8F\u53D8\u66F4\u4ECD\u80FD\u6B63\u786E\u53D6\u9996\u6761\n allLogs.sort((a, b) => (Number(b.created_at) || 0) - (Number(a.created_at) || 0));\n\n // Match known merchant cards from recent logs if not yet in cache (with 10s total timeout to avoid /state hang)\n if (config.userId || token) {\n const missing = modelIds.filter((m) => {\n const entry = merchantCardCache.get(m.toLowerCase());\n return !entry || Date.now() - entry.at >= MERCHANT_CARD_TTL_MS;\n });\n if (missing.length > 0) {\n let found: Record<string, MerchantChannelInfo> = {};\n try {\n found = await Promise.race([\n getKnownMerchantsFromLogs(config.userId, token, missing, allLogs),\n new Promise<Record<string, MerchantChannelInfo>>((resolve) => setTimeout(() => resolve({}), 10000)),\n ]);\n } catch {\n found = {};\n }\n for (const [mName, card] of Object.entries(found)) {\n merchantCardCache.set(mName.toLowerCase(), { card, at: Date.now() });\n }\n }\n }\n\n // \u8DEF\u7531\u5FEB\u7167\u65F6\u6548: \u6BCF\u4E2A\u6A21\u578B\u6700\u65B0\u4E00\u6761\u300C\u5E26 channel \u7684\u8C03\u7528\u65E5\u5FD7\u300D\u65F6\u95F4 \u2014\u2014 \u4E0E\u9884\u586B\u5145\u5361\u7247\u5546\u6237\u6570\u636E\u540C\u4E00\u6761\u89C4\u5219(\u53D6\u6700\u65B0\u547D\u4E2D\u5546\u6237\u8DEF\u7531\u7684\u8BF7\u6C42)\n const lastRoutedMap = new Map<string, number>();\n for (const log of allLogs) {\n const mName = log.model_name;\n const chId = Number(log.channel);\n const ts = Number(log.created_at) || 0;\n if (mName && chId > 0 && ts > 0 && !lastRoutedMap.has(mName.toLowerCase())) {\n lastRoutedMap.set(mName.toLowerCase(), ts);\n }\n }\n\n const dshSet = new Set(dshConfiguredModels);\n let models: ModelCardData[] = modelIds.map((mId) => {\n const meta = resolveModelMeta(mId);\n const cacheEntry = merchantCardCache.get(mId.toLowerCase());\n const cachedCard =\n cacheEntry && Date.now() - cacheEntry.at < MERCHANT_CARD_TTL_MS\n ? cacheEntry.card\n : undefined;\n const routedAt = lastRoutedMap.get(mId.toLowerCase());\n return {\n model_name: mId,\n brand: meta.brand,\n contextWindow: meta.contextWindow,\n maxTokens: meta.maxTokens,\n modalities: meta.modalities,\n hasReasoning: Boolean(meta.reasoningEfforts || meta.thinkingFormat),\n inDsh: dshSet.has(mId),\n merchant: cachedCard,\n probeStatus: cachedCard ? 'success' : 'idle',\n lastRoutedAt: routedAt,\n lastRoutedText: routedAt ? formatRelativeTime(routedAt) : undefined,\n };\n });\n\n // \u56FA\u5B9A\u72B6\u6001\u53E0\u52A0\uFF1Apins \u5DF2\u5728\u5E76\u884C\u6279\u6B21\u62C9\u53D6\uFF08\u5931\u8D25\u964D\u7EA7\u4E3A\u7A7A\u6570\u7EC4\uFF09\uFF0C\u8BA9\u5361\u7247\u72B6\u6001\u8DDF\u968F\u5B98\u7F51\n // \uFF08\u5B98\u7F51\u4FA7\u89E3\u9664\u56FA\u5B9A/\u6DA8\u4EF7\u81EA\u52A8\u89E3\u9664\u90FD\u4F1A\u53CD\u6620\u8FC7\u6765\uFF09\n const resolvedTokenId = pins.length > 0 ? await resolveTokenId(config) : null;\n models = overlayPinsOnModels(models, pins, resolvedTokenId);\n\n // \u56FA\u5B9A\u5546\u5BB6\u81EA\u52A8\u63A5\u7BA1\u5361\u7247\uFF1A\u6A21\u578B\u5DF2\u56FA\u5B9A\u5230\u300C\u975E\u5F53\u524D\u5361\u7247\u300D\u7684\u5546\u5BB6\u65F6\uFF08\u5F53\u524D\u4EE4\u724C\u7684\u56FA\u5B9A\uFF09\uFF0C\n // \u62C9\u53D6\u8BE5\u56FA\u5B9A\u5546\u5BB6\u7684\u6E20\u9053\u8BE6\u60C5\u66FF\u6362\u5361\u7247\uFF0C\u800C\u4E0D\u662F\u63D0\u793A\u300C\u5DF2\u56FA\u5B9A\u5230\u5176\u4ED6\u5546\u5BB6\u300D\u3002\n // \u62C9\u53D6\u5931\u8D25/\u56FA\u5B9A\u5C5E\u4E8E\u5176\u4ED6\u4EE4\u724C\u65F6\u4FDD\u6301\u539F\u5361\u7247\u5E76\u56DE\u9000\u5230\u63D0\u793A\u5FBD\u6807\u3002\n const rePointTargets = models\n .filter(\n (m) =>\n m.pinStatus === 'pin_elsewhere' &&\n m.pinTokenMatched === true &&\n m.pinnedChannelId &&\n m.pinnedChannelId > 0,\n )\n .map((m) => ({ modelName: m.model_name, channelId: m.pinnedChannelId as number }));\n if (rePointTargets.length > 0 && config.userId && token) {\n try {\n await Promise.race([\n (async () => {\n for (let i = 0; i < rePointTargets.length; i += 4) {\n const batch = rePointTargets.slice(i, i + 4);\n await Promise.all(\n batch.map(async ({ modelName, channelId }) => {\n try {\n const pinnedCard = await fetchChannelDetails(\n channelId,\n config.userId,\n token,\n modelName,\n );\n // \u6821\u9A8C\u8FD4\u56DE\u5361\u7247\u786E\u5B9E\u5C5E\u4E8E\u76EE\u6807\u56FA\u5B9A\u6E20\u9053\uFF0C\u907F\u514D\u5B98\u65B9\u641C\u7D22\u8FD4\u56DE\u5176\u4ED6\u6761\u76EE\u6C61\u67D3\u7F13\u5B58\n if (pinnedCard && Number(pinnedCard.channel_id) === Number(channelId)) {\n merchantCardCache.set(modelName.toLowerCase(), { card: pinnedCard, at: Date.now() });\n }\n } catch {}\n }),\n );\n }\n })(),\n new Promise<void>((resolve) => setTimeout(() => resolve(), 10000)),\n ]);\n } catch {}\n // \u7528\u56DE\u586B\u540E\u7684\u7F13\u5B58\u91CD\u5EFA\u5361\u7247\uFF08\u56FA\u5B9A\u5546\u5BB6\u5373\u5361\u7247\u5546\u5BB6 \u2192 \u72B6\u6001\u5347\u7EA7\u4E3A pin_here\uFF09\n models = models.map((m) => {\n if (m.pinStatus !== 'pin_elsewhere' || m.pinTokenMatched !== true) return m;\n const entry = merchantCardCache.get(m.model_name.toLowerCase());\n const card = entry && Date.now() - entry.at < MERCHANT_CARD_TTL_MS ? entry.card : undefined;\n if (card && Number(card.channel_id) === Number(m.pinnedChannelId)) {\n // \u8DEF\u7531\u5FEB\u7167\u53E3\u5F84\u5BF9\u9F50\uFF1A\u53D6\u300C\u8BE5\u5546\u5BB6\u7684\u8BE5\u6A21\u578B\u300D\u6700\u8FD1\u4E00\u6B21\u8BF7\u6C42\uFF08\u5361\u7247\u5DF2\u5207\u6362\u5230\u56FA\u5B9A\u5546\u5BB6\uFF0C\u65F6\u95F4\u4E0D\u80FD\u518D\u6309\u4EFB\u610F\u5546\u5BB6\u53D6\uFF09\n const pinnedLog = allLogs.find(\n (l) =>\n l.model_name?.toLowerCase() === m.model_name.toLowerCase() &&\n Number(l.channel) === m.pinnedChannelId,\n );\n const pinnedAt = pinnedLog ? Number(pinnedLog.created_at) || 0 : undefined;\n return {\n ...m,\n merchant: card,\n pinStatus: 'pin_here' as const,\n probeStatus: 'success' as const,\n lastRoutedAt: pinnedAt,\n lastRoutedText: pinnedAt ? formatRelativeTime(pinnedAt) : undefined,\n };\n }\n return m;\n });\n }\n\n // Account \u9875\u660E\u7EC6\u4FDD\u6301\u539F\u6709\u7A97\u53E3 (20 \u6761)\n const recentLogs = allLogs.slice(0, 20);\n\n const response: A6ApiStateResponse = {\n config: maskConfig(config),\n balance,\n models,\n dshConfiguredModels,\n recentLogs,\n pins,\n };\n return sendJson(res, 200, { ok: true, data: response });\n }\n\n // POST /config\n if (pathname === '/config' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const current = await configAccess.readConfig();\n // \u517C\u5BB9\u65E7\u5BA2\u6237\u7AEF bundle \u4ECD\u4F1A\u53D1\u9001 sessionCookie\uFF1A\u540C\u4E00\u51ED\u636E\uFF0C\u53D6\u4EFB\u4E00\u975E\u5360\u4F4D\u503C\n const rawToken =\n body.accessToken !== undefined && body.accessToken !== MASK\n ? body.accessToken\n : body.sessionCookie !== undefined && body.sessionCookie !== MASK\n ? body.sessionCookie\n : current.accessToken;\n const newApiKey =\n body.apiKey !== undefined && body.apiKey !== MASK ? body.apiKey : current.apiKey;\n // API Key / \u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\uFF08\u8D26\u53F7\uFF09/ userId \u4EFB\u4E00\u53D8\u66F4\u540E\uFF0C\u65E7 tokenId \u4E0D\u518D\u5BF9\u5E94\u5F53\u524D\u8D26\u53F7\u7684\u4EE4\u724C\uFF0C\n // \u6E05\u9664\u5E76\u91CD\u7F6E\u89E3\u6790\u7F13\u5B58\uFF0C\u4E0B\u6B21\u56FA\u5B9A/\u53D6\u6D88\u56FA\u5B9A\u65F6\u91CD\u65B0\u89E3\u6790\n const credChanged =\n newApiKey !== current.apiKey ||\n rawToken !== (current.accessToken || '') ||\n (body.userId !== undefined && body.userId !== MASK && body.userId !== current.userId);\n if (credChanged) {\n tokenResolveCache = null;\n }\n\n const updated: A6ApiConfig = {\n baseURL: body.baseURL !== undefined ? body.baseURL : current.baseURL,\n apiKey: newApiKey,\n accessToken: rawToken,\n userId: body.userId !== undefined && body.userId !== MASK ? body.userId : current.userId,\n activeModels: Array.isArray(body.activeModels) ? body.activeModels : current.activeModels,\n };\n\n // Validate access token and auto-fetch balance & userId\n const balance = await fetchBalance(updated.baseURL, updated.apiKey, updated.userId, updated.accessToken);\n if (balance?.userId) {\n updated.userId = String(balance.userId);\n }\n\n // \u51ED\u636E\u5199\u5165\u539F\u751F\u5B58\u50A8\uFF08credentials refs\uFF1B\u7A7A\u4E32 = \u6E05\u9664\uFF09\uFF1B\u4EC5\u5199\u6709\u53D8\u5316\u7684\u5B57\u6BB5\n const credWrites: Partial<Pick<A6ApiConfig, 'apiKey' | 'accessToken' | 'userId'>> = {};\n if (updated.apiKey !== current.apiKey) credWrites.apiKey = updated.apiKey;\n if ((updated.accessToken || '') !== (current.accessToken || '')) credWrites.accessToken = updated.accessToken;\n if ((updated.userId || '') !== (current.userId || '')) credWrites.userId = updated.userId;\n if (Object.keys(credWrites).length > 0) {\n await configAccess.writeConfig(credWrites);\n }\n\n // \u540C\u6B65 DSH settings\uFF08\u4E0E\u65E7\u884C\u4E3A\u4E00\u81F4\uFF1A\u4EC5\u5F53\u6709\u6D3B\u52A8\u6A21\u578B\u65F6\uFF09\u3002\n // \u6CE8\uFF1A\u96F6\u6A21\u578B\u65F6\u65E0\u6CD5\u6301\u4E45\u5316 baseURL\u2014\u2014llm-pi-ai \u5BF9\u624B\u5199\u8DEF\u7531\u65E0\u5408\u6CD5\u7684\u96F6\u6A21\u578B\u8868\u793A\n // \uFF08models: [] \u4F1A\u88AB assertServiceable \u62D2\u7EDD\u5E76\u6BD2\u5316\u4E0B\u6B21\u542F\u52A8\uFF09\uFF0Ca6api \u5757\u6B64\u65F6\u4E0D\u5B58\u5728\uFF0C\n // \u8282\u70B9\u8BBE\u7F6E\u5C5E\u60F0\u6027\u72B6\u6001\uFF0C\u5F85\u7528\u6237\u542F\u7528\u6A21\u578B\u65F6\u968F\u5757\u4E00\u5E76\u843D\u76D8\u3002\n if (updated.activeModels.length > 0) {\n await configAccess.syncModels(updated.baseURL, updated.activeModels);\n }\n return sendJson(res, 200, { ok: true, config: maskConfig(updated), balance });\n }\n\n // GET /balance\n if (pathname === '/balance' && (req.method === 'GET' || req.method === 'HEAD')) {\n const config = await configAccess.readConfig();\n const token = config.accessToken || '';\n const balance = await fetchBalance(config.baseURL, config.apiKey, config.userId, token);\n const recentLogs = await fetchRecentLogs(config.userId, token, 20);\n return sendJson(res, 200, { ok: true, balance, recentLogs });\n }\n\n // GET /logs\n if (pathname === '/logs' && (req.method === 'GET' || req.method === 'HEAD')) {\n const config = await configAccess.readConfig();\n const token = config.accessToken || '';\n const recentLogs = await fetchRecentLogs(config.userId, token, 30);\n return sendJson(res, 200, { ok: true, logs: recentLogs });\n }\n\n // POST /probe\n if (pathname === '/probe' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const config = await configAccess.readConfig();\n const token = config.accessToken || '';\n const modelName = body.modelName;\n\n if (modelName && modelName !== 'all') {\n const result = await probeSingleModel(config.baseURL, config.apiKey, config.userId, token, modelName);\n if (result.merchant) {\n merchantCardCache.set(modelName.toLowerCase(), { card: result.merchant, at: Date.now() });\n }\n return sendJson(res, 200, { ok: true, result });\n }\n\n // Probe all models in token\n let modelIds: string[] = body.modelNames;\n if (!Array.isArray(modelIds) || modelIds.length === 0) {\n modelIds = await fetchTokenModels(config.baseURL, config.apiKey);\n }\n if (modelIds.length === 0) {\n modelIds = await configAccess.getDshConfiguredModels();\n }\n\n const results = [];\n for (const m of modelIds) {\n const r = await probeSingleModel(config.baseURL, config.apiKey, config.userId, token, m);\n if (r.merchant) {\n merchantCardCache.set(m.toLowerCase(), { card: r.merchant, at: Date.now() });\n }\n results.push(r);\n }\n\n return sendJson(res, 200, { ok: true, results });\n }\n\n // POST /sync-models\n if (pathname === '/sync-models' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n await configAccess.ensureMigrated();\n const config = await configAccess.readConfig();\n const modelIds = Array.isArray(body.modelIds) ? body.modelIds : [];\n const baseURL = body.baseURL || config.baseURL;\n\n // \u6A21\u578B\u5217\u8868\u552F\u4E00\u771F\u76F8\u6E90 = DSH settings.yaml \u7684 llm-pi-ai.providers.a6api.models\n await configAccess.syncModels(baseURL, modelIds);\n\n const dshConfiguredModels = await configAccess.getDshConfiguredModels();\n return sendJson(res, 200, { ok: true, dshConfiguredModels });\n }\n\n // POST /pin \u2014 \u628A\u5361\u7247\u5F53\u524D\u5546\u5BB6\u56FA\u5B9A\u4E3A\u8BE5\u6A21\u578B\u7684\u670D\u52A1\u6E20\u9053\uFF08\u5E73\u53F0\u4FA7\uFF0C\u6309 API Key \u4EE4\u724C\u7ED1\u5B9A\uFF09\n if (pathname === '/pin' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const config = await configAccess.readConfig();\n const modelName = String(body.modelName || '').trim();\n if (!modelName) return sendJson(res, 400, { ok: false, error: '\u7F3A\u5C11\u6A21\u578B\u540D\u79F0' });\n const { userId, token } = webAuthOf(config);\n if (!userId || !token) {\n return sendJson(res, 400, { ok: false, error: '\u9700\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u586B\u5199\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD\u540E\u624D\u80FD\u56FA\u5B9A\u5546\u5BB6' });\n }\n // \u56FA\u5B9A\u7684\u662F\u5361\u7247\u5F53\u524D\u5C55\u793A\u7684\u5546\u5BB6\uFF08\u65E0\u5546\u5BB6\u9009\u62E9\u5668\uFF09\n let card = cachedMerchantOf(modelName);\n // token_id \u89E3\u6790\u94FE\uFF1A\u914D\u7F6E\u7F13\u5B58 \u2192 \u4EE4\u724C\u5217\u8868 \u2192 \u63A2\u6D4B\u65E5\u5FD7\uFF081-token\uFF09\n let tokenId = await resolveTokenId(config);\n // \u5361\u7247\u7F3A\u5931\u6216\u4EE4\u724C\u672A\u89E3\u6790\u65F6\uFF0C\u7528\u4E00\u6B21\u63A2\u6D4B\u540C\u65F6\u56DE\u586B\u4E24\u8005\uFF08\u63A2\u6D4B\u8BF7\u6C42\u672C\u8EAB\u4F1A\u5199\u8DEF\u7531\u65E5\u5FD7\uFF09\n if ((!card || !tokenId) && config.apiKey) {\n try {\n const probe = await probeSingleModel(config.baseURL, config.apiKey, userId, token, modelName);\n if (!tokenId && probe.tokenId && Number(probe.tokenId) > 0) tokenId = Number(probe.tokenId);\n if (!card && probe.merchant) {\n card = probe.merchant;\n merchantCardCache.set(modelName.toLowerCase(), { card, at: Date.now() });\n }\n } catch {}\n }\n if (!card) {\n return sendJson(res, 400, { ok: false, error: '\u8BE5\u6A21\u578B\u6682\u65E0\u5546\u5BB6\u6570\u636E\uFF0C\u8BF7\u5148\u300C\u63A2\u6D4B\u5546\u5BB6\u300D' });\n }\n if (!tokenId) {\n return sendJson(res, 400, { ok: false, error: '\u65E0\u6CD5\u81EA\u52A8\u89E3\u6790 API Key \u5BF9\u5E94\u7684\u4EE4\u724C ID\uFF0C\u8BF7\u68C0\u67E5\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\u662F\u5426\u6709\u6548\uFF0C\u6216\u5230\u5B98\u7F51\u300C\u4EE4\u724C\u300D\u9875\u624B\u52A8\u56FA\u5B9A' });\n }\n if (!card.channel_id) {\n return sendJson(res, 400, { ok: false, error: '\u5546\u5BB6\u5361\u7247\u7F3A\u5C11\u6E20\u9053 ID\uFF0C\u8BF7\u91CD\u65B0\u63A2\u6D4B' });\n }\n const pinResult = await marketplacePin(userId, token, {\n token_id: tokenId,\n channel_id: card.channel_id,\n model_name: modelName,\n // \u5E73\u53F0\u9ED8\u8BA4\u515C\u5E95\uFF1A\u6E20\u9053\u5F02\u5E38\u65F6\u81EA\u52A8\u5207\u6362\u667A\u80FD\u4F18\u9009\uFF08\u4E0D\u66B4\u9732 UI \u5F00\u5173\uFF09\n fallback_to_smart_routing: true,\n });\n if (!pinResult.ok) {\n return sendJson(res, 400, { ok: false, error: pinResult.message || '\u56FA\u5B9A\u5931\u8D25' });\n }\n // \u66F4\u65B0\u5185\u5B58\u4EE4\u724C\u89E3\u6790\u7F13\u5B58\uFF08tokenId \u4E3A\u6D3E\u751F\u6570\u636E\uFF0C\u4E0D\u6301\u4E45\u5316\uFF09\n tokenResolveCache = { tokenId, at: Date.now() };\n merchantCardCache.set(modelName.toLowerCase(), {\n card: { ...card, is_pinned: true, pin_status: 'pin_here' },\n at: Date.now(),\n });\n const pinList = await fetchMarketplacePins(userId, token);\n return sendJson(res, 200, { ok: true, message: `\u5DF2\u56FA\u5B9A ${modelName} \u81F3\u5546\u6237 #${card.channel_id}`, pins: pinList, tokenId });\n }\n\n // POST /unpin \u2014 \u53D6\u6D88\u8BE5\u6A21\u578B\u7684\u56FA\u5B9A\uFF08\u53D6\u6D88\u540E\u91CD\u65B0\u63A2\u6D4B\u5373\u53EF\u8DEF\u7531\u5230\u65B0\u5546\u5BB6\uFF09\n if (pathname === '/unpin' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const config = await configAccess.readConfig();\n const modelName = String(body.modelName || '').trim();\n if (!modelName) return sendJson(res, 400, { ok: false, error: '\u7F3A\u5C11\u6A21\u578B\u540D\u79F0' });\n const { userId, token } = webAuthOf(config);\n if (!userId || !token) {\n return sendJson(res, 400, { ok: false, error: '\u9700\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u586B\u5199\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD\u540E\u624D\u80FD\u53D6\u6D88\u56FA\u5B9A' });\n }\n const tokenId = await resolveTokenId(config);\n if (!tokenId) {\n return sendJson(res, 400, { ok: false, error: '\u65E0\u6CD5\u89E3\u6790 API Key \u5BF9\u5E94\u7684\u4EE4\u724C ID\uFF0C\u8BF7\u68C0\u67E5\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\u662F\u5426\u6709\u6548' });\n }\n const unpinResult = await marketplaceUnpin(userId, token, { token_id: tokenId, model_name: modelName });\n if (!unpinResult.ok) {\n return sendJson(res, 400, { ok: false, error: unpinResult.message || '\u53D6\u6D88\u56FA\u5B9A\u5931\u8D25' });\n }\n const card = cachedMerchantOf(modelName);\n if (card) {\n merchantCardCache.set(modelName.toLowerCase(), {\n card: { ...card, is_pinned: false, pin_status: undefined },\n at: Date.now(),\n });\n }\n const pinList = await fetchMarketplacePins(userId, token);\n return sendJson(res, 200, { ok: true, message: `\u5DF2\u53D6\u6D88\u56FA\u5B9A ${modelName}`, pins: pinList, tokenId });\n }\n\n // POST /disable \u2014 \u7981\u7528\u5361\u7247\u5F53\u524D\u5546\u5BB6\u5BF9\u8BE5\u6A21\u578B\u7684\u670D\u52A1\uFF08\u5E73\u53F0\u4FA7\uFF0C\u6309 \u6E20\u9053\u00D7\u6A21\u578B\uFF09\n if (pathname === '/disable' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const config = await configAccess.readConfig();\n const modelName = String(body.modelName || '').trim();\n if (!modelName) return sendJson(res, 400, { ok: false, error: '\u7F3A\u5C11\u6A21\u578B\u540D\u79F0' });\n let card = cachedMerchantOf(modelName);\n // \u5361\u7247\u7F13\u5B58\u8FC7\u671F\u65F6\u7528\u4E00\u6B21\u63A2\u6D4B\u56DE\u586B\uFF08\u4E0E /pin \u4E00\u81F4\uFF0C\u907F\u514D\u300C\u6309\u94AE\u53EF\u7528\u4F46\u63A5\u53E3 400\u300D\uFF09\n if (!card && config.apiKey) {\n try {\n const probe = await probeSingleModel(config.baseURL, config.apiKey, config.userId, config.accessToken || '', modelName);\n if (probe.merchant) {\n card = probe.merchant;\n merchantCardCache.set(modelName.toLowerCase(), { card, at: Date.now() });\n }\n } catch {}\n }\n if (!card || !card.channel_id) {\n return sendJson(res, 400, { ok: false, error: '\u8BE5\u6A21\u578B\u6682\u65E0\u5546\u5BB6\u6570\u636E\uFF0C\u8BF7\u5148\u300C\u63A2\u6D4B\u5546\u5BB6\u300D' });\n }\n const { userId, token } = webAuthOf(config);\n if (!userId || !token) {\n return sendJson(res, 400, { ok: false, error: '\u9700\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u586B\u5199\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD\u540E\u624D\u80FD\u7981\u7528\u5546\u5BB6' });\n }\n const disableResult = await marketplaceDisableChannel(userId, token, card.channel_id, modelName);\n if (!disableResult.ok) {\n return sendJson(res, 400, { ok: false, error: disableResult.message || '\u7981\u7528\u5931\u8D25' });\n }\n merchantCardCache.set(modelName.toLowerCase(), {\n card: { ...card, user_channel_disabled: true },\n at: Date.now(),\n });\n return sendJson(res, 200, { ok: true, message: `\u5DF2\u7981\u7528\u5546\u6237 #${card.channel_id} \u5BF9\u8BE5\u6A21\u578B\u7684\u670D\u52A1` });\n }\n\n // POST /restore \u2014 \u6062\u590D\u88AB\u7981\u7528\u7684\u5546\u5BB6\n if (pathname === '/restore' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const config = await configAccess.readConfig();\n const modelName = String(body.modelName || '').trim();\n if (!modelName) return sendJson(res, 400, { ok: false, error: '\u7F3A\u5C11\u6A21\u578B\u540D\u79F0' });\n let card = cachedMerchantOf(modelName);\n if (!card && config.apiKey) {\n try {\n const probe = await probeSingleModel(config.baseURL, config.apiKey, config.userId, config.accessToken || '', modelName);\n if (probe.merchant) {\n card = probe.merchant;\n merchantCardCache.set(modelName.toLowerCase(), { card, at: Date.now() });\n }\n } catch {}\n }\n if (!card || !card.channel_id) {\n return sendJson(res, 400, { ok: false, error: '\u8BE5\u6A21\u578B\u6682\u65E0\u5546\u5BB6\u6570\u636E\uFF0C\u8BF7\u5148\u300C\u63A2\u6D4B\u5546\u5BB6\u300D' });\n }\n const { userId, token } = webAuthOf(config);\n if (!userId || !token) {\n return sendJson(res, 400, { ok: false, error: '\u9700\u5728\u300C\u57FA\u7840\u914D\u7F6E\u300D\u586B\u5199\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C/\u4F1A\u8BDD\u540E\u624D\u80FD\u6062\u590D\u5546\u5BB6' });\n }\n const restoreResult = await marketplaceRestoreChannel(userId, token, card.channel_id, modelName);\n if (!restoreResult.ok) {\n return sendJson(res, 400, { ok: false, error: restoreResult.message || '\u6062\u590D\u5931\u8D25' });\n }\n merchantCardCache.set(modelName.toLowerCase(), {\n card: { ...card, user_channel_disabled: false },\n at: Date.now(),\n });\n return sendJson(res, 200, { ok: true, message: `\u5DF2\u6062\u590D\u5546\u6237 #${card.channel_id} \u5BF9\u8BE5\u6A21\u578B\u7684\u670D\u52A1` });\n }\n\n // GET /price-fluctuation \u2014 \u8F7B\u91CF\u4EF7\u683C\u6CE2\u52A8\u6761\u6570\uFF08\u5F85\u5904\u7406 n\uFF09\uFF0C\u4EC5\u56DE\u4F20\u8BA1\u6570\n if (pathname === '/price-fluctuation' && (req.method === 'GET' || req.method === 'HEAD')) {\n const config = await configAccess.readConfig();\n const token = config.accessToken || '';\n if (!token || !config.userId) {\n return sendJson(res, 200, { ok: true, data: { pendingCount: 0, unseenCount: 0, totalCount: 0, hasAuth: false, authError: false, updatedAt: Date.now() } });\n }\n const result = await fetchPriceFluctuation(config.userId, token);\n const { notices, ...counts } = result as any;\n // 401/403 \u65F6 authError=true\uFF0C\u5BA2\u6237\u7AEF\u53EF\u533A\u5206\u201C\u672A\u914D\u7F6E\u201D\u4E0E\u201C\u5931\u6548\u201D\n const hasAuth = !counts.authError;\n return sendJson(res, 200, { ok: true, data: { pendingCount: counts.pendingCount, unseenCount: counts.unseenCount, totalCount: counts.totalCount, hasAuth, authError: Boolean(counts.authError), updatedAt: Date.now() } });\n }\n\n // GET /pins \u2014 \u8F7B\u91CF\u56FA\u5B9A\u8BB0\u5F55\uFF08\u5BA2\u6237\u7AEF 60s \u8F6E\u8BE2\uFF0C\u8BA9\u5361\u7247\u72B6\u6001\u8DDF\u968F\u5B98\u7F51\u4FA7\u89E3\u9664/\u65B0\u589E\u56FA\u5B9A\uFF09\n if (pathname === '/pins' && (req.method === 'GET' || req.method === 'HEAD')) {\n const config = await configAccess.readConfig();\n const { userId, token } = webAuthOf(config);\n if (!userId || !token) {\n return sendJson(res, 200, { ok: true, pins: [] });\n }\n try {\n const pins = await fetchMarketplacePins(userId, token);\n return sendJson(res, 200, { ok: true, pins });\n } catch (err: any) {\n console.warn('[dsh-a6api] GET /pins error:', err);\n return sendJson(res, 200, { ok: true, pins: [] });\n }\n }\n\n // GET /catalog \u2014 \u6A21\u578B\u76EE\u5F55\u5168\u91CF\uFF08\u8FD0\u884C\u65F6 JSON\uFF0C\u5B57\u6BB5 = settings.yaml \u539F\u751F\u6A21\u578B\u5B57\u6BB5 + brand\uFF09\n if (pathname === '/catalog' && (req.method === 'GET' || req.method === 'HEAD')) {\n return sendJson(res, 200, { ok: true, catalog: getCatalog() });\n }\n\n // POST /catalog/clear \u2014 \u6E05\u7A7A\u6A21\u578B\u76EE\u5F55\uFF08\u91CD\u65B0\u62C9\u53D6/\u586B\u5145\u524D\u4F7F\u7528\uFF1Bsettings.yaml \u5DF2\u542F\u7528\u6761\u76EE\u4E0D\u53D7\u5F71\u54CD\uFF09\n if (pathname === '/catalog/clear' && req.method === 'POST') {\n await clearCatalog();\n return sendJson(res, 200, { ok: true });\n }\n\n // POST /catalog/fetch-models \u2014 \u4ECE A6API \u5E02\u573A\u7FFB\u9875\u62C9\u53D6\u5168\u90E8\u6A21\u578B ID\uFF08\u542B\u54C1\u724C\uFF09\uFF0C\u5408\u5E76\u5165\u76EE\u5F55\u3002\n // \u4EC5\u65B0\u589E\u7F3A\u5931\u6761\u76EE/\u8865\u54C1\u724C/\u8865\u9ED8\u8BA4\u63A8\u7406\u6863\u4F4D\uFF0C\u4E0D\u8986\u76D6\u4EFB\u4F55\u5DF2\u5B58\u5728\u6761\u76EE\u7684\u53C2\u6570\u3002\n if (pathname === '/catalog/fetch-models' && req.method === 'POST') {\n const config = await configAccess.readConfig();\n const { userId, token } = webAuthOf(config);\n let result;\n try {\n result = await fetchMarketplaceModels(userId, token);\n } catch (err: any) {\n // \u672A\u914D\u7F6E\u7CFB\u7EDF\u8BBF\u95EE\u4EE4\u724C\u7B49\u9274\u6743\u7C7B\u9519\u8BEF \u2192 400 + \u5F15\u5BFC\u6587\u6848\uFF08\u4E0E /pin \u98CE\u683C\u4E00\u81F4\uFF09\n return sendJson(res, 400, { ok: false, error: err?.message || '\u83B7\u53D6\u5E02\u573A\u6A21\u578B\u5931\u8D25' });\n }\n const models = result.models;\n const before = new Set(getCatalog().map((e) => e.id.toLowerCase()));\n let added = 0;\n for (const m of models) {\n if (!before.has(m.id.toLowerCase())) added++;\n }\n // reasoningEfforts \u9ED8\u8BA4 = DSH \u5168\u90E8\u601D\u8003\u6863\u4F4D\uFF08upsert \u53EA\u8865\u7F3A\u5931\u5B57\u6BB5\uFF0C\u5DF2\u6709\u81EA\u5B9A\u4E49\u4E0D\u53D7\u5F71\u54CD\uFF09\n await upsertCatalogEntries(\n models.map((m) => ({ id: m.id, brand: m.brand, reasoningEfforts: m.reasoningEfforts })),\n );\n return sendJson(res, 200, {\n ok: true,\n total: models.length,\n added,\n failedPages: result.failedPages,\n });\n }\n\n // POST /catalog/query-openrouter \u2014 \u5BF9\u5168\u90E8\uFF08\u6216\u6307\u5B9A\uFF09\u76EE\u5F55\u6A21\u578B\u67E5 OpenRouter \u5E76\u586B\u5145\u53C2\u6570\u3002\n // \u80FD\u67E5\u5230\u7684\u586B\u5145 contextWindow/maxTokens/input/name\uFF1B\u67E5\u4E0D\u5230\u7684\u4FDD\u6301\u539F\u5B57\u6BB5\u4E0D\u53D8\u3002\n if (pathname === '/catalog/query-openrouter' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const catalog = getCatalog();\n const modelIds =\n Array.isArray(body.modelIds) && body.modelIds.length > 0\n ? body.modelIds.map((s: any) => String(s))\n : catalog.map((e) => e.id);\n if (modelIds.length === 0) {\n return sendJson(res, 400, { ok: false, error: '\u76EE\u5F55\u4E3A\u7A7A\uFF0C\u8BF7\u5148\u300C\u4ECE A6API \u83B7\u53D6\u5E02\u573A\u6A21\u578B\u300D' });\n }\n const result = await queryOpenRouter(modelIds);\n return sendJson(res, 200, {\n ok: true,\n updated: result.updated.length,\n notFound: result.notFound,\n });\n }\n\n // POST /catalog/update \u2014 \u4FEE\u6539\u5355\u4E2A\u76EE\u5F55\u6761\u76EE\u53C2\u6570\uFF08name/contextWindow/maxTokens/input/reasoningEfforts\uFF09\u3002\n // \u82E5\u8BE5\u6A21\u578B\u5DF2\u5728 DSH \u542F\u7528\uFF0C\u7ACB\u5373\u91CD\u5199 settings.yaml \u5BF9\u5E94\u6761\u76EE\u4F7F\u53C2\u6570\u5373\u65F6\u751F\u6548\u3002\n if (pathname === '/catalog/update' && req.method === 'POST') {\n const body = await parseJsonBody(req);\n const id = String(body.id || '').trim();\n if (!id) return sendJson(res, 400, { ok: false, error: '\u7F3A\u5C11\u6A21\u578B ID' });\n const patch: Record<string, any> = {};\n // null = \u5220\u9664\u8BE5\u5B57\u6BB5\uFF08\u6E05\u7A7A\u8BED\u4E49\uFF09\uFF1Bundefined = \u4E0D\u4FEE\u6539\n if (body.name !== undefined) {\n if (body.name === null) {\n patch.name = null;\n } else if (typeof body.name !== 'string') {\n return sendJson(res, 400, { ok: false, error: 'name \u5FC5\u987B\u662F\u5B57\u7B26\u4E32' });\n } else {\n const name = body.name.trim();\n patch.name = name || null;\n }\n }\n for (const key of ['contextWindow', 'maxTokens'] as const) {\n if (body[key] === null) {\n patch[key] = null;\n } else if (body[key] !== undefined) {\n const n = Number(body[key]);\n if (!Number.isInteger(n) || n < 1) {\n return sendJson(res, 400, { ok: false, error: `${key} \u5FC5\u987B\u662F\u6B63\u6574\u6570` });\n }\n patch[key] = n;\n }\n }\n if (body.input !== undefined) {\n if (body.input === null) {\n patch.input = null;\n } else if (!Array.isArray(body.input)) {\n return sendJson(res, 400, { ok: false, error: 'input \u5FC5\u987B\u662F\u6570\u7EC4' });\n } else {\n const mods = body.input.filter((m: any) => m === 'text' || m === 'image');\n // \u7A7A\u6570\u7EC4 = \u6E05\u7A7A\u8BE5\u5B57\u6BB5\uFF08null \u8BED\u4E49\u5220\u9664\uFF09\n patch.input = mods.length > 0 ? mods : null;\n }\n }\n if (body.reasoningEfforts !== undefined) {\n if (body.reasoningEfforts === null) {\n patch.reasoningEfforts = null; // \u5220\u9664\u8BE5\u5B57\u6BB5\n } else {\n // DSH \u8BED\u4E49\u4E25\u683C\u6821\u9A8C\uFF1A\u952E \u2208 THINKING_LEVELS\u3001\u503C\u975E\u7A7A\uFF08\u4EC5 off \u53EF null\uFF09\u3001\u975E\u7A7A\u5B57\u5178\u3001\u81F3\u5C11\u4E00\u4E2A\u975E off \u6863\u4F4D\n const v = validateReasoningEfforts(body.reasoningEfforts);\n if (!v.ok) return sendJson(res, 400, { ok: false, error: v.error });\n patch.reasoningEfforts = v.value;\n }\n }\n const entry = await updateCatalogEntry(id, patch);\n if (!entry) return sendJson(res, 404, { ok: false, error: '\u76EE\u5F55\u4E2D\u4E0D\u5B58\u5728\u8BE5\u6A21\u578B' });\n\n // \u5DF2\u542F\u7528\u6A21\u578B\uFF1A\u7ACB\u5373\u91CD\u5199 settings.yaml \u5BF9\u5E94\u6761\u76EE\uFF08\u53C2\u6570\u5373\u65F6\u751F\u6548\uFF0C\u5355\u4E00\u6570\u636E\u6D41\uFF1A\u76EE\u5F55 \u2192 settings.yaml\uFF09\n try {\n const config = await configAccess.readConfig();\n const dshModels = await configAccess.getDshConfiguredModels();\n if (dshModels.some((m) => m.toLowerCase() === entry.id.toLowerCase()) && config.activeModels.length > 0) {\n await configAccess.syncModels(config.baseURL, config.activeModels);\n }\n } catch (err: any) {\n console.warn('[dsh-a6api] catalog update: resync settings failed:', err?.message || err);\n }\n return sendJson(res, 200, { ok: true, entry });\n }\n\n return sendJson(res, 404, { ok: false, error: 'Not found' });\n } catch (err: any) {\n console.error('[dsh-a6api] API error:', err);\n return sendJson(res, 500, { ok: false, error: err?.message || String(err) });\n }\n },\n });\n\n return () => {\n if (typeof unregister === 'function') unregister();\n };\n }, 'dsh-a6api: web API router');\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["name", "buildWebHeaders", "name", "fs", "fsp", "path", "os", "dshHome", "lines", "name"]
|
|
7
7
|
}
|