@acosmi/sdk-ts 2.19.4 → 2.19.5
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 +8 -0
- package/README.md +27 -2
- package/dist/browser/index.mjs +110 -23
- package/dist/browser/index.mjs.map +1 -1
- package/dist/index.mjs +110 -23
- package/dist/index.mjs.map +1 -1
- package/dist/node/adapters/anthropic.cjs.map +1 -1
- package/dist/node/adapters/anthropic.mjs.map +1 -1
- package/dist/node/adapters/openai.cjs.map +1 -1
- package/dist/node/adapters/openai.mjs.map +1 -1
- package/dist/node/index.cjs +110 -22
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +80 -8
- package/dist/node/index.d.ts +80 -8
- package/dist/node/index.mjs +110 -23
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.cjs
CHANGED
|
@@ -150,6 +150,14 @@ var init_types = __esm({
|
|
|
150
150
|
});
|
|
151
151
|
|
|
152
152
|
// src/shared/errors.ts
|
|
153
|
+
function finiteNonNegative(value) {
|
|
154
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
|
|
155
|
+
}
|
|
156
|
+
function isStreamError(err) {
|
|
157
|
+
if (err == null || typeof err !== "object") return false;
|
|
158
|
+
const e = err;
|
|
159
|
+
return e.name === "StreamError" && typeof e.errorCode === "string";
|
|
160
|
+
}
|
|
153
161
|
function nullableID(value) {
|
|
154
162
|
return value === null || typeof value === "string";
|
|
155
163
|
}
|
|
@@ -359,8 +367,23 @@ var init_errors = __esm({
|
|
|
359
367
|
userMessage;
|
|
360
368
|
/** gateway 原始 error 字符串 */
|
|
361
369
|
rawError;
|
|
362
|
-
/** 客户端是否值得重试 */
|
|
370
|
+
/** 客户端是否值得重试 (= 服务端 `retryable` **且** `requestDisposition === 'not_accepted'`) */
|
|
363
371
|
retryable;
|
|
372
|
+
/**
|
|
373
|
+
* 服务端在帧上声明的 `retryable` **原值** (2.19.5 起) —— 不与 requestDisposition 合取,
|
|
374
|
+
* 缺席即 undefined。
|
|
375
|
+
*
|
|
376
|
+
* 为什么要并列存一份: 上面的 `retryable` 是两个判据的合取, 网关的流内错误帧并不总是
|
|
377
|
+
* 下发 `requestDisposition`, 于是"服务端明说可重试"会被合取成 false —— 两端各自正确,
|
|
378
|
+
* 合起来恒否。消费方要区分**「服务端明说不可重试」**(false, 一票否决) 与**「服务端没说」**
|
|
379
|
+
* (undefined, 回落到自己的本地分类表) 时, 只能读这个原值; 读 `retryable` 两种情形不可分。
|
|
380
|
+
*/
|
|
381
|
+
serverRetryable;
|
|
382
|
+
/**
|
|
383
|
+
* 服务端建议的等待秒数 (2.19.5 起)。**有限非负数**才收, 其余 (null / 负数 /
|
|
384
|
+
* NaN / Infinity / 非数字) 一律 undefined —— 宁可不给, 绝不编造等待时间。
|
|
385
|
+
*/
|
|
386
|
+
retryAfterSecs;
|
|
364
387
|
errorContractVersion;
|
|
365
388
|
faultDomain;
|
|
366
389
|
requestDisposition;
|
|
@@ -383,6 +406,8 @@ var init_errors = __esm({
|
|
|
383
406
|
this.userMessage = userMessage;
|
|
384
407
|
this.rawError = rawError;
|
|
385
408
|
this.retryable = retryable;
|
|
409
|
+
this.serverRetryable = opts.retryable;
|
|
410
|
+
this.retryAfterSecs = finiteNonNegative(opts.retryAfterSecs);
|
|
386
411
|
this.errorContractVersion = opts.errorContractVersion;
|
|
387
412
|
this.faultDomain = opts.faultDomain;
|
|
388
413
|
this.requestDisposition = opts.requestDisposition;
|
|
@@ -2197,7 +2222,10 @@ var FileTokenStore = class {
|
|
|
2197
2222
|
/**
|
|
2198
2223
|
* 跨进程临界区. 用 sidecar `<path>.lock` 文件 + O_EXCL 创建语义实现互斥:
|
|
2199
2224
|
* - 创建成功 = 持有锁; 写入 pid+timestamp 便于诊断
|
|
2200
|
-
* - 创建失败 (EEXIST) = 别的进程持锁, backoff 重试
|
|
2225
|
+
* - 创建失败 (EEXIST) = 别的进程持锁, stale 检测后 backoff 重试
|
|
2226
|
+
* - 创建失败 (Windows 的 EPERM / EBUSY) = 前一持有者的 unlink 处于 delete-pending,
|
|
2227
|
+
* 同属争用; 跳过 stale 检测直接 backoff 重试 (见 catch 内注释)。EACCES 不在其中 —
|
|
2228
|
+
* 它是真权限错误, 立即抛
|
|
2201
2229
|
* - 锁文件 mtime > staleMs = 进程崩溃残留, unlink 后重试
|
|
2202
2230
|
* - acquireTimeoutMs 超时 = 抛错 (caller 应作为 transient error 处理, 上层 retry)
|
|
2203
2231
|
*
|
|
@@ -2231,20 +2259,22 @@ ${Date.now()}
|
|
|
2231
2259
|
};
|
|
2232
2260
|
break;
|
|
2233
2261
|
} catch (e) {
|
|
2234
|
-
if (!
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
const st = await fs.stat(lockPath);
|
|
2238
|
-
if (Date.now() - st.mtimeMs > fileLockDefaults.staleMs) stale = true;
|
|
2239
|
-
} catch {
|
|
2240
|
-
continue;
|
|
2241
|
-
}
|
|
2242
|
-
if (stale) {
|
|
2262
|
+
if (!isLockContendedError(e)) throw e;
|
|
2263
|
+
if (!isWindowsLockBusyError(e)) {
|
|
2264
|
+
let stale = false;
|
|
2243
2265
|
try {
|
|
2244
|
-
await fs.
|
|
2266
|
+
const st = await fs.stat(lockPath);
|
|
2267
|
+
if (Date.now() - st.mtimeMs > fileLockDefaults.staleMs) stale = true;
|
|
2245
2268
|
} catch {
|
|
2269
|
+
continue;
|
|
2270
|
+
}
|
|
2271
|
+
if (stale) {
|
|
2272
|
+
try {
|
|
2273
|
+
await fs.unlink(lockPath);
|
|
2274
|
+
} catch {
|
|
2275
|
+
}
|
|
2276
|
+
continue;
|
|
2246
2277
|
}
|
|
2247
|
-
continue;
|
|
2248
2278
|
}
|
|
2249
2279
|
if (Date.now() - startMs > fileLockDefaults.acquireTimeoutMs) {
|
|
2250
2280
|
throw new Error(
|
|
@@ -2350,6 +2380,15 @@ function isNotExistError(e) {
|
|
|
2350
2380
|
}
|
|
2351
2381
|
return false;
|
|
2352
2382
|
}
|
|
2383
|
+
function isWindowsLockBusyError(e) {
|
|
2384
|
+
if (typeof process === "undefined" || process.platform !== "win32") return false;
|
|
2385
|
+
if (typeof e !== "object" || e === null || !("code" in e)) return false;
|
|
2386
|
+
const code = e.code;
|
|
2387
|
+
return code === "EPERM" || code === "EBUSY";
|
|
2388
|
+
}
|
|
2389
|
+
function isLockContendedError(e) {
|
|
2390
|
+
return isAlreadyExistsError(e) || isWindowsLockBusyError(e);
|
|
2391
|
+
}
|
|
2353
2392
|
function isAlreadyExistsError(e) {
|
|
2354
2393
|
if (typeof e === "object" && e !== null && "code" in e) {
|
|
2355
2394
|
return e.code === "EEXIST";
|
|
@@ -2943,7 +2982,7 @@ function parseStreamError(data) {
|
|
|
2943
2982
|
let code = payload.errorCode ?? "";
|
|
2944
2983
|
const stage = payload.stage ?? "";
|
|
2945
2984
|
let message = payload.message ?? "";
|
|
2946
|
-
const retryable = payload.retryable
|
|
2985
|
+
const retryable = payload.retryable;
|
|
2947
2986
|
let rawError = "";
|
|
2948
2987
|
if (payload.error != null) {
|
|
2949
2988
|
if (typeof payload.error === "string") {
|
|
@@ -2961,6 +3000,7 @@ function parseStreamError(data) {
|
|
|
2961
3000
|
message,
|
|
2962
3001
|
rawError,
|
|
2963
3002
|
retryable,
|
|
3003
|
+
retryAfterSecs: payload.retryAfterSecs,
|
|
2964
3004
|
errorContractVersion: payload.errorContractVersion,
|
|
2965
3005
|
faultDomain: payload.faultDomain,
|
|
2966
3006
|
requestDisposition: payload.requestDisposition,
|
|
@@ -3171,6 +3211,25 @@ function notifyGatewayRequestID(cb, headers) {
|
|
|
3171
3211
|
} catch {
|
|
3172
3212
|
}
|
|
3173
3213
|
}
|
|
3214
|
+
function notifyResponseHeaders(cb, headers) {
|
|
3215
|
+
if (!cb) return;
|
|
3216
|
+
try {
|
|
3217
|
+
cb(headers);
|
|
3218
|
+
} catch {
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
function armStreamRequestTimeout(opts, parent) {
|
|
3222
|
+
const ms = opts?.requestTimeoutMs;
|
|
3223
|
+
if (typeof ms !== "number" || !Number.isFinite(ms) || ms <= 0) return void 0;
|
|
3224
|
+
return withRequestTimeout(ms, parent);
|
|
3225
|
+
}
|
|
3226
|
+
async function* disposeTimeoutWhenSettled(inner, ctl) {
|
|
3227
|
+
try {
|
|
3228
|
+
yield* inner;
|
|
3229
|
+
} finally {
|
|
3230
|
+
ctl.dispose();
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3174
3233
|
var DEFAULT_API_TIMEOUT_MS = 6e4;
|
|
3175
3234
|
function newDeferred() {
|
|
3176
3235
|
let resolve;
|
|
@@ -4304,10 +4363,23 @@ var Client = class _Client {
|
|
|
4304
4363
|
*
|
|
4305
4364
|
* @param onUpstreamActivity 见 {@link UpstreamActivityCallback}
|
|
4306
4365
|
* @param onGatewayRequestID 见 {@link GatewayRequestIDCallback}
|
|
4366
|
+
* @param opts 见 {@link ChatStreamOptions} (2.19.5 起)
|
|
4307
4367
|
*/
|
|
4308
|
-
chatStream(modelID, req, signal, onUpstreamActivity, onGatewayRequestID) {
|
|
4368
|
+
chatStream(modelID, req, signal, onUpstreamActivity, onGatewayRequestID, opts) {
|
|
4309
4369
|
return {
|
|
4310
|
-
[Symbol.asyncIterator]: () =>
|
|
4370
|
+
[Symbol.asyncIterator]: () => {
|
|
4371
|
+
const ctl = armStreamRequestTimeout(opts, signal);
|
|
4372
|
+
const inner = this.chatStreamGen(
|
|
4373
|
+
modelID,
|
|
4374
|
+
req,
|
|
4375
|
+
ctl?.signal ?? signal,
|
|
4376
|
+
false,
|
|
4377
|
+
onUpstreamActivity,
|
|
4378
|
+
onGatewayRequestID,
|
|
4379
|
+
opts?.onResponseHeaders
|
|
4380
|
+
);
|
|
4381
|
+
return ctl ? disposeTimeoutWhenSettled(inner, ctl) : inner;
|
|
4382
|
+
}
|
|
4311
4383
|
};
|
|
4312
4384
|
}
|
|
4313
4385
|
/**
|
|
@@ -4317,13 +4389,26 @@ var Client = class _Client {
|
|
|
4317
4389
|
*
|
|
4318
4390
|
* @param onUpstreamActivity 见 {@link UpstreamActivityCallback}
|
|
4319
4391
|
* @param onGatewayRequestID 见 {@link GatewayRequestIDCallback}
|
|
4392
|
+
* @param opts 见 {@link ChatStreamOptions} (2.19.5 起)
|
|
4320
4393
|
*/
|
|
4321
|
-
chatMessagesStream(modelID, req, signal, onUpstreamActivity, onGatewayRequestID) {
|
|
4394
|
+
chatMessagesStream(modelID, req, signal, onUpstreamActivity, onGatewayRequestID, opts) {
|
|
4322
4395
|
return {
|
|
4323
|
-
[Symbol.asyncIterator]: () =>
|
|
4396
|
+
[Symbol.asyncIterator]: () => {
|
|
4397
|
+
const ctl = armStreamRequestTimeout(opts, signal);
|
|
4398
|
+
const inner = this.chatMessagesStreamGen(
|
|
4399
|
+
modelID,
|
|
4400
|
+
req,
|
|
4401
|
+
ctl?.signal ?? signal,
|
|
4402
|
+
false,
|
|
4403
|
+
onUpstreamActivity,
|
|
4404
|
+
onGatewayRequestID,
|
|
4405
|
+
opts?.onResponseHeaders
|
|
4406
|
+
);
|
|
4407
|
+
return ctl ? disposeTimeoutWhenSettled(inner, ctl) : inner;
|
|
4408
|
+
}
|
|
4324
4409
|
};
|
|
4325
4410
|
}
|
|
4326
|
-
async *chatStreamGen(modelID, req, signal, retried, onUpstreamActivity, onGatewayRequestID) {
|
|
4411
|
+
async *chatStreamGen(modelID, req, signal, retried, onUpstreamActivity, onGatewayRequestID, onResponseHeaders) {
|
|
4327
4412
|
const r = { ...req, stream: true };
|
|
4328
4413
|
const { body, adapter } = await this.buildChatRequest(modelID, r, signal);
|
|
4329
4414
|
const token = await this.ensureToken(signal);
|
|
@@ -4355,10 +4440,11 @@ var Client = class _Client {
|
|
|
4355
4440
|
`stream: unauthorized and refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`
|
|
4356
4441
|
);
|
|
4357
4442
|
}
|
|
4358
|
-
yield* this.chatStreamGen(modelID, req, signal, true, onUpstreamActivity, onGatewayRequestID);
|
|
4443
|
+
yield* this.chatStreamGen(modelID, req, signal, true, onUpstreamActivity, onGatewayRequestID, onResponseHeaders);
|
|
4359
4444
|
return;
|
|
4360
4445
|
}
|
|
4361
4446
|
notifyGatewayRequestID(onGatewayRequestID, resp.headers);
|
|
4447
|
+
notifyResponseHeaders(onResponseHeaders, resp.headers);
|
|
4362
4448
|
if (!resp.ok) {
|
|
4363
4449
|
const bodyBytes = await readLimited(resp.body, maxErrorBodySize);
|
|
4364
4450
|
throw parseHTTPErrorWithHeader(resp.status, bodyBytes, resp.headers);
|
|
@@ -4393,7 +4479,7 @@ var Client = class _Client {
|
|
|
4393
4479
|
}
|
|
4394
4480
|
}
|
|
4395
4481
|
}
|
|
4396
|
-
async *chatMessagesStreamGen(modelID, req, signal, retried, onUpstreamActivity, onGatewayRequestID) {
|
|
4482
|
+
async *chatMessagesStreamGen(modelID, req, signal, retried, onUpstreamActivity, onGatewayRequestID, onResponseHeaders) {
|
|
4397
4483
|
const r = { ...req, stream: true };
|
|
4398
4484
|
const { body, adapter } = await this.buildChatRequest(modelID, r, signal);
|
|
4399
4485
|
const token = await this.ensureToken(signal);
|
|
@@ -4425,10 +4511,11 @@ var Client = class _Client {
|
|
|
4425
4511
|
`messages stream: unauthorized and refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`
|
|
4426
4512
|
);
|
|
4427
4513
|
}
|
|
4428
|
-
yield* this.chatMessagesStreamGen(modelID, req, signal, true, onUpstreamActivity, onGatewayRequestID);
|
|
4514
|
+
yield* this.chatMessagesStreamGen(modelID, req, signal, true, onUpstreamActivity, onGatewayRequestID, onResponseHeaders);
|
|
4429
4515
|
return;
|
|
4430
4516
|
}
|
|
4431
4517
|
notifyGatewayRequestID(onGatewayRequestID, resp.headers);
|
|
4518
|
+
notifyResponseHeaders(onResponseHeaders, resp.headers);
|
|
4432
4519
|
if (!resp.ok) {
|
|
4433
4520
|
const bodyBytes = await readLimited(resp.body, maxErrorBodySize);
|
|
4434
4521
|
throw parseHTTPErrorWithHeader(resp.status, bodyBytes, resp.headers);
|
|
@@ -9114,6 +9201,7 @@ exports.isPlatform = isPlatform;
|
|
|
9114
9201
|
exports.isRegion = isRegion;
|
|
9115
9202
|
exports.isSSECommentLine = isSSECommentLine;
|
|
9116
9203
|
exports.isSSLError = isSSLError;
|
|
9204
|
+
exports.isStreamError = isStreamError;
|
|
9117
9205
|
exports.isTerminalRemoteEvent = isTerminalRemoteEvent;
|
|
9118
9206
|
exports.isUserAccessTokenRejected = isUserAccessTokenRejected;
|
|
9119
9207
|
exports.isValidTokenSet = isValidTokenSet;
|