@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.
- package/.output/cli.js +1611 -0
- package/.output/nitro.json +17 -0
- package/.output/public/assets/CompareDrawer-CU5ZrWcL.js +1 -0
- package/.output/public/assets/ProxyViewerContainer-pEBqVp1d.js +101 -0
- package/.output/public/assets/ReplayDialog-F58yNg5j.js +1 -0
- package/.output/public/assets/RequestAnatomy-C9lT0qE_.js +1 -0
- package/.output/public/assets/ResponseView-DHJq6bnz.js +1 -0
- package/.output/public/assets/StreamingChunkSequence-BTgfpFUT.js +1 -0
- package/.output/public/assets/_sessionId-DsNRbnNm.js +1 -0
- package/.output/public/assets/alibaba-TTwafVwX.svg +1 -0
- package/.output/public/assets/index-CpWG2hFn.css +1 -0
- package/.output/public/assets/index-DmBV8Gve.js +1 -0
- package/.output/public/assets/json-viewer-CZVYLR8j.js +14 -0
- package/.output/public/assets/main-DHs7FBK3.js +18 -0
- package/.output/public/assets/minimax-BPMzvuL-.jpeg +0 -0
- package/.output/public/assets/qwen-CONDcHqt.png +0 -0
- package/.output/public/assets/zhipuai-BPNAnxo-.svg +219 -0
- package/.output/server/_chunks/ssr-renderer.mjs +22 -0
- package/.output/server/_libs/@radix-ui/react-accessible-icon+[...].mjs +1 -0
- package/.output/server/_libs/@radix-ui/react-dismissable-layer+[...].mjs +210 -0
- package/.output/server/_libs/@radix-ui/react-navigation-menu+[...].mjs +2 -0
- package/.output/server/_libs/@radix-ui/react-one-time-password-field+[...].mjs +2 -0
- package/.output/server/_libs/@radix-ui/react-password-toggle-field+[...].mjs +2 -0
- package/.output/server/_libs/@radix-ui/react-use-callback-ref+[...].mjs +11 -0
- package/.output/server/_libs/@radix-ui/react-use-controllable-state+[...].mjs +69 -0
- package/.output/server/_libs/@radix-ui/react-use-effect-event+[...].mjs +1 -0
- package/.output/server/_libs/@radix-ui/react-use-escape-keydown+[...].mjs +17 -0
- package/.output/server/_libs/@radix-ui/react-use-is-hydrated+[...].mjs +1 -0
- package/.output/server/_libs/@radix-ui/react-use-layout-effect+[...].mjs +6 -0
- package/.output/server/_libs/@radix-ui/react-visually-hidden+[...].mjs +34 -0
- package/.output/server/_libs/ajv-formats.mjs +330 -0
- package/.output/server/_libs/ajv.mjs +11444 -0
- package/.output/server/_libs/aria-hidden.mjs +122 -0
- package/.output/server/_libs/atomically.mjs +152 -0
- package/.output/server/_libs/bail.mjs +8 -0
- package/.output/server/_libs/cfworker__json-schema.mjs +1 -0
- package/.output/server/_libs/character-entities.mjs +2130 -0
- package/.output/server/_libs/class-variance-authority.mjs +44 -0
- package/.output/server/_libs/clsx.mjs +16 -0
- package/.output/server/_libs/comma-separated-tokens.mjs +10 -0
- package/.output/server/_libs/conf.mjs +635 -0
- package/.output/server/_libs/cookie-es.mjs +58 -0
- package/.output/server/_libs/core-util-is.mjs +75 -0
- package/.output/server/_libs/croner.mjs +1 -0
- package/.output/server/_libs/crossws.mjs +1 -0
- package/.output/server/_libs/debounce-fn.mjs +69 -0
- package/.output/server/_libs/decode-named-character-reference+[...].mjs +8 -0
- package/.output/server/_libs/dequal.mjs +27 -0
- package/.output/server/_libs/detect-node-es.mjs +1 -0
- package/.output/server/_libs/devlop.mjs +8 -0
- package/.output/server/_libs/diff.mjs +320 -0
- package/.output/server/_libs/dot-prop.mjs +265 -0
- package/.output/server/_libs/env-paths.mjs +57 -0
- package/.output/server/_libs/estree-util-is-identifier-name.mjs +11 -0
- package/.output/server/_libs/extend.mjs +97 -0
- package/.output/server/_libs/fast-deep-equal.mjs +38 -0
- package/.output/server/_libs/fast-uri.mjs +812 -0
- package/.output/server/_libs/floating-ui__core.mjs +725 -0
- package/.output/server/_libs/floating-ui__dom.mjs +622 -0
- package/.output/server/_libs/floating-ui__react-dom.mjs +292 -0
- package/.output/server/_libs/floating-ui__utils.mjs +320 -0
- package/.output/server/_libs/get-nonce.mjs +9 -0
- package/.output/server/_libs/h3-v2.mjs +276 -0
- package/.output/server/_libs/h3.mjs +408 -0
- package/.output/server/_libs/hast-util-to-jsx-runtime.mjs +388 -0
- package/.output/server/_libs/hast-util-whitespace.mjs +10 -0
- package/.output/server/_libs/hookable.mjs +1 -0
- package/.output/server/_libs/html-url-attributes.mjs +26 -0
- package/.output/server/_libs/immediate.mjs +74 -0
- package/.output/server/_libs/inherits.mjs +50 -0
- package/.output/server/_libs/inline-style-parser.mjs +142 -0
- package/.output/server/_libs/is-plain-obj.mjs +10 -0
- package/.output/server/_libs/isarray.mjs +14 -0
- package/.output/server/_libs/isbot.mjs +20 -0
- package/.output/server/_libs/json-schema-traverse.mjs +180 -0
- package/.output/server/_libs/jszip.mjs +3051 -0
- package/.output/server/_libs/lie.mjs +273 -0
- package/.output/server/_libs/lucide-react.mjs +492 -0
- package/.output/server/_libs/mdast-util-from-markdown.mjs +717 -0
- package/.output/server/_libs/mdast-util-to-hast.mjs +710 -0
- package/.output/server/_libs/mdast-util-to-string.mjs +38 -0
- package/.output/server/_libs/micromark-core-commonmark.mjs +2259 -0
- package/.output/server/_libs/micromark-factory-destination.mjs +94 -0
- package/.output/server/_libs/micromark-factory-label.mjs +63 -0
- package/.output/server/_libs/micromark-factory-space.mjs +24 -0
- package/.output/server/_libs/micromark-factory-title.mjs +65 -0
- package/.output/server/_libs/micromark-factory-whitespace.mjs +22 -0
- package/.output/server/_libs/micromark-util-character.mjs +44 -0
- package/.output/server/_libs/micromark-util-chunked.mjs +36 -0
- package/.output/server/_libs/micromark-util-classify-character+[...].mjs +12 -0
- package/.output/server/_libs/micromark-util-combine-extensions+[...].mjs +41 -0
- package/.output/server/_libs/micromark-util-decode-numeric-character-reference+[...].mjs +19 -0
- package/.output/server/_libs/micromark-util-decode-string.mjs +21 -0
- package/.output/server/_libs/micromark-util-encode.mjs +1 -0
- package/.output/server/_libs/micromark-util-html-tag-name.mjs +69 -0
- package/.output/server/_libs/micromark-util-normalize-identifier+[...].mjs +6 -0
- package/.output/server/_libs/micromark-util-resolve-all.mjs +15 -0
- package/.output/server/_libs/micromark-util-sanitize-uri.mjs +41 -0
- package/.output/server/_libs/micromark-util-subtokenize.mjs +346 -0
- package/.output/server/_libs/micromark.mjs +906 -0
- package/.output/server/_libs/mimic-function.mjs +47 -0
- package/.output/server/_libs/modelcontextprotocol__server.mjs +9738 -0
- package/.output/server/_libs/ocache.mjs +1 -0
- package/.output/server/_libs/ohash.mjs +1 -0
- package/.output/server/_libs/pako.mjs +4223 -0
- package/.output/server/_libs/process-nextick-args.mjs +48 -0
- package/.output/server/_libs/property-information.mjs +1209 -0
- package/.output/server/_libs/radix-ui.mjs +1 -0
- package/.output/server/_libs/radix-ui__number.mjs +6 -0
- package/.output/server/_libs/radix-ui__primitive.mjs +11 -0
- package/.output/server/_libs/radix-ui__react-accordion.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-alert-dialog.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-arrow.mjs +23 -0
- package/.output/server/_libs/radix-ui__react-aspect-ratio.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-avatar.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-checkbox.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-collapsible.mjs +144 -0
- package/.output/server/_libs/radix-ui__react-collection.mjs +69 -0
- package/.output/server/_libs/radix-ui__react-compose-refs.mjs +39 -0
- package/.output/server/_libs/radix-ui__react-context-menu.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-context.mjs +78 -0
- package/.output/server/_libs/radix-ui__react-dialog.mjs +325 -0
- package/.output/server/_libs/radix-ui__react-direction.mjs +9 -0
- package/.output/server/_libs/radix-ui__react-dropdown-menu.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-focus-guards.mjs +29 -0
- package/.output/server/_libs/radix-ui__react-focus-scope.mjs +206 -0
- package/.output/server/_libs/radix-ui__react-form.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-hover-card.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-id.mjs +14 -0
- package/.output/server/_libs/radix-ui__react-label.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-menu.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-menubar.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-popover.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-popper.mjs +286 -0
- package/.output/server/_libs/radix-ui__react-portal.mjs +16 -0
- package/.output/server/_libs/radix-ui__react-presence.mjs +128 -0
- package/.output/server/_libs/radix-ui__react-primitive.mjs +42 -0
- package/.output/server/_libs/radix-ui__react-progress.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-radio-group.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-roving-focus.mjs +224 -0
- package/.output/server/_libs/radix-ui__react-scroll-area.mjs +721 -0
- package/.output/server/_libs/radix-ui__react-select.mjs +1163 -0
- package/.output/server/_libs/radix-ui__react-separator.mjs +28 -0
- package/.output/server/_libs/radix-ui__react-slider.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-slot.mjs +99 -0
- package/.output/server/_libs/radix-ui__react-switch.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-tabs.mjs +189 -0
- package/.output/server/_libs/radix-ui__react-toast.mjs +2 -0
- package/.output/server/_libs/radix-ui__react-toggle-group.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-toggle.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-toolbar.mjs +1 -0
- package/.output/server/_libs/radix-ui__react-tooltip.mjs +495 -0
- package/.output/server/_libs/radix-ui__react-use-previous.mjs +14 -0
- package/.output/server/_libs/radix-ui__react-use-size.mjs +39 -0
- package/.output/server/_libs/react-dom.mjs +10781 -0
- package/.output/server/_libs/react-markdown.mjs +147 -0
- package/.output/server/_libs/react-remove-scroll-bar.mjs +82 -0
- package/.output/server/_libs/react-remove-scroll.mjs +328 -0
- package/.output/server/_libs/react-style-singleton.mjs +69 -0
- package/.output/server/_libs/react.mjs +515 -0
- package/.output/server/_libs/readable-stream.mjs +1518 -0
- package/.output/server/_libs/remark-parse.mjs +19 -0
- package/.output/server/_libs/remark-rehype.mjs +21 -0
- package/.output/server/_libs/rou3.mjs +14 -0
- package/.output/server/_libs/safe-buffer.mjs +64 -0
- package/.output/server/_libs/semver.mjs +1938 -0
- package/.output/server/_libs/seroval-plugins.mjs +58 -0
- package/.output/server/_libs/seroval.mjs +1765 -0
- package/.output/server/_libs/setimmediate.mjs +152 -0
- package/.output/server/_libs/space-separated-tokens.mjs +6 -0
- package/.output/server/_libs/srvx.mjs +1029 -0
- package/.output/server/_libs/stubborn-fs.mjs +91 -0
- package/.output/server/_libs/stubborn-utils.mjs +66 -0
- package/.output/server/_libs/style-to-js.mjs +72 -0
- package/.output/server/_libs/style-to-object.mjs +38 -0
- package/.output/server/_libs/swr.mjs +939 -0
- package/.output/server/_libs/tailwind-merge.mjs +3010 -0
- package/.output/server/_libs/tanstack__history.mjs +217 -0
- package/.output/server/_libs/tanstack__react-router.mjs +1480 -0
- package/.output/server/_libs/tanstack__react-store.mjs +1 -0
- package/.output/server/_libs/tanstack__react-virtual.mjs +44 -0
- package/.output/server/_libs/tanstack__router-core.mjs +4827 -0
- package/.output/server/_libs/tanstack__store.mjs +1 -0
- package/.output/server/_libs/tanstack__virtual-core.mjs +1225 -0
- package/.output/server/_libs/tiny-invariant.mjs +12 -0
- package/.output/server/_libs/tiny-warning.mjs +5 -0
- package/.output/server/_libs/trim-lines.mjs +41 -0
- package/.output/server/_libs/trough.mjs +85 -0
- package/.output/server/_libs/tslib.mjs +1 -0
- package/.output/server/_libs/ufo.mjs +54 -0
- package/.output/server/_libs/uint8array-extras.mjs +69 -0
- package/.output/server/_libs/ungap__structured-clone.mjs +212 -0
- package/.output/server/_libs/unified.mjs +661 -0
- package/.output/server/_libs/unist-util-is.mjs +100 -0
- package/.output/server/_libs/unist-util-position.mjs +27 -0
- package/.output/server/_libs/unist-util-stringify-position.mjs +27 -0
- package/.output/server/_libs/unist-util-visit-parents.mjs +82 -0
- package/.output/server/_libs/unist-util-visit.mjs +24 -0
- package/.output/server/_libs/unstorage.mjs +1 -0
- package/.output/server/_libs/use-callback-ref.mjs +66 -0
- package/.output/server/_libs/use-sidecar.mjs +106 -0
- package/.output/server/_libs/use-sync-external-store.mjs +64 -0
- package/.output/server/_libs/util-deprecate.mjs +12 -0
- package/.output/server/_libs/vfile-message.mjs +138 -0
- package/.output/server/_libs/vfile.mjs +467 -0
- package/.output/server/_libs/when-exit.mjs +53 -0
- package/.output/server/_libs/zod.mjs +4524 -0
- package/.output/server/_sessionId-wMLPvC5g.mjs +123 -0
- package/.output/server/_ssr/CompareDrawer-BU4V0uVf.mjs +1041 -0
- package/.output/server/_ssr/ProxyViewerContainer-BnRwFEnn.mjs +5972 -0
- package/.output/server/_ssr/ReplayDialog-C7dn9pd_.mjs +322 -0
- package/.output/server/_ssr/RequestAnatomy-C1rWpe9-.mjs +353 -0
- package/.output/server/_ssr/ResponseView-hGpPaYsf.mjs +602 -0
- package/.output/server/_ssr/StreamingChunkSequence-BRWI1r_G.mjs +302 -0
- package/.output/server/_ssr/index-BKURLVPz.mjs +118 -0
- package/.output/server/_ssr/index.mjs +1184 -0
- package/.output/server/_ssr/json-viewer-BBd2DtQP.mjs +515 -0
- package/.output/server/_ssr/router-BcZ0D6AB.mjs +6317 -0
- package/.output/server/_ssr/start-HYkvq4Ni.mjs +4 -0
- package/.output/server/_tanstack-start-manifest_v-1y8ZVxRI.mjs +4 -0
- package/.output/server/index.mjs +436 -0
- package/.output/server/node_modules/tslib/modules/index.js +70 -0
- package/.output/server/node_modules/tslib/modules/package.json +3 -0
- package/.output/server/node_modules/tslib/package.json +47 -0
- package/.output/server/node_modules/tslib/tslib.js +484 -0
- package/.output/server/package.json +9 -0
- package/LICENSE +21 -0
- package/README.md +52 -0
- package/package.json +110 -0
- package/src/assets/favicon.svg +31 -0
- package/src/assets/logos/alibaba.svg +1 -0
- package/src/assets/logos/anthropic.svg +1 -0
- package/src/assets/logos/claude-code.svg +4 -0
- package/src/assets/logos/deepseek.svg +1 -0
- package/src/assets/logos/mcp.png +0 -0
- package/src/assets/logos/minimax.jpeg +0 -0
- package/src/assets/logos/openai.svg +1 -0
- package/src/assets/logos/opencode.svg +4 -0
- package/src/assets/logos/qwen.png +0 -0
- package/src/assets/logos/zhipuai.svg +219 -0
- package/src/cli/detect-tools.ts +147 -0
- package/src/cli/doctor.ts +521 -0
- package/src/cli/onboard.ts +224 -0
- package/src/cli/templates/command-onboard.ts +17 -0
- package/src/cli/templates/skill-onboard.ts +547 -0
- package/src/cli.ts +345 -0
- package/src/components/OnboardingBanner.tsx +67 -0
- package/src/components/ProxyViewer.tsx +545 -0
- package/src/components/ProxyViewerContainer.tsx +363 -0
- package/src/components/providers/ImportWizardDialog.tsx +349 -0
- package/src/components/providers/ProviderCard.tsx +474 -0
- package/src/components/providers/ProviderForm.tsx +494 -0
- package/src/components/providers/ProviderLogo.tsx +117 -0
- package/src/components/providers/ProvidersPanel.tsx +619 -0
- package/src/components/providers/SettingsDialog.tsx +202 -0
- package/src/components/proxy-viewer/CompareDrawer.tsx +893 -0
- package/src/components/proxy-viewer/ConversationGroup.tsx +107 -0
- package/src/components/proxy-viewer/ConversationHeader.tsx +300 -0
- package/src/components/proxy-viewer/LogEntry.tsx +543 -0
- package/src/components/proxy-viewer/LogEntryHeader.tsx +501 -0
- package/src/components/proxy-viewer/ReplayDialog.tsx +218 -0
- package/src/components/proxy-viewer/ResponseView.tsx +171 -0
- package/src/components/proxy-viewer/StreamingChunkSequence.tsx +188 -0
- package/src/components/proxy-viewer/ThreadConnector.tsx +136 -0
- package/src/components/proxy-viewer/TurnGroup.tsx +337 -0
- package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +98 -0
- package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +196 -0
- package/src/components/proxy-viewer/anatomy/tokenEstimate.ts +53 -0
- package/src/components/proxy-viewer/anatomy/types.ts +39 -0
- package/src/components/proxy-viewer/anatomy/useAnatomyJump.ts +114 -0
- package/src/components/proxy-viewer/cacheTrend.ts +50 -0
- package/src/components/proxy-viewer/diff/DiffView.tsx +321 -0
- package/src/components/proxy-viewer/diff/computeDiff.ts +178 -0
- package/src/components/proxy-viewer/diff/index.ts +3 -0
- package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +157 -0
- package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +66 -0
- package/src/components/proxy-viewer/formats/anthropic/thinkingExtract.ts +21 -0
- package/src/components/proxy-viewer/formats/index.tsx +33 -0
- package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +170 -0
- package/src/components/proxy-viewer/index.ts +9 -0
- package/src/components/proxy-viewer/lazy.ts +37 -0
- package/src/components/proxy-viewer/log-formats/anthropic.ts +194 -0
- package/src/components/proxy-viewer/log-formats/index.ts +23 -0
- package/src/components/proxy-viewer/log-formats/openai.ts +167 -0
- package/src/components/proxy-viewer/log-formats/types.ts +40 -0
- package/src/components/proxy-viewer/log-formats/unknown.ts +18 -0
- package/src/components/proxy-viewer/logEntryVisibility.ts +39 -0
- package/src/components/proxy-viewer/requestDiff.ts +277 -0
- package/src/components/proxy-viewer/useCopyFeedback.ts +36 -0
- package/src/components/proxy-viewer/useKeyboardNavigation.ts +190 -0
- package/src/components/proxy-viewer/viewerState.ts +66 -0
- package/src/components/ui/badge.tsx +47 -0
- package/src/components/ui/button.tsx +47 -0
- package/src/components/ui/collapsible.tsx +21 -0
- package/src/components/ui/confirm-dialog.tsx +51 -0
- package/src/components/ui/crab-logo.tsx +95 -0
- package/src/components/ui/crab-variants.tsx +467 -0
- package/src/components/ui/dialog.tsx +129 -0
- package/src/components/ui/json-expansion-button.tsx +56 -0
- package/src/components/ui/json-viewer-bulk.ts +97 -0
- package/src/components/ui/json-viewer.tsx +494 -0
- package/src/components/ui/mcp-logo.tsx +20 -0
- package/src/components/ui/scroll-area.tsx +54 -0
- package/src/components/ui/select.tsx +178 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/tabs.tsx +88 -0
- package/src/components/ui/tooltip.tsx +51 -0
- package/src/index.css +11 -0
- package/src/knowledge/candidateStore.ts +63 -0
- package/src/knowledge/distiller.ts +98 -0
- package/src/knowledge/openclawClient.ts +118 -0
- package/src/knowledge/redactor.ts +80 -0
- package/src/knowledge/types.ts +84 -0
- package/src/lib/apiClient.ts +49 -0
- package/src/lib/export-logs.ts +51 -0
- package/src/lib/mask.ts +4 -0
- package/src/lib/objectUtils.ts +22 -0
- package/src/lib/providerContract.ts +26 -0
- package/src/lib/providerTestContract.ts +107 -0
- package/src/lib/runtimeConfig.ts +25 -0
- package/src/lib/serverPort.ts +41 -0
- package/src/lib/sessionUrl.ts +44 -0
- package/src/lib/stopReason.ts +58 -0
- package/src/lib/useOnboarding.ts +80 -0
- package/src/lib/useProviders.ts +30 -0
- package/src/lib/useStripConfig.ts +108 -0
- package/src/lib/utils.ts +21 -0
- package/src/mcp/loopback.ts +76 -0
- package/src/mcp/previewExtractor.ts +166 -0
- package/src/mcp/server.ts +396 -0
- package/src/mcp/toolHandlers.ts +341 -0
- package/src/proxy/chunkStorage.ts +112 -0
- package/src/proxy/claudeCodeStrip.ts +99 -0
- package/src/proxy/config.ts +172 -0
- package/src/proxy/constants.ts +47 -0
- package/src/proxy/dataDir.ts +86 -0
- package/src/proxy/formats/anthropic/anthropicProvider.ts +75 -0
- package/src/proxy/formats/anthropic/handler.ts +71 -0
- package/src/proxy/formats/anthropic/index.ts +14 -0
- package/src/proxy/formats/anthropic/register.ts +4 -0
- package/src/proxy/formats/anthropic/schemas.ts +237 -0
- package/src/proxy/formats/anthropic/stream.ts +205 -0
- package/src/proxy/formats/handler.ts +46 -0
- package/src/proxy/formats/index.ts +12 -0
- package/src/proxy/formats/jsonSchema.ts +36 -0
- package/src/proxy/formats/openai/alibabaProvider.ts +38 -0
- package/src/proxy/formats/openai/handler.ts +96 -0
- package/src/proxy/formats/openai/index.ts +25 -0
- package/src/proxy/formats/openai/provider.ts +50 -0
- package/src/proxy/formats/openai/register.ts +4 -0
- package/src/proxy/formats/openai/schemas.ts +187 -0
- package/src/proxy/formats/openai/stream.ts +206 -0
- package/src/proxy/formats/protocol.ts +50 -0
- package/src/proxy/formats/providerRegistry.ts +51 -0
- package/src/proxy/formats/providers/index.ts +3 -0
- package/src/proxy/formats/registry.ts +66 -0
- package/src/proxy/handler.ts +334 -0
- package/src/proxy/logFinalizer.ts +305 -0
- package/src/proxy/logFinalizer.worker.ts +24 -0
- package/src/proxy/logIndex.ts +268 -0
- package/src/proxy/logger.ts +179 -0
- package/src/proxy/openaiOrphanToolStrip.ts +142 -0
- package/src/proxy/providerImporters.ts +491 -0
- package/src/proxy/providers.ts +613 -0
- package/src/proxy/schemas.ts +209 -0
- package/src/proxy/sessionProcess.ts +140 -0
- package/src/proxy/sessionRuntime.ts +85 -0
- package/src/proxy/sessionSupervisor.ts +283 -0
- package/src/proxy/sessionWorkerEntry.ts +26 -0
- package/src/proxy/socketTracker.ts +255 -0
- package/src/proxy/store.ts +412 -0
- package/src/proxy/upstream.ts +90 -0
- package/src/router.tsx +16 -0
- package/src/routes/__root.tsx +45 -0
- package/src/routes/api/config.paths.ts +14 -0
- package/src/routes/api/config.ts +53 -0
- package/src/routes/api/health.ts +15 -0
- package/src/routes/api/knowledge.candidates.$candidateId.promote.ts +32 -0
- package/src/routes/api/knowledge.candidates.ts +10 -0
- package/src/routes/api/knowledge.project-context.ts +18 -0
- package/src/routes/api/knowledge.search.ts +31 -0
- package/src/routes/api/knowledge.sessions.$sessionId.candidates.ts +16 -0
- package/src/routes/api/logs.$id.chunks.ts +36 -0
- package/src/routes/api/logs.$id.replay.ts +191 -0
- package/src/routes/api/logs.$id.ts +22 -0
- package/src/routes/api/logs.stream.ts +74 -0
- package/src/routes/api/logs.ts +59 -0
- package/src/routes/api/mcp.ts +25 -0
- package/src/routes/api/models.ts +10 -0
- package/src/routes/api/providers.$providerId.test.log.ts +293 -0
- package/src/routes/api/providers.$providerId.ts +50 -0
- package/src/routes/api/providers.export.ts +26 -0
- package/src/routes/api/providers.import.ts +47 -0
- package/src/routes/api/providers.scan.ts +23 -0
- package/src/routes/api/providers.ts +45 -0
- package/src/routes/api/sessions.ts +17 -0
- package/src/routes/index.tsx +6 -0
- package/src/routes/proxy/$.ts +15 -0
- package/src/routes/session/$sessionId.tsx +23 -0
- package/styles/globals.css +188 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import {
|
|
2
|
+
writeFileSync,
|
|
3
|
+
mkdirSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
unlinkSync,
|
|
6
|
+
existsSync,
|
|
7
|
+
renameSync,
|
|
8
|
+
copyFileSync,
|
|
9
|
+
} from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { logger } from "./logger";
|
|
12
|
+
import { getDataDir } from "./dataDir";
|
|
13
|
+
import {
|
|
14
|
+
DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
15
|
+
RuntimeConfigSchema,
|
|
16
|
+
type RuntimeConfig,
|
|
17
|
+
} from "../lib/runtimeConfig";
|
|
18
|
+
|
|
19
|
+
// Re-export so server-side callers (api/config.ts, tests) keep the
|
|
20
|
+
// existing import path `from "../../proxy/config"`.
|
|
21
|
+
export { RuntimeConfigSchema };
|
|
22
|
+
export type { RuntimeConfig };
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Runtime-mutable server config. Includes proxy behavior flags and UI tuning
|
|
26
|
+
* settings that should take effect without restarting the dev server. The API
|
|
27
|
+
* layer reads and writes the same object via `getConfig` / `setConfig`.
|
|
28
|
+
*
|
|
29
|
+
* Boot-time precedence (first match wins):
|
|
30
|
+
* 1. `data/config.json` on disk (persisted state)
|
|
31
|
+
* 2. `AGENT_INSPECTOR_STRIP_CLAUDE_CODE_BILLING_HEADER` env var
|
|
32
|
+
* 3. `false` (off by default, to keep the proxy transparent)
|
|
33
|
+
*
|
|
34
|
+
* The env var is read once at module init; changing it requires a restart.
|
|
35
|
+
* Once the user has saved a value via the API, the persisted file takes
|
|
36
|
+
* precedence over the env var for the lifetime of the process.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
// --- Persistence ---
|
|
40
|
+
|
|
41
|
+
function getConfigFilePath(): string {
|
|
42
|
+
return join(getDataDir(), "config.json");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getConfigTempPath(): string {
|
|
46
|
+
return join(getDataDir(), "config.json.tmp");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// --- Module state ---
|
|
50
|
+
|
|
51
|
+
// Internal: writeable singleton. Read via getConfig(), mutate via setConfig().
|
|
52
|
+
let currentConfig: RuntimeConfig = resolveInitialConfig();
|
|
53
|
+
|
|
54
|
+
function resolveInitialConfig(): RuntimeConfig {
|
|
55
|
+
// 1. Persisted file
|
|
56
|
+
const filePath = getConfigFilePath();
|
|
57
|
+
if (existsSync(filePath)) {
|
|
58
|
+
try {
|
|
59
|
+
const content = readFileSync(filePath, "utf-8");
|
|
60
|
+
const parsed: unknown = JSON.parse(content);
|
|
61
|
+
const result = RuntimeConfigSchema.safeParse(parsed);
|
|
62
|
+
if (result.success) {
|
|
63
|
+
logger.info(`[config] Loaded persisted config from ${filePath}`);
|
|
64
|
+
return result.data;
|
|
65
|
+
}
|
|
66
|
+
logger.warn(
|
|
67
|
+
`[config] Persisted config at ${filePath} is invalid; falling back to env/default`,
|
|
68
|
+
);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
logger.warn(
|
|
71
|
+
`[config] Failed to read persisted config at ${filePath}: ${String(err)}; falling back to env/default`,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 2. Env var
|
|
77
|
+
if (process.env["AGENT_INSPECTOR_STRIP_CLAUDE_CODE_BILLING_HEADER"] === "1") {
|
|
78
|
+
return {
|
|
79
|
+
stripClaudeCodeBillingHeader: true,
|
|
80
|
+
hasSeenOnboarding: false,
|
|
81
|
+
slowResponseThresholdSeconds: DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 3. Default off
|
|
86
|
+
return {
|
|
87
|
+
stripClaudeCodeBillingHeader: false,
|
|
88
|
+
hasSeenOnboarding: false,
|
|
89
|
+
slowResponseThresholdSeconds: DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Returns the current config. Synchronous; safe to call on the hot path.
|
|
95
|
+
*/
|
|
96
|
+
export function getConfig(): RuntimeConfig {
|
|
97
|
+
return currentConfig;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Applies a partial update to the in-memory config and persists to disk.
|
|
102
|
+
* Returns the updated full config. Persistence failures are logged but
|
|
103
|
+
* do not throw — the in-memory value is always updated so the caller
|
|
104
|
+
* sees a consistent response.
|
|
105
|
+
*/
|
|
106
|
+
export function setConfig(patch: Partial<RuntimeConfig>): RuntimeConfig {
|
|
107
|
+
const next: RuntimeConfig = {
|
|
108
|
+
...currentConfig,
|
|
109
|
+
...patch,
|
|
110
|
+
};
|
|
111
|
+
currentConfig = next;
|
|
112
|
+
persistConfig(next);
|
|
113
|
+
return next;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* For tests: reset the in-memory config to a known value without
|
|
118
|
+
* touching disk. Use `setConfig` in production code.
|
|
119
|
+
*/
|
|
120
|
+
export function _resetConfigForTests(value: RuntimeConfig): void {
|
|
121
|
+
currentConfig = value;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* For tests: re-run the boot-time resolution against the current env vars
|
|
126
|
+
* and the on-disk config file, and update the in-memory value. Use this to
|
|
127
|
+
* test env-var precedence without having to reload the module.
|
|
128
|
+
*/
|
|
129
|
+
export function _rebootForTests(): void {
|
|
130
|
+
currentConfig = resolveInitialConfig();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// --- Atomic write ---
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Atomic write: temp file + rename. Mirrors the pattern in chunkStorage.ts.
|
|
137
|
+
* Returns true on success, false on failure (logged but not thrown).
|
|
138
|
+
*/
|
|
139
|
+
function persistConfig(value: RuntimeConfig): boolean {
|
|
140
|
+
const dir = getDataDir();
|
|
141
|
+
const targetPath = getConfigFilePath();
|
|
142
|
+
const tempPath = getConfigTempPath();
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
mkdirSync(dir, { recursive: true });
|
|
146
|
+
} catch (err) {
|
|
147
|
+
logger.error(`[config] Failed to create data directory ${dir}: ${String(err)}`);
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
writeFileSync(tempPath, JSON.stringify(value), "utf-8");
|
|
153
|
+
} catch (err) {
|
|
154
|
+
logger.error(`[config] Failed to write config temp file: ${String(err)}`);
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
renameSync(tempPath, targetPath);
|
|
160
|
+
return true;
|
|
161
|
+
} catch (err) {
|
|
162
|
+
logger.warn(`[config] Rename failed, falling back to copy+delete: ${String(err)}`);
|
|
163
|
+
try {
|
|
164
|
+
copyFileSync(tempPath, targetPath);
|
|
165
|
+
unlinkSync(tempPath);
|
|
166
|
+
return true;
|
|
167
|
+
} catch (copyErr) {
|
|
168
|
+
logger.error(`[config] Failed to copy config file: ${String(copyErr)}`);
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Proxy module constants
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_UPSTREAM = "https://api.anthropic.com";
|
|
4
|
+
export const DEFAULT_OPENAI_UPSTREAM = "https://api.openai.com/v1";
|
|
5
|
+
|
|
6
|
+
// Unified proxy identity - used as user-agent and x-proxy-identity header value
|
|
7
|
+
export const PROXY_IDENTITY = process.env["PROXY_IDENTITY"] ?? "inspector9527@Tony";
|
|
8
|
+
|
|
9
|
+
// API paths
|
|
10
|
+
export const PATH_V1_CHAT_COMPLETIONS = "/v1/chat/completions";
|
|
11
|
+
export const PATH_CHAT_COMPLETIONS = "/chat/completions";
|
|
12
|
+
export const PATH_V1_MESSAGES = "/v1/messages";
|
|
13
|
+
|
|
14
|
+
// Header names
|
|
15
|
+
export const HEADER_CONTENT_TYPE = "content-type";
|
|
16
|
+
export const HEADER_USER_AGENT = "user-agent";
|
|
17
|
+
export const HEADER_X_PROXY_IDENTITY = "x-proxy-identity";
|
|
18
|
+
export const HEADER_AUTHORIZATION = "authorization";
|
|
19
|
+
export const HEADER_X_API_KEY = "x-api-key";
|
|
20
|
+
export const HEADER_CONTENT_ENCODING = "content-encoding";
|
|
21
|
+
export const HEADER_CONTENT_LENGTH = "content-length";
|
|
22
|
+
export const HEADER_HOST = "host";
|
|
23
|
+
|
|
24
|
+
// Auth header types
|
|
25
|
+
export const AUTH_HEADER_X_API_KEY = "x-api-key";
|
|
26
|
+
|
|
27
|
+
// Content types
|
|
28
|
+
export const CONTENT_TYPE_EVENT_STREAM = "text/event-stream";
|
|
29
|
+
|
|
30
|
+
// Response status
|
|
31
|
+
export const STATUS_FORBIDDEN = 403;
|
|
32
|
+
export const STATUS_BAD_GATEWAY = 502;
|
|
33
|
+
|
|
34
|
+
// Standard/safe headers to preserve when forwarding to upstream.
|
|
35
|
+
// NOTE: Authorization is intentionally excluded to prevent client auth tokens from leaking.
|
|
36
|
+
export const PRESERVE_HEADERS = new Set([HEADER_CONTENT_TYPE]);
|
|
37
|
+
|
|
38
|
+
// Opt-in rewrite: the *initial* value for the strip-Claude-Code-billing-header
|
|
39
|
+
// flag. The runtime, mutable source of truth is `src/proxy/config.ts`, which
|
|
40
|
+
// reads this constant at module-load time as its precedence-2 fallback (after
|
|
41
|
+
// the persisted `data/config.json`, before the `false` default). After boot,
|
|
42
|
+
// the handler reads `getConfig().stripClaudeCodeBillingHeader` on every
|
|
43
|
+
// request, so a PATCH to `/api/config` (or the Settings → Proxy tab in the UI)
|
|
44
|
+
// takes effect without a restart. The env var itself is read once at boot.
|
|
45
|
+
//
|
|
46
|
+
// What it does: when enabled, the proxy strips the
|
|
47
|
+
// `x-anthropic-billing-header:` text block that Claude Code prepends to the
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join } from "node:path";
|
|
3
|
+
|
|
4
|
+
const CURRENT_DATA_DIR_NAME = ".agent-inspector";
|
|
5
|
+
const LEGACY_DATA_DIR_NAME = ".llm-inspector";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Compute the directory where agent-inspector stores its on-disk state
|
|
9
|
+
* (runtime config, providers config, log chunks, etc.). Centralised here
|
|
10
|
+
* so every store agrees on the same path.
|
|
11
|
+
*
|
|
12
|
+
* Resolution order (first match wins):
|
|
13
|
+
* 1. `AGENT_INSPECTOR_DATA_DIR` env var — absolute path used as-is,
|
|
14
|
+
* relative path joined to the OS-specific base below.
|
|
15
|
+
* 2. `AGENT_INSPECTOR_CONFIG_DIR` env var — kept for backward compat
|
|
16
|
+
* with the runtime config; treated as a directory *name* (relative
|
|
17
|
+
* to the OS-specific base) when not absolute.
|
|
18
|
+
* 3. OS-specific base + `.agent-inspector`.
|
|
19
|
+
* 4. Backward compatibility: if `.agent-inspector` has no known state
|
|
20
|
+
* files but `.llm-inspector` does, reuse `.llm-inspector`.
|
|
21
|
+
*
|
|
22
|
+
* Windows base is `%USERPROFILE%` (falling back to `%APPDATA%`, then `C:\`).
|
|
23
|
+
* macOS / Linux base is `$HOME` (falling back to `/tmp`).
|
|
24
|
+
*
|
|
25
|
+
* The env var is re-read on every call so tests and the CLI can swap the
|
|
26
|
+
* directory after this module has been imported.
|
|
27
|
+
*/
|
|
28
|
+
export function getDataDir(): string {
|
|
29
|
+
return resolveDataDir(existsSync);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type PathExists = (path: string) => boolean;
|
|
33
|
+
type DataDirEnv = Readonly<Record<string, string | undefined>>;
|
|
34
|
+
|
|
35
|
+
function hasDataDirState(pathExists: PathExists, dir: string): boolean {
|
|
36
|
+
return (
|
|
37
|
+
pathExists(join(dir, "providers.json")) ||
|
|
38
|
+
pathExists(join(dir, "config.json")) ||
|
|
39
|
+
pathExists(join(dir, "logs")) ||
|
|
40
|
+
pathExists(join(dir, "chunks"))
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function resolveDataDir(
|
|
45
|
+
pathExists: PathExists,
|
|
46
|
+
env: DataDirEnv = process.env,
|
|
47
|
+
platform: typeof process.platform = process.platform,
|
|
48
|
+
): string {
|
|
49
|
+
const isWindows = platform === "win32";
|
|
50
|
+
const base = isWindows
|
|
51
|
+
? (env["USERPROFILE"] ?? env["APPDATA"] ?? "C:\\")
|
|
52
|
+
: (env["HOME"] ?? "/tmp");
|
|
53
|
+
|
|
54
|
+
const dirEnv = env["AGENT_INSPECTOR_DATA_DIR"];
|
|
55
|
+
if (dirEnv !== undefined && dirEnv !== "") {
|
|
56
|
+
return isAbsolute(dirEnv) ? dirEnv : join(base, dirEnv);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Backward-compat: the runtime config historically read
|
|
60
|
+
// `AGENT_INSPECTOR_CONFIG_DIR` as a directory *name* (relative to base).
|
|
61
|
+
// Honour it so existing CLI scripts keep working.
|
|
62
|
+
const legacyDirEnv = env["AGENT_INSPECTOR_CONFIG_DIR"];
|
|
63
|
+
if (legacyDirEnv !== undefined && legacyDirEnv !== "") {
|
|
64
|
+
return isAbsolute(legacyDirEnv) ? legacyDirEnv : join(base, legacyDirEnv);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const currentDir = join(base, CURRENT_DATA_DIR_NAME);
|
|
68
|
+
const legacyDir = join(base, LEGACY_DATA_DIR_NAME);
|
|
69
|
+
return !hasDataDirState(pathExists, currentDir) && hasDataDirState(pathExists, legacyDir)
|
|
70
|
+
? legacyDir
|
|
71
|
+
: currentDir;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* `true` when the user has explicitly asked for a non-default data
|
|
76
|
+
* directory. Used to skip the one-time legacy migration so we don't
|
|
77
|
+
* write to a path the user didn't choose.
|
|
78
|
+
*/
|
|
79
|
+
export function hasExplicitDataDir(): boolean {
|
|
80
|
+
return (
|
|
81
|
+
(process.env["AGENT_INSPECTOR_DATA_DIR"] !== undefined &&
|
|
82
|
+
process.env["AGENT_INSPECTOR_DATA_DIR"] !== "") ||
|
|
83
|
+
(process.env["AGENT_INSPECTOR_CONFIG_DIR"] !== undefined &&
|
|
84
|
+
process.env["AGENT_INSPECTOR_CONFIG_DIR"] !== "")
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { CapturedLog } from "../../schemas";
|
|
2
|
+
import type { ProviderProtocol } from "../protocol";
|
|
3
|
+
import { registry } from "../providers";
|
|
4
|
+
import { extractAnthropicStream } from "./stream";
|
|
5
|
+
|
|
6
|
+
const DEFAULT_UPSTREAM = "https://api.anthropic.com";
|
|
7
|
+
|
|
8
|
+
// Default routes - MiniMax is hardcoded here
|
|
9
|
+
const DEFAULT_ROUTES: Record<string, string> = {
|
|
10
|
+
MiniMax: "https://api.minimaxi.com/anthropic",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function getUpstreamForModel(model: string): string {
|
|
14
|
+
let bestPrefix = "";
|
|
15
|
+
let bestUrl = DEFAULT_UPSTREAM;
|
|
16
|
+
|
|
17
|
+
for (const [prefix, url] of Object.entries(DEFAULT_ROUTES)) {
|
|
18
|
+
if (model.startsWith(prefix) && prefix.length > bestPrefix.length) {
|
|
19
|
+
bestPrefix = prefix;
|
|
20
|
+
bestUrl = url;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return bestUrl;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Anthropic Provider Implementation
|
|
29
|
+
*/
|
|
30
|
+
export const anthropicProvider: ProviderProtocol = {
|
|
31
|
+
name: "anthropic",
|
|
32
|
+
|
|
33
|
+
matches(model: string): boolean {
|
|
34
|
+
const modelLower = model.toLowerCase();
|
|
35
|
+
|
|
36
|
+
// Don't match OpenAI models
|
|
37
|
+
if (modelLower.startsWith("openai-")) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Match Anthropic models
|
|
42
|
+
if (modelLower.includes("claude") || modelLower.includes("anthropic")) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Match known route prefixes (e.g., MiniMax)
|
|
47
|
+
for (const prefix of Object.keys(DEFAULT_ROUTES)) {
|
|
48
|
+
if (modelLower.startsWith(prefix.toLowerCase())) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Default to Anthropic for unknown models (legacy behavior)
|
|
54
|
+
return true;
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
getUpstreamBase(_isChatCompletions: boolean, providerConfig?: { baseUrl?: string }): string {
|
|
58
|
+
if (providerConfig?.baseUrl !== undefined) {
|
|
59
|
+
return providerConfig.baseUrl;
|
|
60
|
+
}
|
|
61
|
+
return DEFAULT_UPSTREAM;
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
extractStream(
|
|
65
|
+
raw: string,
|
|
66
|
+
log: CapturedLog,
|
|
67
|
+
fallbackModel?: string,
|
|
68
|
+
collectChunks?: boolean,
|
|
69
|
+
): string {
|
|
70
|
+
return extractAnthropicStream(raw, log, fallbackModel, collectChunks);
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Register the provider
|
|
75
|
+
registry.register(anthropicProvider);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { FormatHandler, ParsedRequest } from "../handler";
|
|
2
|
+
import type { CapturedLog, TokenUsage } from "../../schemas";
|
|
3
|
+
import { AnthropicRequestSchema, AnthropicResponseSchema } from "./schemas";
|
|
4
|
+
import { extractAnthropicStream } from "./stream";
|
|
5
|
+
|
|
6
|
+
export const AnthropicFormatHandler: FormatHandler = {
|
|
7
|
+
format: "anthropic",
|
|
8
|
+
|
|
9
|
+
parseRequest(rawBody: string, headers?: Headers): ParsedRequest | null {
|
|
10
|
+
try {
|
|
11
|
+
const json: unknown = JSON.parse(rawBody);
|
|
12
|
+
const result = AnthropicRequestSchema.safeParse(json);
|
|
13
|
+
if (result.success) {
|
|
14
|
+
return {
|
|
15
|
+
model: result.data.model,
|
|
16
|
+
sessionId: result.data.metadata?.user_id ?? headers?.get("x-session-affinity") ?? null,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
} catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
extractTokens(responseBody: string): TokenUsage {
|
|
26
|
+
try {
|
|
27
|
+
const json: unknown = JSON.parse(responseBody);
|
|
28
|
+
const result = AnthropicResponseSchema.safeParse(json);
|
|
29
|
+
if (result.success) {
|
|
30
|
+
return {
|
|
31
|
+
inputTokens: result.data.usage.input_tokens ?? null,
|
|
32
|
+
outputTokens: result.data.usage.output_tokens ?? null,
|
|
33
|
+
cacheCreationInputTokens: result.data.usage.cache_creation_input_tokens ?? null,
|
|
34
|
+
cacheReadInputTokens: result.data.usage.cache_read_input_tokens ?? null,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
// Fall through
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
inputTokens: null,
|
|
42
|
+
outputTokens: null,
|
|
43
|
+
cacheCreationInputTokens: null,
|
|
44
|
+
cacheReadInputTokens: null,
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
extractStream(
|
|
49
|
+
raw: string,
|
|
50
|
+
log: CapturedLog,
|
|
51
|
+
fallbackModel?: string,
|
|
52
|
+
collectChunks?: boolean,
|
|
53
|
+
): string {
|
|
54
|
+
return extractAnthropicStream(raw, log, fallbackModel, collectChunks);
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
detectFormat(rawBody: string | null): boolean {
|
|
58
|
+
if (rawBody === null) return false;
|
|
59
|
+
try {
|
|
60
|
+
const json: unknown = JSON.parse(rawBody);
|
|
61
|
+
if (typeof json === "object" && json !== null && !Array.isArray(json)) {
|
|
62
|
+
const keys = Object.keys(json);
|
|
63
|
+
// Anthropic puts `system` as a top-level key alongside `model` and `messages`
|
|
64
|
+
return keys.includes("model") && keys.includes("messages") && keys.includes("system");
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
} catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Register format handler
|
|
2
|
+
import "./register";
|
|
3
|
+
|
|
4
|
+
export { AnthropicFormatHandler } from "./handler";
|
|
5
|
+
export {
|
|
6
|
+
AnthropicRequestSchema,
|
|
7
|
+
AnthropicResponseSchema,
|
|
8
|
+
SseEventSchema,
|
|
9
|
+
type AnthropicRequest,
|
|
10
|
+
type AnthropicResponse,
|
|
11
|
+
type ResponseContentBlockType,
|
|
12
|
+
} from "./schemas";
|
|
13
|
+
export { extractAnthropicStream } from "./stream";
|
|
14
|
+
export { anthropicProvider } from "./anthropicProvider";
|