@d-ai/magpie 0.1.2 → 0.1.3
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 +1 -1
- package/index.mjs +57 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,5 +100,5 @@ same balance but their own reservations and call counts.
|
|
|
100
100
|
- The plugin never rewrites request bodies. Thinking levels are offered as
|
|
101
101
|
model variants, and the gateway passes `reasoning_effort` through.
|
|
102
102
|
- Requests go out with `Authorization: Bearer <key>` plus `x-api-key`, and carry
|
|
103
|
-
`x-dai-client: magpie/0.1.
|
|
103
|
+
`x-dai-client: magpie/0.1.3`. Gateway requests also carry the stable Magpie
|
|
104
104
|
session as `x-dai-session`.
|
package/index.mjs
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
// Sections: constants · helpers · chat catalog · media catalog · plugin.
|
|
34
34
|
|
|
35
35
|
const PROVIDER = "dai";
|
|
36
|
-
const CLIENT = "magpie/0.1.
|
|
36
|
+
const CLIENT = "magpie/0.1.3";
|
|
37
37
|
const DEFAULT_BASE = "https://dai.itbug.shop";
|
|
38
38
|
const OPENAI_NPM = "@ai-sdk/openai-compatible";
|
|
39
39
|
const ANTHROPIC_NPM = "@ai-sdk/anthropic";
|
|
@@ -42,6 +42,23 @@ const REQUEST_TIMEOUT_MS = 20_000;
|
|
|
42
42
|
const MEDIA_CATALOG_LIMIT = 20;
|
|
43
43
|
const MEDIA_KINDS = new Set(["image", "video", "audio"]);
|
|
44
44
|
|
|
45
|
+
/** Display names for the public tiers; unknown codes stay unchanged. */
|
|
46
|
+
const TIER_NAMES = {
|
|
47
|
+
starter: "入门版",
|
|
48
|
+
basic: "基础版",
|
|
49
|
+
pro: "专业版",
|
|
50
|
+
max: "旗舰版",
|
|
51
|
+
trial: "体验版",
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** Billing cycles as the usage card says them. */
|
|
55
|
+
const BILLING_CYCLES = {
|
|
56
|
+
monthly: "月付",
|
|
57
|
+
quarterly: "季付",
|
|
58
|
+
semiannual: "半年付",
|
|
59
|
+
annual: "年付",
|
|
60
|
+
};
|
|
61
|
+
|
|
45
62
|
/** Capability codes whose models are token-metered chat models. */
|
|
46
63
|
const CHAT_CAPABILITIES = new Set(["openai_chat_completions", "claude_messages"]);
|
|
47
64
|
|
|
@@ -135,9 +152,27 @@ const isClaudeModel = (id) => id.startsWith("claude-");
|
|
|
135
152
|
/** `ddsk_01ABC_secret` → what a card may show, never the secret itself. */
|
|
136
153
|
function keyLabel(key) {
|
|
137
154
|
const id = textOf(key).replace(/^ddsk_/u, "").split("_")[0];
|
|
138
|
-
return id ?
|
|
155
|
+
return id ? `密钥 ${id}` : "API 密钥";
|
|
139
156
|
}
|
|
140
157
|
|
|
158
|
+
const tierLabel = (code) => TIER_NAMES[textOf(code)] ?? textOf(code);
|
|
159
|
+
const cycleLabel = (cycle) => BILLING_CYCLES[textOf(cycle)] ?? textOf(cycle);
|
|
160
|
+
const statusLabel = (status) => {
|
|
161
|
+
const value = textOf(status);
|
|
162
|
+
return (
|
|
163
|
+
{
|
|
164
|
+
success: "成功",
|
|
165
|
+
completed: "已完成",
|
|
166
|
+
failed: "失败",
|
|
167
|
+
processing: "处理中",
|
|
168
|
+
pending: "等待中",
|
|
169
|
+
cancelled: "已取消",
|
|
170
|
+
canceled: "已取消",
|
|
171
|
+
refunded: "已退款",
|
|
172
|
+
}[value] ?? value
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
|
|
141
176
|
function variantsOf(id) {
|
|
142
177
|
const levels =
|
|
143
178
|
VARIANTS[id] ??
|
|
@@ -269,7 +304,7 @@ async function fetchCatalog(base, { key, signal } = {}) {
|
|
|
269
304
|
// A refused key must reach Magpie as a sign-in failure. A network or
|
|
270
305
|
// server failure keeps the last good catalog instead.
|
|
271
306
|
if (error?.status === 401 || error?.status === 403) {
|
|
272
|
-
throw Object.assign(new Error("D.AI
|
|
307
|
+
throw Object.assign(new Error("D.AI 拒绝了该 API 密钥,请重新登录"), {
|
|
273
308
|
status: error.status,
|
|
274
309
|
signIn: "expired",
|
|
275
310
|
});
|
|
@@ -308,44 +343,44 @@ function balanceCard(account, key) {
|
|
|
308
343
|
const total = optionalNumber(balance.total);
|
|
309
344
|
const pending = optionalNumber(balance.pending_reserved);
|
|
310
345
|
const calls = optionalNumber(account?.tokens?.today?.calls);
|
|
311
|
-
const parts = [
|
|
312
|
-
if (pending && pending > 0) parts.push(
|
|
346
|
+
const parts = [`余额 $${usd(total ?? 0)}`];
|
|
347
|
+
if (pending && pending > 0) parts.push(`待结算 $${usd(pending)}`);
|
|
313
348
|
if (textOf(tier.code)) {
|
|
314
349
|
parts.push(
|
|
315
350
|
[
|
|
316
|
-
|
|
317
|
-
|
|
351
|
+
tierLabel(tier.code),
|
|
352
|
+
cycleLabel(tier.billing_cycle),
|
|
318
353
|
optionalNumber(tier.expires_in_days) === undefined
|
|
319
354
|
? undefined
|
|
320
|
-
:
|
|
355
|
+
: `剩余 ${tier.expires_in_days} 天`,
|
|
321
356
|
]
|
|
322
357
|
.filter(Boolean)
|
|
323
358
|
.join(" · "),
|
|
324
359
|
);
|
|
325
360
|
}
|
|
326
361
|
const included = optionalNumber(tier.included_usd_total);
|
|
327
|
-
if (included && included > 0) parts.push(
|
|
362
|
+
if (included && included > 0) parts.push(`套餐额度 $${usd(included)}`);
|
|
328
363
|
// Only a key with a budget envelope has a reservation; the shared pool has none.
|
|
329
364
|
if (self.envelope_active) {
|
|
330
365
|
const reserved =
|
|
331
366
|
(optionalNumber(self.reserved_package_usd) ?? 0) +
|
|
332
367
|
(optionalNumber(self.reserved_recharge_usd) ?? 0);
|
|
333
|
-
if (reserved > 0) parts.push(
|
|
368
|
+
if (reserved > 0) parts.push(`本密钥 $${usd(reserved)}`);
|
|
334
369
|
}
|
|
335
370
|
const requestLimit = optionalNumber(self.daily_request_limit);
|
|
336
371
|
const usdLimit = optionalNumber(self.daily_usd_limit);
|
|
337
372
|
const limits = [
|
|
338
|
-
requestLimit === undefined ? undefined : `${requestLimit}
|
|
339
|
-
usdLimit === undefined ? undefined : `$${usd(usdLimit)}
|
|
373
|
+
requestLimit === undefined ? undefined : `${requestLimit} 次/天`,
|
|
374
|
+
usdLimit === undefined ? undefined : `$${usd(usdLimit)}/天`,
|
|
340
375
|
].filter(Boolean);
|
|
341
|
-
if (limits.length) parts.push(
|
|
376
|
+
if (limits.length) parts.push(`限额 ${limits.join(",")}`);
|
|
342
377
|
if (calls !== undefined) {
|
|
343
|
-
parts.push(
|
|
378
|
+
parts.push(`今日 ${calls} 次调用`);
|
|
344
379
|
}
|
|
345
380
|
return {
|
|
346
|
-
plan:
|
|
381
|
+
plan: tierLabel(tier.code) || keyLabel(key),
|
|
347
382
|
balance: total === undefined ? "" : `$${usd(total)}`,
|
|
348
|
-
windows: [{ name: "D.AI
|
|
383
|
+
windows: [{ name: "D.AI 余额", display: parts.join(" · ") }],
|
|
349
384
|
};
|
|
350
385
|
}
|
|
351
386
|
|
|
@@ -359,14 +394,14 @@ async function callLogCard(base, key) {
|
|
|
359
394
|
});
|
|
360
395
|
const total = numberOr(log?.total, 0);
|
|
361
396
|
const last = Array.isArray(log?.data) ? log.data[0] : undefined;
|
|
362
|
-
const parts = [`${total}
|
|
397
|
+
const parts = [`${total} 次调用`];
|
|
363
398
|
if (last) {
|
|
364
399
|
const settled = optionalNumber(last.settled_usd);
|
|
365
400
|
parts.push(
|
|
366
401
|
[
|
|
367
402
|
textOf(last.created_at).replace("T", " ").slice(0, 16),
|
|
368
403
|
textOf(last.model_code),
|
|
369
|
-
|
|
404
|
+
statusLabel(last.status),
|
|
370
405
|
settled === undefined ? undefined : `$${usd(settled)}`,
|
|
371
406
|
]
|
|
372
407
|
.filter(Boolean)
|
|
@@ -375,7 +410,7 @@ async function callLogCard(base, key) {
|
|
|
375
410
|
}
|
|
376
411
|
return {
|
|
377
412
|
plan: keyLabel(key),
|
|
378
|
-
windows: [{ name: "D.AI
|
|
413
|
+
windows: [{ name: "D.AI 调用", display: parts.join(" · ") }],
|
|
379
414
|
};
|
|
380
415
|
}
|
|
381
416
|
|
|
@@ -564,7 +599,7 @@ const DaiPlugin = async (_input, options = {}) => {
|
|
|
564
599
|
auth: {
|
|
565
600
|
provider: PROVIDER,
|
|
566
601
|
|
|
567
|
-
methods: [{ type: "api", label: "D.AI API
|
|
602
|
+
methods: [{ type: "api", label: "D.AI API 密钥", placeholder: "ddsk_…" }],
|
|
568
603
|
|
|
569
604
|
async loader(getAuth) {
|
|
570
605
|
const auth = await getAuth();
|
|
@@ -586,7 +621,7 @@ const DaiPlugin = async (_input, options = {}) => {
|
|
|
586
621
|
const auth = await getAuth();
|
|
587
622
|
const key = textOf(auth?.key);
|
|
588
623
|
if (auth?.type !== "api" || !key) {
|
|
589
|
-
return { windows: [], error: "D.AI
|
|
624
|
+
return { windows: [], error: "D.AI:请使用 API 密钥登录" };
|
|
590
625
|
}
|
|
591
626
|
try {
|
|
592
627
|
const account = await fetchJson(`${base}/api/ai/account`, { apiKey: key });
|
|
@@ -594,7 +629,7 @@ const DaiPlugin = async (_input, options = {}) => {
|
|
|
594
629
|
} catch (error) {
|
|
595
630
|
const status = error?.status;
|
|
596
631
|
if (status === 401 || status === 403) {
|
|
597
|
-
return { windows: [], error: "D.AI
|
|
632
|
+
return { windows: [], error: "D.AI 拒绝了该 API 密钥", signIn: "expired" };
|
|
598
633
|
}
|
|
599
634
|
// A deployment older than the endpoint answers 404. Its call log
|
|
600
635
|
// is still there, and counting calls beats showing an error.
|
package/package.json
CHANGED