@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,100 +0,0 @@
|
|
|
1
|
-
export type ProviderTestMode = "non-streaming" | "streaming";
|
|
2
|
-
export type ProviderTestApiShape = "chat" | "responses";
|
|
3
|
-
|
|
4
|
-
export type ProviderTestMessage = {
|
|
5
|
-
role: "user";
|
|
6
|
-
content: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type ProviderTestChatRequestBody = {
|
|
10
|
-
model: string;
|
|
11
|
-
messages: ProviderTestMessage[];
|
|
12
|
-
max_tokens: number;
|
|
13
|
-
stream: boolean;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type ProviderTestResponsesRequestBody = {
|
|
17
|
-
model: string;
|
|
18
|
-
input: string;
|
|
19
|
-
max_output_tokens: number;
|
|
20
|
-
stream: boolean;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export type ProviderTestRequestBody =
|
|
24
|
-
| ProviderTestChatRequestBody
|
|
25
|
-
| ProviderTestResponsesRequestBody;
|
|
26
|
-
|
|
27
|
-
const MEMORY_PROBE_FACTS = [
|
|
28
|
-
"Project fact: Agent Inspector captures LLM traffic and turns it into Raw Trace, Session Episode, and Memory Candidate layers.",
|
|
29
|
-
"Procedure: before release, run bun test, npm run typecheck, npm run lint, npm run build, and openspec validate --all --strict.",
|
|
30
|
-
"Preference: the user prefers Chinese summaries, explicit verification, and commit/push/release closure when requested.",
|
|
31
|
-
"Pitfall: preserve .llm-inspector config compatibility; do not write raw logs or secrets into durable memory.",
|
|
32
|
-
"OpenClaw boundary: Agent Inspector owns L1-L3; OpenClaw owns durable indexing, retrieval, and recall.",
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
function modeInstruction(mode: ProviderTestMode): string {
|
|
36
|
-
switch (mode) {
|
|
37
|
-
case "non-streaming":
|
|
38
|
-
return "Reply in four concise bullets.";
|
|
39
|
-
case "streaming":
|
|
40
|
-
return "Reply in three concise bullets.";
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function maxTokensForMode(mode: ProviderTestMode): number {
|
|
45
|
-
switch (mode) {
|
|
46
|
-
case "non-streaming":
|
|
47
|
-
return 256;
|
|
48
|
-
case "streaming":
|
|
49
|
-
return 256;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function buildProviderTestUserPrompt(mode: ProviderTestMode): string {
|
|
54
|
-
return [
|
|
55
|
-
"You are validating an LLM provider connection for Agent Inspector.",
|
|
56
|
-
"This request includes a synthetic memory probe so Agent Inspector can verify its three Inspector-owned memory layers.",
|
|
57
|
-
"",
|
|
58
|
-
"Synthetic memory probe:",
|
|
59
|
-
...MEMORY_PROBE_FACTS.map((fact) => `- ${fact}`),
|
|
60
|
-
"",
|
|
61
|
-
"Return:",
|
|
62
|
-
"1. connection status",
|
|
63
|
-
"2. one project fact",
|
|
64
|
-
"3. one reusable procedure",
|
|
65
|
-
"4. one caution",
|
|
66
|
-
"",
|
|
67
|
-
modeInstruction(mode),
|
|
68
|
-
].join("\n");
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export function buildProviderTestMessages(mode: ProviderTestMode): ProviderTestMessage[] {
|
|
72
|
-
return [{ role: "user", content: buildProviderTestUserPrompt(mode) }];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function buildProviderTestRequestBody(
|
|
76
|
-
model: string,
|
|
77
|
-
mode: ProviderTestMode,
|
|
78
|
-
apiShape: ProviderTestApiShape = "chat",
|
|
79
|
-
): ProviderTestRequestBody {
|
|
80
|
-
if (apiShape === "responses") {
|
|
81
|
-
return {
|
|
82
|
-
model,
|
|
83
|
-
input: buildProviderTestUserPrompt(mode),
|
|
84
|
-
max_output_tokens: maxTokensForMode(mode),
|
|
85
|
-
stream: mode === "streaming",
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const base = {
|
|
90
|
-
model,
|
|
91
|
-
messages: buildProviderTestMessages(mode),
|
|
92
|
-
max_tokens: maxTokensForMode(mode),
|
|
93
|
-
};
|
|
94
|
-
switch (mode) {
|
|
95
|
-
case "non-streaming":
|
|
96
|
-
return { ...base, stream: false };
|
|
97
|
-
case "streaming":
|
|
98
|
-
return { ...base, stream: true };
|
|
99
|
-
}
|
|
100
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
-
import {
|
|
3
|
-
AGENT_INSPECTOR_PUBLIC_BASE_PATH_HEADER,
|
|
4
|
-
AGENT_INSPECTOR_PUBLIC_ORIGIN_HEADER,
|
|
5
|
-
AGENT_INSPECTOR_PUBLIC_PORT_HEADER,
|
|
6
|
-
getConfiguredBasePath,
|
|
7
|
-
normalizePublicBasePath,
|
|
8
|
-
} from "./basePath";
|
|
9
|
-
import { getCurrentPort } from "./serverPort";
|
|
10
|
-
|
|
11
|
-
type BasePathEnv = Readonly<Record<string, string | undefined>>;
|
|
12
|
-
|
|
13
|
-
type PublicRequestContext = {
|
|
14
|
-
basePath: string;
|
|
15
|
-
publicOrigin: string | null;
|
|
16
|
-
publicPort: number | null;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const publicRequestStorage = new AsyncLocalStorage<PublicRequestContext>();
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Resolve the public Base Path attached by the trusted ingress. Invalid or
|
|
23
|
-
* missing values fall back to the process's canonical Base Path.
|
|
24
|
-
*/
|
|
25
|
-
export function resolveRequestPublicBasePath(request: Request, env?: BasePathEnv): string {
|
|
26
|
-
const rawValue = request.headers.get(AGENT_INSPECTOR_PUBLIC_BASE_PATH_HEADER);
|
|
27
|
-
if (rawValue !== null) {
|
|
28
|
-
const normalized = normalizePublicBasePath(rawValue);
|
|
29
|
-
if (normalized !== null) return normalized;
|
|
30
|
-
}
|
|
31
|
-
return getConfiguredBasePath(env ?? process.env);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** Resolve the trusted ingress listener port without consulting request URL or Host. */
|
|
35
|
-
export function resolveRequestPublicPort(request: Request): number | null {
|
|
36
|
-
const rawValue = request.headers.get(AGENT_INSPECTOR_PUBLIC_PORT_HEADER);
|
|
37
|
-
if (rawValue !== null && /^\d{1,5}$/u.test(rawValue)) {
|
|
38
|
-
const headerPort = Number(rawValue);
|
|
39
|
-
if (Number.isSafeInteger(headerPort) && headerPort > 0 && headerPort <= 65_535) {
|
|
40
|
-
return headerPort;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
try {
|
|
44
|
-
return getCurrentPort();
|
|
45
|
-
} catch {
|
|
46
|
-
// Vite dev does not always publish its listener port through process env.
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
const urlPort = new URL(request.url).port;
|
|
50
|
-
if (!/^\d{1,5}$/u.test(urlPort)) return null;
|
|
51
|
-
const port = Number(urlPort);
|
|
52
|
-
return Number.isSafeInteger(port) && port > 0 && port <= 65_535 ? port : null;
|
|
53
|
-
} catch {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function normalizedPublicOrigin(value: string): string | null {
|
|
59
|
-
try {
|
|
60
|
-
const parsed = new URL(value);
|
|
61
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
|
|
62
|
-
if (parsed.username.length > 0 || parsed.password.length > 0) return null;
|
|
63
|
-
if (parsed.pathname !== "/" || parsed.search.length > 0 || parsed.hash.length > 0) return null;
|
|
64
|
-
return parsed.origin;
|
|
65
|
-
} catch {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** Resolve the public origin set by trusted ingress without consulting forwarded headers. */
|
|
71
|
-
export function resolveRequestPublicOrigin(request: Request): string | null {
|
|
72
|
-
const headerOrigin = request.headers.get(AGENT_INSPECTOR_PUBLIC_ORIGIN_HEADER);
|
|
73
|
-
if (headerOrigin !== null) return normalizedPublicOrigin(headerOrigin);
|
|
74
|
-
try {
|
|
75
|
-
return normalizedPublicOrigin(new URL(request.url).origin);
|
|
76
|
-
} catch {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** Return the originating request's public Base Path, or the canonical path outside a request. */
|
|
82
|
-
export function getPublicBasePath(env?: BasePathEnv): string {
|
|
83
|
-
return publicRequestStorage.getStore()?.basePath ?? getConfiguredBasePath(env ?? process.env);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/** Return the trusted ingress listener port, or the canonical process port outside a request. */
|
|
87
|
-
export function getPublicPort(): number {
|
|
88
|
-
return publicRequestStorage.getStore()?.publicPort ?? getCurrentPort();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** Return the trusted public origin, with a loopback fallback outside an ingress request. */
|
|
92
|
-
export function getPublicOrigin(): string {
|
|
93
|
-
return (
|
|
94
|
-
publicRequestStorage.getStore()?.publicOrigin ?? `http://localhost:${String(getCurrentPort())}`
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** Run work with an explicitly selected public Base Path. Primarily useful for internal calls. */
|
|
99
|
-
export function runWithPublicBasePath<T>(basePath: string, callback: () => T): T {
|
|
100
|
-
const current = publicRequestStorage.getStore();
|
|
101
|
-
const normalized = normalizePublicBasePath(basePath) ?? getConfiguredBasePath(process.env);
|
|
102
|
-
return publicRequestStorage.run(
|
|
103
|
-
{
|
|
104
|
-
basePath: normalized,
|
|
105
|
-
publicOrigin: current?.publicOrigin ?? null,
|
|
106
|
-
publicPort: current?.publicPort ?? null,
|
|
107
|
-
},
|
|
108
|
-
callback,
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/** Run work with an explicit trusted public listener port. */
|
|
113
|
-
export function runWithPublicPort<T>(publicPort: number, callback: () => T): T {
|
|
114
|
-
const current = publicRequestStorage.getStore();
|
|
115
|
-
const normalizedPort =
|
|
116
|
-
Number.isSafeInteger(publicPort) && publicPort > 0 && publicPort <= 65_535 ? publicPort : null;
|
|
117
|
-
return publicRequestStorage.run(
|
|
118
|
-
{
|
|
119
|
-
basePath: current?.basePath ?? getConfiguredBasePath(process.env),
|
|
120
|
-
publicOrigin: current?.publicOrigin ?? null,
|
|
121
|
-
publicPort: normalizedPort,
|
|
122
|
-
},
|
|
123
|
-
callback,
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/** Run the complete request chain with the ingress-selected public Base Path. */
|
|
128
|
-
export function runWithRequestPublicBasePath<T>(request: Request, callback: () => T): T {
|
|
129
|
-
return publicRequestStorage.run(
|
|
130
|
-
{
|
|
131
|
-
basePath: resolveRequestPublicBasePath(request),
|
|
132
|
-
publicOrigin: resolveRequestPublicOrigin(request),
|
|
133
|
-
publicPort: resolveRequestPublicPort(request),
|
|
134
|
-
},
|
|
135
|
-
callback,
|
|
136
|
-
);
|
|
137
|
-
}
|
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
export const MAX_REST_LOG_PAGE_SIZE = 200;
|
|
4
|
-
export const MAX_SEARCH_QUERY_CHARS = 512;
|
|
5
|
-
export const MAX_SEARCH_PROJECT_CHARS = 256;
|
|
6
|
-
export const MAX_PROVIDER_MODELS = 64;
|
|
7
|
-
export const MAX_PROVIDER_MODEL_NAME_CHARS = 256;
|
|
8
|
-
export const MAX_PROVIDER_MODEL_METADATA = 64;
|
|
9
|
-
export const MAX_SSE_CLIENTS = 32;
|
|
10
|
-
export const MAX_ACTIVE_PROVIDER_TESTS = 2;
|
|
11
|
-
export const MAX_PROVIDER_TEST_CONCURRENCY = 4;
|
|
12
|
-
export const MAX_ACTIVE_PROXY_REQUESTS = 16;
|
|
13
|
-
|
|
14
|
-
const positiveInteger = z.number().int().positive();
|
|
15
|
-
|
|
16
|
-
export const RuntimeBudgetPolicySchema = z
|
|
17
|
-
.object({
|
|
18
|
-
proxy: z.object({
|
|
19
|
-
requestBytes: positiveInteger,
|
|
20
|
-
responseBytes: positiveInteger,
|
|
21
|
-
headerBytes: positiveInteger,
|
|
22
|
-
deadlineMs: positiveInteger,
|
|
23
|
-
idleTimeoutMs: positiveInteger,
|
|
24
|
-
activeRequests: positiveInteger,
|
|
25
|
-
}),
|
|
26
|
-
control: z.object({
|
|
27
|
-
requestBytes: positiveInteger,
|
|
28
|
-
responseBytes: positiveInteger,
|
|
29
|
-
headerBytes: positiveInteger,
|
|
30
|
-
deadlineMs: positiveInteger,
|
|
31
|
-
idleTimeoutMs: positiveInteger,
|
|
32
|
-
activeRequests: positiveInteger,
|
|
33
|
-
}),
|
|
34
|
-
upstream: z.object({
|
|
35
|
-
fetchResponseBytes: positiveInteger,
|
|
36
|
-
fetchDeadlineMs: positiveInteger,
|
|
37
|
-
replayResponseBytes: positiveInteger,
|
|
38
|
-
replayDeadlineMs: positiveInteger,
|
|
39
|
-
metadataResponseBytes: positiveInteger,
|
|
40
|
-
metadataDeadlineMs: positiveInteger,
|
|
41
|
-
connectTimeoutMs: positiveInteger,
|
|
42
|
-
idleTimeoutMs: positiveInteger,
|
|
43
|
-
}),
|
|
44
|
-
pagination: z.object({
|
|
45
|
-
restPageSize: positiveInteger,
|
|
46
|
-
searchQueryChars: positiveInteger,
|
|
47
|
-
searchProjectChars: positiveInteger,
|
|
48
|
-
}),
|
|
49
|
-
sse: z.object({
|
|
50
|
-
clients: positiveInteger,
|
|
51
|
-
initLogs: positiveInteger,
|
|
52
|
-
heartbeatMs: positiveInteger,
|
|
53
|
-
}),
|
|
54
|
-
imports: z.object({
|
|
55
|
-
archiveBytes: positiveInteger,
|
|
56
|
-
entries: positiveInteger,
|
|
57
|
-
entryBytes: positiveInteger,
|
|
58
|
-
uncompressedBytes: positiveInteger,
|
|
59
|
-
expansionRatio: positiveInteger,
|
|
60
|
-
}),
|
|
61
|
-
fanOut: z.object({
|
|
62
|
-
providerModels: positiveInteger,
|
|
63
|
-
providerModelMetadata: positiveInteger,
|
|
64
|
-
providerTestConcurrency: positiveInteger,
|
|
65
|
-
activeProviderTests: positiveInteger,
|
|
66
|
-
}),
|
|
67
|
-
queues: z.object({
|
|
68
|
-
proxyRequests: positiveInteger,
|
|
69
|
-
finalizerJobs: positiveInteger,
|
|
70
|
-
rawStreamMessages: positiveInteger,
|
|
71
|
-
rawStreamBytes: positiveInteger,
|
|
72
|
-
backgroundWorkers: positiveInteger,
|
|
73
|
-
}),
|
|
74
|
-
})
|
|
75
|
-
.superRefine((policy, context) => {
|
|
76
|
-
if (policy.control.requestBytes > policy.proxy.requestBytes) {
|
|
77
|
-
context.addIssue({
|
|
78
|
-
code: "custom",
|
|
79
|
-
path: ["control", "requestBytes"],
|
|
80
|
-
message: "control request budget must not exceed proxy request budget",
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
if (policy.control.responseBytes > policy.proxy.responseBytes) {
|
|
84
|
-
context.addIssue({
|
|
85
|
-
code: "custom",
|
|
86
|
-
path: ["control", "responseBytes"],
|
|
87
|
-
message: "control response budget must not exceed proxy response budget",
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
if (policy.control.activeRequests > policy.proxy.activeRequests) {
|
|
91
|
-
context.addIssue({
|
|
92
|
-
code: "custom",
|
|
93
|
-
path: ["control", "activeRequests"],
|
|
94
|
-
message: "control active request budget must not exceed proxy active request budget",
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
if (policy.upstream.fetchResponseBytes > policy.proxy.responseBytes) {
|
|
98
|
-
context.addIssue({
|
|
99
|
-
code: "custom",
|
|
100
|
-
path: ["upstream", "fetchResponseBytes"],
|
|
101
|
-
message: "upstream fetch response budget must not exceed proxy response budget",
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
if (policy.upstream.replayResponseBytes > policy.proxy.responseBytes) {
|
|
105
|
-
context.addIssue({
|
|
106
|
-
code: "custom",
|
|
107
|
-
path: ["upstream", "replayResponseBytes"],
|
|
108
|
-
message: "upstream replay response budget must not exceed proxy response budget",
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
if (policy.upstream.metadataResponseBytes > policy.control.responseBytes) {
|
|
112
|
-
context.addIssue({
|
|
113
|
-
code: "custom",
|
|
114
|
-
path: ["upstream", "metadataResponseBytes"],
|
|
115
|
-
message: "upstream metadata response budget must not exceed control response budget",
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
if (policy.upstream.metadataDeadlineMs > policy.control.deadlineMs) {
|
|
119
|
-
context.addIssue({
|
|
120
|
-
code: "custom",
|
|
121
|
-
path: ["upstream", "metadataDeadlineMs"],
|
|
122
|
-
message: "upstream metadata deadline must not exceed control deadline",
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
if (policy.queues.proxyRequests < policy.proxy.activeRequests) {
|
|
126
|
-
context.addIssue({
|
|
127
|
-
code: "custom",
|
|
128
|
-
path: ["queues", "proxyRequests"],
|
|
129
|
-
message: "proxy request queue budget must cover active proxy requests",
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
export type RuntimeBudgetPolicy = z.infer<typeof RuntimeBudgetPolicySchema>;
|
|
135
|
-
|
|
136
|
-
export const DEFAULT_RUNTIME_BUDGET_POLICY = RuntimeBudgetPolicySchema.parse({
|
|
137
|
-
proxy: {
|
|
138
|
-
requestBytes: 64 * 1024 * 1024,
|
|
139
|
-
responseBytes: 256 * 1024 * 1024,
|
|
140
|
-
headerBytes: 64 * 1024,
|
|
141
|
-
deadlineMs: 120_000,
|
|
142
|
-
idleTimeoutMs: 30_000,
|
|
143
|
-
activeRequests: MAX_ACTIVE_PROXY_REQUESTS,
|
|
144
|
-
},
|
|
145
|
-
control: {
|
|
146
|
-
requestBytes: 8 * 1024 * 1024,
|
|
147
|
-
responseBytes: 64 * 1024 * 1024,
|
|
148
|
-
headerBytes: 32 * 1024,
|
|
149
|
-
deadlineMs: 30_000,
|
|
150
|
-
idleTimeoutMs: 10_000,
|
|
151
|
-
activeRequests: 8,
|
|
152
|
-
},
|
|
153
|
-
upstream: {
|
|
154
|
-
fetchResponseBytes: 256 * 1024 * 1024,
|
|
155
|
-
fetchDeadlineMs: 120_000,
|
|
156
|
-
replayResponseBytes: 256 * 1024 * 1024,
|
|
157
|
-
replayDeadlineMs: 120_000,
|
|
158
|
-
metadataResponseBytes: 10 * 1024 * 1024,
|
|
159
|
-
metadataDeadlineMs: 30_000,
|
|
160
|
-
connectTimeoutMs: 10_000,
|
|
161
|
-
idleTimeoutMs: 30_000,
|
|
162
|
-
},
|
|
163
|
-
pagination: {
|
|
164
|
-
restPageSize: MAX_REST_LOG_PAGE_SIZE,
|
|
165
|
-
searchQueryChars: MAX_SEARCH_QUERY_CHARS,
|
|
166
|
-
searchProjectChars: MAX_SEARCH_PROJECT_CHARS,
|
|
167
|
-
},
|
|
168
|
-
sse: {
|
|
169
|
-
clients: MAX_SSE_CLIENTS,
|
|
170
|
-
initLogs: 500,
|
|
171
|
-
heartbeatMs: 15_000,
|
|
172
|
-
},
|
|
173
|
-
imports: {
|
|
174
|
-
archiveBytes: 64 * 1024 * 1024,
|
|
175
|
-
entries: 5_000,
|
|
176
|
-
entryBytes: 32 * 1024 * 1024,
|
|
177
|
-
uncompressedBytes: 256 * 1024 * 1024,
|
|
178
|
-
expansionRatio: 20,
|
|
179
|
-
},
|
|
180
|
-
fanOut: {
|
|
181
|
-
providerModels: MAX_PROVIDER_MODELS,
|
|
182
|
-
providerModelMetadata: MAX_PROVIDER_MODEL_METADATA,
|
|
183
|
-
providerTestConcurrency: MAX_PROVIDER_TEST_CONCURRENCY,
|
|
184
|
-
activeProviderTests: MAX_ACTIVE_PROVIDER_TESTS,
|
|
185
|
-
},
|
|
186
|
-
queues: {
|
|
187
|
-
proxyRequests: MAX_ACTIVE_PROXY_REQUESTS,
|
|
188
|
-
finalizerJobs: 1_000,
|
|
189
|
-
rawStreamMessages: 16_384,
|
|
190
|
-
rawStreamBytes: 64 * 1024 * 1024,
|
|
191
|
-
backgroundWorkers: 4,
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
export function validateRuntimeBudgetPolicy(input: unknown): RuntimeBudgetPolicy {
|
|
196
|
-
return RuntimeBudgetPolicySchema.parse(input);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export function runtimeBudgetPolicySnapshot(
|
|
200
|
-
policy: RuntimeBudgetPolicy = DEFAULT_RUNTIME_BUDGET_POLICY,
|
|
201
|
-
): RuntimeBudgetPolicy {
|
|
202
|
-
return RuntimeBudgetPolicySchema.parse(policy);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
export const ResourceLimitErrorCodeSchema = z.enum([
|
|
206
|
-
"invalid-page-request",
|
|
207
|
-
"search-limit-exceeded",
|
|
208
|
-
"provider-model-limit-exceeded",
|
|
209
|
-
"sse-capacity-exceeded",
|
|
210
|
-
"provider-test-capacity-exceeded",
|
|
211
|
-
"proxy-capacity-exceeded",
|
|
212
|
-
]);
|
|
213
|
-
|
|
214
|
-
export const ResourceLimitStatusSchema = z.union([
|
|
215
|
-
z.literal(400),
|
|
216
|
-
z.literal(413),
|
|
217
|
-
z.literal(429),
|
|
218
|
-
z.literal(503),
|
|
219
|
-
]);
|
|
220
|
-
|
|
221
|
-
export const ResourceLimitErrorSchema = z.object({
|
|
222
|
-
error: z.string().min(1).max(300),
|
|
223
|
-
code: ResourceLimitErrorCodeSchema,
|
|
224
|
-
status: ResourceLimitStatusSchema,
|
|
225
|
-
resource: z.string().min(1).max(80),
|
|
226
|
-
limit: z.number().int().positive(),
|
|
227
|
-
retryable: z.boolean(),
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
export type ResourceLimitErrorCode = z.infer<typeof ResourceLimitErrorCodeSchema>;
|
|
231
|
-
export type ResourceLimitStatus = z.infer<typeof ResourceLimitStatusSchema>;
|
|
232
|
-
export type ResourceLimitError = z.infer<typeof ResourceLimitErrorSchema>;
|
|
233
|
-
|
|
234
|
-
export type ResourceLimitErrorInput = {
|
|
235
|
-
error: string;
|
|
236
|
-
code: ResourceLimitErrorCode;
|
|
237
|
-
status: ResourceLimitStatus;
|
|
238
|
-
resource: string;
|
|
239
|
-
limit: number;
|
|
240
|
-
retryable: boolean;
|
|
241
|
-
};
|
|
242
|
-
|
|
243
|
-
export function createResourceLimitError(input: ResourceLimitErrorInput): ResourceLimitError {
|
|
244
|
-
return ResourceLimitErrorSchema.parse(input);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
export function resourceLimitResponse(
|
|
248
|
-
input: ResourceLimitErrorInput & { retryAfterSeconds?: number },
|
|
249
|
-
): Response {
|
|
250
|
-
const body = createResourceLimitError(input);
|
|
251
|
-
const headers = new Headers({ "cache-control": "no-store" });
|
|
252
|
-
if (input.retryAfterSeconds !== undefined) {
|
|
253
|
-
headers.set("retry-after", String(input.retryAfterSeconds));
|
|
254
|
-
}
|
|
255
|
-
return Response.json(body, { status: input.status, headers });
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
type BoundedIntegerParameterInput = {
|
|
259
|
-
value: string | null;
|
|
260
|
-
parameter: string;
|
|
261
|
-
fallback: number;
|
|
262
|
-
minimum: number;
|
|
263
|
-
maximum: number;
|
|
264
|
-
resource: string;
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
export type BoundedIntegerParameterResult =
|
|
268
|
-
| { ok: true; value: number }
|
|
269
|
-
| { ok: false; response: Response };
|
|
270
|
-
|
|
271
|
-
export function parseBoundedIntegerParameter(
|
|
272
|
-
input: BoundedIntegerParameterInput,
|
|
273
|
-
): BoundedIntegerParameterResult {
|
|
274
|
-
if (input.value === null) return { ok: true, value: input.fallback };
|
|
275
|
-
|
|
276
|
-
const parsed = Number(input.value);
|
|
277
|
-
if (!Number.isSafeInteger(parsed) || parsed < input.minimum || parsed > input.maximum) {
|
|
278
|
-
return {
|
|
279
|
-
ok: false,
|
|
280
|
-
response: resourceLimitResponse({
|
|
281
|
-
error: `Query parameter "${input.parameter}" must be an integer between ${String(input.minimum)} and ${String(input.maximum)}.`,
|
|
282
|
-
code: "invalid-page-request",
|
|
283
|
-
status: 400,
|
|
284
|
-
resource: input.resource,
|
|
285
|
-
limit: input.maximum,
|
|
286
|
-
retryable: false,
|
|
287
|
-
}),
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return { ok: true, value: parsed };
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
export type CapacityLease = {
|
|
295
|
-
release: () => void;
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
export type CapacityLimiter = {
|
|
299
|
-
tryAcquire: () => CapacityLease | null;
|
|
300
|
-
activeCount: () => number;
|
|
301
|
-
capacity: number;
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
export function createCapacityLimiter(maxActive: number): CapacityLimiter {
|
|
305
|
-
const capacity = Number.isSafeInteger(maxActive) && maxActive > 0 ? maxActive : 1;
|
|
306
|
-
let active = 0;
|
|
307
|
-
|
|
308
|
-
return {
|
|
309
|
-
capacity,
|
|
310
|
-
activeCount: () => active,
|
|
311
|
-
tryAcquire: () => {
|
|
312
|
-
if (active >= capacity) return null;
|
|
313
|
-
active += 1;
|
|
314
|
-
let released = false;
|
|
315
|
-
return {
|
|
316
|
-
release: () => {
|
|
317
|
-
if (released) return;
|
|
318
|
-
released = true;
|
|
319
|
-
active = Math.max(0, active - 1);
|
|
320
|
-
},
|
|
321
|
-
};
|
|
322
|
-
},
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
export async function runWithConcurrencyLimit(
|
|
327
|
-
tasks: readonly (() => Promise<void>)[],
|
|
328
|
-
maxConcurrent: number,
|
|
329
|
-
): Promise<void> {
|
|
330
|
-
if (tasks.length === 0) return;
|
|
331
|
-
const concurrency = Number.isSafeInteger(maxConcurrent) && maxConcurrent > 0 ? maxConcurrent : 1;
|
|
332
|
-
const workerCount = Math.min(concurrency, tasks.length);
|
|
333
|
-
let nextIndex = 0;
|
|
334
|
-
|
|
335
|
-
const runWorker = async (): Promise<void> => {
|
|
336
|
-
while (nextIndex < tasks.length) {
|
|
337
|
-
const index = nextIndex;
|
|
338
|
-
nextIndex += 1;
|
|
339
|
-
const task = tasks[index];
|
|
340
|
-
if (task !== undefined) await task();
|
|
341
|
-
}
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
await Promise.all(Array.from({ length: workerCount }, runWorker));
|
|
345
|
-
}
|