@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.
- package/CHANGELOG.md +56 -0
- package/dist/browser/index.mjs +219 -43
- package/dist/browser/index.mjs.map +1 -1
- package/dist/index.mjs +219 -43
- package/dist/index.mjs.map +1 -1
- package/dist/node/adapters/anthropic.d.cts +1 -1
- package/dist/node/adapters/anthropic.d.ts +1 -1
- package/dist/node/adapters/openai.d.cts +1 -1
- package/dist/node/adapters/openai.d.ts +1 -1
- package/dist/node/{index-28x02ITB.d.cts → index-CbG9NqE-.d.cts} +1 -1
- package/dist/node/{index-28x02ITB.d.ts → index-CbG9NqE-.d.ts} +1 -1
- package/dist/node/index.cjs +228 -42
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +164 -5
- package/dist/node/index.d.ts +164 -5
- package/dist/node/index.mjs +219 -43
- package/dist/node/index.mjs.map +1 -1
- package/package.json +9 -2
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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 };
|
package/dist/node/index.cjs
CHANGED
|
@@ -1058,7 +1058,7 @@ init_adapters();
|
|
|
1058
1058
|
|
|
1059
1059
|
// src/auth.ts
|
|
1060
1060
|
var authTimeoutMs = 3e4;
|
|
1061
|
-
async function
|
|
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
|
|
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
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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;
|