@newheap/platform-ai-chat 0.1.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.
@@ -0,0 +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-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 { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal } 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';\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`.\n */\n@Component({\n selector: 'nh-assistant-admin-agents',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantAdminAgentEditorComponent],\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 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 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 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 {\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 @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 './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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"}