@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.
Files changed (283) hide show
  1. package/configsamples/config.json +19 -0
  2. package/configsamples/provider/deepseek/config.v1.json +59 -0
  3. package/dist/build-info.js +2 -2
  4. package/dist/cli/commands/claude.d.ts +4 -0
  5. package/dist/cli/commands/claude.js +56 -0
  6. package/dist/cli/commands/claude.js.map +1 -0
  7. package/dist/cli/commands/clock-admin.d.ts +20 -0
  8. package/dist/cli/commands/clock-admin.js +234 -0
  9. package/dist/cli/commands/clock-admin.js.map +1 -0
  10. package/dist/cli/commands/code.d.ts +0 -42
  11. package/dist/cli/commands/code.js +4 -414
  12. package/dist/cli/commands/code.js.map +1 -1
  13. package/dist/cli/commands/codex.d.ts +4 -0
  14. package/dist/cli/commands/codex.js +43 -0
  15. package/dist/cli/commands/codex.js.map +1 -0
  16. package/dist/cli/commands/examples.js +13 -16
  17. package/dist/cli/commands/examples.js.map +1 -1
  18. package/dist/cli/commands/init/basic.d.ts +40 -0
  19. package/dist/cli/commands/init/basic.js +482 -0
  20. package/dist/cli/commands/init/basic.js.map +1 -0
  21. package/dist/cli/commands/init/camoufox.d.ts +7 -0
  22. package/dist/cli/commands/init/camoufox.js +59 -0
  23. package/dist/cli/commands/init/camoufox.js.map +1 -0
  24. package/dist/cli/commands/init/interactive.d.ts +18 -0
  25. package/dist/cli/commands/init/interactive.js +223 -0
  26. package/dist/cli/commands/init/interactive.js.map +1 -0
  27. package/dist/cli/commands/init/shared.d.ts +66 -0
  28. package/dist/cli/commands/init/shared.js +9 -0
  29. package/dist/cli/commands/init/shared.js.map +1 -0
  30. package/dist/cli/commands/init/workflows.d.ts +29 -0
  31. package/dist/cli/commands/init/workflows.js +341 -0
  32. package/dist/cli/commands/init/workflows.js.map +1 -0
  33. package/dist/cli/commands/init.d.ts +2 -26
  34. package/dist/cli/commands/init.js +220 -53
  35. package/dist/cli/commands/init.js.map +1 -1
  36. package/dist/cli/commands/launcher-kernel.d.ts +78 -0
  37. package/dist/cli/commands/launcher-kernel.js +1194 -0
  38. package/dist/cli/commands/launcher-kernel.js.map +1 -0
  39. package/dist/cli/commands/start.js +27 -1
  40. package/dist/cli/commands/start.js.map +1 -1
  41. package/dist/cli/commands/status.d.ts +2 -0
  42. package/dist/cli/commands/status.js +24 -1
  43. package/dist/cli/commands/status.js.map +1 -1
  44. package/dist/cli/commands/stop.d.ts +1 -0
  45. package/dist/cli/commands/stop.js +201 -4
  46. package/dist/cli/commands/stop.js.map +1 -1
  47. package/dist/cli/commands/tmux-inject.d.ts +20 -0
  48. package/dist/cli/commands/tmux-inject.js +212 -0
  49. package/dist/cli/commands/tmux-inject.js.map +1 -0
  50. package/dist/cli/config/init-provider-catalog.js +34 -0
  51. package/dist/cli/config/init-provider-catalog.js.map +1 -1
  52. package/dist/cli/register/claude-command.d.ts +3 -0
  53. package/dist/cli/register/claude-command.js +5 -0
  54. package/dist/cli/register/claude-command.js.map +1 -0
  55. package/dist/cli/register/clock-admin-command.d.ts +3 -0
  56. package/dist/cli/register/clock-admin-command.js +5 -0
  57. package/dist/cli/register/clock-admin-command.js.map +1 -0
  58. package/dist/cli/register/codex-command.d.ts +3 -0
  59. package/dist/cli/register/codex-command.js +5 -0
  60. package/dist/cli/register/codex-command.js.map +1 -0
  61. package/dist/cli/register/status-config-commands.d.ts +2 -0
  62. package/dist/cli/register/status-config-commands.js.map +1 -1
  63. package/dist/cli/register/tmux-inject-command.d.ts +3 -0
  64. package/dist/cli/register/tmux-inject-command.js +5 -0
  65. package/dist/cli/register/tmux-inject-command.js.map +1 -0
  66. package/dist/cli/server/port-utils.d.ts +3 -2
  67. package/dist/cli/server/port-utils.js +171 -32
  68. package/dist/cli/server/port-utils.js.map +1 -1
  69. package/dist/cli.js +45 -6
  70. package/dist/cli.js.map +1 -1
  71. package/dist/client/gemini/gemini-protocol-client.js +56 -5
  72. package/dist/client/gemini/gemini-protocol-client.js.map +1 -1
  73. package/dist/commands/token-daemon.js +59 -7
  74. package/dist/commands/token-daemon.js.map +1 -1
  75. package/dist/commands/validate.js +87 -15
  76. package/dist/commands/validate.js.map +1 -1
  77. package/dist/config/routecodex-config-loader.js +31 -2
  78. package/dist/config/routecodex-config-loader.js.map +1 -1
  79. package/dist/docs/daemon-admin-ui.html +948 -74
  80. package/dist/index.d.ts +1 -0
  81. package/dist/index.js +325 -37
  82. package/dist/index.js.map +1 -1
  83. package/dist/manager/quota/provider-quota-center.js +8 -14
  84. package/dist/manager/quota/provider-quota-center.js.map +1 -1
  85. package/dist/modules/llmswitch/bridge.d.ts +39 -0
  86. package/dist/modules/llmswitch/bridge.js +169 -0
  87. package/dist/modules/llmswitch/bridge.js.map +1 -1
  88. package/dist/modules/pipeline/utils/colored-logger.js +1 -1
  89. package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
  90. package/dist/providers/auth/deepseek-account-auth.d.ts +39 -0
  91. package/dist/providers/auth/deepseek-account-auth.js +329 -0
  92. package/dist/providers/auth/deepseek-account-auth.js.map +1 -0
  93. package/dist/providers/auth/deepseek-account-token-acquirer.d.ts +15 -0
  94. package/dist/providers/auth/deepseek-account-token-acquirer.js +644 -0
  95. package/dist/providers/auth/deepseek-account-token-acquirer.js.map +1 -0
  96. package/dist/providers/auth/oauth-lifecycle.js +26 -4
  97. package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
  98. package/dist/providers/auth/oauth-repair-cooldown.d.ts +5 -0
  99. package/dist/providers/auth/oauth-repair-cooldown.js +39 -0
  100. package/dist/providers/auth/oauth-repair-cooldown.js.map +1 -1
  101. package/dist/providers/auth/token-scanner/index.d.ts +6 -0
  102. package/dist/providers/auth/token-scanner/index.js +53 -0
  103. package/dist/providers/auth/token-scanner/index.js.map +1 -1
  104. package/dist/providers/core/api/provider-config.d.ts +17 -2
  105. package/dist/providers/core/api/provider-types.d.ts +6 -0
  106. package/dist/providers/core/api/provider-types.js.map +1 -1
  107. package/dist/providers/core/config/camoufox-launcher.d.ts +7 -0
  108. package/dist/providers/core/config/camoufox-launcher.js +68 -21
  109. package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
  110. package/dist/providers/core/config/service-profiles.js +19 -0
  111. package/dist/providers/core/config/service-profiles.js.map +1 -1
  112. package/dist/providers/core/contracts/deepseek-provider-contract.d.ts +34 -0
  113. package/dist/providers/core/contracts/deepseek-provider-contract.js +100 -0
  114. package/dist/providers/core/contracts/deepseek-provider-contract.js.map +1 -0
  115. package/dist/providers/core/runtime/anthropic-http-provider.d.ts +0 -5
  116. package/dist/providers/core/runtime/anthropic-http-provider.js +0 -26
  117. package/dist/providers/core/runtime/anthropic-http-provider.js.map +1 -1
  118. package/dist/providers/core/runtime/deepseek-http-provider.d.ts +35 -0
  119. package/dist/providers/core/runtime/deepseek-http-provider.js +373 -0
  120. package/dist/providers/core/runtime/deepseek-http-provider.js.map +1 -0
  121. package/dist/providers/core/runtime/deepseek-session-pow.d.ts +55 -0
  122. package/dist/providers/core/runtime/deepseek-session-pow.js +422 -0
  123. package/dist/providers/core/runtime/deepseek-session-pow.js.map +1 -0
  124. package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +0 -3
  125. package/dist/providers/core/runtime/gemini-cli-http-provider.js +0 -72
  126. package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
  127. package/dist/providers/core/runtime/gemini-http-provider.d.ts +1 -7
  128. package/dist/providers/core/runtime/gemini-http-provider.js +3 -110
  129. package/dist/providers/core/runtime/gemini-http-provider.js.map +1 -1
  130. package/dist/providers/core/runtime/http-request-executor.d.ts +1 -0
  131. package/dist/providers/core/runtime/http-request-executor.js +4 -0
  132. package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
  133. package/dist/providers/core/runtime/http-transport-provider.d.ts +10 -4
  134. package/dist/providers/core/runtime/http-transport-provider.js +308 -82
  135. package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
  136. package/dist/providers/core/runtime/iflow-http-provider.d.ts +0 -4
  137. package/dist/providers/core/runtime/iflow-http-provider.js +0 -28
  138. package/dist/providers/core/runtime/iflow-http-provider.js.map +1 -1
  139. package/dist/providers/core/runtime/provider-factory.d.ts +5 -0
  140. package/dist/providers/core/runtime/provider-factory.js +59 -6
  141. package/dist/providers/core/runtime/provider-factory.js.map +1 -1
  142. package/dist/providers/core/runtime/responses-provider.d.ts +0 -2
  143. package/dist/providers/core/runtime/responses-provider.js +0 -11
  144. package/dist/providers/core/runtime/responses-provider.js.map +1 -1
  145. package/dist/providers/core/strategies/oauth-device-flow.js +16 -1
  146. package/dist/providers/core/strategies/oauth-device-flow.js.map +1 -1
  147. package/dist/providers/core/utils/provider-type-utils.js +2 -1
  148. package/dist/providers/core/utils/provider-type-utils.js.map +1 -1
  149. package/dist/providers/profile/families/anthropic-profile.d.ts +2 -0
  150. package/dist/providers/profile/families/anthropic-profile.js +32 -0
  151. package/dist/providers/profile/families/anthropic-profile.js.map +1 -0
  152. package/dist/providers/profile/families/antigravity-profile.d.ts +2 -0
  153. package/dist/providers/profile/families/antigravity-profile.js +109 -0
  154. package/dist/providers/profile/families/antigravity-profile.js.map +1 -0
  155. package/dist/providers/profile/families/glm-profile.d.ts +2 -0
  156. package/dist/providers/profile/families/glm-profile.js +48 -0
  157. package/dist/providers/profile/families/glm-profile.js.map +1 -0
  158. package/dist/providers/profile/families/iflow-profile.d.ts +2 -0
  159. package/dist/providers/profile/families/iflow-profile.js +232 -0
  160. package/dist/providers/profile/families/iflow-profile.js.map +1 -0
  161. package/dist/providers/profile/families/qwen-profile.d.ts +2 -0
  162. package/dist/providers/profile/families/qwen-profile.js +14 -0
  163. package/dist/providers/profile/families/qwen-profile.js.map +1 -0
  164. package/dist/providers/profile/families/responses-profile.d.ts +2 -0
  165. package/dist/providers/profile/families/responses-profile.js +28 -0
  166. package/dist/providers/profile/families/responses-profile.js.map +1 -0
  167. package/dist/providers/profile/profile-contracts.d.ts +74 -0
  168. package/dist/providers/profile/profile-contracts.js +2 -0
  169. package/dist/providers/profile/profile-contracts.js.map +1 -0
  170. package/dist/providers/profile/profile-registry.d.ts +3 -0
  171. package/dist/providers/profile/profile-registry.js +40 -0
  172. package/dist/providers/profile/profile-registry.js.map +1 -0
  173. package/dist/providers/profile/provider-directory.d.ts +2 -0
  174. package/dist/providers/profile/provider-directory.js +55 -0
  175. package/dist/providers/profile/provider-directory.js.map +1 -0
  176. package/dist/providers/profile/provider-profile-loader.js +43 -3
  177. package/dist/providers/profile/provider-profile-loader.js.map +1 -1
  178. package/dist/providers/profile/provider-profile.d.ts +8 -0
  179. package/dist/scripts/deepseek/pow-solver.mjs +146 -0
  180. package/dist/scripts/deepseek/sha3_wasm_bg.7b9ca65ddd.wasm +0 -0
  181. package/dist/server/handlers/config-admin-handler.js +27 -0
  182. package/dist/server/handlers/config-admin-handler.js.map +1 -1
  183. package/dist/server/runtime/http-server/clock-client-registry.d.ts +113 -0
  184. package/dist/server/runtime/http-server/clock-client-registry.js +592 -0
  185. package/dist/server/runtime/http-server/clock-client-registry.js.map +1 -0
  186. package/dist/server/runtime/http-server/clock-client-routes.d.ts +2 -0
  187. package/dist/server/runtime/http-server/clock-client-routes.js +481 -0
  188. package/dist/server/runtime/http-server/clock-client-routes.js.map +1 -0
  189. package/dist/server/runtime/http-server/clock-daemon-inject-config.d.ts +1 -0
  190. package/dist/server/runtime/http-server/clock-daemon-inject-config.js +11 -0
  191. package/dist/server/runtime/http-server/clock-daemon-inject-config.js.map +1 -0
  192. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +3 -3
  193. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -1
  194. package/dist/server/runtime/http-server/daemon-admin/auth-session.d.ts +1 -0
  195. package/dist/server/runtime/http-server/daemon-admin/auth-session.js +18 -2
  196. package/dist/server/runtime/http-server/daemon-admin/auth-session.js.map +1 -1
  197. package/dist/server/runtime/http-server/daemon-admin/control-handler.js +2 -15
  198. package/dist/server/runtime/http-server/daemon-admin/control-handler.js.map +1 -1
  199. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +65 -7
  200. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
  201. package/dist/server/runtime/http-server/executor-metadata.js +37 -1
  202. package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
  203. package/dist/server/runtime/http-server/executor-provider.js +55 -0
  204. package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
  205. package/dist/server/runtime/http-server/executor-response.js +49 -1
  206. package/dist/server/runtime/http-server/executor-response.js.map +1 -1
  207. package/dist/server/runtime/http-server/index.d.ts +10 -0
  208. package/dist/server/runtime/http-server/index.js +534 -9
  209. package/dist/server/runtime/http-server/index.js.map +1 -1
  210. package/dist/server/runtime/http-server/managed-process-probe.d.ts +6 -0
  211. package/dist/server/runtime/http-server/managed-process-probe.js +294 -0
  212. package/dist/server/runtime/http-server/managed-process-probe.js.map +1 -0
  213. package/dist/server/runtime/http-server/middleware.js +16 -1
  214. package/dist/server/runtime/http-server/middleware.js.map +1 -1
  215. package/dist/server/runtime/http-server/provider-utils.js +6 -2
  216. package/dist/server/runtime/http-server/provider-utils.js.map +1 -1
  217. package/dist/server/runtime/http-server/request-executor.d.ts +1 -0
  218. package/dist/server/runtime/http-server/request-executor.js +360 -35
  219. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  220. package/dist/server/runtime/http-server/routes.js +95 -3
  221. package/dist/server/runtime/http-server/routes.js.map +1 -1
  222. package/dist/server/runtime/http-server/stats-manager.d.ts +10 -0
  223. package/dist/server/runtime/http-server/stats-manager.js +119 -16
  224. package/dist/server/runtime/http-server/stats-manager.js.map +1 -1
  225. package/dist/server/runtime/http-server/tmux-session-probe.d.ts +3 -0
  226. package/dist/server/runtime/http-server/tmux-session-probe.js +101 -0
  227. package/dist/server/runtime/http-server/tmux-session-probe.js.map +1 -0
  228. package/dist/server/utils/stage-logger.js +21 -5
  229. package/dist/server/utils/stage-logger.js.map +1 -1
  230. package/dist/token-daemon/index.js +59 -10
  231. package/dist/token-daemon/index.js.map +1 -1
  232. package/dist/token-daemon/server-utils.d.ts +1 -0
  233. package/dist/token-daemon/server-utils.js +4 -1
  234. package/dist/token-daemon/server-utils.js.map +1 -1
  235. package/dist/token-daemon/token-daemon.js +38 -4
  236. package/dist/token-daemon/token-daemon.js.map +1 -1
  237. package/dist/token-daemon/token-types.d.ts +1 -1
  238. package/dist/token-daemon/token-types.js +2 -1
  239. package/dist/token-daemon/token-types.js.map +1 -1
  240. package/dist/token-daemon/token-utils.js +5 -2
  241. package/dist/token-daemon/token-utils.js.map +1 -1
  242. package/dist/utils/clock-client-token.d.ts +3 -0
  243. package/dist/utils/clock-client-token.js +54 -0
  244. package/dist/utils/clock-client-token.js.map +1 -0
  245. package/dist/utils/managed-server-pids.d.ts +25 -0
  246. package/dist/utils/managed-server-pids.js +176 -0
  247. package/dist/utils/managed-server-pids.js.map +1 -0
  248. package/dist/utils/process-lifecycle-logger.d.ts +8 -0
  249. package/dist/utils/process-lifecycle-logger.js +151 -0
  250. package/dist/utils/process-lifecycle-logger.js.map +1 -0
  251. package/dist/utils/runtime-exit-forensics.d.ts +30 -0
  252. package/dist/utils/runtime-exit-forensics.js +101 -0
  253. package/dist/utils/runtime-exit-forensics.js.map +1 -0
  254. package/dist/utils/shutdown-caller-context.d.ts +22 -0
  255. package/dist/utils/shutdown-caller-context.js +25 -0
  256. package/dist/utils/shutdown-caller-context.js.map +1 -0
  257. package/docs/PROVIDERS_BUILTIN.md +8 -0
  258. package/docs/PROVIDER_TYPES.md +3 -1
  259. package/docs/SERVERTOOL_PRE_COMMAND_HOOKS.md +85 -0
  260. package/docs/clock-client-daemon-design.md +343 -0
  261. package/docs/daemon-admin-ui.html +948 -74
  262. package/docs/providers/deepseek-web-provider-design.md +192 -0
  263. package/docs/routing-instructions.md +4 -1
  264. package/docs/stop-message-auto.md +4 -3
  265. package/docs/v2-architecture/PROVIDER-V2-CHANGESET-RELEASE-CHECKLIST.md +80 -0
  266. package/docs/v2-architecture/PROVIDER-V2-LAYERING-ADR-DRAFT.md +225 -0
  267. package/docs/v2-architecture/PROVIDER-V2-MIGRATION-MATRIX-DRAFT.md +88 -0
  268. package/docs/v2-architecture/PROVIDER-V2-PHASED-MIGRATION-ROLLBACK-DRAFT.md +164 -0
  269. package/docs/v2-architecture/PROVIDER-V2-PROFILE-API-REGISTRY-DRAFT.md +201 -0
  270. package/docs/v2-architecture/PROVIDER-V2-PROFILE-GEMINI-DRAFT.md +56 -0
  271. package/docs/v2-architecture/PROVIDER-V2-REFACTOR-OVERVIEW-DRAFT.md +102 -0
  272. package/docs/v2-architecture/PROVIDER-V2-VERIFICATION-MATRIX-DRAFT.md +163 -0
  273. package/package.json +10 -9
  274. package/scripts/copy-compat-assets.mjs +18 -0
  275. package/scripts/copy-modules-config.mjs +1 -0
  276. package/scripts/deepseek/pow-solver.mjs +146 -0
  277. package/scripts/deepseek/sha3_wasm_bg.7b9ca65ddd.wasm +0 -0
  278. package/scripts/ensure-cli-executable.mjs +64 -0
  279. package/scripts/install-global.sh +5 -2
  280. package/scripts/install.sh +1 -1
  281. package/scripts/monitor/daemon-kill-watch.mjs +184 -0
  282. package/scripts/monitor/port-kill-watch.sh +74 -0
  283. package/scripts/quick-install.sh +1 -1
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * 各协议具体行为(OpenAI Chat、Responses、Anthropic、Gemini 等)通过子类覆写钩子实现。
10
10
  */
11
- import { createHash } from 'node:crypto';
11
+ import { createHash, createHmac } from 'node:crypto';
12
12
  import { BaseProvider } from './base-provider.js';
13
13
  import { HttpClient } from '../utils/http-client.js';
14
14
  import { DynamicProfileLoader, ServiceProfileValidator } from '../config/service-profiles.js';
@@ -17,13 +17,14 @@ import { OAuthAuthProvider } from '../../auth/oauth-auth.js';
17
17
  import { logOAuthDebug } from '../../auth/oauth-logger.js';
18
18
  import { TokenFileAuthProvider } from '../../auth/tokenfile-auth.js';
19
19
  import { IflowCookieAuthProvider } from '../../auth/iflow-cookie-auth.js';
20
- import { ensureValidOAuthToken, handleUpstreamInvalidOAuthToken } from '../../auth/oauth-lifecycle.js';
20
+ import { ensureValidOAuthToken, handleUpstreamInvalidOAuthToken, shouldTriggerInteractiveOAuthRepair } from '../../auth/oauth-lifecycle.js';
21
21
  import { attachProviderSseSnapshotStream, writeProviderSnapshot } from '../utils/snapshot-writer.js';
22
22
  import { attachProviderRuntimeMetadata, extractProviderRuntimeMetadata } from './provider-runtime-metadata.js';
23
23
  import { buildVisionSnapshotPayload, shouldCaptureVisionDebug, summarizeVisionMessages } from './vision-debug-utils.js';
24
24
  import { OpenAIChatProtocolClient } from '../../../client/openai/chat-protocol-client.js';
25
25
  import { HttpRequestExecutor } from './http-request-executor.js';
26
26
  import { extractStatusCodeFromError } from './provider-error-classifier.js';
27
+ import { getProviderFamilyProfile } from '../../profile/profile-registry.js';
27
28
  const isRecord = (value) => typeof value === 'object' && value !== null;
28
29
  const DEFAULT_USER_AGENT = 'codex_cli_rs/0.73.0 (Mac OS 15.6.1; arm64) iTerm.app/3.6.5';
29
30
  export class HttpTransportProvider extends BaseProvider {
@@ -234,11 +235,27 @@ export class HttpTransportProvider extends BaseProvider {
234
235
  const oauthAuth = auth;
235
236
  const oauthProviderId = resolvedOAuthProviderId ?? serviceProfileKey;
236
237
  this.oauthProviderId = oauthProviderId;
238
+ const familyProfile = getProviderFamilyProfile({
239
+ providerId: this.config.config.providerId,
240
+ providerType: this.providerType,
241
+ oauthProviderId
242
+ });
243
+ const profileTokenFileMode = familyProfile?.resolveOAuthTokenFileMode?.({
244
+ oauthProviderId,
245
+ auth: {
246
+ clientId: oauthAuth.clientId,
247
+ tokenUrl: oauthAuth.tokenUrl,
248
+ deviceCodeUrl: oauthAuth.deviceCodeUrl
249
+ },
250
+ moduleType: this.type
251
+ });
237
252
  // For providers like Qwen/iflow/Gemini CLI where public OAuth client may not be available,
238
253
  // allow reading tokens produced by external login tools (CLIProxyAPI) via token file.
239
- const useTokenFile = (oauthProviderId === 'qwen' ||
240
- oauthProviderId === 'iflow' ||
241
- this.type === 'gemini-cli-http-provider') &&
254
+ const useTokenFile = (typeof profileTokenFileMode === 'boolean'
255
+ ? profileTokenFileMode
256
+ : (oauthProviderId === 'qwen' ||
257
+ oauthProviderId === 'iflow' ||
258
+ this.type === 'gemini-cli-http-provider')) &&
242
259
  !oauthAuth.clientId &&
243
260
  !oauthAuth.tokenUrl &&
244
261
  !oauthAuth.deviceCodeUrl;
@@ -318,6 +335,7 @@ export class HttpTransportProvider extends BaseProvider {
318
335
  shouldRetryHttpError: this.shouldRetryHttpError.bind(this),
319
336
  delayBeforeHttpRetry: this.delayBeforeHttpRetry.bind(this),
320
337
  tryRecoverOAuthAndReplay: this.tryRecoverOAuthAndReplay.bind(this),
338
+ resolveBusinessResponseError: this.resolveProfileBusinessResponseError.bind(this),
321
339
  normalizeHttpError: this.normalizeHttpError.bind(this)
322
340
  };
323
341
  }
@@ -430,8 +448,15 @@ export class HttpTransportProvider extends BaseProvider {
430
448
  const context = this.createProviderContext();
431
449
  return this.requestExecutor.execute(request, context);
432
450
  }
433
- wantsUpstreamSse(_request, _context) {
434
- return false;
451
+ wantsUpstreamSse(request, context) {
452
+ const runtimeMetadata = context.runtimeMetadata ?? this.getCurrentRuntimeMetadata();
453
+ const familyProfile = this.resolveFamilyProfile(runtimeMetadata);
454
+ const profileResolved = familyProfile?.resolveStreamIntent?.({
455
+ request,
456
+ context,
457
+ runtimeMetadata
458
+ });
459
+ return typeof profileResolved === 'boolean' ? profileResolved : false;
435
460
  }
436
461
  applyStreamModeHeaders(headers, wantsSse) {
437
462
  const normalized = { ...headers };
@@ -442,10 +467,27 @@ export class HttpTransportProvider extends BaseProvider {
442
467
  delete normalized[acceptKey];
443
468
  }
444
469
  normalized['Accept'] = wantsSse ? 'text/event-stream' : 'application/json';
470
+ const runtimeMetadata = this.getCurrentRuntimeMetadata();
471
+ const familyProfile = this.resolveFamilyProfile(runtimeMetadata);
472
+ const profileHeaders = familyProfile?.applyStreamModeHeaders?.({
473
+ headers: normalized,
474
+ wantsSse,
475
+ runtimeMetadata
476
+ });
477
+ if (profileHeaders && typeof profileHeaders === 'object') {
478
+ return profileHeaders;
479
+ }
445
480
  return normalized;
446
481
  }
447
- prepareSseRequestBody(_body, _context) {
448
- // default no-op
482
+ prepareSseRequestBody(body, context) {
483
+ const runtimeMetadata = context?.runtimeMetadata ?? this.getCurrentRuntimeMetadata();
484
+ const familyProfile = this.resolveFamilyProfile(runtimeMetadata);
485
+ const effectiveContext = context ?? this.createProviderContext();
486
+ familyProfile?.prepareStreamBody?.({
487
+ body,
488
+ context: effectiveContext,
489
+ runtimeMetadata
490
+ });
449
491
  }
450
492
  async wrapUpstreamSseResponse(stream, _context) {
451
493
  return { __sse_responses: stream };
@@ -482,6 +524,39 @@ export class HttpTransportProvider extends BaseProvider {
482
524
  async tryRecoverOAuthAndReplay(error, requestInfo, processedRequest, captureSse, context) {
483
525
  try {
484
526
  const providerAuth = this.config.config.auth;
527
+ const authRawType = typeof providerAuth.rawType === 'string'
528
+ ? String(providerAuth.rawType).trim().toLowerCase()
529
+ : '';
530
+ const isDeepSeekAccount = authRawType === 'deepseek-account';
531
+ if (isDeepSeekAccount) {
532
+ const statusCode = extractStatusCodeFromError(error);
533
+ const authProvider = this.authProvider;
534
+ if (statusCode === 401 && authProvider?.refreshCredentials) {
535
+ await authProvider.refreshCredentials();
536
+ const retryHeaders = await this.buildRequestHeaders();
537
+ let finalRetryHeaders = await this.finalizeRequestHeaders(retryHeaders, processedRequest);
538
+ finalRetryHeaders = this.applyStreamModeHeaders(finalRetryHeaders, requestInfo.wantsSse);
539
+ if (requestInfo.wantsSse) {
540
+ const upstreamStream = await this.httpClient.postStream(requestInfo.targetUrl, requestInfo.body, finalRetryHeaders);
541
+ const streamForHost = captureSse
542
+ ? attachProviderSseSnapshotStream(upstreamStream, {
543
+ requestId: context.requestId,
544
+ headers: finalRetryHeaders,
545
+ url: requestInfo.targetUrl,
546
+ entryEndpoint: requestInfo.entryEndpoint,
547
+ clientRequestId: requestInfo.clientRequestId,
548
+ providerKey: context.providerKey,
549
+ providerId: context.providerId,
550
+ extra: { retry: true, authRefresh: true }
551
+ })
552
+ : upstreamStream;
553
+ return await this.wrapUpstreamSseResponse(streamForHost, context);
554
+ }
555
+ const response = await this.httpClient.post(requestInfo.targetUrl, requestInfo.body, finalRetryHeaders);
556
+ return response;
557
+ }
558
+ return undefined;
559
+ }
485
560
  if (this.normalizeAuthMode(providerAuth.type) !== 'oauth') {
486
561
  return undefined;
487
562
  }
@@ -601,48 +676,150 @@ export class HttpTransportProvider extends BaseProvider {
601
676
  catch { /* non-blocking */ }
602
677
  return normalized;
603
678
  }
679
+ resolveProfileBusinessResponseError(response, context) {
680
+ const runtimeMetadata = context.runtimeMetadata ?? this.getCurrentRuntimeMetadata();
681
+ const familyProfile = this.resolveFamilyProfile(runtimeMetadata);
682
+ if (!familyProfile?.resolveBusinessResponseError) {
683
+ return undefined;
684
+ }
685
+ return familyProfile.resolveBusinessResponseError({
686
+ response,
687
+ runtimeMetadata
688
+ });
689
+ }
604
690
  /**
605
691
  * 为特定请求确定最终 endpoint(默认使用配置值,可由子类覆写)
606
692
  */
607
693
  resolveRequestEndpoint(request, defaultEndpoint) {
608
- const metadataNode = request?.metadata &&
609
- typeof request.metadata === 'object'
610
- ? request.metadata
611
- : undefined;
612
- const isIflowWebSearch = metadataNode?.iflowWebSearch === true;
613
- if (isIflowWebSearch) {
614
- const entryEndpoint = typeof metadataNode?.entryEndpoint === 'string' && metadataNode.entryEndpoint.trim()
615
- ? metadataNode.entryEndpoint.trim()
616
- : undefined;
617
- return entryEndpoint || '/chat/retrieve';
694
+ const protocolResolvedEndpoint = this.protocolClient.resolveEndpoint(request, defaultEndpoint);
695
+ const runtimeMetadata = this.getCurrentRuntimeMetadata();
696
+ const familyProfile = this.resolveFamilyProfile(runtimeMetadata);
697
+ const profileResolvedEndpoint = familyProfile?.resolveEndpoint?.({
698
+ request,
699
+ defaultEndpoint: protocolResolvedEndpoint,
700
+ runtimeMetadata
701
+ });
702
+ if (typeof profileResolvedEndpoint === 'string' && profileResolvedEndpoint.trim()) {
703
+ return profileResolvedEndpoint.trim();
704
+ }
705
+ const legacyEndpoint = this.resolveLegacyIflowEndpoint(request);
706
+ if (legacyEndpoint) {
707
+ return legacyEndpoint;
618
708
  }
619
- return this.protocolClient.resolveEndpoint(request, defaultEndpoint);
709
+ return protocolResolvedEndpoint;
620
710
  }
621
711
  /**
622
712
  * 构造最终发送到上游的请求体,默认实现包含模型/令牌治理,可由子类覆写
623
713
  */
624
714
  buildHttpRequestBody(request) {
625
- const metadataNode = request?.metadata &&
626
- typeof request.metadata === 'object'
627
- ? request.metadata
715
+ const runtimeMetadata = this.getCurrentRuntimeMetadata();
716
+ const familyProfile = this.resolveFamilyProfile(runtimeMetadata);
717
+ const defaultBody = this.protocolClient.buildRequestBody(request);
718
+ const profileBody = familyProfile?.buildRequestBody?.({
719
+ request,
720
+ defaultBody,
721
+ runtimeMetadata
722
+ });
723
+ if (profileBody && typeof profileBody === 'object') {
724
+ return profileBody;
725
+ }
726
+ const legacyBody = this.resolveLegacyIflowRequestBody(request);
727
+ if (legacyBody && typeof legacyBody === 'object') {
728
+ return legacyBody;
729
+ }
730
+ return defaultBody;
731
+ }
732
+ resolveFamilyProfile(runtimeMetadata) {
733
+ const targetNode = runtimeMetadata?.target && typeof runtimeMetadata.target === 'object'
734
+ ? runtimeMetadata.target
628
735
  : undefined;
629
- const isIflowWebSearch = metadataNode?.iflowWebSearch === true;
630
- if (isIflowWebSearch) {
631
- const dataNode = request.data;
632
- if (dataNode && typeof dataNode === 'object') {
633
- return dataNode;
736
+ const normalize = (value) => {
737
+ if (typeof value !== 'string') {
738
+ return undefined;
634
739
  }
635
- return {};
740
+ const normalized = value.trim().toLowerCase();
741
+ return normalized.length ? normalized : undefined;
742
+ };
743
+ return getProviderFamilyProfile({
744
+ providerFamily: normalize(runtimeMetadata?.providerFamily) ??
745
+ normalize(this.getRuntimeProfile()?.providerFamily),
746
+ providerId: normalize(runtimeMetadata?.providerId) ??
747
+ normalize(targetNode?.providerId) ??
748
+ normalize(this.config?.config?.providerId),
749
+ providerKey: normalize(runtimeMetadata?.providerKey) ??
750
+ normalize(targetNode?.providerKey) ??
751
+ normalize(this.getRuntimeProfile()?.providerKey),
752
+ providerType: normalize(runtimeMetadata?.providerType) ??
753
+ normalize(targetNode?.providerType) ??
754
+ normalize(this.config?.config?.providerType) ??
755
+ normalize(this.providerType),
756
+ oauthProviderId: normalize(this.oauthProviderId)
757
+ });
758
+ }
759
+ isIflowWebSearchRequest(request) {
760
+ const metadata = request.metadata;
761
+ if (!metadata || typeof metadata !== 'object') {
762
+ return false;
763
+ }
764
+ const flag = metadata.iflowWebSearch;
765
+ return flag === true;
766
+ }
767
+ resolveLegacyIflowEndpoint(request) {
768
+ if (!this.isIflowTransportRuntime(this.getCurrentRuntimeMetadata())) {
769
+ return undefined;
770
+ }
771
+ if (!this.isIflowWebSearchRequest(request)) {
772
+ return undefined;
636
773
  }
637
- const built = this.protocolClient.buildRequestBody(request);
638
- this.applyProviderSpecificBodyAdjustments(built);
639
- return built;
774
+ const metadata = request.metadata;
775
+ const endpoint = metadata && typeof metadata.entryEndpoint === 'string'
776
+ ? (metadata.entryEndpoint || '').trim()
777
+ : '';
778
+ return endpoint || '/chat/retrieve';
779
+ }
780
+ resolveLegacyIflowRequestBody(request) {
781
+ if (!this.isIflowTransportRuntime(this.getCurrentRuntimeMetadata())) {
782
+ return undefined;
783
+ }
784
+ if (!this.isIflowWebSearchRequest(request)) {
785
+ return undefined;
786
+ }
787
+ const data = request.data;
788
+ if (data && typeof data === 'object') {
789
+ return data;
790
+ }
791
+ return {};
640
792
  }
641
793
  /**
642
794
  * 允许子类在 Hook 运行完后对头部做最终调整
643
795
  */
644
796
  async finalizeRequestHeaders(headers, request) {
645
- return await this.protocolClient.finalizeHeaders(headers, request);
797
+ const finalized = await this.protocolClient.finalizeHeaders(headers, request);
798
+ const runtimeMetadata = this.getCurrentRuntimeMetadata();
799
+ const familyProfile = this.resolveFamilyProfile(runtimeMetadata);
800
+ const profileResolvedUa = await familyProfile?.resolveUserAgent?.({
801
+ uaFromConfig: this.findHeaderValue(finalized, 'User-Agent'),
802
+ uaFromService: undefined,
803
+ inboundUserAgent: undefined,
804
+ defaultUserAgent: DEFAULT_USER_AGENT,
805
+ runtimeMetadata
806
+ });
807
+ if (typeof profileResolvedUa === 'string' && profileResolvedUa.trim()) {
808
+ this.assignHeader(finalized, 'User-Agent', profileResolvedUa.trim());
809
+ }
810
+ const profileAdjustedHeaders = familyProfile?.applyRequestHeaders?.({
811
+ headers: finalized,
812
+ request,
813
+ runtimeMetadata,
814
+ isCodexUaMode: this.isCodexUaMode()
815
+ });
816
+ if (profileAdjustedHeaders && typeof profileAdjustedHeaders === 'object') {
817
+ return profileAdjustedHeaders;
818
+ }
819
+ if (this.isIflowTransportRuntime(runtimeMetadata)) {
820
+ this.enforceIflowCliHeaders(finalized);
821
+ }
822
+ return finalized;
646
823
  }
647
824
  // 私有方法
648
825
  validateConfig() {
@@ -718,8 +895,26 @@ export class HttpTransportProvider extends BaseProvider {
718
895
  catch (error) {
719
896
  const err = error;
720
897
  const msg = err?.message ? String(err.message) : String(error);
721
- // Non-blocking: do not start device-code polling or crash requests here.
722
- // We'll let the upstream 401/403 path trigger interactive repair when appropriate.
898
+ const authErr = (error instanceof Error ? error : new Error(msg));
899
+ const needsInteractiveRepair = shouldTriggerInteractiveOAuthRepair(oauthProviderId, authErr);
900
+ if (needsInteractiveRepair) {
901
+ if (typeof authErr.statusCode !== 'number' && typeof authErr.status !== 'number') {
902
+ authErr.statusCode = 401;
903
+ authErr.status = 401;
904
+ }
905
+ if (typeof authErr.code !== 'string' || !authErr.code.trim()) {
906
+ authErr.code = 'AUTH_INVALID_TOKEN';
907
+ }
908
+ // 非阻塞:后台触发修复,不等待本请求。
909
+ void handleUpstreamInvalidOAuthToken(oauthProviderId, oauthAuth, authErr, {
910
+ allowBlocking: false
911
+ }).catch(() => {
912
+ // ignore background repair errors
913
+ });
914
+ authErr.__routecodexAuthPreflightFatal = true;
915
+ throw authErr;
916
+ }
917
+ // 非认证类的 ensureValid 错误只做日志,避免影响正常流量。
723
918
  logOAuthDebug(`[OAuth] [headers] ensureValid skipped: ${msg}`);
724
919
  }
725
920
  try {
@@ -730,10 +925,22 @@ export class HttpTransportProvider extends BaseProvider {
730
925
  }
731
926
  }
732
927
  }
733
- catch {
928
+ catch (error) {
929
+ if (error &&
930
+ typeof error === 'object' &&
931
+ error.__routecodexAuthPreflightFatal === true) {
932
+ throw error;
933
+ }
734
934
  // bubble up in authHeaders build below
735
935
  }
736
936
  // 认证头部(如为 OAuth,若当前无有效 token 则尝试拉取/刷新一次再取 headers)
937
+ const providerAuth = this.config.config.auth;
938
+ const authRawType = typeof providerAuth.rawType === 'string'
939
+ ? String(providerAuth.rawType).trim().toLowerCase()
940
+ : '';
941
+ if (authRawType === 'deepseek-account' && this.authProvider?.validateCredentials) {
942
+ await this.authProvider.validateCredentials();
943
+ }
737
944
  let authHeaders = {};
738
945
  authHeaders = this.authProvider?.buildHeaders() || {};
739
946
  const finalHeaders = {
@@ -761,9 +968,17 @@ export class HttpTransportProvider extends BaseProvider {
761
968
  // 因此对 iflow:service/profile 的 UA 优先级应高于 inbound client userAgent,
762
969
  // 否则客户端 UA 会把模拟头部冲掉,触发 HTTP 200 + status=435 "Model not support"。
763
970
  const isIflow = this.isIflowTransportRuntime(runtimeMetadata);
764
- const resolvedUa = isIflow
971
+ const familyProfile = this.resolveFamilyProfile(runtimeMetadata);
972
+ const profileResolvedUa = await familyProfile?.resolveUserAgent?.({
973
+ uaFromConfig,
974
+ uaFromService,
975
+ inboundUserAgent,
976
+ defaultUserAgent: DEFAULT_USER_AGENT,
977
+ runtimeMetadata
978
+ });
979
+ const resolvedUa = profileResolvedUa ?? (isIflow
765
980
  ? (uaFromConfig ?? uaFromService ?? inboundUserAgent ?? DEFAULT_USER_AGENT)
766
- : (uaFromConfig ?? inboundUserAgent ?? uaFromService ?? DEFAULT_USER_AGENT);
981
+ : (uaFromConfig ?? inboundUserAgent ?? uaFromService ?? DEFAULT_USER_AGENT));
767
982
  this.assignHeader(finalHeaders, 'User-Agent', resolvedUa);
768
983
  // originator: do not invent one; only forward from config or inbound client.
769
984
  // gcli2api alignment: Gemini-family upstreams do not expect/need originator; avoid leaking client identifiers.
@@ -801,13 +1016,17 @@ export class HttpTransportProvider extends BaseProvider {
801
1016
  this.assignHeader(finalHeaders, 'conversation_id', resolvedConversationId);
802
1017
  }
803
1018
  }
804
- if (!isAntigravity && this.isCodexUaMode()) {
1019
+ const codexUaMode = this.isCodexUaMode();
1020
+ if (!isAntigravity && codexUaMode) {
805
1021
  this.ensureCodexSessionHeaders(finalHeaders, runtimeMetadata);
806
1022
  }
807
1023
  if (isAntigravity) {
808
1024
  this.deleteHeader(finalHeaders, 'session_id');
809
1025
  this.deleteHeader(finalHeaders, 'conversation_id');
810
1026
  }
1027
+ if (isIflow) {
1028
+ this.enforceIflowCliHeaders(finalHeaders);
1029
+ }
811
1030
  return finalHeaders;
812
1031
  }
813
1032
  isCodexUaMode() {
@@ -927,6 +1146,56 @@ export class HttpTransportProvider extends BaseProvider {
927
1146
  }
928
1147
  this.assignHeader(headers, target, value);
929
1148
  }
1149
+ enforceIflowCliHeaders(headers) {
1150
+ const resolvedSessionId = this.findHeaderValue(headers, 'session-id') ??
1151
+ this.findHeaderValue(headers, 'session_id') ??
1152
+ '';
1153
+ const resolvedConversationId = this.findHeaderValue(headers, 'conversation-id') ??
1154
+ this.findHeaderValue(headers, 'conversation_id') ??
1155
+ resolvedSessionId;
1156
+ if (resolvedSessionId) {
1157
+ this.assignHeader(headers, 'session-id', resolvedSessionId);
1158
+ }
1159
+ if (resolvedConversationId) {
1160
+ this.assignHeader(headers, 'conversation-id', resolvedConversationId);
1161
+ }
1162
+ const bearerApiKey = this.extractBearerApiKey(headers);
1163
+ if (!bearerApiKey) {
1164
+ return;
1165
+ }
1166
+ const userAgent = this.findHeaderValue(headers, 'User-Agent') ?? 'iFlow-Cli';
1167
+ const timestamp = Date.now().toString();
1168
+ const signature = this.buildIflowSignature(userAgent, resolvedSessionId, timestamp, bearerApiKey);
1169
+ if (!signature) {
1170
+ return;
1171
+ }
1172
+ this.assignHeader(headers, 'x-iflow-timestamp', timestamp);
1173
+ this.assignHeader(headers, 'x-iflow-signature', signature);
1174
+ }
1175
+ extractBearerApiKey(headers) {
1176
+ const authorization = this.findHeaderValue(headers, 'Authorization');
1177
+ if (!authorization) {
1178
+ return undefined;
1179
+ }
1180
+ const matched = authorization.match(/^Bearer\s+(.+)$/i);
1181
+ if (!matched || !matched[1]) {
1182
+ return undefined;
1183
+ }
1184
+ const apiKey = matched[1].trim();
1185
+ return apiKey || undefined;
1186
+ }
1187
+ buildIflowSignature(userAgent, sessionId, timestamp, apiKey) {
1188
+ if (!apiKey) {
1189
+ return undefined;
1190
+ }
1191
+ const payload = `${userAgent}:${sessionId}:${timestamp}`;
1192
+ try {
1193
+ return createHmac('sha256', apiKey).update(payload, 'utf8').digest('hex');
1194
+ }
1195
+ catch {
1196
+ return undefined;
1197
+ }
1198
+ }
930
1199
  buildCodexIdentifier(kind, runtimeMetadata) {
931
1200
  const fallbackId = runtimeMetadata?.metadata && typeof runtimeMetadata.metadata === 'object'
932
1201
  ? runtimeMetadata.metadata.clientRequestId
@@ -1230,49 +1499,6 @@ export class HttpTransportProvider extends BaseProvider {
1230
1499
  }
1231
1500
  return Object.keys(normalized).length ? normalized : undefined;
1232
1501
  }
1233
- applyProviderSpecificBodyAdjustments(body) {
1234
- if (!body || typeof body !== 'object') {
1235
- return;
1236
- }
1237
- if (this.providerType === 'glm') {
1238
- this.trimGlmRequestMessages(body);
1239
- }
1240
- }
1241
- trimGlmRequestMessages(body) {
1242
- const container = body;
1243
- const rawMessages = container.messages;
1244
- if (!Array.isArray(rawMessages) || rawMessages.length === 0) {
1245
- return;
1246
- }
1247
- const messages = rawMessages;
1248
- for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
1249
- const entry = messages[idx];
1250
- if (!entry || typeof entry !== 'object') {
1251
- continue;
1252
- }
1253
- if (entry.role !== 'assistant') {
1254
- continue;
1255
- }
1256
- const contentNode = entry.content;
1257
- if (typeof contentNode === 'string') {
1258
- continue;
1259
- }
1260
- if (contentNode === null || typeof contentNode === 'undefined') {
1261
- entry.content = '';
1262
- continue;
1263
- }
1264
- if (typeof contentNode === 'object') {
1265
- try {
1266
- entry.content = JSON.stringify(contentNode);
1267
- }
1268
- catch {
1269
- entry.content = '';
1270
- }
1271
- continue;
1272
- }
1273
- entry.content = String(contentNode);
1274
- }
1275
- }
1276
1502
  }
1277
1503
  const CODEX_IDENTIFIER_MAX_LENGTH = 64;
1278
1504
  //# sourceMappingURL=http-transport-provider.js.map