kiku-agent 1.3.0 → 1.3.1
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 +7 -7
- package/package.json +6 -1
- package/server/agent/agentCore.js +2 -2
- package/server/agent/catalogEntityResolver.js +8 -0
- package/server/agent/cli.js +4 -0
- package/server/agent/ink/App.jsx +348 -0
- package/server/agent/ink/Panel.jsx +54 -0
- package/server/agent/ink/PromptInput.jsx +321 -0
- package/server/agent/ink/TaskPlanPanel.jsx +88 -0
- package/server/agent/ink/ThinkingPanel.jsx +68 -0
- package/server/agent/ink/ToolResult.jsx +133 -0
- package/server/agent/ink/main.jsx +195 -0
- package/server/agent/ink/useEventBus.js +218 -0
- package/server/agent/memory/contextAllocator.js +214 -0
- package/server/agent/memory/hierarchicalStore.js +523 -0
- package/server/agent/memory/reflectionWorker.js +110 -0
- package/server/agent/prompts.js +1 -1
- package/server/agent/telemetry/hardwareTiers.js +332 -0
- package/server/agent/telemetry/runtimeWatchdog.js +66 -0
- package/server/agent/telemetry/techPowerUpClient.js +682 -0
- package/server/agent/telemetry/techpowerup-mcp.json +22 -0
- package/server/agent/websearch/adapters/duckduckgo.js +97 -0
- package/server/agent/websearch/adapters/jina.js +77 -0
- package/server/agent/websearch/adapters/searxng.js +57 -0
- package/server/agent/websearch/core/canonical.js +89 -0
- package/server/agent/websearch/core/fusion.js +81 -0
- package/server/agent/websearch/core/types.js +29 -0
- package/server/agent/websearch/extract.js +605 -0
- package/server/agent/websearch/index.js +43 -0
- package/server/agent/websearch/orchestrator.js +266 -0
- package/server/agent/websearch/resilience/breaker.js +97 -0
- package/server/agent/websearch/resilience/cache.js +59 -0
- package/server/agent/websearch/resilience/limiter.js +93 -0
- package/server/agent/websearch/security/filter.js +36 -0
- package/server/agent/websearch/security/ssrf.js +289 -0
- package/server/agent/websearch/telemetry.js +71 -0
- package/server/apiRouter.js +7 -11
- package/server/routes/agent.js +55 -0
|
@@ -0,0 +1,682 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { KIKU_DATA_DIR } from '../appPaths.js';
|
|
5
|
+
import { mcpClientManager } from '../mcpClient.js';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
const TECHPOWERUP_MCP_CONFIG_PATH = path.join(__dirname, 'techpowerup-mcp.json');
|
|
11
|
+
|
|
12
|
+
let techPowerUpMcpConfigCache = null;
|
|
13
|
+
|
|
14
|
+
export async function loadTechPowerUpMcpConfig() {
|
|
15
|
+
if (techPowerUpMcpConfigCache) return techPowerUpMcpConfigCache;
|
|
16
|
+
try {
|
|
17
|
+
const content = await fs.readFile(TECHPOWERUP_MCP_CONFIG_PATH, 'utf8');
|
|
18
|
+
const parsed = JSON.parse(content);
|
|
19
|
+
if (parsed && typeof parsed === 'object') techPowerUpMcpConfigCache = parsed;
|
|
20
|
+
return parsed;
|
|
21
|
+
} catch {
|
|
22
|
+
return { mcpServers: {} };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const TECHPOWERUP_MCP_CONFIG = Object.freeze({
|
|
27
|
+
'techpowerup-gpu': {
|
|
28
|
+
type: 'http',
|
|
29
|
+
url: 'https://www.techpowerup.com/gpu-specs/api/mcp',
|
|
30
|
+
toolName: 'search_gpu_cards',
|
|
31
|
+
queryArg: 'query'
|
|
32
|
+
},
|
|
33
|
+
'techpowerup-cpu': {
|
|
34
|
+
type: 'http',
|
|
35
|
+
url: 'https://www.techpowerup.com/cpu-specs/api/mcp',
|
|
36
|
+
toolName: 'search_cpus',
|
|
37
|
+
queryArg: 'query'
|
|
38
|
+
},
|
|
39
|
+
'techpowerup-ssd': {
|
|
40
|
+
type: 'http',
|
|
41
|
+
url: 'https://www.techpowerup.com/ssd-specs/api/mcp',
|
|
42
|
+
toolName: 'search_ssds',
|
|
43
|
+
queryArg: 'query'
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export const HARDWARE_RESOLUTION_SOURCE = Object.freeze({
|
|
48
|
+
MCP_TECHPOWERUP_GPU: 'mcp:techpowerup-gpu',
|
|
49
|
+
MCP_TECHPOWERUP_CPU: 'mcp:techpowerup-cpu',
|
|
50
|
+
MCP_TECHPOWERUP_SSD: 'mcp:techpowerup-ssd',
|
|
51
|
+
KNOWN_DATABASE: 'known_database',
|
|
52
|
+
HEURISTIC_FALLBACK: 'heuristic_fallback'
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const MCP_RESOLUTION_ORDER = [
|
|
56
|
+
'techpowerup-gpu',
|
|
57
|
+
'techpowerup-cpu',
|
|
58
|
+
'techpowerup-ssd'
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
export const KNOWN_GPU_SPECS = [
|
|
63
|
+
|
|
64
|
+
{ match: /rtx 5090\b/i, name: 'GeForce RTX 5090 32GB', vramGb: 32, busBits: 512, bandwidthGbs: 1792.0, arch: 'Blackwell GB202', pcie: 'PCIe 5.0 x16', memoryType: 'GDDR7' },
|
|
65
|
+
{ match: /rtx 5080\b/i, name: 'GeForce RTX 5080 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 1024.0, arch: 'Blackwell GB203', pcie: 'PCIe 5.0 x16', memoryType: 'GDDR7' },
|
|
66
|
+
{ match: /rtx 5070 ti\b/i, name: 'GeForce RTX 5070 Ti 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 896.0, arch: 'Blackwell GB203', pcie: 'PCIe 5.0 x16', memoryType: 'GDDR7' },
|
|
67
|
+
{ match: /rtx 5070\b/i, name: 'GeForce RTX 5070 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 672.0, arch: 'Blackwell GB205', pcie: 'PCIe 5.0 x16', memoryType: 'GDDR7' },
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
{ match: /rtx 4090\b/i, name: 'GeForce RTX 4090 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 1008.0, arch: 'Ada AD102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
71
|
+
{ match: /rtx 4090\s*d\b/i, name: 'GeForce RTX 4090 D 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 1008.0, arch: 'Ada AD102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
72
|
+
{ match: /rtx 4080 super\b/i, name: 'GeForce RTX 4080 SUPER 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 736.0, arch: 'Ada AD103', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
73
|
+
{ match: /rtx 4080\b/i, name: 'GeForce RTX 4080 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 716.8, arch: 'Ada AD103', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
74
|
+
{ match: /rtx 4070 ti super\b/i, name: 'GeForce RTX 4070 Ti SUPER 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 672.3, arch: 'Ada AD103', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
75
|
+
{ match: /rtx 4070 ti\b/i, name: 'GeForce RTX 4070 Ti 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 504.2, arch: 'Ada AD104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
76
|
+
{ match: /rtx 4070 super\b/i, name: 'GeForce RTX 4070 SUPER 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 504.2, arch: 'Ada AD104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
77
|
+
{ match: /rtx 4070\b/i, name: 'GeForce RTX 4070 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 504.2, arch: 'Ada AD104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
78
|
+
{ match: /rtx 4060 ti\b/i, name: 'GeForce RTX 4060 Ti 16GB', vramGb: 16, busBits: 128, bandwidthGbs: 288.0, arch: 'Ada AD106', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
79
|
+
{ match: /rtx 4060 ti\b/i, name: 'GeForce RTX 4060 Ti 8GB', vramGb: 8, busBits: 128, bandwidthGbs: 288.0, arch: 'Ada AD106', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
80
|
+
{ match: /rtx 4060\b/i, name: 'GeForce RTX 4060 8GB', vramGb: 8, busBits: 128, bandwidthGbs: 272.0, arch: 'Ada AD107', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
81
|
+
{ match: /rtx 4050\b/i, name: 'GeForce RTX 4050 Laptop 6GB', vramGb: 6, busBits: 96, bandwidthGbs: 192.0, arch: 'Ada AD107', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
{ match: /rtx 3090 ti\b/i, name: 'GeForce RTX 3090 Ti 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 1008.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
85
|
+
{ match: /rtx 3090\b/i, name: 'GeForce RTX 3090 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 936.2, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
86
|
+
{ match: /rtx 3080 ti\b/i, name: 'GeForce RTX 3080 Ti 12GB', vramGb: 12, busBits: 384, bandwidthGbs: 912.4, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
87
|
+
{ match: /rtx 3080\b/i, name: 'GeForce RTX 3080 12GB', vramGb: 12, busBits: 384, bandwidthGbs: 912.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
88
|
+
{ match: /rtx 3080\b/i, name: 'GeForce RTX 3080 10GB', vramGb: 10, busBits: 320, bandwidthGbs: 760.3, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
89
|
+
{ match: /rtx 3070 ti\b/i, name: 'GeForce RTX 3070 Ti 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 608.3, arch: 'Ampere GA104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
90
|
+
{ match: /rtx 3070\b/i, name: 'GeForce RTX 3070 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 448.0, arch: 'Ampere GA104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
91
|
+
{ match: /rtx 3060 ti\b/i, name: 'GeForce RTX 3060 Ti 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 448.0, arch: 'Ampere GA104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
92
|
+
{ match: /rtx 3060.*(laptop|mobile)/i, name: 'GeForce RTX 3060 Laptop 6GB', vramGb: 6, busBits: 192, bandwidthGbs: 336.0, arch: 'Ampere GA106', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
93
|
+
{ match: /rtx 3060\b/i, name: 'GeForce RTX 3060 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 360.0, arch: 'Ampere GA106', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
94
|
+
{ match: /rtx 3060\b/i, name: 'GeForce RTX 3060 8GB', vramGb: 8, busBits: 128, bandwidthGbs: 240.0, arch: 'Ampere GA106', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
95
|
+
{ match: /rtx 3050\b/i, name: 'GeForce RTX 3050 8GB', vramGb: 8, busBits: 128, bandwidthGbs: 224.0, arch: 'Ampere GA106', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
96
|
+
{ match: /rtx 3050\b/i, name: 'GeForce RTX 3050 6GB', vramGb: 6, busBits: 96, bandwidthGbs: 168.0, arch: 'Ampere GA107', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
{ match: /titan rtx\b/i, name: 'NVIDIA TITAN RTX 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 672.0, arch: 'Turing TU102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
100
|
+
{ match: /rtx 2080 ti.*(22|mod)/i, name: 'GeForce RTX 2080 Ti 22GB (AI Mod)', vramGb: 22, busBits: 352, bandwidthGbs: 616.0, arch: 'Turing TU102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
101
|
+
{ match: /rtx 2080 ti\b/i, name: 'GeForce RTX 2080 Ti 22GB (AI Mod)', vramGb: 22, busBits: 352, bandwidthGbs: 616.0, arch: 'Turing TU102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
102
|
+
{ match: /rtx 2080 ti\b/i, name: 'GeForce RTX 2080 Ti 11GB', vramGb: 11, busBits: 352, bandwidthGbs: 616.0, arch: 'Turing TU102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
103
|
+
{ match: /rtx 2080 super\b/i, name: 'GeForce RTX 2080 SUPER 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 496.0, arch: 'Turing TU104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
104
|
+
{ match: /rtx 2080\b/i, name: 'GeForce RTX 2080 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 448.0, arch: 'Turing TU104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
105
|
+
{ match: /rtx 2070 super\b/i, name: 'GeForce RTX 2070 SUPER 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 448.0, arch: 'Turing TU104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
106
|
+
{ match: /rtx 2070\b/i, name: 'GeForce RTX 2070 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 448.0, arch: 'Turing TU106', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
107
|
+
{ match: /rtx 2060 super\b/i, name: 'GeForce RTX 2060 SUPER 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 448.0, arch: 'Turing TU106', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
108
|
+
{ match: /rtx 2060\b/i, name: 'GeForce RTX 2060 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 336.0, arch: 'Turing TU106', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
109
|
+
{ match: /rtx 2060\b/i, name: 'GeForce RTX 2060 6GB', vramGb: 6, busBits: 192, bandwidthGbs: 336.0, arch: 'Turing TU106', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
110
|
+
{ match: /gtx 1660 ti\b/i, name: 'GeForce GTX 1660 Ti 6GB', vramGb: 6, busBits: 192, bandwidthGbs: 288.0, arch: 'Turing TU116', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
111
|
+
{ match: /gtx 1660 super\b/i, name: 'GeForce GTX 1660 SUPER 6GB', vramGb: 6, busBits: 192, bandwidthGbs: 336.0, arch: 'Turing TU116', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
112
|
+
{ match: /gtx 1660\b/i, name: 'GeForce GTX 1660 6GB', vramGb: 6, busBits: 192, bandwidthGbs: 192.0, arch: 'Turing TU116', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
113
|
+
{ match: /gtx 1650 super\b/i, name: 'GeForce GTX 1650 SUPER 4GB', vramGb: 4, busBits: 128, bandwidthGbs: 192.0, arch: 'Turing TU116', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
114
|
+
{ match: /gtx 1650\b/i, name: 'GeForce GTX 1650 4GB', vramGb: 4, busBits: 128, bandwidthGbs: 128.0, arch: 'Turing TU117', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
{ match: /titan x(p|\s*pascal)?\b/i, name: 'NVIDIA TITAN Xp 12GB', vramGb: 12, busBits: 384, bandwidthGbs: 547.7, arch: 'Pascal GP102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5X' },
|
|
118
|
+
{ match: /gtx 1080 ti\b/i, name: 'GeForce GTX 1080 Ti 11GB', vramGb: 11, busBits: 352, bandwidthGbs: 484.4, arch: 'Pascal GP102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5X' },
|
|
119
|
+
{ match: /gtx 1080\b/i, name: 'GeForce GTX 1080 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 320.3, arch: 'Pascal GP104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5X' },
|
|
120
|
+
{ match: /gtx 1070 ti\b/i, name: 'GeForce GTX 1070 Ti 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 256.3, arch: 'Pascal GP104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
121
|
+
{ match: /gtx 1070\b/i, name: 'GeForce GTX 1070 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 256.3, arch: 'Pascal GP104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
122
|
+
{ match: /gtx 1060\b/i, name: 'GeForce GTX 1060 6GB', vramGb: 6, busBits: 192, bandwidthGbs: 192.2, arch: 'Pascal GP106', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
123
|
+
{ match: /gtx 1060\b/i, name: 'GeForce GTX 1060 3GB', vramGb: 3, busBits: 192, bandwidthGbs: 192.2, arch: 'Pascal GP106', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
{ match: /b200\b/i, name: 'NVIDIA B200 SXM 192GB HBM3e', vramGb: 192, busBits: 8192, bandwidthGbs: 8000.0, arch: 'Blackwell GB100', pcie: 'SXM6', memoryType: 'HBM3e' },
|
|
128
|
+
{ match: /h200\b/i, name: 'NVIDIA H200 141GB HBM3e', vramGb: 141, busBits: 6144, bandwidthGbs: 4800.0, arch: 'Hopper GH100', pcie: 'SXM5', memoryType: 'HBM3e' },
|
|
129
|
+
{ match: /h100.*sxm/i, name: 'NVIDIA H100 SXM5 80GB HBM3', vramGb: 80, busBits: 5120, bandwidthGbs: 3350.0, arch: 'Hopper GH100', pcie: 'SXM5', memoryType: 'HBM3' },
|
|
130
|
+
{ match: /h100.*nvl/i, name: 'NVIDIA H100 NVL 94GB HBM3', vramGb: 94, busBits: 5120, bandwidthGbs: 3900.0, arch: 'Hopper GH100', pcie: 'PCIe 5.0 x16', memoryType: 'HBM3' },
|
|
131
|
+
{ match: /h100\b/i, name: 'NVIDIA H100 PCIe 80GB HBM2e', vramGb: 80, busBits: 5120, bandwidthGbs: 2039.0, arch: 'Hopper GH100', pcie: 'PCIe 5.0 x16', memoryType: 'HBM2e' },
|
|
132
|
+
{ match: /a100\b/i, name: 'NVIDIA A100 80GB HBM2e', vramGb: 80, busBits: 5120, bandwidthGbs: 2039.0, arch: 'Ampere GA100', pcie: 'PCIe 4.0 x16 / SXM4', memoryType: 'HBM2e' },
|
|
133
|
+
{ match: /a100\b/i, name: 'NVIDIA A100 40GB HBM2', vramGb: 40, busBits: 5120, bandwidthGbs: 1555.0, arch: 'Ampere GA100', pcie: 'PCIe 4.0 x16 / SXM4', memoryType: 'HBM2' },
|
|
134
|
+
{ match: /a800\b/i, name: 'NVIDIA A800 80GB HBM2e', vramGb: 80, busBits: 5120, bandwidthGbs: 2039.0, arch: 'Ampere GA100', pcie: 'PCIe 4.0 x16', memoryType: 'HBM2e' },
|
|
135
|
+
{ match: /l40s\b/i, name: 'NVIDIA L40S 48GB', vramGb: 48, busBits: 384, bandwidthGbs: 864.0, arch: 'Ada AD102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
136
|
+
{ match: /l40\b/i, name: 'NVIDIA L40 48GB', vramGb: 48, busBits: 384, bandwidthGbs: 864.0, arch: 'Ada AD102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
137
|
+
{ match: /l4\b/i, name: 'NVIDIA L4 24GB', vramGb: 24, busBits: 192, bandwidthGbs: 300.0, arch: 'Ada AD104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
138
|
+
{ match: /rtx 6000 ada\b/i, name: 'NVIDIA RTX 6000 Ada Generation 48GB', vramGb: 48, busBits: 384, bandwidthGbs: 960.0, arch: 'Ada AD102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
139
|
+
{ match: /rtx 5000 ada\b/i, name: 'NVIDIA RTX 5000 Ada Generation 32GB', vramGb: 32, busBits: 256, bandwidthGbs: 576.0, arch: 'Ada AD102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
140
|
+
{ match: /rtx 4500 ada\b/i, name: 'NVIDIA RTX 4500 Ada Generation 24GB', vramGb: 24, busBits: 192, bandwidthGbs: 432.0, arch: 'Ada AD104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
141
|
+
{ match: /rtx 4000.*sff ada\b/i, name: 'NVIDIA RTX 4000 SFF Ada Generation 20GB', vramGb: 20, busBits: 160, bandwidthGbs: 280.0, arch: 'Ada AD104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
142
|
+
{ match: /rtx 4000 ada\b/i, name: 'NVIDIA RTX 4000 Ada Generation 20GB', vramGb: 20, busBits: 160, bandwidthGbs: 360.0, arch: 'Ada AD104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
143
|
+
{ match: /rtx 2000 ada\b/i, name: 'NVIDIA RTX 2000 Ada Generation 16GB', vramGb: 16, busBits: 128, bandwidthGbs: 224.0, arch: 'Ada AD107', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
144
|
+
{ match: /rtx a6000\b/i, name: 'NVIDIA RTX A6000 48GB', vramGb: 48, busBits: 384, bandwidthGbs: 768.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
145
|
+
{ match: /rtx a5500\b/i, name: 'NVIDIA RTX A5500 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 768.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
146
|
+
{ match: /rtx a5000\b/i, name: 'NVIDIA RTX A5000 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 768.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
147
|
+
{ match: /rtx a4500\b/i, name: 'NVIDIA RTX A4500 20GB', vramGb: 20, busBits: 320, bandwidthGbs: 640.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
148
|
+
{ match: /rtx a4000\b/i, name: 'NVIDIA RTX A4000 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 448.0, arch: 'Ampere GA104', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
149
|
+
{ match: /rtx a2000\b/i, name: 'NVIDIA RTX A2000 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 288.0, arch: 'Ampere GA106', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
150
|
+
{ match: /rtx a2000\b/i, name: 'NVIDIA RTX A2000 6GB', vramGb: 6, busBits: 192, bandwidthGbs: 288.0, arch: 'Ampere GA106', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
151
|
+
{ match: /a40\b/i, name: 'NVIDIA A40 48GB', vramGb: 48, busBits: 384, bandwidthGbs: 696.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
152
|
+
{ match: /a30\b/i, name: 'NVIDIA A30 24GB HBM2', vramGb: 24, busBits: 3072, bandwidthGbs: 933.0, arch: 'Ampere GA100', pcie: 'PCIe 4.0 x16', memoryType: 'HBM2' },
|
|
153
|
+
{ match: /a16\b/i, name: 'NVIDIA A16 64GB (4x16GB)', vramGb: 64, busBits: 512, bandwidthGbs: 800.0, arch: 'Ampere GA107', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
154
|
+
{ match: /a10g\b/i, name: 'NVIDIA A10G 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 600.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
155
|
+
{ match: /a10\b/i, name: 'NVIDIA A10 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 600.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
156
|
+
{ match: /a2\b/i, name: 'NVIDIA A2 16GB', vramGb: 16, busBits: 128, bandwidthGbs: 200.0, arch: 'Ampere GA107', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
157
|
+
{ match: /quadro rtx 8000\b/i, name: 'Quadro RTX 8000 48GB', vramGb: 48, busBits: 384, bandwidthGbs: 672.0, arch: 'Turing TU102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
158
|
+
{ match: /quadro rtx 6000\b/i, name: 'Quadro RTX 6000 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 672.0, arch: 'Turing TU102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
159
|
+
{ match: /quadro rtx 5000\b/i, name: 'Quadro RTX 5000 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 448.0, arch: 'Turing TU104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
160
|
+
{ match: /quadro rtx 4000\b/i, name: 'Quadro RTX 4000 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 416.0, arch: 'Turing TU106', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
161
|
+
{ match: /quadro p6000\b/i, name: 'Quadro P6000 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 432.0, arch: 'Pascal GP102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5X' },
|
|
162
|
+
{ match: /quadro p5000\b/i, name: 'Quadro P5000 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 288.0, arch: 'Pascal GP104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5X' },
|
|
163
|
+
{ match: /quadro p4000\b/i, name: 'Quadro P4000 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 243.0, arch: 'Pascal GP104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
164
|
+
{ match: /quadro m6000\b/i, name: 'Quadro M6000 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 317.0, arch: 'Maxwell GM200', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
165
|
+
{ match: /tesla v100\b/i, name: 'NVIDIA Tesla V100 32GB HBM2', vramGb: 32, busBits: 4096, bandwidthGbs: 900.0, arch: 'Volta GV100', pcie: 'PCIe 3.0 x16 / SXM2', memoryType: 'HBM2' },
|
|
166
|
+
{ match: /tesla v100\b/i, name: 'NVIDIA Tesla V100 16GB HBM2', vramGb: 16, busBits: 4096, bandwidthGbs: 900.0, arch: 'Volta GV100', pcie: 'PCIe 3.0 x16 / SXM2', memoryType: 'HBM2' },
|
|
167
|
+
{ match: /tesla t4\b/i, name: 'NVIDIA Tesla T4 16GB', vramGb: 16, busBits: 128, bandwidthGbs: 320.0, arch: 'Turing TU104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR6' },
|
|
168
|
+
{ match: /tesla p40\b/i, name: 'NVIDIA Tesla P40 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 345.6, arch: 'Pascal GP102', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
169
|
+
{ match: /tesla p100\b/i, name: 'NVIDIA Tesla P100 16GB HBM2', vramGb: 16, busBits: 4096, bandwidthGbs: 732.0, arch: 'Pascal GP100', pcie: 'PCIe 3.0 x16', memoryType: 'HBM2' },
|
|
170
|
+
{ match: /tesla p4\b/i, name: 'NVIDIA Tesla P4 8GB', vramGb: 8, busBits: 128, bandwidthGbs: 192.0, arch: 'Pascal GP104', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
171
|
+
{ match: /tesla m40\b/i, name: 'NVIDIA Tesla M40 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 288.0, arch: 'Maxwell GM200', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
172
|
+
{ match: /cmp 170hx\b/i, name: 'NVIDIA CMP 170HX 8GB HBM2e', vramGb: 8, busBits: 4096, bandwidthGbs: 1493.0, arch: 'Ampere GA100', pcie: 'PCIe 4.0 x4', memoryType: 'HBM2e' },
|
|
173
|
+
{ match: /cmp 90hx\b/i, name: 'NVIDIA CMP 90HX 10GB', vramGb: 10, busBits: 320, bandwidthGbs: 760.0, arch: 'Ampere GA102', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6X' },
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
{ match: /mi300x\b/i, name: 'AMD Instinct MI300X 192GB HBM3', vramGb: 192, busBits: 8192, bandwidthGbs: 5300.0, arch: 'CDNA 3', pcie: 'OAM', memoryType: 'HBM3' },
|
|
177
|
+
{ match: /mi300a\b/i, name: 'AMD Instinct MI300A 128GB HBM3', vramGb: 128, busBits: 8192, bandwidthGbs: 5300.0, arch: 'CDNA 3', pcie: 'APU', memoryType: 'HBM3' },
|
|
178
|
+
{ match: /mi250x\b/i, name: 'AMD Instinct MI250X 128GB HBM2e', vramGb: 128, busBits: 8192, bandwidthGbs: 3200.0, arch: 'CDNA 2', pcie: 'OAM', memoryType: 'HBM2e' },
|
|
179
|
+
{ match: /mi210\b/i, name: 'AMD Instinct MI210 64GB HBM2e', vramGb: 64, busBits: 4096, bandwidthGbs: 1600.0, arch: 'CDNA 2', pcie: 'PCIe 4.0 x16', memoryType: 'HBM2e' },
|
|
180
|
+
{ match: /mi100\b/i, name: 'AMD Instinct MI100 32GB HBM2', vramGb: 32, busBits: 4096, bandwidthGbs: 1228.8, arch: 'CDNA 1', pcie: 'PCIe 4.0 x16', memoryType: 'HBM2' },
|
|
181
|
+
{ match: /mi60\b/i, name: 'AMD Instinct MI60 32GB HBM2', vramGb: 32, busBits: 4096, bandwidthGbs: 1024.0, arch: 'Vega 20', pcie: 'PCIe 4.0 x16', memoryType: 'HBM2' },
|
|
182
|
+
{ match: /mi50\b/i, name: 'AMD Instinct MI50 16GB HBM2', vramGb: 16, busBits: 4096, bandwidthGbs: 1024.0, arch: 'Vega 20', pcie: 'PCIe 4.0 x16', memoryType: 'HBM2' },
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
{ match: /pro w7900\b/i, name: 'Radeon PRO W7900 48GB', vramGb: 48, busBits: 384, bandwidthGbs: 864.0, arch: 'RDNA 3 Navi 31', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
186
|
+
{ match: /pro w7800\b/i, name: 'Radeon PRO W7800 32GB', vramGb: 32, busBits: 256, bandwidthGbs: 576.0, arch: 'RDNA 3 Navi 31', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
187
|
+
{ match: /pro w7700\b/i, name: 'Radeon PRO W7700 16GB', vramGb: 16, busBits: 128, bandwidthGbs: 288.0, arch: 'RDNA 3 Navi 32', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
188
|
+
{ match: /pro w6800\b/i, name: 'Radeon PRO W6800 32GB', vramGb: 32, busBits: 256, bandwidthGbs: 512.0, arch: 'RDNA 2 Navi 21', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
189
|
+
{ match: /radeon pro vii\b/i, name: 'Radeon PRO VII 16GB HBM2', vramGb: 16, busBits: 4096, bandwidthGbs: 1024.0, arch: 'Vega 20', pcie: 'PCIe 4.0 x16', memoryType: 'HBM2' },
|
|
190
|
+
{ match: /radeon vii\b/i, name: 'Radeon VII 16GB HBM2', vramGb: 16, busBits: 4096, bandwidthGbs: 1024.0, arch: 'Vega 20', pcie: 'PCIe 3.0 x16', memoryType: 'HBM2' },
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
{ match: /rx 7900 xtx\b/i, name: 'Radeon RX 7900 XTX 24GB', vramGb: 24, busBits: 384, bandwidthGbs: 960.0, arch: 'RDNA 3 Navi 31', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
195
|
+
{ match: /rx 7900 xt\b/i, name: 'Radeon RX 7900 XT 20GB', vramGb: 20, busBits: 320, bandwidthGbs: 800.0, arch: 'RDNA 3 Navi 31', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
196
|
+
{ match: /rx 7900 gre\b/i, name: 'Radeon RX 7900 GRE 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 576.0, arch: 'RDNA 3 Navi 31', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
197
|
+
{ match: /rx 7800 xt\b/i, name: 'Radeon RX 7800 XT 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 624.1, arch: 'RDNA 3 Navi 32', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
198
|
+
{ match: /rx 7700 xt\b/i, name: 'Radeon RX 7700 XT 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 432.0, arch: 'RDNA 3 Navi 32', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
199
|
+
{ match: /rx 7600 xt\b/i, name: 'Radeon RX 7600 XT 16GB', vramGb: 16, busBits: 128, bandwidthGbs: 288.0, arch: 'RDNA 3 Navi 33', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
200
|
+
{ match: /rx 7600\b/i, name: 'Radeon RX 7600 8GB', vramGb: 8, busBits: 128, bandwidthGbs: 288.0, arch: 'RDNA 3 Navi 33', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
{ match: /rx 6950 xt\b/i, name: 'Radeon RX 6950 XT 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 576.0, arch: 'RDNA 2 Navi 21', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
204
|
+
{ match: /rx 6900 xt\b/i, name: 'Radeon RX 6900 XT 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 512.0, arch: 'RDNA 2 Navi 21', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
205
|
+
{ match: /rx 6800 xt\b/i, name: 'Radeon RX 6800 XT 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 512.0, arch: 'RDNA 2 Navi 21', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
206
|
+
{ match: /rx 6800\b/i, name: 'Radeon RX 6800 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 512.0, arch: 'RDNA 2 Navi 21', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
207
|
+
{ match: /rx 6750 xt\b/i, name: 'Radeon RX 6750 XT 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 432.0, arch: 'RDNA 2 Navi 22', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
208
|
+
{ match: /rx 6700 xt\b/i, name: 'Radeon RX 6700 XT 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 384.0, arch: 'RDNA 2 Navi 22', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
209
|
+
{ match: /rx 6650 xt\b/i, name: 'Radeon RX 6650 XT 8GB', vramGb: 8, busBits: 128, bandwidthGbs: 280.0, arch: 'RDNA 2 Navi 23', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
210
|
+
{ match: /rx 6600 xt\b/i, name: 'Radeon RX 6600 XT 8GB', vramGb: 8, busBits: 128, bandwidthGbs: 256.0, arch: 'RDNA 2 Navi 23', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
211
|
+
{ match: /rx 6600\b/i, name: 'Radeon RX 6600 8GB', vramGb: 8, busBits: 128, bandwidthGbs: 224.0, arch: 'RDNA 2 Navi 23', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
212
|
+
{ match: /rx 5700 xt\b/i, name: 'Radeon RX 5700 XT 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 448.0, arch: 'RDNA 1 Navi 10', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
213
|
+
{ match: /rx 580\b/i, name: 'Radeon RX 580 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 256.0, arch: 'Polaris 20', pcie: 'PCIe 3.0 x16', memoryType: 'GDDR5' },
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
{ match: /ryzen ai max\+? 395|strix halo/i, name: 'AMD Ryzen AI Max+ 395 (Strix Halo) Unified Memory', vramGb: 128, busBits: 256, bandwidthGbs: 256.0, arch: 'RDNA 3.5', pcie: 'Unified APU', memoryType: 'LPDDR5X', isUnifiedMemory: true },
|
|
217
|
+
{ match: /ryzen ai 9 hx 370|strix point/i, name: 'AMD Ryzen AI 9 HX 370 (Strix Point) Unified Memory', vramGb: 32, busBits: 128, bandwidthGbs: 120.0, arch: 'RDNA 3.5', pcie: 'Unified APU', memoryType: 'LPDDR5X', isUnifiedMemory: true },
|
|
218
|
+
{ match: /radeon 780m/i, name: 'AMD Radeon 780M Unified Memory', vramGb: 16, busBits: 128, bandwidthGbs: 120.0, arch: 'RDNA 3', pcie: 'Unified APU', memoryType: 'LPDDR5X', isUnifiedMemory: true },
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
{ match: /apple m.*ultra\b/i, name: 'Apple M Ultra Unified Memory', vramGb: 128, busBits: 1024, bandwidthGbs: 800.0, arch: 'Apple Silicon Ultra', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
222
|
+
{ match: /apple m4 max\b/i, name: 'Apple M4 Max Unified Memory (16-Core)', vramGb: 128, busBits: 512, bandwidthGbs: 546.0, arch: 'Apple Silicon Max', pcie: 'Unified SoC', memoryType: 'LPDDR5X', isUnifiedMemory: true },
|
|
223
|
+
{ match: /apple m4 max\b/i, name: 'Apple M4 Max Unified Memory (14-Core)', vramGb: 36, busBits: 384, bandwidthGbs: 410.0, arch: 'Apple Silicon Max', pcie: 'Unified SoC', memoryType: 'LPDDR5X', isUnifiedMemory: true },
|
|
224
|
+
{ match: /apple m4 pro\b/i, name: 'Apple M4 Pro Unified Memory', vramGb: 48, busBits: 256, bandwidthGbs: 273.0, arch: 'Apple Silicon Pro', pcie: 'Unified SoC', memoryType: 'LPDDR5X', isUnifiedMemory: true },
|
|
225
|
+
{ match: /apple m4\b/i, name: 'Apple M4 Unified Memory', vramGb: 24, busBits: 128, bandwidthGbs: 120.0, arch: 'Apple Silicon', pcie: 'Unified SoC', memoryType: 'LPDDR5X', isUnifiedMemory: true },
|
|
226
|
+
{ match: /apple m3 max\b/i, name: 'Apple M3 Max Unified Memory (16-Core)', vramGb: 128, busBits: 512, bandwidthGbs: 400.0, arch: 'Apple Silicon Max', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
227
|
+
{ match: /apple m3 max\b/i, name: 'Apple M3 Max Unified Memory (14-Core)', vramGb: 36, busBits: 384, bandwidthGbs: 300.0, arch: 'Apple Silicon Max', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
228
|
+
{ match: /apple m3 pro\b/i, name: 'Apple M3 Pro Unified Memory', vramGb: 36, busBits: 192, bandwidthGbs: 150.0, arch: 'Apple Silicon Pro', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
229
|
+
{ match: /apple m3\b/i, name: 'Apple M3 Unified Memory', vramGb: 24, busBits: 128, bandwidthGbs: 100.0, arch: 'Apple Silicon', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
230
|
+
{ match: /apple m2 max\b/i, name: 'Apple M2 Max Unified Memory', vramGb: 96, busBits: 512, bandwidthGbs: 400.0, arch: 'Apple Silicon Max', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
231
|
+
{ match: /apple m2 pro\b/i, name: 'Apple M2 Pro Unified Memory', vramGb: 32, busBits: 256, bandwidthGbs: 200.0, arch: 'Apple Silicon Pro', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
232
|
+
{ match: /apple m2\b/i, name: 'Apple M2 Unified Memory', vramGb: 24, busBits: 128, bandwidthGbs: 100.0, arch: 'Apple Silicon', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
233
|
+
{ match: /apple m1 max\b/i, name: 'Apple M1 Max Unified Memory', vramGb: 64, busBits: 512, bandwidthGbs: 400.0, arch: 'Apple Silicon Max', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
234
|
+
{ match: /apple m1 pro\b/i, name: 'Apple M1 Pro Unified Memory', vramGb: 32, busBits: 256, bandwidthGbs: 200.0, arch: 'Apple Silicon Pro', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
235
|
+
{ match: /apple m1\b/i, name: 'Apple M1 Unified Memory', vramGb: 16, busBits: 128, bandwidthGbs: 68.3, arch: 'Apple Silicon', pcie: 'Unified SoC', memoryType: 'LPDDR4X', isUnifiedMemory: true },
|
|
236
|
+
{ match: /apple/i, name: 'Apple Silicon Unified Memory', vramGb: 16, busBits: 128, bandwidthGbs: 100.0, arch: 'Apple Silicon', pcie: 'Unified SoC', memoryType: 'LPDDR5', isUnifiedMemory: true },
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
{ match: /gaudi 3\b/i, name: 'Intel Gaudi 3 AI Accelerator 128GB HBM2e', vramGb: 128, busBits: 8192, bandwidthGbs: 3700.0, arch: 'Gaudi 3', pcie: 'OAM', memoryType: 'HBM2e' },
|
|
240
|
+
{ match: /gaudi 2\b/i, name: 'Intel Gaudi 2 AI Accelerator 96GB HBM2e', vramGb: 96, busBits: 6144, bandwidthGbs: 2450.0, arch: 'Gaudi 2', pcie: 'OAM', memoryType: 'HBM2e' },
|
|
241
|
+
{ match: /gpu max 1550|ponte vecchio\b/i, name: 'Intel Data Center GPU Max 1550 128GB HBM2e', vramGb: 128, busBits: 4096, bandwidthGbs: 3276.8, arch: 'Xe-HPC', pcie: 'OAM', memoryType: 'HBM2e' },
|
|
242
|
+
{ match: /gpu max 1100\b/i, name: 'Intel Data Center GPU Max 1100 48GB HBM2e', vramGb: 48, busBits: 4096, bandwidthGbs: 1228.8, arch: 'Xe-HPC', pcie: 'PCIe 5.0 x16', memoryType: 'HBM2e' },
|
|
243
|
+
{ match: /arc b580\b/i, name: 'Intel Arc B580 12GB', vramGb: 12, busBits: 192, bandwidthGbs: 456.0, arch: 'Battlemage BMG-G21', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
244
|
+
{ match: /arc b570\b/i, name: 'Intel Arc B570 10GB', vramGb: 10, busBits: 160, bandwidthGbs: 380.0, arch: 'Battlemage BMG-G21', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
245
|
+
{ match: /arc a770\b/i, name: 'Intel Arc A770 16GB', vramGb: 16, busBits: 256, bandwidthGbs: 560.0, arch: 'Alchemist ACM-G10', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
246
|
+
{ match: /arc a770\b/i, name: 'Intel Arc A770 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 512.0, arch: 'Alchemist ACM-G10', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
247
|
+
{ match: /arc a750\b/i, name: 'Intel Arc A750 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 512.0, arch: 'Alchemist ACM-G10', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
248
|
+
{ match: /arc a580\b/i, name: 'Intel Arc A580 8GB', vramGb: 8, busBits: 256, bandwidthGbs: 512.0, arch: 'Alchemist ACM-G10', pcie: 'PCIe 4.0 x16', memoryType: 'GDDR6' },
|
|
249
|
+
{ match: /arc a380\b/i, name: 'Intel Arc A380 6GB', vramGb: 6, busBits: 96, bandwidthGbs: 186.0, arch: 'Alchemist ACM-G11', pcie: 'PCIe 4.0 x8', memoryType: 'GDDR6' },
|
|
250
|
+
{ match: /arc 140v|lunar lake/i, name: 'Intel Core Ultra Arc 140V Unified Memory', vramGb: 32, busBits: 128, bandwidthGbs: 136.5, arch: 'Xe2-LPG', pcie: 'Unified SoC', memoryType: 'LPDDR5X', isUnifiedMemory: true }
|
|
251
|
+
];
|
|
252
|
+
|
|
253
|
+
const DISAMBIGUATED_GPU_MEMO_LIMIT = 200;
|
|
254
|
+
const disambiguateGpuMemo = new Map();
|
|
255
|
+
|
|
256
|
+
function memoizeDisambiguatedGpu(raw, spec) {
|
|
257
|
+
if (disambiguateGpuMemo.size >= DISAMBIGUATED_GPU_MEMO_LIMIT) {
|
|
258
|
+
disambiguateGpuMemo.delete(disambiguateGpuMemo.keys().next().value);
|
|
259
|
+
}
|
|
260
|
+
disambiguateGpuMemo.set(raw, spec);
|
|
261
|
+
return { ...spec };
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function _computeHardwareFingerprint(detectedName, detectedVramGb, detectedVendor) {
|
|
265
|
+
const raw = [
|
|
266
|
+
String(detectedName || '').trim().toLowerCase(),
|
|
267
|
+
Number(detectedVramGb) || 0,
|
|
268
|
+
String(detectedVendor || '').trim().toLowerCase()
|
|
269
|
+
].join('|');
|
|
270
|
+
return createHash('sha256').update(raw, 'utf8').digest('hex').slice(0, 16);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function _normalizeMcpPayload(payload, detectedVramGb) {
|
|
274
|
+
if (!payload || typeof payload !== 'object') return null;
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
if (payload.results && Array.isArray(payload.results) && payload.results.length > 0) {
|
|
278
|
+
const data = payload.results[0];
|
|
279
|
+
if (data && typeof data === 'object' && data._type !== 'withheld') {
|
|
280
|
+
const name = String(data.name || data.productName || data.model || data.card_name || '').trim();
|
|
281
|
+
const vramMb = data.vramMb ? data.vramMb / 1024 : 0;
|
|
282
|
+
const memSizeGb = data.memSize ? data.memSize / 1024 : 0;
|
|
283
|
+
const vram = Number(data.vramGb ?? data.memoryGb ?? data.totalVramGb ?? vramMb ?? memSizeGb ?? data.memory_size_gb ?? 0) || 0;
|
|
284
|
+
const busBits = Number(data.busBits ?? data.memoryBusWidth ?? data.busWidth ?? data.memory_bus_width ?? data.memBusWidth ?? 0) || 0;
|
|
285
|
+
const bandwidth = Number(data.bandwidthGbs ?? data.memoryBandwidth ?? data.bandwidth ?? data.memory_bandwidth_gb_s ?? data.memBandwidth ?? 0) || 0;
|
|
286
|
+
const chipName = data.chip && data.chip.name ? data.chip.name : data.chip;
|
|
287
|
+
const arch = String(data.arch ?? data.architecture ?? data.gpuArchitecture ?? chipName ?? 'Generic').trim();
|
|
288
|
+
const pcie = String(data.pcie ?? data.pciInterface ?? data.busInterface ?? data.interface ?? 'PCIe x16').trim();
|
|
289
|
+
const memoryType = String(data.memoryType ?? data.ramType ?? data.memType ?? data.memory_type ?? 'GDDR6').trim();
|
|
290
|
+
|
|
291
|
+
if (!name || (!vram && !busBits && !bandwidth)) return null;
|
|
292
|
+
const out = {
|
|
293
|
+
name,
|
|
294
|
+
vramGb: vram > 0 ? vram : (Number(detectedVramGb) || 0),
|
|
295
|
+
busBits: busBits > 0 ? busBits : 0,
|
|
296
|
+
bandwidthGbs: bandwidth > 0 ? bandwidth : 0,
|
|
297
|
+
arch: arch || 'Generic Discrete GPU',
|
|
298
|
+
pcie: pcie || 'PCIe x16',
|
|
299
|
+
memoryType: memoryType || 'GDDR6'
|
|
300
|
+
};
|
|
301
|
+
if (data.isUnifiedMemory || data.unifiedMemory) out.isUnifiedMemory = true;
|
|
302
|
+
return out;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const candidates = [payload.data, payload.result, payload.content, payload];
|
|
307
|
+
for (const c of candidates) {
|
|
308
|
+
if (!c || typeof c !== 'object') continue;
|
|
309
|
+
const data = Array.isArray(c) ? c[0] : c;
|
|
310
|
+
if (!data || typeof data !== 'object') continue;
|
|
311
|
+
|
|
312
|
+
const name = String(data.name || data.productName || data.model || data.card_name || '').trim();
|
|
313
|
+
const vramMb = data.vramMb ? data.vramMb / 1024 : 0;
|
|
314
|
+
const memSizeGb = data.memSize ? data.memSize / 1024 : 0;
|
|
315
|
+
const vram = Number(data.vramGb ?? data.memoryGb ?? data.totalVramGb ?? vramMb ?? memSizeGb ?? data.memory_size_gb ?? 0) || 0;
|
|
316
|
+
const busBits = Number(data.busBits ?? data.memoryBusWidth ?? data.busWidth ?? data.memory_bus_width ?? data.memBusWidth ?? 0) || 0;
|
|
317
|
+
const bandwidth = Number(data.bandwidthGbs ?? data.memoryBandwidth ?? data.bandwidth ?? data.memory_bandwidth_gb_s ?? data.memBandwidth ?? 0) || 0;
|
|
318
|
+
const chipName = data.chip && data.chip.name ? data.chip.name : data.chip;
|
|
319
|
+
const arch = String(data.arch ?? data.architecture ?? data.gpuArchitecture ?? chipName ?? 'Generic').trim();
|
|
320
|
+
const pcie = String(data.pcie ?? data.pciInterface ?? data.busInterface ?? data.interface ?? 'PCIe x16').trim();
|
|
321
|
+
const memoryType = String(data.memoryType ?? data.ramType ?? data.memType ?? data.memory_type ?? 'GDDR6').trim();
|
|
322
|
+
|
|
323
|
+
if (!name || (!vram && !busBits && !bandwidth)) continue;
|
|
324
|
+
const out = {
|
|
325
|
+
name,
|
|
326
|
+
vramGb: vram > 0 ? vram : (Number(detectedVramGb) || 0),
|
|
327
|
+
busBits: busBits > 0 ? busBits : 0,
|
|
328
|
+
bandwidthGbs: bandwidth > 0 ? bandwidth : 0,
|
|
329
|
+
arch: arch || 'Generic Discrete GPU',
|
|
330
|
+
pcie: pcie || 'PCIe x16',
|
|
331
|
+
memoryType: memoryType || 'GDDR6'
|
|
332
|
+
};
|
|
333
|
+
if (data.isUnifiedMemory || data.unifiedMemory) out.isUnifiedMemory = true;
|
|
334
|
+
return out;
|
|
335
|
+
}
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export class HardwareFingerprintCache {
|
|
340
|
+
constructor(options = {}) {
|
|
341
|
+
this.cacheFile = options.cacheFile || path.join(KIKU_DATA_DIR, 'hardware_fingerprint_cache.json');
|
|
342
|
+
this.maxAgeMs = options.maxAgeMs ?? 30 * 86400 * 1000;
|
|
343
|
+
this._loaded = null;
|
|
344
|
+
this._flushTimer = null;
|
|
345
|
+
this._flushChain = null;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
async _load() {
|
|
349
|
+
if (this._loaded) return this._loaded;
|
|
350
|
+
try {
|
|
351
|
+
const raw = await fs.readFile(this.cacheFile, 'utf8');
|
|
352
|
+
const parsed = JSON.parse(raw);
|
|
353
|
+
this._loaded = {
|
|
354
|
+
schemaVersion: 1,
|
|
355
|
+
generatedAt: Date.now(),
|
|
356
|
+
profiles: parsed && typeof parsed.profiles === 'object' ? parsed.profiles : {}
|
|
357
|
+
};
|
|
358
|
+
} catch {
|
|
359
|
+
this._loaded = { schemaVersion: 1, generatedAt: Date.now(), profiles: {} };
|
|
360
|
+
}
|
|
361
|
+
return this._loaded;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async _flush() {
|
|
365
|
+
if (!this._loaded) return;
|
|
366
|
+
try {
|
|
367
|
+
await fs.mkdir(path.dirname(this.cacheFile), { recursive: true });
|
|
368
|
+
await fs.writeFile(this.cacheFile, JSON.stringify(this._loaded, null, 2), 'utf8');
|
|
369
|
+
} catch {}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
async get(fingerprint) {
|
|
373
|
+
const store = await this._load();
|
|
374
|
+
const entry = store.profiles[fingerprint];
|
|
375
|
+
if (!entry) return null;
|
|
376
|
+
if (Date.now() - (entry.resolvedAt || 0) > this.maxAgeMs) return null;
|
|
377
|
+
return entry.profile || null;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
async put(fingerprint, profile) {
|
|
381
|
+
const store = await this._load();
|
|
382
|
+
store.profiles[fingerprint] = {
|
|
383
|
+
resolvedAt: Date.now(),
|
|
384
|
+
profile
|
|
385
|
+
};
|
|
386
|
+
await this._flush();
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async touch(fingerprint) {
|
|
390
|
+
const store = await this._load();
|
|
391
|
+
const entry = store.profiles[fingerprint];
|
|
392
|
+
if (entry) {
|
|
393
|
+
entry.lastHitAt = Date.now();
|
|
394
|
+
this._scheduleFlush();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
_scheduleFlush() {
|
|
399
|
+
if (this._flushTimer) clearTimeout(this._flushTimer);
|
|
400
|
+
this._flushTimer = setTimeout(() => {
|
|
401
|
+
this._flushTimer = null;
|
|
402
|
+
this._flushChain = (this._flushChain || Promise.resolve())
|
|
403
|
+
.then(() => this._flush())
|
|
404
|
+
.catch(() => {});
|
|
405
|
+
}, 500);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export class TechPowerUpClient {
|
|
410
|
+
constructor(options = {}) {
|
|
411
|
+
this.legacyCacheFile = options.cacheFile || path.join(KIKU_DATA_DIR, 'hardware_profile.json');
|
|
412
|
+
this.cacheFile = options.cacheFile || path.join(KIKU_DATA_DIR, 'hardware_profile.json');
|
|
413
|
+
this.timeoutMs = options.timeoutMs || 2500;
|
|
414
|
+
this.mcpTimeoutMs = options.mcpTimeoutMs || 1500;
|
|
415
|
+
this.mcpEnabled = options.mcpEnabled ?? true;
|
|
416
|
+
this.fingerprintCache = new HardwareFingerprintCache({
|
|
417
|
+
cacheFile: path.join(path.dirname(this.cacheFile), 'hardware_fingerprint_cache.json'),
|
|
418
|
+
maxAgeMs: options.fingerprintCacheMaxAgeMs ?? 30 * 86400 * 1000
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
async _querySingleMcpServer(mcpId, config, queryName, queryVramGb) {
|
|
424
|
+
if (!this.mcpEnabled) return null;
|
|
425
|
+
const url = config.url && !config.url.endsWith('/') ? config.url + '/' : (config.url || '');
|
|
426
|
+
const endpoint = url + 'tools/call';
|
|
427
|
+
const args = {};
|
|
428
|
+
args[config.queryArg || 'query'] = queryName;
|
|
429
|
+
if (queryVramGb > 0) args.vramGb = queryVramGb;
|
|
430
|
+
const body = {
|
|
431
|
+
jsonrpc: '2.0',
|
|
432
|
+
id: Date.now().toString(36) + Math.random().toString(36).slice(2, 8),
|
|
433
|
+
method: 'tools/call',
|
|
434
|
+
params: { name: config.toolName || 'gpu_lookup', arguments: args }
|
|
435
|
+
};
|
|
436
|
+
let res;
|
|
437
|
+
try {
|
|
438
|
+
res = await fetch(endpoint, {
|
|
439
|
+
method: 'POST',
|
|
440
|
+
headers: { 'Content-Type': 'application/json' },
|
|
441
|
+
body: JSON.stringify(body),
|
|
442
|
+
signal: AbortSignal.timeout(this.mcpTimeoutMs)
|
|
443
|
+
});
|
|
444
|
+
} catch {
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
if (!res.ok) return null;
|
|
448
|
+
let payload;
|
|
449
|
+
try {
|
|
450
|
+
payload = await res.json();
|
|
451
|
+
} catch {
|
|
452
|
+
return null;
|
|
453
|
+
}
|
|
454
|
+
const normalized = _normalizeMcpPayload(payload, queryVramGb);
|
|
455
|
+
if (!normalized) return null;
|
|
456
|
+
return { source: `mcp:${mcpId}`, spec: normalized };
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
async _queryHardwareMcp(detectedName = '', detectedVramGb = 0) {
|
|
460
|
+
if (!this.mcpEnabled) return null;
|
|
461
|
+
const queryName = String(detectedName || '').trim();
|
|
462
|
+
if (!queryName) return null;
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
const mcpConfig = await loadTechPowerUpMcpConfig();
|
|
466
|
+
const servers = mcpConfig.mcpServers || {};
|
|
467
|
+
|
|
468
|
+
try {
|
|
469
|
+
await mcpClientManager.loadPersistedServers();
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
for (const [name, config] of Object.entries(servers)) {
|
|
473
|
+
try {
|
|
474
|
+
await mcpClientManager.connect(name, config, { persist: false, fetchMetadata: true });
|
|
475
|
+
} catch {}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
for (const mcpId of MCP_RESOLUTION_ORDER) {
|
|
479
|
+
const config = servers[mcpId] || TECHPOWERUP_MCP_CONFIG[mcpId];
|
|
480
|
+
if (!config) continue;
|
|
481
|
+
|
|
482
|
+
const toolName = config.toolName || 'search_gpu_cards';
|
|
483
|
+
const args = {};
|
|
484
|
+
args[config.queryArg || 'query'] = queryName;
|
|
485
|
+
if (detectedVramGb > 0) args.vramGb = detectedVramGb;
|
|
486
|
+
|
|
487
|
+
try {
|
|
488
|
+
const result = await mcpClientManager.callTool(toolName, args);
|
|
489
|
+
if (result && result.status === 'success') {
|
|
490
|
+
const normalized = _normalizeMcpPayload(result, detectedVramGb);
|
|
491
|
+
if (normalized) {
|
|
492
|
+
return { source: `mcp:${mcpId}`, spec: normalized };
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
} catch {}
|
|
496
|
+
}
|
|
497
|
+
} catch {}
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
for (const mcpId of MCP_RESOLUTION_ORDER) {
|
|
501
|
+
const config = servers[mcpId] || TECHPOWERUP_MCP_CONFIG[mcpId];
|
|
502
|
+
if (!config) continue;
|
|
503
|
+
|
|
504
|
+
const updatedConfig = { ...config, toolName: config.toolName || 'search_gpu_cards' };
|
|
505
|
+
try {
|
|
506
|
+
const result = await this._querySingleMcpServer(mcpId, updatedConfig, queryName, detectedVramGb);
|
|
507
|
+
if (result && result.spec) return result;
|
|
508
|
+
} catch {}
|
|
509
|
+
}
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
disambiguateGpu(detectedName = '', detectedVramGb = 0) {
|
|
515
|
+
const raw = String(detectedName || '').trim();
|
|
516
|
+
if (disambiguateGpuMemo.has(raw)) {
|
|
517
|
+
return { ...disambiguateGpuMemo.get(raw) };
|
|
518
|
+
}
|
|
519
|
+
const vram = Number(detectedVramGb) || 0;
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
const explicitMatch = raw.match(/\b(\d{1,3})\s*(?:gb|g)\b/i);
|
|
523
|
+
const explicitVram = explicitMatch ? parseFloat(explicitMatch[1]) : 0;
|
|
524
|
+
const targetVram = vram > 0 ? vram : explicitVram;
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
const matchedSpecs = [];
|
|
528
|
+
for (const spec of KNOWN_GPU_SPECS) {
|
|
529
|
+
const match = raw.match(spec.match);
|
|
530
|
+
if (match) {
|
|
531
|
+
matchedSpecs.push({
|
|
532
|
+
spec,
|
|
533
|
+
matchLength: match[0].length
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
if (matchedSpecs.length > 0) {
|
|
539
|
+
const maxLength = Math.max(...matchedSpecs.map(m => m.matchLength));
|
|
540
|
+
const topCandidates = matchedSpecs
|
|
541
|
+
.filter(m => m.matchLength === maxLength)
|
|
542
|
+
.map(m => {
|
|
543
|
+
const { match: _ignored, ...rest } = m.spec;
|
|
544
|
+
return { ...rest, source: HARDWARE_RESOLUTION_SOURCE.KNOWN_DATABASE };
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
if (topCandidates.length === 1) {
|
|
548
|
+
return topCandidates[0];
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
if (targetVram > 0) {
|
|
552
|
+
topCandidates.sort((a, b) => Math.abs(a.vramGb - targetVram) - Math.abs(b.vramGb - targetVram));
|
|
553
|
+
return topCandidates[0];
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
return topCandidates[0];
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
let busBits = 192;
|
|
561
|
+
let bandwidthGbs = 250;
|
|
562
|
+
let memoryType = 'GDDR6';
|
|
563
|
+
|
|
564
|
+
if (vram <= 4) { busBits = 128; bandwidthGbs = 128; memoryType = 'GDDR6'; }
|
|
565
|
+
else if (vram <= 6) { busBits = 192; bandwidthGbs = 288; memoryType = 'GDDR6'; }
|
|
566
|
+
else if (vram <= 8) { busBits = 256; bandwidthGbs = 448; memoryType = 'GDDR6'; }
|
|
567
|
+
else if (vram <= 12) { busBits = 192; bandwidthGbs = 504; memoryType = 'GDDR6X'; }
|
|
568
|
+
else if (vram <= 16) { busBits = 256; bandwidthGbs = 672; memoryType = 'GDDR6X'; }
|
|
569
|
+
else if (vram <= 24) { busBits = 384; bandwidthGbs = 936; memoryType = 'GDDR6X'; }
|
|
570
|
+
else if (vram <= 48) { busBits = 384; bandwidthGbs = 768; memoryType = 'GDDR6'; }
|
|
571
|
+
else if (vram <= 96) { busBits = 5120; bandwidthGbs = 2039; memoryType = 'HBM2e'; }
|
|
572
|
+
else { busBits = 6144; bandwidthGbs = 3200; memoryType = 'HBM3'; }
|
|
573
|
+
|
|
574
|
+
return {
|
|
575
|
+
name: raw || 'Generic Acceleration Device',
|
|
576
|
+
vramGb: vram || 6,
|
|
577
|
+
busBits,
|
|
578
|
+
bandwidthGbs,
|
|
579
|
+
arch: 'Generic Discrete GPU',
|
|
580
|
+
pcie: 'PCIe x16',
|
|
581
|
+
memoryType,
|
|
582
|
+
approximate: true,
|
|
583
|
+
source: HARDWARE_RESOLUTION_SOURCE.HEURISTIC_FALLBACK
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
calculateTheoreticalTps(bandwidthGbs, modelSizeGb = 4.0) {
|
|
589
|
+
const bw = Number(bandwidthGbs) || 0;
|
|
590
|
+
const size = Number(modelSizeGb) || 4.0;
|
|
591
|
+
if (bw <= 0 || size <= 0) return 0;
|
|
592
|
+
return Number((bw / size).toFixed(1));
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
estimateColdStartTimeSec(modelSizeGb = 4.0, storageSeqReadGbs = 3.5) {
|
|
597
|
+
const size = Number(modelSizeGb) || 4.0;
|
|
598
|
+
const speed = Math.max(0.2, Number(storageSeqReadGbs) || 3.5);
|
|
599
|
+
return Number((size / speed).toFixed(2));
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
async resolveHardwareProfile(gpuInfo = {}, options = {}) {
|
|
604
|
+
const name = gpuInfo.name || 'GeForce RTX 2060';
|
|
605
|
+
const vramGb = gpuInfo.totalMb ? (gpuInfo.totalMb / 1024) : 6.0;
|
|
606
|
+
const vendor = gpuInfo.vendor || '';
|
|
607
|
+
const fingerprint = _computeHardwareFingerprint(name, vramGb, vendor);
|
|
608
|
+
|
|
609
|
+
if (!options.forceRefresh) {
|
|
610
|
+
const cached = await this.fingerprintCache.get(fingerprint);
|
|
611
|
+
if (cached) {
|
|
612
|
+
await this.fingerprintCache.touch(fingerprint).catch(() => {});
|
|
613
|
+
return cached;
|
|
614
|
+
}
|
|
615
|
+
const legacy = await this._loadLegacyCachedProfile(name);
|
|
616
|
+
if (legacy && legacy.spec) return legacy;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
let source = HARDWARE_RESOLUTION_SOURCE.MCP_TECHPOWERUP_GPU;
|
|
620
|
+
let spec = null;
|
|
621
|
+
|
|
622
|
+
const mcpResult = await this._queryHardwareMcp(name, vramGb);
|
|
623
|
+
if (mcpResult && mcpResult.spec) {
|
|
624
|
+
source = mcpResult.source;
|
|
625
|
+
spec = mcpResult.spec;
|
|
626
|
+
} else {
|
|
627
|
+
const dbSpec = this.disambiguateGpu(name, vramGb);
|
|
628
|
+
spec = dbSpec;
|
|
629
|
+
source = dbSpec.source || HARDWARE_RESOLUTION_SOURCE.KNOWN_DATABASE;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
if (!spec.source) spec.source = source;
|
|
633
|
+
|
|
634
|
+
const profile = {
|
|
635
|
+
fingerprint,
|
|
636
|
+
spec,
|
|
637
|
+
resolution: {
|
|
638
|
+
source,
|
|
639
|
+
resolvedAt: new Date().toISOString(),
|
|
640
|
+
requestedName: name,
|
|
641
|
+
requestedVramGb: Number(vramGb.toFixed(2))
|
|
642
|
+
},
|
|
643
|
+
theoreticalMaxTps4Gb: this.calculateTheoreticalTps(spec.bandwidthGbs, 4.0),
|
|
644
|
+
theoreticalMaxTps7Gb: this.calculateTheoreticalTps(spec.bandwidthGbs, 7.0),
|
|
645
|
+
nvmeColdStartSec4Gb: this.estimateColdStartTimeSec(4.0, 3.5),
|
|
646
|
+
timestamp: Date.now()
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
await this.fingerprintCache.put(fingerprint, profile).catch(() => {});
|
|
650
|
+
await this._saveLegacyCachedProfile(profile).catch(() => {});
|
|
651
|
+
return profile;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
async _loadLegacyCachedProfile(detectedName) {
|
|
655
|
+
try {
|
|
656
|
+
const content = await fs.readFile(this.legacyCacheFile, 'utf8');
|
|
657
|
+
const data = JSON.parse(content);
|
|
658
|
+
const fresh = Date.now() - (data.timestamp || 0) < 7 * 86400 * 1000;
|
|
659
|
+
if (!fresh) return null;
|
|
660
|
+
if (detectedName && data.spec && !String(data.spec.name || '').includes(detectedName.split(' ')[0] || '')) return null;
|
|
661
|
+
return data;
|
|
662
|
+
} catch {
|
|
663
|
+
return null;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
async _saveLegacyCachedProfile(profile) {
|
|
668
|
+
try {
|
|
669
|
+
await fs.mkdir(path.dirname(this.legacyCacheFile), { recursive: true });
|
|
670
|
+
const legacy = {
|
|
671
|
+
spec: profile.spec,
|
|
672
|
+
theoreticalMaxTps4Gb: profile.theoreticalMaxTps4Gb,
|
|
673
|
+
theoreticalMaxTps7Gb: profile.theoreticalMaxTps7Gb,
|
|
674
|
+
nvmeColdStartSec4Gb: profile.nvmeColdStartSec4Gb,
|
|
675
|
+
timestamp: profile.timestamp
|
|
676
|
+
};
|
|
677
|
+
await fs.writeFile(this.legacyCacheFile, JSON.stringify(legacy, null, 2), 'utf8');
|
|
678
|
+
} catch {}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
export const techPowerUpClient = new TechPowerUpClient();
|