mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
adjustments based on gemini review
This commit is contained in:
@@ -404,7 +404,7 @@ class FeatureLoader {
|
|||||||
status: status,
|
status: status,
|
||||||
images: [],
|
images: [],
|
||||||
imagePaths: [],
|
imagePaths: [],
|
||||||
skipTests: true,
|
skipTests: false, // Auto-generated features should run tests by default
|
||||||
model: "sonnet",
|
model: "sonnet",
|
||||||
thinkingLevel: "none",
|
thinkingLevel: "none",
|
||||||
summary: summary || description || '',
|
summary: summary || description || '',
|
||||||
|
|||||||
@@ -461,8 +461,7 @@ Use the UpdateFeatureStatus tool to create features with ALL the fields above.`,
|
|||||||
const currentQuery = query({ prompt, options });
|
const currentQuery = query({ prompt, options });
|
||||||
execution.query = currentQuery;
|
execution.query = currentQuery;
|
||||||
|
|
||||||
let toolCallCount = 0;
|
const counters = { toolCallCount: 0, messageCount: 0 };
|
||||||
let messageCount = 0;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for await (const msg of currentQuery) {
|
for await (const msg of currentQuery) {
|
||||||
@@ -472,67 +471,11 @@ Use the UpdateFeatureStatus tool to create features with ALL the fields above.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msg.type === "assistant" && msg.message?.content) {
|
if (msg.type === "assistant" && msg.message?.content) {
|
||||||
messageCount++;
|
this._handleAssistantMessage(msg, sendToRenderer, counters);
|
||||||
for (const block of msg.message.content) {
|
|
||||||
if (block.type === "text") {
|
|
||||||
const preview = block.text.substring(0, 100).replace(/\n/g, " ");
|
|
||||||
console.log(`[SpecRegeneration] Feature gen message #${messageCount}: ${preview}...`);
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_progress",
|
|
||||||
content: block.text,
|
|
||||||
});
|
|
||||||
} else if (block.type === "tool_use") {
|
|
||||||
toolCallCount++;
|
|
||||||
const toolName = block.name;
|
|
||||||
const toolInput = block.input;
|
|
||||||
console.log(`[SpecRegeneration] Feature gen tool call #${toolCallCount}: ${toolName}`);
|
|
||||||
|
|
||||||
if (toolName === "mcp__automaker-tools__UpdateFeatureStatus" || toolName === "UpdateFeatureStatus") {
|
|
||||||
const featureId = toolInput?.featureId || "unknown";
|
|
||||||
const status = toolInput?.status || "unknown";
|
|
||||||
const summary = toolInput?.summary || "";
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_progress",
|
|
||||||
content: `\n[Feature Creation] Creating feature "${featureId}" with status "${status}"${summary ? `\n Summary: ${summary}` : ""}\n`,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_progress",
|
|
||||||
content: `\n[Tool] Using ${toolName}...\n`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_tool",
|
|
||||||
tool: toolName,
|
|
||||||
input: toolInput,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (msg.type === "tool_result") {
|
} else if (msg.type === "tool_result") {
|
||||||
const toolName = msg.toolName || "unknown";
|
this._handleToolResult(msg, sendToRenderer);
|
||||||
const result = msg.content?.[0]?.text || JSON.stringify(msg.content);
|
|
||||||
const resultPreview = result.substring(0, 200).replace(/\n/g, " ");
|
|
||||||
console.log(`[SpecRegeneration] Feature gen tool result (${toolName}): ${resultPreview}...`);
|
|
||||||
|
|
||||||
if (toolName === "mcp__automaker-tools__UpdateFeatureStatus" || toolName === "UpdateFeatureStatus") {
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_progress",
|
|
||||||
content: `[Feature Creation] ${result}\n`,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_progress",
|
|
||||||
content: `[Tool Result] ${toolName} completed successfully\n`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (msg.type === "error") {
|
} else if (msg.type === "error") {
|
||||||
const errorMsg = msg.error?.message || JSON.stringify(msg.error);
|
this._handleStreamError(msg, sendToRenderer);
|
||||||
console.error(`[SpecRegeneration] ERROR in feature generation stream: ${errorMsg}`);
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_error",
|
|
||||||
error: `Error during feature generation: ${errorMsg}`,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (streamError) {
|
} catch (streamError) {
|
||||||
@@ -544,7 +487,7 @@ Use the UpdateFeatureStatus tool to create features with ALL the fields above.`,
|
|||||||
throw streamError;
|
throw streamError;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[SpecRegeneration] Feature generation completed - ${messageCount} messages, ${toolCallCount} tool calls`);
|
console.log(`[SpecRegeneration] Feature generation completed - ${counters.messageCount} messages, ${counters.toolCallCount} tool calls`);
|
||||||
|
|
||||||
execution.query = null;
|
execution.query = null;
|
||||||
execution.abortController = null;
|
execution.abortController = null;
|
||||||
@@ -1003,6 +946,94 @@ Use this general structure:
|
|||||||
Begin by exploring the project structure.`;
|
Begin by exploring the project structure.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle assistant message in feature generation stream
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_handleAssistantMessage(msg, sendToRenderer, counters) {
|
||||||
|
counters.messageCount++;
|
||||||
|
for (const block of msg.message.content) {
|
||||||
|
if (block.type === "text") {
|
||||||
|
const preview = block.text.substring(0, 100).replace(/\n/g, " ");
|
||||||
|
console.log(`[SpecRegeneration] Feature gen message #${counters.messageCount}: ${preview}...`);
|
||||||
|
sendToRenderer({
|
||||||
|
type: "spec_regeneration_progress",
|
||||||
|
content: block.text,
|
||||||
|
});
|
||||||
|
} else if (block.type === "tool_use") {
|
||||||
|
this._handleToolUse(block, sendToRenderer, counters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle tool use block in feature generation stream
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_handleToolUse(block, sendToRenderer, counters) {
|
||||||
|
counters.toolCallCount++;
|
||||||
|
const toolName = block.name;
|
||||||
|
const toolInput = block.input;
|
||||||
|
console.log(`[SpecRegeneration] Feature gen tool call #${counters.toolCallCount}: ${toolName}`);
|
||||||
|
|
||||||
|
if (toolName === "mcp__automaker-tools__UpdateFeatureStatus" || toolName === "UpdateFeatureStatus") {
|
||||||
|
const featureId = toolInput?.featureId || "unknown";
|
||||||
|
const status = toolInput?.status || "unknown";
|
||||||
|
const summary = toolInput?.summary || "";
|
||||||
|
sendToRenderer({
|
||||||
|
type: "spec_regeneration_progress",
|
||||||
|
content: `\n[Feature Creation] Creating feature "${featureId}" with status "${status}"${summary ? `\n Summary: ${summary}` : ""}\n`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
sendToRenderer({
|
||||||
|
type: "spec_regeneration_progress",
|
||||||
|
content: `\n[Tool] Using ${toolName}...\n`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sendToRenderer({
|
||||||
|
type: "spec_regeneration_tool",
|
||||||
|
tool: toolName,
|
||||||
|
input: toolInput,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle tool result in feature generation stream
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_handleToolResult(msg, sendToRenderer) {
|
||||||
|
const toolName = msg.toolName || "unknown";
|
||||||
|
const result = msg.content?.[0]?.text || JSON.stringify(msg.content);
|
||||||
|
const resultPreview = result.substring(0, 200).replace(/\n/g, " ");
|
||||||
|
console.log(`[SpecRegeneration] Feature gen tool result (${toolName}): ${resultPreview}...`);
|
||||||
|
|
||||||
|
if (toolName === "mcp__automaker-tools__UpdateFeatureStatus" || toolName === "UpdateFeatureStatus") {
|
||||||
|
sendToRenderer({
|
||||||
|
type: "spec_regeneration_progress",
|
||||||
|
content: `[Feature Creation] ${result}\n`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
sendToRenderer({
|
||||||
|
type: "spec_regeneration_progress",
|
||||||
|
content: `[Tool Result] ${toolName} completed successfully\n`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle error in feature generation stream
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_handleStreamError(msg, sendToRenderer) {
|
||||||
|
const errorMsg = msg.error?.message || JSON.stringify(msg.error);
|
||||||
|
console.error(`[SpecRegeneration] ERROR in feature generation stream: ${errorMsg}`);
|
||||||
|
sendToRenderer({
|
||||||
|
type: "spec_regeneration_error",
|
||||||
|
error: `Error during feature generation: ${errorMsg}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop the current regeneration
|
* Stop the current regeneration
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ import { Checkbox } from "@/components/ui/checkbox";
|
|||||||
import { XmlSyntaxEditor } from "@/components/ui/xml-syntax-editor";
|
import { XmlSyntaxEditor } from "@/components/ui/xml-syntax-editor";
|
||||||
import type { SpecRegenerationEvent } from "@/types/electron";
|
import type { SpecRegenerationEvent } from "@/types/electron";
|
||||||
|
|
||||||
|
// Delay before reloading spec file to ensure it's written to disk
|
||||||
|
const SPEC_FILE_WRITE_DELAY = 500;
|
||||||
|
|
||||||
|
// Interval for polling backend status during generation
|
||||||
|
const STATUS_CHECK_INTERVAL_MS = 2000;
|
||||||
|
|
||||||
export function SpecView() {
|
export function SpecView() {
|
||||||
const { currentProject, appSpec, setAppSpec } = useAppStore();
|
const { currentProject, appSpec, setAppSpec } = useAppStore();
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
@@ -40,6 +46,9 @@ export function SpecView() {
|
|||||||
// Generate features only state
|
// Generate features only state
|
||||||
const [isGeneratingFeatures, setIsGeneratingFeatures] = useState(false);
|
const [isGeneratingFeatures, setIsGeneratingFeatures] = useState(false);
|
||||||
|
|
||||||
|
// Logs state (kept for internal tracking, but UI removed)
|
||||||
|
const [logs, setLogs] = useState<string>("");
|
||||||
|
const logsRef = useRef<string>("");
|
||||||
|
|
||||||
// Phase tracking and status
|
// Phase tracking and status
|
||||||
const [currentPhase, setCurrentPhase] = useState<string>("");
|
const [currentPhase, setCurrentPhase] = useState<string>("");
|
||||||
@@ -246,7 +255,7 @@ export function SpecView() {
|
|||||||
loadSpec();
|
loadSpec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, STATUS_CHECK_INTERVAL_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -310,7 +319,7 @@ export function SpecView() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[SpecView] Periodic status check error:", error);
|
console.error("[SpecView] Periodic status check error:", error);
|
||||||
}
|
}
|
||||||
}, 2000); // Check every 2 seconds (more frequent)
|
}, STATUS_CHECK_INTERVAL_MS);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(intervalId);
|
clearInterval(intervalId);
|
||||||
@@ -342,7 +351,7 @@ export function SpecView() {
|
|||||||
// Small delay to ensure spec file is written
|
// Small delay to ensure spec file is written
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loadSpec();
|
loadSpec();
|
||||||
}, 500);
|
}, SPEC_FILE_WRITE_DELAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +366,7 @@ export function SpecView() {
|
|||||||
stateRestoredRef.current = false;
|
stateRestoredRef.current = false;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loadSpec();
|
loadSpec();
|
||||||
}, 500);
|
}, SPEC_FILE_WRITE_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append progress to logs
|
// Append progress to logs
|
||||||
@@ -399,37 +408,37 @@ export function SpecView() {
|
|||||||
logsRef.current = completionLog;
|
logsRef.current = completionLog;
|
||||||
setLogs(completionLog);
|
setLogs(completionLog);
|
||||||
|
|
||||||
// Check if this is the final completion
|
// --- Completion Detection Logic ---
|
||||||
const isFinalCompletion = event.message?.includes("All tasks completed") ||
|
// Check 1: Message explicitly indicates all tasks are done
|
||||||
event.message === "All tasks completed!" ||
|
const isFinalCompletionMessage = event.message?.includes("All tasks completed") ||
|
||||||
event.message === "All tasks completed";
|
event.message === "All tasks completed!" ||
|
||||||
|
event.message === "All tasks completed";
|
||||||
|
|
||||||
// Check if we've already seen a completion phase in logs (including the message we just added)
|
// Check 2: We've seen a [Phase: complete] marker in the logs
|
||||||
const hasSeenCompletePhase = logsRef.current.includes("[Phase: complete]");
|
const hasCompletePhase = logsRef.current.includes("[Phase: complete]");
|
||||||
|
|
||||||
// Check recent logs for feature activity
|
// Check 3: Feature generation has finished (no recent activity and not actively generating)
|
||||||
const recentLogs = logsRef.current.slice(-2000);
|
const recentLogs = logsRef.current.slice(-2000);
|
||||||
const hasRecentFeatureActivity = recentLogs.includes("Feature Creation") ||
|
const hasRecentFeatureActivity = recentLogs.includes("Feature Creation") ||
|
||||||
recentLogs.includes("Creating feature") ||
|
recentLogs.includes("Creating feature") ||
|
||||||
recentLogs.includes("UpdateFeatureStatus");
|
recentLogs.includes("UpdateFeatureStatus");
|
||||||
|
const isStillGeneratingFeatures = !isFinalCompletionMessage &&
|
||||||
|
!hasCompletePhase &&
|
||||||
|
(event.message?.includes("Features are being generated") ||
|
||||||
|
event.message?.includes("features are being generated"));
|
||||||
|
const isFeatureGenerationComplete = currentPhase === "feature_generation" &&
|
||||||
|
!hasRecentFeatureActivity &&
|
||||||
|
!isStillGeneratingFeatures;
|
||||||
|
|
||||||
// Check if we're still generating features (only for intermediate completion)
|
// Determine if we should mark everything as complete
|
||||||
const isGeneratingFeatures = !isFinalCompletion &&
|
const shouldComplete = isFinalCompletionMessage || hasCompletePhase || isFeatureGenerationComplete;
|
||||||
!hasSeenCompletePhase &&
|
|
||||||
(event.message?.includes("Features are being generated") ||
|
|
||||||
event.message?.includes("features are being generated"));
|
|
||||||
|
|
||||||
// If we're in feature_generation but no recent activity and we see completion, we're done
|
|
||||||
const shouldComplete = isFinalCompletion ||
|
|
||||||
hasSeenCompletePhase ||
|
|
||||||
(currentPhase === "feature_generation" && !hasRecentFeatureActivity && !isGeneratingFeatures);
|
|
||||||
|
|
||||||
if (shouldComplete) {
|
if (shouldComplete) {
|
||||||
// Fully complete - clear all states immediately
|
// Fully complete - clear all states immediately
|
||||||
console.log("[SpecView] Final completion detected - clearing state", {
|
console.log("[SpecView] Final completion detected - clearing state", {
|
||||||
isFinalCompletion,
|
isFinalCompletionMessage,
|
||||||
hasSeenCompletePhase,
|
hasCompletePhase,
|
||||||
shouldComplete,
|
isFeatureGenerationComplete,
|
||||||
hasRecentFeatureActivity,
|
hasRecentFeatureActivity,
|
||||||
currentPhase,
|
currentPhase,
|
||||||
message: event.message
|
message: event.message
|
||||||
@@ -452,7 +461,7 @@ export function SpecView() {
|
|||||||
setIsRegenerating(true);
|
setIsRegenerating(true);
|
||||||
setCurrentPhase("feature_generation");
|
setCurrentPhase("feature_generation");
|
||||||
console.log("[SpecView] Spec complete, continuing with feature generation", {
|
console.log("[SpecView] Spec complete, continuing with feature generation", {
|
||||||
isGeneratingFeatures,
|
isStillGeneratingFeatures,
|
||||||
hasRecentFeatureActivity,
|
hasRecentFeatureActivity,
|
||||||
currentPhase
|
currentPhase
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user