UAIX / AI Memory / Handoff
Executive Summary
Report summary
We propose a .NET library (e.g. UAIX.UAI ) that implements the UAIX UAI-1 message spec and supports UAIX “AI memory” components. The library would define C classes or interfaces mirroring the UAI-1 envelope (version, profile, message ID, source/target, conversation, delivery, trust, provenance, inte
Key topics
- UAIX / AI Memory / Handoff
- UAIX
- AI Memory
- Handoff
- AI
- UAI
- Agentic Web
- .NET
- C#
Research provenance
For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.
This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.
Full report
On this page
We propose a .NET library (e.g. UAIX.UAI) that implements the UAIX UAI-1 message spec and supports UAIX “AI memory” components. The library would define C# classes or interfaces mirroring the UAI-1 envelope (version, profile, message ID, source/target, conversation, delivery, trust, provenance, integrity, etc.)【30†L155-L163】. We recommend an SDK‐style, multi‐targeted project (e.g. net8.0 plus netstandard2.0 for broad compatibility【25†L92-L100】) with a clear namespace (e.g. UAIX.UAI.*). The public API might include a UaiMessage class, profile-specific message subtypes, and an IMemoryStore interface for memory semantics. NuGet metadata (PackageId like “UAIX.UAI”, Version in SemVer format【43†L155-L160】, authors, description, repository URL, tags, license, etc.) should be specified in the project file.
Building and deployment would use standard .NET tools: dotnet build, dotnet pack (including symbols) and a CI workflow. We provide a sample GitHub Actions YAML that restores, builds, packs, and pushes the package using the NUGET_API_KEY. We also recommend signing the package and generating a .snupkg symbol package【33†L64-L69】【35†L81-L89】. For testing, use unit tests (e.g. xUnit) for individual components and integration tests for cross-cutting flows【37†L52-L60】【37†L62-L70】.
The library should include “memory package” support as a separate component or project. We define a simple IAgentMemory interface and give an example InMemoryAgentMemory implementation (storing memories in a list or file). This can be packaged as a second NuGet (e.g. UAIX.UAI.Memory) or as part of the main package, depending on design choices. We compare monolithic vs. modular packaging in the table below. All package design will follow Microsoft’s best practices for NuGet authoring, semantic versioning, and CI/CD.
Key sources: UAIX UAI-1 schemas and docs (for message fields and profiles)【30†L155-L163】, and Microsoft’s NuGet authoring docs on package IDs, SemVer, symbols, and signing【28†L138-L147】【43†L155-L160】【33†L64-L69】【35†L81-L89】.
UAIX UAI-1 Spec: Mapping to .NET Types
The UAIX UAI-1 message is a JSON envelope containing fields for identity, workflow, trust, provenance, etc.【30†L155-L163】. For example, it has identity fields (uai_version, profile, message_id, source, target), workflow (conversation, delivery, etc.), trust (channel, auth_scheme, principal, etc.), and audit (provenance, integrity, extensions)【30†L155-L163】. In .NET, each of these can map to classes or structs. For instance:
public class UaiMessage
{
[JsonPropertyName("uai_version")]
public string UaiVersion { get; set; } // e.g. "1.0"
[JsonPropertyName("profile")]
public string Profile { get; set; }
[JsonPropertyName("message_id")]
public string MessageId { get; set; }
[JsonPropertyName("source")]
public Participant Source { get; set; }
[JsonPropertyName("target")]
public Participant Target { get; set; }
[JsonPropertyName("conversation")]
public ConversationInfo Conversation { get; set; }
[JsonPropertyName("delivery")]
public DeliveryInfo Delivery { get; set; }
[JsonPropertyName("trust")]
public TrustInfo Trust { get; set; }
[JsonPropertyName("body")]
public object Body { get; set; } // profile-specific payload
[JsonPropertyName("provenance")]
public ProvenanceInfo Provenance { get; set; }
[JsonPropertyName("integrity")]
public IntegrityInfo Integrity { get; set; }
[JsonPropertyName("extensions")]
public List<object> Extensions { get; set; }
}
Here Participant, ConversationInfo, etc., are helper classes for the nested fields (e.g. Source may have type, id, uri). The Body property can be object or a generic type; one could define subclasses for known profiles (like IntentRequestBody). System.Text.Json or Newtonsoft.Json can serialize/deserialize these with attributes or naming policies. Validation of messages against UAIX JSON schemas would happen outside or via a separate validator tool, but our types should align with the schema definitions【30†L155-L163】.
Project Structure and API Design
We recommend an SDK-style .NET class library, with a root namespace like UAIX.UAI. A possible structure:
- UAIX.UAI.Core (namespace UAIX.UAI) – contains the shared types (envelope, transport, trust, base classes).
- UAIX.UAI.Profiles – optional project or namespace for specific message profiles (e.g.
IntentRequest,TaskStatusbody types). - UAIX.UAI.Memory (namespace UAIX.UAI.Memory) – contains memory-related types (see below). This could be a separate project/package if large or optional.
Use one project or solution with multiple projects. Ensure public API is clear: e.g. UaiMessage, Participant, DeliveryMode enum, etc., and public interfaces like an IUaiSerializer or IUaiClient for helper functionality if needed. For example, an IUaiMessageSender might be an interface for sending UAI messages over HTTP.
Sample interface:
public interface IAgentMemory
{
Task AddMemoryAsync(MemoryEntry entry);
Task<IEnumerable<MemoryEntry>> SearchMemoryAsync(string query);
}
This abstractly represents storing and querying memory (discussed below).
Target Frameworks and Dependencies
Target .NET 8.0 (or latest LTS) for full features, and consider multi-targeting netstandard2.0 if .NET Framework compatibility or broad support is needed【25†L92-L100】. For instance:
<TargetFrameworks>net8.0;netstandard2.0</TargetFrameworks>
Core dependencies will be minimal: e.g. System.Text.Json for JSON, and any logging or DI libraries if desired (e.g. Microsoft.Extensions.Logging.Abstractions for logging hooks). Avoid heavy dependencies; prefer no dependencies beyond the base SDK unless needed. If UAIX validator or registry services have HTTP APIs, you might depend on System.Net.Http or RestSharp, but these are optional.
For a memory package, you might depend on additional libraries (e.g. Vector databases, file I/O, or in-memory cache). But keep the core UAI package lean.
Semantic Versioning and Version Strategy
Use Semantic Versioning (SemVer) for the NuGet package【43†L155-L160】. This means version numbers like Major.Minor.Patch, with optional pre-release suffixes (e.g. 1.0.0-alpha). Increase:
- Major for breaking changes to the API or UAIX profile implementation,
- Minor for new features that are backwards-compatible,
- Patch for bug fixes.
E.g. start at 1.0.0. For development, you might use pre-release versions (1.0.0-preview.1). Follow Microsoft guidance: pre-release packages if non-stable【43†L155-L160】. Align the assembly version and package version if practical.
NuGet Metadata and .csproj Example
Use an SDK-style project file with <PropertyGroup> metadata. Key properties: PackageId, Version, Authors, Description, RepositoryUrl, PackageTags, License, etc. For example:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;netstandard2.0</TargetFrameworks>
<PackageId>UAIX.UAI</PackageId>
<Version>1.0.0</Version>
<Authors>UAIX Open Standards</Authors>
<Company>UAIX</Company>
<Description>Library for UAIX UAI-1 message format and AI memory</Description>
<PackageTags>UAIX UAI AI memory JSON interoperable</PackageTags>
<PackageProjectUrl>https://github.com/uaixorg/uaix-dotnet</PackageProjectUrl>
<RepositoryUrl>https://github.com/uaixorg/uaix-dotnet</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Authors>UAIX Contributors</Authors>
<PackageReleaseNotes>Initial release of UAIX UAI.NET SDK</PackageReleaseNotes>
<!-- Enable symbol package generation -->
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<!-- JSON library -->
<PackageReference Include="System.Text.Json" Version="8.0.0" />
</ItemGroup>
</Project>
This ensures NuGet picks up metadata from the csproj【28†L77-L86】. We set IncludeSymbols and SymbolPackageFormat to generate a .snupkg symbol package【33†L64-L69】. The PackageId follows a namespace-like convention【28†L138-L147】. Adjust values (version, authors, URLs) for your project.
If needed, a legacy .nuspec file can be used, but the SDK-style csproj is preferred for modern .NET. Always include a README and license in the package per best practices【43†L173-L181】【43†L258-L262】.
Build & CI/CD Pipeline
Local build: Use dotnet build and dotnet pack. For example:
dotnet restore
dotnet build -c Release
dotnet pack -c Release
This creates the .nupkg (and .snupkg) in bin/Release.
CI (GitHub Actions example):
name: Build and Publish
on:
push:
branches: [main]
tags: ['v*'] # on version tags
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
- name: Restore
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal
- name: Pack
run: dotnet pack --configuration Release --no-build --include-symbols --output nupkgs
- name: Publish to NuGet
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
run: dotnet nuget push nupkgs/*.nupkg --api-key $NUGET_API_KEY --source https://api.nuget.org/v3/index.json --skip-duplicate
In this workflow, we restore, build, test, pack (producing both .nupkg and .snupkg), and push to nuget.org. The NUGET_API_KEY (from GitHub Secrets) is used for authentication. This follows common patterns (see GitHub docs) and ensures artifacts are versioned and pushed on new tags.
For Azure Pipelines, similar steps can be used (e.g. using NuGetToolInstaller, dotnet pack and dotnet nuget push tasks). The key is automating package creation on each release and keeping a record.
Signing and Symbol Packages
For trust, sign your NuGet package with a code-signing certificate【35†L81-L89】. For example, use dotnet nuget sign:
dotnet nuget sign MyPackage.nupkg --certificate-path /path/to/cert.pfx --timestamper https://timestamp.url
This embeds a digital signature in the .nupkg. Before publishing, register the signing certificate on nuget.org so the signature will be accepted【35†L108-L117】. Also push the symbol package: with our csproj settings, dotnet pack generated a .snupkg. You can push it along with the main package:
dotnet nuget push MyPackage.nupkg --api-key <key> --source https://api.nuget.org/v3/index.json
dotnet nuget push MyPackage.snupkg --api-key <key> --source https://api.nuget.org/v3/index.json
NuGet.org’s symbol server will index the symbols【33†L64-L69】. Signed packages improve security and authenticity. Ensure you keep the certificate secure and include a timestamp (so signatures remain valid after expiry)【35†L96-L104】.
Testing Strategy
Follow .NET testing best practices. Create a unit test project (xUnit or NUnit) alongside your code. Unit tests should isolate individual classes/methods (e.g. test JSON serialization of UaiMessage, or business logic in memory classes) and avoid external dependencies【37†L52-L60】. For example, mock any file or network calls.
Use integration tests for end-to-end flows, such as serializing a real UAI message, running it through the validator, or storing/retrieving memory from a database【37†L62-L70】. Integration tests may involve real file I/O or HTTP calls (but in a test environment). Automate tests with dotnet test. The CI above includes a Test step. Cover key behaviors: parsing UAI JSON, enforcing required fields, memory queries, etc. Using Microsoft’s guidance, separate unit vs integration as above【37†L52-L60】【37†L62-L70】.
For memory packages, test the persistence (e.g. writing/reading file or querying memory). If you depend on UAIX’s validator service or schemas, include tests that validate your messages against the public schemas. This ensures the .NET implementation truly matches the spec.
AI Memory Components
UAIX “AI Memory” is the concept of storing and retrieving contextual data for agents. We assume memory entries are structured records (e.g. facts or events) that can be added and searched. For example, one could define:
public record MemoryEntry(string Id, string Content, DateTime Timestamp);
public interface IAgentMemory
{
Task AddAsync(MemoryEntry entry);
Task<IEnumerable<MemoryEntry>> QueryAsync(string keyword);
}
A concrete in-memory implementation:
public class InMemoryAgentMemory : IAgentMemory
{
private readonly List<MemoryEntry> _entries = new();
public Task AddAsync(MemoryEntry entry)
{
_entries.Add(entry);
return Task.CompletedTask;
}
public Task<IEnumerable<MemoryEntry>> QueryAsync(string keyword)
{
var result = _entries.Where(e => e.Content.Contains(keyword, StringComparison.OrdinalIgnoreCase));
return Task.FromResult(result);
}
}
This InMemoryAgentMemory simply holds entries in a list. A memory package might be this class (in UAIX.UAI.Memory project) plus utilities to save/load (e.g. to JSON file or database). For example, a file-based memory:
public class FileAgentMemory : IAgentMemory
{
private readonly string _filePath;
public FileAgentMemory(string filePath) { _filePath = filePath; }
public async Task AddAsync(MemoryEntry entry)
{
var list = await ReadFileAsync();
list.Add(entry);
await File.WriteAllTextAsync(_filePath, JsonSerializer.Serialize(list));
}
public async Task<IEnumerable<MemoryEntry>> QueryAsync(string keyword)
{
var list = await ReadFileAsync();
return list.Where(e => e.Content.Contains(keyword, StringComparison.OrdinalIgnoreCase));
}
private async Task<List<MemoryEntry>> ReadFileAsync()
{
if (!File.Exists(_filePath)) return new List<MemoryEntry>();
var text = await File.ReadAllTextAsync(_filePath);
return JsonSerializer.Deserialize<List<MemoryEntry>>(text) ?? new List<MemoryEntry>();
}
}
These examples illustrate one memory design. The actual semantics (semantic vs episodic memory, multi-user, wiki integration) would affect the model. We assume a simple keyword search memory. The memory package should itself be versioned and published (e.g. UAIX.UAI.Memory 1.0.0) alongside the core package, unless you choose to keep it internal.
flowchart LR
Agent["AI Agent or Client"] -->|sends UAI JSON| Bridge["UAIX .NET Bridge\n(UaiMessage Parser)"]
Bridge --> Processor["Message Processor / Handler"]
Processor --> MemoryStore["AI Memory Store\n(implements IAgentMemory)"]
Processor --> External["External Services (APIs/LLM)"]
MemoryStore --> Storage[(Database or File)]
Processor --> Response["UAI Response"]
This diagram shows an agent sending a UAI message, which the .NET library parses and processes, potentially using a memory store component, and then produces a response. The memory components (e.g. InMemoryAgentMemory or FileAgentMemory) interact with storage.
Single vs. Modular Packaging
Multiple approaches exist:
Pros: Simpler for users (one install, one version); less overhead managing multiple versions. Cons: Larger assembly with everything (memory, validators, profiles) even if some users don’t need parts; harder to isolate changes; merges unrelated concerns.
- Single Monolithic Package (all in one
UAIX.UAI):
Pros: Smaller focused packages; users pick what they need; independent versioning; clearer API boundaries. Cons: More NuGet artifacts to manage; potential for versioning mismatches; slightly more complex dependency graph.
- Modular Packages (e.g.
UAIX.UAI.Core,UAIX.UAI.Memory,UAIX.UAI.Profiles):
- Profile-specific vs. Shared Package: Another axis is splitting per UAIX profile (e.g. an
IntentRequestpackage) or not. Usually profile types can live in core assembly since they share envelope fields.
Below is a comparison summary:
| Approach | Description | Pros | Cons |
|---|---|---|---|
| Single Package | One NuGet containing all UAIX features (core + memory + profiles) | Easy for users; single version to manage; cohesive. | Large assembly; unnecessary code for some users; harder to evolve parts independently. |
| Modular Packages | Split into core, memory, etc. packages | Smaller, focused libraries; optional dependencies; independent releases. | More complex to manage; consumers must add multiple packages; version alignment needed. |
| Mixed (Core+Plugins) | Core with interfaces, plus separate plugin packages (e.g. Memory plugin) | Flexibility to extend without core changes; users pick plugins. | Requires plugin discovery or DI; more setup by user. |
For UAIX, a reasonable approach is to put the shared envelope and common types in a core package (e.g. UAIX.UAI.Core) and optional components (memory store, validation helpers) in separate packages. This keeps the core light and lets specialized implementations evolve on their own.
CI Diagram (Sample Flowchart)
flowchart TD
CodeRepo["GitHub Repo"] --> CI["GitHub Actions CI"]
CI --> Restore["dotnet restore"]
CI --> Build["dotnet build"]
CI --> Test["dotnet test"]
CI --> Pack["dotnet pack"]
Pack --> PublishNuGet["dotnet nuget push (nuget.org)"]
This flowchart outlines the CI process: on code push/tag, the GitHub Actions pipeline restores packages, builds the solution, runs tests, packs the NuGet, and then publishes it to nuget.org.
Publishing Steps to nuget.org
Finally, to publish: create an account on nuget.org and obtain an API key. Locally or in CI, run:
dotnet nuget push UAIX.UAI.1.0.0.nupkg --api-key <API_KEY> --source https://api.nuget.org/v3/index.json
(And similarly push the .snupkg symbol package.) Secure the API key (use GitHub Secrets or Azure Pipelines secure variables) and do not hard-code it. After push, the package will appear on nuget.org (typically within minutes). Use release notes or GitHub tags to document what changed.
Ensure the NuGet account has any needed verification (like a valid email) and that any signing certificates are registered on your account【35†L110-L119】. Once published, others can install via dotnet add package UAIX.UAI --version 1.0.0.
In summary, by following UAIX specifications for message structures【30†L155-L163】 and Microsoft’s guidance on .NET packaging【28†L138-L147】【43†L155-L160】【33†L64-L69】【35†L81-L89】, you can create a robust, well-versioned, and interoperable .NET library (or set of libraries) that provides all core UAI-1 functionality and memory support. This library would streamline building .NET AI services that adhere to the UAIX standard, with full transparency and trust as envisioned by the UAIX interoperability charter.