-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathagent-core-configuration-ui.html
More file actions
33 lines (27 loc) · 18.6 KB
/
Copy pathagent-core-configuration-ui.html
File metadata and controls
33 lines (27 loc) · 18.6 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
<!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}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(1160px,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-bottom: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,40px);line-height:1.15}h2{margin:0 0 14px;font-size:23px}h3{margin:0;font-size:16px}h4{margin:0;font-size:12px}.lead{max-width:920px;margin:0;color:#c7cbd3;font-size:16px}section{padding:29px 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}.warning{border-left-color:var(--orange);background:#241d18;color:#d9cabf}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}.prototype{overflow:hidden;margin:17px 0;border:1px solid var(--line);border-radius:12px;background:#0f1013}.proto-head{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line);background:#15171b}.avatar{display:grid;place-items:center;width:34px;height:34px;border:1px solid #3d5660;border-radius:9px;background:#172227;color:var(--cyan);font:12px var(--mono)}.proto-head p{margin:1px 0 0;color:var(--muted);font-size:9px}.saved{margin-left:auto;color:var(--green);font:9px var(--mono)}.proto-tabs{display:flex;gap:3px;padding:0 14px;border-bottom:1px solid var(--line);overflow:auto}.proto-tab{flex:none;padding:10px;border:0;border-bottom:2px solid transparent;background:transparent;color:#818895;font-size:10px}.proto-tab[aria-selected="true"]{border-bottom-color:var(--cyan);color:#edf0f3}.proto-body{padding:16px}.proto-panel[hidden]{display:none}.section-head{display:flex;align-items:flex-start;gap:12px;margin-bottom:13px}.section-head p{margin:2px 0 0;color:var(--muted);font-size:10px}.status{margin-left:auto;padding:2px 7px;border:1px solid var(--line2);border-radius:999px;color:#aeb4bd;font:8px var(--mono)}.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:#737a86;font-size:8px}.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:104px;resize:vertical}.readonly{opacity:.62}.preview{margin-top:12px;padding:11px;border:1px solid var(--line);border-radius:8px;background:#17191e}.preview .label{color:#737a86;font:8px var(--mono);letter-spacing:.06em;text-transform:uppercase}.mention-preview{display:flex;align-items:center;gap:8px;margin-top:8px;padding:8px;border-radius:7px;background:#131519;color:#aeb4bd;font-size:9px}.mention-preview b{color:var(--cyan)}.model-state{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:12px}.model-card{padding:10px;border:1px solid var(--line);border-radius:8px;background:#17191e}.model-card span{display:block;color:#737a86;font:8px var(--mono);text-transform:uppercase}.model-card strong{font-size:10px}.model-card p{margin:3px 0 0;color:#858c97;font-size:8px}.file-list{display:grid;gap:7px;margin-top:12px}.file{display:grid;grid-template-columns:30px 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:30px;height:30px;border-radius:7px;background:#23272e;color:#9ba2ad;font:9px var(--mono)}.file strong{display:block;font-size:10px}.file small{display:block;color:#767d89;font:8px var(--mono)}.file button{padding:4px 7px;border:1px solid var(--line);border-radius:6px;background:#1d2025;color:#aeb4bd;font-size:8px}.scope-options{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}.scope{position:relative;padding:11px 34px 11px 11px;border:1px solid var(--line);border-radius:8px;background:#17191e}.scope:has(input:checked){border-color:#39727c;background:#162126}.scope input{position:absolute;top:12px;right:11px;accent-color:var(--cyan)}.scope strong{display:block;font-size:10px}.scope p{margin:3px 0 0;color:#858c97;font-size:8.5px}.reset-row{display:grid;grid-template-columns:160px minmax(0,1fr);gap:12px;align-items:center;padding:10px 0;border-bottom:1px solid #292d35}.reset-row p{margin:1px 0 0;color:#7d8490;font-size:8px}.session-summary{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:12px}.metric{padding:10px;border:1px solid var(--line);border-radius:8px;background:#17191e}.metric span{display:block;color:#737a86;font:8px var(--mono);text-transform:uppercase}.metric strong{font-size:11px}.danger{margin-top:15px;padding:12px;border:1px solid #593536;border-radius:8px;background:#211719}.danger p{color:#bc9293;font-size:9px}.danger button{padding:5px 8px;border:1px solid #7a4143;border-radius:6px;background:#2a181a;color:#ef9698;font-size:9px}.matrix{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}.note{padding:13px;border:1px solid var(--line);border-radius:9px;background:var(--surface)}.note span{color:var(--cyan);font:9px var(--mono);text-transform:uppercase}.note p{color:var(--muted);font-size:12px}.acceptance{padding-left:20px;color:#c5c9d0}.acceptance li+li{margin-top:5px}@media(max-width:700px){.form-grid,.model-state,.scope-options,.session-summary,.matrix{grid-template-columns:1fr}.field.full{grid-column:auto}.reset-row{grid-template-columns:1fr}.proto-head{align-items:flex-start}.saved{margin-left:auto}table{display:block;overflow:auto}}
</style>
</head>
<body><div class="page">
<nav class="doc-nav" aria-label="Agent 配置设计文档"><a href="./agent-configuration-ui.html">整体框架</a><a href="./agent-core-configuration-ui.html" aria-current="page">基础配置</a><a href="./agent-capability-configuration-ui.html">能力配置</a><a href="./agent-tool-configuration-ui.html">Programs 选择器</a></nav>
<header><div class="eyebrow">Agent configuration · Core</div><h1>身份、模型、指令与会话</h1><p class="lead">本页只定义Agent自身的配置和本地资源。Programs、Skills与MCP的选择规则在能力配置文档中处理,不在这里重复目录。</p></header>
<section id="overview"><h2>1. 基础配置原型</h2><p>点击三个分页查看设计。Overview负责稳定身份和路由标识;Model & Instructions负责推理默认值与持久提示;Sessions负责上下文隔离、重置和workspace入口。</p>
<div class="prototype"><div class="proto-head"><span class="avatar">A</span><div><h3>Default Agent</h3><p>main · default Agent</p></div><span class="saved">Saved</span></div><div class="proto-tabs" role="tablist"><button class="proto-tab" role="tab" aria-selected="true" aria-controls="core-overview" tabindex="0" data-target="core-overview">Overview</button><button class="proto-tab" role="tab" aria-selected="false" aria-controls="core-model" tabindex="-1" data-target="core-model">Model & Instructions</button><button class="proto-tab" role="tab" aria-selected="false" aria-controls="core-sessions" tabindex="-1" data-target="core-sessions">Sessions</button></div><div class="proto-body">
<div class="proto-panel" id="core-overview" role="tabpanel"><div class="section-head"><div><h3>Overview</h3><p>名称与群聊路由身份。</p></div><span class="status">Default</span></div><div class="form-grid"><label class="field">Display name<input value="Default Agent"></label><label class="field readonly">Agent ID<input value="main" disabled><small>文件夹名和持久引用;创建后不可改名。</small></label><label class="field">Channel identity<input value="OpenProgram"><small>Agent在channel消息中的显示名。</small></label><label class="field">Mention patterns<input value="@openprogram, @assistant"><small>支持明确pattern,不自动从Display name推导。</small></label></div><div class="preview"><span class="label">Routing preview</span><div class="mention-preview"><b>@openprogram</b><span>帮我整理今天的研究记录</span><span style="margin-left:auto;color:#78d29e">→ main</span></div></div></div>
<div class="proto-panel" id="core-model" role="tabpanel" hidden><div class="section-head"><div><h3>Model & Instructions</h3><p>Agent默认值;会话覆盖应在聊天输入区显示。</p></div><span class="status">Inherited by new sessions</span></div><div class="form-grid"><label class="field">Provider<select><option>minimax</option><option>openai</option><option>anthropic</option></select></label><label class="field">Model<select><option>MiniMax-M3</option><option>GPT-5.4</option></select></label><label class="field">Thinking effort<select><option>Medium</option><option>Low</option><option>High</option></select><small>只显示当前模型支持的值。</small></label><label class="field full">System prompt<textarea>Help the user complete tasks using the configured Programs, Skills, and MCP services. Ask for clarification only when a missing choice changes the result.</textarea><small>存放简短、稳定的Agent级指令;项目规则仍由workspace文件提供。</small></label></div><div class="model-state"><div class="model-card"><span>Provider health</span><strong>Connected</strong><p>凭据由Provider设置管理。</p></div><div class="model-card"><span>Context source</span><strong>Agent + workspace</strong><p>不复制Skill或Program正文。</p></div><div class="model-card"><span>Conversation</span><strong>No override</strong><p>当前新会话继承这里的值。</p></div></div><div class="file-list"><div class="file"><span class="file-icon">md</span><span><strong>AGENTS.md</strong><small>作用域规则与工作说明</small></span><button type="button">Open</button></div><div class="file"><span class="file-icon">md</span><span><strong>SOUL.md</strong><small>persona与行为边界</small></span><button type="button">Open</button></div><div class="file"><span class="file-icon">md</span><span><strong>USER.md</strong><small>该Agent持久保存的用户上下文</small></span><button type="button">Open</button></div></div></div>
<div class="proto-panel" id="core-sessions" role="tabpanel" hidden><div class="section-head"><div><h3>Sessions</h3><p>决定不同联系人或channel是否共享上下文。</p></div><span class="status">3 active</span></div><div class="scope-options"><label class="scope"><input type="radio" name="scope"><strong>Shared main session</strong><p>所有直接消息共用同一session。只适用于单用户、本地Agent。</p></label><label class="scope"><input type="radio" name="scope"><strong>Per peer</strong><p>同一联系人跨channel共用session。</p></label><label class="scope"><input type="radio" name="scope"><strong>Per channel + peer</strong><p>按channel与联系人隔离。</p></label><label class="scope"><input type="radio" name="scope" checked><strong>Per account + channel + peer</strong><p>按账号、channel和联系人隔离,默认最严格。</p></label></div><div class="reset-row"><div><h4>Idle reset</h4><p>最后活动后多久创建新session。</p></div><label class="field"><input value="4320 minutes"><small>0表示永不按空闲重置。</small></label></div><div class="reset-row"><div><h4>Daily reset</h4><p>本地时区每日切断旧session。</p></div><label class="field"><input placeholder="Disabled or HH:MM" value=""></label></div><div class="session-summary"><div class="metric"><span>Workspace</span><strong>3 prompt files</strong></div><div class="metric"><span>Sessions</span><strong>3 active · 18 total</strong></div><div class="metric"><span>Storage</span><strong>12.4 MB</strong></div></div><div class="danger"><h4>Delete Agent</h4><p>删除Agent会同时删除这个Agent的workspace和全部sessions。全局Programs、Skills、MCP及Provider凭据不受影响。默认Agent必须先切换。</p><button type="button">Delete Agent…</button></div></div>
</div></div>
</section>
<section id="model"><h2>2. 字段与上下文边界</h2><table><thead><tr><th>输入</th><th>保存位置</th><th>进入模型上下文的方式</th></tr></thead><tbody><tr><td>Display name / Agent ID</td><td><code>agent.json</code></td><td>作为运行身份元数据;ID不作为自然语言指令注入。</td></tr><tr><td>Channel identity / mention patterns</td><td><code>agent.json.identity</code></td><td>用于消息路由和外显身份;pattern本身不写入模型提示。</td></tr><tr><td>Provider / model / effort</td><td><code>agent.json</code></td><td>由Runtime创建模型调用时解析;凭据不经过Agent配置。</td></tr><tr><td>System prompt</td><td><code>agent.json.system_prompt</code></td><td>每次新session按固定优先级注入。</td></tr><tr><td>AGENTS.md / SOUL.md / USER.md</td><td><code>agents/<id>/workspace/</code></td><td>按workspace loader规则加载;UI显示来源和最后修改时间。</td></tr><tr><td>Session scope / reset</td><td><code>agent.json</code></td><td>只影响session key与生命周期,不作为提示文本。</td></tr></tbody></table><div class="callout"><strong>优先级:</strong>系统运行约束 → Agent system prompt → workspace规则 → 当前项目规则 → 会话消息。UI只展示OpenProgram实际实现并可追踪的层级,不允许用户通过System prompt编辑系统安全约束。</div></section>
<section id="sessions"><h2>3. 会话和workspace合同</h2><div class="matrix"><article class="note"><span>Workspace</span><h3>可编辑的持久文件</h3><p>显示完整路径、文件用途、最后修改时间和打开入口。workspace是Agent默认工作目录与指令来源,不宣称为安全sandbox。</p></article><article class="note"><span>Sessions</span><h3>独立的运行历史</h3><p>配置页只显示数量、存储占用与“Open sessions”入口。具体消息、DAG和重试仍在Chats页面。</p></article><article class="note"><span>Reset</span><h3>只影响后续路由</h3><p>修改scope或reset不迁移、合并或删除现有session。新消息按新策略选择session,旧session保持可查看。</p></article><article class="note"><span>Delete</span><h3>不可恢复的目录删除</h3><p>删除确认需要显示Agent ID、workspace路径和session数量。默认Agent不可删除;失败后不得部分更新默认指针。</p></article></div></section>
<section id="states"><h2>4. 必须设计的状态</h2><table><thead><tr><th>状态</th><th>页面行为</th></tr></thead><tbody><tr><td>Provider未配置</td><td>模型字段显示Unavailable和Provider设置入口;允许保存其他分页,但Agent状态标记为Cannot start。</td></tr><tr><td>模型已删除或不再支持effort</td><td>保留原值并标记Missing/Unsupported;用户明确选择新值前不自动替换。</td></tr><tr><td>workspace文件缺失</td><td>显示Missing和Create入口;不在读取页面时静默生成。</td></tr><tr><td>workspace文件不可写</td><td>允许只读打开;编辑操作禁用并显示具体路径和系统错误。</td></tr><tr><td>session scope变更</td><td>显示“仅影响后续消息”;不提供自动合并历史。</td></tr><tr><td>保存失败</td><td>保留表单值和dirty状态;错误靠近对应字段,同时在页头提供总错误。</td></tr><tr><td>并发修改</td><td>阻止最后写入覆盖;显示服务端版本与本地变更,不自动合并prompt正文。</td></tr></tbody></table></section>
<section id="api"><h2>5. 最小接口合同</h2><table><thead><tr><th>操作</th><th>接口职责</th><th>非职责</th></tr></thead><tbody><tr><td>Create</td><td>校验ID唯一性,创建agent.json、workspace、sessions和bootstrap文件</td><td>不复制其他Agent的sessions或凭据</td></tr><tr><td>Patch core fields</td><td>校验model、identity与session字段,按版本更新</td><td>不修改Programs、Skills或MCP实体</td></tr><tr><td>Read workspace metadata</td><td>返回允许显示的文件、路径、修改时间、可写状态</td><td>不自动把文件正文并入Agent列表响应</td></tr><tr><td>Set default</td><td>原子切换唯一默认Agent</td><td>不删除旧默认Agent</td></tr><tr><td>Delete</td><td>校验非默认Agent后删除其配置、workspace和sessions</td><td>不删除任何全局能力实体</td></tr></tbody></table></section>
<section id="acceptance"><h2>6. 验收条件</h2><ol class="acceptance"><li>Agent ID创建后只读,Display name和Channel identity可独立编辑。</li><li>模型列表严格由所选Provider返回;凭据只在Provider设置中管理。</li><li>System prompt与workspace文件分开显示、分开保存,页面明确展示上下文来源。</li><li>四种session scope的隔离语义与Runtime现有枚举完全一致。</li><li>修改session策略不迁移或删除历史session。</li><li>删除确认列出workspace和sessions影响,默认Agent不可直接删除。</li><li>所有失败状态保留用户未保存输入,不使用成功toast替代字段错误。</li></ol></section>
</div>
<script>(()=>{const tabs=[...document.querySelectorAll('[role="tab"]')],panels=[...document.querySelectorAll('[role="tabpanel"]')];const select=(tab,focus=false)=>{tabs.forEach(item=>{const active=item===tab;item.setAttribute('aria-selected',String(active));item.tabIndex=active?0:-1});panels.forEach(panel=>panel.hidden=panel.id!==tab.dataset.target);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)})})})();</script>
</body></html>