mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Improve DevUI, add Context Inspector view as new tab under traces (#2742)
* Improve DevUI, add Context Inspector view as new tab under traces * fix mypy errors * fix: Handle stale MCP connections in DevUI executor MCP tools can become stale when HTTP streaming responses end - the underlying stdio streams close but `is_connected` remains True. This causes subsequent requests to fail with `ClosedResourceError`. Add `_ensure_mcp_connections()` to detect and reconnect stale MCP tools before agent execution. This is a workaround for an upstream Agent Framework issue where connection state isn't properly tracked. Fixes MCP tools failing on second HTTP request in DevUI. fixes #1476 #1515 #2865 * fix #1572 report import dependency errors more clearly * Ensure there is streaming toggle where users can select streaming vs non streaming mode in devui . Fixes .NET: [Python] DevUI tool call rendering in non-streaming mode? * remove unused dead code * improve ux - workflows with agents show a chat component in execution timelien, also ensure magentic final output shows correctly * update ui build * update devui to use instrumentation instead of tracing, other instrumentation and type/instance check fixes
This commit is contained in:
committed by
GitHub
Unverified
parent
db283cd396
commit
2e1189ca65
@@ -398,7 +398,11 @@ class ApiClient {
|
||||
async listConversationItems(
|
||||
conversationId: string,
|
||||
options?: { limit?: number; after?: string; order?: "asc" | "desc" }
|
||||
): Promise<{ data: unknown[]; has_more: boolean }> {
|
||||
): Promise<{
|
||||
data: unknown[];
|
||||
has_more: boolean;
|
||||
metadata?: { traces?: unknown[] };
|
||||
}> {
|
||||
const params = new URLSearchParams();
|
||||
if (options?.limit) params.set("limit", options.limit.toString());
|
||||
if (options?.after) params.set("after", options.after);
|
||||
@@ -409,7 +413,11 @@ class ApiClient {
|
||||
queryString ? `?${queryString}` : ""
|
||||
}`;
|
||||
|
||||
return this.request<{ data: unknown[]; has_more: boolean }>(url);
|
||||
return this.request<{
|
||||
data: unknown[];
|
||||
has_more: boolean;
|
||||
metadata?: { traces?: unknown[] };
|
||||
}>(url);
|
||||
}
|
||||
|
||||
async getConversationItem(
|
||||
@@ -800,34 +808,68 @@ class ApiClient {
|
||||
yield* this.streamOpenAIResponse(openAIRequest, request.conversation_id, signal);
|
||||
}
|
||||
|
||||
// REMOVED: Legacy streaming methods - use streamAgentExecutionOpenAI and streamWorkflowExecutionOpenAI instead
|
||||
// ========================================
|
||||
// Non-Streaming Execution Methods
|
||||
// ========================================
|
||||
|
||||
// Non-streaming execution (for testing)
|
||||
async runAgent(
|
||||
// Non-streaming agent execution using /v1/responses with stream=false
|
||||
async runAgentSync(
|
||||
agentId: string,
|
||||
request: RunAgentRequest
|
||||
): Promise<{
|
||||
conversation_id: string;
|
||||
result: unknown[];
|
||||
message_count: number;
|
||||
}> {
|
||||
return this.request(`/agents/${agentId}/run`, {
|
||||
): Promise<import("@/types/openai").OpenAIResponse> {
|
||||
// Check if OAI proxy mode is enabled
|
||||
const { oaiMode } = await import("@/stores").then((m) => ({
|
||||
oaiMode: m.useDevUIStore.getState().oaiMode,
|
||||
}));
|
||||
|
||||
const openAIRequest: AgentFrameworkRequest = {
|
||||
metadata: { entity_id: agentId },
|
||||
input: request.input,
|
||||
stream: false,
|
||||
conversation: request.conversation_id,
|
||||
};
|
||||
|
||||
// Apply OAI mode settings if enabled
|
||||
if (oaiMode.enabled) {
|
||||
openAIRequest.model = oaiMode.model;
|
||||
if (oaiMode.temperature !== undefined) {
|
||||
openAIRequest.temperature = oaiMode.temperature;
|
||||
}
|
||||
if (oaiMode.max_output_tokens !== undefined) {
|
||||
openAIRequest.max_output_tokens = oaiMode.max_output_tokens;
|
||||
}
|
||||
}
|
||||
|
||||
const headers: Record<string, string> = {};
|
||||
if (oaiMode.enabled) {
|
||||
headers["X-Proxy-Backend"] = "openai";
|
||||
}
|
||||
|
||||
return this.request<import("@/types/openai").OpenAIResponse>("/v1/responses", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(request),
|
||||
headers,
|
||||
body: JSON.stringify(openAIRequest),
|
||||
});
|
||||
}
|
||||
|
||||
async runWorkflow(
|
||||
// Non-streaming workflow execution using /v1/responses with stream=false
|
||||
async runWorkflowSync(
|
||||
workflowId: string,
|
||||
request: RunWorkflowRequest
|
||||
): Promise<{
|
||||
result: string;
|
||||
events: number;
|
||||
message_count: number;
|
||||
}> {
|
||||
return this.request(`/workflows/${workflowId}/run`, {
|
||||
): Promise<import("@/types/openai").OpenAIResponse> {
|
||||
const openAIRequest: AgentFrameworkRequest = {
|
||||
metadata: { entity_id: workflowId },
|
||||
input: JSON.stringify(request.input_data || {}),
|
||||
stream: false,
|
||||
conversation: request.conversation_id,
|
||||
extra_body: request.checkpoint_id
|
||||
? { entity_id: workflowId, checkpoint_id: request.checkpoint_id }
|
||||
: undefined,
|
||||
};
|
||||
|
||||
return this.request<import("@/types/openai").OpenAIResponse>("/v1/responses", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(request),
|
||||
body: JSON.stringify(openAIRequest),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user