@psnext/slingcli 2.5.20260725-1 → 2.5.20260727-1

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 (30) hide show
  1. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  2. package/node_modules/@earendil-works/pi-ai/dist/api/bedrock-converse-stream.js +8 -3
  3. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/radius.js +37 -35
  4. package/node_modules/@earendil-works/pi-ai/dist/auth/resolve.js +11 -1
  5. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  6. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  7. package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.json +1 -1
  8. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  9. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  10. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  11. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  12. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  13. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  14. package/node_modules/@earendil-works/pi-ai/dist/utils/error-body.js +8 -3
  15. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  16. package/node_modules/@earendil-works/pi-coding-agent/dist/core/model-resolver.js +13 -3
  17. package/node_modules/@earendil-works/pi-coding-agent/dist/core/remote-catalog-provider.js +19 -1
  18. package/node_modules/@earendil-works/pi-coding-agent/dist/core/resource-loader.js +3 -0
  19. package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js +4 -4
  20. package/node_modules/@earendil-works/pi-coding-agent/dist/extensions/llama/provider.js +6 -0
  21. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/custom-message.js +10 -2
  22. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +22 -13
  23. package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +38 -27
  24. package/node_modules/@earendil-works/pi-coding-agent/npm-shrinkwrap.json +12 -12
  25. package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -5
  26. package/node_modules/@earendil-works/pi-server/package.json +2 -2
  27. package/node_modules/@earendil-works/pi-tui/dist/tui.js +1 -1
  28. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  29. package/package.json +7 -7
  30. package/slingshot/index.js +164 -164
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-agent-core",
3
- "version": "0.82.0",
3
+ "version": "0.82.1",
4
4
  "description": "General-purpose agent with transport abstraction, state management, and attachment support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -29,7 +29,7 @@
29
29
  "prepublishOnly": "npm run build"
30
30
  },
31
31
  "dependencies": {
32
- "@earendil-works/pi-ai": "^0.82.0",
32
+ "@earendil-works/pi-ai": "^0.82.1",
33
33
  "diff": "8.0.4",
34
34
  "ignore": "7.0.5",
35
35
  "typebox": "1.1.38",
@@ -432,13 +432,18 @@ function supportsAdaptiveThinking(modelId, modelName) {
432
432
  return candidates.some((s) => s.includes("opus-4-6") ||
433
433
  s.includes("opus-4-7") ||
434
434
  s.includes("opus-4-8") ||
435
+ s.includes("opus-5") ||
435
436
  s.includes("sonnet-4-6") ||
436
437
  s.includes("sonnet-5") ||
437
438
  s.includes("fable-5"));
438
439
  }
439
440
  function supportsNativeXhighEffort(model) {
440
441
  const candidates = getModelMatchCandidates(model.id, model.name);
441
- return candidates.some((s) => s.includes("opus-4-7") || s.includes("opus-4-8") || s.includes("sonnet-5") || s.includes("fable-5"));
442
+ return candidates.some((s) => s.includes("opus-4-7") ||
443
+ s.includes("opus-4-8") ||
444
+ s.includes("opus-5") ||
445
+ s.includes("sonnet-5") ||
446
+ s.includes("fable-5"));
442
447
  }
443
448
  function mapThinkingLevelToEffort(model, level) {
444
449
  if (level === "xhigh" && supportsNativeXhighEffort(model))
@@ -507,8 +512,8 @@ function supportsPromptCaching(model, env) {
507
512
  return true;
508
513
  return false;
509
514
  }
510
- // Claude 5 models (fable-5, sonnet-5)
511
- if (candidates.some((s) => s.includes("fable-5") || s.includes("sonnet-5")))
515
+ // Claude 5 models (fable-5, opus-5, sonnet-5)
516
+ if (candidates.some((s) => s.includes("fable-5") || s.includes("opus-5") || s.includes("sonnet-5")))
512
517
  return true;
513
518
  // Claude 4.x models (opus-4, sonnet-4, haiku-4)
514
519
  if (candidates.some((s) => s.includes("-4-")))
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Radius gateway OAuth flow.
3
3
  *
4
- * Radius is a pi-messages gateway. OAuth endpoints are discovered from the
5
- * gateway (`/v1/oauth`); model catalog loading is owned by the Radius provider.
4
+ * Radius is a pi-messages gateway. OAuth client APIs live on the configured
5
+ * gateway; only the interactive browser authorization endpoint is discovered.
6
+ * Model catalog loading is owned by the Radius provider.
6
7
  *
7
8
  * NOTE: This module uses node:http for the OAuth callback server.
8
9
  * It is only intended for CLI use, not browser environments.
@@ -25,14 +26,21 @@ const REDIRECT_URI = `http://${CALLBACK_HOST}:${CALLBACK_PORT}${CALLBACK_PATH}`;
25
26
  const TOKEN_EXPIRY_SKEW_MS = 60_000;
26
27
  const LOGIN_METHOD_BROWSER = "browser";
27
28
  const LOGIN_METHOD_DEVICE_CODE = "device-code";
28
- async function loadRadiusOAuthConfig(gateway) {
29
+ const OAUTH_CLIENT_ID = "pi-gateway";
30
+ const OAUTH_SCOPE = "gateway offline_access";
31
+ const OAUTH_DEVICE_CODE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
32
+ async function loadRadiusOAuthDiscovery(gateway) {
29
33
  const response = await fetch(new URL("/v1/oauth", gateway), {
30
34
  headers: { accept: "application/json" },
31
35
  });
32
36
  if (!response.ok) {
33
37
  throw new Error(`Could not load Radius OAuth config from ${gateway}: ${response.status} ${await response.text()}`);
34
38
  }
35
- return (await response.json());
39
+ const discovery = (await response.json());
40
+ if (typeof discovery.authorizationEndpoint !== "string") {
41
+ throw new Error(`Invalid Radius OAuth config from ${gateway}`);
42
+ }
43
+ return { authorizationEndpoint: discovery.authorizationEndpoint };
36
44
  }
37
45
  class OAuthResponseError extends Error {
38
46
  status;
@@ -64,10 +72,10 @@ async function readOAuthResponseError(response, message) {
64
72
  }
65
73
  return new OAuthResponseError(response.status, oauthError, description, message);
66
74
  }
67
- async function requestOAuthToken(oauth, body, signal) {
75
+ async function requestOAuthToken(gateway, body, signal) {
68
76
  let response;
69
77
  try {
70
- response = await fetch(oauth.tokenEndpoint, {
78
+ response = await fetch(new URL("/v1/oauth/token", gateway), {
71
79
  method: "POST",
72
80
  headers: { accept: "application/json", "content-type": "application/x-www-form-urlencoded" },
73
81
  body,
@@ -157,15 +165,15 @@ function startOAuthCallbackServer(expectedState, signal) {
157
165
  });
158
166
  });
159
167
  }
160
- async function loginWithBrowser(oauth, interaction) {
168
+ async function loginWithBrowser(gateway, authorizationEndpoint, interaction) {
161
169
  const { verifier, challenge } = await generatePKCE();
162
170
  const state = crypto.randomUUID();
163
- const authorizeUrl = new URL(oauth.authorizationEndpoint);
171
+ const authorizeUrl = new URL(authorizationEndpoint);
164
172
  authorizeUrl.search = new URLSearchParams({
165
173
  response_type: "code",
166
- client_id: oauth.clientId,
174
+ client_id: OAUTH_CLIENT_ID,
167
175
  redirect_uri: REDIRECT_URI,
168
- scope: oauth.scope,
176
+ scope: OAUTH_SCOPE,
169
177
  code_challenge: challenge,
170
178
  code_challenge_method: "S256",
171
179
  handoff: "url",
@@ -186,9 +194,9 @@ async function loginWithBrowser(oauth, interaction) {
186
194
  }
187
195
  throw new Error("OAuth callback did not complete.");
188
196
  }
189
- return await requestOAuthToken(oauth, new URLSearchParams({
197
+ return await requestOAuthToken(gateway, new URLSearchParams({
190
198
  grant_type: "authorization_code",
191
- client_id: oauth.clientId,
199
+ client_id: OAUTH_CLIENT_ID,
192
200
  redirect_uri: REDIRECT_URI,
193
201
  code,
194
202
  code_verifier: verifier,
@@ -198,13 +206,13 @@ async function loginWithBrowser(oauth, interaction) {
198
206
  callbackServer.close();
199
207
  }
200
208
  }
201
- async function requestDeviceAuthorization(oauth, signal) {
209
+ async function requestDeviceAuthorization(gateway, signal) {
202
210
  let response;
203
211
  try {
204
- response = await fetch(oauth.deviceAuthorizationEndpoint, {
212
+ response = await fetch(new URL("/v1/oauth/device", gateway), {
205
213
  method: "POST",
206
214
  headers: { accept: "application/json", "content-type": "application/x-www-form-urlencoded" },
207
- body: new URLSearchParams({ client_id: oauth.clientId, scope: oauth.scope }),
215
+ body: new URLSearchParams({ client_id: OAUTH_CLIENT_ID, scope: OAUTH_SCOPE }),
208
216
  signal,
209
217
  });
210
218
  }
@@ -218,24 +226,23 @@ async function requestDeviceAuthorization(oauth, signal) {
218
226
  throw await readOAuthResponseError(response, "Radius OAuth device authorization failed");
219
227
  }
220
228
  const data = (await response.json());
221
- if (!data.device_code || !data.user_code || !data.expires_in) {
229
+ if (!data.device_code || !data.user_code || !data.verification_uri || !data.expires_in) {
222
230
  throw new Error("Radius OAuth device authorization response is missing required fields");
223
231
  }
224
232
  return {
225
233
  device_code: data.device_code,
226
234
  user_code: data.user_code,
227
235
  verification_uri: data.verification_uri,
228
- verification_uri_complete: data.verification_uri_complete,
229
236
  expires_in: data.expires_in,
230
237
  interval: data.interval,
231
238
  };
232
239
  }
233
- async function loginWithDeviceCode(oauth, interaction) {
234
- const device = await requestDeviceAuthorization(oauth, interaction.signal);
240
+ async function loginWithDeviceCode(gateway, interaction) {
241
+ const device = await requestDeviceAuthorization(gateway, interaction.signal);
235
242
  interaction.notify({
236
243
  type: "device_code",
237
244
  userCode: device.user_code,
238
- verificationUri: device.verification_uri || oauth.verificationEndpoint,
245
+ verificationUri: device.verification_uri,
239
246
  intervalSeconds: device.interval,
240
247
  expiresInSeconds: device.expires_in,
241
248
  });
@@ -245,9 +252,9 @@ async function loginWithDeviceCode(oauth, interaction) {
245
252
  signal: interaction.signal,
246
253
  poll: async () => {
247
254
  try {
248
- const credentials = await requestOAuthToken(oauth, new URLSearchParams({
249
- grant_type: oauth.deviceCodeGrantType,
250
- client_id: oauth.clientId,
255
+ const credentials = await requestOAuthToken(gateway, new URLSearchParams({
256
+ grant_type: OAUTH_DEVICE_CODE_GRANT_TYPE,
257
+ client_id: OAUTH_CLIENT_ID,
251
258
  device_code: device.device_code,
252
259
  }), interaction.signal);
253
260
  return { status: "complete", value: credentials };
@@ -277,7 +284,6 @@ export function createRadiusOAuth(options) {
277
284
  return {
278
285
  name: options.name,
279
286
  async login(interaction) {
280
- const oauth = await loadRadiusOAuthConfig(gateway);
281
287
  const loginMethod = await interaction.prompt({
282
288
  type: "select",
283
289
  message: `Sign in to ${options.name}:`,
@@ -289,23 +295,19 @@ export function createRadiusOAuth(options) {
289
295
  },
290
296
  ],
291
297
  });
292
- let credential;
293
298
  if (loginMethod === LOGIN_METHOD_DEVICE_CODE) {
294
- credential = await loginWithDeviceCode(oauth, interaction);
295
- }
296
- else if (loginMethod === LOGIN_METHOD_BROWSER) {
297
- credential = await loginWithBrowser(oauth, interaction);
299
+ return loginWithDeviceCode(gateway, interaction);
298
300
  }
299
- else {
300
- throw new Error(`Unknown ${options.name} sign-in method: ${loginMethod}`);
301
+ if (loginMethod === LOGIN_METHOD_BROWSER) {
302
+ const discovery = await loadRadiusOAuthDiscovery(gateway);
303
+ return loginWithBrowser(gateway, discovery.authorizationEndpoint, interaction);
301
304
  }
302
- return credential;
305
+ throw new Error(`Unknown ${options.name} sign-in method: ${loginMethod}`);
303
306
  },
304
307
  async refresh(credential, signal) {
305
- const oauth = await loadRadiusOAuthConfig(gateway);
306
- const refreshed = await requestOAuthToken(oauth, new URLSearchParams({
308
+ const refreshed = await requestOAuthToken(gateway, new URLSearchParams({
307
309
  grant_type: "refresh_token",
308
- client_id: oauth.clientId,
310
+ client_id: OAUTH_CLIENT_ID,
309
311
  refresh_token: credential.refresh,
310
312
  }), signal);
311
313
  return refreshed;
@@ -1,11 +1,21 @@
1
+ import { formatThrownValue } from "../utils/diagnostics.js";
1
2
  export class ModelsError extends Error {
2
3
  code;
3
4
  constructor(code, message, options) {
4
- super(message, options);
5
+ super(withCauseDetail(message, options?.cause), options);
5
6
  this.name = "ModelsError";
6
7
  this.code = code;
7
8
  }
8
9
  }
10
+ /** Callers surface `error.message` only, so keep the underlying reason in it. */
11
+ function withCauseDetail(message, cause) {
12
+ if (cause === undefined || cause === null)
13
+ return message;
14
+ const detail = formatThrownValue(cause).trim();
15
+ if (!detail || message.includes(detail))
16
+ return message;
17
+ return `${message}: ${detail}`;
18
+ }
9
19
  /**
10
20
  * Auth resolution shared by the `Models` and `ImagesModels` collections.
11
21
  * A stored credential owns the provider: ambient/env is consulted only when
@@ -1 +1 @@
1
- {"schemaVersion":3,"generatedAt":"2026-07-25T04:49:49.529Z","structureHash":"7da5294256e6c090a31898f6395e37190af6a91e1967ece9eb5bac23f88509d4","files":{"amazon-bedrock.json":"dcd1ea8bd2cd948f8f5b2e6dd1ea97dc9678848a32eac6c157a540ff164d05ef","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"830afd9b99a5f7306903858e4b6fb49f6e28573ab73338c7a876eff69dd0b269","azure-openai-responses.json":"2d13ecc23826b5be73f3628fca5f70cc2c5c15ff609b41e4acba8167cd40934b","cerebras.json":"3fd3e19b83ab4be07d27817e25e5be0ffe4158b1394f0311d6a22d9f03847728","cloudflare-ai-gateway.json":"9974b65a0c6dda063ea3a30f4a819cab7bf70f9a25e5e3ee2feaf85cfc167b9b","cloudflare-workers-ai.json":"03b19d69433c843512e953390d51d4578e9b91f19098a9b14ff820c001623598","deepseek.json":"0dcc807a4e5827b488c6ceac87884ff6e735e01cf4f2ddfec9dd812e6fde041b","fireworks.json":"0ea306d50e72343439f71995dcda0776473e0e43a8500c4ff42769f085fee09d","github-copilot.json":"62a6256926ef2cb44e717ad30031dfbe2c3777ed38fd0db24e48b01666254a6c","google-vertex.json":"99d0b89ac9d8dc460ed922236abffbe88c9381af4d35046d2ad3a8f08fa2560c","google.json":"bcf8a8d59ccbb75bc6fb4a261a37ac4b7c806f40ee7313b4411178964be5fa37","groq.json":"868c90a897f75f866e09a585f6aee5cb991e40a9c3281497b5842a23de7d9add","huggingface.json":"e001db7b5925939c5850f31cd08b323cd40eb586222e2f74d7890eb52a30f161","kimi-coding.json":"ba42a26a69e5cb2122c0b384ba572efae93f42239ad86f26c2b7320a14aa75a1","minimax-cn.json":"8ccd71ff838f4b78bb88809babb0dc32a4fcfaec2bc4f4083841000428df4f77","minimax.json":"253edd4c910a41c8bb252400ba099f3a4de0a8900ce154319288ab091b372987","mistral.json":"44531201e872713923b7544a1f75a048d31fa25292e3e1f9f896f608a52e412d","moonshotai-cn.json":"1e6146ff3477883636448c0f44222f0a52b3c4562ef8f4eecf7e941cdd59d12e","moonshotai.json":"d8d5209873058ddccd37c1f026833e2ea3f9476c3dc9628b4a940d407acc0b2e","nvidia.json":"f476e23d9c3743c8ed3bb24a7d43b33cf90d1539ebe61c070ea2323555853e25","openai-codex.json":"c3313710bc6910e6bbcb06d5867247e97ec3fa6c2af9bc780f8a3eefb03e32e1","openai.json":"8e3852ef3567b23d2ab03b0f52f1caeb77e6e776f248e6111f851ccbe0fca8b6","opencode-go.json":"57a677764bc885c83fbbba46ad5d418baabe012a062424a0f6d8d488352102ce","opencode.json":"080500ebc60933e415c05f6e1a4e5fcc1751571ec1a46fea3d0289445257866d","openrouter.json":"3be497ceaa7ec70a2689a73f505b2abce55385c09e09a648020b2cb93a56cfa0","qwen-token-plan-cn.json":"a1495ccc21835c51d438207652f948aa9ecf4a3d784e81deaf313e484bdab1ec","qwen-token-plan.json":"597fae649f549a8ffb0b6a28426ea6761b7ece41a78b6fdef49ca970ac029970","together.json":"1d46a57e99da9be6f7e78d8f98f5610adbb266df3de7b0a13652d6fa175086e7","vercel-ai-gateway.json":"d4802bd7cf1905103c03b5819c1cbc6b55dec57d76f8330bd76baff1189a0b58","xai.json":"4cbdbfbbf915246369b9bacbc6f1feeb56accdac9f3444456343f750547f2f38","xiaomi-token-plan-ams.json":"7ce8ed244672c45737d286ff3ca9c3a2686a5d4b2f0c5f71ab9348c14b14daf3","xiaomi-token-plan-cn.json":"684892b5fe6fa371d6040d2011c0fa33facd650d2eaf19f5dbee8efb33016200","xiaomi-token-plan-sgp.json":"b19e79b82ac4fdcb080e6d220106797504c885ed70b27fc2b3c1aa4810f32963","xiaomi.json":"810368d3828c8bb9498012a0d48639030c0c216b8c13e79da02daa515aa23448","zai-coding-cn.json":"28fcb04ce65b4c6612a6b866902e0c832e18b685e5374578c4e2872569131d39","zai.json":"474670a0cf1109f4c296ea93d2c5c6eb8f53541dc9c0bddbb0e6cb054b971ebe"}}
1
+ {"schemaVersion":3,"generatedAt":"2026-07-27T03:47:01.896Z","structureHash":"af3ded7a9ebefec1131521259cd58cea6f00df4283da89abfb4de141e3519b7f","files":{"amazon-bedrock.json":"1aabd3227d32b332727eec7638cebdbd1323d2e7eedbf9b174226c5d38196df9","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"fea1226a62396c8d4a3d9c3b7f65d4dc527ac025d05719880418d3a2b0665a69","azure-openai-responses.json":"2d13ecc23826b5be73f3628fca5f70cc2c5c15ff609b41e4acba8167cd40934b","cerebras.json":"3fd3e19b83ab4be07d27817e25e5be0ffe4158b1394f0311d6a22d9f03847728","cloudflare-ai-gateway.json":"692b375a3bcb11743a9c1899442caecc3861163d9424356d3d073d9fa5c04091","cloudflare-workers-ai.json":"03b19d69433c843512e953390d51d4578e9b91f19098a9b14ff820c001623598","deepseek.json":"0dcc807a4e5827b488c6ceac87884ff6e735e01cf4f2ddfec9dd812e6fde041b","fireworks.json":"0ea306d50e72343439f71995dcda0776473e0e43a8500c4ff42769f085fee09d","github-copilot.json":"1215a0792908480ff709a26954b1c4b76bcfec5d31f31d0843d505770c764c1e","google-vertex.json":"99d0b89ac9d8dc460ed922236abffbe88c9381af4d35046d2ad3a8f08fa2560c","google.json":"bcf8a8d59ccbb75bc6fb4a261a37ac4b7c806f40ee7313b4411178964be5fa37","groq.json":"868c90a897f75f866e09a585f6aee5cb991e40a9c3281497b5842a23de7d9add","huggingface.json":"e001db7b5925939c5850f31cd08b323cd40eb586222e2f74d7890eb52a30f161","kimi-coding.json":"ba42a26a69e5cb2122c0b384ba572efae93f42239ad86f26c2b7320a14aa75a1","minimax-cn.json":"8ccd71ff838f4b78bb88809babb0dc32a4fcfaec2bc4f4083841000428df4f77","minimax.json":"253edd4c910a41c8bb252400ba099f3a4de0a8900ce154319288ab091b372987","mistral.json":"44531201e872713923b7544a1f75a048d31fa25292e3e1f9f896f608a52e412d","moonshotai-cn.json":"1e6146ff3477883636448c0f44222f0a52b3c4562ef8f4eecf7e941cdd59d12e","moonshotai.json":"d8d5209873058ddccd37c1f026833e2ea3f9476c3dc9628b4a940d407acc0b2e","nvidia.json":"79482f617066917a4525f78c19738c3b392e1e2e35c9d8ba3183b874bb504463","openai-codex.json":"c3313710bc6910e6bbcb06d5867247e97ec3fa6c2af9bc780f8a3eefb03e32e1","openai.json":"8e3852ef3567b23d2ab03b0f52f1caeb77e6e776f248e6111f851ccbe0fca8b6","opencode-go.json":"57a677764bc885c83fbbba46ad5d418baabe012a062424a0f6d8d488352102ce","opencode.json":"905b27bf3d7e48f35ca862991411b97a93782ad92b24129a2c3ee377fd1e3675","openrouter.json":"3dcc960f1fe6a84e6e1773425884195a70c43e5364bc34ae1f411d52072631e1","qwen-token-plan-cn.json":"a1495ccc21835c51d438207652f948aa9ecf4a3d784e81deaf313e484bdab1ec","qwen-token-plan.json":"597fae649f549a8ffb0b6a28426ea6761b7ece41a78b6fdef49ca970ac029970","together.json":"1d46a57e99da9be6f7e78d8f98f5610adbb266df3de7b0a13652d6fa175086e7","vercel-ai-gateway.json":"61242947db49d08e4a70ccf4cd16eea9d58758effc35c2f6abdd953f8da64013","xai.json":"4cbdbfbbf915246369b9bacbc6f1feeb56accdac9f3444456343f750547f2f38","xiaomi-token-plan-ams.json":"7ce8ed244672c45737d286ff3ca9c3a2686a5d4b2f0c5f71ab9348c14b14daf3","xiaomi-token-plan-cn.json":"684892b5fe6fa371d6040d2011c0fa33facd650d2eaf19f5dbee8efb33016200","xiaomi-token-plan-sgp.json":"b19e79b82ac4fdcb080e6d220106797504c885ed70b27fc2b3c1aa4810f32963","xiaomi.json":"810368d3828c8bb9498012a0d48639030c0c216b8c13e79da02daa515aa23448","zai-coding-cn.json":"28fcb04ce65b4c6612a6b866902e0c832e18b685e5374578c4e2872569131d39","zai.json":"474670a0cf1109f4c296ea93d2c5c6eb8f53541dc9c0bddbb0e6cb054b971ebe"}}