Skip to content
Open
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
62 changes: 62 additions & 0 deletions site/src/pages/WorkspacesPage/WorkspacesPageView.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
MockUserOwner,
MockWorkspace,
MockWorkspaceAgent,
MockWorkspaceApp,
MockWorkspaceSubAgent,
mockApiError,
} from "#/testHelpers/entities";
import {
Expand Down Expand Up @@ -362,6 +364,66 @@ export const MultipleApps: Story = {
},
};

// The shortcuts row only renders apps from the parent agent (the agent without
// a `parent_id`). Apps from sub-agents, such as those created by devcontainers,
// are excluded so the row stays deterministic regardless of agent ordering.
export const ParentAgentApps: Story = {
args: {
workspaces: [
{
...MockWorkspace,
name: "parent-agent-apps",
latest_build: {
...MockWorkspace.latest_build,
resources: [
{
...MockWorkspace.latest_build.resources[0],
agents: [
// Sub-agent is listed first to prove ordering does
// not determine which apps are shown.
{
...MockWorkspaceSubAgent,
display_apps: [],
apps: [
{
...MockWorkspaceApp,
id: "sub-agent-app",
slug: "sub-agent-app",
display_name: "Sub Agent App",
health: "healthy",
},
],
},
{
...MockWorkspaceAgent,
display_apps: [],
apps: [
{
...MockWorkspaceApp,
id: "parent-agent-app",
slug: "parent-agent-app",
display_name: "Parent Agent App",
health: "healthy",
},
],
},
],
},
],
},
},
],
count: allWorkspaces.length,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByRole("link", { name: /Open Parent Agent App/i });
expect(
canvas.queryByRole("link", { name: /Open Sub Agent App/i }),
).not.toBeInTheDocument();
},
};

export const ShowOrganizations: Story = {
args: {
workspaces: [
Expand Down
14 changes: 9 additions & 5 deletions site/src/pages/WorkspacesPage/WorkspacesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -656,15 +656,19 @@ const WorkspaceApps: FC<WorkspaceAppsProps> = ({ workspace }) => {
* Coder is pretty flexible and allows an enormous variety of use cases, such
* as having multiple resources with many agents, but they are not common. The
* most common scenario is to have one single compute resource with one single
* agent containing all the apps. Lets test this getting the apps for the
* first resource, and first agent - they are sorted to return the compute
* resource first - and see what customers and ourselves, using dogfood, think
* about that.
* agent containing all the apps. We get the apps from the first compute
* resource (they are sorted to return the compute resource first).
*
* For multi-agent workspaces we show the apps from the parent agent, the one
* without a `parent_id`, instead of whichever agent happens to be discovered
* first. Sub-agents, such as those created by devcontainers, are skipped so

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit [CRF-1] "their apps do not replace the parent agent's apps depending on ordering" parses two ways: (1) the ordering-dependent replacement no longer happens, or (2) whether replacement happens depends on ordering. The follow-up sentence resolves it, but a reader shouldn't have to read ahead to parse one sentence.

Suggestion:

 * Sub-agents, such as those created by devcontainers, are skipped so
 * agent ordering does not determine which apps appear.

(Leorio)

🤖

Comment on lines +662 to +664

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only valid for multi-agent workspaces with child agents. There are cases when there could be multiple parent-level agents.

* their apps do not replace the parent agent's apps depending on ordering.
* This keeps the shortcuts row deterministic.
*/
const agent = workspace.latest_build.resources

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit [CRF-2] agent is now selected by parent_id === null, not by position. Renaming to parentAgent would carry the selection semantics to downstream uses (parentAgent.display_apps, parentAgent.apps) where the .find predicate is no longer visible.

(Gon)

🤖

.filter((r) => !r.hide)
.at(0)
?.agents?.at(0);
?.agents?.find((a) => a.parent_id === null);
if (!agent) {
return null;
}
Expand Down
Loading