@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.
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RECOMMENDED_MODELS = void 0;
4
+ exports.detectOllama = detectOllama;
5
+ exports.detectAiping = detectAiping;
6
+ const child_process_1 = require("child_process");
7
+ // ──────────────────────────────────────────────────────────────────────────────
8
+ // Ollama detector
9
+ // ──────────────────────────────────────────────────────────────────────────────
10
+ async function detectOllama(baseUrl = 'http://localhost:11434') {
11
+ const url = baseUrl.replace(/\/$/, '');
12
+ // 1. Check if binary exists
13
+ const binaryFound = isOllamaBinaryAvailable();
14
+ // 2. Try to ping the REST endpoint
15
+ const start = Date.now();
16
+ let serviceRunning = false;
17
+ let models = [];
18
+ let latencyMs;
19
+ let error;
20
+ try {
21
+ const res = await fetch(`${url}/api/tags`, {
22
+ signal: AbortSignal.timeout(4000),
23
+ });
24
+ latencyMs = Date.now() - start;
25
+ if (res.ok) {
26
+ serviceRunning = true;
27
+ const data = (await res.json());
28
+ models = (data.models ?? []).map((m) => ({
29
+ name: m.name,
30
+ size: m.size ? formatBytes(m.size) : undefined,
31
+ modifiedAt: m.modified_at,
32
+ }));
33
+ }
34
+ else {
35
+ error = `HTTP ${res.status}`;
36
+ }
37
+ }
38
+ catch (e) {
39
+ error = e.message;
40
+ latencyMs = Date.now() - start;
41
+ }
42
+ // 3. If REST failed but binary exists, try `ollama list` as fallback
43
+ if (!serviceRunning && binaryFound) {
44
+ const cliModels = tryOllamaListCLI();
45
+ if (cliModels.length > 0) {
46
+ models = cliModels;
47
+ }
48
+ }
49
+ return { binaryFound, serviceRunning, models, latencyMs, error };
50
+ }
51
+ function isOllamaBinaryAvailable() {
52
+ try {
53
+ (0, child_process_1.execSync)('ollama --version', { stdio: 'ignore', timeout: 3000 });
54
+ return true;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ function tryOllamaListCLI() {
61
+ try {
62
+ const output = (0, child_process_1.execSync)('ollama list', { timeout: 5000, encoding: 'utf8' });
63
+ // Output format: "NAME ID SIZE MODIFIED\nqwen2.5:4b ..."
64
+ const lines = output.split('\n').slice(1); // skip header
65
+ return lines
66
+ .map((line) => line.trim())
67
+ .filter(Boolean)
68
+ .map((line) => {
69
+ const parts = line.split(/\s+/);
70
+ const name = parts[0] ?? '';
71
+ const size = parts[2] ? `${parts[2]} ${parts[3] ?? ''}`.trim() : undefined;
72
+ return { name, size };
73
+ })
74
+ .filter((m) => m.name);
75
+ }
76
+ catch {
77
+ return [];
78
+ }
79
+ }
80
+ function formatBytes(bytes) {
81
+ if (bytes >= 1e9)
82
+ return `${(bytes / 1e9).toFixed(1)} GB`;
83
+ if (bytes >= 1e6)
84
+ return `${(bytes / 1e6).toFixed(0)} MB`;
85
+ return `${bytes} B`;
86
+ }
87
+ // ──────────────────────────────────────────────────────────────────────────────
88
+ // AIPing detector
89
+ // ──────────────────────────────────────────────────────────────────────────────
90
+ const AIPING_BASE = 'https://aiping.cn/api/v1';
91
+ async function detectAiping(apiKey, model = 'kimi-2.5') {
92
+ if (!apiKey) {
93
+ return { reachable: false, keyValid: false, model, error: '未提供 API Key' };
94
+ }
95
+ const start = Date.now();
96
+ try {
97
+ const res = await fetch(`${AIPING_BASE}/chat/completions`, {
98
+ method: 'POST',
99
+ headers: {
100
+ 'Content-Type': 'application/json',
101
+ Authorization: `Bearer ${apiKey}`,
102
+ },
103
+ body: JSON.stringify({
104
+ model,
105
+ messages: [{ role: 'user', content: 'ping' }],
106
+ max_tokens: 1,
107
+ stream: false,
108
+ }),
109
+ signal: AbortSignal.timeout(10000),
110
+ });
111
+ const latencyMs = Date.now() - start;
112
+ if (res.ok) {
113
+ return { reachable: true, keyValid: true, model, latencyMs };
114
+ }
115
+ const body = await res.text().catch(() => '');
116
+ if (res.status === 401 || res.status === 403) {
117
+ return {
118
+ reachable: true,
119
+ keyValid: false,
120
+ model,
121
+ latencyMs,
122
+ error: 'API Key 无效或已过期',
123
+ errorCode: res.status,
124
+ };
125
+ }
126
+ if (res.status === 429) {
127
+ return {
128
+ reachable: true,
129
+ keyValid: true, // key itself is valid, just rate-limited
130
+ model,
131
+ latencyMs,
132
+ error: '请求频率超限(Rate limited),请稍后重试',
133
+ errorCode: 429,
134
+ };
135
+ }
136
+ return {
137
+ reachable: true,
138
+ keyValid: false,
139
+ model,
140
+ latencyMs,
141
+ error: `HTTP ${res.status}: ${body.slice(0, 120)}`,
142
+ errorCode: res.status,
143
+ };
144
+ }
145
+ catch (e) {
146
+ const latencyMs = Date.now() - start;
147
+ const msg = e.message;
148
+ const isNetworkError = msg.includes('fetch') || msg.includes('ECONNREFUSED') ||
149
+ msg.includes('ENOTFOUND') || msg.includes('timeout');
150
+ return {
151
+ reachable: !isNetworkError,
152
+ keyValid: false,
153
+ model,
154
+ latencyMs,
155
+ error: isNetworkError ? '网络不可达,请检查网络连接' : msg,
156
+ };
157
+ }
158
+ }
159
+ // ──────────────────────────────────────────────────────────────────────────────
160
+ // Recommended models (shown when user has no local models)
161
+ // ──────────────────────────────────────────────────────────────────────────────
162
+ exports.RECOMMENDED_MODELS = [
163
+ { name: 'qwen2.5:4b', size: '~2.3 GB', desc: '推荐首选:阿里通义千问,中文能力强' },
164
+ { name: 'qwen2.5:7b', size: '~4.4 GB', desc: '质量更高,需要更多内存' },
165
+ { name: 'llama3.2:3b', size: '~2.0 GB', desc: 'Meta Llama,英文能力优秀' },
166
+ { name: 'phi3.5:mini', size: '~2.2 GB', desc: 'Microsoft Phi,推理能力强' },
167
+ { name: 'gemma3:4b', size: '~3.3 GB', desc: 'Google Gemma,均衡性能' },
168
+ ];
169
+ //# sourceMappingURL=detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/setup/detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { PluginConfig } from '../types.js';
2
+ export interface PartialConfig extends Partial<PluginConfig> {
3
+ aipingApiKey?: string;
4
+ }
5
+ export declare function runSetupWizard(existingConfig?: PartialConfig): Promise<PluginConfig>;
6
+ //# sourceMappingURL=wizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../../src/setup/wizard.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAUhD,MAAM,WAAW,aAAc,SAAQ,OAAO,CAAC,YAAY,CAAC;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAkSD,wBAAsB,cAAc,CAAC,cAAc,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CA2R9F"}