Add reusable agent profiles (#3208)

* Search models across all providers from the picker root

* Store agent profiles in daemon config and apply agent config in one RPC

An agent profile is a named bundle of provider, model, mode, thinking
option, feature values and notes, stored host-wide next to terminal
profiles. It carries no system prompt: AgentSessionConfig.systemPrompt is
creation-only, so a profile holding one would apply when starting an agent
and silently do nothing when applied to a running one.

Applying a profile through the four single-field RPCs can fail halfway and
leave an agent matching no profile, so agent.config.apply takes the whole
bundle. Model runs first because a thinking option only means anything
against the model that offers it.

Old daemons parse their persisted config strictly and would drop an
unknown agentProfiles key, making a save appear to succeed and vanish, so
both capabilities are advertised on server_info for the client to gate on.

list_profiles exposes the profiles to orchestrating agents, which read the
notes to pick one and copy its values into create_agent.

* Add the agent profiles settings section

Profiles live behind one module boundary so removing the feature is a
directory plus one mount, which is what favourites never was. The picker
and composer will ask for rows and an apply function rather than learning
what a profile contains.

The edit form follows the form-model pattern instead of the terminal
profile modal's per-field state, because provider selection cascades into
which models, modes, thinking levels and features exist below it.

The section is gated on server_info.features.agentProfiles: an older daemon
drops the key on write, and a save that appears to work and then vanishes
is worse than an unavailable state.

* Document agent profiles and name the four senses of profile

The glossary reserved Profile for HostProfile, terminal profiles owned the
user-facing word, and custom-providers.md used it for provider aliases.
Agent profile is now the term, with all four cross-referenced.

data-model.md never documented terminalProfiles either, so both profile
lists are backfilled together along with the whole-list patch semantics and
why absent and empty differ.

* Pin agent profiles to the model picker and delete favourites

Applying a profile writes its values into the agent controls and is then
forgotten, so rows carry no checkmark and no selected state: after applying,
nothing is selected. Chevron still means navigate deeper, so the absence of
one is what marks a row as an action.

A running agent is its provider's process and agent.config.apply carries no
provider, so the live picker only offers profiles matching the agent's
provider rather than showing rows that cannot do what they say. The draft
path has no such limit and switches provider freely.

Draft feature values go through preferences rather than the feature
callback alone, because the draft feature hook clears local values whenever
the provider changes and a provider-switching profile would lose them.

Favourites are deleted rather than migrated: they were device-local
AsyncStorage keyed by provider and model, while profiles are host-wide
daemon config. ProviderSelectionModelRow.favoriteKey stays as row identity
and moves to its real owner; renaming it is its own commit.

* Cover agent profiles and cross-provider search with E2E specs

Model rows expressed selection only as a checkmark glyph, which assistive
tech cannot see and a spec cannot assert. Rows that draw the indicator now
carry aria-selected; profile rows deliberately carry none, because a
profile is an action rather than a selection. That is what makes "nothing
is marked selected after applying a profile" a real assertion instead of a
tautology, with the materialized model one level down as the control.

The search fixture extends claude rather than mock: provider-config.ts
only allows the six shipped providers as extends targets, so a derived
provider cannot inherit the dev-only mock provider.

* State what applying a config bundle does on partial failure

applyBundle is not a transaction and the earlier commit message implied it
was. A step that rejects aborts the rest and the steps that already applied
stay applied, which a profile omitting modelId can reach: provider setters
validate against the agent's live model, so mode can land while a feature
that model does not support is rejected.

Nothing is hidden by that. Every setter emits agent state before returning,
so what applied is streamed to the client next to the rejected response.
Rolling back would re-invoke the setters that just failed, usually against
a session that is gone, and pre-flight validation would restate each
provider's model-dependent checks where they would drift from the setters
that own them.

What sending the bundle in one request removes is the multi-round-trip
failure class: interruption between hops, and interleaving with another
client. The test already pinned this behaviour; its name now says so.

* feat(agent-profiles): refine profile discovery and appearance

Make profiles discoverable from empty and provider-scoped model pickers, keep global search stable and virtualized, and move profile settings under Agents. Replace emoji identity with a shared Lucide icon and host-color picker, while requiring concrete provider selections so profiles materialize predictably.

* fix(agent-profiles): defer profile swatch styles

Resolving Unistyles proxies at module load can freeze the temporary startup color scheme before the persisted theme is restored. Keep only style-key names at module scope and resolve the selected swatch during render.
This commit is contained in:
Mohamed Boudra
2026-08-11 17:42:35 +02:00
committed by GitHub
parent 07044136c8
commit 308e9af845
72 changed files with 6348 additions and 538 deletions
+1 -1
View File
@@ -318,7 +318,7 @@ describe("translation resources", () => {
it("includes provider selector and pairing keys for the Batch 4D migration", () => {
expect(en.modelSelector.title).toBe("Select provider");
expect(en.modelSelector.favorites).toBe("Favorites");
expect(en.modelSelector.profiles).toBe("Profiles");
expect(en.providerCatalog.title).toBe("Add provider");
expect(en.providerCatalog.actions.installInstructions).toBe("Install instructions");
expect(en.pairing.link.title).toBe("Paste pairing link");
+43 -3
View File
@@ -1396,14 +1396,18 @@ export const ar: TranslationResources = {
loadingSelector: "جارٍ تحميل محدد النموذج...",
error: "خطأ",
defaultModel: "تقصير",
favorites: "المفضلة",
favoriteModel: "النموذج المفضل",
unfavoriteModel: "نموذج غير مفضل",
profiles: "الملفات الشخصية",
providers: "المزودون",
editProfiles: "تحرير",
editProfilesLabel: "تحرير ملفات الوكيل",
createProfile: "إنشاء ملف شخصي",
modelCount: "{{count}} نموذج",
modelCountPlural: "{{count}} نماذج",
retry: "أعد المحاولة",
retrying: "جارٍ إعادة المحاولة...",
noMatches: "لا توجد نماذج تطابق بحثك",
noMatchesForQuery: 'لا توجد نماذج تطابق "{{query}}"',
searchAllPlaceholder: "ابحث في كل النماذج...",
searchPlaceholder: "نماذج البحث...",
openProviderSettings: "افتح إعدادات{{provider}}",
},
@@ -2190,6 +2194,42 @@ export const ar: TranslationResources = {
save: "Save",
emptyState: "No profiles yet. Add one to launch terminals with a specific command.",
},
agentProfiles: {
sectionTitle: "ملفات تعريف الوكيل",
unavailable: "اتصل بهذا المضيف لإدارة ملفات تعريف الوكيل",
unsupported: "يشغّل هذا المضيف نسخة Daemon لا تدعم ملفات تعريف الوكيل بعد",
emptyState: "لا توجد ملفات تعريف بعد. أضف واحدًا لبدء الوكلاء من مزود ونموذج محفوظين.",
addProfileTitle: "إضافة ملف تعريف وكيل",
newProfile: "ملف تعريف جديد",
editProfile: "تعديل الملف",
editProfileTitle: "تعديل ملف تعريف الوكيل",
nameLabel: "الاسم",
namePlaceholder: "عمل الواجهة",
iconLabel: "الأيقونة",
noIcon: "بلا",
providerLabel: "المزود",
providerPlaceholder: "اختر مزودًا",
noProviders: "لا يوجد مزودون متاحون على هذا المضيف",
modelLabel: "النموذج",
noModels: "لا توجد نماذج يمكن الاختيار من بينها لهذا المزود",
modeLabel: "الوضع",
noModes: "لا توجد أوضاع يمكن الاختيار من بينها لهذا المزود",
thinkingLabel: "التفكير",
noThinkingOptions: "لا توجد مستويات تفكير لهذا النموذج",
featuresLabel: "السمات",
featureCount: "{{count}} سمة",
featureCountOne: "{{count}} سمة",
notesLabel: "ملاحظات للوكلاء",
notesPlaceholder: "استخدمه لعمل الواجهة — المكونات والتخطيط ورموز التصميم.",
notesHint: 'تُعاد بواسطة أداة MCP "list_profiles". اكتبها كتعليمة لوكيل آخر.',
save: "حفظ",
saving: "جارٍ الحفظ...",
remove: "إزالة",
removeConfirmTitle: "إزالة الملف؟",
removeConfirmMessage: 'إزالة "{{name}}"؟',
moveUp: "نقل لأعلى",
moveDown: "نقل لأسفل",
},
daemon: {
rename: {
editLabel: "تحرير التسمية",
+44 -3
View File
@@ -1407,14 +1407,18 @@ export const en = {
loadingSelector: "Loading model selector...",
error: "Error",
defaultModel: "Default",
favorites: "Favorites",
favoriteModel: "Favorite model",
unfavoriteModel: "Unfavorite model",
profiles: "Profiles",
providers: "Providers",
editProfiles: "Edit",
editProfilesLabel: "Edit agent profiles",
createProfile: "Create profile",
modelCount: "{{count}} model",
modelCountPlural: "{{count}} models",
retry: "Retry",
retrying: "Retrying...",
noMatches: "No models match your search",
noMatchesForQuery: 'No models match "{{query}}"',
searchAllPlaceholder: "Search all models...",
searchPlaceholder: "Search models...",
openProviderSettings: "Open {{provider}} settings",
},
@@ -2201,6 +2205,43 @@ export const en = {
save: "Save",
emptyState: "No profiles yet. Add one to launch terminals with a specific command.",
},
agentProfiles: {
sectionTitle: "Agent profiles",
unavailable: "Connect to this host to manage agent profiles",
unsupported: "This host runs a daemon that does not support agent profiles yet",
emptyState: "No profiles yet. Add one to start agents from a saved provider and model.",
addProfileTitle: "Add agent profile",
newProfile: "New profile",
editProfile: "Edit profile",
editProfileTitle: "Edit agent profile",
nameLabel: "Name",
namePlaceholder: "UI work",
iconLabel: "Icon",
noIcon: "None",
providerLabel: "Provider",
providerPlaceholder: "Select a provider",
noProviders: "No providers are available on this host",
modelLabel: "Model",
noModels: "This provider has no models to choose from",
modeLabel: "Mode",
noModes: "This provider has no modes to choose from",
thinkingLabel: "Thinking",
noThinkingOptions: "This model has no thinking levels",
featuresLabel: "Features",
featureCount: "{{count}} features",
featureCountOne: "{{count}} feature",
notesLabel: "Notes for agents",
notesPlaceholder: "Use for UI work — components, layout and design tokens.",
notesHint:
"Returned by the list_profiles MCP tool. Write it as an instruction to another agent.",
save: "Save",
saving: "Saving...",
remove: "Remove",
removeConfirmTitle: "Remove profile?",
removeConfirmMessage: 'Remove "{{name}}"?',
moveUp: "Move up",
moveDown: "Move down",
},
daemon: {
rename: {
editLabel: "Edit label",
+45 -3
View File
@@ -1437,14 +1437,18 @@ export const es: TranslationResources = {
loadingSelector: "Cargando selector de modelo...",
error: "Error",
defaultModel: "Por defecto",
favorites: "Favoritos",
favoriteModel: "modelo favorito",
unfavoriteModel: "Modelo no favorito",
profiles: "Perfiles",
providers: "Proveedores",
editProfiles: "Editar",
editProfilesLabel: "Editar perfiles de agente",
createProfile: "Crear perfil",
modelCount: "{{count}} modelo",
modelCountPlural: "{{count}} modelos",
retry: "Rever",
retrying: "Reintentando...",
noMatches: "Ningún modelo coincide con tu búsqueda",
noMatchesForQuery: "Ningún modelo coincide con «{{query}}»",
searchAllPlaceholder: "Buscar en todos los modelos...",
searchPlaceholder: "Buscar modelos...",
openProviderSettings: "Abrir configuración de{{provider}}",
},
@@ -2240,6 +2244,44 @@ export const es: TranslationResources = {
save: "Save",
emptyState: "No profiles yet. Add one to launch terminals with a specific command.",
},
agentProfiles: {
sectionTitle: "Perfiles de agente",
unavailable: "Conéctese a este host para administrar perfiles de agente",
unsupported: "Este host ejecuta un daemon que aún no admite perfiles de agente",
emptyState:
"Aún no hay perfiles. Agregue uno para iniciar agentes con un proveedor y un modelo guardados.",
addProfileTitle: "Agregar perfil de agente",
newProfile: "Nuevo perfil",
editProfile: "Editar perfil",
editProfileTitle: "Editar perfil de agente",
nameLabel: "Nombre",
namePlaceholder: "Trabajo de UI",
iconLabel: "Icono",
noIcon: "Ninguno",
providerLabel: "Proveedor",
providerPlaceholder: "Seleccione un proveedor",
noProviders: "No hay proveedores disponibles en este host",
modelLabel: "Modelo",
noModels: "Este proveedor no tiene modelos para elegir",
modeLabel: "Modo",
noModes: "Este proveedor no tiene modos para elegir",
thinkingLabel: "Pensamiento",
noThinkingOptions: "Este modelo no tiene niveles de pensamiento",
featuresLabel: "Características",
featureCount: "{{count}} características",
featureCountOne: "{{count}} característica",
notesLabel: "Notas para los agentes",
notesPlaceholder: "Úselo para trabajo de UI: componentes, diseño y tokens de diseño.",
notesHint:
'Devuelto por la herramienta MCP "list_profiles". Escríbalo como una instrucción para otro agente.',
save: "Guardar",
saving: "Guardando...",
remove: "Eliminar",
removeConfirmTitle: "¿Eliminar perfil?",
removeConfirmMessage: '¿Eliminar "{{name}}"?',
moveUp: "Mover hacia arriba",
moveDown: "Mover hacia abajo",
},
daemon: {
rename: {
editLabel: "Editar etiqueta",
+47 -3
View File
@@ -1441,14 +1441,18 @@ export const fr: TranslationResources = {
loadingSelector: "Chargement du sélecteur de modèle...",
error: "Erreur",
defaultModel: "Défaut",
favorites: "Favoris",
favoriteModel: "Modèle préféré",
unfavoriteModel: "Modèle défavorisé",
profiles: "Profils",
providers: "Fournisseurs",
editProfiles: "Modifier",
editProfilesLabel: "Modifier les profils d'agent",
createProfile: "Créer un profil",
modelCount: "{{count}} modèle",
modelCountPlural: "{{count}} modèles",
retry: "Réessayer",
retrying: "Nouvelle tentative...",
noMatches: "Aucun modèle ne correspond à votre recherche",
noMatchesForQuery: "Aucun modèle ne correspond à « {{query}} »",
searchAllPlaceholder: "Rechercher dans tous les modèles...",
searchPlaceholder: "Rechercher des modèles...",
openProviderSettings: "Ouvrir les paramètres{{provider}}",
},
@@ -2244,6 +2248,46 @@ export const fr: TranslationResources = {
save: "Save",
emptyState: "No profiles yet. Add one to launch terminals with a specific command.",
},
agentProfiles: {
sectionTitle: "Profils d'agent",
unavailable: "Connectez-vous à cet hôte pour gérer les profils d'agent",
unsupported:
"Cet hôte exécute un daemon qui ne prend pas encore en charge les profils d'agent",
emptyState:
"Aucun profil pour le moment. Ajoutez-en un pour démarrer des agents à partir d'un fournisseur et d'un modèle enregistrés.",
addProfileTitle: "Ajouter un profil d'agent",
newProfile: "Nouveau profil",
editProfile: "Modifier le profil",
editProfileTitle: "Modifier le profil d'agent",
nameLabel: "Nom",
namePlaceholder: "Travail sur l'UI",
iconLabel: "Icône",
noIcon: "Aucune",
providerLabel: "Fournisseur",
providerPlaceholder: "Sélectionner un fournisseur",
noProviders: "Aucun fournisseur n'est disponible sur cet hôte",
modelLabel: "Modèle",
noModels: "Ce fournisseur n'a aucun modèle à choisir",
modeLabel: "Mode",
noModes: "Ce fournisseur n'a aucun mode à choisir",
thinkingLabel: "Pensée",
noThinkingOptions: "Ce modèle n'a aucun niveau de pensée",
featuresLabel: "Caractéristiques",
featureCount: "{{count}} caractéristiques",
featureCountOne: "{{count}} caractéristique",
notesLabel: "Notes pour les agents",
notesPlaceholder:
"À utiliser pour le travail sur l'UI — composants, mise en page et tokens de design.",
notesHint:
"Renvoyé par l'outil MCP « list_profiles ». Rédigez-le comme une instruction destinée à un autre agent.",
save: "Enregistrer",
saving: "Enregistrement...",
remove: "Supprimer",
removeConfirmTitle: "Supprimer le profil ?",
removeConfirmMessage: "Supprimer « {{name}} » ?",
moveUp: "Déplacer vers le haut",
moveDown: "Déplacer vers le bas",
},
daemon: {
rename: {
editLabel: "Modifier l'étiquette",
+45 -3
View File
@@ -1410,14 +1410,18 @@ export const ja: TranslationResources = {
loadingSelector: "モデルセレクターを読み込み中...",
error: "エラー",
defaultModel: "デフォルト",
favorites: "お気に入り",
favoriteModel: "お気に入りモデル",
unfavoriteModel: "お気に入りを解除",
profiles: "プロファイル",
providers: "プロバイダー",
editProfiles: "編集",
editProfilesLabel: "エージェントプロファイルを編集",
createProfile: "プロファイルを作成",
modelCount: "{{count}}つのモデル",
modelCountPlural: "{{count}}つのモデル",
retry: "再試行",
retrying: "再試行中...",
noMatches: "検索に一致するモデルがありません",
noMatchesForQuery: "「{{query}}」に一致するモデルがありません",
searchAllPlaceholder: "すべてのモデルを検索...",
searchPlaceholder: "モデルを検索...",
openProviderSettings: "{{provider}}の設定を開く",
},
@@ -2210,6 +2214,44 @@ export const ja: TranslationResources = {
emptyState:
"プロファイルがまだありません。特定のコマンドでターミナルを起動するために追加してください。",
},
agentProfiles: {
sectionTitle: "エージェントプロファイル",
unavailable: "エージェントプロファイルを管理するにはこのホストに接続してください",
unsupported: "このホストで動作するデーモンはまだエージェントプロファイルに対応していません",
emptyState:
"プロファイルがまだありません。保存したプロバイダーとモデルでエージェントを起動するために追加してください。",
addProfileTitle: "エージェントプロファイルを追加",
newProfile: "新しいプロファイル",
editProfile: "プロファイルを編集",
editProfileTitle: "エージェントプロファイルを編集",
nameLabel: "名前",
namePlaceholder: "UI作業",
iconLabel: "アイコン",
noIcon: "なし",
providerLabel: "プロバイダー",
providerPlaceholder: "プロバイダーを選択",
noProviders: "このホストで利用できるプロバイダーがありません",
modelLabel: "モデル",
noModels: "このプロバイダーには選択できるモデルがありません",
modeLabel: "モード",
noModes: "このプロバイダーには選択できるモードがありません",
thinkingLabel: "思考",
noThinkingOptions: "このモデルには思考レベルがありません",
featuresLabel: "機能",
featureCount: "{{count}}個の機能",
featureCountOne: "{{count}}個の機能",
notesLabel: "エージェントへのメモ",
notesPlaceholder: "UI作業に使用 — コンポーネント、レイアウト、デザイントークンなど。",
notesHint:
"list_profiles MCPツールによって返されます。他のエージェントへの指示として記述してください。",
save: "保存",
saving: "保存中...",
remove: "削除",
removeConfirmTitle: "プロファイルを削除しますか?",
removeConfirmMessage: '"{{name}}"を削除しますか?',
moveUp: "上に移動",
moveDown: "下に移動",
},
daemon: {
rename: {
editLabel: "ラベルを編集",
+45 -3
View File
@@ -1406,14 +1406,18 @@ export const ko: TranslationResources = {
loadingSelector: "모델 선택기 불러오는 중...",
error: "오류",
defaultModel: "기본값",
favorites: "즐겨찾기",
favoriteModel: "모델 즐겨찾기",
unfavoriteModel: "모델 즐겨찾기 해제",
profiles: "프로필",
providers: "제공자",
editProfiles: "편집",
editProfilesLabel: "에이전트 프로필 편집",
createProfile: "프로필 만들기",
modelCount: "모델 {{count}}개",
modelCountPlural: "모델 {{count}}개",
retry: "다시 시도",
retrying: "다시 시도 중...",
noMatches: "검색과 일치하는 모델이 없습니다",
noMatchesForQuery: '"{{query}}"과(와) 일치하는 모델이 없습니다',
searchAllPlaceholder: "모든 모델 검색...",
searchPlaceholder: "모델 검색...",
openProviderSettings: "{{provider}} 설정 열기",
},
@@ -2202,6 +2206,44 @@ export const ko: TranslationResources = {
save: "저장",
emptyState: "아직 프로필이 없습니다. 특정 명령으로 터미널을 실행하려면 하나 추가하세요.",
},
agentProfiles: {
sectionTitle: "에이전트 프로필",
unavailable: "에이전트 프로필을 관리하려면 이 호스트에 연결하세요",
unsupported: "이 호스트에서 실행 중인 데몬은 아직 에이전트 프로필을 지원하지 않습니다",
emptyState:
"아직 프로필이 없습니다. 저장된 프로바이더와 모델로 에이전트를 시작하려면 하나 추가하세요.",
addProfileTitle: "에이전트 프로필 추가",
newProfile: "새 프로필",
editProfile: "프로필 편집",
editProfileTitle: "에이전트 프로필 편집",
nameLabel: "이름",
namePlaceholder: "UI 작업",
iconLabel: "아이콘",
noIcon: "없음",
providerLabel: "프로바이더",
providerPlaceholder: "프로바이더 선택",
noProviders: "이 호스트에서 사용 가능한 프로바이더가 없습니다",
modelLabel: "모델",
noModels: "이 프로바이더에는 선택할 수 있는 모델이 없습니다",
modeLabel: "모드",
noModes: "이 프로바이더에는 선택할 수 있는 모드가 없습니다",
thinkingLabel: "사고",
noThinkingOptions: "이 모델에는 사고 수준이 없습니다",
featuresLabel: "기능",
featureCount: "기능 {{count}}개",
featureCountOne: "기능 {{count}}개",
notesLabel: "에이전트를 위한 메모",
notesPlaceholder: "UI 작업에 사용 — 컴포넌트, 레이아웃, 디자인 토큰.",
notesHint:
"list_profiles MCP 도구가 반환합니다. 다른 에이전트에게 전달할 지침으로 작성하세요.",
save: "저장",
saving: "저장하는 중...",
remove: "제거",
removeConfirmTitle: "프로필을 제거할까요?",
removeConfirmMessage: '"{{name}}"을(를) 제거할까요?',
moveUp: "위로 이동",
moveDown: "아래로 이동",
},
daemon: {
rename: {
editLabel: "레이블 편집",
+45 -3
View File
@@ -1423,14 +1423,18 @@ export const ptBR: TranslationResources = {
loadingSelector: "Carregando seletor de modelos...",
error: "Erro",
defaultModel: "Padrão",
favorites: "Favoritos",
favoriteModel: "Favoritar modelo",
unfavoriteModel: "Remover modelo dos favoritos",
profiles: "Perfis",
providers: "Provedores",
editProfiles: "Editar",
editProfilesLabel: "Editar perfis de agente",
createProfile: "Criar perfil",
modelCount: "{{count}} modelo",
modelCountPlural: "{{count}} modelos",
retry: "Tentar novamente",
retrying: "Tentando novamente...",
noMatches: "Nenhum modelo corresponde à sua busca",
noMatchesForQuery: "Nenhum modelo corresponde a «{{query}}»",
searchAllPlaceholder: "Buscar em todos os modelos...",
searchPlaceholder: "Buscar modelos...",
openProviderSettings: "Abrir configurações de {{provider}}",
},
@@ -2225,6 +2229,44 @@ export const ptBR: TranslationResources = {
emptyState:
"Nenhum perfil ainda. Adicione um para abrir terminais com um comando específico.",
},
agentProfiles: {
sectionTitle: "Perfis de agente",
unavailable: "Conecte-se a este host para gerenciar perfis de agente",
unsupported: "Este host executa um daemon que ainda não é compatível com perfis de agente",
emptyState:
"Nenhum perfil ainda. Adicione um para iniciar agentes a partir de um provedor e modelo salvos.",
addProfileTitle: "Adicionar perfil de agente",
newProfile: "Novo perfil",
editProfile: "Editar perfil",
editProfileTitle: "Editar perfil de agente",
nameLabel: "Nome",
namePlaceholder: "Trabalho de UI",
iconLabel: "Ícone",
noIcon: "Nenhum",
providerLabel: "Provedor",
providerPlaceholder: "Selecione um provedor",
noProviders: "Nenhum provedor está disponível neste host",
modelLabel: "Modelo",
noModels: "Este provedor não tem modelos para escolher",
modeLabel: "Modo",
noModes: "Este provedor não tem modos para escolher",
thinkingLabel: "Raciocínio",
noThinkingOptions: "Este modelo não tem níveis de raciocínio",
featuresLabel: "Recursos",
featureCount: "{{count}} recursos",
featureCountOne: "{{count}} recurso",
notesLabel: "Notas para os agentes",
notesPlaceholder: "Use para trabalho de UI — componentes, layout e tokens de design.",
notesHint:
'Retornado pela ferramenta MCP "list_profiles". Escreva como uma instrução para outro agente.',
save: "Salvar",
saving: "Salvando...",
remove: "Remover",
removeConfirmTitle: "Remover perfil?",
removeConfirmMessage: 'Remover "{{name}}"?',
moveUp: "Mover para cima",
moveDown: "Mover para baixo",
},
daemon: {
rename: {
editLabel: "Editar rótulo",
+45 -3
View File
@@ -1428,14 +1428,18 @@ export const ru: TranslationResources = {
loadingSelector: "Загрузка выбора модели...",
error: "Ошибка",
defaultModel: "По умолчанию",
favorites: "Избранное",
favoriteModel: "Любимая модель",
unfavoriteModel: "Нелюбимая модель",
profiles: "Профили",
providers: "Провайдеры",
editProfiles: "Изменить",
editProfilesLabel: "Изменить профили агентов",
createProfile: "Создать профиль",
modelCount: "{{count}} модель",
modelCountPlural: "{{count}} моделей",
retry: "Повторить попытку",
retrying: "Повторная попытка...",
noMatches: "Ни одна модель не соответствует вашему запросу",
noMatchesForQuery: "Нет моделей, соответствующих «{{query}}»",
searchAllPlaceholder: "Поиск по всем моделям...",
searchPlaceholder: "Поиск моделей...",
openProviderSettings: "Открыть настройки{{provider}}",
},
@@ -2229,6 +2233,44 @@ export const ru: TranslationResources = {
save: "Save",
emptyState: "No profiles yet. Add one to launch terminals with a specific command.",
},
agentProfiles: {
sectionTitle: "Профили агента",
unavailable: "Подключитесь к этому хосту, чтобы управлять профилями агента",
unsupported: "На этом хосте работает daemon, который пока не поддерживает профили агента",
emptyState:
"Пока нет профилей. Добавьте один, чтобы запускать агентов с сохранённым провайдером и моделью.",
addProfileTitle: "Добавить профиль агента",
newProfile: "Новый профиль",
editProfile: "Изменить профиль",
editProfileTitle: "Изменить профиль агента",
nameLabel: "Имя",
namePlaceholder: "Работа над UI",
iconLabel: "Значок",
noIcon: "Нет",
providerLabel: "Провайдер",
providerPlaceholder: "Выберите провайдера",
noProviders: "На этом хосте нет доступных провайдеров",
modelLabel: "Модель",
noModels: "У этого провайдера нет моделей для выбора",
modeLabel: "Режим",
noModes: "У этого провайдера нет режимов для выбора",
thinkingLabel: "Мышление",
noThinkingOptions: "У этой модели нет уровней мышления",
featuresLabel: "Функции",
featureCount: "{{count}} функций",
featureCountOne: "{{count}} функция",
notesLabel: "Заметки для агентов",
notesPlaceholder: "Используйте для работы над UI — компоненты, макет и токены дизайна.",
notesHint:
"Возвращается инструментом MCP «list_profiles». Напишите это как инструкцию для другого агента.",
save: "Сохранить",
saving: "Сохранение...",
remove: "Удалить",
removeConfirmTitle: "Удалить профиль?",
removeConfirmMessage: "Удалить «{{name}}»?",
moveUp: "Переместить вверх",
moveDown: "Переместить вниз",
},
daemon: {
rename: {
editLabel: "Изменить ярлык",
+43 -3
View File
@@ -1379,14 +1379,18 @@ export const zhCN: TranslationResources = {
loadingSelector: "正在加载模型选择器...",
error: "错误",
defaultModel: "默认",
favorites: "收藏",
favoriteModel: "收藏模型",
unfavoriteModel: "取消收藏模型",
profiles: "配置文件",
providers: "提供方",
editProfiles: "编辑",
editProfilesLabel: "编辑智能体配置文件",
createProfile: "创建配置文件",
modelCount: "{{count}} 个模型",
modelCountPlural: "{{count}} 个模型",
retry: "重试",
retrying: "正在重试...",
noMatches: "没有匹配的模型",
noMatchesForQuery: "没有与“{{query}}”匹配的模型",
searchAllPlaceholder: "搜索所有模型...",
searchPlaceholder: "搜索模型...",
openProviderSettings: "打开 {{provider}} 设置",
},
@@ -2167,6 +2171,42 @@ export const zhCN: TranslationResources = {
save: "Save",
emptyState: "No profiles yet. Add one to launch terminals with a specific command.",
},
agentProfiles: {
sectionTitle: "Agent 配置",
unavailable: "连接到这个 Host 以管理 Agent 配置",
unsupported: "此 Host 运行的 Daemon 尚不支持 Agent 配置",
emptyState: "还没有配置。添加一个以便使用保存的 Provider 和 Model 启动 Agent。",
addProfileTitle: "添加 Agent 配置",
newProfile: "新建配置",
editProfile: "编辑配置",
editProfileTitle: "编辑 Agent 配置",
nameLabel: "名称",
namePlaceholder: "UI 工作",
iconLabel: "图标",
noIcon: "无",
providerLabel: "Provider",
providerPlaceholder: "选择一个 Provider",
noProviders: "此 Host 上没有可用的 Provider",
modelLabel: "Model",
noModels: "此 Provider 没有可选择的 Model",
modeLabel: "Mode",
noModes: "此 Provider 没有可选择的 Mode",
thinkingLabel: "Thinking",
noThinkingOptions: "此 Model 没有 Thinking 级别",
featuresLabel: "Features",
featureCount: "{{count}} 个 Feature",
featureCountOne: "{{count}} 个 Feature",
notesLabel: "给 Agent 的说明",
notesPlaceholder: "用于 UI 工作 — 组件、布局和设计 token。",
notesHint: "由 list_profiles MCP 工具返回。请将其写成给另一个 Agent 的指令。",
save: "保存",
saving: "保存中...",
remove: "移除",
removeConfirmTitle: "移除配置?",
removeConfirmMessage: "移除「{{name}}」?",
moveUp: "上移",
moveDown: "下移",
},
daemon: {
rename: {
editLabel: "编辑标签",