agentx-kit 0.3.0__tar.gz → 0.5.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.
- agentx_kit-0.5.0/.agentx/llm_cache.sqlite +0 -0
- agentx_kit-0.5.0/.claude-plugin/marketplace.json +15 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/PKG-INFO +70 -1
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/README.md +67 -0
- agentx_kit-0.5.0/integrations/claude-plugin/.claude-plugin/plugin.json +9 -0
- agentx_kit-0.5.0/integrations/claude-plugin/.mcp.json +8 -0
- agentx_kit-0.5.0/integrations/claude-plugin/README.md +29 -0
- agentx_kit-0.5.0/integrations/claude-plugin/commands/new-agent.md +14 -0
- agentx_kit-0.5.0/integrations/vscode/.vscodeignore +4 -0
- agentx_kit-0.5.0/integrations/vscode/README.md +34 -0
- agentx_kit-0.5.0/integrations/vscode/extension.js +87 -0
- agentx_kit-0.5.0/integrations/vscode/package.json +34 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/pyproject.toml +3 -1
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/__init__.py +7 -1
- agentx_kit-0.5.0/src/agentx/cache.py +166 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/cli.py +62 -0
- agentx_kit-0.5.0/src/agentx/connector/__init__.py +18 -0
- agentx_kit-0.5.0/src/agentx/connector/build.py +112 -0
- agentx_kit-0.5.0/src/agentx/connector/recommend.py +120 -0
- agentx_kit-0.5.0/src/agentx/connector/server.py +108 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/dashboard/app.py +15 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/generator.py +1 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/spec.py +2 -1
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/main.py.j2 +8 -0
- agentx_kit-0.5.0/tests/test_cache.py +60 -0
- agentx_kit-0.5.0/tests/test_connector.py +70 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/.github/workflows/publish.yml +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/.gitignore +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/DESIGN.md +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/LICENSE +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/RESEARCH.md +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/config.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/dashboard/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/frameworks/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/frameworks/crewai_agent.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/frameworks/langchain_agent.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/guardrails.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/insights/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/insights/analyze.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/insights/log.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/insights/optimize.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/insights/tokens.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/memory/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/memory/store.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/observability.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/prompts/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/prompts/templates.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/providers/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/providers/base.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/providers/factory.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/providers/registry.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/rag/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/rag/pipeline.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/reliability.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/prompts_store.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/Dockerfile.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/README.md.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/ci.yml.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/docker-compose.yml.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/dockerignore.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/env.example.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/evals/dataset.json.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/evals/run_evals.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/gitignore.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/mcp_servers.json.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/__init__.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/agents.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/config.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/guardrails.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/memory.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/observability.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/prompts.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/rag.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/server.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pkg/tools.py.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/pyproject.toml.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/templates/skills_seed.json.j2 +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/scaffold/wizard.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/skills/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/skills/registry.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/structured.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/tools/__init__.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/tools/builtin.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/src/agentx/tools/mcp.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/tests/test_enterprise.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/tests/test_insights.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/tests/test_prompts.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/tests/test_providers.py +0 -0
- {agentx_kit-0.3.0 → agentx_kit-0.5.0}/tests/test_scaffold.py +0 -0
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentx-kit",
|
|
3
|
+
"owner": { "name": "AgentX", "url": "https://github.com/muhammadyahiya/agentx-kit" },
|
|
4
|
+
"metadata": {
|
|
5
|
+
"description": "AgentX-Kit — scaffold agent projects from a prompt, in Claude Code.",
|
|
6
|
+
"version": "0.1.0"
|
|
7
|
+
},
|
|
8
|
+
"plugins": [
|
|
9
|
+
{
|
|
10
|
+
"name": "agentx-kit",
|
|
11
|
+
"source": "./integrations/claude-plugin",
|
|
12
|
+
"description": "Scaffold complete LangChain/CrewAI agent projects from a single problem statement via AgentX-Kit's MCP tools."
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentx-kit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.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
|
|
@@ -59,6 +59,8 @@ Provides-Extra: azure
|
|
|
59
59
|
Requires-Dist: langchain-openai>=0.2.0; extra == 'azure'
|
|
60
60
|
Provides-Extra: bedrock
|
|
61
61
|
Requires-Dist: langchain-aws>=0.2.0; extra == 'bedrock'
|
|
62
|
+
Provides-Extra: connector
|
|
63
|
+
Requires-Dist: mcp>=1.2.0; extra == 'connector'
|
|
62
64
|
Provides-Extra: crewai
|
|
63
65
|
Requires-Dist: crewai>=0.70.0; extra == 'crewai'
|
|
64
66
|
Provides-Extra: dashboard
|
|
@@ -260,6 +262,72 @@ It gives you, live as you edit:
|
|
|
260
262
|
Run it inside a generated AgentX project and it reads/writes that project's
|
|
261
263
|
`prompts.json`; run it anywhere else for a free-form prompt scratchpad.
|
|
262
264
|
|
|
265
|
+
## 🔌 Use as a connector (Claude / Copilot / Codex)
|
|
266
|
+
AgentX-Kit ships an **MCP server**, so any MCP-capable assistant can scaffold a
|
|
267
|
+
complete project from **a single prompt with your problem statement**.
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
pip install "agentx-kit[connector]"
|
|
271
|
+
agentx mcp --print-config # prints the client config below
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Add it to your client (then restart it):
|
|
275
|
+
```jsonc
|
|
276
|
+
// Claude Desktop / Codex / Copilot — under "mcpServers"
|
|
277
|
+
{ "mcpServers": { "agentx-kit": { "command": "agentx", "args": ["mcp"] } } }
|
|
278
|
+
```
|
|
279
|
+
```bash
|
|
280
|
+
# Claude Code one-liner
|
|
281
|
+
claude mcp add agentx-kit -- agentx mcp
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Now just ask, in plain language:
|
|
285
|
+
> *“Build a customer-support agent that answers from our product docs and serves a REST API.”*
|
|
286
|
+
|
|
287
|
+
The assistant calls AgentX-Kit's tools and you get a complete, runnable project:
|
|
288
|
+
- **`recommend_project(problem_statement)`** — suggests framework, provider, agent count, and features.
|
|
289
|
+
- **`create_agent_project(problem_statement, …)`** — generates the project (infers RAG/serve/memory/etc. from the statement, or take explicit overrides / `enterprise=true`) and returns the file tree + key file contents + run steps.
|
|
290
|
+
- **`list_providers`**, **`analyze_prompt`**, **`optimize_prompt`** — provider list + prompt insights.
|
|
291
|
+
|
|
292
|
+
So from one sentence the assistant produces a pre-wired project (prompts already seeded from your use case), ready to `uv sync && uv run`.
|
|
293
|
+
|
|
294
|
+
## 🧩 Editor & assistant integrations
|
|
295
|
+
The same connector powers ready-made integrations (see [`integrations/`](integrations/)):
|
|
296
|
+
|
|
297
|
+
- **VS Code extension** ([`integrations/vscode`](integrations/vscode)) — commands for
|
|
298
|
+
*New Agent Project*, *Open Prompt Dashboard*, *Add Prompt*, *Cache Stats*, and
|
|
299
|
+
*Register MCP Server for Copilot* (writes `.vscode/mcp.json`). Build with `vsce package`.
|
|
300
|
+
- **GitHub Copilot** (agent mode) — add the MCP server via `.vscode/mcp.json`:
|
|
301
|
+
```jsonc
|
|
302
|
+
{ "servers": { "agentx-kit": { "command": "agentx", "args": ["mcp"] } } }
|
|
303
|
+
```
|
|
304
|
+
(the VS Code command above writes this for you), then ask Copilot to build an agent.
|
|
305
|
+
- **Claude Code plugin** ([`integrations/claude-plugin`](integrations/claude-plugin)):
|
|
306
|
+
```text
|
|
307
|
+
/plugin marketplace add muhammadyahiya/agentx-kit
|
|
308
|
+
/plugin install agentx-kit@agentx-kit
|
|
309
|
+
/agentx-kit:new-agent a support agent that answers from our docs and serves an API
|
|
310
|
+
```
|
|
311
|
+
- **Claude Desktop / Codex** — add the connector config from `agentx mcp --print-config`.
|
|
312
|
+
|
|
313
|
+
## 💾 Response caching (cost & latency saver)
|
|
314
|
+
Caching is the top 2026 token-optimization lever. Turn on a **global LLM response
|
|
315
|
+
cache** and every provider call is served from a local store on repeat — no code changes:
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
from agentx import enable_caching, cache_stats
|
|
319
|
+
enable_caching() # all get_chat_model(...) calls are cached
|
|
320
|
+
...
|
|
321
|
+
print(cache_stats()) # {'hit_rate': 0.6, 'tokens_saved': 12000, 'est_usd_saved': 0.024, ...}
|
|
322
|
+
```
|
|
323
|
+
```bash
|
|
324
|
+
agentx cache stats # hit rate + estimated tokens/$ saved
|
|
325
|
+
agentx cache clear
|
|
326
|
+
```
|
|
327
|
+
Generated projects can enable it automatically (it's part of `--enterprise`), and the
|
|
328
|
+
**dashboard's Trends tab shows live hit-rate and $ saved**. TTL-capable, SQLite-backed
|
|
329
|
+
at `.agentx/llm_cache.sqlite`.
|
|
330
|
+
|
|
263
331
|
## 🏢 Enterprise pack
|
|
264
332
|
Generate a production-shaped project with one flag — informed by a survey of
|
|
265
333
|
CrewAI/LangGraph/create-llama/AgentStack/agno/pydantic-ai (see [RESEARCH.md](RESEARCH.md)):
|
|
@@ -309,6 +377,7 @@ llm = build_resilient_chat("openai", "gpt-4o-mini", fallbacks=[("anthropic", "cl
|
|
|
309
377
|
| `observability` | `opentelemetry-*`, `openinference-*` | tracing |
|
|
310
378
|
| `server` | `fastapi`, `uvicorn` | serving |
|
|
311
379
|
| `dashboard` | `streamlit`, `tiktoken`, `pandas` | prompt observability dashboard |
|
|
380
|
+
| `connector` | `mcp` | MCP server for Claude/Copilot/Codex |
|
|
312
381
|
| `all` | everything above | kitchen sink |
|
|
313
382
|
|
|
314
383
|
See [DESIGN.md](DESIGN.md) for the architecture and [RESEARCH.md](RESEARCH.md) for the competitive analysis behind these features.
|
|
@@ -158,6 +158,72 @@ It gives you, live as you edit:
|
|
|
158
158
|
Run it inside a generated AgentX project and it reads/writes that project's
|
|
159
159
|
`prompts.json`; run it anywhere else for a free-form prompt scratchpad.
|
|
160
160
|
|
|
161
|
+
## 🔌 Use as a connector (Claude / Copilot / Codex)
|
|
162
|
+
AgentX-Kit ships an **MCP server**, so any MCP-capable assistant can scaffold a
|
|
163
|
+
complete project from **a single prompt with your problem statement**.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
pip install "agentx-kit[connector]"
|
|
167
|
+
agentx mcp --print-config # prints the client config below
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Add it to your client (then restart it):
|
|
171
|
+
```jsonc
|
|
172
|
+
// Claude Desktop / Codex / Copilot — under "mcpServers"
|
|
173
|
+
{ "mcpServers": { "agentx-kit": { "command": "agentx", "args": ["mcp"] } } }
|
|
174
|
+
```
|
|
175
|
+
```bash
|
|
176
|
+
# Claude Code one-liner
|
|
177
|
+
claude mcp add agentx-kit -- agentx mcp
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Now just ask, in plain language:
|
|
181
|
+
> *“Build a customer-support agent that answers from our product docs and serves a REST API.”*
|
|
182
|
+
|
|
183
|
+
The assistant calls AgentX-Kit's tools and you get a complete, runnable project:
|
|
184
|
+
- **`recommend_project(problem_statement)`** — suggests framework, provider, agent count, and features.
|
|
185
|
+
- **`create_agent_project(problem_statement, …)`** — generates the project (infers RAG/serve/memory/etc. from the statement, or take explicit overrides / `enterprise=true`) and returns the file tree + key file contents + run steps.
|
|
186
|
+
- **`list_providers`**, **`analyze_prompt`**, **`optimize_prompt`** — provider list + prompt insights.
|
|
187
|
+
|
|
188
|
+
So from one sentence the assistant produces a pre-wired project (prompts already seeded from your use case), ready to `uv sync && uv run`.
|
|
189
|
+
|
|
190
|
+
## 🧩 Editor & assistant integrations
|
|
191
|
+
The same connector powers ready-made integrations (see [`integrations/`](integrations/)):
|
|
192
|
+
|
|
193
|
+
- **VS Code extension** ([`integrations/vscode`](integrations/vscode)) — commands for
|
|
194
|
+
*New Agent Project*, *Open Prompt Dashboard*, *Add Prompt*, *Cache Stats*, and
|
|
195
|
+
*Register MCP Server for Copilot* (writes `.vscode/mcp.json`). Build with `vsce package`.
|
|
196
|
+
- **GitHub Copilot** (agent mode) — add the MCP server via `.vscode/mcp.json`:
|
|
197
|
+
```jsonc
|
|
198
|
+
{ "servers": { "agentx-kit": { "command": "agentx", "args": ["mcp"] } } }
|
|
199
|
+
```
|
|
200
|
+
(the VS Code command above writes this for you), then ask Copilot to build an agent.
|
|
201
|
+
- **Claude Code plugin** ([`integrations/claude-plugin`](integrations/claude-plugin)):
|
|
202
|
+
```text
|
|
203
|
+
/plugin marketplace add muhammadyahiya/agentx-kit
|
|
204
|
+
/plugin install agentx-kit@agentx-kit
|
|
205
|
+
/agentx-kit:new-agent a support agent that answers from our docs and serves an API
|
|
206
|
+
```
|
|
207
|
+
- **Claude Desktop / Codex** — add the connector config from `agentx mcp --print-config`.
|
|
208
|
+
|
|
209
|
+
## 💾 Response caching (cost & latency saver)
|
|
210
|
+
Caching is the top 2026 token-optimization lever. Turn on a **global LLM response
|
|
211
|
+
cache** and every provider call is served from a local store on repeat — no code changes:
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
from agentx import enable_caching, cache_stats
|
|
215
|
+
enable_caching() # all get_chat_model(...) calls are cached
|
|
216
|
+
...
|
|
217
|
+
print(cache_stats()) # {'hit_rate': 0.6, 'tokens_saved': 12000, 'est_usd_saved': 0.024, ...}
|
|
218
|
+
```
|
|
219
|
+
```bash
|
|
220
|
+
agentx cache stats # hit rate + estimated tokens/$ saved
|
|
221
|
+
agentx cache clear
|
|
222
|
+
```
|
|
223
|
+
Generated projects can enable it automatically (it's part of `--enterprise`), and the
|
|
224
|
+
**dashboard's Trends tab shows live hit-rate and $ saved**. TTL-capable, SQLite-backed
|
|
225
|
+
at `.agentx/llm_cache.sqlite`.
|
|
226
|
+
|
|
161
227
|
## 🏢 Enterprise pack
|
|
162
228
|
Generate a production-shaped project with one flag — informed by a survey of
|
|
163
229
|
CrewAI/LangGraph/create-llama/AgentStack/agno/pydantic-ai (see [RESEARCH.md](RESEARCH.md)):
|
|
@@ -207,6 +273,7 @@ llm = build_resilient_chat("openai", "gpt-4o-mini", fallbacks=[("anthropic", "cl
|
|
|
207
273
|
| `observability` | `opentelemetry-*`, `openinference-*` | tracing |
|
|
208
274
|
| `server` | `fastapi`, `uvicorn` | serving |
|
|
209
275
|
| `dashboard` | `streamlit`, `tiktoken`, `pandas` | prompt observability dashboard |
|
|
276
|
+
| `connector` | `mcp` | MCP server for Claude/Copilot/Codex |
|
|
210
277
|
| `all` | everything above | kitchen sink |
|
|
211
278
|
|
|
212
279
|
See [DESIGN.md](DESIGN.md) for the architecture and [RESEARCH.md](RESEARCH.md) for the competitive analysis behind these features.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentx-kit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Scaffold complete provider-agnostic LangChain/CrewAI agent projects from a single problem statement, via AgentX-Kit's MCP tools.",
|
|
5
|
+
"author": { "name": "AgentX" },
|
|
6
|
+
"homepage": "https://github.com/muhammadyahiya/agentx-kit",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": ["agents", "scaffold", "langchain", "crewai", "mcp"]
|
|
9
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# AgentX-Kit — Claude Code plugin
|
|
2
|
+
|
|
3
|
+
Bundles AgentX-Kit's MCP server + a `/agentx-kit:new-agent` slash command so you
|
|
4
|
+
can scaffold a complete agent project from a single problem statement inside
|
|
5
|
+
Claude Code.
|
|
6
|
+
|
|
7
|
+
## Prerequisite
|
|
8
|
+
```bash
|
|
9
|
+
pip install "agentx-kit[connector]" # provides `agentx mcp`
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Install (from this repo's marketplace)
|
|
13
|
+
```text
|
|
14
|
+
/plugin marketplace add muhammadyahiya/agentx-kit
|
|
15
|
+
/plugin install agentx-kit@agentx-kit
|
|
16
|
+
```
|
|
17
|
+
Then use it:
|
|
18
|
+
```text
|
|
19
|
+
/agentx-kit:new-agent a customer-support agent that answers from our docs and serves an API
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Or just add the MCP server (no plugin)
|
|
23
|
+
```bash
|
|
24
|
+
claude mcp add agentx-kit -- agentx mcp
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The plugin ships:
|
|
28
|
+
- `.mcp.json` — registers the `agentx-kit` MCP server (`agentx mcp`).
|
|
29
|
+
- `commands/new-agent.md` — the `/agentx-kit:new-agent` workflow.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Scaffold a complete AgentX-Kit agent project from a problem statement
|
|
3
|
+
argument-hint: <describe the agent / use case you want to build>
|
|
4
|
+
---
|
|
5
|
+
Build a complete, runnable agent project for this request using the AgentX-Kit MCP tools:
|
|
6
|
+
|
|
7
|
+
**$ARGUMENTS**
|
|
8
|
+
|
|
9
|
+
Steps:
|
|
10
|
+
1. Call `recommend_project` with the problem statement and briefly show the recommended stack (framework, provider, agents, features) + rationale.
|
|
11
|
+
2. Ask the user to confirm or adjust (provider/framework/enterprise), then call `create_agent_project` with the problem statement and any overrides.
|
|
12
|
+
3. Report the target directory, the generated file tree, and the exact run steps it returns. Offer to open key files (main.py, agents.py, prompts.json).
|
|
13
|
+
|
|
14
|
+
Keep it concise; the tools do the heavy lifting.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# AgentX-Kit — VS Code extension
|
|
2
|
+
|
|
3
|
+
Scaffold agent projects, open the prompt dashboard, and wire AgentX-Kit into
|
|
4
|
+
**GitHub Copilot** (agent mode) — without leaving VS Code.
|
|
5
|
+
|
|
6
|
+
## Prerequisite
|
|
7
|
+
```bash
|
|
8
|
+
pip install "agentx-kit[all]" # provides the `agentx` CLI the extension calls
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Commands (⇧⌘P)
|
|
12
|
+
- **AgentX: New Agent Project** — name + use case → `agentx new`
|
|
13
|
+
- **AgentX: Open Prompt Dashboard** — `agentx dashboard`
|
|
14
|
+
- **AgentX: Add Agent Prompt** — `agentx prompt set … -d`
|
|
15
|
+
- **AgentX: Show Response-Cache Stats** — `agentx cache stats`
|
|
16
|
+
- **AgentX: Register MCP Server for Copilot** — writes `.vscode/mcp.json` so Copilot
|
|
17
|
+
agent mode can call AgentX-Kit's tools (e.g. *"build a support agent over our docs"*).
|
|
18
|
+
|
|
19
|
+
Set a custom CLI path with the `agentx.command` setting.
|
|
20
|
+
|
|
21
|
+
## Build / install locally
|
|
22
|
+
```bash
|
|
23
|
+
npm install -g @vscode/vsce
|
|
24
|
+
cd integrations/vscode
|
|
25
|
+
vsce package # -> agentx-kit-0.1.0.vsix
|
|
26
|
+
code --install-extension agentx-kit-0.1.0.vsix
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Publish (needs a Marketplace publisher + PAT)
|
|
30
|
+
```bash
|
|
31
|
+
vsce login <publisher>
|
|
32
|
+
vsce publish
|
|
33
|
+
```
|
|
34
|
+
See https://code.visualstudio.com/api/working-with-extensions/publishing-extension.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// AgentX-Kit VS Code extension.
|
|
2
|
+
// Thin wrapper over the `agentx` CLI + MCP registration for Copilot/agent mode.
|
|
3
|
+
// Pure JS (no build step). Requires `pip install agentx-kit` on PATH.
|
|
4
|
+
const vscode = require("vscode");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
|
|
8
|
+
function cli() {
|
|
9
|
+
return vscode.workspace.getConfiguration("agentx").get("command", "agentx");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function runInTerminal(name, commandLine) {
|
|
13
|
+
const term = vscode.window.createTerminal({ name });
|
|
14
|
+
term.show();
|
|
15
|
+
term.sendText(commandLine);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function workspaceRoot() {
|
|
19
|
+
const folders = vscode.workspace.workspaceFolders;
|
|
20
|
+
return folders && folders.length ? folders[0].uri.fsPath : process.cwd();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function newProject() {
|
|
24
|
+
const name = await vscode.window.showInputBox({
|
|
25
|
+
prompt: "Project name", value: "my-agent",
|
|
26
|
+
});
|
|
27
|
+
if (!name) return;
|
|
28
|
+
const problem = await vscode.window.showInputBox({
|
|
29
|
+
prompt: "Describe the use case (optional — seeds the agent's prompt)", value: "",
|
|
30
|
+
});
|
|
31
|
+
const enterprise = await vscode.window.showQuickPick(["No", "Yes (tracing, guardrails, FastAPI, Docker, CI, evals, cache)"], {
|
|
32
|
+
placeHolder: "Enterprise pack?",
|
|
33
|
+
});
|
|
34
|
+
let cmd = `${cli()} new --yes --name ${JSON.stringify(name)}`;
|
|
35
|
+
if (problem) cmd += ` --prompt ${JSON.stringify(problem)}`;
|
|
36
|
+
if (enterprise && enterprise.startsWith("Yes")) cmd += " --enterprise";
|
|
37
|
+
runInTerminal("AgentX: new", cmd);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function dashboard() {
|
|
41
|
+
runInTerminal("AgentX: dashboard", `${cli()} dashboard`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function addPrompt() {
|
|
45
|
+
const agent = await vscode.window.showInputBox({ prompt: "Agent name", value: "assistant" });
|
|
46
|
+
if (!agent) return;
|
|
47
|
+
const text = await vscode.window.showInputBox({ prompt: "System prompt" });
|
|
48
|
+
if (text === undefined) return;
|
|
49
|
+
runInTerminal("AgentX: prompt", `${cli()} prompt set ${JSON.stringify(agent)} --text ${JSON.stringify(text)} -d`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function cacheStats() {
|
|
53
|
+
runInTerminal("AgentX: cache", `${cli()} cache stats`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Write .vscode/mcp.json so GitHub Copilot (agent mode) / VS Code can use AgentX-Kit's MCP server.
|
|
57
|
+
async function registerMcp() {
|
|
58
|
+
const root = workspaceRoot();
|
|
59
|
+
const dir = path.join(root, ".vscode");
|
|
60
|
+
const file = path.join(dir, "mcp.json");
|
|
61
|
+
let config = { servers: {} };
|
|
62
|
+
try {
|
|
63
|
+
if (fs.existsSync(file)) config = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
64
|
+
} catch (e) { /* start fresh on parse error */ }
|
|
65
|
+
config.servers = config.servers || {};
|
|
66
|
+
config.servers["agentx-kit"] = { command: cli(), args: ["mcp"] };
|
|
67
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
68
|
+
fs.writeFileSync(file, JSON.stringify(config, null, 2));
|
|
69
|
+
vscode.window.showInformationMessage(
|
|
70
|
+
"AgentX-Kit MCP server registered in .vscode/mcp.json. Open Copilot Chat (Agent mode) and ask it to build an agent from a problem statement."
|
|
71
|
+
);
|
|
72
|
+
const doc = await vscode.workspace.openTextDocument(file);
|
|
73
|
+
vscode.window.showTextDocument(doc);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function activate(context) {
|
|
77
|
+
const reg = (id, fn) => context.subscriptions.push(vscode.commands.registerCommand(id, fn));
|
|
78
|
+
reg("agentx.newProject", newProject);
|
|
79
|
+
reg("agentx.dashboard", dashboard);
|
|
80
|
+
reg("agentx.addPrompt", addPrompt);
|
|
81
|
+
reg("agentx.cacheStats", cacheStats);
|
|
82
|
+
reg("agentx.registerMcp", registerMcp);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function deactivate() {}
|
|
86
|
+
|
|
87
|
+
module.exports = { activate, deactivate };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentx-kit",
|
|
3
|
+
"displayName": "AgentX-Kit",
|
|
4
|
+
"description": "Scaffold provider-agnostic LangChain/CrewAI agent projects, open the prompt dashboard, and wire AgentX-Kit into Copilot — from VS Code.",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"publisher": "agentx",
|
|
7
|
+
"engines": { "vscode": "^1.85.0" },
|
|
8
|
+
"categories": ["Machine Learning", "Snippets", "Other"],
|
|
9
|
+
"keywords": ["ai", "agents", "llm", "langchain", "crewai", "mcp", "scaffold", "copilot"],
|
|
10
|
+
"icon": "icon.png",
|
|
11
|
+
"repository": { "type": "git", "url": "https://github.com/muhammadyahiya/agentx-kit" },
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"main": "./extension.js",
|
|
14
|
+
"activationEvents": [],
|
|
15
|
+
"contributes": {
|
|
16
|
+
"commands": [
|
|
17
|
+
{ "command": "agentx.newProject", "title": "AgentX: New Agent Project" },
|
|
18
|
+
{ "command": "agentx.dashboard", "title": "AgentX: Open Prompt Dashboard" },
|
|
19
|
+
{ "command": "agentx.addPrompt", "title": "AgentX: Add Agent Prompt" },
|
|
20
|
+
{ "command": "agentx.cacheStats", "title": "AgentX: Show Response-Cache Stats" },
|
|
21
|
+
{ "command": "agentx.registerMcp", "title": "AgentX: Register MCP Server for Copilot" }
|
|
22
|
+
],
|
|
23
|
+
"configuration": {
|
|
24
|
+
"title": "AgentX-Kit",
|
|
25
|
+
"properties": {
|
|
26
|
+
"agentx.command": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"default": "agentx",
|
|
29
|
+
"description": "Path to the agentx CLI (from `pip install agentx-kit`)."
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -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.
|
|
4
|
+
version = "0.5.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"
|
|
@@ -60,6 +60,7 @@ observability = [
|
|
|
60
60
|
]
|
|
61
61
|
server = ["fastapi>=0.110.0", "uvicorn[standard]>=0.29.0", "sse-starlette>=2.0.0"]
|
|
62
62
|
dashboard = ["streamlit>=1.40.0", "tiktoken>=0.7.0", "pandas>=2.0.0"]
|
|
63
|
+
connector = ["mcp>=1.2.0"]
|
|
63
64
|
|
|
64
65
|
# ---- Bundles ----
|
|
65
66
|
all = [
|
|
@@ -73,6 +74,7 @@ all = [
|
|
|
73
74
|
"openinference-instrumentation-langchain>=0.1.0",
|
|
74
75
|
"fastapi>=0.110.0", "uvicorn[standard]>=0.29.0", "sse-starlette>=2.0.0",
|
|
75
76
|
"streamlit>=1.40.0", "tiktoken>=0.7.0", "pandas>=2.0.0",
|
|
77
|
+
"mcp>=1.2.0",
|
|
76
78
|
]
|
|
77
79
|
dev = ["pytest>=8.0.0", "pytest-cov>=5.0.0"]
|
|
78
80
|
|
|
@@ -16,7 +16,7 @@ is enough to get started.
|
|
|
16
16
|
"""
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
-
__version__ = "0.
|
|
19
|
+
__version__ = "0.5.0"
|
|
20
20
|
|
|
21
21
|
from .providers import ( # noqa: E402
|
|
22
22
|
ProviderSpec,
|
|
@@ -39,6 +39,7 @@ from .insights import ( # noqa: E402
|
|
|
39
39
|
estimate_cost,
|
|
40
40
|
optimize_prompt,
|
|
41
41
|
)
|
|
42
|
+
from .cache import cache_stats, clear_cache, disable_caching, enable_caching # noqa: E402
|
|
42
43
|
|
|
43
44
|
__all__ = [
|
|
44
45
|
"__version__",
|
|
@@ -63,4 +64,9 @@ __all__ = [
|
|
|
63
64
|
"optimize_prompt",
|
|
64
65
|
"count_tokens",
|
|
65
66
|
"estimate_cost",
|
|
67
|
+
# response caching
|
|
68
|
+
"enable_caching",
|
|
69
|
+
"disable_caching",
|
|
70
|
+
"cache_stats",
|
|
71
|
+
"clear_cache",
|
|
66
72
|
]
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""LLM response caching — cut cost & latency across all providers.
|
|
2
|
+
|
|
3
|
+
Caching is the top token-optimization lever (2026): repeat/near-repeat calls are
|
|
4
|
+
served from a local store instead of the model. This is an **exact** response
|
|
5
|
+
cache implemented as a LangChain ``BaseCache`` and installed globally, so every
|
|
6
|
+
``get_chat_model(...)`` call benefits automatically — no code changes.
|
|
7
|
+
|
|
8
|
+
from agentx.cache import enable_caching, cache_stats
|
|
9
|
+
enable_caching() # all subsequent LLM calls are cached
|
|
10
|
+
...
|
|
11
|
+
print(cache_stats()) # hits, misses, est. tokens/$ saved
|
|
12
|
+
|
|
13
|
+
Persistence is a small SQLite file (default ``.agentx/llm_cache.sqlite``) with an
|
|
14
|
+
optional TTL. Stats track hit/miss and estimated tokens + USD saved (derived from
|
|
15
|
+
cached completion sizes — see ``agentx.insights.tokens``).
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import hashlib
|
|
20
|
+
import sqlite3
|
|
21
|
+
import threading
|
|
22
|
+
import time
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
_DEFAULT_PATH = ".agentx/llm_cache.sqlite"
|
|
27
|
+
_lock = threading.Lock()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _key(prompt: str, llm_string: str) -> str:
|
|
31
|
+
return hashlib.sha256(f"{llm_string}\x00{prompt}".encode("utf-8")).hexdigest()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _model_from_llm_string(llm_string: str) -> str:
|
|
35
|
+
# llm_string is a serialized model descriptor; best-effort model name for costing.
|
|
36
|
+
for token in ("gpt-4o-mini", "gpt-4o", "gpt-4.1", "claude-3-5", "gemini-1.5", "llama"):
|
|
37
|
+
if token in llm_string:
|
|
38
|
+
return token
|
|
39
|
+
return "gpt-4o-mini"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class AgentXCache:
|
|
43
|
+
"""A LangChain ``BaseCache`` backed by SQLite, with TTL + savings stats.
|
|
44
|
+
|
|
45
|
+
Implements ``lookup``/``update`` (and ``aclear``) so it can be passed to
|
|
46
|
+
``langchain_core.globals.set_llm_cache``.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(self, path: str | Path = _DEFAULT_PATH, ttl: int | None = None):
|
|
50
|
+
self.path = Path(path)
|
|
51
|
+
self.path.parent.mkdir(parents=True, exist_ok=True)
|
|
52
|
+
self.ttl = ttl
|
|
53
|
+
self._init_db()
|
|
54
|
+
|
|
55
|
+
def _conn(self) -> sqlite3.Connection:
|
|
56
|
+
return sqlite3.connect(str(self.path))
|
|
57
|
+
|
|
58
|
+
def _init_db(self) -> None:
|
|
59
|
+
with _lock, self._conn() as c:
|
|
60
|
+
c.execute(
|
|
61
|
+
"CREATE TABLE IF NOT EXISTS cache "
|
|
62
|
+
"(key TEXT PRIMARY KEY, value TEXT, ts REAL, model TEXT, out_tokens INT)"
|
|
63
|
+
)
|
|
64
|
+
c.execute("CREATE TABLE IF NOT EXISTS stats (name TEXT PRIMARY KEY, val REAL)")
|
|
65
|
+
for name in ("hits", "misses", "tokens_saved"):
|
|
66
|
+
c.execute("INSERT OR IGNORE INTO stats(name, val) VALUES (?, 0)", (name,))
|
|
67
|
+
|
|
68
|
+
def _bump(self, conn: sqlite3.Connection, name: str, by: float = 1) -> None:
|
|
69
|
+
conn.execute("UPDATE stats SET val = val + ? WHERE name = ?", (by, name))
|
|
70
|
+
|
|
71
|
+
# ----- BaseCache interface -----
|
|
72
|
+
def lookup(self, prompt: str, llm_string: str) -> Any | None:
|
|
73
|
+
import warnings
|
|
74
|
+
|
|
75
|
+
from langchain_core.load import loads
|
|
76
|
+
|
|
77
|
+
key = _key(prompt, llm_string)
|
|
78
|
+
with _lock, self._conn() as c:
|
|
79
|
+
row = c.execute("SELECT value, ts, out_tokens FROM cache WHERE key = ?", (key,)).fetchone()
|
|
80
|
+
if not row:
|
|
81
|
+
self._bump(c, "misses")
|
|
82
|
+
return None
|
|
83
|
+
value, ts, out_tokens = row
|
|
84
|
+
if self.ttl is not None and (time.time() - ts) > self.ttl:
|
|
85
|
+
c.execute("DELETE FROM cache WHERE key = ?", (key,))
|
|
86
|
+
self._bump(c, "misses")
|
|
87
|
+
return None
|
|
88
|
+
self._bump(c, "hits")
|
|
89
|
+
self._bump(c, "tokens_saved", out_tokens or 0)
|
|
90
|
+
try:
|
|
91
|
+
# We wrote these values ourselves, so deserialization is trusted.
|
|
92
|
+
with warnings.catch_warnings():
|
|
93
|
+
warnings.simplefilter("ignore")
|
|
94
|
+
return loads(value)
|
|
95
|
+
except Exception: # noqa: BLE001 - corrupt entry
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
def update(self, prompt: str, llm_string: str, return_val: Any) -> None:
|
|
99
|
+
from langchain_core.load import dumps
|
|
100
|
+
|
|
101
|
+
from .insights.tokens import count_tokens
|
|
102
|
+
|
|
103
|
+
key = _key(prompt, llm_string)
|
|
104
|
+
model = _model_from_llm_string(llm_string)
|
|
105
|
+
text = ""
|
|
106
|
+
try:
|
|
107
|
+
text = " ".join(getattr(g, "text", "") or "" for g in return_val)
|
|
108
|
+
except Exception: # noqa: BLE001
|
|
109
|
+
text = ""
|
|
110
|
+
out_tokens = count_tokens(text, model)
|
|
111
|
+
try:
|
|
112
|
+
payload = dumps(return_val)
|
|
113
|
+
except Exception: # noqa: BLE001 - non-serializable result; skip caching
|
|
114
|
+
return
|
|
115
|
+
with _lock, self._conn() as c:
|
|
116
|
+
c.execute(
|
|
117
|
+
"INSERT OR REPLACE INTO cache(key, value, ts, model, out_tokens) VALUES (?, ?, ?, ?, ?)",
|
|
118
|
+
(key, payload, time.time(), model, out_tokens),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
def clear(self, **kwargs: Any) -> None:
|
|
122
|
+
with _lock, self._conn() as c:
|
|
123
|
+
c.execute("DELETE FROM cache")
|
|
124
|
+
c.execute("UPDATE stats SET val = 0")
|
|
125
|
+
|
|
126
|
+
def stats(self) -> dict:
|
|
127
|
+
with _lock, self._conn() as c:
|
|
128
|
+
rows = dict(c.execute("SELECT name, val FROM stats").fetchall())
|
|
129
|
+
entries = c.execute("SELECT COUNT(*) FROM cache").fetchone()[0]
|
|
130
|
+
hits, misses = int(rows.get("hits", 0)), int(rows.get("misses", 0))
|
|
131
|
+
total = hits + misses
|
|
132
|
+
tokens_saved = int(rows.get("tokens_saved", 0))
|
|
133
|
+
# Conservative blended estimate: $0.002 / 1K output tokens saved.
|
|
134
|
+
cost_saved = round(tokens_saved / 1000 * 0.002, 6)
|
|
135
|
+
return {
|
|
136
|
+
"entries": entries,
|
|
137
|
+
"hits": hits,
|
|
138
|
+
"misses": misses,
|
|
139
|
+
"hit_rate": round(hits / total, 3) if total else 0.0,
|
|
140
|
+
"tokens_saved": tokens_saved,
|
|
141
|
+
"est_usd_saved": cost_saved,
|
|
142
|
+
"path": str(self.path),
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def enable_caching(path: str | Path = _DEFAULT_PATH, ttl: int | None = None) -> AgentXCache:
|
|
147
|
+
"""Install a global LLM response cache. All providers benefit automatically."""
|
|
148
|
+
from langchain_core.globals import set_llm_cache
|
|
149
|
+
|
|
150
|
+
cache = AgentXCache(path, ttl=ttl)
|
|
151
|
+
set_llm_cache(cache)
|
|
152
|
+
return cache
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def disable_caching() -> None:
|
|
156
|
+
from langchain_core.globals import set_llm_cache
|
|
157
|
+
|
|
158
|
+
set_llm_cache(None)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def cache_stats(path: str | Path = _DEFAULT_PATH) -> dict:
|
|
162
|
+
return AgentXCache(path).stats()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def clear_cache(path: str | Path = _DEFAULT_PATH) -> None:
|
|
166
|
+
AgentXCache(path).clear()
|