diff --git a/apps/cli/config/agent-presets/cordis/preset.yml b/apps/cli/config/agent-presets/cordis/preset.yml new file mode 100644 index 0000000000..b4d2e6a6f7 --- /dev/null +++ b/apps/cli/config/agent-presets/cordis/preset.yml @@ -0,0 +1,2 @@ +name: 创造模式 +description: 标准模式加上自指工具集,可以读改自己运行的这套组装,并据此创作新的预设。 diff --git a/apps/cli/config/agent-presets/core-web/profile.yml b/apps/cli/config/agent-presets/core-web/profile.yml new file mode 100644 index 0000000000..957796b6a0 --- /dev/null +++ b/apps/cli/config/agent-presets/core-web/profile.yml @@ -0,0 +1,2 @@ +name: 极简模式 +description: 只向模型呈现 bash 与 str_replace_editor,适合 benchmark 与最小复现。 diff --git a/apps/cli/config/agent-presets/standard/preset.yml b/apps/cli/config/agent-presets/standard/preset.yml new file mode 100644 index 0000000000..090576f0f2 --- /dev/null +++ b/apps/cli/config/agent-presets/standard/preset.yml @@ -0,0 +1,2 @@ +name: 标准模式 +description: 完整的编码 agent:文件读写、shell、检索、计划、委派与工作流。 diff --git a/docs/config-catalog.md b/docs/config-catalog.md index 7a1f74328f..3761927cd7 100644 --- a/docs/config-catalog.md +++ b/docs/config-catalog.md @@ -139,7 +139,7 @@ export interface PresetRoot { export type PresetTrust = 'system' | 'user' ``` -Source: [`packages/preset/agent-presets/src/types.ts:29`](../packages/preset/agent-presets/src/types.ts) +Source: [`packages/preset/agent-presets/src/types.ts:33`](../packages/preset/agent-presets/src/types.ts) ## `@deepseek-ai/dsh-agent-spine-demo` diff --git a/docs/cordis-catalog/services.md b/docs/cordis-catalog/services.md index 84154c375e..212a0d1d6a 100644 --- a/docs/cordis-catalog/services.md +++ b/docs/cordis-catalog/services.md @@ -96,10 +96,11 @@ async read(id: string): Promise * names a missing plugin still fails at the next session that selects it. * @param id - the profile id, which becomes its directory name. * @param content - the composition text. + * @param metadata - display name and description; clearing both removes the file. * @throws when the id is unusable, the text is not an entry list, or the * deployment configures no writable root. */ -async write(id: string, content: string): Promise +async write(id: string, content: string, metadata: PresetMetadata = {}): Promise /** * Delete a locally authored profile. @@ -145,7 +146,7 @@ serviceFor(agent: { ctx: Context }, name: K): async recompose(agentCtx: Context, id: string): Promise ``` -Source: [`packages/preset/agent-presets/src/index.ts:63`](../../packages/preset/agent-presets/src/index.ts) +Source: [`packages/preset/agent-presets/src/index.ts:67`](../../packages/preset/agent-presets/src/index.ts) ## `ctx.agents` — `AgentRegistry` diff --git a/packages/client/ui-agent-preset/src/client/AgentPresetSection.module.css b/packages/client/ui-agent-preset/src/client/AgentPresetSection.module.css index 67c44a20ca..8d1fcecf7e 100644 --- a/packages/client/ui-agent-preset/src/client/AgentPresetSection.module.css +++ b/packages/client/ui-agent-preset/src/client/AgentPresetSection.module.css @@ -29,35 +29,77 @@ color: var(--dsw-alias-label-tertiary); } -.rows { +/* Cards, not rows: a preset is a thing you pick, and the description is the + part that tells them apart — a row would bury it beside the actions. */ +.cards { list-style: none; margin: 0; padding: 0; - display: flex; - flex-direction: column; - gap: 10px; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); + gap: 12px; } -.rowCard { +.card { border: 1px solid var(--dsw-alias-border-l2); border-radius: 12px; - padding: 12px 14px; + padding: 14px 16px; display: flex; flex-direction: column; - gap: 12px; + gap: 8px; background: var(--dsw-alias-bg-layer-3); } -.rowHead { +/* The default preset is the one in use; it reads as selected rather than + merely badged. */ +.cardActive { + background: var(--dsw-alias-bg-layer-2); + border-color: var(--dsw-alias-label-tertiary); +} + +.cardHead { + display: flex; + align-items: baseline; + gap: 8px; +} + +.cardName { + font-size: 15px; + font-weight: 600; + line-height: 1.4; +} + +.inUse { + margin-left: auto; + font-size: 11px; + color: var(--dsw-alias-label-tertiary); + white-space: nowrap; +} + +.cardDesc { + margin: 0; + font-size: 13px; + line-height: 1.55; + color: var(--dsw-alias-label-secondary); + flex: 1; +} + +.cardMeta { display: flex; align-items: center; gap: 8px; - flex-wrap: wrap; } -.rowName { - font-size: 15px; - font-weight: 600; +.cardId { + font-family: var(--dsw-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace); + font-size: 11px; + color: var(--dsw-alias-label-dimmed); +} + +.cardFoot { + display: flex; + padding-top: 4px; + border-top: 1px solid var(--dsw-alias-border-l2); } .badge, @@ -80,30 +122,38 @@ .rowActions { display: inline-flex; - gap: 8px; - margin-left: auto; + gap: 4px; + flex-wrap: wrap; + align-items: center; } .secondaryButton { - border: 1px solid var(--dsw-alias-border-l2); - border-radius: 999px; - padding: 6px 14px; - background: var(--dsw-alias-bg-layer-3); - color: inherit; + border: none; + border-radius: 7px; + padding: 5px 8px; + background: none; + color: var(--dsw-alias-label-secondary); font: inherit; - font-size: 13px; + font-size: 12.5px; cursor: pointer; } .dangerButton { border: none; + border-radius: 7px; + padding: 5px 8px; background: none; color: var(--dsw-alias-state-error-primary); font: inherit; - font-size: 13px; + font-size: 12.5px; cursor: pointer; } +.secondaryButton:hover:not(:disabled), +.dangerButton:hover:not(:disabled) { + background: var(--dsw-alias-bg-layer-1); +} + .secondaryButton:disabled, .dangerButton:disabled, .addButton:disabled { diff --git a/packages/client/ui-agent-preset/src/client/AgentPresetSection.tsx b/packages/client/ui-agent-preset/src/client/AgentPresetSection.tsx index bbd44aebfe..b5fdf2aead 100644 --- a/packages/client/ui-agent-preset/src/client/AgentPresetSection.tsx +++ b/packages/client/ui-agent-preset/src/client/AgentPresetSection.tsx @@ -35,6 +35,10 @@ export interface AgentPresetSectionInjected { setId: (id: string) => void /** Replace the draft's composition text. */ setContent: (content: string) => void + /** Rename the draft. */ + setName: (name: string) => void + /** Replace the draft's description. */ + setDescription: (description: string) => void /** Save the open draft. */ save: () => Promise /** Ask for delete confirmation, or dismiss it with null. */ @@ -56,7 +60,8 @@ interface EditorProps { draft: PresetDraft blocker: ReturnType t: (key: AgentPresetSettingsKey) => string - actions: Pick + actions: Pick } function Editor({ draft, blocker, t, actions }: EditorProps): ReactNode { @@ -66,19 +71,44 @@ function Editor({ draft, blocker, t, actions }: EditorProps): ReactNode { {draft.creating ? ( ) : null} + {draft.writable + ? ( + <> + + + + ) + : null} {draft.writable ? null :

{t('readOnlyNotice')}

}