decorated-pi 0.1.0 → 0.2.1

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.
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Baidu Qianfan Coding Plan — OAuth/subscription provider with hardcoded models
3
+ *
4
+ * Provider: "qianfan-coding"
5
+ * Base URL: https://qianfan.baidubce.com/v2/coding (OpenAI-compatible)
6
+ * Auth: OAuth/subscription login → prompt for API key
7
+ *
8
+ * All models hardcoded. No dynamic fetching, no config file caching.
9
+ * - No auth → no models in /model (clean UX, via hasConfiguredAuth)
10
+ * - Login → models become available immediately
11
+ * - Startup → models registered unconditionally (hardcoded)
12
+ */
13
+
14
+ import type { ExtensionAPI, ProviderModelConfig } from "@earendil-works/pi-coding-agent";
15
+ import type { OAuthCredentials, OAuthLoginCallbacks } from "@earendil-works/pi-ai";
16
+
17
+ const PROVIDER_ID = "qianfan-coding";
18
+ const PROVIDER_DISPLAY_NAME = "Baidu Qianfan Coding Plan";
19
+ const BASE_URL = "https://qianfan.baidubce.com/v2/coding";
20
+
21
+ // ── Hardcoded models (parameters from models.dev + Baidu docs) ────────────
22
+
23
+ const MODELS: ProviderModelConfig[] = [
24
+ { id: "deepseek-v3.2", name: "DeepSeek V3.2", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 163_840, maxTokens: 65_536, compat: { supportsDeveloperRole: false, supportsReasoningEffort: true } as any },
25
+ { id: "glm-4.7", name: "GLM 4.7", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 202_752, maxTokens: 131_072, compat: { supportsDeveloperRole: false, supportsReasoningEffort: true } as any },
26
+ { id: "glm-5", name: "GLM 5", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 202_752, maxTokens: 131_072, compat: { supportsDeveloperRole: false, supportsReasoningEffort: true } as any },
27
+ { id: "glm-5.1", name: "GLM 5.1", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 202_752, maxTokens: 131_072, compat: { supportsDeveloperRole: false, supportsReasoningEffort: true } as any },
28
+ { id: "kimi-k2.5", name: "Kimi K2.5", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262_144, maxTokens: 262_144, compat: { supportsDeveloperRole: false, supportsReasoningEffort: true } as any },
29
+ { id: "minimax-m2.1", name: "MiniMax M2.1", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 204_800, maxTokens: 131_072, compat: { supportsDeveloperRole: false, supportsReasoningEffort: true } as any },
30
+ { id: "minimax-m2.5", name: "MiniMax M2.5", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 204_800, maxTokens: 131_072, compat: { supportsDeveloperRole: false, supportsReasoningEffort: true } as any },
31
+ { id: "ernie-4.5-turbo-20260402", name: "ERNIE 4.5 Turbo", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128_000, maxTokens: 12_288, compat: { supportsDeveloperRole: false, supportsReasoningEffort: true } as any },
32
+ { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 1_048_576, maxTokens: 1_048_576, compat: { supportsDeveloperRole: false, supportsReasoningEffort: true } as any },
33
+ ];
34
+
35
+ // ── Entry ──────────────────────────────────────────────────────────────────
36
+
37
+ export function setupQianfanCoding(pi: ExtensionAPI) {
38
+ pi.registerProvider(PROVIDER_ID, {
39
+ name: PROVIDER_DISPLAY_NAME,
40
+ baseUrl: BASE_URL,
41
+ api: "openai-completions",
42
+ authHeader: true,
43
+ models: MODELS,
44
+ oauth: {
45
+ name: PROVIDER_DISPLAY_NAME,
46
+
47
+ async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {
48
+ const apiKey = (await callbacks.onPrompt({
49
+ message: "Enter Baidu Qianfan Coding Plan API key:",
50
+ placeholder: "your-api-key",
51
+ })).trim();
52
+
53
+ if (!apiKey) throw new Error("API key cannot be empty.");
54
+
55
+ return {
56
+ refresh: apiKey,
57
+ access: apiKey,
58
+ expires: Date.now() + 1000 * 365.24 * 24 * 3600 * 1000, // ~1000 years
59
+ };
60
+ },
61
+
62
+ refreshToken(cred: OAuthCredentials): Promise<OAuthCredentials> {
63
+ return Promise.resolve(cred); // API key never expires
64
+ },
65
+
66
+ getApiKey(cred: OAuthCredentials): string {
67
+ return cred.access;
68
+ },
69
+ },
70
+ });
71
+ }