@newheap/platform-ai-chat 0.17.0 → 0.18.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/nh-assistant-account-names.ts","../../../projects/nh-ai-chat/admin/src/agents/agent-texts.ts","../../../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-agent-run-history.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-run-history.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/run-config-shared.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/agent-flow.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-agent-flow.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-agent-flow.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-account-picker.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/run-config-form.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-agent-work-setup.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-agent-work-setup.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-file-limits-fields.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-file-limits-fields.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-run-settings-form.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-run-settings-form.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-skill-form.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-skill-form.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-trigger-form.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-trigger-form.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-run-configuration.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-run-configuration.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 { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, signal } from '@angular/core';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\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 * The names the application knows for account ids, for the screens of the administration\n * (internal). A screen shows the name only; it shows the id, labeled as an account ID, only while\n * no name is known. When the lookup fails, `error` says why with the failure's code and `retry` asks\n * for the names that are still missing, so a failure never hides behind the ids. Create it in an\n * injection context, such as a component's field.\n */\nexport class NhAssistantAccountNames {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly translate = inject(TranslateService);\n private readonly subscriptions = new Subscription();\n /** The ids whose names were asked for, also the ones the application does not know. */\n private readonly asked = new Set<string>();\n /** The ids of failed lookups, which `retry` asks for again. */\n private failed = new Set<string>();\n\n /** The names found so far, by account id. */\n readonly names = signal<ReadonlyMap<string, string>>(new Map());\n /** Why the latest lookup failed; `null` while none did. */\n readonly error = signal<NhAssistantError | null>(null);\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscriptions.unsubscribe());\n }\n\n /**\n * The name of an account for a sentence, or its id labeled as an account ID (\"account ID …\")\n * while the application knows no name for it.\n */\n nameOf(actorId: string | null | undefined): string {\n if (!actorId) {\n return '';\n }\n\n return this.names().get(actorId) ?? this.translate.instant('nh-assistant.account-id', { id: actorId }) as string;\n }\n\n /**\n * The account ID as a tooltip for a name shown in its place; `null` while no name is known,\n * because the text shows the id then.\n */\n idTitleOf(actorId: string | null | undefined): string | null {\n if (!actorId || !this.names().has(actorId)) {\n return null;\n }\n\n return this.translate.instant('nh-assistant.account-id-title', { id: actorId }) as string;\n }\n\n /** Looks up the names of the ids that were not asked for yet. */\n load(actorIds: readonly (string | null | undefined)[]): void {\n const missing = [...new Set(actorIds.filter((id): id is string => !!id && !this.asked.has(id)))];\n if (missing.length === 0) {\n return;\n }\n\n for (const id of missing) {\n this.asked.add(id);\n }\n this.subscriptions.add(this.admin.getAccounts(missing).subscribe({\n next: accounts => {\n this.names.update(names => new Map([...names, ...accounts.map(account => [account.actorId, account.displayName] as const)]));\n },\n error: (error: unknown) => {\n for (const id of missing) {\n this.asked.delete(id);\n this.failed.add(id);\n }\n this.error.set(toNhAssistantError(error));\n }\n }));\n }\n\n /** Asks again for the names whose lookup failed. */\n retry(): void {\n const ids = [...this.failed];\n this.failed = new Set();\n this.error.set(null);\n this.load(ids);\n }\n}\n\n/**\n * The notice of a failed lookup of account names (internal): the screen shows ids, says why there\n * are no names and offers to look them up again.\n */\n@Component({\n selector: 'nh-assistant-account-names-error',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (names().error(); as failure) {\n <p class=\"names-error\" role=\"status\" data-account-names-error>\n <nh-assistant-icon name=\"warning\" />\n <span>{{ 'nh-assistant.admin.account-names-failed' | translate }} {{ keys() | nhAssistantTranslate: failure.code }}</span>\n <button type=\"button\" class=\"link\" data-account-names-retry (click)=\"names().retry()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </p>\n }\n `,\n styles: [`\n :host { display: block; min-width: 0; }\n .names-error {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 6px;\n margin: 0;\n border: 1px solid var(--nha-warning, #8a5a00);\n border-radius: var(--nha-radius-control, 12px);\n padding: 8px 12px;\n color: var(--nha-text, inherit);\n background: var(--nha-warning-soft, transparent);\n font-size: 13px;\n overflow-wrap: anywhere;\n }\n .names-error span { flex: 1 1 auto; min-width: 0; }\n button.link {\n border: 0;\n padding: 0;\n color: var(--nha-accent, currentColor);\n background: none;\n font: inherit;\n text-decoration: underline;\n cursor: pointer;\n }\n `]\n})\nexport class NhAssistantAccountNamesErrorComponent {\n readonly names = input.required<NhAssistantAccountNames>();\n readonly keys = computed(() => nhAssistantErrorKeys(this.names().error()));\n}\n\n/**\n * One account by its name (internal): the name only, with the account ID as its tooltip and a\n * button that copies the ID; without a known name the ID itself, labeled as an account ID. Where\n * the browser refuses the clipboard, the button shows the ID next to the name to copy by hand.\n */\n@Component({\n selector: 'nh-assistant-account-label',\n standalone: true,\n imports: [TranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (name(); as known) {\n <span class=\"account-name\" data-account-label-name [attr.title]=\"'nh-assistant.account-id-title' | translate: { id: actorId() }\">{{ known }}</span>\n <button\n type=\"button\"\n class=\"copy-id\"\n data-account-copy-id\n [attr.aria-label]=\"'nh-assistant.admin.account.copy-id' | translate: { name: known }\"\n [attr.title]=\"'nh-assistant.admin.account.copy-id' | translate: { name: known }\"\n (click)=\"copyId()\">\n <nh-assistant-icon [name]=\"copied() ? 'check' : 'copy'\" />\n </button>\n @if (revealed()) {\n <span class=\"account-id\" data-account-label-revealed>{{ 'nh-assistant.admin.account.id' | translate: { id: actorId() } }}</span>\n }\n <span class=\"visually-hidden\" role=\"status\">{{ copied() ? ('nh-assistant.admin.account.id-copied' | translate) : '' }}</span>\n } @else {\n <span class=\"account-id\" data-account-label-id>{{ 'nh-assistant.admin.account.id' | translate: { id: actorId() } }}</span>\n }\n `,\n styles: [`\n :host { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; min-width: 0; max-width: 100%; }\n .account-name { font-weight: 600; overflow-wrap: anywhere; }\n .account-id { color: var(--nha-muted, inherit); overflow-wrap: anywhere; }\n .copy-id {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n min-width: 28px;\n min-height: 28px;\n border: 1px solid transparent;\n border-radius: var(--nha-radius-control, 12px);\n padding: 4px;\n color: var(--nha-muted, currentColor);\n background: none;\n cursor: pointer;\n }\n .copy-id:hover { color: var(--nha-text, currentColor); border-color: var(--nha-border, currentColor); }\n .copy-id:focus-visible { outline: 2px solid var(--nha-accent, currentColor); outline-offset: 2px; }\n .visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n }\n `]\n})\nexport class NhAssistantAccountLabelComponent {\n /** The account's id. */\n readonly actorId = input.required<string>();\n /** The account's name; `null` while the application knows none. */\n readonly name = input<string | null>(null);\n\n readonly copied = signal(false);\n readonly revealed = signal(false);\n private resetTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => clearTimeout(this.resetTimer));\n effect(() => {\n // Another account starts without the state of the previous one.\n this.actorId();\n this.copied.set(false);\n this.revealed.set(false);\n });\n }\n\n async copyId(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.actorId());\n } catch {\n // Without clipboard access the ID is shown to copy by hand.\n this.revealed.set(true);\n return;\n }\n\n this.copied.set(true);\n clearTimeout(this.resetTimer);\n this.resetTimer = setTimeout(() => this.copied.set(false), 3_000);\n }\n}\n","/**\n * Translation keys for the texts the administration shows about agents, skills and policies. Each\n * list goes through `nhAssistantTranslate` with the text itself as fallback, so a missing\n * translation shows what the server sent.\n */\n\n/**\n * The key of a text of an agent in code, which names and describes itself with translation keys;\n * none for an agent created in the administration, whose texts are what the administrator typed.\n */\nexport function codeTextKeys(source: string, text: string | null | undefined): string[] {\n return source === 'code' && text ? [text] : [];\n}\n\n/** The key an application may translate a skill's name with. */\nexport function skillNameKeys(agentId: string, skillId: string): string[] {\n return [`nh-assistant.agents.${agentId}.skills.${skillId}.name`];\n}\n\n/**\n * The key an application may translate a skill's description with. Skills in code describe\n * themselves in the language triage reads; the screen shows a translation when there is one.\n */\nexport function skillDescriptionKeys(agentId: string, skillId: string): string[] {\n return [`nh-assistant.agents.${agentId}.skills.${skillId}.description`];\n}\n\n/**\n * The key of a warning about an agent or a skill that is saved and in effect but may not work as\n * configured, such as `classification-not-permitted`; a code the screen does not know shows as sent.\n */\nexport function warningKeys(kind: 'agent' | 'skill', code: string): string[] {\n return kind === 'agent'\n ? [`nh-assistant.admin.agents.warnings.${code}`]\n : [`nh-assistant.admin.run-config.skills.warnings.${code}`];\n}\n\n/** The key an application may translate an authorization policy's name with. */\nexport function policyKeys(policy: string | null | undefined): string[] {\n return policy ? [`nh-assistant.policies.${policy}`] : [];\n}\n\n/** A readable name for a dash-case id: `task-follow-up` reads \"Task follow up\". */\nexport function readableId(id: string): string {\n const words = id.split('-').filter(word => word.length > 0).join(' ');\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\n/** What an agent works on, ready to show: object types by name, all objects and the application. */\nexport interface WorksOnSummary {\n /** The names of the object types it works on; empty with `all`. */\n types: string[];\n /** It works on every object type. */\n all: boolean;\n /** It works on the whole application. */\n application: boolean;\n perDivision: boolean;\n /** An agent in code that does not say what it works on. */\n undeclared: boolean;\n /** The names of the object types it is known to work on, as a hint next to \"All objects\". */\n known: string[];\n runPolicy: string | null;\n viewPolicy: string | null;\n}\n\n/**\n * What an agent works on, with object types named as the run catalog names several of them in the\n * reader's language, and their ids otherwise. An older server that does not say reads as all objects.\n * The platform's types (`nh-`, such as the whole application's `nh-system`) are not object types of\n * the application: the agent's threads on the whole application are no hint next to \"All objects\".\n */\nexport function worksOnSummary(\n agent: {\n worksOnSubjectTypes?: string[];\n worksOnAllSubjects?: boolean;\n worksOnApplication?: boolean;\n perDivision?: boolean;\n worksOnDeclared?: boolean;\n knownSubjectTypes?: string[];\n runPolicy?: string | null;\n viewPolicy?: string | null;\n },\n subjectTypes: readonly { id: string; name: string; pluralName?: string | null; isSystem?: boolean }[] | null | undefined\n): WorksOnSummary {\n const names = new Map((subjectTypes ?? []).map(type => [type.id, type.pluralName ?? type.name]));\n const system = new Set((subjectTypes ?? []).filter(type => type.isSystem).map(type => type.id));\n const name = (id: string): string => names.get(id) ?? id;\n const objectType = (id: string): boolean => !id.startsWith('nh-') && !system.has(id);\n const types = (agent.worksOnSubjectTypes ?? []).filter(objectType);\n const all = agent.worksOnAllSubjects ?? (types.length === 0 && agent.worksOnApplication !== true);\n return {\n types: all ? [] : types.map(name),\n all,\n application: agent.worksOnApplication === true,\n perDivision: agent.perDivision === true,\n undeclared: agent.worksOnDeclared === false,\n known: (agent.knownSubjectTypes ?? []).filter(objectType).map(name),\n runPolicy: agent.runPolicy ?? null,\n viewPolicy: agent.viewPolicy ?? null\n };\n}\n\n/** What the run-now dialog needs of an agent: its id, its name as people read it and what it works on. */\nexport interface RunNowAgentInput {\n id: string;\n worksOnSubjectTypes?: string[];\n worksOnAllSubjects?: boolean;\n worksOnApplication?: boolean;\n perDivision?: boolean;\n}\n\n/**\n * The agent as the run-now dialog runs it, with its name in the reader's language. An older server that\n * does not say what the agent works on reads as all objects, not the whole application, app-wide.\n */\nexport function runNowAgentOf(agent: RunNowAgentInput, name: string): {\n id: string;\n name: string;\n worksOnSubjectTypes: string[];\n worksOnAllSubjects: boolean;\n worksOnApplication: boolean;\n perDivision: boolean;\n} {\n return {\n id: agent.id,\n name,\n worksOnSubjectTypes: agent.worksOnSubjectTypes ?? [],\n worksOnAllSubjects: agent.worksOnAllSubjects ?? true,\n worksOnApplication: agent.worksOnApplication ?? false,\n perDivision: agent.perDivision ?? false\n };\n}\n","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';\nimport { NhAssistantAccountNames, NhAssistantAccountNamesErrorComponent } from '../nh-assistant-account-names';\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, NhAssistantAccountNamesErrorComponent],\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 /** The names of the people who changed the context, once known, and why they are not. */\n readonly accountNames = new NhAssistantAccountNames();\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.accountNames.load(versions.map(version => version.updatedBy));\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 /** A person's name, or the id when the application does not know it. */\n nameOf(actorId: string | null | undefined): string {\n return this.accountNames.nameOf(actorId);\n }\n\n /** The account ID as the tooltip of a name shown in its place. */\n accountTitle(actorId: string | null | undefined): string | null {\n return this.accountNames.idTitleOf(actorId);\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.accountNames.load([updated.updatedBy]);\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 <nh-assistant-account-names-error [names]=\"accountNames\" />\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 [attr.title]=\"accountTitle(current.updatedBy)\">\n @if (current.updatedBy) {\n {{ 'nh-assistant.admin.context.updated' | translate: { date: (current.updatedAt | date: 'medium'), user: nameOf(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 [attr.title]=\"accountTitle(version.updatedBy)\">{{ nameOf(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, TranslateService } from '@ngx-translate/core';\nimport { Observable, Subscription, map, of, switchMap, tap } from 'rxjs';\nimport {\n AdminAgent,\n AdminAgentGroups,\n AdminAgentInput,\n AssistantAutonomy,\n AssistantDataClassification,\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 RunCatalog,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport { NH_ASSISTANT_MAX_INSTRUCTIONS } from '../context/nh-assistant-admin-context.component';\nimport { policyKeys, warningKeys, worksOnSummary } from './agent-texts';\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\n/** A text of an agent in code: its translation key and the translation the editor shows instead. */\ninterface KeyedText {\n key: string;\n shown: string;\n}\n\n/** How an agent created in the administration is used: chosen in the chat, working on its own, or both. */\nexport type AgentUse = 'chat' | 'background' | 'both';\n\n/** Whether an agent created in the administration works on every object type or on chosen ones. */\nexport type WorksOnScope = 'all' | 'types';\n\n/** The most object types one agent works on, as the server allows. */\nconst maxWorksOnTypes = 20;\n\nlet nextId = 0;\n\n/**\n * Creates or edits one agent: how it is used (offered in the chat, working on its own, or both),\n * what it works on (all objects or chosen object types, the whole application, per division when\n * the application lists divisions, and who may run it and see its results for the whole\n * application), texts, autonomy, policy, tool selectors chosen from the tool catalog or typed as\n * patterns, and assigned MCP servers. A new agent meant to work on its own continues with\n * `workRequested`. An agent in code names and describes itself with translation keys: the editor\n * shows their translation and sends the key back unless the administrator changed the text, so the\n * agent stays translated; what it works on comes from its code and is not edited here.\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 readonly translate = inject(TranslateService);\n private subscription?: Subscription;\n private keyedName: KeyedText | null = null;\n private keyedDescription: KeyedText | null = null;\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 /** The run catalog: the object types by name, the policies to choose and whether divisions are listed. */\n readonly catalog = input<RunCatalog | null>(null);\n /**\n * The run catalog could not be read: the editor then leaves out what the agent works on and its\n * groups, which depend on it, and a save keeps them as they are.\n */\n readonly catalogUnavailable = input(false);\n readonly saved = output<AdminAgent>();\n /**\n * A new agent meant to work on its own was created; the host continues with its run\n * configuration's guided setup. `saved` is not emitted for it.\n */\n readonly workRequested = output<AdminAgent>();\n readonly cancelled = output<void>();\n readonly uses: readonly AgentUse[] = ['chat', 'background', 'both'];\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 readonly classifications: readonly AssistantDataClassification[] = ['public', 'internal', 'confidential', 'restricted'];\n\n readonly agentId = signal('');\n readonly displayName = signal('');\n readonly description = signal('');\n readonly instructions = signal('');\n readonly autonomy = signal<AssistantAutonomy>('explain');\n /** How the agent is used: in the chat, on its own, or both. */\n readonly use = signal<AgentUse>('chat');\n /** A new agent takes its triggers at once; without it, it starts off until someone switches it on. */\n readonly switchOnNow = signal(true);\n /** The model profile of an agent created here; empty uses the application's chat profile. */\n readonly profile = signal('');\n /** The classification of the model calls of an agent created here; `internal` when it has none. */\n readonly dataClassification = signal<AssistantDataClassification>('internal');\n readonly requiredPolicy = signal('');\n readonly toolSelectors = signal<string[]>([]);\n readonly mcpServerIds = signal<string[]>([]);\n /** What the agent works on: all objects or the chosen object types. */\n readonly worksOnScope = signal<WorksOnScope>('all');\n readonly worksOnTypes = signal<string[]>([]);\n readonly worksOnApplication = signal(false);\n readonly perDivision = signal(false);\n readonly runPolicy = signal('');\n readonly viewPolicy = signal('');\n /** The groups of agents the agent is in, by id. */\n readonly groups = 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 /**\n * A new agent that was created while its groups could not be saved yet: the next save completes it\n * as an existing agent.\n */\n private readonly created = signal<AdminAgent | null>(null);\n /** The agent the next save updates; `null` while a new agent is not created yet. */\n private readonly editing = computed(() => this.created() ?? this.agent());\n\n readonly isNew = computed(() => this.editing() === null);\n /** Only agents created here choose whether they are offered in the chat; code decides for the others. */\n readonly choosesUse = computed(() => this.agent()?.source !== 'code');\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 /**\n * The application's own object types, by name; the platform's types, such as the whole\n * application, are chosen otherwise. A stored type the application no longer registers stays\n * listed by its id, so it can be unticked.\n */\n readonly subjectTypes = computed(() => {\n const catalog = this.catalog()?.subjectTypes ?? [];\n const registered = catalog.filter(type => !type.isSystem);\n const stored = (this.agent()?.worksOnSubjectTypes ?? [])\n .filter(id => !id.startsWith('nh-') && !catalog.some(type => type.id === id))\n .map(id => ({ id, name: id, pluralName: null as string | null }));\n return [...registered, ...stored];\n });\n readonly agentPolicies = computed(() => this.catalog()?.agentPolicies ?? []);\n /** The groups of agents the application registers, which boards show. */\n readonly agentGroups = computed(() => this.catalog()?.agentGroups ?? []);\n /** The groups the agent joins in code. */\n readonly codeGroups = computed(() => this.agent()?.codeGroups ?? []);\n /** A shadow variant works for administrators only and joins no group. */\n readonly isVariant = computed(() => !!this.agent()?.shadowOf);\n /** The server's refusal of the groups, as a translation key. */\n readonly groupsError = computed(() => this.fieldError('groups'));\n /** Per division is offered only when the application lists its divisions. */\n readonly divisionsListed = computed(() => this.catalog()?.divisions === true);\n /** The object types the agent is known to work on, by name, as a hint next to \"All objects\". */\n readonly knownTypes = computed(() => {\n const agent = this.agent();\n return agent ? worksOnSummary(agent, this.catalog()?.subjectTypes).known : [];\n });\n /** What the agent works on is edited here: an agent created here, while the run catalog is known. */\n readonly editsWorksOn = computed(() => this.choosesUse() && !this.catalogUnavailable());\n /** An agent created here chooses its profile from those the run catalog offers. */\n readonly choosesProfile = computed(() => this.choosesUse() && !this.catalogUnavailable());\n /** The profiles the run catalog offers, and the agent's own when the catalog no longer lists it. */\n readonly profileChoices = computed(() => {\n const listed = this.catalog()?.profiles ?? [];\n const current = this.agent()?.profile;\n return current && !listed.includes(current) ? [...listed, current] : listed;\n });\n /** Chosen object types without a type, and not the application either: the agent would work on nothing. */\n readonly worksOnMissing = computed(() =>\n this.editsWorksOn() && this.worksOnScope() === 'types' && this.worksOnTypes().length === 0 && !this.worksOnApplication());\n readonly tooManyTypes = computed(() =>\n this.editsWorksOn() && this.worksOnScope() === 'types' && this.worksOnTypes().length > maxWorksOnTypes);\n readonly policyKeys = policyKeys;\n readonly warningKeys = warningKeys;\n /** The warnings of the agent as it was saved, until this editor saves it again. */\n readonly warnings = computed(() => this.agent()?.warnings ?? []);\n readonly valid = computed(() => !this.idInvalid() && !this.nameMissing() && !this.tooLong() && !this.worksOnMissing() && !this.tooManyTypes());\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 toggleWorksOnType(typeId: string, checked: boolean): void {\n this.worksOnTypes.update(types => checked ? [...types.filter(type => type !== typeId), typeId] : types.filter(type => type !== typeId));\n }\n\n toggleGroup(groupId: string, checked: boolean): void {\n this.groups.update(groups => checked ? [...groups.filter(group => group !== groupId), groupId] : groups.filter(group => group !== groupId));\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 /** The first error the server reported for a field, as a translation key. */\n fieldError(field: string): string | null {\n const code = this.error()?.fieldErrors?.[field]?.[0];\n return code ? `nh-assistant.admin.run-config.field-errors.${code}` : null;\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.editing()!.id,\n displayName: keyOrText(this.displayName(), this.keyedName),\n description: keyOrText(this.description(), this.keyedDescription),\n instructions: this.instructions(),\n toolSelectors: this.toolSelectors(),\n mcpServerIds: this.mcpServerIds(),\n requiredPolicy: policy.length > 0 ? policy : null,\n autonomy: this.autonomy(),\n ...(this.choosesUse() ? { offeredInChat: this.use() !== 'background' } : {}),\n // Omitted, what the agent works on stays as it is; a new agent then works on every object type.\n ...(this.editsWorksOn() ? this.worksOnInput() : {}),\n ...(this.isNew() && !this.switchOnNow() ? { startsOff: true } : {}),\n // Omitted, the profile stays as it is; a new agent then uses the application's chat profile.\n ...(this.choosesProfile() && this.profile() !== '' ? { profile: this.profile() } : {}),\n // Sent only when it changes, so an agent without a classification keeps none.\n ...(this.choosesUse() && this.dataClassification() !== (this.editing()?.dataClassification ?? 'internal')\n ? { dataClassification: this.dataClassification() }\n : {})\n };\n const startsWork = this.agent() === null && this.use() !== 'chat';\n\n // An existing agent's groups are saved before its definition, a new agent's right after it is\n // created; a new agent whose groups failed is completed as an existing one by the next save.\n // Without the run catalog the groups are not shown, so they stay as they are.\n const existing = this.editing();\n const groups = this.catalogUnavailable() ? [...(existing?.groups ?? [])].sort() : [...this.groups()].sort();\n const groupsChanged = !sameGroups(groups, existing?.groups ?? []);\n const groupsSaved: Observable<AdminAgentGroups | null> = existing && groupsChanged && !this.isVariant()\n ? this.admin.setAgentGroups(existing.id, groups)\n : of(null);\n const request: Observable<AdminAgent> = existing\n ? groupsSaved.pipe(\n switchMap(membership => this.admin.updateAgent(existing.id, { ...input, expectedVersion: existing.version }).pipe(\n map(agent => withGroups(agent, membership)))))\n : this.admin.createAgent(input).pipe(\n tap(agent => this.created.set(agent)),\n switchMap(agent => groups.length > 0\n ? this.admin.setAgentGroups(agent.id, groups).pipe(map(membership => withGroups(agent, membership)))\n : of(agent)));\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 if (startsWork) {\n this.workRequested.emit(agent);\n } else {\n this.saved.emit(agent);\n }\n },\n error: (error: unknown) => {\n this.saving.set(false);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n /** What the agent works on, as the six fields the server reads together. */\n private worksOnInput(): Pick<AdminAgentInput,\n 'worksOnSubjectTypes' | 'worksOnAllSubjects' | 'worksOnApplication' | 'perDivision' | 'runPolicy' | 'viewPolicy'> {\n const all = this.worksOnScope() === 'all';\n return {\n worksOnSubjectTypes: all ? [] : [...this.worksOnTypes()].sort(),\n worksOnAllSubjects: all,\n worksOnApplication: this.worksOnApplication(),\n perDivision: this.divisionsListed() && this.perDivision(),\n runPolicy: this.runPolicy() || null,\n viewPolicy: this.viewPolicy() || null\n };\n }\n\n private reset(agent: AdminAgent | null): void {\n this.agentId.set(agent?.id ?? '');\n this.keyedName = agent?.source === 'code' ? this.keyed(agent.displayName) : null;\n this.keyedDescription = agent?.source === 'code' ? this.keyed(agent.description) : null;\n this.displayName.set(this.keyedName?.shown ?? agent?.displayName ?? '');\n this.description.set(this.keyedDescription?.shown ?? agent?.description ?? '');\n this.instructions.set(agent?.instructions ?? '');\n this.autonomy.set(agent?.autonomy ?? 'explain');\n this.use.set(agent?.offeredInChat === false ? 'background' : 'chat');\n this.switchOnNow.set(true);\n this.profile.set(agent?.source === 'admin' ? agent.profile ?? '' : '');\n this.dataClassification.set(agent?.source === 'admin' ? agent.dataClassification ?? 'internal' : 'internal');\n this.requiredPolicy.set(agent?.requiredPolicy ?? '');\n this.toolSelectors.set([...(agent?.toolSelectors ?? [])]);\n this.mcpServerIds.set([...(agent?.mcpServerIds ?? [])]);\n const worksOn = worksOnSummary(agent ?? {}, null);\n this.worksOnScope.set(worksOn.all ? 'all' : 'types');\n this.worksOnTypes.set([...(worksOn.all ? [] : agent?.worksOnSubjectTypes ?? [])]);\n this.worksOnApplication.set(worksOn.application);\n this.perDivision.set(worksOn.perDivision);\n this.runPolicy.set(worksOn.runPolicy ?? '');\n this.viewPolicy.set(worksOn.viewPolicy ?? '');\n this.groups.set([...(agent?.groups ?? [])]);\n this.created.set(null);\n this.submitted.set(false);\n this.error.set(null);\n }\n\n /** The translation of a key of an agent in code, or `null` when the text is not a key with a translation. */\n private keyed(text: string | null | undefined): KeyedText | null {\n if (!text) {\n return null;\n }\n const shown = this.translate.instant(text) as unknown;\n return typeof shown === 'string' && shown.length > 0 && shown !== text ? { key: text, shown } : null;\n }\n}\n\n/** Whether two sorted lists of group ids are the same. */\nfunction sameGroups(left: readonly string[], right: readonly string[]): boolean {\n const sorted = [...right].sort();\n return left.length === sorted.length && left.every((group, index) => group === sorted[index]);\n}\n\n/** The agent with the groups the server answered, or as it is without an answer. */\nfunction withGroups(agent: AdminAgent, membership: AdminAgentGroups | null): AdminAgent {\n return membership ? { ...agent, groups: membership.groups, codeGroups: membership.codeGroups } : agent;\n}\n\n/** The key of a text of an agent in code while the administrator kept its translation, otherwise the typed text. */\nfunction keyOrText(value: string, keyed: KeyedText | null): string {\n const text = value.trim();\n return keyed !== null && text === keyed.shown.trim() ? keyed.key : text;\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 @if (choosesUse()) {\n <fieldset class=\"subsection\" data-agent-use>\n <legend>{{ 'nh-assistant.admin.agent-editor.use.title' | translate }}</legend>\n <div class=\"uses\">\n @for (option of uses; track option) {\n <label class=\"use\" [class.selected]=\"use() === option\">\n <input type=\"radio\" [name]=\"id + '-use'\" [value]=\"option\" [checked]=\"use() === option\" (change)=\"use.set(option)\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.use.' + option | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.use.' + option + '-hint' | translate }}</span>\n </span>\n </label>\n }\n </div>\n @if (isNew() && use() !== 'chat') {\n <p class=\"hint\">{{ 'nh-assistant.admin.agent-editor.use.next' | translate }}</p>\n }\n @if (isNew()) {\n <label class=\"check described\" data-switch-on-now>\n <input type=\"checkbox\" [checked]=\"switchOnNow()\" (change)=\"switchOnNow.set(checked($event))\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.switch-on-now' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.switch-on-now-hint' | translate }}</span>\n </span>\n </label>\n }\n </fieldset>\n\n @if (catalogUnavailable()) {\n <!-- Without the run catalog the kinds of objects and policies are unknown: what the agent works on stays as it is. -->\n <p class=\"message warning\" role=\"note\" data-catalog-unavailable>\n <nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.agent-editor.catalog-unavailable' | translate }}\n </p>\n } @else {\n <fieldset\n class=\"subsection\"\n data-works-on\n [attr.aria-describedby]=\"id + '-works-on-hint ' + id + '-works-on-error'\"\n [attr.aria-invalid]=\"(submitted() && worksOnMissing()) || fieldError('worksOn') ? true : null\">\n <legend>{{ 'nh-assistant.admin.agent-editor.works-on.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-works-on-hint'\">{{ 'nh-assistant.admin.agent-editor.works-on.hint' | translate }}</p>\n <div class=\"uses\">\n <label class=\"use\" [class.selected]=\"worksOnScope() === 'all'\">\n <input type=\"radio\" [name]=\"id + '-works-on'\" value=\"all\" [checked]=\"worksOnScope() === 'all'\" (change)=\"worksOnScope.set('all')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.works-on.all' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.all-hint' | translate }}</span>\n </span>\n </label>\n <label class=\"use\" [class.selected]=\"worksOnScope() === 'types'\">\n <input type=\"radio\" [name]=\"id + '-works-on'\" value=\"types\" [checked]=\"worksOnScope() === 'types'\" (change)=\"worksOnScope.set('types')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.works-on.types' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.types-hint' | translate }}</span>\n </span>\n </label>\n </div>\n\n @if (worksOnScope() === 'types') {\n <div class=\"checks\" role=\"group\" [attr.aria-label]=\"'nh-assistant.admin.agent-editor.works-on.types' | translate\" data-works-on-types>\n @for (type of subjectTypes(); track type.id) {\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"worksOnTypes().includes(type.id)\" (change)=\"toggleWorksOnType(type.id, checked($event))\" />\n <span>{{ type.pluralName ?? type.name }} <span class=\"mono muted\">{{ type.id }}</span></span>\n </label>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.no-types' | translate }}</p>\n }\n </div>\n @if (fieldError('worksOnSubjectTypes'); as key) {\n <p class=\"hint\"><span class=\"error-text\">{{ key | translate }}</span></p>\n } @else if (tooManyTypes()) {\n <p class=\"hint\"><span class=\"error-text\">{{ 'nh-assistant.admin.agent-editor.works-on.too-many' | translate }}</span></p>\n }\n }\n\n @if (knownTypes().length > 0) {\n <p class=\"hint\" data-known-types>{{ 'nh-assistant.admin.agent-editor.works-on.known' | translate: { types: knownTypes().join(', ') } }}</p>\n }\n\n <label class=\"check described\">\n <input type=\"checkbox\" [checked]=\"worksOnApplication()\" (change)=\"worksOnApplication.set(checked($event))\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.works-on.application' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.application-hint' | translate }}</span>\n </span>\n </label>\n\n @if (divisionsListed()) {\n <label class=\"check described\" data-per-division>\n <input\n type=\"checkbox\"\n [checked]=\"perDivision()\"\n [attr.aria-invalid]=\"fieldError('perDivision') ? true : null\"\n [attr.aria-describedby]=\"fieldError('perDivision') ? id + '-per-division-error' : null\"\n (change)=\"perDivision.set(checked($event))\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.works-on.per-division' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.per-division-hint' | translate }}</span>\n </span>\n </label>\n @if (fieldError('perDivision'); as key) {\n <p class=\"hint\" [id]=\"id + '-per-division-error'\"><span class=\"error-text\">{{ key | translate }}</span></p>\n }\n }\n\n <p class=\"hint\" [id]=\"id + '-works-on-error'\" aria-live=\"polite\">\n @if (submitted() && worksOnMissing()) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.agent-editor.works-on.missing' | translate }}</span>\n } @else if (fieldError('worksOn'); as key) {\n <span class=\"error-text\">{{ key | translate }}</span>\n }\n </p>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-run-policy'\">{{ 'nh-assistant.admin.agent-editor.works-on.run-policy' | translate }}</label>\n <select\n [id]=\"id + '-run-policy'\"\n [attr.aria-describedby]=\"id + '-run-policy-hint'\"\n [attr.aria-invalid]=\"fieldError('runPolicy') ? true : null\"\n (change)=\"runPolicy.set(value($event))\">\n <option value=\"\" [selected]=\"runPolicy() === ''\">{{ 'nh-assistant.admin.agent-editor.works-on.run-policy-default' | translate }}</option>\n @for (policy of agentPolicies(); track policy.name) {\n <option [value]=\"policy.name\" [selected]=\"runPolicy() === policy.name\">{{ policyKeys(policy.name) | nhAssistantTranslate: policy.description }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-run-policy-hint'\">\n @if (fieldError('runPolicy'); as key) {\n <span class=\"error-text\">{{ key | translate }}</span>\n } @else {\n {{ 'nh-assistant.admin.agent-editor.works-on.run-policy-hint' | translate }}\n }\n </p>\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-view-policy'\">{{ 'nh-assistant.admin.agent-editor.works-on.view-policy' | translate }}</label>\n <select\n [id]=\"id + '-view-policy'\"\n [attr.aria-describedby]=\"id + '-view-policy-hint'\"\n [attr.aria-invalid]=\"fieldError('viewPolicy') ? true : null\"\n (change)=\"viewPolicy.set(value($event))\">\n <option value=\"\" [selected]=\"viewPolicy() === ''\">{{ 'nh-assistant.admin.agent-editor.works-on.view-policy-default' | translate }}</option>\n @for (policy of agentPolicies(); track policy.name) {\n <option [value]=\"policy.name\" [selected]=\"viewPolicy() === policy.name\">{{ policyKeys(policy.name) | nhAssistantTranslate: policy.description }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-view-policy-hint'\">\n @if (fieldError('viewPolicy'); as key) {\n <span class=\"error-text\">{{ key | translate }}</span>\n } @else {\n {{ 'nh-assistant.admin.agent-editor.works-on.view-policy-hint' | translate }}\n }\n </p>\n </div>\n </div>\n </fieldset>\n }\n }\n\n @if (agentGroups().length > 0 && !catalogUnavailable()) {\n <fieldset\n class=\"subsection\"\n data-agent-groups\n [attr.aria-describedby]=\"id + '-groups-hint ' + id + '-groups-error'\"\n [attr.aria-invalid]=\"groupsError() ? true : null\">\n <legend>{{ 'nh-assistant.admin.agent-editor.groups.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-groups-hint'\">{{ 'nh-assistant.admin.agent-editor.groups.hint' | translate }}</p>\n @if (isVariant()) {\n <p class=\"hint\" data-groups-variant>{{ 'nh-assistant.admin.agent-editor.groups.shadow-variant' | translate }}</p>\n } @else {\n <div class=\"checks\" role=\"group\" [attr.aria-label]=\"'nh-assistant.admin.agent-editor.groups.title' | translate\">\n @for (group of agentGroups(); track group.id) {\n <label class=\"check described\" [attr.data-agent-group]=\"group.id\">\n <input type=\"checkbox\" [checked]=\"groups().includes(group.id)\" (change)=\"toggleGroup(group.id, checked($event))\" />\n <span>\n <strong>{{ group.name }}</strong>\n @if (group.description; as description) {\n <span class=\"muted\">{{ description }}</span>\n }\n @if (codeGroups().includes(group.id)) {\n <span class=\"muted\" data-group-in-code>{{ 'nh-assistant.admin.agent-editor.groups.in-code' | translate }}</span>\n }\n </span>\n </label>\n }\n </div>\n }\n <p class=\"hint\" [id]=\"id + '-groups-error'\" aria-live=\"polite\">\n @if (groupsError(); as key) {\n <span class=\"error-text\">{{ key | translate }}</span>\n }\n </p>\n </fieldset>\n }\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\n @if (choosesProfile()) {\n <div class=\"field\" data-agent-profile>\n <label [for]=\"id + '-profile'\">{{ 'nh-assistant.admin.agent-editor.profile' | translate }}</label>\n <select\n [id]=\"id + '-profile'\"\n [attr.aria-describedby]=\"id + '-profile-hint' + (fieldError('profile') ? ' ' + id + '-profile-error' : '')\"\n [attr.aria-invalid]=\"fieldError('profile') ? true : null\"\n (change)=\"profile.set(value($event))\">\n @if (isNew()) {\n <option value=\"\" [selected]=\"profile() === ''\">{{ 'nh-assistant.admin.agent-editor.profile-default' | translate }}</option>\n }\n @for (name of profileChoices(); track name) {\n <option [value]=\"name\" [selected]=\"profile() === name\">{{ name }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-profile-hint'\">{{ 'nh-assistant.admin.agent-editor.profile-hint' | translate }}</p>\n @if (fieldError('profile'); as key) {\n <p class=\"hint\" [id]=\"id + '-profile-error'\"><span class=\"error-text\">{{ key | translate }}</span></p>\n }\n </div>\n }\n\n @if (choosesUse()) {\n <div class=\"field\" data-agent-classification>\n <label [for]=\"id + '-classification'\">{{ 'nh-assistant.admin.agent-editor.classification' | translate }}</label>\n <select\n [id]=\"id + '-classification'\"\n [attr.aria-describedby]=\"id + '-classification-hint' + (fieldError('dataClassification') ? ' ' + id + '-classification-error' : '')\"\n [attr.aria-invalid]=\"fieldError('dataClassification') ? true : null\"\n (change)=\"dataClassification.set($any(value($event)))\">\n @for (classification of classifications; track classification) {\n <option [value]=\"classification\" [selected]=\"dataClassification() === classification\">\n {{ 'nh-assistant.admin.run-config.skills.classification.' + classification | translate }}\n </option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-classification-hint'\">{{ 'nh-assistant.admin.agent-editor.classification-hint' | translate }}</p>\n @for (warning of warnings(); track warning) {\n <p class=\"message warning\" [attr.data-agent-editor-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('agent', warning) | nhAssistantTranslate: warning }}\n </p>\n }\n @if (fieldError('dataClassification'); as key) {\n <p class=\"hint\" [id]=\"id + '-classification-error'\"><span class=\"error-text\">{{ key | translate }}</span></p>\n }\n </div>\n }\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\n data-feedback-author\n [attr.title]=\"item.authorDisplayName ? ('nh-assistant.account-id-title' | translate: { id: item.authorActorId }) : null\">{{ 'nh-assistant.admin.feedback.author' | translate: { actor: item.authorDisplayName || ('nh-assistant.account-id' | translate: { id: 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 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 AgentRunFilter,\n AgentRunHistoryItem,\n AgentRunStatus,\n AgentSubjectType,\n NH_ASSISTANT_SYSTEM_SUBJECT_TYPE,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantCodeKeys as nhAssistantCodeKeys,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantSubjectLinkComponent as NhAssistantSubjectLinkComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantRunResultComponent } from '@newheap/platform-ai-chat/agent-runs';\n\nlet nextId = 0;\n\n/** The runs one page of the runs view loads. */\nconst pageSize = 20;\n\n/** The statuses a run can have, in the order the filter offers them. */\nconst statuses: readonly AgentRunStatus[] = ['completed', 'failed', 'cancelled', 'waiting-for-approval', 'running', 'queued'];\n\n/** A filter value as the form holds it: the empty string means \"any\". */\ninterface RunHistoryForm {\n subjectType: string;\n subjectId: string;\n status: AgentRunStatus | '';\n from: string;\n to: string;\n}\n\nconst emptyForm: RunHistoryForm = { subjectType: '', subjectId: '', status: '', from: '', to: '' };\n\n/** The filter fields the form shows; the server's errors of others stay with the form's error. */\nconst formFields = ['subjectType', 'subjectId', 'status', 'to'] as const;\n\n/**\n * The runs view of one agent for administrators (`GET admin/agents/{id}/runs`): every run of the\n * agent, shadow runs marked, newest first, filtered by the kind of object, one object, the whole\n * application, the status and the period. Per run its time, trigger, object, the beginning of its\n * result, its proposals, usage and duration; \"Show the result\" opens the run's whole result, its\n * proposals and its files in `nh-assistant-run-result`. The administration's agent cards open it with\n * \"Runs\". A filter the server refuses (`assistant-run-filter-invalid`) shows each refused part at its\n * field, and a run's failure reads as its translated code.\n */\n@Component({\n selector: 'nh-assistant-agent-run-history',\n standalone: true,\n imports: [\n DatePipe,\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantSubjectLinkComponent,\n NhAssistantRunResultComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-run-history.component.html',\n styleUrls: ['../nh-assistant-admin-shared.scss', './nh-assistant-agent-run-history.component.scss']\n})\nexport class NhAssistantAgentRunHistoryComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly injector = inject(Injector);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private subscription?: Subscription;\n\n /** The agent whose runs are shown. */\n readonly agentId = input.required<string>();\n /** The kinds of objects of the application, from the run catalog, to filter by. */\n readonly subjectTypes = input<readonly AgentSubjectType[]>([]);\n /** Emits the conversation of a run, so the host can open it in the assistant panel. */\n readonly openConversation = output<string>();\n\n readonly id = `nh-assistant-agent-run-history-${nextId++}`;\n readonly statuses = statuses;\n readonly systemType = NH_ASSISTANT_SYSTEM_SUBJECT_TYPE;\n /** The kinds of objects, the whole application left out: it has an option of its own. */\n readonly objectTypes = computed(() => this.subjectTypes().filter(type => !type.isSystem));\n readonly form = signal<RunHistoryForm>(emptyForm);\n /** The period ends before it starts. */\n readonly periodInvalid = signal(false);\n /** One object can be chosen once a kind of object is. */\n readonly objectChoosable = computed(() => {\n const type = this.form().subjectType;\n return type !== '' && type !== NH_ASSISTANT_SYSTEM_SUBJECT_TYPE;\n });\n readonly loading = signal(true);\n readonly loadingMore = signal(false);\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n /** The refused filter fields the form shows, with the server's first value per field. */\n readonly fieldErrors = computed<Partial<Record<string, string>>>(() => {\n const errors: Partial<Record<string, string>> = {};\n for (const field of formFields) {\n const value = this.error()?.fieldErrors?.[field]?.[0];\n if (value) {\n errors[field] = value;\n }\n }\n return errors;\n });\n readonly codeKeys = nhAssistantCodeKeys;\n readonly items = signal<AgentRunHistoryItem[]>([]);\n readonly total = signal(0);\n readonly page = signal(1);\n readonly hasMore = computed(() => this.items().length < this.total());\n /** The run whose whole result is shown instead of the list. */\n readonly opened = signal<AgentRunHistoryItem | null>(null);\n private applied: AgentRunFilter = {};\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n effect(() => {\n this.agentId();\n untracked(() => {\n this.opened.set(null);\n this.form.set(emptyForm);\n this.applied = {};\n this.fetch(1);\n });\n });\n }\n\n /** The text of the server's error of a filter field; a refused end of the period reads as such. */\n fieldErrorKeys(field: string): string[] {\n const value = this.fieldErrors()[field];\n if (!value) {\n return [];\n }\n const own = field === 'to' ? ['nh-assistant.admin.runs.period-invalid'] : [];\n return [...own, `nh-assistant.admin.run-config.field-errors.${value}`, 'nh-assistant.errors.generic'];\n }\n\n /** The ids a filter field describes itself with: its hint and its error while there is one. */\n describedBy(hintId: string | null, field: string): string | null {\n const ids = [hintId, this.fieldErrors()[field] ? `${this.id}-${field}-error` : null].filter((id): id is string => id !== null);\n return ids.length > 0 ? ids.join(' ') : null;\n }\n\n update(field: keyof RunHistoryForm, event: Event): void {\n const value = (event.target as HTMLInputElement | HTMLSelectElement).value;\n this.form.update(form => field === 'subjectType'\n // Another kind of object starts a new choice of object.\n ? { ...form, subjectType: value, subjectId: '' }\n : { ...form, [field]: value });\n if (field === 'from' || field === 'to') {\n this.periodInvalid.set(false);\n }\n }\n\n /** Reads the runs that match the form, from the first page. */\n apply(): void {\n const form = this.form();\n const from = form.from ? startOfDay(form.from) : undefined;\n // The last day counts in full: the period ends where the next day starts.\n const to = form.to ? startOfDay(form.to, 1) : undefined;\n if (from && to && Date.parse(to) <= Date.parse(from)) {\n this.periodInvalid.set(true);\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLInputElement>(`#${this.id}-to`)?.focus(), { injector: this.injector });\n return;\n }\n\n this.periodInvalid.set(false);\n this.applied = {\n subjectType: form.subjectType || undefined,\n subjectId: this.objectChoosable() ? form.subjectId.trim() || undefined : undefined,\n status: form.status || undefined,\n from,\n to\n };\n this.fetch(1);\n }\n\n /** Clears the filters and reads every run again. */\n clear(): void {\n this.form.set(emptyForm);\n this.periodInvalid.set(false);\n this.applied = {};\n this.fetch(1);\n }\n\n /** Narrows the view to the runs on the object of one run. */\n onlyObject(run: AgentRunHistoryItem): void {\n this.form.set({\n ...emptyForm,\n subjectType: run.subjectType,\n subjectId: run.subjectType === NH_ASSISTANT_SYSTEM_SUBJECT_TYPE ? '' : run.subjectId\n });\n this.apply();\n }\n\n loadMore(): void {\n this.fetch(this.page() + 1);\n }\n\n open(run: AgentRunHistoryItem): void {\n this.opened.set(run);\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLButtonElement>('[data-runs-back]')?.focus(), { injector: this.injector });\n }\n\n /** Returns to the list and to the result action of the run that was open. */\n close(): void {\n const runId = this.opened()?.id;\n this.opened.set(null);\n afterNextRender(() => {\n const action = Array.from(this.host.nativeElement.querySelectorAll<HTMLButtonElement>('[data-open-run]'))\n .find(item => item.dataset['openRun'] === runId);\n action?.focus();\n }, { injector: this.injector });\n }\n\n /** How long the run took, as a text key and its number; `null` while it runs. */\n durationOf(run: AgentRunHistoryItem): { key: string; value: number } | null {\n if (!run.startedAt || !run.endedAt) {\n return null;\n }\n\n const seconds = Math.max(0, Math.round((Date.parse(run.endedAt) - Date.parse(run.startedAt)) / 1000));\n return seconds < 120\n ? { key: 'nh-assistant.agent-runs.result.duration-seconds', value: seconds }\n : { key: 'nh-assistant.agent-runs.result.duration-minutes', value: Math.round(seconds / 60) };\n }\n\n /** Moves the focus to the first filter field the server refused. */\n private focusRefusedField(): void {\n if (Object.keys(this.fieldErrors()).length === 0) {\n return;\n }\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>('.filters [aria-invalid=\"true\"]')?.focus(), { injector: this.injector });\n }\n\n private fetch(page: number): void {\n const first = page === 1;\n this.loading.set(first);\n this.loadingMore.set(!first);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.getAgentRuns(this.agentId(), { ...this.applied, page, itemsPerPage: pageSize }).subscribe({\n next: history => {\n this.items.update(items => first ? history.items : [...items, ...history.items]);\n this.total.set(history.total);\n this.page.set(page);\n this.loading.set(false);\n this.loadingMore.set(false);\n },\n error: (failure: unknown) => {\n if (first) {\n this.items.set([]);\n this.total.set(0);\n }\n this.loading.set(false);\n this.loadingMore.set(false);\n this.error.set(toNhAssistantError(failure));\n this.focusRefusedField();\n }\n });\n }\n}\n\n/** The start of a day of the person's calendar, plus some days, as an ISO 8601 time. */\nfunction startOfDay(date: string, plusDays = 0): string {\n const [year, month, day] = date.split('-').map(Number);\n return new Date(year, month - 1, day + plusDays).toISOString();\n}\n","@if (opened(); as run) {\n <div class=\"stack\">\n <div>\n <button class=\"secondary\" type=\"button\" data-runs-back (click)=\"close()\">\n {{ 'nh-assistant.admin.runs.back-to-runs' | translate }}\n </button>\n </div>\n <nh-assistant-run-result [runId]=\"run.id\" (openConversation)=\"openConversation.emit($event)\" />\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.runs.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.runs.description' | translate }}</p>\n </div>\n </header>\n\n <form class=\"filters\" [attr.aria-label]=\"'nh-assistant.admin.runs.filters' | translate\" (submit)=\"$event.preventDefault(); apply()\">\n <div class=\"field\">\n <label [for]=\"id + '-type'\">{{ 'nh-assistant.admin.runs.subject-type' | translate }}</label>\n <select\n [id]=\"id + '-type'\"\n [attr.aria-invalid]=\"fieldErrors()['subjectType'] ? true : null\"\n [attr.aria-describedby]=\"describedBy(null, 'subjectType')\"\n (change)=\"update('subjectType', $event)\">\n <option value=\"\" [selected]=\"form().subjectType === ''\">{{ 'nh-assistant.admin.runs.any-subject' | translate }}</option>\n <option [value]=\"systemType\" [selected]=\"form().subjectType === systemType\">{{ 'nh-assistant.admin.runs.whole-application' | translate }}</option>\n @for (type of objectTypes(); track type.id) {\n <option [value]=\"type.id\" [selected]=\"form().subjectType === type.id\">{{ type.pluralName ?? type.name }}</option>\n }\n </select>\n @if (fieldErrors()['subjectType']) {\n <p class=\"field-error\" [id]=\"id + '-subjectType-error'\"><nh-assistant-icon name=\"warning\" />{{ fieldErrorKeys('subjectType') | nhAssistantTranslate }}</p>\n }\n </div>\n @if (objectChoosable()) {\n <div class=\"field\">\n <label [for]=\"id + '-object'\">{{ 'nh-assistant.admin.runs.subject-id' | translate }}</label>\n <input\n type=\"text\"\n autocomplete=\"off\"\n maxlength=\"200\"\n [id]=\"id + '-object'\"\n [attr.aria-describedby]=\"describedBy(id + '-object-hint', 'subjectId')\"\n [attr.aria-invalid]=\"fieldErrors()['subjectId'] ? true : null\"\n [value]=\"form().subjectId\"\n (input)=\"update('subjectId', $event)\" />\n <p class=\"hint\" [id]=\"id + '-object-hint'\"><span>{{ 'nh-assistant.admin.runs.subject-id-hint' | translate }}</span></p>\n @if (fieldErrors()['subjectId']) {\n <p class=\"field-error\" [id]=\"id + '-subjectId-error'\"><nh-assistant-icon name=\"warning\" />{{ fieldErrorKeys('subjectId') | nhAssistantTranslate }}</p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-status'\">{{ 'nh-assistant.admin.runs.status' | translate }}</label>\n <select\n [id]=\"id + '-status'\"\n [attr.aria-invalid]=\"fieldErrors()['status'] ? true : null\"\n [attr.aria-describedby]=\"describedBy(null, 'status')\"\n (change)=\"update('status', $event)\">\n <option value=\"\" [selected]=\"form().status === ''\">{{ 'nh-assistant.admin.runs.any-status' | translate }}</option>\n @for (status of statuses; track status) {\n <option [value]=\"status\" [selected]=\"form().status === status\">{{ 'nh-assistant.agent-runs.run.status.' + status | translate }}</option>\n }\n </select>\n @if (fieldErrors()['status']) {\n <p class=\"field-error\" [id]=\"id + '-status-error'\"><nh-assistant-icon name=\"warning\" />{{ fieldErrorKeys('status') | nhAssistantTranslate }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-from'\">{{ 'nh-assistant.admin.runs.from' | translate }}</label>\n <input type=\"date\" [id]=\"id + '-from'\" [value]=\"form().from\" (change)=\"update('from', $event)\" />\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-to'\">{{ 'nh-assistant.admin.runs.to' | translate }}</label>\n <input\n type=\"date\"\n [id]=\"id + '-to'\"\n [value]=\"form().to\"\n [attr.aria-invalid]=\"periodInvalid() || fieldErrors()['to'] ? true : null\"\n [attr.aria-describedby]=\"periodInvalid() || fieldErrors()['to'] ? id + '-to-error' : null\"\n (change)=\"update('to', $event)\" />\n @if (periodInvalid()) {\n <p class=\"field-error\" role=\"alert\" [id]=\"id + '-to-error'\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.runs.period-invalid' | translate }}</p>\n } @else if (fieldErrors()['to']) {\n <p class=\"field-error\" [id]=\"id + '-to-error'\"><nh-assistant-icon name=\"warning\" />{{ fieldErrorKeys('to') | nhAssistantTranslate }}</p>\n }\n </div>\n <div class=\"filter-actions\">\n <button class=\"primary\" type=\"submit\" [disabled]=\"loading()\">{{ 'nh-assistant.admin.runs.apply' | translate }}</button>\n <button class=\"secondary\" type=\"button\" [disabled]=\"loading()\" (click)=\"clear()\">{{ 'nh-assistant.admin.runs.clear' | translate }}</button>\n </div>\n </form>\n\n @if (error(); as failure) {\n <div class=\"state\" role=\"alert\">\n <p>{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"apply()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (items().length === 0) {\n <p class=\"state\" data-runs-empty>{{ 'nh-assistant.admin.runs.empty' | translate }}</p>\n } @else {\n <p class=\"muted\" role=\"status\" data-runs-count>{{ 'nh-assistant.admin.runs.count' | translate: { shown: items().length, total: total() } }}</p>\n <ol class=\"cards\" [attr.aria-labelledby]=\"id + '-title'\">\n @for (run of items(); track run.id) {\n <li class=\"card\" [attr.data-run]=\"run.id\">\n <div class=\"card-header\">\n <strong><time [attr.datetime]=\"run.createdAt\">{{ run.createdAt | date: 'medium' }}</time></strong>\n <span\n class=\"badge\"\n [class.success]=\"run.status === 'completed'\"\n [class.warning]=\"run.status === 'waiting-for-approval' || run.status === 'queued' || run.status === 'running'\"\n [class.danger]=\"run.status === 'failed'\">{{ 'nh-assistant.agent-runs.run.status.' + run.status | translate }}</span>\n @if (run.shadow) {\n <span class=\"badge warning\" data-run-shadow>{{ 'nh-assistant.agent-runs.run.shadow' | translate }}</span>\n }\n @if (run.kind !== 'model') {\n <span class=\"badge\">{{ 'nh-assistant.agent-runs.run.kind.' + run.kind | translate }}</span>\n }\n <span class=\"mono muted\">{{ 'nh-assistant.agent-runs.run.trigger' | translate: { trigger: run.triggerId } }}</span>\n </div>\n <p class=\"run-subject\">\n <nh-assistant-subject-link\n [subjectType]=\"run.subjectType\"\n [subjectId]=\"run.subjectId\"\n [label]=\"run.subjectDisplayName ?? run.subjectId\"\n [typeName]=\"run.subjectTypeName\"\n [link]=\"run.subjectLink\" />\n </p>\n <!-- The beginning of the result is model output, shown as text. -->\n @if (run.result; as result) {\n <p class=\"run-preview\" data-run-preview>{{ result }}@if (run.resultTruncated) {…}</p>\n } @else {\n <p class=\"muted\">{{ 'nh-assistant.agent-runs.object-agents.no-result' | translate }}</p>\n }\n <div class=\"meta\">\n <span>{{ 'nh-assistant.agent-runs.run.proposals' | translate: { count: run.proposalCount } }}</span>\n <span>{{ 'nh-assistant.agent-runs.run.tool-calls' | translate: { count: run.toolCalls } }}</span>\n <span>{{ 'nh-assistant.agent-runs.run.tokens' | translate: { count: run.inputTokens + run.outputTokens } }}</span>\n @if (durationOf(run); as took) {\n <span data-run-duration>{{ took.key | translate: { count: took.value } }}</span>\n }\n @if (run.failureCode; as code) {\n <span data-run-failure>{{ codeKeys(code) | nhAssistantTranslate: code }}</span>\n }\n @if (run.mcpConnectionSkips?.length) {\n <span class=\"badge warning\" data-run-mcp-skips>{{ 'nh-assistant.agent-runs.run.mcp-skipped' | translate: { count: run.mcpConnectionSkips?.length } }}</span>\n }\n </div>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [attr.data-open-run]=\"run.id\" (click)=\"open(run)\">\n <nh-assistant-icon name=\"page\" />{{ 'nh-assistant.agent-runs.result.show' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" data-only-object (click)=\"onlyObject(run)\">\n <nh-assistant-icon name=\"list\" />{{ (run.subjectType === systemType ? 'nh-assistant.admin.runs.only-application' : 'nh-assistant.admin.runs.only-object') | translate }}\n </button>\n </div>\n </li>\n }\n </ol>\n @if (hasMore()) {\n <div>\n <button class=\"secondary\" type=\"button\" data-runs-more [disabled]=\"loadingMore()\" (click)=\"loadMore()\">\n {{ (loadingMore() ? 'nh-assistant.admin.loading' : 'nh-assistant.admin.runs.more') | translate }}\n </button>\n </div>\n }\n }\n </section>\n}\n","import { WritableSignal, signal } from '@angular/core';\nimport {\n ApprovalPolicySummary,\n AssistantDataClassification,\n FileLimits,\n LowerFileLimits,\n NhAssistantError,\n RunCatalog,\n ToolCatalogEntry,\n ɵNhAssistantPickerOption as NhAssistantPickerOption\n} from '@newheap/platform-ai-chat';\nimport { nhAssistantSelectorMatches } from '../nh-assistant-admin-agent-editor.component';\n\n/** The longest texts and numbers the server accepts in the run configuration. */\nexport const runConfigLimits = {\n reason: 500,\n description: 300,\n instructions: 20_000,\n message: 2_000,\n retries: [0, 10],\n concurrent: [1, 100],\n perSubject: [1, 1000],\n debounce: [0, 3600]\n} as const;\n\nexport const dashCase = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;\n\n/** A field error: a code such as `required`, with its translation parameters. */\nexport interface RunConfigFieldError {\n code: string;\n params?: Record<string, unknown>;\n}\n\nexport type RunConfigErrors = Record<string, RunConfigFieldError>;\n\n/** The translation key of a field error code, shared by the forms. */\nexport function fieldErrorKey(error: RunConfigFieldError | null | undefined): string | null {\n return error ? `nh-assistant.admin.run-config.field-errors.${error.code}` : null;\n}\n\n/**\n * The field errors of a refused save, by field; the server's codes are `required`, `invalid`,\n * `too-long` and `not-found`.\n */\nexport function serverFieldErrors(error: NhAssistantError | null): RunConfigErrors {\n const result: RunConfigErrors = {};\n for (const [field, codes] of Object.entries(error?.fieldErrors ?? {})) {\n if (codes.length > 0) {\n result[field] = { code: codes[0] };\n }\n }\n return result;\n}\n\n/** Requires text, optionally within a length. */\nexport function requireText(errors: RunConfigErrors, field: string, value: string, max?: number): void {\n const text = value.trim();\n if (text.length === 0) {\n errors[field] = { code: 'required' };\n } else if (max !== undefined && text.length > max) {\n errors[field] = { code: 'too-long', params: { max } };\n }\n}\n\n/** Accepts an empty value or a whole number within the range. */\nexport function checkWhole(errors: RunConfigErrors, field: string, value: string, min: number, max?: number, required = false): void {\n const text = value.trim();\n if (text.length === 0) {\n if (required) {\n errors[field] = { code: 'required' };\n }\n return;\n }\n const parsed = Number(text);\n if (!Number.isInteger(parsed) || parsed < min || (max !== undefined && parsed > max)) {\n errors[field] = max === undefined\n ? { code: 'at-least', params: { min } }\n : { code: 'between', params: { min, max } };\n }\n}\n\n/** A daily budget limits both tool calls and tokens, or neither. */\nexport function checkBudget(errors: RunConfigErrors, calls: string, tokens: string): void {\n checkWhole(errors, 'dailyToolCalls', calls, 1);\n checkWhole(errors, 'dailyTokens', tokens, 1);\n if ((calls.trim() === '') !== (tokens.trim() === '') && !errors['dailyToolCalls'] && !errors['dailyTokens']) {\n errors[calls.trim() === '' ? 'dailyToolCalls' : 'dailyTokens'] = { code: 'budget-pair' };\n }\n}\n\n/**\n * The server reports one `dailyBudget` error for both budget fields; the forms show it at the field\n * that is filled in least.\n */\nexport function withBudgetField(errors: RunConfigErrors, calls: string): RunConfigErrors {\n const budget = errors['dailyBudget'];\n if (!budget) {\n return errors;\n }\n const { dailyBudget: _, ...rest } = errors;\n return { ...rest, [calls.trim() === '' ? 'dailyToolCalls' : 'dailyTokens']: budget };\n}\n\n/**\n * Moves the focus to the first invalid control of a form, after Angular rendered the errors; a\n * picker's text field carries `aria-invalid` too.\n */\nexport function focusFirstInvalid(form: HTMLElement | null | undefined): void {\n const invalid = form?.querySelector<HTMLElement>('[aria-invalid=\"true\"]');\n invalid?.focus();\n invalid?.scrollIntoView?.({ block: 'center' });\n}\n\nexport function ruleOptions(catalog: RunCatalog | null): NhAssistantPickerOption[] {\n return (catalog?.ruleHandlers ?? []).map(block => ({ value: block.name, label: block.name, description: block.description }));\n}\n\n/** The platform's object type of the whole application. */\nexport const systemSubjectType = 'nh-system';\n\n/** What an agent works on, as far as the trigger events and schedules it is offered depend on it. */\nexport interface WorksOnStatement {\n worksOnSubjectTypes?: string[];\n worksOnAllSubjects?: boolean;\n worksOnApplication?: boolean;\n /** Its work for the whole application, such as a schedule without a subject set, runs once per division. */\n perDivision?: boolean;\n}\n\n/** Whether an agent works on subjects of the type, as the server's rule decides it. */\nexport function worksOnCovers(statement: WorksOnStatement | null | undefined, subjectType: string): boolean {\n if (subjectType === systemSubjectType) {\n return statement?.worksOnApplication === true;\n }\n if (subjectType.startsWith('nh-')) {\n return false;\n }\n return !statement || statement.worksOnAllSubjects !== false || (statement.worksOnSubjectTypes ?? []).includes(subjectType);\n}\n\n/**\n * The trigger events an agent can start on: an event that names its object type up front is offered\n * only to an agent that works on that type.\n */\nexport function eventOptions(catalog: RunCatalog | null, worksOn?: WorksOnStatement | null): NhAssistantPickerOption[] {\n return (catalog?.triggerEvents ?? [])\n .filter(block => !block.subjectType || worksOnCovers(worksOn, block.subjectType))\n .map(block => ({ value: block.name, label: block.name, description: block.description }));\n}\n\nexport function subjectSetOptions(catalog: RunCatalog | null): NhAssistantPickerOption[] {\n return (catalog?.subjectSets ?? []).map(block => ({ value: block.name, label: block.name, description: block.description }));\n}\n\n/**\n * What a schedule runs for each time: the whole application (once, or once per division for an\n * agent that works per division), or every object in a subject set.\n */\nexport type ScheduleTarget = 'application' | 'set';\n\n/**\n * The server refuses a schedule without a subject set with `subjectSet: required` when the agent\n * does not work on the whole application; a form that chose the whole application says why there.\n */\nexport function withScheduleTargetError(errors: RunConfigErrors, target: ScheduleTarget): RunConfigErrors {\n return target === 'application' && errors['subjectSet']\n ? { ...errors, subjectSet: { code: 'application-not-worked-on' } }\n : errors;\n}\n\n/** The data classifications a skill can choose, from the least to the most sensitive. */\nexport const dataClassifications: readonly AssistantDataClassification[] = ['public', 'internal', 'confidential', 'restricted'];\n\nexport function profileOptions(catalog: RunCatalog | null): NhAssistantPickerOption[] {\n return (catalog?.profiles ?? []).map(profile => ({ value: profile, label: profile }));\n}\n\n/** The approval policies, each with its summary when the server sent one. */\nexport function policyOptions(catalog: RunCatalog | null, describe: (summary: ApprovalPolicySummary) => string): NhAssistantPickerOption[] {\n const summaries = new Map((catalog?.approvalPolicySummaries ?? []).map(summary => [summary.name, summary]));\n return (catalog?.approvalPolicies ?? []).map(policy => {\n const summary = summaries.get(policy);\n return { value: policy, label: policy, description: summary ? describe(summary) : null };\n });\n}\n\n/** The IANA time zones of the browser, UTC first. */\nexport function timeZoneOptions(): NhAssistantPickerOption[] {\n const intl = Intl as unknown as { supportedValuesOf?: (key: string) => string[] };\n const zones = intl.supportedValuesOf?.('timeZone') ?? ['Europe/Amsterdam', 'Europe/London'];\n return ['UTC', ...zones.filter(zone => zone !== 'UTC')].map(zone => ({ value: zone, label: zone }));\n}\n\n/** Common schedules, as examples next to the cron field. */\nexport const cronExamples: readonly { cron: string; key: string }[] = [\n { cron: '0 8 * * 1-5', key: 'weekdays-8' },\n { cron: '0 7 * * *', key: 'daily-7' },\n { cron: '0 9 * * 1', key: 'monday-9' },\n { cron: '0 * * * *', key: 'hourly' }\n];\n\n/** One of the agent's tool selectors with what it offers, for the tool choice of a skill. */\nexport interface ToolChoice {\n selector: string;\n /** The tool's description, for a selector that names one tool of the catalog. */\n description: string | null;\n /** How many tools of the catalog a pattern matches; `null` for a single tool. */\n matches: number | null;\n}\n\n/** The agent's tool selectors with the description of their tool, or how many tools a pattern matches. */\nexport function toolChoices(selectors: readonly string[], catalog: readonly ToolCatalogEntry[]): ToolChoice[] {\n return selectors.map(selector => {\n if (selector.includes('*')) {\n return { selector, description: null, matches: catalog.filter(tool => nhAssistantSelectorMatches(tool.id, selector)).length };\n }\n const tool = catalog.find(item => item.id === selector);\n return { selector, description: tool?.description || null, matches: null };\n });\n}\n\nexport function blank(value: string): string | null {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nexport function toNumber(value: string): number | null {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n return null;\n }\n const parsed = Number(trimmed);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nexport function numberText(value: number | null | undefined): string {\n return value === null || value === undefined ? '' : String(value);\n}\n\n/** A readable id from a name: lowercase letters, digits and dashes. */\nexport function toDashCase(name: string): string {\n return name\n .normalize('NFKD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .replace(/^[0-9-]+/, '')\n .slice(0, 64)\n .replace(/-+$/, '');\n}\n\ntype Translate = (key: string, params?: Record<string, unknown>) => string;\n\n/**\n * An approval policy in one or two sentences: who decides, how long a proposal waits, whether the\n * run waits, and four eyes.\n */\nexport function describePolicy(summary: ApprovalPolicySummary, t: Translate): string {\n const base = 'nh-assistant.admin.run-config.policy-summary';\n const approvers = summary.approvers.map(approver => {\n switch (approver.kind) {\n case 'initiator':\n return t(`${base}.approver.initiator`);\n case 'subject-role':\n return approver.namedRole\n ? t(`${base}.approver.named-role`, { role: approver.namedRole })\n : t(`${base}.approver.subject-role.${approver.role ?? 'approver'}`);\n case 'policy':\n return t(`${base}.approver.policy`, { policy: approver.policy ?? '' });\n default:\n return approver.kind;\n }\n });\n const who = approvers.length === 0\n ? t(`${base}.nobody`)\n : t(`${base}.who`, { approvers: joinWithOr(approvers, t(`${base}.or`)) });\n const parts = [\n who,\n t(`${base}.wait`, { duration: describeDuration(summary.lifetimeMinutes, t) }),\n t(`${base}.mode.${summary.mode === 'deferred' ? 'deferred' : 'inline'}`)\n ];\n if (summary.fourEyes) {\n parts.push(t(`${base}.four-eyes`));\n }\n return parts.join(' ');\n}\n\nfunction joinWithOr(items: string[], or: string): string {\n return items.length <= 1 ? items.join('') : `${items.slice(0, -1).join(', ')} ${or} ${items[items.length - 1]}`;\n}\n\nfunction describeDuration(minutes: number, t: Translate): string {\n const base = 'nh-assistant.admin.run-config.policy-summary.duration';\n if (minutes >= 1440 && minutes % 1440 === 0) {\n const days = minutes / 1440;\n return t(days === 1 ? `${base}.day` : `${base}.days`, { count: days });\n }\n if (minutes >= 60 && minutes % 60 === 0) {\n const hours = minutes / 60;\n return t(hours === 1 ? `${base}.hour` : `${base}.hours`, { count: hours });\n }\n return t(minutes === 1 ? `${base}.minute` : `${base}.minutes`, { count: minutes });\n}\n\n/** The bytes of one megabyte, as the forms show a file size. */\nconst bytesPerMegabyte = 1024 * 1024;\n\n/** The lower file limits of an agent or a skill, as their fields name them on the server. */\nexport type FileLimitField = keyof FileLimits;\n\n/** The file limit fields in the order the forms show them. */\nexport const fileLimitFields: readonly FileLimitField[] = ['maxFileBytes', 'maxFilePages', 'maxFilesPerTurn', 'maxFileTokensPerTurn'];\n\n/** A size in megabytes as a form shows it: whole megabytes plainly, others with up to two decimals. */\nexport function megabytesText(bytes: number): string {\n const megabytes = bytes / bytesPerMegabyte;\n return Number.isInteger(megabytes) ? String(megabytes) : String(Math.round(megabytes * 100) / 100);\n}\n\n/**\n * The lower file limits of an agent or a skill as a form edits them: the largest file in megabytes,\n * the others as whole numbers; an empty field keeps the application's limit (for a skill, the\n * agent's). A size shown with decimals keeps its exact bytes until the administrator changes it.\n */\nexport class FileLimitsDraft {\n readonly megabytes = signal('');\n readonly pages = signal('');\n readonly files = signal('');\n readonly tokens = signal('');\n private loadedBytes: number | null = null;\n private loadedMegabytes = '';\n\n load(limits: LowerFileLimits | null | undefined): void {\n this.loadedBytes = limits?.maxFileBytes ?? null;\n this.loadedMegabytes = this.loadedBytes === null ? '' : megabytesText(this.loadedBytes);\n this.megabytes.set(this.loadedMegabytes);\n this.pages.set(numberText(limits?.maxFilePages));\n this.files.set(numberText(limits?.maxFilesPerTurn));\n this.tokens.set(numberText(limits?.maxFileTokensPerTurn));\n }\n\n /** The text of a field, by its server name. */\n text(field: FileLimitField): WritableSignal<string> {\n switch (field) {\n case 'maxFileBytes':\n return this.megabytes;\n case 'maxFilePages':\n return this.pages;\n case 'maxFilesPerTurn':\n return this.files;\n default:\n return this.tokens;\n }\n }\n\n /** Checks the fields against the application's limits, as the server does; only next to accepting files. */\n check(errors: RunConfigErrors, application: FileLimits | null | undefined): void {\n const bytes = this.bytes();\n if (this.megabytes().trim() !== '' && (bytes === null || bytes < 1 || (application && bytes > application.maxFileBytes))) {\n errors['maxFileBytes'] = application\n ? { code: 'megabytes-up-to', params: { max: megabytesText(application.maxFileBytes) } }\n : { code: 'megabytes-positive' };\n }\n checkWhole(errors, 'maxFilePages', this.pages(), 1, application?.maxFilePages);\n checkWhole(errors, 'maxFilesPerTurn', this.files(), 1, application?.maxFilesPerTurn);\n checkWhole(errors, 'maxFileTokensPerTurn', this.tokens(), 1, application?.maxFileTokensPerTurn);\n }\n\n /** The limits a save sends: none when the agent or skill accepts no files. */\n toRequest(acceptsFiles: boolean): Required<LowerFileLimits> {\n return {\n maxFileBytes: acceptsFiles ? this.bytes() : null,\n maxFilePages: acceptsFiles ? toNumber(this.pages()) : null,\n maxFilesPerTurn: acceptsFiles ? toNumber(this.files()) : null,\n maxFileTokensPerTurn: acceptsFiles ? toNumber(this.tokens()) : null\n };\n }\n\n private bytes(): number | null {\n const text = this.megabytes().trim();\n if (text === '') {\n return null;\n }\n if (text === this.loadedMegabytes && this.loadedBytes !== null) {\n return this.loadedBytes;\n }\n const megabytes = Number(text.replace(',', '.'));\n return Number.isFinite(megabytes) ? Math.round(megabytes * bytesPerMegabyte) : null;\n }\n}\n","import {\n AdminAgent,\n AgentAccountability,\n AgentRunConfiguration,\n DataTrigger,\n McpHeadlessUse,\n McpServer,\n RunCatalog,\n RunConfigurationProblem,\n ToolCatalogEffect,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport { nhAssistantSelectorMatches } from '../nh-assistant-admin-agent-editor.component';\nimport { systemSubjectType } from './run-config-shared';\n\n/**\n * The flow view of an agent: what it works on, when it runs, how it works, who it answers to, who\n * approves its proposals and its results. Each step summarizes what the run configuration, the agent\n * editor and the runs view hold and opens the form that changes it; the flow itself edits nothing.\n */\nexport type AgentFlowStepId = 'works-on' | 'when' | 'skills' | 'account' | 'approval' | 'results';\n\nexport const agentFlowSteps: readonly AgentFlowStepId[] = ['works-on', 'when', 'skills', 'account', 'approval', 'results'];\n\n/**\n * What an entry point of the flow opens: the run configuration opens its own forms; the agent editor,\n * the technical account, the runs view and the MCP servers belong to the page that hosts it.\n */\nexport type AgentFlowEntry =\n | { kind: 'setup' }\n | { kind: 'settings' }\n | { kind: 'add-skill' }\n | { kind: 'edit-skill'; skillId: string }\n | { kind: 'add-trigger' }\n | { kind: 'edit-trigger'; triggerId: string }\n | { kind: 'edit-agent' }\n | { kind: 'account' }\n | { kind: 'runs' }\n | { kind: 'mcp-servers' };\n\n/** Something in a step that no longer fits or keeps the agent from working, with the form that fixes it. */\nexport interface AgentFlowWarning {\n /** Translation key of the warning and its parameters. */\n key: string;\n params?: Record<string, unknown>;\n /** A second translation key that explains it, such as a problem's code. */\n detailKey?: string;\n /** The entry point that fixes it and the key of its label. */\n entry?: AgentFlowEntry;\n entryKey?: string;\n /** Tells several warnings with the same entry apart, for tracking. */\n id: string;\n}\n\n/**\n * What a trigger runs for each time it starts the agent: the whole application (once per division for\n * an agent that works per division), objects of a type (`value` names the type), every object of a\n * subject set (`value` names the set) or of a set in code, or the object the event names when it fires.\n */\nexport interface AgentFlowTarget {\n kind: 'application' | 'every-division' | 'type' | 'set' | 'code-set' | 'when-fired';\n value: string | null;\n}\n\n/** A trigger in code or as data, as the flow lists it. */\nexport interface AgentFlowTrigger {\n triggerId: string;\n origin: 'code' | 'data';\n source: 'event' | 'schedule' | 'webhook';\n /** The event, or the schedule with its time zone; `null` for a trigger in code. */\n detail: string | null;\n target: AgentFlowTarget;\n skillId: string | null;\n /** A trigger as data in shadow; `false` for a trigger in code, which follows the agent. */\n shadow: boolean;\n inEffect: boolean;\n}\n\n/** One tool of the agent's own tools, and where a run's proposals of it wait. */\nexport interface AgentFlowTool {\n id: string;\n description: string;\n effect: ToolCatalogEffect;\n /** The name of the object type a run places the tool's proposals at; `null` when it declares none. */\n placesAt: string | null;\n}\n\n/** The tools the agent's selectors choose from the catalog, without its MCP servers. */\nexport interface AgentFlowTools {\n tools: AgentFlowTool[];\n /** Tools the selectors choose beyond those listed. */\n more: number;\n /** Selectors that choose no tool of the catalog: those tools are no longer offered. */\n unmatched: string[];\n /** Whether the catalog was known; without it, the selectors are listed as they are. */\n known: boolean;\n}\n\n/**\n * Whether an MCP server's tools are offered in runs that start without a person, given the server's\n * background use and whom the agent answers to.\n */\nexport type AgentFlowServerUse =\n | 'unknown'\n | 'missing'\n | 'disabled'\n | 'never'\n | 'organization'\n | 'organization-grant'\n | 'personal'\n | 'personal-responsible'\n | 'personal-initiator'\n | 'personal-never-account'\n | 'personal-never-agent';\n\nexport interface AgentFlowServer {\n id: string;\n name: string;\n headlessUse: McpHeadlessUse | null;\n use: AgentFlowServerUse;\n}\n\n/** Whom an agent answers to, as its run settings (data) or its code say; `null` while unknown. */\nexport interface AgentFlowAccountability {\n accountability: AgentAccountability;\n delegateFromInitiator: boolean;\n}\n\n/**\n * Whether people can run the agent now, by the rule of runs by hand: it runs on its own, is neither\n * stopped nor disabled in code, has run settings and the run catalog names what it runs on.\n */\nexport type AgentFlowRunNow =\n | { available: true; paused: boolean }\n | { available: false; reason: 'stopped' | 'configured-off' | 'no-settings' | 'no-catalog' };\n\n/** The most tools the flow lists before it counts the rest. */\nexport const agentFlowToolLimit = 8;\n\n/** The run setting problems that concern the way of working or the approval instead of the account. */\nconst skillProblems = new Set(['unknown-rule-handler', 'unknown-profile']);\n\n/** Whom the agent answers to, from its run settings as data or from its code; `null` while unknown. */\nexport function flowAccountability(configuration: AgentRunConfiguration): AgentFlowAccountability | null {\n const settings = configuration.source === 'admin' ? configuration.runSettings : configuration.codeRunSettings;\n return settings ? { accountability: settings.accountability, delegateFromInitiator: settings.delegateFromInitiator } : null;\n}\n\n/** The step a problem of the run configuration concerns. */\nexport function problemStep(problem: RunConfigurationProblem): AgentFlowStepId {\n switch (problem.kind) {\n case 'trigger':\n return 'when';\n case 'skill':\n case 'candidate':\n return 'skills';\n default:\n if (problem.code === 'unknown-policy') {\n return 'approval';\n }\n return skillProblems.has(problem.code) ? 'skills' : 'account';\n }\n}\n\n/** A problem as a warning on its step, with the form that fixes it. */\nexport function problemWarning(problem: RunConfigurationProblem, configuration: AgentRunConfiguration): AgentFlowWarning {\n const base = {\n id: `problem:${problem.kind}:${problem.id}:${problem.code}`,\n key: `nh-assistant.admin.run-config.problems.kind.${problem.kind}`,\n params: { id: problem.id },\n detailKey: `nh-assistant.admin.run-config.problems.code.${problem.code}`\n };\n switch (problem.kind) {\n case 'trigger':\n return configuration.dataTriggers.some(trigger => trigger.triggerId === problem.id)\n ? { ...base, entry: { kind: 'edit-trigger', triggerId: problem.id }, entryKey: 'nh-assistant.admin.run-config.flow.entry.edit-trigger' }\n : base;\n case 'skill':\n case 'candidate':\n return configuration.dataSkills.some(skill => skill.skillId === problem.id)\n ? { ...base, entry: { kind: 'edit-skill', skillId: problem.id }, entryKey: 'nh-assistant.admin.run-config.flow.entry.edit-skill' }\n : base;\n default:\n return configuration.source === 'admin' && configuration.runSettings\n ? { ...base, entry: { kind: 'settings' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.settings' }\n : base;\n }\n}\n\n/** The name of an object type as the run catalog gives it in the reader's language; the id otherwise. */\nexport function typeName(catalog: RunCatalog | null, subjectType: string, plural = false): string {\n const type = catalog?.subjectTypes?.find(item => item.id === subjectType);\n if (!type) {\n return subjectType;\n }\n return plural ? type.pluralName ?? type.name : type.name;\n}\n\n/** The triggers in code and as data with what each runs for. */\nexport function flowTriggers(configuration: AgentRunConfiguration, catalog: RunCatalog | null, agent: AdminAgent): AgentFlowTrigger[] {\n const application: AgentFlowTarget = { kind: agent.perDivision === true ? 'every-division' : 'application', value: null };\n const ofType = (subjectType: string | null | undefined, schedule: boolean): AgentFlowTarget => {\n if (subjectType === systemSubjectType) {\n return application;\n }\n if (subjectType) {\n return { kind: 'type', value: typeName(catalog, subjectType) };\n }\n return { kind: schedule ? 'code-set' : 'when-fired', value: null };\n };\n\n const code = configuration.codeTriggers.map((trigger): AgentFlowTrigger => ({\n triggerId: trigger.triggerId,\n origin: 'code',\n source: trigger.source,\n detail: null,\n target: ofType(trigger.subjectType, trigger.source === 'schedule'),\n skillId: trigger.skillId,\n shadow: false,\n inEffect: true\n }));\n const data = configuration.dataTriggers.map((trigger): AgentFlowTrigger => ({\n triggerId: trigger.triggerId,\n origin: 'data',\n source: trigger.source,\n detail: triggerDetail(trigger),\n target: trigger.source === 'event'\n ? ofType(catalog?.triggerEvents.find(block => block.name === trigger.event)?.subjectType, false)\n : trigger.subjectSet ? { kind: 'set', value: trigger.subjectSet } : application,\n skillId: trigger.skillId,\n shadow: trigger.shadow,\n inEffect: trigger.inEffect\n }));\n return [...code, ...data];\n}\n\nfunction triggerDetail(trigger: DataTrigger): string | null {\n return trigger.source === 'event' ? trigger.event : `${trigger.cron ?? ''} ${trigger.timeZone ?? 'UTC'}`.trim();\n}\n\n/**\n * The tools the agent's selectors choose from the catalog. MCP tools come from the agent's servers,\n * so the flow lists those per server; a selector that chooses only MCP tools still counts as matched.\n * Without a catalog the selectors stay as they are and nothing reads as missing.\n */\nexport function flowTools(\n selectors: readonly string[],\n catalog: readonly ToolCatalogEntry[],\n runCatalog: RunCatalog | null,\n limit = agentFlowToolLimit\n): AgentFlowTools {\n if (catalog.length === 0) {\n return { tools: [], more: 0, unmatched: [], known: false };\n }\n\n const chosen = new Map<string, ToolCatalogEntry>();\n const unmatched: string[] = [];\n for (const selector of selectors) {\n const matches = catalog.filter(tool => nhAssistantSelectorMatches(tool.id, selector));\n if (matches.length === 0) {\n unmatched.push(selector);\n }\n for (const tool of matches) {\n if (tool.source !== 'mcp') {\n chosen.set(tool.id, tool);\n }\n }\n }\n\n const tools = [...chosen.values()]\n .sort((left, right) => left.id.localeCompare(right.id))\n .map((tool): AgentFlowTool => ({\n id: tool.id,\n description: tool.description,\n effect: tool.effect,\n placesAt: tool.subjectType ? typeName(runCatalog, tool.subjectType) : null\n }));\n return { tools: tools.slice(0, limit), more: Math.max(0, tools.length - limit), unmatched, known: true };\n}\n\n/**\n * The agent's MCP servers with whether their tools are offered in runs that start without a person:\n * a server's background use (`never`, `organization`, `personal`) decides, and for `personal` also\n * whom the agent answers to. A run of an agent that answers to itself uses an organization's\n * credential only with a grant in code; a personal connection serves the person the run acts for,\n * with that person's consent, and never a technical account. Without the servers nothing is known.\n */\nexport function flowServers(\n serverIds: readonly string[],\n servers: readonly McpServer[] | null,\n accountability: AgentFlowAccountability | null\n): AgentFlowServer[] {\n return serverIds.map(id => {\n if (servers === null) {\n return { id, name: id, headlessUse: null, use: 'unknown' };\n }\n const server = servers.find(item => item.id === id);\n if (!server) {\n return { id, name: id, headlessUse: null, use: 'missing' };\n }\n return { id, name: server.displayName, headlessUse: server.headlessUse, use: serverUse(server, accountability) };\n });\n}\n\nfunction serverUse(server: McpServer, accountability: AgentFlowAccountability | null): AgentFlowServerUse {\n if (!server.isEnabled) {\n return 'disabled';\n }\n switch (server.headlessUse) {\n case 'organization':\n return accountability?.accountability === 'agent' ? 'organization-grant' : 'organization';\n case 'personal':\n return personalUse(accountability);\n default:\n return 'never';\n }\n}\n\nfunction personalUse(accountability: AgentFlowAccountability | null): AgentFlowServerUse {\n if (!accountability) {\n return 'personal';\n }\n switch (accountability.accountability) {\n case 'subject-responsible':\n return 'personal-responsible';\n case 'service-account':\n return accountability.delegateFromInitiator ? 'personal-initiator' : 'personal-never-account';\n default:\n return accountability.delegateFromInitiator ? 'personal-initiator' : 'personal-never-agent';\n }\n}\n\n/** Server uses that keep its tools out of runs that start without a person. */\nexport const unavailableServerUses: ReadonlySet<AgentFlowServerUse> = new Set([\n 'missing',\n 'disabled',\n 'never',\n 'personal-never-account',\n 'personal-never-agent'\n]);\n\n/**\n * Whether the agent can be run now, by the rule the server applies to runs by hand: it is neither\n * stopped nor disabled in code, an agent created here has run settings, and the run catalog names\n * what it runs on. A paused agent accepts the run, which waits until it is resumed; an agent that is\n * off runs it at once, because it only ignores the work it would take on by itself.\n */\nexport function flowRunNow(agent: AdminAgent, configuration: AgentRunConfiguration, catalog: RunCatalog | null): AgentFlowRunNow {\n if (agent.runState === 'configured-off') {\n return { available: false, reason: 'configured-off' };\n }\n if (agent.runState === 'stopped') {\n return { available: false, reason: 'stopped' };\n }\n if (configuration.source === 'admin' && configuration.runSettings === null) {\n return { available: false, reason: 'no-settings' };\n }\n if (catalog === null) {\n return { available: false, reason: 'no-catalog' };\n }\n return { available: true, paused: agent.runState === 'paused' };\n}\n","import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n OnInit,\n computed,\n inject,\n input,\n output,\n signal\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport { Subscription, map, startWith } from 'rxjs';\nimport {\n AdminAgent,\n AgentRunConfiguration,\n AgentRunHistory,\n McpServer,\n NhAssistantAdminApiService,\n NhAssistantError,\n NhAssistantPanelService,\n RunCatalog,\n ToolCatalogEntry,\n ɵnhAssistantCodeKeys as nhAssistantCodeKeys,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantSubjectLinkComponent as NhAssistantSubjectLinkComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport {\n ɵNhAssistantRunNowDialogComponent as NhAssistantRunNowDialogComponent,\n type ɵNhAssistantRunNowAgent as NhAssistantRunNowAgent\n} from '@newheap/platform-ai-chat/agent-runs';\nimport { codeTextKeys, policyKeys, readableId, runNowAgentOf, skillDescriptionKeys, skillNameKeys, worksOnSummary } from '../agent-texts';\nimport {\n AgentFlowEntry,\n AgentFlowServerUse,\n AgentFlowStepId,\n AgentFlowWarning,\n agentFlowSteps,\n flowAccountability,\n flowRunNow,\n flowServers,\n flowTools,\n flowTriggers,\n problemStep,\n problemWarning,\n unavailableServerUses\n} from './agent-flow';\nimport { NhAssistantAccountLabelComponent } from '../../nh-assistant-account-names';\nimport { describePolicy } from './run-config-shared';\n\nlet nextId = 0;\n\n/** The most recent runs the flow shows; the runs view lists the rest. */\nconst latestRunCount = 3;\n\n/** One approval policy with its sentence, of the agent or of one of its skills. */\ninterface FlowPolicy {\n /** The skill whose own policy it is; `null` for the agent's. */\n skillId: string | null;\n /** The policy's name; `null` for the application's default. */\n name: string | null;\n sentence: string | null;\n}\n\n/**\n * The flow view of an agent at the top of its run configuration: what it works on, when it runs (its\n * triggers with what each runs for, and run now), how it works (its way of working, skills and tools,\n * with where a run's proposals of each tool wait and whether its MCP servers are used in runs without\n * a person), whom it answers to, who approves its proposals, and its results (its groups and latest\n * runs). Problems show at the step they concern with the entry point that fixes them. The flow edits\n * nothing: every entry point opens a form of the run configuration, or asks the page that hosts it to\n * open the agent editor, the technical account, the runs view or the MCP servers (`entry`). Run now\n * opens the run-now dialog here.\n */\n@Component({\n selector: 'nh-assistant-agent-flow',\n standalone: true,\n imports: [\n DatePipe,\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantSubjectLinkComponent,\n NhAssistantRunNowDialogComponent,\n NhAssistantAccountLabelComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-flow.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss', './nh-assistant-agent-flow.component.scss']\n})\nexport class NhAssistantAgentFlowComponent implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly panel = inject(NhAssistantPanelService);\n private readonly translate = inject(TranslateService);\n private runsSubscription?: Subscription;\n\n readonly agent = input.required<AdminAgent>();\n readonly configuration = input.required<AgentRunConfiguration>();\n readonly catalog = input<RunCatalog | null>(null);\n /** The tool catalog; without it the agent's tools are listed by their selectors. */\n readonly tools = input<readonly ToolCatalogEntry[]>([]);\n /** The MCP servers; `null` while unknown, so nothing reads as missing. */\n readonly servers = input<readonly McpServer[] | null>(null);\n /** The name of the account the agent answers to, once known. */\n readonly accountName = input<string | null>(null);\n /** An action of the run configuration is busy; the entry points wait. */\n readonly busy = input(false);\n /** An entry point asks to open the form or view it summarizes. */\n readonly entry = output<AgentFlowEntry>();\n\n readonly id = `nh-assistant-agent-flow-${nextId++}`;\n readonly steps = agentFlowSteps;\n readonly skillNameKeys = skillNameKeys;\n readonly skillDescriptionKeys = skillDescriptionKeys;\n readonly policyKeys = policyKeys;\n readonly readableId = readableId;\n readonly codeKeys = nhAssistantCodeKeys;\n\n readonly runs = signal<AgentRunHistory | null>(null);\n readonly runsError = signal<NhAssistantError | null>(null);\n readonly runsErrorKeys = computed(() => nhAssistantErrorKeys(this.runsError()));\n readonly runsLoading = signal(false);\n /** The run-now dialog is open. */\n readonly runningNow = signal(false);\n\n private readonly language = toSignal(\n this.translate.onLangChange.pipe(map(event => event.lang), startWith(this.translate.currentLang)),\n { initialValue: this.translate.currentLang });\n\n readonly isAdmin = computed(() => this.configuration().source === 'admin');\n /** An agent created here gets skills and triggers once it has run settings. */\n readonly canAddRunData = computed(() => !this.isAdmin() || this.configuration().runSettings !== null);\n readonly worksOn = computed(() => {\n const summary = worksOnSummary(this.agent(), this.catalog()?.subjectTypes);\n return { ...summary, only: summary.all ? 'all' : summary.types.length > 0 ? 'types' : 'application' };\n });\n readonly triggers = computed(() => flowTriggers(this.configuration(), this.catalog(), this.agent()));\n readonly runNow = computed(() => flowRunNow(this.agent(), this.configuration(), this.catalog()));\n /**\n * What people run the agent for by hand, as the run-now dialog offers it: the whole application (one\n * division at a time for an agent that works per division) and the objects it works on.\n */\n readonly runNowScopeKey = computed(() => {\n const works = this.worksOn();\n const objects = works.all || works.types.length > 0;\n const base = 'nh-assistant.admin.run-config.flow.when.scope.';\n if (!works.application) {\n return `${base}objects`;\n }\n return `${base}${works.perDivision ? 'division' : 'application'}${objects ? '-and-objects' : ''}`;\n });\n readonly runNowAgent = computed<NhAssistantRunNowAgent>(() => {\n this.language();\n return runNowAgentOf(this.agent(), this.agentName());\n });\n readonly agentName = computed(() => {\n this.language();\n const agent = this.agent();\n return this.translated(codeTextKeys(agent.source, agent.displayName), agent.displayName);\n });\n readonly accountability = computed(() => flowAccountability(this.configuration()));\n /** The way of working of the agent: fixed rules (named for an agent created here) or the model. */\n readonly wayOfWorking = computed(() => {\n const configuration = this.configuration();\n if (configuration.source === 'admin') {\n const settings = configuration.runSettings;\n if (!settings) {\n return null;\n }\n const rules = settings.ruleHandler;\n return rules\n ? { kind: 'rules' as const, name: rules, description: this.catalog()?.ruleHandlers.find(block => block.name === rules)?.description ?? null }\n : { kind: 'model' as const, name: null, description: null };\n }\n return configuration.codeRunSettings?.usesRules\n ? { kind: 'code-rules' as const, name: null, description: null }\n : { kind: 'model' as const, name: null, description: null };\n });\n readonly agentTools = computed(() => flowTools(this.configuration().toolSelectors, this.tools(), this.catalog()));\n readonly agentServers = computed(() => flowServers(this.agent().mcpServerIds, this.servers(), this.accountability()));\n /** The agent's approval policy and the skills' own, each with its sentence. */\n readonly policies = computed<FlowPolicy[]>(() => {\n this.language();\n const configuration = this.configuration();\n const policies: FlowPolicy[] = [];\n // The run settings as data, or how an agent in code runs; neither while an agent created here has none.\n const settings = configuration.source === 'admin' ? configuration.runSettings : configuration.codeRunSettings;\n if (settings) {\n policies.push({ skillId: null, name: settings.approvalPolicy, sentence: this.sentence(settings.approvalPolicy) });\n }\n for (const skill of configuration.dataSkills) {\n if (skill.approvalPolicy) {\n policies.push({ skillId: skill.skillId, name: skill.approvalPolicy, sentence: this.sentence(skill.approvalPolicy) });\n }\n }\n return policies;\n });\n /** The names of the groups the agent is in, as the run catalog names them. */\n readonly groups = computed(() => {\n const groups = this.catalog()?.agentGroups ?? [];\n return (this.agent().groups ?? []).map(id => groups.find(group => group.id === id)?.name ?? id);\n });\n /** Whether the agent can be put in groups: every agent except a shadow variant. */\n readonly groupable = computed(() => !this.agent().shadowOf);\n /** The warnings of each step: problems of the run configuration and what keeps the agent from working. */\n readonly warnings = computed<Record<AgentFlowStepId, AgentFlowWarning[]>>(() => {\n const configuration = this.configuration();\n const result: Record<AgentFlowStepId, AgentFlowWarning[]> = {\n 'works-on': [],\n when: [],\n skills: [],\n account: [],\n approval: [],\n results: []\n };\n for (const problem of configuration.problems) {\n result[problemStep(problem)].push(problemWarning(problem, configuration));\n }\n for (const selector of this.agentTools().unmatched) {\n result.skills.push({\n id: `tool:${selector}`,\n key: 'nh-assistant.admin.run-config.flow.skills.tool-not-offered',\n params: { selector },\n entry: { kind: 'edit-agent' },\n entryKey: 'nh-assistant.admin.run-config.flow.entry.tools'\n });\n }\n for (const server of this.agentServers()) {\n if (unavailableServerUses.has(server.use)) {\n result.skills.push(this.serverWarning(server.id, server.name, server.use));\n }\n }\n if (configuration.source === 'admin' && configuration.runSettings === null) {\n result.account.push({\n id: 'no-settings',\n key: 'nh-assistant.admin.run-config.flow.account.no-settings',\n entry: { kind: 'setup' },\n entryKey: 'nh-assistant.admin.run-config.setup.start'\n });\n }\n return result;\n });\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.runsSubscription?.unsubscribe());\n }\n\n ngOnInit(): void {\n this.loadRuns();\n }\n\n /** Reads the agent's latest runs; a failure shows with its code and a retry in the results step. */\n loadRuns(): void {\n this.runsLoading.set(true);\n this.runsError.set(null);\n this.runsSubscription?.unsubscribe();\n this.runsSubscription = this.admin.getAgentRuns(this.agent().id, { page: 1, itemsPerPage: latestRunCount }).subscribe({\n next: runs => {\n this.runs.set(runs);\n this.runsLoading.set(false);\n },\n error: (error: unknown) => {\n this.runsError.set(toNhAssistantError(error));\n this.runsLoading.set(false);\n }\n });\n }\n\n open(entry: AgentFlowEntry): void {\n this.entry.emit(entry);\n }\n\n openRunNow(): void {\n this.runningNow.set(true);\n }\n\n /** The run-now dialog closed; its run may be among the latest now. */\n onRunNowClosed(): void {\n this.runningNow.set(false);\n this.loadRuns();\n }\n\n openConversation(conversationId: string): void {\n this.panel.open(conversationId);\n }\n\n /** A skill's name: the application's translation, or a readable form of its id. */\n skillName(skillId: string | null | undefined): string {\n return skillId ? this.translated(skillNameKeys(this.agent().id, skillId), readableId(skillId)) : '';\n }\n\n /** The text of a step's warning count. */\n warningCountKey(count: number): string {\n return count === 1 ? 'nh-assistant.admin.run-config.flow.attention-one' : 'nh-assistant.admin.run-config.flow.attention';\n }\n\n private serverWarning(id: string, name: string, use: AgentFlowServerUse): AgentFlowWarning {\n const base = { id: `server:${id}`, key: `nh-assistant.admin.run-config.flow.servers.warning.${use}`, params: { server: name } };\n switch (use) {\n case 'missing':\n return { ...base, entry: { kind: 'edit-agent' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.tools' };\n case 'personal-never-account':\n case 'personal-never-agent':\n // Delegating to the person who starts a run lets the server serve that person.\n return this.isAdmin() && this.configuration().runSettings\n ? { ...base, entry: { kind: 'settings' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.settings' }\n : { ...base, entry: { kind: 'mcp-servers' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.mcp-servers' };\n default:\n return { ...base, entry: { kind: 'mcp-servers' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.mcp-servers' };\n }\n }\n\n private sentence(policy: string | null): string | null {\n const summary = this.catalog()?.approvalPolicySummaries?.find(item => item.name === policy);\n return summary ? describePolicy(summary, (key, params) => this.translate.instant(key, params) as string) : null;\n }\n\n /** The first of the keys with a translation, or the fallback. */\n private translated(keys: readonly string[], fallback: string): string {\n for (const key of keys) {\n const value = this.translate.instant(key) as unknown;\n if (typeof value === 'string' && value.length > 0 && value !== key) {\n return value;\n }\n }\n return fallback;\n }\n}\n","<section class=\"flow\" [attr.aria-labelledby]=\"id + '-title'\" data-flow>\n <header class=\"flow-header\">\n <h4 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.run-config.flow.title' | translate }}</h4>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.description' | translate }}</p>\n </header>\n\n <!-- An overview in order, not an editor: each step summarizes and opens the form that changes it. -->\n <ol class=\"flow-steps\">\n @for (step of steps; track step; let index = $index) {\n <li class=\"flow-step\" [class.attention]=\"warnings()[step].length > 0\" [attr.data-flow-step]=\"step\">\n <div class=\"step-head\">\n <span class=\"marker\" aria-hidden=\"true\">{{ index + 1 }}</span>\n <h5 [id]=\"id + '-' + step\">{{ 'nh-assistant.admin.run-config.flow.steps.' + step | translate }}</h5>\n @if (warnings()[step].length > 0) {\n <span class=\"badge warning\" data-flow-attention>\n <nh-assistant-icon name=\"warning\" />{{ warningCountKey(warnings()[step].length) | translate: { count: warnings()[step].length } }}\n </span>\n }\n </div>\n\n <div class=\"step-body\">\n @switch (step) {\n @case ('works-on') {\n @let works = worksOn();\n <p data-flow-works-on>\n <strong>\n @switch (works.only) {\n @case ('all') { {{ 'nh-assistant.admin.agents.works-on.all' | translate }} }\n @case ('types') { {{ works.types.join(', ') }} }\n @default { {{ 'nh-assistant.admin.agents.works-on.application' | translate }} }\n }\n </strong>\n @if (works.application && works.only !== 'application') {\n {{ 'nh-assistant.admin.agents.works-on.and-application' | translate }}\n }\n @if (works.perDivision) {\n {{ 'nh-assistant.admin.agents.works-on.per-division' | translate }}\n }\n </p>\n @if (works.undeclared) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.works-on.undeclared' | translate }}</p>\n }\n @if (works.all && works.known.length > 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.agents.works-on.known' | translate: { types: works.known.join(', ') } }}</p>\n }\n @if (!isAdmin()) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.works-on.in-code' | translate }}</p>\n }\n }\n\n @case ('when') {\n @if (triggers().length === 0) {\n <p class=\"muted\" data-flow-no-triggers>{{ 'nh-assistant.admin.run-config.flow.when.none' | translate }}</p>\n } @else {\n <ul class=\"items\">\n @for (trigger of triggers(); track trigger.origin + trigger.triggerId) {\n <li [attr.data-flow-trigger]=\"trigger.triggerId\">\n <div class=\"item-head\">\n <strong class=\"mono\">{{ trigger.triggerId }}</strong>\n <span class=\"badge\">{{ 'nh-assistant.admin.run-config.triggers.sources.' + trigger.source | translate }}</span>\n @if (trigger.origin === 'code') {\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n } @else if (trigger.shadow) {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.agents.shadow.badge' | translate }}</span>\n } @else {\n <span class=\"badge success\">{{ 'nh-assistant.admin.run-config.triggers.live-badge' | translate }}</span>\n }\n @if (!trigger.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n </div>\n <div class=\"meta\">\n @if (trigger.detail) {\n <span class=\"mono\">{{ trigger.detail }}</span>\n }\n <span data-flow-target>{{ 'nh-assistant.admin.run-config.flow.target.' + trigger.target.kind | translate: { value: trigger.target.value } }}</span>\n <span>{{ (trigger.skillId ? 'nh-assistant.admin.run-config.triggers.skill-value' : 'nh-assistant.admin.run-config.triggers.agent-routes') | translate: { skill: skillName(trigger.skillId) } }}</span>\n </div>\n @if (trigger.origin === 'data') {\n <div class=\"item-actions\">\n <button\n class=\"secondary small\"\n type=\"button\"\n [attr.aria-label]=\"'nh-assistant.admin.run-config.flow.entry.edit-trigger-named' | translate: { trigger: trigger.triggerId }\"\n [disabled]=\"busy()\"\n (click)=\"open({ kind: 'edit-trigger', triggerId: trigger.triggerId })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n </div>\n }\n </li>\n }\n </ul>\n }\n @let now = runNow();\n <p data-flow-run-now>\n @if (now.available) {\n {{ runNowScopeKey() | translate }}\n @if (worksOn().application) {\n {{ 'nh-assistant.admin.run-config.flow.when.run-policy' | translate: { policy: worksOn().runPolicy ? (policyKeys(worksOn().runPolicy) | nhAssistantTranslate: worksOn().runPolicy!) : ('nh-assistant.admin.run-config.flow.when.run-policy-default' | translate) } }}\n }\n @if (now.paused) {\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.flow.when.paused' | translate }}</span>\n }\n } @else {\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.when.run-now-unavailable.' + now.reason | translate }}</span>\n }\n </p>\n }\n\n @case ('skills') {\n @if (wayOfWorking(); as way) {\n <p data-flow-way>\n <span class=\"flow-label\">{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}:</span>&ngsp;\n @switch (way.kind) {\n @case ('rules') {\n <strong>{{ 'nh-assistant.admin.run-config.rule-handler-value' | translate: { name: way.name } }}</strong>\n @if (way.description) {\n <span class=\"muted block\">{{ way.description }}</span>\n }\n }\n @case ('code-rules') { <strong>{{ 'nh-assistant.admin.run-config.flow.skills.code-rules' | translate }}</strong> }\n @default { <strong>{{ 'nh-assistant.admin.run-config.model' | translate }}</strong> }\n }\n </p>\n }\n @let config = configuration();\n @if (config.codeSkills.length === 0 && config.dataSkills.length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.skills.none' | translate }}</p>\n } @else {\n <ul class=\"items\" [attr.aria-label]=\"'nh-assistant.admin.agents.skills.title' | translate\">\n @for (skill of config.codeSkills; track skill.skillId) {\n <li [attr.data-flow-skill]=\"skill.skillId\">\n <div class=\"item-head\">\n <strong>{{ skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId) }}</strong>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n </div>\n <p class=\"muted\">{{ skillDescriptionKeys(config.agentId, skill.skillId) | nhAssistantTranslate: skill.description }}</p>\n </li>\n }\n @for (skill of config.dataSkills; track skill.skillId) {\n <li [attr.data-flow-skill]=\"skill.skillId\">\n <div class=\"item-head\">\n <strong>{{ skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId) }}</strong>\n @if (!skill.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n @if (skill.candidate) {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.run-config.candidate.badge' | translate: { version: skill.candidate.version } }}</span>\n }\n </div>\n <p class=\"muted\">{{ skill.description }}</p>\n <div class=\"meta\">\n <span>{{ skill.ruleHandler ? ('nh-assistant.admin.run-config.rule-handler-value' | translate: { name: skill.ruleHandler }) : ('nh-assistant.admin.run-config.model' | translate) }}</span>\n <span>{{ (skill.tools.length === 1 ? 'nh-assistant.admin.agents.tool-count-one' : 'nh-assistant.admin.agents.tool-count') | translate: { count: skill.tools.length } }}</span>\n </div>\n <div class=\"item-actions\">\n <button\n class=\"secondary small\"\n type=\"button\"\n [attr.aria-label]=\"'nh-assistant.admin.run-config.flow.entry.edit-skill-named' | translate: { skill: (skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) }\"\n [disabled]=\"busy()\"\n (click)=\"open({ kind: 'edit-skill', skillId: skill.skillId })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n </div>\n </li>\n }\n </ul>\n }\n\n <div class=\"tools\" data-flow-tools>\n <p class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.skills.tools' | translate }}</p>\n @let tools = agentTools();\n @if (!tools.known) {\n @if (config.toolSelectors.length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.skills.no-tools' | translate }}</p>\n } @else {\n <p class=\"mono\">{{ config.toolSelectors.join(', ') }}</p>\n }\n } @else if (tools.tools.length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.skills.no-tools' | translate }}</p>\n } @else {\n <ul class=\"items compact\">\n @for (tool of tools.tools; track tool.id) {\n <li [attr.data-flow-tool]=\"tool.id\">\n <div class=\"item-head\">\n <span class=\"mono\">{{ tool.id }}</span>\n <span class=\"badge\" [class.warning]=\"tool.effect !== 'read-only'\">{{ 'nh-assistant.admin.run-config.flow.effect.' + tool.effect | translate }}</span>\n </div>\n @if (tool.effect !== 'read-only') {\n <!-- Where a run's proposal of the tool waits: at the object it names (W5), or in the run's own thread. -->\n <p class=\"muted\" data-flow-places>\n {{ (tool.placesAt ? 'nh-assistant.admin.run-config.flow.skills.places-at' : 'nh-assistant.admin.run-config.flow.skills.places-in-run') | translate: { type: tool.placesAt } }}\n </p>\n }\n </li>\n }\n </ul>\n @if (tools.more > 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.skills.more-tools' | translate: { count: tools.more } }}</p>\n }\n }\n </div>\n\n @if (agentServers().length > 0) {\n <div class=\"tools\" data-flow-servers>\n <p class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.skills.servers' | translate }}</p>\n <ul class=\"items compact\">\n @for (server of agentServers(); track server.id) {\n <li [attr.data-flow-server]=\"server.id\">\n <div class=\"item-head\">\n <strong>{{ server.name }}</strong>\n @if (server.headlessUse) {\n <span class=\"badge\">{{ 'nh-assistant.admin.run-config.flow.servers.headless.' + server.headlessUse | translate }}</span>\n }\n </div>\n <p class=\"muted\" data-flow-server-use>{{ 'nh-assistant.admin.run-config.flow.servers.use.' + server.use | translate }}</p>\n </li>\n }\n </ul>\n </div>\n }\n }\n\n @case ('account') {\n @let config = configuration();\n @if (accountability(); as account) {\n <p data-flow-account>\n <strong>{{ 'nh-assistant.admin.run-config.settings.accountability.' + account.accountability | translate }}</strong>\n @if (account.accountability === 'service-account') {\n @let actorId = isAdmin() ? config.runSettings?.serviceAccountActorId : agent().serviceAccount?.actorId;\n @if (actorId) {\n <span class=\"block\" data-flow-account-name>\n <nh-assistant-account-label [actorId]=\"actorId\" [name]=\"accountName()\" />\n </span>\n }\n }\n </p>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.account.rights.' + account.accountability | translate }}</p>\n @if (account.delegateFromInitiator) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.account.delegates' | translate }}</p>\n }\n @if (!isAdmin() && agent().serviceAccount?.overridden) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.account.overridden' | translate }}</p>\n }\n } @else if (!isAdmin()) {\n <!-- An older server does not say how an agent in code runs. -->\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.account.in-code' | translate }}</p>\n }\n }\n\n @case ('approval') {\n <p>\n <span class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.approval.autonomy' | translate }}</span>&ngsp;\n <strong>{{ 'nh-assistant.admin.agents.autonomy.' + agent().autonomy | translate }}</strong>\n </p>\n @if (policies().length === 0) {\n <p class=\"muted\">{{ (isAdmin() ? 'nh-assistant.admin.run-config.flow.approval.no-settings' : 'nh-assistant.admin.run-config.flow.approval.in-code') | translate }}</p>\n } @else {\n <ul class=\"items\">\n @for (policy of policies(); track policy.skillId ?? '') {\n <li [attr.data-flow-policy]=\"policy.skillId ?? 'agent'\">\n <div class=\"item-head\">\n @if (policy.skillId) {\n <span>{{ 'nh-assistant.admin.run-config.flow.approval.skill' | translate: { skill: skillName(policy.skillId) } }}</span>\n }\n <strong>{{ policy.name ?? ('nh-assistant.admin.run-config.settings.approval.default' | translate) }}</strong>\n </div>\n @if (policy.sentence) {\n <p class=\"muted\" data-flow-policy-sentence>{{ policy.sentence }}</p>\n }\n </li>\n }\n </ul>\n }\n }\n\n @case ('results') {\n <p data-flow-groups>\n <span class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.results.groups' | translate }}</span>&ngsp;\n @if (groups().length > 0) {\n <strong>{{ groups().join(', ') }}</strong>\n } @else {\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.results.no-groups' | translate }}</span>\n }\n </p>\n @if (worksOn().application) {\n <p class=\"muted\" data-flow-view-policy>\n {{ 'nh-assistant.admin.run-config.flow.results.view-policy' | translate: { policy: worksOn().viewPolicy ? (policyKeys(worksOn().viewPolicy) | nhAssistantTranslate: worksOn().viewPolicy!) : ('nh-assistant.admin.run-config.flow.results.view-policy-default' | translate) } }}\n </p>\n }\n @if (agent().shadow?.shadow) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.results.shadow' | translate }}</p>\n }\n <div class=\"latest\" data-flow-runs>\n <p class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.results.latest' | translate }}</p>\n @if (runsError(); as failure) {\n <div class=\"message error\" role=\"alert\" data-flow-runs-error>\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">{{ runsErrorKeys() | nhAssistantTranslate: failure.code }}</span>\n <button class=\"secondary small\" type=\"button\" [disabled]=\"runsLoading()\" (click)=\"loadRuns()\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.retry' | translate }}\n </button>\n </div>\n } @else if (runsLoading() && !runs()) {\n <p class=\"muted\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (runs(); as history) {\n @if (history.items.length === 0) {\n <p class=\"muted\" data-flow-runs-empty>{{ 'nh-assistant.agent-runs.run.empty' | translate }}</p>\n } @else {\n <ol class=\"items\">\n @for (run of history.items; track run.id) {\n <li [attr.data-flow-run]=\"run.id\">\n <div class=\"item-head\">\n <time [attr.datetime]=\"run.createdAt\">{{ run.createdAt | date: 'medium' }}</time>\n <span\n class=\"badge\"\n [class.success]=\"run.status === 'completed'\"\n [class.warning]=\"run.status === 'waiting-for-approval' || run.status === 'queued' || run.status === 'running'\"\n [class.danger]=\"run.status === 'failed'\">{{ 'nh-assistant.agent-runs.run.status.' + run.status | translate }}</span>\n @if (run.shadow) {\n <span class=\"badge warning\">{{ 'nh-assistant.agent-runs.run.shadow' | translate }}</span>\n }\n </div>\n <nh-assistant-subject-link\n [subjectType]=\"run.subjectType\"\n [subjectId]=\"run.subjectId\"\n [label]=\"run.subjectDisplayName ?? run.subjectId\"\n [typeName]=\"run.subjectTypeName\"\n [link]=\"run.subjectLink\" />\n <!-- The beginning of the result is model output, shown as text. -->\n @if (run.result; as result) {\n <p class=\"preview\" data-flow-run-preview>{{ result }}@if (run.resultTruncated) {…}</p>\n } @else if (run.failureCode; as code) {\n <p class=\"muted\">{{ codeKeys(code) | nhAssistantTranslate: code }}</p>\n }\n @if (run.mcpConnectionSkips?.length) {\n <p class=\"muted\" data-flow-run-mcp-skips>{{ 'nh-assistant.agent-runs.run.mcp-skipped' | translate: { count: run.mcpConnectionSkips?.length } }}</p>\n }\n </li>\n }\n </ol>\n @if (history.total > history.items.length) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.results.more-runs' | translate: { count: history.total - history.items.length } }}</p>\n }\n }\n }\n </div>\n }\n }\n\n @if (warnings()[step].length > 0) {\n <ul class=\"warnings\" [attr.aria-label]=\"'nh-assistant.admin.run-config.flow.warnings' | translate\">\n @for (warning of warnings()[step]; track warning.id) {\n <li class=\"message warning\" [attr.data-flow-warning]=\"warning.id\">\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">\n {{ warning.key | translate: warning.params }}\n @if (warning.detailKey) {\n {{ warning.detailKey | translate }}\n }\n </span>\n @if (warning.entry; as target) {\n <button class=\"secondary small\" type=\"button\" [attr.data-flow-fix]=\"target.kind\" [disabled]=\"busy()\" (click)=\"open(target)\">\n {{ warning.entryKey! | translate }}\n </button>\n }\n </li>\n }\n </ul>\n }\n\n <div class=\"card-actions\" [attr.data-flow-entries]=\"step\">\n @switch (step) {\n @case ('works-on') {\n @if (isAdmin()) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"edit-agent\" [disabled]=\"busy()\" (click)=\"open({ kind: 'edit-agent' })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.run-config.flow.entry.works-on' | translate }}\n </button>\n }\n }\n @case ('when') {\n @if (canAddRunData()) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"add-trigger\" [disabled]=\"busy()\" (click)=\"open({ kind: 'add-trigger' })\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.triggers.add' | translate }}\n </button>\n }\n @if (runNow().available) {\n <button class=\"secondary\" type=\"button\" aria-haspopup=\"dialog\" data-flow-entry=\"run-now\" [disabled]=\"busy()\" (click)=\"openRunNow()\">\n <nh-assistant-icon name=\"send\" />{{ 'nh-assistant.admin.agents.run-now' | translate }}\n </button>\n }\n }\n @case ('skills') {\n @if (canAddRunData()) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"add-skill\" [disabled]=\"busy()\" (click)=\"open({ kind: 'add-skill' })\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.skills.add' | translate }}\n </button>\n }\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"tools\" [disabled]=\"busy()\" (click)=\"open({ kind: 'edit-agent' })\">\n <nh-assistant-icon name=\"tool\" />{{ 'nh-assistant.admin.run-config.flow.entry.tools' | translate }}\n </button>\n }\n @case ('account') {\n @if (isAdmin()) {\n @if (configuration().runSettings) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"settings\" [disabled]=\"busy()\" (click)=\"open({ kind: 'settings' })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.run-config.settings.edit' | translate }}\n </button>\n } @else {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"settings\" [disabled]=\"busy()\" (click)=\"open({ kind: 'settings' })\">\n {{ 'nh-assistant.admin.run-config.settings.add' | translate }}\n </button>\n }\n } @else if (agent().serviceAccount) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"account\" [disabled]=\"busy()\" (click)=\"open({ kind: 'account' })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.agents.service-account.action.set' | translate }}\n </button>\n }\n }\n @case ('approval') {\n @if (isAdmin() && configuration().runSettings) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"approval\" [disabled]=\"busy()\" (click)=\"open({ kind: 'settings' })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.run-config.flow.entry.approval' | translate }}\n </button>\n }\n }\n @case ('results') {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"runs\" (click)=\"open({ kind: 'runs' })\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.run-config.flow.entry.runs' | translate }}\n </button>\n @if (groupable()) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"groups\" [disabled]=\"busy()\" (click)=\"open({ kind: 'edit-agent' })\">\n <nh-assistant-icon name=\"users\" />{{ 'nh-assistant.admin.run-config.flow.entry.groups' | translate }}\n </button>\n }\n }\n }\n </div>\n </div>\n </li>\n }\n </ol>\n\n @if (runningNow()) {\n <nh-assistant-run-now-dialog\n [agent]=\"runNowAgent()\"\n [subjectTypes]=\"catalog()?.subjectTypes ?? []\"\n [divisions]=\"catalog()?.divisions === true\"\n (started)=\"loadRuns()\"\n (openConversation)=\"openConversation($event)\"\n (closed)=\"onRunNowClosed()\" />\n }\n</section>\n","import { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, output, signal, untracked, viewChild } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Observable, Subscription, map } from 'rxjs';\nimport {\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantPickerOption as NhAssistantPickerOption,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\nconst lookupDelayMs = 300;\n\nlet nextId = 0;\n\n/**\n * Chooses the account an agent answers to. When the application offers an account search the\n * administrator finds the account by name or e-mail address; otherwise they enter its id and the\n * screen shows the name the application knows for it. When the name cannot be looked up, the screen\n * says why with the translated code and offers to look it up again, instead of calling the account\n * unknown.\n */\n@Component({\n selector: 'nh-assistant-account-picker',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantPickerComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (searchable()) {\n <nh-assistant-picker\n [inputId]=\"inputId()\"\n [value]=\"value()\"\n [selectedLabel]=\"label()\"\n [search]=\"search\"\n [invalid]=\"invalid()\"\n [describedBy]=\"fieldDescribedBy()\"\n [placeholder]=\"'nh-assistant.admin.run-config.account.search-placeholder' | translate\"\n (valueChange)=\"valueChange.emit($event)\"\n (optionChange)=\"label.set($event?.label ?? null)\" />\n } @else {\n <input\n #manual\n type=\"text\"\n class=\"mono\"\n autocomplete=\"off\"\n maxlength=\"256\"\n [id]=\"inputId()\"\n [value]=\"value() ?? ''\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [attr.aria-describedby]=\"fieldDescribedBy()\"\n [attr.placeholder]=\"'nh-assistant.admin.run-config.account.id-placeholder' | translate\"\n (input)=\"valueChange.emit(text($event))\" />\n }\n @if (lookupError(); as failure) {\n <p class=\"lookup-error\" role=\"alert\" data-account-lookup-error [id]=\"lookupErrorId\">\n <nh-assistant-icon name=\"warning\" />\n <span>{{ lookupErrorKeys() | nhAssistantTranslate: failure.code }}</span>\n <button type=\"button\" class=\"link\" data-account-lookup-retry (click)=\"lookUpAgain()\">\n {{ 'nh-assistant.admin.run-config.account.lookup-again' | translate }}\n </button>\n </p>\n } @else if (!searchable() && value()) {\n <p class=\"account-name\" aria-live=\"polite\">\n {{ (label() ? 'nh-assistant.admin.run-config.account.known' : 'nh-assistant.admin.run-config.account.unknown') | translate: { name: label() } }}\n </p>\n }\n `,\n styles: [`\n :host { display: block; min-width: 0; }\n input {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n min-height: 38px;\n border: 1px solid var(--nha-border, #d0d5dd);\n border-radius: var(--nha-radius-control, 8px);\n padding: 8px 10px;\n color: var(--nha-text, inherit);\n background: var(--nha-background, transparent);\n font-family: var(--nha-mono, monospace);\n font-size: 12px;\n }\n input[aria-invalid='true'] { border-color: var(--nha-danger, #b42318); }\n .account-name { margin: 4px 2px 0; color: var(--nha-text-muted, #667085); font-size: 12px; overflow-wrap: anywhere; }\n .lookup-error {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 6px;\n margin: 4px 2px 0;\n color: var(--nha-danger, #b42318);\n font-size: 12px;\n font-weight: 600;\n overflow-wrap: anywhere;\n }\n .lookup-error span { flex: 1 1 auto; min-width: 0; }\n button.link {\n border: 0;\n padding: 0;\n color: var(--nha-accent, currentColor);\n background: none;\n font: inherit;\n text-decoration: underline;\n cursor: pointer;\n }\n `]\n})\nexport class NhAssistantAccountPickerComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private lookupTimer?: ReturnType<typeof setTimeout>;\n private lookupSubscription?: Subscription;\n private readonly picker = viewChild(NhAssistantPickerComponent);\n private readonly manual = viewChild<{ nativeElement: HTMLInputElement }>('manual');\n\n readonly inputId = input.required<string>();\n readonly value = input<string | null>(null);\n /** Whether the application offers an account search (`RunCatalog.accountSearch`). */\n readonly searchable = input(false);\n readonly invalid = input(false);\n readonly describedBy = input<string | null>(null);\n readonly valueChange = output<string>();\n\n readonly lookupErrorId = `nh-assistant-account-picker-lookup-${nextId++}`;\n /** The name of the chosen account, once known. */\n readonly label = signal<string | null>(null);\n /** Why the name of the account could not be looked up; `null` after a lookup that answered. */\n readonly lookupError = signal<NhAssistantError | null>(null);\n readonly lookupErrorKeys = computed(() => nhAssistantErrorKeys(this.lookupError()));\n readonly fieldDescribedBy = computed(() =>\n [this.describedBy(), this.lookupError() ? this.lookupErrorId : null].filter(Boolean).join(' ') || null);\n\n readonly search = (query: string): Observable<NhAssistantPickerOption[]> =>\n this.admin.searchAccounts(query).pipe(map(accounts => accounts.map(account => ({\n value: account.actorId,\n label: account.displayName,\n // An account named by its e-mail address needs no second line.\n description: account.detail === account.displayName ? null : account.detail\n }))));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n clearTimeout(this.lookupTimer);\n this.lookupSubscription?.unsubscribe();\n });\n // The name of a stored account comes from the application's directory.\n effect(() => {\n const value = this.value()?.trim() ?? '';\n const delay = this.searchable() ? 0 : lookupDelayMs;\n untracked(() => this.lookUp(value, delay));\n });\n }\n\n focus(): void {\n this.picker()?.focus();\n this.manual()?.nativeElement.focus();\n }\n\n text(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n\n /** Looks the name of the account up again after a failed lookup. */\n lookUpAgain(): void {\n this.lookUp(this.value()?.trim() ?? '', 0);\n }\n\n private lookUp(value: string, delay: number): void {\n clearTimeout(this.lookupTimer);\n this.lookupSubscription?.unsubscribe();\n this.lookupError.set(null);\n if (value.length === 0) {\n this.label.set(null);\n return;\n }\n\n this.lookupTimer = setTimeout(() => {\n this.lookupSubscription = this.admin.getAccounts([value]).subscribe({\n next: accounts => this.label.set(accounts.find(account => account.actorId === value)?.displayName ?? null),\n error: (error: unknown) => {\n this.label.set(null);\n this.lookupError.set(toNhAssistantError(error));\n }\n });\n }, delay);\n }\n}\n","import { DestroyRef, ElementRef, Injector, afterNextRender, computed, inject, signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { TranslateService } from '@ngx-translate/core';\nimport { Observable, Subscription, map, startWith } from 'rxjs';\nimport {\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport { RunConfigErrors, RunConfigFieldError, fieldErrorKey, focusFirstInvalid, serverFieldErrors } from './run-config-shared';\n\n/**\n * What the run configuration forms share: errors checked before sending and those the server\n * returns, each shown at its field, a form-level error next to the actions, and the focus on the\n * first invalid field after a refused save.\n */\nexport abstract class RunConfigForm {\n protected readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n protected readonly injector = inject(Injector);\n protected readonly translate = inject(TranslateService);\n private subscription?: Subscription;\n\n readonly busy = signal(false);\n readonly clientErrors = signal<RunConfigErrors>({});\n readonly serverError = signal<NhAssistantError | null>(null);\n /** Fields whose server error the administrator already corrected. */\n private readonly cleared = signal<ReadonlySet<string>>(new Set());\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.serverError()));\n\n /** The language, so computed texts follow a switch. */\n protected readonly language = toSignal(\n this.translate.onLangChange.pipe(map(event => event.lang), startWith(this.translate.currentLang)),\n { initialValue: this.translate.currentLang });\n\n /** The fields this form shows; server errors of other fields are listed with the form's error. */\n protected abstract readonly fields: readonly string[];\n\n readonly fieldErrors = computed<RunConfigErrors>(() => {\n const cleared = this.cleared();\n const server = Object.fromEntries(Object.entries(this.mapServerErrors(serverFieldErrors(this.serverError())))\n .filter(([field]) => !cleared.has(field)));\n return { ...server, ...this.clientErrors() };\n });\n\n /** Server errors of fields this form does not show, by name. */\n readonly otherFieldErrors = computed(() => Object.keys(serverFieldErrors(this.serverError()))\n .filter(field => !this.fields.includes(field) && field !== 'dailyBudget'));\n\n readonly hasErrors = computed(() => this.serverError() !== null || Object.keys(this.clientErrors()).length > 0);\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n }\n\n fieldError(field: string): RunConfigFieldError | null {\n return this.fieldErrors()[field] ?? null;\n }\n\n errorKey(field: string): string | null {\n return fieldErrorKey(this.fieldError(field));\n }\n\n /** The ids a control describes itself with: its hint and, when shown, its error. */\n describedBy(hintId: string | null, field: string, errorId: string): string | null {\n const ids = [hintId, this.fieldError(field) ? errorId : null].filter((id): id is string => id !== null);\n return ids.length > 0 ? ids.join(' ') : null;\n }\n\n /** Removes a field's error once the administrator changes it. */\n touch(field: string): void {\n if (this.clientErrors()[field]) {\n const { [field]: _, ...rest } = this.clientErrors();\n this.clientErrors.set(rest);\n }\n if (!this.cleared().has(field)) {\n this.cleared.set(new Set([...this.cleared(), field]));\n }\n }\n\n /** The server's codes for fields of other forms, such as a budget the server reports as one. */\n protected mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n return errors;\n }\n\n /**\n * Sends the request when `errors` is empty; otherwise shows them and focuses the first. A refused\n * request shows its errors the same way and calls `refused`; `done` receives the last value once\n * the request completed.\n */\n protected submit<T>(\n errors: RunConfigErrors,\n request: () => Observable<T>,\n done: (result: T) => void,\n refused?: () => void\n ): void {\n this.serverError.set(null);\n this.cleared.set(new Set());\n this.clientErrors.set(errors);\n if (Object.keys(errors).length > 0) {\n this.focusFirstInvalid();\n return;\n }\n this.busy.set(true);\n this.subscription?.unsubscribe();\n let last: T | undefined;\n this.subscription = request().subscribe({\n next: result => {\n last = result;\n },\n complete: () => {\n this.busy.set(false);\n done(last as T);\n },\n error: (error: unknown) => {\n this.busy.set(false);\n this.serverError.set(toNhAssistantError(error));\n refused?.();\n this.focusFirstInvalid();\n }\n });\n }\n\n protected focusFirstInvalid(): void {\n afterNextRender(() => {\n const form = this.host.nativeElement.querySelector<HTMLElement>('form');\n const invalid = form?.querySelector('[aria-invalid=\"true\"]');\n if (invalid) {\n focusFirstInvalid(form);\n } else {\n form?.querySelector<HTMLElement>('.form-error')?.scrollIntoView?.({ block: 'nearest' });\n }\n }, { injector: this.injector });\n }\n\n /** The translated text of a key, for computed descriptions. */\n protected t(key: string, params?: Record<string, unknown>): string {\n return this.translate.instant(key, params) as string;\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n\n checked(event: Event): boolean {\n return (event.target as HTMLInputElement).checked;\n }\n}\n","import { ChangeDetectionStrategy, Component, OnInit, afterNextRender, computed, inject, input, output, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Observable, concat, defer, of, tap } from 'rxjs';\nimport {\n AgentAccountability,\n NhAssistantAdminApiService,\n RunCatalog,\n ToolCatalogEntry,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAccountPickerComponent } from './nh-assistant-account-picker.component';\nimport { RunConfigForm } from './run-config-form';\nimport {\n RunConfigErrors,\n ScheduleTarget,\n blank,\n checkBudget,\n checkWhole,\n cronExamples,\n dashCase,\n describePolicy,\n eventOptions,\n WorksOnStatement,\n policyOptions,\n requireText,\n ruleOptions,\n runConfigLimits,\n toolChoices,\n subjectSetOptions,\n systemSubjectType,\n timeZoneOptions,\n toDashCase,\n toNumber,\n withBudgetField,\n withScheduleTargetError,\n worksOnCovers\n} from './run-config-shared';\n\nlet nextId = 0;\n\nexport type WorkSetupStep = 'when' | 'what' | 'who' | 'limits' | 'review';\n\nconst steps: WorkSetupStep[] = ['when', 'what', 'who', 'limits', 'review'];\n\n/** The step whose fields a server error belongs to. */\nconst stepOfField: Record<string, WorkSetupStep> = {\n triggerId: 'when', source: 'when', event: 'when', debounceSeconds: 'when', cron: 'when', timeZone: 'when',\n subjectSet: 'when', message: 'when', skill: 'when', conflict: 'when',\n skillId: 'what', name: 'what', description: 'what', instructions: 'what', tools: 'what', ruleHandler: 'what', profile: 'what',\n accountability: 'who', serviceAccountActorId: 'who',\n approvalPolicy: 'limits', maxTokensPerRun: 'limits', dailyToolCalls: 'limits', dailyTokens: 'limits'\n};\n\n/**\n * Lets an agent created in the administration work on its own in one flow: when it starts, what it\n * does, on whose behalf, who approves its proposals and its limits, and a review. Saving adds the run\n * settings, a skill and a trigger that starts it; the skill and the trigger start in shadow, where\n * nobody is notified and nothing executes, and can be put live at the end. A schedule of an agent\n * that works on the whole application may run for the whole application instead of a set of\n * subjects, once per division for an agent that works per division.\n */\n@Component({\n selector: 'nh-assistant-agent-work-setup',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantPickerComponent, NhAssistantAccountPickerComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-work-setup.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantAgentWorkSetupComponent extends RunConfigForm implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n\n readonly agentId = input.required<string>();\n readonly agentName = input('');\n readonly catalog = input<RunCatalog | null>(null);\n /**\n * What the agent works on: events about other object types are not offered, and a schedule runs\n * for the whole application only for an agent that works on it.\n */\n readonly worksOn = input<WorksOnStatement | null>(null);\n readonly toolSelectors = input<readonly string[]>([]);\n /** The tool catalog, to show what each of the agent's tool selectors offers. */\n readonly toolCatalog = input<readonly ToolCatalogEntry[]>([]);\n readonly toolChoices = computed(() => toolChoices(this.toolSelectors(), this.toolCatalog()));\n readonly takenSkillIds = input<readonly string[]>([]);\n readonly takenTriggerIds = input<readonly string[]>([]);\n /** The setup saved; `live` tells whether the skill and the trigger were put live. */\n readonly completed = output<{ live: boolean }>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-work-setup-${nextId++}`;\n readonly steps = steps;\n readonly examples = cronExamples;\n readonly timeZones = timeZoneOptions().filter(zone => zone.value !== 'UTC');\n readonly accountabilities: AgentAccountability[] = ['service-account', 'subject-responsible', 'agent'];\n readonly maxDescription = runConfigLimits.description;\n readonly maxInstructions = runConfigLimits.instructions;\n readonly maxMessage = runConfigLimits.message;\n protected readonly fields = Object.keys(stepOfField);\n\n readonly step = signal<WorkSetupStep>('when');\n /** Saved parts, so a retry after a refusal does not add them again. */\n private readonly savedSettingsVersion = signal<number | null>(null);\n private readonly savedSkill = signal(false);\n readonly done = signal(false);\n\n // When.\n readonly source = signal<'event' | 'schedule'>('event');\n readonly event = signal('');\n readonly cron = signal('');\n readonly timeZone = signal('');\n readonly subjectSet = signal('');\n /** The administrator's choice of what a schedule runs for; see `target`. */\n readonly scheduleTarget = signal<ScheduleTarget>('application');\n readonly message = signal('');\n // What.\n readonly name = signal('');\n readonly description = signal('');\n readonly ruleHandler = signal('');\n readonly instructions = signal('');\n readonly tools = signal<string[]>([]);\n // Who.\n readonly accountability = signal<AgentAccountability>('service-account');\n readonly serviceAccount = signal('');\n // Approval and limits.\n readonly approvalPolicy = signal('');\n readonly maxTokensPerRun = signal('');\n readonly dailyToolCalls = signal('');\n readonly dailyTokens = signal('');\n\n readonly stepIndex = computed(() => steps.indexOf(this.step()));\n readonly skillId = computed(() => toDashCase(this.name()));\n readonly triggerId = computed(() => {\n const base = this.source() === 'schedule' ? `${this.skillId()}-schedule` : `${this.skillId()}-${this.event()}`;\n return toDashCase(base).slice(0, 64).replace(/-+$/, '');\n });\n readonly accountSearch = computed(() => this.catalog()?.accountSearch === true);\n readonly events = computed(() => eventOptions(this.catalog(), this.worksOn()));\n readonly subjectSets = computed(() => subjectSetOptions(this.catalog()));\n /** A schedule may run for the whole application only for an agent that works on it. */\n readonly offersApplication = computed(() => worksOnCovers(this.worksOn(), systemSubjectType));\n /** What the schedule runs for: the whole application while the agent works on it, otherwise a set. */\n readonly target = computed<ScheduleTarget>(() => this.offersApplication() ? this.scheduleTarget() : 'set');\n /** The agent's work for the whole application runs once per division. */\n readonly perDivision = computed(() => this.worksOn()?.perDivision === true);\n readonly rules = computed(() => ruleOptions(this.catalog()));\n readonly policies = computed(() => {\n this.language();\n return policyOptions(this.catalog(), summary => describePolicy(summary, (key, params) => this.t(key, params)));\n });\n readonly eventDescription = computed(() => this.events().find(option => option.value === this.event())?.description ?? null);\n readonly subjectSetDescription = computed(() => this.subjectSets().find(option => option.value === this.subjectSet())?.description ?? null);\n readonly ruleDescription = computed(() => this.rules().find(option => option.value === this.ruleHandler())?.description ?? null);\n readonly policyDescription = computed(() => this.policies().find(option => option.value === this.approvalPolicy())?.description ?? null);\n\n ngOnInit(): void {\n // A new skill starts with every tool of the agent; the administrator narrows it.\n this.tools.set([...this.toolSelectors()]);\n }\n\n stepState(step: WorkSetupStep): 'current' | 'done' | 'next' {\n const index = steps.indexOf(step);\n return index === this.stepIndex() ? 'current' : index < this.stepIndex() ? 'done' : 'next';\n }\n\n setSource(source: 'event' | 'schedule'): void {\n this.source.set(source);\n this.touch('source');\n }\n\n setTarget(target: ScheduleTarget): void {\n this.scheduleTarget.set(target);\n this.touch('subjectSet');\n }\n\n setAccountability(accountability: AgentAccountability): void {\n this.accountability.set(accountability);\n this.touch('accountability');\n this.touch('serviceAccountActorId');\n }\n\n toggleTool(selector: string, selected: boolean): void {\n this.tools.update(tools => selected ? [...tools.filter(tool => tool !== selector), selector] : tools.filter(tool => tool !== selector));\n this.touch('tools');\n }\n\n useExample(cron: string): void {\n this.cron.set(cron);\n this.touch('cron');\n }\n\n back(): void {\n const index = this.stepIndex();\n if (index > 0) {\n this.go(steps[index - 1]);\n }\n }\n\n next(): void {\n const errors = this.validate(this.step());\n this.serverError.set(null);\n this.clientErrors.set(errors);\n if (Object.keys(errors).length > 0) {\n this.focusFirstInvalid();\n return;\n }\n const index = this.stepIndex();\n if (index < steps.length - 1) {\n this.go(steps[index + 1]);\n }\n }\n\n /** Saves the run settings, the skill and the trigger, in that order, and stops at a refusal. */\n save(live = false): void {\n const errors: RunConfigErrors = {};\n for (const step of steps) {\n Object.assign(errors, this.validate(step));\n }\n const first = Object.keys(errors)[0];\n if (first) {\n this.go(stepOfField[first] ?? 'when', false);\n this.submit(errors, () => of(null), () => undefined);\n return;\n }\n\n const agentId = this.agentId();\n const skillId = this.skillId();\n const triggerId = this.triggerId();\n const schedule = this.source() === 'schedule';\n const forSet = schedule && this.target() === 'set';\n const settings = defer(() => this.admin.saveRunSettings(agentId, {\n accountability: this.accountability(),\n serviceAccountActorId: this.accountability() === 'service-account' ? blank(this.serviceAccount()) : null,\n approvalPolicy: blank(this.approvalPolicy()),\n maxTokensPerRun: toNumber(this.maxTokensPerRun()),\n dailyToolCalls: toNumber(this.dailyToolCalls()),\n dailyTokens: toNumber(this.dailyTokens()),\n expectedVersion: this.savedSettingsVersion(),\n reason: null\n }).pipe(tap(saved => this.savedSettingsVersion.set(saved.version))));\n const skill = defer(() => this.savedSkill()\n ? of(null)\n : this.admin.saveDataSkill(agentId, skillId, {\n description: this.description().trim(),\n instructions: blank(this.instructions()),\n tools: this.tools(),\n ruleHandler: blank(this.ruleHandler()),\n expectedVersion: null,\n reason: null\n }).pipe(tap(() => this.savedSkill.set(true))));\n const trigger = defer(() => this.admin.saveDataTrigger(agentId, triggerId, {\n source: this.source(),\n skill: skillId,\n event: schedule ? null : blank(this.event()),\n cron: schedule ? blank(this.cron()) : null,\n timeZone: schedule ? blank(this.timeZone()) : null,\n // Without a subject set the schedule runs for the whole application.\n subjectSet: forSet ? blank(this.subjectSet()) : null,\n message: schedule ? blank(this.message()) : null,\n conflict: schedule ? 'ignore' : 'coalesce',\n debounceSeconds: schedule ? null : 120,\n expectedVersion: null,\n reason: null\n }));\n const goLive: Observable<unknown>[] = live\n ? [\n defer(() => this.admin.setSkillShadow(agentId, skillId, { mode: 'live', reason: null })),\n defer(() => this.admin.setDataTriggerShadow(agentId, triggerId, { mode: 'live', reason: null }))\n ]\n : [];\n this.submit({}, () => concat(settings, skill, trigger, ...goLive), () => {\n this.done.set(true);\n this.completed.emit({ live });\n }, () => {\n const field = Object.keys(this.fieldErrors())[0];\n this.go(field ? stepOfField[field] ?? 'review' : 'review', false);\n });\n }\n\n protected override mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n const mapped = withScheduleTargetError(\n withBudgetField(errors, this.dailyToolCalls()),\n this.source() === 'schedule' ? this.target() : 'set');\n // The skill id is derived from the name.\n if (mapped['skillId']) {\n const { skillId, ...rest } = mapped;\n return { ...rest, name: skillId };\n }\n return mapped;\n }\n\n private go(step: WorkSetupStep, focus = true): void {\n this.step.set(step);\n if (focus) {\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>(`[data-step=\"${step}\"] legend`)?.focus(), { injector: this.injector });\n }\n }\n\n private validate(step: WorkSetupStep): RunConfigErrors {\n const errors: RunConfigErrors = {};\n switch (step) {\n case 'when':\n if (this.source() === 'event') {\n if (this.event() === '') {\n errors['event'] = { code: 'required' };\n }\n } else {\n requireText(errors, 'cron', this.cron());\n if (this.target() === 'set' && this.subjectSet() === '') {\n errors['subjectSet'] = { code: 'required' };\n }\n requireText(errors, 'message', this.message(), this.maxMessage);\n }\n break;\n case 'what':\n requireText(errors, 'name', this.name());\n if (!errors['name'] && (!dashCase.test(this.skillId()) || this.skillId().length === 0)) {\n errors['name'] = { code: 'name-letters' };\n } else if (!errors['name'] && this.takenSkillIds().includes(this.skillId())) {\n errors['name'] = { code: 'taken' };\n }\n requireText(errors, 'description', this.description(), this.maxDescription);\n if (this.instructions().length > this.maxInstructions) {\n errors['instructions'] = { code: 'too-long', params: { max: this.maxInstructions } };\n }\n if (this.ruleHandler() === '' && this.instructions().trim() === '') {\n errors['instructions'] = { code: 'instructions-for-model' };\n }\n break;\n case 'who':\n if (this.accountability() === 'service-account' && this.serviceAccount().trim() === '') {\n errors['serviceAccountActorId'] = { code: 'required' };\n }\n break;\n case 'limits':\n checkWhole(errors, 'maxTokensPerRun', this.maxTokensPerRun(), 1);\n checkBudget(errors, this.dailyToolCalls(), this.dailyTokens());\n break;\n }\n return errors;\n }\n}\n","<section class=\"stack card\" data-work-setup [attr.aria-labelledby]=\"id + '-title'\">\n <header class=\"stack\">\n <h5 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.run-config.setup.title' | translate: { name: agentName() } }}</h5>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.setup.explain' | translate }}</p>\n <ol class=\"steps\" [attr.aria-label]=\"'nh-assistant.admin.run-config.setup.progress' | translate\">\n @for (item of steps; track item; let index = $index) {\n <li [class.done]=\"stepState(item) === 'done'\" [attr.aria-current]=\"stepState(item) === 'current' ? 'step' : null\">\n @if (stepState(item) === 'done') {\n <nh-assistant-icon name=\"check\" />\n }\n {{ index + 1 }}. {{ 'nh-assistant.admin.run-config.setup.step.' + item | translate }}\n </li>\n }\n </ol>\n </header>\n\n @if (done()) {\n <p class=\"message success\" role=\"status\" data-setup-done>{{ 'nh-assistant.admin.run-config.setup.done' | translate }}</p>\n } @else {\n <form class=\"stack\" novalidate (submit)=\"$event.preventDefault(); step() === 'review' ? save() : next()\">\n @switch (step()) {\n @case ('when') {\n <fieldset class=\"group\" data-step=\"when\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.setup.when.title' | translate }}</legend>\n <div class=\"choices\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.run-config.setup.when.title' | translate\">\n <label class=\"choice\" [class.selected]=\"source() === 'event'\">\n <input type=\"radio\" [name]=\"id + '-source'\" value=\"event\" [checked]=\"source() === 'event'\" (change)=\"setSource('event')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.source-event' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.source-event-hint' | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"source() === 'schedule'\">\n <input type=\"radio\" [name]=\"id + '-source'\" value=\"schedule\" [checked]=\"source() === 'schedule'\" (change)=\"setSource('schedule')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.source-schedule' | translate }}</strong>\n <span class=\"muted\">{{ (offersApplication() ? 'nh-assistant.admin.run-config.triggers.source-schedule-application-hint' : 'nh-assistant.admin.run-config.triggers.source-schedule-hint') | translate }}</span>\n </span>\n </label>\n </div>\n @if (source() === 'event') {\n <div class=\"field\">\n <label [for]=\"id + '-event'\">{{ 'nh-assistant.admin.run-config.triggers.event' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-event'\" [options]=\"events()\" [value]=\"event()\"\n [placeholder]=\"'nh-assistant.admin.run-config.choose' | translate\"\n [invalid]=\"fieldError('event') !== null\"\n [describedBy]=\"describedBy(null, 'event', id + '-event-error')\"\n (valueChange)=\"event.set($event); touch('event')\" />\n @if (errorKey('event'); as key) {\n <p class=\"field-error\" [id]=\"id + '-event-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('event')?.params }}</p>\n }\n @if (events().length === 0) {\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.setup.no-events' | translate }}</p>\n }\n </div>\n } @else {\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-cron'\">{{ 'nh-assistant.admin.run-config.triggers.cron' | translate }}</label>\n <input type=\"text\" class=\"mono\" autocomplete=\"off\" maxlength=\"128\" [id]=\"id + '-cron'\" [value]=\"cron()\"\n [attr.aria-invalid]=\"fieldError('cron') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-cron-hint', 'cron', id + '-cron-error')\"\n (input)=\"cron.set(value($event)); touch('cron')\" />\n <p class=\"hint\" [id]=\"id + '-cron-hint'\">{{ 'nh-assistant.admin.run-config.triggers.cron-hint' | translate }}</p>\n <ul class=\"examples\" [attr.aria-label]=\"'nh-assistant.admin.run-config.triggers.examples' | translate\">\n @for (example of examples; track example.cron) {\n <li><button type=\"button\" (click)=\"useExample(example.cron)\">{{ 'nh-assistant.admin.run-config.triggers.example.' + example.key | translate }}</button></li>\n }\n </ul>\n @if (errorKey('cron'); as key) {\n <p class=\"field-error\" [id]=\"id + '-cron-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('cron')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-zone'\">{{ 'nh-assistant.admin.run-config.triggers.time-zone' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-zone'\" [options]=\"timeZones\" [value]=\"timeZone()\" [noneLabel]=\"'UTC'\"\n [invalid]=\"fieldError('timeZone') !== null\"\n [describedBy]=\"describedBy(null, 'timeZone', id + '-zone-error')\"\n (valueChange)=\"timeZone.set($event); touch('timeZone')\" />\n @if (errorKey('timeZone'); as key) {\n <p class=\"field-error\" [id]=\"id + '-zone-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('timeZone')?.params }}</p>\n }\n </div>\n </div>\n @if (offersApplication()) {\n <!-- An agent that works on the whole application chooses what the schedule runs for. -->\n <div class=\"field\" data-schedule-target>\n <span class=\"label\" [id]=\"id + '-target-label'\">{{ 'nh-assistant.admin.run-config.triggers.target.title' | translate }}</span>\n <div\n class=\"choices\"\n role=\"radiogroup\"\n tabindex=\"-1\"\n [attr.aria-labelledby]=\"id + '-target-label'\"\n [attr.aria-invalid]=\"target() === 'application' && fieldError('subjectSet') ? true : null\"\n [attr.aria-describedby]=\"target() === 'application' ? describedBy(null, 'subjectSet', id + '-target-error') : null\">\n <label class=\"choice\" [class.selected]=\"target() === 'application'\">\n <input type=\"radio\" [name]=\"id + '-target'\" value=\"application\" [checked]=\"target() === 'application'\" (change)=\"setTarget('application')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.target.application' | translate }}</strong>\n <span class=\"muted\" data-target-hint>{{ (perDivision() ? 'nh-assistant.admin.run-config.triggers.target.application-per-division-hint' : 'nh-assistant.admin.run-config.triggers.target.application-hint') | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"target() === 'set'\">\n <input type=\"radio\" [name]=\"id + '-target'\" value=\"set\" [checked]=\"target() === 'set'\" (change)=\"setTarget('set')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.target.set' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.target.set-hint' | translate }}</span>\n </span>\n </label>\n </div>\n @if (target() === 'application' && errorKey('subjectSet'); as key) {\n <p class=\"field-error\" [id]=\"id + '-target-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate }}</p>\n }\n </div>\n }\n @if (target() === 'set') {\n <div class=\"field\">\n <label [for]=\"id + '-set'\">{{ 'nh-assistant.admin.run-config.triggers.subject-set' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-set'\" [options]=\"subjectSets()\" [value]=\"subjectSet()\"\n [placeholder]=\"'nh-assistant.admin.run-config.choose' | translate\"\n [invalid]=\"fieldError('subjectSet') !== null\"\n [describedBy]=\"describedBy(id + '-set-hint', 'subjectSet', id + '-set-error')\"\n (valueChange)=\"subjectSet.set($event); touch('subjectSet')\" />\n <p class=\"hint\" [id]=\"id + '-set-hint'\">{{ 'nh-assistant.admin.run-config.triggers.subject-set-hint' | translate }}</p>\n @if (errorKey('subjectSet'); as key) {\n <p class=\"field-error\" [id]=\"id + '-set-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('subjectSet')?.params }}</p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-message'\">{{ 'nh-assistant.admin.run-config.triggers.message' | translate }}</label>\n <textarea rows=\"2\" [id]=\"id + '-message'\" [value]=\"message()\"\n [attr.aria-invalid]=\"fieldError('message') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-message-hint', 'message', id + '-message-error')\"\n (input)=\"message.set(value($event)); touch('message')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-message-hint'\">{{ 'nh-assistant.admin.run-config.triggers.message-hint' | translate }}</p>\n @if (errorKey('message'); as key) {\n <p class=\"field-error\" [id]=\"id + '-message-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('message')?.params }}</p>\n }\n </div>\n }\n </fieldset>\n }\n @case ('what') {\n <fieldset class=\"group\" data-step=\"what\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.setup.what.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-name'\">{{ 'nh-assistant.admin.run-config.setup.what.name' | translate }}</label>\n <input type=\"text\" autocomplete=\"off\" maxlength=\"64\" [id]=\"id + '-name'\" [value]=\"name()\"\n [attr.aria-invalid]=\"fieldError('name') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-name-hint', 'name', id + '-name-error')\"\n (input)=\"name.set(value($event)); touch('name')\" />\n <p class=\"hint\" [id]=\"id + '-name-hint'\">\n {{ (skillId() ? 'nh-assistant.admin.run-config.setup.what.name-id' : 'nh-assistant.admin.run-config.setup.what.name-hint') | translate: { id: skillId() } }}\n </p>\n @if (errorKey('name'); as key) {\n <p class=\"field-error\" [id]=\"id + '-name-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('name')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-description'\">{{ 'nh-assistant.admin.run-config.skills.description-label' | translate }}</label>\n <input type=\"text\" [id]=\"id + '-description'\" [value]=\"description()\"\n [attr.aria-invalid]=\"fieldError('description') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-description-hint', 'description', id + '-description-error')\"\n (input)=\"description.set(value($event)); touch('description')\" />\n <p class=\"hint\" [id]=\"id + '-description-hint'\">\n <span>{{ 'nh-assistant.admin.run-config.skills.description-hint' | translate }}</span>\n <span class=\"counter\">{{ 'nh-assistant.admin.characters' | translate: { count: description().length, max: maxDescription } }}</span>\n </p>\n @if (errorKey('description'); as key) {\n <p class=\"field-error\" [id]=\"id + '-description-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('description')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-rules'\">{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-rules'\" [options]=\"rules()\" [value]=\"ruleHandler()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.model' | translate\"\n [invalid]=\"fieldError('ruleHandler') !== null\"\n [describedBy]=\"describedBy(id + '-rules-hint', 'ruleHandler', id + '-rules-error')\"\n (valueChange)=\"ruleHandler.set($event); touch('ruleHandler'); touch('instructions')\" />\n <p class=\"hint\" [id]=\"id + '-rules-hint'\">\n {{ (ruleHandler() ? 'nh-assistant.admin.run-config.skills.rules-hint' : 'nh-assistant.admin.run-config.skills.model-hint') | translate }}\n </p>\n @if (errorKey('ruleHandler'); as key) {\n <p class=\"field-error\" [id]=\"id + '-rules-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('ruleHandler')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-instructions'\">{{ 'nh-assistant.admin.run-config.skills.instructions' | translate }}</label>\n <textarea rows=\"4\" [id]=\"id + '-instructions'\" [value]=\"instructions()\"\n [attr.aria-invalid]=\"fieldError('instructions') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-instructions-hint', 'instructions', id + '-instructions-error')\"\n (input)=\"instructions.set(value($event)); touch('instructions')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-instructions-hint'\">{{ 'nh-assistant.admin.run-config.skills.instructions-hint' | translate }} {{ 'nh-assistant.admin.run-config.skills.background-hint' | translate }}</p>\n @if (errorKey('instructions'); as key) {\n <p class=\"field-error\" [id]=\"id + '-instructions-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('instructions')?.params }}</p>\n }\n </div>\n <fieldset class=\"field\">\n <legend>{{ 'nh-assistant.admin.run-config.skills.tools' | translate }}</legend>\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.skills.tools-hint' | translate }}</p>\n @for (choice of toolChoices(); track choice.selector) {\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"tools().includes(choice.selector)\" (change)=\"toggleTool(choice.selector, checked($event))\" />\n <span class=\"tool-choice\">\n <span class=\"mono\">{{ choice.selector }}</span>\n @if (choice.description) {\n <span class=\"muted block\">{{ choice.description }}</span>\n } @else if (choice.matches !== null) {\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.skills.tools-pattern' | translate: { count: choice.matches } }}</span>\n }\n </span>\n </label>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.no-selectors' | translate }}</p>\n }\n @if (errorKey('tools'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('tools')?.params }}</p>\n }\n </fieldset>\n </fieldset>\n }\n @case ('who') {\n <fieldset class=\"group\" data-step=\"who\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.settings.who.title' | translate }}</legend>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.who.explain' | translate }}</p>\n <div class=\"choices\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.run-config.settings.who.title' | translate\">\n @for (option of accountabilities; track option) {\n <label class=\"choice\" [class.selected]=\"accountability() === option\">\n <input type=\"radio\" [name]=\"id + '-accountability'\" [value]=\"option\" [checked]=\"accountability() === option\" (change)=\"setAccountability(option)\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.settings.accountability.' + option | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.accountability-explain.' + option | translate }}</span>\n </span>\n </label>\n }\n </div>\n @if (accountability() === 'service-account') {\n <div class=\"field\">\n <label [for]=\"id + '-account'\">{{ 'nh-assistant.admin.run-config.settings.service-account' | translate }}</label>\n <nh-assistant-account-picker [inputId]=\"id + '-account'\" [value]=\"serviceAccount()\" [searchable]=\"accountSearch()\"\n [invalid]=\"fieldError('serviceAccountActorId') !== null\"\n [describedBy]=\"describedBy(id + '-account-hint', 'serviceAccountActorId', id + '-account-error')\"\n (valueChange)=\"serviceAccount.set($event); touch('serviceAccountActorId')\" />\n <p class=\"hint\" [id]=\"id + '-account-hint'\">\n {{ (accountSearch() ? 'nh-assistant.admin.run-config.account.search-hint' : 'nh-assistant.admin.run-config.account.id-hint') | translate }}\n </p>\n @if (errorKey('serviceAccountActorId'); as key) {\n <p class=\"field-error\" [id]=\"id + '-account-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('serviceAccountActorId')?.params }}</p>\n }\n </div>\n }\n @if (errorKey('accountability'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('accountability')?.params }}</p>\n }\n </fieldset>\n }\n @case ('limits') {\n <fieldset class=\"group\" data-step=\"limits\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.setup.limits.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-policy'\">{{ 'nh-assistant.admin.run-config.approval-policy' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-policy'\" [options]=\"policies()\" [value]=\"approvalPolicy()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.settings.approval.default' | translate\"\n [invalid]=\"fieldError('approvalPolicy') !== null\"\n [describedBy]=\"describedBy(id + '-policy-hint', 'approvalPolicy', id + '-policy-error')\"\n (valueChange)=\"approvalPolicy.set($event); touch('approvalPolicy')\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.run-config.settings.approval.hint' | translate }}</p>\n @if (errorKey('approvalPolicy'); as key) {\n <p class=\"field-error\" [id]=\"id + '-policy-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('approvalPolicy')?.params }}</p>\n }\n </div>\n <p class=\"muted\" [id]=\"id + '-limits-hint'\">{{ 'nh-assistant.admin.run-config.budget-hint' | translate }}</p>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-run-tokens'\">{{ 'nh-assistant.admin.run-config.max-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-run-tokens'\" [value]=\"maxTokensPerRun()\"\n [attr.aria-invalid]=\"fieldError('maxTokensPerRun') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'maxTokensPerRun', id + '-run-tokens-error')\"\n (input)=\"maxTokensPerRun.set(value($event)); touch('maxTokensPerRun')\" />\n @if (errorKey('maxTokensPerRun'); as key) {\n <p class=\"field-error\" [id]=\"id + '-run-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxTokensPerRun')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-daily-calls'\">{{ 'nh-assistant.admin.run-config.daily-tool-calls' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-daily-calls'\" [value]=\"dailyToolCalls()\"\n [attr.aria-invalid]=\"fieldError('dailyToolCalls') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyToolCalls', id + '-daily-calls-error')\"\n (input)=\"dailyToolCalls.set(value($event)); touch('dailyToolCalls'); touch('dailyTokens')\" />\n @if (errorKey('dailyToolCalls'); as key) {\n <p class=\"field-error\" [id]=\"id + '-daily-calls-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyToolCalls')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-daily-tokens'\">{{ 'nh-assistant.admin.run-config.daily-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-daily-tokens'\" [value]=\"dailyTokens()\"\n [attr.aria-invalid]=\"fieldError('dailyTokens') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyTokens', id + '-daily-tokens-error')\"\n (input)=\"dailyTokens.set(value($event)); touch('dailyTokens'); touch('dailyToolCalls')\" />\n @if (errorKey('dailyTokens'); as key) {\n <p class=\"field-error\" [id]=\"id + '-daily-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyTokens')?.params }}</p>\n }\n </div>\n </div>\n </fieldset>\n }\n @case ('review') {\n <fieldset class=\"group\" data-step=\"review\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.setup.review.title' | translate }}</legend>\n <dl class=\"review\">\n <dt>{{ 'nh-assistant.admin.run-config.setup.step.when' | translate }}</dt>\n <dd>\n @if (source() === 'event') {\n {{ 'nh-assistant.admin.run-config.setup.review.event' | translate: { event: event() } }}\n @if (eventDescription(); as description) { <span class=\"muted block\">{{ description }}</span> }\n } @else if (target() === 'application') {\n <!-- Without a subject set the schedule runs for the whole application, per division for a per-division agent. -->\n <span data-review-target>{{ (perDivision() ? 'nh-assistant.admin.run-config.setup.review.schedule-divisions' : 'nh-assistant.admin.run-config.setup.review.schedule-application') | translate: { cron: cron(), zone: timeZone() || 'UTC' } }}</span>\n } @else {\n {{ 'nh-assistant.admin.run-config.setup.review.schedule' | translate: { cron: cron(), zone: timeZone() || 'UTC', set: subjectSet() } }}\n @if (subjectSetDescription(); as description) { <span class=\"muted block\">{{ description }}</span> }\n }\n </dd>\n <dt>{{ 'nh-assistant.admin.run-config.setup.step.what' | translate }}</dt>\n <dd>\n <strong>{{ name() }}</strong> <span class=\"mono\">({{ skillId() }})</span>\n <span class=\"block\">{{ description() }}</span>\n <span class=\"muted block\">\n {{ ruleHandler() ? ruleHandler() + (ruleDescription() ? ' — ' + ruleDescription() : '') : ('nh-assistant.admin.run-config.model' | translate) }}\n </span>\n </dd>\n <dt>{{ 'nh-assistant.admin.run-config.setup.step.who' | translate }}</dt>\n <dd>{{ 'nh-assistant.admin.run-config.settings.accountability.' + accountability() | translate }}</dd>\n <dt>{{ 'nh-assistant.admin.run-config.setup.step.limits' | translate }}</dt>\n <dd>\n {{ approvalPolicy() || ('nh-assistant.admin.run-config.settings.approval.default' | translate) }}\n @if (policyDescription(); as description) { <span class=\"muted block\">{{ description }}</span> }\n </dd>\n </dl>\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.setup.review.shadow' | translate }}</p>\n </fieldset>\n }\n }\n\n @if (hasErrors()) {\n <div class=\"form-error\" role=\"alert\" data-form-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n @if (serverError(); as failure) {\n @if (failure.code === 'assistant-validation') {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n } @else {\n {{ errorKeys() | nhAssistantTranslate: failure.code }}\n }\n } @else {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n }\n </div>\n </div>\n }\n <div class=\"actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"cancelled.emit()\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n @if (stepIndex() > 0) {\n <button class=\"secondary\" type=\"button\" [disabled]=\"busy()\" (click)=\"back()\">{{ 'nh-assistant.admin.run-config.setup.back' | translate }}</button>\n }\n @if (step() === 'review') {\n <button class=\"secondary\" type=\"button\" data-setup-live [disabled]=\"busy()\" (click)=\"save(true)\">{{ 'nh-assistant.admin.run-config.setup.save-live' | translate }}</button>\n <button class=\"primary\" type=\"submit\" [disabled]=\"busy()\">{{ (busy() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.run-config.setup.save-shadow') | translate }}</button>\n } @else {\n <button class=\"primary\" type=\"submit\">{{ 'nh-assistant.admin.run-config.setup.next' | translate }}</button>\n }\n </div>\n </form>\n }\n</section>\n","import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { FileLimits, ɵNhAssistantIconComponent as NhAssistantIconComponent } from '@newheap/platform-ai-chat';\nimport { FileLimitField, FileLimitsDraft, RunConfigErrors, fieldErrorKey, fileLimitFields, megabytesText } from './run-config-shared';\n\n/** How a form shows one file limit. */\ninterface FileLimitControl {\n field: FileLimitField;\n /** The id suffix of the control. */\n key: string;\n label: string;\n step: string;\n inputMode: 'decimal' | 'numeric';\n}\n\nconst controls: Record<FileLimitField, FileLimitControl> = {\n maxFileBytes: { field: 'maxFileBytes', key: 'file-size', label: 'max-file-megabytes', step: 'any', inputMode: 'decimal' },\n maxFilePages: { field: 'maxFilePages', key: 'file-pages', label: 'max-file-pages', step: '1', inputMode: 'numeric' },\n maxFilesPerTurn: { field: 'maxFilesPerTurn', key: 'files-per-turn', label: 'max-files-per-turn', step: '1', inputMode: 'numeric' },\n maxFileTokensPerTurn: { field: 'maxFileTokensPerTurn', key: 'file-tokens', label: 'max-file-tokens-per-turn', step: '1', inputMode: 'numeric' }\n};\n\n/**\n * The lower file limits of an agent or a skill that accepts files, next to its \"Accepts files\"\n * switch: the largest file in megabytes, the most pages of one file, the most files of one turn and\n * the most file tokens of one turn. Each field names the application's limit, which it can only\n * lower; an empty field keeps it. Errors appear at their fields with the form's other errors.\n */\n@Component({\n selector: 'nh-assistant-file-limits-fields',\n standalone: true,\n imports: [TranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-file-limits-fields.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantFileLimitsFieldsComponent {\n /** The form's limits. */\n readonly draft = input.required<FileLimitsDraft>();\n /** The application's limits from the run catalog; `null` on older servers. */\n readonly application = input<FileLimits | null | undefined>(null);\n /** The form's field errors, by server field name. */\n readonly errors = input<RunConfigErrors>({});\n /** The prefix of the controls' ids. */\n readonly idPrefix = input.required<string>();\n /** The hint under the title: what an empty field keeps. */\n readonly hintKey = input.required<string>();\n /** A field the administrator changed, so the form clears its error. */\n readonly touched = output<FileLimitField>();\n\n readonly controls = fileLimitFields.map(field => controls[field]);\n\n idOf(control: FileLimitControl, suffix = ''): string {\n return `${this.idPrefix()}-${control.key}${suffix}`;\n }\n\n /** The application's limit as the field shows it: megabytes for the file size. */\n applicationLimit(control: FileLimitControl): string | null {\n const application = this.application();\n if (!application) {\n return null;\n }\n const value = application[control.field];\n return control.field === 'maxFileBytes' ? `${megabytesText(value)} MB` : String(value);\n }\n\n /** The upper bound a browser shows for the field. */\n max(control: FileLimitControl): number | null {\n const application = this.application();\n if (!application) {\n return null;\n }\n return control.field === 'maxFileBytes' ? application.maxFileBytes / (1024 * 1024) : application[control.field];\n }\n\n errorKey(control: FileLimitControl): string | null {\n return fieldErrorKey(this.errors()[control.field]);\n }\n\n errorParams(control: FileLimitControl): Record<string, unknown> | undefined {\n return this.errors()[control.field]?.params;\n }\n\n describedBy(control: FileLimitControl): string {\n const ids = [`${this.idPrefix()}-file-limits-hint`];\n if (this.application()) {\n ids.push(this.idOf(control, '-limit'));\n }\n if (this.errors()[control.field]) {\n ids.push(this.idOf(control, '-error'));\n }\n return ids.join(' ');\n }\n\n change(control: FileLimitControl, event: Event): void {\n this.draft().text(control.field).set((event.target as HTMLInputElement).value);\n this.touched.emit(control.field);\n }\n}\n","<fieldset class=\"field file-limits\" data-file-limits>\n <legend>{{ 'nh-assistant.admin.run-config.files.limits-title' | translate }}</legend>\n <p class=\"hint\" [id]=\"idPrefix() + '-file-limits-hint'\">{{ hintKey() | translate }}</p>\n <div class=\"grid\">\n @for (control of controls; track control.field) {\n <div class=\"field\" [attr.data-file-limit]=\"control.field\">\n <label [for]=\"idOf(control)\">{{ 'nh-assistant.admin.run-config.files.' + control.label | translate }}</label>\n <input type=\"number\" min=\"0\" [attr.step]=\"control.step\" [attr.max]=\"max(control)\" [attr.inputmode]=\"control.inputMode\"\n [id]=\"idOf(control)\" [value]=\"draft().text(control.field)()\"\n [attr.aria-invalid]=\"errorKey(control) ? true : null\"\n [attr.aria-describedby]=\"describedBy(control)\"\n (input)=\"change(control, $event)\" />\n @if (applicationLimit(control); as limit) {\n <p class=\"hint\" [id]=\"idOf(control, '-limit')\">{{ 'nh-assistant.admin.run-config.files.application-limit' | translate: { value: limit } }}</p>\n }\n @if (errorKey(control); as key) {\n <p class=\"field-error\" [id]=\"idOf(control, '-error')\"><nh-assistant-icon name=\"warning\" />{{ key | translate: errorParams(control) }}</p>\n }\n </div>\n }\n </div>\n</fieldset>\n","import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n AgentAccountability,\n AgentElevatedReads,\n AgentRunSettings,\n AgentRunSettingsRequest,\n NhAssistantAdminApiService,\n RunCatalog,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAccountPickerComponent } from './nh-assistant-account-picker.component';\nimport { NhAssistantFileLimitsFieldsComponent } from './nh-assistant-file-limits-fields.component';\nimport { RunConfigForm } from './run-config-form';\nimport {\n RunConfigErrors,\n blank,\n checkBudget,\n checkWhole,\n describePolicy,\n FileLimitsDraft,\n numberText,\n policyOptions,\n profileOptions,\n ruleOptions,\n runConfigLimits,\n toNumber,\n withBudgetField\n} from './run-config-shared';\n\nlet nextId = 0;\n\nconst defaults = { retries: '3', concurrent: '4', perSubject: '10' };\n\n/**\n * The run settings of an agent created in the administration, as questions: who the agent answers to,\n * how it works, who approves its proposals, and its limits, with the rarely changed options under\n * \"Advanced\". Errors appear at their fields and next to the actions.\n */\n@Component({\n selector: 'nh-assistant-run-settings-form',\n standalone: true,\n imports: [\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantPickerComponent,\n NhAssistantAccountPickerComponent,\n NhAssistantFileLimitsFieldsComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-run-settings-form.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantRunSettingsFormComponent extends RunConfigForm implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n\n readonly agentId = input.required<string>();\n readonly catalog = input<RunCatalog | null>(null);\n /** The current run settings; `null` adds them. */\n readonly settings = input<AgentRunSettings | null>(null);\n readonly saved = output<AgentRunSettings>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-run-settings-${nextId++}`;\n readonly maxReason = runConfigLimits.reason;\n readonly accountabilities: AgentAccountability[] = ['service-account', 'subject-responsible', 'agent'];\n readonly elevatedReadModes: AgentElevatedReads[] = ['restricted', 'deny'];\n protected readonly fields = [\n 'accountability', 'serviceAccountActorId', 'ruleHandler', 'approvalPolicy', 'triageProfile', 'retryCount',\n 'maxConcurrentRuns', 'maxRunsPerSubjectPerDay', 'maxTokensPerRun', 'dailyToolCalls', 'dailyTokens',\n 'elevatedReads', 'allowGatewayReads', 'reason', 'maxFileBytes', 'maxFilePages', 'maxFilesPerTurn', 'maxFileTokensPerTurn'\n ];\n\n readonly accountability = signal<AgentAccountability>('service-account');\n readonly serviceAccount = signal('');\n readonly approvalPolicy = signal('');\n readonly ruleHandler = signal('');\n readonly triageProfile = signal('');\n readonly retryCount = signal(defaults.retries);\n readonly maxConcurrentRuns = signal(defaults.concurrent);\n readonly maxRunsPerSubjectPerDay = signal(defaults.perSubject);\n readonly maxTokensPerRun = signal('');\n readonly dailyToolCalls = signal('');\n readonly dailyTokens = signal('');\n readonly allowGatewayReads = signal(false);\n readonly delegateFromInitiator = signal(false);\n /** Whether people's messages and the agent's tools may give it files; off for a new agent. */\n readonly acceptsFiles = signal(false);\n /** The agent's lower file limits, next to accepting files; empty keeps the application's. */\n readonly fileLimits = new FileLimitsDraft();\n readonly elevatedReads = signal<AgentElevatedReads>('restricted');\n readonly reason = signal('');\n readonly advancedOpen = signal(false);\n\n readonly accountSearch = computed(() => this.catalog()?.accountSearch === true);\n readonly rules = computed(() => ruleOptions(this.catalog()));\n readonly profiles = computed(() => profileOptions(this.catalog()));\n readonly policies = computed(() => {\n this.language();\n return policyOptions(this.catalog(), summary => describePolicy(summary, (key, params) => this.t(key, params)));\n });\n\n /** An error under \"Advanced\" keeps it open, so the field with the error can be seen. */\n readonly advancedHasErrors = computed(() => ['retryCount', 'maxConcurrentRuns', 'maxRunsPerSubjectPerDay', 'triageProfile',\n 'elevatedReads', 'allowGatewayReads'].some(field => this.fieldError(field) !== null));\n\n /** Whether the advanced options differ from their defaults. */\n private readonly advancedInUse = computed(() =>\n this.retryCount() !== defaults.retries\n || this.maxConcurrentRuns() !== defaults.concurrent\n || this.maxRunsPerSubjectPerDay() !== defaults.perSubject\n || this.triageProfile() !== ''\n || this.elevatedReads() !== 'restricted'\n || this.allowGatewayReads()\n || this.delegateFromInitiator());\n\n ngOnInit(): void {\n const settings = this.settings();\n this.accountability.set(settings?.accountability ?? 'service-account');\n this.serviceAccount.set(settings?.serviceAccountActorId ?? '');\n this.approvalPolicy.set(settings?.approvalPolicy ?? '');\n this.ruleHandler.set(settings?.ruleHandler ?? '');\n this.triageProfile.set(settings?.triageProfile ?? '');\n this.retryCount.set(String(settings?.retryCount ?? defaults.retries));\n this.maxConcurrentRuns.set(String(settings?.maxConcurrentRuns ?? defaults.concurrent));\n this.maxRunsPerSubjectPerDay.set(String(settings?.maxRunsPerSubjectPerDay ?? defaults.perSubject));\n this.maxTokensPerRun.set(numberText(settings?.maxTokensPerRun));\n this.dailyToolCalls.set(numberText(settings?.dailyToolCalls));\n this.dailyTokens.set(numberText(settings?.dailyTokens));\n this.allowGatewayReads.set(settings?.allowGatewayReads ?? false);\n this.delegateFromInitiator.set(settings?.delegateFromInitiator ?? false);\n this.acceptsFiles.set(settings?.acceptsFiles ?? false);\n this.fileLimits.load(settings);\n this.elevatedReads.set(settings?.elevatedReads ?? 'restricted');\n this.advancedOpen.set(this.advancedInUse());\n }\n\n setAccountability(accountability: AgentAccountability): void {\n this.accountability.set(accountability);\n this.touch('accountability');\n this.touch('serviceAccountActorId');\n }\n\n save(): void {\n const errors: RunConfigErrors = {};\n if (this.accountability() === 'service-account' && this.serviceAccount().trim() === '') {\n errors['serviceAccountActorId'] = { code: 'required' };\n }\n checkWhole(errors, 'retryCount', this.retryCount(), ...runConfigLimits.retries, true);\n checkWhole(errors, 'maxConcurrentRuns', this.maxConcurrentRuns(), ...runConfigLimits.concurrent, true);\n checkWhole(errors, 'maxRunsPerSubjectPerDay', this.maxRunsPerSubjectPerDay(), ...runConfigLimits.perSubject, true);\n checkWhole(errors, 'maxTokensPerRun', this.maxTokensPerRun(), 1);\n checkBudget(errors, this.dailyToolCalls(), this.dailyTokens());\n if (this.acceptsFiles()) {\n this.fileLimits.check(errors, this.catalog()?.fileLimits);\n }\n\n const request: AgentRunSettingsRequest = {\n accountability: this.accountability(),\n serviceAccountActorId: this.accountability() === 'service-account' ? blank(this.serviceAccount()) : null,\n delegateFromInitiator: this.delegateFromInitiator(),\n allowGatewayReads: this.allowGatewayReads(),\n elevatedReads: this.elevatedReads(),\n approvalPolicy: blank(this.approvalPolicy()),\n retryCount: toNumber(this.retryCount()),\n maxConcurrentRuns: toNumber(this.maxConcurrentRuns()),\n maxRunsPerSubjectPerDay: toNumber(this.maxRunsPerSubjectPerDay()),\n maxTokensPerRun: toNumber(this.maxTokensPerRun()),\n dailyToolCalls: toNumber(this.dailyToolCalls()),\n dailyTokens: toNumber(this.dailyTokens()),\n triageProfile: blank(this.triageProfile()),\n ruleHandler: blank(this.ruleHandler()),\n expectedVersion: this.settings()?.version ?? null,\n reason: blank(this.reason()),\n acceptsFiles: this.acceptsFiles(),\n ...this.fileLimits.toRequest(this.acceptsFiles())\n };\n this.submit(errors, () => this.admin.saveRunSettings(this.agentId(), request), settings => this.saved.emit(settings));\n }\n\n protected override mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n return withBudgetField(errors, this.dailyToolCalls());\n }\n}\n","<form class=\"stack card\" data-form=\"settings\" novalidate (submit)=\"$event.preventDefault(); save()\">\n <h5>{{ (settings() ? 'nh-assistant.admin.run-config.settings.edit-title' : 'nh-assistant.admin.run-config.settings.add-title') | translate }}</h5>\n\n <fieldset class=\"group\" [attr.aria-describedby]=\"id + '-who-explain'\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.who.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-who-explain'\">{{ 'nh-assistant.admin.run-config.settings.who.explain' | translate }}</p>\n <div class=\"choices\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.run-config.settings.who.title' | translate\">\n @for (option of accountabilities; track option) {\n <label class=\"choice\" [class.selected]=\"accountability() === option\">\n <input type=\"radio\" [name]=\"id + '-accountability'\" [value]=\"option\" [checked]=\"accountability() === option\" (change)=\"setAccountability(option)\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.settings.accountability.' + option | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.accountability-explain.' + option | translate }}</span>\n </span>\n </label>\n }\n </div>\n @if (errorKey('accountability'); as key) {\n <p class=\"field-error\" [id]=\"id + '-accountability-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('accountability')?.params }}</p>\n }\n @if (accountability() === 'service-account') {\n <div class=\"field\">\n <label [for]=\"id + '-service-account'\">{{ 'nh-assistant.admin.run-config.settings.service-account' | translate }}</label>\n <nh-assistant-account-picker\n [inputId]=\"id + '-service-account'\"\n [value]=\"serviceAccount()\"\n [searchable]=\"accountSearch()\"\n [invalid]=\"fieldError('serviceAccountActorId') !== null\"\n [describedBy]=\"describedBy(id + '-service-account-hint', 'serviceAccountActorId', id + '-service-account-error')\"\n (valueChange)=\"serviceAccount.set($event); touch('serviceAccountActorId')\" />\n <p class=\"hint\" [id]=\"id + '-service-account-hint'\">\n {{ (accountSearch() ? 'nh-assistant.admin.run-config.account.search-hint' : 'nh-assistant.admin.run-config.account.id-hint') | translate }}\n </p>\n @if (errorKey('serviceAccountActorId'); as key) {\n <p class=\"field-error\" [id]=\"id + '-service-account-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('serviceAccountActorId')?.params }}</p>\n }\n </div>\n }\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.how.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-rule-handler'\">{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-rule-handler'\"\n [options]=\"rules()\"\n [value]=\"ruleHandler()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.model' | translate\"\n [invalid]=\"fieldError('ruleHandler') !== null\"\n [describedBy]=\"describedBy(id + '-rule-handler-hint', 'ruleHandler', id + '-rule-handler-error')\"\n (valueChange)=\"ruleHandler.set($event); touch('ruleHandler')\" />\n <p class=\"hint\" [id]=\"id + '-rule-handler-hint'\">{{ 'nh-assistant.admin.run-config.settings.how.hint' | translate }}</p>\n @if (errorKey('ruleHandler'); as key) {\n <p class=\"field-error\" [id]=\"id + '-rule-handler-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('ruleHandler')?.params }}</p>\n }\n </div>\n <label class=\"check\" data-accepts-files>\n <input type=\"checkbox\" [checked]=\"acceptsFiles()\" (change)=\"acceptsFiles.set(checked($event))\" />\n <span>\n {{ 'nh-assistant.admin.run-config.files.label' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.files.agent-hint' | translate }}</span>\n </span>\n </label>\n @if (acceptsFiles()) {\n <nh-assistant-file-limits-fields\n [draft]=\"fileLimits\"\n [application]=\"catalog()?.fileLimits\"\n [errors]=\"fieldErrors()\"\n [idPrefix]=\"id\"\n hintKey=\"nh-assistant.admin.run-config.files.agent-limits-hint\"\n (touched)=\"touch($event)\" />\n }\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.approval.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-policy'\">{{ 'nh-assistant.admin.run-config.approval-policy' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-policy'\"\n [options]=\"policies()\"\n [value]=\"approvalPolicy()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.settings.approval.default' | translate\"\n [invalid]=\"fieldError('approvalPolicy') !== null\"\n [describedBy]=\"describedBy(id + '-policy-hint', 'approvalPolicy', id + '-policy-error')\"\n (valueChange)=\"approvalPolicy.set($event); touch('approvalPolicy')\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.run-config.settings.approval.hint' | translate }}</p>\n @if (errorKey('approvalPolicy'); as key) {\n <p class=\"field-error\" [id]=\"id + '-policy-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('approvalPolicy')?.params }}</p>\n }\n </div>\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.limits.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-limits-hint'\">{{ 'nh-assistant.admin.run-config.budget-hint' | translate }}</p>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-run-tokens'\">{{ 'nh-assistant.admin.run-config.max-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-run-tokens'\" [value]=\"maxTokensPerRun()\"\n [attr.aria-invalid]=\"fieldError('maxTokensPerRun') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'maxTokensPerRun', id + '-run-tokens-error')\"\n (input)=\"maxTokensPerRun.set(value($event)); touch('maxTokensPerRun')\" />\n @if (errorKey('maxTokensPerRun'); as key) {\n <p class=\"field-error\" [id]=\"id + '-run-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxTokensPerRun')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-daily-calls'\">{{ 'nh-assistant.admin.run-config.daily-tool-calls' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-daily-calls'\" [value]=\"dailyToolCalls()\"\n [attr.aria-invalid]=\"fieldError('dailyToolCalls') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyToolCalls', id + '-daily-calls-error')\"\n (input)=\"dailyToolCalls.set(value($event)); touch('dailyToolCalls'); touch('dailyTokens')\" />\n @if (errorKey('dailyToolCalls'); as key) {\n <p class=\"field-error\" [id]=\"id + '-daily-calls-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyToolCalls')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-daily-tokens'\">{{ 'nh-assistant.admin.run-config.daily-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-daily-tokens'\" [value]=\"dailyTokens()\"\n [attr.aria-invalid]=\"fieldError('dailyTokens') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyTokens', id + '-daily-tokens-error')\"\n (input)=\"dailyTokens.set(value($event)); touch('dailyTokens'); touch('dailyToolCalls')\" />\n @if (errorKey('dailyTokens'); as key) {\n <p class=\"field-error\" [id]=\"id + '-daily-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyTokens')?.params }}</p>\n }\n </div>\n </div>\n </fieldset>\n\n <details class=\"advanced\" data-advanced [open]=\"advancedOpen() || advancedHasErrors()\" (toggle)=\"advancedOpen.set($any($event.target).open)\">\n <summary>{{ 'nh-assistant.admin.run-config.advanced.title' | translate }}</summary>\n <div class=\"stack\">\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.advanced.explain' | translate }}</p>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-retries'\">{{ 'nh-assistant.admin.run-config.settings.retries' | translate }}</label>\n <input type=\"number\" min=\"0\" max=\"10\" inputmode=\"numeric\" [id]=\"id + '-retries'\" [value]=\"retryCount()\"\n [attr.aria-invalid]=\"fieldError('retryCount') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-retries-hint', 'retryCount', id + '-retries-error')\"\n (input)=\"retryCount.set(value($event)); touch('retryCount')\" />\n <p class=\"hint\" [id]=\"id + '-retries-hint'\">{{ 'nh-assistant.admin.run-config.settings.retries-hint' | translate }}</p>\n @if (errorKey('retryCount'); as key) {\n <p class=\"field-error\" [id]=\"id + '-retries-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('retryCount')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-concurrent'\">{{ 'nh-assistant.admin.run-config.settings.max-concurrent' | translate }}</label>\n <input type=\"number\" min=\"1\" max=\"100\" inputmode=\"numeric\" [id]=\"id + '-concurrent'\" [value]=\"maxConcurrentRuns()\"\n [attr.aria-invalid]=\"fieldError('maxConcurrentRuns') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-concurrent-hint', 'maxConcurrentRuns', id + '-concurrent-error')\"\n (input)=\"maxConcurrentRuns.set(value($event)); touch('maxConcurrentRuns')\" />\n <p class=\"hint\" [id]=\"id + '-concurrent-hint'\">{{ 'nh-assistant.admin.run-config.settings.max-concurrent-hint' | translate }}</p>\n @if (errorKey('maxConcurrentRuns'); as key) {\n <p class=\"field-error\" [id]=\"id + '-concurrent-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxConcurrentRuns')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-per-subject'\">{{ 'nh-assistant.admin.run-config.settings.max-per-subject' | translate }}</label>\n <input type=\"number\" min=\"1\" max=\"1000\" inputmode=\"numeric\" [id]=\"id + '-per-subject'\" [value]=\"maxRunsPerSubjectPerDay()\"\n [attr.aria-invalid]=\"fieldError('maxRunsPerSubjectPerDay') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-per-subject-hint', 'maxRunsPerSubjectPerDay', id + '-per-subject-error')\"\n (input)=\"maxRunsPerSubjectPerDay.set(value($event)); touch('maxRunsPerSubjectPerDay')\" />\n <p class=\"hint\" [id]=\"id + '-per-subject-hint'\">{{ 'nh-assistant.admin.run-config.settings.max-per-subject-hint' | translate }}</p>\n @if (errorKey('maxRunsPerSubjectPerDay'); as key) {\n <p class=\"field-error\" [id]=\"id + '-per-subject-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxRunsPerSubjectPerDay')?.params }}</p>\n }\n </div>\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-triage'\">{{ 'nh-assistant.admin.run-config.settings.triage' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-triage'\"\n [options]=\"profiles()\"\n [value]=\"triageProfile()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.settings.no-triage' | translate\"\n [invalid]=\"fieldError('triageProfile') !== null\"\n [describedBy]=\"describedBy(id + '-triage-hint', 'triageProfile', id + '-triage-error')\"\n (valueChange)=\"triageProfile.set($event); touch('triageProfile')\" />\n <p class=\"hint\" [id]=\"id + '-triage-hint'\">{{ 'nh-assistant.admin.run-config.settings.triage-hint' | translate }}</p>\n @if (errorKey('triageProfile'); as key) {\n <p class=\"field-error\" [id]=\"id + '-triage-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('triageProfile')?.params }}</p>\n }\n </div>\n <fieldset class=\"field\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.elevated-reads' | translate }}</legend>\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.settings.elevated-reads-hint' | translate }}</p>\n @for (mode of elevatedReadModes; track mode) {\n <label class=\"check\">\n <input type=\"radio\" [name]=\"id + '-elevated'\" [value]=\"mode\" [checked]=\"elevatedReads() === mode\" (change)=\"elevatedReads.set(mode); touch('elevatedReads')\" />\n <span>{{ 'nh-assistant.admin.run-config.settings.elevated.' + mode | translate }}</span>\n </label>\n }\n @if (errorKey('elevatedReads'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('elevatedReads')?.params }}</p>\n }\n </fieldset>\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"allowGatewayReads()\" [attr.aria-invalid]=\"fieldError('allowGatewayReads') ? true : null\" (change)=\"allowGatewayReads.set(checked($event)); touch('allowGatewayReads')\" />\n <span>\n {{ 'nh-assistant.admin.run-config.settings.gateway-reads' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.settings.gateway-reads-hint' | translate }}</span>\n </span>\n </label>\n @if (errorKey('allowGatewayReads'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('allowGatewayReads')?.params }}</p>\n }\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"delegateFromInitiator()\" (change)=\"delegateFromInitiator.set(checked($event))\" />\n <span>\n {{ 'nh-assistant.admin.run-config.settings.delegate' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.settings.delegate-hint' | translate }}</span>\n </span>\n </label>\n </div>\n </details>\n\n <div class=\"field\">\n <label [for]=\"id + '-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input type=\"text\" autocomplete=\"off\" [id]=\"id + '-reason'\" [maxLength]=\"maxReason\" [value]=\"reason()\" [attr.aria-describedby]=\"id + '-reason-hint'\" (input)=\"reason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-reason-hint'\">{{ 'nh-assistant.admin.run-config.note-hint' | translate }}</p>\n </div>\n\n @if (hasErrors()) {\n <div class=\"form-error\" role=\"alert\" data-form-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n @if (serverError(); as failure) {\n @if (failure.code === 'assistant-validation') {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n } @else {\n {{ errorKeys() | nhAssistantTranslate: failure.code }}\n }\n } @else {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n }\n @if (otherFieldErrors().length > 0) {\n <ul>\n @for (field of otherFieldErrors(); track field) {\n <li><span class=\"mono\">{{ field }}</span></li>\n }\n </ul>\n }\n </div>\n </div>\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]=\"busy()\">{{ (busy() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}</button>\n </div>\n</form>\n","import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n AssistantDataClassification,\n DataSkill,\n DataSkillRequest,\n NhAssistantAdminApiService,\n RunCatalog,\n ToolCatalogEntry,\n SkillApplyMode,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantFileLimitsFieldsComponent } from './nh-assistant-file-limits-fields.component';\nimport { RunConfigForm } from './run-config-form';\nimport {\n RunConfigErrors,\n blank,\n checkBudget,\n checkWhole,\n dashCase,\n dataClassifications,\n describePolicy,\n FileLimitsDraft,\n numberText,\n policyOptions,\n profileOptions,\n requireText,\n ruleOptions,\n runConfigLimits,\n toolChoices,\n toNumber,\n withBudgetField\n} from './run-config-shared';\nimport { warningKeys } from '../agent-texts';\n\nlet nextId = 0;\n\n/** What a saved skill form tells its host. */\nexport interface SkillFormSaved {\n skill: DataSkill;\n /** The change runs as the skill's candidate in shadow. */\n candidate: boolean;\n added: boolean;\n}\n\n/**\n * Adds or changes a skill defined as data: what it is for, how it works (fixed rules or the model,\n * with instructions), its tools within the agent's own, and its approval and limits. A change is\n * evaluated in shadow by default.\n */\n@Component({\n selector: 'nh-assistant-skill-form',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantPickerComponent, NhAssistantFileLimitsFieldsComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-skill-form.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantSkillFormComponent extends RunConfigForm implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n\n readonly agentId = input.required<string>();\n readonly catalog = input<RunCatalog | null>(null);\n /** The agent's own tool selectors; a skill's tools stay within them. */\n readonly toolSelectors = input<readonly string[]>([]);\n /** The tool catalog, to show what each of the agent's tool selectors offers. */\n readonly toolCatalog = input<readonly ToolCatalogEntry[]>([]);\n readonly toolChoices = computed(() => toolChoices(this.toolSelectors(), this.toolCatalog()));\n /** The skill to change; `null` adds one. */\n readonly skill = input<DataSkill | null>(null);\n /** Skill ids in use, to refuse a duplicate before sending. */\n readonly takenIds = input<readonly string[]>([]);\n readonly saved = output<SkillFormSaved>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-skill-form-${nextId++}`;\n readonly maxReason = runConfigLimits.reason;\n readonly maxDescription = runConfigLimits.description;\n readonly maxInstructions = runConfigLimits.instructions;\n protected readonly fields = [\n 'skillId', 'description', 'instructions', 'tools', 'ruleHandler', 'profile', 'dataClassification', 'approvalPolicy',\n 'maxTokensPerRun', 'dailyToolCalls', 'dailyTokens', 'apply', 'startsOff', 'reason',\n 'maxFileBytes', 'maxFilePages', 'maxFilesPerTurn', 'maxFileTokensPerTurn'\n ];\n\n readonly skillId = signal('');\n readonly description = signal('');\n readonly instructions = signal('');\n readonly tools = signal<string[]>([]);\n readonly profile = signal('');\n /** The skill's data classification; empty uses the agent's. */\n readonly dataClassification = signal('');\n /** Whether a run in the skill reads files when the agent accepts them too; off for a new skill. */\n readonly acceptsFiles = signal(false);\n /** The skill's lower file limits, next to accepting files; empty keeps the agent's. */\n readonly fileLimits = new FileLimitsDraft();\n readonly ruleHandler = signal('');\n readonly approvalPolicy = signal('');\n readonly maxTokens = signal('');\n readonly dailyToolCalls = signal('');\n readonly dailyTokens = signal('');\n readonly apply = signal<SkillApplyMode>('shadow');\n /** A new skill takes work at once; without it, it starts off until someone switches it on. */\n readonly switchOnNow = signal(true);\n readonly reason = signal('');\n\n readonly editing = computed(() => this.skill() !== null);\n /** The warnings of the skill as it was saved, until this form saves it again. */\n readonly warnings = computed(() => this.skill()?.warnings ?? []);\n readonly warningKeys = warningKeys;\n readonly rules = computed(() => ruleOptions(this.catalog()));\n readonly profiles = computed(() => profileOptions(this.catalog()));\n readonly classifications = computed(() => {\n this.language();\n return dataClassifications.map(value => ({\n value,\n label: this.t(`nh-assistant.admin.run-config.skills.classification.${value}`),\n description: this.t(`nh-assistant.admin.run-config.skills.classification.${value}-hint`)\n }));\n });\n readonly policies = computed(() => {\n this.language();\n return policyOptions(this.catalog(), summary => describePolicy(summary, (key, params) => this.t(key, params)));\n });\n\n ngOnInit(): void {\n const skill = this.skill();\n this.skillId.set(skill?.skillId ?? '');\n this.description.set(skill?.description ?? '');\n this.instructions.set(skill?.instructions ?? '');\n this.tools.set([...(skill?.tools ?? [])]);\n this.profile.set(skill?.profile ?? '');\n this.dataClassification.set(skill?.dataClassification ?? '');\n this.acceptsFiles.set(skill?.acceptsFiles ?? false);\n this.fileLimits.load(skill);\n this.ruleHandler.set(skill?.ruleHandler ?? '');\n this.approvalPolicy.set(skill?.approvalPolicy ?? '');\n this.maxTokens.set(numberText(skill?.maxTokensPerRun));\n this.dailyToolCalls.set(numberText(skill?.dailyToolCalls));\n this.dailyTokens.set(numberText(skill?.dailyTokens));\n // A real change is evaluated in shadow first; a small correction can go live at once.\n this.apply.set('shadow');\n }\n\n toggleTool(selector: string, selected: boolean): void {\n this.tools.update(tools => selected\n ? [...tools.filter(tool => tool !== selector), selector]\n : tools.filter(tool => tool !== selector));\n this.touch('tools');\n }\n\n save(): void {\n const editing = this.skill();\n const skillId = editing?.skillId ?? this.skillId().trim();\n const errors: RunConfigErrors = {};\n if (!editing) {\n if (skillId.length === 0) {\n errors['skillId'] = { code: 'required' };\n } else if (!dashCase.test(skillId) || skillId.length > 64) {\n errors['skillId'] = { code: 'dash-case' };\n } else if (this.takenIds().includes(skillId)) {\n errors['skillId'] = { code: 'taken' };\n }\n }\n requireText(errors, 'description', this.description(), this.maxDescription);\n if (this.instructions().length > this.maxInstructions) {\n errors['instructions'] = { code: 'too-long', params: { max: this.maxInstructions } };\n }\n checkWhole(errors, 'maxTokensPerRun', this.maxTokens(), 1);\n checkBudget(errors, this.dailyToolCalls(), this.dailyTokens());\n if (this.acceptsFiles()) {\n this.fileLimits.check(errors, this.catalog()?.fileLimits);\n }\n\n const request: DataSkillRequest = {\n description: this.description().trim(),\n instructions: blank(this.instructions()),\n tools: this.tools(),\n profile: blank(this.profile()),\n dataClassification: (blank(this.dataClassification()) as AssistantDataClassification | null),\n acceptsFiles: this.acceptsFiles(),\n ...this.fileLimits.toRequest(this.acceptsFiles()),\n ruleHandler: blank(this.ruleHandler()),\n approvalPolicy: blank(this.approvalPolicy()),\n maxTokensPerRun: toNumber(this.maxTokens()),\n dailyToolCalls: toNumber(this.dailyToolCalls()),\n dailyTokens: toNumber(this.dailyTokens()),\n expectedVersion: editing?.version ?? null,\n reason: blank(this.reason()),\n ...(editing ? { apply: this.apply() } : {}),\n ...(!editing && !this.switchOnNow() ? { startsOff: true } : {})\n };\n this.submit(errors, () => this.admin.saveDataSkill(this.agentId(), skillId, request), skill => this.saved.emit({\n skill,\n candidate: editing !== null && this.apply() === 'shadow',\n added: editing === null\n }));\n }\n\n protected override mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n return withBudgetField(errors, this.dailyToolCalls());\n }\n}\n","<form class=\"stack card\" data-form=\"skill\" novalidate (submit)=\"$event.preventDefault(); save()\">\n <h5>\n @if (skill(); as current) {\n {{ 'nh-assistant.admin.run-config.skills.edit-title' | translate: { skill: current.skillId, version: current.version } }}\n } @else {\n {{ 'nh-assistant.admin.run-config.skills.new-title' | translate }}\n }\n </h5>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.skills.what.title' | translate }}</legend>\n @if (!editing()) {\n <div class=\"field\">\n <label [for]=\"id + '-skill-id'\">{{ 'nh-assistant.admin.run-config.skills.id' | translate }}</label>\n <input type=\"text\" class=\"mono\" autocomplete=\"off\" maxlength=\"64\" [id]=\"id + '-skill-id'\" [value]=\"skillId()\"\n [attr.aria-invalid]=\"fieldError('skillId') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-skill-id-hint', 'skillId', id + '-skill-id-error')\"\n (input)=\"skillId.set(value($event)); touch('skillId')\" />\n <p class=\"hint\" [id]=\"id + '-skill-id-hint'\">{{ 'nh-assistant.admin.run-config.skills.id-hint' | translate }}</p>\n @if (errorKey('skillId'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-id-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('skillId')?.params }}</p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-skill-description'\">{{ 'nh-assistant.admin.run-config.skills.description-label' | translate }}</label>\n <input type=\"text\" [id]=\"id + '-skill-description'\" [value]=\"description()\"\n [attr.aria-invalid]=\"fieldError('description') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-skill-description-hint', 'description', id + '-skill-description-error')\"\n (input)=\"description.set(value($event)); touch('description')\" />\n <p class=\"hint\" [id]=\"id + '-skill-description-hint'\">\n <span>{{ 'nh-assistant.admin.run-config.skills.description-hint' | translate }}</span>\n <span class=\"counter\" [class.error-text]=\"description().length > maxDescription\">{{ 'nh-assistant.admin.characters' | translate: { count: description().length, max: maxDescription } }}</span>\n </p>\n @if (errorKey('description'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-description-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('description')?.params }}</p>\n }\n </div>\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.skills.how.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-skill-rules'\">{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-skill-rules'\"\n [options]=\"rules()\"\n [value]=\"ruleHandler()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.model' | translate\"\n [invalid]=\"fieldError('ruleHandler') !== null\"\n [describedBy]=\"describedBy(id + '-skill-rules-hint', 'ruleHandler', id + '-skill-rules-error')\"\n (valueChange)=\"ruleHandler.set($event); touch('ruleHandler')\" />\n <p class=\"hint\" [id]=\"id + '-skill-rules-hint'\">\n {{ (ruleHandler() ? 'nh-assistant.admin.run-config.skills.rules-hint' : 'nh-assistant.admin.run-config.skills.model-hint') | translate }}\n </p>\n @if (errorKey('ruleHandler'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-rules-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('ruleHandler')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-skill-instructions'\">{{ 'nh-assistant.admin.run-config.skills.instructions' | translate }}</label>\n <textarea rows=\"5\" [id]=\"id + '-skill-instructions'\" [value]=\"instructions()\"\n [attr.aria-invalid]=\"fieldError('instructions') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-skill-instructions-hint', 'instructions', id + '-skill-instructions-error')\"\n (input)=\"instructions.set(value($event)); touch('instructions')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-skill-instructions-hint'\">\n <span>{{ 'nh-assistant.admin.run-config.skills.instructions-hint' | translate }} {{ 'nh-assistant.admin.run-config.skills.background-hint' | translate }}</span>\n <span class=\"counter\" [class.error-text]=\"instructions().length > maxInstructions\">{{ 'nh-assistant.admin.characters' | translate: { count: instructions().length, max: maxInstructions } }}</span>\n </p>\n @if (errorKey('instructions'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-instructions-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('instructions')?.params }}</p>\n }\n </div>\n <fieldset class=\"field\" [attr.aria-describedby]=\"id + '-tools-hint'\">\n <legend>{{ 'nh-assistant.admin.run-config.skills.tools' | translate }}</legend>\n <p class=\"hint\" [id]=\"id + '-tools-hint'\">{{ 'nh-assistant.admin.run-config.skills.tools-hint' | translate }}</p>\n @for (choice of toolChoices(); track choice.selector) {\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"tools().includes(choice.selector)\" [attr.aria-invalid]=\"fieldError('tools') ? true : null\" (change)=\"toggleTool(choice.selector, checked($event))\" />\n <span class=\"tool-choice\">\n <span class=\"mono\">{{ choice.selector }}</span>\n @if (choice.description) {\n <span class=\"muted block\">{{ choice.description }}</span>\n } @else if (choice.matches !== null) {\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.skills.tools-pattern' | translate: { count: choice.matches } }}</span>\n }\n </span>\n </label>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.no-selectors' | translate }}</p>\n }\n @if (errorKey('tools'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('tools')?.params }}</p>\n }\n </fieldset>\n <div class=\"field\">\n <label [for]=\"id + '-skill-profile'\">{{ 'nh-assistant.admin.run-config.skills.profile' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-skill-profile'\"\n [options]=\"profiles()\"\n [value]=\"profile()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.skills.agent-profile' | translate\"\n [invalid]=\"fieldError('profile') !== null\"\n [describedBy]=\"describedBy(id + '-skill-profile-hint', 'profile', id + '-skill-profile-error')\"\n (valueChange)=\"profile.set($event); touch('profile')\" />\n <p class=\"hint\" [id]=\"id + '-skill-profile-hint'\">{{ 'nh-assistant.admin.run-config.skills.profile-hint' | translate }}</p>\n @if (errorKey('profile'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-profile-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('profile')?.params }}</p>\n }\n </div>\n <div class=\"field\" data-classification>\n <label [for]=\"id + '-skill-classification'\">{{ 'nh-assistant.admin.run-config.skills.classification.label' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-skill-classification'\"\n [options]=\"classifications()\"\n [value]=\"dataClassification()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.skills.classification.agent' | translate\"\n [invalid]=\"fieldError('dataClassification') !== null\"\n [describedBy]=\"describedBy(id + '-skill-classification-hint', 'dataClassification', id + '-skill-classification-error')\"\n (valueChange)=\"dataClassification.set($event); touch('dataClassification')\" />\n <p class=\"hint\" [id]=\"id + '-skill-classification-hint'\">{{ 'nh-assistant.admin.run-config.skills.classification.hint' | translate }}</p>\n @for (warning of warnings(); track warning) {\n <p class=\"message warning\" [attr.data-skill-form-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('skill', warning) | nhAssistantTranslate: warning }}\n </p>\n }\n @if (errorKey('dataClassification'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-classification-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dataClassification')?.params }}</p>\n }\n </div>\n <label class=\"check\" data-accepts-files>\n <input type=\"checkbox\" [checked]=\"acceptsFiles()\" (change)=\"acceptsFiles.set(checked($event))\" />\n <span>\n {{ 'nh-assistant.admin.run-config.files.label' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.files.skill-hint' | translate }}</span>\n </span>\n </label>\n @if (acceptsFiles()) {\n <nh-assistant-file-limits-fields\n [draft]=\"fileLimits\"\n [application]=\"catalog()?.fileLimits\"\n [errors]=\"fieldErrors()\"\n [idPrefix]=\"id\"\n hintKey=\"nh-assistant.admin.run-config.files.skill-limits-hint\"\n (touched)=\"touch($event)\" />\n }\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.approval.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-skill-policy'\">{{ 'nh-assistant.admin.run-config.approval-policy' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-skill-policy'\"\n [options]=\"policies()\"\n [value]=\"approvalPolicy()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.skills.agent-policy' | translate\"\n [invalid]=\"fieldError('approvalPolicy') !== null\"\n [describedBy]=\"describedBy(null, 'approvalPolicy', id + '-skill-policy-error')\"\n (valueChange)=\"approvalPolicy.set($event); touch('approvalPolicy')\" />\n @if (errorKey('approvalPolicy'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-policy-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('approvalPolicy')?.params }}</p>\n }\n </div>\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.limits.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-limits-hint'\">{{ 'nh-assistant.admin.run-config.budget-hint' | translate }}</p>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-skill-tokens'\">{{ 'nh-assistant.admin.run-config.max-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-skill-tokens'\" [value]=\"maxTokens()\"\n [attr.aria-invalid]=\"fieldError('maxTokensPerRun') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'maxTokensPerRun', id + '-skill-tokens-error')\"\n (input)=\"maxTokens.set(value($event)); touch('maxTokensPerRun')\" />\n @if (errorKey('maxTokensPerRun'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxTokensPerRun')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-skill-calls'\">{{ 'nh-assistant.admin.run-config.daily-tool-calls' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-skill-calls'\" [value]=\"dailyToolCalls()\"\n [attr.aria-invalid]=\"fieldError('dailyToolCalls') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyToolCalls', id + '-skill-calls-error')\"\n (input)=\"dailyToolCalls.set(value($event)); touch('dailyToolCalls'); touch('dailyTokens')\" />\n @if (errorKey('dailyToolCalls'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-calls-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyToolCalls')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-skill-daily-tokens'\">{{ 'nh-assistant.admin.run-config.daily-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-skill-daily-tokens'\" [value]=\"dailyTokens()\"\n [attr.aria-invalid]=\"fieldError('dailyTokens') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyTokens', id + '-skill-daily-tokens-error')\"\n (input)=\"dailyTokens.set(value($event)); touch('dailyTokens'); touch('dailyToolCalls')\" />\n @if (errorKey('dailyTokens'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-daily-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyTokens')?.params }}</p>\n }\n </div>\n </div>\n </fieldset>\n\n @if (editing()) {\n <fieldset class=\"group\" data-apply>\n <legend>{{ 'nh-assistant.admin.run-config.skills.apply' | translate }}</legend>\n <div class=\"choices\">\n <label class=\"choice\" [class.selected]=\"apply() === 'shadow'\">\n <input type=\"radio\" [name]=\"id + '-apply'\" value=\"shadow\" [checked]=\"apply() === 'shadow'\" (change)=\"apply.set('shadow')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.skills.apply-shadow' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.skills.apply-shadow-hint' | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"apply() === 'live'\">\n <input type=\"radio\" [name]=\"id + '-apply'\" value=\"live\" [checked]=\"apply() === 'live'\" (change)=\"apply.set('live')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.skills.apply-live' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.skills.apply-live-hint' | translate }}</span>\n </span>\n </label>\n </div>\n </fieldset>\n } @else {\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.skills.starts-in-shadow' | translate }}</p>\n <label class=\"check\" data-switch-on-now>\n <input type=\"checkbox\" [checked]=\"switchOnNow()\" (change)=\"switchOnNow.set(checked($event))\" />\n <span>\n {{ 'nh-assistant.admin.run-config.skills.switch-on-now' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.skills.switch-on-now-hint' | translate }}</span>\n </span>\n </label>\n }\n\n <div class=\"field\">\n <label [for]=\"id + '-skill-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input type=\"text\" autocomplete=\"off\" [id]=\"id + '-skill-reason'\" [maxLength]=\"maxReason\" [value]=\"reason()\" [attr.aria-describedby]=\"id + '-skill-reason-hint'\" (input)=\"reason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-skill-reason-hint'\">{{ 'nh-assistant.admin.run-config.note-hint' | translate }}</p>\n </div>\n\n @if (hasErrors()) {\n <div class=\"form-error\" role=\"alert\" data-form-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n @if (serverError(); as failure) {\n @if (failure.code === 'assistant-validation') {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n } @else {\n {{ errorKeys() | nhAssistantTranslate: failure.code }}\n }\n } @else {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n }\n @if (otherFieldErrors().length > 0) {\n <ul>\n @for (field of otherFieldErrors(); track field) {\n <li><span class=\"mono\">{{ field }}</span></li>\n }\n </ul>\n }\n </div>\n </div>\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]=\"busy()\">{{ (busy() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}</button>\n </div>\n</form>\n","import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n DataTrigger,\n DataTriggerRequest,\n NhAssistantAdminApiService,\n RunBlock,\n RunCatalog,\n TriggerConflict,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantPickerOption as NhAssistantPickerOption,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe\n} from '@newheap/platform-ai-chat';\nimport { RunConfigForm } from './run-config-form';\nimport {\n RunConfigErrors,\n ScheduleTarget,\n blank,\n checkWhole,\n cronExamples,\n dashCase,\n eventOptions,\n WorksOnStatement,\n requireText,\n runConfigLimits,\n subjectSetOptions,\n systemSubjectType,\n timeZoneOptions,\n toNumber,\n withScheduleTargetError,\n worksOnCovers\n} from './run-config-shared';\n\nlet nextId = 0;\n\nconst conflicts: TriggerConflict[] = ['coalesce', 'queue', 'supersede', 'ignore'];\n\n/**\n * Adds or changes a trigger defined as data: an event of the application or a schedule starts a skill\n * of the agent, or lets the agent choose. A schedule runs for every subject in a set or, for an agent\n * that works on the whole application, for the whole application: once each time, or once per\n * division for an agent that works per division. A new trigger starts in shadow. An event trigger may\n * select named filters the event offers, such as one that skips the agent's own changes; every selected\n * filter must let an event through.\n */\n@Component({\n selector: 'nh-assistant-trigger-form',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantPickerComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-trigger-form.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantTriggerFormComponent extends RunConfigForm implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n\n readonly agentId = input.required<string>();\n readonly catalog = input<RunCatalog | null>(null);\n /**\n * What the agent works on: events about other object types are not offered, and a schedule runs\n * for the whole application only for an agent that works on it.\n */\n readonly worksOn = input<WorksOnStatement | null>(null);\n /** The agent's skills, in code and as data, a trigger can start. */\n readonly skills = input<readonly NhAssistantPickerOption[]>([]);\n /** The trigger to change; `null` adds one. */\n readonly trigger = input<DataTrigger | null>(null);\n readonly takenIds = input<readonly string[]>([]);\n readonly saved = output<{ trigger: DataTrigger; added: boolean }>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-trigger-form-${nextId++}`;\n readonly maxReason = runConfigLimits.reason;\n readonly maxMessage = runConfigLimits.message;\n readonly examples = cronExamples;\n readonly timeZones = timeZoneOptions().filter(zone => zone.value !== 'UTC');\n protected readonly fields = [\n 'triggerId', 'source', 'event', 'debounceSeconds', 'filters', 'cron', 'timeZone', 'subjectSet', 'message', 'skill', 'conflict', 'reason'\n ];\n\n readonly triggerId = signal('');\n readonly source = signal<'event' | 'schedule'>('event');\n readonly event = signal('');\n readonly cron = signal('');\n readonly timeZone = signal('');\n readonly subjectSet = signal('');\n /** The administrator's choice of what a schedule runs for; see `target`. */\n readonly scheduleTarget = signal<ScheduleTarget>('application');\n readonly message = signal('');\n readonly skill = signal('');\n readonly conflict = signal<TriggerConflict>('coalesce');\n readonly debounce = signal('120');\n /** The names of the event's filters the trigger applies. */\n readonly filters = signal<readonly string[]>([]);\n readonly reason = signal('');\n\n readonly editing = computed(() => this.trigger() !== null);\n readonly events = computed(() => eventOptions(this.catalog(), this.worksOn()));\n readonly subjectSets = computed(() => subjectSetOptions(this.catalog()));\n /** The filters the chosen event offers, in the order the application registered them. */\n readonly eventFilters = computed<readonly RunBlock[]>(() => {\n const event = this.event();\n return this.catalog()?.triggerEvents.find(block => block.name === event)?.filters ?? [];\n });\n /**\n * Selected filters the chosen event no longer offers, such as after a deploy removed one: the trigger\n * starts nothing until they are cleared.\n */\n readonly missingFilters = computed(() => {\n const offered = this.eventFilters();\n return this.catalog() === null\n ? []\n : this.filters().filter(name => !offered.some(filter => filter.name === name));\n });\n /** A schedule may run for the whole application only for an agent that works on it. */\n readonly offersApplication = computed(() => worksOnCovers(this.worksOn(), systemSubjectType));\n /** What the schedule runs for: the whole application while the agent works on it, otherwise a set. */\n readonly target = computed<ScheduleTarget>(() => this.offersApplication() ? this.scheduleTarget() : 'set');\n /** The agent's work for the whole application runs once per division. */\n readonly perDivision = computed(() => this.worksOn()?.perDivision === true);\n /** A stored schedule for the whole application of an agent that no longer works on it. */\n readonly applicationDropped = computed(() => {\n const trigger = this.trigger();\n return trigger?.source === 'schedule' && !trigger.subjectSet && !this.offersApplication();\n });\n readonly conflictOptions = computed<NhAssistantPickerOption[]>(() => {\n this.language();\n return conflicts.map(conflict => ({\n value: conflict,\n label: this.t(`nh-assistant.admin.run-config.triggers.conflicts.${conflict}`),\n description: this.t(`nh-assistant.admin.run-config.triggers.conflict-explain.${conflict}`)\n }));\n });\n\n ngOnInit(): void {\n const trigger = this.trigger();\n this.triggerId.set(trigger?.triggerId ?? '');\n this.source.set(trigger?.source === 'schedule' ? 'schedule' : 'event');\n this.event.set(trigger?.event ?? '');\n this.cron.set(trigger?.cron ?? '');\n this.timeZone.set(trigger?.timeZone ?? '');\n this.subjectSet.set(trigger?.subjectSet ?? '');\n // A stored schedule without a subject set runs for the whole application; a new one starts there\n // for an agent that works on it.\n this.scheduleTarget.set(trigger?.source === 'schedule' && trigger.subjectSet ? 'set' : 'application');\n this.message.set(trigger?.message ?? '');\n this.skill.set(trigger?.skillId ?? '');\n this.conflict.set(trigger?.conflict ?? 'coalesce');\n this.debounce.set(String(trigger?.debounceSeconds ?? 120));\n this.filters.set(trigger?.filters ?? []);\n }\n\n /** Another event offers other filters: those it does not offer no longer apply. */\n setEvent(event: string): void {\n this.event.set(event);\n this.touch('event');\n const offered = this.eventFilters();\n this.filters.update(filters => filters.filter(name => offered.some(filter => filter.name === name)));\n }\n\n toggleFilter(name: string, selected: boolean): void {\n this.filters.update(filters => selected\n ? [...filters.filter(filter => filter !== name), name]\n : filters.filter(filter => filter !== name));\n this.touch('filters');\n }\n\n /** A schedule skips a tick while a run is busy by default; an event coalesces. */\n setSource(source: 'event' | 'schedule'): void {\n this.source.set(source);\n this.touch('source');\n if (!this.editing()) {\n this.conflict.set(source === 'schedule' ? 'ignore' : 'coalesce');\n }\n }\n\n setTarget(target: ScheduleTarget): void {\n this.scheduleTarget.set(target);\n this.touch('subjectSet');\n }\n\n useExample(cron: string): void {\n this.cron.set(cron);\n this.touch('cron');\n }\n\n save(): void {\n const editing = this.trigger();\n const triggerId = editing?.triggerId ?? this.triggerId().trim();\n const schedule = this.source() === 'schedule';\n const forSet = schedule && this.target() === 'set';\n const errors: RunConfigErrors = {};\n if (!editing) {\n if (triggerId.length === 0) {\n errors['triggerId'] = { code: 'required' };\n } else if (!dashCase.test(triggerId) || triggerId.length > 64) {\n errors['triggerId'] = { code: 'dash-case' };\n } else if (this.takenIds().includes(triggerId)) {\n errors['triggerId'] = { code: 'taken' };\n }\n }\n if (schedule) {\n requireText(errors, 'cron', this.cron());\n if (forSet && this.subjectSet() === '') {\n errors['subjectSet'] = { code: 'required' };\n }\n requireText(errors, 'message', this.message(), this.maxMessage);\n } else {\n if (this.event() === '') {\n errors['event'] = { code: 'required' };\n }\n if (this.missingFilters().length > 0) {\n errors['filters'] = { code: 'not-found' };\n }\n checkWhole(errors, 'debounceSeconds', this.debounce(), ...runConfigLimits.debounce, true);\n }\n\n const request: DataTriggerRequest = {\n source: this.source(),\n skill: blank(this.skill()),\n event: schedule ? null : blank(this.event()),\n cron: schedule ? blank(this.cron()) : null,\n timeZone: schedule ? blank(this.timeZone()) : null,\n // Without a subject set the schedule runs for the whole application.\n subjectSet: forSet ? blank(this.subjectSet()) : null,\n message: schedule ? blank(this.message()) : null,\n conflict: this.conflict(),\n debounceSeconds: schedule ? null : toNumber(this.debounce()),\n // In the order the event offers them; a schedule takes none.\n filters: schedule ? [] : this.orderedFilters(),\n expectedVersion: editing?.version ?? null,\n reason: blank(this.reason())\n };\n this.submit(errors, () => this.admin.saveDataTrigger(this.agentId(), triggerId, request), trigger => this.saved.emit({\n trigger,\n added: editing === null\n }));\n }\n\n /** The selected filters in the order the event offers them, those it no longer offers last. */\n private orderedFilters(): string[] {\n const selected = this.filters();\n return [\n ...this.eventFilters().map(filter => filter.name).filter(name => selected.includes(name)),\n ...selected.filter(name => !this.eventFilters().some(filter => filter.name === name))\n ];\n }\n\n protected override mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n return withScheduleTargetError(errors, this.source() === 'schedule' ? this.target() : 'set');\n }\n}\n","<form class=\"stack card\" data-form=\"trigger\" novalidate (submit)=\"$event.preventDefault(); save()\">\n <h5>\n @if (trigger(); as current) {\n {{ 'nh-assistant.admin.run-config.triggers.edit-title' | translate: { trigger: current.triggerId } }}\n } @else {\n {{ 'nh-assistant.admin.run-config.triggers.new-title' | translate }}\n }\n </h5>\n\n @if (!editing()) {\n <div class=\"field\">\n <label [for]=\"id + '-trigger-id'\">{{ 'nh-assistant.admin.run-config.triggers.id' | translate }}</label>\n <input type=\"text\" class=\"mono\" autocomplete=\"off\" maxlength=\"64\" [id]=\"id + '-trigger-id'\" [value]=\"triggerId()\"\n [attr.aria-invalid]=\"fieldError('triggerId') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-trigger-id-hint', 'triggerId', id + '-trigger-id-error')\"\n (input)=\"triggerId.set(value($event)); touch('triggerId')\" />\n <p class=\"hint\" [id]=\"id + '-trigger-id-hint'\">{{ 'nh-assistant.admin.run-config.triggers.id-hint' | translate }}</p>\n @if (errorKey('triggerId'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-id-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('triggerId')?.params }}</p>\n }\n </div>\n }\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.triggers.when.title' | translate }}</legend>\n <div class=\"choices\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.run-config.triggers.when.title' | translate\">\n <label class=\"choice\" [class.selected]=\"source() === 'event'\">\n <input type=\"radio\" [name]=\"id + '-source'\" value=\"event\" [checked]=\"source() === 'event'\" (change)=\"setSource('event')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.source-event' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.source-event-hint' | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"source() === 'schedule'\">\n <input type=\"radio\" [name]=\"id + '-source'\" value=\"schedule\" [checked]=\"source() === 'schedule'\" (change)=\"setSource('schedule')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.source-schedule' | translate }}</strong>\n <span class=\"muted\">{{ (offersApplication() ? 'nh-assistant.admin.run-config.triggers.source-schedule-application-hint' : 'nh-assistant.admin.run-config.triggers.source-schedule-hint') | translate }}</span>\n </span>\n </label>\n </div>\n\n @if (source() === 'event') {\n <div class=\"field\">\n <label [for]=\"id + '-trigger-event'\">{{ 'nh-assistant.admin.run-config.triggers.event' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-event'\"\n [options]=\"events()\"\n [value]=\"event()\"\n [placeholder]=\"'nh-assistant.admin.run-config.choose' | translate\"\n [invalid]=\"fieldError('event') !== null\"\n [describedBy]=\"describedBy(null, 'event', id + '-trigger-event-error')\"\n (valueChange)=\"setEvent($event)\" />\n @if (errorKey('event'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-event-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('event')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-trigger-debounce'\">{{ 'nh-assistant.admin.run-config.triggers.debounce' | translate }}</label>\n <input type=\"number\" min=\"0\" max=\"3600\" inputmode=\"numeric\" [id]=\"id + '-trigger-debounce'\" [value]=\"debounce()\"\n [attr.aria-invalid]=\"fieldError('debounceSeconds') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-trigger-debounce-hint', 'debounceSeconds', id + '-trigger-debounce-error')\"\n (input)=\"debounce.set(value($event)); touch('debounceSeconds')\" />\n <p class=\"hint\" [id]=\"id + '-trigger-debounce-hint'\">{{ 'nh-assistant.admin.run-config.triggers.debounce-hint' | translate }}</p>\n @if (errorKey('debounceSeconds'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-debounce-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('debounceSeconds')?.params }}</p>\n }\n </div>\n @if (event() !== '') {\n <!-- The filters of the chosen event; each one selected must let an event through. -->\n <fieldset class=\"field\" data-trigger-filters [attr.aria-describedby]=\"describedBy(id + '-trigger-filters-hint', 'filters', id + '-trigger-filters-error')\">\n <legend>{{ 'nh-assistant.admin.run-config.triggers.filters.title' | translate }}</legend>\n <p class=\"hint\" [id]=\"id + '-trigger-filters-hint'\">{{ 'nh-assistant.admin.run-config.triggers.filters.hint' | translate }}</p>\n <!-- In their own block: a label right under the field would take the field's label style. -->\n <div class=\"checks\">\n @for (filter of eventFilters(); track filter.name) {\n <label class=\"check described\" [attr.data-filter]=\"filter.name\">\n <input type=\"checkbox\" [checked]=\"filters().includes(filter.name)\" [attr.aria-invalid]=\"fieldError('filters') ? true : null\" (change)=\"toggleFilter(filter.name, checked($event))\" />\n <span>\n <span class=\"mono\">{{ filter.name }}</span>\n <span class=\"muted\">{{ filter.description }}</span>\n </span>\n </label>\n }\n @for (name of missingFilters(); track name) {\n <!-- Stored, but the event no longer offers it: the trigger starts nothing until it is cleared. -->\n <label class=\"check described\" [attr.data-missing-filter]=\"name\">\n <input type=\"checkbox\" [checked]=\"true\" aria-invalid=\"true\" (change)=\"toggleFilter(name, checked($event))\" />\n <span>\n <span class=\"mono\">{{ name }}</span>\n <span class=\"error-text\">{{ 'nh-assistant.admin.run-config.triggers.filters.missing' | translate }}</span>\n </span>\n </label>\n }\n </div>\n @if (eventFilters().length === 0 && missingFilters().length === 0) {\n <p class=\"muted\" data-filters-empty>{{ 'nh-assistant.admin.run-config.triggers.filters.empty' | translate }}</p>\n }\n @if (errorKey('filters'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-filters-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('filters')?.params }}</p>\n }\n </fieldset>\n }\n } @else {\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-trigger-cron'\">{{ 'nh-assistant.admin.run-config.triggers.cron' | translate }}</label>\n <input type=\"text\" class=\"mono\" autocomplete=\"off\" maxlength=\"128\" [id]=\"id + '-trigger-cron'\" [value]=\"cron()\"\n [attr.aria-invalid]=\"fieldError('cron') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-trigger-cron-hint', 'cron', id + '-trigger-cron-error')\"\n (input)=\"cron.set(value($event)); touch('cron')\" />\n <p class=\"hint\" [id]=\"id + '-trigger-cron-hint'\">{{ 'nh-assistant.admin.run-config.triggers.cron-hint' | translate }}</p>\n <ul class=\"examples\" [attr.aria-label]=\"'nh-assistant.admin.run-config.triggers.examples' | translate\">\n @for (example of examples; track example.cron) {\n <li><button type=\"button\" (click)=\"useExample(example.cron)\">{{ 'nh-assistant.admin.run-config.triggers.example.' + example.key | translate }}</button></li>\n }\n </ul>\n @if (errorKey('cron'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-cron-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('cron')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-trigger-zone'\">{{ 'nh-assistant.admin.run-config.triggers.time-zone' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-zone'\"\n [options]=\"timeZones\"\n [value]=\"timeZone()\"\n [noneLabel]=\"'UTC'\"\n [invalid]=\"fieldError('timeZone') !== null\"\n [describedBy]=\"describedBy(null, 'timeZone', id + '-trigger-zone-error')\"\n (valueChange)=\"timeZone.set($event); touch('timeZone')\" />\n @if (errorKey('timeZone'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-zone-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('timeZone')?.params }}</p>\n }\n </div>\n </div>\n @if (offersApplication()) {\n <!-- An agent that works on the whole application chooses what the schedule runs for. -->\n <div class=\"field\" data-schedule-target>\n <span class=\"label\" [id]=\"id + '-trigger-target-label'\">{{ 'nh-assistant.admin.run-config.triggers.target.title' | translate }}</span>\n <div\n class=\"choices\"\n role=\"radiogroup\"\n tabindex=\"-1\"\n [attr.aria-labelledby]=\"id + '-trigger-target-label'\"\n [attr.aria-invalid]=\"target() === 'application' && fieldError('subjectSet') ? true : null\"\n [attr.aria-describedby]=\"target() === 'application' ? describedBy(null, 'subjectSet', id + '-trigger-target-error') : null\">\n <label class=\"choice\" [class.selected]=\"target() === 'application'\">\n <input type=\"radio\" [name]=\"id + '-target'\" value=\"application\" [checked]=\"target() === 'application'\" (change)=\"setTarget('application')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.target.application' | translate }}</strong>\n <span class=\"muted\" data-target-hint>{{ (perDivision() ? 'nh-assistant.admin.run-config.triggers.target.application-per-division-hint' : 'nh-assistant.admin.run-config.triggers.target.application-hint') | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"target() === 'set'\">\n <input type=\"radio\" [name]=\"id + '-target'\" value=\"set\" [checked]=\"target() === 'set'\" (change)=\"setTarget('set')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.target.set' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.target.set-hint' | translate }}</span>\n </span>\n </label>\n </div>\n @if (target() === 'application' && errorKey('subjectSet'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-target-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate }}</p>\n }\n </div>\n }\n @if (target() === 'set') {\n <div class=\"field\">\n <label [for]=\"id + '-trigger-set'\">{{ 'nh-assistant.admin.run-config.triggers.subject-set' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-set'\"\n [options]=\"subjectSets()\"\n [value]=\"subjectSet()\"\n [placeholder]=\"'nh-assistant.admin.run-config.choose' | translate\"\n [invalid]=\"fieldError('subjectSet') !== null\"\n [describedBy]=\"describedBy(id + '-trigger-set-hint', 'subjectSet', id + '-trigger-set-error')\"\n (valueChange)=\"subjectSet.set($event); touch('subjectSet')\" />\n <p class=\"hint\" [id]=\"id + '-trigger-set-hint'\">\n {{ (applicationDropped() ? 'nh-assistant.admin.run-config.triggers.target.dropped' : 'nh-assistant.admin.run-config.triggers.subject-set-hint') | translate }}\n </p>\n @if (errorKey('subjectSet'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-set-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('subjectSet')?.params }}</p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-trigger-message'\">{{ 'nh-assistant.admin.run-config.triggers.message' | translate }}</label>\n <textarea rows=\"2\" [id]=\"id + '-trigger-message'\" [value]=\"message()\"\n [attr.aria-invalid]=\"fieldError('message') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-trigger-message-hint', 'message', id + '-trigger-message-error')\"\n (input)=\"message.set(value($event)); touch('message')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-trigger-message-hint'\">{{ 'nh-assistant.admin.run-config.triggers.message-hint' | translate }}</p>\n @if (errorKey('message'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-message-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('message')?.params }}</p>\n }\n </div>\n }\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.triggers.then.title' | translate }}</legend>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-trigger-skill'\">{{ 'nh-assistant.admin.run-config.triggers.skill' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-skill'\"\n [options]=\"skills()\"\n [value]=\"skill()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.triggers.agent-routes' | translate\"\n [invalid]=\"fieldError('skill') !== null\"\n [describedBy]=\"describedBy(null, 'skill', id + '-trigger-skill-error')\"\n (valueChange)=\"skill.set($event); touch('skill')\" />\n @if (errorKey('skill'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-skill-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('skill')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-trigger-conflict'\">{{ 'nh-assistant.admin.run-config.triggers.conflict' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-conflict'\"\n [options]=\"conflictOptions()\"\n [value]=\"conflict()\"\n [invalid]=\"fieldError('conflict') !== null\"\n [describedBy]=\"describedBy(null, 'conflict', id + '-trigger-conflict-error')\"\n (valueChange)=\"conflict.set($any($event)); touch('conflict')\" />\n @if (errorKey('conflict'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-conflict-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('conflict')?.params }}</p>\n }\n </div>\n </div>\n </fieldset>\n\n @if (!editing()) {\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.triggers.starts-in-shadow' | translate }}</p>\n }\n <div class=\"field\">\n <label [for]=\"id + '-trigger-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input type=\"text\" autocomplete=\"off\" [id]=\"id + '-trigger-reason'\" [maxLength]=\"maxReason\" [value]=\"reason()\" [attr.aria-describedby]=\"id + '-trigger-reason-hint'\" (input)=\"reason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-trigger-reason-hint'\">{{ 'nh-assistant.admin.run-config.note-hint' | translate }}</p>\n </div>\n\n @if (hasErrors()) {\n <div class=\"form-error\" role=\"alert\" data-form-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n @if (serverError(); as failure) {\n @if (failure.code === 'assistant-validation') {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n } @else {\n {{ errorKeys() | nhAssistantTranslate: failure.code }}\n }\n } @else {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n }\n @if (otherFieldErrors().length > 0) {\n <ul>\n @for (field of otherFieldErrors(); track field) {\n <li><span class=\"mono\">{{ field }}</span></li>\n }\n </ul>\n }\n </div>\n </div>\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]=\"busy()\">{{ (busy() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}</button>\n </div>\n</form>\n","import { DatePipe, DecimalPipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n OnInit,\n afterNextRender,\n computed,\n inject,\n input,\n output,\n signal\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport { Observable, Subscription, forkJoin, map, startWith } from 'rxjs';\nimport {\n AdminAgent,\n AgentRunConfiguration,\n DataSkill,\n DataSkillVersion,\n DataTrigger,\n McpServer,\n NhAssistantAdminApiService,\n NhAssistantError,\n RunCatalog,\n SkillComparison,\n ToolCatalogEntry,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerOption as NhAssistantPickerOption,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAccountLabelComponent, NhAssistantAccountNames, NhAssistantAccountNamesErrorComponent } from '../nh-assistant-account-names';\nimport { codeTextKeys, readableId, skillDescriptionKeys, skillNameKeys, warningKeys } from './agent-texts';\nimport { AgentFlowEntry } from './run-config/agent-flow';\nimport { NhAssistantAgentFlowComponent } from './run-config/nh-assistant-agent-flow.component';\nimport { NhAssistantAgentWorkSetupComponent } from './run-config/nh-assistant-agent-work-setup.component';\nimport { NhAssistantRunSettingsFormComponent } from './run-config/nh-assistant-run-settings-form.component';\nimport { NhAssistantSkillFormComponent, SkillFormSaved } from './run-config/nh-assistant-skill-form.component';\nimport { NhAssistantTriggerFormComponent } from './run-config/nh-assistant-trigger-form.component';\nimport { describePolicy, runConfigLimits } from './run-config/run-config-shared';\n\nlet nextId = 0;\n\ntype Form = 'setup' | 'settings' | 'skill' | 'trigger';\n\n/** A removal, promotion or discard that waits for its confirmation. */\ninterface Confirmation {\n action: 'remove-settings' | 'remove-skill' | 'remove-trigger' | 'promote' | 'discard';\n id: string;\n}\n\n/**\n * The run configuration of one agent as data: the run settings of an agent created in the\n * administration, its skills and triggers in code (read only) and as data, and the data that no\n * longer fits the code. It opens with the agent's flow: what it works on, when it runs, how it works,\n * whom it answers to, who approves and its results, each step with its problems and an entry point\n * to the form below that changes it; the agent editor (`editAgent`), the technical account of an\n * agent in code (`changeAccount`), the runs view (`openRuns`) and the MCP servers (`openMcpServers`)\n * belong to the page that hosts it. An agent created here that only chats gets a guided setup that\n * lets it work on its own. Administrators add and change data skills, live at once or as a candidate in shadow that\n * they compare with the live version and promote or discard; they add data triggers on the\n * application's events or on a schedule and put them live; a schedule without a subject set runs for\n * the whole application, or for every division of an agent that works per division. New skills and\n * triggers start in shadow; `changed` tells the agents page to reload the agent's skill states.\n */\n@Component({\n selector: 'nh-assistant-agent-run-configuration',\n standalone: true,\n imports: [\n DatePipe,\n DecimalPipe,\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantAgentFlowComponent,\n NhAssistantAgentWorkSetupComponent,\n NhAssistantRunSettingsFormComponent,\n NhAssistantSkillFormComponent,\n NhAssistantTriggerFormComponent,\n NhAssistantAccountNamesErrorComponent,\n NhAssistantAccountLabelComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-run-configuration.component.html',\n styleUrls: ['../nh-assistant-admin-shared.scss', './nh-assistant-agent-feedback-report.component.scss', './run-config/run-config-forms.scss']\n})\nexport class NhAssistantAgentRunConfigurationComponent implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly translate = inject(TranslateService);\n private readonly injector = inject(Injector);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private loadSubscription?: Subscription;\n private actionSubscription?: Subscription;\n private detailSubscription?: Subscription;\n /** The flow's entry point that opened the form, which takes the focus back when the form closes. */\n private returnFocus: HTMLElement | null = null;\n\n readonly agent = input.required<AdminAgent>();\n /** Opens the guided setup at once, for an agent that was just created to work on its own. */\n readonly startSetup = input(false);\n /** The tool catalog, to show what the agent's tool selectors offer in the skill forms and the flow. */\n readonly tools = input<readonly ToolCatalogEntry[]>([]);\n /**\n * The MCP servers, so the flow shows whether the agent's servers are used in runs without a person;\n * `null` while unknown.\n */\n readonly servers = input<readonly McpServer[] | null>(null);\n /** A change of the run configuration changed the agent's skills or state. */\n readonly changed = output<void>();\n /** The flow asks to open the agent editor: what it works on, its tools, MCP servers and groups. */\n readonly editAgent = output<void>();\n /** The flow asks to change the technical account of an agent in code. */\n readonly changeAccount = output<void>();\n /** The flow asks to open the agent's runs. */\n readonly openRuns = output<void>();\n /** The flow asks to open the MCP servers, whose background use decides what runs without a person use. */\n readonly openMcpServers = output<void>();\n\n readonly id = `nh-assistant-run-configuration-${nextId++}`;\n readonly maxReason = runConfigLimits.reason;\n readonly skillNameKeys = skillNameKeys;\n readonly warningKeys = warningKeys;\n readonly skillDescriptionKeys = skillDescriptionKeys;\n readonly readableId = readableId;\n\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly busy = signal(false);\n readonly catalog = signal<RunCatalog | null>(null);\n readonly configuration = signal<AgentRunConfiguration | null>(null);\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n readonly saved = signal<string | null>(null);\n /** The warnings of the skill that was just saved, shown with the saved message. */\n readonly savedWarnings = signal<readonly string[]>([]);\n readonly form = signal<Form | null>(null);\n readonly confirming = signal<Confirmation | null>(null);\n readonly reason = signal('');\n /** The item whose action failed, so its error shows next to it: `settings`, `skill:{id}` or `trigger:{id}`. */\n readonly actionTarget = signal<string | null>(null);\n /**\n * The names of the account the agent answers to and of the people who changed skills, once known,\n * and why they are not.\n */\n readonly accountNames = new NhAssistantAccountNames();\n /**\n * The name of the account the agent answers to, once known: the technical account of its run\n * settings, or of an agent in code.\n */\n readonly accountName = computed(() => {\n const configuration = this.configuration();\n const actorId = configuration?.source === 'admin'\n ? configuration.runSettings?.serviceAccountActorId\n : this.agent().serviceAccount?.actorId;\n return actorId ? this.accountNames.names().get(actorId) ?? null : null;\n });\n /** The agent's name; an agent in code names itself with a translation key. */\n readonly agentName = computed(() => {\n this.language();\n const agent = this.agent();\n return this.translated(codeTextKeys(agent.source, agent.displayName), agent.displayName);\n });\n\n /** The skill being changed; `null` with the skill form open adds a new skill. */\n readonly editingSkill = signal<DataSkill | null>(null);\n /** The trigger being changed; `null` with the trigger form open adds a new trigger. */\n readonly editingTrigger = signal<DataTrigger | null>(null);\n readonly comparison = signal<{ skillId: string; result: SkillComparison | null; failed: boolean } | null>(null);\n readonly versions = signal<{ skillId: string; items: DataSkillVersion[] | null; failed: boolean } | null>(null);\n\n private readonly language = toSignal(\n this.translate.onLangChange.pipe(map(event => event.lang), startWith(this.translate.currentLang)),\n { initialValue: this.translate.currentLang });\n\n readonly isAdminAgent = computed(() => this.configuration()?.source === 'admin');\n /** An agent created in the administration gets skills and triggers once it has run settings. */\n readonly canAddRunData = computed(() => {\n const configuration = this.configuration();\n return configuration !== null && (configuration.source === 'code' || configuration.runSettings !== null);\n });\n readonly skillOptions = computed<NhAssistantPickerOption[]>(() => {\n this.language();\n const configuration = this.configuration();\n return configuration\n ? [\n ...configuration.codeSkills.map(skill => ({\n value: skill.skillId,\n label: this.skillName(skill.skillId),\n description: this.translated(skillDescriptionKeys(configuration.agentId, skill.skillId), skill.description)\n })),\n ...configuration.dataSkills.map(skill => ({ value: skill.skillId, label: this.skillName(skill.skillId), description: skill.description }))\n ]\n : [];\n });\n readonly skillIds = computed(() => this.skillOptions().map(option => option.value));\n readonly triggerIds = computed(() => {\n const configuration = this.configuration();\n return configuration ? [...configuration.codeTriggers, ...configuration.dataTriggers].map(trigger => trigger.triggerId) : [];\n });\n readonly problems = computed(() => this.configuration()?.problems ?? []);\n /** What the run settings' approval policy means, in a sentence. */\n readonly settingsPolicy = computed(() => {\n this.language();\n const name = this.configuration()?.runSettings?.approvalPolicy;\n const summary = this.catalog()?.approvalPolicySummaries?.find(item => item.name === name);\n return summary ? describePolicy(summary, (key, params) => this.translate.instant(key, params) as string) : null;\n });\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.loadSubscription?.unsubscribe();\n this.actionSubscription?.unsubscribe();\n this.detailSubscription?.unsubscribe();\n });\n }\n\n ngOnInit(): void {\n this.load(this.startSetup());\n }\n\n load(openSetup = false): void {\n this.loading.set(true);\n this.loadFailed.set(false);\n this.loadSubscription?.unsubscribe();\n this.loadSubscription = forkJoin([this.admin.getRunCatalog(), this.admin.getAgentConfiguration(this.agent().id)]).subscribe({\n next: ([catalog, configuration]) => {\n this.catalog.set(catalog);\n this.configuration.set(configuration);\n this.loading.set(false);\n this.accountNames.load([\n configuration.runSettings?.serviceAccountActorId,\n this.agent().serviceAccount?.actorId,\n ...configuration.dataSkills.map(skill => skill.changedBy)\n ]);\n if (openSetup && configuration.source === 'admin' && configuration.runSettings === null) {\n this.open('setup');\n }\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n openSetup(): void {\n this.open('setup');\n }\n\n editSettings(): void {\n this.open('settings');\n }\n\n removeSettings(): void {\n const version = this.configuration()?.runSettings?.version ?? null;\n this.run(this.admin.removeRunSettings(this.agent().id, { expectedVersion: version }), 'nh-assistant.admin.run-config.settings.removed', 'settings');\n }\n\n addSkill(): void {\n this.editingSkill.set(null);\n this.open('skill');\n }\n\n editSkill(skill: DataSkill): void {\n this.editingSkill.set(skill);\n this.open('skill');\n }\n\n removeSkill(skill: DataSkill): void {\n this.run(\n this.admin.removeDataSkill(this.agent().id, skill.skillId, { expectedVersion: skill.version }),\n 'nh-assistant.admin.run-config.skills.removed',\n `skill:${skill.skillId}`);\n }\n\n promote(skill: DataSkill): void {\n const candidate = skill.candidate;\n if (candidate) {\n this.run(\n this.admin.promoteSkillCandidate(this.agent().id, skill.skillId, { version: candidate.version, reason: blank(this.reason()) }),\n 'nh-assistant.admin.run-config.candidate.promoted',\n `skill:${skill.skillId}`);\n }\n }\n\n discard(skill: DataSkill): void {\n const candidate = skill.candidate;\n if (candidate) {\n this.run(\n this.admin.discardSkillCandidate(this.agent().id, skill.skillId, { version: candidate.version, reason: blank(this.reason()) }),\n 'nh-assistant.admin.run-config.candidate.discarded',\n `skill:${skill.skillId}`);\n }\n }\n\n /** Shows or hides the comparison of a skill's candidate with its live version. */\n toggleComparison(skill: DataSkill): void {\n if (this.comparison()?.skillId === skill.skillId) {\n this.comparison.set(null);\n return;\n }\n\n this.versions.set(null);\n this.comparison.set({ skillId: skill.skillId, result: null, failed: false });\n this.detailSubscription?.unsubscribe();\n this.detailSubscription = this.admin.compareSkillCandidate(this.agent().id, skill.skillId).subscribe({\n next: result => this.comparison.set({ skillId: skill.skillId, result, failed: false }),\n error: () => this.comparison.set({ skillId: skill.skillId, result: null, failed: true })\n });\n }\n\n /** Shows or hides the version history of a skill. */\n toggleVersions(skill: DataSkill): void {\n if (this.versions()?.skillId === skill.skillId) {\n this.versions.set(null);\n return;\n }\n\n this.comparison.set(null);\n this.versions.set({ skillId: skill.skillId, items: null, failed: false });\n this.detailSubscription?.unsubscribe();\n this.detailSubscription = this.admin.getDataSkillVersions(this.agent().id, skill.skillId).subscribe({\n next: items => {\n this.versions.set({ skillId: skill.skillId, items, failed: false });\n this.accountNames.load(items.map(item => item.createdBy));\n },\n error: () => this.versions.set({ skillId: skill.skillId, items: null, failed: true })\n });\n }\n\n addTrigger(): void {\n this.editingTrigger.set(null);\n this.open('trigger');\n }\n\n editTrigger(trigger: DataTrigger): void {\n this.editingTrigger.set(trigger);\n this.open('trigger');\n }\n\n setTriggerShadow(trigger: DataTrigger, shadow: boolean): void {\n this.run(\n this.admin.setDataTriggerShadow(this.agent().id, trigger.triggerId, { mode: shadow ? 'shadow' : 'live', reason: null }),\n shadow ? 'nh-assistant.admin.run-config.triggers.in-shadow' : 'nh-assistant.admin.run-config.triggers.live',\n `trigger:${trigger.triggerId}`);\n }\n\n removeTrigger(trigger: DataTrigger): void {\n this.run(\n this.admin.removeDataTrigger(this.agent().id, trigger.triggerId, { expectedVersion: trigger.version }),\n 'nh-assistant.admin.run-config.triggers.removed',\n `trigger:${trigger.triggerId}`);\n }\n\n /** A form saved: show what happened and reload, which every change may affect. */\n onSetupCompleted(live: boolean): void {\n this.finish(live ? 'nh-assistant.admin.run-config.setup.saved-live' : 'nh-assistant.admin.run-config.setup.saved-shadow');\n }\n\n onSettingsSaved(): void {\n this.finish('nh-assistant.admin.run-config.settings.saved');\n }\n\n onSkillSaved(result: SkillFormSaved): void {\n this.finish(\n result.candidate\n ? 'nh-assistant.admin.run-config.skills.saved-candidate'\n : result.added ? 'nh-assistant.admin.run-config.skills.added' : 'nh-assistant.admin.run-config.skills.saved',\n result.skill.warnings ?? []);\n }\n\n onTriggerSaved(added: boolean): void {\n this.finish(added ? 'nh-assistant.admin.run-config.triggers.added' : 'nh-assistant.admin.run-config.triggers.saved');\n }\n\n confirm(action: Confirmation['action'], id: string): void {\n this.form.set(null);\n this.error.set(null);\n this.saved.set(null);\n this.reason.set('');\n this.confirming.set({ action, id });\n }\n\n isConfirming(action: Confirmation['action'], id: string): boolean {\n const confirming = this.confirming();\n return confirming?.action === action && confirming.id === id;\n }\n\n /**\n * An entry point of the flow: the forms of the run configuration open below with the focus in them;\n * the editor, the account, the runs and the MCP servers belong to the host.\n */\n onFlowEntry(entry: AgentFlowEntry): void {\n const opener = this.host.nativeElement.ownerDocument.activeElement;\n switch (entry.kind) {\n case 'setup':\n this.openFromFlow(opener, () => this.openSetup());\n return;\n case 'settings':\n this.openFromFlow(opener, () => this.editSettings());\n return;\n case 'add-skill':\n this.openFromFlow(opener, () => this.addSkill());\n return;\n case 'edit-skill': {\n const skill = this.configuration()?.dataSkills.find(item => item.skillId === entry.skillId);\n if (skill) {\n this.openFromFlow(opener, () => this.editSkill(skill));\n }\n return;\n }\n case 'add-trigger':\n this.openFromFlow(opener, () => this.addTrigger());\n return;\n case 'edit-trigger': {\n const trigger = this.configuration()?.dataTriggers.find(item => item.triggerId === entry.triggerId);\n if (trigger) {\n this.openFromFlow(opener, () => this.editTrigger(trigger));\n }\n return;\n }\n case 'edit-agent':\n this.editAgent.emit();\n return;\n case 'account':\n this.changeAccount.emit();\n return;\n case 'runs':\n this.openRuns.emit();\n return;\n case 'mcp-servers':\n this.openMcpServers.emit();\n return;\n }\n }\n\n cancel(): void {\n const form = this.form();\n const opener = this.returnFocus;\n this.returnFocus = null;\n this.form.set(null);\n this.confirming.set(null);\n this.error.set(null);\n // Back to the action that opened the form: the flow's entry point, or the action of its section.\n afterNextRender(() => {\n const target = opener?.isConnected\n ? opener\n : this.host.nativeElement.querySelector<HTMLElement>(`[data-open-form=\"${form}\"]`);\n target?.focus();\n }, { injector: this.injector });\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n\n /** A skill's name: the application's translation, or a readable form of its id. */\n skillName(skillId: string | null | undefined): string {\n return skillId ? this.translated(skillNameKeys(this.agent().id, skillId), readableId(skillId)) : '';\n }\n\n /** A person's name, or the id when the application does not know it. */\n nameOf(actorId: string | null | undefined): string {\n return this.accountNames.nameOf(actorId);\n }\n\n /** The account ID as the tooltip of a name shown in its place. */\n accountTitle(actorId: string | null | undefined): string | null {\n return this.accountNames.idTitleOf(actorId);\n }\n\n /** The first of the keys with a translation, or the fallback. */\n private translated(keys: readonly string[], fallback: string): string {\n for (const key of keys) {\n const value = this.translate.instant(key) as unknown;\n if (typeof value === 'string' && value.length > 0 && value !== key) {\n return value;\n }\n }\n return fallback;\n }\n\n /** Opens a form for the flow and remembers the entry point that opened it. */\n private openFromFlow(opener: Element | null, openForm: () => void): void {\n openForm();\n this.returnFocus = opener instanceof HTMLElement ? opener : null;\n }\n\n private finish(savedKey: string, warnings: readonly string[] = []): void {\n this.returnFocus = null;\n this.form.set(null);\n this.saved.set(savedKey);\n this.savedWarnings.set(warnings);\n this.changed.emit();\n this.load();\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>('[data-saved]')?.focus(), { injector: this.injector });\n }\n\n /** Opens one form at a time and moves the focus into it. */\n private open(form: Form): void {\n this.returnFocus = null;\n this.confirming.set(null);\n this.error.set(null);\n this.saved.set(null);\n this.reason.set('');\n this.form.set(form);\n afterNextRender(() => {\n this.host.nativeElement.querySelector<HTMLElement>(\n `[data-form=\"${form}\"] input:not([disabled]), [data-form=\"${form}\"] textarea, [data-work-setup] input:not([disabled])`)?.focus();\n }, { injector: this.injector });\n }\n\n /** Whether the last failed action concerned this item, so its error shows there. */\n failed(target: string): boolean {\n return this.error() !== null && this.actionTarget() === target;\n }\n\n /** Runs a change and reloads the configuration, which every change may affect. */\n private run(request: Observable<unknown>, savedKey: string, target: string): void {\n this.busy.set(true);\n this.error.set(null);\n this.saved.set(null);\n this.actionTarget.set(target);\n this.actionSubscription?.unsubscribe();\n this.actionSubscription = request.subscribe({\n error: (error: unknown) => {\n this.busy.set(false);\n this.error.set(toNhAssistantError(error));\n },\n complete: () => {\n this.busy.set(false);\n this.confirming.set(null);\n this.comparison.set(null);\n this.versions.set(null);\n this.finish(savedKey);\n }\n });\n }\n}\n\nfunction blank(value: string): string | null {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n","<section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || busy()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.run-config.title' | translate: { name: agentName() } }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.description' | translate }}</p>\n </div>\n </header>\n\n @if (saved(); as key) {\n <p class=\"message success\" role=\"status\" tabindex=\"-1\" data-saved>{{ key | translate }}</p>\n <!-- The save succeeded; a warning says what may still keep the skill from working. -->\n @for (warning of savedWarnings(); track warning) {\n <p class=\"message warning\" role=\"status\" [attr.data-saved-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('skill', warning) | nhAssistantTranslate: warning }}\n </p>\n }\n }\n\n @if (loading() && !configuration()) {\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 (configuration(); as config) {\n <nh-assistant-account-names-error [names]=\"accountNames\" />\n @if (problems().length > 0) {\n <!-- Each problem shows at the step of the flow it concerns, with the form that fixes it. -->\n <p class=\"message warning\" role=\"status\" data-problems>\n <nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.run-config.flow.problems' | translate }}\n </p>\n }\n\n <!-- The agent at a glance; the forms below change what each step shows. -->\n <nh-assistant-agent-flow\n [agent]=\"agent()\"\n [configuration]=\"config\"\n [catalog]=\"catalog()\"\n [tools]=\"tools()\"\n [servers]=\"servers()\"\n [accountName]=\"accountName()\"\n [busy]=\"busy()\"\n (entry)=\"onFlowEntry($event)\" />\n\n @if (config.source === 'admin') {\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-settings-title'\" data-run-settings>\n <header class=\"section-header\">\n <h4 [id]=\"id + '-settings-title'\">{{ 'nh-assistant.admin.run-config.settings.title' | translate }}</h4>\n </header>\n @if (form() === 'setup') {\n <nh-assistant-agent-work-setup\n [agentId]=\"config.agentId\"\n [agentName]=\"agentName()\"\n [catalog]=\"catalog()\"\n [worksOn]=\"agent()\"\n [toolSelectors]=\"config.toolSelectors\"\n [toolCatalog]=\"tools()\"\n [takenSkillIds]=\"skillIds()\"\n [takenTriggerIds]=\"triggerIds()\"\n (completed)=\"onSetupCompleted($event.live)\"\n (cancelled)=\"cancel()\" />\n } @else if (form() === 'settings') {\n <nh-assistant-run-settings-form\n [agentId]=\"config.agentId\"\n [catalog]=\"catalog()\"\n [settings]=\"config.runSettings\"\n (saved)=\"onSettingsSaved()\"\n (cancelled)=\"cancel()\" />\n } @else if (config.runSettings; as settings) {\n <dl class=\"review\" data-settings-summary>\n <dt>{{ 'nh-assistant.admin.run-config.settings.who.short' | translate }}</dt>\n <dd>\n {{ 'nh-assistant.admin.run-config.settings.accountability.' + settings.accountability | translate }}\n @if (settings.serviceAccountActorId; as accountId) {\n <span class=\"block\" data-account-name>\n <nh-assistant-account-label [actorId]=\"accountId\" [name]=\"accountName()\" />\n </span>\n }\n </dd>\n <dt>{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}</dt>\n <dd>{{ settings.ruleHandler ?? ('nh-assistant.admin.run-config.model' | translate) }}</dd>\n <dt>{{ 'nh-assistant.admin.run-config.approval-policy' | translate }}</dt>\n <dd>\n {{ settings.approvalPolicy ?? ('nh-assistant.admin.run-config.settings.approval.default' | translate) }}\n @if (settingsPolicy(); as sentence) {\n <span class=\"muted block\">{{ sentence }}</span>\n }\n </dd>\n <dt>{{ 'nh-assistant.admin.agents.version-label' | translate }}</dt>\n <dd>\n {{ 'nh-assistant.admin.agents.version' | translate: { version: settings.version } }}\n @if (!settings.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n </dd>\n </dl>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.rights' | translate }}</p>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" data-open-form=\"settings\" [disabled]=\"busy()\" (click)=\"editSettings()\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.run-config.settings.edit' | translate }}\n </button>\n @if (isConfirming('remove-settings', config.agentId)) {\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.remove-explain' | translate }}</span>\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"removeSettings()\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('remove-settings', config.agentId)\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.run-config.settings.remove' | translate }}\n </button>\n }\n </div>\n @if (failed('settings')) {\n <p class=\"form-error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: error()!.code }}</p>\n }\n } @else {\n <div class=\"state\" data-setup-offer>\n <p>{{ 'nh-assistant.admin.run-config.settings.empty' | translate }}</p>\n <div class=\"card-actions\">\n <button class=\"primary\" type=\"button\" data-open-form=\"setup\" [disabled]=\"busy()\" (click)=\"openSetup()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.setup.start' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" data-open-form=\"settings\" [disabled]=\"busy()\" (click)=\"editSettings()\">\n {{ 'nh-assistant.admin.run-config.settings.add' | translate }}\n </button>\n </div>\n </div>\n }\n </section>\n }\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-skills-title'\" data-skills>\n <header class=\"section-header\">\n <div>\n <h4 [id]=\"id + '-skills-title'\">{{ 'nh-assistant.admin.agents.skills.title' | translate }}</h4>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.skills.description' | translate }}</p>\n </div>\n <button class=\"secondary\" type=\"button\" data-open-form=\"skill\" [disabled]=\"busy() || !canAddRunData() || form() === 'skill'\" (click)=\"addSkill()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.skills.add' | translate }}\n </button>\n </header>\n @if (!canAddRunData()) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.needs-settings' | translate }}</p>\n }\n\n @if (form() === 'skill') {\n <nh-assistant-skill-form\n [agentId]=\"config.agentId\"\n [catalog]=\"catalog()\"\n [toolSelectors]=\"config.toolSelectors\"\n [toolCatalog]=\"tools()\"\n [skill]=\"editingSkill()\"\n [takenIds]=\"skillIds()\"\n (saved)=\"onSkillSaved($event)\"\n (cancelled)=\"cancel()\" />\n }\n\n @if (config.codeSkills.length === 0 && config.dataSkills.length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.run-config.skills.empty' | translate }}</p>\n } @else {\n <ul class=\"skills\">\n @for (skill of config.codeSkills; track skill.skillId) {\n <li class=\"skill\" [attr.data-code-skill]=\"skill.skillId\">\n <div class=\"card-header\">\n <strong>{{ (skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) }}</strong>\n <span class=\"mono muted\">{{ skill.skillId }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n </div>\n <p class=\"muted\">{{ skillDescriptionKeys(config.agentId, skill.skillId) | nhAssistantTranslate: skill.description }}</p>\n </li>\n }\n @for (skill of config.dataSkills; track skill.skillId) {\n <li class=\"skill\" [attr.data-data-skill]=\"skill.skillId\">\n <div class=\"card-header\">\n <strong>{{ (skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) }}</strong>\n <span class=\"mono muted\">{{ skill.skillId }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.version' | translate: { version: skill.version } }}</span>\n @if (!skill.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n @if (skill.candidate) {\n <span class=\"badge warning\" data-candidate-badge>{{ 'nh-assistant.admin.run-config.candidate.badge' | translate: { version: skill.candidate.version } }}</span>\n }\n </div>\n <p class=\"muted\">{{ skill.description }}</p>\n @for (warning of skill.warnings ?? []; track warning) {\n <p class=\"message warning\" [attr.data-skill-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('skill', warning) | nhAssistantTranslate: warning }}\n </p>\n }\n <div class=\"meta\">\n <span>{{ skill.ruleHandler ? ('nh-assistant.admin.run-config.rule-handler-value' | translate: { name: skill.ruleHandler }) : ('nh-assistant.admin.run-config.model' | translate) }}</span>\n @if (skill.profile) {\n <span>{{ 'nh-assistant.admin.run-config.profile-value' | translate: { name: skill.profile } }}</span>\n }\n <span>{{ (skill.tools.length === 1 ? 'nh-assistant.admin.agents.tool-count-one' : 'nh-assistant.admin.agents.tool-count') | translate: { count: skill.tools.length } }}</span>\n <span [attr.title]=\"accountTitle(skill.changedBy)\">{{ 'nh-assistant.admin.run-config.changed' | translate: { user: nameOf(skill.changedBy), date: (skill.changedAt | date: 'medium') } }}</span>\n </div>\n @if (skill.candidate; as candidate) {\n <div class=\"subsection\" data-candidate>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.candidate.explain' | translate: { version: candidate.version, description: candidate.description } }}</p>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [attr.aria-expanded]=\"comparison()?.skillId === skill.skillId\" (click)=\"toggleComparison(skill)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.run-config.candidate.compare' | translate }}\n </button>\n @if (isConfirming('promote', skill.skillId)) {\n <button class=\"primary\" type=\"button\" [disabled]=\"busy()\" (click)=\"promote(skill)\">{{ 'nh-assistant.admin.run-config.candidate.confirm-promote' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else if (isConfirming('discard', skill.skillId)) {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"discard(skill)\">{{ 'nh-assistant.admin.run-config.candidate.confirm-discard' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"secondary\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('promote', skill.skillId)\">{{ 'nh-assistant.admin.run-config.candidate.promote' | translate }}</button>\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('discard', skill.skillId)\">{{ 'nh-assistant.admin.run-config.candidate.discard' | translate }}</button>\n }\n </div>\n @if (comparison(); as shown) {\n @if (shown.skillId === skill.skillId) {\n @if (shown.failed) {\n <p class=\"message error\" role=\"alert\">{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n } @else if (shown.result; as result) {\n <div class=\"table-scroll\">\n <table class=\"summary-table\" data-comparison>\n <caption class=\"visually-hidden\">{{ 'nh-assistant.admin.run-config.candidate.comparison' | translate: { skill: (skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) } }}</caption>\n <thead>\n <tr>\n <th scope=\"col\">{{ 'nh-assistant.admin.evaluation.columns.measure' | translate }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.run-config.candidate.live-column' | translate: { version: result.live.version } }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.run-config.candidate.candidate-column' | translate: { version: result.candidate.version } }}</th>\n </tr>\n </thead>\n <tbody>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.runs' | translate }}</th><td>{{ result.live.runs | number }}</td><td>{{ result.candidate.runs | number }}</td></tr>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.completed' | translate }}</th><td>{{ result.live.completed | number }}</td><td>{{ result.candidate.completed | number }}</td></tr>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.failed' | translate }}</th><td>{{ result.live.failed | number }}</td><td>{{ result.candidate.failed | number }}</td></tr>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.proposals' | translate }}</th><td>{{ result.live.proposals | number }}</td><td>{{ result.candidate.proposals | number }}</td></tr>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.tokens' | translate }}</th><td>{{ result.live.tokens | number }}</td><td>{{ result.candidate.tokens | number }}</td></tr>\n </tbody>\n </table>\n </div>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.candidate.paired' | translate: { count: result.pairedEvents, date: (result.from | date: 'medium') } }}</p>\n } @else {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n }\n }\n }\n </div>\n }\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"busy()\" (click)=\"editSkill(skill)\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" [attr.aria-expanded]=\"versions()?.skillId === skill.skillId\" (click)=\"toggleVersions(skill)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.run-config.skills.versions' | translate }}\n </button>\n @if (isConfirming('remove-skill', skill.skillId)) {\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.skills.remove-explain' | translate }}</span>\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"removeSkill(skill)\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('remove-skill', skill.skillId)\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.delete' | translate }}\n </button>\n }\n </div>\n @if (failed('skill:' + skill.skillId)) {\n <p class=\"form-error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: error()!.code }}</p>\n }\n @if (versions(); as shown) {\n @if (shown.skillId === skill.skillId) {\n @if (shown.failed) {\n <p class=\"message error\" role=\"alert\">{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n } @else if (shown.items; as items) {\n <ul class=\"history\" data-versions>\n @for (version of items; track version.version) {\n <li>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.version' | translate: { version: version.version } }}</span>\n <span class=\"badge\" [class.success]=\"version.status === 'live'\" [class.warning]=\"version.status === 'candidate'\">{{ 'nh-assistant.admin.run-config.status.' + version.status | translate }}</span>\n <span>{{ version.description }}</span>\n <span class=\"muted\" [attr.title]=\"accountTitle(version.createdBy)\">{{ 'nh-assistant.admin.run-config.changed' | translate: { user: nameOf(version.createdBy), date: (version.createdAt | date: 'medium') } }}</span>\n @if (version.reason) {\n <span class=\"muted\">{{ 'nh-assistant.admin.agents.state.reason' | translate: { reason: version.reason } }}</span>\n }\n </li>\n }\n </ul>\n } @else {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n }\n }\n }\n </li>\n }\n </ul>\n }\n </section>\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-triggers-title'\" data-triggers>\n <header class=\"section-header\">\n <div>\n <h4 [id]=\"id + '-triggers-title'\">{{ 'nh-assistant.admin.run-config.triggers.title' | translate }}</h4>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.description' | translate }}</p>\n </div>\n <button class=\"secondary\" type=\"button\" data-open-form=\"trigger\" [disabled]=\"busy() || !canAddRunData() || form() === 'trigger'\" (click)=\"addTrigger()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.triggers.add' | translate }}\n </button>\n </header>\n\n @if (form() === 'trigger') {\n <nh-assistant-trigger-form\n [agentId]=\"config.agentId\"\n [catalog]=\"catalog()\"\n [worksOn]=\"agent()\"\n [skills]=\"skillOptions()\"\n [trigger]=\"editingTrigger()\"\n [takenIds]=\"triggerIds()\"\n (saved)=\"onTriggerSaved($event.added)\"\n (cancelled)=\"cancel()\" />\n }\n\n @if (config.codeTriggers.length === 0 && config.dataTriggers.length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.run-config.triggers.empty' | translate }}</p>\n } @else {\n <ul class=\"skills\">\n @for (trigger of config.codeTriggers; track trigger.triggerId) {\n <li class=\"skill\" [attr.data-code-trigger]=\"trigger.triggerId\">\n <div class=\"card-header\">\n <span class=\"mono\">{{ trigger.triggerId }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.run-config.triggers.sources.' + trigger.source | translate }}</span>\n </div>\n @if (trigger.skillId) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.skill-value' | translate: { skill: skillName(trigger.skillId) } }}</p>\n }\n </li>\n }\n @for (trigger of config.dataTriggers; track trigger.triggerId) {\n <li class=\"skill\" [attr.data-data-trigger]=\"trigger.triggerId\">\n <div class=\"card-header\">\n <span class=\"mono\">{{ trigger.triggerId }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.run-config.triggers.sources.' + trigger.source | translate }}</span>\n @if (trigger.shadow) {\n <span class=\"badge warning\" data-shadow-badge>{{ 'nh-assistant.admin.agents.shadow.badge' | translate }}</span>\n } @else {\n <span class=\"badge success\">{{ 'nh-assistant.admin.run-config.triggers.live-badge' | translate }}</span>\n }\n @if (!trigger.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n </div>\n <div class=\"meta\">\n @if (trigger.source === 'event') {\n <span class=\"mono\">{{ trigger.event }}</span>\n @if (trigger.filters?.length) {\n <span data-trigger-filters>{{ 'nh-assistant.admin.run-config.triggers.filters.applied' | translate: { filters: trigger.filters!.join(', ') } }}</span>\n }\n } @else {\n <span class=\"mono\">{{ trigger.cron }} {{ trigger.timeZone ?? 'UTC' }}</span>\n @if (trigger.subjectSet) {\n <span class=\"mono\">{{ trigger.subjectSet }}</span>\n } @else {\n <!-- A schedule without a subject set runs for the whole application, per division for a per-division agent. -->\n <span data-trigger-target>{{ (agent().perDivision ? 'nh-assistant.admin.run-config.triggers.target.every-division' : 'nh-assistant.admin.run-config.triggers.target.application') | translate }}</span>\n }\n }\n <span>{{ (trigger.skillId ? 'nh-assistant.admin.run-config.triggers.skill-value' : 'nh-assistant.admin.run-config.triggers.agent-routes') | translate: { skill: skillName(trigger.skillId) } }}</span>\n <span>{{ 'nh-assistant.admin.run-config.triggers.conflicts.' + trigger.conflict | translate }}</span>\n <span>{{ 'nh-assistant.admin.agents.version' | translate: { version: trigger.version } }}</span>\n </div>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"busy()\" (click)=\"editTrigger(trigger)\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" [attr.data-trigger-shadow]=\"trigger.shadow ? 'live' : 'shadow'\" [disabled]=\"busy()\" (click)=\"setTriggerShadow(trigger, !trigger.shadow)\">\n {{ (trigger.shadow ? 'nh-assistant.admin.agents.shadow.action.live' : 'nh-assistant.admin.agents.shadow.action.shadow') | translate }}\n </button>\n @if (isConfirming('remove-trigger', trigger.triggerId)) {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"removeTrigger(trigger)\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('remove-trigger', trigger.triggerId)\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.delete' | translate }}\n </button>\n }\n </div>\n @if (failed('trigger:' + trigger.triggerId)) {\n <p class=\"form-error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: error()!.code }}</p>\n }\n </li>\n }\n </ul>\n }\n </section>\n }\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 output,\n signal,\n viewChild\n} from '@angular/core';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport { Observable, Subscription, catchError, forkJoin, map, of } from 'rxjs';\nimport {\n AdminAgent,\n AgentShadowMode,\n AgentShadowState,\n AgentSkillState,\n AgentState,\n McpServer,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n NhAssistantPanelService,\n NhAssistantStore,\n nhAssistantErrorMessageKey,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError,\n RunCatalog,\n SetAgentStateRequest,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport {\n ɵNhAssistantRunNowDialogComponent as NhAssistantRunNowDialogComponent,\n type ɵNhAssistantRunNowAgent as NhAssistantRunNowAgent\n} from '@newheap/platform-ai-chat/agent-runs';\nimport { NhAssistantAccountNames, NhAssistantAccountNamesErrorComponent } from '../nh-assistant-account-names';\nimport {\n codeTextKeys,\n policyKeys,\n readableId,\n runNowAgentOf,\n skillDescriptionKeys,\n skillNameKeys,\n warningKeys,\n WorksOnSummary,\n worksOnSummary\n} from './agent-texts';\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';\nimport { NhAssistantAgentRunHistoryComponent } from './nh-assistant-agent-run-history.component';\nimport { NhAssistantAgentRunConfigurationComponent } from './nh-assistant-agent-run-configuration.component';\nimport { NhAssistantAccountPickerComponent } from './run-config/nh-assistant-account-picker.component';\n\nlet nextId = 0;\n\ntype AgentStateAction = SetAgentStateRequest['state'];\n\n/** A state change being entered, of the agent or one of its skills, with the state it changes from. */\ninterface StateChange {\n agentId: string;\n skillId?: string;\n state: AgentStateAction;\n from: AdminAgent['runState'] | AgentSkillState['runState'];\n}\n\n/** The longest reason the server stores with a state change. */\nconst maxStateReason = 500;\n\n/** Refusals of a technical account that concern the account field itself. */\nconst accountRefusals = new Set(['assistant-service-account-not-found', 'assistant-service-account-not-used']);\n\n/** The run catalog as `load` reads it: the catalog, or why it could not be read. */\ninterface CatalogRead {\n catalog: RunCatalog | null;\n error: NhAssistantError | null;\n}\n\n/**\n * Agent administration: code agents (override, reset) and agents created here (edit, delete),\n * and for every agent and skill its run state with pause, switch off, stop and resume (switch on\n * for one that is off), its shadow mode and that of each\n * skill, and the technical account of an agent that answers to one, 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, the evaluation action of an agent with\n * shadow variants opens `nh-assistant-agent-evaluation`, and the run configuration action opens\n * `nh-assistant-agent-run-configuration` for the skills, triggers and run settings defined as data.\n * \"Run now\" on an agent that runs on its own opens the run-now dialog: the whole application (or a\n * division of it) or an object of one of its types, and an optional instruction; the receipt opens\n * the agent's conversation in the assistant panel. \"Runs\" opens `nh-assistant-agent-run-history`, the\n * agent's runs with their results. When the run catalog cannot be read, the page says why with its\n * code and offers to read it again; until then it offers no \"Run now\" and the editor leaves what an\n * agent works on and its groups as they are. The run configuration opens with the agent's flow, whose\n * entry points open the editor, the runs and the technical account here and return to the run\n * configuration afterwards; `openMcpServers` asks the host to show the MCP servers.\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 NhAssistantAgentRunHistoryComponent,\n NhAssistantAgentRunConfigurationComponent,\n NhAssistantAccountPickerComponent,\n NhAssistantRunNowDialogComponent,\n NhAssistantAccountNamesErrorComponent\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 panel = inject(NhAssistantPanelService);\n private readonly translate = inject(TranslateService);\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 private catalogSubscription?: 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 /** The run catalog: object types by name, policies and divisions; `null` when it could not be read. */\n readonly catalog = signal<RunCatalog | null>(null);\n /** Why the run catalog could not be read; `null` once it was. */\n readonly catalogError = signal<NhAssistantError | null>(null);\n readonly catalogErrorKeys = computed(() => nhAssistantErrorKeys(this.catalogError()));\n /** The run catalog is being read again after a failure. */\n readonly catalogLoading = signal(false);\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 /** The agent whose run configuration is shown instead of the list. */\n readonly configuring = signal<AdminAgent | null>(null);\n /** The agent whose runs are shown instead of the list. */\n readonly viewingRuns = signal<AdminAgent | null>(null);\n /**\n * The agent whose run configuration opened the editor or the runs from its flow; closing them\n * returns to its run configuration instead of the list.\n */\n readonly returnTo = signal<string | null>(null);\n /** The flow of a run configuration asks to show the MCP servers, whose background use it explains. */\n readonly openMcpServers = output<void>();\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<StateChange | null>(null);\n /** The shadow mode change whose reason is being entered, of the agent or one of its skills. */\n readonly changingShadow = signal<{ agentId: string; skillId?: string; mode: AgentShadowMode } | null>(null);\n /** The change of the technical account being entered: a new account, or the one in code. */\n readonly changingAccount = signal<{ agentId: string; mode: 'set' | 'code' } | null>(null);\n readonly accountId = signal('');\n /** Why the account of the open account form was refused, shown at the account field. */\n readonly accountError = signal<NhAssistantError | null>(null);\n /** The text of the account field's error: the refused field value, then the code. */\n readonly accountErrorKeys = computed(() => {\n const error = this.accountError();\n const value = error?.fieldErrors?.['actorId']?.[0];\n return value ? [`nh-assistant.admin.run-config.field-errors.${value}`, ...nhAssistantErrorKeys(error)] : nhAssistantErrorKeys(error);\n });\n /** Whether the application offers an account search for the technical account. */\n readonly accountSearch = signal(false);\n /**\n * The names of the technical accounts and of the people who changed an agent, once known, and why\n * they are not.\n */\n readonly accountNameLookup = new NhAssistantAccountNames();\n /** The names of the technical accounts in the list, by account id. */\n readonly accountNames = computed(() => this.accountNameLookup.names());\n /** The agent whose last action failed, so its error shows on its card. */\n readonly errorAgentId = signal<string | null>(null);\n /** The agent the run-now dialog runs; `null` while it is closed. */\n readonly runningNow = signal<AdminAgent | null>(null);\n /** The agent of the run-now dialog as the dialog needs it: its name and what it works on. */\n readonly runNowAgent = computed<NhAssistantRunNowAgent | null>(() => {\n const agent = this.runningNow();\n if (!agent) {\n return null;\n }\n const keys = codeTextKeys(agent.source, agent.displayName);\n const translated = keys.length > 0 ? this.translate.instant(keys[0]) as string : null;\n return runNowAgentOf(agent, translated && translated !== keys[0] ? translated : agent.displayName);\n });\n /** The run configuration opens with the guided setup, for an agent created to work on its own. */\n readonly setupOnOpen = signal(false);\n readonly stateReason = signal('');\n readonly maxReason = maxStateReason;\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n readonly codeTextKeys = codeTextKeys;\n readonly skillNameKeys = skillNameKeys;\n readonly warningKeys = warningKeys;\n readonly skillDescriptionKeys = skillDescriptionKeys;\n readonly policyKeys = policyKeys;\n readonly readableId = readableId;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.actionSubscription?.unsubscribe();\n this.catalogSubscription?.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.catalogSubscription?.unsubscribe();\n this.catalogLoading.set(false);\n this.subscription = forkJoin([\n this.admin.getAgents(),\n this.admin.getTools(),\n this.admin.getMcpServers(),\n // The agents stay usable without the catalog; the page says why it is missing.\n this.readCatalog()\n ]).subscribe({\n next: ([agents, tools, servers, read]) => {\n this.agents.set(agents);\n this.tools.set(tools);\n this.servers.set(servers);\n this.applyCatalog(read);\n this.loading.set(false);\n this.loadAccountNames(agents);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n /** Reads the run catalog again after it could not be read. */\n retryCatalog(): void {\n this.catalogLoading.set(true);\n this.catalogSubscription?.unsubscribe();\n this.catalogSubscription = this.readCatalog().subscribe(read => {\n this.catalogLoading.set(false);\n this.applyCatalog(read);\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 /**\n * Whether the agent can run on its own and so has a run configuration: an agent in code with runs,\n * or any agent created here, which gets run settings as data.\n */\n hasRunConfiguration(agent: AdminAgent): boolean {\n return agent.source === 'admin' || (agent.shadow !== null && agent.shadow !== undefined);\n }\n\n /**\n * Whether the agent can be run now: it runs on its own, so it has a run configuration, it is\n * neither stopped nor disabled in code, and the run catalog names what it can run on. An agent\n * that is off still runs for a person. The server decides the rest when the run starts.\n */\n canRunNow(agent: AdminAgent): boolean {\n return this.catalog() !== null\n && this.hasRunConfiguration(agent)\n && (agent.runState === 'active' || agent.runState === 'paused' || agent.runState === 'off');\n }\n\n /** Opens the run-now dialog of the agent. */\n runNow(agent: AdminAgent): void {\n this.closeForms();\n this.runningNow.set(agent);\n }\n\n /** Opens the conversation the run works in, in the assistant panel. */\n openConversation(conversationId: string): void {\n this.panel.open(conversationId);\n }\n\n /** Shows the agent's skills, triggers and run settings defined as data. */\n openRunConfiguration(agent: AdminAgent, setup = false): void {\n this.setupOnOpen.set(setup);\n this.error.set(null);\n this.confirming.set(null);\n this.configuring.set(agent);\n afterNextRender(() => this.backButton()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /** Returns to the list, refreshed, and to the run configuration action of the agent. */\n closeRunConfiguration(): void {\n const agentId = this.configuring()?.id;\n this.returnTo.set(null);\n this.configuring.set(null);\n this.refreshAgents();\n if (agentId !== undefined) {\n afterNextRender(() => {\n const action = Array.from(this.host.nativeElement.querySelectorAll<HTMLButtonElement>('[data-run-config-agent]'))\n .find(item => item.dataset['runConfigAgent'] === agentId);\n action?.focus();\n }, { injector: this.injector });\n }\n }\n\n /** Shows the agent's runs with their results. */\n openRuns(agent: AdminAgent): void {\n this.error.set(null);\n this.confirming.set(null);\n this.viewingRuns.set(agent);\n afterNextRender(() => this.backButton()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /**\n * Returns to the run configuration whose flow opened the runs, or to the list and the runs action of\n * the agent whose runs were open.\n */\n closeRuns(): void {\n const agentId = this.viewingRuns()?.id;\n this.viewingRuns.set(null);\n if (this.returnToRunConfiguration(agentId)) {\n return;\n }\n if (agentId !== undefined) {\n afterNextRender(() => {\n const action = Array.from(this.host.nativeElement.querySelectorAll<HTMLButtonElement>('[data-runs-agent]'))\n .find(item => item.dataset['runsAgent'] === agentId);\n action?.focus();\n }, { injector: this.injector });\n }\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 /** A new agent meant to work on its own continues in its run configuration's guided setup. */\n onWorkRequested(agent: AdminAgent): void {\n this.returnTo.set(null);\n this.onSaved(agent);\n this.openRunConfiguration(agent, true);\n }\n\n /** The flow of the agent's run configuration opens the editor; saving or cancelling returns there. */\n editFromRunConfiguration(agent: AdminAgent): void {\n this.configuring.set(null);\n this.returnTo.set(agent.id);\n this.edit(agent);\n }\n\n /** The flow of the agent's run configuration opens its runs; going back returns there. */\n runsFromRunConfiguration(agent: AdminAgent): void {\n this.configuring.set(null);\n this.returnTo.set(agent.id);\n this.openRuns(agent);\n }\n\n /** The flow of an agent in code opens the form that replaces its technical account on its card. */\n accountFromRunConfiguration(agent: AdminAgent): void {\n this.configuring.set(null);\n this.returnTo.set(null);\n this.refreshAgents();\n this.askAccount(agent, 'set');\n }\n\n /** The editor saved: back to the run configuration that opened it, or to the list. */\n onEditorSaved(agent: AdminAgent): void {\n this.onSaved(agent);\n this.returnToRunConfiguration(agent.id, agent);\n }\n\n /** The editor closed without saving: back to the run configuration that opened it, or to the list. */\n onEditorCancelled(): void {\n const agentId = this.editing()?.id;\n this.editing.set(undefined);\n this.returnToRunConfiguration(agentId);\n }\n\n /** Opens the run configuration again when its flow opened what closes now; `false` otherwise. */\n private returnToRunConfiguration(agentId: string | undefined, saved?: AdminAgent): boolean {\n const returnTo = this.returnTo();\n this.returnTo.set(null);\n if (returnTo === null || returnTo !== agentId) {\n return false;\n }\n const agent = saved ?? this.agents().find(item => item.id === returnTo);\n if (!agent) {\n return false;\n }\n this.openRunConfiguration(agent);\n return true;\n }\n\n /** What the agent works on, with its object types named as the run catalog names them. */\n worksOn(agent: AdminAgent): WorksOnSummary & { only: 'all' | 'types' | 'application' } {\n const summary = worksOnSummary(agent, this.catalog()?.subjectTypes);\n return {\n ...summary,\n only: summary.all ? 'all' : summary.types.length > 0 ? 'types' : 'application'\n };\n }\n\n /** The groups the agent is in, named as the run catalog names them; `null` for none. */\n groupNames(agent: AdminAgent): string | null {\n const groups = this.catalog()?.agentGroups ?? [];\n const names = (agent.groups ?? []).map(id => groups.find(group => group.id === id)?.name ?? id);\n return names.length > 0 ? names.join(', ') : null;\n }\n\n /** The name of an account or person, or the id when the application does not know it. */\n accountName(actorId: string | null | undefined): string {\n return this.accountNameLookup.nameOf(actorId);\n }\n\n /** The account ID as the tooltip of a name shown in its place. */\n accountTitle(actorId: string | null | undefined): string | null {\n return this.accountNameLookup.idTitleOf(actorId);\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', 'off', 'stopped'];\n case 'paused':\n return ['active', 'off', 'stopped'];\n case 'off':\n return ['active', 'stopped'];\n case 'stopped':\n return ['active', 'off'];\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', 'off', 'stopped'];\n case 'paused':\n return ['active', 'off', 'stopped'];\n case 'off':\n return ['active', 'stopped'];\n default:\n return ['active'];\n }\n }\n\n /**\n * The key of a state change's label, explanation or confirmation: making an agent or skill that is\n * off active again switches it on, which replays nothing, unlike a resume.\n */\n stateKey(part: 'action' | 'explain' | 'confirm', from: string, action: AgentStateAction): string {\n return `nh-assistant.admin.agents.state.${part}.${from === 'off' && action === 'active' ? 'switch-on' : action}`;\n }\n\n /** The explanation of a state change of one skill. */\n skillStateExplainKey(change: StateChange): string {\n return `nh-assistant.admin.agents.skills.explain.${change.from === 'off' && change.state === 'active' ? 'switch-on' : change.state}`;\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.closeForms();\n this.changingState.set({ agentId: agent.id, skillId: skill?.skillId, state, from: skill?.runState ?? agent.runState });\n afterNextRender(() => this.reasonInput()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /**\n * The shadow modes an agent or skill can change to: the opposite of its own mode, and the mode\n * in code once an administrator overrode it. A shadow variant, and an agent without runs that\n * only chats, offer none.\n */\n shadowActions(shadow: AgentShadowState | null | undefined): AgentShadowMode[] {\n if (!shadow || shadow.locked) {\n return [];\n }\n const own = shadow.override ?? shadow.configured;\n const actions: AgentShadowMode[] = [own ? 'live' : 'shadow'];\n return shadow.override === null ? actions : [...actions, 'code'];\n }\n\n /** Opens the reason form of a shadow mode change of the agent or, with a skill, of that skill. */\n askShadow(agent: AdminAgent, mode: AgentShadowMode, skill?: AgentSkillState): void {\n this.closeForms();\n this.changingShadow.set({ agentId: agent.id, skillId: skill?.skillId, mode });\n afterNextRender(() => this.reasonInput()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /**\n * The label of a shadow action. An agent created here has no code: returning to its \"code\" mode\n * means returning to the mode it was set up with.\n */\n shadowActionKey(agent: AdminAgent, mode: AgentShadowMode): string {\n return mode === 'code' && agent.source !== 'code'\n ? 'nh-assistant.admin.agents.shadow.action.own'\n : `nh-assistant.admin.agents.shadow.action.${mode}`;\n }\n\n /** The explanation of a shadow change of the agent or one of its skills. */\n shadowExplainKey(agent: AdminAgent, mode: AgentShadowMode, skill: boolean): string {\n const group = skill ? 'skill-explain' : 'explain';\n return `nh-assistant.admin.agents.shadow.${group}.${mode === 'code' && agent.source !== 'code' ? 'own' : mode}`;\n }\n\n /** The mode the agent, or one of its skills, was set up with: what returning to it means. */\n ownShadowModeKey(agent: AdminAgent, skillId?: string): string {\n const shadow = skillId === undefined\n ? agent.shadow\n : agent.skills?.find(skill => skill.skillId === skillId)?.shadow;\n return shadow?.configured ? 'nh-assistant.admin.agents.shadow.mode.shadow' : 'nh-assistant.admin.agents.shadow.mode.live';\n }\n\n isChangingShadow(agentId: string, mode: AgentShadowMode, skillId?: string): boolean {\n const change = this.changingShadow();\n return change?.agentId === agentId && change.mode === mode && change.skillId === skillId;\n }\n\n applyShadow(agent: AdminAgent): void {\n const change = this.changingShadow();\n if (change?.agentId !== agent.id) {\n return;\n }\n\n const reason = this.stateReason().trim();\n const request = { mode: change.mode, reason: reason.length > 0 ? reason : null };\n if (change.skillId !== undefined) {\n this.run(\n agent.id,\n this.admin.setSkillShadow(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.setAgentShadow(agent.id, request),\n state => this.replace(withState(agent, state)));\n }\n\n /** Opens the form that changes the technical account, or returns to the one in code. */\n askAccount(agent: AdminAgent, mode: 'set' | 'code'): void {\n this.closeForms();\n this.changingAccount.set({ agentId: agent.id, mode });\n this.accountId.set('');\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>('[data-account-form] input')?.focus(), { injector: this.injector });\n }\n\n /** A changed account clears the error of the one before. */\n onAccountChange(actorId: string): void {\n this.accountId.set(actorId);\n this.accountError.set(null);\n }\n\n isChangingAccount(agentId: string, mode: 'set' | 'code'): boolean {\n const change = this.changingAccount();\n return change?.agentId === agentId && change.mode === mode;\n }\n\n /**\n * Changes the technical account. The form stays open while the server decides, so a missing or\n * refused account shows at the account field, which takes the focus.\n */\n applyAccount(agent: AdminAgent): void {\n const change = this.changingAccount();\n if (change?.agentId !== agent.id || this.busyAgentId() !== null) {\n return;\n }\n\n const actorId = change.mode === 'set' ? this.accountId().trim() : null;\n if (actorId === '') {\n this.accountError.set({\n code: 'assistant-validation',\n messageKey: nhAssistantErrorMessageKey('assistant-validation'),\n fieldErrors: { actorId: ['required'] }\n });\n this.focusAccount();\n return;\n }\n\n const reason = this.stateReason().trim();\n this.busyAgentId.set(agent.id);\n this.errorAgentId.set(agent.id);\n this.error.set(null);\n this.accountError.set(null);\n this.actionSubscription?.unsubscribe();\n this.actionSubscription = this.admin.setServiceAccount(agent.id, { actorId, reason: reason.length > 0 ? reason : null }).subscribe({\n next: state => this.replace(withState(agent, state)),\n complete: () => {\n this.busyAgentId.set(null);\n this.changingAccount.set(null);\n this.stateReason.set('');\n this.refreshChat();\n this.loadAccountNames(this.agents());\n },\n error: (error: unknown) => {\n this.busyAgentId.set(null);\n const failure = toNhAssistantError(error);\n if (failure.fieldErrors?.['actorId'] || accountRefusals.has(failure.code)) {\n this.accountError.set(failure);\n this.focusAccount();\n } else {\n this.error.set(failure);\n }\n }\n });\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.changingShadow.set(null);\n this.changingAccount.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.errorAgentId.set(agentId);\n this.confirming.set(null);\n this.changingState.set(null);\n this.changingShadow.set(null);\n this.changingAccount.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 this.loadAccountNames(this.agents());\n },\n error: (error: unknown) => {\n this.busyAgentId.set(null);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n /** Looks up the names of the technical accounts and of the people who changed an agent's state. */\n private loadAccountNames(agents: readonly AdminAgent[]): void {\n this.accountNameLookup.load(agents.flatMap(agent => [\n agent.serviceAccount?.actorId,\n agent.serviceAccount?.configuredActorId,\n agent.stateChangedBy,\n agent.shadow?.changedBy\n ]));\n }\n\n /** The run catalog, or why it could not be read; it never errors. */\n private readCatalog(): Observable<CatalogRead> {\n return this.admin.getRunCatalog().pipe(\n map(catalog => ({ catalog, error: null })),\n catchError((error: unknown) => of({ catalog: null, error: toNhAssistantError(error) })));\n }\n\n private applyCatalog(read: CatalogRead): void {\n this.catalog.set(read.catalog);\n this.catalogError.set(read.error);\n this.accountSearch.set(read.catalog?.accountSearch === true);\n }\n\n private focusAccount(): void {\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>('[data-account-form] input')?.focus(), { injector: this.injector });\n }\n\n /** Closes the open confirmation and change forms before another opens; one is open at a time. */\n private closeForms(): void {\n this.confirming.set(null);\n this.error.set(null);\n this.accountError.set(null);\n this.stateReason.set('');\n this.accountId.set('');\n this.changingState.set(null);\n this.changingShadow.set(null);\n this.changingAccount.set(null);\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 /**\n * Reloads the agents behind the visible list, for example their skills after the run\n * configuration changed; the list stays as it is when that fails.\n */\n private refreshAgents(): void {\n this.subscription?.unsubscribe();\n this.subscription = this.admin.getAgents().subscribe({\n next: agents => this.agents.set(agents),\n error: () => undefined\n });\n this.refreshChat();\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 shadow: state.shadow ?? agent.shadow,\n serviceAccount: state.serviceAccount === undefined ? agent.serviceAccount : state.serviceAccount\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 [catalog]=\"catalog()\"\n [catalogUnavailable]=\"catalogError() !== null\"\n (saved)=\"onEditorSaved($event)\"\n (workRequested)=\"onWorkRequested($event)\"\n (cancelled)=\"onEditorCancelled()\" />\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: (codeTextKeys(agent.source, agent.displayName) | nhAssistantTranslate: agent.displayName), id: agent.id } }}</p>\n <nh-assistant-agent-feedback-report [agentId]=\"agent.id\" />\n </div>\n} @else if (configuring(); as agent) {\n <div class=\"stack\">\n <div>\n <button #back class=\"secondary\" type=\"button\" (click)=\"closeRunConfiguration()\">\n {{ 'nh-assistant.admin.run-config.back' | translate }}\n </button>\n </div>\n <nh-assistant-agent-run-configuration\n [agent]=\"agent\"\n [startSetup]=\"setupOnOpen()\"\n [tools]=\"tools()\"\n [servers]=\"servers()\"\n (editAgent)=\"editFromRunConfiguration(agent)\"\n (openRuns)=\"runsFromRunConfiguration(agent)\"\n (changeAccount)=\"accountFromRunConfiguration(agent)\"\n (openMcpServers)=\"openMcpServers.emit()\" />\n </div>\n} @else if (viewingRuns(); as agent) {\n <div class=\"stack\">\n <div>\n <button #back class=\"secondary\" type=\"button\" (click)=\"closeRuns()\">\n {{ (returnTo() === agent.id ? 'nh-assistant.admin.runs.back-to-run-config' : 'nh-assistant.admin.runs.back') | translate }}\n </button>\n </div>\n <p class=\"muted\">{{ 'nh-assistant.admin.feedback.agent' | translate: { name: (codeTextKeys(agent.source, agent.displayName) | nhAssistantTranslate: agent.displayName), id: agent.id } }}</p>\n <nh-assistant-agent-run-history\n [agentId]=\"agent.id\"\n [subjectTypes]=\"catalog()?.subjectTypes ?? []\"\n (openConversation)=\"openConversation($event)\" />\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: (codeTextKeys(agent.source, agent.displayName) | nhAssistantTranslate: 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 @if (errorAgentId() === null) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n }\n @if (!loading() && !loadFailed()) {\n @if (catalogError(); as failure) {\n <!-- Without the run catalog nothing that depends on it is offered: run now, what agents work on, groups. -->\n <div class=\"message warning catalog-error\" role=\"alert\" data-catalog-error>\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">\n {{ 'nh-assistant.admin.agents.catalog-failed' | translate }}\n {{ catalogErrorKeys() | nhAssistantTranslate: failure.code }}\n </span>\n <button class=\"secondary\" type=\"button\" data-catalog-retry [disabled]=\"catalogLoading()\" (click)=\"retryCatalog()\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.retry' | translate }}\n </button>\n </div>\n }\n <nh-assistant-account-names-error [names]=\"accountNameLookup\" />\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 <!-- An agent in code names and describes itself with translation keys. -->\n <strong>{{ (codeTextKeys(agent.source, agent.displayName) | nhAssistantTranslate: 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 @if (agent.shadow?.shadow) {\n <span class=\"badge warning\" data-shadow-badge>{{ 'nh-assistant.admin.agents.shadow.badge' | translate }}</span>\n }\n @if (agent.offeredInChat === false) {\n <span class=\"badge\" data-hidden-from-chat>{{ 'nh-assistant.admin.agents.chat.hidden' | translate }}</span>\n }\n </div>\n @if (agent.description) {\n <p class=\"muted\">{{ codeTextKeys(agent.source, agent.description) | nhAssistantTranslate: agent.description }}</p>\n }\n <!-- A warning never refused the save: the agent is in effect but may not work as configured. -->\n @for (warning of agent.warnings ?? []; track warning) {\n <p class=\"message warning\" [attr.data-agent-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('agent', warning) | nhAssistantTranslate: warning }}\n </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 <span [attr.title]=\"accountTitle(agent.stateChangedBy)\">{{ 'nh-assistant.admin.agents.state.changed' | translate: { user: accountName(agent.stateChangedBy), date: (agent.stateChangedAt | date: 'medium') } }}</span>\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 @if (agent.runState === 'off') {\n <p class=\"muted\" data-off-hint>\n {{ 'nh-assistant.admin.agents.state.off-hint' | translate }}\n @if (!agent.stateChangedAt) {\n {{ 'nh-assistant.admin.agents.state.starts-off' | translate }}\n }\n </p>\n }\n }\n @if (agent.shadow; as shadow) {\n @if (shadow.shadow) {\n <p class=\"muted\">\n {{ (shadow.locked ? 'nh-assistant.admin.agents.shadow.locked' : 'nh-assistant.admin.agents.shadow.hint') | translate }}\n @if (shadow.changedAt && shadow.override !== null) {\n <span [attr.title]=\"accountTitle(shadow.changedBy)\">{{ 'nh-assistant.admin.agents.shadow.changed' | translate: { user: accountName(shadow.changedBy), date: (shadow.changedAt | date: 'medium') } }}</span>\n }\n @if (shadow.reason && shadow.override !== null) {\n {{ 'nh-assistant.admin.agents.state.reason' | translate: { reason: shadow.reason } }}\n }\n </p>\n }\n }\n @if (agent.serviceAccount; as account) {\n <p class=\"muted\" data-service-account>\n <span [attr.title]=\"accountTitle(account.actorId)\">{{ 'nh-assistant.admin.agents.service-account.label' | translate: { account: accountName(account.actorId) } }}</span>\n @if (account.overridden) {\n <span [attr.title]=\"accountTitle(account.configuredActorId)\">{{ 'nh-assistant.admin.agents.service-account.configured' | translate: { account: accountName(account.configuredActorId) } }}</span>\n @if (account.reason) {\n {{ 'nh-assistant.admin.agents.state.reason' | translate: { reason: account.reason } }}\n }\n }\n </p>\n }\n @if (worksOn(agent); as works) {\n <!-- What the agent works on; an agent in code shows its code setting. -->\n <p class=\"muted\" data-works-on>\n <span>{{ 'nh-assistant.admin.agents.works-on.label' | translate }}</span>\n <strong>\n @switch (works.only) {\n @case ('all') { {{ 'nh-assistant.admin.agents.works-on.all' | translate }} }\n @case ('types') { {{ works.types.join(', ') }} }\n @default { {{ 'nh-assistant.admin.agents.works-on.application' | translate }} }\n }\n </strong>\n @if (works.application && works.only !== 'application') {\n <span>{{ 'nh-assistant.admin.agents.works-on.and-application' | translate }}</span>\n }\n @if (works.perDivision) {\n <span>{{ 'nh-assistant.admin.agents.works-on.per-division' | translate }}</span>\n }\n @if (works.undeclared) {\n <span>{{ 'nh-assistant.admin.agents.works-on.undeclared' | translate }}</span>\n }\n </p>\n @if (works.all && works.known.length > 0) {\n <p class=\"muted\" data-known-types>{{ 'nh-assistant.admin.agents.works-on.known' | translate: { types: works.known.join(', ') } }}</p>\n }\n @if (works.runPolicy || works.viewPolicy) {\n <!-- Each policy is an item of its own, wrapping on narrow screens. -->\n <div class=\"meta\" data-works-on-policies>\n @if (works.runPolicy; as policy) {\n <span>{{ 'nh-assistant.admin.agents.works-on.run-policy' | translate: { policy: (policyKeys(policy) | nhAssistantTranslate: policy) } }}</span>\n }\n @if (works.viewPolicy; as policy) {\n <span>{{ 'nh-assistant.admin.agents.works-on.view-policy' | translate: { policy: (policyKeys(policy) | nhAssistantTranslate: policy) } }}</span>\n }\n </div>\n }\n }\n @if (groupNames(agent); as names) {\n <p class=\"muted\" data-agent-groups>{{ 'nh-assistant.admin.agents.groups' | translate: { groups: names } }}</p>\n }\n <div class=\"meta\">\n <span>{{ 'nh-assistant.admin.agents.autonomy.' + agent.autonomy | translate }}</span>\n <span>{{ (agent.toolSelectors.length === 1 ? 'nh-assistant.admin.agents.tool-count-one' : 'nh-assistant.admin.agents.tool-count') | translate: { count: agent.toolSelectors.length } }}</span>\n <span>{{ (agent.mcpServerIds.length === 1 ? 'nh-assistant.admin.agents.server-count-one' : '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; as policy) {\n <!-- The application may name its policies; otherwise the policy shows as it is called in code. -->\n <span data-required-policy>\n {{ 'nh-assistant.admin.agents.required-policy' | translate }}\n @if (policyKeys(policy) | nhAssistantTranslate; as text) {\n {{ text }}\n } @else {\n <code class=\"mono\">{{ policy }}</code>\n }\n </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.data-state-action]=\"action\"\n [attr.aria-expanded]=\"isChangingState(agent.id, action)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askState(agent, action)\">\n {{ stateKey('action', agent.runState, action) | translate }}\n </button>\n }\n @if (agent.runState !== 'configured-off') {\n @for (mode of shadowActions(agent.shadow); track mode) {\n <button\n class=\"secondary\"\n type=\"button\"\n [attr.data-shadow-action]=\"mode\"\n [attr.aria-expanded]=\"isChangingShadow(agent.id, mode)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askShadow(agent, mode)\">\n {{ shadowActionKey(agent, mode) | translate }}\n </button>\n }\n }\n @if (agent.serviceAccount; as account) {\n <button\n class=\"secondary\"\n type=\"button\"\n data-account-action=\"set\"\n [attr.aria-expanded]=\"isChangingAccount(agent.id, 'set')\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askAccount(agent, 'set')\">\n {{ 'nh-assistant.admin.agents.service-account.action.set' | translate }}\n </button>\n @if (account.overridden) {\n <button\n class=\"secondary\"\n type=\"button\"\n data-account-action=\"code\"\n [attr.aria-expanded]=\"isChangingAccount(agent.id, 'code')\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askAccount(agent, 'code')\">\n {{ 'nh-assistant.admin.agents.service-account.action.code' | translate }}\n </button>\n }\n }\n @if (hasRunConfiguration(agent)) {\n <button class=\"secondary\" type=\"button\" [attr.data-run-config-agent]=\"agent.id\" (click)=\"openRunConfiguration(agent)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.agents.run-config' | translate }}\n </button>\n }\n @if (hasRunConfiguration(agent)) {\n <button class=\"secondary\" type=\"button\" [attr.data-runs-agent]=\"agent.id\" (click)=\"openRuns(agent)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.agents.runs' | translate }}\n </button>\n }\n @if (canRunNow(agent)) {\n <button\n class=\"secondary\"\n type=\"button\"\n aria-haspopup=\"dialog\"\n [attr.data-run-now-agent]=\"agent.id\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"runNow(agent)\">\n <nh-assistant-icon name=\"send\" />{{ 'nh-assistant.admin.agents.run-now' | 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.cancel' | 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.cancel' | 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 <strong>{{ (skillNameKeys(agent.id, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) }}</strong>\n <span class=\"mono muted\">{{ 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 @if (skill.shadow?.shadow) {\n <span class=\"badge warning\" data-shadow-badge>{{ 'nh-assistant.admin.agents.shadow.badge' | translate }}</span>\n }\n </div>\n <p class=\"muted\">{{ skillDescriptionKeys(agent.id, skill.skillId) | nhAssistantTranslate: 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.data-state-action]=\"action\"\n [attr.aria-label]=\"(stateKey('action', skill.runState, action) | translate) + ' ' + (skillNameKeys(agent.id, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId))\"\n [attr.aria-expanded]=\"isChangingState(agent.id, action, skill.skillId)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askState(agent, action, skill)\">\n {{ stateKey('action', skill.runState, action) | translate }}\n </button>\n }\n @for (mode of shadowActions(skill.shadow); track mode) {\n <button\n class=\"secondary\"\n type=\"button\"\n [attr.data-shadow-action]=\"mode\"\n [attr.aria-label]=\"(shadowActionKey(agent, mode) | translate) + ' ' + (skillNameKeys(agent.id, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId))\"\n [attr.aria-expanded]=\"isChangingShadow(agent.id, mode, skill.skillId)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askShadow(agent, mode, skill)\">\n {{ shadowActionKey(agent, mode) | 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\">{{ skillStateExplainKey(change) | translate: { skill: (skillNameKeys(agent.id, change.skillId) | nhAssistantTranslate: readableId(change.skillId)) } }}</p>\n } @else {\n <p class=\"muted\">{{ stateKey('explain', change.from, change.state) | translate }}</p>\n }\n <div class=\"field\">\n <label [for]=\"id + '-' + agent.id + '-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input\n #reasonInput\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"id + '-' + agent.id + '-reason'\"\n [attr.aria-describedby]=\"id + '-' + agent.id + '-reason-hint'\"\n [maxLength]=\"maxReason\"\n [value]=\"stateReason()\"\n (input)=\"stateReason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-' + agent.id + '-reason-hint'\">{{ 'nh-assistant.admin.agents.state.note-hint' | translate }}</p>\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 {{ stateKey('confirm', change.from, change.state) | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"changingState.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n </div>\n </form>\n }\n }\n @if (changingShadow(); as change) {\n @if (change.agentId === agent.id) {\n <form class=\"stack\" data-shadow-form (submit)=\"$event.preventDefault(); applyShadow(agent)\">\n @if (change.skillId) {\n <p class=\"muted\">{{ shadowExplainKey(agent, change.mode, true) | translate: { skill: (skillNameKeys(agent.id, change.skillId) | nhAssistantTranslate: readableId(change.skillId)), mode: (ownShadowModeKey(agent, change.skillId) | translate) } }}</p>\n } @else {\n <p class=\"muted\">{{ shadowExplainKey(agent, change.mode, false) | translate: { mode: (ownShadowModeKey(agent) | translate) } }}</p>\n }\n <div class=\"field\">\n <label [for]=\"id + '-' + agent.id + '-shadow-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input\n #reasonInput\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"id + '-' + agent.id + '-shadow-reason'\"\n [attr.aria-describedby]=\"id + '-' + agent.id + '-shadow-reason-hint'\"\n [maxLength]=\"maxReason\"\n [value]=\"stateReason()\"\n (input)=\"stateReason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-' + agent.id + '-shadow-reason-hint'\">{{ 'nh-assistant.admin.agents.state.note-hint' | translate }}</p>\n </div>\n <div class=\"card-actions\">\n <button type=\"submit\" class=\"primary\" [disabled]=\"busyAgentId() !== null\">\n {{ 'nh-assistant.admin.agents.shadow.confirm.' + change.mode | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"changingShadow.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n </div>\n </form>\n }\n }\n @if (changingAccount(); as change) {\n @if (change.agentId === agent.id) {\n <form class=\"stack\" data-account-form (submit)=\"$event.preventDefault(); applyAccount(agent)\">\n <p class=\"muted\" [attr.title]=\"accountTitle(agent.serviceAccount?.configuredActorId)\">{{ 'nh-assistant.admin.agents.service-account.explain.' + change.mode | translate: { account: accountName(agent.serviceAccount?.configuredActorId) } }}</p>\n @if (change.mode === 'set') {\n <div class=\"field\">\n <label [for]=\"id + '-' + agent.id + '-account'\">{{ (accountSearch() ? 'nh-assistant.admin.agents.service-account.input-label-search' : 'nh-assistant.admin.agents.service-account.input-label') | translate }}</label>\n <nh-assistant-account-picker\n [inputId]=\"id + '-' + agent.id + '-account'\"\n [value]=\"accountId()\"\n [searchable]=\"accountSearch()\"\n [invalid]=\"accountError() !== null\"\n [describedBy]=\"accountError() ? id + '-' + agent.id + '-account-error' : null\"\n (valueChange)=\"onAccountChange($event)\" />\n @if (accountError(); as failure) {\n <p class=\"field-error\" data-account-error [id]=\"id + '-' + agent.id + '-account-error'\">\n <nh-assistant-icon name=\"warning\" />{{ accountErrorKeys() | nhAssistantTranslate: failure.code }}\n </p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-' + agent.id + '-account-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"id + '-' + agent.id + '-account-reason'\"\n [attr.aria-describedby]=\"id + '-' + agent.id + '-account-reason-hint'\"\n [maxLength]=\"maxReason\"\n [value]=\"stateReason()\"\n (input)=\"stateReason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-' + agent.id + '-account-reason-hint'\">{{ 'nh-assistant.admin.agents.state.note-hint' | translate }}</p>\n </div>\n <div class=\"card-actions\">\n <button type=\"submit\" class=\"primary\" [disabled]=\"busyAgentId() !== null\">\n {{ 'nh-assistant.admin.agents.service-account.confirm.' + change.mode | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"changingAccount.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n </div>\n </form>\n }\n }\n @if (error(); as failure) {\n @if (errorAgentId() === agent.id) {\n <p class=\"form-error\" role=\"alert\" data-agent-error><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n }\n </li>\n }\n </ul>\n }\n @if (runNowAgent(); as runAgent) {\n <nh-assistant-run-now-dialog\n [agent]=\"runAgent\"\n [subjectTypes]=\"catalog()?.subjectTypes ?? []\"\n [divisions]=\"catalog()?.divisions === true\"\n (openConversation)=\"openConversation($event)\"\n (closed)=\"runningNow.set(null)\" />\n }\n </section>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n afterNextRender,\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 AssistantDataClassification,\n McpAuthMode,\n McpBuiltInAuthMode,\n McpConnectionScope,\n McpCustomAuthMode,\n McpDiscovery,\n McpHeadlessUse,\n McpOAuthInput,\n McpServer,\n McpServerInput,\n McpTool,\n McpTransport,\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';\nimport { focusFirstInvalid } from '../agents/run-config/run-config-shared';\n\n/**\n * The longest values the server accepts per field of a server (`POST`/`PUT admin/mcp-servers`); the\n * editor's fields stop there.\n */\nconst NH_ASSISTANT_MCP_SERVER_LIMITS = {\n id: 40,\n displayName: 200,\n url: 2048,\n headerName: 128,\n secret: 2000,\n secretReference: 233,\n userName: 256,\n clientCertificateReference: 100,\n requiredPolicy: 256,\n scopes: 1024,\n clientId: 512,\n clientSecret: 2000,\n organizationAccountLabel: 200\n} as const;\n\n/** The fields of a server the server reports errors for, as the editor shows them. */\nconst serverFields = [\n 'id',\n 'displayName',\n 'url',\n 'authMode',\n 'headerName',\n 'secret',\n 'secretReference',\n 'userName',\n 'clientCertificateReference',\n 'transport',\n 'connectionScope',\n 'oauth.scopes',\n 'oauth.clientId',\n 'oauth.clientSecret',\n 'oauth.clientSecretReference',\n 'oauth.organizationAccountLabel',\n 'oauth.confirmAuthorization',\n 'requiredPolicy',\n 'headlessUse',\n 'readers'\n] as const;\n\n/** The fields of one reader the server reports errors for, as `readers[<index>].<field>`. */\nconst readerFieldPattern = /^readers\\[\\d+\\]\\.(mediaTypes|toolName|maxClassification|priority)$/;\n\n/** A header name the server accepts: 1 to 128 letters, digits and dashes. */\nconst headerNamePattern = /^[A-Za-z0-9-]{1,128}$/;\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. The editor offers no `clear`:\n * the API refuses a mode with a secret that has none, so a stored secret goes by choosing a reference\n * or a mode without a secret.\n */\nexport type NhAssistantSecretAction = 'keep' | 'replace' | 'clear';\n\n/** Where the secret is: stored here, encrypted, or a reference to a secret of the application. */\nexport type NhAssistantSecretSource = 'stored' | 'reference';\n\n/** `<prefix>:<name>` as the server accepts it; the name never climbs a path. */\nconst secretReferencePattern = /^[a-z][a-z0-9-]{0,31}:[A-Za-z0-9][A-Za-z0-9._/-]{0,199}$/;\nconst certificateNamePattern = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;\n/** Space-separated scope tokens: printable ASCII without quotes or backslashes (RFC 6749). */\nconst scopesPattern = /^[\\x21\\x23-\\x5B\\x5D-\\x7E]+( [\\x21\\x23-\\x5B\\x5D-\\x7E]+)*$/;\n/** A media type without parameters, as the server compares them (`type/subtype`). */\nconst mediaTypePattern = /^[a-z0-9][a-z0-9!#$&^_.+-]*\\/[a-z0-9][a-z0-9!#$&^_.+-]*$/;\n/** The most media types one reader reads. */\nconst maxReaderMediaTypes = 16;\n/** The most readers one server has. */\nconst maxReaders = 16;\n/** The priorities a reader can have; a higher one is asked first. */\nconst readerPriority = { min: -1000, max: 1000 } as const;\n\n/**\n * One reader as the editor shows it: the tool, the media types as typed (separated by commas, spaces\n * or new lines), the highest classification and the priority as typed. `key` keeps a row's controls\n * when another row is removed.\n */\nexport interface NhAssistantReaderDraft {\n key: number;\n toolName: string;\n mediaTypes: string;\n maxClassification: AssistantDataClassification | '';\n priority: string;\n}\n\n/** What is wrong with one reader before it is saved. */\ninterface ReaderProblems {\n types: boolean;\n tool: boolean;\n duplicate: boolean;\n classification: boolean;\n priority: boolean;\n}\n\nlet nextId = 0;\nlet nextReaderKey = 0;\n\n/**\n * Creates or edits one MCP server: the authentication with a write-only secret or a reference to\n * one, OAuth with discovery the administrator confirms, an optional client certificate, the\n * transport, the use in background runs and, for a server that exists, its readers: per reader the\n * synced tool that turns files into text, the media types it reads, the highest classification that\n * may be sent to it and its priority, with readers to add and remove. Every field stops at the length\n * the server accepts; a refused save shows each of the server's field errors at its field, those of a\n * reader at that reader (`readers[0].toolName`), for example a secret reference the application cannot\n * resolve (`not-found`), and moves the focus to the first of them.\n */\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 readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n private subscription?: Subscription;\n private discoverySubscription?: Subscription;\n private modesSubscription?: Subscription;\n private toolsSubscription?: Subscription;\n /** Fields whose server error the administrator changed since the refused save. */\n private readonly touched = signal<ReadonlySet<string>>(new Set());\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 limits = NH_ASSISTANT_MCP_SERVER_LIMITS;\n readonly builtInAuthModes: readonly McpBuiltInAuthMode[] = ['none', 'bearer', 'api-key', 'basic', 'forward-user-token', 'oauth', 'oauth-client-credentials'];\n /** The modes the application registered in code; none until they are loaded or when loading fails. */\n readonly customAuthModes = signal<readonly McpCustomAuthMode[]>([]);\n /** The built-in modes, the application's own and, kept selectable, a stored mode no longer registered. */\n readonly authModes = computed<readonly McpAuthMode[]>(() => {\n const modes: McpAuthMode[] = [...this.builtInAuthModes, ...this.customAuthModes().map(item => item.mode)];\n const stored = this.server()?.authMode;\n return stored && !modes.includes(stored) ? [...modes, stored] : modes;\n });\n readonly transports: readonly McpTransport[] = ['streamable-http', 'auto'];\n readonly secretSources: readonly NhAssistantSecretSource[] = ['stored', 'reference'];\n readonly connectionScopes: readonly McpConnectionScope[] = ['organization', 'user'];\n readonly classifications: readonly AssistantDataClassification[] = ['public', 'internal', 'confidential', 'restricted'];\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 headlessUse = signal<McpHeadlessUse>('never');\n readonly userName = signal('');\n readonly secretSource = signal<NhAssistantSecretSource>('stored');\n readonly secretReference = signal('');\n readonly clientCertificateReference = signal('');\n readonly transport = signal<McpTransport>('streamable-http');\n readonly secretAction = signal<NhAssistantSecretAction>('keep');\n /** The new secret while typing. Never filled from the server. */\n readonly secret = signal('');\n readonly connectionScope = signal<McpConnectionScope>('organization');\n readonly oauthClientId = signal('');\n readonly oauthScopes = signal('');\n readonly organizationAccountLabel = signal('');\n readonly oauthSecretSource = signal<NhAssistantSecretSource>('stored');\n readonly oauthSecretReference = signal('');\n readonly oauthSecretAction = signal<NhAssistantSecretAction>('keep');\n /** The new client secret while typing. Never filled from the server. */\n readonly oauthSecret = signal('');\n /** What discovery found for the address; the administrator confirms it on save. */\n readonly discovery = signal<McpDiscovery | null>(null);\n readonly discovering = signal(false);\n readonly discoveryError = signal<NhAssistantError | null>(null);\n readonly confirmAuthorization = signal(false);\n /** The readers of the server as the editor shows them, in their order. */\n readonly readers = signal<readonly NhAssistantReaderDraft[]>([]);\n readonly maxReaders = maxReaders;\n readonly readerPriority = readerPriority;\n /** The server's synced tools, which can read files; empty until they are loaded. */\n readonly readerTools = signal<readonly McpTool[]>([]);\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 /** A stored secret that a save keeps; a reference replaces it. */\n readonly hasSecret = computed(() => this.server()?.hasSecret === true);\n /** The server's own secret; OAuth modes have a client secret instead. */\n readonly usesSecret = computed(() => this.authMode() === 'bearer' || this.authMode() === 'api-key' || this.authMode() === 'basic');\n readonly usesReference = computed(() => this.usesSecret() && this.secretSource() === 'reference');\n /**\n * The organization's credential may serve background runs; a forwarded user token only as the\n * short-lived token of the person a run acts for, after that person allowed it.\n */\n readonly headlessUses = computed<readonly McpHeadlessUse[]>(() =>\n this.personalCredential() ? ['never', 'personal'] : ['never', 'organization']);\n readonly isOAuth = computed(() => this.authMode() === 'oauth' || this.authMode() === 'oauth-client-credentials');\n readonly isClientCredentials = computed(() => this.authMode() === 'oauth-client-credentials');\n /** One authorization of the organization's account that everyone uses. */\n readonly isOrganizationOAuth = computed(() => this.authMode() === 'oauth' && this.connectionScope() === 'organization');\n /** Whose credential the application's own mode sends; null for a built-in mode. */\n readonly customOwnership = computed(() =>\n this.customAuthModes().find(item => item.mode === this.authMode())?.ownership ?? null);\n /**\n * The server runs with each person's own account: a forwarded sign-in, a personal OAuth connection\n * or a mode of the application that sends a person's credential.\n */\n readonly personalCredential = computed(() =>\n this.authMode() === 'forward-user-token' || (this.authMode() === 'oauth' && this.connectionScope() === 'user') ||\n this.customOwnership() === 'person');\n readonly hasOAuthSecret = computed(() => this.server()?.oauth?.hasClientSecret === true);\n readonly usesOAuthReference = computed(() => this.isOAuth() && this.oauthSecretSource() === 'reference');\n readonly showOAuthSecretInput = computed(() => this.isOAuth() && !this.usesOAuthReference() &&\n (!this.hasOAuthSecret() || this.oauthSecretAction() === 'replace'));\n /**\n * The confirmed authorization server stays valid while the address and the OAuth use stay; a new\n * server, a new address or a switch to OAuth needs discovery and the administrator's confirmation.\n */\n readonly needsConfirmation = computed(() => {\n const server = this.server();\n return this.isOAuth() && (server === null || server.authorization === null ||\n server.url !== this.url().trim() || (server.authMode !== 'oauth' && server.authMode !== 'oauth-client-credentials'));\n });\n readonly pkceMissing = computed(() => this.authMode() === 'oauth' && this.discovery()?.pkceSupported === false);\n readonly confirmMissing = computed(() => this.needsConfirmation() && (!this.confirmAuthorization() || this.discovery() === null));\n readonly scopesInvalid = computed(() => {\n const scopes = this.oauthScopes().trim();\n return scopes.length > 1_024 || (scopes.length > 0 && !scopesPattern.test(scopes));\n });\n readonly clientIdMissing = computed(() => this.isClientCredentials() && this.oauthClientId().trim().length === 0);\n readonly labelMissing = computed(() => this.isOrganizationOAuth() &&\n (this.organizationAccountLabel().trim().length === 0 || this.organizationAccountLabel().length > 200));\n readonly oauthReferenceInvalid = computed(() => this.usesOAuthReference() && !isSecretReference(this.oauthSecretReference().trim()));\n /** The registration discovery offers when no client id is entered. */\n readonly registration = computed(() => {\n const found = this.discovery();\n if (!found) {\n return null;\n }\n return found.clientIdMetadataDocumentSupported ? 'metadata-document' : found.dynamicRegistrationSupported ? 'dynamic' : 'manual';\n });\n readonly effectiveHeadlessUse = computed(() => this.headlessUses().includes(this.headlessUse()) ? this.headlessUse() : 'never');\n readonly showSecretInput = computed(() => this.usesSecret() && !this.usesReference() && (!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 userNameInvalid = computed(() => this.authMode() === 'basic' &&\n (this.userName().trim().length === 0 || this.userName().length > 256 || this.userName().includes(':')));\n readonly secretReferenceInvalid = computed(() => this.usesReference() && !isSecretReference(this.secretReference().trim()));\n readonly certificateInvalid = computed(() => {\n const name = this.clientCertificateReference().trim();\n return name.length > 0 && !certificateNamePattern.test(name);\n });\n readonly oauthInvalid = computed(() => this.isOAuth() && (this.confirmMissing() || this.pkceMissing() || this.scopesInvalid() ||\n this.clientIdMissing() || this.labelMissing() || this.oauthReferenceInvalid()));\n readonly headerNameInvalid = computed(() => {\n const header = this.headerName().trim();\n return this.authMode() === 'api-key' && header.length > 0 && !headerNamePattern.test(header);\n });\n /** The tool names to choose from, keeping the stored tools the list no longer holds selectable. */\n readonly readerToolNames = computed(() => {\n const names = this.readerTools().map(tool => tool.remoteName);\n const stored = (this.server()?.readers ?? []).map(reader => reader.toolName).filter(name => !names.includes(name));\n return [...names, ...stored];\n });\n /** What is wrong with each reader, in the order of `readers`. */\n readonly readerProblems = computed<readonly ReaderProblems[]>(() => {\n const seen = new Set<string>();\n return this.readers().map(reader => {\n const types = splitMediaTypes(reader.mediaTypes);\n const duplicate = reader.toolName.length > 0 && seen.has(reader.toolName);\n seen.add(reader.toolName);\n return {\n types: types.length === 0 || types.some(type => !isMediaType(type)) ||\n new Set(types.map(type => type.split(';')[0].trim().toLowerCase())).size > maxReaderMediaTypes,\n tool: reader.toolName.length === 0,\n duplicate,\n classification: reader.maxClassification === '',\n priority: parsePriority(reader.priority) === null\n };\n });\n });\n /** Why a reader can or cannot be added: the server's tools are not synced, or it has the most. */\n readonly readerAddHint = computed(() => this.readerToolNames().length === 0\n ? 'nh-assistant.admin.server-editor.reader.tool-sync'\n : this.readers().length >= maxReaders\n ? 'nh-assistant.admin.server-editor.reader.limit'\n : 'nh-assistant.admin.server-editor.reader.add-hint');\n readonly readerInvalid = computed(() => this.readerProblems().some(problems =>\n problems.types || problems.tool || problems.duplicate || problems.classification || problems.priority));\n readonly valid = computed(() => !this.idInvalid() && !this.nameMissing() && !this.urlInvalid() && !this.headerNameInvalid() &&\n !this.userNameInvalid() && !this.secretReferenceInvalid() && !this.certificateInvalid() && !this.oauthInvalid() &&\n !this.readerInvalid());\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n /** The server's first error per field of the refused save, until the administrator changes the field. */\n readonly serverErrors = computed<Readonly<Record<string, string>>>(() => {\n const touched = this.touched();\n const errors: Record<string, string> = {};\n for (const [field, values] of Object.entries(this.error()?.fieldErrors ?? {})) {\n if (values.length > 0 && !touched.has(field)) {\n errors[field] = values[0];\n }\n }\n return errors;\n });\n /** Field errors of fields the editor does not show, listed with the form's error. */\n readonly otherServerErrors = computed(() => Object.entries(this.serverErrors())\n .filter(([field]) => !(serverFields as readonly string[]).includes(field) && !this.showsReaderField(field))\n .map(([field, value]) => ({ field, keys: this.valueKeys(value) })));\n readonly discoveryErrorKeys = computed(() => nhAssistantErrorKeys(this.discoveryError()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.discoverySubscription?.unsubscribe();\n this.modesSubscription?.unsubscribe();\n this.toolsSubscription?.unsubscribe();\n });\n // The application's own modes; without them the editor offers the built-in modes.\n this.modesSubscription = this.admin.getMcpAuthModes().subscribe({\n next: modes => this.customAuthModes.set(modes),\n error: () => this.customAuthModes.set([])\n });\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 /** Whether the server refused the field in the last save. */\n serverInvalid(field: string): boolean {\n return this.serverErrors()[field] !== undefined;\n }\n\n /** The text of the server's error of a field: the text of its value, then the generic text. */\n serverErrorKeys(field: string): string[] {\n const value = this.serverErrors()[field];\n return value ? this.valueKeys(value) : [];\n }\n\n /** The id of a field's error, for `aria-describedby`. */\n errorId(field: string): string {\n return `${this.id}-${field.replace(/[^A-Za-z0-9-]+/g, '-')}-error`;\n }\n\n /** The name of a reader's field in the server's errors, such as `readers[0].toolName`. */\n readerField(index: number, field: 'mediaTypes' | 'toolName' | 'maxClassification' | 'priority'): string {\n return `readers[${index}].${field}`;\n }\n\n /** Adds an empty reader at the end, at priority 0, and moves the focus to its tool. */\n addReader(): void {\n if (this.readers().length >= maxReaders) {\n return;\n }\n this.forgetReaderErrors();\n const key = nextReaderKey++;\n this.readers.set([...this.readers(), { key, toolName: '', mediaTypes: '', maxClassification: '', priority: '0' }]);\n this.focusById(`${this.id}-reader-tool-${key}`);\n }\n\n /**\n * Removes a reader and moves the focus to the button that adds one; the server's errors of the\n * readers no longer match their positions.\n */\n removeReader(index: number): void {\n this.forgetReaderErrors();\n this.readers.set(this.readers().filter((_, position) => position !== index));\n this.focusById(`${this.id}-reader-add`);\n }\n\n /** Changes one field of a reader as the administrator typed or chose it. */\n updateReader(index: number, field: 'toolName' | 'mediaTypes' | 'maxClassification' | 'priority', value: string): void {\n // The classification comes from the select's options, the empty choice included.\n this.readers.set(this.readers().map((reader, position) =>\n position === index ? { ...reader, [field]: value } as NhAssistantReaderDraft : reader));\n this.touch(this.readerField(index, field));\n }\n\n /** The ids a control describes itself with: its hint and, while the server refused it, its error. */\n describedBy(hintId: string | null, field: string): string | null {\n const ids = [hintId, this.serverInvalid(field) ? this.errorId(field) : null].filter((id): id is string => id !== null);\n return ids.length > 0 ? ids.join(' ') : null;\n }\n\n /** The administrator changed a field; its server error no longer applies. */\n touch(field: string): void {\n if (this.serverErrors()[field] !== undefined) {\n this.touched.set(new Set([...this.touched(), field]));\n }\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 setSecretSource(source: NhAssistantSecretSource): void {\n this.secretSource.set(source);\n this.secret.set('');\n this.secretAction.set('keep');\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 /** A new address makes earlier discovery meaningless. */\n onUrlInput(event: Event): void {\n this.url.set(this.value(event));\n this.discoverySubscription?.unsubscribe();\n this.discovering.set(false);\n this.discovery.set(null);\n this.confirmAuthorization.set(false);\n }\n\n setOAuthSecretSource(source: NhAssistantSecretSource): void {\n this.oauthSecretSource.set(source);\n this.oauthSecret.set('');\n this.oauthSecretAction.set('keep');\n }\n\n onOAuthSecretInput(event: Event): void {\n this.oauthSecret.set(this.value(event));\n if (!this.hasOAuthSecret()) {\n this.oauthSecretAction.set(this.oauthSecret().length > 0 ? 'replace' : 'keep');\n }\n }\n\n /** Reads the authorization of the address; the administrator confirms what it found. */\n discover(): void {\n if (this.urlInvalid() || this.discovering()) {\n return;\n }\n this.discovering.set(true);\n this.discovery.set(null);\n this.discoveryError.set(null);\n this.confirmAuthorization.set(false);\n this.discoverySubscription?.unsubscribe();\n this.discoverySubscription = this.admin.discoverMcpServer(this.url().trim()).subscribe({\n next: discovery => {\n this.discovering.set(false);\n this.discovery.set(discovery);\n if (this.oauthScopes().trim().length === 0 && discovery.challengedScopes.length > 0) {\n // The scopes the server asked for are a starting point the administrator can narrow.\n this.oauthScopes.set(discovery.challengedScopes.join(' '));\n }\n },\n error: (error: unknown) => {\n this.discovering.set(false);\n this.discoveryError.set(toNhAssistantError(error));\n }\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 headlessUse: this.effectiveHeadlessUse(),\n transport: this.transport(),\n // \"\" clears the certificate; the server ignores the user name outside basic authentication.\n clientCertificateReference: this.clientCertificateReference().trim(),\n userName: authMode === 'basic' ? this.userName().trim() : null\n };\n\n // Write-only secret: omitted keeps the stored value, \"\" clears it. A reference and a stored\n // secret exclude each other: sending one replaces the other.\n const action = this.secretAction();\n const storedReference = this.server()?.secretReference ?? null;\n if (this.usesReference()) {\n input.secretReference = this.secretReference().trim();\n } else if (!this.usesSecret()) {\n if (this.hasSecret()) {\n input.secret = '';\n }\n if (storedReference !== null) {\n input.secretReference = '';\n }\n } else {\n if (storedReference !== null) {\n input.secretReference = '';\n }\n if (action === 'clear') {\n input.secret = '';\n } else if (action === 'replace' && this.secret().length > 0) {\n input.secret = this.secret();\n }\n }\n if (this.isOAuth()) {\n input.connectionScope = authMode === 'oauth' ? this.connectionScope() : 'organization';\n input.oauth = this.oauthInput();\n }\n if (!this.isNew()) {\n // Every save sends the readers as shown; none removes them all.\n input.readers = this.readers().map(reader => ({\n mediaTypes: splitMediaTypes(reader.mediaTypes),\n toolName: reader.toolName,\n maxClassification: reader.maxClassification || null,\n priority: parsePriority(reader.priority) ?? 0\n }));\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.touched.set(new Set());\n this.subscription?.unsubscribe();\n this.subscription = request.subscribe({\n next: server => {\n this.saving.set(false);\n this.secret.set('');\n this.oauthSecret.set('');\n this.saved.emit(server);\n },\n error: (error: unknown) => {\n this.saving.set(false);\n this.error.set(toNhAssistantError(error));\n this.focusFirstInvalid();\n }\n });\n }\n\n private focusFirstInvalid(): void {\n afterNextRender(() => focusFirstInvalid(this.host.nativeElement.querySelector('form')), { injector: this.injector });\n }\n\n private focusById(id: string): void {\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>(`[id=\"${id}\"]`)?.focus(), { injector: this.injector });\n }\n\n private valueKeys(value: string): string[] {\n return [`nh-assistant.admin.run-config.field-errors.${value}`, 'nh-assistant.errors.generic'];\n }\n\n /** Whether the editor shows a field error at a reader's own field. */\n private showsReaderField(field: string): boolean {\n const match = /^readers\\[(\\d+)\\]\\./.exec(field);\n return match !== null && readerFieldPattern.test(field) && Number(match[1]) < this.readers().length;\n }\n\n /** The server's errors of the readers no longer apply once a reader is added or removed. */\n private forgetReaderErrors(): void {\n const readerFields = Object.keys(this.serverErrors()).filter(field => field.startsWith('readers'));\n if (readerFields.length > 0) {\n this.touched.set(new Set([...this.touched(), ...readerFields]));\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.headlessUse.set(server?.headlessUse ?? 'never');\n this.userName.set(server?.userName ?? '');\n this.secretSource.set(server?.secretReference ? 'reference' : 'stored');\n this.secretReference.set(server?.secretReference ?? '');\n this.clientCertificateReference.set(server?.clientCertificateReference ?? '');\n this.transport.set(server?.transport ?? 'streamable-http');\n this.secretAction.set('keep');\n this.secret.set('');\n this.connectionScope.set(server?.connectionScope ?? 'organization');\n this.oauthClientId.set(server?.oauth?.clientId ?? '');\n this.oauthScopes.set(server?.oauth?.scopes ?? '');\n this.organizationAccountLabel.set(server?.oauth?.organizationAccountLabel ?? '');\n this.oauthSecretSource.set(server?.oauth?.clientSecretReference ? 'reference' : 'stored');\n this.oauthSecretReference.set(server?.oauth?.clientSecretReference ?? '');\n this.oauthSecretAction.set('keep');\n this.oauthSecret.set('');\n this.discoverySubscription?.unsubscribe();\n this.discovering.set(false);\n this.discovery.set(null);\n this.discoveryError.set(null);\n this.confirmAuthorization.set(false);\n this.readers.set((server?.readers ?? []).map(reader => ({\n key: nextReaderKey++,\n toolName: reader.toolName,\n mediaTypes: reader.mediaTypes.join(', '),\n maxClassification: reader.maxClassification,\n priority: String(reader.priority)\n })));\n this.loadReaderTools(server);\n this.submitted.set(false);\n this.error.set(null);\n this.touched.set(new Set());\n }\n\n /** The synced tools of an existing server, to choose the reading tool from. */\n private loadReaderTools(server: McpServer | null): void {\n this.toolsSubscription?.unsubscribe();\n this.readerTools.set([]);\n if (server === null) {\n return;\n }\n this.toolsSubscription = this.admin.getMcpTools(server.id).subscribe({\n next: tools => this.readerTools.set(tools),\n error: () => this.readerTools.set([])\n });\n }\n\n /**\n * The OAuth settings as the editor shows them: every value is sent, so an emptied field clears the\n * stored value. The client secret is write-only: sent only when replaced.\n */\n private oauthInput(): McpOAuthInput {\n const storedReference = this.server()?.oauth?.clientSecretReference ?? null;\n const input: McpOAuthInput = {\n clientId: this.oauthClientId().trim(),\n scopes: this.oauthScopes().trim(),\n organizationAccountLabel: this.isOrganizationOAuth() ? this.organizationAccountLabel().trim() : '',\n // Required when the address is new or changed; otherwise it pins what was read again.\n confirmAuthorization: this.discovery() !== null && this.confirmAuthorization()\n };\n if (this.usesOAuthReference()) {\n input.clientSecretReference = this.oauthSecretReference().trim();\n } else {\n if (storedReference !== null) {\n input.clientSecretReference = '';\n }\n if (this.oauthSecretAction() === 'replace' && this.oauthSecret().length > 0) {\n input.clientSecret = this.oauthSecret();\n }\n }\n return input;\n }\n}\n\nfunction isSecretReference(value: string): boolean {\n return secretReferencePattern.test(value) && !value.includes('..');\n}\n\n/** The media types an administrator typed, separated by commas, spaces or new lines. */\nfunction splitMediaTypes(value: string): string[] {\n return value.split(/[\\s,]+/).map(item => item.trim()).filter(item => item.length > 0);\n}\n\n/**\n * The priority a reader's field holds: a whole number from -1000 to 1000, empty for 0, or `null` when\n * the server would refuse it.\n */\nfunction parsePriority(value: string): number | null {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n return 0;\n }\n const priority = Number(trimmed);\n return Number.isInteger(priority) && priority >= readerPriority.min && priority <= readerPriority.max ? priority : null;\n}\n\n/** Whether a value is a media type the server accepts: `type/subtype`, optionally with parameters. */\nfunction isMediaType(value: string): boolean {\n const essence = value.split(';')[0].trim().toLowerCase();\n return essence.length <= 128 && mediaTypePattern.test(essence);\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 [maxLength]=\"limits.id\"\n [value]=\"serverId()\"\n [disabled]=\"!isNew()\"\n [attr.aria-describedby]=\"describedBy(id + '-id-hint', 'id')\"\n [attr.aria-invalid]=\"(submitted() && idInvalid()) || serverInvalid('id') ? true : null\"\n (input)=\"serverId.set(value($event)); touch('id')\" />\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 @if (serverInvalid('id')) {\n <p class=\"field-error\" [id]=\"errorId('id')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('id') | nhAssistantTranslate }}</p>\n }\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 [maxLength]=\"limits.displayName\"\n [value]=\"displayName()\"\n [attr.aria-invalid]=\"(submitted() && nameMissing()) || serverInvalid('displayName') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-name-hint', 'displayName')\"\n (input)=\"displayName.set(value($event)); touch('displayName')\" />\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 @if (serverInvalid('displayName')) {\n <p class=\"field-error\" [id]=\"errorId('displayName')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('displayName') | nhAssistantTranslate }}</p>\n }\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 [maxLength]=\"limits.url\"\n [value]=\"url()\"\n [attr.aria-describedby]=\"describedBy(id + '-url-hint', 'url')\"\n [attr.aria-invalid]=\"(submitted() && urlInvalid()) || serverInvalid('url') ? true : null\"\n (input)=\"onUrlInput($event); touch('url')\" />\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 @if (serverInvalid('url')) {\n <p class=\"field-error\" [id]=\"errorId('url')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('url') | nhAssistantTranslate }}</p>\n }\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\n [id]=\"id + '-auth'\"\n [attr.aria-describedby]=\"describedBy(null, 'authMode')\"\n [attr.aria-invalid]=\"serverInvalid('authMode') ? true : null\"\n (change)=\"authMode.set($any(value($event))); touch('authMode')\">\n @for (mode of authModes(); track mode) {\n <option [value]=\"mode\" [selected]=\"authMode() === mode\">{{ ['nh-assistant.admin.mcp.auth.' + mode] | nhAssistantTranslate: mode }}</option>\n }\n </select>\n @if (customOwnership(); as ownership) {\n <p class=\"hint\" data-custom-auth-mode>{{ 'nh-assistant.admin.server-editor.custom-auth.' + ownership | translate }}</p>\n }\n @if (serverInvalid('authMode')) {\n <p class=\"field-error\" [id]=\"errorId('authMode')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('authMode') | nhAssistantTranslate }}</p>\n }\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 [maxLength]=\"limits.headerName\"\n [value]=\"headerName()\"\n [attr.aria-describedby]=\"describedBy(id + '-header-hint', 'headerName')\"\n [attr.aria-invalid]=\"(submitted() && headerNameInvalid()) || serverInvalid('headerName') ? true : null\"\n (input)=\"headerName.set(value($event)); touch('headerName')\" />\n <p class=\"hint\" [id]=\"id + '-header-hint'\">\n <span [class.error-text]=\"submitted() && headerNameInvalid()\">\n {{ (submitted() && headerNameInvalid() ? 'nh-assistant.admin.server-editor.header-name-invalid' : 'nh-assistant.admin.server-editor.header-name-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('headerName')) {\n <p class=\"field-error\" [id]=\"errorId('headerName')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('headerName') | nhAssistantTranslate }}</p>\n }\n </div>\n }\n\n @if (authMode() === 'basic') {\n <div class=\"field\">\n <label [for]=\"id + '-user'\">{{ 'nh-assistant.admin.server-editor.user-name' | translate }}</label>\n <input\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [id]=\"id + '-user'\"\n [maxLength]=\"limits.userName\"\n [value]=\"userName()\"\n [attr.aria-describedby]=\"describedBy(id + '-user-hint', 'userName')\"\n [attr.aria-invalid]=\"(submitted() && userNameInvalid()) || serverInvalid('userName') ? true : null\"\n (input)=\"userName.set(value($event)); touch('userName')\" />\n <p class=\"hint\" [id]=\"id + '-user-hint'\">\n <span [class.error-text]=\"submitted() && userNameInvalid()\">\n {{ (submitted() && userNameInvalid() ? 'nh-assistant.admin.server-editor.user-name-invalid' : 'nh-assistant.admin.server-editor.user-name-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('userName')) {\n <p class=\"field-error\" [id]=\"errorId('userName')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('userName') | nhAssistantTranslate }}</p>\n }\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 (isOAuth()) {\n <fieldset class=\"field\">\n <legend>OAuth</legend>\n\n @if (authMode() === 'oauth') {\n <div\n class=\"inline\"\n role=\"radiogroup\"\n [attr.aria-label]=\"'nh-assistant.admin.server-editor.connection-scope' | translate\"\n [attr.aria-describedby]=\"describedBy(id + '-scope-hint', 'connectionScope')\">\n @for (scope of connectionScopes; track scope) {\n <label class=\"check\">\n <input\n type=\"radio\"\n [name]=\"id + '-connection-scope'\"\n [value]=\"scope\"\n [checked]=\"connectionScope() === scope\"\n [attr.aria-invalid]=\"serverInvalid('connectionScope') ? true : null\"\n (change)=\"connectionScope.set(scope); touch('connectionScope')\" />\n <span>{{ 'nh-assistant.admin.mcp.connection-scope.' + scope | translate }}</span>\n </label>\n }\n </div>\n <p class=\"hint\" [id]=\"id + '-scope-hint'\">{{ 'nh-assistant.admin.server-editor.connection-scope-hint' | translate }}</p>\n @if (serverInvalid('connectionScope')) {\n <p class=\"field-error\" [id]=\"errorId('connectionScope')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('connectionScope') | nhAssistantTranslate }}</p>\n }\n }\n\n @if (isOrganizationOAuth()) {\n <p class=\"message warning\" role=\"note\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.oauth-warning' | translate }}</p>\n <label [for]=\"id + '-account-label'\">{{ 'nh-assistant.admin.server-editor.organization-account-label' | translate }}</label>\n <input\n type=\"text\"\n [id]=\"id + '-account-label'\"\n [maxLength]=\"limits.organizationAccountLabel\"\n [value]=\"organizationAccountLabel()\"\n [attr.aria-describedby]=\"describedBy(id + '-account-label-hint', 'oauth.organizationAccountLabel')\"\n [attr.aria-invalid]=\"(submitted() && labelMissing()) || serverInvalid('oauth.organizationAccountLabel') ? true : null\"\n (input)=\"organizationAccountLabel.set(value($event)); touch('oauth.organizationAccountLabel')\" />\n <p class=\"hint\" [id]=\"id + '-account-label-hint'\">\n <span [class.error-text]=\"submitted() && labelMissing()\">\n {{ (submitted() && labelMissing() ? 'nh-assistant.admin.server-editor.organization-account-label-required' : 'nh-assistant.admin.server-editor.organization-account-label-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('oauth.organizationAccountLabel')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.organizationAccountLabel')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.organizationAccountLabel') | nhAssistantTranslate }}</p>\n }\n }\n\n <div class=\"meta\">\n @if (server()?.authorization; as confirmed) {\n @if (!needsConfirmation()) {\n <span class=\"badge success\">{{ 'nh-assistant.admin.server-editor.confirmed-authorization' | translate: { issuer: confirmed.issuer } }}</span>\n }\n }\n <button class=\"secondary\" type=\"button\" [disabled]=\"discovering() || urlInvalid()\" (click)=\"discover()\">\n <nh-assistant-icon name=\"link\" />{{ (discovering() ? 'nh-assistant.admin.server-editor.discovering' : 'nh-assistant.admin.server-editor.discover') | translate }}\n </button>\n </div>\n @if (discoveryError(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ discoveryErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n @if (discovery(); as found) {\n <div class=\"discovery\" role=\"group\" [attr.aria-label]=\"'nh-assistant.admin.server-editor.discovery-title' | translate\">\n <dl>\n <dt>{{ 'nh-assistant.admin.server-editor.discovery-issuer' | translate }}</dt>\n <dd class=\"mono\">{{ found.issuer }}</dd>\n <dt>{{ 'nh-assistant.admin.server-editor.discovery-resource' | translate }}</dt>\n <dd class=\"mono\">{{ found.resource }}</dd>\n @if (found.scopesSupported.length > 0) {\n <dt>{{ 'nh-assistant.admin.server-editor.discovery-scopes' | translate }}</dt>\n <dd class=\"mono\">{{ found.scopesSupported.join(' ') }}</dd>\n }\n @if (authMode() === 'oauth' && registration(); as kind) {\n <dt>{{ 'nh-assistant.admin.server-editor.discovery-registration' | translate }}</dt>\n <dd>{{ 'nh-assistant.admin.server-editor.registration-' + kind | translate }}</dd>\n }\n </dl>\n @if (pkceMissing()) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.pkce-missing' | translate }}</p>\n } @else {\n <label class=\"check\">\n <input\n type=\"checkbox\"\n [checked]=\"confirmAuthorization()\"\n [attr.aria-describedby]=\"describedBy(id + '-confirm-hint', 'oauth.confirmAuthorization')\"\n [attr.aria-invalid]=\"serverInvalid('oauth.confirmAuthorization') ? true : null\"\n (change)=\"confirmAuthorization.set(checked($event)); touch('oauth.confirmAuthorization')\" />\n <span>{{ 'nh-assistant.admin.server-editor.confirm-authorization' | translate }}</span>\n </label>\n <p class=\"hint\" [id]=\"id + '-confirm-hint'\">{{ 'nh-assistant.admin.server-editor.confirm-authorization-hint' | translate }}</p>\n }\n </div>\n }\n @if (submitted() && confirmMissing()) {\n <p class=\"hint\"><span class=\"error-text\">{{ 'nh-assistant.admin.server-editor.confirm-required' | translate }}</span></p>\n } @else if (serverInvalid('oauth.confirmAuthorization')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.confirmAuthorization')\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.confirm-required' | translate }}</p>\n }\n\n <label [for]=\"id + '-scopes'\">{{ 'nh-assistant.admin.server-editor.scopes' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n [id]=\"id + '-scopes'\"\n [maxLength]=\"limits.scopes\"\n [value]=\"oauthScopes()\"\n [attr.aria-describedby]=\"describedBy(id + '-scopes-hint', 'oauth.scopes')\"\n [attr.aria-invalid]=\"(submitted() && scopesInvalid()) || serverInvalid('oauth.scopes') ? true : null\"\n (input)=\"oauthScopes.set(value($event)); touch('oauth.scopes')\" />\n <p class=\"hint\" [id]=\"id + '-scopes-hint'\">\n <span [class.error-text]=\"submitted() && scopesInvalid()\">\n {{ (submitted() && scopesInvalid() ? 'nh-assistant.admin.server-editor.scopes-invalid' : 'nh-assistant.admin.server-editor.scopes-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('oauth.scopes')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.scopes')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.scopes') | nhAssistantTranslate }}</p>\n }\n\n <label [for]=\"id + '-client-id'\">{{ 'nh-assistant.admin.server-editor.client-id' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n [id]=\"id + '-client-id'\"\n [maxLength]=\"limits.clientId\"\n [value]=\"oauthClientId()\"\n [attr.aria-describedby]=\"describedBy(id + '-client-id-hint', 'oauth.clientId')\"\n [attr.aria-invalid]=\"(submitted() && clientIdMissing()) || serverInvalid('oauth.clientId') ? true : null\"\n (input)=\"oauthClientId.set(value($event)); touch('oauth.clientId')\" />\n <p class=\"hint\" [id]=\"id + '-client-id-hint'\">\n <span [class.error-text]=\"submitted() && clientIdMissing()\">\n {{ (submitted() && clientIdMissing() ? 'nh-assistant.admin.server-editor.client-id-required' : 'nh-assistant.admin.server-editor.client-id-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('oauth.clientId')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.clientId')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.clientId') | nhAssistantTranslate }}</p>\n }\n\n @if (oauthClientId().trim().length > 0) {\n <div class=\"inline\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.server-editor.client-secret' | translate\">\n @for (source of secretSources; track source) {\n <label class=\"check\">\n <input\n type=\"radio\"\n [name]=\"id + '-oauth-secret-source'\"\n [value]=\"source\"\n [checked]=\"oauthSecretSource() === source\"\n (change)=\"setOAuthSecretSource(source)\" />\n <span>{{ 'nh-assistant.admin.server-editor.secret-source-' + source | translate }}</span>\n </label>\n }\n </div>\n @if (usesOAuthReference()) {\n <label [for]=\"id + '-oauth-reference'\">{{ 'nh-assistant.admin.server-editor.client-secret-reference' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n placeholder=\"config:planning-client-secret\"\n [id]=\"id + '-oauth-reference'\"\n [maxLength]=\"limits.secretReference\"\n [value]=\"oauthSecretReference()\"\n [attr.aria-describedby]=\"describedBy(null, 'oauth.clientSecretReference')\"\n [attr.aria-invalid]=\"(submitted() && oauthReferenceInvalid()) || serverInvalid('oauth.clientSecretReference') ? true : null\"\n (input)=\"oauthSecretReference.set(value($event)); touch('oauth.clientSecretReference')\" />\n @if (submitted() && oauthReferenceInvalid()) {\n <p class=\"hint\"><span class=\"error-text\">{{ 'nh-assistant.admin.server-editor.secret-reference-invalid' | translate }}</span></p>\n }\n @if (serverInvalid('oauth.clientSecretReference')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.clientSecretReference')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.clientSecretReference') | nhAssistantTranslate }}</p>\n }\n } @else {\n @if (hasOAuthSecret() && oauthSecretAction() === 'keep') {\n <div class=\"meta secret-state\">\n <span class=\"badge success\">{{ 'nh-assistant.admin.server-editor.secret-set' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"oauthSecretAction.set('replace')\">{{ 'nh-assistant.admin.server-editor.secret-replace' | translate }}</button>\n </div>\n }\n @if (showOAuthSecretInput()) {\n <label [for]=\"id + '-oauth-secret'\">{{ 'nh-assistant.admin.server-editor.client-secret' | translate }}</label>\n <input\n type=\"password\"\n class=\"mono\"\n autocomplete=\"new-password\"\n spellcheck=\"false\"\n [id]=\"id + '-oauth-secret'\"\n [maxLength]=\"limits.clientSecret\"\n [attr.aria-describedby]=\"describedBy(id + '-oauth-secret-hint', 'oauth.clientSecret')\"\n [attr.aria-invalid]=\"serverInvalid('oauth.clientSecret') ? true : null\"\n [value]=\"oauthSecret()\"\n (input)=\"onOAuthSecretInput($event); touch('oauth.clientSecret')\" />\n }\n <p class=\"hint\" [id]=\"id + '-oauth-secret-hint'\">{{ 'nh-assistant.admin.server-editor.client-secret-hint' | translate }}</p>\n }\n }\n @if (serverInvalid('oauth.clientSecret')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.clientSecret')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.clientSecret') | nhAssistantTranslate }}</p>\n }\n </fieldset>\n }\n\n @if (usesSecret()) {\n <fieldset class=\"field\">\n <legend>{{ 'nh-assistant.admin.server-editor.secret' | translate }}</legend>\n <div class=\"inline\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.server-editor.secret-source' | translate\">\n @for (source of secretSources; track source) {\n <label class=\"check\">\n <input\n type=\"radio\"\n [name]=\"id + '-secret-source'\"\n [value]=\"source\"\n [checked]=\"secretSource() === source\"\n (change)=\"setSecretSource(source)\" />\n <span>{{ 'nh-assistant.admin.server-editor.secret-source-' + source | translate }}</span>\n </label>\n }\n </div>\n @if (usesReference()) {\n <label [for]=\"id + '-secret-reference'\">{{ 'nh-assistant.admin.server-editor.secret-reference' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n placeholder=\"config:planning-token\"\n [id]=\"id + '-secret-reference'\"\n [maxLength]=\"limits.secretReference\"\n [value]=\"secretReference()\"\n [attr.aria-describedby]=\"describedBy(id + '-secret-reference-hint', 'secretReference')\"\n [attr.aria-invalid]=\"(submitted() && secretReferenceInvalid()) || serverInvalid('secretReference') ? true : null\"\n (input)=\"secretReference.set(value($event)); touch('secretReference')\" />\n <p class=\"hint\" [id]=\"id + '-secret-reference-hint'\">\n <span [class.error-text]=\"submitted() && secretReferenceInvalid()\">\n {{ (submitted() && secretReferenceInvalid() ? 'nh-assistant.admin.server-editor.secret-reference-invalid' : 'nh-assistant.admin.server-editor.secret-reference-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('secretReference')) {\n <p class=\"field-error\" [id]=\"errorId('secretReference')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('secretReference') | nhAssistantTranslate }}</p>\n }\n } @else 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 <!-- A mode with a secret always needs one: it is replaced, or removed by choosing a reference or another mode. -->\n <button class=\"secondary\" type=\"button\" (click)=\"setSecretAction('replace')\">{{ 'nh-assistant.admin.server-editor.secret-replace' | 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 [maxLength]=\"limits.secret\"\n [attr.placeholder]=\"'nh-assistant.admin.server-editor.secret-new' | translate\"\n [attr.aria-describedby]=\"describedBy(id + '-secret-hint', 'secret')\"\n [attr.aria-invalid]=\"serverInvalid('secret') ? true : null\"\n [value]=\"secret()\"\n (input)=\"onSecretInput($event); touch('secret')\" />\n }\n @if (!usesReference()) {\n <p class=\"hint\" [id]=\"id + '-secret-hint'\">{{ 'nh-assistant.admin.server-editor.secret-hint' | translate }}</p>\n }\n @if (serverInvalid('secret')) {\n <p class=\"field-error\" [id]=\"errorId('secret')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('secret') | nhAssistantTranslate }}</p>\n }\n </fieldset>\n }\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-certificate'\">{{ 'nh-assistant.admin.server-editor.client-certificate' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n [id]=\"id + '-certificate'\"\n [maxLength]=\"limits.clientCertificateReference\"\n [value]=\"clientCertificateReference()\"\n [attr.aria-describedby]=\"describedBy(id + '-certificate-hint', 'clientCertificateReference')\"\n [attr.aria-invalid]=\"(submitted() && certificateInvalid()) || serverInvalid('clientCertificateReference') ? true : null\"\n (input)=\"clientCertificateReference.set(value($event)); touch('clientCertificateReference')\" />\n <p class=\"hint\" [id]=\"id + '-certificate-hint'\">\n <span [class.error-text]=\"submitted() && certificateInvalid()\">\n {{ (submitted() && certificateInvalid() ? 'nh-assistant.admin.server-editor.client-certificate-invalid' : 'nh-assistant.admin.server-editor.client-certificate-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('clientCertificateReference')) {\n <p class=\"field-error\" [id]=\"errorId('clientCertificateReference')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('clientCertificateReference') | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-transport'\">{{ 'nh-assistant.admin.server-editor.transport' | translate }}</label>\n <select\n [id]=\"id + '-transport'\"\n [attr.aria-describedby]=\"describedBy(id + '-transport-hint', 'transport')\"\n [attr.aria-invalid]=\"serverInvalid('transport') ? true : null\"\n (change)=\"transport.set($any(value($event))); touch('transport')\">\n @for (option of transports; track option) {\n <option [value]=\"option\" [selected]=\"transport() === option\">{{ 'nh-assistant.admin.mcp.transport.' + option | translate }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-transport-hint'\">{{ 'nh-assistant.admin.server-editor.transport-hint' | translate }}</p>\n @if (serverInvalid('transport')) {\n <p class=\"field-error\" [id]=\"errorId('transport')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('transport') | nhAssistantTranslate }}</p>\n }\n </div>\n </div>\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 [maxLength]=\"limits.requiredPolicy\"\n [value]=\"requiredPolicy()\"\n [attr.aria-describedby]=\"describedBy(id + '-policy-hint', 'requiredPolicy')\"\n [attr.aria-invalid]=\"serverInvalid('requiredPolicy') ? true : null\"\n (input)=\"requiredPolicy.set(value($event)); touch('requiredPolicy')\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.server-editor.required-policy-hint' | translate }}</p>\n @if (serverInvalid('requiredPolicy')) {\n <p class=\"field-error\" [id]=\"errorId('requiredPolicy')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('requiredPolicy') | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-headless'\">{{ 'nh-assistant.admin.server-editor.headless-use' | translate }}</label>\n <select\n [id]=\"id + '-headless'\"\n [attr.aria-describedby]=\"describedBy(id + '-headless-hint', 'headlessUse')\"\n [attr.aria-invalid]=\"serverInvalid('headlessUse') ? true : null\"\n (change)=\"headlessUse.set($any(value($event))); touch('headlessUse')\">\n @for (use of headlessUses(); track use) {\n <option [value]=\"use\" [selected]=\"effectiveHeadlessUse() === use\">{{ 'nh-assistant.admin.mcp.headless.' + use | translate }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-headless-hint'\">\n {{ (personalCredential() ? 'nh-assistant.admin.server-editor.headless-use-personal' : 'nh-assistant.admin.server-editor.headless-use-hint') | translate }}\n </p>\n @if (serverInvalid('headlessUse')) {\n <p class=\"field-error\" [id]=\"errorId('headlessUse')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('headlessUse') | nhAssistantTranslate }}</p>\n }\n </div>\n\n @if (!isNew()) {\n <fieldset class=\"field readers\">\n <legend>{{ 'nh-assistant.admin.server-editor.reader.title' | translate }}</legend>\n <p class=\"hint\">{{ 'nh-assistant.admin.server-editor.reader.hint' | translate }}</p>\n @if (serverInvalid('readers')) {\n <p class=\"field-error\" [id]=\"errorId('readers')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('readers') | nhAssistantTranslate }}</p>\n }\n\n @for (reader of readers(); track reader.key; let index = $index) {\n <fieldset class=\"subsection reader\" [attr.data-reader]=\"index\">\n <legend class=\"reader-title\">{{ 'nh-assistant.admin.server-editor.reader.item' | translate: { number: index + 1 } }}</legend>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-reader-tool-' + reader.key\">{{ 'nh-assistant.admin.server-editor.reader.tool' | translate }}</label>\n <select\n [id]=\"id + '-reader-tool-' + reader.key\"\n [attr.aria-describedby]=\"describedBy(id + '-reader-tool-hint-' + reader.key, readerField(index, 'toolName'))\"\n [attr.aria-invalid]=\"(submitted() && (readerProblems()[index].tool || readerProblems()[index].duplicate)) || serverInvalid(readerField(index, 'toolName')) ? true : null\"\n (change)=\"updateReader(index, 'toolName', value($event))\">\n <option value=\"\" [selected]=\"reader.toolName === ''\">{{ 'nh-assistant.admin.server-editor.reader.tool-choose' | translate }}</option>\n @for (name of readerToolNames(); track name) {\n <option [value]=\"name\" [selected]=\"reader.toolName === name\">{{ name }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-reader-tool-hint-' + reader.key\">\n @if (submitted() && readerProblems()[index].tool) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.required' | translate }}</span>\n } @else if (submitted() && readerProblems()[index].duplicate) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.server-editor.reader.tool-duplicate' | translate }}</span>\n } @else {\n {{ 'nh-assistant.admin.server-editor.reader.tool-hint' | translate }}\n }\n </p>\n @if (serverInvalid(readerField(index, 'toolName'))) {\n <p class=\"field-error\" [id]=\"errorId(readerField(index, 'toolName'))\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys(readerField(index, 'toolName')) | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-reader-classification-' + reader.key\">{{ 'nh-assistant.admin.server-editor.reader.max-classification' | translate }}</label>\n <select\n [id]=\"id + '-reader-classification-' + reader.key\"\n [attr.aria-describedby]=\"describedBy(id + '-reader-classification-hint-' + reader.key, readerField(index, 'maxClassification'))\"\n [attr.aria-invalid]=\"(submitted() && readerProblems()[index].classification) || serverInvalid(readerField(index, 'maxClassification')) ? true : null\"\n (change)=\"updateReader(index, 'maxClassification', value($event))\">\n <option value=\"\" [selected]=\"reader.maxClassification === ''\">{{ 'nh-assistant.admin.server-editor.reader.max-classification-choose' | translate }}</option>\n @for (classification of classifications; track classification) {\n <option [value]=\"classification\" [selected]=\"reader.maxClassification === classification\">\n {{ 'nh-assistant.admin.run-config.skills.classification.' + classification | translate }}\n </option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-reader-classification-hint-' + reader.key\">\n @if (submitted() && readerProblems()[index].classification) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.required' | translate }}</span>\n } @else {\n {{ 'nh-assistant.admin.server-editor.reader.max-classification-hint' | translate }}\n }\n </p>\n @if (serverInvalid(readerField(index, 'maxClassification'))) {\n <p class=\"field-error\" [id]=\"errorId(readerField(index, 'maxClassification'))\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys(readerField(index, 'maxClassification')) | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-reader-types-' + reader.key\">{{ 'nh-assistant.admin.server-editor.reader.media-types' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n [id]=\"id + '-reader-types-' + reader.key\"\n [value]=\"reader.mediaTypes\"\n [attr.aria-describedby]=\"describedBy(id + '-reader-types-hint-' + reader.key, readerField(index, 'mediaTypes'))\"\n [attr.aria-invalid]=\"(submitted() && readerProblems()[index].types) || serverInvalid(readerField(index, 'mediaTypes')) ? true : null\"\n (input)=\"updateReader(index, 'mediaTypes', value($event))\" />\n <p class=\"hint\" [id]=\"id + '-reader-types-hint-' + reader.key\">\n <span [class.error-text]=\"submitted() && readerProblems()[index].types\">\n {{ (submitted() && readerProblems()[index].types ? 'nh-assistant.admin.server-editor.reader.media-types-invalid' : 'nh-assistant.admin.server-editor.reader.media-types-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid(readerField(index, 'mediaTypes'))) {\n <p class=\"field-error\" [id]=\"errorId(readerField(index, 'mediaTypes'))\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys(readerField(index, 'mediaTypes')) | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-reader-priority-' + reader.key\">{{ 'nh-assistant.admin.server-editor.reader.priority' | translate }}</label>\n <input\n type=\"number\"\n inputmode=\"numeric\"\n step=\"1\"\n [min]=\"readerPriority.min\"\n [max]=\"readerPriority.max\"\n [id]=\"id + '-reader-priority-' + reader.key\"\n [value]=\"reader.priority\"\n [attr.aria-describedby]=\"describedBy(id + '-reader-priority-hint-' + reader.key, readerField(index, 'priority'))\"\n [attr.aria-invalid]=\"(submitted() && readerProblems()[index].priority) || serverInvalid(readerField(index, 'priority')) ? true : null\"\n (input)=\"updateReader(index, 'priority', value($event))\" />\n <p class=\"hint\" [id]=\"id + '-reader-priority-hint-' + reader.key\">\n <span [class.error-text]=\"submitted() && readerProblems()[index].priority\">\n {{ (submitted() && readerProblems()[index].priority ? 'nh-assistant.admin.server-editor.reader.priority-invalid' : 'nh-assistant.admin.server-editor.reader.priority-hint') | translate: readerPriority }}\n </span>\n </p>\n @if (serverInvalid(readerField(index, 'priority'))) {\n <p class=\"field-error\" [id]=\"errorId(readerField(index, 'priority'))\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys(readerField(index, 'priority')) | nhAssistantTranslate }}</p>\n }\n </div>\n </div>\n\n <div class=\"inline\">\n <button\n type=\"button\"\n class=\"secondary\"\n [attr.aria-label]=\"'nh-assistant.admin.server-editor.reader.remove-label' | translate: { number: index + 1 }\"\n (click)=\"removeReader(index)\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.server-editor.reader.remove' | translate }}\n </button>\n </div>\n </fieldset>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.server-editor.reader.empty' | translate }}</p>\n }\n\n <div class=\"inline\">\n <button\n type=\"button\"\n class=\"secondary\"\n [id]=\"id + '-reader-add'\"\n [disabled]=\"readers().length >= maxReaders || readerToolNames().length === 0\"\n [attr.aria-describedby]=\"id + '-reader-add-hint'\"\n (click)=\"addReader()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.server-editor.reader.add' | translate }}\n </button>\n </div>\n <p class=\"hint\" [id]=\"id + '-reader-add-hint'\">{{ readerAddHint() | translate: { max: maxReaders } }}</p>\n @if (readers().length > 0) {\n <p class=\"message warning\" role=\"note\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.reader.leaves-application' | translate }}</p>\n }\n </fieldset>\n }\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 <div class=\"form-error\" role=\"alert\" data-server-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n <span>{{ errorKeys() | nhAssistantTranslate: failure.code }}</span>\n @if (otherServerErrors().length > 0) {\n <ul>\n @for (other of otherServerErrors(); track other.field) {\n <li><code class=\"mono\">{{ other.field }}</code>: {{ other.keys | nhAssistantTranslate }}</li>\n }\n </ul>\n }\n </div>\n </div>\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, effect, inject, signal, untracked } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n McpConnectionsSummary,\n McpServer,\n McpServerTestResult,\n NhAssistantAdminApiService,\n NhAssistantError,\n NhAssistantMcpConnectService,\n ɵnhAssistantCodeKeys as nhAssistantCodeKeys,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵnhAssistantErrorOf as nhAssistantErrorOf,\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 organization's OAuth connection,\n * the server editor and the tool table of one server. The personal connections are counted and\n * revoked only for servers each person connects to with OAuth; a count that could not be read shows\n * its translated code at the 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 readonly connector = inject(NhAssistantMcpConnectService);\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 /** The server whose organization connection is being authorized. */\n readonly connecting = signal<string | null>(null);\n readonly confirmingDisconnect = signal<string | null>(null);\n readonly confirmingRevokeAll = signal<string | null>(null);\n /** The personal connections per status of each server people connect to themselves. */\n readonly summaries = signal<Record<string, McpConnectionsSummary>>({});\n /** Why the personal connections of a server could not be counted, per server. */\n readonly summaryErrors = signal<Record<string, NhAssistantError>>({});\n /** The latest connection result to announce, per server. */\n readonly notice = signal<{ serverId: string; key: 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 // An authorization in redirect mode that returned to this page.\n effect(() => {\n const returned = this.connector.returned();\n if (returned) {\n untracked(() => {\n this.connector.returned.set(null);\n if (returned.completion) {\n this.notice.set({ serverId: returned.completion.serverId, key: 'nh-assistant.admin.mcp.connect-done' });\n this.refresh();\n } else {\n this.error.set(nhAssistantErrorOf(returned.code));\n }\n });\n }\n });\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 this.loadSummaries(servers);\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({\n next: servers => {\n this.servers.set(servers);\n this.loadSummaries(servers);\n },\n error: () => undefined\n }));\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 => {\n this.setTest(server.id, { running: false, result });\n // The test records the connection state of the server.\n this.refresh();\n },\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 ? nhAssistantCodeKeys(code) : ['nh-assistant.errors.generic'];\n }\n\n /** The text of a server's failed count of personal connections. */\n summaryErrorKeys(serverId: string): string[] {\n return nhAssistantErrorKeys(this.summaryErrors()[serverId] ?? null);\n }\n\n /** Whether an administrator connects the organization's account to the server. */\n authorizesOrganization(server: McpServer): boolean {\n return server.authMode === 'oauth' && server.connectionScope === 'organization';\n }\n\n /** Whether each person connects their own account to the server. */\n connectsPeople(server: McpServer): boolean {\n return server.authMode === 'oauth' && server.connectionScope === 'user';\n }\n\n summary(server: McpServer): McpConnectionsSummary | null {\n return this.summaries()[server.id] ?? null;\n }\n\n /** Revokes every person's connection of the server; each person connects again. */\n revokeAll(server: McpServer): void {\n this.confirmingRevokeAll.set(null);\n this.error.set(null);\n this.notice.set(null);\n this.actions.add(this.admin.revokeMcpConnections(server.id).subscribe({\n complete: () => {\n this.notice.set({ serverId: server.id, key: 'nh-assistant.admin.mcp.revoke-all-done' });\n this.loadSummaries([server]);\n },\n error: (error: unknown) => this.error.set(toNhAssistantError(error))\n }));\n }\n\n /** Counts the personal connections of the servers each person connects to with OAuth; only those have them. */\n private loadSummaries(servers: readonly McpServer[]): void {\n for (const server of servers.filter(item => this.connectsPeople(item))) {\n this.actions.add(this.admin.getMcpConnectionsSummary(server.id).subscribe({\n next: summary => {\n this.summaries.update(summaries => ({ ...summaries, [server.id]: summary }));\n this.summaryErrors.update(({ [server.id]: _, ...others }) => others);\n },\n error: (error: unknown) => {\n this.summaryErrors.update(errors => ({ ...errors, [server.id]: toNhAssistantError(error) }));\n }\n }));\n }\n }\n\n /** Counts the personal connections of one server again. */\n retrySummary(server: McpServer): void {\n this.loadSummaries([server]);\n }\n\n /**\n * Authorizes the organization's account, or for a server people connect to themselves the\n * administrator's own account, in a window opened right away, so popup blockers allow it, and\n * completes the connection with this administrator's session.\n */\n connect(server: McpServer): void {\n this.error.set(null);\n this.notice.set(null);\n this.connecting.set(server.id);\n this.actions.add(this.connector.run(request => this.admin.authorizeMcpOrganizationConnection(server.id, request), server.id).subscribe({\n next: () => {\n this.connecting.set(null);\n this.notice.set({\n serverId: server.id,\n key: this.connectsPeople(server) ? 'nh-assistant.admin.mcp.connect-own-done' : 'nh-assistant.admin.mcp.connect-done'\n });\n this.refresh();\n },\n error: (error: unknown) => {\n this.connecting.set(null);\n this.error.set(toNhAssistantError(error));\n }\n }));\n }\n\n /** Removes the organization connection; the server revokes its tokens. */\n disconnect(server: McpServer): void {\n this.confirmingDisconnect.set(null);\n this.error.set(null);\n this.notice.set(null);\n this.actions.add(this.admin.disconnectMcpOrganizationConnection(server.id).subscribe({\n complete: () => {\n this.notice.set({ serverId: server.id, key: 'nh-assistant.admin.mcp.disconnect-done' });\n this.refresh();\n },\n error: (error: unknown) => this.error.set(toNhAssistantError(error))\n }));\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] | nhAssistantTranslate: server.authMode }}</span>\n @if (server.authMode === 'bearer' || server.authMode === 'api-key' || server.authMode === 'basic') {\n @if (server.secretReference; as reference) {\n <span class=\"badge success\">{{ 'nh-assistant.admin.mcp.secret-reference' | translate: { reference: reference } }}</span>\n } @else {\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 }\n @if (server.authMode === 'oauth') {\n <span>{{ 'nh-assistant.admin.mcp.connection-scope.' + server.connectionScope | translate }}</span>\n }\n @if (server.organizationConnection; as connection) {\n <span\n class=\"badge\"\n [class.success]=\"connection.status === 'active'\"\n [class.warning]=\"connection.status === 'reauthorization-required' || connection.status === 'issuer-changed'\">\n {{ 'nh-assistant.admin.mcp.connection-status.' + connection.status | translate }}\n </span>\n @if (server.oauth?.organizationAccountLabel; as account) {\n <span>{{ 'nh-assistant.admin.mcp.organization-account' | translate: { account: account } }}</span>\n }\n @if (connection.status === 'active' && connection.connectedAt) {\n <span>{{ 'nh-assistant.admin.mcp.connected-by' | translate: { actor: connection.connectedBy ?? '', date: (connection.connectedAt | date: 'medium') } }}</span>\n }\n @if (connection.requiredScopes; as scopes) {\n <span>{{ 'nh-assistant.admin.mcp.required-scopes' | translate: { scopes: scopes } }}</span>\n }\n }\n @if (connectsPeople(server) && summary(server); as counts) {\n <span>{{ 'nh-assistant.admin.mcp.personal-connections' | translate: { active: counts.active } }}</span>\n @if (counts.reauthorizationRequired + counts.issuerChanged > 0) {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.mcp.personal-attention' | translate: { count: counts.reauthorizationRequired + counts.issuerChanged } }}</span>\n }\n }\n @if (server.clientCertificateReference; as certificate) {\n <span class=\"badge\">{{ 'nh-assistant.admin.mcp.client-certificate' | translate: { name: certificate } }}</span>\n }\n @if (server.transport === 'auto') {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.mcp.transport-fallback' | translate }}</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 <span>{{ 'nh-assistant.admin.mcp.headless.' + (server.headlessUse ?? 'never') | translate }}</span>\n @if (server.lastConnectAt; as connectedAt) {\n @if (server.lastConnectCode; as code) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.mcp.connect-failed' | translate: { date: (connectedAt | date: 'medium') } }}</span>\n <span>{{ testErrorKeys(code) | nhAssistantTranslate: code }}</span>\n } @else {\n <span>{{ 'nh-assistant.admin.mcp.connected' | translate: { date: (connectedAt | date: 'medium') } }}</span>\n }\n } @else {\n <span>{{ 'nh-assistant.admin.mcp.never-connected' | translate }}</span>\n }\n </div>\n\n @if (summaryErrors()[server.id]; as failure) {\n <p class=\"message warning catalog-error\" role=\"status\" data-summary-error>\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">\n {{ 'nh-assistant.admin.mcp.personal-connections-failed' | translate }}\n {{ summaryErrorKeys(server.id) | nhAssistantTranslate: failure.code }}\n </span>\n <button class=\"secondary\" type=\"button\" (click)=\"retrySummary(server)\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </p>\n }\n @if (server.organizationConnection?.status === 'issuer-changed') {\n <p class=\"message warning\" role=\"note\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.mcp.issuer-changed' | translate }}</p>\n }\n @if (connecting() === server.id) {\n <p class=\"muted\" role=\"status\">{{ 'nh-assistant.admin.mcp.connecting' | translate }}</p>\n } @else if (notice()?.serverId === server.id) {\n <p class=\"message success\" role=\"status\"><nh-assistant-icon name=\"check\" />{{ notice()!.key | translate }}</p>\n }\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 (authorizesOrganization(server)) {\n <button class=\"secondary\" type=\"button\" [disabled]=\"connecting() !== null\" (click)=\"connect(server)\">\n <nh-assistant-icon name=\"link\" />{{ (server.organizationConnection?.status === 'not-connected' ? 'nh-assistant.admin.mcp.connect' : 'nh-assistant.admin.mcp.reconnect') | translate }}\n </button>\n }\n @if (connectsPeople(server)) {\n <button class=\"secondary\" type=\"button\" [disabled]=\"connecting() !== null\" (click)=\"connect(server)\">\n <nh-assistant-icon name=\"link\" />{{ 'nh-assistant.admin.mcp.connect-own' | translate }}\n </button>\n @if (confirmingRevokeAll() === server.id) {\n <button class=\"danger\" type=\"button\" (click)=\"revokeAll(server)\">{{ 'nh-assistant.admin.mcp.confirm-revoke-all' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingRevokeAll.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else if ((summary(server)?.active ?? 0) + (summary(server)?.reauthorizationRequired ?? 0) + (summary(server)?.issuerChanged ?? 0) > 0) {\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingRevokeAll.set(server.id)\">{{ 'nh-assistant.admin.mcp.revoke-all' | translate }}</button>\n }\n }\n @if (server.organizationConnection && server.organizationConnection.status !== 'not-connected') {\n @if (confirmingDisconnect() === server.id) {\n <button class=\"danger\" type=\"button\" (click)=\"disconnect(server)\">{{ 'nh-assistant.admin.mcp.confirm-disconnect' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingDisconnect.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingDisconnect.set(server.id)\">{{ 'nh-assistant.admin.mcp.disconnect' | translate }}</button>\n }\n }\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.cancel' | 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, Injector, 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 private readonly injector = inject(Injector);\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 /**\n * Shows the MCP servers, for example from an agent's flow that explains why a server is not used in\n * runs without a person, and moves the focus to their tab.\n */\n showMcpServers(): void {\n this.select('mcp-servers');\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>(`#${this.id}-tab-mcp-servers`)?.focus(), { injector: this.injector });\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 (openMcpServers)=\"showMcpServers()\" />\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 './agents/nh-assistant-agent-run-history.component';\nexport * from './agents/nh-assistant-agent-run-configuration.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":["toNhAssistantError","nhAssistantErrorKeys","NhAssistantIconComponent","NhAssistantTranslatePipe","nextId","NH_ASSISTANT_DASH_CASE","dayMs","periodRange","nhAssistantCodeKeys","NhAssistantSubjectLinkComponent","blank","NhAssistantRunNowDialogComponent","NhAssistantPickerComponent","nhAssistantErrorOf"],"mappings":"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"}
1
+ {"version":3,"file":"newheap-platform-ai-chat-admin.mjs","sources":["../../../projects/nh-ai-chat/admin/src/nh-assistant-account-names.ts","../../../projects/nh-ai-chat/admin/src/agents/agent-texts.ts","../../../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-agent-run-history.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-run-history.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-consultation-routes.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-consultation-routes.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/run-config-shared.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/agent-flow.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/consultations.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/run-config-form.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-consultation-form.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-consultation-form.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-agent-flow.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-agent-flow.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-account-picker.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-agent-work-setup.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-agent-work-setup.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-file-limits-fields.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-file-limits-fields.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-run-settings-form.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-run-settings-form.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-skill-form.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-skill-form.component.html","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-trigger-form.component.ts","../../../projects/nh-ai-chat/admin/src/agents/run-config/nh-assistant-trigger-form.component.html","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-run-configuration.component.ts","../../../projects/nh-ai-chat/admin/src/agents/nh-assistant-agent-run-configuration.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 { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, signal } from '@angular/core';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\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 * The names the application knows for account ids, for the screens of the administration\n * (internal). A screen shows the name only; it shows the id, labeled as an account ID, only while\n * no name is known. When the lookup fails, `error` says why with the failure's code and `retry` asks\n * for the names that are still missing, so a failure never hides behind the ids. Create it in an\n * injection context, such as a component's field.\n */\nexport class NhAssistantAccountNames {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly translate = inject(TranslateService);\n private readonly subscriptions = new Subscription();\n /** The ids whose names were asked for, also the ones the application does not know. */\n private readonly asked = new Set<string>();\n /** The ids of failed lookups, which `retry` asks for again. */\n private failed = new Set<string>();\n\n /** The names found so far, by account id. */\n readonly names = signal<ReadonlyMap<string, string>>(new Map());\n /** Why the latest lookup failed; `null` while none did. */\n readonly error = signal<NhAssistantError | null>(null);\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscriptions.unsubscribe());\n }\n\n /**\n * The name of an account for a sentence, or its id labeled as an account ID (\"account ID …\")\n * while the application knows no name for it.\n */\n nameOf(actorId: string | null | undefined): string {\n if (!actorId) {\n return '';\n }\n\n return this.names().get(actorId) ?? this.translate.instant('nh-assistant.account-id', { id: actorId }) as string;\n }\n\n /**\n * The account ID as a tooltip for a name shown in its place; `null` while no name is known,\n * because the text shows the id then.\n */\n idTitleOf(actorId: string | null | undefined): string | null {\n if (!actorId || !this.names().has(actorId)) {\n return null;\n }\n\n return this.translate.instant('nh-assistant.account-id-title', { id: actorId }) as string;\n }\n\n /** Looks up the names of the ids that were not asked for yet. */\n load(actorIds: readonly (string | null | undefined)[]): void {\n const missing = [...new Set(actorIds.filter((id): id is string => !!id && !this.asked.has(id)))];\n if (missing.length === 0) {\n return;\n }\n\n for (const id of missing) {\n this.asked.add(id);\n }\n this.subscriptions.add(this.admin.getAccounts(missing).subscribe({\n next: accounts => {\n this.names.update(names => new Map([...names, ...accounts.map(account => [account.actorId, account.displayName] as const)]));\n },\n error: (error: unknown) => {\n for (const id of missing) {\n this.asked.delete(id);\n this.failed.add(id);\n }\n this.error.set(toNhAssistantError(error));\n }\n }));\n }\n\n /** Asks again for the names whose lookup failed. */\n retry(): void {\n const ids = [...this.failed];\n this.failed = new Set();\n this.error.set(null);\n this.load(ids);\n }\n}\n\n/**\n * The notice of a failed lookup of account names (internal): the screen shows ids, says why there\n * are no names and offers to look them up again.\n */\n@Component({\n selector: 'nh-assistant-account-names-error',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (names().error(); as failure) {\n <p class=\"names-error\" role=\"status\" data-account-names-error>\n <nh-assistant-icon name=\"warning\" />\n <span>{{ 'nh-assistant.admin.account-names-failed' | translate }} {{ keys() | nhAssistantTranslate: failure.code }}</span>\n <button type=\"button\" class=\"link\" data-account-names-retry (click)=\"names().retry()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </p>\n }\n `,\n styles: [`\n :host { display: block; min-width: 0; }\n .names-error {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 6px;\n margin: 0;\n border: 1px solid var(--nha-warning, #8a5a00);\n border-radius: var(--nha-radius-control, 12px);\n padding: 8px 12px;\n color: var(--nha-text, inherit);\n background: var(--nha-warning-soft, transparent);\n font-size: 13px;\n overflow-wrap: anywhere;\n }\n .names-error span { flex: 1 1 auto; min-width: 0; }\n button.link {\n border: 0;\n padding: 0;\n color: var(--nha-accent, currentColor);\n background: none;\n font: inherit;\n text-decoration: underline;\n cursor: pointer;\n }\n `]\n})\nexport class NhAssistantAccountNamesErrorComponent {\n readonly names = input.required<NhAssistantAccountNames>();\n readonly keys = computed(() => nhAssistantErrorKeys(this.names().error()));\n}\n\n/**\n * One account by its name (internal): the name only, with the account ID as its tooltip and a\n * button that copies the ID; without a known name the ID itself, labeled as an account ID. Where\n * the browser refuses the clipboard, the button shows the ID next to the name to copy by hand.\n */\n@Component({\n selector: 'nh-assistant-account-label',\n standalone: true,\n imports: [TranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (name(); as known) {\n <span class=\"account-name\" data-account-label-name [attr.title]=\"'nh-assistant.account-id-title' | translate: { id: actorId() }\">{{ known }}</span>\n <button\n type=\"button\"\n class=\"copy-id\"\n data-account-copy-id\n [attr.aria-label]=\"'nh-assistant.admin.account.copy-id' | translate: { name: known }\"\n [attr.title]=\"'nh-assistant.admin.account.copy-id' | translate: { name: known }\"\n (click)=\"copyId()\">\n <nh-assistant-icon [name]=\"copied() ? 'check' : 'copy'\" />\n </button>\n @if (revealed()) {\n <span class=\"account-id\" data-account-label-revealed>{{ 'nh-assistant.admin.account.id' | translate: { id: actorId() } }}</span>\n }\n <span class=\"visually-hidden\" role=\"status\">{{ copied() ? ('nh-assistant.admin.account.id-copied' | translate) : '' }}</span>\n } @else {\n <span class=\"account-id\" data-account-label-id>{{ 'nh-assistant.admin.account.id' | translate: { id: actorId() } }}</span>\n }\n `,\n styles: [`\n :host { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; min-width: 0; max-width: 100%; }\n .account-name { font-weight: 600; overflow-wrap: anywhere; }\n .account-id { color: var(--nha-muted, inherit); overflow-wrap: anywhere; }\n .copy-id {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n min-width: 28px;\n min-height: 28px;\n border: 1px solid transparent;\n border-radius: var(--nha-radius-control, 12px);\n padding: 4px;\n color: var(--nha-muted, currentColor);\n background: none;\n cursor: pointer;\n }\n .copy-id:hover { color: var(--nha-text, currentColor); border-color: var(--nha-border, currentColor); }\n .copy-id:focus-visible { outline: 2px solid var(--nha-accent, currentColor); outline-offset: 2px; }\n .visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n }\n `]\n})\nexport class NhAssistantAccountLabelComponent {\n /** The account's id. */\n readonly actorId = input.required<string>();\n /** The account's name; `null` while the application knows none. */\n readonly name = input<string | null>(null);\n\n readonly copied = signal(false);\n readonly revealed = signal(false);\n private resetTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => clearTimeout(this.resetTimer));\n effect(() => {\n // Another account starts without the state of the previous one.\n this.actorId();\n this.copied.set(false);\n this.revealed.set(false);\n });\n }\n\n async copyId(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.actorId());\n } catch {\n // Without clipboard access the ID is shown to copy by hand.\n this.revealed.set(true);\n return;\n }\n\n this.copied.set(true);\n clearTimeout(this.resetTimer);\n this.resetTimer = setTimeout(() => this.copied.set(false), 3_000);\n }\n}\n","/**\n * Translation keys for the texts the administration shows about agents, skills and policies. Each\n * list goes through `nhAssistantTranslate` with the text itself as fallback, so a missing\n * translation shows what the server sent.\n */\n\n/**\n * The key of a text of an agent in code, which names and describes itself with translation keys;\n * none for an agent created in the administration, whose texts are what the administrator typed.\n */\nexport function codeTextKeys(source: string, text: string | null | undefined): string[] {\n return source === 'code' && text ? [text] : [];\n}\n\n/** The key an application may translate a skill's name with. */\nexport function skillNameKeys(agentId: string, skillId: string): string[] {\n return [`nh-assistant.agents.${agentId}.skills.${skillId}.name`];\n}\n\n/**\n * The key an application may translate a skill's description with. Skills in code describe\n * themselves in the language triage reads; the screen shows a translation when there is one.\n */\nexport function skillDescriptionKeys(agentId: string, skillId: string): string[] {\n return [`nh-assistant.agents.${agentId}.skills.${skillId}.description`];\n}\n\n/**\n * The key of a warning about an agent or a skill that is saved and in effect but may not work as\n * configured, such as `classification-not-permitted`; a code the screen does not know shows as sent.\n */\nexport function warningKeys(kind: 'agent' | 'skill', code: string): string[] {\n return kind === 'agent'\n ? [`nh-assistant.admin.agents.warnings.${code}`]\n : [`nh-assistant.admin.run-config.skills.warnings.${code}`];\n}\n\n/** The key an application may translate an authorization policy's name with. */\nexport function policyKeys(policy: string | null | undefined): string[] {\n return policy ? [`nh-assistant.policies.${policy}`] : [];\n}\n\n/** A readable name for a dash-case id: `task-follow-up` reads \"Task follow up\". */\nexport function readableId(id: string): string {\n const words = id.split('-').filter(word => word.length > 0).join(' ');\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\n/** What an agent works on, ready to show: object types by name, all objects and the application. */\nexport interface WorksOnSummary {\n /** The names of the object types it works on; empty with `all`. */\n types: string[];\n /** It works on every object type. */\n all: boolean;\n /** It works on the whole application. */\n application: boolean;\n perDivision: boolean;\n /** An agent in code that does not say what it works on. */\n undeclared: boolean;\n /** The names of the object types it is known to work on, as a hint next to \"All objects\". */\n known: string[];\n runPolicy: string | null;\n viewPolicy: string | null;\n}\n\n/**\n * What an agent works on, with object types named as the run catalog names several of them in the\n * reader's language, and their ids otherwise. An older server that does not say reads as all objects.\n * The platform's types (`nh-`, such as the whole application's `nh-system`) are not object types of\n * the application: the agent's threads on the whole application are no hint next to \"All objects\".\n */\nexport function worksOnSummary(\n agent: {\n worksOnSubjectTypes?: string[];\n worksOnAllSubjects?: boolean;\n worksOnApplication?: boolean;\n perDivision?: boolean;\n worksOnDeclared?: boolean;\n knownSubjectTypes?: string[];\n runPolicy?: string | null;\n viewPolicy?: string | null;\n },\n subjectTypes: readonly { id: string; name: string; pluralName?: string | null; isSystem?: boolean }[] | null | undefined\n): WorksOnSummary {\n const names = new Map((subjectTypes ?? []).map(type => [type.id, type.pluralName ?? type.name]));\n const system = new Set((subjectTypes ?? []).filter(type => type.isSystem).map(type => type.id));\n const name = (id: string): string => names.get(id) ?? id;\n const objectType = (id: string): boolean => !id.startsWith('nh-') && !system.has(id);\n const types = (agent.worksOnSubjectTypes ?? []).filter(objectType);\n const all = agent.worksOnAllSubjects ?? (types.length === 0 && agent.worksOnApplication !== true);\n return {\n types: all ? [] : types.map(name),\n all,\n application: agent.worksOnApplication === true,\n perDivision: agent.perDivision === true,\n undeclared: agent.worksOnDeclared === false,\n known: (agent.knownSubjectTypes ?? []).filter(objectType).map(name),\n runPolicy: agent.runPolicy ?? null,\n viewPolicy: agent.viewPolicy ?? null\n };\n}\n\n/** What the run-now dialog needs of an agent: its id, its name as people read it and what it works on. */\nexport interface RunNowAgentInput {\n id: string;\n worksOnSubjectTypes?: string[];\n worksOnAllSubjects?: boolean;\n worksOnApplication?: boolean;\n perDivision?: boolean;\n}\n\n/**\n * The agent as the run-now dialog runs it, with its name in the reader's language. An older server that\n * does not say what the agent works on reads as all objects, not the whole application, app-wide.\n */\nexport function runNowAgentOf(agent: RunNowAgentInput, name: string): {\n id: string;\n name: string;\n worksOnSubjectTypes: string[];\n worksOnAllSubjects: boolean;\n worksOnApplication: boolean;\n perDivision: boolean;\n} {\n return {\n id: agent.id,\n name,\n worksOnSubjectTypes: agent.worksOnSubjectTypes ?? [],\n worksOnAllSubjects: agent.worksOnAllSubjects ?? true,\n worksOnApplication: agent.worksOnApplication ?? false,\n perDivision: agent.perDivision ?? false\n };\n}\n","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';\nimport { NhAssistantAccountNames, NhAssistantAccountNamesErrorComponent } from '../nh-assistant-account-names';\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, NhAssistantAccountNamesErrorComponent],\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 /** The names of the people who changed the context, once known, and why they are not. */\n readonly accountNames = new NhAssistantAccountNames();\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.accountNames.load(versions.map(version => version.updatedBy));\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 /** A person's name, or the id when the application does not know it. */\n nameOf(actorId: string | null | undefined): string {\n return this.accountNames.nameOf(actorId);\n }\n\n /** The account ID as the tooltip of a name shown in its place. */\n accountTitle(actorId: string | null | undefined): string | null {\n return this.accountNames.idTitleOf(actorId);\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.accountNames.load([updated.updatedBy]);\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 <nh-assistant-account-names-error [names]=\"accountNames\" />\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 [attr.title]=\"accountTitle(current.updatedBy)\">\n @if (current.updatedBy) {\n {{ 'nh-assistant.admin.context.updated' | translate: { date: (current.updatedAt | date: 'medium'), user: nameOf(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 [attr.title]=\"accountTitle(version.updatedBy)\">{{ nameOf(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, TranslateService } from '@ngx-translate/core';\nimport { Observable, Subscription, map, of, switchMap, tap } from 'rxjs';\nimport {\n AdminAgent,\n AdminAgentGroups,\n AdminAgentInput,\n AssistantAutonomy,\n AssistantDataClassification,\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 RunCatalog,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport { NH_ASSISTANT_MAX_INSTRUCTIONS } from '../context/nh-assistant-admin-context.component';\nimport { policyKeys, warningKeys, worksOnSummary } from './agent-texts';\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\n/** A text of an agent in code: its translation key and the translation the editor shows instead. */\ninterface KeyedText {\n key: string;\n shown: string;\n}\n\n/** How an agent created in the administration is used: chosen in the chat, working on its own, or both. */\nexport type AgentUse = 'chat' | 'background' | 'both';\n\n/** Whether an agent created in the administration works on every object type or on chosen ones. */\nexport type WorksOnScope = 'all' | 'types';\n\n/** The most object types one agent works on, as the server allows. */\nconst maxWorksOnTypes = 20;\n\nlet nextId = 0;\n\n/**\n * Creates or edits one agent: how it is used (offered in the chat, working on its own, or both),\n * what it works on (all objects or chosen object types, the whole application, per division when\n * the application lists divisions, and who may run it and see its results for the whole\n * application), texts, autonomy, policy, tool selectors chosen from the tool catalog or typed as\n * patterns, and assigned MCP servers. A new agent meant to work on its own continues with\n * `workRequested`. An agent in code names and describes itself with translation keys: the editor\n * shows their translation and sends the key back unless the administrator changed the text, so the\n * agent stays translated; what it works on comes from its code and is not edited here.\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 readonly translate = inject(TranslateService);\n private subscription?: Subscription;\n private keyedName: KeyedText | null = null;\n private keyedDescription: KeyedText | null = null;\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 /** The run catalog: the object types by name, the policies to choose and whether divisions are listed. */\n readonly catalog = input<RunCatalog | null>(null);\n /**\n * The run catalog could not be read: the editor then leaves out what the agent works on and its\n * groups, which depend on it, and a save keeps them as they are.\n */\n readonly catalogUnavailable = input(false);\n readonly saved = output<AdminAgent>();\n /**\n * A new agent meant to work on its own was created; the host continues with its run\n * configuration's guided setup. `saved` is not emitted for it.\n */\n readonly workRequested = output<AdminAgent>();\n readonly cancelled = output<void>();\n readonly uses: readonly AgentUse[] = ['chat', 'background', 'both'];\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 readonly classifications: readonly AssistantDataClassification[] = ['public', 'internal', 'confidential', 'restricted'];\n\n readonly agentId = signal('');\n readonly displayName = signal('');\n readonly description = signal('');\n readonly instructions = signal('');\n readonly autonomy = signal<AssistantAutonomy>('explain');\n /** How the agent is used: in the chat, on its own, or both. */\n readonly use = signal<AgentUse>('chat');\n /** A new agent takes its triggers at once; without it, it starts off until someone switches it on. */\n readonly switchOnNow = signal(true);\n /** The model profile of an agent created here; empty uses the application's chat profile. */\n readonly profile = signal('');\n /** The classification of the model calls of an agent created here; `internal` when it has none. */\n readonly dataClassification = signal<AssistantDataClassification>('internal');\n readonly requiredPolicy = signal('');\n readonly toolSelectors = signal<string[]>([]);\n readonly mcpServerIds = signal<string[]>([]);\n /** What the agent works on: all objects or the chosen object types. */\n readonly worksOnScope = signal<WorksOnScope>('all');\n readonly worksOnTypes = signal<string[]>([]);\n readonly worksOnApplication = signal(false);\n readonly perDivision = signal(false);\n readonly runPolicy = signal('');\n readonly viewPolicy = signal('');\n /** The groups of agents the agent is in, by id. */\n readonly groups = 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 /**\n * A new agent that was created while its groups could not be saved yet: the next save completes it\n * as an existing agent.\n */\n private readonly created = signal<AdminAgent | null>(null);\n /** The agent the next save updates; `null` while a new agent is not created yet. */\n private readonly editing = computed(() => this.created() ?? this.agent());\n\n readonly isNew = computed(() => this.editing() === null);\n /** Only agents created here choose whether they are offered in the chat; code decides for the others. */\n readonly choosesUse = computed(() => this.agent()?.source !== 'code');\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 /**\n * The application's own object types, by name; the platform's types, such as the whole\n * application, are chosen otherwise. A stored type the application no longer registers stays\n * listed by its id, so it can be unticked.\n */\n readonly subjectTypes = computed(() => {\n const catalog = this.catalog()?.subjectTypes ?? [];\n const registered = catalog.filter(type => !type.isSystem);\n const stored = (this.agent()?.worksOnSubjectTypes ?? [])\n .filter(id => !id.startsWith('nh-') && !catalog.some(type => type.id === id))\n .map(id => ({ id, name: id, pluralName: null as string | null }));\n return [...registered, ...stored];\n });\n readonly agentPolicies = computed(() => this.catalog()?.agentPolicies ?? []);\n /** The groups of agents the application registers, which boards show. */\n readonly agentGroups = computed(() => this.catalog()?.agentGroups ?? []);\n /** The groups the agent joins in code. */\n readonly codeGroups = computed(() => this.agent()?.codeGroups ?? []);\n /** A shadow variant works for administrators only and joins no group. */\n readonly isVariant = computed(() => !!this.agent()?.shadowOf);\n /** The server's refusal of the groups, as a translation key. */\n readonly groupsError = computed(() => this.fieldError('groups'));\n /** Per division is offered only when the application lists its divisions. */\n readonly divisionsListed = computed(() => this.catalog()?.divisions === true);\n /** The object types the agent is known to work on, by name, as a hint next to \"All objects\". */\n readonly knownTypes = computed(() => {\n const agent = this.agent();\n return agent ? worksOnSummary(agent, this.catalog()?.subjectTypes).known : [];\n });\n /** What the agent works on is edited here: an agent created here, while the run catalog is known. */\n readonly editsWorksOn = computed(() => this.choosesUse() && !this.catalogUnavailable());\n /** An agent created here chooses its profile from those the run catalog offers. */\n readonly choosesProfile = computed(() => this.choosesUse() && !this.catalogUnavailable());\n /** The profiles the run catalog offers, and the agent's own when the catalog no longer lists it. */\n readonly profileChoices = computed(() => {\n const listed = this.catalog()?.profiles ?? [];\n const current = this.agent()?.profile;\n return current && !listed.includes(current) ? [...listed, current] : listed;\n });\n /** Chosen object types without a type, and not the application either: the agent would work on nothing. */\n readonly worksOnMissing = computed(() =>\n this.editsWorksOn() && this.worksOnScope() === 'types' && this.worksOnTypes().length === 0 && !this.worksOnApplication());\n readonly tooManyTypes = computed(() =>\n this.editsWorksOn() && this.worksOnScope() === 'types' && this.worksOnTypes().length > maxWorksOnTypes);\n readonly policyKeys = policyKeys;\n readonly warningKeys = warningKeys;\n /** The warnings of the agent as it was saved, until this editor saves it again. */\n readonly warnings = computed(() => this.agent()?.warnings ?? []);\n readonly valid = computed(() => !this.idInvalid() && !this.nameMissing() && !this.tooLong() && !this.worksOnMissing() && !this.tooManyTypes());\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 toggleWorksOnType(typeId: string, checked: boolean): void {\n this.worksOnTypes.update(types => checked ? [...types.filter(type => type !== typeId), typeId] : types.filter(type => type !== typeId));\n }\n\n toggleGroup(groupId: string, checked: boolean): void {\n this.groups.update(groups => checked ? [...groups.filter(group => group !== groupId), groupId] : groups.filter(group => group !== groupId));\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 /** The first error the server reported for a field, as a translation key. */\n fieldError(field: string): string | null {\n const code = this.error()?.fieldErrors?.[field]?.[0];\n return code ? `nh-assistant.admin.run-config.field-errors.${code}` : null;\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.editing()!.id,\n displayName: keyOrText(this.displayName(), this.keyedName),\n description: keyOrText(this.description(), this.keyedDescription),\n instructions: this.instructions(),\n toolSelectors: this.toolSelectors(),\n mcpServerIds: this.mcpServerIds(),\n requiredPolicy: policy.length > 0 ? policy : null,\n autonomy: this.autonomy(),\n ...(this.choosesUse() ? { offeredInChat: this.use() !== 'background' } : {}),\n // Omitted, what the agent works on stays as it is; a new agent then works on every object type.\n ...(this.editsWorksOn() ? this.worksOnInput() : {}),\n ...(this.isNew() && !this.switchOnNow() ? { startsOff: true } : {}),\n // Omitted, the profile stays as it is; a new agent then uses the application's chat profile.\n ...(this.choosesProfile() && this.profile() !== '' ? { profile: this.profile() } : {}),\n // Sent only when it changes, so an agent without a classification keeps none.\n ...(this.choosesUse() && this.dataClassification() !== (this.editing()?.dataClassification ?? 'internal')\n ? { dataClassification: this.dataClassification() }\n : {})\n };\n const startsWork = this.agent() === null && this.use() !== 'chat';\n\n // An existing agent's groups are saved before its definition, a new agent's right after it is\n // created; a new agent whose groups failed is completed as an existing one by the next save.\n // Without the run catalog the groups are not shown, so they stay as they are.\n const existing = this.editing();\n const groups = this.catalogUnavailable() ? [...(existing?.groups ?? [])].sort() : [...this.groups()].sort();\n const groupsChanged = !sameGroups(groups, existing?.groups ?? []);\n const groupsSaved: Observable<AdminAgentGroups | null> = existing && groupsChanged && !this.isVariant()\n ? this.admin.setAgentGroups(existing.id, groups)\n : of(null);\n const request: Observable<AdminAgent> = existing\n ? groupsSaved.pipe(\n switchMap(membership => this.admin.updateAgent(existing.id, { ...input, expectedVersion: existing.version }).pipe(\n map(agent => withGroups(agent, membership)))))\n : this.admin.createAgent(input).pipe(\n tap(agent => this.created.set(agent)),\n switchMap(agent => groups.length > 0\n ? this.admin.setAgentGroups(agent.id, groups).pipe(map(membership => withGroups(agent, membership)))\n : of(agent)));\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 if (startsWork) {\n this.workRequested.emit(agent);\n } else {\n this.saved.emit(agent);\n }\n },\n error: (error: unknown) => {\n this.saving.set(false);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n /** What the agent works on, as the six fields the server reads together. */\n private worksOnInput(): Pick<AdminAgentInput,\n 'worksOnSubjectTypes' | 'worksOnAllSubjects' | 'worksOnApplication' | 'perDivision' | 'runPolicy' | 'viewPolicy'> {\n const all = this.worksOnScope() === 'all';\n return {\n worksOnSubjectTypes: all ? [] : [...this.worksOnTypes()].sort(),\n worksOnAllSubjects: all,\n worksOnApplication: this.worksOnApplication(),\n perDivision: this.divisionsListed() && this.perDivision(),\n runPolicy: this.runPolicy() || null,\n viewPolicy: this.viewPolicy() || null\n };\n }\n\n private reset(agent: AdminAgent | null): void {\n this.agentId.set(agent?.id ?? '');\n this.keyedName = agent?.source === 'code' ? this.keyed(agent.displayName) : null;\n this.keyedDescription = agent?.source === 'code' ? this.keyed(agent.description) : null;\n this.displayName.set(this.keyedName?.shown ?? agent?.displayName ?? '');\n this.description.set(this.keyedDescription?.shown ?? agent?.description ?? '');\n this.instructions.set(agent?.instructions ?? '');\n this.autonomy.set(agent?.autonomy ?? 'explain');\n this.use.set(agent?.offeredInChat === false ? 'background' : 'chat');\n this.switchOnNow.set(true);\n this.profile.set(agent?.source === 'admin' ? agent.profile ?? '' : '');\n this.dataClassification.set(agent?.source === 'admin' ? agent.dataClassification ?? 'internal' : 'internal');\n this.requiredPolicy.set(agent?.requiredPolicy ?? '');\n this.toolSelectors.set([...(agent?.toolSelectors ?? [])]);\n this.mcpServerIds.set([...(agent?.mcpServerIds ?? [])]);\n const worksOn = worksOnSummary(agent ?? {}, null);\n this.worksOnScope.set(worksOn.all ? 'all' : 'types');\n this.worksOnTypes.set([...(worksOn.all ? [] : agent?.worksOnSubjectTypes ?? [])]);\n this.worksOnApplication.set(worksOn.application);\n this.perDivision.set(worksOn.perDivision);\n this.runPolicy.set(worksOn.runPolicy ?? '');\n this.viewPolicy.set(worksOn.viewPolicy ?? '');\n this.groups.set([...(agent?.groups ?? [])]);\n this.created.set(null);\n this.submitted.set(false);\n this.error.set(null);\n }\n\n /** The translation of a key of an agent in code, or `null` when the text is not a key with a translation. */\n private keyed(text: string | null | undefined): KeyedText | null {\n if (!text) {\n return null;\n }\n const shown = this.translate.instant(text) as unknown;\n return typeof shown === 'string' && shown.length > 0 && shown !== text ? { key: text, shown } : null;\n }\n}\n\n/** Whether two sorted lists of group ids are the same. */\nfunction sameGroups(left: readonly string[], right: readonly string[]): boolean {\n const sorted = [...right].sort();\n return left.length === sorted.length && left.every((group, index) => group === sorted[index]);\n}\n\n/** The agent with the groups the server answered, or as it is without an answer. */\nfunction withGroups(agent: AdminAgent, membership: AdminAgentGroups | null): AdminAgent {\n return membership ? { ...agent, groups: membership.groups, codeGroups: membership.codeGroups } : agent;\n}\n\n/** The key of a text of an agent in code while the administrator kept its translation, otherwise the typed text. */\nfunction keyOrText(value: string, keyed: KeyedText | null): string {\n const text = value.trim();\n return keyed !== null && text === keyed.shown.trim() ? keyed.key : text;\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 @if (choosesUse()) {\n <fieldset class=\"subsection\" data-agent-use>\n <legend>{{ 'nh-assistant.admin.agent-editor.use.title' | translate }}</legend>\n <div class=\"uses\">\n @for (option of uses; track option) {\n <label class=\"use\" [class.selected]=\"use() === option\">\n <input type=\"radio\" [name]=\"id + '-use'\" [value]=\"option\" [checked]=\"use() === option\" (change)=\"use.set(option)\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.use.' + option | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.use.' + option + '-hint' | translate }}</span>\n </span>\n </label>\n }\n </div>\n @if (isNew() && use() !== 'chat') {\n <p class=\"hint\">{{ 'nh-assistant.admin.agent-editor.use.next' | translate }}</p>\n }\n @if (isNew()) {\n <label class=\"check described\" data-switch-on-now>\n <input type=\"checkbox\" [checked]=\"switchOnNow()\" (change)=\"switchOnNow.set(checked($event))\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.switch-on-now' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.switch-on-now-hint' | translate }}</span>\n </span>\n </label>\n }\n </fieldset>\n\n @if (catalogUnavailable()) {\n <!-- Without the run catalog the kinds of objects and policies are unknown: what the agent works on stays as it is. -->\n <p class=\"message warning\" role=\"note\" data-catalog-unavailable>\n <nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.agent-editor.catalog-unavailable' | translate }}\n </p>\n } @else {\n <fieldset\n class=\"subsection\"\n data-works-on\n [attr.aria-describedby]=\"id + '-works-on-hint ' + id + '-works-on-error'\"\n [attr.aria-invalid]=\"(submitted() && worksOnMissing()) || fieldError('worksOn') ? true : null\">\n <legend>{{ 'nh-assistant.admin.agent-editor.works-on.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-works-on-hint'\">{{ 'nh-assistant.admin.agent-editor.works-on.hint' | translate }}</p>\n <div class=\"uses\">\n <label class=\"use\" [class.selected]=\"worksOnScope() === 'all'\">\n <input type=\"radio\" [name]=\"id + '-works-on'\" value=\"all\" [checked]=\"worksOnScope() === 'all'\" (change)=\"worksOnScope.set('all')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.works-on.all' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.all-hint' | translate }}</span>\n </span>\n </label>\n <label class=\"use\" [class.selected]=\"worksOnScope() === 'types'\">\n <input type=\"radio\" [name]=\"id + '-works-on'\" value=\"types\" [checked]=\"worksOnScope() === 'types'\" (change)=\"worksOnScope.set('types')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.works-on.types' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.types-hint' | translate }}</span>\n </span>\n </label>\n </div>\n\n @if (worksOnScope() === 'types') {\n <div class=\"checks\" role=\"group\" [attr.aria-label]=\"'nh-assistant.admin.agent-editor.works-on.types' | translate\" data-works-on-types>\n @for (type of subjectTypes(); track type.id) {\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"worksOnTypes().includes(type.id)\" (change)=\"toggleWorksOnType(type.id, checked($event))\" />\n <span>{{ type.pluralName ?? type.name }} <span class=\"mono muted\">{{ type.id }}</span></span>\n </label>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.no-types' | translate }}</p>\n }\n </div>\n @if (fieldError('worksOnSubjectTypes'); as key) {\n <p class=\"hint\"><span class=\"error-text\">{{ key | translate }}</span></p>\n } @else if (tooManyTypes()) {\n <p class=\"hint\"><span class=\"error-text\">{{ 'nh-assistant.admin.agent-editor.works-on.too-many' | translate }}</span></p>\n }\n }\n\n @if (knownTypes().length > 0) {\n <p class=\"hint\" data-known-types>{{ 'nh-assistant.admin.agent-editor.works-on.known' | translate: { types: knownTypes().join(', ') } }}</p>\n }\n\n <label class=\"check described\">\n <input type=\"checkbox\" [checked]=\"worksOnApplication()\" (change)=\"worksOnApplication.set(checked($event))\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.works-on.application' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.application-hint' | translate }}</span>\n </span>\n </label>\n\n @if (divisionsListed()) {\n <label class=\"check described\" data-per-division>\n <input\n type=\"checkbox\"\n [checked]=\"perDivision()\"\n [attr.aria-invalid]=\"fieldError('perDivision') ? true : null\"\n [attr.aria-describedby]=\"fieldError('perDivision') ? id + '-per-division-error' : null\"\n (change)=\"perDivision.set(checked($event))\" />\n <span>\n <strong>{{ 'nh-assistant.admin.agent-editor.works-on.per-division' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.agent-editor.works-on.per-division-hint' | translate }}</span>\n </span>\n </label>\n @if (fieldError('perDivision'); as key) {\n <p class=\"hint\" [id]=\"id + '-per-division-error'\"><span class=\"error-text\">{{ key | translate }}</span></p>\n }\n }\n\n <p class=\"hint\" [id]=\"id + '-works-on-error'\" aria-live=\"polite\">\n @if (submitted() && worksOnMissing()) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.agent-editor.works-on.missing' | translate }}</span>\n } @else if (fieldError('worksOn'); as key) {\n <span class=\"error-text\">{{ key | translate }}</span>\n }\n </p>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-run-policy'\">{{ 'nh-assistant.admin.agent-editor.works-on.run-policy' | translate }}</label>\n <select\n [id]=\"id + '-run-policy'\"\n [attr.aria-describedby]=\"id + '-run-policy-hint'\"\n [attr.aria-invalid]=\"fieldError('runPolicy') ? true : null\"\n (change)=\"runPolicy.set(value($event))\">\n <option value=\"\" [selected]=\"runPolicy() === ''\">{{ 'nh-assistant.admin.agent-editor.works-on.run-policy-default' | translate }}</option>\n @for (policy of agentPolicies(); track policy.name) {\n <option [value]=\"policy.name\" [selected]=\"runPolicy() === policy.name\">{{ policyKeys(policy.name) | nhAssistantTranslate: policy.description }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-run-policy-hint'\">\n @if (fieldError('runPolicy'); as key) {\n <span class=\"error-text\">{{ key | translate }}</span>\n } @else {\n {{ 'nh-assistant.admin.agent-editor.works-on.run-policy-hint' | translate }}\n }\n </p>\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-view-policy'\">{{ 'nh-assistant.admin.agent-editor.works-on.view-policy' | translate }}</label>\n <select\n [id]=\"id + '-view-policy'\"\n [attr.aria-describedby]=\"id + '-view-policy-hint'\"\n [attr.aria-invalid]=\"fieldError('viewPolicy') ? true : null\"\n (change)=\"viewPolicy.set(value($event))\">\n <option value=\"\" [selected]=\"viewPolicy() === ''\">{{ 'nh-assistant.admin.agent-editor.works-on.view-policy-default' | translate }}</option>\n @for (policy of agentPolicies(); track policy.name) {\n <option [value]=\"policy.name\" [selected]=\"viewPolicy() === policy.name\">{{ policyKeys(policy.name) | nhAssistantTranslate: policy.description }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-view-policy-hint'\">\n @if (fieldError('viewPolicy'); as key) {\n <span class=\"error-text\">{{ key | translate }}</span>\n } @else {\n {{ 'nh-assistant.admin.agent-editor.works-on.view-policy-hint' | translate }}\n }\n </p>\n </div>\n </div>\n </fieldset>\n }\n }\n\n @if (agentGroups().length > 0 && !catalogUnavailable()) {\n <fieldset\n class=\"subsection\"\n data-agent-groups\n [attr.aria-describedby]=\"id + '-groups-hint ' + id + '-groups-error'\"\n [attr.aria-invalid]=\"groupsError() ? true : null\">\n <legend>{{ 'nh-assistant.admin.agent-editor.groups.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-groups-hint'\">{{ 'nh-assistant.admin.agent-editor.groups.hint' | translate }}</p>\n @if (isVariant()) {\n <p class=\"hint\" data-groups-variant>{{ 'nh-assistant.admin.agent-editor.groups.shadow-variant' | translate }}</p>\n } @else {\n <div class=\"checks\" role=\"group\" [attr.aria-label]=\"'nh-assistant.admin.agent-editor.groups.title' | translate\">\n @for (group of agentGroups(); track group.id) {\n <label class=\"check described\" [attr.data-agent-group]=\"group.id\">\n <input type=\"checkbox\" [checked]=\"groups().includes(group.id)\" (change)=\"toggleGroup(group.id, checked($event))\" />\n <span>\n <strong>{{ group.name }}</strong>\n @if (group.description; as description) {\n <span class=\"muted\">{{ description }}</span>\n }\n @if (codeGroups().includes(group.id)) {\n <span class=\"muted\" data-group-in-code>{{ 'nh-assistant.admin.agent-editor.groups.in-code' | translate }}</span>\n }\n </span>\n </label>\n }\n </div>\n }\n <p class=\"hint\" [id]=\"id + '-groups-error'\" aria-live=\"polite\">\n @if (groupsError(); as key) {\n <span class=\"error-text\">{{ key | translate }}</span>\n }\n </p>\n </fieldset>\n }\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\n @if (choosesProfile()) {\n <div class=\"field\" data-agent-profile>\n <label [for]=\"id + '-profile'\">{{ 'nh-assistant.admin.agent-editor.profile' | translate }}</label>\n <select\n [id]=\"id + '-profile'\"\n [attr.aria-describedby]=\"id + '-profile-hint' + (fieldError('profile') ? ' ' + id + '-profile-error' : '')\"\n [attr.aria-invalid]=\"fieldError('profile') ? true : null\"\n (change)=\"profile.set(value($event))\">\n @if (isNew()) {\n <option value=\"\" [selected]=\"profile() === ''\">{{ 'nh-assistant.admin.agent-editor.profile-default' | translate }}</option>\n }\n @for (name of profileChoices(); track name) {\n <option [value]=\"name\" [selected]=\"profile() === name\">{{ name }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-profile-hint'\">{{ 'nh-assistant.admin.agent-editor.profile-hint' | translate }}</p>\n @if (fieldError('profile'); as key) {\n <p class=\"hint\" [id]=\"id + '-profile-error'\"><span class=\"error-text\">{{ key | translate }}</span></p>\n }\n </div>\n }\n\n @if (choosesUse()) {\n <div class=\"field\" data-agent-classification>\n <label [for]=\"id + '-classification'\">{{ 'nh-assistant.admin.agent-editor.classification' | translate }}</label>\n <select\n [id]=\"id + '-classification'\"\n [attr.aria-describedby]=\"id + '-classification-hint' + (fieldError('dataClassification') ? ' ' + id + '-classification-error' : '')\"\n [attr.aria-invalid]=\"fieldError('dataClassification') ? true : null\"\n (change)=\"dataClassification.set($any(value($event)))\">\n @for (classification of classifications; track classification) {\n <option [value]=\"classification\" [selected]=\"dataClassification() === classification\">\n {{ 'nh-assistant.admin.run-config.skills.classification.' + classification | translate }}\n </option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-classification-hint'\">{{ 'nh-assistant.admin.agent-editor.classification-hint' | translate }}</p>\n @for (warning of warnings(); track warning) {\n <p class=\"message warning\" [attr.data-agent-editor-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('agent', warning) | nhAssistantTranslate: warning }}\n </p>\n }\n @if (fieldError('dataClassification'); as key) {\n <p class=\"hint\" [id]=\"id + '-classification-error'\"><span class=\"error-text\">{{ key | translate }}</span></p>\n }\n </div>\n }\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\n data-feedback-author\n [attr.title]=\"item.authorDisplayName ? ('nh-assistant.account-id-title' | translate: { id: item.authorActorId }) : null\">{{ 'nh-assistant.admin.feedback.author' | translate: { actor: item.authorDisplayName || ('nh-assistant.account-id' | translate: { id: 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 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 AgentRunFilter,\n AgentRunHistoryItem,\n AgentRunStatus,\n AgentSubjectType,\n NH_ASSISTANT_SYSTEM_SUBJECT_TYPE,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantCodeKeys as nhAssistantCodeKeys,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantSubjectLinkComponent as NhAssistantSubjectLinkComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantRunResultComponent } from '@newheap/platform-ai-chat/agent-runs';\n\nlet nextId = 0;\n\n/** The runs one page of the runs view loads. */\nconst pageSize = 20;\n\n/** The statuses a run can have, in the order the filter offers them. */\nconst statuses: readonly AgentRunStatus[] = ['completed', 'failed', 'cancelled', 'waiting-for-approval', 'running', 'queued'];\n\n/** A filter value as the form holds it: the empty string means \"any\". */\ninterface RunHistoryForm {\n subjectType: string;\n subjectId: string;\n status: AgentRunStatus | '';\n from: string;\n to: string;\n}\n\nconst emptyForm: RunHistoryForm = { subjectType: '', subjectId: '', status: '', from: '', to: '' };\n\n/** The filter fields the form shows; the server's errors of others stay with the form's error. */\nconst formFields = ['subjectType', 'subjectId', 'status', 'to'] as const;\n\n/**\n * The runs view of one agent for administrators (`GET admin/agents/{id}/runs`): every run of the\n * agent, shadow runs marked, newest first, filtered by the kind of object, one object, the whole\n * application, the status and the period. Per run its time, trigger, object, the beginning of its\n * result, its proposals, usage and duration; \"Show the result\" opens the run's whole result, its\n * proposals and its files in `nh-assistant-run-result`. The administration's agent cards open it with\n * \"Runs\". A filter the server refuses (`assistant-run-filter-invalid`) shows each refused part at its\n * field, and a run's failure reads as its translated code.\n */\n@Component({\n selector: 'nh-assistant-agent-run-history',\n standalone: true,\n imports: [\n DatePipe,\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantSubjectLinkComponent,\n NhAssistantRunResultComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-run-history.component.html',\n styleUrls: ['../nh-assistant-admin-shared.scss', './nh-assistant-agent-run-history.component.scss']\n})\nexport class NhAssistantAgentRunHistoryComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly injector = inject(Injector);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private subscription?: Subscription;\n\n /** The agent whose runs are shown. */\n readonly agentId = input.required<string>();\n /** The kinds of objects of the application, from the run catalog, to filter by. */\n readonly subjectTypes = input<readonly AgentSubjectType[]>([]);\n /** Emits the conversation of a run, so the host can open it in the assistant panel. */\n readonly openConversation = output<string>();\n\n readonly id = `nh-assistant-agent-run-history-${nextId++}`;\n readonly statuses = statuses;\n readonly systemType = NH_ASSISTANT_SYSTEM_SUBJECT_TYPE;\n /** The kinds of objects, the whole application left out: it has an option of its own. */\n readonly objectTypes = computed(() => this.subjectTypes().filter(type => !type.isSystem));\n readonly form = signal<RunHistoryForm>(emptyForm);\n /** The period ends before it starts. */\n readonly periodInvalid = signal(false);\n /** One object can be chosen once a kind of object is. */\n readonly objectChoosable = computed(() => {\n const type = this.form().subjectType;\n return type !== '' && type !== NH_ASSISTANT_SYSTEM_SUBJECT_TYPE;\n });\n readonly loading = signal(true);\n readonly loadingMore = signal(false);\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n /** The refused filter fields the form shows, with the server's first value per field. */\n readonly fieldErrors = computed<Partial<Record<string, string>>>(() => {\n const errors: Partial<Record<string, string>> = {};\n for (const field of formFields) {\n const value = this.error()?.fieldErrors?.[field]?.[0];\n if (value) {\n errors[field] = value;\n }\n }\n return errors;\n });\n readonly codeKeys = nhAssistantCodeKeys;\n readonly items = signal<AgentRunHistoryItem[]>([]);\n readonly total = signal(0);\n readonly page = signal(1);\n readonly hasMore = computed(() => this.items().length < this.total());\n /** The run whose whole result is shown instead of the list. */\n readonly opened = signal<AgentRunHistoryItem | null>(null);\n private applied: AgentRunFilter = {};\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n effect(() => {\n this.agentId();\n untracked(() => {\n this.opened.set(null);\n this.form.set(emptyForm);\n this.applied = {};\n this.fetch(1);\n });\n });\n }\n\n /** The text of the server's error of a filter field; a refused end of the period reads as such. */\n fieldErrorKeys(field: string): string[] {\n const value = this.fieldErrors()[field];\n if (!value) {\n return [];\n }\n const own = field === 'to' ? ['nh-assistant.admin.runs.period-invalid'] : [];\n return [...own, `nh-assistant.admin.run-config.field-errors.${value}`, 'nh-assistant.errors.generic'];\n }\n\n /** The ids a filter field describes itself with: its hint and its error while there is one. */\n describedBy(hintId: string | null, field: string): string | null {\n const ids = [hintId, this.fieldErrors()[field] ? `${this.id}-${field}-error` : null].filter((id): id is string => id !== null);\n return ids.length > 0 ? ids.join(' ') : null;\n }\n\n update(field: keyof RunHistoryForm, event: Event): void {\n const value = (event.target as HTMLInputElement | HTMLSelectElement).value;\n this.form.update(form => field === 'subjectType'\n // Another kind of object starts a new choice of object.\n ? { ...form, subjectType: value, subjectId: '' }\n : { ...form, [field]: value });\n if (field === 'from' || field === 'to') {\n this.periodInvalid.set(false);\n }\n }\n\n /** Reads the runs that match the form, from the first page. */\n apply(): void {\n const form = this.form();\n const from = form.from ? startOfDay(form.from) : undefined;\n // The last day counts in full: the period ends where the next day starts.\n const to = form.to ? startOfDay(form.to, 1) : undefined;\n if (from && to && Date.parse(to) <= Date.parse(from)) {\n this.periodInvalid.set(true);\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLInputElement>(`#${this.id}-to`)?.focus(), { injector: this.injector });\n return;\n }\n\n this.periodInvalid.set(false);\n this.applied = {\n subjectType: form.subjectType || undefined,\n subjectId: this.objectChoosable() ? form.subjectId.trim() || undefined : undefined,\n status: form.status || undefined,\n from,\n to\n };\n this.fetch(1);\n }\n\n /** Clears the filters and reads every run again. */\n clear(): void {\n this.form.set(emptyForm);\n this.periodInvalid.set(false);\n this.applied = {};\n this.fetch(1);\n }\n\n /** Narrows the view to the runs on the object of one run. */\n onlyObject(run: AgentRunHistoryItem): void {\n this.form.set({\n ...emptyForm,\n subjectType: run.subjectType,\n subjectId: run.subjectType === NH_ASSISTANT_SYSTEM_SUBJECT_TYPE ? '' : run.subjectId\n });\n this.apply();\n }\n\n loadMore(): void {\n this.fetch(this.page() + 1);\n }\n\n open(run: AgentRunHistoryItem): void {\n this.opened.set(run);\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLButtonElement>('[data-runs-back]')?.focus(), { injector: this.injector });\n }\n\n /** Returns to the list and to the result action of the run that was open. */\n close(): void {\n const runId = this.opened()?.id;\n this.opened.set(null);\n afterNextRender(() => {\n const action = Array.from(this.host.nativeElement.querySelectorAll<HTMLButtonElement>('[data-open-run]'))\n .find(item => item.dataset['openRun'] === runId);\n action?.focus();\n }, { injector: this.injector });\n }\n\n /** How long the run took, as a text key and its number; `null` while it runs. */\n durationOf(run: AgentRunHistoryItem): { key: string; value: number } | null {\n if (!run.startedAt || !run.endedAt) {\n return null;\n }\n\n const seconds = Math.max(0, Math.round((Date.parse(run.endedAt) - Date.parse(run.startedAt)) / 1000));\n return seconds < 120\n ? { key: 'nh-assistant.agent-runs.result.duration-seconds', value: seconds }\n : { key: 'nh-assistant.agent-runs.result.duration-minutes', value: Math.round(seconds / 60) };\n }\n\n /** Moves the focus to the first filter field the server refused. */\n private focusRefusedField(): void {\n if (Object.keys(this.fieldErrors()).length === 0) {\n return;\n }\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>('.filters [aria-invalid=\"true\"]')?.focus(), { injector: this.injector });\n }\n\n private fetch(page: number): void {\n const first = page === 1;\n this.loading.set(first);\n this.loadingMore.set(!first);\n this.error.set(null);\n this.subscription?.unsubscribe();\n this.subscription = this.admin.getAgentRuns(this.agentId(), { ...this.applied, page, itemsPerPage: pageSize }).subscribe({\n next: history => {\n this.items.update(items => first ? history.items : [...items, ...history.items]);\n this.total.set(history.total);\n this.page.set(page);\n this.loading.set(false);\n this.loadingMore.set(false);\n },\n error: (failure: unknown) => {\n if (first) {\n this.items.set([]);\n this.total.set(0);\n }\n this.loading.set(false);\n this.loadingMore.set(false);\n this.error.set(toNhAssistantError(failure));\n this.focusRefusedField();\n }\n });\n }\n}\n\n/** The start of a day of the person's calendar, plus some days, as an ISO 8601 time. */\nfunction startOfDay(date: string, plusDays = 0): string {\n const [year, month, day] = date.split('-').map(Number);\n return new Date(year, month - 1, day + plusDays).toISOString();\n}\n","@if (opened(); as run) {\n <div class=\"stack\">\n <div>\n <button class=\"secondary\" type=\"button\" data-runs-back (click)=\"close()\">\n {{ 'nh-assistant.admin.runs.back-to-runs' | translate }}\n </button>\n </div>\n <nh-assistant-run-result [runId]=\"run.id\" (openConversation)=\"openConversation.emit($event)\" />\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.runs.title' | translate }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.runs.description' | translate }}</p>\n </div>\n </header>\n\n <form class=\"filters\" [attr.aria-label]=\"'nh-assistant.admin.runs.filters' | translate\" (submit)=\"$event.preventDefault(); apply()\">\n <div class=\"field\">\n <label [for]=\"id + '-type'\">{{ 'nh-assistant.admin.runs.subject-type' | translate }}</label>\n <select\n [id]=\"id + '-type'\"\n [attr.aria-invalid]=\"fieldErrors()['subjectType'] ? true : null\"\n [attr.aria-describedby]=\"describedBy(null, 'subjectType')\"\n (change)=\"update('subjectType', $event)\">\n <option value=\"\" [selected]=\"form().subjectType === ''\">{{ 'nh-assistant.admin.runs.any-subject' | translate }}</option>\n <option [value]=\"systemType\" [selected]=\"form().subjectType === systemType\">{{ 'nh-assistant.admin.runs.whole-application' | translate }}</option>\n @for (type of objectTypes(); track type.id) {\n <option [value]=\"type.id\" [selected]=\"form().subjectType === type.id\">{{ type.pluralName ?? type.name }}</option>\n }\n </select>\n @if (fieldErrors()['subjectType']) {\n <p class=\"field-error\" [id]=\"id + '-subjectType-error'\"><nh-assistant-icon name=\"warning\" />{{ fieldErrorKeys('subjectType') | nhAssistantTranslate }}</p>\n }\n </div>\n @if (objectChoosable()) {\n <div class=\"field\">\n <label [for]=\"id + '-object'\">{{ 'nh-assistant.admin.runs.subject-id' | translate }}</label>\n <input\n type=\"text\"\n autocomplete=\"off\"\n maxlength=\"200\"\n [id]=\"id + '-object'\"\n [attr.aria-describedby]=\"describedBy(id + '-object-hint', 'subjectId')\"\n [attr.aria-invalid]=\"fieldErrors()['subjectId'] ? true : null\"\n [value]=\"form().subjectId\"\n (input)=\"update('subjectId', $event)\" />\n <p class=\"hint\" [id]=\"id + '-object-hint'\"><span>{{ 'nh-assistant.admin.runs.subject-id-hint' | translate }}</span></p>\n @if (fieldErrors()['subjectId']) {\n <p class=\"field-error\" [id]=\"id + '-subjectId-error'\"><nh-assistant-icon name=\"warning\" />{{ fieldErrorKeys('subjectId') | nhAssistantTranslate }}</p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-status'\">{{ 'nh-assistant.admin.runs.status' | translate }}</label>\n <select\n [id]=\"id + '-status'\"\n [attr.aria-invalid]=\"fieldErrors()['status'] ? true : null\"\n [attr.aria-describedby]=\"describedBy(null, 'status')\"\n (change)=\"update('status', $event)\">\n <option value=\"\" [selected]=\"form().status === ''\">{{ 'nh-assistant.admin.runs.any-status' | translate }}</option>\n @for (status of statuses; track status) {\n <option [value]=\"status\" [selected]=\"form().status === status\">{{ 'nh-assistant.agent-runs.run.status.' + status | translate }}</option>\n }\n </select>\n @if (fieldErrors()['status']) {\n <p class=\"field-error\" [id]=\"id + '-status-error'\"><nh-assistant-icon name=\"warning\" />{{ fieldErrorKeys('status') | nhAssistantTranslate }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-from'\">{{ 'nh-assistant.admin.runs.from' | translate }}</label>\n <input type=\"date\" [id]=\"id + '-from'\" [value]=\"form().from\" (change)=\"update('from', $event)\" />\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-to'\">{{ 'nh-assistant.admin.runs.to' | translate }}</label>\n <input\n type=\"date\"\n [id]=\"id + '-to'\"\n [value]=\"form().to\"\n [attr.aria-invalid]=\"periodInvalid() || fieldErrors()['to'] ? true : null\"\n [attr.aria-describedby]=\"periodInvalid() || fieldErrors()['to'] ? id + '-to-error' : null\"\n (change)=\"update('to', $event)\" />\n @if (periodInvalid()) {\n <p class=\"field-error\" role=\"alert\" [id]=\"id + '-to-error'\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.runs.period-invalid' | translate }}</p>\n } @else if (fieldErrors()['to']) {\n <p class=\"field-error\" [id]=\"id + '-to-error'\"><nh-assistant-icon name=\"warning\" />{{ fieldErrorKeys('to') | nhAssistantTranslate }}</p>\n }\n </div>\n <div class=\"filter-actions\">\n <button class=\"primary\" type=\"submit\" [disabled]=\"loading()\">{{ 'nh-assistant.admin.runs.apply' | translate }}</button>\n <button class=\"secondary\" type=\"button\" [disabled]=\"loading()\" (click)=\"clear()\">{{ 'nh-assistant.admin.runs.clear' | translate }}</button>\n </div>\n </form>\n\n @if (error(); as failure) {\n <div class=\"state\" role=\"alert\">\n <p>{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"apply()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n } @else if (loading()) {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (items().length === 0) {\n <p class=\"state\" data-runs-empty>{{ 'nh-assistant.admin.runs.empty' | translate }}</p>\n } @else {\n <p class=\"muted\" role=\"status\" data-runs-count>{{ 'nh-assistant.admin.runs.count' | translate: { shown: items().length, total: total() } }}</p>\n <ol class=\"cards\" [attr.aria-labelledby]=\"id + '-title'\">\n @for (run of items(); track run.id) {\n <li class=\"card\" [attr.data-run]=\"run.id\">\n <div class=\"card-header\">\n <strong><time [attr.datetime]=\"run.createdAt\">{{ run.createdAt | date: 'medium' }}</time></strong>\n <span\n class=\"badge\"\n [class.success]=\"run.status === 'completed'\"\n [class.warning]=\"run.status === 'waiting-for-approval' || run.status === 'queued' || run.status === 'running'\"\n [class.danger]=\"run.status === 'failed'\">{{ 'nh-assistant.agent-runs.run.status.' + run.status | translate }}</span>\n @if (run.shadow) {\n <span class=\"badge warning\" data-run-shadow>{{ 'nh-assistant.agent-runs.run.shadow' | translate }}</span>\n }\n @if (run.kind !== 'model') {\n <span class=\"badge\">{{ 'nh-assistant.agent-runs.run.kind.' + run.kind | translate }}</span>\n }\n <span class=\"mono muted\">{{ 'nh-assistant.agent-runs.run.trigger' | translate: { trigger: run.triggerId } }}</span>\n </div>\n <p class=\"run-subject\">\n <nh-assistant-subject-link\n [subjectType]=\"run.subjectType\"\n [subjectId]=\"run.subjectId\"\n [label]=\"run.subjectDisplayName ?? run.subjectId\"\n [typeName]=\"run.subjectTypeName\"\n [link]=\"run.subjectLink\" />\n </p>\n <!-- The beginning of the result is model output, shown as text. -->\n @if (run.result; as result) {\n <p class=\"run-preview\" data-run-preview>{{ result }}@if (run.resultTruncated) {…}</p>\n } @else {\n <p class=\"muted\">{{ 'nh-assistant.agent-runs.object-agents.no-result' | translate }}</p>\n }\n <div class=\"meta\">\n <span>{{ 'nh-assistant.agent-runs.run.proposals' | translate: { count: run.proposalCount } }}</span>\n <span>{{ 'nh-assistant.agent-runs.run.tool-calls' | translate: { count: run.toolCalls } }}</span>\n <span>{{ 'nh-assistant.agent-runs.run.tokens' | translate: { count: run.inputTokens + run.outputTokens } }}</span>\n @if (durationOf(run); as took) {\n <span data-run-duration>{{ took.key | translate: { count: took.value } }}</span>\n }\n @if (run.failureCode; as code) {\n <span data-run-failure>{{ codeKeys(code) | nhAssistantTranslate: code }}</span>\n }\n @if (run.mcpConnectionSkips?.length) {\n <span class=\"badge warning\" data-run-mcp-skips>{{ 'nh-assistant.agent-runs.run.mcp-skipped' | translate: { count: run.mcpConnectionSkips?.length } }}</span>\n }\n </div>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [attr.data-open-run]=\"run.id\" (click)=\"open(run)\">\n <nh-assistant-icon name=\"page\" />{{ 'nh-assistant.agent-runs.result.show' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" data-only-object (click)=\"onlyObject(run)\">\n <nh-assistant-icon name=\"list\" />{{ (run.subjectType === systemType ? 'nh-assistant.admin.runs.only-application' : 'nh-assistant.admin.runs.only-object') | translate }}\n </button>\n </div>\n </li>\n }\n </ol>\n @if (hasMore()) {\n <div>\n <button class=\"secondary\" type=\"button\" data-runs-more [disabled]=\"loadingMore()\" (click)=\"loadMore()\">\n {{ (loadingMore() ? 'nh-assistant.admin.loading' : 'nh-assistant.admin.runs.more') | translate }}\n </button>\n </div>\n }\n }\n </section>\n}\n","import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n untracked,\n viewChild\n} from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n AgentConsultationRouteState,\n AgentConsultationRouteSwitch,\n AgentConsultationRoutesState,\n AgentState,\n NhAssistantAdminApiService,\n NhAssistantConsultationRoute,\n NhAssistantError,\n SetAgentConsultationRoutesRequest,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAccountNames, NhAssistantAccountNamesErrorComponent } from '../nh-assistant-account-names';\n\nlet nextId = 0;\n\n/** The longest reason the server stores with a change of the routes. */\nconst maxReason = 500;\n\n/** The field of `POST admin/agents/{id}/consultation-routes` that switches each route. */\nconst requestFields: Readonly<Record<NhAssistantConsultationRoute, keyof Omit<SetAgentConsultationRoutesRequest, 'reason'>>> = {\n 'asker-decides': 'askerDecides',\n 'subject-agent-rights': 'subjectAgentRights',\n 'subject-asker-rights': 'subjectAskerRights'\n};\n\n/** A change of one route whose reason is being entered. */\ninterface RouteChange {\n route: NhAssistantConsultationRoute;\n action: AgentConsultationRouteSwitch;\n /** Whether code allows the route, which decides what returning to the code means. */\n allowed: boolean;\n}\n\n/**\n * The routes of an agent's consultations (internal to the run configuration's Consultations section):\n * when another assistant consults the agent and the agent proposes a change, a route says who decides\n * it and whose rights run it. Shown only for an agent that can be consulted\n * (`AgentState.consultationRoutes`), through a consultation in code or one defined as data. Each route\n * says whether it is on, whether that is what the consultations allow or an administrator's switch,\n * and when no consultation allows it, which keeps it off. Administrators switch a route off for all\n * consultations of the agent at once, or on, or back to what the consultations allow, each with an\n * optional reason; a refusal, such as a route no consultation allows any more, shows with the routes.\n * `refresh` reads the routes again after the consultations changed; `changed` emits the agent's state\n * after a change.\n */\n@Component({\n selector: 'nh-assistant-agent-consultation-routes',\n standalone: true,\n imports: [DatePipe, TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantAccountNamesErrorComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-consultation-routes.component.html',\n styleUrls: ['../nh-assistant-admin-shared.scss', './run-config/run-config-forms.scss']\n})\nexport class NhAssistantAgentConsultationRoutesComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly injector = inject(Injector);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly reasonInput = viewChild<ElementRef<HTMLInputElement>>('reasonInput');\n private loadSubscription?: Subscription;\n private actionSubscription?: Subscription;\n\n readonly agentId = input.required<string>();\n /** The object types of the run catalog, to name the types whose consultation allows a route. */\n readonly subjectTypes = input<readonly { id: string; name: string; pluralName?: string | null }[]>([]);\n /** Changes when the agent's consultations changed, so the routes they allow are read again. */\n readonly refresh = input(0);\n /** The agent's state after its routes changed. */\n readonly changed = output<AgentState>();\n\n readonly id = `nh-assistant-consultation-routes-${nextId++}`;\n readonly maxReason = maxReason;\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly busy = signal(false);\n /** The routes; `null` for an agent nobody can consult, which shows nothing. */\n readonly routes = signal<AgentConsultationRoutesState | null>(null);\n readonly changing = signal<RouteChange | null>(null);\n readonly reason = signal('');\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n /** The name of the administrator who changed the routes last, once known. */\n readonly accountNames = new NhAssistantAccountNames();\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.loadSubscription?.unsubscribe();\n this.actionSubscription?.unsubscribe();\n });\n effect(() => {\n this.agentId();\n this.refresh();\n untracked(() => this.load());\n });\n }\n\n load(): void {\n this.loading.set(true);\n this.loadFailed.set(false);\n this.loadSubscription?.unsubscribe();\n this.loadSubscription = this.admin.getAgentState(this.agentId()).subscribe({\n next: state => {\n this.show(state);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n /** The types whose consultation allows the route, by name. */\n typeNames(route: AgentConsultationRouteState): string {\n const names = new Map(this.subjectTypes().map(type => [type.id, type.pluralName ?? type.name]));\n return route.subjectTypes.map(type => names.get(type) ?? type).join(', ');\n }\n\n /** The switch of a route's main action: off for a route that is on, otherwise on. */\n switchOf(route: AgentConsultationRouteState): AgentConsultationRouteSwitch {\n return route.on ? 'off' : 'on';\n }\n\n /** The explanation of a change in its form: what dropping the switch means depends on whether a consultation allows the route. */\n explainKey(change: RouteChange): string {\n const action = change.action === 'code' ? (change.allowed ? 'code-on' : 'code-off') : change.action;\n return `nh-assistant.admin.agents.consultation-routes.explain-change.${action}`;\n }\n\n isChanging(route: NhAssistantConsultationRoute, action: AgentConsultationRouteSwitch): boolean {\n const change = this.changing();\n return change?.route === route && change.action === action;\n }\n\n /** Opens the reason form of a change of one route. A route no consultation allows cannot be switched on. */\n ask(route: AgentConsultationRouteState, action: AgentConsultationRouteSwitch): void {\n if (this.busy() || (action === 'on' && !route.allowed)) {\n return;\n }\n\n this.error.set(null);\n this.reason.set('');\n this.changing.set({ route: route.route, action, allowed: route.allowed });\n afterNextRender(() => this.reasonInput()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /** Closes the reason form and returns focus to the route's action. */\n cancel(): void {\n const change = this.changing();\n this.changing.set(null);\n if (change) {\n this.focusRoute(change.route);\n }\n }\n\n /**\n * Saves the change of the open form; the other routes keep their switch. The form stays open while\n * the server decides, and a refusal shows with the routes.\n */\n apply(): void {\n const change = this.changing();\n if (!change || this.busy()) {\n return;\n }\n\n const reason = this.reason().trim();\n const request: SetAgentConsultationRoutesRequest = {\n [requestFields[change.route]]: change.action,\n reason: reason.length > 0 ? reason : null\n };\n this.busy.set(true);\n this.error.set(null);\n this.actionSubscription?.unsubscribe();\n this.actionSubscription = this.admin.setConsultationRoutes(this.agentId(), request).subscribe({\n next: updated => {\n this.busy.set(false);\n this.changing.set(null);\n this.reason.set('');\n this.show(updated);\n this.changed.emit(updated);\n this.focusRoute(change.route);\n },\n error: (failure: unknown) => {\n this.busy.set(false);\n this.error.set(toNhAssistantError(failure));\n }\n });\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n\n private show(state: AgentState): void {\n this.routes.set(state.consultationRoutes ?? null);\n this.accountNames.load([state.consultationRoutes?.changedBy]);\n }\n\n private focusRoute(route: NhAssistantConsultationRoute): void {\n afterNextRender(() => {\n const action = this.host.nativeElement.querySelector<HTMLButtonElement>(`[data-route=\"${route}\"] [data-route-action]:not([disabled])`);\n action?.focus();\n }, { injector: this.injector });\n }\n}\n","@if (loadFailed()) {\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-title'\" data-consultation-routes>\n <header class=\"section-header\">\n <h5 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.agents.consultation-routes.title' | translate }}</h5>\n </header>\n <div class=\"state\" role=\"alert\">\n <p>{{ 'nh-assistant.admin.agents.consultation-routes.load-failed' | translate }}</p>\n <button class=\"secondary\" type=\"button\" (click)=\"load()\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </div>\n </section>\n} @else if (routes(); as current) {\n <!-- Only an agent that can be consulted has routes; its consultations allow them and administrators switch them off. -->\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || busy()\" data-consultation-routes>\n <header class=\"section-header\">\n <h5 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.agents.consultation-routes.title' | translate }}</h5>\n </header>\n <p class=\"muted\">{{ 'nh-assistant.admin.agents.consultation-routes.description' | translate }}</p>\n <nh-assistant-account-names-error [names]=\"accountNames\" />\n @if (current.changedAt) {\n <p class=\"muted\" data-routes-changed>\n <span [attr.title]=\"accountNames.idTitleOf(current.changedBy)\">{{ 'nh-assistant.admin.agents.state.changed' | translate: { user: accountNames.nameOf(current.changedBy), date: (current.changedAt | date: 'medium') } }}</span>\n @if (current.reason) {\n {{ 'nh-assistant.admin.agents.state.reason' | translate: { reason: current.reason } }}\n }\n </p>\n }\n\n <ul class=\"cards\">\n @for (route of current.routes; track route.route) {\n <li class=\"card\" [class.inactive]=\"!route.on\" [attr.data-route]=\"route.route\">\n <div class=\"card-header\">\n <strong [id]=\"id + '-' + route.route\">{{ 'nh-assistant.admin.agents.consultation-routes.route.' + route.route | translate }}</strong>\n <span class=\"badge\" [class.success]=\"route.on\" data-route-state>\n {{ (route.on ? 'nh-assistant.admin.agents.consultation-routes.on' : 'nh-assistant.admin.agents.consultation-routes.off') | translate }}\n </span>\n @if (!route.allowed) {\n <span class=\"badge\" data-route-source=\"not-allowed\">{{ 'nh-assistant.admin.agents.consultation-routes.not-allowed' | translate }}</span>\n } @else if (route.override === null) {\n <span class=\"badge\" data-route-source=\"code\">{{ 'nh-assistant.admin.agents.consultation-routes.code' | translate }}</span>\n } @else {\n <span class=\"badge warning\" data-route-source=\"override\">{{ 'nh-assistant.admin.agents.consultation-routes.overridden' | translate }}</span>\n }\n </div>\n <p class=\"muted\" data-route-explain>{{ 'nh-assistant.admin.agents.consultation-routes.explain.' + route.route | translate }}</p>\n @if (!route.allowed) {\n <p class=\"muted\" data-route-not-allowed [id]=\"id + '-' + route.route + '-not-allowed'\">\n {{ 'nh-assistant.admin.agents.consultation-routes.not-allowed-hint' | translate }}\n </p>\n } @else if (route.subjectTypes.length > 0) {\n <p class=\"muted\" data-route-types>{{ 'nh-assistant.admin.agents.consultation-routes.subject-types' | translate: { types: typeNames(route) } }}</p>\n }\n <div class=\"card-actions\">\n @let action = switchOf(route);\n <button\n class=\"secondary\"\n type=\"button\"\n [attr.data-route-action]=\"action\"\n [attr.aria-expanded]=\"isChanging(route.route, action)\"\n [attr.aria-describedby]=\"route.allowed ? null : id + '-' + route.route + '-not-allowed'\"\n [attr.aria-label]=\"('nh-assistant.admin.agents.consultation-routes.action.' + action | translate) + ': ' + ('nh-assistant.admin.agents.consultation-routes.route.' + route.route | translate)\"\n [disabled]=\"busy() || (action === 'on' && !route.allowed)\"\n (click)=\"ask(route, action)\">\n {{ 'nh-assistant.admin.agents.consultation-routes.action.' + action | translate }}\n </button>\n @if (route.override !== null) {\n <button\n class=\"secondary\"\n type=\"button\"\n data-route-action=\"code\"\n [attr.aria-expanded]=\"isChanging(route.route, 'code')\"\n [attr.aria-label]=\"('nh-assistant.admin.agents.consultation-routes.action.code' | translate) + ': ' + ('nh-assistant.admin.agents.consultation-routes.route.' + route.route | translate)\"\n [disabled]=\"busy()\"\n (click)=\"ask(route, 'code')\">\n {{ 'nh-assistant.admin.agents.consultation-routes.action.code' | translate }}\n </button>\n }\n </div>\n @if (changing(); as change) {\n @if (change.route === route.route) {\n <form class=\"stack\" data-route-form (submit)=\"$event.preventDefault(); apply()\">\n <p class=\"muted\">{{ explainKey(change) | translate }}</p>\n <div class=\"field\">\n <label [for]=\"id + '-' + route.route + '-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input\n #reasonInput\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"id + '-' + route.route + '-reason'\"\n [attr.aria-describedby]=\"id + '-' + route.route + '-reason-hint'\"\n [maxLength]=\"maxReason\"\n [value]=\"reason()\"\n (input)=\"reason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-' + route.route + '-reason-hint'\">{{ 'nh-assistant.admin.agents.state.note-hint' | translate }}</p>\n </div>\n <div class=\"card-actions\">\n <button type=\"submit\" class=\"primary\" [disabled]=\"busy()\">\n {{ 'nh-assistant.admin.agents.consultation-routes.confirm.' + change.action | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"cancel()\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n </div>\n </form>\n }\n }\n </li>\n }\n </ul>\n @if (error(); as failure) {\n <p class=\"form-error\" role=\"alert\" data-routes-error><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n </section>\n}\n","import { WritableSignal, signal } from '@angular/core';\nimport {\n ApprovalPolicySummary,\n AssistantDataClassification,\n FileLimits,\n LowerFileLimits,\n NhAssistantError,\n RunCatalog,\n ToolCatalogEntry,\n ɵNhAssistantPickerOption as NhAssistantPickerOption\n} from '@newheap/platform-ai-chat';\nimport { nhAssistantSelectorMatches } from '../nh-assistant-admin-agent-editor.component';\n\n/** The longest texts and numbers the server accepts in the run configuration. */\nexport const runConfigLimits = {\n reason: 500,\n description: 300,\n instructions: 20_000,\n message: 2_000,\n retries: [0, 10],\n concurrent: [1, 100],\n perSubject: [1, 1000],\n debounce: [0, 3600]\n} as const;\n\nexport const dashCase = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;\n\n/** A field error: a code such as `required`, with its translation parameters. */\nexport interface RunConfigFieldError {\n code: string;\n params?: Record<string, unknown>;\n}\n\nexport type RunConfigErrors = Record<string, RunConfigFieldError>;\n\n/** The translation key of a field error code, shared by the forms. */\nexport function fieldErrorKey(error: RunConfigFieldError | null | undefined): string | null {\n return error ? `nh-assistant.admin.run-config.field-errors.${error.code}` : null;\n}\n\n/**\n * The field errors of a refused save, by field; the server's codes are `required`, `invalid`,\n * `too-long` and `not-found`.\n */\nexport function serverFieldErrors(error: NhAssistantError | null): RunConfigErrors {\n const result: RunConfigErrors = {};\n for (const [field, codes] of Object.entries(error?.fieldErrors ?? {})) {\n if (codes.length > 0) {\n result[field] = { code: codes[0] };\n }\n }\n return result;\n}\n\n/** Requires text, optionally within a length. */\nexport function requireText(errors: RunConfigErrors, field: string, value: string, max?: number): void {\n const text = value.trim();\n if (text.length === 0) {\n errors[field] = { code: 'required' };\n } else if (max !== undefined && text.length > max) {\n errors[field] = { code: 'too-long', params: { max } };\n }\n}\n\n/** Accepts an empty value or a whole number within the range. */\nexport function checkWhole(errors: RunConfigErrors, field: string, value: string, min: number, max?: number, required = false): void {\n const text = value.trim();\n if (text.length === 0) {\n if (required) {\n errors[field] = { code: 'required' };\n }\n return;\n }\n const parsed = Number(text);\n if (!Number.isInteger(parsed) || parsed < min || (max !== undefined && parsed > max)) {\n errors[field] = max === undefined\n ? { code: 'at-least', params: { min } }\n : { code: 'between', params: { min, max } };\n }\n}\n\n/** A daily budget limits both tool calls and tokens, or neither. */\nexport function checkBudget(errors: RunConfigErrors, calls: string, tokens: string): void {\n checkWhole(errors, 'dailyToolCalls', calls, 1);\n checkWhole(errors, 'dailyTokens', tokens, 1);\n if ((calls.trim() === '') !== (tokens.trim() === '') && !errors['dailyToolCalls'] && !errors['dailyTokens']) {\n errors[calls.trim() === '' ? 'dailyToolCalls' : 'dailyTokens'] = { code: 'budget-pair' };\n }\n}\n\n/**\n * The server reports one `dailyBudget` error for both budget fields; the forms show it at the field\n * that is filled in least.\n */\nexport function withBudgetField(errors: RunConfigErrors, calls: string): RunConfigErrors {\n const budget = errors['dailyBudget'];\n if (!budget) {\n return errors;\n }\n const { dailyBudget: _, ...rest } = errors;\n return { ...rest, [calls.trim() === '' ? 'dailyToolCalls' : 'dailyTokens']: budget };\n}\n\n/**\n * Moves the focus to the first invalid control of a form, after Angular rendered the errors; a\n * picker's text field carries `aria-invalid` too.\n */\nexport function focusFirstInvalid(form: HTMLElement | null | undefined): void {\n const invalid = form?.querySelector<HTMLElement>('[aria-invalid=\"true\"]');\n invalid?.focus();\n invalid?.scrollIntoView?.({ block: 'center' });\n}\n\nexport function ruleOptions(catalog: RunCatalog | null): NhAssistantPickerOption[] {\n return (catalog?.ruleHandlers ?? []).map(block => ({ value: block.name, label: block.name, description: block.description }));\n}\n\n/** The platform's object type of the whole application. */\nexport const systemSubjectType = 'nh-system';\n\n/** What an agent works on, as far as the trigger events and schedules it is offered depend on it. */\nexport interface WorksOnStatement {\n worksOnSubjectTypes?: string[];\n worksOnAllSubjects?: boolean;\n worksOnApplication?: boolean;\n /** Its work for the whole application, such as a schedule without a subject set, runs once per division. */\n perDivision?: boolean;\n}\n\n/** Whether an agent works on subjects of the type, as the server's rule decides it. */\nexport function worksOnCovers(statement: WorksOnStatement | null | undefined, subjectType: string): boolean {\n if (subjectType === systemSubjectType) {\n return statement?.worksOnApplication === true;\n }\n if (subjectType.startsWith('nh-')) {\n return false;\n }\n return !statement || statement.worksOnAllSubjects !== false || (statement.worksOnSubjectTypes ?? []).includes(subjectType);\n}\n\n/**\n * The trigger events an agent can start on: an event that names its object type up front is offered\n * only to an agent that works on that type.\n */\nexport function eventOptions(catalog: RunCatalog | null, worksOn?: WorksOnStatement | null): NhAssistantPickerOption[] {\n return (catalog?.triggerEvents ?? [])\n .filter(block => !block.subjectType || worksOnCovers(worksOn, block.subjectType))\n .map(block => ({ value: block.name, label: block.name, description: block.description }));\n}\n\nexport function subjectSetOptions(catalog: RunCatalog | null): NhAssistantPickerOption[] {\n return (catalog?.subjectSets ?? []).map(block => ({ value: block.name, label: block.name, description: block.description }));\n}\n\n/**\n * What a schedule runs for each time: the whole application (once, or once per division for an\n * agent that works per division), or every object in a subject set.\n */\nexport type ScheduleTarget = 'application' | 'set';\n\n/**\n * The server refuses a schedule without a subject set with `subjectSet: required` when the agent\n * does not work on the whole application; a form that chose the whole application says why there.\n */\nexport function withScheduleTargetError(errors: RunConfigErrors, target: ScheduleTarget): RunConfigErrors {\n return target === 'application' && errors['subjectSet']\n ? { ...errors, subjectSet: { code: 'application-not-worked-on' } }\n : errors;\n}\n\n/** The data classifications a skill can choose, from the least to the most sensitive. */\nexport const dataClassifications: readonly AssistantDataClassification[] = ['public', 'internal', 'confidential', 'restricted'];\n\nexport function profileOptions(catalog: RunCatalog | null): NhAssistantPickerOption[] {\n return (catalog?.profiles ?? []).map(profile => ({ value: profile, label: profile }));\n}\n\n/** The approval policies, each with its summary when the server sent one. */\nexport function policyOptions(catalog: RunCatalog | null, describe: (summary: ApprovalPolicySummary) => string): NhAssistantPickerOption[] {\n const summaries = new Map((catalog?.approvalPolicySummaries ?? []).map(summary => [summary.name, summary]));\n return (catalog?.approvalPolicies ?? []).map(policy => {\n const summary = summaries.get(policy);\n return { value: policy, label: policy, description: summary ? describe(summary) : null };\n });\n}\n\n/** The IANA time zones of the browser, UTC first. */\nexport function timeZoneOptions(): NhAssistantPickerOption[] {\n const intl = Intl as unknown as { supportedValuesOf?: (key: string) => string[] };\n const zones = intl.supportedValuesOf?.('timeZone') ?? ['Europe/Amsterdam', 'Europe/London'];\n return ['UTC', ...zones.filter(zone => zone !== 'UTC')].map(zone => ({ value: zone, label: zone }));\n}\n\n/** Common schedules, as examples next to the cron field. */\nexport const cronExamples: readonly { cron: string; key: string }[] = [\n { cron: '0 8 * * 1-5', key: 'weekdays-8' },\n { cron: '0 7 * * *', key: 'daily-7' },\n { cron: '0 9 * * 1', key: 'monday-9' },\n { cron: '0 * * * *', key: 'hourly' }\n];\n\n/** One of the agent's tool selectors with what it offers, for the tool choice of a skill. */\nexport interface ToolChoice {\n selector: string;\n /** The tool's description, for a selector that names one tool of the catalog. */\n description: string | null;\n /** How many tools of the catalog a pattern matches; `null` for a single tool. */\n matches: number | null;\n}\n\n/** The agent's tool selectors with the description of their tool, or how many tools a pattern matches. */\nexport function toolChoices(selectors: readonly string[], catalog: readonly ToolCatalogEntry[]): ToolChoice[] {\n return selectors.map(selector => {\n if (selector.includes('*')) {\n return { selector, description: null, matches: catalog.filter(tool => nhAssistantSelectorMatches(tool.id, selector)).length };\n }\n const tool = catalog.find(item => item.id === selector);\n return { selector, description: tool?.description || null, matches: null };\n });\n}\n\nexport function blank(value: string): string | null {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nexport function toNumber(value: string): number | null {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n return null;\n }\n const parsed = Number(trimmed);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nexport function numberText(value: number | null | undefined): string {\n return value === null || value === undefined ? '' : String(value);\n}\n\n/** A readable id from a name: lowercase letters, digits and dashes. */\nexport function toDashCase(name: string): string {\n return name\n .normalize('NFKD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .replace(/^[0-9-]+/, '')\n .slice(0, 64)\n .replace(/-+$/, '');\n}\n\ntype Translate = (key: string, params?: Record<string, unknown>) => string;\n\n/**\n * An approval policy in one or two sentences: who decides, how long a proposal waits, whether the\n * run waits, and four eyes.\n */\nexport function describePolicy(summary: ApprovalPolicySummary, t: Translate): string {\n const base = 'nh-assistant.admin.run-config.policy-summary';\n const approvers = summary.approvers.map(approver => {\n switch (approver.kind) {\n case 'initiator':\n return t(`${base}.approver.initiator`);\n case 'subject-role':\n return approver.namedRole\n ? t(`${base}.approver.named-role`, { role: approver.namedRole })\n : t(`${base}.approver.subject-role.${approver.role ?? 'approver'}`);\n case 'policy':\n return t(`${base}.approver.policy`, { policy: approver.policy ?? '' });\n default:\n return approver.kind;\n }\n });\n const who = approvers.length === 0\n ? t(`${base}.nobody`)\n : t(`${base}.who`, { approvers: joinWithOr(approvers, t(`${base}.or`)) });\n const parts = [\n who,\n t(`${base}.wait`, { duration: describeDuration(summary.lifetimeMinutes, t) }),\n t(`${base}.mode.${summary.mode === 'deferred' ? 'deferred' : 'inline'}`)\n ];\n if (summary.fourEyes) {\n parts.push(t(`${base}.four-eyes`));\n }\n return parts.join(' ');\n}\n\nfunction joinWithOr(items: string[], or: string): string {\n return items.length <= 1 ? items.join('') : `${items.slice(0, -1).join(', ')} ${or} ${items[items.length - 1]}`;\n}\n\nfunction describeDuration(minutes: number, t: Translate): string {\n const base = 'nh-assistant.admin.run-config.policy-summary.duration';\n if (minutes >= 1440 && minutes % 1440 === 0) {\n const days = minutes / 1440;\n return t(days === 1 ? `${base}.day` : `${base}.days`, { count: days });\n }\n if (minutes >= 60 && minutes % 60 === 0) {\n const hours = minutes / 60;\n return t(hours === 1 ? `${base}.hour` : `${base}.hours`, { count: hours });\n }\n return t(minutes === 1 ? `${base}.minute` : `${base}.minutes`, { count: minutes });\n}\n\n/** The bytes of one megabyte, as the forms show a file size. */\nconst bytesPerMegabyte = 1024 * 1024;\n\n/** The lower file limits of an agent or a skill, as their fields name them on the server. */\nexport type FileLimitField = keyof FileLimits;\n\n/** The file limit fields in the order the forms show them. */\nexport const fileLimitFields: readonly FileLimitField[] = ['maxFileBytes', 'maxFilePages', 'maxFilesPerTurn', 'maxFileTokensPerTurn'];\n\n/** A size in megabytes as a form shows it: whole megabytes plainly, others with up to two decimals. */\nexport function megabytesText(bytes: number): string {\n const megabytes = bytes / bytesPerMegabyte;\n return Number.isInteger(megabytes) ? String(megabytes) : String(Math.round(megabytes * 100) / 100);\n}\n\n/**\n * The lower file limits of an agent or a skill as a form edits them: the largest file in megabytes,\n * the others as whole numbers; an empty field keeps the application's limit (for a skill, the\n * agent's). A size shown with decimals keeps its exact bytes until the administrator changes it.\n */\nexport class FileLimitsDraft {\n readonly megabytes = signal('');\n readonly pages = signal('');\n readonly files = signal('');\n readonly tokens = signal('');\n private loadedBytes: number | null = null;\n private loadedMegabytes = '';\n\n load(limits: LowerFileLimits | null | undefined): void {\n this.loadedBytes = limits?.maxFileBytes ?? null;\n this.loadedMegabytes = this.loadedBytes === null ? '' : megabytesText(this.loadedBytes);\n this.megabytes.set(this.loadedMegabytes);\n this.pages.set(numberText(limits?.maxFilePages));\n this.files.set(numberText(limits?.maxFilesPerTurn));\n this.tokens.set(numberText(limits?.maxFileTokensPerTurn));\n }\n\n /** The text of a field, by its server name. */\n text(field: FileLimitField): WritableSignal<string> {\n switch (field) {\n case 'maxFileBytes':\n return this.megabytes;\n case 'maxFilePages':\n return this.pages;\n case 'maxFilesPerTurn':\n return this.files;\n default:\n return this.tokens;\n }\n }\n\n /** Checks the fields against the application's limits, as the server does; only next to accepting files. */\n check(errors: RunConfigErrors, application: FileLimits | null | undefined): void {\n const bytes = this.bytes();\n if (this.megabytes().trim() !== '' && (bytes === null || bytes < 1 || (application && bytes > application.maxFileBytes))) {\n errors['maxFileBytes'] = application\n ? { code: 'megabytes-up-to', params: { max: megabytesText(application.maxFileBytes) } }\n : { code: 'megabytes-positive' };\n }\n checkWhole(errors, 'maxFilePages', this.pages(), 1, application?.maxFilePages);\n checkWhole(errors, 'maxFilesPerTurn', this.files(), 1, application?.maxFilesPerTurn);\n checkWhole(errors, 'maxFileTokensPerTurn', this.tokens(), 1, application?.maxFileTokensPerTurn);\n }\n\n /** The limits a save sends: none when the agent or skill accepts no files. */\n toRequest(acceptsFiles: boolean): Required<LowerFileLimits> {\n return {\n maxFileBytes: acceptsFiles ? this.bytes() : null,\n maxFilePages: acceptsFiles ? toNumber(this.pages()) : null,\n maxFilesPerTurn: acceptsFiles ? toNumber(this.files()) : null,\n maxFileTokensPerTurn: acceptsFiles ? toNumber(this.tokens()) : null\n };\n }\n\n private bytes(): number | null {\n const text = this.megabytes().trim();\n if (text === '') {\n return null;\n }\n if (text === this.loadedMegabytes && this.loadedBytes !== null) {\n return this.loadedBytes;\n }\n const megabytes = Number(text.replace(',', '.'));\n return Number.isFinite(megabytes) ? Math.round(megabytes * bytesPerMegabyte) : null;\n }\n}\n","import {\n AdminAgent,\n AgentAccountability,\n AgentRunConfiguration,\n DataTrigger,\n McpHeadlessUse,\n McpServer,\n RunCatalog,\n RunConfigurationProblem,\n ToolCatalogEffect,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport { nhAssistantSelectorMatches } from '../nh-assistant-admin-agent-editor.component';\nimport { systemSubjectType } from './run-config-shared';\n\n/**\n * The flow view of an agent: what it works on, when it runs, how it works, who it answers to, who\n * approves its proposals and its results. Each step summarizes what the run configuration, the agent\n * editor and the runs view hold and opens the form that changes it; the flow itself edits nothing.\n */\nexport type AgentFlowStepId = 'works-on' | 'when' | 'skills' | 'account' | 'approval' | 'results';\n\nexport const agentFlowSteps: readonly AgentFlowStepId[] = ['works-on', 'when', 'skills', 'account', 'approval', 'results'];\n\n/**\n * What an entry point of the flow opens: the run configuration opens its own forms; the agent editor,\n * the technical account, the runs view and the MCP servers belong to the page that hosts it.\n */\nexport type AgentFlowEntry =\n | { kind: 'setup' }\n | { kind: 'settings' }\n | { kind: 'add-skill' }\n | { kind: 'edit-skill'; skillId: string }\n | { kind: 'add-trigger' }\n | { kind: 'edit-trigger'; triggerId: string }\n | { kind: 'add-consultation' }\n | { kind: 'edit-consultation'; subjectType: string }\n | { kind: 'edit-agent' }\n | { kind: 'account' }\n | { kind: 'runs' }\n | { kind: 'mcp-servers' };\n\n/** Something in a step that no longer fits or keeps the agent from working, with the form that fixes it. */\nexport interface AgentFlowWarning {\n /** Translation key of the warning and its parameters. */\n key: string;\n params?: Record<string, unknown>;\n /** A second translation key that explains it, such as a problem's code. */\n detailKey?: string;\n /** The entry point that fixes it and the key of its label. */\n entry?: AgentFlowEntry;\n entryKey?: string;\n /** Tells several warnings with the same entry apart, for tracking. */\n id: string;\n}\n\n/**\n * What a trigger runs for each time it starts the agent: the whole application (once per division for\n * an agent that works per division), objects of a type (`value` names the type), every object of a\n * subject set (`value` names the set) or of a set in code, or the object the event names when it fires.\n */\nexport interface AgentFlowTarget {\n kind: 'application' | 'every-division' | 'type' | 'set' | 'code-set' | 'when-fired';\n value: string | null;\n}\n\n/** A trigger in code or as data, as the flow lists it. */\nexport interface AgentFlowTrigger {\n triggerId: string;\n origin: 'code' | 'data';\n source: 'event' | 'schedule' | 'webhook';\n /** The event, or the schedule with its time zone; `null` for a trigger in code. */\n detail: string | null;\n target: AgentFlowTarget;\n skillId: string | null;\n /** A trigger as data in shadow; `false` for a trigger in code, which follows the agent. */\n shadow: boolean;\n inEffect: boolean;\n}\n\n/** One tool of the agent's own tools, and where a run's proposals of it wait. */\nexport interface AgentFlowTool {\n id: string;\n description: string;\n effect: ToolCatalogEffect;\n /** The name of the object type a run places the tool's proposals at; `null` when it declares none. */\n placesAt: string | null;\n}\n\n/** The tools the agent's selectors choose from the catalog, without its MCP servers. */\nexport interface AgentFlowTools {\n tools: AgentFlowTool[];\n /** Tools the selectors choose beyond those listed. */\n more: number;\n /** Selectors that choose no tool of the catalog: those tools are no longer offered. */\n unmatched: string[];\n /** Whether the catalog was known; without it, the selectors are listed as they are. */\n known: boolean;\n}\n\n/**\n * Whether an MCP server's tools are offered in runs that start without a person, given the server's\n * background use and whom the agent answers to.\n */\nexport type AgentFlowServerUse =\n | 'unknown'\n | 'missing'\n | 'disabled'\n | 'never'\n | 'organization'\n | 'organization-grant'\n | 'personal'\n | 'personal-responsible'\n | 'personal-initiator'\n | 'personal-never-account'\n | 'personal-never-agent';\n\nexport interface AgentFlowServer {\n id: string;\n name: string;\n headlessUse: McpHeadlessUse | null;\n use: AgentFlowServerUse;\n}\n\n/** Whom an agent answers to, as its run settings (data) or its code say; `null` while unknown. */\nexport interface AgentFlowAccountability {\n accountability: AgentAccountability;\n delegateFromInitiator: boolean;\n}\n\n/**\n * Whether people can run the agent now, by the rule of runs by hand: it runs on its own, is neither\n * stopped nor disabled in code, has run settings and the run catalog names what it runs on.\n */\nexport type AgentFlowRunNow =\n | { available: true; paused: boolean }\n | { available: false; reason: 'stopped' | 'configured-off' | 'no-settings' | 'no-catalog' };\n\n/** The most tools the flow lists before it counts the rest. */\nexport const agentFlowToolLimit = 8;\n\n/** The run setting problems that concern the way of working or the approval instead of the account. */\nconst skillProblems = new Set(['unknown-rule-handler', 'unknown-profile']);\n\n/** Whom the agent answers to, from its run settings as data or from its code; `null` while unknown. */\nexport function flowAccountability(configuration: AgentRunConfiguration): AgentFlowAccountability | null {\n const settings = configuration.source === 'admin' ? configuration.runSettings : configuration.codeRunSettings;\n return settings ? { accountability: settings.accountability, delegateFromInitiator: settings.delegateFromInitiator } : null;\n}\n\n/** The step a problem of the run configuration concerns. */\nexport function problemStep(problem: RunConfigurationProblem): AgentFlowStepId {\n switch (problem.kind) {\n case 'trigger':\n case 'consultation':\n return 'when';\n case 'skill':\n case 'candidate':\n return 'skills';\n default:\n if (problem.code === 'unknown-policy') {\n return 'approval';\n }\n return skillProblems.has(problem.code) ? 'skills' : 'account';\n }\n}\n\n/**\n * A problem as a warning on its step, with the form that fixes it. A consultation's problem names its\n * subject type as the run catalog names it.\n */\nexport function problemWarning(problem: RunConfigurationProblem, configuration: AgentRunConfiguration, catalog: RunCatalog | null = null): AgentFlowWarning {\n const base = {\n id: `problem:${problem.kind}:${problem.id}:${problem.code}`,\n key: `nh-assistant.admin.run-config.problems.kind.${problem.kind}`,\n params: { id: problem.kind === 'consultation' ? typeName(catalog, problem.id) : problem.id },\n detailKey: `nh-assistant.admin.run-config.problems.code.${problem.code}`\n };\n switch (problem.kind) {\n case 'consultation':\n // A consultation the agent may no longer get can only be removed, below in the section.\n return (configuration.consultationCeiling ?? null) !== null\n && (configuration.dataConsultations ?? []).some(consultation => consultation.subjectType === problem.id)\n ? {\n ...base,\n entry: { kind: 'edit-consultation', subjectType: problem.id },\n entryKey: 'nh-assistant.admin.run-config.flow.entry.edit-consultation'\n }\n : base;\n case 'trigger':\n return configuration.dataTriggers.some(trigger => trigger.triggerId === problem.id)\n ? { ...base, entry: { kind: 'edit-trigger', triggerId: problem.id }, entryKey: 'nh-assistant.admin.run-config.flow.entry.edit-trigger' }\n : base;\n case 'skill':\n case 'candidate':\n return configuration.dataSkills.some(skill => skill.skillId === problem.id)\n ? { ...base, entry: { kind: 'edit-skill', skillId: problem.id }, entryKey: 'nh-assistant.admin.run-config.flow.entry.edit-skill' }\n : base;\n default:\n return configuration.source === 'admin' && configuration.runSettings\n ? { ...base, entry: { kind: 'settings' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.settings' }\n : base;\n }\n}\n\n/** The name of an object type as the run catalog gives it in the reader's language; the id otherwise. */\nexport function typeName(catalog: RunCatalog | null, subjectType: string, plural = false): string {\n const type = catalog?.subjectTypes?.find(item => item.id === subjectType);\n if (!type) {\n return subjectType;\n }\n return plural ? type.pluralName ?? type.name : type.name;\n}\n\n/** The triggers in code and as data with what each runs for. */\nexport function flowTriggers(configuration: AgentRunConfiguration, catalog: RunCatalog | null, agent: AdminAgent): AgentFlowTrigger[] {\n const application: AgentFlowTarget = { kind: agent.perDivision === true ? 'every-division' : 'application', value: null };\n const ofType = (subjectType: string | null | undefined, schedule: boolean): AgentFlowTarget => {\n if (subjectType === systemSubjectType) {\n return application;\n }\n if (subjectType) {\n return { kind: 'type', value: typeName(catalog, subjectType) };\n }\n return { kind: schedule ? 'code-set' : 'when-fired', value: null };\n };\n\n const code = configuration.codeTriggers.map((trigger): AgentFlowTrigger => ({\n triggerId: trigger.triggerId,\n origin: 'code',\n source: trigger.source,\n detail: null,\n target: ofType(trigger.subjectType, trigger.source === 'schedule'),\n skillId: trigger.skillId,\n shadow: false,\n inEffect: true\n }));\n const data = configuration.dataTriggers.map((trigger): AgentFlowTrigger => ({\n triggerId: trigger.triggerId,\n origin: 'data',\n source: trigger.source,\n detail: triggerDetail(trigger),\n target: trigger.source === 'event'\n ? ofType(catalog?.triggerEvents.find(block => block.name === trigger.event)?.subjectType, false)\n : trigger.subjectSet ? { kind: 'set', value: trigger.subjectSet } : application,\n skillId: trigger.skillId,\n shadow: trigger.shadow,\n inEffect: trigger.inEffect\n }));\n return [...code, ...data];\n}\n\nfunction triggerDetail(trigger: DataTrigger): string | null {\n return trigger.source === 'event' ? trigger.event : `${trigger.cron ?? ''} ${trigger.timeZone ?? 'UTC'}`.trim();\n}\n\n/**\n * The tools the agent's selectors choose from the catalog. MCP tools come from the agent's servers,\n * so the flow lists those per server; a selector that chooses only MCP tools still counts as matched.\n * Without a catalog the selectors stay as they are and nothing reads as missing.\n */\nexport function flowTools(\n selectors: readonly string[],\n catalog: readonly ToolCatalogEntry[],\n runCatalog: RunCatalog | null,\n limit = agentFlowToolLimit\n): AgentFlowTools {\n if (catalog.length === 0) {\n return { tools: [], more: 0, unmatched: [], known: false };\n }\n\n const chosen = new Map<string, ToolCatalogEntry>();\n const unmatched: string[] = [];\n for (const selector of selectors) {\n const matches = catalog.filter(tool => nhAssistantSelectorMatches(tool.id, selector));\n if (matches.length === 0) {\n unmatched.push(selector);\n }\n for (const tool of matches) {\n if (tool.source !== 'mcp') {\n chosen.set(tool.id, tool);\n }\n }\n }\n\n const tools = [...chosen.values()]\n .sort((left, right) => left.id.localeCompare(right.id))\n .map((tool): AgentFlowTool => ({\n id: tool.id,\n description: tool.description,\n effect: tool.effect,\n placesAt: tool.subjectType ? typeName(runCatalog, tool.subjectType) : null\n }));\n return { tools: tools.slice(0, limit), more: Math.max(0, tools.length - limit), unmatched, known: true };\n}\n\n/**\n * The agent's MCP servers with whether their tools are offered in runs that start without a person:\n * a server's background use (`never`, `organization`, `personal`) decides, and for `personal` also\n * whom the agent answers to. A run of an agent that answers to itself uses an organization's\n * credential only with a grant in code; a personal connection serves the person the run acts for,\n * with that person's consent, and never a technical account. Without the servers nothing is known.\n */\nexport function flowServers(\n serverIds: readonly string[],\n servers: readonly McpServer[] | null,\n accountability: AgentFlowAccountability | null\n): AgentFlowServer[] {\n return serverIds.map(id => {\n if (servers === null) {\n return { id, name: id, headlessUse: null, use: 'unknown' };\n }\n const server = servers.find(item => item.id === id);\n if (!server) {\n return { id, name: id, headlessUse: null, use: 'missing' };\n }\n return { id, name: server.displayName, headlessUse: server.headlessUse, use: serverUse(server, accountability) };\n });\n}\n\nfunction serverUse(server: McpServer, accountability: AgentFlowAccountability | null): AgentFlowServerUse {\n if (!server.isEnabled) {\n return 'disabled';\n }\n switch (server.headlessUse) {\n case 'organization':\n return accountability?.accountability === 'agent' ? 'organization-grant' : 'organization';\n case 'personal':\n return personalUse(accountability);\n default:\n return 'never';\n }\n}\n\nfunction personalUse(accountability: AgentFlowAccountability | null): AgentFlowServerUse {\n if (!accountability) {\n return 'personal';\n }\n switch (accountability.accountability) {\n case 'subject-responsible':\n return 'personal-responsible';\n case 'service-account':\n return accountability.delegateFromInitiator ? 'personal-initiator' : 'personal-never-account';\n default:\n return accountability.delegateFromInitiator ? 'personal-initiator' : 'personal-never-agent';\n }\n}\n\n/** Server uses that keep its tools out of runs that start without a person. */\nexport const unavailableServerUses: ReadonlySet<AgentFlowServerUse> = new Set([\n 'missing',\n 'disabled',\n 'never',\n 'personal-never-account',\n 'personal-never-agent'\n]);\n\n/**\n * Whether the agent can be run now, by the rule the server applies to runs by hand: it is neither\n * stopped nor disabled in code, an agent created here has run settings, and the run catalog names\n * what it runs on. A paused agent accepts the run, which waits until it is resumed; an agent that is\n * off runs it at once, because it only ignores the work it would take on by itself.\n */\nexport function flowRunNow(agent: AdminAgent, configuration: AgentRunConfiguration, catalog: RunCatalog | null): AgentFlowRunNow {\n if (agent.runState === 'configured-off') {\n return { available: false, reason: 'configured-off' };\n }\n if (agent.runState === 'stopped') {\n return { available: false, reason: 'stopped' };\n }\n if (configuration.source === 'admin' && configuration.runSettings === null) {\n return { available: false, reason: 'no-settings' };\n }\n if (catalog === null) {\n return { available: false, reason: 'no-catalog' };\n }\n return { available: true, paused: agent.runState === 'paused' };\n}\n","import {\n AgentAccountability,\n AgentRunConfiguration,\n AgentSubjectType,\n ApprovalPolicySummary,\n CodeConsultation,\n ConsultationCeiling,\n ConsultationSubjectRole,\n DataConsultation,\n NhAssistantConsultationRoute,\n RunCatalog\n} from '@newheap/platform-ai-chat';\nimport { WorksOnStatement, systemSubjectType, worksOnCovers } from './run-config-shared';\n\n/**\n * Consultations in the run configuration (AC20): other assistants consult an agent about a subject\n * type, through a consultation in code (read only) or one defined as data within the agent's ceiling\n * in code. These helpers decide what the Consultations section, its form and the flow view show.\n */\n\n/** The routes of a consultation's proposals, in the order the form offers them. */\nexport const consultationRoutes: readonly NhAssistantConsultationRoute[] = ['asker-decides', 'subject-asker-rights', 'subject-agent-rights'];\n\n/** The two routes at the subject, of which a consultation uses one at most. */\nexport const subjectRoutes: readonly NhAssistantConsultationRoute[] = ['subject-asker-rights', 'subject-agent-rights'];\n\n/** The roles a person may need on the subject, from the lowest. */\nexport const consultationRoles: readonly ConsultationSubjectRole[] = ['reader', 'participant', 'approver'];\n\n/** A limit of a consultation: its field, the bounds of `AllowConsultation` and the default of code. */\nexport interface ConsultationLimit {\n field: 'maxToolCalls' | 'timeoutSeconds' | 'maxAnswerChars' | 'maxHistoryMessages';\n /** The key of its name under `nh-assistant.admin.run-config.consultations.limits`. */\n key: string;\n min: number;\n max: number;\n initial: number;\n /** The ceiling's maximum of this limit. */\n ceiling: (ceiling: ConsultationCeiling) => number;\n}\n\n/** The limits a consultation defined as data sets, within the bounds of code and the ceiling. */\nexport const consultationLimits: readonly ConsultationLimit[] = [\n { field: 'maxToolCalls', key: 'tool-calls', min: 0, max: 32, initial: 4, ceiling: ceiling => ceiling.maxToolCalls },\n { field: 'timeoutSeconds', key: 'timeout-seconds', min: 1, max: 600, initial: 60, ceiling: ceiling => ceiling.maxTimeoutSeconds },\n { field: 'maxAnswerChars', key: 'answer-chars', min: 200, max: 32_000, initial: 4_000, ceiling: ceiling => ceiling.maxAnswerChars },\n { field: 'maxHistoryMessages', key: 'history-messages', min: 0, max: 200, initial: 20, ceiling: ceiling => ceiling.maxHistoryMessages }\n];\n\n/** The longest description of a consultation defined as data. */\nexport const maxConsultationDescription = 1_000;\n\n/** One consultation as the section and the flow list it: in code or defined as data. */\nexport interface ConsultationRow {\n subjectType: string;\n origin: 'code' | 'data';\n description: string | null;\n /** The routes in effect: those code allows, or those of the data that still fit. */\n routes: NhAssistantConsultationRoute[];\n /** It generates the request tool now. */\n requests: boolean;\n /** MCP clients see its tools. */\n mcp: boolean;\n consultToolId: string;\n /** The agents whose tool selectors select its consult tool now. */\n askingAgents: string[];\n inEffect: boolean;\n problems: string[];\n /** The consultation defined as data; `null` for one in code. */\n data: DataConsultation | null;\n code: CodeConsultation | null;\n}\n\n/** The agent's consultations in code and as data, by subject type. */\nexport function consultationRows(configuration: AgentRunConfiguration): ConsultationRow[] {\n const code = (configuration.codeConsultations ?? []).map((consultation): ConsultationRow => ({\n subjectType: consultation.subjectType,\n origin: 'code',\n description: consultation.description,\n routes: [...consultation.allowedRoutes],\n requests: consultation.allowRequests,\n mcp: consultation.exposure.includes('mcp'),\n consultToolId: consultation.consultToolId,\n askingAgents: consultation.askingAgents,\n inEffect: true,\n problems: [],\n data: null,\n code: consultation\n }));\n const data = (configuration.dataConsultations ?? []).map((consultation): ConsultationRow => ({\n subjectType: consultation.subjectType,\n origin: 'data',\n description: consultation.description,\n routes: [...consultation.routesInEffect],\n requests: consultation.requestToolId !== null,\n mcp: consultation.inEffect && consultation.exposeToMcp && !consultation.problems.includes('mcp-not-allowed'),\n consultToolId: consultation.consultToolId,\n askingAgents: consultation.askingAgents,\n inEffect: consultation.inEffect,\n problems: consultation.problems.length > 0 ? consultation.problems : consultation.problem ? [consultation.problem] : [],\n data: consultation,\n code: null\n }));\n return [...code, ...data].sort((left, right) => left.subjectType.localeCompare(right.subjectType));\n}\n\n/**\n * Why administrators cannot add a consultation to the agent now, or `null` when they can:\n * `application` when the application does not let them define consultations, `agent` when the agent\n * is in code and not consultable as data, `needs-settings` while an agent created here has no run\n * settings, `limit` when it has as many as the ceiling allows, and `no-types` when every kind of\n * object it works on already has a consultation.\n */\nexport type ConsultationsClosed = 'application' | 'agent' | 'needs-settings' | 'limit' | 'no-types';\n\nexport function consultationsClosed(\n configuration: AgentRunConfiguration,\n catalog: RunCatalog | null,\n worksOn: WorksOnStatement | null\n): ConsultationsClosed | null {\n const ceiling = configuration.consultationCeiling ?? null;\n if (ceiling === null) {\n return configuration.source === 'code' && (catalog?.consultationCeiling ?? null) !== null ? 'agent' : 'application';\n }\n if (configuration.source === 'admin' && configuration.runSettings === null) {\n return 'needs-settings';\n }\n if ((configuration.dataConsultations ?? []).length >= ceiling.maxConsultations) {\n return 'limit';\n }\n return catalog?.subjectTypes && consultationTypeOptions(catalog, worksOn, consultationRows(configuration).map(row => row.subjectType)).length === 0\n ? 'no-types'\n : null;\n}\n\n/**\n * The subject types a new consultation can be about: those the agent works on, the whole application\n * included, that it has no consultation about yet.\n */\nexport function consultationTypeOptions(\n catalog: RunCatalog | null,\n worksOn: WorksOnStatement | null,\n taken: readonly string[]\n): AgentSubjectType[] {\n return (catalog?.subjectTypes ?? []).filter(type => worksOnCovers(worksOn, type.id) && !taken.includes(type.id));\n}\n\n/**\n * Whether the run configuration has a Consultations section: the agent has consultations, in code or\n * as data, or the application lets administrators define consultations, so the section either offers\n * them or says why this agent cannot get any. An application without consultations as data shows no\n * section for an agent nobody can consult, as before.\n */\nexport function showsConsultations(configuration: AgentRunConfiguration, catalog: RunCatalog | null): boolean {\n return (configuration.codeConsultations ?? []).length > 0\n || (configuration.dataConsultations ?? []).length > 0\n || (configuration.consultationCeiling ?? null) !== null\n || (catalog?.consultationCeiling ?? null) !== null;\n}\n\n/**\n * Why a route cannot be chosen for a consultation of this agent, or `null`: the ceiling does not name\n * it, the route with the agent's own rights is never for the whole application, and it needs an agent\n * with rights of its own to lend: not one that answers to the subject's responsible person, and not\n * one created here that answers for itself, which has no grants.\n */\nexport type ConsultationRouteBlock = 'not-in-ceiling' | 'system' | 'agent-answers-to-person' | 'agent-has-no-rights';\n\nexport function consultationRouteBlock(\n route: NhAssistantConsultationRoute,\n ceiling: ConsultationCeiling,\n subjectType: string,\n agent: { source: 'code' | 'admin'; accountability: AgentAccountability | null }\n): ConsultationRouteBlock | null {\n if (!ceiling.routes.includes(route)) {\n return 'not-in-ceiling';\n }\n if (route !== 'subject-agent-rights') {\n return null;\n }\n if (subjectType === systemSubjectType) {\n return 'system';\n }\n if (agent.accountability === 'subject-responsible') {\n return 'agent-answers-to-person';\n }\n return agent.source === 'admin' && agent.accountability === 'agent' ? 'agent-has-no-rights' : null;\n}\n\n/** An approval policy lets only the person who caused a proposal decide it. */\nexport function initiatorOnly(summary: ApprovalPolicySummary | null | undefined): boolean {\n return !!summary && summary.approvers.length > 0 && summary.approvers.every(approver => approver.kind === 'initiator');\n}\n\n/** The approval policy the agent's own proposals use: its run settings as data, or its code. */\nexport function agentApprovalPolicy(configuration: AgentRunConfiguration): string | null {\n const settings = configuration.source === 'admin' ? configuration.runSettings : configuration.codeRunSettings;\n return settings?.approvalPolicy ?? null;\n}\n","import { DestroyRef, ElementRef, Injector, afterNextRender, computed, inject, signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { TranslateService } from '@ngx-translate/core';\nimport { Observable, Subscription, map, startWith } from 'rxjs';\nimport {\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport { RunConfigErrors, RunConfigFieldError, fieldErrorKey, focusFirstInvalid, serverFieldErrors } from './run-config-shared';\n\n/**\n * What the run configuration forms share: errors checked before sending and those the server\n * returns, each shown at its field, a form-level error next to the actions, and the focus on the\n * first invalid field after a refused save.\n */\nexport abstract class RunConfigForm {\n protected readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n protected readonly injector = inject(Injector);\n protected readonly translate = inject(TranslateService);\n private subscription?: Subscription;\n\n readonly busy = signal(false);\n readonly clientErrors = signal<RunConfigErrors>({});\n readonly serverError = signal<NhAssistantError | null>(null);\n /** Fields whose server error the administrator already corrected. */\n private readonly cleared = signal<ReadonlySet<string>>(new Set());\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.serverError()));\n\n /** The language, so computed texts follow a switch. */\n protected readonly language = toSignal(\n this.translate.onLangChange.pipe(map(event => event.lang), startWith(this.translate.currentLang)),\n { initialValue: this.translate.currentLang });\n\n /** The fields this form shows; server errors of other fields are listed with the form's error. */\n protected abstract readonly fields: readonly string[];\n\n readonly fieldErrors = computed<RunConfigErrors>(() => {\n const cleared = this.cleared();\n const server = Object.fromEntries(Object.entries(this.mapServerErrors(serverFieldErrors(this.serverError())))\n .filter(([field]) => !cleared.has(field)));\n return { ...server, ...this.clientErrors() };\n });\n\n /** Server errors of fields this form does not show, by name. */\n readonly otherFieldErrors = computed(() => Object.keys(serverFieldErrors(this.serverError()))\n .filter(field => !this.fields.includes(field) && field !== 'dailyBudget'));\n\n readonly hasErrors = computed(() => this.serverError() !== null || Object.keys(this.clientErrors()).length > 0);\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.subscription?.unsubscribe());\n }\n\n fieldError(field: string): RunConfigFieldError | null {\n return this.fieldErrors()[field] ?? null;\n }\n\n errorKey(field: string): string | null {\n return fieldErrorKey(this.fieldError(field));\n }\n\n /** The ids a control describes itself with: its hint and, when shown, its error. */\n describedBy(hintId: string | null, field: string, errorId: string): string | null {\n const ids = [hintId, this.fieldError(field) ? errorId : null].filter((id): id is string => id !== null);\n return ids.length > 0 ? ids.join(' ') : null;\n }\n\n /** Removes a field's error once the administrator changes it. */\n touch(field: string): void {\n if (this.clientErrors()[field]) {\n const { [field]: _, ...rest } = this.clientErrors();\n this.clientErrors.set(rest);\n }\n if (!this.cleared().has(field)) {\n this.cleared.set(new Set([...this.cleared(), field]));\n }\n }\n\n /** The server's codes for fields of other forms, such as a budget the server reports as one. */\n protected mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n return errors;\n }\n\n /**\n * Sends the request when `errors` is empty; otherwise shows them and focuses the first. A refused\n * request shows its errors the same way and calls `refused`; `done` receives the last value once\n * the request completed.\n */\n protected submit<T>(\n errors: RunConfigErrors,\n request: () => Observable<T>,\n done: (result: T) => void,\n refused?: () => void\n ): void {\n this.serverError.set(null);\n this.cleared.set(new Set());\n this.clientErrors.set(errors);\n if (Object.keys(errors).length > 0) {\n this.focusFirstInvalid();\n return;\n }\n this.busy.set(true);\n this.subscription?.unsubscribe();\n let last: T | undefined;\n this.subscription = request().subscribe({\n next: result => {\n last = result;\n },\n complete: () => {\n this.busy.set(false);\n done(last as T);\n },\n error: (error: unknown) => {\n this.busy.set(false);\n this.serverError.set(toNhAssistantError(error));\n refused?.();\n this.focusFirstInvalid();\n }\n });\n }\n\n protected focusFirstInvalid(): void {\n afterNextRender(() => {\n const form = this.host.nativeElement.querySelector<HTMLElement>('form');\n const invalid = form?.querySelector('[aria-invalid=\"true\"]');\n if (invalid) {\n focusFirstInvalid(form);\n } else {\n form?.querySelector<HTMLElement>('.form-error')?.scrollIntoView?.({ block: 'nearest' });\n }\n }, { injector: this.injector });\n }\n\n /** The translated text of a key, for computed descriptions. */\n protected t(key: string, params?: Record<string, unknown>): string {\n return this.translate.instant(key, params) as string;\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n\n checked(event: Event): boolean {\n return (event.target as HTMLInputElement).checked;\n }\n}\n","import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n AgentAccountability,\n AssistantDataClassification,\n ConsultationCeiling,\n ConsultationSubjectRole,\n DataConsultation,\n DataConsultationRequest,\n NhAssistantAdminApiService,\n NhAssistantConsultationRoute,\n RunCatalog,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantPickerOption as NhAssistantPickerOption,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe\n} from '@newheap/platform-ai-chat';\nimport { policyKeys } from '../agent-texts';\nimport {\n ConsultationLimit,\n ConsultationRouteBlock,\n consultationLimits,\n consultationRoles,\n consultationRouteBlock,\n consultationRoutes,\n consultationTypeOptions,\n initiatorOnly,\n maxConsultationDescription,\n subjectRoutes\n} from './consultations';\nimport { RunConfigForm } from './run-config-form';\nimport {\n RunConfigErrors,\n WorksOnStatement,\n blank,\n checkWhole,\n dataClassifications,\n describePolicy,\n numberText,\n policyOptions,\n requireText,\n runConfigLimits,\n toNumber\n} from './run-config-shared';\n\nlet nextId = 0;\n\n/** The fields under Advanced. */\nconst advancedFields: readonly string[] = [\n 'limits', 'maxToolCalls', 'timeoutSeconds', 'maxAnswerChars', 'maxHistoryMessages', 'allowRequests', 'exposeToMcp', 'dataClassification'\n];\n\n/** What a saved consultation form tells its host. */\nexport interface ConsultationFormSaved {\n consultation: DataConsultation;\n added: boolean;\n}\n\n/** A route as the form offers it, with why it cannot be chosen. */\ninterface RouteChoice {\n route: NhAssistantConsultationRoute;\n checked: boolean;\n block: ConsultationRouteBlock | null;\n}\n\n/**\n * Adds or changes a consultation defined as data (AC20): what other assistants may consult the agent\n * about and when (the subject type and a description for the asking model), what the agent keeps in\n * mind (instructions), who may ask (a role on the subject and a policy the application lists), what\n * it may do (only answer, or also propose with routes within the ceiling, with the role and approval\n * policy its proposals need) and, under Advanced, its limits within the ceiling, the request tool,\n * MCP and the classification of its answers. Routes and options the ceiling or the agent rule out are\n * shown disabled with the reason. A consultation is in effect once saved.\n */\n@Component({\n selector: 'nh-assistant-consultation-form',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantPickerComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-consultation-form.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantConsultationFormComponent extends RunConfigForm implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n\n readonly agentId = input.required<string>();\n readonly agentSource = input<'code' | 'admin'>('admin');\n readonly catalog = input<RunCatalog | null>(null);\n /** The agent's ceiling in code: the routes, requests, MCP and limits a consultation may use. */\n readonly ceiling = input.required<ConsultationCeiling>();\n /** What the agent works on: a consultation can only be about such subjects. */\n readonly worksOn = input<WorksOnStatement | null>(null);\n /** Whom the agent answers to, which decides whether it may lend its own rights; `null` while unknown. */\n readonly accountability = input<AgentAccountability | null>(null);\n /** The agent's own approval policy, which its proposals use without one of the consultation. */\n readonly agentApprovalPolicy = input<string | null>(null);\n /** The consultation to change; `null` adds one. */\n readonly consultation = input<DataConsultation | null>(null);\n /** The subject types the agent already has a consultation about, in code or as data. */\n readonly takenTypes = input<readonly string[]>([]);\n readonly saved = output<ConsultationFormSaved>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-consultation-form-${nextId++}`;\n readonly maxReason = runConfigLimits.reason;\n readonly maxDescription = maxConsultationDescription;\n readonly roles = consultationRoles;\n protected readonly fields = [\n 'subjectType', 'description', 'instructions', 'minimumRole', 'askerPolicy', 'routes', 'proposalRole', 'proposalPolicy',\n 'limits', 'maxToolCalls', 'timeoutSeconds', 'maxAnswerChars', 'maxHistoryMessages', 'allowRequests', 'exposeToMcp',\n 'dataClassification', 'reason'\n ];\n\n readonly subjectType = signal('');\n readonly description = signal('');\n readonly instructions = signal('');\n readonly minimumRole = signal<ConsultationSubjectRole>('reader');\n readonly askerPolicy = signal('');\n /** Only answer, or answer and propose with the routes chosen. */\n readonly mode = signal<'answer' | 'propose'>('answer');\n readonly routes = signal<readonly NhAssistantConsultationRoute[]>([]);\n readonly proposalRole = signal<ConsultationSubjectRole>('participant');\n readonly proposalPolicy = signal('');\n /** The limits as typed, by field; empty starts at the code's default within the ceiling. */\n readonly limits = signal<Record<ConsultationLimit['field'], string>>({ maxToolCalls: '', timeoutSeconds: '', maxAnswerChars: '', maxHistoryMessages: '' });\n readonly allowRequests = signal(false);\n readonly exposeToMcp = signal(false);\n readonly dataClassification = signal('');\n readonly reason = signal('');\n /** Advanced is open: the administrator opened it, or one of its fields has an error to show. */\n readonly advancedOpen = signal(false);\n\n readonly editing = computed(() => this.consultation() !== null);\n readonly maxInstructions = computed(() => this.ceiling().maxInstructionsLength);\n /** The subject being chosen or changed. */\n readonly chosenType = computed(() => this.consultation()?.subjectType ?? this.subjectType());\n /** The name of the subject type, as the run catalog names it. */\n readonly typeName = computed(() => {\n const type = this.chosenType();\n return this.catalog()?.subjectTypes?.find(item => item.id === type)?.name ?? type;\n });\n /** The types the agent works on and has no consultation about yet, the whole application included. */\n readonly typeOptions = computed<NhAssistantPickerOption[]>(() => consultationTypeOptions(this.catalog(), this.worksOn(), this.takenTypes())\n .map(type => ({ value: type.id, label: type.name, description: type.isSystem ? null : type.pluralName ?? null })));\n /** The ceiling allows routes, so the consultation may propose. */\n readonly mayPropose = computed(() => this.ceiling().routes.length > 0);\n readonly routeChoices = computed<RouteChoice[]>(() => {\n const chosen = this.routes();\n const agent = { source: this.agentSource(), accountability: this.accountability() };\n return consultationRoutes.map(route => ({\n route,\n checked: chosen.includes(route),\n block: consultationRouteBlock(route, this.ceiling(), this.chosenType(), agent)\n }));\n });\n /** The policies the application lists for askers, by the application's name for each when it has one. */\n readonly askerPolicies = computed<NhAssistantPickerOption[]>(() => {\n this.language();\n return (this.catalog()?.agentPolicies ?? []).map(policy => ({\n value: policy.name,\n label: this.policyName(policy.name),\n description: policy.description\n }));\n });\n readonly policies = computed(() => {\n this.language();\n return policyOptions(this.catalog(), summary => describePolicy(summary, (key, params) => this.t(key, params)));\n });\n /** The approval policy that decides the consultation's proposals: its own, or the agent's. */\n private readonly policySummary = computed(() => {\n const name = blank(this.proposalPolicy()) ?? this.agentApprovalPolicy();\n return name ? this.catalog()?.approvalPolicySummaries?.find(summary => summary.name === name) ?? null : null;\n });\n /**\n * What the approval policy means for the routes chosen: four eyes keeps the person who asked from\n * deciding their own proposal, and a policy of the initiator only leaves no approver for the route\n * with the agent's own rights.\n */\n readonly policyWarnings = computed(() => {\n if (this.mode() !== 'propose') {\n return [];\n }\n const summary = this.policySummary();\n const routes = this.routes();\n const warnings: string[] = [];\n if (summary?.fourEyes && routes.includes('asker-decides')) {\n warnings.push('four-eyes');\n }\n if (initiatorOnly(summary) && routes.includes('subject-agent-rights')) {\n warnings.push('initiator-only');\n }\n return warnings;\n });\n readonly limitFields = computed(() => consultationLimits.map(limit => ({\n ...limit,\n highest: Math.min(limit.max, limit.ceiling(this.ceiling())),\n placeholder: String(Math.min(limit.initial, limit.ceiling(this.ceiling())))\n })));\n readonly classifications = computed(() => {\n this.language();\n return dataClassifications.map(value => ({\n value,\n label: this.t(`nh-assistant.admin.run-config.skills.classification.${value}`),\n description: this.t(`nh-assistant.admin.run-config.skills.classification.${value}-hint`)\n }));\n });\n\n ngOnInit(): void {\n const consultation = this.consultation();\n this.subjectType.set(consultation?.subjectType ?? '');\n this.description.set(consultation?.description ?? '');\n this.instructions.set(consultation?.instructions ?? '');\n this.minimumRole.set(consultation?.minimumRole ?? 'reader');\n this.askerPolicy.set(consultation?.askerPolicy ?? '');\n this.routes.set([...(consultation?.routes ?? [])]);\n this.mode.set((consultation?.routes.length ?? 0) > 0 ? 'propose' : 'answer');\n this.proposalRole.set(consultation?.proposalRole ?? 'participant');\n this.proposalPolicy.set(consultation?.proposalPolicy ?? '');\n this.limits.set({\n maxToolCalls: numberText(consultation?.maxToolCalls),\n timeoutSeconds: numberText(consultation?.timeoutSeconds),\n maxAnswerChars: numberText(consultation?.maxAnswerChars),\n maxHistoryMessages: numberText(consultation?.maxHistoryMessages)\n });\n this.allowRequests.set(consultation?.allowRequests ?? false);\n this.exposeToMcp.set(consultation?.exposeToMcp ?? false);\n this.dataClassification.set(consultation?.dataClassification ?? '');\n }\n\n setSubjectType(subjectType: string): void {\n this.subjectType.set(subjectType);\n this.touch('subjectType');\n this.touch('routes');\n }\n\n /** Proposing starts with the first route the agent may use; answering only keeps the routes for later. */\n setMode(mode: 'answer' | 'propose'): void {\n this.mode.set(mode);\n this.touch('routes');\n if (mode === 'propose' && this.routes().length === 0) {\n const first = this.routeChoices().find(choice => choice.block === null);\n if (first) {\n this.routes.set([first.route]);\n }\n }\n }\n\n /** Chooses a route; of the two routes at the subject one at most, so choosing one drops the other. */\n toggleRoute(route: NhAssistantConsultationRoute, selected: boolean): void {\n this.routes.update(routes => {\n const others = routes.filter(item => item !== route && (!selected || !subjectRoutes.includes(route) || !subjectRoutes.includes(item)));\n return selected ? [...others, route] : others;\n });\n this.touch('routes');\n }\n\n setLimit(field: ConsultationLimit['field'], value: string): void {\n this.limits.update(limits => ({ ...limits, [field]: value }));\n this.touch(field);\n this.touch('limits');\n }\n\n /** The id of the text that says why a route cannot be chosen. */\n blockId(route: NhAssistantConsultationRoute): string {\n return `${this.id}-route-${route}-block`;\n }\n\n save(): void {\n const editing = this.consultation();\n const subjectType = editing?.subjectType ?? this.subjectType();\n const propose = this.mode() === 'propose';\n const routes = propose ? this.orderedRoutes() : [];\n const errors: RunConfigErrors = {};\n if (!editing && subjectType === '') {\n errors['subjectType'] = { code: 'required' };\n }\n requireText(errors, 'description', this.description(), this.maxDescription);\n if (this.instructions().length > this.maxInstructions()) {\n errors['instructions'] = { code: 'too-long', params: { max: this.maxInstructions() } };\n }\n if (propose && routes.length === 0) {\n errors['routes'] = { code: 'routes-required' };\n } else if (this.routeChoices().some(choice => choice.checked && choice.block !== null && propose)) {\n errors['routes'] = { code: 'not-allowed' };\n }\n for (const limit of this.limitFields()) {\n checkWhole(errors, limit.field, this.limits()[limit.field], limit.min, limit.highest);\n }\n\n const ceiling = this.ceiling();\n const request: DataConsultationRequest = {\n description: this.description().trim(),\n instructions: blank(this.instructions()),\n minimumRole: this.minimumRole(),\n askerPolicy: blank(this.askerPolicy()),\n routes,\n proposalRole: this.proposalRole(),\n proposalPolicy: propose ? blank(this.proposalPolicy()) : null,\n maxToolCalls: toNumber(this.limits().maxToolCalls),\n timeoutSeconds: toNumber(this.limits().timeoutSeconds),\n maxAnswerChars: toNumber(this.limits().maxAnswerChars),\n maxHistoryMessages: toNumber(this.limits().maxHistoryMessages),\n // A choice the ceiling no longer allows is dropped, as the server would drop it.\n allowRequests: ceiling.allowRequests && this.allowRequests(),\n exposeToMcp: ceiling.allowMcp && this.exposeToMcp(),\n dataClassification: blank(this.dataClassification()) as AssistantDataClassification | null,\n expectedVersion: editing?.version ?? null,\n reason: blank(this.reason())\n };\n this.openAdvancedFor(Object.keys(errors));\n this.submit(\n errors,\n () => this.admin.saveDataConsultation(this.agentId(), subjectType, request),\n consultation => this.saved.emit({ consultation, added: editing === null }),\n () => this.openAdvancedFor(Object.keys(this.fieldErrors())));\n }\n\n isOpen(event: Event): boolean {\n return (event.target as HTMLDetailsElement).open;\n }\n\n /** Opens Advanced when one of its fields has an error, so the error and the focus can reach it. */\n private openAdvancedFor(fields: readonly string[]): void {\n if (fields.some(field => advancedFields.includes(field))) {\n this.advancedOpen.set(true);\n }\n }\n\n /** A policy's name as the application translates it, or the policy itself. */\n private policyName(policy: string): string {\n const [key] = policyKeys(policy);\n const translated = this.t(key);\n return translated && translated !== key ? translated : policy;\n }\n\n /** The chosen routes in the order the form offers them. */\n private orderedRoutes(): NhAssistantConsultationRoute[] {\n const chosen = this.routes();\n return consultationRoutes.filter(route => chosen.includes(route));\n }\n}\n","<form class=\"stack card\" data-form=\"consultation\" novalidate (submit)=\"$event.preventDefault(); save()\">\n <h5>\n @if (consultation(); as current) {\n {{ 'nh-assistant.admin.run-config.consultations.form.edit-title' | translate: { type: typeName(), version: current.version } }}\n } @else {\n {{ 'nh-assistant.admin.run-config.consultations.form.new-title' | translate }}\n }\n </h5>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.consultations.form.what' | translate }}</legend>\n @if (!editing()) {\n <div class=\"field\">\n <label [for]=\"id + '-type'\">{{ 'nh-assistant.admin.run-config.consultations.form.subject-type' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-type'\"\n [options]=\"typeOptions()\"\n [value]=\"subjectType()\"\n [placeholder]=\"'nh-assistant.admin.run-config.choose' | translate\"\n [invalid]=\"fieldError('subjectType') !== null\"\n [describedBy]=\"describedBy(id + '-type-hint', 'subjectType', id + '-type-error')\"\n (valueChange)=\"setSubjectType($event)\" />\n <p class=\"hint\" [id]=\"id + '-type-hint'\">{{ 'nh-assistant.admin.run-config.consultations.form.subject-type-hint' | translate }}</p>\n @if (errorKey('subjectType'); as key) {\n <p class=\"field-error\" [id]=\"id + '-type-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('subjectType')?.params }}</p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-description'\">{{ 'nh-assistant.admin.run-config.consultations.form.description' | translate }}</label>\n <textarea rows=\"2\" [id]=\"id + '-description'\" [value]=\"description()\"\n [attr.aria-invalid]=\"fieldError('description') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-description-hint', 'description', id + '-description-error')\"\n (input)=\"description.set(value($event)); touch('description')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-description-hint'\">\n <span>{{ 'nh-assistant.admin.run-config.consultations.form.description-hint' | translate }}</span>\n <span class=\"counter\" [class.error-text]=\"description().length > maxDescription\">{{ 'nh-assistant.admin.characters' | translate: { count: description().length, max: maxDescription } }}</span>\n </p>\n @if (errorKey('description'); as key) {\n <p class=\"field-error\" [id]=\"id + '-description-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('description')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-instructions'\">{{ 'nh-assistant.admin.run-config.consultations.form.instructions' | translate }}</label>\n <textarea rows=\"4\" [id]=\"id + '-instructions'\" [value]=\"instructions()\"\n [attr.aria-invalid]=\"fieldError('instructions') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-instructions-hint', 'instructions', id + '-instructions-error')\"\n (input)=\"instructions.set(value($event)); touch('instructions')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-instructions-hint'\">\n <span>{{ 'nh-assistant.admin.run-config.consultations.form.instructions-hint' | translate }}</span>\n <span class=\"counter\" [class.error-text]=\"instructions().length > maxInstructions()\">{{ 'nh-assistant.admin.characters' | translate: { count: instructions().length, max: maxInstructions() } }}</span>\n </p>\n @if (errorKey('instructions'); as key) {\n <p class=\"field-error\" [id]=\"id + '-instructions-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('instructions')?.params }}</p>\n }\n </div>\n </fieldset>\n\n <fieldset class=\"group\" data-consultation-askers>\n <legend>{{ 'nh-assistant.admin.run-config.consultations.form.who' | translate }}</legend>\n <div class=\"field\">\n <span class=\"label\" [id]=\"id + '-minimum-role-label'\">{{ 'nh-assistant.admin.run-config.consultations.form.minimum-role' | translate }}</span>\n <div\n class=\"choices\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"id + '-minimum-role-label'\"\n [attr.aria-invalid]=\"fieldError('minimumRole') ? true : null\"\n [attr.aria-describedby]=\"describedBy(null, 'minimumRole', id + '-minimum-role-error')\">\n @for (role of roles; track role) {\n <label class=\"choice\" [class.selected]=\"minimumRole() === role\">\n <input type=\"radio\" [name]=\"id + '-minimum-role'\" [value]=\"role\" [checked]=\"minimumRole() === role\" (change)=\"minimumRole.set(role); touch('minimumRole')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.consultations.roles.' + role | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.consultations.form.role-hint.' + role | translate }}</span>\n </span>\n </label>\n }\n </div>\n @if (errorKey('minimumRole'); as key) {\n <p class=\"field-error\" [id]=\"id + '-minimum-role-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-asker-policy'\">{{ 'nh-assistant.admin.run-config.consultations.form.asker-policy' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-asker-policy'\"\n [options]=\"askerPolicies()\"\n [value]=\"askerPolicy()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.consultations.form.asker-policy-agent' | translate\"\n [invalid]=\"fieldError('askerPolicy') !== null\"\n [describedBy]=\"describedBy(id + '-asker-policy-hint', 'askerPolicy', id + '-asker-policy-error')\"\n (valueChange)=\"askerPolicy.set($event); touch('askerPolicy')\" />\n <p class=\"hint\" [id]=\"id + '-asker-policy-hint'\">{{ 'nh-assistant.admin.run-config.consultations.form.asker-policy-hint' | translate }}</p>\n @if (errorKey('askerPolicy'); as key) {\n <p class=\"field-error\" [id]=\"id + '-asker-policy-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('askerPolicy')?.params }}</p>\n }\n </div>\n </fieldset>\n\n <fieldset class=\"group\" data-consultation-proposals>\n <legend>{{ 'nh-assistant.admin.run-config.consultations.form.do' | translate }}</legend>\n <div class=\"choices\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.run-config.consultations.form.do' | translate\">\n <label class=\"choice\" [class.selected]=\"mode() === 'answer'\">\n <input type=\"radio\" [name]=\"id + '-mode'\" value=\"answer\" [checked]=\"mode() === 'answer'\" (change)=\"setMode('answer')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.consultations.form.answer' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.consultations.form.answer-hint' | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"mode() === 'propose'\">\n <input type=\"radio\" [name]=\"id + '-mode'\" value=\"propose\" data-mode=\"propose\" [checked]=\"mode() === 'propose'\" [disabled]=\"!mayPropose()\"\n [attr.aria-describedby]=\"mayPropose() ? null : id + '-propose-closed'\" (change)=\"setMode('propose')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.consultations.form.propose' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.consultations.form.propose-hint' | translate }}</span>\n </span>\n </label>\n </div>\n @if (!mayPropose()) {\n <p class=\"hint\" [id]=\"id + '-propose-closed'\" data-propose-closed>{{ 'nh-assistant.admin.run-config.consultations.form.answers-only' | translate }}</p>\n }\n\n @if (mode() === 'propose') {\n <!-- The routes as explained choices; one the ceiling or the agent rules out stays disabled with the reason. -->\n <fieldset class=\"field\" data-consultation-routes [attr.aria-describedby]=\"describedBy(id + '-routes-hint', 'routes', id + '-routes-error')\">\n <legend>{{ 'nh-assistant.admin.run-config.consultations.form.routes' | translate }}</legend>\n <p class=\"hint\" [id]=\"id + '-routes-hint'\">{{ 'nh-assistant.admin.run-config.consultations.form.routes-hint' | translate }}</p>\n <!-- In their own block: a label right under the field would take the field's label style. -->\n <div class=\"checks routes\">\n @for (choice of routeChoices(); track choice.route) {\n <label class=\"check described\" [attr.data-route-choice]=\"choice.route\" [class.blocked]=\"choice.block !== null\">\n <input\n type=\"checkbox\"\n [checked]=\"choice.checked\"\n [disabled]=\"choice.block !== null && !choice.checked\"\n [attr.aria-invalid]=\"fieldError('routes') || (choice.checked && choice.block !== null) ? true : null\"\n [attr.aria-describedby]=\"choice.block ? blockId(choice.route) : null\"\n (change)=\"toggleRoute(choice.route, checked($event))\" />\n <span>\n <span>{{ 'nh-assistant.admin.run-config.consultations.routes.' + choice.route | translate }}</span>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.consultations.routes-hint.' + choice.route | translate }}</span>\n @if (choice.block; as block) {\n <span class=\"error-text\" [id]=\"blockId(choice.route)\" [attr.data-route-block]=\"block\">{{ 'nh-assistant.admin.run-config.consultations.route-blocks.' + block | translate }}</span>\n }\n </span>\n </label>\n }\n </div>\n @if (errorKey('routes'); as key) {\n <p class=\"field-error\" [id]=\"id + '-routes-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('routes')?.params }}</p>\n }\n </fieldset>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-proposal-role'\">{{ 'nh-assistant.admin.run-config.consultations.form.proposal-role' | translate }}</label>\n <select [id]=\"id + '-proposal-role'\"\n [attr.aria-invalid]=\"fieldError('proposalRole') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-proposal-role-hint', 'proposalRole', id + '-proposal-role-error')\"\n (change)=\"proposalRole.set($any(value($event))); touch('proposalRole')\">\n @for (role of roles; track role) {\n <option [value]=\"role\" [selected]=\"proposalRole() === role\">{{ 'nh-assistant.admin.run-config.consultations.roles.' + role | translate }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-proposal-role-hint'\">{{ 'nh-assistant.admin.run-config.consultations.form.proposal-role-hint' | translate }}</p>\n @if (errorKey('proposalRole'); as key) {\n <p class=\"field-error\" [id]=\"id + '-proposal-role-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-proposal-policy'\">{{ 'nh-assistant.admin.run-config.approval-policy' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-proposal-policy'\"\n [options]=\"policies()\"\n [value]=\"proposalPolicy()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.consultations.form.agent-policy' | translate\"\n [invalid]=\"fieldError('proposalPolicy') !== null\"\n [describedBy]=\"describedBy(null, 'proposalPolicy', id + '-proposal-policy-error')\"\n (valueChange)=\"proposalPolicy.set($event); touch('proposalPolicy')\" />\n @if (errorKey('proposalPolicy'); as key) {\n <p class=\"field-error\" [id]=\"id + '-proposal-policy-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('proposalPolicy')?.params }}</p>\n }\n </div>\n </div>\n @for (warning of policyWarnings(); track warning) {\n <p class=\"message warning\" role=\"status\" [attr.data-policy-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.run-config.consultations.form.policy-warning.' + warning | translate }}\n </p>\n }\n }\n </fieldset>\n\n <details class=\"advanced\" data-consultation-advanced [open]=\"advancedOpen()\" (toggle)=\"advancedOpen.set(isOpen($event))\">\n <summary>{{ 'nh-assistant.admin.run-config.consultations.form.advanced' | translate }}</summary>\n <div class=\"stack\">\n <fieldset class=\"field\" data-consultation-limits [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'limits', id + '-limits-error')\">\n <legend>{{ 'nh-assistant.admin.run-config.consultations.form.limits' | translate }}</legend>\n <p class=\"hint\" [id]=\"id + '-limits-hint'\">{{ 'nh-assistant.admin.run-config.consultations.form.limits-hint' | translate }}</p>\n <div class=\"grid\">\n @for (limit of limitFields(); track limit.field) {\n <div class=\"field\">\n <label [for]=\"id + '-' + limit.field\">{{ 'nh-assistant.admin.run-config.consultations.limits.' + limit.key | translate }}</label>\n <input type=\"number\" inputmode=\"numeric\" [min]=\"limit.min\" [max]=\"limit.highest\" [id]=\"id + '-' + limit.field\" [value]=\"limits()[limit.field]\"\n [placeholder]=\"limit.placeholder\"\n [attr.aria-invalid]=\"fieldError(limit.field) || fieldError('limits') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-' + limit.field + '-hint', limit.field, id + '-' + limit.field + '-error')\"\n (input)=\"setLimit(limit.field, value($event))\" />\n <p class=\"hint\" [id]=\"id + '-' + limit.field + '-hint'\">{{ 'nh-assistant.admin.run-config.consultations.form.limit-range' | translate: { min: limit.min, max: limit.highest } }}</p>\n @if (errorKey(limit.field); as key) {\n <p class=\"field-error\" [id]=\"id + '-' + limit.field + '-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError(limit.field)?.params }}</p>\n }\n </div>\n }\n </div>\n @if (errorKey('limits'); as key) {\n <p class=\"field-error\" [id]=\"id + '-limits-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate }}</p>\n }\n </fieldset>\n\n <div class=\"field\" data-consultation-requests>\n @if (ceiling().allowRequests) {\n <!-- In its own block: a label right under the field would take the field's label style. -->\n <div class=\"checks\">\n <label class=\"check described\">\n <input type=\"checkbox\" [checked]=\"allowRequests()\" [attr.aria-invalid]=\"fieldError('allowRequests') ? true : null\"\n [attr.aria-describedby]=\"describedBy(null, 'allowRequests', id + '-requests-error')\"\n (change)=\"allowRequests.set(checked($event)); touch('allowRequests')\" />\n <span>\n <span>{{ 'nh-assistant.admin.run-config.consultations.form.requests' | translate }}</span>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.consultations.form.requests-hint' | translate }}</span>\n </span>\n </label>\n </div>\n } @else {\n <p class=\"muted\" data-requests-closed>{{ 'nh-assistant.admin.run-config.consultations.form.requests-closed' | translate }}</p>\n }\n @if (errorKey('allowRequests'); as key) {\n <p class=\"field-error\" [id]=\"id + '-requests-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate }}</p>\n }\n </div>\n <div class=\"field\" data-consultation-mcp>\n @if (ceiling().allowMcp) {\n <div class=\"checks\">\n <label class=\"check described\">\n <input type=\"checkbox\" [checked]=\"exposeToMcp()\" [attr.aria-invalid]=\"fieldError('exposeToMcp') ? true : null\"\n [attr.aria-describedby]=\"describedBy(null, 'exposeToMcp', id + '-mcp-error')\"\n (change)=\"exposeToMcp.set(checked($event)); touch('exposeToMcp')\" />\n <span>\n <span>{{ 'nh-assistant.admin.run-config.consultations.form.mcp' | translate }}</span>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.consultations.form.mcp-hint' | translate }}</span>\n </span>\n </label>\n </div>\n } @else {\n <p class=\"muted\" data-mcp-closed>{{ 'nh-assistant.admin.run-config.consultations.form.mcp-closed' | translate }}</p>\n }\n @if (errorKey('exposeToMcp'); as key) {\n <p class=\"field-error\" [id]=\"id + '-mcp-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-classification'\">{{ 'nh-assistant.admin.run-config.skills.classification.label' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-classification'\"\n [options]=\"classifications()\"\n [value]=\"dataClassification()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.skills.classification.agent' | translate\"\n [invalid]=\"fieldError('dataClassification') !== null\"\n [describedBy]=\"describedBy(id + '-classification-hint', 'dataClassification', id + '-classification-error')\"\n (valueChange)=\"dataClassification.set($event); touch('dataClassification')\" />\n <p class=\"hint\" [id]=\"id + '-classification-hint'\">{{ 'nh-assistant.admin.run-config.consultations.form.classification-hint' | translate }}</p>\n @if (errorKey('dataClassification'); as key) {\n <p class=\"field-error\" [id]=\"id + '-classification-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dataClassification')?.params }}</p>\n }\n </div>\n </div>\n </details>\n\n @if (!editing()) {\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.consultations.form.in-effect' | translate }}</p>\n }\n <div class=\"field\">\n <label [for]=\"id + '-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input type=\"text\" autocomplete=\"off\" [id]=\"id + '-reason'\" [maxLength]=\"maxReason\" [value]=\"reason()\" [attr.aria-describedby]=\"id + '-reason-hint'\" (input)=\"reason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-reason-hint'\">{{ 'nh-assistant.admin.run-config.note-hint' | translate }}</p>\n </div>\n\n @if (hasErrors()) {\n <div class=\"form-error\" role=\"alert\" data-form-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n @if (serverError(); as failure) {\n @if (failure.code === 'assistant-validation') {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n } @else {\n {{ errorKeys() | nhAssistantTranslate: failure.code }}\n }\n } @else {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n }\n @if (otherFieldErrors().length > 0) {\n <ul>\n @for (field of otherFieldErrors(); track field) {\n <li><span class=\"mono\">{{ field }}</span></li>\n }\n </ul>\n }\n </div>\n </div>\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]=\"busy()\">{{ (busy() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}</button>\n </div>\n</form>\n","import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n OnInit,\n computed,\n inject,\n input,\n output,\n signal\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport { Subscription, map, startWith } from 'rxjs';\nimport {\n AdminAgent,\n AgentRunConfiguration,\n AgentRunHistory,\n McpServer,\n NhAssistantAdminApiService,\n NhAssistantError,\n NhAssistantPanelService,\n RunCatalog,\n ToolCatalogEntry,\n ɵnhAssistantCodeKeys as nhAssistantCodeKeys,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantSubjectLinkComponent as NhAssistantSubjectLinkComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport {\n ɵNhAssistantRunNowDialogComponent as NhAssistantRunNowDialogComponent,\n type ɵNhAssistantRunNowAgent as NhAssistantRunNowAgent\n} from '@newheap/platform-ai-chat/agent-runs';\nimport { codeTextKeys, policyKeys, readableId, runNowAgentOf, skillDescriptionKeys, skillNameKeys, worksOnSummary } from '../agent-texts';\nimport {\n AgentFlowEntry,\n AgentFlowServerUse,\n AgentFlowStepId,\n AgentFlowWarning,\n agentFlowSteps,\n flowAccountability,\n flowRunNow,\n flowServers,\n flowTools,\n flowTriggers,\n problemStep,\n problemWarning,\n typeName,\n unavailableServerUses\n} from './agent-flow';\nimport { NhAssistantAccountLabelComponent } from '../../nh-assistant-account-names';\nimport { consultationRows, consultationsClosed } from './consultations';\nimport { describePolicy } from './run-config-shared';\n\nlet nextId = 0;\n\n/** The most recent runs the flow shows; the runs view lists the rest. */\nconst latestRunCount = 3;\n\n/** One approval policy with its sentence, of the agent or of one of its skills. */\ninterface FlowPolicy {\n /** The skill whose own policy it is; `null` for the agent's. */\n skillId: string | null;\n /** The policy's name; `null` for the application's default. */\n name: string | null;\n sentence: string | null;\n}\n\n/**\n * The flow view of an agent at the top of its run configuration: what it works on, when it runs (its\n * triggers with what each runs for, run now, and the consultations through which other assistants\n * consult it), how it works (its way of working, skills and tools, with where a run's proposals of\n * each tool wait and whether its MCP servers are used in runs without a person), whom it answers to,\n * who approves its proposals, and its results (its groups and latest runs). Problems show at the step\n * they concern with the entry point that fixes them. The flow edits nothing: every entry point opens\n * a form of the run configuration, or asks the page that hosts it to open the agent editor, the\n * technical account, the runs view or the MCP servers (`entry`). Run now opens the run-now dialog here.\n */\n@Component({\n selector: 'nh-assistant-agent-flow',\n standalone: true,\n imports: [\n DatePipe,\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantSubjectLinkComponent,\n NhAssistantRunNowDialogComponent,\n NhAssistantAccountLabelComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-flow.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss', './nh-assistant-agent-flow.component.scss']\n})\nexport class NhAssistantAgentFlowComponent implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly panel = inject(NhAssistantPanelService);\n private readonly translate = inject(TranslateService);\n private runsSubscription?: Subscription;\n\n readonly agent = input.required<AdminAgent>();\n readonly configuration = input.required<AgentRunConfiguration>();\n readonly catalog = input<RunCatalog | null>(null);\n /** The tool catalog; without it the agent's tools are listed by their selectors. */\n readonly tools = input<readonly ToolCatalogEntry[]>([]);\n /** The MCP servers; `null` while unknown, so nothing reads as missing. */\n readonly servers = input<readonly McpServer[] | null>(null);\n /** The name of the account the agent answers to, once known. */\n readonly accountName = input<string | null>(null);\n /** An action of the run configuration is busy; the entry points wait. */\n readonly busy = input(false);\n /** An entry point asks to open the form or view it summarizes. */\n readonly entry = output<AgentFlowEntry>();\n\n readonly id = `nh-assistant-agent-flow-${nextId++}`;\n readonly steps = agentFlowSteps;\n readonly skillNameKeys = skillNameKeys;\n readonly skillDescriptionKeys = skillDescriptionKeys;\n readonly policyKeys = policyKeys;\n readonly readableId = readableId;\n readonly codeKeys = nhAssistantCodeKeys;\n\n readonly runs = signal<AgentRunHistory | null>(null);\n readonly runsError = signal<NhAssistantError | null>(null);\n readonly runsErrorKeys = computed(() => nhAssistantErrorKeys(this.runsError()));\n readonly runsLoading = signal(false);\n /** The run-now dialog is open. */\n readonly runningNow = signal(false);\n\n private readonly language = toSignal(\n this.translate.onLangChange.pipe(map(event => event.lang), startWith(this.translate.currentLang)),\n { initialValue: this.translate.currentLang });\n\n readonly isAdmin = computed(() => this.configuration().source === 'admin');\n /** An agent created here gets skills and triggers once it has run settings. */\n readonly canAddRunData = computed(() => !this.isAdmin() || this.configuration().runSettings !== null);\n readonly worksOn = computed(() => {\n const summary = worksOnSummary(this.agent(), this.catalog()?.subjectTypes);\n return { ...summary, only: summary.all ? 'all' : summary.types.length > 0 ? 'types' : 'application' };\n });\n readonly triggers = computed(() => flowTriggers(this.configuration(), this.catalog(), this.agent()));\n /** When another assistant consults the agent: its consultations in code and as data. */\n readonly consultations = computed(() => consultationRows(this.configuration()));\n /** Administrators may add a consultation to the agent now. */\n readonly canAddConsultation = computed(() => consultationsClosed(this.configuration(), this.catalog(), this.agent()) === null);\n readonly runNow = computed(() => flowRunNow(this.agent(), this.configuration(), this.catalog()));\n /**\n * What people run the agent for by hand, as the run-now dialog offers it: the whole application (one\n * division at a time for an agent that works per division) and the objects it works on.\n */\n readonly runNowScopeKey = computed(() => {\n const works = this.worksOn();\n const objects = works.all || works.types.length > 0;\n const base = 'nh-assistant.admin.run-config.flow.when.scope.';\n if (!works.application) {\n return `${base}objects`;\n }\n return `${base}${works.perDivision ? 'division' : 'application'}${objects ? '-and-objects' : ''}`;\n });\n readonly runNowAgent = computed<NhAssistantRunNowAgent>(() => {\n this.language();\n return runNowAgentOf(this.agent(), this.agentName());\n });\n readonly agentName = computed(() => {\n this.language();\n const agent = this.agent();\n return this.translated(codeTextKeys(agent.source, agent.displayName), agent.displayName);\n });\n readonly accountability = computed(() => flowAccountability(this.configuration()));\n /** The way of working of the agent: fixed rules (named for an agent created here) or the model. */\n readonly wayOfWorking = computed(() => {\n const configuration = this.configuration();\n if (configuration.source === 'admin') {\n const settings = configuration.runSettings;\n if (!settings) {\n return null;\n }\n const rules = settings.ruleHandler;\n return rules\n ? { kind: 'rules' as const, name: rules, description: this.catalog()?.ruleHandlers.find(block => block.name === rules)?.description ?? null }\n : { kind: 'model' as const, name: null, description: null };\n }\n return configuration.codeRunSettings?.usesRules\n ? { kind: 'code-rules' as const, name: null, description: null }\n : { kind: 'model' as const, name: null, description: null };\n });\n readonly agentTools = computed(() => flowTools(this.configuration().toolSelectors, this.tools(), this.catalog()));\n readonly agentServers = computed(() => flowServers(this.agent().mcpServerIds, this.servers(), this.accountability()));\n /** The agent's approval policy and the skills' own, each with its sentence. */\n readonly policies = computed<FlowPolicy[]>(() => {\n this.language();\n const configuration = this.configuration();\n const policies: FlowPolicy[] = [];\n // The run settings as data, or how an agent in code runs; neither while an agent created here has none.\n const settings = configuration.source === 'admin' ? configuration.runSettings : configuration.codeRunSettings;\n if (settings) {\n policies.push({ skillId: null, name: settings.approvalPolicy, sentence: this.sentence(settings.approvalPolicy) });\n }\n for (const skill of configuration.dataSkills) {\n if (skill.approvalPolicy) {\n policies.push({ skillId: skill.skillId, name: skill.approvalPolicy, sentence: this.sentence(skill.approvalPolicy) });\n }\n }\n return policies;\n });\n /** The names of the groups the agent is in, as the run catalog names them. */\n readonly groups = computed(() => {\n const groups = this.catalog()?.agentGroups ?? [];\n return (this.agent().groups ?? []).map(id => groups.find(group => group.id === id)?.name ?? id);\n });\n /** Whether the agent can be put in groups: every agent except a shadow variant. */\n readonly groupable = computed(() => !this.agent().shadowOf);\n /** The warnings of each step: problems of the run configuration and what keeps the agent from working. */\n readonly warnings = computed<Record<AgentFlowStepId, AgentFlowWarning[]>>(() => {\n const configuration = this.configuration();\n const result: Record<AgentFlowStepId, AgentFlowWarning[]> = {\n 'works-on': [],\n when: [],\n skills: [],\n account: [],\n approval: [],\n results: []\n };\n for (const problem of configuration.problems) {\n result[problemStep(problem)].push(problemWarning(problem, configuration, this.catalog()));\n }\n for (const selector of this.agentTools().unmatched) {\n result.skills.push({\n id: `tool:${selector}`,\n key: 'nh-assistant.admin.run-config.flow.skills.tool-not-offered',\n params: { selector },\n entry: { kind: 'edit-agent' },\n entryKey: 'nh-assistant.admin.run-config.flow.entry.tools'\n });\n }\n for (const server of this.agentServers()) {\n if (unavailableServerUses.has(server.use)) {\n result.skills.push(this.serverWarning(server.id, server.name, server.use));\n }\n }\n if (configuration.source === 'admin' && configuration.runSettings === null) {\n result.account.push({\n id: 'no-settings',\n key: 'nh-assistant.admin.run-config.flow.account.no-settings',\n entry: { kind: 'setup' },\n entryKey: 'nh-assistant.admin.run-config.setup.start'\n });\n }\n return result;\n });\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.runsSubscription?.unsubscribe());\n }\n\n ngOnInit(): void {\n this.loadRuns();\n }\n\n /** Reads the agent's latest runs; a failure shows with its code and a retry in the results step. */\n loadRuns(): void {\n this.runsLoading.set(true);\n this.runsError.set(null);\n this.runsSubscription?.unsubscribe();\n this.runsSubscription = this.admin.getAgentRuns(this.agent().id, { page: 1, itemsPerPage: latestRunCount }).subscribe({\n next: runs => {\n this.runs.set(runs);\n this.runsLoading.set(false);\n },\n error: (error: unknown) => {\n this.runsError.set(toNhAssistantError(error));\n this.runsLoading.set(false);\n }\n });\n }\n\n open(entry: AgentFlowEntry): void {\n this.entry.emit(entry);\n }\n\n openRunNow(): void {\n this.runningNow.set(true);\n }\n\n /** The run-now dialog closed; its run may be among the latest now. */\n onRunNowClosed(): void {\n this.runningNow.set(false);\n this.loadRuns();\n }\n\n openConversation(conversationId: string): void {\n this.panel.open(conversationId);\n }\n\n /** A skill's name: the application's translation, or a readable form of its id. */\n skillName(skillId: string | null | undefined): string {\n return skillId ? this.translated(skillNameKeys(this.agent().id, skillId), readableId(skillId)) : '';\n }\n\n /** The name of an object type, as the run catalog names it in the reader's language. */\n typeName(subjectType: string): string {\n return typeName(this.catalog(), subjectType);\n }\n\n /** The text of a step's warning count. */\n warningCountKey(count: number): string {\n return count === 1 ? 'nh-assistant.admin.run-config.flow.attention-one' : 'nh-assistant.admin.run-config.flow.attention';\n }\n\n private serverWarning(id: string, name: string, use: AgentFlowServerUse): AgentFlowWarning {\n const base = { id: `server:${id}`, key: `nh-assistant.admin.run-config.flow.servers.warning.${use}`, params: { server: name } };\n switch (use) {\n case 'missing':\n return { ...base, entry: { kind: 'edit-agent' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.tools' };\n case 'personal-never-account':\n case 'personal-never-agent':\n // Delegating to the person who starts a run lets the server serve that person.\n return this.isAdmin() && this.configuration().runSettings\n ? { ...base, entry: { kind: 'settings' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.settings' }\n : { ...base, entry: { kind: 'mcp-servers' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.mcp-servers' };\n default:\n return { ...base, entry: { kind: 'mcp-servers' }, entryKey: 'nh-assistant.admin.run-config.flow.entry.mcp-servers' };\n }\n }\n\n private sentence(policy: string | null): string | null {\n const summary = this.catalog()?.approvalPolicySummaries?.find(item => item.name === policy);\n return summary ? describePolicy(summary, (key, params) => this.translate.instant(key, params) as string) : null;\n }\n\n /** The first of the keys with a translation, or the fallback. */\n private translated(keys: readonly string[], fallback: string): string {\n for (const key of keys) {\n const value = this.translate.instant(key) as unknown;\n if (typeof value === 'string' && value.length > 0 && value !== key) {\n return value;\n }\n }\n return fallback;\n }\n}\n","<section class=\"flow\" [attr.aria-labelledby]=\"id + '-title'\" data-flow>\n <header class=\"flow-header\">\n <h4 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.run-config.flow.title' | translate }}</h4>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.description' | translate }}</p>\n </header>\n\n <!-- An overview in order, not an editor: each step summarizes and opens the form that changes it. -->\n <ol class=\"flow-steps\">\n @for (step of steps; track step; let index = $index) {\n <li class=\"flow-step\" [class.attention]=\"warnings()[step].length > 0\" [attr.data-flow-step]=\"step\">\n <div class=\"step-head\">\n <span class=\"marker\" aria-hidden=\"true\">{{ index + 1 }}</span>\n <h5 [id]=\"id + '-' + step\">{{ 'nh-assistant.admin.run-config.flow.steps.' + step | translate }}</h5>\n @if (warnings()[step].length > 0) {\n <span class=\"badge warning\" data-flow-attention>\n <nh-assistant-icon name=\"warning\" />{{ warningCountKey(warnings()[step].length) | translate: { count: warnings()[step].length } }}\n </span>\n }\n </div>\n\n <div class=\"step-body\">\n @switch (step) {\n @case ('works-on') {\n @let works = worksOn();\n <p data-flow-works-on>\n <strong>\n @switch (works.only) {\n @case ('all') { {{ 'nh-assistant.admin.agents.works-on.all' | translate }} }\n @case ('types') { {{ works.types.join(', ') }} }\n @default { {{ 'nh-assistant.admin.agents.works-on.application' | translate }} }\n }\n </strong>\n @if (works.application && works.only !== 'application') {\n {{ 'nh-assistant.admin.agents.works-on.and-application' | translate }}\n }\n @if (works.perDivision) {\n {{ 'nh-assistant.admin.agents.works-on.per-division' | translate }}\n }\n </p>\n @if (works.undeclared) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.works-on.undeclared' | translate }}</p>\n }\n @if (works.all && works.known.length > 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.agents.works-on.known' | translate: { types: works.known.join(', ') } }}</p>\n }\n @if (!isAdmin()) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.works-on.in-code' | translate }}</p>\n }\n }\n\n @case ('when') {\n @if (triggers().length === 0) {\n <p class=\"muted\" data-flow-no-triggers>{{ 'nh-assistant.admin.run-config.flow.when.none' | translate }}</p>\n } @else {\n <ul class=\"items\">\n @for (trigger of triggers(); track trigger.origin + trigger.triggerId) {\n <li [attr.data-flow-trigger]=\"trigger.triggerId\">\n <div class=\"item-head\">\n <strong class=\"mono\">{{ trigger.triggerId }}</strong>\n <span class=\"badge\">{{ 'nh-assistant.admin.run-config.triggers.sources.' + trigger.source | translate }}</span>\n @if (trigger.origin === 'code') {\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n } @else if (trigger.shadow) {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.agents.shadow.badge' | translate }}</span>\n } @else {\n <span class=\"badge success\">{{ 'nh-assistant.admin.run-config.triggers.live-badge' | translate }}</span>\n }\n @if (!trigger.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n </div>\n <div class=\"meta\">\n @if (trigger.detail) {\n <span class=\"mono\">{{ trigger.detail }}</span>\n }\n <span data-flow-target>{{ 'nh-assistant.admin.run-config.flow.target.' + trigger.target.kind | translate: { value: trigger.target.value } }}</span>\n <span>{{ (trigger.skillId ? 'nh-assistant.admin.run-config.triggers.skill-value' : 'nh-assistant.admin.run-config.triggers.agent-routes') | translate: { skill: skillName(trigger.skillId) } }}</span>\n </div>\n @if (trigger.origin === 'data') {\n <div class=\"item-actions\">\n <button\n class=\"secondary small\"\n type=\"button\"\n [attr.aria-label]=\"'nh-assistant.admin.run-config.flow.entry.edit-trigger-named' | translate: { trigger: trigger.triggerId }\"\n [disabled]=\"busy()\"\n (click)=\"open({ kind: 'edit-trigger', triggerId: trigger.triggerId })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n </div>\n }\n </li>\n }\n </ul>\n }\n @let now = runNow();\n <p data-flow-run-now>\n @if (now.available) {\n {{ runNowScopeKey() | translate }}\n @if (worksOn().application) {\n {{ 'nh-assistant.admin.run-config.flow.when.run-policy' | translate: { policy: worksOn().runPolicy ? (policyKeys(worksOn().runPolicy) | nhAssistantTranslate: worksOn().runPolicy!) : ('nh-assistant.admin.run-config.flow.when.run-policy-default' | translate) } }}\n }\n @if (now.paused) {\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.flow.when.paused' | translate }}</span>\n }\n } @else {\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.when.run-now-unavailable.' + now.reason | translate }}</span>\n }\n </p>\n @if (consultations().length > 0 || canAddConsultation()) {\n <!-- When another assistant consults the agent: in code, or as data with the asking agents as its second key. -->\n <div class=\"tools\" data-flow-consultations>\n <p class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.when.consultations' | translate }}</p>\n @if (consultations().length === 0) {\n <p class=\"muted\" data-flow-no-consultations>{{ 'nh-assistant.admin.run-config.flow.when.no-consultations' | translate }}</p>\n } @else {\n <ul class=\"items compact\">\n @for (consultation of consultations(); track consultation.origin + consultation.subjectType) {\n <li [attr.data-flow-consultation]=\"consultation.subjectType\">\n <div class=\"item-head\">\n <strong>{{ typeName(consultation.subjectType) }}</strong>\n @if (consultation.origin === 'code') {\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n }\n @if (!consultation.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n </div>\n <div class=\"meta\">\n <span>{{ (consultation.routes.length > 0 ? 'nh-assistant.admin.run-config.flow.when.consultation-proposes' : 'nh-assistant.admin.run-config.flow.when.consultation-answers') | translate }}</span>\n <span data-flow-consultation-askers>\n {{ (consultation.askingAgents.length === 0\n ? 'nh-assistant.admin.run-config.flow.when.asked-by-none'\n : consultation.askingAgents.length === 1 ? 'nh-assistant.admin.run-config.flow.when.asked-by-one' : 'nh-assistant.admin.run-config.flow.when.asked-by') | translate: { count: consultation.askingAgents.length } }}\n </span>\n </div>\n @if (consultation.origin === 'data' && configuration().consultationCeiling) {\n <div class=\"item-actions\">\n <button\n class=\"secondary small\"\n type=\"button\"\n [attr.aria-label]=\"'nh-assistant.admin.run-config.flow.entry.edit-consultation-named' | translate: { type: typeName(consultation.subjectType) }\"\n [disabled]=\"busy()\"\n (click)=\"open({ kind: 'edit-consultation', subjectType: consultation.subjectType })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n </div>\n }\n </li>\n }\n </ul>\n }\n </div>\n }\n }\n\n @case ('skills') {\n @if (wayOfWorking(); as way) {\n <p data-flow-way>\n <span class=\"flow-label\">{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}:</span>&ngsp;\n @switch (way.kind) {\n @case ('rules') {\n <strong>{{ 'nh-assistant.admin.run-config.rule-handler-value' | translate: { name: way.name } }}</strong>\n @if (way.description) {\n <span class=\"muted block\">{{ way.description }}</span>\n }\n }\n @case ('code-rules') { <strong>{{ 'nh-assistant.admin.run-config.flow.skills.code-rules' | translate }}</strong> }\n @default { <strong>{{ 'nh-assistant.admin.run-config.model' | translate }}</strong> }\n }\n </p>\n }\n @let config = configuration();\n @if (config.codeSkills.length === 0 && config.dataSkills.length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.skills.none' | translate }}</p>\n } @else {\n <ul class=\"items\" [attr.aria-label]=\"'nh-assistant.admin.agents.skills.title' | translate\">\n @for (skill of config.codeSkills; track skill.skillId) {\n <li [attr.data-flow-skill]=\"skill.skillId\">\n <div class=\"item-head\">\n <strong>{{ skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId) }}</strong>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n </div>\n <p class=\"muted\">{{ skillDescriptionKeys(config.agentId, skill.skillId) | nhAssistantTranslate: skill.description }}</p>\n </li>\n }\n @for (skill of config.dataSkills; track skill.skillId) {\n <li [attr.data-flow-skill]=\"skill.skillId\">\n <div class=\"item-head\">\n <strong>{{ skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId) }}</strong>\n @if (!skill.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n @if (skill.candidate) {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.run-config.candidate.badge' | translate: { version: skill.candidate.version } }}</span>\n }\n </div>\n <p class=\"muted\">{{ skill.description }}</p>\n <div class=\"meta\">\n <span>{{ skill.ruleHandler ? ('nh-assistant.admin.run-config.rule-handler-value' | translate: { name: skill.ruleHandler }) : ('nh-assistant.admin.run-config.model' | translate) }}</span>\n <span>{{ (skill.tools.length === 1 ? 'nh-assistant.admin.agents.tool-count-one' : 'nh-assistant.admin.agents.tool-count') | translate: { count: skill.tools.length } }}</span>\n </div>\n <div class=\"item-actions\">\n <button\n class=\"secondary small\"\n type=\"button\"\n [attr.aria-label]=\"'nh-assistant.admin.run-config.flow.entry.edit-skill-named' | translate: { skill: (skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) }\"\n [disabled]=\"busy()\"\n (click)=\"open({ kind: 'edit-skill', skillId: skill.skillId })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n </div>\n </li>\n }\n </ul>\n }\n\n <div class=\"tools\" data-flow-tools>\n <p class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.skills.tools' | translate }}</p>\n @let tools = agentTools();\n @if (!tools.known) {\n @if (config.toolSelectors.length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.skills.no-tools' | translate }}</p>\n } @else {\n <p class=\"mono\">{{ config.toolSelectors.join(', ') }}</p>\n }\n } @else if (tools.tools.length === 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.skills.no-tools' | translate }}</p>\n } @else {\n <ul class=\"items compact\">\n @for (tool of tools.tools; track tool.id) {\n <li [attr.data-flow-tool]=\"tool.id\">\n <div class=\"item-head\">\n <span class=\"mono\">{{ tool.id }}</span>\n <span class=\"badge\" [class.warning]=\"tool.effect !== 'read-only'\">{{ 'nh-assistant.admin.run-config.flow.effect.' + tool.effect | translate }}</span>\n </div>\n @if (tool.effect !== 'read-only') {\n <!-- Where a run's proposal of the tool waits: at the object it names (W5), or in the run's own thread. -->\n <p class=\"muted\" data-flow-places>\n {{ (tool.placesAt ? 'nh-assistant.admin.run-config.flow.skills.places-at' : 'nh-assistant.admin.run-config.flow.skills.places-in-run') | translate: { type: tool.placesAt } }}\n </p>\n }\n </li>\n }\n </ul>\n @if (tools.more > 0) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.skills.more-tools' | translate: { count: tools.more } }}</p>\n }\n }\n </div>\n\n @if (agentServers().length > 0) {\n <div class=\"tools\" data-flow-servers>\n <p class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.skills.servers' | translate }}</p>\n <ul class=\"items compact\">\n @for (server of agentServers(); track server.id) {\n <li [attr.data-flow-server]=\"server.id\">\n <div class=\"item-head\">\n <strong>{{ server.name }}</strong>\n @if (server.headlessUse) {\n <span class=\"badge\">{{ 'nh-assistant.admin.run-config.flow.servers.headless.' + server.headlessUse | translate }}</span>\n }\n </div>\n <p class=\"muted\" data-flow-server-use>{{ 'nh-assistant.admin.run-config.flow.servers.use.' + server.use | translate }}</p>\n </li>\n }\n </ul>\n </div>\n }\n }\n\n @case ('account') {\n @let config = configuration();\n @if (accountability(); as account) {\n <p data-flow-account>\n <strong>{{ 'nh-assistant.admin.run-config.settings.accountability.' + account.accountability | translate }}</strong>\n @if (account.accountability === 'service-account') {\n @let actorId = isAdmin() ? config.runSettings?.serviceAccountActorId : agent().serviceAccount?.actorId;\n @if (actorId) {\n <span class=\"block\" data-flow-account-name>\n <nh-assistant-account-label [actorId]=\"actorId\" [name]=\"accountName()\" />\n </span>\n }\n }\n </p>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.account.rights.' + account.accountability | translate }}</p>\n @if (account.delegateFromInitiator) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.account.delegates' | translate }}</p>\n }\n @if (!isAdmin() && agent().serviceAccount?.overridden) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.account.overridden' | translate }}</p>\n }\n } @else if (!isAdmin()) {\n <!-- An older server does not say how an agent in code runs. -->\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.account.in-code' | translate }}</p>\n }\n }\n\n @case ('approval') {\n <p>\n <span class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.approval.autonomy' | translate }}</span>&ngsp;\n <strong>{{ 'nh-assistant.admin.agents.autonomy.' + agent().autonomy | translate }}</strong>\n </p>\n @if (policies().length === 0) {\n <p class=\"muted\">{{ (isAdmin() ? 'nh-assistant.admin.run-config.flow.approval.no-settings' : 'nh-assistant.admin.run-config.flow.approval.in-code') | translate }}</p>\n } @else {\n <ul class=\"items\">\n @for (policy of policies(); track policy.skillId ?? '') {\n <li [attr.data-flow-policy]=\"policy.skillId ?? 'agent'\">\n <div class=\"item-head\">\n @if (policy.skillId) {\n <span>{{ 'nh-assistant.admin.run-config.flow.approval.skill' | translate: { skill: skillName(policy.skillId) } }}</span>\n }\n <strong>{{ policy.name ?? ('nh-assistant.admin.run-config.settings.approval.default' | translate) }}</strong>\n </div>\n @if (policy.sentence) {\n <p class=\"muted\" data-flow-policy-sentence>{{ policy.sentence }}</p>\n }\n </li>\n }\n </ul>\n }\n }\n\n @case ('results') {\n <p data-flow-groups>\n <span class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.results.groups' | translate }}</span>&ngsp;\n @if (groups().length > 0) {\n <strong>{{ groups().join(', ') }}</strong>\n } @else {\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.results.no-groups' | translate }}</span>\n }\n </p>\n @if (worksOn().application) {\n <p class=\"muted\" data-flow-view-policy>\n {{ 'nh-assistant.admin.run-config.flow.results.view-policy' | translate: { policy: worksOn().viewPolicy ? (policyKeys(worksOn().viewPolicy) | nhAssistantTranslate: worksOn().viewPolicy!) : ('nh-assistant.admin.run-config.flow.results.view-policy-default' | translate) } }}\n </p>\n }\n @if (agent().shadow?.shadow) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.results.shadow' | translate }}</p>\n }\n <div class=\"latest\" data-flow-runs>\n <p class=\"flow-label\">{{ 'nh-assistant.admin.run-config.flow.results.latest' | translate }}</p>\n @if (runsError(); as failure) {\n <div class=\"message error\" role=\"alert\" data-flow-runs-error>\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">{{ runsErrorKeys() | nhAssistantTranslate: failure.code }}</span>\n <button class=\"secondary small\" type=\"button\" [disabled]=\"runsLoading()\" (click)=\"loadRuns()\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.retry' | translate }}\n </button>\n </div>\n } @else if (runsLoading() && !runs()) {\n <p class=\"muted\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n } @else if (runs(); as history) {\n @if (history.items.length === 0) {\n <p class=\"muted\" data-flow-runs-empty>{{ 'nh-assistant.agent-runs.run.empty' | translate }}</p>\n } @else {\n <ol class=\"items\">\n @for (run of history.items; track run.id) {\n <li [attr.data-flow-run]=\"run.id\">\n <div class=\"item-head\">\n <time [attr.datetime]=\"run.createdAt\">{{ run.createdAt | date: 'medium' }}</time>\n <span\n class=\"badge\"\n [class.success]=\"run.status === 'completed'\"\n [class.warning]=\"run.status === 'waiting-for-approval' || run.status === 'queued' || run.status === 'running'\"\n [class.danger]=\"run.status === 'failed'\">{{ 'nh-assistant.agent-runs.run.status.' + run.status | translate }}</span>\n @if (run.shadow) {\n <span class=\"badge warning\">{{ 'nh-assistant.agent-runs.run.shadow' | translate }}</span>\n }\n </div>\n <nh-assistant-subject-link\n [subjectType]=\"run.subjectType\"\n [subjectId]=\"run.subjectId\"\n [label]=\"run.subjectDisplayName ?? run.subjectId\"\n [typeName]=\"run.subjectTypeName\"\n [link]=\"run.subjectLink\" />\n <!-- The beginning of the result is model output, shown as text. -->\n @if (run.result; as result) {\n <p class=\"preview\" data-flow-run-preview>{{ result }}@if (run.resultTruncated) {…}</p>\n } @else if (run.failureCode; as code) {\n <p class=\"muted\">{{ codeKeys(code) | nhAssistantTranslate: code }}</p>\n }\n @if (run.mcpConnectionSkips?.length) {\n <p class=\"muted\" data-flow-run-mcp-skips>{{ 'nh-assistant.agent-runs.run.mcp-skipped' | translate: { count: run.mcpConnectionSkips?.length } }}</p>\n }\n </li>\n }\n </ol>\n @if (history.total > history.items.length) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.flow.results.more-runs' | translate: { count: history.total - history.items.length } }}</p>\n }\n }\n }\n </div>\n }\n }\n\n @if (warnings()[step].length > 0) {\n <ul class=\"warnings\" [attr.aria-label]=\"'nh-assistant.admin.run-config.flow.warnings' | translate\">\n @for (warning of warnings()[step]; track warning.id) {\n <li class=\"message warning\" [attr.data-flow-warning]=\"warning.id\">\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">\n {{ warning.key | translate: warning.params }}\n @if (warning.detailKey) {\n {{ warning.detailKey | translate }}\n }\n </span>\n @if (warning.entry; as target) {\n <button class=\"secondary small\" type=\"button\" [attr.data-flow-fix]=\"target.kind\" [disabled]=\"busy()\" (click)=\"open(target)\">\n {{ warning.entryKey! | translate }}\n </button>\n }\n </li>\n }\n </ul>\n }\n\n <div class=\"card-actions\" [attr.data-flow-entries]=\"step\">\n @switch (step) {\n @case ('works-on') {\n @if (isAdmin()) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"edit-agent\" [disabled]=\"busy()\" (click)=\"open({ kind: 'edit-agent' })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.run-config.flow.entry.works-on' | translate }}\n </button>\n }\n }\n @case ('when') {\n @if (canAddRunData()) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"add-trigger\" [disabled]=\"busy()\" (click)=\"open({ kind: 'add-trigger' })\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.triggers.add' | translate }}\n </button>\n }\n @if (runNow().available) {\n <button class=\"secondary\" type=\"button\" aria-haspopup=\"dialog\" data-flow-entry=\"run-now\" [disabled]=\"busy()\" (click)=\"openRunNow()\">\n <nh-assistant-icon name=\"send\" />{{ 'nh-assistant.admin.agents.run-now' | translate }}\n </button>\n }\n @if (canAddConsultation()) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"add-consultation\" [disabled]=\"busy()\" (click)=\"open({ kind: 'add-consultation' })\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.consultations.add' | translate }}\n </button>\n }\n }\n @case ('skills') {\n @if (canAddRunData()) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"add-skill\" [disabled]=\"busy()\" (click)=\"open({ kind: 'add-skill' })\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.skills.add' | translate }}\n </button>\n }\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"tools\" [disabled]=\"busy()\" (click)=\"open({ kind: 'edit-agent' })\">\n <nh-assistant-icon name=\"tool\" />{{ 'nh-assistant.admin.run-config.flow.entry.tools' | translate }}\n </button>\n }\n @case ('account') {\n @if (isAdmin()) {\n @if (configuration().runSettings) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"settings\" [disabled]=\"busy()\" (click)=\"open({ kind: 'settings' })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.run-config.settings.edit' | translate }}\n </button>\n } @else {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"settings\" [disabled]=\"busy()\" (click)=\"open({ kind: 'settings' })\">\n {{ 'nh-assistant.admin.run-config.settings.add' | translate }}\n </button>\n }\n } @else if (agent().serviceAccount) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"account\" [disabled]=\"busy()\" (click)=\"open({ kind: 'account' })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.agents.service-account.action.set' | translate }}\n </button>\n }\n }\n @case ('approval') {\n @if (isAdmin() && configuration().runSettings) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"approval\" [disabled]=\"busy()\" (click)=\"open({ kind: 'settings' })\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.run-config.flow.entry.approval' | translate }}\n </button>\n }\n }\n @case ('results') {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"runs\" (click)=\"open({ kind: 'runs' })\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.run-config.flow.entry.runs' | translate }}\n </button>\n @if (groupable()) {\n <button class=\"secondary\" type=\"button\" data-flow-entry=\"groups\" [disabled]=\"busy()\" (click)=\"open({ kind: 'edit-agent' })\">\n <nh-assistant-icon name=\"users\" />{{ 'nh-assistant.admin.run-config.flow.entry.groups' | translate }}\n </button>\n }\n }\n }\n </div>\n </div>\n </li>\n }\n </ol>\n\n @if (runningNow()) {\n <nh-assistant-run-now-dialog\n [agent]=\"runNowAgent()\"\n [subjectTypes]=\"catalog()?.subjectTypes ?? []\"\n [divisions]=\"catalog()?.divisions === true\"\n (started)=\"loadRuns()\"\n (openConversation)=\"openConversation($event)\"\n (closed)=\"onRunNowClosed()\" />\n }\n</section>\n","import { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, output, signal, untracked, viewChild } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Observable, Subscription, map } from 'rxjs';\nimport {\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantPickerOption as NhAssistantPickerOption,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\n\nconst lookupDelayMs = 300;\n\nlet nextId = 0;\n\n/**\n * Chooses the account an agent answers to. When the application offers an account search the\n * administrator finds the account by name or e-mail address; otherwise they enter its id and the\n * screen shows the name the application knows for it. When the name cannot be looked up, the screen\n * says why with the translated code and offers to look it up again, instead of calling the account\n * unknown.\n */\n@Component({\n selector: 'nh-assistant-account-picker',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantPickerComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (searchable()) {\n <nh-assistant-picker\n [inputId]=\"inputId()\"\n [value]=\"value()\"\n [selectedLabel]=\"label()\"\n [search]=\"search\"\n [invalid]=\"invalid()\"\n [describedBy]=\"fieldDescribedBy()\"\n [placeholder]=\"'nh-assistant.admin.run-config.account.search-placeholder' | translate\"\n (valueChange)=\"valueChange.emit($event)\"\n (optionChange)=\"label.set($event?.label ?? null)\" />\n } @else {\n <input\n #manual\n type=\"text\"\n class=\"mono\"\n autocomplete=\"off\"\n maxlength=\"256\"\n [id]=\"inputId()\"\n [value]=\"value() ?? ''\"\n [attr.aria-invalid]=\"invalid() ? true : null\"\n [attr.aria-describedby]=\"fieldDescribedBy()\"\n [attr.placeholder]=\"'nh-assistant.admin.run-config.account.id-placeholder' | translate\"\n (input)=\"valueChange.emit(text($event))\" />\n }\n @if (lookupError(); as failure) {\n <p class=\"lookup-error\" role=\"alert\" data-account-lookup-error [id]=\"lookupErrorId\">\n <nh-assistant-icon name=\"warning\" />\n <span>{{ lookupErrorKeys() | nhAssistantTranslate: failure.code }}</span>\n <button type=\"button\" class=\"link\" data-account-lookup-retry (click)=\"lookUpAgain()\">\n {{ 'nh-assistant.admin.run-config.account.lookup-again' | translate }}\n </button>\n </p>\n } @else if (!searchable() && value()) {\n <p class=\"account-name\" aria-live=\"polite\">\n {{ (label() ? 'nh-assistant.admin.run-config.account.known' : 'nh-assistant.admin.run-config.account.unknown') | translate: { name: label() } }}\n </p>\n }\n `,\n styles: [`\n :host { display: block; min-width: 0; }\n input {\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n min-height: 38px;\n border: 1px solid var(--nha-border, #d0d5dd);\n border-radius: var(--nha-radius-control, 8px);\n padding: 8px 10px;\n color: var(--nha-text, inherit);\n background: var(--nha-background, transparent);\n font-family: var(--nha-mono, monospace);\n font-size: 12px;\n }\n input[aria-invalid='true'] { border-color: var(--nha-danger, #b42318); }\n .account-name { margin: 4px 2px 0; color: var(--nha-text-muted, #667085); font-size: 12px; overflow-wrap: anywhere; }\n .lookup-error {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 6px;\n margin: 4px 2px 0;\n color: var(--nha-danger, #b42318);\n font-size: 12px;\n font-weight: 600;\n overflow-wrap: anywhere;\n }\n .lookup-error span { flex: 1 1 auto; min-width: 0; }\n button.link {\n border: 0;\n padding: 0;\n color: var(--nha-accent, currentColor);\n background: none;\n font: inherit;\n text-decoration: underline;\n cursor: pointer;\n }\n `]\n})\nexport class NhAssistantAccountPickerComponent {\n private readonly admin = inject(NhAssistantAdminApiService);\n private lookupTimer?: ReturnType<typeof setTimeout>;\n private lookupSubscription?: Subscription;\n private readonly picker = viewChild(NhAssistantPickerComponent);\n private readonly manual = viewChild<{ nativeElement: HTMLInputElement }>('manual');\n\n readonly inputId = input.required<string>();\n readonly value = input<string | null>(null);\n /** Whether the application offers an account search (`RunCatalog.accountSearch`). */\n readonly searchable = input(false);\n readonly invalid = input(false);\n readonly describedBy = input<string | null>(null);\n readonly valueChange = output<string>();\n\n readonly lookupErrorId = `nh-assistant-account-picker-lookup-${nextId++}`;\n /** The name of the chosen account, once known. */\n readonly label = signal<string | null>(null);\n /** Why the name of the account could not be looked up; `null` after a lookup that answered. */\n readonly lookupError = signal<NhAssistantError | null>(null);\n readonly lookupErrorKeys = computed(() => nhAssistantErrorKeys(this.lookupError()));\n readonly fieldDescribedBy = computed(() =>\n [this.describedBy(), this.lookupError() ? this.lookupErrorId : null].filter(Boolean).join(' ') || null);\n\n readonly search = (query: string): Observable<NhAssistantPickerOption[]> =>\n this.admin.searchAccounts(query).pipe(map(accounts => accounts.map(account => ({\n value: account.actorId,\n label: account.displayName,\n // An account named by its e-mail address needs no second line.\n description: account.detail === account.displayName ? null : account.detail\n }))));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n clearTimeout(this.lookupTimer);\n this.lookupSubscription?.unsubscribe();\n });\n // The name of a stored account comes from the application's directory.\n effect(() => {\n const value = this.value()?.trim() ?? '';\n const delay = this.searchable() ? 0 : lookupDelayMs;\n untracked(() => this.lookUp(value, delay));\n });\n }\n\n focus(): void {\n this.picker()?.focus();\n this.manual()?.nativeElement.focus();\n }\n\n text(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n\n /** Looks the name of the account up again after a failed lookup. */\n lookUpAgain(): void {\n this.lookUp(this.value()?.trim() ?? '', 0);\n }\n\n private lookUp(value: string, delay: number): void {\n clearTimeout(this.lookupTimer);\n this.lookupSubscription?.unsubscribe();\n this.lookupError.set(null);\n if (value.length === 0) {\n this.label.set(null);\n return;\n }\n\n this.lookupTimer = setTimeout(() => {\n this.lookupSubscription = this.admin.getAccounts([value]).subscribe({\n next: accounts => this.label.set(accounts.find(account => account.actorId === value)?.displayName ?? null),\n error: (error: unknown) => {\n this.label.set(null);\n this.lookupError.set(toNhAssistantError(error));\n }\n });\n }, delay);\n }\n}\n","import { ChangeDetectionStrategy, Component, OnInit, afterNextRender, computed, inject, input, output, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Observable, concat, defer, of, tap } from 'rxjs';\nimport {\n AgentAccountability,\n NhAssistantAdminApiService,\n RunCatalog,\n ToolCatalogEntry,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAccountPickerComponent } from './nh-assistant-account-picker.component';\nimport { RunConfigForm } from './run-config-form';\nimport {\n RunConfigErrors,\n ScheduleTarget,\n blank,\n checkBudget,\n checkWhole,\n cronExamples,\n dashCase,\n describePolicy,\n eventOptions,\n WorksOnStatement,\n policyOptions,\n requireText,\n ruleOptions,\n runConfigLimits,\n toolChoices,\n subjectSetOptions,\n systemSubjectType,\n timeZoneOptions,\n toDashCase,\n toNumber,\n withBudgetField,\n withScheduleTargetError,\n worksOnCovers\n} from './run-config-shared';\n\nlet nextId = 0;\n\nexport type WorkSetupStep = 'when' | 'what' | 'who' | 'limits' | 'review';\n\nconst steps: WorkSetupStep[] = ['when', 'what', 'who', 'limits', 'review'];\n\n/** The step whose fields a server error belongs to. */\nconst stepOfField: Record<string, WorkSetupStep> = {\n triggerId: 'when', source: 'when', event: 'when', debounceSeconds: 'when', cron: 'when', timeZone: 'when',\n subjectSet: 'when', message: 'when', skill: 'when', conflict: 'when',\n skillId: 'what', name: 'what', description: 'what', instructions: 'what', tools: 'what', ruleHandler: 'what', profile: 'what',\n accountability: 'who', serviceAccountActorId: 'who',\n approvalPolicy: 'limits', maxTokensPerRun: 'limits', dailyToolCalls: 'limits', dailyTokens: 'limits'\n};\n\n/**\n * Lets an agent created in the administration work on its own in one flow: when it starts, what it\n * does, on whose behalf, who approves its proposals and its limits, and a review. Saving adds the run\n * settings, a skill and a trigger that starts it; the skill and the trigger start in shadow, where\n * nobody is notified and nothing executes, and can be put live at the end. A schedule of an agent\n * that works on the whole application may run for the whole application instead of a set of\n * subjects, once per division for an agent that works per division.\n */\n@Component({\n selector: 'nh-assistant-agent-work-setup',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantPickerComponent, NhAssistantAccountPickerComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-work-setup.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantAgentWorkSetupComponent extends RunConfigForm implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n\n readonly agentId = input.required<string>();\n readonly agentName = input('');\n readonly catalog = input<RunCatalog | null>(null);\n /**\n * What the agent works on: events about other object types are not offered, and a schedule runs\n * for the whole application only for an agent that works on it.\n */\n readonly worksOn = input<WorksOnStatement | null>(null);\n readonly toolSelectors = input<readonly string[]>([]);\n /** The tool catalog, to show what each of the agent's tool selectors offers. */\n readonly toolCatalog = input<readonly ToolCatalogEntry[]>([]);\n readonly toolChoices = computed(() => toolChoices(this.toolSelectors(), this.toolCatalog()));\n readonly takenSkillIds = input<readonly string[]>([]);\n readonly takenTriggerIds = input<readonly string[]>([]);\n /** The setup saved; `live` tells whether the skill and the trigger were put live. */\n readonly completed = output<{ live: boolean }>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-work-setup-${nextId++}`;\n readonly steps = steps;\n readonly examples = cronExamples;\n readonly timeZones = timeZoneOptions().filter(zone => zone.value !== 'UTC');\n readonly accountabilities: AgentAccountability[] = ['service-account', 'subject-responsible', 'agent'];\n readonly maxDescription = runConfigLimits.description;\n readonly maxInstructions = runConfigLimits.instructions;\n readonly maxMessage = runConfigLimits.message;\n protected readonly fields = Object.keys(stepOfField);\n\n readonly step = signal<WorkSetupStep>('when');\n /** Saved parts, so a retry after a refusal does not add them again. */\n private readonly savedSettingsVersion = signal<number | null>(null);\n private readonly savedSkill = signal(false);\n readonly done = signal(false);\n\n // When.\n readonly source = signal<'event' | 'schedule'>('event');\n readonly event = signal('');\n readonly cron = signal('');\n readonly timeZone = signal('');\n readonly subjectSet = signal('');\n /** The administrator's choice of what a schedule runs for; see `target`. */\n readonly scheduleTarget = signal<ScheduleTarget>('application');\n readonly message = signal('');\n // What.\n readonly name = signal('');\n readonly description = signal('');\n readonly ruleHandler = signal('');\n readonly instructions = signal('');\n readonly tools = signal<string[]>([]);\n // Who.\n readonly accountability = signal<AgentAccountability>('service-account');\n readonly serviceAccount = signal('');\n // Approval and limits.\n readonly approvalPolicy = signal('');\n readonly maxTokensPerRun = signal('');\n readonly dailyToolCalls = signal('');\n readonly dailyTokens = signal('');\n\n readonly stepIndex = computed(() => steps.indexOf(this.step()));\n readonly skillId = computed(() => toDashCase(this.name()));\n readonly triggerId = computed(() => {\n const base = this.source() === 'schedule' ? `${this.skillId()}-schedule` : `${this.skillId()}-${this.event()}`;\n return toDashCase(base).slice(0, 64).replace(/-+$/, '');\n });\n readonly accountSearch = computed(() => this.catalog()?.accountSearch === true);\n readonly events = computed(() => eventOptions(this.catalog(), this.worksOn()));\n readonly subjectSets = computed(() => subjectSetOptions(this.catalog()));\n /** A schedule may run for the whole application only for an agent that works on it. */\n readonly offersApplication = computed(() => worksOnCovers(this.worksOn(), systemSubjectType));\n /** What the schedule runs for: the whole application while the agent works on it, otherwise a set. */\n readonly target = computed<ScheduleTarget>(() => this.offersApplication() ? this.scheduleTarget() : 'set');\n /** The agent's work for the whole application runs once per division. */\n readonly perDivision = computed(() => this.worksOn()?.perDivision === true);\n readonly rules = computed(() => ruleOptions(this.catalog()));\n readonly policies = computed(() => {\n this.language();\n return policyOptions(this.catalog(), summary => describePolicy(summary, (key, params) => this.t(key, params)));\n });\n readonly eventDescription = computed(() => this.events().find(option => option.value === this.event())?.description ?? null);\n readonly subjectSetDescription = computed(() => this.subjectSets().find(option => option.value === this.subjectSet())?.description ?? null);\n readonly ruleDescription = computed(() => this.rules().find(option => option.value === this.ruleHandler())?.description ?? null);\n readonly policyDescription = computed(() => this.policies().find(option => option.value === this.approvalPolicy())?.description ?? null);\n\n ngOnInit(): void {\n // A new skill starts with every tool of the agent; the administrator narrows it.\n this.tools.set([...this.toolSelectors()]);\n }\n\n stepState(step: WorkSetupStep): 'current' | 'done' | 'next' {\n const index = steps.indexOf(step);\n return index === this.stepIndex() ? 'current' : index < this.stepIndex() ? 'done' : 'next';\n }\n\n setSource(source: 'event' | 'schedule'): void {\n this.source.set(source);\n this.touch('source');\n }\n\n setTarget(target: ScheduleTarget): void {\n this.scheduleTarget.set(target);\n this.touch('subjectSet');\n }\n\n setAccountability(accountability: AgentAccountability): void {\n this.accountability.set(accountability);\n this.touch('accountability');\n this.touch('serviceAccountActorId');\n }\n\n toggleTool(selector: string, selected: boolean): void {\n this.tools.update(tools => selected ? [...tools.filter(tool => tool !== selector), selector] : tools.filter(tool => tool !== selector));\n this.touch('tools');\n }\n\n useExample(cron: string): void {\n this.cron.set(cron);\n this.touch('cron');\n }\n\n back(): void {\n const index = this.stepIndex();\n if (index > 0) {\n this.go(steps[index - 1]);\n }\n }\n\n next(): void {\n const errors = this.validate(this.step());\n this.serverError.set(null);\n this.clientErrors.set(errors);\n if (Object.keys(errors).length > 0) {\n this.focusFirstInvalid();\n return;\n }\n const index = this.stepIndex();\n if (index < steps.length - 1) {\n this.go(steps[index + 1]);\n }\n }\n\n /** Saves the run settings, the skill and the trigger, in that order, and stops at a refusal. */\n save(live = false): void {\n const errors: RunConfigErrors = {};\n for (const step of steps) {\n Object.assign(errors, this.validate(step));\n }\n const first = Object.keys(errors)[0];\n if (first) {\n this.go(stepOfField[first] ?? 'when', false);\n this.submit(errors, () => of(null), () => undefined);\n return;\n }\n\n const agentId = this.agentId();\n const skillId = this.skillId();\n const triggerId = this.triggerId();\n const schedule = this.source() === 'schedule';\n const forSet = schedule && this.target() === 'set';\n const settings = defer(() => this.admin.saveRunSettings(agentId, {\n accountability: this.accountability(),\n serviceAccountActorId: this.accountability() === 'service-account' ? blank(this.serviceAccount()) : null,\n approvalPolicy: blank(this.approvalPolicy()),\n maxTokensPerRun: toNumber(this.maxTokensPerRun()),\n dailyToolCalls: toNumber(this.dailyToolCalls()),\n dailyTokens: toNumber(this.dailyTokens()),\n expectedVersion: this.savedSettingsVersion(),\n reason: null\n }).pipe(tap(saved => this.savedSettingsVersion.set(saved.version))));\n const skill = defer(() => this.savedSkill()\n ? of(null)\n : this.admin.saveDataSkill(agentId, skillId, {\n description: this.description().trim(),\n instructions: blank(this.instructions()),\n tools: this.tools(),\n ruleHandler: blank(this.ruleHandler()),\n expectedVersion: null,\n reason: null\n }).pipe(tap(() => this.savedSkill.set(true))));\n const trigger = defer(() => this.admin.saveDataTrigger(agentId, triggerId, {\n source: this.source(),\n skill: skillId,\n event: schedule ? null : blank(this.event()),\n cron: schedule ? blank(this.cron()) : null,\n timeZone: schedule ? blank(this.timeZone()) : null,\n // Without a subject set the schedule runs for the whole application.\n subjectSet: forSet ? blank(this.subjectSet()) : null,\n message: schedule ? blank(this.message()) : null,\n conflict: schedule ? 'ignore' : 'coalesce',\n debounceSeconds: schedule ? null : 120,\n expectedVersion: null,\n reason: null\n }));\n const goLive: Observable<unknown>[] = live\n ? [\n defer(() => this.admin.setSkillShadow(agentId, skillId, { mode: 'live', reason: null })),\n defer(() => this.admin.setDataTriggerShadow(agentId, triggerId, { mode: 'live', reason: null }))\n ]\n : [];\n this.submit({}, () => concat(settings, skill, trigger, ...goLive), () => {\n this.done.set(true);\n this.completed.emit({ live });\n }, () => {\n const field = Object.keys(this.fieldErrors())[0];\n this.go(field ? stepOfField[field] ?? 'review' : 'review', false);\n });\n }\n\n protected override mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n const mapped = withScheduleTargetError(\n withBudgetField(errors, this.dailyToolCalls()),\n this.source() === 'schedule' ? this.target() : 'set');\n // The skill id is derived from the name.\n if (mapped['skillId']) {\n const { skillId, ...rest } = mapped;\n return { ...rest, name: skillId };\n }\n return mapped;\n }\n\n private go(step: WorkSetupStep, focus = true): void {\n this.step.set(step);\n if (focus) {\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>(`[data-step=\"${step}\"] legend`)?.focus(), { injector: this.injector });\n }\n }\n\n private validate(step: WorkSetupStep): RunConfigErrors {\n const errors: RunConfigErrors = {};\n switch (step) {\n case 'when':\n if (this.source() === 'event') {\n if (this.event() === '') {\n errors['event'] = { code: 'required' };\n }\n } else {\n requireText(errors, 'cron', this.cron());\n if (this.target() === 'set' && this.subjectSet() === '') {\n errors['subjectSet'] = { code: 'required' };\n }\n requireText(errors, 'message', this.message(), this.maxMessage);\n }\n break;\n case 'what':\n requireText(errors, 'name', this.name());\n if (!errors['name'] && (!dashCase.test(this.skillId()) || this.skillId().length === 0)) {\n errors['name'] = { code: 'name-letters' };\n } else if (!errors['name'] && this.takenSkillIds().includes(this.skillId())) {\n errors['name'] = { code: 'taken' };\n }\n requireText(errors, 'description', this.description(), this.maxDescription);\n if (this.instructions().length > this.maxInstructions) {\n errors['instructions'] = { code: 'too-long', params: { max: this.maxInstructions } };\n }\n if (this.ruleHandler() === '' && this.instructions().trim() === '') {\n errors['instructions'] = { code: 'instructions-for-model' };\n }\n break;\n case 'who':\n if (this.accountability() === 'service-account' && this.serviceAccount().trim() === '') {\n errors['serviceAccountActorId'] = { code: 'required' };\n }\n break;\n case 'limits':\n checkWhole(errors, 'maxTokensPerRun', this.maxTokensPerRun(), 1);\n checkBudget(errors, this.dailyToolCalls(), this.dailyTokens());\n break;\n }\n return errors;\n }\n}\n","<section class=\"stack card\" data-work-setup [attr.aria-labelledby]=\"id + '-title'\">\n <header class=\"stack\">\n <h5 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.run-config.setup.title' | translate: { name: agentName() } }}</h5>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.setup.explain' | translate }}</p>\n <ol class=\"steps\" [attr.aria-label]=\"'nh-assistant.admin.run-config.setup.progress' | translate\">\n @for (item of steps; track item; let index = $index) {\n <li [class.done]=\"stepState(item) === 'done'\" [attr.aria-current]=\"stepState(item) === 'current' ? 'step' : null\">\n @if (stepState(item) === 'done') {\n <nh-assistant-icon name=\"check\" />\n }\n {{ index + 1 }}. {{ 'nh-assistant.admin.run-config.setup.step.' + item | translate }}\n </li>\n }\n </ol>\n </header>\n\n @if (done()) {\n <p class=\"message success\" role=\"status\" data-setup-done>{{ 'nh-assistant.admin.run-config.setup.done' | translate }}</p>\n } @else {\n <form class=\"stack\" novalidate (submit)=\"$event.preventDefault(); step() === 'review' ? save() : next()\">\n @switch (step()) {\n @case ('when') {\n <fieldset class=\"group\" data-step=\"when\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.setup.when.title' | translate }}</legend>\n <div class=\"choices\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.run-config.setup.when.title' | translate\">\n <label class=\"choice\" [class.selected]=\"source() === 'event'\">\n <input type=\"radio\" [name]=\"id + '-source'\" value=\"event\" [checked]=\"source() === 'event'\" (change)=\"setSource('event')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.source-event' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.source-event-hint' | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"source() === 'schedule'\">\n <input type=\"radio\" [name]=\"id + '-source'\" value=\"schedule\" [checked]=\"source() === 'schedule'\" (change)=\"setSource('schedule')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.source-schedule' | translate }}</strong>\n <span class=\"muted\">{{ (offersApplication() ? 'nh-assistant.admin.run-config.triggers.source-schedule-application-hint' : 'nh-assistant.admin.run-config.triggers.source-schedule-hint') | translate }}</span>\n </span>\n </label>\n </div>\n @if (source() === 'event') {\n <div class=\"field\">\n <label [for]=\"id + '-event'\">{{ 'nh-assistant.admin.run-config.triggers.event' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-event'\" [options]=\"events()\" [value]=\"event()\"\n [placeholder]=\"'nh-assistant.admin.run-config.choose' | translate\"\n [invalid]=\"fieldError('event') !== null\"\n [describedBy]=\"describedBy(null, 'event', id + '-event-error')\"\n (valueChange)=\"event.set($event); touch('event')\" />\n @if (errorKey('event'); as key) {\n <p class=\"field-error\" [id]=\"id + '-event-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('event')?.params }}</p>\n }\n @if (events().length === 0) {\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.setup.no-events' | translate }}</p>\n }\n </div>\n } @else {\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-cron'\">{{ 'nh-assistant.admin.run-config.triggers.cron' | translate }}</label>\n <input type=\"text\" class=\"mono\" autocomplete=\"off\" maxlength=\"128\" [id]=\"id + '-cron'\" [value]=\"cron()\"\n [attr.aria-invalid]=\"fieldError('cron') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-cron-hint', 'cron', id + '-cron-error')\"\n (input)=\"cron.set(value($event)); touch('cron')\" />\n <p class=\"hint\" [id]=\"id + '-cron-hint'\">{{ 'nh-assistant.admin.run-config.triggers.cron-hint' | translate }}</p>\n <ul class=\"examples\" [attr.aria-label]=\"'nh-assistant.admin.run-config.triggers.examples' | translate\">\n @for (example of examples; track example.cron) {\n <li><button type=\"button\" (click)=\"useExample(example.cron)\">{{ 'nh-assistant.admin.run-config.triggers.example.' + example.key | translate }}</button></li>\n }\n </ul>\n @if (errorKey('cron'); as key) {\n <p class=\"field-error\" [id]=\"id + '-cron-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('cron')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-zone'\">{{ 'nh-assistant.admin.run-config.triggers.time-zone' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-zone'\" [options]=\"timeZones\" [value]=\"timeZone()\" [noneLabel]=\"'UTC'\"\n [invalid]=\"fieldError('timeZone') !== null\"\n [describedBy]=\"describedBy(null, 'timeZone', id + '-zone-error')\"\n (valueChange)=\"timeZone.set($event); touch('timeZone')\" />\n @if (errorKey('timeZone'); as key) {\n <p class=\"field-error\" [id]=\"id + '-zone-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('timeZone')?.params }}</p>\n }\n </div>\n </div>\n @if (offersApplication()) {\n <!-- An agent that works on the whole application chooses what the schedule runs for. -->\n <div class=\"field\" data-schedule-target>\n <span class=\"label\" [id]=\"id + '-target-label'\">{{ 'nh-assistant.admin.run-config.triggers.target.title' | translate }}</span>\n <div\n class=\"choices\"\n role=\"radiogroup\"\n tabindex=\"-1\"\n [attr.aria-labelledby]=\"id + '-target-label'\"\n [attr.aria-invalid]=\"target() === 'application' && fieldError('subjectSet') ? true : null\"\n [attr.aria-describedby]=\"target() === 'application' ? describedBy(null, 'subjectSet', id + '-target-error') : null\">\n <label class=\"choice\" [class.selected]=\"target() === 'application'\">\n <input type=\"radio\" [name]=\"id + '-target'\" value=\"application\" [checked]=\"target() === 'application'\" (change)=\"setTarget('application')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.target.application' | translate }}</strong>\n <span class=\"muted\" data-target-hint>{{ (perDivision() ? 'nh-assistant.admin.run-config.triggers.target.application-per-division-hint' : 'nh-assistant.admin.run-config.triggers.target.application-hint') | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"target() === 'set'\">\n <input type=\"radio\" [name]=\"id + '-target'\" value=\"set\" [checked]=\"target() === 'set'\" (change)=\"setTarget('set')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.target.set' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.target.set-hint' | translate }}</span>\n </span>\n </label>\n </div>\n @if (target() === 'application' && errorKey('subjectSet'); as key) {\n <p class=\"field-error\" [id]=\"id + '-target-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate }}</p>\n }\n </div>\n }\n @if (target() === 'set') {\n <div class=\"field\">\n <label [for]=\"id + '-set'\">{{ 'nh-assistant.admin.run-config.triggers.subject-set' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-set'\" [options]=\"subjectSets()\" [value]=\"subjectSet()\"\n [placeholder]=\"'nh-assistant.admin.run-config.choose' | translate\"\n [invalid]=\"fieldError('subjectSet') !== null\"\n [describedBy]=\"describedBy(id + '-set-hint', 'subjectSet', id + '-set-error')\"\n (valueChange)=\"subjectSet.set($event); touch('subjectSet')\" />\n <p class=\"hint\" [id]=\"id + '-set-hint'\">{{ 'nh-assistant.admin.run-config.triggers.subject-set-hint' | translate }}</p>\n @if (errorKey('subjectSet'); as key) {\n <p class=\"field-error\" [id]=\"id + '-set-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('subjectSet')?.params }}</p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-message'\">{{ 'nh-assistant.admin.run-config.triggers.message' | translate }}</label>\n <textarea rows=\"2\" [id]=\"id + '-message'\" [value]=\"message()\"\n [attr.aria-invalid]=\"fieldError('message') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-message-hint', 'message', id + '-message-error')\"\n (input)=\"message.set(value($event)); touch('message')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-message-hint'\">{{ 'nh-assistant.admin.run-config.triggers.message-hint' | translate }}</p>\n @if (errorKey('message'); as key) {\n <p class=\"field-error\" [id]=\"id + '-message-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('message')?.params }}</p>\n }\n </div>\n }\n </fieldset>\n }\n @case ('what') {\n <fieldset class=\"group\" data-step=\"what\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.setup.what.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-name'\">{{ 'nh-assistant.admin.run-config.setup.what.name' | translate }}</label>\n <input type=\"text\" autocomplete=\"off\" maxlength=\"64\" [id]=\"id + '-name'\" [value]=\"name()\"\n [attr.aria-invalid]=\"fieldError('name') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-name-hint', 'name', id + '-name-error')\"\n (input)=\"name.set(value($event)); touch('name')\" />\n <p class=\"hint\" [id]=\"id + '-name-hint'\">\n {{ (skillId() ? 'nh-assistant.admin.run-config.setup.what.name-id' : 'nh-assistant.admin.run-config.setup.what.name-hint') | translate: { id: skillId() } }}\n </p>\n @if (errorKey('name'); as key) {\n <p class=\"field-error\" [id]=\"id + '-name-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('name')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-description'\">{{ 'nh-assistant.admin.run-config.skills.description-label' | translate }}</label>\n <input type=\"text\" [id]=\"id + '-description'\" [value]=\"description()\"\n [attr.aria-invalid]=\"fieldError('description') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-description-hint', 'description', id + '-description-error')\"\n (input)=\"description.set(value($event)); touch('description')\" />\n <p class=\"hint\" [id]=\"id + '-description-hint'\">\n <span>{{ 'nh-assistant.admin.run-config.skills.description-hint' | translate }}</span>\n <span class=\"counter\">{{ 'nh-assistant.admin.characters' | translate: { count: description().length, max: maxDescription } }}</span>\n </p>\n @if (errorKey('description'); as key) {\n <p class=\"field-error\" [id]=\"id + '-description-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('description')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-rules'\">{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-rules'\" [options]=\"rules()\" [value]=\"ruleHandler()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.model' | translate\"\n [invalid]=\"fieldError('ruleHandler') !== null\"\n [describedBy]=\"describedBy(id + '-rules-hint', 'ruleHandler', id + '-rules-error')\"\n (valueChange)=\"ruleHandler.set($event); touch('ruleHandler'); touch('instructions')\" />\n <p class=\"hint\" [id]=\"id + '-rules-hint'\">\n {{ (ruleHandler() ? 'nh-assistant.admin.run-config.skills.rules-hint' : 'nh-assistant.admin.run-config.skills.model-hint') | translate }}\n </p>\n @if (errorKey('ruleHandler'); as key) {\n <p class=\"field-error\" [id]=\"id + '-rules-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('ruleHandler')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-instructions'\">{{ 'nh-assistant.admin.run-config.skills.instructions' | translate }}</label>\n <textarea rows=\"4\" [id]=\"id + '-instructions'\" [value]=\"instructions()\"\n [attr.aria-invalid]=\"fieldError('instructions') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-instructions-hint', 'instructions', id + '-instructions-error')\"\n (input)=\"instructions.set(value($event)); touch('instructions')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-instructions-hint'\">{{ 'nh-assistant.admin.run-config.skills.instructions-hint' | translate }} {{ 'nh-assistant.admin.run-config.skills.background-hint' | translate }}</p>\n @if (errorKey('instructions'); as key) {\n <p class=\"field-error\" [id]=\"id + '-instructions-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('instructions')?.params }}</p>\n }\n </div>\n <fieldset class=\"field\">\n <legend>{{ 'nh-assistant.admin.run-config.skills.tools' | translate }}</legend>\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.skills.tools-hint' | translate }}</p>\n @for (choice of toolChoices(); track choice.selector) {\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"tools().includes(choice.selector)\" (change)=\"toggleTool(choice.selector, checked($event))\" />\n <span class=\"tool-choice\">\n <span class=\"mono\">{{ choice.selector }}</span>\n @if (choice.description) {\n <span class=\"muted block\">{{ choice.description }}</span>\n } @else if (choice.matches !== null) {\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.skills.tools-pattern' | translate: { count: choice.matches } }}</span>\n }\n </span>\n </label>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.no-selectors' | translate }}</p>\n }\n @if (errorKey('tools'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('tools')?.params }}</p>\n }\n </fieldset>\n </fieldset>\n }\n @case ('who') {\n <fieldset class=\"group\" data-step=\"who\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.settings.who.title' | translate }}</legend>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.who.explain' | translate }}</p>\n <div class=\"choices\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.run-config.settings.who.title' | translate\">\n @for (option of accountabilities; track option) {\n <label class=\"choice\" [class.selected]=\"accountability() === option\">\n <input type=\"radio\" [name]=\"id + '-accountability'\" [value]=\"option\" [checked]=\"accountability() === option\" (change)=\"setAccountability(option)\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.settings.accountability.' + option | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.accountability-explain.' + option | translate }}</span>\n </span>\n </label>\n }\n </div>\n @if (accountability() === 'service-account') {\n <div class=\"field\">\n <label [for]=\"id + '-account'\">{{ 'nh-assistant.admin.run-config.settings.service-account' | translate }}</label>\n <nh-assistant-account-picker [inputId]=\"id + '-account'\" [value]=\"serviceAccount()\" [searchable]=\"accountSearch()\"\n [invalid]=\"fieldError('serviceAccountActorId') !== null\"\n [describedBy]=\"describedBy(id + '-account-hint', 'serviceAccountActorId', id + '-account-error')\"\n (valueChange)=\"serviceAccount.set($event); touch('serviceAccountActorId')\" />\n <p class=\"hint\" [id]=\"id + '-account-hint'\">\n {{ (accountSearch() ? 'nh-assistant.admin.run-config.account.search-hint' : 'nh-assistant.admin.run-config.account.id-hint') | translate }}\n </p>\n @if (errorKey('serviceAccountActorId'); as key) {\n <p class=\"field-error\" [id]=\"id + '-account-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('serviceAccountActorId')?.params }}</p>\n }\n </div>\n }\n @if (errorKey('accountability'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('accountability')?.params }}</p>\n }\n </fieldset>\n }\n @case ('limits') {\n <fieldset class=\"group\" data-step=\"limits\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.setup.limits.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-policy'\">{{ 'nh-assistant.admin.run-config.approval-policy' | translate }}</label>\n <nh-assistant-picker [inputId]=\"id + '-policy'\" [options]=\"policies()\" [value]=\"approvalPolicy()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.settings.approval.default' | translate\"\n [invalid]=\"fieldError('approvalPolicy') !== null\"\n [describedBy]=\"describedBy(id + '-policy-hint', 'approvalPolicy', id + '-policy-error')\"\n (valueChange)=\"approvalPolicy.set($event); touch('approvalPolicy')\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.run-config.settings.approval.hint' | translate }}</p>\n @if (errorKey('approvalPolicy'); as key) {\n <p class=\"field-error\" [id]=\"id + '-policy-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('approvalPolicy')?.params }}</p>\n }\n </div>\n <p class=\"muted\" [id]=\"id + '-limits-hint'\">{{ 'nh-assistant.admin.run-config.budget-hint' | translate }}</p>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-run-tokens'\">{{ 'nh-assistant.admin.run-config.max-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-run-tokens'\" [value]=\"maxTokensPerRun()\"\n [attr.aria-invalid]=\"fieldError('maxTokensPerRun') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'maxTokensPerRun', id + '-run-tokens-error')\"\n (input)=\"maxTokensPerRun.set(value($event)); touch('maxTokensPerRun')\" />\n @if (errorKey('maxTokensPerRun'); as key) {\n <p class=\"field-error\" [id]=\"id + '-run-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxTokensPerRun')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-daily-calls'\">{{ 'nh-assistant.admin.run-config.daily-tool-calls' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-daily-calls'\" [value]=\"dailyToolCalls()\"\n [attr.aria-invalid]=\"fieldError('dailyToolCalls') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyToolCalls', id + '-daily-calls-error')\"\n (input)=\"dailyToolCalls.set(value($event)); touch('dailyToolCalls'); touch('dailyTokens')\" />\n @if (errorKey('dailyToolCalls'); as key) {\n <p class=\"field-error\" [id]=\"id + '-daily-calls-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyToolCalls')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-daily-tokens'\">{{ 'nh-assistant.admin.run-config.daily-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-daily-tokens'\" [value]=\"dailyTokens()\"\n [attr.aria-invalid]=\"fieldError('dailyTokens') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyTokens', id + '-daily-tokens-error')\"\n (input)=\"dailyTokens.set(value($event)); touch('dailyTokens'); touch('dailyToolCalls')\" />\n @if (errorKey('dailyTokens'); as key) {\n <p class=\"field-error\" [id]=\"id + '-daily-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyTokens')?.params }}</p>\n }\n </div>\n </div>\n </fieldset>\n }\n @case ('review') {\n <fieldset class=\"group\" data-step=\"review\">\n <legend tabindex=\"-1\">{{ 'nh-assistant.admin.run-config.setup.review.title' | translate }}</legend>\n <dl class=\"review\">\n <dt>{{ 'nh-assistant.admin.run-config.setup.step.when' | translate }}</dt>\n <dd>\n @if (source() === 'event') {\n {{ 'nh-assistant.admin.run-config.setup.review.event' | translate: { event: event() } }}\n @if (eventDescription(); as description) { <span class=\"muted block\">{{ description }}</span> }\n } @else if (target() === 'application') {\n <!-- Without a subject set the schedule runs for the whole application, per division for a per-division agent. -->\n <span data-review-target>{{ (perDivision() ? 'nh-assistant.admin.run-config.setup.review.schedule-divisions' : 'nh-assistant.admin.run-config.setup.review.schedule-application') | translate: { cron: cron(), zone: timeZone() || 'UTC' } }}</span>\n } @else {\n {{ 'nh-assistant.admin.run-config.setup.review.schedule' | translate: { cron: cron(), zone: timeZone() || 'UTC', set: subjectSet() } }}\n @if (subjectSetDescription(); as description) { <span class=\"muted block\">{{ description }}</span> }\n }\n </dd>\n <dt>{{ 'nh-assistant.admin.run-config.setup.step.what' | translate }}</dt>\n <dd>\n <strong>{{ name() }}</strong> <span class=\"mono\">({{ skillId() }})</span>\n <span class=\"block\">{{ description() }}</span>\n <span class=\"muted block\">\n {{ ruleHandler() ? ruleHandler() + (ruleDescription() ? ' — ' + ruleDescription() : '') : ('nh-assistant.admin.run-config.model' | translate) }}\n </span>\n </dd>\n <dt>{{ 'nh-assistant.admin.run-config.setup.step.who' | translate }}</dt>\n <dd>{{ 'nh-assistant.admin.run-config.settings.accountability.' + accountability() | translate }}</dd>\n <dt>{{ 'nh-assistant.admin.run-config.setup.step.limits' | translate }}</dt>\n <dd>\n {{ approvalPolicy() || ('nh-assistant.admin.run-config.settings.approval.default' | translate) }}\n @if (policyDescription(); as description) { <span class=\"muted block\">{{ description }}</span> }\n </dd>\n </dl>\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.setup.review.shadow' | translate }}</p>\n </fieldset>\n }\n }\n\n @if (hasErrors()) {\n <div class=\"form-error\" role=\"alert\" data-form-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n @if (serverError(); as failure) {\n @if (failure.code === 'assistant-validation') {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n } @else {\n {{ errorKeys() | nhAssistantTranslate: failure.code }}\n }\n } @else {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n }\n </div>\n </div>\n }\n <div class=\"actions\">\n <button class=\"secondary\" type=\"button\" (click)=\"cancelled.emit()\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n @if (stepIndex() > 0) {\n <button class=\"secondary\" type=\"button\" [disabled]=\"busy()\" (click)=\"back()\">{{ 'nh-assistant.admin.run-config.setup.back' | translate }}</button>\n }\n @if (step() === 'review') {\n <button class=\"secondary\" type=\"button\" data-setup-live [disabled]=\"busy()\" (click)=\"save(true)\">{{ 'nh-assistant.admin.run-config.setup.save-live' | translate }}</button>\n <button class=\"primary\" type=\"submit\" [disabled]=\"busy()\">{{ (busy() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.run-config.setup.save-shadow') | translate }}</button>\n } @else {\n <button class=\"primary\" type=\"submit\">{{ 'nh-assistant.admin.run-config.setup.next' | translate }}</button>\n }\n </div>\n </form>\n }\n</section>\n","import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { FileLimits, ɵNhAssistantIconComponent as NhAssistantIconComponent } from '@newheap/platform-ai-chat';\nimport { FileLimitField, FileLimitsDraft, RunConfigErrors, fieldErrorKey, fileLimitFields, megabytesText } from './run-config-shared';\n\n/** How a form shows one file limit. */\ninterface FileLimitControl {\n field: FileLimitField;\n /** The id suffix of the control. */\n key: string;\n label: string;\n step: string;\n inputMode: 'decimal' | 'numeric';\n}\n\nconst controls: Record<FileLimitField, FileLimitControl> = {\n maxFileBytes: { field: 'maxFileBytes', key: 'file-size', label: 'max-file-megabytes', step: 'any', inputMode: 'decimal' },\n maxFilePages: { field: 'maxFilePages', key: 'file-pages', label: 'max-file-pages', step: '1', inputMode: 'numeric' },\n maxFilesPerTurn: { field: 'maxFilesPerTurn', key: 'files-per-turn', label: 'max-files-per-turn', step: '1', inputMode: 'numeric' },\n maxFileTokensPerTurn: { field: 'maxFileTokensPerTurn', key: 'file-tokens', label: 'max-file-tokens-per-turn', step: '1', inputMode: 'numeric' }\n};\n\n/**\n * The lower file limits of an agent or a skill that accepts files, next to its \"Accepts files\"\n * switch: the largest file in megabytes, the most pages of one file, the most files of one turn and\n * the most file tokens of one turn. Each field names the application's limit, which it can only\n * lower; an empty field keeps it. Errors appear at their fields with the form's other errors.\n */\n@Component({\n selector: 'nh-assistant-file-limits-fields',\n standalone: true,\n imports: [TranslatePipe, NhAssistantIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-file-limits-fields.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantFileLimitsFieldsComponent {\n /** The form's limits. */\n readonly draft = input.required<FileLimitsDraft>();\n /** The application's limits from the run catalog; `null` on older servers. */\n readonly application = input<FileLimits | null | undefined>(null);\n /** The form's field errors, by server field name. */\n readonly errors = input<RunConfigErrors>({});\n /** The prefix of the controls' ids. */\n readonly idPrefix = input.required<string>();\n /** The hint under the title: what an empty field keeps. */\n readonly hintKey = input.required<string>();\n /** A field the administrator changed, so the form clears its error. */\n readonly touched = output<FileLimitField>();\n\n readonly controls = fileLimitFields.map(field => controls[field]);\n\n idOf(control: FileLimitControl, suffix = ''): string {\n return `${this.idPrefix()}-${control.key}${suffix}`;\n }\n\n /** The application's limit as the field shows it: megabytes for the file size. */\n applicationLimit(control: FileLimitControl): string | null {\n const application = this.application();\n if (!application) {\n return null;\n }\n const value = application[control.field];\n return control.field === 'maxFileBytes' ? `${megabytesText(value)} MB` : String(value);\n }\n\n /** The upper bound a browser shows for the field. */\n max(control: FileLimitControl): number | null {\n const application = this.application();\n if (!application) {\n return null;\n }\n return control.field === 'maxFileBytes' ? application.maxFileBytes / (1024 * 1024) : application[control.field];\n }\n\n errorKey(control: FileLimitControl): string | null {\n return fieldErrorKey(this.errors()[control.field]);\n }\n\n errorParams(control: FileLimitControl): Record<string, unknown> | undefined {\n return this.errors()[control.field]?.params;\n }\n\n describedBy(control: FileLimitControl): string {\n const ids = [`${this.idPrefix()}-file-limits-hint`];\n if (this.application()) {\n ids.push(this.idOf(control, '-limit'));\n }\n if (this.errors()[control.field]) {\n ids.push(this.idOf(control, '-error'));\n }\n return ids.join(' ');\n }\n\n change(control: FileLimitControl, event: Event): void {\n this.draft().text(control.field).set((event.target as HTMLInputElement).value);\n this.touched.emit(control.field);\n }\n}\n","<fieldset class=\"field file-limits\" data-file-limits>\n <legend>{{ 'nh-assistant.admin.run-config.files.limits-title' | translate }}</legend>\n <p class=\"hint\" [id]=\"idPrefix() + '-file-limits-hint'\">{{ hintKey() | translate }}</p>\n <div class=\"grid\">\n @for (control of controls; track control.field) {\n <div class=\"field\" [attr.data-file-limit]=\"control.field\">\n <label [for]=\"idOf(control)\">{{ 'nh-assistant.admin.run-config.files.' + control.label | translate }}</label>\n <input type=\"number\" min=\"0\" [attr.step]=\"control.step\" [attr.max]=\"max(control)\" [attr.inputmode]=\"control.inputMode\"\n [id]=\"idOf(control)\" [value]=\"draft().text(control.field)()\"\n [attr.aria-invalid]=\"errorKey(control) ? true : null\"\n [attr.aria-describedby]=\"describedBy(control)\"\n (input)=\"change(control, $event)\" />\n @if (applicationLimit(control); as limit) {\n <p class=\"hint\" [id]=\"idOf(control, '-limit')\">{{ 'nh-assistant.admin.run-config.files.application-limit' | translate: { value: limit } }}</p>\n }\n @if (errorKey(control); as key) {\n <p class=\"field-error\" [id]=\"idOf(control, '-error')\"><nh-assistant-icon name=\"warning\" />{{ key | translate: errorParams(control) }}</p>\n }\n </div>\n }\n </div>\n</fieldset>\n","import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n AgentAccountability,\n AgentElevatedReads,\n AgentRunSettings,\n AgentRunSettingsRequest,\n NhAssistantAdminApiService,\n RunCatalog,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAccountPickerComponent } from './nh-assistant-account-picker.component';\nimport { NhAssistantFileLimitsFieldsComponent } from './nh-assistant-file-limits-fields.component';\nimport { RunConfigForm } from './run-config-form';\nimport {\n RunConfigErrors,\n blank,\n checkBudget,\n checkWhole,\n describePolicy,\n FileLimitsDraft,\n numberText,\n policyOptions,\n profileOptions,\n ruleOptions,\n runConfigLimits,\n toNumber,\n withBudgetField\n} from './run-config-shared';\n\nlet nextId = 0;\n\nconst defaults = { retries: '3', concurrent: '4', perSubject: '10' };\n\n/**\n * The run settings of an agent created in the administration, as questions: who the agent answers to,\n * how it works, who approves its proposals, and its limits, with the rarely changed options under\n * \"Advanced\". Errors appear at their fields and next to the actions.\n */\n@Component({\n selector: 'nh-assistant-run-settings-form',\n standalone: true,\n imports: [\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantPickerComponent,\n NhAssistantAccountPickerComponent,\n NhAssistantFileLimitsFieldsComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-run-settings-form.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantRunSettingsFormComponent extends RunConfigForm implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n\n readonly agentId = input.required<string>();\n readonly catalog = input<RunCatalog | null>(null);\n /** The current run settings; `null` adds them. */\n readonly settings = input<AgentRunSettings | null>(null);\n readonly saved = output<AgentRunSettings>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-run-settings-${nextId++}`;\n readonly maxReason = runConfigLimits.reason;\n readonly accountabilities: AgentAccountability[] = ['service-account', 'subject-responsible', 'agent'];\n readonly elevatedReadModes: AgentElevatedReads[] = ['restricted', 'deny'];\n protected readonly fields = [\n 'accountability', 'serviceAccountActorId', 'ruleHandler', 'approvalPolicy', 'triageProfile', 'retryCount',\n 'maxConcurrentRuns', 'maxRunsPerSubjectPerDay', 'maxTokensPerRun', 'dailyToolCalls', 'dailyTokens',\n 'elevatedReads', 'allowGatewayReads', 'reason', 'maxFileBytes', 'maxFilePages', 'maxFilesPerTurn', 'maxFileTokensPerTurn'\n ];\n\n readonly accountability = signal<AgentAccountability>('service-account');\n readonly serviceAccount = signal('');\n readonly approvalPolicy = signal('');\n readonly ruleHandler = signal('');\n readonly triageProfile = signal('');\n readonly retryCount = signal(defaults.retries);\n readonly maxConcurrentRuns = signal(defaults.concurrent);\n readonly maxRunsPerSubjectPerDay = signal(defaults.perSubject);\n readonly maxTokensPerRun = signal('');\n readonly dailyToolCalls = signal('');\n readonly dailyTokens = signal('');\n readonly allowGatewayReads = signal(false);\n readonly delegateFromInitiator = signal(false);\n /** Whether people's messages and the agent's tools may give it files; off for a new agent. */\n readonly acceptsFiles = signal(false);\n /** The agent's lower file limits, next to accepting files; empty keeps the application's. */\n readonly fileLimits = new FileLimitsDraft();\n readonly elevatedReads = signal<AgentElevatedReads>('restricted');\n readonly reason = signal('');\n readonly advancedOpen = signal(false);\n\n readonly accountSearch = computed(() => this.catalog()?.accountSearch === true);\n readonly rules = computed(() => ruleOptions(this.catalog()));\n readonly profiles = computed(() => profileOptions(this.catalog()));\n readonly policies = computed(() => {\n this.language();\n return policyOptions(this.catalog(), summary => describePolicy(summary, (key, params) => this.t(key, params)));\n });\n\n /** An error under \"Advanced\" keeps it open, so the field with the error can be seen. */\n readonly advancedHasErrors = computed(() => ['retryCount', 'maxConcurrentRuns', 'maxRunsPerSubjectPerDay', 'triageProfile',\n 'elevatedReads', 'allowGatewayReads'].some(field => this.fieldError(field) !== null));\n\n /** Whether the advanced options differ from their defaults. */\n private readonly advancedInUse = computed(() =>\n this.retryCount() !== defaults.retries\n || this.maxConcurrentRuns() !== defaults.concurrent\n || this.maxRunsPerSubjectPerDay() !== defaults.perSubject\n || this.triageProfile() !== ''\n || this.elevatedReads() !== 'restricted'\n || this.allowGatewayReads()\n || this.delegateFromInitiator());\n\n ngOnInit(): void {\n const settings = this.settings();\n this.accountability.set(settings?.accountability ?? 'service-account');\n this.serviceAccount.set(settings?.serviceAccountActorId ?? '');\n this.approvalPolicy.set(settings?.approvalPolicy ?? '');\n this.ruleHandler.set(settings?.ruleHandler ?? '');\n this.triageProfile.set(settings?.triageProfile ?? '');\n this.retryCount.set(String(settings?.retryCount ?? defaults.retries));\n this.maxConcurrentRuns.set(String(settings?.maxConcurrentRuns ?? defaults.concurrent));\n this.maxRunsPerSubjectPerDay.set(String(settings?.maxRunsPerSubjectPerDay ?? defaults.perSubject));\n this.maxTokensPerRun.set(numberText(settings?.maxTokensPerRun));\n this.dailyToolCalls.set(numberText(settings?.dailyToolCalls));\n this.dailyTokens.set(numberText(settings?.dailyTokens));\n this.allowGatewayReads.set(settings?.allowGatewayReads ?? false);\n this.delegateFromInitiator.set(settings?.delegateFromInitiator ?? false);\n this.acceptsFiles.set(settings?.acceptsFiles ?? false);\n this.fileLimits.load(settings);\n this.elevatedReads.set(settings?.elevatedReads ?? 'restricted');\n this.advancedOpen.set(this.advancedInUse());\n }\n\n setAccountability(accountability: AgentAccountability): void {\n this.accountability.set(accountability);\n this.touch('accountability');\n this.touch('serviceAccountActorId');\n }\n\n save(): void {\n const errors: RunConfigErrors = {};\n if (this.accountability() === 'service-account' && this.serviceAccount().trim() === '') {\n errors['serviceAccountActorId'] = { code: 'required' };\n }\n checkWhole(errors, 'retryCount', this.retryCount(), ...runConfigLimits.retries, true);\n checkWhole(errors, 'maxConcurrentRuns', this.maxConcurrentRuns(), ...runConfigLimits.concurrent, true);\n checkWhole(errors, 'maxRunsPerSubjectPerDay', this.maxRunsPerSubjectPerDay(), ...runConfigLimits.perSubject, true);\n checkWhole(errors, 'maxTokensPerRun', this.maxTokensPerRun(), 1);\n checkBudget(errors, this.dailyToolCalls(), this.dailyTokens());\n if (this.acceptsFiles()) {\n this.fileLimits.check(errors, this.catalog()?.fileLimits);\n }\n\n const request: AgentRunSettingsRequest = {\n accountability: this.accountability(),\n serviceAccountActorId: this.accountability() === 'service-account' ? blank(this.serviceAccount()) : null,\n delegateFromInitiator: this.delegateFromInitiator(),\n allowGatewayReads: this.allowGatewayReads(),\n elevatedReads: this.elevatedReads(),\n approvalPolicy: blank(this.approvalPolicy()),\n retryCount: toNumber(this.retryCount()),\n maxConcurrentRuns: toNumber(this.maxConcurrentRuns()),\n maxRunsPerSubjectPerDay: toNumber(this.maxRunsPerSubjectPerDay()),\n maxTokensPerRun: toNumber(this.maxTokensPerRun()),\n dailyToolCalls: toNumber(this.dailyToolCalls()),\n dailyTokens: toNumber(this.dailyTokens()),\n triageProfile: blank(this.triageProfile()),\n ruleHandler: blank(this.ruleHandler()),\n expectedVersion: this.settings()?.version ?? null,\n reason: blank(this.reason()),\n acceptsFiles: this.acceptsFiles(),\n ...this.fileLimits.toRequest(this.acceptsFiles())\n };\n this.submit(errors, () => this.admin.saveRunSettings(this.agentId(), request), settings => this.saved.emit(settings));\n }\n\n protected override mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n return withBudgetField(errors, this.dailyToolCalls());\n }\n}\n","<form class=\"stack card\" data-form=\"settings\" novalidate (submit)=\"$event.preventDefault(); save()\">\n <h5>{{ (settings() ? 'nh-assistant.admin.run-config.settings.edit-title' : 'nh-assistant.admin.run-config.settings.add-title') | translate }}</h5>\n\n <fieldset class=\"group\" [attr.aria-describedby]=\"id + '-who-explain'\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.who.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-who-explain'\">{{ 'nh-assistant.admin.run-config.settings.who.explain' | translate }}</p>\n <div class=\"choices\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.run-config.settings.who.title' | translate\">\n @for (option of accountabilities; track option) {\n <label class=\"choice\" [class.selected]=\"accountability() === option\">\n <input type=\"radio\" [name]=\"id + '-accountability'\" [value]=\"option\" [checked]=\"accountability() === option\" (change)=\"setAccountability(option)\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.settings.accountability.' + option | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.accountability-explain.' + option | translate }}</span>\n </span>\n </label>\n }\n </div>\n @if (errorKey('accountability'); as key) {\n <p class=\"field-error\" [id]=\"id + '-accountability-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('accountability')?.params }}</p>\n }\n @if (accountability() === 'service-account') {\n <div class=\"field\">\n <label [for]=\"id + '-service-account'\">{{ 'nh-assistant.admin.run-config.settings.service-account' | translate }}</label>\n <nh-assistant-account-picker\n [inputId]=\"id + '-service-account'\"\n [value]=\"serviceAccount()\"\n [searchable]=\"accountSearch()\"\n [invalid]=\"fieldError('serviceAccountActorId') !== null\"\n [describedBy]=\"describedBy(id + '-service-account-hint', 'serviceAccountActorId', id + '-service-account-error')\"\n (valueChange)=\"serviceAccount.set($event); touch('serviceAccountActorId')\" />\n <p class=\"hint\" [id]=\"id + '-service-account-hint'\">\n {{ (accountSearch() ? 'nh-assistant.admin.run-config.account.search-hint' : 'nh-assistant.admin.run-config.account.id-hint') | translate }}\n </p>\n @if (errorKey('serviceAccountActorId'); as key) {\n <p class=\"field-error\" [id]=\"id + '-service-account-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('serviceAccountActorId')?.params }}</p>\n }\n </div>\n }\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.how.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-rule-handler'\">{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-rule-handler'\"\n [options]=\"rules()\"\n [value]=\"ruleHandler()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.model' | translate\"\n [invalid]=\"fieldError('ruleHandler') !== null\"\n [describedBy]=\"describedBy(id + '-rule-handler-hint', 'ruleHandler', id + '-rule-handler-error')\"\n (valueChange)=\"ruleHandler.set($event); touch('ruleHandler')\" />\n <p class=\"hint\" [id]=\"id + '-rule-handler-hint'\">{{ 'nh-assistant.admin.run-config.settings.how.hint' | translate }}</p>\n @if (errorKey('ruleHandler'); as key) {\n <p class=\"field-error\" [id]=\"id + '-rule-handler-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('ruleHandler')?.params }}</p>\n }\n </div>\n <label class=\"check\" data-accepts-files>\n <input type=\"checkbox\" [checked]=\"acceptsFiles()\" (change)=\"acceptsFiles.set(checked($event))\" />\n <span>\n {{ 'nh-assistant.admin.run-config.files.label' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.files.agent-hint' | translate }}</span>\n </span>\n </label>\n @if (acceptsFiles()) {\n <nh-assistant-file-limits-fields\n [draft]=\"fileLimits\"\n [application]=\"catalog()?.fileLimits\"\n [errors]=\"fieldErrors()\"\n [idPrefix]=\"id\"\n hintKey=\"nh-assistant.admin.run-config.files.agent-limits-hint\"\n (touched)=\"touch($event)\" />\n }\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.approval.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-policy'\">{{ 'nh-assistant.admin.run-config.approval-policy' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-policy'\"\n [options]=\"policies()\"\n [value]=\"approvalPolicy()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.settings.approval.default' | translate\"\n [invalid]=\"fieldError('approvalPolicy') !== null\"\n [describedBy]=\"describedBy(id + '-policy-hint', 'approvalPolicy', id + '-policy-error')\"\n (valueChange)=\"approvalPolicy.set($event); touch('approvalPolicy')\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.run-config.settings.approval.hint' | translate }}</p>\n @if (errorKey('approvalPolicy'); as key) {\n <p class=\"field-error\" [id]=\"id + '-policy-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('approvalPolicy')?.params }}</p>\n }\n </div>\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.limits.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-limits-hint'\">{{ 'nh-assistant.admin.run-config.budget-hint' | translate }}</p>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-run-tokens'\">{{ 'nh-assistant.admin.run-config.max-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-run-tokens'\" [value]=\"maxTokensPerRun()\"\n [attr.aria-invalid]=\"fieldError('maxTokensPerRun') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'maxTokensPerRun', id + '-run-tokens-error')\"\n (input)=\"maxTokensPerRun.set(value($event)); touch('maxTokensPerRun')\" />\n @if (errorKey('maxTokensPerRun'); as key) {\n <p class=\"field-error\" [id]=\"id + '-run-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxTokensPerRun')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-daily-calls'\">{{ 'nh-assistant.admin.run-config.daily-tool-calls' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-daily-calls'\" [value]=\"dailyToolCalls()\"\n [attr.aria-invalid]=\"fieldError('dailyToolCalls') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyToolCalls', id + '-daily-calls-error')\"\n (input)=\"dailyToolCalls.set(value($event)); touch('dailyToolCalls'); touch('dailyTokens')\" />\n @if (errorKey('dailyToolCalls'); as key) {\n <p class=\"field-error\" [id]=\"id + '-daily-calls-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyToolCalls')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-daily-tokens'\">{{ 'nh-assistant.admin.run-config.daily-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-daily-tokens'\" [value]=\"dailyTokens()\"\n [attr.aria-invalid]=\"fieldError('dailyTokens') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyTokens', id + '-daily-tokens-error')\"\n (input)=\"dailyTokens.set(value($event)); touch('dailyTokens'); touch('dailyToolCalls')\" />\n @if (errorKey('dailyTokens'); as key) {\n <p class=\"field-error\" [id]=\"id + '-daily-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyTokens')?.params }}</p>\n }\n </div>\n </div>\n </fieldset>\n\n <details class=\"advanced\" data-advanced [open]=\"advancedOpen() || advancedHasErrors()\" (toggle)=\"advancedOpen.set($any($event.target).open)\">\n <summary>{{ 'nh-assistant.admin.run-config.advanced.title' | translate }}</summary>\n <div class=\"stack\">\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.advanced.explain' | translate }}</p>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-retries'\">{{ 'nh-assistant.admin.run-config.settings.retries' | translate }}</label>\n <input type=\"number\" min=\"0\" max=\"10\" inputmode=\"numeric\" [id]=\"id + '-retries'\" [value]=\"retryCount()\"\n [attr.aria-invalid]=\"fieldError('retryCount') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-retries-hint', 'retryCount', id + '-retries-error')\"\n (input)=\"retryCount.set(value($event)); touch('retryCount')\" />\n <p class=\"hint\" [id]=\"id + '-retries-hint'\">{{ 'nh-assistant.admin.run-config.settings.retries-hint' | translate }}</p>\n @if (errorKey('retryCount'); as key) {\n <p class=\"field-error\" [id]=\"id + '-retries-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('retryCount')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-concurrent'\">{{ 'nh-assistant.admin.run-config.settings.max-concurrent' | translate }}</label>\n <input type=\"number\" min=\"1\" max=\"100\" inputmode=\"numeric\" [id]=\"id + '-concurrent'\" [value]=\"maxConcurrentRuns()\"\n [attr.aria-invalid]=\"fieldError('maxConcurrentRuns') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-concurrent-hint', 'maxConcurrentRuns', id + '-concurrent-error')\"\n (input)=\"maxConcurrentRuns.set(value($event)); touch('maxConcurrentRuns')\" />\n <p class=\"hint\" [id]=\"id + '-concurrent-hint'\">{{ 'nh-assistant.admin.run-config.settings.max-concurrent-hint' | translate }}</p>\n @if (errorKey('maxConcurrentRuns'); as key) {\n <p class=\"field-error\" [id]=\"id + '-concurrent-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxConcurrentRuns')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-per-subject'\">{{ 'nh-assistant.admin.run-config.settings.max-per-subject' | translate }}</label>\n <input type=\"number\" min=\"1\" max=\"1000\" inputmode=\"numeric\" [id]=\"id + '-per-subject'\" [value]=\"maxRunsPerSubjectPerDay()\"\n [attr.aria-invalid]=\"fieldError('maxRunsPerSubjectPerDay') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-per-subject-hint', 'maxRunsPerSubjectPerDay', id + '-per-subject-error')\"\n (input)=\"maxRunsPerSubjectPerDay.set(value($event)); touch('maxRunsPerSubjectPerDay')\" />\n <p class=\"hint\" [id]=\"id + '-per-subject-hint'\">{{ 'nh-assistant.admin.run-config.settings.max-per-subject-hint' | translate }}</p>\n @if (errorKey('maxRunsPerSubjectPerDay'); as key) {\n <p class=\"field-error\" [id]=\"id + '-per-subject-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxRunsPerSubjectPerDay')?.params }}</p>\n }\n </div>\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-triage'\">{{ 'nh-assistant.admin.run-config.settings.triage' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-triage'\"\n [options]=\"profiles()\"\n [value]=\"triageProfile()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.settings.no-triage' | translate\"\n [invalid]=\"fieldError('triageProfile') !== null\"\n [describedBy]=\"describedBy(id + '-triage-hint', 'triageProfile', id + '-triage-error')\"\n (valueChange)=\"triageProfile.set($event); touch('triageProfile')\" />\n <p class=\"hint\" [id]=\"id + '-triage-hint'\">{{ 'nh-assistant.admin.run-config.settings.triage-hint' | translate }}</p>\n @if (errorKey('triageProfile'); as key) {\n <p class=\"field-error\" [id]=\"id + '-triage-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('triageProfile')?.params }}</p>\n }\n </div>\n <fieldset class=\"field\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.elevated-reads' | translate }}</legend>\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.settings.elevated-reads-hint' | translate }}</p>\n @for (mode of elevatedReadModes; track mode) {\n <label class=\"check\">\n <input type=\"radio\" [name]=\"id + '-elevated'\" [value]=\"mode\" [checked]=\"elevatedReads() === mode\" (change)=\"elevatedReads.set(mode); touch('elevatedReads')\" />\n <span>{{ 'nh-assistant.admin.run-config.settings.elevated.' + mode | translate }}</span>\n </label>\n }\n @if (errorKey('elevatedReads'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('elevatedReads')?.params }}</p>\n }\n </fieldset>\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"allowGatewayReads()\" [attr.aria-invalid]=\"fieldError('allowGatewayReads') ? true : null\" (change)=\"allowGatewayReads.set(checked($event)); touch('allowGatewayReads')\" />\n <span>\n {{ 'nh-assistant.admin.run-config.settings.gateway-reads' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.settings.gateway-reads-hint' | translate }}</span>\n </span>\n </label>\n @if (errorKey('allowGatewayReads'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('allowGatewayReads')?.params }}</p>\n }\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"delegateFromInitiator()\" (change)=\"delegateFromInitiator.set(checked($event))\" />\n <span>\n {{ 'nh-assistant.admin.run-config.settings.delegate' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.settings.delegate-hint' | translate }}</span>\n </span>\n </label>\n </div>\n </details>\n\n <div class=\"field\">\n <label [for]=\"id + '-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input type=\"text\" autocomplete=\"off\" [id]=\"id + '-reason'\" [maxLength]=\"maxReason\" [value]=\"reason()\" [attr.aria-describedby]=\"id + '-reason-hint'\" (input)=\"reason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-reason-hint'\">{{ 'nh-assistant.admin.run-config.note-hint' | translate }}</p>\n </div>\n\n @if (hasErrors()) {\n <div class=\"form-error\" role=\"alert\" data-form-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n @if (serverError(); as failure) {\n @if (failure.code === 'assistant-validation') {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n } @else {\n {{ errorKeys() | nhAssistantTranslate: failure.code }}\n }\n } @else {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n }\n @if (otherFieldErrors().length > 0) {\n <ul>\n @for (field of otherFieldErrors(); track field) {\n <li><span class=\"mono\">{{ field }}</span></li>\n }\n </ul>\n }\n </div>\n </div>\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]=\"busy()\">{{ (busy() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}</button>\n </div>\n</form>\n","import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n AssistantDataClassification,\n DataSkill,\n DataSkillRequest,\n NhAssistantAdminApiService,\n RunCatalog,\n ToolCatalogEntry,\n SkillApplyMode,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantFileLimitsFieldsComponent } from './nh-assistant-file-limits-fields.component';\nimport { RunConfigForm } from './run-config-form';\nimport {\n RunConfigErrors,\n blank,\n checkBudget,\n checkWhole,\n dashCase,\n dataClassifications,\n describePolicy,\n FileLimitsDraft,\n numberText,\n policyOptions,\n profileOptions,\n requireText,\n ruleOptions,\n runConfigLimits,\n toolChoices,\n toNumber,\n withBudgetField\n} from './run-config-shared';\nimport { warningKeys } from '../agent-texts';\n\nlet nextId = 0;\n\n/** What a saved skill form tells its host. */\nexport interface SkillFormSaved {\n skill: DataSkill;\n /** The change runs as the skill's candidate in shadow. */\n candidate: boolean;\n added: boolean;\n}\n\n/**\n * Adds or changes a skill defined as data: what it is for, how it works (fixed rules or the model,\n * with instructions), its tools within the agent's own, and its approval and limits. A change is\n * evaluated in shadow by default.\n */\n@Component({\n selector: 'nh-assistant-skill-form',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantPickerComponent, NhAssistantFileLimitsFieldsComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-skill-form.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantSkillFormComponent extends RunConfigForm implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n\n readonly agentId = input.required<string>();\n readonly catalog = input<RunCatalog | null>(null);\n /** The agent's own tool selectors; a skill's tools stay within them. */\n readonly toolSelectors = input<readonly string[]>([]);\n /** The tool catalog, to show what each of the agent's tool selectors offers. */\n readonly toolCatalog = input<readonly ToolCatalogEntry[]>([]);\n readonly toolChoices = computed(() => toolChoices(this.toolSelectors(), this.toolCatalog()));\n /** The skill to change; `null` adds one. */\n readonly skill = input<DataSkill | null>(null);\n /** Skill ids in use, to refuse a duplicate before sending. */\n readonly takenIds = input<readonly string[]>([]);\n readonly saved = output<SkillFormSaved>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-skill-form-${nextId++}`;\n readonly maxReason = runConfigLimits.reason;\n readonly maxDescription = runConfigLimits.description;\n readonly maxInstructions = runConfigLimits.instructions;\n protected readonly fields = [\n 'skillId', 'description', 'instructions', 'tools', 'ruleHandler', 'profile', 'dataClassification', 'approvalPolicy',\n 'maxTokensPerRun', 'dailyToolCalls', 'dailyTokens', 'apply', 'startsOff', 'reason',\n 'maxFileBytes', 'maxFilePages', 'maxFilesPerTurn', 'maxFileTokensPerTurn'\n ];\n\n readonly skillId = signal('');\n readonly description = signal('');\n readonly instructions = signal('');\n readonly tools = signal<string[]>([]);\n readonly profile = signal('');\n /** The skill's data classification; empty uses the agent's. */\n readonly dataClassification = signal('');\n /** Whether a run in the skill reads files when the agent accepts them too; off for a new skill. */\n readonly acceptsFiles = signal(false);\n /** The skill's lower file limits, next to accepting files; empty keeps the agent's. */\n readonly fileLimits = new FileLimitsDraft();\n readonly ruleHandler = signal('');\n readonly approvalPolicy = signal('');\n readonly maxTokens = signal('');\n readonly dailyToolCalls = signal('');\n readonly dailyTokens = signal('');\n readonly apply = signal<SkillApplyMode>('shadow');\n /** A new skill takes work at once; without it, it starts off until someone switches it on. */\n readonly switchOnNow = signal(true);\n readonly reason = signal('');\n\n readonly editing = computed(() => this.skill() !== null);\n /** The warnings of the skill as it was saved, until this form saves it again. */\n readonly warnings = computed(() => this.skill()?.warnings ?? []);\n readonly warningKeys = warningKeys;\n readonly rules = computed(() => ruleOptions(this.catalog()));\n readonly profiles = computed(() => profileOptions(this.catalog()));\n readonly classifications = computed(() => {\n this.language();\n return dataClassifications.map(value => ({\n value,\n label: this.t(`nh-assistant.admin.run-config.skills.classification.${value}`),\n description: this.t(`nh-assistant.admin.run-config.skills.classification.${value}-hint`)\n }));\n });\n readonly policies = computed(() => {\n this.language();\n return policyOptions(this.catalog(), summary => describePolicy(summary, (key, params) => this.t(key, params)));\n });\n\n ngOnInit(): void {\n const skill = this.skill();\n this.skillId.set(skill?.skillId ?? '');\n this.description.set(skill?.description ?? '');\n this.instructions.set(skill?.instructions ?? '');\n this.tools.set([...(skill?.tools ?? [])]);\n this.profile.set(skill?.profile ?? '');\n this.dataClassification.set(skill?.dataClassification ?? '');\n this.acceptsFiles.set(skill?.acceptsFiles ?? false);\n this.fileLimits.load(skill);\n this.ruleHandler.set(skill?.ruleHandler ?? '');\n this.approvalPolicy.set(skill?.approvalPolicy ?? '');\n this.maxTokens.set(numberText(skill?.maxTokensPerRun));\n this.dailyToolCalls.set(numberText(skill?.dailyToolCalls));\n this.dailyTokens.set(numberText(skill?.dailyTokens));\n // A real change is evaluated in shadow first; a small correction can go live at once.\n this.apply.set('shadow');\n }\n\n toggleTool(selector: string, selected: boolean): void {\n this.tools.update(tools => selected\n ? [...tools.filter(tool => tool !== selector), selector]\n : tools.filter(tool => tool !== selector));\n this.touch('tools');\n }\n\n save(): void {\n const editing = this.skill();\n const skillId = editing?.skillId ?? this.skillId().trim();\n const errors: RunConfigErrors = {};\n if (!editing) {\n if (skillId.length === 0) {\n errors['skillId'] = { code: 'required' };\n } else if (!dashCase.test(skillId) || skillId.length > 64) {\n errors['skillId'] = { code: 'dash-case' };\n } else if (this.takenIds().includes(skillId)) {\n errors['skillId'] = { code: 'taken' };\n }\n }\n requireText(errors, 'description', this.description(), this.maxDescription);\n if (this.instructions().length > this.maxInstructions) {\n errors['instructions'] = { code: 'too-long', params: { max: this.maxInstructions } };\n }\n checkWhole(errors, 'maxTokensPerRun', this.maxTokens(), 1);\n checkBudget(errors, this.dailyToolCalls(), this.dailyTokens());\n if (this.acceptsFiles()) {\n this.fileLimits.check(errors, this.catalog()?.fileLimits);\n }\n\n const request: DataSkillRequest = {\n description: this.description().trim(),\n instructions: blank(this.instructions()),\n tools: this.tools(),\n profile: blank(this.profile()),\n dataClassification: (blank(this.dataClassification()) as AssistantDataClassification | null),\n acceptsFiles: this.acceptsFiles(),\n ...this.fileLimits.toRequest(this.acceptsFiles()),\n ruleHandler: blank(this.ruleHandler()),\n approvalPolicy: blank(this.approvalPolicy()),\n maxTokensPerRun: toNumber(this.maxTokens()),\n dailyToolCalls: toNumber(this.dailyToolCalls()),\n dailyTokens: toNumber(this.dailyTokens()),\n expectedVersion: editing?.version ?? null,\n reason: blank(this.reason()),\n ...(editing ? { apply: this.apply() } : {}),\n ...(!editing && !this.switchOnNow() ? { startsOff: true } : {})\n };\n this.submit(errors, () => this.admin.saveDataSkill(this.agentId(), skillId, request), skill => this.saved.emit({\n skill,\n candidate: editing !== null && this.apply() === 'shadow',\n added: editing === null\n }));\n }\n\n protected override mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n return withBudgetField(errors, this.dailyToolCalls());\n }\n}\n","<form class=\"stack card\" data-form=\"skill\" novalidate (submit)=\"$event.preventDefault(); save()\">\n <h5>\n @if (skill(); as current) {\n {{ 'nh-assistant.admin.run-config.skills.edit-title' | translate: { skill: current.skillId, version: current.version } }}\n } @else {\n {{ 'nh-assistant.admin.run-config.skills.new-title' | translate }}\n }\n </h5>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.skills.what.title' | translate }}</legend>\n @if (!editing()) {\n <div class=\"field\">\n <label [for]=\"id + '-skill-id'\">{{ 'nh-assistant.admin.run-config.skills.id' | translate }}</label>\n <input type=\"text\" class=\"mono\" autocomplete=\"off\" maxlength=\"64\" [id]=\"id + '-skill-id'\" [value]=\"skillId()\"\n [attr.aria-invalid]=\"fieldError('skillId') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-skill-id-hint', 'skillId', id + '-skill-id-error')\"\n (input)=\"skillId.set(value($event)); touch('skillId')\" />\n <p class=\"hint\" [id]=\"id + '-skill-id-hint'\">{{ 'nh-assistant.admin.run-config.skills.id-hint' | translate }}</p>\n @if (errorKey('skillId'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-id-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('skillId')?.params }}</p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-skill-description'\">{{ 'nh-assistant.admin.run-config.skills.description-label' | translate }}</label>\n <input type=\"text\" [id]=\"id + '-skill-description'\" [value]=\"description()\"\n [attr.aria-invalid]=\"fieldError('description') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-skill-description-hint', 'description', id + '-skill-description-error')\"\n (input)=\"description.set(value($event)); touch('description')\" />\n <p class=\"hint\" [id]=\"id + '-skill-description-hint'\">\n <span>{{ 'nh-assistant.admin.run-config.skills.description-hint' | translate }}</span>\n <span class=\"counter\" [class.error-text]=\"description().length > maxDescription\">{{ 'nh-assistant.admin.characters' | translate: { count: description().length, max: maxDescription } }}</span>\n </p>\n @if (errorKey('description'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-description-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('description')?.params }}</p>\n }\n </div>\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.skills.how.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-skill-rules'\">{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-skill-rules'\"\n [options]=\"rules()\"\n [value]=\"ruleHandler()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.model' | translate\"\n [invalid]=\"fieldError('ruleHandler') !== null\"\n [describedBy]=\"describedBy(id + '-skill-rules-hint', 'ruleHandler', id + '-skill-rules-error')\"\n (valueChange)=\"ruleHandler.set($event); touch('ruleHandler')\" />\n <p class=\"hint\" [id]=\"id + '-skill-rules-hint'\">\n {{ (ruleHandler() ? 'nh-assistant.admin.run-config.skills.rules-hint' : 'nh-assistant.admin.run-config.skills.model-hint') | translate }}\n </p>\n @if (errorKey('ruleHandler'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-rules-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('ruleHandler')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-skill-instructions'\">{{ 'nh-assistant.admin.run-config.skills.instructions' | translate }}</label>\n <textarea rows=\"5\" [id]=\"id + '-skill-instructions'\" [value]=\"instructions()\"\n [attr.aria-invalid]=\"fieldError('instructions') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-skill-instructions-hint', 'instructions', id + '-skill-instructions-error')\"\n (input)=\"instructions.set(value($event)); touch('instructions')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-skill-instructions-hint'\">\n <span>{{ 'nh-assistant.admin.run-config.skills.instructions-hint' | translate }} {{ 'nh-assistant.admin.run-config.skills.background-hint' | translate }}</span>\n <span class=\"counter\" [class.error-text]=\"instructions().length > maxInstructions\">{{ 'nh-assistant.admin.characters' | translate: { count: instructions().length, max: maxInstructions } }}</span>\n </p>\n @if (errorKey('instructions'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-instructions-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('instructions')?.params }}</p>\n }\n </div>\n <fieldset class=\"field\" [attr.aria-describedby]=\"id + '-tools-hint'\">\n <legend>{{ 'nh-assistant.admin.run-config.skills.tools' | translate }}</legend>\n <p class=\"hint\" [id]=\"id + '-tools-hint'\">{{ 'nh-assistant.admin.run-config.skills.tools-hint' | translate }}</p>\n @for (choice of toolChoices(); track choice.selector) {\n <label class=\"check\">\n <input type=\"checkbox\" [checked]=\"tools().includes(choice.selector)\" [attr.aria-invalid]=\"fieldError('tools') ? true : null\" (change)=\"toggleTool(choice.selector, checked($event))\" />\n <span class=\"tool-choice\">\n <span class=\"mono\">{{ choice.selector }}</span>\n @if (choice.description) {\n <span class=\"muted block\">{{ choice.description }}</span>\n } @else if (choice.matches !== null) {\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.skills.tools-pattern' | translate: { count: choice.matches } }}</span>\n }\n </span>\n </label>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.agent-editor.no-selectors' | translate }}</p>\n }\n @if (errorKey('tools'); as key) {\n <p class=\"field-error\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('tools')?.params }}</p>\n }\n </fieldset>\n <div class=\"field\">\n <label [for]=\"id + '-skill-profile'\">{{ 'nh-assistant.admin.run-config.skills.profile' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-skill-profile'\"\n [options]=\"profiles()\"\n [value]=\"profile()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.skills.agent-profile' | translate\"\n [invalid]=\"fieldError('profile') !== null\"\n [describedBy]=\"describedBy(id + '-skill-profile-hint', 'profile', id + '-skill-profile-error')\"\n (valueChange)=\"profile.set($event); touch('profile')\" />\n <p class=\"hint\" [id]=\"id + '-skill-profile-hint'\">{{ 'nh-assistant.admin.run-config.skills.profile-hint' | translate }}</p>\n @if (errorKey('profile'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-profile-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('profile')?.params }}</p>\n }\n </div>\n <div class=\"field\" data-classification>\n <label [for]=\"id + '-skill-classification'\">{{ 'nh-assistant.admin.run-config.skills.classification.label' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-skill-classification'\"\n [options]=\"classifications()\"\n [value]=\"dataClassification()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.skills.classification.agent' | translate\"\n [invalid]=\"fieldError('dataClassification') !== null\"\n [describedBy]=\"describedBy(id + '-skill-classification-hint', 'dataClassification', id + '-skill-classification-error')\"\n (valueChange)=\"dataClassification.set($event); touch('dataClassification')\" />\n <p class=\"hint\" [id]=\"id + '-skill-classification-hint'\">{{ 'nh-assistant.admin.run-config.skills.classification.hint' | translate }}</p>\n @for (warning of warnings(); track warning) {\n <p class=\"message warning\" [attr.data-skill-form-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('skill', warning) | nhAssistantTranslate: warning }}\n </p>\n }\n @if (errorKey('dataClassification'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-classification-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dataClassification')?.params }}</p>\n }\n </div>\n <label class=\"check\" data-accepts-files>\n <input type=\"checkbox\" [checked]=\"acceptsFiles()\" (change)=\"acceptsFiles.set(checked($event))\" />\n <span>\n {{ 'nh-assistant.admin.run-config.files.label' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.files.skill-hint' | translate }}</span>\n </span>\n </label>\n @if (acceptsFiles()) {\n <nh-assistant-file-limits-fields\n [draft]=\"fileLimits\"\n [application]=\"catalog()?.fileLimits\"\n [errors]=\"fieldErrors()\"\n [idPrefix]=\"id\"\n hintKey=\"nh-assistant.admin.run-config.files.skill-limits-hint\"\n (touched)=\"touch($event)\" />\n }\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.settings.approval.title' | translate }}</legend>\n <div class=\"field\">\n <label [for]=\"id + '-skill-policy'\">{{ 'nh-assistant.admin.run-config.approval-policy' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-skill-policy'\"\n [options]=\"policies()\"\n [value]=\"approvalPolicy()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.skills.agent-policy' | translate\"\n [invalid]=\"fieldError('approvalPolicy') !== null\"\n [describedBy]=\"describedBy(null, 'approvalPolicy', id + '-skill-policy-error')\"\n (valueChange)=\"approvalPolicy.set($event); touch('approvalPolicy')\" />\n @if (errorKey('approvalPolicy'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-policy-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('approvalPolicy')?.params }}</p>\n }\n </div>\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.limits.title' | translate }}</legend>\n <p class=\"muted\" [id]=\"id + '-limits-hint'\">{{ 'nh-assistant.admin.run-config.budget-hint' | translate }}</p>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-skill-tokens'\">{{ 'nh-assistant.admin.run-config.max-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-skill-tokens'\" [value]=\"maxTokens()\"\n [attr.aria-invalid]=\"fieldError('maxTokensPerRun') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'maxTokensPerRun', id + '-skill-tokens-error')\"\n (input)=\"maxTokens.set(value($event)); touch('maxTokensPerRun')\" />\n @if (errorKey('maxTokensPerRun'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('maxTokensPerRun')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-skill-calls'\">{{ 'nh-assistant.admin.run-config.daily-tool-calls' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-skill-calls'\" [value]=\"dailyToolCalls()\"\n [attr.aria-invalid]=\"fieldError('dailyToolCalls') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyToolCalls', id + '-skill-calls-error')\"\n (input)=\"dailyToolCalls.set(value($event)); touch('dailyToolCalls'); touch('dailyTokens')\" />\n @if (errorKey('dailyToolCalls'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-calls-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyToolCalls')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-skill-daily-tokens'\">{{ 'nh-assistant.admin.run-config.daily-tokens' | translate }}</label>\n <input type=\"number\" min=\"1\" inputmode=\"numeric\" [id]=\"id + '-skill-daily-tokens'\" [value]=\"dailyTokens()\"\n [attr.aria-invalid]=\"fieldError('dailyTokens') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-limits-hint', 'dailyTokens', id + '-skill-daily-tokens-error')\"\n (input)=\"dailyTokens.set(value($event)); touch('dailyTokens'); touch('dailyToolCalls')\" />\n @if (errorKey('dailyTokens'); as key) {\n <p class=\"field-error\" [id]=\"id + '-skill-daily-tokens-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('dailyTokens')?.params }}</p>\n }\n </div>\n </div>\n </fieldset>\n\n @if (editing()) {\n <fieldset class=\"group\" data-apply>\n <legend>{{ 'nh-assistant.admin.run-config.skills.apply' | translate }}</legend>\n <div class=\"choices\">\n <label class=\"choice\" [class.selected]=\"apply() === 'shadow'\">\n <input type=\"radio\" [name]=\"id + '-apply'\" value=\"shadow\" [checked]=\"apply() === 'shadow'\" (change)=\"apply.set('shadow')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.skills.apply-shadow' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.skills.apply-shadow-hint' | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"apply() === 'live'\">\n <input type=\"radio\" [name]=\"id + '-apply'\" value=\"live\" [checked]=\"apply() === 'live'\" (change)=\"apply.set('live')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.skills.apply-live' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.skills.apply-live-hint' | translate }}</span>\n </span>\n </label>\n </div>\n </fieldset>\n } @else {\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.skills.starts-in-shadow' | translate }}</p>\n <label class=\"check\" data-switch-on-now>\n <input type=\"checkbox\" [checked]=\"switchOnNow()\" (change)=\"switchOnNow.set(checked($event))\" />\n <span>\n {{ 'nh-assistant.admin.run-config.skills.switch-on-now' | translate }}\n <span class=\"muted block\">{{ 'nh-assistant.admin.run-config.skills.switch-on-now-hint' | translate }}</span>\n </span>\n </label>\n }\n\n <div class=\"field\">\n <label [for]=\"id + '-skill-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input type=\"text\" autocomplete=\"off\" [id]=\"id + '-skill-reason'\" [maxLength]=\"maxReason\" [value]=\"reason()\" [attr.aria-describedby]=\"id + '-skill-reason-hint'\" (input)=\"reason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-skill-reason-hint'\">{{ 'nh-assistant.admin.run-config.note-hint' | translate }}</p>\n </div>\n\n @if (hasErrors()) {\n <div class=\"form-error\" role=\"alert\" data-form-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n @if (serverError(); as failure) {\n @if (failure.code === 'assistant-validation') {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n } @else {\n {{ errorKeys() | nhAssistantTranslate: failure.code }}\n }\n } @else {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n }\n @if (otherFieldErrors().length > 0) {\n <ul>\n @for (field of otherFieldErrors(); track field) {\n <li><span class=\"mono\">{{ field }}</span></li>\n }\n </ul>\n }\n </div>\n </div>\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]=\"busy()\">{{ (busy() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}</button>\n </div>\n</form>\n","import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport {\n DataTrigger,\n DataTriggerRequest,\n NhAssistantAdminApiService,\n RunBlock,\n RunCatalog,\n TriggerConflict,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerComponent as NhAssistantPickerComponent,\n ɵNhAssistantPickerOption as NhAssistantPickerOption,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe\n} from '@newheap/platform-ai-chat';\nimport { RunConfigForm } from './run-config-form';\nimport {\n RunConfigErrors,\n ScheduleTarget,\n blank,\n checkWhole,\n cronExamples,\n dashCase,\n eventOptions,\n WorksOnStatement,\n requireText,\n runConfigLimits,\n subjectSetOptions,\n systemSubjectType,\n timeZoneOptions,\n toNumber,\n withScheduleTargetError,\n worksOnCovers\n} from './run-config-shared';\n\nlet nextId = 0;\n\nconst conflicts: TriggerConflict[] = ['coalesce', 'queue', 'supersede', 'ignore'];\n\n/**\n * Adds or changes a trigger defined as data: an event of the application or a schedule starts a skill\n * of the agent, or lets the agent choose. A schedule runs for every subject in a set or, for an agent\n * that works on the whole application, for the whole application: once each time, or once per\n * division for an agent that works per division. A new trigger starts in shadow. An event trigger may\n * select named filters the event offers, such as one that skips the agent's own changes; every selected\n * filter must let an event through.\n */\n@Component({\n selector: 'nh-assistant-trigger-form',\n standalone: true,\n imports: [TranslatePipe, NhAssistantTranslatePipe, NhAssistantIconComponent, NhAssistantPickerComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-trigger-form.component.html',\n styleUrls: ['../../nh-assistant-admin-shared.scss', './run-config-forms.scss']\n})\nexport class NhAssistantTriggerFormComponent extends RunConfigForm implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n\n readonly agentId = input.required<string>();\n readonly catalog = input<RunCatalog | null>(null);\n /**\n * What the agent works on: events about other object types are not offered, and a schedule runs\n * for the whole application only for an agent that works on it.\n */\n readonly worksOn = input<WorksOnStatement | null>(null);\n /** The agent's skills, in code and as data, a trigger can start. */\n readonly skills = input<readonly NhAssistantPickerOption[]>([]);\n /** The trigger to change; `null` adds one. */\n readonly trigger = input<DataTrigger | null>(null);\n readonly takenIds = input<readonly string[]>([]);\n readonly saved = output<{ trigger: DataTrigger; added: boolean }>();\n readonly cancelled = output<void>();\n\n readonly id = `nh-assistant-trigger-form-${nextId++}`;\n readonly maxReason = runConfigLimits.reason;\n readonly maxMessage = runConfigLimits.message;\n readonly examples = cronExamples;\n readonly timeZones = timeZoneOptions().filter(zone => zone.value !== 'UTC');\n protected readonly fields = [\n 'triggerId', 'source', 'event', 'debounceSeconds', 'filters', 'cron', 'timeZone', 'subjectSet', 'message', 'skill', 'conflict', 'reason'\n ];\n\n readonly triggerId = signal('');\n readonly source = signal<'event' | 'schedule'>('event');\n readonly event = signal('');\n readonly cron = signal('');\n readonly timeZone = signal('');\n readonly subjectSet = signal('');\n /** The administrator's choice of what a schedule runs for; see `target`. */\n readonly scheduleTarget = signal<ScheduleTarget>('application');\n readonly message = signal('');\n readonly skill = signal('');\n readonly conflict = signal<TriggerConflict>('coalesce');\n readonly debounce = signal('120');\n /** The names of the event's filters the trigger applies. */\n readonly filters = signal<readonly string[]>([]);\n readonly reason = signal('');\n\n readonly editing = computed(() => this.trigger() !== null);\n readonly events = computed(() => eventOptions(this.catalog(), this.worksOn()));\n readonly subjectSets = computed(() => subjectSetOptions(this.catalog()));\n /** The filters the chosen event offers, in the order the application registered them. */\n readonly eventFilters = computed<readonly RunBlock[]>(() => {\n const event = this.event();\n return this.catalog()?.triggerEvents.find(block => block.name === event)?.filters ?? [];\n });\n /**\n * Selected filters the chosen event no longer offers, such as after a deploy removed one: the trigger\n * starts nothing until they are cleared.\n */\n readonly missingFilters = computed(() => {\n const offered = this.eventFilters();\n return this.catalog() === null\n ? []\n : this.filters().filter(name => !offered.some(filter => filter.name === name));\n });\n /** A schedule may run for the whole application only for an agent that works on it. */\n readonly offersApplication = computed(() => worksOnCovers(this.worksOn(), systemSubjectType));\n /** What the schedule runs for: the whole application while the agent works on it, otherwise a set. */\n readonly target = computed<ScheduleTarget>(() => this.offersApplication() ? this.scheduleTarget() : 'set');\n /** The agent's work for the whole application runs once per division. */\n readonly perDivision = computed(() => this.worksOn()?.perDivision === true);\n /** A stored schedule for the whole application of an agent that no longer works on it. */\n readonly applicationDropped = computed(() => {\n const trigger = this.trigger();\n return trigger?.source === 'schedule' && !trigger.subjectSet && !this.offersApplication();\n });\n readonly conflictOptions = computed<NhAssistantPickerOption[]>(() => {\n this.language();\n return conflicts.map(conflict => ({\n value: conflict,\n label: this.t(`nh-assistant.admin.run-config.triggers.conflicts.${conflict}`),\n description: this.t(`nh-assistant.admin.run-config.triggers.conflict-explain.${conflict}`)\n }));\n });\n\n ngOnInit(): void {\n const trigger = this.trigger();\n this.triggerId.set(trigger?.triggerId ?? '');\n this.source.set(trigger?.source === 'schedule' ? 'schedule' : 'event');\n this.event.set(trigger?.event ?? '');\n this.cron.set(trigger?.cron ?? '');\n this.timeZone.set(trigger?.timeZone ?? '');\n this.subjectSet.set(trigger?.subjectSet ?? '');\n // A stored schedule without a subject set runs for the whole application; a new one starts there\n // for an agent that works on it.\n this.scheduleTarget.set(trigger?.source === 'schedule' && trigger.subjectSet ? 'set' : 'application');\n this.message.set(trigger?.message ?? '');\n this.skill.set(trigger?.skillId ?? '');\n this.conflict.set(trigger?.conflict ?? 'coalesce');\n this.debounce.set(String(trigger?.debounceSeconds ?? 120));\n this.filters.set(trigger?.filters ?? []);\n }\n\n /** Another event offers other filters: those it does not offer no longer apply. */\n setEvent(event: string): void {\n this.event.set(event);\n this.touch('event');\n const offered = this.eventFilters();\n this.filters.update(filters => filters.filter(name => offered.some(filter => filter.name === name)));\n }\n\n toggleFilter(name: string, selected: boolean): void {\n this.filters.update(filters => selected\n ? [...filters.filter(filter => filter !== name), name]\n : filters.filter(filter => filter !== name));\n this.touch('filters');\n }\n\n /** A schedule skips a tick while a run is busy by default; an event coalesces. */\n setSource(source: 'event' | 'schedule'): void {\n this.source.set(source);\n this.touch('source');\n if (!this.editing()) {\n this.conflict.set(source === 'schedule' ? 'ignore' : 'coalesce');\n }\n }\n\n setTarget(target: ScheduleTarget): void {\n this.scheduleTarget.set(target);\n this.touch('subjectSet');\n }\n\n useExample(cron: string): void {\n this.cron.set(cron);\n this.touch('cron');\n }\n\n save(): void {\n const editing = this.trigger();\n const triggerId = editing?.triggerId ?? this.triggerId().trim();\n const schedule = this.source() === 'schedule';\n const forSet = schedule && this.target() === 'set';\n const errors: RunConfigErrors = {};\n if (!editing) {\n if (triggerId.length === 0) {\n errors['triggerId'] = { code: 'required' };\n } else if (!dashCase.test(triggerId) || triggerId.length > 64) {\n errors['triggerId'] = { code: 'dash-case' };\n } else if (this.takenIds().includes(triggerId)) {\n errors['triggerId'] = { code: 'taken' };\n }\n }\n if (schedule) {\n requireText(errors, 'cron', this.cron());\n if (forSet && this.subjectSet() === '') {\n errors['subjectSet'] = { code: 'required' };\n }\n requireText(errors, 'message', this.message(), this.maxMessage);\n } else {\n if (this.event() === '') {\n errors['event'] = { code: 'required' };\n }\n if (this.missingFilters().length > 0) {\n errors['filters'] = { code: 'not-found' };\n }\n checkWhole(errors, 'debounceSeconds', this.debounce(), ...runConfigLimits.debounce, true);\n }\n\n const request: DataTriggerRequest = {\n source: this.source(),\n skill: blank(this.skill()),\n event: schedule ? null : blank(this.event()),\n cron: schedule ? blank(this.cron()) : null,\n timeZone: schedule ? blank(this.timeZone()) : null,\n // Without a subject set the schedule runs for the whole application.\n subjectSet: forSet ? blank(this.subjectSet()) : null,\n message: schedule ? blank(this.message()) : null,\n conflict: this.conflict(),\n debounceSeconds: schedule ? null : toNumber(this.debounce()),\n // In the order the event offers them; a schedule takes none.\n filters: schedule ? [] : this.orderedFilters(),\n expectedVersion: editing?.version ?? null,\n reason: blank(this.reason())\n };\n this.submit(errors, () => this.admin.saveDataTrigger(this.agentId(), triggerId, request), trigger => this.saved.emit({\n trigger,\n added: editing === null\n }));\n }\n\n /** The selected filters in the order the event offers them, those it no longer offers last. */\n private orderedFilters(): string[] {\n const selected = this.filters();\n return [\n ...this.eventFilters().map(filter => filter.name).filter(name => selected.includes(name)),\n ...selected.filter(name => !this.eventFilters().some(filter => filter.name === name))\n ];\n }\n\n protected override mapServerErrors(errors: RunConfigErrors): RunConfigErrors {\n return withScheduleTargetError(errors, this.source() === 'schedule' ? this.target() : 'set');\n }\n}\n","<form class=\"stack card\" data-form=\"trigger\" novalidate (submit)=\"$event.preventDefault(); save()\">\n <h5>\n @if (trigger(); as current) {\n {{ 'nh-assistant.admin.run-config.triggers.edit-title' | translate: { trigger: current.triggerId } }}\n } @else {\n {{ 'nh-assistant.admin.run-config.triggers.new-title' | translate }}\n }\n </h5>\n\n @if (!editing()) {\n <div class=\"field\">\n <label [for]=\"id + '-trigger-id'\">{{ 'nh-assistant.admin.run-config.triggers.id' | translate }}</label>\n <input type=\"text\" class=\"mono\" autocomplete=\"off\" maxlength=\"64\" [id]=\"id + '-trigger-id'\" [value]=\"triggerId()\"\n [attr.aria-invalid]=\"fieldError('triggerId') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-trigger-id-hint', 'triggerId', id + '-trigger-id-error')\"\n (input)=\"triggerId.set(value($event)); touch('triggerId')\" />\n <p class=\"hint\" [id]=\"id + '-trigger-id-hint'\">{{ 'nh-assistant.admin.run-config.triggers.id-hint' | translate }}</p>\n @if (errorKey('triggerId'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-id-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('triggerId')?.params }}</p>\n }\n </div>\n }\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.triggers.when.title' | translate }}</legend>\n <div class=\"choices\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.run-config.triggers.when.title' | translate\">\n <label class=\"choice\" [class.selected]=\"source() === 'event'\">\n <input type=\"radio\" [name]=\"id + '-source'\" value=\"event\" [checked]=\"source() === 'event'\" (change)=\"setSource('event')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.source-event' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.source-event-hint' | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"source() === 'schedule'\">\n <input type=\"radio\" [name]=\"id + '-source'\" value=\"schedule\" [checked]=\"source() === 'schedule'\" (change)=\"setSource('schedule')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.source-schedule' | translate }}</strong>\n <span class=\"muted\">{{ (offersApplication() ? 'nh-assistant.admin.run-config.triggers.source-schedule-application-hint' : 'nh-assistant.admin.run-config.triggers.source-schedule-hint') | translate }}</span>\n </span>\n </label>\n </div>\n\n @if (source() === 'event') {\n <div class=\"field\">\n <label [for]=\"id + '-trigger-event'\">{{ 'nh-assistant.admin.run-config.triggers.event' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-event'\"\n [options]=\"events()\"\n [value]=\"event()\"\n [placeholder]=\"'nh-assistant.admin.run-config.choose' | translate\"\n [invalid]=\"fieldError('event') !== null\"\n [describedBy]=\"describedBy(null, 'event', id + '-trigger-event-error')\"\n (valueChange)=\"setEvent($event)\" />\n @if (errorKey('event'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-event-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('event')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-trigger-debounce'\">{{ 'nh-assistant.admin.run-config.triggers.debounce' | translate }}</label>\n <input type=\"number\" min=\"0\" max=\"3600\" inputmode=\"numeric\" [id]=\"id + '-trigger-debounce'\" [value]=\"debounce()\"\n [attr.aria-invalid]=\"fieldError('debounceSeconds') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-trigger-debounce-hint', 'debounceSeconds', id + '-trigger-debounce-error')\"\n (input)=\"debounce.set(value($event)); touch('debounceSeconds')\" />\n <p class=\"hint\" [id]=\"id + '-trigger-debounce-hint'\">{{ 'nh-assistant.admin.run-config.triggers.debounce-hint' | translate }}</p>\n @if (errorKey('debounceSeconds'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-debounce-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('debounceSeconds')?.params }}</p>\n }\n </div>\n @if (event() !== '') {\n <!-- The filters of the chosen event; each one selected must let an event through. -->\n <fieldset class=\"field\" data-trigger-filters [attr.aria-describedby]=\"describedBy(id + '-trigger-filters-hint', 'filters', id + '-trigger-filters-error')\">\n <legend>{{ 'nh-assistant.admin.run-config.triggers.filters.title' | translate }}</legend>\n <p class=\"hint\" [id]=\"id + '-trigger-filters-hint'\">{{ 'nh-assistant.admin.run-config.triggers.filters.hint' | translate }}</p>\n <!-- In their own block: a label right under the field would take the field's label style. -->\n <div class=\"checks\">\n @for (filter of eventFilters(); track filter.name) {\n <label class=\"check described\" [attr.data-filter]=\"filter.name\">\n <input type=\"checkbox\" [checked]=\"filters().includes(filter.name)\" [attr.aria-invalid]=\"fieldError('filters') ? true : null\" (change)=\"toggleFilter(filter.name, checked($event))\" />\n <span>\n <span class=\"mono\">{{ filter.name }}</span>\n <span class=\"muted\">{{ filter.description }}</span>\n </span>\n </label>\n }\n @for (name of missingFilters(); track name) {\n <!-- Stored, but the event no longer offers it: the trigger starts nothing until it is cleared. -->\n <label class=\"check described\" [attr.data-missing-filter]=\"name\">\n <input type=\"checkbox\" [checked]=\"true\" aria-invalid=\"true\" (change)=\"toggleFilter(name, checked($event))\" />\n <span>\n <span class=\"mono\">{{ name }}</span>\n <span class=\"error-text\">{{ 'nh-assistant.admin.run-config.triggers.filters.missing' | translate }}</span>\n </span>\n </label>\n }\n </div>\n @if (eventFilters().length === 0 && missingFilters().length === 0) {\n <p class=\"muted\" data-filters-empty>{{ 'nh-assistant.admin.run-config.triggers.filters.empty' | translate }}</p>\n }\n @if (errorKey('filters'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-filters-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('filters')?.params }}</p>\n }\n </fieldset>\n }\n } @else {\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-trigger-cron'\">{{ 'nh-assistant.admin.run-config.triggers.cron' | translate }}</label>\n <input type=\"text\" class=\"mono\" autocomplete=\"off\" maxlength=\"128\" [id]=\"id + '-trigger-cron'\" [value]=\"cron()\"\n [attr.aria-invalid]=\"fieldError('cron') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-trigger-cron-hint', 'cron', id + '-trigger-cron-error')\"\n (input)=\"cron.set(value($event)); touch('cron')\" />\n <p class=\"hint\" [id]=\"id + '-trigger-cron-hint'\">{{ 'nh-assistant.admin.run-config.triggers.cron-hint' | translate }}</p>\n <ul class=\"examples\" [attr.aria-label]=\"'nh-assistant.admin.run-config.triggers.examples' | translate\">\n @for (example of examples; track example.cron) {\n <li><button type=\"button\" (click)=\"useExample(example.cron)\">{{ 'nh-assistant.admin.run-config.triggers.example.' + example.key | translate }}</button></li>\n }\n </ul>\n @if (errorKey('cron'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-cron-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('cron')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-trigger-zone'\">{{ 'nh-assistant.admin.run-config.triggers.time-zone' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-zone'\"\n [options]=\"timeZones\"\n [value]=\"timeZone()\"\n [noneLabel]=\"'UTC'\"\n [invalid]=\"fieldError('timeZone') !== null\"\n [describedBy]=\"describedBy(null, 'timeZone', id + '-trigger-zone-error')\"\n (valueChange)=\"timeZone.set($event); touch('timeZone')\" />\n @if (errorKey('timeZone'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-zone-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('timeZone')?.params }}</p>\n }\n </div>\n </div>\n @if (offersApplication()) {\n <!-- An agent that works on the whole application chooses what the schedule runs for. -->\n <div class=\"field\" data-schedule-target>\n <span class=\"label\" [id]=\"id + '-trigger-target-label'\">{{ 'nh-assistant.admin.run-config.triggers.target.title' | translate }}</span>\n <div\n class=\"choices\"\n role=\"radiogroup\"\n tabindex=\"-1\"\n [attr.aria-labelledby]=\"id + '-trigger-target-label'\"\n [attr.aria-invalid]=\"target() === 'application' && fieldError('subjectSet') ? true : null\"\n [attr.aria-describedby]=\"target() === 'application' ? describedBy(null, 'subjectSet', id + '-trigger-target-error') : null\">\n <label class=\"choice\" [class.selected]=\"target() === 'application'\">\n <input type=\"radio\" [name]=\"id + '-target'\" value=\"application\" [checked]=\"target() === 'application'\" (change)=\"setTarget('application')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.target.application' | translate }}</strong>\n <span class=\"muted\" data-target-hint>{{ (perDivision() ? 'nh-assistant.admin.run-config.triggers.target.application-per-division-hint' : 'nh-assistant.admin.run-config.triggers.target.application-hint') | translate }}</span>\n </span>\n </label>\n <label class=\"choice\" [class.selected]=\"target() === 'set'\">\n <input type=\"radio\" [name]=\"id + '-target'\" value=\"set\" [checked]=\"target() === 'set'\" (change)=\"setTarget('set')\" />\n <span>\n <strong>{{ 'nh-assistant.admin.run-config.triggers.target.set' | translate }}</strong>\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.target.set-hint' | translate }}</span>\n </span>\n </label>\n </div>\n @if (target() === 'application' && errorKey('subjectSet'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-target-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate }}</p>\n }\n </div>\n }\n @if (target() === 'set') {\n <div class=\"field\">\n <label [for]=\"id + '-trigger-set'\">{{ 'nh-assistant.admin.run-config.triggers.subject-set' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-set'\"\n [options]=\"subjectSets()\"\n [value]=\"subjectSet()\"\n [placeholder]=\"'nh-assistant.admin.run-config.choose' | translate\"\n [invalid]=\"fieldError('subjectSet') !== null\"\n [describedBy]=\"describedBy(id + '-trigger-set-hint', 'subjectSet', id + '-trigger-set-error')\"\n (valueChange)=\"subjectSet.set($event); touch('subjectSet')\" />\n <p class=\"hint\" [id]=\"id + '-trigger-set-hint'\">\n {{ (applicationDropped() ? 'nh-assistant.admin.run-config.triggers.target.dropped' : 'nh-assistant.admin.run-config.triggers.subject-set-hint') | translate }}\n </p>\n @if (errorKey('subjectSet'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-set-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('subjectSet')?.params }}</p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-trigger-message'\">{{ 'nh-assistant.admin.run-config.triggers.message' | translate }}</label>\n <textarea rows=\"2\" [id]=\"id + '-trigger-message'\" [value]=\"message()\"\n [attr.aria-invalid]=\"fieldError('message') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-trigger-message-hint', 'message', id + '-trigger-message-error')\"\n (input)=\"message.set(value($event)); touch('message')\"></textarea>\n <p class=\"hint\" [id]=\"id + '-trigger-message-hint'\">{{ 'nh-assistant.admin.run-config.triggers.message-hint' | translate }}</p>\n @if (errorKey('message'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-message-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('message')?.params }}</p>\n }\n </div>\n }\n </fieldset>\n\n <fieldset class=\"group\">\n <legend>{{ 'nh-assistant.admin.run-config.triggers.then.title' | translate }}</legend>\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-trigger-skill'\">{{ 'nh-assistant.admin.run-config.triggers.skill' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-skill'\"\n [options]=\"skills()\"\n [value]=\"skill()\"\n [noneLabel]=\"'nh-assistant.admin.run-config.triggers.agent-routes' | translate\"\n [invalid]=\"fieldError('skill') !== null\"\n [describedBy]=\"describedBy(null, 'skill', id + '-trigger-skill-error')\"\n (valueChange)=\"skill.set($event); touch('skill')\" />\n @if (errorKey('skill'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-skill-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('skill')?.params }}</p>\n }\n </div>\n <div class=\"field\">\n <label [for]=\"id + '-trigger-conflict'\">{{ 'nh-assistant.admin.run-config.triggers.conflict' | translate }}</label>\n <nh-assistant-picker\n [inputId]=\"id + '-trigger-conflict'\"\n [options]=\"conflictOptions()\"\n [value]=\"conflict()\"\n [invalid]=\"fieldError('conflict') !== null\"\n [describedBy]=\"describedBy(null, 'conflict', id + '-trigger-conflict-error')\"\n (valueChange)=\"conflict.set($any($event)); touch('conflict')\" />\n @if (errorKey('conflict'); as key) {\n <p class=\"field-error\" [id]=\"id + '-trigger-conflict-error'\"><nh-assistant-icon name=\"warning\" />{{ key | translate: fieldError('conflict')?.params }}</p>\n }\n </div>\n </div>\n </fieldset>\n\n @if (!editing()) {\n <p class=\"hint\">{{ 'nh-assistant.admin.run-config.triggers.starts-in-shadow' | translate }}</p>\n }\n <div class=\"field\">\n <label [for]=\"id + '-trigger-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input type=\"text\" autocomplete=\"off\" [id]=\"id + '-trigger-reason'\" [maxLength]=\"maxReason\" [value]=\"reason()\" [attr.aria-describedby]=\"id + '-trigger-reason-hint'\" (input)=\"reason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-trigger-reason-hint'\">{{ 'nh-assistant.admin.run-config.note-hint' | translate }}</p>\n </div>\n\n @if (hasErrors()) {\n <div class=\"form-error\" role=\"alert\" data-form-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n @if (serverError(); as failure) {\n @if (failure.code === 'assistant-validation') {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n } @else {\n {{ errorKeys() | nhAssistantTranslate: failure.code }}\n }\n } @else {\n {{ 'nh-assistant.admin.run-config.check-fields' | translate }}\n }\n @if (otherFieldErrors().length > 0) {\n <ul>\n @for (field of otherFieldErrors(); track field) {\n <li><span class=\"mono\">{{ field }}</span></li>\n }\n </ul>\n }\n </div>\n </div>\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]=\"busy()\">{{ (busy() ? 'nh-assistant.admin.saving' : 'nh-assistant.admin.save') | translate }}</button>\n </div>\n</form>\n","import { DatePipe, DecimalPipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n OnInit,\n afterNextRender,\n computed,\n inject,\n input,\n output,\n signal\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport { Observable, Subscription, forkJoin, map, startWith } from 'rxjs';\nimport {\n AdminAgent,\n AgentRunConfiguration,\n DataConsultation,\n DataSkill,\n DataSkillVersion,\n DataTrigger,\n McpServer,\n NhAssistantAdminApiService,\n NhAssistantError,\n RunCatalog,\n SkillComparison,\n ToolCatalogEntry,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n ɵNhAssistantPickerOption as NhAssistantPickerOption,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError\n} from '@newheap/platform-ai-chat';\nimport { NhAssistantAccountLabelComponent, NhAssistantAccountNames, NhAssistantAccountNamesErrorComponent } from '../nh-assistant-account-names';\nimport { codeTextKeys, policyKeys, readableId, skillDescriptionKeys, skillNameKeys, warningKeys } from './agent-texts';\nimport { NhAssistantAgentConsultationRoutesComponent } from './nh-assistant-agent-consultation-routes.component';\nimport { AgentFlowEntry, flowAccountability, typeName } from './run-config/agent-flow';\nimport { ConsultationRow, agentApprovalPolicy, consultationRows, consultationsClosed, showsConsultations } from './run-config/consultations';\nimport { ConsultationFormSaved, NhAssistantConsultationFormComponent } from './run-config/nh-assistant-consultation-form.component';\nimport { NhAssistantAgentFlowComponent } from './run-config/nh-assistant-agent-flow.component';\nimport { NhAssistantAgentWorkSetupComponent } from './run-config/nh-assistant-agent-work-setup.component';\nimport { NhAssistantRunSettingsFormComponent } from './run-config/nh-assistant-run-settings-form.component';\nimport { NhAssistantSkillFormComponent, SkillFormSaved } from './run-config/nh-assistant-skill-form.component';\nimport { NhAssistantTriggerFormComponent } from './run-config/nh-assistant-trigger-form.component';\nimport { describePolicy, runConfigLimits } from './run-config/run-config-shared';\n\nlet nextId = 0;\n\ntype Form = 'setup' | 'settings' | 'skill' | 'trigger' | 'consultation';\n\n/** A removal, promotion or discard that waits for its confirmation. */\ninterface Confirmation {\n action: 'remove-settings' | 'remove-skill' | 'remove-trigger' | 'remove-consultation' | 'promote' | 'discard';\n id: string;\n}\n\n/**\n * The run configuration of one agent as data: the run settings of an agent created in the\n * administration, its skills and triggers in code (read only) and as data, and the data that no\n * longer fits the code. It opens with the agent's flow: what it works on, when it runs, how it works,\n * whom it answers to, who approves and its results, each step with its problems and an entry point\n * to the form below that changes it; the agent editor (`editAgent`), the technical account of an\n * agent in code (`changeAccount`), the runs view (`openRuns`) and the MCP servers (`openMcpServers`)\n * belong to the page that hosts it. An agent created here that only chats gets a guided setup that\n * lets it work on its own. Administrators add and change data skills, live at once or as a candidate in shadow that\n * they compare with the live version and promote or discard; they add data triggers on the\n * application's events or on a schedule and put them live; a schedule without a subject set runs for\n * the whole application, or for every division of an agent that works per division. New skills and\n * triggers start in shadow; `changed` tells the agents page to reload the agent's skill states. Its\n * consultations (AC20) show what other assistants may consult it about: those in code read only, and\n * those defined as data, which administrators add, change and remove within the agent's ceiling in\n * code, each with the agents that ask it (`openAgent` opens the editor of one) and its problems,\n * followed by the switches that turn a route off for all of its consultations.\n */\n@Component({\n selector: 'nh-assistant-agent-run-configuration',\n standalone: true,\n imports: [\n DatePipe,\n DecimalPipe,\n TranslatePipe,\n NhAssistantTranslatePipe,\n NhAssistantIconComponent,\n NhAssistantAgentFlowComponent,\n NhAssistantAgentWorkSetupComponent,\n NhAssistantRunSettingsFormComponent,\n NhAssistantSkillFormComponent,\n NhAssistantTriggerFormComponent,\n NhAssistantConsultationFormComponent,\n NhAssistantAccountNamesErrorComponent,\n NhAssistantAccountLabelComponent,\n NhAssistantAgentConsultationRoutesComponent\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './nh-assistant-agent-run-configuration.component.html',\n styleUrls: ['../nh-assistant-admin-shared.scss', './nh-assistant-agent-feedback-report.component.scss', './run-config/run-config-forms.scss']\n})\nexport class NhAssistantAgentRunConfigurationComponent implements OnInit {\n private readonly admin = inject(NhAssistantAdminApiService);\n private readonly translate = inject(TranslateService);\n private readonly injector = inject(Injector);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private loadSubscription?: Subscription;\n private actionSubscription?: Subscription;\n private detailSubscription?: Subscription;\n /** The flow's entry point that opened the form, which takes the focus back when the form closes. */\n private returnFocus: HTMLElement | null = null;\n\n readonly agent = input.required<AdminAgent>();\n /** Opens the guided setup at once, for an agent that was just created to work on its own. */\n readonly startSetup = input(false);\n /** The tool catalog, to show what the agent's tool selectors offer in the skill forms and the flow. */\n readonly tools = input<readonly ToolCatalogEntry[]>([]);\n /**\n * The MCP servers, so the flow shows whether the agent's servers are used in runs without a person;\n * `null` while unknown.\n */\n readonly servers = input<readonly McpServer[] | null>(null);\n /** Every agent of the administration, to name the agents that ask the agent's consultations. */\n readonly agents = input<readonly AdminAgent[]>([]);\n /** A change of the run configuration changed the agent's skills or state. */\n readonly changed = output<void>();\n /** The flow asks to open the agent editor: what it works on, its tools, MCP servers and groups. */\n readonly editAgent = output<void>();\n /** The flow asks to change the technical account of an agent in code. */\n readonly changeAccount = output<void>();\n /** The flow asks to open the agent's runs. */\n readonly openRuns = output<void>();\n /** The flow asks to open the MCP servers, whose background use decides what runs without a person use. */\n readonly openMcpServers = output<void>();\n /** Opens the editor of an agent that asks one of the agent's consultations, by its id. */\n readonly openAgent = output<string>();\n\n readonly id = `nh-assistant-run-configuration-${nextId++}`;\n readonly maxReason = runConfigLimits.reason;\n readonly skillNameKeys = skillNameKeys;\n readonly warningKeys = warningKeys;\n readonly skillDescriptionKeys = skillDescriptionKeys;\n readonly readableId = readableId;\n\n readonly loading = signal(true);\n readonly loadFailed = signal(false);\n readonly busy = signal(false);\n readonly catalog = signal<RunCatalog | null>(null);\n readonly configuration = signal<AgentRunConfiguration | null>(null);\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n readonly saved = signal<string | null>(null);\n /** The warnings of the skill that was just saved, shown with the saved message. */\n readonly savedWarnings = signal<readonly string[]>([]);\n readonly form = signal<Form | null>(null);\n readonly confirming = signal<Confirmation | null>(null);\n readonly reason = signal('');\n /** The item whose action failed, so its error shows next to it: `settings`, `skill:{id}` or `trigger:{id}`. */\n readonly actionTarget = signal<string | null>(null);\n /**\n * The names of the account the agent answers to and of the people who changed skills, once known,\n * and why they are not.\n */\n readonly accountNames = new NhAssistantAccountNames();\n /**\n * The name of the account the agent answers to, once known: the technical account of its run\n * settings, or of an agent in code.\n */\n readonly accountName = computed(() => {\n const configuration = this.configuration();\n const actorId = configuration?.source === 'admin'\n ? configuration.runSettings?.serviceAccountActorId\n : this.agent().serviceAccount?.actorId;\n return actorId ? this.accountNames.names().get(actorId) ?? null : null;\n });\n /** The agent's name; an agent in code names itself with a translation key. */\n readonly agentName = computed(() => {\n this.language();\n const agent = this.agent();\n return this.translated(codeTextKeys(agent.source, agent.displayName), agent.displayName);\n });\n\n /** The skill being changed; `null` with the skill form open adds a new skill. */\n readonly editingSkill = signal<DataSkill | null>(null);\n /** The trigger being changed; `null` with the trigger form open adds a new trigger. */\n readonly editingTrigger = signal<DataTrigger | null>(null);\n /** The consultation being changed; `null` with the consultation form open adds a new one. */\n readonly editingConsultation = signal<DataConsultation | null>(null);\n /** Counts the loads, so the route switches read the agent's routes again after a change. */\n readonly loads = signal(0);\n readonly comparison = signal<{ skillId: string; result: SkillComparison | null; failed: boolean } | null>(null);\n readonly versions = signal<{ skillId: string; items: DataSkillVersion[] | null; failed: boolean } | null>(null);\n\n private readonly language = toSignal(\n this.translate.onLangChange.pipe(map(event => event.lang), startWith(this.translate.currentLang)),\n { initialValue: this.translate.currentLang });\n\n readonly isAdminAgent = computed(() => this.configuration()?.source === 'admin');\n /** An agent created in the administration gets skills and triggers once it has run settings. */\n readonly canAddRunData = computed(() => {\n const configuration = this.configuration();\n return configuration !== null && (configuration.source === 'code' || configuration.runSettings !== null);\n });\n readonly skillOptions = computed<NhAssistantPickerOption[]>(() => {\n this.language();\n const configuration = this.configuration();\n return configuration\n ? [\n ...configuration.codeSkills.map(skill => ({\n value: skill.skillId,\n label: this.skillName(skill.skillId),\n description: this.translated(skillDescriptionKeys(configuration.agentId, skill.skillId), skill.description)\n })),\n ...configuration.dataSkills.map(skill => ({ value: skill.skillId, label: this.skillName(skill.skillId), description: skill.description }))\n ]\n : [];\n });\n readonly skillIds = computed(() => this.skillOptions().map(option => option.value));\n readonly triggerIds = computed(() => {\n const configuration = this.configuration();\n return configuration ? [...configuration.codeTriggers, ...configuration.dataTriggers].map(trigger => trigger.triggerId) : [];\n });\n readonly problems = computed(() => this.configuration()?.problems ?? []);\n /** The consultations in code and as data, by subject type. */\n readonly consultationRows = computed(() => {\n const configuration = this.configuration();\n return configuration ? consultationRows(configuration) : [];\n });\n readonly showConsultations = computed(() => {\n const configuration = this.configuration();\n return configuration !== null && showsConsultations(configuration, this.catalog());\n });\n /** The ceiling within which administrators may define the agent's consultations; `null` for none. */\n readonly consultationCeiling = computed(() => this.configuration()?.consultationCeiling ?? null);\n /** Why administrators cannot add a consultation now, or `null` when they can. */\n readonly consultationsClosed = computed(() => {\n const configuration = this.configuration();\n return configuration ? consultationsClosed(configuration, this.catalog(), this.agent()) : null;\n });\n /** The subject types the agent already has a consultation about. */\n readonly consultationTypes = computed(() => this.consultationRows().map(row => row.subjectType));\n /** Whom the agent answers to, which decides whether a consultation may lend its rights. */\n readonly accountability = computed(() => {\n const configuration = this.configuration();\n return configuration ? flowAccountability(configuration)?.accountability ?? null : null;\n });\n readonly approvalPolicy = computed(() => {\n const configuration = this.configuration();\n return configuration ? agentApprovalPolicy(configuration) : null;\n });\n /** What the run settings' approval policy means, in a sentence. */\n readonly settingsPolicy = computed(() => {\n this.language();\n const name = this.configuration()?.runSettings?.approvalPolicy;\n const summary = this.catalog()?.approvalPolicySummaries?.find(item => item.name === name);\n return summary ? describePolicy(summary, (key, params) => this.translate.instant(key, params) as string) : null;\n });\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.loadSubscription?.unsubscribe();\n this.actionSubscription?.unsubscribe();\n this.detailSubscription?.unsubscribe();\n });\n }\n\n ngOnInit(): void {\n this.load(this.startSetup());\n }\n\n load(openSetup = false): void {\n this.loading.set(true);\n this.loadFailed.set(false);\n this.loadSubscription?.unsubscribe();\n this.loadSubscription = forkJoin([this.admin.getRunCatalog(), this.admin.getAgentConfiguration(this.agent().id)]).subscribe({\n next: ([catalog, configuration]) => {\n this.catalog.set(catalog);\n this.configuration.set(configuration);\n this.loading.set(false);\n this.loads.update(count => count + 1);\n this.accountNames.load([\n configuration.runSettings?.serviceAccountActorId,\n this.agent().serviceAccount?.actorId,\n ...configuration.dataSkills.map(skill => skill.changedBy),\n ...(configuration.dataConsultations ?? []).map(consultation => consultation.changedBy)\n ]);\n if (openSetup && configuration.source === 'admin' && configuration.runSettings === null) {\n this.open('setup');\n }\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n openSetup(): void {\n this.open('setup');\n }\n\n editSettings(): void {\n this.open('settings');\n }\n\n removeSettings(): void {\n const version = this.configuration()?.runSettings?.version ?? null;\n this.run(this.admin.removeRunSettings(this.agent().id, { expectedVersion: version }), 'nh-assistant.admin.run-config.settings.removed', 'settings');\n }\n\n addSkill(): void {\n this.editingSkill.set(null);\n this.open('skill');\n }\n\n editSkill(skill: DataSkill): void {\n this.editingSkill.set(skill);\n this.open('skill');\n }\n\n removeSkill(skill: DataSkill): void {\n this.run(\n this.admin.removeDataSkill(this.agent().id, skill.skillId, { expectedVersion: skill.version }),\n 'nh-assistant.admin.run-config.skills.removed',\n `skill:${skill.skillId}`);\n }\n\n promote(skill: DataSkill): void {\n const candidate = skill.candidate;\n if (candidate) {\n this.run(\n this.admin.promoteSkillCandidate(this.agent().id, skill.skillId, { version: candidate.version, reason: blank(this.reason()) }),\n 'nh-assistant.admin.run-config.candidate.promoted',\n `skill:${skill.skillId}`);\n }\n }\n\n discard(skill: DataSkill): void {\n const candidate = skill.candidate;\n if (candidate) {\n this.run(\n this.admin.discardSkillCandidate(this.agent().id, skill.skillId, { version: candidate.version, reason: blank(this.reason()) }),\n 'nh-assistant.admin.run-config.candidate.discarded',\n `skill:${skill.skillId}`);\n }\n }\n\n /** Shows or hides the comparison of a skill's candidate with its live version. */\n toggleComparison(skill: DataSkill): void {\n if (this.comparison()?.skillId === skill.skillId) {\n this.comparison.set(null);\n return;\n }\n\n this.versions.set(null);\n this.comparison.set({ skillId: skill.skillId, result: null, failed: false });\n this.detailSubscription?.unsubscribe();\n this.detailSubscription = this.admin.compareSkillCandidate(this.agent().id, skill.skillId).subscribe({\n next: result => this.comparison.set({ skillId: skill.skillId, result, failed: false }),\n error: () => this.comparison.set({ skillId: skill.skillId, result: null, failed: true })\n });\n }\n\n /** Shows or hides the version history of a skill. */\n toggleVersions(skill: DataSkill): void {\n if (this.versions()?.skillId === skill.skillId) {\n this.versions.set(null);\n return;\n }\n\n this.comparison.set(null);\n this.versions.set({ skillId: skill.skillId, items: null, failed: false });\n this.detailSubscription?.unsubscribe();\n this.detailSubscription = this.admin.getDataSkillVersions(this.agent().id, skill.skillId).subscribe({\n next: items => {\n this.versions.set({ skillId: skill.skillId, items, failed: false });\n this.accountNames.load(items.map(item => item.createdBy));\n },\n error: () => this.versions.set({ skillId: skill.skillId, items: null, failed: true })\n });\n }\n\n addTrigger(): void {\n this.editingTrigger.set(null);\n this.open('trigger');\n }\n\n editTrigger(trigger: DataTrigger): void {\n this.editingTrigger.set(trigger);\n this.open('trigger');\n }\n\n setTriggerShadow(trigger: DataTrigger, shadow: boolean): void {\n this.run(\n this.admin.setDataTriggerShadow(this.agent().id, trigger.triggerId, { mode: shadow ? 'shadow' : 'live', reason: null }),\n shadow ? 'nh-assistant.admin.run-config.triggers.in-shadow' : 'nh-assistant.admin.run-config.triggers.live',\n `trigger:${trigger.triggerId}`);\n }\n\n removeTrigger(trigger: DataTrigger): void {\n this.run(\n this.admin.removeDataTrigger(this.agent().id, trigger.triggerId, { expectedVersion: trigger.version }),\n 'nh-assistant.admin.run-config.triggers.removed',\n `trigger:${trigger.triggerId}`);\n }\n\n addConsultation(): void {\n this.editingConsultation.set(null);\n this.open('consultation');\n }\n\n editConsultation(consultation: DataConsultation): void {\n this.editingConsultation.set(consultation);\n this.open('consultation');\n }\n\n removeConsultation(consultation: DataConsultation): void {\n this.run(\n this.admin.removeDataConsultation(this.agent().id, consultation.subjectType, { expectedVersion: consultation.version }),\n 'nh-assistant.admin.run-config.consultations.removed',\n `consultation:${consultation.subjectType}`);\n }\n\n onConsultationSaved(result: ConsultationFormSaved): void {\n this.finish(result.added ? 'nh-assistant.admin.run-config.consultations.added' : 'nh-assistant.admin.run-config.consultations.saved');\n }\n\n /** The name of a subject type, as the run catalog names it in the reader's language. */\n typeName(subjectType: string): string {\n return typeName(this.catalog(), subjectType);\n }\n\n /** An agent's name: the translation of an agent in code, the administrator's text, or its id. */\n agentNameOf(agentId: string): string {\n const agent = this.agents().find(item => item.id === agentId);\n return agent ? this.translated(codeTextKeys(agent.source, agent.displayName), agent.displayName) : agentId;\n }\n\n /** Who may ask a consultation defined as data, in a sentence; `null` for one in code, whose code says it. */\n askSentence(row: ConsultationRow): string | null {\n const data = row.data;\n if (!data) {\n return null;\n }\n const base = 'nh-assistant.admin.run-config.consultations.summary';\n const role = this.translate.instant(`nh-assistant.admin.run-config.consultations.roles-lower.${data.minimumRole}`) as string;\n const ask = this.translate.instant(`${base}.ask`, { role }) as string;\n const policy = data.askerPolicy\n ? this.translate.instant(`${base}.asker-policy`, { policy: this.translated(policyKeys(data.askerPolicy), data.askerPolicy) }) as string\n : this.translate.instant(`${base}.asker-policy-agent`) as string;\n return `${ask} ${policy}`;\n }\n\n /** What the consultation may do and who decides its proposals, by the routes in effect. */\n decideSentence(row: ConsultationRow): string {\n const base = 'nh-assistant.admin.run-config.consultations.summary';\n if (row.routes.length === 0) {\n return this.translate.instant(`${base}.read-only`) as string;\n }\n const routes = row.routes\n .map(route => this.translate.instant(`nh-assistant.admin.agents.consultation-routes.route.${route}`) as string)\n .join('; ');\n if (!row.data) {\n return this.translate.instant(`${base}.proposes-code`, { routes }) as string;\n }\n const role = this.translate.instant(`nh-assistant.admin.run-config.consultations.roles-lower.${row.data.proposalRole}`) as string;\n return this.translate.instant(`${base}.proposes`, { role, routes }) as string;\n }\n\n /** A form saved: show what happened and reload, which every change may affect. */\n onSetupCompleted(live: boolean): void {\n this.finish(live ? 'nh-assistant.admin.run-config.setup.saved-live' : 'nh-assistant.admin.run-config.setup.saved-shadow');\n }\n\n onSettingsSaved(): void {\n this.finish('nh-assistant.admin.run-config.settings.saved');\n }\n\n onSkillSaved(result: SkillFormSaved): void {\n this.finish(\n result.candidate\n ? 'nh-assistant.admin.run-config.skills.saved-candidate'\n : result.added ? 'nh-assistant.admin.run-config.skills.added' : 'nh-assistant.admin.run-config.skills.saved',\n result.skill.warnings ?? []);\n }\n\n onTriggerSaved(added: boolean): void {\n this.finish(added ? 'nh-assistant.admin.run-config.triggers.added' : 'nh-assistant.admin.run-config.triggers.saved');\n }\n\n confirm(action: Confirmation['action'], id: string): void {\n this.form.set(null);\n this.error.set(null);\n this.saved.set(null);\n this.reason.set('');\n this.confirming.set({ action, id });\n }\n\n isConfirming(action: Confirmation['action'], id: string): boolean {\n const confirming = this.confirming();\n return confirming?.action === action && confirming.id === id;\n }\n\n /**\n * An entry point of the flow: the forms of the run configuration open below with the focus in them;\n * the editor, the account, the runs and the MCP servers belong to the host.\n */\n onFlowEntry(entry: AgentFlowEntry): void {\n const opener = this.host.nativeElement.ownerDocument.activeElement;\n switch (entry.kind) {\n case 'setup':\n this.openFromFlow(opener, () => this.openSetup());\n return;\n case 'settings':\n this.openFromFlow(opener, () => this.editSettings());\n return;\n case 'add-skill':\n this.openFromFlow(opener, () => this.addSkill());\n return;\n case 'edit-skill': {\n const skill = this.configuration()?.dataSkills.find(item => item.skillId === entry.skillId);\n if (skill) {\n this.openFromFlow(opener, () => this.editSkill(skill));\n }\n return;\n }\n case 'add-trigger':\n this.openFromFlow(opener, () => this.addTrigger());\n return;\n case 'edit-trigger': {\n const trigger = this.configuration()?.dataTriggers.find(item => item.triggerId === entry.triggerId);\n if (trigger) {\n this.openFromFlow(opener, () => this.editTrigger(trigger));\n }\n return;\n }\n case 'add-consultation':\n this.openFromFlow(opener, () => this.addConsultation());\n return;\n case 'edit-consultation': {\n const consultation = this.configuration()?.dataConsultations?.find(item => item.subjectType === entry.subjectType);\n if (consultation) {\n this.openFromFlow(opener, () => this.editConsultation(consultation));\n }\n return;\n }\n case 'edit-agent':\n this.editAgent.emit();\n return;\n case 'account':\n this.changeAccount.emit();\n return;\n case 'runs':\n this.openRuns.emit();\n return;\n case 'mcp-servers':\n this.openMcpServers.emit();\n return;\n }\n }\n\n cancel(): void {\n const form = this.form();\n const opener = this.returnFocus;\n this.returnFocus = null;\n this.form.set(null);\n this.confirming.set(null);\n this.error.set(null);\n // Back to the action that opened the form: the flow's entry point, or the action of its section.\n afterNextRender(() => {\n const target = opener?.isConnected\n ? opener\n : this.host.nativeElement.querySelector<HTMLElement>(`[data-open-form=\"${form}\"]`);\n target?.focus();\n }, { injector: this.injector });\n }\n\n value(event: Event): string {\n return (event.target as HTMLInputElement).value;\n }\n\n /** A skill's name: the application's translation, or a readable form of its id. */\n skillName(skillId: string | null | undefined): string {\n return skillId ? this.translated(skillNameKeys(this.agent().id, skillId), readableId(skillId)) : '';\n }\n\n /** A person's name, or the id when the application does not know it. */\n nameOf(actorId: string | null | undefined): string {\n return this.accountNames.nameOf(actorId);\n }\n\n /** The account ID as the tooltip of a name shown in its place. */\n accountTitle(actorId: string | null | undefined): string | null {\n return this.accountNames.idTitleOf(actorId);\n }\n\n /** The first of the keys with a translation, or the fallback. */\n private translated(keys: readonly string[], fallback: string): string {\n for (const key of keys) {\n const value = this.translate.instant(key) as unknown;\n if (typeof value === 'string' && value.length > 0 && value !== key) {\n return value;\n }\n }\n return fallback;\n }\n\n /** Opens a form for the flow and remembers the entry point that opened it. */\n private openFromFlow(opener: Element | null, openForm: () => void): void {\n openForm();\n this.returnFocus = opener instanceof HTMLElement ? opener : null;\n }\n\n private finish(savedKey: string, warnings: readonly string[] = []): void {\n this.returnFocus = null;\n this.form.set(null);\n this.saved.set(savedKey);\n this.savedWarnings.set(warnings);\n this.changed.emit();\n this.load();\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>('[data-saved]')?.focus(), { injector: this.injector });\n }\n\n /** Opens one form at a time and moves the focus into it. */\n private open(form: Form): void {\n this.returnFocus = null;\n this.confirming.set(null);\n this.error.set(null);\n this.saved.set(null);\n this.reason.set('');\n this.form.set(form);\n afterNextRender(() => {\n this.host.nativeElement.querySelector<HTMLElement>(\n `[data-form=\"${form}\"] input:not([disabled]), [data-form=\"${form}\"] textarea, [data-work-setup] input:not([disabled])`)?.focus();\n }, { injector: this.injector });\n }\n\n /** Whether the last failed action concerned this item, so its error shows there. */\n failed(target: string): boolean {\n return this.error() !== null && this.actionTarget() === target;\n }\n\n /** Runs a change and reloads the configuration, which every change may affect. */\n private run(request: Observable<unknown>, savedKey: string, target: string): void {\n this.busy.set(true);\n this.error.set(null);\n this.saved.set(null);\n this.actionTarget.set(target);\n this.actionSubscription?.unsubscribe();\n this.actionSubscription = request.subscribe({\n error: (error: unknown) => {\n this.busy.set(false);\n this.error.set(toNhAssistantError(error));\n },\n complete: () => {\n this.busy.set(false);\n this.confirming.set(null);\n this.comparison.set(null);\n this.versions.set(null);\n this.finish(savedKey);\n }\n });\n }\n}\n\nfunction blank(value: string): string | null {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n","<section class=\"section\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-busy]=\"loading() || busy()\">\n <header class=\"section-header\">\n <div>\n <h3 [id]=\"id + '-title'\">{{ 'nh-assistant.admin.run-config.title' | translate: { name: agentName() } }}</h3>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.description' | translate }}</p>\n </div>\n </header>\n\n @if (saved(); as key) {\n <p class=\"message success\" role=\"status\" tabindex=\"-1\" data-saved>{{ key | translate }}</p>\n <!-- The save succeeded; a warning says what may still keep the skill from working. -->\n @for (warning of savedWarnings(); track warning) {\n <p class=\"message warning\" role=\"status\" [attr.data-saved-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('skill', warning) | nhAssistantTranslate: warning }}\n </p>\n }\n }\n\n @if (loading() && !configuration()) {\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 (configuration(); as config) {\n <nh-assistant-account-names-error [names]=\"accountNames\" />\n @if (problems().length > 0) {\n <!-- Each problem shows at the step of the flow it concerns, with the form that fixes it. -->\n <p class=\"message warning\" role=\"status\" data-problems>\n <nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.run-config.flow.problems' | translate }}\n </p>\n }\n\n <!-- The agent at a glance; the forms below change what each step shows. -->\n <nh-assistant-agent-flow\n [agent]=\"agent()\"\n [configuration]=\"config\"\n [catalog]=\"catalog()\"\n [tools]=\"tools()\"\n [servers]=\"servers()\"\n [accountName]=\"accountName()\"\n [busy]=\"busy()\"\n (entry)=\"onFlowEntry($event)\" />\n\n @if (config.source === 'admin') {\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-settings-title'\" data-run-settings>\n <header class=\"section-header\">\n <h4 [id]=\"id + '-settings-title'\">{{ 'nh-assistant.admin.run-config.settings.title' | translate }}</h4>\n </header>\n @if (form() === 'setup') {\n <nh-assistant-agent-work-setup\n [agentId]=\"config.agentId\"\n [agentName]=\"agentName()\"\n [catalog]=\"catalog()\"\n [worksOn]=\"agent()\"\n [toolSelectors]=\"config.toolSelectors\"\n [toolCatalog]=\"tools()\"\n [takenSkillIds]=\"skillIds()\"\n [takenTriggerIds]=\"triggerIds()\"\n (completed)=\"onSetupCompleted($event.live)\"\n (cancelled)=\"cancel()\" />\n } @else if (form() === 'settings') {\n <nh-assistant-run-settings-form\n [agentId]=\"config.agentId\"\n [catalog]=\"catalog()\"\n [settings]=\"config.runSettings\"\n (saved)=\"onSettingsSaved()\"\n (cancelled)=\"cancel()\" />\n } @else if (config.runSettings; as settings) {\n <dl class=\"review\" data-settings-summary>\n <dt>{{ 'nh-assistant.admin.run-config.settings.who.short' | translate }}</dt>\n <dd>\n {{ 'nh-assistant.admin.run-config.settings.accountability.' + settings.accountability | translate }}\n @if (settings.serviceAccountActorId; as accountId) {\n <span class=\"block\" data-account-name>\n <nh-assistant-account-label [actorId]=\"accountId\" [name]=\"accountName()\" />\n </span>\n }\n </dd>\n <dt>{{ 'nh-assistant.admin.run-config.way-of-working' | translate }}</dt>\n <dd>{{ settings.ruleHandler ?? ('nh-assistant.admin.run-config.model' | translate) }}</dd>\n <dt>{{ 'nh-assistant.admin.run-config.approval-policy' | translate }}</dt>\n <dd>\n {{ settings.approvalPolicy ?? ('nh-assistant.admin.run-config.settings.approval.default' | translate) }}\n @if (settingsPolicy(); as sentence) {\n <span class=\"muted block\">{{ sentence }}</span>\n }\n </dd>\n <dt>{{ 'nh-assistant.admin.agents.version-label' | translate }}</dt>\n <dd>\n {{ 'nh-assistant.admin.agents.version' | translate: { version: settings.version } }}\n @if (!settings.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n </dd>\n </dl>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.rights' | translate }}</p>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" data-open-form=\"settings\" [disabled]=\"busy()\" (click)=\"editSettings()\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.run-config.settings.edit' | translate }}\n </button>\n @if (isConfirming('remove-settings', config.agentId)) {\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.settings.remove-explain' | translate }}</span>\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"removeSettings()\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('remove-settings', config.agentId)\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.run-config.settings.remove' | translate }}\n </button>\n }\n </div>\n @if (failed('settings')) {\n <p class=\"form-error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: error()!.code }}</p>\n }\n } @else {\n <div class=\"state\" data-setup-offer>\n <p>{{ 'nh-assistant.admin.run-config.settings.empty' | translate }}</p>\n <div class=\"card-actions\">\n <button class=\"primary\" type=\"button\" data-open-form=\"setup\" [disabled]=\"busy()\" (click)=\"openSetup()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.setup.start' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" data-open-form=\"settings\" [disabled]=\"busy()\" (click)=\"editSettings()\">\n {{ 'nh-assistant.admin.run-config.settings.add' | translate }}\n </button>\n </div>\n </div>\n }\n </section>\n }\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-skills-title'\" data-skills>\n <header class=\"section-header\">\n <div>\n <h4 [id]=\"id + '-skills-title'\">{{ 'nh-assistant.admin.agents.skills.title' | translate }}</h4>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.skills.description' | translate }}</p>\n </div>\n <button class=\"secondary\" type=\"button\" data-open-form=\"skill\" [disabled]=\"busy() || !canAddRunData() || form() === 'skill'\" (click)=\"addSkill()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.skills.add' | translate }}\n </button>\n </header>\n @if (!canAddRunData()) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.needs-settings' | translate }}</p>\n }\n\n @if (form() === 'skill') {\n <nh-assistant-skill-form\n [agentId]=\"config.agentId\"\n [catalog]=\"catalog()\"\n [toolSelectors]=\"config.toolSelectors\"\n [toolCatalog]=\"tools()\"\n [skill]=\"editingSkill()\"\n [takenIds]=\"skillIds()\"\n (saved)=\"onSkillSaved($event)\"\n (cancelled)=\"cancel()\" />\n }\n\n @if (config.codeSkills.length === 0 && config.dataSkills.length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.run-config.skills.empty' | translate }}</p>\n } @else {\n <ul class=\"skills\">\n @for (skill of config.codeSkills; track skill.skillId) {\n <li class=\"skill\" [attr.data-code-skill]=\"skill.skillId\">\n <div class=\"card-header\">\n <strong>{{ (skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) }}</strong>\n <span class=\"mono muted\">{{ skill.skillId }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n </div>\n <p class=\"muted\">{{ skillDescriptionKeys(config.agentId, skill.skillId) | nhAssistantTranslate: skill.description }}</p>\n </li>\n }\n @for (skill of config.dataSkills; track skill.skillId) {\n <li class=\"skill\" [attr.data-data-skill]=\"skill.skillId\">\n <div class=\"card-header\">\n <strong>{{ (skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) }}</strong>\n <span class=\"mono muted\">{{ skill.skillId }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.version' | translate: { version: skill.version } }}</span>\n @if (!skill.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n @if (skill.candidate) {\n <span class=\"badge warning\" data-candidate-badge>{{ 'nh-assistant.admin.run-config.candidate.badge' | translate: { version: skill.candidate.version } }}</span>\n }\n </div>\n <p class=\"muted\">{{ skill.description }}</p>\n @for (warning of skill.warnings ?? []; track warning) {\n <p class=\"message warning\" [attr.data-skill-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('skill', warning) | nhAssistantTranslate: warning }}\n </p>\n }\n <div class=\"meta\">\n <span>{{ skill.ruleHandler ? ('nh-assistant.admin.run-config.rule-handler-value' | translate: { name: skill.ruleHandler }) : ('nh-assistant.admin.run-config.model' | translate) }}</span>\n @if (skill.profile) {\n <span>{{ 'nh-assistant.admin.run-config.profile-value' | translate: { name: skill.profile } }}</span>\n }\n <span>{{ (skill.tools.length === 1 ? 'nh-assistant.admin.agents.tool-count-one' : 'nh-assistant.admin.agents.tool-count') | translate: { count: skill.tools.length } }}</span>\n <span [attr.title]=\"accountTitle(skill.changedBy)\">{{ 'nh-assistant.admin.run-config.changed' | translate: { user: nameOf(skill.changedBy), date: (skill.changedAt | date: 'medium') } }}</span>\n </div>\n @if (skill.candidate; as candidate) {\n <div class=\"subsection\" data-candidate>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.candidate.explain' | translate: { version: candidate.version, description: candidate.description } }}</p>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [attr.aria-expanded]=\"comparison()?.skillId === skill.skillId\" (click)=\"toggleComparison(skill)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.run-config.candidate.compare' | translate }}\n </button>\n @if (isConfirming('promote', skill.skillId)) {\n <button class=\"primary\" type=\"button\" [disabled]=\"busy()\" (click)=\"promote(skill)\">{{ 'nh-assistant.admin.run-config.candidate.confirm-promote' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else if (isConfirming('discard', skill.skillId)) {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"discard(skill)\">{{ 'nh-assistant.admin.run-config.candidate.confirm-discard' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"secondary\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('promote', skill.skillId)\">{{ 'nh-assistant.admin.run-config.candidate.promote' | translate }}</button>\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('discard', skill.skillId)\">{{ 'nh-assistant.admin.run-config.candidate.discard' | translate }}</button>\n }\n </div>\n @if (comparison(); as shown) {\n @if (shown.skillId === skill.skillId) {\n @if (shown.failed) {\n <p class=\"message error\" role=\"alert\">{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n } @else if (shown.result; as result) {\n <div class=\"table-scroll\">\n <table class=\"summary-table\" data-comparison>\n <caption class=\"visually-hidden\">{{ 'nh-assistant.admin.run-config.candidate.comparison' | translate: { skill: (skillNameKeys(config.agentId, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) } }}</caption>\n <thead>\n <tr>\n <th scope=\"col\">{{ 'nh-assistant.admin.evaluation.columns.measure' | translate }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.run-config.candidate.live-column' | translate: { version: result.live.version } }}</th>\n <th scope=\"col\">{{ 'nh-assistant.admin.run-config.candidate.candidate-column' | translate: { version: result.candidate.version } }}</th>\n </tr>\n </thead>\n <tbody>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.runs' | translate }}</th><td>{{ result.live.runs | number }}</td><td>{{ result.candidate.runs | number }}</td></tr>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.completed' | translate }}</th><td>{{ result.live.completed | number }}</td><td>{{ result.candidate.completed | number }}</td></tr>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.failed' | translate }}</th><td>{{ result.live.failed | number }}</td><td>{{ result.candidate.failed | number }}</td></tr>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.proposals' | translate }}</th><td>{{ result.live.proposals | number }}</td><td>{{ result.candidate.proposals | number }}</td></tr>\n <tr><th scope=\"row\">{{ 'nh-assistant.admin.run-config.candidate.tokens' | translate }}</th><td>{{ result.live.tokens | number }}</td><td>{{ result.candidate.tokens | number }}</td></tr>\n </tbody>\n </table>\n </div>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.candidate.paired' | translate: { count: result.pairedEvents, date: (result.from | date: 'medium') } }}</p>\n } @else {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n }\n }\n }\n </div>\n }\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"busy()\" (click)=\"editSkill(skill)\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" [attr.aria-expanded]=\"versions()?.skillId === skill.skillId\" (click)=\"toggleVersions(skill)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.run-config.skills.versions' | translate }}\n </button>\n @if (isConfirming('remove-skill', skill.skillId)) {\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.skills.remove-explain' | translate }}</span>\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"removeSkill(skill)\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('remove-skill', skill.skillId)\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.delete' | translate }}\n </button>\n }\n </div>\n @if (failed('skill:' + skill.skillId)) {\n <p class=\"form-error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: error()!.code }}</p>\n }\n @if (versions(); as shown) {\n @if (shown.skillId === skill.skillId) {\n @if (shown.failed) {\n <p class=\"message error\" role=\"alert\">{{ 'nh-assistant.admin.load-failed' | translate }}</p>\n } @else if (shown.items; as items) {\n <ul class=\"history\" data-versions>\n @for (version of items; track version.version) {\n <li>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.version' | translate: { version: version.version } }}</span>\n <span class=\"badge\" [class.success]=\"version.status === 'live'\" [class.warning]=\"version.status === 'candidate'\">{{ 'nh-assistant.admin.run-config.status.' + version.status | translate }}</span>\n <span>{{ version.description }}</span>\n <span class=\"muted\" [attr.title]=\"accountTitle(version.createdBy)\">{{ 'nh-assistant.admin.run-config.changed' | translate: { user: nameOf(version.createdBy), date: (version.createdAt | date: 'medium') } }}</span>\n @if (version.reason) {\n <span class=\"muted\">{{ 'nh-assistant.admin.agents.state.reason' | translate: { reason: version.reason } }}</span>\n }\n </li>\n }\n </ul>\n } @else {\n <p class=\"state\" role=\"status\">{{ 'nh-assistant.admin.loading' | translate }}</p>\n }\n }\n }\n </li>\n }\n </ul>\n }\n </section>\n\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-triggers-title'\" data-triggers>\n <header class=\"section-header\">\n <div>\n <h4 [id]=\"id + '-triggers-title'\">{{ 'nh-assistant.admin.run-config.triggers.title' | translate }}</h4>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.description' | translate }}</p>\n </div>\n <button class=\"secondary\" type=\"button\" data-open-form=\"trigger\" [disabled]=\"busy() || !canAddRunData() || form() === 'trigger'\" (click)=\"addTrigger()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.triggers.add' | translate }}\n </button>\n </header>\n\n @if (form() === 'trigger') {\n <nh-assistant-trigger-form\n [agentId]=\"config.agentId\"\n [catalog]=\"catalog()\"\n [worksOn]=\"agent()\"\n [skills]=\"skillOptions()\"\n [trigger]=\"editingTrigger()\"\n [takenIds]=\"triggerIds()\"\n (saved)=\"onTriggerSaved($event.added)\"\n (cancelled)=\"cancel()\" />\n }\n\n @if (config.codeTriggers.length === 0 && config.dataTriggers.length === 0) {\n <p class=\"state\">{{ 'nh-assistant.admin.run-config.triggers.empty' | translate }}</p>\n } @else {\n <ul class=\"skills\">\n @for (trigger of config.codeTriggers; track trigger.triggerId) {\n <li class=\"skill\" [attr.data-code-trigger]=\"trigger.triggerId\">\n <div class=\"card-header\">\n <span class=\"mono\">{{ trigger.triggerId }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.run-config.triggers.sources.' + trigger.source | translate }}</span>\n </div>\n @if (trigger.skillId) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.triggers.skill-value' | translate: { skill: skillName(trigger.skillId) } }}</p>\n }\n </li>\n }\n @for (trigger of config.dataTriggers; track trigger.triggerId) {\n <li class=\"skill\" [attr.data-data-trigger]=\"trigger.triggerId\">\n <div class=\"card-header\">\n <span class=\"mono\">{{ trigger.triggerId }}</span>\n <span class=\"badge\">{{ 'nh-assistant.admin.run-config.triggers.sources.' + trigger.source | translate }}</span>\n @if (trigger.shadow) {\n <span class=\"badge warning\" data-shadow-badge>{{ 'nh-assistant.admin.agents.shadow.badge' | translate }}</span>\n } @else {\n <span class=\"badge success\">{{ 'nh-assistant.admin.run-config.triggers.live-badge' | translate }}</span>\n }\n @if (!trigger.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n </div>\n <div class=\"meta\">\n @if (trigger.source === 'event') {\n <span class=\"mono\">{{ trigger.event }}</span>\n @if (trigger.filters?.length) {\n <span data-trigger-filters>{{ 'nh-assistant.admin.run-config.triggers.filters.applied' | translate: { filters: trigger.filters!.join(', ') } }}</span>\n }\n } @else {\n <span class=\"mono\">{{ trigger.cron }} {{ trigger.timeZone ?? 'UTC' }}</span>\n @if (trigger.subjectSet) {\n <span class=\"mono\">{{ trigger.subjectSet }}</span>\n } @else {\n <!-- A schedule without a subject set runs for the whole application, per division for a per-division agent. -->\n <span data-trigger-target>{{ (agent().perDivision ? 'nh-assistant.admin.run-config.triggers.target.every-division' : 'nh-assistant.admin.run-config.triggers.target.application') | translate }}</span>\n }\n }\n <span>{{ (trigger.skillId ? 'nh-assistant.admin.run-config.triggers.skill-value' : 'nh-assistant.admin.run-config.triggers.agent-routes') | translate: { skill: skillName(trigger.skillId) } }}</span>\n <span>{{ 'nh-assistant.admin.run-config.triggers.conflicts.' + trigger.conflict | translate }}</span>\n <span>{{ 'nh-assistant.admin.agents.version' | translate: { version: trigger.version } }}</span>\n </div>\n <div class=\"card-actions\">\n <button class=\"secondary\" type=\"button\" [disabled]=\"busy()\" (click)=\"editTrigger(trigger)\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" [attr.data-trigger-shadow]=\"trigger.shadow ? 'live' : 'shadow'\" [disabled]=\"busy()\" (click)=\"setTriggerShadow(trigger, !trigger.shadow)\">\n {{ (trigger.shadow ? 'nh-assistant.admin.agents.shadow.action.live' : 'nh-assistant.admin.agents.shadow.action.shadow') | translate }}\n </button>\n @if (isConfirming('remove-trigger', trigger.triggerId)) {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"removeTrigger(trigger)\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"confirm('remove-trigger', trigger.triggerId)\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.delete' | translate }}\n </button>\n }\n </div>\n @if (failed('trigger:' + trigger.triggerId)) {\n <p class=\"form-error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: error()!.code }}</p>\n }\n </li>\n }\n </ul>\n }\n </section>\n\n @if (showConsultations()) {\n <!-- What other assistants may consult the agent about: in code read only, as data within the ceiling in code. -->\n <section class=\"subsection\" [attr.aria-labelledby]=\"id + '-consultations-title'\" data-consultations>\n <header class=\"section-header\">\n <div>\n <h4 [id]=\"id + '-consultations-title'\">{{ 'nh-assistant.admin.run-config.consultations.title' | translate }}</h4>\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.consultations.description' | translate }}</p>\n </div>\n @if (consultationCeiling()) {\n <button\n class=\"secondary\"\n type=\"button\"\n data-open-form=\"consultation\"\n [attr.aria-describedby]=\"consultationsClosed() ? id + '-consultations-closed' : null\"\n [disabled]=\"busy() || consultationsClosed() !== null || form() === 'consultation'\"\n (click)=\"addConsultation()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.run-config.consultations.add' | translate }}\n </button>\n }\n </header>\n @if (consultationsClosed(); as closed) {\n <p class=\"muted\" [id]=\"id + '-consultations-closed'\" [attr.data-consultations-closed]=\"closed\">\n {{ 'nh-assistant.admin.run-config.consultations.closed.' + closed | translate: { max: consultationCeiling()?.maxConsultations } }}\n </p>\n }\n\n @if (form() === 'consultation') {\n @if (consultationCeiling(); as ceiling) {\n <nh-assistant-consultation-form\n [agentId]=\"config.agentId\"\n [agentSource]=\"config.source\"\n [catalog]=\"catalog()\"\n [ceiling]=\"ceiling\"\n [worksOn]=\"agent()\"\n [accountability]=\"accountability()\"\n [agentApprovalPolicy]=\"approvalPolicy()\"\n [consultation]=\"editingConsultation()\"\n [takenTypes]=\"consultationTypes()\"\n (saved)=\"onConsultationSaved($event)\"\n (cancelled)=\"cancel()\" />\n }\n }\n\n @if (consultationRows().length === 0) {\n <p class=\"state\" data-consultations-empty>{{ 'nh-assistant.admin.run-config.consultations.empty' | translate }}</p>\n } @else {\n <ul class=\"skills\">\n @for (row of consultationRows(); track row.origin + row.subjectType) {\n <li class=\"skill\" [attr.data-consultation]=\"row.subjectType\" [attr.data-consultation-origin]=\"row.origin\">\n <div class=\"card-header\">\n <strong>{{ typeName(row.subjectType) }}</strong>\n <span class=\"mono muted\">{{ row.subjectType }}</span>\n @if (row.data; as data) {\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.version' | translate: { version: data.version } }}</span>\n } @else {\n <span class=\"badge\">{{ 'nh-assistant.admin.agents.source-code' | translate }}</span>\n }\n @if (!row.inEffect) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.run-config.out-of-effect' | translate }}</span>\n }\n @if (row.requests) {\n <span class=\"badge\" data-consultation-requests>{{ 'nh-assistant.admin.run-config.consultations.requests' | translate }}</span>\n }\n @if (row.mcp) {\n <span class=\"badge\" data-consultation-mcp>{{ 'nh-assistant.admin.run-config.consultations.mcp' | translate }}</span>\n }\n </div>\n <p class=\"muted\">{{ row.description ?? ('nh-assistant.admin.run-config.consultations.no-description' | translate) }}</p>\n @if (askSentence(row); as sentence) {\n <p class=\"summary\" data-consultation-ask>{{ sentence }}</p>\n }\n <p class=\"summary\" data-consultation-decides>{{ decideSentence(row) }}</p>\n <!-- The second key: the agents whose tool selectors select the consult tool now. -->\n <div class=\"meta\" data-consultation-askers>\n @if (row.askingAgents.length > 0) {\n <span>{{ 'nh-assistant.admin.run-config.consultations.askers' | translate }}</span>\n @for (asker of row.askingAgents; track asker) {\n <button\n class=\"link\"\n type=\"button\"\n [attr.data-asker]=\"asker\"\n [attr.aria-label]=\"'nh-assistant.admin.run-config.consultations.open-asker' | translate: { agent: agentNameOf(asker) }\"\n (click)=\"openAgent.emit(asker)\">{{ agentNameOf(asker) }}</button>\n }\n } @else {\n <span data-consultation-no-askers>{{ 'nh-assistant.admin.run-config.consultations.no-askers' | translate }}</span>\n }\n <span class=\"mono\" data-consultation-tool>{{ row.consultToolId }}</span>\n </div>\n @if (row.code) {\n <p class=\"muted\">{{ 'nh-assistant.admin.run-config.consultations.code-hint' | translate }}</p>\n }\n @for (problem of row.problems; track problem) {\n <p class=\"message warning\" [attr.data-consultation-problem]=\"problem\">\n <nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.run-config.problems.code.' + problem | translate }}\n </p>\n }\n @if (row.data; as data) {\n <div class=\"meta\">\n <span>{{ 'nh-assistant.admin.run-config.consultations.limits-value' | translate: { calls: data.maxToolCalls, seconds: data.timeoutSeconds, chars: data.maxAnswerChars, history: data.maxHistoryMessages } }}</span>\n <span [attr.title]=\"accountTitle(data.changedBy)\">{{ 'nh-assistant.admin.run-config.changed' | translate: { user: nameOf(data.changedBy), date: (data.changedAt | date: 'medium') } }}</span>\n </div>\n <div class=\"card-actions\">\n <!-- Without a ceiling, as after a deploy took it away, the consultation can only be removed. -->\n @if (consultationCeiling()) {\n <button\n class=\"secondary\"\n type=\"button\"\n [attr.aria-label]=\"'nh-assistant.admin.run-config.consultations.edit-named' | translate: { type: typeName(row.subjectType) }\"\n [disabled]=\"busy()\"\n (click)=\"editConsultation(data)\">\n <nh-assistant-icon name=\"edit\" />{{ 'nh-assistant.admin.edit' | translate }}\n </button>\n }\n @if (isConfirming('remove-consultation', row.subjectType)) {\n <span class=\"muted\">{{ 'nh-assistant.admin.run-config.consultations.remove-explain' | translate }}</span>\n <button class=\"danger\" type=\"button\" [disabled]=\"busy()\" (click)=\"removeConsultation(data)\">{{ 'nh-assistant.admin.confirm-delete' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirming.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button\n class=\"danger\"\n type=\"button\"\n [attr.aria-label]=\"'nh-assistant.admin.run-config.consultations.remove-named' | translate: { type: typeName(row.subjectType) }\"\n [disabled]=\"busy()\"\n (click)=\"confirm('remove-consultation', row.subjectType)\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.delete' | translate }}\n </button>\n }\n </div>\n @if (failed('consultation:' + row.subjectType)) {\n <p class=\"form-error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: error()!.code }}</p>\n }\n }\n </li>\n }\n </ul>\n\n <!-- Switch a route off for every consultation of the agent, in code and as data, in one action. -->\n <nh-assistant-agent-consultation-routes\n [agentId]=\"config.agentId\"\n [subjectTypes]=\"catalog()?.subjectTypes ?? []\"\n [refresh]=\"loads()\"\n (changed)=\"changed.emit()\" />\n }\n </section>\n }\n }\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 output,\n signal,\n viewChild\n} from '@angular/core';\nimport { TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport { Observable, Subscription, catchError, forkJoin, map, of } from 'rxjs';\nimport {\n AdminAgent,\n AgentShadowMode,\n AgentShadowState,\n AgentSkillState,\n AgentState,\n McpServer,\n NhAssistantAdminApiService,\n NhAssistantError,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵNhAssistantIconComponent as NhAssistantIconComponent,\n NhAssistantPanelService,\n NhAssistantStore,\n nhAssistantErrorMessageKey,\n ɵNhAssistantTranslatePipe as NhAssistantTranslatePipe,\n ɵtoNhAssistantError as toNhAssistantError,\n RunCatalog,\n SetAgentStateRequest,\n ToolCatalogEntry\n} from '@newheap/platform-ai-chat';\nimport {\n ɵNhAssistantRunNowDialogComponent as NhAssistantRunNowDialogComponent,\n type ɵNhAssistantRunNowAgent as NhAssistantRunNowAgent\n} from '@newheap/platform-ai-chat/agent-runs';\nimport { NhAssistantAccountNames, NhAssistantAccountNamesErrorComponent } from '../nh-assistant-account-names';\nimport {\n codeTextKeys,\n policyKeys,\n readableId,\n runNowAgentOf,\n skillDescriptionKeys,\n skillNameKeys,\n warningKeys,\n WorksOnSummary,\n worksOnSummary\n} from './agent-texts';\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';\nimport { NhAssistantAgentRunHistoryComponent } from './nh-assistant-agent-run-history.component';\nimport { NhAssistantAgentRunConfigurationComponent } from './nh-assistant-agent-run-configuration.component';\nimport { NhAssistantAccountPickerComponent } from './run-config/nh-assistant-account-picker.component';\n\nlet nextId = 0;\n\ntype AgentStateAction = SetAgentStateRequest['state'];\n\n/** A state change being entered, of the agent or one of its skills, with the state it changes from. */\ninterface StateChange {\n agentId: string;\n skillId?: string;\n state: AgentStateAction;\n from: AdminAgent['runState'] | AgentSkillState['runState'];\n}\n\n/** The longest reason the server stores with a state change. */\nconst maxStateReason = 500;\n\n/** Refusals of a technical account that concern the account field itself. */\nconst accountRefusals = new Set(['assistant-service-account-not-found', 'assistant-service-account-not-used']);\n\n/** The run catalog as `load` reads it: the catalog, or why it could not be read. */\ninterface CatalogRead {\n catalog: RunCatalog | null;\n error: NhAssistantError | null;\n}\n\n/**\n * Agent administration: code agents (override, reset) and agents created here (edit, delete),\n * and for every agent and skill its run state with pause, switch off, stop and resume (switch on\n * for one that is off), its shadow mode and that of each\n * skill, and the technical account of an agent that answers to one, 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, the evaluation action of an agent with\n * shadow variants opens `nh-assistant-agent-evaluation`, and the run configuration action opens\n * `nh-assistant-agent-run-configuration` for the skills, triggers and run settings defined as data.\n * \"Run now\" on an agent that runs on its own opens the run-now dialog: the whole application (or a\n * division of it) or an object of one of its types, and an optional instruction; the receipt opens\n * the agent's conversation in the assistant panel. \"Runs\" opens `nh-assistant-agent-run-history`, the\n * agent's runs with their results. When the run catalog cannot be read, the page says why with its\n * code and offers to read it again; until then it offers no \"Run now\" and the editor leaves what an\n * agent works on and its groups as they are. The run configuration opens with the agent's flow, whose\n * entry points open the editor, the runs and the technical account here and return to the run\n * configuration afterwards; `openMcpServers` asks the host to show the MCP servers.\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 NhAssistantAgentRunHistoryComponent,\n NhAssistantAgentRunConfigurationComponent,\n NhAssistantAccountPickerComponent,\n NhAssistantRunNowDialogComponent,\n NhAssistantAccountNamesErrorComponent\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 panel = inject(NhAssistantPanelService);\n private readonly translate = inject(TranslateService);\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 private catalogSubscription?: 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 /** The run catalog: object types by name, policies and divisions; `null` when it could not be read. */\n readonly catalog = signal<RunCatalog | null>(null);\n /** Why the run catalog could not be read; `null` once it was. */\n readonly catalogError = signal<NhAssistantError | null>(null);\n readonly catalogErrorKeys = computed(() => nhAssistantErrorKeys(this.catalogError()));\n /** The run catalog is being read again after a failure. */\n readonly catalogLoading = signal(false);\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 /** The agent whose run configuration is shown instead of the list. */\n readonly configuring = signal<AdminAgent | null>(null);\n /** The agent whose runs are shown instead of the list. */\n readonly viewingRuns = signal<AdminAgent | null>(null);\n /**\n * The agent whose run configuration opened the editor or the runs from its flow; closing them\n * returns to its run configuration instead of the list.\n */\n readonly returnTo = signal<string | null>(null);\n /** The flow of a run configuration asks to show the MCP servers, whose background use it explains. */\n readonly openMcpServers = output<void>();\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<StateChange | null>(null);\n /** The shadow mode change whose reason is being entered, of the agent or one of its skills. */\n readonly changingShadow = signal<{ agentId: string; skillId?: string; mode: AgentShadowMode } | null>(null);\n /** The change of the technical account being entered: a new account, or the one in code. */\n readonly changingAccount = signal<{ agentId: string; mode: 'set' | 'code' } | null>(null);\n readonly accountId = signal('');\n /** Why the account of the open account form was refused, shown at the account field. */\n readonly accountError = signal<NhAssistantError | null>(null);\n /** The text of the account field's error: the refused field value, then the code. */\n readonly accountErrorKeys = computed(() => {\n const error = this.accountError();\n const value = error?.fieldErrors?.['actorId']?.[0];\n return value ? [`nh-assistant.admin.run-config.field-errors.${value}`, ...nhAssistantErrorKeys(error)] : nhAssistantErrorKeys(error);\n });\n /** Whether the application offers an account search for the technical account. */\n readonly accountSearch = signal(false);\n /**\n * The names of the technical accounts and of the people who changed an agent, once known, and why\n * they are not.\n */\n readonly accountNameLookup = new NhAssistantAccountNames();\n /** The names of the technical accounts in the list, by account id. */\n readonly accountNames = computed(() => this.accountNameLookup.names());\n /** The agent whose last action failed, so its error shows on its card. */\n readonly errorAgentId = signal<string | null>(null);\n /** The agent the run-now dialog runs; `null` while it is closed. */\n readonly runningNow = signal<AdminAgent | null>(null);\n /** The agent of the run-now dialog as the dialog needs it: its name and what it works on. */\n readonly runNowAgent = computed<NhAssistantRunNowAgent | null>(() => {\n const agent = this.runningNow();\n if (!agent) {\n return null;\n }\n const keys = codeTextKeys(agent.source, agent.displayName);\n const translated = keys.length > 0 ? this.translate.instant(keys[0]) as string : null;\n return runNowAgentOf(agent, translated && translated !== keys[0] ? translated : agent.displayName);\n });\n /** The run configuration opens with the guided setup, for an agent created to work on its own. */\n readonly setupOnOpen = signal(false);\n readonly stateReason = signal('');\n readonly maxReason = maxStateReason;\n readonly error = signal<NhAssistantError | null>(null);\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n readonly codeTextKeys = codeTextKeys;\n readonly skillNameKeys = skillNameKeys;\n readonly warningKeys = warningKeys;\n readonly skillDescriptionKeys = skillDescriptionKeys;\n readonly policyKeys = policyKeys;\n readonly readableId = readableId;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.actionSubscription?.unsubscribe();\n this.catalogSubscription?.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.catalogSubscription?.unsubscribe();\n this.catalogLoading.set(false);\n this.subscription = forkJoin([\n this.admin.getAgents(),\n this.admin.getTools(),\n this.admin.getMcpServers(),\n // The agents stay usable without the catalog; the page says why it is missing.\n this.readCatalog()\n ]).subscribe({\n next: ([agents, tools, servers, read]) => {\n this.agents.set(agents);\n this.tools.set(tools);\n this.servers.set(servers);\n this.applyCatalog(read);\n this.loading.set(false);\n this.loadAccountNames(agents);\n },\n error: () => {\n this.loading.set(false);\n this.loadFailed.set(true);\n }\n });\n }\n\n /** Reads the run catalog again after it could not be read. */\n retryCatalog(): void {\n this.catalogLoading.set(true);\n this.catalogSubscription?.unsubscribe();\n this.catalogSubscription = this.readCatalog().subscribe(read => {\n this.catalogLoading.set(false);\n this.applyCatalog(read);\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 /**\n * Whether the agent can run on its own and so has a run configuration: an agent in code with runs,\n * or any agent created here, which gets run settings as data.\n */\n hasRunConfiguration(agent: AdminAgent): boolean {\n return agent.source === 'admin' || (agent.shadow !== null && agent.shadow !== undefined);\n }\n\n /**\n * Whether the agent can be run now: it runs on its own, so it has a run configuration, it is\n * neither stopped nor disabled in code, and the run catalog names what it can run on. An agent\n * that is off still runs for a person. The server decides the rest when the run starts.\n */\n canRunNow(agent: AdminAgent): boolean {\n return this.catalog() !== null\n && this.hasRunConfiguration(agent)\n && (agent.runState === 'active' || agent.runState === 'paused' || agent.runState === 'off');\n }\n\n /** Opens the run-now dialog of the agent. */\n runNow(agent: AdminAgent): void {\n this.closeForms();\n this.runningNow.set(agent);\n }\n\n /** Opens the conversation the run works in, in the assistant panel. */\n openConversation(conversationId: string): void {\n this.panel.open(conversationId);\n }\n\n /** Shows the agent's skills, triggers and run settings defined as data. */\n openRunConfiguration(agent: AdminAgent, setup = false): void {\n this.setupOnOpen.set(setup);\n this.error.set(null);\n this.confirming.set(null);\n this.configuring.set(agent);\n afterNextRender(() => this.backButton()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /** Returns to the list, refreshed, and to the run configuration action of the agent. */\n closeRunConfiguration(): void {\n const agentId = this.configuring()?.id;\n this.returnTo.set(null);\n this.configuring.set(null);\n this.refreshAgents();\n if (agentId !== undefined) {\n afterNextRender(() => {\n const action = Array.from(this.host.nativeElement.querySelectorAll<HTMLButtonElement>('[data-run-config-agent]'))\n .find(item => item.dataset['runConfigAgent'] === agentId);\n action?.focus();\n }, { injector: this.injector });\n }\n }\n\n /** Shows the agent's runs with their results. */\n openRuns(agent: AdminAgent): void {\n this.error.set(null);\n this.confirming.set(null);\n this.viewingRuns.set(agent);\n afterNextRender(() => this.backButton()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /**\n * Returns to the run configuration whose flow opened the runs, or to the list and the runs action of\n * the agent whose runs were open.\n */\n closeRuns(): void {\n const agentId = this.viewingRuns()?.id;\n this.viewingRuns.set(null);\n if (this.returnToRunConfiguration(agentId)) {\n return;\n }\n if (agentId !== undefined) {\n afterNextRender(() => {\n const action = Array.from(this.host.nativeElement.querySelectorAll<HTMLButtonElement>('[data-runs-agent]'))\n .find(item => item.dataset['runsAgent'] === agentId);\n action?.focus();\n }, { injector: this.injector });\n }\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 /** A new agent meant to work on its own continues in its run configuration's guided setup. */\n onWorkRequested(agent: AdminAgent): void {\n this.returnTo.set(null);\n this.onSaved(agent);\n this.openRunConfiguration(agent, true);\n }\n\n /** The flow of the agent's run configuration opens the editor; saving or cancelling returns there. */\n editFromRunConfiguration(agent: AdminAgent): void {\n this.configuring.set(null);\n this.returnTo.set(agent.id);\n this.edit(agent);\n }\n\n /**\n * A consultation of the agent's run configuration opens the editor of an agent that asks it, whose\n * tool selectors are the consultation's second key; saving or cancelling returns to the run\n * configuration it came from.\n */\n askerFromRunConfiguration(agent: AdminAgent, askerId: string): void {\n const asker = this.agents().find(item => item.id === askerId);\n if (!asker) {\n return;\n }\n this.configuring.set(null);\n this.returnTo.set(agent.id);\n this.edit(asker);\n }\n\n /** The flow of the agent's run configuration opens its runs; going back returns there. */\n runsFromRunConfiguration(agent: AdminAgent): void {\n this.configuring.set(null);\n this.returnTo.set(agent.id);\n this.openRuns(agent);\n }\n\n /** The flow of an agent in code opens the form that replaces its technical account on its card. */\n accountFromRunConfiguration(agent: AdminAgent): void {\n this.configuring.set(null);\n this.returnTo.set(null);\n this.refreshAgents();\n this.askAccount(agent, 'set');\n }\n\n /** The editor saved: back to the run configuration that opened it, or to the list. */\n onEditorSaved(agent: AdminAgent): void {\n this.onSaved(agent);\n this.returnToRunConfiguration(agent.id, agent);\n }\n\n /** The editor closed without saving: back to the run configuration that opened it, or to the list. */\n onEditorCancelled(): void {\n const agentId = this.editing()?.id;\n this.editing.set(undefined);\n this.returnToRunConfiguration(agentId);\n }\n\n /**\n * Opens the run configuration again when its flow, or one of its consultations, opened what closes\n * now; `false` otherwise. The editor of an agent that asks a consultation returns to the consulted\n * agent's run configuration.\n */\n private returnToRunConfiguration(agentId: string | undefined, saved?: AdminAgent): boolean {\n const returnTo = this.returnTo();\n this.returnTo.set(null);\n if (returnTo === null || agentId === undefined) {\n return false;\n }\n const agent = saved?.id === returnTo ? saved : this.agents().find(item => item.id === returnTo);\n if (!agent) {\n return false;\n }\n this.openRunConfiguration(agent);\n return true;\n }\n\n /** What the agent works on, with its object types named as the run catalog names them. */\n worksOn(agent: AdminAgent): WorksOnSummary & { only: 'all' | 'types' | 'application' } {\n const summary = worksOnSummary(agent, this.catalog()?.subjectTypes);\n return {\n ...summary,\n only: summary.all ? 'all' : summary.types.length > 0 ? 'types' : 'application'\n };\n }\n\n /** The groups the agent is in, named as the run catalog names them; `null` for none. */\n groupNames(agent: AdminAgent): string | null {\n const groups = this.catalog()?.agentGroups ?? [];\n const names = (agent.groups ?? []).map(id => groups.find(group => group.id === id)?.name ?? id);\n return names.length > 0 ? names.join(', ') : null;\n }\n\n /** The name of an account or person, or the id when the application does not know it. */\n accountName(actorId: string | null | undefined): string {\n return this.accountNameLookup.nameOf(actorId);\n }\n\n /** The account ID as the tooltip of a name shown in its place. */\n accountTitle(actorId: string | null | undefined): string | null {\n return this.accountNameLookup.idTitleOf(actorId);\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', 'off', 'stopped'];\n case 'paused':\n return ['active', 'off', 'stopped'];\n case 'off':\n return ['active', 'stopped'];\n case 'stopped':\n return ['active', 'off'];\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', 'off', 'stopped'];\n case 'paused':\n return ['active', 'off', 'stopped'];\n case 'off':\n return ['active', 'stopped'];\n default:\n return ['active'];\n }\n }\n\n /**\n * The key of a state change's label, explanation or confirmation: making an agent or skill that is\n * off active again switches it on, which replays nothing, unlike a resume.\n */\n stateKey(part: 'action' | 'explain' | 'confirm', from: string, action: AgentStateAction): string {\n return `nh-assistant.admin.agents.state.${part}.${from === 'off' && action === 'active' ? 'switch-on' : action}`;\n }\n\n /** The explanation of a state change of one skill. */\n skillStateExplainKey(change: StateChange): string {\n return `nh-assistant.admin.agents.skills.explain.${change.from === 'off' && change.state === 'active' ? 'switch-on' : change.state}`;\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.closeForms();\n this.changingState.set({ agentId: agent.id, skillId: skill?.skillId, state, from: skill?.runState ?? agent.runState });\n afterNextRender(() => this.reasonInput()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /**\n * The shadow modes an agent or skill can change to: the opposite of its own mode, and the mode\n * in code once an administrator overrode it. A shadow variant, and an agent without runs that\n * only chats, offer none.\n */\n shadowActions(shadow: AgentShadowState | null | undefined): AgentShadowMode[] {\n if (!shadow || shadow.locked) {\n return [];\n }\n const own = shadow.override ?? shadow.configured;\n const actions: AgentShadowMode[] = [own ? 'live' : 'shadow'];\n return shadow.override === null ? actions : [...actions, 'code'];\n }\n\n /** Opens the reason form of a shadow mode change of the agent or, with a skill, of that skill. */\n askShadow(agent: AdminAgent, mode: AgentShadowMode, skill?: AgentSkillState): void {\n this.closeForms();\n this.changingShadow.set({ agentId: agent.id, skillId: skill?.skillId, mode });\n afterNextRender(() => this.reasonInput()?.nativeElement.focus(), { injector: this.injector });\n }\n\n /**\n * The label of a shadow action. An agent created here has no code: returning to its \"code\" mode\n * means returning to the mode it was set up with.\n */\n shadowActionKey(agent: AdminAgent, mode: AgentShadowMode): string {\n return mode === 'code' && agent.source !== 'code'\n ? 'nh-assistant.admin.agents.shadow.action.own'\n : `nh-assistant.admin.agents.shadow.action.${mode}`;\n }\n\n /** The explanation of a shadow change of the agent or one of its skills. */\n shadowExplainKey(agent: AdminAgent, mode: AgentShadowMode, skill: boolean): string {\n const group = skill ? 'skill-explain' : 'explain';\n return `nh-assistant.admin.agents.shadow.${group}.${mode === 'code' && agent.source !== 'code' ? 'own' : mode}`;\n }\n\n /** The mode the agent, or one of its skills, was set up with: what returning to it means. */\n ownShadowModeKey(agent: AdminAgent, skillId?: string): string {\n const shadow = skillId === undefined\n ? agent.shadow\n : agent.skills?.find(skill => skill.skillId === skillId)?.shadow;\n return shadow?.configured ? 'nh-assistant.admin.agents.shadow.mode.shadow' : 'nh-assistant.admin.agents.shadow.mode.live';\n }\n\n isChangingShadow(agentId: string, mode: AgentShadowMode, skillId?: string): boolean {\n const change = this.changingShadow();\n return change?.agentId === agentId && change.mode === mode && change.skillId === skillId;\n }\n\n applyShadow(agent: AdminAgent): void {\n const change = this.changingShadow();\n if (change?.agentId !== agent.id) {\n return;\n }\n\n const reason = this.stateReason().trim();\n const request = { mode: change.mode, reason: reason.length > 0 ? reason : null };\n if (change.skillId !== undefined) {\n this.run(\n agent.id,\n this.admin.setSkillShadow(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.setAgentShadow(agent.id, request),\n state => this.replace(withState(agent, state)));\n }\n\n /** Opens the form that changes the technical account, or returns to the one in code. */\n askAccount(agent: AdminAgent, mode: 'set' | 'code'): void {\n this.closeForms();\n this.changingAccount.set({ agentId: agent.id, mode });\n this.accountId.set('');\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>('[data-account-form] input')?.focus(), { injector: this.injector });\n }\n\n /** A changed account clears the error of the one before. */\n onAccountChange(actorId: string): void {\n this.accountId.set(actorId);\n this.accountError.set(null);\n }\n\n isChangingAccount(agentId: string, mode: 'set' | 'code'): boolean {\n const change = this.changingAccount();\n return change?.agentId === agentId && change.mode === mode;\n }\n\n /**\n * Changes the technical account. The form stays open while the server decides, so a missing or\n * refused account shows at the account field, which takes the focus.\n */\n applyAccount(agent: AdminAgent): void {\n const change = this.changingAccount();\n if (change?.agentId !== agent.id || this.busyAgentId() !== null) {\n return;\n }\n\n const actorId = change.mode === 'set' ? this.accountId().trim() : null;\n if (actorId === '') {\n this.accountError.set({\n code: 'assistant-validation',\n messageKey: nhAssistantErrorMessageKey('assistant-validation'),\n fieldErrors: { actorId: ['required'] }\n });\n this.focusAccount();\n return;\n }\n\n const reason = this.stateReason().trim();\n this.busyAgentId.set(agent.id);\n this.errorAgentId.set(agent.id);\n this.error.set(null);\n this.accountError.set(null);\n this.actionSubscription?.unsubscribe();\n this.actionSubscription = this.admin.setServiceAccount(agent.id, { actorId, reason: reason.length > 0 ? reason : null }).subscribe({\n next: state => this.replace(withState(agent, state)),\n complete: () => {\n this.busyAgentId.set(null);\n this.changingAccount.set(null);\n this.stateReason.set('');\n this.refreshChat();\n this.loadAccountNames(this.agents());\n },\n error: (error: unknown) => {\n this.busyAgentId.set(null);\n const failure = toNhAssistantError(error);\n if (failure.fieldErrors?.['actorId'] || accountRefusals.has(failure.code)) {\n this.accountError.set(failure);\n this.focusAccount();\n } else {\n this.error.set(failure);\n }\n }\n });\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.changingShadow.set(null);\n this.changingAccount.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.errorAgentId.set(agentId);\n this.confirming.set(null);\n this.changingState.set(null);\n this.changingShadow.set(null);\n this.changingAccount.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 this.loadAccountNames(this.agents());\n },\n error: (error: unknown) => {\n this.busyAgentId.set(null);\n this.error.set(toNhAssistantError(error));\n }\n });\n }\n\n /** Looks up the names of the technical accounts and of the people who changed an agent's state. */\n private loadAccountNames(agents: readonly AdminAgent[]): void {\n this.accountNameLookup.load(agents.flatMap(agent => [\n agent.serviceAccount?.actorId,\n agent.serviceAccount?.configuredActorId,\n agent.stateChangedBy,\n agent.shadow?.changedBy\n ]));\n }\n\n /** The run catalog, or why it could not be read; it never errors. */\n private readCatalog(): Observable<CatalogRead> {\n return this.admin.getRunCatalog().pipe(\n map(catalog => ({ catalog, error: null })),\n catchError((error: unknown) => of({ catalog: null, error: toNhAssistantError(error) })));\n }\n\n private applyCatalog(read: CatalogRead): void {\n this.catalog.set(read.catalog);\n this.catalogError.set(read.error);\n this.accountSearch.set(read.catalog?.accountSearch === true);\n }\n\n private focusAccount(): void {\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>('[data-account-form] input')?.focus(), { injector: this.injector });\n }\n\n /** Closes the open confirmation and change forms before another opens; one is open at a time. */\n private closeForms(): void {\n this.confirming.set(null);\n this.error.set(null);\n this.accountError.set(null);\n this.stateReason.set('');\n this.accountId.set('');\n this.changingState.set(null);\n this.changingShadow.set(null);\n this.changingAccount.set(null);\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 /**\n * Reloads the agents behind the visible list, for example their skills after the run\n * configuration changed; the list stays as it is when that fails.\n */\n private refreshAgents(): void {\n this.subscription?.unsubscribe();\n this.subscription = this.admin.getAgents().subscribe({\n next: agents => this.agents.set(agents),\n error: () => undefined\n });\n this.refreshChat();\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 offBeforeStop: state.offBeforeStop,\n skills: state.skills ?? agent.skills,\n shadow: state.shadow ?? agent.shadow,\n serviceAccount: state.serviceAccount === undefined ? agent.serviceAccount : state.serviceAccount\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 [catalog]=\"catalog()\"\n [catalogUnavailable]=\"catalogError() !== null\"\n (saved)=\"onEditorSaved($event)\"\n (workRequested)=\"onWorkRequested($event)\"\n (cancelled)=\"onEditorCancelled()\" />\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: (codeTextKeys(agent.source, agent.displayName) | nhAssistantTranslate: agent.displayName), id: agent.id } }}</p>\n <nh-assistant-agent-feedback-report [agentId]=\"agent.id\" />\n </div>\n} @else if (configuring(); as agent) {\n <div class=\"stack\">\n <div>\n <button #back class=\"secondary\" type=\"button\" (click)=\"closeRunConfiguration()\">\n {{ 'nh-assistant.admin.run-config.back' | translate }}\n </button>\n </div>\n <nh-assistant-agent-run-configuration\n [agent]=\"agent\"\n [startSetup]=\"setupOnOpen()\"\n [tools]=\"tools()\"\n [servers]=\"servers()\"\n [agents]=\"agents()\"\n (editAgent)=\"editFromRunConfiguration(agent)\"\n (openRuns)=\"runsFromRunConfiguration(agent)\"\n (changeAccount)=\"accountFromRunConfiguration(agent)\"\n (openMcpServers)=\"openMcpServers.emit()\"\n (openAgent)=\"askerFromRunConfiguration(agent, $event)\" />\n </div>\n} @else if (viewingRuns(); as agent) {\n <div class=\"stack\">\n <div>\n <button #back class=\"secondary\" type=\"button\" (click)=\"closeRuns()\">\n {{ (returnTo() === agent.id ? 'nh-assistant.admin.runs.back-to-run-config' : 'nh-assistant.admin.runs.back') | translate }}\n </button>\n </div>\n <p class=\"muted\">{{ 'nh-assistant.admin.feedback.agent' | translate: { name: (codeTextKeys(agent.source, agent.displayName) | nhAssistantTranslate: agent.displayName), id: agent.id } }}</p>\n <nh-assistant-agent-run-history\n [agentId]=\"agent.id\"\n [subjectTypes]=\"catalog()?.subjectTypes ?? []\"\n (openConversation)=\"openConversation($event)\" />\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: (codeTextKeys(agent.source, agent.displayName) | nhAssistantTranslate: 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 @if (errorAgentId() === null) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n }\n @if (!loading() && !loadFailed()) {\n @if (catalogError(); as failure) {\n <!-- Without the run catalog nothing that depends on it is offered: run now, what agents work on, groups. -->\n <div class=\"message warning catalog-error\" role=\"alert\" data-catalog-error>\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">\n {{ 'nh-assistant.admin.agents.catalog-failed' | translate }}\n {{ catalogErrorKeys() | nhAssistantTranslate: failure.code }}\n </span>\n <button class=\"secondary\" type=\"button\" data-catalog-retry [disabled]=\"catalogLoading()\" (click)=\"retryCatalog()\">\n <nh-assistant-icon name=\"refresh\" />{{ 'nh-assistant.admin.retry' | translate }}\n </button>\n </div>\n }\n <nh-assistant-account-names-error [names]=\"accountNameLookup\" />\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 <!-- An agent in code names and describes itself with translation keys. -->\n <strong>{{ (codeTextKeys(agent.source, agent.displayName) | nhAssistantTranslate: 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 @if (agent.shadow?.shadow) {\n <span class=\"badge warning\" data-shadow-badge>{{ 'nh-assistant.admin.agents.shadow.badge' | translate }}</span>\n }\n @if (agent.offeredInChat === false) {\n <span class=\"badge\" data-hidden-from-chat>{{ 'nh-assistant.admin.agents.chat.hidden' | translate }}</span>\n }\n </div>\n @if (agent.description) {\n <p class=\"muted\">{{ codeTextKeys(agent.source, agent.description) | nhAssistantTranslate: agent.description }}</p>\n }\n <!-- A warning never refused the save: the agent is in effect but may not work as configured. -->\n @for (warning of agent.warnings ?? []; track warning) {\n <p class=\"message warning\" [attr.data-agent-warning]=\"warning\">\n <nh-assistant-icon name=\"warning\" />{{ warningKeys('agent', warning) | nhAssistantTranslate: warning }}\n </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 <span [attr.title]=\"accountTitle(agent.stateChangedBy)\">{{ 'nh-assistant.admin.agents.state.changed' | translate: { user: accountName(agent.stateChangedBy), date: (agent.stateChangedAt | date: 'medium') } }}</span>\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 <!-- What releasing the kill switch does: an agent that was off goes back off. Older servers do not say. -->\n @if (agent.runState === 'stopped' && agent.offBeforeStop !== undefined) {\n <p class=\"muted\" data-stopped-hint [attr.data-off-before-stop]=\"agent.offBeforeStop\">\n {{ (agent.offBeforeStop ? 'nh-assistant.admin.agents.state.stopped-was-off-hint' : 'nh-assistant.admin.agents.state.stopped-was-on-hint') | translate }}\n </p>\n }\n @if (agent.runState === 'off') {\n <p class=\"muted\" data-off-hint>\n {{ 'nh-assistant.admin.agents.state.off-hint' | translate }}\n @if (!agent.stateChangedAt) {\n {{ 'nh-assistant.admin.agents.state.starts-off' | translate }}\n }\n </p>\n }\n }\n @if (agent.shadow; as shadow) {\n @if (shadow.shadow) {\n <p class=\"muted\">\n {{ (shadow.locked ? 'nh-assistant.admin.agents.shadow.locked' : 'nh-assistant.admin.agents.shadow.hint') | translate }}\n @if (shadow.changedAt && shadow.override !== null) {\n <span [attr.title]=\"accountTitle(shadow.changedBy)\">{{ 'nh-assistant.admin.agents.shadow.changed' | translate: { user: accountName(shadow.changedBy), date: (shadow.changedAt | date: 'medium') } }}</span>\n }\n @if (shadow.reason && shadow.override !== null) {\n {{ 'nh-assistant.admin.agents.state.reason' | translate: { reason: shadow.reason } }}\n }\n </p>\n }\n }\n @if (agent.serviceAccount; as account) {\n <p class=\"muted\" data-service-account>\n <span [attr.title]=\"accountTitle(account.actorId)\">{{ 'nh-assistant.admin.agents.service-account.label' | translate: { account: accountName(account.actorId) } }}</span>\n @if (account.overridden) {\n <span [attr.title]=\"accountTitle(account.configuredActorId)\">{{ 'nh-assistant.admin.agents.service-account.configured' | translate: { account: accountName(account.configuredActorId) } }}</span>\n @if (account.reason) {\n {{ 'nh-assistant.admin.agents.state.reason' | translate: { reason: account.reason } }}\n }\n }\n </p>\n }\n @if (worksOn(agent); as works) {\n <!-- What the agent works on; an agent in code shows its code setting. -->\n <p class=\"muted\" data-works-on>\n <span>{{ 'nh-assistant.admin.agents.works-on.label' | translate }}</span>\n <strong>\n @switch (works.only) {\n @case ('all') { {{ 'nh-assistant.admin.agents.works-on.all' | translate }} }\n @case ('types') { {{ works.types.join(', ') }} }\n @default { {{ 'nh-assistant.admin.agents.works-on.application' | translate }} }\n }\n </strong>\n @if (works.application && works.only !== 'application') {\n <span>{{ 'nh-assistant.admin.agents.works-on.and-application' | translate }}</span>\n }\n @if (works.perDivision) {\n <span>{{ 'nh-assistant.admin.agents.works-on.per-division' | translate }}</span>\n }\n @if (works.undeclared) {\n <span>{{ 'nh-assistant.admin.agents.works-on.undeclared' | translate }}</span>\n }\n </p>\n @if (works.all && works.known.length > 0) {\n <p class=\"muted\" data-known-types>{{ 'nh-assistant.admin.agents.works-on.known' | translate: { types: works.known.join(', ') } }}</p>\n }\n @if (works.runPolicy || works.viewPolicy) {\n <!-- Each policy is an item of its own, wrapping on narrow screens. -->\n <div class=\"meta\" data-works-on-policies>\n @if (works.runPolicy; as policy) {\n <span>{{ 'nh-assistant.admin.agents.works-on.run-policy' | translate: { policy: (policyKeys(policy) | nhAssistantTranslate: policy) } }}</span>\n }\n @if (works.viewPolicy; as policy) {\n <span>{{ 'nh-assistant.admin.agents.works-on.view-policy' | translate: { policy: (policyKeys(policy) | nhAssistantTranslate: policy) } }}</span>\n }\n </div>\n }\n }\n @if (groupNames(agent); as names) {\n <p class=\"muted\" data-agent-groups>{{ 'nh-assistant.admin.agents.groups' | translate: { groups: names } }}</p>\n }\n <div class=\"meta\">\n <span>{{ 'nh-assistant.admin.agents.autonomy.' + agent.autonomy | translate }}</span>\n <span>{{ (agent.toolSelectors.length === 1 ? 'nh-assistant.admin.agents.tool-count-one' : 'nh-assistant.admin.agents.tool-count') | translate: { count: agent.toolSelectors.length } }}</span>\n <span>{{ (agent.mcpServerIds.length === 1 ? 'nh-assistant.admin.agents.server-count-one' : '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; as policy) {\n <!-- The application may name its policies; otherwise the policy shows as it is called in code. -->\n <span data-required-policy>\n {{ 'nh-assistant.admin.agents.required-policy' | translate }}\n @if (policyKeys(policy) | nhAssistantTranslate; as text) {\n {{ text }}\n } @else {\n <code class=\"mono\">{{ policy }}</code>\n }\n </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.data-state-action]=\"action\"\n [attr.aria-expanded]=\"isChangingState(agent.id, action)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askState(agent, action)\">\n {{ stateKey('action', agent.runState, action) | translate }}\n </button>\n }\n @if (agent.runState !== 'configured-off') {\n @for (mode of shadowActions(agent.shadow); track mode) {\n <button\n class=\"secondary\"\n type=\"button\"\n [attr.data-shadow-action]=\"mode\"\n [attr.aria-expanded]=\"isChangingShadow(agent.id, mode)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askShadow(agent, mode)\">\n {{ shadowActionKey(agent, mode) | translate }}\n </button>\n }\n }\n @if (agent.serviceAccount; as account) {\n <button\n class=\"secondary\"\n type=\"button\"\n data-account-action=\"set\"\n [attr.aria-expanded]=\"isChangingAccount(agent.id, 'set')\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askAccount(agent, 'set')\">\n {{ 'nh-assistant.admin.agents.service-account.action.set' | translate }}\n </button>\n @if (account.overridden) {\n <button\n class=\"secondary\"\n type=\"button\"\n data-account-action=\"code\"\n [attr.aria-expanded]=\"isChangingAccount(agent.id, 'code')\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askAccount(agent, 'code')\">\n {{ 'nh-assistant.admin.agents.service-account.action.code' | translate }}\n </button>\n }\n }\n @if (hasRunConfiguration(agent)) {\n <button class=\"secondary\" type=\"button\" [attr.data-run-config-agent]=\"agent.id\" (click)=\"openRunConfiguration(agent)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.agents.run-config' | translate }}\n </button>\n }\n @if (hasRunConfiguration(agent)) {\n <button class=\"secondary\" type=\"button\" [attr.data-runs-agent]=\"agent.id\" (click)=\"openRuns(agent)\">\n <nh-assistant-icon name=\"list\" />{{ 'nh-assistant.admin.agents.runs' | translate }}\n </button>\n }\n @if (canRunNow(agent)) {\n <button\n class=\"secondary\"\n type=\"button\"\n aria-haspopup=\"dialog\"\n [attr.data-run-now-agent]=\"agent.id\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"runNow(agent)\">\n <nh-assistant-icon name=\"send\" />{{ 'nh-assistant.admin.agents.run-now' | 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.cancel' | 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.cancel' | 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 <strong>{{ (skillNameKeys(agent.id, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId)) }}</strong>\n <span class=\"mono muted\">{{ 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 @if (skill.shadow?.shadow) {\n <span class=\"badge warning\" data-shadow-badge>{{ 'nh-assistant.admin.agents.shadow.badge' | translate }}</span>\n }\n </div>\n <p class=\"muted\">{{ skillDescriptionKeys(agent.id, skill.skillId) | nhAssistantTranslate: 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.data-state-action]=\"action\"\n [attr.aria-label]=\"(stateKey('action', skill.runState, action) | translate) + ' ' + (skillNameKeys(agent.id, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId))\"\n [attr.aria-expanded]=\"isChangingState(agent.id, action, skill.skillId)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askState(agent, action, skill)\">\n {{ stateKey('action', skill.runState, action) | translate }}\n </button>\n }\n @for (mode of shadowActions(skill.shadow); track mode) {\n <button\n class=\"secondary\"\n type=\"button\"\n [attr.data-shadow-action]=\"mode\"\n [attr.aria-label]=\"(shadowActionKey(agent, mode) | translate) + ' ' + (skillNameKeys(agent.id, skill.skillId) | nhAssistantTranslate: readableId(skill.skillId))\"\n [attr.aria-expanded]=\"isChangingShadow(agent.id, mode, skill.skillId)\"\n [disabled]=\"busyAgentId() !== null\"\n (click)=\"askShadow(agent, mode, skill)\">\n {{ shadowActionKey(agent, mode) | 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\">{{ skillStateExplainKey(change) | translate: { skill: (skillNameKeys(agent.id, change.skillId) | nhAssistantTranslate: readableId(change.skillId)) } }}</p>\n } @else {\n <p class=\"muted\">{{ stateKey('explain', change.from, change.state) | translate }}</p>\n }\n <div class=\"field\">\n <label [for]=\"id + '-' + agent.id + '-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input\n #reasonInput\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"id + '-' + agent.id + '-reason'\"\n [attr.aria-describedby]=\"id + '-' + agent.id + '-reason-hint'\"\n [maxLength]=\"maxReason\"\n [value]=\"stateReason()\"\n (input)=\"stateReason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-' + agent.id + '-reason-hint'\">{{ 'nh-assistant.admin.agents.state.note-hint' | translate }}</p>\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 {{ stateKey('confirm', change.from, change.state) | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"changingState.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n </div>\n </form>\n }\n }\n @if (changingShadow(); as change) {\n @if (change.agentId === agent.id) {\n <form class=\"stack\" data-shadow-form (submit)=\"$event.preventDefault(); applyShadow(agent)\">\n @if (change.skillId) {\n <p class=\"muted\">{{ shadowExplainKey(agent, change.mode, true) | translate: { skill: (skillNameKeys(agent.id, change.skillId) | nhAssistantTranslate: readableId(change.skillId)), mode: (ownShadowModeKey(agent, change.skillId) | translate) } }}</p>\n } @else {\n <p class=\"muted\">{{ shadowExplainKey(agent, change.mode, false) | translate: { mode: (ownShadowModeKey(agent) | translate) } }}</p>\n }\n <div class=\"field\">\n <label [for]=\"id + '-' + agent.id + '-shadow-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input\n #reasonInput\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"id + '-' + agent.id + '-shadow-reason'\"\n [attr.aria-describedby]=\"id + '-' + agent.id + '-shadow-reason-hint'\"\n [maxLength]=\"maxReason\"\n [value]=\"stateReason()\"\n (input)=\"stateReason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-' + agent.id + '-shadow-reason-hint'\">{{ 'nh-assistant.admin.agents.state.note-hint' | translate }}</p>\n </div>\n <div class=\"card-actions\">\n <button type=\"submit\" class=\"primary\" [disabled]=\"busyAgentId() !== null\">\n {{ 'nh-assistant.admin.agents.shadow.confirm.' + change.mode | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"changingShadow.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n </div>\n </form>\n }\n }\n @if (changingAccount(); as change) {\n @if (change.agentId === agent.id) {\n <form class=\"stack\" data-account-form (submit)=\"$event.preventDefault(); applyAccount(agent)\">\n <p class=\"muted\" [attr.title]=\"accountTitle(agent.serviceAccount?.configuredActorId)\">{{ 'nh-assistant.admin.agents.service-account.explain.' + change.mode | translate: { account: accountName(agent.serviceAccount?.configuredActorId) } }}</p>\n @if (change.mode === 'set') {\n <div class=\"field\">\n <label [for]=\"id + '-' + agent.id + '-account'\">{{ (accountSearch() ? 'nh-assistant.admin.agents.service-account.input-label-search' : 'nh-assistant.admin.agents.service-account.input-label') | translate }}</label>\n <nh-assistant-account-picker\n [inputId]=\"id + '-' + agent.id + '-account'\"\n [value]=\"accountId()\"\n [searchable]=\"accountSearch()\"\n [invalid]=\"accountError() !== null\"\n [describedBy]=\"accountError() ? id + '-' + agent.id + '-account-error' : null\"\n (valueChange)=\"onAccountChange($event)\" />\n @if (accountError(); as failure) {\n <p class=\"field-error\" data-account-error [id]=\"id + '-' + agent.id + '-account-error'\">\n <nh-assistant-icon name=\"warning\" />{{ accountErrorKeys() | nhAssistantTranslate: failure.code }}\n </p>\n }\n </div>\n }\n <div class=\"field\">\n <label [for]=\"id + '-' + agent.id + '-account-reason'\">{{ 'nh-assistant.admin.agents.state.note-label' | translate }}</label>\n <input\n type=\"text\"\n autocomplete=\"off\"\n [id]=\"id + '-' + agent.id + '-account-reason'\"\n [attr.aria-describedby]=\"id + '-' + agent.id + '-account-reason-hint'\"\n [maxLength]=\"maxReason\"\n [value]=\"stateReason()\"\n (input)=\"stateReason.set(value($event))\" />\n <p class=\"hint\" [id]=\"id + '-' + agent.id + '-account-reason-hint'\">{{ 'nh-assistant.admin.agents.state.note-hint' | translate }}</p>\n </div>\n <div class=\"card-actions\">\n <button type=\"submit\" class=\"primary\" [disabled]=\"busyAgentId() !== null\">\n {{ 'nh-assistant.admin.agents.service-account.confirm.' + change.mode | translate }}\n </button>\n <button class=\"secondary\" type=\"button\" (click)=\"changingAccount.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n </div>\n </form>\n }\n }\n @if (error(); as failure) {\n @if (errorAgentId() === agent.id) {\n <p class=\"form-error\" role=\"alert\" data-agent-error><nh-assistant-icon name=\"warning\" />{{ errorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n }\n </li>\n }\n </ul>\n }\n @if (runNowAgent(); as runAgent) {\n <nh-assistant-run-now-dialog\n [agent]=\"runAgent\"\n [subjectTypes]=\"catalog()?.subjectTypes ?? []\"\n [divisions]=\"catalog()?.divisions === true\"\n (openConversation)=\"openConversation($event)\"\n (closed)=\"runningNow.set(null)\" />\n }\n </section>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n afterNextRender,\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 AssistantDataClassification,\n McpAuthMode,\n McpBuiltInAuthMode,\n McpConnectionScope,\n McpCustomAuthMode,\n McpDiscovery,\n McpHeadlessUse,\n McpOAuthInput,\n McpServer,\n McpServerInput,\n McpTool,\n McpTransport,\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';\nimport { focusFirstInvalid } from '../agents/run-config/run-config-shared';\n\n/**\n * The longest values the server accepts per field of a server (`POST`/`PUT admin/mcp-servers`); the\n * editor's fields stop there.\n */\nconst NH_ASSISTANT_MCP_SERVER_LIMITS = {\n id: 40,\n displayName: 200,\n url: 2048,\n headerName: 128,\n secret: 2000,\n secretReference: 233,\n userName: 256,\n clientCertificateReference: 100,\n requiredPolicy: 256,\n scopes: 1024,\n clientId: 512,\n clientSecret: 2000,\n organizationAccountLabel: 200\n} as const;\n\n/** The fields of a server the server reports errors for, as the editor shows them. */\nconst serverFields = [\n 'id',\n 'displayName',\n 'url',\n 'authMode',\n 'headerName',\n 'secret',\n 'secretReference',\n 'userName',\n 'clientCertificateReference',\n 'transport',\n 'connectionScope',\n 'oauth.scopes',\n 'oauth.clientId',\n 'oauth.clientSecret',\n 'oauth.clientSecretReference',\n 'oauth.organizationAccountLabel',\n 'oauth.confirmAuthorization',\n 'requiredPolicy',\n 'headlessUse',\n 'readers'\n] as const;\n\n/** The fields of one reader the server reports errors for, as `readers[<index>].<field>`. */\nconst readerFieldPattern = /^readers\\[\\d+\\]\\.(mediaTypes|toolName|maxClassification|priority)$/;\n\n/** A header name the server accepts: 1 to 128 letters, digits and dashes. */\nconst headerNamePattern = /^[A-Za-z0-9-]{1,128}$/;\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. The editor offers no `clear`:\n * the API refuses a mode with a secret that has none, so a stored secret goes by choosing a reference\n * or a mode without a secret.\n */\nexport type NhAssistantSecretAction = 'keep' | 'replace' | 'clear';\n\n/** Where the secret is: stored here, encrypted, or a reference to a secret of the application. */\nexport type NhAssistantSecretSource = 'stored' | 'reference';\n\n/** `<prefix>:<name>` as the server accepts it; the name never climbs a path. */\nconst secretReferencePattern = /^[a-z][a-z0-9-]{0,31}:[A-Za-z0-9][A-Za-z0-9._/-]{0,199}$/;\nconst certificateNamePattern = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;\n/** Space-separated scope tokens: printable ASCII without quotes or backslashes (RFC 6749). */\nconst scopesPattern = /^[\\x21\\x23-\\x5B\\x5D-\\x7E]+( [\\x21\\x23-\\x5B\\x5D-\\x7E]+)*$/;\n/** A media type without parameters, as the server compares them (`type/subtype`). */\nconst mediaTypePattern = /^[a-z0-9][a-z0-9!#$&^_.+-]*\\/[a-z0-9][a-z0-9!#$&^_.+-]*$/;\n/** The most media types one reader reads. */\nconst maxReaderMediaTypes = 16;\n/** The most readers one server has. */\nconst maxReaders = 16;\n/** The priorities a reader can have; a higher one is asked first. */\nconst readerPriority = { min: -1000, max: 1000 } as const;\n\n/**\n * One reader as the editor shows it: the tool, the media types as typed (separated by commas, spaces\n * or new lines), the highest classification and the priority as typed. `key` keeps a row's controls\n * when another row is removed.\n */\nexport interface NhAssistantReaderDraft {\n key: number;\n toolName: string;\n mediaTypes: string;\n maxClassification: AssistantDataClassification | '';\n priority: string;\n}\n\n/** What is wrong with one reader before it is saved. */\ninterface ReaderProblems {\n types: boolean;\n tool: boolean;\n duplicate: boolean;\n classification: boolean;\n priority: boolean;\n}\n\nlet nextId = 0;\nlet nextReaderKey = 0;\n\n/**\n * Creates or edits one MCP server: the authentication with a write-only secret or a reference to\n * one, OAuth with discovery the administrator confirms, an optional client certificate, the\n * transport, the use in background runs and, for a server that exists, its readers: per reader the\n * synced tool that turns files into text, the media types it reads, the highest classification that\n * may be sent to it and its priority, with readers to add and remove. Every field stops at the length\n * the server accepts; a refused save shows each of the server's field errors at its field, those of a\n * reader at that reader (`readers[0].toolName`), for example a secret reference the application cannot\n * resolve (`not-found`), and moves the focus to the first of them.\n */\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 readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly injector = inject(Injector);\n private subscription?: Subscription;\n private discoverySubscription?: Subscription;\n private modesSubscription?: Subscription;\n private toolsSubscription?: Subscription;\n /** Fields whose server error the administrator changed since the refused save. */\n private readonly touched = signal<ReadonlySet<string>>(new Set());\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 limits = NH_ASSISTANT_MCP_SERVER_LIMITS;\n readonly builtInAuthModes: readonly McpBuiltInAuthMode[] = ['none', 'bearer', 'api-key', 'basic', 'forward-user-token', 'oauth', 'oauth-client-credentials'];\n /** The modes the application registered in code; none until they are loaded or when loading fails. */\n readonly customAuthModes = signal<readonly McpCustomAuthMode[]>([]);\n /** The built-in modes, the application's own and, kept selectable, a stored mode no longer registered. */\n readonly authModes = computed<readonly McpAuthMode[]>(() => {\n const modes: McpAuthMode[] = [...this.builtInAuthModes, ...this.customAuthModes().map(item => item.mode)];\n const stored = this.server()?.authMode;\n return stored && !modes.includes(stored) ? [...modes, stored] : modes;\n });\n readonly transports: readonly McpTransport[] = ['streamable-http', 'auto'];\n readonly secretSources: readonly NhAssistantSecretSource[] = ['stored', 'reference'];\n readonly connectionScopes: readonly McpConnectionScope[] = ['organization', 'user'];\n readonly classifications: readonly AssistantDataClassification[] = ['public', 'internal', 'confidential', 'restricted'];\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 headlessUse = signal<McpHeadlessUse>('never');\n readonly userName = signal('');\n readonly secretSource = signal<NhAssistantSecretSource>('stored');\n readonly secretReference = signal('');\n readonly clientCertificateReference = signal('');\n readonly transport = signal<McpTransport>('streamable-http');\n readonly secretAction = signal<NhAssistantSecretAction>('keep');\n /** The new secret while typing. Never filled from the server. */\n readonly secret = signal('');\n readonly connectionScope = signal<McpConnectionScope>('organization');\n readonly oauthClientId = signal('');\n readonly oauthScopes = signal('');\n readonly organizationAccountLabel = signal('');\n readonly oauthSecretSource = signal<NhAssistantSecretSource>('stored');\n readonly oauthSecretReference = signal('');\n readonly oauthSecretAction = signal<NhAssistantSecretAction>('keep');\n /** The new client secret while typing. Never filled from the server. */\n readonly oauthSecret = signal('');\n /** What discovery found for the address; the administrator confirms it on save. */\n readonly discovery = signal<McpDiscovery | null>(null);\n readonly discovering = signal(false);\n readonly discoveryError = signal<NhAssistantError | null>(null);\n readonly confirmAuthorization = signal(false);\n /** The readers of the server as the editor shows them, in their order. */\n readonly readers = signal<readonly NhAssistantReaderDraft[]>([]);\n readonly maxReaders = maxReaders;\n readonly readerPriority = readerPriority;\n /** The server's synced tools, which can read files; empty until they are loaded. */\n readonly readerTools = signal<readonly McpTool[]>([]);\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 /** A stored secret that a save keeps; a reference replaces it. */\n readonly hasSecret = computed(() => this.server()?.hasSecret === true);\n /** The server's own secret; OAuth modes have a client secret instead. */\n readonly usesSecret = computed(() => this.authMode() === 'bearer' || this.authMode() === 'api-key' || this.authMode() === 'basic');\n readonly usesReference = computed(() => this.usesSecret() && this.secretSource() === 'reference');\n /**\n * The organization's credential may serve background runs; a forwarded user token only as the\n * short-lived token of the person a run acts for, after that person allowed it.\n */\n readonly headlessUses = computed<readonly McpHeadlessUse[]>(() =>\n this.personalCredential() ? ['never', 'personal'] : ['never', 'organization']);\n readonly isOAuth = computed(() => this.authMode() === 'oauth' || this.authMode() === 'oauth-client-credentials');\n readonly isClientCredentials = computed(() => this.authMode() === 'oauth-client-credentials');\n /** One authorization of the organization's account that everyone uses. */\n readonly isOrganizationOAuth = computed(() => this.authMode() === 'oauth' && this.connectionScope() === 'organization');\n /** Whose credential the application's own mode sends; null for a built-in mode. */\n readonly customOwnership = computed(() =>\n this.customAuthModes().find(item => item.mode === this.authMode())?.ownership ?? null);\n /**\n * The server runs with each person's own account: a forwarded sign-in, a personal OAuth connection\n * or a mode of the application that sends a person's credential.\n */\n readonly personalCredential = computed(() =>\n this.authMode() === 'forward-user-token' || (this.authMode() === 'oauth' && this.connectionScope() === 'user') ||\n this.customOwnership() === 'person');\n readonly hasOAuthSecret = computed(() => this.server()?.oauth?.hasClientSecret === true);\n readonly usesOAuthReference = computed(() => this.isOAuth() && this.oauthSecretSource() === 'reference');\n readonly showOAuthSecretInput = computed(() => this.isOAuth() && !this.usesOAuthReference() &&\n (!this.hasOAuthSecret() || this.oauthSecretAction() === 'replace'));\n /**\n * The confirmed authorization server stays valid while the address and the OAuth use stay; a new\n * server, a new address or a switch to OAuth needs discovery and the administrator's confirmation.\n */\n readonly needsConfirmation = computed(() => {\n const server = this.server();\n return this.isOAuth() && (server === null || server.authorization === null ||\n server.url !== this.url().trim() || (server.authMode !== 'oauth' && server.authMode !== 'oauth-client-credentials'));\n });\n readonly pkceMissing = computed(() => this.authMode() === 'oauth' && this.discovery()?.pkceSupported === false);\n readonly confirmMissing = computed(() => this.needsConfirmation() && (!this.confirmAuthorization() || this.discovery() === null));\n readonly scopesInvalid = computed(() => {\n const scopes = this.oauthScopes().trim();\n return scopes.length > 1_024 || (scopes.length > 0 && !scopesPattern.test(scopes));\n });\n readonly clientIdMissing = computed(() => this.isClientCredentials() && this.oauthClientId().trim().length === 0);\n readonly labelMissing = computed(() => this.isOrganizationOAuth() &&\n (this.organizationAccountLabel().trim().length === 0 || this.organizationAccountLabel().length > 200));\n readonly oauthReferenceInvalid = computed(() => this.usesOAuthReference() && !isSecretReference(this.oauthSecretReference().trim()));\n /** The registration discovery offers when no client id is entered. */\n readonly registration = computed(() => {\n const found = this.discovery();\n if (!found) {\n return null;\n }\n return found.clientIdMetadataDocumentSupported ? 'metadata-document' : found.dynamicRegistrationSupported ? 'dynamic' : 'manual';\n });\n readonly effectiveHeadlessUse = computed(() => this.headlessUses().includes(this.headlessUse()) ? this.headlessUse() : 'never');\n readonly showSecretInput = computed(() => this.usesSecret() && !this.usesReference() && (!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 userNameInvalid = computed(() => this.authMode() === 'basic' &&\n (this.userName().trim().length === 0 || this.userName().length > 256 || this.userName().includes(':')));\n readonly secretReferenceInvalid = computed(() => this.usesReference() && !isSecretReference(this.secretReference().trim()));\n readonly certificateInvalid = computed(() => {\n const name = this.clientCertificateReference().trim();\n return name.length > 0 && !certificateNamePattern.test(name);\n });\n readonly oauthInvalid = computed(() => this.isOAuth() && (this.confirmMissing() || this.pkceMissing() || this.scopesInvalid() ||\n this.clientIdMissing() || this.labelMissing() || this.oauthReferenceInvalid()));\n readonly headerNameInvalid = computed(() => {\n const header = this.headerName().trim();\n return this.authMode() === 'api-key' && header.length > 0 && !headerNamePattern.test(header);\n });\n /** The tool names to choose from, keeping the stored tools the list no longer holds selectable. */\n readonly readerToolNames = computed(() => {\n const names = this.readerTools().map(tool => tool.remoteName);\n const stored = (this.server()?.readers ?? []).map(reader => reader.toolName).filter(name => !names.includes(name));\n return [...names, ...stored];\n });\n /** What is wrong with each reader, in the order of `readers`. */\n readonly readerProblems = computed<readonly ReaderProblems[]>(() => {\n const seen = new Set<string>();\n return this.readers().map(reader => {\n const types = splitMediaTypes(reader.mediaTypes);\n const duplicate = reader.toolName.length > 0 && seen.has(reader.toolName);\n seen.add(reader.toolName);\n return {\n types: types.length === 0 || types.some(type => !isMediaType(type)) ||\n new Set(types.map(type => type.split(';')[0].trim().toLowerCase())).size > maxReaderMediaTypes,\n tool: reader.toolName.length === 0,\n duplicate,\n classification: reader.maxClassification === '',\n priority: parsePriority(reader.priority) === null\n };\n });\n });\n /** Why a reader can or cannot be added: the server's tools are not synced, or it has the most. */\n readonly readerAddHint = computed(() => this.readerToolNames().length === 0\n ? 'nh-assistant.admin.server-editor.reader.tool-sync'\n : this.readers().length >= maxReaders\n ? 'nh-assistant.admin.server-editor.reader.limit'\n : 'nh-assistant.admin.server-editor.reader.add-hint');\n readonly readerInvalid = computed(() => this.readerProblems().some(problems =>\n problems.types || problems.tool || problems.duplicate || problems.classification || problems.priority));\n readonly valid = computed(() => !this.idInvalid() && !this.nameMissing() && !this.urlInvalid() && !this.headerNameInvalid() &&\n !this.userNameInvalid() && !this.secretReferenceInvalid() && !this.certificateInvalid() && !this.oauthInvalid() &&\n !this.readerInvalid());\n readonly errorKeys = computed(() => nhAssistantErrorKeys(this.error()));\n /** The server's first error per field of the refused save, until the administrator changes the field. */\n readonly serverErrors = computed<Readonly<Record<string, string>>>(() => {\n const touched = this.touched();\n const errors: Record<string, string> = {};\n for (const [field, values] of Object.entries(this.error()?.fieldErrors ?? {})) {\n if (values.length > 0 && !touched.has(field)) {\n errors[field] = values[0];\n }\n }\n return errors;\n });\n /** Field errors of fields the editor does not show, listed with the form's error. */\n readonly otherServerErrors = computed(() => Object.entries(this.serverErrors())\n .filter(([field]) => !(serverFields as readonly string[]).includes(field) && !this.showsReaderField(field))\n .map(([field, value]) => ({ field, keys: this.valueKeys(value) })));\n readonly discoveryErrorKeys = computed(() => nhAssistantErrorKeys(this.discoveryError()));\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.subscription?.unsubscribe();\n this.discoverySubscription?.unsubscribe();\n this.modesSubscription?.unsubscribe();\n this.toolsSubscription?.unsubscribe();\n });\n // The application's own modes; without them the editor offers the built-in modes.\n this.modesSubscription = this.admin.getMcpAuthModes().subscribe({\n next: modes => this.customAuthModes.set(modes),\n error: () => this.customAuthModes.set([])\n });\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 /** Whether the server refused the field in the last save. */\n serverInvalid(field: string): boolean {\n return this.serverErrors()[field] !== undefined;\n }\n\n /** The text of the server's error of a field: the text of its value, then the generic text. */\n serverErrorKeys(field: string): string[] {\n const value = this.serverErrors()[field];\n return value ? this.valueKeys(value) : [];\n }\n\n /** The id of a field's error, for `aria-describedby`. */\n errorId(field: string): string {\n return `${this.id}-${field.replace(/[^A-Za-z0-9-]+/g, '-')}-error`;\n }\n\n /** The name of a reader's field in the server's errors, such as `readers[0].toolName`. */\n readerField(index: number, field: 'mediaTypes' | 'toolName' | 'maxClassification' | 'priority'): string {\n return `readers[${index}].${field}`;\n }\n\n /** Adds an empty reader at the end, at priority 0, and moves the focus to its tool. */\n addReader(): void {\n if (this.readers().length >= maxReaders) {\n return;\n }\n this.forgetReaderErrors();\n const key = nextReaderKey++;\n this.readers.set([...this.readers(), { key, toolName: '', mediaTypes: '', maxClassification: '', priority: '0' }]);\n this.focusById(`${this.id}-reader-tool-${key}`);\n }\n\n /**\n * Removes a reader and moves the focus to the button that adds one; the server's errors of the\n * readers no longer match their positions.\n */\n removeReader(index: number): void {\n this.forgetReaderErrors();\n this.readers.set(this.readers().filter((_, position) => position !== index));\n this.focusById(`${this.id}-reader-add`);\n }\n\n /** Changes one field of a reader as the administrator typed or chose it. */\n updateReader(index: number, field: 'toolName' | 'mediaTypes' | 'maxClassification' | 'priority', value: string): void {\n // The classification comes from the select's options, the empty choice included.\n this.readers.set(this.readers().map((reader, position) =>\n position === index ? { ...reader, [field]: value } as NhAssistantReaderDraft : reader));\n this.touch(this.readerField(index, field));\n }\n\n /** The ids a control describes itself with: its hint and, while the server refused it, its error. */\n describedBy(hintId: string | null, field: string): string | null {\n const ids = [hintId, this.serverInvalid(field) ? this.errorId(field) : null].filter((id): id is string => id !== null);\n return ids.length > 0 ? ids.join(' ') : null;\n }\n\n /** The administrator changed a field; its server error no longer applies. */\n touch(field: string): void {\n if (this.serverErrors()[field] !== undefined) {\n this.touched.set(new Set([...this.touched(), field]));\n }\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 setSecretSource(source: NhAssistantSecretSource): void {\n this.secretSource.set(source);\n this.secret.set('');\n this.secretAction.set('keep');\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 /** A new address makes earlier discovery meaningless. */\n onUrlInput(event: Event): void {\n this.url.set(this.value(event));\n this.discoverySubscription?.unsubscribe();\n this.discovering.set(false);\n this.discovery.set(null);\n this.confirmAuthorization.set(false);\n }\n\n setOAuthSecretSource(source: NhAssistantSecretSource): void {\n this.oauthSecretSource.set(source);\n this.oauthSecret.set('');\n this.oauthSecretAction.set('keep');\n }\n\n onOAuthSecretInput(event: Event): void {\n this.oauthSecret.set(this.value(event));\n if (!this.hasOAuthSecret()) {\n this.oauthSecretAction.set(this.oauthSecret().length > 0 ? 'replace' : 'keep');\n }\n }\n\n /** Reads the authorization of the address; the administrator confirms what it found. */\n discover(): void {\n if (this.urlInvalid() || this.discovering()) {\n return;\n }\n this.discovering.set(true);\n this.discovery.set(null);\n this.discoveryError.set(null);\n this.confirmAuthorization.set(false);\n this.discoverySubscription?.unsubscribe();\n this.discoverySubscription = this.admin.discoverMcpServer(this.url().trim()).subscribe({\n next: discovery => {\n this.discovering.set(false);\n this.discovery.set(discovery);\n if (this.oauthScopes().trim().length === 0 && discovery.challengedScopes.length > 0) {\n // The scopes the server asked for are a starting point the administrator can narrow.\n this.oauthScopes.set(discovery.challengedScopes.join(' '));\n }\n },\n error: (error: unknown) => {\n this.discovering.set(false);\n this.discoveryError.set(toNhAssistantError(error));\n }\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 headlessUse: this.effectiveHeadlessUse(),\n transport: this.transport(),\n // \"\" clears the certificate; the server ignores the user name outside basic authentication.\n clientCertificateReference: this.clientCertificateReference().trim(),\n userName: authMode === 'basic' ? this.userName().trim() : null\n };\n\n // Write-only secret: omitted keeps the stored value, \"\" clears it. A reference and a stored\n // secret exclude each other: sending one replaces the other.\n const action = this.secretAction();\n const storedReference = this.server()?.secretReference ?? null;\n if (this.usesReference()) {\n input.secretReference = this.secretReference().trim();\n } else if (!this.usesSecret()) {\n if (this.hasSecret()) {\n input.secret = '';\n }\n if (storedReference !== null) {\n input.secretReference = '';\n }\n } else {\n if (storedReference !== null) {\n input.secretReference = '';\n }\n if (action === 'clear') {\n input.secret = '';\n } else if (action === 'replace' && this.secret().length > 0) {\n input.secret = this.secret();\n }\n }\n if (this.isOAuth()) {\n input.connectionScope = authMode === 'oauth' ? this.connectionScope() : 'organization';\n input.oauth = this.oauthInput();\n }\n if (!this.isNew()) {\n // Every save sends the readers as shown; none removes them all.\n input.readers = this.readers().map(reader => ({\n mediaTypes: splitMediaTypes(reader.mediaTypes),\n toolName: reader.toolName,\n maxClassification: reader.maxClassification || null,\n priority: parsePriority(reader.priority) ?? 0\n }));\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.touched.set(new Set());\n this.subscription?.unsubscribe();\n this.subscription = request.subscribe({\n next: server => {\n this.saving.set(false);\n this.secret.set('');\n this.oauthSecret.set('');\n this.saved.emit(server);\n },\n error: (error: unknown) => {\n this.saving.set(false);\n this.error.set(toNhAssistantError(error));\n this.focusFirstInvalid();\n }\n });\n }\n\n private focusFirstInvalid(): void {\n afterNextRender(() => focusFirstInvalid(this.host.nativeElement.querySelector('form')), { injector: this.injector });\n }\n\n private focusById(id: string): void {\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>(`[id=\"${id}\"]`)?.focus(), { injector: this.injector });\n }\n\n private valueKeys(value: string): string[] {\n return [`nh-assistant.admin.run-config.field-errors.${value}`, 'nh-assistant.errors.generic'];\n }\n\n /** Whether the editor shows a field error at a reader's own field. */\n private showsReaderField(field: string): boolean {\n const match = /^readers\\[(\\d+)\\]\\./.exec(field);\n return match !== null && readerFieldPattern.test(field) && Number(match[1]) < this.readers().length;\n }\n\n /** The server's errors of the readers no longer apply once a reader is added or removed. */\n private forgetReaderErrors(): void {\n const readerFields = Object.keys(this.serverErrors()).filter(field => field.startsWith('readers'));\n if (readerFields.length > 0) {\n this.touched.set(new Set([...this.touched(), ...readerFields]));\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.headlessUse.set(server?.headlessUse ?? 'never');\n this.userName.set(server?.userName ?? '');\n this.secretSource.set(server?.secretReference ? 'reference' : 'stored');\n this.secretReference.set(server?.secretReference ?? '');\n this.clientCertificateReference.set(server?.clientCertificateReference ?? '');\n this.transport.set(server?.transport ?? 'streamable-http');\n this.secretAction.set('keep');\n this.secret.set('');\n this.connectionScope.set(server?.connectionScope ?? 'organization');\n this.oauthClientId.set(server?.oauth?.clientId ?? '');\n this.oauthScopes.set(server?.oauth?.scopes ?? '');\n this.organizationAccountLabel.set(server?.oauth?.organizationAccountLabel ?? '');\n this.oauthSecretSource.set(server?.oauth?.clientSecretReference ? 'reference' : 'stored');\n this.oauthSecretReference.set(server?.oauth?.clientSecretReference ?? '');\n this.oauthSecretAction.set('keep');\n this.oauthSecret.set('');\n this.discoverySubscription?.unsubscribe();\n this.discovering.set(false);\n this.discovery.set(null);\n this.discoveryError.set(null);\n this.confirmAuthorization.set(false);\n this.readers.set((server?.readers ?? []).map(reader => ({\n key: nextReaderKey++,\n toolName: reader.toolName,\n mediaTypes: reader.mediaTypes.join(', '),\n maxClassification: reader.maxClassification,\n priority: String(reader.priority)\n })));\n this.loadReaderTools(server);\n this.submitted.set(false);\n this.error.set(null);\n this.touched.set(new Set());\n }\n\n /** The synced tools of an existing server, to choose the reading tool from. */\n private loadReaderTools(server: McpServer | null): void {\n this.toolsSubscription?.unsubscribe();\n this.readerTools.set([]);\n if (server === null) {\n return;\n }\n this.toolsSubscription = this.admin.getMcpTools(server.id).subscribe({\n next: tools => this.readerTools.set(tools),\n error: () => this.readerTools.set([])\n });\n }\n\n /**\n * The OAuth settings as the editor shows them: every value is sent, so an emptied field clears the\n * stored value. The client secret is write-only: sent only when replaced.\n */\n private oauthInput(): McpOAuthInput {\n const storedReference = this.server()?.oauth?.clientSecretReference ?? null;\n const input: McpOAuthInput = {\n clientId: this.oauthClientId().trim(),\n scopes: this.oauthScopes().trim(),\n organizationAccountLabel: this.isOrganizationOAuth() ? this.organizationAccountLabel().trim() : '',\n // Required when the address is new or changed; otherwise it pins what was read again.\n confirmAuthorization: this.discovery() !== null && this.confirmAuthorization()\n };\n if (this.usesOAuthReference()) {\n input.clientSecretReference = this.oauthSecretReference().trim();\n } else {\n if (storedReference !== null) {\n input.clientSecretReference = '';\n }\n if (this.oauthSecretAction() === 'replace' && this.oauthSecret().length > 0) {\n input.clientSecret = this.oauthSecret();\n }\n }\n return input;\n }\n}\n\nfunction isSecretReference(value: string): boolean {\n return secretReferencePattern.test(value) && !value.includes('..');\n}\n\n/** The media types an administrator typed, separated by commas, spaces or new lines. */\nfunction splitMediaTypes(value: string): string[] {\n return value.split(/[\\s,]+/).map(item => item.trim()).filter(item => item.length > 0);\n}\n\n/**\n * The priority a reader's field holds: a whole number from -1000 to 1000, empty for 0, or `null` when\n * the server would refuse it.\n */\nfunction parsePriority(value: string): number | null {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n return 0;\n }\n const priority = Number(trimmed);\n return Number.isInteger(priority) && priority >= readerPriority.min && priority <= readerPriority.max ? priority : null;\n}\n\n/** Whether a value is a media type the server accepts: `type/subtype`, optionally with parameters. */\nfunction isMediaType(value: string): boolean {\n const essence = value.split(';')[0].trim().toLowerCase();\n return essence.length <= 128 && mediaTypePattern.test(essence);\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 [maxLength]=\"limits.id\"\n [value]=\"serverId()\"\n [disabled]=\"!isNew()\"\n [attr.aria-describedby]=\"describedBy(id + '-id-hint', 'id')\"\n [attr.aria-invalid]=\"(submitted() && idInvalid()) || serverInvalid('id') ? true : null\"\n (input)=\"serverId.set(value($event)); touch('id')\" />\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 @if (serverInvalid('id')) {\n <p class=\"field-error\" [id]=\"errorId('id')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('id') | nhAssistantTranslate }}</p>\n }\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 [maxLength]=\"limits.displayName\"\n [value]=\"displayName()\"\n [attr.aria-invalid]=\"(submitted() && nameMissing()) || serverInvalid('displayName') ? true : null\"\n [attr.aria-describedby]=\"describedBy(id + '-name-hint', 'displayName')\"\n (input)=\"displayName.set(value($event)); touch('displayName')\" />\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 @if (serverInvalid('displayName')) {\n <p class=\"field-error\" [id]=\"errorId('displayName')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('displayName') | nhAssistantTranslate }}</p>\n }\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 [maxLength]=\"limits.url\"\n [value]=\"url()\"\n [attr.aria-describedby]=\"describedBy(id + '-url-hint', 'url')\"\n [attr.aria-invalid]=\"(submitted() && urlInvalid()) || serverInvalid('url') ? true : null\"\n (input)=\"onUrlInput($event); touch('url')\" />\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 @if (serverInvalid('url')) {\n <p class=\"field-error\" [id]=\"errorId('url')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('url') | nhAssistantTranslate }}</p>\n }\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\n [id]=\"id + '-auth'\"\n [attr.aria-describedby]=\"describedBy(null, 'authMode')\"\n [attr.aria-invalid]=\"serverInvalid('authMode') ? true : null\"\n (change)=\"authMode.set($any(value($event))); touch('authMode')\">\n @for (mode of authModes(); track mode) {\n <option [value]=\"mode\" [selected]=\"authMode() === mode\">{{ ['nh-assistant.admin.mcp.auth.' + mode] | nhAssistantTranslate: mode }}</option>\n }\n </select>\n @if (customOwnership(); as ownership) {\n <p class=\"hint\" data-custom-auth-mode>{{ 'nh-assistant.admin.server-editor.custom-auth.' + ownership | translate }}</p>\n }\n @if (serverInvalid('authMode')) {\n <p class=\"field-error\" [id]=\"errorId('authMode')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('authMode') | nhAssistantTranslate }}</p>\n }\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 [maxLength]=\"limits.headerName\"\n [value]=\"headerName()\"\n [attr.aria-describedby]=\"describedBy(id + '-header-hint', 'headerName')\"\n [attr.aria-invalid]=\"(submitted() && headerNameInvalid()) || serverInvalid('headerName') ? true : null\"\n (input)=\"headerName.set(value($event)); touch('headerName')\" />\n <p class=\"hint\" [id]=\"id + '-header-hint'\">\n <span [class.error-text]=\"submitted() && headerNameInvalid()\">\n {{ (submitted() && headerNameInvalid() ? 'nh-assistant.admin.server-editor.header-name-invalid' : 'nh-assistant.admin.server-editor.header-name-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('headerName')) {\n <p class=\"field-error\" [id]=\"errorId('headerName')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('headerName') | nhAssistantTranslate }}</p>\n }\n </div>\n }\n\n @if (authMode() === 'basic') {\n <div class=\"field\">\n <label [for]=\"id + '-user'\">{{ 'nh-assistant.admin.server-editor.user-name' | translate }}</label>\n <input\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [id]=\"id + '-user'\"\n [maxLength]=\"limits.userName\"\n [value]=\"userName()\"\n [attr.aria-describedby]=\"describedBy(id + '-user-hint', 'userName')\"\n [attr.aria-invalid]=\"(submitted() && userNameInvalid()) || serverInvalid('userName') ? true : null\"\n (input)=\"userName.set(value($event)); touch('userName')\" />\n <p class=\"hint\" [id]=\"id + '-user-hint'\">\n <span [class.error-text]=\"submitted() && userNameInvalid()\">\n {{ (submitted() && userNameInvalid() ? 'nh-assistant.admin.server-editor.user-name-invalid' : 'nh-assistant.admin.server-editor.user-name-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('userName')) {\n <p class=\"field-error\" [id]=\"errorId('userName')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('userName') | nhAssistantTranslate }}</p>\n }\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 (isOAuth()) {\n <fieldset class=\"field\">\n <legend>OAuth</legend>\n\n @if (authMode() === 'oauth') {\n <div\n class=\"inline\"\n role=\"radiogroup\"\n [attr.aria-label]=\"'nh-assistant.admin.server-editor.connection-scope' | translate\"\n [attr.aria-describedby]=\"describedBy(id + '-scope-hint', 'connectionScope')\">\n @for (scope of connectionScopes; track scope) {\n <label class=\"check\">\n <input\n type=\"radio\"\n [name]=\"id + '-connection-scope'\"\n [value]=\"scope\"\n [checked]=\"connectionScope() === scope\"\n [attr.aria-invalid]=\"serverInvalid('connectionScope') ? true : null\"\n (change)=\"connectionScope.set(scope); touch('connectionScope')\" />\n <span>{{ 'nh-assistant.admin.mcp.connection-scope.' + scope | translate }}</span>\n </label>\n }\n </div>\n <p class=\"hint\" [id]=\"id + '-scope-hint'\">{{ 'nh-assistant.admin.server-editor.connection-scope-hint' | translate }}</p>\n @if (serverInvalid('connectionScope')) {\n <p class=\"field-error\" [id]=\"errorId('connectionScope')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('connectionScope') | nhAssistantTranslate }}</p>\n }\n }\n\n @if (isOrganizationOAuth()) {\n <p class=\"message warning\" role=\"note\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.oauth-warning' | translate }}</p>\n <label [for]=\"id + '-account-label'\">{{ 'nh-assistant.admin.server-editor.organization-account-label' | translate }}</label>\n <input\n type=\"text\"\n [id]=\"id + '-account-label'\"\n [maxLength]=\"limits.organizationAccountLabel\"\n [value]=\"organizationAccountLabel()\"\n [attr.aria-describedby]=\"describedBy(id + '-account-label-hint', 'oauth.organizationAccountLabel')\"\n [attr.aria-invalid]=\"(submitted() && labelMissing()) || serverInvalid('oauth.organizationAccountLabel') ? true : null\"\n (input)=\"organizationAccountLabel.set(value($event)); touch('oauth.organizationAccountLabel')\" />\n <p class=\"hint\" [id]=\"id + '-account-label-hint'\">\n <span [class.error-text]=\"submitted() && labelMissing()\">\n {{ (submitted() && labelMissing() ? 'nh-assistant.admin.server-editor.organization-account-label-required' : 'nh-assistant.admin.server-editor.organization-account-label-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('oauth.organizationAccountLabel')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.organizationAccountLabel')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.organizationAccountLabel') | nhAssistantTranslate }}</p>\n }\n }\n\n <div class=\"meta\">\n @if (server()?.authorization; as confirmed) {\n @if (!needsConfirmation()) {\n <span class=\"badge success\">{{ 'nh-assistant.admin.server-editor.confirmed-authorization' | translate: { issuer: confirmed.issuer } }}</span>\n }\n }\n <button class=\"secondary\" type=\"button\" [disabled]=\"discovering() || urlInvalid()\" (click)=\"discover()\">\n <nh-assistant-icon name=\"link\" />{{ (discovering() ? 'nh-assistant.admin.server-editor.discovering' : 'nh-assistant.admin.server-editor.discover') | translate }}\n </button>\n </div>\n @if (discoveryError(); as failure) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ discoveryErrorKeys() | nhAssistantTranslate: failure.code }}</p>\n }\n @if (discovery(); as found) {\n <div class=\"discovery\" role=\"group\" [attr.aria-label]=\"'nh-assistant.admin.server-editor.discovery-title' | translate\">\n <dl>\n <dt>{{ 'nh-assistant.admin.server-editor.discovery-issuer' | translate }}</dt>\n <dd class=\"mono\">{{ found.issuer }}</dd>\n <dt>{{ 'nh-assistant.admin.server-editor.discovery-resource' | translate }}</dt>\n <dd class=\"mono\">{{ found.resource }}</dd>\n @if (found.scopesSupported.length > 0) {\n <dt>{{ 'nh-assistant.admin.server-editor.discovery-scopes' | translate }}</dt>\n <dd class=\"mono\">{{ found.scopesSupported.join(' ') }}</dd>\n }\n @if (authMode() === 'oauth' && registration(); as kind) {\n <dt>{{ 'nh-assistant.admin.server-editor.discovery-registration' | translate }}</dt>\n <dd>{{ 'nh-assistant.admin.server-editor.registration-' + kind | translate }}</dd>\n }\n </dl>\n @if (pkceMissing()) {\n <p class=\"message error\" role=\"alert\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.pkce-missing' | translate }}</p>\n } @else {\n <label class=\"check\">\n <input\n type=\"checkbox\"\n [checked]=\"confirmAuthorization()\"\n [attr.aria-describedby]=\"describedBy(id + '-confirm-hint', 'oauth.confirmAuthorization')\"\n [attr.aria-invalid]=\"serverInvalid('oauth.confirmAuthorization') ? true : null\"\n (change)=\"confirmAuthorization.set(checked($event)); touch('oauth.confirmAuthorization')\" />\n <span>{{ 'nh-assistant.admin.server-editor.confirm-authorization' | translate }}</span>\n </label>\n <p class=\"hint\" [id]=\"id + '-confirm-hint'\">{{ 'nh-assistant.admin.server-editor.confirm-authorization-hint' | translate }}</p>\n }\n </div>\n }\n @if (submitted() && confirmMissing()) {\n <p class=\"hint\"><span class=\"error-text\">{{ 'nh-assistant.admin.server-editor.confirm-required' | translate }}</span></p>\n } @else if (serverInvalid('oauth.confirmAuthorization')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.confirmAuthorization')\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.confirm-required' | translate }}</p>\n }\n\n <label [for]=\"id + '-scopes'\">{{ 'nh-assistant.admin.server-editor.scopes' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n [id]=\"id + '-scopes'\"\n [maxLength]=\"limits.scopes\"\n [value]=\"oauthScopes()\"\n [attr.aria-describedby]=\"describedBy(id + '-scopes-hint', 'oauth.scopes')\"\n [attr.aria-invalid]=\"(submitted() && scopesInvalid()) || serverInvalid('oauth.scopes') ? true : null\"\n (input)=\"oauthScopes.set(value($event)); touch('oauth.scopes')\" />\n <p class=\"hint\" [id]=\"id + '-scopes-hint'\">\n <span [class.error-text]=\"submitted() && scopesInvalid()\">\n {{ (submitted() && scopesInvalid() ? 'nh-assistant.admin.server-editor.scopes-invalid' : 'nh-assistant.admin.server-editor.scopes-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('oauth.scopes')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.scopes')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.scopes') | nhAssistantTranslate }}</p>\n }\n\n <label [for]=\"id + '-client-id'\">{{ 'nh-assistant.admin.server-editor.client-id' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n [id]=\"id + '-client-id'\"\n [maxLength]=\"limits.clientId\"\n [value]=\"oauthClientId()\"\n [attr.aria-describedby]=\"describedBy(id + '-client-id-hint', 'oauth.clientId')\"\n [attr.aria-invalid]=\"(submitted() && clientIdMissing()) || serverInvalid('oauth.clientId') ? true : null\"\n (input)=\"oauthClientId.set(value($event)); touch('oauth.clientId')\" />\n <p class=\"hint\" [id]=\"id + '-client-id-hint'\">\n <span [class.error-text]=\"submitted() && clientIdMissing()\">\n {{ (submitted() && clientIdMissing() ? 'nh-assistant.admin.server-editor.client-id-required' : 'nh-assistant.admin.server-editor.client-id-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('oauth.clientId')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.clientId')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.clientId') | nhAssistantTranslate }}</p>\n }\n\n @if (oauthClientId().trim().length > 0) {\n <div class=\"inline\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.server-editor.client-secret' | translate\">\n @for (source of secretSources; track source) {\n <label class=\"check\">\n <input\n type=\"radio\"\n [name]=\"id + '-oauth-secret-source'\"\n [value]=\"source\"\n [checked]=\"oauthSecretSource() === source\"\n (change)=\"setOAuthSecretSource(source)\" />\n <span>{{ 'nh-assistant.admin.server-editor.secret-source-' + source | translate }}</span>\n </label>\n }\n </div>\n @if (usesOAuthReference()) {\n <label [for]=\"id + '-oauth-reference'\">{{ 'nh-assistant.admin.server-editor.client-secret-reference' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n placeholder=\"config:planning-client-secret\"\n [id]=\"id + '-oauth-reference'\"\n [maxLength]=\"limits.secretReference\"\n [value]=\"oauthSecretReference()\"\n [attr.aria-describedby]=\"describedBy(null, 'oauth.clientSecretReference')\"\n [attr.aria-invalid]=\"(submitted() && oauthReferenceInvalid()) || serverInvalid('oauth.clientSecretReference') ? true : null\"\n (input)=\"oauthSecretReference.set(value($event)); touch('oauth.clientSecretReference')\" />\n @if (submitted() && oauthReferenceInvalid()) {\n <p class=\"hint\"><span class=\"error-text\">{{ 'nh-assistant.admin.server-editor.secret-reference-invalid' | translate }}</span></p>\n }\n @if (serverInvalid('oauth.clientSecretReference')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.clientSecretReference')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.clientSecretReference') | nhAssistantTranslate }}</p>\n }\n } @else {\n @if (hasOAuthSecret() && oauthSecretAction() === 'keep') {\n <div class=\"meta secret-state\">\n <span class=\"badge success\">{{ 'nh-assistant.admin.server-editor.secret-set' | translate }}</span>\n <button class=\"secondary\" type=\"button\" (click)=\"oauthSecretAction.set('replace')\">{{ 'nh-assistant.admin.server-editor.secret-replace' | translate }}</button>\n </div>\n }\n @if (showOAuthSecretInput()) {\n <label [for]=\"id + '-oauth-secret'\">{{ 'nh-assistant.admin.server-editor.client-secret' | translate }}</label>\n <input\n type=\"password\"\n class=\"mono\"\n autocomplete=\"new-password\"\n spellcheck=\"false\"\n [id]=\"id + '-oauth-secret'\"\n [maxLength]=\"limits.clientSecret\"\n [attr.aria-describedby]=\"describedBy(id + '-oauth-secret-hint', 'oauth.clientSecret')\"\n [attr.aria-invalid]=\"serverInvalid('oauth.clientSecret') ? true : null\"\n [value]=\"oauthSecret()\"\n (input)=\"onOAuthSecretInput($event); touch('oauth.clientSecret')\" />\n }\n <p class=\"hint\" [id]=\"id + '-oauth-secret-hint'\">{{ 'nh-assistant.admin.server-editor.client-secret-hint' | translate }}</p>\n }\n }\n @if (serverInvalid('oauth.clientSecret')) {\n <p class=\"field-error\" [id]=\"errorId('oauth.clientSecret')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('oauth.clientSecret') | nhAssistantTranslate }}</p>\n }\n </fieldset>\n }\n\n @if (usesSecret()) {\n <fieldset class=\"field\">\n <legend>{{ 'nh-assistant.admin.server-editor.secret' | translate }}</legend>\n <div class=\"inline\" role=\"radiogroup\" [attr.aria-label]=\"'nh-assistant.admin.server-editor.secret-source' | translate\">\n @for (source of secretSources; track source) {\n <label class=\"check\">\n <input\n type=\"radio\"\n [name]=\"id + '-secret-source'\"\n [value]=\"source\"\n [checked]=\"secretSource() === source\"\n (change)=\"setSecretSource(source)\" />\n <span>{{ 'nh-assistant.admin.server-editor.secret-source-' + source | translate }}</span>\n </label>\n }\n </div>\n @if (usesReference()) {\n <label [for]=\"id + '-secret-reference'\">{{ 'nh-assistant.admin.server-editor.secret-reference' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n placeholder=\"config:planning-token\"\n [id]=\"id + '-secret-reference'\"\n [maxLength]=\"limits.secretReference\"\n [value]=\"secretReference()\"\n [attr.aria-describedby]=\"describedBy(id + '-secret-reference-hint', 'secretReference')\"\n [attr.aria-invalid]=\"(submitted() && secretReferenceInvalid()) || serverInvalid('secretReference') ? true : null\"\n (input)=\"secretReference.set(value($event)); touch('secretReference')\" />\n <p class=\"hint\" [id]=\"id + '-secret-reference-hint'\">\n <span [class.error-text]=\"submitted() && secretReferenceInvalid()\">\n {{ (submitted() && secretReferenceInvalid() ? 'nh-assistant.admin.server-editor.secret-reference-invalid' : 'nh-assistant.admin.server-editor.secret-reference-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('secretReference')) {\n <p class=\"field-error\" [id]=\"errorId('secretReference')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('secretReference') | nhAssistantTranslate }}</p>\n }\n } @else 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 <!-- A mode with a secret always needs one: it is replaced, or removed by choosing a reference or another mode. -->\n <button class=\"secondary\" type=\"button\" (click)=\"setSecretAction('replace')\">{{ 'nh-assistant.admin.server-editor.secret-replace' | 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 [maxLength]=\"limits.secret\"\n [attr.placeholder]=\"'nh-assistant.admin.server-editor.secret-new' | translate\"\n [attr.aria-describedby]=\"describedBy(id + '-secret-hint', 'secret')\"\n [attr.aria-invalid]=\"serverInvalid('secret') ? true : null\"\n [value]=\"secret()\"\n (input)=\"onSecretInput($event); touch('secret')\" />\n }\n @if (!usesReference()) {\n <p class=\"hint\" [id]=\"id + '-secret-hint'\">{{ 'nh-assistant.admin.server-editor.secret-hint' | translate }}</p>\n }\n @if (serverInvalid('secret')) {\n <p class=\"field-error\" [id]=\"errorId('secret')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('secret') | nhAssistantTranslate }}</p>\n }\n </fieldset>\n }\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-certificate'\">{{ 'nh-assistant.admin.server-editor.client-certificate' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n [id]=\"id + '-certificate'\"\n [maxLength]=\"limits.clientCertificateReference\"\n [value]=\"clientCertificateReference()\"\n [attr.aria-describedby]=\"describedBy(id + '-certificate-hint', 'clientCertificateReference')\"\n [attr.aria-invalid]=\"(submitted() && certificateInvalid()) || serverInvalid('clientCertificateReference') ? true : null\"\n (input)=\"clientCertificateReference.set(value($event)); touch('clientCertificateReference')\" />\n <p class=\"hint\" [id]=\"id + '-certificate-hint'\">\n <span [class.error-text]=\"submitted() && certificateInvalid()\">\n {{ (submitted() && certificateInvalid() ? 'nh-assistant.admin.server-editor.client-certificate-invalid' : 'nh-assistant.admin.server-editor.client-certificate-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid('clientCertificateReference')) {\n <p class=\"field-error\" [id]=\"errorId('clientCertificateReference')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('clientCertificateReference') | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-transport'\">{{ 'nh-assistant.admin.server-editor.transport' | translate }}</label>\n <select\n [id]=\"id + '-transport'\"\n [attr.aria-describedby]=\"describedBy(id + '-transport-hint', 'transport')\"\n [attr.aria-invalid]=\"serverInvalid('transport') ? true : null\"\n (change)=\"transport.set($any(value($event))); touch('transport')\">\n @for (option of transports; track option) {\n <option [value]=\"option\" [selected]=\"transport() === option\">{{ 'nh-assistant.admin.mcp.transport.' + option | translate }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-transport-hint'\">{{ 'nh-assistant.admin.server-editor.transport-hint' | translate }}</p>\n @if (serverInvalid('transport')) {\n <p class=\"field-error\" [id]=\"errorId('transport')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('transport') | nhAssistantTranslate }}</p>\n }\n </div>\n </div>\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 [maxLength]=\"limits.requiredPolicy\"\n [value]=\"requiredPolicy()\"\n [attr.aria-describedby]=\"describedBy(id + '-policy-hint', 'requiredPolicy')\"\n [attr.aria-invalid]=\"serverInvalid('requiredPolicy') ? true : null\"\n (input)=\"requiredPolicy.set(value($event)); touch('requiredPolicy')\" />\n <p class=\"hint\" [id]=\"id + '-policy-hint'\">{{ 'nh-assistant.admin.server-editor.required-policy-hint' | translate }}</p>\n @if (serverInvalid('requiredPolicy')) {\n <p class=\"field-error\" [id]=\"errorId('requiredPolicy')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('requiredPolicy') | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-headless'\">{{ 'nh-assistant.admin.server-editor.headless-use' | translate }}</label>\n <select\n [id]=\"id + '-headless'\"\n [attr.aria-describedby]=\"describedBy(id + '-headless-hint', 'headlessUse')\"\n [attr.aria-invalid]=\"serverInvalid('headlessUse') ? true : null\"\n (change)=\"headlessUse.set($any(value($event))); touch('headlessUse')\">\n @for (use of headlessUses(); track use) {\n <option [value]=\"use\" [selected]=\"effectiveHeadlessUse() === use\">{{ 'nh-assistant.admin.mcp.headless.' + use | translate }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-headless-hint'\">\n {{ (personalCredential() ? 'nh-assistant.admin.server-editor.headless-use-personal' : 'nh-assistant.admin.server-editor.headless-use-hint') | translate }}\n </p>\n @if (serverInvalid('headlessUse')) {\n <p class=\"field-error\" [id]=\"errorId('headlessUse')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('headlessUse') | nhAssistantTranslate }}</p>\n }\n </div>\n\n @if (!isNew()) {\n <fieldset class=\"field readers\">\n <legend>{{ 'nh-assistant.admin.server-editor.reader.title' | translate }}</legend>\n <p class=\"hint\">{{ 'nh-assistant.admin.server-editor.reader.hint' | translate }}</p>\n @if (serverInvalid('readers')) {\n <p class=\"field-error\" [id]=\"errorId('readers')\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys('readers') | nhAssistantTranslate }}</p>\n }\n\n @for (reader of readers(); track reader.key; let index = $index) {\n <fieldset class=\"subsection reader\" [attr.data-reader]=\"index\">\n <legend class=\"reader-title\">{{ 'nh-assistant.admin.server-editor.reader.item' | translate: { number: index + 1 } }}</legend>\n\n <div class=\"grid\">\n <div class=\"field\">\n <label [for]=\"id + '-reader-tool-' + reader.key\">{{ 'nh-assistant.admin.server-editor.reader.tool' | translate }}</label>\n <select\n [id]=\"id + '-reader-tool-' + reader.key\"\n [attr.aria-describedby]=\"describedBy(id + '-reader-tool-hint-' + reader.key, readerField(index, 'toolName'))\"\n [attr.aria-invalid]=\"(submitted() && (readerProblems()[index].tool || readerProblems()[index].duplicate)) || serverInvalid(readerField(index, 'toolName')) ? true : null\"\n (change)=\"updateReader(index, 'toolName', value($event))\">\n <option value=\"\" [selected]=\"reader.toolName === ''\">{{ 'nh-assistant.admin.server-editor.reader.tool-choose' | translate }}</option>\n @for (name of readerToolNames(); track name) {\n <option [value]=\"name\" [selected]=\"reader.toolName === name\">{{ name }}</option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-reader-tool-hint-' + reader.key\">\n @if (submitted() && readerProblems()[index].tool) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.required' | translate }}</span>\n } @else if (submitted() && readerProblems()[index].duplicate) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.server-editor.reader.tool-duplicate' | translate }}</span>\n } @else {\n {{ 'nh-assistant.admin.server-editor.reader.tool-hint' | translate }}\n }\n </p>\n @if (serverInvalid(readerField(index, 'toolName'))) {\n <p class=\"field-error\" [id]=\"errorId(readerField(index, 'toolName'))\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys(readerField(index, 'toolName')) | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-reader-classification-' + reader.key\">{{ 'nh-assistant.admin.server-editor.reader.max-classification' | translate }}</label>\n <select\n [id]=\"id + '-reader-classification-' + reader.key\"\n [attr.aria-describedby]=\"describedBy(id + '-reader-classification-hint-' + reader.key, readerField(index, 'maxClassification'))\"\n [attr.aria-invalid]=\"(submitted() && readerProblems()[index].classification) || serverInvalid(readerField(index, 'maxClassification')) ? true : null\"\n (change)=\"updateReader(index, 'maxClassification', value($event))\">\n <option value=\"\" [selected]=\"reader.maxClassification === ''\">{{ 'nh-assistant.admin.server-editor.reader.max-classification-choose' | translate }}</option>\n @for (classification of classifications; track classification) {\n <option [value]=\"classification\" [selected]=\"reader.maxClassification === classification\">\n {{ 'nh-assistant.admin.run-config.skills.classification.' + classification | translate }}\n </option>\n }\n </select>\n <p class=\"hint\" [id]=\"id + '-reader-classification-hint-' + reader.key\">\n @if (submitted() && readerProblems()[index].classification) {\n <span class=\"error-text\">{{ 'nh-assistant.admin.required' | translate }}</span>\n } @else {\n {{ 'nh-assistant.admin.server-editor.reader.max-classification-hint' | translate }}\n }\n </p>\n @if (serverInvalid(readerField(index, 'maxClassification'))) {\n <p class=\"field-error\" [id]=\"errorId(readerField(index, 'maxClassification'))\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys(readerField(index, 'maxClassification')) | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-reader-types-' + reader.key\">{{ 'nh-assistant.admin.server-editor.reader.media-types' | translate }}</label>\n <input\n type=\"text\"\n class=\"mono\"\n spellcheck=\"false\"\n [id]=\"id + '-reader-types-' + reader.key\"\n [value]=\"reader.mediaTypes\"\n [attr.aria-describedby]=\"describedBy(id + '-reader-types-hint-' + reader.key, readerField(index, 'mediaTypes'))\"\n [attr.aria-invalid]=\"(submitted() && readerProblems()[index].types) || serverInvalid(readerField(index, 'mediaTypes')) ? true : null\"\n (input)=\"updateReader(index, 'mediaTypes', value($event))\" />\n <p class=\"hint\" [id]=\"id + '-reader-types-hint-' + reader.key\">\n <span [class.error-text]=\"submitted() && readerProblems()[index].types\">\n {{ (submitted() && readerProblems()[index].types ? 'nh-assistant.admin.server-editor.reader.media-types-invalid' : 'nh-assistant.admin.server-editor.reader.media-types-hint') | translate }}\n </span>\n </p>\n @if (serverInvalid(readerField(index, 'mediaTypes'))) {\n <p class=\"field-error\" [id]=\"errorId(readerField(index, 'mediaTypes'))\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys(readerField(index, 'mediaTypes')) | nhAssistantTranslate }}</p>\n }\n </div>\n\n <div class=\"field\">\n <label [for]=\"id + '-reader-priority-' + reader.key\">{{ 'nh-assistant.admin.server-editor.reader.priority' | translate }}</label>\n <input\n type=\"number\"\n inputmode=\"numeric\"\n step=\"1\"\n [min]=\"readerPriority.min\"\n [max]=\"readerPriority.max\"\n [id]=\"id + '-reader-priority-' + reader.key\"\n [value]=\"reader.priority\"\n [attr.aria-describedby]=\"describedBy(id + '-reader-priority-hint-' + reader.key, readerField(index, 'priority'))\"\n [attr.aria-invalid]=\"(submitted() && readerProblems()[index].priority) || serverInvalid(readerField(index, 'priority')) ? true : null\"\n (input)=\"updateReader(index, 'priority', value($event))\" />\n <p class=\"hint\" [id]=\"id + '-reader-priority-hint-' + reader.key\">\n <span [class.error-text]=\"submitted() && readerProblems()[index].priority\">\n {{ (submitted() && readerProblems()[index].priority ? 'nh-assistant.admin.server-editor.reader.priority-invalid' : 'nh-assistant.admin.server-editor.reader.priority-hint') | translate: readerPriority }}\n </span>\n </p>\n @if (serverInvalid(readerField(index, 'priority'))) {\n <p class=\"field-error\" [id]=\"errorId(readerField(index, 'priority'))\"><nh-assistant-icon name=\"warning\" />{{ serverErrorKeys(readerField(index, 'priority')) | nhAssistantTranslate }}</p>\n }\n </div>\n </div>\n\n <div class=\"inline\">\n <button\n type=\"button\"\n class=\"secondary\"\n [attr.aria-label]=\"'nh-assistant.admin.server-editor.reader.remove-label' | translate: { number: index + 1 }\"\n (click)=\"removeReader(index)\">\n <nh-assistant-icon name=\"trash\" />{{ 'nh-assistant.admin.server-editor.reader.remove' | translate }}\n </button>\n </div>\n </fieldset>\n } @empty {\n <p class=\"muted\">{{ 'nh-assistant.admin.server-editor.reader.empty' | translate }}</p>\n }\n\n <div class=\"inline\">\n <button\n type=\"button\"\n class=\"secondary\"\n [id]=\"id + '-reader-add'\"\n [disabled]=\"readers().length >= maxReaders || readerToolNames().length === 0\"\n [attr.aria-describedby]=\"id + '-reader-add-hint'\"\n (click)=\"addReader()\">\n <nh-assistant-icon name=\"plus\" />{{ 'nh-assistant.admin.server-editor.reader.add' | translate }}\n </button>\n </div>\n <p class=\"hint\" [id]=\"id + '-reader-add-hint'\">{{ readerAddHint() | translate: { max: maxReaders } }}</p>\n @if (readers().length > 0) {\n <p class=\"message warning\" role=\"note\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.server-editor.reader.leaves-application' | translate }}</p>\n }\n </fieldset>\n }\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 <div class=\"form-error\" role=\"alert\" data-server-error>\n <nh-assistant-icon name=\"warning\" />\n <div>\n <span>{{ errorKeys() | nhAssistantTranslate: failure.code }}</span>\n @if (otherServerErrors().length > 0) {\n <ul>\n @for (other of otherServerErrors(); track other.field) {\n <li><code class=\"mono\">{{ other.field }}</code>: {{ other.keys | nhAssistantTranslate }}</li>\n }\n </ul>\n }\n </div>\n </div>\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, effect, inject, signal, untracked } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { Subscription } from 'rxjs';\nimport {\n McpConnectionsSummary,\n McpServer,\n McpServerTestResult,\n NhAssistantAdminApiService,\n NhAssistantError,\n NhAssistantMcpConnectService,\n ɵnhAssistantCodeKeys as nhAssistantCodeKeys,\n ɵnhAssistantErrorKeys as nhAssistantErrorKeys,\n ɵnhAssistantErrorOf as nhAssistantErrorOf,\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 organization's OAuth connection,\n * the server editor and the tool table of one server. The personal connections are counted and\n * revoked only for servers each person connects to with OAuth; a count that could not be read shows\n * its translated code at the 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 readonly connector = inject(NhAssistantMcpConnectService);\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 /** The server whose organization connection is being authorized. */\n readonly connecting = signal<string | null>(null);\n readonly confirmingDisconnect = signal<string | null>(null);\n readonly confirmingRevokeAll = signal<string | null>(null);\n /** The personal connections per status of each server people connect to themselves. */\n readonly summaries = signal<Record<string, McpConnectionsSummary>>({});\n /** Why the personal connections of a server could not be counted, per server. */\n readonly summaryErrors = signal<Record<string, NhAssistantError>>({});\n /** The latest connection result to announce, per server. */\n readonly notice = signal<{ serverId: string; key: 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 // An authorization in redirect mode that returned to this page.\n effect(() => {\n const returned = this.connector.returned();\n if (returned) {\n untracked(() => {\n this.connector.returned.set(null);\n if (returned.completion) {\n this.notice.set({ serverId: returned.completion.serverId, key: 'nh-assistant.admin.mcp.connect-done' });\n this.refresh();\n } else {\n this.error.set(nhAssistantErrorOf(returned.code));\n }\n });\n }\n });\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 this.loadSummaries(servers);\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({\n next: servers => {\n this.servers.set(servers);\n this.loadSummaries(servers);\n },\n error: () => undefined\n }));\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 => {\n this.setTest(server.id, { running: false, result });\n // The test records the connection state of the server.\n this.refresh();\n },\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 ? nhAssistantCodeKeys(code) : ['nh-assistant.errors.generic'];\n }\n\n /** The text of a server's failed count of personal connections. */\n summaryErrorKeys(serverId: string): string[] {\n return nhAssistantErrorKeys(this.summaryErrors()[serverId] ?? null);\n }\n\n /** Whether an administrator connects the organization's account to the server. */\n authorizesOrganization(server: McpServer): boolean {\n return server.authMode === 'oauth' && server.connectionScope === 'organization';\n }\n\n /** Whether each person connects their own account to the server. */\n connectsPeople(server: McpServer): boolean {\n return server.authMode === 'oauth' && server.connectionScope === 'user';\n }\n\n summary(server: McpServer): McpConnectionsSummary | null {\n return this.summaries()[server.id] ?? null;\n }\n\n /** Revokes every person's connection of the server; each person connects again. */\n revokeAll(server: McpServer): void {\n this.confirmingRevokeAll.set(null);\n this.error.set(null);\n this.notice.set(null);\n this.actions.add(this.admin.revokeMcpConnections(server.id).subscribe({\n complete: () => {\n this.notice.set({ serverId: server.id, key: 'nh-assistant.admin.mcp.revoke-all-done' });\n this.loadSummaries([server]);\n },\n error: (error: unknown) => this.error.set(toNhAssistantError(error))\n }));\n }\n\n /** Counts the personal connections of the servers each person connects to with OAuth; only those have them. */\n private loadSummaries(servers: readonly McpServer[]): void {\n for (const server of servers.filter(item => this.connectsPeople(item))) {\n this.actions.add(this.admin.getMcpConnectionsSummary(server.id).subscribe({\n next: summary => {\n this.summaries.update(summaries => ({ ...summaries, [server.id]: summary }));\n this.summaryErrors.update(({ [server.id]: _, ...others }) => others);\n },\n error: (error: unknown) => {\n this.summaryErrors.update(errors => ({ ...errors, [server.id]: toNhAssistantError(error) }));\n }\n }));\n }\n }\n\n /** Counts the personal connections of one server again. */\n retrySummary(server: McpServer): void {\n this.loadSummaries([server]);\n }\n\n /**\n * Authorizes the organization's account, or for a server people connect to themselves the\n * administrator's own account, in a window opened right away, so popup blockers allow it, and\n * completes the connection with this administrator's session.\n */\n connect(server: McpServer): void {\n this.error.set(null);\n this.notice.set(null);\n this.connecting.set(server.id);\n this.actions.add(this.connector.run(request => this.admin.authorizeMcpOrganizationConnection(server.id, request), server.id).subscribe({\n next: () => {\n this.connecting.set(null);\n this.notice.set({\n serverId: server.id,\n key: this.connectsPeople(server) ? 'nh-assistant.admin.mcp.connect-own-done' : 'nh-assistant.admin.mcp.connect-done'\n });\n this.refresh();\n },\n error: (error: unknown) => {\n this.connecting.set(null);\n this.error.set(toNhAssistantError(error));\n }\n }));\n }\n\n /** Removes the organization connection; the server revokes its tokens. */\n disconnect(server: McpServer): void {\n this.confirmingDisconnect.set(null);\n this.error.set(null);\n this.notice.set(null);\n this.actions.add(this.admin.disconnectMcpOrganizationConnection(server.id).subscribe({\n complete: () => {\n this.notice.set({ serverId: server.id, key: 'nh-assistant.admin.mcp.disconnect-done' });\n this.refresh();\n },\n error: (error: unknown) => this.error.set(toNhAssistantError(error))\n }));\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] | nhAssistantTranslate: server.authMode }}</span>\n @if (server.authMode === 'bearer' || server.authMode === 'api-key' || server.authMode === 'basic') {\n @if (server.secretReference; as reference) {\n <span class=\"badge success\">{{ 'nh-assistant.admin.mcp.secret-reference' | translate: { reference: reference } }}</span>\n } @else {\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 }\n @if (server.authMode === 'oauth') {\n <span>{{ 'nh-assistant.admin.mcp.connection-scope.' + server.connectionScope | translate }}</span>\n }\n @if (server.organizationConnection; as connection) {\n <span\n class=\"badge\"\n [class.success]=\"connection.status === 'active'\"\n [class.warning]=\"connection.status === 'reauthorization-required' || connection.status === 'issuer-changed'\">\n {{ 'nh-assistant.admin.mcp.connection-status.' + connection.status | translate }}\n </span>\n @if (server.oauth?.organizationAccountLabel; as account) {\n <span>{{ 'nh-assistant.admin.mcp.organization-account' | translate: { account: account } }}</span>\n }\n @if (connection.status === 'active' && connection.connectedAt) {\n <span>{{ 'nh-assistant.admin.mcp.connected-by' | translate: { actor: connection.connectedBy ?? '', date: (connection.connectedAt | date: 'medium') } }}</span>\n }\n @if (connection.requiredScopes; as scopes) {\n <span>{{ 'nh-assistant.admin.mcp.required-scopes' | translate: { scopes: scopes } }}</span>\n }\n }\n @if (connectsPeople(server) && summary(server); as counts) {\n <span>{{ 'nh-assistant.admin.mcp.personal-connections' | translate: { active: counts.active } }}</span>\n @if (counts.reauthorizationRequired + counts.issuerChanged > 0) {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.mcp.personal-attention' | translate: { count: counts.reauthorizationRequired + counts.issuerChanged } }}</span>\n }\n }\n @if (server.clientCertificateReference; as certificate) {\n <span class=\"badge\">{{ 'nh-assistant.admin.mcp.client-certificate' | translate: { name: certificate } }}</span>\n }\n @if (server.transport === 'auto') {\n <span class=\"badge warning\">{{ 'nh-assistant.admin.mcp.transport-fallback' | translate }}</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 <span>{{ 'nh-assistant.admin.mcp.headless.' + (server.headlessUse ?? 'never') | translate }}</span>\n @if (server.lastConnectAt; as connectedAt) {\n @if (server.lastConnectCode; as code) {\n <span class=\"badge danger\">{{ 'nh-assistant.admin.mcp.connect-failed' | translate: { date: (connectedAt | date: 'medium') } }}</span>\n <span>{{ testErrorKeys(code) | nhAssistantTranslate: code }}</span>\n } @else {\n <span>{{ 'nh-assistant.admin.mcp.connected' | translate: { date: (connectedAt | date: 'medium') } }}</span>\n }\n } @else {\n <span>{{ 'nh-assistant.admin.mcp.never-connected' | translate }}</span>\n }\n </div>\n\n @if (summaryErrors()[server.id]; as failure) {\n <p class=\"message warning catalog-error\" role=\"status\" data-summary-error>\n <nh-assistant-icon name=\"warning\" />\n <span class=\"grow\">\n {{ 'nh-assistant.admin.mcp.personal-connections-failed' | translate }}\n {{ summaryErrorKeys(server.id) | nhAssistantTranslate: failure.code }}\n </span>\n <button class=\"secondary\" type=\"button\" (click)=\"retrySummary(server)\">{{ 'nh-assistant.admin.retry' | translate }}</button>\n </p>\n }\n @if (server.organizationConnection?.status === 'issuer-changed') {\n <p class=\"message warning\" role=\"note\"><nh-assistant-icon name=\"warning\" />{{ 'nh-assistant.admin.mcp.issuer-changed' | translate }}</p>\n }\n @if (connecting() === server.id) {\n <p class=\"muted\" role=\"status\">{{ 'nh-assistant.admin.mcp.connecting' | translate }}</p>\n } @else if (notice()?.serverId === server.id) {\n <p class=\"message success\" role=\"status\"><nh-assistant-icon name=\"check\" />{{ notice()!.key | translate }}</p>\n }\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 (authorizesOrganization(server)) {\n <button class=\"secondary\" type=\"button\" [disabled]=\"connecting() !== null\" (click)=\"connect(server)\">\n <nh-assistant-icon name=\"link\" />{{ (server.organizationConnection?.status === 'not-connected' ? 'nh-assistant.admin.mcp.connect' : 'nh-assistant.admin.mcp.reconnect') | translate }}\n </button>\n }\n @if (connectsPeople(server)) {\n <button class=\"secondary\" type=\"button\" [disabled]=\"connecting() !== null\" (click)=\"connect(server)\">\n <nh-assistant-icon name=\"link\" />{{ 'nh-assistant.admin.mcp.connect-own' | translate }}\n </button>\n @if (confirmingRevokeAll() === server.id) {\n <button class=\"danger\" type=\"button\" (click)=\"revokeAll(server)\">{{ 'nh-assistant.admin.mcp.confirm-revoke-all' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingRevokeAll.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else if ((summary(server)?.active ?? 0) + (summary(server)?.reauthorizationRequired ?? 0) + (summary(server)?.issuerChanged ?? 0) > 0) {\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingRevokeAll.set(server.id)\">{{ 'nh-assistant.admin.mcp.revoke-all' | translate }}</button>\n }\n }\n @if (server.organizationConnection && server.organizationConnection.status !== 'not-connected') {\n @if (confirmingDisconnect() === server.id) {\n <button class=\"danger\" type=\"button\" (click)=\"disconnect(server)\">{{ 'nh-assistant.admin.mcp.confirm-disconnect' | translate }}</button>\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingDisconnect.set(null)\">{{ 'nh-assistant.admin.cancel' | translate }}</button>\n } @else {\n <button class=\"secondary\" type=\"button\" (click)=\"confirmingDisconnect.set(server.id)\">{{ 'nh-assistant.admin.mcp.disconnect' | translate }}</button>\n }\n }\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.cancel' | 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, Injector, 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 private readonly injector = inject(Injector);\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 /**\n * Shows the MCP servers, for example from an agent's flow that explains why a server is not used in\n * runs without a person, and moves the focus to their tab.\n */\n showMcpServers(): void {\n this.select('mcp-servers');\n afterNextRender(() => this.host.nativeElement.querySelector<HTMLElement>(`#${this.id}-tab-mcp-servers`)?.focus(), { injector: this.injector });\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 (openMcpServers)=\"showMcpServers()\" />\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 './agents/nh-assistant-agent-run-history.component';\nexport * from './agents/nh-assistant-agent-run-configuration.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":["toNhAssistantError","nhAssistantErrorKeys","NhAssistantIconComponent","NhAssistantTranslatePipe","nextId","NH_ASSISTANT_DASH_CASE","dayMs","periodRange","nhAssistantCodeKeys","NhAssistantSubjectLinkComponent","blank","NhAssistantPickerComponent","NhAssistantRunNowDialogComponent","nhAssistantErrorOf"],"mappings":"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"}