Running Your Agents πŸš€

How to trigger agent runs, stream tokens, hook into execution events, and capture results.

Running a Kern Agent kicks off a stateful orchestration loop. Behind the scenes:

  1. Context Assembly: The agent builds the conversation payload (system prompt, user messages, history context, database preferences, and session variables).
  2. Model Reasoning: This packet is sent to your model.
  3. Tool Loop: If the model decides it needs to use a tool, it calls the tool. The agent executes it, appends the result, and sends it back to the model.
  4. Final Delivery: Once the model is done looping, the agent wraps up the execution and returns the final answer.

Let's look at how to trigger and control this execution!


🏁 Basic Execution

Trigger your agent using the synchronous Agent.run() method. This returns a RunOutput helper object:

1from kern.agent import Agent, RunOutput
2from kern.models.openai import OpenAIChat
3from kern.tools.hackernews import HackerNewsTools
4from kern.utils.pprint import pprint_run_response
5
6# Wire up the agent using a local Ollama model
7agent = Agent(
8 model=OpenAIChat(id="llama3.2:3b", base_url="http://localhost:11434/v1"),
9 tools=[HackerNewsTools()],
10 instructions="Give a short status report.",
11 markdown=True,
12)
13
14# Fire! 🎯
15response: RunOutput = agent.run("Show me trending topics on HackerNews")
16
17# Print the response nicely formatted as markdown
18pprint_run_response(response, markdown=True)

πŸ“¦ What's inside RunOutput?

When you call Agent.run(), you get back a RunOutput object containing rich metadata about the run. Here are the most useful attributes:

  • content: The text response returned by the model.
  • run_id: A unique UUID for tracking this specific run.
  • session_id: The ID of the session (useful for history).
  • user_id: The ID of the user who triggered the run.
  • messages: The complete list of messages (prompts, tool calls, and tool outputs) sent to and from the model.
  • metrics: Token usage counts, execution durations, and tool metrics.

🌊 Streaming Text Response

For real-time user interfaces, you want to stream tokens as they are generated by the model. Just pass stream=True:

1from typing import Iterator
2from kern.agent import Agent, RunOutputEvent, RunEvent
3from kern.models.openai import OpenAIChat
4
5agent = Agent(
6 model=OpenAIChat(id="llama3.2:3b", base_url="http://localhost:11434/v1"),
7 instructions="You are a poet.",
8)
9
10# Stream the text chunks as they arrive 🌊
11stream: Iterator[RunOutputEvent] = agent.run("Write a haiku about local LLMs", stream=True)
12for chunk in stream:
13 if chunk.event == RunEvent.run_content:
14 print(chunk.content, end="", flush=True)

πŸ“‘ Rich Event Streams

If you are building a custom UI (like a web dashboard or agent console), you might want to show the user exactly what the agent is doing in real-time (e.g. "Calling HackerNews API", "Thinking...").

Set stream_events=True to receive a stream containing all system events (tool starts, tool completions, reasoning steps, memory updates, etc.):

1from kern.agent import Agent, RunEvent
2from kern.models.openai import OpenAIChat
3from kern.tools.hackernews import HackerNewsTools
4
5agent = Agent(
6 model=OpenAIChat(id="llama3.2:3b", base_url="http://localhost:11434/v1"),
7 tools=[HackerNewsTools()],
8)
9
10# Listen to everything happening under the hood πŸ“‘
11stream = agent.run("Summarize HackerNews news", stream=True, stream_events=True)
12
13for chunk in stream:
14 if chunk.event == RunEvent.run_content:
15 print(chunk.content, end="", flush=True)
16 elif chunk.event == RunEvent.tool_call_started:
17 print(f"\n[πŸ› οΈ Tool Started] Running: {chunk.tool.tool_name}...")
18 elif chunk.event == RunEvent.tool_call_completed:
19 print(f"\n[βœ… Tool Done] Got output length: {len(chunk.tool.tool_output)}")

πŸ“‘ Core Event Reference

Here are the system event types you can listen to in your event loops:

Event GroupEvent TypeDescription
LifecycleRunStartedThe engine has booted up for this run.
RunCompletedThe run finished successfully.
RunErrorAn exception was raised during execution.
RunCancelledThe execution was aborted.
OutputRunContentA text chunk generated by the model.
RunContentCompletedModel has finished generating response text.
ToolsToolCallStartedThe agent is executing a tool function.
ToolCallCompletedThe tool function has returned its output.
ReasoningReasoningStartedThe model is performing thinking steps.
ReasoningStepA reasoning trace chunk has arrived.
ReasoningCompletedThinking process completed.
MemoryMemoryUpdateStartedExtracted facts are being updated.
MemoryUpdateCompletedMemory transaction saved to database.

πŸ”§ Run Context Configuration

πŸ‘€ User & Session Association

Group runs by user and thread to maintain session memory across requests:

1agent.run("My name is Alice", user_id="user_42", session_id="thread_abc")

πŸ–ΌοΈ Multimodal Inputs

Send images, audio, video, or files along with the run instruction:

1from kern.media import Image
2agent.run("Describe this layout", images=[Image(url="https://example.com/mockup.png")])

🎯 Custom Event Types

Define and yield custom telemetry data structures from your tools:

1from dataclasses import dataclass
2from kern.run.agent import CustomEvent
3
4@dataclass
5class JobStatusEvent(CustomEvent):
6 status_msg: str
7
8# Inside a custom tool:
9# yield JobStatusEvent(status_msg="Connecting to cluster...")

⏸️ Pause, Cancel & Background Runs