llm: drop model/agent scope matching; add instance-wide compaction model picker
Nightly Build / build (push) Successful in 6m50s
Nightly Build / build (push) Successful in 6m50s
Remove the scope system end-to-end (llm_models.scope column, agent meta scope field, scope-based tier in model selection, UI checkboxes/pills): it was only a soft ranking hint, had drifted (6 UI scopes vs 3 used by agents, 'general' not even selectable) and duplicated what strength already decides. Strength stays the single AUTO-selection axis. Compaction: the summary model is now pickable from the Settings page via a new PropertyType::LlmModel config property (registry key compaction_model), instance-wide and live (no restart). Fallback chain: explicit pick -> compaction.strength from config.yml -> priority order; a deleted configured model degrades to AUTO. ContextCompactor reads the key at compact time through GlobalConfigManager.
This commit is contained in:
@@ -111,10 +111,6 @@ export class AgentsPage extends LightElement {
|
||||
`;
|
||||
}
|
||||
|
||||
_scopePill(scope) {
|
||||
return html`<span class="agent-scope-pill">${scope}</span>`;
|
||||
}
|
||||
|
||||
// ── List view ─────────────────────────────────────────────────────────────
|
||||
|
||||
_renderCard(agent) {
|
||||
@@ -137,7 +133,6 @@ export class AgentsPage extends LightElement {
|
||||
<span>${this._strengthLabel(agent.strength)}</span>
|
||||
</span>
|
||||
` : ''}
|
||||
${agent.scope ? html`${this._scopePill(agent.scope)}` : ''}
|
||||
${agent.client ? html`
|
||||
<span class="agent-meta-item text-muted" style="font-size:0.75rem">
|
||||
<i class="bi bi-pin-fill me-1" style="font-size:0.65rem"></i>${agent.client}
|
||||
@@ -189,9 +184,6 @@ export class AgentsPage extends LightElement {
|
||||
${m.is_default ? html`<span class="badge bg-primary ms-1" style="font-size:0.6rem">${t('agents.detail.default')}</span>` : ''}
|
||||
</td>
|
||||
<td class="text-muted agent-model-id">${m.model_id}</td>
|
||||
<td>
|
||||
${(m.scope ?? []).map(s => this._scopePill(s))}
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
@@ -235,9 +227,6 @@ export class AgentsPage extends LightElement {
|
||||
</td>
|
||||
</tr>
|
||||
` : ''}
|
||||
${meta.scope ? html`
|
||||
<tr><td class="agent-meta-key">${t('agents.detail.scope')}</td><td>${this._scopePill(meta.scope)}</td></tr>
|
||||
` : ''}
|
||||
${meta.client ? html`
|
||||
<tr><td class="agent-meta-key">${t('agents.detail.pinned_model')}</td><td><code>${meta.client}</code></td></tr>
|
||||
` : ''}
|
||||
@@ -266,7 +255,6 @@ export class AgentsPage extends LightElement {
|
||||
<th>${t('agents.table.strength')}</th>
|
||||
<th>${t('agents.table.name')}</th>
|
||||
<th>${t('agents.table.model_id')}</th>
|
||||
<th>${t('agents.table.scope')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
@@ -11,6 +11,7 @@ function _configSetSlug(name) {
|
||||
const slugs = {
|
||||
'Interface': 'interface',
|
||||
'TIC Agent': 'tic_agent',
|
||||
'Compaction': 'compaction',
|
||||
};
|
||||
return slugs[name] ?? null;
|
||||
}
|
||||
@@ -193,6 +194,20 @@ export class ConfigPage extends LightElement {
|
||||
</select>`;
|
||||
}
|
||||
|
||||
if (prop.property_type === 'llm_model') {
|
||||
// Configured LLM models, by name. Nullable: the empty choice means
|
||||
// "auto-select" (the backend's own resolution order applies).
|
||||
const models = prop.options ?? [];
|
||||
return html`
|
||||
<select class="form-select form-select-sm config-input"
|
||||
.value=${val}
|
||||
@change=${e => this._setValue(prop.key, e.target.value)}>
|
||||
<option value="">— ${t('config.llm_model.auto')} —</option>
|
||||
${models.map(m => html`
|
||||
<option value=${m.id} ?selected=${val === m.id}>${m.name}</option>`)}
|
||||
</select>`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<input type="text"
|
||||
class="form-control form-control-sm config-input"
|
||||
|
||||
@@ -20,12 +20,11 @@ const STRENGTH_LABELS = {
|
||||
};
|
||||
|
||||
const STRENGTH_OPTIONS = ['very_low', 'low', 'average', 'high', 'very_high'];
|
||||
const SCOPE_OPTIONS = ['coding', 'writing', 'reasoning', 'math', 'basic', 'search'];
|
||||
|
||||
function emptyMeta() {
|
||||
// `reasoning` is the selected reasoning value: a string for a ValueSet mode,
|
||||
// a number for a Range mode, or null (off). Interpreted per provider.
|
||||
return { strength: '', scope: [], priority: 100, is_default: false, reasoning: null };
|
||||
return { strength: '', priority: 100, is_default: false, reasoning: null };
|
||||
}
|
||||
|
||||
function emptyOrForm() {
|
||||
@@ -139,7 +138,6 @@ export class ModelsLlmSection extends LightElement {
|
||||
model_id: m.model_id,
|
||||
name: m.name,
|
||||
strength: m.strength ?? null,
|
||||
scope: m.scope,
|
||||
is_default: m.is_default,
|
||||
priority: (i + 1) * 10,
|
||||
extra_params: m.extra_params ?? null,
|
||||
@@ -208,7 +206,6 @@ export class ModelsLlmSection extends LightElement {
|
||||
const record = await res.json();
|
||||
this._form = {
|
||||
strength: record.strength ?? '',
|
||||
scope: record.scope ?? [],
|
||||
priority: record.priority,
|
||||
is_default: record.is_default,
|
||||
provider_id: record.provider_id,
|
||||
@@ -269,7 +266,6 @@ export class ModelsLlmSection extends LightElement {
|
||||
model_id: f.model_id,
|
||||
name: f.name || f.model_id,
|
||||
strength: f.strength || null,
|
||||
scope: f.scope,
|
||||
is_default: f.is_default,
|
||||
priority: Number(f.priority),
|
||||
extra_params,
|
||||
@@ -310,7 +306,6 @@ export class ModelsLlmSection extends LightElement {
|
||||
model_id: f.model_id,
|
||||
name: f.name || f.model_id,
|
||||
strength: f.strength || null,
|
||||
scope: f.scope,
|
||||
is_default: f.is_default,
|
||||
priority: Number(f.priority),
|
||||
extra_params: Object.keys(extra_params).length ? extra_params : null,
|
||||
@@ -355,7 +350,6 @@ export class ModelsLlmSection extends LightElement {
|
||||
model_id: f.model_id,
|
||||
name: f.name,
|
||||
strength: f.strength || null,
|
||||
scope: f.scope,
|
||||
is_default: f.is_default,
|
||||
priority: Number(f.priority),
|
||||
extra_params,
|
||||
@@ -399,16 +393,6 @@ export class ModelsLlmSection extends LightElement {
|
||||
this._orForm = { ...this._orForm, [field]: value };
|
||||
}
|
||||
|
||||
_toggleScope(scope, isOr = false) {
|
||||
if (isOr) {
|
||||
const s = this._orForm.scope;
|
||||
this._orForm = { ...this._orForm, scope: s.includes(scope) ? s.filter(x => x !== scope) : [...s, scope] };
|
||||
} else {
|
||||
const s = this._form.scope;
|
||||
this._form = { ...this._form, scope: s.includes(scope) ? s.filter(x => x !== scope) : [...s, scope] };
|
||||
}
|
||||
}
|
||||
|
||||
_closeModal() { this._modal = null; this._error = null; }
|
||||
|
||||
// ── Render helpers ───────────────────────────────────────────────────────────
|
||||
@@ -487,10 +471,9 @@ export class ModelsLlmSection extends LightElement {
|
||||
${this._renderPriceCell(m)}
|
||||
</div>
|
||||
|
||||
${(m.scope ?? []).length > 0 || m.extra_params ? html`
|
||||
${m.extra_params ? html`
|
||||
<div class="llm-card-row3">
|
||||
${(m.scope ?? []).map(s => html`<span class="llm-scope-pill">${s}</span>`)}
|
||||
${m.extra_params ? html`<span class="llm-scope-pill llm-params-pill" title=${JSON.stringify(m.extra_params)}>+${t('models.extra_params').toLowerCase()}</span>` : ''}
|
||||
<span class="llm-scope-pill llm-params-pill" title=${JSON.stringify(m.extra_params)}>+${t('models.extra_params').toLowerCase()}</span>
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
@@ -540,7 +523,7 @@ export class ModelsLlmSection extends LightElement {
|
||||
</div>`;
|
||||
}
|
||||
|
||||
_renderMetaFields(form, setField, toggleScope, reasoningMode) {
|
||||
_renderMetaFields(form, setField, reasoningMode) {
|
||||
return html`
|
||||
${this._renderReasoning(form, setField, reasoningMode)}
|
||||
<div class="row g-3 mb-3">
|
||||
@@ -561,19 +544,6 @@ export class ModelsLlmSection extends LightElement {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-semibold" style="font-size:0.82rem">${t('models.scope')}</label>
|
||||
<div class="llm-scope-grid">
|
||||
${SCOPE_OPTIONS.map(s => html`
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="scope-${s}"
|
||||
.checked=${form.scope.includes(s)} @change=${() => toggleScope(s)} />
|
||||
<label class="form-check-label" for="scope-${s}" style="font-size:0.82rem">${s}</label>
|
||||
</div>
|
||||
`)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="m-is-default"
|
||||
@@ -644,7 +614,7 @@ export class ModelsLlmSection extends LightElement {
|
||||
@input=${(e) => this._setField('extra_params', e.target.value)}
|
||||
style="font-size:0.78rem;resize:vertical"></textarea>
|
||||
</div>
|
||||
${this._renderMetaFields(f, (k, v) => this._setField(k, v), (s) => this._toggleScope(s), this._reasoningMode)}
|
||||
${this._renderMetaFields(f, (k, v) => this._setField(k, v), this._reasoningMode)}
|
||||
<div class="agent-dialog-actions">
|
||||
<button type="button" class="btn btn-sm btn-secondary" @click=${() => this._closeModal()}>${t('models.cancel')}</button>
|
||||
<button type="submit" class="btn btn-sm btn-primary" ?disabled=${this._saving}>
|
||||
@@ -738,7 +708,7 @@ export class ModelsLlmSection extends LightElement {
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
${this._renderMetaFields(f, (k, v) => this._setOrField(k, v), (s) => this._toggleScope(s, true), selected?.reasoning)}
|
||||
${this._renderMetaFields(f, (k, v) => this._setOrField(k, v), selected?.reasoning)}
|
||||
|
||||
<div class="agent-dialog-actions">
|
||||
<button type="button" class="btn btn-sm btn-secondary" @click=${() => this._closeModal()}>${t('models.cancel')}</button>
|
||||
@@ -776,7 +746,7 @@ export class ModelsLlmSection extends LightElement {
|
||||
@input=${(e) => this._setField('name', e.target.value)} />
|
||||
<div class="form-text" style="font-size:0.75rem">${unsafeHTML(t('models.name_help'))}</div>
|
||||
</div>
|
||||
${this._renderMetaFields(f, (k, v) => this._setField(k, v), (s) => this._toggleScope(s), this._modal.reasoning_mode)}
|
||||
${this._renderMetaFields(f, (k, v) => this._setField(k, v), this._modal.reasoning_mode)}
|
||||
<div class="agent-dialog-actions">
|
||||
<button type="button" class="btn btn-sm btn-secondary" @click=${() => this._closeModal()}>${t('models.cancel')}</button>
|
||||
<button type="submit" class="btn btn-sm btn-primary" ?disabled=${this._saving}>
|
||||
|
||||
@@ -145,16 +145,6 @@ agents-page {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.agent-scope-pill {
|
||||
display: inline-block;
|
||||
font-size: 0.7rem;
|
||||
padding: 0.1rem 0.45rem;
|
||||
border-radius: 999px;
|
||||
background: var(--bs-secondary-bg);
|
||||
color: var(--bs-secondary-color);
|
||||
border: 1px solid var(--bs-border-color);
|
||||
}
|
||||
|
||||
/* ── Detail view ─────────────────────────────────────────────────────────── */
|
||||
|
||||
.agent-detail {
|
||||
|
||||
@@ -356,14 +356,6 @@
|
||||
max-width: 680px;
|
||||
}
|
||||
|
||||
/* ── Scope checkbox grid ── */
|
||||
|
||||
.llm-scope-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.35rem 1rem;
|
||||
}
|
||||
|
||||
/* ── Provider picker grid ── */
|
||||
|
||||
.llm-provider-grid {
|
||||
|
||||
+5
-3
@@ -177,11 +177,14 @@ export default {
|
||||
'config.error_save':'Error saving "{name}": {msg}',
|
||||
'config.enabled': 'Enabled',
|
||||
'config.disabled': 'Disabled',
|
||||
'config.llm_model.auto': 'auto',
|
||||
|
||||
'config.set.interface.name': 'Interface',
|
||||
'config.set.interface.desc': 'Look and feel of the web interface.',
|
||||
'config.set.tic_agent.name': 'TIC Agent',
|
||||
'config.set.tic_agent.desc': 'TIC is a background agent that monitors all async events generated by connected MCP servers (new emails, calendar updates, WhatsApp messages, etc.). It reads your notification rules from data/notifications.md and your memory to decide — via an LLM call — which events are worth surfacing. Relevant notifications are forwarded to the home agent set via /sethome.',
|
||||
'config.set.compaction.name': 'Compaction',
|
||||
'config.set.compaction.desc': 'When a conversation grows too large, older messages are summarised by an LLM to keep the context within limits.',
|
||||
|
||||
'config.prop.ui_locale.name': 'Language',
|
||||
'config.prop.ui_locale.desc': 'Default interface language for the whole instance. Each user can override it on their profile.',
|
||||
@@ -191,6 +194,8 @@ export default {
|
||||
'config.prop.tic__security_group.desc': 'Tool permission group applied to each TIC agent session. Leave empty to use the default group.',
|
||||
'config.prop.tic__interval_minutes.name': 'Check Interval (minutes)',
|
||||
'config.prop.tic__interval_minutes.desc': 'How often TIC runs, in minutes. Leave empty to use the value from config.yml (tic.interval_secs).',
|
||||
'config.prop.compaction_model.name': 'Compaction model',
|
||||
'config.prop.compaction_model.desc': 'Model used to summarise compacted conversations, for the whole instance. A cheap model is usually enough. Leave empty for automatic selection.',
|
||||
|
||||
// ── Projects ────────────────────────────────────────────────────────────────
|
||||
'projects.title': 'Projects',
|
||||
@@ -444,7 +449,6 @@ export default {
|
||||
'models.reasoning.thinking': 'Reasoning (thinking)',
|
||||
'models.strength': 'Strength',
|
||||
'models.priority': 'Priority',
|
||||
'models.scope': 'Scope',
|
||||
'models.default_model': 'Default model',
|
||||
'models.extra_params': 'Extra params',
|
||||
'models.extra_params_hint': '(JSON, optional)',
|
||||
@@ -743,7 +747,6 @@ export default {
|
||||
'agents.detail.meta': 'Metadata',
|
||||
'agents.detail.id': 'ID',
|
||||
'agents.detail.strength': 'Strength',
|
||||
'agents.detail.scope': 'Scope',
|
||||
'agents.detail.pinned_model': 'Pinned model',
|
||||
'agents.detail.memory_files': 'Memory files',
|
||||
'agents.detail.model_order': 'Model resolution order',
|
||||
@@ -756,7 +759,6 @@ export default {
|
||||
'agents.table.strength': 'Strength',
|
||||
'agents.table.name': 'Name',
|
||||
'agents.table.model_id': 'Model ID',
|
||||
'agents.table.scope': 'Scope',
|
||||
|
||||
'agents.banner.title': '<strong>Read-only view.</strong> Agents are defined by files in <code>agents/</code> — to add, remove, or modify an agent, edit the corresponding <code>AGENT.md</code> file in that directory.',
|
||||
'agents.banner.text': 'You can also ask <strong>Copilot</strong> (top bar) to create a new agent for you — just describe what it should do and it will set up all the files automatically.',
|
||||
|
||||
+5
-3
@@ -177,11 +177,14 @@ export default {
|
||||
'config.error_save':'Erreur lors de l\'enregistrement de "{name}" : {msg}',
|
||||
'config.enabled': 'Activé',
|
||||
'config.disabled': 'Désactivé',
|
||||
'config.llm_model.auto': 'auto',
|
||||
|
||||
'config.set.interface.name': 'Interface',
|
||||
'config.set.interface.desc': 'Aspect et style de l\'interface web.',
|
||||
'config.set.tic_agent.name': 'Agent TIC',
|
||||
'config.set.tic_agent.desc': 'TIC est un agent d\'arrière-plan qui surveille tous les événements asynchrones générés par les serveurs MCP connectés (nouveaux e-mails, mises à jour du calendrier, messages WhatsApp, etc.). Il lit vos règles de notification dans data/notifications.md et votre mémoire pour décider — via un appel LLM — quels événements méritent d\'être signalés. Les notifications pertinentes sont transmises à l\'agent d\'accueil défini via /sethome.',
|
||||
'config.set.compaction.name': 'Compaction',
|
||||
'config.set.compaction.desc': 'Lorsqu\'une conversation devient trop longue, les messages les plus anciens sont résumés par un LLM pour garder le contexte dans les limites.',
|
||||
|
||||
'config.prop.ui_locale.name': 'Langue',
|
||||
'config.prop.ui_locale.desc': 'Langue d\'interface par défaut pour l\'ensemble de l\'instance. Chaque utilisateur peut la modifier dans son profil.',
|
||||
@@ -191,6 +194,8 @@ export default {
|
||||
'config.prop.tic__security_group.desc': 'Groupe de permissions d\'outils appliqué à chaque session de l\'agent TIC. Laissez vide pour utiliser le groupe par défaut.',
|
||||
'config.prop.tic__interval_minutes.name': 'Intervalle de vérification (minutes)',
|
||||
'config.prop.tic__interval_minutes.desc': 'Fréquence d\'exécution de TIC, en minutes. Laissez vide pour utiliser la valeur de config.yml (tic.interval_secs).',
|
||||
'config.prop.compaction_model.name': 'Modèle de compaction',
|
||||
'config.prop.compaction_model.desc': 'Modèle utilisé pour résumer les conversations compactées, pour toute l\'instance. Un modèle économique suffit généralement. Laissez vide pour une sélection automatique.',
|
||||
|
||||
// ── Projects ────────────────────────────────────────────────────────────────
|
||||
'projects.title': 'Projets',
|
||||
@@ -444,7 +449,6 @@ export default {
|
||||
'models.reasoning.thinking': 'Raisonnement (réflexion)',
|
||||
'models.strength': 'Puissance',
|
||||
'models.priority': 'Priorité',
|
||||
'models.scope': 'Portée',
|
||||
'models.default_model': 'Modèle par défaut',
|
||||
'models.extra_params': 'Paramètres supplémentaires',
|
||||
'models.extra_params_hint': '(JSON, facultatif)',
|
||||
@@ -743,7 +747,6 @@ export default {
|
||||
'agents.detail.meta': 'Métadonnées',
|
||||
'agents.detail.id': 'ID',
|
||||
'agents.detail.strength': 'Puissance',
|
||||
'agents.detail.scope': 'Portée',
|
||||
'agents.detail.pinned_model': 'Modèle épinglé',
|
||||
'agents.detail.memory_files': 'Fichiers mémoire',
|
||||
'agents.detail.model_order': 'Ordre de résolution des modèles',
|
||||
@@ -756,7 +759,6 @@ export default {
|
||||
'agents.table.strength': 'Puissance',
|
||||
'agents.table.name': 'Nom',
|
||||
'agents.table.model_id': 'ID du modèle',
|
||||
'agents.table.scope': 'Portée',
|
||||
|
||||
'agents.banner.title': '<strong>Vue en lecture seule.</strong> Les agents sont définis par des fichiers dans <code>agents/</code> — pour ajouter, supprimer ou modifier un agent, modifiez le fichier <code>AGENT.md</code> correspondant dans ce répertoire.',
|
||||
'agents.banner.text': 'Vous pouvez aussi demander au <strong>Copilot</strong> (barre supérieure) de créer un nouvel agent pour vous — décrivez simplement ce qu\'il doit faire et il configurera tous les fichiers automatiquement.',
|
||||
|
||||
+5
-3
@@ -201,11 +201,14 @@ export default {
|
||||
'config.error_save':'Errore durante il salvataggio di "{name}": {msg}',
|
||||
'config.enabled': 'Attivato',
|
||||
'config.disabled': 'Disattivato',
|
||||
'config.llm_model.auto': 'automatico',
|
||||
|
||||
'config.set.interface.name': 'Interfaccia',
|
||||
'config.set.interface.desc': 'Aspetto e stile dell\'interfaccia web.',
|
||||
'config.set.tic_agent.name': 'Agente TIC',
|
||||
'config.set.tic_agent.desc': 'TIC è un agente in background che monitora tutti gli eventi asincroni generati dai server MCP connessi (nuove email, aggiornamenti del calendario, messaggi WhatsApp, ecc.). Legge le regole di notifica da data/notifications.md e la memoria per decidere — tramite una chiamata LLM — quali eventi vale la pena segnalare. Le notifiche rilevanti vengono inoltrate all\'agente predefinito impostato tramite /sethome.',
|
||||
'config.set.compaction.name': 'Compattazione',
|
||||
'config.set.compaction.desc': 'Quando una conversazione diventa troppo lunga, i messaggi più vecchi vengono riassunti da un LLM per mantenere il contesto entro i limiti.',
|
||||
|
||||
'config.prop.ui_locale.name': 'Lingua',
|
||||
'config.prop.ui_locale.desc': 'Lingua predefinita per l\'intera istanza. Ogni utente può modificarla nel proprio profilo.',
|
||||
@@ -215,6 +218,8 @@ export default {
|
||||
'config.prop.tic__security_group.desc': 'Gruppo di permessi strumenti applicato a ogni sessione dell\'agente TIC. Lascia vuoto per usare il gruppo predefinito.',
|
||||
'config.prop.tic__interval_minutes.name': 'Intervallo di controllo (minuti)',
|
||||
'config.prop.tic__interval_minutes.desc': 'Ogni quanto TIC viene eseguito, in minuti. Lascia vuoto per usare il valore da config.yml (tic.interval_secs).',
|
||||
'config.prop.compaction_model.name': 'Modello per la compattazione',
|
||||
'config.prop.compaction_model.desc': 'Modello usato per riassumere le conversazioni compattate, per tutta l\'istanza. Un modello economico di solito è sufficiente. Lascia vuoto per la selezione automatica.',
|
||||
|
||||
// ── Projects ────────────────────────────────────────────────────────────────
|
||||
'projects.title': 'Progetti',
|
||||
@@ -444,7 +449,6 @@ export default {
|
||||
'models.reasoning.thinking': 'Ragionamento (thinking)',
|
||||
'models.strength': 'Forza',
|
||||
'models.priority': 'Priorità',
|
||||
'models.scope': 'Ambito',
|
||||
'models.default_model': 'Modello predefinito',
|
||||
'models.extra_params': 'Parametri extra',
|
||||
'models.extra_params_hint': '(JSON, opzionale)',
|
||||
@@ -743,7 +747,6 @@ export default {
|
||||
'agents.detail.meta': 'Metadati',
|
||||
'agents.detail.id': 'ID',
|
||||
'agents.detail.strength': 'Forza',
|
||||
'agents.detail.scope': 'Ambito',
|
||||
'agents.detail.pinned_model': 'Modello fissato',
|
||||
'agents.detail.memory_files': 'File di memoria',
|
||||
'agents.detail.model_order': 'Ordine di risoluzione modelli',
|
||||
@@ -756,7 +759,6 @@ export default {
|
||||
'agents.table.strength': 'Forza',
|
||||
'agents.table.name': 'Nome',
|
||||
'agents.table.model_id': 'ID modello',
|
||||
'agents.table.scope': 'Ambito',
|
||||
|
||||
'agents.banner.title': '<strong>Vista sola lettura.</strong> Gli agenti sono definiti da file in <code>agents/</code> — per aggiungere, rimuovere o modificare un agente, modifica il corrispondente file <code>AGENT.md</code> in quella directory.',
|
||||
'agents.banner.text': 'Puoi anche chiedere a <strong>Copilot</strong> (barra superiore) di creare un nuovo agente per te — descrivi cosa dovrebbe fare e configurerà automaticamente tutti i file necessari.',
|
||||
|
||||
Reference in New Issue
Block a user