@aiping.cn/model_router 1.2.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 +169 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/cloud.d.ts +23 -0
- package/dist/providers/cloud.d.ts.map +1 -0
- package/dist/providers/cloud.js +128 -0
- package/dist/providers/cloud.js.map +1 -0
- package/dist/providers/local.d.ts +25 -0
- package/dist/providers/local.d.ts.map +1 -0
- package/dist/providers/local.js +167 -0
- package/dist/providers/local.js.map +1 -0
- package/dist/router/router.d.ts +10 -0
- package/dist/router/router.d.ts.map +1 -0
- package/dist/router/router.js +48 -0
- package/dist/router/router.js.map +1 -0
- package/dist/router/rules.d.ts +61 -0
- package/dist/router/rules.d.ts.map +1 -0
- package/dist/router/rules.js +178 -0
- package/dist/router/rules.js.map +1 -0
- package/dist/router/scorer.d.ts +7 -0
- package/dist/router/scorer.d.ts.map +1 -0
- package/dist/router/scorer.js +34 -0
- package/dist/router/scorer.js.map +1 -0
- package/dist/setup/detector.d.ts +28 -0
- package/dist/setup/detector.d.ts.map +1 -0
- package/dist/setup/detector.js +169 -0
- package/dist/setup/detector.js.map +1 -0
- package/dist/setup/wizard.d.ts +6 -0
- package/dist/setup/wizard.d.ts.map +1 -0
- package/dist/setup/wizard.js +527 -0
- package/dist/setup/wizard.js.map +1 -0
- package/dist/types.d.ts +66 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -0
- package/openclaw.plugin.json +70 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# @aiping.cn/model_router
|
|
2
|
+
|
|
3
|
+
> Smart routing between your local Ollama model and AIPing cloud (Kimi-2.5).
|
|
4
|
+
> One plugin, one virtual model — zero workflow changes.
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/@aiping.cn/model_router)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## What it does
|
|
11
|
+
|
|
12
|
+
When you use the `aiping:claw` model in OpenClaw, this plugin automatically decides whether to send your request to:
|
|
13
|
+
|
|
14
|
+
| Destination | When | Why |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| **Local model** (Ollama, e.g. `qwen2.5:4b`) | Short, simple queries | Low latency, zero cost |
|
|
17
|
+
| **AIPing cloud** (Kimi-2.5) | Complex, long, or multi-turn | High capability |
|
|
18
|
+
|
|
19
|
+
Routing is based on a **5-dimension rule scorer** that runs in < 1ms — no ML inference, no extra processes.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
openclaw plugins install @aiping.cn/model_router
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The setup wizard will guide you through configuration automatically.
|
|
32
|
+
|
|
33
|
+
### 2. Get your AIPing API key
|
|
34
|
+
|
|
35
|
+
Visit [https://aiping.cn/user/user-center](https://aiping.cn/user/user-center) to obtain your API key.
|
|
36
|
+
|
|
37
|
+
### 3. Make sure Ollama is running locally
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Start Ollama
|
|
41
|
+
ollama serve
|
|
42
|
+
|
|
43
|
+
# Pull your preferred local model
|
|
44
|
+
ollama pull qwen2.5:4b
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 4. Use it
|
|
48
|
+
|
|
49
|
+
Select **`aiping:claw`** as your model in OpenClaw. The plugin handles the rest.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Manual Configuration
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Set your AIPing API key
|
|
57
|
+
openclaw plugins config @aiping.cn/model_router set aipingApiKey "sk-your-key-here"
|
|
58
|
+
|
|
59
|
+
# Change local proxy URL (default: http://localhost:11434)
|
|
60
|
+
openclaw plugins config @aiping.cn/model_router set localProxyUrl "http://localhost:11434"
|
|
61
|
+
|
|
62
|
+
# Change local model (default: qwen2.5:4b)
|
|
63
|
+
openclaw plugins config @aiping.cn/model_router set localModel "qwen2.5:4b"
|
|
64
|
+
|
|
65
|
+
# Run setup wizard again
|
|
66
|
+
openclaw run aiping:setup
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## How Routing Works
|
|
72
|
+
|
|
73
|
+
Each request is scored across 5 dimensions:
|
|
74
|
+
|
|
75
|
+
| Dimension | Max Points | Trigger |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| Token count | 30 | > 2000 estimated tokens |
|
|
78
|
+
| Code complexity | 20 | Code block with > 30 lines |
|
|
79
|
+
| Reasoning depth | 15 | Keywords: analyze, compare, 分析, 对比... |
|
|
80
|
+
| Multi-turn context | 20 | > 6 messages in history |
|
|
81
|
+
| Override directive | — | `@local` or `@cloud` in message |
|
|
82
|
+
|
|
83
|
+
**Score ≥ threshold (default: 50) → Cloud (Kimi-2.5)**
|
|
84
|
+
**Score < threshold → Local (Ollama)**
|
|
85
|
+
|
|
86
|
+
### Override Routing
|
|
87
|
+
|
|
88
|
+
Add `@local` or `@cloud` to any message to force a specific destination:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
Summarise this paragraph @local
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
Write a comprehensive analysis of this architecture @cloud
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Configuration Reference
|
|
101
|
+
|
|
102
|
+
| Key | Default | Description |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `aipingApiKey` | *(required)* | AIPing API key from [aiping.cn](https://aiping.cn/user/user-center) |
|
|
105
|
+
| `localProxyUrl` | `http://localhost:11434` | Ollama or local proxy base URL |
|
|
106
|
+
| `localProxyKey` | *(empty)* | Optional auth key for local proxy |
|
|
107
|
+
| `localModel` | `qwen2.5:4b` | Local model name in Ollama |
|
|
108
|
+
| `cloudModel` | `kimi-2.5` | Cloud model on AIPing |
|
|
109
|
+
| `routingThreshold` | `50` | Score threshold (0–100) |
|
|
110
|
+
| `fallbackToCloud` | `true` | Auto-fallback to cloud if local fails |
|
|
111
|
+
| `localTimeoutMs` | `30000` | Local request timeout in ms |
|
|
112
|
+
| `debugRouting` | `false` | Print routing decisions to console |
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Architecture
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
OpenClaw Gateway
|
|
120
|
+
└── aiping:claw (virtual model)
|
|
121
|
+
└── ModelRouter Plugin
|
|
122
|
+
├── RuleScorer (5 dimensions, < 1ms)
|
|
123
|
+
│ ├── TokenCountScorer
|
|
124
|
+
│ ├── CodeComplexityScorer
|
|
125
|
+
│ ├── ReasoningDepthScorer
|
|
126
|
+
│ ├── MultiTurnContextScorer
|
|
127
|
+
│ └── OverrideScorer (@local / @cloud)
|
|
128
|
+
├── LocalAdapter → Ollama /v1/chat/completions
|
|
129
|
+
└── CloudAdapter → https://aiping.cn/api/v1/chat/completions
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The `RuleScorer` interface is extensible — add new scoring dimensions by implementing:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
interface RuleScorer {
|
|
136
|
+
readonly name: string;
|
|
137
|
+
readonly maxScore: number;
|
|
138
|
+
score(request: ChatRequest): DimensionScore;
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Development
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Install dependencies
|
|
148
|
+
npm install
|
|
149
|
+
|
|
150
|
+
# Build
|
|
151
|
+
npm run build
|
|
152
|
+
|
|
153
|
+
# Run tests
|
|
154
|
+
npm test
|
|
155
|
+
|
|
156
|
+
# Watch mode
|
|
157
|
+
npm run dev
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Links
|
|
163
|
+
|
|
164
|
+
- [AIPing API](https://aiping.cn/api/v1)
|
|
165
|
+
- [AIPing User Center (API Key)](https://aiping.cn/user/user-center)
|
|
166
|
+
- [OpenClaw Plugin Docs](https://open-claw.bot/docs/plugins/api)
|
|
167
|
+
- [Changelog](docs/CHANGELOG.md)
|
|
168
|
+
- [Architecture Plan](docs/plan-v1.md)
|
|
169
|
+
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiping.cn/model_router — OpenClaw Plugin Entry Point
|
|
3
|
+
*
|
|
4
|
+
* Registers the "aiping:claw" virtual model with the OpenClaw Gateway
|
|
5
|
+
* and routes incoming requests to either a local Ollama model or the
|
|
6
|
+
* AIPing cloud API based on a lightweight 5-dimension rule scorer.
|
|
7
|
+
*
|
|
8
|
+
* 默认策略:约 90% 请求走本地模型,只有复杂任务走云端。
|
|
9
|
+
*/
|
|
10
|
+
import type { ChatRequest, ChatResponse } from './types.js';
|
|
11
|
+
export default function register(api: OpenClawPluginAPI): void;
|
|
12
|
+
interface OpenClawPluginAPI {
|
|
13
|
+
getConfig(): Record<string, unknown>;
|
|
14
|
+
setConfig(config: Record<string, unknown>): Promise<void>;
|
|
15
|
+
onConfigChange(callback: (config: Record<string, unknown>) => void): void;
|
|
16
|
+
registerCommand(cmd: {
|
|
17
|
+
name: string;
|
|
18
|
+
description: string;
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
}): void;
|
|
21
|
+
registerModelRoute(route: {
|
|
22
|
+
model: string;
|
|
23
|
+
description: string;
|
|
24
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
25
|
+
chatStream(request: ChatRequest): AsyncGenerator<string>;
|
|
26
|
+
}): void;
|
|
27
|
+
/** Optional: set the Gateway's default model (available in OpenClaw Gateway ≥ 1.x) */
|
|
28
|
+
setDefaultModel?(model: string): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAC;AAW1E,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CA+D7D;AA8GD,UAAU,iBAAiB;IACzB,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,cAAc,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1E,eAAe,CAAC,GAAG,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;KACtB,GAAG,IAAI,CAAC;IACT,kBAAkB,CAAC,KAAK,EAAE;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;QAClD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;KAC1D,GAAG,IAAI,CAAC;IACT,sFAAsF;IACtF,eAAe,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @aiping.cn/model_router — OpenClaw Plugin Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Registers the "aiping:claw" virtual model with the OpenClaw Gateway
|
|
6
|
+
* and routes incoming requests to either a local Ollama model or the
|
|
7
|
+
* AIPing cloud API based on a lightweight 5-dimension rule scorer.
|
|
8
|
+
*
|
|
9
|
+
* 默认策略:约 90% 请求走本地模型,只有复杂任务走云端。
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.default = register;
|
|
13
|
+
const types_js_1 = require("./types.js");
|
|
14
|
+
const router_js_1 = require("./router/router.js");
|
|
15
|
+
const local_js_1 = require("./providers/local.js");
|
|
16
|
+
const cloud_js_1 = require("./providers/cloud.js");
|
|
17
|
+
const wizard_js_1 = require("./setup/wizard.js");
|
|
18
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
19
|
+
// OpenClaw plugin API surface (api object injected by the Gateway at load time)
|
|
20
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
21
|
+
function register(api) {
|
|
22
|
+
let config = buildConfig(api.getConfig());
|
|
23
|
+
// Re-build config whenever it changes (live reload support)
|
|
24
|
+
api.onConfigChange((newConfig) => {
|
|
25
|
+
config = buildConfig(newConfig);
|
|
26
|
+
});
|
|
27
|
+
// ── 注册 CLI 命令:重新运行配置向导 ─────────────────────────────────────
|
|
28
|
+
api.registerCommand({
|
|
29
|
+
name: 'aiping:setup',
|
|
30
|
+
description: '运行 AIPing Model Router 中文配置向导',
|
|
31
|
+
async run() {
|
|
32
|
+
const updated = await (0, wizard_js_1.runSetupWizard)(config);
|
|
33
|
+
await api.setConfig(updated);
|
|
34
|
+
config = updated;
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
// ── 首次安装:自动触发中文配置向导 ─────────────────────────────────────
|
|
38
|
+
// 如果 aipingApiKey 还没配置,说明是首次安装,自动启动向导。
|
|
39
|
+
if (!config.aipingApiKey) {
|
|
40
|
+
(0, wizard_js_1.runSetupWizard)(config)
|
|
41
|
+
.then(async (updated) => {
|
|
42
|
+
await api.setConfig(updated);
|
|
43
|
+
config = updated;
|
|
44
|
+
})
|
|
45
|
+
.catch((wizardErr) => {
|
|
46
|
+
console.warn('[aiping:router] 配置向导退出,稍后可运行 `openclaw run aiping:setup` 重新配置。', wizardErr.message);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
// ── 注册虚拟模型 aiping:claw ─────────────────────────────────────────────
|
|
50
|
+
api.registerModelRoute({
|
|
51
|
+
model: 'aiping:claw',
|
|
52
|
+
description: 'AIPing 智能路由 — 自动在本地模型和云端 Kimi-2.5 之间切换(约 90% 走本地)',
|
|
53
|
+
async chat(request) {
|
|
54
|
+
return handleChat(request, config);
|
|
55
|
+
},
|
|
56
|
+
async *chatStream(request) {
|
|
57
|
+
yield* handleChatStream(request, config);
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
// ── 注册为默认模型 ────────────────────────────────────────────────────────
|
|
61
|
+
// 尝试通过 Gateway API 设置默认模型(若 API 可用)
|
|
62
|
+
if (typeof api.setDefaultModel === 'function') {
|
|
63
|
+
api.setDefaultModel('aiping:claw').catch(() => {
|
|
64
|
+
// 静默失败:向导内已提供手动设置方式
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
console.log('[aiping:router] ✅ 已注册虚拟模型 "aiping:claw"' +
|
|
68
|
+
` | 阈值=${config.routingThreshold} | 本地=${config.localModel}` +
|
|
69
|
+
(config.debugRouting ? ' | 路由调试开启' : ''));
|
|
70
|
+
}
|
|
71
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
72
|
+
// Core request handlers
|
|
73
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
74
|
+
async function handleChat(request, config) {
|
|
75
|
+
const router = new router_js_1.Router(config);
|
|
76
|
+
const local = new local_js_1.LocalAdapter(config);
|
|
77
|
+
const cloud = new cloud_js_1.CloudAdapter(config);
|
|
78
|
+
const decision = router.decide(request);
|
|
79
|
+
if (decision.target === 'local') {
|
|
80
|
+
try {
|
|
81
|
+
return await local.chat(request);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
if (config.fallbackToCloud) {
|
|
85
|
+
console.warn(`[aiping:router] Local failed (${err.message}), falling back to cloud`);
|
|
86
|
+
return cloud.chat(request);
|
|
87
|
+
}
|
|
88
|
+
throw err;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Cloud path: no fallback needed (cloud errors surface directly)
|
|
92
|
+
try {
|
|
93
|
+
return await cloud.chat(request);
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
// If cloud fails and fallback is enabled, try local as last resort
|
|
97
|
+
if (config.fallbackToCloud && !(err instanceof local_js_1.LocalAdapterError)) {
|
|
98
|
+
console.warn(`[aiping:router] Cloud failed (${err.message}), trying local as fallback`);
|
|
99
|
+
return local.chat(request);
|
|
100
|
+
}
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function* handleChatStream(request, config) {
|
|
105
|
+
const router = new router_js_1.Router(config);
|
|
106
|
+
const local = new local_js_1.LocalAdapter(config);
|
|
107
|
+
const cloud = new cloud_js_1.CloudAdapter(config);
|
|
108
|
+
const decision = router.decide(request);
|
|
109
|
+
if (decision.target === 'local') {
|
|
110
|
+
try {
|
|
111
|
+
yield* local.chatStream(request);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
if (config.fallbackToCloud) {
|
|
116
|
+
console.warn(`[aiping:router] Local stream failed (${err.message}), falling back to cloud`);
|
|
117
|
+
yield* cloud.chatStream(request);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
yield* cloud.chatStream(request);
|
|
124
|
+
}
|
|
125
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
126
|
+
// Helpers
|
|
127
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
128
|
+
function buildConfig(raw) {
|
|
129
|
+
return {
|
|
130
|
+
aipingApiKey: raw['aipingApiKey'] ?? '',
|
|
131
|
+
localProxyUrl: raw['localProxyUrl'] ?? types_js_1.DEFAULT_CONFIG.localProxyUrl,
|
|
132
|
+
localProxyKey: raw['localProxyKey'] ?? '',
|
|
133
|
+
localModel: raw['localModel'] ?? types_js_1.DEFAULT_CONFIG.localModel,
|
|
134
|
+
cloudModel: raw['cloudModel'] ?? types_js_1.DEFAULT_CONFIG.cloudModel,
|
|
135
|
+
routingThreshold: typeof raw['routingThreshold'] === 'number'
|
|
136
|
+
? raw['routingThreshold']
|
|
137
|
+
: types_js_1.DEFAULT_CONFIG.routingThreshold,
|
|
138
|
+
fallbackToCloud: typeof raw['fallbackToCloud'] === 'boolean'
|
|
139
|
+
? raw['fallbackToCloud']
|
|
140
|
+
: types_js_1.DEFAULT_CONFIG.fallbackToCloud,
|
|
141
|
+
localTimeoutMs: typeof raw['localTimeoutMs'] === 'number'
|
|
142
|
+
? raw['localTimeoutMs']
|
|
143
|
+
: types_js_1.DEFAULT_CONFIG.localTimeoutMs,
|
|
144
|
+
debugRouting: typeof raw['debugRouting'] === 'boolean'
|
|
145
|
+
? raw['debugRouting']
|
|
146
|
+
: types_js_1.DEFAULT_CONFIG.debugRouting,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ChatRequest, ChatResponse, PluginConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* CloudAdapter forwards requests to the AIPing API (Kimi-2.5 by default).
|
|
4
|
+
* The AIPing API is OpenAI-compatible.
|
|
5
|
+
*/
|
|
6
|
+
export declare class CloudAdapter {
|
|
7
|
+
private readonly config;
|
|
8
|
+
constructor(config: PluginConfig);
|
|
9
|
+
private buildHeaders;
|
|
10
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
11
|
+
chatStream(request: ChatRequest): AsyncGenerator<string>;
|
|
12
|
+
ping(): Promise<{
|
|
13
|
+
ok: boolean;
|
|
14
|
+
latencyMs: number;
|
|
15
|
+
model: string;
|
|
16
|
+
error?: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
export declare class CloudAdapterError extends Error {
|
|
20
|
+
readonly statusCode: number;
|
|
21
|
+
constructor(message: string, statusCode: number);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=cloud.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/providers/cloud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3E;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,MAAM,EAAE,YAAY;IAIhC,OAAO,CAAC,YAAY;IAOd,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAgChD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC;IAoCzD,IAAI,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CA8CzF;AAED,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM;CAKrC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CloudAdapterError = exports.CloudAdapter = void 0;
|
|
4
|
+
const AIPING_BASE_URL = 'https://aiping.cn/api/v1';
|
|
5
|
+
/**
|
|
6
|
+
* CloudAdapter forwards requests to the AIPing API (Kimi-2.5 by default).
|
|
7
|
+
* The AIPing API is OpenAI-compatible.
|
|
8
|
+
*/
|
|
9
|
+
class CloudAdapter {
|
|
10
|
+
config;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
}
|
|
14
|
+
buildHeaders() {
|
|
15
|
+
return {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
Authorization: `Bearer ${this.config.aipingApiKey}`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async chat(request) {
|
|
21
|
+
const body = JSON.stringify({
|
|
22
|
+
...request,
|
|
23
|
+
model: this.config.cloudModel,
|
|
24
|
+
stream: false,
|
|
25
|
+
});
|
|
26
|
+
const res = await fetch(`${AIPING_BASE_URL}/chat/completions`, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: this.buildHeaders(),
|
|
29
|
+
body,
|
|
30
|
+
});
|
|
31
|
+
if (!res.ok) {
|
|
32
|
+
const text = await res.text().catch(() => '');
|
|
33
|
+
if (res.status === 401) {
|
|
34
|
+
throw new CloudAdapterError('Invalid AIPing API key. Get your key at https://aiping.cn/user/user-center', 401);
|
|
35
|
+
}
|
|
36
|
+
if (res.status === 429) {
|
|
37
|
+
throw new CloudAdapterError('AIPing rate limit exceeded. Please retry later.', 429);
|
|
38
|
+
}
|
|
39
|
+
throw new CloudAdapterError(`AIPing API returned ${res.status}: ${text}`, res.status);
|
|
40
|
+
}
|
|
41
|
+
const data = (await res.json());
|
|
42
|
+
// Normalise model field to the virtual model name
|
|
43
|
+
return { ...data, model: request.model };
|
|
44
|
+
}
|
|
45
|
+
async *chatStream(request) {
|
|
46
|
+
const body = JSON.stringify({
|
|
47
|
+
...request,
|
|
48
|
+
model: this.config.cloudModel,
|
|
49
|
+
stream: true,
|
|
50
|
+
});
|
|
51
|
+
const res = await fetch(`${AIPING_BASE_URL}/chat/completions`, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: this.buildHeaders(),
|
|
54
|
+
body,
|
|
55
|
+
});
|
|
56
|
+
if (!res.ok) {
|
|
57
|
+
const text = await res.text().catch(() => '');
|
|
58
|
+
if (res.status === 401) {
|
|
59
|
+
throw new CloudAdapterError('Invalid AIPing API key. Get your key at https://aiping.cn/user/user-center', 401);
|
|
60
|
+
}
|
|
61
|
+
throw new CloudAdapterError(`AIPing API returned ${res.status}: ${text}`, res.status);
|
|
62
|
+
}
|
|
63
|
+
if (!res.body)
|
|
64
|
+
throw new CloudAdapterError('Empty response body from AIPing', 500);
|
|
65
|
+
const reader = res.body.getReader();
|
|
66
|
+
const decoder = new TextDecoder();
|
|
67
|
+
while (true) {
|
|
68
|
+
const { done, value } = await reader.read();
|
|
69
|
+
if (done)
|
|
70
|
+
break;
|
|
71
|
+
yield decoder.decode(value, { stream: true });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async ping() {
|
|
75
|
+
const start = Date.now();
|
|
76
|
+
try {
|
|
77
|
+
// Use a minimal chat request to verify the key and model are valid
|
|
78
|
+
const res = await fetch(`${AIPING_BASE_URL}/chat/completions`, {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
headers: this.buildHeaders(),
|
|
81
|
+
body: JSON.stringify({
|
|
82
|
+
model: this.config.cloudModel,
|
|
83
|
+
messages: [{ role: 'user', content: 'ping' }],
|
|
84
|
+
max_tokens: 1,
|
|
85
|
+
stream: false,
|
|
86
|
+
}),
|
|
87
|
+
signal: AbortSignal.timeout(10000),
|
|
88
|
+
});
|
|
89
|
+
const latencyMs = Date.now() - start;
|
|
90
|
+
if (res.status === 401) {
|
|
91
|
+
return {
|
|
92
|
+
ok: false,
|
|
93
|
+
latencyMs,
|
|
94
|
+
model: this.config.cloudModel,
|
|
95
|
+
error: 'Invalid API key',
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
if (!res.ok) {
|
|
99
|
+
return {
|
|
100
|
+
ok: false,
|
|
101
|
+
latencyMs,
|
|
102
|
+
model: this.config.cloudModel,
|
|
103
|
+
error: `HTTP ${res.status}`,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return { ok: true, latencyMs, model: this.config.cloudModel };
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
latencyMs: Date.now() - start,
|
|
112
|
+
model: this.config.cloudModel,
|
|
113
|
+
error: err.message,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.CloudAdapter = CloudAdapter;
|
|
119
|
+
class CloudAdapterError extends Error {
|
|
120
|
+
statusCode;
|
|
121
|
+
constructor(message, statusCode) {
|
|
122
|
+
super(message);
|
|
123
|
+
this.statusCode = statusCode;
|
|
124
|
+
this.name = 'CloudAdapterError';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.CloudAdapterError = CloudAdapterError;
|
|
128
|
+
//# sourceMappingURL=cloud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud.js","sourceRoot":"","sources":["../../src/providers/cloud.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ChatRequest, ChatResponse, PluginConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* LocalAdapter forwards requests to an Ollama-compatible local server
|
|
4
|
+
* using the OpenAI-compatible /v1/chat/completions endpoint.
|
|
5
|
+
*/
|
|
6
|
+
export declare class LocalAdapter {
|
|
7
|
+
private readonly config;
|
|
8
|
+
constructor(config: PluginConfig);
|
|
9
|
+
private get baseUrl();
|
|
10
|
+
private buildHeaders;
|
|
11
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
12
|
+
chatStream(request: ChatRequest): AsyncGenerator<string>;
|
|
13
|
+
ping(): Promise<{
|
|
14
|
+
ok: boolean;
|
|
15
|
+
latencyMs: number;
|
|
16
|
+
error?: string;
|
|
17
|
+
}>;
|
|
18
|
+
/** Returns list of model names available on the local server. */
|
|
19
|
+
listModels(): Promise<string[]>;
|
|
20
|
+
}
|
|
21
|
+
export declare class LocalAdapterError extends Error {
|
|
22
|
+
readonly statusCode: number;
|
|
23
|
+
constructor(message: string, statusCode: number);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/providers/local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3E;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,MAAM,EAAE,YAAY;IAIhC,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,CAAC,YAAY;IAUd,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA6ChD,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC;IAoDzD,IAAI,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA+BzE,iEAAiE;IAC3D,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAyBtC;AAED,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM;CAKrC"}
|