Skip to content

feat(blockly): complete Blockly module — secure sandbox, AI exercise generation, score sync - #288

Draft
baaki-hicham wants to merge 5 commits into
Open-TutorAi:mainfrom
HICHAM-BA1:feat/blockly-complete
Draft

feat(blockly): complete Blockly module — secure sandbox, AI exercise generation, score sync#288
baaki-hicham wants to merge 5 commits into
Open-TutorAi:mainfrom
HICHAM-BA1:feat/blockly-complete

Conversation

@baaki-hicham

Copy link
Copy Markdown

Summary

This PR delivers the complete Blockly module for Open TutorAI, combining two contributions:

  1. Secure Python execution via Piston Docker sandbox
  2. AI-powered exercise generation with score synchronization

Problem

The original implementation had several critical issues:

# Issue Impact
#1 Score hardcoded to 85.0 Every student always got 85/100
#2 Wrong API prefix /api/blockly Did not match architecture v1.0.0
#3 No JWT authentication Endpoints were public
#4 subprocess instead of Docker sandbox No isolation, zombie threads under load
#5 stream=False for Ollama Blocked the event loop for 60s
#6 Workspace save/load returned None No real DB persistence
#7 Colors outside monochrome palette (emerald, teal, purple) Violated CHARTE_FRONTEND.md
#8 Forbidden gradients (bg-gradient-to-r) Violated CHARTE_FRONTEND.md
#9 Wrong API URL in frontend (/api/blockly instead of TUTOR_API_BASE_URL) All API calls failed
#10 Blockly v12 inject API + afterUpdate + i18n Editor never rendered

Solution

Backend

Sandbox (Fix #4)
Each student submission now runs in an isolated Piston Docker container:

  • Hard 5s timeout (container killed by OS — no zombie threads)
  • 64 MB memory limit (cgroups v2 compatible — Ubuntu 22+)
  • Network disabled
  • Filesystem isolated from server
    Student → FastAPI (8080) → Piston (2000) → Docker container → Result
    Score synchronization (Fix Update files from open webui to Open Tutor-ai #1)
    Exercises generated by Ollama are now saved in DB (blockly_exercises table).
    On submission, test cases are retrieved from DB using assignment_id + student_id (ownership check).
    No test cases can be manipulated from the frontend.

Real streaming (Fix #5)
Ollama now uses stream=False for exercise generation (reliability) with chunked yielding for SSE.
Feedback uses stream=True token by token.

Frontend

Blockly v12 editor (Fix #10)

  • Import inject from blockly/core
  • Use afterUpdate() with initialization flag instead of tick() alone
  • Load blockly/msg/en before inject
  • i18n wrapper with safe fallback: { t: (s) => _i18n?.t?.(s) ?? s }

Design (Fix #7, #8)

  • All colors replaced with monochrome gray-* palette
  • Blockly form in Dashboard aligned with SupportCreation style (blue-600)
  • No gradients anywhere in Blockly components

New Files

Backend

File Purpose
learning/blockly/router.py 6 endpoints: execute, test, submit, generate/stream, workspace save/load
learning/blockly/service.py Business logic: execution, scoring, AI feedback, DB persistence
learning/blockly/sandbox.py Piston HTTP client replacing subprocess
learning/blockly/models.py BlocklyExercise, BlocklySubmission, BlocklyWorkspace models
learning/blockly/schemas.py Pydantic request/response schemas
ai/llm/blockly_generator.py Ollama exercise generation + feedback streaming
devops/docker/docker-compose.piston.yml Piston sandbox service

Frontend

File Purpose
ui/src/routes/student/blockly/new/+page.svelte Student page with Blockly editor, progression, AI feedback
ui/src/lib/apis/blockly/index.ts API client with JWT auth

API Endpoints

Method Endpoint Auth Description
POST /api/v1/blockly/execute JWT Execute Python in isolated container
POST /api/v1/blockly/test JWT Run against test cases
POST /api/v1/blockly/submit JWT Score + AI feedback (SSE)
POST /api/v1/blockly/generate/stream JWT Generate exercise via Ollama (SSE)
POST /api/v1/blockly/workspace/save JWT Save Blockly workspace to DB
GET /api/v1/blockly/workspace/{id} JWT Load saved workspace

How to Test Locally

1. Start Piston sandbox

docker compose -f devops/docker/docker-compose.piston.yml up -d

# Install Python runtime (once)
curl -X POST http://localhost:2000/api/v2/packages \
  -H "Content-Type: application/json" \
  -d '{"language": "python", "version": "3.10.0"}'

2. Start Ollama

ollama serve
ollama pull qwen2.5:0.5b

3. Start backend

source .venv/bin/activate
uvicorn main:app --reload --port 8080

4. Run tests

# Get token
TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auths/signin \
  -H "Content-Type: application/json" \
  -d '{"email": "test@test.com", "password": "test1234"}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")

# Test execution
curl -X POST http://localhost:8080/api/v1/blockly/execute \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"python_code": "print(3 + 5)"}' 
# Expected: {"stdout":"8\n","error":null,...}

# Test timeout
curl -X POST http://localhost:8080/api/v1/blockly/execute \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"python_code": "while True: pass"}'
# Expected: {"timed_out":true,...}

5. Open student page

http://localhost:5173/student/blockly/new

Dependencies

  • Docker with privileged: true support (required for Piston containers)
  • Ollama running locally with qwen2.5:0.5b model
  • No dependency on other PRs — this PR is self-contained

🚧 Work in progress

Functional features:

  • ✅ Piston sandbox (execution, timeout, isolation)
  • ✅ AI exercise generation via Ollama (streaming)
  • ✅ Score calculated from DB test cases (no more hardcode)
  • ✅ JWT auth on all endpoints
  • ✅ Blockly v12 editor working

Known limitations to fix before review:

  • Ollama sometimes generates imprecise expected_output
  • UI/UX improvements needed on /student/blockly/new
  • student_id not yet linked to authenticated user session
1 3 cas correct cas incorrect

OumaGaour and others added 5 commits July 20, 2026 00:29
Backend:
- Sandbox Python isole (subprocess + timeout 5s)
- Router FastAPI (execute, submit, generate/stream, workspace)
- Schemas Pydantic avec validation stricte
- Generateur LLM Ollama (qwen2.5:0.5b)

Frontend:
- Interface Svelte complete (carte exercice + editeur)
- Integration Blockly (toolbox dynamique par niveau)
- Progression automatique (beginner > intermediate > advanced)
- Feedback IA en temps reel (SSE streaming)

Tests:
- 10 tests unitaires sandbox
- 9 tests progression de niveau
- 17 tests endpoints API
- 10 tests integration flux complets
- Total: 46/46 passed

US-B01 a US-B07: Toutes implementees
…ss with Piston sandbox, fix streaming and monochrome palette
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update files from open webui to Open Tutor-ai

2 participants