@anvia/studio 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/index.js +1850 -1046
  2. package/dist/index.js.map +1 -1
  3. package/dist/ui/assets/{ArrowClockwise.es-Dn4lp0ac.js → ArrowClockwise.es-DwsUsBcf.js} +2 -2
  4. package/dist/ui/assets/{ArrowClockwise.es-Dn4lp0ac.js.map → ArrowClockwise.es-DwsUsBcf.js.map} +1 -1
  5. package/dist/ui/assets/{Check.es-BaQZo8Jl.js → Check.es-DSgPB1Pv.js} +2 -2
  6. package/dist/ui/assets/{Check.es-BaQZo8Jl.js.map → Check.es-DSgPB1Pv.js.map} +1 -1
  7. package/dist/ui/assets/{Combination-Cj4UR5tg.js → Combination-BkVfYDnw.js} +2 -2
  8. package/dist/ui/assets/{Combination-Cj4UR5tg.js.map → Combination-BkVfYDnw.js.map} +1 -1
  9. package/dist/ui/assets/{Copy.es-CU5v9Pav.js → Copy.es-C6Vd2mhd.js} +2 -2
  10. package/dist/ui/assets/{Copy.es-CU5v9Pav.js.map → Copy.es-C6Vd2mhd.js.map} +1 -1
  11. package/dist/ui/assets/{MagnifyingGlass.es-C72UX0bz.js → MagnifyingGlass.es-DP3xtOg0.js} +2 -2
  12. package/dist/ui/assets/{MagnifyingGlass.es-C72UX0bz.js.map → MagnifyingGlass.es-DP3xtOg0.js.map} +1 -1
  13. package/dist/ui/assets/{Wrench.es-Q3fLRWow.js → Wrench.es-BEBc8KqB.js} +2 -2
  14. package/dist/ui/assets/{Wrench.es-Q3fLRWow.js.map → Wrench.es-BEBc8KqB.js.map} +1 -1
  15. package/dist/ui/assets/{agents-page-6DCSMWnZ.js → agents-page-BeBY9su3.js} +2 -2
  16. package/dist/ui/assets/{agents-page-6DCSMWnZ.js.map → agents-page-BeBY9su3.js.map} +1 -1
  17. package/dist/ui/assets/{badge-DUs0RCHV.js → badge-MfEDrFTO.js} +2 -2
  18. package/dist/ui/assets/{badge-DUs0RCHV.js.map → badge-MfEDrFTO.js.map} +1 -1
  19. package/dist/ui/assets/{button-BWxpVW85.js → button-jjWFI6nO.js} +2 -2
  20. package/dist/ui/assets/{button-BWxpVW85.js.map → button-jjWFI6nO.js.map} +1 -1
  21. package/dist/ui/assets/{dialog-DauYXFnG.js → dialog-7KiF6M8r.js} +2 -2
  22. package/dist/ui/assets/{dialog-DauYXFnG.js.map → dialog-7KiF6M8r.js.map} +1 -1
  23. package/dist/ui/assets/dist-Che9Yn41.js +2 -0
  24. package/dist/ui/assets/dist-Che9Yn41.js.map +1 -0
  25. package/dist/ui/assets/{dist-DD97Shn_.js → dist-Du1CgPgL.js} +2 -2
  26. package/dist/ui/assets/{dist-DD97Shn_.js.map → dist-Du1CgPgL.js.map} +1 -1
  27. package/dist/ui/assets/dist-xrWIzsxw.js +2 -0
  28. package/dist/ui/assets/dist-xrWIzsxw.js.map +1 -0
  29. package/dist/ui/assets/{graphs-page-BA0jzknS.js → graphs-page-DqwPocIY.js} +2 -2
  30. package/dist/ui/assets/{graphs-page-BA0jzknS.js.map → graphs-page-DqwPocIY.js.map} +1 -1
  31. package/dist/ui/assets/{icon-ksPSRwE8.js → icon-BivhXy0Y.js} +2 -2
  32. package/dist/ui/assets/{icon-ksPSRwE8.js.map → icon-BivhXy0Y.js.map} +1 -1
  33. package/dist/ui/assets/index-C0JlQS8v.js +67 -0
  34. package/dist/ui/assets/index-C0JlQS8v.js.map +1 -0
  35. package/dist/ui/assets/{input-DdUxz9c8.js → input-C35vs5wD.js} +2 -2
  36. package/dist/ui/assets/{input-DdUxz9c8.js.map → input-C35vs5wD.js.map} +1 -1
  37. package/dist/ui/assets/{knowledge-page-BVVc4w3w.js → knowledge-page-B28XrwD1.js} +2 -2
  38. package/dist/ui/assets/{knowledge-page-BVVc4w3w.js.map → knowledge-page-B28XrwD1.js.map} +1 -1
  39. package/dist/ui/assets/{mcps-page-BfF4B22U.js → mcps-page-Cp0cXu3k.js} +2 -2
  40. package/dist/ui/assets/{mcps-page-BfF4B22U.js.map → mcps-page-Cp0cXu3k.js.map} +1 -1
  41. package/dist/ui/assets/{memory-page-BQkt2BAW.js → memory-page-3S_mBxnY.js} +3 -3
  42. package/dist/ui/assets/memory-page-3S_mBxnY.js.map +1 -0
  43. package/dist/ui/assets/{pipelines-page-Xx2kQNCI.js → pipelines-page-CfRbR4Po.js} +2 -2
  44. package/dist/ui/assets/{pipelines-page-Xx2kQNCI.js.map → pipelines-page-CfRbR4Po.js.map} +1 -1
  45. package/dist/ui/assets/renderers-C5qoR_20.js +94 -0
  46. package/dist/ui/assets/renderers-C5qoR_20.js.map +1 -0
  47. package/dist/ui/assets/{request-DYxy87Kp.js → request-CpxtfF0E.js} +2 -2
  48. package/dist/ui/assets/{request-DYxy87Kp.js.map → request-CpxtfF0E.js.map} +1 -1
  49. package/dist/ui/assets/{sandboxes-page-BwidNA5G.js → sandboxes-page-GPkBA_26.js} +2 -2
  50. package/dist/ui/assets/{sandboxes-page-BwidNA5G.js.map → sandboxes-page-GPkBA_26.js.map} +1 -1
  51. package/dist/ui/assets/{select-C4MbvpHr.js → select-Bt5d0Z3n.js} +2 -2
  52. package/dist/ui/assets/{select-C4MbvpHr.js.map → select-Bt5d0Z3n.js.map} +1 -1
  53. package/dist/ui/assets/sessions-page-CDvKPoVi.js +2 -0
  54. package/dist/ui/assets/{sessions-page-C3dJDjJb.js.map → sessions-page-CDvKPoVi.js.map} +1 -1
  55. package/dist/ui/assets/{status-page-92JD9Hj8.js → status-page-BeUxNJNp.js} +2 -2
  56. package/dist/ui/assets/{status-page-92JD9Hj8.js.map → status-page-BeUxNJNp.js.map} +1 -1
  57. package/dist/ui/assets/{studio-CtQdOoHK.js → studio-DeO7ueA2.js} +2 -2
  58. package/dist/ui/assets/{studio-CtQdOoHK.js.map → studio-DeO7ueA2.js.map} +1 -1
  59. package/dist/ui/assets/{style-CrHHNFw2.js → style-2z5K_w5A.js} +2 -2
  60. package/dist/ui/assets/{style-CrHHNFw2.js.map → style-2z5K_w5A.js.map} +1 -1
  61. package/dist/ui/assets/team-playground-YxRSJeOf.js +2 -0
  62. package/dist/ui/assets/team-playground-YxRSJeOf.js.map +1 -0
  63. package/dist/ui/assets/{textarea-gPj9-ALc.js → textarea-BqjRR-2a.js} +2 -2
  64. package/dist/ui/assets/{textarea-gPj9-ALc.js.map → textarea-BqjRR-2a.js.map} +1 -1
  65. package/dist/ui/assets/{tool-runner-xLspgGPa.js → tool-runner-DvhSexHU.js} +2 -2
  66. package/dist/ui/assets/{tool-runner-xLspgGPa.js.map → tool-runner-DvhSexHU.js.map} +1 -1
  67. package/dist/ui/assets/{tools-page-BMyx2xRT.js → tools-page-B613Kgf3.js} +2 -2
  68. package/dist/ui/assets/{tools-page-BMyx2xRT.js.map → tools-page-B613Kgf3.js.map} +1 -1
  69. package/dist/ui/assets/trace-browser-B4cu-jFZ.js +4 -0
  70. package/dist/ui/assets/trace-browser-B4cu-jFZ.js.map +1 -0
  71. package/dist/ui/assets/{transcript-item-Bl3Yl-NT.js → transcript-item-B_Lyu12N.js} +2 -2
  72. package/dist/ui/assets/{transcript-item-Bl3Yl-NT.js.map → transcript-item-B_Lyu12N.js.map} +1 -1
  73. package/dist/ui/assets/{with-selector-BIQdjRiO.js → with-selector-CfGDDu3e.js} +2 -2
  74. package/dist/ui/assets/{with-selector-BIQdjRiO.js.map → with-selector-CfGDDu3e.js.map} +1 -1
  75. package/dist/ui/index.html +16 -16
  76. package/package.json +12 -12
  77. package/dist/ui/assets/dist-BmLOFYIW.js +0 -2
  78. package/dist/ui/assets/dist-BmLOFYIW.js.map +0 -1
  79. package/dist/ui/assets/dist-CHLp-Np4.js +0 -2
  80. package/dist/ui/assets/dist-CHLp-Np4.js.map +0 -1
  81. package/dist/ui/assets/index-Dyjst4Yt.js +0 -61
  82. package/dist/ui/assets/index-Dyjst4Yt.js.map +0 -1
  83. package/dist/ui/assets/memory-page-BQkt2BAW.js.map +0 -1
  84. package/dist/ui/assets/renderers-CrjMPAR2.js +0 -94
  85. package/dist/ui/assets/renderers-CrjMPAR2.js.map +0 -1
  86. package/dist/ui/assets/sessions-page-C3dJDjJb.js +0 -2
  87. package/dist/ui/assets/team-playground-GcG3j0Hl.js +0 -2
  88. package/dist/ui/assets/team-playground-GcG3j0Hl.js.map +0 -1
  89. package/dist/ui/assets/trace-browser-Axd-aif6.js +0 -4
  90. package/dist/ui/assets/trace-browser-Axd-aif6.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"memory-page-BQkt2BAW.js","names":[],"sources":["../../../../core/dist/chunk-IDNL6IH4.js","../../../src/ui/app/modules/memory/memory-generation-ledger.tsx","../../../src/ui/app/modules/memory/memory-page.tsx"],"sourcesContent":["import {\n isJsonValue\n} from \"./chunk-4C7AXYOM.js\";\n\n// src/completion/types.ts\nfunction reasoningDisplayText(reasoning) {\n const details = \"type\" in reasoning ? reasoning.details : reasoning;\n if (details === void 0) {\n return \"type\" in reasoning ? reasoning.text : \"\";\n }\n return details.flatMap((item) => {\n if (item.type === \"text\" || item.type === \"summary\") {\n return [item.text];\n }\n return [];\n }).join(\"\");\n}\nfunction isProviderTool(value) {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const candidate = value;\n return candidate.kind === \"provider\" && typeof candidate.provider === \"string\" && candidate.provider.trim().length > 0 && typeof candidate.name === \"string\" && candidate.name.trim().length > 0 && (candidate.configuration === void 0 || typeof candidate.configuration === \"object\" && candidate.configuration !== null && !Array.isArray(candidate.configuration) && isJsonValue(candidate.configuration));\n}\nfunction calculateContextUsage(usage, model) {\n if (model === void 0 || !Number.isFinite(usage.inputTokens) || usage.inputTokens <= 0 || !Number.isFinite(model.context.contextWindow) || model.context.contextWindow <= 0) {\n return void 0;\n }\n const usedTokens = Math.max(0, usage.inputTokens);\n const remainingTokens = Math.max(0, model.context.contextWindow - usedTokens);\n const usedPercent = Math.min(100, usedTokens / model.context.contextWindow * 100);\n return {\n model,\n usedTokens,\n remainingTokens,\n usedPercent,\n remainingPercent: 100 - usedPercent\n };\n}\nfunction withContextUsage(response, model) {\n const contextUsage = calculateContextUsage(response.usage, model);\n return contextUsage === void 0 ? response : { ...response, contextUsage };\n}\nfunction resolveModelContextLimits(modelId, catalog, override) {\n return override ?? catalog[modelId];\n}\nvar Usage = {\n empty() {\n return {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n cachedInputTokens: 0,\n cacheCreationInputTokens: 0\n };\n },\n add(left, right) {\n const result = {\n inputTokens: left.inputTokens + right.inputTokens,\n outputTokens: left.outputTokens + right.outputTokens,\n totalTokens: left.totalTokens + right.totalTokens,\n cachedInputTokens: left.cachedInputTokens + right.cachedInputTokens,\n cacheCreationInputTokens: left.cacheCreationInputTokens + right.cacheCreationInputTokens\n };\n const details = addUsageDetails(left, right);\n if (details !== void 0) {\n result.details = details;\n }\n return result;\n },\n isEmpty(usage) {\n return isEmptyUsage(usage) && (usage.details === void 0 || Object.values(usage.details).every((value) => value === 0));\n }\n};\nfunction addUsageDetails(left, right) {\n if (isEmptyUsage(left) && left.details === void 0) {\n return right.details === void 0 ? void 0 : { ...right.details };\n }\n if (isEmptyUsage(right) && right.details === void 0) {\n return left.details === void 0 ? void 0 : { ...left.details };\n }\n if (left.details === void 0 || right.details === void 0) {\n return void 0;\n }\n const details = { ...left.details };\n for (const [key, value] of Object.entries(right.details)) {\n details[key] = (details[key] ?? 0) + value;\n }\n return details;\n}\nfunction isEmptyUsage(usage) {\n return usage.inputTokens === 0 && usage.outputTokens === 0 && usage.totalTokens === 0 && usage.cachedInputTokens === 0 && usage.cacheCreationInputTokens === 0;\n}\nfunction getAssistantGenerationMetadata(message) {\n if (message.role !== \"assistant\" || !isJsonObjectValue(message.metadata)) {\n return void 0;\n }\n const frameworkMetadata = message.metadata.anvia;\n if (!isJsonObjectValue(frameworkMetadata)) {\n return void 0;\n }\n const generation = frameworkMetadata.generation;\n if (!isJsonObjectValue(generation) || typeof generation.provider !== \"string\" || typeof generation.modelId !== \"string\" || !isUsageValue(generation.usage)) {\n return void 0;\n }\n let usage = { ...generation.usage };\n if (generation.usage.details !== void 0) {\n usage = { ...usage, details: { ...generation.usage.details } };\n }\n const metadata = {\n provider: generation.provider,\n modelId: generation.modelId,\n usage\n };\n if (isCompletionFinishReason(generation.finishReason)) {\n metadata.finishReason = generation.finishReason;\n }\n if (typeof generation.providerFinishReason === \"string\") {\n metadata.providerFinishReason = generation.providerFinishReason;\n }\n if (isContextUsageValue(generation.contextUsage)) {\n metadata.contextUsage = {\n ...generation.contextUsage,\n model: {\n ...generation.contextUsage.model,\n context: { ...generation.contextUsage.model.context }\n }\n };\n }\n if (isCompletionSourceArray(generation.sources)) {\n metadata.sources = generation.sources.map((source) => ({ ...source }));\n }\n if (isProviderToolCallArray(generation.providerToolCalls)) {\n metadata.providerToolCalls = generation.providerToolCalls.map((toolCall) => {\n let copy = { ...toolCall };\n if (toolCall.details !== void 0) {\n copy = { ...copy, details: { ...toolCall.details } };\n }\n return copy;\n });\n }\n return metadata;\n}\nfunction isJsonObjectValue(value) {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction isContextUsageValue(value) {\n if (!isJsonObjectValue(value) || !isJsonObjectValue(value.model)) {\n return false;\n }\n const context = value.model.context;\n if (typeof value.model.modelId === \"string\" && isJsonObjectValue(context) && isPositiveFiniteNumber(context.contextWindow) && isOptionalPositiveFiniteNumber(context.maxInputTokens) && isOptionalPositiveFiniteNumber(context.maxOutputTokens) && isNonnegativeFiniteNumber(value.usedTokens) && isNonnegativeFiniteNumber(value.remainingTokens) && isPercentage(value.usedPercent) && isPercentage(value.remainingPercent)) {\n const contextWindow = context.contextWindow;\n const remainingTokens = Math.max(0, contextWindow - value.usedTokens);\n const usedPercent = Math.min(100, value.usedTokens / contextWindow * 100);\n const remainingPercent = remainingTokens / contextWindow * 100;\n return value.remainingTokens === remainingTokens && approximatelyEqual(value.usedPercent, usedPercent) && approximatelyEqual(value.remainingPercent, remainingPercent);\n }\n return false;\n}\nfunction approximatelyEqual(left, right) {\n const scale = Math.max(1, Math.abs(left), Math.abs(right));\n return Math.abs(left - right) <= Number.EPSILON * scale * 8;\n}\nfunction isPositiveFiniteNumber(value) {\n return isNonnegativeFiniteNumber(value) && value > 0;\n}\nfunction isOptionalPositiveFiniteNumber(value) {\n return value === void 0 || isPositiveFiniteNumber(value);\n}\nfunction isPercentage(value) {\n return isNonnegativeFiniteNumber(value) && value <= 100;\n}\nfunction isUsageValue(value) {\n if (!isJsonObjectValue(value)) {\n return false;\n }\n return isNonnegativeFiniteNumber(value.inputTokens) && isNonnegativeFiniteNumber(value.outputTokens) && isNonnegativeFiniteNumber(value.totalTokens) && isNonnegativeFiniteNumber(value.cachedInputTokens) && isNonnegativeFiniteNumber(value.cacheCreationInputTokens) && isUsageDetailsValue(value.details);\n}\nfunction isNonnegativeFiniteNumber(value) {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0;\n}\nfunction isUsageDetailsValue(value) {\n if (value === void 0) {\n return true;\n }\n if (!isJsonObjectValue(value)) {\n return false;\n }\n let total;\n let bucketSum = 0;\n for (const [key, detail] of Object.entries(value)) {\n if (detail === void 0 || !isNonnegativeFiniteNumber(detail)) {\n return false;\n }\n if (key === \"total\") {\n total = detail;\n } else {\n bucketSum += detail;\n }\n }\n return total !== void 0 && total === bucketSum;\n}\nfunction isCompletionSourceArray(value) {\n return Array.isArray(value) && value.every(\n (source) => isJsonObjectValue(source) && source.type === \"url\" && typeof source.url === \"string\" && (source.title === void 0 || typeof source.title === \"string\") && (source.id === void 0 || typeof source.id === \"string\") && (source.startIndex === void 0 || typeof source.startIndex === \"number\") && (source.endIndex === void 0 || typeof source.endIndex === \"number\")\n );\n}\nfunction isProviderToolCallArray(value) {\n return Array.isArray(value) && value.every(\n (toolCall) => isJsonObjectValue(toolCall) && typeof toolCall.id === \"string\" && typeof toolCall.name === \"string\" && (toolCall.status === void 0 || typeof toolCall.status === \"string\") && (toolCall.details === void 0 || isJsonObjectValue(toolCall.details))\n );\n}\nfunction isCompletionFinishReason(value) {\n return value === \"stop\" || value === \"length\" || value === \"content-filter\" || value === \"tool-calls\" || value === \"other\";\n}\nvar CompletionCapabilityError = class extends Error {\n constructor(message) {\n super(message);\n this.name = \"CompletionCapabilityError\";\n }\n};\nfunction assertCompletionRequestSupported(model, request, options = {}) {\n const modelLabel = `${model.provider}:${model.modelId}`;\n const capabilities = model.capabilities;\n assertCompletionControlsSupported(model, request.controls);\n if (options.streaming === true && !capabilities.streaming) {\n throw new CompletionCapabilityError(`${modelLabel} does not support streaming completions.`);\n }\n if (request.tools.length > 0 && !capabilities.tools) {\n throw new CompletionCapabilityError(`${modelLabel} does not support tool definitions.`);\n }\n if ((request.providerTools?.length ?? 0) > 0 && capabilities.providerTools !== true) {\n throw new CompletionCapabilityError(`${modelLabel} does not support provider-executed tools.`);\n }\n if (request.toolChoice !== void 0 && !capabilities.toolChoice) {\n throw new CompletionCapabilityError(`${modelLabel} does not support tool choice.`);\n }\n if (request.outputSchema !== void 0 && !capabilities.outputSchema) {\n throw new CompletionCapabilityError(`${modelLabel} does not support output schemas.`);\n }\n if (!capabilities.imageInput && requestHasImageInput(request)) {\n throw new CompletionCapabilityError(`${modelLabel} does not support image input.`);\n }\n if (!capabilities.documentInput && requestHasFileDocumentInput(request)) {\n throw new CompletionCapabilityError(`${modelLabel} does not support document file input.`);\n }\n}\nfunction assertCompletionControlsSupported(model, controls) {\n const modelLabel = `${model.provider}:${model.modelId}`;\n for (const [controlId, value] of Object.entries(controls ?? {})) {\n if (value === void 0) continue;\n const modelControls = model.controls;\n const control = modelControls !== void 0 && Object.hasOwn(modelControls, controlId) ? modelControls[controlId] : void 0;\n if (control === void 0) {\n throw new CompletionCapabilityError(\n `${modelLabel} does not support completion control \"${controlId}\".`\n );\n }\n if (!control.options.includes(value)) {\n throw new CompletionCapabilityError(\n `${modelLabel} completion control \"${controlId}\" does not support value \"${value}\".`\n );\n }\n }\n}\nfunction textFromAssistantContent(content) {\n return content.flatMap((item) => item.type === \"text\" ? [item.text] : []).join(\"\\n\");\n}\nfunction requestHasImageInput(request) {\n return request.chatHistory.some(\n (message) => message.role === \"system\" || typeof message.content === \"string\" ? false : message.content.some((content) => content.type === \"image\")\n );\n}\nfunction requestHasFileDocumentInput(request) {\n return request.chatHistory.some(\n (message) => message.role === \"user\" && typeof message.content !== \"string\" ? message.content.some((content) => content.type === \"file\" && content.data.type !== \"text\") : false\n );\n}\n\nexport {\n reasoningDisplayText,\n isProviderTool,\n calculateContextUsage,\n withContextUsage,\n resolveModelContextLimits,\n Usage,\n getAssistantGenerationMetadata,\n CompletionCapabilityError,\n assertCompletionRequestSupported,\n assertCompletionControlsSupported,\n textFromAssistantContent\n};\n//# sourceMappingURL=chunk-IDNL6IH4.js.map","import { getAssistantGenerationMetadata, type Message } from \"@anvia/core/completion\";\nimport type { StudioMemoryMessageRecord } from \"../../../../types\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { formatRelativeTime } from \"../shared/format\";\n\ntype AssistantMessage = Extract<Message, { role: \"assistant\" }>;\n\nexport type MemoryGenerationRow = {\n position: number;\n runId: string;\n turn: number;\n createdAt: string;\n preview: string;\n generation: ReturnType<typeof getAssistantGenerationMetadata>;\n};\n\nexport function memoryGenerationRows(records: StudioMemoryMessageRecord[]): MemoryGenerationRow[] {\n return records.flatMap((record) => {\n if (record.message.role !== \"assistant\") {\n return [];\n }\n return [\n {\n position: record.position,\n runId: record.runId,\n turn: record.turn,\n createdAt: record.createdAt,\n preview: assistantPreview(record.message),\n generation: getAssistantGenerationMetadata(record.message),\n },\n ];\n });\n}\n\nexport function MemoryGenerationLedger(props: { records: StudioMemoryMessageRecord[] }) {\n const rows = memoryGenerationRows(props.records);\n return (\n <section className=\"grid min-w-0 overflow-hidden border-y border-hair\">\n <header className=\"flex min-h-11 items-center justify-between gap-3 bg-muted px-3 text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n <span>Assistant responses</span>\n <span className=\"font-medium normal-case tracking-normal\">{rows.length} responses</span>\n </header>\n {rows.length === 0 ? (\n <div className=\"border-t border-hair px-4 py-8 text-center text-sm text-muted-foreground\">\n No persisted assistant responses.\n </div>\n ) : (\n <div className=\"grid divide-y divide-hair border-t border-hair\">\n {rows.map((row) => (\n <GenerationRow row={row} key={`${row.position}:${row.runId}`} />\n ))}\n </div>\n )}\n </section>\n );\n}\n\nfunction GenerationRow(props: { row: MemoryGenerationRow }) {\n const generation = props.row.generation;\n return (\n <article className=\"grid min-w-0 gap-3 px-3 py-4\">\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-2\">\n <div className=\"flex min-w-0 flex-wrap items-center gap-2\">\n <Badge className=\"border-hair bg-muted text-foreground\">Turn {props.row.turn}</Badge>\n {generation === undefined ? (\n <Badge className=\"border-hair bg-background text-muted-foreground\">\n Usage unavailable\n </Badge>\n ) : (\n <>\n <Badge className=\"border-hair bg-muted text-foreground\">{generation.provider}</Badge>\n <Badge className=\"max-w-full truncate border-hair bg-muted text-foreground\">\n {generation.modelId}\n </Badge>\n </>\n )}\n </div>\n <span className=\"shrink-0 text-xs text-muted-foreground\">\n {formatRelativeTime(props.row.createdAt)}\n </span>\n </div>\n <p className=\"m-0 whitespace-pre-wrap break-words text-sm leading-6 text-foreground\">\n {props.row.preview}\n </p>\n {generation === undefined ? null : (\n <div className=\"flex min-w-0 flex-wrap gap-x-4 gap-y-1 text-xs text-muted-foreground\">\n <UsageMetric label=\"total\" value={generation.usage.totalTokens} suffix=\" tokens\" />\n <UsageMetric label=\"input\" value={generation.usage.inputTokens} />\n <UsageMetric label=\"output\" value={generation.usage.outputTokens} />\n <UsageMetric label=\"cached\" value={generation.usage.cachedInputTokens} />\n <UsageMetric label=\"cache create\" value={generation.usage.cacheCreationInputTokens} />\n </div>\n )}\n </article>\n );\n}\n\nfunction UsageMetric(props: { label: string; value: number; suffix?: string | undefined }) {\n return (\n <span>\n {props.label} {props.value.toLocaleString()}\n {props.suffix}\n </span>\n );\n}\n\nfunction assistantPreview(message: AssistantMessage): string {\n if (typeof message.content === \"string\") {\n return message.content.trim().length > 0\n ? truncatePreview(message.content)\n : \"Assistant response\";\n }\n const text = message.content\n .flatMap((content) => (content.type === \"text\" ? [content.text] : []))\n .join(\"\\n\")\n .trim();\n if (text.length > 0) {\n return truncatePreview(text);\n }\n\n const toolNames = message.content.flatMap((content) =>\n content.type === \"tool-call\" ? [content.toolName] : [],\n );\n if (toolNames.length > 0) {\n return `Tool call${toolNames.length === 1 ? \"\" : \"s\"}: ${toolNames.join(\", \")}`;\n }\n\n const reasoning = message.content\n .flatMap((content) => (content.type === \"reasoning\" ? [content.text] : []))\n .join(\"\\n\")\n .trim();\n if (reasoning.length > 0) {\n return truncatePreview(reasoning);\n }\n\n const imageCount = message.content.filter((content) => content.type === \"image\").length;\n return imageCount > 0\n ? `${imageCount} generated image${imageCount === 1 ? \"\" : \"s\"}`\n : \"Assistant response\";\n}\n\nfunction truncatePreview(value: string): string {\n const compact = value.replace(/\\s+/g, \" \").trim();\n return compact.length > 220 ? `${compact.slice(0, 217)}...` : compact;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n StudioConfig,\n StudioMemorySourceConversationMessages,\n StudioMemorySourceConversationSteps,\n StudioMemorySourceConversationSummary,\n StudioMemorySourceConversationsPage,\n StudioMemorySourceSummary,\n StudioMemorySourcesPage,\n StudioMemorySourceUsersPage,\n} from \"../../../../types\";\nimport { Badge } from \"../../components/ui/badge\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/ui/select\";\nimport {\n StudioEmptyState,\n StudioHeaderMetric,\n StudioPageContent,\n StudioPageHeader,\n StudioPageShell,\n} from \"../../components/ui/studio\";\nimport { formatRelativeTime } from \"../shared/format\";\nimport { JsonSyntax } from \"../shared/renderers\";\nimport { MemoryGenerationLedger } from \"./memory-generation-ledger\";\n\nexport function MemoryPage(props: { agents: StudioConfig[\"agents\"]; enabled: boolean }) {\n const [sources, setSources] = useState<StudioMemorySourceSummary[]>([]);\n const [selectedSourceRef, setSelectedSourceRef] = useState(\"\");\n const [users, setUsers] = useState<StudioMemorySourceUsersPage[\"users\"]>([]);\n const [conversations, setConversations] = useState<StudioMemorySourceConversationSummary[]>([]);\n const [selectedUserId, setSelectedUserId] = useState(\"\");\n const [selectedConversationRef, setSelectedConversationRef] = useState(\"\");\n const [messages, setMessages] = useState<StudioMemorySourceConversationMessages | undefined>();\n const [steps, setSteps] = useState<StudioMemorySourceConversationSteps | undefined>();\n const [sourcesLoading, setSourcesLoading] = useState(false);\n const [loading, setLoading] = useState(false);\n const [detailLoading, setDetailLoading] = useState(false);\n const [error, setError] = useState(\"\");\n const memoryRequest = useRef(0);\n\n const selectedSource = sources.find((source) => source.ref === selectedSourceRef);\n\n const loadSources = useCallback(async () => {\n if (!props.enabled) {\n setSources([]);\n setSelectedSourceRef(\"\");\n return;\n }\n setSourcesLoading(true);\n setError(\"\");\n try {\n const response = await fetch(\"/memory/sources\");\n if (!response.ok) throw new Error(`Memory sources failed with HTTP ${response.status}`);\n const body = (await response.json()) as StudioMemorySourcesPage;\n setSources(body.sources);\n setSelectedSourceRef((current) =>\n body.sources.some((source) => source.ref === current)\n ? current\n : defaultSourceRef(body.sources),\n );\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError.message : String(loadError));\n } finally {\n setSourcesLoading(false);\n }\n }, [props.enabled]);\n\n useEffect(() => {\n void loadSources();\n }, [loadSources]);\n\n const loadMemory = useCallback(async () => {\n const requestId = memoryRequest.current + 1;\n memoryRequest.current = requestId;\n if (!props.enabled || selectedSource === undefined || !selectedSource.available) {\n setUsers([]);\n setConversations([]);\n setMessages(undefined);\n setSteps(undefined);\n setLoading(false);\n return;\n }\n setLoading(true);\n setError(\"\");\n try {\n const sourcePath = `/memory/sources/${encodeURIComponent(selectedSource.ref)}`;\n const [usersResponse, conversationsResponse] = await Promise.all([\n fetch(`${sourcePath}/users?limit=50`),\n fetch(`${sourcePath}/conversations?limit=100`),\n ]);\n if (!usersResponse.ok) {\n throw new Error(`Memory users failed with HTTP ${usersResponse.status}`);\n }\n if (!conversationsResponse.ok) {\n throw new Error(`Memory conversations failed with HTTP ${conversationsResponse.status}`);\n }\n const usersBody = (await usersResponse.json()) as StudioMemorySourceUsersPage;\n const conversationsBody =\n (await conversationsResponse.json()) as StudioMemorySourceConversationsPage;\n if (memoryRequest.current !== requestId) return;\n setUsers(usersBody.users);\n setConversations(conversationsBody.conversations);\n setSelectedConversationRef(\n (current) =>\n conversationsBody.conversations.find((conversation) => conversation.ref === current)\n ?.ref ??\n conversationsBody.conversations[0]?.ref ??\n \"\",\n );\n } catch (loadError) {\n if (memoryRequest.current === requestId) {\n setError(loadError instanceof Error ? loadError.message : String(loadError));\n }\n } finally {\n if (memoryRequest.current === requestId) setLoading(false);\n }\n }, [props.enabled, selectedSource]);\n\n useEffect(() => {\n setSelectedUserId(\"\");\n setSelectedConversationRef(\"\");\n setUsers([]);\n setConversations([]);\n setMessages(undefined);\n setSteps(undefined);\n void loadMemory();\n }, [loadMemory]);\n\n useEffect(() => {\n if (\n !props.enabled ||\n selectedSource === undefined ||\n !selectedSource.available ||\n selectedConversationRef.length === 0\n ) {\n setMessages(undefined);\n setSteps(undefined);\n return;\n }\n const sourceRef = selectedSource.ref;\n let cancelled = false;\n async function loadDetail() {\n setDetailLoading(true);\n setError(\"\");\n try {\n const conversationPath = `/memory/sources/${encodeURIComponent(\n sourceRef,\n )}/conversations/${encodeURIComponent(selectedConversationRef)}`;\n const [messagesResponse, stepsResponse] = await Promise.all([\n fetch(`${conversationPath}/messages`),\n fetch(`${conversationPath}/steps`),\n ]);\n if (!messagesResponse.ok) {\n throw new Error(`Conversation messages failed with HTTP ${messagesResponse.status}`);\n }\n if (!stepsResponse.ok) {\n throw new Error(`Conversation steps failed with HTTP ${stepsResponse.status}`);\n }\n if (!cancelled) {\n setMessages((await messagesResponse.json()) as StudioMemorySourceConversationMessages);\n setSteps((await stepsResponse.json()) as StudioMemorySourceConversationSteps);\n }\n } catch (loadError) {\n if (!cancelled) {\n setError(loadError instanceof Error ? loadError.message : String(loadError));\n setMessages(undefined);\n setSteps(undefined);\n }\n } finally {\n if (!cancelled) setDetailLoading(false);\n }\n }\n void loadDetail();\n return () => {\n cancelled = true;\n };\n }, [props.enabled, selectedConversationRef, selectedSource]);\n\n const visibleConversations = useMemo(\n () =>\n selectedUserId.length === 0\n ? conversations\n : conversations.filter((conversation) => conversation.userId === selectedUserId),\n [conversations, selectedUserId],\n );\n const totals = useMemo(() => memoryTotals(users, conversations), [conversations, users]);\n const selectedConversation =\n visibleConversations.find((conversation) => conversation.ref === selectedConversationRef) ??\n visibleConversations[0];\n\n useEffect(() => {\n if (visibleConversations.length === 0) {\n setSelectedConversationRef(\"\");\n return;\n }\n if (\n !visibleConversations.some((conversation) => conversation.ref === selectedConversationRef)\n ) {\n setSelectedConversationRef(visibleConversations[0]?.ref ?? \"\");\n }\n }, [selectedConversationRef, visibleConversations]);\n\n return (\n <StudioPageShell className=\"grid-rows-[auto_minmax(0,1fr)]\" aria-label=\"Memory\">\n <StudioPageHeader\n title=\"Memory\"\n description=\"Inspect persisted agent conversations directly. Studio sessions appear only as a fallback for agents without configured memory.\"\n action={\n <div className=\"flex min-w-0 flex-wrap justify-end gap-2 max-sm:justify-start\">\n {sources.length === 0 ? null : (\n <Select value={selectedSourceRef} onValueChange={setSelectedSourceRef}>\n <SelectTrigger className=\"h-8 min-h-8 w-60 rounded-md border-border text-xs max-sm:w-full\">\n <SelectValue placeholder=\"Memory source\" />\n </SelectTrigger>\n <SelectContent align=\"end\">\n {sources.map((source) => (\n <SelectItem value={source.ref} key={source.ref}>\n {source.label}\n {source.available ? \"\" : \" (unavailable)\"}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <StudioHeaderMetric label=\"users\" value={totals.userCount} />\n <StudioHeaderMetric label=\"conversations\" value={totals.conversationCount} />\n <StudioHeaderMetric label=\"messages\" value={totals.messageCount} />\n <Button\n className=\"h-8 min-h-8 rounded-md px-3 text-xs\"\n type=\"button\"\n variant=\"secondary\"\n disabled={sourcesLoading || loading}\n onClick={() => void loadSources()}\n >\n Refresh\n </Button>\n </div>\n }\n />\n\n <StudioPageContent className=\"overflow-hidden\">\n {!props.enabled ? (\n <StudioEmptyState\n title=\"Memory unavailable\"\n text=\"No agent memory or Studio session store is configured.\"\n />\n ) : sourcesLoading && sources.length === 0 ? (\n <StudioEmptyState title=\"Loading memory\" text=\"Discovering configured memory sources.\" />\n ) : error.length > 0 && sources.length === 0 ? (\n <StudioEmptyState title=\"Memory error\" text={error} />\n ) : selectedSource === undefined ? (\n <StudioEmptyState title=\"No memory sources\" text=\"No registered agent exposes memory.\" />\n ) : !selectedSource.available ? (\n <UnavailableSource source={selectedSource} />\n ) : loading && conversations.length === 0 ? (\n <StudioEmptyState title=\"Loading memory\" text={`Reading ${selectedSource.label}.`} />\n ) : error.length > 0 && conversations.length === 0 ? (\n <StudioEmptyState title=\"Memory error\" text={error} />\n ) : conversations.length === 0 ? (\n <MemoryEmptyDashboard\n source={selectedSource}\n userCount={users.length}\n onRefresh={() => void loadMemory()}\n />\n ) : (\n <div\n className={[\n \"grid h-full min-h-0 overflow-hidden\",\n error.length === 0 ? \"grid-rows-[minmax(0,1fr)]\" : \"grid-rows-[auto_minmax(0,1fr)]\",\n ].join(\" \")}\n >\n {error.length === 0 ? null : <InlineError message={error} />}\n <div className=\"grid min-h-0 grid-cols-[260px_minmax(320px,0.78fr)_minmax(0,1.22fr)] overflow-hidden border-t border-hair max-xl:grid-cols-[240px_minmax(0,1fr)] max-xl:grid-rows-[minmax(240px,0.42fr)_minmax(0,1fr)] max-md:grid-cols-1 max-md:grid-rows-[auto_minmax(240px,0.38fr)_minmax(0,1fr)]\">\n <MemoryUserRail\n users={users}\n selectedUserId={selectedUserId}\n totalConversations={conversations.length}\n onSelect={setSelectedUserId}\n />\n <ConversationLedger\n agents={props.agents}\n conversations={visibleConversations}\n selectedConversationRef={selectedConversation?.ref ?? \"\"}\n source={selectedSource}\n onSelect={setSelectedConversationRef}\n />\n <ConversationDetail\n agents={props.agents}\n conversation={selectedConversation}\n detailLoading={detailLoading}\n messages={messages}\n source={selectedSource}\n steps={steps}\n />\n </div>\n </div>\n )}\n </StudioPageContent>\n </StudioPageShell>\n );\n}\n\nfunction MemoryUserRail(props: {\n users: StudioMemorySourceUsersPage[\"users\"];\n selectedUserId: string;\n totalConversations: number;\n onSelect: (userId: string) => void;\n}) {\n return (\n <aside className=\"min-h-0 overflow-auto border-r border-hair pr-3 max-md:border-b max-md:border-r-0 max-md:pr-0\">\n <div className=\"grid gap-3 py-4 pr-3 max-md:pr-0\">\n <SectionLabel label=\"Users\" value={props.users.length} />\n <UserFilterButton\n active={props.selectedUserId.length === 0}\n title=\"All users\"\n detail={`${props.totalConversations} conversations`}\n onClick={() => props.onSelect(\"\")}\n />\n <div className=\"grid gap-1\">\n {props.users.map((user) => (\n <UserFilterButton\n active={props.selectedUserId === user.userId}\n title={user.userId}\n detail={`${user.conversationCount} conversations / ${formatRelativeTime(\n user.lastInteractionAt,\n )}`}\n key={user.userId}\n onClick={() => props.onSelect(user.userId)}\n />\n ))}\n </div>\n </div>\n </aside>\n );\n}\n\nfunction UserFilterButton(props: {\n active: boolean;\n title: string;\n detail: string;\n onClick: () => void;\n}) {\n return (\n <button\n className={[\n \"grid min-w-0 gap-1 rounded-lg border border-transparent px-3 py-2.5 text-left transition duration-200 hover:border-hair hover:bg-transparent hover:text-foreground focus-visible:border-ring focus-visible:outline-none\",\n props.active ? \"border-hair bg-row-selected\" : \"\",\n ].join(\" \")}\n type=\"button\"\n onClick={props.onClick}\n >\n <span className=\"min-w-0 truncate text-sm font-semibold text-foreground\">{props.title}</span>\n <span className=\"min-w-0 truncate text-xs leading-5 text-muted-foreground\">\n {props.detail}\n </span>\n </button>\n );\n}\n\nfunction ConversationLedger(props: {\n agents: StudioConfig[\"agents\"];\n conversations: StudioMemorySourceConversationSummary[];\n selectedConversationRef: string;\n source: StudioMemorySourceSummary;\n onSelect: (conversationRef: string) => void;\n}) {\n return (\n <section className=\"min-h-0 overflow-auto border-r border-hair px-4 max-xl:border-r-0 max-xl:pr-0 max-md:border-b max-md:px-0\">\n <div className=\"grid gap-3 py-4\">\n <SectionLabel label=\"Conversations\" value={props.conversations.length} />\n {props.conversations.length === 0 ? (\n <div className=\"border-y border-dashed border-hair px-3 py-8 text-center text-sm text-muted-foreground\">\n No conversations for this user.\n </div>\n ) : (\n <div className=\"grid border-y border-hair\">\n {props.conversations.map((conversation) => (\n <ConversationRow\n active={conversation.ref === props.selectedConversationRef}\n agentName={sourceAgentLabel(props.agents, props.source, conversation.agentIds)}\n conversation={conversation}\n key={conversation.ref}\n onSelect={() => props.onSelect(conversation.ref)}\n />\n ))}\n </div>\n )}\n </div>\n </section>\n );\n}\n\nfunction ConversationRow(props: {\n conversation: StudioMemorySourceConversationSummary;\n agentName: string;\n active: boolean;\n onSelect: () => void;\n}) {\n return (\n <button\n className={[\n \"grid min-w-0 gap-2 border-b border-hair px-3 py-3 text-left transition duration-200 last:border-b-0 hover:bg-transparent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\",\n props.active ? \"bg-row-selected\" : \"\",\n ].join(\" \")}\n type=\"button\"\n onClick={props.onSelect}\n >\n <div className=\"flex min-w-0 items-start justify-between gap-3\">\n <div className=\"grid min-w-0 gap-1\">\n <span className=\"min-w-0 truncate text-sm font-semibold text-foreground\">\n {props.conversation.title ?? props.conversation.sessionId}\n </span>\n <span className=\"min-w-0 truncate text-xs text-muted-foreground\">\n {props.agentName} / {props.conversation.userId}\n </span>\n </div>\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {props.conversation.messageCount}\n </span>\n </div>\n <div className=\"flex min-w-0 flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground\">\n <span>{formatRelativeTime(props.conversation.updatedAt)}</span>\n <span className=\"min-w-0 truncate\">{props.conversation.sessionId}</span>\n </div>\n </button>\n );\n}\n\nfunction ConversationDetail(props: {\n agents: StudioConfig[\"agents\"];\n conversation: StudioMemorySourceConversationSummary | undefined;\n detailLoading: boolean;\n messages: StudioMemorySourceConversationMessages | undefined;\n source: StudioMemorySourceSummary;\n steps: StudioMemorySourceConversationSteps | undefined;\n}) {\n if (props.conversation === undefined) {\n return (\n <section className=\"min-h-0 overflow-auto py-4 pl-5 max-xl:col-span-2 max-xl:pl-0 max-md:col-span-1\">\n <StudioEmptyState\n title=\"No conversation selected\"\n text=\"Choose a conversation to inspect.\"\n />\n </section>\n );\n }\n\n return (\n <section className=\"min-h-0 overflow-auto py-4 pl-5 max-xl:col-span-2 max-xl:pl-0 max-md:col-span-1\">\n <div className=\"grid min-w-0 gap-5\">\n <header className=\"grid gap-4 border-b border-hair pb-5\">\n <div className=\"flex min-w-0 items-start justify-between gap-4 max-md:grid\">\n <div className=\"grid min-w-0 gap-2\">\n <div className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Persisted conversation\n </div>\n <h2 className=\"m-0 min-w-0 truncate text-2xl font-semibold leading-none text-foreground\">\n {props.conversation.title ?? props.conversation.sessionId}\n </h2>\n <span className=\"min-w-0 break-all font-mono text-xs text-muted-foreground\">\n {props.conversation.ref}\n </span>\n </div>\n <div className=\"flex flex-wrap justify-end gap-2 max-md:justify-start\">\n <Badge className=\"border-hair bg-muted text-foreground\">\n {props.source.storeKind ?? props.source.kind}\n </Badge>\n <Badge className=\"border-hair bg-muted text-foreground\">\n {sourceAgentLabel(props.agents, props.source, props.conversation.agentIds)}\n </Badge>\n </div>\n </div>\n <div className=\"grid border-y border-hair sm:grid-cols-4 sm:divide-x sm:divide-hair\">\n <Fact label=\"user\" value={props.conversation.userId} />\n <Fact label=\"messages\" value={props.conversation.messageCount} />\n <Fact label=\"created\" value={formatRelativeTime(props.conversation.createdAt)} />\n <Fact label=\"updated\" value={formatRelativeTime(props.conversation.updatedAt)} />\n </div>\n </header>\n\n {props.detailLoading ? (\n <StudioEmptyState title=\"Loading detail\" text=\"Reading persisted messages.\" />\n ) : (\n <div className=\"grid gap-4\">\n {props.conversation.metadata === undefined ? null : (\n <JsonPanel title=\"metadata\" value={props.conversation.metadata} />\n )}\n <MemoryGenerationLedger records={props.messages?.records ?? []} />\n <JsonPanel title=\"messages\" value={props.messages?.messages ?? []} />\n <JsonPanel title=\"message records\" value={props.messages?.records ?? []} />\n <JsonPanel title=\"derived transcript\" value={props.steps?.steps ?? []} />\n </div>\n )}\n </div>\n </section>\n );\n}\n\nfunction UnavailableSource(props: { source: StudioMemorySourceSummary }) {\n return (\n <StudioEmptyState\n className=\"h-full\"\n title={`${props.source.label} is not inspectable`}\n text={props.source.reason ?? \"This memory store does not expose read-only discovery.\"}\n />\n );\n}\n\nfunction JsonPanel(props: { title: string; value: unknown }) {\n const count = Array.isArray(props.value) ? props.value.length : undefined;\n return (\n <details className=\"group grid min-w-0 overflow-hidden border-y border-hair\" open>\n <summary className=\"flex min-h-11 cursor-pointer list-none items-center justify-between gap-3 bg-muted px-3 text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground marker:hidden\">\n <span>{props.title}</span>\n <span className=\"font-medium normal-case tracking-normal\">\n {count === undefined ? \"JSON\" : `${count} items`}\n </span>\n </summary>\n <div className=\"min-w-0 overflow-x-auto border-t border-hair\">\n <pre className=\"m-0 max-h-96 min-w-max p-4 text-xs leading-5 text-foreground\">\n <code>\n <JsonSyntax text={formatJson(props.value)} />\n </code>\n </pre>\n </div>\n </details>\n );\n}\n\nfunction SectionLabel(props: { label: string; value: number }) {\n return (\n <div className=\"flex min-w-0 items-center justify-between gap-3\">\n <h2 className=\"m-0 text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground\">\n {props.label}\n </h2>\n <span className=\"text-xs font-semibold tabular-nums text-muted-foreground\">\n {props.value}\n </span>\n </div>\n );\n}\n\nfunction Fact(props: { label: string; value: string | number }) {\n return (\n <div className=\"grid min-w-0 gap-1 px-3 py-3 first:pl-0 last:pr-0\">\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n {props.label}\n </span>\n <span className=\"min-w-0 truncate text-sm text-foreground\" title={String(props.value)}>\n {props.value}\n </span>\n </div>\n );\n}\n\nfunction MemoryEmptyDashboard(props: {\n source: StudioMemorySourceSummary;\n userCount: number;\n onRefresh: () => void;\n}) {\n return (\n <StudioEmptyState\n className=\"h-full\"\n title=\"No saved conversations yet\"\n text={`Conversations will appear here after the connected agent writes to ${props.source.label}. ${props.userCount} users are currently available.`}\n action={\n <div className=\"flex min-w-0 flex-wrap items-center justify-center gap-3\">\n <Button\n className=\"h-8 min-h-8 rounded-md px-3 text-xs\"\n type=\"button\"\n variant=\"secondary\"\n onClick={props.onRefresh}\n >\n Refresh\n </Button>\n <span className=\"text-xs leading-5 text-muted-foreground\">\n Existing database conversations are discovered automatically.\n </span>\n </div>\n }\n />\n );\n}\n\nfunction InlineError(props: { message: string }) {\n return (\n <div className=\"mb-3 border border-status-danger-ink bg-status-danger-fill px-3 py-2 text-xs leading-5 text-destructive\">\n {props.message}\n </div>\n );\n}\n\nfunction memoryTotals(\n users: StudioMemorySourceUsersPage[\"users\"],\n conversations: StudioMemorySourceConversationSummary[],\n): { userCount: number; conversationCount: number; messageCount: number } {\n return {\n userCount: users.length,\n conversationCount: conversations.length,\n messageCount: conversations.reduce(\n (total, conversation) => total + conversation.messageCount,\n 0,\n ),\n };\n}\n\nfunction defaultSourceRef(sources: StudioMemorySourceSummary[]): string {\n return (\n sources.find((source) => source.kind === \"agent\" && source.available)?.ref ??\n sources.find((source) => source.available)?.ref ??\n sources[0]?.ref ??\n \"\"\n );\n}\n\nfunction formatJson(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nfunction sourceAgentLabel(\n agents: StudioConfig[\"agents\"],\n source: StudioMemorySourceSummary,\n agentIds: string[],\n): string {\n if (agentIds.length === 1) {\n const agentId = agentIds[0] ?? \"agent\";\n return agents.find((agent) => agent.id === agentId)?.name ?? agentId;\n }\n return source.label;\n}\n"],"mappings":"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"}