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.
Files changed (46) hide show
  1. conferllm-0.1.0/.gitignore +137 -0
  2. conferllm-0.1.0/AGENTS.md +48 -0
  3. conferllm-0.1.0/CLAUDE.md +115 -0
  4. conferllm-0.1.0/LICENSE +21 -0
  5. conferllm-0.1.0/PKG-INFO +378 -0
  6. conferllm-0.1.0/README.md +320 -0
  7. conferllm-0.1.0/config_example.yaml +222 -0
  8. conferllm-0.1.0/pyproject.toml +272 -0
  9. conferllm-0.1.0/scripts/upgrade_dependency.py +314 -0
  10. conferllm-0.1.0/skills/conferllm/SKILL.md +85 -0
  11. conferllm-0.1.0/skills/conferllm/agents/openai.yaml +6 -0
  12. conferllm-0.1.0/skills/conferllm/references/errors.md +59 -0
  13. conferllm-0.1.0/skills/conferllm/references/installation.md +89 -0
  14. conferllm-0.1.0/skills/conferllm/references/multimodal.md +74 -0
  15. conferllm-0.1.0/src/conferllm/__init__.py +20 -0
  16. conferllm-0.1.0/src/conferllm/__main__.py +5 -0
  17. conferllm-0.1.0/src/conferllm/artifacts.py +502 -0
  18. conferllm-0.1.0/src/conferllm/chat.py +651 -0
  19. conferllm-0.1.0/src/conferllm/cli.py +450 -0
  20. conferllm-0.1.0/src/conferllm/client.py +410 -0
  21. conferllm-0.1.0/src/conferllm/config.py +216 -0
  22. conferllm-0.1.0/src/conferllm/doctor.py +250 -0
  23. conferllm-0.1.0/src/conferllm/errors.py +74 -0
  24. conferllm-0.1.0/src/conferllm/images.py +571 -0
  25. conferllm-0.1.0/src/conferllm/py.typed +0 -0
  26. conferllm-0.1.0/src/conferllm/server.py +406 -0
  27. conferllm-0.1.0/src/conferllm/session.py +1396 -0
  28. conferllm-0.1.0/src/conferllm/skill.py +196 -0
  29. conferllm-0.1.0/tests/__init__.py +0 -0
  30. conferllm-0.1.0/tests/chat_fixtures.py +44 -0
  31. conferllm-0.1.0/tests/conftest.py +135 -0
  32. conferllm-0.1.0/tests/test_artifacts.py +272 -0
  33. conferllm-0.1.0/tests/test_boundaries.py +361 -0
  34. conferllm-0.1.0/tests/test_chat.py +532 -0
  35. conferllm-0.1.0/tests/test_cli.py +535 -0
  36. conferllm-0.1.0/tests/test_client.py +434 -0
  37. conferllm-0.1.0/tests/test_config.py +407 -0
  38. conferllm-0.1.0/tests/test_doctor.py +165 -0
  39. conferllm-0.1.0/tests/test_local_images.py +431 -0
  40. conferllm-0.1.0/tests/test_packaging.py +99 -0
  41. conferllm-0.1.0/tests/test_protocol.py +134 -0
  42. conferllm-0.1.0/tests/test_regressions.py +382 -0
  43. conferllm-0.1.0/tests/test_server.py +665 -0
  44. conferllm-0.1.0/tests/test_session.py +813 -0
  45. conferllm-0.1.0/tests/test_skill.py +88 -0
  46. 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.
@@ -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.
@@ -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).