Commit Graph

14 Commits

Author SHA1 Message Date
westey a2018b40f9 Python: [BREAKING] Require approval for file-access tools with read-only auto-approval (#6599)
* Require approvals for file-access and expose auto approval funcs for it

* Scope file-access auto-approval rules to local tools; fix base-Agent sample

Address PR #6599 review feedback:
- read_only/all_tools auto-approval rules now reject any call carrying a
  server_label so they stay scoped to FileAccessProvider's local tools and
  never auto-approve a same-named hosted tool.
- Expand the FileAccessProvider docstring to explain the runtime effect of
  approval_mode="always_require" and point to ToolApprovalMiddleware /
  create_harness_agent.
- Fix the base-Agent file_access_data_processing sample, which would otherwise
  stop executing file tools under the new always_require defaults, by adding
  ToolApprovalMiddleware with all_tools_auto_approval_rule.
- Add tests covering hosted (server_label) calls and update docs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Clean up comments

* Update sample after merge

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 09:51:12 +00:00
westey 7b6f582b13 Python: Agent Harness blog post accompanying samples part 1 (#6605)
* Add samples for harness blog post part 1

* Add readme for python samples

* Update python instructions to match dotnet instructions

* Address PR comments

* Add link to blog posts

* Fix blog post naming.

* Add more blog post links
2026-06-22 18:33:36 +01:00
westey d108d4b549 Python: [BREAKING] Integrate looping into HarnessAgent (#6607)
* Integrate looping into harness

* Address PR comments

* Address PR comments.

* Fix typing error
2026-06-22 13:14:30 +00:00
westey dc445592ed Python: [BREAKING] Port FileMemoryProvider and integrate FileMemoryProvider & FileAccess into the harness agent (#6547)
* Port FileMemoryProvider to python and integrate it and FileAccessProvider into the harness

* Address PR comments

* Address PR comments

* Create FileSystemAgentFileStore root lazily on first write

Construction no longer calls mkdir, so building a store (and therefore a
default create_harness_agent, which wires default file-memory and file-access
stores under the CWD) performs no filesystem writes and does not fail in
read-only working directories. The root directory is created on the first
write_file / create_directory call; all read/list/search operations already
tolerate a missing root. Updates docstrings and adds a regression test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix typing

* Fixing typing errors

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-18 20:15:46 +00:00
westey 699916d639 Python: Add WebSearchDisplayObserver to harness console (#6572)
* Adding an observer to the python harness for web search tools

* Escape dynamic strings with rich.markup.escape() in WebSearchDisplayObserver

Apply rich.markup.escape() to all user/tool-provided strings (queries, URLs,
titles, patterns) before interpolation into Rich-markup-enabled output. This
prevents characters like '['/']' from being interpreted as Rich markup tags.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-18 09:42:30 +00:00
westey 7bf2d2a6d0 Python: Fix harness console rendering one streamed tool call many times (#6549)
* Fix render issue for tools that are streamed in parts.

* Address PR review: missing call_id fallback, empty-mapping args, _is_complete perf

- Print call_id-less function calls as-is instead of merging under a name-derived
  key (which could drop distinct unnamed calls).
- Preserve an empty {} mapping rather than coercing it to None.
- Add a structural bracket-balance gate before json.loads in _is_complete to
  avoid O(n^2) re-parsing of growing streamed arguments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-17 05:15:51 +00:00
westey 0db9305625 Python: Integrate tool approval into the harness (#6522)
* Integrate auto tool-approval feature into harness

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Rename disable_tool_approval to disable_tool_auto_approval

Addresses PR review feedback that the parameter name was unclear. The flag
toggles the auto/standing tool-approval middleware.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-16 15:21:31 +00:00
westey d7027fc1f9 Python: [BREAKING] Align FileAccess tools with .NET — directory discovery and recursive search (#6476)
* Align FileAccess tools with .Net; add directory discovery and recursive search

* Fix choices field description: spacing, line length, grammar

Addresses PR review: separate concatenated string literals with proper
spacing/newlines, wrap lines under the 120-char Ruff limit, and fix
"doesn't" -> "don't".

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR comments

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-15 06:55:21 +00:00
westey 3d5421edc1 Python: Integrate shell tool into harness agent (#6451)
* Integrate shell tool into AgentHarness

* Validate shell_executor exposes as_function() with a clear TypeError

Addresses PR review feedback: a public factory should fail fast with an
actionable error rather than a cryptic AttributeError when an incompatible
shell_executor is supplied. Validation happens upfront, regardless of whether
the client supports shell tools.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Type shell harness params via TYPE_CHECKING import

Addresses PR review feedback: type shell_executor and
shell_environment_provider_options instead of Any, using a TYPE_CHECKING
import from agent_framework_tools.shell. The import never executes at
runtime, so there is no circular dependency, and the lazy runtime import of
ShellEnvironmentProvider is retained. Since ShellExecutor is a protocol
without as_function(), the validated getattr result is invoked directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-11 20:51:59 +00:00
westey 8dde9ef627 Python: HarnessAgent: Disable compaction when max tokens not provided (#6410)
* HarnessAgent: Disable compaction when max tokens not provided

* Fix regression.

* Address PR comments

* Require max_output_tokens to be positive

Reject max_output_tokens=0 (must be positive), mirroring
max_context_window_tokens. Addresses PR review feedback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-10 13:57:23 +00:00
Giles Odigwe 93cbf6b3f0 Python: Parse MCP CallToolResult.structuredContent field to prevent tool results returning None (#6421)
* 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>
2026-06-10 12:51:09 +00:00
westey bad05a2bdc Python: Harness console for python (#6312)
* Add initial harness console for python

* Add textual to project

* Add planning and approval flows with list selector

* Address PR comments

* Fix list selection bug

* Fix PR #6312 round 2 review comments

- Escape untrusted agent text with rich.markup.escape() in observers
  (text_output, planning_output, reasoning_display) to prevent markup injection
- Remove non-functional 'Always approve' choices from tool_approval.py
  (framework lacks CreateAlwaysApproveToolResponse support)
- Remove textual from root pyproject.toml dev deps (sample-specific)
- Add PEP 723 inline script metadata to harness_research.py
- Narrow except Exception to except NoMatches in list_selection.py

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix build error

* Fix build errors

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-09 05:48:35 +00:00
Eduard van Valkenburg 8091d052d8 Python: refresh dev dependencies and validate runtime bounds (#6238)
Updates third-party dev dependencies across the Python workspace and
validates that all runtime dependency bounds still hold at both ends.

Dev dependency bumps (root, lab, declarative, durabletask):
- uv 0.11.6 -> 0.11.17, ruff 0.15.8 -> 0.15.15,
  pytest-asyncio 1.3.0 -> 1.4.0, mcp 1.27.0 -> 1.27.2,
  azure-monitor-opentelemetry 1.8.7 -> 1.8.8,
  poethepoet 0.42.1 -> 0.46.0, prek 0.3.9 -> 0.4.3,
  types-python-dateutil and types-PyYaml stub bumps.
- Transitive Dependabot items swept via lock: idna 3.11 -> 3.17,
  pip 26.0.1 -> 26.1.2.

Deliberately excluded:
- opentelemetry-sdk stays 1.40.0: azure-monitor-opentelemetry (incl.
  1.8.8) hard-pins opentelemetry-sdk==1.40.
- mypy stays 1.20.0 and pyright stays 1.1.408: the 2.1.0 / 1.1.409
  bumps introduce new diagnostics that fail type checking and need
  dedicated PRs.
- rich kept as a range: agentlightning (lab[lightning]) forces
  rich==13.9.4.

Code/formatting changes driven by the ruff upgrade:
- devui lifespan now uses try/finally so shutdown cleanup always runs
  (ruff RUF075).
- Removed unused TYPE_CHECKING imports in core and foundry flagged by
  ruff 0.15.15.
- Reapplied ruff 0.15.15 formatting to the files it changed.

Validation: validate-dependency-bounds-test "*" passes (31/31 lower +
31/31 upper); typing 62/62; lint 31/31; devui tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-01 17:53:56 +00:00
westey ef86fb51d5 Python: Add a HarnessAgent with available features and sample (#6041)
* Add a HarnessAgent with available features and sample

* Fix formatting

* Address PR comments and fix mypy error

* Add web search support to HarnessAgent

* Fix build warning

* Apply suggestions from code review

Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>

* Address PR comments

* Address PR comments

* Address further PR comments.

* Fix markdown broken link

---------

Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
2026-05-27 14:54:00 +01:00