@darknesskiller/opencode-cliproxyapi 0.3.1 → 0.4.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/CHANGELOG.md CHANGED
@@ -5,7 +5,26 @@ All notable changes to this project are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
6
6
  and this project follows [Semantic Versioning](https://semver.org/).
7
7
 
8
- ## [0.3.1] - Unreleased
8
+ ## [0.4.0] - 2026-11-13
9
+
10
+ ### Added
11
+
12
+ - Discovered models now carry token limits parsed from the CLIProxyAPI
13
+ codex-client catalog, resolving the V1/V2 alignment gap. Context window
14
+ comes from `context_window`, falling back to `max_context_window` and
15
+ then 128,000; output comes from `max_tokens`, falling back to 32,000,
16
+ OpenCode V1's effective default (`0` breaks Anthropic-routed models and
17
+ V2 has no default of its own). Both plugin versions resolve limits
18
+ through the same shared code.
19
+ - User config now wins per field over discovered models in both versions:
20
+ non-empty strings for `name`/`package`/`provider.npm`, booleans for the
21
+ capability flags, and `limit` merged key-by-key (raising and lowering
22
+ both win; `0` keeps the default policy). `variants` and other nested
23
+ objects keep whole-object override semantics, models configured in user
24
+ config alone are preserved, and invalid values no longer erase what
25
+ discovery found.
26
+
27
+ ## [0.3.1] - 2026-11-13
9
28
 
10
29
  ### Fixed
11
30
 
@@ -17,7 +36,7 @@ and this project follows [Semantic Versioning](https://semver.org/).
17
36
  sets the matching `capabilities.input`, both from one shared policy.
18
37
  Text-only `gpt-oss-*` models are no longer marked as attachment-capable.
19
38
 
20
- ## [0.3.0] - 2026-10-05
39
+ ## [0.3.0] - 2026-10-06
21
40
 
22
41
  ### Added
23
42
 
@@ -90,7 +109,8 @@ and this project follows [Semantic Versioning](https://semver.org/).
90
109
  - Automatic model names and capability hints in OpenCode's model picker.
91
110
  - Local plugin and npm package installation flows.
92
111
 
93
- [Unreleased]: https://github.com/DarknessKiller/opencode-cliproxyapi/compare/v0.3.0...HEAD
112
+ [Unreleased]: https://github.com/DarknessKiller/opencode-cliproxyapi/compare/v0.4.0...HEAD
113
+ [0.4.0]: https://github.com/DarknessKiller/opencode-cliproxyapi/compare/v0.3.1...v0.4.0
94
114
  [0.3.0]: https://github.com/DarknessKiller/opencode-cliproxyapi/compare/v0.2.1...v0.3.0
95
115
  [0.2.1]: https://github.com/DarknessKiller/opencode-cliproxyapi/compare/v0.2.0...v0.2.1
96
116
  [0.2.0]: https://github.com/DarknessKiller/opencode-cliproxyapi/compare/v0.1.2...v0.2.0
package/dist/catalog.d.ts CHANGED
@@ -7,8 +7,12 @@ export type ModelProtocolCatalog = Record<string, {
7
7
  models: Record<string, string>;
8
8
  }>;
9
9
  export type ReasoningEffortLevels = {
10
- levels: string[];
10
+ levels?: string[];
11
11
  defaultLevel?: string;
12
+ limit?: {
13
+ context?: number;
14
+ output?: number;
15
+ };
12
16
  };
13
17
  export type ReasoningEffortCatalog = Record<string, ReasoningEffortLevels>;
14
18
  export declare function normalizeBaseURL(value: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,CACvC,MAAM,EACN;IACE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B,CACF,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAGD,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAA;AAW1E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,UAK7C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,EAAE,CAuB3D;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,CAqBlF;AAED,wBAAsB,wBAAwB,CAAC,KAAK,EAAE;IACpD,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAiBlC;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE;IAC1C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB,2BAcA;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAsB9E;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB,iCAaA"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,CACvC,MAAM,EACN;IACE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC/B,CACF,CAAA;AAID,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9C,CAAA;AAGD,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAA;AAW1E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,UAK7C;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,EAAE,CAuB3D;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,CAiClF;AAED,wBAAsB,wBAAwB,CAAC,KAAK,EAAE;IACpD,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAiBlC;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE;IAC1C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB,2BAcA;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAsB9E;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;CACvB,iCAaA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,MAAM,EAAgB,MAAM,qBAAqB,CAAA;AAwBvE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAWtC,eAAO,MAAM,iBAAiB,EAAE,MAiE/B,CAAA;AAED;;;GAGG;;;;;;AACH,wBAIkD;AAClD,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,wBAAwB,EACxB,gBAAgB,EAChB,YAAY,EACZ,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,MAAM,EAAgB,MAAM,qBAAqB,CAAA;AA6BvE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAWtC,eAAO,MAAM,iBAAiB,EAAE,MAiE/B,CAAA;AAED;;;GAGG;;;;;;AACH,wBAIkD;AAClD,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,wBAAwB,EACxB,gBAAgB,EAChB,YAAY,EACZ,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA"}
package/dist/index.js CHANGED
@@ -38,15 +38,19 @@ function parseReasoningEffortCatalog(input) {
38
38
  if (!isRecord(item) || typeof item.slug !== "string" || item.slug.trim() === "")
39
39
  continue;
40
40
  const rawLevels = item.supported_reasoning_levels;
41
- if (!Array.isArray(rawLevels))
42
- continue;
43
- const levels = rawLevels.map((entry) => isRecord(entry) && typeof entry.effort === "string" ? entry.effort : undefined).filter((level) => level !== undefined);
44
- if (levels.length === 0)
45
- continue;
46
- const defaultLevel = typeof item.default_reasoning_level === "string" ? item.default_reasoning_level : undefined;
41
+ const levels = Array.isArray(rawLevels) ? rawLevels.map((entry) => isRecord(entry) && typeof entry.effort === "string" ? entry.effort : undefined).filter((level) => level !== undefined) : undefined;
42
+ const limit = {};
43
+ const context = [item.context_window, item.max_context_window].find(isPositiveNumber);
44
+ const output = isPositiveNumber(item.max_tokens) ? item.max_tokens : undefined;
45
+ if (context !== undefined)
46
+ limit.context = context;
47
+ if (output !== undefined)
48
+ limit.output = output;
49
+ const defaultLevel = levels && typeof item.default_reasoning_level === "string" ? item.default_reasoning_level : undefined;
47
50
  catalog[item.slug] = {
48
- levels: [...new Set(levels)],
49
- ...defaultLevel ? { defaultLevel } : {}
51
+ ...levels ? { levels: [...new Set(levels)] } : {},
52
+ ...defaultLevel ? { defaultLevel } : {},
53
+ ...Object.keys(limit).length > 0 ? { limit } : {}
50
54
  };
51
55
  }
52
56
  return catalog;
@@ -99,6 +103,9 @@ async function discoverModelProtocols(input) {
99
103
  }
100
104
  return parseModelProtocolCatalog(await response.json());
101
105
  }
106
+ function isPositiveNumber(value) {
107
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
108
+ }
102
109
  function isRecord(value) {
103
110
  return typeof value === "object" && value !== null && !Array.isArray(value);
104
111
  }
@@ -109,6 +116,8 @@ var DEFAULT_PROVIDER_ID = "cliproxyapi";
109
116
  var DEFAULT_PROVIDER_NAME = "CLIProxyAPI";
110
117
  var DEFAULT_DISCOVERY_TIMEOUT_MS = 1e4;
111
118
  var DEFAULT_MODEL_METADATA_URL = "https://models.dev/api.json";
119
+ var DEFAULT_CONTEXT_LIMIT = 128000;
120
+ var DEFAULT_OUTPUT_LIMIT = 32000;
112
121
  var V1_CHAT_PACKAGE = "@ai-sdk/openai-compatible";
113
122
  var V1_RESPONSES_PACKAGE = "@ai-sdk/openai";
114
123
  var V1_ANTHROPIC_PACKAGE = "@ai-sdk/anthropic";
@@ -131,6 +140,35 @@ function readOptions(input) {
131
140
  function stringOption(value) {
132
141
  return typeof value === "string" && value.trim() !== "" ? value : undefined;
133
142
  }
143
+ function resolveModelLimits(model, effortCatalog) {
144
+ const limit = effortCatalog[model.id]?.limit;
145
+ return {
146
+ context: limit?.context ?? DEFAULT_CONTEXT_LIMIT,
147
+ output: limit?.output ?? DEFAULT_OUTPUT_LIMIT
148
+ };
149
+ }
150
+ function isProperString(value) {
151
+ return typeof value === "string" && value.trim() !== "";
152
+ }
153
+ function isProperBoolean(value) {
154
+ return typeof value === "boolean";
155
+ }
156
+ function isProperContextLimit(value) {
157
+ return Number.isInteger(value) && value > 0;
158
+ }
159
+ function isProperOutputLimit(value) {
160
+ return Number.isInteger(value) && value > 0;
161
+ }
162
+ function properLimitOverrides(userLimit) {
163
+ const input = typeof userLimit === "object" && userLimit !== null ? userLimit : {};
164
+ return {
165
+ ...isProperContextLimit(input.context) ? { context: input.context } : {},
166
+ ...isProperOutputLimit(input.output) ? { output: input.output } : {}
167
+ };
168
+ }
169
+ function definedKeys(value) {
170
+ return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
171
+ }
134
172
  function displayName(modelID) {
135
173
  return modelID.split("-").map((part) => {
136
174
  const lower = part.toLowerCase();
@@ -147,7 +185,7 @@ function isImageModel(modelID) {
147
185
  return /(?:^|-)image(?:-|$)/i.test(modelID);
148
186
  }
149
187
  function isReasoningModel(modelID, efforts) {
150
- if (efforts?.levels.length)
188
+ if (efforts?.levels?.length)
151
189
  return efforts.levels.some((level) => level !== "none");
152
190
  return /thinking|reasoning|codex|gpt-(?:5|oss)/i.test(modelID);
153
191
  }
@@ -174,7 +212,7 @@ function supportedEffortLevels(model, input) {
174
212
  return;
175
213
  if (isAnthropicRouted(model, input.protocolCatalog))
176
214
  return;
177
- const levels = efforts.levels.filter((level) => level !== "none");
215
+ const levels = efforts.levels?.filter((level) => level !== "none") ?? [];
178
216
  return levels.length > 0 ? levels : undefined;
179
217
  }
180
218
  async function discoverCatalog(input) {
@@ -209,8 +247,6 @@ function discoverEffortLevels(input) {
209
247
  }
210
248
 
211
249
  // src/plugin-v2.ts
212
- var DEFAULT_CONTEXT_LIMIT = 128000;
213
- var DEFAULT_OUTPUT_LIMIT = 4096;
214
250
  function toV2Model(model, input) {
215
251
  const image = isImageModel(model.id);
216
252
  const modalities = modelModalities(model.id);
@@ -235,12 +271,39 @@ function toV2Model(model, input) {
235
271
  cost: [{ input: 0, output: 0, cache: { read: 0, write: 0 } }],
236
272
  status: "active",
237
273
  enabled: true,
238
- limit: { context: DEFAULT_CONTEXT_LIMIT, output: DEFAULT_OUTPUT_LIMIT }
274
+ limit: resolveModelLimits(model, input.discovery.effortCatalog)
239
275
  };
240
276
  }
241
277
  function toV2Models(input) {
242
278
  return input.discovery.catalog.map((model) => toV2Model(model, { providerID: input.providerID, discovery: input.discovery }));
243
279
  }
280
+ function mergeV2Models(discovered, userModels) {
281
+ const merged = discovered.map((base) => {
282
+ const userModel = userModels?.get(base.id);
283
+ return isRecord2(userModel) ? mergeV2Model(base, userModel) : base;
284
+ });
285
+ if (userModels) {
286
+ const discoveredIDs = new Set(discovered.map((model) => model.id));
287
+ for (const [id, userModel] of userModels) {
288
+ if (!discoveredIDs.has(id) && isRecord2(userModel))
289
+ merged.push(userModel);
290
+ }
291
+ }
292
+ return merged;
293
+ }
294
+ function mergeV2Model(base, userModel) {
295
+ return {
296
+ ...base,
297
+ ...definedKeys(userModel),
298
+ name: isProperString(userModel.name) ? userModel.name : base.name,
299
+ package: isProperString(userModel.package) ? userModel.package : base.package,
300
+ enabled: isProperBoolean(userModel.enabled) ? userModel.enabled : base.enabled,
301
+ limit: { ...base.limit, ...properLimitOverrides(userModel.limit) }
302
+ };
303
+ }
304
+ function isRecord2(value) {
305
+ return typeof value === "object" && value !== null && !Array.isArray(value);
306
+ }
244
307
  async function setup(ctx) {
245
308
  const options = readOptions(ctx.options);
246
309
  const providerID = options.providerID ?? DEFAULT_PROVIDER_ID;
@@ -252,13 +315,14 @@ async function setup(ctx) {
252
315
  for (const error of discovery.errors) {
253
316
  console.warn(`[cliproxyapi] ${error}`);
254
317
  }
255
- const models = toV2Models({ providerID, discovery });
318
+ const discovered = toV2Models({ providerID, discovery });
256
319
  const providerPackage = options.protocol === "responses" ? V2_RESPONSES_PACKAGE : V2_CHAT_PACKAGE;
257
320
  await ctx.provider.transform((editor) => {
258
321
  const settings = { baseURL };
259
322
  if (apiKey)
260
323
  settings.apiKey = apiKey;
261
324
  const existing = editor.get(providerID);
325
+ const models = mergeV2Models(discovered, existing?.models);
262
326
  if (existing) {
263
327
  editor.update(providerID, (provider) => {
264
328
  provider.name = provider.name || options.providerName || DEFAULT_PROVIDER_NAME;
@@ -351,6 +415,7 @@ function addProvider(config, input) {
351
415
  tool_call: !isImageModel(model.id),
352
416
  reasoning: isReasoningModel(model.id, input.effortCatalog[model.id]),
353
417
  attachment: supportsAttachments(model.id),
418
+ limit: resolveModelLimits(model, input.effortCatalog),
354
419
  ...model.ownedBy && resolveModelNpm(input.protocolCatalog, model.ownedBy, model.id) === V1_ANTHROPIC_PACKAGE ? {
355
420
  provider: {
356
421
  npm: V1_ANTHROPIC_PACKAGE
@@ -389,12 +454,12 @@ function reasoningEffortConfig(model, input) {
389
454
  const levels = supportedEffortLevels(model, input);
390
455
  if (!levels)
391
456
  return {};
392
- const defaultLevel = efforts.defaultLevel !== undefined && efforts.levels.includes(efforts.defaultLevel) ? efforts.defaultLevel : undefined;
457
+ const defaultLevel = efforts.defaultLevel !== undefined && efforts.levels?.includes(efforts.defaultLevel) ? efforts.defaultLevel : undefined;
393
458
  return {
394
459
  ...defaultLevel ? { options: { reasoningEffort: defaultLevel } } : {},
395
460
  variants: {
396
- ...Object.fromEntries(efforts.levels.map((level) => [level, { reasoningEffort: level }])),
397
- ...disabledVariants(efforts.levels)
461
+ ...Object.fromEntries((efforts.levels ?? []).map((level) => [level, { reasoningEffort: level }])),
462
+ ...disabledVariants(efforts.levels ?? [])
398
463
  }
399
464
  };
400
465
  }
@@ -408,17 +473,42 @@ function disabledVariants(supported) {
408
473
  }
409
474
  function mergeModels(discovered, existing) {
410
475
  const merged = { ...discovered };
411
- for (const [modelID, model] of Object.entries(existing ?? {})) {
412
- const discoveredModel = merged[modelID];
413
- const providerNpm = model.provider?.npm ?? discoveredModel?.provider?.npm;
414
- merged[modelID] = {
415
- ...discoveredModel,
416
- ...model,
417
- ...providerNpm ? { provider: { npm: providerNpm } } : {}
418
- };
476
+ for (const [modelID, userModel] of Object.entries(existing ?? {})) {
477
+ const base = merged[modelID];
478
+ if (!base) {
479
+ if (isRecord3(userModel))
480
+ merged[modelID] = { ...userModel };
481
+ continue;
482
+ }
483
+ if (isRecord3(userModel))
484
+ merged[modelID] = mergeDiscoveredModel(base, userModel);
485
+ }
486
+ return merged;
487
+ }
488
+ function mergeDiscoveredModel(base, userModel) {
489
+ const limits = { ...base.limit, ...properLimitOverrides(userModel.limit) };
490
+ const merged = {
491
+ ...base,
492
+ ...definedKeys(userModel),
493
+ name: isProperString(userModel.name) ? userModel.name : base.name,
494
+ tool_call: isProperBoolean(userModel.tool_call) ? userModel.tool_call : base.tool_call,
495
+ reasoning: isProperBoolean(userModel.reasoning) ? userModel.reasoning : base.reasoning,
496
+ attachment: isProperBoolean(userModel.attachment) ? userModel.attachment : base.attachment,
497
+ limit: limits
498
+ };
499
+ const userProvider = userModel.provider;
500
+ if (typeof userProvider === "object" && userProvider !== null) {
501
+ const { npm, ...rest } = userProvider;
502
+ const providerNpm = isProperString(npm) ? npm : base.provider?.npm;
503
+ const provider = providerNpm ? { npm: providerNpm, ...rest } : rest;
504
+ if (Object.keys(provider ?? {}).length > 0)
505
+ merged.provider = provider;
419
506
  }
420
507
  return merged;
421
508
  }
509
+ function isRecord3(value) {
510
+ return typeof value === "object" && value !== null && !Array.isArray(value);
511
+ }
422
512
  export {
423
513
  CLIProxyAPIPlugin,
424
514
  src_default as default,
@@ -55,6 +55,12 @@ export declare function toV2Models(input: {
55
55
  providerID: string;
56
56
  discovery: CatalogDiscovery;
57
57
  }): V2ModelInfo[];
58
+ /**
59
+ * Overlays the user's configured models on the discovered list. Discovery
60
+ * provides the defaults; a user value wins only where it is a value V2 can
61
+ * use, and a model the user configured alone is preserved verbatim.
62
+ */
63
+ export declare function mergeV2Models(discovered: V2ModelInfo[], userModels?: ReadonlyMap<string, unknown>): V2ModelInfo[];
58
64
  /**
59
65
  * V2 setup. Registers the provider from the discovered catalog and returns a
60
66
  * no-op cleanup (V2 keeps no timers or subscriptions for this plugin).
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-v2.d.ts","sourceRoot":"","sources":["../src/plugin-v2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAS,MAAM,EAAY,MAAM,kBAAkB,CAAA;AAE/D,OAAO,EAgBL,KAAK,gBAAgB,EAEtB,MAAM,aAAa,CAAA;AAEpB,KAAK,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;AAK7B,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAA;QACd,KAAK,EAAE,MAAM,EAAE,CAAA;QACf,MAAM,EAAE,MAAM,EAAE,CAAA;KACjB,CAAA;IACD,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,IAAI,EAAE,KAAK,CAAC;QACV,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KACvC,CAAC,CAAA;IACF,MAAM,EAAE,QAAQ,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAC1C,KAAK,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,gBAAgB,CAAA;CAAE,GACzD,WAAW,CA6Bb;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,gBAAgB,CAAA;CAC5B,GAAG,WAAW,EAAE,CAIhB;AAED;;;GAGG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CA8CtE;AAED,eAAO,MAAM,YAAY;;;CAGxB,CAAA"}
1
+ {"version":3,"file":"plugin-v2.d.ts","sourceRoot":"","sources":["../src/plugin-v2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAS,MAAM,EAAY,MAAM,kBAAkB,CAAA;AAE/D,OAAO,EAqBL,KAAK,gBAAgB,EAEtB,MAAM,aAAa,CAAA;AAEpB,KAAK,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;AAE7B,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAA;QACd,KAAK,EAAE,MAAM,EAAE,CAAA;QACf,MAAM,EAAE,MAAM,EAAE,CAAA;KACjB,CAAA;IACD,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,IAAI,EAAE,KAAK,CAAC;QACV,KAAK,EAAE,MAAM,CAAA;QACb,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KACvC,CAAC,CAAA;IACF,MAAM,EAAE,QAAQ,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;KACf,CAAA;CACF;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAC1C,KAAK,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,gBAAgB,CAAA;CAAE,GACzD,WAAW,CA6Bb;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,gBAAgB,CAAA;CAC5B,GAAG,WAAW,EAAE,CAIhB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,WAAW,EAAE,EACzB,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GACxC,WAAW,EAAE,CAgBf;AAkBD;;;GAGG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CA+CtE;AAED,eAAO,MAAM,YAAY;;;CAGxB,CAAA"}
package/dist/shared.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import type { PluginOptions } from "@opencode-ai/plugin";
2
- import { type CatalogModel, type ModelProtocolCatalog, type ReasoningEffortCatalog } from "./catalog.js";
2
+ import { type CatalogModel, type ModelProtocolCatalog, type ReasoningEffortCatalog, type ReasoningEffortLevels } from "./catalog.js";
3
3
  export declare const DEFAULT_BASE_URL = "http://localhost:8317/v1";
4
4
  export declare const DEFAULT_PROVIDER_ID = "cliproxyapi";
5
5
  export declare const DEFAULT_PROVIDER_NAME = "CLIProxyAPI";
6
6
  export declare const DEFAULT_DISCOVERY_TIMEOUT_MS = 10000;
7
7
  export declare const DEFAULT_MODEL_METADATA_URL = "https://models.dev/api.json";
8
+ export declare const DEFAULT_CONTEXT_LIMIT = 128000;
9
+ export declare const DEFAULT_OUTPUT_LIMIT = 32000;
8
10
  export declare const V1_CHAT_PACKAGE = "@ai-sdk/openai-compatible";
9
11
  export declare const V1_RESPONSES_PACKAGE = "@ai-sdk/openai";
10
12
  export declare const V1_ANTHROPIC_PACKAGE = "@ai-sdk/anthropic";
@@ -28,12 +30,22 @@ export type CatalogDiscovery = {
28
30
  };
29
31
  export declare function readOptions(input?: PluginOptions): ConnectorOptions;
30
32
  export declare function stringOption(value: unknown): string | undefined;
33
+ export declare function resolveModelLimits(model: CatalogModel, effortCatalog: ReasoningEffortCatalog): {
34
+ context: number;
35
+ output: number;
36
+ };
37
+ export declare function isProperString(value: unknown): value is string;
38
+ export declare function isProperBoolean(value: unknown): value is boolean;
39
+ export declare function isProperContextLimit(value: unknown): value is number;
40
+ export declare function isProperOutputLimit(value: unknown): value is number;
41
+ export declare function properLimitOverrides(userLimit: unknown): {
42
+ context?: number;
43
+ output?: number;
44
+ };
45
+ export declare function definedKeys<T extends object>(value: T): Partial<T>;
31
46
  export declare function displayName(modelID: string): string;
32
47
  export declare function isImageModel(modelID: string): boolean;
33
- export declare function isReasoningModel(modelID: string, efforts?: {
34
- levels: string[];
35
- defaultLevel?: string;
36
- }): boolean;
48
+ export declare function isReasoningModel(modelID: string, efforts?: ReasoningEffortLevels): boolean;
37
49
  export declare function supportsAttachments(modelID: string): boolean;
38
50
  export type ModelModalities = {
39
51
  input: Array<"text" | "image">;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@darknesskiller/opencode-cliproxyapi",
4
- "version": "0.3.1",
4
+ "version": "0.4.0",
5
5
  "description": "Fork of opencode-cliproxyapi that discovers CLIProxyAPI models and auto-configures reasoning-effort variants in OpenCode.",
6
6
  "type": "module",
7
7
  "license": "MIT",