|
| 1 | +-- ============================================ |
| 2 | +-- Neuron AI Framework - Snowflake Setup |
| 3 | +-- Last updated: Setting this up for the agent memory stuff |
| 4 | +-- ============================================ |
| 5 | + |
| 6 | +-- First, let's create our main database |
| 7 | +CREATE DATABASE IF NOT EXISTS NEURON_AI; |
| 8 | +USE DATABASE NEURON_AI; |
| 9 | + |
| 10 | +-- Organizing schemas by function (makes it easier to manage later) |
| 11 | +CREATE SCHEMA IF NOT EXISTS MEMORY_STORE; -- All the agent memories go here |
| 12 | +CREATE SCHEMA IF NOT EXISTS AGENT_COORDINATION; -- Agent talk to each other here |
| 13 | +CREATE SCHEMA IF NOT EXISTS ANALYTICS; -- For tracking what's actually happening |
| 14 | +CREATE SCHEMA IF NOT EXISTS MULTIMODAL_DATA; -- Images, audio, etc. |
| 15 | + |
| 16 | +-- ============================================ |
| 17 | +-- Memory tables - this is where agents remember stuff |
| 18 | +-- ============================================ |
| 19 | +USE SCHEMA MEMORY_STORE; |
| 20 | + |
| 21 | +-- Main memory table - keeping 90 days of history (can adjust if needed) |
| 22 | +CREATE OR REPLACE TABLE EPISODIC_MEMORY ( |
| 23 | + memory_id VARCHAR(36) DEFAULT UUID_STRING(), |
| 24 | + agent_id VARCHAR(100) NOT NULL, |
| 25 | + circuit_id VARCHAR(100) NOT NULL, |
| 26 | + timestamp TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(), |
| 27 | + event_type VARCHAR(50), |
| 28 | + context VARIANT, -- Storing JSON here for flexibility |
| 29 | + embeddings ARRAY, |
| 30 | + metadata OBJECT, |
| 31 | + PRIMARY KEY (memory_id) |
| 32 | +) DATA_RETENTION_TIME_IN_DAYS = 90 -- Adjust based on your storage budget |
| 33 | + CLUSTER BY (agent_id, timestamp); -- Speeds up agent-specific queries |
| 34 | + |
| 35 | +-- Semantic memory - basically the agent's learned concepts |
| 36 | +CREATE OR REPLACE TABLE SEMANTIC_MEMORY ( |
| 37 | + concept_id VARCHAR(36) DEFAULT UUID_STRING(), |
| 38 | + agent_id VARCHAR(100) NOT NULL, |
| 39 | + concept VARCHAR(500), |
| 40 | + relationships VARIANT, |
| 41 | + knowledge_graph OBJECT, |
| 42 | + confidence_score FLOAT, |
| 43 | + last_accessed TIMESTAMP_NTZ, |
| 44 | + access_count INTEGER DEFAULT 0, |
| 45 | + PRIMARY KEY (concept_id) |
| 46 | +) CLUSTER BY (agent_id, concept); |
| 47 | + |
| 48 | +-- Short-term memory (expires after 1 hour by default) |
| 49 | +CREATE OR REPLACE TABLE WORKING_MEMORY ( |
| 50 | + session_id VARCHAR(36), |
| 51 | + agent_id VARCHAR(100), |
| 52 | + circuit_id VARCHAR(100), |
| 53 | + memory_state VARIANT, |
| 54 | + attention_weights ARRAY, |
| 55 | + active_from TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(), |
| 56 | + ttl_seconds INTEGER DEFAULT 3600, -- 1 hour default, change as needed |
| 57 | + PRIMARY KEY (session_id, agent_id) |
| 58 | +); |
| 59 | + |
| 60 | +-- ============================================ |
| 61 | +-- Agent communication tables |
| 62 | +-- ============================================ |
| 63 | +USE SCHEMA AGENT_COORDINATION; |
| 64 | + |
| 65 | +-- Keep track of all our agents |
| 66 | +CREATE OR REPLACE TABLE AGENT_REGISTRY ( |
| 67 | + agent_id VARCHAR(100) PRIMARY KEY, |
| 68 | + agent_type VARCHAR(50), |
| 69 | + capabilities ARRAY, |
| 70 | + status VARCHAR(20) DEFAULT 'INACTIVE', |
| 71 | + circuit_assignments ARRAY, |
| 72 | + created_at TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(), |
| 73 | + last_heartbeat TIMESTAMP_NTZ -- To check if agent is still alive |
| 74 | +); |
| 75 | + |
| 76 | +-- Message passing between agents |
| 77 | +CREATE OR REPLACE TABLE AGENT_MESSAGES ( |
| 78 | + message_id VARCHAR(36) DEFAULT UUID_STRING(), |
| 79 | + from_agent_id VARCHAR(100), |
| 80 | + to_agent_id VARCHAR(100), |
| 81 | + circuit_id VARCHAR(100), |
| 82 | + message_type VARCHAR(50), |
| 83 | + payload VARIANT, -- Flexible JSON payload |
| 84 | + priority INTEGER DEFAULT 5, -- 1-10 scale |
| 85 | + status VARCHAR(20) DEFAULT 'PENDING', |
| 86 | + created_at TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(), |
| 87 | + processed_at TIMESTAMP_NTZ, |
| 88 | + PRIMARY KEY (message_id) |
| 89 | +) CLUSTER BY (to_agent_id, status, priority); -- Optimize for message polling |
| 90 | + |
| 91 | +-- Stream for real-time message processing |
| 92 | +CREATE OR REPLACE STREAM AGENT_MESSAGE_STREAM ON TABLE AGENT_MESSAGES; |
| 93 | + |
| 94 | +-- Event bus for the synaptic system |
| 95 | +CREATE OR REPLACE TABLE SYNAPTIC_EVENTS ( |
| 96 | + event_id VARCHAR(36) DEFAULT UUID_STRING(), |
| 97 | + circuit_id VARCHAR(100), |
| 98 | + event_type VARCHAR(50), |
| 99 | + source_module VARCHAR(100), |
| 100 | + target_modules ARRAY, |
| 101 | + event_data VARIANT, |
| 102 | + timestamp TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(), |
| 103 | + PRIMARY KEY (event_id) |
| 104 | +) CLUSTER BY (circuit_id, timestamp); |
| 105 | + |
| 106 | +CREATE OR REPLACE STREAM SYNAPTIC_EVENT_STREAM ON TABLE SYNAPTIC_EVENTS; |
| 107 | + |
| 108 | +-- ============================================ |
| 109 | +-- Analytics & tracking |
| 110 | +-- ============================================ |
| 111 | +USE SCHEMA ANALYTICS; |
| 112 | + |
| 113 | +-- Track every decision for debugging/audit |
| 114 | +CREATE OR REPLACE TABLE DECISION_TRAILS ( |
| 115 | + trail_id VARCHAR(36) DEFAULT UUID_STRING(), |
| 116 | + agent_id VARCHAR(100), |
| 117 | + circuit_id VARCHAR(100), |
| 118 | + decision_timestamp TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(), |
| 119 | + input_context VARIANT, |
| 120 | + reasoning_steps ARRAY, -- Step by step what the agent thought |
| 121 | + alternatives_considered VARIANT, |
| 122 | + final_decision VARIANT, |
| 123 | + confidence_score FLOAT, |
| 124 | + execution_time_ms INTEGER, |
| 125 | + PRIMARY KEY (trail_id) |
| 126 | +) CLUSTER BY (agent_id, decision_timestamp); |
| 127 | + |
| 128 | +-- Performance metrics |
| 129 | +CREATE OR REPLACE TABLE AGENT_METRICS ( |
| 130 | + metric_id VARCHAR(36) DEFAULT UUID_STRING(), |
| 131 | + agent_id VARCHAR(100), |
| 132 | + circuit_id VARCHAR(100), |
| 133 | + metric_timestamp TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(), |
| 134 | + performance_metrics OBJECT, |
| 135 | + resource_usage OBJECT, |
| 136 | + error_count INTEGER DEFAULT 0, |
| 137 | + success_rate FLOAT, |
| 138 | + avg_response_time_ms FLOAT, |
| 139 | + PRIMARY KEY (metric_id) |
| 140 | +) CLUSTER BY (agent_id, metric_timestamp); |
| 141 | + |
| 142 | +-- ============================================ |
| 143 | +-- Multimodal storage (images, audio, etc) |
| 144 | +-- ============================================ |
| 145 | +USE SCHEMA MULTIMODAL_DATA; |
| 146 | + |
| 147 | +-- Store references to multimodal data |
| 148 | +CREATE OR REPLACE TABLE MULTIMODAL_INPUTS ( |
| 149 | + input_id VARCHAR(36) DEFAULT UUID_STRING(), |
| 150 | + agent_id VARCHAR(100), |
| 151 | + circuit_id VARCHAR(100), |
| 152 | + input_type VARCHAR(20), -- TEXT, IMAGE, AUDIO, VIDEO |
| 153 | + raw_data VARIANT, -- Small stuff goes here |
| 154 | + processed_data VARIANT, |
| 155 | + embeddings ARRAY, |
| 156 | + metadata OBJECT, |
| 157 | + storage_location VARCHAR(500), -- For big files, store path to stage |
| 158 | + created_at TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(), |
| 159 | + PRIMARY KEY (input_id) |
| 160 | +) CLUSTER BY (agent_id, input_type); |
| 161 | + |
| 162 | +-- Stages for large files |
| 163 | +CREATE OR REPLACE STAGE MULTIMODAL_STAGE |
| 164 | + FILE_FORMAT = (TYPE = 'PARQUET'); |
| 165 | + |
| 166 | +CREATE OR REPLACE STAGE IMAGE_STAGE |
| 167 | + FILE_FORMAT = (TYPE = 'BINARY'); |
| 168 | + |
| 169 | +-- ============================================ |
| 170 | +-- Helper procedures |
| 171 | +-- ============================================ |
| 172 | +USE SCHEMA AGENT_COORDINATION; |
| 173 | + |
| 174 | +-- Quick way to get all recent memories for an agent |
| 175 | +CREATE OR REPLACE PROCEDURE GET_AGENT_MEMORY( |
| 176 | + agent_id_param VARCHAR, |
| 177 | + lookback_hours INTEGER |
| 178 | +) |
| 179 | +RETURNS TABLE (memory_type VARCHAR, content VARIANT, timestamp TIMESTAMP_NTZ) |
| 180 | +LANGUAGE SQL |
| 181 | +AS |
| 182 | +$$ |
| 183 | +DECLARE |
| 184 | + res RESULTSET; |
| 185 | +BEGIN |
| 186 | + -- Grab both long-term and working memory |
| 187 | + res := ( |
| 188 | + SELECT 'EPISODIC' as memory_type, context as content, timestamp |
| 189 | + FROM MEMORY_STORE.EPISODIC_MEMORY |
| 190 | + WHERE agent_id = :agent_id_param |
| 191 | + AND timestamp >= DATEADD('hour', -:lookback_hours, CURRENT_TIMESTAMP()) |
| 192 | + UNION ALL |
| 193 | + SELECT 'WORKING' as memory_type, memory_state as content, active_from as timestamp |
| 194 | + FROM MEMORY_STORE.WORKING_MEMORY |
| 195 | + WHERE agent_id = :agent_id_param |
| 196 | + AND DATEADD('second', ttl_seconds, active_from) > CURRENT_TIMESTAMP() |
| 197 | + ORDER BY timestamp DESC |
| 198 | + ); |
| 199 | + RETURN TABLE(res); |
| 200 | +END; |
| 201 | +$$; |
| 202 | + |
| 203 | +-- Run multiple circuits at once |
| 204 | +CREATE OR REPLACE PROCEDURE EXECUTE_PARALLEL_CIRCUITS( |
| 205 | + circuit_ids ARRAY |
| 206 | +) |
| 207 | +RETURNS VARCHAR |
| 208 | +LANGUAGE JAVASCRIPT |
| 209 | +AS |
| 210 | +$$ |
| 211 | + var results = []; |
| 212 | + // Fire off all circuits in parallel |
| 213 | + for (var i = 0; i < CIRCUIT_IDS.length; i++) { |
| 214 | + var circuit_id = CIRCUIT_IDS[i]; |
| 215 | + |
| 216 | + var stmt = snowflake.createStatement({ |
| 217 | + sqlText: `INSERT INTO AGENT_COORDINATION.SYNAPTIC_EVENTS |
| 218 | + (circuit_id, event_type, source_module, event_data) |
| 219 | + VALUES (?, 'CIRCUIT_ACTIVATED', 'ORCHESTRATOR', OBJECT_CONSTRUCT('status', 'processing'))`, |
| 220 | + binds: [circuit_id] |
| 221 | + }); |
| 222 | + stmt.executeAsync(); |
| 223 | + results.push(circuit_id); |
| 224 | + } |
| 225 | + return 'Started circuits: ' + results.join(', '); |
| 226 | +$$; |
| 227 | + |
| 228 | +-- ============================================ |
| 229 | +-- Automated tasks |
| 230 | +-- ============================================ |
| 231 | + |
| 232 | +-- Process messages every minute |
| 233 | +CREATE OR REPLACE TASK PROCESS_AGENT_MESSAGES |
| 234 | + WAREHOUSE = COMPUTE_WH -- Change to your warehouse |
| 235 | + SCHEDULE = '1 MINUTE' |
| 236 | +AS |
| 237 | + INSERT INTO AGENT_COORDINATION.SYNAPTIC_EVENTS (circuit_id, event_type, source_module, target_modules, event_data) |
| 238 | + SELECT |
| 239 | + circuit_id, |
| 240 | + 'MESSAGE_RELAY', |
| 241 | + from_agent_id, |
| 242 | + ARRAY_CONSTRUCT(to_agent_id), |
| 243 | + payload |
| 244 | + FROM AGENT_COORDINATION.AGENT_MESSAGE_STREAM |
| 245 | + WHERE METADATA$ACTION = 'INSERT' |
| 246 | + AND METADATA$ISUPDATE = FALSE; |
| 247 | + |
| 248 | +-- Clean up old working memory every 6 hours |
| 249 | +CREATE OR REPLACE TASK CLEANUP_EXPIRED_MEMORY |
| 250 | + WAREHOUSE = COMPUTE_WH -- Change to your warehouse |
| 251 | + SCHEDULE = 'USING CRON 0 */6 * * * UTC' |
| 252 | +AS |
| 253 | + DELETE FROM MEMORY_STORE.WORKING_MEMORY |
| 254 | + WHERE DATEADD('second', ttl_seconds, active_from) < CURRENT_TIMESTAMP(); |
| 255 | + |
| 256 | +-- Turn on the tasks |
| 257 | +ALTER TASK PROCESS_AGENT_MESSAGES RESUME; |
| 258 | +ALTER TASK CLEANUP_EXPIRED_MEMORY RESUME; |
| 259 | + |
| 260 | +-- ============================================ |
| 261 | +-- Quick analytics views |
| 262 | +-- ============================================ |
| 263 | +USE SCHEMA ANALYTICS; |
| 264 | + |
| 265 | +-- Simple dashboard for agent performance |
| 266 | +CREATE OR REPLACE VIEW AGENT_PERFORMANCE_DASHBOARD AS |
| 267 | +SELECT |
| 268 | + am.agent_id, |
| 269 | + ar.agent_type, |
| 270 | + ar.capabilities, |
| 271 | + AVG(am.success_rate) as avg_success_rate, |
| 272 | + AVG(am.avg_response_time_ms) as avg_response_time, |
| 273 | + SUM(am.error_count) as total_errors, |
| 274 | + COUNT(DISTINCT dt.trail_id) as total_decisions, |
| 275 | + AVG(dt.confidence_score) as avg_confidence |
| 276 | +FROM AGENT_METRICS am |
| 277 | +JOIN AGENT_COORDINATION.AGENT_REGISTRY ar ON am.agent_id = ar.agent_id |
| 278 | +LEFT JOIN DECISION_TRAILS dt ON am.agent_id = dt.agent_id |
| 279 | +WHERE am.metric_timestamp >= DATEADD('day', -7, CURRENT_TIMESTAMP()) -- Last week |
| 280 | +GROUP BY am.agent_id, ar.agent_type, ar.capabilities; |
| 281 | + |
| 282 | +-- See how agents are using memory |
| 283 | +CREATE OR REPLACE VIEW MEMORY_USAGE_PATTERNS AS |
| 284 | +SELECT |
| 285 | + agent_id, |
| 286 | + DATE_TRUNC('hour', timestamp) as hour, |
| 287 | + COUNT(*) as memory_accesses, |
| 288 | + ARRAY_AGG(DISTINCT event_type) as event_types, |
| 289 | + AVG(ARRAY_SIZE(embeddings)) as avg_embedding_size |
| 290 | +FROM MEMORY_STORE.EPISODIC_MEMORY |
| 291 | +WHERE timestamp >= DATEADD('day', -30, CURRENT_TIMESTAMP()) -- Last month |
| 292 | +GROUP BY agent_id, hour |
| 293 | +ORDER BY hour DESC; |
| 294 | + |
| 295 | +-- ============================================ |
| 296 | +-- Set up basic access controls |
| 297 | +-- ============================================ |
| 298 | + |
| 299 | +CREATE ROLE IF NOT EXISTS NEURON_ADMIN; -- Full access |
| 300 | +CREATE ROLE IF NOT EXISTS NEURON_AGENT; -- Read/write for agents |
| 301 | +CREATE ROLE IF NOT EXISTS NEURON_ANALYST; -- Read-only for analytics |
| 302 | + |
| 303 | +-- Basic permissions |
| 304 | +GRANT ALL ON DATABASE NEURON_AI TO ROLE NEURON_ADMIN; |
| 305 | +GRANT USAGE ON DATABASE NEURON_AI TO ROLE NEURON_AGENT; |
| 306 | +GRANT USAGE ON DATABASE NEURON_AI TO ROLE NEURON_ANALYST; |
| 307 | + |
| 308 | +GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA MEMORY_STORE TO ROLE NEURON_AGENT; |
| 309 | +GRANT SELECT, INSERT ON ALL TABLES IN SCHEMA AGENT_COORDINATION TO ROLE NEURON_AGENT; |
| 310 | +GRANT SELECT ON ALL VIEWS IN SCHEMA ANALYTICS TO ROLE NEURON_ANALYST; |
| 311 | + |
| 312 | +-- ============================================ |
| 313 | +-- Add some test agents to get started |
| 314 | +-- ============================================ |
| 315 | + |
| 316 | +INSERT INTO AGENT_COORDINATION.AGENT_REGISTRY (agent_id, agent_type, capabilities, status) |
| 317 | +VALUES |
| 318 | + ('REASONER_001', 'DeliberativeAgent', ARRAY_CONSTRUCT('contradiction_detection', 'memory_retrieval'), 'ACTIVE'), |
| 319 | + ('INTAKE_001', 'ReflexAgent', ARRAY_CONSTRUCT('sentiment_analysis', 'intent_detection'), 'ACTIVE'); |
| 320 | + |
| 321 | +-- All done! |
| 322 | +SELECT 'Neuron Snowflake setup complete - agents ready to go!' as STATUS; |
0 commit comments