@stackbilt/aegis-core 0.1.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/package.json +96 -0
- package/schema.sql +586 -0
- package/src/adapters/voice/cloudflare-agent.ts +34 -0
- package/src/auth.ts +124 -0
- package/src/bluesky.ts +464 -0
- package/src/claude-tools/content.ts +188 -0
- package/src/claude-tools/email.ts +69 -0
- package/src/claude-tools/github.ts +440 -0
- package/src/claude-tools/goals.ts +116 -0
- package/src/claude-tools/index.ts +353 -0
- package/src/claude-tools/web.ts +59 -0
- package/src/claude.ts +406 -0
- package/src/codebeast.ts +200 -0
- package/src/composite.ts +715 -0
- package/src/content/column.ts +80 -0
- package/src/content/hero-image.ts +47 -0
- package/src/content/index.ts +27 -0
- package/src/content/journal.ts +91 -0
- package/src/content/roundtable.ts +163 -0
- package/src/core.ts +309 -0
- package/src/dashboard.ts +620 -0
- package/src/decision-docs.ts +284 -0
- package/src/dispatch.ts +13 -0
- package/src/edge-env.ts +58 -0
- package/src/email.ts +850 -0
- package/src/exports.ts +156 -0
- package/src/github-projects.ts +312 -0
- package/src/github.ts +670 -0
- package/src/groq.ts +247 -0
- package/src/health-page.ts +578 -0
- package/src/index.ts +89 -0
- package/src/kernel/argus-actions.ts +397 -0
- package/src/kernel/argus-correlation.ts +639 -0
- package/src/kernel/board.ts +91 -0
- package/src/kernel/briefing.ts +177 -0
- package/src/kernel/classify-memory-topic.ts +166 -0
- package/src/kernel/cognition.ts +377 -0
- package/src/kernel/court-cards.ts +163 -0
- package/src/kernel/dispatch.ts +587 -0
- package/src/kernel/domain.ts +50 -0
- package/src/kernel/dynamic-tools.ts +322 -0
- package/src/kernel/executor-port.ts +45 -0
- package/src/kernel/executors/claude.ts +73 -0
- package/src/kernel/executors/direct.ts +237 -0
- package/src/kernel/executors/groq.ts +18 -0
- package/src/kernel/executors/index.ts +87 -0
- package/src/kernel/executors/tarotscript.ts +104 -0
- package/src/kernel/executors/workers-ai.ts +54 -0
- package/src/kernel/insight-cache.ts +76 -0
- package/src/kernel/memory/agenda.ts +200 -0
- package/src/kernel/memory/blocks.ts +188 -0
- package/src/kernel/memory/consolidation.ts +194 -0
- package/src/kernel/memory/episodic.ts +241 -0
- package/src/kernel/memory/goals.ts +156 -0
- package/src/kernel/memory/graph.ts +290 -0
- package/src/kernel/memory/index.ts +11 -0
- package/src/kernel/memory/insights.ts +316 -0
- package/src/kernel/memory/procedural.ts +467 -0
- package/src/kernel/memory/pruning.ts +67 -0
- package/src/kernel/memory/recall.ts +367 -0
- package/src/kernel/memory/semantic.ts +315 -0
- package/src/kernel/memory/synthesis.ts +161 -0
- package/src/kernel/memory-adapter.ts +369 -0
- package/src/kernel/memory-guardrails.ts +76 -0
- package/src/kernel/port.ts +23 -0
- package/src/kernel/resilience.ts +322 -0
- package/src/kernel/router.ts +471 -0
- package/src/kernel/scheduled/agent-dispatch.ts +252 -0
- package/src/kernel/scheduled/argus-analytics.ts +247 -0
- package/src/kernel/scheduled/argus-heartbeat.ts +320 -0
- package/src/kernel/scheduled/argus-notify.ts +348 -0
- package/src/kernel/scheduled/board-sync.ts +110 -0
- package/src/kernel/scheduled/ci-watcher.ts +125 -0
- package/src/kernel/scheduled/cognitive-metrics.ts +377 -0
- package/src/kernel/scheduled/consolidation.ts +229 -0
- package/src/kernel/scheduled/content-drip.ts +47 -0
- package/src/kernel/scheduled/content.ts +6 -0
- package/src/kernel/scheduled/conversation-facts.ts +204 -0
- package/src/kernel/scheduled/cost-report.ts +84 -0
- package/src/kernel/scheduled/curiosity.ts +219 -0
- package/src/kernel/scheduled/dev-activity.ts +44 -0
- package/src/kernel/scheduled/digest.ts +317 -0
- package/src/kernel/scheduled/dreaming/agenda-triage.ts +115 -0
- package/src/kernel/scheduled/dreaming/facts.ts +239 -0
- package/src/kernel/scheduled/dreaming/index.ts +8 -0
- package/src/kernel/scheduled/dreaming/llm.ts +33 -0
- package/src/kernel/scheduled/dreaming/pattern-synthesis.ts +124 -0
- package/src/kernel/scheduled/dreaming/persona.ts +75 -0
- package/src/kernel/scheduled/dreaming/symbolic.ts +31 -0
- package/src/kernel/scheduled/dreaming/task-proposals.ts +80 -0
- package/src/kernel/scheduled/dreaming.ts +66 -0
- package/src/kernel/scheduled/entropy.ts +149 -0
- package/src/kernel/scheduled/escalation.ts +192 -0
- package/src/kernel/scheduled/feed-watcher.ts +206 -0
- package/src/kernel/scheduled/goals.ts +214 -0
- package/src/kernel/scheduled/governance.ts +41 -0
- package/src/kernel/scheduled/heartbeat.ts +220 -0
- package/src/kernel/scheduled/inbox-processor.ts +174 -0
- package/src/kernel/scheduled/index.ts +245 -0
- package/src/kernel/scheduled/issue-proposer.ts +478 -0
- package/src/kernel/scheduled/issue-watcher.ts +128 -0
- package/src/kernel/scheduled/pr-automerge.ts +213 -0
- package/src/kernel/scheduled/product-health.ts +107 -0
- package/src/kernel/scheduled/reflection.ts +373 -0
- package/src/kernel/scheduled/self-improvement.ts +114 -0
- package/src/kernel/scheduled/social-engage.ts +175 -0
- package/src/kernel/scheduled/task-audit.ts +60 -0
- package/src/kernel/symbolic.ts +156 -0
- package/src/kernel/types.ts +145 -0
- package/src/landing.ts +1190 -0
- package/src/lib/audit-chain/chain.ts +28 -0
- package/src/lib/audit-chain/types.ts +12 -0
- package/src/lib/observability/errors.ts +55 -0
- package/src/markdown.ts +164 -0
- package/src/mcp/handlers.ts +647 -0
- package/src/mcp/server.ts +184 -0
- package/src/mcp/tools.ts +316 -0
- package/src/mcp-client.ts +275 -0
- package/src/mcp-server.ts +2 -0
- package/src/operator/config.example.ts +60 -0
- package/src/operator/config.ts +60 -0
- package/src/operator/index.ts +46 -0
- package/src/operator/persona.example.ts +34 -0
- package/src/operator/persona.ts +34 -0
- package/src/operator/prompt-builder.ts +190 -0
- package/src/operator/types.ts +43 -0
- package/src/pulse.ts +1179 -0
- package/src/routes/bluesky.ts +116 -0
- package/src/routes/cc-tasks.ts +328 -0
- package/src/routes/codebeast.ts +1 -0
- package/src/routes/content.ts +194 -0
- package/src/routes/conversations.ts +25 -0
- package/src/routes/dynamic-tools.ts +111 -0
- package/src/routes/feedback.ts +192 -0
- package/src/routes/health.ts +147 -0
- package/src/routes/messages.ts +228 -0
- package/src/routes/observability.ts +82 -0
- package/src/routes/operator-logs.ts +42 -0
- package/src/routes/pages.ts +96 -0
- package/src/routes/sessions.ts +54 -0
- package/src/sanitize.ts +73 -0
- package/src/schema-enums.ts +155 -0
- package/src/search.ts +112 -0
- package/src/task-intelligence.ts +497 -0
- package/src/types.ts +194 -0
- package/src/ui.ts +5 -0
- package/src/version.ts +3 -0
- package/src/workers-ai-chat.ts +333 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
// Decision Documentation Renderer (#62)
|
|
2
|
+
//
|
|
3
|
+
// Traces the full decision chain for a topic across 7 data sources:
|
|
4
|
+
// semantic memory, episodic memory, procedural memory, goals/actions,
|
|
5
|
+
// narratives, cc_tasks, and GitHub issues/PRs.
|
|
6
|
+
//
|
|
7
|
+
// Pure data assembly — no LLM synthesis, no hallucinated decisions.
|
|
8
|
+
|
|
9
|
+
import type { EdgeEnv } from './kernel/dispatch.js';
|
|
10
|
+
import type { MemoryFragmentResult } from './types.js';
|
|
11
|
+
import { listIssues, listPullRequests, resolveRepoName } from './github.js';
|
|
12
|
+
|
|
13
|
+
interface TimelineEvent {
|
|
14
|
+
date: string;
|
|
15
|
+
source: string;
|
|
16
|
+
summary: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface DecisionDocOptions {
|
|
20
|
+
days?: number; // lookback window (default: 90)
|
|
21
|
+
includeRaw?: boolean; // include raw evidence section (default: false)
|
|
22
|
+
repo?: string; // GitHub repo to search (default: aegis)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function generateDecisionDoc(
|
|
26
|
+
topic: string,
|
|
27
|
+
env: EdgeEnv,
|
|
28
|
+
options: DecisionDocOptions = {},
|
|
29
|
+
): Promise<string> {
|
|
30
|
+
const days = options.days ?? 90;
|
|
31
|
+
const includeRaw = options.includeRaw ?? false;
|
|
32
|
+
const repo = resolveRepoName(options.repo ?? 'aegis');
|
|
33
|
+
const since = new Date(Date.now() - days * 86400000).toISOString();
|
|
34
|
+
const keywords = topic.toLowerCase().split(/[\s_-]+/).filter(w => w.length > 2);
|
|
35
|
+
const likePattern = `%${topic.replace(/[\s_-]+/g, '%')}%`;
|
|
36
|
+
|
|
37
|
+
// ─── Parallel queries across all sources ─────────────────────
|
|
38
|
+
const [
|
|
39
|
+
memoryFacts,
|
|
40
|
+
episodes,
|
|
41
|
+
procedures,
|
|
42
|
+
narratives,
|
|
43
|
+
goals,
|
|
44
|
+
actions,
|
|
45
|
+
tasks,
|
|
46
|
+
issues,
|
|
47
|
+
prs,
|
|
48
|
+
] = await Promise.all([
|
|
49
|
+
// 1. Semantic memory (Memory Worker hybrid recall)
|
|
50
|
+
env.memoryBinding
|
|
51
|
+
? env.memoryBinding.recall('aegis', { keywords: topic, limit: 20, min_confidence: 0.5 })
|
|
52
|
+
.catch(() => [] as MemoryFragmentResult[])
|
|
53
|
+
: Promise.resolve([] as MemoryFragmentResult[]),
|
|
54
|
+
|
|
55
|
+
// 2. Episodic memory — keyword match in summary
|
|
56
|
+
env.db.prepare(
|
|
57
|
+
`SELECT intent_class, summary, outcome, cost, executor, created_at
|
|
58
|
+
FROM episodic_memory
|
|
59
|
+
WHERE summary LIKE ? AND created_at >= ?
|
|
60
|
+
ORDER BY created_at DESC LIMIT 30`
|
|
61
|
+
).bind(likePattern, since).all<{
|
|
62
|
+
intent_class: string; summary: string; outcome: string;
|
|
63
|
+
cost: number; executor: string; created_at: string;
|
|
64
|
+
}>().then(r => r.results).catch(() => []),
|
|
65
|
+
|
|
66
|
+
// 3. Procedural memory — pattern match
|
|
67
|
+
env.db.prepare(
|
|
68
|
+
`SELECT task_pattern, executor, success_count, fail_count, avg_latency_ms, avg_cost, status, refinements, last_used
|
|
69
|
+
FROM procedural_memory
|
|
70
|
+
WHERE task_pattern LIKE ?
|
|
71
|
+
ORDER BY last_used DESC LIMIT 10`
|
|
72
|
+
).bind(likePattern).all<{
|
|
73
|
+
task_pattern: string; executor: string; success_count: number;
|
|
74
|
+
fail_count: number; avg_latency_ms: number; avg_cost: number;
|
|
75
|
+
status: string; refinements: string; last_used: string;
|
|
76
|
+
}>().then(r => r.results).catch(() => []),
|
|
77
|
+
|
|
78
|
+
// 4. Narratives — topic in title, summary, or related_topics
|
|
79
|
+
env.db.prepare(
|
|
80
|
+
`SELECT title, summary, status, tension, last_beat, beat_count, related_topics, created_at, resolved_at
|
|
81
|
+
FROM narratives
|
|
82
|
+
WHERE title LIKE ? OR summary LIKE ? OR related_topics LIKE ?
|
|
83
|
+
ORDER BY created_at DESC LIMIT 10`
|
|
84
|
+
).bind(likePattern, likePattern, likePattern).all<{
|
|
85
|
+
title: string; summary: string; status: string; tension: string | null;
|
|
86
|
+
last_beat: string | null; beat_count: number; related_topics: string;
|
|
87
|
+
created_at: string; resolved_at: string | null;
|
|
88
|
+
}>().then(r => r.results).catch(() => []),
|
|
89
|
+
|
|
90
|
+
// 5. Goals
|
|
91
|
+
env.db.prepare(
|
|
92
|
+
`SELECT id, title, description, status, run_count, created_at, completed_at
|
|
93
|
+
FROM agent_goals
|
|
94
|
+
WHERE title LIKE ? OR description LIKE ?
|
|
95
|
+
ORDER BY created_at DESC LIMIT 10`
|
|
96
|
+
).bind(likePattern, likePattern).all<{
|
|
97
|
+
id: string; title: string; description: string | null;
|
|
98
|
+
status: string; run_count: number; created_at: string; completed_at: string | null;
|
|
99
|
+
}>().then(r => r.results).catch(() => []),
|
|
100
|
+
|
|
101
|
+
// 6. Goal actions (from matched goals — we'll filter post-query)
|
|
102
|
+
env.db.prepare(
|
|
103
|
+
`SELECT a.description, a.action_type, a.outcome, a.tool_called, a.created_at, g.title as goal_title
|
|
104
|
+
FROM agent_actions a
|
|
105
|
+
LEFT JOIN agent_goals g ON a.goal_id = g.id
|
|
106
|
+
WHERE a.description LIKE ? OR g.title LIKE ?
|
|
107
|
+
ORDER BY a.created_at DESC LIMIT 20`
|
|
108
|
+
).bind(likePattern, likePattern).all<{
|
|
109
|
+
description: string; action_type: string; outcome: string | null;
|
|
110
|
+
tool_called: string | null; created_at: string; goal_title: string | null;
|
|
111
|
+
}>().then(r => r.results).catch(() => []),
|
|
112
|
+
|
|
113
|
+
// 7. CC Tasks
|
|
114
|
+
env.db.prepare(
|
|
115
|
+
`SELECT title, repo, status, category, branch, pr_url, result, created_at, completed_at
|
|
116
|
+
FROM cc_tasks
|
|
117
|
+
WHERE title LIKE ? OR prompt LIKE ?
|
|
118
|
+
ORDER BY created_at DESC LIMIT 15`
|
|
119
|
+
).bind(likePattern, likePattern).all<{
|
|
120
|
+
title: string; repo: string; status: string; category: string | null;
|
|
121
|
+
branch: string | null; pr_url: string | null; result: string | null;
|
|
122
|
+
created_at: string; completed_at: string | null;
|
|
123
|
+
}>().then(r => r.results).catch(() => []),
|
|
124
|
+
|
|
125
|
+
// 8. GitHub issues
|
|
126
|
+
env.githubToken
|
|
127
|
+
? listIssues(env.githubToken, repo, 'all').then(
|
|
128
|
+
issues => issues.filter(i =>
|
|
129
|
+
keywords.some(k => i.title.toLowerCase().includes(k) || i.body?.toLowerCase().includes(k))
|
|
130
|
+
).slice(0, 15)
|
|
131
|
+
).catch(() => [])
|
|
132
|
+
: Promise.resolve([]),
|
|
133
|
+
|
|
134
|
+
// 9. GitHub PRs
|
|
135
|
+
env.githubToken
|
|
136
|
+
? listPullRequests(env.githubToken, repo, 'all').then(
|
|
137
|
+
prs => prs.filter(p =>
|
|
138
|
+
keywords.some(k => p.title.toLowerCase().includes(k))
|
|
139
|
+
).slice(0, 15)
|
|
140
|
+
).catch(() => [])
|
|
141
|
+
: Promise.resolve([]),
|
|
142
|
+
]);
|
|
143
|
+
|
|
144
|
+
// ─── Build timeline ──────────────────────────────────────────
|
|
145
|
+
const timeline: TimelineEvent[] = [];
|
|
146
|
+
|
|
147
|
+
for (const m of memoryFacts) {
|
|
148
|
+
timeline.push({ date: m.created_at, source: 'memory', summary: `[${m.topic}] ${m.content.slice(0, 120)}` });
|
|
149
|
+
}
|
|
150
|
+
for (const e of episodes) {
|
|
151
|
+
timeline.push({ date: e.created_at, source: 'episode', summary: `${e.intent_class} via ${e.executor} → ${e.outcome}` });
|
|
152
|
+
}
|
|
153
|
+
for (const n of narratives) {
|
|
154
|
+
timeline.push({ date: n.created_at, source: 'narrative', summary: `Arc: "${n.title}" (${n.status})` });
|
|
155
|
+
}
|
|
156
|
+
for (const g of goals) {
|
|
157
|
+
timeline.push({ date: g.created_at, source: 'goal', summary: `Goal: "${g.title}" (${g.status}, ${g.run_count} runs)` });
|
|
158
|
+
}
|
|
159
|
+
for (const t of tasks) {
|
|
160
|
+
timeline.push({ date: t.created_at, source: 'task', summary: `Task: "${t.title}" → ${t.status}${t.pr_url ? ` (${t.pr_url})` : ''}` });
|
|
161
|
+
}
|
|
162
|
+
for (const i of issues) {
|
|
163
|
+
timeline.push({ date: i.created_at, source: 'issue', summary: `#${i.number}: ${i.title} (${i.state})` });
|
|
164
|
+
}
|
|
165
|
+
for (const p of prs) {
|
|
166
|
+
timeline.push({ date: p.created_at, source: 'pr', summary: `PR #${p.number}: ${p.title} (${p.merged ? 'merged' : p.state})` });
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
timeline.sort((a, b) => a.date.localeCompare(b.date));
|
|
170
|
+
|
|
171
|
+
// ─── Compute stats ──────────────────────────────────────────
|
|
172
|
+
const episodeSuccesses = episodes.filter(e => e.outcome === 'success').length;
|
|
173
|
+
const episodeTotal = episodes.length;
|
|
174
|
+
const totalCost = episodes.reduce((sum, e) => sum + (e.cost || 0), 0);
|
|
175
|
+
const tasksCompleted = tasks.filter(t => t.status === 'completed').length;
|
|
176
|
+
const tasksFailed = tasks.filter(t => t.status === 'failed').length;
|
|
177
|
+
const issuesClosed = issues.filter(i => i.state === 'closed').length;
|
|
178
|
+
const prsMerged = prs.filter(p => p.merged).length;
|
|
179
|
+
|
|
180
|
+
// ─── Render document ─────────────────────────────────────────
|
|
181
|
+
const lines: string[] = [];
|
|
182
|
+
|
|
183
|
+
lines.push(`# Decision Document: ${topic}`);
|
|
184
|
+
lines.push(`Generated: ${new Date().toISOString().slice(0, 19)}Z | Lookback: ${days} days`);
|
|
185
|
+
lines.push('');
|
|
186
|
+
|
|
187
|
+
// Summary stats
|
|
188
|
+
lines.push('## Summary');
|
|
189
|
+
lines.push(`- **Memory facts**: ${memoryFacts.length}`);
|
|
190
|
+
lines.push(`- **Episodes**: ${episodeTotal} (${episodeSuccesses} success, ${episodeTotal - episodeSuccesses} failure)`);
|
|
191
|
+
if (totalCost > 0) lines.push(`- **Total cost**: $${totalCost.toFixed(4)}`);
|
|
192
|
+
lines.push(`- **Tasks**: ${tasks.length} (${tasksCompleted} completed, ${tasksFailed} failed)`);
|
|
193
|
+
lines.push(`- **GitHub**: ${issues.length} issues (${issuesClosed} closed), ${prs.length} PRs (${prsMerged} merged)`);
|
|
194
|
+
lines.push(`- **Goals**: ${goals.length} | **Narratives**: ${narratives.length}`);
|
|
195
|
+
lines.push('');
|
|
196
|
+
|
|
197
|
+
// Timeline
|
|
198
|
+
if (timeline.length > 0) {
|
|
199
|
+
lines.push('## Timeline');
|
|
200
|
+
for (const event of timeline) {
|
|
201
|
+
const date = event.date.slice(0, 10);
|
|
202
|
+
lines.push(`- **${date}** [${event.source}] ${event.summary}`);
|
|
203
|
+
}
|
|
204
|
+
lines.push('');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Key decisions (from semantic memory — highest confidence facts)
|
|
208
|
+
const keyFacts = [...memoryFacts].sort((a, b) => b.confidence - a.confidence).slice(0, 10);
|
|
209
|
+
if (keyFacts.length > 0) {
|
|
210
|
+
lines.push('## Key Facts');
|
|
211
|
+
for (const f of keyFacts) {
|
|
212
|
+
const lifecycle = (f as unknown as Record<string, unknown>).lifecycle ?? '';
|
|
213
|
+
lines.push(`- [${f.topic}] ${f.content.slice(0, 200)} *(confidence: ${f.confidence}, ${lifecycle})*`);
|
|
214
|
+
}
|
|
215
|
+
lines.push('');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Procedural evolution
|
|
219
|
+
if (procedures.length > 0) {
|
|
220
|
+
lines.push('## Procedural Memory');
|
|
221
|
+
for (const p of procedures) {
|
|
222
|
+
const total = p.success_count + p.fail_count;
|
|
223
|
+
const rate = total > 0 ? Math.round((p.success_count / total) * 100) : 0;
|
|
224
|
+
lines.push(`- **${p.task_pattern}**: ${p.executor} (${p.status}) — ${p.success_count}/${total} success (${rate}%), avg ${Math.round(p.avg_latency_ms)}ms, $${p.avg_cost.toFixed(4)}/call`);
|
|
225
|
+
// Show refinements if any
|
|
226
|
+
try {
|
|
227
|
+
const refs = JSON.parse(p.refinements || '[]') as Array<{ what: string; why: string }>;
|
|
228
|
+
for (const r of refs.slice(-3)) {
|
|
229
|
+
lines.push(` - Refinement: ${r.what} — ${r.why}`);
|
|
230
|
+
}
|
|
231
|
+
} catch { /* skip malformed refinements */ }
|
|
232
|
+
}
|
|
233
|
+
lines.push('');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Narrative arcs
|
|
237
|
+
if (narratives.length > 0) {
|
|
238
|
+
lines.push('## Narrative Arcs');
|
|
239
|
+
for (const n of narratives) {
|
|
240
|
+
lines.push(`### ${n.title}`);
|
|
241
|
+
lines.push(`Status: ${n.status} | Beats: ${n.beat_count}${n.tension ? ` | Tension: ${n.tension}` : ''}`);
|
|
242
|
+
lines.push(n.summary);
|
|
243
|
+
if (n.resolved_at) lines.push(`Resolved: ${n.resolved_at.slice(0, 10)}`);
|
|
244
|
+
lines.push('');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Actions taken
|
|
249
|
+
if (actions.length > 0) {
|
|
250
|
+
lines.push('## Actions Taken');
|
|
251
|
+
for (const a of actions) {
|
|
252
|
+
const goalRef = a.goal_title ? ` (goal: ${a.goal_title})` : '';
|
|
253
|
+
lines.push(`- [${a.created_at.slice(0, 10)}] ${a.action_type}: ${a.description.slice(0, 150)}${goalRef} → ${a.outcome ?? 'pending'}`);
|
|
254
|
+
}
|
|
255
|
+
lines.push('');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// GitHub activity
|
|
259
|
+
if (issues.length > 0 || prs.length > 0) {
|
|
260
|
+
lines.push('## GitHub Activity');
|
|
261
|
+
for (const i of issues) {
|
|
262
|
+
const labels = i.labels.length > 0 ? ` [${i.labels.join(', ')}]` : '';
|
|
263
|
+
lines.push(`- Issue #${i.number}: ${i.title} (${i.state})${labels}`);
|
|
264
|
+
}
|
|
265
|
+
for (const p of prs) {
|
|
266
|
+
lines.push(`- PR #${p.number}: ${p.title} (${p.merged ? 'merged' : p.state})`);
|
|
267
|
+
}
|
|
268
|
+
lines.push('');
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Raw evidence (optional)
|
|
272
|
+
if (includeRaw && episodes.length > 0) {
|
|
273
|
+
lines.push('## Raw Episodes');
|
|
274
|
+
for (const e of episodes.slice(0, 20)) {
|
|
275
|
+
lines.push(`- [${e.created_at}] ${e.intent_class}/${e.executor}: ${e.summary.slice(0, 200)} → ${e.outcome} ($${e.cost.toFixed(4)})`);
|
|
276
|
+
}
|
|
277
|
+
lines.push('');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
lines.push('---');
|
|
281
|
+
lines.push('*Generated by AEGIS Decision Documentation Renderer*');
|
|
282
|
+
|
|
283
|
+
return lines.join('\n');
|
|
284
|
+
}
|
package/src/dispatch.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Stub — full implementation not yet extracted to OSS
|
|
2
|
+
|
|
3
|
+
export async function runDispatchGeneration(
|
|
4
|
+
_roundtableDb: D1Database,
|
|
5
|
+
_aegisDb: D1Database,
|
|
6
|
+
_apiKey: string,
|
|
7
|
+
_model: string,
|
|
8
|
+
_baseUrl: string,
|
|
9
|
+
_githubToken?: string,
|
|
10
|
+
_githubRepo?: string,
|
|
11
|
+
): Promise<{ title: string; slug: string; cost: number }> {
|
|
12
|
+
throw new Error('not implemented');
|
|
13
|
+
}
|
package/src/edge-env.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { EdgeEnv } from './kernel/dispatch.js';
|
|
2
|
+
import type { Env } from './types.js';
|
|
3
|
+
import { operatorConfig } from './operator/index.js';
|
|
4
|
+
|
|
5
|
+
export function buildEdgeEnv(env: Env, ctx?: ExecutionContext): EdgeEnv {
|
|
6
|
+
const gatewayId = env.AI_GATEWAY_ID || '';
|
|
7
|
+
|
|
8
|
+
// When AI Gateway is configured, route LLM calls through it for observability/caching
|
|
9
|
+
let anthropicBaseUrl = 'https://api.anthropic.com';
|
|
10
|
+
let groqBaseUrl = 'https://api.groq.com';
|
|
11
|
+
if (gatewayId) {
|
|
12
|
+
const accountId = env.CF_ACCOUNT_ID;
|
|
13
|
+
const gwBase = `https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}`;
|
|
14
|
+
anthropicBaseUrl = `${gwBase}/anthropic`;
|
|
15
|
+
groqBaseUrl = `${gwBase}/groq`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
db: env.DB,
|
|
20
|
+
anthropicApiKey: env.ANTHROPIC_API_KEY,
|
|
21
|
+
claudeModel: env.CLAUDE_MODEL || 'claude-sonnet-4-6',
|
|
22
|
+
opusModel: env.CLAUDE_OPUS_MODEL || 'claude-opus-4-6',
|
|
23
|
+
gptOssModel: env.GPT_OSS_MODEL || '@cf/openai/gpt-oss-120b',
|
|
24
|
+
groqApiKey: env.GROQ_API_KEY,
|
|
25
|
+
groqModel: env.GROQ_MODEL || 'llama-3.3-70b-versatile',
|
|
26
|
+
groqResponseModel: env.GROQ_RESPONSE_MODEL || 'llama-3.1-8b-instant',
|
|
27
|
+
groqGptOssModel: env.GROQ_GPT_OSS_MODEL || 'openai/gpt-oss-120b',
|
|
28
|
+
bizopsFetcher: env.BIZOPS,
|
|
29
|
+
bizopsToken: env.BIZOPS_TOKEN,
|
|
30
|
+
resendApiKey: env.RESEND_API_KEY,
|
|
31
|
+
resendApiKeyPersonal: env.RESEND_API_KEY_PERSONAL,
|
|
32
|
+
githubToken: env.GITHUB_TOKEN,
|
|
33
|
+
githubRepo: env.GITHUB_REPO,
|
|
34
|
+
braveApiKey: env.BRAVE_API_KEY,
|
|
35
|
+
notifyEmail: env.AEGIS_NOTIFY_EMAIL,
|
|
36
|
+
baseUrl: env.AEGIS_BASE_URL || operatorConfig.baseUrl,
|
|
37
|
+
ai: env.AI,
|
|
38
|
+
aiGatewayId: gatewayId || undefined,
|
|
39
|
+
anthropicBaseUrl,
|
|
40
|
+
groqBaseUrl,
|
|
41
|
+
ctx,
|
|
42
|
+
roundtableDb: env.ROUNDTABLE_DB,
|
|
43
|
+
cfAnalyticsToken: env.CF_ANALYTICS_TOKEN || undefined,
|
|
44
|
+
imgForgeFetcher: env.IMG_FORGE,
|
|
45
|
+
imgForgeSbSecret: env.IMG_FORGE_SB_SECRET || undefined,
|
|
46
|
+
memoryBinding: env.MEMORY,
|
|
47
|
+
tarotscriptFetcher: env.TAROTSCRIPT,
|
|
48
|
+
maraFetcher: env.MARA,
|
|
49
|
+
maraToken: env.MARA_TOKEN,
|
|
50
|
+
codebeastFetcher: env.CODEBEAST,
|
|
51
|
+
mindspringFetcher: env.MINDSPRING,
|
|
52
|
+
mindspringToken: env.MINDSPRING_TOKEN,
|
|
53
|
+
devtoApiKey: env.DEVTO_API_KEY || undefined,
|
|
54
|
+
gaCredentials: env.GA_CREDENTIALS || undefined,
|
|
55
|
+
blueskyHandle: env.BLUESKY_HANDLE || undefined,
|
|
56
|
+
blueskyAppPassword: env.BLUESKY_APP_PASSWORD || undefined,
|
|
57
|
+
};
|
|
58
|
+
}
|