@agnishc/edb-custom-provider 0.14.3

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/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@agnishc/edb-custom-provider",
3
+ "version": "0.14.3",
4
+ "description": "Custom model providers for pi",
5
+ "keywords": [
6
+ "pi-package",
7
+ "pi-extension",
8
+ "edb"
9
+ ],
10
+ "type": "module",
11
+ "license": "MIT",
12
+ "author": "Agnish Chakraborty",
13
+ "scripts": {
14
+ "test": "vitest run"
15
+ },
16
+ "files": [
17
+ "src",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "pi": {
22
+ "extensions": [
23
+ "./src/index.ts"
24
+ ]
25
+ },
26
+ "peerDependencies": {
27
+ "@earendil-works/pi-coding-agent": "*",
28
+ "@earendil-works/pi-ai": "*"
29
+ }
30
+ }
package/src/index.ts ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * pi-custom-provider
3
+ *
4
+ * Registers custom model providers for pi.
5
+ * Each provider is a separate file in this directory.
6
+ */
7
+
8
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
9
+
10
+ import { registerCrofAiProvider } from "./providers/crofai";
11
+
12
+ export default function customProviderExtension(pi: ExtensionAPI): void {
13
+ registerCrofAiProvider(pi);
14
+ }
@@ -0,0 +1,260 @@
1
+ /**
2
+ * CrofAI Provider for pi
3
+ *
4
+ * API: OpenAI-compatible Chat Completions
5
+ * Base URL: https://crof.ai/v1
6
+ * Auth: API key via Bearer token
7
+ *
8
+ * Models sourced from GET https://crof.ai/v1/models (June 2025)
9
+ * Usage data is fetched separately by edb-usage-stats.
10
+ */
11
+
12
+ import type { ExtensionAPI, ProviderModelConfig } from "@earendil-works/pi-coding-agent";
13
+
14
+ // ── Provider Config ───────────────────────────────────────────────────────────
15
+
16
+ const PROVIDER = "crofai";
17
+ const BASE_URL = "https://crof.ai/v1";
18
+
19
+ // ── Models ─────────────────────────────────────────────────────────────────────
20
+ // Cost is in $/million tokens as per pi convention
21
+
22
+ const MODELS: ProviderModelConfig[] = [
23
+ {
24
+ id: "deepseek-v4-pro",
25
+ name: "DeepSeek: DeepSeek V4 Pro",
26
+ reasoning: true,
27
+ input: ["text"],
28
+ cost: { input: 0.3, output: 0.5, cacheRead: 0.003, cacheWrite: 0 },
29
+ contextWindow: 1_000_000,
30
+ maxTokens: 131_072,
31
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
32
+ },
33
+ {
34
+ id: "deepseek-v4-pro-precision",
35
+ name: "DeepSeek: DeepSeek V4 Pro (Precision)",
36
+ reasoning: true,
37
+ input: ["text"],
38
+ cost: { input: 0.7, output: 1.4, cacheRead: 0.006, cacheWrite: 0 },
39
+ contextWindow: 1_000_000,
40
+ maxTokens: 131_072,
41
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
42
+ },
43
+ {
44
+ id: "deepseek-v4-pro-lightning",
45
+ name: "DeepSeek: DeepSeek V4 Pro (Lightning)",
46
+ reasoning: true,
47
+ input: ["text"],
48
+ cost: { input: 1.7, output: 3.4, cacheRead: 0.1, cacheWrite: 0 },
49
+ contextWindow: 1_000_000,
50
+ maxTokens: 131_072,
51
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
52
+ },
53
+ {
54
+ id: "deepseek-v4-flash",
55
+ name: "DeepSeek: DeepSeek V4 Flash",
56
+ reasoning: true,
57
+ input: ["text"],
58
+ cost: { input: 0.12, output: 0.21, cacheRead: 0.003, cacheWrite: 0 },
59
+ contextWindow: 1_000_000,
60
+ maxTokens: 131_072,
61
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
62
+ },
63
+ {
64
+ id: "deepseek-v3.2",
65
+ name: "DeepSeek: DeepSeek V3.2",
66
+ reasoning: false,
67
+ input: ["text"],
68
+ cost: { input: 0.28, output: 0.38, cacheRead: 0.06, cacheWrite: 0 },
69
+ contextWindow: 163_840,
70
+ maxTokens: 163_840,
71
+ compat: { supportsDeveloperRole: true },
72
+ },
73
+ {
74
+ id: "mimo-v2.5-pro",
75
+ name: "Xiaomi: MiMo-V2.5-Pro",
76
+ reasoning: true,
77
+ input: ["text"],
78
+ cost: { input: 0.5, output: 1.5, cacheRead: 0.1, cacheWrite: 0 },
79
+ contextWindow: 1_000_000,
80
+ maxTokens: 131_072,
81
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
82
+ },
83
+ {
84
+ id: "mimo-v2.5-pro-precision",
85
+ name: "Xiaomi: MiMo-V2.5-Pro (Precision)",
86
+ reasoning: true,
87
+ input: ["text"],
88
+ cost: { input: 0.8, output: 2.5, cacheRead: 0.16, cacheWrite: 0 },
89
+ contextWindow: 1_000_000,
90
+ maxTokens: 131_072,
91
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
92
+ },
93
+ {
94
+ id: "glm-5.1",
95
+ name: "Z.ai: GLM 5.1",
96
+ reasoning: true,
97
+ input: ["text"],
98
+ cost: { input: 0.45, output: 2.1, cacheRead: 0.09, cacheWrite: 0 },
99
+ contextWindow: 202_752,
100
+ maxTokens: 202_752,
101
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
102
+ },
103
+ {
104
+ id: "glm-5.1-precision",
105
+ name: "Z.ai: GLM 5.1 (Precision)",
106
+ reasoning: true,
107
+ input: ["text"],
108
+ cost: { input: 0.75, output: 2.9, cacheRead: 0.15, cacheWrite: 0 },
109
+ contextWindow: 202_752,
110
+ maxTokens: 202_752,
111
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
112
+ },
113
+ {
114
+ id: "glm-5",
115
+ name: "Z.ai: GLM 5",
116
+ reasoning: false,
117
+ input: ["text"],
118
+ cost: { input: 0.48, output: 1.9, cacheRead: 0.1, cacheWrite: 0 },
119
+ contextWindow: 202_752,
120
+ maxTokens: 202_752,
121
+ compat: { supportsDeveloperRole: true },
122
+ },
123
+ {
124
+ id: "glm-4.7",
125
+ name: "Z.AI: GLM 4.7",
126
+ reasoning: false,
127
+ input: ["text"],
128
+ cost: { input: 0.25, output: 1.1, cacheRead: 0.05, cacheWrite: 0 },
129
+ contextWindow: 202_752,
130
+ maxTokens: 202_752,
131
+ compat: { supportsDeveloperRole: true },
132
+ },
133
+ {
134
+ id: "glm-4.7-flash",
135
+ name: "Z.AI: GLM 4.7 Flash",
136
+ reasoning: false,
137
+ input: ["text"],
138
+ cost: { input: 0.04, output: 0.3, cacheRead: 0.008, cacheWrite: 0 },
139
+ contextWindow: 202_752,
140
+ maxTokens: 131_072,
141
+ compat: { supportsDeveloperRole: true },
142
+ },
143
+ {
144
+ id: "kimi-k2.6",
145
+ name: "MoonshotAI: Kimi K2.6",
146
+ reasoning: true,
147
+ input: ["text"],
148
+ cost: { input: 0.5, output: 1.99, cacheRead: 0.1, cacheWrite: 0 },
149
+ contextWindow: 262_144,
150
+ maxTokens: 262_144,
151
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
152
+ },
153
+ {
154
+ id: "kimi-k2.6-precision",
155
+ name: "MoonshotAI: Kimi K2.6 (Precision)",
156
+ reasoning: true,
157
+ input: ["text"],
158
+ cost: { input: 0.55, output: 2.7, cacheRead: 0.11, cacheWrite: 0 },
159
+ contextWindow: 262_144,
160
+ maxTokens: 262_144,
161
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
162
+ },
163
+ {
164
+ id: "kimi-k2.5",
165
+ name: "MoonshotAI: Kimi K2.5",
166
+ reasoning: true,
167
+ input: ["text", "image"],
168
+ cost: { input: 0.35, output: 1.7, cacheRead: 0.07, cacheWrite: 0 },
169
+ contextWindow: 262_144,
170
+ maxTokens: 262_144,
171
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
172
+ },
173
+ {
174
+ id: "kimi-k2.5-lightning",
175
+ name: "MoonshotAI: Kimi K2.5 (Lightning)",
176
+ reasoning: true,
177
+ input: ["text"],
178
+ cost: { input: 1.0, output: 3.0, cacheRead: 0.2, cacheWrite: 0 },
179
+ contextWindow: 131_072,
180
+ maxTokens: 32_768,
181
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
182
+ },
183
+ {
184
+ id: "gemma-4-31b-it",
185
+ name: "Google: Gemma 4 31B",
186
+ reasoning: true,
187
+ input: ["text"],
188
+ cost: { input: 0.1, output: 0.3, cacheRead: 0.02, cacheWrite: 0 },
189
+ contextWindow: 262_144,
190
+ maxTokens: 262_144,
191
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
192
+ },
193
+ {
194
+ id: "minimax-m2.5",
195
+ name: "MiniMax: MiniMax M2.5",
196
+ reasoning: false,
197
+ input: ["text"],
198
+ cost: { input: 0.11, output: 0.95, cacheRead: 0.02, cacheWrite: 0 },
199
+ contextWindow: 204_800,
200
+ maxTokens: 131_072,
201
+ compat: { supportsDeveloperRole: true },
202
+ },
203
+ {
204
+ id: "qwen3.6-27b",
205
+ name: "Qwen: Qwen3.6 27B",
206
+ reasoning: true,
207
+ input: ["text"],
208
+ cost: { input: 0.2, output: 1.5, cacheRead: 0.04, cacheWrite: 0 },
209
+ contextWindow: 262_144,
210
+ maxTokens: 262_144,
211
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
212
+ },
213
+ {
214
+ id: "qwen3.5-397b-a17b",
215
+ name: "Qwen: Qwen3.5 397B A17B",
216
+ reasoning: true,
217
+ input: ["text"],
218
+ cost: { input: 0.35, output: 1.75, cacheRead: 0.07, cacheWrite: 0 },
219
+ contextWindow: 262_144,
220
+ maxTokens: 262_144,
221
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
222
+ },
223
+ {
224
+ id: "qwen3.5-9b",
225
+ name: "Qwen: Qwen3.5 9B",
226
+ reasoning: true,
227
+ input: ["text"],
228
+ cost: { input: 0.04, output: 0.15, cacheRead: 0.008, cacheWrite: 0 },
229
+ contextWindow: 262_144,
230
+ maxTokens: 262_144,
231
+ compat: { supportsReasoningEffort: true, supportsDeveloperRole: true },
232
+ },
233
+ ];
234
+
235
+ // ── Provider Registration ─────────────────────────────────────────────────────
236
+
237
+ export function registerCrofAiProvider(pi: ExtensionAPI): void {
238
+ pi.registerProvider(PROVIDER, {
239
+ name: "CrofAi",
240
+ baseUrl: BASE_URL,
241
+ apiKey: "CROFAI_API_KEY",
242
+ api: "openai-completions",
243
+ authHeader: true,
244
+ models: MODELS,
245
+ oauth: {
246
+ name: "CrofAi",
247
+ async login(cb) {
248
+ cb.onAuth({ url: "https://crof.ai/signin" });
249
+ const key = (await cb.onPrompt({ message: "Paste your CrofAi API key:" })).trim();
250
+ if (!key) throw new Error("No CrofAi API key provided");
251
+ // CrofAi keys are long-lived
252
+ return { access: key, refresh: key, expires: Date.now() + 20 * 365 * 86_400_000 };
253
+ },
254
+ async refreshToken(c) {
255
+ return c;
256
+ },
257
+ getApiKey: (c) => c.access,
258
+ },
259
+ });
260
+ }