feat: improve Claude agent mapping and context handling

This commit is contained in:
lzt404 committed 2026-08-02 17:49:43 +08:00
1 parent faa7e97326
commit a7e9cc356d
5 files changed
+672 -256

No files matched your search

-7
View File
@@ -554,13 +554,6 @@ export const jaOverrides = {
'agents.claudeDesktopMapping.description': '各 Claude Desktop モデルが実際に呼び出す上流モデルを選択します。',
'agents.claudeCodeMapping.title': 'Claude Code モデル → 上流モデル',
'agents.claudeCodeMapping.description': '各タスク役割に対して、起動時に設定する上流モデルを選択します。',
'agents.claudeCodeMapping.aliasOnly': 'エイリアスモデルのみ表示',
'agents.claudeCodeMapping.opus': 'Opus',
'agents.claudeCodeMapping.opusHint': '複雑な推論と高難度タスク',
'agents.claudeCodeMapping.sonnet': 'Sonnet',
'agents.claudeCodeMapping.sonnetHint': '既定のメインモデル',
'agents.claudeCodeMapping.haiku': 'Haiku',
'agents.claudeCodeMapping.haikuHint': '高速で軽量なタスク',
'agents.claudeDesktopMapping.customMapping': 'カスタムマッピング',
'agents.claudeDesktopMapping.customMappingHint': '有効にするとエイリアスモデルのみ、無効にするとエイリアス未設定の元モデルのみ表示します。',
'agents.claudeDesktopMapping.opus': 'Claude Opus 5 のマッピング先',
-14
View File
@@ -552,13 +552,6 @@ export const zhCN = {
'agents.claudeDesktopMapping.description': '选择每个 Claude Desktop 模型实际调用的上游模型。',
'agents.claudeCodeMapping.title': 'Claude Code 模型 → 上游模型',
'agents.claudeCodeMapping.description': '为不同任务角色选择启动时注入的上游模型。',
'agents.claudeCodeMapping.aliasOnly': '仅显示别名模型',
'agents.claudeCodeMapping.opus': 'Opus',
'agents.claudeCodeMapping.opusHint': '复杂推理与高难度任务',
'agents.claudeCodeMapping.sonnet': 'Sonnet',
'agents.claudeCodeMapping.sonnetHint': '默认主模型',
'agents.claudeCodeMapping.haiku': 'Haiku',
'agents.claudeCodeMapping.haikuHint': '快速轻量任务',
'agents.claudeDesktopMapping.customMapping': '自定义映射',
'agents.claudeDesktopMapping.customMappingHint': '开启后只显示别名模型;关闭后只显示未设置别名的原始模型。',
'agents.claudeDesktopMapping.opus': 'Claude Opus 5 映射到',
@@ -1487,13 +1480,6 @@ export const en: Record<MessageKey, string> = {
'agents.claudeDesktopMapping.description': 'Choose the upstream model each Claude Desktop model actually calls.',
'agents.claudeCodeMapping.title': 'Claude Code Model → Upstream Model',
'agents.claudeCodeMapping.description': 'Choose the upstream model injected at launch for each task role.',
'agents.claudeCodeMapping.aliasOnly': 'Show aliases only',
'agents.claudeCodeMapping.opus': 'Opus',
'agents.claudeCodeMapping.opusHint': 'Complex reasoning and difficult tasks',
'agents.claudeCodeMapping.sonnet': 'Sonnet',
'agents.claudeCodeMapping.sonnetHint': 'Default primary model',
'agents.claudeCodeMapping.haiku': 'Haiku',
'agents.claudeCodeMapping.haikuHint': 'Fast lightweight tasks',
'agents.claudeDesktopMapping.customMapping': 'Custom Mapping',
'agents.claudeDesktopMapping.customMappingHint': 'When enabled, only aliased models are shown; when disabled, only original models without aliases are shown.',
'agents.claudeDesktopMapping.opus': 'Map Claude Opus 5 to',
+25 -39
View File
@@ -123,20 +123,14 @@ const claudeMappingRoles = [
{
key: 'opus',
labelKey: 'agents.claudeDesktopMapping.opus',
codeLabelKey: 'agents.claudeCodeMapping.opus',
codeHintKey: 'agents.claudeCodeMapping.opusHint',
},
{
key: 'sonnet',
labelKey: 'agents.claudeDesktopMapping.sonnet',
codeLabelKey: 'agents.claudeCodeMapping.sonnet',
codeHintKey: 'agents.claudeCodeMapping.sonnetHint',
},
{
key: 'haiku',
labelKey: 'agents.claudeDesktopMapping.haiku',
codeLabelKey: 'agents.claudeCodeMapping.haiku',
codeHintKey: 'agents.claudeCodeMapping.haikuHint',
},
] as const;
@@ -1177,33 +1171,30 @@ export function AgentsPage() {
</aside>
<section className="panel agent-config-panel">
{selected !== 'claude-code' ? (
<div className="agent-subpage-tabs" role="tablist" aria-label={t('agents.tabs.label')}>
{availableSubpages.map((subpage) => (
<button
type="button"
id={`agent-subpage-tab-${subpage.id}`}
role="tab"
className={activeSubpage === subpage.id ? 'active' : ''}
aria-selected={activeSubpage === subpage.id}
aria-controls={`agent-subpage-panel-${subpage.id}`}
tabIndex={activeSubpage === subpage.id ? 0 : -1}
key={subpage.id}
onClick={() => setActiveSubpage(subpage.id)}
>
{t(subpage.labelKey)}
</button>
))}
</div>
) : null}
<div className="agent-subpage-tabs" role="tablist" aria-label={t('agents.tabs.label')}>
{availableSubpages.map((subpage) => (
<button
type="button"
id={`agent-subpage-tab-${subpage.id}`}
role="tab"
className={activeSubpage === subpage.id ? 'active' : ''}
aria-selected={activeSubpage === subpage.id}
aria-controls={`agent-subpage-panel-${subpage.id}`}
tabIndex={activeSubpage === subpage.id ? 0 : -1}
key={subpage.id}
onClick={() => setActiveSubpage(subpage.id)}
>
{t(subpage.labelKey)}
</button>
))}
</div>
{activeSubpage === 'core' ? (
<div
className={`agent-core-config ${selected === 'claude-code' ? 'agent-claude-code-config' : ''}`}
className="agent-core-config"
id="agent-subpage-panel-core"
role="tabpanel"
aria-labelledby={selected === 'claude-code' ? undefined : 'agent-subpage-tab-core'}
aria-label={selected === 'claude-code' ? t('agents.claudeCodeMapping.title') : undefined}
aria-labelledby="agent-subpage-tab-core"
>
<div className="agent-status-grid">
<div>
@@ -1254,7 +1245,7 @@ export function AgentsPage() {
) : null}
{isClaudeModelMappingClient ? (
<section className={`agent-core-setting-section agent-claude-desktop-mapping ${selected === 'claude-code' ? 'agent-claude-code-mapping' : ''}`}>
<section className="agent-core-setting-section agent-claude-desktop-mapping">
<div className="agent-section-heading">
<div>
<strong>{t(selected === 'claude-code'
@@ -1269,9 +1260,7 @@ export function AgentsPage() {
className="agent-claude-desktop-mapping-filter"
title={t('agents.claudeDesktopMapping.customMappingHint')}
>
<span>{t(selected === 'claude-code'
? 'agents.claudeCodeMapping.aliasOnly'
: 'agents.claudeDesktopMapping.customMapping')}</span>
<span>{t('agents.claudeDesktopMapping.customMapping')}</span>
<span className="switch-control">
<input
type="checkbox"
@@ -1287,11 +1276,8 @@ export function AgentsPage() {
</div>
<div className="agent-claude-desktop-mapping-grid">
{claudeMappingRoles.map((role) => (
<div className={`agent-claude-desktop-mapping-row ${role.key}`} key={role.key}>
<div className="agent-claude-mapping-role">
<strong>{t(selected === 'claude-code' ? role.codeLabelKey : role.labelKey)}</strong>
{selected === 'claude-code' ? <span>{t(role.codeHintKey)}</span> : null}
</div>
<div className="agent-claude-desktop-mapping-row" key={role.key}>
<strong>{t(role.labelKey)}</strong>
<AgentModelPicker
models={claudeMappingModels}
value={claudeModelMappingsDraft[role.key]}
@@ -1364,7 +1350,7 @@ export function AgentsPage() {
>
{busyAction === 'default'
? <LoaderCircle size={16} className="spin" />
: selected === 'claude-code' ? null : <RefreshCw size={16} />}
: <RefreshCw size={16} />}
{t('agents.modify.default')}
</button>
{selected === 'codex' ? (
@@ -1436,7 +1422,7 @@ export function AgentsPage() {
>
{busyAction === 'launch'
? <LoaderCircle size={16} className="spin" />
: selected === 'claude-code' ? null : <Play size={16} />}
: <Play size={16} />}
{busyAction === 'launch' ? t('agents.launch.starting') : defaultLaunchTarget ? t('agents.launch.start', { target: defaultLaunchTarget.label }) : t('agents.launch.unavailable')}
</button>
)}
+14 -156
View File
@@ -3456,7 +3456,7 @@ textarea:focus-visible {
.real-provider-row {
display: grid;
grid-template-columns: minmax(280px, 1.6fr) minmax(120px, 0.5fr) auto;
grid-template-columns: minmax(280px, 1.6fr) minmax(120px, 0.5fr) max-content;
align-items: start;
gap: 16px;
min-height: 88px;
@@ -3559,10 +3559,15 @@ textarea:focus-visible {
}
.provider-row-actions .provider-health-button {
min-width: max-content;
width: auto;
flex: 0 0 auto;
min-height: 30px;
overflow: visible;
padding: 0 10px;
font-size: var(--font-size-label);
text-overflow: clip;
white-space: nowrap;
}
.provider-enabled-control {
@@ -5310,127 +5315,6 @@ textarea:focus-visible {
font-size: var(--font-size-label);
}
.agent-claude-mapping-role {
display: grid;
min-width: 0;
gap: 3px;
}
.agent-claude-mapping-role > strong {
color: var(--theme-5f5a53);
font-size: var(--font-size-label);
}
.agent-claude-mapping-role > span {
overflow: hidden;
color: var(--theme-8a847c);
font-size: var(--font-size-meta);
text-overflow: ellipsis;
white-space: nowrap;
}
.agent-claude-code-config {
gap: 12px;
}
.agent-claude-code-config .agent-status-grid {
min-height: 0;
gap: 0;
padding: 10px 6px;
border: 1px solid var(--theme-e3e1db);
border-radius: 8px;
background: var(--theme-fffdf8);
}
.agent-claude-code-config .agent-status-grid > div {
gap: 3px;
padding: 2px 12px;
border: 0;
border-radius: 0;
background: transparent;
}
.agent-claude-code-config .agent-status-grid > div + div {
border-left: 1px solid var(--theme-e3e1db);
}
.agent-claude-code-mapping {
gap: 14px;
padding: 18px;
border-color: var(--theme-d8d2c8);
background: var(--theme-fffdf8);
}
.agent-claude-code-mapping > .agent-section-heading {
padding-bottom: 13px;
border-bottom: 1px solid var(--theme-e3e1db);
}
.agent-claude-code-mapping .agent-claude-desktop-mapping-grid {
gap: 12px;
}
.agent-claude-code-mapping .agent-claude-desktop-mapping-row {
position: relative;
gap: 10px;
padding: 13px;
overflow: hidden;
border: 1px solid var(--theme-e3e1db);
border-radius: 8px;
background: var(--theme-fff);
}
.agent-claude-code-mapping .agent-claude-desktop-mapping-row::before {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 3px;
background: var(--theme-bdb5a9);
content: '';
}
.agent-claude-code-mapping .agent-claude-desktop-mapping-row.sonnet {
border-color: var(--theme-d8d1eb);
background: var(--theme-f8f5ff);
}
.agent-claude-code-mapping .agent-claude-desktop-mapping-row.sonnet::before {
background: var(--theme-8069ad);
}
.agent-claude-code-mapping .agent-claude-desktop-mapping-row.opus::before {
background: var(--theme-bf8a43);
}
.agent-claude-code-mapping .agent-claude-desktop-mapping-row.haiku::before {
background: var(--theme-4f825c);
}
.agent-claude-code-mapping .agent-claude-desktop-mapping-filter {
padding: 7px 9px;
border-radius: 8px;
}
.agent-claude-code-config .agent-modification-actions {
grid-column: 1 / -1;
background: var(--theme-fffdf8);
}
.agent-claude-code-config .agent-modification-control > .agent-inline-message {
width: 100%;
}
.agent-claude-code-config .agent-config-footer {
padding-top: 0;
border-top: 0;
}
.agent-claude-code-config .agent-launch-button {
min-width: 190px;
min-height: 42px;
}
.agent-section-heading-actions {
display: flex !important;
flex: none;
@@ -7294,27 +7178,6 @@ textarea:focus-visible {
height: 100%;
}
.agent-claude-code-config .agent-modification-actions {
grid-column: 1 / -1;
grid-template-columns: minmax(180px, 0.7fr) minmax(0, 1.3fr);
align-items: center;
height: auto;
}
.agent-claude-code-config .agent-modification-control {
justify-items: end;
}
.agent-claude-code-config .agent-modification-buttons {
display: flex;
width: auto;
justify-content: flex-end;
}
.agent-claude-code-config .agent-modification-buttons button {
width: auto;
min-width: 152px;
}
}
@container agent-panel (max-width: 760px) {
@@ -7345,19 +7208,6 @@ textarea:focus-visible {
}
@container agent-panel (max-width: 640px) {
.agent-claude-code-config .agent-status-grid {
padding: 6px 12px;
}
.agent-claude-code-config .agent-status-grid > div {
padding: 8px 0;
}
.agent-claude-code-config .agent-status-grid > div + div {
border-top: 1px solid var(--theme-e3e1db);
border-left: 0;
}
.agent-claude-desktop-mapping > .agent-section-heading {
align-items: stretch;
flex-direction: column;
@@ -7455,6 +7305,14 @@ textarea:focus-visible {
height: 520px;
}
.real-provider-row {
grid-template-columns: minmax(0, 1fr) max-content;
}
.provider-row-meta {
display: none;
}
.agent-workbench {
grid-template-columns: 200px minmax(0, 1fr);
}