MCPcopy Create free account
hub / github.com/ChatLab/ChatLab / downloadDict

Function downloadDict

packages/node-runtime/src/nlp/dict-manager.ts:60–135  ·  view source on GitHub ↗
(
  nlpDir: string,
  dictId: string,
  onProgress?: (percent: number) => void
)

Source from the content-addressed store, hash-verified

58}
59
60export async function downloadDict(
61 nlpDir: string,
62 dictId: string,
63 onProgress?: (percent: number) => void
64): Promise<{ success: boolean; error?: string }> {
65 if (!AVAILABLE_DICTS.find((d) => d.id === dictId)) {
66 return { success: false, error: `Unknown dict: ${dictId}` }
67 }
68
69 fs.mkdirSync(nlpDir, { recursive: true })
70 const url = `${DICT_DOWNLOAD_URL_BASE}/${dictId}.dict`
71 const filePath = getDictFilePath(nlpDir, dictId)
72 const tmpPath = filePath + '.tmp'
73
74 try {
75 const response = await fetch(url, { signal: AbortSignal.timeout(120_000) })
76 if (!response.ok) throw new Error(`Download failed: HTTP ${response.status}`)
77
78 const total = Number(response.headers.get('content-length') || 0)
79 let buffer: Buffer
80
81 if (!response.body) {
82 buffer = Buffer.from(await response.arrayBuffer())
83 } else {
84 const reader = response.body.getReader()
85 const chunks: Buffer[] = []
86 let loaded = 0
87 while (true) {
88 const { done, value } = await reader.read()
89 if (done) break
90 const chunk = Buffer.from(value)
91 chunks.push(chunk)
92 loaded += chunk.length
93 if (total > 0 && onProgress) onProgress(Math.round((loaded / total) * 100))
94 }
95 buffer = Buffer.concat(chunks)
96 }
97
98 const MIN_DICT_SIZE = 1_000_000
99 if (buffer.length < MIN_DICT_SIZE) {
100 return { success: false, error: `Downloaded file is invalid (${buffer.length} bytes)` }
101 }
102 const head = buffer.subarray(0, 50).toString('utf-8').trim()
103 if (head.startsWith('<!') || head.startsWith('<html')) {
104 return { success: false, error: 'Downloaded file is HTML, not a dictionary file' }
105 }
106
107 const expectedSha256 = DICT_SHA256[dictId]
108 if (!expectedSha256) {
109 return { success: false, error: `Missing SHA256 checksum for dict: ${dictId}` }
110 }
111 const actualSha256 = createHash('sha256').update(buffer).digest('hex')
112 if (actualSha256 !== expectedSha256) {
113 return { success: false, error: 'Dictionary integrity check failed (SHA256 mismatch)' }
114 }
115
116 fs.writeFileSync(tmpPath, buffer)
117 if (fs.existsSync(filePath)) fs.unlinkSync(filePath)

Callers 2

registerNlpRoutesFunction · 0.90
ensureDefaultDictFunction · 0.70

Calls 6

clearJiebaInstanceFunction · 0.90
getDictFilePathFunction · 0.85
getMethod · 0.65
updateMethod · 0.65
errorMethod · 0.65
onProgressFunction · 0.50

Tested by

no test coverage detected