@stackbilt/aegis-core 0.6.5 → 0.8.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 +21 -3
- package/public/assets/index-CQHn03rW.css +1 -0
- package/public/assets/index-CTKpNJEr.js +74 -0
- package/public/index.html +14 -0
- package/schema.sql +4 -0
- package/src/adapters/voice/cloudflare-agent.ts +0 -0
- package/src/agent-routing.ts +38 -0
- package/src/assets.ts +6 -0
- package/src/auth.ts +14 -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 +11 -1
- 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/messages.ts +11 -6
- package/src/routes/observability.ts +0 -0
- package/src/routes/operator-logs.ts +0 -0
- package/src/routes/pages.ts +12 -1
- package/src/schema-enums.ts +0 -0
- package/src/task-intelligence.ts +0 -0
- package/src/types.ts +8 -0
- package/src/ui/index.html +13 -0
- package/src/ui/main.tsx +356 -0
- package/src/ui/styles.css +391 -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.8.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",
|
|
@@ -73,8 +80,9 @@
|
|
|
73
80
|
"./kernel/patterns": "./src/kernel/patterns.ts"
|
|
74
81
|
},
|
|
75
82
|
"scripts": {
|
|
76
|
-
"dev": "wrangler dev",
|
|
77
|
-
"deploy": "wrangler deploy",
|
|
83
|
+
"dev": "npm run build:ui && wrangler dev",
|
|
84
|
+
"deploy": "npm run build:ui && wrangler deploy",
|
|
85
|
+
"build:ui": "vite build --config vite.ui.config.ts",
|
|
78
86
|
"d1:create": "wrangler d1 create aegis-web",
|
|
79
87
|
"d1:migrate": "wrangler d1 execute aegis-web --file=schema.sql",
|
|
80
88
|
"d1:migrate:local": "wrangler d1 execute aegis-web --file=schema.sql --local",
|
|
@@ -89,17 +97,27 @@
|
|
|
89
97
|
"@stackbilt/llm-providers": "^1.6.4",
|
|
90
98
|
"agents": "^0.12.3",
|
|
91
99
|
"hono": "^4.12.12",
|
|
100
|
+
"partysocket": "^1.1.19",
|
|
101
|
+
"react": "^19.2.7",
|
|
102
|
+
"react-dom": "^19.2.7",
|
|
92
103
|
"zod": "^4.4.3"
|
|
93
104
|
},
|
|
94
105
|
"devDependencies": {
|
|
95
106
|
"@cloudflare/workers-types": "^4.20241218.0",
|
|
107
|
+
"@types/react": "^19.2.16",
|
|
108
|
+
"@types/react-dom": "^19.2.3",
|
|
96
109
|
"typescript": "^5.7.3",
|
|
97
110
|
"vite": "^8.0.5",
|
|
98
111
|
"vitest": "^4.0.18",
|
|
99
112
|
"wrangler": "^4.76.0"
|
|
100
113
|
},
|
|
101
114
|
"files": [
|
|
115
|
+
"cli/**/*.mjs",
|
|
102
116
|
"src/**/*.ts",
|
|
117
|
+
"src/**/*.tsx",
|
|
118
|
+
"src/ui/**/*.css",
|
|
119
|
+
"src/ui/**/*.html",
|
|
120
|
+
"public/**/*",
|
|
103
121
|
"schema.sql"
|
|
104
122
|
],
|
|
105
123
|
"keywords": [
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;color:#edf0ef;background:#101317;font-family:IBM Plex Sans,Aptos,Segoe UI,sans-serif;line-height:1.45}*{box-sizing:border-box}body{background-color:#101317;background-image:linear-gradient(90deg,#f6bd6014 1px,#0000 1px),linear-gradient(#76b38414 1px,#0000 1px),none;background-position:0 0,0 0,0 0;background-repeat:repeat,repeat,repeat;background-size:48px 48px;background-attachment:scroll,scroll,scroll;background-origin:padding-box,padding-box,padding-box;background-clip:border-box,border-box,border-box;min-width:320px;min-height:100vh;margin:0}button,input,textarea{font:inherit}button{color:#11130f;cursor:pointer;background:#e7b75f;border:1px solid #3a4440;border-radius:6px;font-weight:700}button:disabled{cursor:not-allowed;opacity:.45}input,textarea{color:#f2f4f1;background:#151a1d;border:1px solid #39413f;border-radius:6px;width:100%}input:focus,textarea:focus,button:focus-visible{outline-offset:2px;outline:2px solid #76b384}.shell{grid-template-columns:minmax(240px,320px) minmax(0,1fr) minmax(260px,340px);min-height:100vh;display:grid}.rail,.voice-panel{background:#0d1113f0;border-color:#28302d;flex-direction:column;gap:18px;padding:18px;display:flex}.rail{border-right:1px solid #28302d}.voice-panel{border-left:1px solid #28302d}.brand{align-items:center;gap:12px;min-height:64px;display:flex}.brand-mark{color:#76b384;border:1px solid #76b384;border-radius:6px;place-items:center;width:44px;height:44px;font-family:IBM Plex Mono,Cascadia Mono,monospace;font-size:1.4rem;font-weight:800;display:grid}.brand h1,.topbar h2{letter-spacing:0;margin:0}.brand p,.eyebrow,.runtime-status,.conversation small,.voice-state,label,dt{color:#9aa39d;font-size:.82rem}.token-panel,.health-panel,.conversation-panel{flex-direction:column;gap:10px;display:flex}.token-row,.panel-title,.voice-actions,.voice-text{align-items:center;gap:8px;display:flex}.token-row button,.panel-title button{width:42px;height:38px}.token-row input,.voice-text input{height:38px;padding:0 10px}.panel-title{text-transform:uppercase;letter-spacing:0;justify-content:space-between;min-height:38px;font-weight:800}.health-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0;display:grid}.health-grid div{background:#151a1d;border:1px solid #2f3835;border-radius:6px;padding:10px}.health-grid dd{margin:4px 0 0;font-family:IBM Plex Mono,Cascadia Mono,monospace;font-weight:800}.new-chat{min-height:38px}.conversation-list{flex-direction:column;gap:6px;max-height:40vh;display:flex;overflow:auto}.conversation{text-align:left;color:#eef0ef;background:#151a1d;gap:4px;min-height:58px;padding:10px;display:grid}.conversation.active{border-color:#76b384}.workspace{grid-template-rows:auto minmax(0,1fr) auto;min-width:0;display:grid}.topbar{background:#101317c7;border-bottom:1px solid #28302d;justify-content:space-between;align-items:center;gap:24px;min-height:84px;padding:18px 22px;display:flex}.eyebrow{text-transform:uppercase;margin:0 0 4px;font-weight:800}.runtime-status{white-space:nowrap;align-items:center;gap:8px;display:flex}.dot{background:#8e403b;border-radius:50%;width:10px;height:10px}.dot.online{background:#76b384}.message-surface{flex-direction:column;gap:12px;padding:22px;display:flex;overflow:auto}.empty-state{color:#b8beb9;text-align:center;place-items:center;min-height:100%;display:grid}.message{background:#151a1deb;border:1px solid #2d3633;border-radius:6px;grid-template-columns:92px minmax(0,1fr);gap:12px;max-width:980px;padding:12px;display:grid}.message.user{border-color:#6f5d38}.message-role{color:#e7b75f;text-transform:uppercase;font-family:IBM Plex Mono,Cascadia Mono,monospace;font-size:.78rem;font-weight:800}.message-content{white-space:pre-wrap;overflow-wrap:anywhere}.composer{background:#0d1113f0;border-top:1px solid #28302d;grid-template-columns:minmax(0,1fr) 96px;gap:10px;padding:18px 22px;display:grid}.composer textarea{resize:vertical;min-height:72px;padding:10px}.composer button{min-height:72px}.meter{background:#151a1d;border:1px solid #39413f;border-radius:999px;height:12px;overflow:hidden}.meter span{background:#76b384;height:100%;display:block}.voice-actions button{flex:1;min-height:40px}.voice-transcript{gap:8px;min-height:180px;max-height:42vh;display:grid;overflow:auto}.voice-transcript p{background:#151a1d;border:1px solid #2f3835;border-radius:6px;gap:4px;margin:0;padding:10px;display:grid}.voice-transcript strong{color:#e7b75f;text-transform:uppercase;font-size:.76rem}.error{color:#f0a39d;margin:0}.voice-text button{width:70px;min-height:38px}@media (width<=1100px){.shell{grid-template-columns:minmax(220px,280px) minmax(0,1fr)}.voice-panel{border-top:1px solid #28302d;border-left:none;grid-column:1/-1}}@media (width<=760px){.shell{grid-template-columns:1fr}.rail,.voice-panel{border-inline:none}.topbar,.composer,.message{grid-template-columns:1fr}}
|