PRD-007 — Agent Tool Runtime & Context Bridge
1. Objetivo
O Agent Tool Runtime & Context Bridge será a camada responsável por conectar o agente à aplicação real.
Até agora temos:
- HAG / Knowledge Base → sabe sobre o sistema;
- Knowledge Router + BM25 → encontra rapidamente conhecimento;
- Capability Registry → define o que o agente pode fazer;
- Intent Engine → entende o que o usuário quer;
- Agent Planner → determina como realizar a tarefa.
Agora falta uma peça fundamental:
O agente precisa saber onde o usuário está, sobre qual objeto está trabalhando e como refletir suas ações na interface.
Essa camada cria a ponte:
┌─────────────────────┐
│ React UI │
│ │
│ page / tab / focus │
│ selection / forms │
└──────────┬──────────┘
│
Context Bridge
│
▼
┌─────────────────────┐
│ Agent Runtime │
└──────────┬──────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
Intent Planner Tools
2. Princípio fundamental
O agente não deve receber o DOM inteiro da aplicação.
Não queremos:
HTML
React Tree
todos os componentes
todos os elementos
todos os textos
Isso seria caro, lento e pouco confiável.
Em vez disso, a aplicação fornecerá um Semantic UI Context compacto.
Exemplo:
{
"application": {
"id": "sst"
},
"route": {
"path": "/work-permits/WP-10231",
"pageId": "workPermit"
},
"activeTab": {
"id": "components"
},
"focus": {
"semanticId": "workPermit.components"
},
"selection": {
"entityType": "workPermit",
"entityId": "WP-10231"
}
}
Isso é muito mais valioso que milhares de elementos do DOM.
3. Problema que queremos resolver
Imagine o usuário estando em:
Permissões de Trabalho
└── WP-10231
├── Dados gerais
├── Componentes
├── Riscos
├── Aprovações
└── Histórico
Na aba:
Componentes
com um componente selecionado.
O usuário simplesmente diz:
“Explique isso.”
O agente deve entender que “isso” provavelmente significa o componente atualmente selecionado.
Não deveria perguntar:
“O que você quer que eu explique?”
4. Context Hierarchy
O Context Bridge deverá fornecer uma hierarquia de referência.
Prioridade:
1. Referência explícita do usuário
2. Entidade selecionada
3. Foco semântico
4. Aba ativa
5. Página atual
6. Breadcrumb
7. Contexto conversacional
8. HAG
9. Inferência geral
Exemplo:
Usuário:
“Altere a validade.”
Contexto:
page = workPermit
tab = details
focus = validity
selection = WP-10231
Resultado:
workPermit.updateValidity
entity = WP-10231
5. Semantic IDs
Este PRD consolida o conceito de Semantic ID utilizado nos PRDs anteriores.
Exemplos:
workPermit
workPermit.details
workPermit.validity
workPermit.components
workPermit.components.item
workPermit.risks
workPermit.approvals
Para entidades:
workPermit:WP-10231
employee:EMP-104
risk:RISK-22
component:COMP-81
Isso cria uma linguagem comum entre:
- React;
- agente;
- HAG;
- capabilities;
- documentação;
- navegação;
- analytics.
6. Semantic UI Registry
A aplicação deverá possuir um registro semântico dos elementos relevantes.
Exemplo:
interface SemanticElement {
semanticId: string;
type:
| 'page'
| 'tab'
| 'section'
| 'field'
| 'table'
| 'entity'
| 'action'
| 'form';
label?: string;
entityType?: string;
capabilityIds?: string[];
documentationRefs?: string[];
}
Exemplo:
semanticId:
workPermit.validity
type:
field
capabilities:
workPermit.updateValidity
documentationRefs:
docs/work-permit/validity
7. Context Snapshot
O frontend deverá produzir um snapshot do contexto atual.
interface SemanticUIContext {
applicationId: string;
route: RouteContext;
page: PageContext;
activeTab?: TabContext;
focus?: FocusContext;
selection?: SelectionContext;
visibleEntities?: VisibleEntity[];
filters?: FilterContext;
form?: FormContext;
breadcrumbs?: Breadcrumb[];
timestamp: string;
contextVersion: number;
}
8. Context Version
Cada alteração significativa no contexto deve incrementar:
contextVersion
Exemplo:
100
usuário muda de aba:
101
seleciona outro registro:
102
abre formulário:
103
Isso ajuda a detectar contexto obsoleto.
9. Stale Context Protection
Imagine:
- usuário seleciona WP-100;
- pergunta algo;
- enquanto o agente processa, seleciona WP-200;
- agente executa ação usando WP-100.
Isso pode ser perigoso.
O Execution Context deve registrar:
contextVersion = 42
Antes da execução:
currentContextVersion = 43
O sistema pode detectar:
CONTEXT_CHANGED
e, dependendo do risco:
- atualizar o contexto;
- reconstruir o plano;
- pedir confirmação;
- cancelar a execução.
Para operações de alto risco, a política deverá ser conservadora.
10. Context Lock
Para determinadas operações:
DELETE
APPROVE
CANCEL
UPDATE critical data
o plano pode registrar explicitamente:
targetEntityId = WP-10231
e nunca depender novamente da seleção visual.
Assim, se o usuário clicar em outro registro durante a execução:
Agent
↓
continua trabalhando em WP-10231
e não no novo registro selecionado.
11. Unsaved Changes
Um dos pontos mais importantes.
Imagine:
Usuário está editando:
Responsável: João
Validade: 30 dias
mas ainda não salvou.
O banco contém:
Responsável: Pedro
Validade: 15 dias
O agente precisa saber a diferença.
Contexto:
{
"form": {
"entityId": "WP-10231",
"dirty": true,
"changes": {
"responsibleId": {
"original": "USR-10",
"current": "USR-20"
},
"validityDays": {
"original": 15,
"current": 30
}
}
}
}
Isso é extremamente importante para evitar decisões incorretas.
12. Form Context
O contexto do formulário deverá informar:
interface FormContext {
formId: string;
entityType?: string;
entityId?: string;
dirty: boolean;
valid: boolean;
fields: FormFieldContext[];
submitCapabilityId?: string;
}
Não precisamos enviar todos os valores para o agente o tempo todo.
O contexto deve ser minimalista.
Somente campos relevantes podem ser incluídos.
13. Sensitive Fields
Dados sensíveis não devem ser enviados automaticamente para o agente.
O Context Bridge deve permitir:
sensitivity:
| 'public'
| 'internal'
| 'sensitive'
| 'restricted'
Exemplo:
CPF
dados médicos
dados financeiros
credenciais
tokens
não devem aparecer no contexto simplesmente porque estão na tela.
O Context Bridge deverá aplicar políticas de redaction/minimization.
14. Context Events
O frontend deverá enviar eventos semânticos.
Exemplos:
PAGE_CHANGED
TAB_CHANGED
ENTITY_SELECTED
ENTITY_DESELECTED
FOCUS_CHANGED
FORM_OPENED
FORM_CHANGED
FORM_SAVED
FILTER_CHANGED
NAVIGATION_STARTED
NAVIGATION_COMPLETED
Exemplo:
{
"type": "ENTITY_SELECTED",
"entity": {
"type": "workPermit",
"id": "WP-10231"
}
}
15. Event-driven Context
A arquitetura ideal:
React
│
├── UI Event
│
▼
Context Bridge
│
├── update local context
│
├── notify Agent Runtime
│
└── update session context
O agente não precisa consultar a UI constantemente.
Ele recebe o contexto quando relevante.
16. Context API
Deverá existir uma interface clara:
interface AgentContextBridge {
getContext(): SemanticUIContext;
updateContext(
event: SemanticUIEvent
): void;
getElement(
semanticId: string
): SemanticElement | undefined;
getSelection(): SelectionContext | undefined;
getFocus(): FocusContext | undefined;
}
17. Agent Commands → UI
A comunicação também ocorre no sentido inverso.
O agente poderá produzir comandos:
NAVIGATE
SELECT_ENTITY
FOCUS_ELEMENT
OPEN_TAB
OPEN_DIALOG
REFRESH_DATA
SHOW_RESULT
SHOW_ERROR
HIGHLIGHT_ELEMENT
Exemplo:
“Abra a permissão WP-123.”
Runtime:
navigation.workPermit.open
UI:
navigate("/work-permits/WP-123")
18. Nunca permitir navegação arbitrária
O agente não deve produzir:
window.location = arbitraryURL
Deve produzir:
{
"command": "NAVIGATE",
"target": {
"semanticId": "workPermit",
"entityId": "WP-123"
}
}
A aplicação decide como essa navegação é realizada.
19. UI Command Registry
Assim como existe Capability Registry para operações de negócio, deverá existir um:
UI Command Registry
Exemplo:
navigation.workPermit.open
navigation.employee.open
ui.workPermit.openComponents
ui.workPermit.focusValidity
ui.workPermit.refresh
ui.dialog.open
ui.dialog.close
Isso evita que o LLM controle diretamente a interface.
20. Agent Tool Runtime
O Runtime será o ambiente que disponibiliza ferramentas controladas ao agente.
Conceitualmente:
AGENT
│
▼
┌───────────────┐
│ Tool Runtime │
└───────┬───────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
Context Business UI
Tools Tools Tools
│ │ │
▼ ▼ ▼
React Capabilities React
21. Classes de Tools
Context Tools
context.get
context.getSelection
context.getFocus
context.getForm
Knowledge Tools
knowledge.search
knowledge.explain
knowledge.related
Business Tools
São as capabilities do PRD-004.
workPermit.read
workPermit.update
...
UI Tools
navigation.open
ui.select
ui.focus
ui.refresh
ui.openTab
22. Tool Discovery
O agente não deve receber centenas de tools.
O Runtime deve filtrar dinamicamente.
Se o usuário está em:
workPermit
o agente recebe principalmente:
workPermit.*
navigation.*
context.*
knowledge.*
Não é necessário carregar:
payroll.*
inventory.*
accounting.*
Isso reduz:
- tokens;
- latência;
- confusão;
- possibilidade de erro.
23. Capability + Context Filtering
O contexto atual deve ser usado para selecionar capabilities relevantes.
Exemplo:
page = workPermit
tab = components
prioridade:
workPermit.components.*
workPermit.*
navigation.*
context.*
Enquanto:
employee.*
financial.*
ficam fora do contexto imediato.
24. Tool Schema
Cada tool deverá possuir JSON Schema.
Exemplo:
{
name: "workPermit.updateValidity",
description:
"Updates the validity period of a work permit.",
inputSchema: {
type: "object",
properties: {
entityId: {
type: "string"
},
validityDays: {
type: "integer",
minimum: 1
}
},
required: [
"entityId",
"validityDays"
]
}
}
O schema será usado tanto pelo Planner quanto pelo Runtime.
25. Tool Invocation Envelope
Toda chamada deverá possuir um envelope padrão:
interface ToolInvocation {
invocationId: string;
executionId?: string;
planId?: string;
stepId?: string;
toolId: string;
userId: string;
tenantId: string;
contextVersion: number;
input: unknown;
timestamp: string;
}
Isso cria rastreabilidade completa.
26. Tool Result Envelope
interface ToolResult {
invocationId: string;
status:
| 'success'
| 'failure'
| 'denied'
| 'validation_error';
data?: unknown;
error?: ToolError;
metadata?: {
durationMs: number;
cached: boolean;
verified: boolean;
};
}
27. Streaming
Para comandos complexos, a UI deverá receber eventos em tempo real.
Exemplo:
USER
↓
"Duplique esta permissão..."
↓
PLAN_CREATED
↓
STEP_STARTED
↓
STEP_COMPLETED
↓
STEP_STARTED
↓
STEP_COMPLETED
↓
VERIFICATION_COMPLETED
↓
DONE
O frontend poderá renderizar:
🤖 Executando...
✓ Permissão original identificada
✓ Nova permissão criada
✓ Componentes copiados
✓ Responsável atualizado
✓ Validade atualizada
✓ Concluído
28. Transport Layer
O mecanismo de comunicação entre frontend e Agent Runtime deverá ser abstraído.
A implementação poderá utilizar:
HTTP
SSE
WebSocket
WebTransport
conforme necessidade.
O PRD não deve acoplar a lógica de negócio ao transporte.
Interface:
interface AgentTransport {
send(event: AgentEvent): Promise<void>;
subscribe(
handler: (event: AgentEvent) => void
): () => void;
}
29. Agent Session
Cada conversa com o agente terá:
agentSessionId
Ela poderá conter:
user
tenant
conversation
currentContext
pendingPlan
execution
Mas esses estados devem permanecer separados internamente.
30. Context Compression
Não enviar o contexto completo a cada mensagem.
O Runtime deve manter:
Context Snapshot
e enviar apenas:
Context Delta
quando possível.
Exemplo:
Estado anterior:
page=workPermit
tab=components
selection=WP-100
Novo evento:
selection=WP-101
Não precisamos reenviar tudo.
31. Cache
O contexto semântico poderá ser mantido em cache por sessão.
Chave conceitual:
agent:context:{sessionId}
Entretanto, o estado operacional definitivo não deve depender apenas de cache.
Cache perdido deve poder ser reconstruído pela UI.
32. Security Boundary
O Context Bridge deve ser tratado como fronteira de segurança.
Nunca aceitar cegamente do cliente:
userId
tenantId
permissions
roles
Esses dados deverão ser derivados da sessão autenticada no backend.
O frontend pode informar:
selection
page
tab
focus
mas não pode declarar:
"eu sou administrador"
33. Anti-Tampering
Exemplo de ataque:
{
"selection": {
"entityId": "WP-99999"
}
}
Mesmo que a UI informe esse ID, o backend deve verificar:
User can access WP-99999?
antes de qualquer operação.
34. Context-Aware Natural Language
Essa arquitetura permite uma mudança enorme na experiência.
O usuário pode dizer:
“Explique.”
O sistema usa:
focus
↓
semanticId
↓
HAG
↓
answer
Pode dizer:
“Abra o anterior.”
O agente utiliza:
conversation
+
navigation history
Pode dizer:
“Mude para 60.”
O agente utiliza:
previous intent
+
current focus
e entende:
validityDays = 60
35. UI Context + HAG
O Context Bridge também alimentará o Knowledge Router.
Exemplo:
User:
"Explique isso."
Context:
semanticId = workPermit.components
Knowledge query enriquecida:
"workPermit.components"
O HAG poderá recuperar diretamente:
documentação
regras
relacionamentos
exemplos
capabilities relacionadas
sem necessidade de uma busca semântica ampla.
36. Context-aware Retrieval
O retrieval deverá aplicar boost contextual.
Exemplo:
currentPage = workPermit
currentTab = components
focus = workPermit.components
Ranking:
exact semantic match +100
current focus +50
current tab +30
current page +20
wikilink proximity +15
BM25 ...
vector similarity ...
Os pesos reais deverão ser calibrados durante benchmark.
37. Agent Interaction Loop
Com este PRD, o ciclo completo passa a ser:
User
↓
UI Context
↓
Intent Engine
↓
Knowledge / Capabilities
↓
Planner
↓
Plan Validation
↓
Confirmation
↓
Execution Runtime
↓
Capability
↓
API
↓
Verification
↓
UI Event
↓
Updated Context
↓
Agent Response
Isso cria um verdadeiro closed-loop agent.
38. Exemplo completo
Usuário está em:
Permissão WP-10231
Tab: Componentes
Componente: Trabalho em altura
Ele pergunta:
“Esse componente exige o quê?”
Context Bridge fornece:
page = workPermit
tab = components
focus = workPermit.components.item
selection = component:HEIGHT-WORK
Intent:
KNOWLEDGE_QUERY
Knowledge Router busca:
component:HEIGHT-WORK
HAG retorna a documentação relevante.
Resposta:
“Para trabalho em altura, o sistema exige…”
Nenhuma chamada de API operacional foi necessária.
39. Exemplo de operação
Usuário:
“Remova esse componente.”
Context:
component = HEIGHT-WORK
permit = WP-10231
Intent:
DELETE
Planner:
workPermit.components.remove
Risk:
HIGH
Confirmation:
“Deseja remover o componente Trabalho em Altura da permissão WP-10231?”
Usuário:
“Sim.”
Execution:
authorize
↓
remove
↓
verify
↓
refresh UI
UI recebe:
REFRESH_DATA
e:
SHOW_RESULT
40. Exemplo de alteração contextual
Usuário está no campo:
Validade
e diz:
“Coloque 45.”
Intent Engine:
target = workPermit.validity
value = 45
Planner:
workPermit.updateValidity
Runtime:
execute
↓
verify
↓
refresh field
O usuário não precisou dizer:
“Altere a validade da permissão WP-10231 para 45 dias.”
Essa é a principal vantagem do Context Bridge.
41. Critérios de Aceitação
AC-01
A aplicação deve produzir Semantic UI Context.
AC-02
O contexto deve incluir página, aba, foco e seleção quando disponíveis.
AC-03
O contexto não deve depender do DOM completo.
AC-04
Semantic IDs devem ser estáveis e versionáveis.
AC-05
O agente deve conseguir resolver referências como “isso”, “este”, “aqui” e “o atual”.
AC-06
Contexto obsoleto deve ser detectável.
AC-07
Dados sensíveis devem ser minimizados/redigidos.
AC-08
O agente não poderá declarar suas próprias permissões.
AC-09
UI Commands devem utilizar um registry controlado.
AC-10
Navegação não poderá utilizar URLs arbitrárias produzidas pelo LLM.
AC-11
Capabilities devem ser filtradas pelo contexto.
AC-12
Execuções complexas devem produzir eventos de progresso.
AC-13
A UI deve conseguir atualizar-se após ações do agente.
AC-14
O estado da aplicação deve continuar sendo a fonte de verdade.
AC-15
Contexto conversacional e contexto operacional devem permanecer separados.
Evidência de implementação e produção — 2026-09-05
O Web produz contexto semântico limitado a página, aba, foco e seleção, sem varrer o DOM; os Semantic IDs vêm de registry versionável. O bridge redige campos sensíveis, detecta versão obsoleta e resolve referência contextual por seleção, foco ou alvo conversacional. O Command Registry é fechado e navegação/capability só podem ser resolvidas por bindings declarados, portanto o contexto não confere permissões nem permite URL arbitrária de LLM.
Em 2026-09-04, o bridge compartilhado aceita somente eventos de execução com status allowlisted, contexto/versionamento atual, sequência crescente e terminal idempotente. O adapter Web mantém callbacks locais fechados: Work Permit registra ui.workPermit.refreshValidity e Auditorias registra ui.audit.refreshWorkspace; apenas COMPLETED no contexto/página corretos recarrega estado autoritativo. FAILED, UNKNOWN, contexto stale e command desconhecido não atualizam a UI. Agora o Agente expõe /execution-events/stream autenticado, em lote SSE finito de no máximo 32 entradas do ledger, filtrado por tenant e usuário verificados; o Web o consome por fetch com abort no unmount e descarta frames malformados antes do bridge. O stream de Auditorias consulta apenas seu ledger append-only e exige criador, auditor registrado ou superadmin; o servidor deriva ambos os refreshes de allowlists locais, nunca do payload remoto. Quatorze testes focados de stream/bridge/contexto e os typechecks Web/Agent passaram. Worker e Pages foram publicados, /health respondeu ok, /work-permits e /auditorias serviram HTML 200 e seus chunks JavaScript tiveram MIME correto. O canário autenticado criou um tenant sintético, concluiu o plano em COMPLETED@5, confirmou o frame SSE terminal workPermit.create@1 e removeu integralmente o estado sintético. A cobertura ainda é limitada a dois workspaces e a polling SSE finito, portanto este PRD permanece parcial.
Em 2026-09-05, os contratos de stream, bridge e contexto foram recertificados com 16 testes em 5 arquivos; os typechecks do Web e do Agent passaram. A cobertura continua deliberadamente limitada aos workspaces Work Permit e Auditorias e ao polling SSE finito; a expansão para outras superfícies permanece trabalho posterior.
Em 2026-09-06, o polling SSE recebeu cursor numérico estrito e monotônico: Agent filtra rowid > cursor dentro do escopo tenant/principal também para Auditorias, e o Web avança o cursor somente depois de aceitar um frame tipado. Assim, polls subsequentes não reproduzem eventos já consumidos e nenhum cursor altera escopo, ordenação ou comando. Nove testes focados e os typechecks Web/Agent passaram; Agent 39e0413c-d0b8-42a0-ba9e-bcd4f8645c74 e Pages b8afd394 foram publicados, com /health e /work-permits públicos em HTTP 200 e bundle contendo o suporte a cursor. O PRD permanece parcial pelo polling limitado e dois workspaces.
42. Resultado da arquitetura após PRD-007
Agora temos praticamente todas as peças fundamentais:
┌───────────────────┐
│ React UI │
└─────────┬─────────┘
│
Semantic Context
│
▼
┌──────────────────┐
│ Context Bridge │
│ PRD-007 │
└────────┬─────────┘
│
▼
USER ───────────────► INTENT ENGINE
│
▼
AGENT PLANNER
│
▼
EXECUTION PLAN
│
▼
POLICY / AUTH
│
▼
CAPABILITY REGISTRY
│
▼
EXECUTION RUNTIME
│
▼
HONO APIs
│
▼
APPLICATION
│
▼
VERIFICATION
│
▼
UI UPDATE
E em paralelo:
┌─────────────────────┐
│ EXISTING HAG │
│ │
│ Markdown │
│ Keywords │
│ Wikilinks │
│ BM25 │
│ Vectorize │
│ Cache │
└──────────┬──────────┘
│
▼
Knowledge Router
│
┌─────────┴─────────┐
▼ ▼
Intent Planner
Próximo estágio — PRD-008
O próximo passo natural é o PRD-008 — Agent Policy, Safety & Governance Engine.
Esse será particularmente importante para o sistema de Segurança e Saúde do Trabalho, porque até aqui já definimos como o agente entende, planeja e executa. Agora precisamos definir até onde ele pode ir.
O PRD-008 deverá estabelecer:
- matriz de risco;
- autorização por usuário/tenant;
- RBAC/ABAC;
- políticas por capability;
- políticas por tipo de registro;
- confirmação simples versus confirmação forte;
- operações proibidas;
- limites de quantidade;
- proteção contra ações em massa;
- segregação de funções;
- regras para aprovação/cancelamento;
- políticas para dados sensíveis;
- políticas temporais;
- horário permitido para determinadas ações;
- políticas de emergência;
- auditabilidade;
- explicabilidade;
- “human-in-the-loop”;
- bloqueio de ações incompatíveis com regras de SST;
- prevenção de escalada de privilégios;
- detecção de comportamento anômalo;
- Policy Decision Point (PDP) e Policy Enforcement Point (PEP).
Esse PRD será a camada que permitirá dizer, de forma formal:
“O agente sabe fazer isso, entendeu que o usuário pediu isso e sabe como executar — mas está autorizado a fazer isso neste contexto específico?”
Essa separação é essencial para que o Agentic Work seja poderoso sem transformar o agente em uma brecha de segurança do sistema.