Skip to content

feat: expose republic models and media attachments in code mode - #351

Merged
frostming merged 1 commit into
refactor/republic-provider-migrationfrom
feat/codemode-republic
Oct 13, 2026
Merged

frostming merged 1 commit into
refactor/republic-provider-migrationfrom
feat/codemode-republic

Conversation

@frostming

Copy link
Copy Markdown
Collaborator

Stacked on #349 (Republic 0.6 migration).

What changed and why

Code written by the model in run_code can now call models and show media to the model.

  • republic module inside run_code (preset global, also importable as republic, republic.events, republic.decisions). It is a stdlib shim in code_runner_child.py:
    • media classes Image / Audio / Video, messages system() / user() / assistant()
    • get_model(spec=None) with chat() and stream(). Without a spec it uses the session model.
    • get_embedding_model(spec) (embed / embed_many) and get_decision_model(spec) (decide with Noul / Choice / Score)
    • Model calls are proxies. The shim forwards them as republic.<op> calls over the existing call_tool channel. RepublicSession (codemode/republic_bridge.py) then runs them with Bub's provider settings and credentials, so credentials never reach model-written code.
    • Streaming is pull-based. Bub pumps events into a queue and each stream_next returns every event that has arrived. Streams the code leaves open are closed when run_code ends.
    • Republic values travel as JSON objects with a "$republic" key.
  • Code-only tools attach_image / attach_audio / attach_video.
    • They take a republic media object, or a file path in the environment, a URL, or a data URL, and load it themselves.
    • The media is attached to that run_code result, which becomes a multimodal tool message.
  • Content results.
    • bub.tools.content_result() builds a JSON tool result ({"type": "tool_content", ...}) that carries text and media.
    • ToolExecutor does not re-render it, tape context turns it into a multimodal republic.tool message, and spilling bounds only its text.
  • Environment.read_bytes(), non-abstract. The default runs the environment's python to print the file; LocalEnvironment reads the file directly.
  • Agent-facing docs.
    • The code mode stub now documents the republic module and has a streaming example.
    • The code mode prompt mentions the attach tools and models.
    • Media parameters render as republic.Image | str.
    • Fixed: the stub builder now resolves $defs nested in a parameter schema.

Impacted modules

bub.builtin.codemode (__init__, code_runner_child, new republic_bridge), bub.tools, bub.environment, bub.builtin.environment, bub.builtin.context, bub.builtin.hook_impl (spill), website docs build/tools.mdx (en + zh-cn).

Limitations

  • chat() / stream() do not support tools, tool_choice or output_schema.
  • Model calls from code do not go through before_llm_call hooks or tracing spans.
  • The code runner child now uses X | Y in isinstance, so the environment's Python must be 3.10+.

Verification

  • uv run ruff check .: passed
  • uv run mypy src: no issues
  • uv run pytest -q: 596 passed, 20 skipped
  • New tests in tests/test_codemode.py, tests/test_spill.py, tests/test_environment.py cover:
    • stub content
    • media attachment from a path, a URL and an object, plus load errors
    • multimodal tool messages
    • model proxy spec and credentials
    • streaming, stream errors and leaked-stream cleanup
    • spilling content results
    • the default read_bytes

🤖 Generated with Claude Code

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bub 3a3537b Commit Preview URL

Branch Preview URL
Oct 13 2026, 12:34 AM

@frostming
frostming force-pushed the feat/codemode-republic branch from ccaaa68 to f92a641 Compare October 10, 2026 09:13
@frostming
frostming added this pull request to stack #352 October 10, 2026 09:22
- Add a stdlib `republic` module to run_code: media classes, messages,
  get_model() (chat and stream), get_embedding_model() and
  get_decision_model(). Model calls are proxied to Bub, which uses its
  provider settings and credentials; they never reach the code.
- Add code-only tools attach_image/attach_audio/attach_video that accept
  republic media or a path/URL/data URL and attach it to the run_code
  result, sent to the model as a multimodal tool message.
- Add content results (bub.tools.content_result) for tool results with
  media; spilling bounds only their text.
- Add Environment.read_bytes with a default that runs the environment's
  python.
- Document the republic module in the code mode stub and prompt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@frostming
frostming force-pushed the feat/codemode-republic branch from f92a641 to 3a3537b Compare October 13, 2026 00:32
@frostming
frostming removed this pull request from stack #352 October 13, 2026 00:53
@frostming
frostming merged commit 80ca6c0 into refactor/republic-provider-migration Oct 13, 2026
6 checks passed
@frostming
frostming deleted the feat/codemode-republic branch October 13, 2026 00:53
frostming added a commit that referenced this pull request Oct 13, 2026
- Add a stdlib `republic` module to run_code: media classes, messages,
  get_model() (chat and stream), get_embedding_model() and
  get_decision_model(). Model calls are proxied to Bub, which uses its
  provider settings and credentials; they never reach the code.
- Add code-only tools attach_image/attach_audio/attach_video that accept
  republic media or a path/URL/data URL and attach it to the run_code
  result, sent to the model as a multimodal tool message.
- Add content results (bub.tools.content_result) for tool results with
  media; spilling bounds only their text.
- Add Environment.read_bytes with a default that runs the environment's
  python.
- Document the republic module in the code mode stub and prompt.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
frostming added a commit that referenced this pull request Oct 14, 2026
* refactor: use Republic for builtin models and authentication

* refactor: consume native model outputs

* refactor: delegate request extras to Republic

* refactor: simplify builtin options and naming

* chore: use Republic 0.6 preview

* Refactor prompt handling and improve compatibility with legacy content

- Introduced `republic` module to manage media types and user content.
- Updated tests to validate new prompt structure and legacy content conversion.
- Modified `build_prompt` to return a list of `UserContent` instead of legacy formats.
- Enhanced documentation to reflect changes in prompt handling and hook signatures.
- Adjusted various tests to ensure compatibility with new prompt formats and legacy support.

Signed-off-by: Frost Ming <me@frostming.com>

* fix: replay Chat Completions tool calls from older tapes

Older Bub versions recorded tool calls as
{"id", "type": "function", "function": {"name", "arguments"}}, which
republic.Message.from_dict rejects with KeyError: 'name', so sessions
with such tapes could not build their context. Convert them to
Republic's form in to_message, next to the other legacy conversions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: identify Republic model clients as bub/{version}

Send User-Agent: bub/{version} instead of Republic's default through
AgentSettings.model_client_kwargs, used by the model runner, code mode
and onboarding. A User-Agent in client_args.headers still wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: expose republic models and media attachments in code mode (#351)

- Add a stdlib `republic` module to run_code: media classes, messages,
  get_model() (chat and stream), get_embedding_model() and
  get_decision_model(). Model calls are proxied to Bub, which uses its
  provider settings and credentials; they never reach the code.
- Add code-only tools attach_image/attach_audio/attach_video that accept
  republic media or a path/URL/data URL and attach it to the run_code
  result, sent to the model as a multimodal tool message.
- Add content results (bub.tools.content_result) for tool results with
  media; spilling bounds only their text.
- Add Environment.read_bytes with a default that runs the environment's
  python.
- Document the republic module in the code mode stub and prompt.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* refactor!: extract an event-driven core agent into bub.core (#356)

* docs: update README to improve clarity and organization of content

Signed-off-by: Frost Ming <me@frostming.com>

* feat: accept republic built-in tools in core Agent

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant