agentx-kit 0.5.0__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/PKG-INFO +48 -1
  2. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/README.md +47 -0
  3. agentx_kit-0.6.0/examples/README.md +28 -0
  4. agentx_kit-0.6.0/examples/demo_local.sh +42 -0
  5. agentx_kit-0.6.0/examples/demo_mcp.py +78 -0
  6. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/pyproject.toml +1 -1
  7. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/__init__.py +1 -1
  8. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/connector/build.py +5 -4
  9. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/generator.py +21 -5
  10. agentx_kit-0.6.0/src/agentx/scaffold/templates/README.md.j2 +69 -0
  11. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/evals/run_evals.py.j2 +3 -9
  12. agentx_kit-0.6.0/src/agentx/scaffold/templates/pkg/agents.py.j2 +21 -0
  13. agentx_kit-0.6.0/src/agentx/scaffold/templates/pkg/crew.py.j2 +18 -0
  14. agentx_kit-0.6.0/src/agentx/scaffold/templates/pkg/graph.py.j2 +69 -0
  15. agentx_kit-0.6.0/src/agentx/scaffold/templates/pkg/main.py.j2 +45 -0
  16. agentx_kit-0.6.0/src/agentx/scaffold/templates/pkg/nodes.py.j2 +76 -0
  17. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/pkg/server.py.j2 +9 -18
  18. agentx_kit-0.6.0/src/agentx/scaffold/templates/pkg/state.py.j2 +21 -0
  19. agentx_kit-0.6.0/src/agentx/scaffold/templates/pkg/tasks.py.j2 +18 -0
  20. agentx_kit-0.6.0/src/agentx/scaffold/templates/pkg/tools.py.j2 +26 -0
  21. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/tests/test_enterprise.py +2 -1
  22. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/tests/test_scaffold.py +15 -5
  23. agentx_kit-0.5.0/src/agentx/scaffold/templates/README.md.j2 +0 -46
  24. agentx_kit-0.5.0/src/agentx/scaffold/templates/pkg/agents.py.j2 +0 -77
  25. agentx_kit-0.5.0/src/agentx/scaffold/templates/pkg/main.py.j2 +0 -87
  26. agentx_kit-0.5.0/src/agentx/scaffold/templates/pkg/tools.py.j2 +0 -16
  27. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/.agentx/llm_cache.sqlite +0 -0
  28. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/.claude-plugin/marketplace.json +0 -0
  29. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/.github/workflows/publish.yml +0 -0
  30. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/.gitignore +0 -0
  31. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/DESIGN.md +0 -0
  32. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/LICENSE +0 -0
  33. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/RESEARCH.md +0 -0
  34. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/integrations/claude-plugin/.claude-plugin/plugin.json +0 -0
  35. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/integrations/claude-plugin/.mcp.json +0 -0
  36. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/integrations/claude-plugin/README.md +0 -0
  37. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/integrations/claude-plugin/commands/new-agent.md +0 -0
  38. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/integrations/vscode/.vscodeignore +0 -0
  39. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/integrations/vscode/README.md +0 -0
  40. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/integrations/vscode/extension.js +0 -0
  41. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/integrations/vscode/package.json +0 -0
  42. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/cache.py +0 -0
  43. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/cli.py +0 -0
  44. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/config.py +0 -0
  45. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/connector/__init__.py +0 -0
  46. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/connector/recommend.py +0 -0
  47. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/connector/server.py +0 -0
  48. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/dashboard/__init__.py +0 -0
  49. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/dashboard/app.py +0 -0
  50. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/frameworks/__init__.py +0 -0
  51. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/frameworks/crewai_agent.py +0 -0
  52. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/frameworks/langchain_agent.py +0 -0
  53. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/guardrails.py +0 -0
  54. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/insights/__init__.py +0 -0
  55. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/insights/analyze.py +0 -0
  56. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/insights/log.py +0 -0
  57. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/insights/optimize.py +0 -0
  58. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/insights/tokens.py +0 -0
  59. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/memory/__init__.py +0 -0
  60. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/memory/store.py +0 -0
  61. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/observability.py +0 -0
  62. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/prompts/__init__.py +0 -0
  63. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/prompts/templates.py +0 -0
  64. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/providers/__init__.py +0 -0
  65. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/providers/base.py +0 -0
  66. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/providers/factory.py +0 -0
  67. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/providers/registry.py +0 -0
  68. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/rag/__init__.py +0 -0
  69. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/rag/pipeline.py +0 -0
  70. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/reliability.py +0 -0
  71. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/__init__.py +0 -0
  72. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/prompts_store.py +0 -0
  73. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/spec.py +0 -0
  74. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/Dockerfile.j2 +0 -0
  75. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/ci.yml.j2 +0 -0
  76. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/docker-compose.yml.j2 +0 -0
  77. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/dockerignore.j2 +0 -0
  78. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/env.example.j2 +0 -0
  79. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/evals/dataset.json.j2 +0 -0
  80. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/gitignore.j2 +0 -0
  81. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/mcp_servers.json.j2 +0 -0
  82. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/pkg/__init__.py.j2 +0 -0
  83. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/pkg/config.py.j2 +0 -0
  84. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/pkg/guardrails.py.j2 +0 -0
  85. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/pkg/memory.py.j2 +0 -0
  86. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/pkg/observability.py.j2 +0 -0
  87. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/pkg/prompts.py.j2 +0 -0
  88. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/pkg/rag.py.j2 +0 -0
  89. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/pyproject.toml.j2 +0 -0
  90. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/templates/skills_seed.json.j2 +0 -0
  91. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/scaffold/wizard.py +0 -0
  92. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/skills/__init__.py +0 -0
  93. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/skills/registry.py +0 -0
  94. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/structured.py +0 -0
  95. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/tools/__init__.py +0 -0
  96. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/tools/builtin.py +0 -0
  97. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/src/agentx/tools/mcp.py +0 -0
  98. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/tests/test_cache.py +0 -0
  99. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/tests/test_connector.py +0 -0
  100. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/tests/test_insights.py +0 -0
  101. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/tests/test_prompts.py +0 -0
  102. {agentx_kit-0.5.0 → agentx_kit-0.6.0}/tests/test_providers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentx-kit
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: An open-source, provider-agnostic agentic framework + interactive project scaffolder for LangChain and CrewAI. Pick your LLM provider, agents, RAG, memory, MCP tools and skills — generate a ready-to-run uv project.
5
5
  Project-URL: Homepage, https://github.com/muhammadyahiya/agentx-kit
6
6
  Project-URL: Repository, https://github.com/muhammadyahiya/agentx-kit
@@ -123,6 +123,53 @@ agentx new # interactive wizard → scaffolds a uv project
123
123
  > The PyPI distribution is **`agentx-kit`**; the import name and CLI are **`agentx`**
124
124
  > (`pip install agentx-kit` → `import agentx` / `agentx --help`).
125
125
 
126
+ ## 🚀 60-second walkthrough
127
+ ```bash
128
+ # 1. Install
129
+ pip install "agentx-kit[all]"
130
+
131
+ # 2. See what you can target
132
+ agentx providers # 9 LLM providers + the env vars each needs
133
+
134
+ # 3. Scaffold a complete project from one line (no keys needed to generate)
135
+ agentx new --yes --name my-bot \
136
+ --provider openai \
137
+ --prompt "You are a support agent that answers from our docs."
138
+
139
+ # 4. Run it
140
+ cd my-bot && cp .env.example .env # add your API key
141
+ uv sync && uv run my-bot
142
+
143
+ # 5. Tune prompts live (tokens, cost, quality, optimize) — optional UI
144
+ pip install "agentx-kit[dashboard]" && agentx dashboard
145
+
146
+ # 6. Use it from Claude / Copilot / Codex
147
+ claude mcp add agentx-kit -- agentx mcp
148
+ ```
149
+ Prefer guided? Just run `agentx new` (interactive wizard) or
150
+ `agentx new --enterprise` for the full production stack
151
+ (tracing, guardrails, FastAPI, Docker, CI, evals, caching).
152
+
153
+ ### 🧭 Command cheat-sheet
154
+ | Command | What it does |
155
+ |---|---|
156
+ | `agentx new` | Interactive wizard → scaffold a uv project |
157
+ | `agentx new --yes [opts]` | Non-interactive scaffold (`--enterprise` for the full pack) |
158
+ | `agentx providers` | List LLM providers + required env vars |
159
+ | `agentx prompt list/set/add/remove` | Manage an existing project's prompts (`-d` opens the dashboard) |
160
+ | `agentx dashboard` | Prompt observability + optimization UI (`[dashboard]` extra) |
161
+ | `agentx cache stats / clear` | Inspect/clear the LLM response cache |
162
+ | `agentx mcp` | Run as an MCP server for Claude/Copilot/Codex |
163
+ | `agentx mcp --print-config` | Print the client config for those tools |
164
+ | `agentx version` | Show the installed version |
165
+
166
+ ### ▶️ Try the demos (no API keys needed)
167
+ ```bash
168
+ bash examples/demo_local.sh # verify local setup end-to-end
169
+ python examples/demo_mcp.py # test the Claude/Copilot MCP path (real handshake)
170
+ ```
171
+ See [`examples/`](examples/) for details.
172
+
126
173
  ## 📦 Installation
127
174
 
128
175
  ### From PyPI (recommended)
@@ -19,6 +19,53 @@ agentx new # interactive wizard → scaffolds a uv project
19
19
  > The PyPI distribution is **`agentx-kit`**; the import name and CLI are **`agentx`**
20
20
  > (`pip install agentx-kit` → `import agentx` / `agentx --help`).
21
21
 
22
+ ## 🚀 60-second walkthrough
23
+ ```bash
24
+ # 1. Install
25
+ pip install "agentx-kit[all]"
26
+
27
+ # 2. See what you can target
28
+ agentx providers # 9 LLM providers + the env vars each needs
29
+
30
+ # 3. Scaffold a complete project from one line (no keys needed to generate)
31
+ agentx new --yes --name my-bot \
32
+ --provider openai \
33
+ --prompt "You are a support agent that answers from our docs."
34
+
35
+ # 4. Run it
36
+ cd my-bot && cp .env.example .env # add your API key
37
+ uv sync && uv run my-bot
38
+
39
+ # 5. Tune prompts live (tokens, cost, quality, optimize) — optional UI
40
+ pip install "agentx-kit[dashboard]" && agentx dashboard
41
+
42
+ # 6. Use it from Claude / Copilot / Codex
43
+ claude mcp add agentx-kit -- agentx mcp
44
+ ```
45
+ Prefer guided? Just run `agentx new` (interactive wizard) or
46
+ `agentx new --enterprise` for the full production stack
47
+ (tracing, guardrails, FastAPI, Docker, CI, evals, caching).
48
+
49
+ ### 🧭 Command cheat-sheet
50
+ | Command | What it does |
51
+ |---|---|
52
+ | `agentx new` | Interactive wizard → scaffold a uv project |
53
+ | `agentx new --yes [opts]` | Non-interactive scaffold (`--enterprise` for the full pack) |
54
+ | `agentx providers` | List LLM providers + required env vars |
55
+ | `agentx prompt list/set/add/remove` | Manage an existing project's prompts (`-d` opens the dashboard) |
56
+ | `agentx dashboard` | Prompt observability + optimization UI (`[dashboard]` extra) |
57
+ | `agentx cache stats / clear` | Inspect/clear the LLM response cache |
58
+ | `agentx mcp` | Run as an MCP server for Claude/Copilot/Codex |
59
+ | `agentx mcp --print-config` | Print the client config for those tools |
60
+ | `agentx version` | Show the installed version |
61
+
62
+ ### ▶️ Try the demos (no API keys needed)
63
+ ```bash
64
+ bash examples/demo_local.sh # verify local setup end-to-end
65
+ python examples/demo_mcp.py # test the Claude/Copilot MCP path (real handshake)
66
+ ```
67
+ See [`examples/`](examples/) for details.
68
+
22
69
  ## 📦 Installation
23
70
 
24
71
  ### From PyPI (recommended)
@@ -0,0 +1,28 @@
1
+ # AgentX-Kit demos
2
+
3
+ Two runnable demos to confirm your setup — **no API keys required** (scaffolding
4
+ and insights are offline; LLM calls are optional).
5
+
6
+ ## 1. Local setup test
7
+ Verifies the install, lists providers, scaffolds a demo project, and exercises
8
+ prompt insights + the response cache.
9
+
10
+ ```bash
11
+ pip install "agentx-kit[all]"
12
+ bash examples/demo_local.sh
13
+ ```
14
+
15
+ ## 2. MCP connector test (the Claude / Copilot / Codex path)
16
+ Spawns `agentx mcp` over stdio, does a real MCP handshake, lists the tools, and
17
+ scaffolds a complete project from a one-line problem statement — exactly what an
18
+ assistant does when connected.
19
+
20
+ ```bash
21
+ pip install "agentx-kit[connector]"
22
+ python examples/demo_mcp.py
23
+ ```
24
+
25
+ Then wire it into Claude for real:
26
+ ```bash
27
+ claude mcp add agentx-kit -- agentx mcp
28
+ ```
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env bash
2
+ # AgentX-Kit — local setup smoke test. No API keys required.
3
+ # Verifies the install, lists providers, scaffolds a demo project, and exercises
4
+ # the prompt-insights + cache so you know everything works end-to-end.
5
+ #
6
+ # bash examples/demo_local.sh
7
+ set -euo pipefail
8
+
9
+ # Resolve the CLI: prefer `agentx` on PATH, else `python -m agentx.cli`.
10
+ if command -v agentx >/dev/null 2>&1; then
11
+ AGENTX="agentx"
12
+ else
13
+ AGENTX="python -m agentx.cli"
14
+ fi
15
+ echo "▶ using: $AGENTX"
16
+
17
+ echo; echo "==> 1) version"
18
+ $AGENTX version
19
+
20
+ echo; echo "==> 2) providers (no keys needed to list)"
21
+ $AGENTX providers
22
+
23
+ WORK="$(mktemp -d)"; trap 'echo; echo "demo project left at: $WORK"' EXIT
24
+ echo; echo "==> 3) scaffold a demo project (local Ollama provider, no key)"
25
+ ( cd "$WORK" && $AGENTX new --yes --name demo-agent --provider ollama \
26
+ --prompt "You are a helpful onboarding assistant." --no-venv )
27
+ echo "files:"
28
+ find "$WORK/demo-agent" -maxdepth 3 -type f | sed "s|$WORK/||" | sort
29
+
30
+ echo; echo "==> 4) prompt insights (offline)"
31
+ python - <<'PY'
32
+ from agentx import analyze_prompt, count_tokens
33
+ a = analyze_prompt("You are a support agent. Goal: answer in JSON. Do not invent policy.", "gpt-4o-mini")
34
+ print(f" quality={a.quality_score}/100 tokens={a.tokens} suggestions={len(a.suggestions)}")
35
+ PY
36
+
37
+ echo; echo "==> 5) response cache stats"
38
+ $AGENTX cache stats || true
39
+
40
+ echo; echo "✅ Local setup looks good."
41
+ echo "Next: cd $WORK/demo-agent && uv sync && uv run demo-agent"
42
+ echo " $AGENTX dashboard # prompt observability UI (needs [dashboard] extra)"
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env python
2
+ """AgentX-Kit — MCP connector demo (the same path Claude / Copilot / Codex use).
3
+
4
+ Spawns `agentx mcp` over stdio, performs a real MCP handshake, lists tools, and
5
+ calls them to scaffold a complete project from a one-line problem statement —
6
+ exactly what an MCP client (Claude) does. No API keys required (scaffolding is
7
+ template generation).
8
+
9
+ pip install "agentx-kit[connector]"
10
+ python examples/demo_mcp.py
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import asyncio
15
+ import json
16
+ import sys
17
+ import tempfile
18
+
19
+
20
+ def _extract(result) -> dict:
21
+ """Pull a dict out of an MCP CallToolResult (structured or text content)."""
22
+ structured = getattr(result, "structuredContent", None)
23
+ if isinstance(structured, dict):
24
+ return structured.get("result", structured)
25
+ for block in getattr(result, "content", []) or []:
26
+ text = getattr(block, "text", None)
27
+ if text:
28
+ try:
29
+ return json.loads(text)
30
+ except json.JSONDecodeError:
31
+ return {"text": text}
32
+ return {}
33
+
34
+
35
+ async def main() -> int:
36
+ try:
37
+ from mcp import ClientSession, StdioServerParameters
38
+ from mcp.client.stdio import stdio_client
39
+ except ImportError:
40
+ print("Install the connector extra first: pip install 'agentx-kit[connector]'")
41
+ return 1
42
+
43
+ # Launch the same server Claude would (use this interpreter for portability).
44
+ params = StdioServerParameters(command=sys.executable, args=["-m", "agentx.cli", "mcp"])
45
+
46
+ print("▶ connecting to `agentx mcp` over stdio …")
47
+ async with stdio_client(params) as (read, write):
48
+ async with ClientSession(read, write) as session:
49
+ await session.initialize()
50
+
51
+ tools = await session.list_tools()
52
+ print("✓ connected. tools:", [t.name for t in tools.tools])
53
+
54
+ problem = "Build a customer-support agent that answers from our product docs and serves a REST API."
55
+ print(f"\n▶ recommend_project('{problem[:50]}…')")
56
+ rec = _extract(await session.call_tool("recommend_project", {"problem_statement": problem}))
57
+ print(f" framework={rec.get('framework')} features={rec.get('features')}")
58
+
59
+ out_dir = tempfile.mkdtemp(prefix="agentx-mcp-demo-")
60
+ print("\n▶ create_agent_project(…)")
61
+ res = _extract(await session.call_tool(
62
+ "create_agent_project",
63
+ {"problem_statement": problem, "output_dir": out_dir + "/support-bot"},
64
+ ))
65
+ if not res.get("ok"):
66
+ print(" ✗ failed:", res.get("error"))
67
+ return 1
68
+ print(f" ✓ generated {len(res['file_tree'])} files at {res['target_dir']}")
69
+ print(" features:", res["features"])
70
+ print(" run:", res["next_steps"][-1])
71
+
72
+ print("\n✅ MCP connector works — Claude/Copilot/Codex can drive this exact flow.")
73
+ print(" Add it to Claude: claude mcp add agentx-kit -- agentx mcp")
74
+ return 0
75
+
76
+
77
+ if __name__ == "__main__":
78
+ raise SystemExit(asyncio.run(main()))
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  # PyPI distribution name (import name + CLI stay `agentx`; `agentx` was taken).
3
3
  name = "agentx-kit"
4
- version = "0.5.0"
4
+ version = "0.6.0"
5
5
  description = "An open-source, provider-agnostic agentic framework + interactive project scaffolder for LangChain and CrewAI. Pick your LLM provider, agents, RAG, memory, MCP tools and skills — generate a ready-to-run uv project."
6
6
  readme = "README.md"
7
7
  requires-python = ">=3.10,<3.14"
@@ -16,7 +16,7 @@ is enough to get started.
16
16
  """
17
17
  from __future__ import annotations
18
18
 
19
- __version__ = "0.5.0"
19
+ __version__ = "0.6.0"
20
20
 
21
21
  from .providers import ( # noqa: E402
22
22
  ProviderSpec,
@@ -74,10 +74,11 @@ def build_project_from_statement(
74
74
  # Collect a compact view for the calling LLM.
75
75
  tree = sorted(str(p.relative_to(root)) for p in root.glob("**/*") if p.is_file())
76
76
  pkg = spec.package
77
- key_paths = [
78
- "pyproject.toml", "prompts.json", "agentx.json",
79
- f"src/{pkg}/main.py", f"src/{pkg}/agents.py", f"src/{pkg}/prompts.py",
80
- ]
77
+ key_paths = ["pyproject.toml", "prompts.json", "agentx.json", f"src/{pkg}/main.py"]
78
+ if spec.framework == "langgraph":
79
+ key_paths += [f"src/{pkg}/graph.py", f"src/{pkg}/state.py", f"src/{pkg}/nodes.py"]
80
+ else:
81
+ key_paths += [f"src/{pkg}/crew.py", f"src/{pkg}/agents.py", f"src/{pkg}/tasks.py"]
81
82
  if spec.serve:
82
83
  key_paths.append(f"src/{pkg}/server.py")
83
84
  key_files = {}
@@ -18,8 +18,8 @@ from .spec import ProjectSpec
18
18
 
19
19
  TEMPLATES_DIR = Path(__file__).parent / "templates"
20
20
 
21
- # (template, output-relative-path, include?) — output paths use {pkg} placeholder.
22
- _FILE_PLAN: list[tuple[str, str]] = [
21
+ # (template, output-relative-path) — output paths use {pkg} placeholder.
22
+ _COMMON_FILES: list[tuple[str, str]] = [
23
23
  ("pyproject.toml.j2", "pyproject.toml"),
24
24
  ("README.md.j2", "README.md"),
25
25
  ("env.example.j2", ".env.example"),
@@ -27,10 +27,24 @@ _FILE_PLAN: list[tuple[str, str]] = [
27
27
  ("pkg/__init__.py.j2", "src/{pkg}/__init__.py"),
28
28
  ("pkg/config.py.j2", "src/{pkg}/config.py"),
29
29
  ("pkg/prompts.py.j2", "src/{pkg}/prompts.py"),
30
- ("pkg/agents.py.j2", "src/{pkg}/agents.py"),
31
30
  ("pkg/main.py.j2", "src/{pkg}/main.py"),
32
31
  ]
33
32
 
33
+ # A real LangGraph project: explicit state + nodes + graph + tool assembly.
34
+ _LANGGRAPH_FILES: list[tuple[str, str]] = [
35
+ ("pkg/state.py.j2", "src/{pkg}/state.py"),
36
+ ("pkg/tools.py.j2", "src/{pkg}/tools.py"),
37
+ ("pkg/nodes.py.j2", "src/{pkg}/nodes.py"),
38
+ ("pkg/graph.py.j2", "src/{pkg}/graph.py"),
39
+ ]
40
+
41
+ # A real CrewAI project: agents + tasks + crew.
42
+ _CREWAI_FILES: list[tuple[str, str]] = [
43
+ ("pkg/agents.py.j2", "src/{pkg}/agents.py"),
44
+ ("pkg/tasks.py.j2", "src/{pkg}/tasks.py"),
45
+ ("pkg/crew.py.j2", "src/{pkg}/crew.py"),
46
+ ]
47
+
34
48
 
35
49
  @dataclass
36
50
  class GenerationResult:
@@ -70,6 +84,7 @@ def _context(spec: ProjectSpec) -> dict:
70
84
  "provider_env": list(provider_spec.env_vars),
71
85
  "extras": _extras(spec),
72
86
  "extras_str": ",".join(_extras(spec)),
87
+ "multi_agent": len(spec.agents) > 1,
73
88
  }
74
89
 
75
90
 
@@ -85,12 +100,13 @@ def _env() -> Environment:
85
100
 
86
101
  def _conditional_files(spec: ProjectSpec) -> list[tuple[str, str]]:
87
102
  plan: list[tuple[str, str]] = []
103
+ # Framework-specific core (real project structure).
104
+ plan += _LANGGRAPH_FILES if spec.framework == "langgraph" else _CREWAI_FILES
88
105
  if spec.use_rag:
89
106
  plan.append(("pkg/rag.py.j2", "src/{pkg}/rag.py"))
90
107
  if spec.needs_memory:
91
108
  plan.append(("pkg/memory.py.j2", "src/{pkg}/memory.py"))
92
109
  if spec.use_mcp:
93
- plan.append(("pkg/tools.py.j2", "src/{pkg}/tools.py"))
94
110
  plan.append(("mcp_servers.json.j2", "mcp_servers.json"))
95
111
  if spec.use_skills:
96
112
  plan.append(("skills_seed.json.j2", "data/skills/star-method.json"))
@@ -156,7 +172,7 @@ def generate_project(spec: ProjectSpec, target_dir: str | Path, overwrite: bool
156
172
  written: list[Path] = []
157
173
  messages: list[str] = []
158
174
 
159
- for template_name, out_rel in _FILE_PLAN + _conditional_files(spec):
175
+ for template_name, out_rel in _COMMON_FILES + _conditional_files(spec):
160
176
  out_path = target / out_rel.format(pkg=spec.package)
161
177
  out_path.parent.mkdir(parents=True, exist_ok=True)
162
178
  rendered = env.get_template(template_name).render(**ctx)
@@ -0,0 +1,69 @@
1
+ # {{ spec.slug }}
2
+
3
+ Agentic app generated by **AgentX**.
4
+
5
+ - **Framework:** {{ spec.framework }}
6
+ - **Provider:** {{ provider_label }} (`{{ model }}`)
7
+ - **Agents:** {% for a in spec.agents %}`{{ a.name }}`{% if not loop.last %}, {% endif %}{% endfor %}
8
+
9
+ - **RAG:** {{ "yes" if spec.use_rag else "no" }}
10
+ - **Memory:** {{ spec.memory }}
11
+ - **MCP tools:** {{ "yes" if spec.use_mcp else "no" }}
12
+ - **Skills:** {{ "yes" if spec.use_skills else "no" }}
13
+
14
+ ## Setup
15
+ ```bash
16
+ uv sync # install dependencies into .venv
17
+ cp .env.example .env # then fill in your credentials
18
+ ```
19
+
20
+ ## Run
21
+ ```bash
22
+ uv run {{ spec.slug }}
23
+ # or:
24
+ uv run python -m {{ pkg }}.main
25
+ {% if spec.serve %}# API server:
26
+ uv run uvicorn {{ pkg }}.server:app --reload
27
+ {% endif %}
28
+ ```
29
+ {% if spec.framework == 'langgraph' %}
30
+ Uses LangGraph's dev server too: `uvx langgraph dev` (the compiled graph is
31
+ `{{ pkg }}.graph:graph`).
32
+
33
+ ## Layout (LangGraph)
34
+ ```
35
+ src/{{ pkg }}/
36
+ ├── config.py # provider/model selection (pydantic-settings)
37
+ ├── prompts.py # loads prompts.json (edit prompts there or via `agentx prompt`)
38
+ ├── state.py # AgentState — the typed graph state (messages + reducers)
39
+ ├── tools.py # tool assembly (web search{% if spec.use_rag %} + knowledge base{% endif %}{% if spec.use_mcp %} + MCP{% endif %})
40
+ ├── nodes.py # graph nodes ({% if multi_agent %}supervisor + workers{% else %}the agent model call{% endif %})
41
+ ├── graph.py # StateGraph workflow + compiled `graph` + run_text()
42
+ {% if spec.use_rag %}├── rag.py # knowledge base / retriever tool
43
+ {% endif %}
44
+ {% if spec.needs_memory %}├── memory.py # conversation / long-term memory helpers
45
+ {% endif %}
46
+ {% if spec.serve %}├── server.py # FastAPI (REST + SSE)
47
+ {% endif %}
48
+ └── main.py # interactive REPL
49
+ ```
50
+ {% else %}
51
+ ## Layout (CrewAI)
52
+ ```
53
+ src/{{ pkg }}/
54
+ ├── config.py # provider/model selection (pydantic-settings)
55
+ ├── prompts.py # loads prompts.json
56
+ ├── agents.py # CrewAI Agent definitions
57
+ ├── tasks.py # Task definitions
58
+ ├── crew.py # Crew assembly + run_text()
59
+ {% if spec.serve %}├── server.py # FastAPI (REST + SSE)
60
+ {% endif %}
61
+ └── main.py # interactive REPL
62
+ ```
63
+ {% endif %}
64
+ {% if spec.use_rag %}
65
+ Add `.txt`/`.md` files under `knowledge/` to populate the RAG index.
66
+ {% endif %}
67
+ {% if spec.use_mcp %}
68
+ Edit `mcp_servers.json` to configure your MCP servers.
69
+ {% endif %}
@@ -17,10 +17,9 @@ from dotenv import load_dotenv
17
17
 
18
18
  from agentx import get_chat_model
19
19
  {% if spec.framework == 'langgraph' %}
20
- from agentx.frameworks import run_agent
21
- from {{ pkg }}.agents import build_agents
20
+ from {{ pkg }}.graph import run_text
22
21
  {% else %}
23
- from {{ pkg }}.agents import build_project_crew
22
+ from {{ pkg }}.crew import run_text
24
23
  {% endif %}
25
24
 
26
25
  THRESHOLD = 0.6
@@ -35,12 +34,7 @@ JUDGE_PROMPT = (
35
34
 
36
35
 
37
36
  def _agent_reply(message: str) -> str:
38
- {% if spec.framework == 'langgraph' %}
39
- agent = next(iter(build_agents().values()))
40
- return run_agent(agent, message)
41
- {% else %}
42
- return str(build_project_crew(message).kickoff())
43
- {% endif %}
37
+ return run_text(message)
44
38
 
45
39
 
46
40
  def _score(judge, case: dict, output: str) -> float:
@@ -0,0 +1,21 @@
1
+ """Agent definitions (CrewAI) for {{ spec.slug }} — built from prompts.json."""
2
+ from __future__ import annotations
3
+
4
+ from agentx.frameworks import build_crewai_agent
5
+ from .config import MODEL, PROVIDER
6
+ from .prompts import agents_meta, resolved_system_prompts
7
+
8
+
9
+ def build_agents() -> dict:
10
+ """Return {name: CrewAI Agent} — one per entry in prompts.json."""
11
+ prompts = resolved_system_prompts()
12
+ agents: dict = {}
13
+ for name, meta in agents_meta().items():
14
+ agents[name] = build_crewai_agent(
15
+ role=meta.get("role", name),
16
+ goal=meta.get("goal", "Help the user accomplish their task accurately."),
17
+ backstory=prompts.get(name, ""),
18
+ provider=PROVIDER,
19
+ model=MODEL,
20
+ )
21
+ return agents
@@ -0,0 +1,18 @@
1
+ """Crew assembly (CrewAI) for {{ spec.slug }}."""
2
+ from __future__ import annotations
3
+
4
+ from agentx.frameworks import build_crew
5
+ from .agents import build_agents
6
+ from .tasks import build_tasks
7
+
8
+
9
+ def build_project_crew(user_input: str):
10
+ """Assemble a sequential crew of all agents for the user's request."""
11
+ agents = build_agents()
12
+ tasks = build_tasks(user_input, agents)
13
+ return build_crew(list(agents.values()), tasks)
14
+
15
+
16
+ def run_text(message: str) -> str:
17
+ """Run the crew on a message and return the final text (used by main/server)."""
18
+ return str(build_project_crew(message).kickoff())
@@ -0,0 +1,69 @@
1
+ """LangGraph workflow for {{ spec.slug }}.
2
+
3
+ Exposes a module-level compiled ``graph`` (the LangGraph convention, also picked
4
+ up by ``langgraph dev``) and a ``run_text`` helper for CLI/server use.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from langgraph.checkpoint.memory import MemorySaver
9
+ from langgraph.graph import END, START, StateGraph
10
+
11
+ from .state import AgentState
12
+ {% if not multi_agent %}
13
+ from langgraph.prebuilt import ToolNode, tools_condition
14
+
15
+ from .nodes import call_model
16
+ from .tools import get_tools
17
+
18
+
19
+ def build_graph():
20
+ """Build the ReAct agent graph: agent ⇄ tools, with checkpointed memory."""
21
+ builder = StateGraph(AgentState)
22
+ builder.add_node("agent", call_model)
23
+ builder.add_node("tools", ToolNode(get_tools()))
24
+
25
+ builder.add_edge(START, "agent")
26
+ # If the model asked for a tool, go run it; otherwise finish.
27
+ builder.add_conditional_edges("agent", tools_condition)
28
+ builder.add_edge("tools", "agent")
29
+
30
+ return builder.compile(checkpointer=MemorySaver())
31
+ {% else %}
32
+ from .nodes import WORKERS, make_worker, supervisor
33
+ from .prompts import resolved_system_prompts
34
+
35
+
36
+ def build_graph():
37
+ """Build a supervisor multi-agent graph: supervisor routes to workers."""
38
+ builder = StateGraph(AgentState)
39
+ builder.add_node("supervisor", supervisor)
40
+ for name, system_prompt in resolved_system_prompts().items():
41
+ builder.add_node(name, make_worker(name, system_prompt))
42
+
43
+ builder.add_edge(START, "supervisor")
44
+ # Supervisor decides the next worker, or ends.
45
+ builder.add_conditional_edges(
46
+ "supervisor",
47
+ lambda state: state.get("next", "FINISH"),
48
+ {**{name: name for name in WORKERS}, "FINISH": END},
49
+ )
50
+ # Every worker reports back to the supervisor.
51
+ for name in WORKERS:
52
+ builder.add_edge(name, "supervisor")
53
+
54
+ return builder.compile(checkpointer=MemorySaver())
55
+ {% endif %}
56
+
57
+
58
+ # Module-level compiled graph (import this, or run `langgraph dev`).
59
+ graph = build_graph()
60
+
61
+
62
+ def run_text(message: str, thread_id: str = "default") -> str:
63
+ """Invoke the graph with one user message; return the final text reply."""
64
+ result = graph.invoke(
65
+ {"messages": [{"role": "user", "content": message}]},
66
+ config={"configurable": {"thread_id": thread_id}},
67
+ )
68
+ messages = result.get("messages", [])
69
+ return getattr(messages[-1], "content", "") if messages else ""
@@ -0,0 +1,45 @@
1
+ """Entry point for {{ spec.slug }} — an interactive REPL over the agent graph."""
2
+ from __future__ import annotations
3
+
4
+ from dotenv import load_dotenv
5
+ {% if spec.observability %}from .observability import init_observability
6
+ {% endif %}
7
+ {% if spec.guardrails %}from .guardrails import guard_input, guard_output
8
+ {% endif %}
9
+ {% if spec.use_cache %}from agentx.cache import enable_caching
10
+ {% endif %}
11
+ {% if spec.framework == 'langgraph' %}from .graph import run_text
12
+ {% else %}from .crew import run_text
13
+ {% endif %}
14
+
15
+
16
+ def main() -> None:
17
+ load_dotenv()
18
+ {% if spec.observability %}
19
+ init_observability()
20
+ {% endif %}
21
+ {% if spec.use_cache %}
22
+ enable_caching() # cache LLM responses → lower cost & latency
23
+ {% endif %}
24
+ print("🧬 {{ spec.slug }} ready. Type 'quit' to exit.\n")
25
+ while True:
26
+ try:
27
+ user = input("you > ").strip()
28
+ except (EOFError, KeyboardInterrupt):
29
+ break
30
+ if user.lower() in {"quit", "exit"}:
31
+ break
32
+ if not user:
33
+ continue
34
+ {% if spec.guardrails %}
35
+ user = guard_input(user).text
36
+ {% endif %}
37
+ reply = run_text(user)
38
+ {% if spec.guardrails %}
39
+ reply = guard_output(reply).text
40
+ {% endif %}
41
+ print(f"\nbot > {reply}\n")
42
+
43
+
44
+ if __name__ == "__main__":
45
+ main()