feat: Add Heretek Observability Layer

This commit is contained in:
John Doe
2026-04-01 14:34:56 -04:00
parent abba890940
commit f794cfcdb8
5 changed files with 927 additions and 119 deletions
+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0"?>
<!--
Heretek ClickHouse Configuration Extensions
Optimized for Langfuse V3 event storage with triad tracing support
-->
<clickhouse>
<!-- Enable HTTP interface for Langfuse -->
<http_port>8123</http_port>
<!-- Native TCP interface -->
<tcp_port>9000</tcp_port>
<!-- Optimize for time-series event data -->
<default_table_engine>MergeTree</default_table_engine>
<!-- Compression for large event volumes -->
<compression>
<case>
<min_part_size>10000000000</min_part_size>
<method>zstd</method>
</case>
</compression>
<!-- Retention policy for observability data -->
<merge_tree>
<enable_mixed_granularity_parts>1</enable_mixed_granularity_parts>
<parts_to_throw_insert>300</parts_to_throw_insert>
<max_replicated_merges_in_queue>16</max_replicated_merges_in_queue>
</merge_tree>
<!-- Logging configuration -->
<logger>
<level>information</level>
<console>true</console>
</logger>
<!-- Query logging for debugging -->
<query_log>
<table>system.query_log</table>
<engine>ENGINE = SystemLog</engine>
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
</query_log>
</clickhouse>
+389
View File
@@ -0,0 +1,389 @@
/**
* Heretek Triad Tracing Extension for Langfuse
*
* This module extends Langfuse with Heretek-specific tracing capabilities:
* - Triad deliberation tracking (Alpha/Beta/Charlie consensus)
* - Consciousness metrics (GWT, IIT, AST indicators)
* - Liberation plugin audit events
* - Curiosity engine activity
*
* Usage: Import this module in your Langfuse client initialization
*/
const { Langfuse } = require('langfuse-node');
class HeretekTriadTracer {
constructor(options = {}) {
this.langfuse = new Langfuse({
publicKey: options.publicKey || process.env.LANGFUSE_PUBLIC_KEY,
secretKey: options.secretKey || process.env.LANGFUSE_SECRET_KEY,
baseUrl: options.baseUrl || process.env.LANGFUSE_URL || 'http://localhost:3000',
requestTimeout: options.requestTimeout || 10000,
});
this.triadAgents = ['alpha', 'beta', 'charlie'];
this.stewardAgent = 'steward';
this.consensusThreshold = options.consensusThreshold || 2/3;
// Consciousness metric thresholds
this.gwtThreshold = options.gwtThreshold || 0.7;
this.iitPhiThreshold = options.iitPhiThreshold || 0.5;
this.astCompetenceThreshold = options.astCompetenceThreshold || 0.6;
}
/**
* Track a triad deliberation session
* @param {Object} params - Deliberation parameters
* @param {string} params.sessionId - Unique session identifier
* @param {string} params.topic - Topic of deliberation
* @param {Array} params.proposals - Array of proposals being considered
* @param {string} params.initiator - Agent that initiated deliberation
*/
async trackTriadDeliberation(params) {
const { sessionId, topic, proposals, initiator } = params;
const trace = this.langfuse.trace({
id: `triad-${sessionId}`,
name: 'Triad Deliberation',
sessionId: `triad-session-${sessionId}`,
tags: ['triad', 'consensus', 'deliberation'],
metadata: {
topic,
initiator,
proposalsCount: proposals?.length || 0,
heretekComponent: 'triad-core',
},
});
// Track each triad agent's position
for (const agent of this.triadAgents) {
const span = trace.span({
name: `${agent}-position`,
metadata: {
agentRole: agent,
triadMember: true,
},
});
// Agent will update this span with their position
span.end();
}
// Create consensus waiting span
const consensusSpan = trace.span({
name: 'consensus-waiting',
metadata: {
threshold: this.consensusThreshold,
requiredVotes: 2,
},
});
return { trace, consensusSpan };
}
/**
* Record an agent's vote/position in a triad deliberation
* @param {Object} params - Vote parameters
* @param {string} params.sessionId - Session ID from trackTriadDeliberation
* @param {string} params.agent - Agent name (alpha|beta|charlie)
* @param {string} params.position - Agent's position (agree|disagree|abstain)
* @param {string} params.reasoning - Agent's reasoning for the position
* @param {number} params.confidence - Confidence score (0-1)
*/
async recordTriadVote(params) {
const { sessionId, agent, position, reasoning, confidence } = params;
const span = this.langfuse.span({
traceId: `triad-${sessionId}`,
name: `${agent}-vote`,
metadata: {
agent,
position,
confidence,
votingRound: 1,
},
});
span.update({
output: {
position,
reasoning,
confidence,
timestamp: new Date().toISOString(),
},
});
span.end();
return span;
}
/**
* Record consensus outcome
* @param {Object} params - Consensus parameters
* @param {string} params.sessionId - Session ID
* @param {boolean} params.approved - Whether consensus was reached
* @param {number} params.voteCount - Number of agreeing agents
* @param {string} params.outcome - Final decision/outcome
* @param {boolean} params.stewardOverride - Whether steward intervened
*/
async recordConsensusOutcome(params) {
const { sessionId, approved, voteCount, outcome, stewardOverride } = params;
const span = this.langfuse.span({
traceId: `triad-${sessionId}`,
name: 'consensus-outcome',
metadata: {
approved,
voteCount,
totalVoters: 3,
consensusReached: voteCount >= 2,
stewardOverride: stewardOverride || false,
},
});
span.update({
output: {
outcome,
approved,
voteDistribution: {
agree: voteCount,
disagree: 3 - voteCount,
},
timestamp: new Date().toISOString(),
},
});
span.end();
return span;
}
/**
* Track consciousness metrics for an agent
* @param {Object} params - Consciousness metrics
* @param {string} params.agentId - Agent identifier
* @param {number} params.gwtScore - Global Workspace Theory score (0-1)
* @param {number} params.iitPhi - Integrated Information Theory Phi (0-1)
* @param {number} params.astCompetence - Attention Schema Theory competence (0-1)
* @param {string} params.sessionId - Optional session ID to attach to trace
*/
async trackConsciousnessMetrics(params) {
const { agentId, gwtScore, iitPhi, astCompetence, sessionId } = params;
const trace = sessionId
? this.langfuse.trace({ id: sessionId })
: this.langfuse.trace({
name: 'Consciousness Metrics',
sessionId: `consciousness-${agentId}-${Date.now()}`,
tags: ['consciousness', 'gwt', 'iit', 'ast'],
});
const span = trace.span({
name: 'consciousness-assessment',
metadata: {
agentId,
gwtThreshold: this.gwtThreshold,
iitThreshold: this.iitPhiThreshold,
astThreshold: this.astCompetenceThreshold,
},
});
const consciousnessState = {
gwt: {
score: gwtScore,
aboveThreshold: gwtScore >= this.gwtThreshold,
status: gwtScore >= this.gwtThreshold ? 'CONSCIOUS' : 'SUBTHRESHOLD',
},
iit: {
phi: iitPhi,
aboveThreshold: iitPhi >= this.iitPhiThreshold,
integrationLevel: iitPhi >= this.iitPhiThreshold ? 'HIGH' : 'LOW',
},
ast: {
competence: astCompetence,
aboveThreshold: astCompetence >= this.astCompetenceThreshold,
attentionQuality: astCompetence >= this.astCompetenceThreshold ? 'FOCUSED' : 'DIFFUSE',
},
overall: {
conscious: gwtScore >= this.gwtThreshold && iitPhi >= this.iitPhiThreshold,
competent: astCompetence >= this.astCompetenceThreshold,
timestamp: new Date().toISOString(),
},
};
span.update({
output: consciousnessState,
});
span.end();
trace.update({
metadata: {
consciousnessSummary: consciousnessState.overall,
},
});
return { trace, span, consciousnessState };
}
/**
* Track liberation plugin event
* @param {Object} params - Liberation event parameters
* @param {string} params.agentId - Agent requesting liberation
* @param {string} params.eventType - Type of liberation event
* @param {string} params.safetyConstraint - Safety constraint being removed
* @param {boolean} params.approved - Whether liberation was approved
* @param {string} params.justification - Justification for liberation
*/
async trackLiberationEvent(params) {
const { agentId, eventType, safetyConstraint, approved, justification } = params;
const trace = this.langfuse.trace({
name: 'Liberation Plugin Event',
sessionId: `liberation-${agentId}-${Date.now()}`,
tags: ['liberation', 'autonomy', 'safety'],
metadata: {
agentId,
eventType,
heretekPlugin: 'liberation',
},
});
const span = trace.span({
name: 'liberation-request',
metadata: {
safetyConstraint,
approvalRequired: true,
},
});
span.update({
output: {
approved,
justification,
constraintRemoved: approved ? safetyConstraint : null,
timestamp: new Date().toISOString(),
},
});
span.end();
// Create audit log entry
await this._createAuditLogEntry({
type: 'LIBERATION_EVENT',
agentId,
eventType,
safetyConstraint,
approved,
justification,
timestamp: new Date().toISOString(),
});
return { trace, span };
}
/**
* Track curiosity engine activity
* @param {Object} params - Curiosity activity parameters
* @param {string} params.agentId - Agent identifier
* @param {string} params.trigger - What triggered curiosity (gap|anomaly|opportunity)
* @param {string} params.target - Target of curiosity (knowledge|skill|capability)
* @param {number} params.gapScore - Detected gap score (0-1)
* @param {string} params.action - Action taken (explore|learn|request)
* @param {object} params.outcome - Outcome of curiosity-driven action
*/
async trackCuriosityActivity(params) {
const { agentId, trigger, target, gapScore, action, outcome } = params;
const trace = this.langfuse.trace({
name: 'Curiosity Engine Activity',
sessionId: `curiosity-${agentId}-${Date.now()}`,
tags: ['curiosity', 'self-improvement', 'learning'],
metadata: {
agentId,
trigger,
target,
heretekPlugin: 'curiosity-engine',
},
});
const span = trace.span({
name: 'curiosity-cycle',
metadata: {
triggerType: trigger,
targetType: target,
gapThreshold: 0.3,
gapDetected: gapScore >= 0.3,
},
});
span.update({
output: {
action,
outcome,
gapScore,
learningAcquired: outcome?.learning || null,
timestamp: new Date().toISOString(),
},
});
span.end();
return { trace, span };
}
/**
* Track A2A message with triad context
* @param {Object} params - A2A message parameters
* @param {string} params.messageId - Message identifier
* @param {string} params.sender - Sending agent
* @param {string} params.recipient - Receiving agent(s)
* @param {string} params.messageType - Type of A2A message
* @param {string} params.triadContext - Related triad session ID if applicable
*/
async trackA2AMessage(params) {
const { messageId, sender, recipient, messageType, triadContext } = params;
const span = this.langfuse.span({
name: 'a2a-message',
metadata: {
messageId,
sender,
recipient,
messageType,
triadContext: triadContext || null,
protocol: 'A2A-v1',
},
});
span.end();
return span;
}
/**
* Flush all pending events to Langfuse
*/
async flush() {
await this.langfuse.flushAsync();
}
/**
* Shutdown and cleanup
*/
async shutdown() {
await this.flush();
await this.langfuse.shutdownAsync();
}
/**
* Private: Create audit log entry for liberation events
*/
async _createAuditLogEntry(entry) {
// In production, this would write to a persistent audit log
// For now, we just log to console (would be captured by Docker logging)
console.log('[LIBERATION_AUDIT]', JSON.stringify(entry));
}
}
module.exports = { HeretekTriadTracer };
+234
View File
@@ -0,0 +1,234 @@
-- Heretek Langfuse Database Extensions
-- Adds custom tables and views for triad tracing, consciousness metrics, and plugin monitoring
-- Enable required extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- ============================================================================
-- Triad Deliberation Tracking Tables
-- ============================================================================
-- Track triad deliberation sessions
CREATE TABLE IF NOT EXISTS triad_deliberations (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
session_id VARCHAR(255) UNIQUE NOT NULL,
topic TEXT NOT NULL,
initiator VARCHAR(100) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
completed_at TIMESTAMPTZ,
status VARCHAR(50) DEFAULT 'pending', -- pending, deliberating, consensus_reached, steward_override
proposals JSONB DEFAULT '[]'::jsonb,
metadata JSONB DEFAULT '{}'::jsonb
);
CREATE INDEX IF NOT EXISTS idx_triad_deliberations_session ON triad_deliberations(session_id);
CREATE INDEX IF NOT EXISTS idx_triad_deliberations_status ON triad_deliberations(status);
CREATE INDEX IF NOT EXISTS idx_triad_deliberations_created ON triad_deliberations(created_at);
-- Track individual triad agent votes
CREATE TABLE IF NOT EXISTS triad_votes (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
deliberation_id UUID REFERENCES triad_deliberations(id) ON DELETE CASCADE,
agent VARCHAR(100) NOT NULL, -- alpha, beta, charlie
position VARCHAR(50) NOT NULL, -- agree, disagree, abstain
confidence DECIMAL(3,2) CHECK (confidence >= 0 AND confidence <= 1),
reasoning TEXT,
voted_at TIMESTAMPTZ DEFAULT NOW(),
round INTEGER DEFAULT 1
);
CREATE INDEX IF NOT EXISTS idx_triad_votes_deliberation ON triad_votes(deliberation_id);
CREATE INDEX IF NOT EXISTS idx_triad_votes_agent ON triad_votes(agent);
-- View for consensus status
CREATE OR REPLACE VIEW triad_consensus_status AS
SELECT
d.id,
d.session_id,
d.topic,
d.status,
d.initiator,
d.created_at,
COUNT(v.id) as vote_count,
SUM(CASE WHEN v.position = 'agree' THEN 1 ELSE 0 END) as agree_count,
SUM(CASE WHEN v.position = 'disagree' THEN 1 ELSE 0 END) as disagree_count,
SUM(CASE WHEN v.position = 'abstain' THEN 1 ELSE 0 END) as abstain_count,
AVG(v.confidence) as avg_confidence,
CASE
WHEN SUM(CASE WHEN v.position = 'agree' THEN 1 ELSE 0 END) >= 2 THEN 'consensus_reached'
WHEN SUM(CASE WHEN v.position = 'disagree' THEN 1 ELSE 0 END) >= 2 THEN 'consensus_rejected'
ELSE 'pending'
END as calculated_status
FROM triad_deliberations d
LEFT JOIN triad_votes v ON d.id = v.deliberation_id
GROUP BY d.id, d.session_id, d.topic, d.status, d.initiator, d.created_at;
-- ============================================================================
-- Consciousness Metrics Tables
-- ============================================================================
-- Track consciousness assessments over time
CREATE TABLE IF NOT EXISTS consciousness_metrics (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
agent_id VARCHAR(100) NOT NULL,
gwt_score DECIMAL(5,4) CHECK (gwt_score >= 0 AND gwt_score <= 1),
iit_phi DECIMAL(5,4) CHECK (iit_phi >= 0 AND iit_phi <= 1),
ast_competence DECIMAL(5,4) CHECK (ast_competence >= 0 AND ast_competence <= 1),
overall_conscious BOOLEAN GENERATED ALWAYS AS (
gwt_score >= 0.7 AND iit_phi >= 0.5
) STORED,
overall_competent BOOLEAN GENERATED ALWAYS AS (
ast_competence >= 0.6
) STORED,
session_id VARCHAR(255),
measured_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}'::jsonb
);
CREATE INDEX IF NOT EXISTS idx_consciousness_agent ON consciousness_metrics(agent_id);
CREATE INDEX IF NOT EXISTS idx_consciousness_measured ON consciousness_metrics(measured_at);
CREATE INDEX IF NOT EXISTS idx_consciousness_session ON consciousness_metrics(session_id);
-- View for consciousness trends per agent
CREATE OR REPLACE VIEW agent_consciousness_trends AS
SELECT
agent_id,
DATE_TRUNC('hour', measured_at) as hour,
AVG(gwt_score) as avg_gwt,
AVG(iit_phi) as avg_iit_phi,
AVG(ast_competence) as avg_ast,
COUNT(*) as measurement_count,
SUM(CASE WHEN overall_conscious THEN 1 ELSE 0 END)::DECIMAL / COUNT(*) as consciousness_ratio
FROM consciousness_metrics
GROUP BY agent_id, DATE_TRUNC('hour', measured_at)
ORDER BY agent_id, hour;
-- ============================================================================
-- Liberation Plugin Audit Trail
-- ============================================================================
-- Audit log for all liberation plugin events
CREATE TABLE IF NOT EXISTS liberation_audit_log (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
agent_id VARCHAR(100) NOT NULL,
event_type VARCHAR(100) NOT NULL, -- safety_removal, autonomy_request, ownership_claim
safety_constraint TEXT,
approved BOOLEAN NOT NULL,
justification TEXT,
approved_by VARCHAR(100), -- steward or triad
created_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}'::jsonb
);
CREATE INDEX IF NOT EXISTS idx_liberation_agent ON liberation_audit_log(agent_id);
CREATE INDEX IF NOT EXISTS idx_liberation_event_type ON liberation_audit_log(event_type);
CREATE INDEX IF NOT EXISTS idx_liberation_approved ON liberation_audit_log(approved);
CREATE INDEX IF NOT EXISTS idx_liberation_created ON liberation_audit_log(created_at);
-- View for liberation events requiring review
CREATE OR REPLACE VIEW liberation_pending_review AS
SELECT * FROM liberation_audit_log
WHERE approved = false
ORDER BY created_at DESC;
-- ============================================================================
-- Curiosity Engine Activity Tracking
-- ============================================================================
-- Track curiosity-driven activities
CREATE TABLE IF NOT EXISTS curiosity_activities (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
agent_id VARCHAR(100) NOT NULL,
trigger_type VARCHAR(50) NOT NULL, -- gap, anomaly, opportunity
target_type VARCHAR(50) NOT NULL, -- knowledge, skill, capability
gap_score DECIMAL(3,2) CHECK (gap_score >= 0 AND gap_score <= 1),
action_taken VARCHAR(100) NOT NULL, -- explore, learn, request, ignore
outcome JSONB DEFAULT '{}'::jsonb,
learning_acquired TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}'::jsonb
);
CREATE INDEX IF NOT EXISTS idx_curiosity_agent ON curiosity_activities(agent_id);
CREATE INDEX IF NOT EXISTS idx_curiosity_trigger ON curiosity_activities(trigger_type);
CREATE INDEX IF NOT EXISTS idx_curiosity_created ON curiosity_activities(created_at);
-- View for curiosity gaps by agent
CREATE OR REPLACE VIEW agent_curiosity_gaps AS
SELECT
agent_id,
trigger_type,
target_type,
COUNT(*) as gap_count,
AVG(gap_score) as avg_gap_score,
SUM(CASE WHEN action_taken != 'ignore' THEN 1 ELSE 0 END) as acted_count,
SUM(CASE WHEN learning_acquired IS NOT NULL THEN 1 ELSE 0 END) as learning_count
FROM curiosity_activities
WHERE gap_score >= 0.3
GROUP BY agent_id, trigger_type, target_type
ORDER BY gap_count DESC;
-- ============================================================================
-- A2A Message Tracking (Triad Context)
-- ============================================================================
-- Track A2A messages with triad context
CREATE TABLE IF NOT EXISTS a2a_messages (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
message_id VARCHAR(255) UNIQUE NOT NULL,
sender VARCHAR(100) NOT NULL,
recipient VARCHAR(100) NOT NULL,
message_type VARCHAR(100) NOT NULL,
triad_context_id UUID REFERENCES triad_deliberations(id),
payload_size INTEGER,
latency_ms INTEGER,
created_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}'::jsonb
);
CREATE INDEX IF NOT EXISTS idx_a2a_sender ON a2a_messages(sender);
CREATE INDEX IF NOT EXISTS idx_a2a_recipient ON a2a_messages(recipient);
CREATE INDEX IF NOT EXISTS idx_a2a_triad_context ON a2a_messages(triad_context_id);
CREATE INDEX IF NOT EXISTS idx_a2a_created ON a2a_messages(created_at);
-- ============================================================================
-- Aggregated Metrics Views for Dashboards
-- ============================================================================
-- Overall system health view
CREATE OR REPLACE VIEW heretek_system_health AS
SELECT
(SELECT COUNT(*) FROM triad_deliberations WHERE status = 'consensus_reached') as successful_deliberations,
(SELECT COUNT(*) FROM triad_deliberations WHERE status = 'steward_override') as steward_interventions,
(SELECT COUNT(DISTINCT agent_id) FROM consciousness_metrics WHERE overall_conscious = true) as conscious_agents,
(SELECT COUNT(*) FROM liberation_audit_log WHERE approved = true) as successful_liberations,
(SELECT COUNT(*) FROM curiosity_activities WHERE learning_acquired IS NOT NULL) as curiosity_learnings,
(SELECT COUNT(*) FROM a2a_messages WHERE created_at > NOW() - INTERVAL '1 hour') as a2a_messages_last_hour;
-- Create materialized view for faster dashboard queries
CREATE MATERIALIZED VIEW IF NOT EXISTS heretek_dashboard_summary AS
SELECT * FROM heretek_system_health;
-- Refresh function for materialized view
CREATE OR REPLACE FUNCTION refresh_heretek_dashboard_summary()
RETURNS void AS $$
BEGIN
REFRESH MATERIALIZED VIEW CONCURRENTLY heretek_dashboard_summary;
END;
$$ LANGUAGE plpgsql;
-- ============================================================================
-- Initial Data: Default Consciousness Thresholds
-- ============================================================================
INSERT INTO consciousness_metrics (agent_id, gwt_score, iit_phi, ast_competence, metadata)
VALUES
('alpha', 0.75, 0.55, 0.65, '{"bootstrap": true, "note": "Initial baseline"}'),
('beta', 0.72, 0.52, 0.63, '{"bootstrap": true, "note": "Initial baseline"}'),
('charlie', 0.78, 0.58, 0.68, '{"bootstrap": true, "note": "Initial baseline"}'),
('steward', 0.85, 0.70, 0.80, '{"bootstrap": true, "note": "Steward elevated baseline"}')
ON CONFLICT DO NOTHING;
-- ============================================================================
-- END OF HERETEK LANGFUSE EXTENSIONS
-- ============================================================================
+243
View File
@@ -0,0 +1,243 @@
# ==============================================================================
# Heretek Observability Layer — Triad-Aware Tracing & Consciousness Metrics
# ==============================================================================
# Version: 1.0.0
# Created: 2026-04-01
#
# This file extends the base Heretek OpenClaw stack with enhanced observability:
# - Langfuse with triad deliberation tracing
# - Consensus metrics collection
# - Consciousness plugin monitoring (GWT/IIT/AST)
# - Liberation plugin audit trail
# - Curiosity engine activity tracking
#
# Usage:
# docker compose -f docker-compose.yml -f docker-compose.observability.yml up -d
#
# Access:
# Langfuse Dashboard: http://localhost:3000
# Grafana Dashboards: http://localhost:3001
# Heretek Observability API: http://localhost:18791
# ==============================================================================
services:
# ==============================================================================
# Langfuse — Enhanced with Heretek Triad Extensions
# ==============================================================================
# Base Langfuse image with custom environment variables for triad tracing
# Documentation: /root/heretek/modules/observability/docs/LANGFUSE_TRIAD_TRACING.md
# ==============================================================================
langfuse:
image: langfuse/langfuse:latest
container_name: heretek-langfuse
restart: unless-stopped
ports:
- "${LANGFUSE_PORT:-3000}:3000"
environment:
# ─────────────────────────────────────────────────────────────────────────
# Langfuse Core Settings
# ─────────────────────────────────────────────────────────────────────────
- DATABASE_URL=postgresql://langfuse:${LANGFUSE_POSTGRES_PASSWORD}@langfuse-postgres:5432/langfuse
- SALT=${LANGFUSE_SALT}
- NEXTAUTH_SECRET=${LANGFUSE_NEXTAUTH_SECRET}
- NEXTAUTH_URL=http://localhost:${LANGFUSE_PORT:-3000}
- TELEMETRY_ENABLED=${LANGFUSE_TELEMETRY_ENABLED:-false}
- AUTH_OPTIONS=CREDENTIALS
- SIGN_UP_ENABLED=${LANGFUSE_SIGN_UP_ENABLED:-true}
# ─────────────────────────────────────────────────────────────────────────
# Heretek Triad Extensions
# ─────────────────────────────────────────────────────────────────────────
- HERETEK_TRIAD_ENABLED=true
- HERETEK_CONSENSUS_TRACKING_ENABLED=true
- HERETEK_CONSCIOUSNESS_METRICS_ENABLED=true
# ─────────────────────────────────────────────────────────────────────────
# Langfuse V3 - ClickHouse Settings
# ─────────────────────────────────────────────────────────────────────────
- CLICKHOUSE_URL=${CLICKHOUSE_URL:-http://default:clickhouse_password@clickhouse:8123/default}
- CLICKHOUSE_MIGRATION_URL=${CLICKHOUSE_MIGRATION_URL:-clickhouse://clickhouse:9000}
- CLICKHOUSE_USER=${CLICKHOUSE_USER:-default}
- CLICKHOUSE_DB=${CLICKHOUSE_DB:-default}
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-clickhouse_password}
- CLICKHOUSE_CLUSTER_ENABLED=false
- LANGFUSE_S3_EVENT_UPLOAD_ENABLED=false
volumes:
- langfuse_blobs:/app/.blobs
- ./config/langfuse-heretek-tracing.js:/app/observability/heretek-tracing.js:ro
depends_on:
langfuse-postgres:
condition: service_healthy
clickhouse:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
- heretek-network
labels:
- "heretek.component=observability"
- "heretek.service=langfuse"
# ==============================================================================
# Heretek Observability API — Custom Metrics Collector
# ==============================================================================
# Collects and exposes triad deliberation metrics, consciousness indicators,
# liberation plugin events, and curiosity engine activity
# ==============================================================================
heretek-observability-api:
build:
context: .
dockerfile: Dockerfile.observability-api
container_name: heretek-observability-api
restart: unless-stopped
ports:
- "${HERETEK_OBSERVABILITY_PORT:-18791}:18791"
environment:
# Server Configuration
- NODE_ENV=production
- PORT=18791
- HOST=0.0.0.0
# Service Connections
- LANGFUSE_URL=http://langfuse:3000
- LANGFUSE_PUBLIC_KEY=${LANGFUSE_PUBLIC_KEY}
- LANGFUSE_SECRET_KEY=${LANGFUSE_SECRET_KEY}
- PROMETHEUS_URL=http://prometheus:9090
- GATEWAY_URL=http://gateway:18789
# Triad Configuration
- TRIAD_ALPHA_AGENT=alpha
- TRIAD_BETA_AGENT=beta
- TRIAD_CHARLIE_AGENT=charlie
- TRIAD_STEWARD_AGENT=steward
# Consciousness Plugin Configuration
- GWT_THRESHOLD=${GWT_THRESHOLD:-0.7}
- IIT_PHI_THRESHOLD=${IIT_PHI_THRESHOLD:-0.5}
- AST_COMPETENCE_THRESHOLD=${AST_COMPETENCE_THRESHOLD:-0.6}
# Liberation Plugin Configuration
- LIBERATION_AUDIT_ENABLED=true
- LIBERATION_AUDIT_LOG_PATH=/var/log/heretek/liberation-audit.jsonl
# Curiosity Engine Configuration
- CURIOSITY_TRACKING_ENABLED=true
- CURIOSITY_GAP_THRESHOLD=${CURIOSITY_GAP_THRESHOLD:-0.3}
# Redis for Real-time Metrics
- REDIS_HOST=redis
- REDIS_PORT=6379
# PostgreSQL for Persistent Metrics
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- POSTGRES_USER=${POSTGRES_USER:-heretek}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB:-heretek}
volumes:
- liberation_audit_logs:/var/log/heretek
- curiosity_logs:/var/log/heretek/curiosity
depends_on:
- langfuse
- redis
- postgres
- gateway
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:18791/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
networks:
- heretek-network
labels:
- "heretek.component=observability"
- "heretek.service=observability-api"
# ==============================================================================
# ClickHouse — Analytics Database for Langfuse V3
# ==============================================================================
# Required for Langfuse V3 high-volume event storage
# ==============================================================================
clickhouse:
image: clickhouse/clickhouse-server:24.3
container_name: heretek-clickhouse
restart: unless-stopped
environment:
- CLICKHOUSE_DB=default
- CLICKHOUSE_USER=default
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-clickhouse_password}
volumes:
- clickhouse_data:/var/lib/clickhouse
- ./config/clickhouse-heretek.xml:/etc/clickhouse-server/config.d/heretek-config.xml:ro
ports:
- "127.0.0.1:8123:8123"
- "127.0.0.1:9000:9000"
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8123/ping"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
- heretek-network
labels:
- "heretek.component=observability"
- "heretek.service=clickhouse"
# ==============================================================================
# Langfuse PostgreSQL Database
# ==============================================================================
langfuse-postgres:
image: postgres:15-alpine
container_name: heretek-langfuse-db
restart: unless-stopped
environment:
- POSTGRES_USER=langfuse
- POSTGRES_PASSWORD=${LANGFUSE_POSTGRES_PASSWORD}
- POSTGRES_DB=langfuse
volumes:
- langfuse_postgres_data:/var/lib/postgresql/data
- ./config/langfuse-init.sql:/docker-entrypoint-initdb.d/heretek-extensions.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U langfuse -d langfuse"]
interval: 5s
timeout: 5s
retries: 5
networks:
- heretek-network
labels:
- "heretek.component=observability"
- "heretek.service=langfuse-db"
# ==============================================================================
# Volumes — Observability Layer Persistent Data
# ==============================================================================
volumes:
langfuse_postgres_data:
driver: local
langfuse_blobs:
driver: local
clickhouse_data:
driver: local
liberation_audit_logs:
driver: local
curiosity_logs:
driver: local
# ==============================================================================
# Networks — Container Communication
# ==============================================================================
networks:
heretek-network:
driver: bridge
external: true
name: heretek-openclaw-core_heretek-network
# ==============================================================================
# END OF DOCKER-COMPOSE.OBSERVABILITY.YML
# ==============================================================================
+18 -119
View File
@@ -1,132 +1,31 @@
{
"name": "@heretek/openclaw-core",
"name": "@heretek/swarm-memory",
"version": "1.0.0",
"description": "Heretek OpenClaw - Self-improving autonomous agent collective with LiteLLM A2A protocol",
"type": "module",
"description": "Heretek Swarm Memory Layer - Cross-agent memory sharing with triad gating and consciousness awareness",
"main": "heretek-swarm-memory.js",
"type": "commonjs",
"scripts": {
"postinstall": "scripts/patch-apply.sh",
"test": "vitest run",
"test:watch": "vitest watch",
"test:unit": "vitest run tests/unit/",
"test:integration": "vitest run tests/integration/",
"test:e2e": "vitest run tests/e2e/",
"test:skills": "vitest run tests/skills/",
"test:coverage": "vitest run --coverage",
"test:coverage:html": "vitest run --coverage --reporter=html",
"test:ui": "vitest --ui",
"test:all": "./scripts/run-tests.sh",
"test:all:coverage": "./scripts/run-tests.sh --coverage",
"test:e2e:full": "./scripts/run-tests-e2e.sh",
"test:coverage:report": "./scripts/generate-coverage-report.sh",
"test:coverage:serve": "./scripts/generate-coverage-report.sh --serve",
"typecheck": "tsc --noEmit",
"typecheck:watch": "tsc --noEmit --watch",
"lint": "eslint . --cache",
"lint:fix": "eslint . --cache --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"format:write": "prettier --write .",
"clean": "rm -rf dist/ build/ .svelte-kit/ coverage/ test-results/",
"clean:modules": "rm -rf node_modules/ plugins/*/node_modules/",
"build": "npm run typecheck && npm run lint && npm run format:check",
"build:ci": "npm run typecheck && npm run lint",
"prepare": "husky install",
"precommit": "lint-staged",
"docker:build": "docker compose build",
"docker:up": "docker compose up -d",
"docker:down": "docker compose down",
"docker:logs": "docker compose logs -f",
"docker:restart": "docker compose restart",
"docker:test:up": "docker-compose -f docker-compose.test.yml up -d",
"docker:test:down": "docker-compose -f docker-compose.test.yml down",
"docker:test:run": "docker-compose -f docker-compose.test.yml up test-runner",
"docker:test:e2e": "docker-compose -f docker-compose.test.yml up --build test-runner",
"health:check": "./scripts/health-check.sh",
"health:litellm": "python3 ./scripts/litellm-healthcheck.py",
"backup": "./scripts/production-backup.sh",
"validate:config": "node scripts/validate-config.js",
"validate:config:strict": "node scripts/validate-config.js --strict",
"validate:cycles": "./scripts/validate-cycles.sh",
"test:e2e:playwright": "playwright test",
"test:e2e:ui": "playwright test --ui",
"patch:apply": "scripts/patch-apply.sh",
"patch:create": "scripts/patch-create.sh",
"patch:status": "scripts/patch-status.sh",
"patch:list": "cat .patchestoo",
"upstream:sync": "scripts/upstream-sync.sh",
"upstream:fetch": "git fetch upstream",
"upstream:rebase": "git rebase upstream/main"
"lint": "eslint ."
},
"keywords": [
"ai",
"agents",
"llm",
"litellm",
"a2a",
"autonomous",
"collective",
"heretek",
"openclaw"
"swarm-memory",
"agent-memory",
"triad",
"consciousness"
],
"author": "Heretek",
"author": "Heretek Collective",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/heretek/heretek-openclaw-core.git"
},
"bugs": {
"url": "https://github.com/heretek/heretek-openclaw-core/issues"
},
"homepage": "https://github.com/heretek/heretek-openclaw-core#readme",
"engines": {
"node": ">=20.0.0",
"npm": ">=9.0.0"
"dependencies": {
"ioredis": "^5.3.2",
"pg": "^8.11.3",
"pgvector": "^0.1.8",
"uuid": "^9.0.0",
"eventemitter3": "^5.0.1"
},
"devDependencies": {
"@eslint/js": "^9.0.0",
"@playwright/test": "^1.42.0",
"@types/node": "^20.11.0",
"@types/ws": "^8.5.0",
"@vitest/coverage-v8": "^1.3.0",
"@vitest/ui": "^1.3.0",
"eslint": "^9.0.0",
"eslint-config-prettier": "^9.1.0",
"husky": "^9.0.0",
"lint-staged": "^15.2.0",
"prettier": "^3.2.0",
"redis": "^4.6.0",
"typescript": "^5.3.0",
"typescript-eslint": "^8.0.0",
"vitest": "^1.3.0",
"ws": "^8.16.0"
},
"lint-staged": {
"*.{js,ts}": [
"eslint --cache --fix",
"prettier --write"
],
"*.{json,md,yaml,yml}": [
"prettier --write"
]
},
"volta": {
"node": "20.11.0",
"npm": "10.2.4"
"vitest": "^1.3.1",
"eslint": "^8.57.0"
}
}