conferllm 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- conferllm-0.1.0/.gitignore +137 -0
- conferllm-0.1.0/AGENTS.md +48 -0
- conferllm-0.1.0/CLAUDE.md +115 -0
- conferllm-0.1.0/LICENSE +21 -0
- conferllm-0.1.0/PKG-INFO +378 -0
- conferllm-0.1.0/README.md +320 -0
- conferllm-0.1.0/config_example.yaml +222 -0
- conferllm-0.1.0/pyproject.toml +272 -0
- conferllm-0.1.0/scripts/upgrade_dependency.py +314 -0
- conferllm-0.1.0/skills/conferllm/SKILL.md +85 -0
- conferllm-0.1.0/skills/conferllm/agents/openai.yaml +6 -0
- conferllm-0.1.0/skills/conferllm/references/errors.md +59 -0
- conferllm-0.1.0/skills/conferllm/references/installation.md +89 -0
- conferllm-0.1.0/skills/conferllm/references/multimodal.md +74 -0
- conferllm-0.1.0/src/conferllm/__init__.py +20 -0
- conferllm-0.1.0/src/conferllm/__main__.py +5 -0
- conferllm-0.1.0/src/conferllm/artifacts.py +502 -0
- conferllm-0.1.0/src/conferllm/chat.py +651 -0
- conferllm-0.1.0/src/conferllm/cli.py +450 -0
- conferllm-0.1.0/src/conferllm/client.py +410 -0
- conferllm-0.1.0/src/conferllm/config.py +216 -0
- conferllm-0.1.0/src/conferllm/doctor.py +250 -0
- conferllm-0.1.0/src/conferllm/errors.py +74 -0
- conferllm-0.1.0/src/conferllm/images.py +571 -0
- conferllm-0.1.0/src/conferllm/py.typed +0 -0
- conferllm-0.1.0/src/conferllm/server.py +406 -0
- conferllm-0.1.0/src/conferllm/session.py +1396 -0
- conferllm-0.1.0/src/conferllm/skill.py +196 -0
- conferllm-0.1.0/tests/__init__.py +0 -0
- conferllm-0.1.0/tests/chat_fixtures.py +44 -0
- conferllm-0.1.0/tests/conftest.py +135 -0
- conferllm-0.1.0/tests/test_artifacts.py +272 -0
- conferllm-0.1.0/tests/test_boundaries.py +361 -0
- conferllm-0.1.0/tests/test_chat.py +532 -0
- conferllm-0.1.0/tests/test_cli.py +535 -0
- conferllm-0.1.0/tests/test_client.py +434 -0
- conferllm-0.1.0/tests/test_config.py +407 -0
- conferllm-0.1.0/tests/test_doctor.py +165 -0
- conferllm-0.1.0/tests/test_local_images.py +431 -0
- conferllm-0.1.0/tests/test_packaging.py +99 -0
- conferllm-0.1.0/tests/test_protocol.py +134 -0
- conferllm-0.1.0/tests/test_regressions.py +382 -0
- conferllm-0.1.0/tests/test_server.py +665 -0
- conferllm-0.1.0/tests/test_session.py +813 -0
- conferllm-0.1.0/tests/test_skill.py +88 -0
- conferllm-0.1.0/uv.lock +3367 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
.DS_Store
|
|
6
|
+
.ruff_cache
|
|
7
|
+
|
|
8
|
+
# C extensions
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
build/
|
|
14
|
+
develop-eggs/
|
|
15
|
+
dist/
|
|
16
|
+
downloads/
|
|
17
|
+
eggs/
|
|
18
|
+
.eggs/
|
|
19
|
+
lib/
|
|
20
|
+
lib64/
|
|
21
|
+
parts/
|
|
22
|
+
sdist/
|
|
23
|
+
var/
|
|
24
|
+
wheels/
|
|
25
|
+
pip-wheel-metadata/
|
|
26
|
+
share/python-wheels/
|
|
27
|
+
*.egg-info/
|
|
28
|
+
.installed.cfg
|
|
29
|
+
*.egg
|
|
30
|
+
MANIFEST
|
|
31
|
+
|
|
32
|
+
# PyInstaller
|
|
33
|
+
# Usually these files are written by a python script from a template
|
|
34
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
35
|
+
*.manifest
|
|
36
|
+
*.spec
|
|
37
|
+
|
|
38
|
+
# Installer logs
|
|
39
|
+
pip-log.txt
|
|
40
|
+
pip-delete-this-directory.txt
|
|
41
|
+
|
|
42
|
+
# Unit test / coverage reports
|
|
43
|
+
htmlcov/
|
|
44
|
+
.tox/
|
|
45
|
+
.nox/
|
|
46
|
+
.coverage
|
|
47
|
+
.coverage.*
|
|
48
|
+
.cache
|
|
49
|
+
nosetests.xml
|
|
50
|
+
coverage.xml
|
|
51
|
+
*.cover
|
|
52
|
+
*.py,cover
|
|
53
|
+
.hypothesis/
|
|
54
|
+
.pytest_cache/
|
|
55
|
+
|
|
56
|
+
# Translations
|
|
57
|
+
*.mo
|
|
58
|
+
*.pot
|
|
59
|
+
|
|
60
|
+
# Django stuff:
|
|
61
|
+
*.log
|
|
62
|
+
local_settings.py
|
|
63
|
+
db.sqlite3
|
|
64
|
+
db.sqlite3-journal
|
|
65
|
+
|
|
66
|
+
# Flask stuff:
|
|
67
|
+
instance/
|
|
68
|
+
.webassets-cache
|
|
69
|
+
|
|
70
|
+
# Scrapy stuff:
|
|
71
|
+
.scrapy
|
|
72
|
+
|
|
73
|
+
# PyBuilder
|
|
74
|
+
target/
|
|
75
|
+
|
|
76
|
+
# Jupyter Notebook
|
|
77
|
+
.ipynb_checkpoints
|
|
78
|
+
|
|
79
|
+
# IPython
|
|
80
|
+
profile_default/
|
|
81
|
+
ipython_config.py
|
|
82
|
+
|
|
83
|
+
# pyenv
|
|
84
|
+
.python-version
|
|
85
|
+
|
|
86
|
+
# pipenv
|
|
87
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
88
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
89
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
90
|
+
# install all needed dependencies.
|
|
91
|
+
#Pipfile.lock
|
|
92
|
+
|
|
93
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
94
|
+
__pypackages__/
|
|
95
|
+
|
|
96
|
+
# Celery stuff
|
|
97
|
+
celerybeat-schedule
|
|
98
|
+
celerybeat.pid
|
|
99
|
+
|
|
100
|
+
# SageMath parsed files
|
|
101
|
+
*.sage.py
|
|
102
|
+
|
|
103
|
+
# Environments
|
|
104
|
+
.env
|
|
105
|
+
# uv keeps the real environment in its cache. Ignore the compatibility link
|
|
106
|
+
# and any numbered copies created by synced-folder conflict resolution.
|
|
107
|
+
/.venv*
|
|
108
|
+
env/
|
|
109
|
+
venv/
|
|
110
|
+
ENV/
|
|
111
|
+
env.bak/
|
|
112
|
+
venv.bak/
|
|
113
|
+
|
|
114
|
+
# Spyder project settings
|
|
115
|
+
.spyderproject
|
|
116
|
+
.spyproject
|
|
117
|
+
|
|
118
|
+
# Rope project settings
|
|
119
|
+
.ropeproject
|
|
120
|
+
|
|
121
|
+
# mkdocs documentation
|
|
122
|
+
/site
|
|
123
|
+
|
|
124
|
+
# mypy
|
|
125
|
+
.mypy_cache/
|
|
126
|
+
.dmypy.json
|
|
127
|
+
dmypy.json
|
|
128
|
+
|
|
129
|
+
# Pyre type checker
|
|
130
|
+
.pyre/
|
|
131
|
+
.streamlit/
|
|
132
|
+
coverage.xml
|
|
133
|
+
htmlcov
|
|
134
|
+
.claude
|
|
135
|
+
.mypy_cache
|
|
136
|
+
.ruff_cache
|
|
137
|
+
.pytest_cache
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Repository Guidelines
|
|
2
|
+
|
|
3
|
+
## Project Structure & Module Organization
|
|
4
|
+
- Source: `src/conferllm/` (`cli.py`, `chat.py`, `session.py`, `artifacts.py`, `images.py`, `server.py`, `client.py`, `config.py`, `doctor.py`, `skill.py`)
|
|
5
|
+
- Tests: `tests/` with shared fixtures in `tests/conftest.py`
|
|
6
|
+
- Config template: `config_example.yaml` (copy to `~/.conferllm/config.yaml`)
|
|
7
|
+
- Skill bundle: `skills/conferllm/` (`SKILL.md`, `agents/openai.yaml`, `references/`)
|
|
8
|
+
- Packaging & tools: `pyproject.toml` (ruff, mypy, pytest), console script `conferllm`
|
|
9
|
+
- Docs: `README.md`, `CLAUDE.md`, `AGENTS.md`
|
|
10
|
+
|
|
11
|
+
## Build, Test, and Development Commands
|
|
12
|
+
- Setup: use `uv>=0.12.9,<0.13`, then run `uv sync --extra dev`
|
|
13
|
+
- Run server: `uv run conferllm serve [--transport stdio|sse|http] [--config PATH] [--log-level DEBUG]`
|
|
14
|
+
- New chat: `uv run conferllm chat --model MODEL --prompt TEXT`
|
|
15
|
+
- Continue chat: `uv run conferllm chat --session SESSION_ID --prompt TEXT`
|
|
16
|
+
- List sessions: `uv run conferllm sessions list`
|
|
17
|
+
- Tests: `uv run pytest`
|
|
18
|
+
- Coverage: `uv run pytest --cov=src/conferllm --cov-report=term-missing`
|
|
19
|
+
- Lint/format: `uv run ruff format . && uv run ruff check .`
|
|
20
|
+
- Type check: `uv run mypy src/`
|
|
21
|
+
- Build: `uv build`
|
|
22
|
+
|
|
23
|
+
## Coding Style & Naming Conventions
|
|
24
|
+
- Python 3.10+, PEP 8, 4-space indent, line length 88 (ruff configured)
|
|
25
|
+
- Type-annotate all functions; keep imports sorted (ruff `I`); avoid unused args
|
|
26
|
+
- Files/modules use `snake_case`; classes `PascalCase`; constants `UPPER_SNAKE_CASE`
|
|
27
|
+
|
|
28
|
+
## Testing Guidelines
|
|
29
|
+
- Frameworks: pytest, pytest-asyncio, pytest-cov
|
|
30
|
+
- Discovery: files `test_*.py` or `*_test.py`; classes `Test*`; functions `test_*`
|
|
31
|
+
- Add tests for new behavior and failure paths; use mocks (no real API calls)
|
|
32
|
+
- Maintain or increase coverage; HTML report emitted to `.cache/coverage/html/`
|
|
33
|
+
|
|
34
|
+
## Commit & Pull Request Guidelines
|
|
35
|
+
- Use Conventional Commits (e.g., `feat:`, `fix:`, `docs:`, `chore:`); imperative, present tense
|
|
36
|
+
- Keep commits focused; exclude generated artifacts (`htmlcov/`, `.coverage`, `coverage.xml`)
|
|
37
|
+
- PRs include: clear summary and rationale, linked issues, reproduction steps or command output, and test plan/results
|
|
38
|
+
|
|
39
|
+
## Security & Configuration Tips
|
|
40
|
+
- Never commit secrets; put real keys only in `~/.conferllm/config.yaml`
|
|
41
|
+
- Keep `~/.conferllm` at mode `0700` and `~/.conferllm/config.yaml` at mode `0600`
|
|
42
|
+
- Session JSONL may contain sensitive conversations; tests and tools must not read real files under `~/.conferllm/sessions/`
|
|
43
|
+
- Tests and docs must not read or print real local configuration values
|
|
44
|
+
- Prefer LiteLM provider/model IDs (e.g., `openai/gpt-4`, `anthropic/claude-3-5-sonnet-20241022`)
|
|
45
|
+
|
|
46
|
+
## Agent-Specific Instructions
|
|
47
|
+
- Treat this file as authoritative across the repo scope
|
|
48
|
+
- Keep changes minimal and idiomatic; run `ruff`, `mypy`, and `pytest` before large refactors
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides project guidance for Claude Code and compatible coding
|
|
4
|
+
agents.
|
|
5
|
+
|
|
6
|
+
## Project overview
|
|
7
|
+
|
|
8
|
+
ConferLLM exposes locally configured LiteLLM models through:
|
|
9
|
+
|
|
10
|
+
- the stateful `conferllm chat` CLI;
|
|
11
|
+
- an MCP server over stdio, SSE, or streamable HTTP;
|
|
12
|
+
- the `conferllm` Agent Skill in `skills/conferllm/`.
|
|
13
|
+
|
|
14
|
+
The default configuration path is `~/.conferllm/config.yaml`. Never read, print,
|
|
15
|
+
commit, or otherwise expose real credentials from that file. Session JSONL is
|
|
16
|
+
stored below `~/.conferllm/sessions/` and may also contain sensitive content.
|
|
17
|
+
|
|
18
|
+
## Architecture
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
src/conferllm/
|
|
22
|
+
├── __init__.py # Package version and public exports
|
|
23
|
+
├── __main__.py # python -m conferllm
|
|
24
|
+
├── cli.py # CLI and MCP-server command routing
|
|
25
|
+
├── chat.py # Shared stateful chat orchestration
|
|
26
|
+
├── client.py # LiteLLM wrapper and local image conversion
|
|
27
|
+
├── config.py # Pydantic YAML configuration models
|
|
28
|
+
├── doctor.py # Safe installation/configuration diagnostics
|
|
29
|
+
├── errors.py # Typed, stable public error mapping
|
|
30
|
+
├── artifacts.py # Transactional session-owned image artifacts
|
|
31
|
+
├── images.py # Input validation and output-image extraction
|
|
32
|
+
├── session.py # JSONL session persistence and filtering
|
|
33
|
+
├── server.py # MCP tools, resources, and transports
|
|
34
|
+
└── skill.py # Version-matched bundled Skill installer
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The main flows are:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
Agent or user -> conferllm CLI -> ChatService -> SessionStore + LLMClient
|
|
41
|
+
MCP client -> MCPServer -> ChatService -> SessionStore + LLMClient
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Internal adapters use the concrete `ChatResult` and
|
|
45
|
+
`SessionListResult` interfaces; do not add runtime reflection or permissive
|
|
46
|
+
fallback branches to accommodate test doubles.
|
|
47
|
+
|
|
48
|
+
YAML model aliases are unique, provider model IDs are required, and relative
|
|
49
|
+
session roots resolve beside the configuration file. Configuration and provider
|
|
50
|
+
exceptions must be sanitized at their source; public codes must not be inferred
|
|
51
|
+
from message wording.
|
|
52
|
+
|
|
53
|
+
For continuation, keep the lock across load, capability/history checks, orphan
|
|
54
|
+
recovery, provider execution, and JSONL commit. JSONL is the commit record.
|
|
55
|
+
Never discard a committed turn, silently truncate history, or retry the model
|
|
56
|
+
because an optional export/inline-image read failed after commit.
|
|
57
|
+
|
|
58
|
+
## Development commands
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv sync --extra dev
|
|
62
|
+
uv run conferllm --help
|
|
63
|
+
uv run pytest
|
|
64
|
+
uv run ruff format .
|
|
65
|
+
uv run ruff check .
|
|
66
|
+
uv run mypy src/
|
|
67
|
+
uv build
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Run dependency discovery without changing `pyproject.toml`:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
uv run scripts/upgrade_dependency.py --dry-run
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## CLI contract
|
|
77
|
+
|
|
78
|
+
- `conferllm` displays top-level help.
|
|
79
|
+
- `conferllm serve` is the only MCP server entry point.
|
|
80
|
+
- `conferllm chat --model MODEL --prompt TEXT` creates a named session.
|
|
81
|
+
- `conferllm chat --session SESSION_ID --prompt TEXT` continues stored history.
|
|
82
|
+
- `conferllm sessions list` lists and filters session metadata.
|
|
83
|
+
- `conferllm models` lists configured aliases.
|
|
84
|
+
- `conferllm model-info MODEL` returns non-secret model metadata.
|
|
85
|
+
- Legacy root-level server options are not supported.
|
|
86
|
+
|
|
87
|
+
Do not change these interfaces without updating README, tests,
|
|
88
|
+
`skills/conferllm/SKILL.md`, and `skills/conferllm/agents/openai.yaml` together.
|
|
89
|
+
|
|
90
|
+
## MCP tools
|
|
91
|
+
|
|
92
|
+
- `create_chat(message, model, name=None, images=None, image_output_dir=None, include_raw_response=False)`
|
|
93
|
+
- `continue_chat(message, session_id, images=None, image_output_dir=None, include_raw_response=False)`
|
|
94
|
+
- `chat(message, model=None, session_id=None, name=None, images=None, image_output_dir=None, image_path=None, include_raw_response=False)` (compatibility wrapper)
|
|
95
|
+
- `list_sessions(query=None, model=None, since=None, until=None, limit=50)`
|
|
96
|
+
- `list_models()`
|
|
97
|
+
- `get_model_info(model)`
|
|
98
|
+
|
|
99
|
+
The code uses MCP 2.x `MCPServer`. Direct `call_tool()` tests receive a
|
|
100
|
+
`CallToolResult`; use its `content` and `structured_content` fields. Generated
|
|
101
|
+
images may be returned inline as `ImageContent` or by
|
|
102
|
+
`conferllm://sessions/{session_id}/artifacts/{artifact_id}` resource URI.
|
|
103
|
+
The first text block contains the same JSON envelope as structured content so
|
|
104
|
+
text-only clients can retain the session ID. Keep expensive listing, replay,
|
|
105
|
+
and inline-artifact I/O off the event loop.
|
|
106
|
+
|
|
107
|
+
## Testing
|
|
108
|
+
|
|
109
|
+
All provider calls must be mocked. Add tests for success and failure paths,
|
|
110
|
+
including CLI exit codes and transport mapping. Keep or improve coverage.
|
|
111
|
+
`tests/conftest.py` isolates `Path.home()` and rejects unmocked provider calls.
|
|
112
|
+
Do not disable these guards for a smoke test or inspect the real user's files.
|
|
113
|
+
|
|
114
|
+
Before handing off a substantial change, run formatting, lint, type checking,
|
|
115
|
+
tests, `git diff --check`, package build, and Skill validation.
|
conferllm-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Pengfei Ni
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
conferllm-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: conferllm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A local CLI and MCP server for talking to configured AI models through LiteLLM.
|
|
5
|
+
Project-URL: Homepage, https://github.com/feiskyer/mcp-ai-hub
|
|
6
|
+
Project-URL: Repository, https://github.com/feiskyer/mcp-ai-hub
|
|
7
|
+
Project-URL: Documentation, https://github.com/feiskyer/mcp-ai-hub#readme
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/feiskyer/mcp-ai-hub/issues
|
|
9
|
+
Author-email: Pengfei Ni <feiskyer@gmail.com>
|
|
10
|
+
License: MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2025 Pengfei Ni
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
16
|
+
in the Software without restriction, including without limitation the rights
|
|
17
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
SOFTWARE.
|
|
31
|
+
License-File: LICENSE
|
|
32
|
+
Classifier: Development Status :: 4 - Beta
|
|
33
|
+
Classifier: Intended Audience :: Developers
|
|
34
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
35
|
+
Classifier: Programming Language :: Python :: 3
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
40
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
41
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
42
|
+
Requires-Python: >=3.10
|
|
43
|
+
Requires-Dist: httpx[socks]>=0.28.1
|
|
44
|
+
Requires-Dist: litellm<1.98.0,>=1.97.0; python_version < '3.11'
|
|
45
|
+
Requires-Dist: litellm<2,>=1.99.0; python_version >= '3.11'
|
|
46
|
+
Requires-Dist: mcp<3,>=2.1.1
|
|
47
|
+
Requires-Dist: pydantic<3,>=2.13.5
|
|
48
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
49
|
+
Provides-Extra: dev
|
|
50
|
+
Requires-Dist: mypy>=2.3.1; extra == 'dev'
|
|
51
|
+
Requires-Dist: pre-commit>=4.6.2; extra == 'dev'
|
|
52
|
+
Requires-Dist: pytest-asyncio>=1.4.0; extra == 'dev'
|
|
53
|
+
Requires-Dist: pytest-cov>=7.1.0; extra == 'dev'
|
|
54
|
+
Requires-Dist: pytest>=9.1.1; extra == 'dev'
|
|
55
|
+
Requires-Dist: ruff>=0.16.6; extra == 'dev'
|
|
56
|
+
Requires-Dist: types-pyyaml>=6.0.12.20260815; extra == 'dev'
|
|
57
|
+
Description-Content-Type: text/markdown
|
|
58
|
+
|
|
59
|
+
# ConferLLM
|
|
60
|
+
|
|
61
|
+
ConferLLM is a local command-line tool for asking configured AI models questions,
|
|
62
|
+
continuing conversations, and working with images. Its bundled Agent Skill lets
|
|
63
|
+
another agent use the same commands for a second opinion or a model comparison.
|
|
64
|
+
|
|
65
|
+
The Python package, import package, executable, and Skill are all named
|
|
66
|
+
`conferllm`. LiteLLM handles provider integration; callers select a local model
|
|
67
|
+
alias and keep the returned session ID.
|
|
68
|
+
|
|
69
|
+
## Install
|
|
70
|
+
|
|
71
|
+
From an authorized ConferLLM source checkout:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
uv tool install .
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If you already use a Python virtual environment:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
python -m pip install .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
A supplied ConferLLM wheel can be used instead of `.`. Once a release of this
|
|
84
|
+
project has been published and its identity verified, it can be installed with
|
|
85
|
+
`uv tool install conferllm`. Do not assume that a same-named package is this project.
|
|
86
|
+
|
|
87
|
+
Verify the executable:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
conferllm --version
|
|
91
|
+
conferllm --help
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
ConferLLM requires Python 3.10+ and POSIX file locking (macOS/Linux). Native Windows
|
|
95
|
+
is not supported.
|
|
96
|
+
|
|
97
|
+
## Configure models
|
|
98
|
+
|
|
99
|
+
Configuration belongs in `~/.conferllm/config.yaml`, outside the repository.
|
|
100
|
+
From a source checkout, create a private directory and copy the example only
|
|
101
|
+
when no configuration exists:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
mkdir -p ~/.conferllm
|
|
105
|
+
chmod 700 ~/.conferllm
|
|
106
|
+
test ! -e ~/.conferllm/config.yaml && cp config_example.yaml ~/.conferllm/config.yaml
|
|
107
|
+
chmod 600 ~/.conferllm/config.yaml
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Alternatively, create the file using this minimal configuration and supply
|
|
111
|
+
your own credentials:
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
model_list:
|
|
115
|
+
- model_name: reasoning
|
|
116
|
+
capabilities:
|
|
117
|
+
input_modalities: [text]
|
|
118
|
+
output_modalities: [text]
|
|
119
|
+
litellm_params:
|
|
120
|
+
model: openai/gpt-5
|
|
121
|
+
api_key: "replace-with-your-key"
|
|
122
|
+
|
|
123
|
+
- model_name: vision
|
|
124
|
+
capabilities:
|
|
125
|
+
input_modalities: [text, image]
|
|
126
|
+
output_modalities: [text]
|
|
127
|
+
max_input_images: 8
|
|
128
|
+
litellm_params:
|
|
129
|
+
model: openai/gpt-4o
|
|
130
|
+
api_key: "replace-with-your-key"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Provider model IDs and parameters are examples; availability depends on your
|
|
134
|
+
provider account. Each local alias must be non-empty and unique, and
|
|
135
|
+
`litellm_params.model` must identify a provider model. See
|
|
136
|
+
[config_example.yaml](config_example.yaml) for additional configuration shapes.
|
|
137
|
+
|
|
138
|
+
Values in `litellm_params` are forwarded to LiteLLM, except that ConferLLM owns
|
|
139
|
+
`messages` and always sets `stream` to `false`. Unknown application configuration
|
|
140
|
+
fields are rejected so typos do not silently change behavior.
|
|
141
|
+
|
|
142
|
+
Optional settings:
|
|
143
|
+
|
|
144
|
+
- `global_system_prompt`: applied to every request.
|
|
145
|
+
- A model's `system_prompt`: overrides the global prompt; `""` disables it.
|
|
146
|
+
- `sessions_dir`: overrides the session root. Relative YAML paths resolve
|
|
147
|
+
beside the configuration file, independently of the caller's working directory.
|
|
148
|
+
- `image_limits`: limits newly attached images per turn. Defaults are 16 images,
|
|
149
|
+
20 MiB per image, and 50 MiB in total.
|
|
150
|
+
|
|
151
|
+
Use `--config PATH` to select another file. An explicitly selected missing file
|
|
152
|
+
is an error. ConferLLM does not create, populate, or automatically migrate provider
|
|
153
|
+
credentials.
|
|
154
|
+
|
|
155
|
+
Check configuration without printing its values:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
conferllm doctor --json
|
|
159
|
+
conferllm models --json
|
|
160
|
+
conferllm model-info reasoning
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Doctor reports safe metadata and suggested next steps. It exits nonzero when
|
|
164
|
+
configuration is missing, invalid, or has no model aliases, while still
|
|
165
|
+
returning its diagnostic report.
|
|
166
|
+
|
|
167
|
+
## Ask a model
|
|
168
|
+
|
|
169
|
+
Create a conversation:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
conferllm chat --model reasoning --prompt "Explain Raft leader election."
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Human-readable output includes the session ID, name, answer, output-image
|
|
176
|
+
locations, and any warnings. A name is derived locally from the first prompt;
|
|
177
|
+
use `--name` to choose one explicitly.
|
|
178
|
+
|
|
179
|
+
For scripts and agents, request structured output:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
conferllm chat \
|
|
183
|
+
--model reasoning \
|
|
184
|
+
--name "Raft notes" \
|
|
185
|
+
--prompt "Explain Raft leader election." \
|
|
186
|
+
--json
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
The stable response envelope is `conferllm.chat.response.v1`. Its authoritative
|
|
190
|
+
fields are:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"schema_version": "conferllm.chat.response.v1",
|
|
195
|
+
"ok": true,
|
|
196
|
+
"session": {
|
|
197
|
+
"id": "20260905-0123456789abcdef0123456789abcdef",
|
|
198
|
+
"name": "Raft notes",
|
|
199
|
+
"model": "reasoning",
|
|
200
|
+
"turn": 1
|
|
201
|
+
},
|
|
202
|
+
"message": {
|
|
203
|
+
"text": "The answer...",
|
|
204
|
+
"content": [{"type": "text", "text": "The answer..."}]
|
|
205
|
+
},
|
|
206
|
+
"artifacts": [],
|
|
207
|
+
"warnings": []
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Compatibility fields `session_id`, `name`, `model`, and `answer` are also
|
|
212
|
+
returned. New integrations should use the nested fields. Raw provider data
|
|
213
|
+
is excluded unless `--include-raw-response` is supplied.
|
|
214
|
+
|
|
215
|
+
For long or multiline prompts:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
conferllm chat --model reasoning --prompt-file ./prompt.md --json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Successful JSON results are written to stdout. Runtime failures exit nonzero
|
|
222
|
+
and write a `conferllm.error.v1` envelope to stderr; library logging is suppressed
|
|
223
|
+
in JSON mode so the envelope remains parseable. Argument-parser failures use
|
|
224
|
+
the normal CLI usage error and exit code 2.
|
|
225
|
+
|
|
226
|
+
## Continue and find conversations
|
|
227
|
+
|
|
228
|
+
Use the actual session ID returned by the preceding call:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
conferllm chat \
|
|
232
|
+
--session 20260905-0123456789abcdef0123456789abcdef \
|
|
233
|
+
--prompt "Now compare it with Paxos." \
|
|
234
|
+
--json
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Exactly one of `--model` and `--session` is required. A session retains its
|
|
238
|
+
model and name; `--name` is only accepted when creating a conversation.
|
|
239
|
+
ConferLLM restores prior successful turns automatically.
|
|
240
|
+
|
|
241
|
+
Find conversations using metadata:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
conferllm sessions list
|
|
245
|
+
conferllm sessions list --query raft --json
|
|
246
|
+
conferllm sessions list --model reasoning --since 2026-09-01 --limit 20 --json
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Filters combine with AND semantics. `--query` matches the ID or name without
|
|
250
|
+
case sensitivity; model aliases match exactly. `--since` and `--until` are
|
|
251
|
+
inclusive creation dates. The default limit is 50; `--limit 0` is unlimited.
|
|
252
|
+
Listing never searches message bodies and reports corrupt headers as warnings
|
|
253
|
+
without hiding unrelated valid sessions.
|
|
254
|
+
|
|
255
|
+
For a model comparison, create one independent session per model using the
|
|
256
|
+
same prompt. Attribute each answer and retain each session ID; a conversation
|
|
257
|
+
does not switch models.
|
|
258
|
+
|
|
259
|
+
## Work with images
|
|
260
|
+
|
|
261
|
+
Repeat `--image` to preserve input order:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
conferllm chat \
|
|
265
|
+
--model vision \
|
|
266
|
+
--prompt "Compare these screenshots." \
|
|
267
|
+
--image ./before.png \
|
|
268
|
+
--image ./after.png \
|
|
269
|
+
--json
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Accepted images are copied into private, session-owned storage. Follow-ups
|
|
273
|
+
use those copies even if the original files change or disappear. PNG, JPEG,
|
|
274
|
+
GIF, WebP, BMP, and SVG MIME types are detected from content rather than file
|
|
275
|
+
extensions.
|
|
276
|
+
|
|
277
|
+
Declared capabilities are checked before reading images or calling the
|
|
278
|
+
provider. Application limits bound new attachments; a model's
|
|
279
|
+
`max_input_images` also counts images replayed from history. Unknown image
|
|
280
|
+
capability produces a warning, not a claim of provider support.
|
|
281
|
+
|
|
282
|
+
Models that return images can produce multiple ordered output artifacts,
|
|
283
|
+
including image-only replies. `message.content` contains their references and
|
|
284
|
+
`artifacts` contains their MIME type, size, SHA-256, local path, and stable
|
|
285
|
+
`conferllm://sessions/.../artifacts/...` URI.
|
|
286
|
+
|
|
287
|
+
Use `--image-output-dir PATH` for additional exported copies. If export fails,
|
|
288
|
+
the canonical artifacts and successful conversation remain available. Preserve
|
|
289
|
+
the session ID and handle the warning instead of repeating the model call.
|
|
290
|
+
|
|
291
|
+
Generated images must be embedded data URLs. ConferLLM does not download
|
|
292
|
+
remote-only image outputs, execute provider tool calls, or silently discard
|
|
293
|
+
unsupported content.
|
|
294
|
+
|
|
295
|
+
## Install the Agent Skill
|
|
296
|
+
|
|
297
|
+
The source layout is:
|
|
298
|
+
|
|
299
|
+
```text
|
|
300
|
+
skills/conferllm/
|
|
301
|
+
├── SKILL.md
|
|
302
|
+
├── agents/openai.yaml
|
|
303
|
+
└── references/
|
|
304
|
+
├── installation.md
|
|
305
|
+
├── multimodal.md
|
|
306
|
+
└── errors.md
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
[skills/conferllm/](skills/conferllm/) is the single source of truth for the Skill.
|
|
310
|
+
The wheel embeds the same files; the source distribution preserves this layout.
|
|
311
|
+
Source and installed Skills use identical relative reference paths.
|
|
312
|
+
|
|
313
|
+
Install the version bundled with the executable:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
conferllm skill install
|
|
317
|
+
conferllm skill install --target codex
|
|
318
|
+
conferllm skill install --destination /custom/skills/conferllm
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Defaults are `~/.agents/skills/conferllm` and `~/.codex/skills/conferllm`. Installation
|
|
322
|
+
is idempotent. A different existing installation is preserved unless `--force`
|
|
323
|
+
is explicitly requested. Home, workspace, package directories, and their
|
|
324
|
+
ancestors are never valid replacement targets.
|
|
325
|
+
|
|
326
|
+
An agent invoking `$conferllm` discovers configured aliases, retains session IDs,
|
|
327
|
+
preserves image order, and attributes answers. It uses the CLI rather than
|
|
328
|
+
opening credential or session files.
|
|
329
|
+
|
|
330
|
+
## Storage and reliability
|
|
331
|
+
|
|
332
|
+
Sessions are UTF-8 JSONL files below `~/.conferllm/sessions/YYYY/MM/DD/`. Every
|
|
333
|
+
committed turn contains a complete user/assistant pair and its artifact
|
|
334
|
+
metadata. Directories use mode `0700`; session and image files use `0600`.
|
|
335
|
+
The configuration file remains user-managed.
|
|
336
|
+
|
|
337
|
+
Continuation holds a thread/process lock across loading, model execution, and
|
|
338
|
+
atomic JSONL replacement. Stored image size/hash checks precede replay.
|
|
339
|
+
Failed provider calls do not append a partial turn.
|
|
340
|
+
|
|
341
|
+
JSONL is the commit record. A locked continuation can recover the next
|
|
342
|
+
uncommitted image directory left by a crash; it never removes committed turns.
|
|
343
|
+
Early staging leftovers are not automatically swept. This is not an
|
|
344
|
+
exactly-once guarantee for provider calls, and long histories are not silently
|
|
345
|
+
summarized or truncated.
|
|
346
|
+
|
|
347
|
+
Session content can be sensitive. Keep credentials and conversations out of
|
|
348
|
+
version control. Configuration/provider errors do not echo raw input or
|
|
349
|
+
provider exception payloads.
|
|
350
|
+
|
|
351
|
+
## Development
|
|
352
|
+
|
|
353
|
+
Use `uv>=0.12.9,<0.13`:
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
uv sync --extra dev
|
|
357
|
+
uv run ruff format --check .
|
|
358
|
+
uv run ruff check .
|
|
359
|
+
uv run mypy src/
|
|
360
|
+
uv run pytest
|
|
361
|
+
uv lock --check
|
|
362
|
+
uv build
|
|
363
|
+
git diff --check
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Tests isolate the user home and block unmocked provider calls. They cover
|
|
367
|
+
persistence, process/thread locking, fault recovery, protocol integration,
|
|
368
|
+
Skill installation, and wheel/source-distribution content.
|
|
369
|
+
|
|
370
|
+
Key dependency major versions are bounded, and `uv.lock` records the development
|
|
371
|
+
resolution. Python 3.10 uses the verified LiteLLM 1.97.x line; Python 3.11+
|
|
372
|
+
permits LiteLLM 1.x from 1.99.0. The project uses uv's centralized environment
|
|
373
|
+
support so editable installs do not depend on hidden `.pth` files in synced
|
|
374
|
+
macOS folders.
|
|
375
|
+
|
|
376
|
+
## License
|
|
377
|
+
|
|
378
|
+
ConferLLM is released under the [MIT License](LICENSE).
|