@snoglobe/helios 0.1.0 → 0.2.0
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/dist/acp/entry.d.ts +7 -0
- package/dist/acp/entry.d.ts.map +1 -0
- package/dist/acp/entry.js +46 -0
- package/dist/acp/entry.js.map +1 -0
- package/dist/acp/server.d.ts +57 -0
- package/dist/acp/server.d.ts.map +1 -0
- package/dist/acp/server.js +434 -0
- package/dist/acp/server.js.map +1 -0
- package/dist/acp/transport.d.ts +31 -0
- package/dist/acp/transport.d.ts.map +1 -0
- package/dist/acp/transport.js +116 -0
- package/dist/acp/transport.js.map +1 -0
- package/dist/acp/types.d.ts +213 -0
- package/dist/acp/types.d.ts.map +1 -0
- package/dist/acp/types.js +3 -0
- package/dist/acp/types.js.map +1 -0
- package/dist/app.d.ts +8 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +51 -281
- package/dist/app.js.map +1 -1
- package/dist/bootstrap.d.ts +3 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +26 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli/auth.d.ts +20 -0
- package/dist/cli/auth.d.ts.map +1 -0
- package/dist/cli/auth.js +62 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/doctor.d.ts +9 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +368 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/env.d.ts +13 -0
- package/dist/cli/env.d.ts.map +1 -0
- package/dist/cli/env.js +16 -0
- package/dist/cli/env.js.map +1 -0
- package/dist/cli/export.d.ts +11 -0
- package/dist/cli/export.d.ts.map +1 -0
- package/dist/cli/export.js +103 -0
- package/dist/cli/export.js.map +1 -0
- package/dist/cli/index.d.ts +22 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +71 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-cmd.d.ts +11 -0
- package/dist/cli/init-cmd.d.ts.map +1 -0
- package/dist/cli/init-cmd.js +37 -0
- package/dist/cli/init-cmd.js.map +1 -0
- package/dist/cli/kill.d.ts +8 -0
- package/dist/cli/kill.d.ts.map +1 -0
- package/dist/cli/kill.js +46 -0
- package/dist/cli/kill.js.map +1 -0
- package/dist/cli/options.d.ts +18 -0
- package/dist/cli/options.d.ts.map +1 -0
- package/dist/cli/options.js +24 -0
- package/dist/cli/options.js.map +1 -0
- package/dist/cli/replay.d.ts +9 -0
- package/dist/cli/replay.d.ts.map +1 -0
- package/dist/cli/replay.js +65 -0
- package/dist/cli/replay.js.map +1 -0
- package/dist/cli/report.d.ts +11 -0
- package/dist/cli/report.d.ts.map +1 -0
- package/dist/cli/report.js +70 -0
- package/dist/cli/report.js.map +1 -0
- package/dist/cli/run.d.ts +17 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +120 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/search.d.ts +9 -0
- package/dist/cli/search.d.ts.map +1 -0
- package/dist/cli/search.js +52 -0
- package/dist/cli/search.js.map +1 -0
- package/dist/cli/sessions.d.ts +8 -0
- package/dist/cli/sessions.d.ts.map +1 -0
- package/dist/cli/sessions.js +38 -0
- package/dist/cli/sessions.js.map +1 -0
- package/dist/cli/watch.d.ts +8 -0
- package/dist/cli/watch.d.ts.map +1 -0
- package/dist/cli/watch.js +81 -0
- package/dist/cli/watch.js.map +1 -0
- package/dist/config/project.d.ts +63 -0
- package/dist/config/project.d.ts.map +1 -0
- package/dist/config/project.js +112 -0
- package/dist/config/project.js.map +1 -0
- package/dist/core/orchestrator.d.ts +4 -2
- package/dist/core/orchestrator.d.ts.map +1 -1
- package/dist/core/orchestrator.js +8 -3
- package/dist/core/orchestrator.js.map +1 -1
- package/dist/core/task-poller.d.ts +43 -0
- package/dist/core/task-poller.d.ts.map +1 -0
- package/dist/core/task-poller.js +98 -0
- package/dist/core/task-poller.js.map +1 -0
- package/dist/experiments/branching.d.ts +38 -0
- package/dist/experiments/branching.d.ts.map +1 -0
- package/dist/experiments/branching.js +80 -0
- package/dist/experiments/branching.js.map +1 -0
- package/dist/hub/client.d.ts +70 -0
- package/dist/hub/client.d.ts.map +1 -0
- package/dist/hub/client.js +140 -0
- package/dist/hub/client.js.map +1 -0
- package/dist/hub/config.d.ts +9 -0
- package/dist/hub/config.d.ts.map +1 -0
- package/dist/hub/config.js +38 -0
- package/dist/hub/config.js.map +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +25 -3
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +44 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +384 -0
- package/dist/init.js.map +1 -0
- package/dist/memory/context-gate.d.ts.map +1 -1
- package/dist/memory/context-gate.js +1 -1
- package/dist/memory/context-gate.js.map +1 -1
- package/dist/memory/experiment-tracker.d.ts.map +1 -1
- package/dist/memory/experiment-tracker.js +2 -6
- package/dist/memory/experiment-tracker.js.map +1 -1
- package/dist/memory/memory-store.d.ts.map +1 -1
- package/dist/memory/memory-store.js +16 -20
- package/dist/memory/memory-store.js.map +1 -1
- package/dist/metrics/collector.d.ts.map +1 -1
- package/dist/metrics/collector.js +7 -7
- package/dist/metrics/collector.js.map +1 -1
- package/dist/metrics/resources.d.ts +44 -0
- package/dist/metrics/resources.d.ts.map +1 -0
- package/dist/metrics/resources.js +382 -0
- package/dist/metrics/resources.js.map +1 -0
- package/dist/metrics/store.d.ts +10 -2
- package/dist/metrics/store.d.ts.map +1 -1
- package/dist/metrics/store.js +91 -27
- package/dist/metrics/store.js.map +1 -1
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +2 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/notifier.d.ts +36 -0
- package/dist/notifications/notifier.d.ts.map +1 -0
- package/dist/notifications/notifier.js +102 -0
- package/dist/notifications/notifier.js.map +1 -0
- package/dist/paths.d.ts +3 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +5 -0
- package/dist/paths.js.map +1 -0
- package/dist/providers/claude/provider.d.ts +7 -3
- package/dist/providers/claude/provider.d.ts.map +1 -1
- package/dist/providers/claude/provider.js +48 -8
- package/dist/providers/claude/provider.js.map +1 -1
- package/dist/providers/openai/callback-server.d.ts +6 -1
- package/dist/providers/openai/callback-server.d.ts.map +1 -1
- package/dist/providers/openai/callback-server.js +44 -20
- package/dist/providers/openai/callback-server.js.map +1 -1
- package/dist/providers/openai/oauth.d.ts +4 -0
- package/dist/providers/openai/oauth.d.ts.map +1 -1
- package/dist/providers/openai/oauth.js +34 -14
- package/dist/providers/openai/oauth.js.map +1 -1
- package/dist/providers/openai/provider.d.ts +6 -3
- package/dist/providers/openai/provider.d.ts.map +1 -1
- package/dist/providers/openai/provider.js +35 -9
- package/dist/providers/openai/provider.js.map +1 -1
- package/dist/providers/types.d.ts +9 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js.map +1 -1
- package/dist/remote/config.d.ts.map +1 -1
- package/dist/remote/config.js +4 -8
- package/dist/remote/config.js.map +1 -1
- package/dist/remote/connection-pool.d.ts.map +1 -1
- package/dist/remote/connection-pool.js +9 -5
- package/dist/remote/connection-pool.js.map +1 -1
- package/dist/store/database.d.ts.map +1 -1
- package/dist/store/database.js +2 -2
- package/dist/store/database.js.map +1 -1
- package/dist/store/migrations.d.ts.map +1 -1
- package/dist/store/migrations.js +27 -0
- package/dist/store/migrations.js.map +1 -1
- package/dist/store/preferences.js +2 -2
- package/dist/store/preferences.js.map +1 -1
- package/dist/store/session-store.d.ts +6 -0
- package/dist/store/session-store.d.ts.map +1 -1
- package/dist/store/session-store.js +20 -5
- package/dist/store/session-store.js.map +1 -1
- package/dist/tools/env-snapshot.d.ts +5 -0
- package/dist/tools/env-snapshot.d.ts.map +1 -0
- package/dist/tools/env-snapshot.js +174 -0
- package/dist/tools/env-snapshot.js.map +1 -0
- package/dist/tools/experiment-branch.d.ts +7 -0
- package/dist/tools/experiment-branch.d.ts.map +1 -0
- package/dist/tools/experiment-branch.js +167 -0
- package/dist/tools/experiment-branch.js.map +1 -0
- package/dist/tools/file-ops.d.ts.map +1 -1
- package/dist/tools/file-ops.js +1 -3
- package/dist/tools/file-ops.js.map +1 -1
- package/dist/tools/hub.d.ts +5 -0
- package/dist/tools/hub.d.ts.map +1 -0
- package/dist/tools/hub.js +298 -0
- package/dist/tools/hub.js.map +1 -0
- package/dist/tools/sweep.d.ts +6 -0
- package/dist/tools/sweep.d.ts.map +1 -0
- package/dist/tools/sweep.js +153 -0
- package/dist/tools/sweep.js.map +1 -0
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +2 -1
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/writeup.d.ts +11 -0
- package/dist/tools/writeup.d.ts.map +1 -0
- package/dist/tools/writeup.js +102 -0
- package/dist/tools/writeup.js.map +1 -0
- package/dist/ui/commands.d.ts +36 -0
- package/dist/ui/commands.d.ts.map +1 -1
- package/dist/ui/commands.js +495 -1
- package/dist/ui/commands.js.map +1 -1
- package/dist/ui/components/input-bar.js.map +1 -1
- package/dist/ui/components/overlay-header.d.ts.map +1 -1
- package/dist/ui/components/overlay-header.js.map +1 -1
- package/dist/ui/components/status-bar.js +1 -1
- package/dist/ui/components/status-bar.js.map +1 -1
- package/dist/ui/format.d.ts +4 -0
- package/dist/ui/format.d.ts.map +1 -1
- package/dist/ui/format.js +16 -0
- package/dist/ui/format.js.map +1 -1
- package/dist/ui/layout.d.ts +7 -42
- package/dist/ui/layout.d.ts.map +1 -1
- package/dist/ui/layout.js +71 -543
- package/dist/ui/layout.js.map +1 -1
- package/dist/ui/overlays/metrics-overlay.js.map +1 -1
- package/dist/ui/overlays/task-overlay.d.ts +1 -1
- package/dist/ui/overlays/task-overlay.d.ts.map +1 -1
- package/dist/ui/overlays/task-overlay.js.map +1 -1
- package/dist/ui/panels/conversation.d.ts +1 -1
- package/dist/ui/panels/conversation.d.ts.map +1 -1
- package/dist/ui/panels/conversation.js +1 -2
- package/dist/ui/panels/conversation.js.map +1 -1
- package/dist/ui/panels/metrics-dashboard.d.ts.map +1 -1
- package/dist/ui/panels/metrics-dashboard.js.map +1 -1
- package/dist/ui/panels/sleep-panel.js.map +1 -1
- package/dist/ui/panels/sticky-notes.d.ts.map +1 -1
- package/dist/ui/panels/sticky-notes.js.map +1 -1
- package/dist/ui/panels/task-list.d.ts +4 -2
- package/dist/ui/panels/task-list.d.ts.map +1 -1
- package/dist/ui/panels/task-list.js +41 -9
- package/dist/ui/panels/task-list.js.map +1 -1
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/types.d.ts +22 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui/types.js +2 -0
- package/dist/ui/types.js.map +1 -0
- package/package.json +19 -6
package/dist/metrics/store.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { getDb } from "../store/database.js";
|
|
2
2
|
export class MetricStore {
|
|
3
|
+
agentId;
|
|
4
|
+
constructor(agentId = "") {
|
|
5
|
+
this.agentId = agentId;
|
|
6
|
+
}
|
|
3
7
|
insert(taskId, machineId, point) {
|
|
4
8
|
const db = getDb();
|
|
5
|
-
db.prepare(`INSERT INTO metrics (task_id, machine_id, metric_name, value, step, timestamp)
|
|
6
|
-
VALUES (?, ?, ?, ?, ?, ?)`).run(taskId, machineId, point.metricName, point.value, point.step ?? null, point.timestamp);
|
|
9
|
+
db.prepare(`INSERT INTO metrics (task_id, machine_id, metric_name, value, step, timestamp, agent_id)
|
|
10
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(taskId, machineId, point.metricName, point.value, point.step ?? null, point.timestamp, this.agentId);
|
|
7
11
|
}
|
|
8
12
|
insertBatch(taskId, machineId, points) {
|
|
9
13
|
const db = getDb();
|
|
10
|
-
const stmt = db.prepare(`INSERT INTO metrics (task_id, machine_id, metric_name, value, step, timestamp)
|
|
11
|
-
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
14
|
+
const stmt = db.prepare(`INSERT INTO metrics (task_id, machine_id, metric_name, value, step, timestamp, agent_id)
|
|
15
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`);
|
|
12
16
|
const insertMany = db.transaction((pts) => {
|
|
13
17
|
for (const p of pts) {
|
|
14
|
-
stmt.run(taskId, machineId, p.metricName, p.value, p.step ?? null, p.timestamp);
|
|
18
|
+
stmt.run(taskId, machineId, p.metricName, p.value, p.step ?? null, p.timestamp, this.agentId);
|
|
15
19
|
}
|
|
16
20
|
});
|
|
17
21
|
insertMany(points);
|
|
@@ -20,9 +24,9 @@ export class MetricStore {
|
|
|
20
24
|
const db = getDb();
|
|
21
25
|
const row = db
|
|
22
26
|
.prepare(`SELECT * FROM metrics
|
|
23
|
-
WHERE task_id = ? AND metric_name = ?
|
|
27
|
+
WHERE task_id = ? AND metric_name = ? AND agent_id = ?
|
|
24
28
|
ORDER BY timestamp DESC LIMIT 1`)
|
|
25
|
-
.get(taskId, metricName);
|
|
29
|
+
.get(taskId, metricName, this.agentId);
|
|
26
30
|
if (!row)
|
|
27
31
|
return null;
|
|
28
32
|
return {
|
|
@@ -37,11 +41,11 @@ export class MetricStore {
|
|
|
37
41
|
const rows = db
|
|
38
42
|
.prepare(`SELECT * FROM (
|
|
39
43
|
SELECT * FROM metrics
|
|
40
|
-
WHERE task_id = ? AND metric_name = ?
|
|
44
|
+
WHERE task_id = ? AND metric_name = ? AND agent_id = ?
|
|
41
45
|
ORDER BY timestamp DESC
|
|
42
46
|
LIMIT ?
|
|
43
47
|
) ORDER BY timestamp ASC`)
|
|
44
|
-
.all(taskId, metricName, limit);
|
|
48
|
+
.all(taskId, metricName, this.agentId, limit);
|
|
45
49
|
return rows.map((row) => ({
|
|
46
50
|
metricName: row.metric_name,
|
|
47
51
|
value: row.value,
|
|
@@ -52,24 +56,24 @@ export class MetricStore {
|
|
|
52
56
|
getMetricNames(taskId) {
|
|
53
57
|
const db = getDb();
|
|
54
58
|
const rows = db
|
|
55
|
-
.prepare(`SELECT DISTINCT metric_name FROM metrics WHERE task_id = ?`)
|
|
56
|
-
.all(taskId);
|
|
59
|
+
.prepare(`SELECT DISTINCT metric_name FROM metrics WHERE task_id = ? AND agent_id = ?`)
|
|
60
|
+
.all(taskId, this.agentId);
|
|
57
61
|
return rows.map((r) => r.metric_name);
|
|
58
62
|
}
|
|
59
63
|
/** Get all distinct task IDs that have metrics */
|
|
60
64
|
getTaskIds() {
|
|
61
65
|
const db = getDb();
|
|
62
66
|
const rows = db
|
|
63
|
-
.prepare("SELECT DISTINCT task_id FROM metrics")
|
|
64
|
-
.all();
|
|
67
|
+
.prepare("SELECT DISTINCT task_id FROM metrics WHERE agent_id = ?")
|
|
68
|
+
.all(this.agentId);
|
|
65
69
|
return rows.map((r) => r.task_id);
|
|
66
70
|
}
|
|
67
|
-
/** Get all metric names across all tasks */
|
|
71
|
+
/** Get all metric names across all tasks for this agent */
|
|
68
72
|
getAllMetricNames() {
|
|
69
73
|
const db = getDb();
|
|
70
74
|
const rows = db
|
|
71
|
-
.prepare("SELECT DISTINCT metric_name FROM metrics")
|
|
72
|
-
.all();
|
|
75
|
+
.prepare("SELECT DISTINCT metric_name FROM metrics WHERE agent_id = ?")
|
|
76
|
+
.all(this.agentId);
|
|
73
77
|
return rows.map((r) => r.metric_name);
|
|
74
78
|
}
|
|
75
79
|
/** Get series for a metric name across all tasks, merged by timestamp */
|
|
@@ -78,11 +82,11 @@ export class MetricStore {
|
|
|
78
82
|
const rows = db
|
|
79
83
|
.prepare(`SELECT * FROM (
|
|
80
84
|
SELECT * FROM metrics
|
|
81
|
-
WHERE metric_name = ?
|
|
85
|
+
WHERE metric_name = ? AND agent_id = ?
|
|
82
86
|
ORDER BY timestamp DESC
|
|
83
87
|
LIMIT ?
|
|
84
88
|
) ORDER BY timestamp ASC`)
|
|
85
|
-
.all(metricName, limit);
|
|
89
|
+
.all(metricName, this.agentId, limit);
|
|
86
90
|
return rows.map((row) => ({
|
|
87
91
|
metricName: row.metric_name,
|
|
88
92
|
value: row.value,
|
|
@@ -90,19 +94,43 @@ export class MetricStore {
|
|
|
90
94
|
timestamp: row.timestamp,
|
|
91
95
|
}));
|
|
92
96
|
}
|
|
97
|
+
/** Get recent series for ALL metric names in a single query. Returns a map of name → values. */
|
|
98
|
+
getAllSeries(limit = 50) {
|
|
99
|
+
const db = getDb();
|
|
100
|
+
// Get the most recent `limit` points per metric name
|
|
101
|
+
const rows = db
|
|
102
|
+
.prepare(`SELECT metric_name, value FROM (
|
|
103
|
+
SELECT metric_name, value, timestamp,
|
|
104
|
+
ROW_NUMBER() OVER (PARTITION BY metric_name ORDER BY timestamp DESC) AS rn
|
|
105
|
+
FROM metrics
|
|
106
|
+
WHERE agent_id = ?
|
|
107
|
+
) WHERE rn <= ?
|
|
108
|
+
ORDER BY metric_name, timestamp ASC`)
|
|
109
|
+
.all(this.agentId, limit);
|
|
110
|
+
const result = new Map();
|
|
111
|
+
for (const row of rows) {
|
|
112
|
+
let arr = result.get(row.metric_name);
|
|
113
|
+
if (!arr) {
|
|
114
|
+
arr = [];
|
|
115
|
+
result.set(row.metric_name, arr);
|
|
116
|
+
}
|
|
117
|
+
arr.push(row.value);
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
93
121
|
/** Get a summary of final metrics for a task (latest value of each metric) */
|
|
94
122
|
getTaskSummary(taskId) {
|
|
95
123
|
const db = getDb();
|
|
96
124
|
const rows = db
|
|
97
125
|
.prepare(`SELECT metric_name,
|
|
98
|
-
(SELECT value FROM metrics m2 WHERE m2.task_id = m1.task_id AND m2.metric_name = m1.metric_name ORDER BY timestamp DESC LIMIT 1) as latest,
|
|
126
|
+
(SELECT value FROM metrics m2 WHERE m2.task_id = m1.task_id AND m2.metric_name = m1.metric_name AND m2.agent_id = ? ORDER BY timestamp DESC LIMIT 1) as latest,
|
|
99
127
|
MIN(value) as min_val,
|
|
100
128
|
MAX(value) as max_val,
|
|
101
129
|
COUNT(*) as cnt
|
|
102
130
|
FROM metrics m1
|
|
103
|
-
WHERE task_id = ?
|
|
131
|
+
WHERE task_id = ? AND agent_id = ?
|
|
104
132
|
GROUP BY metric_name`)
|
|
105
|
-
.all(taskId);
|
|
133
|
+
.all(this.agentId, taskId, this.agentId);
|
|
106
134
|
const summary = {};
|
|
107
135
|
for (const row of rows) {
|
|
108
136
|
summary[row.metric_name] = {
|
|
@@ -118,23 +146,59 @@ export class MetricStore {
|
|
|
118
146
|
clearTask(taskId) {
|
|
119
147
|
const db = getDb();
|
|
120
148
|
const result = db
|
|
121
|
-
.prepare("DELETE FROM metrics WHERE task_id = ?")
|
|
122
|
-
.run(taskId);
|
|
149
|
+
.prepare("DELETE FROM metrics WHERE task_id = ? AND agent_id = ?")
|
|
150
|
+
.run(taskId, this.agentId);
|
|
123
151
|
return result.changes;
|
|
124
152
|
}
|
|
125
|
-
/** Delete all metrics */
|
|
153
|
+
/** Delete all metrics for this agent */
|
|
126
154
|
clear() {
|
|
127
155
|
const db = getDb();
|
|
128
|
-
const result = db
|
|
156
|
+
const result = db
|
|
157
|
+
.prepare("DELETE FROM metrics WHERE agent_id = ?")
|
|
158
|
+
.run(this.agentId);
|
|
129
159
|
return result.changes;
|
|
130
160
|
}
|
|
161
|
+
/** Get latest value for every metric of a given task in a single query. */
|
|
162
|
+
getLatestAll(taskId) {
|
|
163
|
+
const db = getDb();
|
|
164
|
+
const rows = db
|
|
165
|
+
.prepare(`SELECT metric_name, value FROM metrics m1
|
|
166
|
+
WHERE task_id = ? AND agent_id = ?
|
|
167
|
+
AND timestamp = (
|
|
168
|
+
SELECT MAX(timestamp) FROM metrics m2
|
|
169
|
+
WHERE m2.task_id = m1.task_id AND m2.metric_name = m1.metric_name AND m2.agent_id = m1.agent_id
|
|
170
|
+
)`)
|
|
171
|
+
.all(taskId, this.agentId);
|
|
172
|
+
const result = {};
|
|
173
|
+
for (const row of rows) {
|
|
174
|
+
result[row.metric_name] = row.value;
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
/** Get the latest value for every metric name across all tasks in one query. */
|
|
179
|
+
getLatestPerMetric() {
|
|
180
|
+
const db = getDb();
|
|
181
|
+
const rows = db
|
|
182
|
+
.prepare(`SELECT metric_name, value FROM metrics m1
|
|
183
|
+
WHERE agent_id = ?
|
|
184
|
+
AND timestamp = (
|
|
185
|
+
SELECT MAX(timestamp) FROM metrics m2
|
|
186
|
+
WHERE m2.metric_name = m1.metric_name AND m2.agent_id = m1.agent_id
|
|
187
|
+
)`)
|
|
188
|
+
.all(this.agentId);
|
|
189
|
+
const result = {};
|
|
190
|
+
for (const row of rows) {
|
|
191
|
+
result[row.metric_name] = row.value;
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
131
195
|
/** Clean up metrics older than retentionDays */
|
|
132
196
|
cleanup(retentionDays) {
|
|
133
197
|
const db = getDb();
|
|
134
198
|
const cutoff = Date.now() - retentionDays * 24 * 60 * 60 * 1000;
|
|
135
199
|
const result = db
|
|
136
|
-
.prepare("DELETE FROM metrics WHERE timestamp < ?")
|
|
137
|
-
.run(cutoff);
|
|
200
|
+
.prepare("DELETE FROM metrics WHERE timestamp < ? AND agent_id = ?")
|
|
201
|
+
.run(cutoff, this.agentId);
|
|
138
202
|
return result.changes;
|
|
139
203
|
}
|
|
140
204
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/metrics/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAS7C,MAAM,OAAO,WAAW;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/metrics/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/notifications/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,GAIT,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type NotificationChannel = {
|
|
2
|
+
type: "desktop";
|
|
3
|
+
} | {
|
|
4
|
+
type: "webhook";
|
|
5
|
+
url: string;
|
|
6
|
+
method?: "GET" | "POST";
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
} | {
|
|
9
|
+
type: "command";
|
|
10
|
+
command: string;
|
|
11
|
+
};
|
|
12
|
+
export interface NotificationConfig {
|
|
13
|
+
channels: NotificationChannel[];
|
|
14
|
+
/** Only send notifications for these events. If empty, send all. */
|
|
15
|
+
events?: ("task_complete" | "task_failed" | "metric_threshold" | "agent_idle")[];
|
|
16
|
+
}
|
|
17
|
+
export interface NotificationPayload {
|
|
18
|
+
event: string;
|
|
19
|
+
title: string;
|
|
20
|
+
body: string;
|
|
21
|
+
machineId?: string;
|
|
22
|
+
pid?: number;
|
|
23
|
+
metrics?: Record<string, number>;
|
|
24
|
+
timestamp: number;
|
|
25
|
+
}
|
|
26
|
+
export declare class Notifier {
|
|
27
|
+
private config;
|
|
28
|
+
constructor(config: NotificationConfig);
|
|
29
|
+
notify(payload: NotificationPayload): Promise<void>;
|
|
30
|
+
notifyAll(payload: NotificationPayload): Promise<void>;
|
|
31
|
+
private sendToChannel;
|
|
32
|
+
private sendDesktop;
|
|
33
|
+
private sendWebhook;
|
|
34
|
+
private sendCommand;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=notifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../src/notifications/notifier.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC3F;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,oEAAoE;IACpE,MAAM,CAAC,EAAE,CAAC,eAAe,GAAG,aAAa,GAAG,kBAAkB,GAAG,YAAY,CAAC,EAAE,CAAC;CAClF;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAqB;gBAEvB,MAAM,EAAE,kBAAkB;IAIhC,MAAM,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD,SAAS,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;YAW9C,aAAa;IAuB3B,OAAO,CAAC,WAAW;YAuBL,WAAW;IAkCzB,OAAO,CAAC,WAAW;CA0BpB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { exec } from "node:child_process";
|
|
2
|
+
import { shellQuote, formatError } from "../ui/format.js";
|
|
3
|
+
export class Notifier {
|
|
4
|
+
config;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.config = config;
|
|
7
|
+
}
|
|
8
|
+
async notify(payload) {
|
|
9
|
+
const sends = this.config.channels.map((channel) => this.sendToChannel(channel, payload));
|
|
10
|
+
await Promise.allSettled(sends);
|
|
11
|
+
}
|
|
12
|
+
async notifyAll(payload) {
|
|
13
|
+
if (this.config.events &&
|
|
14
|
+
this.config.events.length > 0 &&
|
|
15
|
+
!this.config.events.includes(payload.event)) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
await this.notify(payload);
|
|
19
|
+
}
|
|
20
|
+
async sendToChannel(channel, payload) {
|
|
21
|
+
try {
|
|
22
|
+
switch (channel.type) {
|
|
23
|
+
case "desktop":
|
|
24
|
+
await this.sendDesktop(payload);
|
|
25
|
+
break;
|
|
26
|
+
case "webhook":
|
|
27
|
+
await this.sendWebhook(channel, payload);
|
|
28
|
+
break;
|
|
29
|
+
case "command":
|
|
30
|
+
await this.sendCommand(channel, payload);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
process.stderr.write(`[helios] notification error (${channel.type}): ${formatError(err)}\n`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
sendDesktop(payload) {
|
|
39
|
+
let cmd;
|
|
40
|
+
if (process.platform === "darwin") {
|
|
41
|
+
// AppleScript strings use backslash-escaped double quotes
|
|
42
|
+
const escapeAS = (s) => s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, " ");
|
|
43
|
+
const script = `display notification "${escapeAS(payload.body)}" with title "${escapeAS(payload.title)}"`;
|
|
44
|
+
cmd = `osascript -e ${shellQuote(script)}`;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
cmd = `notify-send ${shellQuote(payload.title)} ${shellQuote(payload.body)}`;
|
|
48
|
+
}
|
|
49
|
+
return new Promise((resolve) => {
|
|
50
|
+
exec(cmd, (err) => {
|
|
51
|
+
if (err) {
|
|
52
|
+
process.stderr.write(`[helios] desktop notification error: ${err.message}\n`);
|
|
53
|
+
}
|
|
54
|
+
resolve();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async sendWebhook(channel, payload) {
|
|
59
|
+
const method = channel.method ?? "POST";
|
|
60
|
+
const headers = {
|
|
61
|
+
"Content-Type": "application/json",
|
|
62
|
+
...channel.headers,
|
|
63
|
+
};
|
|
64
|
+
const controller = new AbortController();
|
|
65
|
+
const timeout = setTimeout(() => controller.abort(), 10_000);
|
|
66
|
+
try {
|
|
67
|
+
const options = {
|
|
68
|
+
method,
|
|
69
|
+
headers,
|
|
70
|
+
signal: controller.signal,
|
|
71
|
+
};
|
|
72
|
+
if (method === "POST") {
|
|
73
|
+
options.body = JSON.stringify(payload);
|
|
74
|
+
}
|
|
75
|
+
await fetch(channel.url, options);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
process.stderr.write(`[helios] webhook error (${channel.url}): ${formatError(err)}\n`);
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
clearTimeout(timeout);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
sendCommand(channel, payload) {
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
exec(channel.command, {
|
|
87
|
+
env: {
|
|
88
|
+
...process.env,
|
|
89
|
+
HELIOS_EVENT: payload.event,
|
|
90
|
+
HELIOS_TITLE: payload.title,
|
|
91
|
+
HELIOS_BODY: payload.body,
|
|
92
|
+
},
|
|
93
|
+
}, (err) => {
|
|
94
|
+
if (err) {
|
|
95
|
+
process.stderr.write(`[helios] command notification error: ${err.message}\n`);
|
|
96
|
+
}
|
|
97
|
+
resolve();
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=notifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifier.js","sourceRoot":"","sources":["../../src/notifications/notifier.ts"],"names":[],"mappings":"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"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAGA,qEAAqE;AACrE,eAAO,MAAM,UAAU,QAAwD,CAAC"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,qEAAqE;AACrE,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type ModelProvider, type ModelInfo, type ToolDefinition, type Session, type SessionConfig, type AgentEvent, type ReasoningEffort } from "../types.js";
|
|
1
|
+
import { type ModelProvider, type ModelInfo, type ToolDefinition, type Session, type SessionConfig, type AgentEvent, type ReasoningEffort, type Attachment } from "../types.js";
|
|
2
2
|
import type { AuthManager } from "../auth/auth-manager.js";
|
|
3
|
+
import { SessionStore } from "../../store/session-store.js";
|
|
3
4
|
type AuthMode = "cli" | "api_key";
|
|
4
5
|
export declare class ClaudeProvider implements ModelProvider {
|
|
5
6
|
readonly name: "claude";
|
|
@@ -17,7 +18,7 @@ export declare class ClaudeProvider implements ModelProvider {
|
|
|
17
18
|
private systemPrompts;
|
|
18
19
|
private cliPendingByName;
|
|
19
20
|
private cliToolResults;
|
|
20
|
-
constructor(authManager: AuthManager, preferredMode?: "cli" | "api");
|
|
21
|
+
constructor(authManager: AuthManager, preferredMode?: "cli" | "api", sessionStore?: SessionStore);
|
|
21
22
|
get currentAuthMode(): AuthMode;
|
|
22
23
|
/** Force a specific auth mode. Re-authenticates on next send. */
|
|
23
24
|
setPreferredAuthMode(mode: "cli" | "api"): void;
|
|
@@ -25,7 +26,7 @@ export declare class ClaudeProvider implements ModelProvider {
|
|
|
25
26
|
authenticate(): Promise<void>;
|
|
26
27
|
createSession(config: SessionConfig): Promise<Session>;
|
|
27
28
|
resumeSession(id: string): Promise<Session>;
|
|
28
|
-
send(session: Session, message: string, tools: ToolDefinition[]): AsyncGenerator<AgentEvent>;
|
|
29
|
+
send(session: Session, message: string, tools: ToolDefinition[], attachments?: Attachment[]): AsyncGenerator<AgentEvent>;
|
|
29
30
|
interrupt(_session: Session): void;
|
|
30
31
|
resetHistory(session: Session, briefingMessage: string): void;
|
|
31
32
|
closeSession(session: Session): Promise<void>;
|
|
@@ -33,9 +34,12 @@ export declare class ClaudeProvider implements ModelProvider {
|
|
|
33
34
|
private sendViaCli;
|
|
34
35
|
private doSendViaCli;
|
|
35
36
|
private sendViaRawApi;
|
|
37
|
+
/** Remove attachment content blocks from history so they aren't re-sent to the API. */
|
|
38
|
+
private stripAttachmentData;
|
|
36
39
|
private streamRawApi;
|
|
37
40
|
/** Strip the MCP server prefix (e.g. "mcp__helios__remote_exec" → "remote_exec") */
|
|
38
41
|
private stripMcpPrefix;
|
|
42
|
+
private _cliAvailable;
|
|
39
43
|
private isClaudeCliAvailable;
|
|
40
44
|
private buildMcpServer;
|
|
41
45
|
private buildZodSchema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/providers/claude/provider.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/providers/claude/provider.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAM5D,KAAK,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAqClC,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,QAAQ,CAAC,WAAW,YAAY;IAChC,YAAY,EAAE,MAAM,CAAiB;IACrC,eAAe,EAAE,eAAe,CAAY;IAE5C,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,mBAAmB,CAAyC;IACpE,OAAO,CAAC,aAAa,CAA6B;IAGlD,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,cAAc,CAAoE;gBAE9E,WAAW,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,YAAY,CAAC,EAAE,YAAY;IAMhG,IAAI,eAAe,IAAI,QAAQ,CAE9B;IAED,iEAAiE;IACjE,oBAAoB,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI;IAIzC,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAMnC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA4C7B,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IActD,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS1C,IAAI,CACT,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,cAAc,EAAE,EACvB,WAAW,CAAC,EAAE,UAAU,EAAE,GACzB,cAAc,CAAC,UAAU,CAAC;IAe7B,SAAS,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAUlC,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAQvD,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7C,WAAW,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YAS1B,UAAU;YAQV,YAAY;YAiFZ,aAAa;IAqI5B,uFAAuF;IACvF,OAAO,CAAC,mBAAmB;YAkBZ,YAAY;IA6L3B,oFAAoF;IACpF,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,cAAc;IAiCtB,OAAO,CAAC,cAAc;IA0CtB,OAAO,CAAE,aAAa;CA6DvB;;AAED,oEAAoE"}
|
|
@@ -35,9 +35,9 @@ export class ClaudeProvider {
|
|
|
35
35
|
// Keyed by original tool name → queue of call IDs (per-tool FIFO, not global FIFO)
|
|
36
36
|
cliPendingByName = new Map();
|
|
37
37
|
cliToolResults = [];
|
|
38
|
-
constructor(authManager, preferredMode) {
|
|
38
|
+
constructor(authManager, preferredMode, sessionStore) {
|
|
39
39
|
this.authManager = authManager;
|
|
40
|
-
this.sessionStore = new SessionStore();
|
|
40
|
+
this.sessionStore = sessionStore ?? new SessionStore();
|
|
41
41
|
this.preferredAuthMode = preferredMode === "cli" ? "cli" : preferredMode === "api" ? "api_key" : null;
|
|
42
42
|
}
|
|
43
43
|
get currentAuthMode() {
|
|
@@ -104,15 +104,18 @@ export class ClaudeProvider {
|
|
|
104
104
|
}
|
|
105
105
|
return session;
|
|
106
106
|
}
|
|
107
|
-
async *send(session, message, tools) {
|
|
107
|
+
async *send(session, message, tools, attachments) {
|
|
108
108
|
if (this.authMode === "cli") {
|
|
109
|
+
if (attachments?.length) {
|
|
110
|
+
process.stderr.write("[helios] Warning: file attachments are not supported in Claude CLI mode. Switch to API mode (--claude-mode api) to send files.\n");
|
|
111
|
+
}
|
|
109
112
|
yield* this.sendViaCli(session, message, tools);
|
|
110
113
|
}
|
|
111
114
|
else {
|
|
112
115
|
const creds = await this.authManager.getCredentials("claude");
|
|
113
116
|
if (!creds?.apiKey)
|
|
114
117
|
throw new Error("No API key — re-authenticate");
|
|
115
|
-
yield* this.sendViaRawApi(session, message, tools, creds.apiKey);
|
|
118
|
+
yield* this.sendViaRawApi(session, message, tools, creds.apiKey, attachments);
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
interrupt(_session) {
|
|
@@ -216,9 +219,25 @@ export class ClaudeProvider {
|
|
|
216
219
|
}
|
|
217
220
|
}
|
|
218
221
|
// ========== Raw API Mode (API Key) — Streaming ==========
|
|
219
|
-
async *sendViaRawApi(session, message, tools, apiKey) {
|
|
222
|
+
async *sendViaRawApi(session, message, tools, apiKey, attachments) {
|
|
220
223
|
const history = this.conversationHistory.get(session.id) ?? [];
|
|
221
|
-
|
|
224
|
+
// Build user message — plain text or multimodal with attachments
|
|
225
|
+
if (attachments && attachments.length > 0) {
|
|
226
|
+
const content = [];
|
|
227
|
+
for (const att of attachments) {
|
|
228
|
+
if (att.mediaType === "application/pdf") {
|
|
229
|
+
content.push({ type: "document", source: { type: "base64", media_type: att.mediaType, data: att.data } });
|
|
230
|
+
}
|
|
231
|
+
else if (att.mediaType.startsWith("image/")) {
|
|
232
|
+
content.push({ type: "image", source: { type: "base64", media_type: att.mediaType, data: att.data } });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
content.push({ type: "text", text: message });
|
|
236
|
+
history.push({ role: "user", content });
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
history.push({ role: "user", content: message });
|
|
240
|
+
}
|
|
222
241
|
const MAX_RETRIES = 3;
|
|
223
242
|
let continueLoop = true;
|
|
224
243
|
while (continueLoop) {
|
|
@@ -312,8 +331,25 @@ export class ClaudeProvider {
|
|
|
312
331
|
};
|
|
313
332
|
}
|
|
314
333
|
}
|
|
334
|
+
// Strip base64 data from attachment blocks so they aren't re-sent on every turn
|
|
335
|
+
this.stripAttachmentData(history);
|
|
315
336
|
this.conversationHistory.set(session.id, history);
|
|
316
337
|
}
|
|
338
|
+
/** Remove attachment content blocks from history so they aren't re-sent to the API. */
|
|
339
|
+
stripAttachmentData(history) {
|
|
340
|
+
for (const msg of history) {
|
|
341
|
+
if (!Array.isArray(msg.content))
|
|
342
|
+
continue;
|
|
343
|
+
msg.content = msg.content.map((block) => {
|
|
344
|
+
if ((block.type === "image" || block.type === "document") &&
|
|
345
|
+
"source" in block &&
|
|
346
|
+
block.source.data.length > 100) {
|
|
347
|
+
return { type: "text", text: `[${block.type} attachment stripped]` };
|
|
348
|
+
}
|
|
349
|
+
return block;
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
}
|
|
317
353
|
// ─── SSE Streaming for Raw API ──────────────────────
|
|
318
354
|
async *streamRawApi(session, apiKey, messages, tools) {
|
|
319
355
|
this.abortController = new AbortController();
|
|
@@ -483,14 +519,18 @@ export class ClaudeProvider {
|
|
|
483
519
|
const prefix = "mcp__helios__";
|
|
484
520
|
return name.startsWith(prefix) ? name.slice(prefix.length) : name;
|
|
485
521
|
}
|
|
522
|
+
_cliAvailable = null;
|
|
486
523
|
isClaudeCliAvailable() {
|
|
524
|
+
if (this._cliAvailable !== null)
|
|
525
|
+
return this._cliAvailable;
|
|
487
526
|
try {
|
|
488
527
|
execSync("which claude", { stdio: "ignore" });
|
|
489
|
-
|
|
528
|
+
this._cliAvailable = true;
|
|
490
529
|
}
|
|
491
530
|
catch {
|
|
492
|
-
|
|
531
|
+
this._cliAvailable = false;
|
|
493
532
|
}
|
|
533
|
+
return this._cliAvailable;
|
|
494
534
|
}
|
|
495
535
|
buildMcpServer(tools) {
|
|
496
536
|
const mcpTools = tools.map((t) => sdkTool(t.name, t.description, this.buildZodSchema(t), async (args) => {
|