@things-factory/ai-assistant 10.1.256 → 10.1.258
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/settings/ai-agent-setting-let.ts +46 -63
- package/client/settings/ai-usage-setting-let.ts +18 -30
- package/dist-client/settings/ai-agent-setting-let.d.ts +8 -7
- package/dist-client/settings/ai-agent-setting-let.js +47 -79
- package/dist-client/settings/ai-agent-setting-let.js.map +1 -1
- package/dist-client/settings/ai-usage-setting-let.d.ts +4 -5
- package/dist-client/settings/ai-usage-setting-let.js +19 -37
- package/dist-client/settings/ai-usage-setting-let.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -11
- package/translations/es.json +21 -1
- package/translations/ja.json +21 -1
- package/translations/ms.json +21 -1
- package/translations/zh.json +21 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-agent-setting-let.js","sourceRoot":"","sources":["../../client/settings/ai-agent-setting-let.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@things-factory/setting-base/dist-client/layout/settinglet.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { OxPrompt } from '@operato/popup'\nimport '@operato/popup/ox-popup-menu.js'\nimport { OxPopupMenu } from '@operato/popup/ox-popup-menu.js'\nimport { ButtonContainerStyles, FormFieldStyles } from '@operato/styles'\n\nimport { providerLabel } from '../utils/agent-choice.js'\nimport {\n type AgentDraft,\n type AgentSettings,\n type AgentView,\n draftOf,\n groupByOwner,\n saveInput,\n type SaveChange\n} from './agent-settings-model.js'\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n i18next.t(`ai-assistant.agent.${key}`, { ...options, defaultValue })\n\nconst SETTINGS_QUERY = gql`\n query AiAgentSettings {\n aiAgentSettings {\n chain {\n id\n name\n }\n agents {\n id\n name\n provider\n model\n baseURL\n organization\n active\n owner {\n id\n name\n }\n inherited\n turnedOff\n keyState\n keyDomain {\n id\n name\n }\n keyHint\n usable\n isDefault\n usedBelow {\n id\n name\n }\n }\n defaultAgentId\n defaultFrom\n state\n reason\n }\n }\n`\n\nconst MODELS_QUERY = gql`\n query AiProviderModels($provider: String!, $apiKey: String, $agentId: String, $baseURL: String, $organization: String) {\n aiProviderModels(provider: $provider, apiKey: $apiKey, agentId: $agentId, baseURL: $baseURL, organization: $organization)\n }\n`\n\nconst SAVE_MUTATION = gql`\n mutation SaveAiAgents($input: AiAgentsInput!) {\n saveAiAgents(input: $input)\n }\n`\n\nconst PROVIDERS = ['openai', 'anthropic', 'gemini']\n\ntype ModelList = { state: 'idle' | 'loading' | 'ready' | 'failed'; models: string[]; reason?: string }\n\n/**\n * A domain's AI agents - the card in Settings › {domain} settings (design/ai/agent-settings.md §7-1, §7-2).\n *\n * The first line says whether AI works here and, if not, the one thing that is missing. The list is grouped by the\n * domain that declared each agent: this domain's own, editable, then each domain above, read-only, closest first. A key\n * is written and never shown again; the model is only ever picked from the list the provider gives that key.\n */\n@customElement('ai-agent-setting-let')\nexport class AiAgentSettingLet extends localize(i18next)(LitElement) {\n static styles = [\n /* The button look comes from the action bar's styles, which also restyle select and text inputs - the form\n field rules come after them, so every field in the card has the standard field look. */\n ButtonContainerStyles,\n FormFieldStyles,\n css`\n :host {\n display: block;\n }\n [slot='content'] {\n display: grid;\n gap: 12px;\n text-transform: none;\n }\n .head {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .status {\n flex: 1;\n font-size: 12px;\n color: var(--md-sys-color-on-surface-variant);\n }\n .status.off {\n color: var(--md-sys-color-error);\n }\n .group-title {\n margin: 4px 0 0;\n font-size: 11px;\n font-weight: 600;\n color: var(--md-sys-color-on-surface-variant);\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n padding-bottom: 2px;\n }\n .row {\n display: grid;\n grid-template-columns: 20px minmax(100px, 1.2fr) 70px minmax(120px, 1.4fr) minmax(110px, 1fr) auto auto 28px;\n align-items: center;\n gap: 8px;\n min-height: 32px;\n font-size: 13px;\n }\n .row.muted > :not(.more-menu) {\n opacity: 0.55;\n }\n .name {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .model {\n font-family: var(--md-sys-typescale-mono-font, monospace);\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .key {\n font-size: 12px;\n white-space: nowrap;\n }\n .key.missing {\n color: var(--md-sys-color-error);\n font-weight: 600;\n }\n .use {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n white-space: nowrap;\n }\n .below {\n border: none;\n background: none;\n padding: 0;\n height: auto;\n font-size: 11px;\n font-weight: 400;\n color: var(--md-sys-color-primary);\n cursor: pointer;\n }\n .more-menu {\n border: none;\n background: none;\n height: auto;\n padding: 2px 6px;\n font-size: 14px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface-variant);\n }\n form.editor {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 12px;\n padding: 12px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: var(--md-sys-shape-corner-small);\n background: var(--md-sys-color-surface-container-lowest);\n }\n @media (max-width: 600px) {\n form.editor {\n grid-template-columns: 1fr;\n }\n }\n form.editor label {\n display: grid;\n gap: 4px;\n font-size: 11px;\n color: var(--md-sys-color-on-surface-variant);\n }\n form.editor input,\n form.editor select {\n height: var(--form-element-height-medium, 32px);\n box-sizing: border-box;\n font-size: 13px;\n }\n .with-action {\n display: flex;\n gap: 4px;\n }\n .with-action > select {\n flex: 1;\n min-width: 0;\n }\n .hint {\n font-size: 11px;\n color: var(--md-sys-color-on-surface-variant);\n }\n .error {\n font-size: 11.5px;\n color: var(--md-sys-color-error);\n }\n details.advanced {\n grid-column: 1 / -1;\n font-size: 12px;\n }\n details.advanced[open] > div {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 12px;\n margin-top: 8px;\n }\n .actions {\n grid-column: 1 / -1;\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n }\n button.primary {\n background: var(--md-sys-color-primary);\n color: var(--md-sys-color-on-primary);\n border-color: var(--md-sys-color-primary);\n }\n button.primary md-icon {\n color: inherit;\n }\n .key-override {\n display: flex;\n gap: 8px;\n align-items: center;\n padding: 8px 0 8px 28px;\n }\n .key-override input {\n flex: 1;\n height: var(--form-element-height-medium, 32px);\n box-sizing: border-box;\n }\n `\n ]\n\n @state() private settings?: AgentSettings\n @state() private loadFailed?: string\n @state() private draft?: AgentDraft\n @state() private models: ModelList = { state: 'idle', models: [] }\n @state() private saving = false\n @state() private saveError?: string\n @state() private keyFor?: string\n @state() private keyDraft = ''\n\n connectedCallback() {\n super.connectedCallback()\n this.load()\n }\n\n private async load() {\n this.loadFailed = undefined\n try {\n const response = await client.query({ query: SETTINGS_QUERY, fetchPolicy: 'network-only' })\n this.settings = answered(response, 'aiAgentSettings')\n } catch (error: any) {\n this.loadFailed = messageOf(error)\n }\n }\n\n render() {\n return html`\n <setting-let>\n <div slot=\"title\">${t('title', 'AI agents')}</div>\n <div slot=\"content\">${this.renderContent()}</div>\n </setting-let>\n `\n }\n\n private renderContent() {\n if (this.loadFailed) {\n return html`\n <div class=\"head\">\n <span class=\"status off\">${t('load-failed', 'Could not read the AI agents.')} ${this.loadFailed}</span>\n <button type=\"button\" @click=${() => this.load()}><md-icon>refresh</md-icon>${t('retry', 'Try again')}</button>\n </div>\n `\n }\n if (!this.settings) return html`<span class=\"status\">${t('loading', 'Reading…')}</span>`\n\n const groups = groupByOwner(this.settings)\n return html`\n <div class=\"head\">\n ${this.renderStatus()}\n <button type=\"button\" ?disabled=${!!this.draft || this.saving} @click=${() => this.startNew()}>\n <md-icon>add</md-icon>${t('add', 'Agent')}\n </button>\n </div>\n ${this.draft && !this.draft.id ? this.renderEditor() : nothing}\n ${groups.map(\n group => html`\n ${groups.length > 1 || group.inherited\n ? html`<div class=\"group-title\">\n ${group.inherited ? t('inherited-from', 'Inherited from {path}', { path: group.path }) : t('this-domain', 'This domain')}\n </div>`\n : nothing}\n ${group.agents.map(agent => html`${this.renderRow(agent)} ${this.draft?.id === agent.id ? this.renderEditor() : nothing}\n ${this.keyFor === agent.id ? this.renderKeyOverride(agent) : nothing}`)}\n `\n )}\n `\n }\n\n private renderStatus() {\n const settings = this.settings!\n if (settings.state === 'configured') {\n const usable = settings.agents.filter(one => one.usable).length\n const chosen = settings.agents.find(one => one.id === settings.defaultAgentId)\n return html`<span class=\"status\">\n ${t('status-on', 'AI is on here · {count} agents to pick · default {name}', { count: usable, name: chosen?.name ?? '' })}\n </span>`\n }\n const why =\n settings.reason === 'no-agent-key'\n ? t('status-no-key', 'No agent has an API key, so AI is off here.')\n : settings.reason === 'no-usable-agent'\n ? t('status-all-off', 'Every agent is turned off, so AI is off here.')\n : t('status-no-agent', 'There is no AI agent, so AI is off here.')\n return html`<span class=\"status off\">${why}</span>`\n }\n\n private renderRow(agent: AgentView) {\n const settings = this.settings!\n const editable = !agent.inherited\n const muted = !agent.usable\n return html`\n <div class=\"row ${muted ? 'muted' : ''}\">\n <input\n type=\"radio\"\n name=\"default\"\n aria-label=${t('default', 'Default')}\n title=${t('default-hint', 'The agent a person gets before picking one')}\n .checked=${agent.id === settings.defaultAgentId}\n ?disabled=${!agent.usable || this.saving}\n @change=${() => this.save({ kind: 'default', agentId: agent.id })} />\n <span class=\"name\" title=${agent.name}>${agent.name}</span>\n <span>${providerLabel(agent.provider)}</span>\n <span class=\"model\" title=${agent.model}>${agent.model}</span>\n ${this.renderKey(agent)}\n ${editable\n ? html`<label class=\"use\">\n <input type=\"checkbox\" .checked=${agent.active} ?disabled=${this.saving} @change=${(e: Event) => this.onActive(agent, (e.target as HTMLInputElement).checked)} />\n ${t('use', 'Use')}\n </label>`\n : html`<label class=\"use\">\n <input type=\"checkbox\" .checked=${!agent.turnedOff} ?disabled=${this.saving} @change=${(e: Event) => this.save({ kind: 'turn-off', agentId: agent.id, off: !(e.target as HTMLInputElement).checked })} />\n ${t('use-here', 'Use here')}\n </label>`}\n ${editable && agent.usedBelow.length\n ? html`<button type=\"button\" class=\"below\" title=${agent.usedBelow.map(one => one.name).join(', ')} @click=${() => this.showUsers(agent)}>\n ${t('used-below', '{count} below', { count: agent.usedBelow.length })}\n </button>`\n : html`<span></span>`}\n ${this.renderMenu(agent)}\n </div>\n `\n }\n\n private renderKey(agent: AgentView) {\n switch (agent.keyState) {\n case 'own':\n return html`<span class=\"key\">${agent.keyHint}</span>`\n case 'overridden':\n return html`<span class=\"key\">${t('key-this-domain', 'This domain\\'s key {hint}', { hint: agent.keyHint ?? '' })}</span>`\n case 'inherited':\n return html`<span class=\"key\">${t('key-of', '{domain} key', { domain: agent.keyDomain?.name ?? '' })}</span>`\n default:\n return html`<span class=\"key missing\">${t('key-missing', 'No key')}</span>`\n }\n }\n\n /** The row's actions in the platform's popup menu - one at a time, closed by a press outside or Escape. */\n private renderMenu(agent: AgentView) {\n return html`<button\n type=\"button\"\n class=\"more-menu\"\n aria-label=${t('more', 'More')}\n title=${t('more', 'More')}\n ?disabled=${this.saving}\n @click=${(e: MouseEvent) => this.openMenu(e, agent)}>⋯</button>`\n }\n\n private openMenu(event: MouseEvent, agent: AgentView) {\n const at = (event.currentTarget as HTMLElement).getBoundingClientRect()\n OxPopupMenu.open({\n template: agent.inherited\n ? html`\n <ox-popup-menuitem\n label=${agent.keyState === 'overridden' ? t('replace-own-key', \"Replace this domain's key\") : t('use-own-key', \"Use this domain's key\")}\n @select=${() => this.startKeyOverride(agent)}></ox-popup-menuitem>\n ${agent.keyState === 'overridden'\n ? html`<ox-popup-menuitem\n label=${t('back-to-key', 'Back to the {domain} key', { domain: agent.owner.name })}\n @select=${() => this.clearKeyOverride(agent)}></ox-popup-menuitem>`\n : nothing}\n `\n : html`\n ${this.draft ? nothing : html`<ox-popup-menuitem label=${t('edit', 'Edit')} @select=${() => this.startEdit(agent)}></ox-popup-menuitem>`}\n <ox-popup-menuitem label=${t('delete', 'Delete')} @select=${() => this.deleteAgent(agent)}></ox-popup-menuitem>\n `,\n top: at.bottom,\n right: window.innerWidth - at.right,\n parent: document.body\n })\n }\n\n private renderKeyOverride(agent: AgentView) {\n return html`\n <div class=\"key-override\">\n <input\n type=\"password\"\n autocomplete=\"new-password\"\n placeholder=${t('key-placeholder', 'API key of this domain')}\n .value=${this.keyDraft}\n @input=${(e: Event) => (this.keyDraft = (e.target as HTMLInputElement).value)} />\n <button type=\"button\" @click=${() => ((this.keyFor = undefined), (this.keyDraft = ''))}>${t('cancel', 'Cancel')}</button>\n <button type=\"button\" class=\"primary\" ?disabled=${!this.keyDraft.trim() || this.saving} @click=${() => this.save({ kind: 'key-override', agentId: agent.id, apiKey: this.keyDraft.trim() })}>\n ${t('save', 'Save')}\n </button>\n </div>\n ${this.saveError ? html`<div class=\"error\">${this.saveError}</div>` : nothing}\n `\n }\n\n private renderEditor() {\n const draft = this.draft!\n const stored = this.settings!.agents.find(one => one.id === draft.id)\n const hasStoredKey = !!stored && stored.keyState === 'own' && draft.provider === stored.provider\n const modelLocked = !draft.apiKey.trim() && !hasStoredKey\n const offered = this.models.state === 'ready' ? this.models.models : []\n const modelGone = this.models.state === 'ready' && !!draft.model && !offered.includes(draft.model)\n const canSave = !!draft.name.trim() && !!draft.model && !modelLocked && !modelGone && this.models.state === 'ready' && !this.saving\n\n return html`\n <form class=\"editor\" @submit=${(e: Event) => (e.preventDefault(), canSave && this.save({ kind: 'upsert', draft }))}>\n <label>\n ${t('name', 'Name')}\n <input .value=${draft.name} @input=${(e: Event) => this.patch({ name: (e.target as HTMLInputElement).value })} />\n </label>\n <label>\n ${t('provider', 'Provider')}\n <select @change=${(e: Event) => this.onProvider((e.target as HTMLSelectElement).value)}>\n ${PROVIDERS.map(one => html`<option value=${one} ?selected=${one === draft.provider}>${providerLabel(one)}</option>`)}\n </select>\n </label>\n <label>\n ${t('api-key', 'API key')}\n <input\n type=\"password\"\n autocomplete=\"new-password\"\n placeholder=${hasStoredKey ? t('key-stored', 'Stored key {hint} - enter only to change it', { hint: stored?.keyHint ?? '' }) : ''}\n .value=${draft.apiKey}\n @input=${(e: Event) => this.patch({ apiKey: (e.target as HTMLInputElement).value })}\n @change=${() => this.loadModels()} />\n </label>\n <label>\n ${t('model', 'Model')}\n <span class=\"with-action\">\n <select ?disabled=${modelLocked || this.models.state !== 'ready'} @change=${(e: Event) => this.patch({ model: (e.target as HTMLSelectElement).value })}>\n ${!draft.model || modelGone ? html`<option value=\"\" selected disabled>${modelGone ? draft.model : t('pick-model', 'Pick a model')}</option>` : nothing}\n ${offered.map(one => html`<option value=${one} ?selected=${one === draft.model}>${one}</option>`)}\n </select>\n <button type=\"button\" aria-label=${t('reload-models', 'Read the models again')} title=${t('reload-models', 'Read the models again')} ?disabled=${modelLocked || this.models.state === 'loading'} @click=${() => this.loadModels()}>\n <md-icon>refresh</md-icon>\n </button>\n </span>\n ${modelLocked\n ? html`<span class=\"hint\">${t('enter-key-first', 'Enter the API key to pick a model.')}</span>`\n : this.models.state === 'loading'\n ? html`<span class=\"hint\">${t('reading-models', 'Reading the provider\\'s models…')}</span>`\n : this.models.state === 'failed'\n ? html`<span class=\"error\">${this.models.reason}</span>`\n : modelGone\n ? html`<span class=\"error\">${t('model-gone', 'The provider no longer offers this model. Pick another.')}</span>`\n : nothing}\n </label>\n <details class=\"advanced\" ?open=${!!(draft.baseURL || draft.organization)}>\n <summary>${t('advanced', 'Advanced')}</summary>\n <div>\n <label>\n ${t('base-url', 'Base URL')}\n <input .value=${draft.baseURL} placeholder=\"https://\" @input=${(e: Event) => this.patch({ baseURL: (e.target as HTMLInputElement).value })} @change=${() => this.loadModels()} />\n </label>\n ${draft.provider === 'openai'\n ? html`<label>\n ${t('organization', 'Organization')}\n <input .value=${draft.organization} @input=${(e: Event) => this.patch({ organization: (e.target as HTMLInputElement).value })} @change=${() => this.loadModels()} />\n </label>`\n : nothing}\n </div>\n </details>\n ${this.saveError ? html`<div class=\"error\" style=\"grid-column: 1 / -1\">${this.saveError}</div>` : nothing}\n <div class=\"actions\">\n <button type=\"button\" @click=${() => this.cancelEdit()}>${t('cancel', 'Cancel')}</button>\n <button type=\"submit\" class=\"primary\" ?disabled=${!canSave}>${t('save', 'Save')}</button>\n </div>\n </form>\n `\n }\n\n private startNew() {\n this.saveError = undefined\n this.draft = draftOf()\n this.models = { state: 'idle', models: [] }\n }\n\n private startEdit(agent: AgentView) {\n this.saveError = undefined\n this.draft = draftOf(agent)\n this.loadModels()\n }\n\n private cancelEdit() {\n this.draft = undefined\n this.saveError = undefined\n this.models = { state: 'idle', models: [] }\n }\n\n private patch(change: Partial<AgentDraft>) {\n this.draft = { ...this.draft!, ...change }\n }\n\n /** A provider decides the model list, so changing it empties the model. */\n private onProvider(provider: string) {\n this.patch({ provider, model: '', organization: provider === 'openai' ? this.draft!.organization : '' })\n this.models = { state: 'idle', models: [] }\n this.loadModels()\n }\n\n private modelsToken = 0\n\n private async loadModels() {\n const draft = this.draft\n if (!draft) return\n const stored = this.settings?.agents.find(one => one.id === draft.id && !one.inherited)\n const useStored = !draft.apiKey.trim() && stored?.keyState === 'own' && stored.provider === draft.provider\n if (!draft.apiKey.trim() && !useStored) {\n this.models = { state: 'idle', models: [] }\n return\n }\n const token = ++this.modelsToken\n this.models = { state: 'loading', models: [] }\n try {\n const response = await client.query({\n query: MODELS_QUERY,\n fetchPolicy: 'network-only',\n variables: {\n provider: draft.provider,\n ...(draft.apiKey.trim() ? { apiKey: draft.apiKey.trim() } : { agentId: draft.id }),\n ...(draft.baseURL.trim() && { baseURL: draft.baseURL.trim() }),\n ...(draft.organization.trim() && { organization: draft.organization.trim() })\n }\n })\n if (token !== this.modelsToken) return\n this.models = { state: 'ready', models: answered(response, 'aiProviderModels') ?? [] }\n } catch (error: any) {\n if (token !== this.modelsToken) return\n this.models = { state: 'failed', models: [], reason: messageOf(error) }\n }\n }\n\n private startKeyOverride(agent: AgentView) {\n this.saveError = undefined\n this.keyDraft = ''\n this.keyFor = agent.id\n }\n\n private async clearKeyOverride(agent: AgentView) {\n const accepted = await confirm(\n t('back-to-key-title', 'Go back to the {domain} key?', { domain: agent.owner.name }),\n t('back-to-key-text', 'This domain\\'s key for \"{name}\" is deleted, and the key of {domain} answers again.', {\n name: agent.name,\n domain: agent.owner.name\n })\n )\n if (accepted) await this.save({ kind: 'key-clear', agentId: agent.id })\n }\n\n /** Turning an agent off reaches every domain below that uses it - they are named before it happens. */\n private async onActive(agent: AgentView, active: boolean) {\n if (!active && agent.usedBelow.length) {\n const accepted = await confirm(\n t('turn-off-title', 'Turn \"{name}\" off?', { name: agent.name }),\n t('turn-off-text', 'It stops answering here and in {domains}.', { domains: agent.usedBelow.map(one => one.name).join(', ') })\n )\n if (!accepted) return this.requestUpdate()\n }\n await this.save({ kind: 'active', agentId: agent.id, active })\n }\n\n private async deleteAgent(agent: AgentView) {\n const below = agent.usedBelow.length\n ? ' ' + t('delete-below', 'It also stops answering in {domains}.', { domains: agent.usedBelow.map(one => one.name).join(', ') })\n : ''\n const accepted = await confirm(\n t('delete-title', 'Delete \"{name}\"?', { name: agent.name }),\n t('delete-text', 'Its API key is deleted with it. Usage already recorded stays.') + below\n )\n if (accepted) await this.save({ kind: 'delete', agentId: agent.id })\n }\n\n private async showUsers(agent: AgentView) {\n await OxPrompt.open({\n type: 'info',\n title: t('used-below-title', 'Domains below using \"{name}\"', { name: agent.name }),\n text: agent.usedBelow.map(one => one.name).join(', '),\n confirmButton: { text: t('close', 'Close') }\n })\n }\n\n private async save(change: SaveChange) {\n this.saving = true\n this.saveError = undefined\n try {\n answered(await client.mutate({ mutation: SAVE_MUTATION, variables: { input: saveInput(this.settings!, change) } }), 'saveAiAgents')\n if (change.kind === 'upsert') this.cancelEdit()\n if (change.kind === 'key-override') ((this.keyFor = undefined), (this.keyDraft = ''))\n await this.load()\n } catch (error: any) {\n this.saveError = messageOf(error)\n if (change.kind !== 'upsert' && change.kind !== 'key-override') {\n await OxPrompt.open({ type: 'error', title: t('save-failed', 'Not saved'), text: this.saveError, confirmButton: { text: t('close', 'Close') } })\n await this.load()\n }\n } finally {\n this.saving = false\n }\n }\n}\n\n/**\n * The data of a query or mutation. This client answers a refusal in `errors` (errorPolicy 'all') instead of\n * throwing, so it is turned into a throw here - the server's sentence, already in the person's language.\n */\nfunction answered(result: any, field: string): any {\n if (result?.errors?.length) throw new Error(result.errors[0].message)\n return result?.data?.[field]\n}\n\nasync function confirm(title: string, text: string): Promise<boolean> {\n return !!(await OxPrompt.open({\n type: 'warning',\n title,\n text,\n confirmButton: { text: t('confirm', 'Confirm') },\n cancelButton: { text: t('cancel', 'Cancel') }\n }))\n}\n\n/** The server's sentence for a refusal - already in the person's language. */\nfunction messageOf(error: any): string {\n return error?.graphQLErrors?.[0]?.message ?? error?.message ?? String(error)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ai-agent-setting-let.js","sourceRoot":"","sources":["../../client/settings/ai-agent-setting-let.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AACnC,OAAO,+DAA+D,CAAA;AAEtE,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACtE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,iCAAiC,CAAA;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAC7D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAIL,OAAO,EACP,YAAY,EACZ,SAAS,EAEV,MAAM,2BAA2B,CAAA;AAElC,MAAM,CAAC,GAAG,CAAC,GAAW,EAAE,YAAoB,EAAE,UAAmC,EAAE,EAAE,EAAE,CACrF,OAAO,CAAC,CAAC,CAAC,sBAAsB,GAAG,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,CAAC,CAAA;AAEtE,MAAM,cAAc,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCzB,CAAA;AAED,MAAM,YAAY,GAAG,GAAG,CAAA;;;;CAIvB,CAAA;AAED,MAAM,aAAa,GAAG,GAAG,CAAA;;;;CAIxB,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAA;AAInD;;;;;;GAMG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC;IAA7D;;QAmLY,aAAQ,GAAG,EAAE,CAAA;QAE9B,iEAAiE;QACzD,WAAM,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC,CAAA;QACnF,cAAS,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC,CAAA;QAC7H,qGAAqG;QAC7F,UAAK,GAAG,IAAI,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAA;IAqXjH,CAAC;aA7iBQ,WAAM,GAAG;QACd;kGAC0F;QAC1F,qBAAqB;QACrB,eAAe;QACf,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAqKF;KACF,AA3KY,CA2KZ;IAeD,IAAY,QAAQ;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAA;IAC1C,CAAC;IAED,IAAY,UAAU;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACrE,CAAC;IAED,IAAY,MAAM;QAChB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;QACzD,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;QACrH,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK;YAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAA;QACzG,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,EAAE,CAAA;IAC/E,CAAC;IAED,IAAY,MAAM;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAA;IAC3B,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;4BAEa,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC;8BACrB,IAAI,CAAC,aAAa,EAAE;;KAE7C,CAAA;IACH,CAAC;IAEO,aAAa;QACnB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO,IAAI,CAAA;;qCAEoB,CAAC,CAAC,aAAa,EAAE,+BAA+B,CAAC,IAAI,IAAI,CAAC,UAAU;yCAChE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC;;OAElH,CAAA;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAA,wBAAwB,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,SAAS,CAAA;QAExF,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC1C,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,YAAY,EAAE;0CACa,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE;kCACnE,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC;;;QAG3C,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,OAAO;QAC5D,MAAM,CAAC,GAAG,CACV,KAAK,CAAC,EAAE,CAAC,IAAI,CAAA;YACT,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,SAAS;YACpC,CAAC,CAAC,IAAI,CAAA;kBACA,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,uBAAuB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,aAAa,CAAC;qBACnH;YACT,CAAC,CAAC,OAAO;YACT,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAA,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,OAAO;YACrH,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;SACxE,CACF;KACF,CAAA;IACH,CAAC;IAEO,YAAY;QAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAS,CAAA;QAC/B,IAAI,QAAQ,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,CAAA;YAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,cAAc,CAAC,CAAA;YAC9E,OAAO,IAAI,CAAA;UACP,CAAC,CAAC,WAAW,EAAE,yDAAyD,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;cAClH,CAAA;QACV,CAAC;QACD,MAAM,GAAG,GACP,QAAQ,CAAC,MAAM,KAAK,cAAc;YAChC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,6CAA6C,CAAC;YACnE,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,iBAAiB;gBACrC,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,+CAA+C,CAAC;gBACtE,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,0CAA0C,CAAC,CAAA;QACxE,OAAO,IAAI,CAAA,4BAA4B,GAAG,SAAS,CAAA;IACrD,CAAC;IAEO,SAAS,CAAC,KAAgB;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAS,CAAA;QAC/B,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,SAAS,CAAA;QACjC,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,MAAM,CAAA;QAC3B,OAAO,IAAI,CAAA;wBACS,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;;;;uBAIrB,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC;kBAC5B,CAAC,CAAC,cAAc,EAAE,4CAA4C,CAAC;qBAC5D,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC,cAAc;sBACnC,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM;oBAC9B,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;mCACxC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI;gBAC3C,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC;oCACT,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK;UACpD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;UACrB,QAAQ;YACR,CAAC,CAAC,IAAI,CAAA;gDACgC,KAAK,CAAC,MAAM,cAAc,IAAI,CAAC,MAAM,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAG,CAAC,CAAC,MAA2B,CAAC,OAAO,CAAC;gBAC3J,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC;qBACV;YACX,CAAC,CAAC,IAAI,CAAA;gDACgC,CAAC,KAAK,CAAC,SAAS,cAAc,IAAI,CAAC,MAAM,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,CAAE,CAAC,CAAC,MAA2B,CAAC,OAAO,EAAE,CAAC;gBACnM,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC;qBACpB;UACX,QAAQ,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM;YAClC,CAAC,CAAC,IAAI,CAAA,6CAA6C,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;gBAClI,CAAC,CAAC,YAAY,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;sBAC7D;YACZ,CAAC,CAAC,IAAI,CAAA,eAAe;UACrB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;;KAE3B,CAAA;IACH,CAAC;IAEO,SAAS,CAAC,KAAgB;QAChC,QAAQ,KAAK,CAAC,QAAQ,EAAE,CAAC;YACvB,KAAK,KAAK;gBACR,OAAO,IAAI,CAAA,qBAAqB,KAAK,CAAC,OAAO,SAAS,CAAA;YACxD,KAAK,YAAY;gBACf,OAAO,IAAI,CAAA,qBAAqB,CAAC,CAAC,iBAAiB,EAAE,2BAA2B,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,SAAS,CAAA;YAC3H,KAAK,WAAW;gBACd,OAAO,IAAI,CAAA,qBAAqB,CAAC,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,SAAS,CAAA;YAC/G;gBACE,OAAO,IAAI,CAAA,6BAA6B,CAAC,CAAC,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAA;QAC/E,CAAC;IACH,CAAC;IAED,2GAA2G;IACnG,UAAU,CAAC,KAAgB;QACjC,OAAO,IAAI,CAAA;;;mBAGI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;cACtB,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;kBACb,IAAI,CAAC,MAAM;eACd,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IACpE,CAAC;IAEO,QAAQ,CAAC,KAAiB,EAAE,KAAgB;QAClD,MAAM,EAAE,GAAI,KAAK,CAAC,aAA6B,CAAC,qBAAqB,EAAE,CAAA;QACvE,WAAW,CAAC,IAAI,CAAC;YACf,QAAQ,EAAE,KAAK,CAAC,SAAS;gBACvB,CAAC,CAAC,IAAI,CAAA;;sBAEQ,KAAK,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,uBAAuB,CAAC;wBAC7H,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;cAC5C,KAAK,CAAC,QAAQ,KAAK,YAAY;oBAC/B,CAAC,CAAC,IAAI,CAAA;0BACM,CAAC,CAAC,aAAa,EAAE,0BAA0B,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;4BACxE,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,uBAAuB;oBACvE,CAAC,CAAC,OAAO;WACZ;gBACH,CAAC,CAAC,IAAI,CAAA;cACA,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA,4BAA4B,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,uBAAuB;uCAC7G,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,YAAY,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;WAC1F;YACL,GAAG,EAAE,EAAE,CAAC,MAAM;YACd,KAAK,EAAE,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC,KAAK;YACnC,MAAM,EAAE,QAAQ,CAAC,IAAI;SACtB,CAAC,CAAA;IACJ,CAAC;IAEO,iBAAiB,CAAC,KAAgB;QACxC,OAAO,IAAI,CAAA;;;;;wBAKS,CAAC,CAAC,iBAAiB,EAAE,wBAAwB,CAAC;mBACnD,IAAI,CAAC,QAAQ;mBACb,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAI,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC;uCAChD,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC;0DAC7D,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACvL,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;;;QAGrB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA,sBAAsB,IAAI,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,OAAO;KAC9E,CAAA;IACH,CAAC;IAEO,YAAY;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAM,CAAA;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAS,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAA;QACrE,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAA;QAChG,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAA;QACzD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;QACvE,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAClG,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAA;QAEnI,OAAO,IAAI,CAAA;qCACsB,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;;YAE5G,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;0BACH,KAAK,CAAC,IAAI,WAAW,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,EAAG,CAAC,CAAC,MAA2B,CAAC,KAAK,EAAE,CAAC;;;YAG3G,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC;4BACT,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAE,CAAC,CAAC,MAA4B,CAAC,KAAK,CAAC;cAClF,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,GAAG,cAAc,GAAG,KAAK,KAAK,CAAC,QAAQ,IAAI,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC;;;;YAIrH,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC;;;;0BAIT,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,6CAA6C,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;qBACxH,KAAK,CAAC,MAAM;qBACZ,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,EAAG,CAAC,CAAC,MAA2B,CAAC,KAAK,EAAE,CAAC;sBACzE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE;;;YAGjC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC;;gCAEC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,OAAO,YAAY,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAG,CAAC,CAAC,MAA4B,CAAC,KAAK,EAAE,CAAC;gBAClJ,CAAC,KAAK,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA,sCAAsC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO;gBACpJ,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,GAAG,cAAc,GAAG,KAAK,KAAK,CAAC,KAAK,IAAI,GAAG,WAAW,CAAC;;+CAEhE,CAAC,CAAC,eAAe,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAC,eAAe,EAAE,uBAAuB,CAAC,cAAc,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE;;;;YAIjO,WAAW;YACX,CAAC,CAAC,IAAI,CAAA,sBAAsB,CAAC,CAAC,iBAAiB,EAAE,oCAAoC,CAAC,SAAS;YAC/F,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS;gBAC/B,CAAC,CAAC,IAAI,CAAA,sBAAsB,CAAC,CAAC,gBAAgB,EAAE,iCAAiC,CAAC,SAAS;gBAC3F,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ;oBAC9B,CAAC,CAAC,IAAI,CAAA,uBAAuB,IAAI,CAAC,MAAM,CAAC,MAAM,SAAS;oBACxD,CAAC,CAAC,SAAS;wBACT,CAAC,CAAC,IAAI,CAAA,uBAAuB,CAAC,CAAC,YAAY,EAAE,yDAAyD,CAAC,SAAS;wBAChH,CAAC,CAAC,OAAO;;0CAEe,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,YAAY,CAAC;qBAC5D,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC;;;gBAG9B,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC;8BACX,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,EAAG,CAAC,CAAC,MAA2B,CAAC,KAAK,EAAE,CAAC,YAAY,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE;;cAE7K,KAAK,CAAC,QAAQ,KAAK,QAAQ;YAC3B,CAAC,CAAC,IAAI,CAAA;oBACA,CAAC,CAAC,cAAc,EAAE,cAAc,CAAC;kCACnB,KAAK,CAAC,YAAY,WAAW,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,YAAY,EAAG,CAAC,CAAC,MAA2B,CAAC,KAAK,EAAE,CAAC,YAAY,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE;yBACzJ;YACX,CAAC,CAAC,OAAO;;;UAGb,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA,kDAAkD,IAAI,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,OAAO;;yCAExE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC;4DAC7B,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;;;KAGpF,CAAA;IACH,CAAC;IAEO,QAAQ;QACd,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,CAAA;QACtB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAEO,SAAS,CAAC,KAAgB;QAChC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;QAC3B,IAAI,CAAC,UAAU,EAAE,CAAA;IACnB,CAAC;IAEO,UAAU;QAChB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAA;QACtB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAEO,KAAK,CAAC,MAA2B;QACvC,IAAI,CAAC,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,KAAM,EAAE,GAAG,MAAM,EAAE,CAAA;IAC5C,CAAC;IAED,2EAA2E;IACnE,UAAU,CAAC,QAAgB;QACjC,IAAI,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACxG,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,UAAU,EAAE,CAAA;IACnB,CAAC;IAEO,UAAU;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACxB,IAAI,CAAC,KAAK;YAAE,OAAM;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACvF,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,EAAE,QAAQ,KAAK,KAAK,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAA;QAC1G,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;YAC1B,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAA2B;YAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAG,EAAE,CAAC;YACnF,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9D,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;SAC9E,CAAA;QACD,kEAAkE;QAClE,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAA;;YAC/E,IAAI,CAAC,SAAS,GAAG,GAAG,CAAA;IAC3B,CAAC;IAEO,gBAAgB,CAAC,KAAgB;QACvC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,EAAE,CAAA;IACxB,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,KAAgB;QAC7C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,CAAC,CAAC,mBAAmB,EAAE,8BAA8B,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EACpF,CAAC,CAAC,kBAAkB,EAAE,oFAAoF,EAAE;YAC1G,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;SACzB,CAAC,CACH,CAAA;QACD,IAAI,QAAQ;YAAE,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;IACzE,CAAC;IAED,uGAAuG;IAC/F,KAAK,CAAC,QAAQ,CAAC,KAAgB,EAAE,MAAe;QACtD,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACtC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,CAAC,CAAC,gBAAgB,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,EAC/D,CAAC,CAAC,eAAe,EAAE,2CAA2C,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAC9H,CAAA;YACD,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC,aAAa,EAAE,CAAA;QAC5C,CAAC;QACD,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;IAChE,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,KAAgB;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM;YAClC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,cAAc,EAAE,uCAAuC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChI,CAAC,CAAC,EAAE,CAAA;QACN,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,CAAC,CAAC,cAAc,EAAE,kBAAkB,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,EAC3D,CAAC,CAAC,aAAa,EAAE,+DAA+D,CAAC,GAAG,KAAK,CAC1F,CAAA;QACD,IAAI,QAAQ;YAAE,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAA;IACtE,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,KAAgB;QACtC,MAAM,QAAQ,CAAC,IAAI,CAAC;YAClB,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,CAAC,CAAC,kBAAkB,EAAE,8BAA8B,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;YAClF,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YACrD,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE;SAC7C,CAAC,CAAA;IACJ,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,MAAkB;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,QAAS,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YACvE,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;gBAAE,IAAI,CAAC,UAAU,EAAE,CAAA;YAC/C,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc;gBAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAA;YACrF,OAAM;QACR,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC5C,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAC/D,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,aAAa,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAA;YAChJ,+DAA+D;YAC/D,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAA;QAC7B,CAAC;IACH,CAAC;;AA/XgB;IAAhB,KAAK,EAAE;;gDAA2B;AAElB;IAAhB,KAAK,EAAE;;oDAA2C;AAClC;IAAhB,KAAK,EAAE;;oDAA2B;AAClB;IAAhB,KAAK,EAAE;;iDAAwB;AACf;IAAhB,KAAK,EAAE;;mDAAsB;AAnLnB,iBAAiB;IAD7B,aAAa,CAAC,sBAAsB,CAAC;GACzB,iBAAiB,CA8iB7B;;AAED,KAAK,UAAU,OAAO,CAAC,KAAa,EAAE,IAAY;IAChD,OAAO,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC;QAC5B,IAAI,EAAE,SAAS;QACf,KAAK;QACL,IAAI;QACJ,aAAa,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE;QAChD,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;KAC9C,CAAC,CAAC,CAAA;AACL,CAAC;AAED,8EAA8E;AAC9E,SAAS,SAAS,CAAC,KAAU;IAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAA;AAC9E,CAAC","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@things-factory/setting-base/dist-client/layout/settinglet.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { MutationController, QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { OxPrompt } from '@operato/popup'\nimport '@operato/popup/ox-popup-menu.js'\nimport { OxPopupMenu } from '@operato/popup/ox-popup-menu.js'\nimport { ButtonContainerStyles, FormFieldStyles } from '@operato/styles'\n\nimport { providerLabel } from '../utils/agent-choice.js'\nimport {\n type AgentDraft,\n type AgentSettings,\n type AgentView,\n draftOf,\n groupByOwner,\n saveInput,\n type SaveChange\n} from './agent-settings-model.js'\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n i18next.t(`ai-assistant.agent.${key}`, { ...options, defaultValue })\n\nconst SETTINGS_QUERY = gql`\n query AiAgentSettings {\n aiAgentSettings {\n chain {\n id\n name\n }\n agents {\n id\n name\n provider\n model\n baseURL\n organization\n active\n owner {\n id\n name\n }\n inherited\n turnedOff\n keyState\n keyDomain {\n id\n name\n }\n keyHint\n usable\n isDefault\n usedBelow {\n id\n name\n }\n }\n defaultAgentId\n defaultFrom\n state\n reason\n }\n }\n`\n\nconst MODELS_QUERY = gql`\n query AiProviderModels($provider: String!, $apiKey: String, $agentId: String, $baseURL: String, $organization: String) {\n aiProviderModels(provider: $provider, apiKey: $apiKey, agentId: $agentId, baseURL: $baseURL, organization: $organization)\n }\n`\n\nconst SAVE_MUTATION = gql`\n mutation SaveAiAgents($input: AiAgentsInput!) {\n saveAiAgents(input: $input)\n }\n`\n\nconst PROVIDERS = ['openai', 'anthropic', 'gemini']\n\ntype ModelList = { state: 'idle' | 'loading' | 'ready' | 'failed'; models: string[]; reason?: string }\n\n/**\n * A domain's AI agents - the card in Settings › {domain} settings (design/ai/agent-settings.md §7-1, §7-2).\n *\n * The first line says whether AI works here and, if not, the one thing that is missing. The list is grouped by the\n * domain that declared each agent: this domain's own, editable, then each domain above, read-only, closest first. A key\n * is written and never shown again; the model is only ever picked from the list the provider gives that key.\n */\n@customElement('ai-agent-setting-let')\nexport class AiAgentSettingLet extends localize(i18next)(LitElement) {\n static styles = [\n /* The button look comes from the action bar's styles, which also restyle select and text inputs - the form\n field rules come after them, so every field in the card has the standard field look. */\n ButtonContainerStyles,\n FormFieldStyles,\n css`\n :host {\n display: block;\n }\n [slot='content'] {\n display: grid;\n gap: 12px;\n text-transform: none;\n }\n .head {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .status {\n flex: 1;\n font-size: 12px;\n color: var(--md-sys-color-on-surface-variant);\n }\n .status.off {\n color: var(--md-sys-color-error);\n }\n .group-title {\n margin: 4px 0 0;\n font-size: 11px;\n font-weight: 600;\n color: var(--md-sys-color-on-surface-variant);\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n padding-bottom: 2px;\n }\n .row {\n display: grid;\n grid-template-columns: 20px minmax(100px, 1.2fr) 70px minmax(120px, 1.4fr) minmax(110px, 1fr) auto auto 28px;\n align-items: center;\n gap: 8px;\n min-height: 32px;\n font-size: 13px;\n }\n .row.muted > :not(.more-menu) {\n opacity: 0.55;\n }\n .name {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .model {\n font-family: var(--md-sys-typescale-mono-font, monospace);\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .key {\n font-size: 12px;\n white-space: nowrap;\n }\n .key.missing {\n color: var(--md-sys-color-error);\n font-weight: 600;\n }\n .use {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n white-space: nowrap;\n }\n .below {\n border: none;\n background: none;\n padding: 0;\n height: auto;\n font-size: 11px;\n font-weight: 400;\n color: var(--md-sys-color-primary);\n cursor: pointer;\n }\n .more-menu {\n border: none;\n background: none;\n height: auto;\n padding: 2px 6px;\n font-size: 14px;\n font-weight: 400;\n color: var(--md-sys-color-on-surface-variant);\n }\n form.editor {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 12px;\n padding: 12px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: var(--md-sys-shape-corner-small);\n background: var(--md-sys-color-surface-container-lowest);\n }\n @media (max-width: 600px) {\n form.editor {\n grid-template-columns: 1fr;\n }\n }\n form.editor label {\n display: grid;\n gap: 4px;\n font-size: 11px;\n color: var(--md-sys-color-on-surface-variant);\n }\n form.editor input,\n form.editor select {\n height: var(--form-element-height-medium, 32px);\n box-sizing: border-box;\n font-size: 13px;\n }\n .with-action {\n display: flex;\n gap: 4px;\n }\n .with-action > select {\n flex: 1;\n min-width: 0;\n }\n .hint {\n font-size: 11px;\n color: var(--md-sys-color-on-surface-variant);\n }\n .error {\n font-size: 11.5px;\n color: var(--md-sys-color-error);\n }\n details.advanced {\n grid-column: 1 / -1;\n font-size: 12px;\n }\n details.advanced[open] > div {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 12px;\n margin-top: 8px;\n }\n .actions {\n grid-column: 1 / -1;\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n }\n button.primary {\n background: var(--md-sys-color-primary);\n color: var(--md-sys-color-on-primary);\n border-color: var(--md-sys-color-primary);\n }\n button.primary md-icon {\n color: inherit;\n }\n .key-override {\n display: flex;\n gap: 8px;\n align-items: center;\n padding: 8px 0 8px 28px;\n }\n .key-override input {\n flex: 1;\n height: var(--form-element-height-medium, 32px);\n box-sizing: border-box;\n }\n `\n ]\n\n @state() private draft?: AgentDraft\n /* The provider, key and address the model list is read for - set when the editor asks, not on every keystroke. */\n @state() private modelsAsk?: Record<string, string>\n @state() private saveError?: string\n @state() private keyFor?: string\n @state() private keyDraft = ''\n\n /* The agents of this domain and the domains above (ADR-0190). */\n private agents = new QueryController(this, SETTINGS_QUERY, { fetchPolicy: 'network-only' })\n private modelList = new QueryController(this, MODELS_QUERY, { variables: () => this.modelsAsk, fetchPolicy: 'network-only' })\n /* A refusal is drawn beside the editor or in a prompt here, so the link does not report it again. */\n private saver = new MutationController(this, SAVE_MUTATION, { refetch: () => [this.agents], showsError: true })\n\n private get settings(): AgentSettings | undefined {\n return this.agents.data?.aiAgentSettings\n }\n\n private get loadFailed(): string | undefined {\n return this.agents.error ? messageOf(this.agents.error) : undefined\n }\n\n private get models(): ModelList {\n if (!this.modelsAsk) return { state: 'idle', models: [] }\n if (this.modelList.loading || !(this.modelList.data || this.modelList.error)) return { state: 'loading', models: [] }\n if (this.modelList.error) return { state: 'failed', models: [], reason: messageOf(this.modelList.error) }\n return { state: 'ready', models: this.modelList.data.aiProviderModels ?? [] }\n }\n\n private get saving() {\n return this.saver.pending\n }\n\n render() {\n return html`\n <setting-let>\n <div slot=\"title\">${t('title', 'AI agents')}</div>\n <div slot=\"content\">${this.renderContent()}</div>\n </setting-let>\n `\n }\n\n private renderContent() {\n if (this.loadFailed) {\n return html`\n <div class=\"head\">\n <span class=\"status off\">${t('load-failed', 'Could not read the AI agents.')} ${this.loadFailed}</span>\n <button type=\"button\" @click=${() => this.agents.refetch()}><md-icon>refresh</md-icon>${t('retry', 'Try again')}</button>\n </div>\n `\n }\n if (!this.settings) return html`<span class=\"status\">${t('loading', 'Reading…')}</span>`\n\n const groups = groupByOwner(this.settings)\n return html`\n <div class=\"head\">\n ${this.renderStatus()}\n <button type=\"button\" ?disabled=${!!this.draft || this.saving} @click=${() => this.startNew()}>\n <md-icon>add</md-icon>${t('add', 'Agent')}\n </button>\n </div>\n ${this.draft && !this.draft.id ? this.renderEditor() : nothing}\n ${groups.map(\n group => html`\n ${groups.length > 1 || group.inherited\n ? html`<div class=\"group-title\">\n ${group.inherited ? t('inherited-from', 'Inherited from {path}', { path: group.path }) : t('this-domain', 'This domain')}\n </div>`\n : nothing}\n ${group.agents.map(agent => html`${this.renderRow(agent)} ${this.draft?.id === agent.id ? this.renderEditor() : nothing}\n ${this.keyFor === agent.id ? this.renderKeyOverride(agent) : nothing}`)}\n `\n )}\n `\n }\n\n private renderStatus() {\n const settings = this.settings!\n if (settings.state === 'configured') {\n const usable = settings.agents.filter(one => one.usable).length\n const chosen = settings.agents.find(one => one.id === settings.defaultAgentId)\n return html`<span class=\"status\">\n ${t('status-on', 'AI is on here · {count} agents to pick · default {name}', { count: usable, name: chosen?.name ?? '' })}\n </span>`\n }\n const why =\n settings.reason === 'no-agent-key'\n ? t('status-no-key', 'No agent has an API key, so AI is off here.')\n : settings.reason === 'no-usable-agent'\n ? t('status-all-off', 'Every agent is turned off, so AI is off here.')\n : t('status-no-agent', 'There is no AI agent, so AI is off here.')\n return html`<span class=\"status off\">${why}</span>`\n }\n\n private renderRow(agent: AgentView) {\n const settings = this.settings!\n const editable = !agent.inherited\n const muted = !agent.usable\n return html`\n <div class=\"row ${muted ? 'muted' : ''}\">\n <input\n type=\"radio\"\n name=\"default\"\n aria-label=${t('default', 'Default')}\n title=${t('default-hint', 'The agent a person gets before picking one')}\n .checked=${agent.id === settings.defaultAgentId}\n ?disabled=${!agent.usable || this.saving}\n @change=${() => this.save({ kind: 'default', agentId: agent.id })} />\n <span class=\"name\" title=${agent.name}>${agent.name}</span>\n <span>${providerLabel(agent.provider)}</span>\n <span class=\"model\" title=${agent.model}>${agent.model}</span>\n ${this.renderKey(agent)}\n ${editable\n ? html`<label class=\"use\">\n <input type=\"checkbox\" .checked=${agent.active} ?disabled=${this.saving} @change=${(e: Event) => this.onActive(agent, (e.target as HTMLInputElement).checked)} />\n ${t('use', 'Use')}\n </label>`\n : html`<label class=\"use\">\n <input type=\"checkbox\" .checked=${!agent.turnedOff} ?disabled=${this.saving} @change=${(e: Event) => this.save({ kind: 'turn-off', agentId: agent.id, off: !(e.target as HTMLInputElement).checked })} />\n ${t('use-here', 'Use here')}\n </label>`}\n ${editable && agent.usedBelow.length\n ? html`<button type=\"button\" class=\"below\" title=${agent.usedBelow.map(one => one.name).join(', ')} @click=${() => this.showUsers(agent)}>\n ${t('used-below', '{count} below', { count: agent.usedBelow.length })}\n </button>`\n : html`<span></span>`}\n ${this.renderMenu(agent)}\n </div>\n `\n }\n\n private renderKey(agent: AgentView) {\n switch (agent.keyState) {\n case 'own':\n return html`<span class=\"key\">${agent.keyHint}</span>`\n case 'overridden':\n return html`<span class=\"key\">${t('key-this-domain', 'This domain\\'s key {hint}', { hint: agent.keyHint ?? '' })}</span>`\n case 'inherited':\n return html`<span class=\"key\">${t('key-of', '{domain} key', { domain: agent.keyDomain?.name ?? '' })}</span>`\n default:\n return html`<span class=\"key missing\">${t('key-missing', 'No key')}</span>`\n }\n }\n\n /** The row's actions in the platform's popup menu - one at a time, closed by a press outside or Escape. */\n private renderMenu(agent: AgentView) {\n return html`<button\n type=\"button\"\n class=\"more-menu\"\n aria-label=${t('more', 'More')}\n title=${t('more', 'More')}\n ?disabled=${this.saving}\n @click=${(e: MouseEvent) => this.openMenu(e, agent)}>⋯</button>`\n }\n\n private openMenu(event: MouseEvent, agent: AgentView) {\n const at = (event.currentTarget as HTMLElement).getBoundingClientRect()\n OxPopupMenu.open({\n template: agent.inherited\n ? html`\n <ox-popup-menuitem\n label=${agent.keyState === 'overridden' ? t('replace-own-key', \"Replace this domain's key\") : t('use-own-key', \"Use this domain's key\")}\n @select=${() => this.startKeyOverride(agent)}></ox-popup-menuitem>\n ${agent.keyState === 'overridden'\n ? html`<ox-popup-menuitem\n label=${t('back-to-key', 'Back to the {domain} key', { domain: agent.owner.name })}\n @select=${() => this.clearKeyOverride(agent)}></ox-popup-menuitem>`\n : nothing}\n `\n : html`\n ${this.draft ? nothing : html`<ox-popup-menuitem label=${t('edit', 'Edit')} @select=${() => this.startEdit(agent)}></ox-popup-menuitem>`}\n <ox-popup-menuitem label=${t('delete', 'Delete')} @select=${() => this.deleteAgent(agent)}></ox-popup-menuitem>\n `,\n top: at.bottom,\n right: window.innerWidth - at.right,\n parent: document.body\n })\n }\n\n private renderKeyOverride(agent: AgentView) {\n return html`\n <div class=\"key-override\">\n <input\n type=\"password\"\n autocomplete=\"new-password\"\n placeholder=${t('key-placeholder', 'API key of this domain')}\n .value=${this.keyDraft}\n @input=${(e: Event) => (this.keyDraft = (e.target as HTMLInputElement).value)} />\n <button type=\"button\" @click=${() => ((this.keyFor = undefined), (this.keyDraft = ''))}>${t('cancel', 'Cancel')}</button>\n <button type=\"button\" class=\"primary\" ?disabled=${!this.keyDraft.trim() || this.saving} @click=${() => this.save({ kind: 'key-override', agentId: agent.id, apiKey: this.keyDraft.trim() })}>\n ${t('save', 'Save')}\n </button>\n </div>\n ${this.saveError ? html`<div class=\"error\">${this.saveError}</div>` : nothing}\n `\n }\n\n private renderEditor() {\n const draft = this.draft!\n const stored = this.settings!.agents.find(one => one.id === draft.id)\n const hasStoredKey = !!stored && stored.keyState === 'own' && draft.provider === stored.provider\n const modelLocked = !draft.apiKey.trim() && !hasStoredKey\n const offered = this.models.state === 'ready' ? this.models.models : []\n const modelGone = this.models.state === 'ready' && !!draft.model && !offered.includes(draft.model)\n const canSave = !!draft.name.trim() && !!draft.model && !modelLocked && !modelGone && this.models.state === 'ready' && !this.saving\n\n return html`\n <form class=\"editor\" @submit=${(e: Event) => (e.preventDefault(), canSave && this.save({ kind: 'upsert', draft }))}>\n <label>\n ${t('name', 'Name')}\n <input .value=${draft.name} @input=${(e: Event) => this.patch({ name: (e.target as HTMLInputElement).value })} />\n </label>\n <label>\n ${t('provider', 'Provider')}\n <select @change=${(e: Event) => this.onProvider((e.target as HTMLSelectElement).value)}>\n ${PROVIDERS.map(one => html`<option value=${one} ?selected=${one === draft.provider}>${providerLabel(one)}</option>`)}\n </select>\n </label>\n <label>\n ${t('api-key', 'API key')}\n <input\n type=\"password\"\n autocomplete=\"new-password\"\n placeholder=${hasStoredKey ? t('key-stored', 'Stored key {hint} - enter only to change it', { hint: stored?.keyHint ?? '' }) : ''}\n .value=${draft.apiKey}\n @input=${(e: Event) => this.patch({ apiKey: (e.target as HTMLInputElement).value })}\n @change=${() => this.loadModels()} />\n </label>\n <label>\n ${t('model', 'Model')}\n <span class=\"with-action\">\n <select ?disabled=${modelLocked || this.models.state !== 'ready'} @change=${(e: Event) => this.patch({ model: (e.target as HTMLSelectElement).value })}>\n ${!draft.model || modelGone ? html`<option value=\"\" selected disabled>${modelGone ? draft.model : t('pick-model', 'Pick a model')}</option>` : nothing}\n ${offered.map(one => html`<option value=${one} ?selected=${one === draft.model}>${one}</option>`)}\n </select>\n <button type=\"button\" aria-label=${t('reload-models', 'Read the models again')} title=${t('reload-models', 'Read the models again')} ?disabled=${modelLocked || this.models.state === 'loading'} @click=${() => this.loadModels()}>\n <md-icon>refresh</md-icon>\n </button>\n </span>\n ${modelLocked\n ? html`<span class=\"hint\">${t('enter-key-first', 'Enter the API key to pick a model.')}</span>`\n : this.models.state === 'loading'\n ? html`<span class=\"hint\">${t('reading-models', 'Reading the provider\\'s models…')}</span>`\n : this.models.state === 'failed'\n ? html`<span class=\"error\">${this.models.reason}</span>`\n : modelGone\n ? html`<span class=\"error\">${t('model-gone', 'The provider no longer offers this model. Pick another.')}</span>`\n : nothing}\n </label>\n <details class=\"advanced\" ?open=${!!(draft.baseURL || draft.organization)}>\n <summary>${t('advanced', 'Advanced')}</summary>\n <div>\n <label>\n ${t('base-url', 'Base URL')}\n <input .value=${draft.baseURL} placeholder=\"https://\" @input=${(e: Event) => this.patch({ baseURL: (e.target as HTMLInputElement).value })} @change=${() => this.loadModels()} />\n </label>\n ${draft.provider === 'openai'\n ? html`<label>\n ${t('organization', 'Organization')}\n <input .value=${draft.organization} @input=${(e: Event) => this.patch({ organization: (e.target as HTMLInputElement).value })} @change=${() => this.loadModels()} />\n </label>`\n : nothing}\n </div>\n </details>\n ${this.saveError ? html`<div class=\"error\" style=\"grid-column: 1 / -1\">${this.saveError}</div>` : nothing}\n <div class=\"actions\">\n <button type=\"button\" @click=${() => this.cancelEdit()}>${t('cancel', 'Cancel')}</button>\n <button type=\"submit\" class=\"primary\" ?disabled=${!canSave}>${t('save', 'Save')}</button>\n </div>\n </form>\n `\n }\n\n private startNew() {\n this.saveError = undefined\n this.draft = draftOf()\n this.modelsAsk = undefined\n }\n\n private startEdit(agent: AgentView) {\n this.saveError = undefined\n this.draft = draftOf(agent)\n this.loadModels()\n }\n\n private cancelEdit() {\n this.draft = undefined\n this.saveError = undefined\n this.modelsAsk = undefined\n }\n\n private patch(change: Partial<AgentDraft>) {\n this.draft = { ...this.draft!, ...change }\n }\n\n /** A provider decides the model list, so changing it empties the model. */\n private onProvider(provider: string) {\n this.patch({ provider, model: '', organization: provider === 'openai' ? this.draft!.organization : '' })\n this.modelsAsk = undefined\n this.loadModels()\n }\n\n private loadModels() {\n const draft = this.draft\n if (!draft) return\n const stored = this.settings?.agents.find(one => one.id === draft.id && !one.inherited)\n const useStored = !draft.apiKey.trim() && stored?.keyState === 'own' && stored.provider === draft.provider\n if (!draft.apiKey.trim() && !useStored) {\n this.modelsAsk = undefined\n return\n }\n const ask: Record<string, string> = {\n provider: draft.provider,\n ...(draft.apiKey.trim() ? { apiKey: draft.apiKey.trim() } : { agentId: draft.id! }),\n ...(draft.baseURL.trim() && { baseURL: draft.baseURL.trim() }),\n ...(draft.organization.trim() && { organization: draft.organization.trim() })\n }\n /* The same ask again (the reload button) reads the list again. */\n if (JSON.stringify(ask) === JSON.stringify(this.modelsAsk)) this.modelList.refetch()\n else this.modelsAsk = ask\n }\n\n private startKeyOverride(agent: AgentView) {\n this.saveError = undefined\n this.keyDraft = ''\n this.keyFor = agent.id\n }\n\n private async clearKeyOverride(agent: AgentView) {\n const accepted = await confirm(\n t('back-to-key-title', 'Go back to the {domain} key?', { domain: agent.owner.name }),\n t('back-to-key-text', 'This domain\\'s key for \"{name}\" is deleted, and the key of {domain} answers again.', {\n name: agent.name,\n domain: agent.owner.name\n })\n )\n if (accepted) await this.save({ kind: 'key-clear', agentId: agent.id })\n }\n\n /** Turning an agent off reaches every domain below that uses it - they are named before it happens. */\n private async onActive(agent: AgentView, active: boolean) {\n if (!active && agent.usedBelow.length) {\n const accepted = await confirm(\n t('turn-off-title', 'Turn \"{name}\" off?', { name: agent.name }),\n t('turn-off-text', 'It stops answering here and in {domains}.', { domains: agent.usedBelow.map(one => one.name).join(', ') })\n )\n if (!accepted) return this.requestUpdate()\n }\n await this.save({ kind: 'active', agentId: agent.id, active })\n }\n\n private async deleteAgent(agent: AgentView) {\n const below = agent.usedBelow.length\n ? ' ' + t('delete-below', 'It also stops answering in {domains}.', { domains: agent.usedBelow.map(one => one.name).join(', ') })\n : ''\n const accepted = await confirm(\n t('delete-title', 'Delete \"{name}\"?', { name: agent.name }),\n t('delete-text', 'Its API key is deleted with it. Usage already recorded stays.') + below\n )\n if (accepted) await this.save({ kind: 'delete', agentId: agent.id })\n }\n\n private async showUsers(agent: AgentView) {\n await OxPrompt.open({\n type: 'info',\n title: t('used-below-title', 'Domains below using \"{name}\"', { name: agent.name }),\n text: agent.usedBelow.map(one => one.name).join(', '),\n confirmButton: { text: t('close', 'Close') }\n })\n }\n\n private async save(change: SaveChange) {\n this.saveError = undefined\n if (await this.saver.run({ input: saveInput(this.settings!, change) })) {\n if (change.kind === 'upsert') this.cancelEdit()\n if (change.kind === 'key-override') ((this.keyFor = undefined), (this.keyDraft = ''))\n return\n }\n this.saveError = messageOf(this.saver.error)\n if (change.kind !== 'upsert' && change.kind !== 'key-override') {\n await OxPrompt.open({ type: 'error', title: t('save-failed', 'Not saved'), text: this.saveError, confirmButton: { text: t('close', 'Close') } })\n /* The switch flipped on screen goes back to what is stored. */\n await this.agents.refetch()\n }\n }\n}\n\nasync function confirm(title: string, text: string): Promise<boolean> {\n return !!(await OxPrompt.open({\n type: 'warning',\n title,\n text,\n confirmButton: { text: t('confirm', 'Confirm') },\n cancelButton: { text: t('cancel', 'Cancel') }\n }))\n}\n\n/** The server's sentence for a refusal - already in the person's language. */\nfunction messageOf(error: any): string {\n return error?.graphQLErrors?.[0]?.message ?? error?.message ?? String(error)\n}\n"]}
|
|
@@ -14,11 +14,10 @@ export declare class AiUsageSettingLet extends AiUsageSettingLet_base {
|
|
|
14
14
|
private includeDescendants;
|
|
15
15
|
private agentFilter;
|
|
16
16
|
private userFilter;
|
|
17
|
-
private
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
private load;
|
|
17
|
+
private range;
|
|
18
|
+
private usage;
|
|
19
|
+
private get rows();
|
|
20
|
+
private get failed();
|
|
22
21
|
render(): import("lit-html").TemplateResult<1>;
|
|
23
22
|
private renderFilters;
|
|
24
23
|
private renderTable;
|
|
@@ -4,7 +4,7 @@ import '@operato/input/ox-input-select-buttons.js';
|
|
|
4
4
|
import gql from 'graphql-tag';
|
|
5
5
|
import { css, html, LitElement, nothing } from 'lit';
|
|
6
6
|
import { customElement, state } from 'lit/decorators.js';
|
|
7
|
-
import {
|
|
7
|
+
import { QueryController } from '@operato/graphql';
|
|
8
8
|
import { i18next, localize } from '@operato/i18n';
|
|
9
9
|
import { FormFieldStyles, ScrollbarStyles } from '@operato/styles';
|
|
10
10
|
import { periodRange, totalsOf } from './usage-model.js';
|
|
@@ -41,7 +41,14 @@ let AiUsageSettingLet = class AiUsageSettingLet extends localize(i18next)(LitEle
|
|
|
41
41
|
this.includeDescendants = false;
|
|
42
42
|
this.agentFilter = '';
|
|
43
43
|
this.userFilter = '';
|
|
44
|
-
|
|
44
|
+
/* The range is fixed when the period is chosen, so it stays the same variables until the next choice. */
|
|
45
|
+
this.range = periodRange(this.period, new Date());
|
|
46
|
+
/* The usage for the chosen period (ADR-0190); the agent and person choices are drawn from it, so they stay while
|
|
47
|
+
another period is read. */
|
|
48
|
+
this.usage = new QueryController(this, USAGE_QUERY, {
|
|
49
|
+
variables: () => ({ ...this.range, bucket: this.bucket, includeDescendants: this.includeDescendants }),
|
|
50
|
+
keepPrevious: true
|
|
51
|
+
});
|
|
45
52
|
}
|
|
46
53
|
static { this.styles = [
|
|
47
54
|
FormFieldStyles,
|
|
@@ -118,33 +125,12 @@ let AiUsageSettingLet = class AiUsageSettingLet extends localize(i18next)(LitEle
|
|
|
118
125
|
}
|
|
119
126
|
`
|
|
120
127
|
]; }
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
this.load();
|
|
128
|
+
get rows() {
|
|
129
|
+
return this.usage.data?.aiUsageSummary ?? undefined;
|
|
124
130
|
}
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
this.rows = undefined;
|
|
129
|
-
const { from, to } = periodRange(this.period, new Date());
|
|
130
|
-
try {
|
|
131
|
-
const response = await client.query({
|
|
132
|
-
query: USAGE_QUERY,
|
|
133
|
-
fetchPolicy: 'network-only',
|
|
134
|
-
variables: { from, to, bucket: this.bucket, includeDescendants: this.includeDescendants }
|
|
135
|
-
});
|
|
136
|
-
if (token !== this.loadToken)
|
|
137
|
-
return;
|
|
138
|
-
/* This client answers a refusal in `errors` (errorPolicy 'all') instead of throwing. */
|
|
139
|
-
if (response.errors?.length)
|
|
140
|
-
throw new Error(response.errors[0].message);
|
|
141
|
-
this.rows = response.data?.aiUsageSummary ?? [];
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
if (token !== this.loadToken)
|
|
145
|
-
return;
|
|
146
|
-
this.failed = error?.graphQLErrors?.[0]?.message ?? error?.message ?? String(error);
|
|
147
|
-
}
|
|
131
|
+
get failed() {
|
|
132
|
+
const error = this.usage.error;
|
|
133
|
+
return error ? (error.graphQLErrors?.[0]?.message ?? error.message ?? String(error)) : undefined;
|
|
148
134
|
}
|
|
149
135
|
render() {
|
|
150
136
|
return html `
|
|
@@ -167,7 +153,7 @@ let AiUsageSettingLet = class AiUsageSettingLet extends localize(i18next)(LitEle
|
|
|
167
153
|
{ display: t('7d', '7 days'), value: '7d' },
|
|
168
154
|
{ display: t('30d', '30 days'), value: '30d' }
|
|
169
155
|
]}
|
|
170
|
-
@change=${(e) => e.detail && ((this.period = e.detail), this.
|
|
156
|
+
@change=${(e) => e.detail && ((this.period = e.detail), (this.range = periodRange(e.detail, new Date())))}></ox-input-select-buttons>
|
|
171
157
|
<ox-input-select-buttons
|
|
172
158
|
.value=${this.bucket}
|
|
173
159
|
.options=${[
|
|
@@ -175,7 +161,7 @@ let AiUsageSettingLet = class AiUsageSettingLet extends localize(i18next)(LitEle
|
|
|
175
161
|
{ display: t('by-day', 'Day'), value: 'day' },
|
|
176
162
|
{ display: t('by-month', 'Month'), value: 'month' }
|
|
177
163
|
]}
|
|
178
|
-
@change=${(e) => e.detail && (
|
|
164
|
+
@change=${(e) => e.detail && (this.bucket = e.detail)}></ox-input-select-buttons>
|
|
179
165
|
<select aria-label=${t('agent', 'Agent')} @change=${(e) => (this.agentFilter = e.target.value)}>
|
|
180
166
|
<option value="">${t('all-agents', 'All agents')}</option>
|
|
181
167
|
${agents.map(([id, name]) => html `<option value=${id} ?selected=${id === this.agentFilter}>${name}</option>`)}
|
|
@@ -185,7 +171,7 @@ let AiUsageSettingLet = class AiUsageSettingLet extends localize(i18next)(LitEle
|
|
|
185
171
|
${users.map(([id, name]) => html `<option value=${id} ?selected=${id === this.userFilter}>${name}</option>`)}
|
|
186
172
|
</select>
|
|
187
173
|
<label>
|
|
188
|
-
<input type="checkbox" .checked=${this.includeDescendants} @change=${(e) => (
|
|
174
|
+
<input type="checkbox" .checked=${this.includeDescendants} @change=${(e) => (this.includeDescendants = e.target.checked)} />
|
|
189
175
|
${t('include-below', 'Domains below')}
|
|
190
176
|
</label>
|
|
191
177
|
</div>
|
|
@@ -263,12 +249,8 @@ __decorate([
|
|
|
263
249
|
], AiUsageSettingLet.prototype, "userFilter", void 0);
|
|
264
250
|
__decorate([
|
|
265
251
|
state(),
|
|
266
|
-
__metadata("design:type",
|
|
267
|
-
], AiUsageSettingLet.prototype, "
|
|
268
|
-
__decorate([
|
|
269
|
-
state(),
|
|
270
|
-
__metadata("design:type", String)
|
|
271
|
-
], AiUsageSettingLet.prototype, "failed", void 0);
|
|
252
|
+
__metadata("design:type", Object)
|
|
253
|
+
], AiUsageSettingLet.prototype, "range", void 0);
|
|
272
254
|
AiUsageSettingLet = __decorate([
|
|
273
255
|
customElement('ai-usage-setting-let')
|
|
274
256
|
], AiUsageSettingLet);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-usage-setting-let.js","sourceRoot":"","sources":["../../client/settings/ai-usage-setting-let.ts"],"names":[],"mappings":"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","sourcesContent":["import '@things-factory/setting-base/dist-client/layout/settinglet.js'\nimport '@operato/input/ox-input-select-buttons.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { FormFieldStyles, ScrollbarStyles } from '@operato/styles'\n\nimport { periodRange, totalsOf, type UsageBucketSize, type UsagePeriod, type UsageRow } from './usage-model.js'\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n i18next.t(`ai-assistant.usage.${key}`, { ...options, defaultValue })\n\nconst USAGE_QUERY = gql`\n query AiUsageSummary($from: DateTimeISO!, $to: DateTimeISO!, $bucket: String!, $includeDescendants: Boolean) {\n aiUsageSummary(from: $from, to: $to, bucket: $bucket, includeDescendants: $includeDescendants) {\n bucket\n agentId\n agentName\n provider\n model\n domainId\n domainName\n userId\n userName\n calls\n inputTokens\n outputTokens\n failures\n }\n }\n`\n\n/**\n * AI usage of this domain - per hour, day or month × agent × person, in the domain's time zone\n * (design/ai/agent-settings.md §7-3). With \"domains below\", what they did with this domain's agents is added as one\n * line per domain; their people are not named here.\n */\n@customElement('ai-usage-setting-let')\nexport class AiUsageSettingLet extends localize(i18next)(LitElement) {\n static styles = [\n FormFieldStyles,\n ScrollbarStyles,\n css`\n :host {\n display: block;\n }\n [slot='content'] {\n display: grid;\n gap: 8px;\n text-transform: none;\n }\n .filters {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 12px;\n }\n .filters select {\n height: var(--form-element-height-small, 26px);\n font-size: 12px;\n }\n .filters label {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n }\n .table {\n max-height: 360px;\n overflow: auto;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n }\n th,\n td {\n padding: 4px 8px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n white-space: nowrap;\n text-align: left;\n }\n th {\n position: sticky;\n top: 0;\n background: var(--md-sys-color-surface-container);\n font-weight: 600;\n color: var(--md-sys-color-on-surface-variant);\n }\n td.number,\n th.number {\n text-align: right;\n font-variant-numeric: tabular-nums;\n }\n td.failed {\n color: var(--md-sys-color-error);\n }\n tr.total td {\n font-weight: 600;\n border-top: 2px solid var(--md-sys-color-outline-variant);\n }\n .below {\n color: var(--md-sys-color-on-surface-variant);\n }\n .state {\n font-size: 12px;\n color: var(--md-sys-color-on-surface-variant);\n }\n .state.failed {\n color: var(--md-sys-color-error);\n }\n `\n ]\n\n @state() private period: UsagePeriod = '7d'\n @state() private bucket: UsageBucketSize = 'day'\n @state() private includeDescendants = false\n @state() private agentFilter = ''\n @state() private userFilter = ''\n @state() private rows?: UsageRow[]\n @state() private failed?: string\n\n connectedCallback() {\n super.connectedCallback()\n this.load()\n }\n\n private loadToken = 0\n\n private async load() {\n const token = ++this.loadToken\n this.failed = undefined\n this.rows = undefined\n const { from, to } = periodRange(this.period, new Date())\n try {\n const response = await client.query({\n query: USAGE_QUERY,\n fetchPolicy: 'network-only',\n variables: { from, to, bucket: this.bucket, includeDescendants: this.includeDescendants }\n })\n if (token !== this.loadToken) return\n /* This client answers a refusal in `errors` (errorPolicy 'all') instead of throwing. */\n if ((response as any).errors?.length) throw new Error((response as any).errors[0].message)\n this.rows = response.data?.aiUsageSummary ?? []\n } catch (error: any) {\n if (token !== this.loadToken) return\n this.failed = error?.graphQLErrors?.[0]?.message ?? error?.message ?? String(error)\n }\n }\n\n render() {\n return html`\n <setting-let>\n <div slot=\"title\">${t('title', 'AI usage')}</div>\n <div slot=\"content\">${this.renderFilters()} ${this.renderTable()}</div>\n </setting-let>\n `\n }\n\n private renderFilters() {\n const rows = this.rows ?? []\n const agents = [...new Map(rows.filter(one => one.agentId).map(one => [one.agentId!, one.agentName ?? t('deleted-agent', '(deleted agent)')])).entries()]\n const users = [...new Map(rows.filter(one => one.userId).map(one => [one.userId!, one.userName ?? one.userId!])).entries()]\n return html`\n <div class=\"filters\">\n <ox-input-select-buttons\n .value=${this.period}\n .options=${[\n { display: t('today', 'Today'), value: 'today' },\n { display: t('7d', '7 days'), value: '7d' },\n { display: t('30d', '30 days'), value: '30d' }\n ]}\n @change=${(e: CustomEvent) => e.detail && ((this.period = e.detail), this.load())}></ox-input-select-buttons>\n <ox-input-select-buttons\n .value=${this.bucket}\n .options=${[\n { display: t('by-hour', 'Hour'), value: 'hour' },\n { display: t('by-day', 'Day'), value: 'day' },\n { display: t('by-month', 'Month'), value: 'month' }\n ]}\n @change=${(e: CustomEvent) => e.detail && ((this.bucket = e.detail), this.load())}></ox-input-select-buttons>\n <select aria-label=${t('agent', 'Agent')} @change=${(e: Event) => (this.agentFilter = (e.target as HTMLSelectElement).value)}>\n <option value=\"\">${t('all-agents', 'All agents')}</option>\n ${agents.map(([id, name]) => html`<option value=${id} ?selected=${id === this.agentFilter}>${name}</option>`)}\n </select>\n <select aria-label=${t('person', 'Person')} @change=${(e: Event) => (this.userFilter = (e.target as HTMLSelectElement).value)}>\n <option value=\"\">${t('all-people', 'Everyone')}</option>\n ${users.map(([id, name]) => html`<option value=${id} ?selected=${id === this.userFilter}>${name}</option>`)}\n </select>\n <label>\n <input type=\"checkbox\" .checked=${this.includeDescendants} @change=${(e: Event) => ((this.includeDescendants = (e.target as HTMLInputElement).checked), this.load())} />\n ${t('include-below', 'Domains below')}\n </label>\n </div>\n `\n }\n\n private renderTable() {\n if (this.failed) return html`<div class=\"state failed\">${t('load-failed', 'Could not read the usage.')} ${this.failed}</div>`\n if (!this.rows) return html`<div class=\"state\">${t('loading', 'Reading…')}</div>`\n\n const rows = this.rows.filter(one => (!this.agentFilter || one.agentId === this.agentFilter) && (!this.userFilter || one.userId === this.userFilter))\n if (!rows.length) return html`<div class=\"state\">${t('empty', 'No AI was used in this period.')}</div>`\n\n const total = totalsOf(rows)\n const number = (value: number) => value.toLocaleString()\n return html`\n <div class=\"table\">\n <table>\n <thead>\n <tr>\n <th>${t('when', 'When')}</th>\n <th>${t('agent', 'Agent')}</th>\n <th>${t('person', 'Person')}</th>\n <th class=\"number\">${t('calls', 'Calls')}</th>\n <th class=\"number\">${t('input-tokens', 'Input tokens')}</th>\n <th class=\"number\">${t('output-tokens', 'Output tokens')}</th>\n <th class=\"number\">${t('failures', 'Failed')}</th>\n </tr>\n </thead>\n <tbody>\n ${rows.map(\n row => html`<tr>\n <td>${row.bucket}</td>\n <td title=${`${row.provider} · ${row.model}`}>${row.agentName ?? t('deleted-agent', '(deleted agent)')}</td>\n <td>\n ${row.userName ??\n (row.userId ? row.userId : nothing)}${!row.userId && row.domainName ? html`<span class=\"below\">(${row.domainName})</span>` : nothing}\n </td>\n <td class=\"number\">${number(row.calls)}</td>\n <td class=\"number\">${number(row.inputTokens)}</td>\n <td class=\"number\">${number(row.outputTokens)}</td>\n <td class=\"number ${row.failures ? 'failed' : ''}\">${number(row.failures)}</td>\n </tr>`\n )}\n <tr class=\"total\">\n <td colspan=\"3\">${t('total', 'Total')}</td>\n <td class=\"number\">${number(total.calls)}</td>\n <td class=\"number\">${number(total.inputTokens)}</td>\n <td class=\"number\">${number(total.outputTokens)}</td>\n <td class=\"number\">${number(total.failures)}</td>\n </tr>\n </tbody>\n </table>\n </div>\n `\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ai-usage-setting-let.js","sourceRoot":"","sources":["../../client/settings/ai-usage-setting-let.ts"],"names":[],"mappings":"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","sourcesContent":["import '@things-factory/setting-base/dist-client/layout/settinglet.js'\nimport '@operato/input/ox-input-select-buttons.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\nimport { QueryController } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { FormFieldStyles, ScrollbarStyles } from '@operato/styles'\n\nimport { periodRange, totalsOf, type UsageBucketSize, type UsagePeriod, type UsageRow } from './usage-model.js'\n\nconst t = (key: string, defaultValue: string, options: Record<string, unknown> = {}) =>\n i18next.t(`ai-assistant.usage.${key}`, { ...options, defaultValue })\n\nconst USAGE_QUERY = gql`\n query AiUsageSummary($from: DateTimeISO!, $to: DateTimeISO!, $bucket: String!, $includeDescendants: Boolean) {\n aiUsageSummary(from: $from, to: $to, bucket: $bucket, includeDescendants: $includeDescendants) {\n bucket\n agentId\n agentName\n provider\n model\n domainId\n domainName\n userId\n userName\n calls\n inputTokens\n outputTokens\n failures\n }\n }\n`\n\n/**\n * AI usage of this domain - per hour, day or month × agent × person, in the domain's time zone\n * (design/ai/agent-settings.md §7-3). With \"domains below\", what they did with this domain's agents is added as one\n * line per domain; their people are not named here.\n */\n@customElement('ai-usage-setting-let')\nexport class AiUsageSettingLet extends localize(i18next)(LitElement) {\n static styles = [\n FormFieldStyles,\n ScrollbarStyles,\n css`\n :host {\n display: block;\n }\n [slot='content'] {\n display: grid;\n gap: 8px;\n text-transform: none;\n }\n .filters {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 12px;\n }\n .filters select {\n height: var(--form-element-height-small, 26px);\n font-size: 12px;\n }\n .filters label {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n }\n .table {\n max-height: 360px;\n overflow: auto;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 12px;\n }\n th,\n td {\n padding: 4px 8px;\n border-bottom: 1px solid var(--md-sys-color-outline-variant);\n white-space: nowrap;\n text-align: left;\n }\n th {\n position: sticky;\n top: 0;\n background: var(--md-sys-color-surface-container);\n font-weight: 600;\n color: var(--md-sys-color-on-surface-variant);\n }\n td.number,\n th.number {\n text-align: right;\n font-variant-numeric: tabular-nums;\n }\n td.failed {\n color: var(--md-sys-color-error);\n }\n tr.total td {\n font-weight: 600;\n border-top: 2px solid var(--md-sys-color-outline-variant);\n }\n .below {\n color: var(--md-sys-color-on-surface-variant);\n }\n .state {\n font-size: 12px;\n color: var(--md-sys-color-on-surface-variant);\n }\n .state.failed {\n color: var(--md-sys-color-error);\n }\n `\n ]\n\n @state() private period: UsagePeriod = '7d'\n @state() private bucket: UsageBucketSize = 'day'\n @state() private includeDescendants = false\n @state() private agentFilter = ''\n @state() private userFilter = ''\n /* The range is fixed when the period is chosen, so it stays the same variables until the next choice. */\n @state() private range = periodRange(this.period, new Date())\n\n /* The usage for the chosen period (ADR-0190); the agent and person choices are drawn from it, so they stay while\n another period is read. */\n private usage = new QueryController(this, USAGE_QUERY, {\n variables: () => ({ ...this.range, bucket: this.bucket, includeDescendants: this.includeDescendants }),\n keepPrevious: true\n })\n\n private get rows(): UsageRow[] | undefined {\n return this.usage.data?.aiUsageSummary ?? undefined\n }\n\n private get failed(): string | undefined {\n const error: any = this.usage.error\n return error ? (error.graphQLErrors?.[0]?.message ?? error.message ?? String(error)) : undefined\n }\n\n render() {\n return html`\n <setting-let>\n <div slot=\"title\">${t('title', 'AI usage')}</div>\n <div slot=\"content\">${this.renderFilters()} ${this.renderTable()}</div>\n </setting-let>\n `\n }\n\n private renderFilters() {\n const rows = this.rows ?? []\n const agents = [...new Map(rows.filter(one => one.agentId).map(one => [one.agentId!, one.agentName ?? t('deleted-agent', '(deleted agent)')])).entries()]\n const users = [...new Map(rows.filter(one => one.userId).map(one => [one.userId!, one.userName ?? one.userId!])).entries()]\n return html`\n <div class=\"filters\">\n <ox-input-select-buttons\n .value=${this.period}\n .options=${[\n { display: t('today', 'Today'), value: 'today' },\n { display: t('7d', '7 days'), value: '7d' },\n { display: t('30d', '30 days'), value: '30d' }\n ]}\n @change=${(e: CustomEvent) => e.detail && ((this.period = e.detail), (this.range = periodRange(e.detail, new Date())))}></ox-input-select-buttons>\n <ox-input-select-buttons\n .value=${this.bucket}\n .options=${[\n { display: t('by-hour', 'Hour'), value: 'hour' },\n { display: t('by-day', 'Day'), value: 'day' },\n { display: t('by-month', 'Month'), value: 'month' }\n ]}\n @change=${(e: CustomEvent) => e.detail && (this.bucket = e.detail)}></ox-input-select-buttons>\n <select aria-label=${t('agent', 'Agent')} @change=${(e: Event) => (this.agentFilter = (e.target as HTMLSelectElement).value)}>\n <option value=\"\">${t('all-agents', 'All agents')}</option>\n ${agents.map(([id, name]) => html`<option value=${id} ?selected=${id === this.agentFilter}>${name}</option>`)}\n </select>\n <select aria-label=${t('person', 'Person')} @change=${(e: Event) => (this.userFilter = (e.target as HTMLSelectElement).value)}>\n <option value=\"\">${t('all-people', 'Everyone')}</option>\n ${users.map(([id, name]) => html`<option value=${id} ?selected=${id === this.userFilter}>${name}</option>`)}\n </select>\n <label>\n <input type=\"checkbox\" .checked=${this.includeDescendants} @change=${(e: Event) => (this.includeDescendants = (e.target as HTMLInputElement).checked)} />\n ${t('include-below', 'Domains below')}\n </label>\n </div>\n `\n }\n\n private renderTable() {\n if (this.failed) return html`<div class=\"state failed\">${t('load-failed', 'Could not read the usage.')} ${this.failed}</div>`\n if (!this.rows) return html`<div class=\"state\">${t('loading', 'Reading…')}</div>`\n\n const rows = this.rows.filter(one => (!this.agentFilter || one.agentId === this.agentFilter) && (!this.userFilter || one.userId === this.userFilter))\n if (!rows.length) return html`<div class=\"state\">${t('empty', 'No AI was used in this period.')}</div>`\n\n const total = totalsOf(rows)\n const number = (value: number) => value.toLocaleString()\n return html`\n <div class=\"table\">\n <table>\n <thead>\n <tr>\n <th>${t('when', 'When')}</th>\n <th>${t('agent', 'Agent')}</th>\n <th>${t('person', 'Person')}</th>\n <th class=\"number\">${t('calls', 'Calls')}</th>\n <th class=\"number\">${t('input-tokens', 'Input tokens')}</th>\n <th class=\"number\">${t('output-tokens', 'Output tokens')}</th>\n <th class=\"number\">${t('failures', 'Failed')}</th>\n </tr>\n </thead>\n <tbody>\n ${rows.map(\n row => html`<tr>\n <td>${row.bucket}</td>\n <td title=${`${row.provider} · ${row.model}`}>${row.agentName ?? t('deleted-agent', '(deleted agent)')}</td>\n <td>\n ${row.userName ??\n (row.userId ? row.userId : nothing)}${!row.userId && row.domainName ? html`<span class=\"below\">(${row.domainName})</span>` : nothing}\n </td>\n <td class=\"number\">${number(row.calls)}</td>\n <td class=\"number\">${number(row.inputTokens)}</td>\n <td class=\"number\">${number(row.outputTokens)}</td>\n <td class=\"number ${row.failures ? 'failed' : ''}\">${number(row.failures)}</td>\n </tr>`\n )}\n <tr class=\"total\">\n <td colspan=\"3\">${t('total', 'Total')}</td>\n <td class=\"number\">${number(total.calls)}</td>\n <td class=\"number\">${number(total.inputTokens)}</td>\n <td class=\"number\">${number(total.outputTokens)}</td>\n <td class=\"number\">${number(total.failures)}</td>\n </tr>\n </tbody>\n </table>\n </div>\n `\n }\n}\n"]}
|