@acorex-platform/extension-ai-otel-client 0.0.33 → 0.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/fesm2022/acorex-platform-extension-ai-otel-client-trace-ai-page.component-DJtbLNgP.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acorex-platform-extension-ai-otel-client-trace-ai-page.component-DJtbLNgP.mjs","sources":["../../../../libs/extensions/ai/otel/client/src/lib/features/traces/project-gen-ai-trace.util.ts","../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-ai-page.component.ts","../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-ai-page.component.html"],"sourcesContent":["import type { TraceSpanDto, TraceTimelineDto } from '@acorex-platform/module-system-insight-client/contracts';\n\n//#region ----- Types -----\n\nexport interface AxpGenAiTraceSummary {\n model?: string;\n provider?: string;\n agentName?: string;\n inputTokens?: number;\n outputTokens?: number;\n duration?: number;\n}\n\nexport interface AxpGenAiTraceStep {\n spanId: string;\n operationName: string;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n timeToFirstChunkSeconds?: number;\n finishReasons?: unknown;\n duration: number;\n status?: string;\n}\n\nexport interface AxpGenAiTraceTool {\n spanId: string;\n toolName?: string;\n toolCallId?: string;\n duration: number;\n status?: string;\n error?: string;\n}\n\nexport interface AxpGenAiTraceView {\n hasAi: true;\n summary: AxpGenAiTraceSummary;\n steps: AxpGenAiTraceStep[];\n tools: AxpGenAiTraceTool[];\n inputMessages?: unknown;\n outputMessages?: unknown;\n}\n\n//#endregion\n\n//#region ----- Tag readers -----\n\nfunction readString(tags: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = tags?.[key];\n if (typeof value === 'string' && value.trim()) {\n return value.trim();\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n return undefined;\n}\n\nfunction readNumber(tags: Record<string, unknown> | undefined, key: string): number | undefined {\n const value = tags?.[key];\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'string' && value.trim()) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n}\n\nfunction genAiOperation(span: TraceSpanDto): string | undefined {\n return readString(span.tags, 'gen_ai.operation.name');\n}\n\nfunction parseMaybeJson(value: unknown): unknown {\n if (typeof value !== 'string') {\n return value;\n }\n const trimmed = value.trim();\n if (\n !(\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n )\n ) {\n return value;\n }\n try {\n return JSON.parse(trimmed) as unknown;\n } catch {\n return value;\n }\n}\n\nfunction firstDefinedTag(spans: TraceSpanDto[], key: string): unknown {\n for (const span of spans) {\n const value = span.tags?.[key];\n if (value !== undefined && value !== null && value !== '') {\n return value;\n }\n }\n return undefined;\n}\n\n//#endregion\n\n//#region ----- Projection -----\n\nexport function projectGenAiTrace(\n timeline: TraceTimelineDto | null | undefined,\n): AxpGenAiTraceView | null {\n const spans = timeline?.spans ?? [];\n const genAiSpans = spans.filter((span) => Boolean(genAiOperation(span)));\n if (!timeline || genAiSpans.length === 0) {\n return null;\n }\n\n const root =\n genAiSpans.find((span) => genAiOperation(span) === 'invoke_agent') ?? genAiSpans[0];\n const rootTags = root?.tags;\n\n const steps = genAiSpans\n .filter((span) => genAiOperation(span) === 'chat')\n .map((span) => ({\n spanId: span.spanId,\n operationName: span.operationName,\n model: readString(span.tags, 'gen_ai.request.model') ?? readString(span.tags, 'gen_ai.response.model'),\n inputTokens: readNumber(span.tags, 'gen_ai.usage.input_tokens'),\n outputTokens: readNumber(span.tags, 'gen_ai.usage.output_tokens'),\n timeToFirstChunkSeconds: readNumber(span.tags, 'gen_ai.client.operation.time_to_first_chunk'),\n finishReasons: parseMaybeJson(span.tags?.['gen_ai.response.finish_reasons']),\n duration: span.duration ?? 0,\n status: span.status,\n }));\n\n const tools = genAiSpans\n .filter((span) => genAiOperation(span) === 'execute_tool')\n .map((span) => ({\n spanId: span.spanId,\n toolName: readString(span.tags, 'gen_ai.tool.name'),\n toolCallId: readString(span.tags, 'gen_ai.tool.call.id'),\n duration: span.duration ?? 0,\n status: span.status,\n error: span.error,\n }));\n\n const inputMessages = parseMaybeJson(firstDefinedTag(genAiSpans, 'gen_ai.input.messages'));\n const outputMessages = parseMaybeJson(\n firstDefinedTag([...genAiSpans].reverse(), 'gen_ai.output.messages'),\n );\n\n const summedInputTokens = steps.reduce<number | undefined>((total, step) => {\n if (step.inputTokens === undefined) {\n return total;\n }\n return (total ?? 0) + step.inputTokens;\n }, undefined);\n const summedOutputTokens = steps.reduce<number | undefined>((total, step) => {\n if (step.outputTokens === undefined) {\n return total;\n }\n return (total ?? 0) + step.outputTokens;\n }, undefined);\n\n return {\n hasAi: true,\n summary: {\n model:\n timeline.aiModel ??\n readString(rootTags, 'gen_ai.request.model') ??\n readString(rootTags, 'gen_ai.response.model') ??\n steps.find((step) => step.model)?.model,\n provider: readString(rootTags, 'gen_ai.provider.name'),\n agentName:\n readString(rootTags, 'gen_ai.agent.name') ??\n readString(rootTags, 'ai.telemetry.functionId'),\n inputTokens:\n timeline.aiInputTokens ??\n readNumber(rootTags, 'gen_ai.usage.input_tokens') ??\n summedInputTokens,\n outputTokens:\n timeline.aiOutputTokens ??\n readNumber(rootTags, 'gen_ai.usage.output_tokens') ??\n summedOutputTokens,\n duration: timeline.duration,\n },\n steps,\n tools,\n ...(inputMessages != null ? { inputMessages } : {}),\n ...(outputMessages != null ? { outputMessages } : {}),\n };\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXLoadingModule } from '@acorex/components/loading';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport {\n AXPPageLayoutBase,\n AXPPageLayoutBaseComponent,\n} from '@acorex-platform/framework-client/layout/views';\nimport { AXPQueryExecutor } from '@acorex-platform/framework-client/runtime';\nimport { runtimeQueryPayloadData } from '@acorex-platform/framework-shared/core';\nimport {\n AXMSystemInsightQueryKeys,\n type TraceTimelineDto,\n} from '@acorex-platform/module-system-insight-client/contracts';\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { projectGenAiTrace, type AxpGenAiTraceView } from './project-gen-ai-trace.util';\n\n//#endregion\n\n//#region ----- Component -----\n\n/**\n * TraceEntry detail tab — GenAI summary, steps, tools, and optional transcript.\n */\n@Component({\n selector: 'axe-trace-ai-page',\n standalone: true,\n imports: [CommonModule, AXBadgeModule, AXLoadingModule, AXTranslationModule],\n templateUrl: './trace-ai-page.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: AXPPageLayoutBase,\n useExisting: AXETraceAiPageComponent,\n },\n ],\n host: { class: 'axe-trace-ai-page block w-full min-h-0' },\n})\nexport class AXETraceAiPageComponent extends AXPPageLayoutBaseComponent {\n //#region ----- Services & Dependencies -----\n\n private readonly queryExecutor = inject(AXPQueryExecutor);\n private readonly translationService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ----- Inputs -----\n\n /** Entity record from TraceEntry detail host. */\n rootContext = input<Record<string, unknown>>();\n pageConfig = input<Record<string, unknown>>();\n\n //#endregion\n\n //#region ----- State Signals -----\n\n readonly loading = signal(true);\n readonly timeline = signal<TraceTimelineDto | null>(null);\n\n readonly view = computed<AxpGenAiTraceView | null>(() => projectGenAiTrace(this.timeline()));\n\n readonly traceId = computed(() => {\n const ctx = this.rootContext() ?? {};\n const fromTraceId = typeof ctx['traceId'] === 'string' ? ctx['traceId'].trim() : '';\n if (fromTraceId) {\n return fromTraceId;\n }\n const fromId = typeof ctx['id'] === 'string' ? ctx['id'].trim() : '';\n return fromId;\n });\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n #loadEffect = effect(() => {\n const id = this.traceId();\n void this.loadTimeline(id);\n });\n\n //#endregion\n\n //#region ----- Page metadata -----\n\n override async getPageTitle(): Promise<string> {\n return this.translationService.translateAsync('@extensions-ai-otel:pages.trace-ai.title');\n }\n\n //#endregion\n\n //#region ----- Display -----\n\n hasValue(value: unknown): boolean {\n if (value === undefined || value === null) {\n return false;\n }\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n if (Array.isArray(value)) {\n return value.length > 0;\n }\n if (typeof value === 'object') {\n return Object.keys(value as Record<string, unknown>).length > 0;\n }\n return true;\n }\n\n formatJson(value: unknown): string {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n return JSON.stringify(JSON.parse(trimmed) as unknown, null, 2);\n } catch {\n return value;\n }\n }\n return value;\n }\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n }\n\n //#endregion\n\n //#region ----- Data Loading -----\n\n private async loadTimeline(traceId: string): Promise<void> {\n if (!traceId) {\n this.timeline.set(null);\n this.loading.set(false);\n return;\n }\n\n this.loading.set(true);\n try {\n const result = await this.queryExecutor.fetch<string, TraceTimelineDto>(\n AXMSystemInsightQueryKeys.TraceTimeline.Get,\n traceId,\n );\n this.timeline.set(runtimeQueryPayloadData(result) ?? null);\n this.recompute();\n } finally {\n this.loading.set(false);\n }\n }\n\n //#endregion\n}\n\n//#endregion\n","<!-- ----- Trace AI detail page ----- -->\n<div class=\"axe-trace-ai flex flex-col gap-4 p-4 w-full min-h-0\">\n @if (loading()) {\n <!-- ----- Loading indicator while timeline is fetched ----- -->\n <div class=\"flex justify-center py-10\">\n <ax-loading />\n </div>\n }\n <!-- ----- Empty state when timeline is missing ----- -->\n @else if (!timeline()) {\n <p class=\"typo-caption text-muted\">\n {{ '@extensions-ai-otel:pages.trace-ai.not-found' | translate | async }}\n </p>\n }\n <!-- ----- Empty state when the trace has no GenAI spans ----- -->\n @else if (!view()) {\n <p class=\"typo-caption text-muted\">\n {{ '@extensions-ai-otel:pages.trace-ai.empty' | translate | async }}\n </p>\n }\n <!-- ----- GenAI summary, steps, tools, transcript ----- -->\n @else if (view(); as data) {\n <div class=\"flex flex-wrap items-center gap-2\">\n @if (data.summary.agentName; as agentName) {\n <ax-badge [text]=\"agentName\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (data.summary.provider; as provider) {\n <ax-badge [text]=\"provider\" color=\"secondary\" size=\"sm\"></ax-badge>\n }\n @if (data.summary.model; as model) {\n <span class=\"text-sm\">{{ model }}</span>\n }\n <span class=\"text-sm text-muted ms-auto\">\n {{ '@extensions-ai-otel:pages.trace-ai.duration' | translate | async }}:\n {{ data.summary.duration ?? 0 }} ms\n </span>\n </div>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-3 text-sm\">\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.model' | translate | async }}\n </div>\n <div>{{ data.summary.model || ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.provider' | translate | async }}\n </div>\n <div>{{ data.summary.provider || ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.input-tokens' | translate | async }}\n </div>\n <div>{{ data.summary.inputTokens ?? ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.output-tokens' | translate | async }}\n </div>\n <div>{{ data.summary.outputTokens ?? ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n </div>\n\n <div>\n <div class=\"text-sm font-medium mb-2\">\n {{ '@extensions-ai-otel:pages.trace-ai.steps' | translate | async }}\n </div>\n <!--->\n <!-- ----- Chat step list ----- -->\n @if (data.steps.length > 0) {\n <div class=\"flex flex-col gap-3\">\n @for (step of data.steps; track step.spanId) {\n <div class=\"border border-lightest rounded-md p-3 flex flex-col gap-2\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <strong class=\"text-sm\">{{ step.operationName }}</strong>\n @if (step.status) {\n <ax-badge\n [text]=\"step.status\"\n [color]=\"step.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n }\n <span class=\"text-sm text-muted ms-auto\">{{ step.duration }} ms</span>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-2 text-sm\">\n @if (step.model) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.model' | translate | async }}\n </div>\n <div>{{ step.model }}</div>\n </div>\n }\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.input-tokens' | translate | async }}\n </div>\n <div>{{ step.inputTokens ?? ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.output-tokens' | translate | async }}\n </div>\n <div>{{ step.outputTokens ?? ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n @if (step.timeToFirstChunkSeconds != null) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.time-to-first-chunk' | translate | async }}\n </div>\n <div>{{ step.timeToFirstChunkSeconds }}</div>\n </div>\n }\n </div>\n @if (hasValue(step.finishReasons)) {\n <div>\n <div class=\"text-muted mb-1 text-sm\">\n {{ '@extensions-ai-otel:pages.trace-ai.finish-reason' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-32\">{{\n formatJson(step.finishReasons)\n }}</pre>\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- ----- No chat steps ----- -->\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@extensions-ai-otel:pages.trace-ai.no-steps' | translate | async }}\n </p>\n }\n </div>\n\n <div>\n <div class=\"text-sm font-medium mb-2\">\n {{ '@extensions-ai-otel:pages.trace-ai.tools' | translate | async }}\n </div>\n <!--->\n <!-- ----- Tool execution list ----- -->\n @if (data.tools.length > 0) {\n <div class=\"flex flex-col gap-3\">\n @for (tool of data.tools; track tool.spanId) {\n <div class=\"border border-lightest rounded-md p-3 flex flex-col gap-2\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <strong class=\"text-sm\">{{ tool.toolName || tool.spanId }}</strong>\n @if (tool.status) {\n <ax-badge\n [text]=\"tool.status\"\n [color]=\"tool.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n }\n <span class=\"text-sm text-muted ms-auto\">{{ tool.duration }} ms</span>\n </div>\n @if (tool.toolCallId) {\n <div class=\"text-sm\">\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.tool-call-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ tool.toolCallId }}</div>\n </div>\n }\n @if (tool.error) {\n <pre class=\"text-sm whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-32 text-danger\">{{\n tool.error\n }}</pre>\n }\n </div>\n }\n </div>\n }\n <!-- ----- No tool spans ----- -->\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@extensions-ai-otel:pages.trace-ai.no-tools' | translate | async }}\n </p>\n }\n </div>\n\n <div>\n <div class=\"text-sm font-medium mb-2\">\n {{ '@extensions-ai-otel:pages.trace-ai.transcript' | translate | async }}\n </div>\n <!--->\n <!-- ----- Recorded prompt / completion ----- -->\n @if (hasValue(data.inputMessages) || hasValue(data.outputMessages)) {\n <!--->\n <!-- ----- Input messages ----- -->\n @if (hasValue(data.inputMessages)) {\n <div class=\"mb-3\">\n <div class=\"text-muted mb-1 text-sm\">\n {{ '@extensions-ai-otel:pages.trace-ai.input' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(data.inputMessages)\n }}</pre>\n </div>\n }\n <!--->\n <!-- ----- Output messages ----- -->\n @if (hasValue(data.outputMessages)) {\n <div>\n <div class=\"text-muted mb-1 text-sm\">\n {{ '@extensions-ai-otel:pages.trace-ai.output' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(data.outputMessages)\n }}</pre>\n </div>\n }\n }\n <!-- ----- Transcript omitted when recording is off ----- -->\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@extensions-ai-otel:pages.trace-ai.no-transcript' | translate | async }}\n </p>\n }\n </div>\n }\n</div>\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"acorex-platform-extension-ai-otel-client-trace-ai-page.component-DJtbLNgP.mjs","sources":["../../../../libs/extensions/ai/otel/client/src/lib/features/traces/project-gen-ai-trace.util.ts","../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-ai-page.component.ts","../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-ai-page.component.html"],"sourcesContent":["import type { TraceSpanDto, TraceTimelineDto } from '@acorex-platform/module-system-insight-client/contracts';\n\n//#region ----- Types -----\n\nexport interface AxpGenAiTraceSummary {\n model?: string;\n provider?: string;\n agentName?: string;\n inputTokens?: number;\n outputTokens?: number;\n duration?: number;\n}\n\nexport interface AxpGenAiTraceStep {\n spanId: string;\n operationName: string;\n model?: string;\n inputTokens?: number;\n outputTokens?: number;\n timeToFirstChunkSeconds?: number;\n finishReasons?: unknown;\n duration: number;\n status?: string;\n}\n\nexport interface AxpGenAiTraceTool {\n spanId: string;\n toolName?: string;\n toolCallId?: string;\n duration: number;\n status?: string;\n error?: string;\n}\n\nexport interface AxpGenAiTraceView {\n hasAi: true;\n summary: AxpGenAiTraceSummary;\n steps: AxpGenAiTraceStep[];\n tools: AxpGenAiTraceTool[];\n inputMessages?: unknown;\n outputMessages?: unknown;\n}\n\n//#endregion\n\n//#region ----- Tag readers -----\n\nfunction readString(tags: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = tags?.[key];\n if (typeof value === 'string' && value.trim()) {\n return value.trim();\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n return undefined;\n}\n\nfunction readNumber(tags: Record<string, unknown> | undefined, key: string): number | undefined {\n const value = tags?.[key];\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'string' && value.trim()) {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n}\n\nfunction genAiOperation(span: TraceSpanDto): string | undefined {\n return readString(span.tags, 'gen_ai.operation.name');\n}\n\nfunction parseMaybeJson(value: unknown): unknown {\n if (typeof value !== 'string') {\n return value;\n }\n const trimmed = value.trim();\n if (\n !(\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n )\n ) {\n return value;\n }\n try {\n return JSON.parse(trimmed) as unknown;\n } catch {\n return value;\n }\n}\n\nfunction firstDefinedTag(spans: TraceSpanDto[], key: string): unknown {\n for (const span of spans) {\n const value = span.tags?.[key];\n if (value !== undefined && value !== null && value !== '') {\n return value;\n }\n }\n return undefined;\n}\n\n//#endregion\n\n//#region ----- Projection -----\n\nexport function projectGenAiTrace(\n timeline: TraceTimelineDto | null | undefined,\n): AxpGenAiTraceView | null {\n const spans = timeline?.spans ?? [];\n const genAiSpans = spans.filter((span) => Boolean(genAiOperation(span)));\n if (!timeline || genAiSpans.length === 0) {\n return null;\n }\n\n const root =\n genAiSpans.find((span) => genAiOperation(span) === 'invoke_agent') ?? genAiSpans[0];\n const rootTags = root?.tags;\n\n const steps = genAiSpans\n .filter((span) => genAiOperation(span) === 'chat')\n .map((span) => ({\n spanId: span.spanId,\n operationName: span.operationName,\n model: readString(span.tags, 'gen_ai.request.model') ?? readString(span.tags, 'gen_ai.response.model'),\n inputTokens: readNumber(span.tags, 'gen_ai.usage.input_tokens'),\n outputTokens: readNumber(span.tags, 'gen_ai.usage.output_tokens'),\n timeToFirstChunkSeconds: readNumber(span.tags, 'gen_ai.client.operation.time_to_first_chunk'),\n finishReasons: parseMaybeJson(span.tags?.['gen_ai.response.finish_reasons']),\n duration: span.duration ?? 0,\n status: span.status,\n }));\n\n const tools = genAiSpans\n .filter((span) => genAiOperation(span) === 'execute_tool')\n .map((span) => ({\n spanId: span.spanId,\n toolName: readString(span.tags, 'gen_ai.tool.name'),\n toolCallId: readString(span.tags, 'gen_ai.tool.call.id'),\n duration: span.duration ?? 0,\n status: span.status,\n error: span.error,\n }));\n\n const inputMessages = parseMaybeJson(firstDefinedTag(genAiSpans, 'gen_ai.input.messages'));\n const outputMessages = parseMaybeJson(\n firstDefinedTag([...genAiSpans].reverse(), 'gen_ai.output.messages'),\n );\n\n const summedInputTokens = steps.reduce<number | undefined>((total, step) => {\n if (step.inputTokens === undefined) {\n return total;\n }\n return (total ?? 0) + step.inputTokens;\n }, undefined);\n const summedOutputTokens = steps.reduce<number | undefined>((total, step) => {\n if (step.outputTokens === undefined) {\n return total;\n }\n return (total ?? 0) + step.outputTokens;\n }, undefined);\n\n return {\n hasAi: true,\n summary: {\n model:\n timeline.aiModel ??\n readString(rootTags, 'gen_ai.request.model') ??\n readString(rootTags, 'gen_ai.response.model') ??\n steps.find((step) => step.model)?.model,\n provider: readString(rootTags, 'gen_ai.provider.name'),\n agentName:\n readString(rootTags, 'gen_ai.agent.name') ??\n readString(rootTags, 'ai.telemetry.functionId'),\n inputTokens:\n timeline.aiInputTokens ??\n readNumber(rootTags, 'gen_ai.usage.input_tokens') ??\n summedInputTokens,\n outputTokens:\n timeline.aiOutputTokens ??\n readNumber(rootTags, 'gen_ai.usage.output_tokens') ??\n summedOutputTokens,\n duration: timeline.duration,\n },\n steps,\n tools,\n ...(inputMessages != null ? { inputMessages } : {}),\n ...(outputMessages != null ? { outputMessages } : {}),\n };\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXBadgeModule } from '@acorex/components/badge';\nimport { AXLoadingModule } from '@acorex/components/loading';\nimport { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';\nimport {\n AXPPageLayoutBase,\n AXPPageLayoutBaseComponent,\n} from '@acorex-platform/framework-client/layout/views';\nimport { AXPQueryExecutor } from '@acorex-platform/framework-client/runtime';\nimport { runtimeQueryPayloadData } from '@acorex-platform/framework-shared/core';\nimport {\n AXMSystemInsightQueryKeys,\n type TraceTimelineDto,\n} from '@acorex-platform/module-system-insight-client/contracts';\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { projectGenAiTrace, type AxpGenAiTraceView } from './project-gen-ai-trace.util';\n\n//#endregion\n\n//#region ----- Component -----\n\n/**\n * TraceEntry detail tab — GenAI summary, steps, tools, and optional transcript.\n */\n@Component({\n selector: 'axe-trace-ai-page',\n standalone: true,\n imports: [CommonModule, AXBadgeModule, AXLoadingModule, AXTranslationModule],\n templateUrl: './trace-ai-page.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: AXPPageLayoutBase,\n useExisting: AXETraceAiPageComponent,\n },\n ],\n host: { class: 'axe-trace-ai-page block w-full min-h-0' },\n})\nexport class AXETraceAiPageComponent extends AXPPageLayoutBaseComponent {\n //#region ----- Services & Dependencies -----\n\n private readonly queryExecutor = inject(AXPQueryExecutor);\n private readonly translationService = inject(AXTranslationService);\n\n //#endregion\n\n //#region ----- Inputs -----\n\n /** Entity record from TraceEntry detail host. */\n rootContext = input<Record<string, unknown>>();\n pageConfig = input<Record<string, unknown>>();\n\n //#endregion\n\n //#region ----- State Signals -----\n\n readonly loading = signal(true);\n readonly timeline = signal<TraceTimelineDto | null>(null);\n\n readonly view = computed<AxpGenAiTraceView | null>(() => projectGenAiTrace(this.timeline()));\n\n readonly traceId = computed(() => {\n const ctx = this.rootContext() ?? {};\n const fromTraceId = typeof ctx['traceId'] === 'string' ? ctx['traceId'].trim() : '';\n if (fromTraceId) {\n return fromTraceId;\n }\n const fromId = typeof ctx['id'] === 'string' ? ctx['id'].trim() : '';\n return fromId;\n });\n\n //#endregion\n\n //#region ----- Lifecycle -----\n\n #loadEffect = effect(() => {\n const id = this.traceId();\n void this.loadTimeline(id);\n });\n\n //#endregion\n\n //#region ----- Page metadata -----\n\n override async getPageTitle(): Promise<string> {\n return this.translationService.translateAsync('@extensions-ai-otel:pages.trace-ai.title');\n }\n\n //#endregion\n\n //#region ----- Display -----\n\n hasValue(value: unknown): boolean {\n if (value === undefined || value === null) {\n return false;\n }\n if (typeof value === 'string') {\n return value.trim().length > 0;\n }\n if (Array.isArray(value)) {\n return value.length > 0;\n }\n if (typeof value === 'object') {\n return Object.keys(value as Record<string, unknown>).length > 0;\n }\n return true;\n }\n\n formatJson(value: unknown): string {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n return JSON.stringify(JSON.parse(trimmed) as unknown, null, 2);\n } catch {\n return value;\n }\n }\n return value;\n }\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n }\n\n //#endregion\n\n //#region ----- Data Loading -----\n\n private async loadTimeline(traceId: string): Promise<void> {\n if (!traceId) {\n this.timeline.set(null);\n this.loading.set(false);\n return;\n }\n\n this.loading.set(true);\n try {\n const result = await this.queryExecutor.fetch<string, TraceTimelineDto>(\n AXMSystemInsightQueryKeys.TraceTimeline.Get,\n traceId,\n );\n this.timeline.set(runtimeQueryPayloadData(result) ?? null);\n this.recompute();\n } finally {\n this.loading.set(false);\n }\n }\n\n //#endregion\n}\n\n//#endregion\n","<!-- ----- Trace AI detail page ----- -->\n<div class=\"axe-trace-ai flex flex-col gap-4 p-4 w-full min-h-0\">\n @if (loading()) {\n <!-- ----- Loading indicator while timeline is fetched ----- -->\n <div class=\"flex justify-center py-10\">\n <ax-loading />\n </div>\n }\n <!-- ----- Empty state when timeline is missing ----- -->\n @else if (!timeline()) {\n <p class=\"typo-caption text-muted\">\n {{ '@extensions-ai-otel:pages.trace-ai.not-found' | translate | async }}\n </p>\n }\n <!-- ----- Empty state when the trace has no GenAI spans ----- -->\n @else if (!view()) {\n <p class=\"typo-caption text-muted\">\n {{ '@extensions-ai-otel:pages.trace-ai.empty' | translate | async }}\n </p>\n }\n <!-- ----- GenAI summary, steps, tools, transcript ----- -->\n @else if (view(); as data) {\n <div class=\"flex flex-wrap items-center gap-2\">\n @if (data.summary.agentName; as agentName) {\n <ax-badge [text]=\"agentName\" color=\"primary\" size=\"sm\"></ax-badge>\n }\n @if (data.summary.provider; as provider) {\n <ax-badge [text]=\"provider\" color=\"secondary\" size=\"sm\"></ax-badge>\n }\n @if (data.summary.model; as model) {\n <span class=\"text-sm\">{{ model }}</span>\n }\n <span class=\"text-sm text-muted ms-auto\">\n {{ '@extensions-ai-otel:pages.trace-ai.duration' | translate | async }}:\n {{ data.summary.duration ?? 0 }} ms\n </span>\n </div>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-3 text-sm\">\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.model' | translate | async }}\n </div>\n <div>{{ data.summary.model || ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.provider' | translate | async }}\n </div>\n <div>{{ data.summary.provider || ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.input-tokens' | translate | async }}\n </div>\n <div>{{ data.summary.inputTokens ?? ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.output-tokens' | translate | async }}\n </div>\n <div>{{ data.summary.outputTokens ?? ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n </div>\n\n <div>\n <div class=\"text-sm font-medium mb-2\">\n {{ '@extensions-ai-otel:pages.trace-ai.steps' | translate | async }}\n </div>\n <!--->\n <!-- ----- Chat step list ----- -->\n @if (data.steps.length > 0) {\n <div class=\"flex flex-col gap-3\">\n @for (step of data.steps; track step.spanId) {\n <div class=\"border border-lightest rounded-md p-3 flex flex-col gap-2\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <strong class=\"text-sm\">{{ step.operationName }}</strong>\n @if (step.status) {\n <ax-badge\n [text]=\"step.status\"\n [color]=\"step.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n }\n <span class=\"text-sm text-muted ms-auto\">{{ step.duration }} ms</span>\n </div>\n <div class=\"grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-2 text-sm\">\n @if (step.model) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.model' | translate | async }}\n </div>\n <div>{{ step.model }}</div>\n </div>\n }\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.input-tokens' | translate | async }}\n </div>\n <div>{{ step.inputTokens ?? ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.output-tokens' | translate | async }}\n </div>\n <div>{{ step.outputTokens ?? ('@extensions-ai-otel:pages.trace-ai.unavailable' | translate | async) }}</div>\n </div>\n @if (step.timeToFirstChunkSeconds != null) {\n <div>\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.time-to-first-chunk' | translate | async }}\n </div>\n <div>{{ step.timeToFirstChunkSeconds }}</div>\n </div>\n }\n </div>\n @if (hasValue(step.finishReasons)) {\n <div>\n <div class=\"text-muted mb-1 text-sm\">\n {{ '@extensions-ai-otel:pages.trace-ai.finish-reason' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-32\">{{\n formatJson(step.finishReasons)\n }}</pre>\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- ----- No chat steps ----- -->\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@extensions-ai-otel:pages.trace-ai.no-steps' | translate | async }}\n </p>\n }\n </div>\n\n <div>\n <div class=\"text-sm font-medium mb-2\">\n {{ '@extensions-ai-otel:pages.trace-ai.tools' | translate | async }}\n </div>\n <!--->\n <!-- ----- Tool execution list ----- -->\n @if (data.tools.length > 0) {\n <div class=\"flex flex-col gap-3\">\n @for (tool of data.tools; track tool.spanId) {\n <div class=\"border border-lightest rounded-md p-3 flex flex-col gap-2\">\n <div class=\"flex flex-wrap items-center gap-2\">\n <strong class=\"text-sm\">{{ tool.toolName || tool.spanId }}</strong>\n @if (tool.status) {\n <ax-badge\n [text]=\"tool.status\"\n [color]=\"tool.status === 'error' ? 'danger' : 'success'\"\n size=\"sm\"\n ></ax-badge>\n }\n <span class=\"text-sm text-muted ms-auto\">{{ tool.duration }} ms</span>\n </div>\n @if (tool.toolCallId) {\n <div class=\"text-sm\">\n <div class=\"text-muted mb-1\">\n {{ '@extensions-ai-otel:pages.trace-ai.tool-call-id' | translate | async }}\n </div>\n <div class=\"font-mono break-all\">{{ tool.toolCallId }}</div>\n </div>\n }\n @if (tool.error) {\n <pre class=\"text-sm whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-32 text-danger\">{{\n tool.error\n }}</pre>\n }\n </div>\n }\n </div>\n }\n <!-- ----- No tool spans ----- -->\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@extensions-ai-otel:pages.trace-ai.no-tools' | translate | async }}\n </p>\n }\n </div>\n\n <div>\n <div class=\"text-sm font-medium mb-2\">\n {{ '@extensions-ai-otel:pages.trace-ai.transcript' | translate | async }}\n </div>\n <!--->\n <!-- ----- Recorded prompt / completion ----- -->\n @if (hasValue(data.inputMessages) || hasValue(data.outputMessages)) {\n <!--->\n <!-- ----- Input messages ----- -->\n @if (hasValue(data.inputMessages)) {\n <div class=\"mb-3\">\n <div class=\"text-muted mb-1 text-sm\">\n {{ '@extensions-ai-otel:pages.trace-ai.input' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(data.inputMessages)\n }}</pre>\n </div>\n }\n <!--->\n <!-- ----- Output messages ----- -->\n @if (hasValue(data.outputMessages)) {\n <div>\n <div class=\"text-muted mb-1 text-sm\">\n {{ '@extensions-ai-otel:pages.trace-ai.output' | translate | async }}\n </div>\n <pre class=\"text-xs whitespace-pre-wrap m-0 p-2 rounded-md bg-lightest overflow-auto max-h-56\">{{\n formatJson(data.outputMessages)\n }}</pre>\n </div>\n }\n }\n <!-- ----- Transcript omitted when recording is off ----- -->\n @else {\n <p class=\"typo-caption text-muted m-0\">\n {{ '@extensions-ai-otel:pages.trace-ai.no-transcript' | translate | async }}\n </p>\n }\n </div>\n }\n</div>\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acorex-platform-extension-ai-otel-client.mjs","sources":["../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-ai-page.constants.ts","../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-entry-ai.entity-modifier.ts","../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-ai-page-component.provider.ts","../../../../libs/extensions/ai/otel/client/src/lib/ai-otel-extension.module.ts","../../../../libs/extensions/ai/otel/client/src/acorex-platform-extension-ai-otel-client.ts"],"sourcesContent":["/** Registry key for the GenAI tab contributed onto TraceEntry. */\nexport const TRACE_AI_PAGE_COMPONENT_KEY = 'trace-ai-page';\n","//#region ----- Imports -----\n\nimport { AXPEntityModifierProvider } from '@acorex-platform/framework-client/layout/entity';\nimport { RootConfig as InsightRootConfig } from '@acorex-platform/module-system-insight-client/contracts';\nimport { TRACE_AI_PAGE_COMPONENT_KEY } from './trace-ai-page.constants';\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst TRACE_AI_PAGE_ORDER = 3;\n\n//#endregion\n\n//#region ----- Modifier -----\n\n/** Adds the GenAI tab to SystemInsight.TraceEntry detail views. */\nexport const AXETraceEntryAiEntityModifier: AXPEntityModifierProvider = {\n entityName: InsightRootConfig.entities.traceEntry.name,\n order: 60,\n modifier: (ctx) => {\n if (ctx.module.get() !== InsightRootConfig.module.name) {\n return;\n }\n\n ctx.entity.pages ??= [];\n const page = {\n componentKey: TRACE_AI_PAGE_COMPONENT_KEY,\n title: '@extensions-ai-otel:pages.trace-ai.title',\n icon: 'fa-light fa-sparkles',\n layout: { order: TRACE_AI_PAGE_ORDER, position: 'after' as const },\n hidden: `{{ !context.eval(\"hasAi\") }}`,\n };\n const existingIndex = ctx.entity.pages.findIndex(\n (entry) => entry.componentKey === TRACE_AI_PAGE_COMPONENT_KEY,\n );\n if (existingIndex >= 0) {\n ctx.entity.pages[existingIndex] = page;\n return;\n }\n\n ctx.entity.pages.push(page);\n },\n};\n\n//#endregion\n","//#region ----- Imports -----\n\nimport {\n AXPPageComponentDefinition,\n AXPPageComponentProvider,\n} from '@acorex-platform/framework-client/layout/components';\nimport { Injectable } from '@angular/core';\nimport { TRACE_AI_PAGE_COMPONENT_KEY } from './trace-ai-page.constants';\n\n//#endregion\n\n//#region ----- Provider -----\n\n@Injectable()\nexport class AXETraceAiPageComponentProvider implements AXPPageComponentProvider {\n async components(): Promise<AXPPageComponentDefinition[]> {\n return [\n {\n key: TRACE_AI_PAGE_COMPONENT_KEY,\n loader: () => import('./trace-ai-page.component').then((m) => m.AXETraceAiPageComponent),\n },\n ];\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXP_PAGE_COMPONENT_PROVIDER } from '@acorex-platform/framework-client/layout/components';\nimport { AXP_ENTITY_MODIFIER } from '@acorex-platform/framework-client/layout/entity';\nimport { NgModule } from '@angular/core';\nimport { AXETraceEntryAiEntityModifier } from './features/traces/trace-entry-ai.entity-modifier';\nimport { AXETraceAiPageComponentProvider } from './features/traces/trace-ai-page-component.provider';\n\n//#endregion\n\n//#region ----- Module -----\n\n/**\n * AI SDK OpenTelemetry UI — contributes the GenAI tab on SystemInsight.TraceEntry.\n */\n@NgModule({\n providers: [\n { provide: AXP_ENTITY_MODIFIER, useValue: AXETraceEntryAiEntityModifier, multi: true },\n {\n provide: AXP_PAGE_COMPONENT_PROVIDER,\n useClass: AXETraceAiPageComponentProvider,\n multi: true,\n },\n ],\n})\nexport class AXEAiOtelExtensionModule {}\n\n//#endregion\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["InsightRootConfig"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"acorex-platform-extension-ai-otel-client.mjs","sources":["../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-ai-page.constants.ts","../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-entry-ai.entity-modifier.ts","../../../../libs/extensions/ai/otel/client/src/lib/features/traces/trace-ai-page-component.provider.ts","../../../../libs/extensions/ai/otel/client/src/lib/ai-otel-extension.module.ts","../../../../libs/extensions/ai/otel/client/src/acorex-platform-extension-ai-otel-client.ts"],"sourcesContent":["/** Registry key for the GenAI tab contributed onto TraceEntry. */\nexport const TRACE_AI_PAGE_COMPONENT_KEY = 'trace-ai-page';\n","//#region ----- Imports -----\n\nimport { AXPEntityModifierProvider } from '@acorex-platform/framework-client/layout/entity';\nimport { RootConfig as InsightRootConfig } from '@acorex-platform/module-system-insight-client/contracts';\nimport { TRACE_AI_PAGE_COMPONENT_KEY } from './trace-ai-page.constants';\n\n//#endregion\n\n//#region ----- Constants -----\n\nconst TRACE_AI_PAGE_ORDER = 3;\n\n//#endregion\n\n//#region ----- Modifier -----\n\n/** Adds the GenAI tab to SystemInsight.TraceEntry detail views. */\nexport const AXETraceEntryAiEntityModifier: AXPEntityModifierProvider = {\n entityName: InsightRootConfig.entities.traceEntry.name,\n order: 60,\n modifier: (ctx) => {\n if (ctx.module.get() !== InsightRootConfig.module.name) {\n return;\n }\n\n ctx.entity.pages ??= [];\n const page = {\n componentKey: TRACE_AI_PAGE_COMPONENT_KEY,\n title: '@extensions-ai-otel:pages.trace-ai.title',\n icon: 'fa-light fa-sparkles',\n layout: { order: TRACE_AI_PAGE_ORDER, position: 'after' as const },\n hidden: `{{ !context.eval(\"hasAi\") }}`,\n };\n const existingIndex = ctx.entity.pages.findIndex(\n (entry) => entry.componentKey === TRACE_AI_PAGE_COMPONENT_KEY,\n );\n if (existingIndex >= 0) {\n ctx.entity.pages[existingIndex] = page;\n return;\n }\n\n ctx.entity.pages.push(page);\n },\n};\n\n//#endregion\n","//#region ----- Imports -----\n\nimport {\n AXPPageComponentDefinition,\n AXPPageComponentProvider,\n} from '@acorex-platform/framework-client/layout/components';\nimport { Injectable } from '@angular/core';\nimport { TRACE_AI_PAGE_COMPONENT_KEY } from './trace-ai-page.constants';\n\n//#endregion\n\n//#region ----- Provider -----\n\n@Injectable()\nexport class AXETraceAiPageComponentProvider implements AXPPageComponentProvider {\n async components(): Promise<AXPPageComponentDefinition[]> {\n return [\n {\n key: TRACE_AI_PAGE_COMPONENT_KEY,\n loader: () => import('./trace-ai-page.component').then((m) => m.AXETraceAiPageComponent),\n },\n ];\n }\n}\n\n//#endregion\n","//#region ----- Imports -----\n\nimport { AXP_PAGE_COMPONENT_PROVIDER } from '@acorex-platform/framework-client/layout/components';\nimport { AXP_ENTITY_MODIFIER } from '@acorex-platform/framework-client/layout/entity';\nimport { NgModule } from '@angular/core';\nimport { AXETraceEntryAiEntityModifier } from './features/traces/trace-entry-ai.entity-modifier';\nimport { AXETraceAiPageComponentProvider } from './features/traces/trace-ai-page-component.provider';\n\n//#endregion\n\n//#region ----- Module -----\n\n/**\n * AI SDK OpenTelemetry UI — contributes the GenAI tab on SystemInsight.TraceEntry.\n */\n@NgModule({\n providers: [\n { provide: AXP_ENTITY_MODIFIER, useValue: AXETraceEntryAiEntityModifier, multi: true },\n {\n provide: AXP_PAGE_COMPONENT_PROVIDER,\n useClass: AXETraceAiPageComponentProvider,\n multi: true,\n },\n ],\n})\nexport class AXEAiOtelExtensionModule {}\n\n//#endregion\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["InsightRootConfig"],"mappings":"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"}
|