Architecture overview
IntentSharp is a .NET 8, 9 and 10 library that applies a natural-language intent to a value and returns a typed,
verified result from OpenAI, Anthropic or any Microsoft.Extensions.AI IChatClient. Everything goes through
one instance class, IntentClient. Two optional packages sit on top of it: IntentSharp.Catalog keeps
intents as data in files, and IntentSharp.Extensions.AI connects the client to Microsoft.Extensions.AI and
Agent Framework.
Packages
| Package (folder) | Depends on | Responsibility |
|---|---|---|
IntentSharp (src/IntentSharp) |
a few Microsoft.Extensions.* packages, System.Text.Json, Microsoft.Data.Sqlite |
The client, the pipeline, the built-in providers and everything in the component map below. |
IntentSharp.Catalog (src/IntentSharp.Catalog) |
IntentSharp, JsonSchema.Net, YamlDotNet |
Behaviour as data: intent definitions in JSON or YAML files, hot reload, declarative rules, runtime-defined shapes, audit tags. See intent-catalog.md. |
IntentSharp.Extensions.AI (src/IntentSharp.Extensions.AI) |
IntentSharp, IntentSharp.Catalog, Microsoft.Extensions.AI.Abstractions |
ChatClientProvider, an IAIProvider over any IChatClient, and catalog intents as AIFunction tools. See extensions-ai.md. |
The core package never references the other two.
Component map
Folder (under src/IntentSharp) |
Responsibility |
|---|---|
IntentClient.cs |
The pipeline. Owns providers, options, memory, cache, rate limiter and judge. Includes the runtime-shape overload TransformAsync(input, intent, JsonNode outputSchema) and AsAmbient(). |
IntentClientScope.cs |
IntentClientScope: makes a client ambient for one async flow (AsyncLocal). There is no process-wide default. |
IntentClientBuilder.cs, DependencyInjection/ |
Construction: fluent builder and services.AddIntentSharp(...). |
IntentClientOptions.cs |
Client-wide IntentClientOptions, per-request AIRequestOptions (including Examples and OutputSchema), IntentExample, JudgeMode. |
Prompting/ |
PromptBuilder (plan and request, including the examples section), InputSerializer (input to text), JsonSchemaBuilder (strict schemas, generated from a type or wrapped around a runtime schema). |
Intent/ |
IntentLint (advisory warnings) and IntentTemplates (ready-made intent phrasings). |
Verification/ |
DeterministicVerifier and the optional ModelJudge. |
Results/ |
AIResult<T>, ResultIssue, IssueSource, AttemptRecord. |
Providers/ |
IAIProvider, HttpProviderBase, OpenAIProvider, AnthropicProvider, exception types. |
Extensions/ |
AIExtensions: scalar helpers and collection transforms. AmbientAIExtensions: the same operations without the client parameter, using the ambient client. |
Data/ |
SemanticDatabase, SqlSafetyChecker, schema discovery. |
Memory/ |
ISemanticMemory with in-process and SQLite implementations. |
Resilience/ |
IRequestCache and IRateLimiter with default implementations. |
Attributes/ |
[AIIntent] and [AIGuardrail] for ExecuteIntentAsync. |
Licensing/ |
Signed license keys (LicenseKeyCodec, LicenseVerifier), trusted public keys and ReleaseInfo, LicenseEnforcer (states, version gate, hourly reminder), LicenseException, LicenseInfo constants. See licensing.md. |
Testing/ |
ScriptedProvider, an in-process provider for tests. |
The request pipeline in one picture
caller: client.TransformAsync<T>(input, intent, options)
(AIExtensions, AmbientAIExtensions, IntentRuntime, the JsonNode
runtime-shape overload, SemanticDatabase and ExecuteIntentAsync all end here)
|
v
PromptBuilder.Plan ----> IntentLint.Check (warnings only)
|
v
+-- attempt loop (MaxAttempts, MaxModelCalls, Timeout) -----------------+
| PromptBuilder.Build (adds previous output + findings on retries) |
| IRequestCache (first attempt only) |
| IRateLimiter.AcquireAsync |
| IAIProvider.CompleteAsync --transient error or timeout--> fallback |
| (OpenAIProvider, AnthropicProvider, ChatClientProvider, your own) |
| DeterministicVerifier.Verify<T> |
| IResultJudge.JudgeAsync (only when JudgeMode allows) |
| passed? return : feed issues into the next attempt |
+-----------------------------------------------------------------------+
|
v
RecordAsync -> ISemanticMemory -> AIResult<T> (Success, Value, Issues, Attempts, Usage)
How the pieces fit
The caller supplies an intent string, an input value and a target type T. PromptBuilder serializes the
input into the prompt and states an output contract. For any T other than string, the model must answer
with a JSON envelope {"value": ...}, backed by a strict JSON schema when the type allows one.
Each response is checked by DeterministicVerifier without calling a model. If it fails, the concrete
findings are sent back to the model on the next attempt. A model-as-judge step can run after deterministic
checks pass. The final result is an AIResult<T> that records every attempt and every issue. There is no
confidence score.
Higher-level features are thin layers over TransformAsync<T>. Collection transforms add validators and
exchange indices with the model. SemanticDatabase asks for a QueryPlan, runs it through
SqlSafetyChecker, and only then touches the database.
A result shape can also be a JSON schema supplied at run time instead of a .NET type:
TransformAsync(input, intent, JsonNode outputSchema) sends the schema strict and enveloped and returns an
AIResult<JsonNode>. IntentRuntime in IntentSharp.Catalog is one more thin layer: it reads a named
intent definition from a file-backed catalog on every call, turns it into AIRequestOptions (examples, rules
as validators, guardrails, audit tags) and calls TransformAsync with the shape the file declares.
ChatClientProvider in IntentSharp.Extensions.AI is one more IAIProvider, so the whole pipeline runs
unchanged on any IChatClient.
client.AsAmbient() makes a client ambient for one async flow, so value.AIAsync<T>("intent") works
without passing it. Outside a scope there is no client to find, and those calls throw with guidance.
Read next
- request-pipeline.md for each step with file and method names.
- verification.md for what makes a result succeed or fail.
- intent-catalog.md for behaviour as data.
- extensions-ai.md for Microsoft.Extensions.AI and Agent Framework.
- public-api.md for every public type.