@assistant-ui/react-devtools 1.2.18 → 1.2.19
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/dist/data/createInProcessClient.d.ts +1 -3
- package/dist/data/createInProcessClient.d.ts.map +1 -1
- package/dist/data/createInProcessClient.js +1 -3
- package/dist/data/createInProcessClient.js.map +1 -1
- package/dist/styles/panel.generated.d.ts +1 -1
- package/dist/styles/panel.generated.js +1 -1
- package/dist/styles/panel.generated.js.map +1 -1
- package/dist/utils/serialization.d.ts.map +1 -1
- package/dist/utils/serialization.js +13 -4
- package/dist/utils/serialization.js.map +1 -1
- package/dist/views/message/MessageMetrics.d.ts.map +1 -1
- package/dist/views/message/MessageMetrics.js +1 -1
- package/dist/views/message/MessageMetrics.js.map +1 -1
- package/dist/views/message/TtftBar.d.ts +1 -1
- package/dist/views/message/TtftBar.js +2 -2
- package/dist/views/message/TtftBar.js.map +1 -1
- package/dist/views/thread/Transcript.d.ts.map +1 -1
- package/dist/views/thread/Transcript.js +1 -1
- package/dist/views/thread/Transcript.js.map +1 -1
- package/dist/views/ui/CopyButton.d.ts +1 -1
- package/dist/views/ui/CopyButton.js +3 -3
- package/dist/views/ui/CopyButton.js.map +1 -1
- package/dist/views/ui/JSONTree.d.ts.map +1 -1
- package/dist/views/ui/JSONTree.js +51 -72
- package/dist/views/ui/JSONTree.js.map +1 -1
- package/dist/views/ui/getInlineJson.d.ts +5 -0
- package/dist/views/ui/getInlineJson.d.ts.map +1 -0
- package/dist/views/ui/getInlineJson.js +22 -0
- package/dist/views/ui/getInlineJson.js.map +1 -0
- package/package.json +6 -4
- package/src/data/createInProcessClient.ts +1 -3
- package/src/styles/panel.generated.ts +1 -1
- package/src/utils/serialization.test.ts +19 -0
- package/src/utils/serialization.ts +32 -7
- package/src/views/message/MessageMetrics.tsx +2 -3
- package/src/views/message/TtftBar.test.tsx +20 -0
- package/src/views/message/TtftBar.tsx +2 -2
- package/src/views/thread/Transcript.tsx +1 -6
- package/src/views/ui/CopyButton.tsx +3 -3
- package/src/views/ui/JSONTree.interaction.test.tsx +118 -0
- package/src/views/ui/JSONTree.tsx +29 -28
- package/src/views/ui/JSONTree.work.test.tsx +60 -0
- package/src/views/ui/getInlineJson.test.ts +83 -0
- package/src/views/ui/getInlineJson.ts +38 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serialization.js","names":["ModelContext","SerializedModelContext","normalizeToolList","NormalizedTool","readProperty","UNSERIALIZABLE","sanitizeForMessage","value","seen","WeakSet","undefined","String","has","add","Date","Number","isNaN","getTime","toISOString","Map","result","Record","nextSuffixByKey","key","entry","entries","serializedKey","Object","hasOwn","baseKey","suffix","get","set","Set","Array","from","map","isArray","length","index","item","push","keys","delete","REDACTED","SENSITIVE_KEYS","normalizeKey","toLowerCase","replace","MASK_ALL_KEYS","redactSensitive","maskAll","normalized","sanitizeAndRedact","serializeModelContext","context","modelContext","systemValue","system","tools","tool","parameters","providerOptions","providerArgs","server","backendDefault","callSettingsValue","callSettings","configValue","config"],"sources":["../../src/utils/serialization.ts"],"sourcesContent":["import type { ModelContext } from \"@assistant-ui/react\";\nimport type { SerializedModelContext } from \"../types\";\nimport { normalizeToolList, type NormalizedTool } from \"./toolNormalization\";\nimport { readProperty, UNSERIALIZABLE } from \"./unserializable\";\n\nexport const sanitizeForMessage = (\n value: unknown,\n seen = new WeakSet<object>(),\n): unknown => {\n // Early return for primitives\n if (value === null || value === undefined) return value;\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n if (typeof value === \"bigint\" || typeof value === \"symbol\") {\n return String(value);\n }\n if (typeof value === \"function\") {\n return \"[Function]\";\n }\n if (typeof value === \"object\") {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n try {\n if (value instanceof Date) {\n return Number.isNaN(value.getTime())\n ? String(value)\n : value.toISOString();\n }\n if (value instanceof Map) {\n const result: Record<string, unknown> = {};\n const nextSuffixByKey = new Map<string, number>();\n for (const [key, entry] of value.entries()) {\n let serializedKey: string;\n try {\n serializedKey = String(key);\n } catch {\n serializedKey = UNSERIALIZABLE;\n }\n\n if (Object.hasOwn(result, serializedKey)) {\n const baseKey = serializedKey;\n let suffix = nextSuffixByKey.get(baseKey) ?? 2;\n do {\n serializedKey = `${baseKey} (${suffix})`;\n suffix += 1;\n } while (Object.hasOwn(result, serializedKey));\n nextSuffixByKey.set(baseKey, suffix);\n } else {\n nextSuffixByKey.set(serializedKey, 2);\n }\n\n result[serializedKey] = sanitizeForMessage(entry, seen);\n }\n return result;\n }\n if (value instanceof Set) {\n return Array.from(value).map((entry) =>\n sanitizeForMessage(entry, seen),\n );\n }\n if (Array.isArray(value)) {\n const result: unknown[] = [];\n const length = value.length;\n for (let index = 0; index < length; index++) {\n try {\n if (!(index in value)) continue;\n const item = sanitizeForMessage(value[index], seen);\n if (item !== undefined) result.push(item);\n } catch {\n result.push(UNSERIALIZABLE);\n }\n }\n return result;\n }\n\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(value)) {\n try {\n result[key] = sanitizeForMessage(\n (value as Record<string, unknown>)[key],\n seen,\n );\n } catch {\n result[key] = UNSERIALIZABLE;\n }\n }\n return result;\n } catch {\n return UNSERIALIZABLE;\n } finally {\n seen.delete(value);\n }\n }\n return value;\n};\n\nexport const REDACTED = \"[redacted]\";\n\nconst SENSITIVE_KEYS = new Set([\n \"apikey\",\n \"xapikey\",\n \"accesskey\",\n \"authorization\",\n \"password\",\n \"passwd\",\n \"secret\",\n \"clientsecret\",\n \"token\",\n \"accesstoken\",\n \"refreshtoken\",\n \"cookie\",\n \"setcookie\",\n \"credential\",\n \"credentials\",\n \"privatekey\",\n \"bearer\",\n \"sessionid\",\n]);\n\nconst normalizeKey = (key: string) => key.toLowerCase().replace(/[-_]/g, \"\");\n\n/**\n * Subtrees that are credential maps with arbitrary, user-defined key names\n * (MCP stdio `env`, HTTP `headers`). Per-key name matching cannot catch\n * `OPENAI_API_KEY` or a custom auth header, so every leaf inside one of these\n * is masked wholesale.\n */\nconst MASK_ALL_KEYS = new Set([\"env\", \"headers\"]);\n\n/**\n * Mask values whose key names a known credential, and mask every value inside\n * an `env`/`headers` subtree wholesale. Operates on already sanitized plain\n * data (primitives, arrays, plain objects). Applied only to config-bearing\n * subtrees, never to a tool's parameters schema, so a schema property literally\n * named `token` is not corrupted.\n */\nexport const redactSensitive = (value: unknown, maskAll = false): unknown => {\n if (Array.isArray(value)) {\n return value.map((entry) => redactSensitive(entry, maskAll));\n }\n if (value && typeof value === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(\n value as Record<string, unknown>,\n )) {\n const normalized = normalizeKey(key);\n result[key] =\n maskAll || SENSITIVE_KEYS.has(normalized)\n ? REDACTED\n : redactSensitive(entry, MASK_ALL_KEYS.has(normalized));\n }\n return result;\n }\n return maskAll ? REDACTED : value;\n};\n\nexport const sanitizeAndRedact = (value: unknown): unknown =>\n redactSensitive(sanitizeForMessage(value));\n\nexport const serializeModelContext = (\n context: ModelContext | undefined,\n): SerializedModelContext | undefined => {\n if (!context || typeof context !== \"object\") {\n return undefined;\n }\n\n const modelContext = context as Record<string, unknown>;\n const result: SerializedModelContext = {};\n\n const systemValue = readProperty(modelContext, \"system\");\n if (typeof systemValue === \"string\" && systemValue.length > 0) {\n result.system = systemValue;\n }\n\n const tools = normalizeToolList(readProperty(modelContext, \"tools\"));\n if (tools.length > 0) {\n result.tools = tools.map((tool): NormalizedTool => {\n return {\n ...tool,\n parameters: sanitizeForMessage(tool.parameters),\n ...(tool.providerOptions !== undefined\n ? { providerOptions: sanitizeAndRedact(tool.providerOptions) }\n : {}),\n ...(tool.providerArgs !== undefined\n ? { providerArgs: sanitizeAndRedact(tool.providerArgs) }\n : {}),\n ...(tool.server !== undefined\n ? { server: sanitizeAndRedact(tool.server) }\n : {}),\n ...(tool.backendDefault !== undefined\n ? { backendDefault: sanitizeForMessage(tool.backendDefault) }\n : {}),\n };\n });\n }\n\n const callSettingsValue = readProperty(modelContext, \"callSettings\");\n if (callSettingsValue !== undefined) {\n const callSettings = sanitizeAndRedact(callSettingsValue);\n if (\n callSettings &&\n typeof callSettings === \"object\" &&\n !Array.isArray(callSettings)\n ) {\n result.callSettings = callSettings as Record<string, unknown>;\n }\n }\n\n const configValue = readProperty(modelContext, \"config\");\n if (configValue !== undefined) {\n const config = sanitizeAndRedact(configValue);\n if (config && typeof config === \"object\" && !Array.isArray(config)) {\n result.config = config as Record<string, unknown>;\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"serialization.js","names":["ModelContext","SerializedModelContext","normalizeToolList","NormalizedTool","readProperty","UNSERIALIZABLE","setOwnProperty","target","Record","key","value","Object","defineProperty","enumerable","configurable","writable","sanitizeForMessage","seen","WeakSet","undefined","String","has","add","Date","Number","isNaN","getTime","toISOString","Map","result","nextSuffixByKey","entry","entries","serializedKey","hasOwn","baseKey","suffix","get","set","Set","Array","from","map","isArray","length","index","item","push","keys","delete","REDACTED","SENSITIVE_KEYS","normalizeKey","toLowerCase","replace","MASK_ALL_KEYS","redactSensitive","maskAll","normalized","sanitizeAndRedact","serializeModelContext","context","modelContext","systemValue","system","tools","tool","parameters","providerOptions","providerArgs","server","backendDefault","callSettingsValue","callSettings","configValue","config"],"sources":["../../src/utils/serialization.ts"],"sourcesContent":["import type { ModelContext } from \"@assistant-ui/react\";\nimport type { SerializedModelContext } from \"../types\";\nimport { normalizeToolList, type NormalizedTool } from \"./toolNormalization\";\nimport { readProperty, UNSERIALIZABLE } from \"./unserializable\";\n\nconst setOwnProperty = (\n target: Record<string, unknown>,\n key: string,\n value: unknown,\n): void => {\n if (key === \"__proto__\") {\n Object.defineProperty(target, key, {\n value,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n } else {\n target[key] = value;\n }\n};\n\nexport const sanitizeForMessage = (\n value: unknown,\n seen = new WeakSet<object>(),\n): unknown => {\n // Early return for primitives\n if (value === null || value === undefined) return value;\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n if (typeof value === \"bigint\" || typeof value === \"symbol\") {\n return String(value);\n }\n if (typeof value === \"function\") {\n return \"[Function]\";\n }\n if (typeof value === \"object\") {\n if (seen.has(value)) return \"[Circular]\";\n seen.add(value);\n try {\n if (value instanceof Date) {\n return Number.isNaN(value.getTime())\n ? String(value)\n : value.toISOString();\n }\n if (value instanceof Map) {\n const result: Record<string, unknown> = {};\n const nextSuffixByKey = new Map<string, number>();\n for (const [key, entry] of value.entries()) {\n let serializedKey: string;\n try {\n serializedKey = String(key);\n } catch {\n serializedKey = UNSERIALIZABLE;\n }\n\n if (Object.hasOwn(result, serializedKey)) {\n const baseKey = serializedKey;\n let suffix = nextSuffixByKey.get(baseKey) ?? 2;\n do {\n serializedKey = `${baseKey} (${suffix})`;\n suffix += 1;\n } while (Object.hasOwn(result, serializedKey));\n nextSuffixByKey.set(baseKey, suffix);\n } else {\n nextSuffixByKey.set(serializedKey, 2);\n }\n\n setOwnProperty(\n result,\n serializedKey,\n sanitizeForMessage(entry, seen),\n );\n }\n return result;\n }\n if (value instanceof Set) {\n return Array.from(value).map((entry) =>\n sanitizeForMessage(entry, seen),\n );\n }\n if (Array.isArray(value)) {\n const result: unknown[] = [];\n const length = value.length;\n for (let index = 0; index < length; index++) {\n try {\n if (!(index in value)) continue;\n const item = sanitizeForMessage(value[index], seen);\n if (item !== undefined) result.push(item);\n } catch {\n result.push(UNSERIALIZABLE);\n }\n }\n return result;\n }\n\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(value)) {\n try {\n setOwnProperty(\n result,\n key,\n sanitizeForMessage((value as Record<string, unknown>)[key], seen),\n );\n } catch {\n setOwnProperty(result, key, UNSERIALIZABLE);\n }\n }\n return result;\n } catch {\n return UNSERIALIZABLE;\n } finally {\n seen.delete(value);\n }\n }\n return value;\n};\n\nexport const REDACTED = \"[redacted]\";\n\nconst SENSITIVE_KEYS = new Set([\n \"apikey\",\n \"xapikey\",\n \"accesskey\",\n \"authorization\",\n \"password\",\n \"passwd\",\n \"secret\",\n \"clientsecret\",\n \"token\",\n \"accesstoken\",\n \"refreshtoken\",\n \"cookie\",\n \"setcookie\",\n \"credential\",\n \"credentials\",\n \"privatekey\",\n \"bearer\",\n \"sessionid\",\n]);\n\nconst normalizeKey = (key: string) => key.toLowerCase().replace(/[-_]/g, \"\");\n\n/**\n * Subtrees that are credential maps with arbitrary, user-defined key names\n * (MCP stdio `env`, HTTP `headers`). Per-key name matching cannot catch\n * `OPENAI_API_KEY` or a custom auth header, so every leaf inside one of these\n * is masked wholesale.\n */\nconst MASK_ALL_KEYS = new Set([\"env\", \"headers\"]);\n\n/**\n * Mask values whose key names a known credential, and mask every value inside\n * an `env`/`headers` subtree wholesale. Operates on already sanitized plain\n * data (primitives, arrays, plain objects). Applied only to config-bearing\n * subtrees, never to a tool's parameters schema, so a schema property literally\n * named `token` is not corrupted.\n */\nexport const redactSensitive = (value: unknown, maskAll = false): unknown => {\n if (Array.isArray(value)) {\n return value.map((entry) => redactSensitive(entry, maskAll));\n }\n if (value && typeof value === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(\n value as Record<string, unknown>,\n )) {\n const normalized = normalizeKey(key);\n setOwnProperty(\n result,\n key,\n maskAll || SENSITIVE_KEYS.has(normalized)\n ? REDACTED\n : redactSensitive(entry, MASK_ALL_KEYS.has(normalized)),\n );\n }\n return result;\n }\n return maskAll ? REDACTED : value;\n};\n\nexport const sanitizeAndRedact = (value: unknown): unknown =>\n redactSensitive(sanitizeForMessage(value));\n\nexport const serializeModelContext = (\n context: ModelContext | undefined,\n): SerializedModelContext | undefined => {\n if (!context || typeof context !== \"object\") {\n return undefined;\n }\n\n const modelContext = context as Record<string, unknown>;\n const result: SerializedModelContext = {};\n\n const systemValue = readProperty(modelContext, \"system\");\n if (typeof systemValue === \"string\" && systemValue.length > 0) {\n result.system = systemValue;\n }\n\n const tools = normalizeToolList(readProperty(modelContext, \"tools\"));\n if (tools.length > 0) {\n result.tools = tools.map((tool): NormalizedTool => {\n return {\n ...tool,\n parameters: sanitizeForMessage(tool.parameters),\n ...(tool.providerOptions !== undefined\n ? { providerOptions: sanitizeAndRedact(tool.providerOptions) }\n : {}),\n ...(tool.providerArgs !== undefined\n ? { providerArgs: sanitizeAndRedact(tool.providerArgs) }\n : {}),\n ...(tool.server !== undefined\n ? { server: sanitizeAndRedact(tool.server) }\n : {}),\n ...(tool.backendDefault !== undefined\n ? { backendDefault: sanitizeForMessage(tool.backendDefault) }\n : {}),\n };\n });\n }\n\n const callSettingsValue = readProperty(modelContext, \"callSettings\");\n if (callSettingsValue !== undefined) {\n const callSettings = sanitizeAndRedact(callSettingsValue);\n if (\n callSettings &&\n typeof callSettings === \"object\" &&\n !Array.isArray(callSettings)\n ) {\n result.callSettings = callSettings as Record<string, unknown>;\n }\n }\n\n const configValue = readProperty(modelContext, \"config\");\n if (configValue !== undefined) {\n const config = sanitizeAndRedact(configValue);\n if (config && typeof config === \"object\" && !Array.isArray(config)) {\n result.config = config as Record<string, unknown>;\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageMetrics.d.ts","names":[],"sources":["../../../src/views/message/MessageMetrics.tsx"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"MessageMetrics.d.ts","names":[],"sources":["../../../src/views/message/MessageMetrics.tsx"],"mappings":";;cAiDa,mBAAkB;EAAe,SAAS;sBAAgB,IAAA"}
|
|
@@ -8,7 +8,7 @@ const inlineStats = (message) => {
|
|
|
8
8
|
const { timing, usage } = message;
|
|
9
9
|
const stats = [];
|
|
10
10
|
if (timing && !canRenderBar(timing)) {
|
|
11
|
-
const ttft = timing.firstTokenTime !== void 0
|
|
11
|
+
const ttft = timing.firstTokenTime !== void 0 ? Math.max(0, timing.firstTokenTime) : void 0;
|
|
12
12
|
if (ttft !== void 0) stats.push(`TTFT ${formatMs(ttft)}`);
|
|
13
13
|
if (timing.totalStreamTime !== void 0) stats.push(`${formatMs(timing.totalStreamTime)} stream`);
|
|
14
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageMetrics.js","names":["formatMs","MessagePreview","TtftBar","canRenderBar","timing","Boolean","streamStartTime","undefined","firstTokenTime","totalStreamTime","inlineStats","message","usage","stats","ttft","Math","max","push","tokensPerSecond","toFixed","tokenCount","totalChunks","toolCallCount","count","inputTokens","outputTokens","steps","stepCount","MessageMetrics","t0","$","_c","t1","t2","t3","t4","Symbol","for","bb0","t5","bar","length","join"],"sources":["../../../src/views/message/MessageMetrics.tsx"],"sourcesContent":["import { formatMs } from \"../../utils/common\";\nimport type { MessagePreview } from \"./types\";\nimport { TtftBar } from \"./TtftBar\";\n\nconst canRenderBar = (timing: MessagePreview[\"timing\"]) =>\n Boolean(\n timing &&\n timing.streamStartTime !== undefined &&\n timing.firstTokenTime !== undefined &&\n timing.totalStreamTime !== undefined,\n );\n\nconst inlineStats = (message: MessagePreview): string[] => {\n const { timing, usage } = message;\n const stats: string[] = [];\n\n if (timing && !canRenderBar(timing)) {\n const ttft =\n timing.firstTokenTime !== undefined
|
|
1
|
+
{"version":3,"file":"MessageMetrics.js","names":["formatMs","MessagePreview","TtftBar","canRenderBar","timing","Boolean","streamStartTime","undefined","firstTokenTime","totalStreamTime","inlineStats","message","usage","stats","ttft","Math","max","push","tokensPerSecond","toFixed","tokenCount","totalChunks","toolCallCount","count","inputTokens","outputTokens","steps","stepCount","MessageMetrics","t0","$","_c","t1","t2","t3","t4","Symbol","for","bb0","t5","bar","length","join"],"sources":["../../../src/views/message/MessageMetrics.tsx"],"sourcesContent":["import { formatMs } from \"../../utils/common\";\nimport type { MessagePreview } from \"./types\";\nimport { TtftBar } from \"./TtftBar\";\n\nconst canRenderBar = (timing: MessagePreview[\"timing\"]) =>\n Boolean(\n timing &&\n timing.streamStartTime !== undefined &&\n timing.firstTokenTime !== undefined &&\n timing.totalStreamTime !== undefined,\n );\n\nconst inlineStats = (message: MessagePreview): string[] => {\n const { timing, usage } = message;\n const stats: string[] = [];\n\n if (timing && !canRenderBar(timing)) {\n const ttft =\n timing.firstTokenTime !== undefined\n ? Math.max(0, timing.firstTokenTime)\n : undefined;\n if (ttft !== undefined) stats.push(`TTFT ${formatMs(ttft)}`);\n if (timing.totalStreamTime !== undefined) {\n stats.push(`${formatMs(timing.totalStreamTime)} stream`);\n }\n }\n\n if (timing?.tokensPerSecond !== undefined) {\n stats.push(`${timing.tokensPerSecond.toFixed(1)} tok/s`);\n }\n if (timing?.tokenCount !== undefined) {\n stats.push(`${timing.tokenCount} tok`);\n }\n if (timing?.totalChunks !== undefined) {\n stats.push(`${timing.totalChunks} chunks`);\n }\n if (timing?.toolCallCount !== undefined) {\n const count = timing.toolCallCount;\n stats.push(`${count} tool${count === 1 ? \"\" : \"s\"}`);\n }\n if (usage) {\n stats.push(`${usage.inputTokens}/${usage.outputTokens} in/out`);\n const steps = usage.stepCount;\n stats.push(`${steps} step${steps === 1 ? \"\" : \"s\"}`);\n }\n\n return stats;\n};\n\nexport const MessageMetrics = ({ message }: { message: MessagePreview }) => {\n const { timing } = message;\n const stats = inlineStats(message);\n const bar = timing && canRenderBar(timing);\n\n if (!bar && stats.length === 0) return null;\n\n return (\n <div className=\"flex flex-col gap-1\">\n {bar ? <TtftBar timing={timing} /> : null}\n {stats.length ? (\n <p className=\"text-muted-foreground text-[10px] leading-tight tabular-nums\">\n {stats.join(\" · \")}\n </p>\n ) : null}\n </div>\n );\n};\n"],"mappings":";;;;;AAIA,MAAMG,gBAAgBC,WACpBC,QACED,UACAA,OAAOE,oBAAoBC,KAAAA,KAC3BH,OAAOI,mBAAmBD,KAAAA,KAC1BH,OAAOK,oBAAoBF,KAAAA,CAC7B;AAEF,MAAMG,eAAeC,YAAsC;CACzD,MAAM,EAAEP,QAAQQ,UAAUD;CAC1B,MAAME,QAAkB,CAAA;CAExB,IAAIT,UAAU,CAACD,aAAaC,MAAM,GAAG;EACnC,MAAMU,OACJV,OAAOI,mBAAmBD,KAAAA,IACtBQ,KAAKC,IAAI,GAAGZ,OAAOI,cAAc,IACjCD,KAAAA;EACN,IAAIO,SAASP,KAAAA,GAAWM,MAAMI,KAAK,QAAQjB,SAASc,IAAI,GAAG;EAC3D,IAAIV,OAAOK,oBAAoBF,KAAAA,GAC7BM,MAAMI,KAAK,GAAGjB,SAASI,OAAOK,eAAe,EAAC,QAAS;CAE3D;CAEA,IAAIL,QAAQc,oBAAoBX,KAAAA,GAC9BM,MAAMI,KAAK,GAAGb,OAAOc,gBAAgBC,QAAQ,CAAC,EAAC,OAAQ;CAEzD,IAAIf,QAAQgB,eAAeb,KAAAA,GACzBM,MAAMI,KAAK,GAAGb,OAAOgB,WAAU,KAAM;CAEvC,IAAIhB,QAAQiB,gBAAgBd,KAAAA,GAC1BM,MAAMI,KAAK,GAAGb,OAAOiB,YAAW,QAAS;CAE3C,IAAIjB,QAAQkB,kBAAkBf,KAAAA,GAAW;EACvC,MAAMgB,QAAQnB,OAAOkB;EACrBT,MAAMI,KAAK,GAAGM,MAAK,OAAQA,UAAU,IAAI,KAAK,KAAK;CACrD;CACA,IAAIX,OAAO;EACTC,MAAMI,KAAK,GAAGL,MAAMY,YAAW,GAAIZ,MAAMa,aAAY,QAAS;EAC9D,MAAMC,QAAQd,MAAMe;EACpBd,MAAMI,KAAK,GAAGS,MAAK,OAAQA,UAAU,IAAI,KAAK,KAAK;CACrD;CAEA,OAAOb;AACT;AAEA,MAAae,kBAAiBC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAApB,YAAAkB;CAC7B,MAAA,EAAAzB,WAAmBO;CAAQ,IAAAqB;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAC;CAAA,IAAAL,EAAA,OAAAnB,WAAAmB,EAAA,OAAA1B,QAAA;EAIY+B,KAAAC,OAAIC,IAAJ,6BAAG;EAACC,KAAA;GAH3C,MAAAzB,QAAcH,YAAYC,OAAO;GAAE,IAAA4B;GAAA,IAAAT,EAAA,OAAA1B,QAAA;IACvBmC,KAAAnC,UAAUD,aAAaC,MAAM;IAAC0B,EAAA,KAAA1B;IAAA0B,EAAA,KAAAS;GAAA,OAAAA,KAAAT,EAAA;GAA1C,MAAAU,MAAYD;GAEZ,IAAI,CAACC,OAAO3B,MAAK4B,WAAY,GAAC;IAASN,KAAA;IAAA,MAAAG;GAAI;GAG1BN,KAAA;GAAqB,IAAAF,EAAA,OAAAU,OAAAV,EAAA,OAAA1B,QAAA;IACjC6B,KAAAO,MAAM,oBAAC,SAAD,EAAiBpC,OAAM,CAAA,IAA7B;IAAwC0B,EAAA,KAAAU;IAAAV,EAAA,KAAA1B;IAAA0B,EAAA,MAAAG;GAAA,OAAAA,KAAAH,EAAA;GACxCI,KAAArB,MAAK4B,SACJ,oBAAA,KAAA;IAAa,WAAA;IACV5B,UAAAA,MAAK6B,KAAM,KAAK;GACf,CAAA,IAHL;EAIO;EAAAZ,EAAA,KAAAnB;EAAAmB,EAAA,KAAA1B;EAAA0B,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;CAAA,OAAA;EAAAH,KAAAF,EAAA;EAAAG,KAAAH,EAAA;EAAAI,KAAAJ,EAAA;EAAAK,KAAAL,EAAA;CAAA;CAAA,IAAAK,OAAAC,OAAAC,IAAA,6BAAA,GAAA,OAAAF;CAAA,IAAAI;CAAA,IAAAT,EAAA,QAAAE,MAAAF,EAAA,QAAAG,MAAAH,EAAA,QAAAI,IAAA;EANVK,KAAA,qBAAA,OAAA;GAAe,WAAAP;GAAf,UAAA,CACGC,IACAC,EAKG;;EAAAJ,EAAA,MAAAE;EAAAF,EAAA,MAAAG;EAAAH,EAAA,MAAAI;EAAAJ,EAAA,MAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,OAPNS;AAOM"}
|
|
@@ -3,7 +3,7 @@ import { MessageTimingPreview } from "./types.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Splits a model turn into the time-to-first-token segment (dim) and the
|
|
5
5
|
* streaming segment (solid). The only width-bearing timing form: both numbers
|
|
6
|
-
* are measured, not derived. Renders nothing unless all three
|
|
6
|
+
* are measured, not derived. Renders nothing unless all three timing values exist.
|
|
7
7
|
*/
|
|
8
8
|
declare const TtftBar: ({ timing }: {
|
|
9
9
|
timing: MessageTimingPreview;
|
|
@@ -5,14 +5,14 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
/**
|
|
6
6
|
* Splits a model turn into the time-to-first-token segment (dim) and the
|
|
7
7
|
* streaming segment (solid). The only width-bearing timing form: both numbers
|
|
8
|
-
* are measured, not derived. Renders nothing unless all three
|
|
8
|
+
* are measured, not derived. Renders nothing unless all three timing values exist.
|
|
9
9
|
*/
|
|
10
10
|
const TtftBar = (t0) => {
|
|
11
11
|
const $ = c(31);
|
|
12
12
|
const { timing } = t0;
|
|
13
13
|
const { streamStartTime, firstTokenTime, totalStreamTime } = timing;
|
|
14
14
|
if (streamStartTime === void 0 || firstTokenTime === void 0 || totalStreamTime === void 0) return null;
|
|
15
|
-
const ttft = Math.max(0, firstTokenTime
|
|
15
|
+
const ttft = Math.max(0, firstTokenTime);
|
|
16
16
|
const total = Math.max(totalStreamTime, ttft);
|
|
17
17
|
const stream = Math.max(0, total - ttft);
|
|
18
18
|
const ttftPercent = total > 0 ? ttft / total * 100 : 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtftBar.js","names":["formatMs","MessageTimingPreview","TtftBar","t0","$","_c","timing","streamStartTime","firstTokenTime","totalStreamTime","undefined","ttft","Math","max","total","stream","ttftPercent","t1","t2","t3","t4","t5","t6","t7","width","t8","t9","t10","t11","t12","t13","t14","t15","t16","t17"],"sources":["../../../src/views/message/TtftBar.tsx"],"sourcesContent":["import { formatMs } from \"../../utils/common\";\nimport type { MessageTimingPreview } from \"./types\";\n\n/**\n * Splits a model turn into the time-to-first-token segment (dim) and the\n * streaming segment (solid). The only width-bearing timing form: both numbers\n * are measured, not derived. Renders nothing unless all three
|
|
1
|
+
{"version":3,"file":"TtftBar.js","names":["formatMs","MessageTimingPreview","TtftBar","t0","$","_c","timing","streamStartTime","firstTokenTime","totalStreamTime","undefined","ttft","Math","max","total","stream","ttftPercent","t1","t2","t3","t4","t5","t6","t7","width","t8","t9","t10","t11","t12","t13","t14","t15","t16","t17"],"sources":["../../../src/views/message/TtftBar.tsx"],"sourcesContent":["import { formatMs } from \"../../utils/common\";\nimport type { MessageTimingPreview } from \"./types\";\n\n/**\n * Splits a model turn into the time-to-first-token segment (dim) and the\n * streaming segment (solid). The only width-bearing timing form: both numbers\n * are measured, not derived. Renders nothing unless all three timing values exist.\n */\nexport const TtftBar = ({ timing }: { timing: MessageTimingPreview }) => {\n const { streamStartTime, firstTokenTime, totalStreamTime } = timing;\n if (\n streamStartTime === undefined ||\n firstTokenTime === undefined ||\n totalStreamTime === undefined\n ) {\n return null;\n }\n\n const ttft = Math.max(0, firstTokenTime);\n const total = Math.max(totalStreamTime, ttft);\n const stream = Math.max(0, total - ttft);\n const ttftPercent = total > 0 ? (ttft / total) * 100 : 0;\n\n return (\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"text-muted-foreground flex justify-between text-[9px] leading-none tabular-nums\">\n <span>TTFT {formatMs(ttft)}</span>\n <span>{formatMs(stream)} stream</span>\n </div>\n <div className=\"bg-muted flex h-1 overflow-hidden rounded-full\">\n <div\n className=\"bg-muted-foreground/40 h-full\"\n style={{ width: `${ttftPercent}%` }}\n title={`TTFT ${formatMs(ttft)}`}\n />\n <div\n className=\"bg-primary h-full\"\n style={{ width: `${100 - ttftPercent}%` }}\n title={`stream ${formatMs(stream)}`}\n />\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transcript.d.ts","names":[],"sources":["../../../src/views/thread/Transcript.tsx"],"mappings":";;cAyBa,gBAAiB;
|
|
1
|
+
{"version":3,"file":"Transcript.d.ts","names":[],"sources":["../../../src/views/thread/Transcript.tsx"],"mappings":";;cAyBa,gBAAiB;cA4JjB,kCAAgB,uBAAA;EAG3B,QAAQ;sBACT,IAAA;cAkGY,eAAc,QAAA,WAAA;EAKzB,QAAQ;EACR;EACA,WAAW;sBACZ,IAAA"}
|
|
@@ -263,7 +263,7 @@ const metricSeries = (messages) => [
|
|
|
263
263
|
},
|
|
264
264
|
{
|
|
265
265
|
label: "TTFT",
|
|
266
|
-
values: collect(messages, (message) => message.timing?.firstTokenTime
|
|
266
|
+
values: collect(messages, (message) => message.timing?.firstTokenTime),
|
|
267
267
|
format: (value) => `${Math.round(value)}ms`
|
|
268
268
|
},
|
|
269
269
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transcript.js","names":["memo","useCallback","useEffect","useMemo","useRef","useState","clsx","truncate","StatusBadge","MessagePreview","PartPreview","messageStepCount","RoleLabel","Chip","PaneHeader","PaneHeaderStack","RailTime","RAIL_STATUS_BADGE_CLASS","SelectableRow","Sparkline","ToneBadge","ComposerPreview","ThreadPreview","MetricSeries","label","values","format","value","messageNodeId","id","formatTokens","toFixed","String","textOf","parts","filter","part","Extract","type","map","text","join","trim","rowSummary","message","tool","find","toolName","rowStepHint","tools","texts","hints","push","length","railStatus","isOptimistic","status","railAttachmentCount","attachments","TurnRow","t0","$","_c","selected","nodeId","onSelect","rowRef","t1","t2","summary","t3","stepHint","attachmentCount","t4","t5","t6","role","t7","reason","undefined","t8","t9","t10","createdAt","t11","t12","t13","t14","t15","t16","GhostComposer","composer","Symbol","for","textLength","canSend","queue","collect","messages","pick","metricSeries","timing","tokensPerSecond","firstTokenTime","streamStartTime","Math","round","usage","outputTokens","series","TranscriptHeader","thread","expanded","setExpanded","reduce","_temp2","_temp3","errors","tokens","_temp4","Boolean","statParts","trendSeries","stats","canExpand","isRunning","_temp5","titleRow","t17","_temp6","t18","Transcript","selection","selectedRef","prevSelectionRef","handleSelect","current","scrollIntoView","block","nodeId_0","_temp","sum","message_0","sum_0","message_1","inputTokens","prev","entry"],"sources":["../../../src/views/thread/Transcript.tsx"],"sourcesContent":["import { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport clsx from \"clsx\";\nimport { truncate } from \"../../utils/common\";\nimport { StatusBadge } from \"../message\";\nimport type { MessagePreview, PartPreview } from \"../message\";\nimport { messageStepCount } from \"../message/MessageTimeline\";\nimport { RoleLabel } from \"../message/RoleLabel\";\nimport {\n Chip,\n PaneHeader,\n PaneHeaderStack,\n RailTime,\n RAIL_STATUS_BADGE_CLASS,\n SelectableRow,\n Sparkline,\n ToneBadge,\n} from \"../ui\";\nimport type { ComposerPreview, ThreadPreview } from \"./types\";\n\ninterface MetricSeries {\n label: string;\n values: number[];\n format: (value: number) => string;\n}\n\nexport const messageNodeId = (id: string) => `msg:${id}`;\n\nconst formatTokens = (value: number) =>\n value >= 1000 ? `${(value / 1000).toFixed(1)}k` : String(value);\n\nconst textOf = (parts: readonly PartPreview[]) =>\n parts\n .filter(\n (part): part is Extract<PartPreview, { type: \"text\" }> =>\n part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\"\\n\")\n .trim();\n\nconst rowSummary = (message: MessagePreview) => {\n const text = textOf(message.parts);\n if (text) return truncate(text, 72);\n const tool = message.parts.find(\n (part): part is Extract<PartPreview, { type: \"tool-call\" }> =>\n part.type === \"tool-call\",\n );\n if (tool) return tool.toolName;\n return \"—\";\n};\n\nconst rowStepHint = (message: MessagePreview) => {\n const { tools, texts } = messageStepCount(message.parts);\n const hints: string[] = [];\n if (tools > 1) hints.push(`${tools} tools`);\n if (texts > 1) hints.push(`${texts} msgs`);\n return hints.length ? hints.join(\" · \") : null;\n};\n\nconst railStatus = (message: MessagePreview) => {\n if (message.isOptimistic) return null;\n if (!message.status || message.status.type === \"complete\") return null;\n return message.status;\n};\n\nconst railAttachmentCount = (message: MessagePreview) => {\n if (message.attachments.length > 0) return message.attachments.length;\n return message.parts.filter(\n (part) =>\n part.type === \"image\" || part.type === \"file\" || part.type === \"audio\",\n ).length;\n};\n\nconst TurnRow = memo(function TurnRow({\n message,\n selected,\n nodeId,\n onSelect,\n rowRef,\n}: {\n message: MessagePreview;\n selected: boolean;\n nodeId: string;\n onSelect: (nodeId: string) => void;\n rowRef?: React.Ref<HTMLButtonElement> | undefined;\n}) {\n const status = railStatus(message);\n const summary = rowSummary(message);\n const stepHint = rowStepHint(message);\n const attachmentCount = railAttachmentCount(message);\n\n return (\n <SelectableRow\n ref={rowRef}\n selected={selected}\n onSelect={() => onSelect(nodeId)}\n dense\n >\n <div\n className=\"flex h-10 flex-col justify-center gap-0.5\"\n title={stepHint ? `${stepHint}\\n${summary}` : summary}\n >\n <div className=\"flex min-w-0 items-center justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-1.5\">\n <RoleLabel role={message.role} compact />\n {message.isOptimistic ? (\n <ToneBadge\n tone=\"amber\"\n size=\"sm\"\n className={RAIL_STATUS_BADGE_CLASS}\n >\n opt\n </ToneBadge>\n ) : status ? (\n <StatusBadge\n type={status.type}\n reason={\"reason\" in status ? status.reason : undefined}\n compact\n size=\"sm\"\n className={RAIL_STATUS_BADGE_CLASS}\n />\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {attachmentCount > 0 ? (\n <span\n className=\"text-muted-foreground text-[10px] leading-none\"\n title={`${attachmentCount} attachment${attachmentCount === 1 ? \"\" : \"s\"}`}\n >\n 📎{attachmentCount}\n </span>\n ) : null}\n <RailTime value={message.createdAt} />\n </div>\n </div>\n <p className=\"text-foreground min-w-0 truncate text-[12px] leading-tight\">\n {stepHint ? (\n <span className=\"text-muted-foreground\">{stepHint} · </span>\n ) : null}\n {summary}\n </p>\n </div>\n </SelectableRow>\n );\n});\n\nconst GhostComposer = ({ composer }: { composer: ComposerPreview }) => (\n <div className=\"border-border text-muted-foreground flex items-center gap-2 border-t px-3 py-2 text-[11px]\">\n <span className=\"text-foreground font-medium\">draft</span>\n <span>{composer.role ?? \"user\"}</span>\n <span>· {composer.textLength} chars</span>\n {composer.canSend ? <Chip>can send</Chip> : null}\n {composer.queue.length ? <Chip>{composer.queue.length} queued</Chip> : null}\n </div>\n);\n\nconst collect = (\n messages: readonly MessagePreview[],\n pick: (message: MessagePreview) => number | undefined,\n): number[] =>\n messages.map(pick).filter((value): value is number => value !== undefined);\n\nconst metricSeries = (messages: readonly MessagePreview[]): MetricSeries[] =>\n [\n {\n label: \"tok/s\",\n values: collect(messages, (message) => message.timing?.tokensPerSecond),\n format: (value: number) => value.toFixed(1),\n },\n {\n label: \"TTFT\",\n values: collect(messages, (message) =>\n message.timing?.firstTokenTime !== undefined &&\n message.timing?.streamStartTime !== undefined\n ? message.timing.firstTokenTime - message.timing.streamStartTime\n : undefined,\n ),\n format: (value: number) => `${Math.round(value)}ms`,\n },\n {\n label: \"output\",\n values: collect(messages, (message) => message.usage?.outputTokens),\n format: (value: number) => String(value),\n },\n ].filter((series) => series.values.length >= 3);\n\nexport const TranscriptHeader = memo(function TranscriptHeader({\n thread,\n}: {\n thread: ThreadPreview;\n}) {\n const [expanded, setExpanded] = useState(false);\n const messages = thread.messages;\n\n const { stats, series, canExpand } = useMemo(() => {\n const tools = messages.reduce(\n (sum, message) =>\n sum + message.parts.filter((part) => part.type === \"tool-call\").length,\n 0,\n );\n const errors = messages.filter(\n (message) => message.status?.type === \"incomplete\",\n ).length;\n const tokens = messages.reduce(\n (sum, message) =>\n sum +\n (message.usage\n ? message.usage.inputTokens + message.usage.outputTokens\n : 0),\n 0,\n );\n\n const statParts = [\n `${messages.length} msg${messages.length === 1 ? \"\" : \"s\"}`,\n tokens ? `${formatTokens(tokens)} tok` : null,\n tools ? `${tools} tool${tools === 1 ? \"\" : \"s\"}` : null,\n errors ? `${errors} err` : null,\n ].filter(Boolean);\n\n const trendSeries = metricSeries(messages);\n\n return {\n stats: statParts,\n series: trendSeries,\n canExpand: trendSeries.length > 0,\n };\n }, [messages]);\n\n const titleRow = (\n <PaneHeader\n borderless={canExpand && expanded}\n trailing={\n <>\n {thread.isRunning ? (\n <ToneBadge tone=\"blue\" size=\"sm\">\n running\n </ToneBadge>\n ) : null}\n {canExpand ? (\n <button\n type=\"button\"\n onClick={() => setExpanded((prev) => !prev)}\n className=\"text-muted-foreground hover:text-foreground text-[11px] leading-none\"\n >\n <span\n className={clsx(\n \"inline-block transition-transform\",\n expanded && \"rotate-90\",\n )}\n >\n ›\n </span>{\" \"}\n trends\n </button>\n ) : null}\n </>\n }\n >\n {stats.join(\" · \")}\n </PaneHeader>\n );\n\n if (canExpand && expanded) {\n return (\n <PaneHeaderStack header={titleRow}>\n {series.map((entry) => (\n <div\n key={entry.label}\n className=\"flex items-center justify-between gap-3 px-3 py-1.5\"\n >\n <div className=\"flex flex-col\">\n <span className=\"text-muted-foreground text-[10px]\">\n {entry.label}\n </span>\n <span className=\"text-foreground text-[12px] font-medium tabular-nums\">\n {entry.format(entry.values[entry.values.length - 1]!)}\n </span>\n </div>\n <Sparkline values={entry.values} className=\"h-6 w-24\" />\n </div>\n ))}\n </PaneHeaderStack>\n );\n }\n\n return titleRow;\n});\n\nexport const Transcript = ({\n thread,\n selection,\n onSelect,\n}: {\n thread: ThreadPreview;\n selection: string | null;\n onSelect: (nodeId: string) => void;\n}) => {\n const selectedRef = useRef<HTMLButtonElement>(null);\n const prevSelectionRef = useRef(selection);\n const handleSelect = useCallback(\n (nodeId: string) => onSelect(nodeId),\n [onSelect],\n );\n\n useEffect(() => {\n if (prevSelectionRef.current === selection) return;\n prevSelectionRef.current = selection;\n selectedRef.current?.scrollIntoView({ block: \"nearest\" });\n }, [selection]);\n\n return (\n <>\n {thread.messages.map((message) => {\n const nodeId = messageNodeId(message.id);\n const selected = selection === nodeId;\n return (\n <TurnRow\n key={message.id}\n message={message}\n nodeId={nodeId}\n selected={selected}\n onSelect={handleSelect}\n rowRef={selected ? selectedRef : undefined}\n />\n );\n })}\n {thread.composer && thread.composer.textLength > 0 ? (\n <GhostComposer composer={thread.composer} />\n ) : null}\n </>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Transcript.js","names":["memo","useCallback","useEffect","useMemo","useRef","useState","clsx","truncate","StatusBadge","MessagePreview","PartPreview","messageStepCount","RoleLabel","Chip","PaneHeader","PaneHeaderStack","RailTime","RAIL_STATUS_BADGE_CLASS","SelectableRow","Sparkline","ToneBadge","ComposerPreview","ThreadPreview","MetricSeries","label","values","format","value","messageNodeId","id","formatTokens","toFixed","String","textOf","parts","filter","part","Extract","type","map","text","join","trim","rowSummary","message","tool","find","toolName","rowStepHint","tools","texts","hints","push","length","railStatus","isOptimistic","status","railAttachmentCount","attachments","TurnRow","t0","$","_c","selected","nodeId","onSelect","rowRef","t1","t2","summary","t3","stepHint","attachmentCount","t4","t5","t6","role","t7","reason","undefined","t8","t9","t10","createdAt","t11","t12","t13","t14","t15","t16","GhostComposer","composer","Symbol","for","textLength","canSend","queue","collect","messages","pick","metricSeries","timing","tokensPerSecond","firstTokenTime","Math","round","usage","outputTokens","series","TranscriptHeader","thread","expanded","setExpanded","reduce","_temp2","_temp3","errors","tokens","_temp4","Boolean","statParts","trendSeries","stats","canExpand","isRunning","_temp5","titleRow","t17","_temp6","t18","Transcript","selection","selectedRef","prevSelectionRef","handleSelect","current","scrollIntoView","block","nodeId_0","_temp","sum","message_0","sum_0","message_1","inputTokens","prev","entry"],"sources":["../../../src/views/thread/Transcript.tsx"],"sourcesContent":["import { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport clsx from \"clsx\";\nimport { truncate } from \"../../utils/common\";\nimport { StatusBadge } from \"../message\";\nimport type { MessagePreview, PartPreview } from \"../message\";\nimport { messageStepCount } from \"../message/MessageTimeline\";\nimport { RoleLabel } from \"../message/RoleLabel\";\nimport {\n Chip,\n PaneHeader,\n PaneHeaderStack,\n RailTime,\n RAIL_STATUS_BADGE_CLASS,\n SelectableRow,\n Sparkline,\n ToneBadge,\n} from \"../ui\";\nimport type { ComposerPreview, ThreadPreview } from \"./types\";\n\ninterface MetricSeries {\n label: string;\n values: number[];\n format: (value: number) => string;\n}\n\nexport const messageNodeId = (id: string) => `msg:${id}`;\n\nconst formatTokens = (value: number) =>\n value >= 1000 ? `${(value / 1000).toFixed(1)}k` : String(value);\n\nconst textOf = (parts: readonly PartPreview[]) =>\n parts\n .filter(\n (part): part is Extract<PartPreview, { type: \"text\" }> =>\n part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\"\\n\")\n .trim();\n\nconst rowSummary = (message: MessagePreview) => {\n const text = textOf(message.parts);\n if (text) return truncate(text, 72);\n const tool = message.parts.find(\n (part): part is Extract<PartPreview, { type: \"tool-call\" }> =>\n part.type === \"tool-call\",\n );\n if (tool) return tool.toolName;\n return \"—\";\n};\n\nconst rowStepHint = (message: MessagePreview) => {\n const { tools, texts } = messageStepCount(message.parts);\n const hints: string[] = [];\n if (tools > 1) hints.push(`${tools} tools`);\n if (texts > 1) hints.push(`${texts} msgs`);\n return hints.length ? hints.join(\" · \") : null;\n};\n\nconst railStatus = (message: MessagePreview) => {\n if (message.isOptimistic) return null;\n if (!message.status || message.status.type === \"complete\") return null;\n return message.status;\n};\n\nconst railAttachmentCount = (message: MessagePreview) => {\n if (message.attachments.length > 0) return message.attachments.length;\n return message.parts.filter(\n (part) =>\n part.type === \"image\" || part.type === \"file\" || part.type === \"audio\",\n ).length;\n};\n\nconst TurnRow = memo(function TurnRow({\n message,\n selected,\n nodeId,\n onSelect,\n rowRef,\n}: {\n message: MessagePreview;\n selected: boolean;\n nodeId: string;\n onSelect: (nodeId: string) => void;\n rowRef?: React.Ref<HTMLButtonElement> | undefined;\n}) {\n const status = railStatus(message);\n const summary = rowSummary(message);\n const stepHint = rowStepHint(message);\n const attachmentCount = railAttachmentCount(message);\n\n return (\n <SelectableRow\n ref={rowRef}\n selected={selected}\n onSelect={() => onSelect(nodeId)}\n dense\n >\n <div\n className=\"flex h-10 flex-col justify-center gap-0.5\"\n title={stepHint ? `${stepHint}\\n${summary}` : summary}\n >\n <div className=\"flex min-w-0 items-center justify-between gap-2\">\n <div className=\"flex min-w-0 items-center gap-1.5\">\n <RoleLabel role={message.role} compact />\n {message.isOptimistic ? (\n <ToneBadge\n tone=\"amber\"\n size=\"sm\"\n className={RAIL_STATUS_BADGE_CLASS}\n >\n opt\n </ToneBadge>\n ) : status ? (\n <StatusBadge\n type={status.type}\n reason={\"reason\" in status ? status.reason : undefined}\n compact\n size=\"sm\"\n className={RAIL_STATUS_BADGE_CLASS}\n />\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-1\">\n {attachmentCount > 0 ? (\n <span\n className=\"text-muted-foreground text-[10px] leading-none\"\n title={`${attachmentCount} attachment${attachmentCount === 1 ? \"\" : \"s\"}`}\n >\n 📎{attachmentCount}\n </span>\n ) : null}\n <RailTime value={message.createdAt} />\n </div>\n </div>\n <p className=\"text-foreground min-w-0 truncate text-[12px] leading-tight\">\n {stepHint ? (\n <span className=\"text-muted-foreground\">{stepHint} · </span>\n ) : null}\n {summary}\n </p>\n </div>\n </SelectableRow>\n );\n});\n\nconst GhostComposer = ({ composer }: { composer: ComposerPreview }) => (\n <div className=\"border-border text-muted-foreground flex items-center gap-2 border-t px-3 py-2 text-[11px]\">\n <span className=\"text-foreground font-medium\">draft</span>\n <span>{composer.role ?? \"user\"}</span>\n <span>· {composer.textLength} chars</span>\n {composer.canSend ? <Chip>can send</Chip> : null}\n {composer.queue.length ? <Chip>{composer.queue.length} queued</Chip> : null}\n </div>\n);\n\nconst collect = (\n messages: readonly MessagePreview[],\n pick: (message: MessagePreview) => number | undefined,\n): number[] =>\n messages.map(pick).filter((value): value is number => value !== undefined);\n\nconst metricSeries = (messages: readonly MessagePreview[]): MetricSeries[] =>\n [\n {\n label: \"tok/s\",\n values: collect(messages, (message) => message.timing?.tokensPerSecond),\n format: (value: number) => value.toFixed(1),\n },\n {\n label: \"TTFT\",\n values: collect(messages, (message) => message.timing?.firstTokenTime),\n format: (value: number) => `${Math.round(value)}ms`,\n },\n {\n label: \"output\",\n values: collect(messages, (message) => message.usage?.outputTokens),\n format: (value: number) => String(value),\n },\n ].filter((series) => series.values.length >= 3);\n\nexport const TranscriptHeader = memo(function TranscriptHeader({\n thread,\n}: {\n thread: ThreadPreview;\n}) {\n const [expanded, setExpanded] = useState(false);\n const messages = thread.messages;\n\n const { stats, series, canExpand } = useMemo(() => {\n const tools = messages.reduce(\n (sum, message) =>\n sum + message.parts.filter((part) => part.type === \"tool-call\").length,\n 0,\n );\n const errors = messages.filter(\n (message) => message.status?.type === \"incomplete\",\n ).length;\n const tokens = messages.reduce(\n (sum, message) =>\n sum +\n (message.usage\n ? message.usage.inputTokens + message.usage.outputTokens\n : 0),\n 0,\n );\n\n const statParts = [\n `${messages.length} msg${messages.length === 1 ? \"\" : \"s\"}`,\n tokens ? `${formatTokens(tokens)} tok` : null,\n tools ? `${tools} tool${tools === 1 ? \"\" : \"s\"}` : null,\n errors ? `${errors} err` : null,\n ].filter(Boolean);\n\n const trendSeries = metricSeries(messages);\n\n return {\n stats: statParts,\n series: trendSeries,\n canExpand: trendSeries.length > 0,\n };\n }, [messages]);\n\n const titleRow = (\n <PaneHeader\n borderless={canExpand && expanded}\n trailing={\n <>\n {thread.isRunning ? (\n <ToneBadge tone=\"blue\" size=\"sm\">\n running\n </ToneBadge>\n ) : null}\n {canExpand ? (\n <button\n type=\"button\"\n onClick={() => setExpanded((prev) => !prev)}\n className=\"text-muted-foreground hover:text-foreground text-[11px] leading-none\"\n >\n <span\n className={clsx(\n \"inline-block transition-transform\",\n expanded && \"rotate-90\",\n )}\n >\n ›\n </span>{\" \"}\n trends\n </button>\n ) : null}\n </>\n }\n >\n {stats.join(\" · \")}\n </PaneHeader>\n );\n\n if (canExpand && expanded) {\n return (\n <PaneHeaderStack header={titleRow}>\n {series.map((entry) => (\n <div\n key={entry.label}\n className=\"flex items-center justify-between gap-3 px-3 py-1.5\"\n >\n <div className=\"flex flex-col\">\n <span className=\"text-muted-foreground text-[10px]\">\n {entry.label}\n </span>\n <span className=\"text-foreground text-[12px] font-medium tabular-nums\">\n {entry.format(entry.values[entry.values.length - 1]!)}\n </span>\n </div>\n <Sparkline values={entry.values} className=\"h-6 w-24\" />\n </div>\n ))}\n </PaneHeaderStack>\n );\n }\n\n return titleRow;\n});\n\nexport const Transcript = ({\n thread,\n selection,\n onSelect,\n}: {\n thread: ThreadPreview;\n selection: string | null;\n onSelect: (nodeId: string) => void;\n}) => {\n const selectedRef = useRef<HTMLButtonElement>(null);\n const prevSelectionRef = useRef(selection);\n const handleSelect = useCallback(\n (nodeId: string) => onSelect(nodeId),\n [onSelect],\n );\n\n useEffect(() => {\n if (prevSelectionRef.current === selection) return;\n prevSelectionRef.current = selection;\n selectedRef.current?.scrollIntoView({ block: \"nearest\" });\n }, [selection]);\n\n return (\n <>\n {thread.messages.map((message) => {\n const nodeId = messageNodeId(message.id);\n const selected = selection === nodeId;\n return (\n <TurnRow\n key={message.id}\n message={message}\n nodeId={nodeId}\n selected={selected}\n onSelect={handleSelect}\n rowRef={selected ? selectedRef : undefined}\n />\n );\n })}\n {thread.composer && thread.composer.textLength > 0 ? (\n <GhostComposer composer={thread.composer} />\n ) : null}\n </>\n );\n};\n"],"mappings":"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"}
|
|
@@ -56,11 +56,11 @@ const CopyButton = (t0) => {
|
|
|
56
56
|
const { isCopied, copy } = useCopyToClipboard();
|
|
57
57
|
let t5;
|
|
58
58
|
if ($[0] !== value) {
|
|
59
|
-
t5 = value.trim();
|
|
59
|
+
t5 = typeof value === "string" && !value.trim();
|
|
60
60
|
$[0] = value;
|
|
61
61
|
$[1] = t5;
|
|
62
62
|
} else t5 = $[1];
|
|
63
|
-
const empty =
|
|
63
|
+
const empty = t5;
|
|
64
64
|
const iconPx = size === "sm" ? 10 : 12;
|
|
65
65
|
const t6 = isCopied ? copiedLabel : label;
|
|
66
66
|
const t7 = isCopied ? copiedLabel : label;
|
|
@@ -68,7 +68,7 @@ const CopyButton = (t0) => {
|
|
|
68
68
|
if ($[2] !== copy || $[3] !== value) {
|
|
69
69
|
t8 = (event) => {
|
|
70
70
|
event.stopPropagation();
|
|
71
|
-
copy(value);
|
|
71
|
+
copy(typeof value === "function" ? value() : value);
|
|
72
72
|
};
|
|
73
73
|
$[2] = copy;
|
|
74
74
|
$[3] = value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyButton.js","names":["clsx","useCopyToClipboard","ClipboardIcon","t0","$","_c","size","t1","undefined","t2","t3","Symbol","for","t4","CopyButton","value","label","copiedLabel","className","iconOnly","isCopied","copy","t5","trim","empty","iconPx","t6","t7","t8","event","stopPropagation","t9","t10","t11","t12","t13"],"sources":["../../../src/views/ui/CopyButton.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { useCopyToClipboard } from \"./useCopyToClipboard\";\n\nconst ClipboardIcon = ({ size = 12 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"9\"\n y=\"9\"\n width=\"11\"\n height=\"11\"\n rx=\"1.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n />\n <path\n d=\"M7 15H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v1\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport const CopyButton = ({\n value,\n label = \"Copy\",\n copiedLabel = \"Copied\",\n className,\n iconOnly = false,\n size = \"default\",\n}: {\n value: string;\n label?: string;\n copiedLabel?: string;\n className?: string | undefined;\n iconOnly?: boolean;\n size?: \"default\" | \"sm\";\n}) => {\n const { isCopied, copy } = useCopyToClipboard();\n const empty = !value.trim();\n const iconPx = size === \"sm\" ? 10 : 12;\n\n return (\n <button\n type=\"button\"\n disabled={empty}\n aria-label={isCopied ? copiedLabel : label}\n title={isCopied ? copiedLabel : label}\n onClick={(event) => {\n event.stopPropagation();\n copy(value);\n }}\n className={clsx(\n \"text-muted-foreground hover:text-foreground inline-flex shrink-0 items-center justify-center rounded transition-colors disabled:pointer-events-none disabled:opacity-40\",\n iconOnly\n ? size === \"sm\"\n ? \"hover:bg-accent/60 size-4\"\n : \"hover:bg-accent/60 size-6\"\n : \"hover:bg-accent/60 h-6 gap-1 px-1.5 text-[10px] font-medium\",\n className,\n )}\n >\n <ClipboardIcon size={iconPx} />\n {!iconOnly ? <span>{isCopied ? copiedLabel : label}</span> : null}\n </button>\n );\n};\n"],"mappings":";;;;;AAGA,MAAME,iBAAgBC,OAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CAAC,MAAA,EAAAC,MAAAC,OAAAJ;CAAE,MAAAG,OAAAC,OAAAC,KAAAA,IAAA,KAAAD;CAAS,IAAAE;CAAA,IAAAC;CAAA,IAAAN,EAAA,OAAAO,OAAAC,IAAA,2BAAA,GAAA;EAQ9BH,KAAA,oBAAA,QAAA;GACI,GAAA;GACA,GAAA;GACI,OAAA;GACC,QAAA;GACJ,IAAA;GACI,QAAA;GACK,aAAA;EAAM,CAAA;EAEpBC,KAAA,oBAAA,QAAA;GACI,GAAA;GACK,QAAA;GACK,aAAA;GACE,eAAA;EAAO,CAAA;EACrBN,EAAA,KAAAK;EAAAL,EAAA,KAAAM;CAAA,OAAA;EAAAD,KAAAL,EAAA;EAAAM,KAAAN,EAAA;CAAA;CAAA,IAAAS;CAAA,IAAAT,EAAA,OAAAE,MAAA;EArBJO,KAAA,qBAAA,OAAA;GACSP,OAAAA;GACCA,QAAAA;GACA,SAAA;GACH,MAAA;GACO,eAAA;GALd,UAAA,CAOEG,IASAC,EAMI;;EAAAN,EAAA,KAAAE;EAAAF,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,OAtBNS;AAsBM;AAGR,MAAaC,cAAaX,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAC,MAAA,EAAAU,OAAAC,OAAAT,IAAAU,aAAAR,IAAAS,WAAAC,UAAAT,IAAAJ,MAAAO,OAAAV;CAEzB,MAAAa,QAAAT,OAAAC,KAAAA,IAAA,SAAAD;CACA,MAAAU,cAAAR,OAAAD,KAAAA,IAAA,WAAAC;CAEA,MAAAU,WAAAT,OAAAF,KAAAA,IAAA,QAAAE;CACA,MAAAJ,OAAAO,OAAAL,KAAAA,IAAA,YAAAK;CASA,MAAA,EAAAO,UAAAC,SAA2BpB,mBAAmB;CAAE,IAAAqB;CAAA,IAAAlB,EAAA,OAAAW,OAAA;
|
|
1
|
+
{"version":3,"file":"CopyButton.js","names":["clsx","useCopyToClipboard","ClipboardIcon","t0","$","_c","size","t1","undefined","t2","t3","Symbol","for","t4","CopyButton","value","label","copiedLabel","className","iconOnly","isCopied","copy","t5","trim","empty","iconPx","t6","t7","t8","event","stopPropagation","t9","t10","t11","t12","t13"],"sources":["../../../src/views/ui/CopyButton.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { useCopyToClipboard } from \"./useCopyToClipboard\";\n\nconst ClipboardIcon = ({ size = 12 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <rect\n x=\"9\"\n y=\"9\"\n width=\"11\"\n height=\"11\"\n rx=\"1.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n />\n <path\n d=\"M7 15H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v1\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport const CopyButton = ({\n value,\n label = \"Copy\",\n copiedLabel = \"Copied\",\n className,\n iconOnly = false,\n size = \"default\",\n}: {\n value: string | (() => string);\n label?: string;\n copiedLabel?: string;\n className?: string | undefined;\n iconOnly?: boolean;\n size?: \"default\" | \"sm\";\n}) => {\n const { isCopied, copy } = useCopyToClipboard();\n const empty = typeof value === \"string\" && !value.trim();\n const iconPx = size === \"sm\" ? 10 : 12;\n\n return (\n <button\n type=\"button\"\n disabled={empty}\n aria-label={isCopied ? copiedLabel : label}\n title={isCopied ? copiedLabel : label}\n onClick={(event) => {\n event.stopPropagation();\n copy(typeof value === \"function\" ? value() : value);\n }}\n className={clsx(\n \"text-muted-foreground hover:text-foreground inline-flex shrink-0 items-center justify-center rounded transition-colors disabled:pointer-events-none disabled:opacity-40\",\n iconOnly\n ? size === \"sm\"\n ? \"hover:bg-accent/60 size-4\"\n : \"hover:bg-accent/60 size-6\"\n : \"hover:bg-accent/60 h-6 gap-1 px-1.5 text-[10px] font-medium\",\n className,\n )}\n >\n <ClipboardIcon size={iconPx} />\n {!iconOnly ? <span>{isCopied ? copiedLabel : label}</span> : null}\n </button>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSONTree.d.ts","names":[],"sources":["../../../src/views/ui/JSONTree.tsx"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"JSONTree.d.ts","names":[],"sources":["../../../src/views/ui/JSONTree.tsx"],"mappings":";;;;cA0Ma,aAAY,OAAA,WAAA;EAKvB;EACA;EACA;sBACD,IAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CopyButton } from "./CopyButton.js";
|
|
2
|
+
import { getInlineJson } from "./getInlineJson.js";
|
|
2
3
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
3
4
|
import { useState } from "@assistant-ui/tap/react-shim";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -7,26 +8,17 @@ import clsx from "clsx";
|
|
|
7
8
|
const ENTRY_LIMIT = 100;
|
|
8
9
|
const INLINE_MAX = 88;
|
|
9
10
|
const isContainer = (value) => value !== null && typeof value === "object";
|
|
10
|
-
const entriesOf = (value) => {
|
|
11
|
-
if (Array.isArray(value)) return value.map((item, index) => ({
|
|
11
|
+
const entriesOf = (value, keys, limit) => {
|
|
12
|
+
if (Array.isArray(value)) return value.slice(0, limit).map((item, index) => ({
|
|
12
13
|
key: String(index),
|
|
13
14
|
value: item
|
|
14
15
|
}));
|
|
15
|
-
return
|
|
16
|
+
return keys.slice(0, limit).map((key) => ({
|
|
16
17
|
key,
|
|
17
|
-
value
|
|
18
|
+
value: value[key]
|
|
18
19
|
}));
|
|
19
20
|
};
|
|
20
|
-
const summaryOf = (value) => {
|
|
21
|
-
if (Array.isArray(value)) return `[${value.length}]`;
|
|
22
|
-
return `{${Object.keys(value).length}}`;
|
|
23
|
-
};
|
|
24
21
|
const serialize = (value, compact) => JSON.stringify(value, null, compact ? 0 : 2);
|
|
25
|
-
const isInline = (value, compact) => {
|
|
26
|
-
if (!compact) return false;
|
|
27
|
-
if (!isContainer(value)) return true;
|
|
28
|
-
return serialize(value, true).length <= INLINE_MAX;
|
|
29
|
-
};
|
|
30
22
|
const Leaf = (t0) => {
|
|
31
23
|
const $ = c(6);
|
|
32
24
|
const { value } = t0;
|
|
@@ -72,7 +64,7 @@ const Leaf = (t0) => {
|
|
|
72
64
|
return t2;
|
|
73
65
|
};
|
|
74
66
|
const TreeNode = (t0) => {
|
|
75
|
-
const $ = c(
|
|
67
|
+
const $ = c(34);
|
|
76
68
|
const { name, value, depth, openDepth, compact } = t0;
|
|
77
69
|
const [open, setOpen] = useState(depth < openDepth);
|
|
78
70
|
const [showAll, setShowAll] = useState(false);
|
|
@@ -114,9 +106,10 @@ const TreeNode = (t0) => {
|
|
|
114
106
|
}
|
|
115
107
|
let t1;
|
|
116
108
|
if ($[10] !== compact || $[11] !== depth || $[12] !== name || $[13] !== open || $[14] !== openDepth || $[15] !== showAll || $[16] !== value) {
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
const
|
|
109
|
+
const keys = Array.isArray(value) ? [] : Object.keys(value);
|
|
110
|
+
const count = Array.isArray(value) ? value.length : keys.length;
|
|
111
|
+
const shown = open ? entriesOf(value, keys, showAll ? count : ENTRY_LIMIT) : [];
|
|
112
|
+
const hidden = count - shown.length;
|
|
120
113
|
let t2;
|
|
121
114
|
if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
|
|
122
115
|
t2 = () => setOpen(_temp);
|
|
@@ -151,23 +144,18 @@ const TreeNode = (t0) => {
|
|
|
151
144
|
$[25] = name;
|
|
152
145
|
$[26] = t8;
|
|
153
146
|
} else t8 = $[26];
|
|
154
|
-
|
|
155
|
-
if ($[27] !== value) {
|
|
156
|
-
t9 = summaryOf(value);
|
|
157
|
-
$[27] = value;
|
|
158
|
-
$[28] = t9;
|
|
159
|
-
} else t9 = $[28];
|
|
147
|
+
const t9 = Array.isArray(value) ? `[${count}]` : `{${count}}`;
|
|
160
148
|
let t10;
|
|
161
|
-
if ($[
|
|
149
|
+
if ($[27] !== t9) {
|
|
162
150
|
t10 = /* @__PURE__ */ jsx("span", {
|
|
163
151
|
className: "opacity-60",
|
|
164
152
|
children: t9
|
|
165
153
|
});
|
|
166
|
-
$[
|
|
167
|
-
$[
|
|
168
|
-
} else t10 = $[
|
|
154
|
+
$[27] = t9;
|
|
155
|
+
$[28] = t10;
|
|
156
|
+
} else t10 = $[28];
|
|
169
157
|
let t11;
|
|
170
|
-
if ($[
|
|
158
|
+
if ($[29] !== t10 || $[30] !== t4 || $[31] !== t7 || $[32] !== t8) {
|
|
171
159
|
t11 = /* @__PURE__ */ jsxs("button", {
|
|
172
160
|
type: "button",
|
|
173
161
|
onClick: t2,
|
|
@@ -178,12 +166,12 @@ const TreeNode = (t0) => {
|
|
|
178
166
|
t10
|
|
179
167
|
]
|
|
180
168
|
});
|
|
181
|
-
$[
|
|
182
|
-
$[
|
|
183
|
-
$[
|
|
184
|
-
$[
|
|
185
|
-
$[
|
|
186
|
-
} else t11 = $[
|
|
169
|
+
$[29] = t10;
|
|
170
|
+
$[30] = t4;
|
|
171
|
+
$[31] = t7;
|
|
172
|
+
$[32] = t8;
|
|
173
|
+
$[33] = t11;
|
|
174
|
+
} else t11 = $[33];
|
|
187
175
|
t1 = /* @__PURE__ */ jsxs("div", {
|
|
188
176
|
className: "min-w-0",
|
|
189
177
|
children: [t11, open ? /* @__PURE__ */ jsxs("div", {
|
|
@@ -326,64 +314,55 @@ const TreeWithCopy = (t0) => {
|
|
|
326
314
|
* Recursive JSON view. `compact` fits tool rows; copy always provides formatted JSON.
|
|
327
315
|
*/
|
|
328
316
|
const JSONTree = (t0) => {
|
|
329
|
-
const $ = c(
|
|
317
|
+
const $ = c(14);
|
|
330
318
|
const { value, openDepth: t1, compact: t2 } = t0;
|
|
331
319
|
const openDepth = t1 === void 0 ? 1 : t1;
|
|
332
320
|
const compact = t2 === void 0 ? false : t2;
|
|
333
321
|
let t3;
|
|
334
322
|
if ($[0] !== compact || $[1] !== value) {
|
|
335
|
-
t3 =
|
|
323
|
+
t3 = !isContainer(value) ? serialize(value, compact) : compact ? getInlineJson(value, INLINE_MAX) : void 0;
|
|
336
324
|
$[0] = compact;
|
|
337
325
|
$[1] = value;
|
|
338
326
|
$[2] = t3;
|
|
339
327
|
} else t3 = $[2];
|
|
340
|
-
const
|
|
328
|
+
const serialized = t3;
|
|
341
329
|
let t4;
|
|
342
|
-
if ($[3] !==
|
|
343
|
-
t4 =
|
|
344
|
-
$[3] =
|
|
345
|
-
$[4] =
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
t5 = JSON.stringify(value, null, 2);
|
|
353
|
-
$[7] = value;
|
|
354
|
-
$[8] = t5;
|
|
355
|
-
} else t5 = $[8];
|
|
356
|
-
const copyText = t5;
|
|
357
|
-
if (isLeaf) {
|
|
358
|
-
let t6;
|
|
359
|
-
if ($[9] !== compact || $[10] !== copyText || $[11] !== serialized) {
|
|
360
|
-
t6 = /* @__PURE__ */ jsx(InlineJson, {
|
|
330
|
+
if ($[3] !== value) {
|
|
331
|
+
t4 = () => JSON.stringify(value, null, 2);
|
|
332
|
+
$[3] = value;
|
|
333
|
+
$[4] = t4;
|
|
334
|
+
} else t4 = $[4];
|
|
335
|
+
const copyText = t4;
|
|
336
|
+
if (serialized !== void 0) {
|
|
337
|
+
let t5;
|
|
338
|
+
if ($[5] !== compact || $[6] !== copyText || $[7] !== serialized) {
|
|
339
|
+
t5 = /* @__PURE__ */ jsx(InlineJson, {
|
|
361
340
|
serialized,
|
|
362
341
|
copyText,
|
|
363
342
|
compact
|
|
364
343
|
});
|
|
365
|
-
$[
|
|
366
|
-
$[
|
|
367
|
-
$[
|
|
368
|
-
$[
|
|
369
|
-
} else
|
|
370
|
-
return
|
|
344
|
+
$[5] = compact;
|
|
345
|
+
$[6] = copyText;
|
|
346
|
+
$[7] = serialized;
|
|
347
|
+
$[8] = t5;
|
|
348
|
+
} else t5 = $[8];
|
|
349
|
+
return t5;
|
|
371
350
|
}
|
|
372
|
-
let
|
|
373
|
-
if ($[
|
|
374
|
-
|
|
351
|
+
let t5;
|
|
352
|
+
if ($[9] !== compact || $[10] !== copyText || $[11] !== openDepth || $[12] !== value) {
|
|
353
|
+
t5 = /* @__PURE__ */ jsx(TreeWithCopy, {
|
|
375
354
|
value,
|
|
376
355
|
openDepth,
|
|
377
356
|
copyText,
|
|
378
357
|
compact
|
|
379
358
|
});
|
|
380
|
-
$[
|
|
381
|
-
$[
|
|
382
|
-
$[
|
|
383
|
-
$[
|
|
384
|
-
$[
|
|
385
|
-
} else
|
|
386
|
-
return
|
|
359
|
+
$[9] = compact;
|
|
360
|
+
$[10] = copyText;
|
|
361
|
+
$[11] = openDepth;
|
|
362
|
+
$[12] = value;
|
|
363
|
+
$[13] = t5;
|
|
364
|
+
} else t5 = $[13];
|
|
365
|
+
return t5;
|
|
387
366
|
};
|
|
388
367
|
function _temp(prev) {
|
|
389
368
|
return !prev;
|