@gotcos/glasses-server 6.39.1 → 6.39.3

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
@@ -1,3 +1,38 @@
1
+ ## 6.39.3
2
+
3
+ Local turns answer in seconds again: thinking is off by default.
4
+
5
+ The Ollama bridge sent no `think` field, so a thinking-class model spent its
6
+ full hidden reasoning chain before the first visible token. Measured on
7
+ qwen3.5:35b the day it became the default local model: 6,265 generated tokens
8
+ for a 150-word answer, 98.6 seconds of dead screen against 2.2 seconds with
9
+ thinking disabled, at the same visible answer quality -- and a hard prompt
10
+ could out-run the 180-second wall clock entirely.
11
+
12
+ Every request now sends `think: false` unless COS_OLLAMA_THINK opts back in
13
+ ("1"/"true", or an explicit budget: low, medium, high, max). The daemon
14
+ silently tolerates `think: false` on models without the thinking capability
15
+ (verified live), so no capability gating is needed. COS Control 0.5.77
16
+ allowlists the new key so a pinned preference survives Update Server.
17
+
18
+ ## 6.39.2
19
+
20
+ Every Claude fork failed; the copy it left behind was real.
21
+
22
+ `buildClaudeForkArgs` still carried `--tools ''`, the third read-only layer the
23
+ attached path retired on 2026-08-16. On the current Claude CLI that flag makes
24
+ a fork-resume attempt a context compaction that fails (`too_few_groups`) and
25
+ then report a synthetic 400 "Prompt is too long" with zero input tokens -- so
26
+ the route classified every claude fork `fork_orphan_possible` even though the
27
+ forked transcript sat on disk complete except for the failed turn. Found the
28
+ hour COS Control 0.5.76 put a Fork button in front of the route; isolated by
29
+ single-flag bisection (plan-only completes, allowedTools-only completes,
30
+ `--tools ''` alone reproduces).
31
+
32
+ The fork keeps its read-only stance -- `--permission-mode plan` plus an empty
33
+ `--allowedTools` -- and drops only the flag the CLI can no longer carry.
34
+ Pinned by a regression test that goes red if `--tools` returns to the argv.
35
+
1
36
  ## 6.39.1
2
37
 
3
38
  Durable jobs now remember they ran on Ollama.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gotcos/glasses-server",
3
- "version": "6.39.1",
3
+ "version": "6.39.3",
4
4
  "description": "COS Glasses \u2014 self-hosted AI heads-up-display server for Even G2 smart glasses, powered by Claude Code, Codex, Cursor Agent CLI, or local Ollama",
5
5
  "type": "module",
6
6
  "bin": {
@@ -211,11 +211,18 @@ export function forkOrphanPossible(result: ForkResult): boolean {
211
211
  * `claude -p --resume <id> --fork-session`, read-only, prompt on stdin.
212
212
  *
213
213
  * `--fork-session` is documented by the installed CLI as "When resuming, create a
214
- * new session ID" and is only meaningful alongside `--resume`. The read-only pair
215
- * (`--permission-mode plan` plus the empty tool lists) is carried over from the
216
- * attached path unchanged: a fork runs a real model turn, and it does so against a
217
- * workspace the user did not explicitly hand us, so it gets no more authority than
218
- * a continuation does.
214
+ * new session ID" and is only meaningful alongside `--resume`. The fork keeps a
215
+ * read-only stance a fork runs a real model turn against a workspace the user
216
+ * did not explicitly hand us but that stance is now `--permission-mode plan`
217
+ * plus an empty `--allowedTools` only. The third layer this used to carry,
218
+ * `--tools ''`, is GONE: on the current CLI an empty --tools on a fork-resume
219
+ * triggers a spurious context compaction (`too_few_groups`) followed by a
220
+ * synthetic 400 "Prompt is too long" with zero input tokens — every claude fork
221
+ * failed as orphan_possible while the transcript copy sat there complete.
222
+ * Isolated by single-flag bisection on 2026-08-26: plan-only completed,
223
+ * allowedTools-only completed, `--tools ''` alone reproduced the failure. (The
224
+ * attached path dropped all three layers on 2026-08-16 by explicit decision;
225
+ * the fork deliberately keeps the two that still work.)
219
226
  *
220
227
  * `stream-json` requires `--verbose`; without it the CLI refuses and we would never
221
228
  * see the id we are required to verify.
@@ -228,7 +235,6 @@ export function buildClaudeForkArgs(nativeThreadId: string): string[] {
228
235
  '--resume', nativeThreadId,
229
236
  '--fork-session',
230
237
  '--permission-mode', 'plan',
231
- '--tools', '',
232
238
  '--allowedTools', '',
233
239
  ]
234
240
  }
@@ -30,6 +30,25 @@ import { OLLAMA_MODEL } from '../../shared/model-preference.js'
30
30
 
31
31
  const INACTIVITY_MS = 60_000
32
32
  const WALL_MAX_MS = 180_000
33
+
34
+ /**
35
+ * Thinking is OFF by default. A thinking-class model spends a hidden
36
+ * reasoning chain before its first visible token -- measured 2026-08-26 on
37
+ * qwen3.5:35b: 6,265 generated tokens for a 150-word answer (~20K thinking
38
+ * chars), 98.6s wall against 2.2s with thinking disabled, at the same
39
+ * visible answer quality. On the lens that is a dead screen for a minute
40
+ * and a half, and a hard prompt can out-run WALL_MAX_MS entirely. The
41
+ * daemon silently tolerates `think: false` on models WITHOUT the thinking
42
+ * capability (verified live against llama3.2:1b -- HTTP 200), so no
43
+ * capability gate is needed. COS_OLLAMA_THINK opts back in: "1"/"true"
44
+ * enables it, or an explicit budget level passes through.
45
+ */
46
+ export function resolveOllamaThink(raw: string | undefined): boolean | string {
47
+ const value = (raw ?? '').trim().toLowerCase()
48
+ if (value === '1' || value === 'true') return true
49
+ if (value === 'low' || value === 'medium' || value === 'high' || value === 'max') return value
50
+ return false
51
+ }
33
52
  const HISTORY_LIMIT = 20
34
53
 
35
54
  type OllamaChatMessage = { role: 'system' | 'user' | 'assistant'; content: string }
@@ -207,6 +226,7 @@ export async function callOllamaStreaming(
207
226
  model: catalog.model,
208
227
  messages,
209
228
  stream: true,
229
+ think: resolveOllamaThink(process.env.COS_OLLAMA_THINK),
210
230
  }),
211
231
  signal: abort.signal,
212
232
  })