Revert experimental UI changes
This commit is contained in:
@@ -1714,31 +1714,33 @@ export async function POST(request: Request) {
|
||||
temperature: 0.3,
|
||||
signal: clientSignal,
|
||||
});
|
||||
if (summary.thoughts) {
|
||||
assistantTimeline.push({
|
||||
kind: "thought",
|
||||
text: summary.thoughts,
|
||||
});
|
||||
emit({ type: "thinking", text: summary.thoughts });
|
||||
}
|
||||
|
||||
if (summary.text && summary.text.trim()) {
|
||||
assistantTimeline.push({ kind: "text", text: summary.text });
|
||||
assistantText += (assistantText ? "\n\n" : "") + summary.text;
|
||||
assistantTextSegments.push(summary.text);
|
||||
emit({ type: "text", text: summary.text });
|
||||
} else {
|
||||
// Gemini returned empty — fall back to a deterministic but
|
||||
// STRUCTURED build-health status (never a vague "didn't reach a
|
||||
// clean stopping point"). It states what happened, what broke,
|
||||
// and the next action, using the same signals as the telemetry
|
||||
// stop_reason.
|
||||
const fallback = buildHealthStatus({
|
||||
loopBreakReason,
|
||||
hitRoundCap: maxToolRounds > 0 && round >= maxToolRounds,
|
||||
lastError: extractLastToolFailure(messages),
|
||||
toolCount: assistantToolCalls.length,
|
||||
});
|
||||
assistantTimeline.push({ kind: "text", text: fallback });
|
||||
assistantText += (assistantText ? "\n\n" : "") + fallback;
|
||||
assistantTextSegments.push(fallback);
|
||||
emit({ type: "text", text: fallback });
|
||||
}
|
||||
if (summary.thoughts) {
|
||||
assistantTimeline.push({
|
||||
kind: "thought",
|
||||
text: summary.thoughts,
|
||||
});
|
||||
emit({ type: "thinking", text: summary.thoughts });
|
||||
}
|
||||
} catch {
|
||||
const fallback = buildHealthStatus({
|
||||
loopBreakReason,
|
||||
@@ -1771,12 +1773,7 @@ export async function POST(request: Request) {
|
||||
temperature: 0.3,
|
||||
signal: clientSignal,
|
||||
});
|
||||
if (finalSummary.thoughts) {
|
||||
assistantTimeline.push({ kind: "thought", text: finalSummary.thoughts });
|
||||
emit({ type: "thinking", text: finalSummary.thoughts });
|
||||
}
|
||||
if (finalSummary.text && finalSummary.text.trim()) {
|
||||
assistantTimeline.push({ kind: "text", text: finalSummary.text });
|
||||
assistantText +=
|
||||
(assistantText ? "\n\n" : "") + finalSummary.text;
|
||||
assistantTextSegments.push(finalSummary.text);
|
||||
|
||||
@@ -284,11 +284,14 @@ function summarizeToolResult(result?: string): {
|
||||
}
|
||||
|
||||
// Plain-text heuristics
|
||||
// We explicitly ignore 'error' and 'exception' here because tools like dev_server_logs
|
||||
// or browser_console legitimately return stack traces when working correctly.
|
||||
// A raw string with 'error' inside it shouldn't auto-fail the tool execution pill.
|
||||
const lower = raw.toLowerCase();
|
||||
if (
|
||||
/(econnrefused|enoent|error|failed|traceback|exception|not found|permission denied|cannot)/.test(
|
||||
/(econnrefused|enoent|permission denied|command not found)/.test(
|
||||
lower,
|
||||
)
|
||||
) && !raw.includes("dev_server_logs") && !raw.includes("browser_console")
|
||||
) {
|
||||
return { ok: false, label: `Failed — ${firstLine(raw)}` };
|
||||
}
|
||||
@@ -665,8 +668,6 @@ function Timeline({ entries, isActiveStream }: { entries: TimelineEntry[], isAct
|
||||
* bubble so each round of multi-tool-loop output reads as a discrete
|
||||
* step instead of concatenating into a wall of text.
|
||||
*/
|
||||
|
||||
|
||||
function TimelineText({ text, isStreaming }: { text: string; isStreaming?: boolean }) {
|
||||
const proseWrap: React.CSSProperties = {
|
||||
overflowWrap: "anywhere",
|
||||
@@ -1062,7 +1063,6 @@ export function ChatPanel({
|
||||
.catch(() => {});
|
||||
}, [projectId, workspace, status]);
|
||||
const [sending, setSending] = useState(false);
|
||||
const [showScrollButton, setShowScrollButton] = useState(false);
|
||||
const [currentPhaseLabel, setCurrentPhaseLabel] = useState<string | null>(
|
||||
null,
|
||||
);
|
||||
@@ -1551,12 +1551,15 @@ export function ChatPanel({
|
||||
}
|
||||
} catch {
|
||||
// 2. If it's a raw string (like a bash crash), scan for fatal keywords
|
||||
// We skip this check for log-reading tools since they legitimately contain errors.
|
||||
const lower = ev.result.toLowerCase();
|
||||
if (
|
||||
lower.includes("error") ||
|
||||
lower.includes("failed") ||
|
||||
lower.includes("unexpected") ||
|
||||
lower.includes("not found")
|
||||
!ev.name?.includes("logs") &&
|
||||
!ev.name?.includes("console") &&
|
||||
(lower.includes("econnrefused") ||
|
||||
lower.includes("enoent") ||
|
||||
lower.includes("permission denied") ||
|
||||
lower.includes("command not found"))
|
||||
) {
|
||||
isToolErr = true;
|
||||
}
|
||||
@@ -1893,11 +1896,6 @@ export function ChatPanel({
|
||||
|
||||
{/* Messages */}
|
||||
<div
|
||||
onScroll={(e) => {
|
||||
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
|
||||
const distanceToBottom = scrollHeight - scrollTop - clientHeight;
|
||||
setShowScrollButton(distanceToBottom > 150);
|
||||
}}
|
||||
style={{
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
@@ -2127,8 +2125,6 @@ export function ChatPanel({
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<ProjectPreviewChatInputWrap unifiedShell={unifiedProjectShell}>
|
||||
{(selectToggle) => (
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user