Skip to main content

Auto-Coursera — AI-powered Coursera quiz assistant

Architecture Overview

A technical guide to how Auto-Coursera works under the hood. For contributors and the curious.

System Diagram

Auto-Coursera system architecture showing three layers: Coursera Page (Content Script + Widget), Service Worker (Message Router, AI Provider Manager, Rate Limiter), and AI Providers (OpenRouter, Gemini, Groq, Cerebras, NVIDIA NIM)

Content Script Layer

The content script runs on every Coursera page and is responsible for detecting, extracting, and applying answers.

Question Detection

A MutationObserver watches for quiz elements matching specific selectors:

  • div[data-testid^="part-Submission_"] — submission containers
  • div[role="group"][aria-labelledby*="-legend"] — question groups

Detection is debounced at 300ms to avoid reacting to intermediate DOM states during Coursera's React rendering.

Content Extraction

Once a question is detected, the extraction pipeline pulls:

  • Question text — the main question body
  • Images — via the CORS image pipeline (see below)
  • LaTeX — mathematical notation in questions
  • Code blocks — programming questions
  • Answer options — radio buttons, checkboxes, or text inputs

Answer Application

Applying answers to Coursera's React-controlled inputs requires a 3-strategy click cascade:

  1. React synthetic events — dispatch React-compatible change events
  2. Native DOM clicks — fallback to standard click()
  3. Direct input manipulation — set .value and dispatch input/change events for text fields

The cascade tries each strategy in order until the answer is confirmed as applied.

Service Worker Layer

The Manifest V3 service worker is the central coordinator. It never touches the DOM directly — all communication happens via chrome.runtime.sendMessage.

Message Routing

Every message between content scripts (and between tabs) passes through the service worker's message router. Messages are typed and validated.

AI Provider Manager

Manages all 5 providers with a circuit breaker pattern:

  • Closed — provider is healthy, requests go through
  • Open — provider has failed too many times, requests are routed to the next provider
  • Half-open — after a cooldown, one test request is sent to check if the provider has recovered

Providers are tried in the order set by the user's priority configuration.

Rate Limiter

A token bucket rate limiter prevents exceeding provider rate limits. Each provider has its own bucket with configurable capacity and refill rate.

Batch Processor

Questions are collected and sent in batches with an 800ms debounce. This avoids sending one API call per question — instead, the entire quiz (or newly detected questions) are batched into a single request.

Prompt Engine

Constructs structured prompts from extracted question data. The prompt format varies by provider and question type (multiple choice vs. code expression vs. image-based).

CORS Image Pipeline

Coursera images are subject to CORS restrictions. The service worker fetches images via its own context (which is not subject to page-level CORS), converts them to base64, and returns them to the content script for inclusion in AI prompts.

Widget Layer

The entire UI is rendered inside a Shadow DOM, completely isolating it from Coursera's page styles and DOM.

Floating Action Button (FAB)

The FAB is a draggable button with 5 visual states:

State Appearance
Disabled Greyed out — extension is off or no quiz detected
Idle Default — ready to scan
Processing Animated — waiting for AI response
Active Answers have been applied
Error Something went wrong — click for details

Control Panel

A 320×480px panel that slides out from the FAB. Contains the results view, per-question confidence display, and action buttons.

Settings Overlay

Full-screen overlay with a focus trap for accessibility. Contains provider configuration, key management, and behavior settings.

WidgetStore

A reactive state store built on EventTarget-based pub/sub. Components subscribe to state changes and re-render automatically — no framework needed.

ContentBridge

Handles bidirectional communication between the widget (inside Shadow DOM) and the content script (in the page context). Uses custom events for decoupled messaging.

Cross-Cutting Concerns

Question Deduplication

Each question is fingerprinted using FNV-1a hashing to prevent re-processing the same question if the page re-renders or the user navigates back.

API Key Encryption

All API keys are encrypted at rest using AES-256-GCM with a key derived via PBKDF2 (100,000 iterations). Keys are decrypted only when needed for an API call and never stored in plaintext. This protects against casual inspection of raw browser storage data, but is not a defense against malicious extensions with storage access or full browser-profile compromise.

Structured Logging

Internal logs use a structured format with automatic key sanitization — API keys and tokens are redacted before any log output.

Tab-Scoped State

All runtime state is scoped per-tab with automatic recovery. If a tab crashes or the service worker restarts, state is reconstructed from persisted checkpoints.

Auto-Update

The extension checks version.json every 6 hours for new releases. Users are notified of available updates through the extension panel.

AI Providers

See the Setup Guide for configuration instructions.

Provider Key Format Best For
OpenRouter sk-or-... General use — many free models, automatic routing
Gemini AIza... Generous free tier, strong reasoning
Groq gsk_... Ultra-fast inference, low latency
Cerebras cbs-... Fast inference, good free tier
NVIDIA NIM nvapi-... Vision models for image-based questions

Circuit Breaker Failover

When a provider fails (timeout, rate limit, server error), the circuit breaker opens and traffic is routed to the next provider in priority order. After a cooldown period, the breaker enters a half-open state and sends a single test request. If it succeeds, the provider is restored; if it fails, the cooldown resets.

This means you should always configure at least two providers for uninterrupted service.

Contributing

Auto-Coursera is open source and contributions are welcome. Whether it's fixing bugs, improving documentation, or suggesting features — every contribution helps.