@tonyclaw/agent-inspector 4.0.1 → 4.0.3
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/backend/nitro.json +1 -1
- package/.output/cli.js +193 -110
- package/.output/server/_ssr/index.mjs +1 -1
- package/.output/server/_ssr/{router-CTHqmroT.mjs → router-ChILzhmz.mjs} +92 -4
- package/.output/server/index.mjs +1 -1
- package/.output/ui/assets/{CompareDrawer-L3n4J-Or.js → CompareDrawer-Co3cUF_I.js} +1 -1
- package/.output/ui/assets/{InspectorPet-D5o_3OZS.js → InspectorPet-jFcrL37X.js} +1 -1
- package/.output/ui/assets/{ProxyViewerContainer-Ocagx75S.js → ProxyViewerContainer-BPzt_VpM.js} +4 -4
- package/.output/ui/assets/{ReplayDialog-Bk7x1h-y.js → ReplayDialog-C6O_zuwI.js} +1 -1
- package/.output/ui/assets/{RequestAnatomy-U4lzL7Sc.js → RequestAnatomy-Ca6NvB7L.js} +1 -1
- package/.output/ui/assets/{ResponseView-LOWfvBLK.js → ResponseView-BzqKcveJ.js} +1 -1
- package/.output/ui/assets/{StreamingChunkSequence-DPfsrrXQ.js → StreamingChunkSequence-9pCZIsS_.js} +1 -1
- package/.output/ui/assets/{_sessionId-0MlWS-CO.js → _sessionId-BMP3KVGR.js} +1 -1
- package/.output/ui/assets/{_sessionId-OdX2Jvt1.js → _sessionId-y4eRoT1H.js} +1 -1
- package/.output/ui/assets/{index-Ea-c8hPg.js → index-CH5w-haG.js} +1 -1
- package/.output/ui/assets/{index-zVVS53Hd.js → index-CmocEhyU.js} +1 -1
- package/.output/ui/assets/{index-Du4qNOOt.js → index-DT8sMJ_n.js} +2 -2
- package/.output/ui/assets/{index-gvFj_9K6.js → index-bfsbIRZa.js} +1 -1
- package/.output/ui/assets/{json-viewer-C1WAMzg3.js → json-viewer-BfFOSDG5.js} +1 -1
- package/.output/ui/assets/{jszip.min-B8AKu2zm.js → jszip.min-BkbVkOsp.js} +1 -1
- package/.output/ui/index.html +1 -1
- package/package.json +5 -10
- package/src/assets/IDE/claudecode-color.svg +0 -1
- package/src/assets/IDE/codex-color.svg +0 -1
- package/src/assets/IDE/opencode.svg +0 -1
- package/src/assets/IDE/xiaomimimo.svg +0 -1
- package/src/assets/favicon.svg +0 -21
- package/src/assets/logos/alibaba.svg +0 -1
- package/src/assets/logos/anthropic.svg +0 -1
- package/src/assets/logos/claude-code.svg +0 -4
- package/src/assets/logos/deepseek.svg +0 -1
- package/src/assets/logos/minimax.jpeg +0 -0
- package/src/assets/logos/openai.svg +0 -1
- package/src/assets/logos/opencode.svg +0 -4
- package/src/assets/logos/qwen.webp +0 -0
- package/src/assets/logos/zhipuai.svg +0 -219
- package/src/backend/router.tsx +0 -36
- package/src/backend/routes/$.ts +0 -26
- package/src/backend/routes/__root.ts +0 -4
- package/src/backend/routes/api/-instances.ts +0 -7
- package/src/backend/routes/api/alerts.summary.ts +0 -28
- package/src/backend/routes/api/alerts.ts +0 -70
- package/src/backend/routes/api/config.paths.ts +0 -14
- package/src/backend/routes/api/config.ts +0 -73
- package/src/backend/routes/api/ecosystem.packages.$packageId.help.ts +0 -11
- package/src/backend/routes/api/ecosystem.packages.$packageId.install.ts +0 -11
- package/src/backend/routes/api/ecosystem.packages.$packageId.runner-presets.ts +0 -11
- package/src/backend/routes/api/ecosystem.packages.$packageId.upgrade.ts +0 -11
- package/src/backend/routes/api/ecosystem.packages.ts +0 -21
- package/src/backend/routes/api/ecosystem.recipes.$recipeId.run.ts +0 -11
- package/src/backend/routes/api/ecosystem.tasks.$taskId.ts +0 -16
- package/src/backend/routes/api/ecosystem.tasks.ts +0 -12
- package/src/backend/routes/api/groups.$groupId.evidence.ts +0 -55
- package/src/backend/routes/api/groups.$groupId.sessions.ts +0 -50
- package/src/backend/routes/api/groups.$groupId.ts +0 -93
- package/src/backend/routes/api/groups.ts +0 -79
- package/src/backend/routes/api/health.ts +0 -22
- package/src/backend/routes/api/instances.$name.connection.ts +0 -12
- package/src/backend/routes/api/instances.$name.restart.ts +0 -23
- package/src/backend/routes/api/instances.$name.start.ts +0 -18
- package/src/backend/routes/api/instances.$name.stop.ts +0 -23
- package/src/backend/routes/api/instances.$name.ts +0 -12
- package/src/backend/routes/api/instances.ts +0 -16
- package/src/backend/routes/api/knowledge.candidates.$candidateId.promote.ts +0 -32
- package/src/backend/routes/api/knowledge.candidates.$candidateId.ts +0 -50
- package/src/backend/routes/api/knowledge.candidates.ts +0 -10
- package/src/backend/routes/api/knowledge.project-context.ts +0 -29
- package/src/backend/routes/api/knowledge.search.ts +0 -62
- package/src/backend/routes/api/knowledge.sessions.$sessionId.candidates.ts +0 -26
- package/src/backend/routes/api/logs.$id.body.ts +0 -58
- package/src/backend/routes/api/logs.$id.chunks.ts +0 -37
- package/src/backend/routes/api/logs.$id.replay.ts +0 -297
- package/src/backend/routes/api/logs.$id.ts +0 -23
- package/src/backend/routes/api/logs.import.ts +0 -39
- package/src/backend/routes/api/logs.stream.ts +0 -174
- package/src/backend/routes/api/logs.ts +0 -214
- package/src/backend/routes/api/mcp.ts +0 -25
- package/src/backend/routes/api/models.ts +0 -10
- package/src/backend/routes/api/pi-agent.ts +0 -29
- package/src/backend/routes/api/providers.$providerId.model-metadata.ts +0 -173
- package/src/backend/routes/api/providers.$providerId.test.log.ts +0 -342
- package/src/backend/routes/api/providers.$providerId.ts +0 -111
- package/src/backend/routes/api/providers.export.ts +0 -44
- package/src/backend/routes/api/providers.import.ts +0 -81
- package/src/backend/routes/api/providers.scan.ts +0 -28
- package/src/backend/routes/api/providers.ts +0 -102
- package/src/backend/routes/api/runs.$runId.evidence.ts +0 -55
- package/src/backend/routes/api/runs.$runId.ts +0 -50
- package/src/backend/routes/api/runs.ts +0 -62
- package/src/backend/routes/api/runtime.ts +0 -46
- package/src/backend/routes/api/sessions.ts +0 -51
- package/src/backend/routes/api/storage.ts +0 -56
- package/src/backend/routes/livez.ts +0 -13
- package/src/backend/routes/metrics.ts +0 -14
- package/src/backend/routes/proxy/$.ts +0 -15
- package/src/backend/routes/readyz.ts +0 -18
- package/src/backend/start.ts +0 -10
- package/src/cli/alias.ts +0 -431
- package/src/cli/detect-tools.ts +0 -123
- package/src/cli/doctor.ts +0 -836
- package/src/cli/instance.ts +0 -1071
- package/src/cli/instanceApi.ts +0 -213
- package/src/cli/instanceArgs.ts +0 -301
- package/src/cli/instanceControl.ts +0 -191
- package/src/cli/instanceModel.ts +0 -276
- package/src/cli/instanceRegistry.ts +0 -731
- package/src/cli/networkHints.ts +0 -170
- package/src/cli/onboard.ts +0 -1668
- package/src/cli/onboardTarget.ts +0 -228
- package/src/cli/rustBackendPackage.ts +0 -458
- package/src/cli/startupOutput.ts +0 -16
- package/src/cli/templates/codex-skill-onboard.ts +0 -320
- package/src/cli/templates/command-onboard.ts +0 -25
- package/src/cli/templates/skill-onboard.ts +0 -625
- package/src/cli.ts +0 -1433
- package/src/components/OnboardingBanner.tsx +0 -115
- package/src/components/ProxyViewer.tsx +0 -2259
- package/src/components/ProxyViewerContainer.tsx +0 -1076
- package/src/components/alerts/AlertsDialog.tsx +0 -615
- package/src/components/clients/ClientLogo.tsx +0 -175
- package/src/components/ecosystem/AgentLabDialog.tsx +0 -947
- package/src/components/errors/SafeErrorBoundary.tsx +0 -201
- package/src/components/groups/GroupsDialog.tsx +0 -1304
- package/src/components/inspector-pet/InspectorPet.tsx +0 -398
- package/src/components/inspector-pet/InspectorPetCrab3D.tsx +0 -455
- package/src/components/inspector-pet/inspectorPetLogic.ts +0 -272
- package/src/components/pi-agent/PiAgentPanel.tsx +0 -446
- package/src/components/pi-agent/piAgentChatLogic.ts +0 -273
- package/src/components/providers/ImportWizardDialog.tsx +0 -281
- package/src/components/providers/ProviderCard.tsx +0 -347
- package/src/components/providers/ProviderForm.tsx +0 -1183
- package/src/components/providers/ProviderLogo.tsx +0 -122
- package/src/components/providers/ProviderTestResultsView.tsx +0 -734
- package/src/components/providers/ProvidersPanel.tsx +0 -714
- package/src/components/providers/SettingsDialog.tsx +0 -1042
- package/src/components/providers/providerFormCapabilities.ts +0 -36
- package/src/components/proxy-viewer/AgentTraceSummary.tsx +0 -902
- package/src/components/proxy-viewer/AnswerMarkdown.tsx +0 -51
- package/src/components/proxy-viewer/ApplicationBar.tsx +0 -123
- package/src/components/proxy-viewer/CompareDrawer.tsx +0 -984
- package/src/components/proxy-viewer/ConversationGroup.tsx +0 -208
- package/src/components/proxy-viewer/ConversationGroupList.tsx +0 -652
- package/src/components/proxy-viewer/ConversationHeader.tsx +0 -429
- package/src/components/proxy-viewer/LiveConnectionStatus.tsx +0 -186
- package/src/components/proxy-viewer/LogEntry.tsx +0 -1419
- package/src/components/proxy-viewer/LogEntryHeader.tsx +0 -596
- package/src/components/proxy-viewer/ProviderLogoStack.tsx +0 -57
- package/src/components/proxy-viewer/RawExportWarning.tsx +0 -77
- package/src/components/proxy-viewer/ReplayDialog.tsx +0 -636
- package/src/components/proxy-viewer/RequestToolsPanel.tsx +0 -299
- package/src/components/proxy-viewer/ResponseView.tsx +0 -202
- package/src/components/proxy-viewer/SessionLoadProgressBar.tsx +0 -61
- package/src/components/proxy-viewer/StreamingChunkSequence.tsx +0 -265
- package/src/components/proxy-viewer/ThreadConnector.tsx +0 -165
- package/src/components/proxy-viewer/ToolTraceEvents.tsx +0 -64
- package/src/components/proxy-viewer/TurnGroup.tsx +0 -383
- package/src/components/proxy-viewer/TurnGroupList.tsx +0 -156
- package/src/components/proxy-viewer/accessibility.ts +0 -8
- package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +0 -887
- package/src/components/proxy-viewer/anatomy/SegmentBar.tsx +0 -222
- package/src/components/proxy-viewer/anatomy/contextIntelligence.ts +0 -737
- package/src/components/proxy-viewer/anatomy/sessionContextSummary.ts +0 -268
- package/src/components/proxy-viewer/anatomy/tokenEstimate.ts +0 -53
- package/src/components/proxy-viewer/anatomy/types.ts +0 -41
- package/src/components/proxy-viewer/anatomy/useAnatomyJump.ts +0 -114
- package/src/components/proxy-viewer/bodyHydration.ts +0 -123
- package/src/components/proxy-viewer/cacheTrend.ts +0 -50
- package/src/components/proxy-viewer/diff/DiffView.tsx +0 -321
- package/src/components/proxy-viewer/diff/computeDiff.ts +0 -178
- package/src/components/proxy-viewer/diff/index.ts +0 -3
- package/src/components/proxy-viewer/formats/anthropic/ContentBlocks.tsx +0 -194
- package/src/components/proxy-viewer/formats/anthropic/ResponseView.tsx +0 -81
- package/src/components/proxy-viewer/formats/anthropic/thinkingExtract.ts +0 -21
- package/src/components/proxy-viewer/formats/index.tsx +0 -47
- package/src/components/proxy-viewer/formats/openai/ResponseView.tsx +0 -442
- package/src/components/proxy-viewer/index.ts +0 -9
- package/src/components/proxy-viewer/lazy.ts +0 -41
- package/src/components/proxy-viewer/liveConnectionState.ts +0 -158
- package/src/components/proxy-viewer/log-formats/anthropic.ts +0 -191
- package/src/components/proxy-viewer/log-formats/index.ts +0 -23
- package/src/components/proxy-viewer/log-formats/openai.ts +0 -256
- package/src/components/proxy-viewer/log-formats/types.ts +0 -40
- package/src/components/proxy-viewer/log-formats/unknown.ts +0 -18
- package/src/components/proxy-viewer/logEntryVisibility.ts +0 -73
- package/src/components/proxy-viewer/logFocus.ts +0 -54
- package/src/components/proxy-viewer/proxyViewerContainerLogic.ts +0 -124
- package/src/components/proxy-viewer/proxyViewerLogic.ts +0 -488
- package/src/components/proxy-viewer/replayComparison.ts +0 -131
- package/src/components/proxy-viewer/requestDiff.ts +0 -277
- package/src/components/proxy-viewer/requestTools.ts +0 -220
- package/src/components/proxy-viewer/useCopyFeedback.ts +0 -38
- package/src/components/proxy-viewer/useKeyboardNavigation.ts +0 -232
- package/src/components/proxy-viewer/viewerState.ts +0 -176
- package/src/components/ui/badge.tsx +0 -47
- package/src/components/ui/button.tsx +0 -47
- package/src/components/ui/collapsible.tsx +0 -21
- package/src/components/ui/confirm-dialog.tsx +0 -51
- package/src/components/ui/crab-logo.tsx +0 -45
- package/src/components/ui/crab-variants.tsx +0 -467
- package/src/components/ui/dialog.tsx +0 -130
- package/src/components/ui/icon-trigger.ts +0 -2
- package/src/components/ui/json-viewer-bulk.ts +0 -132
- package/src/components/ui/json-viewer.tsx +0 -508
- package/src/components/ui/scroll-area.tsx +0 -54
- package/src/components/ui/select.tsx +0 -178
- package/src/components/ui/separator.tsx +0 -28
- package/src/components/ui/tabs.tsx +0 -88
- package/src/components/ui/tooltip.tsx +0 -51
- package/src/components/ui/transient-toast.tsx +0 -105
- package/src/contracts/anthropic.ts +0 -230
- package/src/contracts/index.ts +0 -59
- package/src/contracts/json.ts +0 -37
- package/src/contracts/log.ts +0 -139
- package/src/contracts/openai.ts +0 -267
- package/src/index.css +0 -11
- package/src/knowledge/candidateStore.ts +0 -94
- package/src/knowledge/distiller.ts +0 -98
- package/src/knowledge/openclawClient.ts +0 -161
- package/src/knowledge/openclawGatewayClient.ts +0 -249
- package/src/knowledge/openclawMarkdown.ts +0 -146
- package/src/knowledge/redactor.ts +0 -80
- package/src/knowledge/types.ts +0 -83
- package/src/lib/alertContract.ts +0 -76
- package/src/lib/apiClient.ts +0 -166
- package/src/lib/apiFormat.ts +0 -29
- package/src/lib/backendImplementation.ts +0 -16
- package/src/lib/basePath.ts +0 -107
- package/src/lib/browserRuntimeContract.ts +0 -124
- package/src/lib/browserRuntimeResolver.ts +0 -333
- package/src/lib/chunkLoadRecovery.ts +0 -83
- package/src/lib/claudeCodeStrip.ts +0 -98
- package/src/lib/clipboard.ts +0 -67
- package/src/lib/codingAgentEndpoints.ts +0 -54
- package/src/lib/ecosystemContract.ts +0 -130
- package/src/lib/export-logs.ts +0 -287
- package/src/lib/groupContract.ts +0 -166
- package/src/lib/instanceContract.ts +0 -239
- package/src/lib/jsonFile.ts +0 -46
- package/src/lib/logImportContract.ts +0 -12
- package/src/lib/managedInstance.ts +0 -112
- package/src/lib/mask.ts +0 -4
- package/src/lib/objectUtils.ts +0 -22
- package/src/lib/piAgentContract.ts +0 -102
- package/src/lib/providerContract.ts +0 -125
- package/src/lib/providerImportContract.ts +0 -27
- package/src/lib/providerModelMetadata.ts +0 -458
- package/src/lib/providerTestContract.ts +0 -170
- package/src/lib/providerTestPrompt.ts +0 -100
- package/src/lib/publicBasePathContext.ts +0 -137
- package/src/lib/resourceLimits.ts +0 -345
- package/src/lib/runContract.ts +0 -164
- package/src/lib/runtimeConfig.ts +0 -43
- package/src/lib/safeDiagnostic.ts +0 -38
- package/src/lib/safeFetch.ts +0 -508
- package/src/lib/serverPort.ts +0 -47
- package/src/lib/sessionInfoContract.ts +0 -78
- package/src/lib/sessionUrl.ts +0 -46
- package/src/lib/ssrfGuard.ts +0 -133
- package/src/lib/stopReason.ts +0 -130
- package/src/lib/themeMode.ts +0 -41
- package/src/lib/timeDisplay.ts +0 -22
- package/src/lib/toolTrace.ts +0 -290
- package/src/lib/uiScale.ts +0 -117
- package/src/lib/unknown.ts +0 -27
- package/src/lib/upstreamUrl.ts +0 -150
- package/src/lib/useAlerts.ts +0 -82
- package/src/lib/useGroupEvidence.ts +0 -37
- package/src/lib/useGroups.ts +0 -32
- package/src/lib/useOnboarding.ts +0 -93
- package/src/lib/useProviders.ts +0 -30
- package/src/lib/useStripConfig.ts +0 -154
- package/src/lib/useThemeMode.ts +0 -40
- package/src/lib/useUiScale.ts +0 -52
- package/src/lib/utils.ts +0 -78
- package/src/mcp/currentContext.ts +0 -65
- package/src/mcp/instanceHandlers.ts +0 -151
- package/src/mcp/loopback.ts +0 -88
- package/src/mcp/mode.ts +0 -75
- package/src/mcp/previewExtractor.ts +0 -233
- package/src/mcp/server.ts +0 -2274
- package/src/mcp/toolHandlers.ts +0 -1533
- package/src/proxy/alerts.ts +0 -664
- package/src/proxy/chunkStorage.ts +0 -123
- package/src/proxy/config.ts +0 -218
- package/src/proxy/constants.ts +0 -66
- package/src/proxy/dataDir.ts +0 -147
- package/src/proxy/ecosystemExecutionConfirmation.ts +0 -114
- package/src/proxy/ecosystemExecutionRoute.ts +0 -116
- package/src/proxy/ecosystemRegistry.ts +0 -296
- package/src/proxy/ecosystemTasks.ts +0 -415
- package/src/proxy/evidenceAnalysis.ts +0 -526
- package/src/proxy/evidenceExporter.ts +0 -235
- package/src/proxy/formats/anthropic/anthropicProvider.ts +0 -75
- package/src/proxy/formats/anthropic/handler.ts +0 -75
- package/src/proxy/formats/anthropic/index.ts +0 -13
- package/src/proxy/formats/anthropic/register.ts +0 -4
- package/src/proxy/formats/anthropic/schemas.ts +0 -6
- package/src/proxy/formats/anthropic/stream.ts +0 -205
- package/src/proxy/formats/handler.ts +0 -46
- package/src/proxy/formats/index.ts +0 -13
- package/src/proxy/formats/jsonSchema.ts +0 -2
- package/src/proxy/formats/openai/alibabaProvider.ts +0 -34
- package/src/proxy/formats/openai/codexMetadata.ts +0 -61
- package/src/proxy/formats/openai/handler.ts +0 -133
- package/src/proxy/formats/openai/index.ts +0 -33
- package/src/proxy/formats/openai/provider.ts +0 -50
- package/src/proxy/formats/openai/register.ts +0 -4
- package/src/proxy/formats/openai/schemas.ts +0 -25
- package/src/proxy/formats/openai/stream.ts +0 -600
- package/src/proxy/formats/openai/zhipuProvider.ts +0 -31
- package/src/proxy/formats/providerAdapter.ts +0 -50
- package/src/proxy/formats/providerRegistry.ts +0 -51
- package/src/proxy/formats/providers/index.ts +0 -3
- package/src/proxy/formats/registry.ts +0 -65
- package/src/proxy/groupEvidenceExporter.ts +0 -371
- package/src/proxy/groupStore.ts +0 -336
- package/src/proxy/handler.ts +0 -729
- package/src/proxy/identityProxy.ts +0 -1842
- package/src/proxy/jsonlRecovery.ts +0 -554
- package/src/proxy/logBodyChunks.ts +0 -91
- package/src/proxy/logFinalizer.ts +0 -777
- package/src/proxy/logFinalizer.worker.ts +0 -24
- package/src/proxy/logImportUpload.ts +0 -128
- package/src/proxy/logImporter.ts +0 -813
- package/src/proxy/logIndex.ts +0 -663
- package/src/proxy/logSearch.ts +0 -122
- package/src/proxy/logger.ts +0 -537
- package/src/proxy/openaiOrphanToolStrip.ts +0 -142
- package/src/proxy/platformCommands.ts +0 -258
- package/src/proxy/privateDataPath.ts +0 -419
- package/src/proxy/providerImporters.ts +0 -578
- package/src/proxy/providerScanStore.ts +0 -87
- package/src/proxy/providerSecretStore.ts +0 -216
- package/src/proxy/providers.ts +0 -998
- package/src/proxy/rawStreamCapture.ts +0 -342
- package/src/proxy/runFailures.ts +0 -94
- package/src/proxy/runStore.ts +0 -214
- package/src/proxy/runtimeAdmission.ts +0 -55
- package/src/proxy/runtimeHealth.ts +0 -221
- package/src/proxy/runtimeMetrics.ts +0 -149
- package/src/proxy/runtimeShutdown.ts +0 -157
- package/src/proxy/schemas.ts +0 -112
- package/src/proxy/sessionArchive.ts +0 -479
- package/src/proxy/sessionInfo.ts +0 -266
- package/src/proxy/sessionProcess.ts +0 -194
- package/src/proxy/sessionRuntime.ts +0 -121
- package/src/proxy/sessionSupervisor.ts +0 -305
- package/src/proxy/sessionWorkerEntry.ts +0 -26
- package/src/proxy/shutdownCoordinator.ts +0 -90
- package/src/proxy/socketTracker.ts +0 -639
- package/src/proxy/sqliteLogIndex.ts +0 -733
- package/src/proxy/storageLifecycle.ts +0 -432
- package/src/proxy/store.ts +0 -1773
- package/src/proxy/streamTiming.ts +0 -31
- package/src/proxy/toolSchemaWarnings.ts +0 -529
- package/src/proxy/uiAssetServer.ts +0 -106
- package/src/proxy/upstream.ts +0 -127
- package/src/services/alerts.ts +0 -12
- package/src/services/groups.ts +0 -119
- package/src/services/piAgent.ts +0 -421
- package/src/services/piAgentRetrieval.ts +0 -1180
- package/src/services/result.ts +0 -17
- package/src/services/runs.ts +0 -76
- package/src/ui/bootstrap.ts +0 -167
- package/src/ui/index.html +0 -38
- package/src/ui/logsStreamClient.ts +0 -20
- package/src/ui/main.tsx +0 -13
- package/src/ui/public/runtime-config.js +0 -2
- package/src/ui/router.tsx +0 -13
- package/src/ui/routes/__root.tsx +0 -69
- package/src/ui/routes/index.tsx +0 -35
- package/src/ui/routes/session/$sessionId.tsx +0 -50
- package/src/ui/runtimeDiscovery.ts +0 -50
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { StopCircle, Zap } from "lucide-react";
|
|
2
|
-
import { memo, type JSX } from "react";
|
|
3
|
-
import type { AnthropicResponse } from "../../../../contracts/anthropic";
|
|
4
|
-
import { formatTokens } from "../../../../lib/utils";
|
|
5
|
-
import { Badge } from "../../../ui/badge";
|
|
6
|
-
import { Separator } from "../../../ui/separator";
|
|
7
|
-
import type { ResponseToolFocus } from "../index";
|
|
8
|
-
import { ResponseContentBlockRenderer } from "./ContentBlocks";
|
|
9
|
-
|
|
10
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow -- named function gives React DevTools a readable displayName
|
|
11
|
-
export const StructuredResponseViewAnthropic = memo(function StructuredResponseViewAnthropic({
|
|
12
|
-
response,
|
|
13
|
-
toolFocus,
|
|
14
|
-
}: {
|
|
15
|
-
response: AnthropicResponse;
|
|
16
|
-
toolFocus?: ResponseToolFocus;
|
|
17
|
-
}): JSX.Element {
|
|
18
|
-
let toolIndex = 0;
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<div className="space-y-3">
|
|
22
|
-
<div className="flex items-center gap-2 flex-wrap">
|
|
23
|
-
<Badge variant="secondary" className="text-[10px] px-1.5 py-0 h-5 font-mono">
|
|
24
|
-
{response.model}
|
|
25
|
-
</Badge>
|
|
26
|
-
|
|
27
|
-
{response.stop_reason !== null && (
|
|
28
|
-
<Badge
|
|
29
|
-
variant="outline"
|
|
30
|
-
className="text-[10px] px-1.5 py-0 h-5 font-mono flex items-center gap-1"
|
|
31
|
-
>
|
|
32
|
-
<StopCircle className="size-2.5" />
|
|
33
|
-
{response.stop_reason}
|
|
34
|
-
</Badge>
|
|
35
|
-
)}
|
|
36
|
-
|
|
37
|
-
<span className="flex items-center gap-1 text-muted-foreground text-xs">
|
|
38
|
-
<Zap className="size-3" />
|
|
39
|
-
<span className="font-mono tabular-nums">
|
|
40
|
-
{formatTokens(response.usage.input_tokens ?? 0)} in /{" "}
|
|
41
|
-
{formatTokens(response.usage.output_tokens ?? 0)} out
|
|
42
|
-
</span>
|
|
43
|
-
{response.usage.cache_creation_input_tokens !== undefined &&
|
|
44
|
-
response.usage.cache_creation_input_tokens !== null &&
|
|
45
|
-
response.usage.cache_creation_input_tokens > 0 && (
|
|
46
|
-
<span className="font-mono tabular-nums text-emerald-400">
|
|
47
|
-
KV Cache +{formatTokens(response.usage.cache_creation_input_tokens)}
|
|
48
|
-
</span>
|
|
49
|
-
)}
|
|
50
|
-
{response.usage.cache_read_input_tokens !== undefined &&
|
|
51
|
-
response.usage.cache_read_input_tokens !== null &&
|
|
52
|
-
response.usage.cache_read_input_tokens > 0 && (
|
|
53
|
-
<span className="font-mono tabular-nums text-purple-400">
|
|
54
|
-
KV Cache ~{formatTokens(response.usage.cache_read_input_tokens)}
|
|
55
|
-
</span>
|
|
56
|
-
)}
|
|
57
|
-
</span>
|
|
58
|
-
</div>
|
|
59
|
-
|
|
60
|
-
<Separator className="opacity-50" />
|
|
61
|
-
|
|
62
|
-
<div className="space-y-2">
|
|
63
|
-
{response.content.map((block, i) => {
|
|
64
|
-
const currentToolIndex = block.type === "tool_use" ? toolIndex : undefined;
|
|
65
|
-
if (block.type === "tool_use") toolIndex += 1;
|
|
66
|
-
return (
|
|
67
|
-
<ResponseContentBlockRenderer
|
|
68
|
-
key={i}
|
|
69
|
-
block={block}
|
|
70
|
-
toolIndex={currentToolIndex}
|
|
71
|
-
toolFocus={toolFocus}
|
|
72
|
-
/>
|
|
73
|
-
);
|
|
74
|
-
})}
|
|
75
|
-
{response.content.length === 0 && (
|
|
76
|
-
<p className="text-xs text-muted-foreground italic">Empty response content</p>
|
|
77
|
-
)}
|
|
78
|
-
</div>
|
|
79
|
-
</div>
|
|
80
|
-
);
|
|
81
|
-
});
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// Regex to extract content wrapped in <think>...</thinking> tags (MiniMax format: <think>...</think>)
|
|
2
|
-
const THINKING_TAG_REGEX = /<think>([\s\S]*?)<\/think>/gi;
|
|
3
|
-
const THINKING_TAG_REGEX_SINGLE = /<think>([\s\S]*?)<\/think>/i;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Extract thinking content wrapped in <think> tags (thought balloon emoji) from text.
|
|
7
|
-
* Returns { thinking, remainingText } where thinking is the extracted content
|
|
8
|
-
* and remainingText is the original text with thinking tags removed.
|
|
9
|
-
*/
|
|
10
|
-
export function extractThinkingFromContent(text: string): {
|
|
11
|
-
thinking: string | null;
|
|
12
|
-
remainingText: string;
|
|
13
|
-
} {
|
|
14
|
-
const match = THINKING_TAG_REGEX_SINGLE.exec(text);
|
|
15
|
-
if (!match || match[1] === undefined) {
|
|
16
|
-
return { thinking: null, remainingText: text };
|
|
17
|
-
}
|
|
18
|
-
const thinking = match[1].trim();
|
|
19
|
-
const remainingText = text.replace(THINKING_TAG_REGEX, "").trim();
|
|
20
|
-
return { thinking, remainingText };
|
|
21
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { JSX } from "react";
|
|
2
|
-
import type { ApiFormat } from "../../../contracts";
|
|
3
|
-
import type { AnthropicResponse } from "../../../contracts/anthropic";
|
|
4
|
-
import type { OpenAIResponse, OpenAIResponsesResponse } from "../../../contracts/openai";
|
|
5
|
-
import { StructuredResponseViewAnthropic } from "./anthropic/ResponseView";
|
|
6
|
-
import { OpenAIResponseView, OpenAIResponsesResponseView } from "./openai/ResponseView";
|
|
7
|
-
|
|
8
|
-
export { StructuredResponseViewAnthropic } from "./anthropic/ResponseView";
|
|
9
|
-
export { OpenAIResponseView, OpenAIResponsesResponseView } from "./openai/ResponseView";
|
|
10
|
-
export { ResponseContentBlockRenderer } from "./anthropic/ContentBlocks";
|
|
11
|
-
|
|
12
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
13
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function isOpenAIResponse(response: unknown): response is OpenAIResponse {
|
|
17
|
-
return isRecord(response) && response.object === "chat.completion";
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function isOpenAIResponsesResponse(response: unknown): response is OpenAIResponsesResponse {
|
|
21
|
-
return isRecord(response) && response.object === "response";
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function isAnthropicResponse(response: unknown): response is AnthropicResponse {
|
|
25
|
-
return isRecord(response) && response.type === "message" && Array.isArray(response.content);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function formatViewFor(
|
|
29
|
-
apiFormat: ApiFormat | undefined,
|
|
30
|
-
response: unknown,
|
|
31
|
-
toolFocus?: ResponseToolFocus,
|
|
32
|
-
): JSX.Element | null {
|
|
33
|
-
if (apiFormat === "openai" && isOpenAIResponse(response)) {
|
|
34
|
-
return <OpenAIResponseView response={response} toolFocus={toolFocus} />;
|
|
35
|
-
}
|
|
36
|
-
if (apiFormat === "openai" && isOpenAIResponsesResponse(response)) {
|
|
37
|
-
return <OpenAIResponsesResponseView response={response} toolFocus={toolFocus} />;
|
|
38
|
-
}
|
|
39
|
-
if (apiFormat === "anthropic" && isAnthropicResponse(response)) {
|
|
40
|
-
return <StructuredResponseViewAnthropic response={response} toolFocus={toolFocus} />;
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
export type ResponseToolFocus = {
|
|
45
|
-
focusedToolIndex: number | null;
|
|
46
|
-
toolFocusNonce: number;
|
|
47
|
-
};
|
|
@@ -1,442 +0,0 @@
|
|
|
1
|
-
import { StopCircle, Terminal, Zap } from "lucide-react";
|
|
2
|
-
import { memo, Suspense, useEffect, useRef, useState, type JSX, type RefObject } from "react";
|
|
3
|
-
import type {
|
|
4
|
-
OpenAIResponse,
|
|
5
|
-
OpenAIResponsesResponse,
|
|
6
|
-
OpenAIToolCall,
|
|
7
|
-
} from "../../../../contracts/openai";
|
|
8
|
-
import { safeGetOwnProperty } from "../../../../lib/objectUtils";
|
|
9
|
-
import { formatTokens } from "../../../../lib/utils";
|
|
10
|
-
import { AnswerMarkdown } from "../../AnswerMarkdown";
|
|
11
|
-
import { Badge } from "../../../ui/badge";
|
|
12
|
-
import { safeJsonValue } from "../../../ui/json-viewer-bulk";
|
|
13
|
-
import { ScrollArea } from "../../../ui/scroll-area";
|
|
14
|
-
import { Separator } from "../../../ui/separator";
|
|
15
|
-
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../../ui/collapsible";
|
|
16
|
-
import { ChevronDown, ChevronRight } from "lucide-react";
|
|
17
|
-
import { ThinkingBlock } from "../anthropic/ContentBlocks";
|
|
18
|
-
import { extractThinkingFromContent } from "../anthropic/thinkingExtract";
|
|
19
|
-
import { LazyJsonViewer } from "../../lazy";
|
|
20
|
-
import type { ResponseToolFocus } from "../index";
|
|
21
|
-
|
|
22
|
-
// Re-export for use in other components
|
|
23
|
-
export { extractThinkingFromContent } from "../anthropic/thinkingExtract";
|
|
24
|
-
|
|
25
|
-
/** Best-effort JSON parse of an OpenAI `function.arguments` string. Returns
|
|
26
|
-
* the parsed object, or `null` on parse failure so the renderer can fall
|
|
27
|
-
* back to showing the raw string. */
|
|
28
|
-
function parseToolArguments(raw: string | undefined): unknown {
|
|
29
|
-
if (raw === undefined || raw === "") return {};
|
|
30
|
-
try {
|
|
31
|
-
return JSON.parse(raw);
|
|
32
|
-
} catch {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** One collapsible tool_use row, mirroring the Anthropic ToolUseBlock visual
|
|
38
|
-
* treatment (Terminal icon, soft tool accent, name as a Badge, JSON input in
|
|
39
|
-
* a scrollable JsonViewer). */
|
|
40
|
-
function useToolFocus({
|
|
41
|
-
toolIndex,
|
|
42
|
-
toolFocus,
|
|
43
|
-
setOpen,
|
|
44
|
-
}: {
|
|
45
|
-
toolIndex: number;
|
|
46
|
-
toolFocus?: ResponseToolFocus;
|
|
47
|
-
setOpen: (open: boolean) => void;
|
|
48
|
-
}): RefObject<HTMLButtonElement | null> {
|
|
49
|
-
const triggerRef = useRef<HTMLButtonElement | null>(null);
|
|
50
|
-
const shouldFocus = toolFocus?.focusedToolIndex === toolIndex;
|
|
51
|
-
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
if (!shouldFocus || toolFocus === undefined || toolFocus.toolFocusNonce <= 0) return undefined;
|
|
54
|
-
setOpen(true);
|
|
55
|
-
const timer = window.setTimeout(() => {
|
|
56
|
-
const trigger = triggerRef.current;
|
|
57
|
-
if (trigger === null) return;
|
|
58
|
-
trigger.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
59
|
-
trigger.focus({ preventScroll: true });
|
|
60
|
-
}, 0);
|
|
61
|
-
return () => window.clearTimeout(timer);
|
|
62
|
-
}, [setOpen, shouldFocus, toolFocus, toolFocus?.toolFocusNonce]);
|
|
63
|
-
|
|
64
|
-
return triggerRef;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function OpenAIFunctionCallBlock({
|
|
68
|
-
name,
|
|
69
|
-
argumentsText,
|
|
70
|
-
toolIndex,
|
|
71
|
-
toolFocus,
|
|
72
|
-
}: {
|
|
73
|
-
name: string | undefined;
|
|
74
|
-
argumentsText: string | undefined;
|
|
75
|
-
toolIndex: number;
|
|
76
|
-
toolFocus?: ResponseToolFocus;
|
|
77
|
-
}): JSX.Element {
|
|
78
|
-
const blockRef = useRef<HTMLDivElement | null>(null);
|
|
79
|
-
const shouldFocus = toolFocus?.focusedToolIndex === toolIndex;
|
|
80
|
-
|
|
81
|
-
useEffect(() => {
|
|
82
|
-
if (!shouldFocus || toolFocus === undefined || toolFocus.toolFocusNonce <= 0) return undefined;
|
|
83
|
-
const timer = window.setTimeout(() => {
|
|
84
|
-
const block = blockRef.current;
|
|
85
|
-
if (block === null) return;
|
|
86
|
-
block.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
87
|
-
block.focus({ preventScroll: true });
|
|
88
|
-
}, 0);
|
|
89
|
-
return () => window.clearTimeout(timer);
|
|
90
|
-
}, [shouldFocus, toolFocus, toolFocus?.toolFocusNonce]);
|
|
91
|
-
|
|
92
|
-
return (
|
|
93
|
-
<div
|
|
94
|
-
ref={blockRef}
|
|
95
|
-
tabIndex={-1}
|
|
96
|
-
className="border border-sky-400/20 rounded-md p-3 bg-muted/20 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
97
|
-
data-response-tool-index={toolIndex}
|
|
98
|
-
>
|
|
99
|
-
<div className="text-xs text-sky-400/80 font-mono mb-1">function_call</div>
|
|
100
|
-
<div className="font-mono text-xs">
|
|
101
|
-
<span className="text-foreground/80">{name}</span>
|
|
102
|
-
<span className="text-muted-foreground">({argumentsText})</span>
|
|
103
|
-
</div>
|
|
104
|
-
</div>
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function OpenAIToolCallBlock({
|
|
109
|
-
call,
|
|
110
|
-
toolIndex,
|
|
111
|
-
toolFocus,
|
|
112
|
-
}: {
|
|
113
|
-
call: OpenAIToolCall;
|
|
114
|
-
toolIndex: number;
|
|
115
|
-
toolFocus?: ResponseToolFocus;
|
|
116
|
-
}): JSX.Element {
|
|
117
|
-
const [open, setOpen] = useState(false);
|
|
118
|
-
const name = call.function.name ?? "(unnamed tool)";
|
|
119
|
-
const parsed = open ? parseToolArguments(call.function.arguments) : {};
|
|
120
|
-
const triggerRef = useToolFocus({ toolIndex, toolFocus, setOpen });
|
|
121
|
-
|
|
122
|
-
return (
|
|
123
|
-
<Collapsible open={open} onOpenChange={setOpen}>
|
|
124
|
-
<div className="border-l-2 border-sky-400/25 my-1" data-response-tool-index={toolIndex}>
|
|
125
|
-
<CollapsibleTrigger
|
|
126
|
-
ref={triggerRef}
|
|
127
|
-
className="flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-sky-400/[0.04] transition-colors rounded-r-sm group focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
128
|
-
>
|
|
129
|
-
<Terminal className="size-3.5 text-sky-400/70 shrink-0" />
|
|
130
|
-
<Badge variant="outline" className="text-[10px] font-mono px-1.5 py-0 h-4">
|
|
131
|
-
{name}
|
|
132
|
-
</Badge>
|
|
133
|
-
{call.id !== undefined && call.id !== "" && (
|
|
134
|
-
<span className="text-[10px] font-mono text-muted-foreground/60 truncate">
|
|
135
|
-
{call.id}
|
|
136
|
-
</span>
|
|
137
|
-
)}
|
|
138
|
-
<span className="flex-1" />
|
|
139
|
-
{open ? (
|
|
140
|
-
<ChevronDown className="size-3 text-muted-foreground" />
|
|
141
|
-
) : (
|
|
142
|
-
<ChevronRight className="size-3 text-muted-foreground" />
|
|
143
|
-
)}
|
|
144
|
-
</CollapsibleTrigger>
|
|
145
|
-
<CollapsibleContent>
|
|
146
|
-
{open && (
|
|
147
|
-
<div className="px-3 pb-2">
|
|
148
|
-
<ScrollArea className="max-h-[60vh]">
|
|
149
|
-
{parsed === null ? (
|
|
150
|
-
// JSON.parse failed — show the raw string so the user can
|
|
151
|
-
// still see what the model tried to call.
|
|
152
|
-
<pre className="font-mono text-xs whitespace-pre-wrap break-words text-rose-300/90">
|
|
153
|
-
{call.function.arguments}
|
|
154
|
-
</pre>
|
|
155
|
-
) : (
|
|
156
|
-
<Suspense
|
|
157
|
-
fallback={<div className="text-xs text-muted-foreground">Loading JSON...</div>}
|
|
158
|
-
>
|
|
159
|
-
<LazyJsonViewer data={safeJsonValue(parsed)} defaultExpandDepth={0} />
|
|
160
|
-
</Suspense>
|
|
161
|
-
)}
|
|
162
|
-
</ScrollArea>
|
|
163
|
-
</div>
|
|
164
|
-
)}
|
|
165
|
-
</CollapsibleContent>
|
|
166
|
-
</div>
|
|
167
|
-
</Collapsible>
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
type ResponsesFunctionCall = {
|
|
172
|
-
id: string | null;
|
|
173
|
-
callId: string | null;
|
|
174
|
-
name: string;
|
|
175
|
-
argumentsText: string;
|
|
176
|
-
status: string | null;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
function extractResponsesOutputText(response: OpenAIResponsesResponse): string {
|
|
180
|
-
if (response.output_text !== undefined && response.output_text.length > 0) {
|
|
181
|
-
return response.output_text;
|
|
182
|
-
}
|
|
183
|
-
const parts: string[] = [];
|
|
184
|
-
for (const outputItem of response.output ?? []) {
|
|
185
|
-
if (safeGetOwnProperty(outputItem, "type") !== "message") continue;
|
|
186
|
-
const content = safeGetOwnProperty(outputItem, "content");
|
|
187
|
-
if (!Array.isArray(content)) continue;
|
|
188
|
-
for (const contentPart of content) {
|
|
189
|
-
const type = safeGetOwnProperty(contentPart, "type");
|
|
190
|
-
const text = safeGetOwnProperty(contentPart, "text");
|
|
191
|
-
if ((type === "output_text" || type === "text") && typeof text === "string") {
|
|
192
|
-
parts.push(text);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return parts.join("\n");
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function extractResponsesFunctionCalls(response: OpenAIResponsesResponse): ResponsesFunctionCall[] {
|
|
200
|
-
const calls: ResponsesFunctionCall[] = [];
|
|
201
|
-
for (const outputItem of response.output ?? []) {
|
|
202
|
-
if (safeGetOwnProperty(outputItem, "type") !== "function_call") continue;
|
|
203
|
-
const name = safeGetOwnProperty(outputItem, "name");
|
|
204
|
-
if (typeof name !== "string" || name.length === 0) continue;
|
|
205
|
-
const id = safeGetOwnProperty(outputItem, "id");
|
|
206
|
-
const callId = safeGetOwnProperty(outputItem, "call_id");
|
|
207
|
-
const args = safeGetOwnProperty(outputItem, "arguments");
|
|
208
|
-
const status = safeGetOwnProperty(outputItem, "status");
|
|
209
|
-
calls.push({
|
|
210
|
-
id: typeof id === "string" && id.length > 0 ? id : null,
|
|
211
|
-
callId: typeof callId === "string" && callId.length > 0 ? callId : null,
|
|
212
|
-
name,
|
|
213
|
-
argumentsText: typeof args === "string" ? args : "",
|
|
214
|
-
status: typeof status === "string" && status.length > 0 ? status : null,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
return calls;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function ResponsesFunctionCallBlock({
|
|
221
|
-
call,
|
|
222
|
-
toolIndex,
|
|
223
|
-
toolFocus,
|
|
224
|
-
}: {
|
|
225
|
-
call: ResponsesFunctionCall;
|
|
226
|
-
toolIndex: number;
|
|
227
|
-
toolFocus?: ResponseToolFocus;
|
|
228
|
-
}): JSX.Element {
|
|
229
|
-
const [open, setOpen] = useState(false);
|
|
230
|
-
const parsed = open ? parseToolArguments(call.argumentsText) : {};
|
|
231
|
-
const identity = call.callId ?? call.id;
|
|
232
|
-
const triggerRef = useToolFocus({ toolIndex, toolFocus, setOpen });
|
|
233
|
-
|
|
234
|
-
return (
|
|
235
|
-
<Collapsible open={open} onOpenChange={setOpen}>
|
|
236
|
-
<div className="border-l-2 border-sky-400/25 my-1" data-response-tool-index={toolIndex}>
|
|
237
|
-
<CollapsibleTrigger
|
|
238
|
-
ref={triggerRef}
|
|
239
|
-
className="flex items-center gap-1.5 px-3 py-1 w-full text-left cursor-pointer hover:bg-sky-400/[0.04] transition-colors rounded-r-sm group focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
240
|
-
>
|
|
241
|
-
<Terminal className="size-3.5 text-sky-400/70 shrink-0" />
|
|
242
|
-
<Badge variant="outline" className="text-[10px] font-mono px-1.5 py-0 h-4">
|
|
243
|
-
{call.name}
|
|
244
|
-
</Badge>
|
|
245
|
-
{identity !== null && (
|
|
246
|
-
<span className="text-[10px] font-mono text-muted-foreground/60 truncate">
|
|
247
|
-
{identity}
|
|
248
|
-
</span>
|
|
249
|
-
)}
|
|
250
|
-
{call.status !== null && (
|
|
251
|
-
<Badge variant="secondary" className="text-[10px] px-1.5 py-0 h-4 font-mono">
|
|
252
|
-
{call.status}
|
|
253
|
-
</Badge>
|
|
254
|
-
)}
|
|
255
|
-
<span className="flex-1" />
|
|
256
|
-
{open ? (
|
|
257
|
-
<ChevronDown className="size-3 text-muted-foreground" />
|
|
258
|
-
) : (
|
|
259
|
-
<ChevronRight className="size-3 text-muted-foreground" />
|
|
260
|
-
)}
|
|
261
|
-
</CollapsibleTrigger>
|
|
262
|
-
<CollapsibleContent>
|
|
263
|
-
{open && (
|
|
264
|
-
<div className="px-3 pb-2">
|
|
265
|
-
<ScrollArea className="max-h-[60vh]">
|
|
266
|
-
{parsed === null ? (
|
|
267
|
-
<pre className="font-mono text-xs whitespace-pre-wrap break-words text-rose-300/90">
|
|
268
|
-
{call.argumentsText}
|
|
269
|
-
</pre>
|
|
270
|
-
) : (
|
|
271
|
-
<Suspense
|
|
272
|
-
fallback={<div className="text-xs text-muted-foreground">Loading JSON...</div>}
|
|
273
|
-
>
|
|
274
|
-
<LazyJsonViewer data={safeJsonValue(parsed)} defaultExpandDepth={0} />
|
|
275
|
-
</Suspense>
|
|
276
|
-
)}
|
|
277
|
-
</ScrollArea>
|
|
278
|
-
</div>
|
|
279
|
-
)}
|
|
280
|
-
</CollapsibleContent>
|
|
281
|
-
</div>
|
|
282
|
-
</Collapsible>
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow -- named function gives React DevTools a readable displayName
|
|
287
|
-
export const OpenAIResponseView = memo(function OpenAIResponseView({
|
|
288
|
-
response,
|
|
289
|
-
toolFocus,
|
|
290
|
-
}: {
|
|
291
|
-
response: OpenAIResponse;
|
|
292
|
-
toolFocus?: ResponseToolFocus;
|
|
293
|
-
}): JSX.Element {
|
|
294
|
-
const choice = response.choices[0];
|
|
295
|
-
const message = choice?.message;
|
|
296
|
-
const toolCalls = message?.tool_calls ?? [];
|
|
297
|
-
|
|
298
|
-
return (
|
|
299
|
-
<div className="space-y-3">
|
|
300
|
-
<div className="flex items-center gap-2 flex-wrap">
|
|
301
|
-
<Badge variant="secondary" className="text-[10px] px-1.5 py-0 h-5 font-mono">
|
|
302
|
-
{response.model}
|
|
303
|
-
</Badge>
|
|
304
|
-
|
|
305
|
-
{choice?.finish_reason !== null && choice?.finish_reason !== undefined && (
|
|
306
|
-
<Badge
|
|
307
|
-
variant="outline"
|
|
308
|
-
className="text-[10px] px-1.5 py-0 h-5 font-mono flex items-center gap-1"
|
|
309
|
-
>
|
|
310
|
-
<StopCircle className="size-2.5" />
|
|
311
|
-
{choice.finish_reason}
|
|
312
|
-
</Badge>
|
|
313
|
-
)}
|
|
314
|
-
|
|
315
|
-
<span className="flex items-center gap-1 text-muted-foreground text-xs">
|
|
316
|
-
<Zap className="size-3" />
|
|
317
|
-
<span className="font-mono tabular-nums">
|
|
318
|
-
{formatTokens(response.usage.prompt_tokens ?? 0)} in /{" "}
|
|
319
|
-
{formatTokens(response.usage.completion_tokens ?? 0)} out
|
|
320
|
-
</span>
|
|
321
|
-
</span>
|
|
322
|
-
</div>
|
|
323
|
-
|
|
324
|
-
<Separator className="opacity-50" />
|
|
325
|
-
|
|
326
|
-
<div className="space-y-2">
|
|
327
|
-
{message?.reasoning_content !== null &&
|
|
328
|
-
message?.reasoning_content !== undefined &&
|
|
329
|
-
message.reasoning_content.length > 0 && (
|
|
330
|
-
<ThinkingBlock thinking={message.reasoning_content} />
|
|
331
|
-
)}
|
|
332
|
-
{message?.content !== null &&
|
|
333
|
-
message?.content !== undefined &&
|
|
334
|
-
message.content.length > 0 &&
|
|
335
|
-
(() => {
|
|
336
|
-
// Extract thinking content from tag-wrapped content if no reasoning_content field
|
|
337
|
-
const hasReasoningField =
|
|
338
|
-
message.reasoning_content !== null &&
|
|
339
|
-
message.reasoning_content !== undefined &&
|
|
340
|
-
message.reasoning_content.length > 0;
|
|
341
|
-
const { thinking, remainingText } = extractThinkingFromContent(message.content);
|
|
342
|
-
return (
|
|
343
|
-
<div className="space-y-2">
|
|
344
|
-
{/* Show thinking from tags only if no reasoning_content field */}
|
|
345
|
-
{thinking !== null && !hasReasoningField && <ThinkingBlock thinking={thinking} />}
|
|
346
|
-
{remainingText.length > 0 && <AnswerMarkdown text={remainingText} />}
|
|
347
|
-
</div>
|
|
348
|
-
);
|
|
349
|
-
})()}
|
|
350
|
-
{toolCalls.map((call, i) => (
|
|
351
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: tool_calls is the positionally stable list from the response
|
|
352
|
-
<OpenAIToolCallBlock
|
|
353
|
-
key={call.id ?? `tc-${i}`}
|
|
354
|
-
call={call}
|
|
355
|
-
toolIndex={i}
|
|
356
|
-
toolFocus={toolFocus}
|
|
357
|
-
/>
|
|
358
|
-
))}
|
|
359
|
-
{message?.function_call !== null && message?.function_call !== undefined && (
|
|
360
|
-
<OpenAIFunctionCallBlock
|
|
361
|
-
name={message.function_call.name}
|
|
362
|
-
argumentsText={message.function_call.arguments}
|
|
363
|
-
toolIndex={toolCalls.length}
|
|
364
|
-
toolFocus={toolFocus}
|
|
365
|
-
/>
|
|
366
|
-
)}
|
|
367
|
-
{(message?.content === null ||
|
|
368
|
-
message?.content === undefined ||
|
|
369
|
-
message.content.length === 0) &&
|
|
370
|
-
(message?.reasoning_content === null ||
|
|
371
|
-
message?.reasoning_content === undefined ||
|
|
372
|
-
message.reasoning_content.length === 0) &&
|
|
373
|
-
(message?.function_call === null || message?.function_call === undefined) &&
|
|
374
|
-
toolCalls.length === 0 && (
|
|
375
|
-
<p className="text-xs text-muted-foreground italic">Empty response content</p>
|
|
376
|
-
)}
|
|
377
|
-
</div>
|
|
378
|
-
</div>
|
|
379
|
-
);
|
|
380
|
-
});
|
|
381
|
-
|
|
382
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow -- named function gives React DevTools a readable displayName
|
|
383
|
-
export const OpenAIResponsesResponseView = memo(function OpenAIResponsesResponseView({
|
|
384
|
-
response,
|
|
385
|
-
toolFocus,
|
|
386
|
-
}: {
|
|
387
|
-
response: OpenAIResponsesResponse;
|
|
388
|
-
toolFocus?: ResponseToolFocus;
|
|
389
|
-
}): JSX.Element {
|
|
390
|
-
const text = extractResponsesOutputText(response);
|
|
391
|
-
const calls = extractResponsesFunctionCalls(response);
|
|
392
|
-
const status = response.status ?? null;
|
|
393
|
-
const inputTokens = response.usage?.input_tokens ?? 0;
|
|
394
|
-
const outputTokens = response.usage?.output_tokens ?? 0;
|
|
395
|
-
|
|
396
|
-
return (
|
|
397
|
-
<div className="space-y-3">
|
|
398
|
-
<div className="flex items-center gap-2 flex-wrap">
|
|
399
|
-
{response.model !== undefined && response.model.length > 0 && (
|
|
400
|
-
<Badge variant="secondary" className="text-[10px] px-1.5 py-0 h-5 font-mono">
|
|
401
|
-
{response.model}
|
|
402
|
-
</Badge>
|
|
403
|
-
)}
|
|
404
|
-
|
|
405
|
-
{status !== null && (
|
|
406
|
-
<Badge
|
|
407
|
-
variant="outline"
|
|
408
|
-
className="text-[10px] px-1.5 py-0 h-5 font-mono flex items-center gap-1"
|
|
409
|
-
>
|
|
410
|
-
<StopCircle className="size-2.5" />
|
|
411
|
-
{status}
|
|
412
|
-
</Badge>
|
|
413
|
-
)}
|
|
414
|
-
|
|
415
|
-
<span className="flex items-center gap-1 text-muted-foreground text-xs">
|
|
416
|
-
<Zap className="size-3" />
|
|
417
|
-
<span className="font-mono tabular-nums">
|
|
418
|
-
{formatTokens(inputTokens)} in / {formatTokens(outputTokens)} out
|
|
419
|
-
</span>
|
|
420
|
-
</span>
|
|
421
|
-
</div>
|
|
422
|
-
|
|
423
|
-
<Separator className="opacity-50" />
|
|
424
|
-
|
|
425
|
-
<div className="space-y-2">
|
|
426
|
-
{text.length > 0 && <AnswerMarkdown text={text} />}
|
|
427
|
-
{calls.map((call, i) => (
|
|
428
|
-
// biome-ignore lint/suspicious/noArrayIndexKey: response output order is stable
|
|
429
|
-
<ResponsesFunctionCallBlock
|
|
430
|
-
key={call.callId ?? call.id ?? `call-${i}`}
|
|
431
|
-
call={call}
|
|
432
|
-
toolIndex={i}
|
|
433
|
-
toolFocus={toolFocus}
|
|
434
|
-
/>
|
|
435
|
-
))}
|
|
436
|
-
{text.length === 0 && calls.length === 0 && (
|
|
437
|
-
<p className="text-xs text-muted-foreground italic">Empty response content</p>
|
|
438
|
-
)}
|
|
439
|
-
</div>
|
|
440
|
-
</div>
|
|
441
|
-
);
|
|
442
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { ConversationGroup } from "./ConversationGroup";
|
|
2
|
-
export {
|
|
3
|
-
ConversationHeader,
|
|
4
|
-
getConversationId,
|
|
5
|
-
groupLogsByConversation,
|
|
6
|
-
} from "./ConversationHeader";
|
|
7
|
-
export type { ConversationGroupData } from "./ConversationHeader";
|
|
8
|
-
export { LogEntry } from "./LogEntry";
|
|
9
|
-
export { ThreadConnector } from "./ThreadConnector";
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { lazy } from "react";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Lazy-loaded heavy leaf components. Each is split into its own chunk by Vite
|
|
5
|
-
* (named after the source file) so the main bundle stays small. Imports use
|
|
6
|
-
* the `.then(m => ({ default: m.X }))` adapter so the original modules can
|
|
7
|
-
* keep their named exports without needing a default export.
|
|
8
|
-
*/
|
|
9
|
-
export const LazyCompareDrawer = lazy(() =>
|
|
10
|
-
import("./CompareDrawer").then((m) => ({ default: m.CompareDrawer })),
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
export const LazyInspectorPet = lazy(() =>
|
|
14
|
-
import("../inspector-pet/InspectorPet").then((m) => ({ default: m.InspectorPet })),
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
export const LazyReplayDialog = lazy(() =>
|
|
18
|
-
import("./ReplayDialog").then((m) => ({ default: m.ReplayDialog })),
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
export const LazyRequestAnatomy = lazy(() =>
|
|
22
|
-
import("./anatomy/RequestAnatomy").then((m) => ({ default: m.RequestAnatomy })),
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
export const LazyResponseView = lazy(() =>
|
|
26
|
-
import("./ResponseView").then((m) => ({ default: m.ResponseView })),
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
export const LazyStreamingChunkSequence = lazy(() =>
|
|
30
|
-
import("./StreamingChunkSequence").then((m) => ({
|
|
31
|
-
default: m.StreamingChunkSequence,
|
|
32
|
-
})),
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
export const LazyJsonViewer = lazy(() =>
|
|
36
|
-
import("../ui/json-viewer").then((m) => ({ default: m.JsonViewer })),
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
export const LazyJsonViewerFromString = lazy(() =>
|
|
40
|
-
import("../ui/json-viewer").then((m) => ({ default: m.JsonViewerFromString })),
|
|
41
|
-
);
|