diff --git a/site/src/pages/AgentsPage/AgentChatPage.tsx b/site/src/pages/AgentsPage/AgentChatPage.tsx
index 2f0c6aa01c..140599324c 100644
--- a/site/src/pages/AgentsPage/AgentChatPage.tsx
+++ b/site/src/pages/AgentsPage/AgentChatPage.tsx
@@ -470,6 +470,7 @@ type _UncoveredAgentFields = Omit<
| "status"
| "name"
| "expanded_directory"
+ | "lifecycle_state"
// Fields below are intentionally not compared. They change
// frequently (stats, metadata) or are objects/arrays that would
// require deep comparison, and the UI does not read them.
@@ -481,7 +482,6 @@ type _UncoveredAgentFields = Omit<
| "disconnected_at"
| "started_at"
| "ready_at"
- | "lifecycle_state"
| "resource_id"
| "instance_id"
| "architecture"
@@ -641,7 +641,8 @@ const AgentChatPage: FC = () => {
prevAgent?.status === nextAgent?.status &&
prevAgent?.name === nextAgent?.name &&
prevAgent?.expanded_directory ===
- nextAgent?.expanded_directory
+ nextAgent?.expanded_directory &&
+ prevAgent?.lifecycle_state === nextAgent?.lifecycle_state
) {
return prev;
}
diff --git a/site/src/pages/AgentsPage/AgentChatPageView.stories.tsx b/site/src/pages/AgentsPage/AgentChatPageView.stories.tsx
index ced1b0506f..c00958a329 100644
--- a/site/src/pages/AgentsPage/AgentChatPageView.stories.tsx
+++ b/site/src/pages/AgentsPage/AgentChatPageView.stories.tsx
@@ -5,7 +5,11 @@ import { reactRouterParameters } from "storybook-addon-remix-react-router";
import { API } from "#/api/api";
import type * as TypesGen from "#/api/typesGenerated";
import type { ChatDiffStatus, ChatMessagePart } from "#/api/typesGenerated";
-import { MockUserOwner } from "#/testHelpers/entities";
+import {
+ MockUserOwner,
+ MockWorkspace,
+ MockWorkspaceAgent,
+} from "#/testHelpers/entities";
import {
withAuthProvider,
withDashboardProvider,
@@ -373,6 +377,74 @@ export const WithWorkspaceActions: Story = {
),
};
+// ---------------------------------------------------------------------------
+// Workspace status pill stories
+// ---------------------------------------------------------------------------
+
+export const WorkspaceAgentStarting: Story = {
+ render: () => (
+
+ ),
+};
+
+export const WorkspaceAgentCreated: Story = {
+ render: () => (
+
+ ),
+};
+
+export const WorkspaceAgentReady: Story = {
+ render: () => (
+
+ ),
+};
+
+export const WorkspaceAgentStartError: Story = {
+ render: () => (
+
+ ),
+};
+
+export const WorkspaceAgentStartTimeout: Story = {
+ render: () => (
+
+ ),
+};
+
+export const WorkspaceNoAgent: Story = {
+ render: () => ,
+};
+
// ---------------------------------------------------------------------------
// AgentChatPageLoadingView stories
// ---------------------------------------------------------------------------
diff --git a/site/src/pages/AgentsPage/AgentChatPageView.tsx b/site/src/pages/AgentsPage/AgentChatPageView.tsx
index 2056ba48c0..6655c4d27c 100644
--- a/site/src/pages/AgentsPage/AgentChatPageView.tsx
+++ b/site/src/pages/AgentsPage/AgentChatPageView.tsx
@@ -278,10 +278,25 @@ export const AgentChatPageView: FC = ({
const attachedWorkspace = (() => {
if (!workspace || !workspaceRoute) return undefined;
- const { type, text } = getDisplayWorkspaceStatus(
+ let { type, text } = getDisplayWorkspaceStatus(
workspace.latest_build.status,
workspace.latest_build.job,
);
+ const agentPreparing =
+ workspace.latest_build.status === "running" &&
+ (workspaceAgent?.lifecycle_state === "created" ||
+ workspaceAgent?.lifecycle_state === "starting");
+ const agentStartupFailed =
+ workspace.latest_build.status === "running" &&
+ (workspaceAgent?.lifecycle_state === "start_error" ||
+ workspaceAgent?.lifecycle_state === "start_timeout");
+ if (agentPreparing) {
+ type = "active";
+ text = "Preparing";
+ } else if (agentStartupFailed) {
+ type = "warning";
+ text = "Startup failed";
+ }
const effectiveType = workspace.health.healthy ? type : "warning";
const statusLabel = workspace.health.healthy
? `Workspace ${text.toLowerCase()}`