ADK-Rust v2 · CodeAct Agent

Let the model write the workflow.

CodeAct is a way for an AI agent to take action by writing a short program. That program calls only the tools you approve, combines their results with ordinary code, and returns an answer through the ADK-Rust runtime.

cart_assistant.py
cart = call_tool("fetch_cart", args)
subtotal = sum(item["price"] * item["qty"]
               for item in cart["items"])
rate = call_tool("tax_rate", region)
total = subtotal * (1 + rate)
pause · tool · resume
Write
Run
Return
total = $141.57 · 3 cart lines

Start here

What is a CodeAct agent?

A CodeAct agent is an AI agent that writes executable code to decide how several approved tools should work together. Your application runs that code in a controlled interpreter and remains responsible for every external action.

Traditional tool calling

The model chooses one action at a time.

  1. 01Ask the model which tool to call.
  2. 02Run that tool and send its result back to the model.
  3. 03Ask the model what to do next, then repeat.
model → fetch_cart → model → tax_rate → model → answer

CodeAct

The model writes the complete procedure.

  1. 01Ask the model for a short program using the available tools.
  2. 02Run the program and pause only when it reaches a real tool.
  3. 03Resume with the tool result until the program returns its answer.
model → one script ↔ approved tools → answer

A simple analogy

Traditional tool calling is like asking a colleague to press one calculator button, report the screen, and wait for the next instruction. CodeAct is like giving that colleague permission to write a small spreadsheet formula: the allowed inputs stay the same, but the calculation can contain variables, conditions, loops, and several steps.

Eight words you will see on this page

Model

The LLM that writes the script.

Agent

The component that turns a goal into actions and results.

Tool

An approved Rust function that reaches business data or systems.

Script

The short program written for the current agent turn.

Runtime

The interpreter that executes and pauses the script.

Observation

A result or error returned to the model for another turn.

Checkpoint

A saved paused program that can continue later.

Final result

The typed answer returned to your application.

Where the idea came from

CodeAct began as a research question about an agent's action language.

Most early tool-using agents represented an action as natural language or a JSON object containing a tool name and arguments. Researchers Xingyao Wang, Yangyi Chen, Lifan Yuan, Yizhe Zhang, Yunzhu Li, Hao Peng, and Heng Ji asked whether executable Python would be a more expressive action format.

Their paper, “Executable Code Actions Elicit Better LLM Agents”, was released in February 2024 and appeared at ICML 2024. It evaluated 17 language models on API-Bank and the paper's M³ToolEval benchmark. The authors reported that code actions achieved success rates up to 20% higher than the text and JSON action formats tested.

The paper also introduced CodeActInstruct, a dataset of 7,000 multi-turn interactions, and CodeActAgent models fine-tuned to execute code, observe results, revise failed programs, and continue the conversation. These are research results on the paper's tasks; they do not mean code actions are automatically better for every product.

Why would I use CodeAct?

CodeAct

CodeAct is compelling when the agent must combine tools with computation. It gives the model a familiar language for expressing logic while your application retains the tool and runtime boundaries.

01

Compose several tools

A script can call several approved tools and pass one result directly into the next step.

02

Use real control flow

Loops, conditions, variables, sorting, filtering, and arithmetic are expressed directly in code.

03

Reduce model round trips

Work that would require several tool-selection turns can sometimes be expressed in one generated script.

04

Keep intermediate data local

The runtime can filter or aggregate large tool results before deciding what belongs in the model transcript.

05

Correct executable mistakes

A syntax error, exception, or failed assertion can become an observation the model uses to revise the next script.

06

Inspect the action

Developers can read the generated program, tool calls, outputs, and checkpoints as an execution trail.

Trade-offs

When should I avoid it?

One simple action

A normal LlmAgent tool call is easier when the request maps cleanly to one business operation.

Weak code generation

A model that struggles to write valid code may need more correction turns than structured tool calling.

No safe runtime

Generated code needs an interpreter with explicit access and resource limits. Never pass it to unrestricted eval or exec.

Full software development

Use CodingAgent when the goal is editing repositories, running shell commands, or operating a development workspace.

How ADK-Rust implements CodeAct

CodeAct works inside the ADK-Rust runtime.

CodeActAgent is an agent type alongside LlmAgent. You give it a model, a CodeRuntime, and Rust tools. You then run it through the same Runner, session, event, callback, authorization, and output systems used by other ADK-Rust agents.

1. Model

Choose any ADK-Rust model provider capable of producing reliable code.

2. CodeRuntime

Use the Monty-backed Python runtime or implement the language-agnostic CodeRuntime trait.

3. Rust tools

Register typed tools. The script can reach only the tools supplied for that invocation.

4. Runner

Run the agent with a user and session, then consume normal typed ADK-Rust events.

5. Session

Persist checkpoints when approval or a long-running tool pauses the program.

6. Controls

Apply confirmation, retries, timeouts, callbacks, guardrails, and validated outputs.

Fastest working start

Run the checked-in example first.

It uses a deterministic model, a real Monty Python interpreter, two Rust tools, an in-memory session, and the ADK-Rust Runner. No model API key is required.

The Monty adapter is currently an experimental Git dependency and requires Rust 1.95+, so the example carries its own toolchain file.

terminal
git clone https://github.com/zavora-ai/adk-rust.git
cd adk-rust/examples/codeact_monty_agent

# This example selects Rust 1.95 automatically.
cargo run
verified output
=== ADK-Rust CodeAct × Monty (Python) example ===

[cart_assistant]
{
  "lines": 3,
  "region": "CA",
  "subtotal": 132.0,
  "tax_rate": 0.0725,
  "total": 141.57,
  "user": "u-42"
}

Done.

Architecture

The script runs inside the agent system.

The model proposes executable logic. The CodeRuntime controls how that logic advances. ADK-Rust owns every external action, durable checkpoint, and event that the application sees.

ADK-Rust CodeAct architectureA request moves through the Runner and CodeAct agent into a code runtime. Tool calls cross back into ADK-Rust while runtime policy and session checkpoints control execution.One request, one executable plan, controlled at every boundarySolid arrows carry the request and result. Dashed arrows show suspension, policy, and durable state.Productuser requestRunnersession + contextCodeActAgentmodel ↔ script loopCodeRuntimestart · pause · resumeScriptOutputresult · observe · transferADK-Rust toolsauth · retry · callbacksSession statedurable checkpointRuntime policyfiles · env · limitscall_tool pauses the interpreter; the host resolves the call and resumes the same continuation

Model

Writes a script using the runtime briefing and the tools available for this invocation.

CodeRuntime

Runs the script step by step and exposes calls, completion, stdout, and script errors.

ADK-Rust host

Executes tools with authorization and context, persists state, and streams the final result.

Source-backed execution walkthrough

Case study: price a shopping cart in one CodeAct turn.

This follows the deterministic CodeAct × Monty example in the ADK-Rust repository. Select each boundary to see which part of the system is working and what becomes visible to the next part.

Runner

The request enters ADK-Rust

The Runner attaches the user, session, invocation context, callbacks, and available tools before the CodeAct agent begins.

Visible signal

What's the total for cart u-42, including CA tax?

1 of 6

Choose the right agent shape

CodeAct has a specific job.

Use it when a model can express the work more clearly as a program. ADK-Rust also provides agent shapes for conversational tool use and full software-development environments.

LlmAgent

Choose and call tools conversationally.

Best for: Questions, dialogue, isolated business actions, and natural handoffs.

model → tool → model

CodeActAgent

Compose tools and logic in one executable plan.

Best for: Analysis, data transformation, batch work, calculations, and conditional flows.

model → script ↔ tools → result

CodingAgent

Work inside a software-development harness.

Best for: Repository editing, shell commands, builds, tests, patches, and coding-agent protocols.

agent ↔ workspace + shell

Monty runtime

Give generated code a clear operating boundary.

ADK-Rust's current Python adapter runs Monty in-process. The host decides what the script can read, write, know, and consume before execution begins.

Monty is still experimental. It is currently a pinned Git dependency and requires Rust 1.95+. The adapter lives in its own crate until Monty is available on crates.io.

Default sandbox

No filesystem access and an empty environment. Network and subprocess operations have no Monty surface.

Explicit mounts

Map selected host directories to virtual paths and choose read-only or read-write access for each one.

Resource limits

Set a time cap and memory cap for every advance. Serialized continuations retain those limits when resumed.

One tool form

Scripts call call_tool(name, args). Exact named arguments survive serialization and bind centrally in ADK-Rust.

Controlled environment

Expose only the environment values the task needs. Host process secrets are never inherited automatically.

Visible failures

Syntax errors and exceptions return to the model as fixable script feedback; host runtime failures stop the run.

Durable execution

A paused program can become durable agent state.

Confirmation-gated and long-running tools may need the request to end before the answer exists. CodeAct snapshots the paused interpreter, its transcript, and pending call into the session so another invocation can continue from the same line of code.

01

Save before

Persist the continuation before an external tool is allowed to run.

02

Resolve

Execute, approve, reject, or wait for the pending tool result.

03

Save after

Persist the returned value so recovery does not repeat a completed call.

04

Resume

Load the checkpoint and continue the same script from its call boundary.

Developer responsibility: a crash after an external side effect but before the save-after checkpoint may cause that tool to run again. Give non-idempotent tools an idempotency key or another duplicate-action guard.

Implementation

Four pieces define the complete agent.

Choose a model, supply a CodeRuntime, register the tools the script may call, and run the agent through the normal ADK-Rust Runner.

ADK-Rust v2
use std::sync::Arc;
use adk_agent::codeact::CodeActAgent;
use adk_codeact_monty::MontyRuntime;

let runtime = MontyRuntime::builder()
    .environ_var("CART_USER", "u-42")
    .environ_var("TAX_REGION", "CA")
    .system_clock(true)
    .build();

let agent = CodeActAgent::builder()
    .name("cart_assistant")
    .model(model)
    .runtime(Arc::new(runtime))
    .instruction("Price the cart by writing Python.")
    .tool(Arc::new(fetch_cart))
    .tool(Arc::new(tax_rate))
    .output_key("priced_cart")
    .build()?;

Build with CodeAct

Turn a multi-step tool conversation into one readable program.

Start with the deterministic example, inspect every pause and resume, then connect the model and tools your product already uses.