@tonyclaw/agent-inspector 2.0.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.
Files changed (400) hide show
  1. package/.output/cli.js +1611 -0
  2. package/.output/nitro.json +17 -0
  3. package/.output/public/assets/CompareDrawer-CU5ZrWcL.js +1 -0
  4. package/.output/public/assets/ProxyViewerContainer-pEBqVp1d.js +101 -0
  5. package/.output/public/assets/ReplayDialog-F58yNg5j.js +1 -0
  6. package/.output/public/assets/RequestAnatomy-C9lT0qE_.js +1 -0
  7. package/.output/public/assets/ResponseView-DHJq6bnz.js +1 -0
  8. package/.output/public/assets/StreamingChunkSequence-BTgfpFUT.js +1 -0
  9. package/.output/public/assets/_sessionId-DsNRbnNm.js +1 -0
  10. package/.output/public/assets/alibaba-TTwafVwX.svg +1 -0
  11. package/.output/public/assets/index-CpWG2hFn.css +1 -0
  12. package/.output/public/assets/index-DmBV8Gve.js +1 -0
  13. package/.output/public/assets/json-viewer-CZVYLR8j.js +14 -0
  14. package/.output/public/assets/main-DHs7FBK3.js +18 -0
  15. package/.output/public/assets/minimax-BPMzvuL-.jpeg +0 -0
  16. package/.output/public/assets/qwen-CONDcHqt.png +0 -0
  17. package/.output/public/assets/zhipuai-BPNAnxo-.svg +219 -0
  18. package/.output/server/_chunks/ssr-renderer.mjs +22 -0
  19. package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +1 -0
  20. package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +210 -0
  21. package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +2 -0
  22. package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +2 -0
  23. package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +2 -0
  24. package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +11 -0
  25. package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +69 -0
  26. package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +1 -0
  27. package/.output/server/_libs/@radix-ui/react-use-escape-keydown+[...].mjs +17 -0
  28. package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +1 -0
  29. package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +6 -0
  30. package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +34 -0
  31. package/.output/server/_libs/ajv-formats.mjs +330 -0
  32. package/.output/server/_libs/ajv.mjs +11444 -0
  33. package/.output/server/_libs/aria-hidden.mjs +122 -0
  34. package/.output/server/_libs/atomically.mjs +152 -0
  35. package/.output/server/_libs/bail.mjs +8 -0
  36. package/.output/server/_libs/cfworker__json-schema.mjs +1 -0
  37. package/.output/server/_libs/character-entities.mjs +2130 -0
  38. package/.output/server/_libs/class-variance-authority.mjs +44 -0
  39. package/.output/server/_libs/clsx.mjs +16 -0
  40. package/.output/server/_libs/comma-separated-tokens.mjs +10 -0
  41. package/.output/server/_libs/conf.mjs +635 -0
  42. package/.output/server/_libs/cookie-es.mjs +58 -0
  43. package/.output/server/_libs/core-util-is.mjs +75 -0
  44. package/.output/server/_libs/croner.mjs +1 -0
  45. package/.output/server/_libs/crossws.mjs +1 -0
  46. package/.output/server/_libs/debounce-fn.mjs +69 -0
  47. package/.output/server/_libs/decode-named-character-reference+[...].mjs +8 -0
  48. package/.output/server/_libs/dequal.mjs +27 -0
  49. package/.output/server/_libs/detect-node-es.mjs +1 -0
  50. package/.output/server/_libs/devlop.mjs +8 -0
  51. package/.output/server/_libs/diff.mjs +320 -0
  52. package/.output/server/_libs/dot-prop.mjs +265 -0
  53. package/.output/server/_libs/env-paths.mjs +57 -0
  54. package/.output/server/_libs/estree-util-is-identifier-name.mjs +11 -0
  55. package/.output/server/_libs/extend.mjs +97 -0
  56. package/.output/server/_libs/fast-deep-equal.mjs +38 -0
  57. package/.output/server/_libs/fast-uri.mjs +812 -0
  58. package/.output/server/_libs/floating-ui__core.mjs +725 -0
  59. package/.output/server/_libs/floating-ui__dom.mjs +622 -0
  60. package/.output/server/_libs/floating-ui__react-dom.mjs +292 -0
  61. package/.output/server/_libs/floating-ui__utils.mjs +320 -0
  62. package/.output/server/_libs/get-nonce.mjs +9 -0
  63. package/.output/server/_libs/h3-v2.mjs +276 -0
  64. package/.output/server/_libs/h3.mjs +408 -0
  65. package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +388 -0
  66. package/.output/server/_libs/hast-util-whitespace.mjs +10 -0
  67. package/.output/server/_libs/hookable.mjs +1 -0
  68. package/.output/server/_libs/html-url-attributes.mjs +26 -0
  69. package/.output/server/_libs/immediate.mjs +74 -0
  70. package/.output/server/_libs/inherits.mjs +50 -0
  71. package/.output/server/_libs/inline-style-parser.mjs +142 -0
  72. package/.output/server/_libs/is-plain-obj.mjs +10 -0
  73. package/.output/server/_libs/isarray.mjs +14 -0
  74. package/.output/server/_libs/isbot.mjs +20 -0
  75. package/.output/server/_libs/json-schema-traverse.mjs +180 -0
  76. package/.output/server/_libs/jszip.mjs +3051 -0
  77. package/.output/server/_libs/lie.mjs +273 -0
  78. package/.output/server/_libs/lucide-react.mjs +492 -0
  79. package/.output/server/_libs/mdast-util-from-markdown.mjs +717 -0
  80. package/.output/server/_libs/mdast-util-to-hast.mjs +710 -0
  81. package/.output/server/_libs/mdast-util-to-string.mjs +38 -0
  82. package/.output/server/_libs/micromark-core-commonmark.mjs +2259 -0
  83. package/.output/server/_libs/micromark-factory-destination.mjs +94 -0
  84. package/.output/server/_libs/micromark-factory-label.mjs +63 -0
  85. package/.output/server/_libs/micromark-factory-space.mjs +24 -0
  86. package/.output/server/_libs/micromark-factory-title.mjs +65 -0
  87. package/.output/server/_libs/micromark-factory-whitespace.mjs +22 -0
  88. package/.output/server/_libs/micromark-util-character.mjs +44 -0
  89. package/.output/server/_libs/micromark-util-chunked.mjs +36 -0
  90. package/.output/server/_libs/micromark-util-classify-character+[...].mjs +12 -0
  91. package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +41 -0
  92. package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +19 -0
  93. package/.output/server/_libs/micromark-util-decode-string.mjs +21 -0
  94. package/.output/server/_libs/micromark-util-encode.mjs +1 -0
  95. package/.output/server/_libs/micromark-util-html-tag-name.mjs +69 -0
  96. package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +6 -0
  97. package/.output/server/_libs/micromark-util-resolve-all.mjs +15 -0
  98. package/.output/server/_libs/micromark-util-sanitize-uri.mjs +41 -0
  99. package/.output/server/_libs/micromark-util-subtokenize.mjs +346 -0
  100. package/.output/server/_libs/micromark.mjs +906 -0
  101. package/.output/server/_libs/mimic-function.mjs +47 -0
  102. package/.output/server/_libs/modelcontextprotocol__server.mjs +9738 -0
  103. package/.output/server/_libs/ocache.mjs +1 -0
  104. package/.output/server/_libs/ohash.mjs +1 -0
  105. package/.output/server/_libs/pako.mjs +4223 -0
  106. package/.output/server/_libs/process-nextick-args.mjs +48 -0
  107. package/.output/server/_libs/property-information.mjs +1209 -0
  108. package/.output/server/_libs/radix-ui.mjs +1 -0
  109. package/.output/server/_libs/radix-ui__number.mjs +6 -0
  110. package/.output/server/_libs/radix-ui__primitive.mjs +11 -0
  111. package/.output/server/_libs/radix-ui__react-accordion.mjs +1 -0
  112. package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +1 -0
  113. package/.output/server/_libs/radix-ui__react-arrow.mjs +23 -0
  114. package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +1 -0
  115. package/.output/server/_libs/radix-ui__react-avatar.mjs +1 -0
  116. package/.output/server/_libs/radix-ui__react-checkbox.mjs +1 -0
  117. package/.output/server/_libs/radix-ui__react-collapsible.mjs +144 -0
  118. package/.output/server/_libs/radix-ui__react-collection.mjs +69 -0
  119. package/.output/server/_libs/radix-ui__react-compose-refs.mjs +39 -0
  120. package/.output/server/_libs/radix-ui__react-context-menu.mjs +1 -0
  121. package/.output/server/_libs/radix-ui__react-context.mjs +78 -0
  122. package/.output/server/_libs/radix-ui__react-dialog.mjs +325 -0
  123. package/.output/server/_libs/radix-ui__react-direction.mjs +9 -0
  124. package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +1 -0
  125. package/.output/server/_libs/radix-ui__react-focus-guards.mjs +29 -0
  126. package/.output/server/_libs/radix-ui__react-focus-scope.mjs +206 -0
  127. package/.output/server/_libs/radix-ui__react-form.mjs +1 -0
  128. package/.output/server/_libs/radix-ui__react-hover-card.mjs +1 -0
  129. package/.output/server/_libs/radix-ui__react-id.mjs +14 -0
  130. package/.output/server/_libs/radix-ui__react-label.mjs +1 -0
  131. package/.output/server/_libs/radix-ui__react-menu.mjs +1 -0
  132. package/.output/server/_libs/radix-ui__react-menubar.mjs +1 -0
  133. package/.output/server/_libs/radix-ui__react-popover.mjs +1 -0
  134. package/.output/server/_libs/radix-ui__react-popper.mjs +286 -0
  135. package/.output/server/_libs/radix-ui__react-portal.mjs +16 -0
  136. package/.output/server/_libs/radix-ui__react-presence.mjs +128 -0
  137. package/.output/server/_libs/radix-ui__react-primitive.mjs +42 -0
  138. package/.output/server/_libs/radix-ui__react-progress.mjs +1 -0
  139. package/.output/server/_libs/radix-ui__react-radio-group.mjs +1 -0
  140. package/.output/server/_libs/radix-ui__react-roving-focus.mjs +224 -0
  141. package/.output/server/_libs/radix-ui__react-scroll-area.mjs +721 -0
  142. package/.output/server/_libs/radix-ui__react-select.mjs +1163 -0
  143. package/.output/server/_libs/radix-ui__react-separator.mjs +28 -0
  144. package/.output/server/_libs/radix-ui__react-slider.mjs +1 -0
  145. package/.output/server/_libs/radix-ui__react-slot.mjs +99 -0
  146. package/.output/server/_libs/radix-ui__react-switch.mjs +1 -0
  147. package/.output/server/_libs/radix-ui__react-tabs.mjs +189 -0
  148. package/.output/server/_libs/radix-ui__react-toast.mjs +2 -0
  149. package/.output/server/_libs/radix-ui__react-toggle-group.mjs +1 -0
  150. package/.output/server/_libs/radix-ui__react-toggle.mjs +1 -0
  151. package/.output/server/_libs/radix-ui__react-toolbar.mjs +1 -0
  152. package/.output/server/_libs/radix-ui__react-tooltip.mjs +495 -0
  153. package/.output/server/_libs/radix-ui__react-use-previous.mjs +14 -0
  154. package/.output/server/_libs/radix-ui__react-use-size.mjs +39 -0
  155. package/.output/server/_libs/react-dom.mjs +10781 -0
  156. package/.output/server/_libs/react-markdown.mjs +147 -0
  157. package/.output/server/_libs/react-remove-scroll-bar.mjs +82 -0
  158. package/.output/server/_libs/react-remove-scroll.mjs +328 -0
  159. package/.output/server/_libs/react-style-singleton.mjs +69 -0
  160. package/.output/server/_libs/react.mjs +515 -0
  161. package/.output/server/_libs/readable-stream.mjs +1518 -0
  162. package/.output/server/_libs/remark-parse.mjs +19 -0
  163. package/.output/server/_libs/remark-rehype.mjs +21 -0
  164. package/.output/server/_libs/rou3.mjs +14 -0
  165. package/.output/server/_libs/safe-buffer.mjs +64 -0
  166. package/.output/server/_libs/semver.mjs +1938 -0
  167. package/.output/server/_libs/seroval-plugins.mjs +58 -0
  168. package/.output/server/_libs/seroval.mjs +1765 -0
  169. package/.output/server/_libs/setimmediate.mjs +152 -0
  170. package/.output/server/_libs/space-separated-tokens.mjs +6 -0
  171. package/.output/server/_libs/srvx.mjs +1029 -0
  172. package/.output/server/_libs/stubborn-fs.mjs +91 -0
  173. package/.output/server/_libs/stubborn-utils.mjs +66 -0
  174. package/.output/server/_libs/style-to-js.mjs +72 -0
  175. package/.output/server/_libs/style-to-object.mjs +38 -0
  176. package/.output/server/_libs/swr.mjs +939 -0
  177. package/.output/server/_libs/tailwind-merge.mjs +3010 -0
  178. package/.output/server/_libs/tanstack__history.mjs +217 -0
  179. package/.output/server/_libs/tanstack__react-router.mjs +1480 -0
  180. package/.output/server/_libs/tanstack__react-store.mjs +1 -0
  181. package/.output/server/_libs/tanstack__react-virtual.mjs +44 -0
  182. package/.output/server/_libs/tanstack__router-core.mjs +4827 -0
  183. package/.output/server/_libs/tanstack__store.mjs +1 -0
  184. package/.output/server/_libs/tanstack__virtual-core.mjs +1225 -0
  185. package/.output/server/_libs/tiny-invariant.mjs +12 -0
  186. package/.output/server/_libs/tiny-warning.mjs +5 -0
  187. package/.output/server/_libs/trim-lines.mjs +41 -0
  188. package/.output/server/_libs/trough.mjs +85 -0
  189. package/.output/server/_libs/tslib.mjs +1 -0
  190. package/.output/server/_libs/ufo.mjs +54 -0
  191. package/.output/server/_libs/uint8array-extras.mjs +69 -0
  192. package/.output/server/_libs/ungap__structured-clone.mjs +212 -0
  193. package/.output/server/_libs/unified.mjs +661 -0
  194. package/.output/server/_libs/unist-util-is.mjs +100 -0
  195. package/.output/server/_libs/unist-util-position.mjs +27 -0
  196. package/.output/server/_libs/unist-util-stringify-position.mjs +27 -0
  197. package/.output/server/_libs/unist-util-visit-parents.mjs +82 -0
  198. package/.output/server/_libs/unist-util-visit.mjs +24 -0
  199. package/.output/server/_libs/unstorage.mjs +1 -0
  200. package/.output/server/_libs/use-callback-ref.mjs +66 -0
  201. package/.output/server/_libs/use-sidecar.mjs +106 -0
  202. package/.output/server/_libs/use-sync-external-store.mjs +64 -0
  203. package/.output/server/_libs/util-deprecate.mjs +12 -0
  204. package/.output/server/_libs/vfile-message.mjs +138 -0
  205. package/.output/server/_libs/vfile.mjs +467 -0
  206. package/.output/server/_libs/when-exit.mjs +53 -0
  207. package/.output/server/_libs/zod.mjs +4524 -0
  208. package/.output/server/_sessionId-wMLPvC5g.mjs +123 -0
  209. package/.output/server/_ssr/CompareDrawer-BU4V0uVf.mjs +1041 -0
  210. package/.output/server/_ssr/ProxyViewerContainer-BnRwFEnn.mjs +5972 -0
  211. package/.output/server/_ssr/ReplayDialog-C7dn9pd_.mjs +322 -0
  212. package/.output/server/_ssr/RequestAnatomy-C1rWpe9-.mjs +353 -0
  213. package/.output/server/_ssr/ResponseView-hGpPaYsf.mjs +602 -0
  214. package/.output/server/_ssr/StreamingChunkSequence-BRWI1r_G.mjs +302 -0
  215. package/.output/server/_ssr/index-BKURLVPz.mjs +118 -0
  216. package/.output/server/_ssr/index.mjs +1184 -0
  217. package/.output/server/_ssr/json-viewer-BBd2DtQP.mjs +515 -0
  218. package/.output/server/_ssr/router-BcZ0D6AB.mjs +6317 -0
  219. package/.output/server/_ssr/start-HYkvq4Ni.mjs +4 -0
  220. package/.output/server/_tanstack-start-manifest_v-1y8ZVxRI.mjs +4 -0
  221. package/.output/server/index.mjs +436 -0
  222. package/.output/server/node_modules/tslib/modules/index.js +70 -0
  223. package/.output/server/node_modules/tslib/modules/package.json +3 -0
  224. package/.output/server/node_modules/tslib/package.json +47 -0
  225. package/.output/server/node_modules/tslib/tslib.js +484 -0
  226. package/.output/server/package.json +9 -0
  227. package/LICENSE +21 -0
  228. package/README.md +52 -0
  229. package/package.json +110 -0
  230. package/src/assets/favicon.svg +31 -0
  231. package/src/assets/logos/alibaba.svg +1 -0
  232. package/src/assets/logos/anthropic.svg +1 -0
  233. package/src/assets/logos/claude-code.svg +4 -0
  234. package/src/assets/logos/deepseek.svg +1 -0
  235. package/src/assets/logos/mcp.png +0 -0
  236. package/src/assets/logos/minimax.jpeg +0 -0
  237. package/src/assets/logos/openai.svg +1 -0
  238. package/src/assets/logos/opencode.svg +4 -0
  239. package/src/assets/logos/qwen.png +0 -0
  240. package/src/assets/logos/zhipuai.svg +219 -0
  241. package/src/cli/detect-tools.ts +147 -0
  242. package/src/cli/doctor.ts +521 -0
  243. package/src/cli/onboard.ts +224 -0
  244. package/src/cli/templates/command-onboard.ts +17 -0
  245. package/src/cli/templates/skill-onboard.ts +547 -0
  246. package/src/cli.ts +345 -0
  247. package/src/components/OnboardingBanner.tsx +67 -0
  248. package/src/components/ProxyViewer.tsx +545 -0
  249. package/src/components/ProxyViewerContainer.tsx +363 -0
  250. package/src/components/providers/ImportWizardDialog.tsx +349 -0
  251. package/src/components/providers/ProviderCard.tsx +474 -0
  252. package/src/components/providers/ProviderForm.tsx +494 -0
  253. package/src/components/providers/ProviderLogo.tsx +117 -0
  254. package/src/components/providers/ProvidersPanel.tsx +619 -0
  255. package/src/components/providers/SettingsDialog.tsx +202 -0
  256. package/src/components/proxy-viewer/CompareDrawer.tsx +893 -0
  257. package/src/components/proxy-viewer/ConversationGroup.tsx +107 -0
  258. package/src/components/proxy-viewer/ConversationHeader.tsx +300 -0
  259. package/src/components/proxy-viewer/LogEntry.tsx +543 -0
  260. package/src/components/proxy-viewer/LogEntryHeader.tsx +501 -0
  261. package/src/components/proxy-viewer/ReplayDialog.tsx +218 -0
  262. package/src/components/proxy-viewer/ResponseView.tsx +171 -0
  263. package/src/components/proxy-viewer/StreamingChunkSequence.tsx +188 -0
  264. package/src/components/proxy-viewer/ThreadConnector.tsx +136 -0
  265. package/src/components/proxy-viewer/TurnGroup.tsx +337 -0
  266. package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +98 -0
  267. package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +196 -0
  268. package/src/components/proxy-viewer/anatomy/tokenEstimate.ts +53 -0
  269. package/src/components/proxy-viewer/anatomy/types.ts +39 -0
  270. package/src/components/proxy-viewer/anatomy/useAnatomyJump.ts +114 -0
  271. package/src/components/proxy-viewer/cacheTrend.ts +50 -0
  272. package/src/components/proxy-viewer/diff/DiffView.tsx +321 -0
  273. package/src/components/proxy-viewer/diff/computeDiff.ts +178 -0
  274. package/src/components/proxy-viewer/diff/index.ts +3 -0
  275. package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +157 -0
  276. package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +66 -0
  277. package/src/components/proxy-viewer/formats/anthropic/thinkingExtract.ts +21 -0
  278. package/src/components/proxy-viewer/formats/index.tsx +33 -0
  279. package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +170 -0
  280. package/src/components/proxy-viewer/index.ts +9 -0
  281. package/src/components/proxy-viewer/lazy.ts +37 -0
  282. package/src/components/proxy-viewer/log-formats/anthropic.ts +194 -0
  283. package/src/components/proxy-viewer/log-formats/index.ts +23 -0
  284. package/src/components/proxy-viewer/log-formats/openai.ts +167 -0
  285. package/src/components/proxy-viewer/log-formats/types.ts +40 -0
  286. package/src/components/proxy-viewer/log-formats/unknown.ts +18 -0
  287. package/src/components/proxy-viewer/logEntryVisibility.ts +39 -0
  288. package/src/components/proxy-viewer/requestDiff.ts +277 -0
  289. package/src/components/proxy-viewer/useCopyFeedback.ts +36 -0
  290. package/src/components/proxy-viewer/useKeyboardNavigation.ts +190 -0
  291. package/src/components/proxy-viewer/viewerState.ts +66 -0
  292. package/src/components/ui/badge.tsx +47 -0
  293. package/src/components/ui/button.tsx +47 -0
  294. package/src/components/ui/collapsible.tsx +21 -0
  295. package/src/components/ui/confirm-dialog.tsx +51 -0
  296. package/src/components/ui/crab-logo.tsx +95 -0
  297. package/src/components/ui/crab-variants.tsx +467 -0
  298. package/src/components/ui/dialog.tsx +129 -0
  299. package/src/components/ui/json-expansion-button.tsx +56 -0
  300. package/src/components/ui/json-viewer-bulk.ts +97 -0
  301. package/src/components/ui/json-viewer.tsx +494 -0
  302. package/src/components/ui/mcp-logo.tsx +20 -0
  303. package/src/components/ui/scroll-area.tsx +54 -0
  304. package/src/components/ui/select.tsx +178 -0
  305. package/src/components/ui/separator.tsx +28 -0
  306. package/src/components/ui/tabs.tsx +88 -0
  307. package/src/components/ui/tooltip.tsx +51 -0
  308. package/src/index.css +11 -0
  309. package/src/knowledge/candidateStore.ts +63 -0
  310. package/src/knowledge/distiller.ts +98 -0
  311. package/src/knowledge/openclawClient.ts +118 -0
  312. package/src/knowledge/redactor.ts +80 -0
  313. package/src/knowledge/types.ts +84 -0
  314. package/src/lib/apiClient.ts +49 -0
  315. package/src/lib/export-logs.ts +51 -0
  316. package/src/lib/mask.ts +4 -0
  317. package/src/lib/objectUtils.ts +22 -0
  318. package/src/lib/providerContract.ts +26 -0
  319. package/src/lib/providerTestContract.ts +107 -0
  320. package/src/lib/runtimeConfig.ts +25 -0
  321. package/src/lib/serverPort.ts +41 -0
  322. package/src/lib/sessionUrl.ts +44 -0
  323. package/src/lib/stopReason.ts +58 -0
  324. package/src/lib/useOnboarding.ts +80 -0
  325. package/src/lib/useProviders.ts +30 -0
  326. package/src/lib/useStripConfig.ts +108 -0
  327. package/src/lib/utils.ts +21 -0
  328. package/src/mcp/loopback.ts +76 -0
  329. package/src/mcp/previewExtractor.ts +166 -0
  330. package/src/mcp/server.ts +396 -0
  331. package/src/mcp/toolHandlers.ts +341 -0
  332. package/src/proxy/chunkStorage.ts +112 -0
  333. package/src/proxy/claudeCodeStrip.ts +99 -0
  334. package/src/proxy/config.ts +172 -0
  335. package/src/proxy/constants.ts +47 -0
  336. package/src/proxy/dataDir.ts +86 -0
  337. package/src/proxy/formats/anthropic/anthropicProvider.ts +75 -0
  338. package/src/proxy/formats/anthropic/handler.ts +71 -0
  339. package/src/proxy/formats/anthropic/index.ts +14 -0
  340. package/src/proxy/formats/anthropic/register.ts +4 -0
  341. package/src/proxy/formats/anthropic/schemas.ts +237 -0
  342. package/src/proxy/formats/anthropic/stream.ts +205 -0
  343. package/src/proxy/formats/handler.ts +46 -0
  344. package/src/proxy/formats/index.ts +12 -0
  345. package/src/proxy/formats/jsonSchema.ts +36 -0
  346. package/src/proxy/formats/openai/alibabaProvider.ts +38 -0
  347. package/src/proxy/formats/openai/handler.ts +96 -0
  348. package/src/proxy/formats/openai/index.ts +25 -0
  349. package/src/proxy/formats/openai/provider.ts +50 -0
  350. package/src/proxy/formats/openai/register.ts +4 -0
  351. package/src/proxy/formats/openai/schemas.ts +187 -0
  352. package/src/proxy/formats/openai/stream.ts +206 -0
  353. package/src/proxy/formats/protocol.ts +50 -0
  354. package/src/proxy/formats/providerRegistry.ts +51 -0
  355. package/src/proxy/formats/providers/index.ts +3 -0
  356. package/src/proxy/formats/registry.ts +66 -0
  357. package/src/proxy/handler.ts +334 -0
  358. package/src/proxy/logFinalizer.ts +305 -0
  359. package/src/proxy/logFinalizer.worker.ts +24 -0
  360. package/src/proxy/logIndex.ts +268 -0
  361. package/src/proxy/logger.ts +179 -0
  362. package/src/proxy/openaiOrphanToolStrip.ts +142 -0
  363. package/src/proxy/providerImporters.ts +491 -0
  364. package/src/proxy/providers.ts +613 -0
  365. package/src/proxy/schemas.ts +209 -0
  366. package/src/proxy/sessionProcess.ts +140 -0
  367. package/src/proxy/sessionRuntime.ts +85 -0
  368. package/src/proxy/sessionSupervisor.ts +283 -0
  369. package/src/proxy/sessionWorkerEntry.ts +26 -0
  370. package/src/proxy/socketTracker.ts +255 -0
  371. package/src/proxy/store.ts +412 -0
  372. package/src/proxy/upstream.ts +90 -0
  373. package/src/router.tsx +16 -0
  374. package/src/routes/__root.tsx +45 -0
  375. package/src/routes/api/config.paths.ts +14 -0
  376. package/src/routes/api/config.ts +53 -0
  377. package/src/routes/api/health.ts +15 -0
  378. package/src/routes/api/knowledge.candidates.$candidateId.promote.ts +32 -0
  379. package/src/routes/api/knowledge.candidates.ts +10 -0
  380. package/src/routes/api/knowledge.project-context.ts +18 -0
  381. package/src/routes/api/knowledge.search.ts +31 -0
  382. package/src/routes/api/knowledge.sessions.$sessionId.candidates.ts +16 -0
  383. package/src/routes/api/logs.$id.chunks.ts +36 -0
  384. package/src/routes/api/logs.$id.replay.ts +191 -0
  385. package/src/routes/api/logs.$id.ts +22 -0
  386. package/src/routes/api/logs.stream.ts +74 -0
  387. package/src/routes/api/logs.ts +59 -0
  388. package/src/routes/api/mcp.ts +25 -0
  389. package/src/routes/api/models.ts +10 -0
  390. package/src/routes/api/providers.$providerId.test.log.ts +293 -0
  391. package/src/routes/api/providers.$providerId.ts +50 -0
  392. package/src/routes/api/providers.export.ts +26 -0
  393. package/src/routes/api/providers.import.ts +47 -0
  394. package/src/routes/api/providers.scan.ts +23 -0
  395. package/src/routes/api/providers.ts +45 -0
  396. package/src/routes/api/sessions.ts +17 -0
  397. package/src/routes/index.tsx +6 -0
  398. package/src/routes/proxy/$.ts +15 -0
  399. package/src/routes/session/$sessionId.tsx +23 -0
  400. package/styles/globals.css +188 -0
@@ -0,0 +1,543 @@
1
+ import { GitCompareArrows } from "lucide-react";
2
+ import { Suspense, type JSX } from "react";
3
+ import { useMemo, useRef, useState, memo } from "react";
4
+ import type { CapturedLog } from "../../proxy/schemas";
5
+ import { stripClaudeCodeBillingHeader } from "../../proxy/claudeCodeStrip";
6
+ import { Button } from "../ui/button";
7
+ import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "../ui/tooltip";
8
+ import { useJsonBulkExpansion } from "../ui/json-viewer-bulk";
9
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/tabs";
10
+ import { useCopyFeedback } from "./useCopyFeedback";
11
+ import type { HeaderTabActions } from "./LogEntryHeader";
12
+ import {
13
+ LazyJsonViewer,
14
+ LazyJsonViewerFromString,
15
+ LazyReplayDialog,
16
+ LazyRequestAnatomy,
17
+ LazyResponseView,
18
+ LazyStreamingChunkSequence,
19
+ } from "./lazy";
20
+ import type { AnatomySegment } from "./anatomy/types";
21
+ import { useAnatomyJump } from "./anatomy/useAnatomyJump";
22
+ import { computeHeadersDiff, computeRequestDiff, DiffView } from "./diff";
23
+ import { LogEntryHeader } from "./LogEntryHeader";
24
+ import type { CacheTrendEntry } from "./cacheTrend";
25
+ import { getLogFormatAdapter, resolveLogFormat } from "./log-formats";
26
+ import {
27
+ shouldShowHeadersDiffButton,
28
+ shouldShowRawRequestTab,
29
+ shouldShowRequestDiffButton,
30
+ } from "./logEntryVisibility";
31
+
32
+ /**
33
+ * Lightweight fallback for lazy-loaded tabs. Renders an empty 1px-tall row so
34
+ * the layout doesn't jump while the chunk is fetching.
35
+ */
36
+ function TabFallback(): JSX.Element {
37
+ return <div className="h-1" aria-hidden="true" />;
38
+ }
39
+
40
+ export type LogEntryProps = {
41
+ log: CapturedLog;
42
+ viewMode?: "simple" | "full";
43
+ /** Live "strip Claude Code billing header" flag, sourced once at the viewer
44
+ * container. Hoisted out of `LogEntry` so a single SWR subscription serves
45
+ * the whole virtualized list (N logs == N subscriptions is the previous
46
+ * cost).
47
+ */
48
+ strip: boolean;
49
+ /** Slow-response threshold in seconds. `0` disables the warning indicator. */
50
+ slowResponseThresholdSeconds: number;
51
+ /**
52
+ * Per-log cache token trend, looked up in the viewer-level trend map.
53
+ * `null` (or absent) means the header should render with no arrows.
54
+ */
55
+ cacheTrend?: CacheTrendEntry | null;
56
+ /** Callback to open CompareDrawer with this log and its immediate predecessor. */
57
+ onCompareWithPrevious?: (log: CapturedLog) => void;
58
+ };
59
+
60
+ function DiffToggleButton({
61
+ active,
62
+ onClick,
63
+ }: {
64
+ active: boolean;
65
+ onClick: (e: React.MouseEvent) => void;
66
+ }): JSX.Element {
67
+ return (
68
+ <Tooltip>
69
+ <TooltipTrigger asChild>
70
+ <Button
71
+ variant={active ? "default" : "outline"}
72
+ size="sm"
73
+ className="h-8 text-xs"
74
+ onClick={onClick}
75
+ aria-pressed={active}
76
+ >
77
+ <GitCompareArrows className="size-3.5 mr-1" />
78
+ {active ? "Showing diff" : "Diff with Raw"}
79
+ </Button>
80
+ </TooltipTrigger>
81
+ <TooltipContent>
82
+ {active ? "Hide diff view" : "Compare proxy output against the original raw version"}
83
+ </TooltipContent>
84
+ </Tooltip>
85
+ );
86
+ }
87
+
88
+ const RequestDiffContent = memo(function ({
89
+ rawBody,
90
+ displayedBody,
91
+ emptyLabel,
92
+ }: {
93
+ rawBody: string | null;
94
+ displayedBody: string | null;
95
+ emptyLabel: string;
96
+ }): JSX.Element {
97
+ const result = useMemo(
98
+ () => computeRequestDiff(rawBody, displayedBody),
99
+ [rawBody, displayedBody],
100
+ );
101
+ return <DiffView result={result} emptyLabel={emptyLabel} />;
102
+ });
103
+
104
+ const HeadersDiffContent = memo(function ({
105
+ rawHeaders,
106
+ headers,
107
+ emptyLabel,
108
+ }: {
109
+ rawHeaders: Record<string, string> | undefined;
110
+ headers: Record<string, string> | undefined;
111
+ emptyLabel: string;
112
+ }): JSX.Element {
113
+ const result = useMemo(() => computeHeadersDiff(rawHeaders, headers), [rawHeaders, headers]);
114
+ return <DiffView result={result} emptyLabel={emptyLabel} />;
115
+ });
116
+
117
+ export const LogEntry = memo(function ({
118
+ log,
119
+ viewMode = "simple",
120
+ strip,
121
+ slowResponseThresholdSeconds,
122
+ cacheTrend = null,
123
+ onCompareWithPrevious,
124
+ }: LogEntryProps): JSX.Element {
125
+ const [expanded, setExpanded] = useState<boolean>(false);
126
+ const [replayOpen, setReplayOpen] = useState<boolean>(false);
127
+ const [headersDiff, setHeadersDiff] = useState<boolean>(false);
128
+ const [requestDiff, setRequestDiff] = useState<boolean>(false);
129
+ const [activeTab, setActiveTab] = useState("request");
130
+ const [expandToPath, setExpandToPath] = useState<string | null>(null);
131
+ const requestJsonRef = useRef<HTMLDivElement | null>(null);
132
+ const resolvedFormat = resolveLogFormat(log);
133
+ const adapter = getLogFormatAdapter(resolvedFormat);
134
+ const requestAnalysis = useMemo(
135
+ () => adapter.analyzeRequest(log.rawRequestBody),
136
+ [adapter, log.rawRequestBody],
137
+ );
138
+ const responseAnalysis = useMemo(
139
+ () => adapter.analyzeResponse(log.responseText),
140
+ [adapter, log.responseText],
141
+ );
142
+ const strippedRequestBody = useMemo(() => {
143
+ if (!strip || resolvedFormat !== "anthropic" || log.rawRequestBody === null) {
144
+ return null;
145
+ }
146
+ return stripClaudeCodeBillingHeader(log.rawRequestBody).body;
147
+ }, [log.rawRequestBody, resolvedFormat, strip]);
148
+ const displayedRequestBody = strippedRequestBody ?? log.rawRequestBody;
149
+ const requestExpansion = useJsonBulkExpansion(displayedRequestBody);
150
+ const rawRequestExpansion = useJsonBulkExpansion(log.rawRequestBody);
151
+ const responseExpansion = useJsonBulkExpansion(log.responseText);
152
+
153
+ // Headers are rendered as a flat list, so we copy them as pretty-printed JSON.
154
+ // Only build the string when there's at least one entry — empty headers would
155
+ // otherwise copy "{}", which is misleading.
156
+ const headersText = useMemo(
157
+ () =>
158
+ log.headers && Object.keys(log.headers).length > 0
159
+ ? JSON.stringify(log.headers, null, 2)
160
+ : null,
161
+ [log.headers],
162
+ );
163
+ const rawHeadersText = useMemo(
164
+ () =>
165
+ log.rawHeaders && Object.keys(log.rawHeaders).length > 0
166
+ ? JSON.stringify(log.rawHeaders, null, 2)
167
+ : null,
168
+ [log.rawHeaders],
169
+ );
170
+
171
+ // One copy-feedback hook per JSON-bearing tab, so each tab can surface its
172
+ // own Copy button in the header with independent "Copied!" feedback.
173
+ const requestCopy = useCopyFeedback(displayedRequestBody);
174
+ const rawRequestCopy = useCopyFeedback(log.rawRequestBody);
175
+ const headersCopy = useCopyFeedback(headersText);
176
+ const rawHeadersCopy = useCopyFeedback(rawHeadersText);
177
+ const responseCopy = useCopyFeedback(log.responseText);
178
+
179
+ // Per-tab action bundles consumed by the header. The header renders the
180
+ // entry whose key matches `activeTab`. Tabs without an entry (Anatomy,
181
+ // Parsed Response) render no header buttons.
182
+ const tabActions: HeaderTabActions = useMemo(
183
+ () => ({
184
+ request: {
185
+ copyLabel: "Copy request body",
186
+ copyText: displayedRequestBody,
187
+ copyCopied: requestCopy.copied,
188
+ onCopy: requestCopy.copy,
189
+ expansion: {
190
+ isExpanded: requestExpansion.isExpanded,
191
+ isPending: requestExpansion.isPending,
192
+ onToggle: requestExpansion.toggle,
193
+ },
194
+ // "Diff with Raw" only makes sense when there's a raw body to compare
195
+ // against (Anthropic + strip pipeline produces one). "Diff with
196
+ // Previous" only exists when the parent wired up the compare drawer.
197
+ diffWithRaw: shouldShowRequestDiffButton(
198
+ resolvedFormat,
199
+ viewMode,
200
+ strip,
201
+ log.rawRequestBody !== null,
202
+ )
203
+ ? { active: requestDiff, onToggle: () => setRequestDiff(!requestDiff) }
204
+ : undefined,
205
+ diffWithPrevious:
206
+ onCompareWithPrevious === undefined
207
+ ? undefined
208
+ : () => {
209
+ onCompareWithPrevious(log);
210
+ },
211
+ },
212
+ "raw-request": {
213
+ copyLabel: "Copy raw request",
214
+ copyText: log.rawRequestBody,
215
+ copyCopied: rawRequestCopy.copied,
216
+ onCopy: rawRequestCopy.copy,
217
+ expansion: {
218
+ isExpanded: rawRequestExpansion.isExpanded,
219
+ isPending: rawRequestExpansion.isPending,
220
+ onToggle: rawRequestExpansion.toggle,
221
+ },
222
+ },
223
+ headers: {
224
+ copyLabel: "Copy headers",
225
+ copyText: headersText,
226
+ copyCopied: headersCopy.copied,
227
+ onCopy: headersCopy.copy,
228
+ // Headers are a flat dict, no JSON tree to expand.
229
+ expansion: null,
230
+ },
231
+ "raw-headers": {
232
+ copyLabel: "Copy raw headers",
233
+ copyText: rawHeadersText,
234
+ copyCopied: rawHeadersCopy.copied,
235
+ onCopy: rawHeadersCopy.copy,
236
+ expansion: null,
237
+ },
238
+ raw: {
239
+ copyLabel: "Copy response",
240
+ copyText: log.responseText,
241
+ copyCopied: responseCopy.copied,
242
+ onCopy: responseCopy.copy,
243
+ expansion: {
244
+ isExpanded: responseExpansion.isExpanded,
245
+ isPending: responseExpansion.isPending,
246
+ onToggle: responseExpansion.toggle,
247
+ },
248
+ },
249
+ }),
250
+ [
251
+ displayedRequestBody,
252
+ requestCopy,
253
+ requestExpansion,
254
+ requestDiff,
255
+ log.rawRequestBody,
256
+ rawRequestCopy,
257
+ rawRequestExpansion,
258
+ headersText,
259
+ headersCopy,
260
+ rawHeadersText,
261
+ rawHeadersCopy,
262
+ log.responseText,
263
+ responseCopy,
264
+ responseExpansion,
265
+ resolvedFormat,
266
+ viewMode,
267
+ strip,
268
+ onCompareWithPrevious,
269
+ ],
270
+ );
271
+ const anatomySegments = useMemo(
272
+ () =>
273
+ requestExpansion.parsedData !== null
274
+ ? adapter.anatomySegments(requestExpansion.parsedData)
275
+ : null,
276
+ [adapter, requestExpansion.parsedData],
277
+ );
278
+ const anatomyPaths = useMemo(() => {
279
+ if (anatomySegments === null) return undefined;
280
+ return new Set(anatomySegments.map((s) => s.path));
281
+ }, [anatomySegments]);
282
+ const jumpToAnatomySegment = useAnatomyJump({
283
+ containerRef: requestJsonRef,
284
+ setExpandToPath,
285
+ ensureTabActive: () => {
286
+ if (activeTab !== "request") setActiveTab("request");
287
+ },
288
+ });
289
+
290
+ return (
291
+ <TooltipProvider>
292
+ <div className="border border-border rounded-lg mb-1 overflow-hidden">
293
+ <LogEntryHeader
294
+ log={log}
295
+ messageCount={requestAnalysis.messageCount}
296
+ toolCount={requestAnalysis.toolCount}
297
+ expanded={expanded}
298
+ onToggle={() => setExpanded(!expanded)}
299
+ responseToolNames={responseAnalysis.toolNames}
300
+ cacheTrend={cacheTrend}
301
+ slowResponseThresholdSeconds={slowResponseThresholdSeconds}
302
+ activeTab={activeTab}
303
+ tabActions={tabActions}
304
+ onReplay={
305
+ onCompareWithPrevious === undefined
306
+ ? undefined
307
+ : () => {
308
+ setReplayOpen(true);
309
+ }
310
+ }
311
+ />
312
+
313
+ {expanded && (
314
+ <div onClick={(e) => e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}>
315
+ <Tabs value={activeTab} onValueChange={setActiveTab}>
316
+ <TabsList className="mx-4 mt-2">
317
+ {viewMode === "full" && <TabsTrigger value="raw-headers">Raw Headers</TabsTrigger>}
318
+ {viewMode === "full" && <TabsTrigger value="headers">Headers</TabsTrigger>}
319
+ {shouldShowRawRequestTab(resolvedFormat, viewMode, strip) && (
320
+ <TabsTrigger value="raw-request">Raw Request</TabsTrigger>
321
+ )}
322
+ <TabsTrigger value="request">Request</TabsTrigger>
323
+ {anatomySegments !== null && <TabsTrigger value="anatomy">Anatomy</TabsTrigger>}
324
+ {viewMode === "full" && <TabsTrigger value="raw">Raw Response</TabsTrigger>}
325
+ <TabsTrigger value="parsed">Response</TabsTrigger>
326
+ </TabsList>
327
+
328
+ {shouldShowRawRequestTab(resolvedFormat, viewMode, strip) && (
329
+ <TabsContent value="raw-request">
330
+ {activeTab === "raw-request" && (
331
+ <div className="px-4 pt-1 pb-3">
332
+ {log.rawRequestBody === null ? (
333
+ <p className="text-xs text-muted-foreground italic">No request body</p>
334
+ ) : rawRequestExpansion.parsedData !== null ? (
335
+ <Suspense fallback={<TabFallback />}>
336
+ <LazyJsonViewer
337
+ data={rawRequestExpansion.parsedData}
338
+ bulkDepth={rawRequestExpansion.bulkDepth}
339
+ bulkRevision={rawRequestExpansion.bulkRevision}
340
+ />
341
+ </Suspense>
342
+ ) : (
343
+ <pre className="font-mono text-xs whitespace-pre-wrap break-words">
344
+ {log.rawRequestBody}
345
+ </pre>
346
+ )}
347
+ </div>
348
+ )}
349
+ </TabsContent>
350
+ )}
351
+
352
+ <TabsContent value="request">
353
+ {activeTab === "request" && (
354
+ <div className="px-4 pt-1 pb-3">
355
+ {/* All tab actions (Copy, Expand, Diff with Raw, Diff with
356
+ Previous) live in the log header. The body is just
357
+ the diff or JSON view, depending on toggle state. */}
358
+ {requestDiff ? (
359
+ <RequestDiffContent
360
+ rawBody={log.rawRequestBody}
361
+ displayedBody={displayedRequestBody}
362
+ emptyLabel="No transformation applied — raw and sent request bodies are identical."
363
+ />
364
+ ) : (
365
+ <div ref={requestJsonRef}>
366
+ {displayedRequestBody === null ? (
367
+ <p className="text-xs text-muted-foreground italic">No request body</p>
368
+ ) : requestExpansion.parsedData !== null ? (
369
+ <Suspense fallback={<TabFallback />}>
370
+ <LazyJsonViewer
371
+ data={requestExpansion.parsedData}
372
+ bulkDepth={requestExpansion.bulkDepth}
373
+ bulkRevision={requestExpansion.bulkRevision}
374
+ anatomyPaths={anatomyPaths}
375
+ expandToPath={expandToPath}
376
+ />
377
+ </Suspense>
378
+ ) : (
379
+ <pre className="font-mono text-xs whitespace-pre-wrap break-words">
380
+ {displayedRequestBody}
381
+ </pre>
382
+ )}
383
+ </div>
384
+ )}
385
+ </div>
386
+ )}
387
+ </TabsContent>
388
+
389
+ {anatomySegments !== null && (
390
+ <TabsContent value="anatomy">
391
+ {activeTab === "anatomy" && (
392
+ <Suspense fallback={<TabFallback />}>
393
+ <LazyRequestAnatomy
394
+ parsed={null}
395
+ inputTokens={log.inputTokens ?? null}
396
+ segments={anatomySegments}
397
+ onSegmentActivate={jumpToAnatomySegment}
398
+ />
399
+ </Suspense>
400
+ )}
401
+ </TabsContent>
402
+ )}
403
+
404
+ {viewMode === "full" && (
405
+ <TabsContent value="headers">
406
+ {activeTab === "headers" && (
407
+ <div className="px-4 pt-1 pb-3">
408
+ {/* Copy lives in the log header. */}
409
+ <div className="flex justify-end gap-2 mb-2">
410
+ {shouldShowHeadersDiffButton(
411
+ viewMode,
412
+ log.rawHeaders !== undefined && Object.keys(log.rawHeaders).length > 0,
413
+ ) && (
414
+ <DiffToggleButton
415
+ active={headersDiff}
416
+ onClick={(e) => {
417
+ e.stopPropagation();
418
+ setHeadersDiff(!headersDiff);
419
+ }}
420
+ />
421
+ )}
422
+ </div>
423
+ {headersDiff ? (
424
+ <HeadersDiffContent
425
+ rawHeaders={log.rawHeaders}
426
+ headers={log.headers}
427
+ emptyLabel="No transformation applied — raw and processed headers are identical."
428
+ />
429
+ ) : log.headers && Object.keys(log.headers).length > 0 ? (
430
+ <div className="space-y-1 font-mono text-xs">
431
+ {Object.entries(log.headers)
432
+ .sort(([a], [b]) => a.localeCompare(b))
433
+ .map(([key, value]) => (
434
+ <div key={key} className="flex gap-2">
435
+ <span className="text-blue-600 dark:text-blue-400 font-semibold shrink-0">
436
+ {key}:
437
+ </span>
438
+ <span className="text-muted-foreground truncate" title={value}>
439
+ {value}
440
+ </span>
441
+ </div>
442
+ ))}
443
+ </div>
444
+ ) : (
445
+ <p className="text-xs text-muted-foreground italic">No headers captured</p>
446
+ )}
447
+ </div>
448
+ )}
449
+ </TabsContent>
450
+ )}
451
+
452
+ {viewMode === "full" && (
453
+ <TabsContent value="raw-headers">
454
+ {activeTab === "raw-headers" && (
455
+ <div className="px-4 pt-1 pb-3">
456
+ {/* Copy lives in the log header. */}
457
+ {log.rawHeaders && Object.keys(log.rawHeaders).length > 0 ? (
458
+ <div className="space-y-1 font-mono text-xs">
459
+ {Object.entries(log.rawHeaders)
460
+ .sort(([a], [b]) => a.localeCompare(b))
461
+ .map(([key, value]) => (
462
+ <div key={key} className="flex gap-2">
463
+ <span className="text-blue-600 dark:text-blue-400 font-semibold shrink-0">
464
+ {key}:
465
+ </span>
466
+ <span className="text-muted-foreground truncate" title={value}>
467
+ {value}
468
+ </span>
469
+ </div>
470
+ ))}
471
+ </div>
472
+ ) : (
473
+ <p className="text-xs text-muted-foreground italic">
474
+ No raw headers captured
475
+ </p>
476
+ )}
477
+ </div>
478
+ )}
479
+ </TabsContent>
480
+ )}
481
+
482
+ <TabsContent value="raw">
483
+ {activeTab === "raw" && (
484
+ <div className="px-4 pt-1 pb-3 space-y-3">
485
+ {log.error !== undefined && log.error !== null && (
486
+ <div className="rounded border border-destructive/50 bg-destructive/10 p-3 text-xs">
487
+ <div className="font-semibold text-destructive mb-1">SSE Error</div>
488
+ <div className="text-muted-foreground font-mono">{log.error}</div>
489
+ </div>
490
+ )}
491
+ {log.responseText !== null ? (
492
+ <Suspense fallback={<TabFallback />}>
493
+ <LazyJsonViewerFromString
494
+ text={log.responseText}
495
+ defaultExpandDepth={0}
496
+ bulkDepth={responseExpansion.bulkDepth}
497
+ bulkRevision={responseExpansion.bulkRevision}
498
+ />
499
+ </Suspense>
500
+ ) : (
501
+ <p className="text-xs text-muted-foreground italic">No response</p>
502
+ )}
503
+ {log.streaming === true && (
504
+ <Suspense fallback={<TabFallback />}>
505
+ <LazyStreamingChunkSequence
506
+ logId={log.id}
507
+ truncated={log.streamingChunksPath !== null}
508
+ />
509
+ </Suspense>
510
+ )}
511
+ </div>
512
+ )}
513
+ </TabsContent>
514
+
515
+ <TabsContent value="parsed">
516
+ {activeTab === "parsed" && (
517
+ <div className="px-4 pt-1 pb-3">
518
+ <Suspense fallback={<TabFallback />}>
519
+ <LazyResponseView
520
+ responseText={log.responseText}
521
+ responseStatus={log.responseStatus}
522
+ streaming={log.streaming}
523
+ inputTokens={log.inputTokens}
524
+ outputTokens={log.outputTokens}
525
+ cacheCreationInputTokens={log.cacheCreationInputTokens}
526
+ cacheReadInputTokens={log.cacheReadInputTokens}
527
+ apiFormat={resolvedFormat}
528
+ error={log.error}
529
+ />
530
+ </Suspense>
531
+ </div>
532
+ )}
533
+ </TabsContent>
534
+ </Tabs>
535
+ </div>
536
+ )}
537
+ </div>
538
+ <Suspense fallback={null}>
539
+ <LazyReplayDialog log={log} open={replayOpen} onOpenChange={setReplayOpen} />
540
+ </Suspense>
541
+ </TooltipProvider>
542
+ );
543
+ });