polyllmkit 0.1.0__tar.gz → 0.1.1__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 (26) hide show
  1. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/PKG-INFO +6 -1
  2. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/pyproject.toml +9 -1
  3. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/adapters/anthropic.py +8 -8
  4. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/adapters/claude_code.py +11 -8
  5. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/adapters/google.py +4 -7
  6. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/cli.py +6 -0
  7. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/client.py +4 -7
  8. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/__init__.py +0 -0
  9. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/__init__.py +0 -0
  10. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/__main__.py +0 -0
  11. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/adapters/__init__.py +0 -0
  12. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/adapters/openai.py +0 -0
  13. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/bridge.py +0 -0
  14. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/config.py +0 -0
  15. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/sinks.py +0 -0
  16. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/bridge/stream.py +0 -0
  17. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/md/__init__.py +0 -0
  18. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/md/render/__init__.py +0 -0
  19. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/md/render/__main__.py +0 -0
  20. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/md/render/cli.py +0 -0
  21. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/md/render/stream.py +0 -0
  22. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/md/view/__init__.py +0 -0
  23. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/md/view/__main__.py +0 -0
  24. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/md/view/app.py +0 -0
  25. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/md/view/cli.py +0 -0
  26. {polyllmkit-0.1.0 → polyllmkit-0.1.1}/src/llmkit/py.typed +0 -0
@@ -1,7 +1,11 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: polyllmkit
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Streaming, multi-provider LLM bridge + markdown rendering toolkit for terminal apps.
5
+ Requires-Dist: openai>=1.0 ; extra == 'all'
6
+ Requires-Dist: claude-agent-sdk>=0.2 ; extra == 'all'
7
+ Requires-Dist: anthropic>=0.40 ; extra == 'all'
8
+ Requires-Dist: google-genai>=1.0 ; extra == 'all'
5
9
  Requires-Dist: anthropic>=0.40 ; extra == 'anthropic'
6
10
  Requires-Dist: openai>=1.0 ; extra == 'bridge'
7
11
  Requires-Dist: claude-agent-sdk>=0.2 ; extra == 'claude'
@@ -10,6 +14,7 @@ Requires-Dist: rich>=13.0 ; extra == 'md'
10
14
  Requires-Dist: textual>=0.50 ; extra == 'md'
11
15
  Requires-Dist: markdown-it-py>=3.0 ; extra == 'md'
12
16
  Requires-Python: >=3.11
17
+ Provides-Extra: all
13
18
  Provides-Extra: anthropic
14
19
  Provides-Extra: bridge
15
20
  Provides-Extra: claude
@@ -4,7 +4,7 @@
4
4
  # module-name below): consumers keep `import llmkit`, `pip install polyllmkit`.
5
5
  [project]
6
6
  name = "polyllmkit"
7
- version = "0.1.0"
7
+ version = "0.1.1"
8
8
  description = "Streaming, multi-provider LLM bridge + markdown rendering toolkit for terminal apps."
9
9
  requires-python = ">=3.11" # tomllib (bridge.config) is stdlib only from 3.11
10
10
  # Base install pulls nothing — pick the subpackage(s) you need via extras.
@@ -21,6 +21,14 @@ bridge = ["openai>=1.0"]
21
21
  claude = ["claude-agent-sdk>=0.2"] # claude_code adapter (Claude Agent SDK)
22
22
  anthropic = ["anthropic>=0.40"] # anthropic adapter (native Messages API)
23
23
  google = ["google-genai>=1.0"] # google adapter (native Gemini API)
24
+ # Every backend at once — for hosts that resolve the adapter at runtime and
25
+ # must have all of them present (e.g. cribsheet's daemon).
26
+ all = [
27
+ "openai>=1.0",
28
+ "claude-agent-sdk>=0.2",
29
+ "anthropic>=0.40",
30
+ "google-genai>=1.0",
31
+ ]
24
32
  # llmkit.md — markdown rendering (one-shot + live stream + scrollable modal).
25
33
  # markdown-it-py is a direct import in md.render.stream (textual also pulls
26
34
  # it, but we depend on it explicitly since we use it ourselves).
@@ -29,7 +29,6 @@ openai-compatible path never requires it.
29
29
  from __future__ import annotations
30
30
 
31
31
  import os
32
- import sys
33
32
  from typing import Any, Optional
34
33
  from urllib.parse import urlsplit, urlunsplit
35
34
 
@@ -57,17 +56,18 @@ def _base_url(endpoint: str) -> str:
57
56
 
58
57
 
59
58
  def _require_sdk() -> Any:
60
- """Import the SDK or exit(2) with an actionable install hint."""
59
+ """Import the SDK, or raise ImportError with an actionable install hint.
60
+
61
+ Catchable exception, never ``SystemExit`` — see the note in
62
+ ``claude_code._require_sdk``."""
61
63
  try:
62
64
  import anthropic # type: ignore[import-not-found]
63
- except ImportError:
64
- print(
65
+ except ImportError as e:
66
+ raise ImportError(
65
67
  "llmkit: the anthropic adapter needs the Anthropic SDK. "
66
68
  "Install it with `pip install llmkit[anthropic]` (or `pip install "
67
- "anthropic`).",
68
- file=sys.stderr,
69
- )
70
- raise SystemExit(2)
69
+ "anthropic`)."
70
+ ) from e
71
71
  return anthropic
72
72
 
73
73
 
@@ -18,7 +18,6 @@ CLI governs those itself. Only ``model``, the request's ``system``, and
18
18
  from __future__ import annotations
19
19
 
20
20
  import os
21
- import sys
22
21
  from typing import Any
23
22
 
24
23
  from ..bridge import ChatRequest, _Emitter
@@ -26,17 +25,21 @@ from ..config import Provider
26
25
 
27
26
 
28
27
  def _require_sdk() -> Any:
29
- """Import the SDK or exit(2) with an actionable install hint."""
28
+ """Import the SDK, or raise ImportError with an actionable install hint.
29
+
30
+ A missing optional dependency must surface as a *catchable* exception, never
31
+ ``SystemExit``: llmkit is a library, and hosts embed it inside long-lived
32
+ processes (e.g. an MCP daemon's lifespan startup) where a stray ``SystemExit``
33
+ — a ``BaseException`` — escapes ``except Exception`` and tears the whole
34
+ process down. The CLI translates this back into a clean exit(2)."""
30
35
  try:
31
36
  import claude_agent_sdk as sdk # type: ignore[import-not-found]
32
- except ImportError:
33
- print(
37
+ except ImportError as e:
38
+ raise ImportError(
34
39
  "llmkit: the claude_code adapter needs the Claude Agent SDK. "
35
40
  "Install it with `pip install llmkit[claude]` (or `pip install "
36
- "claude-agent-sdk`), and make sure the `claude` CLI is on PATH.",
37
- file=sys.stderr,
38
- )
39
- raise SystemExit(2)
41
+ "claude-agent-sdk`), and make sure the `claude` CLI is on PATH."
42
+ ) from e
40
43
  return sdk
41
44
 
42
45
 
@@ -20,7 +20,6 @@ openai-compatible path never requires it.
20
20
  from __future__ import annotations
21
21
 
22
22
  import os
23
- import sys
24
23
  from typing import Any, Optional
25
24
 
26
25
  from ..bridge import DEFAULT_ENDPOINT, ChatRequest, _Emitter
@@ -33,14 +32,12 @@ def _require_sdk() -> Any:
33
32
  try:
34
33
  from google import genai # type: ignore[import-untyped,import-not-found]
35
34
  from google.genai import types # type: ignore[import-untyped,import-not-found]
36
- except ImportError:
37
- print(
35
+ except ImportError as e:
36
+ raise ImportError(
38
37
  "llmkit: the google adapter needs the Google GenAI SDK. "
39
38
  "Install it with `pip install llmkit[google]` (or `pip install "
40
- "google-genai`).",
41
- file=sys.stderr,
42
- )
43
- raise SystemExit(2)
39
+ "google-genai`)."
40
+ ) from e
44
41
  return genai, types
45
42
 
46
43
 
@@ -172,3 +172,9 @@ if __name__ == "__main__":
172
172
  sys.exit(main())
173
173
  except BrokenPipeError:
174
174
  sys.exit(0)
175
+ except ImportError as e:
176
+ # A missing optional-adapter dependency. The adapters raise a catchable
177
+ # ImportError (never SystemExit, so library hosts survive); the CLI turns
178
+ # it back into the actionable message + exit(2).
179
+ print(e, file=sys.stderr)
180
+ sys.exit(2)
@@ -10,7 +10,6 @@ from __future__ import annotations
10
10
 
11
11
  import os
12
12
  import re
13
- import sys
14
13
  import time
15
14
  import uuid
16
15
  from typing import Any, Callable, Dict, Optional
@@ -55,14 +54,12 @@ def build_client(provider: Provider) -> Any:
55
54
  hard import of ``openai.OpenAI`` at module load."""
56
55
  try:
57
56
  from openai import OpenAI
58
- except ImportError:
59
- print(
57
+ except ImportError as e:
58
+ raise ImportError(
60
59
  "llmkit: the openai package is not installed. "
61
60
  "Install it with `pip install llmkit[bridge]` (or `pip install "
62
- "openai`).",
63
- file=sys.stderr,
64
- )
65
- raise SystemExit(2)
61
+ "openai`)."
62
+ ) from e
66
63
  return OpenAI(
67
64
  base_url=provider.endpoint,
68
65
  api_key=_resolve_api_key(provider),