@tonyclaw/agent-inspector 3.0.26 → 3.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.output/cli.js +80 -11
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-SZRUDQc9.js → CompareDrawer-TghZr5t1.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-BJvwOrSi.js → ProxyViewerContainer-fShBAZjj.js} +201 -201
- package/.output/public/assets/{ReplayDialog-DgfmqiM3.js → ReplayDialog-CZMApaF4.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-CS6c7Qfn.js → RequestAnatomy-DNWccR7O.js} +1 -1
- package/.output/public/assets/{ResponseView-C0Ri_5gm.js → ResponseView-d25MdFhY.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-7dYcHWyZ.js → StreamingChunkSequence-DIFZEnWe.js} +1 -1
- package/.output/public/assets/{_sessionId-D-V84cgw.js → _sessionId-DRfvuE2k.js} +1 -1
- package/.output/public/assets/{index-DgFWCxOs.js → index-B3aAuqWq.js} +1 -1
- package/.output/public/assets/index-BsxAGqMA.css +1 -0
- package/.output/public/assets/{index-DrVJsks2.js → index-D4HkS7Ct.js} +1 -1
- package/.output/public/assets/{index-CSIL7-MK.js → index-DzARL2Fi.js} +3 -3
- package/.output/public/assets/{json-viewer-C9Ji3gYN.js → json-viewer-wuJSKaed.js} +1 -1
- package/.output/server/_libs/lucide-react.mjs +39 -39
- package/.output/server/{_sessionId-BQ6YQOO1.mjs → _sessionId-BJTNiP_O.mjs} +4 -2
- package/.output/server/_ssr/{CompareDrawer-CqNzIeMR.mjs → CompareDrawer-BMRH3N97.mjs} +5 -3
- package/.output/server/_ssr/{ProxyViewerContainer-CMC7Vsbw.mjs → ProxyViewerContainer-AFwcHAIR.mjs} +330 -223
- package/.output/server/_ssr/{ReplayDialog-D9p_LaTr.mjs → ReplayDialog-CbWvRHiN.mjs} +6 -4
- package/.output/server/_ssr/{RequestAnatomy-B4ge3qNZ.mjs → RequestAnatomy-C4kcPyqN.mjs} +4 -2
- package/.output/server/_ssr/{ResponseView-BCqMKApI.mjs → ResponseView-D8VYt-gZ.mjs} +5 -3
- package/.output/server/_ssr/{StreamingChunkSequence-BA4zTLE4.mjs → StreamingChunkSequence-BUUo6vU0.mjs} +4 -2
- package/.output/server/_ssr/{index-CzxhDjlq.mjs → index-DTwMEEXO.mjs} +4 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-B3qV6iEJ.mjs → json-viewer-BqF1pSQD.mjs} +5 -3
- package/.output/server/_ssr/{router-CZe_R31M.mjs → router-C8BOns7y.mjs} +839 -368
- package/.output/server/{_tanstack-start-manifest_v-B50VTLrH.mjs → _tanstack-start-manifest_v-BBf2nRhb.mjs} +1 -1
- package/.output/server/index.mjs +70 -70
- package/README.md +8 -0
- package/package.json +4 -5
- package/src/cli.ts +43 -9
- package/src/components/ProxyViewer.tsx +57 -1
- package/src/components/clients/ClientLogo.tsx +43 -4
- package/src/components/inspector-pet/InspectorPet.tsx +0 -7
- package/src/components/providers/ProviderCard.tsx +3 -36
- package/src/components/providers/ProviderForm.tsx +13 -12
- package/src/components/providers/ProvidersPanel.tsx +2 -2
- package/src/components/providers/SettingsDialog.tsx +3 -3
- package/src/components/proxy-viewer/ConversationGroup.tsx +1 -1
- package/src/components/proxy-viewer/ConversationGroupList.tsx +233 -152
- package/src/components/proxy-viewer/ConversationHeader.tsx +29 -13
- package/src/components/proxy-viewer/ProviderLogoStack.tsx +0 -3
- package/src/contracts/anthropic.ts +0 -5
- package/src/contracts/index.ts +0 -4
- package/src/contracts/log.ts +0 -1
- package/src/contracts/openai.ts +0 -3
- package/src/knowledge/openclawClient.ts +22 -9
- package/src/knowledge/openclawGatewayClient.ts +20 -13
- package/src/lib/alertContract.ts +0 -3
- package/src/lib/ecosystemContract.ts +0 -3
- package/src/lib/export-logs.ts +1 -4
- package/src/lib/jsonFile.ts +46 -0
- package/src/lib/safeFetch.ts +100 -0
- package/src/lib/ssrfGuard.ts +133 -0
- package/src/lib/stopReason.ts +1 -4
- package/src/lib/unknown.ts +27 -0
- package/src/lib/useProviders.ts +1 -1
- package/src/mcp/mode.ts +3 -9
- package/src/mcp/server.ts +5 -14
- package/src/mcp/toolHandlers.ts +45 -54
- package/src/proxy/constants.ts +17 -0
- package/src/proxy/evidenceAnalysis.ts +116 -117
- package/src/proxy/formats/anthropic/handler.ts +5 -1
- package/src/proxy/formats/anthropic/schemas.ts +1 -7
- package/src/proxy/formats/index.ts +1 -1
- package/src/proxy/formats/openai/schemas.ts +0 -3
- package/src/proxy/formats/registry.ts +0 -3
- package/src/proxy/groupEvidenceExporter.ts +4 -8
- package/src/proxy/groupStore.ts +3 -10
- package/src/proxy/handler.ts +91 -12
- package/src/proxy/identityProxy.ts +74 -1
- package/src/proxy/logImporter.ts +82 -12
- package/src/proxy/logIndex.ts +1 -4
- package/src/proxy/providerSecretStore.ts +177 -0
- package/src/proxy/providers.ts +84 -11
- package/src/proxy/runFailures.ts +4 -10
- package/src/proxy/runStore.ts +4 -11
- package/src/proxy/schemas.ts +1 -8
- package/src/proxy/sqliteLogIndex.ts +0 -16
- package/src/proxy/store.ts +1 -5
- package/src/proxy/toolSchemaWarnings.ts +1 -9
- package/src/routes/api/logs.$id.replay.ts +17 -5
- package/src/routes/api/providers.$providerId.model-metadata.ts +11 -1
- package/src/routes/api/providers.$providerId.ts +18 -5
- package/src/routes/api/providers.ts +18 -7
- package/.output/public/assets/index-CmeF5XXS.css +0 -1
|
@@ -2,22 +2,16 @@ import { type JSX, useState } from "react";
|
|
|
2
2
|
import { Button } from "../ui/button";
|
|
3
3
|
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "../ui/tooltip";
|
|
4
4
|
import {
|
|
5
|
-
Eye,
|
|
6
|
-
EyeOff,
|
|
7
5
|
Pencil,
|
|
8
6
|
Trash2,
|
|
9
7
|
RotateCw,
|
|
10
8
|
CheckCircle,
|
|
11
9
|
ExternalLink,
|
|
12
10
|
Clock,
|
|
13
|
-
Copy,
|
|
14
|
-
Check,
|
|
15
11
|
ChevronDown,
|
|
16
12
|
ChevronRight,
|
|
17
13
|
} from "lucide-react";
|
|
18
14
|
import type { ProviderConfig } from "../../proxy/providers";
|
|
19
|
-
import { copyTextToClipboard } from "../../lib/clipboard";
|
|
20
|
-
import { maskApiKey } from "../../lib/mask";
|
|
21
15
|
import {
|
|
22
16
|
findProviderModelMetadata,
|
|
23
17
|
providerHasContextMetadata,
|
|
@@ -174,18 +168,8 @@ export function ProviderCard({
|
|
|
174
168
|
onRefreshMetadata,
|
|
175
169
|
isRefreshingMetadata = false,
|
|
176
170
|
}: ProviderCardProps): JSX.Element {
|
|
177
|
-
const [showApiKey, setShowApiKey] = useState(false);
|
|
178
|
-
const [copied, setCopied] = useState(false);
|
|
179
171
|
const [showDetails, setShowDetails] = useState(false);
|
|
180
172
|
|
|
181
|
-
function handleCopy() {
|
|
182
|
-
void copyTextToClipboard(provider.apiKey).then((success) => {
|
|
183
|
-
if (!success) return;
|
|
184
|
-
setCopied(true);
|
|
185
|
-
setTimeout(() => setCopied(false), 2000);
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
|
|
189
173
|
const docsUrl =
|
|
190
174
|
provider.apiDocsUrl ??
|
|
191
175
|
Object.entries(KNOWN_PROVIDER_DOCS).find(([keyword]) =>
|
|
@@ -285,26 +269,9 @@ export function ProviderCard({
|
|
|
285
269
|
|
|
286
270
|
{showDetails && (
|
|
287
271
|
<div className="space-y-3 border-t border-border/60 pt-3">
|
|
288
|
-
<div className="flex items-center gap-2">
|
|
289
|
-
<
|
|
290
|
-
|
|
291
|
-
</code>
|
|
292
|
-
<button
|
|
293
|
-
type="button"
|
|
294
|
-
onClick={() => setShowApiKey((s) => !s)}
|
|
295
|
-
className="p-1 text-muted-foreground transition-colors hover:text-foreground"
|
|
296
|
-
aria-label={showApiKey ? "Hide API key" : "Show API key"}
|
|
297
|
-
>
|
|
298
|
-
{showApiKey ? <EyeOff className="size-4" /> : <Eye className="size-4" />}
|
|
299
|
-
</button>
|
|
300
|
-
<button
|
|
301
|
-
type="button"
|
|
302
|
-
onClick={handleCopy}
|
|
303
|
-
className="p-1 text-muted-foreground transition-colors hover:text-foreground"
|
|
304
|
-
aria-label="Copy API key"
|
|
305
|
-
>
|
|
306
|
-
{copied ? <Check className="size-4 text-cyan-300" /> : <Copy className="size-4" />}
|
|
307
|
-
</button>
|
|
272
|
+
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
|
273
|
+
<CheckCircle className="size-3.5 text-emerald-500" />
|
|
274
|
+
<span>API key configured</span>
|
|
308
275
|
</div>
|
|
309
276
|
|
|
310
277
|
{provider.models !== undefined && provider.models.length > 0 && (
|
|
@@ -4,7 +4,6 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from ".
|
|
|
4
4
|
import { Eye, EyeOff, Copy, Check, ChevronDown } from "lucide-react";
|
|
5
5
|
import type { ProviderConfig, ProviderModelMetadata } from "../../lib/providerContract";
|
|
6
6
|
import { copyTextToClipboard } from "../../lib/clipboard";
|
|
7
|
-
import { maskApiKey } from "../../lib/mask";
|
|
8
7
|
import {
|
|
9
8
|
PATH_V1_CHAT_COMPLETIONS,
|
|
10
9
|
PATH_V1_MESSAGES,
|
|
@@ -327,7 +326,7 @@ function EndpointUrlPreview({
|
|
|
327
326
|
export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps): JSX.Element {
|
|
328
327
|
const initialCapabilities = deriveProviderCapabilities(provider);
|
|
329
328
|
const [name, setName] = useState(provider?.name ?? "");
|
|
330
|
-
const [apiKey, setApiKey] = useState(
|
|
329
|
+
const [apiKey, setApiKey] = useState("");
|
|
331
330
|
const [showApiKey, setShowApiKey] = useState(false);
|
|
332
331
|
const [copied, setCopied] = useState(false);
|
|
333
332
|
const initialModels = provider?.models;
|
|
@@ -411,7 +410,8 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
|
|
|
411
410
|
useEffect(() => {
|
|
412
411
|
if (provider) {
|
|
413
412
|
setName(provider.name);
|
|
414
|
-
setApiKey(
|
|
413
|
+
setApiKey("");
|
|
414
|
+
setShowApiKey(false);
|
|
415
415
|
const nextModels = (provider.models?.length ?? 0) > 0 ? provider.models : [""];
|
|
416
416
|
setModels(nextModels);
|
|
417
417
|
setModelMetadataDrafts(createMetadataDrafts(provider, nextModels));
|
|
@@ -482,7 +482,7 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
|
|
|
482
482
|
if (!name.trim()) {
|
|
483
483
|
newErrors.name = "Name is required";
|
|
484
484
|
}
|
|
485
|
-
if (!apiKey.trim()) {
|
|
485
|
+
if (provider === undefined && !apiKey.trim()) {
|
|
486
486
|
newErrors.apiKey = "API key is required";
|
|
487
487
|
}
|
|
488
488
|
if (models.length === 0 || models.every((m) => !m.trim())) {
|
|
@@ -950,19 +950,15 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
|
|
|
950
950
|
|
|
951
951
|
<div className="space-y-2">
|
|
952
952
|
<label htmlFor="provider-apikey" className="text-sm font-medium">
|
|
953
|
-
API Key <span className="text-destructive">*</span>
|
|
953
|
+
API Key {provider === undefined && <span className="text-destructive">*</span>}
|
|
954
954
|
</label>
|
|
955
955
|
<div className="flex items-center gap-2">
|
|
956
956
|
<input
|
|
957
957
|
id="provider-apikey"
|
|
958
|
-
type="text"
|
|
959
|
-
value={
|
|
958
|
+
type={showApiKey ? "text" : "password"}
|
|
959
|
+
value={apiKey}
|
|
960
960
|
onChange={(e) => setApiKey(e.target.value)}
|
|
961
|
-
|
|
962
|
-
if (!showApiKey && apiKey.length > 0) setShowApiKey(true);
|
|
963
|
-
}}
|
|
964
|
-
placeholder="sk-ant-..."
|
|
965
|
-
readOnly={!showApiKey && apiKey.length > 0}
|
|
961
|
+
placeholder={provider === undefined ? "sk-ant-..." : "Leave blank to keep current key"}
|
|
966
962
|
className="flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50"
|
|
967
963
|
/>
|
|
968
964
|
<button
|
|
@@ -982,6 +978,11 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
|
|
|
982
978
|
{copied ? <Check className="size-4 text-cyan-300" /> : <Copy className="size-4" />}
|
|
983
979
|
</button>
|
|
984
980
|
</div>
|
|
981
|
+
{provider !== undefined && apiKey.trim() === "" && (
|
|
982
|
+
<p className="text-xs text-muted-foreground">
|
|
983
|
+
A key is configured. Enter a new value only to rotate it.
|
|
984
|
+
</p>
|
|
985
|
+
)}
|
|
985
986
|
{errors.apiKey !== undefined && <p className="text-xs text-destructive">{errors.apiKey}</p>}
|
|
986
987
|
</div>
|
|
987
988
|
|
|
@@ -81,7 +81,7 @@ function endpointPayloadValue(
|
|
|
81
81
|
function createProviderPayload(data: ProviderFormData, preserveEmptyEndpoints = false) {
|
|
82
82
|
return {
|
|
83
83
|
name: data.name,
|
|
84
|
-
apiKey: data.apiKey,
|
|
84
|
+
...(data.apiKey.trim() === "" ? {} : { apiKey: data.apiKey }),
|
|
85
85
|
models: data.models,
|
|
86
86
|
anthropicBaseUrl: endpointPayloadValue(data.anthropicBaseUrl, preserveEmptyEndpoints),
|
|
87
87
|
openaiBaseUrl: endpointPayloadValue(data.openaiBaseUrl, preserveEmptyEndpoints),
|
|
@@ -430,7 +430,7 @@ export function ProvidersPanel({
|
|
|
430
430
|
refreshProviders();
|
|
431
431
|
// Only run connection test when critical fields (apiKey, model, base URLs) changed
|
|
432
432
|
const criticalFieldsChanged =
|
|
433
|
-
|
|
433
|
+
data.apiKey.trim() !== "" ||
|
|
434
434
|
JSON.stringify(data.models) !== JSON.stringify(editingProvider.models) ||
|
|
435
435
|
(data.anthropicBaseUrl ?? "") !== (editingProvider.anthropicBaseUrl ?? "") ||
|
|
436
436
|
(data.openaiBaseUrl ?? "") !== (editingProvider.openaiBaseUrl ?? "") ||
|
|
@@ -471,9 +471,9 @@ function McpSettingsTab(): JSX.Element {
|
|
|
471
471
|
value: `agent-inspector-mcp doctor --url ${endpoint}`,
|
|
472
472
|
},
|
|
473
473
|
{
|
|
474
|
-
id: "
|
|
475
|
-
label: "
|
|
476
|
-
value: "
|
|
474
|
+
id: "writes",
|
|
475
|
+
label: "Enable write tools",
|
|
476
|
+
value: "AGENT_INSPECTOR_MCP_WRITES=1 agent-inspector",
|
|
477
477
|
},
|
|
478
478
|
{
|
|
479
479
|
id: "capabilities",
|