more progress along ChatTurn processing
The agent has been failing and failing and failing, so I: 1. Swapped models 2. Did some by-hand enhancements 3. Set this checkpoint for continuing
This commit is contained in:
parent
b94fe24287
commit
cb73d276a3
@ -80,9 +80,21 @@ const ChatTurn = memo(function ChatTurn({ turn, onUpdate }: ChatTurnProps) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Error Alert */}
|
||||||
|
{turn.errorMessage && turn.status === "error" && (
|
||||||
|
<div className="max-w-[80%] ml-0 mb-4">
|
||||||
|
<div className="bg-red-600 text-white rounded p-4 border-2 border-red-400">
|
||||||
|
<div className="text-sm font-semibold mb-2 flex items-center gap-2">
|
||||||
|
<span>⚠️</span> Error
|
||||||
|
</div>
|
||||||
|
<div className="whitespace-pre-wrap">{turn.errorMessage}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* User Prompt */}
|
{/* User Prompt */}
|
||||||
<div className="max-w-[80%] ml-0 mb-4">
|
<div className="max-w-[80%] ml-0 mb-4">
|
||||||
<div className="bg-brand text-white rounded p-4">
|
<div className="bg-[#4a0000] text-white rounded p-4">
|
||||||
<div className="text-sm font-semibold mb-2">You</div>
|
<div className="text-sm font-semibold mb-2">You</div>
|
||||||
<div className="whitespace-pre-wrap">{turn.prompts?.user || ""}</div>
|
<div className="whitespace-pre-wrap">{turn.prompts?.user || ""}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -311,6 +311,7 @@ export interface ChatTurn {
|
|||||||
prompts: ChatTurnPrompts;
|
prompts: ChatTurnPrompts;
|
||||||
thinking?: string;
|
thinking?: string;
|
||||||
response?: string;
|
response?: string;
|
||||||
|
errorMessage?: string;
|
||||||
toolCalls: Array<{
|
toolCalls: Array<{
|
||||||
callId: string;
|
callId: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@ -19,7 +19,6 @@ interface LogEntry {
|
|||||||
export default function ChatSessionView() {
|
export default function ChatSessionView() {
|
||||||
const { projectId, sessionId } = useParams<{ projectId: string; sessionId: string }>();
|
const { projectId, sessionId } = useParams<{ projectId: string; sessionId: string }>();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const socket = socketClient.socket;
|
|
||||||
const appContext = useContext(AppContext);
|
const appContext = useContext(AppContext);
|
||||||
|
|
||||||
const [project, setProject] = useState<Project | null>(null);
|
const [project, setProject] = useState<Project | null>(null);
|
||||||
@ -91,27 +90,23 @@ export default function ChatSessionView() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const setupSocketListeners = () => {
|
const setupSocketListeners = () => {
|
||||||
if (!socket) return;
|
socketClient.on('thinking', handleThinking);
|
||||||
|
socketClient.on('response', handleResponse);
|
||||||
socket.on('thinking', handleThinking);
|
socketClient.on('toolCall', handleToolCall);
|
||||||
socket.on('response', handleResponse);
|
socketClient.on('workOrderComplete', handleWorkOrderComplete);
|
||||||
socket.on('toolCall', handleToolCall);
|
socketClient.on('workspaceModeChanged', handleWorkspaceModeChanged);
|
||||||
socket.on('workOrderComplete', handleWorkOrderComplete);
|
socketClient.on('log:entry', handleLogEntry);
|
||||||
socket.on('workspaceModeChanged', handleWorkspaceModeChanged);
|
socketClient.on('status', handleStatus);
|
||||||
socket.on('log:entry', handleLogEntry);
|
|
||||||
socket.on('status', handleStatus);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const cleanupSocketListeners = () => {
|
const cleanupSocketListeners = () => {
|
||||||
if (!socket) return;
|
socketClient.off('thinking', handleThinking);
|
||||||
|
socketClient.off('response', handleResponse);
|
||||||
socket.off('thinking', handleThinking);
|
socketClient.off('toolCall', handleToolCall);
|
||||||
socket.off('response', handleResponse);
|
socketClient.off('workOrderComplete', handleWorkOrderComplete);
|
||||||
socket.off('toolCall', handleToolCall);
|
socketClient.off('workspaceModeChanged', handleWorkspaceModeChanged);
|
||||||
socket.off('workOrderComplete', handleWorkOrderComplete);
|
socketClient.off('log:entry', handleLogEntry);
|
||||||
socket.off('workspaceModeChanged', handleWorkspaceModeChanged);
|
socketClient.off('status', handleStatus);
|
||||||
socket.off('log:entry', handleLogEntry);
|
|
||||||
socket.off('status', handleStatus);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const scheduleUpdate = useCallback(() => {
|
const scheduleUpdate = useCallback(() => {
|
||||||
@ -194,7 +189,7 @@ export default function ChatSessionView() {
|
|||||||
setTurns(prevTurns =>
|
setTurns(prevTurns =>
|
||||||
prevTurns.map(turn =>
|
prevTurns.map(turn =>
|
||||||
turn._id === turnId
|
turn._id === turnId
|
||||||
? { ...turn, status: success ? 'finished' : 'error', response: message && !success ? message : turn.response }
|
? { ...turn, status: success ? 'finished' : 'error', errorMessage: message && !success ? message : turn.errorMessage }
|
||||||
: turn
|
: turn
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -264,7 +259,7 @@ export default function ChatSessionView() {
|
|||||||
|
|
||||||
const handleSubmitPrompt = async (e: React.FormEvent) => {
|
const handleSubmitPrompt = async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!promptInput.trim() || isProcessing || !socket || !sessionLocked) return;
|
if (!promptInput.trim() || isProcessing || !socketClient.connected || !sessionLocked) return;
|
||||||
if (workspaceMode !== WorkspaceMode.Agent) return;
|
if (workspaceMode !== WorkspaceMode.Agent) return;
|
||||||
|
|
||||||
const userTurn: ChatTurn = {
|
const userTurn: ChatTurn = {
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import {
|
|||||||
GadgetId,
|
GadgetId,
|
||||||
ChatTurnDocument,
|
ChatTurnDocument,
|
||||||
WorkspaceMode,
|
WorkspaceMode,
|
||||||
|
SubmitPromptCallback,
|
||||||
} from "@gadget/api";
|
} from "@gadget/api";
|
||||||
|
|
||||||
import { ChatSessionService, SocketService } from "../services/index.ts";
|
import { ChatSessionService, SocketService } from "../services/index.ts";
|
||||||
@ -134,18 +135,21 @@ export class CodeSession extends SocketSession {
|
|||||||
* Called when the IDE submits a prompt to be processed by the agent.
|
* Called when the IDE submits a prompt to be processed by the agent.
|
||||||
* Creates a ChatTurn document and sends a work order to the selected drone.
|
* Creates a ChatTurn document and sends a work order to the selected drone.
|
||||||
*/
|
*/
|
||||||
async onSubmitPrompt(content: string): Promise<void> {
|
async onSubmitPrompt(
|
||||||
|
content: string,
|
||||||
|
cb: SubmitPromptCallback,
|
||||||
|
): Promise<void> {
|
||||||
if (!this.selectedDrone) {
|
if (!this.selectedDrone) {
|
||||||
this.log.warn("prompt rejected: no drone selected");
|
this.log.warn("prompt rejected: no drone selected");
|
||||||
throw new Error("No drone selected");
|
return cb(false, { message: "No drone selected" });
|
||||||
}
|
}
|
||||||
if (!this.chatSession) {
|
if (!this.chatSession) {
|
||||||
this.log.warn("prompt rejected: no chat session active");
|
this.log.warn("prompt rejected: no chat session active");
|
||||||
throw new Error("No chat session active");
|
return cb(false, { message: "No chat session active" });
|
||||||
}
|
}
|
||||||
if (!this.project) {
|
if (!this.project) {
|
||||||
this.log.warn("prompt rejected: no project selected");
|
this.log.warn("prompt rejected: no project selected");
|
||||||
throw new Error("No project selected");
|
return cb(false, { message: "No project selected" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const droneSession = SocketService.getDroneSession(this.selectedDrone);
|
const droneSession = SocketService.getDroneSession(this.selectedDrone);
|
||||||
@ -162,6 +166,7 @@ export class CodeSession extends SocketSession {
|
|||||||
});
|
});
|
||||||
|
|
||||||
droneSession.setCurrentTurnId(turn._id);
|
droneSession.setCurrentTurnId(turn._id);
|
||||||
|
cb(true, { turnId: turn._id, message: "turn created successfully" });
|
||||||
|
|
||||||
droneSession.socket.emit(
|
droneSession.socket.emit(
|
||||||
"processWorkOrder",
|
"processWorkOrder",
|
||||||
@ -198,4 +203,29 @@ export class CodeSession extends SocketSession {
|
|||||||
onStatus(content: string): void {
|
onStatus(content: string): void {
|
||||||
this.socket.emit("status", content);
|
this.socket.emit("status", content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onThinking(content: string): void {
|
||||||
|
this.socket.emit("thinking", content);
|
||||||
|
}
|
||||||
|
|
||||||
|
onResponse(content: string): void {
|
||||||
|
this.socket.emit("response", content);
|
||||||
|
}
|
||||||
|
|
||||||
|
onToolCall(
|
||||||
|
callId: string,
|
||||||
|
name: string,
|
||||||
|
params: string,
|
||||||
|
response: string,
|
||||||
|
): void {
|
||||||
|
this.socket.emit("toolCall", callId, name, params, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
onWorkOrderComplete(
|
||||||
|
turnId: string,
|
||||||
|
success: boolean,
|
||||||
|
message?: string,
|
||||||
|
): void {
|
||||||
|
this.socket.emit("workOrderComplete", turnId, success, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,7 +82,7 @@ export class DroneSession extends SocketSession {
|
|||||||
const codeSession = SocketService.getCodeSessionByChatSessionId(
|
const codeSession = SocketService.getCodeSessionByChatSessionId(
|
||||||
this.chatSessionId,
|
this.chatSessionId,
|
||||||
);
|
);
|
||||||
codeSession.socket.emit("thinking", content);
|
codeSession.onThinking(content);
|
||||||
|
|
||||||
if (this.currentTurnId) {
|
if (this.currentTurnId) {
|
||||||
await ChatTurn.findByIdAndUpdate(this.currentTurnId, {
|
await ChatTurn.findByIdAndUpdate(this.currentTurnId, {
|
||||||
@ -107,7 +107,7 @@ export class DroneSession extends SocketSession {
|
|||||||
const codeSession = SocketService.getCodeSessionByChatSessionId(
|
const codeSession = SocketService.getCodeSessionByChatSessionId(
|
||||||
this.chatSessionId,
|
this.chatSessionId,
|
||||||
);
|
);
|
||||||
codeSession.socket.emit("response", content);
|
codeSession.onResponse(content);
|
||||||
|
|
||||||
if (this.currentTurnId) {
|
if (this.currentTurnId) {
|
||||||
await ChatTurn.findByIdAndUpdate(this.currentTurnId, {
|
await ChatTurn.findByIdAndUpdate(this.currentTurnId, {
|
||||||
@ -137,7 +137,7 @@ export class DroneSession extends SocketSession {
|
|||||||
const codeSession = SocketService.getCodeSessionByChatSessionId(
|
const codeSession = SocketService.getCodeSessionByChatSessionId(
|
||||||
this.chatSessionId,
|
this.chatSessionId,
|
||||||
);
|
);
|
||||||
codeSession.socket.emit("toolCall", callId, name, params, response);
|
codeSession.onToolCall(callId, name, params, response);
|
||||||
|
|
||||||
if (this.currentTurnId) {
|
if (this.currentTurnId) {
|
||||||
const turn = await ChatTurn.findById(this.currentTurnId);
|
const turn = await ChatTurn.findById(this.currentTurnId);
|
||||||
@ -177,7 +177,7 @@ export class DroneSession extends SocketSession {
|
|||||||
if (turn) {
|
if (turn) {
|
||||||
turn.status = success ? ChatTurnStatus.Finished : ChatTurnStatus.Error;
|
turn.status = success ? ChatTurnStatus.Finished : ChatTurnStatus.Error;
|
||||||
if (!success && message) {
|
if (!success && message) {
|
||||||
turn.response = message;
|
turn.errorMessage = message;
|
||||||
}
|
}
|
||||||
await turn.save();
|
await turn.save();
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ export class DroneSession extends SocketSession {
|
|||||||
const codeSession = SocketService.getCodeSessionByChatSessionId(
|
const codeSession = SocketService.getCodeSessionByChatSessionId(
|
||||||
this.chatSessionId,
|
this.chatSessionId,
|
||||||
);
|
);
|
||||||
codeSession.socket.emit("workOrderComplete", turnId, success, message);
|
codeSession.onWorkOrderComplete(turnId, success, message);
|
||||||
|
|
||||||
this.currentTurnId = undefined;
|
this.currentTurnId = undefined;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -67,6 +67,7 @@ export const ChatTurnSchema = new Schema<IChatTurn>({
|
|||||||
prompts: { type: ChatTurnPromptsSchema, required: true },
|
prompts: { type: ChatTurnPromptsSchema, required: true },
|
||||||
thinking: { type: String, required: false },
|
thinking: { type: String, required: false },
|
||||||
response: { type: String, required: false },
|
response: { type: String, required: false },
|
||||||
|
errorMessage: { type: String, required: false },
|
||||||
toolCalls: { type: [ChatToolCallSchema], default: [], required: true },
|
toolCalls: { type: [ChatToolCallSchema], default: [], required: true },
|
||||||
subagents: { type: [ChatSubagentProcessSchema], default: [], required: true },
|
subagents: { type: [ChatSubagentProcessSchema], default: [], required: true },
|
||||||
stats: {
|
stats: {
|
||||||
|
|||||||
@ -65,6 +65,7 @@ export interface IChatTurn {
|
|||||||
prompts: IChatTurnPrompts;
|
prompts: IChatTurnPrompts;
|
||||||
thinking?: string;
|
thinking?: string;
|
||||||
response?: string;
|
response?: string;
|
||||||
|
errorMessage?: string;
|
||||||
toolCalls: IChatToolCall[];
|
toolCalls: IChatToolCall[];
|
||||||
subagents: IChatSubagentProcess[]; // subagents used while processing this turn
|
subagents: IChatSubagentProcess[]; // subagents used while processing this turn
|
||||||
stats: IChatTurnStats;
|
stats: IChatTurnStats;
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
import { IChatSession } from "../interfaces/chat-session.ts";
|
import { IChatSession } from "../interfaces/chat-session.ts";
|
||||||
import { IDroneRegistration } from "../interfaces/drone-registration.ts";
|
import { IDroneRegistration } from "../interfaces/drone-registration.ts";
|
||||||
import { IProject } from "../interfaces/project.ts";
|
import { IProject } from "../interfaces/project.ts";
|
||||||
|
import { GadgetId } from "../lib/gadget-id.ts";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* requestSessionLock
|
* requestSessionLock
|
||||||
@ -51,4 +52,17 @@ export type RequestWorkspaceModeMessage = (
|
|||||||
* submitPrompt
|
* submitPrompt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type SubmitPromptMessage = (prompt: string) => void;
|
export interface SubmitPromptCallbackData {
|
||||||
|
turnId?: GadgetId;
|
||||||
|
message?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SubmitPromptCallback = (
|
||||||
|
success: boolean,
|
||||||
|
data: SubmitPromptCallbackData,
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
export type SubmitPromptMessage = (
|
||||||
|
prompt: string,
|
||||||
|
cb: SubmitPromptCallback,
|
||||||
|
) => void;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user