dsh-lcx-codex 0.3.3 → 0.4.0-rc.13

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.
@@ -0,0 +1,31 @@
1
+ import { execFileSync } from 'node:child_process'
2
+ import { join } from 'node:path'
3
+ import { pathToFileURL } from 'node:url'
4
+ import { ALPHA_SEARCH_OUTPUT, ALPHA_SEARCH_PARAMETERS } from '../lib/web-search-alpha.js'
5
+ import { HOSTED_SEARCH_OUTPUT, HOSTED_SEARCH_PARAMETERS } from '../lib/web-search-hosted.js'
6
+
7
+ async function dshTools() {
8
+ try {
9
+ return await import('@deepseek-ai/dsh-tools')
10
+ } catch (error) {
11
+ if (error?.code !== 'ERR_MODULE_NOT_FOUND') throw error
12
+ const root = process.platform === 'win32'
13
+ ? process.env.npm_config_prefix
14
+ ? join(process.env.npm_config_prefix, 'node_modules')
15
+ : join(process.env.APPDATA ?? '', 'npm', 'node_modules')
16
+ : execFileSync('npm', ['root', '-g'], { encoding: 'utf8', windowsHide: true }).trim()
17
+ const entry = join(root, '@deepseek-ai', 'dsh', 'node_modules', '@deepseek-ai', 'dsh-tools', 'lib', 'index.js')
18
+ return import(pathToFileURL(entry).href)
19
+ }
20
+ }
21
+
22
+ const { assertSupportedJsonSchema } = await dshTools()
23
+ for (const [name, schema] of Object.entries({
24
+ HOSTED_SEARCH_PARAMETERS,
25
+ HOSTED_SEARCH_OUTPUT,
26
+ ALPHA_SEARCH_PARAMETERS,
27
+ ALPHA_SEARCH_OUTPUT,
28
+ })) {
29
+ assertSupportedJsonSchema(schema)
30
+ process.stdout.write(`${name}: ok\n`)
31
+ }
@@ -1,459 +0,0 @@
1
- import {
2
- chmodSync,
3
- closeSync,
4
- fsyncSync,
5
- mkdirSync,
6
- openSync,
7
- readFileSync,
8
- readdirSync,
9
- renameSync,
10
- statSync,
11
- unlinkSync,
12
- writeFileSync,
13
- } from 'node:fs'
14
- import { dirname, join, basename } from 'node:path'
15
- import { randomUUID } from 'node:crypto'
16
- import { PORTABLE_HISTORY_BYTE_BUDGET } from './compact.js'
17
- import { ensurePrivateFileAcl } from './private-file.js'
18
-
19
- export const CHECKPOINT_V3_VERSION = 3
20
- export const CHECKPOINT_V3_MAX_RECORDS = 256
21
- export const CHECKPOINT_V3_MAX_BYTES = 16 * 1024 * 1024
22
-
23
- const LOCK_STALE_MS = 30 * 1000
24
- const LOCK_WAIT_MS = 5 * 1000
25
- const TEMP_STALE_MS = 60 * 60 * 1000
26
- const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu
27
-
28
- export class CheckpointV3Error extends Error {
29
- constructor(message, code, cause) {
30
- super(message, cause === undefined ? undefined : { cause })
31
- this.name = 'CheckpointV3Error'
32
- this.code = code
33
- }
34
- }
35
-
36
- function isObject(value) {
37
- return value !== null && typeof value === 'object' && !Array.isArray(value)
38
- }
39
-
40
- function bytes(value, pretty = false) {
41
- return Buffer.byteLength(JSON.stringify(value, null, pretty ? 2 : undefined), 'utf8')
42
- }
43
-
44
- function validImageAttachmentRef(ref) {
45
- return isObject(ref) && /^sha256:[a-f0-9]{64}$/iu.test(String(ref.attachmentId ?? '')) &&
46
- ['image/png', 'image/jpeg', 'image/webp', 'image/gif'].includes(ref.mediaType) &&
47
- Number.isSafeInteger(ref.bytes) && ref.bytes > 0 && Number.isSafeInteger(ref.width) && ref.width > 0 &&
48
- Number.isSafeInteger(ref.height) && ref.height > 0 && (ref.name === undefined || typeof ref.name === 'string')
49
- }
50
-
51
- function validContentPart(part) {
52
- if (!isObject(part) || typeof part.type !== 'string' || part.type.length === 0 || part.type === 'input_image') return false
53
- if (part.type === 'dsh_image_attachment') return validImageAttachmentRef(part.attachment)
54
- if ((part.type === 'input_text' || part.type === 'output_text' || part.type === 'summary_text' || part.type === 'refusal') && typeof part.text !== 'string') return false
55
- return true
56
- }
57
-
58
- function validMessageItem(item) {
59
- return typeof item.role === 'string' && item.role.length > 0 && Array.isArray(item.content) && item.content.every(validContentPart)
60
- }
61
-
62
- function validPortableMessageItem(item) {
63
- return typeof item.role === 'string' && item.role.length > 0 && Array.isArray(item.content) &&
64
- item.content.every(validContentPart)
65
- }
66
-
67
- function validNativeOutputItem(item) {
68
- if (!isObject(item) || typeof item.type !== 'string' || item.type.length === 0) return false
69
- if (item.id !== undefined && (typeof item.id !== 'string' || item.id.length === 0)) return false
70
- if (item.type === 'message') return validMessageItem(item)
71
- if (item.type === 'compaction') return validNativeCompaction(item)
72
- if (item.type === 'function_call') {
73
- return typeof item.call_id === 'string' && item.call_id.length > 0 &&
74
- typeof item.name === 'string' && item.name.length > 0 &&
75
- typeof item.arguments === 'string'
76
- }
77
- if (item.type === 'function_call_output') {
78
- return typeof item.call_id === 'string' && item.call_id.length > 0 &&
79
- (typeof item.output === 'string' || (Array.isArray(item.output) && item.output.every(validContentPart)))
80
- }
81
- if (item.type === 'reasoning') {
82
- return (item.encrypted_content === undefined || typeof item.encrypted_content === 'string') &&
83
- (item.content === undefined || (Array.isArray(item.content) && item.content.every(validContentPart))) &&
84
- (item.summary === undefined || (Array.isArray(item.summary) && item.summary.every(validContentPart)))
85
- }
86
- return true
87
- }
88
-
89
- function validPortableItem(item) {
90
- if (!isObject(item) || typeof item.type !== 'string' || item.type.length === 0) return false
91
- if (item.type === 'compaction' || item.type === 'context_compaction' || item.type === 'compaction_trigger') return false
92
- if (item.type.startsWith('response.')) return false
93
- if (Object.prototype.hasOwnProperty.call(item, 'encrypted_content')) return false
94
- if (item.id !== undefined && (typeof item.id !== 'string' || item.id.length === 0)) return false
95
- if (item.type === 'message') return validPortableMessageItem(item)
96
- if (item.type === 'function_call') {
97
- return typeof item.call_id === 'string' && item.call_id.length > 0 &&
98
- typeof item.name === 'string' && item.name.length > 0 &&
99
- typeof item.arguments === 'string'
100
- }
101
- if (item.type === 'function_call_output') {
102
- return typeof item.call_id === 'string' && item.call_id.length > 0 &&
103
- (typeof item.output === 'string' || (Array.isArray(item.output) && item.output.every(validContentPart)))
104
- }
105
- return true
106
- }
107
-
108
- function validNativeCompaction(item) {
109
- return isObject(item) && item.type === 'compaction' &&
110
- typeof item.encrypted_content === 'string' && item.encrypted_content.length > 0
111
- }
112
-
113
- function validateItemCollection(items, validator, strictPairing) {
114
- const ids = new Set()
115
- const callIndexes = new Map()
116
- const outputIndexes = new Map()
117
- for (let index = 0; index < items.length; index += 1) {
118
- const item = items[index]
119
- if (!validator(item)) return false
120
- if (item.id !== undefined) {
121
- if (ids.has(item.id)) return false
122
- ids.add(item.id)
123
- }
124
- if (item.type === 'function_call') {
125
- if (callIndexes.has(item.call_id)) return false
126
- callIndexes.set(item.call_id, index)
127
- }
128
- if (item.type === 'function_call_output') {
129
- if (outputIndexes.has(item.call_id)) return false
130
- outputIndexes.set(item.call_id, index)
131
- }
132
- }
133
- if (strictPairing) {
134
- if (callIndexes.size !== outputIndexes.size) return false
135
- for (const [callId, callIndex] of callIndexes) {
136
- if (!outputIndexes.has(callId) || callIndex >= outputIndexes.get(callId)) return false
137
- }
138
- }
139
- return true
140
- }
141
-
142
- function validRecord(record, { strictPortablePairing = false } = {}) {
143
- if (!isObject(record) || record.version !== CHECKPOINT_V3_VERSION ||
144
- typeof record.checkpointId !== 'string' || record.checkpointId.length < 8 ||
145
- typeof record.lineageId !== 'string' || record.lineageId.length === 0 ||
146
- typeof record.sourceSessionId !== 'string' || record.sourceSessionId.length === 0 ||
147
- record.sourceSessionId !== record.lineageId ||
148
- (record.sourceBranchId !== undefined && (typeof record.sourceBranchId !== 'string' || record.sourceBranchId.length === 0)) ||
149
- (record.parentCheckpointId !== undefined && (typeof record.parentCheckpointId !== 'string' || !UUID_PATTERN.test(record.parentCheckpointId))) ||
150
- (record.transport !== undefined && typeof record.transport !== 'string') ||
151
- typeof record.provider !== 'string' || record.provider.length === 0 ||
152
- typeof record.model !== 'string' || record.model.length === 0 ||
153
- typeof record.modelKey !== 'string' || record.modelKey !== `${record.provider}:${record.model}` ||
154
- typeof record.baseURLFingerprint !== 'string' || record.baseURLFingerprint.length === 0 ||
155
- typeof record.routeFingerprint !== 'string' || record.routeFingerprint.length === 0 ||
156
- !Array.isArray(record.nativeOutput) || record.nativeOutput.length === 0 ||
157
- !validNativeCompaction(record.nativeCompaction) ||
158
- !Array.isArray(record.portableHistory) ||
159
- typeof record.portableSummary !== 'string' ||
160
- (record.portableImageCount !== undefined && (!Number.isSafeInteger(record.portableImageCount) || record.portableImageCount < 0)) ||
161
- !Number.isFinite(record.createdAt)) return false
162
-
163
- const nativeCompactions = record.nativeOutput.filter((item) => isObject(item) && item.type === 'compaction')
164
- if (nativeCompactions.length !== 1 ||
165
- nativeCompactions[0].encrypted_content !== record.nativeCompaction.encrypted_content) return false
166
- if (!validateItemCollection(record.nativeOutput, validNativeOutputItem, true)) return false
167
- if (!validateItemCollection(record.portableHistory, validPortableItem, strictPortablePairing)) return false
168
- return bytes(record.nativeOutput) <= PORTABLE_HISTORY_BYTE_BUDGET &&
169
- bytes(record.portableHistory) <= PORTABLE_HISTORY_BYTE_BUDGET &&
170
- bytes(record.portableSummary) <= 16 * 1024
171
- }
172
-
173
- function emptyData() {
174
- return { version: CHECKPOINT_V3_VERSION, checkpoints: {} }
175
- }
176
-
177
- function normalizedLimits(options = {}) {
178
- const maxRecords = options.maxRecords ?? options.maxRecordCount ?? CHECKPOINT_V3_MAX_RECORDS
179
- const maxBytes = options.maxBytes ?? options.maxTotalBytes ?? CHECKPOINT_V3_MAX_BYTES
180
- if (!Number.isSafeInteger(maxRecords) || maxRecords < 1 || !Number.isSafeInteger(maxBytes) || maxBytes < 1) {
181
- throw new CheckpointV3Error('Invalid checkpoint v3 store limits', 'LCX_CHECKPOINT_V3_LIMIT_INVALID')
182
- }
183
- return { maxRecords, maxBytes }
184
- }
185
-
186
- function validateData(parsed, file, limits, { strict = false, strictIds = new Set() } = {}) {
187
- if (parsed?.version !== CHECKPOINT_V3_VERSION) {
188
- throw new CheckpointV3Error(`Unsupported checkpoint v3 store in ${file}`, 'LCX_CHECKPOINT_V3_VERSION_UNSUPPORTED')
189
- }
190
- if (!isObject(parsed.checkpoints)) {
191
- throw new CheckpointV3Error(`Invalid checkpoint v3 store in ${file}`, 'LCX_CHECKPOINT_V3_CORRUPT')
192
- }
193
- const entries = Object.entries(parsed.checkpoints)
194
- if (entries.length > limits.maxRecords) {
195
- throw new CheckpointV3Error(`Checkpoint v3 store exceeds record limit (${entries.length}/${limits.maxRecords})`, 'LCX_CHECKPOINT_V3_LIMIT_EXCEEDED')
196
- }
197
- for (const [id, record] of entries) {
198
- if (id !== record?.checkpointId) {
199
- throw new CheckpointV3Error(`Checkpoint v3 map key does not match record checkpointId (${id})`, 'LCX_CHECKPOINT_V3_KEY_MISMATCH')
200
- }
201
- if (!validRecord(record, { strictPortablePairing: strict || strictIds.has(id) })) {
202
- throw new CheckpointV3Error(`Invalid checkpoint v3 record ${id} in ${file}`, 'LCX_CHECKPOINT_V3_CORRUPT')
203
- }
204
- }
205
- for (const [id, record] of entries) {
206
- if (record.parentCheckpointId !== undefined) {
207
- const parent = parsed.checkpoints[record.parentCheckpointId]
208
- if (!parent) throw new CheckpointV3Error(`Checkpoint v3 parent ${record.parentCheckpointId} for ${id} is missing`, 'LCX_CHECKPOINT_V3_PARENT_MISSING')
209
- if (parent.lineageId !== record.lineageId) throw new CheckpointV3Error(`Checkpoint v3 parent ${record.parentCheckpointId} for ${id} has a different lineage`, 'LCX_CHECKPOINT_V3_PARENT_MISMATCH')
210
- }
211
- }
212
- const data = { version: CHECKPOINT_V3_VERSION, checkpoints: parsed.checkpoints }
213
- if (bytes(data, true) > limits.maxBytes) {
214
- throw new CheckpointV3Error(`Checkpoint v3 store exceeds byte limit (${bytes(data, true)}/${limits.maxBytes})`, 'LCX_CHECKPOINT_V3_LIMIT_EXCEEDED')
215
- }
216
- return data
217
- }
218
-
219
- function sleepSync(milliseconds) {
220
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds)
221
- }
222
-
223
- function fileSignature(file) {
224
- try {
225
- const info = statSync(file)
226
- return { mtimeMs: info.mtimeMs, ctimeMs: info.ctimeMs, size: info.size, ino: info.ino }
227
- } catch (error) {
228
- if (error?.code === 'ENOENT') return undefined
229
- throw error
230
- }
231
- }
232
-
233
- function sameFileSignature(left, right) {
234
- return left?.mtimeMs === right?.mtimeMs && left?.ctimeMs === right?.ctimeMs &&
235
- left?.size === right?.size && left?.ino === right?.ino
236
- }
237
-
238
- function lockMetadata(text) {
239
- const lines = String(text ?? '').split(/\r?\n/u)
240
- const pid = Number(lines[0])
241
- const startedAt = Number(lines[1])
242
- const token = typeof lines[2] === 'string' && lines[2].length > 0 ? lines[2] : undefined
243
- return {
244
- pid: Number.isSafeInteger(pid) && pid > 0 ? pid : undefined,
245
- startedAt: Number.isFinite(startedAt) && startedAt > 0 ? startedAt : undefined,
246
- token,
247
- }
248
- }
249
-
250
- function processAlive(pid) {
251
- if (!Number.isSafeInteger(pid) || pid <= 0) return false
252
- try {
253
- process.kill(pid, 0)
254
- return true
255
- } catch (error) {
256
- return error?.code === 'EPERM'
257
- }
258
- }
259
-
260
- function staleLockSnapshot(file) {
261
- try {
262
- const info = statSync(file)
263
- const text = readFileSync(file, 'utf8')
264
- const metadata = lockMetadata(text)
265
- const age = Date.now() - Math.max(info.mtimeMs, metadata.startedAt ?? 0)
266
- if (age <= LOCK_STALE_MS || processAlive(metadata.pid)) return undefined
267
- return { text, mtimeMs: info.mtimeMs, size: info.size }
268
- } catch {
269
- return undefined
270
- }
271
- }
272
-
273
- function unlinkLockIfUnchanged(file, snapshot) {
274
- if (!snapshot) return false
275
- try {
276
- const info = statSync(file)
277
- if (info.mtimeMs !== snapshot.mtimeMs || info.size !== snapshot.size || readFileSync(file, 'utf8') !== snapshot.text) return false
278
- unlinkSync(file)
279
- return true
280
- } catch {
281
- return false
282
- }
283
- }
284
-
285
- function cleanupStaleTemps(file) {
286
- const directory = dirname(file)
287
- const prefix = `.${basename(file)}.`
288
- let names
289
- try {
290
- names = readdirSync(directory)
291
- } catch {
292
- return
293
- }
294
- const now = Date.now()
295
- for (const name of names) {
296
- if (!name.startsWith(prefix) || !name.endsWith('.tmp')) continue
297
- const temporary = join(directory, name)
298
- try {
299
- const info = statSync(temporary)
300
- if (info.isFile() && now - info.mtimeMs > TEMP_STALE_MS) unlinkSync(temporary)
301
- } catch {
302
- // A concurrent writer may have removed or replaced the candidate.
303
- }
304
- }
305
- }
306
-
307
- export class CheckpointV3Store {
308
- constructor(file, options = {}) {
309
- this.file = file
310
- this.lockFile = `${file}.lock`
311
- this.limits = normalizedLimits(options)
312
- this.fileSignature = undefined
313
- this.data = this.load()
314
- }
315
-
316
- load(options = {}) {
317
- cleanupStaleTemps(this.file)
318
- try {
319
- const data = validateData(JSON.parse(readFileSync(this.file, 'utf8')), this.file, this.limits, options)
320
- this.fileSignature = fileSignature(this.file)
321
- return data
322
- } catch (error) {
323
- if (error?.code === 'ENOENT') {
324
- this.fileSignature = undefined
325
- return emptyData()
326
- }
327
- if (error instanceof CheckpointV3Error) throw error
328
- throw new CheckpointV3Error(`Unable to load checkpoint v3 store ${this.file}`, 'LCX_CHECKPOINT_V3_CORRUPT', error)
329
- }
330
- }
331
-
332
- refreshIfChanged() {
333
- const currentSignature = fileSignature(this.file)
334
- if (!sameFileSignature(currentSignature, this.fileSignature)) this.data = this.load()
335
- }
336
-
337
- get(id) {
338
- this.refreshIfChanged()
339
- return Object.prototype.hasOwnProperty.call(this.data.checkpoints, id) ? this.data.checkpoints[id] : undefined
340
- }
341
-
342
- has(id) {
343
- return this.get(id) !== undefined
344
- }
345
-
346
- put(id, record) {
347
- if (typeof id !== 'string' || id !== record?.checkpointId) {
348
- throw new CheckpointV3Error(`Checkpoint v3 map key does not match record checkpointId (${id})`, 'LCX_CHECKPOINT_V3_KEY_MISMATCH')
349
- }
350
- if (!validRecord(record, { strictPortablePairing: true })) {
351
- throw new CheckpointV3Error(`Invalid checkpoint v3 record ${id}`, 'LCX_CHECKPOINT_V3_CORRUPT')
352
- }
353
- mkdirSync(dirname(this.file), { recursive: true })
354
- if (fileSignature(this.file)) ensurePrivateFileAcl(this.file)
355
- ensurePrivateFileAcl(dirname(this.file))
356
- const release = this.acquireLock()
357
- try {
358
- const latest = this.load()
359
- const candidate = {
360
- version: CHECKPOINT_V3_VERSION,
361
- checkpoints: { ...latest.checkpoints, [id]: structuredClone(record) },
362
- }
363
- this.data = validateData(candidate, this.file, this.limits, { strictIds: new Set([id]) })
364
- this.saveAtomicUnlocked()
365
- } finally {
366
- release()
367
- }
368
- }
369
-
370
- acquireLock() {
371
- const started = Date.now()
372
- while (Date.now() - started <= LOCK_WAIT_MS) {
373
- let fd
374
- const token = randomUUID()
375
- const lockText = `${process.pid}\n${Date.now()}\n${token}\n`
376
- try {
377
- fd = openSync(this.lockFile, 'wx', 0o600)
378
- try {
379
- writeFileSync(fd, lockText, { encoding: 'utf8' })
380
- fsyncSync(fd)
381
- } finally {
382
- closeSync(fd)
383
- fd = undefined
384
- }
385
- ensurePrivateFileAcl(this.lockFile)
386
- return () => {
387
- try {
388
- const current = readFileSync(this.lockFile, 'utf8')
389
- if (current === lockText) unlinkSync(this.lockFile)
390
- } catch {
391
- // The lock may have been removed by stale recovery after a crash.
392
- }
393
- }
394
- } catch (error) {
395
- if (fd !== undefined) {
396
- try { closeSync(fd) } catch {}
397
- }
398
- if (error?.code !== 'EEXIST') {
399
- throw new CheckpointV3Error(`Unable to acquire checkpoint v3 lock ${this.lockFile}`, 'LCX_CHECKPOINT_V3_LOCK_FAILED', error)
400
- }
401
- if (unlinkLockIfUnchanged(this.lockFile, staleLockSnapshot(this.lockFile))) continue
402
- sleepSync(10)
403
- }
404
- }
405
- throw new CheckpointV3Error(`Timed out acquiring checkpoint v3 lock`, 'LCX_CHECKPOINT_V3_LOCK_TIMEOUT')
406
- }
407
-
408
- saveAtomic(options = {}) {
409
- mkdirSync(dirname(this.file), { recursive: true })
410
- if (fileSignature(this.file)) ensurePrivateFileAcl(this.file)
411
- ensurePrivateFileAcl(dirname(this.file))
412
- const release = this.acquireLock()
413
- try {
414
- const latest = this.load()
415
- const merged = {
416
- version: CHECKPOINT_V3_VERSION,
417
- checkpoints: { ...latest.checkpoints, ...this.data.checkpoints },
418
- }
419
- this.data = validateData(merged, this.file, this.limits, { strict: options.strict === true })
420
- this.saveAtomicUnlocked()
421
- } finally {
422
- release()
423
- }
424
- }
425
-
426
- saveAtomicUnlocked() {
427
- cleanupStaleTemps(this.file)
428
- const directory = dirname(this.file)
429
- mkdirSync(directory, { recursive: true })
430
- const temporary = join(directory, `.${basename(this.file)}.${randomUUID()}.tmp`)
431
- const serialized = JSON.stringify(this.data, null, 2)
432
- let fd
433
- try {
434
- fd = openSync(temporary, 'wx', 0o600)
435
- // Harden the empty temporary file before it receives checkpoint content.
436
- if (!ensurePrivateFileAcl(temporary)) {
437
- throw new Error(`Unable to apply private ACL to checkpoint temporary file ${temporary}`)
438
- }
439
- writeFileSync(fd, serialized, { encoding: 'utf8' })
440
- fsyncSync(fd)
441
- closeSync(fd)
442
- fd = undefined
443
- try { chmodSync(temporary, 0o600) } catch {
444
- // Windows may not expose POSIX mode bits; the ACL was applied before writing.
445
- }
446
- renameSync(temporary, this.file)
447
- ensurePrivateFileAcl(this.file)
448
- this.fileSignature = fileSignature(this.file)
449
- } catch (error) {
450
- if (fd !== undefined) {
451
- try { closeSync(fd) } catch {}
452
- }
453
- try { unlinkSync(temporary) } catch {
454
- // Preserve the original write failure.
455
- }
456
- throw new CheckpointV3Error(`Unable to atomically write checkpoint v3 store ${this.file}`, 'LCX_CHECKPOINT_V3_WRITE_FAILED', error)
457
- }
458
- }
459
- }