pi-free 2.0.1 → 2.0.4
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 +179 -3
- package/README.md +495 -393
- package/config.ts +46 -54
- package/constants.ts +6 -0
- package/index.ts +39 -12
- package/lib/built-in-toggle.ts +63 -43
- package/lib/model-enhancer.ts +20 -20
- package/lib/open-browser.ts +1 -1
- package/lib/provider-compat.ts +46 -0
- package/lib/registry.ts +193 -144
- package/lib/toggle-state.ts +86 -0
- package/lib/types.ts +101 -108
- package/package.json +8 -8
- package/provider-failover/benchmark-lookup.ts +637 -247
- package/provider-helper.ts +279 -260
- package/providers/cline/cline-auth.ts +473 -473
- package/providers/cline/cline-models.ts +129 -128
- package/providers/cline/cline.ts +311 -298
- package/providers/crofai/crofai.ts +170 -0
- package/providers/dynamic-built-in/index.ts +259 -308
- package/providers/kilo/kilo-auth.ts +155 -155
- package/providers/kilo/kilo-models.ts +2 -1
- package/providers/kilo/kilo.ts +263 -235
- package/providers/nvidia/nvidia.ts +476 -152
- package/providers/ollama/ollama.ts +130 -7
- package/providers/opencode-session.ts +3 -4
- package/providers/qwen/qwen-models.ts +101 -101
- package/providers/zenmux/zenmux.ts +176 -0
- package/scripts/check-extensions.mjs +64 -55
- package/provider-factory.ts +0 -207
- package/providers/cloudflare/cloudflare.ts +0 -368
- package/providers/modal/modal.ts +0 -44
package/lib/registry.ts
CHANGED
|
@@ -1,144 +1,193 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Global Provider Registry for pi-free.
|
|
3
|
-
*
|
|
4
|
-
* Decoupled from index.ts so providers can import toggle logic
|
|
5
|
-
* without creating a circular dependency.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type {
|
|
9
|
-
ExtensionAPI,
|
|
10
|
-
ProviderModelConfig,
|
|
11
|
-
} from "@mariozechner/pi-coding-agent";
|
|
12
|
-
import { getFreeOnly, saveConfig } from "../config.ts";
|
|
13
|
-
import { createLogger } from "./logger.ts";
|
|
14
|
-
|
|
15
|
-
const _logger = createLogger("pi-free");
|
|
16
|
-
|
|
17
|
-
// =============================================================================
|
|
18
|
-
// Types
|
|
19
|
-
// =============================================================================
|
|
20
|
-
|
|
21
|
-
interface ProviderEntry {
|
|
22
|
-
id: string;
|
|
23
|
-
stored: { free: ProviderModelConfig[]; all: ProviderModelConfig[] };
|
|
24
|
-
reRegister: (models: ProviderModelConfig[]) => void;
|
|
25
|
-
hasKey: boolean;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// =============================================================================
|
|
29
|
-
// State
|
|
30
|
-
// =============================================================================
|
|
31
|
-
|
|
32
|
-
const providerRegistry = new Map<string, ProviderEntry>();
|
|
33
|
-
let globalFreeOnly = getFreeOnly();
|
|
34
|
-
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Global Provider Registry for pi-free.
|
|
3
|
+
*
|
|
4
|
+
* Decoupled from index.ts so providers can import toggle logic
|
|
5
|
+
* without creating a circular dependency.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
ExtensionAPI,
|
|
10
|
+
ProviderModelConfig,
|
|
11
|
+
} from "@mariozechner/pi-coding-agent";
|
|
12
|
+
import { getFreeOnly, saveConfig } from "../config.ts";
|
|
13
|
+
import { createLogger } from "./logger.ts";
|
|
14
|
+
|
|
15
|
+
const _logger = createLogger("pi-free");
|
|
16
|
+
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// Types
|
|
19
|
+
// =============================================================================
|
|
20
|
+
|
|
21
|
+
interface ProviderEntry {
|
|
22
|
+
id: string;
|
|
23
|
+
stored: { free: ProviderModelConfig[]; all: ProviderModelConfig[] };
|
|
24
|
+
reRegister: (models: ProviderModelConfig[]) => void;
|
|
25
|
+
hasKey: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// State
|
|
30
|
+
// =============================================================================
|
|
31
|
+
|
|
32
|
+
const providerRegistry = new Map<string, ProviderEntry>();
|
|
33
|
+
let globalFreeOnly = getFreeOnly();
|
|
34
|
+
|
|
35
|
+
// =============================================================================
|
|
36
|
+
// Free-model detection
|
|
37
|
+
// =============================================================================
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Detect if a provider exposes actual per-model pricing.
|
|
41
|
+
*
|
|
42
|
+
* Heuristic: If ALL models have cost === 0, the provider likely doesn't expose
|
|
43
|
+
* real pricing (cost was defaulted to 0). If SOME models have cost > 0, the
|
|
44
|
+
* provider definitely exposes pricing.
|
|
45
|
+
*
|
|
46
|
+
* @param allModels - All models from the provider to check
|
|
47
|
+
* @returns true if pricing appears to be exposed (some costs > 0)
|
|
48
|
+
*/
|
|
49
|
+
function detectPricingExposed(allModels: ProviderModelConfig[]): boolean {
|
|
50
|
+
if (allModels.length === 0) return false;
|
|
51
|
+
|
|
52
|
+
// If ANY model has cost > 0, pricing is definitely exposed
|
|
53
|
+
return allModels.some(
|
|
54
|
+
(m) => (m.cost?.input ?? 0) > 0 || (m.cost?.output ?? 0) > 0,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Check if a model is free using adaptive Route A/B logic.
|
|
60
|
+
*
|
|
61
|
+
* **Automatic Detection:**
|
|
62
|
+
* The function detects whether the provider exposes pricing by checking if
|
|
63
|
+
* ALL models have cost === 0. If so, it assumes no pricing is exposed and
|
|
64
|
+
* falls back to name-based detection.
|
|
65
|
+
*
|
|
66
|
+
* **Route A (Pricing-Exposed Providers):** Uses ONLY cost-based detection.
|
|
67
|
+
* - Detected when SOME models have cost > 0
|
|
68
|
+
* - Free = cost.input === 0 && cost.output === 0
|
|
69
|
+
* - No fallback to name-based detection
|
|
70
|
+
*
|
|
71
|
+
* **Route B (Non-Pricing-Exposed Providers):** Uses ONLY name-based detection.
|
|
72
|
+
* - Detected when ALL models have cost === 0 (or no models)
|
|
73
|
+
* - Free = model name contains "free" (case-insensitive)
|
|
74
|
+
* - No cost-based detection (avoids marking freemium as free)
|
|
75
|
+
*
|
|
76
|
+
* This automatic detection handles providers without hardcoding - if a provider
|
|
77
|
+
* shows all models as zero cost, we assume pricing isn't exposed and check
|
|
78
|
+
* model names instead.
|
|
79
|
+
*
|
|
80
|
+
* @param model - The model config to check
|
|
81
|
+
* @param allModels - Optional: all models from the same provider for detection
|
|
82
|
+
* @returns true if the model is definitively free per the provider's API
|
|
83
|
+
*/
|
|
84
|
+
export function isFreeModel(
|
|
85
|
+
model: ProviderModelConfig & { provider?: string },
|
|
86
|
+
allModels?: ProviderModelConfig[],
|
|
87
|
+
): boolean {
|
|
88
|
+
return isFreeModelInternal(model, allModels);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Internal implementation to work around TypeScript filter callback issues
|
|
92
|
+
function isFreeModelInternal(
|
|
93
|
+
model: ProviderModelConfig & { provider?: string },
|
|
94
|
+
allModels: ProviderModelConfig[] | undefined,
|
|
95
|
+
): boolean {
|
|
96
|
+
// Determine if pricing is exposed
|
|
97
|
+
let pricingExposed: boolean;
|
|
98
|
+
|
|
99
|
+
if (allModels && allModels.length > 0) {
|
|
100
|
+
// Dynamic detection: check if ALL models have cost === 0
|
|
101
|
+
// If all costs are 0, assume pricing is NOT actually exposed
|
|
102
|
+
pricingExposed = detectPricingExposed(allModels);
|
|
103
|
+
} else {
|
|
104
|
+
// No allModels provided - default to cost-based detection
|
|
105
|
+
// This maintains backward compatibility
|
|
106
|
+
pricingExposed = true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Route A: Pricing-exposed providers - use OR logic
|
|
110
|
+
// Model is free if EITHER cost is zero OR name contains "free"
|
|
111
|
+
if (pricingExposed) {
|
|
112
|
+
const isZeroCost =
|
|
113
|
+
(model.cost?.input ?? 0) === 0 && (model.cost?.output ?? 0) === 0;
|
|
114
|
+
const hasFreeInName = model.name.toLowerCase().includes("free");
|
|
115
|
+
return isZeroCost || hasFreeInName;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Route B: Non-pricing-exposed providers - use ONLY name-based detection
|
|
119
|
+
// This handles providers where all costs are defaulted to 0
|
|
120
|
+
return model.name.toLowerCase().includes("free");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// =============================================================================
|
|
124
|
+
// Registration
|
|
125
|
+
// =============================================================================
|
|
126
|
+
|
|
127
|
+
/** Register a provider with the global free/paid toggle system */
|
|
128
|
+
export function registerWithGlobalToggle(
|
|
129
|
+
providerId: string,
|
|
130
|
+
stored: { free: ProviderModelConfig[]; all: ProviderModelConfig[] },
|
|
131
|
+
reRegister: (models: ProviderModelConfig[]) => void,
|
|
132
|
+
hasKey: boolean = false,
|
|
133
|
+
): void {
|
|
134
|
+
providerRegistry.set(providerId, {
|
|
135
|
+
id: providerId,
|
|
136
|
+
stored,
|
|
137
|
+
reRegister,
|
|
138
|
+
hasKey,
|
|
139
|
+
});
|
|
140
|
+
_logger.info(
|
|
141
|
+
`[pi-free] Registered ${providerId} with global toggle (${stored.free.length} free, ${stored.all.length} total)`,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Get current global free-only state */
|
|
146
|
+
export function getGlobalFreeOnly(): boolean {
|
|
147
|
+
return globalFreeOnly;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Access the raw registry (used by /free-providers command) */
|
|
151
|
+
export function getProviderRegistry(): ReadonlyMap<string, ProviderEntry> {
|
|
152
|
+
return providerRegistry;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// =============================================================================
|
|
156
|
+
// Global filter application
|
|
157
|
+
// =============================================================================
|
|
158
|
+
|
|
159
|
+
export function applyGlobalFilter(_pi: ExtensionAPI, freeOnly: boolean): void {
|
|
160
|
+
globalFreeOnly = freeOnly;
|
|
161
|
+
saveConfig({ free_only: freeOnly });
|
|
162
|
+
|
|
163
|
+
for (const [providerId, entry] of providerRegistry) {
|
|
164
|
+
try {
|
|
165
|
+
if (freeOnly) {
|
|
166
|
+
// Show only free models
|
|
167
|
+
if (entry.stored.free.length > 0) {
|
|
168
|
+
entry.reRegister(entry.stored.free);
|
|
169
|
+
_logger.info(
|
|
170
|
+
`[pi-free] ${providerId}: filtered to ${entry.stored.free.length} free models`,
|
|
171
|
+
);
|
|
172
|
+
} else {
|
|
173
|
+
_logger.warn(`[pi-free] ${providerId}: no free models available`);
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
// Show all models (paid + free)
|
|
177
|
+
const allModels =
|
|
178
|
+
entry.stored.all.length > 0 ? entry.stored.all : entry.stored.free;
|
|
179
|
+
if (allModels.length > 0) {
|
|
180
|
+
entry.reRegister(allModels);
|
|
181
|
+
_logger.info(
|
|
182
|
+
`[pi-free] ${providerId}: showing all ${allModels.length} models`,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
} catch (err) {
|
|
187
|
+
_logger.error(
|
|
188
|
+
`[pi-free] Failed to apply filter to ${providerId}`,
|
|
189
|
+
err instanceof Error ? { error: err.message } : { error: String(err) },
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { saveConfig } from "../config.ts";
|
|
2
|
+
|
|
3
|
+
export type ToggleMode = "free" | "all";
|
|
4
|
+
|
|
5
|
+
export interface ToggleModelStore<T> {
|
|
6
|
+
free: T[];
|
|
7
|
+
all: T[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface CreateToggleStateOptions<T> {
|
|
11
|
+
providerId: string;
|
|
12
|
+
initialShowPaid: boolean;
|
|
13
|
+
save?: typeof saveConfig;
|
|
14
|
+
initialModels?: ToggleModelStore<T>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ToggleResult<T> {
|
|
18
|
+
mode: ToggleMode;
|
|
19
|
+
models: T[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function createToggleState<T>({
|
|
23
|
+
providerId,
|
|
24
|
+
initialShowPaid,
|
|
25
|
+
save = saveConfig,
|
|
26
|
+
initialModels,
|
|
27
|
+
}: CreateToggleStateOptions<T>) {
|
|
28
|
+
let stored: ToggleModelStore<T> = initialModels ?? { free: [], all: [] };
|
|
29
|
+
let currentMode: ToggleMode = initialShowPaid ? "all" : "free";
|
|
30
|
+
|
|
31
|
+
function resolveMode(mode: ToggleMode): ToggleResult<T> {
|
|
32
|
+
if (mode === "all") {
|
|
33
|
+
if (stored.all.length > 0) {
|
|
34
|
+
return { mode: "all", models: stored.all };
|
|
35
|
+
}
|
|
36
|
+
return { mode: "free", models: stored.free };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (stored.free.length > 0) {
|
|
40
|
+
return { mode: "free", models: stored.free };
|
|
41
|
+
}
|
|
42
|
+
return { mode: "all", models: stored.all };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function persist(mode: ToggleMode): void {
|
|
46
|
+
save({ [`${providerId}_show_paid`]: mode === "all" });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function applyMode(
|
|
50
|
+
mode: ToggleMode,
|
|
51
|
+
apply?: (models: T[]) => void,
|
|
52
|
+
): ToggleResult<T> {
|
|
53
|
+
const resolved = resolveMode(mode);
|
|
54
|
+
currentMode = resolved.mode;
|
|
55
|
+
if (apply) apply(resolved.models);
|
|
56
|
+
return resolved;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
setModels(next: ToggleModelStore<T>): ToggleModelStore<T> {
|
|
61
|
+
stored = next;
|
|
62
|
+
const resolved = resolveMode(currentMode);
|
|
63
|
+
currentMode = resolved.mode;
|
|
64
|
+
return stored;
|
|
65
|
+
},
|
|
66
|
+
getStored(): ToggleModelStore<T> {
|
|
67
|
+
return stored;
|
|
68
|
+
},
|
|
69
|
+
getCurrentMode(): ToggleMode {
|
|
70
|
+
return currentMode;
|
|
71
|
+
},
|
|
72
|
+
getCurrentModels(): T[] {
|
|
73
|
+
return resolveMode(currentMode).models;
|
|
74
|
+
},
|
|
75
|
+
applyCurrent(apply?: (models: T[]) => void): ToggleResult<T> {
|
|
76
|
+
return applyMode(currentMode, apply);
|
|
77
|
+
},
|
|
78
|
+
applyMode,
|
|
79
|
+
toggle(apply?: (models: T[]) => void): ToggleResult<T> {
|
|
80
|
+
const nextMode = currentMode === "all" ? "free" : "all";
|
|
81
|
+
const resolved = applyMode(nextMode, apply);
|
|
82
|
+
persist(resolved.mode);
|
|
83
|
+
return resolved;
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
package/lib/types.ts
CHANGED
|
@@ -1,108 +1,101 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared types for pi-free-providers.
|
|
3
|
-
* Interfaces duplicated across providers consolidated here.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// =============================================================================
|
|
7
|
-
// Provider model configuration (matches Pi's ProviderModelConfig)
|
|
8
|
-
// =============================================================================
|
|
9
|
-
|
|
10
|
-
export interface CostConfig {
|
|
11
|
-
input: number;
|
|
12
|
-
output: number;
|
|
13
|
-
cacheRead: number;
|
|
14
|
-
cacheWrite: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface ProviderModelConfig {
|
|
18
|
-
id: string;
|
|
19
|
-
name: string;
|
|
20
|
-
reasoning: boolean;
|
|
21
|
-
input: ("text" | "image")[];
|
|
22
|
-
cost: CostConfig;
|
|
23
|
-
contextWindow: number;
|
|
24
|
-
maxTokens: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// =============================================================================
|
|
28
|
-
// models.dev schema types
|
|
29
|
-
// =============================================================================
|
|
30
|
-
|
|
31
|
-
export interface ModelsDevCost {
|
|
32
|
-
input: number;
|
|
33
|
-
output: number;
|
|
34
|
-
cache_read?: number;
|
|
35
|
-
cache_write?: number;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface ModelsDevLimit {
|
|
39
|
-
context: number;
|
|
40
|
-
output: number;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface ModelsDevModalities {
|
|
44
|
-
input?: string[];
|
|
45
|
-
output?: string[];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface ModelsDevModel {
|
|
49
|
-
id: string;
|
|
50
|
-
name: string;
|
|
51
|
-
reasoning: boolean;
|
|
52
|
-
cost?: ModelsDevCost;
|
|
53
|
-
limit: ModelsDevLimit;
|
|
54
|
-
modalities?: ModelsDevModalities;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface ModelsDevProvider {
|
|
58
|
-
id: string;
|
|
59
|
-
api: string;
|
|
60
|
-
models: Record<string, ModelsDevModel>;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// =============================================================================
|
|
64
|
-
// OpenRouter API response types
|
|
65
|
-
// =============================================================================
|
|
66
|
-
|
|
67
|
-
export interface OpenRouterPricing {
|
|
68
|
-
prompt?: string | null;
|
|
69
|
-
completion?: string | null;
|
|
70
|
-
input_cache_write?: string | null;
|
|
71
|
-
input_cache_read?: string | null;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export interface OpenRouterArchitecture {
|
|
75
|
-
input_modalities?: string[] | null;
|
|
76
|
-
output_modalities?: string[] | null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface OpenRouterTopProvider {
|
|
80
|
-
max_completion_tokens?: number | null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export interface OpenRouterModel {
|
|
84
|
-
id: string;
|
|
85
|
-
name: string;
|
|
86
|
-
context_length: number;
|
|
87
|
-
max_completion_tokens?: number | null;
|
|
88
|
-
pricing?: OpenRouterPricing;
|
|
89
|
-
architecture?: OpenRouterArchitecture;
|
|
90
|
-
top_provider?: OpenRouterTopProvider;
|
|
91
|
-
supported_parameters?: string[];
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// =============================================================================
|
|
95
|
-
// Zen gateway types
|
|
96
|
-
// =============================================================================
|
|
97
|
-
|
|
98
|
-
export interface ZenGatewayModel {
|
|
99
|
-
id: string;
|
|
100
|
-
object?: string;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Test: LSP should handle new interface
|
|
104
|
-
export interface LspTestInterface {
|
|
105
|
-
name: string;
|
|
106
|
-
value: number;
|
|
107
|
-
enabled: boolean;
|
|
108
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for pi-free-providers.
|
|
3
|
+
* Interfaces duplicated across providers consolidated here.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// =============================================================================
|
|
7
|
+
// Provider model configuration (matches Pi's ProviderModelConfig)
|
|
8
|
+
// =============================================================================
|
|
9
|
+
|
|
10
|
+
export interface CostConfig {
|
|
11
|
+
input: number;
|
|
12
|
+
output: number;
|
|
13
|
+
cacheRead: number;
|
|
14
|
+
cacheWrite: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ProviderModelConfig {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
reasoning: boolean;
|
|
21
|
+
input: ("text" | "image")[];
|
|
22
|
+
cost: CostConfig;
|
|
23
|
+
contextWindow: number;
|
|
24
|
+
maxTokens: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// models.dev schema types
|
|
29
|
+
// =============================================================================
|
|
30
|
+
|
|
31
|
+
export interface ModelsDevCost {
|
|
32
|
+
input: number;
|
|
33
|
+
output: number;
|
|
34
|
+
cache_read?: number;
|
|
35
|
+
cache_write?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ModelsDevLimit {
|
|
39
|
+
context: number;
|
|
40
|
+
output: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ModelsDevModalities {
|
|
44
|
+
input?: string[];
|
|
45
|
+
output?: string[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface ModelsDevModel {
|
|
49
|
+
id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
reasoning: boolean;
|
|
52
|
+
cost?: ModelsDevCost;
|
|
53
|
+
limit: ModelsDevLimit;
|
|
54
|
+
modalities?: ModelsDevModalities;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface ModelsDevProvider {
|
|
58
|
+
id: string;
|
|
59
|
+
api: string;
|
|
60
|
+
models: Record<string, ModelsDevModel>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// =============================================================================
|
|
64
|
+
// OpenRouter API response types
|
|
65
|
+
// =============================================================================
|
|
66
|
+
|
|
67
|
+
export interface OpenRouterPricing {
|
|
68
|
+
prompt?: string | null;
|
|
69
|
+
completion?: string | null;
|
|
70
|
+
input_cache_write?: string | null;
|
|
71
|
+
input_cache_read?: string | null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface OpenRouterArchitecture {
|
|
75
|
+
input_modalities?: string[] | null;
|
|
76
|
+
output_modalities?: string[] | null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface OpenRouterTopProvider {
|
|
80
|
+
max_completion_tokens?: number | null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface OpenRouterModel {
|
|
84
|
+
id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
context_length: number;
|
|
87
|
+
max_completion_tokens?: number | null;
|
|
88
|
+
pricing?: OpenRouterPricing;
|
|
89
|
+
architecture?: OpenRouterArchitecture;
|
|
90
|
+
top_provider?: OpenRouterTopProvider;
|
|
91
|
+
supported_parameters?: string[];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// =============================================================================
|
|
95
|
+
// Zen gateway types
|
|
96
|
+
// =============================================================================
|
|
97
|
+
|
|
98
|
+
export interface ZenGatewayModel {
|
|
99
|
+
id: string;
|
|
100
|
+
object?: string;
|
|
101
|
+
}
|