@gotcos/glasses-server 6.21.0 → 6.21.1
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 +9 -0
- package/package.json +1 -1
- package/server/lib/provider-proof.ts +44 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## 6.21.1
|
|
2
|
+
|
|
3
|
+
- Make the transactional Claude readiness proof explicitly use Haiku instead
|
|
4
|
+
of inheriting a user's heavyweight default model. The no-tool proof now has
|
|
5
|
+
a 45-second bound, while normal COS queries keep their selected models.
|
|
6
|
+
- Preserve timeout and cancellation reasons across the provider-process close
|
|
7
|
+
race. A timed-out proof now reports `provider proof timed out` instead of the
|
|
8
|
+
misleading `provider process exited before launch`.
|
|
9
|
+
|
|
1
10
|
## 6.21.0
|
|
2
11
|
|
|
3
12
|
Transcription quality is now a machine-owned, observable two-tier policy.
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@ const PROOF_PROMPT = `This is an automated local readiness check. Do not use too
|
|
|
17
17
|
const successCache = new Map<ProofProvider, ProviderProofResult>()
|
|
18
18
|
const inFlight = new Map<ProofProvider, Promise<ProviderProofResult>>()
|
|
19
19
|
|
|
20
|
-
interface ProcessResult {
|
|
20
|
+
export interface ProcessResult {
|
|
21
21
|
code: number | null
|
|
22
22
|
stdout: string
|
|
23
23
|
stderr: string
|
|
@@ -25,7 +25,9 @@ interface ProcessResult {
|
|
|
25
25
|
aborted: boolean
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
type TerminationReason = 'timeout' | 'abort' | null
|
|
29
|
+
|
|
30
|
+
export function runBounded(
|
|
29
31
|
command: string,
|
|
30
32
|
args: string[],
|
|
31
33
|
input: string,
|
|
@@ -48,6 +50,11 @@ function runBounded(
|
|
|
48
50
|
let stdout = ''
|
|
49
51
|
let stderr = ''
|
|
50
52
|
let settled = false
|
|
53
|
+
// The child `close` event normally wins the race against the async
|
|
54
|
+
// terminateProviderProcess() result. Record WHY termination began before
|
|
55
|
+
// sending a signal so that close cannot misreport a timeout as
|
|
56
|
+
// "exited before launch" (Control 0.3.5 field failure, 2026-08-03).
|
|
57
|
+
let terminationReason: TerminationReason = null
|
|
51
58
|
const cap = (value: string) => value.slice(-256_000)
|
|
52
59
|
child.stdout.on('data', chunk => { stdout = cap(stdout + chunk.toString()) })
|
|
53
60
|
child.stderr.on('data', chunk => { stderr = cap(stderr + chunk.toString()) })
|
|
@@ -58,27 +65,57 @@ function runBounded(
|
|
|
58
65
|
signal?.removeEventListener('abort', abort)
|
|
59
66
|
resolvePromise(result)
|
|
60
67
|
}
|
|
68
|
+
const terminatedResult = (code: number | null): ProcessResult => ({
|
|
69
|
+
code,
|
|
70
|
+
stdout,
|
|
71
|
+
stderr,
|
|
72
|
+
timedOut: terminationReason === 'timeout',
|
|
73
|
+
aborted: terminationReason === 'abort',
|
|
74
|
+
})
|
|
61
75
|
const timer = setTimeout(() => {
|
|
76
|
+
if (settled || terminationReason) return
|
|
77
|
+
terminationReason = 'timeout'
|
|
62
78
|
void terminateProviderProcess(child, { termGraceMs: 50 }).then(result => {
|
|
63
|
-
if (result.closed) finish(
|
|
79
|
+
if (result.closed) finish(terminatedResult(result.code))
|
|
64
80
|
else console.error('[provider-proof] timed-out provider did not close after SIGKILL; retaining request ownership')
|
|
65
81
|
})
|
|
66
82
|
}, timeoutMs)
|
|
67
83
|
timer.unref?.()
|
|
68
84
|
const abort = () => {
|
|
85
|
+
if (settled || terminationReason) return
|
|
86
|
+
terminationReason = 'abort'
|
|
69
87
|
void terminateProviderProcess(child).then(result => {
|
|
70
|
-
if (result.closed) finish(
|
|
88
|
+
if (result.closed) finish(terminatedResult(result.code))
|
|
71
89
|
else console.error('[provider-proof] canceled provider did not close after SIGKILL; retaining request ownership')
|
|
72
90
|
})
|
|
73
91
|
}
|
|
74
|
-
child.once('error', err =>
|
|
75
|
-
|
|
92
|
+
child.once('error', err => {
|
|
93
|
+
stderr = cap(stderr + err.message)
|
|
94
|
+
finish(terminatedResult(null))
|
|
95
|
+
})
|
|
96
|
+
child.once('close', code => finish(terminatedResult(code)))
|
|
76
97
|
signal?.addEventListener('abort', abort, { once: true })
|
|
77
98
|
child.stdin.on('error', () => { /* close/error is authoritative */ })
|
|
78
99
|
child.stdin.end(input)
|
|
79
100
|
})
|
|
80
101
|
}
|
|
81
102
|
|
|
103
|
+
export const CLAUDE_PROOF_MODEL = 'haiku'
|
|
104
|
+
export const CLAUDE_PROOF_TIMEOUT_MS = 45_000
|
|
105
|
+
|
|
106
|
+
export function claudeProofArgs(): string[] {
|
|
107
|
+
return [
|
|
108
|
+
'-p',
|
|
109
|
+
'--model', CLAUDE_PROOF_MODEL,
|
|
110
|
+
'--output-format', 'json',
|
|
111
|
+
'--permission-mode', 'dontAsk',
|
|
112
|
+
'--tools', '',
|
|
113
|
+
'--allowedTools', '',
|
|
114
|
+
'--system-prompt', PROOF_PROMPT,
|
|
115
|
+
PROOF_PROMPT,
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
|
|
82
119
|
export function claudeProofText(stdout: string): string {
|
|
83
120
|
try {
|
|
84
121
|
const parsed = JSON.parse(stdout) as { result?: unknown }
|
|
@@ -120,15 +157,7 @@ function safeProofError(result: ProcessResult): string {
|
|
|
120
157
|
async function executeProof(provider: ProofProvider, signal?: AbortSignal): Promise<ProviderProofResult> {
|
|
121
158
|
const started = Date.now()
|
|
122
159
|
const result = provider === 'claude'
|
|
123
|
-
? await runBounded('claude',
|
|
124
|
-
'-p',
|
|
125
|
-
'--output-format', 'json',
|
|
126
|
-
'--permission-mode', 'dontAsk',
|
|
127
|
-
'--tools', '',
|
|
128
|
-
'--allowedTools', '',
|
|
129
|
-
'--system-prompt', PROOF_PROMPT,
|
|
130
|
-
PROOF_PROMPT,
|
|
131
|
-
], '', 120_000, signal)
|
|
160
|
+
? await runBounded('claude', claudeProofArgs(), '', CLAUDE_PROOF_TIMEOUT_MS, signal)
|
|
132
161
|
: await runBounded('codex', [
|
|
133
162
|
'exec',
|
|
134
163
|
'--sandbox', 'read-only',
|