Files
westey 96d242fa7f .NET: Remove required token params from HarnessAgent, make compaction opt-in (#6409)
* Move token params from HarnessAgent constructor to options

Remove the required maxContextWindowTokens and maxOutputTokens
constructor parameters from HarnessAgent and AsHarnessAgent, replacing
them with optional MaxContextWindowTokens and MaxOutputTokens properties
on HarnessAgentOptions.

When both values are provided, compaction is enabled as before (in-loop
CompactionProvider and chat reducer on the default InMemoryChatHistory
Provider). When either is null, compaction is disabled entirely, making
it opt-in.

New constructor: HarnessAgent(IChatClient, HarnessAgentOptions?,
ILoggerFactory?, IServiceProvider?)

Closes #6333

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

* Improving comments.

* feat: Add custom CompactionStrategy and DisableCompaction to HarnessAgentOptions

Allow users to provide their own CompactionStrategy via options, with
a clear priority system:
1. DisableCompaction=true: no compaction regardless of other settings
2. Custom CompactionStrategy provided: use it (token params ignored)
3. Both MaxContextWindowTokens and MaxOutputTokens set: default strategy
4. Otherwise: no compaction

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

* fix: Address PR review comments on compaction opt-in

- Update chatClient param XML doc to reflect compaction is opt-in
- Strengthen compaction tests to assert ChatReducer is null/not-null
  rather than just asserting construction succeeds

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
96d242fa7f · 2026-06-09 13:06:00 +00:00
History
..

What this sample demonstrates

This sample demonstrates how to use a HarnessAgent with the default FileAccessProvider to give an agent access to a folder of data files for reading, analyzing, and writing results. The HarnessAgent pre-configures function invocation, per-service-call chat history persistence, in-loop compaction, tool approval, and OpenTelemetry — so the sample only needs to supply the chat client, token limits, custom instructions, and opt out of unused features.

Key features showcased:

  • HarnessAgent — a pre-configured agent that wraps a ChatClientAgent with function invocation, per-service-call persistence, and context-window compaction
  • FileAccessProvider — the HarnessAgent's default file access provider uses {cwd}/working as its working directory, matching this sample's working/ folder
  • CSV data processing — the agent reads sales transaction data and performs analysis on demand
  • Output file creation — the agent can write summaries, filtered data, or reports back to the data folder
  • Streaming output — responses are streamed token-by-token for a natural experience
  • No planning mode — this is a simple conversational sample focused on data interaction

Prerequisites

Before running this sample, ensure you have:

  1. An Azure AI Foundry project with a deployed model (e.g., gpt-5.4)
  2. Azure CLI installed and authenticated (az login)

Environment Variables

Set the following environment variables:

# Required: Your Azure AI Foundry OpenAI endpoint
export AZURE_FOUNDRY_OPENAI_ENDPOINT="https://your-project.services.ai.azure.com/openai/v1/"

# Optional: Model deployment name (defaults to gpt-5.4)
export AZURE_AI_MODEL_DEPLOYMENT_NAME="gpt-5.4"

Running the Sample

cd dotnet
dotnet run --project samples/02-agents/Harness/Harness_Step03_DataProcessing

What to Expect

The sample starts an interactive conversation with a data analyst agent. The working/ folder contains a sales.csv file with ~50 rows of sales transaction data (date, product, category, quantity, unit price, region, salesperson).

You can ask the agent to:

  1. List available files — "What files do you have?"
  2. Analyze the data — "What are the total sales by region?" or "Which salesperson has the highest revenue?"
  3. Create output files — "Create a summary report as a markdown file" or "Write a CSV with monthly totals"
  4. Search for patterns — "Find all transactions over $1000"
  5. Type exit — to end the session

E.g. try the following prompt Please process the sales.csv file by first filtering it to only North region sales, and then calculating the sum of sales by person. I'd like to write the results of the processing to north_region_totals.csv.

Sample Data

The included working/sales.csv contains sales transactions from January to March 2025 with the following columns:

Column Description
date Transaction date (YYYY-MM-DD)
product Product name
category Product category (Electronics, Furniture, Stationery)
quantity Units sold
unit_price Price per unit
region Sales region (North, South, West)
salesperson Name of the salesperson