Runner
O tempo de execução de adk-runner que orquestra a execução do Agent.
Visão Geral
O Runner gerencia o ciclo de vida completo da execução do Agent:
- Gerenciamento de Session (criar/recuperar Sessions)
- Injeção de memória (pesquisar e injetar memórias relevantes)
- Manipulação de artefatos (acesso a artefatos com escopo)
- Streaming de eventos (processar e encaminhar eventos)
- Transferências de Agent (lidar com repasses multi-Agent)
Instalação
[dependencies]
adk-runner = "0.2.0"
RunnerConfig
Configure o Runner com os serviços necessários:
use adk_runner::{Runner, RunnerConfig};
use adk_session::InMemorySessionService;
use adk_artifact::InMemoryArtifactService;
use std::sync::Arc;
let config = RunnerConfig {
app_name: "my_app".to_string(),
agent: Arc::new(my_agent),
session_service: Arc::new(InMemorySessionService::new()),
artifact_service: Some(Arc::new(InMemoryArtifactService::new())),
memory_service: None,
run_config: None,
};
let runner = Runner::new(config)?;
Campos de Configuração
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
app_name | String | Sim | Identificador da aplicação |
agent | Arc<dyn Agent> | Sim | Agent raiz a ser executado |
session_service | Arc<dyn SessionService> | Sim | Backend de armazenamento de Session |
artifact_service | Option<Arc<dyn ArtifactService>> | Não | Armazenamento de artefatos |
memory_service | Option<Arc<dyn Memory>> | Não | Memória de longo prazo |
run_config | Option<RunConfig> | Não | Opções de execução |
Executando Agents
Execute um Agent com entrada do usuário:
use adk_core::Content;
use futures::StreamExt;
let user_content = Content::new("user").with_text("Hello!");
let mut stream = runner.run(
"user-123".to_string(),
"session-456".to_string(),
user_content,
).await?;
while let Some(event) = stream.next().await {
match event {
Ok(e) => {
if let Some(content) = e.content() {
for part in &content.parts {
if let Some(text) = part.text() {
print!("{}", text);
}
}
}
}
Err(e) => eprintln!("Error: {}", e),
}
}
Fluxo de Execução
┌─────────────────────────────────────────────────────────────┐
│ Runner.run() │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 1. Recuperação da Sessão │
│ │
│ SessionService.get(app_name, user_id, session_id) │
│ → Cria nova sessão se não existir │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. Seleção do Agent │
│ │
│ Verifica o estado da sessão para o Agent ativo │
│ → Usa o Agent raiz ou o Agent transferido │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. Criação do Contexto │
│ │
│ InvocationContext com: │
│ - Session (mutável) │
│ - Artefatos (com escopo na sessão) │
│ - Memória (se configurado) │
│ - Run config │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. Execução do Agent │
│ │
│ agent.run(ctx) → EventStream │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 5. Processamento de Eventos │
│ │
│ Para cada evento: │
│ - Atualiza o estado da sessão │
│ - Lida com as transferências │
│ - Encaminha para o chamador │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 6. Salvamento da Sessão │
│ │
│ SessionService.append_event(session, events) │
└─────────────────────────────────────────────────────────────┘
Contexto de Invocação
O contexto fornecido aos agents durante a execução:
pub trait InvocationContext: CallbackContext {
/// O agent sendo executado
fn agent(&self) -> Arc<dyn Agent>;
/// Serviço de memória (se configurado)
fn memory(&self) -> Option<Arc<dyn Memory>>;
/// Session atual
fn session(&self) -> &dyn Session;
/// Configuração de execução
fn run_config(&self) -> &RunConfig;
/// Sinaliza o fim da invocação
fn end_invocation(&self);
/// Verifica se a invocação terminou
fn ended(&self) -> bool;
}
RunConfig
Opções de execução:
pub struct RunConfig {
/// Modo de streaming para respostas
pub streaming_mode: StreamingMode,
}
pub enum StreamingMode {
/// Sem streaming, retorna a resposta completa
None,
/// Server-Sent Events (padrão)
SSE,
/// Streaming bidirecional (em tempo real)
Bidi,
}
Nota: Campos adicionais como
max_turnseinclude_historyestão planejados para futuras versões.
Transferências de Agent
O Runner lida com transferências multi-agent automaticamente:
// Em uma tool ou callback de um agent
if should_transfer {
// Define a transferência nas ações do evento
ctx.set_actions(EventActions {
transfer_to_agent: Some("specialist_agent".to_string()),
..Default::default()
});
}
O Runner irá:
- Detectar a solicitação de transferência no evento
- Encontrar o agent alvo em sub_agents
- Atualizar o estado da session com o novo agent ativo
- Continuar a execução com o novo agent
Integração com o Launcher
O Launcher usa o Runner internamente:
// O Launcher cria o Runner com serviços padrão
Launcher::new(agent)
.app_name("my_app")
.run()
.await?;
// Equivalente a:
let runner = Runner::new(RunnerConfig {
app_name: "my_app".to_string(),
agent,
session_service: Arc::new(InMemorySessionService::new()),
artifact_service: Some(Arc::new(FileArtifactService::new("./artifacts")?)),
memory_service: None,
run_config: None,
})?;
Uso Customizado do Runner
Para cenários avançados, use o Runner diretamente:
use adk_runner::{Runner, RunnerConfig};
use adk_session::DatabaseSessionService;
use adk_artifact::S3ArtifactService;
use adk_memory::QdrantMemoryService;
// Configuração de produção
let config = RunnerConfig {
app_name: "production_app".to_string(),
agent: my_agent,
session_service: Arc::new(DatabaseSessionService::new(db_pool)),
artifact_service: Some(Arc::new(S3ArtifactService::new(s3_client))),
memory_service: Some(Arc::new(QdrantMemoryService::new(qdrant_client))),
run_config: None, // Usa streaming SSE padrão
};
let runner = Runner::new(config)?;
// Usar em handler HTTP
async fn chat_handler(runner: &Runner, request: ChatRequest) -> Response {
let stream = runner.run(
request.user_id,
request.session_id,
request.content,
).await?;
// Fazer streaming de eventos para o cliente
Response::sse(stream)
}
Anterior: ← Core Types | Próximo: Launcher →