agentgui 1.0.363 → 1.0.365

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/build-portable.js CHANGED
@@ -143,7 +143,7 @@ if (process.env.NO_BUNDLE_MODELS === 'true') {
143
143
  console.log('[BUILD] Models not found, cloning from GitHub...');
144
144
  const ciModelsDir = path.join(os.tmpdir(), 'models-clone');
145
145
  try {
146
- require('child_process').execSync(`git clone https://github.com/AnEntrypoint/models.git "${ciModelsDir}" --depth 1`, { stdio: 'inherit' });
146
+ execSync(`git clone https://github.com/AnEntrypoint/models.git "${ciModelsDir}" --depth 1`, { stdio: 'inherit' });
147
147
  modelsDir = ciModelsDir;
148
148
  } catch (e) {
149
149
  console.error('[BUILD] Failed to clone models from GitHub:', e.message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.363",
3
+ "version": "1.0.365",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
@@ -1,67 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import os from 'os';
4
-
5
- const METRICS_PATH = path.join(os.homedir(), '.gmgui', 'models', '.metrics.json');
6
-
7
- export function recordMetric(metric) {
8
- const metricsDir = path.dirname(METRICS_PATH);
9
- if (!fs.existsSync(metricsDir)) {
10
- fs.mkdirSync(metricsDir, { recursive: true });
11
- }
12
-
13
- let metrics = [];
14
- if (fs.existsSync(METRICS_PATH)) {
15
- try {
16
- metrics = JSON.parse(fs.readFileSync(METRICS_PATH, 'utf8'));
17
- } catch (e) {
18
- metrics = [];
19
- }
20
- }
21
-
22
- metrics.push({
23
- ...metric,
24
- timestamp: new Date().toISOString()
25
- });
26
-
27
- const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
28
- metrics = metrics.filter(m => new Date(m.timestamp).getTime() > oneDayAgo);
29
-
30
- fs.writeFileSync(METRICS_PATH, JSON.stringify(metrics, null, 2));
31
- }
32
-
33
- export function getMetrics() {
34
- if (!fs.existsSync(METRICS_PATH)) {
35
- return [];
36
- }
37
- return JSON.parse(fs.readFileSync(METRICS_PATH, 'utf8'));
38
- }
39
-
40
- export function getMetricsSummary() {
41
- const metrics = getMetrics();
42
-
43
- const summary = {
44
- total: metrics.length,
45
- cache_hits: metrics.filter(m => m.layer === 'cache' && m.status === 'hit').length,
46
- huggingface: {
47
- success: metrics.filter(m => m.layer === 'huggingface' && m.status === 'success').length,
48
- error: metrics.filter(m => m.layer === 'huggingface' && m.status === 'error').length,
49
- avg_latency: 0
50
- }
51
- };
52
-
53
- const hfSuccess = metrics.filter(m => m.layer === 'huggingface' && m.status === 'success');
54
- if (hfSuccess.length > 0) {
55
- summary.huggingface.avg_latency = Math.round(
56
- hfSuccess.reduce((sum, m) => sum + m.latency_ms, 0) / hfSuccess.length
57
- );
58
- }
59
-
60
- return summary;
61
- }
62
-
63
- export function resetMetrics() {
64
- if (fs.existsSync(METRICS_PATH)) {
65
- fs.unlinkSync(METRICS_PATH);
66
- }
67
- }
@@ -1,26 +0,0 @@
1
- import fs from 'fs';
2
- import crypto from 'crypto';
3
-
4
- export function verifyFileIntegrity(filepath, expectedHash, minBytes) {
5
- if (!fs.existsSync(filepath)) {
6
- return { valid: false, reason: 'file_not_found' };
7
- }
8
-
9
- const stats = fs.statSync(filepath);
10
- if (minBytes && stats.size < minBytes) {
11
- return { valid: false, reason: 'size_too_small', actual: stats.size, expected: minBytes };
12
- }
13
-
14
- if (expectedHash) {
15
- const hash = crypto.createHash('sha256');
16
- const data = fs.readFileSync(filepath);
17
- hash.update(data);
18
- const actualHash = hash.digest('hex');
19
-
20
- if (actualHash !== expectedHash) {
21
- return { valid: false, reason: 'hash_mismatch', actual: actualHash, expected: expectedHash };
22
- }
23
- }
24
-
25
- return { valid: true };
26
- }
@@ -1,116 +0,0 @@
1
- import { createRequire } from 'module';
2
- import fs from 'fs';
3
- import path from 'path';
4
- import { recordMetric } from './download-metrics.js';
5
- import { verifyFileIntegrity } from './file-verification.js';
6
-
7
- const require = createRequire(import.meta.url);
8
-
9
- const GATEWAYS = [
10
- 'https://cloudflare-huggingface.com/huggingface/',
11
- 'https://dweb.link/huggingface/',
12
- 'https://gateway.pinata.cloud/huggingface/',
13
- 'https://huggingface.io/huggingface/'
14
- ];
15
-
16
-
17
-
18
- async function downloadFromHuggingFace(url, destPath, minBytes, onProgress) {
19
- const startTime = Date.now();
20
-
21
- try {
22
- if (onProgress) {
23
- onProgress({
24
- layer: 'huggingface',
25
- status: 'attempting'
26
- });
27
- }
28
-
29
- const { downloadFile } = require('webtalk/whisper-models');
30
- await downloadFile(url, destPath);
31
-
32
- const verification = verifyFileIntegrity(destPath, null, minBytes);
33
- if (!verification.valid) {
34
- if (fs.existsSync(destPath)) fs.unlinkSync(destPath);
35
- throw new Error(`Verification failed: ${verification.reason}`);
36
- }
37
-
38
- recordMetric({
39
- modelType: 'model',
40
- layer: 'huggingface',
41
- status: 'success',
42
- latency_ms: Date.now() - startTime,
43
- bytes_downloaded: fs.statSync(destPath).size
44
- });
45
-
46
- return { success: true, source: 'huggingface' };
47
- } catch (error) {
48
- recordMetric({
49
- modelType: 'model',
50
- layer: 'huggingface',
51
- status: 'error',
52
- error_type: error.name,
53
- error_message: error.message,
54
- latency_ms: Date.now() - startTime
55
- });
56
-
57
- throw error;
58
- }
59
- }
60
-
61
- export async function downloadWithFallback(options, onProgress) {
62
- const {
63
- huggingfaceCid,
64
- huggingfaceUrl,
65
- destPath,
66
- manifest,
67
- minBytes,
68
- preferredLayer = } = options;
69
-
70
- const dir = path.dirname(destPath);
71
- if (!fs.existsSync(dir)) {
72
- fs.mkdirSync(dir, { recursive: true });
73
- }
74
-
75
- if (fs.existsSync(destPath)) {
76
- const verification = verifyFileIntegrity(destPath, manifest?.sha256, minBytes);
77
- if (verification.valid) {
78
- recordMetric({
79
- modelType: 'model',
80
- layer: 'cache',
81
- status: 'hit'
82
- });
83
- return { success: true, source: 'cache' };
84
- } else {
85
- console.warn(`Cache invalid (${verification.reason}), re-downloading...`);
86
- const backupPath = `${destPath}.bak`;
87
- if (fs.existsSync(backupPath)) fs.unlinkSync(backupPath);
88
- fs.renameSync(destPath, backupPath);
89
- }
90
- }
91
-
92
- const layers = preferredLayer === ? ['huggingface']
93
- : ['huggingface', ];
94
-
95
- for (const layer of layers) {
96
- try {
97
- if (layer === && huggingfaceCid) {
98
- return await downloadFromhuggingface(huggingfaceCid, destPath, manifest, onProgress);
99
- } else if (layer === 'huggingface' && huggingfaceUrl) {
100
- return await downloadFromHuggingFace(huggingfaceUrl, destPath, minBytes, onProgress);
101
- }
102
- } catch (error) {
103
- console.warn(`${layer} layer failed:`, error.message);
104
- continue;
105
- }
106
- }
107
-
108
- recordMetric({
109
- modelType: 'model',
110
- status: 'all_layers_exhausted'
111
- });
112
-
113
- throw new Error('All download layers exhausted');
114
- }
115
-
116
- export { getMetrics, getMetricsSummary, resetMetrics } from './download-metrics.js';