@acosmi/sdk-ts 2.10.0 → 2.12.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.
@@ -93,7 +93,34 @@ var init_types = __esm({
93
93
  });
94
94
 
95
95
  // src/shared/errors.ts
96
- exports.RateLimitError = void 0; exports.BusinessError = void 0; exports.OrderTerminalError = void 0; exports.ModelNotFoundError = void 0; exports.HTTPError = void 0; exports.NetworkError = void 0; exports.StreamError = void 0;
96
+ function isWindowLimitError(err) {
97
+ if (!(err instanceof exports.HTTPError)) return false;
98
+ if (err.errorCode === windowLimitErrorCode) return true;
99
+ return err.message.includes(windowLimitErrorCode) || err.body.includes(windowLimitErrorCode);
100
+ }
101
+ function isWindowLimitStreamError(err) {
102
+ if (err == null || typeof err !== "object") return false;
103
+ const e = err;
104
+ if (e.code === windowLimitStreamCode) return true;
105
+ for (const field of [e.message, e.userMessage, e.rawError]) {
106
+ if (typeof field === "string" && field.includes(windowLimitErrorCode)) return true;
107
+ }
108
+ return false;
109
+ }
110
+ function isContinuableWindowLimitError(err) {
111
+ return isWindowLimitError(err) && err.windowOverridable === true;
112
+ }
113
+ function getWindowLimitStreamDetails(err) {
114
+ if (!isWindowLimitStreamError(err)) return null;
115
+ const e = err ?? {};
116
+ const kind = e.windowKind === "FIVE_HOUR" || e.windowKind === "WEEKLY" ? e.windowKind : void 0;
117
+ return {
118
+ windowKind: kind,
119
+ windowResetAt: typeof e.windowResetAt === "string" ? e.windowResetAt : void 0,
120
+ windowOverridable: typeof e.windowOverridable === "boolean" ? e.windowOverridable : void 0
121
+ };
122
+ }
123
+ exports.RateLimitError = void 0; exports.BusinessError = void 0; exports.OrderTerminalError = void 0; exports.ModelNotFoundError = void 0; exports.HTTPError = void 0; exports.NetworkError = void 0; exports.StreamError = void 0; var windowLimitErrorCode, windowLimitStreamCode;
97
124
  var init_errors = __esm({
98
125
  "src/shared/errors.ts"() {
99
126
  exports.RateLimitError = class extends Error {
@@ -140,6 +167,18 @@ var init_errors = __esm({
140
167
  retryAfter;
141
168
  /** 原始响应体 (截断到 maxErrorBodySize) */
142
169
  body;
170
+ /** 后端业务机器码 (响应体顶层 errorCode, e.g. "WINDOW_LIMIT_EXCEEDED"); 缺失为 undefined */
171
+ errorCode;
172
+ /** 窗口限额场景: 触发的滚动窗口档位 (FIVE_HOUR = 5 小时 / WEEKLY = 7 天); 缺失为 undefined */
173
+ windowKind;
174
+ /** 窗口限额场景: 预计恢复时间 (ISO-8601 UTC); 缺失为 undefined */
175
+ windowResetAt;
176
+ /**
177
+ * [W1 2026-07-11 软限额] 窗口限额场景: 该 429 可否被用户「继续」开关豁免 —
178
+ * true = 5 小时软限额严格模式 (客户端可提示「继续任务」以消耗周配额继续);
179
+ * false/缺失 = 周窗/显式禁止/灰度关 (硬等待, 无豁免路径, 老网关不返回时为 undefined)。
180
+ */
181
+ windowOverridable;
143
182
  constructor(statusCode, opts = {}) {
144
183
  let msg;
145
184
  if (opts.type) {
@@ -157,6 +196,10 @@ var init_errors = __esm({
157
196
  this.type = opts.type ?? "";
158
197
  this.retryAfter = opts.retryAfter ?? 0;
159
198
  this.body = opts.body ?? "";
199
+ this.errorCode = opts.errorCode;
200
+ this.windowKind = opts.windowKind;
201
+ this.windowResetAt = opts.windowResetAt;
202
+ this.windowOverridable = opts.windowOverridable;
160
203
  }
161
204
  };
162
205
  exports.NetworkError = class extends Error {
@@ -212,6 +255,8 @@ var init_errors = __esm({
212
255
  this.retryable = retryable;
213
256
  }
214
257
  };
258
+ windowLimitErrorCode = "WINDOW_LIMIT_EXCEEDED";
259
+ windowLimitStreamCode = "window_limit_exceeded";
215
260
  }
216
261
  });
217
262
 
@@ -1932,19 +1977,39 @@ function parseHTTPErrorWithHeader(statusCode, body, header) {
1932
1977
  }
1933
1978
  let type = "";
1934
1979
  let message = "";
1980
+ let errorCode;
1981
+ let windowKind;
1982
+ let windowResetAt;
1983
+ let windowOverridable;
1935
1984
  try {
1936
1985
  const obj = JSON.parse(bodyStr);
1937
1986
  if (obj && typeof obj === "object") {
1938
- const errObj = obj.error;
1987
+ const top = obj;
1988
+ const errObj = top.error;
1939
1989
  if (errObj && typeof errObj === "object") {
1940
1990
  const e = errObj;
1941
1991
  if (typeof e.message === "string") message = e.message;
1942
1992
  if (typeof e.type === "string") type = e.type;
1993
+ } else if (typeof top.message === "string") {
1994
+ message = top.message;
1943
1995
  }
1996
+ if (typeof top.errorCode === "string") errorCode = top.errorCode;
1997
+ if (top.windowKind === "FIVE_HOUR" || top.windowKind === "WEEKLY") windowKind = top.windowKind;
1998
+ if (typeof top.windowResetAt === "string") windowResetAt = top.windowResetAt;
1999
+ if (typeof top.windowOverridable === "boolean") windowOverridable = top.windowOverridable;
1944
2000
  }
1945
2001
  } catch {
1946
2002
  }
1947
- return new exports.HTTPError(statusCode, { type, message, retryAfter, body: bodyStr });
2003
+ return new exports.HTTPError(statusCode, {
2004
+ type,
2005
+ message,
2006
+ retryAfter,
2007
+ body: bodyStr,
2008
+ errorCode,
2009
+ windowKind,
2010
+ windowResetAt,
2011
+ windowOverridable
2012
+ });
1948
2013
  }
1949
2014
  function classifyTransport(op, urlStr, err) {
1950
2015
  const ne = new exports.NetworkError(op, urlStr, err);
@@ -2733,6 +2798,24 @@ var Client = class _Client {
2733
2798
  );
2734
2799
  return resp.data;
2735
2800
  }
2801
+ /**
2802
+ * [W1 2026-07-11 软限额] 设置当前用户 5 小时窗口软限额「继续」开关 (v2.12+)。
2803
+ *
2804
+ * enabled=true = 软限额 (到达 5h 后继续消耗周配额, 默认); false = 严格模式 (到达即等待逐步恢复)。
2805
+ * userId 由网关从鉴权态解析 (客户端永不传), 故只需 enabled + 可选 source (审计: web /
2806
+ * crabcode-gui / crabcode-tui / dialog)。用于个人中心开关、429 严格模式「重新开启继续」续跑。
2807
+ *
2808
+ * @returns 网关回显的新状态 { enabled }。
2809
+ */
2810
+ async setWindowContinuePreference(enabled, opts) {
2811
+ const resp = await this.doJSON(
2812
+ "POST",
2813
+ "/entitlements/window-continue-pref",
2814
+ { enabled, source: opts?.source },
2815
+ opts?.signal
2816
+ );
2817
+ return { enabled: resp.data.enabled };
2818
+ }
2736
2819
  /**
2737
2820
  * 查询单个模型的能力矩阵
2738
2821
  * 优先从 listModels 缓存读取, miss 时调用 listModels 刷新
@@ -5638,6 +5721,9 @@ function normalizeError(value) {
5638
5721
  message: stringField(value, "message", "error") || "agent run failed",
5639
5722
  stage: optionalStringField(value, "stage"),
5640
5723
  retryable: typeof value.retryable === "boolean" ? value.retryable : void 0,
5724
+ // 窗口限额扩展 (code="window_limit_exceeded"): 契约 wire 为 camelCase, 蛇形兼容兜底。
5725
+ windowKind: optionalStringField(value, "windowKind", "window_kind"),
5726
+ windowResetAt: optionalStringField(value, "windowResetAt", "window_reset_at"),
5641
5727
  raw: value
5642
5728
  };
5643
5729
  }
@@ -7687,10 +7773,12 @@ exports.findFirstModelByInputModality = findFirstModelByInputModality;
7687
7773
  exports.generateState = generateState;
7688
7774
  exports.getAdapter = getAdapter;
7689
7775
  exports.getAdapterForModel = getAdapterForModel;
7776
+ exports.getWindowLimitStreamDetails = getWindowLimitStreamDetails;
7690
7777
  exports.isBillingConfirmable = isBillingConfirmable;
7691
7778
  exports.isChannelInboundEvent = isChannelInboundEvent;
7692
7779
  exports.isComplianceBusinessError = isComplianceBusinessError;
7693
7780
  exports.isComplianceTerminalError = isComplianceTerminalError;
7781
+ exports.isContinuableWindowLimitError = isContinuableWindowLimitError;
7694
7782
  exports.isIntegrationStatus = isIntegrationStatus;
7695
7783
  exports.isInvalidGrantError = isInvalidGrantError;
7696
7784
  exports.isPlatform = isPlatform;
@@ -7699,6 +7787,8 @@ exports.isSSECommentLine = isSSECommentLine;
7699
7787
  exports.isSSLError = isSSLError;
7700
7788
  exports.isTerminalRemoteEvent = isTerminalRemoteEvent;
7701
7789
  exports.isValidTokenSet = isValidTokenSet;
7790
+ exports.isWindowLimitError = isWindowLimitError;
7791
+ exports.isWindowLimitStreamError = isWindowLimitStreamError;
7702
7792
  exports.maxEndUserIdLength = maxEndUserIdLength;
7703
7793
  exports.modelScopes = modelScopes;
7704
7794
  exports.modelSupportsImageInput = modelSupportsImageInput;