Skip to content

Commit 35fdfc2

Browse files
feat: add top level obot page to admin ui (#1993)
* fix: ensure project inherits parent from copied project - additionally ensure project IDs are converted properly when forwarding to the UI Signed-off-by: Ryan Hopper-Lowe <[email protected]> * feat: add top level obots page to admin ui * chore: fix tests * fix: invalid json tag on project type * feat: add filtering to threads page by obotId in admin ui * feat: add filters for obot children and parents in admin ui * feat: enable filtering obots by userID * feat: add ability to filter out spawned obots from obots page * feat: add column filters to top level obot page * chore: update tests in admin UI * chore: generate new types * chore: update obot page icon --------- Signed-off-by: Ryan Hopper-Lowe <[email protected]>
1 parent 59db081 commit 35fdfc2

File tree

25 files changed

+609
-33
lines changed

25 files changed

+609
-33
lines changed

apiclient/types/project.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ type Project struct {
55
ProjectManifest
66
AssistantID string `json:"assistantID,omitempty"`
77
Editor bool `json:"editor"`
8+
ParentID string `json:"parentID,omitempty"`
9+
UserID string `json:"userID,omitempty"`
810
}
911

1012
type ProjectManifest struct {

pkg/api/handlers/projects.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,10 @@ func convertProject(thread *v1.Thread) types.Project {
494494
ProjectManifest: types.ProjectManifest{
495495
ThreadManifest: thread.Spec.Manifest,
496496
},
497+
ParentID: strings.Replace(thread.Spec.ParentThreadName, system.ThreadPrefix, system.ProjectPrefix, 1),
497498
AssistantID: thread.Spec.AgentName,
498499
Editor: thread.IsEditor(),
500+
UserID: thread.Spec.UserID,
499501
}
500502
p.Type = "project"
501503
p.ID = strings.Replace(p.ID, system.ThreadPrefix, system.ProjectPrefix, 1)

pkg/api/handlers/threads.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/obot-platform/obot/pkg/api"
1212
"github.com/obot-platform/obot/pkg/events"
1313
v1 "github.com/obot-platform/obot/pkg/storage/apis/obot.obot.ai/v1"
14+
"github.com/obot-platform/obot/pkg/system"
1415
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1516
)
1617

@@ -49,7 +50,7 @@ func convertThread(thread v1.Thread) types.Thread {
4950
LastRunID: thread.Status.LastRunName,
5051
CurrentRunID: thread.Status.CurrentRunName,
5152
State: state,
52-
ProjectID: thread.Spec.ParentThreadName,
53+
ProjectID: strings.Replace(thread.Spec.ParentThreadName, system.ThreadPrefix, system.ProjectPrefix, 1),
5354
UserID: thread.Spec.UserID,
5455
Abort: thread.Spec.Abort,
5556
SystemTask: thread.Spec.SystemTask,

pkg/storage/openapi/generated/openapi_generated.go

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ui/admin/app/components/composed/Filters.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { useNavigate, useSearchParams } from "react-router";
44
import { $path, Routes } from "safe-routes";
55

66
import { Agent } from "~/lib/model/agents";
7+
import { Project } from "~/lib/model/project";
78
import { Task } from "~/lib/model/tasks";
89
import { User } from "~/lib/model/users";
910
import { RouteService } from "~/lib/service/routeService";
@@ -14,6 +15,8 @@ type QueryParams = {
1415
agentId?: string;
1516
userId?: string;
1617
taskId?: string;
18+
obotId?: string;
19+
parentObotId?: string;
1720
createdStart?: string;
1821
createdEnd?: string;
1922
};
@@ -22,11 +25,13 @@ export function Filters({
2225
agentMap,
2326
userMap,
2427
taskMap,
28+
projectMap,
2529
url,
2630
}: {
2731
agentMap?: Map<string, Agent>;
2832
userMap?: Map<string, User>;
2933
taskMap?: Map<string, Task>;
34+
projectMap?: Map<string, Project>;
3035
url: keyof Routes;
3136
}) {
3237
const [searchParams] = useSearchParams();
@@ -85,8 +90,25 @@ export function Filters({
8590
value: `${new Date(filters.createdStart).toLocaleDateString()} ${filters.createdEnd ? `- ${new Date(filters.createdEnd).toLocaleDateString()}` : ""}`,
8691
onRemove: () => deleteFilters("createdStart", "createdEnd"),
8792
},
93+
"obotId" in filters &&
94+
filters.obotId &&
95+
projectMap && {
96+
key: "obotId",
97+
label: "Obot",
98+
value: projectMap.get(filters.obotId)?.name ?? filters.obotId,
99+
onRemove: () => deleteFilters("obotId"),
100+
},
101+
"parentObotId" in filters &&
102+
filters.parentObotId &&
103+
projectMap && {
104+
key: "parentObotId",
105+
label: "Spawned from",
106+
value:
107+
projectMap.get(filters.parentObotId)?.name ?? filters.parentObotId,
108+
onRemove: () => deleteFilters("parentObotId"),
109+
},
88110
].filter((x) => !!x);
89-
}, [navigate, searchParams, agentMap, userMap, taskMap, url]);
111+
}, [url, searchParams, agentMap, userMap, taskMap, projectMap, navigate]);
90112

91113
return (
92114
<div className="flex gap-2 pb-2">

ui/admin/app/components/composed/typography.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export function Truncate({
5353
"line-clamp-2": clamp && clampLength === 2,
5454
truncate: !clamp,
5555
},
56+
"break-all",
5657
classNames?.content
5758
)}
5859
>

ui/admin/app/components/sidebar/Sidebar.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
BotIcon,
3+
BotMessageSquareIcon,
34
BoxesIcon,
45
CpuIcon,
56
InfoIcon,
@@ -46,6 +47,11 @@ const items = [
4647
url: $path("/agents"),
4748
icon: BotIcon,
4849
},
50+
{
51+
title: "Obots",
52+
url: $path("/obots"),
53+
icon: BotMessageSquareIcon,
54+
},
4955
{
5056
title: "Chat Threads",
5157
url: $path("/chat-threads"),

ui/admin/app/components/thread/ThreadMeta.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,10 @@ export function ThreadMeta({ entity, thread, className }: ThreadMetaProps) {
160160
<td className="text-right">{thread.currentRunId}</td>
161161
</tr>
162162
)}
163-
{thread.parentThreadId && (
163+
{thread.projectID && (
164164
<tr className="border-foreground/25">
165165
<td className="py-2 pr-4 font-medium">Parent Thread ID</td>
166-
<td className="text-right">{thread.parentThreadId}</td>
166+
<td className="text-right">{thread.projectID}</td>
167167
</tr>
168168
)}
169169
{thread.lastRunID && (

ui/admin/app/components/tools/ToolCatalogGroup.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from "react";
1+
import { Fragment, useState } from "react";
22

33
import {
44
ToolReference,
@@ -67,7 +67,7 @@ export function ToolCatalogGroup({
6767
const configured = configuredTools.has(tool.id);
6868

6969
return (
70-
<>
70+
<Fragment key={tool.id}>
7171
<ToolItem
7272
key={tool.id}
7373
tool={tool}
@@ -100,7 +100,7 @@ export function ToolCatalogGroup({
100100
}
101101
/>
102102
))}
103-
</>
103+
</Fragment>
104104
);
105105
})}
106106
</CommandGroup>

ui/admin/app/components/user/UserMenu.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { LogOutIcon, User } from "lucide-react";
22
import React from "react";
33

4-
import { AuthDisabledUsername, CommonAuthProviderIds } from "~/lib/model/auth";
5-
import { User as UserModel, roleLabel } from "~/lib/model/users";
4+
import { AuthDisabledUsername } from "~/lib/model/auth";
5+
import { getUserDisplayName, roleLabel } from "~/lib/model/users";
66
import { BootstrapApiService } from "~/lib/service/api/bootstrapApiService";
77
import { cn } from "~/lib/utils";
88

@@ -32,7 +32,7 @@ export const UserMenu: React.FC<UserMenuProps> = ({
3232
return null;
3333
}
3434

35-
const displayName = getDisplayName(me);
35+
const displayName = getUserDisplayName(me);
3636

3737
return (
3838
<DropdownMenu>
@@ -80,12 +80,4 @@ export const UserMenu: React.FC<UserMenuProps> = ({
8080
</DropdownMenuContent>
8181
</DropdownMenu>
8282
);
83-
84-
function getDisplayName(user?: UserModel) {
85-
if (user?.currentAuthProvider === CommonAuthProviderIds.GITHUB) {
86-
return user.username;
87-
}
88-
89-
return user?.email;
90-
}
9183
};

0 commit comments

Comments
 (0)