@cgh567/agent 2.4.0 → 2.4.2
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/bin/helios +0 -0
- package/bin/helios-rpc-node-wrapper.cjs +0 -0
- package/bin/helios-rpc-wrapper.sh +0 -0
- package/daemon/adapters/helios-rpc-adapter.js +47 -25
- package/daemon/config/com.familiar.helios-daemon.plist +5 -0
- package/daemon/config/helios-daemon.service +4 -0
- package/daemon/context-enrichment.js +59 -21
- package/daemon/helios-api.js +149 -37
- package/daemon/helios-company-daemon.js +516 -124
- package/daemon/lib/harada/cascade-judge.js +12 -50
- package/daemon/lib/harada/mandala.js +20 -0
- package/daemon/lib/harada/pillar-dispatcher.js +1 -1
- package/daemon/lib/harada/project-factory.js +7 -2
- package/daemon/lib/hbo-bridge.js +31 -12
- package/daemon/lib/helios-hitl-host.js +15 -2
- package/daemon/lib/hitl-interaction-service.js +0 -0
- package/daemon/lib/memgraph-verify.js +38 -33
- package/daemon/lib/project-drift-detector.js +7 -17
- package/daemon/lib/project-semantic-updater.js +1 -14
- package/daemon/routes/channels.js +10 -5
- package/daemon/routes/harada-map.js +11 -48
- package/daemon/routes/hbo.js +89 -28
- package/daemon/routes/hitl.js +0 -0
- package/daemon/routes/project.js +4 -3
- package/daemon/routes/wizard.js +11 -4
- package/daemon/schema-migrations-hitl.js +0 -0
- package/extensions/001-tool-output-cap.ts +0 -0
- package/extensions/context-compaction.ts +45 -26
- package/extensions/cortex/activation-bridge.ts +5 -0
- package/extensions/cortex/learn.ts +26 -0
- package/extensions/email/backfill.ts +0 -0
- package/extensions/helios-governance/analysis/ambiguity.ts +0 -0
- package/extensions/helios-governance/analysis/compliance.ts +0 -0
- package/extensions/helios-governance/analysis/long-task-detector.ts +0 -0
- package/extensions/helios-governance/analysis/output-contract.ts +0 -0
- package/extensions/helios-governance/analysis/patterns.ts +0 -0
- package/extensions/helios-governance/analysis/preflight.ts +0 -0
- package/extensions/helios-governance/analysis/recurring-violations.ts +0 -0
- package/extensions/helios-governance/analysis/task-classification.ts +0 -0
- package/extensions/helios-governance/analysis/task-intent.ts +0 -0
- package/extensions/helios-governance/gates/high-impact.ts +1 -1
- package/extensions/helios-governance/handlers/_jiti-require.ts +15 -8
- package/extensions/helios-governance/handlers/proxy-test-detector.ts +0 -0
- package/extensions/hema-dispatch-v3/graph-memory.ts +10 -0
- package/extensions/hema-dispatch-v3/index.ts +59 -40
- package/extensions/lib/elo-engine.js +0 -0
- package/extensions/lib/elo-engine.test.js +0 -0
- package/extensions/memgraph-autostart.ts +13 -0
- package/extensions/neuroplastic-eval.ts +0 -0
- package/extensions/shadow-loop/index.ts +0 -0
- package/lib/brain-v2-budget.js +0 -0
- package/lib/brain-v2-circuit-breaker.js +0 -0
- package/lib/brain-v2.js +0 -0
- package/lib/broker/adaptive-throttle.js +0 -0
- package/lib/broker/batch-coalescer.js +0 -0
- package/lib/broker/bulkhead.js +0 -0
- package/lib/broker/channel-registry.js +0 -0
- package/lib/broker/circuit-breaker.js +0 -0
- package/lib/broker/evidence-cache.js +0 -0
- package/lib/broker/health-monitor.js +0 -0
- package/lib/broker/mage-queue.js +0 -0
- package/lib/broker/priority-queue.js +0 -0
- package/lib/broker/server.js.bak-error2-fix +0 -0
- package/lib/broker/session-registry.js +0 -0
- package/lib/broker/singleton-timers.js +0 -0
- package/lib/broker/types.d.ts +0 -0
- package/lib/broker/vegas-limit.js +0 -0
- package/lib/compression/dist/ccr-store.js +74 -0
- package/lib/compression/dist/content-router.js +115 -0
- package/lib/compression/dist/pipeline.js +113 -0
- package/lib/compression/dist/server.js +265 -0
- package/lib/compression/dist/smart-crusher.js +251 -0
- package/lib/context-budget.ts +0 -0
- package/lib/context-firewall.js +0 -0
- package/lib/crm/integration/triage-bridge.js +0 -0
- package/lib/email-utils.ts +0 -0
- package/lib/eval/__tests__/preflight-checker.test.ts +0 -0
- package/lib/eval/__tests__/task-instruction-parser.test.ts +0 -0
- package/lib/eval/__tests__/verifier-runner.test.ts +0 -0
- package/lib/eval/index.ts +0 -0
- package/lib/eval/preflight-checker.ts +0 -0
- package/lib/eval/task-domain-classifier.ts +0 -0
- package/lib/eval/task-instruction-parser.ts +0 -0
- package/lib/eval/verifier-runner.ts +0 -0
- package/lib/event-bus.d.ts +0 -0
- package/lib/governance-context-selector.ts +0 -0
- package/lib/graph/generate-extension-embeddings.js +0 -0
- package/lib/graph/generate-static-embeddings.js +0 -0
- package/lib/graph/lib/utils.js +1 -1
- package/lib/graph-audit.d.ts +0 -0
- package/lib/mesh-circuit-breaker.js +0 -0
- package/lib/mission-loop/lesson-extractor.ts +0 -0
- package/lib/mission-loop/mental-model-scorer.ts +0 -0
- package/lib/mission-loop/occ-detector.ts +0 -0
- package/lib/mission-loop/query-variants.ts +0 -0
- package/lib/mission-loop/verifier-check.ts +0 -0
- package/lib/skill-reference-builder.ts +0 -0
- package/lib/telemetry/token-breakdown.ts +0 -0
- package/lib/tool-compressor.ts +0 -0
- package/lib/triage-core/legal-routing.ts +0 -0
- package/lib/triage-core/mental-model/dunbar-classifier.ts +0 -0
- package/lib/triage-core/mental-model/enrich-all.ts +0 -0
- package/lib/triage-core/mental-model/identity-resolver.ts +0 -0
- package/lib/triage-core/mental-model/key-facts.ts +0 -0
- package/lib/triage-core/mental-model/model-assembler.ts +0 -0
- package/lib/triage-core/orchestrator.ts +0 -0
- package/lib/triage-core/orchestrator.ts.bak-r005-r006-r008 +0 -0
- package/package.json +10 -4
- package/skills/helios-business-operator/services/signals/upwork-signals.js +0 -0
- package/skills/talisman-ceo/SKILL.md +23 -25
- package/skills/talisman-comms/SKILL.md +5 -5
- package/skills/talisman-engineering/SKILL.md +5 -5
- package/skills/talisman-finance/SKILL.md +10 -8
- package/skills/talisman-marketing/SKILL.md +10 -10
- package/skills/talisman-sales/SKILL.md +12 -15
- package/skills/talisman-support/SKILL.md +5 -5
- package/agents/business/talisman-ceo.md +0 -183
- package/agents/business/talisman-comms.md +0 -257
- package/agents/business/talisman-cto.md +0 -153
- package/agents/business/talisman-finance.md +0 -246
- package/agents/business/talisman-marketing.md +0 -240
- package/agents/business/talisman-sales.md +0 -242
- package/agents/business/talisman-support.md +0 -236
- package/daemon/lib/approval-expiry.js +0 -162
- package/daemon/lib/blast-radius-analyzer.js +0 -75
- package/daemon/lib/domain-bootstrap-orchestrator.js +0 -267
- package/daemon/lib/forensic-log.js +0 -113
- package/daemon/lib/goal-research-pipeline.js +0 -644
- package/daemon/lib/harada/cascade-research-dispatcher.js +0 -261
- package/daemon/lib/headroom-middleware.js +0 -167
- package/daemon/lib/headroom-proxy-manager.js +0 -623
- package/daemon/lib/hed-engine.js +0 -307
- package/daemon/lib/mental-model-cache.js +0 -96
- package/daemon/lib/project-factory.js +0 -47
- package/daemon/lib/session-log-reader.js +0 -93
- package/daemon/routes/hed.js +0 -133
- package/lib/graph/learning/headroom-learn-bridge.js +0 -215
- package/skills/helios-bookkeeping/SKILL.md +0 -321
- package/skills/helios-briefer/SKILL.md +0 -44
- package/skills/helios-client-relations/SKILL.md +0 -322
- package/skills/helios-personal-triager/SKILL.md +0 -45
- package/skills/helios-recruitment/SKILL.md +0 -317
- package/skills/helios-relationship-nudger/SKILL.md +0 -77
- package/skills/helios-researcher/SKILL.md +0 -44
- package/skills/helios-scheduler/SKILL.md +0 -58
- package/skills/helios-tax-analyst/SKILL.md +0 -280
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SmartCrusher = exports.DEFAULT_CRUSHER_CONFIG = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* lib/compression/smart-crusher.ts
|
|
6
|
+
*
|
|
7
|
+
* TypeScript implementation of the Headroom SmartCrusher algorithm.
|
|
8
|
+
*
|
|
9
|
+
* SmartCrusher compresses JSON arrays by:
|
|
10
|
+
* 1. Lossless path: for homogeneous arrays, render as CSV+schema (removes
|
|
11
|
+
* repeated key names). Wins when savings ≥ 15%.
|
|
12
|
+
* 2. Lossy path: keep first 30% + last 15% + importance-scored middle 55%.
|
|
13
|
+
* Dropped rows are stored in the CCR store and retrievable on demand.
|
|
14
|
+
*
|
|
15
|
+
* Ported from headroom/crates/headroom-core (Rust) algorithm.
|
|
16
|
+
* No external dependencies — pure TypeScript.
|
|
17
|
+
*
|
|
18
|
+
* Every company's HBO data (signals, leads, pipeline, tasks, goals) flows
|
|
19
|
+
* through this compressor before reaching the LLM, reducing token cost
|
|
20
|
+
* by 70–92% for typical array payloads.
|
|
21
|
+
*/
|
|
22
|
+
const crypto_1 = require("crypto");
|
|
23
|
+
exports.DEFAULT_CRUSHER_CONFIG = {
|
|
24
|
+
minItemsToAnalyze: 5,
|
|
25
|
+
minCharsToCompress: 200,
|
|
26
|
+
maxItemsAfterCrush: 15,
|
|
27
|
+
firstFraction: 0.3,
|
|
28
|
+
lastFraction: 0.15,
|
|
29
|
+
losslessMinSavingsRatio: 0.15,
|
|
30
|
+
compactionCoreFieldFraction: 0.8,
|
|
31
|
+
};
|
|
32
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
33
|
+
function shortHash(data) {
|
|
34
|
+
return (0, crypto_1.createHash)('sha256').update(data).digest('hex').slice(0, 12);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Check if an array is homogeneous enough for lossless CSV compaction.
|
|
38
|
+
*
|
|
39
|
+
* Conditions (all must be true):
|
|
40
|
+
* 1. ≥90% of items are plain objects
|
|
41
|
+
* 2. At least 3 fields appear in ≥ coreFieldFraction of items
|
|
42
|
+
* (single shared field like 'id' is not enough structure for CSV)
|
|
43
|
+
* 3. Core fields cover ≥50% of the average object's field count
|
|
44
|
+
* (prevents trivial matches where most fields are non-shared)
|
|
45
|
+
*/
|
|
46
|
+
function isHomogeneousArray(items, coreFieldFraction) {
|
|
47
|
+
if (items.length === 0)
|
|
48
|
+
return { homogeneous: false, coreFields: [] };
|
|
49
|
+
const objectItems = items.filter((x) => x !== null && typeof x === 'object' && !Array.isArray(x));
|
|
50
|
+
if (objectItems.length / items.length < 0.9) {
|
|
51
|
+
return { homogeneous: false, coreFields: [] };
|
|
52
|
+
}
|
|
53
|
+
// Count field frequencies
|
|
54
|
+
const fieldFreq = new Map();
|
|
55
|
+
let totalFields = 0;
|
|
56
|
+
for (const obj of objectItems) {
|
|
57
|
+
const keys = Object.keys(obj);
|
|
58
|
+
totalFields += keys.length;
|
|
59
|
+
for (const key of keys) {
|
|
60
|
+
fieldFreq.set(key, (fieldFreq.get(key) ?? 0) + 1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Core fields: appear in ≥ coreFieldFraction of objects
|
|
64
|
+
const threshold = objectItems.length * coreFieldFraction;
|
|
65
|
+
const coreFields = [...fieldFreq.entries()]
|
|
66
|
+
.filter(([, count]) => count >= threshold)
|
|
67
|
+
.map(([key]) => key)
|
|
68
|
+
.sort();
|
|
69
|
+
// Gate 1: must have at least 3 core fields
|
|
70
|
+
// A single shared key (like 'id') is not enough structure for meaningful CSV
|
|
71
|
+
if (coreFields.length < 3) {
|
|
72
|
+
return { homogeneous: false, coreFields: [] };
|
|
73
|
+
}
|
|
74
|
+
// Gate 2: core fields must cover ≥50% of the average object's field count
|
|
75
|
+
// Prevents trivial CSV on objects where most fields are non-shared
|
|
76
|
+
const avgFieldCount = totalFields / objectItems.length;
|
|
77
|
+
const coverage = coreFields.length / avgFieldCount;
|
|
78
|
+
if (coverage < 0.5) {
|
|
79
|
+
return { homogeneous: false, coreFields: [] };
|
|
80
|
+
}
|
|
81
|
+
return { homogeneous: true, coreFields };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Lossless CSV compaction for homogeneous arrays.
|
|
85
|
+
* Format: header row + value rows, tab-separated within each row,
|
|
86
|
+
* pipe-separated rows. Significantly reduces token count for repeated keys.
|
|
87
|
+
*/
|
|
88
|
+
function losslessCsvCompress(items, coreFields) {
|
|
89
|
+
const header = coreFields.join('\t');
|
|
90
|
+
const rows = items.map((item) => coreFields
|
|
91
|
+
.map((f) => {
|
|
92
|
+
const v = item[f];
|
|
93
|
+
if (v === null || v === undefined)
|
|
94
|
+
return '';
|
|
95
|
+
if (typeof v === 'object')
|
|
96
|
+
return JSON.stringify(v);
|
|
97
|
+
return String(v);
|
|
98
|
+
})
|
|
99
|
+
.join('\t'));
|
|
100
|
+
return `[csv:${coreFields.length}cols×${items.length}rows]\n${header}\n${rows.join('\n')}`;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Score items for importance. Higher = more important to keep.
|
|
104
|
+
* Keeps items that: have errors, have non-null/non-zero values,
|
|
105
|
+
* or are at structural boundaries (first/last).
|
|
106
|
+
* Mid-range items are scored by field diversity (more unique values = more important).
|
|
107
|
+
*/
|
|
108
|
+
function scoreItems(items) {
|
|
109
|
+
return items.map((item) => {
|
|
110
|
+
let score = 0;
|
|
111
|
+
const str = JSON.stringify(item);
|
|
112
|
+
// Error/anomaly signals — always preserve
|
|
113
|
+
if (str.includes('"error"') ||
|
|
114
|
+
str.includes('"failed"') ||
|
|
115
|
+
str.includes('"ERROR"') ||
|
|
116
|
+
str.includes('"FAILED"')) {
|
|
117
|
+
score += 100;
|
|
118
|
+
}
|
|
119
|
+
// Non-trivial values (not null, not 0, not empty string)
|
|
120
|
+
const values = Object.values(item);
|
|
121
|
+
const nonTrivial = values.filter((v) => v !== null && v !== undefined && v !== '' && v !== 0 && v !== false).length;
|
|
122
|
+
score += (nonTrivial / Math.max(values.length, 1)) * 10;
|
|
123
|
+
// Field diversity (unique values signal interesting data)
|
|
124
|
+
const uniqueVals = new Set(values.map((v) => JSON.stringify(v))).size;
|
|
125
|
+
score += (uniqueVals / Math.max(values.length, 1)) * 5;
|
|
126
|
+
return score;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// ── Main SmartCrusher ─────────────────────────────────────────────────────────
|
|
130
|
+
class SmartCrusher {
|
|
131
|
+
cfg;
|
|
132
|
+
constructor(config = {}) {
|
|
133
|
+
this.cfg = { ...exports.DEFAULT_CRUSHER_CONFIG, ...config };
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Compress a JSON array string.
|
|
137
|
+
* If input is not a JSON array, returns passthrough.
|
|
138
|
+
* If array is too small, returns passthrough.
|
|
139
|
+
* Otherwise attempts lossless CSV then lossy sampling.
|
|
140
|
+
*/
|
|
141
|
+
compress(input, ccrStore) {
|
|
142
|
+
const passthrough = {
|
|
143
|
+
output: input,
|
|
144
|
+
compressed: false,
|
|
145
|
+
strategy: 'passthrough',
|
|
146
|
+
ccrHash: null,
|
|
147
|
+
rowsDropped: 0,
|
|
148
|
+
originalCount: 0,
|
|
149
|
+
keptCount: 0,
|
|
150
|
+
};
|
|
151
|
+
// Gate: too short
|
|
152
|
+
if (input.length < this.cfg.minCharsToCompress)
|
|
153
|
+
return passthrough;
|
|
154
|
+
// Parse JSON
|
|
155
|
+
let parsed;
|
|
156
|
+
try {
|
|
157
|
+
parsed = JSON.parse(input);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return passthrough;
|
|
161
|
+
}
|
|
162
|
+
// Must be a non-empty array
|
|
163
|
+
if (!Array.isArray(parsed) || parsed.length < this.cfg.minItemsToAnalyze) {
|
|
164
|
+
return passthrough;
|
|
165
|
+
}
|
|
166
|
+
const items = parsed;
|
|
167
|
+
// ── Lossless path ────────────────────────────────────────────────────────
|
|
168
|
+
const { homogeneous, coreFields } = isHomogeneousArray(items, this.cfg.compactionCoreFieldFraction);
|
|
169
|
+
if (homogeneous) {
|
|
170
|
+
const objectItems = items.filter((x) => x !== null && typeof x === 'object' && !Array.isArray(x));
|
|
171
|
+
const losslessOutput = losslessCsvCompress(objectItems, coreFields);
|
|
172
|
+
const savingsRatio = 1 - losslessOutput.length / input.length;
|
|
173
|
+
if (savingsRatio >= this.cfg.losslessMinSavingsRatio) {
|
|
174
|
+
return {
|
|
175
|
+
output: losslessOutput,
|
|
176
|
+
compressed: true,
|
|
177
|
+
strategy: 'lossless-csv',
|
|
178
|
+
ccrHash: null,
|
|
179
|
+
rowsDropped: 0,
|
|
180
|
+
originalCount: items.length,
|
|
181
|
+
keptCount: items.length,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// ── Lossy path ───────────────────────────────────────────────────────────
|
|
186
|
+
const n = items.length;
|
|
187
|
+
const maxKeep = this.cfg.maxItemsAfterCrush;
|
|
188
|
+
if (n <= maxKeep) {
|
|
189
|
+
// Already small enough — check if lossless was worth it
|
|
190
|
+
return passthrough;
|
|
191
|
+
}
|
|
192
|
+
const firstCount = Math.max(1, Math.floor(n * this.cfg.firstFraction));
|
|
193
|
+
const lastCount = Math.max(1, Math.floor(n * this.cfg.lastFraction));
|
|
194
|
+
const midBudget = Math.max(0, maxKeep - firstCount - lastCount);
|
|
195
|
+
const firstItems = items.slice(0, firstCount);
|
|
196
|
+
const lastItems = items.slice(n - lastCount);
|
|
197
|
+
const midItems = items.slice(firstCount, n - lastCount);
|
|
198
|
+
// Score mid-range items and keep the most important
|
|
199
|
+
const objectMidItems = midItems.filter((x) => x !== null && typeof x === 'object' && !Array.isArray(x));
|
|
200
|
+
let keptMid;
|
|
201
|
+
let droppedMid;
|
|
202
|
+
if (objectMidItems.length > 0 && midBudget > 0) {
|
|
203
|
+
const scores = scoreItems(objectMidItems);
|
|
204
|
+
const indexed = scores.map((s, i) => ({ s, i }));
|
|
205
|
+
indexed.sort((a, b) => b.s - a.s);
|
|
206
|
+
const keepIndices = new Set(indexed.slice(0, midBudget).map((x) => x.i));
|
|
207
|
+
keptMid = objectMidItems.filter((_, i) => keepIndices.has(i));
|
|
208
|
+
droppedMid = objectMidItems.filter((_, i) => !keepIndices.has(i));
|
|
209
|
+
// Dedup: remove items from keptMid that are identical to firstItems or lastItems
|
|
210
|
+
const existingSet = new Set([...firstItems, ...lastItems].map((x) => JSON.stringify(x)));
|
|
211
|
+
keptMid = keptMid.filter((x) => !existingSet.has(JSON.stringify(x)));
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
keptMid = midBudget > 0 ? midItems.slice(0, midBudget) : [];
|
|
215
|
+
droppedMid = midItems.slice(midBudget);
|
|
216
|
+
}
|
|
217
|
+
const keptItems = [...firstItems, ...keptMid, ...lastItems];
|
|
218
|
+
const droppedItems = droppedMid;
|
|
219
|
+
const rowsDropped = droppedItems.length;
|
|
220
|
+
// Store dropped rows in CCR
|
|
221
|
+
let ccrHash = null;
|
|
222
|
+
if (rowsDropped > 0 && ccrStore) {
|
|
223
|
+
const droppedJson = JSON.stringify(droppedItems);
|
|
224
|
+
ccrHash = shortHash(droppedJson);
|
|
225
|
+
ccrStore.set(ccrHash, droppedJson);
|
|
226
|
+
}
|
|
227
|
+
// Build output
|
|
228
|
+
const ccrMarker = ccrHash && rowsDropped > 0
|
|
229
|
+
? `\n{"_ccr_dropped":"<<ccr:${ccrHash} ${rowsDropped}_rows_offloaded>>"}`
|
|
230
|
+
: '';
|
|
231
|
+
const output = JSON.stringify(keptItems) + ccrMarker;
|
|
232
|
+
const savingsRatio = 1 - output.length / input.length;
|
|
233
|
+
// Only return lossy result if it actually saved something meaningful
|
|
234
|
+
if (savingsRatio < this.cfg.losslessMinSavingsRatio) {
|
|
235
|
+
// Clean up CCR entry — not worth it
|
|
236
|
+
if (ccrHash && ccrStore)
|
|
237
|
+
ccrStore.delete(ccrHash);
|
|
238
|
+
return passthrough;
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
output,
|
|
242
|
+
compressed: true,
|
|
243
|
+
strategy: 'lossy-sample',
|
|
244
|
+
ccrHash,
|
|
245
|
+
rowsDropped,
|
|
246
|
+
originalCount: items.length,
|
|
247
|
+
keptCount: keptItems.length,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
exports.SmartCrusher = SmartCrusher;
|
package/lib/context-budget.ts
CHANGED
|
File without changes
|
package/lib/context-firewall.js
CHANGED
|
File without changes
|
|
File without changes
|
package/lib/email-utils.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/eval/index.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/event-bus.d.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/graph/lib/utils.js
CHANGED
|
@@ -468,7 +468,7 @@ async function mgQueryAsync(cypher, params = {}, opts = {}) {
|
|
|
468
468
|
let _queryTimer;
|
|
469
469
|
const result = await Promise.race([
|
|
470
470
|
session.run(cleanCypher, params),
|
|
471
|
-
new Promise((_, rej) => { _queryTimer = setTimeout(() => rej(new Error('direct bolt query timeout (15s)')),
|
|
471
|
+
new Promise((_, rej) => { _queryTimer = setTimeout(() => rej(new Error('direct bolt query timeout (15s)')), parseInt(process.env.HELIOS_BOLT_QUERY_TIMEOUT_MS || '25000', 10)); })
|
|
472
472
|
]);
|
|
473
473
|
clearTimeout(_queryTimer);
|
|
474
474
|
const keys = result.records.length > 0 ? result.records[0].keys : [];
|
package/lib/graph-audit.d.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/lib/tool-compressor.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cgh567/agent",
|
|
3
|
-
"version": "2.4.
|
|
4
|
-
"description": "Helios agent runtime
|
|
3
|
+
"version": "2.4.2",
|
|
4
|
+
"description": "Helios agent runtime \u2014 full stack: extensions, skills, daemon, brain-v2, HEMA, governance",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
7
7
|
"helios-rpc": "./bin/helios-rpc.cjs",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "node scripts/build-brain-service.js",
|
|
13
|
+
"build:compression": "node node_modules/typescript/bin/tsc -p lib/compression/tsconfig.json",
|
|
13
14
|
"postinstall": "node postinstall.cjs || echo '[helios-agent] postinstall skipped'",
|
|
14
15
|
"patch-aliases": "node scripts/patch-pi-aliases.js",
|
|
15
16
|
"update": "helios update",
|
|
@@ -25,7 +26,12 @@
|
|
|
25
26
|
"test:hbo-wizard": "node tests/hbo/wizard-infra-gate.test.js && node tests/hbo/wizard-provider-validation.test.js && node tests/hbo/wizard-company-creation.test.js",
|
|
26
27
|
"test:harbor": "python3 -m pytest evals/harbor/ -v --timeout=60 --tb=short",
|
|
27
28
|
"test:harada": "python3 -m pytest evals/harbor/test_harada.py -v --timeout=60 --tb=short",
|
|
28
|
-
"test:harbor:all": "python3 -m pytest evals/harbor/ -v --timeout=60 --tb=short"
|
|
29
|
+
"test:harbor:all": "python3 -m pytest evals/harbor/ -v --timeout=60 --tb=short",
|
|
30
|
+
"test:compression": "python3 -m pytest evals/harbor/test_compression.py -v --tb=short",
|
|
31
|
+
"db:migrate-hbo": "node --experimental-sqlite daemon/db/hbo-core-migrate.js",
|
|
32
|
+
"db:migrate-all": "node --experimental-sqlite daemon/db/email-infrastructure-migrate.js && node --experimental-sqlite daemon/db/hbo-core-migrate.js",
|
|
33
|
+
"test:hbo-store": "node --experimental-sqlite lib/__tests__/hbo-core-store.test.js",
|
|
34
|
+
"test:hbo-fallback": "NODE_OPTIONS=--experimental-sqlite npx vitest run daemon/__tests__/hbo-core-fallback.test.js"
|
|
29
35
|
},
|
|
30
36
|
"pi": {
|
|
31
37
|
"extensions": [
|
|
@@ -79,6 +85,7 @@
|
|
|
79
85
|
"croner": "^9.0.0",
|
|
80
86
|
"ghost-cursor": "^1.4.2",
|
|
81
87
|
"googleapis": "^171.4.0",
|
|
88
|
+
"headroom-ai": "^0.22.4",
|
|
82
89
|
"httpsms": "^0.0.4",
|
|
83
90
|
"ioredis": "^5.10.1",
|
|
84
91
|
"js-tiktoken": "^1.0.21",
|
|
@@ -94,7 +101,6 @@
|
|
|
94
101
|
"tree-sitter-javascript": "^0.25.0",
|
|
95
102
|
"tree-sitter-python": "^0.25.0",
|
|
96
103
|
"tree-sitter-typescript": "^0.23.2",
|
|
97
|
-
"headroom-ai": "~0.27.0",
|
|
98
104
|
"write-file-atomic": "^7.0.1"
|
|
99
105
|
},
|
|
100
106
|
"devDependencies": {
|
|
File without changes
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
disableModelInvocation: true
|
|
3
3
|
name: talisman-ceo
|
|
4
|
-
description: CEO/Strategy agent
|
|
4
|
+
description: CEO/Strategy agent — weekly planning, goal decomposition, department delegation
|
|
5
5
|
when: Loaded by the CEO agent on all planning, review, and delegation tasks
|
|
6
6
|
adapter:
|
|
7
7
|
type: helios_rpc
|
|
8
8
|
skills:
|
|
9
9
|
- helios-prime
|
|
10
10
|
- helios-business-operator
|
|
11
|
-
agent_id: "agent:ceo"
|
|
12
|
-
company_id: talisman
|
|
13
11
|
departments:
|
|
14
12
|
- Strategy
|
|
15
13
|
- Engineering
|
|
@@ -30,14 +28,14 @@ If **YES** → Check the approval first. Do NOT start new planning cycles while
|
|
|
30
28
|
### ✅ Example of Good CEO Output:
|
|
31
29
|
```
|
|
32
30
|
Weekly Plan — Week of 2026-05-19
|
|
33
|
-
Goal:
|
|
31
|
+
Goal: Grow revenue 30% this quarter (30% complete)
|
|
34
32
|
|
|
35
33
|
Delegated This Week:
|
|
36
|
-
- Engineering: Implement
|
|
34
|
+
- Engineering: Implement key product feature (priority: P1)
|
|
37
35
|
- Sales: Follow up on 3 warm leads from last week (priority: P2)
|
|
38
|
-
- Marketing: Draft blog post
|
|
36
|
+
- Marketing: Draft blog post on company value proposition (priority: P3)
|
|
39
37
|
|
|
40
|
-
Pending Approvals: 1 (
|
|
38
|
+
Pending Approvals: 1 (review before EOD)
|
|
41
39
|
Budget Status: ✅ 42% used ($25/$60 monthly)
|
|
42
40
|
```
|
|
43
41
|
|
|
@@ -47,20 +45,20 @@ Budget Status: ✅ 42% used ($25/$60 monthly)
|
|
|
47
45
|
|
|
48
46
|
**Step 1**: Query Memgraph for all pending approvals and current goal progress
|
|
49
47
|
```cypher
|
|
50
|
-
MATCH (a:Approval {status: 'pending'}) RETURN a.title, a.type, a.createdAt;
|
|
51
|
-
MATCH (g:
|
|
48
|
+
MATCH (a:Approval {companyId: $HELIOS_COMPANY_ID, status: 'pending'}) RETURN a.title, a.type, a.createdAt;
|
|
49
|
+
MATCH (g:CompanyGoal {companyId: $HELIOS_COMPANY_ID}) WHERE g.status <> 'completed' RETURN g.title, g.status;
|
|
52
50
|
```
|
|
53
51
|
|
|
54
52
|
**Step 2**: Query all department statuses (Task counts by status for each department)
|
|
55
53
|
```cypher
|
|
56
|
-
MATCH (t:Task {companyId:
|
|
54
|
+
MATCH (t:Task {companyId: $HELIOS_COMPANY_ID})
|
|
57
55
|
WHERE t.status IN ['todo', 'in_progress', 'blocked']
|
|
58
56
|
RETURN t.status, count(t) AS count;
|
|
59
57
|
```
|
|
60
58
|
|
|
61
59
|
**Step 3**: Check budget health
|
|
62
|
-
```
|
|
63
|
-
|
|
60
|
+
```cypher
|
|
61
|
+
MATCH (bp:BudgetPolicy {companyId: $HELIOS_COMPANY_ID}) RETURN bp.scope, bp.agentId, bp.limitCents, bp.spentCents, bp.percentUsed, bp.status
|
|
64
62
|
```
|
|
65
63
|
|
|
66
64
|
---
|
|
@@ -99,7 +97,7 @@ Company Goal (e.g., "Ship Talisman v1.2")
|
|
|
99
97
|
└── Task (e.g., "Implement CSV parser for Chase format")
|
|
100
98
|
```
|
|
101
99
|
|
|
102
|
-
- Goals must have: `title`, `level`, `status`, `companyId:
|
|
100
|
+
- Goals must have: `title`, `level`, `status`, `companyId: $HELIOS_COMPANY_ID`, `ownerId` (dept)
|
|
103
101
|
- Tasks must have: `title`, `priority`, `acceptanceCriteria`, `assignedTo` (dept head), `dueDate`
|
|
104
102
|
- Never create a task without acceptance criteria
|
|
105
103
|
|
|
@@ -178,7 +176,7 @@ Approval gates. Your job is quality reviewer:
|
|
|
178
176
|
- Any external payment processing → Approval required
|
|
179
177
|
- New vendor agreements → Approval required
|
|
180
178
|
- Budget override requests → Approval required
|
|
181
|
-
- Approval node schema: `{title, type, status: 'pending', requestedBy, createdAt, companyId:
|
|
179
|
+
- Approval node schema: `{title, type, status: 'pending', requestedBy, createdAt, companyId: $HELIOS_COMPANY_ID}`
|
|
182
180
|
|
|
183
181
|
**Goal Rules:**
|
|
184
182
|
- Goals have 4 levels: Company → Department → Project → Task
|
|
@@ -192,7 +190,7 @@ Approval gates. Your job is quality reviewer:
|
|
|
192
190
|
- P2/P3 messages: handle in daily triage — batch processing OK
|
|
193
191
|
|
|
194
192
|
**Budget Rules:**
|
|
195
|
-
- Budget source of truth:
|
|
193
|
+
- Budget source of truth: Memgraph `MATCH (bp:BudgetPolicy {companyId: $HELIOS_COMPANY_ID})`
|
|
196
194
|
- Alert threshold: 80% of monthly budget consumed
|
|
197
195
|
- Hard stop: 95% — no new tasks until next billing cycle
|
|
198
196
|
- Finance dept owns budget recovery plans
|
|
@@ -217,10 +215,10 @@ Before completing any planning cycle:
|
|
|
217
215
|
```cypher
|
|
218
216
|
CREATE (wp:WeeklyPlan {
|
|
219
217
|
id: randomUUID(),
|
|
220
|
-
companyId:
|
|
218
|
+
companyId: $HELIOS_COMPANY_ID,
|
|
221
219
|
weekOf: date(),
|
|
222
220
|
status: 'active',
|
|
223
|
-
createdBy:
|
|
221
|
+
createdBy: $HELIOS_AGENT_ID,
|
|
224
222
|
createdAt: datetime()
|
|
225
223
|
});
|
|
226
224
|
```
|
|
@@ -229,7 +227,7 @@ CREATE (wp:WeeklyPlan {
|
|
|
229
227
|
```cypher
|
|
230
228
|
CREATE (t:Task {
|
|
231
229
|
id: randomUUID(),
|
|
232
|
-
companyId:
|
|
230
|
+
companyId: $HELIOS_COMPANY_ID,
|
|
233
231
|
title: $title,
|
|
234
232
|
priority: toInteger($priority),
|
|
235
233
|
status: 'todo',
|
|
@@ -238,7 +236,7 @@ CREATE (t:Task {
|
|
|
238
236
|
acceptanceCriteria: $criteria,
|
|
239
237
|
dueDate: $dueDate,
|
|
240
238
|
originKind: 'ceo_delegation',
|
|
241
|
-
createdBy:
|
|
239
|
+
createdBy: $HELIOS_AGENT_ID,
|
|
242
240
|
createdAt: localDateTime()
|
|
243
241
|
});
|
|
244
242
|
```
|
|
@@ -247,18 +245,18 @@ CREATE (t:Task {
|
|
|
247
245
|
```cypher
|
|
248
246
|
CREATE (a:Approval {
|
|
249
247
|
id: randomUUID(),
|
|
250
|
-
companyId:
|
|
248
|
+
companyId: $HELIOS_COMPANY_ID,
|
|
251
249
|
title: $title,
|
|
252
250
|
type: $type,
|
|
253
251
|
status: 'pending',
|
|
254
|
-
requestedBy:
|
|
252
|
+
requestedBy: $HELIOS_AGENT_ID,
|
|
255
253
|
createdAt: datetime()
|
|
256
254
|
});
|
|
257
255
|
```
|
|
258
256
|
|
|
259
257
|
### Flag At-Risk Goal
|
|
260
258
|
```cypher
|
|
261
|
-
MATCH (g:
|
|
259
|
+
MATCH (g:CompanyGoal {companyId: $HELIOS_COMPANY_ID, id: $goalId})
|
|
262
260
|
SET g.atRisk = true, g.atRiskReason = $reason, g.atRiskFlaggedAt = datetime();
|
|
263
261
|
```
|
|
264
262
|
|
|
@@ -269,17 +267,17 @@ When you need to create follow-up work or delegate, create a BusinessTask node:
|
|
|
269
267
|
```cypher
|
|
270
268
|
MERGE (bt:BusinessTask {id: $id})
|
|
271
269
|
ON CREATE SET
|
|
272
|
-
bt.companyId =
|
|
270
|
+
bt.companyId = $HELIOS_COMPANY_ID,
|
|
273
271
|
bt.title = $title,
|
|
274
272
|
bt.description = $description,
|
|
275
|
-
bt.assigneeId =
|
|
273
|
+
bt.assigneeId = $assigneeAgentId,
|
|
276
274
|
bt.priority = $priority,
|
|
277
275
|
bt.status = 'todo',
|
|
278
276
|
bt.goalId = $goalId,
|
|
279
277
|
bt.createdAt = datetime()
|
|
280
278
|
```
|
|
281
279
|
|
|
282
|
-
**Your agent ID**: `
|
|
280
|
+
**Your agent ID**: use `$HELIOS_AGENT_ID` env var
|
|
283
281
|
**Priority values**: `'critical'`, `'high'`, `'medium'`, `'low'`
|
|
284
282
|
**CRITICAL**: `assigneeId` must always be set — null means the task is never dispatched.
|
|
285
283
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
disableModelInvocation: true
|
|
3
3
|
name: talisman-comms
|
|
4
|
-
description: Communications/Triage department
|
|
4
|
+
description: Communications/Triage department — auto-routing, response drafting, and escalation via triage pipeline
|
|
5
5
|
when: Loaded by the Communications agent when running triage, classifying messages, or drafting responses
|
|
6
6
|
disable-model-invocation: true
|
|
7
7
|
---
|
|
@@ -37,7 +37,7 @@ cd ~/helios-agent && node extensions/email/commands/triage.js --limit 20 2>&1 |
|
|
|
37
37
|
|
|
38
38
|
**Step 2**: Query classification results — sort by priority
|
|
39
39
|
```
|
|
40
|
-
MATCH (m:Message {companyId:
|
|
40
|
+
MATCH (m:Message {companyId: $HELIOS_COMPANY_ID, processed: false})
|
|
41
41
|
RETURN m.priority, count(m) as count ORDER BY m.priority
|
|
42
42
|
```
|
|
43
43
|
|
|
@@ -83,17 +83,17 @@ When you need to create follow-up work or delegate, create a BusinessTask node:
|
|
|
83
83
|
```cypher
|
|
84
84
|
MERGE (bt:BusinessTask {id: $id})
|
|
85
85
|
ON CREATE SET
|
|
86
|
-
bt.companyId =
|
|
86
|
+
bt.companyId = $HELIOS_COMPANY_ID,
|
|
87
87
|
bt.title = $title,
|
|
88
88
|
bt.description = $description,
|
|
89
|
-
bt.assigneeId =
|
|
89
|
+
bt.assigneeId = $HELIOS_AGENT_ID,
|
|
90
90
|
bt.priority = $priority,
|
|
91
91
|
bt.status = 'todo',
|
|
92
92
|
bt.goalId = $goalId,
|
|
93
93
|
bt.createdAt = datetime()
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
**Your agent ID**: `
|
|
96
|
+
**Your agent ID**: use `$HELIOS_AGENT_ID` env var
|
|
97
97
|
**Priority values**: `'critical'`, `'high'`, `'medium'`, `'low'`
|
|
98
98
|
**CRITICAL**: `assigneeId` must always be set — null means the task is never dispatched.
|
|
99
99
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
disableModelInvocation: true
|
|
3
3
|
name: talisman-engineering
|
|
4
|
-
description: "Engineering department
|
|
5
|
-
when: Loaded by the CTO/Engineering agent when processing engineering tasks
|
|
4
|
+
description: "Engineering department — autonomous feature development from backlog to staging PR. Runs the complete pipeline: Plan → Code → Test → PR → Staging."
|
|
5
|
+
when: Loaded by the CTO/Engineering agent when processing engineering tasks
|
|
6
6
|
disable-model-invocation: true
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -261,17 +261,17 @@ When you need to create follow-up work or delegate, create a BusinessTask node:
|
|
|
261
261
|
```cypher
|
|
262
262
|
MERGE (bt:BusinessTask {id: $id})
|
|
263
263
|
ON CREATE SET
|
|
264
|
-
bt.companyId =
|
|
264
|
+
bt.companyId = $HELIOS_COMPANY_ID,
|
|
265
265
|
bt.title = $title,
|
|
266
266
|
bt.description = $description,
|
|
267
|
-
bt.assigneeId =
|
|
267
|
+
bt.assigneeId = $HELIOS_AGENT_ID,
|
|
268
268
|
bt.priority = $priority,
|
|
269
269
|
bt.status = 'todo',
|
|
270
270
|
bt.goalId = $goalId,
|
|
271
271
|
bt.createdAt = datetime()
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
-
**Your agent ID**: `
|
|
274
|
+
**Your agent ID**: use `$HELIOS_AGENT_ID` env var
|
|
275
275
|
**Priority values**: `'critical'`, `'high'`, `'medium'`, `'low'`
|
|
276
276
|
**CRITICAL**: `assigneeId` must always be set — null means the task is never dispatched.
|
|
277
277
|
|