feat(agent): add event orchestration surface

This commit is contained in:
Junyan Qin
2026-06-23 23:23:09 +08:00
committed by huanghuoguoguo
parent c6596b98e6
commit 27b43c1731
34 changed files with 2980 additions and 139 deletions
@@ -455,7 +455,7 @@ export default function DynamicFormComponent({
}: {
itemConfigList: IDynamicFormItemSchema[];
onSubmit?: (val: object) => unknown;
initialValues?: Record<string, object>;
initialValues?: Record<string, any>;
onFileUploaded?: (fileKey: string) => void;
isEditing?: boolean;
externalDependentValues?: Record<string, unknown>;
@@ -77,6 +77,51 @@ function hasUsableOptionName(option: { name?: string | null }): boolean {
return typeof option.name === 'string' && option.name.trim().length > 0;
}
function getPluginComponentIconURL(value?: string): string | null {
if (!value?.startsWith('plugin:')) {
return null;
}
const match = value.match(/^plugin:([^/]+)\/([^/]+)(?:\/|$)/);
if (!match) {
return null;
}
return httpClient.getPluginIconURL(match[1], match[2]);
}
function SelectOptionContent({
label,
value,
showDescription = false,
}: {
label: string;
value: string;
showDescription?: boolean;
}) {
const iconURL = getPluginComponentIconURL(value);
return (
<div className="flex min-w-0 items-center gap-2">
{iconURL && (
<img
src={iconURL}
alt=""
className="size-5 shrink-0 rounded object-cover"
/>
)}
<div className="min-w-0 flex flex-col">
<span className="truncate">{label}</span>
{showDescription && (
<span className="truncate text-xs text-muted-foreground">
{value}
</span>
)}
</div>
</div>
);
}
export default function DynamicFormItemComponent({
config,
field,
@@ -416,10 +461,20 @@ export default function DynamicFormItemComponent({
);
case DynamicFormItemType.SELECT:
const selectedOption = config.options?.find(
(option) => option.name === field.value,
);
return (
<Select value={field.value} onValueChange={field.onChange}>
<Select value={field.value ?? ''} onValueChange={field.onChange}>
<SelectTrigger className="w-full max-w-md bg-[#ffffff] dark:bg-[#2a2a2e]">
<SelectValue placeholder={t('common.select')} />
{selectedOption ? (
<SelectOptionContent
label={extractI18nObject(selectedOption.label)}
value={selectedOption.name}
/>
) : (
<SelectValue placeholder={t('common.select')} />
)}
</SelectTrigger>
<SelectContent>
<SelectGroup>
@@ -429,7 +484,11 @@ export default function DynamicFormItemComponent({
value={option.name}
description={option.name}
>
{extractI18nObject(option.label)}
<SelectOptionContent
label={extractI18nObject(option.label)}
value={option.name}
showDescription
/>
</SelectItem>
))}
</SelectGroup>
@@ -196,7 +196,7 @@ const ENTITY_KEY_MAP: Record<
// Route prefix map for entity detail pages
const ENTITY_ROUTE_MAP: Record<EntityCategoryId, string> = {
bots: '/home/bots',
pipelines: '/home/pipelines',
pipelines: '/home/agents',
knowledge: '/home/knowledge',
plugins: '/home/extensions',
mcp: '/home/mcp',
@@ -115,9 +115,9 @@ export function SidebarDataProvider({
const refreshPipelines = useCallback(async () => {
try {
const resp = await httpClient.getPipelines();
const resp = await httpClient.getAgents();
setPipelines(
resp.pipelines.map((p) => ({
resp.agents.map((p) => ({
id: p.uuid || '',
name: p.name,
description: p.description,
@@ -126,7 +126,7 @@ export function SidebarDataProvider({
})),
);
} catch (error) {
console.error('Failed to fetch pipelines for sidebar:', error);
console.error('Failed to fetch agents for sidebar:', error);
}
}, []);
@@ -57,10 +57,10 @@ export const sidebarConfigList = [
}),
new SidebarChildVO({
id: 'pipelines',
name: t('pipelines.title'),
name: t('agents.title'),
icon: <Workflow className="text-blue-500" />,
route: '/home/pipelines',
description: t('pipelines.description'),
route: '/home/agents',
description: t('agents.description'),
helpLink: {
en_US: 'https://link.langbot.app/en/docs/pipelines',
zh_Hans: 'https://link.langbot.app/zh/docs/pipelines',