@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.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/index.mjs +57 -22
  3. 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.2`. Gateway requests also carry the stable Magpie
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.2";
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 ? `key ${id}` : "API key";
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 refused the API key; sign in again"), {
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 = [`$${usd(total ?? 0)} left`];
312
- if (pending && pending > 0) parts.push(`$${usd(pending)} pending`);
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
- textOf(tier.code),
317
- textOf(tier.billing_cycle),
351
+ tierLabel(tier.code),
352
+ cycleLabel(tier.billing_cycle),
318
353
  optionalNumber(tier.expires_in_days) === undefined
319
354
  ? undefined
320
- : `${tier.expires_in_days}d left`,
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(`$${usd(included)} included`);
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(`this key $${usd(reserved)}`);
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} requests/day`,
339
- usdLimit === undefined ? undefined : `$${usd(usdLimit)}/day`,
373
+ requestLimit === undefined ? undefined : `${requestLimit} 次/天`,
374
+ usdLimit === undefined ? undefined : `$${usd(usdLimit)}/天`,
340
375
  ].filter(Boolean);
341
- if (limits.length) parts.push(`limits ${limits.join(", ")}`);
376
+ if (limits.length) parts.push(`限额 ${limits.join(",")}`);
342
377
  if (calls !== undefined) {
343
- parts.push(`${calls} call${calls === 1 ? "" : "s"} today`);
378
+ parts.push(`今日 ${calls} 次调用`);
344
379
  }
345
380
  return {
346
- plan: textOf(tier.code) || keyLabel(key),
381
+ plan: tierLabel(tier.code) || keyLabel(key),
347
382
  balance: total === undefined ? "" : `$${usd(total)}`,
348
- windows: [{ name: "D.AI balance", display: parts.join(" · ") }],
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} call${total === 1 ? "" : "s"}`];
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
- textOf(last.status),
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 calls", display: parts.join(" · ") }],
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 key", placeholder: "ddsk_…" }],
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: sign in with an API key" };
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 refused the API key", signIn: "expired" };
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@d-ai/magpie",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "D.AI (dai.itbug.shop) chat models in magpie and OpenCode, plus a read-only image/video/audio model catalog",
5
5
  "type": "module",
6
6
  "main": "./index.mjs",