pi-bailian 1.0.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.
Files changed (3) hide show
  1. package/README.md +50 -0
  2. package/index.ts +170 -0
  3. package/package.json +25 -0
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # pi-bailian
2
+
3
+ Alibaba Bailian (ModelStudio) provider for [pi.dev](https://pi.dev) — routes Qwen3 / GLM-4 / Kimi models through the Anthropic-compatible coding endpoint.
4
+
5
+ ## Models
6
+
7
+ | ID | Name | Context | Output | Thinking |
8
+ |---|---|---|---|---|
9
+ | `qwen3.5-plus` | Qwen 3.5 Plus | 960K | 64K | ✅ |
10
+ | `qwen3-max-2026-01-23` | Qwen3 Max (2026-01-23) | 252K | 32K | ✅ |
11
+ | `qwen3-coder-plus` | Qwen3 Coder Plus | 975K | 64K | ❌ |
12
+ | `qwen3-coder-next` | Qwen3 Coder Next | 200K | 64K | ❌ |
13
+ | `glm-4.7` | GLM-4.7 | 166K | 16K | ✅ |
14
+ | `kimi-k2.5` | Kimi K2.5 | 252K | 32K | ✅ |
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ # Install from local path
20
+ pi install ./pi-bailian
21
+
22
+ # Or test without installing
23
+ pi -e ./pi-bailian
24
+ ```
25
+
26
+ ## Configuration
27
+
28
+ ### Interactive setup (recommended)
29
+
30
+ After installing, run the configure command inside pi:
31
+
32
+ ```
33
+ /bailian-configure
34
+ ```
35
+
36
+ It will prompt you for your API key and save it to `~/.pi/agent/bailian.json`. The key is applied immediately — no restart needed.
37
+
38
+ ### Environment variable
39
+
40
+ Set `BAILIAN_API_KEY` in your environment (takes precedence over the saved config):
41
+
42
+ ```bash
43
+ export BAILIAN_API_KEY=sk-sp-...
44
+ ```
45
+
46
+ Get your API key from the [Model Studio console](https://modelstudio.console.alibabacloud.com).
47
+
48
+ ## Usage
49
+
50
+ After installing, use `/model` or `Ctrl+L` in pi to select a `bailian/...` model. Use `Ctrl+T` to toggle thinking for models that support it.
package/index.ts ADDED
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Alibaba Bailian (ModelStudio) provider for pi.dev
3
+ *
4
+ * Registers the Bailian Anthropic-compatible coding endpoint with all
5
+ * configured Qwen3 / GLM-4 / Kimi models.
6
+ *
7
+ * Usage:
8
+ * # Install from local path
9
+ * pi install ./pi-bailian
10
+ *
11
+ * # Or test in-place without installing
12
+ * pi -e ./pi-bailian
13
+ *
14
+ * # Configure your API key interactively
15
+ * /bailian-configure
16
+ *
17
+ * # Or set via environment variable (takes precedence over saved config)
18
+ * BAILIAN_API_KEY=sk-sp-... pi
19
+ *
20
+ * # Then switch models with /model or Ctrl+L
21
+ * # Look for "bailian/..." entries
22
+ */
23
+
24
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
25
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
26
+ import { homedir } from "node:os";
27
+ import { join } from "node:path";
28
+
29
+ const CONFIG_FILE = join(homedir(), ".pi", "agent", "bailian.json");
30
+
31
+ function readStoredKey(): string | undefined {
32
+ try {
33
+ if (existsSync(CONFIG_FILE)) {
34
+ const data = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
35
+ return typeof data.apiKey === "string" ? data.apiKey : undefined;
36
+ }
37
+ } catch {
38
+ // ignore malformed config
39
+ }
40
+ return undefined;
41
+ }
42
+
43
+ function saveKey(apiKey: string): void {
44
+ const dir = join(homedir(), ".pi", "agent");
45
+ mkdirSync(dir, { recursive: true });
46
+ writeFileSync(CONFIG_FILE, JSON.stringify({ apiKey }, null, 2), "utf-8");
47
+ }
48
+
49
+ const BAILIAN_MODELS = [
50
+ // ── Qwen 3.5 Plus ──────────────────────────────────────────────────────
51
+ // Extended thinking enabled | 960K context | 64K output
52
+ {
53
+ id: "qwen3.5-plus",
54
+ name: "Qwen 3.5 Plus",
55
+ reasoning: true,
56
+ input: ["text"] as ["text"],
57
+ contextWindow: 983616,
58
+ maxTokens: 65536,
59
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
60
+ },
61
+ // ── Qwen3 Max 2026-01-23 ───────────────────────────────────────────────
62
+ // Extended thinking enabled | 252K context | 32K output
63
+ {
64
+ id: "qwen3-max-2026-01-23",
65
+ name: "Qwen3 Max (2026-01-23)",
66
+ reasoning: true,
67
+ input: ["text"] as ["text"],
68
+ contextWindow: 258048,
69
+ maxTokens: 32768,
70
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
71
+ },
72
+ // ── Qwen3 Coder Plus ───────────────────────────────────────────────────
73
+ // No thinking | 975K context | 64K output
74
+ {
75
+ id: "qwen3-coder-plus",
76
+ name: "Qwen3 Coder Plus",
77
+ reasoning: false,
78
+ input: ["text"] as ["text"],
79
+ contextWindow: 997952,
80
+ maxTokens: 65536,
81
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
82
+ },
83
+ // ── Qwen3 Coder Next ───────────────────────────────────────────────────
84
+ // No thinking | 200K context | 64K output
85
+ {
86
+ id: "qwen3-coder-next",
87
+ name: "Qwen3 Coder Next",
88
+ reasoning: false,
89
+ input: ["text"] as ["text"],
90
+ contextWindow: 204800,
91
+ maxTokens: 65536,
92
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
93
+ },
94
+ // ── GLM-4.7 ────────────────────────────────────────────────────────────
95
+ // Extended thinking enabled | 166K context | 16K output
96
+ {
97
+ id: "glm-4.7",
98
+ name: "GLM-4.7",
99
+ reasoning: true,
100
+ input: ["text"] as ["text"],
101
+ contextWindow: 169984,
102
+ maxTokens: 16384,
103
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
104
+ },
105
+ // ── Kimi K2.5 ─────────────────────────────────────────────────────────
106
+ // Extended thinking enabled | 252K context | 32K output
107
+ {
108
+ id: "kimi-k2.5",
109
+ name: "Kimi K2.5",
110
+ reasoning: true,
111
+ input: ["text"] as ["text"],
112
+ contextWindow: 258048,
113
+ maxTokens: 32768,
114
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
115
+ },
116
+ ];
117
+
118
+ const BAILIAN_BASE_URL = "https://coding-intl.dashscope.aliyuncs.com/apps/anthropic/v1";
119
+
120
+ export default function (pi: ExtensionAPI) {
121
+ // Resolve API key: env var takes precedence, then saved config, then env var name
122
+ // (pi resolves env var name strings automatically, so "BAILIAN_API_KEY" is a
123
+ // valid apiKey value that tells pi to look up process.env.BAILIAN_API_KEY).
124
+ const resolvedKey = process.env.BAILIAN_API_KEY ?? readStoredKey() ?? "BAILIAN_API_KEY";
125
+
126
+ pi.registerProvider("bailian", {
127
+ baseUrl: BAILIAN_BASE_URL,
128
+ apiKey: resolvedKey,
129
+ api: "anthropic-messages",
130
+ models: BAILIAN_MODELS,
131
+ });
132
+
133
+ pi.on("session_start", async (_event, ctx) => {
134
+ const hasKey = process.env.BAILIAN_API_KEY !== undefined || readStoredKey() !== undefined;
135
+ if (!hasKey) {
136
+ ctx.ui.notify(
137
+ "Bailian: No API key configured. Run /bailian-configure to set up.",
138
+ "warning",
139
+ );
140
+ }
141
+ });
142
+
143
+ pi.registerCommand("bailian-configure", {
144
+ description: "Configure your Alibaba Bailian API key",
145
+ handler: async (_args, ctx) => {
146
+ const apiKey = await ctx.ui.input(
147
+ "Bailian API key (from https://bailian.console.aliyun.com):",
148
+ "sk-sp-...",
149
+ );
150
+
151
+ if (!apiKey || apiKey.trim() === "") {
152
+ ctx.ui.notify("No API key provided. Configuration cancelled.", "warning");
153
+ return;
154
+ }
155
+
156
+ const trimmedKey = apiKey.trim();
157
+ saveKey(trimmedKey);
158
+
159
+ // Re-register provider immediately with the new key — no reload needed.
160
+ pi.registerProvider("bailian", {
161
+ baseUrl: BAILIAN_BASE_URL,
162
+ apiKey: trimmedKey,
163
+ api: "anthropic-messages",
164
+ models: BAILIAN_MODELS,
165
+ });
166
+
167
+ ctx.ui.notify("Bailian API key saved and applied successfully!", "success");
168
+ },
169
+ });
170
+ }
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "pi-bailian",
3
+ "version": "1.0.0",
4
+ "description": "Alibaba Bailian (ModelStudio) provider for pi.dev — Qwen3, GLM-4, Kimi via Anthropic-compatible API",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "mkurman",
8
+ "files": [
9
+ "index.ts",
10
+ "README.md"
11
+ ],
12
+ "keywords": [
13
+ "pi-package"
14
+ ],
15
+ "pi": {
16
+ "extensions": [
17
+ "./index.ts"
18
+ ]
19
+ },
20
+ "scripts": {
21
+ "clean": "echo 'nothing to clean'",
22
+ "build": "echo 'nothing to build'",
23
+ "check": "echo 'nothing to check'"
24
+ }
25
+ }