exoclaw-turn
Run a single exoclaw agent turn as a library call — no bus, no channels, no persistence.
pip install exoclaw-turn
Why
Most of exoclaw is built around the bus-driven multi-turn model: messages come in on a channel, the agent loop processes them, replies go back out. That shape is right for bots and assistants, but overkill when you just want to call an agent like a function — get one bounded run, with tool dispatch, and a return value.
run_turn is that front door. It spins up an ephemeral AgentLoop with a throwaway MessageBus and an in-memory conversation, drives a single turn to completion, and returns the result. Everything the agent loop already does — compaction on context overflow, loop detection, plugin context collection, subagent chain tracking, tool dispatch — carries over unchanged.
Usage
from exoclaw_turn import run_turn
from exoclaw_provider_litellm.provider import LiteLLMProvider
from exoclaw_openrouter_search.tool import OpenRouterSearchTool
provider = LiteLLMProvider(default_model="claude-sonnet-4-6")
result = await run_turn(
provider=provider,
system="You are a research assistant. Be terse.",
message="What's the population of Reykjavik?",
tools=[OpenRouterSearchTool()],
)
print(result.text) # final assistant reply
print(result.tool_calls) # tools the model invoked, in order
print(result.messages) # all new messages produced this turn
Anything implementing the exoclaw.agent.tools.protocol.Tool protocol works as a tool — every tool plugin in the exoclaw-plugins catalog drops in unchanged.
What it inherits from AgentLoop
run_turn owns no agent behaviour of its own. It assembles the loop and reshapes the result. That means whatever lives in AgentLoop today is available through this front door:
- Context-window compaction. Long tool chains that overflow the model's context window trigger
Conversation.recover_from_overflowif implemented — for the ephemeral conversation it isn't, so the originalContextWindowExceededErrorsurfaces. Pass a longer-lived conversation if you need recovery. - Loop detection. Pass
iteration_policy=...(e.g. fromexoclaw-loop-detection) to terminate based on tool-call patterns instead of a hard count. - Tool dispatch. Tools execute through the same
ToolRegistrythe bus-driven path uses. - Subagent chain tracking. If you call
run_turnfrom inside another turn, the trace contextvars (turn.id,turn.parent_id,turn.chain) extend the parent's ancestry — same logging hierarchy asexoclaw-subagent.
Parameters
| Parameter | Type | Default | Notes |
|---|---|---|---|
provider |
LLMProvider |
required | Any provider — LiteLLM, OpenAI, etc. |
message |
str |
required | The user message that seeds the turn. |
system |
str | None |
None |
System prompt. Plugin context from tools is appended. |
tools |
list[Tool] | None |
None |
Anything implementing Tool. |
model |
str | None |
provider default | Override the provider's default for this turn. |
max_iterations |
int |
40 |
Hard cap on tool-call iterations. |
temperature |
float |
0.1 |
Forwarded to provider. |
max_tokens |
int |
4096 |
Forwarded to provider. |
reasoning_effort |
str | None |
None |
Forwarded to provider for reasoning models. |
iteration_policy |
IterationPolicy | None |
None |
Replace the hard count with pattern-based termination. |
on_progress |
Callable | None |
None |
Async progress callback. |
What it doesn't do
- No persistence. State is dropped at end of turn. For multi-turn conversations, use the bus-driven
AgentLoopdirectly, or build on top ofexoclaw-conversation. - No streaming result. The function awaits the full turn before returning. Use
on_progressfor incremental feedback if you need it. - No multimodal attachments. The ephemeral conversation doesn't encode media into the user message content. For image/file inputs, use a bus-driven
AgentLoopwith a realConversationimplementation. - No channel. This is library-shaped. For an interactive REPL, use
exoclaw-channel-cli.
Release files for exoclaw-turn 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| exoclaw_turn-0.1.0.tar.gz | 5.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| exoclaw_turn-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 11.3 kB
Release files / exoclaw_turn-0.1.0.tar.gz
| Download URL | exoclaw_turn-0.1.0.tar.gz |
|---|---|
| Size | 5.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a75ec6bfc054fd105433155bbf11ff6ea5d346e3ec9f86db65d9a183534b1e6f
|
|
BLAKE2b-256 checksum How to use checksums |
71b2b0a8f6b483d9dc9d03b0b37e437df44e9c263a749aabb27584a50972f203
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / exoclaw_turn-0.1.0-py3-none-any.whl
| Download URL | exoclaw_turn-0.1.0-py3-none-any.whl |
|---|---|
| Size | 6.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
35b3f56d4df28720542b6024ff991524cf827187ec842cc6d00aecd25dcdffc3
|
|
BLAKE2b-256 checksum How to use checksums |
f6a627ef5dca2a0dfa6d02c1ed84562246fb9a1a256895ba1f747ccb7645b134
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|