pi-cache-optimizer 2.4.5 → 2.4.7

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 CHANGED
@@ -46,6 +46,46 @@ This release keeps the original DeepSeek behavior and adds read-only stats adapt
46
46
  | NVIDIA Nemotron | Model id/name contains `nemotron` | `Nemotron cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
47
47
  | Cohere / Command | Model id/name contains `cohere` or `command-r` | `Cohere cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
48
48
  | Yi / 零一万物 | Model id/name contains `yi-`, `01-ai`, `zero-one`, or pattern `yi` with safe boundaries | `Yi cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
49
+ | Doubao / ByteDance / Seed | Model id/name contains `doubao`, `豆包`, `volcengine`, `bytedance`, `byte-dance`, or pattern `seed` with safe boundaries | `Doubao cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
50
+ | Baidu ERNIE / Wenxin | Model id/name contains `ernie`, `wenxin`, `文心`, `yiyan`, `一言`, or `baidu` | `ERNIE cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
51
+ | Baichuan / 百川 | Model id/name contains `baichuan` or `百川` | `Baichuan cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
52
+ | StepFun / 阶跃星辰 | Model id/name contains `stepfun` or `step-` prefix | `StepFun cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
53
+ | iFlytek Spark / 讯飞星火 | Model id/name contains `spark`, `xinghuo`, `星火`, `iflytek`, or `讯飞` | `Spark cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
54
+ | InternLM / 书生 | Model id/name contains `internlm`, `intern-lm`, or `书生` | `InternLM cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
55
+ | Google Gemma | Model id/name contains `gemma` | `Gemma cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
56
+ | Microsoft Phi | Model id/name contains `phi-` prefix, or pattern `phi` with safe boundaries | `Phi cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
57
+ | AI21 Jamba | Model id/name contains `jamba` or `ai21` | `Jamba cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
58
+ | Upstage Solar | Model id/name contains `solar` or `upstage` | `Solar cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
59
+ | Perplexity / Sonar | Model id/name contains `sonar`, `perplexity`, or pattern `pplx` with safe boundaries | `Sonar cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
60
+ | Amazon Nova | Model id/name contains `amazon-nova`, or pattern `nova` with safe boundaries | `Nova cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
61
+ | Reka | Model id/name contains `reka` | `Reka cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
62
+ | Falcon / TII | Model id/name contains `falcon` or `tiiuae` (not bare `tii`) | `Falcon cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
63
+ | Databricks DBRX | Model id/name contains `dbrx` or `databricks` | `DBRX cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
64
+ | MosaicML MPT | Model id/name contains `mosaicml`, `mpt-` prefix, or pattern `mpt` with safe boundaries | `MPT cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
65
+ | StableLM / Stability AI | Model id/name contains `stablelm`, `stable-lm`, or `stability-ai` | `StableLM cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
66
+ | BAAI / Aquila | Model id/name contains `aquila` or `baai` | `Aquila cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
67
+ | LG EXAONE | Model id/name contains `exaone` | `EXAONE cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
68
+ | Naver HyperCLOVA X | Model id/name contains `hyperclova` or `clova-x` (conservative, not bare `clova`/`naver`) | `HyperCLOVA cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
69
+ | Aleph Alpha Luminous | Model id/name contains `luminous`, `aleph-alpha`, or pattern `aleph` with safe boundaries | `Luminous cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
70
+ | Nous / Hermes / OpenHermes | Model id/name contains `nous`, `hermes`, or `openhermes` | `Hermes cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
71
+ | IBM Granite | Model id/name contains `granite` or `ibm-granite` | `Granite cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
72
+ | Snowflake Arctic | Model id/name contains `snowflake-arctic`, or safe-boundary pattern `arctic` | `Arctic cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
73
+ | Huawei Pangu / 盘古 | Model id/name contains `pangu`, `pan-gu`, `盘古`, or `huawei-pangu` | `Pangu cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
74
+ | SenseTime SenseNova / 商汤 | Model id/name contains `sensenova`, `sense-nova`, `sensechat`, or `商汤` | `SenseNova cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
75
+ | 360 Zhinao / 智脑 | Model id/name contains `360gpt`, `360-gpt`, `zhinao`, or `智脑` (no bare `360`) | `Zhinao cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
76
+ | OpenBMB MiniCPM | Model id/name contains `minicpm`, `mini-cpm`, or `openbmb` | `MiniCPM cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
77
+ | XVERSE | Model id/name contains `xverse` | `XVERSE cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
78
+ | OrionStar Orion | Model id/name contains `orionstar`, `orion-star`, or safe-boundary pattern `orion` | `Orion cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
79
+ | OpenChat | Model id/name contains `openchat` | `OpenChat cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
80
+ | Vicuna | Model id/name contains `vicuna` | `Vicuna cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
81
+ | WizardLM / WizardCoder | Model id/name contains `wizardlm`, `wizard-lm`, `wizardcoder`, or `wizard-coder` | `Wizard cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
82
+ | Zephyr | Model id/name contains `zephyr` | `Zephyr cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
83
+ | Dolphin | Model id/name contains `dolphin` | `Dolphin cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
84
+ | OpenOrca | Model id/name contains `openorca` or `open-orca` | `OpenOrca cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
85
+ | Starling | Model id/name contains `starling` | `Starling cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
86
+ | BLOOM / BigScience | Model id/name contains `bloom` or `bigscience` | `BLOOM cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
87
+ | RWKV | Model id/name contains `rwkv` | `RWKV cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
88
+ | Cohere Aya | Model id/name contains `aya-expanse`, or safe-boundary pattern `aya` (avoid `maya`/`payara`) | `Aya cache` | Pi-normalized usage, or raw OpenAI-shaped fields when visible |
49
89
  | Anthropic / Claude | Model id/name contains `anthropic` or `claude` | `Claude cache` | Pi-normalized usage, or raw `cache_read_input_tokens`, `cache_creation_input_tokens`, `input_tokens` |
50
90
  | Gemini / Vertex | Model id/name contains `gemini` or `vertex` | `Gemini cache` | Pi-normalized usage, or raw Gemini/Vertex cached-content token metadata when visible |
51
91
 
package/README.zh-CN.md CHANGED
@@ -49,6 +49,46 @@
49
49
  | NVIDIA Nemotron | model id/name 包含 `nemotron` | `Nemotron cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
50
50
  | Cohere / Command | model id/name 包含 `cohere` 或 `command-r` | `Cohere cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
51
51
  | Yi / 零一万物 | model id/name 包含 `yi-`、`01-ai`、`zero-one`,或安全边界内 `yi` 模式 | `Yi cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
52
+ | Doubao / ByteDance / Seed | model id/name 包含 `doubao`、`豆包`、`volcengine`、`bytedance`、`byte-dance`,或安全边界内 `seed` 模式 | `Doubao cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
53
+ | Baidu ERNIE / 文心一言 | model id/name 包含 `ernie`、`wenxin`、`文心`、`yiyan`、`一言` 或 `baidu` | `ERNIE cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
54
+ | Baichuan / 百川 | model id/name 包含 `baichuan` 或 `百川` | `Baichuan cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
55
+ | StepFun / 阶跃星辰 | model id/name 包含 `stepfun` 或 `step-` 前缀 | `StepFun cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
56
+ | iFlytek Spark / 讯飞星火 | model id/name 包含 `spark`、`xinghuo`、`星火`、`iflytek` 或 `讯飞` | `Spark cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
57
+ | InternLM / 书生 | model id/name 包含 `internlm`、`intern-lm` 或 `书生` | `InternLM cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
58
+ | Google Gemma | model id/name 包含 `gemma` | `Gemma cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
59
+ | Microsoft Phi | model id/name 包含 `phi-` 前缀,或安全边界内 `phi` 模式 | `Phi cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
60
+ | AI21 Jamba | model id/name 包含 `jamba` 或 `ai21` | `Jamba cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
61
+ | Upstage Solar | model id/name 包含 `solar` 或 `upstage` | `Solar cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
62
+ | Perplexity / Sonar | model id/name 包含 `sonar`、`perplexity`,或安全边界内 `pplx` 模式 | `Sonar cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
63
+ | Amazon Nova | model id/name 包含 `amazon-nova`,或安全边界内 `nova` 模式 | `Nova cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
64
+ | Reka | model id/name 包含 `reka` | `Reka cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
65
+ | Falcon / TII | model id/name 包含 `falcon` 或 `tiiuae`(不含裸 `tii`) | `Falcon cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
66
+ | Databricks DBRX | model id/name 包含 `dbrx` 或 `databricks` | `DBRX cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
67
+ | MosaicML MPT | model id/name 包含 `mosaicml`、`mpt-` 前缀,或安全边界内 `mpt` 模式 | `MPT cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
68
+ | StableLM / Stability AI | model id/name 包含 `stablelm`、`stable-lm` 或 `stability-ai` | `StableLM cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
69
+ | BAAI / Aquila | model id/name 包含 `aquila` 或 `baai` | `Aquila cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
70
+ | LG EXAONE | model id/name 包含 `exaone` | `EXAONE cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
71
+ | Naver HyperCLOVA X | model id/name 包含 `hyperclova` 或 `clova-x`(保守检测,不含裸 `clova`/`naver`) | `HyperCLOVA cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
72
+ | Aleph Alpha Luminous | model id/name 包含 `luminous`、`aleph-alpha`,或安全边界内 `aleph` 模式 | `Luminous cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
73
+ | Nous / Hermes / OpenHermes | model id/name 包含 `nous`、`hermes` 或 `openhermes` | `Hermes cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
74
+ | IBM Granite | model id/name 包含 `granite` 或 `ibm-granite` | `Granite cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
75
+ | Snowflake Arctic | model id/name 包含 `snowflake-arctic`,或安全边界内 `arctic` 模式 | `Arctic cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
76
+ | Huawei Pangu / 盘古 | model id/name 包含 `pangu`、`pan-gu`、`盘古` 或 `huawei-pangu` | `Pangu cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
77
+ | SenseTime SenseNova / 商汤 | model id/name 包含 `sensenova`、`sense-nova`、`sensechat` 或 `商汤` | `SenseNova cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
78
+ | 360 Zhinao / 智脑 | model id/name 包含 `360gpt`、`360-gpt`、`zhinao` 或 `智脑`(不含裸 `360`) | `Zhinao cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
79
+ | OpenBMB MiniCPM | model id/name 包含 `minicpm`、`mini-cpm` 或 `openbmb` | `MiniCPM cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
80
+ | XVERSE | model id/name 包含 `xverse` | `XVERSE cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
81
+ | OrionStar Orion | model id/name 包含 `orionstar`、`orion-star`,或安全边界内 `orion` 模式 | `Orion cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
82
+ | OpenChat | model id/name 包含 `openchat` | `OpenChat cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
83
+ | Vicuna | model id/name 包含 `vicuna` | `Vicuna cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
84
+ | WizardLM / WizardCoder | model id/name 包含 `wizardlm`、`wizard-lm`、`wizardcoder` 或 `wizard-coder` | `Wizard cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
85
+ | Zephyr | model id/name 包含 `zephyr` | `Zephyr cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
86
+ | Dolphin | model id/name 包含 `dolphin` | `Dolphin cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
87
+ | OpenOrca | model id/name 包含 `openorca` 或 `open-orca` | `OpenOrca cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
88
+ | Starling | model id/name 包含 `starling` | `Starling cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
89
+ | BLOOM / BigScience | model id/name 包含 `bloom` 或 `bigscience` | `BLOOM cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
90
+ | RWKV | model id/name 包含 `rwkv` | `RWKV cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
91
+ | Cohere Aya | model id/name 包含 `aya-expanse`,或安全边界内 `aya` 模式(避免 `maya`/`payara`) | `Aya cache` | Pi 归一化 usage,或可见 OpenAI 形状字段 |
52
92
  | Anthropic / Claude | model id/name 包含 `anthropic` 或 `claude` | `Claude cache` | Pi 归一化 usage,或可见 raw 字段 `cache_read_input_tokens`、`cache_creation_input_tokens`、`input_tokens` |
53
93
  | Gemini / Vertex | model id/name 包含 `gemini` 或 `vertex` | `Gemini cache` | Pi 归一化 usage,或可见 Gemini/Vertex cached-content token metadata |
54
94
 
package/index.ts CHANGED
@@ -91,6 +91,15 @@ const MIN_STABLE_CANDIDATE_LENGTH = 8;
91
91
  const ASSISTANT_MESSAGE_MODEL_TOKEN_KEYS = ["model", "name"];
92
92
  const OPENAI_REASONING_MODEL_PATTERN = /(^|[/\s:_-])o[1345]($|[-_.:/\s])/;
93
93
  const XAI_MODEL_PATTERN = /(^|[/\s:_-])xai($|[-_.:/\s])/;
94
+ const PPLX_MODEL_PATTERN = /(^|[/\s:_-])pplx($|[-_.:/\s])/i;
95
+ const NOVA_MODEL_PATTERN = /(^|[/\s:_-])nova($|[-_.:/\s])/i;
96
+ const MPT_MODEL_PATTERN = /(^|[/\s:_-])mpt($|[-_.:/\s])/i;
97
+ const ALEPH_MODEL_PATTERN = /(^|[/\s:_-])aleph($|[-_.:/\s])/i;
98
+
99
+ // Safe-boundary patterns for models with short or ambiguous tokens
100
+ const ARCTIC_MODEL_PATTERN = /(^|[\/\s:_-])arctic($|[\-_.:\/\s])/i;
101
+ const AYA_MODEL_PATTERN = /(^|[\/\s:_-])aya($|[\-_.:\/\s])/i;
102
+ const ORION_MODEL_PATTERN = /(^|[\/\s:_-])orion($|[\-_.:\/\s])/i;
94
103
 
95
104
  type CacheCompat = {
96
105
  sendSessionAffinityHeaders?: boolean;
@@ -759,6 +768,373 @@ function isYiLikeAssistantMessage(message: unknown, model: PiModel | undefined):
759
768
  return hasAnyTokenContaining(allTokens, ["yi-", "01-ai", "zero-one"]) || allTokens.some((t) => YI_MODEL_PATTERN.test(t));
760
769
  }
761
770
 
771
+ // ── More OpenAI-compatible model detection (batch 2) ───────────────
772
+
773
+ const DOUBAO_SEED_PATTERN = /(^|[\/\s:_-])seed($|[\-_.:\/\s])/i;
774
+
775
+ function isDoubaoLikeModel(model: PiModel | undefined): boolean {
776
+ const tokens = getModelIdNameTokenValues(model);
777
+ return hasAnyTokenContaining(tokens, ["doubao", "豆包", "volcengine", "bytedance", "byte-dance"]) ||
778
+ tokens.some((t) => DOUBAO_SEED_PATTERN.test(t));
779
+ }
780
+ function isDoubaoLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
781
+ const allTokens = [
782
+ ...getModelIdNameTokenValues(model),
783
+ ...getAssistantMessageModelTokenValues(message),
784
+ ];
785
+ return hasAnyTokenContaining(allTokens, ["doubao", "豆包", "volcengine", "bytedance", "byte-dance"]) ||
786
+ allTokens.some((t) => DOUBAO_SEED_PATTERN.test(t));
787
+ }
788
+
789
+ function isErnieLikeModel(model: PiModel | undefined): boolean {
790
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["ernie", "wenxin", "文心", "yiyan", "一言", "baidu"]);
791
+ }
792
+ function isErnieLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
793
+ return modelOrAssistantMessageHas(message, model, ["ernie", "wenxin", "文心", "yiyan", "一言", "baidu"]);
794
+ }
795
+
796
+ function isBaichuanLikeModel(model: PiModel | undefined): boolean {
797
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["baichuan", "百川"]);
798
+ }
799
+ function isBaichuanLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
800
+ return modelOrAssistantMessageHas(message, model, ["baichuan", "百川"]);
801
+ }
802
+
803
+ function isStepFunLikeModel(model: PiModel | undefined): boolean {
804
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["stepfun", "step-"]);
805
+ }
806
+ function isStepFunLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
807
+ return modelOrAssistantMessageHas(message, model, ["stepfun", "step-"]);
808
+ }
809
+
810
+ function isSparkLikeModel(model: PiModel | undefined): boolean {
811
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["spark", "xinghuo", "星火", "iflytek", "讯飞"]);
812
+ }
813
+ function isSparkLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
814
+ return modelOrAssistantMessageHas(message, model, ["spark", "xinghuo", "星火", "iflytek", "讯飞"]);
815
+ }
816
+
817
+ function isInternLMLikeModel(model: PiModel | undefined): boolean {
818
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["internlm", "intern-lm", "书生"]);
819
+ }
820
+ function isInternLMLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
821
+ return modelOrAssistantMessageHas(message, model, ["internlm", "intern-lm", "书生"]);
822
+ }
823
+
824
+ function isGemmaLikeModel(model: PiModel | undefined): boolean {
825
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["gemma"]);
826
+ }
827
+ function isGemmaLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
828
+ return modelOrAssistantMessageHas(message, model, ["gemma"]);
829
+ }
830
+
831
+ const PHI_MODEL_PATTERN = /(^|[\/\s:_-])phi($|[\-_.:\/\s])/i;
832
+
833
+ function isPhiLikeModel(model: PiModel | undefined): boolean {
834
+ const tokens = getModelIdNameTokenValues(model);
835
+ return hasAnyTokenContaining(tokens, ["phi-"]) || tokens.some((t) => PHI_MODEL_PATTERN.test(t));
836
+ }
837
+ function isPhiLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
838
+ const allTokens = [
839
+ ...getModelIdNameTokenValues(model),
840
+ ...getAssistantMessageModelTokenValues(message),
841
+ ];
842
+ return hasAnyTokenContaining(allTokens, ["phi-"]) || allTokens.some((t) => PHI_MODEL_PATTERN.test(t));
843
+ }
844
+
845
+ function isJambaLikeModel(model: PiModel | undefined): boolean {
846
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["jamba", "ai21"]);
847
+ }
848
+ function isJambaLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
849
+ return modelOrAssistantMessageHas(message, model, ["jamba", "ai21"]);
850
+ }
851
+
852
+ function isSolarLikeModel(model: PiModel | undefined): boolean {
853
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["solar", "upstage"]);
854
+ }
855
+ function isSolarLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
856
+ return modelOrAssistantMessageHas(message, model, ["solar", "upstage"]);
857
+ }
858
+
859
+ // ── New OpenAI-compatible model detection (batch 3, 12 families) ──────
860
+
861
+ // Perplexity / Sonar
862
+ function isPerplexityLikeModel(model: PiModel | undefined): boolean {
863
+ const tokens = getModelIdNameTokenValues(model);
864
+ return hasAnyTokenContaining(tokens, ["sonar", "perplexity"]) || tokens.some((t) => PPLX_MODEL_PATTERN.test(t));
865
+ }
866
+ function isPerplexityLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
867
+ const allTokens = [
868
+ ...getModelIdNameTokenValues(model),
869
+ ...getAssistantMessageModelTokenValues(message),
870
+ ];
871
+ return hasAnyTokenContaining(allTokens, ["sonar", "perplexity"]) || allTokens.some((t) => PPLX_MODEL_PATTERN.test(t));
872
+ }
873
+
874
+ // Amazon Nova
875
+ function isNovaLikeModel(model: PiModel | undefined): boolean {
876
+ const tokens = getModelIdNameTokenValues(model);
877
+ return hasAnyTokenContaining(tokens, ["amazon-nova"]) || tokens.some((t) => NOVA_MODEL_PATTERN.test(t));
878
+ }
879
+ function isNovaLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
880
+ const allTokens = [
881
+ ...getModelIdNameTokenValues(model),
882
+ ...getAssistantMessageModelTokenValues(message),
883
+ ];
884
+ return hasAnyTokenContaining(allTokens, ["amazon-nova"]) || allTokens.some((t) => NOVA_MODEL_PATTERN.test(t));
885
+ }
886
+
887
+ // Reka
888
+ function isRekaLikeModel(model: PiModel | undefined): boolean {
889
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["reka"]);
890
+ }
891
+ function isRekaLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
892
+ return modelOrAssistantMessageHas(message, model, ["reka"]);
893
+ }
894
+
895
+ // Falcon / TII
896
+ function isFalconLikeModel(model: PiModel | undefined): boolean {
897
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["falcon", "tiiuae"]);
898
+ }
899
+ function isFalconLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
900
+ return modelOrAssistantMessageHas(message, model, ["falcon", "tiiuae"]);
901
+ }
902
+
903
+ // Databricks DBRX
904
+ function isDbrxLikeModel(model: PiModel | undefined): boolean {
905
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["dbrx", "databricks"]);
906
+ }
907
+ function isDbrxLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
908
+ return modelOrAssistantMessageHas(message, model, ["dbrx", "databricks"]);
909
+ }
910
+
911
+ // MosaicML MPT
912
+ function isMptLikeModel(model: PiModel | undefined): boolean {
913
+ const tokens = getModelIdNameTokenValues(model);
914
+ return hasAnyTokenContaining(tokens, ["mosaicml", "mpt-"]) || tokens.some((t) => MPT_MODEL_PATTERN.test(t));
915
+ }
916
+ function isMptLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
917
+ const allTokens = [
918
+ ...getModelIdNameTokenValues(model),
919
+ ...getAssistantMessageModelTokenValues(message),
920
+ ];
921
+ return hasAnyTokenContaining(allTokens, ["mosaicml", "mpt-"]) || allTokens.some((t) => MPT_MODEL_PATTERN.test(t));
922
+ }
923
+
924
+ // StableLM / Stability AI
925
+ function isStableLMLikeModel(model: PiModel | undefined): boolean {
926
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["stablelm", "stable-lm", "stability-ai"]);
927
+ }
928
+ function isStableLMLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
929
+ return modelOrAssistantMessageHas(message, model, ["stablelm", "stable-lm", "stability-ai"]);
930
+ }
931
+
932
+ // BAAI / Aquila
933
+ function isAquilaLikeModel(model: PiModel | undefined): boolean {
934
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["aquila", "baai"]);
935
+ }
936
+ function isAquilaLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
937
+ return modelOrAssistantMessageHas(message, model, ["aquila", "baai"]);
938
+ }
939
+
940
+ // LG EXAONE
941
+ function isExaoneLikeModel(model: PiModel | undefined): boolean {
942
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["exaone"]);
943
+ }
944
+ function isExaoneLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
945
+ return modelOrAssistantMessageHas(message, model, ["exaone"]);
946
+ }
947
+
948
+ // Naver HyperCLOVA X (conservative: hyperclova, clova-x only)
949
+ function isHyperCLOVALikeModel(model: PiModel | undefined): boolean {
950
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["hyperclova", "clova-x"]);
951
+ }
952
+ function isHyperCLOVALikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
953
+ return modelOrAssistantMessageHas(message, model, ["hyperclova", "clova-x"]);
954
+ }
955
+
956
+ // Aleph Alpha Luminous
957
+ function isLuminousLikeModel(model: PiModel | undefined): boolean {
958
+ const tokens = getModelIdNameTokenValues(model);
959
+ return hasAnyTokenContaining(tokens, ["luminous", "aleph-alpha"]) || tokens.some((t) => ALEPH_MODEL_PATTERN.test(t));
960
+ }
961
+ function isLuminousLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
962
+ const allTokens = [
963
+ ...getModelIdNameTokenValues(model),
964
+ ...getAssistantMessageModelTokenValues(message),
965
+ ];
966
+ return hasAnyTokenContaining(allTokens, ["luminous", "aleph-alpha"]) || allTokens.some((t) => ALEPH_MODEL_PATTERN.test(t));
967
+ }
968
+
969
+ // Nous / Hermes / OpenHermes
970
+ function isHermesLikeModel(model: PiModel | undefined): boolean {
971
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["nous", "hermes", "openhermes"]);
972
+ }
973
+ function isHermesLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
974
+ return modelOrAssistantMessageHas(message, model, ["nous", "hermes", "openhermes"]);
975
+ }
976
+
977
+ // ── More OpenAI-compatible model detection (batch 4, 18 families) ──
978
+
979
+ // IBM Granite
980
+ function isGraniteLikeModel(model: PiModel | undefined): boolean {
981
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["granite", "ibm-granite"]);
982
+ }
983
+ function isGraniteLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
984
+ return modelOrAssistantMessageHas(message, model, ["granite", "ibm-granite"]);
985
+ }
986
+
987
+ // Snowflake Arctic
988
+ function isArcticLikeModel(model: PiModel | undefined): boolean {
989
+ const tokens = getModelIdNameTokenValues(model);
990
+ return hasAnyTokenContaining(tokens, ["snowflake-arctic"]) || tokens.some((t) => ARCTIC_MODEL_PATTERN.test(t));
991
+ }
992
+ function isArcticLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
993
+ const allTokens = [
994
+ ...getModelIdNameTokenValues(model),
995
+ ...getAssistantMessageModelTokenValues(message),
996
+ ];
997
+ return hasAnyTokenContaining(allTokens, ["snowflake-arctic"]) || allTokens.some((t) => ARCTIC_MODEL_PATTERN.test(t));
998
+ }
999
+
1000
+ // Huawei Pangu / 盘古
1001
+ function isPanguLikeModel(model: PiModel | undefined): boolean {
1002
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["pangu", "pan-gu", "盘古", "huawei-pangu"]);
1003
+ }
1004
+ function isPanguLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1005
+ return modelOrAssistantMessageHas(message, model, ["pangu", "pan-gu", "盘古", "huawei-pangu"]);
1006
+ }
1007
+
1008
+ // SenseTime SenseNova / 商汤
1009
+ function isSenseNovaLikeModel(model: PiModel | undefined): boolean {
1010
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["sensenova", "sense-nova", "sensechat", "商汤"]);
1011
+ }
1012
+ function isSenseNovaLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1013
+ return modelOrAssistantMessageHas(message, model, ["sensenova", "sense-nova", "sensechat", "商汤"]);
1014
+ }
1015
+
1016
+ // 360 Zhinao / 智脑
1017
+ function isZhinaoLikeModel(model: PiModel | undefined): boolean {
1018
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["360gpt", "360-gpt", "zhinao", "智脑"]);
1019
+ }
1020
+ function isZhinaoLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1021
+ return modelOrAssistantMessageHas(message, model, ["360gpt", "360-gpt", "zhinao", "智脑"]);
1022
+ }
1023
+
1024
+ // OpenBMB MiniCPM
1025
+ function isMiniCPMLikeModel(model: PiModel | undefined): boolean {
1026
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["minicpm", "mini-cpm", "openbmb"]);
1027
+ }
1028
+ function isMiniCPMLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1029
+ return modelOrAssistantMessageHas(message, model, ["minicpm", "mini-cpm", "openbmb"]);
1030
+ }
1031
+
1032
+ // XVERSE
1033
+ function isXVerseLikeModel(model: PiModel | undefined): boolean {
1034
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["xverse"]);
1035
+ }
1036
+ function isXVerseLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1037
+ return modelOrAssistantMessageHas(message, model, ["xverse"]);
1038
+ }
1039
+
1040
+ // OrionStar Orion
1041
+ function isOrionLikeModel(model: PiModel | undefined): boolean {
1042
+ const tokens = getModelIdNameTokenValues(model);
1043
+ return hasAnyTokenContaining(tokens, ["orionstar", "orion-star"]) || tokens.some((t) => ORION_MODEL_PATTERN.test(t));
1044
+ }
1045
+ function isOrionLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1046
+ const allTokens = [
1047
+ ...getModelIdNameTokenValues(model),
1048
+ ...getAssistantMessageModelTokenValues(message),
1049
+ ];
1050
+ return hasAnyTokenContaining(allTokens, ["orionstar", "orion-star"]) || allTokens.some((t) => ORION_MODEL_PATTERN.test(t));
1051
+ }
1052
+
1053
+ // OpenChat
1054
+ function isOpenChatLikeModel(model: PiModel | undefined): boolean {
1055
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["openchat"]);
1056
+ }
1057
+ function isOpenChatLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1058
+ return modelOrAssistantMessageHas(message, model, ["openchat"]);
1059
+ }
1060
+
1061
+ // Vicuna
1062
+ function isVicunaLikeModel(model: PiModel | undefined): boolean {
1063
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["vicuna"]);
1064
+ }
1065
+ function isVicunaLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1066
+ return modelOrAssistantMessageHas(message, model, ["vicuna"]);
1067
+ }
1068
+
1069
+ // WizardLM / WizardCoder
1070
+ function isWizardLikeModel(model: PiModel | undefined): boolean {
1071
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["wizardlm", "wizard-lm", "wizardcoder", "wizard-coder"]);
1072
+ }
1073
+ function isWizardLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1074
+ return modelOrAssistantMessageHas(message, model, ["wizardlm", "wizard-lm", "wizardcoder", "wizard-coder"]);
1075
+ }
1076
+
1077
+ // Zephyr
1078
+ function isZephyrLikeModel(model: PiModel | undefined): boolean {
1079
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["zephyr"]);
1080
+ }
1081
+ function isZephyrLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1082
+ return modelOrAssistantMessageHas(message, model, ["zephyr"]);
1083
+ }
1084
+
1085
+ // Dolphin
1086
+ function isDolphinLikeModel(model: PiModel | undefined): boolean {
1087
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["dolphin"]);
1088
+ }
1089
+ function isDolphinLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1090
+ return modelOrAssistantMessageHas(message, model, ["dolphin"]);
1091
+ }
1092
+
1093
+ // OpenOrca
1094
+ function isOpenOrcaLikeModel(model: PiModel | undefined): boolean {
1095
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["openorca", "open-orca"]);
1096
+ }
1097
+ function isOpenOrcaLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1098
+ return modelOrAssistantMessageHas(message, model, ["openorca", "open-orca"]);
1099
+ }
1100
+
1101
+ // Starling
1102
+ function isStarlingLikeModel(model: PiModel | undefined): boolean {
1103
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["starling"]);
1104
+ }
1105
+ function isStarlingLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1106
+ return modelOrAssistantMessageHas(message, model, ["starling"]);
1107
+ }
1108
+
1109
+ // BLOOM / BigScience
1110
+ function isBloomLikeModel(model: PiModel | undefined): boolean {
1111
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["bloom", "bigscience"]);
1112
+ }
1113
+ function isBloomLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1114
+ return modelOrAssistantMessageHas(message, model, ["bloom", "bigscience"]);
1115
+ }
1116
+
1117
+ // RWKV
1118
+ function isRwkvLikeModel(model: PiModel | undefined): boolean {
1119
+ return hasAnyTokenContaining(getModelIdNameTokenValues(model), ["rwkv"]);
1120
+ }
1121
+ function isRwkvLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1122
+ return modelOrAssistantMessageHas(message, model, ["rwkv"]);
1123
+ }
1124
+
1125
+ // Cohere Aya
1126
+ function isAyaLikeModel(model: PiModel | undefined): boolean {
1127
+ const tokens = getModelIdNameTokenValues(model);
1128
+ return hasAnyTokenContaining(tokens, ["aya-expanse"]) || tokens.some((t) => AYA_MODEL_PATTERN.test(t));
1129
+ }
1130
+ function isAyaLikeAssistantMessage(message: unknown, model: PiModel | undefined): boolean {
1131
+ const allTokens = [
1132
+ ...getModelIdNameTokenValues(model),
1133
+ ...getAssistantMessageModelTokenValues(message),
1134
+ ];
1135
+ return hasAnyTokenContaining(allTokens, ["aya-expanse"]) || allTokens.some((t) => AYA_MODEL_PATTERN.test(t));
1136
+ }
1137
+
762
1138
  // ── Model key ──────────────────────────────────────────────────────
763
1139
 
764
1140
  function modelKey(model: PiModel): string {
@@ -1335,6 +1711,689 @@ const CACHE_PROVIDER_ADAPTERS: CacheProviderAdapter[] = [
1335
1711
  return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1336
1712
  },
1337
1713
  },
1714
+ // ── More OpenAI-compatible adapters (batch 2) ───────────────────
1715
+ {
1716
+ id: "openai" as CacheProviderId,
1717
+ label: "Doubao cache",
1718
+ matchesModel: isDoubaoLikeModel,
1719
+ matchesAssistantMessage(message, model) {
1720
+ if (!isAssistantMessage(message)) return false;
1721
+ return isDoubaoLikeAssistantMessage(message, model);
1722
+ },
1723
+ normalizeUsage(message) {
1724
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1725
+ },
1726
+ warningText(model) {
1727
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1728
+ if (missing.length === 0) return undefined;
1729
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1730
+ },
1731
+ },
1732
+ {
1733
+ id: "openai" as CacheProviderId,
1734
+ label: "ERNIE cache",
1735
+ matchesModel: isErnieLikeModel,
1736
+ matchesAssistantMessage(message, model) {
1737
+ if (!isAssistantMessage(message)) return false;
1738
+ return isErnieLikeAssistantMessage(message, model);
1739
+ },
1740
+ normalizeUsage(message) {
1741
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1742
+ },
1743
+ warningText(model) {
1744
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1745
+ if (missing.length === 0) return undefined;
1746
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1747
+ },
1748
+ },
1749
+ {
1750
+ id: "openai" as CacheProviderId,
1751
+ label: "Baichuan cache",
1752
+ matchesModel: isBaichuanLikeModel,
1753
+ matchesAssistantMessage(message, model) {
1754
+ if (!isAssistantMessage(message)) return false;
1755
+ return isBaichuanLikeAssistantMessage(message, model);
1756
+ },
1757
+ normalizeUsage(message) {
1758
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1759
+ },
1760
+ warningText(model) {
1761
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1762
+ if (missing.length === 0) return undefined;
1763
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1764
+ },
1765
+ },
1766
+ {
1767
+ id: "openai" as CacheProviderId,
1768
+ label: "StepFun cache",
1769
+ matchesModel: isStepFunLikeModel,
1770
+ matchesAssistantMessage(message, model) {
1771
+ if (!isAssistantMessage(message)) return false;
1772
+ return isStepFunLikeAssistantMessage(message, model);
1773
+ },
1774
+ normalizeUsage(message) {
1775
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1776
+ },
1777
+ warningText(model) {
1778
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1779
+ if (missing.length === 0) return undefined;
1780
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1781
+ },
1782
+ },
1783
+ {
1784
+ id: "openai" as CacheProviderId,
1785
+ label: "Spark cache",
1786
+ matchesModel: isSparkLikeModel,
1787
+ matchesAssistantMessage(message, model) {
1788
+ if (!isAssistantMessage(message)) return false;
1789
+ return isSparkLikeAssistantMessage(message, model);
1790
+ },
1791
+ normalizeUsage(message) {
1792
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1793
+ },
1794
+ warningText(model) {
1795
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1796
+ if (missing.length === 0) return undefined;
1797
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1798
+ },
1799
+ },
1800
+ {
1801
+ id: "openai" as CacheProviderId,
1802
+ label: "InternLM cache",
1803
+ matchesModel: isInternLMLikeModel,
1804
+ matchesAssistantMessage(message, model) {
1805
+ if (!isAssistantMessage(message)) return false;
1806
+ return isInternLMLikeAssistantMessage(message, model);
1807
+ },
1808
+ normalizeUsage(message) {
1809
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1810
+ },
1811
+ warningText(model) {
1812
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1813
+ if (missing.length === 0) return undefined;
1814
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1815
+ },
1816
+ },
1817
+ {
1818
+ id: "openai" as CacheProviderId,
1819
+ label: "Gemma cache",
1820
+ matchesModel: isGemmaLikeModel,
1821
+ matchesAssistantMessage(message, model) {
1822
+ if (!isAssistantMessage(message)) return false;
1823
+ return isGemmaLikeAssistantMessage(message, model);
1824
+ },
1825
+ normalizeUsage(message) {
1826
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1827
+ },
1828
+ warningText(model) {
1829
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1830
+ if (missing.length === 0) return undefined;
1831
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1832
+ },
1833
+ },
1834
+ {
1835
+ id: "openai" as CacheProviderId,
1836
+ label: "Phi cache",
1837
+ matchesModel: isPhiLikeModel,
1838
+ matchesAssistantMessage(message, model) {
1839
+ if (!isAssistantMessage(message)) return false;
1840
+ return isPhiLikeAssistantMessage(message, model);
1841
+ },
1842
+ normalizeUsage(message) {
1843
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1844
+ },
1845
+ warningText(model) {
1846
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1847
+ if (missing.length === 0) return undefined;
1848
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1849
+ },
1850
+ },
1851
+ {
1852
+ id: "openai" as CacheProviderId,
1853
+ label: "Jamba cache",
1854
+ matchesModel: isJambaLikeModel,
1855
+ matchesAssistantMessage(message, model) {
1856
+ if (!isAssistantMessage(message)) return false;
1857
+ return isJambaLikeAssistantMessage(message, model);
1858
+ },
1859
+ normalizeUsage(message) {
1860
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1861
+ },
1862
+ warningText(model) {
1863
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1864
+ if (missing.length === 0) return undefined;
1865
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1866
+ },
1867
+ },
1868
+ {
1869
+ id: "openai" as CacheProviderId,
1870
+ label: "Solar cache",
1871
+ matchesModel: isSolarLikeModel,
1872
+ matchesAssistantMessage(message, model) {
1873
+ if (!isAssistantMessage(message)) return false;
1874
+ return isSolarLikeAssistantMessage(message, model);
1875
+ },
1876
+ normalizeUsage(message) {
1877
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1878
+ },
1879
+ warningText(model) {
1880
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1881
+ if (missing.length === 0) return undefined;
1882
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1883
+ },
1884
+ },
1885
+ // ── New OpenAI-compatible adapters (batch 3, 12 families) ────────
1886
+ {
1887
+ id: "openai" as CacheProviderId,
1888
+ label: "Sonar cache",
1889
+ matchesModel: isPerplexityLikeModel,
1890
+ matchesAssistantMessage(message, model) {
1891
+ if (!isAssistantMessage(message)) return false;
1892
+ return isPerplexityLikeAssistantMessage(message, model);
1893
+ },
1894
+ normalizeUsage(message) {
1895
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1896
+ },
1897
+ warningText(model) {
1898
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1899
+ if (missing.length === 0) return undefined;
1900
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1901
+ },
1902
+ },
1903
+ {
1904
+ id: "openai" as CacheProviderId,
1905
+ label: "Nova cache",
1906
+ matchesModel: isNovaLikeModel,
1907
+ matchesAssistantMessage(message, model) {
1908
+ if (!isAssistantMessage(message)) return false;
1909
+ return isNovaLikeAssistantMessage(message, model);
1910
+ },
1911
+ normalizeUsage(message) {
1912
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1913
+ },
1914
+ warningText(model) {
1915
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1916
+ if (missing.length === 0) return undefined;
1917
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1918
+ },
1919
+ },
1920
+ {
1921
+ id: "openai" as CacheProviderId,
1922
+ label: "Reka cache",
1923
+ matchesModel: isRekaLikeModel,
1924
+ matchesAssistantMessage(message, model) {
1925
+ if (!isAssistantMessage(message)) return false;
1926
+ return isRekaLikeAssistantMessage(message, model);
1927
+ },
1928
+ normalizeUsage(message) {
1929
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1930
+ },
1931
+ warningText(model) {
1932
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1933
+ if (missing.length === 0) return undefined;
1934
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1935
+ },
1936
+ },
1937
+ {
1938
+ id: "openai" as CacheProviderId,
1939
+ label: "Falcon cache",
1940
+ matchesModel: isFalconLikeModel,
1941
+ matchesAssistantMessage(message, model) {
1942
+ if (!isAssistantMessage(message)) return false;
1943
+ return isFalconLikeAssistantMessage(message, model);
1944
+ },
1945
+ normalizeUsage(message) {
1946
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1947
+ },
1948
+ warningText(model) {
1949
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1950
+ if (missing.length === 0) return undefined;
1951
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1952
+ },
1953
+ },
1954
+ {
1955
+ id: "openai" as CacheProviderId,
1956
+ label: "DBRX cache",
1957
+ matchesModel: isDbrxLikeModel,
1958
+ matchesAssistantMessage(message, model) {
1959
+ if (!isAssistantMessage(message)) return false;
1960
+ return isDbrxLikeAssistantMessage(message, model);
1961
+ },
1962
+ normalizeUsage(message) {
1963
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1964
+ },
1965
+ warningText(model) {
1966
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1967
+ if (missing.length === 0) return undefined;
1968
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1969
+ },
1970
+ },
1971
+ {
1972
+ id: "openai" as CacheProviderId,
1973
+ label: "MPT cache",
1974
+ matchesModel: isMptLikeModel,
1975
+ matchesAssistantMessage(message, model) {
1976
+ if (!isAssistantMessage(message)) return false;
1977
+ return isMptLikeAssistantMessage(message, model);
1978
+ },
1979
+ normalizeUsage(message) {
1980
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1981
+ },
1982
+ warningText(model) {
1983
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
1984
+ if (missing.length === 0) return undefined;
1985
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
1986
+ },
1987
+ },
1988
+ {
1989
+ id: "openai" as CacheProviderId,
1990
+ label: "StableLM cache",
1991
+ matchesModel: isStableLMLikeModel,
1992
+ matchesAssistantMessage(message, model) {
1993
+ if (!isAssistantMessage(message)) return false;
1994
+ return isStableLMLikeAssistantMessage(message, model);
1995
+ },
1996
+ normalizeUsage(message) {
1997
+ return normalizeWithFallback(message, getOpenAIRawUsage);
1998
+ },
1999
+ warningText(model) {
2000
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2001
+ if (missing.length === 0) return undefined;
2002
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2003
+ },
2004
+ },
2005
+ {
2006
+ id: "openai" as CacheProviderId,
2007
+ label: "Aquila cache",
2008
+ matchesModel: isAquilaLikeModel,
2009
+ matchesAssistantMessage(message, model) {
2010
+ if (!isAssistantMessage(message)) return false;
2011
+ return isAquilaLikeAssistantMessage(message, model);
2012
+ },
2013
+ normalizeUsage(message) {
2014
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2015
+ },
2016
+ warningText(model) {
2017
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2018
+ if (missing.length === 0) return undefined;
2019
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2020
+ },
2021
+ },
2022
+ {
2023
+ id: "openai" as CacheProviderId,
2024
+ label: "EXAONE cache",
2025
+ matchesModel: isExaoneLikeModel,
2026
+ matchesAssistantMessage(message, model) {
2027
+ if (!isAssistantMessage(message)) return false;
2028
+ return isExaoneLikeAssistantMessage(message, model);
2029
+ },
2030
+ normalizeUsage(message) {
2031
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2032
+ },
2033
+ warningText(model) {
2034
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2035
+ if (missing.length === 0) return undefined;
2036
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2037
+ },
2038
+ },
2039
+ {
2040
+ id: "openai" as CacheProviderId,
2041
+ label: "HyperCLOVA cache",
2042
+ matchesModel: isHyperCLOVALikeModel,
2043
+ matchesAssistantMessage(message, model) {
2044
+ if (!isAssistantMessage(message)) return false;
2045
+ return isHyperCLOVALikeAssistantMessage(message, model);
2046
+ },
2047
+ normalizeUsage(message) {
2048
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2049
+ },
2050
+ warningText(model) {
2051
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2052
+ if (missing.length === 0) return undefined;
2053
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2054
+ },
2055
+ },
2056
+ {
2057
+ id: "openai" as CacheProviderId,
2058
+ label: "Luminous cache",
2059
+ matchesModel: isLuminousLikeModel,
2060
+ matchesAssistantMessage(message, model) {
2061
+ if (!isAssistantMessage(message)) return false;
2062
+ return isLuminousLikeAssistantMessage(message, model);
2063
+ },
2064
+ normalizeUsage(message) {
2065
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2066
+ },
2067
+ warningText(model) {
2068
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2069
+ if (missing.length === 0) return undefined;
2070
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2071
+ },
2072
+ },
2073
+ {
2074
+ id: "openai" as CacheProviderId,
2075
+ label: "Hermes cache",
2076
+ matchesModel: isHermesLikeModel,
2077
+ matchesAssistantMessage(message, model) {
2078
+ if (!isAssistantMessage(message)) return false;
2079
+ return isHermesLikeAssistantMessage(message, model);
2080
+ },
2081
+ normalizeUsage(message) {
2082
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2083
+ },
2084
+ warningText(model) {
2085
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2086
+ if (missing.length === 0) return undefined;
2087
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2088
+ },
2089
+ },
2090
+ // ── More OpenAI-compatible adapters (batch 4, 18 families) ────────
2091
+ {
2092
+ id: "openai" as CacheProviderId,
2093
+ label: "Granite cache",
2094
+ matchesModel: isGraniteLikeModel,
2095
+ matchesAssistantMessage(message, model) {
2096
+ if (!isAssistantMessage(message)) return false;
2097
+ return isGraniteLikeAssistantMessage(message, model);
2098
+ },
2099
+ normalizeUsage(message) {
2100
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2101
+ },
2102
+ warningText(model) {
2103
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2104
+ if (missing.length === 0) return undefined;
2105
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2106
+ },
2107
+ },
2108
+ {
2109
+ id: "openai" as CacheProviderId,
2110
+ label: "Arctic cache",
2111
+ matchesModel: isArcticLikeModel,
2112
+ matchesAssistantMessage(message, model) {
2113
+ if (!isAssistantMessage(message)) return false;
2114
+ return isArcticLikeAssistantMessage(message, model);
2115
+ },
2116
+ normalizeUsage(message) {
2117
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2118
+ },
2119
+ warningText(model) {
2120
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2121
+ if (missing.length === 0) return undefined;
2122
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2123
+ },
2124
+ },
2125
+ {
2126
+ id: "openai" as CacheProviderId,
2127
+ label: "Pangu cache",
2128
+ matchesModel: isPanguLikeModel,
2129
+ matchesAssistantMessage(message, model) {
2130
+ if (!isAssistantMessage(message)) return false;
2131
+ return isPanguLikeAssistantMessage(message, model);
2132
+ },
2133
+ normalizeUsage(message) {
2134
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2135
+ },
2136
+ warningText(model) {
2137
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2138
+ if (missing.length === 0) return undefined;
2139
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2140
+ },
2141
+ },
2142
+ {
2143
+ id: "openai" as CacheProviderId,
2144
+ label: "SenseNova cache",
2145
+ matchesModel: isSenseNovaLikeModel,
2146
+ matchesAssistantMessage(message, model) {
2147
+ if (!isAssistantMessage(message)) return false;
2148
+ return isSenseNovaLikeAssistantMessage(message, model);
2149
+ },
2150
+ normalizeUsage(message) {
2151
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2152
+ },
2153
+ warningText(model) {
2154
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2155
+ if (missing.length === 0) return undefined;
2156
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2157
+ },
2158
+ },
2159
+ {
2160
+ id: "openai" as CacheProviderId,
2161
+ label: "Zhinao cache",
2162
+ matchesModel: isZhinaoLikeModel,
2163
+ matchesAssistantMessage(message, model) {
2164
+ if (!isAssistantMessage(message)) return false;
2165
+ return isZhinaoLikeAssistantMessage(message, model);
2166
+ },
2167
+ normalizeUsage(message) {
2168
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2169
+ },
2170
+ warningText(model) {
2171
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2172
+ if (missing.length === 0) return undefined;
2173
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2174
+ },
2175
+ },
2176
+ {
2177
+ id: "openai" as CacheProviderId,
2178
+ label: "MiniCPM cache",
2179
+ matchesModel: isMiniCPMLikeModel,
2180
+ matchesAssistantMessage(message, model) {
2181
+ if (!isAssistantMessage(message)) return false;
2182
+ return isMiniCPMLikeAssistantMessage(message, model);
2183
+ },
2184
+ normalizeUsage(message) {
2185
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2186
+ },
2187
+ warningText(model) {
2188
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2189
+ if (missing.length === 0) return undefined;
2190
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2191
+ },
2192
+ },
2193
+ {
2194
+ id: "openai" as CacheProviderId,
2195
+ label: "XVERSE cache",
2196
+ matchesModel: isXVerseLikeModel,
2197
+ matchesAssistantMessage(message, model) {
2198
+ if (!isAssistantMessage(message)) return false;
2199
+ return isXVerseLikeAssistantMessage(message, model);
2200
+ },
2201
+ normalizeUsage(message) {
2202
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2203
+ },
2204
+ warningText(model) {
2205
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2206
+ if (missing.length === 0) return undefined;
2207
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2208
+ },
2209
+ },
2210
+ {
2211
+ id: "openai" as CacheProviderId,
2212
+ label: "Orion cache",
2213
+ matchesModel: isOrionLikeModel,
2214
+ matchesAssistantMessage(message, model) {
2215
+ if (!isAssistantMessage(message)) return false;
2216
+ return isOrionLikeAssistantMessage(message, model);
2217
+ },
2218
+ normalizeUsage(message) {
2219
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2220
+ },
2221
+ warningText(model) {
2222
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2223
+ if (missing.length === 0) return undefined;
2224
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2225
+ },
2226
+ },
2227
+ {
2228
+ id: "openai" as CacheProviderId,
2229
+ label: "OpenChat cache",
2230
+ matchesModel: isOpenChatLikeModel,
2231
+ matchesAssistantMessage(message, model) {
2232
+ if (!isAssistantMessage(message)) return false;
2233
+ return isOpenChatLikeAssistantMessage(message, model);
2234
+ },
2235
+ normalizeUsage(message) {
2236
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2237
+ },
2238
+ warningText(model) {
2239
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2240
+ if (missing.length === 0) return undefined;
2241
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2242
+ },
2243
+ },
2244
+ {
2245
+ id: "openai" as CacheProviderId,
2246
+ label: "Vicuna cache",
2247
+ matchesModel: isVicunaLikeModel,
2248
+ matchesAssistantMessage(message, model) {
2249
+ if (!isAssistantMessage(message)) return false;
2250
+ return isVicunaLikeAssistantMessage(message, model);
2251
+ },
2252
+ normalizeUsage(message) {
2253
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2254
+ },
2255
+ warningText(model) {
2256
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2257
+ if (missing.length === 0) return undefined;
2258
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2259
+ },
2260
+ },
2261
+ {
2262
+ id: "openai" as CacheProviderId,
2263
+ label: "Wizard cache",
2264
+ matchesModel: isWizardLikeModel,
2265
+ matchesAssistantMessage(message, model) {
2266
+ if (!isAssistantMessage(message)) return false;
2267
+ return isWizardLikeAssistantMessage(message, model);
2268
+ },
2269
+ normalizeUsage(message) {
2270
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2271
+ },
2272
+ warningText(model) {
2273
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2274
+ if (missing.length === 0) return undefined;
2275
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2276
+ },
2277
+ },
2278
+ {
2279
+ id: "openai" as CacheProviderId,
2280
+ label: "Zephyr cache",
2281
+ matchesModel: isZephyrLikeModel,
2282
+ matchesAssistantMessage(message, model) {
2283
+ if (!isAssistantMessage(message)) return false;
2284
+ return isZephyrLikeAssistantMessage(message, model);
2285
+ },
2286
+ normalizeUsage(message) {
2287
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2288
+ },
2289
+ warningText(model) {
2290
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2291
+ if (missing.length === 0) return undefined;
2292
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2293
+ },
2294
+ },
2295
+ {
2296
+ id: "openai" as CacheProviderId,
2297
+ label: "Dolphin cache",
2298
+ matchesModel: isDolphinLikeModel,
2299
+ matchesAssistantMessage(message, model) {
2300
+ if (!isAssistantMessage(message)) return false;
2301
+ return isDolphinLikeAssistantMessage(message, model);
2302
+ },
2303
+ normalizeUsage(message) {
2304
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2305
+ },
2306
+ warningText(model) {
2307
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2308
+ if (missing.length === 0) return undefined;
2309
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2310
+ },
2311
+ },
2312
+ {
2313
+ id: "openai" as CacheProviderId,
2314
+ label: "OpenOrca cache",
2315
+ matchesModel: isOpenOrcaLikeModel,
2316
+ matchesAssistantMessage(message, model) {
2317
+ if (!isAssistantMessage(message)) return false;
2318
+ return isOpenOrcaLikeAssistantMessage(message, model);
2319
+ },
2320
+ normalizeUsage(message) {
2321
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2322
+ },
2323
+ warningText(model) {
2324
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2325
+ if (missing.length === 0) return undefined;
2326
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2327
+ },
2328
+ },
2329
+ {
2330
+ id: "openai" as CacheProviderId,
2331
+ label: "Starling cache",
2332
+ matchesModel: isStarlingLikeModel,
2333
+ matchesAssistantMessage(message, model) {
2334
+ if (!isAssistantMessage(message)) return false;
2335
+ return isStarlingLikeAssistantMessage(message, model);
2336
+ },
2337
+ normalizeUsage(message) {
2338
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2339
+ },
2340
+ warningText(model) {
2341
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2342
+ if (missing.length === 0) return undefined;
2343
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2344
+ },
2345
+ },
2346
+ {
2347
+ id: "openai" as CacheProviderId,
2348
+ label: "BLOOM cache",
2349
+ matchesModel: isBloomLikeModel,
2350
+ matchesAssistantMessage(message, model) {
2351
+ if (!isAssistantMessage(message)) return false;
2352
+ return isBloomLikeAssistantMessage(message, model);
2353
+ },
2354
+ normalizeUsage(message) {
2355
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2356
+ },
2357
+ warningText(model) {
2358
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2359
+ if (missing.length === 0) return undefined;
2360
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2361
+ },
2362
+ },
2363
+ {
2364
+ id: "openai" as CacheProviderId,
2365
+ label: "RWKV cache",
2366
+ matchesModel: isRwkvLikeModel,
2367
+ matchesAssistantMessage(message, model) {
2368
+ if (!isAssistantMessage(message)) return false;
2369
+ return isRwkvLikeAssistantMessage(message, model);
2370
+ },
2371
+ normalizeUsage(message) {
2372
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2373
+ },
2374
+ warningText(model) {
2375
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2376
+ if (missing.length === 0) return undefined;
2377
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2378
+ },
2379
+ },
2380
+ {
2381
+ id: "openai" as CacheProviderId,
2382
+ label: "Aya cache",
2383
+ matchesModel: isAyaLikeModel,
2384
+ matchesAssistantMessage(message, model) {
2385
+ if (!isAssistantMessage(message)) return false;
2386
+ return isAyaLikeAssistantMessage(message, model);
2387
+ },
2388
+ normalizeUsage(message) {
2389
+ return normalizeWithFallback(message, getOpenAIRawUsage);
2390
+ },
2391
+ warningText(model) {
2392
+ const missing = describeMissingOpenAICompatibleProxyCompat(model);
2393
+ if (missing.length === 0) return undefined;
2394
+ return buildOpenAIProxyCompatWarningText(modelKey(model), missing);
2395
+ },
2396
+ },
1338
2397
  ];
1339
2398
 
1340
2399
  function selectAdapterForModel(model: PiModel | undefined): CacheProviderAdapter | undefined {
@@ -1680,6 +2739,89 @@ export const __internals_for_tests = {
1680
2739
  isCohereLikeAssistantMessage,
1681
2740
  isYiLikeModel,
1682
2741
  isYiLikeAssistantMessage,
2742
+ // More OpenAI-compatible model detection (batch 2)
2743
+ isDoubaoLikeModel,
2744
+ isDoubaoLikeAssistantMessage,
2745
+ isErnieLikeModel,
2746
+ isErnieLikeAssistantMessage,
2747
+ isBaichuanLikeModel,
2748
+ isBaichuanLikeAssistantMessage,
2749
+ isStepFunLikeModel,
2750
+ isStepFunLikeAssistantMessage,
2751
+ isSparkLikeModel,
2752
+ isSparkLikeAssistantMessage,
2753
+ isInternLMLikeModel,
2754
+ isInternLMLikeAssistantMessage,
2755
+ isGemmaLikeModel,
2756
+ isGemmaLikeAssistantMessage,
2757
+ isPhiLikeModel,
2758
+ isPhiLikeAssistantMessage,
2759
+ isJambaLikeModel,
2760
+ isJambaLikeAssistantMessage,
2761
+ isSolarLikeModel,
2762
+ isSolarLikeAssistantMessage,
2763
+ // New OpenAI-compatible model detection (batch 3, 12 families)
2764
+ isPerplexityLikeModel,
2765
+ isPerplexityLikeAssistantMessage,
2766
+ isNovaLikeModel,
2767
+ isNovaLikeAssistantMessage,
2768
+ isRekaLikeModel,
2769
+ isRekaLikeAssistantMessage,
2770
+ isFalconLikeModel,
2771
+ isFalconLikeAssistantMessage,
2772
+ isDbrxLikeModel,
2773
+ isDbrxLikeAssistantMessage,
2774
+ isMptLikeModel,
2775
+ isMptLikeAssistantMessage,
2776
+ isStableLMLikeModel,
2777
+ isStableLMLikeAssistantMessage,
2778
+ isAquilaLikeModel,
2779
+ isAquilaLikeAssistantMessage,
2780
+ isExaoneLikeModel,
2781
+ isExaoneLikeAssistantMessage,
2782
+ isHyperCLOVALikeModel,
2783
+ isHyperCLOVALikeAssistantMessage,
2784
+ isLuminousLikeModel,
2785
+ isLuminousLikeAssistantMessage,
2786
+ isHermesLikeModel,
2787
+ isHermesLikeAssistantMessage,
2788
+ // More OpenAI-compatible model detection (batch 4, 18 families)
2789
+ isGraniteLikeModel,
2790
+ isGraniteLikeAssistantMessage,
2791
+ isArcticLikeModel,
2792
+ isArcticLikeAssistantMessage,
2793
+ isPanguLikeModel,
2794
+ isPanguLikeAssistantMessage,
2795
+ isSenseNovaLikeModel,
2796
+ isSenseNovaLikeAssistantMessage,
2797
+ isZhinaoLikeModel,
2798
+ isZhinaoLikeAssistantMessage,
2799
+ isMiniCPMLikeModel,
2800
+ isMiniCPMLikeAssistantMessage,
2801
+ isXVerseLikeModel,
2802
+ isXVerseLikeAssistantMessage,
2803
+ isOrionLikeModel,
2804
+ isOrionLikeAssistantMessage,
2805
+ isOpenChatLikeModel,
2806
+ isOpenChatLikeAssistantMessage,
2807
+ isVicunaLikeModel,
2808
+ isVicunaLikeAssistantMessage,
2809
+ isWizardLikeModel,
2810
+ isWizardLikeAssistantMessage,
2811
+ isZephyrLikeModel,
2812
+ isZephyrLikeAssistantMessage,
2813
+ isDolphinLikeModel,
2814
+ isDolphinLikeAssistantMessage,
2815
+ isOpenOrcaLikeModel,
2816
+ isOpenOrcaLikeAssistantMessage,
2817
+ isStarlingLikeModel,
2818
+ isStarlingLikeAssistantMessage,
2819
+ isBloomLikeModel,
2820
+ isBloomLikeAssistantMessage,
2821
+ isRwkvLikeModel,
2822
+ isRwkvLikeAssistantMessage,
2823
+ isAyaLikeModel,
2824
+ isAyaLikeAssistantMessage,
1683
2825
  buildOpenAIProxyCompatWarningText,
1684
2826
  getModelIdNameTokenValues,
1685
2827
  getAssistantMessageModelTokenValues,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-cache-optimizer",
3
- "version": "2.4.5",
3
+ "version": "2.4.7",
4
4
  "description": "Pi extension that improves provider-side KV/prompt cache hit rates (DeepSeek, OpenAI, Claude, Gemini) by reordering the system prompt, requesting long retention, and showing footer cache stats. Renamed from pi-deepseek-cache-optimizer.",
5
5
  "keywords": [
6
6
  "pi-package",