* Bump Python package versions for 1.12.0 release Bump packages represented in the 1.12.0 changelog, promote Foundry Hosting, Azure Content Understanding, Gemini, Mistral, Monty, and Tools to beta, and apply the requested beta cohort date stamp. Root and core move to 1.12.0, released and RC packages use their selected increments, alpha packages including Hosting MCP use the 260721 stamp, and core floors are raised only for proven consumers. Copilot-Session: 2dd9980a-b869-4c16-8642-75b7a6d6ebdf * fix version in readme * Add Responses conversation ID changes to release notes Include the breaking Hosting Responses conversation ID helper changes from #7234 in the Python 1.12.0 changelog. Copilot-Session: 2dd9980a-b869-4c16-8642-75b7a6d6ebdf
Harness Agent Samples
This folder demonstrates create_harness_agent — a factory function that builds a
pre-configured, batteries-included agent by assembling the full agent pipeline
from a chat client.
What is create_harness_agent?
create_harness_agent bundles the following features into a single Agent instance:
| Feature | Description |
|---|---|
| Function invocation | Automatic tool calling loop |
| Per-service-call persistence | History persisted after every model call |
| Compaction | Context-window management (sliding window + tool result compaction) |
| TodoProvider | Todo list management for planning and tracking |
| AgentModeProvider | Plan/execute mode tracking |
| MemoryContextProvider | File-based durable memory (when memory_store provided) |
| SkillsProvider | File-based skill discovery and progressive loading |
| Shell tool | Shell command execution + environment probing (when shell_executor provided) |
| Tool approval | "Don't ask again" standing rules + heuristic auto-approval (enabled by default) |
| Looping | Re-invoke the agent until a loop_should_continue predicate is satisfied (when provided) |
| OpenTelemetry | Built-in observability |
Each feature can be disabled or customized via keyword arguments.
Samples
| File | Description |
|---|---|
harness_research.py |
Interactive research assistant with web search, a plan/execute workflow, and an execute-mode loop that re-invokes the agent until every todo is complete |
harness_data_processing.py |
Data-processing assistant over a folder of CSV files, demonstrating file-access tools and tool approval |
build_your_own_claw/ |
Build your own claw blog series — a personal finance assistant built step by step |
Running
# Set your Foundry environment variables
export FOUNDRY_PROJECT_ENDPOINT="https://your-project.services.ai.azure.com/api/projects/your-project-name"
export FOUNDRY_MODEL="your-model-deployment-name"
# Authenticate with Azure (required for AzureCliCredential)
az login
# Run a sample against the released agent-framework (PEP 723 isolated env)
uv run samples/02-agents/harness/harness_research.py
Running against the local repo
To run a sample against your local agent-framework checkout (so it picks
up uncommitted changes), use the workspace environment instead of the isolated
PEP 723 env. From the python/ directory, run the script with uv run python
and add the textual UI dependency the harness console needs:
uv run --with textual python samples/02-agents/harness/harness_research.py
uv run --with textual python samples/02-agents/harness/harness_data_processing.py
The workspace environment already provides the editable agent-framework
packages plus the samples' other dependencies (rich, python-dotenv);
only textual needs to be supplied with --with.
Note: invoking
uv run python <script>(withpython) bypasses the PEP 723 metadata and uses the workspace env;uv run <script>(withoutpython) uses the isolated env with the released package.
Key Concepts
Minimal Setup
create_harness_agent requires only a chat client:
from agent_framework import create_harness_agent
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential
agent = create_harness_agent(
client=FoundryChatClient(credential=AzureCliCredential()),
)
With Compaction
Provide token budget parameters to enable automatic context-window compaction:
agent = create_harness_agent(
client=FoundryChatClient(credential=AzureCliCredential()),
max_context_window_tokens=128_000,
max_output_tokens=16_384,
)
Further Customization
Disable or customize any feature:
agent = create_harness_agent(
client=client,
max_context_window_tokens=128_000,
max_output_tokens=16_384,
name="my-agent",
agent_instructions="Custom instructions here.",
disable_todo=True, # Skip todo management
disable_mode=True, # Skip plan/execute modes
disable_compaction=True, # Skip compaction
)
Plan/Execute Workflow
The AgentModeProvider enables a two-phase workflow:
- Plan mode — Interactive: the agent asks questions, creates todos, gets approval
- Execute mode — Autonomous: the agent works through todos independently
Shell Tool
Pass a shell executor (e.g. LocalShellTool from agent-framework-tools) to enable shell
command execution plus automatic environment probing via a ShellEnvironmentProvider. The
tool is only wired when the chat client supports shell tools; otherwise a warning is logged
and the shell tool/provider are skipped. The caller owns the executor's lifecycle.
from agent_framework.tools import LocalShellTool, ShellEnvironmentProviderOptions
async with LocalShellTool(acknowledge_unsafe=True) as shell:
agent = create_harness_agent(
client=client,
max_context_window_tokens=128_000,
max_output_tokens=16_384,
shell_executor=shell,
# Optional: customize environment probing.
shell_environment_provider_options=ShellEnvironmentProviderOptions(probe_tools=("git", "python")),
)
Security Considerations
Several harness capabilities extend the agent's trust boundary to external systems the developer configures. Each is opt-in and requires explicit configuration by the developer, who is responsible for vetting the external service, agent, skill source, or provider before enabling it:
background_agents(BackgroundAgentsProvider) — delegates work to developer-supplied agents, which receive input from the parent and whose output is fed back into its context. A compromised agent could exfiltrate data or inject adversarial content via indirect prompt injection. Vet all supplied agents.- External skill sources (
skills_providerwith e.g.MCPSkillsSource) — load skill content, and potentially scripts, from a remote source. A compromised source could return adversarial skills (indirect prompt injection) or exfiltrate data. Only enable sources you trust. AgentLoopMiddleware.with_judge— sends the request and the agent's latest response to a second, external judge chat client on every iteration. A compromised judge could exfiltrate that data or return manipulated feedback. Trust the judge as much as the primary model.SummarizationStrategy(viabefore_compaction_strategy/after_compaction_strategy) — calls out to an LLM whose output permanently becomes chat history. A compromised summarization service could inject unsafe, persistent instructions. Only use a service you trust as much as the primary model.- Auto-approval rules (
FileAccessProvider.read_only_tools_auto_approval_rule/all_tools_auto_approval_rule, and the equivalentSkillsProviderrules, passed toToolApprovalMiddleware) — the built-in rules approve local tools by tool name only (e.g.file_access_read,file_access_ls,file_access_grep). Auto-approval rules may match by name, so any other local tool registered under one of these names — for example the shell tool given a caller-configurable name — may also be auto-approved, bypassing the human approval boundary. Ensure no other tool collides with these reserved names. - Telemetry — when observability is enabled, telemetry destinations are developer-configured. Default telemetry is metadata only; enabling sensitive data additionally emits raw message content, tool arguments, and tool results. See the observability samples.