aura-code 0.3.7 → 0.5.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/README.md +54 -2
- package/dist/agent/compactor.d.ts +26 -0
- package/dist/agent/compactor.js +156 -0
- package/dist/agent/compactor.js.map +1 -0
- package/dist/agent/design.d.ts +17 -0
- package/dist/agent/design.js +175 -0
- package/dist/agent/design.js.map +1 -0
- package/dist/agent/loop.js +8 -1
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/system-prompt.d.ts +1 -1
- package/dist/agent/system-prompt.js +5 -2
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/cli/display.js +40 -4
- package/dist/cli/display.js.map +1 -1
- package/dist/cli/index.js +258 -44
- package/dist/cli/index.js.map +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/project-config.d.ts +6 -0
- package/dist/config/project-config.js +2 -0
- package/dist/config/project-config.js.map +1 -1
- package/dist/dream/dream.d.ts +48 -0
- package/dist/dream/dream.js +187 -0
- package/dist/dream/dream.js.map +1 -0
- package/dist/kanban/index.d.ts +5 -0
- package/dist/kanban/index.js +11 -0
- package/dist/kanban/index.js.map +1 -0
- package/dist/kanban/pipeline.d.ts +16 -0
- package/dist/kanban/pipeline.js +910 -0
- package/dist/kanban/pipeline.js.map +1 -0
- package/dist/kanban/server.d.ts +5 -0
- package/dist/kanban/server.js +820 -0
- package/dist/kanban/server.js.map +1 -0
- package/dist/kanban/types.d.ts +75 -0
- package/dist/kanban/types.js +6 -0
- package/dist/kanban/types.js.map +1 -0
- package/dist/learnlight/driven.d.ts +2 -0
- package/dist/learnlight/driven.js +109 -0
- package/dist/learnlight/driven.js.map +1 -0
- package/dist/learnlight/index.d.ts +4 -0
- package/dist/learnlight/index.js +32 -0
- package/dist/learnlight/index.js.map +1 -0
- package/dist/learnlight/lesson-prep.d.ts +36 -0
- package/dist/learnlight/lesson-prep.js +224 -0
- package/dist/learnlight/lesson-prep.js.map +1 -0
- package/dist/learnlight/report.d.ts +2 -0
- package/dist/learnlight/report.js +37 -0
- package/dist/learnlight/report.js.map +1 -0
- package/dist/learnlight/types.d.ts +72 -0
- package/dist/learnlight/types.js +6 -0
- package/dist/learnlight/types.js.map +1 -0
- package/dist/perception/graph-store.d.ts +11 -0
- package/dist/perception/graph-store.js +33 -0
- package/dist/perception/graph-store.js.map +1 -1
- package/dist/perception/index.d.ts +1 -1
- package/dist/perception/index.js +2 -1
- package/dist/perception/index.js.map +1 -1
- package/dist/providers/factory.d.ts +16 -0
- package/dist/providers/factory.js +72 -0
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/openai-compatible.js +80 -49
- package/dist/providers/openai-compatible.js.map +1 -1
- package/dist/research/council.d.ts +26 -0
- package/dist/research/council.js +225 -0
- package/dist/research/council.js.map +1 -0
- package/dist/research/research.d.ts +24 -0
- package/dist/research/research.js +116 -0
- package/dist/research/research.js.map +1 -0
- package/dist/ruby/alternator.d.ts +36 -1
- package/dist/ruby/alternator.js +40 -31
- package/dist/ruby/alternator.js.map +1 -1
- package/dist/ruby/stats.js +10 -11
- package/dist/ruby/stats.js.map +1 -1
- package/dist/ruby/types.js +1 -1
- package/dist/ruby/types.js.map +1 -1
- package/dist/safety/permissions.d.ts +8 -0
- package/dist/safety/permissions.js +12 -0
- package/dist/safety/permissions.js.map +1 -1
- package/dist/setup/provider-registry.js +14 -0
- package/dist/setup/provider-registry.js.map +1 -1
- package/dist/setup/provider-test.js +24 -2
- package/dist/setup/provider-test.js.map +1 -1
- package/dist/setup/telegram-wizard.d.ts +57 -0
- package/dist/setup/telegram-wizard.js +343 -0
- package/dist/setup/telegram-wizard.js.map +1 -0
- package/dist/tools/audio-transcribe.d.ts +20 -0
- package/dist/tools/audio-transcribe.js +39 -28
- package/dist/tools/audio-transcribe.js.map +1 -1
- package/dist/tools/gmail-tool.d.ts +11 -0
- package/dist/tools/gmail-tool.js +221 -0
- package/dist/tools/gmail-tool.js.map +1 -0
- package/dist/tools/read-file.js +13 -0
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/telegram-bot.js +103 -18
- package/dist/tools/telegram-bot.js.map +1 -1
- package/dist/tools/telegram-voice.d.ts +22 -0
- package/dist/tools/telegram-voice.js +203 -0
- package/dist/tools/telegram-voice.js.map +1 -0
- package/dist/tools/telegram.d.ts +6 -1
- package/dist/tools/telegram.js +115 -5
- package/dist/tools/telegram.js.map +1 -1
- package/dist/tools/video-render.d.ts +11 -0
- package/dist/tools/video-render.js +189 -0
- package/dist/tools/video-render.js.map +1 -0
- package/dist/util/errors.js +6 -0
- package/dist/util/errors.js.map +1 -1
- package/dist/viz/index.js +816 -30
- package/dist/viz/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { LLMProvider } from '../providers/types.js';
|
|
2
|
+
import type { ProjectContext } from '../agent/context.js';
|
|
3
|
+
import type { PermissionSystem } from '../safety/permissions.js';
|
|
4
|
+
import type { Display } from '../cli/display.js';
|
|
5
|
+
export interface CouncilResult {
|
|
6
|
+
path: string;
|
|
7
|
+
htmlPath: string;
|
|
8
|
+
topic: string;
|
|
9
|
+
panelSize: number;
|
|
10
|
+
agentFailures: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Run an Ecclesia: `panelSize` independent agents research the topic
|
|
14
|
+
* (sequentially, on a free local model), then one synthesis call on the
|
|
15
|
+
* caller's active provider reconciles their findings into a verdict.
|
|
16
|
+
*/
|
|
17
|
+
export declare function runCouncil(opts: {
|
|
18
|
+
projectRoot: string;
|
|
19
|
+
topic: string;
|
|
20
|
+
synthesisProvider: LLMProvider;
|
|
21
|
+
context: ProjectContext;
|
|
22
|
+
permissions: PermissionSystem;
|
|
23
|
+
display: Display;
|
|
24
|
+
panelSize?: number;
|
|
25
|
+
panelModel?: string;
|
|
26
|
+
}): Promise<CouncilResult>;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runCouncil = runCouncil;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const marked_1 = require("marked");
|
|
40
|
+
const loop_js_1 = require("../agent/loop.js");
|
|
41
|
+
const factory_js_1 = require("../providers/factory.js");
|
|
42
|
+
/**
|
|
43
|
+
* Aura's `:council` ("Ecclesia") — N independent research agents investigate
|
|
44
|
+
* the same topic, then a synthesis pass reconciles their findings into one
|
|
45
|
+
* verdict: what they agreed on, what's contested, and what only a minority
|
|
46
|
+
* caught. Default panel size is 5 — odd, so majority agreement is always
|
|
47
|
+
* decisive (no 2.5/2.5 ties).
|
|
48
|
+
*
|
|
49
|
+
* Cost design, deliberately conservative (see compaction/dream incidents):
|
|
50
|
+
* - The N panel agents run SEQUENTIALLY, each a short findings-only pass
|
|
51
|
+
* (not a full polished report) on a free LOCAL model (Ollama by default)
|
|
52
|
+
* — so a 5-agent council costs roughly one :research pass, not five.
|
|
53
|
+
* - Only the final synthesis step uses the caller's active provider
|
|
54
|
+
* (better reasoning for reconciling disagreement), and it's one call.
|
|
55
|
+
* - Per-agent turns are capped well below :research's full budget.
|
|
56
|
+
*
|
|
57
|
+
* Output: dated `.md` + `.html` under `<projectRoot>/council/`.
|
|
58
|
+
*/
|
|
59
|
+
const COUNCIL_DIRNAME = 'council';
|
|
60
|
+
const DEFAULT_PANEL_SIZE = 5;
|
|
61
|
+
const DEFAULT_PANEL_MODEL = 'ollama/qwen2.5-coder:3b';
|
|
62
|
+
const FOOTER = '\n---\n\n*Ecclesia — five voices, one verdict. Inspired by DeerFlow.*\n';
|
|
63
|
+
function councilDir(projectRoot) {
|
|
64
|
+
return path.join(projectRoot, COUNCIL_DIRNAME);
|
|
65
|
+
}
|
|
66
|
+
function slugify(topic) {
|
|
67
|
+
return topic
|
|
68
|
+
.toLowerCase()
|
|
69
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
70
|
+
.replace(/^-+|-+$/g, '')
|
|
71
|
+
.slice(0, 60) || 'topic';
|
|
72
|
+
}
|
|
73
|
+
function buildPanelTask(topic, seat, panelSize) {
|
|
74
|
+
return (`You are panel seat ${seat} of ${panelSize} in an independent research council on this topic: "${topic}"\n\n` +
|
|
75
|
+
`Research it on your own — search and fetch what you need. Do NOT try to write a polished ` +
|
|
76
|
+
`report. Instead, respond with ONLY a compact findings list:\n\n` +
|
|
77
|
+
`- 4-8 bullet points, each one specific claim or finding, with its source noted in parentheses.\n` +
|
|
78
|
+
`- If something is disputed, speculative, or you're unsure, say so explicitly in that bullet.\n` +
|
|
79
|
+
`- End with one line: "Stance: <your one-sentence bottom-line take>"\n\n` +
|
|
80
|
+
`No preamble, no headers, no questions back. Just the bullets and the stance line.`);
|
|
81
|
+
}
|
|
82
|
+
function buildSynthesisPrompt(topic, findings) {
|
|
83
|
+
const system = 'You are Aura synthesising an Ecclesia — an independent research council. You are given ' +
|
|
84
|
+
`${findings.length} separate agents' findings on the same topic, gathered without them seeing ` +
|
|
85
|
+
'each other\'s work. Reconcile them into one verdict. Respond in Markdown with EXACTLY these ' +
|
|
86
|
+
'sections:\n\n' +
|
|
87
|
+
'## Convergent findings\n(claims most or all agents independently arrived at — high confidence)\n\n' +
|
|
88
|
+
'## Contested\n(claims where agents disagreed, or where a majority/minority split exists — name the split, ' +
|
|
89
|
+
'e.g. "3 of 5 agents..." )\n\n' +
|
|
90
|
+
'## Minority signal\n(something only one or two agents caught that seems worth surfacing anyway, even if unconfirmed)\n\n' +
|
|
91
|
+
'## Verdict\n(the council\'s bottom-line conclusion — what an informed reader should walk away believing, ' +
|
|
92
|
+
'and how confident that conclusion is)\n\n' +
|
|
93
|
+
'## Sources\n(consolidated list of sources cited across all agents)';
|
|
94
|
+
const user = `Topic: ${topic}\n\n` +
|
|
95
|
+
findings.map((f, i) => `### Agent ${i + 1}\n${f}`).join('\n\n');
|
|
96
|
+
return { system, user };
|
|
97
|
+
}
|
|
98
|
+
function mdToHtml(md) {
|
|
99
|
+
marked_1.marked.setOptions({ gfm: true, breaks: false });
|
|
100
|
+
return marked_1.marked.parse(md);
|
|
101
|
+
}
|
|
102
|
+
function wrapHtml(title, bodyHtml, date, panelSize) {
|
|
103
|
+
const esc = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
104
|
+
return `<!DOCTYPE html>
|
|
105
|
+
<html lang="en">
|
|
106
|
+
<head>
|
|
107
|
+
<meta charset="UTF-8">
|
|
108
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
109
|
+
<title>${esc(title)} — Ecclesia</title>
|
|
110
|
+
<style>
|
|
111
|
+
:root {
|
|
112
|
+
--bg: #fdf6f0; --card: #fffaf5; --text: #3e2f24; --muted: #8a7768;
|
|
113
|
+
--accent: #cc785c; --accent-2: #5a9e6e; --border: #e8d5c8;
|
|
114
|
+
--code-bg: #f4ede6; --bq: #cc785c; --hr: #e0cebc;
|
|
115
|
+
--shadow: 0 2px 12px rgba(62,47,36,0.06); --radius: 12px;
|
|
116
|
+
--serif: 'Georgia', 'Times New Roman', serif;
|
|
117
|
+
--sans: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
|
|
118
|
+
--mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
|
|
119
|
+
}
|
|
120
|
+
@media (prefers-color-scheme: dark) {
|
|
121
|
+
:root {
|
|
122
|
+
--bg: #1e1b18; --card: #26221e; --text: #ede0cc; --muted: #9e8e80;
|
|
123
|
+
--accent: #e08a6e; --accent-2: #6db880; --border: #3a322a;
|
|
124
|
+
--code-bg: #2c2722; --bq: #e08a6e; --hr: #3a322a;
|
|
125
|
+
--shadow: 0 2px 12px rgba(0,0,0,0.25);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
129
|
+
body { background: var(--bg); color: var(--text); font-family: var(--serif); line-height: 1.75; font-size: 18px; }
|
|
130
|
+
.container { max-width: 780px; margin: 0 auto; padding: 3rem 1.5rem 5rem; }
|
|
131
|
+
.hero { text-align: center; padding: 3rem 0 2.5rem; border-bottom: 2px solid var(--border); margin-bottom: 2.5rem; }
|
|
132
|
+
.hero .badge { display: inline-block; background: var(--accent); color: #fff; font-family: var(--sans); font-size: 0.7rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; padding: 0.3em 1em; border-radius: 100px; margin-bottom: 1.25rem; }
|
|
133
|
+
.hero h1 { font-family: var(--sans); font-size: 2.4rem; font-weight: 700; line-height: 1.25; letter-spacing: -0.02em; margin-bottom: 0.5rem; }
|
|
134
|
+
.hero .meta { font-family: var(--sans); font-size: 0.85rem; color: var(--muted); }
|
|
135
|
+
.card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 2.5rem 3rem; }
|
|
136
|
+
@media (max-width: 640px) { .card { padding: 1.5rem; border-radius: 8px; } .hero h1 { font-size: 1.7rem; } .container { padding: 1.5rem 0.75rem 3rem; } }
|
|
137
|
+
.card h1, .card h2, .card h3 { font-family: var(--sans); margin: 2rem 0 0.75rem; line-height: 1.3; }
|
|
138
|
+
.card h2:first-child { margin-top: 0; }
|
|
139
|
+
.card h2 { font-size: 1.45rem; color: var(--accent); border-bottom: 2px solid var(--border); padding-bottom: 0.4rem; }
|
|
140
|
+
.card h3 { font-size: 1.1rem; color: var(--accent-2); }
|
|
141
|
+
.card p { margin: 0.85rem 0; }
|
|
142
|
+
.card a { color: var(--accent); text-decoration: none; border-bottom: 1px solid var(--accent); }
|
|
143
|
+
.card ul, .card ol { margin: 0.85rem 0; padding-left: 1.8rem; }
|
|
144
|
+
.card li { margin: 0.4rem 0; }
|
|
145
|
+
.card code { font-family: var(--mono); font-size: 0.88em; background: var(--code-bg); padding: 0.15em 0.4em; border-radius: 4px; border: 1px solid var(--border); }
|
|
146
|
+
.card hr { border: none; border-top: 1px solid var(--hr); margin: 2rem 0; }
|
|
147
|
+
.footer { text-align: center; margin-top: 2.5rem; font-family: var(--sans); font-size: 0.8rem; color: var(--muted); opacity: 0.7; }
|
|
148
|
+
</style>
|
|
149
|
+
</head>
|
|
150
|
+
<body>
|
|
151
|
+
<div class="container">
|
|
152
|
+
<header class="hero">
|
|
153
|
+
<div class="badge">Ecclesia · ${panelSize} agents</div>
|
|
154
|
+
<h1>${esc(title)}</h1>
|
|
155
|
+
<div class="meta">${date}</div>
|
|
156
|
+
</header>
|
|
157
|
+
<article class="card">
|
|
158
|
+
${bodyHtml}
|
|
159
|
+
</article>
|
|
160
|
+
<footer class="footer"><p>Generated by Aura Code · Ecclesia · Inspired by DeerFlow</p></footer>
|
|
161
|
+
</div>
|
|
162
|
+
</body>
|
|
163
|
+
</html>`;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Run an Ecclesia: `panelSize` independent agents research the topic
|
|
167
|
+
* (sequentially, on a free local model), then one synthesis call on the
|
|
168
|
+
* caller's active provider reconciles their findings into a verdict.
|
|
169
|
+
*/
|
|
170
|
+
async function runCouncil(opts) {
|
|
171
|
+
const { projectRoot, topic, synthesisProvider, context, permissions, display, } = opts;
|
|
172
|
+
const panelSize = Math.max(1, opts.panelSize ?? DEFAULT_PANEL_SIZE);
|
|
173
|
+
const panelModel = opts.panelModel ?? DEFAULT_PANEL_MODEL;
|
|
174
|
+
const findings = [];
|
|
175
|
+
let agentFailures = 0;
|
|
176
|
+
// Sequential by design — see module doc. Each agent is independent: no
|
|
177
|
+
// agent sees another's findings, so agreement/disagreement is genuine.
|
|
178
|
+
for (let seat = 1; seat <= panelSize; seat++) {
|
|
179
|
+
try {
|
|
180
|
+
const panelProvider = (0, factory_js_1.createProvider)({ model: panelModel });
|
|
181
|
+
const res = await (0, loop_js_1.runAgentLoop)({
|
|
182
|
+
provider: panelProvider,
|
|
183
|
+
task: buildPanelTask(topic, seat, panelSize),
|
|
184
|
+
context,
|
|
185
|
+
permissions,
|
|
186
|
+
display,
|
|
187
|
+
maxTurns: 6,
|
|
188
|
+
disableSpawn: true,
|
|
189
|
+
});
|
|
190
|
+
const text = (res.summary ?? '').trim();
|
|
191
|
+
findings.push(text || `(Agent ${seat} returned no findings.)`);
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
agentFailures++;
|
|
195
|
+
findings.push(`(Agent ${seat} failed: ${err instanceof Error ? err.message : String(err)})`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Synthesis — one call, on the caller's real provider.
|
|
199
|
+
const { system, user } = buildSynthesisPrompt(topic, findings);
|
|
200
|
+
let verdictBody;
|
|
201
|
+
try {
|
|
202
|
+
const synth = await synthesisProvider.complete(system, [{ role: 'user', content: user }], []);
|
|
203
|
+
verdictBody = (synth.text ?? '').trim();
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
verdictBody =
|
|
207
|
+
`## Convergent findings\n_Synthesis failed: ${err instanceof Error ? err.message : String(err)}_\n\n` +
|
|
208
|
+
`## Contested\n- none (synthesis did not run)\n\n## Minority signal\n- none\n\n` +
|
|
209
|
+
`## Verdict\nSynthesis could not run, but the ${panelSize} agents' raw findings are preserved below.\n\n## Sources\n- see raw findings`;
|
|
210
|
+
}
|
|
211
|
+
const rawFindingsSection = `\n\n---\n\n## Raw panel findings\n\n` +
|
|
212
|
+
findings.map((f, i) => `### Agent ${i + 1}\n\n${f}`).join('\n\n');
|
|
213
|
+
const md = `# Ecclesia: ${topic}\n\n${verdictBody}${rawFindingsSection}\n${FOOTER}`;
|
|
214
|
+
const dir = councilDir(projectRoot);
|
|
215
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
216
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
217
|
+
const slug = slugify(topic);
|
|
218
|
+
const mdPath = path.join(dir, `${date}-${slug}.md`);
|
|
219
|
+
fs.writeFileSync(mdPath, md);
|
|
220
|
+
const htmlOut = wrapHtml(topic, mdToHtml(`${verdictBody}${rawFindingsSection}`), date, panelSize);
|
|
221
|
+
const htmlPath = path.join(dir, `${date}-${slug}.html`);
|
|
222
|
+
fs.writeFileSync(htmlPath, htmlOut);
|
|
223
|
+
return { path: mdPath, htmlPath, topic, panelSize, agentFailures };
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=council.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"council.js","sourceRoot":"","sources":["../../src/research/council.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { LLMProvider } from '../providers/types.js';
|
|
2
|
+
import type { ProjectContext } from '../agent/context.js';
|
|
3
|
+
import type { PermissionSystem } from '../safety/permissions.js';
|
|
4
|
+
import type { Display } from '../cli/display.js';
|
|
5
|
+
export interface ResearchResult {
|
|
6
|
+
path: string;
|
|
7
|
+
topic: string;
|
|
8
|
+
turns: number;
|
|
9
|
+
toolCalls: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Run a research pass and save it to a dated file. Throws if the underlying
|
|
13
|
+
* agent loop fails outright (caller should catch and report — there is no
|
|
14
|
+
* silent error-stub here, unlike :dream, since a failed research run has no
|
|
15
|
+
* partial state worth preserving).
|
|
16
|
+
*/
|
|
17
|
+
export declare function runResearch(opts: {
|
|
18
|
+
projectRoot: string;
|
|
19
|
+
topic: string;
|
|
20
|
+
provider: LLMProvider;
|
|
21
|
+
context: ProjectContext;
|
|
22
|
+
permissions: PermissionSystem;
|
|
23
|
+
display: Display;
|
|
24
|
+
}): Promise<ResearchResult>;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runResearch = runResearch;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const loop_js_1 = require("../agent/loop.js");
|
|
40
|
+
/**
|
|
41
|
+
* Aura's `:research` — a focused, multi-step research pass on a topic.
|
|
42
|
+
*
|
|
43
|
+
* Pattern is inspired by ByteDance's DeerFlow SuperAgent harness: break a
|
|
44
|
+
* topic into sub-questions, gather evidence (web_search/web_fetch, already
|
|
45
|
+
* wired into the agent loop), and synthesise into a cited report. This is
|
|
46
|
+
* intentionally the *minimal* version of that idea — it reuses the existing
|
|
47
|
+
* agent loop and tool wiring rather than introducing a separate middleware
|
|
48
|
+
* pipeline or concurrent sub-agent executor. If that proves too slow or
|
|
49
|
+
* shallow for a given topic, the heavier DeerFlow-style architecture
|
|
50
|
+
* (concurrent sub-agents, confidence-scored memory, sandboxing) is a
|
|
51
|
+
* candidate for a later, separate pass — not bundled in here.
|
|
52
|
+
*
|
|
53
|
+
* Output is one dated Markdown file per topic under `<projectRoot>/research/`,
|
|
54
|
+
* ending with a short attribution footer.
|
|
55
|
+
*/
|
|
56
|
+
const RESEARCH_DIRNAME = 'research';
|
|
57
|
+
const FOOTER = '\n---\n\n*Inspired by DeerFlow.*\n';
|
|
58
|
+
function researchDir(projectRoot) {
|
|
59
|
+
return path.join(projectRoot, RESEARCH_DIRNAME);
|
|
60
|
+
}
|
|
61
|
+
function slugify(topic) {
|
|
62
|
+
return topic
|
|
63
|
+
.toLowerCase()
|
|
64
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
65
|
+
.replace(/^-+|-+$/g, '')
|
|
66
|
+
.slice(0, 60) || 'topic';
|
|
67
|
+
}
|
|
68
|
+
function buildResearchTask(topic) {
|
|
69
|
+
return (`Research the following topic thoroughly and produce a well-organised, cited report: "${topic}"\n\n` +
|
|
70
|
+
`Approach:\n` +
|
|
71
|
+
`1. Break the topic into the 3-6 sub-questions that matter most (definition/background, ` +
|
|
72
|
+
`current state, key players or evidence, open debates or unknowns, practical takeaway).\n` +
|
|
73
|
+
`2. Search and fetch sources for each sub-question. Prefer primary/official sources over ` +
|
|
74
|
+
`aggregators. Note where claims are speculative, unverified, or disputed — do not present ` +
|
|
75
|
+
`speculation as settled fact.\n` +
|
|
76
|
+
`3. Synthesise into Markdown with clear section headers per sub-question, plus a short ` +
|
|
77
|
+
`"Bottom line" section at the end summarising the most defensible conclusion.\n` +
|
|
78
|
+
`4. List sources used at the end under a "Sources" heading.\n\n` +
|
|
79
|
+
`Respond with ONLY the finished Markdown report — no preamble, no meta-commentary about ` +
|
|
80
|
+
`your process, no questions back to the user.\n\n` +
|
|
81
|
+
`IMPORTANT: the report must be about "${topic}" — and nothing else. Do not write about ` +
|
|
82
|
+
`yourself, this tool, Aura, or this conversation; if you are tempted to, that means you have ` +
|
|
83
|
+
`drifted off-topic and should redirect back to "${topic}".`);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Run a research pass and save it to a dated file. Throws if the underlying
|
|
87
|
+
* agent loop fails outright (caller should catch and report — there is no
|
|
88
|
+
* silent error-stub here, unlike :dream, since a failed research run has no
|
|
89
|
+
* partial state worth preserving).
|
|
90
|
+
*/
|
|
91
|
+
async function runResearch(opts) {
|
|
92
|
+
const { projectRoot, topic, provider, context, permissions, display } = opts;
|
|
93
|
+
const result = await (0, loop_js_1.runAgentLoop)({
|
|
94
|
+
provider,
|
|
95
|
+
task: buildResearchTask(topic),
|
|
96
|
+
context,
|
|
97
|
+
permissions,
|
|
98
|
+
display,
|
|
99
|
+
maxTurns: 12,
|
|
100
|
+
disableSpawn: true,
|
|
101
|
+
});
|
|
102
|
+
const body = (result.summary ?? '').trim() || '_No content was returned for this research pass._';
|
|
103
|
+
const md = `# ${topic}\n\n${body}\n${FOOTER}`;
|
|
104
|
+
const dir = researchDir(projectRoot);
|
|
105
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
106
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
107
|
+
const outPath = path.join(dir, `${date}-${slugify(topic)}.md`);
|
|
108
|
+
fs.writeFileSync(outPath, md);
|
|
109
|
+
return {
|
|
110
|
+
path: outPath,
|
|
111
|
+
topic,
|
|
112
|
+
turns: result.turns ?? 0,
|
|
113
|
+
toolCalls: result.toolCallCount ?? 0,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=research.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research.js","sourceRoot":"","sources":["../../src/research/research.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyEA,kCAmCC;AA5GD,uCAAyB;AACzB,2CAA6B;AAC7B,8CAAgD;AAMhD;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,gBAAgB,GAAG,UAAU,CAAC;AACpC,MAAM,MAAM,GAAG,oCAAoC,CAAC;AAEpD,SAAS,WAAW,CAAC,WAAmB;IACtC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,KAAK;SACT,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC;AAC7B,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,CACL,wFAAwF,KAAK,OAAO;QACpG,aAAa;QACb,yFAAyF;QACzF,0FAA0F;QAC1F,0FAA0F;QAC1F,2FAA2F;QAC3F,gCAAgC;QAChC,wFAAwF;QACxF,gFAAgF;QAChF,gEAAgE;QAChE,yFAAyF;QACzF,kDAAkD;QAClD,wCAAwC,KAAK,2CAA2C;QACxF,8FAA8F;QAC9F,kDAAkD,KAAK,IAAI,CAC5D,CAAC;AACJ,CAAC;AASD;;;;;GAKG;AACI,KAAK,UAAU,WAAW,CAAC,IAOjC;IACC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAE7E,MAAM,MAAM,GAAG,MAAM,IAAA,sBAAY,EAAC;QAChC,QAAQ;QACR,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC;QAC9B,OAAO;QACP,WAAW;QACX,OAAO;QACP,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,mDAAmD,CAAC;IAClG,MAAM,EAAE,GAAG,KAAK,KAAK,OAAO,IAAI,KAAK,MAAM,EAAE,CAAC;IAE9C,MAAM,GAAG,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;IACrC,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/D,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAE9B,OAAO;QACL,IAAI,EAAE,OAAO;QACb,KAAK;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC,aAAa,IAAI,CAAC;KACrC,CAAC;AACJ,CAAC"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { LLMProvider } from '../providers/types.js';
|
|
2
|
+
import type { HistoryMessage } from '../providers/types.js';
|
|
3
|
+
import type { LoopResult } from '../agent/loop.js';
|
|
2
4
|
import type { ProjectContext } from '../agent/context.js';
|
|
5
|
+
import { PermissionSystem } from '../safety/permissions.js';
|
|
3
6
|
import type { Display } from '../cli/display.js';
|
|
4
7
|
import type { AlternationDecision, Episode, RubyConfig } from './types.js';
|
|
5
8
|
import type { EpisodeStats } from './episode-capture.js';
|
|
@@ -11,9 +14,41 @@ export interface AlternatorOptions {
|
|
|
11
14
|
context: ProjectContext;
|
|
12
15
|
/** When set, routing and loop events are surfaced to the user. */
|
|
13
16
|
display?: Display;
|
|
17
|
+
/**
|
|
18
|
+
* The permission system governing the user's actual session. Pass this
|
|
19
|
+
* through from the caller so Ruby's attempt respects whatever mode the
|
|
20
|
+
* user chose (read-only / normal / auto) — without it, this previously
|
|
21
|
+
* defaulted to a hardcoded 'auto', meaning destructive operations could
|
|
22
|
+
* get silently approved during the Ruby attempt even in a session the
|
|
23
|
+
* user explicitly ran in confirmation-required 'normal' mode.
|
|
24
|
+
*/
|
|
25
|
+
permissions?: PermissionSystem;
|
|
26
|
+
/**
|
|
27
|
+
* Confirmation callback for destructive operations, passed through to
|
|
28
|
+
* both the Ruby attempt and the large-model escalation. Pass the same
|
|
29
|
+
* one the caller already uses (e.g. the REPL's readline-based prompt) —
|
|
30
|
+
* without it, each inner loop falls back to its own default terminal
|
|
31
|
+
* confirm(), which can behave inconsistently alongside an already-active
|
|
32
|
+
* readline interface.
|
|
33
|
+
*/
|
|
34
|
+
confirmFn?: (message: string) => Promise<boolean>;
|
|
35
|
+
/**
|
|
36
|
+
* Prior conversation history to resume from (e.g. the REPL's stay-active
|
|
37
|
+
* history, or a loaded session). Without this, every Ruby-alternated
|
|
38
|
+
* turn would silently start fresh, breaking multi-turn conversation
|
|
39
|
+
* continuation any time alternation activates mid-conversation.
|
|
40
|
+
*/
|
|
41
|
+
initialHistory?: HistoryMessage[];
|
|
14
42
|
}
|
|
15
43
|
export interface AlternatorRunResult {
|
|
16
|
-
|
|
44
|
+
/**
|
|
45
|
+
* The full result from whichever path actually produced the final
|
|
46
|
+
* output — Ruby's if it succeeded without escalation, otherwise the
|
|
47
|
+
* large model's. Treat this exactly like a normal runAgentLoop() result:
|
|
48
|
+
* history, costUsd, turns, and toolCallLog are all populated correctly
|
|
49
|
+
* from whichever path ran, so callers don't need special-case handling.
|
|
50
|
+
*/
|
|
51
|
+
loopResult: LoopResult;
|
|
17
52
|
episode: Episode;
|
|
18
53
|
usedRuby: boolean;
|
|
19
54
|
decision: AlternationDecision;
|
package/dist/ruby/alternator.js
CHANGED
|
@@ -88,10 +88,11 @@ function buildRubyProvider(config) {
|
|
|
88
88
|
class RubyAlternator {
|
|
89
89
|
opts;
|
|
90
90
|
display;
|
|
91
|
-
permissions
|
|
91
|
+
permissions;
|
|
92
92
|
constructor(opts) {
|
|
93
93
|
this.opts = opts;
|
|
94
94
|
this.display = opts.display ?? createNoopDisplay();
|
|
95
|
+
this.permissions = opts.permissions ?? new permissions_js_1.PermissionSystem('normal');
|
|
95
96
|
}
|
|
96
97
|
/**
|
|
97
98
|
* Runs a task through Ruby and/or the large model, persists an episode, and
|
|
@@ -100,6 +101,7 @@ class RubyAlternator {
|
|
|
100
101
|
async run(task) {
|
|
101
102
|
const startMs = Date.now();
|
|
102
103
|
const { rubyConfig, largeModelProvider, projectRoot, context } = this.opts;
|
|
104
|
+
const confirmFn = this.opts.confirmFn;
|
|
103
105
|
let decision = {
|
|
104
106
|
useRuby: false,
|
|
105
107
|
reason: 'Initializing alternation.',
|
|
@@ -108,12 +110,12 @@ class RubyAlternator {
|
|
|
108
110
|
};
|
|
109
111
|
let rubyAttempted = false;
|
|
110
112
|
let rubySucceeded = false;
|
|
111
|
-
let
|
|
112
|
-
let
|
|
113
|
-
let largeModelOutput;
|
|
114
|
-
let largeModelTokens = 0;
|
|
113
|
+
let rubyLoopResult;
|
|
114
|
+
let largeModelLoopResult;
|
|
115
115
|
let usedRuby = false;
|
|
116
|
-
|
|
116
|
+
// Only used to build the error-path fallback LoopResult below; the
|
|
117
|
+
// success paths read everything from rubyLoopResult/largeModelLoopResult.
|
|
118
|
+
let errorSummary;
|
|
117
119
|
try {
|
|
118
120
|
const recent = await episode_capture_js_1.episodeStore.loadEpisodes(projectRoot, RECENT_EPISODE_LIMIT);
|
|
119
121
|
decision = (0, competence_js_1.assessCompetence)(recent, task, rubyConfig);
|
|
@@ -129,21 +131,20 @@ class RubyAlternator {
|
|
|
129
131
|
this.display.success(`Trying Ruby (${rubyConfig.modelName})…`);
|
|
130
132
|
try {
|
|
131
133
|
const rubyProvider = buildRubyProvider(rubyConfig);
|
|
132
|
-
|
|
134
|
+
rubyLoopResult = await (0, loop_js_1.runAgentLoop)({
|
|
133
135
|
provider: rubyProvider,
|
|
134
136
|
task,
|
|
135
137
|
context,
|
|
136
138
|
permissions: this.permissions,
|
|
137
139
|
display: this.display,
|
|
140
|
+
confirmFn,
|
|
141
|
+
initialHistory: this.opts.initialHistory,
|
|
138
142
|
disableSpawn: true,
|
|
139
143
|
maxTurns: 15,
|
|
140
144
|
});
|
|
141
|
-
|
|
142
|
-
rubyOutput = loopResult.summary;
|
|
143
|
-
if (isNonEmptyResult(rubyOutput) && loopResult.success) {
|
|
145
|
+
if (isNonEmptyResult(rubyLoopResult.summary) && rubyLoopResult.success) {
|
|
144
146
|
rubySucceeded = true;
|
|
145
147
|
usedRuby = true;
|
|
146
|
-
result = rubyOutput;
|
|
147
148
|
this.display.success('Ruby handled the task without escalation.');
|
|
148
149
|
}
|
|
149
150
|
else {
|
|
@@ -152,40 +153,48 @@ class RubyAlternator {
|
|
|
152
153
|
}
|
|
153
154
|
catch (e) {
|
|
154
155
|
this.display.warning(`Ruby error: ${String(e)} — escalating.`);
|
|
155
|
-
rubyOutput = rubyOutput ?? `Error: ${String(e)}`;
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
if (!usedRuby) {
|
|
160
160
|
this.display.header('Large model', largeModelProvider.name);
|
|
161
161
|
try {
|
|
162
|
-
|
|
162
|
+
largeModelLoopResult = await (0, loop_js_1.runAgentLoop)({
|
|
163
163
|
provider: largeModelProvider,
|
|
164
164
|
task,
|
|
165
165
|
context,
|
|
166
166
|
permissions: this.permissions,
|
|
167
167
|
display: this.display,
|
|
168
|
+
confirmFn,
|
|
169
|
+
initialHistory: this.opts.initialHistory,
|
|
168
170
|
disableSpawn: true,
|
|
169
171
|
});
|
|
170
|
-
largeModelTokens = loopResult.usage.totalTokens;
|
|
171
|
-
largeModelOutput = loopResult.summary;
|
|
172
|
-
result = isNonEmptyResult(largeModelOutput)
|
|
173
|
-
? largeModelOutput
|
|
174
|
-
: loopResult.success
|
|
175
|
-
? '(Task completed with no output)'
|
|
176
|
-
: `Large model did not complete: ${loopResult.summary}`;
|
|
177
172
|
}
|
|
178
173
|
catch (e) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
this.display.error(result);
|
|
174
|
+
errorSummary = `Large model error: ${String(e)}`;
|
|
175
|
+
this.display.error(errorSummary);
|
|
182
176
|
}
|
|
183
177
|
}
|
|
184
178
|
}
|
|
185
179
|
catch (e) {
|
|
186
|
-
|
|
187
|
-
this.display.error(
|
|
180
|
+
errorSummary = `Alternation error: ${String(e)}`;
|
|
181
|
+
this.display.error(errorSummary);
|
|
188
182
|
}
|
|
183
|
+
// The full result that actually represents this run's output — Ruby's
|
|
184
|
+
// if it succeeded, otherwise the large model's, otherwise a safe empty
|
|
185
|
+
// result for the case where something threw before either path ran.
|
|
186
|
+
const finalLoopResult = usedRuby
|
|
187
|
+
? rubyLoopResult
|
|
188
|
+
: largeModelLoopResult ?? {
|
|
189
|
+
success: false,
|
|
190
|
+
summary: errorSummary ?? 'Alternation failed before either model ran.',
|
|
191
|
+
turns: 0,
|
|
192
|
+
toolCallCount: 0,
|
|
193
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
194
|
+
costUsd: 0,
|
|
195
|
+
history: [],
|
|
196
|
+
toolCallLog: [],
|
|
197
|
+
};
|
|
189
198
|
const episode = {
|
|
190
199
|
id: (0, crypto_1.randomUUID)(),
|
|
191
200
|
timestamp: Date.now(),
|
|
@@ -193,13 +202,13 @@ class RubyAlternator {
|
|
|
193
202
|
projectRoot,
|
|
194
203
|
rubyAttempted,
|
|
195
204
|
rubySucceeded,
|
|
196
|
-
rubyOutput,
|
|
205
|
+
rubyOutput: rubyLoopResult?.summary,
|
|
197
206
|
largeModelUsed: usedRuby ? undefined : largeModelProvider.model,
|
|
198
|
-
largeModelOutput: usedRuby ? undefined :
|
|
199
|
-
reviewerApproved: isNonEmptyResult(
|
|
207
|
+
largeModelOutput: usedRuby ? undefined : largeModelLoopResult?.summary,
|
|
208
|
+
reviewerApproved: isNonEmptyResult(finalLoopResult.summary) && finalLoopResult.success,
|
|
200
209
|
tokensUsed: {
|
|
201
|
-
ruby: rubyAttempted ?
|
|
202
|
-
largeModel: usedRuby ? undefined :
|
|
210
|
+
ruby: rubyAttempted ? rubyLoopResult?.usage.totalTokens : undefined,
|
|
211
|
+
largeModel: usedRuby ? undefined : largeModelLoopResult?.usage.totalTokens,
|
|
203
212
|
},
|
|
204
213
|
durationMs: Date.now() - startMs,
|
|
205
214
|
taskCategory: inferTaskCategory(task),
|
|
@@ -219,7 +228,7 @@ class RubyAlternator {
|
|
|
219
228
|
catch {
|
|
220
229
|
/* best-effort */
|
|
221
230
|
}
|
|
222
|
-
return {
|
|
231
|
+
return { loopResult: finalLoopResult, episode, usedRuby, decision };
|
|
223
232
|
}
|
|
224
233
|
/**
|
|
225
234
|
* Returns aggregate episode statistics for this alternator's project.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alternator.js","sourceRoot":"","sources":["../../src/ruby/alternator.ts"],"names":[],"mappings":";;;AAAA,mCAAoC;
|
|
1
|
+
{"version":3,"file":"alternator.js","sourceRoot":"","sources":["../../src/ruby/alternator.ts"],"names":[],"mappings":"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"}
|