@tonyclaw/agent-inspector 2.1.17 → 2.1.18
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-B9sLBHw5.js → CompareDrawer-Fqqw5Lci.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-DbWjc_BE.js → ProxyViewerContainer-CP_RzwW9.js} +31 -31
- package/.output/public/assets/{ReplayDialog-D9I9W9n3.js → ReplayDialog-hYhz_i6W.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-DGXK_Rii.js → RequestAnatomy-CTuWbtwC.js} +1 -1
- package/.output/public/assets/{ResponseView-df_JzwsS.js → ResponseView-CsZ7S5Gv.js} +2 -2
- package/.output/public/assets/{StreamingChunkSequence-i3DM5IKL.js → StreamingChunkSequence-PIbJMotU.js} +1 -1
- package/.output/public/assets/_sessionId-CUGA9qU3.js +1 -0
- package/.output/public/assets/{index-Dqc2r1ea.js → index-F7mynwuH.js} +1 -1
- package/.output/public/assets/index-G4dTUobw.js +1 -0
- package/.output/public/assets/index-gvYkgMPF.css +1 -0
- package/.output/public/assets/{json-viewer-D3QWQlSB.js → json-viewer-DCXtNmmD.js} +1 -1
- package/.output/public/assets/{main-ZhxhOCmF.js → main-BJZf7_Ib.js} +2 -2
- package/.output/server/{_sessionId-YFrP0lZP.mjs → _sessionId-DjSHDNh8.mjs} +2 -2
- package/.output/server/_ssr/{CompareDrawer-qC3adEeq.mjs → CompareDrawer-Dal52IFo.mjs} +2 -2
- package/.output/server/_ssr/{ProxyViewerContainer-DCZIJC2b.mjs → ProxyViewerContainer-CVqFZGff.mjs} +1923 -1918
- package/.output/server/_ssr/{ReplayDialog-CvX4XYCi.mjs → ReplayDialog-BOEgdMes.mjs} +3 -3
- package/.output/server/_ssr/{RequestAnatomy-HQfrxjO1.mjs → RequestAnatomy-gch7_vCV.mjs} +2 -2
- package/.output/server/_ssr/{ResponseView-QSlSD11e.mjs → ResponseView-lEWPy-H4.mjs} +2 -2
- package/.output/server/_ssr/{StreamingChunkSequence-DTAiwlnI.mjs → StreamingChunkSequence-DnudbJ1O.mjs} +2 -2
- package/.output/server/_ssr/{index-D_EzfXaN.mjs → index-Cza8zDrW.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{json-viewer-CrIX0e0Q.mjs → json-viewer-C2lIVEX3.mjs} +2 -2
- package/.output/server/_ssr/{router-__o2wrfO.mjs → router-bF9uzd1k.mjs} +545 -22
- package/.output/server/{_tanstack-start-manifest_v-DbqyLpsI.mjs → _tanstack-start-manifest_v-ErvW-mtr.mjs} +1 -1
- package/.output/server/index.mjs +70 -70
- package/package.json +1 -1
- package/src/components/proxy-viewer/ThreadConnector.tsx +72 -88
- package/src/components/proxy-viewer/TurnGroup.tsx +1 -0
- package/src/mcp/server.ts +275 -0
- package/src/mcp/toolHandlers.ts +380 -3
- package/src/proxy/logSearch.ts +3 -0
- package/src/proxy/store.ts +40 -15
- package/src/routes/api/logs.ts +8 -2
- package/.output/public/assets/_sessionId-CTpCHdFh.js +0 -1
- package/.output/public/assets/index-Blqvndcn.js +0 -1
- package/.output/public/assets/index-Cs79WRQj.css +0 -1
package/.output/server/_ssr/{ProxyViewerContainer-DCZIJC2b.mjs → ProxyViewerContainer-CVqFZGff.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as reactExports, j as jsxRuntimeExports, a as React } from "../_libs/react.mjs";
|
|
2
|
-
import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, 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, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as GroupEvidenceExportResultSchema, o as DeleteInspectorGroupResponseSchema, y as createPendingProviderTestResults, z as ProviderTestResultsSchema, B as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, E as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, t as maskApiKey, u as PATH_V1_MESSAGES, v as PATH_V1_CHAT_COMPLETIONS, w as PATH_V1_RESPONSES, q as providerHasContextMetadata, r as findProviderModelMetadata, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, F as resolveProviderContextWindow, j as getSessionPath, x as previewUpstreamUrl, K as KnowledgeCandidateSchema, H as isPlainRecord, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-
|
|
2
|
+
import { I as InspectorGroupsListResponseSchema, C as CapturedLogSchema, 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, p as packageJson, P as ProviderConfigSchema, i as apiFormatForPath, n as GroupEvidenceExportResultSchema, o as DeleteInspectorGroupResponseSchema, y as createPendingProviderTestResults, z as ProviderTestResultsSchema, B as createFailedProviderTestResults, M as MAX_SLOW_RESPONSE_THRESHOLD_SECONDS, E as MAX_PROVIDER_TEST_TIMEOUT_SECONDS, T as TimeDisplayFormatSchema, l as AlertSummarySchema, m as AlertListResponseSchema, G as GroupEvidenceReadResponseSchema, t as maskApiKey, u as PATH_V1_MESSAGES, v as PATH_V1_CHAT_COMPLETIONS, w as PATH_V1_RESPONSES, q as providerHasContextMetadata, r as findProviderModelMetadata, f as parseOpenAIResponse, g as parseOpenAIResponsesResponse, O as OpenAIRequestSchema, h as OpenAIResponsesRequestSchema, A as AnthropicResponseSchema$1, e as AnthropicRequestSchema, s as safeGetOwnProperty, F as resolveProviderContextWindow, j as getSessionPath, x as previewUpstreamUrl, K as KnowledgeCandidateSchema, H as isPlainRecord, k as stripClaudeCodeBillingHeader, L as LogBodyChunkSchema } from "./router-bF9uzd1k.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";
|
|
@@ -1959,27 +1959,27 @@ function useCopyFeedback(text) {
|
|
|
1959
1959
|
return { copied, copy };
|
|
1960
1960
|
}
|
|
1961
1961
|
const LazyCompareDrawer = reactExports.lazy(
|
|
1962
|
-
() => import("./CompareDrawer-
|
|
1962
|
+
() => import("./CompareDrawer-Dal52IFo.mjs").then((m) => ({ default: m.CompareDrawer }))
|
|
1963
1963
|
);
|
|
1964
1964
|
const LazyReplayDialog = reactExports.lazy(
|
|
1965
|
-
() => import("./ReplayDialog-
|
|
1965
|
+
() => import("./ReplayDialog-BOEgdMes.mjs").then((m) => ({ default: m.ReplayDialog }))
|
|
1966
1966
|
);
|
|
1967
1967
|
const LazyRequestAnatomy = reactExports.lazy(
|
|
1968
|
-
() => import("./RequestAnatomy-
|
|
1968
|
+
() => import("./RequestAnatomy-gch7_vCV.mjs").then((m) => ({ default: m.RequestAnatomy }))
|
|
1969
1969
|
);
|
|
1970
1970
|
const LazyResponseView = reactExports.lazy(
|
|
1971
|
-
() => import("./ResponseView-
|
|
1971
|
+
() => import("./ResponseView-lEWPy-H4.mjs").then((m) => ({ default: m.ResponseView }))
|
|
1972
1972
|
);
|
|
1973
1973
|
const LazyStreamingChunkSequence = reactExports.lazy(
|
|
1974
|
-
() => import("./StreamingChunkSequence-
|
|
1974
|
+
() => import("./StreamingChunkSequence-DnudbJ1O.mjs").then((m) => ({
|
|
1975
1975
|
default: m.StreamingChunkSequence
|
|
1976
1976
|
}))
|
|
1977
1977
|
);
|
|
1978
1978
|
const LazyJsonViewer = reactExports.lazy(
|
|
1979
|
-
() => import("./json-viewer-
|
|
1979
|
+
() => import("./json-viewer-C2lIVEX3.mjs").then((m) => ({ default: m.JsonViewer }))
|
|
1980
1980
|
);
|
|
1981
1981
|
const LazyJsonViewerFromString = reactExports.lazy(
|
|
1982
|
-
() => import("./json-viewer-
|
|
1982
|
+
() => import("./json-viewer-C2lIVEX3.mjs").then((m) => ({ default: m.JsonViewerFromString }))
|
|
1983
1983
|
);
|
|
1984
1984
|
const HIGHLIGHT_DURATION_MS = 1200;
|
|
1985
1985
|
const MAX_HIGHLIGHT_ATTEMPTS = 12;
|
|
@@ -4134,2032 +4134,2037 @@ const LogEntry = reactExports.memo(function({
|
|
|
4134
4134
|
) })
|
|
4135
4135
|
] });
|
|
4136
4136
|
});
|
|
4137
|
-
function
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
case "tool_use":
|
|
4146
|
-
case null:
|
|
4147
|
-
return "End of Turn";
|
|
4148
|
-
}
|
|
4149
|
-
}
|
|
4150
|
-
function markerTone({
|
|
4151
|
-
isFusedBoundary,
|
|
4152
|
-
isBoundary,
|
|
4153
|
-
isTurnStart,
|
|
4154
|
-
isRunning
|
|
4155
|
-
}) {
|
|
4156
|
-
if (isFusedBoundary) return "fused";
|
|
4157
|
-
if (isBoundary) return "end";
|
|
4158
|
-
if (isTurnStart) return "start";
|
|
4159
|
-
if (isRunning) return "running";
|
|
4160
|
-
return "idle";
|
|
4161
|
-
}
|
|
4162
|
-
function markerClass(tone, interactive) {
|
|
4163
|
-
const base = "inline-flex size-3.5 items-center justify-center rounded-full border transition-colors";
|
|
4164
|
-
const cursor = interactive ? "cursor-pointer hover:border-cyan-200/70 hover:bg-cyan-300/20" : "";
|
|
4165
|
-
switch (tone) {
|
|
4166
|
-
case "start":
|
|
4167
|
-
return cn(base, cursor, "border-cyan-300/50 bg-cyan-300/12 text-cyan-200");
|
|
4168
|
-
case "end":
|
|
4169
|
-
return cn(base, cursor, "border-amber-300/55 bg-amber-300/12 text-amber-200");
|
|
4170
|
-
case "fused":
|
|
4171
|
-
return cn(
|
|
4172
|
-
base,
|
|
4173
|
-
cursor,
|
|
4174
|
-
"border-slate-200/50 bg-slate-200/10 text-slate-100 ring-2 ring-cyan-300/15"
|
|
4175
|
-
);
|
|
4176
|
-
case "running":
|
|
4177
|
-
return cn(
|
|
4178
|
-
base,
|
|
4179
|
-
cursor,
|
|
4180
|
-
"border-amber-300/45 bg-amber-300/10 text-amber-200 ring-2 ring-amber-300/10"
|
|
4181
|
-
);
|
|
4182
|
-
case "idle":
|
|
4183
|
-
return cn(base, cursor, "border-muted-foreground/25 bg-muted/30 text-muted-foreground/60");
|
|
4184
|
-
}
|
|
4185
|
-
}
|
|
4186
|
-
function markerInnerClass(tone) {
|
|
4187
|
-
switch (tone) {
|
|
4188
|
-
case "running":
|
|
4189
|
-
return "size-1.5 rounded-full bg-current animate-pulse";
|
|
4190
|
-
case "idle":
|
|
4191
|
-
return "size-1 rounded-full bg-current opacity-55";
|
|
4192
|
-
case "start":
|
|
4193
|
-
case "end":
|
|
4194
|
-
case "fused":
|
|
4195
|
-
return "size-1.5 rounded-full bg-current";
|
|
4196
|
-
}
|
|
4197
|
-
}
|
|
4198
|
-
function markerTitle(tone, stopReason) {
|
|
4199
|
-
switch (tone) {
|
|
4200
|
-
case "start":
|
|
4201
|
-
return "Start of turn";
|
|
4202
|
-
case "end":
|
|
4203
|
-
return boundaryTitle(stopReason);
|
|
4204
|
-
case "fused":
|
|
4205
|
-
return "Single-request turn";
|
|
4206
|
-
case "running":
|
|
4207
|
-
return "Processing";
|
|
4208
|
-
case "idle":
|
|
4209
|
-
return "Request in turn";
|
|
4210
|
-
}
|
|
4211
|
-
}
|
|
4212
|
-
function ThreadConnector({
|
|
4213
|
-
stopReason,
|
|
4214
|
-
isPending,
|
|
4215
|
-
isFirst,
|
|
4216
|
-
isTurnStart,
|
|
4217
|
-
isOnlyEntry = false,
|
|
4218
|
-
collapsible = false,
|
|
4219
|
-
onToggle
|
|
4137
|
+
function SvgShell({
|
|
4138
|
+
className,
|
|
4139
|
+
style,
|
|
4140
|
+
d,
|
|
4141
|
+
eyeStalks,
|
|
4142
|
+
eyes,
|
|
4143
|
+
legs,
|
|
4144
|
+
extras
|
|
4220
4145
|
}) {
|
|
4221
|
-
const isBoundary = isTurnBoundary(stopReason);
|
|
4222
|
-
const isFusedBoundary = isOnlyEntry && isTurnStart && isBoundary;
|
|
4223
|
-
const isRunning = isPending && !isBoundary;
|
|
4224
|
-
const tone = markerTone({ isFusedBoundary, isBoundary, isTurnStart, isRunning });
|
|
4225
|
-
const interactive = collapsible && onToggle !== void 0;
|
|
4226
|
-
const handleMarkerClick = (event) => {
|
|
4227
|
-
if (!interactive || onToggle === void 0) return;
|
|
4228
|
-
event.stopPropagation();
|
|
4229
|
-
onToggle();
|
|
4230
|
-
};
|
|
4231
|
-
const handleMarkerKeyDown = (event) => {
|
|
4232
|
-
if (!interactive || onToggle === void 0) return;
|
|
4233
|
-
if (event.key !== "Enter" && event.key !== " ") return;
|
|
4234
|
-
event.preventDefault();
|
|
4235
|
-
onToggle();
|
|
4236
|
-
};
|
|
4237
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center w-6 shrink-0 pt-0.5 pb-0.5", children: [
|
|
4238
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-center h-[calc(0.75rem-8px)]", children: !isFirst && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-0.5 bg-muted-foreground/30 h-full" }) }),
|
|
4239
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4240
|
-
"span",
|
|
4241
|
-
{
|
|
4242
|
-
role: interactive ? "button" : void 0,
|
|
4243
|
-
tabIndex: interactive ? 0 : void 0,
|
|
4244
|
-
title: markerTitle(tone, stopReason),
|
|
4245
|
-
className: markerClass(tone, interactive),
|
|
4246
|
-
onClick: handleMarkerClick,
|
|
4247
|
-
onKeyDown: handleMarkerKeyDown,
|
|
4248
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: markerInnerClass(tone) })
|
|
4249
|
-
}
|
|
4250
|
-
),
|
|
4251
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex justify-center min-h-0", children: !isBoundary && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4252
|
-
"div",
|
|
4253
|
-
{
|
|
4254
|
-
className: cn(
|
|
4255
|
-
"w-0.5 h-full",
|
|
4256
|
-
isPending ? "border-dashed bg-transparent border-l-2 border-muted-foreground/20" : "bg-muted-foreground/30"
|
|
4257
|
-
)
|
|
4258
|
-
}
|
|
4259
|
-
) })
|
|
4260
|
-
] });
|
|
4261
|
-
}
|
|
4262
|
-
function ToolTraceEventRow({ event }) {
|
|
4263
|
-
const argumentCopy = useCopyFeedback(event.argumentsText);
|
|
4264
|
-
const canCopyArguments = event.argumentsText !== null;
|
|
4265
4146
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4266
|
-
"
|
|
4147
|
+
"svg",
|
|
4267
4148
|
{
|
|
4268
|
-
|
|
4149
|
+
viewBox: "0 0 24 24",
|
|
4150
|
+
fill: "none",
|
|
4151
|
+
stroke: "currentColor",
|
|
4152
|
+
strokeWidth: "1.5",
|
|
4153
|
+
strokeLinecap: "round",
|
|
4154
|
+
strokeLinejoin: "round",
|
|
4155
|
+
"aria-hidden": "true",
|
|
4156
|
+
style,
|
|
4157
|
+
className: cn("inline-block size-5", className),
|
|
4269
4158
|
children: [
|
|
4270
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
] }),
|
|
4276
|
-
canCopyArguments && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4277
|
-
"button",
|
|
4278
|
-
{
|
|
4279
|
-
type: "button",
|
|
4280
|
-
className: "ml-auto inline-flex size-6 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-background/80 hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/tool-trace:opacity-100 group-focus-within/tool-trace:opacity-100",
|
|
4281
|
-
onClick: argumentCopy.copy,
|
|
4282
|
-
"aria-label": argumentCopy.copied ? "Copied tool arguments" : "Copy tool arguments",
|
|
4283
|
-
title: argumentCopy.copied ? "Copied tool arguments" : "Copy tool arguments",
|
|
4284
|
-
children: argumentCopy.copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" })
|
|
4285
|
-
}
|
|
4286
|
-
)
|
|
4159
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d }),
|
|
4160
|
+
eyeStalks,
|
|
4161
|
+
eyes,
|
|
4162
|
+
legs,
|
|
4163
|
+
extras
|
|
4287
4164
|
]
|
|
4288
|
-
}
|
|
4289
|
-
event.id
|
|
4165
|
+
}
|
|
4290
4166
|
);
|
|
4291
4167
|
}
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
}
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
}
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
groups.push({ entries, turnIndex });
|
|
4324
|
-
entries = [];
|
|
4325
|
-
turnIndex += 1;
|
|
4168
|
+
const StdLegs = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4169
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "6.5", y1: "16", x2: "4.5", y2: "19.5" }),
|
|
4170
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9", y1: "17.5", x2: "8", y2: "20.5" }),
|
|
4171
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "15", y1: "17.5", x2: "16", y2: "20.5" }),
|
|
4172
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17.5", y1: "16", x2: "19.5", y2: "19.5" })
|
|
4173
|
+
] });
|
|
4174
|
+
const ShortLegs = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4175
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "7", y1: "16", x2: "5.5", y2: "18.5" }),
|
|
4176
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "17", x2: "8.5", y2: "19.5" }),
|
|
4177
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "17", x2: "15.5", y2: "19.5" }),
|
|
4178
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17", y1: "16", x2: "18.5", y2: "18.5" })
|
|
4179
|
+
] });
|
|
4180
|
+
function Crab1({ className }) {
|
|
4181
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4182
|
+
SvgShell,
|
|
4183
|
+
{
|
|
4184
|
+
className,
|
|
4185
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
4186
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4187
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
4188
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
4189
|
+
] }),
|
|
4190
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4191
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
4192
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" })
|
|
4193
|
+
] }),
|
|
4194
|
+
legs: StdLegs,
|
|
4195
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4196
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
4197
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" })
|
|
4198
|
+
] })
|
|
4326
4199
|
}
|
|
4327
|
-
|
|
4328
|
-
if (entries.length > 0) groups.push({ entries, turnIndex });
|
|
4329
|
-
return groups;
|
|
4200
|
+
);
|
|
4330
4201
|
}
|
|
4331
|
-
function
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4202
|
+
function Crab2({ className }) {
|
|
4203
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4204
|
+
SvgShell,
|
|
4205
|
+
{
|
|
4206
|
+
className,
|
|
4207
|
+
d: "M4 13 C4 7 7.5 5.5 12 5.5 C16.5 5.5 20 7 20 13 C20 17.5 16.5 19 12 19 C7.5 19 4 17.5 4 13 Z",
|
|
4208
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4209
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "6.5", x2: "9.5", y2: "4.5" }),
|
|
4210
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "6.5", x2: "14.5", y2: "4.5" })
|
|
4211
|
+
] }),
|
|
4212
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4213
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4", r: "1.1", fill: "currentColor", stroke: "none" }),
|
|
4214
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4", r: "1.1", fill: "currentColor", stroke: "none" })
|
|
4215
|
+
] }),
|
|
4216
|
+
legs: ShortLegs,
|
|
4217
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4218
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C4 9.5 2.5 10 3 12 C3.5 13.5 4.5 13 5 12" }),
|
|
4219
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20 9.5 21.5 10 21 12 C20.5 13.5 19.5 13 19 12" })
|
|
4220
|
+
] })
|
|
4342
4221
|
}
|
|
4343
|
-
|
|
4344
|
-
return predecessors;
|
|
4222
|
+
);
|
|
4345
4223
|
}
|
|
4346
|
-
function
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4224
|
+
function Crab3({ className }) {
|
|
4225
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4226
|
+
SvgShell,
|
|
4227
|
+
{
|
|
4228
|
+
className,
|
|
4229
|
+
d: "M3 13.5 C3 8 7 6 12 6 C17 6 21 8 21 13.5 C21 17 17 19 12 19 C7 19 3 17 3 13.5 Z",
|
|
4230
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4231
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "7", y1: "7", x2: "6.5", y2: "4.5" }),
|
|
4232
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17", y1: "7", x2: "17.5", y2: "4.5" })
|
|
4233
|
+
] }),
|
|
4234
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4235
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "6.5", cy: "4", r: "0.8", fill: "currentColor", stroke: "none" }),
|
|
4236
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "17.5", cy: "4", r: "0.8", fill: "currentColor", stroke: "none" })
|
|
4237
|
+
] }),
|
|
4238
|
+
legs: StdLegs,
|
|
4239
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4240
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M4 12 C2.5 10.5 1 11 1.5 13 C2 14.5 3.5 14 4.5 13" }),
|
|
4241
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M20 12 C21.5 10.5 23 11 22.5 13 C22 14.5 20.5 14 19.5 13" })
|
|
4242
|
+
] })
|
|
4352
4243
|
}
|
|
4353
|
-
|
|
4354
|
-
} catch {
|
|
4355
|
-
return null;
|
|
4356
|
-
}
|
|
4244
|
+
);
|
|
4357
4245
|
}
|
|
4358
|
-
function
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
}
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4246
|
+
function Crab4({ className }) {
|
|
4247
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4248
|
+
SvgShell,
|
|
4249
|
+
{
|
|
4250
|
+
className,
|
|
4251
|
+
d: "M6 14 C6 8 9 5.5 12 5.5 C15 5.5 18 8 18 14 C18 18 15 20 12 20 C9 20 6 18 6 14 Z",
|
|
4252
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4253
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "6.5", x2: "10", y2: "3.5" }),
|
|
4254
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "6.5", x2: "14", y2: "3.5" })
|
|
4255
|
+
] }),
|
|
4256
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4257
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "10", cy: "3", r: "0.7", fill: "currentColor", stroke: "none" }),
|
|
4258
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14", cy: "3", r: "0.7", fill: "currentColor", stroke: "none" })
|
|
4259
|
+
] }),
|
|
4260
|
+
legs: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4261
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "7", y1: "17", x2: "5", y2: "20.5" }),
|
|
4262
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "18.5", x2: "8.5", y2: "21.5" }),
|
|
4263
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "18.5", x2: "15.5", y2: "21.5" }),
|
|
4264
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17", y1: "17", x2: "19", y2: "20.5" })
|
|
4265
|
+
] }),
|
|
4266
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4267
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6.5 11 C5 8.5 3 9 3.5 11.5 C4 13.5 5 13 6 12" }),
|
|
4268
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M17.5 11 C19 8.5 21 9 20.5 11.5 C20 13.5 19 13 18 12" })
|
|
4269
|
+
] })
|
|
4270
|
+
}
|
|
4271
|
+
);
|
|
4371
4272
|
}
|
|
4372
|
-
function
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
}
|
|
4392
|
-
|
|
4393
|
-
return events;
|
|
4273
|
+
function Crab5({ className }) {
|
|
4274
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4275
|
+
SvgShell,
|
|
4276
|
+
{
|
|
4277
|
+
className,
|
|
4278
|
+
d: "M5 13 C5 9 8 7 12 7 L13 4 L14 7 C16 7 19 9 19 13 C19 16 16 18 13 18 L12 21 L11 18 C8 18 5 16 5 13 Z",
|
|
4279
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4280
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
4281
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
4282
|
+
] }),
|
|
4283
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4284
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.8", fill: "currentColor", stroke: "none" }),
|
|
4285
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.8", fill: "currentColor", stroke: "none" })
|
|
4286
|
+
] }),
|
|
4287
|
+
legs: StdLegs,
|
|
4288
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4289
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
4290
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" })
|
|
4291
|
+
] })
|
|
4292
|
+
}
|
|
4293
|
+
);
|
|
4394
4294
|
}
|
|
4395
|
-
function
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
name,
|
|
4415
|
-
argumentsText: copyValue(args),
|
|
4416
|
-
argumentsPreview: previewValue(args)
|
|
4417
|
-
});
|
|
4295
|
+
function Crab6({ className }) {
|
|
4296
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4297
|
+
SvgShell,
|
|
4298
|
+
{
|
|
4299
|
+
className,
|
|
4300
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
4301
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4302
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
4303
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
4304
|
+
] }),
|
|
4305
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4306
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
4307
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "13.5", y1: "4", x2: "15.5", y2: "5" })
|
|
4308
|
+
] }),
|
|
4309
|
+
legs: StdLegs,
|
|
4310
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4311
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
4312
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" })
|
|
4313
|
+
] })
|
|
4418
4314
|
}
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4315
|
+
);
|
|
4316
|
+
}
|
|
4317
|
+
function Crab7({ className }) {
|
|
4318
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4319
|
+
SvgShell,
|
|
4320
|
+
{
|
|
4321
|
+
className,
|
|
4322
|
+
d: "M5.5 13.5 C5.5 10 8.5 8 12 8 C15.5 8 18.5 10 18.5 13.5 C18.5 16 15.5 17.5 12 17.5 C8.5 17.5 5.5 16 5.5 13.5 Z",
|
|
4323
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4324
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "8", x2: "10", y2: "6" }),
|
|
4325
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "8", x2: "14", y2: "6" })
|
|
4326
|
+
] }),
|
|
4327
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4328
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9", y1: "6", x2: "11", y2: "6.5" }),
|
|
4329
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "13", y1: "6", x2: "15", y2: "6.5" })
|
|
4330
|
+
] }),
|
|
4331
|
+
legs: ShortLegs,
|
|
4332
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4333
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6 11.5 C4.5 10.5 3 11 3.5 12.5 C4 13.5 5 13 5.5 12.5" }),
|
|
4334
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M18 11.5 C19.5 10.5 21 11 20.5 12.5 C20 13.5 19 13 18.5 12.5" })
|
|
4335
|
+
] })
|
|
4436
4336
|
}
|
|
4437
|
-
|
|
4438
|
-
return events;
|
|
4337
|
+
);
|
|
4439
4338
|
}
|
|
4440
|
-
function
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
events = [];
|
|
4465
|
-
break;
|
|
4466
|
-
}
|
|
4467
|
-
toolTraceCache.set(log, {
|
|
4468
|
-
apiFormat: log.apiFormat,
|
|
4469
|
-
responseText: log.responseText,
|
|
4470
|
-
events
|
|
4471
|
-
});
|
|
4472
|
-
return events;
|
|
4339
|
+
function Crab8({ className }) {
|
|
4340
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4341
|
+
SvgShell,
|
|
4342
|
+
{
|
|
4343
|
+
className,
|
|
4344
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
4345
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4346
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
4347
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
4348
|
+
] }),
|
|
4349
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4350
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.7", fill: "currentColor", stroke: "none" }),
|
|
4351
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.7", fill: "currentColor", stroke: "none" })
|
|
4352
|
+
] }),
|
|
4353
|
+
legs: StdLegs,
|
|
4354
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4355
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
4356
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
4357
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "8.5", y1: "4", x2: "10.5", y2: "4.5" }),
|
|
4358
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "15.5", y1: "4", x2: "13.5", y2: "4.5" }),
|
|
4359
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 15.5 C10 14.5 14 14.5 15 15.5" })
|
|
4360
|
+
] })
|
|
4361
|
+
}
|
|
4362
|
+
);
|
|
4473
4363
|
}
|
|
4474
|
-
function
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4364
|
+
function Crab9({ className }) {
|
|
4365
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4366
|
+
SvgShell,
|
|
4367
|
+
{
|
|
4368
|
+
className,
|
|
4369
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
4370
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4371
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
4372
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
4373
|
+
] }),
|
|
4374
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4375
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "1.2", fill: "none", stroke: "currentColor" }),
|
|
4376
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "1.2", fill: "none", stroke: "currentColor" })
|
|
4377
|
+
] }),
|
|
4378
|
+
legs: StdLegs,
|
|
4379
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4380
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
4381
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
4382
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("ellipse", { cx: "12", cy: "15", rx: "2", ry: "1.5", fill: "currentColor", stroke: "none" })
|
|
4383
|
+
] })
|
|
4490
4384
|
}
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4385
|
+
);
|
|
4386
|
+
}
|
|
4387
|
+
function Crab10({ className }) {
|
|
4388
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4389
|
+
SvgShell,
|
|
4390
|
+
{
|
|
4391
|
+
className,
|
|
4392
|
+
d: "M4.5 13 C4.5 8 7.5 6 12 6 C16.5 6 19.5 8 19.5 13 C19.5 17 16.5 18.5 12 18.5 C7.5 18.5 4.5 17 4.5 13 Z",
|
|
4393
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4394
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "7", x2: "9", y2: "5" }),
|
|
4395
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "7", x2: "15", y2: "5" })
|
|
4396
|
+
] }),
|
|
4397
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4398
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9", cy: "4.5", r: "1", fill: "currentColor", stroke: "none" }),
|
|
4399
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "15", cy: "4.5", r: "1", fill: "currentColor", stroke: "none" })
|
|
4400
|
+
] }),
|
|
4401
|
+
legs: StdLegs,
|
|
4402
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4403
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9 2 9.5 2.5 12 C3 14 4 13 5 12" }),
|
|
4404
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9 22 9.5 21.5 12 C21 14 20 13 19 12" }),
|
|
4405
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 14.5 C10 16 14 16 15 14.5" }),
|
|
4406
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "7", cy: "13", r: "1", fill: "currentColor", stroke: "none", opacity: "0.3" }),
|
|
4407
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "17", cy: "13", r: "1", fill: "currentColor", stroke: "none", opacity: "0.3" })
|
|
4408
|
+
] })
|
|
4498
4409
|
}
|
|
4499
|
-
|
|
4500
|
-
|
|
4410
|
+
);
|
|
4411
|
+
}
|
|
4412
|
+
function Crab11({ className }) {
|
|
4413
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4414
|
+
SvgShell,
|
|
4415
|
+
{
|
|
4416
|
+
className,
|
|
4417
|
+
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
4418
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4419
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5.5" }),
|
|
4420
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5.5" })
|
|
4421
|
+
] }),
|
|
4422
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4423
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "7.5", y1: "5.5", x2: "16.5", y2: "5.5" }),
|
|
4424
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x: "7", y: "5", width: "4", height: "2", rx: "0.5", fill: "currentColor", stroke: "none" }),
|
|
4425
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("rect", { x: "13", y: "5", width: "4", height: "2", rx: "0.5", fill: "currentColor", stroke: "none" })
|
|
4426
|
+
] }),
|
|
4427
|
+
legs: StdLegs,
|
|
4428
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4429
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
4430
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
4431
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9.5 15 C10.5 16 13.5 16 14.5 15" })
|
|
4432
|
+
] })
|
|
4501
4433
|
}
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4434
|
+
);
|
|
4435
|
+
}
|
|
4436
|
+
function Crab12({ className }) {
|
|
4437
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4438
|
+
SvgShell,
|
|
4439
|
+
{
|
|
4440
|
+
className,
|
|
4441
|
+
d: "M7 13.5 C7 10.5 9.5 9 12 9 C14.5 9 17 10.5 17 13.5 C17 16 14.5 17.5 12 17.5 C9.5 17.5 7 16 7 13.5 Z",
|
|
4442
|
+
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4443
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10.5", y1: "9.5", x2: "10.5", y2: "8" }),
|
|
4444
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "13.5", y1: "9.5", x2: "13.5", y2: "8" })
|
|
4445
|
+
] }),
|
|
4446
|
+
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4447
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "10.5", cy: "7.5", r: "0.8", fill: "currentColor", stroke: "none" }),
|
|
4448
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "13.5", cy: "7.5", r: "0.8", fill: "currentColor", stroke: "none" })
|
|
4449
|
+
] }),
|
|
4450
|
+
legs: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4451
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "8", y1: "16", x2: "6.5", y2: "18" }),
|
|
4452
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "17", x2: "9.5", y2: "19" }),
|
|
4453
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "17", x2: "14.5", y2: "19" }),
|
|
4454
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "16", y1: "16", x2: "17.5", y2: "18" })
|
|
4455
|
+
] }),
|
|
4456
|
+
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4457
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M7.5 12 C6.5 11 5.5 11.5 6 13 C6.5 14 7 13.5 7.5 13" }),
|
|
4458
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M16.5 12 C17.5 11 18.5 11.5 18 13 C17.5 14 17 13.5 16.5 13" })
|
|
4459
|
+
] })
|
|
4505
4460
|
}
|
|
4506
|
-
|
|
4461
|
+
);
|
|
4462
|
+
}
|
|
4463
|
+
const crabVariants = [
|
|
4464
|
+
Crab1,
|
|
4465
|
+
Crab2,
|
|
4466
|
+
Crab3,
|
|
4467
|
+
Crab4,
|
|
4468
|
+
Crab5,
|
|
4469
|
+
Crab6,
|
|
4470
|
+
Crab7,
|
|
4471
|
+
Crab8,
|
|
4472
|
+
Crab9,
|
|
4473
|
+
Crab10,
|
|
4474
|
+
Crab11,
|
|
4475
|
+
Crab12
|
|
4476
|
+
];
|
|
4477
|
+
function getCrabVariant(index) {
|
|
4478
|
+
return crabVariants[Math.abs(index) % crabVariants.length] ?? Crab1;
|
|
4479
|
+
}
|
|
4480
|
+
function getInteriorCrabVariantIndex(seed) {
|
|
4481
|
+
const interiorCount = crabVariants.length - 2;
|
|
4482
|
+
if (interiorCount <= 0) return 0;
|
|
4483
|
+
const normalizedSeed = Number.isFinite(seed) ? Math.trunc(seed) : 0;
|
|
4484
|
+
return 1 + (normalizedSeed % interiorCount + interiorCount) % interiorCount;
|
|
4485
|
+
}
|
|
4486
|
+
function getInteriorCrabVariant(seed) {
|
|
4487
|
+
return getCrabVariant(getInteriorCrabVariantIndex(seed));
|
|
4488
|
+
}
|
|
4489
|
+
function boundaryTitle(stopReason) {
|
|
4490
|
+
switch (stopReason) {
|
|
4491
|
+
case "end_turn":
|
|
4492
|
+
return "End of Turn (Anthropic)";
|
|
4493
|
+
case "stop":
|
|
4494
|
+
return "End of Turn (OpenAI)";
|
|
4495
|
+
case "length":
|
|
4496
|
+
return "End of Turn (length limit)";
|
|
4497
|
+
case "tool_use":
|
|
4498
|
+
case null:
|
|
4499
|
+
return "End of Turn";
|
|
4507
4500
|
}
|
|
4508
|
-
return {
|
|
4509
|
-
llmCallCount: logs.length,
|
|
4510
|
-
toolCallCount,
|
|
4511
|
-
failedCallCount,
|
|
4512
|
-
pendingCallCount,
|
|
4513
|
-
slowCallCount,
|
|
4514
|
-
totalInputTokens,
|
|
4515
|
-
totalOutputTokens,
|
|
4516
|
-
totalCacheCreationInputTokens,
|
|
4517
|
-
totalCacheReadInputTokens,
|
|
4518
|
-
totalElapsedMs,
|
|
4519
|
-
maxElapsedMs,
|
|
4520
|
-
startedAt: logs[0]?.timestamp ?? null,
|
|
4521
|
-
endedAt: logs[logs.length - 1]?.timestamp ?? null,
|
|
4522
|
-
knowledgeCandidateCount
|
|
4523
|
-
};
|
|
4524
4501
|
}
|
|
4525
|
-
function
|
|
4526
|
-
|
|
4527
|
-
return `${(ms / 1e3).toFixed(1)}s`;
|
|
4502
|
+
function crabShellClass(interactive) {
|
|
4503
|
+
return interactive ? "cursor-pointer transition-transform hover:scale-110" : "";
|
|
4528
4504
|
}
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
timeDisplayFormat,
|
|
4539
|
-
pendingFocusRequest,
|
|
4540
|
-
showLogClientMetadata = true
|
|
4505
|
+
function ThreadConnector({
|
|
4506
|
+
stopReason,
|
|
4507
|
+
isPending,
|
|
4508
|
+
isFirst,
|
|
4509
|
+
isTurnStart,
|
|
4510
|
+
isOnlyEntry = false,
|
|
4511
|
+
crabIndex = 0,
|
|
4512
|
+
collapsible = false,
|
|
4513
|
+
onToggle
|
|
4541
4514
|
}) {
|
|
4542
|
-
const
|
|
4543
|
-
const
|
|
4544
|
-
const
|
|
4545
|
-
const
|
|
4546
|
-
const
|
|
4547
|
-
const
|
|
4548
|
-
const
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
}, 0);
|
|
4581
|
-
return () => window.clearTimeout(timer);
|
|
4582
|
-
}, [collapsible, entries, pendingFocusRequest]);
|
|
4583
|
-
const toggleCollapse = reactExports.useCallback(() => {
|
|
4584
|
-
if (collapsible) setCollapsed((prev) => !prev);
|
|
4585
|
-
}, [collapsible]);
|
|
4586
|
-
const aggregate = reactExports.useMemo(() => {
|
|
4587
|
-
let totalInput = 0;
|
|
4588
|
-
let totalOutput = 0;
|
|
4589
|
-
let maxElapsed = null;
|
|
4590
|
-
let hasTokens = false;
|
|
4591
|
-
for (const e of entries) {
|
|
4592
|
-
if (e.log.inputTokens !== null) {
|
|
4593
|
-
totalInput += e.log.inputTokens;
|
|
4594
|
-
hasTokens = true;
|
|
4515
|
+
const isBoundary = isTurnBoundary(stopReason);
|
|
4516
|
+
const isFusedBoundary = isOnlyEntry && isTurnStart && isBoundary;
|
|
4517
|
+
const isRunning = isPending && !isBoundary;
|
|
4518
|
+
const interactive = collapsible && onToggle !== void 0;
|
|
4519
|
+
const Crab = reactExports.useMemo(() => getCrabVariant(crabIndex), [crabIndex]);
|
|
4520
|
+
const FusedCrab = reactExports.useMemo(() => getInteriorCrabVariant(crabIndex), [crabIndex]);
|
|
4521
|
+
const handleCrabClick = (event) => {
|
|
4522
|
+
if (!interactive || onToggle === void 0) return;
|
|
4523
|
+
event.stopPropagation();
|
|
4524
|
+
onToggle();
|
|
4525
|
+
};
|
|
4526
|
+
const handleCrabKeyDown = (event) => {
|
|
4527
|
+
if (!interactive || onToggle === void 0) return;
|
|
4528
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
4529
|
+
event.preventDefault();
|
|
4530
|
+
onToggle();
|
|
4531
|
+
};
|
|
4532
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center w-6 shrink-0 pt-0.5 pb-0.5", children: [
|
|
4533
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-center h-[calc(0.75rem-8px)]", children: !isFirst && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-0.5 bg-muted-foreground/30 h-full" }) }),
|
|
4534
|
+
isFusedBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4535
|
+
"span",
|
|
4536
|
+
{
|
|
4537
|
+
role: interactive ? "button" : void 0,
|
|
4538
|
+
tabIndex: interactive ? 0 : void 0,
|
|
4539
|
+
title: "Single-request turn",
|
|
4540
|
+
className: crabShellClass(interactive),
|
|
4541
|
+
onClick: handleCrabClick,
|
|
4542
|
+
onKeyDown: handleCrabKeyDown,
|
|
4543
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4544
|
+
FusedCrab,
|
|
4545
|
+
{
|
|
4546
|
+
className: cn(
|
|
4547
|
+
"size-3.5 text-[#80FF00]",
|
|
4548
|
+
"animate-crab-settle",
|
|
4549
|
+
"drop-shadow-[0_0_4px_rgba(128,255,0,0.5)]"
|
|
4550
|
+
)
|
|
4551
|
+
}
|
|
4552
|
+
)
|
|
4595
4553
|
}
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4554
|
+
) : isBoundary ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4555
|
+
"span",
|
|
4556
|
+
{
|
|
4557
|
+
role: interactive ? "button" : void 0,
|
|
4558
|
+
tabIndex: interactive ? 0 : void 0,
|
|
4559
|
+
title: boundaryTitle(stopReason),
|
|
4560
|
+
className: crabShellClass(interactive),
|
|
4561
|
+
onClick: handleCrabClick,
|
|
4562
|
+
onKeyDown: handleCrabKeyDown,
|
|
4563
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4564
|
+
Crab,
|
|
4565
|
+
{
|
|
4566
|
+
className: cn(
|
|
4567
|
+
"size-3.5 text-amber-400",
|
|
4568
|
+
"animate-crab-settle",
|
|
4569
|
+
"drop-shadow-[0_0_4px_rgba(251,191,36,0.5)]"
|
|
4570
|
+
)
|
|
4571
|
+
}
|
|
4572
|
+
)
|
|
4599
4573
|
}
|
|
4600
|
-
|
|
4601
|
-
|
|
4574
|
+
) : isTurnStart ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4575
|
+
"span",
|
|
4576
|
+
{
|
|
4577
|
+
role: interactive ? "button" : void 0,
|
|
4578
|
+
tabIndex: interactive ? 0 : void 0,
|
|
4579
|
+
title: "Start of turn",
|
|
4580
|
+
className: crabShellClass(interactive),
|
|
4581
|
+
onClick: handleCrabClick,
|
|
4582
|
+
onKeyDown: handleCrabKeyDown,
|
|
4583
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4584
|
+
Crab,
|
|
4585
|
+
{
|
|
4586
|
+
className: cn(
|
|
4587
|
+
"size-3.5 text-emerald-400",
|
|
4588
|
+
"animate-crab-appear",
|
|
4589
|
+
"drop-shadow-[0_0_4px_rgba(52,211,153,0.5)]"
|
|
4590
|
+
)
|
|
4591
|
+
}
|
|
4592
|
+
)
|
|
4602
4593
|
}
|
|
4603
|
-
}
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
return events;
|
|
4620
|
-
}, [entries]);
|
|
4621
|
-
const [layoutVersion, setLayoutVersion] = reactExports.useState(0);
|
|
4622
|
-
const containerRef = reactExports.useRef(null);
|
|
4623
|
-
reactExports.useEffect(() => {
|
|
4624
|
-
const el = containerRef.current;
|
|
4625
|
-
if (!el) return;
|
|
4626
|
-
let raf = 0;
|
|
4627
|
-
const ro = new ResizeObserver(() => {
|
|
4628
|
-
window.cancelAnimationFrame(raf);
|
|
4629
|
-
raf = window.requestAnimationFrame(() => setLayoutVersion((v) => v + 1));
|
|
4630
|
-
});
|
|
4631
|
-
ro.observe(el);
|
|
4632
|
-
return () => {
|
|
4633
|
-
ro.disconnect();
|
|
4634
|
-
window.cancelAnimationFrame(raf);
|
|
4635
|
-
};
|
|
4636
|
-
}, []);
|
|
4637
|
-
const firstLogId = entries[0]?.log.id ?? turnIndex;
|
|
4638
|
-
const turnLabel = `Turn ${String(turnIndex + 1)}`;
|
|
4639
|
-
const containmentStyle = reactExports.useMemo(
|
|
4640
|
-
() => ({
|
|
4641
|
-
contentVisibility: "auto",
|
|
4642
|
-
containIntrinsicSize: collapsed ? "48px" : "160px"
|
|
4643
|
-
}),
|
|
4644
|
-
[collapsed]
|
|
4645
|
-
);
|
|
4646
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4594
|
+
) : isRunning ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Processing", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Crab, { className: cn("size-3.5 text-amber-300/80", "animate-crab-crawl") }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { title: "Request in turn", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Crab, { className: "size-3.5 text-muted-foreground/40" }) }),
|
|
4595
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex justify-center min-h-0", children: !isBoundary && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4596
|
+
"div",
|
|
4597
|
+
{
|
|
4598
|
+
className: cn(
|
|
4599
|
+
"w-0.5 h-full",
|
|
4600
|
+
isPending ? "border-dashed bg-transparent border-l-2 border-muted-foreground/20" : "bg-muted-foreground/30"
|
|
4601
|
+
)
|
|
4602
|
+
}
|
|
4603
|
+
) })
|
|
4604
|
+
] });
|
|
4605
|
+
}
|
|
4606
|
+
function ToolTraceEventRow({ event }) {
|
|
4607
|
+
const argumentCopy = useCopyFeedback(event.argumentsText);
|
|
4608
|
+
const canCopyArguments = event.argumentsText !== null;
|
|
4609
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4647
4610
|
"div",
|
|
4648
4611
|
{
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
e.preventDefault();
|
|
4672
|
-
toggleCollapse();
|
|
4673
|
-
}
|
|
4674
|
-
},
|
|
4675
|
-
children: [
|
|
4676
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-5 shrink-0 flex items-start pt-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/50 font-mono tabular-nums leading-none select-none", children: turnIndex + 1 }) }),
|
|
4677
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-6 shrink-0 flex flex-col items-center pt-1.5 pb-1.5", children: [
|
|
4678
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-center h-[calc(0.75rem-8px)]" }),
|
|
4679
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-2 rounded-full border border-cyan-300/45 bg-cyan-300/20" }),
|
|
4680
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex justify-center min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-px bg-muted-foreground/25 h-full" }) }),
|
|
4681
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4682
|
-
"span",
|
|
4683
|
-
{
|
|
4684
|
-
className: cn(
|
|
4685
|
-
"size-2 rounded-full border",
|
|
4686
|
-
isComplete ? "border-amber-300/45 bg-amber-300/20" : "border-muted-foreground/30 bg-muted/30"
|
|
4687
|
-
)
|
|
4688
|
-
}
|
|
4689
|
-
)
|
|
4690
|
-
] }),
|
|
4691
|
-
entries.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4692
|
-
"div",
|
|
4693
|
-
{
|
|
4694
|
-
className: cn(
|
|
4695
|
-
"flex-1 min-w-0 mb-0.5 rounded-[8px] py-1.5 px-3 flex items-center gap-3 text-xs shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]",
|
|
4696
|
-
"border border-border bg-card shadow-sm transition-colors hover:border-cyan-200/20",
|
|
4697
|
-
bgClass
|
|
4698
|
-
),
|
|
4699
|
-
children: [
|
|
4700
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground/70", children: turnLabel }),
|
|
4701
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4702
|
-
"span",
|
|
4703
|
-
{
|
|
4704
|
-
className: "text-blue-300/85 font-mono font-semibold tabular-nums shrink-0",
|
|
4705
|
-
title: `Log IDs ${String(entries[0]?.log.id ?? "?")} ~ ${String(
|
|
4706
|
-
entries[lastIdx]?.log.id ?? "?"
|
|
4707
|
-
)}`,
|
|
4708
|
-
children: [
|
|
4709
|
-
"#",
|
|
4710
|
-
entries[0]?.sessionLogNumber ?? "?",
|
|
4711
|
-
" ~ #",
|
|
4712
|
-
entries[lastIdx]?.sessionLogNumber ?? "?"
|
|
4713
|
-
]
|
|
4714
|
-
}
|
|
4715
|
-
),
|
|
4716
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground shrink-0", children: [
|
|
4717
|
-
entries.length,
|
|
4718
|
-
" request",
|
|
4719
|
-
entries.length > 1 ? "s" : ""
|
|
4720
|
-
] }),
|
|
4721
|
-
aggregate.maxElapsed !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
4722
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4723
|
-
"span",
|
|
4724
|
-
{
|
|
4725
|
-
className: cn(
|
|
4726
|
-
"flex items-center gap-1 shrink-0",
|
|
4727
|
-
aggregateIsSlow ? "text-amber-400" : "text-muted-foreground"
|
|
4728
|
-
),
|
|
4729
|
-
children: [
|
|
4730
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
4731
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatElapsed$2(aggregate.maxElapsed) }),
|
|
4732
|
-
aggregateIsSlow && /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3", "aria-label": "Slow response" })
|
|
4733
|
-
]
|
|
4734
|
-
}
|
|
4735
|
-
) }),
|
|
4736
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: aggregateIsSlow ? `Slow response: ${formatElapsed$2(
|
|
4737
|
-
aggregate.maxElapsed
|
|
4738
|
-
)} exceeds ${formatElapsed$2(slowResponseThresholdSeconds * 1e3)}` : "Slowest request in this turn" })
|
|
4739
|
-
] }) }),
|
|
4740
|
-
aggregate.hasTokens && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 shrink-0", children: [
|
|
4741
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3 text-muted-foreground" }),
|
|
4742
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
|
|
4743
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-blue-400", children: [
|
|
4744
|
-
"IN ",
|
|
4745
|
-
formatTokens(aggregate.totalInput)
|
|
4746
|
-
] }),
|
|
4747
|
-
" / ",
|
|
4748
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-amber-400", children: [
|
|
4749
|
-
"OUT ",
|
|
4750
|
-
formatTokens(aggregate.totalOutput)
|
|
4751
|
-
] })
|
|
4752
|
-
] })
|
|
4753
|
-
] }),
|
|
4754
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0" }),
|
|
4755
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4756
|
-
"span",
|
|
4757
|
-
{
|
|
4758
|
-
className: "border border-input bg-background inline-flex size-7 shrink-0 items-center justify-center rounded-md text-slate-200",
|
|
4759
|
-
"aria-hidden": "true",
|
|
4760
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" })
|
|
4761
|
-
}
|
|
4762
|
-
)
|
|
4763
|
-
]
|
|
4764
|
-
}
|
|
4765
|
-
)
|
|
4766
|
-
]
|
|
4767
|
-
}
|
|
4768
|
-
) : (
|
|
4769
|
-
/* ---- Expanded: full entries ---- */
|
|
4770
|
-
entries.map((entry, visibleIdx) => {
|
|
4771
|
-
const { log, stopReason: reason } = entry;
|
|
4772
|
-
const isTurnStart = visibleIdx === 0;
|
|
4773
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-stretch", children: [
|
|
4774
|
-
isTurnStart ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-5 shrink-0 flex items-start pt-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/50 font-mono tabular-nums leading-none select-none", children: turnIndex + 1 }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-5 shrink-0" }),
|
|
4775
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4776
|
-
ThreadConnector,
|
|
4777
|
-
{
|
|
4778
|
-
stopReason: reason,
|
|
4779
|
-
isPending: log.responseStatus === null,
|
|
4780
|
-
isFirst: visibleIdx === 0,
|
|
4781
|
-
isTurnStart,
|
|
4782
|
-
isOnlyEntry: isSingleLog,
|
|
4783
|
-
collapsible: collapsible && isTurnStart,
|
|
4784
|
-
onToggle: toggleCollapse
|
|
4785
|
-
}
|
|
4786
|
-
),
|
|
4787
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("flex-1 min-w-0 mb-0.5 rounded-[8px]", bgClass), children: [
|
|
4788
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4789
|
-
LogEntry,
|
|
4790
|
-
{
|
|
4791
|
-
log,
|
|
4792
|
-
displayNumber: entry.sessionLogNumber,
|
|
4793
|
-
viewMode,
|
|
4794
|
-
strip,
|
|
4795
|
-
slowResponseThresholdSeconds,
|
|
4796
|
-
timeDisplayFormat,
|
|
4797
|
-
cacheTrend: cacheTrends?.get(log.id) ?? null,
|
|
4798
|
-
showClientMetadata: showLogClientMetadata,
|
|
4799
|
-
onCompareWithPrevious: comparisonPredecessors.has(log.id) ? onCompareWithPrevious : void 0
|
|
4800
|
-
}
|
|
4801
|
-
),
|
|
4802
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ToolTraceEvents, { events: toolEventsByLogId.get(log.id) ?? [] })
|
|
4803
|
-
] })
|
|
4804
|
-
] }, log.id);
|
|
4805
|
-
})
|
|
4806
|
-
)
|
|
4807
|
-
}
|
|
4612
|
+
className: "group/tool-trace flex min-w-0 items-center gap-2 rounded-md border border-border/70 bg-muted/20 px-2.5 py-1.5 text-xs",
|
|
4613
|
+
children: [
|
|
4614
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3.5 shrink-0 text-sky-400/70" }),
|
|
4615
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono font-semibold text-foreground/80", children: event.name }),
|
|
4616
|
+
event.argumentsPreview !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4617
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 shrink-0 text-muted-foreground/60" }),
|
|
4618
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 truncate font-mono text-muted-foreground", children: event.argumentsPreview })
|
|
4619
|
+
] }),
|
|
4620
|
+
canCopyArguments && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4621
|
+
"button",
|
|
4622
|
+
{
|
|
4623
|
+
type: "button",
|
|
4624
|
+
className: "ml-auto inline-flex size-6 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-background/80 hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/tool-trace:opacity-100 group-focus-within/tool-trace:opacity-100",
|
|
4625
|
+
onClick: argumentCopy.copy,
|
|
4626
|
+
"aria-label": argumentCopy.copied ? "Copied tool arguments" : "Copy tool arguments",
|
|
4627
|
+
title: argumentCopy.copied ? "Copied tool arguments" : "Copy tool arguments",
|
|
4628
|
+
children: argumentCopy.copied ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "size-3.5" })
|
|
4629
|
+
}
|
|
4630
|
+
)
|
|
4631
|
+
]
|
|
4632
|
+
},
|
|
4633
|
+
event.id
|
|
4808
4634
|
);
|
|
4809
|
-
});
|
|
4810
|
-
const VIRTUALIZE_TURN_THRESHOLD = 24;
|
|
4811
|
-
const ESTIMATED_TURN_HEIGHT = 132;
|
|
4812
|
-
const VIRTUAL_OVERSCAN = 8;
|
|
4813
|
-
function shouldVirtualizeTurnGroups(turnCount) {
|
|
4814
|
-
return turnCount > VIRTUALIZE_TURN_THRESHOLD;
|
|
4815
|
-
}
|
|
4816
|
-
function buildLogTurnIndex(turnGroups) {
|
|
4817
|
-
const result = /* @__PURE__ */ new Map();
|
|
4818
|
-
for (let index = 0; index < turnGroups.length; index++) {
|
|
4819
|
-
const group = turnGroups[index];
|
|
4820
|
-
if (group === void 0) continue;
|
|
4821
|
-
for (const entry of group.entries) {
|
|
4822
|
-
result.set(entry.log.id, index);
|
|
4823
|
-
}
|
|
4824
|
-
}
|
|
4825
|
-
return result;
|
|
4826
4635
|
}
|
|
4827
|
-
function
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
{
|
|
4831
|
-
entries: turnGroup.entries,
|
|
4832
|
-
viewMode: props.viewMode,
|
|
4833
|
-
strip: props.strip,
|
|
4834
|
-
slowResponseThresholdSeconds: props.slowResponseThresholdSeconds,
|
|
4835
|
-
timeDisplayFormat: props.timeDisplayFormat,
|
|
4836
|
-
cacheTrends: props.cacheTrends,
|
|
4837
|
-
onCompareWithPrevious: props.onCompareWithPrevious,
|
|
4838
|
-
comparisonPredecessors: props.comparisonPredecessors,
|
|
4839
|
-
turnIndex: turnGroup.turnIndex,
|
|
4840
|
-
pendingFocusRequest,
|
|
4841
|
-
showLogClientMetadata: props.showLogClientMetadata
|
|
4842
|
-
},
|
|
4843
|
-
turnGroup.turnIndex
|
|
4844
|
-
);
|
|
4636
|
+
function ToolTraceEvents({ events }) {
|
|
4637
|
+
if (events.length === 0) return null;
|
|
4638
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mx-3 mb-2 grid gap-1.5", children: events.map((event) => /* @__PURE__ */ jsxRuntimeExports.jsx(ToolTraceEventRow, { event }, event.id)) });
|
|
4845
4639
|
}
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4640
|
+
const PREVIEW_LIMIT = 180;
|
|
4641
|
+
const toolTraceCache = /* @__PURE__ */ new WeakMap();
|
|
4642
|
+
function responseMayContainToolTrace(log, format) {
|
|
4643
|
+
const responseText = log.responseText;
|
|
4644
|
+
if (responseText === null) return false;
|
|
4645
|
+
switch (format) {
|
|
4646
|
+
case "anthropic":
|
|
4647
|
+
return responseText.includes("tool_use");
|
|
4648
|
+
case "openai":
|
|
4649
|
+
return responseText.includes("tool_calls") || responseText.includes("function_call");
|
|
4650
|
+
case "unknown":
|
|
4651
|
+
return false;
|
|
4849
4652
|
}
|
|
4850
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(VirtualizedTurnGroupList, { ...props });
|
|
4851
|
-
}
|
|
4852
|
-
function VirtualizedTurnGroupList(props) {
|
|
4853
|
-
const { turnGroups } = props;
|
|
4854
|
-
const [pendingFocusRequest, setPendingFocusRequest] = reactExports.useState(
|
|
4855
|
-
null
|
|
4856
|
-
);
|
|
4857
|
-
const virtualizer = useWindowVirtualizer({
|
|
4858
|
-
count: turnGroups.length,
|
|
4859
|
-
estimateSize: () => ESTIMATED_TURN_HEIGHT,
|
|
4860
|
-
overscan: VIRTUAL_OVERSCAN,
|
|
4861
|
-
getItemKey: (index) => turnGroups[index]?.turnIndex ?? index
|
|
4862
|
-
});
|
|
4863
|
-
const turnIndexByLogId = reactExports.useMemo(() => buildLogTurnIndex(turnGroups), [turnGroups]);
|
|
4864
|
-
reactExports.useEffect(() => {
|
|
4865
|
-
const handleLogFocusRequest = (event) => {
|
|
4866
|
-
const request = readLogFocusRequest(event);
|
|
4867
|
-
if (request === null) return;
|
|
4868
|
-
if (request.source === "virtualizer") return;
|
|
4869
|
-
const turnIndex = turnIndexByLogId.get(request.logId);
|
|
4870
|
-
if (turnIndex === void 0) return;
|
|
4871
|
-
virtualizer.scrollToIndex(turnIndex, { align: "center" });
|
|
4872
|
-
setPendingFocusRequest((previous) => ({
|
|
4873
|
-
...request,
|
|
4874
|
-
turnIndex,
|
|
4875
|
-
nonce: previous === null ? 1 : previous.nonce + 1
|
|
4876
|
-
}));
|
|
4877
|
-
};
|
|
4878
|
-
window.addEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
4879
|
-
return () => {
|
|
4880
|
-
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
4881
|
-
};
|
|
4882
|
-
}, [turnIndexByLogId, virtualizer]);
|
|
4883
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4884
|
-
"div",
|
|
4885
|
-
{
|
|
4886
|
-
className: "relative w-full",
|
|
4887
|
-
style: { height: `${virtualizer.getTotalSize()}px` },
|
|
4888
|
-
"data-virtualized-turn-list": "true",
|
|
4889
|
-
children: virtualizer.getVirtualItems().map((virtualItem) => {
|
|
4890
|
-
const turnGroup = turnGroups[virtualItem.index];
|
|
4891
|
-
if (turnGroup === void 0) return null;
|
|
4892
|
-
const itemFocusRequest = pendingFocusRequest !== null && pendingFocusRequest.turnIndex === virtualItem.index ? pendingFocusRequest : void 0;
|
|
4893
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4894
|
-
"div",
|
|
4895
|
-
{
|
|
4896
|
-
"data-index": virtualItem.index,
|
|
4897
|
-
ref: virtualizer.measureElement,
|
|
4898
|
-
className: "absolute left-0 top-0 w-full",
|
|
4899
|
-
style: { transform: `translateY(${virtualItem.start}px)` },
|
|
4900
|
-
children: renderTurnGroup(turnGroup, props, itemFocusRequest)
|
|
4901
|
-
},
|
|
4902
|
-
virtualItem.key
|
|
4903
|
-
);
|
|
4904
|
-
})
|
|
4905
|
-
}
|
|
4906
|
-
);
|
|
4907
|
-
}
|
|
4908
|
-
const CandidateResponseSchema = object({
|
|
4909
|
-
candidates: array(KnowledgeCandidateSchema)
|
|
4910
|
-
});
|
|
4911
|
-
const CandidatePromotionResponseSchema = object({
|
|
4912
|
-
candidate: KnowledgeCandidateSchema
|
|
4913
|
-
});
|
|
4914
|
-
const CandidatePromotionFailureResponseSchema = object({
|
|
4915
|
-
error: string().optional(),
|
|
4916
|
-
candidate: KnowledgeCandidateSchema.optional()
|
|
4917
|
-
});
|
|
4918
|
-
const CandidateUpdateResponseSchema = object({
|
|
4919
|
-
candidate: KnowledgeCandidateSchema
|
|
4920
|
-
});
|
|
4921
|
-
const CANDIDATE_STATUS_CLASSES = {
|
|
4922
|
-
draft: "border-amber-500/30 bg-amber-500/10 text-amber-500",
|
|
4923
|
-
promoted: "border-emerald-500/30 bg-emerald-500/10 text-emerald-500",
|
|
4924
|
-
failed: "border-destructive/30 bg-destructive/10 text-destructive"
|
|
4925
|
-
};
|
|
4926
|
-
function formatElapsed$1(ms) {
|
|
4927
|
-
if (ms === null) return "-";
|
|
4928
|
-
if (ms < 1e3) return `${String(ms)}ms`;
|
|
4929
|
-
return `${(ms / 1e3).toFixed(1)}s`;
|
|
4930
|
-
}
|
|
4931
|
-
function formatTimeRange$1(startedAt, endedAt, timeDisplayFormat) {
|
|
4932
|
-
if (startedAt === null || endedAt === null) return null;
|
|
4933
|
-
return formatTimestampRange(startedAt, endedAt, timeDisplayFormat);
|
|
4934
|
-
}
|
|
4935
|
-
function formatCandidateCount(count) {
|
|
4936
|
-
return `${String(count)} candidate${count === 1 ? "" : "s"}`;
|
|
4937
|
-
}
|
|
4938
|
-
function getLogAnchor(logId) {
|
|
4939
|
-
return `log-${String(logId)}`;
|
|
4940
4653
|
}
|
|
4941
|
-
function
|
|
4942
|
-
|
|
4943
|
-
const target = document.getElementById(anchor);
|
|
4944
|
-
window.history.replaceState(null, "", `#${anchor}`);
|
|
4945
|
-
if (!(target instanceof HTMLElement)) return;
|
|
4946
|
-
target.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
4947
|
-
target.focus({ preventScroll: true });
|
|
4654
|
+
function isTurnCollapsible(entryCount, isComplete, isPending) {
|
|
4655
|
+
return entryCount > 1 && isComplete && !isPending;
|
|
4948
4656
|
}
|
|
4949
|
-
function
|
|
4950
|
-
|
|
4951
|
-
|
|
4657
|
+
function buildTurnGroups(logs) {
|
|
4658
|
+
const groups = [];
|
|
4659
|
+
let entries = [];
|
|
4660
|
+
let turnIndex = 0;
|
|
4661
|
+
for (let index = 0; index < logs.length; index += 1) {
|
|
4662
|
+
const log = logs[index];
|
|
4663
|
+
if (log === void 0) continue;
|
|
4664
|
+
entries.push({ log, stopReason: extractStopReason(log), sessionLogNumber: index + 1 });
|
|
4665
|
+
const current = entries[entries.length - 1];
|
|
4666
|
+
if (current !== void 0 && isTurnBoundary(current.stopReason)) {
|
|
4667
|
+
groups.push({ entries, turnIndex });
|
|
4668
|
+
entries = [];
|
|
4669
|
+
turnIndex += 1;
|
|
4670
|
+
}
|
|
4952
4671
|
}
|
|
4953
|
-
|
|
4672
|
+
if (entries.length > 0) groups.push({ entries, turnIndex });
|
|
4673
|
+
return groups;
|
|
4954
4674
|
}
|
|
4955
|
-
function
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
current
|
|
4962
|
-
|
|
4675
|
+
function buildValidPredecessors(groups) {
|
|
4676
|
+
const predecessors = /* @__PURE__ */ new Map();
|
|
4677
|
+
for (const group of groups) {
|
|
4678
|
+
for (let index = 1; index < group.logs.length; index += 1) {
|
|
4679
|
+
const current = group.logs[index];
|
|
4680
|
+
const previous = group.logs[index - 1];
|
|
4681
|
+
if (current === void 0 || previous === void 0) continue;
|
|
4682
|
+
const currentFormat = resolveLogFormat(current);
|
|
4683
|
+
const previousFormat = resolveLogFormat(previous);
|
|
4684
|
+
if (currentFormat === "unknown" || currentFormat !== previousFormat) continue;
|
|
4685
|
+
predecessors.set(current.id, previous);
|
|
4963
4686
|
}
|
|
4964
4687
|
}
|
|
4965
|
-
return
|
|
4688
|
+
return predecessors;
|
|
4966
4689
|
}
|
|
4967
|
-
function
|
|
4968
|
-
|
|
4969
|
-
|
|
4690
|
+
function parseJsonResponse(responseText) {
|
|
4691
|
+
if (responseText === null) return null;
|
|
4692
|
+
try {
|
|
4693
|
+
const parsed = JSON.parse(responseText);
|
|
4694
|
+
if (typeof parsed === "string") {
|
|
4695
|
+
return JSON.parse(parsed);
|
|
4696
|
+
}
|
|
4697
|
+
return parsed;
|
|
4698
|
+
} catch {
|
|
4699
|
+
return null;
|
|
4970
4700
|
}
|
|
4971
|
-
return null;
|
|
4972
4701
|
}
|
|
4973
|
-
function
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
}
|
|
4980
|
-
return result;
|
|
4702
|
+
function previewValue(value) {
|
|
4703
|
+
if (value === void 0 || value === null) return null;
|
|
4704
|
+
const raw = typeof value === "string" ? value : JSON.stringify(value);
|
|
4705
|
+
if (raw === void 0) return null;
|
|
4706
|
+
const normalized = raw.replace(/\s+/g, " ").trim();
|
|
4707
|
+
if (normalized.length === 0) return null;
|
|
4708
|
+
return normalized.length > PREVIEW_LIMIT ? `${normalized.slice(0, PREVIEW_LIMIT - 1)}...` : normalized;
|
|
4981
4709
|
}
|
|
4982
|
-
function
|
|
4983
|
-
|
|
4710
|
+
function copyValue(value) {
|
|
4711
|
+
if (value === void 0 || value === null) return null;
|
|
4712
|
+
if (typeof value === "string") return value.length > 0 ? value : null;
|
|
4713
|
+
const raw = JSON.stringify(value, null, 2);
|
|
4714
|
+
return raw === void 0 || raw.length === 0 ? null : raw;
|
|
4984
4715
|
}
|
|
4985
|
-
function
|
|
4986
|
-
const
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
if (failure !== null) {
|
|
5005
|
-
insights.push({
|
|
5006
|
-
kind: "failure",
|
|
5007
|
-
title: `Failure #${String(failure.responseStatus)}`,
|
|
5008
|
-
detail: `First failed request is #${displayLogNumber(failure.id, input.displayNumberByLogId)}`,
|
|
5009
|
-
logId: failure.id
|
|
4716
|
+
function extractAnthropicToolTraceEvents(log) {
|
|
4717
|
+
const parsed = parseJsonResponse(log.responseText);
|
|
4718
|
+
const content = safeGetOwnProperty(parsed, "content");
|
|
4719
|
+
if (!Array.isArray(content)) return [];
|
|
4720
|
+
const events = [];
|
|
4721
|
+
for (const block of content) {
|
|
4722
|
+
const type = safeGetOwnProperty(block, "type");
|
|
4723
|
+
if (type !== "tool_use") continue;
|
|
4724
|
+
const name = safeGetOwnProperty(block, "name");
|
|
4725
|
+
if (typeof name !== "string" || name.length === 0) continue;
|
|
4726
|
+
const input = safeGetOwnProperty(block, "input");
|
|
4727
|
+
events.push({
|
|
4728
|
+
id: `${String(log.id)}-anthropic-tool-${String(events.length)}`,
|
|
4729
|
+
logId: log.id,
|
|
4730
|
+
index: events.length,
|
|
4731
|
+
provider: "anthropic",
|
|
4732
|
+
name,
|
|
4733
|
+
argumentsText: copyValue(input),
|
|
4734
|
+
argumentsPreview: previewValue(input)
|
|
5010
4735
|
});
|
|
5011
4736
|
}
|
|
5012
|
-
|
|
5013
|
-
if (slowest !== null && input.summary.maxElapsedMs !== null) {
|
|
5014
|
-
insights.push({
|
|
5015
|
-
kind: "slow",
|
|
5016
|
-
title: `Slowest ${formatElapsed$1(input.summary.maxElapsedMs)}`,
|
|
5017
|
-
detail: `Max latency observed at #${displayLogNumber(slowest.id, input.displayNumberByLogId)}`,
|
|
5018
|
-
logId: slowest.id
|
|
5019
|
-
});
|
|
5020
|
-
}
|
|
5021
|
-
if (input.candidates.length > 0) {
|
|
5022
|
-
const draftCount = input.candidates.filter((candidate) => candidate.status === "draft").length;
|
|
5023
|
-
const promotedCount = input.candidates.filter(
|
|
5024
|
-
(candidate) => candidate.status === "promoted"
|
|
5025
|
-
).length;
|
|
5026
|
-
insights.push({
|
|
5027
|
-
kind: "candidate",
|
|
5028
|
-
title: `${String(input.candidates.length)} memory candidate${input.candidates.length === 1 ? "" : "s"}`,
|
|
5029
|
-
detail: `${String(draftCount)} draft / ${String(promotedCount)} promoted`,
|
|
5030
|
-
logId: input.candidates[0]?.logIds[0] ?? null
|
|
5031
|
-
});
|
|
5032
|
-
}
|
|
5033
|
-
return insights;
|
|
5034
|
-
}
|
|
5035
|
-
function insightIcon(kind) {
|
|
5036
|
-
switch (kind) {
|
|
5037
|
-
case "session":
|
|
5038
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3.5 text-blue-400" });
|
|
5039
|
-
case "tool":
|
|
5040
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3.5 text-sky-400/70" });
|
|
5041
|
-
case "slow":
|
|
5042
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3.5 text-amber-400" });
|
|
5043
|
-
case "failure":
|
|
5044
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleX, { className: "size-3.5 text-destructive" });
|
|
5045
|
-
case "candidate":
|
|
5046
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(Brain, { className: "size-3.5 text-emerald-400" });
|
|
5047
|
-
}
|
|
5048
|
-
}
|
|
5049
|
-
function TraceInsights({ insights }) {
|
|
5050
|
-
if (insights.length === 0) return null;
|
|
5051
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 grid gap-1.5 border-t border-border/70 pt-2 md:grid-cols-2 xl:grid-cols-3", children: insights.map((insight) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5052
|
-
"button",
|
|
5053
|
-
{
|
|
5054
|
-
type: "button",
|
|
5055
|
-
className: cn(
|
|
5056
|
-
"flex min-w-0 items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs",
|
|
5057
|
-
"text-muted-foreground transition-colors hover:bg-muted/40 hover:text-foreground",
|
|
5058
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
5059
|
-
),
|
|
5060
|
-
onClick: () => {
|
|
5061
|
-
if (insight.logId !== null) jumpToLog(insight.logId);
|
|
5062
|
-
},
|
|
5063
|
-
disabled: insight.logId === null,
|
|
5064
|
-
children: [
|
|
5065
|
-
insightIcon(insight.kind),
|
|
5066
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0", children: [
|
|
5067
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block truncate font-medium text-foreground/90", children: insight.title }),
|
|
5068
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block truncate font-mono text-[10px]", children: insight.detail })
|
|
5069
|
-
] })
|
|
5070
|
-
]
|
|
5071
|
-
},
|
|
5072
|
-
`${insight.kind}-${insight.title}`
|
|
5073
|
-
)) });
|
|
4737
|
+
return events;
|
|
5074
4738
|
}
|
|
5075
|
-
function
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
4739
|
+
function extractOpenAIToolTraceEvents(log) {
|
|
4740
|
+
const parsed = parseJsonResponse(log.responseText);
|
|
4741
|
+
const choices = safeGetOwnProperty(parsed, "choices");
|
|
4742
|
+
if (!Array.isArray(choices)) return [];
|
|
4743
|
+
const events = [];
|
|
4744
|
+
for (const choice of choices) {
|
|
4745
|
+
const message = safeGetOwnProperty(choice, "message");
|
|
4746
|
+
const toolCalls = safeGetOwnProperty(message, "tool_calls");
|
|
4747
|
+
if (!Array.isArray(toolCalls)) continue;
|
|
4748
|
+
for (const call of toolCalls) {
|
|
4749
|
+
const fn = safeGetOwnProperty(call, "function");
|
|
4750
|
+
const name = safeGetOwnProperty(fn, "name");
|
|
4751
|
+
if (typeof name !== "string" || name.length === 0) continue;
|
|
4752
|
+
const args = safeGetOwnProperty(fn, "arguments");
|
|
4753
|
+
events.push({
|
|
4754
|
+
id: `${String(log.id)}-openai-tool-${String(events.length)}`,
|
|
4755
|
+
logId: log.id,
|
|
4756
|
+
index: events.length,
|
|
4757
|
+
provider: "openai",
|
|
4758
|
+
name,
|
|
4759
|
+
argumentsText: copyValue(args),
|
|
4760
|
+
argumentsPreview: previewValue(args)
|
|
4761
|
+
});
|
|
4762
|
+
}
|
|
5083
4763
|
}
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
4764
|
+
const output = safeGetOwnProperty(parsed, "output");
|
|
4765
|
+
if (Array.isArray(output)) {
|
|
4766
|
+
for (const item of output) {
|
|
4767
|
+
if (safeGetOwnProperty(item, "type") !== "function_call") continue;
|
|
4768
|
+
const name = safeGetOwnProperty(item, "name");
|
|
4769
|
+
if (typeof name !== "string" || name.length === 0) continue;
|
|
4770
|
+
const args = safeGetOwnProperty(item, "arguments");
|
|
4771
|
+
events.push({
|
|
4772
|
+
id: `${String(log.id)}-openai-tool-${String(events.length)}`,
|
|
4773
|
+
logId: log.id,
|
|
4774
|
+
index: events.length,
|
|
4775
|
+
provider: "openai",
|
|
4776
|
+
name,
|
|
4777
|
+
argumentsText: copyValue(args),
|
|
4778
|
+
argumentsPreview: previewValue(args)
|
|
4779
|
+
});
|
|
4780
|
+
}
|
|
5094
4781
|
}
|
|
4782
|
+
return events;
|
|
5095
4783
|
}
|
|
5096
|
-
function
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
function previewText(value, maxLength) {
|
|
5101
|
-
const normalized = value.replace(/\s+/g, " ").trim();
|
|
5102
|
-
if (normalized.length <= maxLength) return normalized;
|
|
5103
|
-
return `${normalized.slice(0, maxLength - 3)}...`;
|
|
5104
|
-
}
|
|
5105
|
-
function logRangeLabel(logIds, displayNumberByLogId) {
|
|
5106
|
-
const first = logIds[0];
|
|
5107
|
-
const last = logIds[logIds.length - 1];
|
|
5108
|
-
if (first === void 0) return "No evidence logs";
|
|
5109
|
-
const firstLabel = displayLogNumber(first, displayNumberByLogId);
|
|
5110
|
-
if (last === void 0 || first === last) return `#${firstLabel}`;
|
|
5111
|
-
return `#${firstLabel}-#${displayLogNumber(last, displayNumberByLogId)}`;
|
|
5112
|
-
}
|
|
5113
|
-
function tagsToText(tags) {
|
|
5114
|
-
return tags.join(", ");
|
|
5115
|
-
}
|
|
5116
|
-
function textToTags(value) {
|
|
5117
|
-
return value.split(",").map((tag) => tag.trim()).filter((tag) => tag.length > 0);
|
|
5118
|
-
}
|
|
5119
|
-
function CandidateItem({
|
|
5120
|
-
candidate,
|
|
5121
|
-
isPromoting,
|
|
5122
|
-
isUpdating,
|
|
5123
|
-
onPromoteCandidate,
|
|
5124
|
-
onUpdateCandidate,
|
|
5125
|
-
displayNumberByLogId
|
|
5126
|
-
}) {
|
|
5127
|
-
const [editing, setEditing] = reactExports.useState(false);
|
|
5128
|
-
const [draftType, setDraftType] = reactExports.useState(candidate.type);
|
|
5129
|
-
const [draftTitle, setDraftTitle] = reactExports.useState(candidate.title);
|
|
5130
|
-
const [draftContent, setDraftContent] = reactExports.useState(candidate.content);
|
|
5131
|
-
const [draftTags, setDraftTags] = reactExports.useState(tagsToText(candidate.tags));
|
|
5132
|
-
const [localError, setLocalError] = reactExports.useState(null);
|
|
5133
|
-
const canPromote = candidate.status !== "promoted";
|
|
5134
|
-
const canEdit = candidate.status !== "promoted";
|
|
5135
|
-
const resetDraft = reactExports.useCallback(() => {
|
|
5136
|
-
setDraftType(candidate.type);
|
|
5137
|
-
setDraftTitle(candidate.title);
|
|
5138
|
-
setDraftContent(candidate.content);
|
|
5139
|
-
setDraftTags(tagsToText(candidate.tags));
|
|
5140
|
-
setLocalError(null);
|
|
5141
|
-
}, [candidate.content, candidate.tags, candidate.title, candidate.type]);
|
|
5142
|
-
const saveDraft = reactExports.useCallback(async () => {
|
|
5143
|
-
const title = draftTitle.trim();
|
|
5144
|
-
const content = draftContent.trim();
|
|
5145
|
-
const tags = textToTags(draftTags);
|
|
5146
|
-
if (title.length === 0) {
|
|
5147
|
-
setLocalError("Title is required.");
|
|
5148
|
-
return;
|
|
5149
|
-
}
|
|
5150
|
-
if (content.length === 0) {
|
|
5151
|
-
setLocalError("Content is required.");
|
|
5152
|
-
return;
|
|
5153
|
-
}
|
|
5154
|
-
if (tags.length === 0) {
|
|
5155
|
-
setLocalError("At least one tag is required.");
|
|
5156
|
-
return;
|
|
5157
|
-
}
|
|
5158
|
-
setLocalError(null);
|
|
5159
|
-
const saved = await onUpdateCandidate(candidate.id, {
|
|
5160
|
-
type: draftType,
|
|
5161
|
-
title,
|
|
5162
|
-
content,
|
|
5163
|
-
tags
|
|
5164
|
-
});
|
|
5165
|
-
if (saved) setEditing(false);
|
|
5166
|
-
}, [candidate.id, draftContent, draftTags, draftTitle, draftType, onUpdateCandidate]);
|
|
5167
|
-
if (editing) {
|
|
5168
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-card shadow-sm rounded-[8px] px-2.5 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-2", children: [
|
|
5169
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5170
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5171
|
-
"select",
|
|
5172
|
-
{
|
|
5173
|
-
value: draftType,
|
|
5174
|
-
disabled: isUpdating,
|
|
5175
|
-
onChange: (event) => {
|
|
5176
|
-
const parsed = KnowledgeCandidateSchema.shape.type.safeParse(
|
|
5177
|
-
event.currentTarget.value
|
|
5178
|
-
);
|
|
5179
|
-
if (parsed.success) setDraftType(parsed.data);
|
|
5180
|
-
},
|
|
5181
|
-
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 rounded-md px-2 text-xs",
|
|
5182
|
-
"aria-label": "Candidate type",
|
|
5183
|
-
children: [
|
|
5184
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "episode", children: "episode" }),
|
|
5185
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "procedure", children: "procedure" }),
|
|
5186
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "preference", children: "preference" }),
|
|
5187
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "project-fact", children: "project-fact" })
|
|
5188
|
-
]
|
|
5189
|
-
}
|
|
5190
|
-
),
|
|
5191
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5192
|
-
"input",
|
|
5193
|
-
{
|
|
5194
|
-
value: draftTitle,
|
|
5195
|
-
disabled: isUpdating,
|
|
5196
|
-
onChange: (event) => setDraftTitle(event.currentTarget.value),
|
|
5197
|
-
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 min-w-[220px] flex-1 rounded-md px-2 text-xs",
|
|
5198
|
-
"aria-label": "Candidate title"
|
|
5199
|
-
}
|
|
5200
|
-
)
|
|
5201
|
-
] }),
|
|
5202
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5203
|
-
"textarea",
|
|
5204
|
-
{
|
|
5205
|
-
value: draftContent,
|
|
5206
|
-
disabled: isUpdating,
|
|
5207
|
-
onChange: (event) => setDraftContent(event.currentTarget.value),
|
|
5208
|
-
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground min-h-28 rounded-md px-2 py-1.5 font-mono text-[11px] leading-relaxed",
|
|
5209
|
-
"aria-label": "Candidate content"
|
|
5210
|
-
}
|
|
5211
|
-
),
|
|
5212
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5213
|
-
"input",
|
|
5214
|
-
{
|
|
5215
|
-
value: draftTags,
|
|
5216
|
-
disabled: isUpdating,
|
|
5217
|
-
onChange: (event) => setDraftTags(event.currentTarget.value),
|
|
5218
|
-
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 rounded-md px-2 text-xs",
|
|
5219
|
-
"aria-label": "Candidate tags"
|
|
5220
|
-
}
|
|
5221
|
-
),
|
|
5222
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5223
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] text-muted-foreground", children: [
|
|
5224
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ShieldCheck, { className: "size-3" }),
|
|
5225
|
-
"Saving reruns Inspector redaction before promotion."
|
|
5226
|
-
] }),
|
|
5227
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
|
|
5228
|
-
localError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-destructive", children: localError }),
|
|
5229
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5230
|
-
Button,
|
|
5231
|
-
{
|
|
5232
|
-
type: "button",
|
|
5233
|
-
variant: "ghost",
|
|
5234
|
-
size: "sm",
|
|
5235
|
-
className: "h-7 gap-1.5 px-2 text-xs",
|
|
5236
|
-
disabled: isUpdating,
|
|
5237
|
-
onClick: () => {
|
|
5238
|
-
resetDraft();
|
|
5239
|
-
setEditing(false);
|
|
5240
|
-
},
|
|
5241
|
-
children: [
|
|
5242
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-3.5" }),
|
|
5243
|
-
"Cancel"
|
|
5244
|
-
]
|
|
5245
|
-
}
|
|
5246
|
-
),
|
|
5247
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5248
|
-
Button,
|
|
5249
|
-
{
|
|
5250
|
-
type: "button",
|
|
5251
|
-
variant: "outline",
|
|
5252
|
-
size: "sm",
|
|
5253
|
-
className: "h-7 gap-1.5 px-2 text-xs",
|
|
5254
|
-
disabled: isUpdating,
|
|
5255
|
-
onClick: () => {
|
|
5256
|
-
void saveDraft();
|
|
5257
|
-
},
|
|
5258
|
-
children: [
|
|
5259
|
-
isUpdating ? /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "size-3.5" }),
|
|
5260
|
-
"Save"
|
|
5261
|
-
]
|
|
5262
|
-
}
|
|
5263
|
-
)
|
|
5264
|
-
] })
|
|
5265
|
-
] }) });
|
|
4784
|
+
function extractToolTraceEvents(log) {
|
|
4785
|
+
const cached = toolTraceCache.get(log);
|
|
4786
|
+
if (cached !== void 0 && cached.apiFormat === log.apiFormat && cached.responseText === log.responseText) {
|
|
4787
|
+
return cached.events;
|
|
5266
4788
|
}
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
] }),
|
|
5296
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
5297
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(ShieldCheck, { className: "size-3" }),
|
|
5298
|
-
redactionLabel(candidate)
|
|
5299
|
-
] }),
|
|
5300
|
-
candidate.status === "promoted" && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 text-emerald-500", children: [
|
|
5301
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "size-3" }),
|
|
5302
|
-
candidate.openClawMemoryId ?? "OpenClaw"
|
|
5303
|
-
] }),
|
|
5304
|
-
candidate.status === "failed" && candidate.error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 text-destructive", children: [
|
|
5305
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleX, { className: "size-3" }),
|
|
5306
|
-
candidate.error
|
|
5307
|
-
] })
|
|
5308
|
-
] }),
|
|
5309
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-1.5", children: [
|
|
5310
|
-
candidate.logIds.map((logId) => {
|
|
5311
|
-
const displayNumber = displayLogNumber(logId, displayNumberByLogId);
|
|
5312
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5313
|
-
"a",
|
|
5314
|
-
{
|
|
5315
|
-
href: `#${getLogAnchor(logId)}`,
|
|
5316
|
-
onClick: (event) => {
|
|
5317
|
-
event.preventDefault();
|
|
5318
|
-
jumpToLog(logId);
|
|
5319
|
-
},
|
|
5320
|
-
className: "rounded border border-blue-400/25 px-1.5 py-0.5 font-mono text-[10px] text-blue-400 underline-offset-2 transition-colors hover:bg-blue-400/10 hover:text-blue-300 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5321
|
-
"aria-label": `Jump to evidence log ${displayNumber}`,
|
|
5322
|
-
title: `Log ID ${String(logId)}`,
|
|
5323
|
-
children: [
|
|
5324
|
-
"#",
|
|
5325
|
-
displayNumber
|
|
5326
|
-
]
|
|
5327
|
-
},
|
|
5328
|
-
logId
|
|
5329
|
-
);
|
|
5330
|
-
}),
|
|
5331
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
|
|
5332
|
-
canEdit && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5333
|
-
Button,
|
|
5334
|
-
{
|
|
5335
|
-
type: "button",
|
|
5336
|
-
variant: "ghost",
|
|
5337
|
-
size: "sm",
|
|
5338
|
-
className: "h-6 gap-1.5 px-2 text-[10px]",
|
|
5339
|
-
disabled: isUpdating || isPromoting,
|
|
5340
|
-
onClick: () => setEditing(true),
|
|
5341
|
-
children: [
|
|
5342
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-3" }),
|
|
5343
|
-
"Review"
|
|
5344
|
-
]
|
|
5345
|
-
}
|
|
5346
|
-
),
|
|
5347
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5348
|
-
Button,
|
|
5349
|
-
{
|
|
5350
|
-
type: "button",
|
|
5351
|
-
variant: canPromote ? "outline" : "ghost",
|
|
5352
|
-
size: "sm",
|
|
5353
|
-
className: "h-6 gap-1.5 px-2 text-[10px]",
|
|
5354
|
-
onClick: () => onPromoteCandidate(candidate.id),
|
|
5355
|
-
disabled: !canPromote || isPromoting || isUpdating,
|
|
5356
|
-
children: [
|
|
5357
|
-
isPromoting ? /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "size-3 animate-spin" }) : canPromote ? /* @__PURE__ */ jsxRuntimeExports.jsx(CloudUpload, { className: "size-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "size-3" }),
|
|
5358
|
-
candidatePromoteLabel(candidate, isPromoting)
|
|
5359
|
-
]
|
|
5360
|
-
}
|
|
5361
|
-
)
|
|
5362
|
-
] })
|
|
5363
|
-
] });
|
|
4789
|
+
const format = resolveLogFormat(log);
|
|
4790
|
+
if (!responseMayContainToolTrace(log, format)) {
|
|
4791
|
+
const events2 = [];
|
|
4792
|
+
toolTraceCache.set(log, {
|
|
4793
|
+
apiFormat: log.apiFormat,
|
|
4794
|
+
responseText: log.responseText,
|
|
4795
|
+
events: events2
|
|
4796
|
+
});
|
|
4797
|
+
return events2;
|
|
4798
|
+
}
|
|
4799
|
+
let events;
|
|
4800
|
+
switch (format) {
|
|
4801
|
+
case "anthropic":
|
|
4802
|
+
events = extractAnthropicToolTraceEvents(log);
|
|
4803
|
+
break;
|
|
4804
|
+
case "openai":
|
|
4805
|
+
events = extractOpenAIToolTraceEvents(log);
|
|
4806
|
+
break;
|
|
4807
|
+
case "unknown":
|
|
4808
|
+
events = [];
|
|
4809
|
+
break;
|
|
4810
|
+
}
|
|
4811
|
+
toolTraceCache.set(log, {
|
|
4812
|
+
apiFormat: log.apiFormat,
|
|
4813
|
+
responseText: log.responseText,
|
|
4814
|
+
events
|
|
4815
|
+
});
|
|
4816
|
+
return events;
|
|
5364
4817
|
}
|
|
5365
|
-
function
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
4818
|
+
function buildTraceSummary(logs, slowResponseThresholdSeconds, knowledgeCandidateCount = 0) {
|
|
4819
|
+
let failedCallCount = 0;
|
|
4820
|
+
let pendingCallCount = 0;
|
|
4821
|
+
let slowCallCount = 0;
|
|
4822
|
+
let totalInputTokens = 0;
|
|
4823
|
+
let totalOutputTokens = 0;
|
|
4824
|
+
let totalCacheCreationInputTokens = 0;
|
|
4825
|
+
let totalCacheReadInputTokens = 0;
|
|
4826
|
+
let totalElapsedMs = 0;
|
|
4827
|
+
let maxElapsedMs = null;
|
|
4828
|
+
let toolCallCount = 0;
|
|
4829
|
+
for (const log of logs) {
|
|
4830
|
+
if (log.responseStatus === null) {
|
|
4831
|
+
pendingCallCount += 1;
|
|
4832
|
+
} else if (log.responseStatus >= 400) {
|
|
4833
|
+
failedCallCount += 1;
|
|
4834
|
+
}
|
|
4835
|
+
if (log.elapsedMs !== null && slowResponseThresholdSeconds > 0 && log.elapsedMs > slowResponseThresholdSeconds * 1e3) {
|
|
4836
|
+
slowCallCount += 1;
|
|
4837
|
+
}
|
|
4838
|
+
if (log.inputTokens !== null) totalInputTokens += log.inputTokens;
|
|
4839
|
+
if (log.outputTokens !== null) totalOutputTokens += log.outputTokens;
|
|
4840
|
+
if (log.cacheCreationInputTokens !== null) {
|
|
4841
|
+
totalCacheCreationInputTokens += log.cacheCreationInputTokens;
|
|
4842
|
+
}
|
|
4843
|
+
if (log.cacheReadInputTokens !== null) {
|
|
4844
|
+
totalCacheReadInputTokens += log.cacheReadInputTokens;
|
|
4845
|
+
}
|
|
4846
|
+
if (log.elapsedMs !== null) {
|
|
4847
|
+
totalElapsedMs += log.elapsedMs;
|
|
4848
|
+
maxElapsedMs = maxElapsedMs === null ? log.elapsedMs : Math.max(maxElapsedMs, log.elapsedMs);
|
|
4849
|
+
}
|
|
4850
|
+
toolCallCount += extractToolTraceEvents(log).length;
|
|
4851
|
+
}
|
|
4852
|
+
return {
|
|
4853
|
+
llmCallCount: logs.length,
|
|
4854
|
+
toolCallCount,
|
|
4855
|
+
failedCallCount,
|
|
4856
|
+
pendingCallCount,
|
|
4857
|
+
slowCallCount,
|
|
4858
|
+
totalInputTokens,
|
|
4859
|
+
totalOutputTokens,
|
|
4860
|
+
totalCacheCreationInputTokens,
|
|
4861
|
+
totalCacheReadInputTokens,
|
|
4862
|
+
totalElapsedMs,
|
|
4863
|
+
maxElapsedMs,
|
|
4864
|
+
startedAt: logs[0]?.timestamp ?? null,
|
|
4865
|
+
endedAt: logs[logs.length - 1]?.timestamp ?? null,
|
|
4866
|
+
knowledgeCandidateCount
|
|
4867
|
+
};
|
|
5386
4868
|
}
|
|
5387
|
-
function
|
|
5388
|
-
|
|
5389
|
-
|
|
4869
|
+
function formatElapsed$2(ms) {
|
|
4870
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
4871
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
4872
|
+
}
|
|
4873
|
+
const TurnGroup = reactExports.memo(function TurnGroup2({
|
|
4874
|
+
entries,
|
|
4875
|
+
viewMode,
|
|
4876
|
+
strip,
|
|
5390
4877
|
slowResponseThresholdSeconds,
|
|
5391
|
-
|
|
5392
|
-
|
|
4878
|
+
cacheTrends,
|
|
4879
|
+
onCompareWithPrevious,
|
|
4880
|
+
comparisonPredecessors,
|
|
4881
|
+
turnIndex = 0,
|
|
4882
|
+
timeDisplayFormat,
|
|
4883
|
+
pendingFocusRequest,
|
|
4884
|
+
showLogClientMetadata = true
|
|
5393
4885
|
}) {
|
|
5394
|
-
const
|
|
5395
|
-
const [
|
|
5396
|
-
const
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
const [
|
|
5401
|
-
|
|
5402
|
-
)
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
)
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
() =>
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
const message = await readApiError(
|
|
5432
|
-
response,
|
|
5433
|
-
`Candidate generation failed with ${String(response.status)}`
|
|
5434
|
-
);
|
|
5435
|
-
setCandidateState({ status: "failed", error: message });
|
|
5436
|
-
return;
|
|
5437
|
-
}
|
|
5438
|
-
const parsed = await parseJsonResponse$1(response, CandidateResponseSchema);
|
|
5439
|
-
setCandidates(parsed.candidates);
|
|
5440
|
-
setCandidatesExpanded(parsed.candidates.length > 0);
|
|
5441
|
-
setCandidateState(
|
|
5442
|
-
parsed.candidates.length > 0 ? { status: "ready", error: null } : { status: "failed", error: "No candidate was generated for this trace scope." }
|
|
5443
|
-
);
|
|
5444
|
-
} catch (error) {
|
|
5445
|
-
setCandidateState({
|
|
5446
|
-
status: "failed",
|
|
5447
|
-
error: error instanceof Error ? error.message : "Candidate response was invalid"
|
|
5448
|
-
});
|
|
5449
|
-
}
|
|
5450
|
-
})();
|
|
5451
|
-
}, [candidateState.status, logs.length, scopeId]);
|
|
5452
|
-
const promoteCandidate = reactExports.useCallback((candidateId) => {
|
|
5453
|
-
setPromotingCandidateIds((current) => {
|
|
5454
|
-
if (current.has(candidateId)) return current;
|
|
5455
|
-
const next = new Set(current);
|
|
5456
|
-
next.add(candidateId);
|
|
5457
|
-
return next;
|
|
5458
|
-
});
|
|
5459
|
-
void (async () => {
|
|
5460
|
-
try {
|
|
5461
|
-
const response = await fetch(
|
|
5462
|
-
`/api/knowledge/candidates/${encodeURIComponent(candidateId)}/promote`,
|
|
5463
|
-
{ method: "POST" }
|
|
5464
|
-
);
|
|
5465
|
-
const raw = await response.json().catch(() => null);
|
|
5466
|
-
const parsed = CandidatePromotionResponseSchema.safeParse(raw);
|
|
5467
|
-
if (response.ok && parsed.success) {
|
|
5468
|
-
setCandidates(
|
|
5469
|
-
(current) => current.map(
|
|
5470
|
-
(candidate) => candidate.id === parsed.data.candidate.id ? parsed.data.candidate : candidate
|
|
5471
|
-
)
|
|
5472
|
-
);
|
|
5473
|
-
setCandidateState({ status: "ready", error: null });
|
|
5474
|
-
return;
|
|
5475
|
-
}
|
|
5476
|
-
const failure = CandidatePromotionFailureResponseSchema.safeParse(raw);
|
|
5477
|
-
if (failure.success && failure.data.candidate !== void 0) {
|
|
5478
|
-
setCandidates(
|
|
5479
|
-
(current) => current.map(
|
|
5480
|
-
(candidate) => candidate.id === failure.data.candidate?.id ? failure.data.candidate : candidate
|
|
5481
|
-
)
|
|
5482
|
-
);
|
|
5483
|
-
}
|
|
5484
|
-
setCandidateState({
|
|
5485
|
-
status: "failed",
|
|
5486
|
-
error: failure.success ? failure.data.error ?? "Candidate promotion failed" : `Candidate promotion failed with ${String(response.status)}`
|
|
5487
|
-
});
|
|
5488
|
-
} catch (error) {
|
|
5489
|
-
setCandidateState({
|
|
5490
|
-
status: "failed",
|
|
5491
|
-
error: error instanceof Error ? error.message : "Candidate promotion failed"
|
|
5492
|
-
});
|
|
5493
|
-
} finally {
|
|
5494
|
-
setPromotingCandidateIds((current) => {
|
|
5495
|
-
const next = new Set(current);
|
|
5496
|
-
next.delete(candidateId);
|
|
5497
|
-
return next;
|
|
5498
|
-
});
|
|
5499
|
-
}
|
|
5500
|
-
})();
|
|
5501
|
-
}, []);
|
|
5502
|
-
const updateCandidate = reactExports.useCallback(
|
|
5503
|
-
async (candidateId, update) => {
|
|
5504
|
-
setUpdatingCandidateIds((current) => {
|
|
5505
|
-
if (current.has(candidateId)) return current;
|
|
5506
|
-
const next = new Set(current);
|
|
5507
|
-
next.add(candidateId);
|
|
5508
|
-
return next;
|
|
4886
|
+
const lastIdx = entries.length - 1;
|
|
4887
|
+
const lastStop = entries[lastIdx]?.stopReason ?? null;
|
|
4888
|
+
const isComplete = lastStop !== null ? isTurnBoundary(lastStop) : false;
|
|
4889
|
+
const isPending = entries[lastIdx]?.log.responseStatus === null;
|
|
4890
|
+
const isSingleLog = entries.length === 1;
|
|
4891
|
+
const collapsible = isTurnCollapsible(entries.length, isComplete, isPending);
|
|
4892
|
+
const [collapsed, setCollapsed] = reactExports.useState(false);
|
|
4893
|
+
const prevCompleteRef = reactExports.useRef(false);
|
|
4894
|
+
reactExports.useEffect(() => {
|
|
4895
|
+
if (!collapsible) {
|
|
4896
|
+
setCollapsed(false);
|
|
4897
|
+
} else if (isComplete && !prevCompleteRef.current) {
|
|
4898
|
+
setCollapsed(true);
|
|
4899
|
+
}
|
|
4900
|
+
prevCompleteRef.current = isComplete;
|
|
4901
|
+
}, [collapsible, isComplete]);
|
|
4902
|
+
reactExports.useEffect(() => {
|
|
4903
|
+
const handleLogFocusRequest = (event) => {
|
|
4904
|
+
const request = readLogFocusRequest(event);
|
|
4905
|
+
if (request === null) return;
|
|
4906
|
+
if (!entries.some((entry) => entry.log.id === request.logId)) return;
|
|
4907
|
+
if (collapsible) setCollapsed(false);
|
|
4908
|
+
};
|
|
4909
|
+
window.addEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
4910
|
+
return () => {
|
|
4911
|
+
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
4912
|
+
};
|
|
4913
|
+
}, [collapsible, entries]);
|
|
4914
|
+
reactExports.useEffect(() => {
|
|
4915
|
+
if (pendingFocusRequest === void 0) return void 0;
|
|
4916
|
+
if (!entries.some((entry) => entry.log.id === pendingFocusRequest.logId)) return void 0;
|
|
4917
|
+
if (collapsible) setCollapsed(false);
|
|
4918
|
+
const timer = window.setTimeout(() => {
|
|
4919
|
+
dispatchLogFocusRequest({
|
|
4920
|
+
logId: pendingFocusRequest.logId,
|
|
4921
|
+
tab: pendingFocusRequest.tab,
|
|
4922
|
+
source: "virtualizer"
|
|
5509
4923
|
});
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
return false;
|
|
5526
|
-
}
|
|
5527
|
-
const parsed = await parseJsonResponse$1(response, CandidateUpdateResponseSchema);
|
|
5528
|
-
setCandidates(
|
|
5529
|
-
(current) => current.map(
|
|
5530
|
-
(candidate) => candidate.id === parsed.candidate.id ? parsed.candidate : candidate
|
|
5531
|
-
)
|
|
5532
|
-
);
|
|
5533
|
-
setCandidateState({ status: "ready", error: null });
|
|
5534
|
-
return true;
|
|
5535
|
-
} catch (error) {
|
|
5536
|
-
setCandidateState({
|
|
5537
|
-
status: "failed",
|
|
5538
|
-
error: error instanceof Error ? error.message : "Candidate update failed"
|
|
5539
|
-
});
|
|
5540
|
-
return false;
|
|
5541
|
-
} finally {
|
|
5542
|
-
setUpdatingCandidateIds((current) => {
|
|
5543
|
-
const next = new Set(current);
|
|
5544
|
-
next.delete(candidateId);
|
|
5545
|
-
return next;
|
|
5546
|
-
});
|
|
4924
|
+
}, 0);
|
|
4925
|
+
return () => window.clearTimeout(timer);
|
|
4926
|
+
}, [collapsible, entries, pendingFocusRequest]);
|
|
4927
|
+
const toggleCollapse = reactExports.useCallback(() => {
|
|
4928
|
+
if (collapsible) setCollapsed((prev) => !prev);
|
|
4929
|
+
}, [collapsible]);
|
|
4930
|
+
const aggregate = reactExports.useMemo(() => {
|
|
4931
|
+
let totalInput = 0;
|
|
4932
|
+
let totalOutput = 0;
|
|
4933
|
+
let maxElapsed = null;
|
|
4934
|
+
let hasTokens = false;
|
|
4935
|
+
for (const e of entries) {
|
|
4936
|
+
if (e.log.inputTokens !== null) {
|
|
4937
|
+
totalInput += e.log.inputTokens;
|
|
4938
|
+
hasTokens = true;
|
|
5547
4939
|
}
|
|
5548
|
-
|
|
5549
|
-
|
|
4940
|
+
if (e.log.outputTokens !== null) {
|
|
4941
|
+
totalOutput += e.log.outputTokens;
|
|
4942
|
+
hasTokens = true;
|
|
4943
|
+
}
|
|
4944
|
+
if (e.log.elapsedMs !== null) {
|
|
4945
|
+
maxElapsed = maxElapsed === null ? e.log.elapsedMs : Math.max(maxElapsed, e.log.elapsedMs);
|
|
4946
|
+
}
|
|
4947
|
+
}
|
|
4948
|
+
return {
|
|
4949
|
+
totalInput,
|
|
4950
|
+
totalOutput,
|
|
4951
|
+
hasTokens,
|
|
4952
|
+
maxElapsed
|
|
4953
|
+
};
|
|
4954
|
+
}, [entries, lastIdx]);
|
|
4955
|
+
const bgClass = turnIndex % 2 === 0 ? "bg-white/[0.012]" : "bg-cyan-300/[0.012]";
|
|
4956
|
+
const aggregateIsSlow = aggregate.maxElapsed !== null && slowResponseThresholdSeconds > 0 && aggregate.maxElapsed > slowResponseThresholdSeconds * 1e3;
|
|
4957
|
+
const toolEventsByLogId = reactExports.useMemo(() => {
|
|
4958
|
+
const events = /* @__PURE__ */ new Map();
|
|
4959
|
+
for (const entry of entries) {
|
|
4960
|
+
const extracted = extractToolTraceEvents(entry.log);
|
|
4961
|
+
if (extracted.length > 0) events.set(entry.log.id, extracted);
|
|
4962
|
+
}
|
|
4963
|
+
return events;
|
|
4964
|
+
}, [entries]);
|
|
4965
|
+
const [layoutVersion, setLayoutVersion] = reactExports.useState(0);
|
|
4966
|
+
const containerRef = reactExports.useRef(null);
|
|
4967
|
+
reactExports.useEffect(() => {
|
|
4968
|
+
const el = containerRef.current;
|
|
4969
|
+
if (!el) return;
|
|
4970
|
+
let raf = 0;
|
|
4971
|
+
const ro = new ResizeObserver(() => {
|
|
4972
|
+
window.cancelAnimationFrame(raf);
|
|
4973
|
+
raf = window.requestAnimationFrame(() => setLayoutVersion((v) => v + 1));
|
|
4974
|
+
});
|
|
4975
|
+
ro.observe(el);
|
|
4976
|
+
return () => {
|
|
4977
|
+
ro.disconnect();
|
|
4978
|
+
window.cancelAnimationFrame(raf);
|
|
4979
|
+
};
|
|
4980
|
+
}, []);
|
|
4981
|
+
const firstLogId = entries[0]?.log.id ?? turnIndex;
|
|
4982
|
+
const turnLabel = `Turn ${String(turnIndex + 1)}`;
|
|
4983
|
+
const containmentStyle = reactExports.useMemo(
|
|
4984
|
+
() => ({
|
|
4985
|
+
contentVisibility: "auto",
|
|
4986
|
+
containIntrinsicSize: collapsed ? "48px" : "160px"
|
|
4987
|
+
}),
|
|
4988
|
+
[collapsed]
|
|
5550
4989
|
);
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
"
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
formatTokens(summary.totalInputTokens),
|
|
5568
|
-
" / ",
|
|
5569
|
-
formatTokens(summary.totalOutputTokens)
|
|
5570
|
-
] })
|
|
5571
|
-
] }),
|
|
5572
|
-
(summary.totalCacheCreationInputTokens > 0 || summary.totalCacheReadInputTokens > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
|
|
5573
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3.5 text-purple-400" }),
|
|
5574
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
|
|
5575
|
-
"KV Cache +",
|
|
5576
|
-
formatTokens(summary.totalCacheCreationInputTokens),
|
|
5577
|
-
" / ~",
|
|
5578
|
-
formatTokens(summary.totalCacheReadInputTokens)
|
|
5579
|
-
] })
|
|
5580
|
-
] }),
|
|
5581
|
-
showElapsedSummary && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
|
|
5582
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3.5" }),
|
|
5583
|
-
showRollupMetrics && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatElapsed$1(summary.totalElapsedMs) }),
|
|
5584
|
-
summary.maxElapsedMs !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-muted-foreground/70", children: [
|
|
5585
|
-
"max ",
|
|
5586
|
-
formatElapsed$1(summary.maxElapsedMs)
|
|
5587
|
-
] })
|
|
5588
|
-
] }),
|
|
5589
|
-
showRollupMetrics && timeRange !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground/70", children: timeRange }),
|
|
5590
|
-
(summary.failedCallCount > 0 || summary.pendingCallCount > 0 || summary.slowCallCount > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-amber-400", children: [
|
|
5591
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3.5" }),
|
|
5592
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
|
|
5593
|
-
summary.failedCallCount,
|
|
5594
|
-
" fail / ",
|
|
5595
|
-
summary.pendingCallCount,
|
|
5596
|
-
" pending /",
|
|
5597
|
-
" ",
|
|
5598
|
-
summary.slowCallCount,
|
|
5599
|
-
" slow"
|
|
5600
|
-
] })
|
|
5601
|
-
] }),
|
|
5602
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
|
|
5603
|
-
hasCandidates && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "h-6 px-2 text-[10px] font-mono", children: formatCandidateCount(summary.knowledgeCandidateCount) }),
|
|
5604
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5605
|
-
Button,
|
|
4990
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4991
|
+
"div",
|
|
4992
|
+
{
|
|
4993
|
+
ref: containerRef,
|
|
4994
|
+
style: containmentStyle,
|
|
4995
|
+
tabIndex: collapsed ? void 0 : 0,
|
|
4996
|
+
role: collapsed ? void 0 : "group",
|
|
4997
|
+
"aria-label": collapsed ? void 0 : turnLabel,
|
|
4998
|
+
"data-nav-id": collapsed ? void 0 : `turn-${String(firstLogId)}`,
|
|
4999
|
+
className: cn(
|
|
5000
|
+
"rounded-[8px] border transition-[border-color,box-shadow]",
|
|
5001
|
+
isPending ? "border-amber-300/15 shadow-[0_0_0_1px_rgba(252,211,77,0.04)]" : "border-transparent",
|
|
5002
|
+
!collapsed && "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none"
|
|
5003
|
+
),
|
|
5004
|
+
children: collapsed ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5005
|
+
"div",
|
|
5606
5006
|
{
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5007
|
+
"data-nav-id": `turn-collapsed-${String(firstLogId)}`,
|
|
5008
|
+
"data-nav-action": "expand",
|
|
5009
|
+
role: "button",
|
|
5010
|
+
tabIndex: 0,
|
|
5011
|
+
className: "flex items-stretch cursor-pointer focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:outline-none rounded-lg",
|
|
5012
|
+
onClick: toggleCollapse,
|
|
5013
|
+
onKeyDown: (e) => {
|
|
5014
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
5015
|
+
e.preventDefault();
|
|
5016
|
+
toggleCollapse();
|
|
5017
|
+
}
|
|
5018
|
+
},
|
|
5613
5019
|
children: [
|
|
5614
|
-
|
|
5615
|
-
"
|
|
5020
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-5 shrink-0 flex items-start pt-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/50 font-mono tabular-nums leading-none select-none", children: turnIndex + 1 }) }),
|
|
5021
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-6 shrink-0 flex flex-col items-center pt-1.5 pb-1.5", children: [
|
|
5022
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-center h-[calc(0.75rem-8px)]" }),
|
|
5023
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "size-2 rounded-full border border-cyan-300/45 bg-cyan-300/20" }),
|
|
5024
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex justify-center min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-px bg-muted-foreground/25 h-full" }) }),
|
|
5025
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5026
|
+
"span",
|
|
5027
|
+
{
|
|
5028
|
+
className: cn(
|
|
5029
|
+
"size-2 rounded-full border",
|
|
5030
|
+
isComplete ? "border-amber-300/45 bg-amber-300/20" : "border-muted-foreground/30 bg-muted/30"
|
|
5031
|
+
)
|
|
5032
|
+
}
|
|
5033
|
+
)
|
|
5034
|
+
] }),
|
|
5035
|
+
entries.length > 1 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5036
|
+
"div",
|
|
5037
|
+
{
|
|
5038
|
+
className: cn(
|
|
5039
|
+
"flex-1 min-w-0 mb-0.5 rounded-[8px] py-1.5 px-3 flex items-center gap-3 text-xs shadow-[inset_0_1px_0_rgba(255,255,255,0.04)]",
|
|
5040
|
+
"border border-border bg-card shadow-sm transition-colors hover:border-cyan-200/20",
|
|
5041
|
+
bgClass
|
|
5042
|
+
),
|
|
5043
|
+
children: [
|
|
5044
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground/70", children: turnLabel }),
|
|
5045
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5046
|
+
"span",
|
|
5047
|
+
{
|
|
5048
|
+
className: "text-blue-300/85 font-mono font-semibold tabular-nums shrink-0",
|
|
5049
|
+
title: `Log IDs ${String(entries[0]?.log.id ?? "?")} ~ ${String(
|
|
5050
|
+
entries[lastIdx]?.log.id ?? "?"
|
|
5051
|
+
)}`,
|
|
5052
|
+
children: [
|
|
5053
|
+
"#",
|
|
5054
|
+
entries[0]?.sessionLogNumber ?? "?",
|
|
5055
|
+
" ~ #",
|
|
5056
|
+
entries[lastIdx]?.sessionLogNumber ?? "?"
|
|
5057
|
+
]
|
|
5058
|
+
}
|
|
5059
|
+
),
|
|
5060
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground shrink-0", children: [
|
|
5061
|
+
entries.length,
|
|
5062
|
+
" request",
|
|
5063
|
+
entries.length > 1 ? "s" : ""
|
|
5064
|
+
] }),
|
|
5065
|
+
aggregate.maxElapsed !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
5066
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5067
|
+
"span",
|
|
5068
|
+
{
|
|
5069
|
+
className: cn(
|
|
5070
|
+
"flex items-center gap-1 shrink-0",
|
|
5071
|
+
aggregateIsSlow ? "text-amber-400" : "text-muted-foreground"
|
|
5072
|
+
),
|
|
5073
|
+
children: [
|
|
5074
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
5075
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono tabular-nums", children: formatElapsed$2(aggregate.maxElapsed) }),
|
|
5076
|
+
aggregateIsSlow && /* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3", "aria-label": "Slow response" })
|
|
5077
|
+
]
|
|
5078
|
+
}
|
|
5079
|
+
) }),
|
|
5080
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: aggregateIsSlow ? `Slow response: ${formatElapsed$2(
|
|
5081
|
+
aggregate.maxElapsed
|
|
5082
|
+
)} exceeds ${formatElapsed$2(slowResponseThresholdSeconds * 1e3)}` : "Slowest request in this turn" })
|
|
5083
|
+
] }) }),
|
|
5084
|
+
aggregate.hasTokens && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 shrink-0", children: [
|
|
5085
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3 text-muted-foreground" }),
|
|
5086
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono tabular-nums", children: [
|
|
5087
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-blue-400", children: [
|
|
5088
|
+
"IN ",
|
|
5089
|
+
formatTokens(aggregate.totalInput)
|
|
5090
|
+
] }),
|
|
5091
|
+
" / ",
|
|
5092
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-amber-400", children: [
|
|
5093
|
+
"OUT ",
|
|
5094
|
+
formatTokens(aggregate.totalOutput)
|
|
5095
|
+
] })
|
|
5096
|
+
] })
|
|
5097
|
+
] }),
|
|
5098
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0" }),
|
|
5099
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5100
|
+
"span",
|
|
5101
|
+
{
|
|
5102
|
+
className: "border border-input bg-background inline-flex size-7 shrink-0 items-center justify-center rounded-md text-slate-200",
|
|
5103
|
+
"aria-hidden": "true",
|
|
5104
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 shrink-0" })
|
|
5105
|
+
}
|
|
5106
|
+
)
|
|
5107
|
+
]
|
|
5108
|
+
}
|
|
5109
|
+
)
|
|
5616
5110
|
]
|
|
5617
5111
|
}
|
|
5618
|
-
)
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5112
|
+
) : (
|
|
5113
|
+
/* ---- Expanded: full entries ---- */
|
|
5114
|
+
entries.map((entry, visibleIdx) => {
|
|
5115
|
+
const { log, stopReason: reason } = entry;
|
|
5116
|
+
const isTurnStart = visibleIdx === 0;
|
|
5117
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-stretch", children: [
|
|
5118
|
+
isTurnStart ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-5 shrink-0 flex items-start pt-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground/50 font-mono tabular-nums leading-none select-none", children: turnIndex + 1 }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-5 shrink-0" }),
|
|
5119
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5120
|
+
ThreadConnector,
|
|
5121
|
+
{
|
|
5122
|
+
stopReason: reason,
|
|
5123
|
+
isPending: log.responseStatus === null,
|
|
5124
|
+
isFirst: visibleIdx === 0,
|
|
5125
|
+
isTurnStart,
|
|
5126
|
+
isOnlyEntry: isSingleLog,
|
|
5127
|
+
crabIndex: log.id % 12,
|
|
5128
|
+
collapsible: collapsible && isTurnStart,
|
|
5129
|
+
onToggle: toggleCollapse
|
|
5130
|
+
}
|
|
5131
|
+
),
|
|
5132
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn("flex-1 min-w-0 mb-0.5 rounded-[8px]", bgClass), children: [
|
|
5133
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5134
|
+
LogEntry,
|
|
5135
|
+
{
|
|
5136
|
+
log,
|
|
5137
|
+
displayNumber: entry.sessionLogNumber,
|
|
5138
|
+
viewMode,
|
|
5139
|
+
strip,
|
|
5140
|
+
slowResponseThresholdSeconds,
|
|
5141
|
+
timeDisplayFormat,
|
|
5142
|
+
cacheTrend: cacheTrends?.get(log.id) ?? null,
|
|
5143
|
+
showClientMetadata: showLogClientMetadata,
|
|
5144
|
+
onCompareWithPrevious: comparisonPredecessors.has(log.id) ? onCompareWithPrevious : void 0
|
|
5145
|
+
}
|
|
5146
|
+
),
|
|
5147
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ToolTraceEvents, { events: toolEventsByLogId.get(log.id) ?? [] })
|
|
5148
|
+
] })
|
|
5149
|
+
] }, log.id);
|
|
5150
|
+
})
|
|
5631
5151
|
)
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
updatingCandidateIds,
|
|
5641
|
-
onPromoteCandidate: promoteCandidate,
|
|
5642
|
-
onUpdateCandidate: updateCandidate,
|
|
5643
|
-
displayNumberByLogId
|
|
5644
|
-
}
|
|
5645
|
-
)
|
|
5646
|
-
] });
|
|
5152
|
+
}
|
|
5153
|
+
);
|
|
5154
|
+
});
|
|
5155
|
+
const VIRTUALIZE_TURN_THRESHOLD = 24;
|
|
5156
|
+
const ESTIMATED_TURN_HEIGHT = 132;
|
|
5157
|
+
const VIRTUAL_OVERSCAN = 8;
|
|
5158
|
+
function shouldVirtualizeTurnGroups(turnCount) {
|
|
5159
|
+
return turnCount > VIRTUALIZE_TURN_THRESHOLD;
|
|
5647
5160
|
}
|
|
5648
|
-
function
|
|
5649
|
-
|
|
5650
|
-
let
|
|
5161
|
+
function buildLogTurnIndex(turnGroups) {
|
|
5162
|
+
const result = /* @__PURE__ */ new Map();
|
|
5163
|
+
for (let index = 0; index < turnGroups.length; index++) {
|
|
5164
|
+
const group = turnGroups[index];
|
|
5165
|
+
if (group === void 0) continue;
|
|
5166
|
+
for (const entry of group.entries) {
|
|
5167
|
+
result.set(entry.log.id, index);
|
|
5168
|
+
}
|
|
5169
|
+
}
|
|
5170
|
+
return result;
|
|
5171
|
+
}
|
|
5172
|
+
function renderTurnGroup(turnGroup, props, pendingFocusRequest) {
|
|
5173
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5174
|
+
TurnGroup,
|
|
5175
|
+
{
|
|
5176
|
+
entries: turnGroup.entries,
|
|
5177
|
+
viewMode: props.viewMode,
|
|
5178
|
+
strip: props.strip,
|
|
5179
|
+
slowResponseThresholdSeconds: props.slowResponseThresholdSeconds,
|
|
5180
|
+
timeDisplayFormat: props.timeDisplayFormat,
|
|
5181
|
+
cacheTrends: props.cacheTrends,
|
|
5182
|
+
onCompareWithPrevious: props.onCompareWithPrevious,
|
|
5183
|
+
comparisonPredecessors: props.comparisonPredecessors,
|
|
5184
|
+
turnIndex: turnGroup.turnIndex,
|
|
5185
|
+
pendingFocusRequest,
|
|
5186
|
+
showLogClientMetadata: props.showLogClientMetadata
|
|
5187
|
+
},
|
|
5188
|
+
turnGroup.turnIndex
|
|
5189
|
+
);
|
|
5190
|
+
}
|
|
5191
|
+
function TurnGroupList(props) {
|
|
5192
|
+
if (!shouldVirtualizeTurnGroups(props.turnGroups.length)) {
|
|
5193
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: props.turnGroups.map((turnGroup) => renderTurnGroup(turnGroup, props)) });
|
|
5194
|
+
}
|
|
5195
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(VirtualizedTurnGroupList, { ...props });
|
|
5196
|
+
}
|
|
5197
|
+
function VirtualizedTurnGroupList(props) {
|
|
5198
|
+
const { turnGroups } = props;
|
|
5199
|
+
const [pendingFocusRequest, setPendingFocusRequest] = reactExports.useState(
|
|
5200
|
+
null
|
|
5201
|
+
);
|
|
5202
|
+
const virtualizer = useWindowVirtualizer({
|
|
5203
|
+
count: turnGroups.length,
|
|
5204
|
+
estimateSize: () => ESTIMATED_TURN_HEIGHT,
|
|
5205
|
+
overscan: VIRTUAL_OVERSCAN,
|
|
5206
|
+
getItemKey: (index) => turnGroups[index]?.turnIndex ?? index
|
|
5207
|
+
});
|
|
5208
|
+
const turnIndexByLogId = reactExports.useMemo(() => buildLogTurnIndex(turnGroups), [turnGroups]);
|
|
5209
|
+
reactExports.useEffect(() => {
|
|
5210
|
+
const handleLogFocusRequest = (event) => {
|
|
5211
|
+
const request = readLogFocusRequest(event);
|
|
5212
|
+
if (request === null) return;
|
|
5213
|
+
if (request.source === "virtualizer") return;
|
|
5214
|
+
const turnIndex = turnIndexByLogId.get(request.logId);
|
|
5215
|
+
if (turnIndex === void 0) return;
|
|
5216
|
+
virtualizer.scrollToIndex(turnIndex, { align: "center" });
|
|
5217
|
+
setPendingFocusRequest((previous) => ({
|
|
5218
|
+
...request,
|
|
5219
|
+
turnIndex,
|
|
5220
|
+
nonce: previous === null ? 1 : previous.nonce + 1
|
|
5221
|
+
}));
|
|
5222
|
+
};
|
|
5223
|
+
window.addEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
5224
|
+
return () => {
|
|
5225
|
+
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
5226
|
+
};
|
|
5227
|
+
}, [turnIndexByLogId, virtualizer]);
|
|
5228
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5229
|
+
"div",
|
|
5230
|
+
{
|
|
5231
|
+
className: "relative w-full",
|
|
5232
|
+
style: { height: `${virtualizer.getTotalSize()}px` },
|
|
5233
|
+
"data-virtualized-turn-list": "true",
|
|
5234
|
+
children: virtualizer.getVirtualItems().map((virtualItem) => {
|
|
5235
|
+
const turnGroup = turnGroups[virtualItem.index];
|
|
5236
|
+
if (turnGroup === void 0) return null;
|
|
5237
|
+
const itemFocusRequest = pendingFocusRequest !== null && pendingFocusRequest.turnIndex === virtualItem.index ? pendingFocusRequest : void 0;
|
|
5238
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5239
|
+
"div",
|
|
5240
|
+
{
|
|
5241
|
+
"data-index": virtualItem.index,
|
|
5242
|
+
ref: virtualizer.measureElement,
|
|
5243
|
+
className: "absolute left-0 top-0 w-full",
|
|
5244
|
+
style: { transform: `translateY(${virtualItem.start}px)` },
|
|
5245
|
+
children: renderTurnGroup(turnGroup, props, itemFocusRequest)
|
|
5246
|
+
},
|
|
5247
|
+
virtualItem.key
|
|
5248
|
+
);
|
|
5249
|
+
})
|
|
5250
|
+
}
|
|
5251
|
+
);
|
|
5252
|
+
}
|
|
5253
|
+
const CandidateResponseSchema = object({
|
|
5254
|
+
candidates: array(KnowledgeCandidateSchema)
|
|
5255
|
+
});
|
|
5256
|
+
const CandidatePromotionResponseSchema = object({
|
|
5257
|
+
candidate: KnowledgeCandidateSchema
|
|
5258
|
+
});
|
|
5259
|
+
const CandidatePromotionFailureResponseSchema = object({
|
|
5260
|
+
error: string().optional(),
|
|
5261
|
+
candidate: KnowledgeCandidateSchema.optional()
|
|
5262
|
+
});
|
|
5263
|
+
const CandidateUpdateResponseSchema = object({
|
|
5264
|
+
candidate: KnowledgeCandidateSchema
|
|
5265
|
+
});
|
|
5266
|
+
const CANDIDATE_STATUS_CLASSES = {
|
|
5267
|
+
draft: "border-amber-500/30 bg-amber-500/10 text-amber-500",
|
|
5268
|
+
promoted: "border-emerald-500/30 bg-emerald-500/10 text-emerald-500",
|
|
5269
|
+
failed: "border-destructive/30 bg-destructive/10 text-destructive"
|
|
5270
|
+
};
|
|
5271
|
+
function formatElapsed$1(ms) {
|
|
5272
|
+
if (ms === null) return "-";
|
|
5273
|
+
if (ms < 1e3) return `${String(ms)}ms`;
|
|
5274
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
5275
|
+
}
|
|
5276
|
+
function formatTimeRange$1(startedAt, endedAt, timeDisplayFormat) {
|
|
5277
|
+
if (startedAt === null || endedAt === null) return null;
|
|
5278
|
+
return formatTimestampRange(startedAt, endedAt, timeDisplayFormat);
|
|
5279
|
+
}
|
|
5280
|
+
function formatCandidateCount(count) {
|
|
5281
|
+
return `${String(count)} candidate${count === 1 ? "" : "s"}`;
|
|
5282
|
+
}
|
|
5283
|
+
function getLogAnchor(logId) {
|
|
5284
|
+
return `log-${String(logId)}`;
|
|
5285
|
+
}
|
|
5286
|
+
function jumpToLog(logId) {
|
|
5287
|
+
const anchor = getLogAnchor(logId);
|
|
5288
|
+
const target = document.getElementById(anchor);
|
|
5289
|
+
window.history.replaceState(null, "", `#${anchor}`);
|
|
5290
|
+
if (!(target instanceof HTMLElement)) return;
|
|
5291
|
+
target.scrollIntoView({ block: "center", behavior: "smooth" });
|
|
5292
|
+
target.focus({ preventScroll: true });
|
|
5293
|
+
}
|
|
5294
|
+
function firstFailureLog(logs) {
|
|
5651
5295
|
for (const log of logs) {
|
|
5652
|
-
if (log.
|
|
5653
|
-
if (log.outputTokens !== null) totalOutput += log.outputTokens;
|
|
5296
|
+
if (log.responseStatus !== null && log.responseStatus >= 400) return log;
|
|
5654
5297
|
}
|
|
5655
|
-
return
|
|
5298
|
+
return null;
|
|
5656
5299
|
}
|
|
5657
|
-
function
|
|
5658
|
-
|
|
5300
|
+
function slowestLog(logs) {
|
|
5301
|
+
let current = null;
|
|
5302
|
+
let currentElapsed = -1;
|
|
5659
5303
|
for (const log of logs) {
|
|
5660
|
-
if (log.
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
if (models === void 0) {
|
|
5665
|
-
models = /* @__PURE__ */ new Set();
|
|
5666
|
-
buckets.set(provider, models);
|
|
5304
|
+
if (log.elapsedMs === null) continue;
|
|
5305
|
+
if (log.elapsedMs > currentElapsed) {
|
|
5306
|
+
current = log;
|
|
5307
|
+
currentElapsed = log.elapsedMs;
|
|
5667
5308
|
}
|
|
5668
|
-
models.add(log.model);
|
|
5669
5309
|
}
|
|
5670
|
-
return
|
|
5671
|
-
provider,
|
|
5672
|
-
models: [...models]
|
|
5673
|
-
}));
|
|
5310
|
+
return current;
|
|
5674
5311
|
}
|
|
5675
|
-
function
|
|
5312
|
+
function firstToolLog(logs) {
|
|
5676
5313
|
for (const log of logs) {
|
|
5677
|
-
|
|
5678
|
-
if (pid !== null && pid !== void 0) return pid;
|
|
5314
|
+
if (extractToolTraceEvents(log).length > 0) return log;
|
|
5679
5315
|
}
|
|
5680
5316
|
return null;
|
|
5681
5317
|
}
|
|
5682
|
-
function
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5318
|
+
function buildDisplayNumberByLogId$1(logs) {
|
|
5319
|
+
const result = /* @__PURE__ */ new Map();
|
|
5320
|
+
for (let index = 0; index < logs.length; index += 1) {
|
|
5321
|
+
const log = logs[index];
|
|
5322
|
+
if (log === void 0) continue;
|
|
5323
|
+
result.set(log.id, index + 1);
|
|
5324
|
+
}
|
|
5325
|
+
return result;
|
|
5326
|
+
}
|
|
5327
|
+
function displayLogNumber(logId, displayNumberByLogId) {
|
|
5328
|
+
return String(displayNumberByLogId.get(logId) ?? logId);
|
|
5329
|
+
}
|
|
5330
|
+
function buildTraceInsights(input) {
|
|
5331
|
+
const insights = [
|
|
5332
|
+
{
|
|
5333
|
+
kind: "session",
|
|
5334
|
+
title: `${String(input.summary.llmCallCount)} LLM call${input.summary.llmCallCount === 1 ? "" : "s"}`,
|
|
5335
|
+
detail: `Scope ${input.scopeId}`,
|
|
5336
|
+
logId: input.logs[0]?.id ?? null
|
|
5687
5337
|
}
|
|
5338
|
+
];
|
|
5339
|
+
const toolLog = firstToolLog(input.logs);
|
|
5340
|
+
if (input.summary.toolCallCount > 0 && toolLog !== null) {
|
|
5341
|
+
insights.push({
|
|
5342
|
+
kind: "tool",
|
|
5343
|
+
title: `${String(input.summary.toolCallCount)} tool call${input.summary.toolCallCount === 1 ? "" : "s"}`,
|
|
5344
|
+
detail: `First tool evidence at #${displayLogNumber(toolLog.id, input.displayNumberByLogId)}`,
|
|
5345
|
+
logId: toolLog.id
|
|
5346
|
+
});
|
|
5688
5347
|
}
|
|
5689
|
-
|
|
5348
|
+
const failure = firstFailureLog(input.logs);
|
|
5349
|
+
if (failure !== null) {
|
|
5350
|
+
insights.push({
|
|
5351
|
+
kind: "failure",
|
|
5352
|
+
title: `Failure #${String(failure.responseStatus)}`,
|
|
5353
|
+
detail: `First failed request is #${displayLogNumber(failure.id, input.displayNumberByLogId)}`,
|
|
5354
|
+
logId: failure.id
|
|
5355
|
+
});
|
|
5356
|
+
}
|
|
5357
|
+
const slowest = slowestLog(input.logs);
|
|
5358
|
+
if (slowest !== null && input.summary.maxElapsedMs !== null) {
|
|
5359
|
+
insights.push({
|
|
5360
|
+
kind: "slow",
|
|
5361
|
+
title: `Slowest ${formatElapsed$1(input.summary.maxElapsedMs)}`,
|
|
5362
|
+
detail: `Max latency observed at #${displayLogNumber(slowest.id, input.displayNumberByLogId)}`,
|
|
5363
|
+
logId: slowest.id
|
|
5364
|
+
});
|
|
5365
|
+
}
|
|
5366
|
+
if (input.candidates.length > 0) {
|
|
5367
|
+
const draftCount = input.candidates.filter((candidate) => candidate.status === "draft").length;
|
|
5368
|
+
const promotedCount = input.candidates.filter(
|
|
5369
|
+
(candidate) => candidate.status === "promoted"
|
|
5370
|
+
).length;
|
|
5371
|
+
insights.push({
|
|
5372
|
+
kind: "candidate",
|
|
5373
|
+
title: `${String(input.candidates.length)} memory candidate${input.candidates.length === 1 ? "" : "s"}`,
|
|
5374
|
+
detail: `${String(draftCount)} draft / ${String(promotedCount)} promoted`,
|
|
5375
|
+
logId: input.candidates[0]?.logIds[0] ?? null
|
|
5376
|
+
});
|
|
5377
|
+
}
|
|
5378
|
+
return insights;
|
|
5690
5379
|
}
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5380
|
+
function insightIcon(kind) {
|
|
5381
|
+
switch (kind) {
|
|
5382
|
+
case "session":
|
|
5383
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3.5 text-blue-400" });
|
|
5384
|
+
case "tool":
|
|
5385
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3.5 text-sky-400/70" });
|
|
5386
|
+
case "slow":
|
|
5387
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3.5 text-amber-400" });
|
|
5388
|
+
case "failure":
|
|
5389
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleX, { className: "size-3.5 text-destructive" });
|
|
5390
|
+
case "candidate":
|
|
5391
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Brain, { className: "size-3.5 text-emerald-400" });
|
|
5392
|
+
}
|
|
5393
|
+
}
|
|
5394
|
+
function TraceInsights({ insights }) {
|
|
5395
|
+
if (insights.length === 0) return null;
|
|
5396
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 grid gap-1.5 border-t border-border/70 pt-2 md:grid-cols-2 xl:grid-cols-3", children: insights.map((insight) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5397
|
+
"button",
|
|
5398
|
+
{
|
|
5399
|
+
type: "button",
|
|
5400
|
+
className: cn(
|
|
5401
|
+
"flex min-w-0 items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs",
|
|
5402
|
+
"text-muted-foreground transition-colors hover:bg-muted/40 hover:text-foreground",
|
|
5403
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
5404
|
+
),
|
|
5405
|
+
onClick: () => {
|
|
5406
|
+
if (insight.logId !== null) jumpToLog(insight.logId);
|
|
5407
|
+
},
|
|
5408
|
+
disabled: insight.logId === null,
|
|
5409
|
+
children: [
|
|
5410
|
+
insightIcon(insight.kind),
|
|
5411
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "min-w-0", children: [
|
|
5412
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block truncate font-medium text-foreground/90", children: insight.title }),
|
|
5413
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block truncate font-mono text-[10px]", children: insight.detail })
|
|
5414
|
+
] })
|
|
5415
|
+
]
|
|
5717
5416
|
},
|
|
5718
|
-
|
|
5719
|
-
);
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
return
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5417
|
+
`${insight.kind}-${insight.title}`
|
|
5418
|
+
)) });
|
|
5419
|
+
}
|
|
5420
|
+
function candidateStatusLabel(status) {
|
|
5421
|
+
switch (status) {
|
|
5422
|
+
case "draft":
|
|
5423
|
+
return "Draft";
|
|
5424
|
+
case "promoted":
|
|
5425
|
+
return "Promoted";
|
|
5426
|
+
case "failed":
|
|
5427
|
+
return "Failed";
|
|
5428
|
+
}
|
|
5429
|
+
}
|
|
5430
|
+
function candidatePromoteLabel(candidate, promoting) {
|
|
5431
|
+
if (promoting) return "Promoting";
|
|
5432
|
+
switch (candidate.status) {
|
|
5433
|
+
case "draft":
|
|
5434
|
+
return "Promote";
|
|
5435
|
+
case "failed":
|
|
5436
|
+
return "Retry";
|
|
5437
|
+
case "promoted":
|
|
5438
|
+
return "Promoted";
|
|
5439
|
+
}
|
|
5440
|
+
}
|
|
5441
|
+
function redactionLabel(candidate) {
|
|
5442
|
+
if (!candidate.redaction.redacted) return "No sensitive pattern matched";
|
|
5443
|
+
return `Redacted ${candidate.redaction.patterns.join(", ")}`;
|
|
5444
|
+
}
|
|
5445
|
+
function previewText(value, maxLength) {
|
|
5446
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
5447
|
+
if (normalized.length <= maxLength) return normalized;
|
|
5448
|
+
return `${normalized.slice(0, maxLength - 3)}...`;
|
|
5449
|
+
}
|
|
5450
|
+
function logRangeLabel(logIds, displayNumberByLogId) {
|
|
5451
|
+
const first = logIds[0];
|
|
5452
|
+
const last = logIds[logIds.length - 1];
|
|
5453
|
+
if (first === void 0) return "No evidence logs";
|
|
5454
|
+
const firstLabel = displayLogNumber(first, displayNumberByLogId);
|
|
5455
|
+
if (last === void 0 || first === last) return `#${firstLabel}`;
|
|
5456
|
+
return `#${firstLabel}-#${displayLogNumber(last, displayNumberByLogId)}`;
|
|
5457
|
+
}
|
|
5458
|
+
function tagsToText(tags) {
|
|
5459
|
+
return tags.join(", ");
|
|
5460
|
+
}
|
|
5461
|
+
function textToTags(value) {
|
|
5462
|
+
return value.split(",").map((tag) => tag.trim()).filter((tag) => tag.length > 0);
|
|
5463
|
+
}
|
|
5464
|
+
function CandidateItem({
|
|
5465
|
+
candidate,
|
|
5466
|
+
isPromoting,
|
|
5467
|
+
isUpdating,
|
|
5468
|
+
onPromoteCandidate,
|
|
5469
|
+
onUpdateCandidate,
|
|
5470
|
+
displayNumberByLogId
|
|
5471
|
+
}) {
|
|
5472
|
+
const [editing, setEditing] = reactExports.useState(false);
|
|
5473
|
+
const [draftType, setDraftType] = reactExports.useState(candidate.type);
|
|
5474
|
+
const [draftTitle, setDraftTitle] = reactExports.useState(candidate.title);
|
|
5475
|
+
const [draftContent, setDraftContent] = reactExports.useState(candidate.content);
|
|
5476
|
+
const [draftTags, setDraftTags] = reactExports.useState(tagsToText(candidate.tags));
|
|
5477
|
+
const [localError, setLocalError] = reactExports.useState(null);
|
|
5478
|
+
const canPromote = candidate.status !== "promoted";
|
|
5479
|
+
const canEdit = candidate.status !== "promoted";
|
|
5480
|
+
const resetDraft = reactExports.useCallback(() => {
|
|
5481
|
+
setDraftType(candidate.type);
|
|
5482
|
+
setDraftTitle(candidate.title);
|
|
5483
|
+
setDraftContent(candidate.content);
|
|
5484
|
+
setDraftTags(tagsToText(candidate.tags));
|
|
5485
|
+
setLocalError(null);
|
|
5486
|
+
}, [candidate.content, candidate.tags, candidate.title, candidate.type]);
|
|
5487
|
+
const saveDraft = reactExports.useCallback(async () => {
|
|
5488
|
+
const title = draftTitle.trim();
|
|
5489
|
+
const content = draftContent.trim();
|
|
5490
|
+
const tags = textToTags(draftTags);
|
|
5491
|
+
if (title.length === 0) {
|
|
5492
|
+
setLocalError("Title is required.");
|
|
5493
|
+
return;
|
|
5494
|
+
}
|
|
5495
|
+
if (content.length === 0) {
|
|
5496
|
+
setLocalError("Content is required.");
|
|
5497
|
+
return;
|
|
5498
|
+
}
|
|
5499
|
+
if (tags.length === 0) {
|
|
5500
|
+
setLocalError("At least one tag is required.");
|
|
5501
|
+
return;
|
|
5502
|
+
}
|
|
5503
|
+
setLocalError(null);
|
|
5504
|
+
const saved = await onUpdateCandidate(candidate.id, {
|
|
5505
|
+
type: draftType,
|
|
5506
|
+
title,
|
|
5507
|
+
content,
|
|
5508
|
+
tags
|
|
5509
|
+
});
|
|
5510
|
+
if (saved) setEditing(false);
|
|
5511
|
+
}, [candidate.id, draftContent, draftTags, draftTitle, draftType, onUpdateCandidate]);
|
|
5512
|
+
if (editing) {
|
|
5513
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border border-border bg-card shadow-sm rounded-[8px] px-2.5 py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid gap-2", children: [
|
|
5514
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5515
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5516
|
+
"select",
|
|
5517
|
+
{
|
|
5518
|
+
value: draftType,
|
|
5519
|
+
disabled: isUpdating,
|
|
5520
|
+
onChange: (event) => {
|
|
5521
|
+
const parsed = KnowledgeCandidateSchema.shape.type.safeParse(
|
|
5522
|
+
event.currentTarget.value
|
|
5523
|
+
);
|
|
5524
|
+
if (parsed.success) setDraftType(parsed.data);
|
|
5525
|
+
},
|
|
5526
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 rounded-md px-2 text-xs",
|
|
5527
|
+
"aria-label": "Candidate type",
|
|
5528
|
+
children: [
|
|
5529
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "episode", children: "episode" }),
|
|
5530
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "procedure", children: "procedure" }),
|
|
5531
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "preference", children: "preference" }),
|
|
5532
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "project-fact", children: "project-fact" })
|
|
5533
|
+
]
|
|
5534
|
+
}
|
|
5535
|
+
),
|
|
5536
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5537
|
+
"input",
|
|
5538
|
+
{
|
|
5539
|
+
value: draftTitle,
|
|
5540
|
+
disabled: isUpdating,
|
|
5541
|
+
onChange: (event) => setDraftTitle(event.currentTarget.value),
|
|
5542
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 min-w-[220px] flex-1 rounded-md px-2 text-xs",
|
|
5543
|
+
"aria-label": "Candidate title"
|
|
5544
|
+
}
|
|
5545
|
+
)
|
|
5546
|
+
] }),
|
|
5768
5547
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5769
|
-
|
|
5548
|
+
"textarea",
|
|
5770
5549
|
{
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5550
|
+
value: draftContent,
|
|
5551
|
+
disabled: isUpdating,
|
|
5552
|
+
onChange: (event) => setDraftContent(event.currentTarget.value),
|
|
5553
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground min-h-28 rounded-md px-2 py-1.5 font-mono text-[11px] leading-relaxed",
|
|
5554
|
+
"aria-label": "Candidate content"
|
|
5776
5555
|
}
|
|
5777
5556
|
),
|
|
5778
5557
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5779
|
-
|
|
5558
|
+
"input",
|
|
5780
5559
|
{
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5560
|
+
value: draftTags,
|
|
5561
|
+
disabled: isUpdating,
|
|
5562
|
+
onChange: (event) => setDraftTags(event.currentTarget.value),
|
|
5563
|
+
className: "border border-input bg-background hover:bg-accent hover:text-accent-foreground h-7 rounded-md px-2 text-xs",
|
|
5564
|
+
"aria-label": "Candidate tags"
|
|
5565
|
+
}
|
|
5566
|
+
),
|
|
5567
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
5568
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] text-muted-foreground", children: [
|
|
5569
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ShieldCheck, { className: "size-3" }),
|
|
5570
|
+
"Saving reruns Inspector redaction before promotion."
|
|
5571
|
+
] }),
|
|
5572
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
|
|
5573
|
+
localError !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-destructive", children: localError }),
|
|
5574
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5575
|
+
Button,
|
|
5576
|
+
{
|
|
5577
|
+
type: "button",
|
|
5578
|
+
variant: "ghost",
|
|
5579
|
+
size: "sm",
|
|
5580
|
+
className: "h-7 gap-1.5 px-2 text-xs",
|
|
5581
|
+
disabled: isUpdating,
|
|
5582
|
+
onClick: () => {
|
|
5583
|
+
resetDraft();
|
|
5584
|
+
setEditing(false);
|
|
5585
|
+
},
|
|
5586
|
+
children: [
|
|
5587
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "size-3.5" }),
|
|
5588
|
+
"Cancel"
|
|
5589
|
+
]
|
|
5590
|
+
}
|
|
5591
|
+
),
|
|
5592
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5593
|
+
Button,
|
|
5594
|
+
{
|
|
5595
|
+
type: "button",
|
|
5596
|
+
variant: "outline",
|
|
5597
|
+
size: "sm",
|
|
5598
|
+
className: "h-7 gap-1.5 px-2 text-xs",
|
|
5599
|
+
disabled: isUpdating,
|
|
5600
|
+
onClick: () => {
|
|
5601
|
+
void saveDraft();
|
|
5602
|
+
},
|
|
5603
|
+
children: [
|
|
5604
|
+
isUpdating ? /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "size-3.5" }),
|
|
5605
|
+
"Save"
|
|
5606
|
+
]
|
|
5607
|
+
}
|
|
5608
|
+
)
|
|
5609
|
+
] })
|
|
5610
|
+
] }) });
|
|
5611
|
+
}
|
|
5612
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-border/80 bg-background/60 px-2.5 py-2", children: [
|
|
5613
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
5614
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "h-5 px-1.5 text-[10px] font-mono", children: candidate.type }),
|
|
5615
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 flex-1 truncate text-xs font-medium", title: candidate.title, children: candidate.title }),
|
|
5616
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5617
|
+
Badge,
|
|
5618
|
+
{
|
|
5619
|
+
variant: "outline",
|
|
5620
|
+
className: cn(
|
|
5621
|
+
"h-5 shrink-0 px-1.5 text-[10px] font-mono",
|
|
5622
|
+
CANDIDATE_STATUS_CLASSES[candidate.status]
|
|
5623
|
+
),
|
|
5624
|
+
children: candidateStatusLabel(candidate.status)
|
|
5790
5625
|
}
|
|
5791
5626
|
)
|
|
5792
|
-
] })
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
"aria-hidden": "true",
|
|
5806
|
-
className: cn("inline-block size-5", className),
|
|
5807
|
-
children: [
|
|
5808
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z" }),
|
|
5809
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
5810
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
5811
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
5812
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" }),
|
|
5813
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
5814
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
5815
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "6.5", y1: "16", x2: "4.5", y2: "19.5" }),
|
|
5816
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9", y1: "17.5", x2: "8", y2: "20.5" }),
|
|
5817
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "15", y1: "17.5", x2: "16", y2: "20.5" }),
|
|
5818
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17.5", y1: "16", x2: "19.5", y2: "19.5" })
|
|
5819
|
-
]
|
|
5820
|
-
}
|
|
5821
|
-
);
|
|
5822
|
-
}
|
|
5823
|
-
function SvgShell({
|
|
5824
|
-
className,
|
|
5825
|
-
style,
|
|
5826
|
-
d,
|
|
5827
|
-
eyeStalks,
|
|
5828
|
-
eyes,
|
|
5829
|
-
legs,
|
|
5830
|
-
extras
|
|
5831
|
-
}) {
|
|
5832
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5833
|
-
"svg",
|
|
5834
|
-
{
|
|
5835
|
-
viewBox: "0 0 24 24",
|
|
5836
|
-
fill: "none",
|
|
5837
|
-
stroke: "currentColor",
|
|
5838
|
-
strokeWidth: "1.5",
|
|
5839
|
-
strokeLinecap: "round",
|
|
5840
|
-
strokeLinejoin: "round",
|
|
5841
|
-
"aria-hidden": "true",
|
|
5842
|
-
style,
|
|
5843
|
-
className: cn("inline-block size-5", className),
|
|
5844
|
-
children: [
|
|
5845
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d }),
|
|
5846
|
-
eyeStalks,
|
|
5847
|
-
eyes,
|
|
5848
|
-
legs,
|
|
5849
|
-
extras
|
|
5850
|
-
]
|
|
5851
|
-
}
|
|
5852
|
-
);
|
|
5853
|
-
}
|
|
5854
|
-
const StdLegs = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5855
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "6.5", y1: "16", x2: "4.5", y2: "19.5" }),
|
|
5856
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9", y1: "17.5", x2: "8", y2: "20.5" }),
|
|
5857
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "15", y1: "17.5", x2: "16", y2: "20.5" }),
|
|
5858
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17.5", y1: "16", x2: "19.5", y2: "19.5" })
|
|
5859
|
-
] });
|
|
5860
|
-
const ShortLegs = /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5861
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "7", y1: "16", x2: "5.5", y2: "18.5" }),
|
|
5862
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "17", x2: "8.5", y2: "19.5" }),
|
|
5863
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "17", x2: "15.5", y2: "19.5" }),
|
|
5864
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17", y1: "16", x2: "18.5", y2: "18.5" })
|
|
5865
|
-
] });
|
|
5866
|
-
function Crab1({ className }) {
|
|
5867
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5868
|
-
SvgShell,
|
|
5869
|
-
{
|
|
5870
|
-
className,
|
|
5871
|
-
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
5872
|
-
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5873
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
5874
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
5875
|
-
] }),
|
|
5876
|
-
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5877
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
5878
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" })
|
|
5627
|
+
] }),
|
|
5628
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5629
|
+
"p",
|
|
5630
|
+
{
|
|
5631
|
+
className: "mt-1 text-[11px] leading-relaxed text-muted-foreground",
|
|
5632
|
+
title: candidate.content,
|
|
5633
|
+
children: previewText(candidate.content, 360)
|
|
5634
|
+
}
|
|
5635
|
+
),
|
|
5636
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-[10px] text-muted-foreground", children: [
|
|
5637
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
5638
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FileSearch, { className: "size-3" }),
|
|
5639
|
+
logRangeLabel(candidate.logIds, displayNumberByLogId)
|
|
5879
5640
|
] }),
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" })
|
|
5884
|
-
] })
|
|
5885
|
-
}
|
|
5886
|
-
);
|
|
5887
|
-
}
|
|
5888
|
-
function Crab2({ className }) {
|
|
5889
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5890
|
-
SvgShell,
|
|
5891
|
-
{
|
|
5892
|
-
className,
|
|
5893
|
-
d: "M4 13 C4 7 7.5 5.5 12 5.5 C16.5 5.5 20 7 20 13 C20 17.5 16.5 19 12 19 C7.5 19 4 17.5 4 13 Z",
|
|
5894
|
-
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5895
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "6.5", x2: "9.5", y2: "4.5" }),
|
|
5896
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "6.5", x2: "14.5", y2: "4.5" })
|
|
5641
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1", children: [
|
|
5642
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ShieldCheck, { className: "size-3" }),
|
|
5643
|
+
redactionLabel(candidate)
|
|
5897
5644
|
] }),
|
|
5898
|
-
|
|
5899
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5900
|
-
|
|
5645
|
+
candidate.status === "promoted" && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 text-emerald-500", children: [
|
|
5646
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "size-3" }),
|
|
5647
|
+
candidate.openClawMemoryId ?? "OpenClaw"
|
|
5901
5648
|
] }),
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20 9.5 21.5 10 21 12 C20.5 13.5 19.5 13 19 12" })
|
|
5649
|
+
candidate.status === "failed" && candidate.error !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1 text-destructive", children: [
|
|
5650
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleX, { className: "size-3" }),
|
|
5651
|
+
candidate.error
|
|
5906
5652
|
] })
|
|
5907
|
-
}
|
|
5908
|
-
|
|
5653
|
+
] }),
|
|
5654
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-1.5", children: [
|
|
5655
|
+
candidate.logIds.map((logId) => {
|
|
5656
|
+
const displayNumber = displayLogNumber(logId, displayNumberByLogId);
|
|
5657
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5658
|
+
"a",
|
|
5659
|
+
{
|
|
5660
|
+
href: `#${getLogAnchor(logId)}`,
|
|
5661
|
+
onClick: (event) => {
|
|
5662
|
+
event.preventDefault();
|
|
5663
|
+
jumpToLog(logId);
|
|
5664
|
+
},
|
|
5665
|
+
className: "rounded border border-blue-400/25 px-1.5 py-0.5 font-mono text-[10px] text-blue-400 underline-offset-2 transition-colors hover:bg-blue-400/10 hover:text-blue-300 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
5666
|
+
"aria-label": `Jump to evidence log ${displayNumber}`,
|
|
5667
|
+
title: `Log ID ${String(logId)}`,
|
|
5668
|
+
children: [
|
|
5669
|
+
"#",
|
|
5670
|
+
displayNumber
|
|
5671
|
+
]
|
|
5672
|
+
},
|
|
5673
|
+
logId
|
|
5674
|
+
);
|
|
5675
|
+
}),
|
|
5676
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
|
|
5677
|
+
canEdit && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5678
|
+
Button,
|
|
5679
|
+
{
|
|
5680
|
+
type: "button",
|
|
5681
|
+
variant: "ghost",
|
|
5682
|
+
size: "sm",
|
|
5683
|
+
className: "h-6 gap-1.5 px-2 text-[10px]",
|
|
5684
|
+
disabled: isUpdating || isPromoting,
|
|
5685
|
+
onClick: () => setEditing(true),
|
|
5686
|
+
children: [
|
|
5687
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "size-3" }),
|
|
5688
|
+
"Review"
|
|
5689
|
+
]
|
|
5690
|
+
}
|
|
5691
|
+
),
|
|
5692
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5693
|
+
Button,
|
|
5694
|
+
{
|
|
5695
|
+
type: "button",
|
|
5696
|
+
variant: canPromote ? "outline" : "ghost",
|
|
5697
|
+
size: "sm",
|
|
5698
|
+
className: "h-6 gap-1.5 px-2 text-[10px]",
|
|
5699
|
+
onClick: () => onPromoteCandidate(candidate.id),
|
|
5700
|
+
disabled: !canPromote || isPromoting || isUpdating,
|
|
5701
|
+
children: [
|
|
5702
|
+
isPromoting ? /* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "size-3 animate-spin" }) : canPromote ? /* @__PURE__ */ jsxRuntimeExports.jsx(CloudUpload, { className: "size-3" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(CircleCheck, { className: "size-3" }),
|
|
5703
|
+
candidatePromoteLabel(candidate, isPromoting)
|
|
5704
|
+
]
|
|
5705
|
+
}
|
|
5706
|
+
)
|
|
5707
|
+
] })
|
|
5708
|
+
] });
|
|
5909
5709
|
}
|
|
5910
|
-
function
|
|
5911
|
-
|
|
5912
|
-
|
|
5710
|
+
function CandidateList({
|
|
5711
|
+
candidates,
|
|
5712
|
+
promotingCandidateIds,
|
|
5713
|
+
updatingCandidateIds,
|
|
5714
|
+
onPromoteCandidate,
|
|
5715
|
+
onUpdateCandidate,
|
|
5716
|
+
displayNumberByLogId
|
|
5717
|
+
}) {
|
|
5718
|
+
if (candidates.length === 0) return null;
|
|
5719
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 grid gap-1.5", children: candidates.map((candidate) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5720
|
+
CandidateItem,
|
|
5913
5721
|
{
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5722
|
+
candidate,
|
|
5723
|
+
isPromoting: promotingCandidateIds.has(candidate.id),
|
|
5724
|
+
isUpdating: updatingCandidateIds.has(candidate.id),
|
|
5725
|
+
onPromoteCandidate,
|
|
5726
|
+
onUpdateCandidate,
|
|
5727
|
+
displayNumberByLogId
|
|
5728
|
+
},
|
|
5729
|
+
candidate.id
|
|
5730
|
+
)) });
|
|
5731
|
+
}
|
|
5732
|
+
function AgentTraceSummary({
|
|
5733
|
+
logs,
|
|
5734
|
+
scopeId,
|
|
5735
|
+
slowResponseThresholdSeconds,
|
|
5736
|
+
showRollupMetrics,
|
|
5737
|
+
timeDisplayFormat
|
|
5738
|
+
}) {
|
|
5739
|
+
const [candidates, setCandidates] = reactExports.useState([]);
|
|
5740
|
+
const [candidatesExpanded, setCandidatesExpanded] = reactExports.useState(true);
|
|
5741
|
+
const [candidateState, setCandidateState] = reactExports.useState({
|
|
5742
|
+
status: "idle",
|
|
5743
|
+
error: null
|
|
5744
|
+
});
|
|
5745
|
+
const [promotingCandidateIds, setPromotingCandidateIds] = reactExports.useState(
|
|
5746
|
+
() => /* @__PURE__ */ new Set()
|
|
5747
|
+
);
|
|
5748
|
+
const [updatingCandidateIds, setUpdatingCandidateIds] = reactExports.useState(
|
|
5749
|
+
() => /* @__PURE__ */ new Set()
|
|
5750
|
+
);
|
|
5751
|
+
const hasCandidates = candidates.length > 0;
|
|
5752
|
+
const summary = reactExports.useMemo(
|
|
5753
|
+
() => buildTraceSummary(logs, slowResponseThresholdSeconds, candidates.length),
|
|
5754
|
+
[candidates.length, logs, slowResponseThresholdSeconds]
|
|
5755
|
+
);
|
|
5756
|
+
const displayNumberByLogId = reactExports.useMemo(() => buildDisplayNumberByLogId$1(logs), [logs]);
|
|
5757
|
+
const traceInsights = reactExports.useMemo(
|
|
5758
|
+
() => buildTraceInsights({ logs, scopeId, summary, candidates, displayNumberByLogId }),
|
|
5759
|
+
[candidates, displayNumberByLogId, logs, scopeId, summary]
|
|
5760
|
+
);
|
|
5761
|
+
const showElapsedSummary = showRollupMetrics || summary.maxElapsedMs !== null;
|
|
5762
|
+
const timeRange = reactExports.useMemo(
|
|
5763
|
+
() => formatTimeRange$1(summary.startedAt, summary.endedAt, timeDisplayFormat),
|
|
5764
|
+
[summary.endedAt, summary.startedAt, timeDisplayFormat]
|
|
5765
|
+
);
|
|
5766
|
+
const createCandidates = reactExports.useCallback(() => {
|
|
5767
|
+
if (logs.length === 0 || candidateState.status === "loading") return;
|
|
5768
|
+
setCandidateState({ status: "loading", error: null });
|
|
5769
|
+
void (async () => {
|
|
5770
|
+
try {
|
|
5771
|
+
const response = await fetch(
|
|
5772
|
+
`/api/knowledge/sessions/${encodeURIComponent(scopeId)}/candidates`,
|
|
5773
|
+
{ method: "POST" }
|
|
5774
|
+
);
|
|
5775
|
+
if (!response.ok) {
|
|
5776
|
+
const message = await readApiError(
|
|
5777
|
+
response,
|
|
5778
|
+
`Candidate generation failed with ${String(response.status)}`
|
|
5779
|
+
);
|
|
5780
|
+
setCandidateState({ status: "failed", error: message });
|
|
5781
|
+
return;
|
|
5782
|
+
}
|
|
5783
|
+
const parsed = await parseJsonResponse$1(response, CandidateResponseSchema);
|
|
5784
|
+
setCandidates(parsed.candidates);
|
|
5785
|
+
setCandidatesExpanded(parsed.candidates.length > 0);
|
|
5786
|
+
setCandidateState(
|
|
5787
|
+
parsed.candidates.length > 0 ? { status: "ready", error: null } : { status: "failed", error: "No candidate was generated for this trace scope." }
|
|
5788
|
+
);
|
|
5789
|
+
} catch (error) {
|
|
5790
|
+
setCandidateState({
|
|
5791
|
+
status: "failed",
|
|
5792
|
+
error: error instanceof Error ? error.message : "Candidate response was invalid"
|
|
5793
|
+
});
|
|
5794
|
+
}
|
|
5795
|
+
})();
|
|
5796
|
+
}, [candidateState.status, logs.length, scopeId]);
|
|
5797
|
+
const promoteCandidate = reactExports.useCallback((candidateId) => {
|
|
5798
|
+
setPromotingCandidateIds((current) => {
|
|
5799
|
+
if (current.has(candidateId)) return current;
|
|
5800
|
+
const next = new Set(current);
|
|
5801
|
+
next.add(candidateId);
|
|
5802
|
+
return next;
|
|
5803
|
+
});
|
|
5804
|
+
void (async () => {
|
|
5805
|
+
try {
|
|
5806
|
+
const response = await fetch(
|
|
5807
|
+
`/api/knowledge/candidates/${encodeURIComponent(candidateId)}/promote`,
|
|
5808
|
+
{ method: "POST" }
|
|
5809
|
+
);
|
|
5810
|
+
const raw = await response.json().catch(() => null);
|
|
5811
|
+
const parsed = CandidatePromotionResponseSchema.safeParse(raw);
|
|
5812
|
+
if (response.ok && parsed.success) {
|
|
5813
|
+
setCandidates(
|
|
5814
|
+
(current) => current.map(
|
|
5815
|
+
(candidate) => candidate.id === parsed.data.candidate.id ? parsed.data.candidate : candidate
|
|
5816
|
+
)
|
|
5817
|
+
);
|
|
5818
|
+
setCandidateState({ status: "ready", error: null });
|
|
5819
|
+
return;
|
|
5820
|
+
}
|
|
5821
|
+
const failure = CandidatePromotionFailureResponseSchema.safeParse(raw);
|
|
5822
|
+
if (failure.success && failure.data.candidate !== void 0) {
|
|
5823
|
+
setCandidates(
|
|
5824
|
+
(current) => current.map(
|
|
5825
|
+
(candidate) => candidate.id === failure.data.candidate?.id ? failure.data.candidate : candidate
|
|
5826
|
+
)
|
|
5827
|
+
);
|
|
5828
|
+
}
|
|
5829
|
+
setCandidateState({
|
|
5830
|
+
status: "failed",
|
|
5831
|
+
error: failure.success ? failure.data.error ?? "Candidate promotion failed" : `Candidate promotion failed with ${String(response.status)}`
|
|
5832
|
+
});
|
|
5833
|
+
} catch (error) {
|
|
5834
|
+
setCandidateState({
|
|
5835
|
+
status: "failed",
|
|
5836
|
+
error: error instanceof Error ? error.message : "Candidate promotion failed"
|
|
5837
|
+
});
|
|
5838
|
+
} finally {
|
|
5839
|
+
setPromotingCandidateIds((current) => {
|
|
5840
|
+
const next = new Set(current);
|
|
5841
|
+
next.delete(candidateId);
|
|
5842
|
+
return next;
|
|
5843
|
+
});
|
|
5844
|
+
}
|
|
5845
|
+
})();
|
|
5846
|
+
}, []);
|
|
5847
|
+
const updateCandidate = reactExports.useCallback(
|
|
5848
|
+
async (candidateId, update) => {
|
|
5849
|
+
setUpdatingCandidateIds((current) => {
|
|
5850
|
+
if (current.has(candidateId)) return current;
|
|
5851
|
+
const next = new Set(current);
|
|
5852
|
+
next.add(candidateId);
|
|
5853
|
+
return next;
|
|
5854
|
+
});
|
|
5855
|
+
try {
|
|
5856
|
+
const response = await fetch(
|
|
5857
|
+
`/api/knowledge/candidates/${encodeURIComponent(candidateId)}`,
|
|
5858
|
+
{
|
|
5859
|
+
method: "PATCH",
|
|
5860
|
+
headers: { "Content-Type": "application/json" },
|
|
5861
|
+
body: JSON.stringify(update)
|
|
5862
|
+
}
|
|
5863
|
+
);
|
|
5864
|
+
if (!response.ok) {
|
|
5865
|
+
const message = await readApiError(
|
|
5866
|
+
response,
|
|
5867
|
+
`Candidate update failed with ${String(response.status)}`
|
|
5868
|
+
);
|
|
5869
|
+
setCandidateState({ status: "failed", error: message });
|
|
5870
|
+
return false;
|
|
5871
|
+
}
|
|
5872
|
+
const parsed = await parseJsonResponse$1(response, CandidateUpdateResponseSchema);
|
|
5873
|
+
setCandidates(
|
|
5874
|
+
(current) => current.map(
|
|
5875
|
+
(candidate) => candidate.id === parsed.candidate.id ? parsed.candidate : candidate
|
|
5876
|
+
)
|
|
5877
|
+
);
|
|
5878
|
+
setCandidateState({ status: "ready", error: null });
|
|
5879
|
+
return true;
|
|
5880
|
+
} catch (error) {
|
|
5881
|
+
setCandidateState({
|
|
5882
|
+
status: "failed",
|
|
5883
|
+
error: error instanceof Error ? error.message : "Candidate update failed"
|
|
5884
|
+
});
|
|
5885
|
+
return false;
|
|
5886
|
+
} finally {
|
|
5887
|
+
setUpdatingCandidateIds((current) => {
|
|
5888
|
+
const next = new Set(current);
|
|
5889
|
+
next.delete(candidateId);
|
|
5890
|
+
return next;
|
|
5891
|
+
});
|
|
5892
|
+
}
|
|
5893
|
+
},
|
|
5894
|
+
[]
|
|
5930
5895
|
);
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5939
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "6.5", x2: "10", y2: "3.5" }),
|
|
5940
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "6.5", x2: "14", y2: "3.5" })
|
|
5941
|
-
] }),
|
|
5942
|
-
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5943
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "10", cy: "3", r: "0.7", fill: "currentColor", stroke: "none" }),
|
|
5944
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14", cy: "3", r: "0.7", fill: "currentColor", stroke: "none" })
|
|
5896
|
+
if (logs.length === 0) return null;
|
|
5897
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border border-border bg-card shadow-sm mb-2 rounded-[8px] px-3 py-2", children: [
|
|
5898
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-x-3 gap-y-2 text-xs", children: [
|
|
5899
|
+
showRollupMetrics && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 font-semibold text-foreground", children: [
|
|
5900
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-3.5 text-blue-400" }),
|
|
5901
|
+
summary.llmCallCount,
|
|
5902
|
+
" LLM"
|
|
5945
5903
|
] }),
|
|
5946
|
-
|
|
5947
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17", y1: "17", x2: "19", y2: "20.5" })
|
|
5904
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
|
|
5905
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Wrench, { className: "size-3.5 text-sky-400/70" }),
|
|
5906
|
+
summary.toolCallCount,
|
|
5907
|
+
" tools"
|
|
5951
5908
|
] }),
|
|
5952
|
-
|
|
5953
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5954
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
}
|
|
5959
|
-
function Crab5({ className }) {
|
|
5960
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5961
|
-
SvgShell,
|
|
5962
|
-
{
|
|
5963
|
-
className,
|
|
5964
|
-
d: "M5 13 C5 9 8 7 12 7 L13 4 L14 7 C16 7 19 9 19 13 C19 16 16 18 13 18 L12 21 L11 18 C8 18 5 16 5 13 Z",
|
|
5965
|
-
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5966
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
5967
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
5909
|
+
showRollupMetrics && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
|
|
5910
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3.5 text-emerald-400" }),
|
|
5911
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
|
|
5912
|
+
formatTokens(summary.totalInputTokens),
|
|
5913
|
+
" / ",
|
|
5914
|
+
formatTokens(summary.totalOutputTokens)
|
|
5915
|
+
] })
|
|
5968
5916
|
] }),
|
|
5969
|
-
|
|
5970
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5971
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
5917
|
+
(summary.totalCacheCreationInputTokens > 0 || summary.totalCacheReadInputTokens > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
|
|
5918
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3.5 text-purple-400" }),
|
|
5919
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
|
|
5920
|
+
"KV Cache +",
|
|
5921
|
+
formatTokens(summary.totalCacheCreationInputTokens),
|
|
5922
|
+
" / ~",
|
|
5923
|
+
formatTokens(summary.totalCacheReadInputTokens)
|
|
5924
|
+
] })
|
|
5972
5925
|
] }),
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("
|
|
5976
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
}
|
|
5981
|
-
function Crab6({ className }) {
|
|
5982
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5983
|
-
SvgShell,
|
|
5984
|
-
{
|
|
5985
|
-
className,
|
|
5986
|
-
d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z",
|
|
5987
|
-
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
5988
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
5989
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
5926
|
+
showElapsedSummary && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-muted-foreground", children: [
|
|
5927
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3.5" }),
|
|
5928
|
+
showRollupMetrics && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatElapsed$1(summary.totalElapsedMs) }),
|
|
5929
|
+
summary.maxElapsedMs !== null && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-muted-foreground/70", children: [
|
|
5930
|
+
"max ",
|
|
5931
|
+
formatElapsed$1(summary.maxElapsedMs)
|
|
5932
|
+
] })
|
|
5990
5933
|
] }),
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5934
|
+
showRollupMetrics && timeRange !== null && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-muted-foreground/70", children: timeRange }),
|
|
5935
|
+
(summary.failedCallCount > 0 || summary.pendingCallCount > 0 || summary.slowCallCount > 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "inline-flex items-center gap-1.5 text-amber-400", children: [
|
|
5936
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TriangleAlert, { className: "size-3.5" }),
|
|
5937
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono", children: [
|
|
5938
|
+
summary.failedCallCount,
|
|
5939
|
+
" fail / ",
|
|
5940
|
+
summary.pendingCallCount,
|
|
5941
|
+
" pending /",
|
|
5942
|
+
" ",
|
|
5943
|
+
summary.slowCallCount,
|
|
5944
|
+
" slow"
|
|
5945
|
+
] })
|
|
5994
5946
|
] }),
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
5947
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1" }),
|
|
5948
|
+
hasCandidates && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "h-6 px-2 text-[10px] font-mono", children: formatCandidateCount(summary.knowledgeCandidateCount) }),
|
|
5949
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
5950
|
+
Button,
|
|
5951
|
+
{
|
|
5952
|
+
type: "button",
|
|
5953
|
+
variant: "outline",
|
|
5954
|
+
size: "sm",
|
|
5955
|
+
className: "h-7 gap-1.5 px-2 text-xs",
|
|
5956
|
+
onClick: createCandidates,
|
|
5957
|
+
disabled: candidateState.status === "loading",
|
|
5958
|
+
children: [
|
|
5959
|
+
candidateState.status === "loading" ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Brain, { className: "size-3.5" }),
|
|
5960
|
+
"Candidate"
|
|
5961
|
+
]
|
|
5962
|
+
}
|
|
5963
|
+
),
|
|
5964
|
+
hasCandidates && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5965
|
+
Button,
|
|
5966
|
+
{
|
|
5967
|
+
type: "button",
|
|
5968
|
+
variant: "ghost",
|
|
5969
|
+
size: "icon",
|
|
5970
|
+
className: "size-7 text-muted-foreground",
|
|
5971
|
+
onClick: () => setCandidatesExpanded((value) => !value),
|
|
5972
|
+
"aria-expanded": candidatesExpanded,
|
|
5973
|
+
"aria-label": candidatesExpanded ? "Collapse memory candidates" : "Expand memory candidates",
|
|
5974
|
+
children: candidatesExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3.5" })
|
|
5975
|
+
}
|
|
5976
|
+
)
|
|
5977
|
+
] }),
|
|
5978
|
+
candidateState.status === "failed" && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-xs text-destructive", children: candidateState.error }),
|
|
5979
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TraceInsights, { insights: traceInsights }),
|
|
5980
|
+
candidatesExpanded && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
5981
|
+
CandidateList,
|
|
5982
|
+
{
|
|
5983
|
+
candidates,
|
|
5984
|
+
promotingCandidateIds,
|
|
5985
|
+
updatingCandidateIds,
|
|
5986
|
+
onPromoteCandidate: promoteCandidate,
|
|
5987
|
+
onUpdateCandidate: updateCandidate,
|
|
5988
|
+
displayNumberByLogId
|
|
5989
|
+
}
|
|
5990
|
+
)
|
|
5991
|
+
] });
|
|
6002
5992
|
}
|
|
6003
|
-
function
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "8", x2: "14", y2: "6" })
|
|
6012
|
-
] }),
|
|
6013
|
-
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6014
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9", y1: "6", x2: "11", y2: "6.5" }),
|
|
6015
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "13", y1: "6", x2: "15", y2: "6.5" })
|
|
6016
|
-
] }),
|
|
6017
|
-
legs: ShortLegs,
|
|
6018
|
-
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6019
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6 11.5 C4.5 10.5 3 11 3.5 12.5 C4 13.5 5 13 5.5 12.5" }),
|
|
6020
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M18 11.5 C19.5 10.5 21 11 20.5 12.5 C20 13.5 19 13 18.5 12.5" })
|
|
6021
|
-
] })
|
|
6022
|
-
}
|
|
6023
|
-
);
|
|
5993
|
+
function computeStats(logs) {
|
|
5994
|
+
let totalInput = 0;
|
|
5995
|
+
let totalOutput = 0;
|
|
5996
|
+
for (const log of logs) {
|
|
5997
|
+
if (log.inputTokens !== null) totalInput += log.inputTokens;
|
|
5998
|
+
if (log.outputTokens !== null) totalOutput += log.outputTokens;
|
|
5999
|
+
}
|
|
6000
|
+
return { totalInputTokens: totalInput, totalOutputTokens: totalOutput };
|
|
6024
6001
|
}
|
|
6025
|
-
function
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6036
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.7", fill: "currentColor", stroke: "none" }),
|
|
6037
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.7", fill: "currentColor", stroke: "none" })
|
|
6038
|
-
] }),
|
|
6039
|
-
legs: StdLegs,
|
|
6040
|
-
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6041
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
6042
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
6043
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "8.5", y1: "4", x2: "10.5", y2: "4.5" }),
|
|
6044
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "15.5", y1: "4", x2: "13.5", y2: "4.5" }),
|
|
6045
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 15.5 C10 14.5 14 14.5 15 15.5" })
|
|
6046
|
-
] })
|
|
6002
|
+
function collectProviders(logs) {
|
|
6003
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
6004
|
+
for (const log of logs) {
|
|
6005
|
+
if (log.model === null) continue;
|
|
6006
|
+
const provider = detectProvider(log.model);
|
|
6007
|
+
if (provider === "unknown") continue;
|
|
6008
|
+
let models = buckets.get(provider);
|
|
6009
|
+
if (models === void 0) {
|
|
6010
|
+
models = /* @__PURE__ */ new Set();
|
|
6011
|
+
buckets.set(provider, models);
|
|
6047
6012
|
}
|
|
6048
|
-
|
|
6013
|
+
models.add(log.model);
|
|
6014
|
+
}
|
|
6015
|
+
return [...buckets.entries()].map(([provider, models]) => ({
|
|
6016
|
+
provider,
|
|
6017
|
+
models: [...models]
|
|
6018
|
+
}));
|
|
6049
6019
|
}
|
|
6050
|
-
function
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6057
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
6058
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" })
|
|
6059
|
-
] }),
|
|
6060
|
-
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6061
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "1.2", fill: "none", stroke: "currentColor" }),
|
|
6062
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "1.2", fill: "none", stroke: "currentColor" })
|
|
6063
|
-
] }),
|
|
6064
|
-
legs: StdLegs,
|
|
6065
|
-
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6066
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
6067
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
6068
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("ellipse", { cx: "12", cy: "15", rx: "2", ry: "1.5", fill: "currentColor", stroke: "none" })
|
|
6069
|
-
] })
|
|
6070
|
-
}
|
|
6071
|
-
);
|
|
6020
|
+
function getFirstClientPid(logs) {
|
|
6021
|
+
for (const log of logs) {
|
|
6022
|
+
const pid = log.clientPid;
|
|
6023
|
+
if (pid !== null && pid !== void 0) return pid;
|
|
6024
|
+
}
|
|
6025
|
+
return null;
|
|
6072
6026
|
}
|
|
6073
|
-
function
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
{
|
|
6077
|
-
|
|
6078
|
-
d: "M4.5 13 C4.5 8 7.5 6 12 6 C16.5 6 19.5 8 19.5 13 C19.5 17 16.5 18.5 12 18.5 C7.5 18.5 4.5 17 4.5 13 Z",
|
|
6079
|
-
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6080
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9.5", y1: "7", x2: "9", y2: "5" }),
|
|
6081
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14.5", y1: "7", x2: "15", y2: "5" })
|
|
6082
|
-
] }),
|
|
6083
|
-
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6084
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9", cy: "4.5", r: "1", fill: "currentColor", stroke: "none" }),
|
|
6085
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "15", cy: "4.5", r: "1", fill: "currentColor", stroke: "none" })
|
|
6086
|
-
] }),
|
|
6087
|
-
legs: StdLegs,
|
|
6088
|
-
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6089
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9 2 9.5 2.5 12 C3 14 4 13 5 12" }),
|
|
6090
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9 22 9.5 21.5 12 C21 14 20 13 19 12" }),
|
|
6091
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 14.5 C10 16 14 16 15 14.5" }),
|
|
6092
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "7", cy: "13", r: "1", fill: "currentColor", stroke: "none", opacity: "0.3" }),
|
|
6093
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "17", cy: "13", r: "1", fill: "currentColor", stroke: "none", opacity: "0.3" })
|
|
6094
|
-
] })
|
|
6027
|
+
function getFirstClientProjectFolder(logs) {
|
|
6028
|
+
for (const log of logs) {
|
|
6029
|
+
const projectFolder = log.clientProjectFolder;
|
|
6030
|
+
if (projectFolder !== null && projectFolder !== void 0 && projectFolder !== "") {
|
|
6031
|
+
return projectFolder;
|
|
6095
6032
|
}
|
|
6096
|
-
|
|
6033
|
+
}
|
|
6034
|
+
return null;
|
|
6097
6035
|
}
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6036
|
+
const ConversationGroup = reactExports.memo(function({
|
|
6037
|
+
group,
|
|
6038
|
+
viewMode = "simple",
|
|
6039
|
+
strip,
|
|
6040
|
+
slowResponseThresholdSeconds,
|
|
6041
|
+
cacheTrends,
|
|
6042
|
+
onCompareWithPrevious,
|
|
6043
|
+
comparisonPredecessors,
|
|
6044
|
+
onClearGroup,
|
|
6045
|
+
showClientIdentity = true,
|
|
6046
|
+
showProcessMetadata = true,
|
|
6047
|
+
showLogClientMetadata = true,
|
|
6048
|
+
defaultExpanded = false,
|
|
6049
|
+
timeDisplayFormat,
|
|
6050
|
+
expanded: controlledExpanded,
|
|
6051
|
+
onExpandedChange
|
|
6052
|
+
}) {
|
|
6053
|
+
const [internalExpanded, setInternalExpanded] = reactExports.useState(defaultExpanded);
|
|
6054
|
+
const expanded = controlledExpanded ?? internalExpanded;
|
|
6055
|
+
const setExpanded = reactExports.useCallback(
|
|
6056
|
+
(nextExpanded) => {
|
|
6057
|
+
if (onExpandedChange !== void 0) {
|
|
6058
|
+
onExpandedChange(nextExpanded);
|
|
6059
|
+
return;
|
|
6060
|
+
}
|
|
6061
|
+
setInternalExpanded(nextExpanded);
|
|
6062
|
+
},
|
|
6063
|
+
[onExpandedChange]
|
|
6064
|
+
);
|
|
6065
|
+
reactExports.useEffect(() => {
|
|
6066
|
+
if (!defaultExpanded || controlledExpanded !== void 0) return;
|
|
6067
|
+
setInternalExpanded(true);
|
|
6068
|
+
}, [controlledExpanded, defaultExpanded]);
|
|
6069
|
+
const stats = reactExports.useMemo(() => computeStats(group.logs), [group.logs]);
|
|
6070
|
+
const providers = reactExports.useMemo(() => collectProviders(group.logs), [group.logs]);
|
|
6071
|
+
const startTime = group.logs[0]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
6072
|
+
const endTime = group.logs[group.logs.length - 1]?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
6073
|
+
const isLoading = group.logs.some((log) => log.responseStatus === null);
|
|
6074
|
+
const clientPid = reactExports.useMemo(() => getFirstClientPid(group.logs), [group.logs]);
|
|
6075
|
+
const clientProjectFolder = reactExports.useMemo(() => getFirstClientProjectFolder(group.logs), [group.logs]);
|
|
6076
|
+
const turnGroups = reactExports.useMemo(() => buildTurnGroups(group.logs), [group.logs]);
|
|
6077
|
+
reactExports.useEffect(() => {
|
|
6078
|
+
const handleLogFocusRequest = (event) => {
|
|
6079
|
+
const request = readLogFocusRequest(event);
|
|
6080
|
+
if (request === null) return;
|
|
6081
|
+
if (!group.logs.some((log) => log.id === request.logId)) return;
|
|
6082
|
+
setExpanded(true);
|
|
6083
|
+
};
|
|
6084
|
+
window.addEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
6085
|
+
return () => {
|
|
6086
|
+
window.removeEventListener(LOG_FOCUS_REQUEST_EVENT, handleLogFocusRequest);
|
|
6087
|
+
};
|
|
6088
|
+
}, [group.logs, setExpanded]);
|
|
6089
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2", children: [
|
|
6090
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6091
|
+
ConversationHeader,
|
|
6092
|
+
{
|
|
6093
|
+
conversationId: group.conversationId,
|
|
6094
|
+
startTime,
|
|
6095
|
+
endTime,
|
|
6096
|
+
totalCalls: group.logs.length,
|
|
6097
|
+
totalInputTokens: stats.totalInputTokens,
|
|
6098
|
+
totalOutputTokens: stats.totalOutputTokens,
|
|
6099
|
+
expanded,
|
|
6100
|
+
onToggle: () => setExpanded(!expanded),
|
|
6101
|
+
providers,
|
|
6102
|
+
isLoading,
|
|
6103
|
+
userAgent: group.logs[0]?.userAgent ?? null,
|
|
6104
|
+
clientPid,
|
|
6105
|
+
clientProjectFolder,
|
|
6106
|
+
showClientIdentity,
|
|
6107
|
+
showProcessMetadata,
|
|
6108
|
+
timeDisplayFormat,
|
|
6109
|
+
onClear: () => onClearGroup(group.logs.map((l) => l.id))
|
|
6110
|
+
}
|
|
6111
|
+
),
|
|
6112
|
+
expanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
6113
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6114
|
+
AgentTraceSummary,
|
|
6115
|
+
{
|
|
6116
|
+
logs: group.logs,
|
|
6117
|
+
scopeId: group.conversationId,
|
|
6118
|
+
slowResponseThresholdSeconds,
|
|
6119
|
+
showRollupMetrics: false,
|
|
6120
|
+
timeDisplayFormat
|
|
6121
|
+
}
|
|
6122
|
+
),
|
|
6123
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
6124
|
+
TurnGroupList,
|
|
6125
|
+
{
|
|
6126
|
+
turnGroups,
|
|
6127
|
+
viewMode,
|
|
6128
|
+
strip,
|
|
6129
|
+
slowResponseThresholdSeconds,
|
|
6130
|
+
timeDisplayFormat,
|
|
6131
|
+
cacheTrends,
|
|
6132
|
+
onCompareWithPrevious,
|
|
6133
|
+
comparisonPredecessors,
|
|
6134
|
+
showLogClientMetadata
|
|
6135
|
+
}
|
|
6136
|
+
)
|
|
6137
|
+
] })
|
|
6138
|
+
] });
|
|
6139
|
+
});
|
|
6140
|
+
function CrabLogo({ className }) {
|
|
6141
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
6142
|
+
"svg",
|
|
6101
6143
|
{
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("
|
|
6112
|
-
] }),
|
|
6113
|
-
legs: StdLegs,
|
|
6114
|
-
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6144
|
+
viewBox: "0 0 24 24",
|
|
6145
|
+
fill: "none",
|
|
6146
|
+
stroke: "currentColor",
|
|
6147
|
+
strokeWidth: "1.5",
|
|
6148
|
+
strokeLinecap: "round",
|
|
6149
|
+
strokeLinejoin: "round",
|
|
6150
|
+
"aria-hidden": "true",
|
|
6151
|
+
className: cn("inline-block size-5", className),
|
|
6152
|
+
children: [
|
|
6153
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 13 C5 9 8 7 12 7 C16 7 19 9 19 13 C19 16 16 18 12 18 C8 18 5 16 5 13 Z" }),
|
|
6115
6154
|
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M5 11 C3.5 9.5 1.5 10 2 12.5 C2.5 14 4 13.5 5 12.5" }),
|
|
6116
6155
|
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M19 11 C20.5 9.5 22.5 10 22 12.5 C21.5 14 20 13.5 19 12.5" }),
|
|
6117
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
}
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
className,
|
|
6127
|
-
d: "M7 13.5 C7 10.5 9.5 9 12 9 C14.5 9 17 10.5 17 13.5 C17 16 14.5 17.5 12 17.5 C9.5 17.5 7 16 7 13.5 Z",
|
|
6128
|
-
eyeStalks: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6129
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10.5", y1: "9.5", x2: "10.5", y2: "8" }),
|
|
6130
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "13.5", y1: "9.5", x2: "13.5", y2: "8" })
|
|
6131
|
-
] }),
|
|
6132
|
-
eyes: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6133
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "10.5", cy: "7.5", r: "0.8", fill: "currentColor", stroke: "none" }),
|
|
6134
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "13.5", cy: "7.5", r: "0.8", fill: "currentColor", stroke: "none" })
|
|
6135
|
-
] }),
|
|
6136
|
-
legs: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6137
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "8", y1: "16", x2: "6.5", y2: "18" }),
|
|
6138
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "17", x2: "9.5", y2: "19" }),
|
|
6139
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "17", x2: "14.5", y2: "19" }),
|
|
6140
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "16", y1: "16", x2: "17.5", y2: "18" })
|
|
6141
|
-
] }),
|
|
6142
|
-
extras: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
6143
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M7.5 12 C6.5 11 5.5 11.5 6 13 C6.5 14 7 13.5 7.5 13" }),
|
|
6144
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M16.5 12 C17.5 11 18.5 11.5 18 13 C17.5 14 17 13.5 16.5 13" })
|
|
6145
|
-
] })
|
|
6156
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "10", y1: "7", x2: "9.5", y2: "5" }),
|
|
6157
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "14", y1: "7", x2: "14.5", y2: "5" }),
|
|
6158
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "9.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
6159
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "14.5", cy: "4.5", r: "0.9", fill: "currentColor", stroke: "none" }),
|
|
6160
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "6.5", y1: "16", x2: "4.5", y2: "19.5" }),
|
|
6161
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "9", y1: "17.5", x2: "8", y2: "20.5" }),
|
|
6162
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "15", y1: "17.5", x2: "16", y2: "20.5" }),
|
|
6163
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "17.5", y1: "16", x2: "19.5", y2: "19.5" })
|
|
6164
|
+
]
|
|
6146
6165
|
}
|
|
6147
6166
|
);
|
|
6148
6167
|
}
|
|
6149
|
-
const crabVariants = [
|
|
6150
|
-
Crab1,
|
|
6151
|
-
Crab2,
|
|
6152
|
-
Crab3,
|
|
6153
|
-
Crab4,
|
|
6154
|
-
Crab5,
|
|
6155
|
-
Crab6,
|
|
6156
|
-
Crab7,
|
|
6157
|
-
Crab8,
|
|
6158
|
-
Crab9,
|
|
6159
|
-
Crab10,
|
|
6160
|
-
Crab11,
|
|
6161
|
-
Crab12
|
|
6162
|
-
];
|
|
6163
6168
|
const McpLogoPng = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPoAAAD6CAQAAAAi5ZK2AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfpCxsJDCnsge2KAAAM2ElEQVR42u2de3AW1RnGnyQQDARDwiUFpHIVMHIpYgFRB2nLxQrC0FIDiCKDWNqBUqBlai8wvciIpaRTWh3QDqCDIIjKDL0IaBC5SKlysWJArgqh3BMICYFs/wgpGUi+8579dr89e/Z5zp/59j2755fn3d2z5wJQFEVRFEVRoVQSm+AG1UFrtEdT1EcjNEA5SlCMIhxDAQoJ3S4lIwf9cD+6ozXq1vKbYuzHNmxEPo6xwcKtungIS3EajkYpwLPoyqYLp3KwACe1cFcvezATmWzEMOk+rMBV18CrSjHy0IqNGQb1wMa4cV8vZfgzGrNRTVYm8nDFQ+SV5QymIIWNa6ZGaz6y6ZR/I4cNbJrSkOcb8MpyCVPYzCapKz71GXllWY5b2dhm6EGcTwhyBw52oyUbPHgNx6WEIXfg4CDuYKMHq0kevI/rlhP4Ghs+OE1ERcKRO3BwEh3Z+NFC7sDBATQngMRrcoDIHTj4iE/yUXJ5VVlhYsMkWezy+a6urgRbsAP7cRincQGpqI+maI+O6IMuSHYRbwIW0X/mJvZTeAH9ah1CATTCaKxBmWbUi7iTOMxEXoCncIsodgvM1ezo2cFPMebdy89qfyHL0vxSN5FQzHL5ajRxVU8v7NO4cWQRjCnIy/DDOOq6FcvENS0gGjMS+wUMjvvdZ5awrsv4KvEE7/Iz+Lontc4Q1vc8AQXt8rO4x7Oa54hqLOLI2aBdfrenHVyviWqdQUx2uLxS6fhMUO8ugrLD5VXqLfpmfxdh2eHyKi0S1P5b4rLF5ZVqiiJl/Z8SmD0ur9TzgnNoQWi2uLxSt+Gy8ixGEpvZLs9AN3RGqsYRa5Xn8SeCM9XlDfFT7Ll2bDnWYYRwOMZjyjP5kOjMdPkDOHpTjPX4iuDILOWL2znCMxH5IyitMc4+ZAuO3q08nyYEaFpiHxbjYWyDIMm/qDyje4kwPMgdOBihjDBNeU7fJcQwIXewTnBzUJ3Vk8Rozr18mOAtuxT1FFH6KmNMJkhTkH+7lse3G0s7RZyuygjPEGVYEntV6aSIlKOM8CvCDEtirywVyFDE6q2M8WPiDJPLJcMgBiljPEWg4XG5AwfTlfEmKWPkEml4XO7gCBooI85TRvlm8I1ax3CX68w8PYeB2KGFfEWM6Yo3qgy5uKj8VU/lLz5HG2QjHRlIA1CCIhTjBI6ggg43LbGXYYggZj3lgkYVtbwaluITvIlf4gHhNEomdheJXfpeXoX8EVHUAR4sY1CKfEyN5gibMCIHXvJsBYur2IDxSCNy05HXx1mPFy/5L2ZFZb6rGR2uusiByb6sWlOMZ5FOl5vocqAuDvm2XNExjLV5t52wuhyY7vM6Ve+jA11uksuB5glYcLgIY+hyc1yeJBj87E35q6BXkC5PAHJgdgKXI9xlzzt8eF0OjE/wypQH7Li7h9nl4wJYjPQ4utPlwSF/LKD1Z8+gC10eLeQOHHyJ1nR54pGPCniVadmcGyK3xOVVZYvWnNpqb5hBIv+L1hCJAdiuhXyVcpT6dV3GSLylhXyxy7YrxHYU4CBO4yKABmiCNuiIe9DMVbT5mMp7eWJc/rgLl1dgC6bE2NelM6Zim4uoDzOxm5nYS/GicNOuznhJc0X5k2HprIkS8gos1cTSSrgYodFbhkQ5sR/F/a7aqD8Oa9TSny43x+UblDNialcmVovr2WP2qOYoIV8V57tREuaK6/o+E7sJid2bO+00Ya0HTPV6lFy+3LNWmymsMZfIg+1w9fZ5ep6ozp3mjaKjy90rGetF9d5H5Ha4vFLZOB62zYGIPH6NEk2NqEvk4U/s1V/f8gX1DyJye5ADQC/BGfyRyO1I7Nf1rvIcPiZye1xeqaGCua6ZNiMf7sOSAolD3h+v4otrH2RewYPCo1JxWnkmQ4jcROTZNcyGWSMcN7PQ5KUJw4zc33t5G+xHzfu3S7655wqmPRG5ccgPxxjkqN7DvbnyfDYRuVmJvY1iYMQEQYxCxRkVEnlYXF5ZdguibFLEKI/6S9pQg1x+Ow4IYrZSxlmqjJFGl4fF5dLVJBcoYzQl8jDcy3XestV7tbcl8vC43IGD3spo6gEVtxF5mJCXCu7H6u6ZRlFE/nAoE7sDB8sEEd9URqkTfuT2P7FXlSuiZQb2KKKU0OXhcbmDGYKYdZWrTO8l8nDcyx04mCeKqh5IsYaJPRyJ3cEfhHFnePTPQ+ShQQ68r4z1NJEHkdj9Q95KcN7didwmlwOzBC2dTOT2uByoj5PBPcbR5UEgly0tPo3I7XE5kI1zgoVOWhO5PS4HXhHE/IDI7XE5MFIU9QdEbo/LO6NIEPWS98Mn/F04pD+R16oWOCiK+4LXyMf4irwnin1ErrtWzGtGIW+MXcJvdB4v/H87LvqIvL1yWG90XZ6J7UHNpVvoI/KGKPDxS5q/Lm/ry5e06i7/SBi5HHd5izxVI/nqIpcM6aXL1WW+1z7v6SPyJ0I7RMJvl+sgP+H9uLihviFvp5FDmNhrL096/34+2Jf3cgBYw8TuAfI3/OiHu8MXl+tsMM97ee3lKBr7AT1JuVuwG+Sp2EvkcSMvR1+/PqbO9Bw5MIn38rgTu69rP6fFeJd2hzwFn/OJPU6XO5gNX5VTy6iNk66QA4+KLqoCY5nYay0L4bs6YedN1e5EJ5fRdogu60dM7DE+/SZk+lIqxmMzrl5br2wzxrvbCA5Ad9FlraTLay2vJ3YV2DS0Rds4VzuYI7isQ1q9TNG6l79uzsK/8ldAyffhYRoRwz0qJgLIgT6CC/uHMcjpck/0c8Gl9aHLbUIO/FN5aflEbhfyOoJBfrlEbhNyydf5C0jnvdwm5MAY5eWtInK7kAOzlRc4mYndLuTAq8pL7KGMMTzUXTGGdrj6qc2KS7yq7O27E1fYxx4ufaK4yCOK41M0ofg7dYHIRVIh2xr3gyBdbpxUW8+8ozh+PV0ePqkmSK1RJPdLhrj890Qu1ynFxa6PeXRTQ76X871cS6rPqh/GPDrLiJc0ulxTqgVtj8U8OglneS8Pn9RrHjaMefwbvJeHT4vj/JY+iMjDJ/UQip8oIqyNcewyJnYT9T3lpf9NEaEJPqvlyEV0uZnqKpjVkqWIkV3DTuKlmusfE3kClYwzygaYIIiSi03XxuA7OIF5aE7kJuttZRPsQpIoUga64W601l75mF0xCZdkYdvBPtZP5AGom6Ahtvu2brnfiZ3IXfbKye7rdHmo9AtBc5zyYftIujxAtRONcduIFLrcJm3wpdmDdfm/iDy2BgqbZnpoXE7kSiUJOy8qMNWD2nJwlC43QY+Km+i5OF/fHhD0ARJ5grpjt4qbaT1auM4oU1DGxG6Oev2/71xdCpEr7Jqtro5YpwWELk+AXtZqsHz01ojdDHM1PU7kCVEznNDEko8RuEXQ0bsAJZqRiTxhGqQ5FdGBg3NYgsfRpoZoDTEIv8N/tCNGDnlSwPU/hxkujyzCPhzBOZQiBY3QFB3i6Lidp7lhZSbe0VorcyVGoZwer1JdbHHlTC8LE3vC1US8CLg/xf+XtDqEfLPa4BiRR0/dBXsGhzOxE3kMdcGXCUc+h8iDT/IFCQR+BROJ3ARlaw5DcF8uYAiRm6J6yHPRXaNb9mhvUknkPmuocuGC+MoS1Cdy89QSK3wCvg8PaZ8NkSdM/YT7hsvLRcwSfKwh8kBVB08LN/JSlxIscNUzT+QBKBlDsC1O4OeR53LkDZEHqN7Ic9VRW4a3kav92EbkxigF38BcbEO5CMBhLME45Tz3yCJPChn8dPRBF7RHB3RARrVtvC6hGIewHwUowBYcirMW/e/lubhCZybunyALmR7/6zKxR05ETuRETuRETuRsNCKniJwicorIKSKniJwicorIKSKniJyqGfnHmvsyE3nIlRJzHxi63ErlEXnUNI6JPWrKUO7rTJdbp98QedSUjWIm9qjpGSKPnrYysUdNzYRLEBO5RRrLxF6p5AhB7yz4zUqMtn+CUpSgZyt/sZpz0mzTWuXU5sbRaIgoOT1T8fdCnCZ026RC2lJzQ25CD4EKFX9PwWLUI/RoQQe+hbdcrEBFGazRovf0tdFwe1SUJVyx5u90u03aKOx7J3aLNEP8lY1J3ho10hg3Q7dbo59pjJwhdkvUAMeJPXr6jtY2Ary3W6Jfaw2CptutUJLmJgLEboXSsUkLO5O8JQ9079LtxE7sxE7sxE7sFqkhH+mIXV1WhG43DMoD7OPZZNHD/gWnPUUR+4BwX2wyeQMAijEYH4h/fS+hRw97c0K3B/tAvCf6ZRmh26OLGCpy+wE2VfQe6XLYTFHD/h6bKGrYy9CDDWQr9vwakV/FE2wce5WGl29CfgrD2TC2qy+W4/w14Hsxy5aVKvjFSN1CLVAPp1DEpqAoiqIoyiz9D9lYMumhgrvLAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDI1LTExLTI3VDA5OjEyOjQxKzAwOjAwvIZCxQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyNS0xMS0yN1QwOToxMjo0MSswMDowMM3b+nkAAAAASUVORK5CYII=";
|
|
6164
6169
|
function McpLogo({ className }) {
|
|
6165
6170
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|