feat: implementar audit trail con AuditWriter y emision de eventos
Crea shell/audit/ con Writer que escribe eventos de auditoria a archivo JSONL y opcionalmente a un room Matrix. Integra la emision de eventos en los puntos clave del runtime: - message_received: al recibir cualquier evento Matrix (handler.go) - command_exec: al ejecutar un comando (handler.go) - tool_exec: al ejecutar una tool (tools/registry.go via AuditFunc callback) - llm_request / llm_error: al llamar al LLM (llm.go) El Writer se inicializa en agents/runtime.go si security.audit.enabled=true. Usa patron de inyeccion de dependencias (MatrixSender como funcion, AuditFunc como callback) para evitar acoplamiento entre packages. Incluye tests completos para el Writer: escritura JSONL, filtrado por Include, modo solo-file, modo solo-room, auto-set de timestamp. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/enmanuel/agents/pkg/decision"
|
||||
coretypes "github.com/enmanuel/agents/pkg/llm"
|
||||
"github.com/enmanuel/agents/pkg/personality"
|
||||
"github.com/enmanuel/agents/shell/audit"
|
||||
shelllm "github.com/enmanuel/agents/shell/llm"
|
||||
)
|
||||
|
||||
@@ -75,6 +76,12 @@ func (a *Agent) runLLM(ctx context.Context, msgCtx decision.MessageContext, memK
|
||||
resp, err := a.llm(ctx, req)
|
||||
if err != nil {
|
||||
a.logger.Error("LLM call failed", "model", req.Model, "err", err)
|
||||
// Audit: llm_error
|
||||
a.emitAudit(audit.Event{
|
||||
AgentID: a.cfg.Agent.ID,
|
||||
EventType: audit.EventLLMError,
|
||||
Detail: fmt.Sprintf("provider=%s model=%s error=%s", a.cfg.LLM.Primary.Provider, req.Model, err),
|
||||
})
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -84,6 +91,13 @@ func (a *Agent) runLLM(ctx context.Context, msgCtx decision.MessageContext, memK
|
||||
"finish_reason", resp.FinishReason,
|
||||
)
|
||||
|
||||
// Audit: llm_request
|
||||
a.emitAudit(audit.Event{
|
||||
AgentID: a.cfg.Agent.ID,
|
||||
EventType: audit.EventLLMRequest,
|
||||
Detail: fmt.Sprintf("provider=%s model=%s content_len=%d tool_calls=%d", a.cfg.LLM.Primary.Provider, req.Model, len(resp.Content), len(resp.ToolCalls)),
|
||||
})
|
||||
|
||||
// No tool calls — return the text response
|
||||
if len(resp.ToolCalls) == 0 {
|
||||
return resp.Content, nil
|
||||
|
||||
Reference in New Issue
Block a user