Quickstart¶
This is the shortest useful Ravi program.
import asyncio
from ravi.agents import ReActAgent, Runtime
from ravi.agents.context import ContextConfig, InMemoryHistoryProvider
from ravi.integrations.llm.openai import OpenAIClient
from ravi.kernel import Message, ChatPayload, ChatMessage, Role, TextBlock
from ravi.kernel.core.identity import AgentId
async def main() -> None:
# 1. Initialize the LLM client and the ReActAgent
client = OpenAIClient(api_key="sk-...", model="gpt-4o")
agent = ReActAgent(
"DemoBot",
model=client,
context=ContextConfig(InMemoryHistoryProvider()),
)
# 2. Run the agent via the Runtime
async with Runtime() as rt:
await rt.register(agent)
# 3. Submit a message and await completion
msg = Message(
target=agent.id,
sender=AgentId(type="proxy", key="user"),
payload=ChatPayload(
message=ChatMessage(
role=Role.USER,
content=[TextBlock(text="Why do agents need runtimes?")]
)
),
)
run_id = await rt.submit(agent.id, msg)
async for entry in rt.event_log.tail(run_id):
if entry.kind in ("run.completed", "run.failed", "run.cancelled"):
break
# 4. Extract and print the final assistant turn response
history = await agent.history.get_messages(agent.id, session_id=run_id)
for m in reversed(history):
if m.role == Role.ASSISTANT:
print("Response:", " ".join(b.text for b in m.content if isinstance(b, TextBlock)))
break
if __name__ == "__main__":
asyncio.run(main())
What happened¶
OpenAIClienttranslates Ravi messages into provider API calls.UnboundedMemorystores the conversation in process.ReActAgentruns a bounded Think → Act → Observe loop.- Since there are no tools here, the model produces a direct answer.
What to do next¶
- Add tools with Create A Tool
- Learn the lifecycle in Agent Lifecycle
- Move to the durable runtime in First Durable Run