@acosmi/sdk-ts 1.3.2 → 1.4.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.
@@ -1,4 +1,4 @@
1
- import { P as ProviderAdapter, ak as ProviderFormat, c as ModelCapabilities, d as ChatRequest, e as ChatResponse, f as StreamEvent } from '../index-28x02ITB.cjs';
1
+ import { P as ProviderAdapter, ak as ProviderFormat, c as ModelCapabilities, d as ChatRequest, e as ChatResponse, f as StreamEvent } from '../index-CbG9NqE-.cjs';
2
2
 
3
3
  /** 实现 ProviderAdapter, 用于 Anthropic 原生模型 */
4
4
  declare class AnthropicAdapter implements ProviderAdapter {
@@ -1,4 +1,4 @@
1
- import { P as ProviderAdapter, ak as ProviderFormat, c as ModelCapabilities, d as ChatRequest, e as ChatResponse, f as StreamEvent } from '../index-28x02ITB.js';
1
+ import { P as ProviderAdapter, ak as ProviderFormat, c as ModelCapabilities, d as ChatRequest, e as ChatResponse, f as StreamEvent } from '../index-CbG9NqE-.js';
2
2
 
3
3
  /** 实现 ProviderAdapter, 用于 Anthropic 原生模型 */
4
4
  declare class AnthropicAdapter implements ProviderAdapter {
@@ -1,4 +1,4 @@
1
- import { P as ProviderAdapter, ak as ProviderFormat, c as ModelCapabilities, d as ChatRequest, e as ChatResponse, f as StreamEvent, A as AnthropicResponse } from '../index-28x02ITB.cjs';
1
+ import { P as ProviderAdapter, ak as ProviderFormat, c as ModelCapabilities, d as ChatRequest, e as ChatResponse, f as StreamEvent, A as AnthropicResponse } from '../index-CbG9NqE-.cjs';
2
2
 
3
3
  /** 实现 ProviderAdapter, 用于所有非 Anthropic 厂商 */
4
4
  declare class OpenAIAdapter implements ProviderAdapter {
@@ -1,4 +1,4 @@
1
- import { P as ProviderAdapter, ak as ProviderFormat, c as ModelCapabilities, d as ChatRequest, e as ChatResponse, f as StreamEvent, A as AnthropicResponse } from '../index-28x02ITB.js';
1
+ import { P as ProviderAdapter, ak as ProviderFormat, c as ModelCapabilities, d as ChatRequest, e as ChatResponse, f as StreamEvent, A as AnthropicResponse } from '../index-CbG9NqE-.js';
2
2
 
3
3
  /** 实现 ProviderAdapter, 用于所有非 Anthropic 厂商 */
4
4
  declare class OpenAIAdapter implements ProviderAdapter {
@@ -1024,4 +1024,4 @@ declare function getAdapter(provider: string): ProviderAdapter;
1024
1024
  */
1025
1025
  declare function getAdapterForModel(m: ManagedModel): ProviderAdapter;
1026
1026
 
1027
- export { type ChatUsage as $, type AnthropicResponse as A, BusinessError as B, type ClientRegistration as C, type ToolView as D, type EntitlementBalance as E, type DeviceRegistration as F, type GenerateSkillRequest as G, type NotificationPreference as H, type InputModality as I, type WSEvent as J, type APIResponse as K, type AnthropicContentBlock as L, type ManagedModel as M, type NotificationList as N, type Order as O, type ProviderAdapter as P, type QuotaSummary as Q, type AnthropicUsage as R, type ServerMetadata as S, type TokenResponse as T, BucketClassCommercial as U, BucketClassGeneric as V, type WalletStats as W, type BucketInfo as X, type BucketRow as Y, type ChatContentBlock as Z, type ChatMessage as _, type TokenSet as a, type ConsumeRecord as a0, type EffortConfig as a1, type GeoLoc as a2, HTTPError as a3, ModelNotFoundError as a4, NetworkError as a5, type Notification as a6, type NotificationUnreadCount as a7, type OpenAIChatChoice as a8, type OpenAIChatMessage as a9, type YudaoPageResult as aA, anthropicResponseTextContent as aB, anthropicResponseThinkingContent as aC, anthropicResponseToolUseBlocks as aD, apiResponseBusinessError as aE, apiResponseGetMessage as aF, bucketInfoIsCommercial as aG, bucketRowIsCommercial as aH, getAdapter as aI, getAdapterForModel as aJ, newThinkingConfig as aK, newWebSearchTool as aL, parseNotificationEvent as aM, parseSettlement as aN, parseSourcesEvent as aO, tokenSetIsExpired as aP, type OpenAIChatResponse as aa, type OpenAIFunctionCall as ab, type OpenAIStreamChoice as ac, type OpenAIStreamChunk as ad, type OpenAIStreamDelta as ae, type OpenAIStreamToolCall as af, type OpenAIToolCall as ag, type OpenAIUsage as ah, OrderTerminalError as ai, type OutputConfig as aj, ProviderFormat as ak, RateLimitError as al, type ServerTool as am, ServerToolTypeWebSearch as an, type SkillStoreListItem as ao, StreamError as ap, type ThinkingConfig as aq, ThinkingHigh as ar, ThinkingHighMinMaxTokens as as, ThinkingMax as at, ThinkingMaxFallbackMaxTokens as au, ThinkingOff as av, type ToolListResponse as aw, type ToolProvider as ax, type WebSearchConfig as ay, type WebSearchSource as az, type ModelCoefficient as b, type ModelCapabilities as c, type ChatRequest as d, type ChatResponse as e, type StreamEvent as f, type SourcesEvent as g, type StreamSettlement as h, type BalanceDetail as i, type EntitlementItem as j, type ConsumeRecordPage as k, type ModelByQuotaResponse as l, type ModelBucket as m, type TokenPackage as n, type PayPayload as o, type OrderStatus as p, type Transaction as q, type SkillStoreQuery as r, type SkillStoreItem as s, type SkillBrowseResponse as t, type SkillBrowseListResponse as u, type SkillSummary as v, type CertificationStatus as w, type GenerateSkillResult as x, type OptimizeSkillRequest as y, type OptimizeSkillResult as z };
1027
+ export { type ChatUsage as $, type AnthropicResponse as A, BusinessError as B, type ClientRegistration as C, type ToolView as D, type EntitlementBalance as E, type DeviceRegistration as F, type GenerateSkillRequest as G, type NotificationPreference as H, type InputModality as I, type WSEvent as J, type APIResponse as K, type AnthropicContentBlock as L, type ManagedModel as M, type NotificationList as N, type Order as O, type ProviderAdapter as P, type QuotaSummary as Q, type AnthropicUsage as R, type ServerMetadata as S, type TokenSet as T, BucketClassCommercial as U, BucketClassGeneric as V, type WalletStats as W, type BucketInfo as X, type BucketRow as Y, type ChatContentBlock as Z, type ChatMessage as _, type TokenResponse as a, type ConsumeRecord as a0, type EffortConfig as a1, type GeoLoc as a2, HTTPError as a3, ModelNotFoundError as a4, NetworkError as a5, type Notification as a6, type NotificationUnreadCount as a7, type OpenAIChatChoice as a8, type OpenAIChatMessage as a9, type YudaoPageResult as aA, anthropicResponseTextContent as aB, anthropicResponseThinkingContent as aC, anthropicResponseToolUseBlocks as aD, apiResponseBusinessError as aE, apiResponseGetMessage as aF, bucketInfoIsCommercial as aG, bucketRowIsCommercial as aH, getAdapter as aI, getAdapterForModel as aJ, newThinkingConfig as aK, newWebSearchTool as aL, parseNotificationEvent as aM, parseSettlement as aN, parseSourcesEvent as aO, tokenSetIsExpired as aP, type OpenAIChatResponse as aa, type OpenAIFunctionCall as ab, type OpenAIStreamChoice as ac, type OpenAIStreamChunk as ad, type OpenAIStreamDelta as ae, type OpenAIStreamToolCall as af, type OpenAIToolCall as ag, type OpenAIUsage as ah, OrderTerminalError as ai, type OutputConfig as aj, ProviderFormat as ak, RateLimitError as al, type ServerTool as am, ServerToolTypeWebSearch as an, type SkillStoreListItem as ao, StreamError as ap, type ThinkingConfig as aq, ThinkingHigh as ar, ThinkingHighMinMaxTokens as as, ThinkingMax as at, ThinkingMaxFallbackMaxTokens as au, ThinkingOff as av, type ToolListResponse as aw, type ToolProvider as ax, type WebSearchConfig as ay, type WebSearchSource as az, type ModelCoefficient as b, type ModelCapabilities as c, type ChatRequest as d, type ChatResponse as e, type StreamEvent as f, type SourcesEvent as g, type StreamSettlement as h, type BalanceDetail as i, type EntitlementItem as j, type ConsumeRecordPage as k, type ModelByQuotaResponse as l, type ModelBucket as m, type TokenPackage as n, type PayPayload as o, type OrderStatus as p, type Transaction as q, type SkillStoreQuery as r, type SkillStoreItem as s, type SkillBrowseResponse as t, type SkillBrowseListResponse as u, type SkillSummary as v, type CertificationStatus as w, type GenerateSkillResult as x, type OptimizeSkillRequest as y, type OptimizeSkillResult as z };
@@ -1024,4 +1024,4 @@ declare function getAdapter(provider: string): ProviderAdapter;
1024
1024
  */
1025
1025
  declare function getAdapterForModel(m: ManagedModel): ProviderAdapter;
1026
1026
 
1027
- export { type ChatUsage as $, type AnthropicResponse as A, BusinessError as B, type ClientRegistration as C, type ToolView as D, type EntitlementBalance as E, type DeviceRegistration as F, type GenerateSkillRequest as G, type NotificationPreference as H, type InputModality as I, type WSEvent as J, type APIResponse as K, type AnthropicContentBlock as L, type ManagedModel as M, type NotificationList as N, type Order as O, type ProviderAdapter as P, type QuotaSummary as Q, type AnthropicUsage as R, type ServerMetadata as S, type TokenResponse as T, BucketClassCommercial as U, BucketClassGeneric as V, type WalletStats as W, type BucketInfo as X, type BucketRow as Y, type ChatContentBlock as Z, type ChatMessage as _, type TokenSet as a, type ConsumeRecord as a0, type EffortConfig as a1, type GeoLoc as a2, HTTPError as a3, ModelNotFoundError as a4, NetworkError as a5, type Notification as a6, type NotificationUnreadCount as a7, type OpenAIChatChoice as a8, type OpenAIChatMessage as a9, type YudaoPageResult as aA, anthropicResponseTextContent as aB, anthropicResponseThinkingContent as aC, anthropicResponseToolUseBlocks as aD, apiResponseBusinessError as aE, apiResponseGetMessage as aF, bucketInfoIsCommercial as aG, bucketRowIsCommercial as aH, getAdapter as aI, getAdapterForModel as aJ, newThinkingConfig as aK, newWebSearchTool as aL, parseNotificationEvent as aM, parseSettlement as aN, parseSourcesEvent as aO, tokenSetIsExpired as aP, type OpenAIChatResponse as aa, type OpenAIFunctionCall as ab, type OpenAIStreamChoice as ac, type OpenAIStreamChunk as ad, type OpenAIStreamDelta as ae, type OpenAIStreamToolCall as af, type OpenAIToolCall as ag, type OpenAIUsage as ah, OrderTerminalError as ai, type OutputConfig as aj, ProviderFormat as ak, RateLimitError as al, type ServerTool as am, ServerToolTypeWebSearch as an, type SkillStoreListItem as ao, StreamError as ap, type ThinkingConfig as aq, ThinkingHigh as ar, ThinkingHighMinMaxTokens as as, ThinkingMax as at, ThinkingMaxFallbackMaxTokens as au, ThinkingOff as av, type ToolListResponse as aw, type ToolProvider as ax, type WebSearchConfig as ay, type WebSearchSource as az, type ModelCoefficient as b, type ModelCapabilities as c, type ChatRequest as d, type ChatResponse as e, type StreamEvent as f, type SourcesEvent as g, type StreamSettlement as h, type BalanceDetail as i, type EntitlementItem as j, type ConsumeRecordPage as k, type ModelByQuotaResponse as l, type ModelBucket as m, type TokenPackage as n, type PayPayload as o, type OrderStatus as p, type Transaction as q, type SkillStoreQuery as r, type SkillStoreItem as s, type SkillBrowseResponse as t, type SkillBrowseListResponse as u, type SkillSummary as v, type CertificationStatus as w, type GenerateSkillResult as x, type OptimizeSkillRequest as y, type OptimizeSkillResult as z };
1027
+ export { type ChatUsage as $, type AnthropicResponse as A, BusinessError as B, type ClientRegistration as C, type ToolView as D, type EntitlementBalance as E, type DeviceRegistration as F, type GenerateSkillRequest as G, type NotificationPreference as H, type InputModality as I, type WSEvent as J, type APIResponse as K, type AnthropicContentBlock as L, type ManagedModel as M, type NotificationList as N, type Order as O, type ProviderAdapter as P, type QuotaSummary as Q, type AnthropicUsage as R, type ServerMetadata as S, type TokenSet as T, BucketClassCommercial as U, BucketClassGeneric as V, type WalletStats as W, type BucketInfo as X, type BucketRow as Y, type ChatContentBlock as Z, type ChatMessage as _, type TokenResponse as a, type ConsumeRecord as a0, type EffortConfig as a1, type GeoLoc as a2, HTTPError as a3, ModelNotFoundError as a4, NetworkError as a5, type Notification as a6, type NotificationUnreadCount as a7, type OpenAIChatChoice as a8, type OpenAIChatMessage as a9, type YudaoPageResult as aA, anthropicResponseTextContent as aB, anthropicResponseThinkingContent as aC, anthropicResponseToolUseBlocks as aD, apiResponseBusinessError as aE, apiResponseGetMessage as aF, bucketInfoIsCommercial as aG, bucketRowIsCommercial as aH, getAdapter as aI, getAdapterForModel as aJ, newThinkingConfig as aK, newWebSearchTool as aL, parseNotificationEvent as aM, parseSettlement as aN, parseSourcesEvent as aO, tokenSetIsExpired as aP, type OpenAIChatResponse as aa, type OpenAIFunctionCall as ab, type OpenAIStreamChoice as ac, type OpenAIStreamChunk as ad, type OpenAIStreamDelta as ae, type OpenAIStreamToolCall as af, type OpenAIToolCall as ag, type OpenAIUsage as ah, OrderTerminalError as ai, type OutputConfig as aj, ProviderFormat as ak, RateLimitError as al, type ServerTool as am, ServerToolTypeWebSearch as an, type SkillStoreListItem as ao, StreamError as ap, type ThinkingConfig as aq, ThinkingHigh as ar, ThinkingHighMinMaxTokens as as, ThinkingMax as at, ThinkingMaxFallbackMaxTokens as au, ThinkingOff as av, type ToolListResponse as aw, type ToolProvider as ax, type WebSearchConfig as ay, type WebSearchSource as az, type ModelCoefficient as b, type ModelCapabilities as c, type ChatRequest as d, type ChatResponse as e, type StreamEvent as f, type SourcesEvent as g, type StreamSettlement as h, type BalanceDetail as i, type EntitlementItem as j, type ConsumeRecordPage as k, type ModelByQuotaResponse as l, type ModelBucket as m, type TokenPackage as n, type PayPayload as o, type OrderStatus as p, type Transaction as q, type SkillStoreQuery as r, type SkillStoreItem as s, type SkillBrowseResponse as t, type SkillBrowseListResponse as u, type SkillSummary as v, type CertificationStatus as w, type GenerateSkillResult as x, type OptimizeSkillRequest as y, type OptimizeSkillResult as z };
@@ -1058,7 +1058,7 @@ init_adapters();
1058
1058
 
1059
1059
  // src/auth.ts
1060
1060
  var authTimeoutMs = 3e4;
1061
- async function discover(serverURL, signal) {
1061
+ async function discoverWithProfile(serverURL, profile, signal) {
1062
1062
  let parsed;
1063
1063
  try {
1064
1064
  parsed = new URL(serverURL.replace(/\/+$/, ""));
@@ -1066,7 +1066,7 @@ async function discover(serverURL, signal) {
1066
1066
  throw new Error(`discover: invalid server URL: ${e instanceof Error ? e.message : String(e)}`);
1067
1067
  }
1068
1068
  const origin = `${parsed.protocol}//${parsed.host}`;
1069
- const endpoint = `${origin}/.well-known/oauth-authorization-server/desktop`;
1069
+ const endpoint = `${origin}/.well-known/oauth-authorization-server/${profile}`;
1070
1070
  const ctl = withTimeout(authTimeoutMs, signal);
1071
1071
  let resp;
1072
1072
  try {
@@ -1092,6 +1092,12 @@ async function discover(serverURL, signal) {
1092
1092
  }
1093
1093
  return meta;
1094
1094
  }
1095
+ async function discover(serverURL, signal) {
1096
+ return discoverWithProfile(serverURL, "desktop", signal);
1097
+ }
1098
+ async function discoverWebOAuthMetadata(serverURL, signal) {
1099
+ return discoverWithProfile(serverURL, "web", signal);
1100
+ }
1095
1101
  async function register(meta, appName, signal) {
1096
1102
  const regReq = {
1097
1103
  client_name: appName,
@@ -1123,12 +1129,50 @@ async function register(meta, appName, signal) {
1123
1129
  throw new Error(`register: decode: ${e instanceof Error ? e.message : String(e)}`);
1124
1130
  }
1125
1131
  }
1126
- async function generateCodeVerifier() {
1132
+ async function registerWebOAuthClient(meta, opts, signal) {
1133
+ const regReq = {
1134
+ client_name: opts.clientName,
1135
+ token_endpoint_auth_method: "none",
1136
+ grant_types: ["authorization_code", "refresh_token"],
1137
+ redirect_uris: opts.redirectURIs,
1138
+ response_types: ["code"],
1139
+ ...opts.scopes ? { scope: opts.scopes.join(" ") } : {}
1140
+ };
1141
+ const ctl = withTimeout(authTimeoutMs, signal);
1142
+ let resp;
1143
+ try {
1144
+ resp = await fetch(meta.registration_endpoint, {
1145
+ method: "POST",
1146
+ headers: { "Content-Type": "application/json" },
1147
+ body: JSON.stringify(regReq),
1148
+ signal: ctl.signal
1149
+ });
1150
+ } catch (e) {
1151
+ throw new Error(`register: ${e instanceof Error ? e.message : String(e)}`);
1152
+ } finally {
1153
+ ctl.dispose();
1154
+ }
1155
+ if (resp.status !== 200 && resp.status !== 201) {
1156
+ throw new Error(`register: HTTP ${resp.status}`);
1157
+ }
1158
+ try {
1159
+ return await resp.json();
1160
+ } catch (e) {
1161
+ throw new Error(`register: decode: ${e instanceof Error ? e.message : String(e)}`);
1162
+ }
1163
+ }
1164
+ async function randomBase64Url32() {
1127
1165
  const c = await getCrypto();
1128
1166
  const b = new Uint8Array(32);
1129
1167
  c.getRandomValues(b);
1130
1168
  return base64urlNoPad(b);
1131
1169
  }
1170
+ async function generateCodeVerifier() {
1171
+ return randomBase64Url32();
1172
+ }
1173
+ async function generateState() {
1174
+ return randomBase64Url32();
1175
+ }
1132
1176
  async function codeChallenge(verifier) {
1133
1177
  const c = await getCrypto();
1134
1178
  const buf = await c.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
@@ -1162,6 +1206,7 @@ var ErrAuthDenied = "auth_denied";
1162
1206
  var ErrTimeout = "auth_timeout";
1163
1207
  var ErrTokenExchange = "token_exchange_failed";
1164
1208
  var ErrSSLProxy = "ssl_proxy_detected";
1209
+ var ErrStateMismatch = "state_mismatch";
1165
1210
  function isSSLError(err) {
1166
1211
  const msg = err instanceof Error ? err.message : String(err);
1167
1212
  return msg.includes("tls:") || msg.includes("x509:") || msg.includes("certificate");
@@ -1275,6 +1320,51 @@ async function authorize(meta, clientID, scopes, opts = {}) {
1275
1320
  function htmlEscape(s) {
1276
1321
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
1277
1322
  }
1323
+ async function createWebAuthorizationRequest(meta, opts) {
1324
+ const verifier = await generateCodeVerifier();
1325
+ const challenge = await codeChallenge(verifier);
1326
+ const state = await generateState();
1327
+ const authURL = new URL(meta.authorization_endpoint);
1328
+ authURL.searchParams.set("response_type", "code");
1329
+ authURL.searchParams.set("client_id", opts.clientID);
1330
+ authURL.searchParams.set("redirect_uri", opts.redirectURI);
1331
+ authURL.searchParams.set("code_challenge", challenge);
1332
+ authURL.searchParams.set("code_challenge_method", "S256");
1333
+ authURL.searchParams.set("state", state);
1334
+ authURL.searchParams.set("scope", opts.scopes.join(" "));
1335
+ if (opts.loginHint) {
1336
+ authURL.searchParams.set("login_hint", opts.loginHint);
1337
+ }
1338
+ return {
1339
+ authUrl: authURL.toString(),
1340
+ state,
1341
+ verifier,
1342
+ clientID: opts.clientID,
1343
+ redirectURI: opts.redirectURI,
1344
+ serverURL: opts.serverURL,
1345
+ createdAt: Date.now()
1346
+ };
1347
+ }
1348
+ async function completeWebAuthorizationRequest(pending, params, signal) {
1349
+ if (!params.code) {
1350
+ throw new Error("completeWebAuthorizationRequest: missing authorization code");
1351
+ }
1352
+ if (params.state !== pending.state) {
1353
+ throw new Error(
1354
+ `completeWebAuthorizationRequest: ${ErrStateMismatch}: callback state does not match pending state (possible CSRF)`
1355
+ );
1356
+ }
1357
+ const meta = await discoverWebOAuthMetadata(pending.serverURL, signal);
1358
+ const resp = await exchangeCode(
1359
+ meta,
1360
+ pending.clientID,
1361
+ params.code,
1362
+ pending.redirectURI,
1363
+ pending.verifier,
1364
+ signal
1365
+ );
1366
+ return newTokenSet(resp, pending.clientID, pending.serverURL);
1367
+ }
1278
1368
  async function exchangeCode(meta, clientID, code, redirectURI, codeVerifier, signal) {
1279
1369
  const data = new URLSearchParams({
1280
1370
  grant_type: "authorization_code",
@@ -2152,6 +2242,9 @@ var FilterStatusFallbackTkdistSkew = "fallback-tkdist-deployment-skew";
2152
2242
  var FilterStatusFallbackNoBuckets = "fallback-no-buckets";
2153
2243
  var FilterStatusFallbackMissingUser = "fallback-missing-userid";
2154
2244
  var FilterStatusUnknown = "";
2245
+ var ErrOAuthCORSBlocked = "oauth_cors_blocked";
2246
+ var ErrRefreshProxyFailed = "refresh_proxy_failed";
2247
+ var ErrTokenExpired = "token_expired";
2155
2248
  function newDeferred() {
2156
2249
  let resolve;
2157
2250
  let reject;
@@ -2167,6 +2260,12 @@ var Client = class _Client {
2167
2260
  serverURL;
2168
2261
  /** Compliance API 根地址 (已 trim 尾随 /); null = 走默认 ${serverURL}/admin-api */
2169
2262
  complianceBaseURL;
2263
+ /** OAuth metadata profile — 刷新 token 时发现 metadata 用 (默认 'desktop') */
2264
+ oauthMetadataProfile;
2265
+ /** Browser Web OAuth refresh strategy (default 'direct') */
2266
+ browserRefreshMode;
2267
+ /** Same-origin refresh proxy URL for browserRefreshMode='server-proxy' */
2268
+ refreshProxyURL;
2170
2269
  /** OAuth metadata (lazy loaded) */
2171
2270
  meta = null;
2172
2271
  /** 当前 token (内存) */
@@ -2201,6 +2300,9 @@ var Client = class _Client {
2201
2300
  constructor(cfg = {}) {
2202
2301
  this.serverURL = (cfg.serverURL ?? "https://acosmi.com").replace(/\/+$/, "");
2203
2302
  this.complianceBaseURL = cfg.complianceBaseURL ? cfg.complianceBaseURL.replace(/\/+$/, "") : null;
2303
+ this.oauthMetadataProfile = cfg.oauthMetadataProfile ?? "desktop";
2304
+ this.browserRefreshMode = cfg.browserRefreshMode ?? "direct";
2305
+ this.refreshProxyURL = cfg.refreshProxyURL ?? null;
2204
2306
  this.store = cfg.store ?? defaultTokenStore();
2205
2307
  this.fetchImpl = cfg.fetchImpl ?? globalThis.fetch.bind(globalThis);
2206
2308
  this.retryPolicy = effectivePolicy(cfg.retryPolicy ?? null);
@@ -2375,7 +2477,7 @@ var Client = class _Client {
2375
2477
  if (tokens) {
2376
2478
  if (!meta) {
2377
2479
  try {
2378
- meta = await discover(this.serverURL, signal);
2480
+ meta = await discoverWithProfile(this.serverURL, this.oauthMetadataProfile, signal);
2379
2481
  } catch (e) {
2380
2482
  console.warn(`[acosmi-sdk] warning: discover for revocation failed: ${e instanceof Error ? e.message : String(e)}`);
2381
2483
  }
@@ -2444,27 +2546,7 @@ var Client = class _Client {
2444
2546
  if (!tokenSetIsExpired(this.tokens)) {
2445
2547
  return this.tokens.access_token;
2446
2548
  }
2447
- if (this.meta == null) {
2448
- try {
2449
- this.meta = await discover(this.serverURL, signal);
2450
- } catch (e) {
2451
- throw new Error(
2452
- `discover for refresh: ${e instanceof Error ? e.message : String(e)}`
2453
- );
2454
- }
2455
- }
2456
- let tokenResp;
2457
- try {
2458
- tokenResp = await refreshToken(this.meta, this.tokens.client_id, this.tokens.refresh_token, signal);
2459
- } catch (e) {
2460
- throw new Error(`refresh token: ${e instanceof Error ? e.message : String(e)}`);
2461
- }
2462
- this.tokens = newTokenSet(tokenResp, this.tokens.client_id, this.serverURL);
2463
- try {
2464
- await this.store.save(this.tokens);
2465
- } catch (e) {
2466
- console.warn(`[acosmi-sdk] warning: save refreshed token failed: ${e instanceof Error ? e.message : String(e)}`);
2467
- }
2549
+ await this.refreshCurrentToken(signal);
2468
2550
  return this.tokens.access_token;
2469
2551
  })
2470
2552
  );
@@ -2477,26 +2559,111 @@ var Client = class _Client {
2477
2559
  if (this.tokens == null) {
2478
2560
  throw new Error("no tokens to refresh");
2479
2561
  }
2480
- if (this.meta == null) {
2481
- this.meta = await discover(this.serverURL, signal);
2482
- }
2483
- const tokenResp = await refreshToken(
2484
- this.meta,
2485
- this.tokens.client_id,
2486
- this.tokens.refresh_token,
2487
- signal
2488
- );
2489
- this.tokens = newTokenSet(tokenResp, this.tokens.client_id, this.serverURL);
2490
- try {
2491
- await this.store.save(this.tokens);
2492
- } catch (e) {
2493
- console.warn(
2494
- `[acosmi-sdk] warning: save refreshed token failed: ${e instanceof Error ? e.message : String(e)}`
2495
- );
2496
- }
2562
+ await this.refreshCurrentToken(signal);
2497
2563
  })
2498
2564
  );
2499
2565
  }
2566
+ async refreshCurrentToken(signal) {
2567
+ if (this.tokens == null) {
2568
+ throw new Error("no tokens to refresh");
2569
+ }
2570
+ if (this.browserRefreshMode === "none") {
2571
+ throw new Error(`${ErrTokenExpired}: token refresh disabled`);
2572
+ }
2573
+ if (this.browserRefreshMode === "server-proxy") {
2574
+ await this.refreshCurrentTokenViaProxy(signal);
2575
+ return;
2576
+ }
2577
+ await this.refreshCurrentTokenDirect(signal);
2578
+ }
2579
+ async refreshCurrentTokenDirect(signal) {
2580
+ if (this.tokens == null) {
2581
+ throw new Error("no tokens to refresh");
2582
+ }
2583
+ if (this.meta == null) {
2584
+ try {
2585
+ this.meta = await discoverWithProfile(this.serverURL, this.oauthMetadataProfile, signal);
2586
+ } catch (e) {
2587
+ throw new Error(
2588
+ `discover for refresh: ${e instanceof Error ? e.message : String(e)}`
2589
+ );
2590
+ }
2591
+ }
2592
+ let tokenResp;
2593
+ try {
2594
+ tokenResp = await refreshToken(
2595
+ this.meta,
2596
+ this.tokens.client_id,
2597
+ this.tokens.refresh_token,
2598
+ signal
2599
+ );
2600
+ } catch (e) {
2601
+ const message = e instanceof Error ? e.message : String(e);
2602
+ if (isLikelyBrowserOAuthCORSError(message)) {
2603
+ throw new Error(`${ErrOAuthCORSBlocked}: refresh token: ${message}`);
2604
+ }
2605
+ throw new Error(`refresh token: ${message}`);
2606
+ }
2607
+ this.tokens = newTokenSet(tokenResp, this.tokens.client_id, this.serverURL);
2608
+ await this.saveRefreshedToken();
2609
+ }
2610
+ async refreshCurrentTokenViaProxy(signal) {
2611
+ if (this.tokens == null) {
2612
+ throw new Error("no tokens to refresh");
2613
+ }
2614
+ if (!this.refreshProxyURL) {
2615
+ throw new Error(`${ErrRefreshProxyFailed}: refreshProxyURL is required`);
2616
+ }
2617
+ let resp;
2618
+ try {
2619
+ resp = await this.fetchImpl(this.refreshProxyURL, {
2620
+ method: "POST",
2621
+ headers: { "Content-Type": "application/json" },
2622
+ body: JSON.stringify({
2623
+ client_id: this.tokens.client_id,
2624
+ refresh_token: this.tokens.refresh_token,
2625
+ server_url: this.tokens.server_url || this.serverURL
2626
+ }),
2627
+ signal
2628
+ });
2629
+ } catch (e) {
2630
+ throw new Error(
2631
+ `${ErrRefreshProxyFailed}: ${e instanceof Error ? e.message : String(e)}`
2632
+ );
2633
+ }
2634
+ if (!resp.ok) {
2635
+ let message = "";
2636
+ try {
2637
+ const body2 = await resp.json();
2638
+ if (typeof body2.error === "string") message = body2.error;
2639
+ } catch {
2640
+ }
2641
+ throw new Error(`${ErrRefreshProxyFailed}: HTTP ${resp.status}: ${message}`);
2642
+ }
2643
+ let body;
2644
+ try {
2645
+ body = await resp.json();
2646
+ } catch (e) {
2647
+ throw new Error(
2648
+ `${ErrRefreshProxyFailed}: decode: ${e instanceof Error ? e.message : String(e)}`
2649
+ );
2650
+ }
2651
+ if (!isTokenSetLike(body.tokenSet)) {
2652
+ throw new Error(`${ErrRefreshProxyFailed}: response missing tokenSet`);
2653
+ }
2654
+ this.tokens = body.tokenSet;
2655
+ await this.saveRefreshedToken();
2656
+ }
2657
+ async saveRefreshedToken() {
2658
+ if (this.tokens == null) return;
2659
+ try {
2660
+ await this.store.save(this.tokens);
2661
+ } catch (e) {
2662
+ console.warn(
2663
+ `[acosmi-sdk] warning: save refreshed token failed: ${e instanceof Error ? e.message : String(e)}`
2664
+ );
2665
+ }
2666
+ }
2500
2667
  /** 互斥锁 helper (替代 Go sync.Mutex) */
2501
2668
  withMu(fn) {
2502
2669
  const next = this.mu.then(fn, fn);
@@ -3195,6 +3362,15 @@ function defaultTokenStore() {
3195
3362
  }
3196
3363
  return new InMemoryTokenStore();
3197
3364
  }
3365
+ function isLikelyBrowserOAuthCORSError(message) {
3366
+ const lower = message.toLowerCase();
3367
+ return lower.includes("failed to fetch") || lower.includes("networkerror") || lower.includes("cors") || lower.includes("http 403");
3368
+ }
3369
+ function isTokenSetLike(value) {
3370
+ if (value == null || typeof value !== "object") return false;
3371
+ const candidate = value;
3372
+ return typeof candidate.access_token === "string" && typeof candidate.refresh_token === "string" && typeof candidate.expires_at === "string" && typeof candidate.scope === "string" && typeof candidate.client_id === "string" && typeof candidate.server_url === "string";
3373
+ }
3198
3374
  function zeroModelCapabilities() {
3199
3375
  return {
3200
3376
  supports_thinking: false,
@@ -5385,8 +5561,10 @@ exports.ErrBrowserOpen = ErrBrowserOpen;
5385
5561
  exports.ErrComplianceStepUpRequired = ErrComplianceStepUpRequired;
5386
5562
  exports.ErrDiscovery = ErrDiscovery;
5387
5563
  exports.ErrEnvelopeGateClosed = ErrEnvelopeGateClosed;
5564
+ exports.ErrOAuthCORSBlocked = ErrOAuthCORSBlocked;
5388
5565
  exports.ErrProviderNotConfigured = ErrProviderNotConfigured;
5389
5566
  exports.ErrProviderUnknownNoRetry = ErrProviderUnknownNoRetry;
5567
+ exports.ErrRefreshProxyFailed = ErrRefreshProxyFailed;
5390
5568
  exports.ErrRegistration = ErrRegistration;
5391
5569
  exports.ErrSSLProxy = ErrSSLProxy;
5392
5570
  exports.ErrSealApprovalContractHashMismatch = ErrSealApprovalContractHashMismatch;
@@ -5397,8 +5575,10 @@ exports.ErrSealApprovalNotApproved = ErrSealApprovalNotApproved;
5397
5575
  exports.ErrSealApprovalSealMismatch = ErrSealApprovalSealMismatch;
5398
5576
  exports.ErrSealApprovalTransactorMismatch = ErrSealApprovalTransactorMismatch;
5399
5577
  exports.ErrSealUseAlreadyConsumed = ErrSealUseAlreadyConsumed;
5578
+ exports.ErrStateMismatch = ErrStateMismatch;
5400
5579
  exports.ErrTimeout = ErrTimeout;
5401
5580
  exports.ErrTokenExchange = ErrTokenExchange;
5581
+ exports.ErrTokenExpired = ErrTokenExpired;
5402
5582
  exports.EventAuthURL = EventAuthURL;
5403
5583
  exports.EventComplete = EventComplete;
5404
5584
  exports.EventError = EventError;
@@ -5452,17 +5632,22 @@ exports.bucketRowIsCommercial = bucketRowIsCommercial;
5452
5632
  exports.buildBetas = buildBetas;
5453
5633
  exports.classifyComplianceError = classifyComplianceError;
5454
5634
  exports.commerceScopes = commerceScopes;
5635
+ exports.completeWebAuthorizationRequest = completeWebAuthorizationRequest;
5455
5636
  exports.complianceScopes = complianceScopes;
5456
5637
  exports.computeBackoff = computeBackoff;
5638
+ exports.createWebAuthorizationRequest = createWebAuthorizationRequest;
5457
5639
  exports.defaultRetryable = defaultRetryable;
5458
5640
  exports.defaultSafeToRetry = defaultSafeToRetry;
5459
5641
  exports.discover = discover;
5642
+ exports.discoverWebOAuthMetadata = discoverWebOAuthMetadata;
5643
+ exports.discoverWithProfile = discoverWithProfile;
5460
5644
  exports.effectivePolicy = effectivePolicy;
5461
5645
  exports.exchangeCode = exchangeCode;
5462
5646
  exports.extractAnthropicBlockMeta = extractAnthropicBlockMeta;
5463
5647
  exports.fileLockDefaults = fileLockDefaults;
5464
5648
  exports.findDesktopVisualUnderstandingModel = findDesktopVisualUnderstandingModel;
5465
5649
  exports.findFirstModelByInputModality = findFirstModelByInputModality;
5650
+ exports.generateState = generateState;
5466
5651
  exports.getAdapter = getAdapter;
5467
5652
  exports.getAdapterForModel = getAdapterForModel;
5468
5653
  exports.isBillingConfirmable = isBillingConfirmable;
@@ -5481,6 +5666,7 @@ exports.parseSettlement = parseSettlement;
5481
5666
  exports.parseSourcesEvent = parseSourcesEvent;
5482
5667
  exports.refreshToken = refreshToken;
5483
5668
  exports.register = register;
5669
+ exports.registerWebOAuthClient = registerWebOAuthClient;
5484
5670
  exports.revokeToken = revokeToken;
5485
5671
  exports.sanitize = sanitize_exports;
5486
5672
  exports.skillScopes = skillScopes;