.NET: Expose more agent metadata through DevUI discovery endpoint (#2138)

* Exposes more agent metadata through DevUI discovery endpoint

* Exposes more agent metadata through DevUI discovery endpoint

* pr feedback

* pr feedback

* Don't expose Workflows as agents to DevUI
This commit is contained in:
Reuben Bond
2025-11-12 15:38:06 -08:00
committed by GitHub
Unverified
parent edb367a2b9
commit 4b0f724e62
12 changed files with 277 additions and 127 deletions
File diff suppressed because one or more lines are too long
@@ -94,14 +94,14 @@ export function AgentDetailsModal({
{/* Grid Layout for Metadata */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
{/* Model & Client */}
{(agent.model || agent.chat_client_type) && (
{(agent.model_id || agent.chat_client_type) && (
<DetailCard
title="Model & Client"
icon={<Bot className="h-4 w-4 text-muted-foreground" />}
>
<div className="space-y-1">
{agent.model && (
<div className="font-mono text-foreground">{agent.model}</div>
{agent.model_id && (
<div className="font-mono text-foreground">{agent.model_id}</div>
)}
{agent.chat_client_type && (
<div className="text-xs">({agent.chat_client_type})</div>
@@ -136,7 +136,9 @@ export function AgentDetailsModal({
>
<div
className={
agent.has_env ? "text-orange-600 dark:text-orange-400" : "text-green-600 dark:text-green-400"
agent.has_env
? "text-orange-600 dark:text-orange-400"
: "text-green-600 dark:text-green-400"
}
>
{agent.has_env
@@ -162,11 +164,11 @@ export function AgentDetailsModal({
{/* Tools and Middleware Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{/* Tools */}
<DetailCard
title={`Tools (${agent.tools.length})`}
icon={<Package className="h-4 w-4 text-muted-foreground" />}
>
{agent.tools.length > 0 ? (
{agent.tools && agent.tools.length > 0 && (
<DetailCard
title={`Tools (${agent.tools.length})`}
icon={<Package className="h-4 w-4 text-muted-foreground" />}
>
<ul className="space-y-1">
{agent.tools.map((tool, index) => (
<li key={index} className="font-mono text-xs text-foreground">
@@ -174,10 +176,8 @@ export function AgentDetailsModal({
</li>
))}
</ul>
) : (
<div className="text-muted-foreground">No tools configured</div>
)}
</DetailCard>
</DetailCard>
)}
{/* Middleware */}
{agent.middleware && agent.middleware.length > 0 && (
@@ -64,8 +64,8 @@ export function WorkflowDetailsModal({
workflow.source === "directory"
? "Local"
: workflow.source === "in_memory"
? "In-Memory"
: "Gallery";
? "In-Memory"
: "Gallery";
return (
<Dialog open={open} onOpenChange={onOpenChange}>
@@ -151,7 +151,8 @@ export function WorkflowDetailsModal({
{workflow.executors.map((executor, index) => (
<div
key={index}
className="font-mono text-xs text-foreground bg-muted px-2 py-1 rounded"
className="font-mono text-xs text-foreground bg-muted px-2 py-1 rounded truncate"
title={executor}
>
{executor}
</div>
@@ -33,12 +33,13 @@ interface BackendEntityInfo {
tools?: (string | Record<string, unknown>)[];
metadata: Record<string, unknown>;
source?: string;
required_env_vars?: import("@/types").EnvVarRequirement[];
// Deployment support
deployment_supported?: boolean;
deployment_reason?: string;
// Agent-specific fields (present when type === "agent")
instructions?: string;
model?: string;
model_id?: string;
chat_client_type?: string;
context_providers?: string[];
middleware?: string[];
@@ -205,41 +206,51 @@ class ApiClient {
tools: (entity.tools || []).map((tool) =>
typeof tool === "string" ? tool : JSON.stringify(tool)
),
has_env: false, // Default value
has_env: !!(entity.required_env_vars && entity.required_env_vars.length > 0),
module_path:
typeof entity.metadata?.module_path === "string"
? entity.metadata.module_path
: undefined,
required_env_vars: entity.required_env_vars,
metadata: entity.metadata, // Preserve metadata including lazy_loaded flag
// Deployment support
deployment_supported: entity.deployment_supported,
deployment_reason: entity.deployment_reason,
// Agent-specific fields
instructions: entity.instructions,
model: entity.model,
model_id: entity.model_id,
chat_client_type: entity.chat_client_type,
context_providers: entity.context_providers,
middleware: entity.middleware,
};
} else {
// Workflow
const firstTool = entity.tools?.[0];
const startExecutorId = typeof firstTool === "string" ? firstTool : "";
// Workflow - prefer executors field, fall back to tools for backward compatibility
const executorList = entity.executors || entity.tools || [];
// Determine start_executor_id: use entity value, or first executor if it's a string
let startExecutorId = entity.start_executor_id || "";
if (!startExecutorId && executorList.length > 0) {
const firstExecutor = executorList[0];
if (typeof firstExecutor === "string") {
startExecutorId = firstExecutor;
}
}
return {
id: entity.id,
name: entity.name,
description: entity.description,
type: "workflow" as const,
source: (entity.source as AgentSource) || "directory",
executors: (entity.tools || []).map((tool) =>
typeof tool === "string" ? tool : JSON.stringify(tool)
executors: executorList.map((executor) =>
typeof executor === "string" ? executor : JSON.stringify(executor)
),
has_env: false,
has_env: !!(entity.required_env_vars && entity.required_env_vars.length > 0),
module_path:
typeof entity.metadata?.module_path === "string"
? entity.metadata.module_path
: undefined,
required_env_vars: entity.required_env_vars,
metadata: entity.metadata, // Preserve metadata including lazy_loaded flag
// Deployment support
deployment_supported: entity.deployment_supported,
@@ -250,6 +261,7 @@ class ApiClient {
}, // Default schema
input_type_name: entity.input_type_name || "Input",
start_executor_id: startExecutorId,
tools: [],
};
}
});
@@ -37,7 +37,7 @@ export interface AgentInfo {
deployment_reason?: string;
// Agent-specific fields
instructions?: string;
model?: string;
model_id?: string;
chat_client_type?: string;
context_providers?: string[];
middleware?: string[];