-
Notifications
You must be signed in to change notification settings - Fork 0
Contributing
PRs welcome. The codebase is small and approachable — ~5000 lines of Python with no native deps.
git clone https://github.com/mtecnic/model-chat-cli.git
cd model-chat-cli
python -m venv venv
source venv/bin/activate
pip install -r requirements.txtRun it against your own local model server before you change anything — make sure the baseline works.
- No comments unless the why is non-obvious. Well-named identifiers should carry the what.
-
Async everywhere for I/O. Don't add
requestsorurllib— usehttpx. -
One server-type branch. When code crosses backends, isolate the
if server["type"] == "openai"to one place. Don't sprinkle it. -
Dataclasses for record types. No untyped
dictpayloads in public engine APIs. -
No global state. Pass
console,server,modelexplicitly through view constructors.
- Add the default port to
scanner.COMMON_PORTS. - Extend
scanner.probe_server()with a detection endpoint:newproto_data = await check_endpoint(client, base_url, "/newproto/models") if newproto_data: return {"ip": ip, "port": port, "url": base_url, "type": "newproto", "models": [...]}
- Implement
client.ModelClient._chat_stream_newproto()matching the signature of the existing two. - Dispatch from
client.ModelClient.chat_stream():if self.server_type == "newproto": async for chunk in self._chat_stream_newproto(...): yield chunk
- Add a row to the Supported Servers table in the README.
In tool_bench.py:
- Write a
_exec_yourtool(args: dict) -> strreturning a deterministic string. - Add a tool schema entry in the catalog (
TOOLSor the realistic catalog if it's for that tier). - Add tasks that exercise it to
TASKS:AgentTask( "hard_yourtool_basic", "What is …?", expected_words=(("answer", "ans"),), required_calls=(("yourtool", {"key": "value"}),), difficulty="H", ),
- Re-run
QuickandHardtiers to confirm nothing else broke.
prompt_arena.py → SYSTEM_PROMPTS:
"yourkey": {
"name": "YourName",
"prompt": "You are…"
}That's it — the UI auto-picks it up.
- Add a method
StressTester.run_yourmode_test(...)returning aTestStats. - Wire it into
ui/stress_test.py's mode selector. - Document the mode in Stress-Testing and the README.
storage/history.py is finished but unused by the UI. To wire it up:
- In
ui/chat.py, on/export, also callChatHistoryManager().save(history, model, server). - Add a
/loadcommand that lists saved conversations and restores one. - Add
/searchto grep saved history.
The dataclass / format compatibility is already there — ChatHistoryManager.save() takes the same history list that ChatView already maintains.
- Colors →
ui/theme.py(APP_THEME— semantic names likechrome,server,model,status.error) - Layout primitives →
ui/components.py - Per-view layout → the relevant
ui/<view>.py
There is no automated test suite yet. Manual verification:
-
Discovery:
python main.pyfinds your local server. -
Chat: send a message; TPS / TTFT render;
/thinktoggles on a thinking model. - Arena: run a 3-model Quick Compare.
- Stress: run a 10-request Throughput test, confirm dashboard updates.
-
Tool Bench: run the
Quicktier (7 tasks) — should complete in <60s on a fast model.
If you change client.py, also verify with both an Ollama server and an OpenAI-compatible server, since the two paths diverge there.
- Manually tested the changed path.
- No new third-party dependencies unless absolutely needed.
- Public functions / dataclasses match existing naming.
- README updated if you added user-visible features.
- Wiki page updated if you changed behavior documented here.
https://github.com/mtecnic/model-chat-cli/issues
Useful things to include:
- OS + Python version
- Server type (Ollama / LM Studio / vLLM / other)
- Model name
- Relevant
logs/stress_test_*.logexcerpt - Steps to reproduce
MIT. By contributing you agree your changes ship under the same license.
Getting started
Features
Internals
Operating