polyllmkit 0.1.1__tar.gz → 0.1.2__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 (27) hide show
  1. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/PKG-INFO +1 -1
  2. polyllmkit-0.1.2/pyproject.toml +37 -0
  3. polyllmkit-0.1.1/pyproject.toml → polyllmkit-0.1.2/pyproject.toml.orig +1 -1
  4. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/adapters/claude_code.py +21 -12
  5. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/bridge.py +9 -9
  6. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/__init__.py +0 -0
  7. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/__init__.py +0 -0
  8. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/__main__.py +0 -0
  9. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/adapters/__init__.py +0 -0
  10. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/adapters/anthropic.py +0 -0
  11. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/adapters/google.py +0 -0
  12. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/adapters/openai.py +0 -0
  13. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/cli.py +0 -0
  14. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/client.py +0 -0
  15. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/config.py +0 -0
  16. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/sinks.py +0 -0
  17. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/bridge/stream.py +0 -0
  18. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/md/__init__.py +0 -0
  19. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/md/render/__init__.py +0 -0
  20. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/md/render/__main__.py +0 -0
  21. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/md/render/cli.py +0 -0
  22. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/md/render/stream.py +0 -0
  23. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/md/view/__init__.py +0 -0
  24. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/md/view/__main__.py +0 -0
  25. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/md/view/app.py +0 -0
  26. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/md/view/cli.py +0 -0
  27. {polyllmkit-0.1.1 → polyllmkit-0.1.2}/src/llmkit/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: polyllmkit
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Streaming, multi-provider LLM bridge + markdown rendering toolkit for terminal apps.
5
5
  Requires-Dist: openai>=1.0 ; extra == 'all'
6
6
  Requires-Dist: claude-agent-sdk>=0.2 ; extra == 'all'
@@ -0,0 +1,37 @@
1
+ [project]
2
+ name = "polyllmkit"
3
+ version = "0.1.2"
4
+ description = "Streaming, multi-provider LLM bridge + markdown rendering toolkit for terminal apps."
5
+ requires-python = ">=3.11"
6
+ dependencies = []
7
+
8
+ [project.optional-dependencies]
9
+ bridge = ["openai>=1.0"]
10
+ claude = ["claude-agent-sdk>=0.2"]
11
+ anthropic = ["anthropic>=0.40"]
12
+ google = ["google-genai>=1.0"]
13
+ all = [
14
+ "openai>=1.0",
15
+ "claude-agent-sdk>=0.2",
16
+ "anthropic>=0.40",
17
+ "google-genai>=1.0",
18
+ ]
19
+ md = [
20
+ "rich>=13.0",
21
+ "textual>=0.50",
22
+ "markdown-it-py>=3.0",
23
+ ]
24
+
25
+ [build-system]
26
+ requires = ["uv_build>=0.5,<0.12"]
27
+ build-backend = "uv_build"
28
+
29
+ [tool.uv.build-backend]
30
+ module-root = "src"
31
+ module-name = "llmkit"
32
+
33
+ [dependency-groups]
34
+ dev = [
35
+ "ruff>=0.6",
36
+ "mypy>=1.10",
37
+ ]
@@ -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.1"
7
+ version = "0.1.2"
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.
@@ -58,15 +58,15 @@ def _thinking_budget() -> int:
58
58
 
59
59
  def _build_options(sdk: Any, provider: Provider, request: ChatRequest) -> Any:
60
60
  """Assemble ClaudeAgentOptions for a tool-free single-turn chat."""
61
- opts: dict[str, Any] = dict(
62
- tools=[], # no built-in tools — plain chat, no file/shell access
63
- allowed_tools=[],
64
- disallowed_tools=[],
65
- max_turns=1,
66
- permission_mode="bypassPermissions",
67
- include_partial_messages=True, # token-level streaming deltas
68
- setting_sources=[], # ignore project/user CLAUDE.md, settings, etc.
69
- )
61
+ opts: dict[str, Any] = {
62
+ "tools": [], # no built-in tools — plain chat, no file/shell access
63
+ "allowed_tools": [],
64
+ "disallowed_tools": [],
65
+ "max_turns": 1,
66
+ "permission_mode": "bypassPermissions",
67
+ "include_partial_messages": True, # token-level streaming deltas
68
+ "setting_sources": [], # ignore project/user CLAUDE.md, settings, etc.
69
+ }
70
70
  if provider.model:
71
71
  opts["model"] = provider.model
72
72
  if request.system:
@@ -87,13 +87,22 @@ def _build_options(sdk: Any, provider: Provider, request: ChatRequest) -> Any:
87
87
  opts["thinking"] = {"type": "disabled"}
88
88
  return sdk.ClaudeAgentOptions(**opts)
89
89
 
90
+ # ``display: "summarized"`` is required on current models: they default it
91
+ # to ``omitted``, which silences thinking entirely — no deltas stream and
92
+ # the final ThinkingBlock is empty (verified: enabled+budget without display
93
+ # streams 0 chars of thinking; with display, ~tokens arrive). Mirrors the
94
+ # anthropic adapter's same-named field.
90
95
  flag = provider.enable_thinking or "auto"
91
96
  if flag == "false":
92
97
  opts["thinking"] = {"type": "disabled"}
93
98
  elif flag == "true":
94
- opts["thinking"] = {"type": "enabled", "budget_tokens": _thinking_budget()}
99
+ opts["thinking"] = {
100
+ "type": "enabled",
101
+ "budget_tokens": _thinking_budget(),
102
+ "display": "summarized",
103
+ }
95
104
  else:
96
- opts["thinking"] = {"type": "adaptive"}
105
+ opts["thinking"] = {"type": "adaptive", "display": "summarized"}
97
106
 
98
107
  return sdk.ClaudeAgentOptions(**opts)
99
108
 
@@ -146,7 +155,7 @@ async def _run(
146
155
 
147
156
  def structured_claude_code(
148
157
  provider: Provider, request: ChatRequest
149
- ) -> "tuple[int, Any]":
158
+ ) -> tuple[int, Any]:
150
159
  """Structured output via the SDK's native ``output_format`` (set in
151
160
  ``_build_options`` when the request carries a schema). Runs the single-turn
152
161
  query and returns ``(exit_code, structured_output)`` from the ResultMessage —
@@ -336,7 +336,7 @@ def complete(
336
336
  ) -> int:
337
337
  """Run a text-completion (FIM) request, streaming text to ``out``
338
338
  (default stdout). ``openai-compatible`` only."""
339
- out = out if out is not None else sys.stdout
339
+ sink = out if out is not None else sys.stdout
340
340
  provider = with_defaults(provider)
341
341
  if not provider_supports_complete(provider):
342
342
  print(
@@ -349,12 +349,12 @@ def complete(
349
349
  return 2
350
350
 
351
351
  client = build_client(provider)
352
- kwargs: dict[str, Any] = dict(
353
- model=provider.model,
354
- prompt=request.prompt,
355
- max_tokens=provider.max_tokens,
356
- temperature=provider.temperature,
357
- )
352
+ kwargs: dict[str, Any] = {
353
+ "model": provider.model,
354
+ "prompt": request.prompt,
355
+ "max_tokens": provider.max_tokens,
356
+ "temperature": provider.temperature,
357
+ }
358
358
  if request.suffix:
359
359
  kwargs["suffix"] = request.suffix
360
360
  if request.stop:
@@ -364,8 +364,8 @@ def complete(
364
364
  for chunk in client.completions.create(**kwargs):
365
365
  t = chunk.choices[0].text if chunk.choices else ""
366
366
  if t:
367
- out.write(t)
368
- out.flush()
367
+ sink.write(t)
368
+ sink.flush()
369
369
  except KeyboardInterrupt:
370
370
  return 130
371
371
  except Exception as e: