u-foo 1.9.8 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -4
- package/src/agent/claudeEventTranslator.js +267 -0
- package/src/agent/claudeOauthTokenReader.js +52 -0
- package/src/agent/claudeThreadProvider.js +343 -0
- package/src/agent/cliRunner.js +4 -16
- package/src/agent/codexEventTranslator.js +78 -0
- package/src/agent/codexThreadProvider.js +181 -0
- package/src/agent/controllerToolExecutor.js +233 -0
- package/src/agent/credentials/claude.js +324 -0
- package/src/agent/credentials/codex.js +203 -0
- package/src/agent/credentials/index.js +106 -0
- package/src/agent/defaultBootstrap.js +128 -5
- package/src/agent/internalRunner.js +333 -2
- package/src/agent/loopObservability.js +190 -0
- package/src/agent/loopRuntime.js +457 -0
- package/src/agent/ufooAgent.js +178 -120
- package/src/agent/upstreamTransport.js +464 -0
- package/src/bus/utils.js +3 -2
- package/src/chat/dashboardView.js +51 -1
- package/src/chat/index.js +3 -1
- package/src/config.js +53 -17
- package/src/controller/flags.js +160 -0
- package/src/controller/gateRouter.js +201 -0
- package/src/controller/routerFastPath.js +22 -0
- package/src/controller/shadowGuard.js +280 -0
- package/src/daemon/index.js +2 -3
- package/src/daemon/promptLoop.js +33 -224
- package/src/daemon/promptRequest.js +360 -5
- package/src/daemon/status.js +2 -0
- package/src/history/inputTimeline.js +9 -4
- package/src/memory/index.js +24 -0
- package/src/providerapi/redactor.js +87 -0
- package/src/providerapi/shadowDiff.js +174 -0
- package/src/report/store.js +4 -3
- package/src/tools/handlers/ackBus.js +26 -0
- package/src/tools/handlers/common.js +64 -0
- package/src/tools/handlers/dispatchMessage.js +81 -0
- package/src/tools/handlers/listAgents.js +14 -0
- package/src/tools/handlers/readBusSummary.js +34 -0
- package/src/tools/handlers/readOpenDecisions.js +26 -0
- package/src/tools/handlers/readProjectRegistry.js +20 -0
- package/src/tools/handlers/readPromptHistory.js +123 -0
- package/src/tools/handlers/tier2.js +134 -0
- package/src/tools/index.js +55 -0
- package/src/tools/registry.js +69 -0
- package/src/tools/schemaFixtures.js +415 -0
- package/src/tools/tier0/listAgents.js +14 -0
- package/src/tools/tier0/readBusSummary.js +14 -0
- package/src/tools/tier0/readOpenDecisions.js +14 -0
- package/src/tools/tier0/readProjectRegistry.js +14 -0
- package/src/tools/tier0/readPromptHistory.js +14 -0
- package/src/tools/tier1/ackBus.js +14 -0
- package/src/tools/tier1/dispatchMessage.js +14 -0
- package/src/tools/tier1/routeAgent.js +14 -0
- package/src/tools/tier2/closeAgent.js +14 -0
- package/src/tools/tier2/launchAgent.js +14 -0
- package/src/tools/tier2/manageCron.js +14 -0
- package/src/tools/tier2/renameAgent.js +14 -0
- package/src/tools/types.js +75 -0
- package/src/tools/unimplemented.js +13 -0
- package/src/ufoo/paths.js +4 -0
- package/bin/ufoo-assistant-agent.js +0 -5
- package/bin/ufoo-engine.js +0 -25
- package/src/assistant/agent.js +0 -261
- package/src/assistant/bridge.js +0 -178
- package/src/assistant/constants.js +0 -15
- package/src/assistant/engine.js +0 -252
- package/src/assistant/stdio.js +0 -58
- package/src/assistant/ufooEngineCli.js +0 -312
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
const { runCliAgent } = require("../agent/cliRunner");
|
|
2
|
-
const { normalizeCliOutput } = require("../agent/normalizeOutput");
|
|
3
|
-
const { loadConfig } = require("../config");
|
|
4
|
-
const { DEFAULT_ASSISTANT_TIMEOUT_MS, normalizeAssistantTimeoutMs } = require("./constants");
|
|
5
|
-
|
|
6
|
-
function normalizeProvider(value, fallback = "codex-cli") {
|
|
7
|
-
const raw = String(value || "").trim().toLowerCase();
|
|
8
|
-
if (!raw) return fallback;
|
|
9
|
-
if (raw === "codex" || raw === "codex-cli") return "codex-cli";
|
|
10
|
-
if (raw === "claude" || raw === "claude-cli") return "claude-cli";
|
|
11
|
-
return fallback;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function parseAssistantTaskArgs(argv = []) {
|
|
15
|
-
const options = {
|
|
16
|
-
assistantTask: false,
|
|
17
|
-
json: false,
|
|
18
|
-
cwd: "",
|
|
19
|
-
model: "",
|
|
20
|
-
sessionId: "",
|
|
21
|
-
provider: "",
|
|
22
|
-
kind: "mixed",
|
|
23
|
-
context: "",
|
|
24
|
-
expect: "",
|
|
25
|
-
timeoutMs: DEFAULT_ASSISTANT_TIMEOUT_MS,
|
|
26
|
-
task: "",
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const args = Array.isArray(argv) ? argv.slice() : [];
|
|
30
|
-
const rest = [];
|
|
31
|
-
for (let i = 0; i < args.length; i += 1) {
|
|
32
|
-
const arg = args[i];
|
|
33
|
-
if (arg === "--assistant-task") {
|
|
34
|
-
options.assistantTask = true;
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
if (arg === "--json") {
|
|
38
|
-
options.json = true;
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
if (arg === "--cwd") {
|
|
42
|
-
options.cwd = args[++i] || "";
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
if (arg === "--model") {
|
|
46
|
-
options.model = args[++i] || "";
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
if (arg === "--session-id") {
|
|
50
|
-
options.sessionId = args[++i] || "";
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
if (arg === "--provider") {
|
|
54
|
-
options.provider = args[++i] || "";
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
if (arg === "--kind") {
|
|
58
|
-
options.kind = args[++i] || "mixed";
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (arg === "--context") {
|
|
62
|
-
options.context = args[++i] || "";
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (arg === "--expect") {
|
|
66
|
-
options.expect = args[++i] || "";
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
if (arg === "--timeout-ms") {
|
|
70
|
-
options.timeoutMs = normalizeAssistantTimeoutMs(args[++i], DEFAULT_ASSISTANT_TIMEOUT_MS);
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
rest.push(arg);
|
|
74
|
-
}
|
|
75
|
-
options.task = rest.join(" ").trim();
|
|
76
|
-
return options;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function buildPrompt({ kind = "mixed", context = "", task = "", expect = "" } = {}) {
|
|
80
|
-
const lines = [];
|
|
81
|
-
lines.push(`Task kind: ${kind || "mixed"}`);
|
|
82
|
-
if (context) {
|
|
83
|
-
lines.push("Context:");
|
|
84
|
-
lines.push(context);
|
|
85
|
-
}
|
|
86
|
-
lines.push("Task:");
|
|
87
|
-
lines.push(task || "");
|
|
88
|
-
if (expect) {
|
|
89
|
-
lines.push("Expected result:");
|
|
90
|
-
lines.push(expect);
|
|
91
|
-
}
|
|
92
|
-
return lines.join("\n");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function buildSystemPrompt() {
|
|
96
|
-
return [
|
|
97
|
-
"You are ufoo-engine, a self-hosted assistant core.",
|
|
98
|
-
"Return ONLY valid JSON.",
|
|
99
|
-
"Schema:",
|
|
100
|
-
"{",
|
|
101
|
-
' "ok": true|false,',
|
|
102
|
-
' "summary": "string",',
|
|
103
|
-
' "artifacts": ["string"],',
|
|
104
|
-
' "logs": ["string"],',
|
|
105
|
-
' "error": "string",',
|
|
106
|
-
' "metrics": {"key":"value"}',
|
|
107
|
-
"}",
|
|
108
|
-
"Rules:",
|
|
109
|
-
"- summary should be concise and actionable.",
|
|
110
|
-
"- error must be non-empty only when ok=false.",
|
|
111
|
-
"- Do not output markdown wrappers.",
|
|
112
|
-
].join("\n");
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function normalizeEngineResult(parsed, fallbackError = "") {
|
|
116
|
-
if (!parsed || typeof parsed !== "object") {
|
|
117
|
-
const text = String(parsed || "").trim();
|
|
118
|
-
if (text) {
|
|
119
|
-
return {
|
|
120
|
-
ok: true,
|
|
121
|
-
summary: text,
|
|
122
|
-
artifacts: [],
|
|
123
|
-
logs: [],
|
|
124
|
-
error: "",
|
|
125
|
-
metrics: {},
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
return {
|
|
129
|
-
ok: false,
|
|
130
|
-
summary: "",
|
|
131
|
-
artifacts: [],
|
|
132
|
-
logs: [],
|
|
133
|
-
error: fallbackError || "ufoo-engine invalid response",
|
|
134
|
-
metrics: {},
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
ok: parsed.ok !== false,
|
|
140
|
-
summary: typeof parsed.summary === "string" ? parsed.summary : "",
|
|
141
|
-
artifacts: Array.isArray(parsed.artifacts) ? parsed.artifacts : [],
|
|
142
|
-
logs: Array.isArray(parsed.logs) ? parsed.logs : [],
|
|
143
|
-
error: typeof parsed.error === "string" ? parsed.error : "",
|
|
144
|
-
metrics: parsed.metrics && typeof parsed.metrics === "object" ? parsed.metrics : {},
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function isSessionError(errorText = "") {
|
|
149
|
-
const text = String(errorText || "").toLowerCase();
|
|
150
|
-
return text.includes("session id")
|
|
151
|
-
|| text.includes("session-id")
|
|
152
|
-
|| text.includes("already in use");
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function parseStdinPayload(stdinText = "") {
|
|
156
|
-
const line = String(stdinText || "")
|
|
157
|
-
.split(/\r?\n/)
|
|
158
|
-
.map((part) => part.trim())
|
|
159
|
-
.find(Boolean);
|
|
160
|
-
if (!line) return null;
|
|
161
|
-
try {
|
|
162
|
-
return JSON.parse(line);
|
|
163
|
-
} catch {
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
async function runEngineTask(taskInput, deps = {}) {
|
|
169
|
-
const {
|
|
170
|
-
runCliAgentImpl = runCliAgent,
|
|
171
|
-
normalizeCliOutputImpl = normalizeCliOutput,
|
|
172
|
-
loadConfigImpl = loadConfig,
|
|
173
|
-
env = process.env,
|
|
174
|
-
cwd = process.cwd(),
|
|
175
|
-
} = deps;
|
|
176
|
-
|
|
177
|
-
const projectRoot = taskInput.cwd || taskInput.projectRoot || cwd;
|
|
178
|
-
const config = loadConfigImpl(projectRoot);
|
|
179
|
-
const provider = normalizeProvider(
|
|
180
|
-
taskInput.provider || env.UFOO_UFOO_ENGINE_PROVIDER || config.agentProvider,
|
|
181
|
-
"codex-cli"
|
|
182
|
-
);
|
|
183
|
-
const model =
|
|
184
|
-
String(taskInput.model || "").trim()
|
|
185
|
-
|| String(env.UFOO_UFOO_ENGINE_MODEL || "").trim()
|
|
186
|
-
|| String(config.agentModel || "").trim()
|
|
187
|
-
|| (provider === "claude-cli" ? "opus" : "");
|
|
188
|
-
|
|
189
|
-
const systemPrompt = buildSystemPrompt();
|
|
190
|
-
const prompt = buildPrompt({
|
|
191
|
-
kind: taskInput.kind,
|
|
192
|
-
context: taskInput.context,
|
|
193
|
-
task: taskInput.task,
|
|
194
|
-
expect: taskInput.expect,
|
|
195
|
-
});
|
|
196
|
-
const timeoutMs = normalizeAssistantTimeoutMs(taskInput.timeoutMs, DEFAULT_ASSISTANT_TIMEOUT_MS);
|
|
197
|
-
|
|
198
|
-
const runOnce = async (sessionId) => runCliAgentImpl({
|
|
199
|
-
provider,
|
|
200
|
-
model,
|
|
201
|
-
prompt,
|
|
202
|
-
systemPrompt,
|
|
203
|
-
sessionId: sessionId || undefined,
|
|
204
|
-
disableSession: false,
|
|
205
|
-
cwd: projectRoot,
|
|
206
|
-
timeoutMs,
|
|
207
|
-
sandbox: taskInput.kind === "explore" ? "read-only" : "workspace-write",
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
let cliRes = await runOnce(taskInput.sessionId || "");
|
|
211
|
-
if (!cliRes.ok && taskInput.sessionId && isSessionError(cliRes.error)) {
|
|
212
|
-
cliRes = await runOnce("");
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (!cliRes.ok) {
|
|
216
|
-
return {
|
|
217
|
-
ok: false,
|
|
218
|
-
summary: "",
|
|
219
|
-
artifacts: [],
|
|
220
|
-
logs: [],
|
|
221
|
-
error: cliRes.error || "ufoo-engine cli failed",
|
|
222
|
-
metrics: {},
|
|
223
|
-
session_id: "",
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const normalized = normalizeCliOutputImpl(cliRes.output);
|
|
228
|
-
let parsed;
|
|
229
|
-
try {
|
|
230
|
-
parsed = JSON.parse(normalized);
|
|
231
|
-
} catch {
|
|
232
|
-
parsed = normalized;
|
|
233
|
-
}
|
|
234
|
-
const result = normalizeEngineResult(parsed);
|
|
235
|
-
return {
|
|
236
|
-
...result,
|
|
237
|
-
session_id: cliRes.sessionId || "",
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async function runUfooEngineCli({ argv = [], stdinText = "", deps = {} } = {}) {
|
|
242
|
-
const options = parseAssistantTaskArgs(argv);
|
|
243
|
-
|
|
244
|
-
let taskInput;
|
|
245
|
-
if (options.assistantTask) {
|
|
246
|
-
if (!options.task) {
|
|
247
|
-
const error = {
|
|
248
|
-
ok: false,
|
|
249
|
-
summary: "",
|
|
250
|
-
artifacts: [],
|
|
251
|
-
logs: [],
|
|
252
|
-
error: "missing task",
|
|
253
|
-
metrics: {},
|
|
254
|
-
};
|
|
255
|
-
return { exitCode: 1, output: `${JSON.stringify(error)}\n` };
|
|
256
|
-
}
|
|
257
|
-
taskInput = {
|
|
258
|
-
task: options.task,
|
|
259
|
-
kind: options.kind,
|
|
260
|
-
context: options.context,
|
|
261
|
-
expect: options.expect,
|
|
262
|
-
provider: options.provider,
|
|
263
|
-
model: options.model,
|
|
264
|
-
sessionId: options.sessionId,
|
|
265
|
-
cwd: options.cwd,
|
|
266
|
-
timeoutMs: normalizeAssistantTimeoutMs(options.timeoutMs, DEFAULT_ASSISTANT_TIMEOUT_MS),
|
|
267
|
-
};
|
|
268
|
-
} else {
|
|
269
|
-
const payload = parseStdinPayload(stdinText);
|
|
270
|
-
if (!payload || typeof payload !== "object") {
|
|
271
|
-
const error = {
|
|
272
|
-
ok: false,
|
|
273
|
-
summary: "",
|
|
274
|
-
artifacts: [],
|
|
275
|
-
logs: [],
|
|
276
|
-
error: "missing request payload",
|
|
277
|
-
metrics: {},
|
|
278
|
-
};
|
|
279
|
-
return { exitCode: 1, output: `${JSON.stringify(error)}\n` };
|
|
280
|
-
}
|
|
281
|
-
taskInput = {
|
|
282
|
-
task: typeof payload.task === "string" ? payload.task : "",
|
|
283
|
-
kind: typeof payload.kind === "string" ? payload.kind : "mixed",
|
|
284
|
-
context: typeof payload.context === "string" ? payload.context : "",
|
|
285
|
-
expect: typeof payload.expect === "string" ? payload.expect : "",
|
|
286
|
-
provider: typeof payload.provider === "string" ? payload.provider : "",
|
|
287
|
-
model: typeof payload.model === "string" ? payload.model : "",
|
|
288
|
-
sessionId: typeof payload.session_id === "string" ? payload.session_id : "",
|
|
289
|
-
cwd: typeof payload.project_root === "string" ? payload.project_root : "",
|
|
290
|
-
timeoutMs: normalizeAssistantTimeoutMs(payload.timeout_ms, DEFAULT_ASSISTANT_TIMEOUT_MS),
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const result = await runEngineTask(taskInput, deps);
|
|
295
|
-
const output = `${JSON.stringify(result)}\n`;
|
|
296
|
-
return {
|
|
297
|
-
exitCode: result.ok === false ? 1 : 0,
|
|
298
|
-
output,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
module.exports = {
|
|
303
|
-
normalizeProvider,
|
|
304
|
-
parseAssistantTaskArgs,
|
|
305
|
-
buildPrompt,
|
|
306
|
-
buildSystemPrompt,
|
|
307
|
-
normalizeEngineResult,
|
|
308
|
-
parseStdinPayload,
|
|
309
|
-
runEngineTask,
|
|
310
|
-
runUfooEngineCli,
|
|
311
|
-
isSessionError,
|
|
312
|
-
};
|