@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/dist/index.mjs CHANGED
@@ -2288,6 +2288,13 @@ var ErrOAuthCORSBlocked = "oauth_cors_blocked";
2288
2288
  var ErrRefreshProxyFailed = "refresh_proxy_failed";
2289
2289
  var ErrTokenExpired = "token_expired";
2290
2290
  var CHAT_REQUEST_TIMEOUT_MS = 11 * 60 * 1e3;
2291
+ function notifyUpstreamActivity(cb) {
2292
+ if (!cb) return;
2293
+ try {
2294
+ cb();
2295
+ } catch {
2296
+ }
2297
+ }
2291
2298
  var DEFAULT_API_TIMEOUT_MS = 6e4;
2292
2299
  function newDeferred() {
2293
2300
  let resolve;
@@ -3001,7 +3008,13 @@ var Client = class _Client {
3001
3008
  try {
3002
3009
  const { body, adapter } = await this.buildChatRequest(modelID, r, ctl.signal);
3003
3010
  const endpoint = `/managed-models/${encodeURIComponent(modelID)}${adapter.endpointSuffix()}`;
3004
- const { result, headers } = await this.doJSONFullRaw("POST", endpoint, body, ctl.signal);
3011
+ const { result, headers } = await this.doJSONFullRaw(
3012
+ "POST",
3013
+ endpoint,
3014
+ body,
3015
+ ctl.signal,
3016
+ CHAT_REQUEST_TIMEOUT_MS
3017
+ );
3005
3018
  const resp = adapter.parseResponse(result);
3006
3019
  const v1 = headers.get("X-Token-Remaining");
3007
3020
  if (v1) {
@@ -3066,7 +3079,13 @@ var Client = class _Client {
3066
3079
  */
3067
3080
  async generateVideo(modelID, req, signal) {
3068
3081
  const endpoint = `/managed-models/${encodeURIComponent(modelID)}/videos/generations`;
3069
- const { result } = await this.doJSONFullRaw("POST", endpoint, req, signal);
3082
+ const { result } = await this.doJSONFullRaw(
3083
+ "POST",
3084
+ endpoint,
3085
+ req,
3086
+ signal,
3087
+ CHAT_REQUEST_TIMEOUT_MS
3088
+ );
3070
3089
  return this.unwrapAPIResponse(result);
3071
3090
  }
3072
3091
  /**
@@ -3135,7 +3154,8 @@ var Client = class _Client {
3135
3154
  "POST",
3136
3155
  `/managed-models/${encodeURIComponent(modelID)}/anthropic`,
3137
3156
  data,
3138
- ctl.signal
3157
+ ctl.signal,
3158
+ CHAT_REQUEST_TIMEOUT_MS
3139
3159
  );
3140
3160
  const rawStr = new TextDecoder().decode(result);
3141
3161
  try {
@@ -3169,7 +3189,13 @@ var Client = class _Client {
3169
3189
  const body = adapter.buildRequestBody(caps, r);
3170
3190
  const data = JSON.stringify(body);
3171
3191
  const endpoint = `/managed-models/${encodeURIComponent(modelID)}${adapter.endpointSuffix()}`;
3172
- const { result } = await this.doJSONFullRaw("POST", endpoint, data, ctl.signal);
3192
+ const { result } = await this.doJSONFullRaw(
3193
+ "POST",
3194
+ endpoint,
3195
+ data,
3196
+ ctl.signal,
3197
+ CHAT_REQUEST_TIMEOUT_MS
3198
+ );
3173
3199
  const { parseOpenAIResponseToAnthropic: parseOpenAIResponseToAnthropic2 } = await Promise.resolve().then(() => (init_openai(), openai_exports));
3174
3200
  return parseOpenAIResponseToAnthropic2(result);
3175
3201
  } finally {
@@ -3179,23 +3205,27 @@ var Client = class _Client {
3179
3205
  /**
3180
3206
  * 流式聊天 (SSE), 通过 async generator 返回事件
3181
3207
  * v0.5.0: 根据 adapter 路由端点
3208
+ *
3209
+ * @param onUpstreamActivity 见 {@link UpstreamActivityCallback}
3182
3210
  */
3183
- chatStream(modelID, req, signal) {
3211
+ chatStream(modelID, req, signal, onUpstreamActivity) {
3184
3212
  return {
3185
- [Symbol.asyncIterator]: () => this.chatStreamGen(modelID, req, signal, false)
3213
+ [Symbol.asyncIterator]: () => this.chatStreamGen(modelID, req, signal, false, onUpstreamActivity)
3186
3214
  };
3187
3215
  }
3188
3216
  /**
3189
3217
  * Anthropic 原生格式流式聊天 (SSE)
3190
3218
  * 调用 POST /managed-models/:id/anthropic, SSE 事件为 Anthropic 协议格式
3191
3219
  * 无 started/settled/failed 自定义事件, 无 data: [DONE], message_stop 为自然结束
3220
+ *
3221
+ * @param onUpstreamActivity 见 {@link UpstreamActivityCallback}
3192
3222
  */
3193
- chatMessagesStream(modelID, req, signal) {
3223
+ chatMessagesStream(modelID, req, signal, onUpstreamActivity) {
3194
3224
  return {
3195
- [Symbol.asyncIterator]: () => this.chatMessagesStreamGen(modelID, req, signal, false)
3225
+ [Symbol.asyncIterator]: () => this.chatMessagesStreamGen(modelID, req, signal, false, onUpstreamActivity)
3196
3226
  };
3197
3227
  }
3198
- async *chatStreamGen(modelID, req, signal, retried) {
3228
+ async *chatStreamGen(modelID, req, signal, retried, onUpstreamActivity) {
3199
3229
  const r = { ...req, stream: true };
3200
3230
  const { body, adapter } = await this.buildChatRequest(modelID, r, signal);
3201
3231
  const token = await this.ensureToken(signal);
@@ -3228,7 +3258,7 @@ var Client = class _Client {
3228
3258
  `stream: unauthorized and refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`
3229
3259
  );
3230
3260
  }
3231
- yield* this.chatStreamGen(modelID, req, signal, true);
3261
+ yield* this.chatStreamGen(modelID, req, signal, true, onUpstreamActivity);
3232
3262
  return;
3233
3263
  }
3234
3264
  if (!resp.ok) {
@@ -3244,6 +3274,7 @@ var Client = class _Client {
3244
3274
  }
3245
3275
  let currentEvent = "";
3246
3276
  for await (const line of iterSSELines(resp.body)) {
3277
+ notifyUpstreamActivity(onUpstreamActivity);
3247
3278
  if (isSSECommentLine(line)) continue;
3248
3279
  if (line.startsWith("event:")) {
3249
3280
  currentEvent = line.slice("event:".length).trim();
@@ -3264,7 +3295,7 @@ var Client = class _Client {
3264
3295
  }
3265
3296
  }
3266
3297
  }
3267
- async *chatMessagesStreamGen(modelID, req, signal, retried) {
3298
+ async *chatMessagesStreamGen(modelID, req, signal, retried, onUpstreamActivity) {
3268
3299
  const r = { ...req, stream: true };
3269
3300
  const { body, adapter } = await this.buildChatRequest(modelID, r, signal);
3270
3301
  const token = await this.ensureToken(signal);
@@ -3297,7 +3328,7 @@ var Client = class _Client {
3297
3328
  `messages stream: unauthorized and refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`
3298
3329
  );
3299
3330
  }
3300
- yield* this.chatMessagesStreamGen(modelID, req, signal, true);
3331
+ yield* this.chatMessagesStreamGen(modelID, req, signal, true, onUpstreamActivity);
3301
3332
  return;
3302
3333
  }
3303
3334
  if (!resp.ok) {
@@ -3310,6 +3341,7 @@ var Client = class _Client {
3310
3341
  if (adapter.format() === 1 /* OpenAI */) {
3311
3342
  const converter = newOpenAIStreamConverter();
3312
3343
  for await (const line of iterSSELines(resp.body)) {
3344
+ notifyUpstreamActivity(onUpstreamActivity);
3313
3345
  if (isSSECommentLine(line)) continue;
3314
3346
  if (line.startsWith("event:")) {
3315
3347
  line.slice("event:".length).trim();
@@ -3324,6 +3356,7 @@ var Client = class _Client {
3324
3356
  const blockTypeMap = /* @__PURE__ */ new Map();
3325
3357
  let currentEvent = "";
3326
3358
  for await (const line of iterSSELines(resp.body)) {
3359
+ notifyUpstreamActivity(onUpstreamActivity);
3327
3360
  if (isSSECommentLine(line)) continue;
3328
3361
  if (line.startsWith("event:")) {
3329
3362
  currentEvent = line.slice("event:".length).trim();
@@ -3456,7 +3489,19 @@ var Client = class _Client {
3456
3489
  ctl.dispose();
3457
3490
  }
3458
3491
  }
3459
- /** doJSONFull 的 raw bytes 变体 (chat 用, 不立即 JSON.parse) */
3492
+ /**
3493
+ * doJSONFull 的 raw bytes 变体 (chat 用, 不立即 JSON.parse)
3494
+ *
3495
+ * ⚠️ 契约 (2026-08-06): `timeoutMs` 的 30s 默认值只适用于**控制面**端点 (列目录 /
3496
+ * 查配额 / 取任务状态)。凡走**模型推理或生成**的端点 —— chat / anthropic /
3497
+ * embeddings / rerank / images / videos —— 一律必须显式传入 `CHAT_REQUEST_TIMEOUT_MS`,
3498
+ * 哪怕调用方已经用 `withRequestTimeout` 建了外层预算: 外层只约束 `signal`, 内层
3499
+ * 会**另建**一个 `timeoutMs` 计时器, 30s 恒先于任何更长的外层预算触发。
3500
+ *
3501
+ * 这不是假设 —— 2026-08-06 事故里 chat 路径正因漏传本参数而被恒定钉死在 30s,
3502
+ * 且上方 v1.6.0 的注释还声称它已是 11min。回归闸门见
3503
+ * `tests/chat-timeout-budget.test.ts`。
3504
+ */
3460
3505
  async doJSONFullRaw(method, path, body, signal, timeoutMs = 3e4) {
3461
3506
  return this.doJSONFullRawInternal(method, path, body, signal, false, timeoutMs);
3462
3507
  }
@@ -7117,6 +7162,15 @@ function sleep2(ms, signal) {
7117
7162
  }
7118
7163
 
7119
7164
  // src/support/bug-report.ts
7165
+ function unwrapBugReport(raw, op, isComplete) {
7166
+ if (raw && isComplete(raw)) return raw;
7167
+ const inner = raw?.data;
7168
+ if (inner && isComplete(inner)) return inner;
7169
+ const keys = raw && typeof raw === "object" ? Object.keys(raw) : [];
7170
+ throw new Error(
7171
+ `acosmi: ${op}: gateway accepted the request but the response is missing required fields (observed keys: ${keys.length > 0 ? keys.join(",") : "<none>"})`
7172
+ );
7173
+ }
7120
7174
  Client.prototype.submitBugReport = async function(reportData, signal) {
7121
7175
  if (reportData == null) {
7122
7176
  throw new Error("acosmi: reportData required");
@@ -7133,7 +7187,11 @@ Client.prototype.submitBugReport = async function(reportData, signal) {
7133
7187
  { content: contentStr },
7134
7188
  signal
7135
7189
  );
7136
- return result.data;
7190
+ return unwrapBugReport(
7191
+ result,
7192
+ "submitBugReport",
7193
+ (r) => typeof r.feedback_id === "string" && r.feedback_id.length > 0
7194
+ );
7137
7195
  };
7138
7196
  Client.prototype.getBugReport = async function(bugID, signal) {
7139
7197
  const trimmed = bugID.trim();
@@ -7146,7 +7204,7 @@ Client.prototype.getBugReport = async function(bugID, signal) {
7146
7204
  null,
7147
7205
  signal
7148
7206
  );
7149
- return resp.data;
7207
+ return unwrapBugReport(resp, "getBugReport", (r) => typeof r.id === "string");
7150
7208
  };
7151
7209
 
7152
7210
  // src/subscription/client.ts
@@ -7728,6 +7786,6 @@ function brandCredential(c) {
7728
7786
  return c;
7729
7787
  }
7730
7788
 
7731
- export { AGENT_RUN_META_TITLE, AGENT_RUN_META_WORKSPACE, ALL_INTEGRATION_STATUS, ALL_PLATFORMS, ALL_REGIONS, AgentRunStreamError, AgentRunsClient, AnthropicAdapter, AudienceEnum, BillingModeEnum, BucketClassCommercial, BucketClassGeneric, BusinessError, ChatBridgeClient, Client, ComplianceClient, CompliancePollError, CrabCodeByokClient, DEFAULT_API_TIMEOUT_MS, DEFAULT_GATEWAY_BASE_URL, DefaultRetryPolicy, ErrAuthDenied, ErrBillingCallbackCannotCommit, ErrBillingCommitRequiresLocalVerify, ErrBillingS2sForbidden, ErrBrowserOpen, ErrComplianceStepUpRequired, ErrDiscovery, ErrEnvelopeGateClosed, ErrOAuthCORSBlocked, ErrProviderNotConfigured, ErrProviderUnknownNoRetry, ErrRefreshProxyFailed, ErrRegistration, ErrSSLProxy, ErrSealApprovalContractHashMismatch, ErrSealApprovalExpired, ErrSealApprovalLocationMismatch, ErrSealApprovalNonceUsed, ErrSealApprovalNotApproved, ErrSealApprovalSealMismatch, ErrSealApprovalTransactorMismatch, ErrSealUseAlreadyConsumed, ErrStateMismatch, ErrTimeout, ErrTokenExchange, ErrTokenExpired, EventAuthURL, EventComplete, EventError, FileTokenStore, FilterStatusAdminBypass, FilterStatusDisabledByFlag, FilterStatusFallbackMissingUser, FilterStatusFallbackNoBuckets, FilterStatusFallbackTkdistError, FilterStatusFallbackTkdistSkew, FilterStatusInternalBypass, FilterStatusOK, FilterStatusUnknown, HTTPError, IdempotencyKeyHeader, InMemoryTokenStore, LocalStorageTokenStore, ModelNotFoundError, NetworkError, OAuthTokenEndpointError, OpenAIAdapter, OrderTerminalError, ProductFamilyEnum, ProviderFormat, RETRY_ADVICE_REASONS, RateLimitError, RegionScopeEnum, ScopeAI, ScopeAccount, ScopeChatBridge, ScopeChatBridgeRead, ScopeChatBridgeRotate, ScopeChatBridgeWrite, ScopeComplianceContractSigningRead, ScopeComplianceContractSigningWrite, ScopeComplianceContractTemplateRead, ScopeComplianceContractTemplateWrite, ScopeComplianceEvidenceRead, ScopeComplianceEvidenceWrite, ScopeComplianceReportsPublish, ScopeComplianceReportsRead, ScopeComplianceReportsWrite, ScopeComplianceSealApprovalApprove, ScopeComplianceSealApprovalRequest, ScopeComplianceSealManage, ScopeComplianceSealUseExecute, ScopeComplianceTimestampIssue, ScopeComplianceTimestampVerify, ScopeEntitlements, ScopeModels, ScopeModelsChat, ScopeProfile, ScopeRemoteControl, ScopeRemoteControlAgentRun, ScopeRemoteControlPermissionResponse, ScopeRemoteControlSessionControl, ScopeSkillStore, ScopeSkills, ScopeTokenPackages, ScopeTools, ScopeToolsExecute, ScopeWallet, ScopeWalletReadonly, ServerToolTypeWebSearch, StreamError, ThinkingHigh, ThinkingHighMinMaxTokens, ThinkingMax, ThinkingMaxFallbackMaxTokens, ThinkingOff, allScopes, anthropicResponseTextContent, anthropicResponseThinkingContent, anthropicResponseToolUseBlocks, apiResponseBusinessError, apiResponseGetMessage, asCredentialRef, authorize, bucketInfoIsCommercial, bucketRowIsCommercial, buildBetas, chatBridgeScopes, classifyComplianceError, classifySourcesEvent, commerceScopes, completeWebAuthorizationRequest, complianceErrorToRetryAdvice, complianceScopes, computeBackoff, createWebAuthorizationRequest, defaultRetryable, defaultSafeToRetry, discover, discoverWebOAuthMetadata, discoverWithProfile, effectivePolicy, exchangeCode, extractAnthropicBlockMeta, fileLockDefaults, findDesktopVisualUnderstandingModel, findFirstModelByInputModality, generateState, getAdapter, getAdapterForModel, getWindowLimitStreamDetails, isBillingConfirmable, isChannelInboundEvent, isComplianceBusinessError, isComplianceTerminalError, isContinuableWindowLimitError, isIntegrationStatus, isInvalidGrantError, isPlatform, isRegion, isSSECommentLine, isSSLError, isTerminalRemoteEvent, isValidTokenSet, isWindowLimitError, isWindowLimitStreamError, maxEndUserIdLength, modelScopes, modelSupportsImageInput, modelSupportsInputModality, newFileTokenStore, newThinkingConfig, newTokenSet, newWebSearchTool, normalizeGatewayBaseURL, normalizeOverrideBaseURL, parseNotificationEvent, parseRemoteControlEvent, parseSettlement, parseSourcesEvent, refreshToken, register, registerWebOAuthClient, remoteControlScopes, retryReasonForComplianceKey, retryReasonForOAuthError, revokeToken, sanitize_exports as sanitize, skillScopes, tokenSetIsExpired, uniqueMerge, validateEndUserId };
7789
+ export { AGENT_RUN_META_TITLE, AGENT_RUN_META_WORKSPACE, ALL_INTEGRATION_STATUS, ALL_PLATFORMS, ALL_REGIONS, AgentRunStreamError, AgentRunsClient, AnthropicAdapter, AudienceEnum, BillingModeEnum, BucketClassCommercial, BucketClassGeneric, BusinessError, CHAT_REQUEST_TIMEOUT_MS, ChatBridgeClient, Client, ComplianceClient, CompliancePollError, CrabCodeByokClient, DEFAULT_API_TIMEOUT_MS, DEFAULT_GATEWAY_BASE_URL, DefaultRetryPolicy, ErrAuthDenied, ErrBillingCallbackCannotCommit, ErrBillingCommitRequiresLocalVerify, ErrBillingS2sForbidden, ErrBrowserOpen, ErrComplianceStepUpRequired, ErrDiscovery, ErrEnvelopeGateClosed, ErrOAuthCORSBlocked, ErrProviderNotConfigured, ErrProviderUnknownNoRetry, ErrRefreshProxyFailed, ErrRegistration, ErrSSLProxy, ErrSealApprovalContractHashMismatch, ErrSealApprovalExpired, ErrSealApprovalLocationMismatch, ErrSealApprovalNonceUsed, ErrSealApprovalNotApproved, ErrSealApprovalSealMismatch, ErrSealApprovalTransactorMismatch, ErrSealUseAlreadyConsumed, ErrStateMismatch, ErrTimeout, ErrTokenExchange, ErrTokenExpired, EventAuthURL, EventComplete, EventError, FileTokenStore, FilterStatusAdminBypass, FilterStatusDisabledByFlag, FilterStatusFallbackMissingUser, FilterStatusFallbackNoBuckets, FilterStatusFallbackTkdistError, FilterStatusFallbackTkdistSkew, FilterStatusInternalBypass, FilterStatusOK, FilterStatusUnknown, HTTPError, IdempotencyKeyHeader, InMemoryTokenStore, LocalStorageTokenStore, ModelNotFoundError, NetworkError, OAuthTokenEndpointError, OpenAIAdapter, OrderTerminalError, ProductFamilyEnum, ProviderFormat, RETRY_ADVICE_REASONS, RateLimitError, RegionScopeEnum, ScopeAI, ScopeAccount, ScopeChatBridge, ScopeChatBridgeRead, ScopeChatBridgeRotate, ScopeChatBridgeWrite, ScopeComplianceContractSigningRead, ScopeComplianceContractSigningWrite, ScopeComplianceContractTemplateRead, ScopeComplianceContractTemplateWrite, ScopeComplianceEvidenceRead, ScopeComplianceEvidenceWrite, ScopeComplianceReportsPublish, ScopeComplianceReportsRead, ScopeComplianceReportsWrite, ScopeComplianceSealApprovalApprove, ScopeComplianceSealApprovalRequest, ScopeComplianceSealManage, ScopeComplianceSealUseExecute, ScopeComplianceTimestampIssue, ScopeComplianceTimestampVerify, ScopeEntitlements, ScopeModels, ScopeModelsChat, ScopeProfile, ScopeRemoteControl, ScopeRemoteControlAgentRun, ScopeRemoteControlPermissionResponse, ScopeRemoteControlSessionControl, ScopeSkillStore, ScopeSkills, ScopeTokenPackages, ScopeTools, ScopeToolsExecute, ScopeWallet, ScopeWalletReadonly, ServerToolTypeWebSearch, StreamError, ThinkingHigh, ThinkingHighMinMaxTokens, ThinkingMax, ThinkingMaxFallbackMaxTokens, ThinkingOff, allScopes, anthropicResponseTextContent, anthropicResponseThinkingContent, anthropicResponseToolUseBlocks, apiResponseBusinessError, apiResponseGetMessage, asCredentialRef, authorize, bucketInfoIsCommercial, bucketRowIsCommercial, buildBetas, chatBridgeScopes, classifyComplianceError, classifySourcesEvent, commerceScopes, completeWebAuthorizationRequest, complianceErrorToRetryAdvice, complianceScopes, computeBackoff, createWebAuthorizationRequest, defaultRetryable, defaultSafeToRetry, discover, discoverWebOAuthMetadata, discoverWithProfile, effectivePolicy, exchangeCode, extractAnthropicBlockMeta, fileLockDefaults, findDesktopVisualUnderstandingModel, findFirstModelByInputModality, generateState, getAdapter, getAdapterForModel, getWindowLimitStreamDetails, isBillingConfirmable, isChannelInboundEvent, isComplianceBusinessError, isComplianceTerminalError, isContinuableWindowLimitError, isIntegrationStatus, isInvalidGrantError, isPlatform, isRegion, isSSECommentLine, isSSLError, isTerminalRemoteEvent, isValidTokenSet, isWindowLimitError, isWindowLimitStreamError, maxEndUserIdLength, modelScopes, modelSupportsImageInput, modelSupportsInputModality, newFileTokenStore, newThinkingConfig, newTokenSet, newWebSearchTool, normalizeGatewayBaseURL, normalizeOverrideBaseURL, parseNotificationEvent, parseRemoteControlEvent, parseSettlement, parseSourcesEvent, refreshToken, register, registerWebOAuthClient, remoteControlScopes, retryReasonForComplianceKey, retryReasonForOAuthError, revokeToken, sanitize_exports as sanitize, skillScopes, tokenSetIsExpired, uniqueMerge, validateEndUserId };
7732
7790
  //# sourceMappingURL=index.mjs.map
7733
7791
  //# sourceMappingURL=index.mjs.map