Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.6 to 4.1.9. - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/HEAD/packages/vitest) --- updated-dependencies: - dependency-name: vitest dependency-version: 4.1.9 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Coding Mentor Agent
A local-first AI coding mentor for a Chinese-language Python course. The app combines a React learning interface, a TypeScript HTTP/SSE backend, a Practical Python knowledge base, adaptive diagnostics, progress tracking, and a Docker-backed Python sandbox.
Features • Getting Started • Configuration • Architecture • Development • Troubleshooting
Features
- Tutor chat for Python learners: explains concepts, reviews code, and guides debugging without bypassing the learning process.
- Course-grounded knowledge base: ships with a curated Practical Python catalog containing 9 units, 34 concepts, 25 exercises, mistake tags, and prerequisite relations.
- Adaptive diagnostic flow: places learners by concept readiness before unlocking structured practice.
- Structured practice and project workflows: selects exercises, creates practice contracts, reviews submissions, and records learning evidence.
- Isolated Python execution: runs student code and public tests in a Docker container with no network, dropped capabilities, memory limits, PID limits, and output truncation.
- Local learning state: stores sessions, mastery, evidence, practice reviews, and audit summaries in a local SQLite database under
.appby default. - Tool policy and auditing: gates model-visible tools by intent, caller, capability, and risk level, with redaction for secrets and local paths.
Important
Model-backed tutoring requires AI provider settings. Without
AI_PROVIDERandAI_API_KEY, model-dependent chat turns returnMODEL_UNAVAILABLE, although local catalog and diagnostic data can still initialize.
Getting Started
Prerequisites
- Node.js 24.x recommended. The Docker Compose setup uses
node:24.14.0-bookworm-slim. - npm.
- Docker Desktop or Docker Engine for code execution and grading.
- Python 3 if you plan to run the Python-based student-loop test harness.
- An AI provider API key for tutor responses.
Run locally
npm install
cp .env.example .env
docker build -t coding-mentor-python-runner:0.1.0 -f sandbox-runner.Dockerfile .
npm start
Open http://127.0.0.1:3000.
On Windows PowerShell, use this instead of cp:
Copy-Item .env.example .env
Then edit .env with your AI settings:
AI_PROVIDER=openai
AI_API=openai-responses
AI_BASE_URL=https://api.openai.com/v1
AI_MODEL=gpt-5.5
AI_API_KEY=your-api-key
Run with Docker Compose
docker compose up --build
The Compose setup starts the app at http://127.0.0.1:3000, starts a sandbox service on the internal Compose network, and mounts the Docker socket so the sandbox service can launch isolated runner containers.
Configuration
The app loads .env and .env.local from the repository root. Useful settings:
| Variable | Default | Purpose |
|---|---|---|
PORT |
3000 |
Local HTTP server port. |
APP_DATA_DIR |
.app |
SQLite database, Pi session files, backups, and test artifacts. |
COURSE_KB_ROOT |
kb/python-course-kb-practical-python/wiki |
Course catalog and source content root. |
COURSE_KB_VERSION |
kb-local |
Version label included in tutor prompts and catalog identity. |
ENABLED_BATCH |
full |
Tool allowlist: batch-a, batch-b, batch-c, or full. |
SANDBOX_IMAGE |
coding-mentor-python-runner:0.1.0 |
Docker image used for Python execution. |
SANDBOX_SERVICE_URL |
empty | Optional HTTP sandbox service URL. Empty uses local Docker directly. |
SANDBOX_TIMEOUT_MS |
3000 |
Max runtime for simple Python execution. |
SANDBOX_PYTEST_TIMEOUT_MS |
8000 |
Max runtime for pytest grading. |
SANDBOX_MEMORY_MB |
128 |
Container memory limit. |
AI_PROVIDER |
empty | Provider name used by @earendil-works/pi-ai. |
AI_API |
empty | Set to openai-responses for the built-in Responses-compatible adapter. |
AI_BASE_URL |
https://api.openai.com/v1 |
HTTPS model API base URL. |
AI_MODEL |
gpt-5.5 |
Model id passed to the provider adapter. |
AI_API_KEY |
empty | API key for tutor responses. |
Architecture
flowchart LR
UI["React + CodeMirror UI"] --> API["TypeScript HTTP/SSE server"]
API --> DB["Local SQLite progress DB"]
API --> KB["Course knowledge base"]
API --> Tutor["Pi AI tutor session"]
API --> Gate["Tool policy gate"]
Gate --> Sandbox["Docker Python sandbox"]
Gate --> Tools["KB, progress, exercise, project tools"]
Key paths:
| Path | Purpose |
|---|---|
src/frontend |
React app, CodeMirror editor, SSE state handling, safe Markdown rendering. |
src/server |
HTTP API, sessions, diagnostics, progress policy, recommendations, project flow, local data management. |
src/agent |
Tutor prompt construction and Pi AI / Pi coding-agent integration. |
src/tools |
Course tools, schemas, envelopes, tool registry, and capability policy. |
src/sandbox |
Docker runner and optional HTTP sandbox service. |
src/db |
SQLite schema, migrations, bootstrap, and validators. |
src/security |
Redaction, path validation, ids, and in-memory rate limits. |
kb/python-course-kb-practical-python |
Bundled Practical Python source material, summaries, concepts, exercises, and catalog manifest. |
tests |
Vitest unit/integration coverage plus Playwright and Python student-loop harnesses. |
API Surface
The backend serves the React app and exposes local JSON/SSE endpoints:
POST /api/sessionscreates or resumes a local tutor session.GET /api/sessions/:id/eventsstreams assistant messages and tool events over SSE.GET /api/sessions/:id/snapshotreturns the current conversation, practice, progress, and tutor state.POST /api/sessions/:id/messagessends a learner message and optional code.GET /api/diagnostics/nextandPOST /api/diagnostics/:id/answersdrive the adaptive diagnostic flow.GET /api/progress/mereturns local mastery and evidence summaries.POST /api/code/runexecutes Python through the gated sandbox.GET /api/exercises/nextandPOST /api/exercises/:id/submissionshandle structured practice.GET /api/data/export,POST /api/data/delete, andPOST /api/data/backupsmanage local learning data.
Development
Common scripts:
| Command | Description |
|---|---|
npm start |
Build the Vite client and run the local server on 127.0.0.1. |
npm run dev |
Same server entry point as npm start. |
npm run dev:frontend |
Start Vite for frontend-only iteration. |
npm run build |
Type-check and build the client into dist/client. |
npm run lint |
Run TypeScript type-checking with tsc --noEmit. |
npm test |
Run Vitest tests under tests/**/*.test.ts. |
npm run start:sandbox |
Start the optional HTTP sandbox service. |
npm run test:student-loop:realistic |
Run the realistic Python student-loop discovery harness. |
npm run test:student-loop:release |
Run the release-profile student-loop harness. |
npm run test:student-loop:security |
Run the security-profile student-loop harness. |
For UI-oriented checks, Playwright is configured to build the app and preview it at http://127.0.0.1:4173.
Local Data
By default, all learner state lives under .app:
progress.dbstores profile, sessions, mastery, exercises, diagnostics, practice reviews, projects, audit logs, and security events.pi-sessionsstores Pi agent session files.student-loopstores e2e harness artifacts.
Use GET /api/data/export for a redacted JSON export, POST /api/data/backups for an encrypted database backup, and POST /api/data/delete with {"confirm":"DELETE_LOCAL_LEARNING_DATA"} to clear local learner state.
Troubleshooting
MODEL_UNAVAILABLE
Set AI_PROVIDER, AI_MODEL, and AI_API_KEY in .env. If using the built-in OpenAI-compatible Responses adapter, also set AI_API=openai-responses.
Docker sandbox errors
Make sure Docker is running and the runner image exists:
docker build -t coding-mentor-python-runner:0.1.0 -f sandbox-runner.Dockerfile .
Port already in use
Change PORT in .env, then restart the server.
Practice is locked
Complete the initial diagnostic first. The backend intentionally blocks structured practice until it has enough placement evidence.
Reset local progress
Delete .app while the server is stopped, or use the data deletion endpoint with the explicit confirmation token shown above.