/** * 匹配层 —— 纯函数:把 DSH 的 (provider, model) 映射到数据源里的 profile。 * * 严格规则:provider 与 model 必须同时命中同一 profile 才返回;否则返回 undefined, * UI 侧对未匹配模型**什么都不显示**。 */ /** 数据源 profile 的归一化形态(仅保留匹配与展示所需字段)。 */ export interface RateProfile { id: string; /** 数据源里的 provider 展示名,如 "Ollama"。 */ providerName: string; /** 数据源里的 model 描述,如 "DeepSeek V4.1 Flash / V4 Flash / V4 Pro"。 */ modelLabel: string; schedule: { timeZone: string; peakDays: number[]; peakWindows: { start: string; end: string; }[]; offDayName?: string; /** 法定节假日(`YYYY-MM-DD`,本 schedule 时区);当天全天谷价。见 `schedule.ts`。 */ publicHolidayDates?: string[]; /** 节假日的展示名;目前仅透传。 */ publicHolidayName?: string; /** 节假日依据的日历时区(峰价时区与节假日日历可能不同);见 `schedule.ts`。 */ publicHolidayTimeZone?: string; /** 带日期区间的覆盖段(活动/促销窗口);优先级高于节假日与常规峰谷。 */ overrides?: { /** 归一化三态;促销类 period 一律落到 `campaign`。 */ period: 'peak' | 'offPeak' | 'campaign'; /** 数据源里的原始 period 名(`promotion` / `campaign10` / …)。 */ periodName?: string; /** 该活动自己的倍率徽章(同一 profile 可有多个促销态,各倍率不同)。 */ badge?: string; name?: string; detail?: string; startDate?: string; endDate?: string; days: number[]; windows: { start: string; end: string; }[]; }[]; }; peakBadge: string; offPeakBadge: string; /** 峰/谷时段名,用于 hover 详情。 */ peakName: string; offPeakName: string; /** 活动态(数据源 `periods.campaign`)——仅部分 profile 有。 */ campaignBadge?: string; campaignName?: string; campaignDetail?: string; source?: string; verifiedAt?: string; } /** 用户配置的模型归属覆盖项。 */ export interface ModelMapping { provider: string; /** 前缀(默认)或正则(matchIsRegex: true)。 */ match: string; profile: string; matchIsRegex?: boolean; } export interface MatchConfig { /** provider id → 数据源 provider 展示名。覆盖内置默认。 */ providerAliases?: Record; /** 补充/覆盖的模型归属规则,优先于内置规则。 */ modelMappings?: ModelMapping[]; } /** * 内置 provider 别名:DSH 的 provider id → 数据源里的 provider 展示名。 * * 数据源覆盖的 provider 家数**随其收录范围变化**(2026-09-11 版 8 家 → 2026-09-28 版 13 家: * 新增 AIHubMix、Baidu Qianfan、above.dev 等)——**数量不是契约**,本表按需增补。 * 本机配置中的 openrouter / ocg / opencode-go / 转售/网关类 provider(如 OpenCode Go) * **继承上游时段**,故显式映射到上游 profile; * 仅当某 provider 确实没有时段计价时才不映射,且必须写明理由(见 UNMATCHED_BY_DESIGN)。 * * 注意:数据源新收录的 provider 若既无别名也未进 `UNMATCHED_BY_DESIGN`,属"未登记", * 由 `scripts/audit-coverage.mjs`(运行时穷举)在覆盖面板里以告警暴露。 */ export declare const DEFAULT_PROVIDER_ALIASES: Record; /** * 内置模型归属规则:按 (provider, 模型前缀) 指向 profile id。 * * V4 系为**宽松归属**(spec §4.2 已确认):`deepseek-v4*` 前缀涵盖 * `deepseek-v4-flash:0731`、`deepseek-v4-pro:0813`、`deepseek-v4.1-flash`; * 另含历史别名 `deepseek-flash`(其实现为 DeepSeek-V41-Flash)与 * `deepseek-v4-flash-vision-exp`。 */ export declare const DEFAULT_MODEL_MAPPINGS: ModelMapping[]; /** * **已知但有意不映射**的 provider —— 每一项都必须写明理由与依据。 * * 这份清单的作用是**防静默遗漏**(2026-09-12 教训): * 本插件曾把 `ocg` / `opencode-go` 归入「数据源没有 → 不显示」, * 但真实原因是「**我没查这个 endpoint 有没有峰谷定价**」—— * 把「数据源覆盖率」误当成「上游是否有峰谷定价」。而 OpenCode Go 是 * DeepSeek 的**转售方**,其文档载明峰值窗口与官方完全一致。 * * 因此现在的纪律是:**每个已知 provider 要么有映射,要么在这里留一条理由**。 * 守卫测试 `test/matching.test.ts` 会断言此清单的条目齐备且理由非空, * 新增映射时忘了同步就会失败。 */ export declare const UNMATCHED_BY_DESIGN: Record; /** * 归一化模型 id:去掉 provider 侧 tag 后缀、小写化、统一分隔符。 * * @param modelId - provider 原始模型 id,如 "deepseek-v4-flash:0731"。 * @returns 归一化后的 id,如 "deepseek-v4-flash"。 */ export declare function normalizeModelId(modelId: string): string; /** * 把 (provider, model) 匹配到唯一 profile。 * * @param providerId - DSH 的 provider id。 * @param modelId - provider 原始模型 id。 * @param profiles - 可用 profile 列表。 * @param config - 可选的别名与归属覆盖。 * @returns 命中的 profile;未命中返回 undefined(UI 不显示任何内容)。 */ export declare function matchProfile(providerId: string, modelId: string, profiles: RateProfile[], config?: MatchConfig): RateProfile | undefined;