mohdel 0.114.0 → 0.115.0
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/js/core/events.js +4 -0
- package/js/session/driver.js +31 -10
- package/package.json +12 -12
package/js/core/events.js
CHANGED
|
@@ -87,6 +87,10 @@
|
|
|
87
87
|
* Input tokens written to a fresh prompt cache breakpoint, billed at
|
|
88
88
|
* `cacheWritePrice`. Absent when the provider has no separate
|
|
89
89
|
* cache-write counter.
|
|
90
|
+
* @property {number} [cacheWrite1hInputTokens]
|
|
91
|
+
* The 1h-TTL subset of `cacheWriteInputTokens` (Anthropic), billed at
|
|
92
|
+
* `cacheWrite1hPrice`; the 5m portion is the remainder. A request may mix
|
|
93
|
+
* TTLs. Absent when the turn has no 1h-TTL cache writes.
|
|
90
94
|
* @property {number} [cacheReadInputTokens]
|
|
91
95
|
* Input tokens served from prompt cache, billed at `cacheReadPrice`.
|
|
92
96
|
* Absent when the provider has no prompt caching.
|
package/js/session/driver.js
CHANGED
|
@@ -12,8 +12,6 @@
|
|
|
12
12
|
* @module session/driver
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import readline from 'node:readline'
|
|
16
|
-
|
|
17
15
|
import { run } from './run.js'
|
|
18
16
|
import { runImage } from './run_image.js'
|
|
19
17
|
import { runTranscription } from './run_transcription.js'
|
|
@@ -29,8 +27,6 @@ const PRECANCEL_CAP = 128
|
|
|
29
27
|
* @returns {Promise<void>}
|
|
30
28
|
*/
|
|
31
29
|
export async function drive (stdin, stdout) {
|
|
32
|
-
const rl = readline.createInterface({ input: stdin, crlfDelay: Infinity })
|
|
33
|
-
|
|
34
30
|
/** @type {{callId: string, controller: AbortController} | null} */
|
|
35
31
|
let currentCall = null
|
|
36
32
|
/** @type {import('#core/envelope.js').CallEnvelope[]} */
|
|
@@ -38,6 +34,7 @@ export async function drive (stdin, stdout) {
|
|
|
38
34
|
/** @type {(() => void) | null} */
|
|
39
35
|
let queueNotify = null
|
|
40
36
|
let stdinClosed = false
|
|
37
|
+
let framingError = null
|
|
41
38
|
/** Cancel messages received before their envelope was dequeued.
|
|
42
39
|
* JS Sets are insertion-ordered, so `values().next()` is the
|
|
43
40
|
* oldest entry — cheap FIFO eviction at cap. */
|
|
@@ -51,7 +48,8 @@ export async function drive (stdin, stdout) {
|
|
|
51
48
|
precancelled.add(callId)
|
|
52
49
|
}
|
|
53
50
|
|
|
54
|
-
|
|
51
|
+
const onLine = (line) => {
|
|
52
|
+
if (framingError) return
|
|
55
53
|
const trimmed = line.trim()
|
|
56
54
|
if (!trimmed) return
|
|
57
55
|
|
|
@@ -59,7 +57,17 @@ export async function drive (stdin, stdout) {
|
|
|
59
57
|
try {
|
|
60
58
|
obj = JSON.parse(trimmed)
|
|
61
59
|
} catch (e) {
|
|
62
|
-
process.stderr.write(`session:
|
|
60
|
+
process.stderr.write(`session: malformed stdin line, exiting: ${e.message}\n`)
|
|
61
|
+
const error = {
|
|
62
|
+
message: 'SESSION_STDIN_MALFORMED',
|
|
63
|
+
detail: `stdin line is not valid JSON: ${e.message}`,
|
|
64
|
+
severity: 'error',
|
|
65
|
+
retryable: false,
|
|
66
|
+
type: 'SESSION_STDIN_MALFORMED'
|
|
67
|
+
}
|
|
68
|
+
stdout.write(JSON.stringify({ type: 'error', error }) + '\n')
|
|
69
|
+
framingError = Object.assign(new Error(error.message), { detail: error.detail })
|
|
70
|
+
if (queueNotify) { queueNotify(); queueNotify = null }
|
|
63
71
|
return
|
|
64
72
|
}
|
|
65
73
|
|
|
@@ -113,22 +121,35 @@ export async function drive (stdin, stdout) {
|
|
|
113
121
|
|
|
114
122
|
envelopeQueue.push(obj)
|
|
115
123
|
if (queueNotify) { queueNotify(); queueNotify = null }
|
|
116
|
-
}
|
|
124
|
+
}
|
|
117
125
|
|
|
118
|
-
|
|
126
|
+
let stdinBuf = ''
|
|
127
|
+
stdin.setEncoding('utf8')
|
|
128
|
+
stdin.on('data', (chunk) => {
|
|
129
|
+
stdinBuf += chunk
|
|
130
|
+
let nl
|
|
131
|
+
while ((nl = stdinBuf.indexOf('\n')) !== -1) {
|
|
132
|
+
const line = stdinBuf.slice(0, nl)
|
|
133
|
+
stdinBuf = stdinBuf.slice(nl + 1)
|
|
134
|
+
onLine(line)
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
stdin.on('end', () => {
|
|
138
|
+
if (stdinBuf) onLine(stdinBuf)
|
|
119
139
|
stdinClosed = true
|
|
120
140
|
if (queueNotify) { queueNotify(); queueNotify = null }
|
|
121
141
|
})
|
|
122
142
|
|
|
123
143
|
while (true) {
|
|
124
|
-
// `stdinClosed` flips asynchronously inside the `
|
|
144
|
+
// `stdinClosed` flips asynchronously inside the `stdin.on('end')`
|
|
125
145
|
// callback above, which also signals `queueNotify`. The linter's
|
|
126
146
|
// no-unmodified-loop-condition rule can't see callback mutation,
|
|
127
147
|
// so it false-positives here.
|
|
128
148
|
// eslint-disable-next-line no-unmodified-loop-condition
|
|
129
|
-
while (envelopeQueue.length === 0 && !stdinClosed) {
|
|
149
|
+
while (envelopeQueue.length === 0 && !stdinClosed && !framingError) {
|
|
130
150
|
await new Promise(resolve => { queueNotify = resolve })
|
|
131
151
|
}
|
|
152
|
+
if (framingError) throw framingError
|
|
132
153
|
if (envelopeQueue.length === 0) return
|
|
133
154
|
|
|
134
155
|
const envelope = envelopeQueue.shift()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mohdel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.115.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Christophe Le Bars",
|
|
@@ -83,20 +83,20 @@
|
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
85
|
"optionalDependencies": {
|
|
86
|
-
"@clack/prompts": "^1.
|
|
87
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "^0.
|
|
88
|
-
"@opentelemetry/sdk-node": "^0.
|
|
86
|
+
"@clack/prompts": "^1.7.0",
|
|
87
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "^0.220.0",
|
|
88
|
+
"@opentelemetry/sdk-node": "^0.220.0",
|
|
89
89
|
"chalk": "^5.4.0",
|
|
90
|
-
"mohdel-thin-gate-linux-x64-gnu": "0.
|
|
90
|
+
"mohdel-thin-gate-linux-x64-gnu": "0.115.0"
|
|
91
91
|
},
|
|
92
92
|
"dependencies": {
|
|
93
|
-
"@anthropic-ai/sdk": "^0.
|
|
93
|
+
"@anthropic-ai/sdk": "^0.110.0",
|
|
94
94
|
"@cerebras/cerebras_cloud_sdk": "^1.61.1",
|
|
95
|
-
"@google/genai": "^2.
|
|
95
|
+
"@google/genai": "^2.10.0",
|
|
96
96
|
"@opentelemetry/api": "^1.9.1",
|
|
97
97
|
"env-paths": "^4.0.0",
|
|
98
|
-
"groq-sdk": "^1.
|
|
99
|
-
"openai": "^6.
|
|
98
|
+
"groq-sdk": "^1.3.0",
|
|
99
|
+
"openai": "^6.45.0",
|
|
100
100
|
"undici": "^7.24.5"
|
|
101
101
|
},
|
|
102
102
|
"lint-staged": {
|
|
@@ -104,9 +104,9 @@
|
|
|
104
104
|
},
|
|
105
105
|
"devDependencies": {
|
|
106
106
|
"gpt-tokenizer": "^3.4.0",
|
|
107
|
-
"lint-staged": "^17.0.
|
|
108
|
-
"release-it": "^20.2.
|
|
107
|
+
"lint-staged": "^17.0.8",
|
|
108
|
+
"release-it": "^20.2.1",
|
|
109
109
|
"standard": "^17.1.2",
|
|
110
|
-
"vitest": "^4.1.
|
|
110
|
+
"vitest": "^4.1.10"
|
|
111
111
|
}
|
|
112
112
|
}
|