Fall 2026
  • Discord
  • Gradescope
  • Syllabus

On this page

  • Start
  • Learning Objectives
  • Build docchat
  • Grading Rubric
  • Extra Credit
  • Submit

Project 3: docchat

Webcomic titled 'Task description vs. effort': a one-line request, 'put the round thing on top,' sounds easy, but the effort turns out to be a mountain to climb.

In this project you will build chat, a command-line program that answers questions about the documents in a folder.

The language model can call four tools to inspect the files: ls, cat, grep, and calculate. Ask “does this project use regular expressions?” and the model can grep the code and answer from what it finds. chat uses retrieval-augmented generation, a method also used by many AI coding assistants.

Due: Wednesday, November 11 at 11:59pm, see the schedule.

Coding estimates are often too short:

Meme: 'New project idea, it will only take 2 days, let's do this!' followed by '1 month later' over a photo of hopelessly tangled wires.

Start

Continue in the independent docchat repository you created for the More Project Setup lab. Before adding new features, confirm that it still meets that lab’s specifications for chat.py, the repl loop, GitHub Actions, and packaging.

Learning Objectives

  1. understand how AI agents call and use tools
  2. create doctests and other project scaffolding from scratch
  3. maintain one project across several assignments:
    1. in a later lab, someone else will have to commit code to your project
    2. in the next project, you will extend this project with more features
    3. in your final project, you will use this project to write code for you

Build docchat

Note: You will write your own doctests from the specification below. Translate each requirement into concrete test cases.

The Tools

Extend the Chat class with four tools the model can call.

    Hint: Use the glob.glob function to list the files. glob.glob returns files in an arbitrary order, so sort them asciibetically before returning them; otherwise your test cases will pass and fail at random.

  • Hint: Catch any exception your code might raise. The common ones are FileNotFoundError (the file isn’t there) and UnicodeDecodeError (the file is there but isn’t a text file). On Windows you may have to handle files encoded in both UTF-16 and UTF-8; on every other machine, UTF-8 alone should be fine.

    Like cat, grep must not allow absolute paths or directory traversal attacks (see below).

    Hint: re.search tests whether a string matches a regex.

Calling the Tools Two Ways

Every tool must be callable in both of the following ways.

  • chat> /ls .github
    workflows
    chat> what files are in the .github folder?
    There is only a `workflows` folder in the `.github` folder.

    /ls .github runs directly and puts its output into the model’s context. The later question can then be answered without another tool call.

    This “slash command” syntax avoids an API call and lets the user choose the exact tool. To make it work, modify the repl function so that it checks whether the first character of a line is /.

    Warning: Prove that the manual and automatic tool calls work with doctests and integration tests.

Keep the Tools Inside the Folder

These tools can read files on your computer. Restrict them to the folder where chat was started. None of your tools may allow:

  1. reading absolute paths (paths that start with /), or
  2. directory traversal attacks, passing the filename .. anywhere in the path, which would let the model climb out of the project folder and read documents elsewhere.

Use a shared helper function, is_path_safe:

Coding Conventions

  • def do_fancy_string_processing(input_str):
        '''
        This function does a lot of hard, fancy string processing.
    
        >>> assert do_fancy_string_processing('this is a **super** __hard__ function to implement')
        '''

    This test hides the output of do_fancy_string_processing with assert. It neither documents the output nor detects changes in behavior.

Integration Tests

Your chat program will use these projects as test inputs.

Repository Organization

Hint: Describe what the program does in your README instead of presenting it as a school project.

    Note: Your lab had the doctests and integration-tests actions but not flake8. Copy the flake8 action from one of your previous assignments.

    • Note: The gif should show only your terminal session, not your whole VS Code window. See examples from terminalizer, terminal-demo, and vhs. If you need recording software, this dev.to post gives instructions and links.

    • $ cd markdown_compiler
      $ chat
      chat> does this project use regular expressions?
      No. I grepped all of the python files for any uses of the `re` library and did not find any.

      or

      $ cd ebay_scraper
      $ chat
      chat> tell me about this project
      The README says this project is designed to scrape product information off of ebay.
      chat> is this legal?
      Yes. It is generally legal to scrape webpages, but ebay offers an API that would be more efficient to use.

      Put these examples in their own section of the README, and give a one-sentence explanation of why each example is a good one.

Grading Rubric

This project is worth 41 points. There are also up to 26 possible points of extra credit, so it is possible to score 67/41 on this assignment.

To earn the full 41 points, your project must satisfy every requirement in the Instructions above:

The 38 automated points come from instructor-owned pytest tests in Gradescope. Model calls are mocked and file tools run only in temporary fixtures, so grading is deterministic, offline, and does not consume your API quota. The grader exercises each tool, automatic tool calls, and manual slash commands, including whether a manual result reaches the next model request. It measures the four required tools’ doctest coverage directly. The instructor reviews overall coverage and live integration-test results from your Actions, along with the README, terminal demonstration, and other presentation requirements. Student doctests that expect live model responses are not graded against arbitrary canned replies. GitHub Actions are useful feedback, but their badges are not the grade.

This project uses the late schedule below instead of the usual doubling penalty. The standard two-day extension for collaboration still applies.

Days late Standard policy This project
1 -1 -1
2 -2 -1
3 -4 -2
4 -8 -2
5 -16 -4
6 -32 -4
7 -64 -8
8 -128 -8
9 -256 -16

Extra Credit

Note: Many of these tasks cannot be covered by doctests, so completing them may lower your code coverage. Keep 100% coverage on your tool functions.

  • $ chat 'what files are in the .github folder?'
    The only file in this folder is the workflows subfolder
    $ chat 'what is this project about?'
    Looking at the README.md file, I see this project is an AI agent for chatting with documents.
  • $ chat
    chat> what files are in the .github folder?
    The only file in this folder is the workflows subfolder
    chat> ^C
    $ chat --debug
    chat> what files are in the .github folder?
    [tool] /ls .github
    The only file in this folder is the workflows subfolder

    To earn this, you must have both doctests and an integration test demonstrating the behavior works.

    1. openai: use the latest GPT model;
    2. anthropic: use the latest Claude Opus model;
    3. google: use the latest Gemini model;
    4. groq (the default): use whichever Groq model you like best.

    Note: You will need an openrouter.ai API key for this. All of your queries should cost less than a penny, so $10 of credit is more than enough.

  • Note: The compact command has to create its own instance of the Chat class to do the summarizing. That second instance is technically called a subagent.

    1. typing / and pressing tab lists the supported tools;
    2. typing /l and pressing tab completes to /ls;
    3. typing /ls .g and pressing tab completes to /ls .git;
    4. typing /ls .gith and pressing tab completes to /ls .github.

    For examples of how to do this, see this gist and the readline docs.

  • Note: If you complete this task, include a video in your README demonstrating the output. If you add that video, you do not also need the animated gif.

  • Note: If you complete this task, include a video in your README demonstrating the output.

    Note: If you use trigger word detection instead of a keypress, you get an additional +2 points of extra credit.

Submit

If you completed extra credit, add submission.toml at the repository root and set only the features you actually implemented:

[features]
cli_message = false
debug = false
providers = false
compact = false
tab_completion = false
images = false
text_to_speech = false
speech_to_text = false
trigger_word = false
mobile = false

# Supply these URLs only for claims that require video/deployment evidence.
trigger_word_evidence = ""
mobile_evidence = ""

Unclaimed extra-credit tests are skipped and do not lower the grade. The one-shot message feature is checked with an offline model. The other extra-credit claims appear as pending instructor review, with the specific behavior and evidence to be checked listed in the feedback. They receive credit after that review; a feature name in the source or an evidence URL by itself does not earn points.

Commit and sync the required files. On Gradescope, choose GitHub and submit your docchat repository and the branch containing your commit.

In the Gradescope comments, also submit a one-to-two sentence explanation of what you believe your grade should be: