agentx-dev 3.1.5__tar.gz → 3.2.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_dev-3.1.5 → agentx_dev-3.2.0}/CHANGELOG.md +181 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/CONTRIBUTING.md +105 -105
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/PKG-INFO +7 -7
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/README.md +3 -3
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/DefaultTools.py +2026 -1978
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Embeddings.py +35 -3
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Runner/AgentRun.py +346 -22
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Runner/AsyncAgentRun.py +121 -8
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Supervisor.py +41 -6
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/VectorStores/qdrant_store.py +239 -198
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/WebTools.py +501 -360
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev.egg-info/PKG-INFO +7 -7
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev.egg-info/SOURCES.txt +2 -2
- agentx_dev-3.2.0/agentx_dev.egg-info/top_level.txt +3 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/README.md +35 -2
- agentx_dev-3.2.0/examples/mcp_github_triage_demo.py +248 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/supervisor_example.py +6 -6
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/pyproject.toml +4 -4
- agentx_dev-3.1.5/agentx_dev.egg-info/top_level.txt +0 -14
- agentx_dev-3.1.5/host/build_data.py +0 -129
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/AGENTX.md +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/LICENSE +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/MANIFEST.in +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Agents/Agent.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Agents/__init__.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/AsyncTools.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/AutoSetup.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Cache.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/ChatModel.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Compiler.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Config.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Evals.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Handoffs.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Loader.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/MCP.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Memory.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Observability.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Planner.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Runner/__init__.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Runner/promptTemplate.yaml +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Session.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Splitters.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Streaming.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/Tools.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/VectorStores/__init__.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/VectorStores/chroma_store.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/VectorStores/pg_store.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/__init__.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/resources/__init__.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev/resources/promptTemplate.yaml +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev.egg-info/dependency_links.txt +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/agentx_dev.egg-info/requires.txt +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/agentic_rag_demo.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/async_example.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/async_quickstart.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/auto_features_example.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/caching_example.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/chatbot_example.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/complete_example.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/concurrent_example.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/concurrent_tool_example.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/file_agent_demo.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/function_calling_demo.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/mcp_demo.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/observability_example.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/orchestration_demo.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/planner_example.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/robust_link_scraper.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/supervisor_codebase_analysis_demo.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/sync_quickstart.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/v3_1_1_features_demo.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/v3_1_comprehensive_demo.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/examples/v3_1_features_demo.py +0 -0
- {agentx_dev-3.1.5 → agentx_dev-3.2.0}/setup.cfg +0 -0
|
@@ -4,6 +4,187 @@ All notable changes to `agentx-dev` are documented here. Format loosely
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/); versioning is
|
|
5
5
|
[Semver](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [3.2.0] - 2026-08-13
|
|
8
|
+
|
|
9
|
+
Typed multi-agent pipelines. Specialists can now declare a Pydantic
|
|
10
|
+
output schema once and pass validated instances to each other through
|
|
11
|
+
the Supervisor, instead of downstream agents re-parsing prose.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`output_schema` on the `AgentRunner` / `AsyncAgentRunner`
|
|
16
|
+
constructor.** Declare the runner's output shape once
|
|
17
|
+
(`AgentRunner(..., output_schema=QueryIntent)`) instead of passing it
|
|
18
|
+
on every call or describing JSON in the prompt. A per-call
|
|
19
|
+
`output_schema=` still wins when both are set. `None` keeps the exact
|
|
20
|
+
pre-3.2 behaviour: no coercion, `completion.output` stays `None`.
|
|
21
|
+
|
|
22
|
+
- **Schema coercion via forced native function calling.** When a schema
|
|
23
|
+
is in play, the final answer is converted by forcing a provider-native
|
|
24
|
+
tool call against the schema (constrained decoding), not by regexing
|
|
25
|
+
JSON out of prose. The ReAct loop itself is untouched: tool selection
|
|
26
|
+
and intermediate reasoning run exactly as before, and the coercion
|
|
27
|
+
happens once, after the loop finishes. Models without a
|
|
28
|
+
`call_with_tools` implementation fall back to the previous text-JSON
|
|
29
|
+
parsing, so custom `BaseChatModel` subclasses keep working.
|
|
30
|
+
`completion.content` keeps the human-readable answer alongside
|
|
31
|
+
`completion.output` in every case.
|
|
32
|
+
|
|
33
|
+
- **`SubtaskResult.output`.** The Supervisor now preserves each
|
|
34
|
+
specialist's validated Pydantic instance next to its `content` text.
|
|
35
|
+
Consumers that only read `content` are unaffected.
|
|
36
|
+
|
|
37
|
+
- **Structured specialist-to-specialist handoff.** When an earlier step
|
|
38
|
+
produced typed output, `_build_augmented_query` serializes it into the
|
|
39
|
+
next specialist's context as a labelled JSON block
|
|
40
|
+
(`STRUCTURED OUTPUT (QueryIntent): {...}`) followed by the summary
|
|
41
|
+
text, so downstream steps parse fields rather than interpreting
|
|
42
|
+
sentences like `INTENT: ... SEARCH_QUERY: ...`.
|
|
43
|
+
|
|
44
|
+
- **`vector_search_tool` pipeline options.** New kwargs:
|
|
45
|
+
`max_text_chars` (default 500; pass `0` for full untruncated passages,
|
|
46
|
+
which a reranker judging evidence actually needs) and
|
|
47
|
+
`structured_output` (default False; when True the tool returns a JSON
|
|
48
|
+
array of `{id, text, vector_score, metadata}` instead of the
|
|
49
|
+
human-formatted list). Defaults preserve existing behaviour byte-for-
|
|
50
|
+
byte.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- **Supervisor planning prompt contradicted the execution engine.** The
|
|
55
|
+
planner rule said sub-agents "do NOT see previous steps' output" and
|
|
56
|
+
discouraged dependency chains, but the dispatcher has threaded prior
|
|
57
|
+
findings into every step since `_build_augmented_query` shipped.
|
|
58
|
+
The rule now tells the planner that sequential steps receive earlier
|
|
59
|
+
results (structured when available) and that chains like
|
|
60
|
+
intent -> retrieval -> reranking are a good plan shape, while still
|
|
61
|
+
requiring same-specialist steps to merge and banning report-only steps.
|
|
62
|
+
|
|
63
|
+
## [3.1.7] — 2026-07-27
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- **`use_function_calling` default flipped to auto-detect** on
|
|
68
|
+
`AgentRunner` / `AsyncAgentRunner`. The parameter's default type is
|
|
69
|
+
now `Optional[bool] = None`; `None` resolves to `True` when the
|
|
70
|
+
model class overrides `BaseChatModel.call_with_tools` (both `GPT`
|
|
71
|
+
and `Claude` do) and to `False` when it doesn't (or when
|
|
72
|
+
`bind_tools_natively=True`). Callers passing `True`/`False`
|
|
73
|
+
explicitly are unaffected. Rationale: text-mode ReAct requires the
|
|
74
|
+
model to emit strict JSON with any long `action_input` string
|
|
75
|
+
properly escaped — a 1200-word markdown draft with unescaped
|
|
76
|
+
newlines or quotes reliably breaks `json.loads` and killed the run.
|
|
77
|
+
Function-calling mode routes the parser through the SDK's typed
|
|
78
|
+
channel so escaping is handled automatically. The historical
|
|
79
|
+
default (`False`) was the fragile option; the new default matches
|
|
80
|
+
what most users actually want.
|
|
81
|
+
|
|
82
|
+
### Fixed
|
|
83
|
+
|
|
84
|
+
- **Malformed parser JSON no longer crashes the run.** When the
|
|
85
|
+
text-mode assistant response failed `json.loads` (typically because
|
|
86
|
+
a long `action_input` string had unescaped `"`, `\n`, or backticks),
|
|
87
|
+
the framework used to raise `JSONDecodeError` and unwind the whole
|
|
88
|
+
invocation. The runner now (1) tries a regex-based salvage that
|
|
89
|
+
extracts `{Thought, action, action_input}` from the raw text
|
|
90
|
+
covering the common "outer envelope valid, inner string broke
|
|
91
|
+
escaping" failure, and (2) if salvage fails, feeds a targeted fix
|
|
92
|
+
hint back to the model (`"your last response was not valid JSON;
|
|
93
|
+
emit …, escape newlines as \n"`) and continues the loop bounded
|
|
94
|
+
by `max_iterations`. Exhaustion returns a clear framework message
|
|
95
|
+
rather than an uncaught exception. Applied to both sync and async
|
|
96
|
+
runners via a shared `_salvage_react_json` helper.
|
|
97
|
+
The salvager's action-name regex is intentionally strict
|
|
98
|
+
(`[A-Za-z_][A-Za-z0-9_.\- ]{0,79}`) so it can't hallucinate an
|
|
99
|
+
"action" out of an unrelated `"key":"value"` pair inside malformed
|
|
100
|
+
JSON.
|
|
101
|
+
|
|
102
|
+
- **Verbose trace in `bind_tools_natively` mode now prints tool
|
|
103
|
+
name + args + response.** Previously native runs showed blank
|
|
104
|
+
`[tool.call.start]` / `[tool.call.complete]` pairs (the
|
|
105
|
+
observability layer fires them without the trace context), so you
|
|
106
|
+
couldn't tell which tool the model actually invoked or what came
|
|
107
|
+
back. The runner now prints `[tool] Invoking '<name>' with args:
|
|
108
|
+
<input>` and `[tool] Response: <preview>` (or `[tool] Error: ...`
|
|
109
|
+
when the dispatch raised) in the post-dispatch loop, matching the
|
|
110
|
+
format text-mode and function-calling mode use. Mirrored to the
|
|
111
|
+
async runner.
|
|
112
|
+
|
|
113
|
+
- **`web_fetch_tool(vector_store=...)` auto-ingests fetched pages into
|
|
114
|
+
a vector store** instead of dumping raw HTML into the model's
|
|
115
|
+
context. Fixes the TPM-limit trap: when a research agent fetches
|
|
116
|
+
four articles in parallel (via ``multi_tool_use.parallel`` or
|
|
117
|
+
native binding), the combined bodies can easily exceed 40k tokens
|
|
118
|
+
and blow past a 30k TPM ceiling on the very next model call.
|
|
119
|
+
New parameters on ``web_fetch_tool``:
|
|
120
|
+
|
|
121
|
+
| Kwarg | Default | Effect |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| ``vector_store`` | ``None`` | When set, each fetch is HTML-stripped, chunked with ``TextSplitter``, embedded via the store's embeddings, and added with ``{src: url, chunk_index, total_chunks}`` metadata. The tool response becomes a compact summary (URL, byte count, chunk count, 240-char preview) — NOT the raw body. The model then calls ``vector_search`` / ``Rag`` to pull only the passages it needs. |
|
|
124
|
+
| ``chunk_size`` | ``1500`` | Characters per chunk when ``vector_store`` is set. Ignored otherwise. |
|
|
125
|
+
| ``chunk_overlap`` | ``200`` | Overlap between adjacent chunks so a fact spanning a boundary is still retrievable. Ignored otherwise. |
|
|
126
|
+
|
|
127
|
+
Backwards-compatible: the positional ``cache_dir`` signature keeps
|
|
128
|
+
working; `web_fetch_tool()` with no ``vector_store`` returns raw
|
|
129
|
+
body as before. Ingest and cache_dir compose — enable both and get
|
|
130
|
+
disk-cached full bodies AND searchable chunks. HTML stripping is
|
|
131
|
+
minimal and dependency-free (regex-based: script/style blocks
|
|
132
|
+
dropped whole, then tags stripped, whitespace collapsed) so the
|
|
133
|
+
ingest path adds no new install dependency. On JSON/plain-text
|
|
134
|
+
responses the stripper is a near no-op.
|
|
135
|
+
|
|
136
|
+
The observation returned to the model shows topical coverage --
|
|
137
|
+
first, middle, and last chunk previews (up to 3 samples,
|
|
138
|
+
deduplicated for short pages) -- so the model can tell what
|
|
139
|
+
topics the page actually covers, not just the intro paragraph.
|
|
140
|
+
Without this the model would only see the page's opening and
|
|
141
|
+
wouldn't know to query for topics discussed later in the same
|
|
142
|
+
page. Explicit instruction in the observation ("query with
|
|
143
|
+
SPECIFIC keywords from the topics above; do NOT re-fetch; do
|
|
144
|
+
NOT ask for the full body") steers the model toward the RAG path
|
|
145
|
+
on follow-up turns.
|
|
146
|
+
|
|
147
|
+
- **`multi_tool_use.parallel` now reaches its dispatch path.**
|
|
148
|
+
When GPT wanted to batch several tool calls into one turn (fetch N
|
|
149
|
+
URLs concurrently, run M searches at once), it emitted OpenAI's
|
|
150
|
+
synthetic `multi_tool_use.parallel` meta-tool. The registry's
|
|
151
|
+
`_dispatch_multi_parallel` / `_adispatch_multi_parallel` handlers
|
|
152
|
+
already knew how to unpack it, but the runner loop's known-tools
|
|
153
|
+
guardrail rejected the name FIRST as unregistered — dumping the
|
|
154
|
+
raw `{"tool_uses": [...]}` payload into the user-facing "final
|
|
155
|
+
answer" and never invoking any of the nested calls. Added
|
|
156
|
+
`multi_tool_use.parallel` to the recognized action set in both
|
|
157
|
+
sync and async runners so the meta-tool flows through to dispatch
|
|
158
|
+
and the existing unpackers run. Nested calls with the `functions.`
|
|
159
|
+
prefix are normalized before dispatch (same as top-level FC
|
|
160
|
+
calls), so the model can emit either shape.
|
|
161
|
+
|
|
162
|
+
- **`Permissions.full_access` / `read_only` auto-wrap a bare string.**
|
|
163
|
+
Passing `full_access("./workspace")` used to iterate the string
|
|
164
|
+
into 11 single-character "subtrees" (Python's `list("./workspace")`)
|
|
165
|
+
— every path check silently rejected because no real path could
|
|
166
|
+
ever match a `"."` or `"/"` "allowed subtree". The classmethod
|
|
167
|
+
now detects a bare string and treats it as `[allowed_paths]`, so
|
|
168
|
+
`full_access("./workspace")` does the intuitive thing (equivalent
|
|
169
|
+
to `full_access(["./workspace"])` and auto-infers the workspace).
|
|
170
|
+
Same fix on `read_only`. List inputs are unchanged.
|
|
171
|
+
|
|
172
|
+
- **`Permissions.full_access` now accepts (and auto-infers)
|
|
173
|
+
`workspace`.** The classmethod set `allowed_paths` but not
|
|
174
|
+
`workspace`, so short paths like `write_file(path="report.md")`
|
|
175
|
+
resolved to CWD (outside the sandbox) and raised
|
|
176
|
+
`PermissionError: access denied` — a landmine that every caller of
|
|
177
|
+
`Permissions.full_access(["./workspace"])` hit sooner or later.
|
|
178
|
+
New signature: `full_access(allowed_paths, *, workspace=None)`.
|
|
179
|
+
When `workspace` isn't passed AND `allowed_paths` has exactly one
|
|
180
|
+
entry, that path is auto-set as the workspace (the "project-scoped
|
|
181
|
+
agent whose one allowed subtree IS its workspace" case, which is
|
|
182
|
+
99% of use). Two or more paths stay ambiguous and require an
|
|
183
|
+
explicit `workspace=` if short-path resolution is wanted. Pass an
|
|
184
|
+
explicit `workspace=` string to override the auto-choice.
|
|
185
|
+
Backwards-compatible on the positional signature; adds a keyword
|
|
186
|
+
argument that existing callers didn't use.
|
|
187
|
+
|
|
7
188
|
## [3.1.5] — 2026-07-26
|
|
8
189
|
|
|
9
190
|
### Fixed
|
|
@@ -1,105 +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/
|
|
11
|
-
cd
|
|
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
|
+
# 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/agentx_dev.git
|
|
11
|
+
cd agentx_dev
|
|
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.
|
|
3
|
+
Version: 3.2.0
|
|
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
|
|
@@ -25,9 +25,9 @@ License: MIT License
|
|
|
25
25
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
26
|
SOFTWARE.
|
|
27
27
|
|
|
28
|
-
Project-URL: Homepage, https://github.com/shadrach098/
|
|
29
|
-
Project-URL: Bug Tracker, https://github.com/shadrach098/
|
|
30
|
-
Project-URL: Source, https://github.com/shadrach098/
|
|
28
|
+
Project-URL: Homepage, https://github.com/shadrach098/agentx_dev
|
|
29
|
+
Project-URL: Bug Tracker, https://github.com/shadrach098/agentx_dev/issues
|
|
30
|
+
Project-URL: Source, https://github.com/shadrach098/agentx_dev
|
|
31
31
|
Requires-Python: >=3.10
|
|
32
32
|
Description-Content-Type: text/markdown
|
|
33
33
|
License-File: LICENSE
|
|
@@ -479,7 +479,7 @@ project with **deny-all** defaults:
|
|
|
479
479
|
```json
|
|
480
480
|
{
|
|
481
481
|
"_comment": "Edit this file to control which capabilities the agent has...",
|
|
482
|
-
"_docs": "https://github.com/shadrach098/
|
|
482
|
+
"_docs": "https://github.com/shadrach098/agentx_dev",
|
|
483
483
|
"read_files": false,
|
|
484
484
|
"list_directories": false,
|
|
485
485
|
"write_files": false,
|
|
@@ -1123,5 +1123,5 @@ print(f"Spent: ${llm.usage.estimate_cost(0.003, 0.015):.4f}")
|
|
|
1123
1123
|
|
|
1124
1124
|
## Links
|
|
1125
1125
|
|
|
1126
|
-
- Repo: https://github.com/shadrach098/
|
|
1127
|
-
- Issues: https://github.com/shadrach098/
|
|
1126
|
+
- Repo: https://github.com/shadrach098/agentx_dev
|
|
1127
|
+
- Issues: https://github.com/shadrach098/agentx_dev/issues
|
|
@@ -415,7 +415,7 @@ project with **deny-all** defaults:
|
|
|
415
415
|
```json
|
|
416
416
|
{
|
|
417
417
|
"_comment": "Edit this file to control which capabilities the agent has...",
|
|
418
|
-
"_docs": "https://github.com/shadrach098/
|
|
418
|
+
"_docs": "https://github.com/shadrach098/agentx_dev",
|
|
419
419
|
"read_files": false,
|
|
420
420
|
"list_directories": false,
|
|
421
421
|
"write_files": false,
|
|
@@ -1059,5 +1059,5 @@ print(f"Spent: ${llm.usage.estimate_cost(0.003, 0.015):.4f}")
|
|
|
1059
1059
|
|
|
1060
1060
|
## Links
|
|
1061
1061
|
|
|
1062
|
-
- Repo: https://github.com/shadrach098/
|
|
1063
|
-
- Issues: https://github.com/shadrach098/
|
|
1062
|
+
- Repo: https://github.com/shadrach098/agentx_dev
|
|
1063
|
+
- Issues: https://github.com/shadrach098/agentx_dev/issues
|