mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
93cbf6b3f0
* Parse structuredContent from MCP CallToolResult (#3313) The _parse_tool_result_from_mcp method only iterated over the content field from CallToolResult, ignoring the structuredContent field entirely. MCP servers that return JSON data via structuredContent (e.g., Power BI MCP) appeared to return None. Add handling for structuredContent: when present, serialize it as JSON text and append it to the result list. This preserves the data for the LLM while maintaining backward compatibility with existing behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Parse MCP CallToolResult.structuredContent field to prevent tool results returning None Fixes #3313 * Address review feedback: add default=str to json.dumps and remove .checkpoints/ - Add default=str to json.dumps for structuredContent serialization so non-JSON-serializable values (e.g. bytes) degrade gracefully instead of raising TypeError - Remove all .checkpoints/ runtime artifacts from the repository - Add **/.checkpoints/ to .gitignore to prevent future accidental commits - Add test for non-serializable structuredContent values Fixes #3313 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review feedback for #3313: Python: MCP CallToolResult.structuredContent field is not parsed, causing tool results to return None --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
93cbf6b3f0
·
2026-06-10 12:51:09 +00:00
History
Harness Console
A Textual-based terminal UI for running and observing AI agents built with the Agent Framework.
Quick Start
from console import run_agent_async, build_default_observers
await run_agent_async(
agent=my_agent,
session=my_session,
observers=build_default_observers(),
)
See harness_research.py for a complete example.
Package Structure
console/
├── __init__.py # Public API exports
├── harness_console.py # run_agent_async() entry point
├── app.py # HarnessApp (Textual application)
├── app_state.py # HarnessAppState, enums, data types
├── agent_runner.py # HarnessAgentRunner (streaming orchestration)
├── state_driver.py # IUXStateDriver protocol
├── textual_state_driver.py # Textual implementation of IUXStateDriver
├── formatters.py # Tool call formatters
├── observers/ # Lifecycle observers
│ ├── base.py # ConsoleObserver abstract base
│ ├── text_output.py # Streaming text display
│ ├── tool_call_display.py # Tool call formatting
│ ├── tool_approval.py # User approval for tool calls
│ ├── error_display.py # Error messages
│ ├── usage_display.py # Token usage tracking
│ └── reasoning_display.py # Reasoning/thinking blocks
├── components/ # Textual UI widgets
│ ├── scroll_panel.py # Conversation history
│ ├── text_input.py # User text input
│ ├── list_selection.py # Multiple choice selector
│ ├── agent_status.py # Spinner + usage display
│ └── agent_mode_help.py # Mode indicator + help text
└── commands/ # Slash command handlers
├── base.py # CommandHandler abstract base
├── exit_handler.py # /exit
├── mode_handler.py # /mode [plan|execute]
├── todo_handler.py # /todos
└── session_handler.py # /session-export, /session-import
Public API
| Export | Description |
|---|---|
run_agent_async |
Main entry point — runs the Textual app with an agent |
build_default_observers |
Factory for the standard observer set |
build_default_command_handlers |
Factory for slash command handlers |
ConsoleObserver |
Base class for custom observers |
ToolCallFormatter |
Base class for custom tool formatters |
CommandHandler |
Base class for custom slash commands |
Architecture
The console follows a unidirectional data flow:
AgentRunner → Observers → StateDriver → AppState → Textual UI
↑
User Input (app.py)
- AgentRunner streams responses from the agent and dispatches events to observers.
- Observers process events (text chunks, tool calls, errors) and update the state driver.
- StateDriver (
IUXStateDriver) mutatesHarnessAppStateand notifies the UI. - Textual App reads state and syncs widgets on each notification.
Key Design Choices
| Concern | Approach |
|---|---|
| Rendering | Textual widgets + Rich markup (no manual ANSI) |
| State | Single HarnessAppState dataclass, mutated by driver |
| Streaming text | Truncate-and-rewrite on RichLog for flicker-free updates |
| Extensibility | Custom observers, formatters, and commands via base classes |
| Follow-up questions | Observer returns FollowUpQuestion → UI shows prompt/choices |
Dependencies
textual— TUI frameworkrich— Text formattingagent-framework— Core agent framework