u-foo 3.0.0 → 3.0.1
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/code/agent.js +17 -3
- package/src/code/context/executionSegment.js +5 -0
- package/src/code/context/planMode.js +8 -1
- package/src/code/index.js +2 -0
- package/src/code/nativeRunner.js +143 -207
- package/src/code/protocol/controlPlane.js +93 -0
- package/src/code/protocol/faultHarness.js +90 -0
- package/src/code/protocol/index.js +20 -0
- package/src/code/protocol/loopEvents.js +102 -0
- package/src/code/protocol/materialize.js +107 -0
- package/src/code/protocol/messageFixtures.js +116 -0
- package/src/code/protocol/ownership.js +147 -0
- package/src/code/protocol/protocolValidator.js +165 -0
- package/src/code/protocol/suspension.js +173 -0
- package/src/code/protocol/toolCallLedger.js +222 -0
- package/src/code/protocol/transitions.js +97 -0
- package/src/code/providers/anthropicMessagesTransport.js +93 -0
- package/src/code/providers/index.js +7 -0
- package/src/code/providers/openaiChatTransport.js +98 -0
- package/src/code/providers/transportContract.js +46 -0
- package/src/code/repl.js +8 -21
- package/src/code/runtime/taskLoop.js +13 -2
- package/src/code/runtime/taskRun.js +162 -1
- package/src/code/runtime/workspaceLease.js +41 -0
- package/src/code/sessionStore.js +1 -0
- package/src/code/taskRoute.js +73 -0
- package/src/ui/ink/UcodeApp.js +10 -27
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Structural / explicit decomposition upgrade decisions (R7).
|
|
5
|
+
* Not a language-specific bug-keyword classifier.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
function shouldUpgradeToDecomposition(task = "", options = {}) {
|
|
9
|
+
const text = String(task || "").trim();
|
|
10
|
+
const reasons = [];
|
|
11
|
+
|
|
12
|
+
if (options.forceDirect === true || options.disableDecomposition === true) {
|
|
13
|
+
return {
|
|
14
|
+
upgrade: false,
|
|
15
|
+
reason: "forced_direct",
|
|
16
|
+
reasons: ["forced_direct"],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (options.forceDecomposition === true || options.forceDecompose === true) {
|
|
20
|
+
return {
|
|
21
|
+
upgrade: true,
|
|
22
|
+
reason: "forced_decomposition",
|
|
23
|
+
reasons: ["forced_decomposition"],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (!text) {
|
|
27
|
+
return { upgrade: false, reason: "empty", reasons: ["empty"] };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Explicit user/model requests (EN + ZH).
|
|
31
|
+
if (/(?:\bdecompos(?:e|ition)\b|\bbreak\s+(?:this|it)\s+down\b|\bmulti[- ]?step\s+plan\b|拆解|分步|分解任务|制定计划)/i.test(text)) {
|
|
32
|
+
reasons.push("explicit_decompose_request");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Multiple independently verifiable goals (numbered / bulleted / conjunctions).
|
|
36
|
+
const numbered = (text.match(/(?:^|\n)\s*(?:\d+[\).]|[-*•])\s+\S+/g) || []).length;
|
|
37
|
+
if (numbered >= 2) reasons.push("multiple_listed_goals");
|
|
38
|
+
|
|
39
|
+
const multiClause = /(?:^|[;;。\n])\s*(?:and\s+also|also|然后|并且|同时|另外|以及)\b/i.test(text)
|
|
40
|
+
|| (text.split(/[;;]/).map((s) => s.trim()).filter((s) => s.length > 12).length >= 3);
|
|
41
|
+
if (multiClause) reasons.push("multi_clause_objectives");
|
|
42
|
+
|
|
43
|
+
// High-risk / multi-file structural cues (not "fix" alone).
|
|
44
|
+
if (/\b(?:across\s+(?:files?|modules?|packages?)|multiple\s+files?|refactor\s+the\s+\w+|迁移|跨文件|多文件)\b/i.test(text)) {
|
|
45
|
+
reasons.push("multi_file_or_refactor_scope");
|
|
46
|
+
}
|
|
47
|
+
if (/\b(?:checkpoint|rollback|migration|schema\s+change|生产环境|回滚)\b/i.test(text)) {
|
|
48
|
+
reasons.push("high_risk_change");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Runtime budget / prior failures may request upgrade.
|
|
52
|
+
if (Number(options.failureCount || 0) >= 2) {
|
|
53
|
+
reasons.push("repeated_failures");
|
|
54
|
+
}
|
|
55
|
+
if (options.modelRequestedUpgrade === true) {
|
|
56
|
+
reasons.push("model_route_decision");
|
|
57
|
+
}
|
|
58
|
+
if (options.hasPlanGraph === true) {
|
|
59
|
+
// Already structured — keep direct loop unless other reasons fire.
|
|
60
|
+
// (graph exists is not itself a decompose trigger)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const upgrade = reasons.length > 0;
|
|
64
|
+
return {
|
|
65
|
+
upgrade,
|
|
66
|
+
reason: upgrade ? reasons[0] : "direct_default",
|
|
67
|
+
reasons,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
shouldUpgradeToDecomposition,
|
|
73
|
+
};
|
package/src/ui/ink/UcodeApp.js
CHANGED
|
@@ -950,18 +950,8 @@ function createUcodeApp({ React, ink, props, interactive = true }) {
|
|
|
950
950
|
|
|
951
951
|
// Pending approval/choice/chat takes priority over nudge / new NL.
|
|
952
952
|
try {
|
|
953
|
-
const {
|
|
954
|
-
hasPendingUserInteraction,
|
|
955
|
-
parseUserInteractionInput,
|
|
956
|
-
getPendingUserInteraction,
|
|
957
|
-
} = require("../../code/context/userInteraction");
|
|
953
|
+
const { hasPendingUserInteraction } = require("../../code/context/userInteraction");
|
|
958
954
|
if (props.state && props.state.executionState && hasPendingUserInteraction(props.state.executionState)) {
|
|
959
|
-
const pending = getPendingUserInteraction(props.state.executionState);
|
|
960
|
-
const parsed = parseUserInteractionInput(pending, trimmed);
|
|
961
|
-
if (!parsed.ok) {
|
|
962
|
-
appendLogText(parsed.error || "Invalid reply", "error");
|
|
963
|
-
return;
|
|
964
|
-
}
|
|
965
955
|
appendLogText(`› ${trimmed}`, "user");
|
|
966
956
|
const startedAt = Date.now();
|
|
967
957
|
setStatus({
|
|
@@ -972,14 +962,14 @@ function createUcodeApp({ React, ink, props, interactive = true }) {
|
|
|
972
962
|
});
|
|
973
963
|
runChainRef.current = runChainRef.current
|
|
974
964
|
.then(async () => {
|
|
975
|
-
const
|
|
976
|
-
? props.
|
|
977
|
-
: require("../../code/
|
|
965
|
+
const submit = typeof props.submitUserInteractionAnswer === "function"
|
|
966
|
+
? props.submitUserInteractionAnswer
|
|
967
|
+
: require("../../code/protocol").submitUserInteractionAnswer;
|
|
978
968
|
let streamBuf = "";
|
|
979
969
|
let sawStreamText = false;
|
|
980
970
|
let streamStarted = false;
|
|
981
971
|
let dropLeadingStreamBlank = false;
|
|
982
|
-
const result = await
|
|
972
|
+
const result = await submit(trimmed, props.state, {
|
|
983
973
|
onDelta: (delta) => {
|
|
984
974
|
const text = String(delta || "");
|
|
985
975
|
if (!text) return;
|
|
@@ -1006,19 +996,12 @@ function createUcodeApp({ React, ink, props, interactive = true }) {
|
|
|
1006
996
|
}
|
|
1007
997
|
flushTableBuffer();
|
|
1008
998
|
refreshPlanUi();
|
|
1009
|
-
if (result && result.waitingUserInteraction) {
|
|
1010
|
-
appendLogText("Still waiting for your reply.", "system");
|
|
1011
|
-
setStatus({ message: "", type: "thinking", showTimer: false, startedAt: 0 });
|
|
1012
|
-
return;
|
|
1013
|
-
}
|
|
1014
999
|
if (!result || result.ok === false) {
|
|
1015
1000
|
appendLogText(`Error: ${(result && result.error) || "resume failed"}`, "error");
|
|
1016
|
-
} else {
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
appendLogText(result.summary);
|
|
1021
|
-
}
|
|
1001
|
+
} else if (result.shouldEchoSummary) {
|
|
1002
|
+
appendLogText(result.echoSummaryText || result.summary || "", result.waitingUserInteraction ? "system" : "assistant");
|
|
1003
|
+
} else if (result.waitingUserInteraction) {
|
|
1004
|
+
appendLogText("Still waiting for your reply.", "system");
|
|
1022
1005
|
}
|
|
1023
1006
|
setStatus({ message: "", type: "thinking", showTimer: false, startedAt: 0 });
|
|
1024
1007
|
})
|
|
@@ -1067,7 +1050,7 @@ function createUcodeApp({ React, ink, props, interactive = true }) {
|
|
|
1067
1050
|
flushActiveMerge,
|
|
1068
1051
|
flushTableBuffer,
|
|
1069
1052
|
props.state,
|
|
1070
|
-
props.
|
|
1053
|
+
props.submitUserInteractionAnswer,
|
|
1071
1054
|
refreshPlanUi,
|
|
1072
1055
|
]);
|
|
1073
1056
|
|