Cavin

Phase 0: Environment and a bare completion call

AI Agents / 2026-09-18

Goal: prove you can send a prompt to a model and get text back, with no tools and no loop yet. This is the smallest working piece of the harness: one request out, one reply in. Everything later builds on it.

Think of this phase as checking the phone line before trying to have a conversation on it. If phase 1's tool loop breaks, you already know the connection to the model works, so the bug is in the loop logic.

1. Create the repo and clone it

Set this up on GitHub before writing any code, then clone it down, rather than running git init locally and pushing everything at the end. That way every phase's commits and tags land on GitHub as they happen.

Bash
gh repo create agent-harness --public --clone
cd agent-harness

No gh CLI installed? Create the repo at github.com/new instead, public, no template needed, then clone it the ordinary way:

Bash
git clone https://github.com/<your-username>/agent-harness.git
cd agent-harness

Either way, set up a virtual environment inside the cloned folder so this project's packages stay separate from anything else on the machine:

Bash
python3 -m venv .venv
source .venv/bin/activate

On Windows, activate with .venv\Scripts\activate instead of the source line.

2. Install the packages

Two packages cover this whole build. openai talks to Groq, since Groq's API is OpenAI-compatible and the same client library works against it. Groq has its own SDK too, but the OpenAI client uses the same shape as other free-tier providers, so adding a second backend later is a config change instead of a new library.

Bash
pip install openai python-dotenv

python-dotenv keeps the API key in a file instead of typed into the code.

3. Get a free Groq API key

Go to console.groq.com and sign up, no card needed. Open the API Keys page and create a new key, it's shown once, so copy it somewhere safe before closing that screen.

openai/gpt-oss-120b is the model used here, Groq's own recommended replacement after retiring llama-3.3-70b-versatile in August 2026. openai/gpt-oss-20b is a faster alternative worth trying later if speed matters more than raw capability.

Create a file named .env in the project folder:

INI.env
GROQ_API_KEY=gsk_your_key_here

Then add that file, along with the virtual environment folder, to .gitignore before writing another line of code, so neither ends up in the public repo:

Bash
echo ".env" >> .gitignore
echo ".venv" >> .gitignore
echo "__pycache__/" >> .gitignore

4. Write the test script

Create test_groq.py:

Pythontest_groq.py
from dotenv import load_dotenv
from openai import OpenAI
import os

load_dotenv()

client = OpenAI(
    api_key=os.environ["GROQ_API_KEY"],
    base_url="https://api.groq.com/openai/v1",
)

response = client.chat.completions.create(
    model="openai/gpt-oss-120b",
    messages=[{"role": "user", "content": "Say hello in one sentence."}],
)

print(response.choices[0].message.content)

The only unusual part is base_url. Groq speaks the same API shape as OpenAI, so pointing the OpenAI client at Groq's address is all that's needed, no separate SDK required.

Run it:

Bash
python test_groq.py

A 401 error usually means the .env file isn't being found, double check it's in the same folder and named exactly .env.

Groq retires free-tier models with little warning. A model_not_found 404 means the model id changed and your setup is fine. Check Groq's model list for the current name and swap it in.

You should see a message similar to:

Output
Hello! I hope you're having a wonderful day.

5. Wrap it in one function

Even with a single backend, write this as a function that takes a backend argument now. It costs nothing today, and it means phase 3's provider swapping is a config change later instead of a rewrite.

Create backend.py:

Pythonbackend.py
from dotenv import load_dotenv
from openai import OpenAI
import os

load_dotenv()

def complete(prompt: str, backend: str = "groq") -> str:
    if backend == "groq":
        client = OpenAI(
            api_key=os.environ["GROQ_API_KEY"],
            base_url="https://api.groq.com/openai/v1",
        )
        response = client.chat.completions.create(
            model="openai/gpt-oss-120b",
            messages=[{"role": "user", "content": prompt}],
        )
        return response.choices[0].message.content

    raise ValueError(f"unknown backend: {backend}")

if __name__ == "__main__":
    print(complete("Say hello in one sentence."))

You should now be able to run python backend.py and have it print one greeting back from Groq, similar to above.

Output
Hello, I hope you're having a wonderful day!

That confirms the connection works end to end. Phase 1 builds on it.

6. Troubleshooting

If everything worked, skip to step 7.

A 401 usually means the .env file isn't being found, or the key was copied with an extra space at either end. Print os.environ.get("GROQ_API_KEY") before the request to confirm it loaded.

Stuck?

Ask an agent something like: "my Groq request is returning a 401, what's wrong with this auth header?" A specific error beats "help me call the Groq API."

7. Commit and push

Bash
git add .
git commit -m "phase 0: hello world against groq"
git tag v0.1-hello
git push origin main --tags

Pushing the tag alongside the commit means the phase marker shows up on GitHub right away instead of sitting on your machine until you remember to push it.