u-foo 2.5.14 → 3.0.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 +1 -1
- package/src/agents/prompts/native/environment.js +20 -8
- package/src/code/agent.js +517 -112
- package/src/code/commands.js +77 -0
- package/src/code/context/artifactGc.js +292 -0
- package/src/code/context/artifactIndex.js +161 -0
- package/src/code/context/artifacts.js +183 -0
- package/src/code/context/assembler.js +703 -0
- package/src/code/context/executionSegment.js +292 -0
- package/src/code/context/index.js +28 -0
- package/src/code/context/planGraph.js +1410 -0
- package/src/code/context/planGraphService.js +857 -0
- package/src/code/context/planMode.js +398 -0
- package/src/code/context/planProjection.js +432 -0
- package/src/code/context/projectSnapshot.js +201 -0
- package/src/code/context/promptLayers.js +175 -0
- package/src/code/context/reducers.js +328 -0
- package/src/code/context/stableJson.js +29 -0
- package/src/code/context/stateCommit.js +414 -0
- package/src/code/context/toolRuntime.js +172 -0
- package/src/code/context/transcript.js +182 -0
- package/src/code/context/transcriptSync.js +106 -0
- package/src/code/context/userInteraction.js +457 -0
- package/src/code/context/userNudge.js +116 -0
- package/src/code/context/workingSet.js +323 -0
- package/src/code/dispatch.js +20 -1
- package/src/code/index.js +8 -0
- package/src/code/modelCommand.js +87 -0
- package/src/code/nativeRunner.js +625 -34
- package/src/code/repl.js +196 -50
- package/src/code/runtime/agentWakeup.js +58 -0
- package/src/code/runtime/graphOwner.js +41 -0
- package/src/code/runtime/graphYieldRouter.js +42 -0
- package/src/code/runtime/index.js +15 -0
- package/src/code/runtime/loopMailbox.js +124 -0
- package/src/code/runtime/runtimeEvents.js +39 -0
- package/src/code/runtime/taskControl.js +565 -0
- package/src/code/runtime/taskFocus.js +165 -0
- package/src/code/runtime/taskLoop.js +383 -0
- package/src/code/runtime/taskRun.js +187 -0
- package/src/code/runtime/toolProvenance.js +70 -0
- package/src/code/runtime/workspaceLease.js +208 -0
- package/src/code/sessionStore.js +217 -15
- package/src/code/skills/index.js +10 -0
- package/src/code/skills/injection.js +66 -3
- package/src/code/skills/loader.js +21 -0
- package/src/code/skills/manifest.js +87 -0
- package/src/code/skills/render.js +15 -1
- package/src/code/taskDecomposer.js +56 -2
- package/src/code/tools/artifactRead.js +40 -0
- package/src/code/tools/askUser.js +11 -0
- package/src/code/tools/planGraph.js +29 -0
- package/src/code/tui.js +2 -0
- package/src/code/usageStore.js +15 -0
- package/src/ui/format/index.js +285 -45
- package/src/ui/format/markdownRenderer.js +436 -71
- package/src/ui/ink/ChatApp.js +39 -8
- package/src/ui/ink/UcodeApp.js +592 -43
- package/src/ui/ink/chatLogModel.js +102 -21
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { randomUUID } = require("crypto");
|
|
4
|
+
const {
|
|
5
|
+
executePlanGraph,
|
|
6
|
+
planGraphFromExecutionSegment,
|
|
7
|
+
compilePlanGraph,
|
|
8
|
+
} = require("./planGraph");
|
|
9
|
+
|
|
10
|
+
function emptyExecutionState() {
|
|
11
|
+
return {
|
|
12
|
+
currentSegmentId: "",
|
|
13
|
+
mode: "single_action",
|
|
14
|
+
planMode: false,
|
|
15
|
+
planModeSource: "",
|
|
16
|
+
steps: {},
|
|
17
|
+
modifiedFiles: [],
|
|
18
|
+
lastExitCodes: [],
|
|
19
|
+
approvals: [],
|
|
20
|
+
retries: {},
|
|
21
|
+
segments: [],
|
|
22
|
+
pendingUserPrompts: [],
|
|
23
|
+
planGraph: require("./planGraphService").emptyPlanGraphState(),
|
|
24
|
+
graphs: {},
|
|
25
|
+
taskRuns: require("../runtime/taskRun").emptyTaskRunStore(),
|
|
26
|
+
agentMailbox: require("../runtime/loopMailbox").emptyMailbox(),
|
|
27
|
+
taskMailboxes: {},
|
|
28
|
+
workspaceLease: require("../runtime/workspaceLease").emptyWorkspaceLease(),
|
|
29
|
+
planUi: { bandMode: "auto" },
|
|
30
|
+
pendingUserInteraction: null,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function createSegmentId() {
|
|
35
|
+
return `seg_${Date.now().toString(36)}_${randomUUID().slice(0, 6)}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function normalizeExecutionSegment(segment = {}) {
|
|
39
|
+
const source = segment && typeof segment === "object" ? segment : {};
|
|
40
|
+
const steps = Array.isArray(source.steps) ? source.steps : [];
|
|
41
|
+
return {
|
|
42
|
+
type: String(source.type || "execution_segment").trim(),
|
|
43
|
+
objective: String(source.objective || "").trim(),
|
|
44
|
+
steps: steps.map((step, index) => ({
|
|
45
|
+
id: String(step.id || `s${index + 1}`).trim(),
|
|
46
|
+
tool: String(step.tool || "").trim(),
|
|
47
|
+
args: step.args && typeof step.args === "object" ? step.args : {},
|
|
48
|
+
dependsOn: Array.isArray(step.dependsOn) ? step.dependsOn.map(String) : [],
|
|
49
|
+
})),
|
|
50
|
+
checkpoint: source.checkpoint && typeof source.checkpoint === "object"
|
|
51
|
+
? source.checkpoint
|
|
52
|
+
: { after: [] },
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function startExecutionSegment(executionState = null, segment = {}) {
|
|
57
|
+
const state = executionState && typeof executionState === "object"
|
|
58
|
+
? { ...executionState }
|
|
59
|
+
: emptyExecutionState();
|
|
60
|
+
const normalized = normalizeExecutionSegment(segment);
|
|
61
|
+
const segmentId = createSegmentId();
|
|
62
|
+
state.currentSegmentId = segmentId;
|
|
63
|
+
state.mode = normalized.type === "execution_segment" ? "execution_segment" : "single_action";
|
|
64
|
+
state.segments = Array.isArray(state.segments) ? state.segments : [];
|
|
65
|
+
state.segments.push({
|
|
66
|
+
segmentId,
|
|
67
|
+
objective: normalized.objective,
|
|
68
|
+
startedAt: new Date().toISOString(),
|
|
69
|
+
steps: normalized.steps,
|
|
70
|
+
checkpoint: normalized.checkpoint,
|
|
71
|
+
status: "running",
|
|
72
|
+
});
|
|
73
|
+
state.steps = {};
|
|
74
|
+
return { state, segmentId, segment: normalized };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function recordStepResult(executionState = null, {
|
|
78
|
+
stepId = "",
|
|
79
|
+
status = "success",
|
|
80
|
+
artifactId = "",
|
|
81
|
+
exitCode = null,
|
|
82
|
+
error = "",
|
|
83
|
+
} = {}) {
|
|
84
|
+
const state = executionState && typeof executionState === "object"
|
|
85
|
+
? { ...executionState }
|
|
86
|
+
: emptyExecutionState();
|
|
87
|
+
state.steps = state.steps && typeof state.steps === "object" ? { ...state.steps } : {};
|
|
88
|
+
state.steps[stepId] = {
|
|
89
|
+
status: String(status || "success"),
|
|
90
|
+
artifactId: String(artifactId || ""),
|
|
91
|
+
exitCode,
|
|
92
|
+
error: String(error || ""),
|
|
93
|
+
at: new Date().toISOString(),
|
|
94
|
+
};
|
|
95
|
+
return state;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function shouldStopSegment(executionState = null, {
|
|
99
|
+
hadError = false,
|
|
100
|
+
schemaMismatch = false,
|
|
101
|
+
sideEffect = false,
|
|
102
|
+
reachedCheckpoint = false,
|
|
103
|
+
} = {}) {
|
|
104
|
+
if (hadError || schemaMismatch || sideEffect) return true;
|
|
105
|
+
if (reachedCheckpoint) return true;
|
|
106
|
+
const state = executionState && typeof executionState === "object" ? executionState : null;
|
|
107
|
+
if (!state || state.mode !== "execution_segment") return true;
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function renderExecutionSegmentContext(executionState = null) {
|
|
112
|
+
if (!executionState || typeof executionState !== "object") return "";
|
|
113
|
+
const lines = [];
|
|
114
|
+
if (executionState.planMode) {
|
|
115
|
+
// Detailed plan-mode instructions come from renderPlanModeContext.
|
|
116
|
+
lines.push("Execution mode: plan_mode");
|
|
117
|
+
}
|
|
118
|
+
if (!executionState.currentSegmentId && !(executionState.planGraph && executionState.planGraph.graphId)) {
|
|
119
|
+
return lines.join("\n");
|
|
120
|
+
}
|
|
121
|
+
if (executionState.currentSegmentId) {
|
|
122
|
+
lines.push(
|
|
123
|
+
"Current Execution Segment:",
|
|
124
|
+
`- Segment: ${executionState.currentSegmentId}`,
|
|
125
|
+
`- Mode: ${executionState.mode || "single_action"}`,
|
|
126
|
+
);
|
|
127
|
+
const steps = executionState.steps && typeof executionState.steps === "object"
|
|
128
|
+
? Object.entries(executionState.steps)
|
|
129
|
+
: [];
|
|
130
|
+
if (steps.length > 0) {
|
|
131
|
+
lines.push("Step status:");
|
|
132
|
+
for (const [id, info] of steps) {
|
|
133
|
+
lines.push(`- ${id}: ${info.status}${info.error ? ` (${info.error})` : ""}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return lines.join("\n");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function parseExecutionSegment(sideEffects = null) {
|
|
141
|
+
if (!sideEffects || typeof sideEffects !== "object") return null;
|
|
142
|
+
if (sideEffects.nextSegment) return normalizeExecutionSegment(sideEffects.nextSegment);
|
|
143
|
+
if (sideEffects.type === "execution_segment") return normalizeExecutionSegment(sideEffects);
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const DEFAULT_MAX_SEGMENT_STEPS = 16;
|
|
148
|
+
const SIDE_EFFECT_TOOLS = new Set(["write", "edit"]);
|
|
149
|
+
|
|
150
|
+
function isSideEffectTool(tool = "") {
|
|
151
|
+
return SIDE_EFFECT_TOOLS.has(String(tool || "").trim().toLowerCase());
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function formatSegmentResultMessage(result = {}) {
|
|
155
|
+
return JSON.stringify({
|
|
156
|
+
type: "execution_segment_result",
|
|
157
|
+
segmentId: result.segmentId || "",
|
|
158
|
+
ok: result.ok !== false,
|
|
159
|
+
objective: result.objective || "",
|
|
160
|
+
stoppedAt: result.stoppedAt || "",
|
|
161
|
+
steps: Array.isArray(result.results) ? result.results : [],
|
|
162
|
+
error: result.error || "",
|
|
163
|
+
plan: result.summary || null,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Execute a legacy execution_segment via the unified plan graph engine.
|
|
169
|
+
* Preserves the previous return shape used by agent/nativeRunner.
|
|
170
|
+
*/
|
|
171
|
+
function executeExecutionSegment({
|
|
172
|
+
segment = {},
|
|
173
|
+
executionState = null,
|
|
174
|
+
runStep = () => ({ ok: false, error: "no runner" }),
|
|
175
|
+
onStepStart = null,
|
|
176
|
+
onStepComplete = null,
|
|
177
|
+
maxSteps = DEFAULT_MAX_SEGMENT_STEPS,
|
|
178
|
+
} = {}) {
|
|
179
|
+
const normalized = normalizeExecutionSegment(segment);
|
|
180
|
+
const cappedSteps = normalized.steps.slice(0, Math.max(1, Math.floor(maxSteps)));
|
|
181
|
+
const cappedSegment = { ...normalized, steps: cappedSteps };
|
|
182
|
+
const { state: startedState, segmentId } = startExecutionSegment(executionState, cappedSegment);
|
|
183
|
+
let state = startedState;
|
|
184
|
+
|
|
185
|
+
const plan = planGraphFromExecutionSegment(cappedSegment);
|
|
186
|
+
plan.id = segmentId;
|
|
187
|
+
|
|
188
|
+
const graphResult = executePlanGraph(plan, {
|
|
189
|
+
maxNodeRuns: Math.max(1, Math.floor(maxSteps)) * 2,
|
|
190
|
+
runStep: ({ stepId, tool, args }) => {
|
|
191
|
+
if (typeof onStepStart === "function") {
|
|
192
|
+
try {
|
|
193
|
+
onStepStart({ stepId, tool, args });
|
|
194
|
+
} catch {
|
|
195
|
+
// ignore
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const result = runStep({ stepId, tool, args }) || { ok: false, error: "step failed" };
|
|
199
|
+
if (typeof onStepComplete === "function") {
|
|
200
|
+
try {
|
|
201
|
+
onStepComplete({ stepId, tool, args, result });
|
|
202
|
+
} catch {
|
|
203
|
+
// ignore
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (result && result.ok !== false) {
|
|
207
|
+
state = recordStepResult(state, {
|
|
208
|
+
stepId,
|
|
209
|
+
status: "success",
|
|
210
|
+
artifactId: result.artifactId || "",
|
|
211
|
+
exitCode: Number.isFinite(result.code) ? result.code : null,
|
|
212
|
+
});
|
|
213
|
+
} else {
|
|
214
|
+
state = recordStepResult(state, {
|
|
215
|
+
stepId,
|
|
216
|
+
status: "failed",
|
|
217
|
+
error: String((result && result.error) || "step failed"),
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
return result;
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const results = Array.isArray(graphResult.results) ? graphResult.results : [];
|
|
225
|
+
const stoppedAt = String(graphResult.stoppedAt || "");
|
|
226
|
+
const fatalError = graphResult.ok === false
|
|
227
|
+
? String(graphResult.error || "segment failed")
|
|
228
|
+
: "";
|
|
229
|
+
|
|
230
|
+
let finalStatus = "success";
|
|
231
|
+
if (fatalError) finalStatus = "failed";
|
|
232
|
+
else if (stoppedAt === "checkpoint" || stoppedAt === "waiting_llm") finalStatus = "checkpoint";
|
|
233
|
+
else if (stoppedAt === "side_effect") finalStatus = "success";
|
|
234
|
+
|
|
235
|
+
state = completeExecutionSegment(state, { status: finalStatus, error: fatalError });
|
|
236
|
+
return {
|
|
237
|
+
ok: graphResult.ok !== false,
|
|
238
|
+
segmentId,
|
|
239
|
+
objective: cappedSegment.objective,
|
|
240
|
+
executionState: state,
|
|
241
|
+
results,
|
|
242
|
+
error: fatalError,
|
|
243
|
+
stoppedAt,
|
|
244
|
+
waitingFor: graphResult.waitingFor || null,
|
|
245
|
+
summary: graphResult.summary || null,
|
|
246
|
+
compile: graphResult.compile || null,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function completeExecutionSegment(executionState = null, { status = "success", error = "" } = {}) {
|
|
251
|
+
const state = executionState && typeof executionState === "object"
|
|
252
|
+
? { ...executionState }
|
|
253
|
+
: emptyExecutionState();
|
|
254
|
+
const segments = Array.isArray(state.segments) ? state.segments.slice() : [];
|
|
255
|
+
const currentId = String(state.currentSegmentId || "").trim();
|
|
256
|
+
if (currentId) {
|
|
257
|
+
for (let i = segments.length - 1; i >= 0; i -= 1) {
|
|
258
|
+
if (segments[i].segmentId === currentId) {
|
|
259
|
+
segments[i] = {
|
|
260
|
+
...segments[i],
|
|
261
|
+
status,
|
|
262
|
+
error: String(error || ""),
|
|
263
|
+
endedAt: new Date().toISOString(),
|
|
264
|
+
};
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
state.segments = segments;
|
|
270
|
+
state.currentSegmentId = "";
|
|
271
|
+
state.mode = "single_action";
|
|
272
|
+
return state;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
module.exports = {
|
|
276
|
+
DEFAULT_MAX_SEGMENT_STEPS,
|
|
277
|
+
emptyExecutionState,
|
|
278
|
+
createSegmentId,
|
|
279
|
+
normalizeExecutionSegment,
|
|
280
|
+
startExecutionSegment,
|
|
281
|
+
recordStepResult,
|
|
282
|
+
shouldStopSegment,
|
|
283
|
+
renderExecutionSegmentContext,
|
|
284
|
+
parseExecutionSegment,
|
|
285
|
+
completeExecutionSegment,
|
|
286
|
+
executeExecutionSegment,
|
|
287
|
+
formatSegmentResultMessage,
|
|
288
|
+
isSideEffectTool,
|
|
289
|
+
planGraphFromExecutionSegment,
|
|
290
|
+
compilePlanGraph,
|
|
291
|
+
executePlanGraph,
|
|
292
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
...require("./transcript"),
|
|
5
|
+
...require("./transcriptSync"),
|
|
6
|
+
...require("./artifacts"),
|
|
7
|
+
...require("./artifactIndex"),
|
|
8
|
+
...require("./artifactGc"),
|
|
9
|
+
...require("./stableJson"),
|
|
10
|
+
...require("./reducers"),
|
|
11
|
+
...require("./promptLayers"),
|
|
12
|
+
...require("./projectSnapshot"),
|
|
13
|
+
...require("./stateCommit"),
|
|
14
|
+
...require("./workingSet"),
|
|
15
|
+
...require("./executionSegment"),
|
|
16
|
+
...require("./planGraph"),
|
|
17
|
+
...require("./planGraphService"),
|
|
18
|
+
...require("./toolRuntime"),
|
|
19
|
+
...require("./planMode"),
|
|
20
|
+
...require("./planProjection"),
|
|
21
|
+
...require("./userNudge"),
|
|
22
|
+
...require("./userInteraction"),
|
|
23
|
+
...require("./assembler"),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Runtime TaskLoop surface (avoid name clashes by nesting under .runtime if needed by callers)
|
|
27
|
+
module.exports.runtime = require("../runtime");
|
|
28
|
+
|