claude-brain 0.30.2 → 0.30.3
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/README.md +241 -191
- package/VERSION +1 -1
- package/assets/CLAUDE-unified.md +11 -11
- package/assets/CLAUDE.md +29 -29
- package/package.json +7 -3
- package/packs/backend/node.json +173 -173
- package/packs/core/javascript.json +176 -176
- package/packs/core/typescript.json +222 -222
- package/packs/frontend/react.json +254 -254
- package/packs/meta/testing.json +172 -172
- package/scripts/postinstall.mjs +531 -531
- package/src/automation/decision-detector.ts +452 -452
- package/src/automation/phase12-manager.ts +456 -456
- package/src/automation/proactive-recall.ts +373 -373
- package/src/automation/project-detector.ts +310 -310
- package/src/automation/repo-scanner.ts +210 -205
- package/src/cli/auto-setup.ts +75 -75
- package/src/cli/auto-start.ts +266 -266
- package/src/cli/bin.ts +264 -264
- package/src/cli/commands/autostart.ts +90 -90
- package/src/cli/commands/chroma.ts +578 -577
- package/src/cli/commands/export-training.ts +70 -70
- package/src/cli/commands/export.ts +130 -130
- package/src/cli/commands/git-hook.ts +183 -183
- package/src/cli/commands/hooks.ts +217 -217
- package/src/cli/commands/init.ts +123 -123
- package/src/cli/commands/install-mcp.ts +122 -111
- package/src/cli/commands/models.ts +979 -979
- package/src/cli/commands/pack.ts +200 -200
- package/src/cli/commands/refresh.ts +344 -339
- package/src/cli/commands/reindex.ts +120 -120
- package/src/cli/commands/serve.ts +466 -463
- package/src/cli/commands/start.ts +44 -44
- package/src/cli/commands/status.ts +220 -203
- package/src/cli/commands/uninstall-mcp.ts +45 -41
- package/src/cli/commands/update.ts +130 -124
- package/src/cli/migrate-chroma.ts +106 -106
- package/src/cli/ui/animations.ts +80 -80
- package/src/cli/ui/components.ts +82 -82
- package/src/cli/ui/index.ts +4 -4
- package/src/cli/ui/logo.ts +36 -36
- package/src/cli/ui/theme.ts +55 -55
- package/src/code-intelligence/indexer.ts +352 -352
- package/src/code-intelligence/linker.ts +178 -178
- package/src/code-intelligence/parser.ts +484 -484
- package/src/code-intelligence/query.ts +291 -291
- package/src/code-intelligence/schema.ts +83 -83
- package/src/code-intelligence/types.ts +95 -95
- package/src/config/defaults.ts +52 -52
- package/src/config/home.ts +56 -56
- package/src/config/index.ts +5 -5
- package/src/config/loader.ts +192 -192
- package/src/config/schema.ts +446 -415
- package/src/config/validator.ts +182 -182
- package/src/context/assembler.ts +407 -400
- package/src/context/index.ts +79 -79
- package/src/context/progress-tracker.ts +174 -174
- package/src/context/standards-manager.ts +287 -287
- package/src/context/validator.ts +58 -58
- package/src/diagnostics/index.ts +122 -121
- package/src/health/index.ts +233 -232
- package/src/hooks/brain-hook.ts +134 -131
- package/src/hooks/capture.ts +168 -168
- package/src/hooks/claude-code-mastery.md +112 -112
- package/src/hooks/context-hook.ts +260 -245
- package/src/hooks/deduplicator.ts +72 -72
- package/src/hooks/git-capture.ts +109 -109
- package/src/hooks/git-hook-installer.ts +211 -207
- package/src/hooks/index.ts +20 -20
- package/src/hooks/installer.ts +306 -288
- package/src/hooks/interceptor-hook.ts +204 -201
- package/src/hooks/passive-classifier.ts +397 -397
- package/src/hooks/queue.ts +160 -129
- package/src/hooks/session-tracker.ts +312 -312
- package/src/hooks/types.ts +52 -52
- package/src/index.ts +7 -7
- package/src/intelligence/cross-project/generalizer.ts +283 -283
- package/src/intelligence/cross-project/index.ts +7 -7
- package/src/intelligence/hf-downloader.ts +222 -222
- package/src/intelligence/hf-manifest.json +78 -78
- package/src/intelligence/index.ts +24 -24
- package/src/intelligence/inference-router.ts +762 -762
- package/src/intelligence/model-manager.ts +263 -245
- package/src/intelligence/optimization/index.ts +10 -10
- package/src/intelligence/optimization/precompute.ts +202 -202
- package/src/intelligence/optimization/semantic-cache.ts +213 -207
- package/src/intelligence/prediction/index.ts +7 -7
- package/src/intelligence/prediction/recommender.ts +276 -268
- package/src/intelligence/reasoning/chain-retrieval.ts +243 -247
- package/src/intelligence/reasoning/index.ts +7 -7
- package/src/intelligence/temporal/evolution.ts +193 -197
- package/src/intelligence/temporal/index.ts +16 -16
- package/src/intelligence/temporal/query-processor.ts +190 -190
- package/src/intelligence/temporal/timeline.ts +272 -259
- package/src/intelligence/temporal/trends.ts +263 -263
- package/src/intelligence/tokenizer.ts +118 -118
- package/src/knowledge/entity-extractor.ts +447 -443
- package/src/knowledge/graph/builder.ts +185 -185
- package/src/knowledge/graph/linker.ts +201 -201
- package/src/knowledge/graph/memory-graph.ts +359 -359
- package/src/knowledge/graph/schema.ts +99 -99
- package/src/knowledge/graph/search.ts +166 -166
- package/src/knowledge/relationship-extractor.ts +108 -108
- package/src/memory/chroma/client.ts +211 -192
- package/src/memory/chroma/collection-manager.ts +92 -92
- package/src/memory/chroma/config.ts +57 -57
- package/src/memory/chroma/embeddings.ts +177 -175
- package/src/memory/chroma/index.ts +82 -82
- package/src/memory/chroma/migration.ts +270 -270
- package/src/memory/chroma/schemas.ts +69 -69
- package/src/memory/chroma/search.ts +319 -315
- package/src/memory/chroma/store.ts +755 -747
- package/src/memory/compression.ts +121 -121
- package/src/memory/consolidation/archiver.ts +162 -165
- package/src/memory/consolidation/merger.ts +182 -186
- package/src/memory/consolidation/scorer.ts +136 -136
- package/src/memory/database.ts +9 -0
- package/src/memory/dual-write.ts +145 -0
- package/src/memory/embeddings.ts +226 -226
- package/src/memory/episodic/detector.ts +108 -108
- package/src/memory/episodic/manager.ts +347 -351
- package/src/memory/episodic/summarizer.ts +179 -179
- package/src/memory/episodic/types.ts +52 -52
- package/src/memory/fts5-search.ts +692 -633
- package/src/memory/index.ts +943 -1060
- package/src/memory/migrations/add-fts5.ts +118 -108
- package/src/memory/patterns.ts +438 -438
- package/src/memory/pruning.ts +60 -60
- package/src/memory/schema.ts +88 -88
- package/src/memory/store.ts +911 -787
- package/src/orchestrator/handlers/decision-handler.ts +204 -204
- package/src/packs/index.ts +9 -9
- package/src/packs/loader.ts +134 -134
- package/src/packs/manager.ts +204 -204
- package/src/packs/ranker.ts +78 -78
- package/src/packs/types.ts +81 -81
- package/src/phase12/index.ts +5 -5
- package/src/retrieval/bm25/index.ts +300 -297
- package/src/retrieval/bm25/tokenizer.ts +184 -184
- package/src/retrieval/feedback/adaptive.ts +221 -221
- package/src/retrieval/feedback/index.ts +16 -16
- package/src/retrieval/feedback/metrics.ts +221 -221
- package/src/retrieval/feedback/store.ts +283 -283
- package/src/retrieval/fusion/index.ts +194 -194
- package/src/retrieval/fusion/rrf.ts +165 -165
- package/src/retrieval/index.ts +12 -12
- package/src/retrieval/pipeline.ts +375 -375
- package/src/retrieval/query/expander.ts +203 -203
- package/src/retrieval/query/index.ts +27 -27
- package/src/retrieval/query/intent-classifier.ts +252 -252
- package/src/retrieval/query/temporal-parser.ts +295 -295
- package/src/retrieval/reranker/index.ts +189 -188
- package/src/retrieval/reranker/model.ts +99 -95
- package/src/retrieval/service.ts +125 -125
- package/src/retrieval/types.ts +162 -162
- package/src/routing/entity-extractor.ts +454 -454
- package/src/routing/handlers/exploration-handler.ts +369 -0
- package/src/routing/handlers/index.ts +19 -0
- package/src/routing/handlers/memory-handler.ts +273 -0
- package/src/routing/handlers/mutation-handler.ts +241 -0
- package/src/routing/handlers/recall-handler.ts +642 -0
- package/src/routing/handlers/shared.ts +515 -0
- package/src/routing/handlers/types.ts +48 -0
- package/src/routing/intent-classifier.ts +552 -552
- package/src/routing/response-filter.ts +399 -391
- package/src/routing/router.ts +245 -2193
- package/src/routing/search-engine.ts +521 -514
- package/src/routing/types.ts +104 -94
- package/src/scripts/health-check.ts +118 -118
- package/src/scripts/setup.ts +122 -122
- package/src/server/auto-updater.ts +283 -276
- package/src/server/handlers/call-tool.ts +159 -159
- package/src/server/handlers/list-tools.ts +35 -35
- package/src/server/handlers/tools/auto-remember.ts +165 -165
- package/src/server/handlers/tools/brain.ts +86 -86
- package/src/server/handlers/tools/create-project.ts +135 -135
- package/src/server/handlers/tools/get-code-standards.ts +123 -123
- package/src/server/handlers/tools/get-corrections.ts +152 -152
- package/src/server/handlers/tools/get-patterns.ts +156 -156
- package/src/server/handlers/tools/get-project-context.ts +75 -75
- package/src/server/handlers/tools/index.ts +30 -30
- package/src/server/handlers/tools/init-project.ts +756 -756
- package/src/server/handlers/tools/list-projects.ts +126 -126
- package/src/server/handlers/tools/recall-similar.ts +87 -87
- package/src/server/handlers/tools/recognize-pattern.ts +132 -132
- package/src/server/handlers/tools/record-correction.ts +131 -131
- package/src/server/handlers/tools/remember-decision.ts +168 -168
- package/src/server/handlers/tools/schemas.ts +179 -179
- package/src/server/handlers/tools/search-code.ts +122 -122
- package/src/server/handlers/tools/smart-context.ts +146 -146
- package/src/server/handlers/tools/update-progress.ts +131 -131
- package/src/server/http-api.ts +215 -1229
- package/src/server/mcp-proxy.ts +85 -84
- package/src/server/mcp-server.ts +285 -284
- package/src/server/middleware/auth.ts +39 -0
- package/src/server/middleware/error-handler.ts +37 -0
- package/src/server/middleware/rate-limit.ts +53 -0
- package/src/server/middleware/validate.ts +42 -0
- package/src/server/pid-manager.ts +137 -136
- package/src/server/providers/resources.ts +581 -581
- package/src/server/routes/code.ts +228 -0
- package/src/server/routes/context.ts +26 -0
- package/src/server/routes/health.ts +19 -0
- package/src/server/routes/helpers.ts +100 -0
- package/src/server/routes/hooks.ts +197 -0
- package/src/server/routes/mcp.ts +47 -0
- package/src/server/routes/memory.ts +397 -0
- package/src/server/routes/models.ts +96 -0
- package/src/server/routes/projects.ts +89 -0
- package/src/server/routes/types.ts +21 -0
- package/src/server/schemas/api-schemas.ts +202 -0
- package/src/server/services.ts +720 -720
- package/src/server/utils/memory-indicator.ts +84 -84
- package/src/server/utils/response-formatter.ts +129 -129
- package/src/server/web-viewer.ts +1145 -1115
- package/src/setup/index.ts +38 -38
- package/src/tools/registry.ts +115 -115
- package/src/tools/schemas.ts +666 -666
- package/src/tools/types.ts +412 -412
- package/src/training/data-store.ts +320 -298
- package/src/training/retrain-pipeline.ts +399 -394
- package/src/utils/error-handler.ts +136 -136
- package/src/utils/index.ts +58 -58
- package/src/utils/kill-port.ts +55 -53
- package/src/utils/phase12-helper.ts +56 -56
- package/src/utils/safe-path.ts +43 -0
- package/src/utils/timing.ts +47 -47
- package/src/utils/transaction.ts +63 -63
- package/src/vault/index.ts +4 -3
- package/src/vault/paths.ts +106 -106
- package/src/vault/query.ts +4 -1
- package/src/vault/reader.ts +44 -1
- package/src/vault/watcher.ts +24 -1
- package/src/vault/writer.ts +487 -413
- package/skills/persistent-memory/SKILL.md +0 -148
- package/skills/persistent-memory/references/tool-reference.md +0 -90
|
@@ -1,222 +1,222 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hugging Face Hub Downloader — streams ONNX models from HF with SHA256 verification.
|
|
3
|
-
* Atomic writes via temp file + rename. Inline retry with exponential backoff.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { createHash } from 'node:crypto'
|
|
7
|
-
import { existsSync, mkdirSync, renameSync, unlinkSync } from 'node:fs'
|
|
8
|
-
import { join } from 'node:path'
|
|
9
|
-
import type { ModelTask } from '@/intelligence/model-manager'
|
|
10
|
-
|
|
11
|
-
export interface HfManifestEntry {
|
|
12
|
-
file: string
|
|
13
|
-
metaFile: string
|
|
14
|
-
sha256: string
|
|
15
|
-
metaSha256: string
|
|
16
|
-
size: number
|
|
17
|
-
version: string
|
|
18
|
-
params: string
|
|
19
|
-
accuracy: number | null
|
|
20
|
-
labels: string[]
|
|
21
|
-
maxSeqLen: number
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface HfManifest {
|
|
25
|
-
hfRepo: string
|
|
26
|
-
hfBranch: string
|
|
27
|
-
models: Record<string, HfManifestEntry>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface DownloadOptions {
|
|
31
|
-
/** Target directory to write models into */
|
|
32
|
-
destDir: string
|
|
33
|
-
/** Tasks to download (subset of manifest keys) */
|
|
34
|
-
tasks: ModelTask[]
|
|
35
|
-
/** HF repo override (default from manifest) */
|
|
36
|
-
hfRepo?: string
|
|
37
|
-
/** HF branch override (default from manifest) */
|
|
38
|
-
hfBranch?: string
|
|
39
|
-
/** Progress callback: task name, bytes downloaded so far, total bytes */
|
|
40
|
-
onProgress?: (task: string, downloaded: number, total: number) => void
|
|
41
|
-
/** Called when a task completes */
|
|
42
|
-
onComplete?: (task: string, bytes: number) => void
|
|
43
|
-
/** Called on error */
|
|
44
|
-
onError?: (task: string, error: string) => void
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface DownloadResult {
|
|
48
|
-
task: string
|
|
49
|
-
success: boolean
|
|
50
|
-
bytes: number
|
|
51
|
-
error?: string
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const MAX_RETRIES = 3
|
|
55
|
-
const RETRY_DELAYS = [2000, 4000, 8000]
|
|
56
|
-
const DOWNLOAD_TIMEOUT_MS = 300_000 // 5 minutes per file
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Build HF resolve URL for a file.
|
|
60
|
-
* Pattern: https://huggingface.co/{repo}/resolve/{branch}/{filename}
|
|
61
|
-
*/
|
|
62
|
-
function hfUrl(repo: string, branch: string, filename: string): string {
|
|
63
|
-
return `https://huggingface.co/${repo}/resolve/${branch}/${filename}`
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Stream-download a single file with SHA256 verification and atomic write.
|
|
68
|
-
* Returns the number of bytes written.
|
|
69
|
-
*/
|
|
70
|
-
async function downloadFile(
|
|
71
|
-
url: string,
|
|
72
|
-
destPath: string,
|
|
73
|
-
expectedSha256: string,
|
|
74
|
-
expectedSize: number,
|
|
75
|
-
onProgress?: (downloaded: number, total: number) => void,
|
|
76
|
-
): Promise<number> {
|
|
77
|
-
const tempPath = `${destPath}.download`
|
|
78
|
-
|
|
79
|
-
// Clean up any leftover temp file
|
|
80
|
-
if (existsSync(tempPath)) {
|
|
81
|
-
unlinkSync(tempPath)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const response = await fetch(url, {
|
|
85
|
-
signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS),
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
if (!response.ok) {
|
|
89
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (!response.body) {
|
|
93
|
-
throw new Error('Response body is null')
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const contentLength = parseInt(response.headers.get('content-length') || '0', 10) || expectedSize
|
|
97
|
-
const hash = createHash('sha256')
|
|
98
|
-
const writer = Bun.file(tempPath).writer()
|
|
99
|
-
let downloaded = 0
|
|
100
|
-
|
|
101
|
-
const reader = response.body.getReader()
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
while (true) {
|
|
105
|
-
const { done, value } = await reader.read()
|
|
106
|
-
if (done) break
|
|
107
|
-
|
|
108
|
-
writer.write(value)
|
|
109
|
-
hash.update(value)
|
|
110
|
-
downloaded += value.byteLength
|
|
111
|
-
|
|
112
|
-
if (onProgress) {
|
|
113
|
-
onProgress(downloaded, contentLength)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
} finally {
|
|
117
|
-
await writer.end()
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Verify SHA256
|
|
121
|
-
const actualSha256 = hash.digest('hex')
|
|
122
|
-
if (actualSha256 !== expectedSha256) {
|
|
123
|
-
// Clean up bad file
|
|
124
|
-
if (existsSync(tempPath)) unlinkSync(tempPath)
|
|
125
|
-
throw new Error(
|
|
126
|
-
`SHA256 mismatch: expected ${expectedSha256.slice(0, 12)}..., got ${actualSha256.slice(0, 12)}...`
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Atomic rename
|
|
131
|
-
renameSync(tempPath, destPath)
|
|
132
|
-
return downloaded
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Download a single file with retry logic.
|
|
137
|
-
*/
|
|
138
|
-
async function downloadWithRetry(
|
|
139
|
-
url: string,
|
|
140
|
-
destPath: string,
|
|
141
|
-
expectedSha256: string,
|
|
142
|
-
expectedSize: number,
|
|
143
|
-
onProgress?: (downloaded: number, total: number) => void,
|
|
144
|
-
): Promise<number> {
|
|
145
|
-
let lastError: Error | null = null
|
|
146
|
-
|
|
147
|
-
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
148
|
-
try {
|
|
149
|
-
return await downloadFile(url, destPath, expectedSha256, expectedSize, onProgress)
|
|
150
|
-
} catch (err) {
|
|
151
|
-
lastError = err instanceof Error ? err : new Error(String(err))
|
|
152
|
-
|
|
153
|
-
// Clean up temp file on failure
|
|
154
|
-
const tempPath = `${destPath}.download`
|
|
155
|
-
if (existsSync(tempPath)) {
|
|
156
|
-
try { unlinkSync(tempPath) } catch { /* ignore */ }
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (attempt < MAX_RETRIES) {
|
|
160
|
-
await new Promise(resolve => setTimeout(resolve, RETRY_DELAYS[attempt]))
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
throw lastError!
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Main entry point: download models from Hugging Face Hub.
|
|
170
|
-
*/
|
|
171
|
-
export async function downloadFromHuggingFace(
|
|
172
|
-
manifest: HfManifest,
|
|
173
|
-
options: DownloadOptions,
|
|
174
|
-
): Promise<DownloadResult[]> {
|
|
175
|
-
const repo = options.hfRepo || manifest.hfRepo
|
|
176
|
-
const branch = options.hfBranch || manifest.hfBranch
|
|
177
|
-
const results: DownloadResult[] = []
|
|
178
|
-
|
|
179
|
-
// Ensure dest directory exists
|
|
180
|
-
if (!existsSync(options.destDir)) {
|
|
181
|
-
mkdirSync(options.destDir, { recursive: true })
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
for (const task of options.tasks) {
|
|
185
|
-
const entry = manifest.models[task]
|
|
186
|
-
if (!entry) {
|
|
187
|
-
const err = `No manifest entry for task "${task}"`
|
|
188
|
-
options.onError?.(task, err)
|
|
189
|
-
results.push({ task, success: false, bytes: 0, error: err })
|
|
190
|
-
continue
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
try {
|
|
194
|
-
// Download ONNX model
|
|
195
|
-
const modelUrl = hfUrl(repo, branch, entry.file)
|
|
196
|
-
const modelDest = join(options.destDir, entry.file)
|
|
197
|
-
|
|
198
|
-
const bytes = await downloadWithRetry(
|
|
199
|
-
modelUrl,
|
|
200
|
-
modelDest,
|
|
201
|
-
entry.sha256,
|
|
202
|
-
entry.size,
|
|
203
|
-
(downloaded, total) => options.onProgress?.(task, downloaded, total),
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
// Download metadata JSON
|
|
207
|
-
const metaUrl = hfUrl(repo, branch, entry.metaFile)
|
|
208
|
-
const metaDest = join(options.destDir, entry.metaFile)
|
|
209
|
-
|
|
210
|
-
await downloadWithRetry(metaUrl, metaDest, entry.metaSha256, 0)
|
|
211
|
-
|
|
212
|
-
options.onComplete?.(task, bytes)
|
|
213
|
-
results.push({ task, success: true, bytes })
|
|
214
|
-
} catch (err) {
|
|
215
|
-
const msg = err instanceof Error ? err.message : String(err)
|
|
216
|
-
options.onError?.(task, msg)
|
|
217
|
-
results.push({ task, success: false, bytes: 0, error: msg })
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return results
|
|
222
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Hugging Face Hub Downloader — streams ONNX models from HF with SHA256 verification.
|
|
3
|
+
* Atomic writes via temp file + rename. Inline retry with exponential backoff.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { createHash } from 'node:crypto'
|
|
7
|
+
import { existsSync, mkdirSync, renameSync, unlinkSync } from 'node:fs'
|
|
8
|
+
import { join } from 'node:path'
|
|
9
|
+
import type { ModelTask } from '@/intelligence/model-manager'
|
|
10
|
+
|
|
11
|
+
export interface HfManifestEntry {
|
|
12
|
+
file: string
|
|
13
|
+
metaFile: string
|
|
14
|
+
sha256: string
|
|
15
|
+
metaSha256: string
|
|
16
|
+
size: number
|
|
17
|
+
version: string
|
|
18
|
+
params: string
|
|
19
|
+
accuracy: number | null
|
|
20
|
+
labels: string[]
|
|
21
|
+
maxSeqLen: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface HfManifest {
|
|
25
|
+
hfRepo: string
|
|
26
|
+
hfBranch: string
|
|
27
|
+
models: Record<string, HfManifestEntry>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface DownloadOptions {
|
|
31
|
+
/** Target directory to write models into */
|
|
32
|
+
destDir: string
|
|
33
|
+
/** Tasks to download (subset of manifest keys) */
|
|
34
|
+
tasks: ModelTask[]
|
|
35
|
+
/** HF repo override (default from manifest) */
|
|
36
|
+
hfRepo?: string
|
|
37
|
+
/** HF branch override (default from manifest) */
|
|
38
|
+
hfBranch?: string
|
|
39
|
+
/** Progress callback: task name, bytes downloaded so far, total bytes */
|
|
40
|
+
onProgress?: (task: string, downloaded: number, total: number) => void
|
|
41
|
+
/** Called when a task completes */
|
|
42
|
+
onComplete?: (task: string, bytes: number) => void
|
|
43
|
+
/** Called on error */
|
|
44
|
+
onError?: (task: string, error: string) => void
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface DownloadResult {
|
|
48
|
+
task: string
|
|
49
|
+
success: boolean
|
|
50
|
+
bytes: number
|
|
51
|
+
error?: string
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const MAX_RETRIES = 3
|
|
55
|
+
const RETRY_DELAYS = [2000, 4000, 8000]
|
|
56
|
+
const DOWNLOAD_TIMEOUT_MS = 300_000 // 5 minutes per file
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Build HF resolve URL for a file.
|
|
60
|
+
* Pattern: https://huggingface.co/{repo}/resolve/{branch}/{filename}
|
|
61
|
+
*/
|
|
62
|
+
function hfUrl(repo: string, branch: string, filename: string): string {
|
|
63
|
+
return `https://huggingface.co/${repo}/resolve/${branch}/${filename}`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Stream-download a single file with SHA256 verification and atomic write.
|
|
68
|
+
* Returns the number of bytes written.
|
|
69
|
+
*/
|
|
70
|
+
async function downloadFile(
|
|
71
|
+
url: string,
|
|
72
|
+
destPath: string,
|
|
73
|
+
expectedSha256: string,
|
|
74
|
+
expectedSize: number,
|
|
75
|
+
onProgress?: (downloaded: number, total: number) => void,
|
|
76
|
+
): Promise<number> {
|
|
77
|
+
const tempPath = `${destPath}.download`
|
|
78
|
+
|
|
79
|
+
// Clean up any leftover temp file
|
|
80
|
+
if (existsSync(tempPath)) {
|
|
81
|
+
unlinkSync(tempPath)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const response = await fetch(url, {
|
|
85
|
+
signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS),
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!response.body) {
|
|
93
|
+
throw new Error('Response body is null')
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const contentLength = parseInt(response.headers.get('content-length') || '0', 10) || expectedSize
|
|
97
|
+
const hash = createHash('sha256')
|
|
98
|
+
const writer = Bun.file(tempPath).writer()
|
|
99
|
+
let downloaded = 0
|
|
100
|
+
|
|
101
|
+
const reader = response.body.getReader()
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
while (true) {
|
|
105
|
+
const { done, value } = await reader.read()
|
|
106
|
+
if (done) break
|
|
107
|
+
|
|
108
|
+
writer.write(value)
|
|
109
|
+
hash.update(value)
|
|
110
|
+
downloaded += value.byteLength
|
|
111
|
+
|
|
112
|
+
if (onProgress) {
|
|
113
|
+
onProgress(downloaded, contentLength)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} finally {
|
|
117
|
+
await writer.end()
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Verify SHA256
|
|
121
|
+
const actualSha256 = hash.digest('hex')
|
|
122
|
+
if (actualSha256 !== expectedSha256) {
|
|
123
|
+
// Clean up bad file
|
|
124
|
+
if (existsSync(tempPath)) unlinkSync(tempPath)
|
|
125
|
+
throw new Error(
|
|
126
|
+
`SHA256 mismatch: expected ${expectedSha256.slice(0, 12)}..., got ${actualSha256.slice(0, 12)}...`
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Atomic rename
|
|
131
|
+
renameSync(tempPath, destPath)
|
|
132
|
+
return downloaded
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Download a single file with retry logic.
|
|
137
|
+
*/
|
|
138
|
+
async function downloadWithRetry(
|
|
139
|
+
url: string,
|
|
140
|
+
destPath: string,
|
|
141
|
+
expectedSha256: string,
|
|
142
|
+
expectedSize: number,
|
|
143
|
+
onProgress?: (downloaded: number, total: number) => void,
|
|
144
|
+
): Promise<number> {
|
|
145
|
+
let lastError: Error | null = null
|
|
146
|
+
|
|
147
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
148
|
+
try {
|
|
149
|
+
return await downloadFile(url, destPath, expectedSha256, expectedSize, onProgress)
|
|
150
|
+
} catch (err) {
|
|
151
|
+
lastError = err instanceof Error ? err : new Error(String(err))
|
|
152
|
+
|
|
153
|
+
// Clean up temp file on failure
|
|
154
|
+
const tempPath = `${destPath}.download`
|
|
155
|
+
if (existsSync(tempPath)) {
|
|
156
|
+
try { unlinkSync(tempPath) } catch { /* ignore */ }
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (attempt < MAX_RETRIES) {
|
|
160
|
+
await new Promise(resolve => setTimeout(resolve, RETRY_DELAYS[attempt]))
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
throw lastError!
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Main entry point: download models from Hugging Face Hub.
|
|
170
|
+
*/
|
|
171
|
+
export async function downloadFromHuggingFace(
|
|
172
|
+
manifest: HfManifest,
|
|
173
|
+
options: DownloadOptions,
|
|
174
|
+
): Promise<DownloadResult[]> {
|
|
175
|
+
const repo = options.hfRepo || manifest.hfRepo
|
|
176
|
+
const branch = options.hfBranch || manifest.hfBranch
|
|
177
|
+
const results: DownloadResult[] = []
|
|
178
|
+
|
|
179
|
+
// Ensure dest directory exists
|
|
180
|
+
if (!existsSync(options.destDir)) {
|
|
181
|
+
mkdirSync(options.destDir, { recursive: true })
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
for (const task of options.tasks) {
|
|
185
|
+
const entry = manifest.models[task]
|
|
186
|
+
if (!entry) {
|
|
187
|
+
const err = `No manifest entry for task "${task}"`
|
|
188
|
+
options.onError?.(task, err)
|
|
189
|
+
results.push({ task, success: false, bytes: 0, error: err })
|
|
190
|
+
continue
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
// Download ONNX model
|
|
195
|
+
const modelUrl = hfUrl(repo, branch, entry.file)
|
|
196
|
+
const modelDest = join(options.destDir, entry.file)
|
|
197
|
+
|
|
198
|
+
const bytes = await downloadWithRetry(
|
|
199
|
+
modelUrl,
|
|
200
|
+
modelDest,
|
|
201
|
+
entry.sha256,
|
|
202
|
+
entry.size,
|
|
203
|
+
(downloaded, total) => options.onProgress?.(task, downloaded, total),
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
// Download metadata JSON
|
|
207
|
+
const metaUrl = hfUrl(repo, branch, entry.metaFile)
|
|
208
|
+
const metaDest = join(options.destDir, entry.metaFile)
|
|
209
|
+
|
|
210
|
+
await downloadWithRetry(metaUrl, metaDest, entry.metaSha256, 0)
|
|
211
|
+
|
|
212
|
+
options.onComplete?.(task, bytes)
|
|
213
|
+
results.push({ task, success: true, bytes })
|
|
214
|
+
} catch (err) {
|
|
215
|
+
const msg = err instanceof Error ? err.message : String(err)
|
|
216
|
+
options.onError?.(task, msg)
|
|
217
|
+
results.push({ task, success: false, bytes: 0, error: msg })
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return results
|
|
222
|
+
}
|
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
{
|
|
2
|
-
"hfRepo": "demgun101/claude-brain-models",
|
|
3
|
-
"hfBranch": "main",
|
|
4
|
-
"models": {
|
|
5
|
-
"intent": {
|
|
6
|
-
"file": "intent.onnx",
|
|
7
|
-
"metaFile": "intent.json",
|
|
8
|
-
"sha256": "f276ec091712f53ceeccfdca70d468d0b5aa6da7ee5c4bd7867a7464a9732dd2",
|
|
9
|
-
"metaSha256": "d5702fd45e5685187e74810da75e41be9d12d9fd82b7ccd7244a9f0d33076c65",
|
|
10
|
-
"size": 120073283,
|
|
11
|
-
"version": "0.1.0",
|
|
12
|
-
"params": "nanoGPT-intent",
|
|
13
|
-
"accuracy": 0.9904,
|
|
14
|
-
"labels": ["session_start", "context_needed", "decision_made", "store_this", "pattern_found", "mistake_learned", "progress_update", "question", "comparison", "exploration", "list_all", "update_memory", "delete_memory", "detail_request", "timeline", "no_action"],
|
|
15
|
-
"maxSeqLen": 128
|
|
16
|
-
},
|
|
17
|
-
"entity": {
|
|
18
|
-
"file": "entity.onnx",
|
|
19
|
-
"metaFile": "entity.json",
|
|
20
|
-
"sha256": "d15706b78112e8dda3caa7e054237106b67200f90a1e6e0e4336526468dea8b5",
|
|
21
|
-
"metaSha256": "1de0636bc3bd9de23c0ce767a148d6becad7b6add6a0a717449a7ac185296d55",
|
|
22
|
-
"size": 120058476,
|
|
23
|
-
"version": "0.1.0",
|
|
24
|
-
"params": "nanoGPT-entity",
|
|
25
|
-
"accuracy": 0.9795,
|
|
26
|
-
"labels": ["O", "B-TECH", "I-TECH", "B-PROJECT", "I-PROJECT", "B-CONCEPT", "I-CONCEPT"],
|
|
27
|
-
"maxSeqLen": 128
|
|
28
|
-
},
|
|
29
|
-
"query": {
|
|
30
|
-
"file": "query.onnx",
|
|
31
|
-
"metaFile": "query.json",
|
|
32
|
-
"sha256": "802446105ad873b4a172dc875c07e245882f48691f72ae0abb0bda5934fa084a",
|
|
33
|
-
"metaSha256": "32393875ff58a87da83480673868e4ac14c3fd1a59e16836d7c1f2fa02a7f25e",
|
|
34
|
-
"size": 120057880,
|
|
35
|
-
"version": "0.1.0",
|
|
36
|
-
"params": "nanoGPT-query",
|
|
37
|
-
"accuracy": 0.985,
|
|
38
|
-
"labels": ["factual", "procedural", "comparative", "temporal", "exploratory", "decision"],
|
|
39
|
-
"maxSeqLen": 128
|
|
40
|
-
},
|
|
41
|
-
"knowledge": {
|
|
42
|
-
"file": "knowledge.onnx",
|
|
43
|
-
"metaFile": "knowledge.json",
|
|
44
|
-
"sha256": "a786eefc5ef5c6f2fc132c6de7f0972891057f5a993c9c2d9264207d36165035",
|
|
45
|
-
"metaSha256": "6aa77194cbd8c10a2451958ec5a3e43328df97ee8aea46abf53e3e432f3f3c4d",
|
|
46
|
-
"size": 120056340,
|
|
47
|
-
"version": "0.1.0",
|
|
48
|
-
"params": "nanoGPT-knowledge",
|
|
49
|
-
"accuracy": 0.998,
|
|
50
|
-
"labels": ["fact", "preference", "constraint", "goal", "definition"],
|
|
51
|
-
"maxSeqLen": 128
|
|
52
|
-
},
|
|
53
|
-
"compress": {
|
|
54
|
-
"file": "compress.onnx",
|
|
55
|
-
"metaFile": "compress.json",
|
|
56
|
-
"sha256": "2d950a0e0a2cdc5dc90b7c44803c5fb81c76d824bd208c64a7104c5845e1c237",
|
|
57
|
-
"metaSha256": "e91500c665ec47083bb6b3ff8c83d529f263792d83f7f169401267ceb1e8d031",
|
|
58
|
-
"size": 357902441,
|
|
59
|
-
"version": "0.1.0",
|
|
60
|
-
"params": "nanoGPT-compress",
|
|
61
|
-
"accuracy": null,
|
|
62
|
-
"labels": [],
|
|
63
|
-
"maxSeqLen": 256
|
|
64
|
-
},
|
|
65
|
-
"pattern": {
|
|
66
|
-
"file": "pattern.onnx",
|
|
67
|
-
"metaFile": "pattern.json",
|
|
68
|
-
"sha256": "3b44371eaef11fb8ccc4c1636d6cfbdcdf62ae8bc6ffc808ff0ff45b24824fde",
|
|
69
|
-
"metaSha256": "1126f3fa9a115b4d26063e006e7d33b9e82b7740194ac86b5dae9f25d5dfd1a2",
|
|
70
|
-
"size": 254526620,
|
|
71
|
-
"version": "0.1.0",
|
|
72
|
-
"params": "nanoGPT-pattern",
|
|
73
|
-
"accuracy": 0.8667,
|
|
74
|
-
"labels": ["solution", "anti-pattern", "best-practice", "common-issue"],
|
|
75
|
-
"maxSeqLen": 128
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"hfRepo": "demgun101/claude-brain-models",
|
|
3
|
+
"hfBranch": "main",
|
|
4
|
+
"models": {
|
|
5
|
+
"intent": {
|
|
6
|
+
"file": "intent.onnx",
|
|
7
|
+
"metaFile": "intent.json",
|
|
8
|
+
"sha256": "f276ec091712f53ceeccfdca70d468d0b5aa6da7ee5c4bd7867a7464a9732dd2",
|
|
9
|
+
"metaSha256": "d5702fd45e5685187e74810da75e41be9d12d9fd82b7ccd7244a9f0d33076c65",
|
|
10
|
+
"size": 120073283,
|
|
11
|
+
"version": "0.1.0",
|
|
12
|
+
"params": "nanoGPT-intent",
|
|
13
|
+
"accuracy": 0.9904,
|
|
14
|
+
"labels": ["session_start", "context_needed", "decision_made", "store_this", "pattern_found", "mistake_learned", "progress_update", "question", "comparison", "exploration", "list_all", "update_memory", "delete_memory", "detail_request", "timeline", "no_action"],
|
|
15
|
+
"maxSeqLen": 128
|
|
16
|
+
},
|
|
17
|
+
"entity": {
|
|
18
|
+
"file": "entity.onnx",
|
|
19
|
+
"metaFile": "entity.json",
|
|
20
|
+
"sha256": "d15706b78112e8dda3caa7e054237106b67200f90a1e6e0e4336526468dea8b5",
|
|
21
|
+
"metaSha256": "1de0636bc3bd9de23c0ce767a148d6becad7b6add6a0a717449a7ac185296d55",
|
|
22
|
+
"size": 120058476,
|
|
23
|
+
"version": "0.1.0",
|
|
24
|
+
"params": "nanoGPT-entity",
|
|
25
|
+
"accuracy": 0.9795,
|
|
26
|
+
"labels": ["O", "B-TECH", "I-TECH", "B-PROJECT", "I-PROJECT", "B-CONCEPT", "I-CONCEPT"],
|
|
27
|
+
"maxSeqLen": 128
|
|
28
|
+
},
|
|
29
|
+
"query": {
|
|
30
|
+
"file": "query.onnx",
|
|
31
|
+
"metaFile": "query.json",
|
|
32
|
+
"sha256": "802446105ad873b4a172dc875c07e245882f48691f72ae0abb0bda5934fa084a",
|
|
33
|
+
"metaSha256": "32393875ff58a87da83480673868e4ac14c3fd1a59e16836d7c1f2fa02a7f25e",
|
|
34
|
+
"size": 120057880,
|
|
35
|
+
"version": "0.1.0",
|
|
36
|
+
"params": "nanoGPT-query",
|
|
37
|
+
"accuracy": 0.985,
|
|
38
|
+
"labels": ["factual", "procedural", "comparative", "temporal", "exploratory", "decision"],
|
|
39
|
+
"maxSeqLen": 128
|
|
40
|
+
},
|
|
41
|
+
"knowledge": {
|
|
42
|
+
"file": "knowledge.onnx",
|
|
43
|
+
"metaFile": "knowledge.json",
|
|
44
|
+
"sha256": "a786eefc5ef5c6f2fc132c6de7f0972891057f5a993c9c2d9264207d36165035",
|
|
45
|
+
"metaSha256": "6aa77194cbd8c10a2451958ec5a3e43328df97ee8aea46abf53e3e432f3f3c4d",
|
|
46
|
+
"size": 120056340,
|
|
47
|
+
"version": "0.1.0",
|
|
48
|
+
"params": "nanoGPT-knowledge",
|
|
49
|
+
"accuracy": 0.998,
|
|
50
|
+
"labels": ["fact", "preference", "constraint", "goal", "definition"],
|
|
51
|
+
"maxSeqLen": 128
|
|
52
|
+
},
|
|
53
|
+
"compress": {
|
|
54
|
+
"file": "compress.onnx",
|
|
55
|
+
"metaFile": "compress.json",
|
|
56
|
+
"sha256": "2d950a0e0a2cdc5dc90b7c44803c5fb81c76d824bd208c64a7104c5845e1c237",
|
|
57
|
+
"metaSha256": "e91500c665ec47083bb6b3ff8c83d529f263792d83f7f169401267ceb1e8d031",
|
|
58
|
+
"size": 357902441,
|
|
59
|
+
"version": "0.1.0",
|
|
60
|
+
"params": "nanoGPT-compress",
|
|
61
|
+
"accuracy": null,
|
|
62
|
+
"labels": [],
|
|
63
|
+
"maxSeqLen": 256
|
|
64
|
+
},
|
|
65
|
+
"pattern": {
|
|
66
|
+
"file": "pattern.onnx",
|
|
67
|
+
"metaFile": "pattern.json",
|
|
68
|
+
"sha256": "3b44371eaef11fb8ccc4c1636d6cfbdcdf62ae8bc6ffc808ff0ff45b24824fde",
|
|
69
|
+
"metaSha256": "1126f3fa9a115b4d26063e006e7d33b9e82b7740194ac86b5dae9f25d5dfd1a2",
|
|
70
|
+
"size": 254526620,
|
|
71
|
+
"version": "0.1.0",
|
|
72
|
+
"params": "nanoGPT-pattern",
|
|
73
|
+
"accuracy": 0.8667,
|
|
74
|
+
"labels": ["solution", "anti-pattern", "best-practice", "common-issue"],
|
|
75
|
+
"maxSeqLen": 128
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Intelligence Module
|
|
3
|
-
* Phase 22: Consolidates advanced intelligence features under one namespace.
|
|
4
|
-
*
|
|
5
|
-
* Features are lazy-loaded to avoid startup cost when not needed.
|
|
6
|
-
* Gate on config.intelligence?.enabled for opt-in activation.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { Config } from '@/config'
|
|
10
|
-
|
|
11
|
-
export async function loadIntelligence(config: Config) {
|
|
12
|
-
if (!(config as
|
|
13
|
-
return {
|
|
14
|
-
prediction: await import('./prediction'),
|
|
15
|
-
reasoning: await import('./reasoning'),
|
|
16
|
-
temporal: await import('./temporal'),
|
|
17
|
-
optimization: await import('./optimization'),
|
|
18
|
-
crossProject: await import('./cross-project')
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Re-export submodule paths for direct imports
|
|
23
|
-
export * from './optimization/semantic-cache'
|
|
24
|
-
export * from './optimization/precompute'
|
|
1
|
+
/**
|
|
2
|
+
* Intelligence Module
|
|
3
|
+
* Phase 22: Consolidates advanced intelligence features under one namespace.
|
|
4
|
+
*
|
|
5
|
+
* Features are lazy-loaded to avoid startup cost when not needed.
|
|
6
|
+
* Gate on config.intelligence?.enabled for opt-in activation.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Config } from '@/config'
|
|
10
|
+
|
|
11
|
+
export async function loadIntelligence(config: Config) {
|
|
12
|
+
if (!(config as Record<string, unknown>).intelligence) return null
|
|
13
|
+
return {
|
|
14
|
+
prediction: await import('./prediction'),
|
|
15
|
+
reasoning: await import('./reasoning'),
|
|
16
|
+
temporal: await import('./temporal'),
|
|
17
|
+
optimization: await import('./optimization'),
|
|
18
|
+
crossProject: await import('./cross-project')
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Re-export submodule paths for direct imports
|
|
23
|
+
export * from './optimization/semantic-cache'
|
|
24
|
+
export * from './optimization/precompute'
|