agentx-dev 3.1.2__tar.gz → 3.1.3__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_dev-3.1.3/CHANGELOG.md +209 -0
- agentx_dev-3.1.3/CONTRIBUTING.md +105 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/MANIFEST.in +2 -0
- {agentx_dev-3.1.2/agentx_dev.egg-info → agentx_dev-3.1.3}/PKG-INFO +1 -1
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Runner/AgentRun.py +147 -26
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Runner/AsyncAgentRun.py +68 -3
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Tools.py +60 -41
- {agentx_dev-3.1.2 → agentx_dev-3.1.3/agentx_dev.egg-info}/PKG-INFO +1 -1
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev.egg-info/SOURCES.txt +2 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/pyproject.toml +1 -1
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/AGENTX.md +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/LICENSE +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/README.md +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Agents/Agent.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Agents/__init__.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/AsyncTools.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/AutoSetup.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Cache.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/ChatModel.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Compiler.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Config.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/DefaultTools.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Embeddings.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Evals.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Handoffs.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Loader.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/MCP.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Memory.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Observability.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Planner.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Runner/__init__.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Runner/promptTemplate.yaml +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Session.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Splitters.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Streaming.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/Supervisor.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/VectorStores/__init__.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/VectorStores/chroma_store.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/VectorStores/pg_store.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/VectorStores/qdrant_store.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/WebTools.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/__init__.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/resources/__init__.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev/resources/promptTemplate.yaml +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev.egg-info/dependency_links.txt +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev.egg-info/requires.txt +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/agentx_dev.egg-info/top_level.txt +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/README.md +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/agentic_rag_demo.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/async_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/async_quickstart.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/auto_features_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/caching_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/chatbot_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/complete_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/concurrent_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/concurrent_tool_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/file_agent_demo.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/function_calling_demo.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/mcp_demo.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/observability_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/orchestration_demo.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/planner_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/supervisor_codebase_analysis_demo.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/supervisor_example.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/sync_quickstart.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/v3_1_1_features_demo.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/v3_1_comprehensive_demo.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/examples/v3_1_features_demo.py +0 -0
- {agentx_dev-3.1.2 → agentx_dev-3.1.3}/setup.cfg +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `agentx-dev` are documented here. Format loosely
|
|
4
|
+
follows [Keep a Changelog](https://keepachangelog.com/); versioning is
|
|
5
|
+
[Semver](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [3.1.3] — 2026-07-22
|
|
8
|
+
|
|
9
|
+
Docs-only patch. No code changes since 3.1.2. Users on 3.1.2 don't
|
|
10
|
+
need to upgrade for functionality; upgrade to pick up the improved
|
|
11
|
+
onboarding docs bundled in the sdist.
|
|
12
|
+
|
|
13
|
+
### Documentation
|
|
14
|
+
|
|
15
|
+
- **Tools doc rewritten to answer "how do I actually use these?"**
|
|
16
|
+
Added §0 `How each built-in tool is registered` as the entry
|
|
17
|
+
section. Two registration paths — auto vs manual — laid out in a
|
|
18
|
+
table on the first screen. Six runnable subsections covering every
|
|
19
|
+
combination:
|
|
20
|
+
- §0.1 DefaultTools via `Permissions(...)` (auto)
|
|
21
|
+
- §0.2 WebTools via `tools=[web_search_tool(), web_fetch_tool()]`
|
|
22
|
+
- §0.3 RAG via `TextSplitter` -> `VectorStore.add_documents` ->
|
|
23
|
+
`vector_search_tool(store)`
|
|
24
|
+
- §0.4 Handoffs via `handoff_tool` + `HandoffCoordinator`
|
|
25
|
+
- §0.5 Custom `StructuredTool` from scratch
|
|
26
|
+
- §0.6 Fully-loaded runner combining all of the above
|
|
27
|
+
- §0.7 Rules on name collisions, invisible-denied-capabilities,
|
|
28
|
+
async-tool behavior
|
|
29
|
+
The existing inventory + wrapper / controls / cheat-sheet sections
|
|
30
|
+
are unchanged; they now sit after the "how to use them" primer
|
|
31
|
+
instead of before it.
|
|
32
|
+
|
|
33
|
+
## [3.1.2] — 2026-07-22
|
|
34
|
+
|
|
35
|
+
Patch release. Two independent fixes.
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- **`llm_judge` correctly parses YES/NO across providers.** The judge
|
|
40
|
+
parser was comparing the reply's first word to the literal string
|
|
41
|
+
`"YES"`. GPT-4o answers `"YES,"` (comma-suffixed), which failed the
|
|
42
|
+
equality check and marked every genuine PASS as FAIL. Claude replies
|
|
43
|
+
`"YES"` without punctuation so the bug hid during local development.
|
|
44
|
+
Fixed by matching `\b(YES|NO)\b` (word-boundary regex, case-
|
|
45
|
+
insensitive) at the start of the reply. Handles every real shape:
|
|
46
|
+
`YES`, `YES.`, `YES!`, `YES, exactly right`, `Yes.`, `yes -- reason`.
|
|
47
|
+
Ambiguous replies (`Maybe`, empty string) still fail closed.
|
|
48
|
+
- Regression test `test_llm_judge_parses_various_verdict_shapes`
|
|
49
|
+
covers 8 YES shapes, 5 NO shapes, and 4 ambiguous replies.
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
|
|
53
|
+
- **`agentx_dev.Tools` is a one-stop tools namespace.** Users no
|
|
54
|
+
longer need to remember which module each tool lives in:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from agentx_dev.Tools import (
|
|
58
|
+
StandardTool, StructuredTool,
|
|
59
|
+
AsyncStandardTool, AsyncStructuredTool,
|
|
60
|
+
web_search_tool, web_fetch_tool,
|
|
61
|
+
vector_search_tool, handoff_tool,
|
|
62
|
+
DefaultTools, Permissions,
|
|
63
|
+
)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Both this form and the pre-existing `from agentx_dev import X`
|
|
67
|
+
form coexist. Implementation uses PEP 562 module `__getattr__`
|
|
68
|
+
and `__dir__` so re-exports are lazy (no import cost for modules
|
|
69
|
+
the caller doesn't touch) and show up in IDE autocomplete +
|
|
70
|
+
`dir(agentx_dev.Tools)`.
|
|
71
|
+
|
|
72
|
+
## [3.1.1] — 2026-07-21
|
|
73
|
+
|
|
74
|
+
Second batch of 3.1 features + a full docs + brand pass.
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
|
|
78
|
+
**Streaming through orchestration**
|
|
79
|
+
- `Supervisor.stream()` / `AsyncSupervisor.astream()` emit
|
|
80
|
+
`plan_start` / `plan` / `dispatch` / `subtask_result` /
|
|
81
|
+
`synthesize_start` / `final` / `completion` events.
|
|
82
|
+
- `HandoffCoordinator.stream()` / `.astream()` emit `invoke` /
|
|
83
|
+
`completion` / `handoff` / `final` / `result` events per hop.
|
|
84
|
+
- Legacy `.run()` / `.arun()` refactored to consume the streams (no
|
|
85
|
+
code duplication).
|
|
86
|
+
|
|
87
|
+
**Prompt optimization — `Compiled`**
|
|
88
|
+
- New `agentx_dev.Compiler` module.
|
|
89
|
+
- `Compiled(runner_factory, trainset, ...)` iteratively refines a
|
|
90
|
+
runner's `system_addendum` against the eval harness. Half of
|
|
91
|
+
DSPy's power at a tenth of the surface.
|
|
92
|
+
|
|
93
|
+
**Anthropic Batch API**
|
|
94
|
+
- `Claude.batch(requests)` submits many prompts at Anthropic's 50%-off
|
|
95
|
+
batch rate, polls to completion, returns results in submission order.
|
|
96
|
+
- Per-request error dicts on failure; token usage funneled into
|
|
97
|
+
`TokenUsage` so cost tracking stays a single source of truth.
|
|
98
|
+
|
|
99
|
+
**Vector store adapters — `agentx_dev.VectorStores`**
|
|
100
|
+
- `ChromaVectorStore`, `QdrantVectorStore`, `PgVectorStore` — same
|
|
101
|
+
public shape as the in-memory `VectorStore` (`add` / `search` /
|
|
102
|
+
`delete` / `clear` / `__len__` / `embeddings`).
|
|
103
|
+
- `vector_search_tool()` and `SemanticMemory` accept any of them.
|
|
104
|
+
- SDK imports lazy; friendly `ImportError` when the underlying SDK
|
|
105
|
+
is missing.
|
|
106
|
+
|
|
107
|
+
**Trace viewer (`viewer/`)**
|
|
108
|
+
- Self-hosted single-page app that reads `FileHook` JSONL and renders
|
|
109
|
+
a timeline with type/text filters, summary sidebar, JSON drill-down.
|
|
110
|
+
- Works from `file://`, no server required.
|
|
111
|
+
|
|
112
|
+
**Docs site (`host/`)**
|
|
113
|
+
- Full editorial dark-first design system (JetBrains Mono headings,
|
|
114
|
+
Inter body, `#B8FF3E` electric-lime accent).
|
|
115
|
+
- Command palette (`Cmd+K`) with keyboard navigation and live search.
|
|
116
|
+
- Hero code snippet with hand-tinted syntax highlighting.
|
|
117
|
+
- Reading progress bar, breadcrumbs, header anchor links.
|
|
118
|
+
- Sidebar sliding active marker, collapsible groups.
|
|
119
|
+
- Code copy buttons, language labels.
|
|
120
|
+
- Right-rail auto-TOC with `IntersectionObserver` scrollspy.
|
|
121
|
+
- Dark/light theme toggle, persisted.
|
|
122
|
+
- Cache-busted assets so edits land on refresh without hard-reload.
|
|
123
|
+
|
|
124
|
+
**Brand identity (`brand/`)**
|
|
125
|
+
- Full brand kit: 5 SVG assets (`mark`, `mono`, `wordmark`, `logo-full`,
|
|
126
|
+
`app-icon`), `BRAND.md` strategy doc, rendered brand-kit HTML deck.
|
|
127
|
+
- Copy audit dropped "small" (weak) and "LangChain" references from
|
|
128
|
+
all marketing surfaces.
|
|
129
|
+
- Favicon wired into docs + trace viewer.
|
|
130
|
+
|
|
131
|
+
**Test suite (`tests/`)**
|
|
132
|
+
- Restored + expanded pytest suite: 127 tests passing (3 skipped for
|
|
133
|
+
absent optional SDKs).
|
|
134
|
+
- Coverage: parser + all `AgentType` variants, `ToolRegistry`
|
|
135
|
+
(dispatch / dup-guard / circuit-breaker / timeout), Permissions
|
|
136
|
+
(capability gating + sandbox + traversal), budgets (cost / rate /
|
|
137
|
+
retry / non-retryable HTTP), runner loop (streaming + output_schema
|
|
138
|
+
+ chat history), embeddings + `VectorStore` + `SemanticMemory`,
|
|
139
|
+
handoffs (bounded hops + history sanitization), evals harness
|
|
140
|
+
(all assertion helpers + JSON case loaders), vector-store adapter
|
|
141
|
+
shape conformance.
|
|
142
|
+
|
|
143
|
+
**Docs (`docs/`)**
|
|
144
|
+
- Full docs tree (34 pages), including new pages for:
|
|
145
|
+
vector store adapters, prompt optimization, batch API, trace viewer,
|
|
146
|
+
and a **use-cases** landing (13 concrete scenarios with runnable code).
|
|
147
|
+
- Rewrote **Tools** page to enumerate every built-in tool with args,
|
|
148
|
+
return shape, capability flag, and use-case guidance.
|
|
149
|
+
- Rewrote **Agents** page to cover all four orchestration
|
|
150
|
+
architectures (Solo / Supervisor / Handoffs / Compiled) with
|
|
151
|
+
decision trees, worked examples, and cheat sheet.
|
|
152
|
+
- **Agentic RAG chatbot** as use case §13 — multi-query decomposition,
|
|
153
|
+
parallel retrieval, self-critique, citations, user memory.
|
|
154
|
+
|
|
155
|
+
**Examples**
|
|
156
|
+
- `examples/agentic_rag_demo.py` — the runnable version of the
|
|
157
|
+
agentic RAG use case. Auto-seeds a KB if none exists, `--demo` flag
|
|
158
|
+
runs a 3-turn scripted session proving user-notes recall works.
|
|
159
|
+
|
|
160
|
+
**Package**
|
|
161
|
+
- `[chroma]`, `[qdrant]`, `[pgvector]`, `[dev]` extras added.
|
|
162
|
+
- `[anthropic]` bumped to `>=0.36` (Batch API + prompt cache).
|
|
163
|
+
|
|
164
|
+
### Fixed
|
|
165
|
+
|
|
166
|
+
- `AgentRunner._iter_run` in `bind_tools_natively=True` mode uses a
|
|
167
|
+
minimal system prompt instead of the AgentType template so the
|
|
168
|
+
ReAct `action/action_input` scaffold no longer fights the native
|
|
169
|
+
tool interface. Previously produced JSON-blob answers under GPT.
|
|
170
|
+
- `HandoffCoordinator._sanitize_history_for_next_agent` strips tool
|
|
171
|
+
and function role messages between hops so tool_call_ids from a
|
|
172
|
+
previous agent don't leak into the next model's call (OpenAI 400).
|
|
173
|
+
- Docs site marker positioning uses double-`requestAnimationFrame` +
|
|
174
|
+
`document.fonts.ready` so the sidebar accent bar lands on the
|
|
175
|
+
correct row even on a cold font cache.
|
|
176
|
+
- Primary hero CTA color uses `#doc .hero-cta a.primary` selector to
|
|
177
|
+
outrank `#doc a` link styling (previously rendered lime-on-lime
|
|
178
|
+
and was invisible).
|
|
179
|
+
|
|
180
|
+
### Notes
|
|
181
|
+
|
|
182
|
+
- Package version bumped from `3.0.6` to `3.1.1`. The 3.1.0 release
|
|
183
|
+
did not ship publicly — 3.1.1 is the first 3.1-tagged PyPI release
|
|
184
|
+
and includes both batches of features.
|
|
185
|
+
|
|
186
|
+
## [3.1.0] — internal only (commits 52840e7)
|
|
187
|
+
|
|
188
|
+
First batch of 3.1 features. Committed but not released to PyPI.
|
|
189
|
+
Merged into 3.1.1 for the public release.
|
|
190
|
+
|
|
191
|
+
### Added
|
|
192
|
+
- Anthropic prompt caching (`Claude(enable_prompt_cache=True)`).
|
|
193
|
+
- Parallel per-turn tool dispatch in `AgentRunner`
|
|
194
|
+
(`bind_tools_natively=True`, `parallel_tool_workers`).
|
|
195
|
+
- Semantic memory (`SemanticMemory`, embeddings-backed retrieval).
|
|
196
|
+
- RAG core (`Embeddings`, `HashEmbeddings`, `OpenAIEmbeddings`,
|
|
197
|
+
`VectorStore`, `VectorHit`, `vector_search_tool()`).
|
|
198
|
+
- Agent-to-agent handoffs (`HandoffRequest`, `handoff_tool`,
|
|
199
|
+
`HandoffCoordinator`, `HandoffResult`).
|
|
200
|
+
- Evals harness (`EvalCase`, `EvalRunner`, `EvalReport`, 7 assertion
|
|
201
|
+
helpers, JSON case loader, `python -m agentx_dev.Evals run` CLI).
|
|
202
|
+
- `TokenUsage.cache_hit_ratio` property.
|
|
203
|
+
|
|
204
|
+
## [3.0.6] — 2026-03 (baseline)
|
|
205
|
+
|
|
206
|
+
Security hardening baseline (SSRF guard on `web_fetch`, HMAC-signed
|
|
207
|
+
persistent state, scrubbed subprocess env, path sanitizer,
|
|
208
|
+
`permissions.json` mode 0o600, ReDoS guard on `grep`,
|
|
209
|
+
`invoke`/`ainvoke` accept bare strings and message lists).
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Contributing to agentx-dev
|
|
2
|
+
|
|
3
|
+
Thanks for your interest. This is a solo-authored framework, so a few
|
|
4
|
+
process choices are opinionated -- they exist to keep the surface area
|
|
5
|
+
small and the codebase readable.
|
|
6
|
+
|
|
7
|
+
## Getting set up
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/shadrach098/Bruce_framework.git
|
|
11
|
+
cd Bruce_framework
|
|
12
|
+
python -m venv .venv && source .venv/bin/activate # or .venv\Scripts\activate on Windows
|
|
13
|
+
pip install -e ".[dev,anthropic]"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Sanity check:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pytest tests/ # should show 127 passing, 3 skipped
|
|
20
|
+
python -c "import agentx_dev; print(agentx_dev.__all__)"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Before you open a PR
|
|
24
|
+
|
|
25
|
+
1. **Run the tests.** `pytest tests/ -q` from the repo root.
|
|
26
|
+
2. **Add tests** for whatever you changed. Every existing subsystem
|
|
27
|
+
has a `tests/test_<module>.py`; add cases there.
|
|
28
|
+
3. **Keep the change focused.** One PR per feature or fix. If your
|
|
29
|
+
change touches five modules and adds three exports, split it.
|
|
30
|
+
4. **Preserve existing behavior** unless the change is explicitly a
|
|
31
|
+
breaking one. Backwards-compat is a real value.
|
|
32
|
+
5. **Update docs** if you added or changed a public API. `docs/`
|
|
33
|
+
holds the source; run `python host/build_data.py` to regenerate
|
|
34
|
+
the browsable site's `data.js`.
|
|
35
|
+
|
|
36
|
+
## Commit + PR style
|
|
37
|
+
|
|
38
|
+
- **Commit messages:** `<type>: <short summary>` where type is one of
|
|
39
|
+
`feat` / `fix` / `docs` / `test` / `refactor` / `chore`. Follow
|
|
40
|
+
with a blank line and the body if the summary isn't enough. Look
|
|
41
|
+
at recent commits (`git log --oneline -20`) for the shape.
|
|
42
|
+
- **PR titles:** same shape as the commit message. If the PR has
|
|
43
|
+
multiple commits, the title summarizes the whole PR.
|
|
44
|
+
- **PR descriptions:** what changed, why, and one before/after
|
|
45
|
+
example if the change is user-visible.
|
|
46
|
+
|
|
47
|
+
## What lands and what doesn't
|
|
48
|
+
|
|
49
|
+
Things that land easily:
|
|
50
|
+
|
|
51
|
+
- Bug fixes with a regression test.
|
|
52
|
+
- New tools that follow the existing patterns.
|
|
53
|
+
- Docs improvements (more examples, clearer explanations, fixing typos).
|
|
54
|
+
- New vector-store adapters or provider adapters that follow the
|
|
55
|
+
existing interface.
|
|
56
|
+
- Test coverage for uncovered paths.
|
|
57
|
+
|
|
58
|
+
Things that need discussion first (open an issue):
|
|
59
|
+
|
|
60
|
+
- New public classes or modules.
|
|
61
|
+
- Changes to public method signatures.
|
|
62
|
+
- Anything that grows the dependency footprint of the base install.
|
|
63
|
+
- Anything that reshapes the runner loop, `Supervisor`, or
|
|
64
|
+
`HandoffCoordinator`.
|
|
65
|
+
|
|
66
|
+
Things that don't land:
|
|
67
|
+
|
|
68
|
+
- Style-only refactors that reshape existing files.
|
|
69
|
+
- Adding a "generic" abstraction over one specific thing.
|
|
70
|
+
- Wrapping existing SDKs "for consistency."
|
|
71
|
+
- LangChain-compatibility shims.
|
|
72
|
+
- Auto-generated boilerplate.
|
|
73
|
+
|
|
74
|
+
## Code style
|
|
75
|
+
|
|
76
|
+
- **Docstrings are the source of truth.** Every public class + method
|
|
77
|
+
gets one. Say *why* the choice was made, not just what it does.
|
|
78
|
+
- **No trailing summary comments** at the end of functions.
|
|
79
|
+
- **Type hints on public APIs.** Not needed on internal helpers if
|
|
80
|
+
the shape is obvious from three lines up.
|
|
81
|
+
- **Small files > large files**, but one-module features > splitting
|
|
82
|
+
a single concept across three files for tidiness.
|
|
83
|
+
|
|
84
|
+
## Security-sensitive changes
|
|
85
|
+
|
|
86
|
+
The framework has explicit security surfaces:
|
|
87
|
+
|
|
88
|
+
- `Permissions` + sandbox enforcement in `DefaultTools.py`
|
|
89
|
+
- `run_python` HMAC-signed persistent state in `AutoSetup.py`
|
|
90
|
+
- SSRF guard in `WebTools.py`
|
|
91
|
+
- Session-id sanitizer in `DefaultTools.py`
|
|
92
|
+
|
|
93
|
+
If your change touches any of these, please:
|
|
94
|
+
|
|
95
|
+
1. Add a test that exercises the security check.
|
|
96
|
+
2. Add a note in the PR describing the threat model you considered.
|
|
97
|
+
|
|
98
|
+
See `AGENTX.md` at the repo root for the guardrails the framework
|
|
99
|
+
imposes on itself.
|
|
100
|
+
|
|
101
|
+
## Questions?
|
|
102
|
+
|
|
103
|
+
Open an issue with the "question" label. Solo maintainer, so response
|
|
104
|
+
time varies -- a good repro / minimal example is the single biggest
|
|
105
|
+
help.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentx-dev
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.3
|
|
4
4
|
Summary: A production-grade Python framework for building LLM agents. Multi-provider chat, permission-gated tools, RAG (in-mem + Chroma/Qdrant/pgvector), semantic memory, Supervisor + Handoffs multi-agent orchestration with streaming, evals harness, prompt caching, Batch API, prompt-optimizer, MCP integration.
|
|
5
5
|
Author-email: Bruce-Arhin Shadrach <brucearhin098@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -1095,18 +1095,38 @@ def _read_action_input(parser_instance: BaseModel):
|
|
|
1095
1095
|
|
|
1096
1096
|
|
|
1097
1097
|
class AgentRunner:
|
|
1098
|
-
"""
|
|
1099
|
-
|
|
1098
|
+
"""Sync agent runner. Connects a chat model, a prompt template, and a
|
|
1099
|
+
set of tools into a reason-act loop.
|
|
1100
|
+
|
|
1101
|
+
Typical use::
|
|
1100
1102
|
|
|
1101
|
-
|
|
1102
|
-
and the prompt. It manages the agent's state, including its conversational
|
|
1103
|
-
history and internal scratchpad, and runs the primary "reason-act" cycle.
|
|
1103
|
+
from agentx_dev import AgentRunner, AgentType, Claude, Permissions
|
|
1104
1104
|
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1105
|
+
runner = AgentRunner(
|
|
1106
|
+
model=Claude(), # or GPT()
|
|
1107
|
+
agent=AgentType.ReAct,
|
|
1108
|
+
tools=[weather_tool], # your tools
|
|
1109
|
+
permissions=Permissions.full_access(["./workspace"]),
|
|
1110
|
+
)
|
|
1111
|
+
result = runner.invoke("What's the weather in Paris?")
|
|
1112
|
+
print(result.content)
|
|
1113
|
+
|
|
1114
|
+
The runner supports three execution modes, all set via constructor
|
|
1115
|
+
flags:
|
|
1116
|
+
|
|
1117
|
+
- **Text mode** (default) -- the model emits JSON matching the
|
|
1118
|
+
AgentType parser; the runner parses out the action and dispatches
|
|
1119
|
+
the tool. Works with any chat model.
|
|
1120
|
+
- **Function-calling mode** (``use_function_calling=True``) -- the
|
|
1121
|
+
AgentType parser itself is forwarded as the native FC tool.
|
|
1122
|
+
Requires the model to implement ``call_with_tools``.
|
|
1123
|
+
- **Native binding mode** (``bind_tools_natively=True``, 3.1) --
|
|
1124
|
+
your tools are bound directly as native FC tools; the AgentType
|
|
1125
|
+
parser is skipped. Multiple tool_use blocks in one turn dispatch
|
|
1126
|
+
concurrently on a bounded thread pool. Mutually exclusive with
|
|
1127
|
+
``use_function_calling``.
|
|
1128
|
+
|
|
1129
|
+
For the async equivalent, see :class:`AsyncAgentRunner`.
|
|
1110
1130
|
"""
|
|
1111
1131
|
|
|
1112
1132
|
def __init__(
|
|
@@ -1128,6 +1148,123 @@ class AgentRunner:
|
|
|
1128
1148
|
system_addendum: Optional[str] = None,
|
|
1129
1149
|
strict_tool_dispatch: bool = False,
|
|
1130
1150
|
):
|
|
1151
|
+
"""Construct an ``AgentRunner``.
|
|
1152
|
+
|
|
1153
|
+
Args:
|
|
1154
|
+
model: The chat model backing every LLM call. Any
|
|
1155
|
+
``BaseChatModel`` subclass -- ``Claude()``, ``GPT()``,
|
|
1156
|
+
or your own provider adapter.
|
|
1157
|
+
Agent: The prompt template + parser pair the runner uses.
|
|
1158
|
+
Accepts an ``AgentType`` member
|
|
1159
|
+
(``AgentType.ReAct`` / ``AgentType.Chain_of_Thought``
|
|
1160
|
+
/ ``AgentType.Zero_Shot`` / ``AgentType.Few_Shot`` /
|
|
1161
|
+
``AgentType.Instruction_Tuned``), a custom
|
|
1162
|
+
``AgentFormatter`` instance you built, or a raw
|
|
1163
|
+
prompt-template string containing ``{tools}``,
|
|
1164
|
+
``{tool_names}``, and ``{user_input}`` placeholders.
|
|
1165
|
+
Aliased as ``agent=`` (lowercase, PEP-8-friendly).
|
|
1166
|
+
Passing both ``Agent=`` and ``agent=`` raises
|
|
1167
|
+
``TypeError`` -- pick one.
|
|
1168
|
+
tools: Tool instances the LLM can call. Each must be a
|
|
1169
|
+
``StandardTool`` / ``StructuredTool`` /
|
|
1170
|
+
``AsyncStandardTool`` / ``AsyncStructuredTool``.
|
|
1171
|
+
Defaults to an empty list. Framework guards apply
|
|
1172
|
+
automatically (duplicate-call, timeout, circuit
|
|
1173
|
+
breaker, cache, observability). Merged with any
|
|
1174
|
+
``DefaultTools`` produced from ``permissions=`` below;
|
|
1175
|
+
collisions raise ``TypeError``.
|
|
1176
|
+
max_iterations: Cap on tool-calling cycles per invoke.
|
|
1177
|
+
Default 4. Bump for complex multi-step tasks. If the
|
|
1178
|
+
loop reaches the cap without a Final_Answer, the
|
|
1179
|
+
runner synthesizes a summary of what actually
|
|
1180
|
+
happened (last successful tool result + step list)
|
|
1181
|
+
so callers never get a bare "No final answer".
|
|
1182
|
+
auto_cache: When True (default), tool results are cached
|
|
1183
|
+
by ``(name, args)`` signature via
|
|
1184
|
+
``get_global_cache()``. Second identical dispatch is
|
|
1185
|
+
a cache hit -- observability emits ``CACHE_HIT``.
|
|
1186
|
+
Disable when your tools have side effects
|
|
1187
|
+
(``send_email`` / ``write_file``) or time-varying
|
|
1188
|
+
outputs (``current_time`` / ``stock_price``).
|
|
1189
|
+
auto_memory: When True, the runner instantiates a default
|
|
1190
|
+
``ConversationMemory`` and threads it as chat history
|
|
1191
|
+
automatically between invokes. Off by default; most
|
|
1192
|
+
real apps prefer explicit ``Session`` + custom
|
|
1193
|
+
``BaseMemory`` (see the memory strategies guide).
|
|
1194
|
+
use_function_calling: When True, route the AgentType
|
|
1195
|
+
parser through the model's native tool-calling API
|
|
1196
|
+
(``call_with_tools``) instead of parsing JSON out of
|
|
1197
|
+
assistant text. Slightly higher accuracy on tool-call
|
|
1198
|
+
correctness. Requires the model to implement
|
|
1199
|
+
``call_with_tools`` (GPT and Claude both do). Mutually
|
|
1200
|
+
exclusive with ``bind_tools_natively``.
|
|
1201
|
+
verbose: Print the running Thought / Action / Observation
|
|
1202
|
+
trace to stdout while the loop executes. Convenient
|
|
1203
|
+
during development; usually off in production.
|
|
1204
|
+
Independent of ``observability_enabled`` (which
|
|
1205
|
+
controls structured events, not stdout).
|
|
1206
|
+
bind_tools_natively: When True (3.1), the AgentType parser
|
|
1207
|
+
is bypassed and your tools are bound directly as
|
|
1208
|
+
native function-calling tools. The framework
|
|
1209
|
+
auto-registers a synthetic ``respond`` tool the model
|
|
1210
|
+
calls to end the loop. Multiple ``tool_use`` blocks
|
|
1211
|
+
per turn are dispatched concurrently on a bounded
|
|
1212
|
+
``ThreadPoolExecutor``. Best latency for multi-tool
|
|
1213
|
+
turns. Mutually exclusive with
|
|
1214
|
+
``use_function_calling``. Uses a minimal system
|
|
1215
|
+
prompt (not the AgentType template) so the parser
|
|
1216
|
+
scaffolding doesn't fight the native interface.
|
|
1217
|
+
parallel_tool_workers: Max concurrent dispatches per turn
|
|
1218
|
+
when ``bind_tools_natively=True``. Default 8. Actual
|
|
1219
|
+
worker count is ``min(this, number_of_tool_calls)``.
|
|
1220
|
+
Ignored when native binding is off. Only affects
|
|
1221
|
+
per-turn parallelism -- separate calls to
|
|
1222
|
+
``runner.invoke`` remain sequential.
|
|
1223
|
+
agent: Lowercase PEP-8 alias for ``Agent``. Prefer this
|
|
1224
|
+
spelling in new code.
|
|
1225
|
+
permissions: A ``Permissions`` instance. When supplied,
|
|
1226
|
+
the framework calls ``DefaultTools.build(permissions)``
|
|
1227
|
+
and merges the resulting tools into ``tools=``. This
|
|
1228
|
+
is how you enable the sandboxed filesystem tools
|
|
1229
|
+
(``read_path`` / ``write_file`` / ``run_python``
|
|
1230
|
+
etc.) -- denied capabilities aren't registered, so
|
|
1231
|
+
the LLM literally cannot call them. Also injects a
|
|
1232
|
+
filesystem-sandbox description into the system
|
|
1233
|
+
prompt automatically. Name collisions with
|
|
1234
|
+
``tools=`` raise ``TypeError`` at construction.
|
|
1235
|
+
include_denied_tools: When True, denied capabilities
|
|
1236
|
+
surface as no-op tools that return an error message
|
|
1237
|
+
("this capability is disabled"). Useful for testing
|
|
1238
|
+
model behavior against a wider tool surface. Default
|
|
1239
|
+
False -- denied tools don't exist to the model.
|
|
1240
|
+
system_addendum: A role-specific instruction block
|
|
1241
|
+
appended to the AgentType template's system prompt.
|
|
1242
|
+
Use to encode a specialist contract
|
|
1243
|
+
(e.g. "you MUST call ``write_file`` at the end;
|
|
1244
|
+
never just describe the content"). When
|
|
1245
|
+
``permissions=`` is also set, the auto-generated
|
|
1246
|
+
sandbox hint is prepended so the role text can
|
|
1247
|
+
reference paths. Set this to a lightweight cache
|
|
1248
|
+
miss beat -- Anthropic prompt caching kicks in when
|
|
1249
|
+
the addendum stays stable across calls.
|
|
1250
|
+
strict_tool_dispatch: When True, an unknown ``action``
|
|
1251
|
+
that looks like a tool identifier feeds an error
|
|
1252
|
+
observation back into the loop
|
|
1253
|
+
("that tool doesn't exist; use one of X or
|
|
1254
|
+
Final_Answer") so the model can retry. Default
|
|
1255
|
+
False, which routes unknown actions to
|
|
1256
|
+
implicit-final. Turn on for models prone to
|
|
1257
|
+
misnaming tools (gpt-4o-mini).
|
|
1258
|
+
|
|
1259
|
+
Raises:
|
|
1260
|
+
TypeError: If both ``Agent`` and ``agent`` are passed, if
|
|
1261
|
+
``Agent``/``agent`` is missing, if any item in
|
|
1262
|
+
``tools`` is not a supported tool subclass, or if
|
|
1263
|
+
``permissions`` isn't a ``Permissions`` instance.
|
|
1264
|
+
ValueError: If ``use_function_calling`` and
|
|
1265
|
+
``bind_tools_natively`` are both True (mutually
|
|
1266
|
+
exclusive modes).
|
|
1267
|
+
"""
|
|
1131
1268
|
# PEP 8 alias: prefer lowercase `agent=`. Either argument works; passing
|
|
1132
1269
|
# both raises so misuse is loud rather than silently ambiguous.
|
|
1133
1270
|
if Agent is not None and agent is not None:
|
|
@@ -1173,23 +1310,7 @@ class AgentRunner:
|
|
|
1173
1310
|
)
|
|
1174
1311
|
tools = list(default_tools) + list(tools)
|
|
1175
1312
|
auto_sandbox_hint = _build_sandbox_hint(permissions)
|
|
1176
|
-
"""
|
|
1177
|
-
Initializes the AgentRunner.
|
|
1178
|
-
|
|
1179
|
-
Args:
|
|
1180
|
-
model (BaseChatModel): The LLM model.
|
|
1181
|
-
Agent: The agent's prompt template (string, AgentFormattor, or AgentPrompt).
|
|
1182
|
-
tools (List): A list of tool instances available to the agent.
|
|
1183
|
-
max_iterations (Optional[int]): Maximum tool-calling cycles.
|
|
1184
|
-
auto_cache (bool): Enable automatic tool result caching (default: True).
|
|
1185
|
-
auto_memory (bool): Enable automatic memory management (default: False).
|
|
1186
|
-
use_function_calling (bool): Route the AgentType parser through the
|
|
1187
|
-
model's native tool-calling API. Requires the chat model to
|
|
1188
|
-
implement ``call_with_tools`` (GPT and Claude do).
|
|
1189
1313
|
|
|
1190
|
-
Raises:
|
|
1191
|
-
TypeError: If any item in ``tools`` is not a StandardTool/StructuredTool.
|
|
1192
|
-
"""
|
|
1193
1314
|
self.Query = ""
|
|
1194
1315
|
self.Agent = Agent
|
|
1195
1316
|
self.tools = tools
|
|
@@ -66,9 +66,27 @@ def _read_action_input(parser_instance: BaseModel):
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
class AsyncAgentRunner:
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
"""Async agent runner. Same reason-act loop as :class:`AgentRunner`
|
|
70
|
+
but every I/O path is awaitable.
|
|
71
|
+
|
|
72
|
+
Typical use::
|
|
73
|
+
|
|
74
|
+
import asyncio
|
|
75
|
+
from agentx_dev import AsyncAgentRunner, AgentType, Claude
|
|
76
|
+
|
|
77
|
+
runner = AsyncAgentRunner(
|
|
78
|
+
model=Claude(),
|
|
79
|
+
agent=AgentType.ReAct,
|
|
80
|
+
tools=[my_async_tool],
|
|
81
|
+
)
|
|
82
|
+
result = asyncio.run(runner.ainvoke("..."))
|
|
83
|
+
|
|
84
|
+
Accepts a mix of sync and async tools transparently. When at least
|
|
85
|
+
one async tool is registered, a ``batch_concurrent`` meta-tool is
|
|
86
|
+
auto-added so the LLM can dispatch several async calls in one turn
|
|
87
|
+
via ``asyncio.gather``. Combine with ``bind_tools_natively=True``
|
|
88
|
+
for the modern "parallel tool calls per turn" pattern where every
|
|
89
|
+
tool_use block in one assistant response is dispatched concurrently.
|
|
72
90
|
"""
|
|
73
91
|
|
|
74
92
|
def __init__(
|
|
@@ -88,6 +106,53 @@ class AsyncAgentRunner:
|
|
|
88
106
|
include_denied_tools: bool = False,
|
|
89
107
|
strict_tool_dispatch: bool = False,
|
|
90
108
|
):
|
|
109
|
+
"""Construct an ``AsyncAgentRunner``. Parameters mirror
|
|
110
|
+
:class:`AgentRunner` -- see that docstring for the full details;
|
|
111
|
+
the differences are noted here.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
model: A ``BaseChatModel`` subclass. Both providers ship
|
|
115
|
+
sync + async paths, so ``Claude()`` and ``GPT()``
|
|
116
|
+
work here without changes.
|
|
117
|
+
Agent: The prompt template + parser pair. Same accepted
|
|
118
|
+
shapes as ``AgentRunner`` (``AgentType`` member,
|
|
119
|
+
custom ``AgentFormatter``, or raw string).
|
|
120
|
+
tools: Any mix of ``StandardTool`` / ``StructuredTool``
|
|
121
|
+
(sync) and ``AsyncStandardTool`` /
|
|
122
|
+
``AsyncStructuredTool`` (async). Async tools use
|
|
123
|
+
``asyncio.wait_for`` for cancellable timeouts; sync
|
|
124
|
+
tools run on the thread pool. When at least one async
|
|
125
|
+
tool is present, ``batch_concurrent`` is auto-added
|
|
126
|
+
so the LLM can batch calls via ``asyncio.gather``.
|
|
127
|
+
max_iterations: Loop cap per ``ainvoke``. Default 4.
|
|
128
|
+
auto_cache: Same as ``AgentRunner``: cache tool results
|
|
129
|
+
by ``(name, args)``. Default True.
|
|
130
|
+
auto_memory: Same as ``AgentRunner``. Default False.
|
|
131
|
+
use_function_calling: Route the AgentType parser through
|
|
132
|
+
native ``async_call_with_tools``. Mutually exclusive
|
|
133
|
+
with ``bind_tools_natively``.
|
|
134
|
+
verbose: Print step trace to stdout during ``ainvoke``.
|
|
135
|
+
bind_tools_natively: Bind user tools directly as native
|
|
136
|
+
FC tools; skip the AgentType parser. Multiple
|
|
137
|
+
``tool_use`` blocks per turn dispatch concurrently
|
|
138
|
+
via ``asyncio.gather`` (no thread pool needed because
|
|
139
|
+
async tools are cancellable natively).
|
|
140
|
+
agent: PEP-8 lowercase alias for ``Agent``.
|
|
141
|
+
permissions: A ``Permissions`` instance -- auto-registers
|
|
142
|
+
the sandboxed ``DefaultTools`` and injects the
|
|
143
|
+
filesystem hint into the system prompt.
|
|
144
|
+
include_denied_tools: Surface denied capabilities as no-op
|
|
145
|
+
tools. Default False.
|
|
146
|
+
strict_tool_dispatch: Feed unknown-tool errors back into
|
|
147
|
+
the loop so the model can retry with a valid name.
|
|
148
|
+
Default False.
|
|
149
|
+
|
|
150
|
+
Raises:
|
|
151
|
+
TypeError: On missing / duplicate ``Agent``/``agent`` or
|
|
152
|
+
on a bad ``permissions`` type.
|
|
153
|
+
ValueError: On the mutually-exclusive combination of
|
|
154
|
+
``use_function_calling`` and ``bind_tools_natively``.
|
|
155
|
+
"""
|
|
91
156
|
if Agent is not None and agent is not None:
|
|
92
157
|
raise TypeError("AsyncAgentRunner received both 'Agent' and 'agent'; pass only one.")
|
|
93
158
|
if agent is not None:
|
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
This module
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
Tool primitives + one-stop tools namespace for `agentx_dev`.
|
|
3
|
+
|
|
4
|
+
This module ships two things:
|
|
5
|
+
|
|
6
|
+
1. The `StandardTool` and `StructuredTool` wrappers that adapt a
|
|
7
|
+
Python callable into something an LLM can call, with Pydantic-
|
|
8
|
+
validated arguments for the structured variant.
|
|
9
|
+
2. A curated re-export surface (see the section at the bottom) so
|
|
10
|
+
users can import any built-in tool from a single namespace:
|
|
11
|
+
|
|
12
|
+
from agentx_dev.Tools import (
|
|
13
|
+
StandardTool, StructuredTool,
|
|
14
|
+
AsyncStandardTool, AsyncStructuredTool,
|
|
15
|
+
web_search_tool, web_fetch_tool,
|
|
16
|
+
vector_search_tool, handoff_tool,
|
|
17
|
+
DefaultTools, Permissions,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
The tool wrappers are the foundation of the framework's function-
|
|
21
|
+
calling story -- every dispatched call, whether it's a filesystem
|
|
22
|
+
tool, a RAG search, or a user-supplied Slack notifier, flows through
|
|
23
|
+
these two classes.
|
|
8
24
|
"""
|
|
9
25
|
|
|
10
26
|
from typing import Dict, Callable, List, Type
|
|
@@ -168,12 +184,13 @@ from typing import List, Dict, Any
|
|
|
168
184
|
|
|
169
185
|
|
|
170
186
|
# ---------------------------------------------------------------------------
|
|
171
|
-
# Convenience re-exports so `agentx_dev.Tools` is a one-stop namespace
|
|
187
|
+
# Convenience re-exports so `agentx_dev.Tools` is a one-stop namespace.
|
|
172
188
|
#
|
|
173
189
|
# Users can now import any tool from this module:
|
|
174
190
|
#
|
|
175
191
|
# from agentx_dev.Tools import (
|
|
176
192
|
# StandardTool, StructuredTool, # wrappers (defined above)
|
|
193
|
+
# AsyncStandardTool, AsyncStructuredTool,# async wrappers
|
|
177
194
|
# web_search_tool, web_fetch_tool, # web
|
|
178
195
|
# vector_search_tool, # RAG
|
|
179
196
|
# handoff_tool, # multi-agent
|
|
@@ -182,43 +199,45 @@ from typing import List, Dict, Any
|
|
|
182
199
|
#
|
|
183
200
|
# The top-level imports (from agentx_dev import ...) still work; this is
|
|
184
201
|
# purely additive so callers who prefer the namespaced form get it too.
|
|
185
|
-
#
|
|
186
|
-
#
|
|
202
|
+
#
|
|
203
|
+
# Design note: previously this used a PEP 562 __getattr__ for lazy
|
|
204
|
+
# loading. That saved microseconds at import time but broke IDE
|
|
205
|
+
# autocomplete + syntax highlighting -- static analyzers can't see
|
|
206
|
+
# names that only exist inside a __getattr__ fallback. Since
|
|
207
|
+
# `agentx_dev/__init__.py` already eager-loads all these modules at
|
|
208
|
+
# top-level import anyway, the lazy-load was a false economy.
|
|
209
|
+
# Eager imports here just re-export symbols that are already in memory.
|
|
187
210
|
# ---------------------------------------------------------------------------
|
|
188
211
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
212
|
+
# Web
|
|
213
|
+
from agentx_dev.WebTools import web_search_tool, web_fetch_tool
|
|
214
|
+
|
|
215
|
+
# RAG
|
|
216
|
+
from agentx_dev.Embeddings import vector_search_tool
|
|
217
|
+
|
|
218
|
+
# Multi-agent handoffs
|
|
219
|
+
from agentx_dev.Handoffs import handoff_tool
|
|
220
|
+
|
|
221
|
+
# Async tool wrappers (siblings to Standard/Structured)
|
|
222
|
+
from agentx_dev.AsyncTools import AsyncStandardTool, AsyncStructuredTool
|
|
223
|
+
|
|
224
|
+
# Filesystem / permissions
|
|
225
|
+
from agentx_dev.DefaultTools import DefaultTools, Permissions
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
__all__ = [
|
|
229
|
+
# Wrappers defined in this module
|
|
230
|
+
"StandardTool", "StructuredTool",
|
|
231
|
+
"AsyncStandardTool", "AsyncStructuredTool",
|
|
232
|
+
# Web
|
|
233
|
+
"web_search_tool", "web_fetch_tool",
|
|
193
234
|
# RAG
|
|
194
|
-
"vector_search_tool"
|
|
195
|
-
# Multi-agent
|
|
196
|
-
"handoff_tool"
|
|
197
|
-
#
|
|
198
|
-
"
|
|
199
|
-
|
|
200
|
-
# Filesystem / permissions
|
|
201
|
-
"DefaultTools": ("agentx_dev.DefaultTools", "DefaultTools"),
|
|
202
|
-
"Permissions": ("agentx_dev.DefaultTools", "Permissions"),
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
def __getattr__(name):
|
|
207
|
-
"""PEP 562 module __getattr__: lazy-load re-exports on first access."""
|
|
208
|
-
if name in _TOOL_EXPORTS:
|
|
209
|
-
import importlib
|
|
210
|
-
mod_name, attr_name = _TOOL_EXPORTS[name]
|
|
211
|
-
mod = importlib.import_module(mod_name)
|
|
212
|
-
obj = getattr(mod, attr_name)
|
|
213
|
-
# Cache on the module so subsequent lookups skip the importlib call.
|
|
214
|
-
globals()[name] = obj
|
|
215
|
-
return obj
|
|
216
|
-
raise AttributeError(f"module 'agentx_dev.Tools' has no attribute {name!r}")
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
def __dir__():
|
|
220
|
-
"""Expose the re-exports to `dir(agentx_dev.Tools)` and IDE autocomplete."""
|
|
221
|
-
return sorted(list(globals().keys()) + list(_TOOL_EXPORTS.keys()))
|
|
235
|
+
"vector_search_tool",
|
|
236
|
+
# Multi-agent
|
|
237
|
+
"handoff_tool",
|
|
238
|
+
# Sandbox
|
|
239
|
+
"DefaultTools", "Permissions",
|
|
240
|
+
]
|
|
222
241
|
|
|
223
242
|
|
|
224
243
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentx-dev
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.3
|
|
4
4
|
Summary: A production-grade Python framework for building LLM agents. Multi-provider chat, permission-gated tools, RAG (in-mem + Chroma/Qdrant/pgvector), semantic memory, Supervisor + Handoffs multi-agent orchestration with streaming, evals harness, prompt caching, Batch API, prompt-optimizer, MCP integration.
|
|
5
5
|
Author-email: Bruce-Arhin Shadrach <brucearhin098@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
|
|
3
3
|
name = "agentx-dev"
|
|
4
|
-
version = "3.1.
|
|
4
|
+
version = "3.1.3"
|
|
5
5
|
description = "A production-grade Python framework for building LLM agents. Multi-provider chat, permission-gated tools, RAG (in-mem + Chroma/Qdrant/pgvector), semantic memory, Supervisor + Handoffs multi-agent orchestration with streaming, evals harness, prompt caching, Batch API, prompt-optimizer, MCP integration."
|
|
6
6
|
authors = [{ name = "Bruce-Arhin Shadrach", email = "brucearhin098@gmail.com" }]
|
|
7
7
|
# Best practice: link to the license file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|