⚗️ The Lab ⚗️

Welcome to The Lab

This is a showcase of Miigwech AI projects, wrapped in 90s nostalgia. Look around, there's more here than you might expect.

||
11:13 AM
Miigwech AI Solutions
←
Back
→
Forward
■
Stop
↻
Refresh
⌂
Home
🔍
Search
★
Favorites
⎙
Print
A
Font
✉
Mail
Address
★ miigEngine ★

Local Retrieval and Source-Context Assembly

This sanitized sample shows how miigEngine retrieves local source records and builds source-linked context for a local model. Proprietary ingestion logic, data, schema details, prompts, and deployment configuration are omitted.


DESCRIPTION

python

import os
from typing import Any

os.environ["HF_HUB_OFFLINE"] = "1"
os.environ["TRANSFORMERS_OFFLINE"] = "1"


def retrieve_sources(connection, embedder, question: str,
                     limit: int = 5,
                     max_distance: float = 1.2) -> list[dict[str, Any]]:
    """Retrieve source-linked records from a local vector index."""
    query_vector = embedder.encode(question).astype("float32").tobytes()

    rows = connection.execute(
        """
        SELECT d.citation, d.title, d.source_url, d.source_text,
               vec_distance_L2(v.embedding, ?) AS distance
        FROM document_vectors v
        JOIN documents d ON d.id = v.document_id
        WHERE d.citation IS NOT NULL
          AND vec_distance_L2(v.embedding, ?) < ?
        ORDER BY distance
        LIMIT ?
        """,
        (query_vector, query_vector, max_distance, limit),
    ).fetchall()

    return [
        {
            "citation": row["citation"],
            "title": row["title"],
            "url": row["source_url"] or "",
            "excerpt": (row["source_text"] or "")[:4000],
            "distance": float(row["distance"]),
        }
        for row in rows
    ]


def build_context(sources: list[dict[str, Any]]) -> str:
    """Format retrieved records as source-linked model context."""
    blocks = []
    for i, s in enumerate(sources, start=1):
        blocks.append(
            f"[Source {i}] {s['citation']} - {s['title']}\n"
            f"URL: {s['url'] or 'No URL available'}\n"
            f"Excerpt: {s['excerpt'] or 'No text available'}"
        )
    return "\n\n".join(blocks)

Representative excerpt. The full miigEngine implementation also includes document ingestion, indexing, source validation, access controls, and local deployment components not shown here.

★ miigCloud Line ★

miigCloud Line: Selected Implementation Excerpts

miigCloud Line is a Rust-based infrastructure prototype for operating S3-compatible storage on organization-controlled infrastructure. The excerpts below demonstrate the storage-client setup, authenticated request handling, and bucket-provisioning workflow.

Representative excerpts are shown below; environment-specific configuration, credentials, internal schema details, and deployment topology are intentionally omitted.


S3-Compatible Storage Client

miigCloud Line creates an S3-compatible client from configurable connection settings, allowing the storage layer to target a locally controlled object-storage service rather than requiring a public-cloud endpoint.


miigCloud Line screenshot

rust

use std::sync::Arc;

use aws_config::BehaviorVersion;
use aws_credential_types::Credentials;
use aws_sdk_s3::config::Region;
use aws_sdk_s3::Client as S3Client;

#[derive(Debug, Clone)]
pub struct StorageConfig {
    pub endpoint: String,
    pub region: String,
    pub access_key: String,
    pub secret_key: String,
    pub use_path_style: bool,
}

#[derive(Debug, Clone)]
pub struct StorageClient {
    client: Arc<S3Client>,
}

impl StorageClient {
    pub async fn new(config: StorageConfig) -> Result<Self, StorageError> {
        let credentials = Credentials::new(
            &config.access_key,
            &config.secret_key,
            None,
            None,
            "local-storage",
        );

        let s3_config = aws_sdk_s3::config::Builder::new()
            .behavior_version(BehaviorVersion::v2024_03_28())
            .region(Region::new(config.region))
            .endpoint_url(config.endpoint)
            .credentials_provider(credentials)
            .force_path_style(config.use_path_style)
            .build();

        Ok(Self {
            client: Arc::new(S3Client::from_conf(s3_config)),
        })
    }

    pub fn inner(&self) -> &S3Client {
        &self.client
    }
}

This client abstraction provides a consistent Rust interface for bucket and object-storage operations while keeping endpoint and credential values outside the application logic.


JWT-Protected Storage Requests

Before performing a protected storage operation, miigCloud Line validates a Bearer token and extracts the authenticated user identifier from the token subject claim.

rust

use jsonwebtoken::{decode, DecodingKey, Validation};
use serde_json::Value;
use uuid::Uuid;

fn extract_user_id_from_jwt(token: &str) -> Result<Uuid, String> {
    let jwt_secret = std::env::var("JWT_SECRET")
        .map_err(|_| "JWT secret is not configured")?;

    let token_data = decode::<Value>(
        token,
        &DecodingKey::from_secret(jwt_secret.as_ref()),
        &Validation::default(),
    )
    .map_err(|_| "Token validation failed")?;

    let subject = token_data
        .claims
        .get("sub")
        .and_then(|value| value.as_str())
        .ok_or("Token is missing a subject claim")?;

    subject
        .parse::<Uuid>()
        .map_err(|_| "Token subject is not a valid user ID".to_string())
}

The authenticated user context can then be used to associate storage resources with the user who requested them.


Authenticated Bucket Provisioning

This request flow validates a bucket request, requires a valid Bearer token, provisions an S3-compatible bucket through the storage client, and records resource metadata through the application data layer.

rust

pub fn create_bucket(
    db_pool: Arc<DbPool>,
    storage: Arc<StorageClient>,
) -> impl Fn(&Request) -> Response + Clone {
    move |req: &Request| {
        let request: CreateBucketRequest = match serde_json::from_slice(&req.body) {
            Ok(value) => value,
            Err(_) => {
                return json_error(StatusCode::BadRequest, "Invalid request body");
            }
        };

        let token = match req
            .header("authorization")
            .and_then(|value| value.strip_prefix("Bearer "))
        {
            Some(token) => token,
            None => {
                return json_error(StatusCode::Unauthorized, "Authentication required");
            }
        };

        let owner_id = match extract_user_id_from_jwt(token) {
            Ok(id) => id,
            Err(_) => {
                return json_error(StatusCode::Unauthorized, "Invalid token");
            }
        };

        let storage_result = run_async(async {
            storage
                .inner()
                .create_bucket()
                .bucket(&request.name)
                .send()
                .await
        });

        if storage_result.is_err() {
            return json_error(
                StatusCode::InternalServerError,
                "Storage bucket creation failed",
            );
        }

        match save_bucket_metadata(&db_pool, &request.name, owner_id) {
            Ok(bucket) => json_response(StatusCode::Created, &bucket),
            Err(_) => json_error(
                StatusCode::InternalServerError,
                "Bucket metadata could not be saved",
            ),
        }
    }
}

This pattern connects application-level identity, S3-compatible bucket creation, and resource metadata into a single controlled workflow.


★ miigModel Adapter ★

miigModel Adapter: Selected Implementation Excerpts

miigModel Adapter is a local FastAPI service for running language-model inference from files controlled by the organization. These representative excerpts show local checkpoint validation, device-safe inference preparation, and a structured chat API.

Production paths, model assets, system instructions, logging configuration, and deployment settings are intentionally omitted. These excerpts reflect the current adapter implementation.


Local Checkpoint Validation and Offline Model Loading

Before inference begins, the adapter verifies that the expected local checkpoint files are present, selects an available CUDA or CPU device, loads the processor and model only from the local package, and places the model in evaluation mode.


DESCRIPTION

python

from pathlib import Path

import torch
from transformers import AutoModelForImageTextToText, AutoProcessor


def load_local_model(model_path: str, required_files: tuple[str, ...]):
    """Validate and load a local model package for inference."""
    model_path = Path(model_path).expanduser().resolve()
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    dtype = torch.bfloat16 if device.type == "cuda" else torch.float32

    if not model_path.is_dir():
        raise FileNotFoundError("Local model directory does not exist.")

    missing_files = [
        filename
        for filename in required_files
        if not (model_path / filename).is_file()
    ]

    if missing_files:
        raise FileNotFoundError(
            "Local checkpoint is incomplete. Missing: "
            + ", ".join(missing_files)
        )

    processor = AutoProcessor.from_pretrained(
        str(model_path),
        local_files_only=True,
    )

    model = AutoModelForImageTextToText.from_pretrained(
        str(model_path),
        local_files_only=True,
        dtype=dtype,
        low_cpu_mem_usage=True,
    )

    model.to(device)
    model.eval()

    return model, processor, device

This pattern verifies the local package before startup and avoids runtime dependency on a hosted model-inference API.


Device-Safe Local Inference Input Preparation

Local inference must preserve integer token IDs, masks, and position indices while ensuring floating-point inputs use the same runtime dtype as the loaded model. This helper prepares processor output safely for CPU or GPU inference.

python

from typing import Any

import torch


def move_inputs_to_device(
    encoded: dict[str, Any],
    device: torch.device,
    model_dtype: torch.dtype,
) -> dict[str, Any]:
    """Move processor tensors to the active device safely."""
    model_inputs: dict[str, Any] = {}

    for key, value in encoded.items():
        if not isinstance(value, torch.Tensor):
            continue

        value = value.to(device)

        # Token IDs, masks, and position indices remain integer or boolean.
        # Floating-point inputs follow the loaded model dtype.
        if torch.is_floating_point(value):
            value = value.to(dtype=model_dtype)

        model_inputs[key] = value

    return model_inputs

This prevents avoidable device and precision mismatches when the service is running on different local hardware configurations.


Structured Local Chat API

The chat endpoint accepts structured messages, removes empty input, ensures a system instruction is present, applies the local model’s chat template, runs local generation, cleans accidental next-turn delimiters, and returns a structured completion response.

python

import uuid
from typing import Any

from fastapi import HTTPException


async def chat_completion(request, local_model, default_system_prompt: str) -> dict[str, Any]:
    """Create a structured completion through a local model adapter."""
    request_id = str(uuid.uuid4())

    messages = [
        {
            "role": message.role.strip().lower(),
            "content": message.content.strip(),
        }
        for message in request.messages
        if message.content and message.content.strip()
    ]

    if not messages:
        raise HTTPException(
            status_code=400,
            detail="messages must contain at least one non-empty message",
        )

    if not any(message["role"] == "system" for message in messages):
        messages.insert(
            0,
            {"role": "system", "content": default_system_prompt},
        )

    prompt = local_model.format_chat(messages)

    result = local_model.generate(
        prompt=prompt,
        max_tokens=request.max_tokens,
        temperature=request.temperature,
        do_sample=True,
        request_id=request_id,
    )

    if result.get("status") != "success":
        raise HTTPException(
            status_code=500,
            detail=result.get("error", "Chat generation failed"),
        )

    completion = clean_completion(result.get("generated_text", ""))

    return {
        "choices": [{
            "message": {
                "role": "assistant",
                "content": completion,
            },
            "finish_reason": "stop",
        }],
        "usage": {
            "completion_tokens": result.get("tokens_generated", 0),
        },
        "model": "local-inference",
    }

The full service also includes health and model-information endpoints, CUDA-aware diagnostics that avoid recording raw prompt or completion content, generation error handling, and API tests.


★ Contact Us ★

Interested in working together? Get in touch through the main site.

Contact Me

★ Resume ★
WAYNE NORMAN
APPLIED AI & SYSTEMS INTEGRATION DEVELOPER
Canadian citizen | Previously held Government of Canada Reliability Status (2014); open to renewal | Available for hybrid and in-person work in Ottawa
PROFESSIONAL SUMMARY

Applied AI and systems-integration developer with 6+ years of experience delivering privacy-first AI applications, Python API services, data integrations, workflow automation, and production web systems for business and public-sector environments. Builds practical local-LLM, retrieval, and controlled-data solutions while connecting requirements discovery, architecture, testing, documentation, security controls, and stakeholder communication.

CORE EXPERTISE
Applied AI & Backend
Python, FastAPI, Flask, REST APIs, local LLMs, Ollama, RAG, embeddings, document ingestion, PyTorch, Safetensors
Data & Infrastructure
PostgreSQL, SQLite, SQL Server, S3-compatible storage, Rust, AWS SDK for Rust, Linux
Systems & Integration
Power Platform, Power Automate, Dataverse, SharePoint, CRM integration, Power BI, SQL/T-SQL
Security & Delivery
Authentication, RBAC, JWT, CSRF, rate limiting, IP allowlisting, audit logging, pytest, integration testing
PROFESSIONAL EXPERIENCE
AI Developer & Founder
Miigwech AI Solutions — Ottawa, ON Dec 2024–Present

Independent applied-AI and systems-integration practice building privacy-first local AI, legal-research, model-serving, and controlled-data solutions.

  • Translated privacy, data-residency, security, and operational requirements into deployable application and infrastructure designs.
  • Developed secure Python/FastAPI services, REST APIs, document-ingestion pipelines, retrieval workflows, access controls, and automated tests.
  • Evaluated local and open-weight models, inference runtimes, embeddings, and retrieval approaches against quality, hardware, privacy, compliance, and deployment requirements.
  • Developed miigEngine, a local legal-research RAG application over 118,891 Canadian case-law and legislative records using vector retrieval and citation grounding to canonical legal records.
  • Implemented 41+ application and administrative endpoints for chat, retrieval, authentication, RBAC, sessions, CSRF, IP allowlisting, rate limiting, and audit logging.
  • Wrote 38 automated tests covering model integration, RAG retrieval, document parsing, routes, CSRF, input validation, cancellation, and error handling.
  • Developed miigModel Adapter, a model-agnostic FastAPI service for open-weight local models, including Mistral 3 3B, using PyTorch and Safetensors.
  • Engineered miigCloud Line, a Rust/PostgreSQL controlled-infrastructure prototype with REST APIs, JWT/RBAC, S3-compatible storage, and a CLI; demonstrated it to public-sector attendees and technology vendors at GovTech Summit 2025.
Business Systems Analyst
Universities Canada — Ottawa, ON Oct 2019–Nov 2024
  • Maintained six production websites and hundreds of pages serving 100,000+ users; resolved platform, content, vendor, integration, and access issues across a complex stakeholder environment.
  • Built API-driven Power Platform and Power Automate integrations connecting a legacy CRM, SharePoint, Dataverse, Microsoft storage, and operational workflows; profiled, transformed, validated, and loaded inconsistent data into downstream systems.
  • Reverse-engineered undocumented CRM behavior and data structures, converting findings into reusable integration templates, field mappings, and technical documentation.
  • Mapped enterprise systems, data flows, and integration dependencies across national post-secondary institution networks; provided leadership recommendations on data governance, infrastructure resilience, and vendor lock-in.
  • Translated stakeholder needs into technical specifications and delivery roadmaps, balancing business priorities, data quality, technical constraints, and adoption.
  • Created Power BI reporting from Dataverse data to improve operational visibility, support data-quality review, and inform decisions.
  • Helped establish a SharePoint information environment, defining site structure, templates, navigation, and handoff practices that enabled non-technical teams to maintain content consistently.
SELECTED TECHNICAL PROJECTS
miigEngine — Local Legal Research Assistant

Privacy-first local legal-research RAG application for PDF and Word ingestion, embeddings, SQLite/vector retrieval, source-context handling, streamed responses, cancellation, authenticated access, administrative controls, and pytest coverage.

Technologies: Python, Flask, Ollama, SQLite, RAG, embeddings, Flask-Login, Flask-WTF, Flask-Limiter, pytest.

miigModel Adapter — Local Model Serving

Model-agnostic FastAPI service for local open-weight model generation and chat, including Mistral 3 3B, using PyTorch and Safetensors. Includes text/chat APIs, health and model-status endpoints, logging, startup scripts, and API/model tests.

Technologies: Python, FastAPI, PyTorch, Safetensors, REST APIs, local inference.

miigCloud Line — Controlled Infrastructure Prototype

Rust/PostgreSQL prototype for S3-compatible storage operations with JWT/RBAC-secured REST API and CLI workflows, permission checks, and local infrastructure configuration.

Technologies: Rust, AWS SDK for Rust, PostgreSQL, S3-compatible storage, REST APIs, JWT, RBAC, CLI, TOML, Linux.

EDUCATION
Computer Programmer Diploma
Algonquin College — Ottawa, ON 2018

Download Resume in PDF Contact Me

★ CanadaBuys Tender Scope★
CanadaBuys Tender Scope dashboard screenshot

Explores how AI can support public-sector business development. It turns CanadaBuys tender data into a searchable workflow with capability-based shortlisting, local AI analysis backed by source quotes, and saved opportunities with notes. Helps move from “what could we build?” to “what is worth investigating?”


The CanadaBuys Open Tender Notices dataset is a downloadable list of federal government procurement opportunities recorded as open, including what buyers need, who is buying, and submission deadlines.
Its value is evidence: real buyer requests that help us identify relevant opportunities and investigate which products or services may be worth building, not just brainstorm ideas.

Video Demo


Application Guide

My Computer
text.txt
i
Internet
Recycle