Merge branch 'stack/agent-profiles-8-authoring' into stack/agent-profiles-9-rename

This commit is contained in:
Yichen Jiang
2026-08-07 03:02:47 +08:00
4 changed files with 18 additions and 9 deletions

View File

@@ -14,9 +14,9 @@
- button "关闭":
- img
- text: 关闭
- text: Agent 预设 对此后新建的会话生效。运行中的会话保持它开始时的 preset
- button "standard":
- text: standard
- text: Agent 预设 对此后新建的会话生效。运行中的会话保持它开始时的预设
- button "标准模式":
- text: 标准模式
- img
- text: 权限 选择新会话的默认权限模式
- button "Workspace Write":

View File

@@ -52,7 +52,12 @@ export function AgentPresetRow({ load, select, useAgentPreset, t }: AgentPresetR
// every session shares the host composition — the row simply does not exist.
if (state.status === 'unavailable') return null
const busy = state.status === 'loading' || state.status === 'saving'
const label = state.currentValue === '' ? t('loading') : state.currentValue
// The metadata name is what every other surface shows — the new-session chip,
// the session header, the preset cards — so this row shows it too; the id is
// the addressing, not the label. A preset that names itself nothing falls
// back to its id, which is then all there is to say about it.
const chosen = state.options.find(option => option.id === state.currentValue)
const label = state.currentValue === '' ? t('loading') : (chosen?.name ?? state.currentValue)
const description: string = state.error ?? t('description')
return (
@@ -69,7 +74,9 @@ export function AgentPresetRow({ load, select, useAgentPreset, t }: AgentPresetR
// every preset as shipped and vetted.
items={state.options.map(option => ({
id: option.id,
label: option.trust === 'user' ? `${option.id} · ${t('userTrust')}` : option.id,
label: option.trust === 'user'
? `${option.name ?? option.id} · ${t('userTrust')}`
: option.name ?? option.id,
}))}
selectedId={state.currentValue}
onSelect={(id) => {

View File

@@ -64,7 +64,7 @@ export const en: Record<AgentPresetSettingsKey, string> = {
/** Simplified Chinese copy. */
export const zh: Record<AgentPresetSettingsKey, string> = {
title: 'Agent 预设',
description: '对此后新建的会话生效。运行中的会话保持它开始时的 preset。',
description: '对此后新建的会话生效。运行中的会话保持它开始时的预设。',
loading: '正在加载预设…',
error: '无法加载 Agent 预设。',
userTrust: '自定义',

View File

@@ -28,7 +28,9 @@ const ROW_READY: AgentPresetSettingsState = {
error: null,
writable: true,
currentValue: 'standard',
options: [{ id: 'standard', trust: 'system' }, { id: 'mine', trust: 'user' }],
// `mine` deliberately names itself nothing: the row must fall back to the
// id for a preset whose author wrote no metadata.
options: [{ id: 'standard', trust: 'system', name: '标准模式' }, { id: 'mine', trust: 'user' }],
}
const SEAT_READY: AgentPresetSeatState = {
@@ -88,7 +90,7 @@ describe('the General-settings row', () => {
const actions = renderRow()
await waitFor(() => { expect(actions.load).toHaveBeenCalledTimes(1) })
expect(screen.getByRole('button').textContent).toContain('standard')
expect(screen.getByRole('button').textContent).toContain('标准模式')
})
it('marks a locally authored option as local', () => {
@@ -100,7 +102,7 @@ describe('the General-settings row', () => {
// list says which rows are local rather than presenting all as vetted.
expect(screen.getByText(`mine · ${en.userTrust}`)).toBeTruthy()
// The shipped one carries no marker; only local rows are called out.
expect(screen.getAllByText('standard')).toHaveLength(2)
expect(screen.getAllByText('标准模式')).toHaveLength(2)
})
it('writes the picked preset and closes the menu', () => {