@anvia/studio 1.0.11 → 1.0.13

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.
@@ -1 +1 @@
1
- {"version":3,"file":"memory-page-DxClkjRl.js","names":[],"sources":["../../../../core/dist/chunk-TB5EKZM7.js","../../../src/ui/app/modules/memory/memory-generation-ledger.tsx","../../../src/ui/app/modules/memory/memory-page.tsx"],"sourcesContent":["import {\n assertJsonObject\n} from \"./chunk-7JLAIN6E.js\";\nimport {\n parseMessage,\n parseMessages,\n toProviderJsonSchema\n} from \"./chunk-QGX73TSQ.js\";\nimport {\n isJsonValue\n} from \"./chunk-3XQGVDU5.js\";\nimport {\n abortError,\n completionProviderOutputErrorUsage,\n resolveRetryOptions,\n retryDelayMs,\n retryOptionsForFailure,\n throwIfAborted,\n waitForRetry\n} from \"./chunk-3RWESPUG.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 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 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\n// src/completion/provider-output-error.ts\nvar COMPLETION_PROVIDER_OUTPUT_ERROR_CODE = \"ANVIA_COMPLETION_PROVIDER_OUTPUT\";\nvar PROVIDER_OUTPUT_ERROR_KINDS = /* @__PURE__ */ new Set([\n \"malformed-tool-arguments\",\n \"invalid-tool-arguments\",\n \"invalid-stream-event\",\n \"invalid-response\",\n \"incomplete-stream\",\n \"incomplete-tool-call\",\n \"invalid-tool-call\",\n \"truncated-tool-call\",\n \"filtered-tool-call\"\n]);\nvar CompletionProviderOutputError = class extends Error {\n code = COMPLETION_PROVIDER_OUTPUT_ERROR_CODE;\n kind;\n toolCallId;\n finishReason;\n usage;\n constructor(options) {\n assertProviderOutputErrorOptions(options);\n super(providerOutputErrorMessage(options.kind, options.toolCallId));\n this.name = \"CompletionProviderOutputError\";\n this.kind = options.kind;\n this.toolCallId = options.toolCallId;\n this.finishReason = options.finishReason;\n this.usage = options.usage === void 0 ? void 0 : copyUsage(options.usage);\n }\n};\nfunction assertCompletionResponseIntegrity(options) {\n const { response } = options;\n const toolCalls = response.choice.filter(\n (content) => content.type === \"tool-call\"\n );\n if (toolCalls.length > 0) {\n if (response.finishReason !== void 0 && !isCompletionFinishReason2(response.finishReason)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n usage: response.usage\n });\n }\n if (response.finishReason === \"length\") {\n throw new CompletionProviderOutputError({\n kind: \"truncated-tool-call\",\n finishReason: response.finishReason,\n usage: response.usage\n });\n }\n if (response.finishReason === \"content-filter\") {\n throw new CompletionProviderOutputError({\n kind: \"filtered-tool-call\",\n finishReason: response.finishReason,\n usage: response.usage\n });\n }\n if (response.finishReason === \"other\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n finishReason: response.finishReason,\n usage: response.usage\n });\n }\n } else if (response.finishReason === \"tool-calls\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n finishReason: response.finishReason,\n usage: response.usage\n });\n }\n const toolCallIds = /* @__PURE__ */ new Set();\n const callIds = /* @__PURE__ */ new Set();\n for (const toolCall of toolCalls) {\n if (!isNonblankString(toolCall.toolCallId) || !isNonblankString(toolCall.toolName)) {\n throw invalidToolCall(toolCall.toolCallId, response.usage);\n }\n if (toolCall.callId !== void 0 && !isNonblankString(toolCall.callId)) {\n throw invalidToolCall(toolCall.toolCallId, response.usage);\n }\n if (toolCallIds.has(toolCall.toolCallId)) {\n throw invalidToolCall(toolCall.toolCallId, response.usage);\n }\n toolCallIds.add(toolCall.toolCallId);\n if (toolCall.callId !== void 0) {\n if (callIds.has(toolCall.callId)) {\n throw invalidToolCall(toolCall.toolCallId, response.usage);\n }\n callIds.add(toolCall.callId);\n }\n if (!isJsonValue(toolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId: toolCall.toolCallId,\n usage: response.usage\n });\n }\n }\n}\nfunction invalidToolCall(toolCallId, usage) {\n return new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: isNonblankString(toolCallId) ? toolCallId : void 0,\n usage\n });\n}\nfunction assertProviderOutputErrorOptions(options) {\n if (typeof options !== \"object\" || options === null) {\n throw new TypeError(\"CompletionProviderOutputError options must be an object.\");\n }\n if (!PROVIDER_OUTPUT_ERROR_KINDS.has(options.kind)) {\n throw new TypeError(\"CompletionProviderOutputError kind is invalid.\");\n }\n if (options.toolCallId !== void 0 && !isNonblankString(options.toolCallId)) {\n throw new TypeError(\"CompletionProviderOutputError toolCallId must be a non-empty string.\");\n }\n if (options.finishReason !== void 0 && !isCompletionFinishReason2(options.finishReason)) {\n throw new TypeError(\"CompletionProviderOutputError finishReason is invalid.\");\n }\n if (options.kind === \"truncated-tool-call\" && options.finishReason !== \"length\") {\n throw new TypeError('CompletionProviderOutputError truncated-tool-call requires \"length\".');\n }\n if (options.kind === \"filtered-tool-call\" && options.finishReason !== \"content-filter\") {\n throw new TypeError(\n 'CompletionProviderOutputError filtered-tool-call requires \"content-filter\".'\n );\n }\n if (options.finishReason === \"length\" && options.kind !== \"truncated-tool-call\") {\n throw new TypeError(\n 'CompletionProviderOutputError finishReason \"length\" requires truncated-tool-call.'\n );\n }\n if (options.finishReason === \"content-filter\" && options.kind !== \"filtered-tool-call\") {\n throw new TypeError(\n 'CompletionProviderOutputError finishReason \"content-filter\" requires filtered-tool-call.'\n );\n }\n if (options.usage !== void 0) {\n assertUsage(options.usage);\n }\n}\nfunction providerOutputErrorMessage(kind, toolCallId) {\n const toolCall = toolCallId === void 0 ? \"tool call\" : `tool call ${JSON.stringify(displayId(toolCallId))}`;\n if (kind === \"malformed-tool-arguments\") {\n return `Completion provider returned ${toolCall} with malformed JSON arguments.`;\n }\n if (kind === \"invalid-tool-arguments\") {\n return `Completion provider returned ${toolCall} with arguments that are not a JSON value.`;\n }\n if (kind === \"invalid-stream-event\") {\n return \"Completion provider returned an invalid stream event.\";\n }\n if (kind === \"invalid-response\") {\n return \"Completion provider returned a response that cannot be consumed safely.\";\n }\n if (kind === \"incomplete-tool-call\") {\n return \"Completion provider stream ended before its tool call was complete.\";\n }\n if (kind === \"incomplete-stream\") {\n return \"Completion provider stream ended without a terminal response.\";\n }\n if (kind === \"truncated-tool-call\") {\n return \"Completion provider stopped at its output limit before a tool call could be consumed safely.\";\n }\n if (kind === \"filtered-tool-call\") {\n return \"Completion provider content filtering prevented a tool call from being consumed safely.\";\n }\n return `Completion provider returned an invalid ${toolCall}.`;\n}\nfunction displayId(value) {\n let sanitized = \"\";\n for (const character of value) {\n const code = character.charCodeAt(0);\n sanitized += code <= 31 || code === 127 ? \"\\uFFFD\" : character;\n }\n return sanitized.length <= 128 ? sanitized : `${sanitized.slice(0, 127)}\\u2026`;\n}\nfunction isNonblankString(value) {\n return typeof value === \"string\" && value.trim().length > 0;\n}\nfunction isCompletionFinishReason2(value) {\n return value === \"stop\" || value === \"length\" || value === \"content-filter\" || value === \"tool-calls\" || value === \"other\";\n}\nfunction assertUsage(usage) {\n for (const value of [\n usage.inputTokens,\n usage.outputTokens,\n usage.totalTokens,\n usage.cachedInputTokens,\n usage.cacheCreationInputTokens\n ]) {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n throw new TypeError(\"CompletionProviderOutputError usage must contain finite token counts.\");\n }\n }\n if (usage.details !== void 0) {\n for (const value of Object.values(usage.details)) {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n throw new TypeError(\n \"CompletionProviderOutputError usage details must contain finite token counts.\"\n );\n }\n }\n }\n}\nfunction copyUsage(usage) {\n const copied = {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n cachedInputTokens: usage.cachedInputTokens,\n cacheCreationInputTokens: usage.cacheCreationInputTokens\n };\n if (usage.details !== void 0) copied.details = { ...usage.details };\n return copied;\n}\n\n// src/internal/completion-request.ts\nfunction createCompletionRequest(input, options) {\n const configuredTools = options.tools ?? [];\n const chatHistory = messagesFromInput(input);\n assertNoAgentInteractionParts(chatHistory);\n const request = {\n chatHistory,\n documents: [...options.documents ?? []],\n tools: configuredTools.filter((tool) => !isProviderTool(tool))\n };\n const providerTools = configuredTools.filter(isProviderTool);\n if (providerTools.length > 0) request.providerTools = providerTools;\n if (options.instructions !== void 0 && options.instructions.length > 0) {\n request.instructions = options.instructions;\n }\n if (options.temperature !== void 0) request.temperature = options.temperature;\n if (options.maxTokens !== void 0) request.maxTokens = options.maxTokens;\n if (options.toolChoice !== void 0) request.toolChoice = options.toolChoice;\n if (options.outputSchema !== void 0) request.outputSchema = options.outputSchema;\n if (options.providerOptions !== void 0) {\n assertJsonObject(options.providerOptions, \"providerOptions\");\n request.providerOptions = options.providerOptions;\n }\n return request;\n}\nfunction assertNoAgentInteractionParts(messages) {\n for (const message of messages) {\n if (message.role === \"tool\" && message.content.some((part) => part.type !== \"tool-result\")) {\n throw new TypeError(\n \"Completion messages contain an unresolved Agent interaction response. Resume the Agent with its continuation instead of sending interaction parts directly to a provider.\"\n );\n }\n }\n}\nfunction messagesFromInput(input) {\n if (typeof input === \"string\") {\n return [{ role: \"user\", content: input }];\n }\n if (Array.isArray(input)) {\n if (input.length === 0) {\n throw new Error(\"input must contain at least one Message.\");\n }\n return parseMessages(input);\n }\n return [parseMessage(input)];\n}\n\n// src/completion/stream-accumulator.ts\nvar CompletionStreamAccumulator = class {\n orderedParts = [];\n textParts = /* @__PURE__ */ new Map();\n reasoningByKey = /* @__PURE__ */ new Map();\n reasoningKeyById = /* @__PURE__ */ new Map();\n toolCalls = /* @__PURE__ */ new Map();\n sources = /* @__PURE__ */ new Map();\n providerToolCalls = /* @__PURE__ */ new Map();\n finalResponse;\n messageId;\n nextTextKey = 0;\n nextReasoningKey = 0;\n accept(event) {\n if (event.type === \"text_delta\") {\n if (typeof event.delta !== \"string\") {\n throw new CompletionProviderOutputError({ kind: \"invalid-stream-event\" });\n }\n this.appendText(event.delta);\n return { type: \"text_delta\", delta: event.delta };\n }\n if (event.type === \"reasoning_delta\") {\n if (typeof event.delta !== \"string\" || event.id !== void 0 && !isNonblankString2(event.id) || event.signature !== void 0 && !isNonblankString2(event.signature) || event.contentType !== void 0 && !isReasoningContentType(event.contentType)) {\n throw new CompletionProviderOutputError({ kind: \"invalid-stream-event\" });\n }\n const reasoning = this.reasoningStateForEvent(event);\n this.appendReasoning(reasoning, event);\n return reasoningDeltaEvent(event);\n }\n if (event.type === \"tool_call_delta\") {\n if (!isNonblankString2(event.id)) {\n throw new CompletionProviderOutputError({ kind: \"invalid-tool-call\" });\n }\n const toolCall = this.toolCallStateForId(event.id);\n if (toolCall.fullCallSeen) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n if (event.callId !== void 0) {\n if (!isNonblankString2(event.callId)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n if (toolCall.callId !== void 0 && toolCall.callId !== event.callId) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.callId = event.callId;\n }\n if (event.name !== void 0) {\n if (!isNonblankString2(event.name)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n if (toolCall.name.length > 0 && toolCall.name !== event.name) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.name = event.name;\n }\n if (event.signature !== void 0) {\n if (!isNonblankString2(event.signature) || toolCall.signature !== void 0 && toolCall.signature !== event.signature) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.signature = event.signature;\n }\n if (event.argumentsMode !== void 0 && event.argumentsMode !== \"append\" && event.argumentsMode !== \"replace\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-stream-event\",\n toolCallId: toolCall.id\n });\n }\n if (event.argumentsMode !== void 0 && event.argumentsDelta === void 0) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-stream-event\",\n toolCallId: toolCall.id\n });\n }\n if (event.argumentsDelta !== void 0) {\n if (typeof event.argumentsDelta !== \"string\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId: toolCall.id\n });\n }\n if (event.argumentsMode === \"replace\") {\n if (toolCall.argumentsText.length > 0 && toolCall.argumentsText !== event.argumentsDelta && (toolCall.argumentsSnapshotSeen || !event.argumentsDelta.startsWith(toolCall.argumentsText))) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.argumentsText = event.argumentsDelta;\n toolCall.argumentsSnapshotSeen = true;\n } else {\n if (toolCall.argumentsSnapshotSeen) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.argumentsText += event.argumentsDelta;\n }\n }\n return void 0;\n }\n if (event.type === \"tool_call\") {\n this.upsertToolCall(event.toolCall);\n return { type: \"tool_call\", toolCall: event.toolCall };\n }\n if (event.type === \"source\") {\n this.sources.set(sourceKey(event.source), event.source);\n return { type: \"source\", source: event.source };\n }\n if (event.type === \"provider_tool_call\") {\n this.providerToolCalls.set(event.toolCall.id, event.toolCall);\n return { type: \"provider_tool_call\", toolCall: event.toolCall };\n }\n if (event.type === \"message_id\") {\n if (!isNonblankString2(event.id)) {\n throw new CompletionProviderOutputError({ kind: \"invalid-stream-event\" });\n }\n this.messageId = event.id;\n return void 0;\n }\n if (event.type === \"final\") {\n this.finalResponse = event.response;\n return void 0;\n }\n return void 0;\n }\n response() {\n this.assertAccumulatedFinishReason();\n let accumulatedResponse;\n try {\n accumulatedResponse = this.buildAccumulatedResponse();\n } catch (error) {\n if (error instanceof CompletionProviderOutputError && this.finalResponse !== void 0) {\n throw providerOutputErrorWithUsage(error, this.finalResponse.usage);\n }\n throw error;\n }\n if (this.finalResponse !== void 0) {\n if (accumulatedResponse.choice.length === 0) {\n return this.withAccumulatedArtifacts(this.finalResponse, accumulatedResponse);\n }\n return this.mergeFinalResponse(accumulatedResponse, this.finalResponse);\n }\n return accumulatedResponse;\n }\n assertAccumulatedFinishReason() {\n if (this.finalResponse === void 0) {\n if (this.toolCalls.size === 0) {\n throw new CompletionProviderOutputError({ kind: \"incomplete-stream\" });\n }\n const toolCallId = this.toolCalls.size === 1 ? this.toolCalls.keys().next().value : void 0;\n throw new CompletionProviderOutputError({\n kind: \"incomplete-tool-call\",\n toolCallId\n });\n }\n if (this.toolCalls.size === 0) return;\n const finishReason = this.finalResponse.finishReason;\n if (finishReason === \"length\") {\n throw new CompletionProviderOutputError({\n kind: \"truncated-tool-call\",\n finishReason,\n usage: this.finalResponse.usage\n });\n }\n if (finishReason === \"content-filter\") {\n throw new CompletionProviderOutputError({\n kind: \"filtered-tool-call\",\n finishReason,\n usage: this.finalResponse.usage\n });\n }\n if (finishReason !== void 0 && finishReason !== \"stop\" && finishReason !== \"tool-calls\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n usage: this.finalResponse.usage\n });\n }\n }\n buildAccumulatedResponse() {\n const choice = [];\n for (const part of this.orderedParts) {\n if (part.type === \"text\") {\n const text = this.textParts.get(part.key) ?? \"\";\n if (text.length > 0) {\n choice.push({ type: \"text\", text });\n }\n continue;\n }\n if (part.type === \"reasoning\") {\n const reasoning = this.reasoningByKey.get(part.key);\n if (reasoning !== void 0) {\n choice.push(reasoningContent(reasoning));\n }\n continue;\n }\n const toolCall = this.toolCalls.get(part.key);\n if (toolCall !== void 0) {\n choice.push(toolCallContent(toolCall));\n }\n }\n const response = {\n choice,\n usage: Usage.empty(),\n rawResponse: void 0\n };\n if (this.messageId !== void 0) {\n response.messageId = this.messageId;\n }\n const sources = [...this.sources.values()];\n if (sources.length > 0) {\n response.sources = sources;\n }\n const providerToolCalls = [...this.providerToolCalls.values()];\n if (providerToolCalls.length > 0) {\n response.providerToolCalls = providerToolCalls;\n }\n return response;\n }\n upsertToolCall(toolCall) {\n if (!isNonblankString2(toolCall.toolCallId) || !isNonblankString2(toolCall.toolName) || toolCall.callId !== void 0 && !isNonblankString2(toolCall.callId) || toolCall.signature !== void 0 && !isNonblankString2(toolCall.signature)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: isNonblankString2(toolCall.toolCallId) ? toolCall.toolCallId : void 0\n });\n }\n if (!isJsonValue(toolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId: toolCall.toolCallId\n });\n }\n const existing = this.toolCalls.get(toolCall.toolCallId);\n if (existing !== void 0) {\n if (existing.fullCallSeen) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.toolCallId\n });\n }\n if (existing.name.length > 0 && existing.name !== toolCall.toolName || existing.callId !== void 0 && existing.callId !== toolCall.callId || existing.signature !== void 0 && toolCall.signature !== void 0 && existing.signature !== toolCall.signature) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.toolCallId\n });\n }\n if (existing.argumentsText.length > 0) {\n const accumulatedInput = parseToolArguments(existing.id, existing.argumentsText);\n if (!jsonValuesEqual(accumulatedInput, toolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.toolCallId\n });\n }\n }\n }\n if (!this.toolCalls.has(toolCall.toolCallId)) {\n this.orderedParts.push({ type: \"tool_call\", key: toolCall.toolCallId });\n }\n const partial = {\n id: toolCall.toolCallId,\n name: toolCall.toolName,\n argumentsText: JSON.stringify(toolCall.input),\n argumentsSnapshotSeen: true,\n fullCallSeen: true\n };\n if (toolCall.callId !== void 0) {\n partial.callId = toolCall.callId;\n }\n const signature = toolCall.signature ?? existing?.signature;\n if (signature !== void 0) {\n partial.signature = signature;\n }\n this.toolCalls.set(toolCall.toolCallId, partial);\n }\n mergeFinalResponse(accumulatedResponse, finalResponse) {\n if (finalResponse.choice.length === 0) {\n const mergedResponse = {\n ...accumulatedResponse,\n usage: finalResponse.usage,\n rawResponse: finalResponse.rawResponse\n };\n if (finalResponse.finishReason !== void 0) {\n mergedResponse.finishReason = finalResponse.finishReason;\n }\n if (finalResponse.providerFinishReason !== void 0) {\n mergedResponse.providerFinishReason = finalResponse.providerFinishReason;\n }\n if (finalResponse.messageId !== void 0) {\n mergedResponse.messageId = finalResponse.messageId;\n }\n return this.withAccumulatedArtifacts(mergedResponse, accumulatedResponse);\n }\n const accumulatedNonTool = accumulatedResponse.choice.filter(\n (content) => content.type !== \"tool-call\"\n );\n const finalNonTool = finalResponse.choice.filter((content) => content.type !== \"tool-call\");\n if (accumulatedNonTool.length > 0 && !nonToolPartsEqual(accumulatedNonTool, finalNonTool)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-stream-event\",\n usage: finalResponse.usage\n });\n }\n const accumulatedById = /* @__PURE__ */ new Map();\n const accumulatedByCallId = /* @__PURE__ */ new Map();\n for (const content of accumulatedResponse.choice) {\n if (content.type !== \"tool-call\") continue;\n accumulatedById.set(content.toolCallId, content);\n if (content.callId !== void 0) accumulatedByCallId.set(content.callId, content);\n }\n const matchedAccumulatedToolCalls = /* @__PURE__ */ new Set();\n const choice = finalResponse.choice.map((content) => {\n if (content.type !== \"tool-call\") return content;\n const accumulated = accumulatedById.get(content.toolCallId);\n if (accumulated === void 0) {\n const changedIdentity = content.callId === void 0 ? void 0 : accumulatedByCallId.get(content.callId);\n if (changedIdentity !== void 0) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: changedIdentity.toolCallId,\n usage: finalResponse.usage\n });\n }\n return content;\n }\n matchedAccumulatedToolCalls.add(accumulated);\n return mergeFinalToolCall(accumulated, content, finalResponse.usage);\n });\n for (const accumulated of accumulatedById.values()) {\n if (!matchedAccumulatedToolCalls.has(accumulated)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: accumulated.toolCallId,\n usage: finalResponse.usage\n });\n }\n }\n return this.withAccumulatedArtifacts({ ...finalResponse, choice }, accumulatedResponse);\n }\n appendText(delta) {\n const lastPart = this.orderedParts.at(-1);\n const key = lastPart?.type === \"text\" ? lastPart.key : this.createTextKey();\n if (lastPart?.type !== \"text\") {\n this.orderedParts.push({ type: \"text\", key });\n }\n this.textParts.set(key, `${this.textParts.get(key) ?? \"\"}${delta}`);\n }\n reasoningStateForEvent(event) {\n if (event.id !== void 0) {\n const existingKey = this.reasoningKeyById.get(event.id);\n if (existingKey !== void 0) {\n const existing = this.reasoningByKey.get(existingKey);\n if (existing !== void 0) {\n return existing;\n }\n }\n const key2 = this.createReasoningKey();\n const reasoning2 = { id: event.id, text: \"\" };\n this.reasoningKeyById.set(event.id, key2);\n this.reasoningByKey.set(key2, reasoning2);\n this.orderedParts.push({ type: \"reasoning\", key: key2 });\n return reasoning2;\n }\n const lastPart = this.orderedParts.at(-1);\n if (lastPart?.type === \"reasoning\") {\n const lastReasoning = this.reasoningByKey.get(lastPart.key);\n if (lastReasoning !== void 0 && lastReasoning.id === void 0) {\n return lastReasoning;\n }\n }\n const key = this.createReasoningKey();\n const reasoning = { text: \"\" };\n this.reasoningByKey.set(key, reasoning);\n this.orderedParts.push({ type: \"reasoning\", key });\n return reasoning;\n }\n toolCallStateForId(id) {\n const existing = this.toolCalls.get(id);\n if (existing !== void 0) {\n return existing;\n }\n const toolCall = {\n id,\n name: \"\",\n argumentsText: \"\",\n argumentsSnapshotSeen: false,\n fullCallSeen: false\n };\n this.toolCalls.set(id, toolCall);\n this.orderedParts.push({ type: \"tool_call\", key: id });\n return toolCall;\n }\n withMessageIdFallback(response, accumulatedResponse) {\n if (response.messageId !== void 0 || accumulatedResponse.messageId === void 0) {\n return response;\n }\n return { ...response, messageId: accumulatedResponse.messageId };\n }\n withAccumulatedArtifacts(response, accumulatedResponse) {\n const withMessageId = this.withMessageIdFallback(response, accumulatedResponse);\n const sources = mergeSources(accumulatedResponse.sources, response.sources);\n const providerToolCalls = mergeProviderToolCalls(\n accumulatedResponse.providerToolCalls,\n response.providerToolCalls\n );\n let accumulated = { ...withMessageId };\n if (sources.length > 0) accumulated = { ...accumulated, sources };\n if (providerToolCalls.length > 0) {\n accumulated = { ...accumulated, providerToolCalls };\n }\n return accumulated;\n }\n createTextKey() {\n this.nextTextKey += 1;\n return `text_${this.nextTextKey.toString()}`;\n }\n createReasoningKey() {\n this.nextReasoningKey += 1;\n return `reasoning_${this.nextReasoningKey.toString()}`;\n }\n appendReasoning(reasoning, event) {\n const contentType = event.contentType ?? \"text\";\n if (contentType === \"text\" || contentType === \"summary\") {\n reasoning.text += event.delta;\n }\n if (event.contentType === void 0 && event.signature === void 0) {\n return;\n }\n reasoning.details ??= [];\n const last = reasoning.details.at(-1);\n if (contentType === \"text\") {\n if (last?.type === \"text\") {\n let detail = {\n ...last,\n text: `${last.text}${event.delta}`\n };\n if (event.signature !== void 0) detail = { ...detail, signature: event.signature };\n reasoning.details[reasoning.details.length - 1] = detail;\n } else {\n reasoning.details.push(\n event.signature === void 0 ? { type: \"text\", text: event.delta } : { type: \"text\", text: event.delta, signature: event.signature }\n );\n }\n return;\n }\n if (contentType === \"summary\") {\n if (last?.type === \"summary\") {\n reasoning.details[reasoning.details.length - 1] = {\n ...last,\n text: `${last.text}${event.delta}`\n };\n } else {\n reasoning.details.push({ type: \"summary\", text: event.delta });\n }\n return;\n }\n if (contentType === \"encrypted\") {\n reasoning.details.push({ type: \"encrypted\", data: event.delta });\n return;\n }\n reasoning.details.push({ type: \"redacted\", data: event.delta });\n }\n};\nfunction sourceKey(source) {\n return `${source.url}\\0${source.startIndex ?? \"\"}\\0${source.endIndex ?? \"\"}`;\n}\nfunction mergeSources(accumulated, final) {\n const sources = /* @__PURE__ */ new Map();\n for (const source of [...accumulated ?? [], ...final ?? []]) {\n sources.set(sourceKey(source), source);\n }\n return [...sources.values()];\n}\nfunction mergeProviderToolCalls(accumulated, final) {\n const toolCalls = /* @__PURE__ */ new Map();\n for (const toolCall of [...accumulated ?? [], ...final ?? []]) {\n toolCalls.set(toolCall.id, toolCall);\n }\n return [...toolCalls.values()];\n}\nfunction reasoningContent(reasoning) {\n const content = reasoning.details === void 0 ? { type: \"reasoning\", text: reasoning.text } : { type: \"reasoning\", text: reasoning.text, details: reasoning.details };\n return reasoning.id === void 0 ? content : { ...content, id: reasoning.id };\n}\nfunction toolCallContent(toolCall) {\n const argumentsValue = parseToolArguments(toolCall.id, toolCall.argumentsText);\n let content = {\n type: \"tool-call\",\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n input: argumentsValue\n };\n if (toolCall.callId !== void 0) content = { ...content, callId: toolCall.callId };\n if (toolCall.signature !== void 0) content = { ...content, signature: toolCall.signature };\n return content;\n}\nfunction mergeFinalToolCall(accumulated, finalToolCall, usage) {\n if (finalToolCall.toolCallId !== accumulated.toolCallId || finalToolCall.toolName !== accumulated.toolName || accumulated.callId !== void 0 && finalToolCall.callId !== accumulated.callId || accumulated.signature !== void 0 && finalToolCall.signature !== void 0 && finalToolCall.signature !== accumulated.signature) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: accumulated.toolCallId,\n usage\n });\n }\n if (!isJsonValue(finalToolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId: accumulated.toolCallId,\n usage\n });\n }\n if (!jsonValuesEqual(accumulated.input, finalToolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: accumulated.toolCallId,\n usage\n });\n }\n let merged = {\n type: \"tool-call\",\n toolCallId: finalToolCall.toolCallId,\n toolName: finalToolCall.toolName,\n input: accumulated.input\n };\n const callId = finalToolCall.callId ?? accumulated.callId;\n if (callId !== void 0) merged = { ...merged, callId };\n const signature = finalToolCall.signature ?? accumulated.signature;\n if (signature !== void 0) merged = { ...merged, signature };\n return merged;\n}\nfunction reasoningDeltaEvent(event) {\n const mapped = { type: \"reasoning_delta\", delta: event.delta };\n if (event.id !== void 0) mapped.id = event.id;\n if (event.contentType !== void 0) mapped.contentType = event.contentType;\n if (event.signature !== void 0) mapped.signature = event.signature;\n return mapped;\n}\nfunction parseToolArguments(toolCallId, text) {\n let value;\n try {\n value = JSON.parse(text);\n } catch {\n throw new CompletionProviderOutputError({\n kind: \"malformed-tool-arguments\",\n toolCallId\n });\n }\n if (!isJsonValue(value)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId\n });\n }\n return value;\n}\nfunction jsonValuesEqual(left, right) {\n if (left === right) {\n return true;\n }\n if (left === null || right === null || typeof left !== \"object\" || typeof right !== \"object\") {\n return false;\n }\n if (isJsonArray(left) || isJsonArray(right)) {\n if (!isJsonArray(left) || !isJsonArray(right) || left.length !== right.length) {\n return false;\n }\n return left.every((value, index) => {\n const rightValue = right[index];\n return rightValue !== void 0 && jsonValuesEqual(value, rightValue);\n });\n }\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n if (leftKeys.length !== rightKeys.length) {\n return false;\n }\n for (const key of leftKeys) {\n if (!Object.hasOwn(right, key)) {\n return false;\n }\n const leftValue = left[key];\n const rightValue = right[key];\n if (leftValue === void 0 || rightValue === void 0 || !jsonValuesEqual(leftValue, rightValue)) {\n return false;\n }\n }\n return true;\n}\nfunction nonToolPartsEqual(accumulated, final) {\n if (accumulated.length !== final.length) return false;\n if (!isJsonValue(accumulated) || !isJsonValue(final)) return false;\n const unmatched = [...final];\n for (const part of accumulated) {\n const index = unmatched.findIndex((candidate) => jsonValuesEqual(part, candidate));\n if (index < 0) return false;\n unmatched.splice(index, 1);\n }\n return true;\n}\nfunction isJsonArray(value) {\n return Array.isArray(value);\n}\nfunction providerOutputErrorWithUsage(error, usage) {\n const shared = { usage };\n if (error.toolCallId !== void 0) shared.toolCallId = error.toolCallId;\n if (error.kind === \"truncated-tool-call\") {\n return new CompletionProviderOutputError({\n ...shared,\n kind: error.kind,\n finishReason: \"length\"\n });\n }\n if (error.kind === \"filtered-tool-call\") {\n return new CompletionProviderOutputError({\n ...shared,\n kind: error.kind,\n finishReason: \"content-filter\"\n });\n }\n if (error.finishReason === \"length\" || error.finishReason === \"content-filter\") {\n throw error;\n }\n return new CompletionProviderOutputError({\n ...shared,\n kind: error.kind,\n finishReason: error.finishReason\n });\n}\nfunction isNonblankString2(value) {\n return typeof value === \"string\" && value.trim().length > 0;\n}\nfunction isReasoningContentType(value) {\n return value === \"text\" || value === \"summary\" || value === \"encrypted\" || value === \"redacted\";\n}\n\n// src/completion/generate-completion.ts\nvar CompletionStructuredOutputError = class extends Error {\n phase;\n outputLength;\n usage;\n finishReason;\n providerFinishReason;\n constructor(options) {\n const failure = options.phase === \"truncated\" ? \"because the provider reached its output limit\" : options.phase === \"content-filter\" ? \"because the provider filtered the response\" : options.phase === \"parse\" ? \"during JSON parsing\" : \"during schema validation\";\n super(`Structured completion output failed ${failure}.`, { cause: options.cause });\n this.name = \"CompletionStructuredOutputError\";\n this.phase = options.phase;\n this.outputLength = options.outputLength;\n this.usage = options.usage;\n this.finishReason = options.finishReason;\n this.providerFinishReason = options.providerFinishReason;\n }\n};\nasync function generateCompletion(options) {\n throwIfAborted(options.abortSignal);\n const request = requestFromOptions(options);\n assertCompletionRequestSupported(options.model, request);\n const retries = resolveOptionalRetries(options.retries);\n const response = await sendCompletion(options.model, request, retries, options.abortSignal);\n return resultFromResponse(response, structuredOutputSchema(options));\n}\nfunction streamCompletion(options) {\n throwIfAborted(options.abortSignal);\n const request = requestFromOptions(options);\n if (!isStreamingCompletionModel(options.model) || !options.model.capabilities.streaming) {\n throw new Error(\"This completion model does not support streaming\");\n }\n assertCompletionRequestSupported(options.model, request, { streaming: true });\n const retries = resolveOptionalRetries(options.retries);\n return streamCompletionWithRetries(\n options.model,\n request,\n retries,\n options.abortSignal,\n structuredOutputSchema(options)\n );\n}\nasync function sendCompletion(model, request, retries, abortSignal) {\n const callOptions = modelCallOptions(abortSignal);\n let attempt = 1;\n let failedUsage = Usage.empty();\n while (true) {\n try {\n throwIfAborted(abortSignal);\n const response = await model.completion(request, callOptions);\n assertCompletionResponseIntegrity({ response });\n return Usage.isEmpty(failedUsage) ? response : { ...response, usage: Usage.add(failedUsage, response.usage) };\n } catch (error) {\n const normalizedError = abortSignal?.aborted === true ? abortError(abortSignal.reason) : error;\n const attemptUsage = completionProviderOutputErrorUsage(normalizedError);\n if (attemptUsage !== void 0) failedUsage = Usage.add(failedUsage, attemptUsage);\n const retryOptions = retryOptionsForFailure(retries, {\n error: normalizedError,\n attempt,\n streaming: false\n });\n if (retryOptions === void 0) throw normalizedError;\n await waitForRetry(retryDelayMs(retryOptions, attempt), abortSignal);\n attempt += 1;\n }\n }\n}\nfunction resolveOptionalRetries(setting) {\n return setting === void 0 || setting === false ? void 0 : resolveRetryOptions(setting);\n}\nasync function* streamCompletionWithRetries(model, request, retries, abortSignal, outputSchema) {\n let attempt = 1;\n let swallowedUsage = Usage.empty();\n const callOptions = modelCallOptions(abortSignal);\n attemptLoop: while (true) {\n let exposedProgress = false;\n let retryDelay;\n const accumulator = new CompletionStreamAccumulator();\n try {\n throwIfAborted(abortSignal);\n const events = model.streamCompletion(request, callOptions);\n for await (const event of events) {\n if (event.type === \"error\" && !exposedProgress) {\n const eventError = abortSignal?.aborted === true ? abortError(abortSignal.reason) : event.error;\n const eventUsage = event.usage ?? completionProviderOutputErrorUsage(eventError) ?? Usage.empty();\n const retryOptions = retryOptionsForFailure(retries, {\n error: eventError,\n attempt,\n streaming: true\n });\n if (retryOptions !== void 0) {\n swallowedUsage = Usage.add(swallowedUsage, eventUsage);\n retryDelay = retryDelayMs(retryOptions, attempt);\n break;\n }\n }\n if (event.type === \"error\") {\n const eventError = abortSignal?.aborted === true ? abortError(abortSignal.reason) : event.error;\n const eventUsage = event.usage ?? completionProviderOutputErrorUsage(eventError) ?? Usage.empty();\n yield {\n type: \"error\",\n error: eventError,\n usage: Usage.add(swallowedUsage, eventUsage)\n };\n return;\n }\n if (event.type === \"final\") {\n const cumulativeUsage = Usage.add(swallowedUsage, event.response.usage);\n try {\n accumulator.accept(event);\n const accumulatedResponse = accumulator.response();\n const response = Usage.isEmpty(swallowedUsage) ? accumulatedResponse : { ...accumulatedResponse, usage: cumulativeUsage };\n assertCompletionResponseIntegrity({ response });\n yield {\n type: \"final\",\n result: resultFromResponse(response, outputSchema)\n };\n } catch (error) {\n const retryOptions = exposedProgress ? void 0 : retryOptionsForFailure(retries, {\n error,\n attempt,\n streaming: true\n });\n if (retryOptions !== void 0) {\n swallowedUsage = cumulativeUsage;\n await waitForRetry(retryDelayMs(retryOptions, attempt), abortSignal);\n attempt += 1;\n continue attemptLoop;\n }\n yield { type: \"error\", error, usage: cumulativeUsage };\n }\n return;\n }\n accumulator.accept(event);\n exposedProgress = true;\n yield event;\n }\n if (retryDelay !== void 0) {\n await waitForRetry(retryDelay, abortSignal);\n attempt += 1;\n continue;\n }\n let incomplete;\n try {\n accumulator.response();\n incomplete = new CompletionProviderOutputError({ kind: \"incomplete-stream\" });\n } catch (error) {\n incomplete = error;\n }\n if (!exposedProgress) {\n const retryOptions = retryOptionsForFailure(retries, {\n error: incomplete,\n attempt,\n streaming: true\n });\n if (retryOptions !== void 0) {\n await waitForRetry(retryDelayMs(retryOptions, attempt), abortSignal);\n attempt += 1;\n continue;\n }\n }\n yield { type: \"error\", error: incomplete, usage: swallowedUsage };\n return;\n } catch (error) {\n const normalizedError = abortSignal?.aborted === true ? abortError(abortSignal.reason) : error;\n const attemptUsage = completionProviderOutputErrorUsage(normalizedError);\n const cumulativeUsage = attemptUsage === void 0 ? swallowedUsage : Usage.add(swallowedUsage, attemptUsage);\n if (!exposedProgress) {\n const retryOptions = retryOptionsForFailure(retries, {\n error: normalizedError,\n attempt,\n streaming: true\n });\n if (retryOptions !== void 0) {\n try {\n swallowedUsage = cumulativeUsage;\n await waitForRetry(retryDelayMs(retryOptions, attempt), abortSignal);\n attempt += 1;\n continue;\n } catch (waitError) {\n yield { type: \"error\", error: waitError, usage: cumulativeUsage };\n return;\n }\n }\n }\n yield { type: \"error\", error: normalizedError, usage: cumulativeUsage };\n return;\n }\n }\n}\nfunction requestFromOptions(options) {\n const input = inputFromOptions(options);\n return createCompletionRequest(input, {\n instructions: options.instructions,\n documents: options.documents,\n tools: options.tools,\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n toolChoice: options.toolChoice,\n providerOptions: options.providerOptions,\n outputSchema: \"outputSchema\" in options && options.outputSchema !== void 0 ? toProviderJsonSchema(options.outputSchema) : void 0\n });\n}\nfunction inputFromOptions(options) {\n const prompt = options.prompt;\n const messages = options.messages;\n const hasPrompt = prompt !== void 0;\n const hasMessages = messages !== void 0;\n if (hasPrompt === hasMessages) {\n throw new TypeError(\"Exactly one of prompt or messages must be provided.\");\n }\n if (hasPrompt) {\n if (typeof prompt !== \"string\" || prompt.trim().length === 0) {\n throw new TypeError(\"Completion prompt must be a non-empty string.\");\n }\n return prompt;\n }\n if (!Array.isArray(messages)) {\n throw new TypeError(\"Completion messages must be an array of Message values.\");\n }\n return messages;\n}\nfunction structuredOutputSchema(options) {\n return options.outputSchema;\n}\nfunction resultFromResponse(response, outputSchema) {\n const text = textFromAssistantContent(response.choice);\n const result = {\n output: outputSchema === void 0 ? text : parseCompletionOutput(text, outputSchema, response),\n text,\n content: [...response.choice],\n usage: response.usage,\n rawResponse: response.rawResponse\n };\n if (response.finishReason !== void 0) result.finishReason = response.finishReason;\n if (response.providerFinishReason !== void 0) {\n result.providerFinishReason = response.providerFinishReason;\n }\n if (response.contextUsage !== void 0) result.contextUsage = response.contextUsage;\n if (response.messageId !== void 0) result.messageId = response.messageId;\n if (response.sources !== void 0) result.sources = [...response.sources];\n if (response.providerToolCalls !== void 0) {\n result.providerToolCalls = [...response.providerToolCalls];\n }\n return result;\n}\nfunction parseCompletionOutput(text, schema, response) {\n if (response.finishReason === \"content-filter\") {\n throw new CompletionStructuredOutputError({\n phase: \"content-filter\",\n outputLength: text.length,\n usage: response.usage,\n finishReason: response.finishReason,\n providerFinishReason: response.providerFinishReason\n });\n }\n if (response.finishReason === \"length\") {\n throw new CompletionStructuredOutputError({\n phase: \"truncated\",\n outputLength: text.length,\n usage: response.usage,\n finishReason: response.finishReason,\n providerFinishReason: response.providerFinishReason\n });\n }\n let json;\n try {\n json = JSON.parse(text);\n if (!isJsonValue(json)) {\n throw new TypeError(\"Structured completion output is not a JSON value.\");\n }\n } catch (error) {\n throw new CompletionStructuredOutputError({\n phase: \"parse\",\n outputLength: text.length,\n usage: response.usage,\n finishReason: response.finishReason,\n providerFinishReason: response.providerFinishReason,\n cause: error\n });\n }\n try {\n return schema.parse(json);\n } catch (error) {\n throw new CompletionStructuredOutputError({\n phase: \"schema\",\n outputLength: text.length,\n usage: response.usage,\n finishReason: response.finishReason,\n providerFinishReason: response.providerFinishReason,\n cause: error\n });\n }\n}\nfunction modelCallOptions(abortSignal) {\n return abortSignal === void 0 ? void 0 : { abortSignal };\n}\nfunction isStreamingCompletionModel(model) {\n return typeof model.streamCompletion === \"function\";\n}\n\nexport {\n reasoningDisplayText,\n isProviderTool,\n calculateContextUsage,\n withContextUsage,\n resolveModelContextLimits,\n Usage,\n getAssistantGenerationMetadata,\n CompletionCapabilityError,\n assertCompletionRequestSupported,\n textFromAssistantContent,\n createCompletionRequest,\n COMPLETION_PROVIDER_OUTPUT_ERROR_CODE,\n CompletionProviderOutputError,\n assertCompletionResponseIntegrity,\n CompletionStreamAccumulator,\n CompletionStructuredOutputError,\n generateCompletion,\n streamCompletion,\n isStreamingCompletionModel\n};\n//# sourceMappingURL=chunk-TB5EKZM7.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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"}
1
+ {"version":3,"file":"memory-page-DxClkjRl.js","names":[],"sources":["../../../../core/dist/chunk-OI3LSMJG.js","../../../src/ui/app/modules/memory/memory-generation-ledger.tsx","../../../src/ui/app/modules/memory/memory-page.tsx"],"sourcesContent":["import {\n assertJsonObject\n} from \"./chunk-7JLAIN6E.js\";\nimport {\n parseMessage,\n parseMessages,\n toProviderJsonSchema\n} from \"./chunk-QGX73TSQ.js\";\nimport {\n isJsonValue\n} from \"./chunk-3XQGVDU5.js\";\nimport {\n abortError,\n completionProviderOutputErrorUsage,\n resolveRetryOptions,\n retryDelayMs,\n retryOptionsForFailure,\n throwIfAborted,\n waitForRetry\n} from \"./chunk-3RWESPUG.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\n// src/completion/provider-output-error.ts\nvar COMPLETION_PROVIDER_OUTPUT_ERROR_CODE = \"ANVIA_COMPLETION_PROVIDER_OUTPUT\";\nvar PROVIDER_OUTPUT_ERROR_KINDS = /* @__PURE__ */ new Set([\n \"malformed-tool-arguments\",\n \"invalid-tool-arguments\",\n \"invalid-stream-event\",\n \"invalid-response\",\n \"incomplete-stream\",\n \"incomplete-tool-call\",\n \"invalid-tool-call\",\n \"truncated-tool-call\",\n \"filtered-tool-call\"\n]);\nvar CompletionProviderOutputError = class extends Error {\n code = COMPLETION_PROVIDER_OUTPUT_ERROR_CODE;\n kind;\n toolCallId;\n finishReason;\n usage;\n constructor(options) {\n assertProviderOutputErrorOptions(options);\n super(providerOutputErrorMessage(options.kind, options.toolCallId));\n this.name = \"CompletionProviderOutputError\";\n this.kind = options.kind;\n this.toolCallId = options.toolCallId;\n this.finishReason = options.finishReason;\n this.usage = options.usage === void 0 ? void 0 : copyUsage(options.usage);\n }\n};\nfunction assertCompletionResponseIntegrity(options) {\n const { response } = options;\n const toolCalls = response.choice.filter(\n (content) => content.type === \"tool-call\"\n );\n if (toolCalls.length > 0) {\n if (response.finishReason !== void 0 && !isCompletionFinishReason2(response.finishReason)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n usage: response.usage\n });\n }\n if (response.finishReason === \"length\") {\n throw new CompletionProviderOutputError({\n kind: \"truncated-tool-call\",\n finishReason: response.finishReason,\n usage: response.usage\n });\n }\n if (response.finishReason === \"content-filter\") {\n throw new CompletionProviderOutputError({\n kind: \"filtered-tool-call\",\n finishReason: response.finishReason,\n usage: response.usage\n });\n }\n if (response.finishReason === \"other\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n finishReason: response.finishReason,\n usage: response.usage\n });\n }\n } else if (response.finishReason === \"tool-calls\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n finishReason: response.finishReason,\n usage: response.usage\n });\n }\n const toolCallIds = /* @__PURE__ */ new Set();\n const callIds = /* @__PURE__ */ new Set();\n for (const toolCall of toolCalls) {\n if (!isNonblankString(toolCall.toolCallId) || !isNonblankString(toolCall.toolName)) {\n throw invalidToolCall(toolCall.toolCallId, response.usage);\n }\n if (toolCall.callId !== void 0 && !isNonblankString(toolCall.callId)) {\n throw invalidToolCall(toolCall.toolCallId, response.usage);\n }\n if (toolCallIds.has(toolCall.toolCallId)) {\n throw invalidToolCall(toolCall.toolCallId, response.usage);\n }\n toolCallIds.add(toolCall.toolCallId);\n if (toolCall.callId !== void 0) {\n if (callIds.has(toolCall.callId)) {\n throw invalidToolCall(toolCall.toolCallId, response.usage);\n }\n callIds.add(toolCall.callId);\n }\n if (!isJsonValue(toolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId: toolCall.toolCallId,\n usage: response.usage\n });\n }\n }\n}\nfunction invalidToolCall(toolCallId, usage) {\n return new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: isNonblankString(toolCallId) ? toolCallId : void 0,\n usage\n });\n}\nfunction assertProviderOutputErrorOptions(options) {\n if (typeof options !== \"object\" || options === null) {\n throw new TypeError(\"CompletionProviderOutputError options must be an object.\");\n }\n if (!PROVIDER_OUTPUT_ERROR_KINDS.has(options.kind)) {\n throw new TypeError(\"CompletionProviderOutputError kind is invalid.\");\n }\n if (options.toolCallId !== void 0 && !isNonblankString(options.toolCallId)) {\n throw new TypeError(\"CompletionProviderOutputError toolCallId must be a non-empty string.\");\n }\n if (options.finishReason !== void 0 && !isCompletionFinishReason2(options.finishReason)) {\n throw new TypeError(\"CompletionProviderOutputError finishReason is invalid.\");\n }\n if (options.kind === \"truncated-tool-call\" && options.finishReason !== \"length\") {\n throw new TypeError('CompletionProviderOutputError truncated-tool-call requires \"length\".');\n }\n if (options.kind === \"filtered-tool-call\" && options.finishReason !== \"content-filter\") {\n throw new TypeError(\n 'CompletionProviderOutputError filtered-tool-call requires \"content-filter\".'\n );\n }\n if (options.finishReason === \"length\" && options.kind !== \"truncated-tool-call\") {\n throw new TypeError(\n 'CompletionProviderOutputError finishReason \"length\" requires truncated-tool-call.'\n );\n }\n if (options.finishReason === \"content-filter\" && options.kind !== \"filtered-tool-call\") {\n throw new TypeError(\n 'CompletionProviderOutputError finishReason \"content-filter\" requires filtered-tool-call.'\n );\n }\n if (options.usage !== void 0) {\n assertUsage(options.usage);\n }\n}\nfunction providerOutputErrorMessage(kind, toolCallId) {\n const toolCall = toolCallId === void 0 ? \"tool call\" : `tool call ${JSON.stringify(displayId(toolCallId))}`;\n if (kind === \"malformed-tool-arguments\") {\n return `Completion provider returned ${toolCall} with malformed JSON arguments.`;\n }\n if (kind === \"invalid-tool-arguments\") {\n return `Completion provider returned ${toolCall} with arguments that are not a JSON value.`;\n }\n if (kind === \"invalid-stream-event\") {\n return \"Completion provider returned an invalid stream event.\";\n }\n if (kind === \"invalid-response\") {\n return \"Completion provider returned a response that cannot be consumed safely.\";\n }\n if (kind === \"incomplete-tool-call\") {\n return \"Completion provider stream ended before its tool call was complete.\";\n }\n if (kind === \"incomplete-stream\") {\n return \"Completion provider stream ended without a terminal response.\";\n }\n if (kind === \"truncated-tool-call\") {\n return \"Completion provider stopped at its output limit before a tool call could be consumed safely.\";\n }\n if (kind === \"filtered-tool-call\") {\n return \"Completion provider content filtering prevented a tool call from being consumed safely.\";\n }\n return `Completion provider returned an invalid ${toolCall}.`;\n}\nfunction displayId(value) {\n let sanitized = \"\";\n for (const character of value) {\n const code = character.charCodeAt(0);\n sanitized += code <= 31 || code === 127 ? \"\\uFFFD\" : character;\n }\n return sanitized.length <= 128 ? sanitized : `${sanitized.slice(0, 127)}\\u2026`;\n}\nfunction isNonblankString(value) {\n return typeof value === \"string\" && value.trim().length > 0;\n}\nfunction isCompletionFinishReason2(value) {\n return value === \"stop\" || value === \"length\" || value === \"content-filter\" || value === \"tool-calls\" || value === \"other\";\n}\nfunction assertUsage(usage) {\n for (const value of [\n usage.inputTokens,\n usage.outputTokens,\n usage.totalTokens,\n usage.cachedInputTokens,\n usage.cacheCreationInputTokens\n ]) {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n throw new TypeError(\"CompletionProviderOutputError usage must contain finite token counts.\");\n }\n }\n if (usage.details !== void 0) {\n for (const value of Object.values(usage.details)) {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n throw new TypeError(\n \"CompletionProviderOutputError usage details must contain finite token counts.\"\n );\n }\n }\n }\n}\nfunction copyUsage(usage) {\n const copied = {\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n totalTokens: usage.totalTokens,\n cachedInputTokens: usage.cachedInputTokens,\n cacheCreationInputTokens: usage.cacheCreationInputTokens\n };\n if (usage.details !== void 0) copied.details = { ...usage.details };\n return copied;\n}\n\n// src/internal/completion-request.ts\nfunction createCompletionRequest(input, options) {\n const configuredTools = options.tools ?? [];\n const chatHistory = messagesFromInput(input);\n assertNoAgentInteractionParts(chatHistory);\n const request = {\n chatHistory,\n documents: [...options.documents ?? []],\n tools: configuredTools.filter((tool) => !isProviderTool(tool))\n };\n const providerTools = configuredTools.filter(isProviderTool);\n if (providerTools.length > 0) request.providerTools = providerTools;\n if (options.instructions !== void 0 && options.instructions.length > 0) {\n request.instructions = options.instructions;\n }\n if (options.temperature !== void 0) request.temperature = options.temperature;\n if (options.maxTokens !== void 0) request.maxTokens = options.maxTokens;\n if (options.toolChoice !== void 0) request.toolChoice = options.toolChoice;\n if (options.outputSchema !== void 0) request.outputSchema = options.outputSchema;\n if (options.controls !== void 0) {\n const controls = Object.fromEntries(\n Object.entries(options.controls).filter(\n (entry) => typeof entry[1] === \"string\"\n )\n );\n if (Object.keys(controls).length > 0) request.controls = Object.freeze(controls);\n }\n if (options.providerOptions !== void 0) {\n assertJsonObject(options.providerOptions, \"providerOptions\");\n request.providerOptions = options.providerOptions;\n }\n return request;\n}\nfunction assertNoAgentInteractionParts(messages) {\n for (const message of messages) {\n if (message.role === \"tool\" && message.content.some((part) => part.type !== \"tool-result\")) {\n throw new TypeError(\n \"Completion messages contain an unresolved Agent interaction response. Resume the Agent with its continuation instead of sending interaction parts directly to a provider.\"\n );\n }\n }\n}\nfunction messagesFromInput(input) {\n if (typeof input === \"string\") {\n return [{ role: \"user\", content: input }];\n }\n if (Array.isArray(input)) {\n if (input.length === 0) {\n throw new Error(\"input must contain at least one Message.\");\n }\n return parseMessages(input);\n }\n return [parseMessage(input)];\n}\n\n// src/completion/stream-accumulator.ts\nvar CompletionStreamAccumulator = class {\n orderedParts = [];\n textParts = /* @__PURE__ */ new Map();\n reasoningByKey = /* @__PURE__ */ new Map();\n reasoningKeyById = /* @__PURE__ */ new Map();\n toolCalls = /* @__PURE__ */ new Map();\n sources = /* @__PURE__ */ new Map();\n providerToolCalls = /* @__PURE__ */ new Map();\n finalResponse;\n messageId;\n nextTextKey = 0;\n nextReasoningKey = 0;\n accept(event) {\n if (event.type === \"text_delta\") {\n if (typeof event.delta !== \"string\") {\n throw new CompletionProviderOutputError({ kind: \"invalid-stream-event\" });\n }\n this.appendText(event.delta);\n return { type: \"text_delta\", delta: event.delta };\n }\n if (event.type === \"reasoning_delta\") {\n if (typeof event.delta !== \"string\" || event.id !== void 0 && !isNonblankString2(event.id) || event.signature !== void 0 && !isNonblankString2(event.signature) || event.contentType !== void 0 && !isReasoningContentType(event.contentType)) {\n throw new CompletionProviderOutputError({ kind: \"invalid-stream-event\" });\n }\n const reasoning = this.reasoningStateForEvent(event);\n this.appendReasoning(reasoning, event);\n return reasoningDeltaEvent(event);\n }\n if (event.type === \"tool_call_delta\") {\n if (!isNonblankString2(event.id)) {\n throw new CompletionProviderOutputError({ kind: \"invalid-tool-call\" });\n }\n const toolCall = this.toolCallStateForId(event.id);\n if (toolCall.fullCallSeen) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n if (event.callId !== void 0) {\n if (!isNonblankString2(event.callId)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n if (toolCall.callId !== void 0 && toolCall.callId !== event.callId) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.callId = event.callId;\n }\n if (event.name !== void 0) {\n if (!isNonblankString2(event.name)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n if (toolCall.name.length > 0 && toolCall.name !== event.name) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.name = event.name;\n }\n if (event.signature !== void 0) {\n if (!isNonblankString2(event.signature) || toolCall.signature !== void 0 && toolCall.signature !== event.signature) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.signature = event.signature;\n }\n if (event.argumentsMode !== void 0 && event.argumentsMode !== \"append\" && event.argumentsMode !== \"replace\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-stream-event\",\n toolCallId: toolCall.id\n });\n }\n if (event.argumentsMode !== void 0 && event.argumentsDelta === void 0) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-stream-event\",\n toolCallId: toolCall.id\n });\n }\n if (event.argumentsDelta !== void 0) {\n if (typeof event.argumentsDelta !== \"string\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId: toolCall.id\n });\n }\n if (event.argumentsMode === \"replace\") {\n if (toolCall.argumentsText.length > 0 && toolCall.argumentsText !== event.argumentsDelta && (toolCall.argumentsSnapshotSeen || !event.argumentsDelta.startsWith(toolCall.argumentsText))) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.argumentsText = event.argumentsDelta;\n toolCall.argumentsSnapshotSeen = true;\n } else {\n if (toolCall.argumentsSnapshotSeen) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.id\n });\n }\n toolCall.argumentsText += event.argumentsDelta;\n }\n }\n return void 0;\n }\n if (event.type === \"tool_call\") {\n this.upsertToolCall(event.toolCall);\n return { type: \"tool_call\", toolCall: event.toolCall };\n }\n if (event.type === \"source\") {\n this.sources.set(sourceKey(event.source), event.source);\n return { type: \"source\", source: event.source };\n }\n if (event.type === \"provider_tool_call\") {\n this.providerToolCalls.set(event.toolCall.id, event.toolCall);\n return { type: \"provider_tool_call\", toolCall: event.toolCall };\n }\n if (event.type === \"message_id\") {\n if (!isNonblankString2(event.id)) {\n throw new CompletionProviderOutputError({ kind: \"invalid-stream-event\" });\n }\n this.messageId = event.id;\n return void 0;\n }\n if (event.type === \"final\") {\n this.finalResponse = event.response;\n return void 0;\n }\n return void 0;\n }\n response() {\n this.assertAccumulatedFinishReason();\n let accumulatedResponse;\n try {\n accumulatedResponse = this.buildAccumulatedResponse();\n } catch (error) {\n if (error instanceof CompletionProviderOutputError && this.finalResponse !== void 0) {\n throw providerOutputErrorWithUsage(error, this.finalResponse.usage);\n }\n throw error;\n }\n if (this.finalResponse !== void 0) {\n if (accumulatedResponse.choice.length === 0) {\n return this.withAccumulatedArtifacts(this.finalResponse, accumulatedResponse);\n }\n return this.mergeFinalResponse(accumulatedResponse, this.finalResponse);\n }\n return accumulatedResponse;\n }\n assertAccumulatedFinishReason() {\n if (this.finalResponse === void 0) {\n if (this.toolCalls.size === 0) {\n throw new CompletionProviderOutputError({ kind: \"incomplete-stream\" });\n }\n const toolCallId = this.toolCalls.size === 1 ? this.toolCalls.keys().next().value : void 0;\n throw new CompletionProviderOutputError({\n kind: \"incomplete-tool-call\",\n toolCallId\n });\n }\n if (this.toolCalls.size === 0) return;\n const finishReason = this.finalResponse.finishReason;\n if (finishReason === \"length\") {\n throw new CompletionProviderOutputError({\n kind: \"truncated-tool-call\",\n finishReason,\n usage: this.finalResponse.usage\n });\n }\n if (finishReason === \"content-filter\") {\n throw new CompletionProviderOutputError({\n kind: \"filtered-tool-call\",\n finishReason,\n usage: this.finalResponse.usage\n });\n }\n if (finishReason !== void 0 && finishReason !== \"stop\" && finishReason !== \"tool-calls\") {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n usage: this.finalResponse.usage\n });\n }\n }\n buildAccumulatedResponse() {\n const choice = [];\n for (const part of this.orderedParts) {\n if (part.type === \"text\") {\n const text = this.textParts.get(part.key) ?? \"\";\n if (text.length > 0) {\n choice.push({ type: \"text\", text });\n }\n continue;\n }\n if (part.type === \"reasoning\") {\n const reasoning = this.reasoningByKey.get(part.key);\n if (reasoning !== void 0) {\n choice.push(reasoningContent(reasoning));\n }\n continue;\n }\n const toolCall = this.toolCalls.get(part.key);\n if (toolCall !== void 0) {\n choice.push(toolCallContent(toolCall));\n }\n }\n const response = {\n choice,\n usage: Usage.empty(),\n rawResponse: void 0\n };\n if (this.messageId !== void 0) {\n response.messageId = this.messageId;\n }\n const sources = [...this.sources.values()];\n if (sources.length > 0) {\n response.sources = sources;\n }\n const providerToolCalls = [...this.providerToolCalls.values()];\n if (providerToolCalls.length > 0) {\n response.providerToolCalls = providerToolCalls;\n }\n return response;\n }\n upsertToolCall(toolCall) {\n if (!isNonblankString2(toolCall.toolCallId) || !isNonblankString2(toolCall.toolName) || toolCall.callId !== void 0 && !isNonblankString2(toolCall.callId) || toolCall.signature !== void 0 && !isNonblankString2(toolCall.signature)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: isNonblankString2(toolCall.toolCallId) ? toolCall.toolCallId : void 0\n });\n }\n if (!isJsonValue(toolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId: toolCall.toolCallId\n });\n }\n const existing = this.toolCalls.get(toolCall.toolCallId);\n if (existing !== void 0) {\n if (existing.fullCallSeen) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.toolCallId\n });\n }\n if (existing.name.length > 0 && existing.name !== toolCall.toolName || existing.callId !== void 0 && existing.callId !== toolCall.callId || existing.signature !== void 0 && toolCall.signature !== void 0 && existing.signature !== toolCall.signature) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.toolCallId\n });\n }\n if (existing.argumentsText.length > 0) {\n const accumulatedInput = parseToolArguments(existing.id, existing.argumentsText);\n if (!jsonValuesEqual(accumulatedInput, toolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: toolCall.toolCallId\n });\n }\n }\n }\n if (!this.toolCalls.has(toolCall.toolCallId)) {\n this.orderedParts.push({ type: \"tool_call\", key: toolCall.toolCallId });\n }\n const partial = {\n id: toolCall.toolCallId,\n name: toolCall.toolName,\n argumentsText: JSON.stringify(toolCall.input),\n argumentsSnapshotSeen: true,\n fullCallSeen: true\n };\n if (toolCall.callId !== void 0) {\n partial.callId = toolCall.callId;\n }\n const signature = toolCall.signature ?? existing?.signature;\n if (signature !== void 0) {\n partial.signature = signature;\n }\n this.toolCalls.set(toolCall.toolCallId, partial);\n }\n mergeFinalResponse(accumulatedResponse, finalResponse) {\n if (finalResponse.choice.length === 0) {\n const mergedResponse = {\n ...accumulatedResponse,\n usage: finalResponse.usage,\n rawResponse: finalResponse.rawResponse\n };\n if (finalResponse.finishReason !== void 0) {\n mergedResponse.finishReason = finalResponse.finishReason;\n }\n if (finalResponse.providerFinishReason !== void 0) {\n mergedResponse.providerFinishReason = finalResponse.providerFinishReason;\n }\n if (finalResponse.messageId !== void 0) {\n mergedResponse.messageId = finalResponse.messageId;\n }\n return this.withAccumulatedArtifacts(mergedResponse, accumulatedResponse);\n }\n const accumulatedNonTool = accumulatedResponse.choice.filter(\n (content) => content.type !== \"tool-call\"\n );\n const finalNonTool = finalResponse.choice.filter((content) => content.type !== \"tool-call\");\n if (accumulatedNonTool.length > 0 && !nonToolPartsEqual(accumulatedNonTool, finalNonTool)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-stream-event\",\n usage: finalResponse.usage\n });\n }\n const accumulatedById = /* @__PURE__ */ new Map();\n const accumulatedByCallId = /* @__PURE__ */ new Map();\n for (const content of accumulatedResponse.choice) {\n if (content.type !== \"tool-call\") continue;\n accumulatedById.set(content.toolCallId, content);\n if (content.callId !== void 0) accumulatedByCallId.set(content.callId, content);\n }\n const matchedAccumulatedToolCalls = /* @__PURE__ */ new Set();\n const choice = finalResponse.choice.map((content) => {\n if (content.type !== \"tool-call\") return content;\n const accumulated = accumulatedById.get(content.toolCallId);\n if (accumulated === void 0) {\n const changedIdentity = content.callId === void 0 ? void 0 : accumulatedByCallId.get(content.callId);\n if (changedIdentity !== void 0) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: changedIdentity.toolCallId,\n usage: finalResponse.usage\n });\n }\n return content;\n }\n matchedAccumulatedToolCalls.add(accumulated);\n return mergeFinalToolCall(accumulated, content, finalResponse.usage);\n });\n for (const accumulated of accumulatedById.values()) {\n if (!matchedAccumulatedToolCalls.has(accumulated)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: accumulated.toolCallId,\n usage: finalResponse.usage\n });\n }\n }\n return this.withAccumulatedArtifacts({ ...finalResponse, choice }, accumulatedResponse);\n }\n appendText(delta) {\n const lastPart = this.orderedParts.at(-1);\n const key = lastPart?.type === \"text\" ? lastPart.key : this.createTextKey();\n if (lastPart?.type !== \"text\") {\n this.orderedParts.push({ type: \"text\", key });\n }\n this.textParts.set(key, `${this.textParts.get(key) ?? \"\"}${delta}`);\n }\n reasoningStateForEvent(event) {\n if (event.id !== void 0) {\n const existingKey = this.reasoningKeyById.get(event.id);\n if (existingKey !== void 0) {\n const existing = this.reasoningByKey.get(existingKey);\n if (existing !== void 0) {\n return existing;\n }\n }\n const key2 = this.createReasoningKey();\n const reasoning2 = { id: event.id, text: \"\" };\n this.reasoningKeyById.set(event.id, key2);\n this.reasoningByKey.set(key2, reasoning2);\n this.orderedParts.push({ type: \"reasoning\", key: key2 });\n return reasoning2;\n }\n const lastPart = this.orderedParts.at(-1);\n if (lastPart?.type === \"reasoning\") {\n const lastReasoning = this.reasoningByKey.get(lastPart.key);\n if (lastReasoning !== void 0 && lastReasoning.id === void 0) {\n return lastReasoning;\n }\n }\n const key = this.createReasoningKey();\n const reasoning = { text: \"\" };\n this.reasoningByKey.set(key, reasoning);\n this.orderedParts.push({ type: \"reasoning\", key });\n return reasoning;\n }\n toolCallStateForId(id) {\n const existing = this.toolCalls.get(id);\n if (existing !== void 0) {\n return existing;\n }\n const toolCall = {\n id,\n name: \"\",\n argumentsText: \"\",\n argumentsSnapshotSeen: false,\n fullCallSeen: false\n };\n this.toolCalls.set(id, toolCall);\n this.orderedParts.push({ type: \"tool_call\", key: id });\n return toolCall;\n }\n withMessageIdFallback(response, accumulatedResponse) {\n if (response.messageId !== void 0 || accumulatedResponse.messageId === void 0) {\n return response;\n }\n return { ...response, messageId: accumulatedResponse.messageId };\n }\n withAccumulatedArtifacts(response, accumulatedResponse) {\n const withMessageId = this.withMessageIdFallback(response, accumulatedResponse);\n const sources = mergeSources(accumulatedResponse.sources, response.sources);\n const providerToolCalls = mergeProviderToolCalls(\n accumulatedResponse.providerToolCalls,\n response.providerToolCalls\n );\n let accumulated = { ...withMessageId };\n if (sources.length > 0) accumulated = { ...accumulated, sources };\n if (providerToolCalls.length > 0) {\n accumulated = { ...accumulated, providerToolCalls };\n }\n return accumulated;\n }\n createTextKey() {\n this.nextTextKey += 1;\n return `text_${this.nextTextKey.toString()}`;\n }\n createReasoningKey() {\n this.nextReasoningKey += 1;\n return `reasoning_${this.nextReasoningKey.toString()}`;\n }\n appendReasoning(reasoning, event) {\n const contentType = event.contentType ?? \"text\";\n if (contentType === \"text\" || contentType === \"summary\") {\n reasoning.text += event.delta;\n }\n if (event.contentType === void 0 && event.signature === void 0) {\n return;\n }\n reasoning.details ??= [];\n const last = reasoning.details.at(-1);\n if (contentType === \"text\") {\n if (last?.type === \"text\") {\n let detail = {\n ...last,\n text: `${last.text}${event.delta}`\n };\n if (event.signature !== void 0) detail = { ...detail, signature: event.signature };\n reasoning.details[reasoning.details.length - 1] = detail;\n } else {\n reasoning.details.push(\n event.signature === void 0 ? { type: \"text\", text: event.delta } : { type: \"text\", text: event.delta, signature: event.signature }\n );\n }\n return;\n }\n if (contentType === \"summary\") {\n if (last?.type === \"summary\") {\n reasoning.details[reasoning.details.length - 1] = {\n ...last,\n text: `${last.text}${event.delta}`\n };\n } else {\n reasoning.details.push({ type: \"summary\", text: event.delta });\n }\n return;\n }\n if (contentType === \"encrypted\") {\n reasoning.details.push({ type: \"encrypted\", data: event.delta });\n return;\n }\n reasoning.details.push({ type: \"redacted\", data: event.delta });\n }\n};\nfunction sourceKey(source) {\n return `${source.url}\\0${source.startIndex ?? \"\"}\\0${source.endIndex ?? \"\"}`;\n}\nfunction mergeSources(accumulated, final) {\n const sources = /* @__PURE__ */ new Map();\n for (const source of [...accumulated ?? [], ...final ?? []]) {\n sources.set(sourceKey(source), source);\n }\n return [...sources.values()];\n}\nfunction mergeProviderToolCalls(accumulated, final) {\n const toolCalls = /* @__PURE__ */ new Map();\n for (const toolCall of [...accumulated ?? [], ...final ?? []]) {\n toolCalls.set(toolCall.id, toolCall);\n }\n return [...toolCalls.values()];\n}\nfunction reasoningContent(reasoning) {\n const content = reasoning.details === void 0 ? { type: \"reasoning\", text: reasoning.text } : { type: \"reasoning\", text: reasoning.text, details: reasoning.details };\n return reasoning.id === void 0 ? content : { ...content, id: reasoning.id };\n}\nfunction toolCallContent(toolCall) {\n const argumentsValue = parseToolArguments(toolCall.id, toolCall.argumentsText);\n let content = {\n type: \"tool-call\",\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n input: argumentsValue\n };\n if (toolCall.callId !== void 0) content = { ...content, callId: toolCall.callId };\n if (toolCall.signature !== void 0) content = { ...content, signature: toolCall.signature };\n return content;\n}\nfunction mergeFinalToolCall(accumulated, finalToolCall, usage) {\n if (finalToolCall.toolCallId !== accumulated.toolCallId || finalToolCall.toolName !== accumulated.toolName || accumulated.callId !== void 0 && finalToolCall.callId !== accumulated.callId || accumulated.signature !== void 0 && finalToolCall.signature !== void 0 && finalToolCall.signature !== accumulated.signature) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: accumulated.toolCallId,\n usage\n });\n }\n if (!isJsonValue(finalToolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId: accumulated.toolCallId,\n usage\n });\n }\n if (!jsonValuesEqual(accumulated.input, finalToolCall.input)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-call\",\n toolCallId: accumulated.toolCallId,\n usage\n });\n }\n let merged = {\n type: \"tool-call\",\n toolCallId: finalToolCall.toolCallId,\n toolName: finalToolCall.toolName,\n input: accumulated.input\n };\n const callId = finalToolCall.callId ?? accumulated.callId;\n if (callId !== void 0) merged = { ...merged, callId };\n const signature = finalToolCall.signature ?? accumulated.signature;\n if (signature !== void 0) merged = { ...merged, signature };\n return merged;\n}\nfunction reasoningDeltaEvent(event) {\n const mapped = { type: \"reasoning_delta\", delta: event.delta };\n if (event.id !== void 0) mapped.id = event.id;\n if (event.contentType !== void 0) mapped.contentType = event.contentType;\n if (event.signature !== void 0) mapped.signature = event.signature;\n return mapped;\n}\nfunction parseToolArguments(toolCallId, text) {\n let value;\n try {\n value = JSON.parse(text);\n } catch {\n throw new CompletionProviderOutputError({\n kind: \"malformed-tool-arguments\",\n toolCallId\n });\n }\n if (!isJsonValue(value)) {\n throw new CompletionProviderOutputError({\n kind: \"invalid-tool-arguments\",\n toolCallId\n });\n }\n return value;\n}\nfunction jsonValuesEqual(left, right) {\n if (left === right) {\n return true;\n }\n if (left === null || right === null || typeof left !== \"object\" || typeof right !== \"object\") {\n return false;\n }\n if (isJsonArray(left) || isJsonArray(right)) {\n if (!isJsonArray(left) || !isJsonArray(right) || left.length !== right.length) {\n return false;\n }\n return left.every((value, index) => {\n const rightValue = right[index];\n return rightValue !== void 0 && jsonValuesEqual(value, rightValue);\n });\n }\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n if (leftKeys.length !== rightKeys.length) {\n return false;\n }\n for (const key of leftKeys) {\n if (!Object.hasOwn(right, key)) {\n return false;\n }\n const leftValue = left[key];\n const rightValue = right[key];\n if (leftValue === void 0 || rightValue === void 0 || !jsonValuesEqual(leftValue, rightValue)) {\n return false;\n }\n }\n return true;\n}\nfunction nonToolPartsEqual(accumulated, final) {\n if (accumulated.length !== final.length) return false;\n if (!isJsonValue(accumulated) || !isJsonValue(final)) return false;\n const unmatched = [...final];\n for (const part of accumulated) {\n const index = unmatched.findIndex((candidate) => jsonValuesEqual(part, candidate));\n if (index < 0) return false;\n unmatched.splice(index, 1);\n }\n return true;\n}\nfunction isJsonArray(value) {\n return Array.isArray(value);\n}\nfunction providerOutputErrorWithUsage(error, usage) {\n const shared = { usage };\n if (error.toolCallId !== void 0) shared.toolCallId = error.toolCallId;\n if (error.kind === \"truncated-tool-call\") {\n return new CompletionProviderOutputError({\n ...shared,\n kind: error.kind,\n finishReason: \"length\"\n });\n }\n if (error.kind === \"filtered-tool-call\") {\n return new CompletionProviderOutputError({\n ...shared,\n kind: error.kind,\n finishReason: \"content-filter\"\n });\n }\n if (error.finishReason === \"length\" || error.finishReason === \"content-filter\") {\n throw error;\n }\n return new CompletionProviderOutputError({\n ...shared,\n kind: error.kind,\n finishReason: error.finishReason\n });\n}\nfunction isNonblankString2(value) {\n return typeof value === \"string\" && value.trim().length > 0;\n}\nfunction isReasoningContentType(value) {\n return value === \"text\" || value === \"summary\" || value === \"encrypted\" || value === \"redacted\";\n}\n\n// src/completion/generate-completion.ts\nvar CompletionStructuredOutputError = class extends Error {\n phase;\n outputLength;\n usage;\n finishReason;\n providerFinishReason;\n constructor(options) {\n const failure = options.phase === \"truncated\" ? \"because the provider reached its output limit\" : options.phase === \"content-filter\" ? \"because the provider filtered the response\" : options.phase === \"parse\" ? \"during JSON parsing\" : \"during schema validation\";\n super(`Structured completion output failed ${failure}.`, { cause: options.cause });\n this.name = \"CompletionStructuredOutputError\";\n this.phase = options.phase;\n this.outputLength = options.outputLength;\n this.usage = options.usage;\n this.finishReason = options.finishReason;\n this.providerFinishReason = options.providerFinishReason;\n }\n};\nasync function generateCompletion(options) {\n throwIfAborted(options.abortSignal);\n const request = requestFromOptions(options);\n assertCompletionRequestSupported(options.model, request);\n const retries = resolveOptionalRetries(options.retries);\n const response = await sendCompletion(options.model, request, retries, options.abortSignal);\n return resultFromResponse(response, structuredOutputSchema(options));\n}\nfunction streamCompletion(options) {\n throwIfAborted(options.abortSignal);\n const request = requestFromOptions(options);\n if (!isStreamingCompletionModel(options.model) || !options.model.capabilities.streaming) {\n throw new Error(\"This completion model does not support streaming\");\n }\n assertCompletionRequestSupported(options.model, request, { streaming: true });\n const retries = resolveOptionalRetries(options.retries);\n return streamCompletionWithRetries(\n options.model,\n request,\n retries,\n options.abortSignal,\n structuredOutputSchema(options)\n );\n}\nasync function sendCompletion(model, request, retries, abortSignal) {\n const callOptions = modelCallOptions(abortSignal);\n let attempt = 1;\n let failedUsage = Usage.empty();\n while (true) {\n try {\n throwIfAborted(abortSignal);\n const response = await model.completion(request, callOptions);\n assertCompletionResponseIntegrity({ response });\n return Usage.isEmpty(failedUsage) ? response : { ...response, usage: Usage.add(failedUsage, response.usage) };\n } catch (error) {\n const normalizedError = abortSignal?.aborted === true ? abortError(abortSignal.reason) : error;\n const attemptUsage = completionProviderOutputErrorUsage(normalizedError);\n if (attemptUsage !== void 0) failedUsage = Usage.add(failedUsage, attemptUsage);\n const retryOptions = retryOptionsForFailure(retries, {\n error: normalizedError,\n attempt,\n streaming: false\n });\n if (retryOptions === void 0) throw normalizedError;\n await waitForRetry(retryDelayMs(retryOptions, attempt), abortSignal);\n attempt += 1;\n }\n }\n}\nfunction resolveOptionalRetries(setting) {\n return setting === void 0 || setting === false ? void 0 : resolveRetryOptions(setting);\n}\nasync function* streamCompletionWithRetries(model, request, retries, abortSignal, outputSchema) {\n let attempt = 1;\n let swallowedUsage = Usage.empty();\n const callOptions = modelCallOptions(abortSignal);\n attemptLoop: while (true) {\n let exposedProgress = false;\n let retryDelay;\n const accumulator = new CompletionStreamAccumulator();\n try {\n throwIfAborted(abortSignal);\n const events = model.streamCompletion(request, callOptions);\n for await (const event of events) {\n if (event.type === \"error\" && !exposedProgress) {\n const eventError = abortSignal?.aborted === true ? abortError(abortSignal.reason) : event.error;\n const eventUsage = event.usage ?? completionProviderOutputErrorUsage(eventError) ?? Usage.empty();\n const retryOptions = retryOptionsForFailure(retries, {\n error: eventError,\n attempt,\n streaming: true\n });\n if (retryOptions !== void 0) {\n swallowedUsage = Usage.add(swallowedUsage, eventUsage);\n retryDelay = retryDelayMs(retryOptions, attempt);\n break;\n }\n }\n if (event.type === \"error\") {\n const eventError = abortSignal?.aborted === true ? abortError(abortSignal.reason) : event.error;\n const eventUsage = event.usage ?? completionProviderOutputErrorUsage(eventError) ?? Usage.empty();\n yield {\n type: \"error\",\n error: eventError,\n usage: Usage.add(swallowedUsage, eventUsage)\n };\n return;\n }\n if (event.type === \"final\") {\n const cumulativeUsage = Usage.add(swallowedUsage, event.response.usage);\n try {\n accumulator.accept(event);\n const accumulatedResponse = accumulator.response();\n const response = Usage.isEmpty(swallowedUsage) ? accumulatedResponse : { ...accumulatedResponse, usage: cumulativeUsage };\n assertCompletionResponseIntegrity({ response });\n yield {\n type: \"final\",\n result: resultFromResponse(response, outputSchema)\n };\n } catch (error) {\n const retryOptions = exposedProgress ? void 0 : retryOptionsForFailure(retries, {\n error,\n attempt,\n streaming: true\n });\n if (retryOptions !== void 0) {\n swallowedUsage = cumulativeUsage;\n await waitForRetry(retryDelayMs(retryOptions, attempt), abortSignal);\n attempt += 1;\n continue attemptLoop;\n }\n yield { type: \"error\", error, usage: cumulativeUsage };\n }\n return;\n }\n accumulator.accept(event);\n exposedProgress = true;\n yield event;\n }\n if (retryDelay !== void 0) {\n await waitForRetry(retryDelay, abortSignal);\n attempt += 1;\n continue;\n }\n let incomplete;\n try {\n accumulator.response();\n incomplete = new CompletionProviderOutputError({ kind: \"incomplete-stream\" });\n } catch (error) {\n incomplete = error;\n }\n if (!exposedProgress) {\n const retryOptions = retryOptionsForFailure(retries, {\n error: incomplete,\n attempt,\n streaming: true\n });\n if (retryOptions !== void 0) {\n await waitForRetry(retryDelayMs(retryOptions, attempt), abortSignal);\n attempt += 1;\n continue;\n }\n }\n yield { type: \"error\", error: incomplete, usage: swallowedUsage };\n return;\n } catch (error) {\n const normalizedError = abortSignal?.aborted === true ? abortError(abortSignal.reason) : error;\n const attemptUsage = completionProviderOutputErrorUsage(normalizedError);\n const cumulativeUsage = attemptUsage === void 0 ? swallowedUsage : Usage.add(swallowedUsage, attemptUsage);\n if (!exposedProgress) {\n const retryOptions = retryOptionsForFailure(retries, {\n error: normalizedError,\n attempt,\n streaming: true\n });\n if (retryOptions !== void 0) {\n try {\n swallowedUsage = cumulativeUsage;\n await waitForRetry(retryDelayMs(retryOptions, attempt), abortSignal);\n attempt += 1;\n continue;\n } catch (waitError) {\n yield { type: \"error\", error: waitError, usage: cumulativeUsage };\n return;\n }\n }\n }\n yield { type: \"error\", error: normalizedError, usage: cumulativeUsage };\n return;\n }\n }\n}\nfunction requestFromOptions(options) {\n const input = inputFromOptions(options);\n return createCompletionRequest(input, {\n instructions: options.instructions,\n documents: options.documents,\n tools: options.tools,\n temperature: options.temperature,\n maxTokens: options.maxTokens,\n toolChoice: options.toolChoice,\n controls: options.controls,\n providerOptions: options.providerOptions,\n outputSchema: \"outputSchema\" in options && options.outputSchema !== void 0 ? toProviderJsonSchema(options.outputSchema) : void 0\n });\n}\nfunction inputFromOptions(options) {\n const prompt = options.prompt;\n const messages = options.messages;\n const hasPrompt = prompt !== void 0;\n const hasMessages = messages !== void 0;\n if (hasPrompt === hasMessages) {\n throw new TypeError(\"Exactly one of prompt or messages must be provided.\");\n }\n if (hasPrompt) {\n if (typeof prompt !== \"string\" || prompt.trim().length === 0) {\n throw new TypeError(\"Completion prompt must be a non-empty string.\");\n }\n return prompt;\n }\n if (!Array.isArray(messages)) {\n throw new TypeError(\"Completion messages must be an array of Message values.\");\n }\n return messages;\n}\nfunction structuredOutputSchema(options) {\n return options.outputSchema;\n}\nfunction resultFromResponse(response, outputSchema) {\n const text = textFromAssistantContent(response.choice);\n const result = {\n output: outputSchema === void 0 ? text : parseCompletionOutput(text, outputSchema, response),\n text,\n content: [...response.choice],\n usage: response.usage,\n rawResponse: response.rawResponse\n };\n if (response.finishReason !== void 0) result.finishReason = response.finishReason;\n if (response.providerFinishReason !== void 0) {\n result.providerFinishReason = response.providerFinishReason;\n }\n if (response.contextUsage !== void 0) result.contextUsage = response.contextUsage;\n if (response.messageId !== void 0) result.messageId = response.messageId;\n if (response.sources !== void 0) result.sources = [...response.sources];\n if (response.providerToolCalls !== void 0) {\n result.providerToolCalls = [...response.providerToolCalls];\n }\n return result;\n}\nfunction parseCompletionOutput(text, schema, response) {\n if (response.finishReason === \"content-filter\") {\n throw new CompletionStructuredOutputError({\n phase: \"content-filter\",\n outputLength: text.length,\n usage: response.usage,\n finishReason: response.finishReason,\n providerFinishReason: response.providerFinishReason\n });\n }\n if (response.finishReason === \"length\") {\n throw new CompletionStructuredOutputError({\n phase: \"truncated\",\n outputLength: text.length,\n usage: response.usage,\n finishReason: response.finishReason,\n providerFinishReason: response.providerFinishReason\n });\n }\n let json;\n try {\n json = JSON.parse(text);\n if (!isJsonValue(json)) {\n throw new TypeError(\"Structured completion output is not a JSON value.\");\n }\n } catch (error) {\n throw new CompletionStructuredOutputError({\n phase: \"parse\",\n outputLength: text.length,\n usage: response.usage,\n finishReason: response.finishReason,\n providerFinishReason: response.providerFinishReason,\n cause: error\n });\n }\n try {\n return schema.parse(json);\n } catch (error) {\n throw new CompletionStructuredOutputError({\n phase: \"schema\",\n outputLength: text.length,\n usage: response.usage,\n finishReason: response.finishReason,\n providerFinishReason: response.providerFinishReason,\n cause: error\n });\n }\n}\nfunction modelCallOptions(abortSignal) {\n return abortSignal === void 0 ? void 0 : { abortSignal };\n}\nfunction isStreamingCompletionModel(model) {\n return typeof model.streamCompletion === \"function\";\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 createCompletionRequest,\n COMPLETION_PROVIDER_OUTPUT_ERROR_CODE,\n CompletionProviderOutputError,\n assertCompletionResponseIntegrity,\n CompletionStreamAccumulator,\n CompletionStructuredOutputError,\n generateCompletion,\n streamCompletion,\n isStreamingCompletionModel\n};\n//# sourceMappingURL=chunk-OI3LSMJG.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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"}
@@ -30,7 +30,7 @@
30
30
  favicon.href = favicon.href.replace("favicon-dark.svg", `favicon-${theme}.svg`);
31
31
  })();
32
32
  </script>
33
- <script type="module" crossorigin src="/ui/assets/index-DF9Ysm8q.js"></script>
33
+ <script type="module" crossorigin src="/ui/assets/index-DWBW14h1.js"></script>
34
34
  <link rel="modulepreload" crossorigin href="/ui/assets/utils-DzstcfqT.js">
35
35
  <link rel="modulepreload" crossorigin href="/ui/assets/button-B_AoswCu.js">
36
36
  <link rel="modulepreload" crossorigin href="/ui/assets/dist-Dr6EWOhl.js">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anvia/studio",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "Studio UI and HTTP runtime for Anvia agents.",
5
5
  "author": "anvia",
6
6
  "maintainer": "Indra Zulfi",
@@ -46,11 +46,11 @@
46
46
  "react-dom": "^19.2.8",
47
47
  "tailwind-merge": "^3.6.0",
48
48
  "ws": "^8.21.3",
49
- "@anvia/client": "1.0.8",
50
- "@anvia/graph": "1.0.10",
51
- "@anvia/react-ui": "1.0.8",
52
- "@anvia/server": "1.0.8",
53
- "@anvia/react": "1.0.8"
49
+ "@anvia/graph": "1.0.11",
50
+ "@anvia/react": "1.0.10",
51
+ "@anvia/react-ui": "1.0.10",
52
+ "@anvia/server": "1.0.10",
53
+ "@anvia/client": "1.0.10"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@tailwindcss/typography": "^0.5.19",
@@ -67,10 +67,10 @@
67
67
  "vite": "^8.2.2",
68
68
  "vitest": "^4.0.8",
69
69
  "zod": "^4.4.3",
70
- "@anvia/core": "1.0.8"
70
+ "@anvia/core": "1.0.9"
71
71
  },
72
72
  "peerDependencies": {
73
- "@anvia/core": "1.0.8"
73
+ "@anvia/core": "1.0.9"
74
74
  },
75
75
  "engines": {
76
76
  "node": ">=20.12.0"