"""Example runners for kodeagent.
This module contains helper functions to run the bundled example agents from
user code. The API exposes a synchronous `run_examples` function plus an
`async def main()` kept for script usage.
"""
import asyncio
import os
import random
import sys
from typing import Any
import rich
from . import tools as dtools
from .fca import FunctionCallingAgent
from .kodeagent import CodeActAgent, ReActAgent, print_response
async def _run_examples_async(
agent_type: str, max_iterations: int, model_name: str = 'gemini/gemini-2.0-flash-lite'
) -> None:
"""Run the example agent demos asynchronously.
Args:
agent_type: Which agent to run; one of 'react', 'codeact', or 'fca'.
max_iterations: Maximum iterations/steps for the agent.
model_name: Which model to use for the agent.
"""
litellm_params: dict[str, Any] = {'temperature': 0, 'timeout': 30}
def _make_react_agent() -> ReActAgent:
return ReActAgent(
name='Simple agent',
model_name=model_name,
tools=[
dtools.calculator,
dtools.search_web,
dtools.read_webpage,
dtools.extract_as_markdown,
],
max_iterations=max_iterations,
litellm_params=litellm_params,
# tracing_type='langfuse',
)
def _make_code_agent() -> CodeActAgent:
return CodeActAgent(
name='Simple agent',
model_name=model_name,
tools=[
dtools.calculator,
dtools.search_web,
dtools.read_webpage,
dtools.extract_as_markdown,
],
max_iterations=max_iterations,
litellm_params=litellm_params,
run_env='host',
allowed_imports=[
'math',
'datetime',
'time',
're',
'typing',
'mimetypes',
'random',
'ddgs',
'bs4',
'urllib.parse',
'requests',
'markitdown',
'pathlib',
],
pip_packages='ddgs~=9.10.0;beautifulsoup4~=4.14.3;',
work_dir='./agent_workspace',
# tracing_type='langsmith',
)
def _make_fca_agent() -> FunctionCallingAgent:
return FunctionCallingAgent(
model_name=model_name,
tools=[
dtools.calculator,
dtools.search_web,
dtools.read_webpage,
dtools.extract_as_markdown,
],
litellm_params=litellm_params,
)
the_tasks = [
('What is ten plus 15, raised to 2, expressed in words?', None),
('What is the date today? Express it in words like <Month> <Day>, <Year>.', None),
(
'Which image has a purple background?',
[
(
'https://www.slideteam.net/media/catalog/product/cache/1280x720'
'/p/r/process_of_natural_language_processing_training_ppt_slide01.jpg'
),
(
'https://cdn.prod.website-files.com/61a05ff14c09ecacc06eec05'
'/66e8522cbe3d357b8434826a_ai-agents.jpg'
),
],
),
(
'What is four plus seven? Also, what are the festivals in Paris?'
' How they differ from Kolkata?',
None,
),
('Write an elegant haiku in Basho style. Save it as poem.txt', None),
]
async def _run_with_agent(agent: Any) -> None:
"""Run the example tasks with the given agent and print results.
Args:
agent: An agent instance with an async .run() method.
"""
print(f'{agent.__class__.__name__} demo\n')
for task, img_urls in the_tasks:
rich.print(f'[yellow][bold]User[/bold]: {task}[/yellow]')
async for response in agent.run(task, files=img_urls):
print_response(response, only_final=True)
if getattr(agent, 'artifacts', None):
print('Artifacts generated:')
for art in agent.artifacts:
print(f'- {art} (size: {os.path.getsize(art)} bytes)')
if getattr(agent, 'current_plan', None):
print(f'Plan:\n{agent.current_plan}')
await asyncio.sleep(random.uniform(0.15, 0.55))
print('\n\n')
print('Demonstrating recurrent mode:\n')
async for response in agent.run('Find the population of France in 2023'):
print_response(response, only_final=True)
async for response in agent.run(
'What would it be with a 0.5% growth?',
recurrent_mode=True,
):
print_response(response, only_final=True)
print('\n\nDemonstrating Chat History Injection:\n')
# Initial history from a previous session or external storage
history = [
{'role': 'user', 'content': 'What is 5 + 5?'},
{
'role': 'assistant',
'content': 'I will calculate 5 + 5.',
'tool_calls': [
{
'id': 'call_123',
'type': 'function',
'function': {
'name': 'calculator',
'arguments': '{"expression": "5 + 5"}',
},
}
],
},
{'role': 'tool', 'tool_call_id': 'call_123', 'name': 'calculator', 'content': '10.0'},
{'role': 'assistant', 'content': 'The result is 10.0.'},
]
print('Resuming with existing history...')
async for response in agent.run('Now add 20 to that result', chat_history=history):
print_response(response, only_final=True)
atype = agent_type.lower()
if atype == 'codeact':
agent = _make_code_agent()
elif atype == 'react':
agent = _make_react_agent()
elif atype == 'fca':
agent = _make_fca_agent()
else:
raise ValueError(f'Unknown agent_type: {agent_type}')
await _run_with_agent(agent)
[docs]
async def run_examples(
agent_type: str = 'react',
max_iterations: int = 5,
model_name: str = 'gemini/gemini-2.0-flash-lite',
) -> None:
"""Run KodeAgent with a list of pre-defined tasks and the choice of agent.
Some of the tasks include files or URLs.
The demo includes demonstrations of `recurrent_mode` and `chat_history` injection.
Args:
agent_type: Which agent to run; one of `react`, `codeact`, or `fca`.
max_iterations: Maximum iterations/steps for the agent.
model_name: Which model to use for the agent (LiteLLM style).
"""
await _run_examples_async(agent_type, max_iterations, model_name)
if __name__ == '__main__':
os.environ['PYTHONUTF8'] = '1'
# Simple CLI handling for demo purposes
selected_atype = 'react'
if len(sys.argv) > 1:
for arg in sys.argv[1:]:
if arg.startswith('--agent_type='):
selected_atype = arg.split('=', 1)[1] or 'react'
elif arg in ['react', 'codeact', 'fca']:
selected_atype = arg
asyncio.run(run_examples(agent_type=selected_atype))