FieldCure.Ai.Execution
0.4.1
dotnet add package FieldCure.Ai.Execution --version 0.4.1
NuGet\Install-Package FieldCure.Ai.Execution -Version 0.4.1
<PackageReference Include="FieldCure.Ai.Execution" Version="0.4.1" />
<PackageVersion Include="FieldCure.Ai.Execution" Version="0.4.1" />
<PackageReference Include="FieldCure.Ai.Execution" />
paket add FieldCure.Ai.Execution --version 0.4.1
#r "nuget: FieldCure.Ai.Execution, 0.4.1"
#:package FieldCure.Ai.Execution@0.4.1
#addin nuget:?package=FieldCure.Ai.Execution&version=0.4.1
#tool nuget:?package=FieldCure.Ai.Execution&version=0.4.1
FieldCure.Ai.Execution
Agent loop and sub-agent execution engine for autonomous LLM tool-use workflows.
Components
| Class | Description |
|---|---|
IAgentLoop / AgentLoop |
Prompt - model call - tool execution - repeat loop |
ISubAgentExecutor / SubAgentExecutor |
Isolated sub-agent sessions with context propagation |
AgentLoopContext |
Loop input: provider, system prompt, tools, guards |
AgentLoopResult |
Loop output: status, summary, tool call count, Messages (full conversation history for audit trails) |
SubAgentRequest |
Sub-agent task definition with ContextHints |
SubAgentResult |
Sub-agent report, status, duration |
ContextHintKeys |
Well-known keys for context propagation (kb_id, etc.) |
SystemPromptHints |
Converts ContextHints to system prompt fragments |
Quick Start
AgentLoop (standalone)
using FieldCure.Ai.Execution;
using FieldCure.Ai.Providers;
using FieldCure.Ai.Providers.Models;
var loop = new AgentLoop();
var result = await loop.RunAsync(new AgentLoopContext
{
Provider = myProvider, // IAiProvider instance
SystemPrompt = "You are helpful.",
UserPrompt = "Summarize this document.",
Tools = [searchTool, readTool], // IAssistTool list
MaxRounds = 10,
});
Console.WriteLine(result.Summary); // Last assistant message
Console.WriteLine(result.Status); // Completed, Truncated, MaxRoundsReached, Failed
Console.WriteLine(result.Messages); // Full conversation for audit logging
SubAgentExecutor
using FieldCure.Ai.Execution;
using FieldCure.Ai.Execution.Models;
var executor = new SubAgentExecutor(
agentLoop: new AgentLoop(),
resolveProvider: model => ProviderFactory.Create(model),
resolveTools: (servers, allowed, ct) => BootstrapMcpTools(servers, allowed, ct)
);
var result = await executor.ExecuteAsync(new SubAgentRequest
{
Prompt = "Research competitor news and write a report.",
McpServers = ["builtin_essentials"],
AllowedTools = ["http_request"],
MaxRounds = 10,
Timeout = TimeSpan.FromMinutes(2),
ContextHints = new Dictionary<string, string>
{
[ContextHintKeys.KbId] = "my-kb-uuid", // RAG kb_id propagation
},
});
Console.WriteLine(result.Report); // Sub-agent's final report
Console.WriteLine(result.Status); // Completed, Truncated, TimedOut, MaxRoundsReached, Failed
Status values
| Status | AgentLoopStatus |
SubAgentStatus |
Meaning |
|---|---|---|---|
Completed |
✓ | ✓ | Model produced a response with no tool calls. Summary / Report is the final text. |
Truncated |
✓ | ✓ | The terminating response had no tool calls and AiResponse.IsTruncated was set (provider hit max_tokens). The content is partial — do not treat as graceful completion. Callers typically retry with a tighter scope or surface the truncation to the user. |
MaxRoundsReached |
✓ | ✓ | context.MaxRounds reached while the model was still emitting tool calls. |
TimedOut |
— | ✓ | Only SubAgentExecutor enforces a wall-clock timeout (SubAgentRequest.Timeout). AgentLoop itself is timeout-free — cancellation is the caller's responsibility via CancellationToken. |
Failed |
✓ | ✓ | An unhandled exception (other than OperationCanceledException, which propagates). ErrorMessage (loop) / Report (sub-agent) carries the detail. |
Note: when the context guard forces a final summary round (see
MaxContextChars), the terminating response is classified as Completed
even if IsTruncated would otherwise flip it — the guard asked for a
summary on purpose, so the partial marker doesn't apply.
Tool execution order
Within a single round, AgentLoop executes the model's tool_use blocks
sequentially (foreach over response.ToolCalls). Parallel dispatch
of independent tool calls is not a responsibility of this package —
callers that need it (e.g., AssistStudio's ChatPanel for delegate_task
fan-out) implement it at their own level on top of SubAgentExecutor.
Design Principles
- AgentLoop is pure - no timeout, no retry, no MCP. Just CancellationToken.
- Timeout is the caller's responsibility (CancelAfter + catch OperationCanceledException).
- Retry is the caller's responsibility (wrap IAiProvider or handle externally).
- MCP bootstrapping stays in the consumer (Runner, AssistStudio Core).
- ContextHints are resolved by SubAgentExecutor into system prompt text. AgentLoop never sees them.
Dependencies
FieldCure.Ai.Providers(IAiProvider, IAssistTool, AiRequest, AiResponse, ChatMessage)
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- FieldCure.Ai.Providers (>= 0.7.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
v0.4.1: README-only patch. The SubAgentExecutor quick-start sample on nuget.org passed a defaultPresetName argument that was removed in 0.3.0; the page now compiles as written and the lambda parameter name matches the renamed SubAgentRequest.ModelName property. No code, dependency, or behaviour change from 0.4.0.