tsugite-codex-cli 0.17.3__tar.gz → 0.19.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.
@@ -15,8 +15,8 @@ dist/
15
15
  downloads/
16
16
  eggs/
17
17
  .eggs/
18
- lib/
19
- lib64/
18
+ /lib/
19
+ /lib64/
20
20
  parts/
21
21
  sdist/
22
22
  var/
@@ -176,9 +176,21 @@ docs-old/
176
176
  docs/design/
177
177
  examples/*
178
178
  !examples/tsugite-example-plugin/
179
- agents/
179
+ /agents/
180
180
  .claude/
181
181
  .tsugite/
182
182
  benchmarks/
183
183
  docker-compose.test.yml
184
- #### TODO ^^^
184
+ #### TODO ^^^
185
+
186
+ plugins/tsugite-daemon/frontend/node_modules/
187
+ # Vite dep-optimizer cache. Normally under node_modules/.vite, but lands at the
188
+ # cwd's `.vite/` when vite/vitest is run from the repo root, so ignore it anywhere.
189
+ .vite/
190
+ # Built web UI - generated by `mise run web-build`; the wheel bundles it via
191
+ # hatch `artifacts`, git never carries it.
192
+ plugins/tsugite-daemon/tsugite_daemon/web/
193
+ # Re-include frontend source that generic lib/ rules (incl. contributors' global
194
+ # gitignores with Python-style `lib/`) would otherwise silently exclude.
195
+ !plugins/tsugite-daemon/frontend/src/lib/
196
+ !plugins/tsugite-daemon/frontend/src/lib/**
@@ -1,6 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tsugite-codex-cli
3
- Version: 0.17.3
3
+ Version: 0.19.0
4
4
  Summary: Tsugite plugin: ChatGPT subscription auth via Codex CLI token store
5
+ Author: Justyn Shull
5
6
  Requires-Python: >=3.11
6
- Requires-Dist: tsugite-cli==0.17.3
7
+ Requires-Dist: tsugite-cli==0.19.0
@@ -1,10 +1,11 @@
1
1
  [project]
2
2
  name = "tsugite-codex-cli"
3
- version = "0.17.3"
3
+ version = "0.19.0"
4
4
  description = "Tsugite plugin: ChatGPT subscription auth via Codex CLI token store"
5
+ authors = [{ name = "Justyn Shull" }]
5
6
  requires-python = ">=3.11"
6
7
  dependencies = [
7
- "tsugite-cli==0.17.3",
8
+ "tsugite-cli==0.19.0",
8
9
  ]
9
10
 
10
11
  [project.entry-points."tsugite.providers"]
@@ -88,7 +88,7 @@ def _normalise_kwargs(kwargs: dict) -> dict:
88
88
  if key == "max_tokens":
89
89
  body["max_output_tokens"] = value
90
90
  elif key == "reasoning_effort":
91
- body["reasoning"] = {"effort": value}
91
+ body["reasoning"] = {"effort": value, "summary": "auto"}
92
92
  elif key == "response_format":
93
93
  body["text"] = {"format": value}
94
94
  elif key in {"temperature", "top_p", "stop", "presence_penalty", "frequency_penalty"}:
@@ -107,10 +107,16 @@ def _build_usage(usage_in: dict | None) -> Usage:
107
107
  total_tokens = int(total) if total is not None else input_tokens + output_tokens
108
108
  details = usage_in.get("output_tokens_details") or {}
109
109
  reasoning_tokens = details.get("reasoning_tokens")
110
+ # The Responses API reports the cached prompt prefix (a subset of input_tokens)
111
+ # under input_tokens_details.cached_tokens - the input-side mirror of
112
+ # output_tokens_details.reasoning_tokens above.
113
+ input_details = usage_in.get("input_tokens_details") or {}
114
+ cached_tokens = input_details.get("cached_tokens")
110
115
  return Usage(
111
116
  prompt_tokens=input_tokens,
112
117
  completion_tokens=output_tokens,
113
118
  total_tokens=total_tokens,
119
+ cached_tokens=int(cached_tokens) if cached_tokens is not None else None,
114
120
  reasoning_tokens=int(reasoning_tokens) if reasoning_tokens is not None else None,
115
121
  )
116
122
 
@@ -120,6 +126,7 @@ class CodexCliProvider:
120
126
 
121
127
  # Stateless across calls (auth refresh is internal), so the registry can cache one instance.
122
128
  cacheable = True
129
+ models_are_definitive = True # CLI exposes a fixed model set; unlisted ids are typos
123
130
 
124
131
  def __init__(self, name: str = "codex_cli"):
125
132
  self.name = name
@@ -178,6 +185,11 @@ class CodexCliProvider:
178
185
  if stream:
179
186
  body["stream"] = True
180
187
  body.update(_normalise_kwargs(kwargs))
188
+ # Reasoning summaries are opt-in on the Responses API: without
189
+ # `reasoning.summary` no reasoning_summary_text deltas are ever sent,
190
+ # so the UI can never show thinking. Ask for them even when no effort
191
+ # override is set (the codex CLI itself always sends both).
192
+ body.setdefault("reasoning", {}).setdefault("summary", "auto")
181
193
  return body
182
194
 
183
195
  @staticmethod
@@ -279,6 +291,10 @@ class CodexCliProvider:
279
291
  delta = event.get("delta") or ""
280
292
  if delta:
281
293
  yield StreamChunk(reasoning_content=delta)
294
+ elif etype == "response.reasoning_summary_part.done":
295
+ # Summary parts are separate paragraphs; without a break the
296
+ # accumulated markdown runs them together (**a****b**).
297
+ yield StreamChunk(reasoning_content="\n\n")
282
298
  elif etype == "response.completed":
283
299
  response_obj = event.get("response") or {}
284
300
  usage = _build_usage(response_obj.get("usage"))