Track: Professional Agents — Agents for Humans (AWS / Strands)
A class operations desk. Paper + marks in. Chapter map and two briefs out. Empty cells stay empty. The Strands agent runs the desk by calling tools; Python owns every number.
We analyse the page. We do not grade unseen scripts.
Named desk: Kavita Sharma, Class 10-B Mathematics, Greenfield Public School. Named student: Ravi Mehta.
Demo video: https://www.youtube.com/watch?v=mY93KqHv7S0
- Empty /
NA/-is missing, not zero - No brief until the row is complete
- Family pane never receives the teacher brief or PTM wording
- No personality, “potential”, or mental-health claims
- The agent cannot write a mark; the teacher can
GET /api/health prints eval.invented_marks and eval.leaked_teacher_briefs. Both should be 0. make eval is the same gate.
Python 3.10+. Tesseract is optional (brew install tesseract).
One-click on GitHub: Open in Codespaces — desk on port 8080. GitHub Pages cannot run this API.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
make demoOpen http://127.0.0.1:8080 — password demo.
make test
make eval| Door | |
|---|---|
| Teacher | teacher@markmap.demo |
| Student | ravi@markmap.demo |
| Parent | parent.ravi@markmap.demo |
Also 10-A: ira@markmap.demo / parent.ira@markmap.demo.
The six video beats are in docs/demo.md.
Live list: GET /api/policy. Teacher can grant a denied action from Overview (Agent permissions) or PATCH /api/policy { "action": "alter_marks", "allowed": true }. Default is still refuse.
Run desk always goes through one Strands Agent. Tools:
| Tool | What it does |
|---|---|
list_incomplete_rows |
Observe empty cells |
class_hotspots |
Observe leaked questions |
write_student_briefs |
Draft teacher + family briefs (refuses if a cell is empty) |
run_desk_nags |
Teacher fill-marks task or class reteach proposal |
write_mark, unlock_brief, and set_question_chapter are cancelled by a BeforeToolCall hook before they run. The teacher fills a yellow empty cell on the Student pane (PATCH /api/papers/{id}/students/{roll}/cells/{qid}).
The same Strands loop can use several brains. The published demo (this repo, Docker, GitHub Codespaces) uses the built-in desk model.
MARKMAP_DESK_MODEL |
Brain |
|---|---|
desk |
Built-in Strands desk model |
mlx |
LM Studio / oMLX / OpenAI-compatible local server (optional on a laptop) |
ollama |
Ollama on :11434 |
bedrock |
Claude or Nova on Amazon Bedrock (BedrockModel) |
cp .env.example .env
# MARKMAP_DESK_MODEL=mlxGET /api/health reports backend and model. GitHub Pages cannot host this app (it is FastAPI, not a static site). Use make demo locally, docker build, or Open in GitHub Codespaces (port 8080).
Switch brains (same Strands tools):
| Doc | Script | |
|---|---|---|
| Desk (demo) | — | ./scripts/run-desk.sh |
| LM Studio / oMLX | docs/lmstudio-ollama-mlx.md | ./scripts/run-lmstudio.sh |
| Ollama (MLX on Apple silicon) | same | ./scripts/run-ollama.sh |
| Amazon Bedrock | docs/bedrock.md | ./scripts/run-bedrock.sh |
The Strands agent is wired for Bedrock. Invoke is not live.
AWS account 966132822353 (classic, us-west-2 / us-east-1) and project Stack of Dreams (499567237743) both return:
authorizationStatus: NOT_AUTHORIZED
ValidationException: Operation not allowed
That is an account-level Bedrock authorization hold, not a missing IAM policy and not a missing model-access tick. We checked Amazon Nova Micro/Lite/2 Lite, Llama 3, Mistral, and Claude Sonnet 4.6 in us-east-1, us-west-2, ap-south-2, ap-southeast-1, and eu-west-1. Models list. Converse / InvokeModel fail. Root credentials do not change it. A Bedrock API key does not change it. Nova is not a Marketplace subscribe model; the Anthropic first-use form is a separate later step for Claude only.
A Support case was opened. Until AWS sets authorizationStatus to AUTHORIZED, this repo’s public demo runs the same Strands tools on the built-in desk model. A laptop can still point MARKMAP_DESK_MODEL=mlx at LM Studio. No model trace is fabricated as Bedrock. When AWS unblocks invoke, set MARKMAP_DESK_MODEL=bedrock and MARKMAP_DISABLE_BEDROCK=0.
Cron / EventBridge: POST /api/desk/sweep with header X-Markmap-Secret.
- Synthetic class, not a school MIS
- No auto-grading of handwritten answers
- OCR optional; if Tesseract is missing, the sample screenshot is labelled embedded sample text
- Demo accounts only. Set
MARKMAP_SECRETandMARKMAP_ENV=productionbefore a public listen - Store is one JSON file (atomic replace). A hosted demo is ephemeral unless you mount a volume
- No GitHub Pages live desk (Pages is static-only). Codespaces or local
make demois the hosted path
See docs/architecture.md and docs/architecture.svg: request path, multi-agent desk (Strands orchestrator + five specialists), and the Strands tool loop.
MIT. Sample papers and CSVs are in data/samples/.