Skip to content

Latest commit

 

History

History
146 lines (116 loc) · 4.22 KB

File metadata and controls

146 lines (116 loc) · 4.22 KB

Simple Python CLI Chat 🧠💬

A minimal, professional command-line chatbot built in Python using OpenAI’s Chat Completions API. It evolves in three stages: from a single hardcoded prompt, to interactive I/O with token cost reporting, and finally to a persistent chat with function-called termination.


✨ Features

  • Interactive CLI prompt (Enter a message:)
  • Assistant responses printed as Assistant: ...
  • Token usage cost per interaction (Cost: $...)
  • Continuous conversation loop
  • Function calling to terminate the program on request (prints the call ID)

🧩 Project Stages

Stage 1 — Single exchange

  • Hardcoded user message: “What are you?”
  • Sends a system + user message to the API, prints the assistant reply once.
  • Useful to validate environment and SDK integration.

Stage 2 — Interactive I/O + Cost

  • Prompts the user: Enter a message:
  • Prints both:
    • You: <message>
    • Assistant: <reply>
  • Computes and prints total token cost per interaction (input + output).
  • Pricing (USD per 1M tokens) is configurable via env vars:
    • OPENAI_INPUT_COST_PER_MTOK (default 0.15)
    • OPENAI_OUTPUT_COST_PER_MTOK (default 0.60)

Stage 3 — Persistent Chat + Function-Called Termination

  • Continuous loop: after each turn, the program returns to the prompt.
  • Declares a tool/function end_conversation for the model.
  • If the user asks to stop (e.g., “End conversation”), the assistant calls the function:
    • The program prints the function call ID on its own line,
    • Prints Assistant: None,
    • Prints the Cost,
    • Exits with code 0.

🗂️ Repository Structure

.
├─ main.py                 # CLI app (stages implemented here)
├─ .env                    # Environment variables (not committed)
└─ README.md               # This file

⚙️ Setup

  1. Python & Dependencies
python -m venv .venv
# Windows: .venv\Scripts\activate
# macOS/Linux: source .venv/bin/activate
pip install --upgrade openai python-dotenv
  1. Environment Create a .env file next to main.py:
OPENAI_API_KEY=sk-...            # your key
OPENAI_MODEL=gpt-4o-mini         # optional, default used if omitted
OPENAI_INPUT_COST_PER_MTOK=0.15  # optional
OPENAI_OUTPUT_COST_PER_MTOK=0.60 # optional

Do not commit .env.


▶️ Run

python main.py

Examples (Stage 2 & 3 format):

Enter a message: > What is 5 + 10?
You: What is 5 + 10?
Assistant: 5 + 10 equals 15.
Cost: $0.00003000

When ending the chat (Stage 3):

Enter a message: > End conversation
call_TjO2fMKrLs6u...      <-- function call ID
You: End conversation
Assistant: None
Cost: $0.00006350

🧠 Code Highlights

  • Environment loading: python-dotenv loads .env using a path tied to main.py, ensuring it works even if the current working directory changes.

  • Messages format: Uses the Chat Completions messages=[{role, content}, ...] with a concise system prompt to guide behavior.

  • Cost calculation:

    def compute_cost(prompt_tokens, completion_tokens):
        in_cost  = (prompt_tokens    / 1_000_000) * INPUT_COST_PER_MTOK
        out_cost = (completion_tokens / 1_000_000) * OUTPUT_COST_PER_MTOK
        return in_cost + out_cost

    Reads token counts from resp.usage.

  • Function calling (termination):

    tools = [{
        "type": "function",
        "function": {
            "name": "end_conversation",
            "description": "Terminate the program immediately.",
            "parameters": {"type": "object", "properties": {}, "required": []},
        },
    }]

    If resp.choices[0].message.tool_calls is present, the program prints the tool call ID, shows Assistant: None, the Cost, and exits.


🔐 Security & Privacy

  • No sensitive data is logged by default.
  • Keep your API key only in .env and never commit it.
  • Review logs/prints before sharing console output.

✅ Result

You get a compact, production-ready CLI chatbot that:

  1. Works for one-shot prompts,
  2. Supports interactive conversations with cost visibility, and
  3. Terminates cleanly via assistant-initiated function calling.

Enjoy building on top of it! 🚀