All notable changes to tiny-agent-os are documented in this file.
Format follows Keep a Changelog. This project uses Semantic Versioning.
- Restored GIL release while the Rust
_alchemybinding blocks waiting for streamed events and final results, fixing Python scheduling stalls introduced by the re-integrated in-repo binding.
- Fixed the PyPI release workflow to build exactly one Python 3.10
cp310-abi3wheel per platform, eliminating duplicate wheel filenames with different binary contents from the old per-version matrix. - Made the PyPI publish step rerunnable by skipping files that already exist, which prevents partial uploads from blocking a release retry.
- Updated the package metadata and release docs to describe the restored in-repo Rust binding instead of the retired external-binding flow.
- Fixed Linux PyPI wheel uploads by patching the in-repo Rust binding's
alchemy-llmdependency to use Rustls instead of native OpenSSL, removing bundledlibsslandlibcryptofrom the Linux wheel.
- Fixed Linux wheel CI scripting by replacing inline Python heredocs in the release workflow with a checked-in smoke-test script, removing the shell indentation and quoting failures from the manylinux path.
- Fixed the Linux release workflow import check by replacing the inline
python -ccommand with a heredoc so shell quoting cannot strip"tinyagent"fromsys.path.insert(...).
- Fixed Linux wheel builds by moving the manylinux Docker build from
manylinux2014(OpenSSL 1.0.2) tomanylinux_2_28, which satisfies theopenssl-sysminimum supported OpenSSL version.
- Fixed Linux manylinux wheel builds by disabling vendored-OpenSSL-from-source (use system OpenSSL + auditwheel repair to avoid CI Perl module dependency churn).
- Fixed Linux wheel builds by installing the missing Perl
IPC::Cmdmodule dependency required for the vendored OpenSSL compile in manylinux. - Fixed macOS/Windows wheel builds by validating the staged
_alchemybinary without importingtinyagent/__init__.py(avoids missing runtime deps likepydanticin CI).
- Fixed Linux wheel builds in CI by running the manylinux build inside Docker (avoids Node/glibc mismatch from job-level containers).
- Fixed macOS Rust binding builds by enabling the
-undefined dynamic_lookuplink args so pyo3 can resolve Python symbols at runtime on arm64.
- Restored the Rust
_alchemybinding in-repo and added a typed Python adapter for it. - Added a new PyPI publish workflow that builds the binding per platform and uploads the resulting wheels.
- The release workflow now uploads a
.artifactdebug bundle per platform with wheel metadata and staged-binding state for CI triage.
- Avoided system OpenSSL dependencies in Linux wheel builds by switching the TLS stack to a vendored build.
- Repaired Linux release wheels with
auditwheelin CI so published artifacts use PyPI-compatiblemanylinuxtags instead of genericlinux_x86_64. - Added a release-wheel tag check that blocks generic Linux wheel tags before smoke test and publish.
- Updated the release docs and harness guidance to document the repaired Linux wheel path and the new wheel-tag gate.
1.2.16 - 2026-03-23
- Added Linux to the release workflow matrix so tag/manual releases now build and publish Linux, macOS, and Windows wheels with the staged
tinyagent._alchemybinding. - Switched PyPI publishing in the release workflow to the repository
PYPI_TOKENsecret while keeping GitHub release asset uploads enabled for the same artifacts. - Clarified release docs and harness notes so the published release path explicitly covers GitHub release assets and PyPI uploads for all three platforms.
1.2.15 - 2026-03-22
- Pinned the Windows release workflow to
C:\Strawberry\perl\bin\perl.exeviaOPENSSL_SRC_PERLandPERL, so vendoredopenssl-srcno longer depends on runnerPATHordering during the external binding build. - Corrected the release guidance to document the verified external wheel layout (
_alchemy/_alchemy...) and the current staging contract.
1.2.14 - 2026-03-22
- Accepted the actual external binding wheel package layout (
_alchemy/_alchemy...) when staging release artifacts, which unblocks the macOS release job after the 1.2.13 hotfix still proved too narrow.
1.2.13 - 2026-03-22
- Accepted both
tinyagent/_alchemy...and top-level_alchemy...wheel layouts when staging the external binding for release packaging, so the macOS release job can consume the built binding wheel. - Switched the Windows release job to Strawberry Perl before building the vendored OpenSSL dependency, avoiding the broken runner Perl that blocked the wheel build.
1.2.12 - 2026-03-22
- Added
examples/minimax_tool_contract_examples.pyback as the runnable/property-tested MiniMax contract example module consumed by the test suite. - Added
.github/workflows/release-platform-wheels.ymlto build and publish macOS and Windows wheels with the staged externaltinyagent._alchemybinding.
- Restored the missing MiniMax example module so the hypothesis-based contract test suite collects and passes again.
- Improved optional alchemy-binding import failures to preserve the original loader error, making release-time binding mismatches diagnosable.
- Hardened the release binding check to reject staged
_alchemybinaries that do not match the host platform format before packaging. - Tagged staged-binding Linux wheels as
cp310-abi3instead of interpreter-specificcp310-cp310, so the release wheel installs correctly across supported CPython versions.
- Added the dedicated MiniMax single-tool example page and documented the staged-binding release workflow for cross-platform wheels.
1.2.11 - 2026-03-17
- Restored
Agent.replace_messages(...)andAgent.append_message(...)after their accidental removal in1.2.10, preserving minor-version source compatibility for downstream integrations. - Re-aligned the
tinyagentpackage layout and behavior with the pre-regression public API contract used by existing users.
1.2.10 - 2026-03-17
- Refactored
Agentruntime internals by extracting streaming, event handling, and configuration into separate modules (agent_streaming.py,agent_event_handler.py,agent_options.py,message_content.py). - Updated ARCHITECTURE.md to reflect new module boundaries and responsibilities.
- Configured setuptools to include staged prebuilt
tinyagent._alchemyextension artifacts in release wheels again when those binaries are copied intotinyagent/from the external binding repo.
scripts/check_release_binding.py- release gate for the_alchemywheel contract, plus tests covering package-data and staged-binary checks.HARNESS.md- Critical enforcement document describing pre-commit hooks, ratchets, and rule entry points.py-compilepre-commit hook to catch syntax and import-time compilation errors.tinyagent-file-lengthpre-commit hook with 400-line ratchet for files undertinyagent/.docs/harness/HARNESS.md- Guardrails for code indocs/harness.
- Updated
AGENTS.mdto referenceHARNESS.mdand document enforcement-first policy. - Removed obsolete API entries from
docs/api/agent.md(replaced by typedAgentOptions).
1.2.9 - 2026-03-16
- Added a fallback import path for the optional external alchemy binding so TinyAgent accepts both
tinyagent._alchemyand top-level_alchemywheel layouts after the repo split.
1.2.8 - 2026-03-16
- Added
tinyagent/py.typedto mark the published Python package as typed.
- Switched the repo build from a local
maturinmixed Rust/Python package to a pure Pythonsetuptoolsbuild. - Reframed
tinyagent/alchemy_provider.pyas a compatibility adapter for the optional external binding repo athttps://github.com/tunahorse/tinyagent-alchemy. - Updated README, API docs, architecture notes, harness guidance, and
AGENTS.mdto treat the Rust binding as external to this repo.
- Skipped the live harness test when provider API keys are not configured so the default test suite stays green in clean environments.
- Removed the in-repo Rust binding manifests and local binding-enforcement lint now that binding ownership has moved out of this repository.
- Removed stale binding-specific docs and diagrams that still described
src/lib.rsas the source of truth.
1.2.7 - 2026-03-04
- Added an AST-grep
no_any_pythonrule with tests and snapshots undersrc/rules/ast/to enforce the TypedDict-to-Pydantic hard cutover policy. - Added an opt-in live integration test at
tests/test_tool_call_types_harness.pyfor end-to-end harness validation (RUN_LIVE_HARNESS=1).
- Tightened
tinyagent/alchemy_provider.pystream boundary typing by replacingAnywith protocol/object-typed interfaces. - Extended
docs/harness/tool_call_types_harness.pyprovider resolution to include MiniMax and switched tool args toJsonObjectwith numeric coercion.
1.2.6 - 2026-03-03
- Added a mandatory live type-contract harness at
docs/harness/tool_call_types_harness.pyto verify one real tool-call turn and print model/event type names. - Added regression tests for strict model serialization boundaries and malformed proxy event handling.
- Completed the hard cutover to strict model/event contracts in core runtime paths (agent loop, tool execution, caching, proxy handling, and provider serialization).
- Removed the legacy
openrouter_providerpath in favor of the Rust-backed OpenAI-compatible provider flow.
- Restored provider env-key fallback for
openrouter(OPENROUTER_API_KEY) intinyagent/alchemy_provider.py. - Hardened proxy streaming event handling by clamping malformed/negative
contentIndexvalues. - Improved cross-provider tool-call smoke examples to preserve tool execution error signals.
- Updated architecture/API/hard-cutover documentation to reflect strict model-only contracts and the new harness location.
1.2.5 - 2026-02-23
- Executed tool-call batches in parallel via
asyncio.gather()inexecute_tool_calls(). - Added
examples/example_parallel_tools.pyto compare parallel vs sequential tool execution behavior and timing.
- In parallel mode, steering is now applied after the full tool batch completes; already-started tool calls are no longer skipped mid-batch.
- Tool execution events now follow a batch lifecycle: emit all
tool_execution_startevents first, then emit orderedtool_execution_endand tool-result message events.
- Propagated task-level cancellation during parallel tool execution instead of converting it into a synthetic tool error.
- Prevented a self-cancelled tool from aborting the entire parallel tool batch.
- Removed duplicate steering polling after tool batches in the agent loop.
- Hardened Rust tool-call argument normalization to only accept JSON objects (non-object payloads now normalize to
{}). - Switched tool-result timestamps to
asyncio.get_running_loop()for async-loop-safe timing.
- Aligned steering/interruption docs to the post-batch parallel execution contract across architecture and API pages.
- Added comprehensive coverage for parallel tool execution order, concurrency, per-tool error isolation, and cancellation behavior.
- Added regression coverage for task cancellation propagation in
execute_tool_calls(). - Added loop-level coverage to ensure steering is not double-polled after a tool batch.
- Added Rust unit coverage for strict tool-call argument normalization.
1.2.4 - 2026-02-21
- Upgraded
alchemy-llm0.1.5 -> 0.1.6: fixes MiniMax multi-turn tool call arguments (turn 2+ no longer send{}). - Normalized tool call arguments in Rust binding and Python fallback.
- Added
scripts/smoke_rust_tool_calls_three_providers.pyas the canonical raw Rust-binding multi-turn tool-call smoke script (OpenRouter, MiniMax, Chutes).
- Default Chutes model in the Rust smoke script is now
Qwen/Qwen3-Coder-Next-TEE(override withCHUTES_MODEL).
1.2.3 - 2026-02-21
- Upgraded Rust dependency to
alchemy-llm0.1.5. - Updated the PyO3 binding bridge to map tool call IDs into alchemy's typed
ToolCallIdfields for both assistant tool calls and tool results.
- Added
examples/example_tool_calls_three_providers.pyfor one-agent tool-call smoke runs across OpenRouter, MiniMax, and Chutes.
- Added explicit cross-provider smoke-run output documentation for Rust-backed tool calls in
docs/api/providers.md. - Added a quick pointer to the three-provider tool-call example in
docs/README.md.
1.2.1 - 2026-02-18
- Prevented an extra agent turn when tool execution returns no tool results.
- Updated examples to import
Agentthrough the package public API.
- Added regression coverage to ensure
Agent.prompt()does not re-enter the stream loop after empty tool execution results.
1.2.0 - 2026-02-17
- Reasoning effort levels support in Alchemy provider (
low,medium,high) ThinkingContenttype for reasoning/thinking blocks withcache_controlsupport
- Documented reasoning effort levels and ThinkingContent usage
- Added example demonstrating reasoning vs text block separation
- Use absolute URL for logo in README
1.1.5 - 2026-02-12
- Upgraded Rust dependency to
alchemy-llm0.1.3. - Aligned usage semantics with provider-raw reporting across Python and Rust paths.
- OpenRouter usage normalization now prefers provider
total_tokenswhen present. - Rust OpenAI-compatible stream path now maps OpenRouter cost fields into
usage.cost.
- Expanded usage normalization tests for provider
total_tokens, cache precedence, and nested cache-write details. - Added Rust-side cost mapping coverage for
cost,cost_details, and fallback behavior.
- Updated caching and OpenAI-compatible endpoint docs to use snake_case usage keys and document provider-raw semantics.
1.1.3 - 2026-02-11
- OpenAI-compatible
base_urlsupport across Python and Rust providers - Runtime type contract tests
- Expanded OpenAI-compatible endpoint guidance for Rust and Chutes
1.1.2 - 2026-02-10
- Raw usage aliases (
prompt_tokens,completion_tokens) for downstream compatibility
1.1.1 - 2026-02-09
- Prompt caching pipeline:
cache_controlfield onTextContentandThinkingContent add_cache_breakpoints()transform withenable_prompt_cachingoption- OpenRouter structured content blocks and
anthropic-betaheader support - Cache usage stats parsing from API responses
- Verification tests for prompt caching pipeline
- OpenRouter prompt caching behavior and documentation
- Alchemy provider import and typing issues
- Unused
_annotate_system_prompt_block add_cache_breakpointsre-export from package root
1.1.0 - 2026-02-08
- Switched to PyO3 abi3 stable ABI for broader Python version compatibility
- Added vendored OpenSSL for Linux cross-compilation
1.0.0 - 2026-02-08
- Restructured as maturin mixed Python/Rust build
0.2.0 - 2026-02-08
- Initial PyPI release
- Maturin mixed Python/Rust project structure
- grimp-based import boundary enforcement as pre-commit hook
- Code quality gates (dead code, duplicates, debt)
- Rust
alchemy_llm_pybinding documentation