Plenipo.Testing
0.1.0-alpha.29
dotnet add package Plenipo.Testing --version 0.1.0-alpha.29
NuGet\Install-Package Plenipo.Testing -Version 0.1.0-alpha.29
<PackageReference Include="Plenipo.Testing" Version="0.1.0-alpha.29" />
<PackageVersion Include="Plenipo.Testing" Version="0.1.0-alpha.29" />
<PackageReference Include="Plenipo.Testing" />
paket add Plenipo.Testing --version 0.1.0-alpha.29
#r "nuget: Plenipo.Testing, 0.1.0-alpha.29"
#:package Plenipo.Testing@0.1.0-alpha.29
#addin nuget:?package=Plenipo.Testing&version=0.1.0-alpha.29&prerelease
#tool nuget:?package=Plenipo.Testing&version=0.1.0-alpha.29&prerelease
Plenipo
A base platform for building AI-first, chat-first applications across many industries on the .NET + React stack. Plenipo ships as a family of NuGet packages (backend) and npm libraries (frontend); a product is a thin host that installs modules, not a fork of the platform.
Out of the box you get: a chat-first dashboard, a pluggable module system for domain verticals, tool-level security for the agent (the model never sees a tool the user may not call), full audit logging, token-usage monitoring, multi-tenancy, an admin/RBAC/security dashboard, and the IaC + CI/CD to ship it. It unifies the patterns proven in two earlier apps — NutriForge (nutrition) and the-ledger (personal finance) — so a new vertical is a module, not a new codebase.
New here? GETTING_STARTED.md gets you from clone to a running chat with three demo verticals and the admin dashboard in three steps — no AI key required. ARCHITECTURE.md explains how it all fits together (with diagrams). docs/CONFIGURATION.md is the single answer to "how is this configured, by whom, and where do secrets (API keys) go" — including the
plenipo initwizard. docs/TESTING.md is how the base platform itself is run and tested. docs/TESTING_CONTRACT.md is the fleet testing contract — what every product must implement and run, and what the platform owes it so a release cannot break a product unseen. docs/GITHUB_SETUP.md is how to set up the GitHub side of a repo built on this base — branch protection, merge gates, labels, the board, secrets, and which skill runs each step.
Core ideas
| Idea | How Plenipo does it |
|---|---|
| Base, not fork | The platform is 6 NuGet packages + npm libraries (the shared contract @plenipo/client, the domain shell @plenipo/ui, the native shell @plenipo/mobile, the admin console @plenipo/admin-ui). Your product references them and adds modules. |
| Web and native, one manifest | The end-user domain UI (@plenipo/ui, branded per product), the mobile app (@plenipo/mobile), and the generic admin console (@plenipo/admin-ui, served at /admin) are separate surfaces over the same server-driven manifest — so operator administration is consistent everywhere, the product UI stays adaptable, and a new module reaches phones without an app release. |
| Chat-first | Every module gets an agent; the dashboard front page is chat (over SignalR or the open AG-UI protocol). A WhatsApp channel (Meta Cloud API) routes phone messages through the same authorized runner — see docs/WHATSAPP_CHANNEL.md. |
| Modules, not forks | A vertical implements IModule: a manifest of tools + tabs, its own services and endpoints. The host discovers and loads them. |
| Verticals are separate systems | Each vertical ships as its own product — own host, own repo, own deployment, own database — installing only its module(s) on the platform packages (see samples/Plenipo.Legal.Host for the shape). A business that wants only finance runs only Plenipo-for-finance. Systems connect through the plenipo-peer connector: one deployment's agent asks another's over the open AG-UI protocol, with the peer enforcing its own auth, RBAC, and audit. Plenipo.Sample.Host bundles three modules purely as a dev showcase. |
| Manifest-first | A module declares its tools, tabs, permissions, and agent instructions statically, before any of its code runs. |
| Tool security before the model call | The agent runner filters tools by the caller's permissions before building the request — the LLM never sees the schema of a tool the user may not call. |
| Agent guardrails | Tenant admins can run prompt-attack, harmful-content, and sensitive-data controls in audit or enforcement mode across user input, tool calls, tool responses, and final output. See docs/AGENT_SECURITY.md. |
| Documents built in | Every module's agent gets platform document tools — read PDFs (PdfPig, Apache-2.0), generate PDFs, list files, pluggable OCR — over a tenant-scoped file store with chat attachments in the UI. See docs/DOCUMENT_TOOLS.md. |
| Knowledge search (opt-in RAG) | Documents index into scoped collections (per matter/project, or curated libraries built in Admin → Knowledge); search_knowledge retrieves hybrid (pgvector + full-text, RRF), reranked (MMR by default, optional LLM cross-encoder) so repeated boilerplate can't crowd out the answer, with per-passage citations down to the page (p. 7) for paginated sources. Narrowed at three levels, each failing closed: the agent's collection scope, the owning module's collection gate, and per-chunk principal trimming. Language-aware (per-document stemming, not English-only) and facet-filterable (jurisdiction=ES), which is what lets one design serve any domain and any country. Keyless in dev via a deterministic Mock embedder. See docs/PLATFORM_CONNECTORS_RAG_PLAN.md. |
| Agent composition (profiles + skills + MCP) | Tenant admins compose chatbots Foundry/Copilot-Studio-style without code: agent profiles set a module agent's instructions and which tools it may use (selection only narrows RBAC); skills (SKILL.md bundles) ship with the host; MCP servers configured by the operator (Mcp:Servers) surface external tools through the same spine — RBAC-gated (tools.mcp.*, granted to no role by default), audited, approval-gated by default. |
| Connectors | A manifest-first connector SDK bridges agents to where tenant data already lives (Azure Blob ships; a keyless local-folder connector powers dev/CI). Default-off per tenant — an admin enables each on the console's Integrations page; secrets are write-only and protected at rest; fetches are approval-gated and land in the file store. |
| Audit everything | Every tool invocation, data change, and token spend is written to a separate, append-only audit database. |
| Multi-tenant by default | Row-level isolation via EF Core global query filters on TenantId — impossible to forget. |
| Provider-swappable AI | OpenAI / Azure OpenAI / Anthropic (Claude) / Ollama via one config section — plus a dependency-free Mock provider so the chatbot (and even real, audited tool calls + the approval gate) work with zero setup. Tenants can switch the whole connection at runtime from the admin UI (BYO key, vaulted write-only). |
Built on .NET 10, Microsoft Agent Framework (MAF) over Microsoft.Extensions.AI, EF Core 10 (+ Npgsql), .NET Aspire, and React 18 + Vite.
The security spine — every chat turn
The agent never gets more power than the user who asked:
flowchart LR
U(["Your message"]) --> R["Authorized<br/>agent runner"]
R -->|"only the tools<br/>your role may call"| L(["LLM"])
L -->|"tool call"| D{"writes data?"}
D -->|"no"| X["run + audit"]
D -->|"yes"| H["held for<br/>your approval"]
H -->|"approve"| X
X --> A(["answer"])
So the LLM never sees a tool you can't call, every invocation is audited, and anything side-effecting waits for a human — by construction, not by prompt.
Solution layout
The platform (Plenipo.slnx) and the example apps (samples/Plenipo.Samples.slnx) are separate
solutions — the platform never depends on a sample.
Plenipo.slnx # the base platform (publishable)
└── src/
├── Plenipo.Core/ # Domain primitives: entities, multi-tenancy, results, identity
├── Plenipo.Modules.Sdk/ # IModule, ModuleManifest, ToolDescriptor, TabDescriptor, ModuleTool
├── Plenipo.Application/ # Contracts: RBAC, auditing, agents, conversations, token usage, AI options
├── Plenipo.Infrastructure/ # EF Core, audit interceptor, RBAC, AI providers (+ Mock), the agent runner
├── Plenipo.AspNetCore/ # Host integration: auth, middleware, SignalR + Redis, AG-UI, platform/chat/admin endpoints
├── Plenipo.ServiceDefaults/ # Aspire: OpenTelemetry, health checks, resilience
├── Plenipo.Testing/ # Conformance kit: the host fixture, AG-UI parser, eval runner, spine/manifest/tenancy invariants
├── Plenipo.Api/ # Minimal runnable host — a thin shell with NO domain modules
└── Plenipo.AppHost/ # Aspire orchestration for the bare platform
tests/ # Plenipo.Application.Tests, Plenipo.Infrastructure.Tests
samples/Plenipo.Samples.slnx # example apps built ON the platform (NuGet in prod; ProjectReference for dev)
├── Plenipo.Modules.Finance/ # the-ledger vertical — stateful, learns categories from corrections
├── Plenipo.Modules.Nutrition/ # NutriForge vertical — food catalog + persisted food diary
├── Plenipo.Modules.Legal/ # the-lawyer vertical — matters, docketing, time, clause library, drafting
├── Plenipo.Sample.Host/ # runnable host wiring all three modules
└── Plenipo.Sample.AppHost/ # Aspire orchestration for the sample (Postgres ×2, Redis, mock chat)
frontend/plenipo-client/ # @plenipo/client — renderer-free contract: manifest types, REST, AG-UI, RBAC mirror
frontend/plenipo-ui/ # @plenipo/ui — React + Vite library: the end-user (domain) chat shell + server-driven tabs
frontend/plenipo-mobile/ # @plenipo/mobile — React Native shell: the same manifest, rendered natively
frontend/mobile-app/ # the reference Expo app — the template a product copies and rebrands
frontend/admin-ui/ # @plenipo/admin-ui — the admin console app (security/RBAC/users/usage/audit), served at /admin
infra/ # Terraform (azurerm): Container Apps, Postgres, Redis, Key Vault, Entra External ID
.claude/skills/run-plenipo/ # skill: run Aspire, read logs/telemetry, run the UI, test the chatbot
.github/workflows/ # CI/CD: build + scan, deploy (OIDC), terraform PR checks
Layered RBAC
- System roles —
system_admin,tenant_admin,user,guest. What each role grants is a per-tenant, runtime-editable baseline (seeded from built-in defaults), configured from the admin console — no code change to retune a role.system_adminis fixed at the global wildcard (a lockout guardrail) and not editable. - Feature permissions — dotted, hierarchical strings (
tools.finance.categorize_transaction,platform.users.manage). Wildcards (tools.finance.*) and the*global grant are honoured. - Per-resource ACLs — owner/editor/viewer (the seam exists; module-specific).
Bring your own IdP — or none at all. Authentication is OIDC either way. Set the Auth section
(Authority + Audience) and Plenipo validates that IdP's JWTs (Entra External ID, Keycloak,
Authentik — anything compliant). Or set Auth:Mode=Local and the host is its own OIDC issuer:
a built-in login page, users and passwords managed in the admin console, optional TOTP — zero
external identity setup, which is what an on-prem or mini-PC install wants
(docs/CONFIGURATION.md → "Built-in sign-in", ADR 0003). The X-Dev-* dev scheme isn't even
registered once either is configured (and is Development-only regardless). For
deployments that want the IdP to own authorization too, set "Auth": { "PermissionSource": "Token" }:
roles then come exclusively from the token (Entra app roles / B2C claims), internal role
assignments and per-user grants are ignored, JIT provisioning never invents a default role, and the
admin endpoints that would edit internal assignments answer 409 with guidance. The tenant's
role → permission baselines stay in force — they're what translate an IdP role name into Plenipo's
fine-grained tool permissions, which no IdP knows about.
Endpoints gate on permissions with RequireAuthorization(PermissionRequirement.PolicyName("…"));
policies are materialised on demand by a custom IAuthorizationPolicyProvider. The admin console
(@plenipo/admin-ui, a separate app served at /admin) exposes the full permission map (every module
tool + the permission it requires), a schema-driven role editor (toggle what each role grants, with
every permission derived from the live catalog so new modules appear automatically), per-user role/grant
management, the token-usage report, and the agent audit log. It reads the /api/admin/* endpoints, which
stay RBAC-gated server-side.
Running locally
Prerequisites: .NET 10 SDK, Docker (for the Postgres/Redis containers Aspire starts), Node 20+
with pnpm (the frontend is a pnpm workspace — run corepack enable once so pnpm is on your PATH).
# Full demo: Postgres (platform + audit DBs) + Redis + the sample API with Finance, Nutrition, and Legal.
# The chat assistant works immediately via the dependency-free "Mock" provider — no API key needed.
dotnet run --project samples/Plenipo.Sample.AppHost
The platform's own AppHost (
src/Plenipo.AppHost) runs the barePlenipo.Api, which installs no domain modules — useful for platform development, but chat there has nothing to talk to. Run the sample AppHost above for a working, module-loaded demo.
In Development with no identity provider configured, the API uses a dev-auth fallback: requests are
authenticated from optional X-Dev-* headers (defaulting to a system_admin dev user in the seeded
dev tenant), so the whole platform is exercisable without standing up Entra External ID.
To use a commercial model, start the host and configure the tenant's provider, live-discovered model, and write-only API key under Admin → AI Settings. Deployment configuration carries no chat-provider API key. Azure managed identity and local Ollama remain keyless deployment options.
# Frontend — two apps, each a Vite dev server pointed at the API (VITE_API_BASE, default http://localhost:8080).
cd frontend
pnpm install
pnpm dev # @plenipo/ui — the end-user domain shell, on http://localhost:5173
pnpm dev:admin # @plenipo/admin-ui — the admin console, on http://localhost:5174/admin
The admin console is a separate surface from the domain UI. In an integrated host it is served at /admin
by the API itself (app.UsePlenipoAdminConsole()): build it (pnpm build:admin) and copy its dist/ into
the host's wwwroot/admin. When the assets aren't present the call is a no-op, so the API still runs.
For the full run / observe / test workflow (Aspire, the Aspire MCP for logs/telemetry, exercising the
chatbot and admin features), see the run-plenipo skill in .claude/skills/.
Key endpoints
| Endpoint | Purpose |
|---|---|
GET /api/platform/modules |
Modules + tabs the caller can see (drives the dashboard navigation) |
GET /api/platform/me |
Current user, tenant, and effective permissions |
POST /api/chat/stream |
Streamed agent turn (HTTP) |
POST /api/agui/{moduleId} |
Streamed agent turn over the open AG-UI protocol (SSE) |
/hubs/agent (SignalR, method Stream) |
Streamed agent turn (WebSocket) |
GET /api/admin/security/catalog |
The permission map: platform perms + every module tool |
GET /api/admin/users, …/roles, …/usage, …/audit/tool-calls |
RBAC management, token usage, audit log |
POST /api/files, GET /api/files/{id}, GET /api/files/mine |
Tenant-scoped file store (chat attachments; local disk or Azure Blob — see docs/DOCUMENT_TOOLS.md) |
GET/POST /api/channels/whatsapp/webhook |
WhatsApp channel (Meta Cloud API webhook; HMAC-verified, off by default — see docs/WHATSAPP_CHANNEL.md) |
GET /api/finance/transactions, /api/legal/clauses, /api/nutrition/foods |
Sample-module endpoints |
GET /health, /alive |
Aspire health / liveness (never call the LLM) |
The full request catalog — every endpoint above plus the complete admin surface (roles, users,
per-tenant modules, tenants, audit/usage), conversation management, approvals, and the sample modules — is
committed as plenipo.http: open it in VS Code (REST Client) or a JetBrains IDE and run any
request against a locally-running instance (it uses the dev-auth headers, so no token setup).
Adding a module
Building a whole product (own repo, own brand)? BUILDING_A_PRODUCT.md catalogs every host seam.
New here? BUILDING_A_MODULE.md walks you through building a complete module from
scratch (the worked example lives in samples/Plenipo.Modules.Tasks).
The short version:
- New class library, reference the
Plenipo.Modules.Sdkpackage (+Application,Coreas needed). - Implement
IModule: aModuleManifest(tools, tabs, roles, agent instructions),RegisterServices,MapEndpoints. - Implement
IModuleToolSourceto supply the executableModuleTools (eachAIFunctionbound to a permission). - Register it in the host:
builder.AddPlenipoModule<YourModule>();.
The dashboard picks up the new tabs automatically; the agent gains the new tools (each gated by permission).
A module may own persistence (its own DbContext + schema, migrated via IModule.MigrateAsync) or be
stateless — Finance (a ledger), Nutrition (a food diary under the nutrition schema), and Legal (matters,
deadlines, tasks, time, and the firm's clause library under the legal schema) are all stateful; the
Tasks tutorial module shows the minimal stateful shape.
Consuming Plenipo as NuGet packages
Plenipo ships as a family of NuGet packages, so a product lives in its own repo and depends on the platform instead of forking it. The packable libraries:
| Package | What it gives you |
|---|---|
Plenipo.Core |
Domain primitives (entities, multi-tenancy, results) |
Plenipo.Modules.Sdk |
IModule, ModuleManifest, ToolDescriptor — implement these to build a module |
Plenipo.Application |
RBAC, agent abstractions, permission matching |
Plenipo.Infrastructure |
EF Core multi-tenant persistence, audit, AI providers, the agent runner |
Plenipo.AspNetCore |
Auth, endpoints, SignalR + Redis backplane, AddPlenipoModule<T>() |
Plenipo.ServiceDefaults |
Aspire defaults (OpenTelemetry, health checks) |
Published feed: every GitHub Release publishes these packages to the repo's GitHub Packages NuGet feed
(see .github/workflows/publish.yml), so a downstream product adds that feed
once and dotnet add package Plenipo.* — no local pack required.
Local feed (for development before a release): build the whole family to a folder, then consume it:
dotnet pack Plenipo.slnx -c Release -o ./localfeed
<configuration>
<packageSources>
<add key="plenipo-local" value="../localfeed" />
</packageSources>
</configuration>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Plenipo.Modules.Sdk" Version="0.1.0-alpha" />
</ItemGroup>
Implement IModule, then in your API host (referencing Plenipo.AspNetCore) call
builder.AddPlenipoModule<YourModule>(). A complete, runnable example host with three modules lives in
samples/Plenipo.Sample.Host.
This exact pack-and-consume path is verified on every CI run: eng/verify-packaging.sh
packs the platform and builds a throwaway module project against the produced packages, so a broken pack or
bad package metadata fails the build instead of reaching you.
Frontend: three surfaces over one contract
The frontend is split so the product UI stays adaptable while operator administration stays consistent across every Plenipo deployment — and so the same manifest can be rendered on a phone.
Underneath them all sits @plenipo/client (frontend/plenipo-client) — the renderer-free
contract: the TypeScript mirror of every C# descriptor (ModuleManifest, TabDescriptor,
TabEditor, TabChart, …), the REST surface, the AG-UI chat transport, the PermissionMatcher
mirror, form defaults, and chart shaping. No React, no DOM, no bundler globals — checked by a test
that reads the sources. A change to the C# side lands in one TypeScript file and every shell sees it.
@plenipo/ui(frontend/plenipo-ui) — the end-user / domain shell, an npm library (Vite library mode, ESM + UMD, with bundled TypeScript declarations). It exports the batteries-includedPlenipoApp(and the lower-levelAppShell), a client-side module registry (defineModule— register your own React pages per module tab, with a server-driven generic fallback), the chat shell, RBAC primitives (usePermission,PermissionGate), typed API errors (ApiError), the API/AG-UI/SignalR clients (api,useMe, hooks, types), and theming + branding (a--plenipo-brand-*CSS-variable accent, abrandingprop for the product name/logo, and dark mode — a persisted light/dark/systemThemeToggleships in both app headers). A product brands and composes it; the base library carries no vertical-specific and no admin code.@plenipo/admin-ui(frontend/admin-ui) — the admin console, a standalone app (not a library) that owns the administration views: Roles (with the live permission map in-page), Users, Modules, Integrations, Tenants, AI Settings, Agent Profiles, Token Usage, Audit Log, and Operations. It reuses@plenipo/ui's client layer for API access and is served at/admin(by its own Vite dev server, or by the API host viaapp.UsePlenipoAdminConsole()). This is the platform's analogue of OpenClaw's "control UI built into the gateway": every host gets a generic security/RBAC/usage/audit console for free, independent of its domain UI.@plenipo/mobile(frontend/plenipo-mobile) — the native end-user shell (React Native / Expo), the same server-driven idea rendered with native views. It builds its tab bar, lists, editor forms, charts, detail views and chat from the same/api/platform/modulespayload, so installing a backend module puts it on phones that already have the build — a backend deploy, not an App Store review. A product's app is a base URL plus a brand (frontend/mobile-appis the ~30-line template), with the samedefineModuleregistry for native screens where the generic renderer isn't enough. Chat rides the AG-UI SSE endpoint (a WebSocket doesn't survive a phone's backgrounding) and push arrives through the ordinaryINotificationChannelseam, which makes a phone the fastest way to clear the human-in-the-loop approval queue. See docs/MOBILE.md.
Mount the whole domain shell with PlenipoApp (it wires a React Query client + router), registering your
host's React pages for each module's tabs — anything you don't register falls back to the server-driven view:
import { createRoot } from "react-dom/client";
import { PlenipoApp, defineModule } from "@plenipo/ui";
import "@plenipo/ui/theme.css"; // brand accent defaults — override --plenipo-brand-* to rebrand
import { TransactionsBoard } from "./finance";
const finance = defineModule("finance", { tabs: { transactions: TransactionsBoard } });
createRoot(document.getElementById("root")!).render(
<PlenipoApp
moduleUi={[finance]}
branding={{ name: "Acme Ops", logo: <img src="/acme.svg" alt="Acme" className="h-7" /> }}
/>,
);
Point it at your API with VITE_API_BASE (defaults to http://localhost:8080). Rebrand by overriding the
--plenipo-brand-* CSS variables (include @plenipo/ui/tailwind-preset if you run your own Tailwind) and
setting the product name/logo via branding. Inside a tab component you get the platform's RBAC primitives
(usePermission, PermissionGate) and typed API errors (ApiError). Hosts that own their router and query
client can compose the lower-level AppShell instead. This public surface is type-checked against the
published package on every CI run (see eng/verify-frontend-packaging.sh).
Status & next steps
Built and verified: module SDK, 3-layer RBAC with pre-model-call tool filtering, dual-database audit,
MAF agent runner with OpenTelemetry tracing, token-usage tracking + per-conversation budgets,
human-in-the-loop approval for side-effecting tools, AG-UI + SignalR chat (with a zero-config Mock
provider that performs real, audited tool calls and triggers the approval gate — so the security pipeline
is demonstrable with no API key), a WhatsApp channel (Meta Cloud API webhook, HMAC-verified, JIT phone-user provisioning, keyless E2E tests),
the admin/security dashboard, multi-tenancy, the Redis SignalR backplane,
NuGet + npm packaging — both proven by pack-and-consume smoke tests in CI and published on release
(the .NET libraries to GitHub Packages; @plenipo/ui ships bundled TypeScript declarations), Terraform
(azurerm) + Entra External ID app registrations + GitHub Actions (CI, deploy, publish) + Dependabot,
three sample verticals (Finance with a rule-based categorizer + budgets,
Nutrition, Legal) — Finance ships with a seeded demo ledger so its tabs and spending/budget tools work out
of the box — and end-to-end API integration tests. Both solutions build clean and the full .NET test suite is
green, and the React frontend has vitest unit tests (permission/API/chat-client logic) plus component tests for the chat panel, the server-driven data table, and the human-in-the-loop approval UI.
Open items: provision the Entra External ID tenant + user flows (the app registrations are already Terraform-managed, and the publish-on-release workflow is wired — it just needs a tagged release).
Data-source connectors, the plenipo init wizard, and the permission-aware RAG pipeline have all
shipped; their design and the remaining open items (connector-reported source ACLs, scheduled sync,
freshness ranking) are in
docs/PLATFORM_CONNECTORS_RAG_PLAN.md.
Also queued, driven by a consuming product's v2 plan — richer chart kinds (donut/bar,
alongside the existing line chart), stat-tile and progress-bar primitives, mobile
card-mode for the server-driven data table, masked-value rendering for [Pii] fields,
a risk-tiered, explainable approval queue, and two-factor/passkey authentication — are
designed in docs/RICH_UI_KIT_PLAN.md.
See CHANGELOG.md for the full scope of the upcoming 0.1.0-alpha.
Contributing
See CONTRIBUTING.md for the repo layout, build/test commands, conventions, and how to add a module.
Security
See SECURITY.md for how to report a vulnerability and a summary of the security model, and docs/AGENT_SECURITY.md for the cross-framework guardrail research, application-level policy pipeline, configuration, rollout guidance, and known gaps.
License
Plenipo is licensed under the MIT License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. 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. |
-
net10.0
- Anthropic.SDK (>= 5.10.0)
- Aspire.Npgsql.EntityFrameworkCore.PostgreSQL (>= 13.4.6)
- Azure.AI.DocumentIntelligence (>= 1.0.0)
- Azure.AI.OpenAI (>= 2.1.0)
- Azure.Identity (>= 1.21.0)
- Azure.Security.KeyVault.Secrets (>= 4.11.0)
- Azure.Storage.Blobs (>= 12.29.1)
- MailKit (>= 4.17.0)
- Microsoft.Agents.AI (>= 1.15.0)
- Microsoft.Agents.AI.OpenAI (>= 1.15.0)
- Microsoft.AspNetCore.Mvc.Testing (>= 10.0.10)
- Microsoft.EntityFrameworkCore (>= 10.0.10)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.10)
- Microsoft.Extensions.AI (>= 10.8.1)
- Microsoft.Extensions.AI.OpenAI (>= 10.8.1)
- ModelContextProtocol.Core (>= 1.4.1)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 10.0.3)
- OpenIddict.EntityFrameworkCore (>= 7.6.0)
- OpenTelemetry.Extensions.Hosting (>= 1.17.0)
- PdfPig (>= 0.1.15)
- Plenipo.Application (>= 0.1.0-alpha.29)
- Plenipo.Infrastructure (>= 0.1.0-alpha.29)
- Plenipo.Modules.Sdk (>= 0.1.0-alpha.29)
- SSH.NET (>= 2026.0.0)
- Testcontainers.PostgreSql (>= 4.15.0)
- xunit (>= 2.9.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-alpha.29 | 47 | 9/8/2026 |