zames_pro 2.82.10 → 2.82.14

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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2.82.14] - 2026-10-22
11
+
12
+ ### Fixed
13
+
14
+ - **glm:** read token usage inside the chat:completion envelope
15
+
16
+ ## [2.82.13] - 2026-10-22
17
+
18
+ ### Fixed
19
+
20
+ - **qwen:** parse a bare-array history reply on resume
21
+
22
+ ## [2.82.12] - 2026-10-22
23
+
24
+ ### Fixed
25
+
26
+ - **qwen:** find an answer nested in a JSON envelope
27
+
28
+ ## [2.82.11] - 2026-10-22
29
+
30
+ ### Fixed
31
+
32
+ - **commands:** advertise /limits in the slash-command hints
33
+
10
34
  ## [2.82.10] - 2026-10-22
11
35
 
12
36
  ### Fixed
package/dist/commands.js CHANGED
@@ -1117,6 +1117,7 @@ export const SLASH_COMMANDS = [
1117
1117
  { name: '/diff', key: 'help.cmd.diff' },
1118
1118
  { name: '/diffstat', key: 'help.cmd.diffstat' },
1119
1119
  { name: '/cost', key: 'help.cmd.cost' },
1120
+ { name: '/limits', key: 'help.cmd.limits' },
1120
1121
  { name: '/export', key: 'help.cmd.export' },
1121
1122
  { name: '/doctor', key: 'help.cmd.doctor' },
1122
1123
  { name: '/add-dir', key: 'help.cmd.add_dir' },
@@ -197,7 +197,13 @@ export function extractTokenUsage(body) {
197
197
  return lastTotal;
198
198
  try {
199
199
  const obj = JSON.parse(body);
200
- const usage = obj?.usage;
200
+ // A non-streamed reply keeps `usage` inside the same `chat:completion`
201
+ // envelope as the SSE stream (`data.usage`); reading only the top level
202
+ // lost the counter entirely.
203
+ const envelope = obj?.data && typeof obj.data === 'object'
204
+ ? obj.data
205
+ : null;
206
+ const usage = ((envelope ? envelope.usage : undefined) ?? obj?.usage);
201
207
  if (usage) {
202
208
  if (typeof usage.prompt_tokens === 'number')
203
209
  return usage.prompt_tokens;
@@ -151,7 +151,12 @@ export function parseQwenChatList(json) {
151
151
  */
152
152
  export function parseQwenHistory(json) {
153
153
  const root = json;
154
- const data = root && typeof root === 'object' ? root.data : null;
154
+ // A BARE array (no `data` wrapper) and a top-level `messages` are the same
155
+ // simple shapes the chat-LIST endpoint returns: reading only `root.data`
156
+ // made /resume print nothing for a payload that DID carry the dialogue.
157
+ const data = Array.isArray(json) || root === null || typeof root !== 'object'
158
+ ? json
159
+ : (root.data ?? (root.messages ? { messages: root.messages } : null));
155
160
  // The REAL shape (verified live) is a MAP, not an array:
156
161
  // data.chat.history.messages = { <id>: { role, content, timestamp, ... } }
157
162
  // An array is accepted too (older shape).
@@ -122,6 +122,16 @@ function pickAnswer(node) {
122
122
  if (typeof v === 'string' && v)
123
123
  return v;
124
124
  }
125
+ // A wrapper envelope (`{data:{…}}`, `{response:{…}}`) keeps the answer one
126
+ // level deeper; without this the whole reply reads as empty.
127
+ for (const key of ['data', 'response', 'result']) {
128
+ const v = obj[key];
129
+ if (v && typeof v === 'object') {
130
+ const inner = pickAnswer(v);
131
+ if (inner)
132
+ return inner;
133
+ }
134
+ }
125
135
  return '';
126
136
  }
127
137
  // A universal attempt: first SSE, then regular JSON.
@@ -227,7 +237,20 @@ export function isRateLimitText(body) {
227
237
  }
228
238
  // True when the body carries actual answer text in an SSE/JSON chunk.
229
239
  function hasAnswerContent(body) {
230
- for (const obj of parseDataLines(body)) {
240
+ const b = String(body || '');
241
+ // A NON-streamed body is a single JSON object with no `data:` lines; the
242
+ // answer may sit in a wrapper (`{data:{content}}`). Without this check the
243
+ // answer was invisible here and a rate-limit/busy phrase elsewhere in the
244
+ // SAME body (the model may quote the notice) made ask() back off.
245
+ if (!b.split(NL).some((l) => l.trim().startsWith('data:'))) {
246
+ try {
247
+ const parsed = JSON.parse(b);
248
+ if (pickAnswer(parsed).trim())
249
+ return true;
250
+ }
251
+ catch { }
252
+ }
253
+ for (const obj of parseDataLines(b)) {
231
254
  const choices = obj.choices;
232
255
  if (!Array.isArray(choices))
233
256
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zames_pro",
3
- "version": "2.82.10",
3
+ "version": "2.82.14",
4
4
  "description": "Terminal coding agent that drives a real browser to chat with DeepSeek, Qwen and other web LLMs — no API key required. Reads and edits files, runs commands, commits to git, like Claude Code / Codex CLI.",
5
5
  "type": "module",
6
6
  "bin": {