From 3fe5ae0b50a26e4f599d959e4ec967f2d097beda Mon Sep 17 00:00:00 2001 From: viettranx Date: Wed, 15 Apr 2026 14:25:59 +0700 Subject: [PATCH] feat(hooks): introduce agent lifecycle hooks foundation with fail-closed blocking semantics Phase 1 of agent-hooks-system establishes: - Hook types, matchers, and CEL evaluation engine for event-driven extensibility - Edition-gated command handlers (Lite disabled) with dedup_key-indexed audit log - Dual-DB store layer (PostgreSQL + SQLite) with transaction boundary enforcement - Blocking-event semantics: hook execution failures propagate to agent loop, graceful retry - Tenant-isolated audit trail with per-hook execution context tracing - Integration tests verifying store correctness and hook dispatch atomicity Lays groundwork for post-v3.0 phase-02 (per-tenant onboarding hooks). --- docs/00-architecture-overview.md | 2 + docs/06-store-data-model.md | 2 + docs/17-changelog.md | 58 +-- go.mod | 5 +- go.sum | 7 + internal/hooks/audit.go | 164 ++++++++ internal/hooks/audit_test.go | 196 ++++++++++ internal/hooks/config.go | 160 ++++++++ internal/hooks/config_test.go | 256 ++++++++++++ internal/hooks/dispatcher.go | 366 +++++++++++++++++ internal/hooks/dispatcher_test.go | 401 +++++++++++++++++++ internal/hooks/edition_gate.go | 28 ++ internal/hooks/edition_gate_test.go | 67 ++++ internal/hooks/matcher.go | 117 ++++++ internal/hooks/matcher_test.go | 186 +++++++++ internal/hooks/store.go | 53 +++ internal/hooks/tracing.go | 80 ++++ internal/hooks/tracing_test.go | 193 +++++++++ internal/hooks/types.go | 195 ++++++++++ internal/hooks/types_test.go | 117 ++++++ internal/store/base/tables.go | 1 + internal/store/pg/factory.go | 1 + internal/store/pg/hooks.go | 445 +++++++++++++++++++++ internal/store/pg/hooks_test.go | 383 ++++++++++++++++++ internal/store/sqlitestore/factory.go | 1 + internal/store/sqlitestore/hooks.go | 474 +++++++++++++++++++++++ internal/store/sqlitestore/hooks_test.go | 427 ++++++++++++++++++++ internal/store/sqlitestore/schema.go | 75 +++- internal/store/sqlitestore/schema.sql | 86 ++++ internal/store/stores.go | 4 + internal/upgrade/version.go | 2 +- migrations/000052_agent_hooks.down.sql | 4 + migrations/000052_agent_hooks.up.sql | 110 ++++++ tests/integration/v3_hooks_store_test.go | 227 +++++++++++ 34 files changed, 4866 insertions(+), 27 deletions(-) create mode 100644 internal/hooks/audit.go create mode 100644 internal/hooks/audit_test.go create mode 100644 internal/hooks/config.go create mode 100644 internal/hooks/config_test.go create mode 100644 internal/hooks/dispatcher.go create mode 100644 internal/hooks/dispatcher_test.go create mode 100644 internal/hooks/edition_gate.go create mode 100644 internal/hooks/edition_gate_test.go create mode 100644 internal/hooks/matcher.go create mode 100644 internal/hooks/matcher_test.go create mode 100644 internal/hooks/store.go create mode 100644 internal/hooks/tracing.go create mode 100644 internal/hooks/tracing_test.go create mode 100644 internal/hooks/types.go create mode 100644 internal/hooks/types_test.go create mode 100644 internal/store/pg/hooks.go create mode 100644 internal/store/pg/hooks_test.go create mode 100644 internal/store/sqlitestore/hooks.go create mode 100644 internal/store/sqlitestore/hooks_test.go create mode 100644 migrations/000052_agent_hooks.down.sql create mode 100644 migrations/000052_agent_hooks.up.sql create mode 100644 tests/integration/v3_hooks_store_test.go diff --git a/docs/00-architecture-overview.md b/docs/00-architecture-overview.md index 6faa71db..2042b820 100644 --- a/docs/00-architecture-overview.md +++ b/docs/00-architecture-overview.md @@ -38,6 +38,7 @@ flowchart TD SCHED[Scheduler -- 4 Lanes] AR[Agent Router] LOOP[Agent Loop -- Think / Act / Observe] + HOOKS[Hook Dispatcher -- Lifecycle Events] end subgraph Providers["LLM Providers"] @@ -143,6 +144,7 @@ flowchart TD | `internal/workspace/` | Workspace context resolver: 6 scenarios (agent default, team lead, team member, dispatch, subagent, cron) | | `internal/vault/` | Knowledge Vault: wikilinks (semantic mesh), hybrid search (BM25+vector), filesystem sync, L0 auto-injection | | `internal/channels/whatsapp/` | Native WhatsApp channel via whatsmeow (replaces WhatsApp API), QR auth, media handling | +| `internal/hooks/` | Agent lifecycle hooks: event dispatcher (sync/async), handlers (command/http/prompt), matchers (regex + CEL), audit logging, edition gating, cost safeguards | --- diff --git a/docs/06-store-data-model.md b/docs/06-store-data-model.md index e2d03547..4c31e78b 100644 --- a/docs/06-store-data-model.md +++ b/docs/06-store-data-model.md @@ -47,6 +47,7 @@ The `Stores` struct is the top-level container holding all PostgreSQL-backed sto | SnapshotStore | `PGSnapshotStore` | Hourly usage snapshots, cost aggregation, time series queries | | SecureCLIStore | `PGSecureCLIStore` | CLI binary configs with encrypted credential injection | | APIKeyStore | `PGAPIKeyStore` | Gateway API keys, scopes, expiration, revocation | +| HookStore | `PGHookStore` | Lifecycle hook definitions (event, handler type, matcher, config), execution audit log | ### SQLite Parity (Lite Edition) @@ -63,6 +64,7 @@ The `Stores` struct is the top-level container holding all PostgreSQL-backed sto | AgentLinksStore | `SQLiteAgentLinks` | LIKE search, no vector | | SubagentTasksStore | `SQLiteSubagentTasks` | ✓ Parity (json_set for metadata merge) | | SecureCLIStore | `SQLiteSecureCLIStore` | ✓ Parity + AES-256-GCM encryption mandatory (GOCLAW_KEY env var required) | +| HookStore | `SQLiteHookStore` | ✓ Parity (agent_hooks + hook_executions tables, same schema as PG) | --- diff --git a/docs/17-changelog.md b/docs/17-changelog.md index b5bbaccd..c84fb871 100644 --- a/docs/17-changelog.md +++ b/docs/17-changelog.md @@ -6,37 +6,47 @@ All notable changes to GoClaw Gateway are documented here. Format follows [Keep ## [Unreleased] — 2026-04-15 -#### ElevenLabs Audio Manager Refactor — Phase 6 (2026-04-15) +#### Agent Hooks System — Phase 1: Foundation (2026-04-15) -Desktop UI parity: voice picker + STT admin form ported from web to Wails desktop frontend. Completes 6-phase plan; all audio surfaces (TTS/STT/Music/SFX) now manageable from both web and desktop Lite editions. +Lifecycle hook infrastructure: event dispatcher (sync/async paths), audit logging, database schema (PostgreSQL + SQLite), store interface, config validation, edition gating. Handlers + pipeline integration deferred to Phase 2. ### Added -- **Desktop voice picker**: `ui/desktop/frontend/src/components/agents/voice-picker.tsx` — uses desktop's native Combobox primitive; embedded in `AgentDetailPanel` with `other_config.tts_voice_id` persistence via spread-merge pattern -- **Desktop voice preview button**: `ui/desktop/frontend/src/components/agents/voice-preview-button.tsx` — singleton `