Skip to main content

Current capabilities and detailed workflows

Agentstration is a local-first platform for governing, executing, and tracking work delegated to agents.

Agentstration is organized around three explicit planes:

Agentstration
├── Management Plane
├── Runtime Plane
└── Work Plane
  • Management Plane: configures and governs agents and the Agentstration platform.
  • Runtime Plane: executes and orchestrates agents.
  • Work Plane: receives, represents and tracks work delegated to agents.

The Work Plane is where users and systems delegate work to agents, track its lifecycle, interact with ongoing executions, and retrieve results.

The management plane is the source of truth for agent definitions and desired state; runtime AIAgent instances are reconstructible. The Work Plane owns the functional lifecycle, interactions, history, and result of each WorkItem. Its architectural principle is Microsoft-first, provider-neutral, cloud-optional.

The official static Source registry is available as an optional instance-owned discovery input, and Platform administrators can add independent community or private enterprise registrations. Registrations have ETag-protected CRUD, explicit trust/network/refresh/cache policies, and optional instance Secret references resolved only for exact same-origin requests. Manual and opt-in scheduled refreshes retrieve only compatible Registry v1 shards, validate canonical digests, retain a bounded last-known-good cache, and persist conditional HTTP, backoff, staleness, failure, and recovery state across restart. Registry trust evaluation preserves every observation, gates remote publisher assertions through local policy, rejects accepted digest conflicts and revocation, and feeds the existing exact SourceVersion verification boundary. Merged discovery remains offline; an explicit retained-observation selection retrieves and imports only one exact manifest with complete Registry provenance and no Channel materialization. It never equates a trusted origin or verified SourceVersion with a verified mutable Channel Snapshot or makes startup depend on the public network. See Source registry registrations.

The Console exposes these operations under System > Source registries. It supports registration CRUD, enablement, manual refresh, refresh history, Secret-reference selection, merged discovery filters, all observation evidence, and exact import confirmation. The official registration, local origin policy, publisher evidence, SourceVersion verification, and later Snapshot verification are presented separately on responsive desktop and mobile layouts.

Schedule Triggers​

Agentstration can submit autonomous Work from a declarative Workspace-scoped Trigger. Trigger owns when, Work owns what, Flow owns how, and Runtime owns execution. Automation is not a second runtime.

apiVersion: agentstration.io/v1
kind: Trigger
metadata:
name: morning-summary
definition:
displayName: Morning summary
enabled: false
source:
kind: schedule
schedule:
type: cron
expression: "0 0 8 ? * MON-FRI"
timeZone: Europe/Paris
target:
kind: flow
flow:
name: daily-report
input: {}
misfirePolicy: fireOnce
concurrencyPolicy: skip

V1 supports once, interval and Quartz cron schedules, strict IANA time zones, ETag CRUD, enable/disable, Run now, next/last observed status and durable occurrence history. A Trigger can explicitly target a Flow in any namespace of its Workspace, including an installed Pack namespace; cross-Workspace resolution remains forbidden. Quartz registrations live in the scheduler schema or database of the selected relational storage profile and are reconciled from Trigger resources after restart. A deterministic occurrence/Work identity prevents duplicate local submission for the same scheduled instant. Current owner authorization is re-evaluated at every firing and fails closed after revocation.

The Console exposes a searchable /triggers list, a guided schedule editor with Flow selection, IANA time zones and occurrence preview, plus a detail view for desired state, observed status, occurrence history, enable/disable and Run now. The Management API exposes /api/triggers and namespaced equivalents. A scheduled Work becomes an autonomous Task without a fabricated Entry or Interaction. Human input uses the existing task-scoped PendingAction panel and notification path directly from Task details.

See ADR-0068 for policies, guarantees and V1 limits.

Packs are a Management/distribution concept above these planes: they install ordinary resources into deterministic publisher.name namespaces and retain provenance, but they are never run. Local ZIP installation, source/fork coexistence, installed-Pack inventory, compensating failure handling, modification-safe uninstall, and six resource handlers are implemented through the Management API. See Pack format and lifecycle.

Declarative agent resources​

Agent declaration belongs to the Management Plane. It owns the desired state, generation, provisioning status, resource version, canonical resource identifiers, reference validation, and lifecycle events. The Runtime Plane owns dependency resolution, materialization, lifecycle, and execution. Microsoft Agent Framework is an execution implementation detail confined to the runtime adapter and does not appear in Management resources or events.

The module is physically isolated: agent resources, kind constants, validation and lifecycle use cases live in Agentstration.Agents. Other managed kinds follow the same plural resource-family ownership model; there is no shared Management abstractions assembly. No resource-family service remains in the general Domain or Application projects.

Agents use the Agentstration-native resource envelope in both JSON and YAML:

apiVersion: agentstration.io/v1
kind: Agent
metadata:
name: sql-expert
tags:
domain: database
annotations: {}
definition:
displayName: SQL Expert
description: Specialized agent for database questions.
handler: prompt-agent
instructions: |
Focus on SQL Server.
modelProfile:
name: reasoning-default
tools:
- name: sql-readonly

The server generates an immutable UID; logical identity is (Workspace, Agent, metadata.name). PUT is idempotent and conditional writes use ETags.

Tool Providers and discovery​

The Management Plane persists Agentstration.Tools/toolProviders and the Agentstration.Tools/tools resources materialized by discovery. Tool Providers support AEP and MCP; MCP connections support STDIO and Streamable HTTP using the official SDK. Creation/configuration performs an initial discovery attempt and the Console exposes manual test and refresh operations. Refresh reports new, changed, unchanged, and unavailable counts without deleting disappeared tools or overwriting enablement.

AEP itself is staged as an autonomous repository under aep/, with protocol 2026-09-18, canonical discovery at /.well-known/aep, contribution-scoped Value Requirements with optional typed allowed values, bounded inline/Secret-grant invocation values, versioned capability descriptors, a reusable validator and tracing client, a headless CLI, a generic sample, and a standalone Blazor Inspector. Agentstration uses local project references during extraction and can switch to versioned packages with UseLocalAepProjects=false after publication. Registered AEP extensions can use request-scoped Static Bearer authentication backed by a scope-visible Secret; the value is resolved for every request and expected extension identity is checked centrally before functional calls.

The Tools Console separates Providers and Catalog, displays provider status, schemas, and whether approval is required, and defaults every newly discovered tool to disabled. The Agent editor assigns canonical Tool resource IDs and warns when an existing assignment is unavailable. Runtime resolution requires provider enabled, tool enabled, tool available, and assignment before creating an Agentstration-owned MAF function adapter. MAF never receives the native invocable MCP Tool: every effective call crosses the provider-neutral Agentstration Tool Execution Pipeline, then the MCP invoker performs tools/call. Tools governed with requiresApproval wrap the Agentstration adapter in MAF ApprovalRequiredAIFunction, so approval pauses remain ordinary durable Flow input requests and the resumed invocation still crosses the pipeline.

When the AppHost Utilities extension is available, standalone sample data includes demo-interactive-input version 1.3.0. The Flow console initializes its Run dialog from the resource's agentstration.io/sample-input metadata, so this sample starts with a reproducible payload value. Its first agent calls the real hash_compute MCP tool through AEP, waits for explicit approval, then resumes from the persisted MAF checkpoint and continues to the next agent. No demonstration orchestration engine is involved.

Work, Flow, Run, and Agent​

Published Workplace Entries always target an immutable Flow version. The Console may present Agent or Flow as an authoring convenience; an Agent selection is normalized at publication through a hidden system-managed Direct Agent Flow. Consequently every submitted Entry follows Entry -> FlowReference -> FlowRun -> Runtime.

Every Entry remains owned and executed by exactly one Workspace. Its versioned exposure policy independently selects Workplace and Console presentation; Workplace further distinguishes the owning space from explicit Tenant-home promotion. Existing Entries default to Workplace in their owning space. GET /api/entries accepts surface and placement filters, searches only Workspaces the caller may read, and returns the owning Workspace ID with every result. Exposure never makes sibling Workspace resources visible, and invocation still selects the Entry owner's Workspace before resolving its pinned Flow.

Console-targeted discovery additionally projects whether the exact pinned Flow is executable, disabled, or unavailable, with stable reason codes for localization. Draft-only and unauthorized Entries are omitted. The typed Console client invokes an eligible Entry through its owner-Workspace route with surface=Console, and submission rechecks the same readiness decision. The independent Console host now owns its opaque interactive session and will use this contract once downstream delegation is available; discovery does not weaken or bypass the BFF trust boundary.

Console-exposed Entries may declare the Fallback Console role. When search has no authorized page, command, or resource match, Console offers every executable fallback Entry as an explicit choice carrying its owner Workspace and the exact typed query. No execution starts until the user selects an action; an absent, non-executable, or unauthorized fallback retains the ordinary empty result.

Work = what needs to be accomplished
Flow = how the work is routed and processed
Run = a concrete execution
Agent = a participant in the execution
WorkItem
│ handled by
▼
FlowDefinition
│ instantiated as
▼
FlowRun
│ executed by
▼
Runtime
│ mobilizes
▼
Agents

The Flow module manages editable graph drafts, immutable published versions, and durable Flow Runs. The designer adds one generic Flow call card that selects a namespaced published Flow by active or exact version, maps its input schema, exposes its output schema, and blocks missing targets, incompatible mappings, and dependency cycles at publication. Durable child-Flow execution is not yet available. The local sequential executor supports typed Input, Agent, Router, Condition, Transform, Output, and Failure steps through provider-neutral contracts. The earlier Direct, Routing, Workflow, Orchestration, and Composite specifications remain compatible with the same Flow resource and storage boundary. Orchestration Runs can suspend durably for text, choice, or confirmation input, survive process reconstruction through opaque SQLite-backed MAF checkpoints, and resume with the exact Flow snapshot and Agent revisions selected at first execution.

The standalone vertical uses SQLite for management resources and runs without Azure, Foundry, a remote model, or an API key. It seeds dotnet-expert and sql-expert, compiles immutable revisions, deploys them in-process, reconciles their runtime state, routes each request to one agent, and executes that agent through Microsoft Agent Framework.

Prerequisites​

  • .NET SDK 10.0.300 or later feature band
  • Optional: a local Ollama installation for the managed Ollama profile
  • Optional: a local llama-server and GGUF model for the llamacpp provider

No Azure subscription or remote API key is required.

Run locally​

The most direct route is:

dotnet run --project src/Agentstration.Web

Open the Console at http://localhost:5100. The same process hosts the Management, Runtime, Flow, Work, Workplace, generic MCP, and SignalR surfaces. Module-owned SQLite databases and file artifacts live under src/Agentstration.Web/.agentstration by default.

The end-user Workplace remains an autonomous UI host. Start the authoritative server and UI in separate terminals:

$env:AI__Provider = "Deterministic"
dotnet run --project src/Agentstration.Web
dotnet run --project src/Agentstration.Workplace.Web

Open http://localhost:5180; its API defaults to http://localhost:5100. The responsive UX uses the same design system and visual language as the Console while retaining end-user vocabulary. See the Workplace guide.

The Console Tasks section at /tasks supervises the real WorkTasks exposed by Work API. It uses server-side pagination and SignalR updates, remains readable when Workplace is stopped, and never substitutes fictitious Tasks when Work API is unavailable.

The same process now hosts the Blazor operations console in Interactive Server mode. Agent and model management always use the canonical persisted HTTP APIs; unrelated dashboard projections remain simulated by default so every operational section is immediately explorable. See the Web console guide for API client, authentication, rendering, and UI component configuration.

Workspace administrators with both resources/delete and runs/delete can use the Console cleanup screen at /cleanup to review and select terminal Runtime/Flow Runs, Entries, Flows, and Agents. Cleanup deliberately composes the canonical unitary DELETE APIs in dependency order (Runs, Entries, Flows, then Agents), retains failed selections, and reports partial completion without rolling successful deletions back. Entry cleanup can also remove Dashboard references and close active interactions when those explicit options are selected.

Local ASP.NET Core Identity accounts, OIDC/JWT authentication, stable Principals, Workspace-scoped RBAC, Platform administrator lifecycle, external identity links, durable security audit, and the corresponding administration Console are implemented. See the identity and authorization reference for exact modes, routes, policies, persistence, tests, and deferred surfaces.

For the Aspire dashboard and orchestration experience:

dotnet run --project src/Agentstration.AppHost

The AppHost exposes the authoritative server, Workplace, and autonomous extensions as separate resources and wires them through service discovery. It connects the Ollama extension to Ollama:Endpoint (default http://localhost:11434), the llama.cpp extension to LlamaCpp:Endpoint (default http://localhost:8080), and the LocalAI extension to LocalAI:Endpoint (default http://localhost:8081). It provisions no inference server or model. Aspire preserves the server's normal Managed mode; deterministic execution remains an explicit offline/test override.

Or with one provider-specific AEP container topology, for example Ollama:

docker compose -f deploy/compose/ollama.yml up --build

AI modes​

The normal Managed mode resolves the provider, extension registration, endpoint, and model from the persisted Model Profile and Model Provider selected on each agent. It is the default for direct Web and Aspire launches; concrete provider names are never host execution modes. The seeded ollama-local, llama-cpp-local, and localai-local providers reference extension registrations whose URLs are AEP endpoints, never native inference-server URLs.

The Model Provider inventory links every retained observation to a responsive Model detail page. Creating a provider from the Console persists the declaration and immediately attempts initial model discovery; failure leaves the declaration available for correction or retry. Provider details expose an explicit refresh action with created, updated, unchanged, missing, reappeared, and total counts. The Model detail overview presents provider identity, reconciliation freshness, modalities, feature support, known limits and explicit observed-versus-effective provenance. The secondary YAML tab copies the deterministic canonical persisted Model resource; computed effective values are deliberately not written into that document. Missing and failed observations remain readable, and these GET-driven views never trigger provider discovery.

Use the deterministic offline mode explicitly for tests or fallback diagnostics:

$env:AI__Provider = "Deterministic"
dotnet run --project src/Agentstration.Web

Before using the managed Ollama profile, ensure the local server and selected model are available:

ollama pull qwen3:1.7b
$env:Ollama__Endpoint = "http://localhost:11434"
dotnet run --project src/Agentstration.AppHost

The seeded reasoning-default profile resolves to the persisted ollama-local AEP contribution and its qwen3:1.7b model. Aspire injects the autonomous Ollama extension endpoint and passes Ollama:Endpoint to that extension. To target a non-default local address, set Ollama__Endpoint before starting the AppHost. Direct startup of the extension defaults to http://localhost:11434, while Agentstration’s persisted AEP endpoint defaults to http://localhost:5260. The persisted AEP endpoint can be edited without restarting the host and is authoritative for subsequent runtime resolution.

For llama.cpp, start llama-server with a stable alias and point Aspire at it before creating a Model Profile that references llama-cpp-local:

llama-server -m C:\models\model.gguf --alias local-gguf --port 8080 --jinja
$env:LlamaCpp__Endpoint = "http://localhost:8080"
dotnet run --project src/Agentstration.AppHost

For LocalAI, expose an existing server on host port 8081 and create a Model Profile that references one of the chat models returned by its capability endpoint:

$env:LocalAI__Endpoint = "http://localhost:8081"
# Optional: $env:LocalAI__ApiKey = "..."
dotnet run --project src/Agentstration.AppHost

See Model providers for declarations, capabilities, native options, and limitations.

The Agent Runner uses this resolver through Microsoft Agent Framework, so no Ollama-specific execution path exists in the Runtime Plane. Create a normal durable Runtime Run to exercise the entire declared-agent path:

$agentId = "sql-expert"
$body = @{
agent = @{ resourceId = $agentId; version = 1 }
input = @{ messages = @(@{ role = "User"; content = "Quelle est la différence entre WHERE et HAVING ?" }) }
execution = @{ mode = "Interactive"; timeoutSeconds = 120 }
origin = "Api"
} | ConvertTo-Json -Depth 8
Invoke-RestMethod -Method Post -ContentType application/json -Body $body http://localhost:5100/api/runtime/runs

The returned Run is processed asynchronously and exposes status.modelProvider, status.resolvedModel, and the final response when complete. In Development, the smaller connectivity diagnostic remains available:

$body = @{ prompt = "Reply with one short sentence." } | ConvertTo-Json
Invoke-RestMethod -Method Post -ContentType application/json -Body $body http://localhost:5100/api/diagnostics/models/ollama/chat

Agentstration.Models.Application owns persisted profile definitions and projects them into the provider-neutral resolver. Agentstration.ModelProviders reaches provider contributions only through AEP. Autonomous Ollama, llama.cpp, and LocalAI extensions own their native transports, while Agentstration.AppHost owns orchestration. Runtime.AgentFramework consumes IChatClient; it has no dependency on a concrete provider.

Current limitations are deliberate: credentials are not stored on provider resources, llama.cpp reasoning output is not represented as a distinct AEP content kind, and image input is not yet effective through the AEP-to-IChatClient adapter. Separate Flow Runs are not dispatched in parallel and there is no conversation persistence. Other legacy OpenAI-compatible endpoints still use host-level AI__Endpoint, AI__Model, and optional AI__ApiKey settings.

Model provider and profile APIs​

Model providers are durable Management Plane resources with CRUD, ETag concurrency, usage visibility, deletion protection, connectivity testing, and explicit model discovery. Discovery reconciles governed provider-owned Model resources; GET requests read the retained inventory without contacting the provider. A provider can retain bounded per-model specificationOverrides keyed by exact external model identifier. Provider inventory and Model Profile resolution expose observed, override, and effective model specifications separately. The effective model capability level is intersected with provider, adapter, and runtime support, so an override cannot elevate explicit unsupported support or bypass Tool governance. Model Profile resolution exposes those capability levels and profile-option incompatibilities before execution. Runtime and agent-tool compatibility remains an execution-resolution concern. Aspire starts the AEP extensions and supplies their initial seed URLs, but relies on configured local inference servers and remains outside the provider source of truth:

Invoke-RestMethod http://localhost:5100/api/modelproviders
Invoke-RestMethod http://localhost:5100/api/modelproviders/ollama-local/status
Invoke-RestMethod http://localhost:5100/api/modelproviders/ollama-local/models
Invoke-RestMethod -Method Post http://localhost:5100/api/modelproviders/ollama-local/models/refresh
Invoke-RestMethod http://localhost:5100/api/models
Invoke-RestMethod -Method Post http://localhost:5100/api/modelproviders/ollama-local/test
Invoke-RestMethod http://localhost:5100/api/modelproviders/ollama-local/usages
Invoke-RestMethod http://localhost:5100/api/modelproviders/llama-cpp-local/status
Invoke-RestMethod http://localhost:5100/api/modelproviders/llama-cpp-local/models
Invoke-RestMethod http://localhost:5100/api/modelproviders/localai-local/status
Invoke-RestMethod http://localhost:5100/api/modelproviders/localai-local/models

Create or edit Ollama, llama.cpp, and LocalAI extension registrations from the Blazor console at /extensions, then bind their model-provider contributions at /modelproviders. Extension URLs must be absolute HTTP(S) AEP endpoints without embedded credentials, query strings, or fragments. Console creation attempts discovery after the provider is durably saved, while the detail page can refresh it later. The native inference server therefore does not have to be online to retain the provider declaration; a failed initial attempt is surfaced as a warning. LocalAI discovery requires /v1/models/capabilities and filters non-chat models. Deleting a provider is rejected while a model profile references its exact resource ID.

Model profiles are durable Management Plane resources with ETag concurrency and usage protection:

Invoke-RestMethod http://localhost:5100/api/modelprofiles
Invoke-RestMethod http://localhost:5100/api/modelprofiles/reasoning-default/resolution
Invoke-RestMethod http://localhost:5100/api/modelprofiles/reasoning-default/usages
Invoke-RestMethod http://localhost:5100/api/agents/sql-expert/model

Model profiles separate portable generation, reasoning, and output intent from provider-keyed providerOptions. V1 has no legacy options shape: reset/reseed the local control-plane database after upgrading from an earlier development snapshot. Runtime behavior is represented independently by RuntimeProfileResource; streaming is an execution/runtime option, not a model-profile property. The MAF adapter maps these canonical values to ChatOptions and normalized Agentstration execution events, while the Ollama adapter owns think, keepAlive, engine options, and the chat-versus-generate compatibility check.

The seeded reasoning-default profile references the stable ollama-local provider resource and qwen3:1.7b. Profiles remain valid when Ollama or a selected model is temporarily unavailable; only structurally invalid profiles are rejected. An in-use profile cannot be deleted. Agent definitions continue to persist only the model-profile resource ID.

The Blazor console exposes this vertical through /modelproviders, /modelprofiles, /runtimeprofiles, the agent editor, and the Agent Runner. Provider pages create and edit declarations, test connectivity, show dynamic models and usages, and enforce ETag/deletion protection. Model profile pages edit all canonical inference categories; runtime profile pages manage session, tool invocation, streaming, and runtime-specific options with ETag conflict and usage protection. Each active Workspace receives the maf-builtin Microsoft Agent Framework Runtime Profile automatically. Resources shipped with Agentstration use the -builtin suffix and the agentstration.io/builtin: "true" provenance annotation; this identifies their origin without making them implicit defaults. The runner shows the resolved runtime profile and lets an advanced run choose its streaming mode. The reusable agent picker saves only modelProfile.resourceId; agent details render the declared profile separately from the resolved provider and model.

REST quickstart​

Management plane​

After startup, inspect a seeded deployment:

$base = "http://localhost:5100/api"
Invoke-RestMethod "$base/deployments/sql-expert"

Route a request to exactly one ready agent and execute it:

$body = @{ input = "How can I optimize this SQL query?" } | ConvertTo-Json
Invoke-RestMethod -Method Post -ContentType application/json -Body $body "$base/routing/invoke"

Management endpoints support ETag, If-Match, If-None-Match, Problem Details, pagination, and 202 Accepted for deployment actions. SQLite data is stored in .agentstration/control-plane.db by default.

Runtime runs​

The Agent Runner and Runtime API create durable executions without creating Work Items:

$runBody = @{
agent = @{ resourceId = "sql-expert"; version = 1 }
input = @{ messages = @(@{ role = "User"; content = "Analyze this SQL query." }) }
execution = @{ mode = "Interactive"; timeoutSeconds = 120 }
origin = "Api"
} | ConvertTo-Json -Depth 8
$run = Invoke-RestMethod -Method Post -ContentType application/json -Body $runBody http://localhost:5100/api/runtime/runs
Invoke-RestMethod "http://localhost:5100/api/runtime/runs/$($run.id)"

Run history and ordered events are stored independently in .agentstration/runtime-plane.db. The console exposes Quick Run, advanced context/parameters, SSE progress, cancellation, retry, trace and raw inspection from each agent page.

Agent management and Agent Runner always call the canonical Management and Runtime APIs, even when the remaining console dashboard uses simulated projections. Saving an agent activates its current generation; Reconcile runtime retries that idempotent activation manually. A successful replacement is made ready before superseded instances are deprovisioned. A Run resolves the current persisted Model Profile, invokes the deployment model through Microsoft Agent Framework and the selected provider, and records the provider, model, temperature, and maximum output tokens actually used. Advanced overrides accept only temperature and maxOutputTokens; provider, endpoint, and model overrides are rejected.

Work plane​

Submit work through the canonical Work Plane API:

$body = @{ type = "question"; title = "SQL review"; instruction = "How can I optimize this SQL query?" } | ConvertTo-Json
$work = Invoke-RestMethod -Method Post -ContentType application/json -Body $body "http://localhost:5100/api/work/workitems"
Invoke-RestMethod "http://localhost:5100/api/work/workitems/$($work.id)"
Invoke-RestMethod "http://localhost:5100/api/work/workitems/$($work.id)/result"

The local adapter queues the request, executes it through the existing Runtime Plane, and applies stable execution events to the persisted WorkItem. Work data is stored independently in .agentstration/work-plane.db.

Flow definitions​

Create and publish a Direct Flow:

$flow = @{
name = "sql-direct"
description = "Sends SQL work to the SQL expert"
kind = "Direct"
version = "1.0.0"
enabled = $true
definition = @{ flowKind = "direct"; target = @{ kind = "Agent"; id = "sql-expert" } }
} | ConvertTo-Json -Depth 8
Invoke-RestMethod -Method Post -ContentType application/json -Body $flow "http://localhost:5100/api/flows"
Invoke-RestMethod -Method Post -ContentType application/json -Body (@{ version="1.0.0"; activate=$true } | ConvertTo-Json) "http://localhost:5100/api/flows/sql-direct/versions"

Flow definitions are stored in .agentstration/flow-plane.db. Published versions are immutable; a WorkItem may carry a lightweight exact or active FlowReference without embedding the definition.

The Flow console at /flows provides creation templates, a four-zone visual designer, Designer/Definition/Split modes, YAML source editing, validation, optimistic draft saving, publication, published versions and per-Flow Runs. The specialized UI lives in the Agentstration.Web.FlowDesigner Razor Class Library: Z.Blazor.Diagrams owns canvas interaction and BlazorMonaco provides the locally served Monaco editor, while Agentstration.Web supplies backend and resource adapters. A Draft Run validates its JSON input and retains its exact draft revision, hash, and immutable definition snapshot. Run details receive differential SignalR events with replay from persisted history; /flow-runs provides the global searchable Run history. Flow data remains in the independent .agentstration/flow-plane.db store.

MCP​

The official C# MCP SDK exposes Streamable HTTP at http://localhost:5100/mcp. Example VS Code .vscode/mcp.json:

{
"servers": {
"agentstration": {
"type": "http",
"url": "http://localhost:5100/mcp"
}
}
}

The authenticated server dynamically publishes enabled Workspace Tool Definitions and bounded internal Tools through tools/list. Built-in Tools cross the ordinary governance and audit pipeline, while Flow-backed Tool Definitions use the durable root Flow submission boundary and return operation receipts. The endpoint does not expose generic Management CRUD or an unrestricted Flow launcher. Governed external MCP and AEP tool providers continue to be discovered and executed through the Tool catalog rather than being republished automatically.

Runtime and MAF observability​

GenAI observability is enabled by default without capturing prompts or responses. A Runtime Run produces correlated OpenTelemetry spans for the Runtime lifecycle, the Microsoft Agent Framework invocation, the effective IChatClient request, and the outbound HTTP call. Structured Runtime logs carry the same Run and agent correlation scope.

Run through Aspire to inspect traces, metrics, and logs in the local dashboard:

dotnet run --project src/Agentstration.AppHost

For a direct Web launch, set OTEL_EXPORTER_OTLP_ENDPOINT to any OTLP-compatible collector. Disable GenAI instrumentation, without affecting normal execution, with:

{
"Observability": {
"GenAI": {
"Enabled": false
}
}
}

Prompt, response, function argument, function result, credential, and authorization-header capture is intentionally unavailable in the default logging pipeline. Runtime inputs and outputs remain inspectable through the Runtime Run API and console rather than being duplicated into operational telemetry.

For local troubleshooting only, Development can capture the final JSON body sent by the legacy OpenAI-compatible transport and by the AEP model-provider client. The AEP request capture shows the exact messages, including the system message produced from agent instructions, immediately before the request leaves Agentstration. The out-of-process extension does not capture its provider-native request by default:

{
"Observability": {
"GenAI": {
"HttpPayloadCapture": {
"Enabled": true,
"MaximumBodyLength": 16384,
"CaptureResponse": false
}
}
}
}

The capture creates a correlated gen_ai.http.payload_capture span between the GenAI chat span and the network POST, and also emits structured payload logs. It removes URI query strings, never records HTTP headers, recursively redacts common JSON credential fields, and truncates the captured value. The application refuses to start with this option outside Development. Capturing responses is disabled by default because it buffers the complete response and therefore changes streaming behavior. These spans and logs are exported through OTLP when an exporter is configured, so the collector and its retention policy must be treated as containing sensitive data. In an AEP deployment this proves what Agentstration sent to the extension; inspecting the extension-to-model native payload still requires provider-side diagnostics.

Quality gates​

dotnet build Agentstration.slnx --configuration Release
dotnet test --solution Agentstration.slnx --configuration Release --minimum-expected-tests 1

Warnings are errors, .NET analyzers are enabled, and NuGet audit findings fail restore. The test suite covers Management, Work, Workplace, Flow, Runtime, Triggers, Packs, Agents, workspace isolation, MCP infrastructure, REST startup, and dependency rules.

Current boundaries​

This is a product foundation, not a production multi-tenant release. Pack dependency resolution, updates, signatures and Gallery access, parallel Flow scheduling, loops, arbitrary graph waits, HumanApproval nodes, subflows, semantic/LLM routing, durable distributed Work dispatch, authorization coverage outside the first Management/identity vertical, external-only identity provisioning, external artifact storage, general retry policies, provider-level tool idempotency, revision traffic splitting, dedicated process/container hosting, Foundry bindings, and runtime session storage remain planned. Interactive orchestration recovery is implemented for the standalone SQLite/MAF path; it provides at-least-once execution and does not claim exactly-once external effects.

See architecture, decisions, security, and contributing.