@acosmi/sdk-ts 2.19.6 → 2.20.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,7 +1,7 @@
1
- import { a as AnthropicResponse } from './openai-ByUO-cSR.cjs';
2
- export { A as AnthropicContentBlock, b as AnthropicUsage, O as OpenAIAdapter, d as anthropicResponseTextContent, e as anthropicResponseThinkingContent, f as anthropicResponseToolUseBlocks } from './openai-ByUO-cSR.cjs';
3
- import { P as ProviderAdapter, M as ManagedModel, Q as QuotaSummary, Y as WindowResetSummary, n as ModelCapabilities, e as ChatRequest, f as ChatResponse, I as ImageGenerationRequest, k as ImageGenerationResponse, V as VideoGenerationRequest, N as VideoTaskResponse, i as EmbeddingRequest, j as EmbeddingResponse, s as RerankRequest, t as RerankResponse, z as StreamEvent, w as SourcesEvent, A as StreamSettlement, l as InputModality } from './format-CKpXSSqY.cjs';
4
- export { B as BucketClassCommercial, a as BucketClassGeneric, b as BucketInfo, c as BucketRow, C as ChatContentBlock, d as ChatMessage, g as ChatUsage, E as EffortConfig, h as EmbeddingData, G as GeoLoc, m as InputModalityTag, o as MultimodalContent, O as OutputConfig, p as ProviderFormat, q as QuotaSummarySubscriptionPool, R as RerankDocument, r as RerankQuery, u as RerankResult, S as ServerTool, v as ServerToolTypeWebSearch, x as SourcesEventIssueCode, y as SourcesEventParseResult, T as ThinkingConfig, D as ThinkingHigh, F as ThinkingHighMinMaxTokens, H as ThinkingLow, J as ThinkingMax, K as ThinkingMaxFallbackMaxTokens, L as ThinkingOff, W as WebSearchConfig, U as WebSearchSource, X as WindowLimitStatus, Z as bucketInfoIsCommercial, _ as bucketRowIsCommercial, $ as classifySourcesEvent, a0 as newThinkingConfig, a1 as newWebSearchTool, a2 as parseSettlement, a3 as parseSourcesEvent } from './format-CKpXSSqY.cjs';
1
+ import { a as AnthropicResponse } from './openai-DauG8pfK.cjs';
2
+ export { A as AnthropicContentBlock, b as AnthropicUsage, O as OpenAIAdapter, d as anthropicResponseTextContent, e as anthropicResponseThinkingContent, f as anthropicResponseToolUseBlocks } from './openai-DauG8pfK.cjs';
3
+ import { P as ProviderAdapter, M as ManagedModel, Q as QuotaSummary, _ as WindowResetSummary, n as ModelCapabilities, e as ChatRequest, f as ChatResponse, I as ImageGenerationRequest, k as ImageGenerationResponse, V as VideoGenerationRequest, W as VideoTaskResponse, i as EmbeddingRequest, j as EmbeddingResponse, u as RerankRequest, v as RerankResponse, D as StreamEvent, y as SourcesEvent, F as StreamSettlement, l as InputModality } from './format-BBXu82tQ.cjs';
4
+ export { B as BucketClassCommercial, a as BucketClassGeneric, b as BucketInfo, c as BucketRow, C as ChatContentBlock, d as ChatMessage, g as ChatUsage, E as EffortConfig, h as EmbeddingData, G as GeoLoc, m as InputModalityTag, o as MultimodalContent, O as OutputConfig, p as ProviderFormat, q as QuotaSummaryCreditUnit, r as QuotaSummaryFreePool, s as QuotaSummarySubscriptionPool, R as RerankDocument, t as RerankQuery, w as RerankResult, S as ServerTool, x as ServerToolTypeWebSearch, z as SourcesEventIssueCode, A as SourcesEventParseResult, T as ThinkingConfig, H as ThinkingHigh, J as ThinkingHighMinMaxTokens, K as ThinkingLow, L as ThinkingMax, N as ThinkingMaxFallbackMaxTokens, U as ThinkingOff, X as WebSearchConfig, Y as WebSearchSource, Z as WindowLimitStatus, $ as bucketInfoIsCommercial, a0 as bucketRowIsCommercial, a1 as classifySourcesEvent, a2 as newThinkingConfig, a3 as newWebSearchTool, a4 as parseSettlement, a5 as parseSourcesEvent } from './format-BBXu82tQ.cjs';
5
5
  import { M as MinimalSanitizeConfig } from './index-Bah9A83R.cjs';
6
6
  export { A as sanitize } from './index-Bah9A83R.cjs';
7
7
  export { AnthropicAdapter } from './adapters/anthropic.cjs';
@@ -1,7 +1,7 @@
1
- import { a as AnthropicResponse } from './openai-CH0wnJXv.js';
2
- export { A as AnthropicContentBlock, b as AnthropicUsage, O as OpenAIAdapter, d as anthropicResponseTextContent, e as anthropicResponseThinkingContent, f as anthropicResponseToolUseBlocks } from './openai-CH0wnJXv.js';
3
- import { P as ProviderAdapter, M as ManagedModel, Q as QuotaSummary, Y as WindowResetSummary, n as ModelCapabilities, e as ChatRequest, f as ChatResponse, I as ImageGenerationRequest, k as ImageGenerationResponse, V as VideoGenerationRequest, N as VideoTaskResponse, i as EmbeddingRequest, j as EmbeddingResponse, s as RerankRequest, t as RerankResponse, z as StreamEvent, w as SourcesEvent, A as StreamSettlement, l as InputModality } from './format-CKpXSSqY.js';
4
- export { B as BucketClassCommercial, a as BucketClassGeneric, b as BucketInfo, c as BucketRow, C as ChatContentBlock, d as ChatMessage, g as ChatUsage, E as EffortConfig, h as EmbeddingData, G as GeoLoc, m as InputModalityTag, o as MultimodalContent, O as OutputConfig, p as ProviderFormat, q as QuotaSummarySubscriptionPool, R as RerankDocument, r as RerankQuery, u as RerankResult, S as ServerTool, v as ServerToolTypeWebSearch, x as SourcesEventIssueCode, y as SourcesEventParseResult, T as ThinkingConfig, D as ThinkingHigh, F as ThinkingHighMinMaxTokens, H as ThinkingLow, J as ThinkingMax, K as ThinkingMaxFallbackMaxTokens, L as ThinkingOff, W as WebSearchConfig, U as WebSearchSource, X as WindowLimitStatus, Z as bucketInfoIsCommercial, _ as bucketRowIsCommercial, $ as classifySourcesEvent, a0 as newThinkingConfig, a1 as newWebSearchTool, a2 as parseSettlement, a3 as parseSourcesEvent } from './format-CKpXSSqY.js';
1
+ import { a as AnthropicResponse } from './openai-BNJe_o8L.js';
2
+ export { A as AnthropicContentBlock, b as AnthropicUsage, O as OpenAIAdapter, d as anthropicResponseTextContent, e as anthropicResponseThinkingContent, f as anthropicResponseToolUseBlocks } from './openai-BNJe_o8L.js';
3
+ import { P as ProviderAdapter, M as ManagedModel, Q as QuotaSummary, _ as WindowResetSummary, n as ModelCapabilities, e as ChatRequest, f as ChatResponse, I as ImageGenerationRequest, k as ImageGenerationResponse, V as VideoGenerationRequest, W as VideoTaskResponse, i as EmbeddingRequest, j as EmbeddingResponse, u as RerankRequest, v as RerankResponse, D as StreamEvent, y as SourcesEvent, F as StreamSettlement, l as InputModality } from './format-BBXu82tQ.js';
4
+ export { B as BucketClassCommercial, a as BucketClassGeneric, b as BucketInfo, c as BucketRow, C as ChatContentBlock, d as ChatMessage, g as ChatUsage, E as EffortConfig, h as EmbeddingData, G as GeoLoc, m as InputModalityTag, o as MultimodalContent, O as OutputConfig, p as ProviderFormat, q as QuotaSummaryCreditUnit, r as QuotaSummaryFreePool, s as QuotaSummarySubscriptionPool, R as RerankDocument, t as RerankQuery, w as RerankResult, S as ServerTool, x as ServerToolTypeWebSearch, z as SourcesEventIssueCode, A as SourcesEventParseResult, T as ThinkingConfig, H as ThinkingHigh, J as ThinkingHighMinMaxTokens, K as ThinkingLow, L as ThinkingMax, N as ThinkingMaxFallbackMaxTokens, U as ThinkingOff, X as WebSearchConfig, Y as WebSearchSource, Z as WindowLimitStatus, $ as bucketInfoIsCommercial, a0 as bucketRowIsCommercial, a1 as classifySourcesEvent, a2 as newThinkingConfig, a3 as newWebSearchTool, a4 as parseSettlement, a5 as parseSourcesEvent } from './format-BBXu82tQ.js';
5
5
  import { M as MinimalSanitizeConfig } from './index-Bah9A83R.js';
6
6
  export { A as sanitize } from './index-Bah9A83R.js';
7
7
  export { AnthropicAdapter } from './adapters/anthropic.js';
@@ -1095,6 +1095,18 @@ var abort = (signal) => {
1095
1095
  if (signal?.aborted) throw new Error("aborted");
1096
1096
  };
1097
1097
  var sameRequestOwner = (snapshot, expected) => snapshot.storeInstanceId === expected.storeInstanceId && snapshot.authSessionId === expected.authSessionId && snapshot.principal?.issuer === expected.principal?.issuer && snapshot.principal?.subject === expected.principal?.subject && snapshot.principal?.organizationId === expected.principal?.organizationId;
1098
+ var REFRESH_TEMPORARILY_UNAVAILABLE = "refresh_temporarily_unavailable";
1099
+ var REFRESH_RETRY_BASE_MS = 5e3;
1100
+ var REFRESH_RETRY_MAX_MS = 6e4;
1101
+ var REFRESH_RETRY_AFTER_CAP_MS = 3e5;
1102
+ function retryAfterMs(response) {
1103
+ const raw = response.headers.get("retry-after");
1104
+ if (!raw) return null;
1105
+ const seconds = Number(raw);
1106
+ const ms = Number.isFinite(seconds) ? seconds * 1e3 : Date.parse(raw) - Date.now();
1107
+ if (!Number.isFinite(ms)) return null;
1108
+ return Math.min(Math.max(ms, 0), REFRESH_RETRY_AFTER_CAP_MS);
1109
+ }
1098
1110
  var CredentialLifecycle = class {
1099
1111
  constructor(store, protocol) {
1100
1112
  this.store = store;
@@ -1105,6 +1117,8 @@ var CredentialLifecycle = class {
1105
1117
  listeners = /* @__PURE__ */ new Set();
1106
1118
  notificationKey = "";
1107
1119
  observations = /* @__PURE__ */ new Map();
1120
+ /** Last refusal of a refresh token that was not rotated; see `REFRESH_RETRY_BASE_MS`. */
1121
+ refreshDeferral = null;
1108
1122
  read(signal) {
1109
1123
  return this.store.readSnapshot(signal);
1110
1124
  }
@@ -1294,6 +1308,19 @@ var CredentialLifecycle = class {
1294
1308
  usable(s) {
1295
1309
  return !!s.tokenSet && Date.parse(s.tokenSet.expires_at) > Date.now() + 3e5;
1296
1310
  }
1311
+ refreshDeferred(s) {
1312
+ const d = this.refreshDeferral;
1313
+ return !!d && d.refreshToken === s.tokenSet?.refresh_token && Date.now() < d.until;
1314
+ }
1315
+ deferRefresh(refreshToken2, retryAfter) {
1316
+ const failures = this.refreshDeferral?.refreshToken === refreshToken2 ? this.refreshDeferral.failures + 1 : 1;
1317
+ const backoff = Math.min(REFRESH_RETRY_MAX_MS, REFRESH_RETRY_BASE_MS * 2 ** (failures - 1));
1318
+ this.refreshDeferral = {
1319
+ refreshToken: refreshToken2,
1320
+ failures,
1321
+ until: Date.now() + Math.max(backoff, retryAfter ?? 0)
1322
+ };
1323
+ }
1297
1324
  async bindIdentity(sessionId, signal) {
1298
1325
  const s = await this.ensureSnapshot(signal, void 0, true);
1299
1326
  if (s.authSessionId !== sessionId) throw new Error("superseded");
@@ -1407,6 +1434,10 @@ var CredentialLifecycle = class {
1407
1434
  if (live && (refreshed || s.revision !== (rejected?.revision ?? initialRevision) && (rejected !== void 0 || s.tokenSet.access_token !== initialAccess)))
1408
1435
  return s;
1409
1436
  if (this.usable(s) && !rejected) return s;
1437
+ if (this.refreshDeferred(s)) {
1438
+ if (live && !rejected) return s;
1439
+ throw new Error(REFRESH_TEMPORARILY_UNAVAILABLE);
1440
+ }
1410
1441
  const metadata = await this.metadata(s, signal);
1411
1442
  abort(signal);
1412
1443
  const operationId = uuid();
@@ -1429,7 +1460,13 @@ var CredentialLifecycle = class {
1429
1460
  );
1430
1461
  if (r.status !== "committed") continue;
1431
1462
  const owner = this.refresh(r.snapshot, metadata);
1432
- await this.wait(owner, signal);
1463
+ try {
1464
+ await this.wait(owner, signal);
1465
+ } catch (error) {
1466
+ const deferred = error instanceof Error && error.message === REFRESH_TEMPORARILY_UNAVAILABLE;
1467
+ if (rejected || !deferred) throw error;
1468
+ continue;
1469
+ }
1433
1470
  refreshed = true;
1434
1471
  rejected = void 0;
1435
1472
  }
@@ -1470,59 +1507,9 @@ var CredentialLifecycle = class {
1470
1507
  const s = r.snapshot;
1471
1508
  const ctl = new AbortController();
1472
1509
  const timeout = setTimeout(() => ctl.abort(), 3e4);
1473
- let tokens;
1510
+ let outcome;
1474
1511
  try {
1475
- const result = await this.wait(
1476
- (async () => {
1477
- const response = await this.protocol.fetch(metadata.token_endpoint, {
1478
- method: "POST",
1479
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
1480
- body: new URLSearchParams({
1481
- grant_type: "refresh_token",
1482
- client_id: s.tokenSet.client_id,
1483
- refresh_token: s.tokenSet.refresh_token
1484
- }),
1485
- signal: ctl.signal
1486
- });
1487
- const body2 = await response.json();
1488
- return { response, body: body2 };
1489
- })(),
1490
- ctl.signal
1491
- );
1492
- if (!result.response.ok) {
1493
- const code = result.body.error;
1494
- let reason = "refresh_outcome_unknown";
1495
- let state = "reauth_required";
1496
- if (code === "invalid_grant") reason = code;
1497
- else if (["invalid_client", "invalid_scope", "unsupported_grant_type"].includes(code)) {
1498
- reason = code;
1499
- state = "configuration_error";
1500
- } else if (result.body.rotationOutcome === "not_committed" && ["temporarily_unavailable", "server_error"].includes(code)) {
1501
- await this.commit(s, {
1502
- credentialState: s.refreshOperation.returnState,
1503
- refreshOperation: null
1504
- });
1505
- throw new Error("refresh_temporarily_unavailable");
1506
- }
1507
- await this.commit(s, {
1508
- credentialState: state,
1509
- tokenSet: null,
1510
- refreshOperation: null,
1511
- reason
1512
- });
1513
- throw new Error(reason);
1514
- }
1515
- const body = result.body;
1516
- if (!Number.isFinite(body.expires_in) || body.expires_in <= 0)
1517
- throw new Error("invalid_response");
1518
- tokens = {
1519
- ...s.tokenSet,
1520
- access_token: body.access_token,
1521
- refresh_token: body.refresh_token,
1522
- expires_at: new Date(Date.now() + body.expires_in * 1e3).toISOString(),
1523
- scope: body.scope ?? s.tokenSet.scope
1524
- };
1525
- this.validateTokens(tokens);
1512
+ outcome = await this.wait(this.exchange(metadata, s.tokenSet, ctl.signal), ctl.signal);
1526
1513
  } catch (error) {
1527
1514
  await this.commit(s, {
1528
1515
  credentialState: "reauth_required",
@@ -1534,6 +1521,24 @@ var CredentialLifecycle = class {
1534
1521
  } finally {
1535
1522
  clearTimeout(timeout);
1536
1523
  }
1524
+ if (outcome.kind === "not_committed") {
1525
+ this.deferRefresh(s.tokenSet.refresh_token, outcome.retryAfterMs);
1526
+ await this.commit(s, {
1527
+ credentialState: s.refreshOperation.returnState,
1528
+ refreshOperation: null
1529
+ });
1530
+ throw new Error(REFRESH_TEMPORARILY_UNAVAILABLE);
1531
+ }
1532
+ if (outcome.kind === "rejected") {
1533
+ await this.commit(s, {
1534
+ credentialState: outcome.state,
1535
+ tokenSet: null,
1536
+ refreshOperation: null,
1537
+ reason: outcome.reason
1538
+ });
1539
+ throw new Error(outcome.reason);
1540
+ }
1541
+ const tokens = outcome.tokens;
1537
1542
  const started = performance.now(), mutationId = uuid();
1538
1543
  for (; ; ) {
1539
1544
  if (Date.now() >= Date.parse(s.refreshOperation.deadlineAt)) {
@@ -1556,6 +1561,7 @@ var CredentialLifecycle = class {
1556
1561
  mutationId
1557
1562
  );
1558
1563
  if (result.status === "committed") {
1564
+ this.refreshDeferral = null;
1559
1565
  await this.notify(result.snapshot);
1560
1566
  return;
1561
1567
  }
@@ -1567,6 +1573,47 @@ var CredentialLifecycle = class {
1567
1573
  await pause();
1568
1574
  }
1569
1575
  }
1576
+ /**
1577
+ * One refresh-token exchange. Settles with what the authority said; rejects only when there is
1578
+ * no answer or the answer cannot be read, which leaves the rotation outcome unknown.
1579
+ */
1580
+ async exchange(metadata, current, signal) {
1581
+ const response = await this.protocol.fetch(metadata.token_endpoint, {
1582
+ method: "POST",
1583
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
1584
+ body: new URLSearchParams({
1585
+ grant_type: "refresh_token",
1586
+ client_id: current.client_id,
1587
+ refresh_token: current.refresh_token
1588
+ }),
1589
+ signal
1590
+ });
1591
+ if (response.status === 429)
1592
+ return { kind: "not_committed", retryAfterMs: retryAfterMs(response) };
1593
+ const body = await response.json();
1594
+ if (!response.ok) {
1595
+ const code = body.error;
1596
+ if (code === "invalid_grant")
1597
+ return { kind: "rejected", state: "reauth_required", reason: code };
1598
+ if (["invalid_client", "invalid_scope", "unsupported_grant_type"].includes(code))
1599
+ return { kind: "rejected", state: "configuration_error", reason: code };
1600
+ if (body.rotationOutcome === "not_committed" && ["temporarily_unavailable", "server_error"].includes(code))
1601
+ return { kind: "not_committed", retryAfterMs: retryAfterMs(response) };
1602
+ return { kind: "rejected", state: "reauth_required", reason: "refresh_outcome_unknown" };
1603
+ }
1604
+ const tokenResponse = body;
1605
+ if (!Number.isFinite(tokenResponse.expires_in) || tokenResponse.expires_in <= 0)
1606
+ throw new Error("invalid_response");
1607
+ const tokens = {
1608
+ ...current,
1609
+ access_token: tokenResponse.access_token,
1610
+ refresh_token: tokenResponse.refresh_token,
1611
+ expires_at: new Date(Date.now() + tokenResponse.expires_in * 1e3).toISOString(),
1612
+ scope: tokenResponse.scope ?? current.scope
1613
+ };
1614
+ this.validateTokens(tokens);
1615
+ return { kind: "tokens", tokens };
1616
+ }
1570
1617
  async revoke(tokens, metadata, authority) {
1571
1618
  const ctl = new AbortController();
1572
1619
  const timer = setTimeout(() => ctl.abort(), 3e4);