@acosmi/sdk-ts 2.15.0 → 2.16.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.
- package/CHANGELOG.md +21 -0
- package/README.md +27 -2
- package/dist/browser/index.mjs +74 -16
- package/dist/browser/index.mjs.map +1 -1
- package/dist/index.mjs +74 -16
- package/dist/index.mjs.map +1 -1
- package/dist/node/index.cjs +74 -15
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +47 -4
- package/dist/node/index.d.ts +47 -4
- package/dist/node/index.mjs +74 -16
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.cjs
CHANGED
|
@@ -2290,6 +2290,13 @@ var ErrOAuthCORSBlocked = "oauth_cors_blocked";
|
|
|
2290
2290
|
var ErrRefreshProxyFailed = "refresh_proxy_failed";
|
|
2291
2291
|
var ErrTokenExpired = "token_expired";
|
|
2292
2292
|
var CHAT_REQUEST_TIMEOUT_MS = 11 * 60 * 1e3;
|
|
2293
|
+
function notifyUpstreamActivity(cb) {
|
|
2294
|
+
if (!cb) return;
|
|
2295
|
+
try {
|
|
2296
|
+
cb();
|
|
2297
|
+
} catch {
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2293
2300
|
var DEFAULT_API_TIMEOUT_MS = 6e4;
|
|
2294
2301
|
function newDeferred() {
|
|
2295
2302
|
let resolve;
|
|
@@ -3003,7 +3010,13 @@ var Client = class _Client {
|
|
|
3003
3010
|
try {
|
|
3004
3011
|
const { body, adapter } = await this.buildChatRequest(modelID, r, ctl.signal);
|
|
3005
3012
|
const endpoint = `/managed-models/${encodeURIComponent(modelID)}${adapter.endpointSuffix()}`;
|
|
3006
|
-
const { result, headers } = await this.doJSONFullRaw(
|
|
3013
|
+
const { result, headers } = await this.doJSONFullRaw(
|
|
3014
|
+
"POST",
|
|
3015
|
+
endpoint,
|
|
3016
|
+
body,
|
|
3017
|
+
ctl.signal,
|
|
3018
|
+
CHAT_REQUEST_TIMEOUT_MS
|
|
3019
|
+
);
|
|
3007
3020
|
const resp = adapter.parseResponse(result);
|
|
3008
3021
|
const v1 = headers.get("X-Token-Remaining");
|
|
3009
3022
|
if (v1) {
|
|
@@ -3068,7 +3081,13 @@ var Client = class _Client {
|
|
|
3068
3081
|
*/
|
|
3069
3082
|
async generateVideo(modelID, req, signal) {
|
|
3070
3083
|
const endpoint = `/managed-models/${encodeURIComponent(modelID)}/videos/generations`;
|
|
3071
|
-
const { result } = await this.doJSONFullRaw(
|
|
3084
|
+
const { result } = await this.doJSONFullRaw(
|
|
3085
|
+
"POST",
|
|
3086
|
+
endpoint,
|
|
3087
|
+
req,
|
|
3088
|
+
signal,
|
|
3089
|
+
CHAT_REQUEST_TIMEOUT_MS
|
|
3090
|
+
);
|
|
3072
3091
|
return this.unwrapAPIResponse(result);
|
|
3073
3092
|
}
|
|
3074
3093
|
/**
|
|
@@ -3137,7 +3156,8 @@ var Client = class _Client {
|
|
|
3137
3156
|
"POST",
|
|
3138
3157
|
`/managed-models/${encodeURIComponent(modelID)}/anthropic`,
|
|
3139
3158
|
data,
|
|
3140
|
-
ctl.signal
|
|
3159
|
+
ctl.signal,
|
|
3160
|
+
CHAT_REQUEST_TIMEOUT_MS
|
|
3141
3161
|
);
|
|
3142
3162
|
const rawStr = new TextDecoder().decode(result);
|
|
3143
3163
|
try {
|
|
@@ -3171,7 +3191,13 @@ var Client = class _Client {
|
|
|
3171
3191
|
const body = adapter.buildRequestBody(caps, r);
|
|
3172
3192
|
const data = JSON.stringify(body);
|
|
3173
3193
|
const endpoint = `/managed-models/${encodeURIComponent(modelID)}${adapter.endpointSuffix()}`;
|
|
3174
|
-
const { result } = await this.doJSONFullRaw(
|
|
3194
|
+
const { result } = await this.doJSONFullRaw(
|
|
3195
|
+
"POST",
|
|
3196
|
+
endpoint,
|
|
3197
|
+
data,
|
|
3198
|
+
ctl.signal,
|
|
3199
|
+
CHAT_REQUEST_TIMEOUT_MS
|
|
3200
|
+
);
|
|
3175
3201
|
const { parseOpenAIResponseToAnthropic: parseOpenAIResponseToAnthropic2 } = await Promise.resolve().then(() => (init_openai(), openai_exports));
|
|
3176
3202
|
return parseOpenAIResponseToAnthropic2(result);
|
|
3177
3203
|
} finally {
|
|
@@ -3181,23 +3207,27 @@ var Client = class _Client {
|
|
|
3181
3207
|
/**
|
|
3182
3208
|
* 流式聊天 (SSE), 通过 async generator 返回事件
|
|
3183
3209
|
* v0.5.0: 根据 adapter 路由端点
|
|
3210
|
+
*
|
|
3211
|
+
* @param onUpstreamActivity 见 {@link UpstreamActivityCallback}
|
|
3184
3212
|
*/
|
|
3185
|
-
chatStream(modelID, req, signal) {
|
|
3213
|
+
chatStream(modelID, req, signal, onUpstreamActivity) {
|
|
3186
3214
|
return {
|
|
3187
|
-
[Symbol.asyncIterator]: () => this.chatStreamGen(modelID, req, signal, false)
|
|
3215
|
+
[Symbol.asyncIterator]: () => this.chatStreamGen(modelID, req, signal, false, onUpstreamActivity)
|
|
3188
3216
|
};
|
|
3189
3217
|
}
|
|
3190
3218
|
/**
|
|
3191
3219
|
* Anthropic 原生格式流式聊天 (SSE)
|
|
3192
3220
|
* 调用 POST /managed-models/:id/anthropic, SSE 事件为 Anthropic 协议格式
|
|
3193
3221
|
* 无 started/settled/failed 自定义事件, 无 data: [DONE], message_stop 为自然结束
|
|
3222
|
+
*
|
|
3223
|
+
* @param onUpstreamActivity 见 {@link UpstreamActivityCallback}
|
|
3194
3224
|
*/
|
|
3195
|
-
chatMessagesStream(modelID, req, signal) {
|
|
3225
|
+
chatMessagesStream(modelID, req, signal, onUpstreamActivity) {
|
|
3196
3226
|
return {
|
|
3197
|
-
[Symbol.asyncIterator]: () => this.chatMessagesStreamGen(modelID, req, signal, false)
|
|
3227
|
+
[Symbol.asyncIterator]: () => this.chatMessagesStreamGen(modelID, req, signal, false, onUpstreamActivity)
|
|
3198
3228
|
};
|
|
3199
3229
|
}
|
|
3200
|
-
async *chatStreamGen(modelID, req, signal, retried) {
|
|
3230
|
+
async *chatStreamGen(modelID, req, signal, retried, onUpstreamActivity) {
|
|
3201
3231
|
const r = { ...req, stream: true };
|
|
3202
3232
|
const { body, adapter } = await this.buildChatRequest(modelID, r, signal);
|
|
3203
3233
|
const token = await this.ensureToken(signal);
|
|
@@ -3230,7 +3260,7 @@ var Client = class _Client {
|
|
|
3230
3260
|
`stream: unauthorized and refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`
|
|
3231
3261
|
);
|
|
3232
3262
|
}
|
|
3233
|
-
yield* this.chatStreamGen(modelID, req, signal, true);
|
|
3263
|
+
yield* this.chatStreamGen(modelID, req, signal, true, onUpstreamActivity);
|
|
3234
3264
|
return;
|
|
3235
3265
|
}
|
|
3236
3266
|
if (!resp.ok) {
|
|
@@ -3246,6 +3276,7 @@ var Client = class _Client {
|
|
|
3246
3276
|
}
|
|
3247
3277
|
let currentEvent = "";
|
|
3248
3278
|
for await (const line of iterSSELines(resp.body)) {
|
|
3279
|
+
notifyUpstreamActivity(onUpstreamActivity);
|
|
3249
3280
|
if (isSSECommentLine(line)) continue;
|
|
3250
3281
|
if (line.startsWith("event:")) {
|
|
3251
3282
|
currentEvent = line.slice("event:".length).trim();
|
|
@@ -3266,7 +3297,7 @@ var Client = class _Client {
|
|
|
3266
3297
|
}
|
|
3267
3298
|
}
|
|
3268
3299
|
}
|
|
3269
|
-
async *chatMessagesStreamGen(modelID, req, signal, retried) {
|
|
3300
|
+
async *chatMessagesStreamGen(modelID, req, signal, retried, onUpstreamActivity) {
|
|
3270
3301
|
const r = { ...req, stream: true };
|
|
3271
3302
|
const { body, adapter } = await this.buildChatRequest(modelID, r, signal);
|
|
3272
3303
|
const token = await this.ensureToken(signal);
|
|
@@ -3299,7 +3330,7 @@ var Client = class _Client {
|
|
|
3299
3330
|
`messages stream: unauthorized and refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`
|
|
3300
3331
|
);
|
|
3301
3332
|
}
|
|
3302
|
-
yield* this.chatMessagesStreamGen(modelID, req, signal, true);
|
|
3333
|
+
yield* this.chatMessagesStreamGen(modelID, req, signal, true, onUpstreamActivity);
|
|
3303
3334
|
return;
|
|
3304
3335
|
}
|
|
3305
3336
|
if (!resp.ok) {
|
|
@@ -3312,6 +3343,7 @@ var Client = class _Client {
|
|
|
3312
3343
|
if (adapter.format() === 1 /* OpenAI */) {
|
|
3313
3344
|
const converter = newOpenAIStreamConverter();
|
|
3314
3345
|
for await (const line of iterSSELines(resp.body)) {
|
|
3346
|
+
notifyUpstreamActivity(onUpstreamActivity);
|
|
3315
3347
|
if (isSSECommentLine(line)) continue;
|
|
3316
3348
|
if (line.startsWith("event:")) {
|
|
3317
3349
|
line.slice("event:".length).trim();
|
|
@@ -3326,6 +3358,7 @@ var Client = class _Client {
|
|
|
3326
3358
|
const blockTypeMap = /* @__PURE__ */ new Map();
|
|
3327
3359
|
let currentEvent = "";
|
|
3328
3360
|
for await (const line of iterSSELines(resp.body)) {
|
|
3361
|
+
notifyUpstreamActivity(onUpstreamActivity);
|
|
3329
3362
|
if (isSSECommentLine(line)) continue;
|
|
3330
3363
|
if (line.startsWith("event:")) {
|
|
3331
3364
|
currentEvent = line.slice("event:".length).trim();
|
|
@@ -3458,7 +3491,19 @@ var Client = class _Client {
|
|
|
3458
3491
|
ctl.dispose();
|
|
3459
3492
|
}
|
|
3460
3493
|
}
|
|
3461
|
-
/**
|
|
3494
|
+
/**
|
|
3495
|
+
* doJSONFull 的 raw bytes 变体 (chat 用, 不立即 JSON.parse)
|
|
3496
|
+
*
|
|
3497
|
+
* ⚠️ 契约 (2026-08-06): `timeoutMs` 的 30s 默认值只适用于**控制面**端点 (列目录 /
|
|
3498
|
+
* 查配额 / 取任务状态)。凡走**模型推理或生成**的端点 —— chat / anthropic /
|
|
3499
|
+
* embeddings / rerank / images / videos —— 一律必须显式传入 `CHAT_REQUEST_TIMEOUT_MS`,
|
|
3500
|
+
* 哪怕调用方已经用 `withRequestTimeout` 建了外层预算: 外层只约束 `signal`, 内层
|
|
3501
|
+
* 会**另建**一个 `timeoutMs` 计时器, 30s 恒先于任何更长的外层预算触发。
|
|
3502
|
+
*
|
|
3503
|
+
* 这不是假设 —— 2026-08-06 事故里 chat 路径正因漏传本参数而被恒定钉死在 30s,
|
|
3504
|
+
* 且上方 v1.6.0 的注释还声称它已是 11min。回归闸门见
|
|
3505
|
+
* `tests/chat-timeout-budget.test.ts`。
|
|
3506
|
+
*/
|
|
3462
3507
|
async doJSONFullRaw(method, path, body, signal, timeoutMs = 3e4) {
|
|
3463
3508
|
return this.doJSONFullRawInternal(method, path, body, signal, false, timeoutMs);
|
|
3464
3509
|
}
|
|
@@ -7119,6 +7164,15 @@ function sleep2(ms, signal) {
|
|
|
7119
7164
|
}
|
|
7120
7165
|
|
|
7121
7166
|
// src/support/bug-report.ts
|
|
7167
|
+
function unwrapBugReport(raw, op, isComplete) {
|
|
7168
|
+
if (raw && isComplete(raw)) return raw;
|
|
7169
|
+
const inner = raw?.data;
|
|
7170
|
+
if (inner && isComplete(inner)) return inner;
|
|
7171
|
+
const keys = raw && typeof raw === "object" ? Object.keys(raw) : [];
|
|
7172
|
+
throw new Error(
|
|
7173
|
+
`acosmi: ${op}: gateway accepted the request but the response is missing required fields (observed keys: ${keys.length > 0 ? keys.join(",") : "<none>"})`
|
|
7174
|
+
);
|
|
7175
|
+
}
|
|
7122
7176
|
Client.prototype.submitBugReport = async function(reportData, signal) {
|
|
7123
7177
|
if (reportData == null) {
|
|
7124
7178
|
throw new Error("acosmi: reportData required");
|
|
@@ -7135,7 +7189,11 @@ Client.prototype.submitBugReport = async function(reportData, signal) {
|
|
|
7135
7189
|
{ content: contentStr },
|
|
7136
7190
|
signal
|
|
7137
7191
|
);
|
|
7138
|
-
return
|
|
7192
|
+
return unwrapBugReport(
|
|
7193
|
+
result,
|
|
7194
|
+
"submitBugReport",
|
|
7195
|
+
(r) => typeof r.feedback_id === "string" && r.feedback_id.length > 0
|
|
7196
|
+
);
|
|
7139
7197
|
};
|
|
7140
7198
|
Client.prototype.getBugReport = async function(bugID, signal) {
|
|
7141
7199
|
const trimmed = bugID.trim();
|
|
@@ -7148,7 +7206,7 @@ Client.prototype.getBugReport = async function(bugID, signal) {
|
|
|
7148
7206
|
null,
|
|
7149
7207
|
signal
|
|
7150
7208
|
);
|
|
7151
|
-
return resp.
|
|
7209
|
+
return unwrapBugReport(resp, "getBugReport", (r) => typeof r.id === "string");
|
|
7152
7210
|
};
|
|
7153
7211
|
|
|
7154
7212
|
// src/subscription/client.ts
|
|
@@ -7739,6 +7797,7 @@ exports.AgentRunStreamError = AgentRunStreamError;
|
|
|
7739
7797
|
exports.AgentRunsClient = AgentRunsClient;
|
|
7740
7798
|
exports.AudienceEnum = AudienceEnum;
|
|
7741
7799
|
exports.BillingModeEnum = BillingModeEnum;
|
|
7800
|
+
exports.CHAT_REQUEST_TIMEOUT_MS = CHAT_REQUEST_TIMEOUT_MS;
|
|
7742
7801
|
exports.ChatBridgeClient = ChatBridgeClient;
|
|
7743
7802
|
exports.Client = Client;
|
|
7744
7803
|
exports.ComplianceClient = ComplianceClient;
|