@jsonstudio/rcc 0.89.1803 → 0.89.1959
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/configsamples/config.json +19 -0
- package/configsamples/provider/deepseek/config.v1.json +59 -0
- package/dist/build-info.js +2 -2
- package/dist/cli/commands/claude.d.ts +4 -0
- package/dist/cli/commands/claude.js +56 -0
- package/dist/cli/commands/claude.js.map +1 -0
- package/dist/cli/commands/clock-admin.d.ts +20 -0
- package/dist/cli/commands/clock-admin.js +234 -0
- package/dist/cli/commands/clock-admin.js.map +1 -0
- package/dist/cli/commands/code.d.ts +0 -42
- package/dist/cli/commands/code.js +4 -414
- package/dist/cli/commands/code.js.map +1 -1
- package/dist/cli/commands/codex.d.ts +4 -0
- package/dist/cli/commands/codex.js +43 -0
- package/dist/cli/commands/codex.js.map +1 -0
- package/dist/cli/commands/examples.js +13 -16
- package/dist/cli/commands/examples.js.map +1 -1
- package/dist/cli/commands/init/basic.d.ts +40 -0
- package/dist/cli/commands/init/basic.js +482 -0
- package/dist/cli/commands/init/basic.js.map +1 -0
- package/dist/cli/commands/init/camoufox.d.ts +7 -0
- package/dist/cli/commands/init/camoufox.js +59 -0
- package/dist/cli/commands/init/camoufox.js.map +1 -0
- package/dist/cli/commands/init/interactive.d.ts +18 -0
- package/dist/cli/commands/init/interactive.js +223 -0
- package/dist/cli/commands/init/interactive.js.map +1 -0
- package/dist/cli/commands/init/shared.d.ts +66 -0
- package/dist/cli/commands/init/shared.js +9 -0
- package/dist/cli/commands/init/shared.js.map +1 -0
- package/dist/cli/commands/init/workflows.d.ts +29 -0
- package/dist/cli/commands/init/workflows.js +341 -0
- package/dist/cli/commands/init/workflows.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -26
- package/dist/cli/commands/init.js +220 -53
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/launcher-kernel.d.ts +78 -0
- package/dist/cli/commands/launcher-kernel.js +1194 -0
- package/dist/cli/commands/launcher-kernel.js.map +1 -0
- package/dist/cli/commands/start.js +27 -1
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.js +24 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/stop.d.ts +1 -0
- package/dist/cli/commands/stop.js +201 -4
- package/dist/cli/commands/stop.js.map +1 -1
- package/dist/cli/commands/tmux-inject.d.ts +20 -0
- package/dist/cli/commands/tmux-inject.js +212 -0
- package/dist/cli/commands/tmux-inject.js.map +1 -0
- package/dist/cli/config/init-provider-catalog.js +34 -0
- package/dist/cli/config/init-provider-catalog.js.map +1 -1
- package/dist/cli/register/claude-command.d.ts +3 -0
- package/dist/cli/register/claude-command.js +5 -0
- package/dist/cli/register/claude-command.js.map +1 -0
- package/dist/cli/register/clock-admin-command.d.ts +3 -0
- package/dist/cli/register/clock-admin-command.js +5 -0
- package/dist/cli/register/clock-admin-command.js.map +1 -0
- package/dist/cli/register/codex-command.d.ts +3 -0
- package/dist/cli/register/codex-command.js +5 -0
- package/dist/cli/register/codex-command.js.map +1 -0
- package/dist/cli/register/status-config-commands.d.ts +2 -0
- package/dist/cli/register/status-config-commands.js.map +1 -1
- package/dist/cli/register/tmux-inject-command.d.ts +3 -0
- package/dist/cli/register/tmux-inject-command.js +5 -0
- package/dist/cli/register/tmux-inject-command.js.map +1 -0
- package/dist/cli/server/port-utils.d.ts +3 -2
- package/dist/cli/server/port-utils.js +171 -32
- package/dist/cli/server/port-utils.js.map +1 -1
- package/dist/cli.js +45 -6
- package/dist/cli.js.map +1 -1
- package/dist/client/gemini/gemini-protocol-client.js +56 -5
- package/dist/client/gemini/gemini-protocol-client.js.map +1 -1
- package/dist/commands/token-daemon.js +59 -7
- package/dist/commands/token-daemon.js.map +1 -1
- package/dist/commands/validate.js +87 -15
- package/dist/commands/validate.js.map +1 -1
- package/dist/config/routecodex-config-loader.js +31 -2
- package/dist/config/routecodex-config-loader.js.map +1 -1
- package/dist/docs/daemon-admin-ui.html +948 -74
- package/dist/index.d.ts +1 -0
- package/dist/index.js +325 -37
- package/dist/index.js.map +1 -1
- package/dist/manager/quota/provider-quota-center.js +8 -14
- package/dist/manager/quota/provider-quota-center.js.map +1 -1
- package/dist/modules/llmswitch/bridge.d.ts +39 -0
- package/dist/modules/llmswitch/bridge.js +169 -0
- package/dist/modules/llmswitch/bridge.js.map +1 -1
- package/dist/modules/pipeline/utils/colored-logger.js +1 -1
- package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
- package/dist/providers/auth/deepseek-account-auth.d.ts +39 -0
- package/dist/providers/auth/deepseek-account-auth.js +329 -0
- package/dist/providers/auth/deepseek-account-auth.js.map +1 -0
- package/dist/providers/auth/deepseek-account-token-acquirer.d.ts +15 -0
- package/dist/providers/auth/deepseek-account-token-acquirer.js +644 -0
- package/dist/providers/auth/deepseek-account-token-acquirer.js.map +1 -0
- package/dist/providers/auth/oauth-lifecycle.js +26 -4
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/auth/oauth-repair-cooldown.d.ts +5 -0
- package/dist/providers/auth/oauth-repair-cooldown.js +39 -0
- package/dist/providers/auth/oauth-repair-cooldown.js.map +1 -1
- package/dist/providers/auth/token-scanner/index.d.ts +6 -0
- package/dist/providers/auth/token-scanner/index.js +53 -0
- package/dist/providers/auth/token-scanner/index.js.map +1 -1
- package/dist/providers/core/api/provider-config.d.ts +17 -2
- package/dist/providers/core/api/provider-types.d.ts +6 -0
- package/dist/providers/core/api/provider-types.js.map +1 -1
- package/dist/providers/core/config/camoufox-launcher.d.ts +7 -0
- package/dist/providers/core/config/camoufox-launcher.js +68 -21
- package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
- package/dist/providers/core/config/service-profiles.js +19 -0
- package/dist/providers/core/config/service-profiles.js.map +1 -1
- package/dist/providers/core/contracts/deepseek-provider-contract.d.ts +34 -0
- package/dist/providers/core/contracts/deepseek-provider-contract.js +100 -0
- package/dist/providers/core/contracts/deepseek-provider-contract.js.map +1 -0
- package/dist/providers/core/runtime/anthropic-http-provider.d.ts +0 -5
- package/dist/providers/core/runtime/anthropic-http-provider.js +0 -26
- package/dist/providers/core/runtime/anthropic-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/deepseek-http-provider.d.ts +35 -0
- package/dist/providers/core/runtime/deepseek-http-provider.js +373 -0
- package/dist/providers/core/runtime/deepseek-http-provider.js.map +1 -0
- package/dist/providers/core/runtime/deepseek-session-pow.d.ts +55 -0
- package/dist/providers/core/runtime/deepseek-session-pow.js +422 -0
- package/dist/providers/core/runtime/deepseek-session-pow.js.map +1 -0
- package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +0 -3
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +0 -72
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-http-provider.d.ts +1 -7
- package/dist/providers/core/runtime/gemini-http-provider.js +3 -110
- package/dist/providers/core/runtime/gemini-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/http-request-executor.d.ts +1 -0
- package/dist/providers/core/runtime/http-request-executor.js +4 -0
- package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
- package/dist/providers/core/runtime/http-transport-provider.d.ts +10 -4
- package/dist/providers/core/runtime/http-transport-provider.js +308 -82
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/runtime/iflow-http-provider.d.ts +0 -4
- package/dist/providers/core/runtime/iflow-http-provider.js +0 -28
- package/dist/providers/core/runtime/iflow-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/provider-factory.d.ts +5 -0
- package/dist/providers/core/runtime/provider-factory.js +59 -6
- package/dist/providers/core/runtime/provider-factory.js.map +1 -1
- package/dist/providers/core/runtime/responses-provider.d.ts +0 -2
- package/dist/providers/core/runtime/responses-provider.js +0 -11
- package/dist/providers/core/runtime/responses-provider.js.map +1 -1
- package/dist/providers/core/strategies/oauth-device-flow.js +16 -1
- package/dist/providers/core/strategies/oauth-device-flow.js.map +1 -1
- package/dist/providers/core/utils/provider-type-utils.js +2 -1
- package/dist/providers/core/utils/provider-type-utils.js.map +1 -1
- package/dist/providers/profile/families/anthropic-profile.d.ts +2 -0
- package/dist/providers/profile/families/anthropic-profile.js +32 -0
- package/dist/providers/profile/families/anthropic-profile.js.map +1 -0
- package/dist/providers/profile/families/antigravity-profile.d.ts +2 -0
- package/dist/providers/profile/families/antigravity-profile.js +109 -0
- package/dist/providers/profile/families/antigravity-profile.js.map +1 -0
- package/dist/providers/profile/families/glm-profile.d.ts +2 -0
- package/dist/providers/profile/families/glm-profile.js +48 -0
- package/dist/providers/profile/families/glm-profile.js.map +1 -0
- package/dist/providers/profile/families/iflow-profile.d.ts +2 -0
- package/dist/providers/profile/families/iflow-profile.js +232 -0
- package/dist/providers/profile/families/iflow-profile.js.map +1 -0
- package/dist/providers/profile/families/qwen-profile.d.ts +2 -0
- package/dist/providers/profile/families/qwen-profile.js +14 -0
- package/dist/providers/profile/families/qwen-profile.js.map +1 -0
- package/dist/providers/profile/families/responses-profile.d.ts +2 -0
- package/dist/providers/profile/families/responses-profile.js +28 -0
- package/dist/providers/profile/families/responses-profile.js.map +1 -0
- package/dist/providers/profile/profile-contracts.d.ts +74 -0
- package/dist/providers/profile/profile-contracts.js +2 -0
- package/dist/providers/profile/profile-contracts.js.map +1 -0
- package/dist/providers/profile/profile-registry.d.ts +3 -0
- package/dist/providers/profile/profile-registry.js +40 -0
- package/dist/providers/profile/profile-registry.js.map +1 -0
- package/dist/providers/profile/provider-directory.d.ts +2 -0
- package/dist/providers/profile/provider-directory.js +55 -0
- package/dist/providers/profile/provider-directory.js.map +1 -0
- package/dist/providers/profile/provider-profile-loader.js +43 -3
- package/dist/providers/profile/provider-profile-loader.js.map +1 -1
- package/dist/providers/profile/provider-profile.d.ts +8 -0
- package/dist/scripts/deepseek/pow-solver.mjs +146 -0
- package/dist/scripts/deepseek/sha3_wasm_bg.7b9ca65ddd.wasm +0 -0
- package/dist/server/handlers/config-admin-handler.js +27 -0
- package/dist/server/handlers/config-admin-handler.js.map +1 -1
- package/dist/server/runtime/http-server/clock-client-registry.d.ts +113 -0
- package/dist/server/runtime/http-server/clock-client-registry.js +592 -0
- package/dist/server/runtime/http-server/clock-client-registry.js.map +1 -0
- package/dist/server/runtime/http-server/clock-client-routes.d.ts +2 -0
- package/dist/server/runtime/http-server/clock-client-routes.js +481 -0
- package/dist/server/runtime/http-server/clock-client-routes.js.map +1 -0
- package/dist/server/runtime/http-server/clock-daemon-inject-config.d.ts +1 -0
- package/dist/server/runtime/http-server/clock-daemon-inject-config.js +11 -0
- package/dist/server/runtime/http-server/clock-daemon-inject-config.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +3 -3
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/auth-session.d.ts +1 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-session.js +18 -2
- package/dist/server/runtime/http-server/daemon-admin/auth-session.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/control-handler.js +2 -15
- package/dist/server/runtime/http-server/daemon-admin/control-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +65 -7
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
- package/dist/server/runtime/http-server/executor-metadata.js +37 -1
- package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
- package/dist/server/runtime/http-server/executor-provider.js +55 -0
- package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
- package/dist/server/runtime/http-server/executor-response.js +49 -1
- package/dist/server/runtime/http-server/executor-response.js.map +1 -1
- package/dist/server/runtime/http-server/index.d.ts +10 -0
- package/dist/server/runtime/http-server/index.js +534 -9
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/dist/server/runtime/http-server/managed-process-probe.d.ts +6 -0
- package/dist/server/runtime/http-server/managed-process-probe.js +294 -0
- package/dist/server/runtime/http-server/managed-process-probe.js.map +1 -0
- package/dist/server/runtime/http-server/middleware.js +16 -1
- package/dist/server/runtime/http-server/middleware.js.map +1 -1
- package/dist/server/runtime/http-server/provider-utils.js +6 -2
- package/dist/server/runtime/http-server/provider-utils.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.d.ts +1 -0
- package/dist/server/runtime/http-server/request-executor.js +360 -35
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.js +95 -3
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/stats-manager.d.ts +10 -0
- package/dist/server/runtime/http-server/stats-manager.js +119 -16
- package/dist/server/runtime/http-server/stats-manager.js.map +1 -1
- package/dist/server/runtime/http-server/tmux-session-probe.d.ts +3 -0
- package/dist/server/runtime/http-server/tmux-session-probe.js +101 -0
- package/dist/server/runtime/http-server/tmux-session-probe.js.map +1 -0
- package/dist/server/utils/stage-logger.js +21 -5
- package/dist/server/utils/stage-logger.js.map +1 -1
- package/dist/token-daemon/index.js +59 -10
- package/dist/token-daemon/index.js.map +1 -1
- package/dist/token-daemon/server-utils.d.ts +1 -0
- package/dist/token-daemon/server-utils.js +4 -1
- package/dist/token-daemon/server-utils.js.map +1 -1
- package/dist/token-daemon/token-daemon.js +38 -4
- package/dist/token-daemon/token-daemon.js.map +1 -1
- package/dist/token-daemon/token-types.d.ts +1 -1
- package/dist/token-daemon/token-types.js +2 -1
- package/dist/token-daemon/token-types.js.map +1 -1
- package/dist/token-daemon/token-utils.js +5 -2
- package/dist/token-daemon/token-utils.js.map +1 -1
- package/dist/utils/clock-client-token.d.ts +3 -0
- package/dist/utils/clock-client-token.js +54 -0
- package/dist/utils/clock-client-token.js.map +1 -0
- package/dist/utils/managed-server-pids.d.ts +25 -0
- package/dist/utils/managed-server-pids.js +176 -0
- package/dist/utils/managed-server-pids.js.map +1 -0
- package/dist/utils/process-lifecycle-logger.d.ts +8 -0
- package/dist/utils/process-lifecycle-logger.js +151 -0
- package/dist/utils/process-lifecycle-logger.js.map +1 -0
- package/dist/utils/runtime-exit-forensics.d.ts +30 -0
- package/dist/utils/runtime-exit-forensics.js +101 -0
- package/dist/utils/runtime-exit-forensics.js.map +1 -0
- package/dist/utils/shutdown-caller-context.d.ts +22 -0
- package/dist/utils/shutdown-caller-context.js +25 -0
- package/dist/utils/shutdown-caller-context.js.map +1 -0
- package/docs/PROVIDERS_BUILTIN.md +8 -0
- package/docs/PROVIDER_TYPES.md +3 -1
- package/docs/SERVERTOOL_PRE_COMMAND_HOOKS.md +85 -0
- package/docs/clock-client-daemon-design.md +343 -0
- package/docs/daemon-admin-ui.html +948 -74
- package/docs/providers/deepseek-web-provider-design.md +192 -0
- package/docs/routing-instructions.md +4 -1
- package/docs/stop-message-auto.md +4 -3
- package/docs/v2-architecture/PROVIDER-V2-CHANGESET-RELEASE-CHECKLIST.md +80 -0
- package/docs/v2-architecture/PROVIDER-V2-LAYERING-ADR-DRAFT.md +225 -0
- package/docs/v2-architecture/PROVIDER-V2-MIGRATION-MATRIX-DRAFT.md +88 -0
- package/docs/v2-architecture/PROVIDER-V2-PHASED-MIGRATION-ROLLBACK-DRAFT.md +164 -0
- package/docs/v2-architecture/PROVIDER-V2-PROFILE-API-REGISTRY-DRAFT.md +201 -0
- package/docs/v2-architecture/PROVIDER-V2-PROFILE-GEMINI-DRAFT.md +56 -0
- package/docs/v2-architecture/PROVIDER-V2-REFACTOR-OVERVIEW-DRAFT.md +102 -0
- package/docs/v2-architecture/PROVIDER-V2-VERIFICATION-MATRIX-DRAFT.md +163 -0
- package/package.json +10 -9
- package/scripts/copy-compat-assets.mjs +18 -0
- package/scripts/copy-modules-config.mjs +1 -0
- package/scripts/deepseek/pow-solver.mjs +146 -0
- package/scripts/deepseek/sha3_wasm_bg.7b9ca65ddd.wasm +0 -0
- package/scripts/ensure-cli-executable.mjs +64 -0
- package/scripts/install-global.sh +5 -2
- package/scripts/install.sh +1 -1
- package/scripts/monitor/daemon-kill-watch.mjs +184 -0
- package/scripts/monitor/port-kill-watch.sh +74 -0
- package/scripts/quick-install.sh +1 -1
|
@@ -4,12 +4,69 @@ import { attachProviderRuntimeMetadata } from '../../../providers/core/runtime/p
|
|
|
4
4
|
import { extractAnthropicToolAliasMap } from './anthropic-tool-alias.js';
|
|
5
5
|
import { enhanceProviderRequestId } from '../../utils/request-id-manager.js';
|
|
6
6
|
import { buildRequestMetadata, cloneClientHeaders, decorateMetadataForAttempt, ensureClientHeadersOnPayload, resolveClientRequestId } from './executor-metadata.js';
|
|
7
|
-
import { describeRetryReason,
|
|
7
|
+
import { describeRetryReason, shouldRetryProviderError, waitBeforeRetry } from './executor-provider.js';
|
|
8
8
|
import { convertProviderResponse as bridgeConvertProviderResponse, createSnapshotRecorder as bridgeCreateSnapshotRecorder, } from '../../../modules/llmswitch/bridge.js';
|
|
9
|
+
import { getClockClientRegistry, injectClockClientPrompt } from './clock-client-registry.js';
|
|
9
10
|
import { ensureHubPipeline, runHubPipeline } from './executor-pipeline.js';
|
|
10
11
|
import { buildInfo } from '../../../build-info.js';
|
|
11
12
|
const DEFAULT_MAX_PROVIDER_ATTEMPTS = 6;
|
|
12
13
|
const DEFAULT_ANTIGRAVITY_MAX_PROVIDER_ATTEMPTS = 20;
|
|
14
|
+
const RETRYABLE_SSE_ERROR_CODE_HINTS = [
|
|
15
|
+
'internal_network_failure',
|
|
16
|
+
'network_error',
|
|
17
|
+
'api_connection_error',
|
|
18
|
+
'service_unavailable',
|
|
19
|
+
'internal_server_error',
|
|
20
|
+
'overloaded_error',
|
|
21
|
+
'rate_limit_error',
|
|
22
|
+
'request_timeout',
|
|
23
|
+
'timeout'
|
|
24
|
+
];
|
|
25
|
+
const RETRYABLE_SSE_MESSAGE_HINTS = [
|
|
26
|
+
'internal network failure',
|
|
27
|
+
'network failure',
|
|
28
|
+
'network error',
|
|
29
|
+
'temporarily unavailable',
|
|
30
|
+
'temporarily unreachable',
|
|
31
|
+
'upstream disconnected',
|
|
32
|
+
'connection reset',
|
|
33
|
+
'connection closed',
|
|
34
|
+
'timed out',
|
|
35
|
+
'timeout'
|
|
36
|
+
];
|
|
37
|
+
function firstNonEmptyString(candidates) {
|
|
38
|
+
for (const candidate of candidates) {
|
|
39
|
+
if (typeof candidate !== 'string') {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const trimmed = candidate.trim();
|
|
43
|
+
if (trimmed) {
|
|
44
|
+
return trimmed;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
function firstFiniteNumber(candidates) {
|
|
50
|
+
for (const candidate of candidates) {
|
|
51
|
+
if (typeof candidate === 'number' && Number.isFinite(candidate)) {
|
|
52
|
+
return candidate;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
function isRetryableSseWrapperError(message, errorCode, status) {
|
|
58
|
+
if (typeof status === 'number' && Number.isFinite(status)) {
|
|
59
|
+
if (status === 408 || status === 425 || status === 429 || status >= 500) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const normalizedCode = typeof errorCode === 'string' ? errorCode.trim().toLowerCase() : '';
|
|
64
|
+
if (normalizedCode && RETRYABLE_SSE_ERROR_CODE_HINTS.some((hint) => normalizedCode.includes(hint))) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const loweredMessage = message.toLowerCase();
|
|
68
|
+
return RETRYABLE_SSE_MESSAGE_HINTS.some((hint) => loweredMessage.includes(hint));
|
|
69
|
+
}
|
|
13
70
|
function resolveBoolFromEnv(value, fallback) {
|
|
14
71
|
if (!value) {
|
|
15
72
|
return fallback;
|
|
@@ -143,6 +200,48 @@ function injectAntigravityRetrySignal(metadata, signal) {
|
|
|
143
200
|
...(signal.avoidAllOnRetry === true ? { antigravityAvoidAllOnRetry: true } : {})
|
|
144
201
|
};
|
|
145
202
|
}
|
|
203
|
+
function normalizeSessionToken(value) {
|
|
204
|
+
if (typeof value !== 'string') {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
const trimmed = value.trim();
|
|
208
|
+
return trimmed || undefined;
|
|
209
|
+
}
|
|
210
|
+
function inferClockClientTypeFromMetadata(metadata) {
|
|
211
|
+
const direct = normalizeSessionToken(metadata.clockClientType) ?? normalizeSessionToken(metadata.clientType);
|
|
212
|
+
if (direct) {
|
|
213
|
+
return direct;
|
|
214
|
+
}
|
|
215
|
+
const userAgent = normalizeSessionToken(metadata.userAgent)?.toLowerCase() ?? '';
|
|
216
|
+
if (userAgent.includes('codex')) {
|
|
217
|
+
return 'codex';
|
|
218
|
+
}
|
|
219
|
+
if (userAgent.includes('claude')) {
|
|
220
|
+
return 'claude';
|
|
221
|
+
}
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
function bindClockConversationSession(metadata) {
|
|
225
|
+
const conversationSessionId = normalizeSessionToken(metadata.sessionId);
|
|
226
|
+
if (!conversationSessionId) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const tmuxSessionId = normalizeSessionToken(metadata.tmuxSessionId);
|
|
230
|
+
const daemonId = normalizeSessionToken(metadata.clockDaemonId)
|
|
231
|
+
?? normalizeSessionToken(metadata.clockClientDaemonId);
|
|
232
|
+
const clientType = inferClockClientTypeFromMetadata(metadata);
|
|
233
|
+
try {
|
|
234
|
+
getClockClientRegistry().bindConversationSession({
|
|
235
|
+
conversationSessionId,
|
|
236
|
+
...(tmuxSessionId ? { tmuxSessionId } : {}),
|
|
237
|
+
...(daemonId ? { daemonId } : {}),
|
|
238
|
+
...(clientType ? { clientType } : {})
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// best-effort only
|
|
243
|
+
}
|
|
244
|
+
}
|
|
146
245
|
export class HubRequestExecutor {
|
|
147
246
|
deps;
|
|
148
247
|
constructor(deps) {
|
|
@@ -161,6 +260,7 @@ export class HubRequestExecutor {
|
|
|
161
260
|
try {
|
|
162
261
|
const hubPipeline = ensureHubPipeline(this.deps.getHubPipeline);
|
|
163
262
|
const initialMetadata = buildRequestMetadata(input);
|
|
263
|
+
bindClockConversationSession(initialMetadata);
|
|
164
264
|
const inboundClientHeaders = cloneClientHeaders(initialMetadata?.clientHeaders);
|
|
165
265
|
const providerRequestId = input.requestId;
|
|
166
266
|
const clientRequestId = resolveClientRequestId(initialMetadata, providerRequestId);
|
|
@@ -217,7 +317,26 @@ export class HubRequestExecutor {
|
|
|
217
317
|
stream: metadataForAttempt.stream,
|
|
218
318
|
attempt
|
|
219
319
|
});
|
|
220
|
-
|
|
320
|
+
let pipelineResult;
|
|
321
|
+
try {
|
|
322
|
+
pipelineResult = await runHubPipeline(hubPipeline, input, metadataForAttempt);
|
|
323
|
+
}
|
|
324
|
+
catch (pipelineError) {
|
|
325
|
+
const pipelineErrorCode = typeof pipelineError.code === 'string'
|
|
326
|
+
? String(pipelineError.code).trim()
|
|
327
|
+
: '';
|
|
328
|
+
const pipelineErrorMessage = pipelineError instanceof Error
|
|
329
|
+
? pipelineError.message
|
|
330
|
+
: String(pipelineError ?? 'Unknown error');
|
|
331
|
+
const isPoolExhaustedError = pipelineErrorCode === 'PROVIDER_NOT_AVAILABLE' ||
|
|
332
|
+
pipelineErrorCode === 'ERR_NO_PROVIDER_TARGET' ||
|
|
333
|
+
/all providers unavailable/i.test(pipelineErrorMessage) ||
|
|
334
|
+
/virtual router did not produce a provider target/i.test(pipelineErrorMessage);
|
|
335
|
+
if (lastError && isPoolExhaustedError) {
|
|
336
|
+
throw lastError;
|
|
337
|
+
}
|
|
338
|
+
throw pipelineError;
|
|
339
|
+
}
|
|
221
340
|
const pipelineMetadata = pipelineResult.metadata ?? {};
|
|
222
341
|
const mergedMetadata = { ...metadataForAttempt, ...pipelineMetadata };
|
|
223
342
|
const mergedClientHeaders = cloneClientHeaders(mergedMetadata?.clientHeaders) || clientHeadersForAttempt;
|
|
@@ -251,6 +370,38 @@ export class HubRequestExecutor {
|
|
|
251
370
|
}
|
|
252
371
|
const runtimeKey = target.runtimeKey || this.deps.runtimeManager.resolveRuntimeKey(target.providerKey);
|
|
253
372
|
if (!runtimeKey) {
|
|
373
|
+
const runtimeResolveError = Object.assign(new Error(`Runtime for provider ${target.providerKey} not initialized`), {
|
|
374
|
+
code: 'ERR_RUNTIME_NOT_FOUND',
|
|
375
|
+
requestId: input.requestId,
|
|
376
|
+
retryable: true
|
|
377
|
+
});
|
|
378
|
+
try {
|
|
379
|
+
const { emitProviderError } = await import('../../../providers/core/utils/provider-error-reporter.js');
|
|
380
|
+
emitProviderError({
|
|
381
|
+
error: runtimeResolveError,
|
|
382
|
+
stage: 'provider.runtime.resolve',
|
|
383
|
+
runtime: {
|
|
384
|
+
requestId: input.requestId,
|
|
385
|
+
providerKey: target.providerKey,
|
|
386
|
+
providerId: target.providerKey.split('.')[0],
|
|
387
|
+
providerType: String(target.providerType || 'unknown'),
|
|
388
|
+
providerProtocol: String(target.outboundProfile || ''),
|
|
389
|
+
routeName: pipelineResult.routingDecision?.routeName,
|
|
390
|
+
pipelineId: target.providerKey,
|
|
391
|
+
target
|
|
392
|
+
},
|
|
393
|
+
dependencies: this.deps.getModuleDependencies(),
|
|
394
|
+
recoverable: false,
|
|
395
|
+
affectsHealth: true,
|
|
396
|
+
details: {
|
|
397
|
+
reason: 'runtime_not_initialized',
|
|
398
|
+
providerKey: target.providerKey
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
// best-effort
|
|
404
|
+
}
|
|
254
405
|
throw Object.assign(new Error(`Runtime for provider ${target.providerKey} not initialized`), {
|
|
255
406
|
code: 'ERR_RUNTIME_NOT_FOUND',
|
|
256
407
|
requestId: input.requestId
|
|
@@ -258,6 +409,40 @@ export class HubRequestExecutor {
|
|
|
258
409
|
}
|
|
259
410
|
const handle = this.deps.runtimeManager.getHandleByRuntimeKey(runtimeKey);
|
|
260
411
|
if (!handle) {
|
|
412
|
+
const runtimeMissingError = Object.assign(new Error(`Provider runtime ${runtimeKey} not found`), {
|
|
413
|
+
code: 'ERR_PROVIDER_NOT_FOUND',
|
|
414
|
+
requestId: input.requestId,
|
|
415
|
+
retryable: true
|
|
416
|
+
});
|
|
417
|
+
try {
|
|
418
|
+
const { emitProviderError } = await import('../../../providers/core/utils/provider-error-reporter.js');
|
|
419
|
+
emitProviderError({
|
|
420
|
+
error: runtimeMissingError,
|
|
421
|
+
stage: 'provider.runtime.resolve',
|
|
422
|
+
runtime: {
|
|
423
|
+
requestId: input.requestId,
|
|
424
|
+
providerKey: target.providerKey,
|
|
425
|
+
providerId: target.providerKey.split('.')[0],
|
|
426
|
+
providerType: String(target.providerType || 'unknown'),
|
|
427
|
+
providerProtocol: String(target.outboundProfile || ''),
|
|
428
|
+
routeName: pipelineResult.routingDecision?.routeName,
|
|
429
|
+
pipelineId: target.providerKey,
|
|
430
|
+
runtimeKey,
|
|
431
|
+
target
|
|
432
|
+
},
|
|
433
|
+
dependencies: this.deps.getModuleDependencies(),
|
|
434
|
+
recoverable: false,
|
|
435
|
+
affectsHealth: true,
|
|
436
|
+
details: {
|
|
437
|
+
reason: 'runtime_handle_missing',
|
|
438
|
+
providerKey: target.providerKey,
|
|
439
|
+
runtimeKey
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
// best-effort
|
|
445
|
+
}
|
|
261
446
|
throw Object.assign(new Error(`Provider runtime ${runtimeKey} not found`), {
|
|
262
447
|
code: 'ERR_PROVIDER_NOT_FOUND',
|
|
263
448
|
requestId: input.requestId
|
|
@@ -364,22 +549,57 @@ export class HubRequestExecutor {
|
|
|
364
549
|
response: normalized,
|
|
365
550
|
pipelineMetadata: mergedMetadata
|
|
366
551
|
});
|
|
367
|
-
//
|
|
368
|
-
//
|
|
369
|
-
//
|
|
370
|
-
|
|
371
|
-
|
|
552
|
+
// Treat upstream 429 as provider failure across protocols to avoid
|
|
553
|
+
// silently returning success and to let Virtual Router failover to other candidates.
|
|
554
|
+
// Keep existing Gemini compatibility behavior for 400/4xx thoughtSignature-like failures.
|
|
555
|
+
const convertedStatus = typeof converted.status === 'number' ? converted.status : undefined;
|
|
556
|
+
const isGlobalRetryable429 = convertedStatus === 429;
|
|
557
|
+
const isGeminiCompatFailure = typeof convertedStatus === 'number' &&
|
|
558
|
+
convertedStatus >= 400 &&
|
|
372
559
|
(isAntigravityProviderKey(target.providerKey) ||
|
|
373
560
|
(typeof target.providerKey === 'string' && target.providerKey.startsWith('gemini-cli.'))) &&
|
|
374
|
-
providerProtocol === 'gemini-chat'
|
|
561
|
+
providerProtocol === 'gemini-chat';
|
|
562
|
+
if (isGlobalRetryable429 || isGeminiCompatFailure) {
|
|
375
563
|
const bodyForError = converted.body && typeof converted.body === 'object' ? converted.body : undefined;
|
|
376
564
|
const errMsg = bodyForError && bodyForError.error && typeof bodyForError.error === 'object'
|
|
377
565
|
? String(bodyForError.error.message || bodyForError.error || '')
|
|
378
566
|
: '';
|
|
379
|
-
const
|
|
380
|
-
errorToThrow
|
|
381
|
-
errorToThrow.
|
|
567
|
+
const statusCode = typeof convertedStatus === 'number' ? convertedStatus : 500;
|
|
568
|
+
const errorToThrow = new Error(errMsg && errMsg.trim().length ? errMsg : `HTTP ${statusCode}`);
|
|
569
|
+
errorToThrow.statusCode = statusCode;
|
|
570
|
+
errorToThrow.status = statusCode;
|
|
382
571
|
errorToThrow.response = { data: bodyForError };
|
|
572
|
+
try {
|
|
573
|
+
const { emitProviderError } = await import('../../../providers/core/utils/provider-error-reporter.js');
|
|
574
|
+
emitProviderError({
|
|
575
|
+
error: errorToThrow,
|
|
576
|
+
stage: 'provider.http',
|
|
577
|
+
runtime: {
|
|
578
|
+
requestId: input.requestId,
|
|
579
|
+
providerKey: target.providerKey,
|
|
580
|
+
providerId: handle.providerId,
|
|
581
|
+
providerType: handle.providerType,
|
|
582
|
+
providerFamily: handle.providerFamily,
|
|
583
|
+
providerProtocol,
|
|
584
|
+
routeName: pipelineResult.routingDecision?.routeName,
|
|
585
|
+
pipelineId: target.providerKey,
|
|
586
|
+
target,
|
|
587
|
+
runtimeKey
|
|
588
|
+
},
|
|
589
|
+
dependencies: this.deps.getModuleDependencies(),
|
|
590
|
+
statusCode,
|
|
591
|
+
recoverable: statusCode === 429,
|
|
592
|
+
affectsHealth: true,
|
|
593
|
+
details: {
|
|
594
|
+
source: 'converted_response_status',
|
|
595
|
+
convertedStatus: statusCode,
|
|
596
|
+
wrappedErrorResponse: true
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
catch {
|
|
601
|
+
// best-effort; never block retry/failover path
|
|
602
|
+
}
|
|
383
603
|
throw errorToThrow;
|
|
384
604
|
}
|
|
385
605
|
const usage = this.extractUsageFromResult(converted, mergedMetadata);
|
|
@@ -434,11 +654,9 @@ export class HubRequestExecutor {
|
|
|
434
654
|
recordAttempt({ error: true });
|
|
435
655
|
const singleProviderPool = Boolean(initialRoutePool && initialRoutePool.length === 1 && initialRoutePool[0] === target.providerKey);
|
|
436
656
|
if (singleProviderPool) {
|
|
437
|
-
|
|
438
|
-
await waitBeforeRetry(error);
|
|
439
|
-
}
|
|
657
|
+
await waitBeforeRetry(error);
|
|
440
658
|
}
|
|
441
|
-
|
|
659
|
+
if (!singleProviderPool && target.providerKey) {
|
|
442
660
|
const is429 = status === 429;
|
|
443
661
|
if (isAntigravityProviderKey(target.providerKey) && (isVerify || is429)) {
|
|
444
662
|
// For Antigravity 403 verify / 429 states:
|
|
@@ -515,12 +733,21 @@ export class HubRequestExecutor {
|
|
|
515
733
|
if (body && typeof body === 'object') {
|
|
516
734
|
const wrapperError = this.extractSseWrapperError(body);
|
|
517
735
|
if (wrapperError) {
|
|
518
|
-
const
|
|
736
|
+
const codeSuffix = wrapperError.errorCode ? ` [${wrapperError.errorCode}]` : '';
|
|
737
|
+
const error = new Error(`Upstream SSE error event${codeSuffix}: ${wrapperError.message}`);
|
|
519
738
|
error.code = 'SSE_DECODE_ERROR';
|
|
739
|
+
if (wrapperError.errorCode) {
|
|
740
|
+
error.upstreamCode = wrapperError.errorCode;
|
|
741
|
+
}
|
|
742
|
+
error.retryable = wrapperError.retryable;
|
|
743
|
+
if (wrapperError.retryable) {
|
|
744
|
+
error.status = 503;
|
|
745
|
+
error.statusCode = 503;
|
|
746
|
+
}
|
|
520
747
|
throw error;
|
|
521
748
|
}
|
|
522
749
|
}
|
|
523
|
-
if (options.processMode === 'passthrough') {
|
|
750
|
+
if (options.processMode === 'passthrough' && !options.wantsStream) {
|
|
524
751
|
return options.response;
|
|
525
752
|
}
|
|
526
753
|
const entry = (options.entryEndpoint || '').toLowerCase();
|
|
@@ -550,6 +777,12 @@ export class HubRequestExecutor {
|
|
|
550
777
|
const baseContext = {
|
|
551
778
|
...(metadataBag ?? {})
|
|
552
779
|
};
|
|
780
|
+
if (baseContext.capturedChatRequest === undefined &&
|
|
781
|
+
options.originalRequest &&
|
|
782
|
+
typeof options.originalRequest === 'object' &&
|
|
783
|
+
!Array.isArray(options.originalRequest)) {
|
|
784
|
+
baseContext.capturedChatRequest = options.originalRequest;
|
|
785
|
+
}
|
|
553
786
|
if (typeof metadataBag?.routeName === 'string') {
|
|
554
787
|
baseContext.routeId = metadataBag.routeName;
|
|
555
788
|
}
|
|
@@ -636,6 +869,7 @@ export class HubRequestExecutor {
|
|
|
636
869
|
delete nestedMetadata.clientHeaders;
|
|
637
870
|
delete nestedMetadata.clientRequestId;
|
|
638
871
|
}
|
|
872
|
+
bindClockConversationSession(nestedMetadata);
|
|
639
873
|
const nestedInput = {
|
|
640
874
|
entryEndpoint: nestedEntry,
|
|
641
875
|
method: 'POST',
|
|
@@ -645,6 +879,26 @@ export class HubRequestExecutor {
|
|
|
645
879
|
body: reenterOpts.body,
|
|
646
880
|
metadata: nestedMetadata
|
|
647
881
|
};
|
|
882
|
+
try {
|
|
883
|
+
const requestBody = reenterOpts.body;
|
|
884
|
+
const messages = Array.isArray(requestBody.messages) ? requestBody.messages : [];
|
|
885
|
+
const lastUser = [...messages]
|
|
886
|
+
.reverse()
|
|
887
|
+
.find((entry) => entry && typeof entry === 'object' && entry.role === 'user');
|
|
888
|
+
const text = typeof lastUser?.content === 'string' ? String(lastUser.content) : '';
|
|
889
|
+
if (text.includes('<**clock:{') && text.includes('}**>')) {
|
|
890
|
+
await injectClockClientPrompt({
|
|
891
|
+
tmuxSessionId: typeof nestedMetadata.tmuxSessionId === 'string' ? nestedMetadata.tmuxSessionId : undefined,
|
|
892
|
+
sessionId: typeof nestedMetadata.sessionId === 'string' ? nestedMetadata.sessionId : undefined,
|
|
893
|
+
text,
|
|
894
|
+
requestId: reenterOpts.requestId,
|
|
895
|
+
source: 'servertool.reenter'
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
catch {
|
|
900
|
+
// best-effort only
|
|
901
|
+
}
|
|
648
902
|
const nestedResult = await this.execute(nestedInput);
|
|
649
903
|
const nestedBody = nestedResult.body && typeof nestedResult.body === 'object'
|
|
650
904
|
? nestedResult.body
|
|
@@ -668,23 +922,10 @@ export class HubRequestExecutor {
|
|
|
668
922
|
body: { __sse_responses: converted.__sse_responses }
|
|
669
923
|
};
|
|
670
924
|
}
|
|
671
|
-
|
|
925
|
+
return {
|
|
672
926
|
...options.response,
|
|
673
927
|
body: converted.body ?? body
|
|
674
928
|
};
|
|
675
|
-
// Special case: some Antigravity/Gemini upstream failures are intentionally passed through as
|
|
676
|
-
// an error-shaped response (status=429/400) so llmswitch-core servertool can recover via followup.
|
|
677
|
-
// If recovery succeeded, the final client payload will NOT contain an error envelope.
|
|
678
|
-
if (typeof options.response.status === 'number' && options.response.status >= 400) {
|
|
679
|
-
const out = merged.body;
|
|
680
|
-
if (out && typeof out === 'object' && !Array.isArray(out)) {
|
|
681
|
-
const hasError = Object.prototype.hasOwnProperty.call(out, 'error');
|
|
682
|
-
if (!hasError) {
|
|
683
|
-
merged.status = 200;
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
return merged;
|
|
688
929
|
}
|
|
689
930
|
catch (error) {
|
|
690
931
|
const err = error;
|
|
@@ -714,10 +955,11 @@ export class HubRequestExecutor {
|
|
|
714
955
|
if (!record || typeof record !== 'object' || depth < 0) {
|
|
715
956
|
return undefined;
|
|
716
957
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
958
|
+
if (record.mode === 'sse') {
|
|
959
|
+
const normalized = this.normalizeSseWrapperErrorValue(record.error, depth);
|
|
960
|
+
if (normalized) {
|
|
961
|
+
return normalized;
|
|
962
|
+
}
|
|
721
963
|
}
|
|
722
964
|
const nestedKeys = ['body', 'data', 'payload', 'response'];
|
|
723
965
|
for (const key of nestedKeys) {
|
|
@@ -732,6 +974,89 @@ export class HubRequestExecutor {
|
|
|
732
974
|
}
|
|
733
975
|
return undefined;
|
|
734
976
|
}
|
|
977
|
+
normalizeSseWrapperErrorValue(value, depth) {
|
|
978
|
+
if (value === undefined || value === null || depth < 0) {
|
|
979
|
+
return undefined;
|
|
980
|
+
}
|
|
981
|
+
if (typeof value === 'string') {
|
|
982
|
+
const trimmed = value.trim();
|
|
983
|
+
if (!trimmed) {
|
|
984
|
+
return undefined;
|
|
985
|
+
}
|
|
986
|
+
if (depth > 0 && (trimmed.startsWith('{') || trimmed.startsWith('['))) {
|
|
987
|
+
try {
|
|
988
|
+
const parsed = JSON.parse(trimmed);
|
|
989
|
+
const parsedInfo = this.normalizeSseWrapperErrorValue(parsed, depth - 1);
|
|
990
|
+
if (parsedInfo) {
|
|
991
|
+
return parsedInfo;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
catch {
|
|
995
|
+
// fallback to raw string
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
return {
|
|
999
|
+
message: trimmed,
|
|
1000
|
+
retryable: isRetryableSseWrapperError(trimmed)
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
1004
|
+
return undefined;
|
|
1005
|
+
}
|
|
1006
|
+
const record = value;
|
|
1007
|
+
const directMessage = firstNonEmptyString([
|
|
1008
|
+
record.message,
|
|
1009
|
+
record.error_message,
|
|
1010
|
+
record.errorMessage
|
|
1011
|
+
]);
|
|
1012
|
+
const directCode = firstNonEmptyString([
|
|
1013
|
+
record.code,
|
|
1014
|
+
record.error_code,
|
|
1015
|
+
record.errorCode,
|
|
1016
|
+
record.type
|
|
1017
|
+
]);
|
|
1018
|
+
const directStatus = firstFiniteNumber([
|
|
1019
|
+
record.status,
|
|
1020
|
+
record.statusCode,
|
|
1021
|
+
record.status_code,
|
|
1022
|
+
record.http_status
|
|
1023
|
+
]);
|
|
1024
|
+
if (depth > 0) {
|
|
1025
|
+
for (const key of ['error', 'data', 'payload', 'details', 'body', 'response']) {
|
|
1026
|
+
const nestedInfo = this.normalizeSseWrapperErrorValue(record[key], depth - 1);
|
|
1027
|
+
if (nestedInfo) {
|
|
1028
|
+
const mergedCode = nestedInfo.errorCode ?? directCode;
|
|
1029
|
+
const retryable = nestedInfo.retryable || isRetryableSseWrapperError(nestedInfo.message, mergedCode, directStatus);
|
|
1030
|
+
return {
|
|
1031
|
+
message: nestedInfo.message,
|
|
1032
|
+
...(mergedCode ? { errorCode: mergedCode } : {}),
|
|
1033
|
+
retryable
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
if (directMessage) {
|
|
1039
|
+
return {
|
|
1040
|
+
message: directMessage,
|
|
1041
|
+
...(directCode ? { errorCode: directCode } : {}),
|
|
1042
|
+
retryable: isRetryableSseWrapperError(directMessage, directCode, directStatus)
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
try {
|
|
1046
|
+
const serialized = JSON.stringify(record);
|
|
1047
|
+
if (serialized && serialized !== '{}') {
|
|
1048
|
+
return {
|
|
1049
|
+
message: serialized,
|
|
1050
|
+
...(directCode ? { errorCode: directCode } : {}),
|
|
1051
|
+
retryable: isRetryableSseWrapperError(serialized, directCode, directStatus)
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
catch {
|
|
1056
|
+
// ignore stringify failures
|
|
1057
|
+
}
|
|
1058
|
+
return undefined;
|
|
1059
|
+
}
|
|
735
1060
|
extractClientModelId(metadata, originalRequest) {
|
|
736
1061
|
const candidates = [
|
|
737
1062
|
metadata.clientModelId,
|