Jump to content

Abstract Wiki Architect/AI Services

From Meta, a Wikimedia project coordination wiki

⚠️ Disclaimer: This project is the sole independent work of Réjean McCormick. It is not affiliated with, endorsed by, or representing the Wikimedia Foundation.

Abstract Wiki Architect: AI Services

[edit]

This document defines the integrated Artificial Intelligence layer of the Abstract Wiki Architect. The system consolidates all AI interactions into a unified ai_services package, using Large Language Models (Gemini) to handle tasks requiring semantic understanding, code repair, and linguistic quality assurance.

The Three AI Personas

[edit]

The architecture delegates responsibilities to three distinct AI agents, each serving a specific phase of the natural language generation pipeline.

Agent Role Responsibility Implementation
The Lexicographer Data Generator Bootstrap dictionaries for new languages by generating morphological classes and seed lexicons (e.g., classifying "Apple" as a Noun with specific gender/plural forms). Uses batch processing for efficiency. ai_services/lexicographer.py
The Surgeon Code Fixer Implements the "Self-Healing" build pipeline. Reads GF compiler error logs and surgically patches broken .gf source files to resolve API mismatches or syntax errors. ai_services/surgeon.py
The Judge Quality Assurance Generates "Gold Standard" reference sentences and validates the engine's output by scoring linguistic naturalness and accuracy against the source abstract intent. ai_services/judge.py

Directory Structure

[edit]

All AI logic is centralized in the ai_services/ directory to ensure consistent API handling and rate limiting.

ai_services/
├── __init__.py           # Package exposure
├── client.py             # Central Gemini client (API keys, Config, Retries)
├── lexicographer.py      # Logic for seeding dictionaries
├── surgeon.py            # Logic for repairing broken grammars
└── judge.py              # Logic for validation & gold standard generation

1. The Client (client.py)

[edit]

This module manages the connection to the LLM provider. It implements **Singleton initialization**, **Exponential Backoff** for rate limits, and centralized **Logging**.

import os
import time
import logging
import google.generativeai as genai
from dotenv import load_dotenv

load_dotenv()
API_KEY = os.getenv("GOOGLE_API_KEY")
MODEL_NAME = os.getenv("ARCHITECT_AI_MODEL", "gemini-1.5-pro")

# Global Singleton
_model = None

def _initialize():
    """Initializes the Gemini client (Singleton Pattern)."""
    global _model
    if _model: return True
    if not API_KEY: return False
    
    try:
        genai.configure(api_key=API_KEY)
        _model = genai.GenerativeModel(MODEL_NAME)
        return True
    except Exception:
        return False

def generate(prompt, max_retries=3):
    """
    Robust wrapper for text generation with error handling and backoff.
    """
    if not _initialize(): return ""

    wait_time = 2
    for attempt in range(1, max_retries + 1):
        try:
            response = _model.generate_content(prompt)
            return response.text.strip()
        except Exception:
            if attempt < max_retries:
                time.sleep(wait_time)
                wait_time *= 2
            else:
                return ""
    return ""

2. The Judge (judge.py)

[edit]

The Judge is the QA agent. It includes helper functions (`_clean_json_response`) to strip Markdown formatting from AI responses, ensuring strictly valid JSON for the pipeline.

Features

[edit]
  • Gold Standard Generation: Converts abstract concepts into natural reference sentences.
  • Output Validation: Scores linguistic quality (0-10) and provides corrections.

Implementation

[edit]
import json
from . import client

def _clean_json_response(response_text):
    """Helper to extract raw JSON from markdown wrapping."""
    if not response_text: return None
    clean_text = response_text.strip()
    if clean_text.startswith("```"):
        # Logic to strip markdown lines...
        pass
    return clean_text.strip()

def evaluate_output(source_concept, generated_text, lang_name):
    """
    Asks AI to judge the quality of the GF output.
    Returns: { "valid": bool, "score": 0-10, "correction": "..." }
    """
    prompt = f"""
    You are a linguistic judge.
    Task: Verify a translation.
    Source: "{source_concept}"
    Target Language: {lang_name}
    Generated: "{generated_text}"
    
    Return strictly JSON.
    """
    
    response = client.generate(prompt)
    clean_json = _clean_json_response(response)
    
    try:
        return json.loads(clean_json)
    except:
        return {"valid": False, "score": 0, "error": "AI parse failed"}

3. The Surgeon (surgeon.py)

[edit]

The Surgeon uses compiler error logs to rewrite broken GF source code. It validates that the AI output contains valid GF keywords (`concrete`, `open`) before writing to disk.

from . import client

def repair_grammar(rgl_code, file_content, error_log):
    """
    Surgically repairs broken GF code based on compiler error logs.
    """
    prompt = f"""
    You are an expert in Grammatical Framework (GF).
    The build failed.
    
    ERROR: {error_log}
    CODE: {file_content}
    
    Fix the code. Return ONLY the full corrected source.
    """
    
    response = client.generate(prompt)
    # Uses _clean_gf_response to strip markdown...
    return response

Workflow Integration

[edit]

Build Pipeline (Self-Healing)

[edit]

The `build_orchestrator.py` triggers the Surgeon via the `healer` module if compilation fails.

# build_orchestrator.py
success = compiler.run()

if not success:
    print("🚑 Detected Failures. Engaging AI Healer...")
    if healer.run_healing_round():
        print("🔄 Updates Applied. Compiling (Pass 2)...")
        success = compiler.run()

Testing Pipeline (Validation)

[edit]

The `test_gf_dynamic.py` runner calls the Judge for major languages.

# test_gf_dynamic.py
if lang_name in MAJOR_LANGS:
    verdict = judge.evaluate_output(concept, text, lang_name)
    if verdict['valid']:
        print(f"✅ AI Score: {verdict['score']}/10")
    else:
        print(f"⚠️ AI Fix: {verdict['correction']}")