Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc2d5143

Browse files
fix: handle chat app not found (#19947)
Sometimes users can misconfigure the app used for chat. When thathappens, we should make it clear to the user.<img width="1197" height="727" alt="Screenshot 2025-09-24 at 14 15 12"src="https://github.com/user-attachments/assets/6afe2c22-e7c3-47d4-8446-76000535a492"/>- Handle “chat app not found.”- Simplify stories.- Have `TaskAppIframe` handle all task iframes so we don’t need aseparate iframe component for chat.
1 parent43415f0 commitc2d5143

File tree

7 files changed

+246
-299
lines changed

7 files changed

+246
-299
lines changed

‎site/src/modules/tasks/tasks.ts‎

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,12 @@ export type WorkspaceAppWithAgent = WorkspaceApp & {
1616
};
1717

1818
exportfunctiongetTaskApps(task:Task):WorkspaceAppWithAgent[]{
19-
return(
20-
task.workspace.latest_build.resources
21-
.flatMap((r)=>r.agents??[])
22-
.flatMap((agent)=>
23-
agent.apps.map((app)=>({
24-
...app,
25-
agent,
26-
})),
27-
)
28-
// The Chat UI app will be displayed in the sidebar, so we don't want to
29-
// show it as a tab.
30-
.filter(
31-
(app)=>app.id!==task.workspace.latest_build.ai_task_sidebar_app_id,
32-
)
33-
);
19+
returntask.workspace.latest_build.resources
20+
.flatMap((r)=>r.agents??[])
21+
.flatMap((agent)=>
22+
agent.apps.map((app)=>({
23+
...app,
24+
agent,
25+
})),
26+
);
3427
}

‎site/src/pages/TaskPage/TaskAppIframe.tsx‎

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,7 @@ export const TaskAppIFrame: FC<TaskAppIFrameProps> = ({
8484
</div>
8585
)}
8686

87-
{app.health==="healthy"||
88-
app.health==="disabled"||
89-
app.health==="unhealthy" ?(
87+
{app.health==="healthy"||app.health==="disabled" ?(
9088
<iframe
9189
ref={frameRef}
9290
src={link.href}
@@ -95,6 +93,41 @@ export const TaskAppIFrame: FC<TaskAppIFrameProps> = ({
9593
className={"w-full h-full border-0"}
9694
allow="clipboard-read; clipboard-write"
9795
/>
96+
) :app.health==="unhealthy" ?(
97+
<divclassName="w-full h-full flex flex-col items-center justify-center p-4">
98+
<h3className="m-0 font-medium text-content-primary text-base text-center">
99+
App "{app.display_name}" is unhealthy
100+
</h3>
101+
<divclassName="text-content-secondary text-sm">
102+
<spanclassName="block text-center">
103+
Here are some troubleshooting steps you can take:
104+
</span>
105+
<ulclassName="m-0 pt-4 flex flex-col gap-4">
106+
{app.healthcheck&&(
107+
<li>
108+
<spanclassName="block font-medium text-content-primary mb-1">
109+
Verify healthcheck
110+
</span>
111+
Try running the following inside your workspace:{" "}
112+
<codeclassName="font-mono text-content-primary select-all">
113+
curl -v "{app.healthcheck.url}"
114+
</code>
115+
</li>
116+
)}
117+
<li>
118+
<spanclassName="block font-medium text-content-primary mb-1">
119+
Check logs
120+
</span>
121+
See{" "}
122+
<codeclassName="font-mono text-content-primary select-all">
123+
/tmp/coder-agent.log
124+
</code>{" "}
125+
inside your workspace "{task.workspace.name}" for more
126+
information.
127+
</li>
128+
</ul>
129+
</div>
130+
</div>
98131
) :app.health==="initializing" ?(
99132
<divclassName="w-full h-full flex items-center justify-center">
100133
<Spinnerloading/>

‎site/src/pages/TaskPage/TaskApps.stories.tsx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { TaskApps } from "./TaskApps";
1818
constmockExternalApp:WorkspaceApp={
1919
...MockWorkspaceApp,
2020
external:true,
21+
health:"healthy",
2122
};
2223

2324
constmeta:Meta<typeofTaskApps>={
@@ -103,6 +104,7 @@ function mockEmbeddedApp(name = MockWorkspaceApp.display_name): WorkspaceApp {
103104
slug:kebabCase(name),
104105
display_name:name,
105106
external:false,
107+
health:"healthy",
106108
};
107109
}
108110

‎site/src/pages/TaskPage/TaskApps.tsx‎

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,45 @@ type TaskAppsProps = {
2828
};
2929

3030
exportconstTaskApps:FC<TaskAppsProps>=({ task})=>{
31-
constapps=getTaskApps(task);
31+
constapps=getTaskApps(task).filter(
32+
// The Chat UI app will be displayed in the sidebar, so we don't want to
33+
// show it as a web app.
34+
(app)=>
35+
app.id!==task.workspace.latest_build.ai_task_sidebar_app_id&&
36+
app.health!=="disabled",
37+
);
3238
const[embeddedApps,externalApps]=splitEmbeddedAndExternalApps(apps);
3339
const[activeAppId,setActiveAppId]=useState(embeddedApps.at(0)?.id);
40+
consthasAvailableAppsToDisplay=
41+
embeddedApps.length>0||externalApps.length>0;
3442

3543
return(
3644
<mainclassName="flex flex-col h-full">
37-
<divclassName="w-full flex items-center border-0 border-b border-border border-solid">
38-
<ScrollAreaclassName="max-w-full">
39-
<divclassName="flex w-max gap-2 items-center p-2 pb-0">
40-
{embeddedApps.map((app)=>(
41-
<TaskAppTab
42-
key={app.id}
43-
task={task}
44-
app={app}
45-
active={app.id===activeAppId}
46-
onClick={(e)=>{
47-
e.preventDefault();
48-
setActiveAppId(app.id);
49-
}}
50-
/>
51-
))}
52-
</div>
53-
<ScrollBarorientation="horizontal"className="h-2"/>
54-
</ScrollArea>
55-
56-
{externalApps.length>0&&(
57-
<ExternalAppsDropdowntask={task}externalApps={externalApps}/>
58-
)}
59-
</div>
45+
{hasAvailableAppsToDisplay&&(
46+
<divclassName="w-full flex items-center border-0 border-b border-border border-solid">
47+
<ScrollAreaclassName="max-w-full">
48+
<divclassName="flex w-max gap-2 items-center p-2 pb-0">
49+
{embeddedApps.map((app)=>(
50+
<TaskAppTab
51+
key={app.id}
52+
task={task}
53+
app={app}
54+
active={app.id===activeAppId}
55+
onClick={(e)=>{
56+
e.preventDefault();
57+
setActiveAppId(app.id);
58+
}}
59+
/>
60+
))}
61+
</div>
62+
<ScrollBarorientation="horizontal"className="h-2"/>
63+
</ScrollArea>
64+
65+
{externalApps.length>0&&(
66+
<ExternalAppsDropdowntask={task}externalApps={externalApps}/>
67+
)}
68+
</div>
69+
)}
6070

6171
{embeddedApps.length>0 ?(
6272
<divclassName="flex-1">

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp