Skip to main content

State Management

O StateManager gerencia o estado volátil da sessão — dados descartados quando a conversa termina. Use para flags de controle, configurações temporárias e informações de negócio que não precisam ser enviadas ao LLM como contexto.

State vs Memory
StateMemory
PropósitoControle interno e regras de negócioContexto enviado ao LLM
Visibilidade para o LLM❌ Não✅ Sim
PersistênciaDura a sessãoPersistente entre sessões
Uso típicoFlags, etapas de workflow, dados temporáriosFatos do usuário, preferências, histórico

Use MemoryManager quando quiser que os dados influenciem as respostas do LLM.

Inicialização

from actions_sdk.core.types.action_context import ActionContext
from actions_sdk.features.conversational.state import StateManager

ctx: ActionContext

state = StateManager(ctx)

O StateManager extrai ctx.initial_state e ctx.state_protected_keys automaticamente no construtor.


Métodos

update(path, value)

Define ou insere um valor no estado. Cria dicionários intermediários automaticamente.

# Chave simples
state.update("etapa", "validacao")

# Notação por ponto — cria {"usuario": {"nome": "Alice"}}
state.update("usuario.nome", "Alice")
state.update("usuario.cpf", "123.456.789-00")

# Valor booleano
state.update("flags.aceite_termos", True)

Parâmetros:

ParâmetroTipoDescrição
pathstr | list[str]Chave ou caminho com notação por ponto
valueAnyValor a definir
model_classType[BaseModel] | NoneModelo Pydantic para validação antes de persistir

Retorna: True se bem-sucedido.

Exceções:

  • PermissionError — se o caminho referenciar uma chave protegida

get(path, default=None)

Recupera um valor do estado.

etapa = state.get("etapa")                         # None se não existir
nome = state.get("usuario.nome", "Desconhecido") # Default customizado
cpf = state.get("usuario.cpf")

Parâmetros:

ParâmetroTipoDescrição
pathstr | list[str]Chave ou caminho com notação por ponto
defaultAnyValor retornado se o caminho não existir (padrão: None)
model_classType[BaseModel] | NoneModelo Pydantic para validar o retorno

Exceções:

  • ValidationError — se model_class for fornecido e a validação falhar

delete(path)

Remove um valor do estado. Retorna o valor removido, ou None se não existir.

valor_removido = state.delete("etapa")
state.delete("usuario.cpf")

Parâmetros:

ParâmetroTipoDescrição
pathstr | list[str]Caminho do valor a remover

Retorna: Valor removido ou None.

Exceções:

  • PermissionError — se o caminho referenciar uma chave protegida

merge(path, data)

Realiza merge raso de um dicionário no estado no caminho informado. Útil para atualizar múltiplos campos de um objeto sem sobrescrever tudo.

# State: {"usuario": {"nome": "Alice"}}
state.merge("usuario", {"cpf": "123", "telefone": "11999"})
# Resultado: {"usuario": {"nome": "Alice", "cpf": "123", "telefone": "11999"}}

Parâmetros:

ParâmetroTipoDescrição
pathstr | list[str]Caminho de destino
datadict | BaseModelDicionário ou modelo Pydantic para mesclar

Retorna: True se bem-sucedido.

Exceções:

  • PermissionError — se o caminho referenciar uma chave protegida

has_key(key)

Verifica se uma chave de raiz existe no estado.

if state.has_key("usuario"):
nome = state.get("usuario.nome")

Parâmetros: key (str) — chave de raiz.

Retorna: bool


get_full_state()

Retorna uma cópia rasa do dicionário completo de estado. Use sempre no campo state_updates do retorno da action.

return ResponseToAgent(
status=ResponseStatus.SUCCESS,
instruction="Operação concluída.",
state_updates=state.get_full_state(),
)

Retorna: dict[str, Any]


Notação por ponto

O StateManager suporta caminhos aninhados com . em qualquer profundidade:

state.update("pedido.itens.0.status", "processando")
state.update("pedido.itens.0.valor", 99.90)

status = state.get("pedido.itens.0.status") # "processando"

Dicionários intermediários são criados automaticamente.


Chaves protegidas

Algumas chaves são marcadas como protegidas pelo motor e não podem ser sobrescritas ou deletadas:

# PermissionError — chave protegida
state.delete("files")
state.update("files", [])

Para listas protegidas, apenas append é permitido (a nova lista deve estender a atual sem modificar itens existentes).


Validação com Pydantic

from pydantic import BaseModel

class DadosUsuario(BaseModel):
nome: str
cpf: str

# Salvar com validação
state.update("usuario", {"nome": "Alice", "cpf": "123"}, model_class=DadosUsuario)

# Ler como modelo
dados: DadosUsuario = state.get("usuario", model_class=DadosUsuario)
print(dados.nome) # "Alice"

Exemplo completo

Baseado nas actions de homologação do SDK v2:

import traceback

from actions_sdk.core.types.action_context import ActionContext
from actions_sdk.core.types.responses import ResponseStatus, ResponseToAgent
from actions_sdk.features.conversational.state import StateManager
from actions_sdk.features.tracing import ActionSpan

ctx: ActionContext

CHAVE_PROGRESSO = "minha_action.progresso"


def processar_pedido(pedido_id: str):
span = ActionSpan(ctx)
state = StateManager(ctx)

span.event("action.processar_pedido.inicio", {"pedido_id": pedido_id})

try:
# Salvar andamento no state
state.update(CHAVE_PROGRESSO, "buscando_pedido")
state.update("pedido.id", pedido_id)
state.update("pedido.status", "em_processamento")

# ... lógica de negócio ...

valor_confirmado = state.get("pedido.id")
state.update(CHAVE_PROGRESSO, "concluido")

return ResponseToAgent(
status=ResponseStatus.SUCCESS,
instruction=f"Pedido {valor_confirmado} processado com sucesso.",
state_updates=state.get_full_state(),
)

except Exception as erro:
state.update(CHAVE_PROGRESSO, "erro")
span.event("action.processar_pedido.erro", {"erro": str(erro)})
return ResponseToAgent(
status=ResponseStatus.ERROR,
instruction=f"Falha ao processar pedido: {traceback.format_exc()}",
state_updates=state.get_full_state(),
)