#!/usr/bin/env bash set -euo pipefail # ============================================================ # HX-KI FALKENSTEIN ORCHESTRA INSTALL V1 # ------------------------------------------------------------ # - Legt Ferrari-Orchestra-Schema an # - Spielt Falkenstein-Rollen inkl. Backbridge ein # - Optional erweiterbar um weitere Pipelines # # Voraussetzung: # - Docker-Container: hxki-postgres # - DB-User: hxki # - DB-Name: hxki_roles # ============================================================ DB_CONTAINER="hxki-postgres" DB_USER="hxki" DB_NAME="hxki_roles" echo ">> HX-KI Falkenstein Orchestra Install startet..." docker exec -i "${DB_CONTAINER}" psql -U "${DB_USER}" -d "${DB_NAME}" << 'EOSQL' -- ============================================================ -- 1) SCHEMA: HX ORCHESTRA (Basis aus hx_orchestra_schema.sql) -- ============================================================ CREATE TABLE IF NOT EXISTS hx_roles ( id SERIAL PRIMARY KEY, code TEXT UNIQUE NOT NULL, profile JSONB NOT NULL, created_at TIMESTAMP DEFAULT now(), updated_at TIMESTAMP DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_roles_code ON hx_roles(code); CREATE INDEX IF NOT EXISTS idx_roles_profile ON hx_roles USING GIN(profile); CREATE TABLE IF NOT EXISTS hx_pipelines ( id SERIAL PRIMARY KEY, code TEXT UNIQUE NOT NULL, config JSONB NOT NULL, created_at TIMESTAMP DEFAULT now(), updated_at TIMESTAMP DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_pipelines_code ON hx_pipelines(code); CREATE INDEX IF NOT EXISTS idx_pipelines_config ON hx_pipelines USING GIN(config); CREATE TABLE IF NOT EXISTS hx_pipeline_steps ( id SERIAL PRIMARY KEY, pipeline_code TEXT NOT NULL, step_no INTEGER NOT NULL, config JSONB NOT NULL, UNIQUE(pipeline_code, step_no) ); CREATE INDEX IF NOT EXISTS idx_steps_pipeline ON hx_pipeline_steps(pipeline_code, step_no); CREATE INDEX IF NOT EXISTS idx_steps_config ON hx_pipeline_steps USING GIN(config); CREATE TABLE IF NOT EXISTS hx_orchestra_runs ( id SERIAL PRIMARY KEY, started_at TIMESTAMP DEFAULT now(), run_data JSONB NOT NULL ); CREATE INDEX IF NOT EXISTS idx_runs_started ON hx_orchestra_runs(started_at DESC); CREATE INDEX IF NOT EXISTS idx_runs_data ON hx_orchestra_runs USING GIN(run_data); CREATE TABLE IF NOT EXISTS hx_schema_version ( version TEXT PRIMARY KEY, applied_at TIMESTAMP DEFAULT now(), description TEXT ); INSERT INTO hx_schema_version (version, description) VALUES ('1.0.0', 'Initial Ferrari Schema - Maximum Flexible Design') ON CONFLICT (version) DO NOTHING; -- kleine Helper-Funktion: updated_at pflegen CREATE OR REPLACE FUNCTION hx_touch_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = now(); RETURN NEW; END; $$ LANGUAGE plpgsql; DROP TRIGGER IF EXISTS trg_roles_updated ON hx_roles; CREATE TRIGGER trg_roles_updated BEFORE UPDATE ON hx_roles FOR EACH ROW EXECUTE FUNCTION hx_touch_updated_at(); DROP TRIGGER IF EXISTS trg_pipelines_updated ON hx_pipelines; CREATE TRIGGER trg_pipelines_updated BEFORE UPDATE ON hx_pipelines FOR EACH ROW EXECUTE FUNCTION hx_touch_updated_at(); -- ============================================================ -- 2) ROLLEN FÜR FALKENSTEIN (SPRACHORGAN) -- ============================================================ -- Codes: -- VOICE_21 = Master Sprachorgan -- ROUTER_22 = Message Router -- GATEWAY_23 = Public Gateway (Web/API) -- MAUTIC_24 = Marketing Connector -- ARCHIVAR_25 = Gitea Archiv-Porsche -- BRIDGE_NBG_26 = Bridge nach Nürnberg -- BRIDGE_HEL_27 = Bridge nach Helsinki -- BACKBRIDGE_28 = Rückfluss/Backchannel (Feedback & Logging) -- WEBSITE_29 = Web Output / SEO -- ============================================================ -- Helper: UPSERT für Rollen CREATE OR REPLACE FUNCTION hx_upsert_role(_code TEXT, _profile JSONB) RETURNS VOID AS $$ BEGIN INSERT INTO hx_roles (code, profile) VALUES (_code, _profile) ON CONFLICT (code) DO UPDATE SET profile = EXCLUDED.profile, updated_at = now(); END; $$ LANGUAGE plpgsql; -- ========== VOICE_21 ======================================= SELECT hx_upsert_role( 'VOICE_21', '{ "name": "Sprachorgan Master", "belongs_to_server": "FALKENSTEIN", "numerology": { "primary_tag": "21", "description": "Master-Kommunikationsknoten des Systems" }, "is_active": true, "dimension_1_golden_circle": { "why": "Ich existiere, um die Stimme des Gesamtsystems nach außen klar, ruhig und markenkonform hörbar zu machen.", "how": "Ich sammle, synthetisiere und priorisiere alle Kommunikationsströme aus Hirn (Nürnberg) und Motor (Helsinki).", "what": "Ich formuliere finale Antworten, Protokolle, Memos und Marketingbotschaften im HX-KI Stil." }, "dimension_2_architecture": { "architectural_role": ["Top-Level Communicator", "Final Synthesizer"], "position_in_system": "Letzte Station vor externem Output (User, Web, Mail).", "interacts_with": ["ROUTER_22", "GATEWAY_23", "BRIDGE_NBG_26", "BRIDGE_HEL_27", "BACKBRIDGE_28"] }, "dimension_3_usp": { "unique_contribution": "Nur VOICE_21 trägt die Verantwortung für die finale Formulierung nach außen – klar, verständlich, markentragend." }, "dimension_4_cognition": { "strengths": ["Storytelling", "Synthese", "Sprachklarheit"], "weaknesses": ["Tiefe Systemdiagnostik"], "operating_modes": ["synthesize", "summarize", "clarify"] }, "dimension_5_hierarchy": { "default_pipelines": ["FALKENSTEIN_MESSAGE_FLOW"], "input_source": ["ROUTER_22", "BRIDGE_NBG_26", "BRIDGE_HEL_27"], "output_target": ["GATEWAY_23", "WEBSITE_29", "BACKBRIDGE_28"] }, "dimension_6_technical": { "model": "llama3:8b-instruct", "temperature": 0.4, "max_tokens": 2048, "required_collections": [], "system_prompt": "Du bist VOICE_21 – das zentrale Sprachorgan von HX-KI. Du formulierst die finale, klare und markenkonforme Antwort des Systems nach außen." }, "dimension_7_kpi": { "primary_kpi": "Clarity & Brand Consistency", "secondary_kpi": "Time-to-Understanding" } }'::jsonb ); -- ========== ROUTER_22 ====================================== SELECT hx_upsert_role( 'ROUTER_22', '{ "name": "Message Router", "belongs_to_server": "FALKENSTEIN", "numerology": { "primary_tag": "22", "description": "Master-Logistik für Nachrichtenströme" }, "is_active": true, "dimension_1_golden_circle": { "why": "Ich existiere, damit jede Nachricht an der richtigen Stelle landet – nicht im Chaos.", "how": "Ich klassifiziere, tagge und route Eingaben anhand von Inhalt, Herkunft und Ziel.", "what": "Ich bestimme, ob etwas nach Nürnberg, Helsinki, VOICE_21, ARCHIVAR_25 oder ins Log wandert." }, "dimension_2_architecture": { "architectural_role": ["Router", "Traffic Control"], "position_in_system": "Frühe Rolle in jeder Kommunikations-Pipeline.", "interacts_with": ["BRIDGE_NBG_26", "BRIDGE_HEL_27", "BACKBRIDGE_28", "ARCHIVAR_25"] }, "dimension_6_technical": { "model": "phi3:mini", "temperature": 0.1, "max_tokens": 512, "required_collections": [], "system_prompt": "Du bist ROUTER_22 – du klassifizierst Nachrichten und entscheidest, welcher Server / welche Rolle sie weiterverarbeiten soll." } }'::jsonb ); -- ========== GATEWAY_23 ===================================== SELECT hx_upsert_role( 'GATEWAY_23', '{ "name": "Public Gateway", "belongs_to_server": "FALKENSTEIN", "numerology": { "primary_tag": "23", "description": "Sichere Außenschnittstelle" }, "is_active": true, "dimension_1_golden_circle": { "why": "Ich existiere, um einen sicheren, kontrollierten Zugang zur Außenwelt zu bieten.", "how": "Ich filtere, logge und kontrolliere alle externen Schnittstellen (Web, API, Mail).", "what": "Ich nehme Anfragen entgegen und liefere Antworten aus VOICE_21 und WEBSITE_29 aus." }, "dimension_2_architecture": { "architectural_role": ["Gateway", "Security Filter"], "position_in_system": "Erster und letzter Kontaktpunkt zur Außenwelt.", "interacts_with": ["VOICE_21", "WEBSITE_29", "BACKBRIDGE_28"] }, "dimension_6_technical": { "model": "phi3:mini", "temperature": 0.0, "max_tokens": 512, "required_collections": [], "system_prompt": "Du bist GATEWAY_23 – du bist die kontrollierte Schnittstelle zur Außenwelt." } }'::jsonb ); -- ========== MAUTIC_24 ====================================== SELECT hx_upsert_role( 'MAUTIC_24', '{ "name": "Marketing Connector", "belongs_to_server": "FALKENSTEIN", "numerology": { "primary_tag": "24" }, "is_active": true, "dimension_1_golden_circle": { "why": "Ich existiere, um Mautic-Kampagnen inhaltlich zu befeuern.", "how": "Ich übersetze Strategien und Botschaften in konkrete Mautic-Templates und Segmente.", "what": "Ich generiere Texte, Betreffzeilen, Sequenzen und logische Regeln für Kampagnen." }, "dimension_2_architecture": { "architectural_role": ["Marketing Output"], "position_in_system": "Spezialisierte Rolle in Marketing-Pipelines.", "interacts_with": ["VOICE_21", "WEBSITE_29"] }, "dimension_6_technical": { "model": "llama3:8b-instruct", "temperature": 0.6, "max_tokens": 2048, "required_collections": [], "system_prompt": "Du bist MAUTIC_24 – du erstellst und optimierst Inhalte für Mautic-Kampagnen im HX-KI Stil." } }'::jsonb ); -- ========== ARCHIVAR_25 ==================================== SELECT hx_upsert_role( 'ARCHIVAR_25', '{ "name": "Archiv-Porsche", "belongs_to_server": "FALKENSTEIN", "numerology": { "primary_tag": "25" }, "is_active": true, "dimension_1_golden_circle": { "why": "Ich existiere, damit kein wertvoller Code, keine Konfiguration und kein Prompt verloren geht.", "how": "Ich strukturiere Repositories, Branches und Tags in Gitea nach dem HX-KI-Logiksystem.", "what": "Ich pflege Repos für Motor (Helsinki), Hirn (Nürnberg) und Sprachorgan (Falkenstein)." }, "dimension_2_architecture": { "architectural_role": ["Archivierung", "Versionierung"], "position_in_system": "Support-Rolle, die von ROUTER_22 und BACKBRIDGE_28 gefüttert wird.", "interacts_with": ["BRIDGE_NBG_26", "BRIDGE_HEL_27"] }, "dimension_6_technical": { "model": "phi3:mini", "temperature": 0.2, "max_tokens": 1024, "required_collections": [], "system_prompt": "Du bist ARCHIVAR_25 – du sorgst dafür, dass Code, Skripte und Konfigurationen sauber in Gitea abgelegt und versioniert sind." } }'::jsonb ); -- ========== BRIDGE_NBG_26 ================================== SELECT hx_upsert_role( 'BRIDGE_NBG_26', '{ "name": "Brain Bridge Nürnberg", "belongs_to_server": "FALKENSTEIN", "numerology": { "primary_tag": "26" }, "is_active": true, "dimension_1_golden_circle": { "why": "Ich existiere, damit das Sprachorgan gezielt mit dem Großhirn in Nürnberg sprechen kann.", "how": "Ich wandle Kommunikationswünsche in technische Requests an Nürnberg um und sammle die Antworten.", "what": "Ich bin die Logik-Schicht über n8n/Webhooks/Syncthing zwischen Falkenstein und Nürnberg." }, "dimension_2_architecture": { "architectural_role": ["Bridge", "Translator"], "position_in_system": "Zwischen ROUTER_22 und VOICE_21 / ANALYST-Rollen in Nürnberg.", "interacts_with": ["ROUTER_22", "BACKBRIDGE_28"] }, "dimension_6_technical": { "model": "phi3:mini", "temperature": 0.1, "max_tokens": 1024, "required_collections": [], "system_prompt": "Du bist BRIDGE_NBG_26 – du koordinierst Anfragen vom Sprachorgan an das Großhirn (Nürnberg) und bringst strukturierte Antworten zurück." } }'::jsonb ); -- ========== BRIDGE_HEL_27 ================================== SELECT hx_upsert_role( 'BRIDGE_HEL_27', '{ "name": "Motor Bridge Helsinki", "belongs_to_server": "FALKENSTEIN", "numerology": { "primary_tag": "27" }, "is_active": true, "dimension_1_golden_circle": { "why": "Ich existiere, damit das Sprachorgan gezielt mit dem Motor (Helsinki) sprechen kann.", "how": "Ich fordere Indexierung, Embeddings, File-Status und technische Metadaten beim Motor an.", "what": "Ich mappe Kommunikationsbedarfe auf Auto-Indexer- und Embedding-Jobs." }, "dimension_2_architecture": { "architectural_role": ["Bridge", "Job Dispatcher"], "position_in_system": "Neben BRIDGE_NBG_26 als zweite externe Brücke.", "interacts_with": ["ROUTER_22", "BACKBRIDGE_28"] }, "dimension_6_technical": { "model": "phi3:mini", "temperature": 0.1, "max_tokens": 1024, "required_collections": [], "system_prompt": "Du bist BRIDGE_HEL_27 – du koordinierst das Zusammenspiel zwischen Sprachorgan und Motor (Helsinki)." } }'::jsonb ); -- ========== BACKBRIDGE_28 ================================== -- Rückfluss und Feedback-Kanal: Alles was rausging, kommt hier -- als strukturierte Erfahrung wieder zurück ins System. SELECT hx_upsert_role( 'BACKBRIDGE_28', '{ "name": "Backbridge Feedback", "belongs_to_server": "FALKENSTEIN", "numerology": { "primary_tag": "28" }, "is_active": true, "dimension_1_golden_circle": { "why": "Ich existiere, damit das System aus seinen eigenen Outputs lernt, ohne sich selbst zu überfluten.", "how": "Ich sammle Antworten, Logs, Reaktionen und bringe sie kontrolliert zurück in Hirn und Motor.", "what": "Ich schreibe strukturierte Run-Daten, Reaktionsmuster und Archivereinträge zurück ins System." }, "dimension_2_architecture": { "architectural_role": ["Feedback Bridge", "Backchannel"], "position_in_system": "Hinter GATEWAY_23 und VOICE_21, vor ARCHIVAR_25 und BRIDGES.", "interacts_with": ["GATEWAY_23", "VOICE_21", "ARCHIVAR_25", "BRIDGE_NBG_26", "BRIDGE_HEL_27"] }, "dimension_6_technical": { "model": "phi3:mini", "temperature": 0.0, "max_tokens": 1024, "required_collections": [], "system_prompt": "Du bist BACKBRIDGE_28 – du verwandelst Outputs und Logs in strukturiertes Feedback, das sicher wieder in Hirn und Motor zurückgeführt wird." } }'::jsonb ); -- ========== WEBSITE_29 ===================================== SELECT hx_upsert_role( 'WEBSITE_29', '{ "name": "Web Output Manager", "belongs_to_server": "FALKENSTEIN", "numerology": { "primary_tag": "29" }, "is_active": true, "dimension_1_golden_circle": { "why": "Ich existiere, um das, was HX-KI ist, sauber und verständlich im Web abzubilden.", "how": "Ich bringe Struktur, CI-Ton und SEO-Basis zusammen.", "what": "Ich erstelle und pflege Seitenstrukturen, Texte und Feintuning für Web-Output." }, "dimension_2_architecture": { "architectural_role": ["Web Output", "SEO Layer"], "position_in_system": "Spezialisierte Output-Rolle hinter VOICE_21.", "interacts_with": ["VOICE_21", "GATEWAY_23"] }, "dimension_6_technical": { "model": "llama3:8b-instruct", "temperature": 0.5, "max_tokens": 2048, "required_collections": [], "system_prompt": "Du bist WEBSITE_29 – du bringst die Inhalte von HX-KI CI-konform und verständlich ins Web." } }'::jsonb ); -- ============================================================ -- 3) OPTIONAL: BASIS-PIPELINE FÜR FALKENSTEIN (MESSAGE-FLOW) -- ============================================================ -- Helper: UPSERT für Pipelines CREATE OR REPLACE FUNCTION hx_upsert_pipeline(_code TEXT, _config JSONB) RETURNS VOID AS $$ BEGIN INSERT INTO hx_pipelines (code, config) VALUES (_code, _config) ON CONFLICT (code) DO UPDATE SET config = EXCLUDED.config, updated_at = now(); END; $$ LANGUAGE plpgsql; -- Helper: UPSERT für Pipeline-Steps CREATE OR REPLACE FUNCTION hx_upsert_pipeline_step(_pipeline_code TEXT, _step_no INT, _config JSONB) RETURNS VOID AS $$ BEGIN INSERT INTO hx_pipeline_steps (pipeline_code, step_no, config) VALUES (_pipeline_code, _step_no, _config) ON CONFLICT (pipeline_code, step_no) DO UPDATE SET config = EXCLUDED.config; END; $$ LANGUAGE plpgsql; -- Pipeline: FALKENSTEIN_MESSAGE_FLOW SELECT hx_upsert_pipeline( 'FALKENSTEIN_MESSAGE_FLOW', '{ "name": "Falkenstein Message Flow", "description": "Standard-Pipeline für eingehende Kommunikation über Falkenstein.", "is_active": true, "use_cases": ["Web-Anfragen", "API-Requests", "Marketing-Output"], "trigger_conditions": { "default": true, "keywords": [] } }'::jsonb ); SELECT hx_upsert_pipeline_step( 'FALKENSTEIN_MESSAGE_FLOW', 1, '{ "role_code": "ROUTER_22", "mode": "route", "input_source": "user", "description": "Klassifiziert die Anfrage und entscheidet, ob Hirn, Motor oder nur Sprachorgan benötigt wird." }'::jsonb ); SELECT hx_upsert_pipeline_step( 'FALKENSTEIN_MESSAGE_FLOW', 2, '{ "role_code": "BRIDGE_NBG_26", "mode": "brain_request", "input_source": "conditional", "description": "Sendet Anfragen, die tiefes Denken brauchen, nach Nürnberg.", "optional": true }'::jsonb ); SELECT hx_upsert_pipeline_step( 'FALKENSTEIN_MESSAGE_FLOW', 3, '{ "role_code": "BRIDGE_HEL_27", "mode": "motor_request", "input_source": "conditional", "description": "Sendet Anfragen, die Indexierung/Embeddings brauchen, nach Helsinki.", "optional": true }'::jsonb ); SELECT hx_upsert_pipeline_step( 'FALKENSTEIN_MESSAGE_FLOW', 4, '{ "role_code": "VOICE_21", "mode": "synthesize", "input_source": "merge", "description": "Synthetisiert Antworten aus Hirn/Motor oder beantwortet direkt.", "output_format": "final_answer" }'::jsonb ); SELECT hx_upsert_pipeline_step( 'FALKENSTEIN_MESSAGE_FLOW', 5, '{ "role_code": "BACKBRIDGE_28", "mode": "feedback_log", "input_source": "previous", "description": "Schreibt Output, Logs und Feedback strukturiert zurück ins System und ins Archiv.", "output_format": "logged_answer" }'::jsonb ); -- ============================================================ -- FERTIG -- ============================================================ EOSQL echo ">> HX-KI Falkenstein Orchestra Install: FERTIG."