// PicoClaw - Ultra-lightweight personal AI agent package agent import ( "fmt" runtimeevents "github.com/sipeed/picoclaw/pkg/events" ) func (al *AgentLoop) newTurnEventScope(agentID, sessionKey string, turnCtx *TurnContext) turnEventScope { seq := al.turnSeq.Add(1) return turnEventScope{ agentID: agentID, sessionKey: sessionKey, turnID: fmt.Sprintf("%s-turn-%d", agentID, seq), context: cloneTurnContext(turnCtx), } } func (ts turnEventScope) meta(iteration int, source, tracePath string) HookMeta { return HookMeta{ AgentID: ts.agentID, TurnID: ts.turnID, SessionKey: ts.sessionKey, Iteration: iteration, Source: source, TracePath: tracePath, turnContext: cloneTurnContext(ts.context), } } func (al *AgentLoop) emitEvent(kind runtimeevents.Kind, meta HookMeta, payload any) { clonedMeta := cloneHookMeta(meta) eventCtx := cloneTurnContext(clonedMeta.turnContext) evt := runtimeevents.Event{ Kind: kind, Source: runtimeevents.Source{Component: "agent", Name: clonedMeta.AgentID}, Scope: runtimeScopeFromHookMeta(clonedMeta, eventCtx), Correlation: runtimeCorrelationFromHookMeta(clonedMeta), Severity: runtimeSeverityForAgentEvent(kind, payload), Payload: payload, Attrs: runtimeAttrsFromHookMeta(clonedMeta), } if al == nil { return } al.publishRuntimeEvent(evt) } // MountHook registers an in-process hook on the agent loop. func (al *AgentLoop) MountHook(reg HookRegistration) error { if al == nil || al.hooks == nil { return fmt.Errorf("hook manager is not initialized") } return al.hooks.Mount(reg) } // UnmountHook removes a previously registered in-process hook. func (al *AgentLoop) UnmountHook(name string) { if al == nil || al.hooks == nil { return } al.hooks.Unmount(name) } // RuntimeEvents returns the root runtime event channel. func (al *AgentLoop) RuntimeEvents() runtimeevents.EventChannel { if al == nil || al.runtimeEvents == nil { return nil } return al.runtimeEvents.Channel() } // RuntimeEventStats returns runtime event bus counters. func (al *AgentLoop) RuntimeEventStats() runtimeevents.Stats { if al == nil || al.runtimeEvents == nil { return runtimeevents.Stats{Closed: true} } return al.runtimeEvents.Stats() } // RuntimeEventBus returns the runtime event bus used by the agent loop. func (al *AgentLoop) RuntimeEventBus() runtimeevents.Bus { if al == nil { return nil } return al.runtimeEvents }