u-foo 2.3.30 → 2.3.32
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 +5 -1
- package/scripts/chat-app-smoke.js +30 -0
- package/scripts/ink-demo.js +23 -0
- package/scripts/ink-smoke.js +30 -0
- package/scripts/ucode-app-smoke.js +36 -0
- package/src/chat/commandExecutor.js +6 -2
- package/src/chat/daemonMessageRouter.js +9 -1
- package/src/chat/daemonTransport.js +2 -1
- package/src/chat/dashboardKeyController.js +0 -40
- package/src/chat/dashboardView.js +0 -20
- package/src/chat/index.js +9 -1
- package/src/chat/inputSubmitHandler.js +34 -0
- package/src/chat/projectCloseController.js +1 -1
- package/src/chat/shellCommand.js +42 -0
- package/src/chat/transport.js +16 -3
- package/src/cli.js +4 -3
- package/src/code/agent.js +4 -0
- package/src/code/nativeRunner.js +74 -0
- package/src/code/taskDecomposer.js +5 -4
- package/src/code/tui.js +73 -561
- package/src/daemon/index.js +169 -27
- package/src/daemon/ipcServer.js +23 -1
- package/src/daemon/promptRequest.js +6 -1
- package/src/daemon/run.js +11 -4
- package/src/projects/runtimes.js +1 -1
- package/src/ufoo/agentRegistryDiagnostics.js +43 -0
- package/src/ui/MIGRATION.md +382 -0
- package/src/ui/components/ChatApp.js +2950 -0
- package/src/ui/components/DashboardBar.js +417 -0
- package/src/ui/components/InkDemo.js +96 -0
- package/src/ui/components/MultilineInput.js +387 -0
- package/src/ui/components/UcodeApp.js +813 -0
- package/src/ui/components/agentMirror.js +725 -0
- package/src/ui/components/chatReducer.js +337 -0
- package/src/ui/format/index.js +997 -0
- package/src/ui/index.js +9 -0
- package/src/ui/runInk.js +57 -0
- package/src/utils/nodeExecutable.js +26 -0
package/src/code/nativeRunner.js
CHANGED
|
@@ -512,12 +512,23 @@ function runCoreTool({ tool = "", args = {}, workspaceRoot = process.cwd(), onTo
|
|
|
512
512
|
return result;
|
|
513
513
|
}
|
|
514
514
|
|
|
515
|
+
function emitPhase(callback, event = {}) {
|
|
516
|
+
if (typeof callback !== "function") return;
|
|
517
|
+
try {
|
|
518
|
+
callback(event);
|
|
519
|
+
} catch {
|
|
520
|
+
// ignore phase callback failures
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
515
524
|
async function runOpenAiLikeTurn({
|
|
516
525
|
url = "",
|
|
517
526
|
apiKey = "",
|
|
518
527
|
model = "",
|
|
519
528
|
messages = [],
|
|
520
529
|
onTextDelta = null,
|
|
530
|
+
onThinkingDelta = null,
|
|
531
|
+
onPhase = null,
|
|
521
532
|
signal = null,
|
|
522
533
|
timeoutMs = 300000,
|
|
523
534
|
} = {}) {
|
|
@@ -540,6 +551,8 @@ async function runOpenAiLikeTurn({
|
|
|
540
551
|
|
|
541
552
|
const request = createRequestController({ signal, timeoutMs });
|
|
542
553
|
|
|
554
|
+
emitPhase(onPhase, { type: "request_start" });
|
|
555
|
+
|
|
543
556
|
try {
|
|
544
557
|
const response = await fetch(url, {
|
|
545
558
|
method: "POST",
|
|
@@ -574,6 +587,7 @@ async function runOpenAiLikeTurn({
|
|
|
574
587
|
const toolCallMap = new Map();
|
|
575
588
|
let rawBuffer = "";
|
|
576
589
|
let responseText = "";
|
|
590
|
+
const announcedToolNames = new Set();
|
|
577
591
|
|
|
578
592
|
while (true) {
|
|
579
593
|
const { done, value } = await reader.read();
|
|
@@ -599,8 +613,19 @@ async function runOpenAiLikeTurn({
|
|
|
599
613
|
|
|
600
614
|
const delta = choice.delta && typeof choice.delta === "object" ? choice.delta : {};
|
|
601
615
|
|
|
616
|
+
const reasoningChunk = typeof delta.reasoning_content === "string"
|
|
617
|
+
? delta.reasoning_content
|
|
618
|
+
: (typeof delta.reasoning === "string" ? delta.reasoning : "");
|
|
619
|
+
if (reasoningChunk) {
|
|
620
|
+
emitPhase(onPhase, { type: "thinking_delta", text: reasoningChunk });
|
|
621
|
+
if (typeof onThinkingDelta === "function") {
|
|
622
|
+
onThinkingDelta(reasoningChunk);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
602
626
|
if (typeof delta.content === "string" && delta.content) {
|
|
603
627
|
responseText += delta.content;
|
|
628
|
+
emitPhase(onPhase, { type: "text_delta", text: delta.content });
|
|
604
629
|
if (typeof onTextDelta === "function") {
|
|
605
630
|
onTextDelta(delta.content);
|
|
606
631
|
}
|
|
@@ -629,6 +654,13 @@ async function runOpenAiLikeTurn({
|
|
|
629
654
|
}
|
|
630
655
|
|
|
631
656
|
toolCallMap.set(index, previous);
|
|
657
|
+
|
|
658
|
+
const toolName = previous.function.name;
|
|
659
|
+
const announceKey = `${index}:${toolName}`;
|
|
660
|
+
if (toolName && !announcedToolNames.has(announceKey)) {
|
|
661
|
+
announcedToolNames.add(announceKey);
|
|
662
|
+
emitPhase(onPhase, { type: "tool_request", name: toolName });
|
|
663
|
+
}
|
|
632
664
|
}
|
|
633
665
|
}
|
|
634
666
|
}
|
|
@@ -716,6 +748,8 @@ async function runAnthropicTurn({
|
|
|
716
748
|
systemPrompt = "",
|
|
717
749
|
messages = [],
|
|
718
750
|
onTextDelta = null,
|
|
751
|
+
onThinkingDelta = null,
|
|
752
|
+
onPhase = null,
|
|
719
753
|
signal = null,
|
|
720
754
|
timeoutMs = 300000,
|
|
721
755
|
} = {}) {
|
|
@@ -741,6 +775,8 @@ async function runAnthropicTurn({
|
|
|
741
775
|
|
|
742
776
|
const request = createRequestController({ signal, timeoutMs });
|
|
743
777
|
|
|
778
|
+
emitPhase(onPhase, { type: "request_start" });
|
|
779
|
+
|
|
744
780
|
try {
|
|
745
781
|
const response = await fetch(url, {
|
|
746
782
|
method: "POST",
|
|
@@ -811,6 +847,12 @@ async function runAnthropicTurn({
|
|
|
811
847
|
type: "text",
|
|
812
848
|
text: String(contentBlock.text || ""),
|
|
813
849
|
});
|
|
850
|
+
} else if (contentBlock.type === "thinking") {
|
|
851
|
+
blockMap.set(index, {
|
|
852
|
+
order: index,
|
|
853
|
+
type: "thinking",
|
|
854
|
+
text: String(contentBlock.thinking || ""),
|
|
855
|
+
});
|
|
814
856
|
} else if (contentBlock.type === "tool_use") {
|
|
815
857
|
blockMap.set(index, {
|
|
816
858
|
order: index,
|
|
@@ -822,6 +864,10 @@ async function runAnthropicTurn({
|
|
|
822
864
|
: {},
|
|
823
865
|
inputJson: "",
|
|
824
866
|
});
|
|
867
|
+
const toolName = String(contentBlock.name || "");
|
|
868
|
+
if (toolName) {
|
|
869
|
+
emitPhase(onPhase, { type: "tool_request", name: toolName });
|
|
870
|
+
}
|
|
825
871
|
}
|
|
826
872
|
continue;
|
|
827
873
|
}
|
|
@@ -840,6 +886,7 @@ async function runAnthropicTurn({
|
|
|
840
886
|
blockMap.set(index, current);
|
|
841
887
|
if (deltaText) {
|
|
842
888
|
responseText += deltaText;
|
|
889
|
+
emitPhase(onPhase, { type: "text_delta", text: deltaText });
|
|
843
890
|
if (typeof onTextDelta === "function") {
|
|
844
891
|
onTextDelta(deltaText);
|
|
845
892
|
}
|
|
@@ -847,6 +894,20 @@ async function runAnthropicTurn({
|
|
|
847
894
|
continue;
|
|
848
895
|
}
|
|
849
896
|
|
|
897
|
+
if (delta.type === "thinking_delta") {
|
|
898
|
+
const deltaText = String(delta.thinking || "");
|
|
899
|
+
current.type = "thinking";
|
|
900
|
+
current.text = `${String(current.text || "")}${deltaText}`;
|
|
901
|
+
blockMap.set(index, current);
|
|
902
|
+
if (deltaText) {
|
|
903
|
+
emitPhase(onPhase, { type: "thinking_delta", text: deltaText });
|
|
904
|
+
if (typeof onThinkingDelta === "function") {
|
|
905
|
+
onThinkingDelta(deltaText);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
continue;
|
|
909
|
+
}
|
|
910
|
+
|
|
850
911
|
if (delta.type === "input_json_delta") {
|
|
851
912
|
current.type = "tool_use";
|
|
852
913
|
current.inputJson = `${String(current.inputJson || "")}${String(delta.partial_json || "")}`;
|
|
@@ -859,6 +920,7 @@ async function runAnthropicTurn({
|
|
|
859
920
|
|
|
860
921
|
const assistantContent = Array.from(blockMap.values())
|
|
861
922
|
.sort((a, b) => a.order - b.order)
|
|
923
|
+
.filter((item) => item.type !== "thinking")
|
|
862
924
|
.map((item) => {
|
|
863
925
|
if (item.type === "text") {
|
|
864
926
|
return {
|
|
@@ -919,6 +981,8 @@ async function runNativeLoopOpenAi({
|
|
|
919
981
|
apiKey = "",
|
|
920
982
|
timeoutMs = 300000,
|
|
921
983
|
onStreamDelta = null,
|
|
984
|
+
onThinkingDelta = null,
|
|
985
|
+
onPhase = null,
|
|
922
986
|
onToolEvent = null,
|
|
923
987
|
signal = null,
|
|
924
988
|
guards,
|
|
@@ -957,6 +1021,8 @@ async function runNativeLoopOpenAi({
|
|
|
957
1021
|
messages,
|
|
958
1022
|
signal,
|
|
959
1023
|
timeoutMs,
|
|
1024
|
+
onPhase,
|
|
1025
|
+
onThinkingDelta,
|
|
960
1026
|
onTextDelta: (chunk) => {
|
|
961
1027
|
const text = String(chunk || "");
|
|
962
1028
|
if (!text) return;
|
|
@@ -1061,6 +1127,8 @@ async function runNativeLoopAnthropic({
|
|
|
1061
1127
|
apiKey = "",
|
|
1062
1128
|
timeoutMs = 300000,
|
|
1063
1129
|
onStreamDelta = null,
|
|
1130
|
+
onThinkingDelta = null,
|
|
1131
|
+
onPhase = null,
|
|
1064
1132
|
onToolEvent = null,
|
|
1065
1133
|
signal = null,
|
|
1066
1134
|
guards,
|
|
@@ -1098,6 +1166,8 @@ async function runNativeLoopAnthropic({
|
|
|
1098
1166
|
messages,
|
|
1099
1167
|
signal,
|
|
1100
1168
|
timeoutMs,
|
|
1169
|
+
onPhase,
|
|
1170
|
+
onThinkingDelta,
|
|
1101
1171
|
onTextDelta: (chunk) => {
|
|
1102
1172
|
const text = String(chunk || "");
|
|
1103
1173
|
if (!text) return;
|
|
@@ -1198,6 +1268,8 @@ async function runNativeAgentTask({
|
|
|
1198
1268
|
sessionId = "",
|
|
1199
1269
|
timeoutMs = 300000,
|
|
1200
1270
|
onStreamDelta = null,
|
|
1271
|
+
onThinkingDelta = null,
|
|
1272
|
+
onPhase = null,
|
|
1201
1273
|
onToolEvent = null,
|
|
1202
1274
|
signal = null,
|
|
1203
1275
|
} = {}) {
|
|
@@ -1238,6 +1310,8 @@ async function runNativeAgentTask({
|
|
|
1238
1310
|
apiKey: runtime.apiKey,
|
|
1239
1311
|
timeoutMs,
|
|
1240
1312
|
onStreamDelta,
|
|
1313
|
+
onThinkingDelta,
|
|
1314
|
+
onPhase,
|
|
1241
1315
|
onToolEvent,
|
|
1242
1316
|
signal,
|
|
1243
1317
|
guards,
|
|
@@ -10,6 +10,7 @@ const { runNativeAgentTask } = require("./nativeRunner");
|
|
|
10
10
|
*/
|
|
11
11
|
function decomposeBugFixTask(task) {
|
|
12
12
|
const steps = [];
|
|
13
|
+
const taskContext = String(task || "");
|
|
13
14
|
|
|
14
15
|
// Analyze task to determine if it's a bug fix
|
|
15
16
|
const isBugFix = /fix|bug|issue|problem|error|broken|doesn't work|not work/i.test(task);
|
|
@@ -18,7 +19,7 @@ function decomposeBugFixTask(task) {
|
|
|
18
19
|
steps.push({
|
|
19
20
|
id: "identify",
|
|
20
21
|
name: "Identifying the issue",
|
|
21
|
-
prompt: `
|
|
22
|
+
prompt: `Task context:\n${taskContext}\n\nIdentify the specific problem.\n\nBe concise. Focus only on:\n1. What is broken\n2. What file/function is likely involved\n3. What the expected behavior should be\n\nDo NOT analyze entire codebases. Find the specific issue quickly.`,
|
|
22
23
|
timeoutMs: 30000, // 30 seconds
|
|
23
24
|
earlyExit: true,
|
|
24
25
|
});
|
|
@@ -26,7 +27,7 @@ function decomposeBugFixTask(task) {
|
|
|
26
27
|
steps.push({
|
|
27
28
|
id: "locate",
|
|
28
29
|
name: "Locating relevant code",
|
|
29
|
-
prompt: `
|
|
30
|
+
prompt: `Task context:\n${taskContext}\n\nBased on the identified issue, find the exact location of the bug.\n\nSearch for and read ONLY the relevant function/file. Stop as soon as you find the problematic code.`,
|
|
30
31
|
timeoutMs: 30000,
|
|
31
32
|
earlyExit: true,
|
|
32
33
|
});
|
|
@@ -34,7 +35,7 @@ function decomposeBugFixTask(task) {
|
|
|
34
35
|
steps.push({
|
|
35
36
|
id: "fix",
|
|
36
37
|
name: "Applying the fix",
|
|
37
|
-
prompt: `
|
|
38
|
+
prompt: `Task context:\n${taskContext}\n\nApply the minimal fix needed. Do NOT refactor or improve unrelated code. Just fix the specific issue.`,
|
|
38
39
|
timeoutMs: 60000,
|
|
39
40
|
earlyExit: false,
|
|
40
41
|
});
|
|
@@ -42,7 +43,7 @@ function decomposeBugFixTask(task) {
|
|
|
42
43
|
steps.push({
|
|
43
44
|
id: "verify",
|
|
44
45
|
name: "Verifying the fix",
|
|
45
|
-
prompt: `
|
|
46
|
+
prompt: `Task context:\n${taskContext}\n\nVerify the fix resolves the issue. Check that:\n1. The specific problem is fixed\n2. No new issues were introduced\n\nBe brief.`,
|
|
46
47
|
timeoutMs: 20000,
|
|
47
48
|
earlyExit: false,
|
|
48
49
|
});
|