Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
0c91b87
docs(roadmap): document competitive research findings and priority-or…
johnnichev Apr 10, 2026
412091f
docs(plan): competitor-informed bug fix implementation plan
johnnichev Apr 10, 2026
167ffe1
fix(streaming): collect ToolCall objects during streaming
johnnichev Apr 10, 2026
cf95734
fix(tests): relocate BUG-01 regression tests to canonical location
johnnichev Apr 10, 2026
ac212c1
docs(plan): sweep stale tests/regressions/ references in task code bl…
johnnichev Apr 10, 2026
a592570
fix(tools): support typing.Literal in @tool() parameters
johnnichev Apr 10, 2026
005f62d
fix(async): safe run_sync helper for 8 sync wrappers
johnnichev Apr 10, 2026
c311b25
fix(_async_utils): use module-level executor singleton (pitfall #20)
johnnichev Apr 10, 2026
5ea31fc
fix(orchestration): propagate HITL interrupts from parallel groups
johnnichev Apr 10, 2026
995577f
fix(orchestration): propagate HITL interrupts from subgraphs
johnnichev Apr 10, 2026
6bbb2fd
fix(orchestration): flat-key propagation for subgraph HITL resume
johnnichev Apr 10, 2026
4809e45
fix(memory): add threading.RLock to ConversationMemory
johnnichev Apr 11, 2026
953f759
fix(anthropic): strip <think> reasoning tags from text output
johnnichev Apr 11, 2026
733dd10
fix(rag): chunk large upserts in Chroma, Pinecone, Qdrant
johnnichev Apr 11, 2026
cc89e86
fix(mcp): serialize concurrent tool calls on shared session
johnnichev Apr 11, 2026
b2f9c72
fix(tools): coerce str args + fallback for Union[str, int]
johnnichev Apr 11, 2026
b20d3a3
fix(state,memory): fail fast on non-serializable data + cap summary g…
johnnichev Apr 11, 2026
c765cd9
fix(orchestration): handle multi-interrupt generator nodes
johnnichev Apr 11, 2026
0656c0f
fix(sessions): add namespace parameter for isolation
johnnichev Apr 11, 2026
8d39d60
fix(observability): thread-safety for AgentTrace + OTel + Langfuse ob…
johnnichev Apr 11, 2026
330f535
fix(agent): log async observer exceptions + isolate clone observers
johnnichev Apr 11, 2026
57d781a
fix(agent,tools): cancelled extraction + Optional as not-required
johnnichev Apr 11, 2026
df9dc44
fix(rag): opt-in search result deduplication
johnnichev Apr 11, 2026
aabe367
docs(changelog): document 22 competitor-informed bug fixes
johnnichev Apr 11, 2026
19da051
docs: update for v0.22.0 bug fixes + sync stale test counts
johnnichev Apr 11, 2026
a9b1c0b
docs(mkdocs): sync docs/CHANGELOG.md + restore EOF newline
johnnichev Apr 11, 2026
e17234d
release: v0.22.0 — competitor-informed bug fixes
johnnichev Apr 11, 2026
65e0a66
fix(tests): unblock CI on PR #55 — drop nonexistent LocalProvider arg…
johnnichev Apr 11, 2026
1546fb0
fix(rag): BUG-23 — reranker top_k=0 swallowed by `or` fallback
johnnichev Apr 11, 2026
a5c8244
fix(rag): BUG-24 — _dedup_search_results keyed only on document.text
johnnichev Apr 11, 2026
21e15c2
fix(providers): BUG-26 — gemini_provider.py `or 0` swallow on token_c…
johnnichev Apr 11, 2026
379721c
fix(rag): BUG-25 — in-memory filter silently mishandles operator-dict…
johnnichev Apr 11, 2026
6f62947
docs(changelog): add round-2 competitor bug-hunt section (BUG-23 – BU…
johnnichev Apr 11, 2026
6398dc9
fix(providers): BUG-27 — FallbackProvider retriable-error list incomp…
johnnichev Apr 12, 2026
a56138e
fix(providers): BUG-28 — Azure deployment names bypass GPT-5 family d…
johnnichev Apr 12, 2026
986c091
fix(tools): BUG-29 — bare list/dict tool params emit schemas with no …
johnnichev Apr 12, 2026
b04cbad
fix(pipeline): BUG-30 — parallel() branches share input reference
johnnichev Apr 12, 2026
d545717
fix(agent, orchestration): BUG-32 — run_in_executor drops contextvars…
johnnichev Apr 12, 2026
718f07f
fix(providers, agent): BUG-31 — malformed tool-call JSON silently dro…
johnnichev Apr 12, 2026
f44d686
fix(agent): BUG-33 — astream() provider generators leak on inner exce…
johnnichev Apr 12, 2026
441743e
fix(agent): BUG-34 — max_iterations consumed by structured-retry budget
johnnichev Apr 12, 2026
c928634
docs(changelog): add round-3 competitor bug-hunt section (BUG-27 – BU…
johnnichev Apr 12, 2026
27b40db
feat(docs, examples): expand cookbook from 7 to 30 recipes + 6 new ex…
johnnichev Apr 13, 2026
6b3e253
docs: sweep stale counts + add v0.22.0 module documentation
johnnichev Apr 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
385 changes: 385 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ Apply to every public class/function in `__init__.py` exports:
24. **`ConversationMemory.branch()` deep copy**: Use `dataclasses.replace()` on every Message. Restore `image_base64` explicitly (it's `init=False`).
25. **SVG badge XML escaping**: Use `xml.sax.saxutils.escape()` for label/value interpolation.
26. **`bandit` annotations**: Mark safe SQL with `# nosec B608`, safe subprocess with `# nosec B404`.
27. **`aclosing()` for async generators**: `async for item in provider.astream(...)` MUST be wrapped in `async with aclosing(gen) as gen:` so the provider generator is deterministically closed on exception. Use `selectools._async_utils.aclosing` (Python 3.9 backport of `contextlib.aclosing`).
28. **ContextVars propagation in `run_in_executor`**: Direct `loop.run_in_executor(None, fn)` drops `contextvars.Context` (OTel spans, Langfuse traces lost). Use `run_in_executor_copyctx(loop, executor, fn)` from `_async_utils.py`.
29. **Malformed tool-call JSON recovery**: Provider `json.loads()` failures MUST surface via `ToolCall.parse_error`, not silent `return {}`. Use shared `_parse_tool_args()` helper. Tool executor checks `parse_error` before tool lookup.
30. **Structured retry budget**: `RetryConfig.max_retries` controls structured-validation retries INDEPENDENTLY of `max_iterations`. Outer loop uses `max_iterations + ctx.structured_retries` so validation failures don't eat the tool budget.
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Thank you for your interest in contributing to Selectools! We welcome contributions from the community.

**Current Version:** v0.21.0
**Test Status:** 5203 tests passing (95% coverage)
**Test Status:** 5271 tests collected (95% coverage)
**Python:** 3.9 – 3.13

## Getting Started
Expand Down Expand Up @@ -74,7 +74,7 @@ Similar to `npm run` scripts, here are the common commands for this project:
### Testing

```bash
# Run all tests (5203 tests)
# Run all tests (5271 tests)
pytest tests/ -v

# Run tests quietly (summary only)
Expand Down Expand Up @@ -264,7 +264,7 @@ selectools/
│ ├── embeddings/ # Embedding providers
│ ├── rag/ # RAG: vector stores, chunking, loaders
│ └── toolbox/ # 33 pre-built tools
├── tests/ # Test suite (5203 tests, 95% coverage)
├── tests/ # Test suite (5271 tests, 95% coverage)
│ ├── agent/ # Agent tests
│ ├── rag/ # RAG tests
│ ├── tools/ # Tool tests
Expand Down Expand Up @@ -371,7 +371,7 @@ We especially welcome contributions in these areas:
- Add comparison guides (vs LangChain, LlamaIndex)

### 🧪 **Testing**
- Increase test coverage (currently 5203 tests passing!)
- Increase test coverage (currently 5271 tests collected!)
- Add performance benchmarks
- Improve E2E test stability with retry/rate-limit handling

Expand Down
42 changes: 38 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,40 @@ result = AgentGraph.chain(planner, writer, reviewer).run("Write a blog post")
# selectools serve agent.yaml
```

## What's New in v0.22

### v0.22.0 — Competitor-Informed Bug Fixes

22 bugs identified by mining 95+ closed bug reports from [Agno](https://github.com/agno-agi/agno) (39k stars) and 60+ from [PraisonAI](https://github.com/MervinPraison/PraisonAI) (6.9k stars), then cross-referencing the patterns against selectools v0.21.0 source code. Six were shipping blockers. All 22 are now fixed with TDD regression tests.

```python
# BUG-02: typing.Literal now supported in @tool()
from typing import Literal
from selectools.tools import tool

@tool()
def set_mode(mode: Literal["fast", "slow", "auto"]) -> str:
return f"mode={mode}"

# BUG-14: session namespace isolation
store.save("session_123", memory_a, namespace="agent_a")
store.save("session_123", memory_b, namespace="agent_b") # No collision

# BUG-21: opt-in vector store search dedup
results = store.search(query_embedding=emb, top_k=10, dedup=True)

# BUG-03: sync APIs now work in Jupyter / FastAPI handlers
agent.run("hello") # Just works inside async contexts
```

- **6 HIGH severity** (shipping blockers): streaming dropped tool calls, `typing.Literal` crashed `@tool()`, `asyncio.run()` re-entry in 8 sync wrappers, HITL silently lost in parallel groups + subgraphs, `ConversationMemory` had no thread lock
- **9 MEDIUM severity**: `<think>` tag stripping, RAG batch limits, MCP concurrent race, str→int/float/bool argument coercion, `Union[str, int]` support, multi-interrupt generators, GraphState fail-fast validation, session namespace isolation, summary growth cap
- **7 LOW-MED severity**: cancelled-result extraction, `AgentTrace` lock, async observer exception logging, batch clone isolation, OTel/Langfuse observer locks, vector store search dedup, `Optional[T]` without default handling
- **+57 new regression tests** in `tests/agent/test_regression.py`, each with empirical fault-injection verification (test fails without fix, passes after)
- **Thread safety end-to-end correct** across `ConversationMemory`, `AgentTrace`, `OTelObserver`, `LangfuseObserver`, `MCPClient`, `FallbackProvider`, batch clone isolation

See `CHANGELOG.md` for the full per-bug breakdown with cross-references to every original Agno/PraisonAI issue.

## What's New in v0.21

### v0.21.0 — Connector Expansion
Expand Down Expand Up @@ -73,7 +107,7 @@ The first AI agent framework to ship a visual graph builder in a single `pip ins

**[Try the builder in your browser →](https://selectools.dev/builder/)** — no install required.

[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/johnnichev/selectools/blob/main/notebooks/getting_started.ipynb) [![Examples Gallery](https://img.shields.io/badge/examples-88_scripts-06b6d4)](https://selectools.dev/examples/)
[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/johnnichev/selectools/blob/main/notebooks/getting_started.ipynb) [![Examples Gallery](https://img.shields.io/badge/examples-94_scripts-06b6d4)](https://selectools.dev/examples/)

```bash
pip install selectools
Expand Down Expand Up @@ -130,7 +164,7 @@ Path("trace.html").write_text(trace_to_html(result.trace))
- **Trace HTML viewer** — `trace_to_html(trace)` renders a standalone waterfall timeline
- **Deprecation policy** — 2-minor-version window, programmatic introspection via `.__stability__`
- **Security audit** — all 41 `# nosec` annotations reviewed and published in `docs/SECURITY.md`
- **Quality infrastructure** — property-based tests (Hypothesis), thread-safety smoke suite, 5 new production simulations (4612 tests total)
- **Quality infrastructure** — property-based tests (Hypothesis), thread-safety smoke suite, 5 new production simulations (5271 tests total)

### v0.19.1 — Advanced Agent Patterns

Expand Down Expand Up @@ -486,7 +520,7 @@ report.to_html("report.html")
- **76 Examples**: Multi-agent graphs, RAG, hybrid search, streaming, structured output, traces, batch, policy, observer, guardrails, audit, sessions, entity memory, knowledge graph, eval framework, advanced agent patterns, stability markers, HTML trace viewer, and more
- **Built-in Eval Framework**: 50 evaluators (30 deterministic + 21 LLM-as-judge), A/B testing, regression detection, HTML reports, JUnit XML, snapshot testing
- **AgentObserver Protocol**: 45 lifecycle events with `run_id` correlation, `LoggingObserver`, `SimpleStepObserver`, OTel export
- **5203 Tests**: Unit, integration, regression, and E2E with real API calls
- **5271 Tests**: Unit, integration, regression, and E2E with real API calls

## Install

Expand Down Expand Up @@ -1110,7 +1144,7 @@ pytest tests/ -x -q # All tests
pytest tests/ -k "not e2e" # Skip E2E (no API keys needed)
```

5203 tests covering parsing, agent loop, providers, RAG pipeline, hybrid search, advanced chunking, dynamic tools, caching, streaming, guardrails, sessions, memory, eval framework, budget/cancellation, knowledge stores, orchestration, pipelines, agent patterns, stability markers, trace viewer, and E2E integration with real API calls.
5271 tests covering parsing, agent loop, providers, RAG pipeline, hybrid search, advanced chunking, dynamic tools, caching, streaming, guardrails, sessions, memory, eval framework, budget/cancellation, knowledge stores, orchestration, pipelines, agent patterns, stability markers, trace viewer, and E2E integration with real API calls.

## License

Expand Down
Loading