Skip to main content

Events

litellm.agent(..., stream=True) yields eight kinds of event. Each adapter translates its runtime's native events into these.

from litellm.harness import (
Text, Reasoning, ToolCall, ToolResult, FileChange, Compaction, Approval, Done,
)

for event in litellm.agent(Harness.CLAUDE_CODE, "Add type hints to utils.py", sandbox=box, model="litellm_proxy/coder", stream=True):
match event:
case Text(delta=d):
print(d, end="")
case Reasoning():
pass
case ToolCall(name=name, input=args):
log.info("tool %s %s", name, args)
case ToolResult(is_error=True, output=out):
log.warning("tool failed: %s", out)
case ToolResult():
pass
case FileChange(kind=kind, path=path):
changed.append(path)
case Compaction():
pass
case Approval() as a:
a.allow() if a.tool == "read" else a.deny("read-only review")
case Done(cost=cost):
print(f"\n${cost:.4f}")

That match has no case _. Event is a closed union, so mypy and pyright both treat it as exhaustive.

EventFieldsNotes
TextdeltaAssistant text, streamed.
ReasoningdeltaOnly when the model and the harness emit it.
ToolCallid, name, native_name, input, builtinbuiltin is False for your own tools=.
ToolResultid, output, is_errorPaired with ToolCall.id.
FileChangepath, kind, diffkind is "created", "modified" or "deleted". diff is a unified diff for text files up to 256 KB, else None.
Compactiontokens_before, tokens_afterThe runtime summarized its own history.
Approvaltool, input, allow(), deny(reason)Only from harnesses with tool approval.
Doneresult, usage, cost, stop_reasonAlways the last event, exactly once.

FileChange events come from diffing a sandbox snapshot taken before and after each turn, so edits appear even when the runtime doesn't report them as a tool call.

Tool names​

Built-in tools that do the same thing get the same name on every harness, so UI code doesn't need a branch per runtime. native_name always has the runtime's original name.

nameClaude CodeCodexOpenCodeDeep Agents
readReadreadread_file
writeWritewritewrite_file
editEditeditedit_file
bashBashcommand executionbashexecute
globGlobglobglob
grepGrepgrepgrep
lsLSlistls
web_searchWebSearchweb searchwebfetch

Tools that aren't in this table keep their native name in name.

Stream result​

stream = litellm.agent(Harness.OPENCODE, prompt, sandbox=box, model="litellm_proxy/coder", stream=True)
for event in stream:
render(event)
result = stream.result # the same Result the Done event carries
LiteLLM Enterprise
SSO/SAML, audit logs, spend tracking, multi-team management, and guardrails, built for production.
Learn more →