@@ -23,6 +23,11 @@ type TaskAppsProps = {
2323task :Task ;
2424} ;
2525
26+ type AppWithAgent = {
27+ app :WorkspaceApp ;
28+ agent :WorkspaceAgent ;
29+ } ;
30+
2631export const TaskApps :FC < TaskAppsProps > = ( { task} ) => {
2732const agents = task . workspace . latest_build . resources
2833. flatMap ( ( r ) => r . agents )
@@ -31,27 +36,34 @@ export const TaskApps: FC<TaskAppsProps> = ({ task }) => {
3136// The Chat UI app will be displayed in the sidebar, so we don't want to show
3237// it here
3338const apps = agents
34- . flatMap ( ( a ) => a ?. apps )
39+ . flatMap ( ( agent ) =>
40+ agent . apps . map ( ( app ) => ( {
41+ app,
42+ agent,
43+ } ) ) ,
44+ )
3545. filter (
36- ( a ) => ! ! a && a . id !== task . workspace . latest_build . ai_task_sidebar_app_id ,
46+ ( { app} ) =>
47+ ! ! app && app . id !== task . workspace . latest_build . ai_task_sidebar_app_id ,
3748) ;
3849
39- const embeddedApps = apps . filter ( ( app ) => ! app . external ) ;
40- const externalApps = apps . filter ( ( app ) => app . external ) ;
50+ const embeddedApps = apps . filter ( ( { app} ) => ! app . external ) ;
51+ const externalApps = apps . filter ( ( { app} ) => app . external ) ;
4152
4253const [ activeAppId , setActiveAppId ] = useState < string | undefined > (
43- embeddedApps [ 0 ] ?. id ,
54+ embeddedApps [ 0 ] ?. app . id ,
4455) ;
4556
4657return (
4758< main className = "flex flex-col" >
4859< div className = "w-full flex items-center border-0 border-b border-border border-solid" >
4960< div className = "p-2 pb-0 flex gap-2 items-center" >
50- { embeddedApps . map ( ( app ) => (
61+ { embeddedApps . map ( ( { app, agent } ) => (
5162< TaskAppTab
5263key = { app . id }
5364task = { task }
5465app = { app }
66+ agent = { agent }
5567active = { app . id === activeAppId }
5668onClick = { ( e ) => {
5769e . preventDefault ( ) ;
@@ -72,7 +84,7 @@ export const TaskApps: FC<TaskAppsProps> = ({ task }) => {
7284
7385{ embeddedApps . length > 0 ?(
7486< div className = "flex-1" >
75- { embeddedApps . map ( ( app ) => {
87+ { embeddedApps . map ( ( { app} ) => {
7688return (
7789< TaskAppIFrame
7890key = { app . id }
@@ -108,7 +120,7 @@ export const TaskApps: FC<TaskAppsProps> = ({ task }) => {
108120type TaskExternalAppsDropdownProps = {
109121task :Task ;
110122agents :WorkspaceAgent [ ] ;
111- externalApps :WorkspaceApp [ ] ;
123+ externalApps :AppWithAgent [ ] ;
112124} ;
113125
114126const TaskExternalAppsDropdown :FC < TaskExternalAppsDropdownProps > = ( {
@@ -126,16 +138,7 @@ const TaskExternalAppsDropdown: FC<TaskExternalAppsDropdownProps> = ({
126138</ Button >
127139</ DropdownMenuTrigger >
128140< DropdownMenuContent >
129- { externalApps . map ( ( app ) => {
130- const agent = agents . find ( ( agent ) =>
131- agent . apps . some ( ( a ) => a . id === app . id ) ,
132- ) ;
133- if ( ! agent ) {
134- throw new Error (
135- `Agent for app${ app . id } not found in task workspace` ,
136- ) ;
137- }
138-
141+ { externalApps . map ( ( { app, agent} ) => {
139142const link = useAppLink ( app , {
140143agent,
141144workspace :task . workspace ,
@@ -163,20 +166,18 @@ const TaskExternalAppsDropdown: FC<TaskExternalAppsDropdownProps> = ({
163166type TaskAppTabProps = {
164167task :Task ;
165168app :WorkspaceApp ;
169+ agent :WorkspaceAgent ;
166170active :boolean ;
167171onClick :( e :React . MouseEvent < HTMLAnchorElement > ) => void ;
168172} ;
169173
170- const TaskAppTab :FC < TaskAppTabProps > = ( { task, app, active, onClick} ) => {
171- const agent = task . workspace . latest_build . resources
172- . flatMap ( ( r ) => r . agents )
173- . filter ( ( a ) => ! ! a )
174- . find ( ( a ) => a . apps . some ( ( a ) => a . id === app . id ) ) ;
175-
176- if ( ! agent ) {
177- throw new Error ( `Agent for app${ app . id } not found in task workspace` ) ;
178- }
179-
174+ const TaskAppTab :FC < TaskAppTabProps > = ( {
175+ task,
176+ app,
177+ agent,
178+ active,
179+ onClick,
180+ } ) => {
180181const link = useAppLink ( app , {
181182agent,
182183workspace :task . workspace ,