@stackbilt/aegis-core 0.6.5 → 0.7.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/cli/aegis.mjs +356 -0
- package/package.json +9 -1
- package/schema.sql +4 -0
- package/src/adapters/voice/cloudflare-agent.ts +0 -0
- package/src/auth.ts +13 -5
- package/src/bluesky.ts +0 -0
- package/src/claude-tools/content.ts +0 -0
- package/src/claude-tools/email.ts +0 -0
- package/src/claude.ts +133 -268
- package/src/codebeast.ts +0 -0
- package/src/composite.ts +49 -79
- package/src/content/column.ts +0 -0
- package/src/content/hero-image.ts +0 -0
- package/src/content/index.ts +0 -0
- package/src/content/journal.ts +0 -0
- package/src/content/roundtable.ts +0 -0
- package/src/contracts/agenda-item.contract.ts +0 -0
- package/src/contracts/cc-task.contract.ts +0 -0
- package/src/contracts/goal.contract.ts +0 -0
- package/src/contracts/memory-entry.contract.ts +0 -0
- package/src/core.ts +5 -0
- package/src/dashboard.ts +0 -0
- package/src/decision-docs.ts +0 -0
- package/src/dispatch.ts +0 -0
- package/src/durable-objects/chat-session-auth.ts +20 -0
- package/src/durable-objects/chat-session.ts +251 -0
- package/src/edge-env.ts +0 -0
- package/src/exports.ts +0 -0
- package/src/github-projects.ts +0 -0
- package/src/groq.ts +61 -113
- package/src/index.ts +4 -0
- package/src/kernel/argus-actions.ts +0 -0
- package/src/kernel/argus-correlation.ts +0 -0
- package/src/kernel/board.ts +0 -0
- package/src/kernel/classify-memory-topic.ts +0 -0
- package/src/kernel/disambiguation.ts +55 -0
- package/src/kernel/dispatch.ts +59 -44
- package/src/kernel/dynamic-tools.ts +30 -52
- package/src/kernel/executor-port.ts +0 -0
- package/src/kernel/executor-router.ts +0 -0
- package/src/kernel/executors/claude.ts +1 -0
- package/src/kernel/executors/direct.ts +14 -0
- package/src/kernel/executors/workers-ai.ts +5 -0
- package/src/kernel/grounding/fabrication-detector.ts +0 -0
- package/src/kernel/grounding/fanout.ts +0 -0
- package/src/kernel/grounding/semantic-sanhedrin.ts +0 -0
- package/src/kernel/grounding/verify.ts +0 -0
- package/src/kernel/grounding-layer.ts +0 -0
- package/src/kernel/insight-cache.ts +0 -0
- package/src/kernel/memory/episodic.ts +3 -1
- package/src/kernel/memory/insights.ts +0 -0
- package/src/kernel/memory-guardrails.ts +0 -0
- package/src/kernel/memory-service.ts +0 -0
- package/src/kernel/patterns.ts +0 -0
- package/src/kernel/port.ts +0 -0
- package/src/kernel/provider-factory.ts +0 -0
- package/src/kernel/resilience.ts +0 -0
- package/src/kernel/router.ts +33 -11
- package/src/kernel/scheduled/agent-dispatch.ts +0 -0
- package/src/kernel/scheduled/argus-analytics.ts +0 -0
- package/src/kernel/scheduled/argus-heartbeat.ts +0 -0
- package/src/kernel/scheduled/argus-notify.ts +0 -0
- package/src/kernel/scheduled/board-sync.ts +0 -0
- package/src/kernel/scheduled/ci-watcher.ts +0 -0
- package/src/kernel/scheduled/content-drip.ts +0 -0
- package/src/kernel/scheduled/content.ts +0 -0
- package/src/kernel/scheduled/conversation-facts.ts +9 -7
- package/src/kernel/scheduled/cost-report.ts +0 -0
- package/src/kernel/scheduled/dev-activity.ts +0 -0
- package/src/kernel/scheduled/digest.ts +30 -3
- package/src/kernel/scheduled/dreaming/agenda-triage.ts +0 -0
- package/src/kernel/scheduled/dreaming/facts.ts +0 -0
- package/src/kernel/scheduled/dreaming/index.ts +0 -0
- package/src/kernel/scheduled/dreaming/llm.ts +9 -5
- package/src/kernel/scheduled/dreaming/pattern-synthesis.ts +0 -0
- package/src/kernel/scheduled/dreaming/persona.ts +0 -0
- package/src/kernel/scheduled/dreaming/symbolic.ts +0 -0
- package/src/kernel/scheduled/dreaming/task-proposals.ts +0 -0
- package/src/kernel/scheduled/entropy.ts +0 -0
- package/src/kernel/scheduled/feed-watcher.ts +0 -0
- package/src/kernel/scheduled/inbox-processor.ts +0 -0
- package/src/kernel/scheduled/issue-proposer.ts +0 -0
- package/src/kernel/scheduled/issue-watcher.ts +0 -0
- package/src/kernel/scheduled/pr-automerge.ts +0 -0
- package/src/kernel/scheduled/product-health.ts +0 -0
- package/src/kernel/scheduled/self-improvement.ts +0 -0
- package/src/kernel/scheduled/social-engage.ts +12 -8
- package/src/kernel/scheduled/task-audit.ts +0 -0
- package/src/kernel/types.ts +6 -0
- package/src/landing.ts +0 -0
- package/src/lib/audit-chain/chain.ts +0 -0
- package/src/lib/audit-chain/types.ts +0 -0
- package/src/lib/observability/errors.ts +0 -0
- package/src/operator/config.ts +0 -0
- package/src/operator/persona.ts +0 -0
- package/src/operator/prompt-builder.ts +3 -0
- package/src/pulse.ts +0 -0
- package/src/routes/bluesky.ts +0 -0
- package/src/routes/chat-ws.ts +17 -0
- package/src/routes/codebeast.ts +0 -0
- package/src/routes/content.ts +0 -0
- package/src/routes/dynamic-tools.ts +0 -0
- package/src/routes/observability.ts +0 -0
- package/src/routes/operator-logs.ts +0 -0
- package/src/routes/pages.ts +5 -1
- package/src/schema-enums.ts +0 -0
- package/src/task-intelligence.ts +0 -0
- package/src/types.ts +6 -0
- package/src/ui.ts +594 -2
- package/src/version.ts +3 -3
- package/src/wiki/client.ts +0 -0
- package/src/wiki/types.ts +0 -0
package/cli/aegis.mjs
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// AEGIS CLI: zero-dependency terminal chat over /chat/ws.
|
|
3
|
+
// Requires Node >= 21 for the built-in WebSocket client.
|
|
4
|
+
|
|
5
|
+
import { readFileSync } from 'node:fs';
|
|
6
|
+
import { dirname, join } from 'node:path';
|
|
7
|
+
import readline from 'node:readline';
|
|
8
|
+
import { stdin, stdout } from 'node:process';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
|
|
11
|
+
const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json'), 'utf8'));
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
const has = (flag) => args.includes(flag);
|
|
14
|
+
const argVal = (flag) => {
|
|
15
|
+
const i = args.indexOf(flag);
|
|
16
|
+
return i >= 0 ? args[i + 1] : undefined;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const HELP = `AEGIS CLI
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
aegis [--host <host>] [--token <token>] [--exec <executor>] [--conversation <uuid>] [--verbose] [--quick]
|
|
23
|
+
|
|
24
|
+
Options:
|
|
25
|
+
--host <host> AEGIS worker host or URL. Defaults to AEGIS_HOST or aegis.stackbilt.dev.
|
|
26
|
+
--token <token> Bearer token. Defaults to AEGIS_TOKEN.
|
|
27
|
+
--exec <executor> Force an executor for this session. Use auto to let the kernel route.
|
|
28
|
+
--conversation <uuid> Resume an existing conversation.
|
|
29
|
+
--verbose Show executor/classification/cost metadata after each response.
|
|
30
|
+
--quick Skip the startup executor picker.
|
|
31
|
+
--version Print version and exit.
|
|
32
|
+
--help Print this help and exit.
|
|
33
|
+
|
|
34
|
+
REPL commands:
|
|
35
|
+
/new /exec [name] /verbose /clear /help /quit
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
if (has('--help') || has('-h')) {
|
|
39
|
+
console.log(HELP.trimEnd());
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
if (has('--version') || has('-v')) {
|
|
43
|
+
console.log(pkg.version);
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
if (typeof WebSocket === 'undefined') {
|
|
47
|
+
console.error('AEGIS CLI requires Node >= 21 for built-in WebSocket support.');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let conversationId = argVal('--conversation') || null;
|
|
52
|
+
let executor = normalizeExecutor(argVal('--exec'));
|
|
53
|
+
let verbose = has('--verbose');
|
|
54
|
+
const quick = has('--quick') || Boolean(argVal('--exec'));
|
|
55
|
+
const token = argVal('--token') || process.env.AEGIS_TOKEN;
|
|
56
|
+
const host = normalizeHost(argVal('--host') || process.env.AEGIS_HOST || 'aegis.stackbilt.dev');
|
|
57
|
+
|
|
58
|
+
if (!token) {
|
|
59
|
+
console.error('Missing AEGIS_TOKEN. Set AEGIS_TOKEN or pass --token <token>.');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const c = {
|
|
64
|
+
reset: '\x1b[0m',
|
|
65
|
+
dim: '\x1b[2m',
|
|
66
|
+
bold: '\x1b[1m',
|
|
67
|
+
cyan: '\x1b[36m',
|
|
68
|
+
green: '\x1b[32m',
|
|
69
|
+
yellow: '\x1b[33m',
|
|
70
|
+
red: '\x1b[31m',
|
|
71
|
+
};
|
|
72
|
+
const paint = (color, s) => `${color}${s}${c.reset}`;
|
|
73
|
+
|
|
74
|
+
const EXECUTORS = [
|
|
75
|
+
{ value: null, label: 'auto', hint: 'kernel routes automatically' },
|
|
76
|
+
{ value: 'workers_ai', label: 'workers_ai', hint: 'Cloudflare Workers AI' },
|
|
77
|
+
{ value: 'gpt_oss', label: 'gpt_oss', hint: 'tool-capable standard path' },
|
|
78
|
+
{ value: 'groq', label: 'groq', hint: 'fast simple responses' },
|
|
79
|
+
{ value: 'claude', label: 'claude', hint: 'reliability-critical work' },
|
|
80
|
+
{ value: 'claude_opus', label: 'claude_opus', hint: 'frontier tier' },
|
|
81
|
+
{ value: 'composite', label: 'composite', hint: 'multi-model synthesis' },
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
const EXECUTOR_VALUES = new Set(EXECUTORS.map((e) => e.value).filter(Boolean));
|
|
85
|
+
|
|
86
|
+
function normalizeExecutor(value) {
|
|
87
|
+
if (!value || value === 'auto') return null;
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function normalizeHost(value) {
|
|
92
|
+
return value.replace(/^https?:\/\//, '').replace(/^wss?:\/\//, '').replace(/\/+$/, '');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function printBanner() {
|
|
96
|
+
console.log('');
|
|
97
|
+
console.log(paint(c.cyan, 'AEGIS'));
|
|
98
|
+
console.log(paint(c.dim, 'persistent agent terminal'));
|
|
99
|
+
console.log('');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function select(title, options, initial = 0) {
|
|
103
|
+
return new Promise((resolve) => {
|
|
104
|
+
let idx = initial;
|
|
105
|
+
readline.emitKeypressEvents(stdin);
|
|
106
|
+
const wasRaw = Boolean(stdin.isRaw);
|
|
107
|
+
if (stdin.isTTY) stdin.setRawMode(true);
|
|
108
|
+
|
|
109
|
+
const draw = (first = false) => {
|
|
110
|
+
if (!first) stdout.write(`\x1b[${options.length + 1}A`);
|
|
111
|
+
stdout.write(`${c.bold}?${c.reset} ${title}\x1b[K\n`);
|
|
112
|
+
options.forEach((o, i) => {
|
|
113
|
+
const on = i === idx;
|
|
114
|
+
const pointer = on ? paint(c.cyan, '>') : ' ';
|
|
115
|
+
const label = on ? paint(c.cyan, o.label) : o.label;
|
|
116
|
+
const hint = o.hint ? paint(c.dim, ` - ${o.hint}`) : '';
|
|
117
|
+
stdout.write(`${pointer} ${label}${hint}\x1b[K\n`);
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const done = (value) => {
|
|
122
|
+
stdin.removeListener('keypress', onKey);
|
|
123
|
+
if (stdin.isTTY) stdin.setRawMode(wasRaw);
|
|
124
|
+
resolve(value);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const onKey = (_str, key) => {
|
|
128
|
+
if (!key) return;
|
|
129
|
+
if (key.name === 'up' || key.name === 'k') {
|
|
130
|
+
idx = (idx - 1 + options.length) % options.length;
|
|
131
|
+
draw();
|
|
132
|
+
} else if (key.name === 'down' || key.name === 'j') {
|
|
133
|
+
idx = (idx + 1) % options.length;
|
|
134
|
+
draw();
|
|
135
|
+
} else if (key.name === 'return') {
|
|
136
|
+
done(options[idx].value);
|
|
137
|
+
} else if (key.name === 'escape') {
|
|
138
|
+
done(options[initial].value);
|
|
139
|
+
} else if (key.ctrl && key.name === 'c') {
|
|
140
|
+
stdout.write('\n');
|
|
141
|
+
process.exit(0);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
draw(true);
|
|
146
|
+
stdin.on('keypress', onKey);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function makeSpinner(label) {
|
|
151
|
+
const frames = ['-', '\\', '|', '/'];
|
|
152
|
+
let i = 0;
|
|
153
|
+
let timer = null;
|
|
154
|
+
return {
|
|
155
|
+
start() {
|
|
156
|
+
if (timer) return;
|
|
157
|
+
timer = setInterval(() => {
|
|
158
|
+
stdout.write(`\r${paint(c.cyan, frames[i = (i + 1) % frames.length])} ${paint(c.dim, label)}\x1b[K`);
|
|
159
|
+
}, 90);
|
|
160
|
+
},
|
|
161
|
+
stop() {
|
|
162
|
+
if (timer) clearInterval(timer);
|
|
163
|
+
timer = null;
|
|
164
|
+
stdout.write('\r\x1b[K');
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const fmtCost = (n) => (typeof n === 'number' ? `$${n.toFixed(5)}` : `$${n ?? 0}`);
|
|
170
|
+
const think = makeSpinner('thinking');
|
|
171
|
+
let rl = null;
|
|
172
|
+
let conn = null;
|
|
173
|
+
|
|
174
|
+
function connect() {
|
|
175
|
+
const q = new URLSearchParams({ token });
|
|
176
|
+
if (conversationId) q.set('conversationId', conversationId);
|
|
177
|
+
const ws = new WebSocket(`wss://${host}/chat/ws?${q.toString()}`, 'aegis-chat');
|
|
178
|
+
let streaming = false;
|
|
179
|
+
let pending = false;
|
|
180
|
+
let firstDelta = false;
|
|
181
|
+
|
|
182
|
+
ws.addEventListener('open', () => {
|
|
183
|
+
think.stop();
|
|
184
|
+
console.log(`${paint(c.green, 'connected')} ${paint(c.dim, host)}`);
|
|
185
|
+
console.log(`${paint(c.dim, 'executor')} ${executor || 'auto'}`);
|
|
186
|
+
console.log(`${paint(c.dim, 'conversation')} ${conversationId ?? 'new on first message'}`);
|
|
187
|
+
console.log(paint(c.dim, '/new /exec [name] /verbose /clear /help /quit'));
|
|
188
|
+
startRepl();
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
ws.addEventListener('message', (ev) => {
|
|
192
|
+
let frame;
|
|
193
|
+
try {
|
|
194
|
+
frame = JSON.parse(typeof ev.data === 'string' ? ev.data : ev.data.toString());
|
|
195
|
+
} catch {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
switch (frame.type) {
|
|
200
|
+
case 'history':
|
|
201
|
+
if (Array.isArray(frame.messages) && frame.messages.length) {
|
|
202
|
+
console.log(paint(c.dim, `${frame.messages.length} prior messages loaded`));
|
|
203
|
+
}
|
|
204
|
+
break;
|
|
205
|
+
case 'start':
|
|
206
|
+
if (frame.conversationId) conversationId = frame.conversationId;
|
|
207
|
+
streaming = true;
|
|
208
|
+
firstDelta = false;
|
|
209
|
+
break;
|
|
210
|
+
case 'delta':
|
|
211
|
+
if (!frame.text) break;
|
|
212
|
+
if (!firstDelta) {
|
|
213
|
+
think.stop();
|
|
214
|
+
stdout.write(`${paint(c.cyan, 'aegis')} `);
|
|
215
|
+
firstDelta = true;
|
|
216
|
+
}
|
|
217
|
+
stdout.write(frame.text);
|
|
218
|
+
break;
|
|
219
|
+
case 'done':
|
|
220
|
+
if (!firstDelta) think.stop();
|
|
221
|
+
streaming = false;
|
|
222
|
+
pending = false;
|
|
223
|
+
stdout.write('\n');
|
|
224
|
+
if (verbose && frame.metadata) {
|
|
225
|
+
const md = frame.metadata;
|
|
226
|
+
console.log(paint(c.dim, `${md.executor} / ${md.classification} / ${fmtCost(md.cost)} / ${md.latencyMs ?? '?'}ms${md.grounded !== undefined ? ` / grounded=${md.grounded}` : ''}`));
|
|
227
|
+
if (md.unverifiedClaims?.length) console.log(paint(c.yellow, `${md.unverifiedClaims.length} unverified claim(s)`));
|
|
228
|
+
}
|
|
229
|
+
rl?.prompt();
|
|
230
|
+
break;
|
|
231
|
+
case 'error':
|
|
232
|
+
think.stop();
|
|
233
|
+
streaming = false;
|
|
234
|
+
pending = false;
|
|
235
|
+
console.log(`\n${paint(c.red, 'error:')} ${frame.error}`);
|
|
236
|
+
rl?.prompt();
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
ws.addEventListener('error', () => {
|
|
242
|
+
think.stop();
|
|
243
|
+
console.log(paint(c.red, 'websocket error'));
|
|
244
|
+
});
|
|
245
|
+
ws.addEventListener('close', (ev) => {
|
|
246
|
+
think.stop();
|
|
247
|
+
console.log(paint(c.dim, `disconnected${ev.reason ? ` (${ev.reason})` : ''}`));
|
|
248
|
+
process.exit(ev.code === 1000 ? 0 : 1);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
send(text) {
|
|
253
|
+
if (pending || streaming) {
|
|
254
|
+
console.log(paint(c.dim, 'still responding'));
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
pending = true;
|
|
258
|
+
think.start();
|
|
259
|
+
ws.send(JSON.stringify({
|
|
260
|
+
type: 'message',
|
|
261
|
+
text,
|
|
262
|
+
conversationId,
|
|
263
|
+
eventId: crypto.randomUUID(),
|
|
264
|
+
...(executor ? { executor } : {}),
|
|
265
|
+
}));
|
|
266
|
+
},
|
|
267
|
+
close() {
|
|
268
|
+
ws.close(1000, 'bye');
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function startRepl() {
|
|
274
|
+
rl = readline.createInterface({ input: stdin, output: stdout, prompt: `${paint(c.green, '>')} ` });
|
|
275
|
+
rl.prompt();
|
|
276
|
+
|
|
277
|
+
rl.on('line', async (line) => {
|
|
278
|
+
const text = line.trim();
|
|
279
|
+
if (!text) {
|
|
280
|
+
rl.prompt();
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (text.startsWith('/')) {
|
|
285
|
+
const [cmd, arg] = text.slice(1).split(/\s+/);
|
|
286
|
+
switch (cmd) {
|
|
287
|
+
case 'new':
|
|
288
|
+
conversationId = null;
|
|
289
|
+
console.log(paint(c.dim, 'new conversation on next message'));
|
|
290
|
+
break;
|
|
291
|
+
case 'exec':
|
|
292
|
+
if (arg) {
|
|
293
|
+
const next = normalizeExecutor(arg);
|
|
294
|
+
if (next && !EXECUTOR_VALUES.has(next)) {
|
|
295
|
+
console.log(paint(c.dim, `unknown executor: ${arg}`));
|
|
296
|
+
} else {
|
|
297
|
+
executor = next;
|
|
298
|
+
console.log(paint(c.dim, `executor -> ${executor || 'auto'}`));
|
|
299
|
+
}
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
if (!stdin.isTTY) {
|
|
303
|
+
console.log(paint(c.dim, `usage: /exec <${EXECUTORS.map((e) => e.label).join('|')}>`));
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
rl.removeAllListeners('line');
|
|
307
|
+
rl.close();
|
|
308
|
+
executor = await select('executor', EXECUTORS, Math.max(0, EXECUTORS.findIndex((e) => e.value === executor)));
|
|
309
|
+
console.log(paint(c.dim, `executor -> ${executor || 'auto'}`));
|
|
310
|
+
startRepl();
|
|
311
|
+
return;
|
|
312
|
+
case 'verbose':
|
|
313
|
+
verbose = !verbose;
|
|
314
|
+
console.log(paint(c.dim, `verbose ${verbose ? 'on' : 'off'}`));
|
|
315
|
+
break;
|
|
316
|
+
case 'clear':
|
|
317
|
+
stdout.write('\x1b[2J\x1b[H');
|
|
318
|
+
break;
|
|
319
|
+
case 'help':
|
|
320
|
+
console.log(paint(c.dim, '/new /exec [name] /verbose /clear /help /quit'));
|
|
321
|
+
break;
|
|
322
|
+
case 'quit':
|
|
323
|
+
case 'q':
|
|
324
|
+
case 'exit':
|
|
325
|
+
conn.close();
|
|
326
|
+
return;
|
|
327
|
+
default:
|
|
328
|
+
console.log(paint(c.dim, `unknown command /${cmd}`));
|
|
329
|
+
}
|
|
330
|
+
rl.prompt();
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
conn.send(text);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
rl.on('SIGINT', () => conn.close());
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
async function main() {
|
|
341
|
+
if (executor && !EXECUTOR_VALUES.has(executor)) {
|
|
342
|
+
console.error(`Unknown executor: ${executor}`);
|
|
343
|
+
process.exit(1);
|
|
344
|
+
}
|
|
345
|
+
printBanner();
|
|
346
|
+
if (!executor && !quick && stdin.isTTY) {
|
|
347
|
+
executor = await select('Launch executor', EXECUTORS, 0);
|
|
348
|
+
}
|
|
349
|
+
think.start();
|
|
350
|
+
conn = connect();
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
main().catch((err) => {
|
|
354
|
+
console.error(`aegis: ${err.message}`);
|
|
355
|
+
process.exit(1);
|
|
356
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackbilt/aegis-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Persistent AI agent framework for Cloudflare Workers. Multi-tier memory, autonomous goals, dreaming cycles, MCP native.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
"type": "module",
|
|
15
15
|
"main": "src/exports.ts",
|
|
16
16
|
"types": "src/exports.ts",
|
|
17
|
+
"bin": {
|
|
18
|
+
"aegis": "./cli/aegis.mjs"
|
|
19
|
+
},
|
|
17
20
|
"exports": {
|
|
18
21
|
".": "./src/exports.ts",
|
|
19
22
|
"./core": "./src/core.ts",
|
|
@@ -24,6 +27,7 @@
|
|
|
24
27
|
"./kernel/dispatch": "./src/kernel/dispatch.ts",
|
|
25
28
|
"./kernel/router": "./src/kernel/router.ts",
|
|
26
29
|
"./kernel/types": "./src/kernel/types.ts",
|
|
30
|
+
"./kernel/disambiguation": "./src/kernel/disambiguation.ts",
|
|
27
31
|
"./kernel/memory": "./src/kernel/memory/index.ts",
|
|
28
32
|
"./kernel/memory-adapter": "./src/kernel/memory-adapter.ts",
|
|
29
33
|
"./kernel/resilience": "./src/kernel/resilience.ts",
|
|
@@ -50,6 +54,7 @@
|
|
|
50
54
|
"./routes/health": "./src/routes/health.ts",
|
|
51
55
|
"./routes/sessions": "./src/routes/sessions.ts",
|
|
52
56
|
"./routes/messages": "./src/routes/messages.ts",
|
|
57
|
+
"./routes/chat-ws": "./src/routes/chat-ws.ts",
|
|
53
58
|
"./routes/conversations": "./src/routes/conversations.ts",
|
|
54
59
|
"./routes/feedback": "./src/routes/feedback.ts",
|
|
55
60
|
"./routes/observability": "./src/routes/observability.ts",
|
|
@@ -57,6 +62,8 @@
|
|
|
57
62
|
"./routes/pages": "./src/routes/pages.ts",
|
|
58
63
|
"./routes/dynamic-tools": "./src/routes/dynamic-tools.ts",
|
|
59
64
|
"./adapters/voice": "./src/adapters/voice/cloudflare-agent.ts",
|
|
65
|
+
"./durable-objects/chat-session": "./src/durable-objects/chat-session.ts",
|
|
66
|
+
"./durable-objects/chat-session-auth": "./src/durable-objects/chat-session-auth.ts",
|
|
60
67
|
"./schema-enums": "./src/schema-enums.ts",
|
|
61
68
|
"./contracts/goal": "./src/contracts/goal.contract.ts",
|
|
62
69
|
"./contracts/agenda-item": "./src/contracts/agenda-item.contract.ts",
|
|
@@ -99,6 +106,7 @@
|
|
|
99
106
|
"wrangler": "^4.76.0"
|
|
100
107
|
},
|
|
101
108
|
"files": [
|
|
109
|
+
"cli/**/*.mjs",
|
|
102
110
|
"src/**/*.ts",
|
|
103
111
|
"schema.sql"
|
|
104
112
|
],
|
package/schema.sql
CHANGED
|
@@ -7,6 +7,7 @@ CREATE TABLE IF NOT EXISTS conversations (
|
|
|
7
7
|
id TEXT PRIMARY KEY,
|
|
8
8
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
9
9
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
10
|
+
user_id TEXT NOT NULL DEFAULT 'operator',
|
|
10
11
|
title TEXT
|
|
11
12
|
);
|
|
12
13
|
|
|
@@ -67,6 +68,7 @@ CREATE TABLE IF NOT EXISTS episodic_memory (
|
|
|
67
68
|
executor TEXT, -- which executor handled this
|
|
68
69
|
complexity_tier TEXT, -- aegis#563: procedureKey complement (low|mid|high); NULL for non-dispatcher producers
|
|
69
70
|
executor_config TEXT, -- aegis#563: config snapshot at emit time (evaluator-replay fidelity)
|
|
71
|
+
grounding_gap INTEGER NOT NULL DEFAULT 0, -- aegis#497/#34: unresolved grounding gap observed on this episode
|
|
70
72
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
71
73
|
);
|
|
72
74
|
|
|
@@ -199,6 +201,7 @@ CREATE TABLE IF NOT EXISTS operator_log (
|
|
|
199
201
|
|
|
200
202
|
CREATE INDEX IF NOT EXISTS idx_messages_conversation ON messages(conversation_id);
|
|
201
203
|
CREATE INDEX IF NOT EXISTS idx_messages_created ON messages(created_at);
|
|
204
|
+
CREATE INDEX IF NOT EXISTS idx_conversations_user_updated ON conversations(user_id, updated_at);
|
|
202
205
|
CREATE INDEX IF NOT EXISTS idx_memory_topic ON memory_entries(topic);
|
|
203
206
|
CREATE INDEX IF NOT EXISTS idx_memory_dedup ON memory_entries(topic, fact_hash);
|
|
204
207
|
CREATE INDEX IF NOT EXISTS idx_memory_expires ON memory_entries(expires_at);
|
|
@@ -208,6 +211,7 @@ CREATE INDEX IF NOT EXISTS idx_episodic_class ON episodic_memory(intent_class);
|
|
|
208
211
|
CREATE INDEX IF NOT EXISTS idx_episodic_created ON episodic_memory(created_at);
|
|
209
212
|
CREATE INDEX IF NOT EXISTS idx_episodic_thread ON episodic_memory(thread_id);
|
|
210
213
|
CREATE INDEX IF NOT EXISTS idx_episodic_class_complexity ON episodic_memory(intent_class, complexity_tier);
|
|
214
|
+
CREATE INDEX IF NOT EXISTS idx_episodic_grounding_gap ON episodic_memory(grounding_gap, created_at);
|
|
211
215
|
CREATE INDEX IF NOT EXISTS idx_procedural_pattern ON procedural_memory(task_pattern);
|
|
212
216
|
CREATE INDEX IF NOT EXISTS idx_procedural_status ON procedural_memory(status);
|
|
213
217
|
CREATE INDEX IF NOT EXISTS idx_heartbeat_created ON heartbeat_results(created_at);
|
|
File without changes
|
package/src/auth.ts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import type { Context, Next } from 'hono';
|
|
2
2
|
import type { Env } from './types.js';
|
|
3
3
|
|
|
4
|
-
export async function bearerAuth(c: Context<{ Bindings: Env }>, next: Next): Promise<Response | void> {
|
|
5
|
-
// Public routes — no auth required
|
|
6
|
-
if (
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
export async function bearerAuth(c: Context<{ Bindings: Env }>, next: Next): Promise<Response | void> {
|
|
5
|
+
// Public routes — no auth required
|
|
6
|
+
if (
|
|
7
|
+
c.req.path === '/health' ||
|
|
8
|
+
c.req.path === '/pulse' ||
|
|
9
|
+
((c.req.path === '/' || c.req.path === '/chat' || c.req.path === '/manifest.json' || c.req.path === '/sw.js') && c.req.method === 'GET') ||
|
|
10
|
+
c.req.path.startsWith('/tech') ||
|
|
11
|
+
c.req.path === '/api/feedback' ||
|
|
12
|
+
c.req.path === '/observe' ||
|
|
13
|
+
c.req.path.startsWith('/api/overworld/public')
|
|
14
|
+
) {
|
|
15
|
+
return next();
|
|
16
|
+
}
|
|
9
17
|
|
|
10
18
|
// Webhook routes — auth handled by per-route HMAC verification
|
|
11
19
|
if (c.req.path.startsWith('/webhooks/') || c.req.path === '/api/webhook') {
|
package/src/bluesky.ts
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|