← SELECTED WORK
Python / LLM APIs / pytestSummer 2026

FitFindr

An agent that knows when to re-plan.

tools in the planning loop
3

What I built.
How I evaluated it.

  • Built a planning-loop agent over three tools for listing search, outfit suggestion, and result card generation, decomposing user requests into ordered tool calls and re-planning when a call returned nothing usable.
  • Specified a tool inventory with typed inputs, explicit return contents, and a defined empty-result contract for every tool, so the agent branched on absent data instead of crashing mid-loop.
  • Ran a structured before-and-after evaluation across a fixed query set, assigning pass or fail verdicts, diagnosing each failure to a specific loop step, and shipping one targeted fix measured against the same set.
  • Logged full loop traces per run, making it possible to diagnose why a specific plan was chosen rather than inspecting only the final answer.
  • Wrote pytest coverage targeting agent failure modes including tool selection errors, unbounded planning loops, and empty tool responses.

The bullets above are reported in the full source resume ↗. Repository findings and any differences are identified separately below.

How it fits together.

A Python session dictionary carries the parsed query, listing results, selected item, wardrobe, outfit and caption through a conditional planning loop. Search operates on a local mock catalog; when no item matches, the agent retries by dropping size, price, then both before it stops. Successful searches feed Groq-backed styling and caption tools, with price comparison and catalog-derived trends added as stretch features.

Groqpython-dotenvGradiopytest

Choices with a reason.

  1. 01

    Token-based size matching

    Alternative considered: Naive substring matching

    Mixed letter, compound and shoe sizes need an exact token contract so unrelated sizes do not pass the filter.

    Source ↗
  2. 02

    Regex query parsing

    Alternative considered: An LLM extraction call returning JSON

    The parser is fast and dependency-free for the specified phrasings, with a documented flexibility trade-off for messier queries.

    Source ↗
  3. 03

    Retry constrained search before generation

    Alternative considered: Call all tools even when listing search returns no results

    The loop can relax filters, record the adjustment, and stop before spending LLM calls on an empty item.

    Source ↗

The result and the method.

Recorded Milestone 5 triggers: no search matches, an empty wardrobe, an empty outfit, and the full impossible-query path.

Search returned []; the empty wardrobe produced styling advice; the empty outfit returned a guard message. The recorded full-agent failure left both outfit_suggestion and fit_card unset. These are concrete failure checks, not an aggregate before/after success-rate table.

Source ↗

Tracked tool-test inspection at the linked commit.

15 test functions cover filtering, empty inputs, comparable prices and catalog trend shape. The README’s earlier “9 tests” paragraph predates six stretch-feature checks.

Source ↗

What still needs work.

Excerpts from the repository’s own notes. These limits belong beside the results.

  • Token-overlap scoring is order-blind.
    Source ↗
  • Query parsing is regex, not semantic.
    Source ↗
  • create_fit_card variation is "different enough" rather than measured.
    Source ↗

Read the code.

Python15 test definitions

Counted from tracked Python test functions. This audit did not execute the project suite. Source ↗

  1. agent.py

    Start at run_agent: session state, retry conditions and the early return.

  2. tools.py

    Read the contracts and guards for search, styling, captions and stretch tools.

  3. tests/test_tools.py

    Inspect the 15 current tool-contract tests rather than relying on the older README count.

Open repository ↗
  1. 01

    Establish a baseline.

  2. 02

    Make a targeted change.

  3. 03

    Re-measure on the same set.

  4. 04

    Document what still fails.

TakeMeter