Skip to content

Releases: bubbuild/republic

0.5.4

09 Mar 04:40
c3d2c1f

Choose a tag to compare

What's Changed

  • fix: treat max_retries as retry count by @Andy963 in #26
  • feat: add query filters for text matching and date range in TapeQuery by @frostming in #24
  • OpenAI codex oauth integration by @niyue in #23
  • fix(responses): restore parity with chat completions and refactor parsing by @PsiACE in #21

New Contributors

Full Changelog: 0.5.3...0.5.4

0.5.3

05 Mar 10:51
d8ba90e

Choose a tag to compare

What's Changed

  • chore(meta): migrate links to bubbuild/republic and align attribution by @PsiACE in #20

Full Changelog: 0.5.2...0.5.3

0.5.2

01 Mar 06:32
f0ccc1a

Choose a tag to compare

Full Changelog: 0.5.1...0.5.2

0.5.1

01 Mar 06:20
cc1e4e4

Choose a tag to compare

Full Changelog: 0.5.0...0.5.1

Release v0.5.0: Async tape storage

01 Mar 06:02
2d330aa

Choose a tag to compare

Key Changes

1. Added opt-in Responses API mode

LLM now supports use_responses: bool = False for explicit Responses mode.

  • When enabled (and supported by the provider), non-stream requests use the Responses API.
  • Added internal conversion from chat/tool history to Responses input items.
  • Tool-call extraction now supports both completion-style and responses-style payloads.

Files involved:

  • src/republic/llm.py
  • src/republic/core/execution.py
  • src/republic/clients/chat.py
  • tests/test_responses_handling.py

2. Tape subsystem refactored for async support

Tape management now supports both sync and async paths, including async storage and context lifecycle.

  • Added AsyncTapeStore protocol.
  • Added AsyncTapeStoreAdapter to wrap sync stores for async usage.
  • Added AsyncTapeManager for async read/write/handoff/record flows.
  • TapeQuery is now generic and supports await query.all() for async stores.
  • Tape session now provides async tape methods: read_messages_async, append_async, reset_async, handoff_async.

Files involved:

  • src/republic/tape/store.py
  • src/republic/tape/manager.py
  • src/republic/tape/query.py
  • src/republic/tape/session.py
  • src/republic/tape/__init__.py

3. Expanded top-level exports for async tape types

republic top-level exports now include:

  • AsyncTapeManager
  • AsyncTapeStore

Files involved:

  • src/republic/__init__.py

4. Reliability and release pipeline fixes

  • Fixed TapeEntry.copy() to preserve timestamp during copies.
  • Fixed docs deployment workflow permissions by adding contents: write to deploy-docs and updating actions/checkout version.

Files involved:

  • src/republic/tape/entries.py
  • .github/workflows/on-release-main.yml

Behavior Changes and Upgrade Notes

AsyncTapeStore with sync APIs

When tape_store is an AsyncTapeStore, sync APIs with tape=... raise ErrorPayload.

Use async APIs instead:

  • chat_async
  • tool_calls_async
  • run_tools_async
  • stream_async
  • stream_events_async

LLM direct tape helpers moved behind session objects

LLM no longer directly exposes:

  • tapes()
  • handoff(...)
  • read_messages(...)
  • query(...)
  • reset_tape(...)

Migration: use operations on the session returned by llm.tape("<name>").

Documentation Updates

  • docs/guides/tape.md now includes Async Tape Store usage and sync/async behavior rules.

Commit List

  • 2d330aa fix: add permissions for contents write in deploy-docs job
  • edd9400 chore: bump version to 0.5.0 in pyproject.toml, about.py, and uv.lock
  • 4ffea2d feat: Refactor tape management to support asynchronous operations (#19)
  • 04525fb fix: import time and include timestamp in TapeEntry copy method
  • b9069a5 feat: add opt-in Responses API mode (#18)

Upgrade Checklist

  • If you use an async tape backend, migrate tape-related calls to async APIs.
  • If you relied on removed LLM tape helpers, migrate to llm.tape(name).
  • Enable Responses behavior explicitly with LLM(..., use_responses=True) when needed.

0.4.1

27 Feb 02:50
f5afe26

Choose a tag to compare

What's Changed

  • refactor tape query API and document read_entries deprecation by @frostming in #17

Full Changelog: 0.4.0...0.4.1

Release 0.4.0: Async tools

12 Feb 09:08
422a6e8

Choose a tag to compare

Highlights

  • Introduced async tool execution support.
  • Simplified public error handling by removing StructuredOutput.
  • Added provider-specific max token handling in LLMCore.
  • Improved tool error responses by preserving tool arguments on failure.

Breaking Changes

StructuredOutput removed from public API

StructuredOutput(value, error) is no longer used for non-streaming APIs.
Success now returns plain values, and failures raise ErrorPayload.

Affected API families include:

  • LLM.chat*, LLM.tool_calls*, LLM.if_*, LLM.classify*, LLM.embed*
  • Tape.chat*, Tape.tool_calls*
  • ToolExecutor.execute(...) now raises ErrorPayload for validation/input/tool lookup failures

Also removed/simplified:

  • ContextSelection removed (read_messages(...) returns list[dict[str, Any]])
  • QueryResult removed (TapeQuery.all() returns list[TapeEntry])

Migration pattern:

  • Replace .value / .error checks with try/except ErrorPayload.
  • Search old usage quickly with:
rg -n "StructuredOutput|\\.value\\b|\\.error\\b" src tests

For detailed migration examples, see docs/guides/breaking-changes.md.

Features

  • feat: implement async tool execution (86a5f43)

    • Added async execution path for tool calls.
    • Updated chat client and tool executor integration.
    • Expanded contract and UX test coverage around async behavior.
  • feat: add provider-specific max tokens handling in LLMCore (a79be07)

    • LLMCore now applies max token behavior with provider-specific handling.

Fixes

  • fix: return tool arguments on error in tool response handling (279a36e)
    • Tool execution error responses now preserve original tool arguments for better debugging and recovery.

Refactors and Tooling

  • refactor: Refactor error handling and remove StructuredOutput (025b045)
    • Aligned client/core error semantics to Python-style exceptions.
    • Updated tape query/context/session return types.
    • Refreshed tests for new behavior.
  • CI/dev tooling updates:
    • Switched workflow hooks from pre-commit to prek.
    • Updated related config/docs and lockfile.

Diff Summary

From 0.3.2 to 0.4.0:

  • 5 commits
  • 25 files changed
  • 998 insertions, 696 deletions

Recommended Upgrade Checklist

  • Update call sites that rely on .value / .error.
  • Add/adjust exception handling for ErrorPayload.
  • Re-run test suites covering chat/tool-call/tape flows.
  • Validate provider-specific token limits in your production configs.

0.3.2

10 Feb 13:19
14ecbdf

Choose a tag to compare

What's Changed

Full Changelog: 0.3.1...0.3.2

0.3.1

10 Feb 03:54
8ab96b0

Choose a tag to compare

What's Changed

  • feat: add model parameter to tool decorator for enhanced functionality by @frostming in #8
  • fix: include tool error as model context by @frostming in #9

New Contributors

Full Changelog: 0.3.0...0.3.1

Release 0.3.0: Tape-First UX Refresh

08 Feb 17:52

Choose a tag to compare

This release refines Republic around a tape-first, practical developer workflow. The API surface is smaller and more intentional, docs/examples were fully rewritten, and reliability improved in streaming and fallback behavior.

Highlights

  • Tape-first flow with explicit anchors (handoff) and queryable execution history.
  • Unified LLM facade for chat, tools, streaming, text decisions, and embeddings.
  • Structured return pattern (value + error) across core interfaces.
  • Improved event streaming, including more robust tool-call delta merging.
  • Better error classification and fallback handling across provider exception shapes.
  • New docs and runnable examples with a simpler, usage-first style.
  • Contract-style test suite focused on user-facing behavior.

Example

import os

from republic import LLM

llm = LLM(model="openrouter:openrouter/free", api_key=os.environ["LLM_API_KEY"])

out = llm.chat("Describe Republic in one sentence.", max_tokens=48)
print(out.value if out.error is None else out.error.message)

tape = llm.tape("release-notes")
tape.handoff("draft_v1", state={"owner": "assistant"})

reply = tape.chat("Summarize the latest changes in three bullets.", max_tokens=96)
print(reply.value if reply.error is None else reply.error.message)

Upgrade Notes

  • Main usage is now centered on LLM + structured outputs.
  • Docs were reorganized to a Quickstart + focused Guides layout.
  • Streaming/tool behavior is aligned around explicit inspectable results.
  • Error/retry/fallback logic was updated for mixed provider environments.
  • Core dependency surface now includes pydantic.

Thanks

Derived from lightning-ai/litai, inspired by pydantic/pydantic-ai, and adapted into Republic’s tape-first execution style.