@acosmi/sdk-ts 2.7.0 → 2.9.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/dist/index.mjs CHANGED
@@ -1259,10 +1259,17 @@ async function authorize(meta, clientID, scopes, opts = {}) {
1259
1259
  codeRejecter(new Error(`authorization denied: ${errMsg}`));
1260
1260
  return;
1261
1261
  }
1262
- res.setHeader("Content-Type", "text/html; charset=utf-8");
1263
- res.end(
1264
- `<!DOCTYPE html><html><head><meta charset="utf-8"><title>\u6388\u6743\u6210\u529F</title></head><body style="font-family:system-ui,sans-serif;text-align:center;padding:60px 20px"><h2>\u6388\u6743\u6210\u529F</h2><p>\u5DF2\u5B8C\u6210\u8EAB\u4EFD\u8BA4\u8BC1, \u8BF7\u8FD4\u56DE\u5E94\u7528\u7EE7\u7EED\u4F7F\u7528\u3002</p><p style="color:#888;font-size:14px">\u6B64\u7A97\u53E3\u5C06\u5728 3 \u79D2\u540E\u81EA\u52A8\u5173\u95ED\u2026</p><script>setTimeout(function(){window.close()},3000)</script></body></html>`
1265
- );
1262
+ const successRedirect = resolveSuccessRedirect(opts.successRedirectURL);
1263
+ if (successRedirect) {
1264
+ res.statusCode = 302;
1265
+ res.setHeader("Location", successRedirect);
1266
+ res.end();
1267
+ } else {
1268
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
1269
+ res.end(
1270
+ `<!DOCTYPE html><html><head><meta charset="utf-8"><title>\u6388\u6743\u6210\u529F</title></head><body style="font-family:system-ui,sans-serif;text-align:center;padding:60px 20px"><h2>\u6388\u6743\u6210\u529F</h2><p>\u5DF2\u5B8C\u6210\u8EAB\u4EFD\u8BA4\u8BC1, \u8BF7\u8FD4\u56DE\u5E94\u7528\u7EE7\u7EED\u4F7F\u7528\u3002</p><p style="color:#888;font-size:14px">\u6B64\u7A97\u53E3\u5C06\u5728 3 \u79D2\u540E\u81EA\u52A8\u5173\u95ED\u2026</p><script>setTimeout(function(){window.close()},3000)</script></body></html>`
1271
+ );
1272
+ }
1266
1273
  codeResolver(code);
1267
1274
  });
1268
1275
  const authURL = new URL(meta.authorization_endpoint);
@@ -1324,6 +1331,16 @@ async function authorize(meta, clientID, scopes, opts = {}) {
1324
1331
  function htmlEscape(s) {
1325
1332
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
1326
1333
  }
1334
+ function resolveSuccessRedirect(raw) {
1335
+ if (!raw) return null;
1336
+ try {
1337
+ const u = new URL(raw);
1338
+ if (u.protocol !== "http:" && u.protocol !== "https:") return null;
1339
+ return u.toString();
1340
+ } catch {
1341
+ return null;
1342
+ }
1343
+ }
1327
1344
  async function createWebAuthorizationRequest(meta, opts) {
1328
1345
  const verifier = await generateCodeVerifier();
1329
1346
  const challenge = await codeChallenge(verifier);
@@ -2662,8 +2679,8 @@ var Client = class _Client {
2662
2679
  * V30 二轮审计 D-P1-2: 此方法不返回 entitlement-filter-status header.
2663
2680
  * UI 想根据 fallback 状态显示降级提示, 请改调 listModelsWithStatus.
2664
2681
  */
2665
- async listModels(signal) {
2666
- const r = await this.listModelsWithStatus(signal);
2682
+ async listModels(signal, opts) {
2683
+ const r = await this.listModelsWithStatus(signal, opts);
2667
2684
  return r.models;
2668
2685
  }
2669
2686
  /**
@@ -2676,16 +2693,20 @@ var Client = class _Client {
2676
2693
  * - status === 'disabled-by-flag' → 不显示余量 (运维灰度中)
2677
2694
  * - status === '' (Unknown) → 老 nexus, 按老 v0.17 行为 (不显示 BucketInfo)
2678
2695
  */
2679
- async listModelsWithStatus(signal) {
2696
+ async listModelsWithStatus(signal, opts) {
2697
+ const includeLocked = opts?.includeLocked === true;
2698
+ const path = includeLocked ? "/managed-models?picker=1" : "/managed-models";
2680
2699
  const { result, headers } = await this.doJSONFull(
2681
2700
  "GET",
2682
- "/managed-models",
2701
+ path,
2683
2702
  null,
2684
2703
  signal
2685
2704
  );
2686
2705
  const normalized = normalizeInputModalities(result.data);
2687
- this.modelCache = normalized;
2688
- this.modelCacheTimeMs = Date.now();
2706
+ if (!includeLocked) {
2707
+ this.modelCache = normalized;
2708
+ this.modelCacheTimeMs = Date.now();
2709
+ }
2689
2710
  let status = "";
2690
2711
  if (headers) {
2691
2712
  const h = headers.get("X-Entitlement-Filter-Status");
@@ -2880,6 +2901,34 @@ var Client = class _Client {
2880
2901
  const { result } = await this.doJSONFullRaw("GET", endpoint, null, signal);
2881
2902
  return this.unwrapAPIResponse(result);
2882
2903
  }
2904
+ /**
2905
+ * 向量 (同步)。POST /managed-models/:id/embeddings
2906
+ *
2907
+ * 仅 capabilities.supports_embedding=true 的托管模型可用 (上游接 DashScope)。
2908
+ * 响应为 OpenAI /v1/embeddings 标准格式 (网关直通, 无 response.Success 包装)。
2909
+ *
2910
+ * @param modelID 向量托管模型 ID
2911
+ */
2912
+ async embeddings(modelID, req, signal) {
2913
+ const endpoint = `/managed-models/${encodeURIComponent(modelID)}/embeddings`;
2914
+ const { result } = await this.doJSONFullRaw("POST", endpoint, req, signal, CHAT_REQUEST_TIMEOUT_MS);
2915
+ return JSON.parse(new TextDecoder().decode(result));
2916
+ }
2917
+ /**
2918
+ * 重排序 (同步)。POST /managed-models/:id/rerank
2919
+ *
2920
+ * 仅 capabilities.supports_rerank=true 的托管模型可用 (上游接 DashScope)。
2921
+ * 统一扁平契约: { query, documents[], top_n?, return_documents?, instruct? };
2922
+ * 响应 { results: [{ index, relevance_score, document? }], usage, model }
2923
+ * (网关已把上游原生/OpenAI 兼容两线路归一化, 无 response.Success 包装)。
2924
+ *
2925
+ * @param modelID 重排序托管模型 ID
2926
+ */
2927
+ async rerank(modelID, req, signal) {
2928
+ const endpoint = `/managed-models/${encodeURIComponent(modelID)}/rerank`;
2929
+ const { result } = await this.doJSONFullRaw("POST", endpoint, req, signal, CHAT_REQUEST_TIMEOUT_MS);
2930
+ return JSON.parse(new TextDecoder().decode(result));
2931
+ }
2883
2932
  /**
2884
2933
  * Anthropic 原生格式同步聊天
2885
2934
  * v0.5.0: 根据 provider 自动路由