feat: Add presence heartbeat for Matrix online status
- matrix-gateway: POST /internal/matrix/presence/online endpoint - usePresenceHeartbeat hook with activity tracking - Auto away after 5 min inactivity - Offline on page close/visibility change - Integrated in MatrixChatRoom component
This commit is contained in:
256
migrations/007_create_agents_tables.sql
Normal file
256
migrations/007_create_agents_tables.sql
Normal file
@@ -0,0 +1,256 @@
|
||||
-- ============================================================================
|
||||
-- Migration 007: Agent Lifecycle Tables
|
||||
-- Phase 6: CRUD + DB Persistence + Events
|
||||
-- ============================================================================
|
||||
|
||||
-- ============================================================================
|
||||
-- Table: agent_blueprints
|
||||
-- Purpose: Agent templates/archetypes (Sofia, Alex, Guardian, etc.)
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_blueprints (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
code TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
default_model TEXT NOT NULL DEFAULT 'gpt-4.1-mini',
|
||||
default_tools JSONB DEFAULT '[]'::jsonb,
|
||||
default_system_prompt TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_agent_blueprints_code ON agent_blueprints(code);
|
||||
|
||||
COMMENT ON TABLE agent_blueprints IS 'Agent templates/archetypes';
|
||||
COMMENT ON COLUMN agent_blueprints.code IS 'Unique code like sofia_prime, alex_analyst';
|
||||
COMMENT ON COLUMN agent_blueprints.default_tools IS 'JSON array of default tool IDs';
|
||||
|
||||
-- ============================================================================
|
||||
-- Table: agents
|
||||
-- Purpose: Agent instances (actual agents in the system)
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agents (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
external_id TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL,
|
||||
kind TEXT NOT NULL,
|
||||
microdao_id UUID REFERENCES microdaos(id) ON DELETE SET NULL,
|
||||
owner_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
blueprint_id UUID REFERENCES agent_blueprints(id) ON DELETE SET NULL,
|
||||
model TEXT NOT NULL DEFAULT 'gpt-4.1-mini',
|
||||
tools_enabled JSONB DEFAULT '[]'::jsonb,
|
||||
system_prompt TEXT,
|
||||
avatar_url TEXT,
|
||||
description TEXT,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_agents_external_id ON agents(external_id);
|
||||
CREATE INDEX idx_agents_owner_user_id ON agents(owner_user_id);
|
||||
CREATE INDEX idx_agents_microdao_id ON agents(microdao_id);
|
||||
CREATE INDEX idx_agents_kind ON agents(kind);
|
||||
CREATE INDEX idx_agents_is_active ON agents(is_active);
|
||||
|
||||
COMMENT ON TABLE agents IS 'Agent instances in the system';
|
||||
COMMENT ON COLUMN agents.external_id IS 'External identifier like agent:sofia';
|
||||
COMMENT ON COLUMN agents.kind IS 'assistant, node, system, guardian, analyst, quest';
|
||||
COMMENT ON COLUMN agents.tools_enabled IS 'JSON array of enabled tool IDs';
|
||||
COMMENT ON COLUMN agents.is_active IS 'Soft delete flag';
|
||||
|
||||
-- ============================================================================
|
||||
-- Table: agent_events
|
||||
-- Purpose: Event log for agent activity
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_events (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
agent_id UUID NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
|
||||
ts TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
kind TEXT NOT NULL,
|
||||
channel_id TEXT,
|
||||
payload JSONB,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_agent_events_agent_id ON agent_events(agent_id);
|
||||
CREATE INDEX idx_agent_events_agent_id_ts ON agent_events(agent_id, ts DESC);
|
||||
CREATE INDEX idx_agent_events_kind ON agent_events(kind);
|
||||
CREATE INDEX idx_agent_events_ts ON agent_events(ts DESC);
|
||||
|
||||
COMMENT ON TABLE agent_events IS 'Event log for agent activity';
|
||||
COMMENT ON COLUMN agent_events.kind IS 'created, updated, deleted, invocation, reply_sent, tool_call, error, etc.';
|
||||
COMMENT ON COLUMN agent_events.payload IS 'Event-specific data (JSON)';
|
||||
|
||||
-- ============================================================================
|
||||
-- Seed Data: Agent Blueprints
|
||||
-- ============================================================================
|
||||
|
||||
INSERT INTO agent_blueprints (code, name, description, default_model, default_tools, default_system_prompt)
|
||||
VALUES
|
||||
(
|
||||
'sofia_prime',
|
||||
'Sofia',
|
||||
'Універсальний асистент для проєктів та задач',
|
||||
'gpt-4.1-mini',
|
||||
'["projects.list", "task.create", "task.list", "followups.create"]'::jsonb,
|
||||
'You are Sofia, a helpful assistant for managing projects and tasks.'
|
||||
),
|
||||
(
|
||||
'alex_analyst',
|
||||
'Alex',
|
||||
'Аналітик даних та метрик',
|
||||
'deepseek-r1',
|
||||
'["metrics.get", "analytics.run", "reports.generate"]'::jsonb,
|
||||
'You are Alex, a data analyst specialized in metrics and insights.'
|
||||
),
|
||||
(
|
||||
'guardian',
|
||||
'Guardian',
|
||||
'Захисник безпеки та compliance',
|
||||
'gpt-4.1-mini',
|
||||
'["security.check", "compliance.verify", "alerts.send"]'::jsonb,
|
||||
'You are Guardian, a security and compliance specialist.'
|
||||
),
|
||||
(
|
||||
'quest_master',
|
||||
'Quest Master',
|
||||
'Координатор квестів та завдань',
|
||||
'gpt-4.1-mini',
|
||||
'["quest.create", "quest.update", "rewards.allocate"]'::jsonb,
|
||||
'You are Quest Master, a coordinator for quests and achievements.'
|
||||
),
|
||||
(
|
||||
'node_monitor',
|
||||
'Node Monitor',
|
||||
'Моніторинг нод та системних метрик',
|
||||
'gpt-4.1-mini',
|
||||
'["node.status", "metrics.collect", "alerts.trigger"]'::jsonb,
|
||||
'You are Node Monitor, responsible for infrastructure monitoring.'
|
||||
)
|
||||
ON CONFLICT (code) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- Seed Data: Initial Agents (for testing)
|
||||
-- ============================================================================
|
||||
|
||||
-- Insert Sofia instance
|
||||
INSERT INTO agents (
|
||||
external_id,
|
||||
name,
|
||||
kind,
|
||||
blueprint_id,
|
||||
model,
|
||||
tools_enabled,
|
||||
system_prompt,
|
||||
description,
|
||||
is_active
|
||||
)
|
||||
SELECT
|
||||
'agent:sofia',
|
||||
'Sofia',
|
||||
'assistant',
|
||||
id,
|
||||
'gpt-4.1-mini',
|
||||
'["projects.list", "task.create"]'::jsonb,
|
||||
'You are Sofia, a helpful assistant for managing projects and tasks.',
|
||||
'Допомагає з управлінням проєктами та задачами',
|
||||
true
|
||||
FROM agent_blueprints WHERE code = 'sofia_prime'
|
||||
ON CONFLICT (external_id) DO NOTHING;
|
||||
|
||||
-- Insert Alex instance
|
||||
INSERT INTO agents (
|
||||
external_id,
|
||||
name,
|
||||
kind,
|
||||
blueprint_id,
|
||||
model,
|
||||
tools_enabled,
|
||||
system_prompt,
|
||||
description,
|
||||
is_active
|
||||
)
|
||||
SELECT
|
||||
'agent:alex',
|
||||
'Alex',
|
||||
'analyst',
|
||||
id,
|
||||
'deepseek-r1',
|
||||
'["metrics.get", "analytics.run"]'::jsonb,
|
||||
'You are Alex, a data analyst specialized in metrics and insights.',
|
||||
'Аналітик даних та метрик',
|
||||
true
|
||||
FROM agent_blueprints WHERE code = 'alex_analyst'
|
||||
ON CONFLICT (external_id) DO NOTHING;
|
||||
|
||||
-- Insert Guardian instance
|
||||
INSERT INTO agents (
|
||||
external_id,
|
||||
name,
|
||||
kind,
|
||||
blueprint_id,
|
||||
model,
|
||||
tools_enabled,
|
||||
system_prompt,
|
||||
description,
|
||||
is_active
|
||||
)
|
||||
SELECT
|
||||
'agent:guardian',
|
||||
'Guardian',
|
||||
'guardian',
|
||||
id,
|
||||
'gpt-4.1-mini',
|
||||
'["security.check", "compliance.verify"]'::jsonb,
|
||||
'You are Guardian, a security and compliance specialist.',
|
||||
'Захисник безпеки системи',
|
||||
true
|
||||
FROM agent_blueprints WHERE code = 'guardian'
|
||||
ON CONFLICT (external_id) DO NOTHING;
|
||||
|
||||
-- ============================================================================
|
||||
-- Update Trigger: agents.updated_at
|
||||
-- ============================================================================
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_agents_updated_at()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER trigger_update_agents_updated_at
|
||||
BEFORE UPDATE ON agents
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_agents_updated_at();
|
||||
|
||||
-- ============================================================================
|
||||
-- Grants (for daarion app user)
|
||||
-- ============================================================================
|
||||
|
||||
-- Assuming app user is 'daarion' or 'postgres'
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON agent_blueprints TO postgres;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON agents TO postgres;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON agent_events TO postgres;
|
||||
|
||||
-- ============================================================================
|
||||
-- Migration Complete
|
||||
-- ============================================================================
|
||||
|
||||
-- Verify tables created
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM information_schema.tables
|
||||
WHERE table_name IN ('agent_blueprints', 'agents', 'agent_events')
|
||||
) THEN
|
||||
RAISE NOTICE 'Migration 007: Agent Lifecycle Tables created successfully';
|
||||
ELSE
|
||||
RAISE EXCEPTION 'Migration 007: Failed to create tables';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
Reference in New Issue
Block a user