Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions src/backend/v3/api/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,18 +235,7 @@ async def process_request(
)
raise HTTPException(
status_code=400,
detail={
"error_type": "RAI_VALIDATION_FAILED",
"message": "Content Safety Check Failed",
"description": "Your request contains content that doesn't meet our safety guidelines. Please modify your request to ensure it's appropriate and try again.",
"suggestions": [
"Remove any potentially harmful, inappropriate, or unsafe content",
"Use more professional and constructive language",
"Focus on legitimate business or educational objectives",
"Ensure your request complies with content policies",
],
"user_action": "Please revise your request and try again",
},
detail="Request contains content that doesn't meet our safety guidelines, try again.",
)

authenticated_user = get_authenticated_user_details(request_headers=request.headers)
Expand All @@ -256,7 +245,7 @@ async def process_request(
track_event_if_configured(
"UserIdNotFound", {"status_code": 400, "detail": "no user"}
)
raise HTTPException(status_code=400, detail="no user")
raise HTTPException(status_code=400, detail="no user found")

# if not input_task.team_id:
# track_event_if_configured(
Expand Down
31 changes: 7 additions & 24 deletions src/frontend/src/components/content/HomeInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,36 +114,19 @@ const HomeInput: React.FC<HomeInputProps> = ({
dismissToast(id);
}
} catch (error: any) {
console.log("Error creating plan:", error);
let errorMessage = "Unable to create plan. Please try again.";
dismissToast(id);
// Check if this is an RAI validation error
let errorDetail = null;
try {
// Try to parse the error detail if it's a string
if (typeof error?.response?.data?.detail === 'string') {
errorDetail = JSON.parse(error.response.data.detail);
} else {
errorDetail = error?.response?.data?.detail;
}
// errorDetail = JSON.parse(error);
errorMessage = error?.message || errorMessage;
} catch (parseError) {
// If parsing fails, use the original error
errorDetail = error?.response?.data?.detail;
console.error("Error parsing error detail:", parseError);
}

// Handle RAI validation errors - just show description as toast
if (errorDetail?.error_type === 'RAI_VALIDATION_FAILED') {
const description = errorDetail.description ||
"Your request contains content that doesn't meet our safety guidelines. Please try rephrasing.";
showToast(description, "error");
} else {
// Handle other errors with toast messages
const errorMessage = errorDetail?.description ||
errorDetail?.message ||
error?.response?.data?.message ||
error?.message ||
"Something went wrong. Please try again.";

showToast(errorMessage, "error");
}

showToast(errorMessage, "error");
} finally {
setInput("");
setSubmitting(false);
Expand Down
8 changes: 2 additions & 6 deletions src/frontend/src/components/content/PlanChatBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@ const PlanChatBody: React.FC<SimplifiedPlanChatProps> = ({
onChange={setInput}
onEnter={() => OnChatSubmit(input)}
disabledChat={submittingChatDisableInput}
placeholder={
waitingForPlan
? "Creating plan..."
: "Type your message here..."
}
placeholder="Type your message here..."
style={{
fontSize: '16px',
borderRadius: '8px',
Expand All @@ -68,7 +64,7 @@ const PlanChatBody: React.FC<SimplifiedPlanChatProps> = ({
backgroundColor: 'transparent',
border: 'none',
color: (submittingChatDisableInput || !input.trim())
? 'var(--colorNeutralForegroundDisabled)'
? 'var(--colorNeutralForegroundDisabled)'
: 'var(--colorBrandForeground1)',
flexShrink: 0,
}}
Expand Down
9 changes: 8 additions & 1 deletion src/frontend/src/components/content/PlanPanelLeft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({
setUserInfo(getUserInfoGlobal());
}, [loadPlansData, setUserInfo]);


useEffect(() => {
console.log("Reload tasks changed:", reloadTasks);
if (reloadTasks) {
loadPlansData();
}
}, [loadPlansData, setUserInfo, reloadTasks]);
useEffect(() => {
if (plans) {
const { inProgress, completed } =
Expand Down Expand Up @@ -215,7 +222,7 @@ const PlanPanelLeft: React.FC<PlanPanelLefProps> = ({
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px', width: '100%' }}>
{/* User Card */}
<PanelUserCard
name={userInfo ? userInfo.user_first_last_name : "Guest"}
name={userInfo?.user_first_last_name || "Guest"}
// alias={userInfo ? userInfo.user_email : ""}
size={32}
/>
Expand Down
25 changes: 22 additions & 3 deletions src/frontend/src/pages/PlanPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useRef, useState, useMemo } from "react"
import { useParams, useNavigate } from "react-router-dom";
import { Spinner, Text } from "@fluentui/react-components";
import { PlanDataService } from "../services/PlanDataService";
import { ProcessedPlanData, WebsocketMessageType, MPlanData, AgentMessageData, AgentMessageType, ParsedUserClarification, AgentType, PlanStatus, FinalMessage } from "../models";
import { ProcessedPlanData, WebsocketMessageType, MPlanData, AgentMessageData, AgentMessageType, ParsedUserClarification, AgentType, PlanStatus, FinalMessage, TeamConfig } from "../models";
import PlanChat from "../components/content/PlanChat";
import PlanPanelRight from "../components/content/PlanPanelRight";
import PlanPanelLeft from "../components/content/PlanPanelLeft";
Expand Down Expand Up @@ -48,6 +48,7 @@ const PlanPage: React.FC = () => {
const [showProcessingPlanSpinner, setShowProcessingPlanSpinner] = useState<boolean>(false);
const [showApprovalButtons, setShowApprovalButtons] = useState<boolean>(true);
const [continueWithWebsocketFlow, setContinueWithWebsocketFlow] = useState<boolean>(false);
const [selectedTeam, setSelectedTeam] = useState<TeamConfig | null>(null);
// WebSocket connection state
const [wsConnected, setWsConnected] = useState<boolean>(false);
const [streamingMessages, setStreamingMessages] = useState<StreamingPlanUpdate[]>([]);
Expand Down Expand Up @@ -261,6 +262,7 @@ const PlanPage: React.FC = () => {
setShowBufferingText(true);
setShowProcessingPlanSpinner(false);
setAgentMessages(prev => [...prev, agentMessageData]);
setSelectedTeam(planData?.team || null);
scrollToBottom();
// Persist the agent message
const is_final = true;
Expand All @@ -270,13 +272,19 @@ const PlanPage: React.FC = () => {
}

processAgentMessage(agentMessageData, planData, is_final, streamingMessageBuffer);

setTimeout(() => {
console.log('✅ Plan completed, refreshing left list');
setReloadLeftList(true);
}, 1000);

}


});

return () => unsubscribe();
}, [scrollToBottom, planData, processAgentMessage, streamingMessageBuffer]);
}, [scrollToBottom, planData, processAgentMessage, streamingMessageBuffer, setSelectedTeam, setReloadLeftList]);

//WebsocketMessageType.AGENT_MESSAGE
useEffect(() => {
Expand Down Expand Up @@ -409,6 +417,8 @@ const PlanPage: React.FC = () => {
return planResult;
} catch (err) {
console.log("Failed to load plan data:", err);
setErrorLoading(true);
setPlanData(null);
return null;
} finally {
setLoading(false);
Expand Down Expand Up @@ -564,6 +574,15 @@ const PlanPage: React.FC = () => {
return (
<CoralShellColumn>
<CoralShellRow>
<PlanPanelLeft
reloadTasks={reloadLeftList}
onNewTaskButton={handleNewTaskButton}
restReload={resetReload}
onTeamSelect={() => { }}
onTeamUpload={async () => { }}
isHomePage={false}
selectedTeam={selectedTeam}
/>
<Content>
<div style={{
textAlign: "center",
Expand Down Expand Up @@ -591,7 +610,7 @@ const PlanPage: React.FC = () => {
onTeamSelect={() => { }}
onTeamUpload={async () => { }}
isHomePage={false}
selectedTeam={null}
selectedTeam={selectedTeam}
/>

<Content>
Expand Down
24 changes: 19 additions & 5 deletions src/frontend/src/services/PlanDataService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -893,16 +893,30 @@ export class PlanDataService {
}

// Capture the inside of UserClarificationResponse(...)
const outerMatch = line.match(/Human clarification:\s*UserClarificationResponse\((.*?)\)/s);
const outerMatch = line.match(/Human clarification:\s*UserClarificationResponse\((.*)\)$/s);
if (!outerMatch) return line;

const inner = outerMatch[1];

// Find answer= '...' | "..."
const answerMatch = inner.match(/answer=(?:"((?:\\.|[^"])*)"|'((?:\\.|[^'])*)')/);
if (!answerMatch) return line;
// Find answer= '...' | "..." - Updated regex to handle the full content properly
const answerMatch = inner.match(/answer='([^']*(?:''[^']*)*)'/);
if (!answerMatch) {
// Try double quotes if single quotes don't work
const doubleQuoteMatch = inner.match(/answer="([^"]*(?:""[^"]*)*)"/);
if (!doubleQuoteMatch) return line;

let answer = answerMatch[1] ?? answerMatch[2] ?? '';
let answer = doubleQuoteMatch[1];
answer = answer
.replace(/\\n/g, '\n')
.replace(/\\'/g, "'")
.replace(/\\"/g, '"')
.replace(/\\\\/g, '\\')
.trim();

return `Human clarification: ${answer}`;
}

let answer = answerMatch[1];
// Unescape common sequences
answer = answer
.replace(/\\n/g, '\n')
Expand Down
22 changes: 2 additions & 20 deletions src/frontend/src/services/TaskService.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,28 +195,10 @@ export class TaskService {
try {
return await apiService.createPlan(inputTask);
} catch (error: any) {

// You can customize this logic as needed
let message = "Unable to create plan. Please try again.";
if (error?.response?.data?.detail) {
const detail = error.response.data.detail;
if (typeof detail === 'string' && detail.includes('RAI_VALIDATION_FAILED')) {
message = "Your request contains content that doesn't meet our safety guidelines. Please rephrase and try again.";
} else if (detail.includes('quota') || detail.includes('limit')) {
message = "Service is currently at capacity. Please try again in a few minutes.";
} else if (detail.includes('unauthorized') || detail.includes('forbidden')) {
message = "You don't have permission to create plans. Please contact your administrator.";
} else {
message = detail;
}
} else if (error?.response?.data?.message) {
message = error.response.data.message;
} else if (error?.message) {
if (error.message.includes('Network Error') || error.message.includes('fetch')) {
message = "Network error. Please check your connection and try again.";
} else {
message = error.message;
}
}

throw new Error(message);
}
}
Expand Down
Loading