@tonyclaw/agent-inspector 4.0.1 → 4.0.2
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 +192 -109
- package/.output/server/_ssr/index.mjs +1 -1
- package/.output/server/_ssr/{router-CTHqmroT.mjs → router-BBY_zWRK.mjs} +91 -3
- package/.output/server/index.mjs +1 -1
- package/.output/ui/assets/{CompareDrawer-L3n4J-Or.js → CompareDrawer-rtNElN-B.js} +1 -1
- package/.output/ui/assets/{InspectorPet-D5o_3OZS.js → InspectorPet-QaAiuF3d.js} +1 -1
- package/.output/ui/assets/{ProxyViewerContainer-Ocagx75S.js → ProxyViewerContainer-6twNZHwl.js} +4 -4
- package/.output/ui/assets/{ReplayDialog-Bk7x1h-y.js → ReplayDialog-B7KlziO2.js} +1 -1
- package/.output/ui/assets/{RequestAnatomy-U4lzL7Sc.js → RequestAnatomy-2XVFBrW4.js} +1 -1
- package/.output/ui/assets/{ResponseView-LOWfvBLK.js → ResponseView-BULgzLVB.js} +1 -1
- package/.output/ui/assets/{StreamingChunkSequence-DPfsrrXQ.js → StreamingChunkSequence-DSkvkbns.js} +1 -1
- package/.output/ui/assets/{_sessionId-OdX2Jvt1.js → _sessionId-D2dmJi3G.js} +1 -1
- package/.output/ui/assets/{_sessionId-0MlWS-CO.js → _sessionId-DcS0s1Mr.js} +1 -1
- package/.output/ui/assets/{index-Du4qNOOt.js → index-B0TN1KKO.js} +2 -2
- package/.output/ui/assets/{index-gvFj_9K6.js → index-Bva1zHEs.js} +1 -1
- package/.output/ui/assets/{index-Ea-c8hPg.js → index-BzBExOxu.js} +1 -1
- package/.output/ui/assets/{index-zVVS53Hd.js → index-k6sRQz55.js} +1 -1
- package/.output/ui/assets/{json-viewer-C1WAMzg3.js → json-viewer-CWM4tY-j.js} +1 -1
- package/.output/ui/assets/{jszip.min-B8AKu2zm.js → jszip.min-BkWvRFlo.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,158 +0,0 @@
|
|
|
1
|
-
export type LiveConnectionPhase =
|
|
2
|
-
| "connecting"
|
|
3
|
-
| "live"
|
|
4
|
-
| "reconnecting"
|
|
5
|
-
| "stale"
|
|
6
|
-
| "offline"
|
|
7
|
-
| "error";
|
|
8
|
-
|
|
9
|
-
export type LiveConnectionState = {
|
|
10
|
-
status: LiveConnectionPhase;
|
|
11
|
-
lastSuccessAt: number | null;
|
|
12
|
-
retryCount: number;
|
|
13
|
-
errorMessage: string | null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type LiveConnectionEvent =
|
|
17
|
-
| { type: "connect-requested" }
|
|
18
|
-
| { type: "message-received"; at: number }
|
|
19
|
-
| { type: "connection-lost"; online: boolean; message: string }
|
|
20
|
-
| { type: "stale-timeout" }
|
|
21
|
-
| { type: "browser-offline" }
|
|
22
|
-
| { type: "stop-retrying" }
|
|
23
|
-
| { type: "recoverable-error"; message: string };
|
|
24
|
-
|
|
25
|
-
export function createInitialLiveConnectionState(): LiveConnectionState {
|
|
26
|
-
return {
|
|
27
|
-
status: "connecting",
|
|
28
|
-
lastSuccessAt: null,
|
|
29
|
-
retryCount: 0,
|
|
30
|
-
errorMessage: null,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function reduceLiveConnectionState(
|
|
35
|
-
state: LiveConnectionState,
|
|
36
|
-
event: LiveConnectionEvent,
|
|
37
|
-
): LiveConnectionState {
|
|
38
|
-
switch (event.type) {
|
|
39
|
-
case "connect-requested":
|
|
40
|
-
return {
|
|
41
|
-
...state,
|
|
42
|
-
status:
|
|
43
|
-
state.lastSuccessAt === null
|
|
44
|
-
? "connecting"
|
|
45
|
-
: state.status === "stale"
|
|
46
|
-
? "stale"
|
|
47
|
-
: "reconnecting",
|
|
48
|
-
errorMessage: null,
|
|
49
|
-
};
|
|
50
|
-
case "message-received":
|
|
51
|
-
return {
|
|
52
|
-
status: "live",
|
|
53
|
-
lastSuccessAt: event.at,
|
|
54
|
-
retryCount: 0,
|
|
55
|
-
errorMessage: null,
|
|
56
|
-
};
|
|
57
|
-
case "connection-lost": {
|
|
58
|
-
const retryCount = state.retryCount + 1;
|
|
59
|
-
if (!event.online) {
|
|
60
|
-
return {
|
|
61
|
-
...state,
|
|
62
|
-
status: "offline",
|
|
63
|
-
retryCount,
|
|
64
|
-
errorMessage: "Browser is offline.",
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
...state,
|
|
69
|
-
status: state.lastSuccessAt === null ? "error" : "reconnecting",
|
|
70
|
-
retryCount,
|
|
71
|
-
errorMessage: event.message,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
case "stale-timeout":
|
|
75
|
-
if (state.lastSuccessAt === null || state.status === "live" || state.status === "offline") {
|
|
76
|
-
return state;
|
|
77
|
-
}
|
|
78
|
-
return { ...state, status: "stale" };
|
|
79
|
-
case "browser-offline":
|
|
80
|
-
return {
|
|
81
|
-
...state,
|
|
82
|
-
status: "offline",
|
|
83
|
-
errorMessage: "Browser is offline.",
|
|
84
|
-
};
|
|
85
|
-
case "stop-retrying":
|
|
86
|
-
return {
|
|
87
|
-
...state,
|
|
88
|
-
status: "offline",
|
|
89
|
-
errorMessage: "Automatic live updates are paused.",
|
|
90
|
-
};
|
|
91
|
-
case "recoverable-error":
|
|
92
|
-
return {
|
|
93
|
-
...state,
|
|
94
|
-
status: "error",
|
|
95
|
-
errorMessage: event.message,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export type LiveEmptyState =
|
|
101
|
-
| "connecting"
|
|
102
|
-
| "empty"
|
|
103
|
-
| "reconnecting"
|
|
104
|
-
| "stale"
|
|
105
|
-
| "offline"
|
|
106
|
-
| "error";
|
|
107
|
-
|
|
108
|
-
export function resolveLiveEmptyState(state: LiveConnectionState | undefined): LiveEmptyState {
|
|
109
|
-
if (state === undefined || state.status === "live") return "empty";
|
|
110
|
-
return state.status;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export type LiveEmptyStateCopy = {
|
|
114
|
-
title: string;
|
|
115
|
-
description: string;
|
|
116
|
-
showConnectionCommands: boolean;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
export function getLiveEmptyStateCopy(state: LiveEmptyState): LiveEmptyStateCopy {
|
|
120
|
-
switch (state) {
|
|
121
|
-
case "connecting":
|
|
122
|
-
return {
|
|
123
|
-
title: "Connecting to the live stream...",
|
|
124
|
-
description: "Waiting for the first successful initialization before checking for logs.",
|
|
125
|
-
showConnectionCommands: false,
|
|
126
|
-
};
|
|
127
|
-
case "empty":
|
|
128
|
-
return {
|
|
129
|
-
title: "No logs captured yet.",
|
|
130
|
-
description: "Connect an AI coding tool to capture its first request.",
|
|
131
|
-
showConnectionCommands: true,
|
|
132
|
-
};
|
|
133
|
-
case "reconnecting":
|
|
134
|
-
return {
|
|
135
|
-
title: "Reconnecting to live updates...",
|
|
136
|
-
description: "The stream was interrupted. Agent Inspector is retrying automatically.",
|
|
137
|
-
showConnectionCommands: false,
|
|
138
|
-
};
|
|
139
|
-
case "stale":
|
|
140
|
-
return {
|
|
141
|
-
title: "Live data is stale.",
|
|
142
|
-
description: "No logs are hidden; retry the connection to resume live updates.",
|
|
143
|
-
showConnectionCommands: false,
|
|
144
|
-
};
|
|
145
|
-
case "offline":
|
|
146
|
-
return {
|
|
147
|
-
title: "Live updates are offline.",
|
|
148
|
-
description: "Check the browser and Inspector connection, then retry.",
|
|
149
|
-
showConnectionCommands: false,
|
|
150
|
-
};
|
|
151
|
-
case "error":
|
|
152
|
-
return {
|
|
153
|
-
title: "Live updates could not initialize.",
|
|
154
|
-
description: "The error is recoverable. Retry without reloading the page.",
|
|
155
|
-
showConnectionCommands: false,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { AnthropicRequestSchema, AnthropicResponseSchema } from "../../../contracts/anthropic";
|
|
2
|
-
import type { AnatomySegment } from "../anatomy/types";
|
|
3
|
-
import { countCharacters, estimateTokens } from "../anatomy/tokenEstimate";
|
|
4
|
-
import { parseRequestTools } from "../requestTools";
|
|
5
|
-
import type { LogFormatAdapter } from "./types";
|
|
6
|
-
import { emptyRequestAnalysis, EMPTY_RESPONSE_ANALYSIS } from "./types";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Flatten an Anthropic `content` field to the text used for token
|
|
10
|
-
* estimation. The function never throws: unknown content shapes are
|
|
11
|
-
* treated as empty. We deliberately do NOT use JSON.stringify on the
|
|
12
|
-
* content because base64 image data would dominate the size.
|
|
13
|
-
*/
|
|
14
|
-
function contentToText(content: unknown): string {
|
|
15
|
-
if (typeof content === "string") return content;
|
|
16
|
-
if (!Array.isArray(content)) return "";
|
|
17
|
-
const parts: string[] = [];
|
|
18
|
-
for (const block of content) {
|
|
19
|
-
if (block === null || typeof block !== "object") continue;
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
21
|
-
const b = block as Record<string, unknown>;
|
|
22
|
-
const type = b.type;
|
|
23
|
-
switch (type) {
|
|
24
|
-
case "text":
|
|
25
|
-
if (typeof b.text === "string") parts.push(b.text);
|
|
26
|
-
break;
|
|
27
|
-
case "thinking":
|
|
28
|
-
case "think":
|
|
29
|
-
if (typeof b.thinking === "string") parts.push(b.thinking);
|
|
30
|
-
break;
|
|
31
|
-
case "tool_use": {
|
|
32
|
-
const name = typeof b.name === "string" ? b.name : "";
|
|
33
|
-
const input = b.input !== undefined ? JSON.stringify(b.input) : "";
|
|
34
|
-
parts.push(`${name} ${input}`.trim());
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
case "tool_result": {
|
|
38
|
-
const inner = b.content;
|
|
39
|
-
if (typeof inner === "string") {
|
|
40
|
-
parts.push(inner);
|
|
41
|
-
} else if (Array.isArray(inner)) {
|
|
42
|
-
for (const item of inner) {
|
|
43
|
-
if (item !== null && typeof item === "object") {
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
45
|
-
const t = (item as Record<string, unknown>).text;
|
|
46
|
-
if (typeof t === "string") parts.push(t);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
case "image":
|
|
53
|
-
// Skip base64 payload but record the image type so the segment is not empty.
|
|
54
|
-
parts.push("[image]");
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return parts.join("\n");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/** Flatten an Anthropic `system` value to its text. The API accepts
|
|
62
|
-
* either a string or an array of text blocks. */
|
|
63
|
-
function systemToText(system: unknown): string {
|
|
64
|
-
if (typeof system === "string") return system;
|
|
65
|
-
if (!Array.isArray(system)) return "";
|
|
66
|
-
const parts: string[] = [];
|
|
67
|
-
for (const block of system) {
|
|
68
|
-
if (block !== null && typeof block === "object") {
|
|
69
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
70
|
-
const t = (block as { type?: unknown; text?: unknown }).text;
|
|
71
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
72
|
-
const type = (block as { type?: unknown }).type;
|
|
73
|
-
if (type === "text" && typeof t === "string") parts.push(t);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return parts.join("\n");
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** Flatten Anthropic `tools` array to its schema text. */
|
|
80
|
-
function toolsToText(tools: unknown): string {
|
|
81
|
-
if (!Array.isArray(tools)) return "";
|
|
82
|
-
const parts: string[] = [];
|
|
83
|
-
for (const tool of tools) {
|
|
84
|
-
if (tool === null || typeof tool !== "object") continue;
|
|
85
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
86
|
-
const t = tool as { name?: unknown; description?: unknown; input_schema?: unknown };
|
|
87
|
-
if (typeof t.name === "string") parts.push(t.name);
|
|
88
|
-
if (typeof t.description === "string") parts.push(t.description);
|
|
89
|
-
if (t.input_schema !== undefined) parts.push(JSON.stringify(t.input_schema));
|
|
90
|
-
}
|
|
91
|
-
return parts.join("\n");
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** Build one segment from a piece of text + a stable label and path. */
|
|
95
|
-
function segment(
|
|
96
|
-
role: AnatomySegment["role"],
|
|
97
|
-
label: string,
|
|
98
|
-
text: string,
|
|
99
|
-
path: string,
|
|
100
|
-
): AnatomySegment {
|
|
101
|
-
return {
|
|
102
|
-
role,
|
|
103
|
-
label,
|
|
104
|
-
text,
|
|
105
|
-
size: estimateTokens(text),
|
|
106
|
-
characters: countCharacters(text),
|
|
107
|
-
path,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export const anthropicLogFormatAdapter: LogFormatAdapter = {
|
|
112
|
-
format: "anthropic",
|
|
113
|
-
|
|
114
|
-
analyzeRequest(rawBody) {
|
|
115
|
-
if (rawBody === null) return emptyRequestAnalysis(rawBody);
|
|
116
|
-
try {
|
|
117
|
-
const parsedBody: unknown = JSON.parse(rawBody);
|
|
118
|
-
const toolCount = parseRequestTools(parsedBody)?.tools.length ?? null;
|
|
119
|
-
const result = AnthropicRequestSchema.safeParse(parsedBody);
|
|
120
|
-
if (!result.success) return emptyRequestAnalysis(rawBody);
|
|
121
|
-
return {
|
|
122
|
-
parsed: result.data,
|
|
123
|
-
comparisonValue: result.data,
|
|
124
|
-
messageCount: result.data.messages.length,
|
|
125
|
-
toolCount,
|
|
126
|
-
};
|
|
127
|
-
} catch {
|
|
128
|
-
return emptyRequestAnalysis(rawBody);
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
|
|
132
|
-
analyzeResponse(responseText) {
|
|
133
|
-
if (responseText === null) return EMPTY_RESPONSE_ANALYSIS;
|
|
134
|
-
try {
|
|
135
|
-
let json: unknown = JSON.parse(responseText);
|
|
136
|
-
if (typeof json === "string") json = JSON.parse(json);
|
|
137
|
-
const result = AnthropicResponseSchema.safeParse(json);
|
|
138
|
-
if (!result.success) return EMPTY_RESPONSE_ANALYSIS;
|
|
139
|
-
const toolNames = result.data.content
|
|
140
|
-
.filter((block) => block.type === "tool_use")
|
|
141
|
-
.map((block) => block.name);
|
|
142
|
-
return {
|
|
143
|
-
parsed: result.data,
|
|
144
|
-
toolNames: toolNames.length > 0 ? toolNames : null,
|
|
145
|
-
};
|
|
146
|
-
} catch {
|
|
147
|
-
return EMPTY_RESPONSE_ANALYSIS;
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
anatomySegments(parsed) {
|
|
152
|
-
if (parsed === null || typeof parsed !== "object") return null;
|
|
153
|
-
// We deliberately skip AnthropicRequestSchema validation here:
|
|
154
|
-
// real Anthropic requests accept `system` as either a string or
|
|
155
|
-
// an array, and we want the Context view to render even when the
|
|
156
|
-
// body shape is slightly off-schema (e.g. system: "string" vs
|
|
157
|
-
// system: [{type:"text",text:"..."}]).
|
|
158
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
159
|
-
const body = parsed as {
|
|
160
|
-
system?: unknown;
|
|
161
|
-
messages?: unknown;
|
|
162
|
-
tools?: unknown;
|
|
163
|
-
};
|
|
164
|
-
const segments: AnatomySegment[] = [];
|
|
165
|
-
|
|
166
|
-
if (body.system !== undefined) {
|
|
167
|
-
const text = systemToText(body.system);
|
|
168
|
-
if (text.length > 0) {
|
|
169
|
-
segments.push(segment("system", "system", text, "/system"));
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (Array.isArray(body.messages)) {
|
|
174
|
-
body.messages.forEach((message, index) => {
|
|
175
|
-
if (message === null || typeof message !== "object") return;
|
|
176
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
177
|
-
const m = message as { role?: unknown; content?: unknown };
|
|
178
|
-
const role = m.role === "user" || m.role === "assistant" ? m.role : "user";
|
|
179
|
-
const text = contentToText(m.content);
|
|
180
|
-
segments.push(segment(role, `[${index}] ${role}`, text, `/messages/${index}`));
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (Array.isArray(body.tools) && body.tools.length > 0) {
|
|
185
|
-
const text = toolsToText(body.tools);
|
|
186
|
-
segments.push(segment("tools", "tools", text, "/tools"));
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return segments.length > 0 ? segments : null;
|
|
190
|
-
},
|
|
191
|
-
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { apiFormatForPath } from "../../../lib/apiFormat";
|
|
2
|
-
import type { ApiFormat, CapturedLog } from "../../../contracts";
|
|
3
|
-
import { anthropicLogFormatAdapter } from "./anthropic";
|
|
4
|
-
import { openAILogFormatAdapter } from "./openai";
|
|
5
|
-
import type { LogFormatAdapter } from "./types";
|
|
6
|
-
import { unknownLogFormatAdapter } from "./unknown";
|
|
7
|
-
|
|
8
|
-
const ADAPTERS: Record<ApiFormat, LogFormatAdapter> = {
|
|
9
|
-
anthropic: anthropicLogFormatAdapter,
|
|
10
|
-
openai: openAILogFormatAdapter,
|
|
11
|
-
unknown: unknownLogFormatAdapter,
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export function getLogFormatAdapter(format: ApiFormat): LogFormatAdapter {
|
|
15
|
-
return ADAPTERS[format];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function resolveLogFormat(log: Pick<CapturedLog, "path" | "apiFormat">): ApiFormat {
|
|
19
|
-
const pathFormat = apiFormatForPath(log.path);
|
|
20
|
-
return pathFormat === "unknown" ? log.apiFormat : pathFormat;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type { LogFormatAdapter, RequestAnalysis, ResponseAnalysis } from "./types";
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
OpenAIRequestSchema,
|
|
3
|
-
OpenAIResponsesRequestSchema,
|
|
4
|
-
parseOpenAIResponsesResponse,
|
|
5
|
-
parseOpenAIResponse,
|
|
6
|
-
} from "../../../contracts/openai";
|
|
7
|
-
import { safeGetOwnProperty } from "../../../lib/objectUtils";
|
|
8
|
-
import type { AnatomySegment } from "../anatomy/types";
|
|
9
|
-
import { countCharacters, estimateTokens } from "../anatomy/tokenEstimate";
|
|
10
|
-
import { parseRequestTools } from "../requestTools";
|
|
11
|
-
import type { LogFormatAdapter } from "./types";
|
|
12
|
-
import { emptyRequestAnalysis, EMPTY_RESPONSE_ANALYSIS } from "./types";
|
|
13
|
-
|
|
14
|
-
type OpenAIMessageContent = string | ReadonlyArray<Record<string, unknown>> | null | undefined;
|
|
15
|
-
|
|
16
|
-
/** Flatten an OpenAI `content` field to its text representation. */
|
|
17
|
-
function contentToText(content: unknown): string {
|
|
18
|
-
if (typeof content === "string") return content;
|
|
19
|
-
if (!Array.isArray(content)) return "";
|
|
20
|
-
const parts: string[] = [];
|
|
21
|
-
for (const block of content) {
|
|
22
|
-
if (block === null || typeof block !== "object") continue;
|
|
23
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
24
|
-
const b = block as Record<string, unknown>;
|
|
25
|
-
const type = b.type;
|
|
26
|
-
if (
|
|
27
|
-
(type === "text" || type === "input_text" || type === "output_text") &&
|
|
28
|
-
typeof b.text === "string"
|
|
29
|
-
) {
|
|
30
|
-
parts.push(b.text);
|
|
31
|
-
} else if (type === "image_url" || type === "input_image") {
|
|
32
|
-
parts.push("[image]");
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return parts.join("\n");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Flatten an OpenAI message to text — content plus optional tool calls plus optional reasoning. */
|
|
39
|
-
function messageToText(message: Record<string, unknown>): string {
|
|
40
|
-
const parts: string[] = [];
|
|
41
|
-
const text = contentToText(message.content);
|
|
42
|
-
if (text.length > 0) parts.push(text);
|
|
43
|
-
const reasoning =
|
|
44
|
-
typeof message.reasoning_content === "string"
|
|
45
|
-
? message.reasoning_content
|
|
46
|
-
: typeof message.thinking === "string"
|
|
47
|
-
? message.thinking
|
|
48
|
-
: typeof message.think === "string"
|
|
49
|
-
? message.think
|
|
50
|
-
: "";
|
|
51
|
-
if (reasoning.length > 0) parts.push(reasoning);
|
|
52
|
-
const toolCalls = message.tool_calls;
|
|
53
|
-
if (Array.isArray(toolCalls)) {
|
|
54
|
-
for (const call of toolCalls) {
|
|
55
|
-
if (call === null || typeof call !== "object") continue;
|
|
56
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
57
|
-
const fn = (call as { function?: { name?: unknown; arguments?: unknown } }).function;
|
|
58
|
-
if (fn === undefined) continue;
|
|
59
|
-
const name = typeof fn.name === "string" ? fn.name : "";
|
|
60
|
-
const args = typeof fn.arguments === "string" ? fn.arguments : "";
|
|
61
|
-
parts.push(`${name} ${args}`.trim());
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return parts.join("\n");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** Flatten an OpenAI `tools` array to its schema text. */
|
|
68
|
-
function toolsToText(tools: unknown): string {
|
|
69
|
-
if (!Array.isArray(tools)) return "";
|
|
70
|
-
const parts: string[] = [];
|
|
71
|
-
for (const tool of tools) {
|
|
72
|
-
if (tool === null || typeof tool !== "object") continue;
|
|
73
|
-
const fn = safeGetOwnProperty(tool, "function");
|
|
74
|
-
const name = safeGetOwnProperty(fn, "name") ?? safeGetOwnProperty(tool, "name");
|
|
75
|
-
const description =
|
|
76
|
-
safeGetOwnProperty(fn, "description") ?? safeGetOwnProperty(tool, "description");
|
|
77
|
-
const parameters =
|
|
78
|
-
safeGetOwnProperty(fn, "parameters") ?? safeGetOwnProperty(tool, "parameters");
|
|
79
|
-
if (typeof name === "string") parts.push(name);
|
|
80
|
-
if (typeof description === "string") parts.push(description);
|
|
81
|
-
if (parameters !== undefined) parts.push(JSON.stringify(parameters));
|
|
82
|
-
}
|
|
83
|
-
return parts.join("\n");
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function countResponsesInput(input: unknown): number | null {
|
|
87
|
-
if (typeof input === "string") return input.length > 0 ? 1 : 0;
|
|
88
|
-
if (Array.isArray(input)) return input.length;
|
|
89
|
-
if (input === undefined || input === null) return null;
|
|
90
|
-
return 1;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function responsesInputItemToText(input: unknown): string {
|
|
94
|
-
if (typeof input === "string") return input;
|
|
95
|
-
const directText = safeGetOwnProperty(input, "text");
|
|
96
|
-
if (typeof directText === "string") return directText;
|
|
97
|
-
const contentText = contentToText(safeGetOwnProperty(input, "content"));
|
|
98
|
-
if (contentText.length > 0) return contentText;
|
|
99
|
-
const outputText = contentToText(safeGetOwnProperty(input, "output"));
|
|
100
|
-
if (outputText.length > 0) return outputText;
|
|
101
|
-
const argumentsText = safeGetOwnProperty(input, "arguments");
|
|
102
|
-
return typeof argumentsText === "string" ? argumentsText : "";
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function responsesInputRole(input: unknown): AnatomySegment["role"] {
|
|
106
|
-
const role = safeGetOwnProperty(input, "role");
|
|
107
|
-
if (role === "system" || role === "user" || role === "assistant" || role === "tool") {
|
|
108
|
-
return role;
|
|
109
|
-
}
|
|
110
|
-
const type = safeGetOwnProperty(input, "type");
|
|
111
|
-
if (type === "function_call_output") return "tool";
|
|
112
|
-
if (type === "message") return "user";
|
|
113
|
-
return "user";
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function responsesToolNames(response: unknown): string[] {
|
|
117
|
-
const output = safeGetOwnProperty(response, "output");
|
|
118
|
-
if (!Array.isArray(output)) return [];
|
|
119
|
-
const names: string[] = [];
|
|
120
|
-
for (const item of output) {
|
|
121
|
-
if (safeGetOwnProperty(item, "type") !== "function_call") continue;
|
|
122
|
-
const name = safeGetOwnProperty(item, "name");
|
|
123
|
-
if (typeof name === "string" && name.length > 0) names.push(name);
|
|
124
|
-
}
|
|
125
|
-
return names;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function segment(
|
|
129
|
-
role: AnatomySegment["role"],
|
|
130
|
-
label: string,
|
|
131
|
-
text: string,
|
|
132
|
-
path: string,
|
|
133
|
-
): AnatomySegment {
|
|
134
|
-
return {
|
|
135
|
-
role,
|
|
136
|
-
label,
|
|
137
|
-
text,
|
|
138
|
-
size: estimateTokens(text),
|
|
139
|
-
characters: countCharacters(text),
|
|
140
|
-
path,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export const openAILogFormatAdapter: LogFormatAdapter = {
|
|
145
|
-
format: "openai",
|
|
146
|
-
|
|
147
|
-
analyzeRequest(rawBody) {
|
|
148
|
-
if (rawBody === null) return emptyRequestAnalysis(rawBody);
|
|
149
|
-
try {
|
|
150
|
-
const parsedBody: unknown = JSON.parse(rawBody);
|
|
151
|
-
const toolCount = parseRequestTools(parsedBody)?.tools.length ?? null;
|
|
152
|
-
const result = OpenAIRequestSchema.safeParse(parsedBody);
|
|
153
|
-
if (!result.success) {
|
|
154
|
-
const responsesResult = OpenAIResponsesRequestSchema.safeParse(parsedBody);
|
|
155
|
-
if (!responsesResult.success) return emptyRequestAnalysis(rawBody);
|
|
156
|
-
return {
|
|
157
|
-
parsed: responsesResult.data,
|
|
158
|
-
comparisonValue: responsesResult.data,
|
|
159
|
-
messageCount: countResponsesInput(responsesResult.data.input),
|
|
160
|
-
toolCount,
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
return {
|
|
164
|
-
parsed: result.data,
|
|
165
|
-
comparisonValue: result.data,
|
|
166
|
-
messageCount: result.data.messages.length,
|
|
167
|
-
toolCount,
|
|
168
|
-
};
|
|
169
|
-
} catch {
|
|
170
|
-
return emptyRequestAnalysis(rawBody);
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
|
|
174
|
-
analyzeResponse(responseText) {
|
|
175
|
-
if (responseText === null) return EMPTY_RESPONSE_ANALYSIS;
|
|
176
|
-
const parsed = parseOpenAIResponse(responseText);
|
|
177
|
-
if (parsed === null) {
|
|
178
|
-
const responsesParsed = parseOpenAIResponsesResponse(responseText);
|
|
179
|
-
if (responsesParsed === null) return EMPTY_RESPONSE_ANALYSIS;
|
|
180
|
-
const toolNames = responsesToolNames(responsesParsed);
|
|
181
|
-
return {
|
|
182
|
-
parsed: responsesParsed,
|
|
183
|
-
toolNames: toolNames.length > 0 ? toolNames : null,
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
const toolNames =
|
|
187
|
-
parsed.choices[0]?.message?.tool_calls
|
|
188
|
-
?.map((toolCall) => toolCall.function?.name ?? "")
|
|
189
|
-
.filter((name) => name !== "") ?? [];
|
|
190
|
-
return {
|
|
191
|
-
parsed,
|
|
192
|
-
toolNames: toolNames.length > 0 ? toolNames : null,
|
|
193
|
-
};
|
|
194
|
-
},
|
|
195
|
-
|
|
196
|
-
anatomySegments(parsed) {
|
|
197
|
-
if (parsed === null || typeof parsed !== "object") return null;
|
|
198
|
-
// We deliberately skip OpenAIRequestSchema validation here for the
|
|
199
|
-
// same reason as the Anthropic adapter: the Context view should
|
|
200
|
-
// render even when the body shape is slightly off-schema. We only
|
|
201
|
-
// need the top-level `messages` and `tools` arrays.
|
|
202
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
203
|
-
const body = parsed as {
|
|
204
|
-
messages?: unknown;
|
|
205
|
-
input?: unknown;
|
|
206
|
-
instructions?: unknown;
|
|
207
|
-
tools?: unknown;
|
|
208
|
-
};
|
|
209
|
-
const segments: AnatomySegment[] = [];
|
|
210
|
-
|
|
211
|
-
if (typeof body.instructions === "string" && body.instructions.length > 0) {
|
|
212
|
-
segments.push(segment("system", "instructions", body.instructions, "/instructions"));
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// Promote a leading role: "system" message into a "system" segment.
|
|
216
|
-
// Spec: derive system role from a leading role: "system" message, then
|
|
217
|
-
// a segment per remaining message. We still keep the system message in
|
|
218
|
-
// the segment list (not skipped) when there is no separate system field
|
|
219
|
-
// to compare against — the leading role: "system" message IS the system
|
|
220
|
-
// content for OpenAI Chat Completions. If a separate `system` field
|
|
221
|
-
// existed and matched the message, we would dedupe, but Chat
|
|
222
|
-
// Completions has no such field, so we never have to skip.
|
|
223
|
-
if (Array.isArray(body.messages)) {
|
|
224
|
-
body.messages.forEach((message, index) => {
|
|
225
|
-
if (message === null || typeof message !== "object") return;
|
|
226
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
227
|
-
const m = message as { role?: unknown; content?: unknown };
|
|
228
|
-
const role =
|
|
229
|
-
m.role === "user" || m.role === "assistant" || m.role === "system" || m.role === "tool"
|
|
230
|
-
? m.role
|
|
231
|
-
: "user";
|
|
232
|
-
const text = messageToText(m);
|
|
233
|
-
segments.push(segment(role, `[${index}] ${role}`, text, `/messages/${index}`));
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (!Array.isArray(body.messages)) {
|
|
238
|
-
if (typeof body.input === "string" && body.input.length > 0) {
|
|
239
|
-
segments.push(segment("user", "input", body.input, "/input"));
|
|
240
|
-
} else if (Array.isArray(body.input)) {
|
|
241
|
-
body.input.forEach((item, index) => {
|
|
242
|
-
const role = responsesInputRole(item);
|
|
243
|
-
const text = responsesInputItemToText(item);
|
|
244
|
-
segments.push(segment(role, `[${index}] ${role}`, text, `/input/${index}`));
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (Array.isArray(body.tools) && body.tools.length > 0) {
|
|
250
|
-
const text = toolsToText(body.tools);
|
|
251
|
-
segments.push(segment("tools", "tools", text, "/tools"));
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
return segments.length > 0 ? segments : null;
|
|
255
|
-
},
|
|
256
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { ApiFormat } from "../../../contracts";
|
|
2
|
-
import type { AnatomySegment } from "../anatomy/types";
|
|
3
|
-
|
|
4
|
-
export type RequestAnalysis = {
|
|
5
|
-
parsed: unknown | null;
|
|
6
|
-
comparisonValue: unknown;
|
|
7
|
-
messageCount: number | null;
|
|
8
|
-
toolCount: number | null;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type ResponseAnalysis = {
|
|
12
|
-
parsed: unknown | null;
|
|
13
|
-
toolNames: string[] | null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type LogFormatAdapter = {
|
|
17
|
-
readonly format: ApiFormat;
|
|
18
|
-
analyzeRequest(rawBody: string | null): RequestAnalysis;
|
|
19
|
-
analyzeResponse(responseText: string | null): ResponseAnalysis;
|
|
20
|
-
/**
|
|
21
|
-
* Derive the ordered list of segments shown in the Context tab for a
|
|
22
|
-
* parsed request body. Returns `null` when the body is `null` or fails
|
|
23
|
-
* the format's schema (e.g. unknown format).
|
|
24
|
-
*/
|
|
25
|
-
anatomySegments(parsed: unknown): AnatomySegment[] | null;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export function emptyRequestAnalysis(rawBody: string | null): RequestAnalysis {
|
|
29
|
-
return {
|
|
30
|
-
parsed: null,
|
|
31
|
-
comparisonValue: rawBody,
|
|
32
|
-
messageCount: null,
|
|
33
|
-
toolCount: null,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const EMPTY_RESPONSE_ANALYSIS: ResponseAnalysis = {
|
|
38
|
-
parsed: null,
|
|
39
|
-
toolNames: null,
|
|
40
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { LogFormatAdapter } from "./types";
|
|
2
|
-
import { emptyRequestAnalysis, EMPTY_RESPONSE_ANALYSIS } from "./types";
|
|
3
|
-
|
|
4
|
-
export const unknownLogFormatAdapter: LogFormatAdapter = {
|
|
5
|
-
format: "unknown",
|
|
6
|
-
|
|
7
|
-
analyzeRequest(rawBody) {
|
|
8
|
-
return emptyRequestAnalysis(rawBody);
|
|
9
|
-
},
|
|
10
|
-
|
|
11
|
-
analyzeResponse() {
|
|
12
|
-
return EMPTY_RESPONSE_ANALYSIS;
|
|
13
|
-
},
|
|
14
|
-
|
|
15
|
-
anatomySegments() {
|
|
16
|
-
return null;
|
|
17
|
-
},
|
|
18
|
-
};
|