agentx-dev 3.1.5__tar.gz → 3.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/CHANGELOG.md +249 -0
  2. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/CONTRIBUTING.md +105 -105
  3. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/PKG-INFO +7 -7
  4. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/README.md +3 -3
  5. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/DefaultTools.py +2026 -1978
  6. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Embeddings.py +35 -3
  7. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Runner/AgentRun.py +346 -22
  8. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Runner/AsyncAgentRun.py +121 -8
  9. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Supervisor.py +636 -63
  10. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/VectorStores/qdrant_store.py +239 -198
  11. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/WebTools.py +501 -360
  12. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/__init__.py +2 -1
  13. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev.egg-info/PKG-INFO +7 -7
  14. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev.egg-info/SOURCES.txt +2 -2
  15. agentx_dev-3.3.0/agentx_dev.egg-info/top_level.txt +3 -0
  16. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/README.md +35 -2
  17. agentx_dev-3.3.0/examples/mcp_github_triage_demo.py +248 -0
  18. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/supervisor_example.py +6 -6
  19. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/pyproject.toml +4 -4
  20. agentx_dev-3.1.5/agentx_dev.egg-info/top_level.txt +0 -14
  21. agentx_dev-3.1.5/host/build_data.py +0 -129
  22. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/AGENTX.md +0 -0
  23. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/LICENSE +0 -0
  24. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/MANIFEST.in +0 -0
  25. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Agents/Agent.py +0 -0
  26. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Agents/__init__.py +0 -0
  27. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/AsyncTools.py +0 -0
  28. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/AutoSetup.py +0 -0
  29. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Cache.py +0 -0
  30. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/ChatModel.py +0 -0
  31. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Compiler.py +0 -0
  32. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Config.py +0 -0
  33. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Evals.py +0 -0
  34. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Handoffs.py +0 -0
  35. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Loader.py +0 -0
  36. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/MCP.py +0 -0
  37. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Memory.py +0 -0
  38. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Observability.py +0 -0
  39. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Planner.py +0 -0
  40. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Runner/__init__.py +0 -0
  41. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Runner/promptTemplate.yaml +0 -0
  42. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Session.py +0 -0
  43. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Splitters.py +0 -0
  44. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Streaming.py +0 -0
  45. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/Tools.py +0 -0
  46. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/VectorStores/__init__.py +0 -0
  47. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/VectorStores/chroma_store.py +0 -0
  48. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/VectorStores/pg_store.py +0 -0
  49. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/resources/__init__.py +0 -0
  50. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev/resources/promptTemplate.yaml +0 -0
  51. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev.egg-info/dependency_links.txt +0 -0
  52. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/agentx_dev.egg-info/requires.txt +0 -0
  53. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/agentic_rag_demo.py +0 -0
  54. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/async_example.py +0 -0
  55. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/async_quickstart.py +0 -0
  56. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/auto_features_example.py +0 -0
  57. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/caching_example.py +0 -0
  58. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/chatbot_example.py +0 -0
  59. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/complete_example.py +0 -0
  60. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/concurrent_example.py +0 -0
  61. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/concurrent_tool_example.py +0 -0
  62. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/file_agent_demo.py +0 -0
  63. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/function_calling_demo.py +0 -0
  64. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/mcp_demo.py +0 -0
  65. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/observability_example.py +0 -0
  66. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/orchestration_demo.py +0 -0
  67. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/planner_example.py +0 -0
  68. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/robust_link_scraper.py +0 -0
  69. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/supervisor_codebase_analysis_demo.py +0 -0
  70. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/sync_quickstart.py +0 -0
  71. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/v3_1_1_features_demo.py +0 -0
  72. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/v3_1_comprehensive_demo.py +0 -0
  73. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/examples/v3_1_features_demo.py +0 -0
  74. {agentx_dev-3.1.5 → agentx_dev-3.3.0}/setup.cfg +0 -0
@@ -4,6 +4,255 @@ 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.3.0] - 2026-08-19
8
+
9
+ Dependency DAGs for the Supervisor. Plans declare which steps consume
10
+ which, and the executor derives ordering, parallelism, AND context
11
+ routing from those edges — unifying the old split where sequential
12
+ mode had threading but no parallelism and concurrent mode had
13
+ parallelism but no threading. Design: docs/design/3.3-depends-on-dag.md.
14
+
15
+ ### Added
16
+
17
+ - **`depends_on` plan steps.** Every plan step now carries an `id`;
18
+ a step that consumes an earlier step's output lists that id in
19
+ `depends_on`. Sync `Supervisor` executes in stable topological
20
+ order; `AsyncSupervisor` runs a completion-driven scheduler where a
21
+ step starts the MOMENT its dependencies finish (not on wave
22
+ barriers) and independent steps run concurrently. In DAG mode each
23
+ step is threaded ONLY its direct dependencies' results — explicit
24
+ routing instead of "everything prior", which also stops the
25
+ per-entry context budget shrinking as plans grow.
26
+
27
+ - **Plan sanitization that never fails a run.** Missing/duplicate ids
28
+ auto-assigned, unknown dependencies dropped (a planner typo degrades
29
+ to a root step, not a dead run), self-deps dropped, cycles broken
30
+ deterministically (back-edge in plan order), spawn steps cannot be
31
+ depended on. If repairs were needed, the plan is re-requested once
32
+ (`max_plan_retries`, default 1) with the repair warnings appended;
33
+ the sanitized original is kept when the retry is no better.
34
+
35
+ - **Failure cascade + `skipped` flag.** A step whose dependency failed
36
+ (after retries / success-check) is skipped, transitively, with
37
+ `SubtaskResult.skipped=True` and an error naming the failed dep.
38
+ Independent branches keep running; synthesis runs over what
39
+ succeeded. Skipped steps never dispatch — no tokens burned
40
+ downstream of garbage.
41
+
42
+ - **`skip_when` conditional execution.** A step may declare
43
+ `{"step": <direct dep id>, "field": <typed output field>, "is": <value>}`;
44
+ evaluated in Python (no LLM call) against the dependency's 3.2
45
+ structured output, dotted paths supported, strictly FAIL-OPEN (any
46
+ doubt → the step runs). Condition-skips do NOT cascade — dependents
47
+ treat them as empty successes ("retrieval unnecessary" is not
48
+ "answering impossible").
49
+
50
+ - **`Specialist` registry entries.** `agents={}` now also accepts
51
+ `Specialist(description, runner, depends_on=[...names...],
52
+ output_schema=..., when_to_use=...)`. The extras render into the
53
+ planning catalog (`typically after:` / `returns: Schema(fields)` /
54
+ `use when:`) so the planner can write real dependency graphs and
55
+ `skip_when` conditions against actual field names. `depends_on`
56
+ here is a planner HINT, never an execution constraint (the same
57
+ specialist can appear twice in one plan; step-ids disambiguate).
58
+ Classic `(description, runner)` tuples keep working — they are
59
+ wrapped internally, and `Specialist` tuple-unpacks for older code.
60
+
61
+ - **`AsyncSupervisor(max_parallel=N)`.** Caps concurrent sub-tasks for
62
+ rate-limited deployments. `sequential=True` is now sugar for
63
+ `max_parallel=1` with all-prior threading.
64
+
65
+ - **`SubtaskResult.step_id` / `.depends_on` / `.skipped`** and a
66
+ `step_id` field on `dispatch` / `subtask_result` stream events.
67
+
68
+ ### Backward compatibility
69
+
70
+ A plan where NO step declares `depends_on` runs with byte-identical
71
+ legacy semantics: sync + async-sequential thread all prior results in
72
+ plan order; async-concurrent runs everything at once with no
73
+ threading. Verified by regression tests against the 3.2 behaviour.
74
+
75
+ ## [3.2.0] - 2026-08-13
76
+
77
+ Typed multi-agent pipelines. Specialists can now declare a Pydantic
78
+ output schema once and pass validated instances to each other through
79
+ the Supervisor, instead of downstream agents re-parsing prose.
80
+
81
+ ### Added
82
+
83
+ - **`output_schema` on the `AgentRunner` / `AsyncAgentRunner`
84
+ constructor.** Declare the runner's output shape once
85
+ (`AgentRunner(..., output_schema=QueryIntent)`) instead of passing it
86
+ on every call or describing JSON in the prompt. A per-call
87
+ `output_schema=` still wins when both are set. `None` keeps the exact
88
+ pre-3.2 behaviour: no coercion, `completion.output` stays `None`.
89
+
90
+ - **Schema coercion via forced native function calling.** When a schema
91
+ is in play, the final answer is converted by forcing a provider-native
92
+ tool call against the schema (constrained decoding), not by regexing
93
+ JSON out of prose. The ReAct loop itself is untouched: tool selection
94
+ and intermediate reasoning run exactly as before, and the coercion
95
+ happens once, after the loop finishes. Models without a
96
+ `call_with_tools` implementation fall back to the previous text-JSON
97
+ parsing, so custom `BaseChatModel` subclasses keep working.
98
+ `completion.content` keeps the human-readable answer alongside
99
+ `completion.output` in every case.
100
+
101
+ - **`SubtaskResult.output`.** The Supervisor now preserves each
102
+ specialist's validated Pydantic instance next to its `content` text.
103
+ Consumers that only read `content` are unaffected.
104
+
105
+ - **Structured specialist-to-specialist handoff.** When an earlier step
106
+ produced typed output, `_build_augmented_query` serializes it into the
107
+ next specialist's context as a labelled JSON block
108
+ (`STRUCTURED OUTPUT (QueryIntent): {...}`) followed by the summary
109
+ text, so downstream steps parse fields rather than interpreting
110
+ sentences like `INTENT: ... SEARCH_QUERY: ...`.
111
+
112
+ - **`vector_search_tool` pipeline options.** New kwargs:
113
+ `max_text_chars` (default 500; pass `0` for full untruncated passages,
114
+ which a reranker judging evidence actually needs) and
115
+ `structured_output` (default False; when True the tool returns a JSON
116
+ array of `{id, text, vector_score, metadata}` instead of the
117
+ human-formatted list). Defaults preserve existing behaviour byte-for-
118
+ byte.
119
+
120
+ ### Fixed
121
+
122
+ - **Supervisor planning prompt contradicted the execution engine.** The
123
+ planner rule said sub-agents "do NOT see previous steps' output" and
124
+ discouraged dependency chains, but the dispatcher has threaded prior
125
+ findings into every step since `_build_augmented_query` shipped.
126
+ The rule now tells the planner that sequential steps receive earlier
127
+ results (structured when available) and that chains like
128
+ intent -> retrieval -> reranking are a good plan shape, while still
129
+ requiring same-specialist steps to merge and banning report-only steps.
130
+
131
+ ## [3.1.7] — 2026-07-27
132
+
133
+ ### Changed
134
+
135
+ - **`use_function_calling` default flipped to auto-detect** on
136
+ `AgentRunner` / `AsyncAgentRunner`. The parameter's default type is
137
+ now `Optional[bool] = None`; `None` resolves to `True` when the
138
+ model class overrides `BaseChatModel.call_with_tools` (both `GPT`
139
+ and `Claude` do) and to `False` when it doesn't (or when
140
+ `bind_tools_natively=True`). Callers passing `True`/`False`
141
+ explicitly are unaffected. Rationale: text-mode ReAct requires the
142
+ model to emit strict JSON with any long `action_input` string
143
+ properly escaped — a 1200-word markdown draft with unescaped
144
+ newlines or quotes reliably breaks `json.loads` and killed the run.
145
+ Function-calling mode routes the parser through the SDK's typed
146
+ channel so escaping is handled automatically. The historical
147
+ default (`False`) was the fragile option; the new default matches
148
+ what most users actually want.
149
+
150
+ ### Fixed
151
+
152
+ - **Malformed parser JSON no longer crashes the run.** When the
153
+ text-mode assistant response failed `json.loads` (typically because
154
+ a long `action_input` string had unescaped `"`, `\n`, or backticks),
155
+ the framework used to raise `JSONDecodeError` and unwind the whole
156
+ invocation. The runner now (1) tries a regex-based salvage that
157
+ extracts `{Thought, action, action_input}` from the raw text
158
+ covering the common "outer envelope valid, inner string broke
159
+ escaping" failure, and (2) if salvage fails, feeds a targeted fix
160
+ hint back to the model (`"your last response was not valid JSON;
161
+ emit …, escape newlines as \n"`) and continues the loop bounded
162
+ by `max_iterations`. Exhaustion returns a clear framework message
163
+ rather than an uncaught exception. Applied to both sync and async
164
+ runners via a shared `_salvage_react_json` helper.
165
+ The salvager's action-name regex is intentionally strict
166
+ (`[A-Za-z_][A-Za-z0-9_.\- ]{0,79}`) so it can't hallucinate an
167
+ "action" out of an unrelated `"key":"value"` pair inside malformed
168
+ JSON.
169
+
170
+ - **Verbose trace in `bind_tools_natively` mode now prints tool
171
+ name + args + response.** Previously native runs showed blank
172
+ `[tool.call.start]` / `[tool.call.complete]` pairs (the
173
+ observability layer fires them without the trace context), so you
174
+ couldn't tell which tool the model actually invoked or what came
175
+ back. The runner now prints `[tool] Invoking '<name>' with args:
176
+ <input>` and `[tool] Response: <preview>` (or `[tool] Error: ...`
177
+ when the dispatch raised) in the post-dispatch loop, matching the
178
+ format text-mode and function-calling mode use. Mirrored to the
179
+ async runner.
180
+
181
+ - **`web_fetch_tool(vector_store=...)` auto-ingests fetched pages into
182
+ a vector store** instead of dumping raw HTML into the model's
183
+ context. Fixes the TPM-limit trap: when a research agent fetches
184
+ four articles in parallel (via ``multi_tool_use.parallel`` or
185
+ native binding), the combined bodies can easily exceed 40k tokens
186
+ and blow past a 30k TPM ceiling on the very next model call.
187
+ New parameters on ``web_fetch_tool``:
188
+
189
+ | Kwarg | Default | Effect |
190
+ |---|---|---|
191
+ | ``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. |
192
+ | ``chunk_size`` | ``1500`` | Characters per chunk when ``vector_store`` is set. Ignored otherwise. |
193
+ | ``chunk_overlap`` | ``200`` | Overlap between adjacent chunks so a fact spanning a boundary is still retrievable. Ignored otherwise. |
194
+
195
+ Backwards-compatible: the positional ``cache_dir`` signature keeps
196
+ working; `web_fetch_tool()` with no ``vector_store`` returns raw
197
+ body as before. Ingest and cache_dir compose — enable both and get
198
+ disk-cached full bodies AND searchable chunks. HTML stripping is
199
+ minimal and dependency-free (regex-based: script/style blocks
200
+ dropped whole, then tags stripped, whitespace collapsed) so the
201
+ ingest path adds no new install dependency. On JSON/plain-text
202
+ responses the stripper is a near no-op.
203
+
204
+ The observation returned to the model shows topical coverage --
205
+ first, middle, and last chunk previews (up to 3 samples,
206
+ deduplicated for short pages) -- so the model can tell what
207
+ topics the page actually covers, not just the intro paragraph.
208
+ Without this the model would only see the page's opening and
209
+ wouldn't know to query for topics discussed later in the same
210
+ page. Explicit instruction in the observation ("query with
211
+ SPECIFIC keywords from the topics above; do NOT re-fetch; do
212
+ NOT ask for the full body") steers the model toward the RAG path
213
+ on follow-up turns.
214
+
215
+ - **`multi_tool_use.parallel` now reaches its dispatch path.**
216
+ When GPT wanted to batch several tool calls into one turn (fetch N
217
+ URLs concurrently, run M searches at once), it emitted OpenAI's
218
+ synthetic `multi_tool_use.parallel` meta-tool. The registry's
219
+ `_dispatch_multi_parallel` / `_adispatch_multi_parallel` handlers
220
+ already knew how to unpack it, but the runner loop's known-tools
221
+ guardrail rejected the name FIRST as unregistered — dumping the
222
+ raw `{"tool_uses": [...]}` payload into the user-facing "final
223
+ answer" and never invoking any of the nested calls. Added
224
+ `multi_tool_use.parallel` to the recognized action set in both
225
+ sync and async runners so the meta-tool flows through to dispatch
226
+ and the existing unpackers run. Nested calls with the `functions.`
227
+ prefix are normalized before dispatch (same as top-level FC
228
+ calls), so the model can emit either shape.
229
+
230
+ - **`Permissions.full_access` / `read_only` auto-wrap a bare string.**
231
+ Passing `full_access("./workspace")` used to iterate the string
232
+ into 11 single-character "subtrees" (Python's `list("./workspace")`)
233
+ — every path check silently rejected because no real path could
234
+ ever match a `"."` or `"/"` "allowed subtree". The classmethod
235
+ now detects a bare string and treats it as `[allowed_paths]`, so
236
+ `full_access("./workspace")` does the intuitive thing (equivalent
237
+ to `full_access(["./workspace"])` and auto-infers the workspace).
238
+ Same fix on `read_only`. List inputs are unchanged.
239
+
240
+ - **`Permissions.full_access` now accepts (and auto-infers)
241
+ `workspace`.** The classmethod set `allowed_paths` but not
242
+ `workspace`, so short paths like `write_file(path="report.md")`
243
+ resolved to CWD (outside the sandbox) and raised
244
+ `PermissionError: access denied` — a landmine that every caller of
245
+ `Permissions.full_access(["./workspace"])` hit sooner or later.
246
+ New signature: `full_access(allowed_paths, *, workspace=None)`.
247
+ When `workspace` isn't passed AND `allowed_paths` has exactly one
248
+ entry, that path is auto-set as the workspace (the "project-scoped
249
+ agent whose one allowed subtree IS its workspace" case, which is
250
+ 99% of use). Two or more paths stay ambiguous and require an
251
+ explicit `workspace=` if short-path resolution is wanted. Pass an
252
+ explicit `workspace=` string to override the auto-choice.
253
+ Backwards-compatible on the positional signature; adds a keyword
254
+ argument that existing callers didn't use.
255
+
7
256
  ## [3.1.5] — 2026-07-26
8
257
 
9
258
  ### 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/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
+ # 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.1.5
3
+ Version: 3.3.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/Bruce_framework
29
- Project-URL: Bug Tracker, https://github.com/shadrach098/Bruce_framework/issues
30
- Project-URL: Source, https://github.com/shadrach098/Bruce_framework
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/Bruce_framework",
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/Bruce_framework
1127
- - Issues: https://github.com/shadrach098/Bruce_framework/issues
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/Bruce_framework",
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/Bruce_framework
1063
- - Issues: https://github.com/shadrach098/Bruce_framework/issues
1062
+ - Repo: https://github.com/shadrach098/agentx_dev
1063
+ - Issues: https://github.com/shadrach098/agentx_dev/issues