dsh-lcx-codex 0.4.2 → 0.4.3-pre.2

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.
Files changed (47) hide show
  1. package/README.md +116 -202
  2. package/cordis.patch.yml +3 -20
  3. package/lib/client.js +273 -146
  4. package/lib/compact-v2.js +218 -199
  5. package/lib/dsh-compat.js +227 -100
  6. package/lib/dsh-responses.js +445 -277
  7. package/lib/index.js +851 -757
  8. package/lib/json-store.js +50 -31
  9. package/lib/native-checkpoint.js +520 -194
  10. package/lib/responses-request.js +106 -121
  11. package/lib/responses-stream.js +972 -443
  12. package/lib/route.js +229 -355
  13. package/lib/service-mutex.js +73 -64
  14. package/lib/token-budget.js +176 -108
  15. package/lib/transport.js +277 -67
  16. package/lib/types/client/index.d.ts +6 -0
  17. package/lib/types/compact-v2.d.ts +104 -0
  18. package/lib/types/dsh-compat.d.ts +78 -0
  19. package/lib/types/dsh-responses.d.ts +82 -0
  20. package/lib/types/index.d.ts +83 -0
  21. package/lib/types/json-store.d.ts +10 -0
  22. package/lib/types/native-checkpoint.d.ts +213 -0
  23. package/lib/types/responses-request.d.ts +58 -0
  24. package/lib/types/responses-stream.d.ts +51 -0
  25. package/lib/types/route.d.ts +132 -0
  26. package/lib/types/service-mutex.d.ts +14 -0
  27. package/lib/types/token-budget.d.ts +50 -0
  28. package/lib/types/transport.d.ts +20 -0
  29. package/lib/types/web-run-output.d.ts +29 -0
  30. package/lib/types/web-search-alpha.d.ts +286 -0
  31. package/lib/types/web-search-capability.d.ts +26 -0
  32. package/lib/types/web-search-hosted.d.ts +246 -0
  33. package/lib/types/web-search-ref-store.d.ts +22 -0
  34. package/lib/web-run-output.js +167 -18
  35. package/lib/web-search-alpha.js +865 -163
  36. package/lib/web-search-capability.js +55 -65
  37. package/lib/web-search-hosted.js +210 -32
  38. package/lib/web-search-ref-store.js +63 -59
  39. package/package.json +79 -27
  40. package/ARCHITECTURE.md +0 -117
  41. package/CHANGELOG.md +0 -224
  42. package/README_EN.md +0 -277
  43. package/assets/dsh-lcx-codex-banner.jpg +0 -0
  44. package/lib/legacy-v3.js +0 -20
  45. package/lib/responses-replay.js +0 -68
  46. package/scripts/probe-alpha.mjs +0 -43
  47. package/scripts/validate-dsh-schema.mjs +0 -31
package/README_EN.md DELETED
@@ -1,277 +0,0 @@
1
- # dsh-lcx-codex
2
-
3
- [![npm](https://img.shields.io/npm/v/dsh-lcx-codex?label=stable&color=1677ff)](https://www.npmjs.com/package/dsh-lcx-codex)
4
- [![CI](https://github.com/kk3ya03-star/dsh-lcx-codex/actions/workflows/publish.yml/badge.svg)](https://github.com/kk3ya03-star/dsh-lcx-codex/actions/workflows/publish.yml)
5
- ![DSH](https://img.shields.io/badge/DSH-0.1.1--rc.2-4ea8ff)
6
- ![Node](https://img.shields.io/badge/Node-%5E22.19%20%7C%7C%20%3E%3D24-2f855a)
7
- ![Plugin Pi](https://img.shields.io/badge/plugin%20Pi-0.84.3-111827)
8
- ![License](https://img.shields.io/badge/license-MIT-6b7280)
9
-
10
- [简体中文](README.md) · **English** · [Architecture](ARCHITECTURE.md) · [Changelog](CHANGELOG.md) · [Releases](https://github.com/kk3ya03-star/dsh-lcx-codex/releases)
11
-
12
- > **Keep a DSH GPT Responses conversation on one final Responses wire owner from the first ordinary turn through tools, Native V2 Compact / Replay, restart recovery, and GPT model switching.**
13
-
14
- `dsh-lcx-codex` does not replace DSH. DSH still owns the Agent, Session, model selection, tool execution, attachments, and compaction policy. When **LCX is ON**, LCX owns the final request / SSE wire for the selected GPT Responses conversation.
15
-
16
- ## Current stable release
17
-
18
- **`0.4.2`** is the current stable release and a **zero-functional-change stable promotion** of the fully validated `0.4.2-pre.1` runtime.
19
-
20
- ```powershell
21
- dsh plugin --profile web add dsh-lcx-codex
22
- dsh web
23
- ```
24
-
25
- - npm dist-tag: `latest`
26
- - DSH: `0.1.1-rc.2`
27
- - Plugin Pi: `0.84.3`
28
- - Node.js: `^22.19.0 || >=24.0.0`
29
-
30
- `0.4.2-pre.1` remains a historical prerelease; new users should install `latest`.
31
-
32
- ## Product contract
33
-
34
- ```text
35
- LCX OFF
36
- = use the native DSH LLM path
37
-
38
- LCX ON
39
- = LCX owns the final Responses request / SSE wire
40
- for the selected GPT Responses conversation starting at ordinary turn 1
41
- ```
42
-
43
- Turn LCX off before switching to Claude, Gemini, DeepSeek, or another non-GPT model. Model switching itself does not require a DSH restart.
44
-
45
- ## Why LCX exists
46
-
47
- DSH already owns the Agent, Session, tools, and compaction lifecycle. LCX addresses the final provider-native GPT Responses layer: ordinary requests, tools, Native Compact, Replay, restart/resume, and GPT route migration no longer switch final wire owners inside one conversation.
48
-
49
- ```text
50
- DSH
51
- Agent / Session / Tools
52
-
53
- llm / stream seam
54
-
55
- ┌──────────┴──────────┐
56
- │ │
57
- LCX OFF LCX ON
58
- │ │
59
- native DSH adapter LCX Responses Core
60
-
61
- ordinary turn 1
62
-
63
- tools
64
-
65
- Native V2 Compact
66
-
67
- Replay
68
-
69
- Restart / Resume
70
-
71
- GPT Model Migration
72
- ```
73
-
74
- Compact therefore changes history representation without also changing request ownership.
75
-
76
- ## Core capabilities
77
-
78
- ### 1. Full GPT Responses lifecycle ownership
79
-
80
- With LCX ON, ordinary requests, tool continuations, Native Compact, Native Replay, restart/resume, and portable GPT migration use one LCX Responses request-builder / transport owner.
81
-
82
- DSH remains the canonical session/history owner. LCX does not create a second conversation database or replace the DSH Tool Executor.
83
-
84
- ### 2. GPT-5.6 Prompt Cache
85
-
86
- `0.4.2` uses the current GPT-5.6 cache-options path and maintains stable cache identity inside a session:
87
-
88
- - implicit caching by default;
89
- - the supported route sends `prompt_cache_options.ttl = 30m`;
90
- - ordinary consecutive turns and tool-heavy workloads can reuse warm prefixes;
91
- - Native Compact intentionally creates a new history/cache epoch, so the old uncompressed prefix is not promised to remain reusable;
92
- - real long-session validation repeatedly observed near-complete prefix reuse while request topology remained stable.
93
-
94
- Cache reuse depends on provider behavior, model, request prefix, tool schemas, and session state; it is not a fixed performance guarantee.
95
-
96
- One confirmed boundary: activating a skill at runtime can change the top-level tool schema and cause a one-time cache reset. The new topology warms again on the next request. The currently supported route rejects content-level `prompt_cache_breakpoint`, and DSH `0.1.1-rc.2` does not expose authoritative dynamic-tool provenance, so `0.4.2` preserves the safe one-time reset instead of guessing tool history.
97
-
98
- ### 3. Native V2 Compact + Replay
99
-
100
- DSH still decides **when to compact, what range to compact, transaction boundaries, and recovery**. LCX owns only the provider-native Responses V2 wire.
101
-
102
- Default pressure coordination:
103
-
104
- ```text
105
- 0% ─────────────────── 90% ───── 95% ───── 100%
106
- normal Native emergency hard cap
107
- V2 DSH prune
108
- ```
109
-
110
- - `90%`: prefer Native V2;
111
- - `95%`: allow emergency DSH tool-result pruning;
112
- - provider-confirmed overflow stays with DSH recovery;
113
- - manual `/compact` keeps the native DSH compaction transaction.
114
-
115
- Native checkpoint v5 persists provider-native compaction state plus the portable retained history needed for fidelity. Compatible same-session routes can use Native replay; incompatible routes never reuse unsafe opaque state.
116
-
117
- ### 4. Restart / Resume + hot GPT switching
118
-
119
- A single DSH session can continue through:
120
-
121
- ```text
122
- Terra
123
- → Compact
124
- → Replay
125
- → Restart DSH
126
- → Resume same session
127
- → Switch to Sol
128
- → Continue
129
- ```
130
-
131
- Compatible route/model resumes may restore Native opaque state. An incompatible GPT model / route drops unsafe opaque state and reconstructs portable history while remaining on LCX Responses transport.
132
-
133
- ### 5. Hosted Search + stateful Web Actions
134
-
135
- Ordinary web search still uses DSH's native `web_search`. LCX can map its SearchProvider to the active GPT Hosted Search route instead of exposing a second ordinary-search tool.
136
-
137
- | Need | Entry |
138
- |---|---|
139
- | Ordinary web search | DSH `web_search` |
140
- | Advanced Hosted Search controls | `websearch_gpt_advanced` |
141
- | Stateful page / PDF actions | `websearch_alpha` |
142
-
143
- Alpha supports:
144
-
145
- ```text
146
- search → open → find / click → screenshot
147
- ```
148
-
149
- Alpha is off by default and is registered only after the current endpoint / provider / model / schema passes a capability probe. Unknown deployments fail closed.
150
-
151
- ### 6. Isolated Pi 0.84.3 upgrade
152
-
153
- The plugin uses `@earendil-works/pi-ai 0.84.3` without overriding the DSH host dependency:
154
-
155
- ```text
156
- DSH 0.1.1-rc.2
157
- └─ host Pi 0.82.1 ← unchanged
158
-
159
- dsh-lcx-codex 0.4.2
160
- └─ plugin Pi 0.84.3 ← isolated plugin dependency
161
- ```
162
-
163
- Pi owns canonical Responses message/tool serialization, reasoning, IDs, strict/grammar/custom tools, `additional_tools`, `tool_search`, namespace, and stream semantics. LCX does not maintain a second generic provider framework.
164
-
165
- ## Configure in 30 seconds
166
-
167
- ### Requirements
168
-
169
- - Node.js `^22.19.0 || >=24.0.0`
170
- - DSH `0.1.1-rc.2`
171
- - a working GPT Responses route in DSH
172
- - actual upstream support for the Hosted Search / Native V2 / Alpha capabilities you enable
173
-
174
- ### Suggested first-run settings
175
-
176
- | Setting | Suggested | Notes |
177
- |---|---:|---|
178
- | Enable LCX | **On** | Own the current GPT Responses conversation |
179
- | Use GPT Hosted Search | As needed | Use GPT Hosted Search behind DSH `web_search` |
180
- | Advanced Hosted Search | Off | Enable only for advanced Hosted parameters |
181
- | Alpha Search | Off | Enable after capability validation |
182
- | Native-first auto compaction | On | Use Native-first pressure coordination |
183
- | Native threshold | `90%` | Proactive Native V2 threshold |
184
- | Emergency DSH prune | `95%` | Emergency prune threshold |
185
- | Fallback to Basic Compaction | On | Allow bounded fallback after Native failure |
186
- | `web_search` timeout | `240s` | Avoid premature timeout on slower Hosted Search |
187
-
188
- ### Verify observable behavior
189
-
190
- | Capability | Expected behavior |
191
- |---|---|
192
- | LCX ownership | With LCX ON, the first GPT ordinary request already uses the LCX Responses path |
193
- | Prompt Cache | Stable warm turns may report provider `cached_tokens` |
194
- | Hosted Search | Ordinary entry remains DSH `web_search` |
195
- | Advanced Hosted | `websearch_gpt_advanced` appears when enabled |
196
- | Alpha | `websearch_alpha` appears only after capability validation |
197
- | Native V2 | Compact produces provider-native checkpoint behavior rather than relabeling Basic Compaction |
198
- | Replay | The same DSH session continues after Compact and remains resumable after restart |
199
-
200
- ## DSH / LCX responsibility boundary
201
-
202
- | Component | Owns |
203
- |---|---|
204
- | **DSH** | Agent loop, Session/history, GenerateOptions, model/credential selection, tool execution, AttachmentStore, pressure policy, compaction transaction |
205
- | **DSH compatibility seam** | Projects DSH messages / GenerateOptions into Pi Context and bridges results back to DSH |
206
- | **Plugin Pi 0.84.3** | Canonical Responses serialization / parser semantics |
207
- | **LCX** | ON/OFF ownership, final Responses body + HTTP/SSE wire, ordinary/compact/replay orchestration, Native opaque state, Search capabilities |
208
-
209
- See [ARCHITECTURE.md](ARCHITECTURE.md) for checkpoint, portable replay, cache identity, RefStore, pressure coordination, and protocol details.
210
-
211
- ## Compatibility
212
-
213
- | Plugin | DSH | DSH host Pi | Plugin Pi | Status |
214
- |---|---|---|---|---|
215
- | `0.4.2` | `0.1.1-rc.2` | `0.82.1` | `0.84.3` | **VERIFIED STABLE** |
216
- | `0.4.1` | `0.1.1-rc.2` | `0.82.1` | `0.82.1` | historical stable |
217
-
218
- DSH `0.1.2-alpha.1` and newer Pi versions are not part of the formal `0.4.2` compatibility claim. They will be validated by affected seam rather than assumed compatible automatically.
219
-
220
- ## Current boundaries
221
-
222
- - The supported route uses implicit Prompt Cache. Content-level explicit breakpoints are rejected on that route and are not exposed as a product setting.
223
- - Dynamic skills/plugins that change the top-level tool schema can trigger a one-time prompt-cache reset; functionality remains correct and the new topology warms again.
224
- - `reasoning.context` / `reasoning.mode` remain host/Pi exposure boundaries; LCX does not invent a second control surface.
225
- - The normal operational context profile remains in the ~`262K` class; 1.05M long context is not enabled by default.
226
- - Credentialed `ALPHA-004` runtime coverage remains `NOT_COVERED`, while fail-closed behavior is covered by tests.
227
- - Programmatic Tool Calling is not currently advertised as supported.
228
-
229
- ## FAQ
230
-
231
- <details>
232
- <summary><strong>Why do I need to turn LCX off before switching to a non-GPT model?</strong></summary>
233
-
234
- LCX ON is a GPT Responses lifecycle ownership switch, not a universal multi-model proxy. Non-GPT models continue through native DSH adapters.
235
-
236
- </details>
237
-
238
- <details>
239
- <summary><strong>Why is web_search still the same tool?</strong></summary>
240
-
241
- By design. LCX changes the SearchProvider behind DSH `web_search` instead of exposing two ordinary search tools to the model.
242
-
243
- </details>
244
-
245
- <details>
246
- <summary><strong>Why is Alpha sometimes missing?</strong></summary>
247
-
248
- That is fail-closed behavior. `websearch_alpha` is not registered until the active route/schema passes capability probing.
249
-
250
- </details>
251
-
252
- <details>
253
- <summary><strong>Why can a skill load cause the cache to warm again?</strong></summary>
254
-
255
- Some skills dynamically register new top-level tools. Tool schemas are part of the cacheable prompt prefix, so a topology change can establish a new cache epoch. `0.4.2` prioritizes correct tool definitions instead of guessing provenance to force reuse of an old cache.
256
-
257
- </details>
258
-
259
- ## Development and verification
260
-
261
- ```bash
262
- npm run typecheck
263
- npm test
264
- npm run test:schema
265
- npm pack --ignore-scripts
266
- ```
267
-
268
- - Architecture: [ARCHITECTURE.md](ARCHITECTURE.md)
269
- - Changelog: [CHANGELOG.md](CHANGELOG.md)
270
- - GitHub Releases: [Releases](https://github.com/kk3ya03-star/dsh-lcx-codex/releases)
271
- - npm: [`dsh-lcx-codex`](https://www.npmjs.com/package/dsh-lcx-codex)
272
-
273
- ## License
274
-
275
- MIT
276
-
277
- > `LCX` is only the project name. This is a community project and is not affiliated with OpenAI, DeepSeek, Sub2API, or NewAPI.
Binary file
package/lib/legacy-v3.js DELETED
@@ -1,20 +0,0 @@
1
- import { readFileSync } from 'node:fs'
2
- import { baseURLFingerprint, sessionAncestry } from './route.js'
3
-
4
- const PATTERN = /\[dsh-lcx-codex-v3-checkpoint:([0-9a-f-]{36})\]/iu
5
- function textOf(message) { return (message?.content ?? []).filter((b) => b?.type === 'text').map((b) => b.text).join('') }
6
- export function legacyV3Id(message) { return textOf(message).match(PATTERN)?.[1]?.toLowerCase() }
7
- export function loadLegacyRecord(file, id) {
8
- if (!file || !id) return undefined
9
- try {
10
- const parsed = JSON.parse(readFileSync(file, 'utf8'))
11
- const record = parsed?.version === 3 ? parsed.checkpoints?.[id] : undefined
12
- if (!record || record.version !== 3 || !Array.isArray(record.nativeOutput)) return undefined
13
- return structuredClone(record)
14
- } catch { return undefined }
15
- }
16
- export function legacyRouteCompatible(record, route, ctx) {
17
- if (!record || record.provider !== route.provider || record.model !== route.model) return false
18
- if (record.baseURLFingerprint !== baseURLFingerprint(route.baseURL)) return false
19
- return sessionAncestry(ctx, route.sessionId).includes(record.sourceSessionId ?? record.lineageId)
20
- }
@@ -1,68 +0,0 @@
1
- import { mergeFeatureHeader } from './compact-v2.js'
2
- import { resolvePiResponsesModel } from './dsh-responses.js'
3
- import { buildResponsesBody } from './responses-request.js'
4
- import { streamResponsesRequest } from './responses-stream.js'
5
-
6
- /**
7
- * Backward-compatible body helper retained for protocol tests and downstream imports.
8
- * Production managed replay already carries the DSH system prompt in canonical input;
9
- * `system` remains only as a low-level compatibility field.
10
- */
11
- export function replayBody({ model, modelDescriptor, input, system, tools, promptCacheKey, promptCacheRetention, cacheRetention, reasoningEffort, temperature, maxTokens }) {
12
- const descriptor = modelDescriptor ?? resolvePiResponsesModel({
13
- route: { provider: 'lcx', model, baseURL: '' },
14
- model: { id: model, provider: 'lcx', baseUrl: '', api: 'openai-responses', reasoning: true, input: ['text'] },
15
- })
16
- const body = buildResponsesBody({
17
- model: descriptor,
18
- input,
19
- instructions: system,
20
- tools,
21
- promptCacheKey,
22
- promptCacheRetention,
23
- cacheRetention: cacheRetention ?? (promptCacheKey ? (promptCacheRetention ? 'long' : 'short') : 'none'),
24
- reasoningEffort,
25
- temperature,
26
- maxTokens,
27
- })
28
- // Opaque Native replay stays on the Remote V2 wire contract while sharing the standard builder.
29
- body.tool_choice = 'auto'
30
- body.parallel_tool_calls = true
31
- return body
32
- }
33
-
34
- /**
35
- * Compatibility wrapper: Native replay now uses the same builder/transport/parser as ordinary turns.
36
- */
37
- export async function* requestNativeReplay({ baseURL, provider, model, modelDescriptor, input, system, tools, promptCacheKey, promptCacheRetention, cacheRetention, reasoningEffort, temperature, maxTokens, grammarToolInputProperties, headers, signal, timeoutMs, maxAttempts = 1, maxResponseBytes }) {
38
- const descriptor = modelDescriptor ?? resolvePiResponsesModel({
39
- route: { provider, model, baseURL },
40
- model: { id: model, provider, baseUrl: baseURL, api: 'openai-responses', reasoning: true, input: ['text'] },
41
- })
42
- const body = replayBody({
43
- model,
44
- modelDescriptor: descriptor,
45
- input,
46
- system,
47
- tools,
48
- promptCacheKey,
49
- promptCacheRetention,
50
- cacheRetention,
51
- reasoningEffort,
52
- temperature,
53
- maxTokens,
54
- })
55
- yield* streamResponsesRequest({
56
- baseURL,
57
- provider,
58
- model,
59
- piModel: descriptor,
60
- body,
61
- grammarToolInputProperties,
62
- headers: mergeFeatureHeader(headers),
63
- signal,
64
- timeoutMs,
65
- maxAttempts,
66
- maxResponseBytes,
67
- })
68
- }
@@ -1,43 +0,0 @@
1
- import { readFileSync } from 'node:fs'
2
- import { homedir } from 'node:os'
3
- import { join } from 'node:path'
4
- import { randomUUID } from 'node:crypto'
5
- import { ALPHA_SCHEMA_FINGERPRINT, buildAlphaSearchBody, normalizeAlphaSearchArgs, parseAlphaSearchResponse, probeAlphaCapabilities } from '../lib/web-search-alpha.js'
6
- import { AlphaCapabilityStore, alphaCapabilityFingerprint } from '../lib/web-search-capability.js'
7
-
8
- const baseURL = String(process.env.LCX_BASE_URL ?? 'https://api.lcxbot.com/v1').replace(/\/+$/u, '')
9
- const model = String(process.env.LCX_MODEL ?? '').trim()
10
- const provider = String(process.env.LCX_PROVIDER ?? 'lcx').trim()
11
- const profile = String(process.env.LCX_ALPHA_PROFILE ?? '')
12
- const group = String(process.env.LCX_ALPHA_GROUP ?? '')
13
- const keyFile = String(process.env.LCX_API_KEY_FILE ?? '').trim()
14
- if (!model) throw new Error('Set LCX_MODEL to the exact GPT model id')
15
- if (!keyFile) throw new Error('Set LCX_API_KEY_FILE to a local file containing the bearer key')
16
- const apiKey = readFileSync(keyFile, 'utf8').trim()
17
- if (!apiKey) throw new Error('LCX_API_KEY_FILE is empty')
18
- const storeFile = process.env.LCX_ALPHA_CAPABILITY_PATH ?? join(process.env.DSH_HOME ?? join(homedir(), '.dsh'), 'storages', 'lcx-codex', 'web-alpha-capabilities.json')
19
- const sessionId = `lcx-probe-${randomUUID()}`
20
-
21
- async function invoke(rawArgs) {
22
- const args = normalizeAlphaSearchArgs(rawArgs)
23
- const requestId = randomUUID()
24
- const response = await fetch(`${baseURL}/alpha/search`, {
25
- method: 'POST',
26
- headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}`, 'x-client-request-id': requestId, 'session-id': sessionId },
27
- body: JSON.stringify(buildAlphaSearchBody(args, model, sessionId, true, 2500)),
28
- })
29
- const text = await response.text()
30
- let body
31
- try { body = text ? JSON.parse(text) : {} } catch { body = { output: text, results: [] } }
32
- if (!response.ok) { const e = new Error(body?.error?.message ?? body?.message ?? `HTTP ${response.status}`); e.status = response.status; throw e }
33
- return parseAlphaSearchResponse(body, { action: args.action, capability: 'command-capable', requestId })
34
- }
35
-
36
- const structured = process.env.LCX_ALPHA_PROBE_STRUCTURED === '1'
37
- const actionProbes = structured ? {
38
- image_query: { query: 'OpenAI logo' }, finance: { ticker: 'MSFT', assetType: 'equity', market: 'USA' }, weather: { location: 'San Francisco, CA' }, sports: { fn: 'standings', league: 'nba' }, time: { utcOffset: '+00:00' },
39
- } : {}
40
- const result = await probeAlphaCapabilities({ invoke, schemaFingerprint: ALPHA_SCHEMA_FINGERPRINT, trustedNativeProvenance: process.env.LCX_ALPHA_TRUST_NATIVE === '1', actionProbes, clickProbeRef: process.env.LCX_ALPHA_CLICK_PROBE_REF, screenshotProbeRef: process.env.LCX_ALPHA_SCREENSHOT_PROBE_REF })
41
- const fingerprint = alphaCapabilityFingerprint({ baseURL, provider, model, profile, group, schemaFingerprint: ALPHA_SCHEMA_FINGERPRINT })
42
- new AlphaCapabilityStore(storeFile).put(fingerprint, result)
43
- console.log(JSON.stringify({ fingerprint, storeFile, classification: result.classification, actions: result.actions, probedAt: result.probedAt, provenance: result.provenance }, null, 2))
@@ -1,31 +0,0 @@
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
- }