agentx-kit 0.2.0__py3-none-any.whl

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 (58) hide show
  1. agentx/__init__.py +55 -0
  2. agentx/cli.py +230 -0
  3. agentx/config.py +34 -0
  4. agentx/frameworks/__init__.py +5 -0
  5. agentx/frameworks/crewai_agent.py +52 -0
  6. agentx/frameworks/langchain_agent.py +43 -0
  7. agentx/guardrails.py +89 -0
  8. agentx/memory/__init__.py +4 -0
  9. agentx/memory/store.py +78 -0
  10. agentx/observability.py +103 -0
  11. agentx/prompts/__init__.py +8 -0
  12. agentx/prompts/templates.py +40 -0
  13. agentx/providers/__init__.py +15 -0
  14. agentx/providers/base.py +50 -0
  15. agentx/providers/factory.py +71 -0
  16. agentx/providers/registry.py +165 -0
  17. agentx/rag/__init__.py +8 -0
  18. agentx/rag/pipeline.py +121 -0
  19. agentx/reliability.py +112 -0
  20. agentx/scaffold/__init__.py +14 -0
  21. agentx/scaffold/generator.py +190 -0
  22. agentx/scaffold/prompts_store.py +99 -0
  23. agentx/scaffold/spec.py +85 -0
  24. agentx/scaffold/templates/Dockerfile.j2 +17 -0
  25. agentx/scaffold/templates/README.md.j2 +46 -0
  26. agentx/scaffold/templates/ci.yml.j2 +41 -0
  27. agentx/scaffold/templates/docker-compose.yml.j2 +9 -0
  28. agentx/scaffold/templates/dockerignore.j2 +11 -0
  29. agentx/scaffold/templates/env.example.j2 +12 -0
  30. agentx/scaffold/templates/evals/dataset.json.j2 +10 -0
  31. agentx/scaffold/templates/evals/run_evals.py.j2 +70 -0
  32. agentx/scaffold/templates/gitignore.j2 +8 -0
  33. agentx/scaffold/templates/mcp_servers.json.j2 +7 -0
  34. agentx/scaffold/templates/pkg/__init__.py.j2 +3 -0
  35. agentx/scaffold/templates/pkg/agents.py.j2 +77 -0
  36. agentx/scaffold/templates/pkg/config.py.j2 +25 -0
  37. agentx/scaffold/templates/pkg/guardrails.py.j2 +21 -0
  38. agentx/scaffold/templates/pkg/main.py.j2 +79 -0
  39. agentx/scaffold/templates/pkg/memory.py.j2 +17 -0
  40. agentx/scaffold/templates/pkg/observability.py.j2 +17 -0
  41. agentx/scaffold/templates/pkg/prompts.py.j2 +45 -0
  42. agentx/scaffold/templates/pkg/rag.py.j2 +37 -0
  43. agentx/scaffold/templates/pkg/server.py.j2 +85 -0
  44. agentx/scaffold/templates/pkg/tools.py.j2 +16 -0
  45. agentx/scaffold/templates/pyproject.toml.j2 +28 -0
  46. agentx/scaffold/templates/skills_seed.json.j2 +6 -0
  47. agentx/scaffold/wizard.py +125 -0
  48. agentx/skills/__init__.py +4 -0
  49. agentx/skills/registry.py +63 -0
  50. agentx/structured.py +37 -0
  51. agentx/tools/__init__.py +5 -0
  52. agentx/tools/builtin.py +45 -0
  53. agentx/tools/mcp.py +64 -0
  54. agentx_kit-0.2.0.dist-info/METADATA +289 -0
  55. agentx_kit-0.2.0.dist-info/RECORD +58 -0
  56. agentx_kit-0.2.0.dist-info/WHEEL +4 -0
  57. agentx_kit-0.2.0.dist-info/entry_points.txt +2 -0
  58. agentx_kit-0.2.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,4 @@
1
+ """User-extensible skills: reusable instruction blocks injected into prompts."""
2
+ from .registry import Skill, SkillRegistry, get_skill_registry
3
+
4
+ __all__ = ["Skill", "SkillRegistry", "get_skill_registry"]
@@ -0,0 +1,63 @@
1
+ """Filesystem-backed skill registry.
2
+
3
+ A *skill* is a named instruction block (e.g. "Always use the STAR method") that
4
+ gets injected into agent prompts. Skills are stored as JSON files under a
5
+ directory so users can add/version them outside the code.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import re
11
+ from dataclasses import asdict, dataclass
12
+ from pathlib import Path
13
+
14
+
15
+ def _slug(name: str) -> str:
16
+ return re.sub(r"[^a-z0-9]+", "-", name.strip().lower()).strip("-") or "skill"
17
+
18
+
19
+ @dataclass
20
+ class Skill:
21
+ slug: str
22
+ name: str
23
+ description: str
24
+ instructions: str
25
+
26
+
27
+ class SkillRegistry:
28
+ def __init__(self, directory: str | Path):
29
+ self.dir = Path(directory)
30
+ self.dir.mkdir(parents=True, exist_ok=True)
31
+
32
+ def add(self, name: str, description: str, instructions: str) -> Skill:
33
+ if not name.strip():
34
+ raise ValueError("Skill name is required.")
35
+ skill = Skill(_slug(name), name.strip(), description.strip(), instructions.strip())
36
+ (self.dir / f"{skill.slug}.json").write_text(json.dumps(asdict(skill), indent=2), encoding="utf-8")
37
+ return skill
38
+
39
+ def list(self) -> list[Skill]:
40
+ out: list[Skill] = []
41
+ for fp in sorted(self.dir.glob("*.json")):
42
+ try:
43
+ out.append(Skill(**json.loads(fp.read_text(encoding="utf-8"))))
44
+ except Exception: # noqa: BLE001 - skip malformed files
45
+ continue
46
+ return out
47
+
48
+ def delete(self, slug: str) -> None:
49
+ (self.dir / f"{slug}.json").unlink(missing_ok=True)
50
+
51
+ def combined_instructions(self, slugs: list[str] | None = None) -> str:
52
+ """Concatenate selected (or all) skills' instructions for prompt injection."""
53
+ skills = self.list()
54
+ if slugs:
55
+ wanted = set(slugs)
56
+ skills = [s for s in skills if s.slug in wanted]
57
+ if not skills:
58
+ return ""
59
+ return "\n".join(f"- {s.name}: {s.instructions}" for s in skills)
60
+
61
+
62
+ def get_skill_registry(directory: str | Path = "data/skills") -> SkillRegistry:
63
+ return SkillRegistry(directory)
agentx/structured.py ADDED
@@ -0,0 +1,37 @@
1
+ """Structured outputs — typed, validated model responses.
2
+
3
+ Thin, provider-agnostic wrappers over LangChain's ``with_structured_output``
4
+ (supported across OpenAI, Anthropic, Gemini, Bedrock, Groq, Ollama, …). Pass a
5
+ Pydantic model or a JSON schema; get back validated objects instead of strings.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from typing import Any
10
+
11
+ from .providers import get_chat_model
12
+
13
+
14
+ def structured_model(schema: Any, provider: str | None = None, model: str | None = None, **kwargs):
15
+ """Return a chat model that emits instances of ``schema`` (a Pydantic model).
16
+
17
+ Example::
18
+
19
+ from pydantic import BaseModel
20
+ class Person(BaseModel):
21
+ name: str
22
+ age: int
23
+ llm = structured_model(Person, "openai", "gpt-4o-mini")
24
+ person = llm.invoke("Alice is 30") # -> Person(name='Alice', age=30)
25
+ """
26
+ llm = get_chat_model(provider, model, **kwargs)
27
+ return as_structured(llm, schema)
28
+
29
+
30
+ def as_structured(llm: Any, schema: Any):
31
+ """Attach structured-output decoding to an existing chat model."""
32
+ if not hasattr(llm, "with_structured_output"):
33
+ raise TypeError(
34
+ f"{type(llm).__name__} does not support structured output; "
35
+ "use a provider/model that implements with_structured_output()."
36
+ )
37
+ return llm.with_structured_output(schema)
@@ -0,0 +1,5 @@
1
+ """Tools: MCP tool loading + a few built-in tools."""
2
+ from .mcp import load_mcp_tools
3
+ from .builtin import make_web_search_tool
4
+
5
+ __all__ = ["load_mcp_tools", "make_web_search_tool"]
@@ -0,0 +1,45 @@
1
+ """Built-in tools usable by agents. Currently: a keyless web search.
2
+
3
+ Uses the ``ddgs`` (DuckDuckGo) package if available; otherwise the tool returns
4
+ a friendly message instead of failing.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import logging
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ def web_search(query: str, max_results: int = 5) -> str:
14
+ """Run a DuckDuckGo text search and return a formatted string."""
15
+ try:
16
+ from ddgs import DDGS
17
+ except ImportError:
18
+ try:
19
+ from duckduckgo_search import DDGS # older package name
20
+ except ImportError:
21
+ return "Web search unavailable (install `ddgs`)."
22
+ try:
23
+ lines = []
24
+ with DDGS() as ddgs:
25
+ for r in ddgs.text(query, max_results=max_results):
26
+ title = r.get("title", "")
27
+ body = r.get("body", "")
28
+ url = r.get("href", r.get("url", ""))
29
+ lines.append(f"- {title}\n {body}\n {url}")
30
+ return "\n".join(lines) if lines else f"No results for '{query}'."
31
+ except Exception as exc: # noqa: BLE001
32
+ logger.warning("web_search failed: %s", exc)
33
+ return f"Web search error: {exc!r}"
34
+
35
+
36
+ def make_web_search_tool():
37
+ """Return ``web_search`` wrapped as a LangChain ``@tool`` (lazy import)."""
38
+ from langchain_core.tools import tool
39
+
40
+ @tool
41
+ def web_search_tool(query: str) -> str:
42
+ """Search the public web for up-to-date information. Input a concise query."""
43
+ return web_search(query)
44
+
45
+ return web_search_tool
agentx/tools/mcp.py ADDED
@@ -0,0 +1,64 @@
1
+ """Load MCP servers as LangChain tools via ``langchain-mcp-adapters``.
2
+
3
+ Config format (JSON or dict) follows MultiServerMCPClient, e.g.::
4
+
5
+ {
6
+ "filesystem": {
7
+ "command": "npx",
8
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"],
9
+ "transport": "stdio"
10
+ }
11
+ }
12
+
13
+ Returns ``[]`` (never raises) if the extra isn't installed or loading fails, so
14
+ agents degrade gracefully.
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import asyncio
19
+ import json
20
+ import logging
21
+ from pathlib import Path
22
+ from typing import Any
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+
27
+ def _load_config(config: str | Path | dict | None) -> dict:
28
+ if config is None:
29
+ return {}
30
+ if isinstance(config, dict):
31
+ return config
32
+ p = Path(config)
33
+ if p.exists():
34
+ return json.loads(p.read_text(encoding="utf-8"))
35
+ return {}
36
+
37
+
38
+ def load_mcp_tools(config: str | Path | dict | None) -> list[Any]:
39
+ """Synchronously load MCP tools from a config path/dict. Returns [] on failure."""
40
+ servers = _load_config(config)
41
+ if not servers:
42
+ return []
43
+ try:
44
+ from langchain_mcp_adapters.client import MultiServerMCPClient
45
+ except ImportError:
46
+ logger.warning("langchain-mcp-adapters not installed; run `uv pip install 'agentx-kit[mcp]'`.")
47
+ return []
48
+
49
+ async def _gather() -> list[Any]:
50
+ client = MultiServerMCPClient(servers)
51
+ return await client.get_tools()
52
+
53
+ try:
54
+ return asyncio.run(_gather())
55
+ except RuntimeError:
56
+ # Already inside an event loop (e.g. notebook) — run in a fresh loop.
57
+ loop = asyncio.new_event_loop()
58
+ try:
59
+ return loop.run_until_complete(_gather())
60
+ finally:
61
+ loop.close()
62
+ except Exception as exc: # noqa: BLE001
63
+ logger.warning("Failed to load MCP tools: %s", exc)
64
+ return []
@@ -0,0 +1,289 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentx-kit
3
+ Version: 0.2.0
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
+ Project-URL: Homepage, https://github.com/muhammadyahiya/agentx-kit
6
+ Project-URL: Repository, https://github.com/muhammadyahiya/agentx-kit
7
+ Project-URL: Issues, https://github.com/muhammadyahiya/agentx-kit/issues
8
+ Author: AgentX
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: agents,azure,bedrock,crewai,gemini,langchain,llm,mcp,openrouter,rag,scaffold,vertex
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Software Development :: Code Generators
23
+ Requires-Python: <3.14,>=3.10
24
+ Requires-Dist: jinja2>=3.1.0
25
+ Requires-Dist: langchain-core>=0.3.0
26
+ Requires-Dist: pydantic-settings>=2.2.0
27
+ Requires-Dist: pydantic>=2.7.0
28
+ Requires-Dist: python-dotenv>=1.0.0
29
+ Requires-Dist: questionary>=2.0.0
30
+ Requires-Dist: rich>=13.7.0
31
+ Requires-Dist: typer>=0.12.0
32
+ Provides-Extra: all
33
+ Requires-Dist: chromadb>=0.5.0; extra == 'all'
34
+ Requires-Dist: fastapi>=0.110.0; extra == 'all'
35
+ Requires-Dist: langchain-anthropic>=0.2.0; extra == 'all'
36
+ Requires-Dist: langchain-aws>=0.2.0; extra == 'all'
37
+ Requires-Dist: langchain-community>=0.3.0; extra == 'all'
38
+ Requires-Dist: langchain-google-genai>=2.0.0; extra == 'all'
39
+ Requires-Dist: langchain-google-vertexai>=2.0.0; extra == 'all'
40
+ Requires-Dist: langchain-groq>=0.2.0; extra == 'all'
41
+ Requires-Dist: langchain-mcp-adapters>=0.1.0; extra == 'all'
42
+ Requires-Dist: langchain-ollama>=0.2.0; extra == 'all'
43
+ Requires-Dist: langchain-openai>=0.2.0; extra == 'all'
44
+ Requires-Dist: langchain-text-splitters>=0.3.0; extra == 'all'
45
+ Requires-Dist: langchain>=0.3.0; extra == 'all'
46
+ Requires-Dist: langgraph>=0.2.0; extra == 'all'
47
+ Requires-Dist: mcp>=1.2.0; extra == 'all'
48
+ Requires-Dist: openinference-instrumentation-langchain>=0.1.0; extra == 'all'
49
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0; extra == 'all'
50
+ Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'all'
51
+ Requires-Dist: sse-starlette>=2.0.0; extra == 'all'
52
+ Requires-Dist: uvicorn[standard]>=0.29.0; extra == 'all'
53
+ Provides-Extra: anthropic
54
+ Requires-Dist: langchain-anthropic>=0.2.0; extra == 'anthropic'
55
+ Provides-Extra: azure
56
+ Requires-Dist: langchain-openai>=0.2.0; extra == 'azure'
57
+ Provides-Extra: bedrock
58
+ Requires-Dist: langchain-aws>=0.2.0; extra == 'bedrock'
59
+ Provides-Extra: crewai
60
+ Requires-Dist: crewai>=0.70.0; extra == 'crewai'
61
+ Provides-Extra: dev
62
+ Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
63
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
64
+ Provides-Extra: google
65
+ Requires-Dist: langchain-google-genai>=2.0.0; extra == 'google'
66
+ Provides-Extra: groq
67
+ Requires-Dist: langchain-groq>=0.2.0; extra == 'groq'
68
+ Provides-Extra: langgraph
69
+ Requires-Dist: langchain>=0.3.0; extra == 'langgraph'
70
+ Requires-Dist: langgraph>=0.2.0; extra == 'langgraph'
71
+ Provides-Extra: mcp
72
+ Requires-Dist: langchain-mcp-adapters>=0.1.0; extra == 'mcp'
73
+ Requires-Dist: mcp>=1.2.0; extra == 'mcp'
74
+ Provides-Extra: observability
75
+ Requires-Dist: openinference-instrumentation-langchain>=0.1.0; extra == 'observability'
76
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0; extra == 'observability'
77
+ Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'observability'
78
+ Provides-Extra: ollama
79
+ Requires-Dist: langchain-ollama>=0.2.0; extra == 'ollama'
80
+ Provides-Extra: openai
81
+ Requires-Dist: langchain-openai>=0.2.0; extra == 'openai'
82
+ Provides-Extra: openrouter
83
+ Requires-Dist: langchain-openai>=0.2.0; extra == 'openrouter'
84
+ Provides-Extra: rag
85
+ Requires-Dist: chromadb>=0.5.0; extra == 'rag'
86
+ Requires-Dist: langchain-community>=0.3.0; extra == 'rag'
87
+ Requires-Dist: langchain-text-splitters>=0.3.0; extra == 'rag'
88
+ Provides-Extra: server
89
+ Requires-Dist: fastapi>=0.110.0; extra == 'server'
90
+ Requires-Dist: sse-starlette>=2.0.0; extra == 'server'
91
+ Requires-Dist: uvicorn[standard]>=0.29.0; extra == 'server'
92
+ Provides-Extra: vertex
93
+ Requires-Dist: langchain-google-vertexai>=2.0.0; extra == 'vertex'
94
+ Description-Content-Type: text/markdown
95
+
96
+ # 🧬 AgentX-Kit
97
+
98
+ [![PyPI](https://img.shields.io/pypi/v/agentx-kit.svg)](https://pypi.org/project/agentx-kit/)
99
+ [![Python](https://img.shields.io/pypi/pyversions/agentx-kit.svg)](https://pypi.org/project/agentx-kit/)
100
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
101
+
102
+ **A provider-agnostic agentic framework + interactive project scaffolder for LangChain & CrewAI.**
103
+
104
+ Pick your LLM provider (OpenAI, Azure, OpenRouter, Anthropic, Gemini, Vertex AI,
105
+ Bedrock, Groq, Ollama), choose your framework, agents, RAG, memory, MCP tools and
106
+ skills — and AgentX-Kit generates a **ready-to-run project in its own `uv`
107
+ virtual environment**.
108
+
109
+ ```bash
110
+ pip install "agentx-kit[all]"
111
+ agentx new # interactive wizard → scaffolds a uv project
112
+ ```
113
+
114
+ > The PyPI distribution is **`agentx-kit`**; the import name and CLI are **`agentx`**
115
+ > (`pip install agentx-kit` → `import agentx` / `agentx --help`).
116
+
117
+ ## 📦 Installation
118
+
119
+ ### From PyPI (recommended)
120
+ ```bash
121
+ pip install agentx-kit # core: CLI + scaffolder + base abstractions
122
+ pip install "agentx-kit[all]" # everything
123
+ ```
124
+ Each LLM provider is an **optional extra** so you only pull the SDKs you use:
125
+ ```bash
126
+ pip install "agentx-kit[openai,langgraph]" # OpenAI + LangGraph
127
+ pip install "agentx-kit[bedrock,crewai,rag,mcp]" # Bedrock + CrewAI + RAG + MCP
128
+ ```
129
+
130
+ ### Using `uv`
131
+ ```bash
132
+ uv pip install "agentx-kit[all]"
133
+ ```
134
+
135
+ ### From GitHub (latest, unreleased)
136
+ ```bash
137
+ pip install "agentx-kit[all] @ git+https://github.com/muhammadyahiya/agentx-kit.git"
138
+ ```
139
+
140
+ ### From a local clone (development)
141
+ ```bash
142
+ git clone https://github.com/muhammadyahiya/agentx-kit.git
143
+ cd agentx-kit
144
+ uv venv && uv pip install -e ".[all,dev]" # or: pip install -e ".[all,dev]"
145
+ pytest -q
146
+ ```
147
+
148
+ > Requires **Python 3.10–3.13** and (for the scaffolder's `.venv` creation)
149
+ > [`uv`](https://docs.astral.sh/uv/).
150
+
151
+ ### Verify
152
+ ```bash
153
+ agentx version
154
+ agentx providers # lists every provider + the env vars it needs
155
+ ```
156
+
157
+ ## Why
158
+ - **One factory, every provider.** `get_chat_model("bedrock", ...)` or
159
+ `get_chat_model("openrouter", ...)` — same call, lazy imports, install only
160
+ the extras you use.
161
+ - **Two frameworks.** LangChain/LangGraph *and* CrewAI from the same building blocks.
162
+ - **Batteries included.** RAG, short/long-term memory, MCP tools, and a skills
163
+ registry — each optional and gracefully degrading.
164
+ - **Scaffolder, not a black box.** The generated project is readable, idiomatic
165
+ code you own, pre-wired to your selections, in a fresh `.venv`.
166
+
167
+ ## Use as a library
168
+ ```python
169
+ from agentx import get_chat_model, list_providers
170
+
171
+ llm = get_chat_model("openai", "gpt-4o-mini")
172
+ print(llm.invoke("Say hi in 3 words").content)
173
+
174
+ for spec in list_providers():
175
+ print(spec.id, "→", spec.label)
176
+ ```
177
+
178
+ CrewAI:
179
+ ```python
180
+ from agentx import get_crewai_llm
181
+ llm = get_crewai_llm("openrouter", "anthropic/claude-3.5-sonnet")
182
+ ```
183
+
184
+ ## Scaffold a project
185
+ ```bash
186
+ agentx new # fully interactive
187
+ agentx new --name my-bot --yes # accept sensible defaults
188
+ agentx providers # list providers + required env vars
189
+ ```
190
+
191
+ The wizard asks, one option at a time:
192
+
193
+ 1. Project name & target directory
194
+ 2. Framework — **LangGraph** or **CrewAI**
195
+ 3. LLM **provider** and **model**
196
+ 4. Number of **agents** (and their roles)
197
+ 5. **RAG** module? (vector store)
198
+ 6. **Memory**? (short-term / long-term / both)
199
+ 7. **MCP tools**?
200
+ 8. **Skills** integration?
201
+ 9. **Prompt** style (defaults or scaffolded custom prompts)
202
+ 10. Create `.venv` and `uv sync` now?
203
+
204
+ It then renders the project, writes a feature-aware `pyproject.toml` + `.env.example`,
205
+ and runs `uv venv` to create `.venv`.
206
+
207
+ ## Prompts: add at creation, or any time after
208
+ Prompts are **not baked into code** — every generated project keeps them in a
209
+ `prompts.json` that `agents.py` loads dynamically. Add an entry and the project
210
+ runs it on next start, **no code changes**.
211
+
212
+ ```bash
213
+ # at creation
214
+ agentx new --yes -n chatops --prompt "You are a senior DevOps engineer. Be terse."
215
+
216
+ # after creation (run inside the project)
217
+ agentx prompt list
218
+ agentx prompt set assistant --text "You are an SRE. Prioritise reliability."
219
+ agentx prompt add reviewer --role "Code Reviewer" --goal "Review diffs" \
220
+ --text "You review code for bugs and security."
221
+ agentx prompt remove reviewer
222
+ ```
223
+
224
+ `prompts.json`:
225
+ ```json
226
+ {
227
+ "with_rag": false,
228
+ "agents": {
229
+ "assistant": {"role": "...", "goal": "...", "system_prompt": "You are ..."}
230
+ }
231
+ }
232
+ ```
233
+ A blank `system_prompt` is auto-derived from the agent's role + goal. You can also
234
+ just open `prompts.json` in an editor — the CLI is a convenience, not a gate.
235
+
236
+ ## 🏢 Enterprise pack
237
+ Generate a production-shaped project with one flag — informed by a survey of
238
+ CrewAI/LangGraph/create-llama/AgentStack/agno/pydantic-ai (see [RESEARCH.md](RESEARCH.md)):
239
+
240
+ ```bash
241
+ agentx new --yes -n my-bot --enterprise # everything below
242
+ # or pick individually:
243
+ agentx new --yes -n my-bot --observability --guardrails --serve --docker --ci --evals
244
+ ```
245
+
246
+ What `--enterprise` adds to the generated project:
247
+ - **Observability** — OpenTelemetry GenAI tracing + optional Langfuse (`observability.py`), opt-out via `AGENTX_TELEMETRY=false`.
248
+ - **Guardrails** — input/output validation + PII redaction (`guardrails.py`).
249
+ - **FastAPI server** — `server.py` with `/health`, `/chat`, and SSE `/chat/stream`.
250
+ - **Docker** — `Dockerfile` + `docker-compose.yml` (+ `.dockerignore`).
251
+ - **CI** — `.github/workflows/ci.yml` (lint + compile + tests, optional eval gate).
252
+ - **Evals** — `evals/` LLM-as-judge harness runnable locally and in CI.
253
+ - **Typed config** — `config.py` via `pydantic-settings` (12-factor).
254
+ - **Manifest** — `agentx.json` declaring framework, provider, features (à la `langgraph.json`).
255
+
256
+ These are also usable as a **library** in any project:
257
+ ```python
258
+ from agentx import (
259
+ setup_tracing, get_callbacks, # observability
260
+ build_resilient_chat, # retries + provider fallbacks
261
+ UsageLimits, UsageTracker, # token/cost budgets
262
+ apply_guards, structured_model, # guardrails + typed outputs
263
+ )
264
+ setup_tracing("my-service")
265
+ llm = build_resilient_chat("openai", "gpt-4o-mini", fallbacks=[("anthropic", "claude-3-5-sonnet-latest")])
266
+ ```
267
+
268
+ ## Installation extras
269
+ | Extra | Installs | For |
270
+ |---|---|---|
271
+ | `openai` / `azure` / `openrouter` | `langchain-openai` | OpenAI-compatible |
272
+ | `anthropic` | `langchain-anthropic` | Claude |
273
+ | `google` | `langchain-google-genai` | Gemini (AI Studio) |
274
+ | `vertex` | `langchain-google-vertexai` | Vertex AI |
275
+ | `bedrock` | `langchain-aws` | Amazon Bedrock |
276
+ | `groq` | `langchain-groq` | Groq |
277
+ | `ollama` | `langchain-ollama` | local |
278
+ | `langgraph` | `langgraph`, `langchain` | LangGraph agents |
279
+ | `crewai` | `crewai` | CrewAI crews |
280
+ | `rag` | `langchain-community`, `chromadb` | RAG |
281
+ | `mcp` | `langchain-mcp-adapters` | MCP tools |
282
+ | `observability` | `opentelemetry-*`, `openinference-*` | tracing |
283
+ | `server` | `fastapi`, `uvicorn` | serving |
284
+ | `all` | everything above | kitchen sink |
285
+
286
+ See [DESIGN.md](DESIGN.md) for the architecture and [RESEARCH.md](RESEARCH.md) for the competitive analysis behind these features.
287
+
288
+ ## License
289
+ MIT
@@ -0,0 +1,58 @@
1
+ agentx/__init__.py,sha256=HUgko0a8eqk4KRC4PQtEK_8BplbYCzhHbFMUa_8Nfx0,1422
2
+ agentx/cli.py,sha256=uBogXBaFM11rEwDHO1vvJ0TEDrKQzOoalZ4XhTuvvLg,9869
3
+ agentx/config.py,sha256=7kyJfr2NrKxiBtaxxKjJO0UNsw1C-prg_3Syg9TO5uU,1312
4
+ agentx/guardrails.py,sha256=wYYW-tReK9hW69ulgxJtKjHGqL2tFRhgTNX-nLCAk_U,3015
5
+ agentx/observability.py,sha256=8dt-WUj_pXMydO3_uYztCOQxMnCE1KVEPWekUOdMB5Y,3931
6
+ agentx/reliability.py,sha256=xXLXe2-Br4SmtQ_Id8UoUojDsSDKFrggzTexig6VSqo,4476
7
+ agentx/structured.py,sha256=82ny87Qf8yw2yYBCQ-iQBBj_Kp54xkPyaybsKvEocVg,1354
8
+ agentx/frameworks/__init__.py,sha256=jBfT-uZYs1vA9fAJmwz6GYL6589XAivcHu-YopEtKAI,282
9
+ agentx/frameworks/crewai_agent.py,sha256=H7UQcumr_zAsRdj29frSv2kQSMtkEvoS_Yc2J_ddqkg,1548
10
+ agentx/frameworks/langchain_agent.py,sha256=8E5zNMoHg_uEd_PxvdWOmHi6eaXs9bdxzRCh-Oz-b4M,1514
11
+ agentx/memory/__init__.py,sha256=LbwInW9GLpArre9Y-Zs5puFy_-AwUGwAt4iECYhKRHQ,180
12
+ agentx/memory/store.py,sha256=oQh7B4N723MReibLEhH-dC1FqRUMjBu6EHxgK3HWB-k,2393
13
+ agentx/prompts/__init__.py,sha256=BSqUfXT_u97SKUutNMZ_ND5S8O1cMjIyTRr30POj9Xg,238
14
+ agentx/prompts/templates.py,sha256=LsIBnPsflq1UKRC705tEr9f2gNtOoj3kTqhlLWgRLfw,1312
15
+ agentx/providers/__init__.py,sha256=VFXv5s8qnXpfkJEAFbesxc13h_4I0jnXdxDeTfESUYg,420
16
+ agentx/providers/base.py,sha256=d0GI9LmWA4mICqhoa7e74V6tneCG-o70N73clhW2J9A,1822
17
+ agentx/providers/factory.py,sha256=q9LceEBZfBG5PScA62gzuHXhZUBYmE_z4IQPJew4Ux8,2647
18
+ agentx/providers/registry.py,sha256=tTM48a5zQDOH7CQArQOZh_95kNMNsNENeKIQCVTrpGI,7102
19
+ agentx/rag/__init__.py,sha256=0p-fzaR17q8U4iSaQqh8Ai70gL0qo46EpqO8y5Bp64k,369
20
+ agentx/rag/pipeline.py,sha256=a4sckVrynp52PP1woUBnlWXzd51o83y_ICnSSTa_Auo,4210
21
+ agentx/scaffold/__init__.py,sha256=DJu5mUBfzrp-ySYkck80ck-k2PD3d36t44GnWxQIraU,374
22
+ agentx/scaffold/generator.py,sha256=7NooN2EGUDB59K1XYgtS7VcjHg9vu1ZKr2X5GJeyrbE,7155
23
+ agentx/scaffold/prompts_store.py,sha256=oZHzZCDfm69EY2HcvcD6I59MG1sX6LbCu6ylbgiAhM4,3084
24
+ agentx/scaffold/spec.py,sha256=p-Fx0T-ACF6ELgRjIr-LVLDxyKNn9ZnhCMS4FisbZdg,3002
25
+ agentx/scaffold/wizard.py,sha256=zse6hiPmqTfCFGeQxKojr-2LNT-PTPzAf-8mP-wSIMA,5050
26
+ agentx/scaffold/templates/Dockerfile.j2,sha256=cISw2diE6jjLxeRkEEr569l_zcXFQel8NqAer91mPnM,399
27
+ agentx/scaffold/templates/README.md.j2,sha256=b7WbA8spalUuYNgpHHYls9E3iMzzflKx-7pGVZolpuw,1343
28
+ agentx/scaffold/templates/ci.yml.j2,sha256=O6Ahul7PlIClRah-emM3XbMYiXvCInsPsrNRqvWbw1k,974
29
+ agentx/scaffold/templates/docker-compose.yml.j2,sha256=PAyffd9Du9q_l4x2KeQGb0A6PZNr1FKKOVmO_hJpZ6c,152
30
+ agentx/scaffold/templates/dockerignore.j2,sha256=3J8-k75GHEb3nVMKCu1b9l07H66qYz5a5jYQkRKdHLI,90
31
+ agentx/scaffold/templates/env.example.j2,sha256=VEaveuQk0h97UAmJ2gEJMfFecVxMMc6W3xYe1ycqdxM,323
32
+ agentx/scaffold/templates/gitignore.j2,sha256=BZlrEbYc3EauoEeHLtvlekhwIi16rmrfpVuW9CiOqM8,77
33
+ agentx/scaffold/templates/mcp_servers.json.j2,sha256=klkgZz4OVORg-1SRn5XRKczC3if7Q883eoVzwqBnPq8,141
34
+ agentx/scaffold/templates/pyproject.toml.j2,sha256=TZ-otXEt-CgpI-TRM3B5WknllF9TWkQJmrwIx8HY36s,691
35
+ agentx/scaffold/templates/skills_seed.json.j2,sha256=NpnBET11WJkUogWsZ_DCGZRj4QNy3wYhm5cB9H5c9t0,327
36
+ agentx/scaffold/templates/evals/dataset.json.j2,sha256=f--9wf8_YYvUZ-E-lYYucmOcLbf8httdlc_WkmdnhTs,327
37
+ agentx/scaffold/templates/evals/run_evals.py.j2,sha256=kGLZEM854Wc5Ao656a-TP16AUu_XRseinZ812I677to,2119
38
+ agentx/scaffold/templates/pkg/__init__.py.j2,sha256=iu0vi0VYs7TX64XBiUR4MR1MOBRiQYbjgiYlJuZbDjg,70
39
+ agentx/scaffold/templates/pkg/agents.py.j2,sha256=i3CHAyK5eFXYylRixz8_GGUx5XiOXMmWjq1IIqKf-vc,2499
40
+ agentx/scaffold/templates/pkg/config.py.j2,sha256=sSQdwIbCZjhKvMJFo2SjvHN7iDRWYcQ9qLnVQ0ReQbc,676
41
+ agentx/scaffold/templates/pkg/guardrails.py.j2,sha256=Op4a40FaaKP-OKyQkX5RGDqr1BoBjNvR2DgC4lLMPU4,825
42
+ agentx/scaffold/templates/pkg/main.py.j2,sha256=GV4OtcaJIqGR50iAKJsNiJoUm2eeCbaRvZWfDeB1T1U,2138
43
+ agentx/scaffold/templates/pkg/memory.py.j2,sha256=t7D1csRxdFSABaJthgO8XdQ4YiZANaRLY1HzISUkKYI,568
44
+ agentx/scaffold/templates/pkg/observability.py.j2,sha256=NlTJiz6mQ9L5qhuivEOjzunGXVSF0EHcBqzs2xlFfYM,584
45
+ agentx/scaffold/templates/pkg/prompts.py.j2,sha256=5xy3YmItC_5-8ewftvbImGR4jvJthV0okGxO7JJd7XA,1475
46
+ agentx/scaffold/templates/pkg/rag.py.j2,sha256=NNZJjHzKSOHKH8VeITReDZ0nZziSx5dyB8wtdwhic3U,1092
47
+ agentx/scaffold/templates/pkg/server.py.j2,sha256=CTNu6W2aFOvSA7kGgHTptYfS5X-UUiQdorZp9VfYXBM,2124
48
+ agentx/scaffold/templates/pkg/tools.py.j2,sha256=X4Si0KFMjaJLNW3f-jnsU_SAdy6EMKXqnWIE5zIXS3c,406
49
+ agentx/skills/__init__.py,sha256=bx8wVOU3CYbQfnsOLwIsTJQcXa3K60HaY8ttJTyu3Q4,204
50
+ agentx/skills/registry.py,sha256=ymP4L86fKcCuqfn0kSoC699wu8fJrVfWVPdtInkKREg,2099
51
+ agentx/tools/__init__.py,sha256=J7li3RR5Dh6_nILMSZ8oY3i31UpJgiFWDSAydpjTbdI,182
52
+ agentx/tools/builtin.py,sha256=th_S8ebJpKz4MH7uot0llWSerRoTG2ZaT-57it4jjPo,1539
53
+ agentx/tools/mcp.py,sha256=V63AVWX2rxt1V7rwhTWZ2Ell3zlrZFD07fWVG-wI4H4,1863
54
+ agentx_kit-0.2.0.dist-info/METADATA,sha256=pEtXZpn8Wqy0zkb4LeDLo6nnxu3yqovQlfYkhEwxBSM,11789
55
+ agentx_kit-0.2.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
56
+ agentx_kit-0.2.0.dist-info/entry_points.txt,sha256=7vwVzYRgV1cUZLVkt2ULUymznbCarWPw29nUXKdfKG8,42
57
+ agentx_kit-0.2.0.dist-info/licenses/LICENSE,sha256=wWCp0PehBii6IUiqhSmPsyhT6GidoH7zj6uBkfEu1v0,1063
58
+ agentx_kit-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ agentx = agentx.cli:app
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AgentX
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.