@tonyclaw/agent-inspector 3.0.25 → 3.0.26
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/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-BnvOPwpe.js → CompareDrawer-SZRUDQc9.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-BJvwOrSi.js +4234 -0
- package/.output/public/assets/{ReplayDialog-BJgoQWdW.js → ReplayDialog-DgfmqiM3.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-CpBZEHnM.js → RequestAnatomy-CS6c7Qfn.js} +1 -1
- package/.output/public/assets/{ResponseView-CWmyRb2M.js → ResponseView-C0Ri_5gm.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-BWhC8bwx.js → StreamingChunkSequence-7dYcHWyZ.js} +1 -1
- package/.output/public/assets/{_sessionId-Cq-2OqUU.js → _sessionId-D-V84cgw.js} +1 -1
- package/.output/public/assets/{index-BKi9IRtV.js → index-CSIL7-MK.js} +3 -3
- package/.output/public/assets/index-CmeF5XXS.css +1 -0
- package/.output/public/assets/{index-Cf8O0Oos.js → index-DgFWCxOs.js} +1 -1
- package/.output/public/assets/{index-DdgTJ4QJ.js → index-DrVJsks2.js} +1 -1
- package/.output/public/assets/{json-viewer-Bqu_4hmm.js → json-viewer-C9Ji3gYN.js} +1 -1
- package/.output/server/_libs/three.mjs +26016 -0
- package/.output/server/{_sessionId-Ba7H3Gjw.mjs → _sessionId-BQ6YQOO1.mjs} +7 -6
- package/.output/server/_ssr/{CompareDrawer-aH59Ab6x.mjs → CompareDrawer-CqNzIeMR.mjs} +7 -6
- package/.output/server/_ssr/{ProxyViewerContainer-By-I0tJv.mjs → ProxyViewerContainer-CMC7Vsbw.mjs} +785 -311
- package/.output/server/_ssr/{ReplayDialog-BO4Vy0et.mjs → ReplayDialog-D9p_LaTr.mjs} +8 -7
- package/.output/server/_ssr/{RequestAnatomy-FtOr7vSS.mjs → RequestAnatomy-B4ge3qNZ.mjs} +7 -6
- package/.output/server/_ssr/{ResponseView-cvw6ajue.mjs → ResponseView-BCqMKApI.mjs} +7 -6
- package/.output/server/_ssr/{StreamingChunkSequence-Oc8S2kD6.mjs → StreamingChunkSequence-BA4zTLE4.mjs} +7 -6
- package/.output/server/_ssr/{index-BDRlQheR.mjs → index-CzxhDjlq.mjs} +7 -6
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-Cd6trhQr.mjs → json-viewer-B3qV6iEJ.mjs} +7 -6
- package/.output/server/_ssr/{router-bofP-Ekl.mjs → router-CZe_R31M.mjs} +4 -4
- package/.output/server/{_tanstack-start-manifest_v-BPuf86qB.mjs → _tanstack-start-manifest_v-B50VTLrH.mjs} +1 -1
- package/.output/server/index.mjs +68 -68
- package/package.json +3 -1
- package/src/components/inspector-pet/InspectorPet.tsx +66 -51
- package/src/components/inspector-pet/InspectorPetCrab3D.tsx +455 -0
- package/src/components/inspector-pet/inspectorPetLogic.ts +28 -43
- package/src/components/providers/ProviderForm.tsx +238 -163
- package/src/components/providers/ProvidersPanel.tsx +16 -6
- package/src/components/providers/providerFormCapabilities.ts +36 -0
- package/styles/globals.css +0 -61
- package/.output/public/assets/ProxyViewerContainer-DcqFqo1m.js +0 -127
- package/.output/public/assets/index-BMYuDL5X.css +0 -1
package/.output/server/_ssr/{ProxyViewerContainer-By-I0tJv.mjs → ProxyViewerContainer-CMC7Vsbw.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, R as React } from "../_libs/react.mjs";
|
|
2
|
-
import { C as CapturedLogSchema, z as DeleteInspectorGroupsResponseSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, g as readStoredUiScalePreference, h as persistUiScalePreference, i as applyUiScalePreference, w as extractStopReason, p as packageJson, P as ProviderConfigSchema, U as UI_SCALE_STORAGE_KEY, j as normalizeUiScalePreference, q as apiFormatForPath, B as GroupEvidenceExportResultSchema, E as DeleteInspectorGroupResponseSchema, $ as PiAgentResponseSchema, v as isTurnBoundary, r as readStoredThemeMode, e as applyThemeMode, f as persistThemeMode, a2 as formatUiScale, x as AlertSummarySchema, y as AlertListResponseSchema, I as InspectorGroupsListResponseSchema, G as GroupEvidenceReadResponseSchema, V as createPendingProviderTestResults, W as ProviderTestResultsSchema, X as createFailedProviderTestResults, Y as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, Z as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, _ as TimeDisplayFormatSchema, T as THEME_MODE_STORAGE_KEY, n as normalizeThemeMode,
|
|
2
|
+
import { C as CapturedLogSchema, z as DeleteInspectorGroupsResponseSchema, D as DEFAULT_CAPTURE_MODE, a as DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS, b as DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS, c as DEFAULT_TIME_DISPLAY_FORMAT, d as RuntimeConfigSchema, g as readStoredUiScalePreference, h as persistUiScalePreference, i as applyUiScalePreference, w as extractStopReason, p as packageJson, P as ProviderConfigSchema, U as UI_SCALE_STORAGE_KEY, j as normalizeUiScalePreference, q as apiFormatForPath, B as GroupEvidenceExportResultSchema, E as DeleteInspectorGroupResponseSchema, $ as PiAgentResponseSchema, v as isTurnBoundary, r as readStoredThemeMode, e as applyThemeMode, f as persistThemeMode, a2 as formatUiScale, x as AlertSummarySchema, y as AlertListResponseSchema, I as InspectorGroupsListResponseSchema, G as GroupEvidenceReadResponseSchema, V as createPendingProviderTestResults, W as ProviderTestResultsSchema, X as createFailedProviderTestResults, Y as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, Z as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, _ as TimeDisplayFormatSchema, T as THEME_MODE_STORAGE_KEY, n as normalizeThemeMode, M as PATH_V1_MESSAGES, N as PATH_V1_CHAT_COMPLETIONS, Q as PATH_V1_RESPONSES, H as maskApiKey, F as providerHasContextMetadata, l as parseOpenAIResponse, m as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, o as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, k as AnthropicRequestSchema, s as safeGetOwnProperty, a0 as resolveProviderContextWindow, t as getSessionPath, J as findProviderModelMetadata, S as previewUpstreamUrl, K as KnowledgeCandidateSchema, a1 as isPlainRecord, u as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-CZe_R31M.mjs";
|
|
3
3
|
import { u as useSWR, a as useSWRConfig } from "../_libs/swr.mjs";
|
|
4
4
|
import { J as JSZip } from "../_libs/jszip.mjs";
|
|
5
5
|
import { c as clsx } from "../_libs/clsx.mjs";
|
|
@@ -7,6 +7,8 @@ import { t as twMerge } from "../_libs/tailwind-merge.mjs";
|
|
|
7
7
|
import { c as cva } from "../_libs/class-variance-authority.mjs";
|
|
8
8
|
import { u as useWindowVirtualizer, a as useVirtualizer } from "../_libs/tanstack__react-virtual.mjs";
|
|
9
9
|
import { d as diffJson, a as diffLines } from "../_libs/diff.mjs";
|
|
10
|
+
import { r as reactDomExports } from "../_libs/react-dom.mjs";
|
|
11
|
+
import { W as WebGLRenderer, S as SRGBColorSpace, A as ACESFilmicToneMapping, a as Scene, O as OrthographicCamera, M as MeshPhysicalMaterial, C as Color, G as Group, b as Mesh, c as CircleGeometry, d as MeshBasicMaterial, e as SphereGeometry, f as AmbientLight, H as HemisphereLight, D as DirectionalLight, P as PointLight, V as Vector3, g as CylinderGeometry } from "../_libs/three.mjs";
|
|
10
12
|
import { T as TriangleAlert, C as CircleCheck, X, I as Info, a as ChevronDown, b as Check, P as PanelRightOpen, c as PanelRightClose, S as Search, U as Upload, D as Download, F as FileBraces, R as RefreshCw, d as Trash2, H as Heart, e as Pause, f as Play, g as Plus, B as BrainCircuit, L as LoaderCircle, h as Send, A as ArrowLeft, i as ChevronUp, j as Copy, k as ChevronsLeft, l as ChevronLeft, m as ChevronRight, n as ChevronsRight, o as Clapperboard, p as Flag, q as Siren, r as Timer, G as Gauge, s as Sun, E as Eye, M as Moon, t as ALargeSmall, u as Layers, v as FlaskConical, w as Sparkles, x as Activity, y as Beaker, N as Network, z as Terminal, J as Settings, K as Monitor, O as Rocket, Q as PackageCheck, V as History, W as Scan, Y as CircleAlert, Z as ArrowUpRight, _ as ArrowDownRight, $ as Cpu, a0 as FolderOpen, a1 as Bell, a2 as Clock3, a3 as ShieldAlert, a4 as EyeOff, a5 as ExternalLink, a6 as Clock, a7 as RotateCw, a8 as Pencil, a9 as MessageSquare, aa as Zap, ab as Wrench, ac as Brain, ad as CircleCheckBig, ae as Minus, af as CircleX, ag as ShieldCheck, ah as Save, ai as FileSearch, aj as CloudUpload, ak as CircleQuestionMark, al as Server, am as Lock, an as Wifi, ao as WifiOff, ap as OctagonAlert, aq as Radio, ar as Globe, as as FileTerminal, at as ChevronsUp, au as ChevronsDown, av as FileDiff, aw as RotateCcw, ax as GitCompareArrows, ay as ArrowUp, az as ArrowDown, aA as Ellipsis, aB as CodeXml, aC as Blocks, aD as MousePointerClick, aE as FileText, aF as Rows3, aG as Columns2 } from "../_libs/lucide-react.mjs";
|
|
11
13
|
import { u as union, o as object, e as array, l as literal, n as number, d as boolean, b as string, _ as _enum } from "../_libs/zod.mjs";
|
|
12
14
|
import { S as Select$1, a as SelectTrigger$1, b as SelectIcon, c as SelectValue$1, d as SelectPortal, e as SelectContent$1, f as SelectViewport, g as SelectItem$1, h as SelectItemIndicator, i as SelectItemText, j as SelectScrollUpButton$1, k as SelectScrollDownButton$1 } from "../_libs/radix-ui__react-select.mjs";
|
|
@@ -2525,27 +2527,27 @@ function useCopyFeedback(text) {
|
|
|
2525
2527
|
return { copied, copy };
|
|
2526
2528
|
}
|
|
2527
2529
|
const LazyCompareDrawer = reactExports.lazy(
|
|
2528
|
-
() => import("./CompareDrawer-
|
|
2530
|
+
() => import("./CompareDrawer-CqNzIeMR.mjs").then((m) => ({ default: m.CompareDrawer }))
|
|
2529
2531
|
);
|
|
2530
2532
|
const LazyReplayDialog = reactExports.lazy(
|
|
2531
|
-
() => import("./ReplayDialog-
|
|
2533
|
+
() => import("./ReplayDialog-D9p_LaTr.mjs").then((m) => ({ default: m.ReplayDialog }))
|
|
2532
2534
|
);
|
|
2533
2535
|
const LazyRequestAnatomy = reactExports.lazy(
|
|
2534
|
-
() => import("./RequestAnatomy-
|
|
2536
|
+
() => import("./RequestAnatomy-B4ge3qNZ.mjs").then((m) => ({ default: m.RequestAnatomy }))
|
|
2535
2537
|
);
|
|
2536
2538
|
const LazyResponseView = reactExports.lazy(
|
|
2537
|
-
() => import("./ResponseView-
|
|
2539
|
+
() => import("./ResponseView-BCqMKApI.mjs").then((m) => ({ default: m.ResponseView }))
|
|
2538
2540
|
);
|
|
2539
2541
|
const LazyStreamingChunkSequence = reactExports.lazy(
|
|
2540
|
-
() => import("./StreamingChunkSequence-
|
|
2542
|
+
() => import("./StreamingChunkSequence-BA4zTLE4.mjs").then((m) => ({
|
|
2541
2543
|
default: m.StreamingChunkSequence
|
|
2542
2544
|
}))
|
|
2543
2545
|
);
|
|
2544
2546
|
const LazyJsonViewer = reactExports.lazy(
|
|
2545
|
-
() => import("./json-viewer-
|
|
2547
|
+
() => import("./json-viewer-B3qV6iEJ.mjs").then((m) => ({ default: m.JsonViewer }))
|
|
2546
2548
|
);
|
|
2547
2549
|
const LazyJsonViewerFromString = reactExports.lazy(
|
|
2548
|
-
() => import("./json-viewer-
|
|
2550
|
+
() => import("./json-viewer-B3qV6iEJ.mjs").then((m) => ({ default: m.JsonViewerFromString }))
|
|
2549
2551
|
);
|
|
2550
2552
|
const HIGHLIGHT_DURATION_MS = 1200;
|
|
2551
2553
|
const MAX_HIGHLIGHT_ATTEMPTS = 12;
|
|
@@ -8935,7 +8937,7 @@ function ProviderTestPill({
|
|
|
8935
8937
|
testResults,
|
|
8936
8938
|
isTesting
|
|
8937
8939
|
}) {
|
|
8938
|
-
const
|
|
8940
|
+
const hasEndpoint2 = providerHasEndpoint$1(provider.anthropicBaseUrl) || providerHasEndpoint$1(provider.openaiBaseUrl) || providerHasEndpoint$1(provider.openaiResponsesBaseUrl);
|
|
8939
8941
|
const summary = summarizeProviderTestResults(provider, testResults);
|
|
8940
8942
|
if (isTesting) {
|
|
8941
8943
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 rounded border border-cyan-300/25 bg-cyan-300/[0.08] px-2 py-1 text-xs text-cyan-100", children: [
|
|
@@ -8943,7 +8945,7 @@ function ProviderTestPill({
|
|
|
8943
8945
|
"Testing"
|
|
8944
8946
|
] });
|
|
8945
8947
|
}
|
|
8946
|
-
if (!
|
|
8948
|
+
if (!hasEndpoint2) {
|
|
8947
8949
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "rounded border border-border/70 bg-muted/20 px-2 py-1 text-xs text-muted-foreground", children: "No endpoint" });
|
|
8948
8950
|
}
|
|
8949
8951
|
if (testResults === void 0 || summary.total === 0) {
|
|
@@ -9254,6 +9256,25 @@ function ProviderCard({
|
|
|
9254
9256
|
}
|
|
9255
9257
|
);
|
|
9256
9258
|
}
|
|
9259
|
+
function hasEndpoint(value) {
|
|
9260
|
+
return value !== void 0 && value.trim() !== "";
|
|
9261
|
+
}
|
|
9262
|
+
function deriveProviderCapabilities(provider) {
|
|
9263
|
+
const anthropic = hasEndpoint(provider?.anthropicBaseUrl);
|
|
9264
|
+
const openaiChat = hasEndpoint(provider?.openaiBaseUrl);
|
|
9265
|
+
const openaiResponses = hasEndpoint(provider?.openaiResponsesBaseUrl);
|
|
9266
|
+
return {
|
|
9267
|
+
anthropic,
|
|
9268
|
+
openai: openaiChat || openaiResponses,
|
|
9269
|
+
openaiChat,
|
|
9270
|
+
openaiResponses
|
|
9271
|
+
};
|
|
9272
|
+
}
|
|
9273
|
+
function endpointForCapability(enabled, value, clearWhenDisabled) {
|
|
9274
|
+
if (!enabled) return clearWhenDisabled ? "" : void 0;
|
|
9275
|
+
const trimmed = value.trim();
|
|
9276
|
+
return trimmed === "" ? void 0 : trimmed;
|
|
9277
|
+
}
|
|
9257
9278
|
const ZHIPU_PROVIDER_KEYWORDS = ["zhipu", "zhipuai", "bigmodel", "z.ai", "zai", "glm"];
|
|
9258
9279
|
const ZHIPU_CODING_PROVIDER_KEYWORDS = [
|
|
9259
9280
|
"zhipu coding",
|
|
@@ -9477,6 +9498,7 @@ function EndpointUrlPreview({
|
|
|
9477
9498
|
] });
|
|
9478
9499
|
}
|
|
9479
9500
|
function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
9501
|
+
const initialCapabilities = deriveProviderCapabilities(provider);
|
|
9480
9502
|
const [name, setName] = reactExports.useState(provider?.name ?? "");
|
|
9481
9503
|
const [apiKey, setApiKey] = reactExports.useState(provider?.apiKey ?? "");
|
|
9482
9504
|
const [showApiKey, setShowApiKey] = reactExports.useState(false);
|
|
@@ -9491,7 +9513,12 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9491
9513
|
initialModels !== void 0 && initialModels.length > 0 ? initialModels : [""]
|
|
9492
9514
|
)
|
|
9493
9515
|
);
|
|
9494
|
-
const [
|
|
9516
|
+
const [supportsAnthropic, setSupportsAnthropic] = reactExports.useState(initialCapabilities.anthropic);
|
|
9517
|
+
const [supportsOpenai, setSupportsOpenai] = reactExports.useState(initialCapabilities.openai);
|
|
9518
|
+
const [supportsOpenaiChat, setSupportsOpenaiChat] = reactExports.useState(initialCapabilities.openaiChat);
|
|
9519
|
+
const [supportsOpenaiResponses, setSupportsOpenaiResponses] = reactExports.useState(
|
|
9520
|
+
initialCapabilities.openaiResponses
|
|
9521
|
+
);
|
|
9495
9522
|
const [anthropicBaseUrl, setAnthropicBaseUrl] = reactExports.useState(
|
|
9496
9523
|
stripEndpointSuffix(provider?.anthropicBaseUrl, ANTHROPIC_MESSAGES_ENDPOINT)
|
|
9497
9524
|
);
|
|
@@ -9545,6 +9572,11 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9545
9572
|
const nextModels = (provider.models?.length ?? 0) > 0 ? provider.models : [""];
|
|
9546
9573
|
setModels(nextModels);
|
|
9547
9574
|
setModelMetadataDrafts(createMetadataDrafts(provider, nextModels));
|
|
9575
|
+
const nextCapabilities = deriveProviderCapabilities(provider);
|
|
9576
|
+
setSupportsAnthropic(nextCapabilities.anthropic);
|
|
9577
|
+
setSupportsOpenai(nextCapabilities.openai);
|
|
9578
|
+
setSupportsOpenaiChat(nextCapabilities.openaiChat);
|
|
9579
|
+
setSupportsOpenaiResponses(nextCapabilities.openaiResponses);
|
|
9548
9580
|
setAnthropicBaseUrl(
|
|
9549
9581
|
stripEndpointSuffix(provider.anthropicBaseUrl, ANTHROPIC_MESSAGES_ENDPOINT)
|
|
9550
9582
|
);
|
|
@@ -9602,14 +9634,32 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9602
9634
|
if (models.length === 0 || models.every((m) => !m.trim())) {
|
|
9603
9635
|
newErrors.models = "At least one model is required";
|
|
9604
9636
|
}
|
|
9605
|
-
if (
|
|
9606
|
-
newErrors.
|
|
9637
|
+
if (!supportsAnthropic && !supportsOpenai) {
|
|
9638
|
+
newErrors.capabilities = "Select at least one API capability";
|
|
9639
|
+
}
|
|
9640
|
+
if (supportsOpenai && !supportsOpenaiChat && !supportsOpenaiResponses) {
|
|
9641
|
+
newErrors.openaiCapabilities = "Select Chat Completions, Responses, or both";
|
|
9607
9642
|
}
|
|
9608
|
-
if (
|
|
9609
|
-
|
|
9643
|
+
if (supportsAnthropic) {
|
|
9644
|
+
if (anthropicBaseUrl.trim() === "") {
|
|
9645
|
+
newErrors.anthropicBaseUrl = "Anthropic base URL is required";
|
|
9646
|
+
} else if (!isValidUrl(anthropicBaseUrl.trim())) {
|
|
9647
|
+
newErrors.anthropicBaseUrl = "Invalid URL format";
|
|
9648
|
+
}
|
|
9649
|
+
}
|
|
9650
|
+
if (supportsOpenai && supportsOpenaiChat) {
|
|
9651
|
+
if (openaiBaseUrl.trim() === "") {
|
|
9652
|
+
newErrors.openaiBaseUrl = "OpenAI Chat base URL is required";
|
|
9653
|
+
} else if (!isValidUrl(openaiBaseUrl.trim())) {
|
|
9654
|
+
newErrors.openaiBaseUrl = "Invalid URL format";
|
|
9655
|
+
}
|
|
9610
9656
|
}
|
|
9611
|
-
if (
|
|
9612
|
-
|
|
9657
|
+
if (supportsOpenai && supportsOpenaiResponses) {
|
|
9658
|
+
if (openaiResponsesBaseUrl.trim() === "") {
|
|
9659
|
+
newErrors.openaiResponsesBaseUrl = "OpenAI Responses base URL is required";
|
|
9660
|
+
} else if (!isValidUrl(openaiResponsesBaseUrl.trim())) {
|
|
9661
|
+
newErrors.openaiResponsesBaseUrl = "Invalid URL format";
|
|
9662
|
+
}
|
|
9613
9663
|
}
|
|
9614
9664
|
if (modelMetadataUrl.trim() && !isValidUrl(modelMetadataUrl.trim())) {
|
|
9615
9665
|
newErrors.modelMetadataUrl = "Invalid URL format";
|
|
@@ -9627,9 +9677,6 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9627
9677
|
newErrors[`modelMetadata.${index}.outputLimit`] = "Output limit should not exceed context window";
|
|
9628
9678
|
}
|
|
9629
9679
|
});
|
|
9630
|
-
if (!anthropicBaseUrl.trim() && !openaiBaseUrl.trim() && !openaiResponsesBaseUrl.trim()) {
|
|
9631
|
-
newErrors.format = "At least one format URL (Anthropic or OpenAI) is required";
|
|
9632
|
-
}
|
|
9633
9680
|
setErrors(newErrors);
|
|
9634
9681
|
return Object.keys(newErrors).length === 0;
|
|
9635
9682
|
}
|
|
@@ -9736,14 +9783,27 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9736
9783
|
e.preventDefault();
|
|
9737
9784
|
if (!validate()) return;
|
|
9738
9785
|
setIsSubmitting(true);
|
|
9786
|
+
const clearDisabledEndpoints = provider !== void 0;
|
|
9739
9787
|
try {
|
|
9740
9788
|
onSubmit({
|
|
9741
9789
|
name: name.trim(),
|
|
9742
9790
|
apiKey: apiKey.trim(),
|
|
9743
9791
|
models: models.map((m) => m.trim()).filter((m) => m !== ""),
|
|
9744
|
-
anthropicBaseUrl:
|
|
9745
|
-
|
|
9746
|
-
|
|
9792
|
+
anthropicBaseUrl: endpointForCapability(
|
|
9793
|
+
supportsAnthropic,
|
|
9794
|
+
anthropicBaseUrl,
|
|
9795
|
+
clearDisabledEndpoints
|
|
9796
|
+
),
|
|
9797
|
+
openaiBaseUrl: endpointForCapability(
|
|
9798
|
+
supportsOpenai && supportsOpenaiChat,
|
|
9799
|
+
openaiBaseUrl,
|
|
9800
|
+
clearDisabledEndpoints
|
|
9801
|
+
),
|
|
9802
|
+
openaiResponsesBaseUrl: endpointForCapability(
|
|
9803
|
+
supportsOpenai && supportsOpenaiResponses,
|
|
9804
|
+
openaiResponsesBaseUrl,
|
|
9805
|
+
clearDisabledEndpoints
|
|
9806
|
+
),
|
|
9747
9807
|
apiDocsUrl: apiDocsUrl.trim() || void 0,
|
|
9748
9808
|
modelMetadataUrl: modelMetadataUrl.trim() || void 0,
|
|
9749
9809
|
modelMetadata: buildModelMetadata(),
|
|
@@ -9772,6 +9832,205 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
9772
9832
|
),
|
|
9773
9833
|
errors.name !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.name })
|
|
9774
9834
|
] }),
|
|
9835
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("fieldset", { className: "space-y-3", children: [
|
|
9836
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("legend", { className: "text-sm font-medium", children: [
|
|
9837
|
+
"Capabilities ",
|
|
9838
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
|
|
9839
|
+
] }),
|
|
9840
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "divide-y divide-border overflow-hidden rounded-md border border-border", children: [
|
|
9841
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: supportsOpenai ? "bg-primary/[0.04] px-3 py-3" : "px-3 py-3", children: [
|
|
9842
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9843
|
+
"label",
|
|
9844
|
+
{
|
|
9845
|
+
htmlFor: "provider-capability-openai",
|
|
9846
|
+
className: "flex cursor-pointer items-start gap-3",
|
|
9847
|
+
children: [
|
|
9848
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9849
|
+
"input",
|
|
9850
|
+
{
|
|
9851
|
+
id: "provider-capability-openai",
|
|
9852
|
+
type: "checkbox",
|
|
9853
|
+
checked: supportsOpenai,
|
|
9854
|
+
onChange: (event) => setSupportsOpenai(event.target.checked),
|
|
9855
|
+
className: "mt-0.5 size-4 shrink-0 accent-primary"
|
|
9856
|
+
}
|
|
9857
|
+
),
|
|
9858
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0", children: [
|
|
9859
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-sm font-medium", children: "OpenAI" }),
|
|
9860
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-muted-foreground", children: "Chat Completions and Responses" })
|
|
9861
|
+
] })
|
|
9862
|
+
]
|
|
9863
|
+
}
|
|
9864
|
+
),
|
|
9865
|
+
supportsOpenai && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ml-7 mt-3 flex flex-wrap gap-x-5 gap-y-2 border-t border-border/70 pt-3", children: [
|
|
9866
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9867
|
+
"label",
|
|
9868
|
+
{
|
|
9869
|
+
htmlFor: "provider-capability-openai-chat",
|
|
9870
|
+
className: "flex cursor-pointer items-center gap-2 text-sm",
|
|
9871
|
+
children: [
|
|
9872
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9873
|
+
"input",
|
|
9874
|
+
{
|
|
9875
|
+
id: "provider-capability-openai-chat",
|
|
9876
|
+
type: "checkbox",
|
|
9877
|
+
checked: supportsOpenaiChat,
|
|
9878
|
+
onChange: (event) => setSupportsOpenaiChat(event.target.checked),
|
|
9879
|
+
className: "size-4 shrink-0 accent-primary"
|
|
9880
|
+
}
|
|
9881
|
+
),
|
|
9882
|
+
"Chat Completions"
|
|
9883
|
+
]
|
|
9884
|
+
}
|
|
9885
|
+
),
|
|
9886
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9887
|
+
"label",
|
|
9888
|
+
{
|
|
9889
|
+
htmlFor: "provider-capability-openai-responses",
|
|
9890
|
+
className: "flex cursor-pointer items-center gap-2 text-sm",
|
|
9891
|
+
children: [
|
|
9892
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9893
|
+
"input",
|
|
9894
|
+
{
|
|
9895
|
+
id: "provider-capability-openai-responses",
|
|
9896
|
+
type: "checkbox",
|
|
9897
|
+
checked: supportsOpenaiResponses,
|
|
9898
|
+
onChange: (event) => setSupportsOpenaiResponses(event.target.checked),
|
|
9899
|
+
className: "size-4 shrink-0 accent-primary"
|
|
9900
|
+
}
|
|
9901
|
+
),
|
|
9902
|
+
"Responses"
|
|
9903
|
+
]
|
|
9904
|
+
}
|
|
9905
|
+
)
|
|
9906
|
+
] }),
|
|
9907
|
+
errors.openaiCapabilities !== void 0 && supportsOpenai && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ml-7 mt-2 text-xs text-destructive", children: errors.openaiCapabilities })
|
|
9908
|
+
] }),
|
|
9909
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
9910
|
+
"label",
|
|
9911
|
+
{
|
|
9912
|
+
htmlFor: "provider-capability-anthropic",
|
|
9913
|
+
className: `flex cursor-pointer items-start gap-3 px-3 py-3 ${supportsAnthropic ? "bg-primary/[0.04]" : ""}`,
|
|
9914
|
+
children: [
|
|
9915
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9916
|
+
"input",
|
|
9917
|
+
{
|
|
9918
|
+
id: "provider-capability-anthropic",
|
|
9919
|
+
type: "checkbox",
|
|
9920
|
+
checked: supportsAnthropic,
|
|
9921
|
+
onChange: (event) => setSupportsAnthropic(event.target.checked),
|
|
9922
|
+
className: "mt-0.5 size-4 shrink-0 accent-primary"
|
|
9923
|
+
}
|
|
9924
|
+
),
|
|
9925
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0", children: [
|
|
9926
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-sm font-medium", children: "Anthropic" }),
|
|
9927
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-muted-foreground", children: "Messages" })
|
|
9928
|
+
] })
|
|
9929
|
+
]
|
|
9930
|
+
}
|
|
9931
|
+
)
|
|
9932
|
+
] }),
|
|
9933
|
+
errors.capabilities !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.capabilities })
|
|
9934
|
+
] }),
|
|
9935
|
+
(supportsAnthropic || supportsOpenai && (supportsOpenaiChat || supportsOpenaiResponses)) && /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "space-y-5 border-l border-border pl-4", "aria-label": "API endpoints", children: [
|
|
9936
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium", children: "Endpoint Configuration" }),
|
|
9937
|
+
supportsAnthropic && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9938
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { htmlFor: "provider-anthropic-base-url", className: "text-sm font-medium", children: [
|
|
9939
|
+
"Anthropic Messages Base URL ",
|
|
9940
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
|
|
9941
|
+
] }),
|
|
9942
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
9943
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9944
|
+
"input",
|
|
9945
|
+
{
|
|
9946
|
+
id: "provider-anthropic-base-url",
|
|
9947
|
+
type: "text",
|
|
9948
|
+
value: anthropicBaseUrl,
|
|
9949
|
+
onChange: (event) => {
|
|
9950
|
+
setManualAnthropicUrlOverride(true);
|
|
9951
|
+
setAnthropicBaseUrl(event.target.value);
|
|
9952
|
+
},
|
|
9953
|
+
placeholder: "https://api.anthropic.com",
|
|
9954
|
+
className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
9955
|
+
}
|
|
9956
|
+
),
|
|
9957
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: ANTHROPIC_MESSAGES_ENDPOINT })
|
|
9958
|
+
] }),
|
|
9959
|
+
errors.anthropicBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.anthropicBaseUrl }),
|
|
9960
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9961
|
+
EndpointUrlPreview,
|
|
9962
|
+
{
|
|
9963
|
+
baseUrl: anthropicBaseUrl,
|
|
9964
|
+
endpoint: ANTHROPIC_MESSAGES_ENDPOINT,
|
|
9965
|
+
providerName: name
|
|
9966
|
+
}
|
|
9967
|
+
)
|
|
9968
|
+
] }),
|
|
9969
|
+
supportsOpenai && supportsOpenaiChat && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9970
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { htmlFor: "provider-openai-base-url", className: "text-sm font-medium", children: [
|
|
9971
|
+
"OpenAI Chat Base URL ",
|
|
9972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
|
|
9973
|
+
] }),
|
|
9974
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
9975
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9976
|
+
"input",
|
|
9977
|
+
{
|
|
9978
|
+
id: "provider-openai-base-url",
|
|
9979
|
+
type: "text",
|
|
9980
|
+
value: openaiBaseUrl,
|
|
9981
|
+
onChange: (event) => {
|
|
9982
|
+
setManualOpenaiUrlOverride(true);
|
|
9983
|
+
setOpenaiBaseUrl(event.target.value);
|
|
9984
|
+
},
|
|
9985
|
+
placeholder: "https://api.openai.com",
|
|
9986
|
+
className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
9987
|
+
}
|
|
9988
|
+
),
|
|
9989
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_CHAT_COMPLETIONS_ENDPOINT })
|
|
9990
|
+
] }),
|
|
9991
|
+
errors.openaiBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiBaseUrl }),
|
|
9992
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
9993
|
+
EndpointUrlPreview,
|
|
9994
|
+
{
|
|
9995
|
+
baseUrl: openaiBaseUrl,
|
|
9996
|
+
endpoint: OPENAI_CHAT_COMPLETIONS_ENDPOINT,
|
|
9997
|
+
providerName: name
|
|
9998
|
+
}
|
|
9999
|
+
)
|
|
10000
|
+
] }),
|
|
10001
|
+
supportsOpenai && supportsOpenaiResponses && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
10002
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { htmlFor: "provider-openai-responses-base-url", className: "text-sm font-medium", children: [
|
|
10003
|
+
"OpenAI Responses Base URL ",
|
|
10004
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-destructive", children: "*" })
|
|
10005
|
+
] }),
|
|
10006
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
10007
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10008
|
+
"input",
|
|
10009
|
+
{
|
|
10010
|
+
id: "provider-openai-responses-base-url",
|
|
10011
|
+
type: "text",
|
|
10012
|
+
value: openaiResponsesBaseUrl,
|
|
10013
|
+
onChange: (event) => {
|
|
10014
|
+
setManualOpenaiResponsesUrlOverride(true);
|
|
10015
|
+
setOpenaiResponsesBaseUrl(event.target.value);
|
|
10016
|
+
},
|
|
10017
|
+
placeholder: "https://api.openai.com",
|
|
10018
|
+
className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
10019
|
+
}
|
|
10020
|
+
),
|
|
10021
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_RESPONSES_ENDPOINT })
|
|
10022
|
+
] }),
|
|
10023
|
+
errors.openaiResponsesBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiResponsesBaseUrl }),
|
|
10024
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10025
|
+
EndpointUrlPreview,
|
|
10026
|
+
{
|
|
10027
|
+
baseUrl: openaiResponsesBaseUrl,
|
|
10028
|
+
endpoint: OPENAI_RESPONSES_ENDPOINT,
|
|
10029
|
+
providerName: name
|
|
10030
|
+
}
|
|
10031
|
+
)
|
|
10032
|
+
] })
|
|
10033
|
+
] }),
|
|
9775
10034
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
9776
10035
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-source", className: "text-sm font-medium", children: "Token Source" }),
|
|
9777
10036
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -10025,127 +10284,6 @@ function ProviderForm({ provider, onSubmit, onCancel }) {
|
|
|
10025
10284
|
),
|
|
10026
10285
|
errors.models !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.models })
|
|
10027
10286
|
] }),
|
|
10028
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
10029
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-border bg-muted/40 flex gap-1 rounded-[8px] p-1", children: [
|
|
10030
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
10031
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10032
|
-
"button",
|
|
10033
|
-
{
|
|
10034
|
-
type: "button",
|
|
10035
|
-
onClick: () => setActiveTab("anthropic"),
|
|
10036
|
-
className: `px-3 py-2 text-sm font-medium border-b-2 transition-colors ${activeTab === "anthropic" ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground"}`,
|
|
10037
|
-
children: "Anthropic Format"
|
|
10038
|
-
}
|
|
10039
|
-
) }),
|
|
10040
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Anthropic Messages API format" })
|
|
10041
|
-
] }) }),
|
|
10042
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
10043
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10044
|
-
"button",
|
|
10045
|
-
{
|
|
10046
|
-
type: "button",
|
|
10047
|
-
onClick: () => setActiveTab("openai"),
|
|
10048
|
-
className: `px-3 py-2 text-sm font-medium border-b-2 transition-colors ${activeTab === "openai" ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground"}`,
|
|
10049
|
-
children: "OpenAI Format"
|
|
10050
|
-
}
|
|
10051
|
-
) }),
|
|
10052
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "OpenAI Chat Completions API format" })
|
|
10053
|
-
] }) })
|
|
10054
|
-
] }),
|
|
10055
|
-
errors.format !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.format })
|
|
10056
|
-
] }),
|
|
10057
|
-
activeTab === "anthropic" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
10058
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-anthropic-base-url", className: "text-sm font-medium", children: "Anthropic Base URL" }),
|
|
10059
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
10060
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10061
|
-
"input",
|
|
10062
|
-
{
|
|
10063
|
-
id: "provider-anthropic-base-url",
|
|
10064
|
-
type: "text",
|
|
10065
|
-
value: anthropicBaseUrl,
|
|
10066
|
-
onChange: (e) => {
|
|
10067
|
-
setManualAnthropicUrlOverride(true);
|
|
10068
|
-
setAnthropicBaseUrl(e.target.value);
|
|
10069
|
-
},
|
|
10070
|
-
placeholder: "https://api.anthropic.com",
|
|
10071
|
-
className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
10072
|
-
}
|
|
10073
|
-
),
|
|
10074
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: ANTHROPIC_MESSAGES_ENDPOINT })
|
|
10075
|
-
] }),
|
|
10076
|
-
errors.anthropicBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.anthropicBaseUrl }),
|
|
10077
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10078
|
-
EndpointUrlPreview,
|
|
10079
|
-
{
|
|
10080
|
-
baseUrl: anthropicBaseUrl,
|
|
10081
|
-
endpoint: ANTHROPIC_MESSAGES_ENDPOINT,
|
|
10082
|
-
providerName: name
|
|
10083
|
-
}
|
|
10084
|
-
),
|
|
10085
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Anthropic-compatible base URL. Leave empty if this provider does not support Anthropic format." })
|
|
10086
|
-
] }),
|
|
10087
|
-
activeTab === "openai" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
|
|
10088
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
10089
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-base-url", className: "text-sm font-medium", children: "OpenAI Chat Base URL" }),
|
|
10090
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
10091
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10092
|
-
"input",
|
|
10093
|
-
{
|
|
10094
|
-
id: "provider-openai-base-url",
|
|
10095
|
-
type: "text",
|
|
10096
|
-
value: openaiBaseUrl,
|
|
10097
|
-
onChange: (e) => {
|
|
10098
|
-
setManualOpenaiUrlOverride(true);
|
|
10099
|
-
setOpenaiBaseUrl(e.target.value);
|
|
10100
|
-
},
|
|
10101
|
-
placeholder: "https://api.openai.com",
|
|
10102
|
-
className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
10103
|
-
}
|
|
10104
|
-
),
|
|
10105
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_CHAT_COMPLETIONS_ENDPOINT })
|
|
10106
|
-
] }),
|
|
10107
|
-
errors.openaiBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiBaseUrl }),
|
|
10108
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10109
|
-
EndpointUrlPreview,
|
|
10110
|
-
{
|
|
10111
|
-
baseUrl: openaiBaseUrl,
|
|
10112
|
-
endpoint: OPENAI_CHAT_COMPLETIONS_ENDPOINT,
|
|
10113
|
-
providerName: name
|
|
10114
|
-
}
|
|
10115
|
-
),
|
|
10116
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "OpenAI Chat Completions-compatible base URL. Leave empty if this provider only supports the Responses API." })
|
|
10117
|
-
] }),
|
|
10118
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
10119
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-openai-responses-base-url", className: "text-sm font-medium", children: "OpenAI Responses Base URL" }),
|
|
10120
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground flex min-w-0 overflow-hidden rounded-md focus-within:border-ring focus-within:outline-ring focus-within:ring-[3px]", children: [
|
|
10121
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10122
|
-
"input",
|
|
10123
|
-
{
|
|
10124
|
-
id: "provider-openai-responses-base-url",
|
|
10125
|
-
type: "text",
|
|
10126
|
-
value: openaiResponsesBaseUrl,
|
|
10127
|
-
onChange: (e) => {
|
|
10128
|
-
setManualOpenaiResponsesUrlOverride(true);
|
|
10129
|
-
setOpenaiResponsesBaseUrl(e.target.value);
|
|
10130
|
-
},
|
|
10131
|
-
placeholder: "https://api.openai.com",
|
|
10132
|
-
className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
|
|
10133
|
-
}
|
|
10134
|
-
),
|
|
10135
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 select-none border-l border-white/10 bg-white/[0.04] px-3 py-2 font-mono text-xs text-muted-foreground", children: OPENAI_RESPONSES_ENDPOINT })
|
|
10136
|
-
] }),
|
|
10137
|
-
errors.openaiResponsesBaseUrl !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-destructive", children: errors.openaiResponsesBaseUrl }),
|
|
10138
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
10139
|
-
EndpointUrlPreview,
|
|
10140
|
-
{
|
|
10141
|
-
baseUrl: openaiResponsesBaseUrl,
|
|
10142
|
-
endpoint: OPENAI_RESPONSES_ENDPOINT,
|
|
10143
|
-
providerName: name
|
|
10144
|
-
}
|
|
10145
|
-
),
|
|
10146
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground", children: "Optional Responses-compatible base URL. Set only when the provider supports the Responses API." })
|
|
10147
|
-
] })
|
|
10148
|
-
] }),
|
|
10149
10287
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
10150
10288
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { htmlFor: "provider-api-docs-url", className: "text-sm font-medium", children: "API Docs URL" }),
|
|
10151
10289
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -10191,14 +10329,21 @@ const PROVIDER_DELETE_TIMEOUT_MS = 1e4;
|
|
|
10191
10329
|
const PROVIDER_EXPORT_TIMEOUT_MS = 2e4;
|
|
10192
10330
|
const PROVIDER_IMPORT_TIMEOUT_MS = 2e4;
|
|
10193
10331
|
const PROVIDER_METADATA_TIMEOUT_MS = 3e4;
|
|
10194
|
-
function
|
|
10332
|
+
function endpointPayloadValue(value, preserveEmptyEndpoints) {
|
|
10333
|
+
if ((value?.length ?? 0) > 0) return value;
|
|
10334
|
+
return preserveEmptyEndpoints && value !== void 0 ? "" : void 0;
|
|
10335
|
+
}
|
|
10336
|
+
function createProviderPayload(data, preserveEmptyEndpoints = false) {
|
|
10195
10337
|
return {
|
|
10196
10338
|
name: data.name,
|
|
10197
10339
|
apiKey: data.apiKey,
|
|
10198
10340
|
models: data.models,
|
|
10199
|
-
anthropicBaseUrl: (data.anthropicBaseUrl
|
|
10200
|
-
openaiBaseUrl: (data.openaiBaseUrl
|
|
10201
|
-
openaiResponsesBaseUrl: (
|
|
10341
|
+
anthropicBaseUrl: endpointPayloadValue(data.anthropicBaseUrl, preserveEmptyEndpoints),
|
|
10342
|
+
openaiBaseUrl: endpointPayloadValue(data.openaiBaseUrl, preserveEmptyEndpoints),
|
|
10343
|
+
openaiResponsesBaseUrl: endpointPayloadValue(
|
|
10344
|
+
data.openaiResponsesBaseUrl,
|
|
10345
|
+
preserveEmptyEndpoints
|
|
10346
|
+
),
|
|
10202
10347
|
apiDocsUrl: (data.apiDocsUrl?.length ?? 0) > 0 ? data.apiDocsUrl : void 0,
|
|
10203
10348
|
modelMetadataUrl: (data.modelMetadataUrl?.length ?? 0) > 0 ? data.modelMetadataUrl : void 0,
|
|
10204
10349
|
modelMetadata: data.modelMetadata,
|
|
@@ -10481,7 +10626,7 @@ function ProvidersPanel({
|
|
|
10481
10626
|
{
|
|
10482
10627
|
method: "PUT",
|
|
10483
10628
|
headers: { "Content-Type": "application/json" },
|
|
10484
|
-
body: JSON.stringify(createProviderPayload(data))
|
|
10629
|
+
body: JSON.stringify(createProviderPayload(data, true))
|
|
10485
10630
|
},
|
|
10486
10631
|
() => "Failed to update provider"
|
|
10487
10632
|
);
|
|
@@ -12134,11 +12279,11 @@ function AgentLabDialog({ currentSessionId, logCount }) {
|
|
|
12134
12279
|
] })
|
|
12135
12280
|
] });
|
|
12136
12281
|
}
|
|
12137
|
-
const INSPECTOR_PET_SIZE =
|
|
12282
|
+
const INSPECTOR_PET_SIZE = 112;
|
|
12138
12283
|
const INSPECTOR_PET_MARGIN = 14;
|
|
12139
|
-
const
|
|
12140
|
-
const INSPECTOR_PET_MIN_STEP =
|
|
12141
|
-
const INSPECTOR_PET_MAX_STEP =
|
|
12284
|
+
const INSPECTOR_PET_EDGE_GAP = 20;
|
|
12285
|
+
const INSPECTOR_PET_MIN_STEP = 36;
|
|
12286
|
+
const INSPECTOR_PET_MAX_STEP = 92;
|
|
12142
12287
|
const INSPECTOR_PET_SLEEP_AFTER_MS = 45e3;
|
|
12143
12288
|
const INSPECTOR_PET_PANEL_WIDTH = 192;
|
|
12144
12289
|
const INSPECTOR_PET_PANEL_HEIGHT = 68;
|
|
@@ -12155,33 +12300,27 @@ function clampUnit(value) {
|
|
|
12155
12300
|
return Math.min(Math.max(value, 0), 1);
|
|
12156
12301
|
}
|
|
12157
12302
|
function maximumPetX(viewport) {
|
|
12158
|
-
const
|
|
12159
|
-
return Math.max(
|
|
12160
|
-
-edgePeek,
|
|
12161
|
-
viewport.width - scaledMetric(INSPECTOR_PET_SIZE, viewport) + edgePeek
|
|
12162
|
-
);
|
|
12303
|
+
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12304
|
+
return Math.max(edgeGap, viewport.width - scaledMetric(INSPECTOR_PET_SIZE, viewport) - edgeGap);
|
|
12163
12305
|
}
|
|
12164
12306
|
function maximumPetY(viewport) {
|
|
12165
|
-
const
|
|
12166
|
-
return Math.max(
|
|
12167
|
-
-edgePeek,
|
|
12168
|
-
viewport.height - scaledMetric(INSPECTOR_PET_SIZE, viewport) + edgePeek
|
|
12169
|
-
);
|
|
12307
|
+
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12308
|
+
return Math.max(edgeGap, viewport.height - scaledMetric(INSPECTOR_PET_SIZE, viewport) - edgeGap);
|
|
12170
12309
|
}
|
|
12171
12310
|
function clampInspectorPetPosition(position, viewport) {
|
|
12172
|
-
const
|
|
12311
|
+
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12173
12312
|
return {
|
|
12174
|
-
x: Math.min(Math.max(position.x,
|
|
12175
|
-
y: Math.min(Math.max(position.y,
|
|
12313
|
+
x: Math.min(Math.max(position.x, edgeGap), maximumPetX(viewport)),
|
|
12314
|
+
y: Math.min(Math.max(position.y, edgeGap), maximumPetY(viewport))
|
|
12176
12315
|
};
|
|
12177
12316
|
}
|
|
12178
12317
|
function nearestInspectorPetEdge(position, viewport) {
|
|
12179
12318
|
const clamped = clampInspectorPetPosition(position, viewport);
|
|
12180
|
-
const
|
|
12319
|
+
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12181
12320
|
const distances = [
|
|
12182
|
-
{ edge: "left", distance: clamped.x
|
|
12321
|
+
{ edge: "left", distance: clamped.x - edgeGap },
|
|
12183
12322
|
{ edge: "right", distance: maximumPetX(viewport) - clamped.x },
|
|
12184
|
-
{ edge: "top", distance: clamped.y
|
|
12323
|
+
{ edge: "top", distance: clamped.y - edgeGap },
|
|
12185
12324
|
{ edge: "bottom", distance: maximumPetY(viewport) - clamped.y }
|
|
12186
12325
|
];
|
|
12187
12326
|
return distances.reduce((best, current) => current.distance < best.distance ? current : best).edge;
|
|
@@ -12189,33 +12328,26 @@ function nearestInspectorPetEdge(position, viewport) {
|
|
|
12189
12328
|
function snapInspectorPetToEdge(position, viewport) {
|
|
12190
12329
|
const clamped = clampInspectorPetPosition(position, viewport);
|
|
12191
12330
|
const edge = nearestInspectorPetEdge(clamped, viewport);
|
|
12192
|
-
const
|
|
12331
|
+
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12193
12332
|
switch (edge) {
|
|
12194
12333
|
case "left":
|
|
12195
|
-
return { x:
|
|
12334
|
+
return { x: edgeGap, y: clamped.y };
|
|
12196
12335
|
case "right":
|
|
12197
12336
|
return { x: maximumPetX(viewport), y: clamped.y };
|
|
12198
12337
|
case "top":
|
|
12199
|
-
return { x: clamped.x, y:
|
|
12338
|
+
return { x: clamped.x, y: edgeGap };
|
|
12200
12339
|
case "bottom":
|
|
12201
12340
|
return { x: clamped.x, y: maximumPetY(viewport) };
|
|
12202
12341
|
}
|
|
12203
12342
|
}
|
|
12204
|
-
function randomInspectorPetEdgePosition(viewport,
|
|
12343
|
+
function randomInspectorPetEdgePosition(viewport, positionSample) {
|
|
12205
12344
|
const maxX = maximumPetX(viewport);
|
|
12206
12345
|
const maxY = maximumPetY(viewport);
|
|
12207
|
-
const
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
case 0:
|
|
12213
|
-
return { x: -edgePeek, y: randomY };
|
|
12214
|
-
case 1:
|
|
12215
|
-
return { x: maxX, y: randomY };
|
|
12216
|
-
default:
|
|
12217
|
-
return { x: maxX, y: maxY };
|
|
12218
|
-
}
|
|
12346
|
+
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12347
|
+
return {
|
|
12348
|
+
x: edgeGap + clampUnit(positionSample) * (maxX - edgeGap),
|
|
12349
|
+
y: maxY
|
|
12350
|
+
};
|
|
12219
12351
|
}
|
|
12220
12352
|
function nextInspectorPetWalkingPosition(position, viewport, stepSample, directionSample) {
|
|
12221
12353
|
const clamped = snapInspectorPetToEdge(position, viewport);
|
|
@@ -12224,12 +12356,12 @@ function nextInspectorPetWalkingPosition(position, viewport, stepSample, directi
|
|
|
12224
12356
|
const edge = nearestInspectorPetEdge(clamped, viewport);
|
|
12225
12357
|
const maxX = maximumPetX(viewport);
|
|
12226
12358
|
const maxY = maximumPetY(viewport);
|
|
12227
|
-
const
|
|
12359
|
+
const edgeGap = scaledMetric(INSPECTOR_PET_EDGE_GAP, viewport);
|
|
12228
12360
|
const minimumSafeY = Math.min(scaledMetric(INSPECTOR_PET_VERTICAL_SAFE_MARGIN, viewport), maxY);
|
|
12229
12361
|
switch (edge) {
|
|
12230
12362
|
case "left":
|
|
12231
12363
|
return {
|
|
12232
|
-
x:
|
|
12364
|
+
x: edgeGap,
|
|
12233
12365
|
y: Math.min(Math.max(clamped.y + step * direction, minimumSafeY), maxY)
|
|
12234
12366
|
};
|
|
12235
12367
|
case "right":
|
|
@@ -12239,12 +12371,12 @@ function nextInspectorPetWalkingPosition(position, viewport, stepSample, directi
|
|
|
12239
12371
|
};
|
|
12240
12372
|
case "top":
|
|
12241
12373
|
return {
|
|
12242
|
-
x: Math.min(Math.max(clamped.x + step * direction,
|
|
12243
|
-
y:
|
|
12374
|
+
x: Math.min(Math.max(clamped.x + step * direction, edgeGap), maxX),
|
|
12375
|
+
y: edgeGap
|
|
12244
12376
|
};
|
|
12245
12377
|
case "bottom":
|
|
12246
12378
|
return {
|
|
12247
|
-
x: Math.min(Math.max(clamped.x + step * direction,
|
|
12379
|
+
x: Math.min(Math.max(clamped.x + step * direction, edgeGap), maxX),
|
|
12248
12380
|
y: maxY
|
|
12249
12381
|
};
|
|
12250
12382
|
}
|
|
@@ -12333,12 +12465,344 @@ function resolveInspectorPetStatus(logs, nowMs) {
|
|
|
12333
12465
|
capturedCount
|
|
12334
12466
|
};
|
|
12335
12467
|
}
|
|
12468
|
+
function createRod(start, end, radius, material) {
|
|
12469
|
+
const direction = end.clone().sub(start);
|
|
12470
|
+
const length = direction.length();
|
|
12471
|
+
const rod = new Mesh(new CylinderGeometry(radius, radius * 0.9, length, 12), material);
|
|
12472
|
+
rod.position.copy(start.clone().add(end).multiplyScalar(0.5));
|
|
12473
|
+
rod.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), direction.normalize());
|
|
12474
|
+
return rod;
|
|
12475
|
+
}
|
|
12476
|
+
function addClaw(root, side, shellMaterial, accentMaterial) {
|
|
12477
|
+
const clawScale = side < 0 ? 1.5 : 0.68;
|
|
12478
|
+
const clawGroup = new Group();
|
|
12479
|
+
const pincers = [];
|
|
12480
|
+
root.add(clawGroup);
|
|
12481
|
+
const shoulder = new Vector3(side * 1.2, 0.25, -0.05);
|
|
12482
|
+
const wrist = new Vector3(side * (1.65 + clawScale * 0.18), 0.5, 0);
|
|
12483
|
+
const arm = createRod(shoulder, wrist, 0.16 * clawScale, accentMaterial);
|
|
12484
|
+
clawGroup.add(arm);
|
|
12485
|
+
const palm = new Mesh(new SphereGeometry(0.55, 24, 16), shellMaterial);
|
|
12486
|
+
palm.position.set(side * (1.95 + clawScale * 0.16), 0.62, 0.05);
|
|
12487
|
+
palm.scale.set(1.05 * clawScale, 0.72 * clawScale, 0.55 * clawScale);
|
|
12488
|
+
clawGroup.add(palm);
|
|
12489
|
+
for (const pincerDirection of [-1, 1]) {
|
|
12490
|
+
const pincer = new Mesh(new SphereGeometry(0.36, 20, 14), accentMaterial);
|
|
12491
|
+
pincer.position.set(
|
|
12492
|
+
side * (2.22 + clawScale * 0.26),
|
|
12493
|
+
0.62 + pincerDirection * 0.24 * clawScale,
|
|
12494
|
+
0.08
|
|
12495
|
+
);
|
|
12496
|
+
pincer.scale.set(1.05 * clawScale, 0.34 * clawScale, 0.42 * clawScale);
|
|
12497
|
+
pincer.rotation.z = pincerDirection * side * 0.42;
|
|
12498
|
+
clawGroup.add(pincer);
|
|
12499
|
+
pincers.push({
|
|
12500
|
+
direction: pincerDirection,
|
|
12501
|
+
mesh: pincer,
|
|
12502
|
+
restRotationZ: pincer.rotation.z,
|
|
12503
|
+
restY: pincer.position.y
|
|
12504
|
+
});
|
|
12505
|
+
}
|
|
12506
|
+
return { group: clawGroup, pincers, scale: clawScale };
|
|
12507
|
+
}
|
|
12508
|
+
function pinchPulse(cycleTime, start, duration) {
|
|
12509
|
+
const progress = (cycleTime - start) / duration;
|
|
12510
|
+
if (progress <= 0 || progress >= 1) return 0;
|
|
12511
|
+
return Math.sin(progress * Math.PI);
|
|
12512
|
+
}
|
|
12513
|
+
function dominantClawGrip(elapsed) {
|
|
12514
|
+
const cycleTime = elapsed % 6.8;
|
|
12515
|
+
return Math.max(pinchPulse(cycleTime, 0.72, 0.82), pinchPulse(cycleTime, 1.72, 0.68));
|
|
12516
|
+
}
|
|
12517
|
+
function addEyes(root, shellMaterial, eyeMaterial) {
|
|
12518
|
+
const eyes = [];
|
|
12519
|
+
for (const side of [-1, 1]) {
|
|
12520
|
+
const stalkStart = new Vector3(side * 0.48, 0.68, 0.05);
|
|
12521
|
+
const stalkEnd = new Vector3(side * 0.1, 0.82, 0.07);
|
|
12522
|
+
const eyeGroup = new Group();
|
|
12523
|
+
eyeGroup.position.copy(stalkStart);
|
|
12524
|
+
eyeGroup.add(createRod(new Vector3(0, 0, 0), stalkEnd, 0.1, shellMaterial));
|
|
12525
|
+
const eye = new Mesh(new SphereGeometry(0.24, 20, 16), eyeMaterial);
|
|
12526
|
+
eye.position.copy(stalkEnd);
|
|
12527
|
+
eye.scale.set(1, 1, 0.85);
|
|
12528
|
+
eyeGroup.add(eye);
|
|
12529
|
+
const pupil = new Mesh(
|
|
12530
|
+
new SphereGeometry(0.105, 16, 12),
|
|
12531
|
+
new MeshPhysicalMaterial({ color: 1120295, roughness: 0.25 })
|
|
12532
|
+
);
|
|
12533
|
+
const pupilRest = new Vector3(stalkEnd.x, stalkEnd.y, stalkEnd.z + 0.2);
|
|
12534
|
+
pupil.position.copy(pupilRest);
|
|
12535
|
+
eyeGroup.add(pupil);
|
|
12536
|
+
root.add(eyeGroup);
|
|
12537
|
+
eyes.push({
|
|
12538
|
+
group: eyeGroup,
|
|
12539
|
+
phase: side < 0 ? 0 : Math.PI / 3,
|
|
12540
|
+
pupil,
|
|
12541
|
+
pupilRest
|
|
12542
|
+
});
|
|
12543
|
+
}
|
|
12544
|
+
return eyes;
|
|
12545
|
+
}
|
|
12546
|
+
function addLegs(root, legMaterial) {
|
|
12547
|
+
const legs = [];
|
|
12548
|
+
for (const side of [-1, 1]) {
|
|
12549
|
+
for (let index = 0; index < 4; index += 1) {
|
|
12550
|
+
const leg = new Group();
|
|
12551
|
+
const baseY = -0.3 - index * 0.22;
|
|
12552
|
+
leg.position.set(side * (0.8 + index * 0.12), baseY, -0.18);
|
|
12553
|
+
leg.add(
|
|
12554
|
+
createRod(
|
|
12555
|
+
new Vector3(0, 0, 0),
|
|
12556
|
+
new Vector3(side * (0.62 + index * 0.06), -0.34, 0),
|
|
12557
|
+
0.095,
|
|
12558
|
+
legMaterial
|
|
12559
|
+
)
|
|
12560
|
+
);
|
|
12561
|
+
leg.add(
|
|
12562
|
+
createRod(
|
|
12563
|
+
new Vector3(side * (0.58 + index * 0.06), -0.31, 0),
|
|
12564
|
+
new Vector3(side * (1.02 + index * 0.08), -0.88 + index * 0.07, 0.04),
|
|
12565
|
+
0.075,
|
|
12566
|
+
legMaterial
|
|
12567
|
+
)
|
|
12568
|
+
);
|
|
12569
|
+
root.add(leg);
|
|
12570
|
+
legs.push({ group: leg, phase: index * Math.PI + (side > 0 ? Math.PI / 2 : 0), side });
|
|
12571
|
+
}
|
|
12572
|
+
}
|
|
12573
|
+
return legs;
|
|
12574
|
+
}
|
|
12575
|
+
function createCrabScene(scene) {
|
|
12576
|
+
const shellMaterial = new MeshPhysicalMaterial({
|
|
12577
|
+
color: 16096779,
|
|
12578
|
+
roughness: 0.34,
|
|
12579
|
+
metalness: 0.04,
|
|
12580
|
+
clearcoat: 0.78,
|
|
12581
|
+
clearcoatRoughness: 0.18,
|
|
12582
|
+
emissive: new Color(0),
|
|
12583
|
+
emissiveIntensity: 0
|
|
12584
|
+
});
|
|
12585
|
+
const accentMaterial = new MeshPhysicalMaterial({
|
|
12586
|
+
color: 16486972,
|
|
12587
|
+
roughness: 0.42,
|
|
12588
|
+
metalness: 0.02,
|
|
12589
|
+
clearcoat: 0.52,
|
|
12590
|
+
clearcoatRoughness: 0.28
|
|
12591
|
+
});
|
|
12592
|
+
const legMaterial = new MeshPhysicalMaterial({
|
|
12593
|
+
color: 14251782,
|
|
12594
|
+
roughness: 0.48,
|
|
12595
|
+
clearcoat: 0.35,
|
|
12596
|
+
clearcoatRoughness: 0.35
|
|
12597
|
+
});
|
|
12598
|
+
const eyeMaterial = new MeshPhysicalMaterial({
|
|
12599
|
+
color: 16776171,
|
|
12600
|
+
roughness: 0.22,
|
|
12601
|
+
clearcoat: 0.8,
|
|
12602
|
+
clearcoatRoughness: 0.12
|
|
12603
|
+
});
|
|
12604
|
+
const root = new Group();
|
|
12605
|
+
root.rotation.x = -0.12;
|
|
12606
|
+
root.rotation.y = -0.08;
|
|
12607
|
+
root.scale.setScalar(1.08);
|
|
12608
|
+
scene.add(root);
|
|
12609
|
+
const shadow = new Mesh(
|
|
12610
|
+
new CircleGeometry(1.65, 40),
|
|
12611
|
+
new MeshBasicMaterial({ color: 1120295, transparent: true, opacity: 0.16, depthWrite: false })
|
|
12612
|
+
);
|
|
12613
|
+
shadow.position.set(0, -1.33, -0.65);
|
|
12614
|
+
shadow.scale.set(1.4, 0.34, 1);
|
|
12615
|
+
root.add(shadow);
|
|
12616
|
+
const body = new Mesh(new SphereGeometry(1, 36, 24), shellMaterial);
|
|
12617
|
+
body.position.set(0, 0.02, 0);
|
|
12618
|
+
body.scale.set(1.58, 0.92, 0.68);
|
|
12619
|
+
root.add(body);
|
|
12620
|
+
const lowerShell = new Mesh(new SphereGeometry(0.92, 28, 20), accentMaterial);
|
|
12621
|
+
lowerShell.position.set(0, -0.48, 0.22);
|
|
12622
|
+
lowerShell.scale.set(1.28, 0.42, 0.56);
|
|
12623
|
+
root.add(lowerShell);
|
|
12624
|
+
const dominantClaw = addClaw(root, -1, shellMaterial, accentMaterial);
|
|
12625
|
+
addClaw(root, 1, shellMaterial, accentMaterial);
|
|
12626
|
+
const eyes = addEyes(root, shellMaterial, eyeMaterial);
|
|
12627
|
+
const legs = addLegs(root, legMaterial);
|
|
12628
|
+
scene.add(new AmbientLight(16775149, 1.65));
|
|
12629
|
+
scene.add(new HemisphereLight(16775149, 1515571, 2.15));
|
|
12630
|
+
const keyLight = new DirectionalLight(16777215, 3.6);
|
|
12631
|
+
keyLight.position.set(3.5, 4.5, 6);
|
|
12632
|
+
scene.add(keyLight);
|
|
12633
|
+
const fillLight = new DirectionalLight(16498468, 1.35);
|
|
12634
|
+
fillLight.position.set(-4, 1.5, 4);
|
|
12635
|
+
scene.add(fillLight);
|
|
12636
|
+
const rimLight = new PointLight(16096779, 1.8, 12, 2);
|
|
12637
|
+
rimLight.position.set(0, 1.8, 4.5);
|
|
12638
|
+
scene.add(rimLight);
|
|
12639
|
+
return { bodyMaterial: shellMaterial, dominantClaw, eyes, legs, rimLight, root };
|
|
12640
|
+
}
|
|
12641
|
+
function moodColor(mood) {
|
|
12642
|
+
switch (mood) {
|
|
12643
|
+
case "active":
|
|
12644
|
+
return 2282478;
|
|
12645
|
+
case "attention":
|
|
12646
|
+
return 15680580;
|
|
12647
|
+
case "idle":
|
|
12648
|
+
return 16096779;
|
|
12649
|
+
case "sleeping":
|
|
12650
|
+
return 9741240;
|
|
12651
|
+
}
|
|
12652
|
+
}
|
|
12653
|
+
function isDisposableMesh(object2) {
|
|
12654
|
+
return object2 instanceof Mesh;
|
|
12655
|
+
}
|
|
12656
|
+
function disposeScene(scene) {
|
|
12657
|
+
const materials = /* @__PURE__ */ new Set();
|
|
12658
|
+
scene.traverse((object2) => {
|
|
12659
|
+
if (!isDisposableMesh(object2)) return;
|
|
12660
|
+
object2.geometry.dispose();
|
|
12661
|
+
const material = object2.material;
|
|
12662
|
+
if (Array.isArray(material)) {
|
|
12663
|
+
for (const item of material) materials.add(item);
|
|
12664
|
+
return;
|
|
12665
|
+
}
|
|
12666
|
+
materials.add(material);
|
|
12667
|
+
});
|
|
12668
|
+
for (const material of materials) material.dispose();
|
|
12669
|
+
}
|
|
12670
|
+
function InspectorPetCrab3D({
|
|
12671
|
+
mood,
|
|
12672
|
+
moving,
|
|
12673
|
+
reduceMotion
|
|
12674
|
+
}) {
|
|
12675
|
+
const canvasRef = reactExports.useRef(null);
|
|
12676
|
+
const moodRef = reactExports.useRef(mood);
|
|
12677
|
+
const movingRef = reactExports.useRef(moving);
|
|
12678
|
+
const reduceMotionRef = reactExports.useRef(reduceMotion);
|
|
12679
|
+
const [renderFailed, setRenderFailed] = reactExports.useState(false);
|
|
12680
|
+
reactExports.useEffect(() => {
|
|
12681
|
+
moodRef.current = mood;
|
|
12682
|
+
}, [mood]);
|
|
12683
|
+
reactExports.useEffect(() => {
|
|
12684
|
+
movingRef.current = moving;
|
|
12685
|
+
}, [moving]);
|
|
12686
|
+
reactExports.useEffect(() => {
|
|
12687
|
+
reduceMotionRef.current = reduceMotion;
|
|
12688
|
+
}, [reduceMotion]);
|
|
12689
|
+
reactExports.useEffect(() => {
|
|
12690
|
+
const canvas = canvasRef.current;
|
|
12691
|
+
if (canvas === null) return void 0;
|
|
12692
|
+
let renderer;
|
|
12693
|
+
try {
|
|
12694
|
+
renderer = new WebGLRenderer({
|
|
12695
|
+
alpha: true,
|
|
12696
|
+
antialias: true,
|
|
12697
|
+
canvas,
|
|
12698
|
+
powerPreference: "low-power",
|
|
12699
|
+
preserveDrawingBuffer: true
|
|
12700
|
+
});
|
|
12701
|
+
} catch {
|
|
12702
|
+
setRenderFailed(true);
|
|
12703
|
+
return void 0;
|
|
12704
|
+
}
|
|
12705
|
+
renderer.setClearColor(0, 0);
|
|
12706
|
+
renderer.outputColorSpace = SRGBColorSpace;
|
|
12707
|
+
renderer.toneMapping = ACESFilmicToneMapping;
|
|
12708
|
+
renderer.toneMappingExposure = 1.18;
|
|
12709
|
+
const scene = new Scene();
|
|
12710
|
+
const camera = new OrthographicCamera(-3.65, 3.65, 3.65, -3.65, 0.1, 20);
|
|
12711
|
+
camera.position.set(0, 0.05, 8);
|
|
12712
|
+
camera.lookAt(0, 0, 0);
|
|
12713
|
+
const parts = createCrabScene(scene);
|
|
12714
|
+
const startedAt = window.performance.now();
|
|
12715
|
+
let lastFrameAt = 0;
|
|
12716
|
+
const renderFrame = (timestamp) => {
|
|
12717
|
+
if (timestamp - lastFrameAt < 32) return;
|
|
12718
|
+
lastFrameAt = timestamp;
|
|
12719
|
+
const elapsed = (timestamp - startedAt) / 1e3;
|
|
12720
|
+
const motionAllowed = !reduceMotionRef.current;
|
|
12721
|
+
const gait = movingRef.current ? 1 : moodRef.current === "active" ? 0.42 : 0;
|
|
12722
|
+
const idleMotion = motionAllowed ? Math.sin(elapsed * 0.85) : 0;
|
|
12723
|
+
const stepMotion = motionAllowed ? Math.sin(elapsed * 3.4) : 0;
|
|
12724
|
+
const clawGrip = motionAllowed ? dominantClawGrip(elapsed) : 0;
|
|
12725
|
+
parts.root.position.y = idleMotion * 0.035 + Math.abs(stepMotion) * 0.055 * gait;
|
|
12726
|
+
parts.root.rotation.y = -0.08 + idleMotion * 0.055;
|
|
12727
|
+
parts.root.rotation.z = stepMotion * 0.028 * gait;
|
|
12728
|
+
parts.dominantClaw.group.rotation.z = -clawGrip * 0.035;
|
|
12729
|
+
for (const pincer of parts.dominantClaw.pincers) {
|
|
12730
|
+
pincer.mesh.position.y = pincer.restY - pincer.direction * parts.dominantClaw.scale * 0.16 * clawGrip;
|
|
12731
|
+
pincer.mesh.rotation.z = pincer.restRotationZ * (1 - clawGrip * 0.72);
|
|
12732
|
+
}
|
|
12733
|
+
for (const leg of parts.legs) {
|
|
12734
|
+
leg.group.rotation.z = motionAllowed && gait > 0 ? Math.sin(elapsed * 4.25 + leg.phase) * 0.2 * leg.side * gait : 0;
|
|
12735
|
+
leg.group.rotation.x = motionAllowed && gait > 0 ? stepMotion * 0.045 * gait : 0;
|
|
12736
|
+
}
|
|
12737
|
+
for (const eye of parts.eyes) {
|
|
12738
|
+
const gaze = motionAllowed ? Math.sin(elapsed * 0.72 + eye.phase) : 0;
|
|
12739
|
+
const lift = motionAllowed ? Math.cos(elapsed * 0.9 + eye.phase) : 0;
|
|
12740
|
+
eye.group.rotation.z = gaze * 0.075;
|
|
12741
|
+
eye.group.rotation.x = lift * 0.025;
|
|
12742
|
+
eye.pupil.position.set(
|
|
12743
|
+
eye.pupilRest.x + gaze * 0.055,
|
|
12744
|
+
eye.pupilRest.y + lift * 0.025,
|
|
12745
|
+
eye.pupilRest.z
|
|
12746
|
+
);
|
|
12747
|
+
}
|
|
12748
|
+
const color = moodColor(moodRef.current);
|
|
12749
|
+
parts.rimLight.color.setHex(color);
|
|
12750
|
+
parts.rimLight.intensity = moodRef.current === "attention" ? 3.2 : 1.8;
|
|
12751
|
+
parts.bodyMaterial.emissive.setHex(color);
|
|
12752
|
+
parts.bodyMaterial.emissiveIntensity = moodRef.current === "active" ? 0.12 : 0.035;
|
|
12753
|
+
renderer.render(scene, camera);
|
|
12754
|
+
};
|
|
12755
|
+
const resize = () => {
|
|
12756
|
+
const width = Math.max(canvas.clientWidth, 1);
|
|
12757
|
+
const height = Math.max(canvas.clientHeight, 1);
|
|
12758
|
+
renderer.setDrawingBufferSize(width, height, Math.min(window.devicePixelRatio, 2));
|
|
12759
|
+
renderer.render(scene, camera);
|
|
12760
|
+
};
|
|
12761
|
+
const resizeObserver = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(resize);
|
|
12762
|
+
if (resizeObserver === null) {
|
|
12763
|
+
window.addEventListener("resize", resize);
|
|
12764
|
+
} else {
|
|
12765
|
+
resizeObserver.observe(canvas);
|
|
12766
|
+
}
|
|
12767
|
+
resize();
|
|
12768
|
+
const handleContextLost = (event) => {
|
|
12769
|
+
event.preventDefault();
|
|
12770
|
+
setRenderFailed(true);
|
|
12771
|
+
};
|
|
12772
|
+
canvas.addEventListener("webglcontextlost", handleContextLost);
|
|
12773
|
+
renderer.setAnimationLoop(renderFrame);
|
|
12774
|
+
return () => {
|
|
12775
|
+
renderer.setAnimationLoop(null);
|
|
12776
|
+
if (resizeObserver === null) {
|
|
12777
|
+
window.removeEventListener("resize", resize);
|
|
12778
|
+
} else {
|
|
12779
|
+
resizeObserver.disconnect();
|
|
12780
|
+
}
|
|
12781
|
+
canvas.removeEventListener("webglcontextlost", handleContextLost);
|
|
12782
|
+
disposeScene(scene);
|
|
12783
|
+
renderer.dispose();
|
|
12784
|
+
};
|
|
12785
|
+
}, []);
|
|
12786
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "relative flex size-24 items-center justify-center", "aria-hidden": "true", children: [
|
|
12787
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12788
|
+
"canvas",
|
|
12789
|
+
{
|
|
12790
|
+
ref: canvasRef,
|
|
12791
|
+
className: renderFailed ? "hidden" : "block size-full bg-transparent",
|
|
12792
|
+
"data-inspector-pet-canvas": "true"
|
|
12793
|
+
}
|
|
12794
|
+
),
|
|
12795
|
+
renderFailed && /* @__PURE__ */ jsxRuntimeExports.jsx(CrabLogo, { className: "size-22 text-amber-500 drop-shadow-[0_0_18px_rgba(245,158,11,0.28)]" })
|
|
12796
|
+
] });
|
|
12797
|
+
}
|
|
12336
12798
|
const INSPECTOR_PET_ROAMING_STORAGE_KEY = "agent-inspector.pet.roaming";
|
|
12337
|
-
const
|
|
12338
|
-
const
|
|
12799
|
+
const INSPECTOR_PET_MIN_PAUSE_MS = 11e3;
|
|
12800
|
+
const INSPECTOR_PET_PAUSE_WINDOW_MS = 9e3;
|
|
12801
|
+
const INSPECTOR_PET_SCUTTLE_MS = 7200;
|
|
12339
12802
|
const INSPECTOR_PET_PANEL_DISMISS_MS = 6e3;
|
|
12340
12803
|
const INSPECTOR_PET_REACTION_MS = 760;
|
|
12341
12804
|
const INSPECTOR_PET_DRAG_THRESHOLD = 4;
|
|
12805
|
+
const INSPECTOR_PET_TOP_LAYER_Z_INDEX = 2147483647;
|
|
12342
12806
|
function readViewport() {
|
|
12343
12807
|
if (typeof window === "undefined") return { width: 1280, height: 720, scale: 1 };
|
|
12344
12808
|
const rawScale = window.getComputedStyle(document.documentElement).getPropertyValue("--inspector-ui-scale");
|
|
@@ -12383,13 +12847,14 @@ function moodMotionClass(mood) {
|
|
|
12383
12847
|
}
|
|
12384
12848
|
}
|
|
12385
12849
|
function InspectorPet({ logs }) {
|
|
12850
|
+
const [portalHost, setPortalHost] = reactExports.useState(null);
|
|
12386
12851
|
const [viewport, setViewport] = reactExports.useState(readViewport);
|
|
12387
12852
|
const [position, setPosition] = reactExports.useState({
|
|
12388
12853
|
x: INSPECTOR_PET_MARGIN,
|
|
12389
12854
|
y: INSPECTOR_PET_MARGIN
|
|
12390
12855
|
});
|
|
12391
12856
|
const [clockMs, setClockMs] = reactExports.useState(() => Date.now());
|
|
12392
|
-
const [
|
|
12857
|
+
const [scuttling, setScuttling] = reactExports.useState(false);
|
|
12393
12858
|
const [panelTick, setPanelTick] = reactExports.useState(0);
|
|
12394
12859
|
const [panelVisible, setPanelVisible] = reactExports.useState(false);
|
|
12395
12860
|
const [reactionTick, setReactionTick] = reactExports.useState(0);
|
|
@@ -12404,10 +12869,11 @@ function InspectorPet({ logs }) {
|
|
|
12404
12869
|
() => inspectorPetPanelPosition(position, viewport),
|
|
12405
12870
|
[position, viewport]
|
|
12406
12871
|
);
|
|
12872
|
+
reactExports.useEffect(() => setPortalHost(document.body), []);
|
|
12407
12873
|
reactExports.useEffect(() => {
|
|
12408
12874
|
const nextViewport = readViewport();
|
|
12409
12875
|
setViewport(nextViewport);
|
|
12410
|
-
setPosition(randomInspectorPetEdgePosition(nextViewport, Math.random()
|
|
12876
|
+
setPosition(randomInspectorPetEdgePosition(nextViewport, Math.random()));
|
|
12411
12877
|
}, []);
|
|
12412
12878
|
reactExports.useEffect(() => {
|
|
12413
12879
|
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
@@ -12428,25 +12894,31 @@ function InspectorPet({ logs }) {
|
|
|
12428
12894
|
}, [roaming]);
|
|
12429
12895
|
reactExports.useEffect(() => {
|
|
12430
12896
|
if (!roaming || dragging || reduceMotion) return void 0;
|
|
12431
|
-
let
|
|
12432
|
-
|
|
12433
|
-
|
|
12434
|
-
|
|
12435
|
-
|
|
12897
|
+
let pauseTimeoutId = null;
|
|
12898
|
+
let scuttleTimeoutId = null;
|
|
12899
|
+
const scheduleScuttle = () => {
|
|
12900
|
+
const delay = INSPECTOR_PET_MIN_PAUSE_MS + Math.random() * INSPECTOR_PET_PAUSE_WINDOW_MS;
|
|
12901
|
+
pauseTimeoutId = window.setTimeout(() => {
|
|
12902
|
+
setScuttling(true);
|
|
12436
12903
|
setPosition(
|
|
12437
12904
|
(current) => nextInspectorPetWalkingPosition(current, viewport, Math.random(), Math.random())
|
|
12438
12905
|
);
|
|
12439
|
-
|
|
12906
|
+
scuttleTimeoutId = window.setTimeout(() => {
|
|
12907
|
+
setScuttling(false);
|
|
12908
|
+
scheduleScuttle();
|
|
12909
|
+
}, INSPECTOR_PET_SCUTTLE_MS);
|
|
12440
12910
|
}, delay);
|
|
12441
12911
|
};
|
|
12442
|
-
|
|
12912
|
+
scheduleScuttle();
|
|
12443
12913
|
return () => {
|
|
12444
|
-
if (
|
|
12914
|
+
if (pauseTimeoutId !== null) window.clearTimeout(pauseTimeoutId);
|
|
12915
|
+
if (scuttleTimeoutId !== null) window.clearTimeout(scuttleTimeoutId);
|
|
12445
12916
|
};
|
|
12446
12917
|
}, [dragging, reduceMotion, roaming, viewport]);
|
|
12447
12918
|
reactExports.useEffect(() => {
|
|
12448
12919
|
const handleResize = () => {
|
|
12449
12920
|
const nextViewport = readViewport();
|
|
12921
|
+
setScuttling(false);
|
|
12450
12922
|
setViewport(nextViewport);
|
|
12451
12923
|
setPosition((current) => snapInspectorPetToEdge(current, nextViewport));
|
|
12452
12924
|
};
|
|
@@ -12489,6 +12961,7 @@ function InspectorPet({ logs }) {
|
|
|
12489
12961
|
moved: false
|
|
12490
12962
|
};
|
|
12491
12963
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
12964
|
+
setScuttling(false);
|
|
12492
12965
|
setPanelVisible(false);
|
|
12493
12966
|
setDragging(true);
|
|
12494
12967
|
}, []);
|
|
@@ -12533,135 +13006,136 @@ function InspectorPet({ logs }) {
|
|
|
12533
13006
|
dragOccurredRef.current = false;
|
|
12534
13007
|
setDragging(false);
|
|
12535
13008
|
}, []);
|
|
13009
|
+
const handleToggleRoaming = reactExports.useCallback(() => {
|
|
13010
|
+
setScuttling(false);
|
|
13011
|
+
setRoaming((current) => !current);
|
|
13012
|
+
}, []);
|
|
12536
13013
|
const petStyle = reactExports.useMemo(
|
|
12537
13014
|
() => ({
|
|
12538
|
-
transform: `translate3d(${String(position.x)}px, ${String(position.y)}px, 0)
|
|
12539
|
-
transition: dragging ? "none" :
|
|
13015
|
+
transform: `translate3d(${String(position.x)}px, ${String(position.y)}px, 0) scale(${dragging ? "1.04" : "1"})`,
|
|
13016
|
+
transition: dragging ? "none" : scuttling ? `transform ${String(INSPECTOR_PET_SCUTTLE_MS)}ms cubic-bezier(0.22, 0.72, 0.32, 1)` : "transform 900ms cubic-bezier(0.22, 0.72, 0.32, 1)",
|
|
12540
13017
|
touchAction: "none"
|
|
12541
13018
|
}),
|
|
12542
|
-
[dragging,
|
|
13019
|
+
[dragging, position.x, position.y, scuttling]
|
|
12543
13020
|
);
|
|
12544
13021
|
const panelStyle = reactExports.useMemo(
|
|
12545
13022
|
() => ({ left: panelPosition.x, top: panelPosition.y }),
|
|
12546
13023
|
[panelPosition.x, panelPosition.y]
|
|
12547
13024
|
);
|
|
12548
13025
|
const roamingLabel = roaming ? "Pause pet roaming" : "Resume pet roaming";
|
|
12549
|
-
return /* @__PURE__ */ jsxRuntimeExports.
|
|
12550
|
-
|
|
12551
|
-
|
|
13026
|
+
if (portalHost === null) return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, {});
|
|
13027
|
+
return reactDomExports.createPortal(
|
|
13028
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13029
|
+
"div",
|
|
12552
13030
|
{
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
|
|
12570
|
-
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12575
|
-
|
|
12576
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13031
|
+
className: "pointer-events-none fixed inset-0 isolate",
|
|
13032
|
+
style: { zIndex: INSPECTOR_PET_TOP_LAYER_Z_INDEX },
|
|
13033
|
+
"data-inspector-pet-layer": "true",
|
|
13034
|
+
children: [
|
|
13035
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13036
|
+
"button",
|
|
13037
|
+
{
|
|
13038
|
+
type: "button",
|
|
13039
|
+
className: cn(
|
|
13040
|
+
"pointer-events-auto fixed left-0 top-0 z-10 flex size-28 items-center justify-center bg-transparent text-foreground outline-none transition-[filter,opacity] duration-200 hover:opacity-95 hover:drop-shadow-[0_0_28px_rgba(245,158,11,0.32)] focus-visible:drop-shadow-[0_0_14px_rgba(251,191,36,0.72)]",
|
|
13041
|
+
dragging ? "cursor-grabbing" : "cursor-grab"
|
|
13042
|
+
),
|
|
13043
|
+
style: petStyle,
|
|
13044
|
+
"data-pet-mood": status.mood,
|
|
13045
|
+
"data-pet-moving": scuttling ? "true" : "false",
|
|
13046
|
+
onClick: handlePet,
|
|
13047
|
+
onPointerDown: handlePointerDown,
|
|
13048
|
+
onPointerMove: handlePointerMove,
|
|
13049
|
+
onPointerUp: handlePointerUp,
|
|
13050
|
+
onPointerCancel: handlePointerCancel,
|
|
13051
|
+
"aria-label": `Inspector pet: ${status.label}`,
|
|
13052
|
+
title: status.label,
|
|
13053
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
12577
13054
|
"span",
|
|
12578
13055
|
{
|
|
12579
13056
|
className: cn(
|
|
12580
|
-
"relative flex size-
|
|
12581
|
-
|
|
13057
|
+
"relative z-10 flex size-24 items-center justify-center",
|
|
13058
|
+
reactionVisible && "inspector-pet-patted"
|
|
12582
13059
|
),
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "
|
|
12593
|
-
|
|
13060
|
+
"aria-hidden": "true",
|
|
13061
|
+
children: [
|
|
13062
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13063
|
+
"span",
|
|
13064
|
+
{
|
|
13065
|
+
className: cn(
|
|
13066
|
+
"relative flex size-24 items-center justify-center",
|
|
13067
|
+
moodMotionClass(status.mood)
|
|
13068
|
+
),
|
|
13069
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "relative flex size-24 items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13070
|
+
InspectorPetCrab3D,
|
|
12594
13071
|
{
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
|
|
12598
|
-
|
|
12599
|
-
|
|
12600
|
-
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
|
|
13072
|
+
mood: status.mood,
|
|
13073
|
+
moving: scuttling && !dragging,
|
|
13074
|
+
reduceMotion
|
|
13075
|
+
}
|
|
13076
|
+
) })
|
|
13077
|
+
}
|
|
13078
|
+
),
|
|
13079
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13080
|
+
"span",
|
|
13081
|
+
{
|
|
13082
|
+
className: cn(
|
|
13083
|
+
"absolute right-0 top-2 size-3 rounded-full border border-background/90",
|
|
13084
|
+
moodDotClass(status.mood),
|
|
13085
|
+
status.mood === "active" && !reduceMotion && "animate-pulse"
|
|
13086
|
+
)
|
|
13087
|
+
}
|
|
13088
|
+
),
|
|
13089
|
+
reactionVisible && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13090
|
+
Heart,
|
|
13091
|
+
{
|
|
13092
|
+
className: "inspector-pet-heart absolute -right-2 -top-3 size-5 fill-amber-400 text-amber-400"
|
|
13093
|
+
},
|
|
13094
|
+
reactionTick
|
|
13095
|
+
)
|
|
13096
|
+
]
|
|
12617
13097
|
}
|
|
12618
|
-
),
|
|
12619
|
-
reactionVisible && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
12620
|
-
Heart,
|
|
12621
|
-
{
|
|
12622
|
-
className: "inspector-pet-heart absolute -right-1 -top-2 size-3.5 fill-amber-400 text-amber-400"
|
|
12623
|
-
},
|
|
12624
|
-
reactionTick
|
|
12625
13098
|
)
|
|
12626
|
-
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12654
|
-
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
|
|
13099
|
+
}
|
|
13100
|
+
),
|
|
13101
|
+
panelVisible && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
13102
|
+
"div",
|
|
13103
|
+
{
|
|
13104
|
+
className: "pointer-events-auto fixed z-20 w-48 rounded-md border border-border/80 bg-popover/95 px-3 py-2 text-popover-foreground shadow-[0_14px_34px_rgba(0,0,0,0.28)] backdrop-blur",
|
|
13105
|
+
style: panelStyle,
|
|
13106
|
+
role: "status",
|
|
13107
|
+
"aria-live": "polite",
|
|
13108
|
+
children: [
|
|
13109
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
13110
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("size-2 shrink-0 rounded-full", moodDotClass(status.mood)) }),
|
|
13111
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 truncate text-xs font-medium", children: status.label }),
|
|
13112
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
13113
|
+
"button",
|
|
13114
|
+
{
|
|
13115
|
+
type: "button",
|
|
13116
|
+
className: "inline-flex size-6 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none",
|
|
13117
|
+
onClick: handleToggleRoaming,
|
|
13118
|
+
"aria-label": roamingLabel,
|
|
13119
|
+
title: roamingLabel,
|
|
13120
|
+
children: roaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(Pause, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Play, { className: "size-3.5" })
|
|
13121
|
+
}
|
|
13122
|
+
)
|
|
13123
|
+
] }),
|
|
13124
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex items-center justify-between gap-3 font-mono text-[10px] text-muted-foreground", children: [
|
|
13125
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
13126
|
+
String(status.capturedCount),
|
|
13127
|
+
" captured"
|
|
13128
|
+
] }),
|
|
13129
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: status.pendingCount > 0 ? `${String(status.pendingCount)} active` : scuttling ? "Scuttling" : roaming ? "Resting" : "Paused" })
|
|
13130
|
+
] })
|
|
13131
|
+
]
|
|
13132
|
+
}
|
|
13133
|
+
)
|
|
12661
13134
|
]
|
|
12662
13135
|
}
|
|
12663
|
-
)
|
|
12664
|
-
|
|
13136
|
+
),
|
|
13137
|
+
portalHost
|
|
13138
|
+
);
|
|
12665
13139
|
}
|
|
12666
13140
|
const DEFAULT_QUESTION = "Analyze the current Inspector session. What looks abnormal, slow, or likely to hang?";
|
|
12667
13141
|
function providerSupportsPiAgent(provider) {
|