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