@acosmi/sdk-ts 2.15.0 → 2.17.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 +35 -0
- package/README.md +27 -2
- package/dist/browser/index.mjs +103 -19
- package/dist/browser/index.mjs.map +1 -1
- package/dist/index.mjs +103 -19
- package/dist/index.mjs.map +1 -1
- package/dist/node/index.cjs +105 -18
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +63 -6
- package/dist/node/index.d.ts +63 -6
- package/dist/node/index.mjs +103 -19
- package/dist/node/index.mjs.map +1 -1
- package/package.json +4 -1
package/dist/node/index.cjs
CHANGED
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __esm = (fn, res) => function __init() {
|
|
6
|
-
|
|
5
|
+
var __esm = (fn, res, err) => function __init() {
|
|
6
|
+
if (err) throw err[0];
|
|
7
|
+
try {
|
|
8
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
9
|
+
} catch (e) {
|
|
10
|
+
throw err = [e], e;
|
|
11
|
+
}
|
|
7
12
|
};
|
|
8
13
|
var __export = (target, all) => {
|
|
9
14
|
for (var name in all)
|
|
@@ -1324,6 +1329,7 @@ async function authorize(meta, clientID, scopes, opts = {}) {
|
|
|
1324
1329
|
};
|
|
1325
1330
|
const verifier = await generateCodeVerifier();
|
|
1326
1331
|
const challenge = await codeChallenge(verifier);
|
|
1332
|
+
const state = await generateState();
|
|
1327
1333
|
const http = await import('http');
|
|
1328
1334
|
const server = http.createServer();
|
|
1329
1335
|
await new Promise((resolve, reject) => {
|
|
@@ -1339,6 +1345,8 @@ async function authorize(meta, clientID, scopes, opts = {}) {
|
|
|
1339
1345
|
codeResolver = resolve;
|
|
1340
1346
|
codeRejecter = reject;
|
|
1341
1347
|
});
|
|
1348
|
+
codePromise.catch(() => {
|
|
1349
|
+
});
|
|
1342
1350
|
server.on("request", (req, res) => {
|
|
1343
1351
|
const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
|
|
1344
1352
|
if (url.pathname !== "/callback") {
|
|
@@ -1346,6 +1354,16 @@ async function authorize(meta, clientID, scopes, opts = {}) {
|
|
|
1346
1354
|
res.end();
|
|
1347
1355
|
return;
|
|
1348
1356
|
}
|
|
1357
|
+
const states = url.searchParams.getAll("state");
|
|
1358
|
+
const stateFailure = states.length === 0 ? "callback missing state" : states.length > 1 ? "callback carried multiple state values" : states[0] !== state ? "callback state does not match pending state" : null;
|
|
1359
|
+
if (stateFailure !== null) {
|
|
1360
|
+
res.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
1361
|
+
res.end(
|
|
1362
|
+
`<!DOCTYPE html><html><head><meta charset="utf-8"><title>\u6388\u6743\u5931\u8D25</title></head><body style="font-family:system-ui,sans-serif;text-align:center;padding:60px 20px"><h2>\u6388\u6743\u5931\u8D25</h2><p>\u56DE\u8C03\u6821\u9A8C\u672A\u901A\u8FC7, \u5DF2\u4E2D\u6B62\u767B\u5F55\u3002</p><p style="color:#888;font-size:14px">\u53EF\u4EE5\u5173\u95ED\u6B64\u7A97\u53E3\u3002</p></body></html>`
|
|
1363
|
+
);
|
|
1364
|
+
codeRejecter(new Error(`authorize: ${ErrStateMismatch}: ${stateFailure} (possible CSRF)`));
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1349
1367
|
const code = url.searchParams.get("code");
|
|
1350
1368
|
if (!code) {
|
|
1351
1369
|
const errMsg = url.searchParams.get("error_description") || url.searchParams.get("error") || "";
|
|
@@ -1376,6 +1394,7 @@ async function authorize(meta, clientID, scopes, opts = {}) {
|
|
|
1376
1394
|
authURL.searchParams.set("response_type", "code");
|
|
1377
1395
|
authURL.searchParams.set("code_challenge", challenge);
|
|
1378
1396
|
authURL.searchParams.set("code_challenge_method", "S256");
|
|
1397
|
+
authURL.searchParams.set("state", state);
|
|
1379
1398
|
if (scopes.length > 0) {
|
|
1380
1399
|
authURL.searchParams.set("scope", scopes.join(" "));
|
|
1381
1400
|
}
|
|
@@ -1413,7 +1432,9 @@ async function authorize(meta, clientID, scopes, opts = {}) {
|
|
|
1413
1432
|
return { result: { code, redirectURI }, verifier };
|
|
1414
1433
|
} catch (e) {
|
|
1415
1434
|
const msg = e instanceof Error ? e.message : String(e);
|
|
1416
|
-
if (msg.includes(
|
|
1435
|
+
if (msg.includes(ErrStateMismatch)) {
|
|
1436
|
+
emit({ type: EventError, err_code: ErrStateMismatch, error: msg });
|
|
1437
|
+
} else if (msg.includes("denied")) {
|
|
1417
1438
|
emit({ type: EventError, err_code: ErrAuthDenied, error: msg });
|
|
1418
1439
|
} else if (msg.includes("timed out")) {
|
|
1419
1440
|
emit({ type: EventError, err_code: ErrTimeout, error: msg });
|
|
@@ -1424,6 +1445,7 @@ async function authorize(meta, clientID, scopes, opts = {}) {
|
|
|
1424
1445
|
} finally {
|
|
1425
1446
|
if (abortHandler && signal) signal.removeEventListener("abort", abortHandler);
|
|
1426
1447
|
server.close();
|
|
1448
|
+
server.closeIdleConnections?.();
|
|
1427
1449
|
}
|
|
1428
1450
|
}
|
|
1429
1451
|
function htmlEscape(s) {
|
|
@@ -2290,6 +2312,13 @@ var ErrOAuthCORSBlocked = "oauth_cors_blocked";
|
|
|
2290
2312
|
var ErrRefreshProxyFailed = "refresh_proxy_failed";
|
|
2291
2313
|
var ErrTokenExpired = "token_expired";
|
|
2292
2314
|
var CHAT_REQUEST_TIMEOUT_MS = 11 * 60 * 1e3;
|
|
2315
|
+
function notifyUpstreamActivity(cb) {
|
|
2316
|
+
if (!cb) return;
|
|
2317
|
+
try {
|
|
2318
|
+
cb();
|
|
2319
|
+
} catch {
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2293
2322
|
var DEFAULT_API_TIMEOUT_MS = 6e4;
|
|
2294
2323
|
function newDeferred() {
|
|
2295
2324
|
let resolve;
|
|
@@ -3003,7 +3032,13 @@ var Client = class _Client {
|
|
|
3003
3032
|
try {
|
|
3004
3033
|
const { body, adapter } = await this.buildChatRequest(modelID, r, ctl.signal);
|
|
3005
3034
|
const endpoint = `/managed-models/${encodeURIComponent(modelID)}${adapter.endpointSuffix()}`;
|
|
3006
|
-
const { result, headers } = await this.doJSONFullRaw(
|
|
3035
|
+
const { result, headers } = await this.doJSONFullRaw(
|
|
3036
|
+
"POST",
|
|
3037
|
+
endpoint,
|
|
3038
|
+
body,
|
|
3039
|
+
ctl.signal,
|
|
3040
|
+
CHAT_REQUEST_TIMEOUT_MS
|
|
3041
|
+
);
|
|
3007
3042
|
const resp = adapter.parseResponse(result);
|
|
3008
3043
|
const v1 = headers.get("X-Token-Remaining");
|
|
3009
3044
|
if (v1) {
|
|
@@ -3068,7 +3103,13 @@ var Client = class _Client {
|
|
|
3068
3103
|
*/
|
|
3069
3104
|
async generateVideo(modelID, req, signal) {
|
|
3070
3105
|
const endpoint = `/managed-models/${encodeURIComponent(modelID)}/videos/generations`;
|
|
3071
|
-
const { result } = await this.doJSONFullRaw(
|
|
3106
|
+
const { result } = await this.doJSONFullRaw(
|
|
3107
|
+
"POST",
|
|
3108
|
+
endpoint,
|
|
3109
|
+
req,
|
|
3110
|
+
signal,
|
|
3111
|
+
CHAT_REQUEST_TIMEOUT_MS
|
|
3112
|
+
);
|
|
3072
3113
|
return this.unwrapAPIResponse(result);
|
|
3073
3114
|
}
|
|
3074
3115
|
/**
|
|
@@ -3137,7 +3178,8 @@ var Client = class _Client {
|
|
|
3137
3178
|
"POST",
|
|
3138
3179
|
`/managed-models/${encodeURIComponent(modelID)}/anthropic`,
|
|
3139
3180
|
data,
|
|
3140
|
-
ctl.signal
|
|
3181
|
+
ctl.signal,
|
|
3182
|
+
CHAT_REQUEST_TIMEOUT_MS
|
|
3141
3183
|
);
|
|
3142
3184
|
const rawStr = new TextDecoder().decode(result);
|
|
3143
3185
|
try {
|
|
@@ -3171,7 +3213,13 @@ var Client = class _Client {
|
|
|
3171
3213
|
const body = adapter.buildRequestBody(caps, r);
|
|
3172
3214
|
const data = JSON.stringify(body);
|
|
3173
3215
|
const endpoint = `/managed-models/${encodeURIComponent(modelID)}${adapter.endpointSuffix()}`;
|
|
3174
|
-
const { result } = await this.doJSONFullRaw(
|
|
3216
|
+
const { result } = await this.doJSONFullRaw(
|
|
3217
|
+
"POST",
|
|
3218
|
+
endpoint,
|
|
3219
|
+
data,
|
|
3220
|
+
ctl.signal,
|
|
3221
|
+
CHAT_REQUEST_TIMEOUT_MS
|
|
3222
|
+
);
|
|
3175
3223
|
const { parseOpenAIResponseToAnthropic: parseOpenAIResponseToAnthropic2 } = await Promise.resolve().then(() => (init_openai(), openai_exports));
|
|
3176
3224
|
return parseOpenAIResponseToAnthropic2(result);
|
|
3177
3225
|
} finally {
|
|
@@ -3181,23 +3229,27 @@ var Client = class _Client {
|
|
|
3181
3229
|
/**
|
|
3182
3230
|
* 流式聊天 (SSE), 通过 async generator 返回事件
|
|
3183
3231
|
* v0.5.0: 根据 adapter 路由端点
|
|
3232
|
+
*
|
|
3233
|
+
* @param onUpstreamActivity 见 {@link UpstreamActivityCallback}
|
|
3184
3234
|
*/
|
|
3185
|
-
chatStream(modelID, req, signal) {
|
|
3235
|
+
chatStream(modelID, req, signal, onUpstreamActivity) {
|
|
3186
3236
|
return {
|
|
3187
|
-
[Symbol.asyncIterator]: () => this.chatStreamGen(modelID, req, signal, false)
|
|
3237
|
+
[Symbol.asyncIterator]: () => this.chatStreamGen(modelID, req, signal, false, onUpstreamActivity)
|
|
3188
3238
|
};
|
|
3189
3239
|
}
|
|
3190
3240
|
/**
|
|
3191
3241
|
* Anthropic 原生格式流式聊天 (SSE)
|
|
3192
3242
|
* 调用 POST /managed-models/:id/anthropic, SSE 事件为 Anthropic 协议格式
|
|
3193
3243
|
* 无 started/settled/failed 自定义事件, 无 data: [DONE], message_stop 为自然结束
|
|
3244
|
+
*
|
|
3245
|
+
* @param onUpstreamActivity 见 {@link UpstreamActivityCallback}
|
|
3194
3246
|
*/
|
|
3195
|
-
chatMessagesStream(modelID, req, signal) {
|
|
3247
|
+
chatMessagesStream(modelID, req, signal, onUpstreamActivity) {
|
|
3196
3248
|
return {
|
|
3197
|
-
[Symbol.asyncIterator]: () => this.chatMessagesStreamGen(modelID, req, signal, false)
|
|
3249
|
+
[Symbol.asyncIterator]: () => this.chatMessagesStreamGen(modelID, req, signal, false, onUpstreamActivity)
|
|
3198
3250
|
};
|
|
3199
3251
|
}
|
|
3200
|
-
async *chatStreamGen(modelID, req, signal, retried) {
|
|
3252
|
+
async *chatStreamGen(modelID, req, signal, retried, onUpstreamActivity) {
|
|
3201
3253
|
const r = { ...req, stream: true };
|
|
3202
3254
|
const { body, adapter } = await this.buildChatRequest(modelID, r, signal);
|
|
3203
3255
|
const token = await this.ensureToken(signal);
|
|
@@ -3230,7 +3282,7 @@ var Client = class _Client {
|
|
|
3230
3282
|
`stream: unauthorized and refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`
|
|
3231
3283
|
);
|
|
3232
3284
|
}
|
|
3233
|
-
yield* this.chatStreamGen(modelID, req, signal, true);
|
|
3285
|
+
yield* this.chatStreamGen(modelID, req, signal, true, onUpstreamActivity);
|
|
3234
3286
|
return;
|
|
3235
3287
|
}
|
|
3236
3288
|
if (!resp.ok) {
|
|
@@ -3246,6 +3298,7 @@ var Client = class _Client {
|
|
|
3246
3298
|
}
|
|
3247
3299
|
let currentEvent = "";
|
|
3248
3300
|
for await (const line of iterSSELines(resp.body)) {
|
|
3301
|
+
notifyUpstreamActivity(onUpstreamActivity);
|
|
3249
3302
|
if (isSSECommentLine(line)) continue;
|
|
3250
3303
|
if (line.startsWith("event:")) {
|
|
3251
3304
|
currentEvent = line.slice("event:".length).trim();
|
|
@@ -3266,7 +3319,7 @@ var Client = class _Client {
|
|
|
3266
3319
|
}
|
|
3267
3320
|
}
|
|
3268
3321
|
}
|
|
3269
|
-
async *chatMessagesStreamGen(modelID, req, signal, retried) {
|
|
3322
|
+
async *chatMessagesStreamGen(modelID, req, signal, retried, onUpstreamActivity) {
|
|
3270
3323
|
const r = { ...req, stream: true };
|
|
3271
3324
|
const { body, adapter } = await this.buildChatRequest(modelID, r, signal);
|
|
3272
3325
|
const token = await this.ensureToken(signal);
|
|
@@ -3299,7 +3352,7 @@ var Client = class _Client {
|
|
|
3299
3352
|
`messages stream: unauthorized and refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`
|
|
3300
3353
|
);
|
|
3301
3354
|
}
|
|
3302
|
-
yield* this.chatMessagesStreamGen(modelID, req, signal, true);
|
|
3355
|
+
yield* this.chatMessagesStreamGen(modelID, req, signal, true, onUpstreamActivity);
|
|
3303
3356
|
return;
|
|
3304
3357
|
}
|
|
3305
3358
|
if (!resp.ok) {
|
|
@@ -3312,6 +3365,7 @@ var Client = class _Client {
|
|
|
3312
3365
|
if (adapter.format() === 1 /* OpenAI */) {
|
|
3313
3366
|
const converter = newOpenAIStreamConverter();
|
|
3314
3367
|
for await (const line of iterSSELines(resp.body)) {
|
|
3368
|
+
notifyUpstreamActivity(onUpstreamActivity);
|
|
3315
3369
|
if (isSSECommentLine(line)) continue;
|
|
3316
3370
|
if (line.startsWith("event:")) {
|
|
3317
3371
|
line.slice("event:".length).trim();
|
|
@@ -3326,6 +3380,7 @@ var Client = class _Client {
|
|
|
3326
3380
|
const blockTypeMap = /* @__PURE__ */ new Map();
|
|
3327
3381
|
let currentEvent = "";
|
|
3328
3382
|
for await (const line of iterSSELines(resp.body)) {
|
|
3383
|
+
notifyUpstreamActivity(onUpstreamActivity);
|
|
3329
3384
|
if (isSSECommentLine(line)) continue;
|
|
3330
3385
|
if (line.startsWith("event:")) {
|
|
3331
3386
|
currentEvent = line.slice("event:".length).trim();
|
|
@@ -3458,7 +3513,19 @@ var Client = class _Client {
|
|
|
3458
3513
|
ctl.dispose();
|
|
3459
3514
|
}
|
|
3460
3515
|
}
|
|
3461
|
-
/**
|
|
3516
|
+
/**
|
|
3517
|
+
* doJSONFull 的 raw bytes 变体 (chat 用, 不立即 JSON.parse)
|
|
3518
|
+
*
|
|
3519
|
+
* ⚠️ 契约 (2026-08-06): `timeoutMs` 的 30s 默认值只适用于**控制面**端点 (列目录 /
|
|
3520
|
+
* 查配额 / 取任务状态)。凡走**模型推理或生成**的端点 —— chat / anthropic /
|
|
3521
|
+
* embeddings / rerank / images / videos —— 一律必须显式传入 `CHAT_REQUEST_TIMEOUT_MS`,
|
|
3522
|
+
* 哪怕调用方已经用 `withRequestTimeout` 建了外层预算: 外层只约束 `signal`, 内层
|
|
3523
|
+
* 会**另建**一个 `timeoutMs` 计时器, 30s 恒先于任何更长的外层预算触发。
|
|
3524
|
+
*
|
|
3525
|
+
* 这不是假设 —— 2026-08-06 事故里 chat 路径正因漏传本参数而被恒定钉死在 30s,
|
|
3526
|
+
* 且上方 v1.6.0 的注释还声称它已是 11min。回归闸门见
|
|
3527
|
+
* `tests/chat-timeout-budget.test.ts`。
|
|
3528
|
+
*/
|
|
3462
3529
|
async doJSONFullRaw(method, path, body, signal, timeoutMs = 3e4) {
|
|
3463
3530
|
return this.doJSONFullRawInternal(method, path, body, signal, false, timeoutMs);
|
|
3464
3531
|
}
|
|
@@ -4126,6 +4193,7 @@ var ScopeChatBridge = "chat_bridge";
|
|
|
4126
4193
|
var ScopeChatBridgeRead = "chat_bridge:read";
|
|
4127
4194
|
var ScopeChatBridgeWrite = "chat_bridge:write";
|
|
4128
4195
|
var ScopeChatBridgeRotate = "chat_bridge:rotate";
|
|
4196
|
+
var ScopeAgentAccessManage = "agent_access:manage";
|
|
4129
4197
|
var ScopeModels = "models";
|
|
4130
4198
|
var ScopeModelsChat = "models:chat";
|
|
4131
4199
|
var ScopeEntitlements = "entitlements";
|
|
@@ -4154,6 +4222,9 @@ function remoteControlScopes() {
|
|
|
4154
4222
|
function chatBridgeScopes() {
|
|
4155
4223
|
return [ScopeChatBridge];
|
|
4156
4224
|
}
|
|
4225
|
+
function agentAccessScopes() {
|
|
4226
|
+
return [ScopeAgentAccessManage];
|
|
4227
|
+
}
|
|
4157
4228
|
|
|
4158
4229
|
// src/models/index.ts
|
|
4159
4230
|
init_types();
|
|
@@ -7119,6 +7190,15 @@ function sleep2(ms, signal) {
|
|
|
7119
7190
|
}
|
|
7120
7191
|
|
|
7121
7192
|
// src/support/bug-report.ts
|
|
7193
|
+
function unwrapBugReport(raw, op, isComplete) {
|
|
7194
|
+
if (raw && isComplete(raw)) return raw;
|
|
7195
|
+
const inner = raw?.data;
|
|
7196
|
+
if (inner && isComplete(inner)) return inner;
|
|
7197
|
+
const keys = raw && typeof raw === "object" ? Object.keys(raw) : [];
|
|
7198
|
+
throw new Error(
|
|
7199
|
+
`acosmi: ${op}: gateway accepted the request but the response is missing required fields (observed keys: ${keys.length > 0 ? keys.join(",") : "<none>"})`
|
|
7200
|
+
);
|
|
7201
|
+
}
|
|
7122
7202
|
Client.prototype.submitBugReport = async function(reportData, signal) {
|
|
7123
7203
|
if (reportData == null) {
|
|
7124
7204
|
throw new Error("acosmi: reportData required");
|
|
@@ -7135,7 +7215,11 @@ Client.prototype.submitBugReport = async function(reportData, signal) {
|
|
|
7135
7215
|
{ content: contentStr },
|
|
7136
7216
|
signal
|
|
7137
7217
|
);
|
|
7138
|
-
return
|
|
7218
|
+
return unwrapBugReport(
|
|
7219
|
+
result,
|
|
7220
|
+
"submitBugReport",
|
|
7221
|
+
(r) => typeof r.feedback_id === "string" && r.feedback_id.length > 0
|
|
7222
|
+
);
|
|
7139
7223
|
};
|
|
7140
7224
|
Client.prototype.getBugReport = async function(bugID, signal) {
|
|
7141
7225
|
const trimmed = bugID.trim();
|
|
@@ -7148,7 +7232,7 @@ Client.prototype.getBugReport = async function(bugID, signal) {
|
|
|
7148
7232
|
null,
|
|
7149
7233
|
signal
|
|
7150
7234
|
);
|
|
7151
|
-
return resp.
|
|
7235
|
+
return unwrapBugReport(resp, "getBugReport", (r) => typeof r.id === "string");
|
|
7152
7236
|
};
|
|
7153
7237
|
|
|
7154
7238
|
// src/subscription/client.ts
|
|
@@ -7739,6 +7823,7 @@ exports.AgentRunStreamError = AgentRunStreamError;
|
|
|
7739
7823
|
exports.AgentRunsClient = AgentRunsClient;
|
|
7740
7824
|
exports.AudienceEnum = AudienceEnum;
|
|
7741
7825
|
exports.BillingModeEnum = BillingModeEnum;
|
|
7826
|
+
exports.CHAT_REQUEST_TIMEOUT_MS = CHAT_REQUEST_TIMEOUT_MS;
|
|
7742
7827
|
exports.ChatBridgeClient = ChatBridgeClient;
|
|
7743
7828
|
exports.Client = Client;
|
|
7744
7829
|
exports.ComplianceClient = ComplianceClient;
|
|
@@ -7795,6 +7880,7 @@ exports.RETRY_ADVICE_REASONS = RETRY_ADVICE_REASONS;
|
|
|
7795
7880
|
exports.RegionScopeEnum = RegionScopeEnum;
|
|
7796
7881
|
exports.ScopeAI = ScopeAI;
|
|
7797
7882
|
exports.ScopeAccount = ScopeAccount;
|
|
7883
|
+
exports.ScopeAgentAccessManage = ScopeAgentAccessManage;
|
|
7798
7884
|
exports.ScopeChatBridge = ScopeChatBridge;
|
|
7799
7885
|
exports.ScopeChatBridgeRead = ScopeChatBridgeRead;
|
|
7800
7886
|
exports.ScopeChatBridgeRotate = ScopeChatBridgeRotate;
|
|
@@ -7829,6 +7915,7 @@ exports.ScopeTools = ScopeTools;
|
|
|
7829
7915
|
exports.ScopeToolsExecute = ScopeToolsExecute;
|
|
7830
7916
|
exports.ScopeWallet = ScopeWallet;
|
|
7831
7917
|
exports.ScopeWalletReadonly = ScopeWalletReadonly;
|
|
7918
|
+
exports.agentAccessScopes = agentAccessScopes;
|
|
7832
7919
|
exports.allScopes = allScopes;
|
|
7833
7920
|
exports.anthropicResponseTextContent = anthropicResponseTextContent;
|
|
7834
7921
|
exports.anthropicResponseThinkingContent = anthropicResponseThinkingContent;
|