XGEN 3.0 β μ§ν νν©
νλͺ©
νμΌ
μν
νλ‘μ νΈ κ΅¬μ‘°
pyproject.toml, Dockerfile, λλ ν 리 ꡬ쑰
β
@tool λ°μ½λ μ΄ν°
src/tools/decorator.py
β
Tool Registry
src/tools/registry.py
β
Agent Core λ§μ€ν° 루ν
src/core/agent.py
β
λν 컨ν
μ€νΈ
src/core/context.py
β
LLM ν΄λΌμ΄μΈνΈ
src/core/model_client.py (OpenAI νΈν)
β
Built-in λꡬ
src/tools/builtin/http.py, db.py, file.py
β
CLI
cli.py (serve, import, run, tools, connect)
β
Trace/Log
src/trace/collector.py, exporter.py
β
State Store
src/store/state.py (PostgreSQL Checkpointer)
β
Agent Store
src/store/agent_store.py (Agent μ μ CRUD)
β
μ€ν μ΄λ ₯
src/store/history.py
β
Phase 2: AI κ°λ° + μλλ°μ€ β
νλͺ©
νμΌ
μν
Docker Sandbox
src/sandbox/docker.py (격리μ€ν, νμμμ, 리μμ€μ ν)
β
Sandbox @tool
src/sandbox/runner.py (execute_code, execute_code_with_test)
β
AI λꡬ μμ±
src/tools/generator.py (LLM β μ½λμμ± β μλλ°μ€ν
μ€νΈ β λ±λ‘)
β
Human-in-the-Loop
src/core/approval.py (μΉμΈ λκΈ° β μΉμΈ/κ±°μ β μ¬κ°)
β
μ€ν¨ μ¬κ°
src/core/agent.py (State Store μ°λ, resume=True)
β
λ©ν°ν΄ 컨ν
μ€νΈ μ μ₯
Agent β State Store μλ 체ν¬ν¬μΈνΈ
β
Phase 3: νλ«νΌ ν΅ν© β
νλͺ©
νμΌ
μν
MCP ν΄λΌμ΄μΈνΈ
src/mcp/client.py (SSE + STDIO)
β
MCP β @tool λΈλ¦Ώμ§
src/mcp/bridge.py
β
graph-tool-call
src/tools/graph_tool.py β μ€μ ν¨ν€μ§(0.13.1) μ°λ
β
Agent Core μ°λ
_resolve_tools_schema() β λꡬ 15κ°+ μ μλ κ²μ λͺ¨λ
β
MCP API
/api/mcp/connect, /api/mcp/servers
β
graph-tool API
/api/tools/search, /api/tools/ingest, /api/tools/graph/stats
β
Phase 4: μ΄μ κ³ λν β
νλͺ©
νμΌ
μν
μ€μ κ΄λ¦¬
src/core/config.py (νκ²½λ³μ κΈ°λ°)
β
κΆν κ΄λ¦¬
src/core/permissions.py (ADMIN/DEVELOPER/USER/VIEWER)
β
Agent λ²μ κ΄λ¦¬
src/store/versioning.py
β
νΈλ¦¬κ±°
src/core/triggers.py (Webhook + μ€μΌμ€)
β
xgen-workflow API νΈν β
νλͺ©
λ΄μ©
μν
μμ² λͺ¨λΈ
WorkflowRequest β xgen-workflowμ λμΌ νλ
β
SSE μ΄λ²€νΈ ν¬λ§·
log, tool, data, end, error β κΈ°μ‘΄ νλ‘ νΈμλ νΈν
β
Deploy μλ΅
{success, content, citations, error} + Envelope ν¬λ§·
β
API κ²½λ‘
/api/workflow/* μ 체 κ²½λ‘ μ μ§
β
input_data λ³ν
str/dict/list/None β μλ λ©μμ§ λ³ν
β
graph-tool-call μ°λ β
(μ κ·)
νλͺ©
λ΄μ©
μν
ν¨ν€μ§
graph-tool-call 0.13.1 μ€μΉ λ° pyproject.toml μΆκ°
β
GraphToolManager
ToolGraph λν β ingest_from_registry, ingest_openapi, ingest_mcp_tools
β
Agent Core μ°λ
_resolve_tools_schema() β λꡬ 15κ°+ μ μλ graph κ²μ
β
νΈμΆ μ΄λ ₯
record_call() β history-aware retrieval
β
xgen-infra λ°°ν¬ μ€μ β
(μ κ·)
νμΌ
μμ
μν
dockerfiles/xgen-agent/Dockerfile
μμ± (Chromium μ κ±°, κ²½λ)
β
dockerfiles/xgen-agent/Dockerfile.local
μμ± (Jenkins λ‘컬 λΉλμ©)
β
k3s/helm-chart/values/xgen-agent.yaml
μμ± (νκ²½λ³μ, 리μμ€ μ€μ )
β
k3s/jenkins/config/services.yaml
xgen-agent μΆκ°
β
k3s/argocd/projects/xgen.yaml
dev/prdμ xgen-agent μΆκ°
β
k3s/argocd/projects/xgen-son.yaml
dev/prdμ xgen-agent μΆκ°
β
compose/full-stack/docker-compose.yml
xgen-agent μλΉμ€ μΆκ° (ν¬νΈ 8010)
β
compose/full-stack/docker-compose.dev.yml
xgen-agent profile μΆκ°
β
xgen2.0 λ ν¬ ν΄λ‘ β
(μ κ·)
repos/
βββ xgen-infra/ β λΉλ/λ°°ν¬ μ€μ (μμ λ¨)
βββ xgen-workflow/ β κ΅μ²΄ λμ (μ°Έκ³ μ©)
βββ xgen-core/ β μ μ§ (xgen-agentκ° νΈμΆ)
βββ xgen-frontend/ β νλ‘ νΈμλ μ°λ λμ
βββ xgen-model/ β LLM μΆλ‘
βββ xgen-mcp-station/ β Phase 3μμ ν‘μ
βββ xgen-documents/ β μ μ§
βββ xgen-backend-gateway/ β μ μ§
ν
μ€νΈ
νκ²½
κ²°κ³Ό
GPT-4o-mini λ¨μ λν
λ‘컬 Python
β
λꡬ μλ μ ν (get_time, calculate)
λ‘컬 Python
β
file_read λꡬ (pyproject.toml)
Docker λ¨λ
β
db_query λꡬ (PostgreSQL)
Docker λ¨λ
β
http_request λꡬ (httpbin.org)
Docker λ¨λ
β
Agent μ μ₯/λͺ©λ‘ (DB CRUD)
Docker λ¨λ
β
νμ€ν compose DB μ°λ
compose (PostgreSQL + Redis + xgen-agent)
β
νμ€ν compose LLM λν
compose (GPT-4o-mini + λꡬ 7κ°)
β
νμ€ν compose Agent CRUD
compose (μ μ₯/λͺ©λ‘/λ‘λ)
β
Swagger UI
http://localhost:8010/docs
β
116κ° ν
μ€νΈ μ λΆ ν΅κ³Ό (2.27μ΄)
ν
μ€νΈ νμΌ
κ°μ
λμ
test_api.py
21
API μλν¬μΈνΈ (CRUD, deploy, trace, schedule λ±)
test_graph_tool.py
20
graph-tool-call μ°λ (μ€μ ν¨ν€μ§)
test_sse_adapter.py
11
SSE μ΄λ²€νΈ ν¬λ§· νΈν
test_models.py
9
WorkflowRequest μ
λ ₯ λ³ν
test_context.py
8
λν 컨ν
μ€νΈ
test_generator.py
6
AI λꡬ μμ±κΈ°
test_permissions.py
6
κΆν κ΄λ¦¬
test_triggers.py
6
νΈλ¦¬κ±°
test_model_client.py
5
LLM μλ΅ νμ±
test_mcp.py
5
MCP ν΄λΌμ΄μΈνΈ/λΈλ¦Ώμ§
test_trace.py
5
Trace μμ§κΈ°
test_approval.py
4
Human-in-the-Loop
test_sandbox.py
4
Docker μλλ°μ€
test_tools.py
4
@tool + Registry
test_config.py
2
νκ²½λ³μ μ€μ
νΈν API μλν¬μΈνΈ μ 체 λͺ©λ‘
GET /health
POST /api/workflow/execute/based_id/stream β ν΅μ¬ SSE μ€ν
POST /api/workflow/execute/based_id/stream/deploy β Deploy SSE (λ‘κ·Έ λ―Έμ μ‘)
POST /api/workflow/execute/deploy/stream β Deploy (json/stream μ ν)
POST /api/workflow/execute/deploy/result β Java Envelope μλ΅
GET /api/workflow/execute/status β μ€ν μν λͺ©λ‘
GET /api/workflow/execute/status/{id} β μ€ν μν μ‘°ν
POST /api/workflow/execute/cleanup β μλ£ μ 리
GET /api/workflow/list β μν¬νλ‘μ° λͺ©λ‘
POST /api/workflow/save β μν¬νλ‘μ° μ μ₯
GET /api/workflow/load/{workflow_id} β μν¬νλ‘μ° λ‘λ
DELETE /api/workflow/delete/{workflow_id} β μν¬νλ‘μ° μμ
POST /api/workflow/rename/workflow β μ΄λ¦ λ³κ²½
POST /api/workflow/check/workflow β μ‘΄μ¬ νμΈ
GET /api/workflow/version/list β λ²μ λͺ©λ‘
GET /api/workflow/version/data β λ²μ λ°μ΄ν°
GET /api/workflow/deploy/load/{user_id}/{wf_id} β Deploy λ‘λ
POST /api/workflow/deploy/toggle/{workflow_id} β λ°°ν¬ ν κΈ
GET /api/workflow/deploy/status/{workflow_id} β λ°°ν¬ μν
GET /api/workflow/deploy/list β λ°°ν¬ λͺ©λ‘
GET /api/workflow/trace/list β νΈλ μ΄μ€ λͺ©λ‘
GET /api/workflow/trace/detail/{trace_id} β νΈλ μ΄μ€ μμΈ
GET /api/workflow/trace/by-interaction/{id} β μΈν°λμ
λ³ νΈλ μ΄μ€
POST /api/workflow/schedule/sessions β μ€μΌμ€ μμ±
GET /api/workflow/schedule/sessions β μ€μΌμ€ λͺ©λ‘
GET /api/workflow/schedule/status β μ€μΌμ€ μν
GET /api/workflow/performance β μ±λ₯ ν΅κ³
POST /api/agent/run β xgen3.0 μ μ© (non-streaming)
GET /api/tools/list β λꡬ λͺ©λ‘
POST /api/tools/generate β AI λꡬ μμ±
POST /api/tools/search β graph-tool-call κ²μ
POST /api/tools/ingest β graph-tool-call μμ€ μΆκ°
GET /api/tools/graph/stats β κ·Έλν ν΅κ³
POST /api/mcp/connect β MCP μλ² μ°κ²°
DELETE /api/mcp/disconnect/{name} β MCP μ°κ²° ν΄μ
GET /api/mcp/servers β MCP μλ² λͺ©λ‘
POST /api/approval/action β μΉμΈ/κ±°μ μ²λ¦¬
GET /api/approval/pending β λκΈ° μΉμΈ λͺ©λ‘
GET /api/sessions β μΈμ
λͺ©λ‘
DELETE /api/sessions/{session_id} β μΈμ
μμ
GET /api/history β μ€ν μ΄λ ₯
νμ€ν end-to-end ν
μ€νΈ νν©
μλΉμ€
ν¬νΈ
μν
PostgreSQL
5432
β
healthy
Redis
6379
β
healthy
xgen-core
8001
β
healthy (DB + Redis)
xgen-agent
8010
β
ok (λꡬ 7κ°, DB Store 3κ°)
xgen-frontend
3000
β
Ready (Next.js 15.5.7 Turbopack)
xgen-backend-gateway
8000
β
running
cd repos/xgen-infra/compose/full-stack
# .env μ€μ
cp .env.dev .env
# GITLAB_TOKEN, MODEL_API_KEY μ€μ
# μΈνλΌ + core + agent + frontend κΈ°λ
docker compose -f docker-compose.dev.yml up -d --build postgresql redis
docker compose -f docker-compose.dev.yml up -d --build git-cloner xgen-core
docker compose -f docker-compose.dev.yml --profile agent up -d --build xgen-agent
docker compose -f docker-compose.dev.yml --profile frontend up -d --build xgen-frontend
xgen3.0 μ μ© νλ‘ νΈμλ μ¬κ΅¬μ± β
(μ κ·)
κΈ°μ‘΄ xgen-frontend(μΊλ²μ€ μλν° μ€μ¬)λ₯Ό xgen3.0 μ² νμ λ§κ² λν μ€μ¬ UI λ‘ μμ μ¬μ€κ³.
κΈ°μ‘΄ λμμΈ μμ€ν
(μμ, νμ΄ν¬, μ€νμ΄μ±, SCSS ν¨ν΄)μ κ³μΉνλ ꡬ쑰λ₯Ό κ·Όλ³Έμ μΌλ‘ λ³κ²½.
νλͺ©
νμΌ
μν
νλ‘μ νΈ μ€μ
frontend/package.json, next.config.ts, tsconfig.json
β
λμμΈ μμ€ν
frontend/src/app/_common/_variables.scss, globals.css
β
κ³΅ν΅ νμ
frontend/src/app/_common/types/index.ts (Agent, Message, Trace, SSE)
β
API ν΄λΌμ΄μΈνΈ
frontend/src/app/_common/api/ (client, config, agentAPI β SSE μ€νΈλ¦¬λ° ν¬ν¨)
β
λ£¨νΈ λ μ΄μμ + μ¬μ΄λλ°
frontend/src/app/layout.tsx, Sidebar/ (λν/μμ΄μ νΈ/νΈλ μ΄μ€/μ€μ )
β
λμ보λ (/)
frontend/src/app/page.tsx (Agent λͺ©λ‘, ν΅κ³, λΉ λ₯Έ λν μμ)
β
λν UI (/chat/[agentId])
frontend/src/app/chat/[agentId]/page.tsx β ν΅μ¬ νμ΄μ§
β
Trace λ·°μ΄ (/trace/[traceId])
frontend/src/app/trace/[traceId]/page.tsx (μ½κΈ° μ μ© Flow Viewer)
β
Agent μμΈ (/agents/[agentId])
frontend/src/app/agents/[agentId]/page.tsx (κ°μ/λꡬ/μ΄λ ₯ ν)
β
ChatMessage μ»΄ν¬λνΈ
ChatMessage/ (ThinkλΈλ‘, ToolCall, μΉμΈμμ², 볡μ¬)
β
TraceTimeline μ»΄ν¬λνΈ
TraceTimeline/ (μ€ν νλ¦ νμλΌμΈ)
β
κΈ°μ‘΄ λλΉ ν΅μ¬ λ³κ²½:
κΈ°μ‘΄ xgen-frontend
μ frontend/
μΊλ²μ€ μλν°κ° λ©μΈ (/canvas, ReactFlow λλκ·Έμ€λλ‘)
λν UIκ° λ©μΈ (/chat/[agentId])
229κ° SCSS λͺ¨λ, 61KB ChatInterface.tsx
12κ° SCSS λͺ¨λλ‘ κ²½λν
LangChain λ
Έλ μμ€ν
@tool κΈ°λ° λꡬ νμ
LocalStorage μνκ΄λ¦¬
μλ² State Store μ°λ
λΉμ£ΌμΌ μλν° (μμ μ©)
μ½κΈ° μ μ© Trace λ·°μ΄λ§ ("μμ μ λνλ‘")
λν UI ν΅μ¬ κΈ°λ₯:
SSE μ€νΈλ¦¬λ°: Think β Act β Observe κ³Όμ μ€μκ° νμ
Think λΈλ‘: μ μ΄μ μΆλ‘ κ³Όμ
Tool Call: λꡬ νΈμΆ νλΌλ―Έν°/κ²°κ³Ό μ€μκ° νμ
Human-in-the-Loop: μΉμΈ/κ±°λΆ λ²νΌμ΄ λν νλ¦ μμ μμ°μ€λ½κ² λ±μ₯
Trace λ§ν¬: ν€λμμ μ½κΈ° μ μ© Flow Viewerλ‘ μ¦μ μ΄λ
κΈμΌ μ§ν μ¬ν (2026-03-16)
xgen-infra μμ‘΄ μ κ±°, docker-compose.yml λ¨λ
λΉλ μ²΄κ³ κ΅¬μΆ
docker compose up -d --build ν λ°©μΌλ‘ postgres + xgen-agent + xgen-agent-frontend κΈ°λ
frontend Dockerfile μμ±, μμ€ λ³Όλ₯¨ λ§μ΄νΈ (ν«λ¦¬λ‘λ)
.env νμΌλ‘ API ν€ λΆλ¦¬
νλ‘ νΈμλ β xgen-agent SSE μ°λ β
SSE μ΄λ²€νΈ ν¬λ§· λ§€ν (xgen-workflow νΈν β xgen3.0 νλ‘ νΈμλ)
Next.js rewrite SSE λ²νΌλ§ λ¬Έμ ν΄κ²° (λΈλΌμ°μ β λ°±μλ μ§μ μμ²)
CORS μ€μ μΆκ°
WorkflowRequest.interaction_id null νμ© μμ
λν UIμμ LLM μλ΅ + λꡬ νΈμΆ SSE μ€νΈλ¦¬λ° νμΈ
xgen-core / xgen-documents @tool λν β
src/tools/builtin/xgen_core.py β DB 8κ° + Config 4κ° + Auth 1κ° = 13κ° λꡬ
src/tools/builtin/xgen_documents.py β RAG 3κ° + Embedding 3κ° + λ¬Έμμ²λ¦¬ 3κ° = 9κ° λꡬ
μ΄ λꡬ 29κ° (7 λΉνΈμΈ + 13 xgen-core + 9 xgen-documents)
15κ° μ΄κ³Όλ‘ graph-tool-call μλ κ²μ λͺ¨λ λμ νμΈ
LLMμ΄ "μ£Όλ¬Έ μ‘°νν΄μ€" β core_db_find μλ μ ν νμΈ
νλ‘ νΈμλ λ²κ·Έ μμ β
listAgents() API μλ΅ νν λ§€ν ({agents:[]} β λ°°μ΄)
AgentSummary νλ λ³ν (toolsβtool_count, status κΈ°λ³Έκ°)
<a> μ€μ²© μλ¬ μμ (agents νμ΄μ§)
stats.totalTools NaN μμ
μ€μ νμ΄μ§ (/settings) μ κ· μμ± β μλΉμ€ μν, λꡬ λͺ©λ‘, MCP, νκ²½μ 보
κ΄μ°° κ°λ₯μ± β Trace / μ€ν μ΄λ ₯ UI β
νλͺ©
λ΄μ©
μν
Trace λͺ©λ‘ νμ΄μ§
/trace β μΉ΄λν λͺ©λ‘, νμ΄μ§λ€μ΄μ
, step λ°°μ§
β
Trace μμΈ νμ΄μ§
/trace/[traceId] β μ€μ λ°μ΄ν° μ°κ²° (λ°λͺ¨ ν΄λ°± μ κ±°)
β
μ€ν μ΄λ ₯ νμ΄μ§
/history β ν
μ΄λΈν, μμ΄μ νΈ νν°, Trace λ§ν¬
β
Sidebar λ©λ΄
"μ€ν μ΄λ ₯" μΆκ° (FiClock μμ΄μ½)
β
API URL μμ
listTraces, getTrace μλͺ»λ URL β μ€μ λ°±μλ κ²½λ‘ μ°κ²°
β
Trace step κΈ°λ‘
Agent Coreμμ Think/Tool/Response stepμ traceμ μλ κΈ°λ‘
β
μ€ν μ΄λ ₯ μλ κΈ°λ‘
SSE μ€ν μλ£ μ history_store.record() νΈμΆ μΆκ°
β
λ°±μλβνλ‘ νΈ νλ 보μ
normalizeTrace() β start_timeβtimestamp, duration_msβtotal_duration_ms
β
Mode A: μμ΄μ νΈ μμ΄ λ°λ‘ λν β
plan.mdμ ν΅μ¬ λΉμ ꡬν β "νλμ λνμ°½μμ AIκ° μ§μ agentλ₯Ό κ°λ°Β·μ€ν"
νλͺ©
λ΄μ©
μν
μμ΄μ νΈ κ΄λ¦¬ λꡬ
src/tools/builtin/agent_mgmt.py β create/list/get/update/delete_agent + list_available_tools (6κ°)
β
graph-tool-call νμ νμ±
μκ³κ° 15 β 0 λ³κ²½, λꡬ μ 무κ΄νκ² νμ κ²μ λͺ¨λ
β
λ©ν μμ΄μ νΈ λΆνμ
λ³λ ν둬ννΈ μμ΄ graph searchκ° create_agent λ± μλ νμ
β
/chat λ°λ‘ λν
μμ΄μ νΈ μ ν μμ΄ defaultλ‘ μ¦μ λν μμ
β
λν μ΄λ ₯ νμ
/chat μ°μ»΄ νλ©΄μ μ΅κ·Ό λν 5건 + λΉ λ₯Έ ν둬ννΈ 4κ°
β
DB μμ΄μ νΈ λ‘λ
_create_agentμμ agent_store.load() β system_prompt/model/approval μλ μ μ©
β
μ΄ λꡬ 40κ°
κΈ°μ‘΄ 34 + μμ΄μ νΈ κ΄λ¦¬ 6κ°
β
λμ νλ¦:
μ¬μ©μ: "μ£Όλ¬Έ μ‘°ν μμ΄μ νΈ λ§λ€μ΄μ€"
β graph-tool-callμ΄ create_agent λꡬ κ²μ
β LLMμ΄ list_available_tools β create_agent μμλ‘ νΈμΆ
β DBμ μμ΄μ νΈ μ μ μ μ₯
β μ¬μ©μμκ² κ²°κ³Ό 보κ³
νλͺ©
λ΄μ©
μν
docker.sock λ§μ΄νΈ
docker-compose.ymlμ /var/run/docker.sock λ³Όλ₯¨ μΆκ°
β
Docker CLI μ€μΉ
Dockerfileμ Docker CLI μ€μΉ μ€ν¬λ¦½νΈ μΆκ°
β
stdin λ°©μ μ€ν
νμΌ λ§μ΄νΈ λμ stdinμΌλ‘ μ½λ μ λ¬ (컨ν
μ΄λ κ²½λ‘ κ³΅μ λ¬Έμ ν΄κ²°)
β
보μ νλκ·Έ νΈν
--no-new-privileges β --security-opt no-new-privileges
β
execute_code κ²μ¦
print(sum(range(1,11))) β stdout: "55", exit_code: 0, 328ms
β
execute_code_with_test κ²μ¦
add(1,2)==3 β tests_passed: true, 409ms
β
Human-in-the-Loop e2e κ²μ¦ β
νλͺ©
λ΄μ©
μν
_active_agents λ±λ‘
SSE μ€ν μ agent λ±λ‘, μλ£ μ μ κ±°
β
νλ‘ νΈ API μμ
/api/workflow/approval β /api/approval/action, request_id + action μ€ν€λ§
β
SSE approval μ΄λ²€νΈ
log μ΄λ²€νΈμ approval νλ κ°μ§ β approval_required λ³ν
β
ApprovalRequest.request_id
νμ
+ SSE νΈλ€λ¬ + ChatMessage μ½λ°± μ 체 μ°κ²°
β
e2e ν
μ€νΈ κ²°κ³Ό:
1. SSE μμ β approval_required (request_id: apr_617ebd75)
2. GET /api/approval/pending β pending 1건
3. POST /api/approval/action β approve μ±κ³΅
4. μΉμΈ ν db_query μ€ν β SELECT 1 β rows: [{?column?: 1}]
5. LLM μλ΅ β "κ²°κ³Όκ° μ±κ³΅μ μΌλ‘ λ°νλμμ΅λλ€"
μμ΄μ νΈ μμ± ν μ ν β
νλͺ©
λ΄μ©
μν
ChatMessage λ§ν¬
create_agent μ±κ³΅ μ "μμ΄μ νΈμ λννκΈ°" λ§ν¬ μλ νμ
β
λ§ν¬ μ΄λ
/chat/{agentName}μΌλ‘ μ¦μ μ΄λ κ°λ₯
β
κΈμΌ μ§ν μ¬ν (2026-03-17)
create_tool β ToolGenerator e2e μ°κ²° β
plan.md Mode A ν΅μ¬ λΉμ "AIκ° μ½λ μμ± β μλλ°μ€ ν
μ€νΈ β λ±λ‘" μμ±.
νλͺ©
λ΄μ©
μν
ToolGenerator μ£Όμ
app.py startupμμ ModelClient + ToolGenerator μ΄κΈ°ν β set_tool_generator()
β
create_tool μ€μ°κ²°
create_tool νΈμΆ β ToolGenerator.generate() μ€ν (κΈ°μ‘΄ "pending" λ°ν μ κ±°)
β
μ½λ+ν
μ€νΈ λμ μμ±
LLM ν둬ννΈμ python + test λΈλ‘ 2κ° μΆλ ₯ μꡬ, _extract_code_and_test() νμ±
β
λ¬Έλ² κ²μ¦
μλλ°μ€μμ @tool λͺ¨νΉ + μ½λ λ‘λ β SYNTAX_OK νμΈ
β
κΈ°λ₯ ν
μ€νΈ
μλλ°μ€μμ μ½λ+ν
μ€νΈ ν¨κ» μ€ν β ALL_TESTS_PASSED assert κ²μ¦
β
νμΌ μ μ₯ + Registry λ±λ‘
tools/{name}.py μ μ₯ β load_from_file() β graph-tool-call ingest
β
μ λ¨κ³ λ‘κΉ
[ToolGenerator] μ λμ¬λ‘ μμ±βκ²μ¦βν
μ€νΈβμ μ₯βλ±λ‘ μ κ³Όμ INFO/ERROR λ‘κ·Έ
β
e2e κ²μ¦ κ²°κ³Ό:
μ¬μ©μ: "νΌλ³΄λμΉ μμ΄μ nλ²μ§Έ κ°μ ꡬνλ λꡬλ₯Ό λ§λ€μ΄μ€"
β LLMμ΄ μ½λ(532μ) + ν
μ€νΈ(591μ) μμ±
β λ¬Έλ² κ²μ¦ ν΅κ³Ό β
β κΈ°λ₯ ν
μ€νΈ: fibonacci(0)=0, fibonacci(1)=1, fibonacci(5)=5, fibonacci(10)=55 β ALL_TESTS_PASSED β
β tools/fibonacci.py μ μ₯ β Registry λ±λ‘
β μ΄ν "fibonacci(10) ꡬν΄μ€" β {"fibonacci": 55} μ¦μ μ€ν
graph-tool-call κ³ κΈ κΈ°λ₯ μ μ© β
κΈ°λ₯
λ΄μ©
μν
auto_organize()
startup μ 41κ° λꡬ μλ λΆλ₯ β 16κ° λλ©μΈ, 36κ° μΉ΄ν
κ³ λ¦¬
β
validate_tool_call()
Agent Coreμμ λꡬ μ΄λ¦ μ€ν fuzzy matching μλ κ΅μ
β
analyze() API
GET /api/tools/graph/analyze β μ€λ³΅/μΆ©λ/κ³ μ/μΉ΄ν
κ³ λ¦¬ 리ν¬νΈ
β
find_duplicates() API
GET /api/tools/graph/duplicates β 5λ¨κ³ νμ΄νλΌμΈ μ€λ³΅ νμ§
β
GraphToolManager startup μ΄κΈ°ν
app.pyμμ λ°λ‘ μ΄κΈ°ν β app.state.graph_tool_manager λ±λ‘
β
νλ‘ νΈμλ API νλ‘μ μμ β
νλͺ©
λ΄μ©
μν
REST/SSE λΆλ¦¬
BASE_URL=''(νλ‘μ) + STREAM_URL=hostname:8010(μ§μ )
β
next.config.ts
/api/history, /api/approval/*, /api/sessions/* rewrite μΆκ°
β
NEXT_PUBLIC_BACKEND_URL μ κ±°
Turbopack μ»΄νμΌνμ μΈλΌμΈ λ¬Έμ ν΄κ²°
β
λν μ΄λ ₯ μ μ§ (μΈμ
볡μ) β
νλͺ©
λ΄μ©
μν
chatSession.ts μ κ·
sessionStorageμ sessionId + messages μ μ₯/볡μ
β
historyToMessages()
λ°±μλ HistoryEntry β Message[] λ³ν (λꡬ νΈμΆ ν¬ν¨)
β
/chat 볡μ
νμ΄μ§ λ§μ΄νΈ β sessionStorage β fallback: λ°±μλ history API
β
/chat/[agentId] 볡μ
agentIdλ³ λ
립 μΈμ
κ΄λ¦¬
β
Hydration μλ¬ μμ
SSR/CSR HTML λΆμΌμΉ β useEffectμμλ§ λ³΅μ
β
νλͺ©
λ΄μ©
μν
test_graph_tool.py
threshold=0 λ³κ²½μ λ§κ² ν
μ€νΈ μμ (κΈ°μ‘΄ 2κ° μ€ν¨ ν΄μ)
β
μ΄ ν
μ€νΈ
132 passed, 0 failed (0.98s)
β
Step 1: MCP Station ν‘μ ν
μ€νΈ
xgen-mcp-stationμ΄ νλ μν μ xgen-agent λ΄μ₯ MCP ν΄λΌμ΄μΈνΈλ‘ λ체 κ°λ₯νμ§ νμΈ
Step 2: API κ²½λ‘ λ§μ΄κ·Έλ μ΄μ
(μ ν)
/api/workflow/* β /api/agent/* μ μ§μ μ ν
Step 3: graph-tool-call μΆκ° κΈ°λ₯
enable_embedding() β μλ―Έ κ²μ (ν€μλ λ―Έμ€ ν΄κ²°)
enhanced/full κ²μ λͺ¨λ β λ³΅ν© μΏΌλ¦¬ λΆν΄
νλ‘μ νΈ νμΌ κ΅¬μ‘°
xgen3.0/
βββ pyproject.toml
βββ Dockerfile
βββ docker-compose.yml β λ¨λ
μ€νμ©
βββ cli.py
βββ plan.md
βββ PROGRESS.md β μ΄ νμΌ
βββ agents/
β βββ customer-support.yaml
βββ src/
β βββ api/
β β βββ app.py
β β βββ routes.py
β β βββ models.py
β β βββ sse_adapter.py
β βββ core/
β β βββ agent.py β graph-tool-call μ°λ ν¬ν¨
β β βββ approval.py
β β βββ config.py
β β βββ context.py
β β βββ model_client.py
β β βββ permissions.py
β β βββ planner.py
β β βββ triggers.py
β βββ tools/
β β βββ decorator.py
β β βββ registry.py
β β βββ generator.py
β β βββ graph_tool.py β μ€μ graph-tool-call ν¨ν€μ§ λν (νμ νμ±)
β β βββ builtin/ (http, db, file, xgen_core, xgen_documents, xgen_utils, agent_mgmt)
β βββ sandbox/
β β βββ docker.py
β β βββ runner.py
β βββ mcp/
β β βββ client.py
β β βββ bridge.py
β βββ store/
β β βββ state.py
β β βββ agent_store.py
β β βββ history.py
β β βββ versioning.py
β βββ trace/
β βββ collector.py
β βββ exporter.py
βββ frontend/ β xgen3.0 μ μ© νλ‘ νΈμλ (λν μ€μ¬)
β βββ package.json (Next.js 15 + React 19)
β βββ next.config.ts (/api/workflow/* νλ‘μ)
β βββ src/app/
β βββ layout.tsx (Sidebar + Content)
β βββ page.tsx (/ λμ보λ)
β βββ chat/ (β
λ°λ‘ λν μμ β default μμ΄μ νΈ)
β βββ chat/[agentId]/ (νΉμ μμ΄μ νΈ λν UI)
β βββ trace/ (Trace λͺ©λ‘)
β βββ trace/[traceId]/ (Trace μμΈ β μ€ν νλ¦ νμλΌμΈ)
β βββ history/ (μ€ν μ΄λ ₯ β ν
μ΄λΈν)
β βββ agents/[agentId]/ (Agent μμΈ)
β βββ _common/ (λμμΈ μμ€ν
, API, μ»΄ν¬λνΈ)
βββ repos/ β xgen2.0 ν΄λ‘ (λ‘컬 μ€νμ©)
β βββ xgen-infra/ β λ°°ν¬ μ€μ μμ λ¨
β βββ xgen-workflow/
β βββ xgen-core/
β βββ xgen-frontend/
β βββ xgen-model/
β βββ xgen-mcp-station/
β βββ xgen-documents/
β βββ xgen-backend-gateway/
βββ tests/ (16κ° νμΌ, 116κ° ν
μ€νΈ)
βββ tools/ (컀μ€ν
λꡬ λλ ν 리)
νλͺ©
κ°
Python
3.12.10 (λ‘컬), 3.14-slim (Docker)
Docker
29.2.1
LLM
GPT-4o-mini (OpenAI API)
DB
PostgreSQL 15.4-alpine
graph-tool-call
0.13.1
νμ€ν compose
repos/xgen-infra/compose/full-stack/docker-compose.dev.yml
xgen-agent ν¬νΈ
8010 (compose), 8000 (λ¨λ
)
Swagger UI
http://localhost:8010/docs