Python Tutor Chatbot banner
heitor-am heitor-am

Python Tutor Chatbot

Development community

Description

Conversational Python tutor — Chainlit + LangChain create_agent + LangGraph (InMemorySaver memory) + OpenRouter (claude-haiku) on Fly.io

Installation

This entry records only its repository, not the path inside it, so there is no exact command to give. Open the source below and copy the folder into ~/.claude/skills/, or the file into ~/.claude/agents/.

README

Python Tutor Chatbot

[![CI](https://github.com/heitor-am/python-tutor-chatbot/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/heitor-am/python-tutor-chatbot/actions/workflows/ci.yml) [![Deploy](https://github.com/heitor-am/python-tutor-chatbot/actions/workflows/deploy.yml/badge.svg?branch=main)](https://github.com/heitor-am/python-tutor-chatbot/actions/workflows/deploy.yml) [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3120/) [![Coverage 100%](https://img.shields.io/badge/coverage-100%25-brightgreen.svg)](#testing) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

Conversational Python tutor — Chainlit UI on top of LangChain `create_agent` (the modern canonical pattern; `RunnableWithMessageHistory` legacy avoided per current docs) with thread-based memory via LangGraph `InMemorySaver`. Talks to OpenRouter behind a single `ChatOpenAI` client.

**Live:**

Quickstart

git clone git@github.com:heitor-am/python-tutor-chatbot.git
cd python-tutor-chatbot
uv sync --all-extras

cp .env.example .env
# edit .env and set OPENROUTER_API_KEY=sk-or-...

make dev
# open http://localhost:8000

Or just hit production: . Fly auto-stops the machine after idle, so the first message after a quiet period pays a 2-3s cold-start.

What it does

  • Answers Python questions in PT-BR with executable examples and a clear "explain reasoning before code" structure.
  • Remembers the conversation within a session via per-tab thread_id + LangGraph InMemorySaver.
  • Refuses off-topic questions in one polite sentence (smoke-verified end-to-end against real OpenRouter — see PR #3 description for the test transcript).
  • Streams tokens as they arrive (via agent.astream(stream_mode="messages") piped to cl.Message.stream_token()).
  • Logs structured thumbs-up / thumbs-down feedback.
  • F