-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathagent-configuration-ui.html
More file actions
73 lines (64 loc) · 33.2 KB
/
Copy pathagent-configuration-ui.html
File metadata and controls
73 lines (64 loc) · 33.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Agent 配置框架 — OpenProgram</title>
<style>
:root{color-scheme:dark;--bg:#111216;--surface:#17191e;--surface2:#1d2026;--surface3:#242830;--line:#303540;--line2:#454c59;--text:#eceef2;--muted:#a0a6b1;--quiet:#747b87;--cyan:#63ccd8;--blue:#82aef8;--green:#78d29e;--orange:#eca06d;--red:#ee7b7b;--mono:ui-monospace,"SFMono-Regular",Menlo,monospace;--sans:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC",sans-serif}
*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:var(--bg);color:var(--text);font:15px/1.65 var(--sans)}button,input,select,textarea{font:inherit}button{cursor:pointer}a{color:var(--blue)}code{padding:1px 5px;border-radius:4px;background:#24272e;color:#dce0e7;font:12px var(--mono)}.page{width:min(1220px,calc(100% - 32px));margin:auto;padding:28px 0 72px}.doc-nav{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:22px}.doc-nav a{padding:5px 9px;border:1px solid var(--line);border-radius:7px;color:#adb3bd;text-decoration:none;font-size:12px}.doc-nav a[aria-current="page"]{border-color:#39727c;background:#162126;color:#8fe0e9}header{padding:0 0 23px;border-bottom:1px solid var(--line)}.eyebrow{color:var(--cyan);font:11px var(--mono);letter-spacing:.08em;text-transform:uppercase}h1{margin:8px 0 10px;font-size:clamp(28px,4vw,42px);line-height:1.15}h2{margin:0 0 14px;font-size:24px}h3{margin:0;font-size:16px}h4{margin:0;font-size:13px}.lead{max-width:940px;margin:0;color:#c7cbd3;font-size:16px}section{padding:30px 0;border-bottom:1px solid var(--line)}p{margin:9px 0}.callout{margin:14px 0;padding:12px 14px;border-left:3px solid var(--cyan);background:#162126;color:#c9dadd}.callout.warning{border-left-color:var(--orange);background:#241d18;color:#d9cabf}.layer-grid,.choice-grid,.state-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}.card{padding:15px;border:1px solid var(--line);border-radius:10px;background:var(--surface)}.card .kicker{color:var(--cyan);font:10px var(--mono);letter-spacing:.06em;text-transform:uppercase}.card p{color:var(--muted);font-size:13px}.card ul{margin:8px 0 0;padding-left:18px;color:#c4c8d0;font-size:12px}.card li+li{margin-top:4px}table{width:100%;margin:14px 0;border-collapse:collapse;font-size:13px}th,td{padding:10px 11px;border:1px solid var(--line);text-align:left;vertical-align:top}th{background:var(--surface2)}td{color:#bec3cc}.done{color:var(--green)}.target{color:var(--orange)}.absent{color:var(--red)}
.prototype{position:relative;margin:18px 0;overflow:hidden;border:1px solid var(--line);border-radius:13px;background:#0e1013;box-shadow:0 22px 70px #0004}.proto-bar{display:flex;align-items:center;gap:10px;min-height:50px;padding:9px 12px;border-bottom:1px solid var(--line);background:#14161a}.proto-brand{font-weight:750}.proto-global{display:flex;gap:3px}.proto-global span{padding:5px 8px;border-radius:6px;color:#7f8692;font-size:10px}.proto-global .active{background:#272a31;color:#eef0f3}.dirty{display:none;margin-left:auto;color:var(--orange);font:9px var(--mono)}.prototype[data-dirty="true"] .dirty{display:block}.save{margin-left:auto;padding:6px 10px;border:1px solid #3d7780;border-radius:7px;background:#16262a;color:#91e1ea;font-size:10px}.prototype[data-dirty="false"] .save{border-color:var(--line);background:#1a1c21;color:#707783}.shell{display:grid;grid-template-columns:205px minmax(0,1fr);min-height:660px}.agent-list{padding:11px;border-right:1px solid var(--line);background:#15171b}.list-head{display:flex;align-items:center;justify-content:space-between;margin:1px 6px 10px;color:#d9dce2;font-size:11px}.new-agent{padding:4px 7px;border:0;border-radius:6px;background:transparent;color:var(--cyan);font-size:10px}.agent{display:grid;grid-template-columns:30px minmax(0,1fr);gap:8px;margin:3px 0;padding:8px;border:1px solid transparent;border-radius:8px;color:#aab0bb}.agent.active{border-color:#363b46;background:#24272e;color:var(--text)}.avatar{display:grid;place-items:center;width:30px;height:30px;border:1px solid #3d5660;border-radius:8px;background:#172227;color:var(--cyan);font:12px var(--mono)}.agent strong{display:block;font-size:10.5px}.agent small{display:block;color:#767d89;font:8.5px var(--mono)}.detail{min-width:0;padding:16px 18px}.detail-head{display:flex;align-items:center;gap:10px}.detail-head p{margin:1px 0 0;color:var(--muted);font-size:9.5px}.default-badge{margin-left:auto;padding:2px 7px;border:1px solid #3c6c4e;border-radius:999px;color:#87d6a3;font:8px var(--mono)}.more{width:28px;height:28px;border:1px solid var(--line);border-radius:7px;background:#1a1c21;color:#aab0ba}.tabs{display:flex;gap:2px;margin:14px 0 17px;border-bottom:1px solid var(--line);overflow:auto}.tab{flex:none;padding:8px 9px;border:0;border-bottom:2px solid transparent;background:transparent;color:#818895;font-size:9.5px;white-space:nowrap}.tab[aria-selected="true"]{border-bottom-color:var(--cyan);color:#edf0f3}.panel{padding:0;border:0}.panel[hidden]{display:none}.panel-head{display:flex;align-items:flex-start;gap:14px;margin-bottom:12px}.panel-head p{margin:2px 0 0;color:var(--muted);font-size:10px}.panel-link{margin-left:auto;padding:5px 8px;border:1px solid var(--line);border-radius:6px;color:#9ebee9;text-decoration:none;font-size:9px}.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}.field{display:grid;gap:4px;color:#c9cdd5;font-size:9.5px}.field.full{grid-column:1/-1}.field small{color:#727986;font-size:8px}.input,.field input,.field select,.field textarea{width:100%;padding:7px 8px;border:1px solid var(--line2);border-radius:7px;background:#15171b;color:#dfe2e7;font-size:9.5px}.field textarea{min-height:94px;resize:vertical}.summary-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.summary{padding:11px;border:1px solid var(--line);border-radius:8px;background:#17191e}.summary span{display:block;color:#747b87;font:8px var(--mono);text-transform:uppercase}.summary strong{display:block;margin-top:3px;font-size:12px}.summary p{margin:2px 0 0;color:#8e949f;font-size:8.5px}.scope-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:14px;align-items:center;padding:12px;border:1px solid var(--line);border-radius:8px;background:#17191e}.scope-row+.scope-row{margin-top:8px}.scope-row p{margin:2px 0 0;color:#858c97;font-size:9px}.scope-meta{color:#a7adb7;font:9px var(--mono)}.pill{padding:2px 6px;border:1px solid var(--line2);border-radius:999px;color:#9ea5b0;font:8px var(--mono)}.files{display:grid;gap:7px}.file{display:grid;grid-template-columns:28px minmax(0,1fr) auto;gap:8px;align-items:center;padding:9px;border:1px solid var(--line);border-radius:8px;background:#17191e}.file-icon{display:grid;place-items:center;width:28px;height:28px;border-radius:7px;background:#21252c;color:#98a0ad;font:10px var(--mono)}.file strong{display:block;font-size:10px}.file small{display:block;color:#777e89;font:8px var(--mono)}.file button{padding:4px 7px;border:1px solid var(--line);border-radius:6px;background:#1c1f24;color:#aab0bb;font-size:8px}.danger-zone{margin-top:14px;padding:11px;border:1px solid #593536;border-radius:8px;background:#211719}.danger-zone p{color:#ba9192;font-size:9px}.danger-zone button{padding:5px 8px;border:1px solid #7a4143;border-radius:6px;background:#2a181a;color:#ef9698;font-size:9px}.modal{position:absolute;inset:0;z-index:10;display:grid;place-items:center;background:#07090cba}.modal[hidden]{display:none}.modal-card{width:min(390px,calc(100% - 28px));padding:17px;border:1px solid var(--line2);border-radius:11px;background:#1a1c21;box-shadow:0 24px 70px #0009}.modal-card p{color:var(--muted);font-size:9.5px}.modal-actions{display:flex;justify-content:flex-end;gap:7px;margin-top:14px}.modal-actions button{padding:6px 10px;border:1px solid var(--line2);border-radius:7px;background:#20232a;color:#b9bec7;font-size:9px}.modal-actions .primary{border-color:#39727c;background:#17262a;color:#91dfe7}.more-menu{position:absolute;top:102px;right:18px;z-index:7;width:165px;padding:5px;border:1px solid var(--line2);border-radius:8px;background:#202329;box-shadow:0 15px 35px #0008}.more-menu[hidden]{display:none}.more-menu button{display:block;width:100%;padding:7px 8px;border:0;border-radius:5px;background:transparent;color:#b8bdc6;text-align:left;font-size:9px}.more-menu button:hover{background:#2a2e35}.more-menu .danger{color:#ef8f90}.caption{color:#7f8691;font-size:12px}.flow{display:grid;grid-template-columns:1fr 22px 1fr 22px 1fr;gap:8px;align-items:center;margin:16px 0}.flow-node{padding:13px;border:1px solid var(--line);border-radius:9px;background:var(--surface);text-align:center}.flow-node strong{display:block;font-size:11px}.flow-node span{display:block;color:var(--muted);font-size:9px}.arrow{color:#58616d;text-align:center}.acceptance{padding-left:20px;color:#c5c9d0}.acceptance li+li{margin-top:5px}
@media(max-width:860px){.layer-grid,.choice-grid,.state-grid{grid-template-columns:1fr}.flow{grid-template-columns:1fr}.arrow{transform:rotate(90deg)}}
@media(max-width:700px){.shell{grid-template-columns:1fr}.agent-list{border-right:0;border-bottom:1px solid var(--line)}.agent-list .agent:not(.active){display:none}.proto-global{display:none}.form-grid,.summary-grid{grid-template-columns:1fr}.field.full{grid-column:auto}.detail{padding:14px}.scope-row{grid-template-columns:1fr}.panel-link{display:none}table{display:block;overflow:auto}}
.inline-create{display:flex;gap:5px;margin:0 0 8px}.inline-create[hidden]{display:none}.inline-create form{display:contents}.inline-create input{min-width:0;height:30px;flex:1;padding:0 7px;border:1px solid var(--line2);border-radius:6px;background:#101216;color:var(--text);font-size:9.5px}.inline-create button{width:30px;height:30px;padding:0;border:1px solid var(--line);border-radius:6px;background:#1c2025;color:#aeb4bd}.inline-create .confirm{border-color:#39727c;color:#91dfe7}
</style>
</head>
<body><div class="page">
<nav class="doc-nav" aria-label="Agent 配置设计文档"><a href="./agent-configuration-ui.html" aria-current="page">整体框架</a><a href="./agent-core-configuration-ui.html">基础配置</a><a href="./agent-capability-configuration-ui.html">能力配置</a><a href="./agent-tool-configuration-ui.html">Programs 选择器</a></nav>
<header><div class="eyebrow">OpenProgram · Target design · Framework first</div><h1>Agent 配置框架</h1><p class="lead">Agents页面管理可运行Agent的身份、模型、指令、能力范围和会话策略。Programs、Skills与MCP仍是独立实体目录;Agent只保存对它们的引用和访问策略,不复制实体内容。</p></header>
<section id="scope"><h2>1. 三层职责</h2><div class="layer-grid">
<article class="card"><span class="kicker">Global entities</span><h3>Programs / Skills / MCP</h3><p>系统中实际存在、可安装、可编辑或可连接的能力实体。</p><ul><li>实体源码、schema、连接状态和版本</li><li>由各自的全局页面管理</li><li>不保存某个Agent的模型或会话设置</li></ul></article>
<article class="card"><span class="kicker">Agent configuration</span><h3>Agents</h3><p>某个Agent使用什么模型、指令、能力和会话边界。</p><ul><li>保存实体引用与访问规则</li><li>创建独立workspace与sessions目录</li><li>一个页面内分区编辑,统一保存</li></ul></article>
<article class="card"><span class="kicker">Conversation override</span><h3>当前会话</h3><p>只覆盖本次会话,不改写Agent持久配置。</p><ul><li>临时模型、thinking effort或工具范围</li><li>明确显示“继承Agent”或“已覆盖”</li><li>新会话重新读取Agent配置</li></ul></article>
</div><div class="callout"><strong>边界:</strong>Agent配置不保存120个工具的schema,不复制Skill正文,不保存MCP凭据。Runtime根据Agent规则解析当前可用实体,失效引用在页面中标记,但不静默删除。</div></section>
<section id="ia"><h2>2. 信息架构</h2><table><thead><tr><th>配置区</th><th>用户任务</th><th>真实字段或资源</th><th>下钻文档</th></tr></thead><tbody>
<tr><td>Overview</td><td>识别Agent、设为默认、复制或删除</td><td><code>id</code>、<code>name</code>、<code>default</code>、<code>identity</code>、时间信息</td><td><a href="./agent-core-configuration-ui.html#overview">基础配置</a></td></tr>
<tr><td>Model & Instructions</td><td>选择模型、推理强度和持久指令</td><td><code>model.provider</code>、<code>model.id</code>、<code>thinking_effort</code>、<code>system_prompt</code>、workspace prompt files</td><td><a href="./agent-core-configuration-ui.html#model">基础配置</a></td></tr>
<tr><td>Programs</td><td>决定Agent可发现和调用哪些Programs</td><td><code>tools</code></td><td><a href="./agent-tool-configuration-ui.html">Programs选择器</a></td></tr>
<tr><td>Skills</td><td>允许哪些Skills被发现和加载</td><td><code>skills.disabled</code>、<code>allowed</code>、<code>categories</code></td><td><a href="./agent-capability-configuration-ui.html#skills">能力配置</a></td></tr>
<tr><td>MCP</td><td>允许哪些MCP服务;哪些服务缺失时禁止启动</td><td><code>mcp.disabled</code>、<code>allowed</code>、<code>required</code></td><td><a href="./agent-capability-configuration-ui.html#mcp">能力配置</a></td></tr>
<tr><td>Sessions</td><td>控制联系人隔离、空闲重置、每日重置和workspace</td><td><code>session_scope</code>、<code>session_idle_minutes</code>、<code>session_daily_reset</code>、agent workspace/sessions</td><td><a href="./agent-core-configuration-ui.html#sessions">基础配置</a></td></tr>
</tbody></table><p class="caption">六个配置区保持稳定。以后增加连接器权限、预算或运行限制时,应进入最接近的现有区;只有出现新的持久职责才增加一级分页。</p></section>
<section id="prototype"><h2>3. 整体页面原型</h2><p>下面的原型用于确认页面层级、创建入口、六个配置区、保存状态和生命周期操作。生产实现不得另建一套页面窗口:顶部<code>ManagePageHeader</code>只放页面标题与New / Save操作;点击New后在左侧Agent列表顶部原位显示一行名称输入、取消和确认按钮,不显示backdrop,不要求用户填写Agent ID。后端根据名称生成唯一、稳定的内部ID。六个配置分页属于当前Agent,使用现有<code>Tabs</code>组件放在右侧Agent标题下。左右分栏与列表复用<code>splitBody</code>和<code>ManageRow</code>,右侧详情复用Settings的<code>pageHeader</code>与<code>pageBody</code>。生产页面同时复用全局字体体系:正文、字段和按钮使用<code>--fs-base</code>,辅助说明使用<code>--fs-sm</code>;原型为容纳完整页面而使用的缩放字号不得复制到生产CSS,只有路径、ID等明确元数据可使用等宽字体。</p>
<div class="prototype" id="agent-prototype" data-dirty="false">
<div class="proto-bar"><span class="proto-brand">OpenProgram</span><div class="proto-global" aria-hidden="true"><span>Programs</span><span class="active">Agents</span><span>Skills</span><span>MCP Servers</span></div><span class="dirty">Unsaved changes</span><button class="save" id="save-agent" type="button" disabled>Saved</button></div>
<div class="shell"><aside class="agent-list"><div class="list-head"><strong>Agents</strong><button class="new-agent" id="open-create" type="button">+ New</button></div><div class="inline-create" id="create-modal" hidden><form id="create-form"><input aria-label="Agent name" placeholder="Agent name" required><button type="button" id="cancel-create" aria-label="Cancel">×</button><button class="confirm" type="submit" aria-label="Create Agent">✓</button></form></div><button class="agent active" type="button"><span class="avatar">A</span><span><strong>Default Agent</strong><small>main · default</small></span></button><button class="agent" type="button"><span class="avatar">R</span><span><strong>Research Agent</strong><small>research_agent</small></span></button><button class="agent" type="button"><span class="avatar">G</span><span><strong>GUI Agent</strong><small>gui_agent</small></span></button></aside>
<main class="detail"><div class="detail-head"><span class="avatar">A</span><div><h3>Default Agent</h3><p>main · updated just now</p></div><span class="default-badge">Default</span><button class="more" id="open-more" type="button" aria-label="Agent actions" aria-expanded="false">•••</button></div>
<div class="tabs" role="tablist" aria-label="Agent配置区">
<button class="tab" role="tab" aria-selected="true" aria-controls="panel-overview" tabindex="0" data-panel="overview">Overview</button><button class="tab" role="tab" aria-selected="false" aria-controls="panel-model" tabindex="-1" data-panel="model">Model & Instructions</button><button class="tab" role="tab" aria-selected="false" aria-controls="panel-programs" tabindex="-1" data-panel="programs">Programs</button><button class="tab" role="tab" aria-selected="false" aria-controls="panel-skills" tabindex="-1" data-panel="skills">Skills</button><button class="tab" role="tab" aria-selected="false" aria-controls="panel-mcp" tabindex="-1" data-panel="mcp">MCP</button><button class="tab" role="tab" aria-selected="false" aria-controls="panel-sessions" tabindex="-1" data-panel="sessions">Sessions</button>
</div>
<section class="panel" id="panel-overview" role="tabpanel" data-name="overview"><div class="panel-head"><div><h3>Overview</h3><p>名称、ID、用户可见身份和提及规则。</p></div><a class="panel-link" href="./agent-core-configuration-ui.html#overview">Open detailed design ↗</a></div><div class="form-grid"><label class="field">Display name<input value="Default Agent" data-editable></label><label class="field">Agent ID<input value="main" disabled><small>创建后不可修改。</small></label><label class="field">Channel identity<input value="OpenProgram" data-editable></label><label class="field">Mention patterns<input value="@openprogram, @assistant" data-editable><small>按pattern路由群聊消息。</small></label></div><div class="summary-grid" style="margin-top:12px"><div class="summary"><span>Model</span><strong>MiniMax-M3</strong><p>medium effort</p></div><div class="summary"><span>Programs</span><strong>All Programs</strong><p>schemas on demand</p></div><div class="summary"><span>Session scope</span><strong>Account + channel + peer</strong><p>idle reset: 3 days</p></div></div></section>
<section class="panel" id="panel-model" role="tabpanel" data-name="model" hidden><div class="panel-head"><div><h3>Model & Instructions</h3><p>默认模型与持久指令;会话可临时覆盖。</p></div><a class="panel-link" href="./agent-core-configuration-ui.html#model">Open detailed design ↗</a></div><div class="form-grid"><label class="field">Provider<select data-editable><option>minimax</option><option>openai</option><option>anthropic</option></select></label><label class="field">Model<select data-editable><option>MiniMax-M3</option><option>GPT-5.4</option></select></label><label class="field">Thinking effort<select data-editable><option>Medium</option><option>Low</option><option>High</option></select></label><label class="field full">System prompt<textarea data-editable>Help the user complete tasks using available Programs, Skills, and MCP services.</textarea></label></div></section>
<section class="panel" id="panel-programs" role="tabpanel" data-name="programs" hidden><div class="panel-head"><div><h3>Programs</h3><p>控制可发现和可调用的Functions、Agentic Functions和Applications。</p></div><a class="panel-link" href="./agent-tool-configuration-ui.html">Open Programs selector ↗</a></div><div class="scope-row"><div><h4>All Programs</h4><p>允许全部全局可用Programs;schema按需加载,不写入完整上下文。</p></div><span class="scope-meta">130 available</span></div><div class="scope-row"><div><h4>Conversation override</h4><p>当前会话继承Agent配置,没有临时排除项。</p></div><span class="pill">Inherited</span></div></section>
<section class="panel" id="panel-skills" role="tabpanel" data-name="skills" hidden><div class="panel-head"><div><h3>Skills</h3><p>按类别或名称控制可发现Skills;Skill正文仍存放在Skills目录。</p></div><a class="panel-link" href="./agent-capability-configuration-ui.html#skills">Open detailed design ↗</a></div><div class="scope-row"><div><h4>Discovery mode</h4><p>允许全部Skills,排除3个不适用于默认聊天的运行型Skills。</p></div><span class="scope-meta">42 allowed · 3 excluded</span></div><div class="scope-row"><div><h4>Categories</h4><p>Research、Writing、Code、Media。</p></div><span class="pill">4 categories</span></div></section>
<section class="panel" id="panel-mcp" role="tabpanel" data-name="mcp" hidden><div class="panel-head"><div><h3>MCP</h3><p>控制服务访问范围,并区分“允许”与“运行所必需”。</p></div><a class="panel-link" href="./agent-capability-configuration-ui.html#mcp">Open detailed design ↗</a></div><div class="scope-row"><div><h4>Allowed services</h4><p>filesystem、browser、memory。</p></div><span class="scope-meta">3 connected</span></div><div class="scope-row"><div><h4>Required services</h4><p>没有必需服务;连接失败不会阻止Agent启动。</p></div><span class="pill">None</span></div></section>
<section class="panel" id="panel-sessions" role="tabpanel" data-name="sessions" hidden><div class="panel-head"><div><h3>Sessions</h3><p>会话隔离、重置条件和Agent workspace。</p></div><a class="panel-link" href="./agent-core-configuration-ui.html#sessions">Open detailed design ↗</a></div><div class="form-grid"><label class="field full">Session scope<select data-editable><option>Per account + channel + peer</option><option>Per channel + peer</option><option>Per peer</option><option>Shared main session</option></select></label><label class="field">Idle reset<input value="4320 minutes" data-editable></label><label class="field">Daily reset<input value="Disabled" data-editable></label></div><div class="files" style="margin-top:12px"><div class="file"><span class="file-icon">md</span><span><strong>AGENTS.md</strong><small>workspace/AGENTS.md · instructions</small></span><button type="button">Open</button></div><div class="file"><span class="file-icon">md</span><span><strong>SOUL.md</strong><small>workspace/SOUL.md · persona</small></span><button type="button">Open</button></div></div></section>
</main></div>
<div class="more-menu" id="more-menu" hidden><button type="button">Set as default</button><button type="button">Duplicate Agent</button><button type="button">Open workspace</button><button class="danger" id="delete-agent" type="button">Delete Agent…</button></div>
<div class="modal" id="delete-modal" hidden><div class="modal-card"><h3>Delete Default Agent?</h3><p>删除会永久移除该Agent的配置、workspace和全部sessions。默认Agent必须先切换到另一个Agent。此操作不删除全局Programs、Skills或MCP服务。</p><div class="modal-actions"><button id="cancel-delete" type="button">Cancel</button><button type="button" disabled>Delete unavailable</button></div></div></div>
</div>
</section>
<section id="states"><h2>4. 页面状态与失败行为</h2><div class="state-grid"><article class="card"><span class="kicker">Editing</span><h3>本地草稿</h3><p>任一字段变化后显示Unsaved changes;切换Agent或离开页面前提示保存或放弃。保存请求只发送变更字段。</p></article><article class="card"><span class="kicker">Conflict</span><h3>版本冲突</h3><p>如果配置在其他窗口更新,拒绝覆盖并展示Reload / Review changes。初期后端若无版本字段,需要先补充乐观并发合同。</p></article><article class="card"><span class="kicker">Missing reference</span><h3>实体失效</h3><p>已删除Program、Skill或MCP服务显示Missing,不自动移除引用;用户确认保存后才能清理。</p></article></div><table><thead><tr><th>操作</th><th>预期行为</th></tr></thead><tbody><tr><td>Create Agent</td><td>创建配置、workspace与sessions目录;成功后选中新Agent并停留Overview。失败时保留表单。</td></tr><tr><td>Set as default</td><td>原子更新默认指针;至少保留一个默认Agent。</td></tr><tr><td>Duplicate</td><td>复制配置和workspace模板,不复制sessions、历史消息或凭据。</td></tr><tr><td>Delete</td><td>明确列出将删除的配置、workspace和sessions;默认Agent不可直接删除;删除前要求输入Agent ID。</td></tr><tr><td>Save</td><td>当前分页的修改可以批量保存,但成功后所有分页读取同一AgentSpec版本。</td></tr><tr><td>窄屏</td><td>Agent列表收为顶部选择器;分页可横向滚动;编辑区单列,不出现横向页面滚动。</td></tr></tbody></table></section>
<section id="architecture"><h2>5. 数据与实现边界</h2><div class="flow"><div class="flow-node"><strong>Agents UI</strong><span>six configuration sections</span></div><span class="arrow">→</span><div class="flow-node"><strong>Agent API</strong><span>create / read / patch / default / delete</span></div><span class="arrow">→</span><div class="flow-node"><strong>Agent manager</strong><span>agent.json + workspace + sessions</span></div></div><table><thead><tr><th>责任</th><th>决定</th></tr></thead><tbody><tr><td>持久配置</td><td><code>agent.json</code>保存AgentSpec;workspace文件继续独立保存,避免把大段文件内容塞进AgentSpec。</td></tr><tr><td>实体引用</td><td>Programs、Skills、MCP只保存稳定名称/pattern和policy,不保存schema或凭据。</td></tr><tr><td>运行解析</td><td>每次新会话或配置变更后由统一Runtime registry解析;页面不实现第二套resolver。</td></tr><tr><td>凭据</td><td>Provider与MCP凭据由各自全局配置管理;Agents页面只选择引用,不读取或复制secret。</td></tr><tr><td>历史</td><td>会话历史属于Agent sessions;Programs运行历史属于聊天DAG;配置页只提供进入相应页面的链接。</td></tr></tbody></table></section>
<section id="references"><h2>6. 参考框架比较</h2><table><thead><tr><th>参考</th><th>采用</th><th>调整</th><th>不采用或当前缺失</th></tr></thead><tbody>
<tr><td><a href="https://docs.openclaw.ai/gateway/config-agents">OpenClaw Agent configuration</a>、<a href="https://docs.openclaw.ai/cli/agents">Agents CLI</a></td><td>per-agent workspace、model、skills、tool policy、identity、session scope</td><td>OpenProgram将全局实体目录与Agent访问策略分开,并用六个配置区展示</td><td>bindings/channels编辑器、avatar、archive尚未进入当前AgentSpec</td></tr>
<tr><td><a href="https://docs.openclaw.ai/agent-workspace">OpenClaw workspace</a>、<a href="https://docs.openclaw.ai/agent">Agent runtime</a></td><td>workspace文件与session store分开;bootstrap文件可检查和编辑</td><td>UI明确区分持久system prompt与workspace prompt files</td><td>本设计不把workspace解释为安全sandbox</td></tr>
<tr><td><a href="https://docs.anthropic.com/en/docs/claude-code/cli-usage">Claude Code CLI reference</a></td><td>model、thinking、allowed/disallowed tools和session controls是独立配置职责</td><td>CLI flags转为持久Agent配置与会话级override两层</td><td>max turns、budget、permission mode尚无AgentSpec字段</td></tr>
<tr><td><a href="https://developers.openai.com/codex/config-reference">Codex configuration reference</a></td><td>model/provider、instructions、profiles、MCP等配置职责分区</td><td>OpenProgram围绕可运行Agent实体组织,而不是围绕单个全局配置文件</td><td>hooks、sandbox、project trust和managed requirements不在本次Agent页面范围</td></tr>
</tbody></table></section>
<section id="gaps"><h2>7. 当前实现差距</h2><table><thead><tr><th>能力</th><th>当前状态</th><th>剩余边界</th></tr></thead><tbody><tr><td>Agent列表与读取</td><td class="done">已实现</td><td>加载、空状态与错误状态已进入共享管理页结构</td></tr><tr><td>Programs策略</td><td class="done">已实现</td><td>摘要、按需选择器与统一resolver已接入</td></tr><tr><td>创建Agent</td><td class="done">已实现</td><td>左侧原位名称输入;后端生成唯一ID并bootstrap workspace</td></tr><tr><td>完整编辑</td><td class="done">已实现</td><td>六个配置区共享同一AgentSpec与保存流程</td></tr><tr><td>Skills / MCP</td><td class="done">已实现</td><td>独立分页、实体选择器和missing状态</td></tr><tr><td>Sessions / workspace</td><td class="done">已实现</td><td>scope/reset编辑与workspace文件入口</td></tr><tr><td>设为默认 / 复制 / 删除</td><td class="done">已实现</td><td>生命周期菜单、默认Agent限制与破坏性确认</td></tr><tr><td>并发更新</td><td class="done">已实现</td><td><code>updated_at</code>前置条件拒绝覆盖较新配置</td></tr></tbody></table></section>
<section id="acceptance"><h2>8. 框架验收合同</h2><ol class="acceptance"><li>Agents页面存在一个明确的创建入口;创建成功后可配置全部六个区域。</li><li>Overview、Model & Instructions、Programs、Skills、MCP、Sessions均使用同一Agent ID和同一持久版本,不形成多套配置对象。</li><li>Programs、Skills和MCP实体仍由各自全局页面管理;Agent页面只保存引用与策略。</li><li>完整实体schema、Skill正文和MCP凭据不写入Agent上下文;Runtime按需解析。</li><li>默认Agent、失效引用、未保存修改、保存失败和并发冲突均有独立可见状态。</li><li>删除确认明确说明配置、workspace和sessions会永久删除,且不能直接删除当前默认Agent。</li><li>键盘可用Arrow Left/Right、Home、End切换分页;焦点、保存状态和错误信息可访问。</li><li>窄屏仍可选择Agent、切换分页和完成表单,不依赖hover。</li></ol></section>
<section id="record"><h2>9. 实现与验证记录</h2><table><thead><tr><th>项目</th><th>状态</th><th>证据</th></tr></thead><tbody><tr><td>整体信息架构</td><td class="done">设计完成</td><td>本页六区原型、字段映射和交互合同</td></tr><tr><td>基础配置下钻</td><td class="done">设计完成</td><td><a href="./agent-core-configuration-ui.html">agent-core-configuration-ui.html</a></td></tr><tr><td>能力配置下钻</td><td class="done">设计完成</td><td><a href="./agent-capability-configuration-ui.html">agent-capability-configuration-ui.html</a></td></tr><tr><td>Programs选择器</td><td class="done">设计与实现完成</td><td><a href="./agent-tool-configuration-ui.html">agent-tool-configuration-ui.html</a></td></tr><tr><td>生产实现</td><td class="done">已实现</td><td><code>apps/web/components/agents/agents-page.tsx</code>、<code>agents-page.module.css</code>、<code>openprogram/webui/routes/agents.py</code></td></tr><tr><td>定向验证</td><td class="done">通过</td><td>Agent API 12项、Agents Web合同、Ruff与TypeScript通过;最终App的18100页面显示左栏内联名称输入、无Dialog遮罩,375px视口为单列且无横向溢出</td></tr></tbody></table></section>
</div>
<script>(()=>{const root=document.querySelector('#agent-prototype'),tabs=[...root.querySelectorAll('[role="tab"]')],panels=[...root.querySelectorAll('[role="tabpanel"]')],save=root.querySelector('#save-agent');const select=(tab,focus=false)=>{tabs.forEach(item=>{const on=item===tab;item.setAttribute('aria-selected',String(on));item.tabIndex=on?0:-1});panels.forEach(panel=>panel.hidden=panel.dataset.name!==tab.dataset.panel);if(focus)tab.focus()};tabs.forEach((tab,index)=>{tab.addEventListener('click',()=>select(tab));tab.addEventListener('keydown',event=>{let next=index;if(event.key==='ArrowRight')next=(index+1)%tabs.length;else if(event.key==='ArrowLeft')next=(index-1+tabs.length)%tabs.length;else if(event.key==='Home')next=0;else if(event.key==='End')next=tabs.length-1;else return;event.preventDefault();select(tabs[next],true)})});root.querySelectorAll('[data-editable]').forEach(control=>control.addEventListener('input',()=>{root.dataset.dirty='true';save.disabled=false;save.textContent='Save changes'}));save.addEventListener('click',()=>{root.dataset.dirty='false';save.disabled=true;save.textContent='Saved'});const create=root.querySelector('#create-modal'),openCreate=root.querySelector('#open-create');openCreate.addEventListener('click',()=>{create.hidden=false;create.querySelector('input').focus()});root.querySelector('#cancel-create').addEventListener('click',()=>create.hidden=true);root.querySelector('#create-form').addEventListener('submit',event=>{event.preventDefault();create.hidden=true});const menu=root.querySelector('#more-menu'),more=root.querySelector('#open-more');more.addEventListener('click',()=>{menu.hidden=!menu.hidden;more.setAttribute('aria-expanded',String(!menu.hidden))});const deletion=root.querySelector('#delete-modal');root.querySelector('#delete-agent').addEventListener('click',()=>{menu.hidden=true;deletion.hidden=false});root.querySelector('#cancel-delete').addEventListener('click',()=>deletion.hidden=true);[create,deletion].forEach(modal=>modal.addEventListener('click',event=>{if(event.target===modal)modal.hidden=true}));document.addEventListener('keydown',event=>{if(event.key==='Escape'){create.hidden=true;deletion.hidden=true;menu.hidden=true;more.setAttribute('aria-expanded','false')}})})();</script>
</body></html>