feat: 初始化 sundynix-agentix 分层式 AI Agent 平台脚手架

5 层 + 1 条 NATS 零拷贝消息总线的 monorepo(Monolith First → Microservices Morph B)。
纵向主干(任务流 + Token 流回流)已真实跑通,横向各层能力为带注释的桩。

已贯通(real code):
- sundynix-shared: 共享契约 + JetStream/core NATS 真实收发(bus) + 内嵌 NATS(devnats) + e2e 测试
- sundynix-gateway: Gin 接入 + DSL 解析组装 + NATS Publish + SSE 流式输出
- sundynix-dispatcher: NATS 消费 + Eino Orchestrator 流式回流 + 熔断器 + LLM Pool 占位流式
- 链路: HTTP POST → DSL → sundynix.tasks.* → Dispatcher → Token 经 sundynix.streams.<id> 回流 → SSE
- 基础设施: docker-compose(nats/postgres/redis/neo4j/milvus) + Makefile(make demo/e2e)

待填(桩):
- Eino 图编排 compose.NewGraph、LLM Pool 接 vLLM/Ollama
- Gateway store 换真实 pgx/redis
- sundynix-mcp-go: Bleve+Milvus+Neo4j 混合检索 / UniOffice / 外部 API
- sundynix-mcp-py: gVisor 沙箱 / MinerU(PaddleOCR) / Docker 解释器
- sundynix-desktop: React Flow 画布 → DSL 导出 → SSE 展示
This commit is contained in:
Blizzard
2026-06-10 11:00:29 +08:00
commit c7a02c3905
74 changed files with 2570 additions and 0 deletions
+286
View File
@@ -0,0 +1,286 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>sundynix-agentix · 系统架构图</title>
<style>
:root{
--client:#f6d9b0; --client-bg:#fdf2e3; --client-br:#e0a85a;
--gateway:#f8c9c9; --gateway-stroke:#d96b6b;
--nats:#cfe8c6; --nats-bg:#e7f4e1; --nats-br:#86c06a;
--dispatcher:#dcc7ef; --dispatcher-bg:#efe5f8; --dispatcher-br:#a984cf;
--gotools:#bcdcef; --gotools-bg:#dcecf7; --gotools-br:#5fa9d4;
--pytools:#f6e6a8; --pytools-bg:#fbf3cf; --pytools-br:#d8bf52;
--ginserver:#bfe3c4;
--box:#eef1f4; --box-br:#c4ccd4;
--ink:#1c2b3a; --muted:#5a6b7b;
}
*{box-sizing:border-box;}
body{
margin:0; padding:32px;
font-family:"PingFang SC","Microsoft YaHei","Segoe UI",system-ui,sans-serif;
background:#f3f5f7; color:var(--ink);
}
h1{font-size:22px; margin:0 0 4px;}
.sub{color:var(--muted); margin:0 0 24px; font-size:13px;}
.grid{
display:grid;
grid-template-columns: 1.05fr 1.05fr 1.15fr;
gap:22px;
align-items:start;
max-width:1980px;
}
/* ---- generic layer card ---- */
.layer{
border-radius:14px; padding:14px;
border:2px solid transparent;
}
.layer > .ltitle{
font-weight:800; font-size:15px; margin:0 0 12px; letter-spacing:.2px;
}
.layer > .ltitle small{display:block; font-weight:600; font-size:11px; color:var(--muted); margin-top:2px;}
.panel{
background:rgba(255,255,255,.65);
border-radius:11px; padding:12px; margin-bottom:12px;
}
.panel:last-child{margin-bottom:0;}
.panel-title{font-weight:700; font-size:13px; margin:0 0 10px;}
.panel-title small{font-weight:500; color:var(--muted);}
.box{
background:var(--box); border:1px solid var(--box-br);
border-radius:8px; padding:9px 11px; margin-bottom:8px;
font-size:12.5px; line-height:1.35; text-align:center;
}
.box:last-child{margin-bottom:0;}
.box b{display:block; font-weight:700;}
.box span{display:block; color:var(--muted); font-size:11px; margin-top:2px;}
.box.hl{background:#fff;}
.row2{display:grid; grid-template-columns:1fr 1fr; gap:8px;}
.row2 .box{margin-bottom:0;}
/* ---- layer colors ---- */
.client { background:var(--client-bg); border-color:var(--client-br); }
.gateway { background:#e6eef6; border-color:var(--gotools-br); }
.gateway .panel{background:#cfe0ef;}
.nats { background:var(--nats-bg); border-color:var(--nats-br); }
.dispatcher{ background:var(--dispatcher-bg); border-color:var(--dispatcher-br); }
.toolswrap { background:var(--nats-bg); border-color:var(--nats-br); padding:14px; border-radius:14px; border:2px solid var(--nats-br);}
.mcp-go { background:#d6e7f3; border:2px solid var(--gotools-br); border-radius:12px; padding:12px; margin-bottom:14px;}
.mcp-py { background:var(--pytools-bg); border:2px solid var(--pytools-br); border-radius:12px; padding:12px;}
.colA{display:flex; flex-direction:column; gap:0;}
.colB{display:flex; flex-direction:column; gap:18px;}
/* connector labels */
.conn{
text-align:center; font-size:11px; color:#2a3a49; font-weight:700;
margin:6px 0; line-height:1.4;
}
.conn .arr{font-size:15px; color:#33485c;}
.conn small{display:block; font-weight:500; color:var(--muted);}
.midbar{
display:flex; align-items:center; justify-content:center; gap:8px;
font-weight:800; font-size:12px; color:#2a3a49; text-align:center;
background:#fff; border:1px dashed #9fb0bf; border-radius:8px;
padding:8px 10px; margin:14px 0;
}
.llmpool{
background:#e9edf0; border:1px solid #c4ccd4; border-radius:50px/40px;
padding:14px 16px; text-align:center; font-size:12.5px;
}
.llmpool b{display:block;}
.einolink{text-align:center; font-size:11px; font-weight:700; color:#6a4fa0; margin:8px 0;}
/* legend */
.legend{
margin-top:26px; display:flex; flex-wrap:wrap; gap:10px 26px;
align-items:center; background:#fff; border:1px solid var(--box-br);
border-radius:12px; padding:14px 18px; max-width:1980px;
}
.legend b{width:100%; font-size:13px; margin-bottom:2px;}
.lg{display:flex; align-items:center; gap:8px; font-size:12.5px;}
.sw{width:20px; height:14px; border-radius:4px; border:1px solid rgba(0,0,0,.15);}
.sw.client{background:var(--client);} .sw.gateway{background:var(--gateway);}
.sw.nats{background:var(--nats);} .sw.dispatcher{background:var(--dispatcher);}
.sw.gotools{background:var(--gotools);} .sw.pytools{background:var(--pytools);}
.sw.ginserver{background:var(--ginserver);}
.flow-note{
max-width:1980px; margin-top:22px; background:#fff; border:1px solid var(--box-br);
border-radius:12px; padding:16px 20px; font-size:13px; line-height:1.7;
}
.flow-note b{color:#2a3a49;}
.tag{display:inline-block; background:#eef1f4; border:1px solid var(--box-br);
border-radius:5px; padding:1px 7px; font-size:11.5px; font-family:ui-monospace,monospace;}
</style>
</head>
<body>
<h1>sundynix-agentix · 系统架构图</h1>
<p class="sub">分层式 AI Agent 平台 — Client / Gateway / NATS 总线 / Dispatcher / MCP ToolsMonolith First → Microservices Morph B</p>
<div class="grid">
<!-- ===================== 列 1:左纵列 (Client → Gateway → NATS → Dispatcher) ===================== -->
<div class="colA">
<!-- 1. CLIENT -->
<div class="layer client">
<div class="ltitle">1. CLIENT LAYER <small>Edge Interaction</small></div>
<div class="panel">
<div class="panel-title">sundynix-desktop <small>(User Device App)</small></div>
<div class="box hl"><b>UI Representation Layer</b><span>React 19 + TypeScript</span></div>
<div class="box"><b>shadcn/ui + Tailwind CSS</b><span>Styles / Components</span></div>
<div class="row2" style="margin-bottom:8px;">
<div class="box"><b>React Flow Canvas</b><span>Agent Orchestration</span></div>
<div class="box"><b>JSON DSL export</b><span>&nbsp;</span></div>
</div>
<div class="box"><b>LLM Wiki Management Panel</b></div>
<div class="box hl" style="background:var(--ginserver);"><b>Wails Local Go Runtime</b></div>
<div class="row2">
<div class="box hl" style="background:var(--gotools);"><b>Strong Binding</b><span>TS / Go</span></div>
<div class="box hl" style="background:var(--gotools);"><b>Local File System I/O</b></div>
</div>
</div>
</div>
<!-- connector client <-> gateway -->
<div class="conn">
<span class="arr"></span> 4. PHYSICAL COMMUNICATION<br>
<small>HTTPS / WebSocket / SSE &nbsp;·&nbsp; <span class="tag">sundynix.streams.task_id</span> Token Stream</small>
</div>
<!-- 2. GATEWAY -->
<div class="layer gateway">
<div class="ltitle">2. BUSINESS GATEWAY LAYER</div>
<div class="panel">
<div class="panel-title">sundynix-gateway <small>(Gin 微服务 · 集成 Monolith First)</small></div>
<div class="box hl"><b>Gin 微服务 / 统一接入层</b></div>
<div class="row2" style="margin-bottom:8px;">
<div class="box">🗄️ <b>MainDB</b><span>PgSQL: Users, Billing, DSL</span></div>
<div class="box">🧱 <b>CacheDB</b><span>Session / Rate Limit</span></div>
</div>
<div class="row2" style="margin-bottom:8px;">
<div class="box">🧱 <b>CacheDB</b><span>Redis: Session, Rate Limit</span></div>
<div class="box"><b>商业化与计费模块</b></div>
</div>
<div class="row2">
<div class="box"><b>Harness</b><span>Input / Output Guardrail</span></div>
<div class="box"><b>Task DSL Parser & Assembly</b></div>
</div>
</div>
</div>
<!-- connector gateway <-> nats -->
<div class="conn">
<span class="arr"></span> 1. Publish Task DSL &nbsp;&nbsp;|&nbsp;&nbsp; 4. Subscribe Stream <span class="arr"></span>
</div>
<!-- 3. NATS -->
<div class="layer nats">
<div class="ltitle">3. MESSAGE BUS — NATS 零拷贝骨干网</div>
<div class="panel">
<div class="panel-title" style="text-align:center;">NATS Server (Go) 🗄️</div>
<div class="row2">
<div class="box"><b>NATS Queue</b><span>分布式任务队列<br><span class="tag">sundynix.tasks.*</span></span></div>
<div class="box"><b>NATS Stream</b><span>零拷贝字节管道<br><span class="tag">sundynix.streams.*</span></span></div>
</div>
</div>
</div>
<!-- connector nats <-> dispatcher -->
<div class="conn"><span class="arr"></span> 4. Subscribe Stream</div>
<!-- 4. DISPATCHER -->
<div class="layer dispatcher">
<div class="ltitle">4. AI AGENT DISPATCHER LAYER</div>
<div class="llmpool" style="margin-bottom:10px;">
<b>LLM Pool</b><span style="color:var(--muted); font-size:11px;">vLLM / Ollama 集群</span>
</div>
<div class="einolink">↑ EinoCore &nbsp;·&nbsp; Eino 回调机制 ↓</div>
<div class="panel">
<div class="panel-title">sundynix-dispatcher <small>(Go / Eino 集群)</small></div>
<div class="row2" style="margin-bottom:8px;">
<div class="box hl"><b>Eino 图编排引擎</b></div>
<div class="box hl"><b>nats.go client</b></div>
</div>
<div class="box"><b>Harness: LLM 自动化评测</b></div>
<div class="box"><b>Harness: 熔断降级中心</b></div>
</div>
</div>
</div>
<!-- ===================== 列 2:留白做视觉间隔 / 物理通信说明 ===================== -->
<div class="colA" style="justify-content:flex-start;">
<div class="midbar">&nbsp; 4. PHYSICAL COMMUNICATION &nbsp;</div>
<div class="flow-note" style="margin-top:0;">
<b>核心数据流(编号对应连线)</b><br>
<b>1.</b> Gateway 解析 DSL 后 <b>Publish Task DSL</b> → NATS Queue<span class="tag">sundynix.tasks.*</span><br>
<b>2.</b> Dispatcher 通过 <span class="tag">nats.go</span> 订阅任务,Eino 图编排引擎驱动 LLM Pool 推理<br>
<b>3.</b> Dispatcher / Gateway 经 NATS 调用第 5 层 MCP 工具(Go I/O 型 + Python 算法型)<br>
<b>4.</b> 推理结果以 <b>零拷贝 Token Stream</b><span class="tag">sundynix.streams.task_id</span> 回流 Gateway → 经 SSE/WS 推送给 Client
</div>
<div class="midbar" style="margin-top:18px;">&nbsp; 4. Subscribe Stream &nbsp;&nbsp; MCP Tools</div>
</div>
<!-- ===================== 列 3MCP Tools 层 ===================== -->
<div class="colB">
<div class="toolswrap">
<div style="font-weight:800; font-size:15px; margin-bottom:4px;">5. MICROSERVICE MCP TOOLS LAYER</div>
<div style="font-size:11px; color:var(--muted); margin-bottom:12px;">Standalone microservices · Morph B</div>
<!-- mcp_go -->
<div class="mcp-go">
<div class="panel-title">sundynix-mcp-go <small>(Go 微服务 · I/O 型)</small></div>
<div class="box hl"><b>MCP Protocol Gateway</b></div>
<div class="box hl"><b>LLM Wiki 搜索引擎</b><span>Hybrid Search: Bleve · Milvus Go SDK · Neo4j Go Driver</span></div>
<div class="row2" style="margin-bottom:8px;">
<div class="box">🧊 <b>Milvus</b><span>Vector DB</span></div>
<div class="box">🔎 <b>Bleve</b><span>Go Search Index</span></div>
</div>
<div class="row2" style="margin-bottom:8px;">
<div class="box">🕸️ <b>Neo4j</b><span>Knowledge Graph</span></div>
<div class="box">🕸️ <b>Neo4j</b><span>Graph</span></div>
</div>
<div class="row2">
<div class="box">📄 <b>UniOffice</b><span>Word/Doc Rendering</span></div>
<div class="box"><b>External APIs</b></div>
</div>
</div>
<!-- mcp_py -->
<div class="mcp-py">
<div class="panel-title">sundynix-mcp-py <small>(Python 微服务 · 算法型)</small></div>
<div class="box hl"><b>MCP Protocol Gateway</b></div>
<div class="box"><b>Harness: Secure Code Sandbox</b><span>gVisor / KataVM · Static Code Guard</span></div>
<div class="box"><b>MinerU</b><span>Multimodal Parser: PaddleOCR</span></div>
<div class="box"><b>Docker 隔离沙箱</b><span>Code Interpreter</span></div>
</div>
</div>
</div>
</div>
<!-- ===================== 图例 ===================== -->
<div class="legend">
<b>Legend</b>
<div class="lg"><span class="sw client"></span>Client</div>
<div class="lg"><span class="sw gateway"></span>Gateway</div>
<div class="lg"><span class="sw nats"></span>NATS</div>
<div class="lg"><span class="sw dispatcher"></span>Dispatcher</div>
<div class="lg"><span class="sw gotools"></span>Go Tools</div>
<div class="lg"><span class="sw pytools"></span>Python Tools</div>
<div class="lg"><span class="sw ginserver"></span>GinServer</div>
</div>
</body>
</html>