-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathagent-tool-configuration-ui.html
More file actions
61 lines (56 loc) · 50.1 KB
/
Copy pathagent-tool-configuration-ui.html
File metadata and controls
61 lines (56 loc) · 50.1 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
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Agent 工具配置 — Tools & Programs</title>
<style>
:root{color-scheme:dark;--bg:#121316;--surface:#181a1f;--surface2:#1e2127;--surface3:#24272d;--line:#30343d;--line2:#484e5a;--text:#e8e9ed;--muted:#9ca1ac;--quiet:#777d89;--blue:#79aaff;--cyan:#58cadb;--green:#72d09a;--orange:#ef9b6b;--red:#ed7777;--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.68 var(--sans)}a{color:var(--blue)}code{padding:1px 5px;border-radius:4px;background:#24272e;color:#d9dce4;font:12px var(--mono)}button,select{font:inherit}.page{width:min(1180px,calc(100% - 32px));margin:auto;padding:30px 0 70px}.set-nav{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:22px}.set-nav a{padding:5px 9px;border:1px solid var(--line);border-radius:7px;color:#aeb3bd;text-decoration:none;font-size:12px}.set-nav a[aria-current="page"]{border-color:#39717b;background:#172126;color:#8ddbe6}header{padding-bottom:22px;border-bottom:1px solid var(--line)}.eyebrow{color:var(--cyan);font:11px var(--mono);letter-spacing:.08em;text-transform:uppercase}h1{margin:8px 0 9px;font-size:clamp(27px,4vw,40px);line-height:1.18}h2{margin:0 0 13px;font-size:23px}h3{margin:0;font-size:16px}h4{margin:0;font-size:12px}.lead{max-width:920px;margin:0;color:#c5c8d0;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:#c7d8dc}.warning{border-left-color:var(--orange);background:#241d18;color:#daccc1}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:#bcc0c9}.boundary{display:grid;grid-template-columns:1fr 1fr;gap:12px}.boundary-card{padding:15px;border:1px solid var(--line);border-radius:10px;background:var(--surface)}.boundary-card .label{color:var(--cyan);font:10px var(--mono);letter-spacing:.06em;text-transform:uppercase}.boundary-card p{color:var(--muted);font-size:13px}.boundary-card ul{margin:9px 0 0;padding-left:19px;color:#c2c6ce;font-size:12px}.boundary-card li+li{margin-top:4px}
.prototype{margin:18px 0;overflow:hidden;border:1px solid var(--line);border-radius:12px;background:#0f1013}.agent-shell{display:grid;grid-template-columns:205px minmax(0,1fr);min-height:650px}.agents-list{padding:10px;border-right:1px solid var(--line);background:#15171b}.list-title{display:flex;align-items:center;justify-content:space-between;margin:2px 7px 9px;color:#d5d8df;font-size:11px}.list-title button{border:0;background:transparent;color:var(--cyan);cursor:pointer}.agent-row{display:grid;grid-template-columns:28px minmax(0,1fr);gap:8px;margin:3px 0;padding:8px;border:1px solid transparent;border-radius:7px;color:#aeb3bd}.agent-row.active{border-color:#343842;background:#24272d;color:var(--text)}.agent-avatar{display:grid;place-items:center;width:28px;height:28px;border:1px solid #3d5560;border-radius:8px;background:#172126;color:var(--cyan);font:12px var(--mono)}.agent-row strong{display:block;font-size:11px}.agent-row small{display:block;overflow:hidden;color:#7f8590;font:8.5px var(--mono);text-overflow:ellipsis;white-space:nowrap}.agent-detail{min-width:0;padding:16px}.detail-head{display:flex;align-items:center;gap:10px;padding-bottom:12px;border-bottom:1px solid var(--line)}.detail-head p{margin:1px 0 0;color:var(--muted);font-size:10px}.status{margin-left:auto;padding:2px 7px;border:1px solid #396d4d;border-radius:999px;color:#86d4a3;font:8.5px var(--mono)}.detail-tabs{display:flex;gap:3px;margin:12px 0 14px;border-bottom:1px solid var(--line)}.detail-tab{padding:7px 9px;border-bottom:2px solid transparent;color:#858b96;font-size:10px}.detail-tab.active{border-bottom-color:var(--cyan);color:var(--text)}.section-label{margin:13px 0 7px;color:var(--quiet);font:9px var(--mono);letter-spacing:.06em;text-transform:uppercase}.mode-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:7px}.mode{position:relative;display:block;padding:11px;border:1px solid var(--line);border-radius:8px;background:#17191e;cursor:pointer}.mode:has(input:checked){border-color:#39717b;background:#162126}.mode input{position:absolute;top:11px;right:11px;accent-color:var(--cyan)}.mode strong{display:block;padding-right:23px;font-size:10.5px}.mode span{display:block;margin-top:3px;color:#858b96;font-size:9px;line-height:1.45}.mode:has(input:checked) strong{color:#9de3eb}.policy-row{display:grid;grid-template-columns:145px minmax(0,1fr);gap:10px;align-items:center;padding:9px 0;border-bottom:1px solid #282b32}.policy-row label{font-size:10px}.policy-row select{width:100%;padding:6px 8px;border:1px solid var(--line2);border-radius:6px;background:#17191e;color:#bec3cc;font-size:10px}.summary-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:7px;margin:10px 0}.summary{padding:8px 9px;border:1px solid var(--line);border-radius:7px;background:#17191e}.summary span{display:block;color:#777d89;font:8px var(--mono);text-transform:uppercase}.summary strong{font-size:12px}.scope{display:grid;grid-template-columns:minmax(0,1fr) minmax(225px,.72fr);gap:10px}.scope-list,.prompt-preview{min-width:0;padding:11px;border:1px solid var(--line);border-radius:8px;background:#15171b}.group+.group{margin-top:9px}.group-head{display:flex;justify-content:space-between;margin-bottom:4px;color:#aeb3bd;font-size:9px}.group-head span{color:#777d89;font:8px var(--mono)}.program{display:grid;grid-template-columns:17px minmax(0,1fr) auto;gap:7px;align-items:center;padding:6px 7px;border-radius:6px;color:#aeb3bd;font-size:9.5px}.program:hover{background:#202329}.program input{accent-color:var(--cyan)}.program small{color:#777d89;font:8px var(--mono)}.program[data-disabled="true"]{opacity:.48}.prompt-preview h4{margin-bottom:7px}.context-item{display:grid;grid-template-columns:14px minmax(0,1fr);gap:6px;padding:6px 0;border-bottom:1px solid #282b32;color:#aeb3bd;font-size:9px}.context-item:last-child{border-bottom:0}.context-item b{color:var(--green)}.context-item.no b{color:var(--red)}.context-note{margin-top:8px;color:#777d89;font-size:8.5px}
.access-summary{padding:16px;border:1px solid var(--line);border-radius:10px;background:#17191e}.access-head{display:flex;align-items:flex-start;gap:14px;padding-bottom:13px;border-bottom:1px solid #2b2f37}.access-head h4{font-size:15px}.access-head p{max-width:590px;margin:3px 0 0;color:var(--muted);font-size:10px}.access-stats{display:flex;gap:18px;margin-left:auto}.access-stat{min-width:68px}.access-stat span{display:block;color:var(--quiet);font:8px var(--mono);letter-spacing:.04em;text-transform:uppercase}.access-stat strong{display:block;margin-top:2px;color:#d9dce3;font-size:12px}.scope-accordion{display:grid;gap:7px;margin:12px 0}.scope-section{overflow:hidden;padding:0;border:1px solid #2d323a;border-radius:8px;background:#14171b}.scope-summary{display:grid;width:100%;grid-template-columns:16px 28px minmax(0,1fr) auto;gap:8px;align-items:center;padding:9px;border:0;background:transparent;color:inherit;text-align:left;cursor:pointer}.scope-disclosure{display:grid;place-items:center;width:16px;height:16px;color:#777e88;font-size:9px;transition:transform .18s ease}.scope-section.open>.scope-summary .scope-disclosure{transform:rotate(90deg)}.scope-icon{display:grid;place-items:center;width:27px;height:27px;border-radius:7px;background:#20242a;color:#9ca3ae;font:11px var(--mono)}.scope-copy strong{display:block;font-size:10px}.scope-copy small{display:block;color:var(--quiet);font-size:8px}.scope-count{color:#c9cdd5;font:10px var(--mono)}.scope-panel{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .22s ease,opacity .14s ease}.scope-section.open>.scope-panel{grid-template-rows:1fr;opacity:1}.scope-panel-inner{min-height:0;overflow:hidden}.inline-workflow-panel{display:grid;grid-template-columns:225px minmax(0,1fr);border-top:1px solid #2d323a}.inline-workflow-list{padding:8px;border-right:1px solid #2d323a;background:#121418}.inline-workflow-row{display:grid;width:100%;grid-template-columns:8px minmax(0,1fr) auto;gap:7px;align-items:center;padding:7px;border:0;border-radius:6px;background:transparent;color:#959ba6;font-size:8.5px;text-align:left;cursor:pointer}.inline-workflow-row:hover{background:#1c1f24}.inline-workflow-row.active{background:#20262b;color:#d5d8dd}.inline-workflow-row .dot{width:6px;height:6px;border-radius:50%;background:#5f6873}.inline-workflow-row.active .dot{background:var(--cyan)}.inline-workflow-row small{color:#707782;font:7px var(--mono)}.inline-workflow-preview{min-width:0;padding:10px 12px}.inline-preview-head{display:flex;align-items:flex-start;margin-bottom:8px}.inline-preview-head strong{font-size:10px}.inline-preview-head p{margin:2px 0 0;color:#858c97;font-size:8px}.inline-preview-head span{margin-left:auto;color:#86d4a3;font:7.5px var(--mono)}.inline-preview-meta{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:8px}.inline-preview-meta span{padding:2px 5px;border:1px solid #30353d;border-radius:999px;color:#868d98;font:7px var(--mono)}.loading-policy{display:flex;align-items:center;gap:10px;padding:10px;border:1px solid #2d323a;border-radius:8px;background:#14171b}.loading-policy strong{font-size:9.5px}.loading-policy span{display:block;color:var(--quiet);font-size:8.5px}.loading-values{display:flex;gap:14px;margin-left:auto}.loading-value{color:#aeb4be;font:9px var(--mono);white-space:nowrap}.manage-access,.primary-action,.secondary-action{border:1px solid #39717b;border-radius:7px;background:#172126;color:#8ddbe6;cursor:pointer;font-size:10px}.manage-access{flex:none;padding:8px 11px}.picker-sheet{position:absolute;padding:0;border-bottom:0;inset:0 0 0 205px;display:grid;grid-template-rows:auto auto minmax(0,1fr);z-index:5;background:#111317;box-shadow:-12px 0 30px #05060788}.picker-sheet[hidden]{display:none}.picker-head{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--line)}.picker-head h3{font-size:14px}.picker-head p{margin:0;color:var(--quiet);font-size:9px}.picker-head .secondary-action{margin-left:auto;padding:6px 9px;border-color:var(--line2);background:#1a1c21;color:#adb2bc}.picker-controls{display:flex;gap:8px;padding:10px 16px;border-bottom:1px solid var(--line)}.picker-controls input{min-width:0;flex:1;padding:7px 9px;border:1px solid var(--line2);border-radius:7px;background:#17191e;color:var(--text);font-size:10px}.picker-tabs{display:flex;gap:3px}.picker-tabs button{padding:6px 8px;border:0;border-radius:6px;background:transparent;color:#858b96;font-size:9px}.picker-tabs button.active{background:#262a31;color:#e5e7eb}.picker-body{min-height:0;display:grid;grid-template-columns:150px minmax(0,1fr)}.picker-sources{padding:10px;border-right:1px solid var(--line);background:#15171b}.picker-source{display:flex;width:100%;justify-content:space-between;padding:7px;border:0;border-radius:6px;background:transparent;color:#979da8;font-size:9px}.picker-source.active{background:#25282f;color:#e3e5e9}.picker-results{padding:12px 16px;overflow:auto}.picker-results-head{display:flex;align-items:center;margin-bottom:8px}.picker-results-head span{margin-left:auto;color:var(--quiet);font:8px var(--mono)}.picker-group{margin-bottom:6px;border:1px solid var(--line);border-radius:7px;overflow:hidden}.picker-group summary{display:flex;align-items:center;padding:8px 10px;background:#181a1f;cursor:pointer;font-size:9.5px}.picker-group summary span{margin-left:auto;color:var(--quiet)}.picker-row{display:grid;grid-template-columns:18px minmax(0,1fr);gap:7px;padding:8px 10px;border-top:1px solid #282b32;font-size:9px}.picker-row small{display:block;color:var(--quiet);font-size:8px}.prototype{position:relative}
.picker-filter{display:flex;align-items:center;gap:6px;color:#8e949f;font-size:9px;white-space:nowrap}.picker-filter input{accent-color:var(--cyan)}.picker-stage{min-width:0;min-height:0;overflow:hidden}.source-panel{height:100%;padding:0;border-bottom:0;overflow:auto}.source-panel[hidden]{display:none}.workflow-browser{display:grid;grid-template-columns:280px minmax(0,1fr);height:100%;overflow:hidden}.workflow-list{min-width:0;overflow:auto;border-right:1px solid var(--line);background:#131519}.workflow-list-head{display:flex;align-items:end;justify-content:space-between;padding:13px 12px 8px}.workflow-list-head strong{font-size:11px}.workflow-list-head span{color:var(--quiet);font:8px var(--mono)}.workflow-row{display:grid;grid-template-columns:18px minmax(0,1fr);gap:7px;margin:2px 7px;padding:9px;border:1px solid transparent;border-radius:7px;cursor:pointer}.workflow-row:hover{background:#1d2025}.workflow-row.active{border-color:#37434a;background:#20262b}.workflow-row input{margin-top:3px;accent-color:var(--cyan)}.workflow-row strong{display:block;color:#d2d5dc;font-size:9.5px}.workflow-row p{margin:2px 0;color:#898f9a;font-size:8.5px;line-height:1.4}.workflow-row small{display:flex;gap:7px;margin-top:5px;color:#747b86;font:7.8px var(--mono)}.workflow-row .issue{color:var(--orange)}.workflow-inspector{min-width:0;overflow:auto;padding:15px 16px;background:#111317}.inspector-head{display:flex;align-items:flex-start;gap:9px;padding-bottom:12px;border-bottom:1px solid var(--line)}.inspector-icon{display:grid;place-items:center;width:32px;height:32px;border:1px solid #38545c;border-radius:8px;background:#172126;color:var(--cyan)}.inspector-title{min-width:0}.inspector-title h4{font-size:13px}.inspector-title p{margin:2px 0 0;color:#9298a3;font-size:8.5px}.selected-state{margin-left:auto;color:#86d4a3;font:8px var(--mono)}.workflow-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin:11px 0}.workflow-fact{padding:8px;border:1px solid #2b2f37;border-radius:7px;background:#17191e}.workflow-fact span{display:block;color:var(--quiet);font:7.5px var(--mono);text-transform:uppercase}.workflow-fact code{display:block;margin-top:3px;padding:0;background:transparent;color:#c8ccd4;font-size:8.5px;white-space:normal}.inspector-section{margin-top:12px}.inspector-section-head{display:flex;align-items:center;margin-bottom:6px}.inspector-section-head strong{font-size:9.5px}.inspector-section-head span{margin-left:auto;color:var(--quiet);font:7.5px var(--mono)}.composition{padding:9px;border:1px solid #2b2f37;border-radius:8px;background:#15171b}.composition-node{position:relative}.composition-node.child{margin-left:21px}.composition-node.child:before{content:"";position:absolute;left:-13px;top:-6px;width:10px;height:19px;border-left:1px solid #3b4049;border-bottom:1px solid #3b4049}.composition-row{display:grid;grid-template-columns:16px minmax(0,1fr) auto;gap:7px;align-items:center;min-height:25px;padding:0 4px;border:1px solid transparent;border-radius:5px;color:#aeb3bd;font-size:8.5px;transition:background-color .16s ease,border-color .16s ease}.composition-node.open>.composition-row{border-color:#303a40;background:#1b2226;color:#d4d7dc}.composition-row em{color:#747b86;font:7px var(--mono);font-style:normal}.composition-leaf,.composition-toggle{display:grid;place-items:center;width:16px;height:16px;color:#858c97;font:8px var(--mono)}.composition-toggle{padding:0;border:1px solid #49505a;border-radius:50%;background:#17191e;cursor:pointer;transition:border-color .16s ease,background-color .16s ease,color .16s ease}.composition-toggle:before{content:"+"}.composition-node.open>.composition-row .composition-toggle{border-color:#39717b;background:#17262b;color:#82d7e2}.composition-node.open>.composition-row .composition-toggle:before{content:"−"}.composition-children{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .2s ease,opacity .14s ease}.composition-node.open>.composition-children{grid-template-rows:1fr;opacity:1}.composition-children-inner{min-height:0;overflow:hidden;margin-left:7px;padding-left:18px;border-left:1px solid #3b4049}.composition-child-row{display:grid;grid-template-columns:16px minmax(0,1fr) auto;gap:7px;align-items:center;min-height:24px;color:#9fa5af;font-size:8px}.composition-child-row em{color:#6f7680;font:7px var(--mono);font-style:normal}.composition-more{margin:3px 0 4px 23px;color:#69717c;font:7px var(--mono)}@media(prefers-reduced-motion:reduce){.composition-row,.composition-toggle,.composition-children{transition-duration:.01ms}}.dependency-chips{display:flex;flex-wrap:wrap;gap:5px}.dependency-chip{padding:3px 6px;border:1px solid #313640;border-radius:999px;color:#9ca2ad;font:7.8px var(--mono)}.exposure-note{padding:8px 9px;border-left:2px solid #39717b;background:#162126;color:#9daab0;font-size:8px}.inspector-actions{display:flex;gap:6px;margin-top:12px}.inspector-actions .secondary-action{padding:6px 8px}.source-simple{padding:13px 16px}.source-simple .picker-group{max-width:620px}@media(max-width:960px){.workflow-browser{grid-template-columns:235px minmax(0,1fr)}.workflow-facts{grid-template-columns:1fr}}@media(max-width:760px){.workflow-browser{grid-template-columns:1fr;overflow:auto}.workflow-list{max-height:250px;border-right:0;border-bottom:1px solid var(--line)}.workflow-inspector{overflow:visible}}
.resolver{display:grid;grid-template-columns:1fr 20px 1fr 20px 1fr 20px 1fr;gap:6px;align-items:center;margin:18px 0}.resolve-node{min-width:0;padding:12px;border:1px solid var(--line);border-radius:8px;background:var(--surface);text-align:center}.resolve-node strong{display:block;font-size:11px}.resolve-node span{display:block;color:var(--muted);font-size:9px}.arrow{color:#59616d;text-align:center}.status-table .done{color:var(--green)}.status-table .target{color:var(--orange)}.acceptance{padding-left:21px;color:#c4c8d0}.acceptance li+li{margin-top:5px}
@media(max-width:820px){.scope{grid-template-columns:1fr}.resolver{grid-template-columns:1fr}.arrow{transform:rotate(90deg)}}
@media(max-width:760px){.inline-workflow-panel{grid-template-columns:1fr}.inline-workflow-list{border-right:0;border-bottom:1px solid #2d323a}.access-head{flex-wrap:wrap}.access-stats{width:100%;margin-left:0}.loading-policy{align-items:flex-start;flex-direction:column}.loading-values{margin-left:0}}@media(max-width:680px){.boundary,.mode-grid,.summary-grid{grid-template-columns:1fr}.agent-shell{grid-template-columns:1fr}.agents-list{border-right:0;border-bottom:1px solid var(--line)}.policy-row{grid-template-columns:1fr}table{display:block;overflow:auto}.picker-sheet{inset:0}}
.inline-create-agent{display:flex;gap:5px;margin:0 0 8px}.inline-create-agent[hidden]{display:none}.inline-create-agent input{min-width:0;height:29px;flex:1;padding:0 7px;border:1px solid var(--line2);border-radius:6px;background:#101216;color:var(--text);font-size:9px}.inline-create-agent button{height:29px;padding:0 7px;border:1px solid var(--line);border-radius:6px;background:#1c2025;color:#aeb4bd;font-size:9px}.inline-create-agent .confirm{border-color:#39717b;color:#8ddbe6}
</style>
</head>
<body><div class="page">
<nav class="set-nav" aria-label="Agent 配置设计文档"><a href="./agent-configuration-ui.html">整体框架</a><a href="./agent-core-configuration-ui.html">基础配置</a><a href="./agent-capability-configuration-ui.html">能力配置</a><a href="./agent-tool-configuration-ui.html" aria-current="page">Programs 选择器</a></nav>
<header><div class="eyebrow">OpenProgram · Target UI · Programs section</div><h1>Agent Programs 配置:与实体目录分开</h1><p class="lead">本页是完整<a href="./agent-configuration-ui.html">Agent配置框架</a>中的Programs下钻设计。Programs回答“系统中存在哪些可调用实体”;Agents回答“某个Agent允许发现和调用哪些实体”。页面与数据归属分开,实际调用仍使用同一套AgentTool registry、resolver和executor。</p></header>
<section id="boundary"><h2>1. 页面与数据边界</h2>
<div class="boundary"><div class="boundary-card"><span class="label">Programs · entity catalog</span><h3>管理实体</h3><p>Functions(Vanilla / Agentic)、Workflows和Applications是系统中的可调用对象。</p><ul><li>源码、export、schema、Git状态和测试</li><li>静态Calls / Used by关系</li><li>安装、编辑、收藏、运行和删除</li></ul></div><div class="boundary-card"><span class="label">Agents · configuration</span><h3>管理使用策略</h3><p>Agent配置决定模型、指令、Skills、MCP及允许访问的Programs。</p><ul><li>默认访问模式和可复用Access preset</li><li>允许、排除和全局不可用项</li><li>首轮上下文与按需发现策略</li></ul></div></div>
<div class="callout"><strong>不复制实体:</strong>Agent配置只保存工具访问意图或工具名引用,不复制Program schema、description、Python源码或Workflow仓库。删除或禁用Program后,所有Agent在下一次解析时得到一致结果。</div>
</section>
<section id="prototype"><h2>2. Agents 配置页面原型</h2>
<p>主页面只承担Agent选择、配置分页、访问模式和当前范围摘要。外层页面复用现有Web管理页与Settings结构,不另建Agent专用窗口;全局标题栏只放页面级操作,配置分页位于选中Agent的详情标题下。页面字体直接使用Web全局<code>--fs-base</code>/<code>--fs-sm</code>层级,不从缩放原型复制8–12px的局部字号。工具目录是一个按需打开的选择器,不随Agent详情常驻渲染;新增Agent由共享管理页标题栏提供。</p>
<div class="prototype" aria-label="Agent Tools and Programs 配置页面原型">
<div class="agent-shell">
<aside class="agents-list"><div class="list-title"><strong>Agents</strong><button id="new-agent" type="button" aria-label="新建Agent">+ New</button></div><form class="inline-create-agent" id="create-agent" hidden><input id="agent-name" aria-label="Agent name" placeholder="Agent name" value="Research Agent"><button id="cancel-create" type="button">Cancel</button><button class="confirm" id="confirm-create" type="button">Create</button></form><div class="agent-row active"><span class="agent-avatar">A</span><span><strong>Default Agent</strong><small>all programs</small></span></div><div class="agent-row"><span class="agent-avatar">R</span><span><strong>research_agent</strong><small>preset: research</small></span></div><div class="agent-row"><span class="agent-avatar">G</span><span><strong>gui_agent</strong><small>selected scope</small></span></div></aside>
<main class="agent-detail"><div class="detail-head"><span class="agent-avatar">A</span><div><h3>Default Agent</h3><p>默认聊天Agent · Local instance</p></div><span class="status">Saved</span></div><div class="detail-tabs" aria-label="Agent配置分页"><span class="detail-tab">Overview</span><span class="detail-tab">Model & Instructions</span><span class="detail-tab active">Programs</span><span class="detail-tab">Skills</span><span class="detail-tab">MCP</span><span class="detail-tab">Sessions</span></div>
<div class="section-label">Access mode</div><div class="mode-grid" id="access-modes"><label class="mode"><input type="radio" name="mode" value="automatic" checked><strong>All Programs</strong><span>允许使用全部Functions、Workflows和Applications;不把完整清单写入上下文。</span></label><label class="mode"><input type="radio" name="mode" value="selected"><strong>Selected scope</strong><span>只允许Access preset或手动选择的Programs。</span></label><label class="mode"><input type="radio" name="mode" value="none"><strong>No Programs</strong><span>仅保留不依赖Program registry的基础对话能力。</span></label></div>
<div class="section-label">Effective Program access</div><div class="access-summary"><div class="access-head"><div><h4 id="access-title">All Programs</h4><p id="access-description">此Agent可以发现全部全局Programs;单独禁用项会从结果中排除。</p></div><div class="access-stats"><div class="access-stat"><span>Allowed</span><strong id="discoverable-count">77</strong></div><div class="access-stat"><span>Excluded</span><strong id="excluded-count">0</strong></div></div><button class="manage-access" id="manage-access" type="button">Edit access…</button></div><div class="scope-accordion" aria-label="按Program类型显示有效访问范围"><section class="scope-section"><button class="scope-summary" type="button" data-scope-toggle aria-expanded="false"><span class="scope-disclosure">›</span><span class="scope-icon">ƒ</span><span class="scope-copy"><strong>Functions</strong><small>Vanilla 60 · Agentic 10</small></span><span class="scope-count" id="functions-count">70 / 70</span></button><div class="scope-panel"><div class="scope-panel-inner"></div></div></section><section class="scope-section open"><button class="scope-summary" type="button" data-scope-toggle aria-expanded="true"><span class="scope-disclosure">›</span><span class="scope-icon">◇</span><span class="scope-copy"><strong>Workflows</strong><small>Reusable workflow projects</small></span><span class="scope-count" id="workflows-count">4 / 4</span></button><div class="scope-panel"><div class="scope-panel-inner"><div class="inline-workflow-panel"><div class="inline-workflow-list"><button class="inline-workflow-row active" type="button" data-inline-workflow="literature_review"><span class="dot"></span><span>literature_review</span><small>validated</small></button><button class="inline-workflow-row" type="button" data-inline-workflow="paper_search"><span class="dot"></span><span>paper_search</span><small>validated</small></button><button class="inline-workflow-row" type="button" data-inline-workflow="paper_screening"><span class="dot"></span><span>paper_screening</span><small>stale</small></button><button class="inline-workflow-row" type="button" data-inline-workflow="research_synthesis"><span class="dot"></span><span>research_synthesis</span><small>modified</small></button></div><div class="inline-workflow-preview"><div class="inline-preview-head"><div><strong id="inline-workflow-name">literature_review</strong><p id="inline-workflow-description">检索、筛选并整理近期论文。</p></div><span>Allowed</span></div><div class="inline-preview-meta" id="inline-workflow-meta"><span>3 direct calls</span><span>12 Functions</span><span>1 Workflow</span></div><div class="composition static-composition" id="inline-workflow-composition"><div class="composition-node"><div class="composition-row"><span class="composition-leaf">◇</span><strong>literature_review</strong><em>workflow</em></div></div><div class="composition-node child"><div class="composition-row"><span class="composition-leaf">◎</span><strong>collect_papers</strong><em>goal</em></div></div><div class="composition-node child open"><div class="composition-row"><button class="composition-toggle" type="button" aria-label="收起 paper_screening" aria-expanded="true"></button><strong>paper_screening</strong><em>workflow</em></div><div class="composition-children"><div class="composition-children-inner"><div class="composition-child-row"><span class="composition-leaf">◎</span><strong>apply_criteria</strong><em>goal</em></div><div class="composition-child-row"><span class="composition-leaf">ƒ</span><strong>score_relevance</strong><em>function</em></div><div class="composition-child-row"><span class="composition-leaf">A</span><strong>review_ambiguous</strong><em>agent</em></div><div class="composition-more">deeper internals remain in Programs</div></div></div></div><div class="composition-node child"><div class="composition-row"><span class="composition-leaf">◎</span><strong>synthesize_results</strong><em>goal</em></div></div></div></div></div></div></div></section><section class="scope-section"><button class="scope-summary" type="button" data-scope-toggle aria-expanded="false"><span class="scope-disclosure">›</span><span class="scope-icon">⌘</span><span class="scope-copy"><strong>Applications</strong><small>Complete application packages</small></span><span class="scope-count" id="applications-count">3 / 3</span></button><div class="scope-panel"><div class="scope-panel-inner"></div></div></section></div><div class="loading-policy"><div><strong>Model context</strong><span id="loading-description">只常驻核心工具schema;其余Programs由tool_search按需加载。</span></div><div class="loading-values"><span class="loading-value">8 resident schemas</span><span class="loading-value" id="searchable-count">69 searchable</span></div></div></div>
</main>
</div>
<section class="picker-sheet" id="program-picker" hidden aria-label="Program选择器"><div class="picker-head"><div><h3>Select Programs</h3><p>77 available · changes apply to Default Agent</p></div><button class="secondary-action" id="close-picker" type="button">Done</button></div><div class="picker-controls"><input type="search" placeholder="Search by name, capability, input or dependency…"><label class="picker-filter"><input type="checkbox">Selected only</label><label class="picker-filter"><input type="checkbox">Issues only</label></div><div class="picker-body"><nav class="picker-sources" aria-label="Program类型"><button class="picker-source" data-picker-source="functions" type="button"><span>Functions</span><span>70</span></button><button class="picker-source active" data-picker-source="workflows" type="button"><span>Workflows</span><span>4</span></button><button class="picker-source" data-picker-source="applications" type="button"><span>Applications</span><span>3</span></button></nav><div class="picker-stage"><section class="source-panel source-simple" data-source-panel="functions" hidden><div class="picker-results-head"><strong>Functions</strong><span>70 selected</span></div><details class="picker-group" open><summary><strong>Vanilla Functions</strong><span>60</span></summary><label class="picker-row"><input type="checkbox" checked><span><strong>read</strong><small>Read a local file.</small></span></label><label class="picker-row"><input type="checkbox" checked><span><strong>bash</strong><small>Execute a shell command.</small></span></label></details><details class="picker-group"><summary><strong>Agentic Functions</strong><span>10</span></summary></details></section><section class="source-panel workflow-browser" data-source-panel="workflows"><div class="workflow-list"><div class="workflow-list-head"><strong>Workflows</strong><span>4 selected</span></div><div class="workflow-row active" data-workflow="literature_review"><input type="checkbox" checked aria-label="允许literature_review"><span><strong>literature_review</strong><p>检索、筛选并整理近期论文。</p><small><span>3 direct calls</span><span>validated</span></small></span></div><div class="workflow-row" data-workflow="paper_search"><input type="checkbox" checked aria-label="允许paper_search"><span><strong>paper_search</strong><p>跨来源检索论文并去重。</p><small><span>8 functions</span><span>validated</span></small></span></div><div class="workflow-row" data-workflow="paper_screening"><input type="checkbox" checked aria-label="允许paper_screening"><span><strong>paper_screening</strong><p>按研究标准筛选候选论文。</p><small><span>2 goals</span><span class="issue">test stale</span></small></span></div><div class="workflow-row" data-workflow="research_synthesis"><input type="checkbox" checked aria-label="允许research_synthesis"><span><strong>research_synthesis</strong><p>根据结构化证据生成研究脉络。</p><small><span>1 workflow</span><span class="issue">modified</span></small></span></div></div><aside class="workflow-inspector" aria-live="polite"><div class="inspector-head"><span class="inspector-icon">◇</span><div class="inspector-title"><h4 id="workflow-detail-name">literature_review</h4><p id="workflow-detail-description">检索、筛选并整理近期论文的可复用 Workflow。</p></div><span class="selected-state">Allowed</span></div><div class="workflow-facts"><div class="workflow-fact"><span>Entry</span><code id="workflow-detail-entry">literature_review(task: str)</code></div><div class="workflow-fact"><span>Input → Output</span><code id="workflow-detail-io">research task → report path</code></div><div class="workflow-fact"><span>Validation</span><code id="workflow-detail-validation">HEAD clean · 18 tests passed</code></div><div class="workflow-fact"><span>Source</span><code id="workflow-detail-source">programs/workflows/literature_review</code></div></div><div class="inspector-section"><div class="inspector-section-head"><strong>Direct composition</strong><span>one level</span></div><div class="composition" id="workflow-detail-composition"><div class="composition-row"><span>◇</span><strong>literature_review</strong><em>workflow</em></div><div class="composition-row child"><span>◎</span><strong>collect_papers</strong><em>goal</em></div><div class="composition-row child"><span>◇</span><strong>paper_screening</strong><em>workflow</em></div><div class="composition-row child"><span>◎</span><strong>synthesize_results</strong><em>goal</em></div></div></div><div class="inspector-section"><div class="inspector-section-head"><strong>Dependencies</strong><span>direct only</span></div><div class="dependency-chips" id="workflow-detail-dependencies"><span class="dependency-chip">12 Functions</span><span class="dependency-chip">1 Workflow</span><span class="dependency-chip">2 Agentic</span></div></div><div class="inspector-section"><div class="inspector-section-head"><strong>Model exposure</strong></div><div class="exposure-note">Agent只获得名称、description和入口schema。内部Goal、Agent、LLM及依赖结构在选择或执行后按需读取,不写入首轮上下文。</div></div><div class="inspector-actions"><button class="secondary-action" type="button">Open in Programs ↗</button><button class="secondary-action" type="button">View full graph ↗</button></div></aside></section><section class="source-panel source-simple" data-source-panel="applications" hidden><div class="picker-results-head"><strong>Applications</strong><span>3 selected</span></div><details class="picker-group" open><summary><strong>Installed Applications</strong><span>3</span></summary><label class="picker-row"><input type="checkbox" checked><span><strong>gui_agent</strong><small>Desktop interaction application.</small></span></label><label class="picker-row"><input type="checkbox" checked><span><strong>research_agent</strong><small>Research workflow application.</small></span></label></details></section></div></div></section>
</div>
<div class="callout"><strong>页面容量边界:</strong>Agent详情页把Functions、Workflows和Applications显示为纵向折叠区,而不是三个静态卡片。展开Workflows后,当前允许的Workflow列表和一层组合预览直接出现在主页面;<code>Edit access…</code>只负责搜索和修改授权。子Workflow可再原位展开一层,更深结构通过Programs完整图查看。</div>
</section>
<section id="runtime"><h2>3. 一个运行时解析链</h2>
<p>拆分的是产品页面和配置归属,不是执行语义。持久Agent配置与会话临时覆盖都进入现有统一resolver。</p>
<div class="resolver" aria-label="统一工具解析流程"><div class="resolve-node"><strong>Programs registry</strong><span>真实实体与全局状态</span></div><span class="arrow">∩</span><div class="resolve-node"><strong>AgentSpec.tools</strong><span>持久访问策略</span></div><span class="arrow">∩</span><div class="resolve-node"><strong>Session override</strong><span>可选临时覆盖</span></div><span class="arrow">→</span><div class="resolve-node"><strong>resolve_tools()</strong><span>resident + scoped search</span></div></div>
<table><thead><tr><th>阶段</th><th>目标行为</th></tr></thead><tbody><tr><td>Agent保存</td><td><code>AgentSpec.tools</code>保存mode、preset引用及显式allow/deny;不保存展开后的schema快照。</td></tr><tr><td>会话开始</td><td>默认使用当前Agent配置;composer中的Tools选择仅作为该会话或该轮override。</td></tr><tr><td>模型上下文</td><td>提供resident schemas、<code>tool_search</code>和数量提示,不列出所有延迟Program名称。</td></tr><tr><td>按需检索</td><td><code>tool_search</code>只搜索统一resolver计算后的允许集合,并返回少量匹配schema。</td></tr><tr><td>调用</td><td>Function、Workflow和Application最终统一进入现有AgentTool executor;页面拆分不增加第二套调用路径。</td></tr></tbody></table>
</section>
<section id="status"><h2>4. 当前实现与目标差异</h2>
<table class="status-table"><thead><tr><th>能力</th><th>状态</th><th>实现边界</th></tr></thead><tbody><tr><td><code>AgentSpec.tools</code>配置字段</td><td class="done">已实现</td><td>保存automatic、selected或none策略。</td></tr><tr><td>统一<code>resolve_tools()</code></td><td class="done">已实现</td><td>会话override高于Agent配置,执行器未分叉。</td></tr><tr><td>Programs实体管理页</td><td class="done">已实现</td><td>显示Functions、Workflows、Applications和独立Favorites视图。</td></tr><tr><td>Agents管理与编辑页</td><td class="done">已实现</td><td>六个配置分页共用同一AgentSpec;主页面仅显示能力策略摘要。</td></tr><tr><td>创建Agent</td><td class="done">已实现</td><td>左侧列表使用单行名称输入;后端自动生成唯一内部ID,不显示全屏遮罩。</td></tr><tr><td>按需Program选择器</td><td class="done">已实现</td><td>点击Browse programs后才请求目录、分类和preset,支持搜索与具体条目勾选。</td></tr><tr><td>Tool Profile作为Access preset</td><td class="done">已实现</td><td>兼容现有存储,迁入Agents页面选择。</td></tr><tr><td>Profile-scoped <code>tool_search</code></td><td class="done">已实现</td><td>名称加载和关键词检索都受resolver允许集合限制。</td></tr><tr><td>不发送延迟工具名称目录</td><td class="done">已实现</td><td>首轮上下文只发送数量与关键词检索指引。</td></tr></tbody></table>
</section>
<section id="acceptance"><h2>5. 验收合同</h2><ul class="acceptance"><li>Programs页不显示User Profile、Access preset、Agent允许/禁止状态或会话override。</li><li>Agents页可以创建Agent、选择Agent并保存其Tools & Programs策略;同一Program实体不会被复制进Agent配置。</li><li>Agent详情主页面使用Functions、Workflows和Applications三个纵向折叠区;折叠态显示数量,展开态显示当前有效条目和结构预览。</li><li>主页面展开Workflows不进入编辑模式;点击Edit access后才打开支持搜索、状态过滤和具体勾选的授权选择器。</li><li>Workflow选择器使用类型导航、Workflow列表和检查器三栏;切换Workflow时检查器同步更新入口、输入输出、直接组合、依赖和验证状态。</li><li>组合树中的可展开节点使用左侧固定圆形控制点;展开时控制点和行位置不移动,子树以200ms容器动画出现,并保留连续层级线。</li><li>Agent配置最多原位展开两层;递归Calls / Used by图进入Programs,真实执行实例进入会话DAG。</li><li>Connected Services只在MCP配置中出现,不作为Programs来源重复展示。</li><li>关闭选择器后,主页面保持同一滚动位置,不因Program数量增加而增长。</li><li>默认聊天Agent不会把全部Workflow名称、描述、schema或源码写进首轮上下文。</li><li>选择Access preset后,<code>tool_search</code>、显式名称加载和真正调用都受同一允许集合限制。</li><li>会话Tools菜单默认显示“Use Agent configuration”;临时修改不反写Agent。</li><li>全局禁用或删除Program后,所有Agent无需迁移配置即可在下一轮得到一致的不可用结果。</li><li>Function、Workflow和Application最终都进入现有统一AgentTool执行路径。</li></ul></section>
<section id="implementation"><h2>6. 实现范围与验证记录</h2>
<p>本轮直接复用<code>AgentSpec</code>、现有Tool Profile存储、<code>resolve_tools()</code>与AgentTool executor;页面层直接复用<code>ManagePageHeader</code>、<code>ManageRow</code>、共享分栏和Settings详情容器。新增内容只保留Agent专属配置表单与Programs / Skills / MCP按需选择器,没有增加第二套页面窗口或执行语义。</p>
<table><thead><tr><th>范围</th><th>文件边界</th></tr></thead><tbody><tr><td>后端</td><td><code>routes/agents.py</code>提供create、read、patch、default、duplicate、workspace和delete入口,仍委托现有Agent manager持久化。</td></tr><tr><td>前端</td><td><code>/agents</code>提供六个配置区;能力目录仅在Manage对话框打开后请求。</td></tr><tr><td>明确不做</td><td>不新增executor,不复制Program schema、Skill正文或MCP凭据,不重写Profile存储,不删除兼容API。</td></tr></tbody></table>
<table><thead><tr><th>检查</th><th>状态</th></tr></thead><tbody><tr><td>Agent HTTP生命周期、完整配置与校验</td><td>定向component测试6项通过</td></tr><tr><td>Agents框架、按需选择器与既有Web合同</td><td>Web test/check、TypeScript和production build通过</td></tr><tr><td>WebUI component测试</td><td>178项通过</td></tr><tr><td>Python contracts</td><td>449项通过,1项跳过</td></tr><tr><td>18100 App可视验收</td><td>封装App已验证六区配置、创建入口和按需Programs选择器;18200未监听,未启动源码Electron。</td></tr></tbody></table>
</section>
</div>
<script>(()=>{const radios=[...document.querySelectorAll('input[name="mode"]')],picker=document.querySelector('#program-picker'),create=document.querySelector('#create-agent'),available=document.querySelector('#discoverable-count'),excluded=document.querySelector('#excluded-count'),title=document.querySelector('#access-title'),description=document.querySelector('#access-description'),functions=document.querySelector('#functions-count'),workflows=document.querySelector('#workflows-count'),applications=document.querySelector('#applications-count'),searchable=document.querySelector('#searchable-count'),loading=document.querySelector('#loading-description');const update=()=>{const mode=radios.find(item=>item.checked)?.value||'automatic';if(mode==='automatic'){title.textContent='All Programs';description.textContent='此Agent可以发现全部全局Programs;单独禁用项会从结果中排除。';available.textContent='77';excluded.textContent='0';functions.textContent='70 / 70';workflows.textContent='4 / 4';applications.textContent='3 / 3';searchable.textContent='69 searchable';loading.textContent='只常驻核心工具schema;其余Programs由tool_search按需加载。'}else if(mode==='none'){title.textContent='No Programs';description.textContent='此Agent不接收任何可调用Program。';available.textContent='0';excluded.textContent='77';functions.textContent='0 / 70';workflows.textContent='0 / 4';applications.textContent='0 / 3';searchable.textContent='0 searchable';loading.textContent='模型上下文不包含Program schema或tool_search入口。'}else{title.textContent='Selected scope';description.textContent='此Agent只允许Access preset和手动选择得到的有效集合。';available.textContent='42';excluded.textContent='35';functions.textContent='36 / 70';workflows.textContent='4 / 4';applications.textContent='2 / 3';searchable.textContent='34 searchable';loading.textContent='常驻核心工具schema;只在42个允许项中执行tool_search。'}};radios.forEach(item=>item.addEventListener('change',update));document.querySelector('#manage-access').addEventListener('click',()=>picker.hidden=false);document.querySelector('#close-picker').addEventListener('click',()=>picker.hidden=true);document.querySelector('#new-agent').addEventListener('click',()=>create.hidden=false);document.querySelector('#cancel-create').addEventListener('click',()=>create.hidden=true);document.querySelector('#confirm-create').addEventListener('click',()=>create.hidden=true);const sourceButtons=[...document.querySelectorAll('[data-picker-source]')],sourcePanels=[...document.querySelectorAll('[data-source-panel]')];sourceButtons.forEach(button=>button.addEventListener('click',()=>{sourceButtons.forEach(item=>item.classList.toggle('active',item===button));sourcePanels.forEach(panel=>panel.hidden=panel.dataset.sourcePanel!==button.dataset.pickerSource)}));const workflowData={literature_review:{description:'检索、筛选并整理近期论文的可复用 Workflow。',entry:'literature_review(task: str)',io:'research task → report path',validation:'HEAD clean · 18 tests passed',source:'programs/workflows/literature_review',rows:[['◇','literature_review','workflow'],['◎','collect_papers','goal'],['◇','paper_screening','workflow',[['◎','apply_criteria','goal'],['ƒ','score_relevance','function'],['A','review_ambiguous','agent']],true],['◎','synthesize_results','goal']],deps:['12 Functions','1 Workflow','2 Agentic']},paper_search:{description:'跨来源检索论文、规范化元数据并去重。',entry:'paper_search(query: str)',io:'query → paper records',validation:'HEAD clean · 12 tests passed',source:'programs/workflows/paper_search',rows:[['◇','paper_search','workflow'],['◎','search_sources','goal'],['ƒ','deduplicate_records','function']],deps:['8 Functions','1 Agentic']},paper_screening:{description:'根据纳入标准筛选论文并保存决策依据。',entry:'paper_screening(records: list)',io:'paper records → decisions',validation:'HEAD changed · tests not checked',source:'programs/workflows/paper_screening',rows:[['◇','paper_screening','workflow'],['◎','apply_criteria','goal'],['◎','review_ambiguous','goal']],deps:['6 Functions','1 Agentic']},research_synthesis:{description:'根据结构化证据生成研究主题与发展脉络。',entry:'research_synthesis(evidence: str)',io:'evidence path → synthesis path',validation:'Working tree modified',source:'programs/workflows/research_synthesis',rows:[['◇','research_synthesis','workflow'],['◇','literature_review','workflow',[['◎','collect_papers','goal'],['◇','paper_screening','workflow']],false],['◎','build_narrative','goal']],deps:['9 Functions','1 Workflow','1 Agentic']}};const renderComposition=(container,rows)=>{container.replaceChildren(...rows.map((item,index)=>{const node=document.createElement('div');node.className='composition-node'+(index?' child':'')+(item[4]?' open':'');const row=document.createElement('div');row.className='composition-row';const marker=item[3]?document.createElement('button'):document.createElement('span');marker.className=item[3]?'composition-toggle':'composition-leaf';if(item[3]){marker.type='button';marker.setAttribute('aria-label',(item[4]?'收起 ':'展开 ')+item[1]);marker.setAttribute('aria-expanded',String(Boolean(item[4])))}else marker.textContent=item[0];const name=document.createElement('strong');name.textContent=item[1];const type=document.createElement('em');type.textContent=item[2];row.append(marker,name,type);node.append(row);if(item[3]){const children=document.createElement('div');children.className='composition-children';const inner=document.createElement('div');inner.className='composition-children-inner';item[3].forEach(child=>{const childRow=document.createElement('div');childRow.className='composition-child-row';const icon=document.createElement('span');icon.className='composition-leaf';icon.textContent=child[0];const childName=document.createElement('strong');childName.textContent=child[1];const childType=document.createElement('em');childType.textContent=child[2];childRow.append(icon,childName,childType);inner.append(childRow)});const more=document.createElement('div');more.className='composition-more';more.textContent='deeper internals remain in Programs';inner.append(more);children.append(inner);node.append(children);marker.addEventListener('click',()=>{const open=node.classList.toggle('open');marker.setAttribute('aria-expanded',String(open));marker.setAttribute('aria-label',(open?'收起 ':'展开 ')+item[1])})}return node}))};const workflowRows=[...document.querySelectorAll('[data-workflow]')],detail={name:document.querySelector('#workflow-detail-name'),description:document.querySelector('#workflow-detail-description'),entry:document.querySelector('#workflow-detail-entry'),io:document.querySelector('#workflow-detail-io'),validation:document.querySelector('#workflow-detail-validation'),source:document.querySelector('#workflow-detail-source'),composition:document.querySelector('#workflow-detail-composition'),dependencies:document.querySelector('#workflow-detail-dependencies')};workflowRows.forEach(row=>{row.addEventListener('click',event=>{if(event.target instanceof HTMLInputElement)return;workflowRows.forEach(item=>item.classList.toggle('active',item===row));const data=workflowData[row.dataset.workflow];detail.name.textContent=row.dataset.workflow;detail.description.textContent=data.description;detail.entry.textContent=data.entry;detail.io.textContent=data.io;detail.validation.textContent=data.validation;detail.source.textContent=data.source;renderComposition(detail.composition,data.rows);detail.dependencies.replaceChildren(...data.deps.map(item=>{const chip=document.createElement('span');chip.className='dependency-chip';chip.textContent=item;return chip}))})});renderComposition(detail.composition,workflowData.literature_review.rows);document.querySelectorAll('[data-scope-toggle]').forEach(button=>button.addEventListener('click',()=>{const section=button.closest('.scope-section');const open=section.classList.toggle('open');button.setAttribute('aria-expanded',String(open))}));const inlineRows=[...document.querySelectorAll('[data-inline-workflow]')],inlineDetail={name:document.querySelector('#inline-workflow-name'),description:document.querySelector('#inline-workflow-description'),meta:document.querySelector('#inline-workflow-meta'),composition:document.querySelector('#inline-workflow-composition')};inlineRows.forEach(row=>row.addEventListener('click',()=>{inlineRows.forEach(item=>item.classList.toggle('active',item===row));const data=workflowData[row.dataset.inlineWorkflow];inlineDetail.name.textContent=row.dataset.inlineWorkflow;inlineDetail.description.textContent=data.description;inlineDetail.meta.replaceChildren(...([String(Math.max(0,data.rows.length-1))+' direct calls',...data.deps].map(item=>{const chip=document.createElement('span');chip.textContent=item;return chip})));renderComposition(inlineDetail.composition,data.rows)}));renderComposition(inlineDetail.composition,workflowData.literature_review.rows);update()})();</script>
</body></html>