@@ -34,27 +34,42 @@ function getModelsJsonPath(): string {
3434 return join ( cacheBase , "opencode" , "models.json" ) ;
3535}
3636
37+ function getOpencodeConfigPath ( ) : string | null {
38+ const envDir = process . env . OPENCODE_CONFIG_DIR ?. trim ( ) ;
39+ const configDir = envDir
40+ ? envDir
41+ : platform ( ) === "win32"
42+ ? join ( homedir ( ) , ".config" , "opencode" )
43+ : join ( process . env . XDG_CONFIG_HOME || join ( homedir ( ) , ".config" ) , "opencode" ) ;
44+
45+ // Check jsonc first, then json (matches OpenCode's own lookup order)
46+ const jsonc = join ( configDir , "opencode.jsonc" ) ;
47+ if ( existsSync ( jsonc ) ) return jsonc ;
48+ const json = join ( configDir , "opencode.json" ) ;
49+ if ( existsSync ( json ) ) return json ;
50+ return null ;
51+ }
52+
3753function loadModelsDevLimits ( ) : Map < string , number > {
3854 const limits = new Map < string , number > ( ) ;
39- const filePath = getModelsJsonPath ( ) ;
4055
56+ // 1. Load from OpenCode's models.dev cache (base layer — all known public models)
57+ const modelsJsonPath = getModelsJsonPath ( ) ;
4158 try {
42- if ( ! existsSync ( filePath ) ) {
43- return limits ;
44- }
59+ if ( existsSync ( modelsJsonPath ) ) {
60+ const raw = readFileSync ( modelsJsonPath , "utf-8" ) ;
61+ const data = JSON . parse ( raw ) as Record <
62+ string ,
63+ { models ?: Record < string , { limit ?: { context ?: number } } > }
64+ > ;
4565
46- const raw = readFileSync ( filePath , "utf-8" ) ;
47- const data = JSON . parse ( raw ) as Record <
48- string ,
49- { models ?: Record < string , { limit ?: { context ?: number } } > }
50- > ;
51-
52- for ( const [ providerId , provider ] of Object . entries ( data ) ) {
53- if ( ! provider ?. models || typeof provider . models !== "object" ) continue ;
54- for ( const [ modelId , model ] of Object . entries ( provider . models ) ) {
55- const context = model ?. limit ?. context ;
56- if ( typeof context === "number" && context > 0 ) {
57- limits . set ( `${ providerId } /${ modelId } ` , context ) ;
66+ for ( const [ providerId , provider ] of Object . entries ( data ) ) {
67+ if ( ! provider ?. models || typeof provider . models !== "object" ) continue ;
68+ for ( const [ modelId , model ] of Object . entries ( provider . models ) ) {
69+ const context = model ?. limit ?. context ;
70+ if ( typeof context === "number" && context > 0 ) {
71+ limits . set ( `${ providerId } /${ modelId } ` , context ) ;
72+ }
5873 }
5974 }
6075 }
@@ -66,6 +81,42 @@ function loadModelsDevLimits(): Map<string, number> {
6681 ) ;
6782 }
6883
84+ // 2. Overlay custom provider models from OpenCode config (higher priority).
85+ // Users define custom/proxy models via provider.<id>.models.<name>.limit.context
86+ // in opencode.json(c). These override models.dev entries for the same key.
87+ try {
88+ const configPath = getOpencodeConfigPath ( ) ;
89+ if ( configPath && existsSync ( configPath ) ) {
90+ let raw = readFileSync ( configPath , "utf-8" ) ;
91+ // Strip JSONC comments (single-line only — sufficient for OpenCode configs)
92+ raw = raw . replace ( / \/ \/ .* $ / gm, "" ) ;
93+ const config = JSON . parse ( raw ) as {
94+ provider ?: Record <
95+ string ,
96+ { models ?: Record < string , { limit ?: { context ?: number } } > }
97+ > ;
98+ } ;
99+
100+ if ( config . provider && typeof config . provider === "object" ) {
101+ for ( const [ providerId , provider ] of Object . entries ( config . provider ) ) {
102+ if ( ! provider ?. models || typeof provider . models !== "object" ) continue ;
103+ for ( const [ modelId , model ] of Object . entries ( provider . models ) ) {
104+ const context = model ?. limit ?. context ;
105+ if ( typeof context === "number" && context > 0 ) {
106+ limits . set ( `${ providerId } /${ modelId } ` , context ) ;
107+ }
108+ }
109+ }
110+ }
111+ }
112+ } catch ( error ) {
113+ sessionLog (
114+ "global" ,
115+ "models-dev-cache: failed to read opencode config for custom models:" ,
116+ error instanceof Error ? error . message : String ( error ) ,
117+ ) ;
118+ }
119+
69120 return limits ;
70121}
71122
0 commit comments