@newheap/platform-ai-chat 0.10.0 → 0.11.0

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":"newheap-platform-ai-chat-admin.mjs","sources":["../../../projects/nh-ai-chat/admin/src/context/nh-assistant-admin-context.component.ts","../../../projects/nh-ai-chat/admin/src/context/nh-assistant-admin-context.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-admin-agent-editor.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-admin-agent-editor.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-feedback-report.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-feedback-report.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-admin-agents.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-admin-agents.component.html","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-server-editor.component.ts","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-server-editor.component.html","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-tools.component.ts","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-tools.component.html","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-servers.component.ts","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-servers.component.html","../../../projects/nh-ai-chat/admin/src/nh-assistant-admin.component.ts","../../../projects/nh-ai-chat/admin/src/nh-assistant-admin.component.html","../../../projects/nh-ai-chat/admin/src/public-api.ts","../../../projects/nh-ai-chat/admin/src/newheap-platform-ai-chat-admin.ts"],"sourcesContent":["import { DatePipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription, forkJoin } from 'rxjs';\nimport {\n ApplicationContext,\n ApplicationContextVersion,\n NhAssistantAdminApiService,\n NhAssistantClientErrorCodes,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\n/** Maximum length of the application context and of agent instructions. */\nexport const NH_ASSISTANT_MAX_INSTRUCTIONS = 20_000;\n\nlet nextId = 0;\n\n/**\n * Editor of the application context: the current version with its hash, optimistic\n * concurrency through `expectedVersion`, and the version history.\n */\n@Component({\n selector: 'nh-assistant-admin-context',\n standalone: true,\n imports: [DatePipe, TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-context.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminContextComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n\n readonly id = `nh-assistant-admin-context-${nextId++}`;\n readonly max = NH_ASSISTANT_MAX_INSTRUCTIONS;\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly saving = signal(false);\n readonly saved = signal(false);\n readonly conflict = signal(false);\n readonly error = signal<NhAssistantError | null>(null);\n readonly context = signal<ApplicationContext | null>(null);\n readonly versions = signal<ApplicationContextVersion[]>([]);\n readonly text = signal('');\n\n readonly tooLong = computed(() => this.text().length > this.max);\n readonly dirty = computed(() => this.text() !== (this.context()?.text ?? ''));\n readonly canSave = computed(() => !this.saving() && !this.tooLong() && this.dirty() && this.context() !== null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n readonly history = computed(() => this.versions().filter(version => version.version !== this.context()?.version));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n this.load(false);\n }\n\n /** Loads the latest version; with `keepDraft` the user's unsaved text stays in the editor. */\n load(keepDraft: boolean): void {\n this.loading.set(!keepDraft);\n this.loadFailed.set(false);\n this.subscription?.unsubscribe();\n this.subscription = forkJoin([this.admin.getContext(), this.admin.getContextVersions()]).subscribe({\n next: ([context, versions]) => {\n const draft = this.text();\n this.context.set(context);\n this.versions.set(versions);\n this.text.set(keepDraft ? draft : context.text);\n this.conflict.set(false);\n this.error.set(null);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n onInput(event: Event): void {\n this.text.set((event.target as HTMLTextAreaElement).value);\n this.saved.set(false);\n }\n\n save(): void {\n const context = this.context();\n if (!context || !this.canSave()) {\n return;\n }\n\n this.saving.set(true);\n this.saved.set(false);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.updateContext({ text: this.text(), expectedVersion: context.version }).subscribe({\n next: updated => {\n this.context.set(updated);\n this.versions.update(versions => [\n { version: updated.version, hash: updated.hash, updatedAt: updated.updatedAt, updatedBy: updated.updatedBy },\n ...versions\n ]);\n this.text.set(updated.text);\n this.saving.set(false);\n this.saved.set(true);\n },\n error: (error: unknown) => {\n const failure = toNhAssistantError(error);\n this.saving.set(false);\n this.conflict.set(failure.code === NhAssistantClientErrorCodes.versionConflict);\n this.error.set(this.conflict() ? null : failure);\n }\n });\n }\n}\n","<section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || saving()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.context.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.context.description' | translate }}</p>\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (loadFailed()) {\n <div class=\"state\" role=\"alert\">\n <p>{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load(false)\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (context(); as current) {\n <form class=\"stack\" (submit)=\"$event.preventDefault(); save()\">\n <div class=\"meta\">\n <span class=\"badge\">{{ 'nh-assistant.admin.context.version' | translate: { version: current.version } }}</span>\n <span>\n @if (current.updatedBy) {\n {{ 'nh-assistant.admin.context.updated' | translate: { date: (current.updatedAt | date: 'medium'), user: current.updatedBy } }}\n } @else {\n {{ 'nh-assistant.admin.context.updated-unknown' | translate: { date: (current.updatedAt | date: 'medium') } }}\n }\n </span>\n <span class=\"mono\" [attr.title]=\"current.hash\">{{ 'nh-assistant.admin.context.hash' | translate }} {{ current.hash.slice(0, 18) }}</span>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-text'\">{{ 'nh-assistant.admin.context.label' | translate }}</label>\n <textarea\n class=\"large\"\n rows=\"14\"\n [id]=\"id + '-text'\"\n [value]=\"text()\"\n [attr.aria-describedby]=\"id + '-hint'\"\n [attr.aria-invalid]=\"tooLong() ? true : null\"\n (input)=\"onInput($event)\"></textarea>\n <p class=\"hint\" [id]=\"id + '-hint'\">\n <span [class.error-text]=\"tooLong()\">{{ tooLong() ? ('nh-assistant.admin.too-long' | translate) : '' }}</span>\n <span class=\"counter\" [class.error-text]=\"tooLong()\">{{ 'nh-assistant.admin.characters' | translate: { count: text().length, max: max } }}</span>\n </p>\n </div>\n\n @if (conflict()) {\n <div class=\"message warning\" role=\"alert\">\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">{{ 'nh-assistant.admin.context.conflict' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"load(true)\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.context.reload' | translate }}\n </button>\n </div>\n }\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n @if (saved()) {\n <p class=\"message success\" role=\"status\"><nh-assistant-icon name=\"check\" />{{ 'nh-assistant.admin.saved' | translate }}</p>\n }\n\n <div class=\"actions\">\n <button class=\"primary\" type=\"submit\" [disabled]=\"!canSave()\">\n {{ (saving() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}\n </button>\n </div>\n </form>\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-history'\">\n <h4 [id]=\"id + '-history'\">{{ 'nh-assistant.admin.context.history' | translate }}</h4>\n @if (history().length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.context.history-empty' | translate }}</p>\n } @else {\n <ol class=\"history\">\n @for (version of history(); track version.version) {\n <li>\n <span class=\"badge\">{{ 'nh-assistant.admin.context.version' | translate: { version: version.version } }}</span>\n <span>{{ version.updatedAt | date: 'medium' }}</span>\n @if (version.updatedBy) {\n <span>{{ version.updatedBy }}</span>\n }\n <span class=\"mono muted\" [attr.title]=\"version.hash\">{{ version.hash.slice(0, 18) }}</span>\n </li>\n }\n </ol>\n }\n </section>\n }\n</section>\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n untracked\n} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n AdminAgent,\n AdminAgentInput,\n AssistantAutonomy,\n McpServer,\n ɵNH_ASSISTANT_DASH_CASE as NH_ASSISTANT_DASH_CASE,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport { NH_ASSISTANT_MAX_INSTRUCTIONS } from '../context/nh-assistant-admin-context.component';\n\n/** True when a tool id matches a selector glob (`*` matches any characters). */\nexport function nhAssistantSelectorMatches(toolId: string, selector: string): boolean {\n const pattern = selector.split('*').map(part => part.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('.*');\n return new RegExp(`^${pattern}$`).test(toolId);\n}\n\nconst selectorPattern = /^[a-z0-9*][a-z0-9.*_-]*$/i;\n\nlet nextId = 0;\n\n/**\n * Creates or edits one agent: texts, autonomy, policy, tool selectors chosen from the tool\n * catalog or typed as patterns, and assigned MCP servers.\n */\n@Component({\n selector: 'nh-assistant-admin-agent-editor',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-agent-editor.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminAgentEditorComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n\n /** The agent to edit, or null for a new agent. */\n readonly agent = input<AdminAgent | null>(null);\n readonly tools = input<readonly ToolCatalogEntry[]>([]);\n readonly servers = input<readonly McpServer[]>([]);\n readonly saved = output<AdminAgent>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-agent-editor-${nextId++}`;\n readonly max = NH_ASSISTANT_MAX_INSTRUCTIONS;\n readonly autonomyLevels: readonly AssistantAutonomy[] = ['observe', 'explain', 'propose', 'simulate', 'execute'];\n\n readonly agentId = signal('');\n readonly displayName = signal('');\n readonly description = signal('');\n readonly instructions = signal('');\n readonly autonomy = signal<AssistantAutonomy>('explain');\n readonly requiredPolicy = signal('');\n readonly isEnabled = signal(true);\n readonly toolSelectors = signal<string[]>([]);\n readonly mcpServerIds = signal<string[]>([]);\n readonly newSelector = signal('');\n readonly catalogFilter = signal('');\n readonly submitted = signal(false);\n readonly saving = signal(false);\n readonly error = signal<NhAssistantError | null>(null);\n\n readonly isNew = computed(() => this.agent() === null);\n readonly idInvalid = computed(() => this.isNew() && !NH_ASSISTANT_DASH_CASE.test(this.agentId()));\n readonly nameMissing = computed(() => this.displayName().trim().length === 0);\n readonly tooLong = computed(() => this.instructions().length > this.max);\n readonly selectorInvalid = computed(() => this.newSelector().trim().length > 0 && !selectorPattern.test(this.newSelector().trim()));\n readonly valid = computed(() => !this.idInvalid() && !this.nameMissing() && !this.tooLong());\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n readonly filteredTools = computed(() => {\n const filter = this.catalogFilter().trim().toLowerCase();\n return this.tools().filter(tool => !filter ||\n tool.id.toLowerCase().includes(filter) || tool.description.toLowerCase().includes(filter));\n });\n readonly matchCount = computed(() => this.tools()\n .filter(tool => this.toolSelectors().some(selector => nhAssistantSelectorMatches(tool.id, selector))).length);\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n\n effect(() => {\n const agent = this.agent();\n untracked(() => this.reset(agent));\n });\n }\n\n isSelected(toolId: string): boolean {\n return this.toolSelectors().includes(toolId);\n }\n\n isCovered(toolId: string): boolean {\n return this.toolSelectors().some(selector => selector !== toolId && nhAssistantSelectorMatches(toolId, selector));\n }\n\n toggleTool(toolId: string, checked: boolean): void {\n this.toolSelectors.update(selectors => checked\n ? [...selectors.filter(selector => selector !== toolId), toolId]\n : selectors.filter(selector => selector !== toolId));\n }\n\n addSelector(): void {\n const selector = this.newSelector().trim();\n if (selector.length === 0 || this.selectorInvalid()) {\n return;\n }\n\n this.toolSelectors.update(selectors => selectors.includes(selector) ? selectors : [...selectors, selector]);\n this.newSelector.set('');\n }\n\n onSelectorKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n event.preventDefault();\n this.addSelector();\n }\n }\n\n removeSelector(selector: string): void {\n this.toolSelectors.update(selectors => selectors.filter(item => item !== selector));\n }\n\n toggleServer(serverId: string, checked: boolean): void {\n this.mcpServerIds.update(ids => checked ? [...ids.filter(id => id !== serverId), serverId] : ids.filter(id => id !== serverId));\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement).value;\n }\n\n checked(event: Event): boolean {\n return (event.target as HTMLInputElement).checked;\n }\n\n save(): void {\n this.submitted.set(true);\n if (!this.valid() || this.saving()) {\n return;\n }\n\n const policy = this.requiredPolicy().trim();\n const input: AdminAgentInput = {\n id: this.isNew() ? this.agentId() : this.agent()!.id,\n displayName: this.displayName().trim(),\n description: this.description().trim(),\n instructions: this.instructions(),\n toolSelectors: this.toolSelectors(),\n mcpServerIds: this.mcpServerIds(),\n requiredPolicy: policy.length > 0 ? policy : null,\n autonomy: this.autonomy(),\n isEnabled: this.isEnabled()\n };\n\n const existing = this.agent();\n const request = existing\n ? this.admin.updateAgent(existing.id, { ...input, expectedVersion: existing.version })\n : this.admin.createAgent(input);\n\n this.saving.set(true);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = request.subscribe({\n next: agent => {\n this.saving.set(false);\n this.saved.emit(agent);\n },\n error: (error: unknown) => {\n this.saving.set(false);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n private reset(agent: AdminAgent | null): void {\n this.agentId.set(agent?.id ?? '');\n this.displayName.set(agent?.displayName ?? '');\n this.description.set(agent?.description ?? '');\n this.instructions.set(agent?.instructions ?? '');\n this.autonomy.set(agent?.autonomy ?? 'explain');\n this.requiredPolicy.set(agent?.requiredPolicy ?? '');\n this.isEnabled.set(agent?.isEnabled ?? true);\n this.toolSelectors.set([...(agent?.toolSelectors ?? [])]);\n this.mcpServerIds.set([...(agent?.mcpServerIds ?? [])]);\n this.submitted.set(false);\n this.error.set(null);\n }\n}\n","<form class=\"section card\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"saving()\" (submit)=\"$event.preventDefault(); save()\">\n <h3 [id]=\"id + '-title'\">\n @if (agent(); as current) {\n {{ 'nh-assistant.admin.agent-editor.edit-title' | translate: { name: current.displayName } }}\n } @else {\n {{ 'nh-assistant.admin.agent-editor.new-title' | translate }}\n }\n </h3>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-id'\">{{ 'nh-assistant.admin.agent-editor.id' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n autocomplete=\"off\"\n [id]=\"id + '-id'\"\n [value]=\"agentId()\"\n [disabled]=\"!isNew()\"\n [attr.aria-describedby]=\"id + '-id-hint'\"\n [attr.aria-invalid]=\"submitted() && idInvalid() ? true : null\"\n (input)=\"agentId.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-id-hint'\">\n <span [class.error-text]=\"submitted() && idInvalid()\">\n {{ (submitted() && idInvalid() ? 'nh-assistant.admin.invalid-id' : 'nh-assistant.admin.agent-editor.id-hint') | translate }}\n </span>\n </p>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-name'\">{{ 'nh-assistant.admin.agent-editor.display-name' | translate }}</label>\n <input\n type=\"text\"\n [id]=\"id + '-name'\"\n [value]=\"displayName()\"\n [attr.aria-invalid]=\"submitted() && nameMissing() ? true : null\"\n [attr.aria-describedby]=\"id + '-name-hint'\"\n (input)=\"displayName.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-name-hint'\">\n @if (submitted() && nameMissing()) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.required' | translate }}</span>\n }\n </p>\n </div>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-description'\">{{ 'nh-assistant.admin.agent-editor.description' | translate }}</label>\n <input type=\"text\" [id]=\"id + '-description'\" [value]=\"description()\" (input)=\"description.set(value($event))\" />\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-instructions'\">{{ 'nh-assistant.admin.agent-editor.instructions' | translate }}</label>\n <textarea\n rows=\"8\"\n [id]=\"id + '-instructions'\"\n [value]=\"instructions()\"\n [attr.aria-describedby]=\"id + '-instructions-hint'\"\n [attr.aria-invalid]=\"tooLong() ? true : null\"\n (input)=\"instructions.set(value($event))\"></textarea>\n <p class=\"hint\" [id]=\"id + '-instructions-hint'\">\n <span [class.error-text]=\"tooLong()\">\n {{ (tooLong() ? 'nh-assistant.admin.too-long' : 'nh-assistant.admin.agent-editor.instructions-hint') | translate }}\n </span>\n <span class=\"counter\" [class.error-text]=\"tooLong()\">{{ 'nh-assistant.admin.characters' | translate: { count: instructions().length, max: max } }}</span>\n </p>\n </div>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-autonomy'\">{{ 'nh-assistant.admin.agent-editor.autonomy' | translate }}</label>\n <select [id]=\"id + '-autonomy'\" [attr.aria-describedby]=\"id + '-autonomy-hint'\" (change)=\"autonomy.set($any(value($event)))\">\n @for (level of autonomyLevels; track level) {\n <option [value]=\"level\" [selected]=\"autonomy() === level\">{{ 'nh-assistant.admin.agents.autonomy.' + level | translate }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-autonomy-hint'\">{{ 'nh-assistant.admin.agent-editor.autonomy-hint' | translate }}</p>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-policy'\">{{ 'nh-assistant.admin.agent-editor.required-policy' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n autocomplete=\"off\"\n [id]=\"id + '-policy'\"\n [value]=\"requiredPolicy()\"\n [attr.aria-describedby]=\"id + '-policy-hint'\"\n (input)=\"requiredPolicy.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.agent-editor.required-policy-hint' | translate }}</p>\n </div>\n </div>\n\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"isEnabled()\" (change)=\"isEnabled.set(checked($event))\" />\n <span>{{ 'nh-assistant.admin.agent-editor.enabled' | translate }}</span>\n </label>\n\n <fieldset class=\"subsection\">\n <legend>{{ 'nh-assistant.admin.agent-editor.tool-selectors' | translate }}</legend>\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.tool-selectors-hint' | translate }}</p>\n\n @if (toolSelectors().length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.no-selectors' | translate }}</p>\n } @else {\n <ul class=\"chips\">\n @for (selector of toolSelectors(); track selector) {\n <li class=\"chip\">\n <span>{{ selector }}</span>\n <button\n type=\"button\"\n [attr.aria-label]=\"'nh-assistant.admin.agent-editor.remove-selector' | translate: { selector: selector }\"\n [attr.title]=\"'nh-assistant.admin.agent-editor.remove-selector' | translate: { selector: selector }\"\n (click)=\"removeSelector(selector)\">\n <nh-assistant-icon name=\"x\" />\n </button>\n </li>\n }\n </ul>\n <p class=\"muted\" role=\"status\">{{ 'nh-assistant.admin.agent-editor.matches' | translate: { count: matchCount() } }}</p>\n }\n\n <div class=\"inline\">\n <input\n type=\"text\"\n class=\"mono\"\n autocomplete=\"off\"\n [attr.aria-label]=\"'nh-assistant.admin.agent-editor.add-selector' | translate\"\n [attr.placeholder]=\"'nh-assistant.admin.agent-editor.selector-placeholder' | translate\"\n [attr.aria-invalid]=\"selectorInvalid() ? true : null\"\n [value]=\"newSelector()\"\n (input)=\"newSelector.set(value($event))\"\n (keydown)=\"onSelectorKeydown($event)\" />\n <button class=\"secondary\" type=\"button\" [disabled]=\"newSelector().trim().length === 0 || selectorInvalid()\" (click)=\"addSelector()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.agent-editor.add-selector' | translate }}\n </button>\n </div>\n\n <div class=\"field\">\n <label class=\"label\" [for]=\"id + '-catalog-filter'\">{{ 'nh-assistant.admin.agent-editor.catalog' | translate }}</label>\n <input\n type=\"search\"\n [id]=\"id + '-catalog-filter'\"\n [attr.placeholder]=\"'nh-assistant.admin.agent-editor.catalog-filter' | translate\"\n [value]=\"catalogFilter()\"\n (input)=\"catalogFilter.set(value($event))\" />\n <ul class=\"catalog\" [attr.aria-label]=\"'nh-assistant.admin.agent-editor.catalog' | translate\">\n @for (tool of filteredTools(); track tool.id) {\n <li>\n <label>\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(tool.id) || isCovered(tool.id)\"\n [disabled]=\"isCovered(tool.id)\"\n (change)=\"toggleTool(tool.id, checked($event))\" />\n <span class=\"tool-id\">{{ tool.id }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.source.' + tool.source | translate }}</span>\n <span class=\"badge\" [class.warning]=\"tool.effect !== 'read-only'\">{{ 'nh-assistant.admin.effect.' + tool.effect | translate }}</span>\n <span class=\"muted\">{{ tool.description }}</span>\n </label>\n </li>\n } @empty {\n <li class=\"muted\">{{ 'nh-assistant.admin.agent-editor.catalog-empty' | translate }}</li>\n }\n </ul>\n </div>\n </fieldset>\n\n <fieldset class=\"subsection\">\n <legend>{{ 'nh-assistant.admin.agent-editor.mcp-servers' | translate }}</legend>\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.mcp-servers-hint' | translate }}</p>\n @for (server of servers(); track server.id) {\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"mcpServerIds().includes(server.id)\" (change)=\"toggleServer(server.id, checked($event))\" />\n <span>{{ server.displayName }} <span class=\"mono muted\">{{ server.id }}</span></span>\n </label>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.mcp-servers-empty' | translate }}</p>\n }\n </fieldset>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n <div class=\"actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"cancelled.emit()\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n <button class=\"primary\" type=\"submit\" [disabled]=\"saving() || tooLong()\">\n {{ (saving() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}\n </button>\n </div>\n</form>\n","import { DatePipe, DOCUMENT, PercentPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, signal, untracked } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n AgentFeedbackCategoryCount,\n AgentFeedbackItem,\n AgentFeedbackSummaryRow,\n AgentProposalFeedbackCategory,\n AgentProposalFeedbackGroup,\n NH_ASSISTANT_FEEDBACK_CATEGORIES,\n StaleKind,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\n/** Periods the report offers, in days before now. */\nexport type NhAssistantFeedbackPeriod = 7 | 30 | 90;\n\n/** A summary row with its most frequent feedback categories and why open proposals closed. */\ninterface NhAssistantFeedbackSummaryView extends AgentFeedbackSummaryRow {\n topCategories: AgentFeedbackCategoryCount[];\n /** Open proposals closed before a decision, per kind, most frequent first. */\n invalidatedKinds: { kind: StaleKind; count: number; reasons: string }[];\n}\n\nconst dayMs = 24 * 60 * 60 * 1000;\nconst topCategoryCount = 3;\n\nlet nextId = 0;\n\n/**\n * What people said when they rejected an agent's proposals, for the agent's administrators: per\n * tool and agent version the decisions, the rejection rate, the share of rejections with feedback,\n * the number of different people and the most frequent categories, followed by the feedback itself\n * and a JSON Lines export. Comparing agent versions shows whether a change to the prompt, tools or\n * policy helped. The server requires the assistant admin policy and reports only the caller's scopes.\n */\n@Component({\n selector: 'nh-assistant-agent-feedback-report',\n standalone: true,\n imports: [DatePipe, PercentPipe, TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-feedback-report.component.html',\n styleUrls: ['../nh-assistant-admin-shared.scss', './nh-assistant-agent-feedback-report.component.scss']\n})\nexport class NhAssistantAgentFeedbackReportComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly document = inject(DOCUMENT);\n private summarySubscription?: Subscription;\n private listSubscription?: Subscription;\n\n readonly agentId = input.required<string>();\n /** Feedback per page; the server allows at most 100. */\n readonly itemsPerPage = input(20);\n\n readonly id = `nh-assistant-agent-feedback-${nextId++}`;\n readonly periods: readonly NhAssistantFeedbackPeriod[] = [7, 30, 90];\n readonly categories = NH_ASSISTANT_FEEDBACK_CATEGORIES;\n\n readonly period = signal<NhAssistantFeedbackPeriod>(30);\n readonly toolId = signal('');\n readonly category = signal<AgentProposalFeedbackCategory | ''>('');\n readonly page = signal(1);\n\n readonly summaryLoading = signal(true);\n readonly summaryError = signal<NhAssistantError | null>(null);\n readonly summaryErrorKeys = computed(() => nhAssistantErrorKeys(this.summaryError()));\n readonly rows = signal<AgentFeedbackSummaryRow[]>([]);\n\n readonly listLoading = signal(true);\n readonly listError = signal<NhAssistantError | null>(null);\n readonly listErrorKeys = computed(() => nhAssistantErrorKeys(this.listError()));\n readonly items = signal<AgentFeedbackItem[]>([]);\n readonly total = signal(0);\n readonly pages = computed(() => Math.max(1, Math.ceil(this.total() / this.itemsPerPage())));\n\n readonly exporting = signal(false);\n readonly exportError = signal<NhAssistantError | null>(null);\n readonly exportErrorKeys = computed(() => nhAssistantErrorKeys(this.exportError()));\n readonly canExport = computed(() => !this.exporting() && !this.listLoading() && this.listError() === null && this.total() > 0);\n\n /** Tools with proposals in the period, plus the chosen tool when the period has none of it. */\n readonly tools = computed(() => {\n const tools = new Set(this.rows().map(row => row.toolId));\n if (this.toolId()) {\n tools.add(this.toolId());\n }\n return [...tools].sort();\n });\n readonly visibleRows = computed<NhAssistantFeedbackSummaryView[]>(() => this.rows()\n .filter(row => !this.toolId() || row.toolId === this.toolId())\n .map(row => ({\n ...row,\n topCategories: [...row.categories].sort((left, right) => right.count - left.count).slice(0, topCategoryCount),\n invalidatedKinds: invalidatedKinds(row)\n })));\n readonly filtered = computed(() => this.toolId() !== '' || this.category() !== '');\n\n /** The period the last load asked for, so the list, summary and export agree. */\n private range = periodRange(30);\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.summarySubscription?.unsubscribe();\n this.listSubscription?.unsubscribe();\n });\n effect(() => {\n this.agentId();\n untracked(() => {\n this.toolId.set('');\n this.category.set('');\n this.load();\n });\n });\n }\n\n /** Reloads the summary and the first page of feedback for the chosen period. */\n load(): void {\n this.range = periodRange(this.period());\n this.page.set(1);\n this.loadSummary();\n this.loadList();\n }\n\n onPeriod(event: Event): void {\n this.period.set(Number((event.target as HTMLSelectElement).value) as NhAssistantFeedbackPeriod);\n this.load();\n }\n\n onTool(event: Event): void {\n this.toolId.set((event.target as HTMLSelectElement).value);\n this.page.set(1);\n this.loadList();\n }\n\n onCategory(event: Event): void {\n this.category.set((event.target as HTMLSelectElement).value as AgentProposalFeedbackCategory | '');\n this.page.set(1);\n this.loadList();\n }\n\n goTo(page: number): void {\n this.page.set(Math.min(Math.max(1, page), this.pages()));\n this.loadList();\n }\n\n loadSummary(): void {\n this.summaryLoading.set(true);\n this.summaryError.set(null);\n this.summarySubscription?.unsubscribe();\n this.summarySubscription = this.admin.getAgentFeedbackSummary(this.agentId(), this.range).subscribe({\n next: summary => {\n this.rows.set(summary.rows);\n this.summaryLoading.set(false);\n },\n error: (failure: unknown) => {\n this.rows.set([]);\n this.summaryLoading.set(false);\n this.summaryError.set(toNhAssistantError(failure));\n }\n });\n }\n\n loadList(): void {\n this.listLoading.set(true);\n this.listError.set(null);\n this.exportError.set(null);\n this.listSubscription?.unsubscribe();\n this.listSubscription = this.admin\n .getAgentFeedback(this.agentId(), {\n ...this.range,\n toolId: this.toolId() || undefined,\n category: this.category() || undefined,\n page: this.page(),\n itemsPerPage: this.itemsPerPage()\n })\n .subscribe({\n next: list => {\n this.items.set(list.items);\n this.total.set(list.total);\n this.listLoading.set(false);\n },\n error: (failure: unknown) => {\n this.items.set([]);\n this.total.set(0);\n this.listLoading.set(false);\n this.listError.set(toNhAssistantError(failure));\n }\n });\n }\n\n /** Downloads the feedback of the period and filters as a JSON Lines file. */\n async export(): Promise<void> {\n if (!this.canExport()) {\n return;\n }\n\n this.exporting.set(true);\n this.exportError.set(null);\n try {\n const blob = await this.admin.exportAgentFeedback(this.agentId(), {\n ...this.range,\n toolId: this.toolId() || undefined,\n category: this.category() || undefined\n });\n const url = URL.createObjectURL(blob);\n const link = this.document.createElement('a');\n link.href = url;\n link.download = `agent-feedback-${this.agentId()}.jsonl`;\n link.click();\n URL.revokeObjectURL(url);\n } catch (failure) {\n this.exportError.set(toNhAssistantError(failure));\n } finally {\n this.exporting.set(false);\n }\n }\n\n /** Badge color of a feedback group: wrong and not allowed are failures, not now is a warning. */\n groupClass(group: AgentProposalFeedbackGroup): string {\n switch (group) {\n case 'wrong':\n case 'not-allowed':\n return 'danger';\n case 'right-but-not-now':\n return 'warning';\n default:\n return '';\n }\n }\n}\n\nfunction periodRange(days: number): { from: string; to: string } {\n const to = Date.now();\n return { from: new Date(to - days * dayMs).toISOString(), to: new Date(to).toISOString() };\n}\n\n/**\n * The open proposals of a row that closed before a decision, per kind, with their reason codes for\n * the tooltip. Proposals that closed after their approval are part of the approved count.\n */\nfunction invalidatedKinds(row: AgentFeedbackSummaryRow): { kind: StaleKind; count: number; reasons: string }[] {\n const kinds = new Map<StaleKind, { count: number; reasons: string[] }>();\n for (const item of row.invalidations ?? []) {\n if (item.afterApproval) {\n continue;\n }\n\n const entry = kinds.get(item.kind) ?? { count: 0, reasons: [] };\n entry.count += item.count;\n entry.reasons.push(`${item.reasonCode} (${item.count})`);\n kinds.set(item.kind, entry);\n }\n\n return [...kinds.entries()]\n .map(([kind, entry]) => ({ kind, count: entry.count, reasons: entry.reasons.join(', ') }))\n .sort((left, right) => right.count - left.count);\n}\n","<section class=\"section report\" [attr.aria-labelledby]=\"id + '-title'\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.feedback.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.feedback.description' | translate }}</p>\n <p class=\"muted export-hint\" [id]=\"id + '-export-hint'\">{{ 'nh-assistant.admin.feedback.export-hint' | translate }}</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"summaryLoading() || listLoading()\" (click)=\"load()\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.feedback.refresh' | translate }}\n </button>\n <button\n class=\"secondary\"\n type=\"button\"\n [disabled]=\"!canExport()\"\n [attr.aria-describedby]=\"id + '-export-hint'\"\n (click)=\"export()\">\n <nh-assistant-icon name=\"page\" />{{ (exporting() ? 'nh-assistant.admin.feedback.exporting' : 'nh-assistant.admin.feedback.export') | translate }}\n </button>\n </div>\n </header>\n\n <div class=\"filters\">\n <div class=\"field\">\n <label [for]=\"id + '-period'\">{{ 'nh-assistant.admin.feedback.period' | translate }}</label>\n <select [id]=\"id + '-period'\" (change)=\"onPeriod($event)\">\n @for (days of periods; track days) {\n <option [value]=\"days\" [selected]=\"period() === days\">{{ 'nh-assistant.admin.feedback.periods.last-' + days + '-days' | translate }}</option>\n }\n </select>\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-tool'\">{{ 'nh-assistant.admin.feedback.tool' | translate }}</label>\n <select [id]=\"id + '-tool'\" [disabled]=\"summaryLoading() && tools().length === 0\" (change)=\"onTool($event)\">\n <option value=\"\" [selected]=\"toolId() === ''\">{{ 'nh-assistant.admin.feedback.all-tools' | translate }}</option>\n @for (tool of tools(); track tool) {\n <option [value]=\"tool\" [selected]=\"toolId() === tool\">{{ tool }}</option>\n }\n </select>\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-category'\">{{ 'nh-assistant.admin.feedback.category' | translate }}</label>\n <select [id]=\"id + '-category'\" [attr.aria-describedby]=\"id + '-category-hint'\" (change)=\"onCategory($event)\">\n <option value=\"\" [selected]=\"category() === ''\">{{ 'nh-assistant.admin.feedback.all-categories' | translate }}</option>\n @for (option of categories; track option) {\n <option [value]=\"option\" [selected]=\"category() === option\">{{ 'nh-assistant.proposal-feedback.categories.' + option | translate }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-category-hint'\"><span>{{ 'nh-assistant.admin.feedback.category-hint' | translate }}</span></p>\n </div>\n </div>\n\n @if (exportError(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ exportErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-summary-title'\" [attr.aria-busy]=\"summaryLoading()\">\n <h4 [id]=\"id + '-summary-title'\">{{ 'nh-assistant.admin.feedback.summary-title' | translate }}</h4>\n @if (summaryLoading() && rows().length === 0) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (summaryError(); as failure) {\n <div class=\"state\" role=\"alert\">\n <p>{{ summaryErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"loadSummary()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (visibleRows().length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.feedback.summary-empty' | translate }}</p>\n } @else {\n <div class=\"table-container\">\n <table class=\"summary-table\" [attr.aria-labelledby]=\"id + '-summary-title'\">\n <thead>\n <tr>\n <th scope=\"col\">{{ 'nh-assistant.admin.feedback.columns.tool' | translate }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.feedback.columns.version' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.approved' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.rejected' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.expired' | translate }}</th>\n <th scope=\"col\" class=\"number\" [attr.title]=\"'nh-assistant.admin.feedback.invalidated-hint' | translate\">\n {{ 'nh-assistant.admin.feedback.columns.invalidated' | translate }}\n </th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.rejection-rate' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.with-feedback' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.people' | translate }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.feedback.columns.categories' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of visibleRows(); track row.toolId + '|' + row.agentVersion) {\n <tr>\n <th scope=\"row\" class=\"tool\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.tool' | translate\">\n <span class=\"mono\">{{ row.toolId }}</span>\n </th>\n <td [attr.data-label]=\"'nh-assistant.admin.feedback.columns.version' | translate\">\n @if (row.agentVersion === null) {\n {{ 'nh-assistant.admin.feedback.consultations' | translate }}\n } @else {\n {{ 'nh-assistant.admin.feedback.version' | translate: { version: row.agentVersion } }}\n }\n </td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.approved' | translate\">{{ row.approved }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.rejected' | translate\">{{ row.rejected }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.expired' | translate\">{{ row.expired }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.invalidated' | translate\">\n {{ row.invalidated ?? 0 }}\n @if (row.invalidatedKinds.length > 0) {\n <ul class=\"badges\">\n @for (item of row.invalidatedKinds; track item.kind) {\n <li>\n <span class=\"badge\" [attr.title]=\"item.reasons\">\n {{ 'nh-assistant.approval.stale-kind.' + item.kind | translate }}\n <span class=\"count\">{{ item.count }}</span>\n </span>\n </li>\n }\n </ul>\n }\n </td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.rejection-rate' | translate\">\n @if (row.rejectionRate === null) {\n <span class=\"muted\">{{ 'nh-assistant.admin.feedback.no-decisions' | translate }}</span>\n } @else {\n {{ row.rejectionRate | percent: '1.0-0' }}\n }\n </td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.with-feedback' | translate\">{{ row.rejectedWithFeedback }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.people' | translate\">{{ row.feedbackAuthors }}</td>\n <td [attr.data-label]=\"'nh-assistant.admin.feedback.columns.categories' | translate\">\n @if (row.topCategories.length === 0) {\n <span class=\"muted\">{{ 'nh-assistant.admin.feedback.no-categories' | translate }}</span>\n } @else {\n <ul class=\"badges\">\n @for (item of row.topCategories; track item.category) {\n <li>\n <span [class]=\"'badge ' + groupClass(item.group)\" [attr.title]=\"'nh-assistant.proposal-feedback.groups.' + item.group | translate\">\n {{ 'nh-assistant.proposal-feedback.categories.' + item.category | nhAssistantTranslate: item.category }}\n <span class=\"count\">{{ item.count }}</span>\n </span>\n </li>\n }\n </ul>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </section>\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-list-title'\" [attr.aria-busy]=\"listLoading()\">\n <div class=\"list-header\">\n <h4 [id]=\"id + '-list-title'\">{{ 'nh-assistant.admin.feedback.list-title' | translate }}</h4>\n @if (!listLoading() && listError() === null) {\n <span class=\"muted\">{{ 'nh-assistant.admin.feedback.list-count' | translate: { count: total() } }}</span>\n }\n </div>\n @if (listLoading() && items().length === 0) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (listError(); as failure) {\n <div class=\"state\" role=\"alert\">\n <p>{{ listErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"loadList()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (items().length === 0) {\n <p class=\"state\">{{ (filtered() ? 'nh-assistant.admin.feedback.list-empty-filtered' : 'nh-assistant.admin.feedback.list-empty') | translate }}</p>\n } @else {\n <ul class=\"cards\">\n @for (item of items(); track item.id) {\n <li class=\"card\">\n <div class=\"card-header\">\n <strong>{{ item.subjectDisplayName ?? item.subjectId }}</strong>\n <span class=\"muted\">{{ item.presentation?.toolDisplayName ?? item.toolId }}</span>\n @if (item.agentVersion !== null) {\n <span class=\"badge\">{{ 'nh-assistant.admin.feedback.version' | translate: { version: item.agentVersion } }}</span>\n }\n <span [class]=\"'badge ' + groupClass(item.group)\" [attr.title]=\"'nh-assistant.proposal-feedback.groups.' + item.group | translate\">\n {{ 'nh-assistant.proposal-feedback.categories.' + item.category | nhAssistantTranslate: item.category }}\n </span>\n @if (item.bulk) {\n <span class=\"badge\" [attr.title]=\"'nh-assistant.admin.feedback.bulk-hint' | translate\">{{ 'nh-assistant.admin.feedback.bulk' | translate }}</span>\n }\n </div>\n @if (item.text) {\n <blockquote class=\"feedback-text\">{{ item.text }}</blockquote>\n } @else {\n <p class=\"muted\">{{ 'nh-assistant.admin.feedback.no-text' | translate }}</p>\n }\n <p class=\"proposal\">\n <span class=\"proposal-label\">{{ 'nh-assistant.admin.feedback.proposal' | translate }}</span>\n {{ item.presentation?.summary ?? item.summary }}\n </p>\n <div class=\"meta\">\n <span>{{ 'nh-assistant.agent-runs.proposal.status.' + item.approvalStatus | nhAssistantTranslate: item.approvalStatus }}</span>\n <span>{{ 'nh-assistant.admin.feedback.author' | translate: { actor: item.authorDisplayName || item.authorActorId } }}</span>\n <span>{{ item.updatedAt | date: 'short' }}</span>\n </div>\n </li>\n }\n </ul>\n @if (pages() > 1) {\n <nav class=\"pager\" [attr.aria-label]=\"'nh-assistant.admin.feedback.pages' | translate\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"page() <= 1 || listLoading()\" (click)=\"goTo(page() - 1)\">\n {{ 'nh-assistant.admin.feedback.previous' | translate }}\n </button>\n <span class=\"muted\">{{ 'nh-assistant.admin.feedback.page' | translate: { page: page(), pages: pages() } }}</span>\n <button class=\"secondary\" type=\"button\" [disabled]=\"page() >= pages() || listLoading()\" (click)=\"goTo(page() + 1)\">\n {{ 'nh-assistant.admin.feedback.next' | translate }}\n </button>\n </nav>\n }\n }\n </section>\n</section>\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n afterNextRender,\n computed,\n inject,\n signal,\n viewChild\n} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Observable, Subscription, forkJoin } from 'rxjs';\nimport {\n AdminAgent,\n McpServer,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n NhAssistantStore,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAdminAgentEditorComponent } from './nh-assistant-admin-agent-editor.component';\nimport { NhAssistantAgentFeedbackReportComponent } from './nh-assistant-agent-feedback-report.component';\n\nlet nextId = 0;\n\n/**\n * Agent administration: code agents (override, disable, reset) and agents created here\n * (edit, disable, delete). Editing opens `nh-assistant-admin-agent-editor`; the feedback action\n * opens `nh-assistant-agent-feedback-report` for the agent.\n */\n@Component({\n selector: 'nh-assistant-admin-agents',\n standalone: true,\n imports: [\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantAdminAgentEditorComponent,\n NhAssistantAgentFeedbackReportComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-agents.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminAgentsComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly store = inject(NhAssistantStore);\n private readonly injector = inject(Injector);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly backButton = viewChild<ElementRef<HTMLButtonElement>>('back');\n private subscription?: Subscription;\n private actionSubscription?: Subscription;\n\n readonly id = `nh-assistant-admin-agents-${nextId++}`;\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly agents = signal<AdminAgent[]>([]);\n readonly tools = signal<ToolCatalogEntry[]>([]);\n readonly servers = signal<McpServer[]>([]);\n /** `undefined`: list; `null`: new agent; an agent: editing that agent. */\n readonly editing = signal<AdminAgent | null | undefined>(undefined);\n /** The agent whose feedback report is shown instead of the list. */\n readonly reporting = signal<AdminAgent | null>(null);\n readonly confirming = signal<{ agentId: string; action: 'delete' | 'reset' } | null>(null);\n readonly busyAgentId = signal<string | null>(null);\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.actionSubscription?.unsubscribe();\n });\n this.load();\n }\n\n load(): void {\n this.loading.set(true);\n this.loadFailed.set(false);\n this.subscription?.unsubscribe();\n this.subscription = forkJoin([this.admin.getAgents(), this.admin.getTools(), this.admin.getMcpServers()]).subscribe({\n next: ([agents, tools, servers]) => {\n this.agents.set(agents);\n this.tools.set(tools);\n this.servers.set(servers);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n create(): void {\n this.error.set(null);\n this.editing.set(null);\n }\n\n edit(agent: AdminAgent): void {\n this.error.set(null);\n this.editing.set(agent);\n }\n\n /** Shows what people said when they rejected the agent's proposals. */\n openReport(agent: AdminAgent): void {\n this.error.set(null);\n this.confirming.set(null);\n this.reporting.set(agent);\n afterNextRender(() => this.backButton()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /** Returns to the list and to the feedback action of the agent whose report was open. */\n closeReport(): void {\n const agentId = this.reporting()?.id;\n this.reporting.set(null);\n if (agentId !== undefined) {\n afterNextRender(() => {\n const host = this.host.nativeElement;\n const action = Array.from(host.querySelectorAll<HTMLButtonElement>('[data-feedback-agent]'))\n .find(item => item.dataset['feedbackAgent'] === agentId);\n action?.focus();\n }, { injector: this.injector });\n }\n }\n\n onSaved(agent: AdminAgent): void {\n this.agents.update(agents => agents.some(item => item.id === agent.id)\n ? agents.map(item => item.id === agent.id ? agent : item)\n : [...agents, agent]);\n this.editing.set(undefined);\n this.refreshChat();\n }\n\n setEnabled(agent: AdminAgent, isEnabled: boolean): void {\n const { version, source, isOverridden, instructionsHash, updatedAt, ...input } = agent;\n this.run(agent.id, this.admin.updateAgent(agent.id, { ...input, isEnabled, expectedVersion: version }), updated => this.replace(updated));\n }\n\n confirm(agentId: string, action: 'delete' | 'reset'): void {\n this.confirming.set({ agentId, action });\n }\n\n isConfirming(agentId: string, action: 'delete' | 'reset'): boolean {\n const confirming = this.confirming();\n return confirming?.agentId === agentId && confirming.action === action;\n }\n\n reset(agent: AdminAgent): void {\n this.run(agent.id, this.admin.resetAgent(agent.id), updated => this.replace(updated));\n }\n\n remove(agent: AdminAgent): void {\n this.run<void>(agent.id, this.admin.deleteAgent(agent.id), () => {\n this.agents.update(agents => agents.filter(item => item.id !== agent.id));\n });\n }\n\n private run<T>(agentId: string, request: Observable<T>, done: (result: T) => void): void {\n this.busyAgentId.set(agentId);\n this.confirming.set(null);\n this.error.set(null);\n this.actionSubscription?.unsubscribe();\n this.actionSubscription = request.subscribe({\n next: result => done(result),\n complete: () => {\n this.busyAgentId.set(null);\n this.refreshChat();\n },\n error: (error: unknown) => {\n this.busyAgentId.set(null);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n private replace(agent: AdminAgent): void {\n this.agents.update(agents => agents.map(item => item.id === agent.id ? agent : item));\n }\n\n /** Agent changes affect the agent picker of the panel. */\n private refreshChat(): void {\n void this.store.reloadStatus();\n }\n}\n","@if (editing() !== undefined) {\n <nh-assistant-admin-agent-editor\n [agent]=\"editing() ?? null\"\n [tools]=\"tools()\"\n [servers]=\"servers()\"\n (saved)=\"onSaved($event)\"\n (cancelled)=\"editing.set(undefined)\" />\n} @else if (reporting(); as agent) {\n <div class=\"stack\">\n <div>\n <button #back class=\"secondary\" type=\"button\" (click)=\"closeReport()\">\n {{ 'nh-assistant.admin.feedback.back' | translate }}\n </button>\n </div>\n <p class=\"muted\">{{ 'nh-assistant.admin.feedback.agent' | translate: { name: agent.displayName, id: agent.id } }}</p>\n <nh-assistant-agent-feedback-report [agentId]=\"agent.id\" />\n </div>\n} @else {\n <section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.agents.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.agents.description' | translate }}</p>\n </div>\n <button class=\"primary\" type=\"button\" [disabled]=\"loading() || loadFailed()\" (click)=\"create()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.agents.new' | translate }}\n </button>\n </header>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n @if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (loadFailed()) {\n <div class=\"state\" role=\"alert\">\n <p>{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (agents().length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.agents.empty' | translate }}</p>\n } @else {\n <ul class=\"cards\">\n @for (agent of agents(); track agent.id) {\n <li class=\"card\" [class.inactive]=\"!agent.isEnabled\" [attr.aria-busy]=\"busyAgentId() === agent.id\">\n <div class=\"card-header\">\n <strong>{{ agent.displayName }}</strong>\n <span class=\"mono muted\">{{ agent.id }}</span>\n <span class=\"badge\">{{ (agent.source === 'code' ? 'nh-assistant.admin.agents.source-code' : 'nh-assistant.admin.agents.source-admin') | translate }}</span>\n @if (agent.isOverridden) {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.agents.overridden' | translate }}</span>\n }\n <span class=\"badge\" [class.success]=\"agent.isEnabled\">{{ (agent.isEnabled ? 'nh-assistant.admin.enabled' : 'nh-assistant.admin.disabled') | translate }}</span>\n </div>\n @if (agent.description) {\n <p class=\"muted\">{{ agent.description }}</p>\n }\n <div class=\"meta\">\n <span>{{ 'nh-assistant.admin.agents.autonomy.' + agent.autonomy | translate }}</span>\n <span>{{ 'nh-assistant.admin.agents.tool-count' | translate: { count: agent.toolSelectors.length } }}</span>\n <span>{{ 'nh-assistant.admin.agents.server-count' | translate: { count: agent.mcpServerIds.length } }}</span>\n <span>{{ 'nh-assistant.admin.agents.version' | translate: { version: agent.version } }}</span>\n @if (agent.requiredPolicy) {\n <span class=\"mono\">{{ agent.requiredPolicy }}</span>\n }\n </div>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"busyAgentId() !== null\" (click)=\"edit(agent)\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" [disabled]=\"busyAgentId() !== null\" (click)=\"setEnabled(agent, !agent.isEnabled)\">\n {{ (agent.isEnabled ? 'nh-assistant.admin.disable' : 'nh-assistant.admin.enable') | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" [attr.data-feedback-agent]=\"agent.id\" (click)=\"openReport(agent)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.agents.feedback' | translate }}\n </button>\n @if (agent.source === 'code' && agent.isOverridden) {\n @if (isConfirming(agent.id, 'reset')) {\n <button class=\"danger\" type=\"button\" (click)=\"reset(agent)\">{{ 'nh-assistant.admin.agents.confirm-reset' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.keep' | translate }}</button>\n } @else {\n <button class=\"secondary\" type=\"button\" [disabled]=\"busyAgentId() !== null\" (click)=\"confirm(agent.id, 'reset')\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.agents.reset' | translate }}\n </button>\n }\n }\n @if (agent.source === 'admin') {\n @if (isConfirming(agent.id, 'delete')) {\n <button class=\"danger\" type=\"button\" (click)=\"remove(agent)\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.keep' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" [disabled]=\"busyAgentId() !== null\" (click)=\"confirm(agent.id, 'delete')\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.delete' | translate }}\n </button>\n }\n }\n </div>\n </li>\n }\n </ul>\n }\n </section>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n untracked\n} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n McpAuthMode,\n McpServer,\n McpServerInput,\n ɵNH_ASSISTANT_DASH_CASE as NH_ASSISTANT_DASH_CASE,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\n/**\n * What happens to the stored secret on save. `keep` omits `secret`, `replace` sends the\n * new value and `clear` sends `\"\"`. The stored value is never shown.\n */\nexport type NhAssistantSecretAction = 'keep' | 'replace' | 'clear';\n\nlet nextId = 0;\n\n/** Creates or edits one MCP server with a write-only secret. */\n@Component({\n selector: 'nh-assistant-admin-mcp-server-editor',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-mcp-server-editor.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminMcpServerEditorComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n\n /** The server to edit, or null for a new server. */\n readonly server = input<McpServer | null>(null);\n readonly saved = output<McpServer>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-server-editor-${nextId++}`;\n readonly authModes: readonly McpAuthMode[] = ['none', 'bearer', 'api-key', 'forward-user-token'];\n\n readonly serverId = signal('');\n readonly displayName = signal('');\n readonly url = signal('');\n readonly authMode = signal<McpAuthMode>('none');\n readonly headerName = signal('');\n readonly requiredPolicy = signal('');\n readonly isEnabled = signal(true);\n readonly secretAction = signal<NhAssistantSecretAction>('keep');\n /** The new secret while typing. Never filled from the server. */\n readonly secret = signal('');\n readonly submitted = signal(false);\n readonly saving = signal(false);\n readonly error = signal<NhAssistantError | null>(null);\n\n readonly isNew = computed(() => this.server() === null);\n readonly hasSecret = computed(() => this.server()?.hasSecret === true);\n readonly usesSecret = computed(() => this.authMode() === 'bearer' || this.authMode() === 'api-key');\n readonly showSecretInput = computed(() => this.usesSecret() && (!this.hasSecret() || this.secretAction() === 'replace'));\n readonly idInvalid = computed(() => this.isNew() && (this.serverId().length > 40 || !NH_ASSISTANT_DASH_CASE.test(this.serverId())));\n readonly nameMissing = computed(() => this.displayName().trim().length === 0);\n readonly urlInvalid = computed(() => !isAllowedUrl(this.url().trim()));\n readonly valid = computed(() => !this.idInvalid() && !this.nameMissing() && !this.urlInvalid());\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n\n effect(() => {\n const server = this.server();\n untracked(() => this.reset(server));\n });\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement | HTMLSelectElement).value;\n }\n\n checked(event: Event): boolean {\n return (event.target as HTMLInputElement).checked;\n }\n\n setSecretAction(action: NhAssistantSecretAction): void {\n this.secretAction.set(action);\n this.secret.set('');\n }\n\n onSecretInput(event: Event): void {\n this.secret.set(this.value(event));\n if (!this.hasSecret()) {\n this.secretAction.set(this.secret().length > 0 ? 'replace' : 'keep');\n }\n }\n\n save(): void {\n this.submitted.set(true);\n if (!this.valid() || this.saving()) {\n return;\n }\n\n const authMode = this.authMode();\n const policy = this.requiredPolicy().trim();\n const header = this.headerName().trim();\n const input: McpServerInput = {\n id: this.isNew() ? this.serverId() : this.server()!.id,\n displayName: this.displayName().trim(),\n url: this.url().trim(),\n authMode,\n headerName: authMode === 'api-key' && header.length > 0 ? header : null,\n requiredPolicy: policy.length > 0 ? policy : null,\n isEnabled: this.isEnabled()\n };\n\n // Write-only secret: omitted keeps the stored value, \"\" clears it.\n const action = this.secretAction();\n if (!this.usesSecret() && this.hasSecret()) {\n input.secret = '';\n } else if (action === 'clear') {\n input.secret = '';\n } else if (action === 'replace' && this.secret().length > 0) {\n input.secret = this.secret();\n }\n\n const existing = this.server();\n const request = existing ? this.admin.updateMcpServer(existing.id, input) : this.admin.createMcpServer(input);\n\n this.saving.set(true);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = request.subscribe({\n next: server => {\n this.saving.set(false);\n this.secret.set('');\n this.saved.emit(server);\n },\n error: (error: unknown) => {\n this.saving.set(false);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n private reset(server: McpServer | null): void {\n this.serverId.set(server?.id ?? '');\n this.displayName.set(server?.displayName ?? '');\n this.url.set(server?.url ?? 'https://');\n this.authMode.set(server?.authMode ?? 'none');\n this.headerName.set(server?.headerName ?? '');\n this.requiredPolicy.set(server?.requiredPolicy ?? '');\n this.isEnabled.set(server?.isEnabled ?? true);\n this.secretAction.set('keep');\n this.secret.set('');\n this.submitted.set(false);\n this.error.set(null);\n }\n}\n\nfunction isAllowedUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === 'https:' || (url.protocol === 'http:' && url.hostname === 'localhost');\n } catch {\n return false;\n }\n}\n","<form class=\"section card\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"saving()\" autocomplete=\"off\" (submit)=\"$event.preventDefault(); save()\">\n <h3 [id]=\"id + '-title'\">\n @if (server(); as current) {\n {{ 'nh-assistant.admin.server-editor.edit-title' | translate: { name: current.displayName } }}\n } @else {\n {{ 'nh-assistant.admin.server-editor.new-title' | translate }}\n }\n </h3>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-id'\">{{ 'nh-assistant.admin.server-editor.id' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n [id]=\"id + '-id'\"\n [value]=\"serverId()\"\n [disabled]=\"!isNew()\"\n [attr.aria-describedby]=\"id + '-id-hint'\"\n [attr.aria-invalid]=\"submitted() && idInvalid() ? true : null\"\n (input)=\"serverId.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-id-hint'\">\n <span [class.error-text]=\"submitted() && idInvalid()\">\n {{ (submitted() && idInvalid() ? 'nh-assistant.admin.invalid-id' : 'nh-assistant.admin.server-editor.id-hint') | translate }}\n </span>\n </p>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-name'\">{{ 'nh-assistant.admin.server-editor.display-name' | translate }}</label>\n <input\n type=\"text\"\n [id]=\"id + '-name'\"\n [value]=\"displayName()\"\n [attr.aria-invalid]=\"submitted() && nameMissing() ? true : null\"\n [attr.aria-describedby]=\"id + '-name-hint'\"\n (input)=\"displayName.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-name-hint'\">\n @if (submitted() && nameMissing()) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.required' | translate }}</span>\n }\n </p>\n </div>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-url'\">{{ 'nh-assistant.admin.server-editor.url' | translate }}</label>\n <input\n type=\"url\"\n class=\"mono\"\n inputmode=\"url\"\n [id]=\"id + '-url'\"\n [value]=\"url()\"\n [attr.aria-describedby]=\"id + '-url-hint'\"\n [attr.aria-invalid]=\"submitted() && urlInvalid() ? true : null\"\n (input)=\"url.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-url-hint'\">\n <span [class.error-text]=\"submitted() && urlInvalid()\">\n {{ (submitted() && urlInvalid() ? 'nh-assistant.admin.server-editor.url-invalid' : 'nh-assistant.admin.server-editor.url-hint') | translate }}\n </span>\n </p>\n </div>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-auth'\">{{ 'nh-assistant.admin.server-editor.auth-mode' | translate }}</label>\n <select [id]=\"id + '-auth'\" (change)=\"authMode.set($any(value($event)))\">\n @for (mode of authModes; track mode) {\n <option [value]=\"mode\" [selected]=\"authMode() === mode\">{{ 'nh-assistant.admin.mcp.auth.' + mode | translate }}</option>\n }\n </select>\n </div>\n\n @if (authMode() === 'api-key') {\n <div class=\"field\">\n <label [for]=\"id + '-header'\">{{ 'nh-assistant.admin.server-editor.header-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n placeholder=\"X-Api-Key\"\n [id]=\"id + '-header'\"\n [value]=\"headerName()\"\n [attr.aria-describedby]=\"id + '-header-hint'\"\n (input)=\"headerName.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-header-hint'\">{{ 'nh-assistant.admin.server-editor.header-name-hint' | translate }}</p>\n </div>\n }\n </div>\n\n @if (authMode() === 'forward-user-token') {\n <p class=\"message warning\" role=\"note\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.forward-warning' | translate }}</p>\n }\n\n @if (usesSecret()) {\n <fieldset class=\"field\">\n <legend>{{ 'nh-assistant.admin.server-editor.secret' | translate }}</legend>\n @if (hasSecret()) {\n <div class=\"meta secret-state\">\n @switch (secretAction()) {\n @case ('clear') {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.server-editor.secret-will-clear' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"setSecretAction('keep')\">{{ 'nh-assistant.admin.server-editor.secret-undo' | translate }}</button>\n }\n @case ('replace') {\n <span class=\"badge\">{{ 'nh-assistant.admin.server-editor.secret-set' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"setSecretAction('keep')\">{{ 'nh-assistant.admin.server-editor.secret-undo' | translate }}</button>\n }\n @default {\n <span class=\"badge success\">{{ 'nh-assistant.admin.server-editor.secret-set' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"setSecretAction('replace')\">{{ 'nh-assistant.admin.server-editor.secret-replace' | translate }}</button>\n <button class=\"danger\" type=\"button\" (click)=\"setSecretAction('clear')\">{{ 'nh-assistant.admin.server-editor.secret-clear' | translate }}</button>\n }\n }\n </div>\n } @else {\n <p class=\"muted\">{{ 'nh-assistant.admin.server-editor.secret-none' | translate }}</p>\n }\n @if (showSecretInput()) {\n <label class=\"visually-hidden\" [for]=\"id + '-secret'\">{{ 'nh-assistant.admin.server-editor.secret-new' | translate }}</label>\n <input\n type=\"password\"\n class=\"mono\"\n autocomplete=\"new-password\"\n spellcheck=\"false\"\n [id]=\"id + '-secret'\"\n [attr.placeholder]=\"'nh-assistant.admin.server-editor.secret-new' | translate\"\n [attr.aria-describedby]=\"id + '-secret-hint'\"\n [value]=\"secret()\"\n (input)=\"onSecretInput($event)\" />\n }\n <p class=\"hint\" [id]=\"id + '-secret-hint'\">{{ 'nh-assistant.admin.server-editor.secret-hint' | translate }}</p>\n </fieldset>\n }\n\n <div class=\"field\">\n <label [for]=\"id + '-policy'\">{{ 'nh-assistant.admin.server-editor.required-policy' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n [id]=\"id + '-policy'\"\n [value]=\"requiredPolicy()\"\n [attr.aria-describedby]=\"id + '-policy-hint'\"\n (input)=\"requiredPolicy.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.server-editor.required-policy-hint' | translate }}</p>\n </div>\n\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"isEnabled()\" (change)=\"isEnabled.set(checked($event))\" />\n <span>{{ 'nh-assistant.admin.server-editor.enabled' | translate }}</span>\n </label>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n <div class=\"actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"cancelled.emit()\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n <button class=\"primary\" type=\"submit\" [disabled]=\"saving()\">\n {{ (saving() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}\n </button>\n </div>\n</form>\n","import { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n McpServer,\n McpTool,\n McpToolEffect,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\n/** Unsaved changes of one tool row. */\ninterface ToolDraft {\n isEnabled: boolean;\n effect: McpToolEffect;\n descriptionOverride: string;\n}\n\nlet nextId = 0;\n\n/**\n * The tools of one MCP server. Every tool starts disabled as a change that needs approval;\n * the administrator enables it and chooses the effect. Remote annotations appear as hints\n * only, and a changed remote input schema is shown as a warning.\n */\n@Component({\n selector: 'nh-assistant-admin-mcp-tools',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-mcp-tools.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminMcpToolsComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n private rowSubscription?: Subscription;\n\n readonly server = input.required<McpServer>();\n readonly closed = output<void>();\n /** Emitted after a sync so the host can refresh the server's sync status. */\n readonly synced = output<void>();\n\n readonly id = `nh-assistant-mcp-tools-${nextId++}`;\n readonly effects: readonly McpToolEffect[] = ['mutation', 'read-only'];\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly syncing = signal(false);\n readonly savingTool = signal<string | null>(null);\n readonly savedTool = signal<string | null>(null);\n readonly tools = signal<McpTool[]>([]);\n readonly drafts = signal<Record<string, ToolDraft>>({});\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.rowSubscription?.unsubscribe();\n });\n\n effect(() => {\n const server = this.server();\n untracked(() => this.load(server.id));\n });\n }\n\n load(serverId = this.server().id): void {\n this.loading.set(true);\n this.loadFailed.set(false);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.getMcpTools(serverId).subscribe({\n next: tools => {\n this.setTools(tools);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n sync(): void {\n this.syncing.set(true);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.syncMcpServer(this.server().id).subscribe({\n next: tools => {\n this.setTools(tools);\n this.syncing.set(false);\n this.synced.emit();\n },\n error: (error: unknown) => {\n this.syncing.set(false);\n this.error.set(toNhAssistantError(error));\n this.synced.emit();\n }\n });\n }\n\n draft(tool: McpTool): ToolDraft {\n return this.drafts()[tool.remoteName] ?? toDraft(tool);\n }\n\n isDirty(tool: McpTool): boolean {\n const draft = this.draft(tool);\n return draft.isEnabled !== tool.isEnabled || draft.effect !== tool.effect ||\n draft.descriptionOverride !== (tool.descriptionOverride ?? '');\n }\n\n change(tool: McpTool, patch: Partial<ToolDraft>): void {\n this.savedTool.set(null);\n this.drafts.update(drafts => ({ ...drafts, [tool.remoteName]: { ...this.draft(tool), ...patch } }));\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement | HTMLSelectElement).value;\n }\n\n checked(event: Event): boolean {\n return (event.target as HTMLInputElement).checked;\n }\n\n save(tool: McpTool): void {\n const draft = this.draft(tool);\n const override = draft.descriptionOverride.trim();\n\n this.savingTool.set(tool.remoteName);\n this.savedTool.set(null);\n this.error.set(null);\n this.rowSubscription?.unsubscribe();\n this.rowSubscription = this.admin.updateMcpTool(this.server().id, tool.remoteName, {\n isEnabled: draft.isEnabled,\n effect: draft.effect,\n descriptionOverride: override.length > 0 ? override : null\n }).subscribe({\n next: updated => {\n this.tools.update(tools => tools.map(item => item.remoteName === updated.remoteName ? updated : item));\n this.drafts.update(drafts => {\n const { [updated.remoteName]: removed, ...rest } = drafts;\n return rest;\n });\n this.savingTool.set(null);\n this.savedTool.set(updated.remoteName);\n },\n error: (error: unknown) => {\n this.savingTool.set(null);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n private setTools(tools: McpTool[]): void {\n this.tools.set(tools);\n this.drafts.set({});\n this.savedTool.set(null);\n }\n}\n\nfunction toDraft(tool: McpTool): ToolDraft {\n return { isEnabled: tool.isEnabled, effect: tool.effect, descriptionOverride: tool.descriptionOverride ?? '' };\n}\n","<section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || syncing()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.tools.title' | translate: { name: server().displayName } }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.tools.description' | translate }}</p>\n </div>\n <div class=\"actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"closed.emit()\">{{ 'nh-assistant.admin.tools.back' | translate }}</button>\n <button class=\"primary\" type=\"button\" [disabled]=\"syncing()\" (click)=\"sync()\">\n <nh-assistant-icon name=\"refresh\" />{{ (syncing() ? 'nh-assistant.admin.mcp.syncing' : 'nh-assistant.admin.mcp.sync') | translate }}\n </button>\n </div>\n </header>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n @if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (loadFailed()) {\n <div class=\"state\" role=\"alert\">\n <p>{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (tools().length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.tools.empty' | translate }}</p>\n } @else {\n <ul class=\"cards\">\n @for (tool of tools(); track tool.remoteName) {\n <li class=\"card\" [class.inactive]=\"!tool.isEnabled\" [attr.data-status]=\"tool.status\" [attr.aria-busy]=\"savingTool() === tool.remoteName\">\n <div class=\"card-header\">\n <strong class=\"mono\">{{ tool.remoteName }}</strong>\n <span class=\"badge\"\n [class.warning]=\"tool.status === 'schema-changed'\"\n [class.danger]=\"tool.status === 'missing'\">{{ 'nh-assistant.admin.tools.status.' + tool.status | translate }}</span>\n <span class=\"badge\" [class.success]=\"tool.isEnabled\">{{ (tool.isEnabled ? 'nh-assistant.admin.enabled' : 'nh-assistant.admin.disabled') | translate }}</span>\n @if (tool.readOnlyHint !== null) {\n <span class=\"badge hint\" [attr.title]=\"'nh-assistant.admin.tools.description' | translate\">\n {{ (tool.readOnlyHint ? 'nh-assistant.admin.tools.hint-read-only' : 'nh-assistant.admin.tools.hint-mutation') | translate }}\n </span>\n }\n </div>\n <span class=\"mono muted\">{{ tool.localId }}</span>\n\n @if (tool.status === 'schema-changed') {\n <p class=\"message warning\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.tools.schema-changed-warning' | translate }}</p>\n }\n @if (tool.status === 'missing') {\n <p class=\"message error\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.tools.missing-warning' | translate }}</p>\n }\n\n <p class=\"muted\"><span class=\"label\">{{ 'nh-assistant.admin.tools.remote-description' | translate }}</span>{{ tool.description }}</p>\n\n <div class=\"grid\">\n <label class=\"check\">\n <input\n type=\"checkbox\"\n [checked]=\"draft(tool).isEnabled\"\n [disabled]=\"tool.status === 'missing'\"\n (change)=\"change(tool, { isEnabled: checked($event) })\" />\n <span>{{ 'nh-assistant.admin.tools.enabled' | translate }}</span>\n </label>\n <div class=\"field\">\n <label [for]=\"id + '-effect-' + $index\">{{ 'nh-assistant.admin.tools.effect' | translate }}</label>\n <select [id]=\"id + '-effect-' + $index\" (change)=\"change(tool, { effect: $any(value($event)) })\">\n @for (effect of effects; track effect) {\n <option [value]=\"effect\" [selected]=\"draft(tool).effect === effect\">{{ 'nh-assistant.admin.effect.' + effect | translate }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-override-' + $index\">{{ 'nh-assistant.admin.tools.description-override' | translate }}</label>\n <input\n type=\"text\"\n maxlength=\"1000\"\n [id]=\"id + '-override-' + $index\"\n [value]=\"draft(tool).descriptionOverride\"\n [attr.aria-describedby]=\"id + '-override-hint-' + $index\"\n (input)=\"change(tool, { descriptionOverride: value($event) })\" />\n <p class=\"hint\" [id]=\"id + '-override-hint-' + $index\">{{ 'nh-assistant.admin.tools.description-override-hint' | translate }}</p>\n </div>\n\n <div class=\"card-actions\">\n <button class=\"primary\" type=\"button\" [disabled]=\"!isDirty(tool) || savingTool() !== null\" (click)=\"save(tool)\">\n {{ (savingTool() === tool.remoteName ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.tools.save') | translate }}\n </button>\n @if (savedTool() === tool.remoteName) {\n <span class=\"badge success\" role=\"status\"><nh-assistant-icon name=\"check\" />{{ 'nh-assistant.admin.saved' | translate }}</span>\n }\n </div>\n </li>\n }\n </ul>\n }\n</section>\n","import { DatePipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n McpServer,\n McpServerTestResult,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n nhAssistantErrorMessageKey,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAdminMcpServerEditorComponent } from './nh-assistant-admin-mcp-server-editor.component';\nimport { NhAssistantAdminMcpToolsComponent } from './nh-assistant-admin-mcp-tools.component';\n\n/** Result of the latest connection test per server. */\ninterface TestState {\n running: boolean;\n result: McpServerTestResult | null;\n}\n\nlet nextId = 0;\n\n/**\n * MCP server administration: list, connection test, tool sync, the server editor and the\n * tool table of one server.\n */\n@Component({\n selector: 'nh-assistant-admin-mcp-servers',\n standalone: true,\n imports: [\n DatePipe,\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantAdminMcpServerEditorComponent,\n NhAssistantAdminMcpToolsComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-mcp-servers.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminMcpServersComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n private readonly actions = new Subscription();\n\n readonly id = `nh-assistant-admin-mcp-${nextId++}`;\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly servers = signal<McpServer[]>([]);\n /** `undefined`: list; `null`: new server; a server: editing that server. */\n readonly editing = signal<McpServer | null | undefined>(undefined);\n readonly toolsOf = signal<McpServer | null>(null);\n readonly tests = signal<Record<string, TestState>>({});\n readonly confirmingDelete = signal<string | null>(null);\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.actions.unsubscribe();\n });\n this.load();\n }\n\n load(): void {\n this.loading.set(true);\n this.loadFailed.set(false);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.getMcpServers().subscribe({\n next: servers => {\n this.servers.set(servers);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n /** Reloads the list silently, for example after a sync changed the sync status. */\n refresh(): void {\n this.actions.add(this.admin.getMcpServers().subscribe({ next: servers => this.servers.set(servers), error: () => undefined }));\n }\n\n create(): void {\n this.error.set(null);\n this.editing.set(null);\n }\n\n edit(server: McpServer): void {\n this.error.set(null);\n this.editing.set(server);\n }\n\n onSaved(server: McpServer): void {\n this.servers.update(servers => servers.some(item => item.id === server.id)\n ? servers.map(item => item.id === server.id ? server : item)\n : [...servers, server]);\n this.editing.set(undefined);\n }\n\n test(server: McpServer): void {\n this.setTest(server.id, { running: true, result: null });\n this.actions.add(this.admin.testMcpServer(server.id).subscribe({\n next: result => this.setTest(server.id, { running: false, result }),\n error: (error: unknown) => {\n const failure = toNhAssistantError(error);\n this.setTest(server.id, { running: false, result: { ok: false, code: failure.code, toolCount: null } });\n }\n }));\n }\n\n testState(serverId: string): TestState | null {\n return this.tests()[serverId] ?? null;\n }\n\n testErrorKeys(code: string | null): string[] {\n return code ? [nhAssistantErrorMessageKey(code), 'nh-assistant.errors.generic'] : ['nh-assistant.errors.generic'];\n }\n\n remove(server: McpServer): void {\n this.confirmingDelete.set(null);\n this.error.set(null);\n this.actions.add(this.admin.deleteMcpServer(server.id).subscribe({\n complete: () => this.servers.update(servers => servers.filter(item => item.id !== server.id)),\n error: (error: unknown) => this.error.set(toNhAssistantError(error))\n }));\n }\n\n private setTest(serverId: string, state: TestState): void {\n this.tests.update(tests => ({ ...tests, [serverId]: state }));\n }\n}\n","@if (editing() !== undefined) {\n <nh-assistant-admin-mcp-server-editor [server]=\"editing() ?? null\" (saved)=\"onSaved($event)\" (cancelled)=\"editing.set(undefined)\" />\n} @else if (toolsOf(); as server) {\n <nh-assistant-admin-mcp-tools [server]=\"server\" (closed)=\"toolsOf.set(null); refresh()\" (synced)=\"refresh()\" />\n} @else {\n <section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.mcp.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.mcp.description' | translate }}</p>\n </div>\n <button class=\"primary\" type=\"button\" [disabled]=\"loading() || loadFailed()\" (click)=\"create()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.mcp.new' | translate }}\n </button>\n </header>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n @if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (loadFailed()) {\n <div class=\"state\" role=\"alert\">\n <p>{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (servers().length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.mcp.empty' | translate }}</p>\n } @else {\n <ul class=\"cards\">\n @for (server of servers(); track server.id) {\n <li class=\"card\" [class.inactive]=\"!server.isEnabled\">\n <div class=\"card-header\">\n <strong>{{ server.displayName }}</strong>\n <span class=\"mono muted\">{{ server.id }}</span>\n <span class=\"badge\" [class.success]=\"server.isEnabled\">{{ (server.isEnabled ? 'nh-assistant.admin.enabled' : 'nh-assistant.admin.disabled') | translate }}</span>\n @if (server.lastSyncStatus) {\n <span class=\"badge\" [class.success]=\"server.lastSyncStatus === 'ok'\" [class.danger]=\"server.lastSyncStatus === 'failed'\">\n {{ (server.lastSyncStatus === 'ok' ? 'nh-assistant.admin.mcp.sync-ok' : 'nh-assistant.admin.mcp.sync-failed') | translate }}\n </span>\n }\n </div>\n <span class=\"mono muted url\">{{ server.url }}</span>\n <div class=\"meta\">\n <span>{{ 'nh-assistant.admin.mcp.auth.' + server.authMode | translate }}</span>\n @if (server.authMode === 'bearer' || server.authMode === 'api-key') {\n <span class=\"badge\" [class.success]=\"server.hasSecret\" [class.warning]=\"!server.hasSecret\">\n {{ (server.hasSecret ? 'nh-assistant.admin.mcp.secret-set' : 'nh-assistant.admin.mcp.no-secret') | translate }}\n </span>\n }\n <span>\n @if (server.lastSyncAt) {\n {{ 'nh-assistant.admin.mcp.last-sync' | translate: { date: (server.lastSyncAt | date: 'medium') } }}\n } @else {\n {{ 'nh-assistant.admin.mcp.never-synced' | translate }}\n }\n </span>\n <span>\n @if (server.assignedAgentIds.length > 0) {\n {{ 'nh-assistant.admin.mcp.assigned' | translate: { agents: server.assignedAgentIds.join(', ') } }}\n } @else {\n {{ 'nh-assistant.admin.mcp.unassigned' | translate }}\n }\n </span>\n </div>\n\n @if (testState(server.id); as state) {\n @if (state.running) {\n <p class=\"muted\" role=\"status\">{{ 'nh-assistant.admin.mcp.testing' | translate }}</p>\n } @else if (state.result?.ok) {\n <p class=\"message success\" role=\"status\"><nh-assistant-icon name=\"check\" />{{ 'nh-assistant.admin.mcp.test-ok' | translate: { count: state.result?.toolCount ?? 0 } }}</p>\n } @else {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ testErrorKeys(state.result?.code ?? null) | nhAssistantTranslate: (state.result?.code ?? '') }}</p>\n }\n }\n\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"edit(server)\"><nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}</button>\n <button class=\"secondary\" type=\"button\" [disabled]=\"testState(server.id)?.running\" (click)=\"test(server)\">\n <nh-assistant-icon name=\"link\" />{{ 'nh-assistant.admin.mcp.test' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"toolsOf.set(server)\"><nh-assistant-icon name=\"tool\" />{{ 'nh-assistant.admin.mcp.tools' | translate }}</button>\n @if (confirmingDelete() === server.id) {\n <button class=\"danger\" type=\"button\" (click)=\"remove(server)\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingDelete.set(null)\">{{ 'nh-assistant.admin.keep' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" (click)=\"confirmingDelete.set(server.id)\"><nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.delete' | translate }}</button>\n }\n </div>\n </li>\n }\n </ul>\n }\n </section>\n}\n","import { ChangeDetectionStrategy, Component, ElementRef, afterNextRender, inject, input, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n NhAssistantStore\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAdminAgentsComponent } from './agents/nh-assistant-admin-agents.component';\nimport { NhAssistantAdminContextComponent } from './context/nh-assistant-admin-context.component';\nimport { NhAssistantAdminMcpServersComponent } from './mcp/nh-assistant-admin-mcp-servers.component';\n\nexport type NhAssistantAdminTab = 'context' | 'agents' | 'mcp-servers';\n\nlet nextId = 0;\n\n/**\n * The assistant administration page with the tabs Context, Agents and MCP servers. The host\n * routes to it and guards the route with its admin permission; the component additionally\n * shows a no-access state unless the server reports `canAdminister`.\n */\n@Component({\n selector: 'nh-assistant-admin',\n standalone: true,\n imports: [\n TranslatePipe,\n NhAssistantIconComponent,\n NhAssistantAdminContextComponent,\n NhAssistantAdminAgentsComponent,\n NhAssistantAdminMcpServersComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin.component.html',\n styleUrl: './nh-assistant-admin.component.scss'\n})\nexport class NhAssistantAdminComponent {\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly store = inject(NhAssistantStore);\n\n /** Tab shown first. */\n readonly initialTab = input<NhAssistantAdminTab>('context');\n\n readonly id = `nh-assistant-admin-${nextId++}`;\n readonly tabs: readonly NhAssistantAdminTab[] = ['context', 'agents', 'mcp-servers'];\n readonly activeTab = signal<NhAssistantAdminTab | null>(null);\n readonly ready = signal(false);\n\n constructor() {\n afterNextRender(() => {\n void this.store.initialize().then(() => this.ready.set(true));\n });\n }\n\n selected(): NhAssistantAdminTab {\n return this.activeTab() ?? this.initialTab();\n }\n\n select(tab: NhAssistantAdminTab): void {\n this.activeTab.set(tab);\n }\n\n /** Arrow keys, Home and End move between tabs as the ARIA tabs pattern describes. */\n onTabKeydown(event: KeyboardEvent): void {\n const index = this.tabs.indexOf(this.selected());\n const last = this.tabs.length - 1;\n const targets: Record<string, number> = {\n ArrowRight: index === last ? 0 : index + 1,\n ArrowLeft: index === 0 ? last : index - 1,\n Home: 0,\n End: last\n };\n const next = targets[event.key];\n if (next === undefined) {\n return;\n }\n\n event.preventDefault();\n this.select(this.tabs[next]);\n this.host.nativeElement.querySelector<HTMLElement>(`#${this.id}-tab-${this.tabs[next]}`)?.focus();\n }\n}\n","<section class=\"admin\" [attr.aria-labelledby]=\"id + '-title'\">\n <header class=\"page-header\">\n <nh-assistant-icon class=\"page-icon\" name=\"admin\" />\n <div>\n <h2 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.title' | translate }}</h2>\n <p>{{ 'nh-assistant.admin.description' | translate }}</p>\n </div>\n </header>\n\n @if (!ready() || (store.statusLoading() && !store.enabled())) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (!store.enabled()) {\n <div class=\"state\">\n <nh-assistant-icon class=\"state-icon\" name=\"warning\" />\n <p class=\"state-title\">{{ 'nh-assistant.panel.unavailable-title' | translate }}</p>\n <p>{{ 'nh-assistant.panel.unavailable-description' | translate }}</p>\n </div>\n } @else if (!store.canAdminister()) {\n <div class=\"state\">\n <nh-assistant-icon class=\"state-icon\" name=\"warning\" />\n <p class=\"state-title\">{{ 'nh-assistant.admin.forbidden-title' | translate }}</p>\n <p>{{ 'nh-assistant.admin.forbidden-description' | translate }}</p>\n </div>\n } @else {\n <div class=\"tabs\" role=\"tablist\" [attr.aria-label]=\"'nh-assistant.admin.tabs-label' | translate\" (keydown)=\"onTabKeydown($event)\">\n @for (tab of tabs; track tab) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"tab\"\n [id]=\"id + '-tab-' + tab\"\n [attr.aria-selected]=\"selected() === tab\"\n [attr.aria-controls]=\"id + '-panel'\"\n [attr.tabindex]=\"selected() === tab ? 0 : -1\"\n (click)=\"select(tab)\">\n {{ 'nh-assistant.admin.tabs.' + tab | translate }}\n </button>\n }\n </div>\n\n <div class=\"panel\" role=\"tabpanel\" tabindex=\"0\" [id]=\"id + '-panel'\" [attr.aria-labelledby]=\"id + '-tab-' + selected()\">\n @switch (selected()) {\n @case ('context') {\n <nh-assistant-admin-context />\n }\n @case ('agents') {\n <nh-assistant-admin-agents />\n }\n @case ('mcp-servers') {\n <nh-assistant-admin-mcp-servers />\n }\n }\n </div>\n }\n</section>\n","/*\n * Public API surface of @newheap/platform-ai-chat/admin.\n *\n * The administration page is a separate entry point so hosts load it only on their lazy\n * admin route and the chat panel stays small.\n */\nexport * from './nh-assistant-admin.component';\nexport * from './context/nh-assistant-admin-context.component';\nexport * from './agents/nh-assistant-admin-agents.component';\nexport * from './agents/nh-assistant-admin-agent-editor.component';\nexport * from './agents/nh-assistant-agent-feedback-report.component';\nexport * from './mcp/nh-assistant-admin-mcp-servers.component';\nexport * from './mcp/nh-assistant-admin-mcp-server-editor.component';\nexport * from './mcp/nh-assistant-admin-mcp-tools.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["nextId","nhAssistantErrorKeys","toNhAssistantError","NhAssistantIconComponent","NhAssistantTranslatePipe","NH_ASSISTANT_DASH_CASE"],"mappings":"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"}
1
+ {"version":3,"file":"newheap-platform-ai-chat-admin.mjs","sources":["../../../projects/nh-ai-chat/admin/src/context/nh-assistant-admin-context.component.ts","../../../projects/nh-ai-chat/admin/src/context/nh-assistant-admin-context.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-admin-agent-editor.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-admin-agent-editor.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-evaluation.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-evaluation.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-feedback-report.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-feedback-report.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-admin-agents.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-admin-agents.component.html","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-server-editor.component.ts","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-server-editor.component.html","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-tools.component.ts","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-tools.component.html","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-servers.component.ts","../../../projects/nh-ai-chat/admin/src/mcp/nh-assistant-admin-mcp-servers.component.html","../../../projects/nh-ai-chat/admin/src/nh-assistant-admin.component.ts","../../../projects/nh-ai-chat/admin/src/nh-assistant-admin.component.html","../../../projects/nh-ai-chat/admin/src/public-api.ts","../../../projects/nh-ai-chat/admin/src/newheap-platform-ai-chat-admin.ts"],"sourcesContent":["import { DatePipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription, forkJoin } from 'rxjs';\nimport {\n ApplicationContext,\n ApplicationContextVersion,\n NhAssistantAdminApiService,\n NhAssistantClientErrorCodes,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\n/** Maximum length of the application context and of agent instructions. */\nexport const NH_ASSISTANT_MAX_INSTRUCTIONS = 20_000;\n\nlet nextId = 0;\n\n/**\n * Editor of the application context: the current version with its hash, optimistic\n * concurrency through `expectedVersion`, and the version history.\n */\n@Component({\n selector: 'nh-assistant-admin-context',\n standalone: true,\n imports: [DatePipe, TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-context.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminContextComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n\n readonly id = `nh-assistant-admin-context-${nextId++}`;\n readonly max = NH_ASSISTANT_MAX_INSTRUCTIONS;\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly saving = signal(false);\n readonly saved = signal(false);\n readonly conflict = signal(false);\n readonly error = signal<NhAssistantError | null>(null);\n readonly context = signal<ApplicationContext | null>(null);\n readonly versions = signal<ApplicationContextVersion[]>([]);\n readonly text = signal('');\n\n readonly tooLong = computed(() => this.text().length > this.max);\n readonly dirty = computed(() => this.text() !== (this.context()?.text ?? ''));\n readonly canSave = computed(() => !this.saving() && !this.tooLong() && this.dirty() && this.context() !== null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n readonly history = computed(() => this.versions().filter(version => version.version !== this.context()?.version));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n this.load(false);\n }\n\n /** Loads the latest version; with `keepDraft` the user's unsaved text stays in the editor. */\n load(keepDraft: boolean): void {\n this.loading.set(!keepDraft);\n this.loadFailed.set(false);\n this.subscription?.unsubscribe();\n this.subscription = forkJoin([this.admin.getContext(), this.admin.getContextVersions()]).subscribe({\n next: ([context, versions]) => {\n const draft = this.text();\n this.context.set(context);\n this.versions.set(versions);\n this.text.set(keepDraft ? draft : context.text);\n this.conflict.set(false);\n this.error.set(null);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n onInput(event: Event): void {\n this.text.set((event.target as HTMLTextAreaElement).value);\n this.saved.set(false);\n }\n\n save(): void {\n const context = this.context();\n if (!context || !this.canSave()) {\n return;\n }\n\n this.saving.set(true);\n this.saved.set(false);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.updateContext({ text: this.text(), expectedVersion: context.version }).subscribe({\n next: updated => {\n this.context.set(updated);\n this.versions.update(versions => [\n { version: updated.version, hash: updated.hash, updatedAt: updated.updatedAt, updatedBy: updated.updatedBy },\n ...versions\n ]);\n this.text.set(updated.text);\n this.saving.set(false);\n this.saved.set(true);\n },\n error: (error: unknown) => {\n const failure = toNhAssistantError(error);\n this.saving.set(false);\n this.conflict.set(failure.code === NhAssistantClientErrorCodes.versionConflict);\n this.error.set(this.conflict() ? null : failure);\n }\n });\n }\n}\n","<section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || saving()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.context.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.context.description' | translate }}</p>\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (loadFailed()) {\n <div class=\"state\" role=\"alert\">\n <p>{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load(false)\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (context(); as current) {\n <form class=\"stack\" (submit)=\"$event.preventDefault(); save()\">\n <div class=\"meta\">\n <span class=\"badge\">{{ 'nh-assistant.admin.context.version' | translate: { version: current.version } }}</span>\n <span>\n @if (current.updatedBy) {\n {{ 'nh-assistant.admin.context.updated' | translate: { date: (current.updatedAt | date: 'medium'), user: current.updatedBy } }}\n } @else {\n {{ 'nh-assistant.admin.context.updated-unknown' | translate: { date: (current.updatedAt | date: 'medium') } }}\n }\n </span>\n <span class=\"mono\" [attr.title]=\"current.hash\">{{ 'nh-assistant.admin.context.hash' | translate }} {{ current.hash.slice(0, 18) }}</span>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-text'\">{{ 'nh-assistant.admin.context.label' | translate }}</label>\n <textarea\n class=\"large\"\n rows=\"14\"\n [id]=\"id + '-text'\"\n [value]=\"text()\"\n [attr.aria-describedby]=\"id + '-hint'\"\n [attr.aria-invalid]=\"tooLong() ? true : null\"\n (input)=\"onInput($event)\"></textarea>\n <p class=\"hint\" [id]=\"id + '-hint'\">\n <span [class.error-text]=\"tooLong()\">{{ tooLong() ? ('nh-assistant.admin.too-long' | translate) : '' }}</span>\n <span class=\"counter\" [class.error-text]=\"tooLong()\">{{ 'nh-assistant.admin.characters' | translate: { count: text().length, max: max } }}</span>\n </p>\n </div>\n\n @if (conflict()) {\n <div class=\"message warning\" role=\"alert\">\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">{{ 'nh-assistant.admin.context.conflict' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"load(true)\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.context.reload' | translate }}\n </button>\n </div>\n }\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n @if (saved()) {\n <p class=\"message success\" role=\"status\"><nh-assistant-icon name=\"check\" />{{ 'nh-assistant.admin.saved' | translate }}</p>\n }\n\n <div class=\"actions\">\n <button class=\"primary\" type=\"submit\" [disabled]=\"!canSave()\">\n {{ (saving() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}\n </button>\n </div>\n </form>\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-history'\">\n <h4 [id]=\"id + '-history'\">{{ 'nh-assistant.admin.context.history' | translate }}</h4>\n @if (history().length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.context.history-empty' | translate }}</p>\n } @else {\n <ol class=\"history\">\n @for (version of history(); track version.version) {\n <li>\n <span class=\"badge\">{{ 'nh-assistant.admin.context.version' | translate: { version: version.version } }}</span>\n <span>{{ version.updatedAt | date: 'medium' }}</span>\n @if (version.updatedBy) {\n <span>{{ version.updatedBy }}</span>\n }\n <span class=\"mono muted\" [attr.title]=\"version.hash\">{{ version.hash.slice(0, 18) }}</span>\n </li>\n }\n </ol>\n }\n </section>\n }\n</section>\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n untracked\n} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n AdminAgent,\n AdminAgentInput,\n AssistantAutonomy,\n McpServer,\n ɵNH_ASSISTANT_DASH_CASE as NH_ASSISTANT_DASH_CASE,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport { NH_ASSISTANT_MAX_INSTRUCTIONS } from '../context/nh-assistant-admin-context.component';\n\n/** True when a tool id matches a selector glob (`*` matches any characters). */\nexport function nhAssistantSelectorMatches(toolId: string, selector: string): boolean {\n const pattern = selector.split('*').map(part => part.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('.*');\n return new RegExp(`^${pattern}$`).test(toolId);\n}\n\nconst selectorPattern = /^[a-z0-9*][a-z0-9.*_-]*$/i;\n\nlet nextId = 0;\n\n/**\n * Creates or edits one agent: texts, autonomy, policy, tool selectors chosen from the tool\n * catalog or typed as patterns, and assigned MCP servers.\n */\n@Component({\n selector: 'nh-assistant-admin-agent-editor',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-agent-editor.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminAgentEditorComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n\n /** The agent to edit, or null for a new agent. */\n readonly agent = input<AdminAgent | null>(null);\n readonly tools = input<readonly ToolCatalogEntry[]>([]);\n readonly servers = input<readonly McpServer[]>([]);\n readonly saved = output<AdminAgent>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-agent-editor-${nextId++}`;\n readonly max = NH_ASSISTANT_MAX_INSTRUCTIONS;\n readonly autonomyLevels: readonly AssistantAutonomy[] = ['observe', 'explain', 'propose', 'simulate', 'execute'];\n\n readonly agentId = signal('');\n readonly displayName = signal('');\n readonly description = signal('');\n readonly instructions = signal('');\n readonly autonomy = signal<AssistantAutonomy>('explain');\n readonly requiredPolicy = signal('');\n readonly toolSelectors = signal<string[]>([]);\n readonly mcpServerIds = signal<string[]>([]);\n readonly newSelector = signal('');\n readonly catalogFilter = signal('');\n readonly submitted = signal(false);\n readonly saving = signal(false);\n readonly error = signal<NhAssistantError | null>(null);\n\n readonly isNew = computed(() => this.agent() === null);\n readonly idInvalid = computed(() => this.isNew() && !NH_ASSISTANT_DASH_CASE.test(this.agentId()));\n readonly nameMissing = computed(() => this.displayName().trim().length === 0);\n readonly tooLong = computed(() => this.instructions().length > this.max);\n readonly selectorInvalid = computed(() => this.newSelector().trim().length > 0 && !selectorPattern.test(this.newSelector().trim()));\n readonly valid = computed(() => !this.idInvalid() && !this.nameMissing() && !this.tooLong());\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n readonly filteredTools = computed(() => {\n const filter = this.catalogFilter().trim().toLowerCase();\n return this.tools().filter(tool => !filter ||\n tool.id.toLowerCase().includes(filter) || tool.description.toLowerCase().includes(filter));\n });\n readonly matchCount = computed(() => this.tools()\n .filter(tool => this.toolSelectors().some(selector => nhAssistantSelectorMatches(tool.id, selector))).length);\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n\n effect(() => {\n const agent = this.agent();\n untracked(() => this.reset(agent));\n });\n }\n\n isSelected(toolId: string): boolean {\n return this.toolSelectors().includes(toolId);\n }\n\n isCovered(toolId: string): boolean {\n return this.toolSelectors().some(selector => selector !== toolId && nhAssistantSelectorMatches(toolId, selector));\n }\n\n toggleTool(toolId: string, checked: boolean): void {\n this.toolSelectors.update(selectors => checked\n ? [...selectors.filter(selector => selector !== toolId), toolId]\n : selectors.filter(selector => selector !== toolId));\n }\n\n addSelector(): void {\n const selector = this.newSelector().trim();\n if (selector.length === 0 || this.selectorInvalid()) {\n return;\n }\n\n this.toolSelectors.update(selectors => selectors.includes(selector) ? selectors : [...selectors, selector]);\n this.newSelector.set('');\n }\n\n onSelectorKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n event.preventDefault();\n this.addSelector();\n }\n }\n\n removeSelector(selector: string): void {\n this.toolSelectors.update(selectors => selectors.filter(item => item !== selector));\n }\n\n toggleServer(serverId: string, checked: boolean): void {\n this.mcpServerIds.update(ids => checked ? [...ids.filter(id => id !== serverId), serverId] : ids.filter(id => id !== serverId));\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement).value;\n }\n\n checked(event: Event): boolean {\n return (event.target as HTMLInputElement).checked;\n }\n\n save(): void {\n this.submitted.set(true);\n if (!this.valid() || this.saving()) {\n return;\n }\n\n const policy = this.requiredPolicy().trim();\n const input: AdminAgentInput = {\n id: this.isNew() ? this.agentId() : this.agent()!.id,\n displayName: this.displayName().trim(),\n description: this.description().trim(),\n instructions: this.instructions(),\n toolSelectors: this.toolSelectors(),\n mcpServerIds: this.mcpServerIds(),\n requiredPolicy: policy.length > 0 ? policy : null,\n autonomy: this.autonomy()\n };\n\n const existing = this.agent();\n const request = existing\n ? this.admin.updateAgent(existing.id, { ...input, expectedVersion: existing.version })\n : this.admin.createAgent(input);\n\n this.saving.set(true);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = request.subscribe({\n next: agent => {\n this.saving.set(false);\n this.saved.emit(agent);\n },\n error: (error: unknown) => {\n this.saving.set(false);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n private reset(agent: AdminAgent | null): void {\n this.agentId.set(agent?.id ?? '');\n this.displayName.set(agent?.displayName ?? '');\n this.description.set(agent?.description ?? '');\n this.instructions.set(agent?.instructions ?? '');\n this.autonomy.set(agent?.autonomy ?? 'explain');\n this.requiredPolicy.set(agent?.requiredPolicy ?? '');\n this.toolSelectors.set([...(agent?.toolSelectors ?? [])]);\n this.mcpServerIds.set([...(agent?.mcpServerIds ?? [])]);\n this.submitted.set(false);\n this.error.set(null);\n }\n}\n","<form class=\"section card\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"saving()\" (submit)=\"$event.preventDefault(); save()\">\n <h3 [id]=\"id + '-title'\">\n @if (agent(); as current) {\n {{ 'nh-assistant.admin.agent-editor.edit-title' | translate: { name: current.displayName } }}\n } @else {\n {{ 'nh-assistant.admin.agent-editor.new-title' | translate }}\n }\n </h3>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-id'\">{{ 'nh-assistant.admin.agent-editor.id' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n autocomplete=\"off\"\n [id]=\"id + '-id'\"\n [value]=\"agentId()\"\n [disabled]=\"!isNew()\"\n [attr.aria-describedby]=\"id + '-id-hint'\"\n [attr.aria-invalid]=\"submitted() && idInvalid() ? true : null\"\n (input)=\"agentId.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-id-hint'\">\n <span [class.error-text]=\"submitted() && idInvalid()\">\n {{ (submitted() && idInvalid() ? 'nh-assistant.admin.invalid-id' : 'nh-assistant.admin.agent-editor.id-hint') | translate }}\n </span>\n </p>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-name'\">{{ 'nh-assistant.admin.agent-editor.display-name' | translate }}</label>\n <input\n type=\"text\"\n [id]=\"id + '-name'\"\n [value]=\"displayName()\"\n [attr.aria-invalid]=\"submitted() && nameMissing() ? true : null\"\n [attr.aria-describedby]=\"id + '-name-hint'\"\n (input)=\"displayName.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-name-hint'\">\n @if (submitted() && nameMissing()) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.required' | translate }}</span>\n }\n </p>\n </div>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-description'\">{{ 'nh-assistant.admin.agent-editor.description' | translate }}</label>\n <input type=\"text\" [id]=\"id + '-description'\" [value]=\"description()\" (input)=\"description.set(value($event))\" />\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-instructions'\">{{ 'nh-assistant.admin.agent-editor.instructions' | translate }}</label>\n <textarea\n rows=\"8\"\n [id]=\"id + '-instructions'\"\n [value]=\"instructions()\"\n [attr.aria-describedby]=\"id + '-instructions-hint'\"\n [attr.aria-invalid]=\"tooLong() ? true : null\"\n (input)=\"instructions.set(value($event))\"></textarea>\n <p class=\"hint\" [id]=\"id + '-instructions-hint'\">\n <span [class.error-text]=\"tooLong()\">\n {{ (tooLong() ? 'nh-assistant.admin.too-long' : 'nh-assistant.admin.agent-editor.instructions-hint') | translate }}\n </span>\n <span class=\"counter\" [class.error-text]=\"tooLong()\">{{ 'nh-assistant.admin.characters' | translate: { count: instructions().length, max: max } }}</span>\n </p>\n </div>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-autonomy'\">{{ 'nh-assistant.admin.agent-editor.autonomy' | translate }}</label>\n <select [id]=\"id + '-autonomy'\" [attr.aria-describedby]=\"id + '-autonomy-hint'\" (change)=\"autonomy.set($any(value($event)))\">\n @for (level of autonomyLevels; track level) {\n <option [value]=\"level\" [selected]=\"autonomy() === level\">{{ 'nh-assistant.admin.agents.autonomy.' + level | translate }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-autonomy-hint'\">{{ 'nh-assistant.admin.agent-editor.autonomy-hint' | translate }}</p>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-policy'\">{{ 'nh-assistant.admin.agent-editor.required-policy' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n autocomplete=\"off\"\n [id]=\"id + '-policy'\"\n [value]=\"requiredPolicy()\"\n [attr.aria-describedby]=\"id + '-policy-hint'\"\n (input)=\"requiredPolicy.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.agent-editor.required-policy-hint' | translate }}</p>\n </div>\n </div>\n\n <p class=\"hint\">{{ 'nh-assistant.admin.agent-editor.state-hint' | translate }}</p>\n\n <fieldset class=\"subsection\">\n <legend>{{ 'nh-assistant.admin.agent-editor.tool-selectors' | translate }}</legend>\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.tool-selectors-hint' | translate }}</p>\n\n @if (toolSelectors().length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.no-selectors' | translate }}</p>\n } @else {\n <ul class=\"chips\">\n @for (selector of toolSelectors(); track selector) {\n <li class=\"chip\">\n <span>{{ selector }}</span>\n <button\n type=\"button\"\n [attr.aria-label]=\"'nh-assistant.admin.agent-editor.remove-selector' | translate: { selector: selector }\"\n [attr.title]=\"'nh-assistant.admin.agent-editor.remove-selector' | translate: { selector: selector }\"\n (click)=\"removeSelector(selector)\">\n <nh-assistant-icon name=\"x\" />\n </button>\n </li>\n }\n </ul>\n <p class=\"muted\" role=\"status\">{{ 'nh-assistant.admin.agent-editor.matches' | translate: { count: matchCount() } }}</p>\n }\n\n <div class=\"inline\">\n <input\n type=\"text\"\n class=\"mono\"\n autocomplete=\"off\"\n [attr.aria-label]=\"'nh-assistant.admin.agent-editor.add-selector' | translate\"\n [attr.placeholder]=\"'nh-assistant.admin.agent-editor.selector-placeholder' | translate\"\n [attr.aria-invalid]=\"selectorInvalid() ? true : null\"\n [value]=\"newSelector()\"\n (input)=\"newSelector.set(value($event))\"\n (keydown)=\"onSelectorKeydown($event)\" />\n <button class=\"secondary\" type=\"button\" [disabled]=\"newSelector().trim().length === 0 || selectorInvalid()\" (click)=\"addSelector()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.agent-editor.add-selector' | translate }}\n </button>\n </div>\n\n <div class=\"field\">\n <label class=\"label\" [for]=\"id + '-catalog-filter'\">{{ 'nh-assistant.admin.agent-editor.catalog' | translate }}</label>\n <input\n type=\"search\"\n [id]=\"id + '-catalog-filter'\"\n [attr.placeholder]=\"'nh-assistant.admin.agent-editor.catalog-filter' | translate\"\n [value]=\"catalogFilter()\"\n (input)=\"catalogFilter.set(value($event))\" />\n <ul class=\"catalog\" [attr.aria-label]=\"'nh-assistant.admin.agent-editor.catalog' | translate\">\n @for (tool of filteredTools(); track tool.id) {\n <li>\n <label>\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(tool.id) || isCovered(tool.id)\"\n [disabled]=\"isCovered(tool.id)\"\n (change)=\"toggleTool(tool.id, checked($event))\" />\n <span class=\"tool-id\">{{ tool.id }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.source.' + tool.source | translate }}</span>\n <span class=\"badge\" [class.warning]=\"tool.effect !== 'read-only'\">{{ 'nh-assistant.admin.effect.' + tool.effect | translate }}</span>\n <span class=\"muted\">{{ tool.description }}</span>\n </label>\n </li>\n } @empty {\n <li class=\"muted\">{{ 'nh-assistant.admin.agent-editor.catalog-empty' | translate }}</li>\n }\n </ul>\n </div>\n </fieldset>\n\n <fieldset class=\"subsection\">\n <legend>{{ 'nh-assistant.admin.agent-editor.mcp-servers' | translate }}</legend>\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.mcp-servers-hint' | translate }}</p>\n @for (server of servers(); track server.id) {\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"mcpServerIds().includes(server.id)\" (change)=\"toggleServer(server.id, checked($event))\" />\n <span>{{ server.displayName }} <span class=\"mono muted\">{{ server.id }}</span></span>\n </label>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.mcp-servers-empty' | translate }}</p>\n }\n </fieldset>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n <div class=\"actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"cancelled.emit()\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n <button class=\"primary\" type=\"submit\" [disabled]=\"saving() || tooLong()\">\n {{ (saving() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}\n </button>\n </div>\n</form>\n","import { DatePipe, DecimalPipe, DOCUMENT } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, signal, untracked } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n AgentEvaluation,\n AgentEvaluationCost,\n AgentReplay,\n NhAssistantAdminApiService,\n NhAssistantError,\n NhAssistantPanelService,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\n/** Periods the evaluation offers, in days before now; the server allows at most 92. */\nexport type NhAssistantEvaluationPeriod = 7 | 30 | 90;\n\n/** One row of the cost comparison: a measure of the live agent next to the variant's. */\ninterface NhAssistantCostRow {\n key: 'runs' | 'model-calls' | 'tokens' | 'tool-calls';\n live: AgentEvaluationCost;\n variant: AgentEvaluationCost;\n}\n\nconst dayMs = 24 * 60 * 60 * 1000;\nconst defaultReplayRuns = 100;\nconst maxReplayRuns = 500;\n\nlet nextId = 0;\n\n/**\n * Compares a shadow variant of an agent with the live agent, for the agent's administrators: the\n * runs that handled the same events, per tool the proposals both made, only one made and what\n * people decided about the live ones, what each cost and how each routed, with links to the threads\n * of the differences. Small numbers mislead, so counts stand next to every share. Administrators\n * replay the recorded runs of the period into the variant and export the comparison as JSON Lines.\n * The report holds no messages or arguments.\n */\n@Component({\n selector: 'nh-assistant-agent-evaluation',\n standalone: true,\n imports: [DatePipe, DecimalPipe, TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-evaluation.component.html',\n styleUrls: ['../nh-assistant-admin-shared.scss', './nh-assistant-agent-feedback-report.component.scss']\n})\nexport class NhAssistantAgentEvaluationComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly panel = inject(NhAssistantPanelService, { optional: true });\n private readonly document = inject(DOCUMENT);\n private subscription?: Subscription;\n private replaySubscription?: Subscription;\n\n /** The live agent. */\n readonly agentId = input.required<string>();\n /** Its shadow variants; the first is compared until another is chosen. */\n readonly variants = input.required<readonly string[]>();\n\n readonly id = `nh-assistant-agent-evaluation-${nextId++}`;\n readonly periods: readonly NhAssistantEvaluationPeriod[] = [7, 30, 90];\n readonly maxReplayRuns = maxReplayRuns;\n readonly canOpenThreads = this.panel !== null;\n\n readonly variant = signal('');\n readonly period = signal<NhAssistantEvaluationPeriod>(7);\n readonly loading = signal(true);\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n readonly evaluation = signal<AgentEvaluation | null>(null);\n\n readonly exporting = signal(false);\n readonly exportError = signal<NhAssistantError | null>(null);\n readonly exportErrorKeys = computed(() => nhAssistantErrorKeys(this.exportError()));\n readonly canExport = computed(() => !this.exporting() && !this.loading() && (this.evaluation()?.runs.paired ?? 0) > 0);\n\n readonly replays = signal<AgentReplay[]>([]);\n readonly replayRuns = signal(defaultReplayRuns);\n readonly replaying = signal(false);\n readonly replayError = signal<NhAssistantError | null>(null);\n readonly replayErrorKeys = computed(() => nhAssistantErrorKeys(this.replayError()));\n readonly replayRunning = computed(() => this.replays().some(replay => replay.status === 'running'));\n\n readonly costRows = computed<NhAssistantCostRow[]>(() => {\n const evaluation = this.evaluation();\n return evaluation\n ? (['runs', 'model-calls', 'tokens', 'tool-calls'] as const).map(key => ({ key, live: evaluation.liveCost, variant: evaluation.variantCost }))\n : [];\n });\n /** Routing matters only when one of the two worked in a skill. */\n readonly showRouting = computed(() => (this.evaluation()?.routing ?? []).some(row => row.liveSkill !== null || row.variantSkill !== null));\n\n /** The period the last load asked for, so the report, the export and a replay agree. */\n private range = periodRange(7);\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.replaySubscription?.unsubscribe();\n });\n effect(() => {\n const variants = this.variants();\n this.agentId();\n untracked(() => {\n if (!variants.includes(this.variant())) {\n this.variant.set(variants[0] ?? '');\n }\n this.load();\n });\n });\n }\n\n /** Reloads the comparison and the variant's replays for the chosen period. */\n load(): void {\n this.range = periodRange(this.period());\n this.error.set(null);\n this.exportError.set(null);\n this.subscription?.unsubscribe();\n if (!this.variant()) {\n this.loading.set(false);\n this.evaluation.set(null);\n return;\n }\n\n this.loading.set(true);\n this.subscription = this.admin.getAgentEvaluation(this.agentId(), { variant: this.variant(), ...this.range }).subscribe({\n next: evaluation => {\n this.evaluation.set(evaluation);\n this.loading.set(false);\n },\n error: (failure: unknown) => {\n this.evaluation.set(null);\n this.loading.set(false);\n this.error.set(toNhAssistantError(failure));\n }\n });\n this.loadReplays();\n }\n\n loadReplays(): void {\n this.replaySubscription?.unsubscribe();\n this.replaySubscription = this.admin.getAgentReplays(this.variant()).subscribe({\n next: list => this.replays.set(list.items),\n error: () => this.replays.set([])\n });\n }\n\n onVariant(event: Event): void {\n this.variant.set((event.target as HTMLSelectElement).value);\n this.load();\n }\n\n onPeriod(event: Event): void {\n this.period.set(Number((event.target as HTMLSelectElement).value) as NhAssistantEvaluationPeriod);\n this.load();\n }\n\n onReplayRuns(event: Event): void {\n const value = Math.round(Number((event.target as HTMLInputElement).value));\n this.replayRuns.set(Number.isFinite(value) ? Math.min(Math.max(value, 1), maxReplayRuns) : defaultReplayRuns);\n }\n\n /** Replays the live agent's recorded runs of the period into the variant. */\n replay(): void {\n if (this.replaying() || this.replayRunning() || !this.variant()) {\n return;\n }\n\n this.replaying.set(true);\n this.replayError.set(null);\n this.admin\n .startAgentReplay(this.variant(), { sourceAgentId: this.agentId(), ...this.range, maxRuns: this.replayRuns() })\n .subscribe({\n next: replay => {\n this.replaying.set(false);\n this.replays.update(items => [replay, ...items.filter(item => item.id !== replay.id)]);\n },\n error: (failure: unknown) => {\n this.replaying.set(false);\n this.replayError.set(toNhAssistantError(failure));\n }\n });\n }\n\n /** Downloads the paired runs of the comparison as a JSON Lines file. */\n async export(): Promise<void> {\n if (!this.canExport()) {\n return;\n }\n\n this.exporting.set(true);\n this.exportError.set(null);\n try {\n const blob = await this.admin.exportAgentEvaluation(this.agentId(), { variant: this.variant(), ...this.range });\n const url = URL.createObjectURL(blob);\n const link = this.document.createElement('a');\n link.href = url;\n link.download = `agent-evaluation-${this.agentId()}-${this.variant()}.jsonl`;\n link.click();\n URL.revokeObjectURL(url);\n } catch (failure) {\n this.exportError.set(toNhAssistantError(failure));\n } finally {\n this.exporting.set(false);\n }\n }\n\n /** Opens a thread of the comparison in the assistant panel, when the host has one. */\n openThread(conversationId: string): void {\n this.panel?.open(conversationId);\n }\n\n /** The share of a count in a total, or `null` without a total. */\n share(count: number, total: number): number | null {\n return total > 0 ? count / total : null;\n }\n\n total(row: AgentEvaluation['tools'][number]): number {\n return row.agreed + row.liveOnly;\n }\n\n categories(row: AgentEvaluation['tools'][number]): { category: string; count: number }[] {\n return Object.entries(row.liveDecisions.rejectionCategories)\n .map(([category, count]) => ({ category, count }))\n .sort((left, right) => right.count - left.count);\n }\n}\n\nfunction periodRange(days: number): { from: string; to: string } {\n const to = Date.now();\n return { from: new Date(to - days * dayMs).toISOString(), to: new Date(to).toISOString() };\n}\n","<section class=\"section report\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.evaluation.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.evaluation.description' | translate }}</p>\n <p class=\"muted export-hint\" [id]=\"id + '-export-hint'\">{{ 'nh-assistant.admin.evaluation.export-hint' | translate }}</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"loading()\" (click)=\"load()\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.evaluation.refresh' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" [disabled]=\"!canExport()\" [attr.aria-describedby]=\"id + '-export-hint'\" (click)=\"export()\">\n <nh-assistant-icon name=\"page\" />{{ (exporting() ? 'nh-assistant.admin.evaluation.exporting' : 'nh-assistant.admin.evaluation.export') | translate }}\n </button>\n </div>\n </header>\n\n <div class=\"filters\">\n <div class=\"field\">\n <label [for]=\"id + '-variant'\">{{ 'nh-assistant.admin.evaluation.variant' | translate }}</label>\n <select [id]=\"id + '-variant'\" (change)=\"onVariant($event)\">\n @for (option of variants(); track option) {\n <option [value]=\"option\" [selected]=\"variant() === option\">\n {{ ['nh-assistant.agents.' + option + '.name'] | nhAssistantTranslate: option }}\n </option>\n }\n </select>\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-period'\">{{ 'nh-assistant.admin.evaluation.period' | translate }}</label>\n <select [id]=\"id + '-period'\" (change)=\"onPeriod($event)\">\n @for (days of periods; track days) {\n <option [value]=\"days\" [selected]=\"period() === days\">{{ 'nh-assistant.admin.feedback.periods.last-' + days + '-days' | translate }}</option>\n }\n </select>\n </div>\n </div>\n\n @if (exportError(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ exportErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n @if (loading() && evaluation() === null) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (error(); as failure) {\n <div class=\"state\" role=\"alert\">\n <p>{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (evaluation(); as report) {\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-runs-title'\">\n <h4 [id]=\"id + '-runs-title'\">{{ 'nh-assistant.admin.evaluation.runs-title' | translate }}</h4>\n <dl class=\"meta\" data-evaluation-runs>\n <div><dt>{{ 'nh-assistant.admin.evaluation.runs.live' | translate }}</dt><dd>{{ report.runs.live }}</dd></div>\n <div><dt>{{ 'nh-assistant.admin.evaluation.runs.variant' | translate }}</dt><dd>{{ report.runs.variant }}</dd></div>\n <div><dt>{{ 'nh-assistant.admin.evaluation.runs.paired' | translate }}</dt><dd data-paired>{{ report.runs.paired }}</dd></div>\n <div><dt>{{ 'nh-assistant.admin.evaluation.runs.replayed' | translate }}</dt><dd>{{ report.runs.replayed }}</dd></div>\n <div><dt>{{ 'nh-assistant.admin.evaluation.runs.live-unpaired' | translate }}</dt><dd>{{ report.runs.liveUnpaired }}</dd></div>\n <div><dt>{{ 'nh-assistant.admin.evaluation.runs.variant-unpaired' | translate }}</dt><dd>{{ report.runs.variantUnpaired }}</dd></div>\n </dl>\n <p class=\"muted\">{{ 'nh-assistant.admin.evaluation.small-numbers' | translate }}</p>\n @if (report.runs.replayed > 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.evaluation.replayed-hint' | translate }}</p>\n }\n @if (report.runs.truncated) {\n <p class=\"message\" role=\"status\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.evaluation.truncated' | translate }}</p>\n }\n </section>\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-tools-title'\">\n <h4 [id]=\"id + '-tools-title'\">{{ 'nh-assistant.admin.evaluation.tools-title' | translate }}</h4>\n @if (report.tools.length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.evaluation.tools-empty' | translate }}</p>\n } @else {\n <div class=\"table-container\">\n <table class=\"summary-table\" [attr.aria-labelledby]=\"id + '-tools-title'\">\n <thead>\n <tr>\n <th scope=\"col\">{{ 'nh-assistant.admin.evaluation.columns.tool' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.evaluation.columns.agreed' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.evaluation.columns.live-only' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.evaluation.columns.variant-only' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.evaluation.columns.rejected-not-proposed' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.evaluation.columns.rejected-also-proposed' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.evaluation.columns.approved-missed' | translate }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.evaluation.columns.live-decisions' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of report.tools; track row.toolId) {\n <tr [attr.data-evaluation-tool]=\"row.toolId\">\n <th scope=\"row\" [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.tool' | translate\"><span class=\"mono\">{{ row.toolId }}</span></th>\n <td class=\"number\" data-agreed [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.agreed' | translate\">\n {{ row.agreed }}\n @if (share(row.agreed, total(row)); as fraction) {\n <span class=\"muted\">({{ fraction * 100 | number: '1.0-0' }}%)</span>\n }\n </td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.live-only' | translate\">{{ row.liveOnly }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.variant-only' | translate\">{{ row.variantOnly }}</td>\n <td class=\"number\" data-rejected-not-proposed [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.rejected-not-proposed' | translate\">{{ row.rejectedLiveNotProposed }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.rejected-also-proposed' | translate\">{{ row.rejectedLiveAlsoProposed }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.approved-missed' | translate\">{{ row.approvedLiveMissed }}</td>\n <td [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.live-decisions' | translate\">\n {{ 'nh-assistant.admin.evaluation.decisions' | translate: row.liveDecisions }}\n @if (categories(row).length > 0) {\n <ul class=\"badges\">\n @for (item of categories(row); track item.category) {\n <li>\n <span class=\"badge\">\n {{ 'nh-assistant.proposal-feedback.categories.' + item.category | nhAssistantTranslate: item.category }}\n <span class=\"count\">{{ item.count }}</span>\n </span>\n </li>\n }\n </ul>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </section>\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-cost-title'\">\n <h4 [id]=\"id + '-cost-title'\">{{ 'nh-assistant.admin.evaluation.cost-title' | translate }}</h4>\n <div class=\"table-container\">\n <table class=\"summary-table\" [attr.aria-labelledby]=\"id + '-cost-title'\">\n <thead>\n <tr>\n <th scope=\"col\">{{ 'nh-assistant.admin.evaluation.columns.measure' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.evaluation.columns.live' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.evaluation.columns.variant' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of costRows(); track row.key) {\n <tr [attr.data-cost]=\"row.key\">\n <th scope=\"row\" [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.measure' | translate\">{{ 'nh-assistant.admin.evaluation.cost.' + row.key | translate }}</th>\n @for (side of [row.live, row.variant]; track $index) {\n <td class=\"number\" [attr.data-label]=\"($index === 0 ? 'nh-assistant.admin.evaluation.columns.live' : 'nh-assistant.admin.evaluation.columns.variant') | translate\">\n @switch (row.key) {\n @case ('runs') { {{ side.runs }} }\n @case ('model-calls') {\n {{ 'nh-assistant.admin.evaluation.cost.average-p95' | translate: { average: (side.averageModelCalls | number: '1.0-2'), p95: side.p95ModelCalls, total: side.modelCalls } }}\n }\n @case ('tokens') {\n {{ 'nh-assistant.admin.evaluation.cost.average-p95' | translate: { average: (side.averageTokens | number: '1.0-0'), p95: side.p95Tokens, total: side.tokens } }}\n }\n @case ('tool-calls') {\n {{ 'nh-assistant.admin.evaluation.cost.average-p95' | translate: { average: (side.averageToolCalls | number: '1.0-2'), p95: side.p95ToolCalls, total: side.toolCalls } }}\n }\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n </section>\n\n @if (showRouting()) {\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-routing-title'\">\n <h4 [id]=\"id + '-routing-title'\">{{ 'nh-assistant.admin.evaluation.routing-title' | translate }}</h4>\n <div class=\"table-container\">\n <table class=\"summary-table\" [attr.aria-labelledby]=\"id + '-routing-title'\">\n <thead>\n <tr>\n <th scope=\"col\">{{ 'nh-assistant.admin.evaluation.columns.live-skill' | translate }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.evaluation.columns.variant-skill' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.evaluation.columns.runs' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of report.routing; track $index) {\n <tr>\n <td [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.live-skill' | translate\">{{ row.liveSkill ?? ('nh-assistant.admin.evaluation.no-skill' | translate) }}</td>\n <td [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.variant-skill' | translate\">{{ row.variantSkill ?? ('nh-assistant.admin.evaluation.no-skill' | translate) }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.evaluation.columns.runs' | translate\">{{ row.runs }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </section>\n }\n\n @if (report.differences.length > 0) {\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-differences-title'\">\n <h4 [id]=\"id + '-differences-title'\">{{ 'nh-assistant.admin.evaluation.differences-title' | translate }}</h4>\n <ul class=\"cards\">\n @for (difference of report.differences; track difference.liveRunId + difference.variantRunId + $index) {\n <li class=\"card\" [attr.data-difference]=\"difference.kind\">\n <div class=\"card-header\">\n <span class=\"mono\">{{ difference.toolId }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.evaluation.kind.' + difference.kind | translate }}</span>\n @if (difference.liveStatus; as status) {\n <span class=\"badge\">{{ 'nh-assistant.admin.evaluation.live-status' | translate: { status } }}</span>\n }\n @if (difference.replayed) {\n <span class=\"badge\">{{ 'nh-assistant.admin.evaluation.replayed' | translate }}</span>\n }\n </div>\n @if (canOpenThreads) {\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"openThread(difference.liveConversationId)\">\n {{ 'nh-assistant.admin.evaluation.open-live' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"openThread(difference.variantConversationId)\">\n {{ 'nh-assistant.admin.evaluation.open-variant' | translate }}\n </button>\n </div>\n }\n </li>\n }\n </ul>\n </section>\n }\n }\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-replay-title'\">\n <h4 [id]=\"id + '-replay-title'\">{{ 'nh-assistant.admin.evaluation.replay-title' | translate }}</h4>\n <p class=\"muted\" [id]=\"id + '-replay-hint'\">{{ 'nh-assistant.admin.evaluation.replay-hint' | translate: { max: maxReplayRuns } }}</p>\n <div class=\"inline\">\n <div class=\"field\">\n <label [for]=\"id + '-replay-runs'\">{{ 'nh-assistant.admin.evaluation.replay-runs' | translate }}</label>\n <input\n [id]=\"id + '-replay-runs'\"\n type=\"number\"\n min=\"1\"\n [max]=\"maxReplayRuns\"\n [value]=\"replayRuns()\"\n [attr.aria-describedby]=\"id + '-replay-hint'\"\n (change)=\"onReplayRuns($event)\" />\n </div>\n <button class=\"secondary\" type=\"button\" [disabled]=\"replaying() || replayRunning() || !variant()\" (click)=\"replay()\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.evaluation.replay' | translate }}\n </button>\n </div>\n @if (replayError(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ replayErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n @if (replays().length > 0) {\n <ul class=\"cards\" data-replays>\n @for (item of replays(); track item.id) {\n <li class=\"card\" [attr.data-replay]=\"item.status\">\n <div class=\"card-header\">\n <strong>{{ item.createdAt | date: 'short' }}</strong>\n <span class=\"badge\">{{ 'nh-assistant.admin.evaluation.replay-status.' + item.status | translate }}</span>\n </div>\n <p class=\"muted\">\n {{ 'nh-assistant.admin.evaluation.replay-progress' | translate: { replayed: item.runsReplayed, skipped: item.runsSkipped, max: item.maxRuns } }}\n </p>\n @if (item.stopReason; as code) {\n <p class=\"muted\">{{ ['nh-assistant.errors.' + code] | nhAssistantTranslate: code }}</p>\n }\n </li>\n }\n </ul>\n }\n </section>\n</section>\n","import { DatePipe, DOCUMENT, PercentPipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, signal, untracked } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n AgentFeedbackCategoryCount,\n AgentFeedbackItem,\n AgentFeedbackSummaryRow,\n AgentProposalFeedbackCategory,\n AgentProposalFeedbackGroup,\n NH_ASSISTANT_FEEDBACK_CATEGORIES,\n StaleKind,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\n/** Periods the report offers, in days before now. */\nexport type NhAssistantFeedbackPeriod = 7 | 30 | 90;\n\n/** A summary row with its most frequent feedback categories and why open proposals closed. */\ninterface NhAssistantFeedbackSummaryView extends AgentFeedbackSummaryRow {\n topCategories: AgentFeedbackCategoryCount[];\n /** Open proposals closed before a decision, per kind, most frequent first. */\n invalidatedKinds: { kind: StaleKind; count: number; reasons: string }[];\n}\n\nconst dayMs = 24 * 60 * 60 * 1000;\nconst topCategoryCount = 3;\n\nlet nextId = 0;\n\n/**\n * What people said when they rejected an agent's proposals, for the agent's administrators: per\n * tool and agent version the decisions, the rejection rate, the share of rejections with feedback,\n * the number of different people and the most frequent categories, followed by the feedback itself\n * and a JSON Lines export. Comparing agent versions shows whether a change to the prompt, tools or\n * policy helped. The server requires the assistant admin policy and reports only the caller's scopes.\n */\n@Component({\n selector: 'nh-assistant-agent-feedback-report',\n standalone: true,\n imports: [DatePipe, PercentPipe, TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-feedback-report.component.html',\n styleUrls: ['../nh-assistant-admin-shared.scss', './nh-assistant-agent-feedback-report.component.scss']\n})\nexport class NhAssistantAgentFeedbackReportComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly document = inject(DOCUMENT);\n private summarySubscription?: Subscription;\n private listSubscription?: Subscription;\n\n readonly agentId = input.required<string>();\n /** Feedback per page; the server allows at most 100. */\n readonly itemsPerPage = input(20);\n\n readonly id = `nh-assistant-agent-feedback-${nextId++}`;\n readonly periods: readonly NhAssistantFeedbackPeriod[] = [7, 30, 90];\n readonly categories = NH_ASSISTANT_FEEDBACK_CATEGORIES;\n\n readonly period = signal<NhAssistantFeedbackPeriod>(30);\n readonly toolId = signal('');\n readonly category = signal<AgentProposalFeedbackCategory | ''>('');\n readonly page = signal(1);\n\n readonly summaryLoading = signal(true);\n readonly summaryError = signal<NhAssistantError | null>(null);\n readonly summaryErrorKeys = computed(() => nhAssistantErrorKeys(this.summaryError()));\n readonly rows = signal<AgentFeedbackSummaryRow[]>([]);\n\n readonly listLoading = signal(true);\n readonly listError = signal<NhAssistantError | null>(null);\n readonly listErrorKeys = computed(() => nhAssistantErrorKeys(this.listError()));\n readonly items = signal<AgentFeedbackItem[]>([]);\n readonly total = signal(0);\n readonly pages = computed(() => Math.max(1, Math.ceil(this.total() / this.itemsPerPage())));\n\n readonly exporting = signal(false);\n readonly exportError = signal<NhAssistantError | null>(null);\n readonly exportErrorKeys = computed(() => nhAssistantErrorKeys(this.exportError()));\n readonly canExport = computed(() => !this.exporting() && !this.listLoading() && this.listError() === null && this.total() > 0);\n\n /** Tools with proposals in the period, plus the chosen tool when the period has none of it. */\n readonly tools = computed(() => {\n const tools = new Set(this.rows().map(row => row.toolId));\n if (this.toolId()) {\n tools.add(this.toolId());\n }\n return [...tools].sort();\n });\n readonly visibleRows = computed<NhAssistantFeedbackSummaryView[]>(() => this.rows()\n .filter(row => !this.toolId() || row.toolId === this.toolId())\n .map(row => ({\n ...row,\n topCategories: [...row.categories].sort((left, right) => right.count - left.count).slice(0, topCategoryCount),\n invalidatedKinds: invalidatedKinds(row)\n })));\n readonly filtered = computed(() => this.toolId() !== '' || this.category() !== '');\n\n /** The period the last load asked for, so the list, summary and export agree. */\n private range = periodRange(30);\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.summarySubscription?.unsubscribe();\n this.listSubscription?.unsubscribe();\n });\n effect(() => {\n this.agentId();\n untracked(() => {\n this.toolId.set('');\n this.category.set('');\n this.load();\n });\n });\n }\n\n /** Reloads the summary and the first page of feedback for the chosen period. */\n load(): void {\n this.range = periodRange(this.period());\n this.page.set(1);\n this.loadSummary();\n this.loadList();\n }\n\n onPeriod(event: Event): void {\n this.period.set(Number((event.target as HTMLSelectElement).value) as NhAssistantFeedbackPeriod);\n this.load();\n }\n\n onTool(event: Event): void {\n this.toolId.set((event.target as HTMLSelectElement).value);\n this.page.set(1);\n this.loadList();\n }\n\n onCategory(event: Event): void {\n this.category.set((event.target as HTMLSelectElement).value as AgentProposalFeedbackCategory | '');\n this.page.set(1);\n this.loadList();\n }\n\n goTo(page: number): void {\n this.page.set(Math.min(Math.max(1, page), this.pages()));\n this.loadList();\n }\n\n loadSummary(): void {\n this.summaryLoading.set(true);\n this.summaryError.set(null);\n this.summarySubscription?.unsubscribe();\n this.summarySubscription = this.admin.getAgentFeedbackSummary(this.agentId(), this.range).subscribe({\n next: summary => {\n this.rows.set(summary.rows);\n this.summaryLoading.set(false);\n },\n error: (failure: unknown) => {\n this.rows.set([]);\n this.summaryLoading.set(false);\n this.summaryError.set(toNhAssistantError(failure));\n }\n });\n }\n\n loadList(): void {\n this.listLoading.set(true);\n this.listError.set(null);\n this.exportError.set(null);\n this.listSubscription?.unsubscribe();\n this.listSubscription = this.admin\n .getAgentFeedback(this.agentId(), {\n ...this.range,\n toolId: this.toolId() || undefined,\n category: this.category() || undefined,\n page: this.page(),\n itemsPerPage: this.itemsPerPage()\n })\n .subscribe({\n next: list => {\n this.items.set(list.items);\n this.total.set(list.total);\n this.listLoading.set(false);\n },\n error: (failure: unknown) => {\n this.items.set([]);\n this.total.set(0);\n this.listLoading.set(false);\n this.listError.set(toNhAssistantError(failure));\n }\n });\n }\n\n /** Downloads the feedback of the period and filters as a JSON Lines file. */\n async export(): Promise<void> {\n if (!this.canExport()) {\n return;\n }\n\n this.exporting.set(true);\n this.exportError.set(null);\n try {\n const blob = await this.admin.exportAgentFeedback(this.agentId(), {\n ...this.range,\n toolId: this.toolId() || undefined,\n category: this.category() || undefined\n });\n const url = URL.createObjectURL(blob);\n const link = this.document.createElement('a');\n link.href = url;\n link.download = `agent-feedback-${this.agentId()}.jsonl`;\n link.click();\n URL.revokeObjectURL(url);\n } catch (failure) {\n this.exportError.set(toNhAssistantError(failure));\n } finally {\n this.exporting.set(false);\n }\n }\n\n /** Badge color of a feedback group: wrong and not allowed are failures, not now is a warning. */\n groupClass(group: AgentProposalFeedbackGroup): string {\n switch (group) {\n case 'wrong':\n case 'not-allowed':\n return 'danger';\n case 'right-but-not-now':\n return 'warning';\n default:\n return '';\n }\n }\n}\n\nfunction periodRange(days: number): { from: string; to: string } {\n const to = Date.now();\n return { from: new Date(to - days * dayMs).toISOString(), to: new Date(to).toISOString() };\n}\n\n/**\n * The open proposals of a row that closed before a decision, per kind, with their reason codes for\n * the tooltip. Proposals that closed after their approval are part of the approved count.\n */\nfunction invalidatedKinds(row: AgentFeedbackSummaryRow): { kind: StaleKind; count: number; reasons: string }[] {\n const kinds = new Map<StaleKind, { count: number; reasons: string[] }>();\n for (const item of row.invalidations ?? []) {\n if (item.afterApproval) {\n continue;\n }\n\n const entry = kinds.get(item.kind) ?? { count: 0, reasons: [] };\n entry.count += item.count;\n entry.reasons.push(`${item.reasonCode} (${item.count})`);\n kinds.set(item.kind, entry);\n }\n\n return [...kinds.entries()]\n .map(([kind, entry]) => ({ kind, count: entry.count, reasons: entry.reasons.join(', ') }))\n .sort((left, right) => right.count - left.count);\n}\n","<section class=\"section report\" [attr.aria-labelledby]=\"id + '-title'\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.feedback.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.feedback.description' | translate }}</p>\n <p class=\"muted export-hint\" [id]=\"id + '-export-hint'\">{{ 'nh-assistant.admin.feedback.export-hint' | translate }}</p>\n </div>\n <div class=\"header-actions\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"summaryLoading() || listLoading()\" (click)=\"load()\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.feedback.refresh' | translate }}\n </button>\n <button\n class=\"secondary\"\n type=\"button\"\n [disabled]=\"!canExport()\"\n [attr.aria-describedby]=\"id + '-export-hint'\"\n (click)=\"export()\">\n <nh-assistant-icon name=\"page\" />{{ (exporting() ? 'nh-assistant.admin.feedback.exporting' : 'nh-assistant.admin.feedback.export') | translate }}\n </button>\n </div>\n </header>\n\n <div class=\"filters\">\n <div class=\"field\">\n <label [for]=\"id + '-period'\">{{ 'nh-assistant.admin.feedback.period' | translate }}</label>\n <select [id]=\"id + '-period'\" (change)=\"onPeriod($event)\">\n @for (days of periods; track days) {\n <option [value]=\"days\" [selected]=\"period() === days\">{{ 'nh-assistant.admin.feedback.periods.last-' + days + '-days' | translate }}</option>\n }\n </select>\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-tool'\">{{ 'nh-assistant.admin.feedback.tool' | translate }}</label>\n <select [id]=\"id + '-tool'\" [disabled]=\"summaryLoading() && tools().length === 0\" (change)=\"onTool($event)\">\n <option value=\"\" [selected]=\"toolId() === ''\">{{ 'nh-assistant.admin.feedback.all-tools' | translate }}</option>\n @for (tool of tools(); track tool) {\n <option [value]=\"tool\" [selected]=\"toolId() === tool\">{{ tool }}</option>\n }\n </select>\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-category'\">{{ 'nh-assistant.admin.feedback.category' | translate }}</label>\n <select [id]=\"id + '-category'\" [attr.aria-describedby]=\"id + '-category-hint'\" (change)=\"onCategory($event)\">\n <option value=\"\" [selected]=\"category() === ''\">{{ 'nh-assistant.admin.feedback.all-categories' | translate }}</option>\n @for (option of categories; track option) {\n <option [value]=\"option\" [selected]=\"category() === option\">{{ 'nh-assistant.proposal-feedback.categories.' + option | translate }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-category-hint'\"><span>{{ 'nh-assistant.admin.feedback.category-hint' | translate }}</span></p>\n </div>\n </div>\n\n @if (exportError(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ exportErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-summary-title'\" [attr.aria-busy]=\"summaryLoading()\">\n <h4 [id]=\"id + '-summary-title'\">{{ 'nh-assistant.admin.feedback.summary-title' | translate }}</h4>\n @if (summaryLoading() && rows().length === 0) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (summaryError(); as failure) {\n <div class=\"state\" role=\"alert\">\n <p>{{ summaryErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"loadSummary()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (visibleRows().length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.feedback.summary-empty' | translate }}</p>\n } @else {\n <div class=\"table-container\">\n <table class=\"summary-table\" [attr.aria-labelledby]=\"id + '-summary-title'\">\n <thead>\n <tr>\n <th scope=\"col\">{{ 'nh-assistant.admin.feedback.columns.tool' | translate }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.feedback.columns.version' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.approved' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.rejected' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.expired' | translate }}</th>\n <th scope=\"col\" class=\"number\" [attr.title]=\"'nh-assistant.admin.feedback.invalidated-hint' | translate\">\n {{ 'nh-assistant.admin.feedback.columns.invalidated' | translate }}\n </th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.rejection-rate' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.with-feedback' | translate }}</th>\n <th scope=\"col\" class=\"number\">{{ 'nh-assistant.admin.feedback.columns.people' | translate }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.feedback.columns.categories' | translate }}</th>\n </tr>\n </thead>\n <tbody>\n @for (row of visibleRows(); track row.toolId + '|' + row.agentVersion) {\n <tr>\n <th scope=\"row\" class=\"tool\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.tool' | translate\">\n <span class=\"mono\">{{ row.toolId }}</span>\n </th>\n <td [attr.data-label]=\"'nh-assistant.admin.feedback.columns.version' | translate\">\n @if (row.agentVersion === null) {\n {{ 'nh-assistant.admin.feedback.consultations' | translate }}\n } @else {\n {{ 'nh-assistant.admin.feedback.version' | translate: { version: row.agentVersion } }}\n }\n </td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.approved' | translate\">{{ row.approved }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.rejected' | translate\">{{ row.rejected }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.expired' | translate\">{{ row.expired }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.invalidated' | translate\">\n {{ row.invalidated ?? 0 }}\n @if (row.invalidatedKinds.length > 0) {\n <ul class=\"badges\">\n @for (item of row.invalidatedKinds; track item.kind) {\n <li>\n <span class=\"badge\" [attr.title]=\"item.reasons\">\n {{ 'nh-assistant.approval.stale-kind.' + item.kind | translate }}\n <span class=\"count\">{{ item.count }}</span>\n </span>\n </li>\n }\n </ul>\n }\n </td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.rejection-rate' | translate\">\n @if (row.rejectionRate === null) {\n <span class=\"muted\">{{ 'nh-assistant.admin.feedback.no-decisions' | translate }}</span>\n } @else {\n {{ row.rejectionRate | percent: '1.0-0' }}\n }\n </td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.with-feedback' | translate\">{{ row.rejectedWithFeedback }}</td>\n <td class=\"number\" [attr.data-label]=\"'nh-assistant.admin.feedback.columns.people' | translate\">{{ row.feedbackAuthors }}</td>\n <td [attr.data-label]=\"'nh-assistant.admin.feedback.columns.categories' | translate\">\n @if (row.topCategories.length === 0) {\n <span class=\"muted\">{{ 'nh-assistant.admin.feedback.no-categories' | translate }}</span>\n } @else {\n <ul class=\"badges\">\n @for (item of row.topCategories; track item.category) {\n <li>\n <span [class]=\"'badge ' + groupClass(item.group)\" [attr.title]=\"'nh-assistant.proposal-feedback.groups.' + item.group | translate\">\n {{ 'nh-assistant.proposal-feedback.categories.' + item.category | nhAssistantTranslate: item.category }}\n <span class=\"count\">{{ item.count }}</span>\n </span>\n </li>\n }\n </ul>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </section>\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-list-title'\" [attr.aria-busy]=\"listLoading()\">\n <div class=\"list-header\">\n <h4 [id]=\"id + '-list-title'\">{{ 'nh-assistant.admin.feedback.list-title' | translate }}</h4>\n @if (!listLoading() && listError() === null) {\n <span class=\"muted\">{{ 'nh-assistant.admin.feedback.list-count' | translate: { count: total() } }}</span>\n }\n </div>\n @if (listLoading() && items().length === 0) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (listError(); as failure) {\n <div class=\"state\" role=\"alert\">\n <p>{{ listErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"loadList()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (items().length === 0) {\n <p class=\"state\">{{ (filtered() ? 'nh-assistant.admin.feedback.list-empty-filtered' : 'nh-assistant.admin.feedback.list-empty') | translate }}</p>\n } @else {\n <ul class=\"cards\">\n @for (item of items(); track item.id) {\n <li class=\"card\">\n <div class=\"card-header\">\n <strong>{{ item.subjectDisplayName ?? item.subjectId }}</strong>\n <span class=\"muted\">{{ item.presentation?.toolDisplayName ?? item.toolId }}</span>\n @if (item.agentVersion !== null) {\n <span class=\"badge\">{{ 'nh-assistant.admin.feedback.version' | translate: { version: item.agentVersion } }}</span>\n }\n <span [class]=\"'badge ' + groupClass(item.group)\" [attr.title]=\"'nh-assistant.proposal-feedback.groups.' + item.group | translate\">\n {{ 'nh-assistant.proposal-feedback.categories.' + item.category | nhAssistantTranslate: item.category }}\n </span>\n @if (item.bulk) {\n <span class=\"badge\" [attr.title]=\"'nh-assistant.admin.feedback.bulk-hint' | translate\">{{ 'nh-assistant.admin.feedback.bulk' | translate }}</span>\n }\n </div>\n @if (item.text) {\n <blockquote class=\"feedback-text\">{{ item.text }}</blockquote>\n } @else {\n <p class=\"muted\">{{ 'nh-assistant.admin.feedback.no-text' | translate }}</p>\n }\n <p class=\"proposal\">\n <span class=\"proposal-label\">{{ 'nh-assistant.admin.feedback.proposal' | translate }}</span>\n {{ item.presentation?.summary ?? item.summary }}\n </p>\n <div class=\"meta\">\n <span>{{ 'nh-assistant.agent-runs.proposal.status.' + item.approvalStatus | nhAssistantTranslate: item.approvalStatus }}</span>\n <span>{{ 'nh-assistant.admin.feedback.author' | translate: { actor: item.authorDisplayName || item.authorActorId } }}</span>\n <span>{{ item.updatedAt | date: 'short' }}</span>\n </div>\n </li>\n }\n </ul>\n @if (pages() > 1) {\n <nav class=\"pager\" [attr.aria-label]=\"'nh-assistant.admin.feedback.pages' | translate\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"page() <= 1 || listLoading()\" (click)=\"goTo(page() - 1)\">\n {{ 'nh-assistant.admin.feedback.previous' | translate }}\n </button>\n <span class=\"muted\">{{ 'nh-assistant.admin.feedback.page' | translate: { page: page(), pages: pages() } }}</span>\n <button class=\"secondary\" type=\"button\" [disabled]=\"page() >= pages() || listLoading()\" (click)=\"goTo(page() + 1)\">\n {{ 'nh-assistant.admin.feedback.next' | translate }}\n </button>\n </nav>\n }\n }\n </section>\n</section>\n","import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n afterNextRender,\n computed,\n inject,\n signal,\n viewChild\n} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Observable, Subscription, forkJoin } from 'rxjs';\nimport {\n AdminAgent,\n AgentSkillState,\n AgentState,\n McpServer,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n NhAssistantStore,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError,\n SetAgentStateRequest,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAdminAgentEditorComponent } from './nh-assistant-admin-agent-editor.component';\nimport { NhAssistantAgentEvaluationComponent } from './nh-assistant-agent-evaluation.component';\nimport { NhAssistantAgentFeedbackReportComponent } from './nh-assistant-agent-feedback-report.component';\n\nlet nextId = 0;\n\ntype AgentStateAction = SetAgentStateRequest['state'];\n\n/** The longest reason the server stores with a state change. */\nconst maxStateReason = 500;\n\n/**\n * Agent administration: code agents (override, reset) and agents created here (edit, delete),\n * and for every agent its run state with pause, stop and resume, each with an optional reason.\n * Editing opens `nh-assistant-admin-agent-editor`; the feedback action opens\n * `nh-assistant-agent-feedback-report` for the agent, and the evaluation action of an agent with\n * shadow variants opens `nh-assistant-agent-evaluation`.\n */\n@Component({\n selector: 'nh-assistant-admin-agents',\n standalone: true,\n imports: [\n DatePipe,\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantAdminAgentEditorComponent,\n NhAssistantAgentEvaluationComponent,\n NhAssistantAgentFeedbackReportComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-agents.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminAgentsComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly store = inject(NhAssistantStore);\n private readonly injector = inject(Injector);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly backButton = viewChild<ElementRef<HTMLButtonElement>>('back');\n private readonly reasonInput = viewChild<ElementRef<HTMLInputElement>>('reasonInput');\n private subscription?: Subscription;\n private actionSubscription?: Subscription;\n\n readonly id = `nh-assistant-admin-agents-${nextId++}`;\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly agents = signal<AdminAgent[]>([]);\n readonly tools = signal<ToolCatalogEntry[]>([]);\n readonly servers = signal<McpServer[]>([]);\n /** `undefined`: list; `null`: new agent; an agent: editing that agent. */\n readonly editing = signal<AdminAgent | null | undefined>(undefined);\n /** The agent whose feedback report is shown instead of the list. */\n readonly reporting = signal<AdminAgent | null>(null);\n /** The agent whose comparison with its shadow variants is shown instead of the list. */\n readonly evaluating = signal<AdminAgent | null>(null);\n readonly confirming = signal<{ agentId: string; action: 'delete' | 'reset' } | null>(null);\n readonly busyAgentId = signal<string | null>(null);\n /** The state change whose reason is being entered, of the agent or one of its skills. */\n readonly changingState = signal<{ agentId: string; skillId?: string; state: AgentStateAction } | null>(null);\n readonly stateReason = signal('');\n readonly maxReason = maxStateReason;\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.actionSubscription?.unsubscribe();\n });\n this.load();\n }\n\n load(): void {\n this.loading.set(true);\n this.loadFailed.set(false);\n this.subscription?.unsubscribe();\n this.subscription = forkJoin([this.admin.getAgents(), this.admin.getTools(), this.admin.getMcpServers()]).subscribe({\n next: ([agents, tools, servers]) => {\n this.agents.set(agents);\n this.tools.set(tools);\n this.servers.set(servers);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n create(): void {\n this.error.set(null);\n this.editing.set(null);\n }\n\n edit(agent: AdminAgent): void {\n this.error.set(null);\n this.editing.set(agent);\n }\n\n /** Shows what people said when they rejected the agent's proposals. */\n openReport(agent: AdminAgent): void {\n this.error.set(null);\n this.confirming.set(null);\n this.reporting.set(agent);\n afterNextRender(() => this.backButton()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /** The shadow variants of an agent, by id. */\n variantsOf(agent: AdminAgent): string[] {\n return this.agents()\n .filter(item => item.shadowOf === agent.id)\n .map(item => item.id);\n }\n\n /** Compares the agent with its shadow variants. */\n openEvaluation(agent: AdminAgent): void {\n this.error.set(null);\n this.confirming.set(null);\n this.evaluating.set(agent);\n afterNextRender(() => this.backButton()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /** Returns to the list and to the evaluation action of the agent whose comparison was open. */\n closeEvaluation(): void {\n const agentId = this.evaluating()?.id;\n this.evaluating.set(null);\n if (agentId !== undefined) {\n afterNextRender(() => {\n const action = Array.from(this.host.nativeElement.querySelectorAll<HTMLButtonElement>('[data-evaluation-agent]'))\n .find(item => item.dataset['evaluationAgent'] === agentId);\n action?.focus();\n }, { injector: this.injector });\n }\n }\n\n /** Returns to the list and to the feedback action of the agent whose report was open. */\n closeReport(): void {\n const agentId = this.reporting()?.id;\n this.reporting.set(null);\n if (agentId !== undefined) {\n afterNextRender(() => {\n const host = this.host.nativeElement;\n const action = Array.from(host.querySelectorAll<HTMLButtonElement>('[data-feedback-agent]'))\n .find(item => item.dataset['feedbackAgent'] === agentId);\n action?.focus();\n }, { injector: this.injector });\n }\n }\n\n onSaved(agent: AdminAgent): void {\n this.agents.update(agents => agents.some(item => item.id === agent.id)\n ? agents.map(item => item.id === agent.id ? agent : item)\n : [...agents, agent]);\n this.editing.set(undefined);\n this.refreshChat();\n }\n\n /** The state changes the agent allows: none for an agent that is disabled in code. */\n stateActions(agent: AdminAgent): AgentStateAction[] {\n switch (agent.runState) {\n case 'active':\n return ['paused', 'stopped'];\n case 'paused':\n return ['active', 'stopped'];\n case 'stopped':\n return ['active'];\n default:\n return [];\n }\n }\n\n /** The state changes a skill allows. */\n skillActions(skill: AgentSkillState): AgentStateAction[] {\n switch (skill.runState) {\n case 'active':\n return ['paused', 'stopped'];\n case 'paused':\n return ['active', 'stopped'];\n default:\n return ['active'];\n }\n }\n\n /** Opens the reason form of a state change of the agent or, with a skill, of that skill. */\n askState(agent: AdminAgent, state: AgentStateAction, skill?: AgentSkillState): void {\n this.confirming.set(null);\n this.error.set(null);\n this.stateReason.set('');\n this.changingState.set({ agentId: agent.id, skillId: skill?.skillId, state });\n afterNextRender(() => this.reasonInput()?.nativeElement.focus(), { injector: this.injector });\n }\n\n isChangingState(agentId: string, state: AgentStateAction, skillId?: string): boolean {\n const change = this.changingState();\n return change?.agentId === agentId && change.state === state && change.skillId === skillId;\n }\n\n applyState(agent: AdminAgent): void {\n const change = this.changingState();\n if (change?.agentId !== agent.id) {\n return;\n }\n\n const reason = this.stateReason().trim();\n const request = { state: change.state, reason: reason.length > 0 ? reason : null };\n if (change.skillId !== undefined) {\n this.run(\n agent.id,\n this.admin.setSkillState(agent.id, change.skillId, request),\n skill => this.replace(withSkill(agent, skill)));\n return;\n }\n\n this.run(\n agent.id,\n this.admin.setAgentState(agent.id, request),\n state => this.replace(withState(agent, state)));\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n\n confirm(agentId: string, action: 'delete' | 'reset'): void {\n this.changingState.set(null);\n this.confirming.set({ agentId, action });\n }\n\n isConfirming(agentId: string, action: 'delete' | 'reset'): boolean {\n const confirming = this.confirming();\n return confirming?.agentId === agentId && confirming.action === action;\n }\n\n reset(agent: AdminAgent): void {\n this.run(agent.id, this.admin.resetAgent(agent.id), updated => this.replace(updated));\n }\n\n remove(agent: AdminAgent): void {\n this.run<void>(agent.id, this.admin.deleteAgent(agent.id), () => {\n this.agents.update(agents => agents.filter(item => item.id !== agent.id));\n });\n }\n\n private run<T>(agentId: string, request: Observable<T>, done: (result: T) => void): void {\n this.busyAgentId.set(agentId);\n this.confirming.set(null);\n this.changingState.set(null);\n this.error.set(null);\n this.actionSubscription?.unsubscribe();\n this.actionSubscription = request.subscribe({\n next: result => done(result),\n complete: () => {\n this.busyAgentId.set(null);\n this.refreshChat();\n },\n error: (error: unknown) => {\n this.busyAgentId.set(null);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n private replace(agent: AdminAgent): void {\n this.agents.update(agents => agents.map(item => item.id === agent.id ? agent : item));\n }\n\n /** Agent changes affect the agent picker of the panel. */\n private refreshChat(): void {\n void this.store.reloadStatus();\n }\n}\n\nfunction withState(agent: AdminAgent, state: AgentState): AdminAgent {\n return {\n ...agent,\n isEnabled: state.runState !== 'stopped',\n runState: state.runState,\n stateChangedAt: state.changedAt,\n stateChangedBy: state.changedBy,\n stateReason: state.reason,\n waitingInputs: state.waitingInputs,\n skills: state.skills ?? agent.skills\n };\n}\n\nfunction withSkill(agent: AdminAgent, skill: AgentSkillState): AdminAgent {\n return {\n ...agent,\n skills: (agent.skills ?? []).map(item => item.skillId === skill.skillId ? skill : item)\n };\n}\n","@if (editing() !== undefined) {\n <nh-assistant-admin-agent-editor\n [agent]=\"editing() ?? null\"\n [tools]=\"tools()\"\n [servers]=\"servers()\"\n (saved)=\"onSaved($event)\"\n (cancelled)=\"editing.set(undefined)\" />\n} @else if (reporting(); as agent) {\n <div class=\"stack\">\n <div>\n <button #back class=\"secondary\" type=\"button\" (click)=\"closeReport()\">\n {{ 'nh-assistant.admin.feedback.back' | translate }}\n </button>\n </div>\n <p class=\"muted\">{{ 'nh-assistant.admin.feedback.agent' | translate: { name: agent.displayName, id: agent.id } }}</p>\n <nh-assistant-agent-feedback-report [agentId]=\"agent.id\" />\n </div>\n} @else if (evaluating(); as agent) {\n <div class=\"stack\">\n <div>\n <button #back class=\"secondary\" type=\"button\" (click)=\"closeEvaluation()\">\n {{ 'nh-assistant.admin.evaluation.back' | translate }}\n </button>\n </div>\n <p class=\"muted\">{{ 'nh-assistant.admin.feedback.agent' | translate: { name: agent.displayName, id: agent.id } }}</p>\n <nh-assistant-agent-evaluation [agentId]=\"agent.id\" [variants]=\"variantsOf(agent)\" />\n </div>\n} @else {\n <section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.agents.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.agents.description' | translate }}</p>\n </div>\n <button class=\"primary\" type=\"button\" [disabled]=\"loading() || loadFailed()\" (click)=\"create()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.agents.new' | translate }}\n </button>\n </header>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n @if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (loadFailed()) {\n <div class=\"state\" role=\"alert\">\n <p>{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (agents().length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.agents.empty' | translate }}</p>\n } @else {\n <ul class=\"cards\">\n @for (agent of agents(); track agent.id) {\n <li class=\"card\" [class.inactive]=\"agent.runState !== 'active'\" [attr.aria-busy]=\"busyAgentId() === agent.id\">\n <div class=\"card-header\">\n <strong>{{ agent.displayName }}</strong>\n <span class=\"mono muted\">{{ agent.id }}</span>\n <span class=\"badge\">{{ (agent.source === 'code' ? 'nh-assistant.admin.agents.source-code' : 'nh-assistant.admin.agents.source-admin') | translate }}</span>\n @if (agent.isOverridden) {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.agents.overridden' | translate }}</span>\n }\n <span\n class=\"badge\"\n [class.success]=\"agent.runState === 'active'\"\n [class.warning]=\"agent.runState === 'paused'\"\n [class.danger]=\"agent.runState === 'stopped'\">{{ 'nh-assistant.admin.agents.state.' + agent.runState | translate }}</span>\n </div>\n @if (agent.description) {\n <p class=\"muted\">{{ agent.description }}</p>\n }\n @if (agent.runState === 'configured-off') {\n <p class=\"muted\">{{ 'nh-assistant.admin.agents.state.configured-off-hint' | translate }}</p>\n } @else if (agent.runState !== 'active') {\n <p class=\"muted\">\n @if (agent.stateChangedAt) {\n {{ 'nh-assistant.admin.agents.state.changed' | translate: { user: agent.stateChangedBy, date: (agent.stateChangedAt | date: 'medium') } }}\n }\n @if (agent.stateReason) {\n {{ 'nh-assistant.admin.agents.state.reason' | translate: { reason: agent.stateReason } }}\n }\n </p>\n @if (agent.runState === 'paused') {\n <p class=\"muted\">{{ 'nh-assistant.admin.agents.state.waiting' | translate: { count: agent.waitingInputs } }}</p>\n }\n }\n <div class=\"meta\">\n <span>{{ 'nh-assistant.admin.agents.autonomy.' + agent.autonomy | translate }}</span>\n <span>{{ 'nh-assistant.admin.agents.tool-count' | translate: { count: agent.toolSelectors.length } }}</span>\n <span>{{ 'nh-assistant.admin.agents.server-count' | translate: { count: agent.mcpServerIds.length } }}</span>\n <span>{{ 'nh-assistant.admin.agents.version' | translate: { version: agent.version } }}</span>\n @if (agent.requiredPolicy) {\n <span class=\"mono\">{{ agent.requiredPolicy }}</span>\n }\n </div>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"busyAgentId() !== null\" (click)=\"edit(agent)\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n @for (action of stateActions(agent); track action) {\n <button\n type=\"button\"\n [class.secondary]=\"action !== 'stopped'\"\n [class.danger]=\"action === 'stopped'\"\n [attr.aria-expanded]=\"isChangingState(agent.id, action)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askState(agent, action)\">\n {{ 'nh-assistant.admin.agents.state.action.' + action | translate }}\n </button>\n }\n <button class=\"secondary\" type=\"button\" [attr.data-feedback-agent]=\"agent.id\" (click)=\"openReport(agent)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.agents.feedback' | translate }}\n </button>\n @if (variantsOf(agent).length > 0) {\n <button class=\"secondary\" type=\"button\" [attr.data-evaluation-agent]=\"agent.id\" (click)=\"openEvaluation(agent)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.agents.evaluation' | translate }}\n </button>\n }\n @if (agent.source === 'code' && agent.isOverridden) {\n @if (isConfirming(agent.id, 'reset')) {\n <span class=\"muted\">{{ 'nh-assistant.admin.agents.reset-keeps-state' | translate }}</span>\n <button class=\"danger\" type=\"button\" (click)=\"reset(agent)\">{{ 'nh-assistant.admin.agents.confirm-reset' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.keep' | translate }}</button>\n } @else {\n <button class=\"secondary\" type=\"button\" [disabled]=\"busyAgentId() !== null\" (click)=\"confirm(agent.id, 'reset')\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.agents.reset' | translate }}\n </button>\n }\n }\n @if (agent.source === 'admin') {\n @if (isConfirming(agent.id, 'delete')) {\n <button class=\"danger\" type=\"button\" (click)=\"remove(agent)\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.keep' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" [disabled]=\"busyAgentId() !== null\" (click)=\"confirm(agent.id, 'delete')\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.delete' | translate }}\n </button>\n }\n }\n </div>\n @if (agent.skills?.length) {\n <ul class=\"skills\" [attr.aria-label]=\"'nh-assistant.admin.agents.skills.title' | translate\">\n @for (skill of agent.skills; track skill.skillId) {\n <li class=\"skill\" [attr.data-skill]=\"skill.skillId\">\n <div class=\"card-header\">\n <span class=\"mono\">{{ skill.skillId }}</span>\n <span\n class=\"badge\"\n [class.success]=\"skill.runState === 'active'\"\n [class.warning]=\"skill.runState === 'paused'\"\n [class.danger]=\"skill.runState === 'stopped'\">{{ 'nh-assistant.admin.agents.state.' + skill.runState | translate }}</span>\n </div>\n <p class=\"muted\">{{ skill.description }}</p>\n <div class=\"meta\">\n <span>{{ 'nh-assistant.admin.agents.skills.usage' | translate: { calls: skill.toolCallsToday, tokens: skill.tokensToday } }}</span>\n @if (skill.dailyToolCalls !== null) {\n <span>{{ 'nh-assistant.admin.agents.skills.budget' | translate: { calls: skill.dailyToolCalls, tokens: skill.dailyTokens } }}</span>\n }\n @if (skill.runState === 'paused') {\n <span>{{ 'nh-assistant.admin.agents.state.waiting' | translate: { count: skill.waitingInputs } }}</span>\n }\n @if (skill.reason) {\n <span>{{ 'nh-assistant.admin.agents.state.reason' | translate: { reason: skill.reason } }}</span>\n }\n </div>\n @if (agent.runState !== 'configured-off') {\n <div class=\"card-actions\">\n @for (action of skillActions(skill); track action) {\n <button\n type=\"button\"\n [class.secondary]=\"action !== 'stopped'\"\n [class.danger]=\"action === 'stopped'\"\n [attr.aria-label]=\"('nh-assistant.admin.agents.state.action.' + action | translate) + ' ' + skill.skillId\"\n [attr.aria-expanded]=\"isChangingState(agent.id, action, skill.skillId)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askState(agent, action, skill)\">\n {{ 'nh-assistant.admin.agents.state.action.' + action | translate }}\n </button>\n }\n </div>\n }\n </li>\n }\n </ul>\n }\n @if (changingState(); as change) {\n @if (change.agentId === agent.id) {\n <form class=\"stack\" (submit)=\"$event.preventDefault(); applyState(agent)\">\n @if (change.skillId) {\n <p class=\"muted\">{{ 'nh-assistant.admin.agents.skills.explain.' + change.state | translate: { skill: change.skillId } }}</p>\n } @else {\n <p class=\"muted\">{{ 'nh-assistant.admin.agents.state.explain.' + change.state | translate }}</p>\n }\n <div class=\"field\">\n <label [for]=\"id + '-' + agent.id + '-reason'\">{{ 'nh-assistant.admin.agents.state.reason-label' | translate }}</label>\n <input\n #reasonInput\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"id + '-' + agent.id + '-reason'\"\n [maxLength]=\"maxReason\"\n [value]=\"stateReason()\"\n (input)=\"stateReason.set(value($event))\" />\n </div>\n <div class=\"card-actions\">\n <button type=\"submit\" [class.primary]=\"change.state !== 'stopped'\" [class.danger]=\"change.state === 'stopped'\" [disabled]=\"busyAgentId() !== null\">\n {{ 'nh-assistant.admin.agents.state.confirm.' + change.state | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"changingState.set(null)\">{{ 'nh-assistant.admin.keep' | translate }}</button>\n </div>\n </form>\n }\n }\n </li>\n }\n </ul>\n }\n </section>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n untracked\n} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n McpAuthMode,\n McpServer,\n McpServerInput,\n ɵNH_ASSISTANT_DASH_CASE as NH_ASSISTANT_DASH_CASE,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\n/**\n * What happens to the stored secret on save. `keep` omits `secret`, `replace` sends the\n * new value and `clear` sends `\"\"`. The stored value is never shown.\n */\nexport type NhAssistantSecretAction = 'keep' | 'replace' | 'clear';\n\nlet nextId = 0;\n\n/** Creates or edits one MCP server with a write-only secret. */\n@Component({\n selector: 'nh-assistant-admin-mcp-server-editor',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-mcp-server-editor.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminMcpServerEditorComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n\n /** The server to edit, or null for a new server. */\n readonly server = input<McpServer | null>(null);\n readonly saved = output<McpServer>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-server-editor-${nextId++}`;\n readonly authModes: readonly McpAuthMode[] = ['none', 'bearer', 'api-key', 'forward-user-token'];\n\n readonly serverId = signal('');\n readonly displayName = signal('');\n readonly url = signal('');\n readonly authMode = signal<McpAuthMode>('none');\n readonly headerName = signal('');\n readonly requiredPolicy = signal('');\n readonly isEnabled = signal(true);\n readonly secretAction = signal<NhAssistantSecretAction>('keep');\n /** The new secret while typing. Never filled from the server. */\n readonly secret = signal('');\n readonly submitted = signal(false);\n readonly saving = signal(false);\n readonly error = signal<NhAssistantError | null>(null);\n\n readonly isNew = computed(() => this.server() === null);\n readonly hasSecret = computed(() => this.server()?.hasSecret === true);\n readonly usesSecret = computed(() => this.authMode() === 'bearer' || this.authMode() === 'api-key');\n readonly showSecretInput = computed(() => this.usesSecret() && (!this.hasSecret() || this.secretAction() === 'replace'));\n readonly idInvalid = computed(() => this.isNew() && (this.serverId().length > 40 || !NH_ASSISTANT_DASH_CASE.test(this.serverId())));\n readonly nameMissing = computed(() => this.displayName().trim().length === 0);\n readonly urlInvalid = computed(() => !isAllowedUrl(this.url().trim()));\n readonly valid = computed(() => !this.idInvalid() && !this.nameMissing() && !this.urlInvalid());\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n\n effect(() => {\n const server = this.server();\n untracked(() => this.reset(server));\n });\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement | HTMLSelectElement).value;\n }\n\n checked(event: Event): boolean {\n return (event.target as HTMLInputElement).checked;\n }\n\n setSecretAction(action: NhAssistantSecretAction): void {\n this.secretAction.set(action);\n this.secret.set('');\n }\n\n onSecretInput(event: Event): void {\n this.secret.set(this.value(event));\n if (!this.hasSecret()) {\n this.secretAction.set(this.secret().length > 0 ? 'replace' : 'keep');\n }\n }\n\n save(): void {\n this.submitted.set(true);\n if (!this.valid() || this.saving()) {\n return;\n }\n\n const authMode = this.authMode();\n const policy = this.requiredPolicy().trim();\n const header = this.headerName().trim();\n const input: McpServerInput = {\n id: this.isNew() ? this.serverId() : this.server()!.id,\n displayName: this.displayName().trim(),\n url: this.url().trim(),\n authMode,\n headerName: authMode === 'api-key' && header.length > 0 ? header : null,\n requiredPolicy: policy.length > 0 ? policy : null,\n isEnabled: this.isEnabled()\n };\n\n // Write-only secret: omitted keeps the stored value, \"\" clears it.\n const action = this.secretAction();\n if (!this.usesSecret() && this.hasSecret()) {\n input.secret = '';\n } else if (action === 'clear') {\n input.secret = '';\n } else if (action === 'replace' && this.secret().length > 0) {\n input.secret = this.secret();\n }\n\n const existing = this.server();\n const request = existing ? this.admin.updateMcpServer(existing.id, input) : this.admin.createMcpServer(input);\n\n this.saving.set(true);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = request.subscribe({\n next: server => {\n this.saving.set(false);\n this.secret.set('');\n this.saved.emit(server);\n },\n error: (error: unknown) => {\n this.saving.set(false);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n private reset(server: McpServer | null): void {\n this.serverId.set(server?.id ?? '');\n this.displayName.set(server?.displayName ?? '');\n this.url.set(server?.url ?? 'https://');\n this.authMode.set(server?.authMode ?? 'none');\n this.headerName.set(server?.headerName ?? '');\n this.requiredPolicy.set(server?.requiredPolicy ?? '');\n this.isEnabled.set(server?.isEnabled ?? true);\n this.secretAction.set('keep');\n this.secret.set('');\n this.submitted.set(false);\n this.error.set(null);\n }\n}\n\nfunction isAllowedUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === 'https:' || (url.protocol === 'http:' && url.hostname === 'localhost');\n } catch {\n return false;\n }\n}\n","<form class=\"section card\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"saving()\" autocomplete=\"off\" (submit)=\"$event.preventDefault(); save()\">\n <h3 [id]=\"id + '-title'\">\n @if (server(); as current) {\n {{ 'nh-assistant.admin.server-editor.edit-title' | translate: { name: current.displayName } }}\n } @else {\n {{ 'nh-assistant.admin.server-editor.new-title' | translate }}\n }\n </h3>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-id'\">{{ 'nh-assistant.admin.server-editor.id' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n [id]=\"id + '-id'\"\n [value]=\"serverId()\"\n [disabled]=\"!isNew()\"\n [attr.aria-describedby]=\"id + '-id-hint'\"\n [attr.aria-invalid]=\"submitted() && idInvalid() ? true : null\"\n (input)=\"serverId.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-id-hint'\">\n <span [class.error-text]=\"submitted() && idInvalid()\">\n {{ (submitted() && idInvalid() ? 'nh-assistant.admin.invalid-id' : 'nh-assistant.admin.server-editor.id-hint') | translate }}\n </span>\n </p>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-name'\">{{ 'nh-assistant.admin.server-editor.display-name' | translate }}</label>\n <input\n type=\"text\"\n [id]=\"id + '-name'\"\n [value]=\"displayName()\"\n [attr.aria-invalid]=\"submitted() && nameMissing() ? true : null\"\n [attr.aria-describedby]=\"id + '-name-hint'\"\n (input)=\"displayName.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-name-hint'\">\n @if (submitted() && nameMissing()) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.required' | translate }}</span>\n }\n </p>\n </div>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-url'\">{{ 'nh-assistant.admin.server-editor.url' | translate }}</label>\n <input\n type=\"url\"\n class=\"mono\"\n inputmode=\"url\"\n [id]=\"id + '-url'\"\n [value]=\"url()\"\n [attr.aria-describedby]=\"id + '-url-hint'\"\n [attr.aria-invalid]=\"submitted() && urlInvalid() ? true : null\"\n (input)=\"url.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-url-hint'\">\n <span [class.error-text]=\"submitted() && urlInvalid()\">\n {{ (submitted() && urlInvalid() ? 'nh-assistant.admin.server-editor.url-invalid' : 'nh-assistant.admin.server-editor.url-hint') | translate }}\n </span>\n </p>\n </div>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-auth'\">{{ 'nh-assistant.admin.server-editor.auth-mode' | translate }}</label>\n <select [id]=\"id + '-auth'\" (change)=\"authMode.set($any(value($event)))\">\n @for (mode of authModes; track mode) {\n <option [value]=\"mode\" [selected]=\"authMode() === mode\">{{ 'nh-assistant.admin.mcp.auth.' + mode | translate }}</option>\n }\n </select>\n </div>\n\n @if (authMode() === 'api-key') {\n <div class=\"field\">\n <label [for]=\"id + '-header'\">{{ 'nh-assistant.admin.server-editor.header-name' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n placeholder=\"X-Api-Key\"\n [id]=\"id + '-header'\"\n [value]=\"headerName()\"\n [attr.aria-describedby]=\"id + '-header-hint'\"\n (input)=\"headerName.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-header-hint'\">{{ 'nh-assistant.admin.server-editor.header-name-hint' | translate }}</p>\n </div>\n }\n </div>\n\n @if (authMode() === 'forward-user-token') {\n <p class=\"message warning\" role=\"note\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.forward-warning' | translate }}</p>\n }\n\n @if (usesSecret()) {\n <fieldset class=\"field\">\n <legend>{{ 'nh-assistant.admin.server-editor.secret' | translate }}</legend>\n @if (hasSecret()) {\n <div class=\"meta secret-state\">\n @switch (secretAction()) {\n @case ('clear') {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.server-editor.secret-will-clear' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"setSecretAction('keep')\">{{ 'nh-assistant.admin.server-editor.secret-undo' | translate }}</button>\n }\n @case ('replace') {\n <span class=\"badge\">{{ 'nh-assistant.admin.server-editor.secret-set' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"setSecretAction('keep')\">{{ 'nh-assistant.admin.server-editor.secret-undo' | translate }}</button>\n }\n @default {\n <span class=\"badge success\">{{ 'nh-assistant.admin.server-editor.secret-set' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"setSecretAction('replace')\">{{ 'nh-assistant.admin.server-editor.secret-replace' | translate }}</button>\n <button class=\"danger\" type=\"button\" (click)=\"setSecretAction('clear')\">{{ 'nh-assistant.admin.server-editor.secret-clear' | translate }}</button>\n }\n }\n </div>\n } @else {\n <p class=\"muted\">{{ 'nh-assistant.admin.server-editor.secret-none' | translate }}</p>\n }\n @if (showSecretInput()) {\n <label class=\"visually-hidden\" [for]=\"id + '-secret'\">{{ 'nh-assistant.admin.server-editor.secret-new' | translate }}</label>\n <input\n type=\"password\"\n class=\"mono\"\n autocomplete=\"new-password\"\n spellcheck=\"false\"\n [id]=\"id + '-secret'\"\n [attr.placeholder]=\"'nh-assistant.admin.server-editor.secret-new' | translate\"\n [attr.aria-describedby]=\"id + '-secret-hint'\"\n [value]=\"secret()\"\n (input)=\"onSecretInput($event)\" />\n }\n <p class=\"hint\" [id]=\"id + '-secret-hint'\">{{ 'nh-assistant.admin.server-editor.secret-hint' | translate }}</p>\n </fieldset>\n }\n\n <div class=\"field\">\n <label [for]=\"id + '-policy'\">{{ 'nh-assistant.admin.server-editor.required-policy' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n [id]=\"id + '-policy'\"\n [value]=\"requiredPolicy()\"\n [attr.aria-describedby]=\"id + '-policy-hint'\"\n (input)=\"requiredPolicy.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.server-editor.required-policy-hint' | translate }}</p>\n </div>\n\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"isEnabled()\" (change)=\"isEnabled.set(checked($event))\" />\n <span>{{ 'nh-assistant.admin.server-editor.enabled' | translate }}</span>\n </label>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n <div class=\"actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"cancelled.emit()\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n <button class=\"primary\" type=\"submit\" [disabled]=\"saving()\">\n {{ (saving() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}\n </button>\n </div>\n</form>\n","import { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n McpServer,\n McpTool,\n McpToolEffect,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\n/** Unsaved changes of one tool row. */\ninterface ToolDraft {\n isEnabled: boolean;\n effect: McpToolEffect;\n descriptionOverride: string;\n}\n\nlet nextId = 0;\n\n/**\n * The tools of one MCP server. Every tool starts disabled as a change that needs approval;\n * the administrator enables it and chooses the effect. Remote annotations appear as hints\n * only, and a changed remote input schema is shown as a warning.\n */\n@Component({\n selector: 'nh-assistant-admin-mcp-tools',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-mcp-tools.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminMcpToolsComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n private rowSubscription?: Subscription;\n\n readonly server = input.required<McpServer>();\n readonly closed = output<void>();\n /** Emitted after a sync so the host can refresh the server's sync status. */\n readonly synced = output<void>();\n\n readonly id = `nh-assistant-mcp-tools-${nextId++}`;\n readonly effects: readonly McpToolEffect[] = ['mutation', 'read-only'];\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly syncing = signal(false);\n readonly savingTool = signal<string | null>(null);\n readonly savedTool = signal<string | null>(null);\n readonly tools = signal<McpTool[]>([]);\n readonly drafts = signal<Record<string, ToolDraft>>({});\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.rowSubscription?.unsubscribe();\n });\n\n effect(() => {\n const server = this.server();\n untracked(() => this.load(server.id));\n });\n }\n\n load(serverId = this.server().id): void {\n this.loading.set(true);\n this.loadFailed.set(false);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.getMcpTools(serverId).subscribe({\n next: tools => {\n this.setTools(tools);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n sync(): void {\n this.syncing.set(true);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.syncMcpServer(this.server().id).subscribe({\n next: tools => {\n this.setTools(tools);\n this.syncing.set(false);\n this.synced.emit();\n },\n error: (error: unknown) => {\n this.syncing.set(false);\n this.error.set(toNhAssistantError(error));\n this.synced.emit();\n }\n });\n }\n\n draft(tool: McpTool): ToolDraft {\n return this.drafts()[tool.remoteName] ?? toDraft(tool);\n }\n\n isDirty(tool: McpTool): boolean {\n const draft = this.draft(tool);\n return draft.isEnabled !== tool.isEnabled || draft.effect !== tool.effect ||\n draft.descriptionOverride !== (tool.descriptionOverride ?? '');\n }\n\n change(tool: McpTool, patch: Partial<ToolDraft>): void {\n this.savedTool.set(null);\n this.drafts.update(drafts => ({ ...drafts, [tool.remoteName]: { ...this.draft(tool), ...patch } }));\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement | HTMLSelectElement).value;\n }\n\n checked(event: Event): boolean {\n return (event.target as HTMLInputElement).checked;\n }\n\n save(tool: McpTool): void {\n const draft = this.draft(tool);\n const override = draft.descriptionOverride.trim();\n\n this.savingTool.set(tool.remoteName);\n this.savedTool.set(null);\n this.error.set(null);\n this.rowSubscription?.unsubscribe();\n this.rowSubscription = this.admin.updateMcpTool(this.server().id, tool.remoteName, {\n isEnabled: draft.isEnabled,\n effect: draft.effect,\n descriptionOverride: override.length > 0 ? override : null\n }).subscribe({\n next: updated => {\n this.tools.update(tools => tools.map(item => item.remoteName === updated.remoteName ? updated : item));\n this.drafts.update(drafts => {\n const { [updated.remoteName]: removed, ...rest } = drafts;\n return rest;\n });\n this.savingTool.set(null);\n this.savedTool.set(updated.remoteName);\n },\n error: (error: unknown) => {\n this.savingTool.set(null);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n private setTools(tools: McpTool[]): void {\n this.tools.set(tools);\n this.drafts.set({});\n this.savedTool.set(null);\n }\n}\n\nfunction toDraft(tool: McpTool): ToolDraft {\n return { isEnabled: tool.isEnabled, effect: tool.effect, descriptionOverride: tool.descriptionOverride ?? '' };\n}\n","<section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || syncing()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.tools.title' | translate: { name: server().displayName } }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.tools.description' | translate }}</p>\n </div>\n <div class=\"actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"closed.emit()\">{{ 'nh-assistant.admin.tools.back' | translate }}</button>\n <button class=\"primary\" type=\"button\" [disabled]=\"syncing()\" (click)=\"sync()\">\n <nh-assistant-icon name=\"refresh\" />{{ (syncing() ? 'nh-assistant.admin.mcp.syncing' : 'nh-assistant.admin.mcp.sync') | translate }}\n </button>\n </div>\n </header>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n @if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (loadFailed()) {\n <div class=\"state\" role=\"alert\">\n <p>{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (tools().length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.tools.empty' | translate }}</p>\n } @else {\n <ul class=\"cards\">\n @for (tool of tools(); track tool.remoteName) {\n <li class=\"card\" [class.inactive]=\"!tool.isEnabled\" [attr.data-status]=\"tool.status\" [attr.aria-busy]=\"savingTool() === tool.remoteName\">\n <div class=\"card-header\">\n <strong class=\"mono\">{{ tool.remoteName }}</strong>\n <span class=\"badge\"\n [class.warning]=\"tool.status === 'schema-changed'\"\n [class.danger]=\"tool.status === 'missing'\">{{ 'nh-assistant.admin.tools.status.' + tool.status | translate }}</span>\n <span class=\"badge\" [class.success]=\"tool.isEnabled\">{{ (tool.isEnabled ? 'nh-assistant.admin.enabled' : 'nh-assistant.admin.disabled') | translate }}</span>\n @if (tool.readOnlyHint !== null) {\n <span class=\"badge hint\" [attr.title]=\"'nh-assistant.admin.tools.description' | translate\">\n {{ (tool.readOnlyHint ? 'nh-assistant.admin.tools.hint-read-only' : 'nh-assistant.admin.tools.hint-mutation') | translate }}\n </span>\n }\n </div>\n <span class=\"mono muted\">{{ tool.localId }}</span>\n\n @if (tool.status === 'schema-changed') {\n <p class=\"message warning\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.tools.schema-changed-warning' | translate }}</p>\n }\n @if (tool.status === 'missing') {\n <p class=\"message error\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.tools.missing-warning' | translate }}</p>\n }\n\n <p class=\"muted\"><span class=\"label\">{{ 'nh-assistant.admin.tools.remote-description' | translate }}</span>{{ tool.description }}</p>\n\n <div class=\"grid\">\n <label class=\"check\">\n <input\n type=\"checkbox\"\n [checked]=\"draft(tool).isEnabled\"\n [disabled]=\"tool.status === 'missing'\"\n (change)=\"change(tool, { isEnabled: checked($event) })\" />\n <span>{{ 'nh-assistant.admin.tools.enabled' | translate }}</span>\n </label>\n <div class=\"field\">\n <label [for]=\"id + '-effect-' + $index\">{{ 'nh-assistant.admin.tools.effect' | translate }}</label>\n <select [id]=\"id + '-effect-' + $index\" (change)=\"change(tool, { effect: $any(value($event)) })\">\n @for (effect of effects; track effect) {\n <option [value]=\"effect\" [selected]=\"draft(tool).effect === effect\">{{ 'nh-assistant.admin.effect.' + effect | translate }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-override-' + $index\">{{ 'nh-assistant.admin.tools.description-override' | translate }}</label>\n <input\n type=\"text\"\n maxlength=\"1000\"\n [id]=\"id + '-override-' + $index\"\n [value]=\"draft(tool).descriptionOverride\"\n [attr.aria-describedby]=\"id + '-override-hint-' + $index\"\n (input)=\"change(tool, { descriptionOverride: value($event) })\" />\n <p class=\"hint\" [id]=\"id + '-override-hint-' + $index\">{{ 'nh-assistant.admin.tools.description-override-hint' | translate }}</p>\n </div>\n\n <div class=\"card-actions\">\n <button class=\"primary\" type=\"button\" [disabled]=\"!isDirty(tool) || savingTool() !== null\" (click)=\"save(tool)\">\n {{ (savingTool() === tool.remoteName ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.tools.save') | translate }}\n </button>\n @if (savedTool() === tool.remoteName) {\n <span class=\"badge success\" role=\"status\"><nh-assistant-icon name=\"check\" />{{ 'nh-assistant.admin.saved' | translate }}</span>\n }\n </div>\n </li>\n }\n </ul>\n }\n</section>\n","import { DatePipe } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n McpServer,\n McpServerTestResult,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n nhAssistantErrorMessageKey,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAdminMcpServerEditorComponent } from './nh-assistant-admin-mcp-server-editor.component';\nimport { NhAssistantAdminMcpToolsComponent } from './nh-assistant-admin-mcp-tools.component';\n\n/** Result of the latest connection test per server. */\ninterface TestState {\n running: boolean;\n result: McpServerTestResult | null;\n}\n\nlet nextId = 0;\n\n/**\n * MCP server administration: list, connection test, tool sync, the server editor and the\n * tool table of one server.\n */\n@Component({\n selector: 'nh-assistant-admin-mcp-servers',\n standalone: true,\n imports: [\n DatePipe,\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantAdminMcpServerEditorComponent,\n NhAssistantAdminMcpToolsComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin-mcp-servers.component.html',\n styleUrl: '../nh-assistant-admin-shared.scss'\n})\nexport class NhAssistantAdminMcpServersComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private subscription?: Subscription;\n private readonly actions = new Subscription();\n\n readonly id = `nh-assistant-admin-mcp-${nextId++}`;\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly servers = signal<McpServer[]>([]);\n /** `undefined`: list; `null`: new server; a server: editing that server. */\n readonly editing = signal<McpServer | null | undefined>(undefined);\n readonly toolsOf = signal<McpServer | null>(null);\n readonly tests = signal<Record<string, TestState>>({});\n readonly confirmingDelete = signal<string | null>(null);\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.actions.unsubscribe();\n });\n this.load();\n }\n\n load(): void {\n this.loading.set(true);\n this.loadFailed.set(false);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.getMcpServers().subscribe({\n next: servers => {\n this.servers.set(servers);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n /** Reloads the list silently, for example after a sync changed the sync status. */\n refresh(): void {\n this.actions.add(this.admin.getMcpServers().subscribe({ next: servers => this.servers.set(servers), error: () => undefined }));\n }\n\n create(): void {\n this.error.set(null);\n this.editing.set(null);\n }\n\n edit(server: McpServer): void {\n this.error.set(null);\n this.editing.set(server);\n }\n\n onSaved(server: McpServer): void {\n this.servers.update(servers => servers.some(item => item.id === server.id)\n ? servers.map(item => item.id === server.id ? server : item)\n : [...servers, server]);\n this.editing.set(undefined);\n }\n\n test(server: McpServer): void {\n this.setTest(server.id, { running: true, result: null });\n this.actions.add(this.admin.testMcpServer(server.id).subscribe({\n next: result => this.setTest(server.id, { running: false, result }),\n error: (error: unknown) => {\n const failure = toNhAssistantError(error);\n this.setTest(server.id, { running: false, result: { ok: false, code: failure.code, toolCount: null } });\n }\n }));\n }\n\n testState(serverId: string): TestState | null {\n return this.tests()[serverId] ?? null;\n }\n\n testErrorKeys(code: string | null): string[] {\n return code ? [nhAssistantErrorMessageKey(code), 'nh-assistant.errors.generic'] : ['nh-assistant.errors.generic'];\n }\n\n remove(server: McpServer): void {\n this.confirmingDelete.set(null);\n this.error.set(null);\n this.actions.add(this.admin.deleteMcpServer(server.id).subscribe({\n complete: () => this.servers.update(servers => servers.filter(item => item.id !== server.id)),\n error: (error: unknown) => this.error.set(toNhAssistantError(error))\n }));\n }\n\n private setTest(serverId: string, state: TestState): void {\n this.tests.update(tests => ({ ...tests, [serverId]: state }));\n }\n}\n","@if (editing() !== undefined) {\n <nh-assistant-admin-mcp-server-editor [server]=\"editing() ?? null\" (saved)=\"onSaved($event)\" (cancelled)=\"editing.set(undefined)\" />\n} @else if (toolsOf(); as server) {\n <nh-assistant-admin-mcp-tools [server]=\"server\" (closed)=\"toolsOf.set(null); refresh()\" (synced)=\"refresh()\" />\n} @else {\n <section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.mcp.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.mcp.description' | translate }}</p>\n </div>\n <button class=\"primary\" type=\"button\" [disabled]=\"loading() || loadFailed()\" (click)=\"create()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.mcp.new' | translate }}\n </button>\n </header>\n\n @if (error(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n\n @if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (loadFailed()) {\n <div class=\"state\" role=\"alert\">\n <p>{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (servers().length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.mcp.empty' | translate }}</p>\n } @else {\n <ul class=\"cards\">\n @for (server of servers(); track server.id) {\n <li class=\"card\" [class.inactive]=\"!server.isEnabled\">\n <div class=\"card-header\">\n <strong>{{ server.displayName }}</strong>\n <span class=\"mono muted\">{{ server.id }}</span>\n <span class=\"badge\" [class.success]=\"server.isEnabled\">{{ (server.isEnabled ? 'nh-assistant.admin.enabled' : 'nh-assistant.admin.disabled') | translate }}</span>\n @if (server.lastSyncStatus) {\n <span class=\"badge\" [class.success]=\"server.lastSyncStatus === 'ok'\" [class.danger]=\"server.lastSyncStatus === 'failed'\">\n {{ (server.lastSyncStatus === 'ok' ? 'nh-assistant.admin.mcp.sync-ok' : 'nh-assistant.admin.mcp.sync-failed') | translate }}\n </span>\n }\n </div>\n <span class=\"mono muted url\">{{ server.url }}</span>\n <div class=\"meta\">\n <span>{{ 'nh-assistant.admin.mcp.auth.' + server.authMode | translate }}</span>\n @if (server.authMode === 'bearer' || server.authMode === 'api-key') {\n <span class=\"badge\" [class.success]=\"server.hasSecret\" [class.warning]=\"!server.hasSecret\">\n {{ (server.hasSecret ? 'nh-assistant.admin.mcp.secret-set' : 'nh-assistant.admin.mcp.no-secret') | translate }}\n </span>\n }\n <span>\n @if (server.lastSyncAt) {\n {{ 'nh-assistant.admin.mcp.last-sync' | translate: { date: (server.lastSyncAt | date: 'medium') } }}\n } @else {\n {{ 'nh-assistant.admin.mcp.never-synced' | translate }}\n }\n </span>\n <span>\n @if (server.assignedAgentIds.length > 0) {\n {{ 'nh-assistant.admin.mcp.assigned' | translate: { agents: server.assignedAgentIds.join(', ') } }}\n } @else {\n {{ 'nh-assistant.admin.mcp.unassigned' | translate }}\n }\n </span>\n </div>\n\n @if (testState(server.id); as state) {\n @if (state.running) {\n <p class=\"muted\" role=\"status\">{{ 'nh-assistant.admin.mcp.testing' | translate }}</p>\n } @else if (state.result?.ok) {\n <p class=\"message success\" role=\"status\"><nh-assistant-icon name=\"check\" />{{ 'nh-assistant.admin.mcp.test-ok' | translate: { count: state.result?.toolCount ?? 0 } }}</p>\n } @else {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ testErrorKeys(state.result?.code ?? null) | nhAssistantTranslate: (state.result?.code ?? '') }}</p>\n }\n }\n\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"edit(server)\"><nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}</button>\n <button class=\"secondary\" type=\"button\" [disabled]=\"testState(server.id)?.running\" (click)=\"test(server)\">\n <nh-assistant-icon name=\"link\" />{{ 'nh-assistant.admin.mcp.test' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"toolsOf.set(server)\"><nh-assistant-icon name=\"tool\" />{{ 'nh-assistant.admin.mcp.tools' | translate }}</button>\n @if (confirmingDelete() === server.id) {\n <button class=\"danger\" type=\"button\" (click)=\"remove(server)\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingDelete.set(null)\">{{ 'nh-assistant.admin.keep' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" (click)=\"confirmingDelete.set(server.id)\"><nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.delete' | translate }}</button>\n }\n </div>\n </li>\n }\n </ul>\n }\n </section>\n}\n","import { ChangeDetectionStrategy, Component, ElementRef, afterNextRender, inject, input, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n NhAssistantStore\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAdminAgentsComponent } from './agents/nh-assistant-admin-agents.component';\nimport { NhAssistantAdminContextComponent } from './context/nh-assistant-admin-context.component';\nimport { NhAssistantAdminMcpServersComponent } from './mcp/nh-assistant-admin-mcp-servers.component';\n\nexport type NhAssistantAdminTab = 'context' | 'agents' | 'mcp-servers';\n\nlet nextId = 0;\n\n/**\n * The assistant administration page with the tabs Context, Agents and MCP servers. The host\n * routes to it and guards the route with its admin permission; the component additionally\n * shows a no-access state unless the server reports `canAdminister`.\n */\n@Component({\n selector: 'nh-assistant-admin',\n standalone: true,\n imports: [\n TranslatePipe,\n NhAssistantIconComponent,\n NhAssistantAdminContextComponent,\n NhAssistantAdminAgentsComponent,\n NhAssistantAdminMcpServersComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-admin.component.html',\n styleUrl: './nh-assistant-admin.component.scss'\n})\nexport class NhAssistantAdminComponent {\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n readonly store = inject(NhAssistantStore);\n\n /** Tab shown first. */\n readonly initialTab = input<NhAssistantAdminTab>('context');\n\n readonly id = `nh-assistant-admin-${nextId++}`;\n readonly tabs: readonly NhAssistantAdminTab[] = ['context', 'agents', 'mcp-servers'];\n readonly activeTab = signal<NhAssistantAdminTab | null>(null);\n readonly ready = signal(false);\n\n constructor() {\n afterNextRender(() => {\n void this.store.initialize().then(() => this.ready.set(true));\n });\n }\n\n selected(): NhAssistantAdminTab {\n return this.activeTab() ?? this.initialTab();\n }\n\n select(tab: NhAssistantAdminTab): void {\n this.activeTab.set(tab);\n }\n\n /** Arrow keys, Home and End move between tabs as the ARIA tabs pattern describes. */\n onTabKeydown(event: KeyboardEvent): void {\n const index = this.tabs.indexOf(this.selected());\n const last = this.tabs.length - 1;\n const targets: Record<string, number> = {\n ArrowRight: index === last ? 0 : index + 1,\n ArrowLeft: index === 0 ? last : index - 1,\n Home: 0,\n End: last\n };\n const next = targets[event.key];\n if (next === undefined) {\n return;\n }\n\n event.preventDefault();\n this.select(this.tabs[next]);\n this.host.nativeElement.querySelector<HTMLElement>(`#${this.id}-tab-${this.tabs[next]}`)?.focus();\n }\n}\n","<section class=\"admin\" [attr.aria-labelledby]=\"id + '-title'\">\n <header class=\"page-header\">\n <nh-assistant-icon class=\"page-icon\" name=\"admin\" />\n <div>\n <h2 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.title' | translate }}</h2>\n <p>{{ 'nh-assistant.admin.description' | translate }}</p>\n </div>\n </header>\n\n @if (!ready() || (store.statusLoading() && !store.enabled())) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (!store.enabled()) {\n <div class=\"state\">\n <nh-assistant-icon class=\"state-icon\" name=\"warning\" />\n <p class=\"state-title\">{{ 'nh-assistant.panel.unavailable-title' | translate }}</p>\n <p>{{ 'nh-assistant.panel.unavailable-description' | translate }}</p>\n </div>\n } @else if (!store.canAdminister()) {\n <div class=\"state\">\n <nh-assistant-icon class=\"state-icon\" name=\"warning\" />\n <p class=\"state-title\">{{ 'nh-assistant.admin.forbidden-title' | translate }}</p>\n <p>{{ 'nh-assistant.admin.forbidden-description' | translate }}</p>\n </div>\n } @else {\n <div class=\"tabs\" role=\"tablist\" [attr.aria-label]=\"'nh-assistant.admin.tabs-label' | translate\" (keydown)=\"onTabKeydown($event)\">\n @for (tab of tabs; track tab) {\n <button\n type=\"button\"\n role=\"tab\"\n class=\"tab\"\n [id]=\"id + '-tab-' + tab\"\n [attr.aria-selected]=\"selected() === tab\"\n [attr.aria-controls]=\"id + '-panel'\"\n [attr.tabindex]=\"selected() === tab ? 0 : -1\"\n (click)=\"select(tab)\">\n {{ 'nh-assistant.admin.tabs.' + tab | translate }}\n </button>\n }\n </div>\n\n <div class=\"panel\" role=\"tabpanel\" tabindex=\"0\" [id]=\"id + '-panel'\" [attr.aria-labelledby]=\"id + '-tab-' + selected()\">\n @switch (selected()) {\n @case ('context') {\n <nh-assistant-admin-context />\n }\n @case ('agents') {\n <nh-assistant-admin-agents />\n }\n @case ('mcp-servers') {\n <nh-assistant-admin-mcp-servers />\n }\n }\n </div>\n }\n</section>\n","/*\n * Public API surface of @newheap/platform-ai-chat/admin.\n *\n * The administration page is a separate entry point so hosts load it only on their lazy\n * admin route and the chat panel stays small.\n */\nexport * from './nh-assistant-admin.component';\nexport * from './context/nh-assistant-admin-context.component';\nexport * from './agents/nh-assistant-admin-agents.component';\nexport * from './agents/nh-assistant-admin-agent-editor.component';\nexport * from './agents/nh-assistant-agent-evaluation.component';\nexport * from './agents/nh-assistant-agent-feedback-report.component';\nexport * from './mcp/nh-assistant-admin-mcp-servers.component';\nexport * from './mcp/nh-assistant-admin-mcp-server-editor.component';\nexport * from './mcp/nh-assistant-admin-mcp-tools.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["nextId","nhAssistantErrorKeys","toNhAssistantError","NhAssistantIconComponent","NhAssistantTranslatePipe","NH_ASSISTANT_DASH_CASE","dayMs","periodRange"],"mappings":"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"}