e-naxosMAF COURSE / COURS
Français

MICROSOFT AGENT FRAMEWORK · 0.16.0-rc.1

Demo340 — Loop Control

Native ChatClientAgent, without HarnessAgent, using the same Maf.Control. Default returns RepeatedCall and code 2 after one admitted attempt. This current entry has no naive/protected menu or unbounded loop.

Objectives

Prepare the demo

Start at the root of the complete distribution built in Release; retain shared projects and files copied beside executables. Scripted transport or heuristic by default: no model, embeddings, secret or container required. --live explicitly selects common chat without cloud fallback.

dotnet build BaseTechnique.slnx -m:1 -c Release
Required projects
ProjectRole
demos/Demo340_LoopControl/Demo340.App.csprojApp
shared/Maf.Control/Maf.Control.csprojShared implementation

Run from the root

dotnet run --project demos/Demo340_LoopControl/Demo340.App.csproj -c Release --no-build

Procedures and variants

Run without arguments to repeat read_ticket(42). Compare complete then changing. Read Middleware separately from ToolCall events.

public AIFunction CreateTool<T>(string name, string capability,
    Func<T, CancellationToken, Task<string>> body)
{
    return AIFunctionFactory.Create(async (T input, CancellationToken cancellationToken) =>
    {
        using var linked = CancellationTokenSource.CreateLinkedTokenSource(Token, cancellationToken);
        linked.Token.ThrowIfCancellationRequested();
        lock (sync)
        {
            CheckCancellation();
            if (!capabilities.Contains(capability)) Halt("PermissionDenied", name, tools);
            if (tools >= Limits.ToolCalls) Halt("ToolBudget", name, tools);
            var key = name + ":" + Canonical(JsonSerializer.SerializeToElement(input));
            var count = repetitions.GetValueOrDefault(key);
            if (count >= Limits.Repetitions) Halt("RepeatedCall", name, count);
            repetitions[key] = count + 1;
            events.Add(new("ToolCall", name, ++tools));
        }
        var result = await body(input, linked.Token);
        CheckCancellation();
        return result;

shared/Maf.Control/ExecutionScope.cs · L75–L95 · 9a895c94534c

Source code · Maf.Control · Folder

dotnet run --project demos/Demo340_LoopControl/Demo340.App.csproj -c Release --no-build -- complete
dotnet run --project demos/Demo340_LoopControl/Demo340.App.csproj -c Release --no-build -- repeat
dotnet run --project demos/Demo340_LoopControl/Demo340.App.csproj -c Release --no-build -- forbidden
dotnet run --project demos/Demo340_LoopControl/Demo340.App.csproj -c Release --no-build -- budget
dotnet run --project demos/Demo340_LoopControl/Demo340.App.csproj -c Release --no-build -- changing
dotnet run --project demos/Demo340_LoopControl/Demo340.App.csproj -c Release --no-build -- deadline
dotnet run --project demos/Demo340_LoopControl/Demo340.App.csproj -c Release --no-build -- incomplete

Results, refusal and evidence

Native ChatClientAgent, without HarnessAgent, using the same Maf.Control. Default returns RepeatedCall and code 2 after one admitted attempt. This current entry has no naive/protected menu or unbounded loop.

Control limits

Scripted results verify actual orchestration and controls without qualifying a model or every attack. Counters are run-local; no durable idempotency or business write. Cancellation remains cooperative.

dotnet test tests/Maf.Control.Tests/Maf.Control.Tests.csproj -m:1 -c Release --no-build --no-restore

Connect contracts and prerequisites

Prerequisites

Continue reading

Complete demo folder · README

lot010-controls-1 · 2026-10-24 · 9a895c94534cd5fc6f3da883e37e5f7856e588c1