@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,733 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
3
|
-
import { logger, resolveLogDir } from "./logger";
|
|
4
|
-
import {
|
|
5
|
-
ToolTraceEventSchema,
|
|
6
|
-
type ApiFormat,
|
|
7
|
-
type CaptureIncompleteReason,
|
|
8
|
-
type StopReason,
|
|
9
|
-
} from "./schemas";
|
|
10
|
-
import type { LogIndexEntry, LogIndexSummary } from "./logIndex";
|
|
11
|
-
import { ensurePrivateDirectorySync, securePrivateFileSync } from "./privateDataPath";
|
|
12
|
-
|
|
13
|
-
type SqliteState =
|
|
14
|
-
| { status: "ready"; db: unknown; path: string }
|
|
15
|
-
| { status: "unavailable"; path: string; reason: string };
|
|
16
|
-
|
|
17
|
-
const SQLITE_INDEX_FILE = "inspector.sqlite";
|
|
18
|
-
const SQLITE_PACKAGE_NAME = "better-sqlite3";
|
|
19
|
-
const BUN_SQLITE_MODULE_NAME = "bun:sqlite";
|
|
20
|
-
|
|
21
|
-
const CREATE_SCHEMA_SQL = `
|
|
22
|
-
CREATE TABLE IF NOT EXISTS log_index (
|
|
23
|
-
id INTEGER PRIMARY KEY,
|
|
24
|
-
file TEXT NOT NULL,
|
|
25
|
-
byte_offset INTEGER NOT NULL,
|
|
26
|
-
byte_length INTEGER NOT NULL,
|
|
27
|
-
session_id TEXT,
|
|
28
|
-
model TEXT,
|
|
29
|
-
timestamp TEXT NOT NULL,
|
|
30
|
-
method TEXT NOT NULL,
|
|
31
|
-
path TEXT NOT NULL,
|
|
32
|
-
response_status INTEGER,
|
|
33
|
-
input_tokens INTEGER,
|
|
34
|
-
output_tokens INTEGER,
|
|
35
|
-
cache_creation_input_tokens INTEGER,
|
|
36
|
-
cache_read_input_tokens INTEGER,
|
|
37
|
-
elapsed_ms INTEGER,
|
|
38
|
-
first_chunk_ms INTEGER,
|
|
39
|
-
total_stream_ms INTEGER,
|
|
40
|
-
tokens_per_second REAL,
|
|
41
|
-
streaming INTEGER NOT NULL,
|
|
42
|
-
user_agent TEXT,
|
|
43
|
-
origin TEXT,
|
|
44
|
-
api_format TEXT NOT NULL,
|
|
45
|
-
is_test INTEGER NOT NULL,
|
|
46
|
-
replay_of_log_id INTEGER,
|
|
47
|
-
provider_name TEXT,
|
|
48
|
-
client_port INTEGER,
|
|
49
|
-
client_pid INTEGER,
|
|
50
|
-
client_cwd TEXT,
|
|
51
|
-
client_project_folder TEXT,
|
|
52
|
-
streaming_chunks_path TEXT,
|
|
53
|
-
raw_request_body_bytes INTEGER,
|
|
54
|
-
response_text_bytes INTEGER,
|
|
55
|
-
capture_incomplete INTEGER NOT NULL DEFAULT 0,
|
|
56
|
-
dropped_chunks INTEGER NOT NULL DEFAULT 0,
|
|
57
|
-
dropped_bytes INTEGER NOT NULL DEFAULT 0,
|
|
58
|
-
capture_incomplete_reason TEXT,
|
|
59
|
-
warnings_json TEXT,
|
|
60
|
-
stop_reason TEXT,
|
|
61
|
-
tool_trace_events_json TEXT,
|
|
62
|
-
error TEXT
|
|
63
|
-
);
|
|
64
|
-
CREATE INDEX IF NOT EXISTS idx_log_index_session_id_id ON log_index(session_id, id);
|
|
65
|
-
CREATE INDEX IF NOT EXISTS idx_log_index_model_id ON log_index(model, id);
|
|
66
|
-
CREATE INDEX IF NOT EXISTS idx_log_index_timestamp ON log_index(timestamp);
|
|
67
|
-
`;
|
|
68
|
-
|
|
69
|
-
const UPSERT_SQL = `
|
|
70
|
-
INSERT INTO log_index (
|
|
71
|
-
id,
|
|
72
|
-
file,
|
|
73
|
-
byte_offset,
|
|
74
|
-
byte_length,
|
|
75
|
-
session_id,
|
|
76
|
-
model,
|
|
77
|
-
timestamp,
|
|
78
|
-
method,
|
|
79
|
-
path,
|
|
80
|
-
response_status,
|
|
81
|
-
input_tokens,
|
|
82
|
-
output_tokens,
|
|
83
|
-
cache_creation_input_tokens,
|
|
84
|
-
cache_read_input_tokens,
|
|
85
|
-
elapsed_ms,
|
|
86
|
-
first_chunk_ms,
|
|
87
|
-
total_stream_ms,
|
|
88
|
-
tokens_per_second,
|
|
89
|
-
streaming,
|
|
90
|
-
user_agent,
|
|
91
|
-
origin,
|
|
92
|
-
api_format,
|
|
93
|
-
is_test,
|
|
94
|
-
replay_of_log_id,
|
|
95
|
-
provider_name,
|
|
96
|
-
client_port,
|
|
97
|
-
client_pid,
|
|
98
|
-
client_cwd,
|
|
99
|
-
client_project_folder,
|
|
100
|
-
streaming_chunks_path,
|
|
101
|
-
raw_request_body_bytes,
|
|
102
|
-
response_text_bytes,
|
|
103
|
-
capture_incomplete,
|
|
104
|
-
dropped_chunks,
|
|
105
|
-
dropped_bytes,
|
|
106
|
-
capture_incomplete_reason,
|
|
107
|
-
warnings_json,
|
|
108
|
-
stop_reason,
|
|
109
|
-
tool_trace_events_json,
|
|
110
|
-
error
|
|
111
|
-
) VALUES (
|
|
112
|
-
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
|
113
|
-
)
|
|
114
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
115
|
-
file = excluded.file,
|
|
116
|
-
byte_offset = excluded.byte_offset,
|
|
117
|
-
byte_length = excluded.byte_length,
|
|
118
|
-
session_id = excluded.session_id,
|
|
119
|
-
model = excluded.model,
|
|
120
|
-
timestamp = excluded.timestamp,
|
|
121
|
-
method = excluded.method,
|
|
122
|
-
path = excluded.path,
|
|
123
|
-
response_status = excluded.response_status,
|
|
124
|
-
input_tokens = excluded.input_tokens,
|
|
125
|
-
output_tokens = excluded.output_tokens,
|
|
126
|
-
cache_creation_input_tokens = excluded.cache_creation_input_tokens,
|
|
127
|
-
cache_read_input_tokens = excluded.cache_read_input_tokens,
|
|
128
|
-
elapsed_ms = excluded.elapsed_ms,
|
|
129
|
-
first_chunk_ms = excluded.first_chunk_ms,
|
|
130
|
-
total_stream_ms = excluded.total_stream_ms,
|
|
131
|
-
tokens_per_second = excluded.tokens_per_second,
|
|
132
|
-
streaming = excluded.streaming,
|
|
133
|
-
user_agent = excluded.user_agent,
|
|
134
|
-
origin = excluded.origin,
|
|
135
|
-
api_format = excluded.api_format,
|
|
136
|
-
is_test = excluded.is_test,
|
|
137
|
-
replay_of_log_id = excluded.replay_of_log_id,
|
|
138
|
-
provider_name = excluded.provider_name,
|
|
139
|
-
client_port = excluded.client_port,
|
|
140
|
-
client_pid = excluded.client_pid,
|
|
141
|
-
client_cwd = excluded.client_cwd,
|
|
142
|
-
client_project_folder = excluded.client_project_folder,
|
|
143
|
-
streaming_chunks_path = excluded.streaming_chunks_path,
|
|
144
|
-
raw_request_body_bytes = excluded.raw_request_body_bytes,
|
|
145
|
-
response_text_bytes = excluded.response_text_bytes,
|
|
146
|
-
capture_incomplete = excluded.capture_incomplete,
|
|
147
|
-
dropped_chunks = excluded.dropped_chunks,
|
|
148
|
-
dropped_bytes = excluded.dropped_bytes,
|
|
149
|
-
capture_incomplete_reason = excluded.capture_incomplete_reason,
|
|
150
|
-
warnings_json = excluded.warnings_json,
|
|
151
|
-
stop_reason = excluded.stop_reason,
|
|
152
|
-
tool_trace_events_json = excluded.tool_trace_events_json,
|
|
153
|
-
error = excluded.error
|
|
154
|
-
`;
|
|
155
|
-
|
|
156
|
-
let sqliteStatePromise: Promise<SqliteState> | null = null;
|
|
157
|
-
let sqliteStatePath: string | null = null;
|
|
158
|
-
let activeDb: unknown | null = null;
|
|
159
|
-
let didLogUnavailable = false;
|
|
160
|
-
|
|
161
|
-
function isSqliteLogIndexEnabled(): boolean {
|
|
162
|
-
const configured = process.env["AGENT_INSPECTOR_SQLITE_INDEX"];
|
|
163
|
-
if (configured === "1") return true;
|
|
164
|
-
if (configured === "0") return false;
|
|
165
|
-
return process.env["NODE_ENV"] !== "test";
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function getSqlitePath(): string {
|
|
169
|
-
return join(resolveLogDir(), SQLITE_INDEX_FILE);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function objectFromUnknown(value: unknown): object | null {
|
|
173
|
-
if (value === null) return null;
|
|
174
|
-
if (typeof value === "object" || typeof value === "function") return value;
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function readProperty(value: unknown, name: string): unknown {
|
|
179
|
-
let current = objectFromUnknown(value);
|
|
180
|
-
while (current !== null) {
|
|
181
|
-
const desc = Object.getOwnPropertyDescriptor(current, name);
|
|
182
|
-
if (desc !== undefined) {
|
|
183
|
-
const propertyValue: unknown = Reflect.get(current, name);
|
|
184
|
-
return propertyValue;
|
|
185
|
-
}
|
|
186
|
-
const nextPrototype: unknown = Object.getPrototypeOf(current);
|
|
187
|
-
current = objectFromUnknown(nextPrototype);
|
|
188
|
-
}
|
|
189
|
-
return undefined;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function readFunction(value: unknown, name: string): Function | null {
|
|
193
|
-
const property = readProperty(value, name);
|
|
194
|
-
return typeof property === "function" ? property : null;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function callMethod(target: unknown, methodName: string, args: readonly unknown[]): unknown {
|
|
198
|
-
const method = readFunction(target, methodName);
|
|
199
|
-
if (method === null) return undefined;
|
|
200
|
-
try {
|
|
201
|
-
return Reflect.apply(method, target, [...args]);
|
|
202
|
-
} catch (err) {
|
|
203
|
-
logger.warn("[sqliteLogIndex] SQLite method failed:", methodName, String(err));
|
|
204
|
-
return undefined;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function prepareStatement(db: unknown, sql: string): unknown {
|
|
209
|
-
return callMethod(db, "prepare", [sql]);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function runPrepared(db: unknown, sql: string, params: readonly unknown[] = []): boolean {
|
|
213
|
-
const statement = prepareStatement(db, sql);
|
|
214
|
-
if (statement === undefined) return false;
|
|
215
|
-
const result = callMethod(statement, "run", params);
|
|
216
|
-
callMethod(statement, "finalize", []);
|
|
217
|
-
return result !== undefined;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function getPrepared(db: unknown, sql: string, params: readonly unknown[] = []): unknown {
|
|
221
|
-
const statement = prepareStatement(db, sql);
|
|
222
|
-
if (statement === undefined) return undefined;
|
|
223
|
-
const result = callMethod(statement, "get", params);
|
|
224
|
-
callMethod(statement, "finalize", []);
|
|
225
|
-
return result;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function allPrepared(db: unknown, sql: string, params: readonly unknown[] = []): unknown[] | null {
|
|
229
|
-
const statement = prepareStatement(db, sql);
|
|
230
|
-
if (statement === undefined) return null;
|
|
231
|
-
const result = callMethod(statement, "all", params);
|
|
232
|
-
callMethod(statement, "finalize", []);
|
|
233
|
-
return Array.isArray(result) ? result : null;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function execSql(db: unknown, sql: string): boolean {
|
|
237
|
-
const result = callMethod(db, "exec", [sql]);
|
|
238
|
-
return result !== undefined;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
const REQUIRED_SCHEMA_COLUMNS = [
|
|
242
|
-
{ name: "capture_incomplete", definition: "INTEGER NOT NULL DEFAULT 0" },
|
|
243
|
-
{ name: "dropped_chunks", definition: "INTEGER NOT NULL DEFAULT 0" },
|
|
244
|
-
{ name: "dropped_bytes", definition: "INTEGER NOT NULL DEFAULT 0" },
|
|
245
|
-
{ name: "capture_incomplete_reason", definition: "TEXT" },
|
|
246
|
-
{ name: "stop_reason", definition: "TEXT" },
|
|
247
|
-
{ name: "tool_trace_events_json", definition: "TEXT" },
|
|
248
|
-
];
|
|
249
|
-
|
|
250
|
-
function ensureSchemaColumns(db: unknown): boolean {
|
|
251
|
-
const rows = allPrepared(db, "PRAGMA table_info(log_index)");
|
|
252
|
-
if (rows === null) return false;
|
|
253
|
-
const existing = new Set<string>();
|
|
254
|
-
for (const row of rows) {
|
|
255
|
-
const name = readProperty(row, "name");
|
|
256
|
-
if (typeof name === "string") existing.add(name);
|
|
257
|
-
}
|
|
258
|
-
for (const column of REQUIRED_SCHEMA_COLUMNS) {
|
|
259
|
-
if (existing.has(column.name)) continue;
|
|
260
|
-
if (!execSql(db, `ALTER TABLE log_index ADD COLUMN ${column.name} ${column.definition}`)) {
|
|
261
|
-
return false;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return true;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
function sqliteConstructorFromModule(
|
|
268
|
-
moduleValue: unknown,
|
|
269
|
-
exportName: "default" | "Database",
|
|
270
|
-
): ((path: string) => unknown) | null {
|
|
271
|
-
const exportedValue = readProperty(moduleValue, exportName);
|
|
272
|
-
if (typeof exportedValue === "function") {
|
|
273
|
-
return (path: string): unknown => Reflect.construct(exportedValue, [path]);
|
|
274
|
-
}
|
|
275
|
-
return null;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
async function loadSqliteModuleConstructor(
|
|
279
|
-
moduleName: string,
|
|
280
|
-
exportName: "default" | "Database",
|
|
281
|
-
): Promise<{ constructor: ((path: string) => unknown) | null; reason: string | null }> {
|
|
282
|
-
try {
|
|
283
|
-
const importedModule: unknown = await import(/* @vite-ignore */ moduleName);
|
|
284
|
-
const exportedConstructor = sqliteConstructorFromModule(importedModule, exportName);
|
|
285
|
-
if (exportedConstructor !== null) return { constructor: exportedConstructor, reason: null };
|
|
286
|
-
if (exportName === "default" && typeof importedModule === "function") {
|
|
287
|
-
return {
|
|
288
|
-
constructor: (path: string): unknown => Reflect.construct(importedModule, [path]),
|
|
289
|
-
reason: null,
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
return { constructor: null, reason: `${moduleName} did not expose ${exportName}` };
|
|
293
|
-
} catch (err) {
|
|
294
|
-
return { constructor: null, reason: String(err) };
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
async function loadSqliteConstructor(): Promise<{
|
|
299
|
-
constructor: ((path: string) => unknown) | null;
|
|
300
|
-
reason: string | null;
|
|
301
|
-
}> {
|
|
302
|
-
const bunRuntimeDesc = Object.getOwnPropertyDescriptor(process.versions, "bun");
|
|
303
|
-
if (bunRuntimeDesc !== undefined) {
|
|
304
|
-
const bunSqlite = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
|
|
305
|
-
if (bunSqlite.constructor !== null) return bunSqlite;
|
|
306
|
-
|
|
307
|
-
const betterSqlite = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
|
|
308
|
-
if (betterSqlite.constructor !== null) return betterSqlite;
|
|
309
|
-
|
|
310
|
-
const reason = [bunSqlite.reason, betterSqlite.reason]
|
|
311
|
-
.filter((item): item is string => item !== null)
|
|
312
|
-
.join("; ");
|
|
313
|
-
if (!didLogUnavailable) {
|
|
314
|
-
didLogUnavailable = true;
|
|
315
|
-
logger.warn("[sqliteLogIndex] Optional SQLite index unavailable:", reason);
|
|
316
|
-
}
|
|
317
|
-
return { constructor: null, reason };
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
const betterSqlite = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
|
|
321
|
-
if (betterSqlite.constructor !== null) return betterSqlite;
|
|
322
|
-
|
|
323
|
-
const bunSqlite = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
|
|
324
|
-
if (bunSqlite.constructor !== null) return bunSqlite;
|
|
325
|
-
|
|
326
|
-
const reason = [betterSqlite.reason, bunSqlite.reason]
|
|
327
|
-
.filter((item): item is string => item !== null)
|
|
328
|
-
.join("; ");
|
|
329
|
-
if (!didLogUnavailable) {
|
|
330
|
-
didLogUnavailable = true;
|
|
331
|
-
logger.warn("[sqliteLogIndex] Optional SQLite index unavailable:", reason);
|
|
332
|
-
}
|
|
333
|
-
return { constructor: null, reason };
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
async function initializeSqliteState(): Promise<SqliteState> {
|
|
337
|
-
const path = getSqlitePath();
|
|
338
|
-
if (!isSqliteLogIndexEnabled()) {
|
|
339
|
-
return { status: "unavailable", path, reason: "SQLite log index is disabled" };
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const sqliteConstructor = await loadSqliteConstructor();
|
|
343
|
-
if (sqliteConstructor.constructor === null) {
|
|
344
|
-
return {
|
|
345
|
-
status: "unavailable",
|
|
346
|
-
path,
|
|
347
|
-
reason: sqliteConstructor.reason ?? "SQLite runtime is not available",
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
try {
|
|
352
|
-
if (!ensurePrivateDirectorySync(dirname(path))) {
|
|
353
|
-
return { status: "unavailable", path, reason: "SQLite index directory is not private" };
|
|
354
|
-
}
|
|
355
|
-
const db = sqliteConstructor.constructor(path);
|
|
356
|
-
execSql(db, "PRAGMA journal_mode = WAL");
|
|
357
|
-
execSql(db, "PRAGMA synchronous = NORMAL");
|
|
358
|
-
if (!securePrivateFileSync(path, true)) {
|
|
359
|
-
callMethod(db, "close", []);
|
|
360
|
-
return { status: "unavailable", path, reason: "SQLite index file is not private" };
|
|
361
|
-
}
|
|
362
|
-
for (const sidecarPath of [`${path}-wal`, `${path}-shm`]) {
|
|
363
|
-
if (existsSync(sidecarPath)) void securePrivateFileSync(sidecarPath);
|
|
364
|
-
}
|
|
365
|
-
if (!execSql(db, CREATE_SCHEMA_SQL)) {
|
|
366
|
-
return { status: "unavailable", path, reason: "SQLite schema initialization failed" };
|
|
367
|
-
}
|
|
368
|
-
if (!ensureSchemaColumns(db)) {
|
|
369
|
-
return { status: "unavailable", path, reason: "SQLite schema migration failed" };
|
|
370
|
-
}
|
|
371
|
-
activeDb = db;
|
|
372
|
-
return { status: "ready", db, path };
|
|
373
|
-
} catch (err) {
|
|
374
|
-
logger.warn("[sqliteLogIndex] Failed to initialize SQLite index:", String(err));
|
|
375
|
-
return { status: "unavailable", path, reason: String(err) };
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
async function getSqliteState(): Promise<SqliteState> {
|
|
380
|
-
const path = getSqlitePath();
|
|
381
|
-
if (sqliteStatePromise !== null && sqliteStatePath !== path) {
|
|
382
|
-
closeSqliteLogIndex();
|
|
383
|
-
}
|
|
384
|
-
if (sqliteStatePromise === null) {
|
|
385
|
-
sqliteStatePath = path;
|
|
386
|
-
sqliteStatePromise = initializeSqliteState();
|
|
387
|
-
}
|
|
388
|
-
return await sqliteStatePromise;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
/** Report only index availability; internal paths and failure reasons remain private. */
|
|
392
|
-
export async function isSqliteLogIndexReady(): Promise<boolean> {
|
|
393
|
-
const state = await getSqliteState();
|
|
394
|
-
return state.status === "ready";
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
export function closeSqliteLogIndex(): void {
|
|
398
|
-
if (activeDb !== null) {
|
|
399
|
-
callMethod(activeDb, "close", []);
|
|
400
|
-
}
|
|
401
|
-
activeDb = null;
|
|
402
|
-
sqliteStatePromise = null;
|
|
403
|
-
sqliteStatePath = null;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
function warningJson(warnings: string[] | undefined): string | null {
|
|
407
|
-
return warnings === undefined ? null : JSON.stringify(warnings);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
function toolTraceEventsJson(summary: LogIndexSummary | undefined): string | null {
|
|
411
|
-
return summary?.toolTraceEvents === undefined ? null : JSON.stringify(summary.toolTraceEvents);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
function boolToInt(value: boolean): number {
|
|
415
|
-
return value ? 1 : 0;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
function entryParams(entry: LogIndexEntry): readonly unknown[] {
|
|
419
|
-
const summary = entry.summary;
|
|
420
|
-
return [
|
|
421
|
-
entry.id,
|
|
422
|
-
entry.file,
|
|
423
|
-
entry.byteOffset,
|
|
424
|
-
entry.byteLength,
|
|
425
|
-
entry.sessionId ?? summary?.sessionId ?? null,
|
|
426
|
-
entry.model ?? summary?.model ?? null,
|
|
427
|
-
summary?.timestamp ?? "",
|
|
428
|
-
summary?.method ?? "",
|
|
429
|
-
summary?.path ?? "",
|
|
430
|
-
summary?.responseStatus ?? null,
|
|
431
|
-
summary?.inputTokens ?? null,
|
|
432
|
-
summary?.outputTokens ?? null,
|
|
433
|
-
summary?.cacheCreationInputTokens ?? null,
|
|
434
|
-
summary?.cacheReadInputTokens ?? null,
|
|
435
|
-
summary?.elapsedMs ?? null,
|
|
436
|
-
summary?.firstChunkMs ?? null,
|
|
437
|
-
summary?.totalStreamMs ?? null,
|
|
438
|
-
summary?.tokensPerSecond ?? null,
|
|
439
|
-
boolToInt(summary?.streaming ?? false),
|
|
440
|
-
summary?.userAgent ?? null,
|
|
441
|
-
summary?.origin ?? null,
|
|
442
|
-
summary?.apiFormat ?? "unknown",
|
|
443
|
-
boolToInt(summary?.isTest ?? false),
|
|
444
|
-
summary?.replayOfLogId ?? null,
|
|
445
|
-
summary?.providerName ?? null,
|
|
446
|
-
summary?.clientPort ?? null,
|
|
447
|
-
summary?.clientPid ?? null,
|
|
448
|
-
summary?.clientCwd ?? null,
|
|
449
|
-
summary?.clientProjectFolder ?? null,
|
|
450
|
-
summary?.streamingChunksPath ?? null,
|
|
451
|
-
summary?.rawRequestBodyBytes ?? null,
|
|
452
|
-
summary?.responseTextBytes ?? null,
|
|
453
|
-
boolToInt(summary?.captureIncomplete ?? false),
|
|
454
|
-
summary?.droppedChunks ?? 0,
|
|
455
|
-
summary?.droppedBytes ?? 0,
|
|
456
|
-
summary?.captureIncompleteReason ?? null,
|
|
457
|
-
warningJson(summary?.warnings),
|
|
458
|
-
summary?.stopReason ?? null,
|
|
459
|
-
toolTraceEventsJson(summary),
|
|
460
|
-
summary?.error ?? null,
|
|
461
|
-
];
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
function readNumber(row: unknown, name: string): number | null {
|
|
465
|
-
const value = readProperty(row, name);
|
|
466
|
-
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
function readString(row: unknown, name: string): string | null {
|
|
470
|
-
const value = readProperty(row, name);
|
|
471
|
-
return typeof value === "string" ? value : null;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
function readBoolean(row: unknown, name: string): boolean {
|
|
475
|
-
return readNumber(row, name) === 1;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
function readApiFormat(row: unknown): ApiFormat {
|
|
479
|
-
const value = readString(row, "api_format");
|
|
480
|
-
switch (value) {
|
|
481
|
-
case "anthropic":
|
|
482
|
-
return "anthropic";
|
|
483
|
-
case "openai":
|
|
484
|
-
return "openai";
|
|
485
|
-
case "unknown":
|
|
486
|
-
case null:
|
|
487
|
-
return "unknown";
|
|
488
|
-
default:
|
|
489
|
-
return "unknown";
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
function readCaptureIncompleteReason(row: unknown): CaptureIncompleteReason | null {
|
|
494
|
-
const value = readString(row, "capture_incomplete_reason");
|
|
495
|
-
switch (value) {
|
|
496
|
-
case "capacity-exceeded":
|
|
497
|
-
case "pipeline-closed":
|
|
498
|
-
case "write-failed":
|
|
499
|
-
case "finalize-failed":
|
|
500
|
-
case "upstream-stream-error":
|
|
501
|
-
case "shutdown":
|
|
502
|
-
return value;
|
|
503
|
-
case null:
|
|
504
|
-
default:
|
|
505
|
-
return null;
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
function readStopReason(row: unknown): StopReason | null {
|
|
510
|
-
const value = readString(row, "stop_reason");
|
|
511
|
-
switch (value) {
|
|
512
|
-
case "end_turn":
|
|
513
|
-
case "tool_use":
|
|
514
|
-
case "stop":
|
|
515
|
-
case "length":
|
|
516
|
-
return value;
|
|
517
|
-
case null:
|
|
518
|
-
default:
|
|
519
|
-
return null;
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
function readWarnings(row: unknown): string[] | undefined {
|
|
524
|
-
const value = readString(row, "warnings_json");
|
|
525
|
-
if (value === null) return undefined;
|
|
526
|
-
try {
|
|
527
|
-
const parsed: unknown = JSON.parse(value);
|
|
528
|
-
if (!Array.isArray(parsed)) return undefined;
|
|
529
|
-
const warnings: string[] = [];
|
|
530
|
-
for (const item of parsed) {
|
|
531
|
-
if (typeof item !== "string") return undefined;
|
|
532
|
-
warnings.push(item);
|
|
533
|
-
}
|
|
534
|
-
return warnings;
|
|
535
|
-
} catch {
|
|
536
|
-
return undefined;
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
function readToolTraceEvents(row: unknown): LogIndexSummary["toolTraceEvents"] {
|
|
541
|
-
const value = readString(row, "tool_trace_events_json");
|
|
542
|
-
if (value === null) return undefined;
|
|
543
|
-
try {
|
|
544
|
-
const parsed: unknown = JSON.parse(value);
|
|
545
|
-
const result = ToolTraceEventSchema.array().safeParse(parsed);
|
|
546
|
-
return result.success ? result.data : undefined;
|
|
547
|
-
} catch {
|
|
548
|
-
return undefined;
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
function readRequiredNumber(row: unknown, name: string): number | null {
|
|
553
|
-
const value = readNumber(row, name);
|
|
554
|
-
return value === null || !Number.isInteger(value) ? null : value;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
function summaryFromRow(row: unknown, id: number): LogIndexSummary {
|
|
558
|
-
return {
|
|
559
|
-
id,
|
|
560
|
-
timestamp: readString(row, "timestamp") ?? "",
|
|
561
|
-
method: readString(row, "method") ?? "",
|
|
562
|
-
path: readString(row, "path") ?? "",
|
|
563
|
-
model: readString(row, "model"),
|
|
564
|
-
sessionId: readString(row, "session_id"),
|
|
565
|
-
responseStatus: readNumber(row, "response_status"),
|
|
566
|
-
inputTokens: readNumber(row, "input_tokens"),
|
|
567
|
-
outputTokens: readNumber(row, "output_tokens"),
|
|
568
|
-
cacheCreationInputTokens: readNumber(row, "cache_creation_input_tokens"),
|
|
569
|
-
cacheReadInputTokens: readNumber(row, "cache_read_input_tokens"),
|
|
570
|
-
elapsedMs: readNumber(row, "elapsed_ms"),
|
|
571
|
-
firstChunkMs: readNumber(row, "first_chunk_ms"),
|
|
572
|
-
totalStreamMs: readNumber(row, "total_stream_ms"),
|
|
573
|
-
tokensPerSecond: readNumber(row, "tokens_per_second"),
|
|
574
|
-
streaming: readBoolean(row, "streaming"),
|
|
575
|
-
userAgent: readString(row, "user_agent"),
|
|
576
|
-
origin: readString(row, "origin"),
|
|
577
|
-
apiFormat: readApiFormat(row),
|
|
578
|
-
isTest: readBoolean(row, "is_test"),
|
|
579
|
-
replayOfLogId: readNumber(row, "replay_of_log_id"),
|
|
580
|
-
providerName: readString(row, "provider_name"),
|
|
581
|
-
clientPort: readNumber(row, "client_port"),
|
|
582
|
-
clientPid: readNumber(row, "client_pid"),
|
|
583
|
-
clientCwd: readString(row, "client_cwd"),
|
|
584
|
-
clientProjectFolder: readString(row, "client_project_folder"),
|
|
585
|
-
streamingChunksPath: readString(row, "streaming_chunks_path"),
|
|
586
|
-
rawRequestBodyBytes: readNumber(row, "raw_request_body_bytes"),
|
|
587
|
-
responseTextBytes: readNumber(row, "response_text_bytes"),
|
|
588
|
-
captureIncomplete: readBoolean(row, "capture_incomplete"),
|
|
589
|
-
droppedChunks: readNumber(row, "dropped_chunks") ?? 0,
|
|
590
|
-
droppedBytes: readNumber(row, "dropped_bytes") ?? 0,
|
|
591
|
-
captureIncompleteReason: readCaptureIncompleteReason(row),
|
|
592
|
-
warnings: readWarnings(row),
|
|
593
|
-
stopReason: readStopReason(row),
|
|
594
|
-
toolTraceEvents: readToolTraceEvents(row),
|
|
595
|
-
error: readString(row, "error"),
|
|
596
|
-
};
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
function entryFromRow(row: unknown): LogIndexEntry | null {
|
|
600
|
-
const id = readRequiredNumber(row, "id");
|
|
601
|
-
const file = readString(row, "file");
|
|
602
|
-
const byteOffset = readRequiredNumber(row, "byte_offset");
|
|
603
|
-
const byteLength = readRequiredNumber(row, "byte_length");
|
|
604
|
-
if (id === null || file === null || byteOffset === null || byteLength === null) return null;
|
|
605
|
-
return {
|
|
606
|
-
id,
|
|
607
|
-
file,
|
|
608
|
-
byteOffset,
|
|
609
|
-
byteLength,
|
|
610
|
-
sessionId: readString(row, "session_id"),
|
|
611
|
-
model: readString(row, "model"),
|
|
612
|
-
summary: summaryFromRow(row, id),
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
export async function getSqliteLogIndexMaxId(): Promise<number | null> {
|
|
617
|
-
const state = await getSqliteState();
|
|
618
|
-
if (state.status !== "ready") return null;
|
|
619
|
-
const row = getPrepared(state.db, "SELECT MAX(id) AS max_id FROM log_index");
|
|
620
|
-
return readNumber(row, "max_id") ?? 0;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
export async function upsertSqliteLogIndexEntry(entry: LogIndexEntry): Promise<boolean> {
|
|
624
|
-
if (entry.summary === undefined) return false;
|
|
625
|
-
const state = await getSqliteState();
|
|
626
|
-
if (state.status !== "ready") return false;
|
|
627
|
-
return runPrepared(state.db, UPSERT_SQL, entryParams(entry));
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
export type SqliteLogCursorEntryFilters = {
|
|
631
|
-
sessionId?: string;
|
|
632
|
-
model?: string;
|
|
633
|
-
clientPid?: number;
|
|
634
|
-
};
|
|
635
|
-
|
|
636
|
-
function sqliteCursorWhereClause(filters: SqliteLogCursorEntryFilters): {
|
|
637
|
-
sql: string;
|
|
638
|
-
params: unknown[];
|
|
639
|
-
} {
|
|
640
|
-
const clauses: string[] = [];
|
|
641
|
-
const params: unknown[] = [];
|
|
642
|
-
if (filters.sessionId !== undefined) {
|
|
643
|
-
clauses.push("session_id = ?");
|
|
644
|
-
params.push(filters.sessionId);
|
|
645
|
-
}
|
|
646
|
-
if (filters.model !== undefined) {
|
|
647
|
-
clauses.push("model = ?");
|
|
648
|
-
params.push(filters.model);
|
|
649
|
-
}
|
|
650
|
-
if (filters.clientPid !== undefined) {
|
|
651
|
-
clauses.push("client_pid = ?");
|
|
652
|
-
params.push(filters.clientPid);
|
|
653
|
-
}
|
|
654
|
-
return {
|
|
655
|
-
sql: clauses.length === 0 ? "" : ` WHERE ${clauses.join(" AND ")}`,
|
|
656
|
-
params,
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
export async function listSqliteLogCursorEntries(
|
|
661
|
-
filters: SqliteLogCursorEntryFilters,
|
|
662
|
-
): Promise<LogIndexEntry[] | null> {
|
|
663
|
-
const state = await getSqliteState();
|
|
664
|
-
if (state.status !== "ready") return null;
|
|
665
|
-
const where = sqliteCursorWhereClause(filters);
|
|
666
|
-
const rows = allPrepared(
|
|
667
|
-
state.db,
|
|
668
|
-
`SELECT * FROM log_index${where.sql} ORDER BY id ASC`,
|
|
669
|
-
where.params,
|
|
670
|
-
);
|
|
671
|
-
if (rows === null) return null;
|
|
672
|
-
const entries: LogIndexEntry[] = [];
|
|
673
|
-
for (const row of rows) {
|
|
674
|
-
const entry = entryFromRow(row);
|
|
675
|
-
if (entry === null || entry.summary === undefined) return null;
|
|
676
|
-
entries.push(entry);
|
|
677
|
-
}
|
|
678
|
-
return entries;
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
export async function syncSqliteLogIndexEntries(
|
|
682
|
-
entries: readonly LogIndexEntry[],
|
|
683
|
-
): Promise<boolean> {
|
|
684
|
-
const state = await getSqliteState();
|
|
685
|
-
if (state.status !== "ready") return false;
|
|
686
|
-
if (entries.length === 0) return true;
|
|
687
|
-
|
|
688
|
-
if (!execSql(state.db, "BEGIN IMMEDIATE")) return false;
|
|
689
|
-
try {
|
|
690
|
-
for (const entry of entries) {
|
|
691
|
-
if (entry.summary === undefined) continue;
|
|
692
|
-
if (!runPrepared(state.db, UPSERT_SQL, entryParams(entry))) {
|
|
693
|
-
execSql(state.db, "ROLLBACK");
|
|
694
|
-
return false;
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
return execSql(state.db, "COMMIT");
|
|
699
|
-
} catch (err) {
|
|
700
|
-
execSql(state.db, "ROLLBACK");
|
|
701
|
-
logger.warn("[sqliteLogIndex] Failed to sync SQLite index:", String(err));
|
|
702
|
-
return false;
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
export async function replaceSqliteLogIndexEntries(
|
|
707
|
-
entries: readonly LogIndexEntry[],
|
|
708
|
-
): Promise<boolean> {
|
|
709
|
-
const state = await getSqliteState();
|
|
710
|
-
if (state.status !== "ready") return false;
|
|
711
|
-
|
|
712
|
-
if (!execSql(state.db, "BEGIN IMMEDIATE")) return false;
|
|
713
|
-
try {
|
|
714
|
-
if (!runPrepared(state.db, "DELETE FROM log_index")) {
|
|
715
|
-
execSql(state.db, "ROLLBACK");
|
|
716
|
-
return false;
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
for (const entry of entries) {
|
|
720
|
-
if (entry.summary === undefined) continue;
|
|
721
|
-
if (!runPrepared(state.db, UPSERT_SQL, entryParams(entry))) {
|
|
722
|
-
execSql(state.db, "ROLLBACK");
|
|
723
|
-
return false;
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
return execSql(state.db, "COMMIT");
|
|
728
|
-
} catch (err) {
|
|
729
|
-
execSql(state.db, "ROLLBACK");
|
|
730
|
-
logger.warn("[sqliteLogIndex] Failed to replace SQLite index:", String(err));
|
|
731
|
-
return false;
|
|
732
|
-
}
|
|
733
|
-
}
|