Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CrestApps.Core.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<Project Path="src/Primitives/CrestApps.Core.AI.Documents.OpenXml/CrestApps.Core.AI.Documents.OpenXml.csproj" />
<Project Path="src/Primitives/CrestApps.Core.AI.Documents.Pdf/CrestApps.Core.AI.Documents.Pdf.csproj" />
<Project Path="src/Primitives/CrestApps.Core.AI.Mcp.Sftp/CrestApps.Core.AI.Mcp.Sftp.csproj" />
<Project Path="src/Primitives/CrestApps.Core.AI.AISearch/CrestApps.Core.AI.AISearch.csproj" />
<Project Path="src/Primitives/CrestApps.Core.AI.Azure.AISearch/CrestApps.Core.AI.Azure.AISearch.csproj" />
<Project Path="src/Primitives/CrestApps.Core.AI.Elasticsearch/CrestApps.Core.AI.Elasticsearch.csproj" />
<Project Path="src/Primitives/CrestApps.Core.AI/CrestApps.Core.AI.csproj" />
<Project Path="src/Primitives/CrestApps.Core.Azure.AISearch/CrestApps.Core.Azure.AISearch.csproj" />
Expand Down
3 changes: 3 additions & 0 deletions src/CrestApps.Core.Docs/docs/changelog/v1.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ description: Initial standalone release notes for the CrestApps.Core repository.
- evaluates every configured AI connection and deployment section when importing appsettings records, including provider-grouped connection sections and deployment entries that reference shared `ConnectionName` values
- adds shared `JsonNode` support extensions for common string, boolean, and raw-value extraction so AI configuration parsing and Elasticsearch document readers reuse one implementation instead of duplicating private helpers
- replaces removed obsolete connection-level deployment-name helpers with non-obsolete legacy lookup extensions for `AIProviderConnectionEntry`, keeping backward-compatible fallback resolution without depending on deleted APIs
- renames `CrestApps.Core.AI.AISearch` to `CrestApps.Core.AI.Azure.AISearch`, groups the docs navigation around orchestrators, surfaces the Claude docs page, renames AI Providers to AI Clients, and updates the OpenAI docs to call out common OpenAI-compatible endpoints plus the dedicated Claude path
- aligns the built-in Entity Framework Core stores with the same `IStoreCommitter` unit-of-work pattern as YesSql and refreshes the storage/getting-started docs to explain MVC, Minimal API, SignalR, and background commit boundaries consistently
- adds hierarchical document retrieval mode support so document RAG can rank on chunks and then inject full matched document text when hosts or profiles opt into that behavior
- clarifies deployment-store registration by introducing `IAIDeploymentStore` for persisted deployments, moves Chat Interactions ahead of AI Profiles / AI Chat in the MVC sample onboarding flow, and adds dedicated AI Profile documentation that explains how profiles power reusable chat, agents, orchestration, retrieval, and session processing
- centralizes reusable MCP runtime registration in `AddCoreAIMcpServices()`, moves the shared MCP metadata, capability-resolution, tool-registry, SSE settings-handler, and invoke-function services into `CrestApps.Core.AI.Mcp`, and splits optional StdIO transport registration so hosts can enable it only where needed
- treats aborted and canceled request-stream failures in the Aspire AppHost as observed task exceptions so local development no longer floods the console with benign unobserved-task noise
Expand Down
2 changes: 1 addition & 1 deletion src/CrestApps.Core.Docs/docs/core/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ This page describes the project architecture and how the major layers depend on
| `CrestApps.Core.AI.AzureAIInference` | Azure AI Inference / GitHub Models provider |
| `CrestApps.Core.AI.Copilot` | GitHub Copilot chat orchestration, OAuth flow, credential management |
| `CrestApps.Core.Azure.AISearch` | Azure AI Search provider primitives for client setup, index management, document management, and OData filters |
| `CrestApps.Core.AI.AISearch` | Azure AI Search integration for AI document index profiles, AI memory search, and AI data-source registrations |
| `CrestApps.Core.AI.Azure.AISearch` | Azure AI Search integration for AI document index profiles, AI memory search, and AI data-source registrations |
| `CrestApps.Core.Elasticsearch` | Elasticsearch provider primitives for client setup, index management, document management, and query/filter translation |
| `CrestApps.Core.AI.Elasticsearch` | Elasticsearch integration for AI document index profiles, AI memory search, and AI data-source registrations |
| `CrestApps.Core.AI.Mcp` | Model Context Protocol (MCP) client and server |
Expand Down
2 changes: 1 addition & 1 deletion src/CrestApps.Core.Docs/docs/core/copilot.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Users authenticate through a standard GitHub OAuth flow. The framework exchanges

### BYOK (API Key) Mode

The tenant admin configures a provider type, base URL, and API key. All users share the same credentials — no per-user authentication is needed. This mode supports any OpenAI-compatible endpoint (OpenAI, Azure OpenAI, Anthropic, or self-hosted).
The tenant admin configures a provider type, base URL, and API key. All users share the same credentials — no per-user authentication is needed. This mode supports OpenAI-compatible endpoints such as OpenAI, Azure OpenAI, Google Gemini compatibility endpoints, Groq, OpenRouter, or self-hosted OpenAI-style servers.

## Configuration

Expand Down
20 changes: 6 additions & 14 deletions src/CrestApps.Core.Docs/docs/core/data-storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public interface ICatalog<T> : IReadCatalog<T>
}
```

The YesSql implementation **stages** writes only. Hosts using `CrestApps.Core.Data.YesSql` must flush the YesSql session at the end of the HTTP request, SignalR hub method, or background operation that performed the write — see [Automatic store commit (`IStoreCommitter`)](#automatic-store-commit-istorecommitter) for how the framework handles this automatically. The Entity Framework Core implementation commits after each write operation via an individual `SaveChangesAsync()` call inside each store method. Every create, update, and delete is durable immediately; no request-level middleware is required or expected for the built-in stores.
The first-party YesSql and Entity Framework Core implementations both use a scoped unit-of-work boundary and flush tracked writes through `IStoreCommitter`. Hosts should call that commit boundary at the end of MVC actions, Minimal API endpoints, SignalR hub methods, or background scopes that performed writes — see [Automatic store commit (`IStoreCommitter`)](#automatic-store-commit-istorecommitter) for the built-in filters and background-task pattern.

### `INamedCatalog<T>`

Expand Down Expand Up @@ -532,15 +532,7 @@ The package stores framework records in EF Core-managed tables and keeps the sam

## Automatic store commit (`IStoreCommitter`)

:::info
**If you are using Entity Framework Core**, you can skip this section entirely. The EntityCore stores commit on every individual write operation via `SaveChangesAsync()`, so no commit middleware or manual flush is required.
:::

### Why does YesSql need this?

YesSql is a document store that **stages** all writes in memory during a request. Nothing is persisted to the database until the YesSql session is explicitly flushed with `ISession.SaveChangesAsync()`. This design gives you transactional consistency — all writes in a single request succeed or fail together — but it means you must call the flush at the end of every request that performs writes.

Instead of requiring you to call that flush manually in every controller action, hub method, and endpoint, the framework provides `IStoreCommitter` — a thin abstraction that triggers the flush at the right time.
The first-party YesSql and Entity Framework Core stores both use `IStoreCommitter` as their commit boundary. YesSql flushes the current `ISession`, while Entity Framework Core flushes the current `DbContext`. That keeps request, endpoint, and hub behavior consistent across the built-in store packages.

```csharp
public interface IStoreCommitter
Expand All @@ -549,11 +541,11 @@ public interface IStoreCommitter
}
```

`AddCoreYesSqlDataStore()` registers `YesSqlStoreCommitter` as the scoped `IStoreCommitter`. The implementation calls `ISession.SaveChangesAsync()` to flush all staged writes to the database.
`AddCoreYesSqlDataStore()` registers `YesSqlStoreCommitter`, and `AddCoreEntityCoreDataStore()` / `AddCoreEntityCoreSqliteDataStore()` register `EntityCoreStoreCommitter`. Both are scoped `IStoreCommitter` implementations.

### What happens if you forget to commit?

If `IStoreCommitter.CommitAsync()` is never called during a YesSql request, all writes made during that request are silently lost. The data appears to be saved in memory (reads within the same request see the staged data), but nothing reaches the database. This is the most common pitfall when using YesSql stores.
If `IStoreCommitter.CommitAsync()` is never called during a request or background scope that stages changes, those writes never become durable. Reads in the same scope may still see tracked changes, which can hide the problem until a later request.

### Automatic commit for MVC controllers

Expand Down Expand Up @@ -614,8 +606,8 @@ The filter infrastructure calls your committer automatically — no other wiring

| Store package | Commit behavior | Middleware required? |
|---------------|----------------|---------------------|
| **Entity Framework Core** | Commits on every individual write (`SaveChangesAsync()` per operation) | No |
| **YesSql** | Stages writes in memory; flushes on `IStoreCommitter.CommitAsync()` | Yes — use `AddCrestAppsStoreCommitterFilter()` for MVC/SignalR, or `StoreCommitterEndpointFilter` for Minimal APIs |
| **Entity Framework Core** | Stages tracked `DbContext` changes and flushes on `IStoreCommitter.CommitAsync()` | Yes — use `AddCrestAppsStoreCommitterFilter()` for MVC/SignalR, or `StoreCommitterEndpointFilter` for Minimal APIs |
| **YesSql** | Stages `ISession` writes in memory and flushes on `IStoreCommitter.CommitAsync()` | Yes — use `AddCrestAppsStoreCommitterFilter()` for MVC/SignalR, or `StoreCommitterEndpointFilter` for Minimal APIs |

## Multi-Source Binding Pattern

Expand Down
47 changes: 47 additions & 0 deletions src/CrestApps.Core.Docs/docs/core/default-orchestrator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
sidebar_label: Default Orchestrator
title: Default Orchestrator
description: The built-in CrestApps.Core orchestrator that composes tools, RAG, streaming, and response handling into one execution pipeline.
---

# Default Orchestrator

> The built-in CrestApps.Core orchestration engine that connects the framework's AI clients, tools, retrieval pipelines, response handlers, and streaming loop into one end-to-end execution model.

## What it is

`DefaultOrchestrator` is the framework's first-party `IOrchestrator` implementation. It is the standard orchestrator used when you call `AddCoreAIOrchestration()` and do not select an alternative such as Copilot or Claude.

It is responsible for:

- loading the active AI client and deployment
- building orchestration context from profiles, templates, MCP, data sources, documents, and memory
- scoping tools progressively so large tool catalogs stay usable
- running preemptive RAG before the main completion call
- streaming model output and routing references back to the caller

## When to use it

Use the default orchestrator when you want the full CrestApps.Core pipeline instead of a provider-specific orchestrator runtime.

That is usually the right choice when you need:

- the shared tool and agent pipeline
- preemptive RAG across documents, memory, and data sources
- MCP integration through the framework's own orchestration flow
- predictable host-controlled deployment and connection resolution

## Registration

```csharp
builder.Services
.AddCoreAIServices()
.AddCoreAIOrchestration()
.AddCoreAIOpenAI();
```

## Relationship to the orchestration docs

This page is the conceptual overview for the built-in orchestrator.

Use **[Orchestration](./orchestration.md)** for the full pipeline details, registered services, progressive tool scoping, configuration knobs, and extension points.
17 changes: 16 additions & 1 deletion src/CrestApps.Core.Docs/docs/core/getting-started-aspnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,24 @@ builder.Services.AddCrestAppsCore(crestApps => crestApps
```

:::tip
YesSql stages writes in memory and flushes them as a single transaction at the end of a request. The framework provides `IStoreCommitter` and automatic commit filters to handle this. See [Data Storage — Automatic store commit](data-storage.md#automatic-store-commit-istorecommitter) for details. Entity Framework Core commits on every individual write, so no commit middleware is needed.
Both Entity Framework Core and the built-in YesSql stores follow the same `IStoreCommitter` pattern. Register the MVC action filter, the Minimal API endpoint filter, and the existing SignalR store-committer filter when your store implementation uses a unit-of-work/session model. If your custom implementation persists immediately and does not stage tracked changes, you do not need `IStoreCommitter`.
:::

For MVC actions:

```csharp
builder.Services
.AddControllersWithViews()
.AddCrestAppsStoreCommitterFilter();
```

For Minimal APIs:

```csharp
app.MapGroup("/api")
.AddEndpointFilter<StoreCommitterEndpointFilter>();
```

If you already use another ORM or storage model, implement the same catalog/store abstractions against your preferred backend. See [Data Storage](data-storage.md) for the full per-feature store reference.

## 6. Add features one layer at a time
Expand Down
2 changes: 1 addition & 1 deletion src/CrestApps.Core.Docs/docs/core/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ The quickest way to validate the setup is to use **Chat Interactions** first, th
| Claude orchestration | `AddCoreAIClaudeOrchestrator()` | `CrestApps.Core.AI.Claude` | [Claude Orchestrator](./claude.md) |
| SignalR and widgets | `AddCoreSignalR()` | `CrestApps.Core.SignalR` | [SignalR](./signalr.md) |
| Data storage | Store registration extensions | `CrestApps.Core.Data.YesSql` | [Data Storage](./data-storage.md) |
| Providers | Provider-specific extensions | Provider packages | [AI Providers](../providers/index.md) |
| AI clients | Provider-specific extensions | Provider packages | [AI Clients](../providers/index.md) |
| Data sources | Backend-specific extensions | Search packages | [Data Sources](../data-sources/index.md) |
| MCP | `AddCoreAIMcpClient()` / `AddCoreAIMcpServer()` | `CrestApps.Core.AI.Mcp` | [MCP](../mcp/index.md) |
| A2A | `AddCoreAIA2AClient()` | `CrestApps.Core.AI.A2A` | [A2A](../a2a/index.md) |
Expand Down
12 changes: 2 additions & 10 deletions src/CrestApps.Core.Docs/docs/core/mvc-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,12 @@ CrestApps.Core.Mvc.Web/
│ ├── DataSources/ ← Data source CRUD and storage
│ └── Indexing/ ← Index profiles and AI document indexing
├── BackgroundTasks/ ← Hosted services for maintenance

├── Controllers/ ← Non-area MVC controllers such as Home and Account

├── Hubs/ ← SignalR hubs for real-time chat

├── Indexes/ ← YesSql index providers

├── Tools/ ← Custom AI tools

├── Views/ ← Non-area Razor views

├── App_Data/ ← Runtime data (DB, logs, documents, settings)

└── wwwroot/ ← Static files
```

Expand All @@ -64,7 +57,6 @@ Configures NLog with daily log file rotation in `App_Data/logs/`. Replaceable wi
Loads settings from the normal appsettings chain plus `App_Data/appsettings.json` as the highest-priority local override file with automatic reload-on-change:

| Service | Purpose |

|---------|---------|
| `App_Data/appsettings.json` | Local machine overrides for infrastructure settings (AI connections, credentials, Elasticsearch, Azure AI Search) |
| `App_Data/site-settings.json` | Mutable admin-managed settings (AI options, deployments, chat, admin widget, etc.) owned exclusively by `SiteSettingsStore` — not registered in the configuration pipeline |
Expand Down Expand Up @@ -135,15 +127,15 @@ builder.Services.AddCrestAppsCore(crestApps => crestApps

`AddAISuite(...)` always wires the shared foundation, AI runtime, and orchestration together. `AddChatInteractions()` inside that suite then registers the shared `DataSourceChatInteractionSettingsHandler`, so Chat Interactions persist the selected data source and RAG metadata through the framework settings pipeline instead of MVC-only wiring. The provider service blocks also pull in the shared data-source RAG registrations, which register both `DataSourceOrchestrationHandler` and `DataSourcePreemptiveRagHandler` at the framework level so source availability instructions and preemptive RAG stay aligned with the saved chat settings.

`AddAIDocuments()`, `AddAIDataSources()`, and `AddAIMemory()` in those indexing blocks now come from the AI-specific provider packages: `CrestApps.Core.AI.Elasticsearch` and `CrestApps.Core.AI.AISearch`. The base `CrestApps.Core.Elasticsearch` and `CrestApps.Core.Azure.AISearch` packages now stay focused on the provider primitives and shared search infrastructure only.
`AddAIDocuments()`, `AddAIDataSources()`, and `AddAIMemory()` in those indexing blocks now come from the AI-specific provider packages: `CrestApps.Core.AI.Elasticsearch` and `CrestApps.Core.AI.Azure.AISearch`. The base `CrestApps.Core.Elasticsearch` and `CrestApps.Core.Azure.AISearch` packages now stay focused on the provider primitives and shared search infrastructure only.

The MVC sample now also registers both the **Claude** and **Copilot** orchestrators. Claude uses the official Anthropic SDK with a site-level authentication mode, API key, and live model discovery, while Copilot keeps its dedicated OAuth/BYOK flow. Admins can choose either orchestrator from the same AI Profile, AI Template, and Chat Interaction editors.

Documents, memory, and data sources now remain fully independent orchestration sources in the shared framework. Each source injects its own availability instructions and preemptive-RAG context, so the orchestrator can compose them together without the document prompts needing to know whether memory or data sources are also attached.

The MVC sample explicitly calls `AddMarkdown()` inside `AddAISuite(...)`. That keeps Markdown-aware normalization opt-in at the host level instead of making `CrestApps.Core.AI` depend on the Markdig-backed package automatically.

### Section 6 — AI Providers
### Section 6 — AI Clients

Registers all supported AI providers:

Expand Down
2 changes: 1 addition & 1 deletion src/CrestApps.Core.Docs/docs/data-sources/azure-ai.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ builder.Services.AddCoreAzureAISearchServices();

When the `Endpoint` is provided, a `SearchIndexClient` singleton is also registered.

AI-specific Azure AI Search registrations now live in `CrestApps.Core.AI.AISearch`. Register that package when you need `AddAIDocuments()`, `AddAIDataSources()`, `AddAIMemory()`, or Azure AI Search-backed AI RAG/search flows.
AI-specific Azure AI Search registrations now live in `CrestApps.Core.AI.Azure.AISearch`. Register that package when you need `AddAIDocuments()`, `AddAIDataSources()`, `AddAIMemory()`, or Azure AI Search-backed AI RAG/search flows.

## Authentication

Expand Down
11 changes: 10 additions & 1 deletion src/CrestApps.Core.Docs/docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,25 @@ By default:
"Deployments": [
{
"Name": "gpt-4.1",
"ClientName": "OpenAI",
"ConnectionName": "primary-openai",
"ModelName": "gpt-4.1",
"Type": "Chat"
},
{
"Name": "standalone-utility",
"ClientName": "OpenAI",
"ModelName": "gpt-4.1-mini",
"Type": "Utility",
"ApiKey": "YOUR_OTHER_API_KEY"
}
]
}
}
}
```

Use `ConnectionName` when a deployment should point at a shared entry from `CrestApps:AI:Connections`. Keep contained connection settings directly on the deployment only when you want a standalone deployment definition.

Create an AI profile that uses your chat deployment, then use Chat Interactions to test it end to end.

## Learn the registration model
Expand Down
10 changes: 5 additions & 5 deletions src/CrestApps.Core.Docs/docs/mcp/client.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
sidebar_label: MCP Client
sidebar_label: Hosts
sidebar_position: 2
title: MCP Client
description: Connect to remote MCP servers to discover and use their tools, prompts, and resources in AI orchestration.
title: MCP Hosts
description: Connect to remote MCP hosts to discover and use their tools, prompts, and resources in AI orchestration.
---

# MCP Client
# MCP Hosts

> Connect to remote MCP servers, discover their capabilities, and make their tools available to the AI orchestrator.
> Connect to remote MCP hosts, discover their capabilities, and make their tools available to the AI orchestrator.

## Quick Start

Expand Down
Loading
Loading