Skip to content

Commit 186e49d

Browse files
committed
working planpage components
1 parent 9a319bd commit 186e49d

File tree

8 files changed

+156
-22
lines changed

8 files changed

+156
-22
lines changed

src/backend/app_kernel.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,74 @@ async def get_agent_messages(session_id: str, request: Request) -> List[AgentMes
772772
return agent_messages
773773

774774

775+
@app.get("/api/agent_messages_by_plan/{plan_id}", response_model=List[AgentMessage])
776+
async def get_agent_messages_by_plan(
777+
plan_id: str, request: Request
778+
) -> List[AgentMessage]:
779+
"""
780+
Retrieve agent messages for a specific session.
781+
782+
---
783+
tags:
784+
- Agent Messages
785+
parameters:
786+
- name: session_id
787+
in: path
788+
type: string
789+
required: true
790+
in: path
791+
type: string
792+
required: true
793+
description: The ID of the session to retrieve agent messages for
794+
responses:
795+
200:
796+
description: List of agent messages associated with the specified session
797+
schema:
798+
type: array
799+
items:
800+
type: object
801+
properties:
802+
id:
803+
type: string
804+
description: Unique ID of the agent message
805+
session_id:
806+
type: string
807+
description: Session ID associated with the message
808+
plan_id:
809+
type: string
810+
description: Plan ID related to the agent message
811+
content:
812+
type: string
813+
description: Content of the message
814+
source:
815+
type: string
816+
description: Source of the message (e.g., agent type)
817+
timestamp:
818+
type: string
819+
format: date-time
820+
description: Timestamp of the message
821+
step_id:
822+
type: string
823+
description: Optional step ID associated with the message
824+
400:
825+
description: Missing or invalid user information
826+
404:
827+
description: Agent messages not found
828+
"""
829+
authenticated_user = get_authenticated_user_details(request_headers=request.headers)
830+
user_id = authenticated_user["user_principal_id"]
831+
if not user_id:
832+
track_event_if_configured(
833+
"UserIdNotFound", {"status_code": 400, "detail": "no user"}
834+
)
835+
raise HTTPException(status_code=400, detail="no user")
836+
837+
# Initialize memory context
838+
kernel, memory_store = await initialize_runtime_and_context("", user_id)
839+
agent_messages = await memory_store.get_data_by_type_and_plan_id("agent_message")
840+
return agent_messages
841+
842+
775843
@app.delete("/api/messages")
776844
async def delete_all_messages(request: Request) -> Dict[str, str]:
777845
"""

src/backend/context/cosmos_memory_kernel.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,27 @@ async def get_data_by_type(self, data_type: str) -> List[BaseDataModel]:
443443
logging.exception(f"Failed to query data by type from Cosmos DB: {e}")
444444
return []
445445

446+
async def get_data_by_type_and_plan_id(
447+
self, data_type: str, plan_id: str
448+
) -> List[BaseDataModel]:
449+
"""Query the Cosmos DB for documents with the matching data_type, session_id and user_id."""
450+
await self.ensure_initialized()
451+
if self._container is None:
452+
return []
453+
454+
model_class = self.MODEL_CLASS_MAPPING.get(data_type, BaseDataModel)
455+
try:
456+
query = "SELECT * FROM c WHERE c.user_id=@user_id AND c.data_type=@data_type AND c.plan_id=@plan_id ORDER BY c._ts ASC"
457+
parameters = [
458+
{"name": "@data_type", "value": data_type},
459+
{"name": "@user_id", "value": self.user_id},
460+
{"name": "@plan_id", "value": plan_id},
461+
]
462+
return await self.query_items(query, parameters, model_class)
463+
except Exception as e:
464+
logging.exception(f"Failed to query data by type from Cosmos DB: {e}")
465+
return []
466+
446467
async def delete_item(self, item_id: str, partition_key: str) -> None:
447468
"""Delete an item from Cosmos DB."""
448469
await self.ensure_initialized()
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { PlanChatProps } from "@/models";
2+
3+
const PlanChat: React.FC<PlanChatProps> = ({
4+
PlanData,
5+
OnChatSubmit
6+
}) => {
7+
8+
return (<> </>);
9+
};
10+
11+
export default PlanChat;

src/frontend_react/src/components/content/TaskDetails.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ import { TaskDetailsProps } from "../../models";
1414
import "../../styles/TaskDetails.css";
1515

1616
const TaskDetails: React.FC<TaskDetailsProps> = ({
17-
taskName,
18-
subTasks,
19-
agents,
20-
humans,
17+
PlanData,
18+
OnApproveStep,
19+
OnRejectStep
2120

2221
}) => {
2322
const completedCount = subTasks.filter(t => t.status === 'completed').length;
@@ -26,7 +25,7 @@ const TaskDetails: React.FC<TaskDetailsProps> = ({
2625
<div className="task-details-container">
2726
<div className="task-details-section">
2827
<div className="task-details-progress-header">
29-
<Subtitle1>{taskName}</Subtitle1>
28+
<Subtitle1>{PlanData.plan.initial_goal}</Subtitle1>
3029
<Text size={200}>
3130
{completedCount} of {subTasks.length} completed
3231
</Text>

src/frontend_react/src/models/plan.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,19 @@ export interface PlanWithSteps extends Plan {
8585
/** Count of steps failed */
8686
failed: number;
8787
}
88+
89+
90+
/**
91+
* Interface for processed plan data
92+
*/
93+
export interface ProcessedPlanData {
94+
plan: PlanWithSteps;
95+
agents: AgentType[];
96+
steps: Step[];
97+
hasHumanClarificationRequest: boolean;
98+
}
99+
100+
export interface PlanChatProps {
101+
PlanData: ProcessedPlanData;
102+
OnChatSubmit: (message: string) => void;
103+
}

src/frontend_react/src/models/taskDetails.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { ProcessedPlanData, Step } from "./plan";
2+
13
export interface SubTask {
24
id: string;
35
name: string;
@@ -19,10 +21,7 @@ export interface Human {
1921
}
2022

2123
export interface TaskDetailsProps {
22-
taskName: string;
23-
subTasks: SubTask[];
24-
agents: Agent[];
25-
humans: Human[];
26-
onAddAgent: () => void;
27-
onAddHuman: () => void;
24+
PlanData: ProcessedPlanData;
25+
OnApproveStep: (step: Step) => void;
26+
OnRejectStep: (step: Step) => void;
2827
}

src/frontend_react/src/pages/PlanPage.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import {
1515
ErrorCircle24Regular,
1616
Person24Regular,
1717
CheckmarkCircle24Regular,
18-
AlertUrgent24Regular
18+
AlertUrgent24Regular,
19+
Sparkle20Filled
1920
} from '@fluentui/react-icons';
2021
import '../styles/PlanPage.css';
2122
import CoralShellColumn from '../coral/components/Layout/CoralShellColumn';
@@ -29,6 +30,10 @@ import { PlanDataService, ProcessedPlanData } from '../services/PlanDataService'
2930
import { PlanWithSteps, Task, AgentType, Step } from '@/models';
3031
import { apiService } from '@/api';
3132
import PlanPanelLeft from '@/components/content/PlanPanelLeft';
33+
import ContentToolbar from '@/coral/components/Content/ContentToolbar';
34+
import Chat from '@/coral/modules/Chat';
35+
import TaskDetails from '@/components/content/TaskDetails';
36+
import PlanChat from '@/components/content/PlanChat';
3237

3338
/**
3439
* Page component for displaying a specific plan
@@ -42,7 +47,17 @@ const PlanPage: React.FC = () => {
4247
const [planData, setPlanData] = useState<ProcessedPlanData | null>(null);
4348
const [loading, setLoading] = useState<boolean>(true);
4449
const [error, setError] = useState<Error | null>(null);
50+
const handleOnchatSubmit = useCallback(() => {
51+
NewTaskService.handleNewTaskFromHome();
52+
}, []);
4553

54+
const handleApproveStep = useCallback((step: Step) => {
55+
NewTaskService.handleNewTaskFromHome();
56+
}, []);
57+
58+
const handleRejectStep = useCallback((step: Step) => {
59+
NewTaskService.handleNewTaskFromHome();
60+
}, []);
4661
/**
4762
* Fetch plan data when component mounts or planId changes
4863
*/
@@ -54,6 +69,7 @@ const PlanPage: React.FC = () => {
5469
setError(null);
5570

5671
const data = await PlanDataService.fetchPlanData(planId);
72+
console.log('Fetched plan data:', data);
5773
setPlanData(data);
5874
} catch (err) {
5975
console.error('Failed to load plan data:', err);
@@ -85,6 +101,19 @@ const PlanPage: React.FC = () => {
85101
<CoralShellRow>
86102
<PlanPanelLeft onNewTaskButton={handleNewTaskButton} />
87103
<Content>
104+
<ContentToolbar
105+
panelTitle={planData?.plan?.initial_goal || 'Plan Details'}
106+
panelIcon={<Sparkle20Filled />}
107+
></ContentToolbar>
108+
<PlanChat
109+
PlanData={planData}
110+
OnChatSubmit={handleOnchatSubmit}
111+
/>
112+
<TaskDetails
113+
PlanData={planData}
114+
OnApproveStep={handleApproveStep}
115+
OnRejectStep={handleRejectStep}
116+
/>
88117

89118
</Content>
90119
</CoralShellRow>

src/frontend_react/src/services/PlanDataService.tsx

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
import { PlanWithSteps, Step, AgentType } from '@/models';
1+
import { PlanWithSteps, Step, AgentType, ProcessedPlanData } from '@/models';
22
import { apiService } from '@/api';
33

4-
/**
5-
* Interface for processed plan data
6-
*/
7-
export interface ProcessedPlanData {
8-
plan: PlanWithSteps;
9-
agents: AgentType[];
10-
steps: Step[];
11-
hasHumanClarificationRequest: boolean;
12-
}
134

145
/**
156
* Service for processing and managing plan data operations

0 commit comments

Comments
 (0)