@obsidicore/cascade-engine 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/LICENSE +21 -0
- package/dist/cascade/checkpoints.d.ts +55 -0
- package/dist/cascade/checkpoints.js +123 -0
- package/dist/cascade/checkpoints.js.map +1 -0
- package/dist/cascade/engine.d.ts +72 -0
- package/dist/cascade/engine.js +170 -0
- package/dist/cascade/engine.js.map +1 -0
- package/dist/cascade/gates.d.ts +46 -0
- package/dist/cascade/gates.js +199 -0
- package/dist/cascade/gates.js.map +1 -0
- package/dist/cascade/research.d.ts +50 -0
- package/dist/cascade/research.js +127 -0
- package/dist/cascade/research.js.map +1 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.js +165 -0
- package/dist/cli.js.map +1 -0
- package/dist/control/kalman.d.ts +53 -0
- package/dist/control/kalman.js +83 -0
- package/dist/control/kalman.js.map +1 -0
- package/dist/control/pid.d.ts +57 -0
- package/dist/control/pid.js +95 -0
- package/dist/control/pid.js.map +1 -0
- package/dist/control/stability.d.ts +42 -0
- package/dist/control/stability.js +117 -0
- package/dist/control/stability.js.map +1 -0
- package/dist/db/index.d.ts +26 -0
- package/dist/db/index.js +116 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.sql +282 -0
- package/dist/graph/amem.d.ts +80 -0
- package/dist/graph/amem.js +190 -0
- package/dist/graph/amem.js.map +1 -0
- package/dist/graph/entities.d.ts +66 -0
- package/dist/graph/entities.js +187 -0
- package/dist/graph/entities.js.map +1 -0
- package/dist/graph/queries.d.ts +48 -0
- package/dist/graph/queries.js +176 -0
- package/dist/graph/queries.js.map +1 -0
- package/dist/hitl/dashboard.d.ts +51 -0
- package/dist/hitl/dashboard.js +135 -0
- package/dist/hitl/dashboard.js.map +1 -0
- package/dist/hitl/interventions.d.ts +36 -0
- package/dist/hitl/interventions.js +150 -0
- package/dist/hitl/interventions.js.map +1 -0
- package/dist/hitl/steering.d.ts +37 -0
- package/dist/hitl/steering.js +118 -0
- package/dist/hitl/steering.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +701 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/consolidation.d.ts +51 -0
- package/dist/memory/consolidation.js +122 -0
- package/dist/memory/consolidation.js.map +1 -0
- package/dist/memory/ncd.d.ts +40 -0
- package/dist/memory/ncd.js +90 -0
- package/dist/memory/ncd.js.map +1 -0
- package/dist/memory/sm2.d.ts +44 -0
- package/dist/memory/sm2.js +119 -0
- package/dist/memory/sm2.js.map +1 -0
- package/dist/memory/tiers.d.ts +49 -0
- package/dist/memory/tiers.js +145 -0
- package/dist/memory/tiers.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +6 -0
- package/dist/server.js.map +1 -0
- package/dist/trust/ingestion.d.ts +38 -0
- package/dist/trust/ingestion.js +147 -0
- package/dist/trust/ingestion.js.map +1 -0
- package/dist/trust/patterns.d.ts +26 -0
- package/dist/trust/patterns.js +78 -0
- package/dist/trust/patterns.js.map +1 -0
- package/dist/trust/scoring.d.ts +39 -0
- package/dist/trust/scoring.js +206 -0
- package/dist/trust/scoring.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HITL Intervention Taxonomy
|
|
3
|
+
*
|
|
4
|
+
* BLOCKING: Round 0 hypothesis (always), hypothesis drift >0.6, round boundaries (15min timeout)
|
|
5
|
+
* ADVISORY: trust <0.4 (2min), circuit breaker open (1min), confidence <0.5 (3min)
|
|
6
|
+
* SILENT: search planning (log only)
|
|
7
|
+
*
|
|
8
|
+
* Each intervention point has a timeout — if no human response, auto-proceeds.
|
|
9
|
+
*/
|
|
10
|
+
import { getDb } from '../db/index.js';
|
|
11
|
+
const RULES = [
|
|
12
|
+
// BLOCKING: Round 0 hypothesis — always require human approval
|
|
13
|
+
{
|
|
14
|
+
category: 'initial_hypothesis',
|
|
15
|
+
level: 'blocking',
|
|
16
|
+
timeoutMinutes: 15,
|
|
17
|
+
check: (cascadeId, ctx) => {
|
|
18
|
+
const db = getDb();
|
|
19
|
+
const cascade = db.prepare('SELECT current_round FROM cascades WHERE id = ?').get(cascadeId);
|
|
20
|
+
if (!cascade || cascade.current_round > 0)
|
|
21
|
+
return { triggered: false, description: '', context: {} };
|
|
22
|
+
const hyps = db.prepare('SELECT id, statement, affinity FROM hypotheses WHERE cascade_id = ? AND status = \'proposed\'')
|
|
23
|
+
.all(cascadeId);
|
|
24
|
+
if (hyps.length === 0)
|
|
25
|
+
return { triggered: false, description: '', context: {} };
|
|
26
|
+
return {
|
|
27
|
+
triggered: true,
|
|
28
|
+
description: `Round 0: ${hyps.length} initial hypotheses need approval before research begins.`,
|
|
29
|
+
context: { hypotheses: hyps },
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
// BLOCKING: Hypothesis drift — affinity changed > 0.6 from original
|
|
34
|
+
{
|
|
35
|
+
category: 'hypothesis_drift',
|
|
36
|
+
level: 'blocking',
|
|
37
|
+
timeoutMinutes: 15,
|
|
38
|
+
check: (cascadeId, _ctx) => {
|
|
39
|
+
const db = getDb();
|
|
40
|
+
const drifted = db.prepare(`SELECT id, statement, affinity FROM hypotheses
|
|
41
|
+
WHERE cascade_id = ? AND ABS(affinity - 0.5) > 0.6 AND status = 'testing'`)
|
|
42
|
+
.all(cascadeId);
|
|
43
|
+
if (drifted.length === 0)
|
|
44
|
+
return { triggered: false, description: '', context: {} };
|
|
45
|
+
return {
|
|
46
|
+
triggered: true,
|
|
47
|
+
description: `${drifted.length} hypotheses have drifted significantly. Review before proceeding.`,
|
|
48
|
+
context: { drifted },
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
// ADVISORY: Low trust findings
|
|
53
|
+
{
|
|
54
|
+
category: 'low_trust',
|
|
55
|
+
level: 'advisory',
|
|
56
|
+
timeoutMinutes: 2,
|
|
57
|
+
check: (cascadeId, _ctx) => {
|
|
58
|
+
const db = getDb();
|
|
59
|
+
const lowTrust = db.prepare(`SELECT id, claim, trust_composite FROM findings
|
|
60
|
+
WHERE cascade_id = ? AND trust_composite < 0.4 AND quarantined = 0 AND human_reviewed = 0
|
|
61
|
+
ORDER BY trust_composite ASC LIMIT 5`)
|
|
62
|
+
.all(cascadeId);
|
|
63
|
+
if (lowTrust.length === 0)
|
|
64
|
+
return { triggered: false, description: '', context: {} };
|
|
65
|
+
return {
|
|
66
|
+
triggered: true,
|
|
67
|
+
description: `${lowTrust.length} findings have low trust scores (<0.4).`,
|
|
68
|
+
context: { lowTrustFindings: lowTrust },
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
// ADVISORY: Low overall confidence
|
|
73
|
+
{
|
|
74
|
+
category: 'low_confidence',
|
|
75
|
+
level: 'advisory',
|
|
76
|
+
timeoutMinutes: 3,
|
|
77
|
+
check: (cascadeId, _ctx) => {
|
|
78
|
+
const db = getDb();
|
|
79
|
+
const avgConf = db.prepare('SELECT AVG(confidence) as v FROM findings WHERE cascade_id = ? AND quarantined = 0')
|
|
80
|
+
.get(cascadeId)?.v;
|
|
81
|
+
if (!avgConf || avgConf >= 0.5)
|
|
82
|
+
return { triggered: false, description: '', context: {} };
|
|
83
|
+
return {
|
|
84
|
+
triggered: true,
|
|
85
|
+
description: `Average confidence is ${(avgConf * 100).toFixed(1)}% — below 50% threshold.`,
|
|
86
|
+
context: { avgConfidence: avgConf },
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
/**
|
|
92
|
+
* Check all intervention rules and return any that are triggered.
|
|
93
|
+
*/
|
|
94
|
+
export function checkInterventions(cascadeId, context = {}) {
|
|
95
|
+
const triggered = [];
|
|
96
|
+
for (const rule of RULES) {
|
|
97
|
+
const result = rule.check(cascadeId, context);
|
|
98
|
+
if (result.triggered) {
|
|
99
|
+
triggered.push({
|
|
100
|
+
id: `${cascadeId}-${rule.category}-${Date.now()}`,
|
|
101
|
+
cascadeId,
|
|
102
|
+
level: rule.level,
|
|
103
|
+
category: rule.category,
|
|
104
|
+
description: result.description,
|
|
105
|
+
context: result.context,
|
|
106
|
+
timeoutMinutes: rule.timeoutMinutes,
|
|
107
|
+
createdAt: new Date().toISOString(),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return triggered;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Check if there are any blocking interventions that must be resolved.
|
|
115
|
+
*/
|
|
116
|
+
export function hasBlockingInterventions(cascadeId) {
|
|
117
|
+
const interventions = checkInterventions(cascadeId);
|
|
118
|
+
return interventions.some(i => i.level === 'blocking');
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Format interventions for display.
|
|
122
|
+
*/
|
|
123
|
+
export function formatInterventions(interventions) {
|
|
124
|
+
if (interventions.length === 0)
|
|
125
|
+
return 'No interventions needed.';
|
|
126
|
+
const lines = [];
|
|
127
|
+
const blocking = interventions.filter(i => i.level === 'blocking');
|
|
128
|
+
const advisory = interventions.filter(i => i.level === 'advisory');
|
|
129
|
+
const silent = interventions.filter(i => i.level === 'silent');
|
|
130
|
+
if (blocking.length > 0) {
|
|
131
|
+
lines.push('== BLOCKING (requires approval) ==');
|
|
132
|
+
for (const i of blocking) {
|
|
133
|
+
lines.push(` [${i.category}] ${i.description} (timeout: ${i.timeoutMinutes}min)`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (advisory.length > 0) {
|
|
137
|
+
lines.push('-- ADVISORY (auto-proceeds after timeout) --');
|
|
138
|
+
for (const i of advisory) {
|
|
139
|
+
lines.push(` [${i.category}] ${i.description} (timeout: ${i.timeoutMinutes}min)`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (silent.length > 0) {
|
|
143
|
+
lines.push('.. SILENT (logged only) ..');
|
|
144
|
+
for (const i of silent) {
|
|
145
|
+
lines.push(` [${i.category}] ${i.description}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return lines.join('\n');
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=interventions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interventions.js","sourceRoot":"","sources":["../../src/hitl/interventions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Steering — Human redirects cascade mid-research
|
|
3
|
+
*
|
|
4
|
+
* Steer events are appended to the database and picked up on the next iteration.
|
|
5
|
+
* Types: redirect, narrow, broaden, add_question, drop_hypothesis, approve, reject
|
|
6
|
+
*
|
|
7
|
+
* "Ralph Loop": instruction → NDJSON injection → agent pivots on next iteration
|
|
8
|
+
*/
|
|
9
|
+
export type SteerType = 'redirect' | 'narrow' | 'broaden' | 'add_question' | 'drop_hypothesis' | 'approve' | 'reject';
|
|
10
|
+
export interface SteerEvent {
|
|
11
|
+
id: number;
|
|
12
|
+
cascadeId: string;
|
|
13
|
+
eventType: SteerType;
|
|
14
|
+
instruction: string;
|
|
15
|
+
targetId?: string;
|
|
16
|
+
applied: boolean;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Submit a steering event.
|
|
21
|
+
*/
|
|
22
|
+
export declare function submitSteer(cascadeId: string, eventType: SteerType, instruction: string, targetId?: string): number;
|
|
23
|
+
/**
|
|
24
|
+
* Get pending (unapplied) steer events for a cascade.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getPendingSteers(cascadeId: string): SteerEvent[];
|
|
27
|
+
/**
|
|
28
|
+
* Apply a steer event and take action.
|
|
29
|
+
* Returns a description of what changed.
|
|
30
|
+
*/
|
|
31
|
+
export declare function applySteer(eventId: number): string;
|
|
32
|
+
/**
|
|
33
|
+
* Apply all pending steer events for a cascade.
|
|
34
|
+
* Called at the start of each cascade iteration.
|
|
35
|
+
*/
|
|
36
|
+
export declare function applyAllPendingSteers(cascadeId: string): string[];
|
|
37
|
+
//# sourceMappingURL=steering.d.ts.map
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Steering — Human redirects cascade mid-research
|
|
3
|
+
*
|
|
4
|
+
* Steer events are appended to the database and picked up on the next iteration.
|
|
5
|
+
* Types: redirect, narrow, broaden, add_question, drop_hypothesis, approve, reject
|
|
6
|
+
*
|
|
7
|
+
* "Ralph Loop": instruction → NDJSON injection → agent pivots on next iteration
|
|
8
|
+
*/
|
|
9
|
+
import { getDb } from '../db/index.js';
|
|
10
|
+
/**
|
|
11
|
+
* Submit a steering event.
|
|
12
|
+
*/
|
|
13
|
+
export function submitSteer(cascadeId, eventType, instruction, targetId) {
|
|
14
|
+
const db = getDb();
|
|
15
|
+
const result = db.prepare(`INSERT INTO steer_events (cascade_id, event_type, instruction, target_id)
|
|
16
|
+
VALUES (?, ?, ?, ?)`).run(cascadeId, eventType, instruction, targetId);
|
|
17
|
+
return Number(result.lastInsertRowid);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get pending (unapplied) steer events for a cascade.
|
|
21
|
+
*/
|
|
22
|
+
export function getPendingSteers(cascadeId) {
|
|
23
|
+
const db = getDb();
|
|
24
|
+
const rows = db.prepare(`SELECT * FROM steer_events
|
|
25
|
+
WHERE cascade_id = ? AND applied = 0
|
|
26
|
+
ORDER BY created_at ASC`).all(cascadeId);
|
|
27
|
+
return rows.map(rowToSteerEvent);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Apply a steer event and take action.
|
|
31
|
+
* Returns a description of what changed.
|
|
32
|
+
*/
|
|
33
|
+
export function applySteer(eventId) {
|
|
34
|
+
const db = getDb();
|
|
35
|
+
const event = db.prepare('SELECT * FROM steer_events WHERE id = ?').get(eventId);
|
|
36
|
+
if (!event)
|
|
37
|
+
return 'Steer event not found.';
|
|
38
|
+
if (event.applied)
|
|
39
|
+
return 'Steer event already applied.';
|
|
40
|
+
let result;
|
|
41
|
+
switch (event.event_type) {
|
|
42
|
+
case 'redirect':
|
|
43
|
+
// Change the cascade's primary question
|
|
44
|
+
db.prepare('UPDATE cascades SET question = ?, updated_at = datetime(\'now\') WHERE id = ?')
|
|
45
|
+
.run(event.instruction, event.cascade_id);
|
|
46
|
+
result = `Redirected cascade to: "${event.instruction}"`;
|
|
47
|
+
break;
|
|
48
|
+
case 'narrow':
|
|
49
|
+
// Add a scope constraint to the plan
|
|
50
|
+
result = `Narrowed scope: "${event.instruction}". Agent should focus on this aspect.`;
|
|
51
|
+
break;
|
|
52
|
+
case 'broaden':
|
|
53
|
+
result = `Broadened scope: "${event.instruction}". Agent should explore wider.`;
|
|
54
|
+
break;
|
|
55
|
+
case 'add_question':
|
|
56
|
+
// Create a new thread for the question
|
|
57
|
+
db.prepare(`INSERT INTO threads (id, cascade_id, question, type, status)
|
|
58
|
+
VALUES (?, ?, ?, 'discovery', 'pending')`)
|
|
59
|
+
.run(`steer-${eventId}`, event.cascade_id, event.instruction);
|
|
60
|
+
result = `Added research question: "${event.instruction}"`;
|
|
61
|
+
break;
|
|
62
|
+
case 'drop_hypothesis':
|
|
63
|
+
if (event.target_id) {
|
|
64
|
+
db.prepare("UPDATE hypotheses SET status = 'archived', updated_at = datetime('now') WHERE id = ?")
|
|
65
|
+
.run(event.target_id);
|
|
66
|
+
result = `Archived hypothesis ${event.target_id}: "${event.instruction}"`;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
result = 'No target hypothesis specified.';
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
case 'approve':
|
|
73
|
+
if (event.target_id) {
|
|
74
|
+
db.prepare("UPDATE findings SET quarantined = 0, human_reviewed = 1, retrieval_weight = 1.0 WHERE id = ?")
|
|
75
|
+
.run(event.target_id);
|
|
76
|
+
result = `Approved finding ${event.target_id}`;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
result = 'No target finding specified.';
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
case 'reject':
|
|
83
|
+
if (event.target_id) {
|
|
84
|
+
db.prepare('DELETE FROM findings WHERE id = ?').run(event.target_id);
|
|
85
|
+
result = `Rejected and removed finding ${event.target_id}`;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
result = 'No target finding specified.';
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
default:
|
|
92
|
+
result = `Unknown steer type: ${event.event_type}`;
|
|
93
|
+
}
|
|
94
|
+
// Mark as applied
|
|
95
|
+
db.prepare('UPDATE steer_events SET applied = 1 WHERE id = ?').run(eventId);
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Apply all pending steer events for a cascade.
|
|
100
|
+
* Called at the start of each cascade iteration.
|
|
101
|
+
*/
|
|
102
|
+
export function applyAllPendingSteers(cascadeId) {
|
|
103
|
+
const pending = getPendingSteers(cascadeId);
|
|
104
|
+
return pending.map(event => applySteer(event.id));
|
|
105
|
+
}
|
|
106
|
+
// --- Helpers ---
|
|
107
|
+
function rowToSteerEvent(row) {
|
|
108
|
+
return {
|
|
109
|
+
id: row.id,
|
|
110
|
+
cascadeId: row.cascade_id,
|
|
111
|
+
eventType: row.event_type,
|
|
112
|
+
instruction: row.instruction,
|
|
113
|
+
targetId: row.target_id,
|
|
114
|
+
applied: row.applied === 1,
|
|
115
|
+
createdAt: row.created_at,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=steering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steering.js","sourceRoot":"","sources":["../../src/hitl/steering.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Research Cascade MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Stdio-based MCP server providing 12+ tools for progressive research
|
|
6
|
+
* with knowledge graph, trust scoring, and self-regulation.
|
|
7
|
+
*
|
|
8
|
+
* NEVER console.log() — corrupts stdio JSON-RPC. Use console.error() only.
|
|
9
|
+
*/
|
|
10
|
+
export declare function startServer(): Promise<void>;
|
|
11
|
+
export default startServer;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|