Rename project to Cortex #1
+12
-12
@@ -1,13 +1,13 @@
|
||||
POSTGRES_DB=cerebro
|
||||
POSTGRES_USER=cerebro
|
||||
POSTGRES_PASSWORD=cerebro_dev_password
|
||||
CEREBRO_APP_PORT=5117
|
||||
CEREBRO_WEB_PORT=5118
|
||||
CEREBRO_DB_PORT=54329
|
||||
CEREBRO_EMBEDDINGS_PORT=8088
|
||||
POSTGRES_DB=cortex
|
||||
POSTGRES_USER=cortex
|
||||
POSTGRES_PASSWORD=cortex_dev_password
|
||||
CORTEX_APP_PORT=5117
|
||||
CORTEX_WEB_PORT=5118
|
||||
CORTEX_DB_PORT=54329
|
||||
CORTEX_EMBEDDINGS_PORT=8088
|
||||
EMBEDDING_MODEL=BAAI/bge-small-en-v1.5
|
||||
CEREBRO_TEST_BASE_URL=http://localhost:5217
|
||||
CEREBRO_TEST_APP_PORT=5217
|
||||
CEREBRO_TEST_WEB_PORT=5218
|
||||
CEREBRO_TEST_DB_PORT=54339
|
||||
CEREBRO_TEST_EMBEDDINGS_PORT=8188
|
||||
CORTEX_TEST_BASE_URL=http://localhost:5217
|
||||
CORTEX_TEST_APP_PORT=5217
|
||||
CORTEX_TEST_WEB_PORT=5218
|
||||
CORTEX_TEST_DB_PORT=54339
|
||||
CORTEX_TEST_EMBEDDINGS_PORT=8188
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<Solution>
|
||||
<Folder Name="/Solution Items/">
|
||||
<File Path="Directory.Packages.props" />
|
||||
</Folder>
|
||||
<Project Path="src/Cerebro.Api/Cerebro.Api.csproj" />
|
||||
<Project Path="src/Cerebro.Web/Cerebro.Web.csproj" />
|
||||
<Project Path="tests/Cerebro.IntegrationTests/Cerebro.IntegrationTests.csproj" />
|
||||
</Solution>
|
||||
@@ -0,0 +1,9 @@
|
||||
<Solution>
|
||||
<Folder Name="/Solution Items/">
|
||||
<File Path="Directory.Packages.props" />
|
||||
</Folder>
|
||||
<Project Path="src/Cortex.Api/Cortex.Api.csproj" />
|
||||
<Project Path="src/Cortex.Core/Cortex.Core.csproj" />
|
||||
<Project Path="src/Cortex.Web/Cortex.Web.csproj" />
|
||||
<Project Path="tests/Cortex.IntegrationTests/Cortex.IntegrationTests.csproj" />
|
||||
</Solution>
|
||||
+7
-5
@@ -4,14 +4,16 @@ WORKDIR /src
|
||||
COPY NuGet.Config ./
|
||||
COPY Directory.Build.props ./
|
||||
COPY Directory.Packages.props ./
|
||||
COPY src/Cerebro.Api/Cerebro.Api.csproj src/Cerebro.Api/
|
||||
RUN dotnet restore src/Cerebro.Api/Cerebro.Api.csproj --configfile NuGet.Config
|
||||
COPY src/Cortex.Core/Cortex.Core.csproj src/Cortex.Core/
|
||||
COPY src/Cortex.Api/Cortex.Api.csproj src/Cortex.Api/
|
||||
RUN dotnet restore src/Cortex.Api/Cortex.Api.csproj --configfile NuGet.Config
|
||||
|
||||
COPY src/Cerebro.Api src/Cerebro.Api
|
||||
RUN dotnet publish src/Cerebro.Api/Cerebro.Api.csproj -c Release -o /app/publish --no-restore
|
||||
COPY src/Cortex.Core src/Cortex.Core
|
||||
COPY src/Cortex.Api src/Cortex.Api
|
||||
RUN dotnet publish src/Cortex.Api/Cortex.Api.csproj -c Release -o /app/publish --no-restore
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
|
||||
WORKDIR /app
|
||||
COPY --from=build /app/publish .
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["dotnet", "Cerebro.Api.dll"]
|
||||
ENTRYPOINT ["dotnet", "Cortex.Api.dll"]
|
||||
|
||||
+7
-7
@@ -4,16 +4,16 @@ WORKDIR /src
|
||||
COPY NuGet.Config ./
|
||||
COPY Directory.Build.props ./
|
||||
COPY Directory.Packages.props ./
|
||||
COPY src/Cerebro.Api/Cerebro.Api.csproj src/Cerebro.Api/
|
||||
COPY src/Cerebro.Web/Cerebro.Web.csproj src/Cerebro.Web/
|
||||
RUN dotnet restore src/Cerebro.Web/Cerebro.Web.csproj --configfile NuGet.Config
|
||||
COPY src/Cortex.Core/Cortex.Core.csproj src/Cortex.Core/
|
||||
COPY src/Cortex.Web/Cortex.Web.csproj src/Cortex.Web/
|
||||
RUN dotnet restore src/Cortex.Web/Cortex.Web.csproj --configfile NuGet.Config
|
||||
|
||||
COPY src/Cerebro.Api src/Cerebro.Api
|
||||
COPY src/Cerebro.Web src/Cerebro.Web
|
||||
RUN dotnet publish src/Cerebro.Web/Cerebro.Web.csproj -c Release -o /app/publish --no-restore
|
||||
COPY src/Cortex.Core src/Cortex.Core
|
||||
COPY src/Cortex.Web src/Cortex.Web
|
||||
RUN dotnet publish src/Cortex.Web/Cortex.Web.csproj -c Release -o /app/publish
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
|
||||
WORKDIR /app
|
||||
COPY --from=build /app/publish .
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["dotnet", "Cerebro.Web.dll"]
|
||||
ENTRYPOINT ["dotnet", "Cortex.Web.dll"]
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Cerebro
|
||||
# Cortex
|
||||
|
||||
Cerebro is a local-first memory server exposed through the Model Context Protocol (MCP). It lets an MCP client store and recall project-scoped requirements, locations, todos, and notes.
|
||||
Cortex is a local-first memory server exposed through the Model Context Protocol (MCP). It lets an MCP client store and recall project-scoped requirements, locations, todos, and notes.
|
||||
|
||||
The project is intentionally small and operationally explicit: everything local is run through PowerShell scripts, the app runs in Docker, data lives in PostgreSQL with pgvector, and embeddings are produced by a local container.
|
||||
|
||||
## What Cerebro Does
|
||||
## What Cortex Does
|
||||
|
||||
- Stores memories inside explicit projects.
|
||||
- Supports four categories: `requirement`, `location`, `todo`, and `note`.
|
||||
@@ -32,7 +32,7 @@ The project is intentionally small and operationally explicit: everything local
|
||||
|
||||
| Service | Dev instance | Test instance |
|
||||
| --- | ---: | ---: |
|
||||
| Cerebro app | <http://localhost:5117> | <http://localhost:5217> |
|
||||
| Cortex app | <http://localhost:5117> | <http://localhost:5217> |
|
||||
| Web UI | <http://localhost:5118> | <http://localhost:5218> |
|
||||
| MCP endpoint | <http://localhost:5117/mcp> | <http://localhost:5217/mcp> |
|
||||
| PostgreSQL | `localhost:54329` | `localhost:54339` |
|
||||
|
||||
+31
-31
@@ -1,77 +1,77 @@
|
||||
name: cerebro-test
|
||||
name: cortex-test
|
||||
|
||||
services:
|
||||
cerebro-test-db:
|
||||
cortex-test-db:
|
||||
image: pgvector/pgvector:pg17
|
||||
container_name: cerebro-test-db
|
||||
container_name: cortex-test-db
|
||||
environment:
|
||||
POSTGRES_DB: cerebro
|
||||
POSTGRES_USER: cerebro
|
||||
POSTGRES_PASSWORD: cerebro_dev_password
|
||||
POSTGRES_DB: cortex
|
||||
POSTGRES_USER: cortex
|
||||
POSTGRES_PASSWORD: cortex_dev_password
|
||||
ports:
|
||||
- "54339:5432"
|
||||
volumes:
|
||||
- cerebro-test-postgres-data:/var/lib/postgresql/data
|
||||
- cortex-test-postgres-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U cerebro -d cerebro"]
|
||||
test: ["CMD-SHELL", "pg_isready -U cortex -d cortex"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
|
||||
cerebro-test-embeddings:
|
||||
cortex-test-embeddings:
|
||||
image: ghcr.io/huggingface/text-embeddings-inference:cpu-latest
|
||||
container_name: cerebro-test-embeddings
|
||||
container_name: cortex-test-embeddings
|
||||
command: ["--model-id", "BAAI/bge-small-en-v1.5", "--port", "80"]
|
||||
ports:
|
||||
- "8188:80"
|
||||
volumes:
|
||||
- cerebro-test-embeddings-data:/data
|
||||
- cortex-test-embeddings-data:/data
|
||||
|
||||
cerebro-test-app:
|
||||
cortex-test-app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: cerebro-app:test
|
||||
container_name: cerebro-test-app
|
||||
image: cortex-app:test
|
||||
container_name: cortex-test-app
|
||||
depends_on:
|
||||
cerebro-test-db:
|
||||
cortex-test-db:
|
||||
condition: service_healthy
|
||||
cerebro-test-embeddings:
|
||||
cortex-test-embeddings:
|
||||
condition: service_started
|
||||
environment:
|
||||
ASPNETCORE_URLS: http://+:8080
|
||||
ASPNETCORE_ENVIRONMENT: Development
|
||||
ConnectionStrings__Cerebro: Host=cerebro-test-db;Port=5432;Database=cerebro;Username=cerebro;Password=cerebro_dev_password;GSS Encryption Mode=Disable
|
||||
Embedding__BaseUrl: http://cerebro-test-embeddings
|
||||
ConnectionStrings__Cortex: Host=cortex-test-db;Port=5432;Database=cortex;Username=cortex;Password=cortex_dev_password;GSS Encryption Mode=Disable
|
||||
Embedding__BaseUrl: http://cortex-test-embeddings
|
||||
Embedding__Model: BAAI/bge-small-en-v1.5
|
||||
Cerebro__EmbeddingModel: BAAI/bge-small-en-v1.5
|
||||
Cerebro__EmbeddingDimensions: 384
|
||||
Cortex__EmbeddingModel: BAAI/bge-small-en-v1.5
|
||||
Cortex__EmbeddingDimensions: 384
|
||||
ports:
|
||||
- "5217:8080"
|
||||
|
||||
cerebro-test-web:
|
||||
cortex-test-web:
|
||||
profiles: ["ui"]
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.web
|
||||
image: cerebro-web:test
|
||||
container_name: cerebro-test-web
|
||||
image: cortex-web:test
|
||||
container_name: cortex-test-web
|
||||
depends_on:
|
||||
cerebro-test-db:
|
||||
cortex-test-db:
|
||||
condition: service_healthy
|
||||
cerebro-test-embeddings:
|
||||
cortex-test-embeddings:
|
||||
condition: service_started
|
||||
environment:
|
||||
ASPNETCORE_URLS: http://+:8080
|
||||
ASPNETCORE_ENVIRONMENT: Development
|
||||
ConnectionStrings__Cerebro: Host=cerebro-test-db;Port=5432;Database=cerebro;Username=cerebro;Password=cerebro_dev_password;GSS Encryption Mode=Disable
|
||||
Embedding__BaseUrl: http://cerebro-test-embeddings
|
||||
ConnectionStrings__Cortex: Host=cortex-test-db;Port=5432;Database=cortex;Username=cortex;Password=cortex_dev_password;GSS Encryption Mode=Disable
|
||||
Embedding__BaseUrl: http://cortex-test-embeddings
|
||||
Embedding__Model: BAAI/bge-small-en-v1.5
|
||||
Cerebro__EmbeddingModel: BAAI/bge-small-en-v1.5
|
||||
Cerebro__EmbeddingDimensions: 384
|
||||
Cortex__EmbeddingModel: BAAI/bge-small-en-v1.5
|
||||
Cortex__EmbeddingDimensions: 384
|
||||
ports:
|
||||
- "5218:8080"
|
||||
|
||||
volumes:
|
||||
cerebro-test-postgres-data:
|
||||
cerebro-test-embeddings-data:
|
||||
cortex-test-postgres-data:
|
||||
cortex-test-embeddings-data:
|
||||
|
||||
+31
-31
@@ -1,77 +1,77 @@
|
||||
name: cerebro
|
||||
name: cortex
|
||||
|
||||
services:
|
||||
cerebro-db:
|
||||
cortex-db:
|
||||
image: pgvector/pgvector:pg17
|
||||
container_name: cerebro-db
|
||||
container_name: cortex-db
|
||||
environment:
|
||||
POSTGRES_DB: cerebro
|
||||
POSTGRES_USER: cerebro
|
||||
POSTGRES_PASSWORD: cerebro_dev_password
|
||||
POSTGRES_DB: cortex
|
||||
POSTGRES_USER: cortex
|
||||
POSTGRES_PASSWORD: cortex_dev_password
|
||||
ports:
|
||||
- "54329:5432"
|
||||
volumes:
|
||||
- cerebro-postgres-data:/var/lib/postgresql/data
|
||||
- cortex-postgres-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U cerebro -d cerebro"]
|
||||
test: ["CMD-SHELL", "pg_isready -U cortex -d cortex"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
|
||||
cerebro-embeddings:
|
||||
cortex-embeddings:
|
||||
image: ghcr.io/huggingface/text-embeddings-inference:cpu-latest
|
||||
container_name: cerebro-embeddings
|
||||
container_name: cortex-embeddings
|
||||
command: ["--model-id", "BAAI/bge-small-en-v1.5", "--port", "80"]
|
||||
ports:
|
||||
- "8088:80"
|
||||
volumes:
|
||||
- cerebro-embeddings-data:/data
|
||||
- cortex-embeddings-data:/data
|
||||
|
||||
cerebro-app:
|
||||
cortex-app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: cerebro-app:local
|
||||
container_name: cerebro-app
|
||||
image: cortex-app:local
|
||||
container_name: cortex-app
|
||||
depends_on:
|
||||
cerebro-db:
|
||||
cortex-db:
|
||||
condition: service_healthy
|
||||
cerebro-embeddings:
|
||||
cortex-embeddings:
|
||||
condition: service_started
|
||||
environment:
|
||||
ASPNETCORE_URLS: http://+:8080
|
||||
ASPNETCORE_ENVIRONMENT: Development
|
||||
ConnectionStrings__Cerebro: Host=cerebro-db;Port=5432;Database=cerebro;Username=cerebro;Password=cerebro_dev_password;GSS Encryption Mode=Disable
|
||||
Embedding__BaseUrl: http://cerebro-embeddings
|
||||
ConnectionStrings__Cortex: Host=cortex-db;Port=5432;Database=cortex;Username=cortex;Password=cortex_dev_password;GSS Encryption Mode=Disable
|
||||
Embedding__BaseUrl: http://cortex-embeddings
|
||||
Embedding__Model: BAAI/bge-small-en-v1.5
|
||||
Cerebro__EmbeddingModel: BAAI/bge-small-en-v1.5
|
||||
Cerebro__EmbeddingDimensions: 384
|
||||
Cortex__EmbeddingModel: BAAI/bge-small-en-v1.5
|
||||
Cortex__EmbeddingDimensions: 384
|
||||
ports:
|
||||
- "5117:8080"
|
||||
|
||||
cerebro-web:
|
||||
cortex-web:
|
||||
profiles: ["ui"]
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.web
|
||||
image: cerebro-web:local
|
||||
container_name: cerebro-web
|
||||
image: cortex-web:local
|
||||
container_name: cortex-web
|
||||
depends_on:
|
||||
cerebro-db:
|
||||
cortex-db:
|
||||
condition: service_healthy
|
||||
cerebro-embeddings:
|
||||
cortex-embeddings:
|
||||
condition: service_started
|
||||
environment:
|
||||
ASPNETCORE_URLS: http://+:8080
|
||||
ASPNETCORE_ENVIRONMENT: Development
|
||||
ConnectionStrings__Cerebro: Host=cerebro-db;Port=5432;Database=cerebro;Username=cerebro;Password=cerebro_dev_password;GSS Encryption Mode=Disable
|
||||
Embedding__BaseUrl: http://cerebro-embeddings
|
||||
ConnectionStrings__Cortex: Host=cortex-db;Port=5432;Database=cortex;Username=cortex;Password=cortex_dev_password;GSS Encryption Mode=Disable
|
||||
Embedding__BaseUrl: http://cortex-embeddings
|
||||
Embedding__Model: BAAI/bge-small-en-v1.5
|
||||
Cerebro__EmbeddingModel: BAAI/bge-small-en-v1.5
|
||||
Cerebro__EmbeddingDimensions: 384
|
||||
Cortex__EmbeddingModel: BAAI/bge-small-en-v1.5
|
||||
Cortex__EmbeddingDimensions: 384
|
||||
ports:
|
||||
- "5118:8080"
|
||||
|
||||
volumes:
|
||||
cerebro-postgres-data:
|
||||
cerebro-embeddings-data:
|
||||
cortex-postgres-data:
|
||||
cortex-embeddings-data:
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# Architecture
|
||||
|
||||
Cerebro is a small domain-specific MCP server.
|
||||
Cortex is a small domain-specific MCP server.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Client["MCP client"] -->|Streamable HTTP| App["Cerebro .NET 10 app"]
|
||||
Browser["Browser"] --> Web["Cerebro Blazor web UI"]
|
||||
Client["MCP client"] -->|Streamable HTTP| App["Cortex .NET 10 app"]
|
||||
Browser["Browser"] --> Web["Cortex Blazor web UI"]
|
||||
Web --> Db
|
||||
Web --> Embed
|
||||
App --> Db["PostgreSQL + pgvector"]
|
||||
@@ -31,7 +31,7 @@ Health is exposed at:
|
||||
|
||||
The web UI is a separate Blazor Server project and Docker container. It is optional and not needed for MCP clients.
|
||||
|
||||
The UI talks to the same PostgreSQL database and embedding service through the existing Cerebro service layer. It is intended for manual browsing, adding memories, searching, editing, and soft-deleting during local development.
|
||||
The UI talks to the same PostgreSQL database and embedding service through the existing Cortex service layer. It is intended for manual browsing, adding memories, searching, editing, and soft-deleting during local development.
|
||||
|
||||
Dev URL:
|
||||
|
||||
|
||||
+12
-12
@@ -4,7 +4,7 @@
|
||||
|
||||
```text
|
||||
src/
|
||||
Cerebro.Api/
|
||||
Cortex.Api/
|
||||
Contracts/
|
||||
Data/
|
||||
Domain/
|
||||
@@ -12,11 +12,11 @@ src/
|
||||
Options/
|
||||
Services/
|
||||
Tools/
|
||||
Cerebro.Web/
|
||||
Cortex.Web/
|
||||
Components/
|
||||
wwwroot/
|
||||
tests/
|
||||
Cerebro.IntegrationTests/
|
||||
Cortex.IntegrationTests/
|
||||
scripts/
|
||||
docs/
|
||||
```
|
||||
@@ -25,19 +25,19 @@ docs/
|
||||
|
||||
| File | Purpose |
|
||||
| --- | --- |
|
||||
| `src/Cerebro.Api/Program.cs` | App startup, DI, MCP route, migration/seed modes. |
|
||||
| `src/Cerebro.Api/Tools/CerebroTools.cs` | MCP tool surface. |
|
||||
| `src/Cerebro.Api/Services/CerebroMemoryService.cs` | Project/item/search behavior. |
|
||||
| `src/Cerebro.Api/Data/CerebroDbContext.cs` | EF Core model. |
|
||||
| `src/Cerebro.Web/Components/Pages/Home.razor` | Optional Blazor web UI dashboard. |
|
||||
| `src/Cerebro.Api/Migrations` | Database schema migrations. |
|
||||
| `src/Cortex.Api/Program.cs` | App startup, DI, MCP route, migration/seed modes. |
|
||||
| `src/Cortex.Api/Tools/CortexTools.cs` | MCP tool surface. |
|
||||
| `src/Cortex.Api/Services/CortexMemoryService.cs` | Project/item/search behavior. |
|
||||
| `src/Cortex.Api/Data/CortexDbContext.cs` | EF Core model. |
|
||||
| `src/Cortex.Web/Components/Pages/Home.razor` | Optional Blazor web UI dashboard. |
|
||||
| `src/Cortex.Api/Migrations` | Database schema migrations. |
|
||||
| `docker-compose.yml` | Dev stack. |
|
||||
| `docker-compose.test.yml` | Test stack. |
|
||||
|
||||
## Adding a Tool
|
||||
|
||||
1. Add a method to `CerebroTools`.
|
||||
2. Add or update a service method in `CerebroMemoryService`.
|
||||
1. Add a method to `CortexTools`.
|
||||
2. Add or update a service method in `CortexMemoryService`.
|
||||
3. Use `[McpServerTool]` with a stable `Name`.
|
||||
4. Set `UseStructuredContent = true` when the tool returns structured data.
|
||||
5. Add an integration test.
|
||||
@@ -58,7 +58,7 @@ docs/
|
||||
|
||||
The current model produces 384-dimensional vectors. If the new model has a different dimension, update:
|
||||
|
||||
- `Cerebro:EmbeddingDimensions`
|
||||
- `Cortex:EmbeddingDimensions`
|
||||
- migration/schema for `vector(N)`
|
||||
- indexes
|
||||
- docs
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"servers": {
|
||||
"cerebro": {
|
||||
"cortex": {
|
||||
"type": "http",
|
||||
"url": "http://localhost:5117/mcp"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"servers": {
|
||||
"cerebro": {
|
||||
"cortex": {
|
||||
"type": "http",
|
||||
"url": "http://localhost:5117/mcp"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"servers": {
|
||||
"cerebro-test": {
|
||||
"cortex-test": {
|
||||
"type": "http",
|
||||
"url": "http://localhost:5217/mcp"
|
||||
}
|
||||
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
# MCP Tools
|
||||
|
||||
Cerebro exposes MCP tools over:
|
||||
Cortex exposes MCP tools over:
|
||||
|
||||
```text
|
||||
http://localhost:5117/mcp
|
||||
@@ -27,8 +27,8 @@ Result:
|
||||
```json
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000000",
|
||||
"name": "Cerebro",
|
||||
"slug": "cerebro",
|
||||
"name": "Cortex",
|
||||
"slug": "cortex",
|
||||
"createdAt": "2026-07-08T12:00:00Z"
|
||||
}
|
||||
```
|
||||
@@ -45,8 +45,8 @@ Result:
|
||||
[
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000000",
|
||||
"name": "Cerebro",
|
||||
"slug": "cerebro",
|
||||
"name": "Cortex",
|
||||
"slug": "cortex",
|
||||
"createdAt": "2026-07-08T12:00:00Z"
|
||||
}
|
||||
]
|
||||
@@ -72,7 +72,7 @@ Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"project": "cerebro",
|
||||
"project": "cortex",
|
||||
"category": "location",
|
||||
"title": "USB-C charging brick",
|
||||
"content": "The USB-C charging brick is in the blue backpack.",
|
||||
@@ -108,7 +108,7 @@ Example:
|
||||
|
||||
## UpdateItem
|
||||
|
||||
Updates an existing item. If title, content, category, or tags change, Cerebro regenerates the embedding.
|
||||
Updates an existing item. If title, content, category, or tags change, Cortex regenerates the embedding.
|
||||
|
||||
Arguments:
|
||||
|
||||
|
||||
+11
-11
@@ -1,28 +1,28 @@
|
||||
# Operations Guide
|
||||
|
||||
Cerebro local operations are PowerShell-only.
|
||||
Cortex local operations are PowerShell-only.
|
||||
|
||||
## Dev Stack
|
||||
|
||||
The dev stack is named `cerebro`.
|
||||
The dev stack is named `cortex`.
|
||||
|
||||
| Container | Purpose |
|
||||
| --- | --- |
|
||||
| `cerebro-db` | PostgreSQL with pgvector. |
|
||||
| `cerebro-embeddings` | Local embedding service. |
|
||||
| `cerebro-app` | .NET 10 MCP server. |
|
||||
| `cerebro-web` | Optional Blazor web UI. |
|
||||
| `cortex-db` | PostgreSQL with pgvector. |
|
||||
| `cortex-embeddings` | Local embedding service. |
|
||||
| `cortex-app` | .NET 10 MCP server. |
|
||||
| `cortex-web` | Optional Blazor web UI. |
|
||||
|
||||
## Test Stack
|
||||
|
||||
The test stack is named `cerebro-test`.
|
||||
The test stack is named `cortex-test`.
|
||||
|
||||
| Container | Purpose |
|
||||
| --- | --- |
|
||||
| `cerebro-test-db` | Isolated PostgreSQL with pgvector. |
|
||||
| `cerebro-test-embeddings` | Isolated embedding service. |
|
||||
| `cerebro-test-app` | Isolated MCP server under test. |
|
||||
| `cerebro-test-web` | Optional isolated Blazor web UI. |
|
||||
| `cortex-test-db` | Isolated PostgreSQL with pgvector. |
|
||||
| `cortex-test-embeddings` | Isolated embedding service. |
|
||||
| `cortex-test-app` | Isolated MCP server under test. |
|
||||
| `cortex-test-web` | Optional isolated Blazor web UI. |
|
||||
|
||||
The test stack uses different ports and a different database volume so it can run beside the dev stack.
|
||||
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
# Setup Guide
|
||||
|
||||
This guide gets a local Cerebro dev instance running on Windows.
|
||||
This guide gets a local Cortex dev instance running on Windows.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -25,7 +25,7 @@ This starts:
|
||||
|
||||
- PostgreSQL with pgvector
|
||||
- Hugging Face Text Embeddings Inference
|
||||
- Cerebro MCP server
|
||||
- Cortex MCP server
|
||||
|
||||
It also applies EF Core migrations before starting the app.
|
||||
|
||||
@@ -41,7 +41,7 @@ Expected result:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Cerebro",
|
||||
"name": "Cortex",
|
||||
"status": "ok"
|
||||
}
|
||||
```
|
||||
@@ -54,7 +54,7 @@ The timestamp will vary.
|
||||
.\scripts\seed-db.ps1
|
||||
```
|
||||
|
||||
The seed creates a `Cerebro` project and a couple of starter memories.
|
||||
The seed creates a `Cortex` project and a couple of starter memories.
|
||||
|
||||
## MCP Endpoint
|
||||
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
# Testing Guide
|
||||
|
||||
Cerebro has two test modes:
|
||||
Cortex has two test modes:
|
||||
|
||||
- normal tests through `scripts\test.ps1`
|
||||
- local end-to-end integration tests through `scripts\test-integration.ps1`
|
||||
@@ -13,7 +13,7 @@ The test stack is isolated from the dev stack.
|
||||
|
||||
| Service | Test value |
|
||||
| --- | --- |
|
||||
| Compose project | `cerebro-test` |
|
||||
| Compose project | `cortex-test` |
|
||||
| App | <http://localhost:5217> |
|
||||
| MCP endpoint | <http://localhost:5217/mcp> |
|
||||
| PostgreSQL | `localhost:54339` |
|
||||
@@ -58,7 +58,7 @@ Or deploy without running tests:
|
||||
|
||||
## Run Tests from Visual Studio
|
||||
|
||||
1. Open `Cerebro.slnx` in Visual Studio.
|
||||
1. Open `Cortex.slnx` in Visual Studio.
|
||||
2. Start the test stack:
|
||||
|
||||
```powershell
|
||||
@@ -66,12 +66,12 @@ Or deploy without running tests:
|
||||
```
|
||||
|
||||
3. Open Test Explorer.
|
||||
4. Run any test in `Cerebro.IntegrationTests`.
|
||||
4. Run any test in `Cortex.IntegrationTests`.
|
||||
|
||||
The tests use:
|
||||
|
||||
```text
|
||||
CEREBRO_TEST_BASE_URL
|
||||
CORTEX_TEST_BASE_URL
|
||||
```
|
||||
|
||||
If that environment variable is not set, they default to:
|
||||
|
||||
@@ -54,7 +54,7 @@ Check logs:
|
||||
|
||||
This is expected when the project does not exist. Create the project first with `CreateProject`.
|
||||
|
||||
Cerebro intentionally has no default project.
|
||||
Cortex intentionally has no default project.
|
||||
|
||||
## Search Returns Nothing
|
||||
|
||||
@@ -105,7 +105,7 @@ If restore fails:
|
||||
3. Run restore from a normal PowerShell session:
|
||||
|
||||
```powershell
|
||||
dotnet restore Cerebro.slnx --configfile NuGet.Config
|
||||
dotnet restore Cortex.slnx --configfile NuGet.Config
|
||||
```
|
||||
|
||||
## Embedding Container Takes a Long Time
|
||||
|
||||
+14
-14
@@ -2,8 +2,8 @@
|
||||
|
||||
This guide covers two related workflows:
|
||||
|
||||
1. Running Cerebro integration tests from Visual Studio Test Explorer.
|
||||
2. Connecting an MCP-capable Copilot client to the Cerebro MCP server.
|
||||
1. Running Cortex integration tests from Visual Studio Test Explorer.
|
||||
2. Connecting an MCP-capable Copilot client to the Cortex MCP server.
|
||||
|
||||
## Visual Studio Test Explorer
|
||||
|
||||
@@ -11,7 +11,7 @@ Visual Studio can run the integration tests because they are ordinary xUnit test
|
||||
|
||||
### Steps
|
||||
|
||||
1. Open `Cerebro.slnx`.
|
||||
1. Open `Cortex.slnx`.
|
||||
2. Start the isolated test stack:
|
||||
|
||||
```powershell
|
||||
@@ -19,7 +19,7 @@ Visual Studio can run the integration tests because they are ordinary xUnit test
|
||||
```
|
||||
|
||||
3. In Visual Studio, open Test Explorer.
|
||||
4. Run tests under `Cerebro.IntegrationTests`.
|
||||
4. Run tests under `Cortex.IntegrationTests`.
|
||||
|
||||
The tests connect to:
|
||||
|
||||
@@ -30,12 +30,12 @@ http://localhost:5217
|
||||
Override that by setting:
|
||||
|
||||
```powershell
|
||||
$env:CEREBRO_TEST_BASE_URL = "http://localhost:5217"
|
||||
$env:CORTEX_TEST_BASE_URL = "http://localhost:5217"
|
||||
```
|
||||
|
||||
## Connecting a Copilot MCP Client
|
||||
|
||||
Cerebro uses Streamable HTTP MCP.
|
||||
Cortex uses Streamable HTTP MCP.
|
||||
|
||||
The Blazor web UI is not needed for this. It is only a browser-based helper for local testing and memory inspection.
|
||||
|
||||
@@ -60,7 +60,7 @@ If your Visual Studio installation exposes MCP server configuration through GitH
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"cerebro": {
|
||||
"cortex": {
|
||||
"type": "http",
|
||||
"url": "http://localhost:5117/mcp"
|
||||
}
|
||||
@@ -74,7 +74,7 @@ If Visual Studio asks for a URL directly, enter:
|
||||
http://localhost:5117/mcp
|
||||
```
|
||||
|
||||
If your Visual Studio build does not expose MCP server configuration, use Visual Studio for normal coding and Test Explorer, and use Visual Studio Code or another MCP-capable client for Cerebro tool calls.
|
||||
If your Visual Studio build does not expose MCP server configuration, use Visual Studio for normal coding and Test Explorer, and use Visual Studio Code or another MCP-capable client for Cortex tool calls.
|
||||
|
||||
## Visual Studio Code MCP Setup
|
||||
|
||||
@@ -91,7 +91,7 @@ Add:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"cerebro": {
|
||||
"cortex": {
|
||||
"type": "http",
|
||||
"url": "http://localhost:5117/mcp"
|
||||
}
|
||||
@@ -103,7 +103,7 @@ The same example is available at `docs/examples/vscode-mcp.dev.json`.
|
||||
|
||||
Then:
|
||||
|
||||
1. Start Cerebro:
|
||||
1. Start Cortex:
|
||||
|
||||
```powershell
|
||||
.\scripts\deploy-all.ps1
|
||||
@@ -111,7 +111,7 @@ Then:
|
||||
|
||||
2. Open the VS Code command palette.
|
||||
3. Run `MCP: List Servers`.
|
||||
4. Start or enable `cerebro`.
|
||||
4. Start or enable `cortex`.
|
||||
5. Open Chat and select/configure tools.
|
||||
|
||||
For the test instance:
|
||||
@@ -119,7 +119,7 @@ For the test instance:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"cerebro-test": {
|
||||
"cortex-test": {
|
||||
"type": "http",
|
||||
"url": "http://localhost:5217/mcp"
|
||||
}
|
||||
@@ -134,7 +134,7 @@ The same example is available at `docs/examples/vscode-mcp.test.json`.
|
||||
After connecting an MCP client:
|
||||
|
||||
```text
|
||||
Create a Cerebro project named Home.
|
||||
Create a Cortex project named Home.
|
||||
```
|
||||
|
||||
```text
|
||||
@@ -151,7 +151,7 @@ Add a todo in the Home project: buy a replacement USB-C cable.
|
||||
|
||||
## Trust and Safety
|
||||
|
||||
Cerebro is local and currently unauthenticated. Treat the endpoint as trusted-local only:
|
||||
Cortex is local and currently unauthenticated. Treat the endpoint as trusted-local only:
|
||||
|
||||
- Keep it bound to localhost for development.
|
||||
- Do not expose it to the public internet.
|
||||
|
||||
+8
-8
@@ -1,6 +1,6 @@
|
||||
# Web UI
|
||||
|
||||
Cerebro includes an optional Blazor Server web UI for local browsing and testing.
|
||||
Cortex includes an optional Blazor Server web UI for local browsing and testing.
|
||||
|
||||
It is not required for:
|
||||
|
||||
@@ -67,22 +67,22 @@ Stop:
|
||||
The web UI runs as its own Docker container:
|
||||
|
||||
```text
|
||||
cerebro-web
|
||||
cortex-web
|
||||
```
|
||||
|
||||
It uses the same database and embedding service as the MCP server:
|
||||
|
||||
```text
|
||||
cerebro-db
|
||||
cerebro-embeddings
|
||||
cortex-db
|
||||
cortex-embeddings
|
||||
```
|
||||
|
||||
The test web UI uses:
|
||||
|
||||
```text
|
||||
cerebro-test-web
|
||||
cerebro-test-db
|
||||
cerebro-test-embeddings
|
||||
cortex-test-web
|
||||
cortex-test-db
|
||||
cortex-test-embeddings
|
||||
```
|
||||
|
||||
The web UI does not expose MCP. It is a browser interface over the same local memory system.
|
||||
@@ -100,5 +100,5 @@ The script handles the profile for you:
|
||||
Manual equivalent:
|
||||
|
||||
```powershell
|
||||
docker compose --project-name cerebro --profile ui up -d --build cerebro-web
|
||||
docker compose --project-name cortex --profile ui up -d --build cortex-web
|
||||
```
|
||||
|
||||
+6
-6
@@ -1,15 +1,15 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Restoring .NET packages"
|
||||
Invoke-DotNet restore Cerebro.slnx --configfile NuGet.Config
|
||||
Invoke-DotNet restore Cortex.slnx --configfile NuGet.Config
|
||||
|
||||
Write-Step "Building Cerebro"
|
||||
Invoke-DotNet build Cerebro.slnx --configuration Release --no-restore
|
||||
Write-Step "Building Cortex"
|
||||
Invoke-DotNet build Cortex.slnx --configuration Release --no-restore
|
||||
|
||||
Write-Step "Building local Docker image"
|
||||
Assert-Docker
|
||||
Invoke-CerebroCompose build cerebro-app
|
||||
Invoke-CortexCompose build cortex-app
|
||||
|
||||
Write-Step "Building optional web UI Docker image"
|
||||
$webBuildArgs = @("--profile", "ui", "build", "cerebro-web")
|
||||
Invoke-CerebroCompose @webBuildArgs
|
||||
$webBuildArgs = @("--profile", "ui", "build", "cortex-web")
|
||||
Invoke-CortexCompose @webBuildArgs
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Starting all Cerebro services"
|
||||
Write-Step "Starting all Cortex services"
|
||||
Assert-Docker
|
||||
Invoke-CerebroCompose up -d cerebro-db cerebro-embeddings
|
||||
Invoke-CortexCompose up -d cortex-db cortex-embeddings
|
||||
|
||||
Write-Step "Waiting for embedding model health"
|
||||
Wait-HttpOk "http://localhost:8088/health" 300
|
||||
|
||||
Write-Step "Building Cerebro MCP server image"
|
||||
Invoke-CerebroCompose build cerebro-app
|
||||
Write-Step "Building Cortex MCP server image"
|
||||
Invoke-CortexCompose build cortex-app
|
||||
|
||||
Write-Step "Applying database migrations"
|
||||
Invoke-CerebroCompose run --rm cerebro-app migrate
|
||||
Invoke-CortexCompose run --rm cortex-app migrate
|
||||
|
||||
Write-Step "Starting Cerebro MCP server"
|
||||
Invoke-CerebroCompose up -d cerebro-app
|
||||
Write-Step "Starting Cortex MCP server"
|
||||
Invoke-CortexCompose up -d cortex-app
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Starting Cerebro app"
|
||||
Write-Step "Starting Cortex app"
|
||||
Assert-Docker
|
||||
Invoke-CerebroCompose up -d cerebro-db cerebro-embeddings
|
||||
Invoke-CortexCompose up -d cortex-db cortex-embeddings
|
||||
Write-Step "Waiting for embedding model health"
|
||||
Wait-HttpOk "http://localhost:8088/health" 300
|
||||
Invoke-CerebroCompose up -d --build cerebro-app
|
||||
Invoke-CortexCompose up -d --build cortex-app
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
Write-Step "Starting PostgreSQL with pgvector"
|
||||
Assert-Docker
|
||||
Invoke-CerebroCompose up -d cerebro-db
|
||||
Invoke-CortexCompose up -d cortex-db
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
Write-Step "Starting local embedding model"
|
||||
Assert-Docker
|
||||
Invoke-CerebroCompose up -d cerebro-embeddings
|
||||
Invoke-CortexCompose up -d cortex-embeddings
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Starting Cerebro test dependencies for web UI"
|
||||
Write-Step "Starting Cortex test dependencies for web UI"
|
||||
Assert-Docker
|
||||
Invoke-CerebroTestCompose up -d cerebro-test-db cerebro-test-embeddings
|
||||
Invoke-CortexTestCompose up -d cortex-test-db cortex-test-embeddings
|
||||
|
||||
Write-Step "Waiting for test embedding model health"
|
||||
Wait-HttpOk "http://localhost:8188/health" 300
|
||||
|
||||
Write-Step "Building Cerebro test app image for migrations"
|
||||
Invoke-CerebroTestCompose build cerebro-test-app
|
||||
Write-Step "Building Cortex test app image for migrations"
|
||||
Invoke-CortexTestCompose build cortex-test-app
|
||||
|
||||
Write-Step "Applying test database migrations"
|
||||
Invoke-CerebroTestCompose run --rm cerebro-test-app migrate
|
||||
Invoke-CortexTestCompose run --rm cortex-test-app migrate
|
||||
|
||||
Write-Step "Starting optional Cerebro test web UI"
|
||||
$webUpArgs = @("--profile", "ui", "up", "-d", "--build", "cerebro-test-web")
|
||||
Invoke-CerebroTestCompose @webUpArgs
|
||||
Write-Step "Starting optional Cortex test web UI"
|
||||
$webUpArgs = @("--profile", "ui", "up", "-d", "--build", "cortex-test-web")
|
||||
Invoke-CortexTestCompose @webUpArgs
|
||||
|
||||
Write-Step "Waiting for test web UI health"
|
||||
Wait-HttpOk "http://localhost:5218/health" 120
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Starting Cerebro test database and embedding model"
|
||||
Write-Step "Starting Cortex test database and embedding model"
|
||||
Assert-Docker
|
||||
Invoke-CerebroTestCompose up -d cerebro-test-db cerebro-test-embeddings
|
||||
Invoke-CortexTestCompose up -d cortex-test-db cortex-test-embeddings
|
||||
|
||||
Write-Step "Waiting for test embedding model health"
|
||||
Wait-HttpOk "http://localhost:8188/health" 300
|
||||
|
||||
Write-Step "Building Cerebro test app image"
|
||||
Invoke-CerebroTestCompose build cerebro-test-app
|
||||
Write-Step "Building Cortex test app image"
|
||||
Invoke-CortexTestCompose build cortex-test-app
|
||||
|
||||
Write-Step "Applying test database migrations"
|
||||
Invoke-CerebroTestCompose run --rm cerebro-test-app migrate
|
||||
Invoke-CortexTestCompose run --rm cortex-test-app migrate
|
||||
|
||||
Write-Step "Starting Cerebro test MCP server"
|
||||
Invoke-CerebroTestCompose up -d cerebro-test-app
|
||||
Write-Step "Starting Cortex test MCP server"
|
||||
Invoke-CortexTestCompose up -d cortex-test-app
|
||||
|
||||
Write-Step "Waiting for test MCP server health"
|
||||
Wait-HttpOk "http://localhost:5217/health" 180
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Starting Cerebro dependencies for web UI"
|
||||
Write-Step "Starting Cortex dependencies for web UI"
|
||||
Assert-Docker
|
||||
Invoke-CerebroCompose up -d cerebro-db cerebro-embeddings
|
||||
Invoke-CortexCompose up -d cortex-db cortex-embeddings
|
||||
|
||||
Write-Step "Waiting for embedding model health"
|
||||
Wait-HttpOk "http://localhost:8088/health" 300
|
||||
|
||||
Write-Step "Building Cerebro app image for migrations"
|
||||
Invoke-CerebroCompose build cerebro-app
|
||||
Write-Step "Building Cortex app image for migrations"
|
||||
Invoke-CortexCompose build cortex-app
|
||||
|
||||
Write-Step "Applying database migrations"
|
||||
Invoke-CerebroCompose run --rm cerebro-app migrate
|
||||
Invoke-CortexCompose run --rm cortex-app migrate
|
||||
|
||||
Write-Step "Starting optional Cerebro web UI"
|
||||
$webUpArgs = @("--profile", "ui", "up", "-d", "--build", "cerebro-web")
|
||||
Invoke-CerebroCompose @webUpArgs
|
||||
Write-Step "Starting optional Cortex web UI"
|
||||
$webUpArgs = @("--profile", "ui", "up", "-d", "--build", "cortex-web")
|
||||
Invoke-CortexCompose @webUpArgs
|
||||
|
||||
Write-Step "Waiting for web UI health"
|
||||
Wait-HttpOk "http://localhost:5118/health" 120
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$Script:RepoRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..")
|
||||
$Script:ComposeProject = "cerebro"
|
||||
$Script:TestComposeProject = "cerebro-test"
|
||||
$Script:ComposeProject = "cortex"
|
||||
$Script:TestComposeProject = "cortex-test"
|
||||
$Script:LocalDockerConfig = Join-Path $Script:RepoRoot ".docker"
|
||||
|
||||
New-Item -ItemType Directory -Force $Script:LocalDockerConfig | Out-Null
|
||||
@@ -20,7 +20,7 @@ function Assert-Docker {
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-CerebroCompose {
|
||||
function Invoke-CortexCompose {
|
||||
$composeArgs = $args
|
||||
|
||||
Push-Location $Script:RepoRoot
|
||||
@@ -35,7 +35,7 @@ function Invoke-CerebroCompose {
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-CerebroTestCompose {
|
||||
function Invoke-CortexTestCompose {
|
||||
$composeArgs = $args
|
||||
|
||||
Push-Location $Script:RepoRoot
|
||||
|
||||
+5
-5
@@ -7,10 +7,10 @@ param(
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
$serviceName = switch ($Service) {
|
||||
"app" { "cerebro-app" }
|
||||
"web" { "cerebro-web" }
|
||||
"db" { "cerebro-db" }
|
||||
"embeddings" { "cerebro-embeddings" }
|
||||
"app" { "cortex-app" }
|
||||
"web" { "cortex-web" }
|
||||
"db" { "cortex-db" }
|
||||
"embeddings" { "cortex-embeddings" }
|
||||
default { $null }
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@ if ($serviceName) {
|
||||
$args += $serviceName
|
||||
}
|
||||
|
||||
Invoke-CerebroCompose @args
|
||||
Invoke-CortexCompose @args
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Applying EF Core migrations"
|
||||
Invoke-DotNet run --project src/Cerebro.Api/Cerebro.Api.csproj -- migrate
|
||||
Invoke-DotNet run --project src/Cortex.Api/Cortex.Api.csproj -- migrate
|
||||
|
||||
@@ -3,15 +3,15 @@ param([switch]$Force)
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
if (-not $Force) {
|
||||
throw "This deletes the local Cerebro database volume. Re-run with -Force to continue."
|
||||
throw "This deletes the local Cortex database volume. Re-run with -Force to continue."
|
||||
}
|
||||
|
||||
Write-Step "Resetting local PostgreSQL data"
|
||||
Assert-Docker
|
||||
Invoke-CerebroCompose stop cerebro-app cerebro-db
|
||||
Invoke-CerebroCompose rm -f cerebro-db
|
||||
Invoke-CortexCompose stop cortex-app cortex-db
|
||||
Invoke-CortexCompose rm -f cortex-db
|
||||
|
||||
$volumeName = "cerebro_cerebro-postgres-data"
|
||||
$volumeName = "cortex_cortex-postgres-data"
|
||||
docker volume inspect $volumeName *> $null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
docker volume rm $volumeName
|
||||
@@ -20,4 +20,4 @@ if ($LASTEXITCODE -eq 0) {
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-CerebroCompose up -d cerebro-db
|
||||
Invoke-CortexCompose up -d cortex-db
|
||||
|
||||
@@ -3,15 +3,15 @@ param([switch]$Force)
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
if (-not $Force) {
|
||||
throw "This deletes the local Cerebro test database volume. Re-run with -Force to continue."
|
||||
throw "This deletes the local Cortex test database volume. Re-run with -Force to continue."
|
||||
}
|
||||
|
||||
Write-Step "Resetting local Cerebro test database"
|
||||
Write-Step "Resetting local Cortex test database"
|
||||
Assert-Docker
|
||||
Invoke-CerebroTestCompose stop cerebro-test-app cerebro-test-db
|
||||
Invoke-CerebroTestCompose rm -f cerebro-test-db
|
||||
Invoke-CortexTestCompose stop cortex-test-app cortex-test-db
|
||||
Invoke-CortexTestCompose rm -f cortex-test-db
|
||||
|
||||
$volumeName = "cerebro-test_cerebro-test-postgres-data"
|
||||
$volumeName = "cortex-test_cortex-test-postgres-data"
|
||||
docker volume inspect $volumeName *> $null
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
docker volume rm $volumeName
|
||||
@@ -20,4 +20,4 @@ if ($LASTEXITCODE -eq 0) {
|
||||
}
|
||||
}
|
||||
|
||||
Invoke-CerebroTestCompose up -d cerebro-test-db
|
||||
Invoke-CortexTestCompose up -d cortex-test-db
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Seeding sample data"
|
||||
Invoke-DotNet run --project src/Cerebro.Api/Cerebro.Api.csproj -- seed
|
||||
Invoke-DotNet run --project src/Cortex.Api/Cortex.Api.csproj -- seed
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Stopping Cerebro services"
|
||||
Write-Step "Stopping Cortex services"
|
||||
Assert-Docker
|
||||
Invoke-CerebroCompose stop
|
||||
Invoke-CortexCompose stop
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Stopping optional Cerebro test web UI"
|
||||
Write-Step "Stopping optional Cortex test web UI"
|
||||
Assert-Docker
|
||||
$webStopArgs = @("--profile", "ui", "stop", "cerebro-test-web")
|
||||
Invoke-CerebroTestCompose @webStopArgs
|
||||
$webStopArgs = @("--profile", "ui", "stop", "cortex-test-web")
|
||||
Invoke-CortexTestCompose @webStopArgs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Stopping Cerebro test services"
|
||||
Write-Step "Stopping Cortex test services"
|
||||
Assert-Docker
|
||||
Invoke-CerebroTestCompose stop
|
||||
Invoke-CortexTestCompose stop
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Stopping optional Cerebro web UI"
|
||||
Write-Step "Stopping optional Cortex web UI"
|
||||
Assert-Docker
|
||||
$webStopArgs = @("--profile", "ui", "stop", "cerebro-web")
|
||||
Invoke-CerebroCompose @webStopArgs
|
||||
$webStopArgs = @("--profile", "ui", "stop", "cortex-web")
|
||||
Invoke-CortexCompose @webStopArgs
|
||||
|
||||
@@ -16,9 +16,9 @@ if (-not $NoReset) {
|
||||
|
||||
try {
|
||||
Write-Step "Running integration tests"
|
||||
$env:CEREBRO_TEST_BASE_URL = "http://localhost:5217"
|
||||
$env:CORTEX_TEST_BASE_URL = "http://localhost:5217"
|
||||
|
||||
$args = @("test", "tests/Cerebro.IntegrationTests/Cerebro.IntegrationTests.csproj", "--configuration", "Release")
|
||||
$args = @("test", "tests/Cortex.IntegrationTests/Cortex.IntegrationTests.csproj", "--configuration", "Release")
|
||||
if (-not [string]::IsNullOrWhiteSpace($Filter)) {
|
||||
$args += @("--filter", $Filter)
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
. "$PSScriptRoot\lib\common.ps1"
|
||||
|
||||
Write-Step "Running tests"
|
||||
Invoke-DotNet test Cerebro.slnx --configuration Release --filter "Category!=Integration"
|
||||
Invoke-DotNet test Cortex.slnx --configuration Release --filter "Category!=Integration"
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace Cerebro.Web;
|
||||
|
||||
public sealed class CerebroWebMarker;
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ModelContextProtocol.AspNetCore" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Cortex.Core\Cortex.Core.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,18 +1,18 @@
|
||||
using Cerebro.Api.Data;
|
||||
using Cerebro.Api.Options;
|
||||
using Cerebro.Api.Services;
|
||||
using Cortex.Core.Data;
|
||||
using Cortex.Core.Options;
|
||||
using Cortex.Core.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ModelContextProtocol.Server;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.Configure<CerebroOptions>(builder.Configuration.GetSection("Cerebro"));
|
||||
builder.Services.Configure<CortexOptions>(builder.Configuration.GetSection("Cortex"));
|
||||
builder.Services.Configure<EmbeddingOptions>(builder.Configuration.GetSection("Embedding"));
|
||||
builder.Services.AddSingleton<DbClockInterceptor>();
|
||||
builder.Services.AddDbContext<CerebroDbContext>((services, options) =>
|
||||
builder.Services.AddDbContext<CortexDbContext>((services, options) =>
|
||||
{
|
||||
var connectionString = builder.Configuration.GetConnectionString("Cerebro")
|
||||
?? throw new InvalidOperationException("Connection string 'Cerebro' is missing.");
|
||||
var connectionString = builder.Configuration.GetConnectionString("Cortex")
|
||||
?? throw new InvalidOperationException("Connection string 'Cortex' is missing.");
|
||||
|
||||
options.UseNpgsql(connectionString);
|
||||
options.AddInterceptors(services.GetRequiredService<DbClockInterceptor>());
|
||||
@@ -24,7 +24,7 @@ builder.Services.AddHttpClient<IEmbeddingClient, TeiEmbeddingClient>((services,
|
||||
client.BaseAddress = new Uri(options.BaseUrl);
|
||||
});
|
||||
|
||||
builder.Services.AddScoped<ICerebroMemoryService, CerebroMemoryService>();
|
||||
builder.Services.AddScoped<ICortexMemoryService, CortexMemoryService>();
|
||||
|
||||
builder.Services
|
||||
.AddMcpServer()
|
||||
@@ -39,7 +39,7 @@ var app = builder.Build();
|
||||
if (args.Contains("migrate", StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
await using var scope = app.Services.CreateAsyncScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<CerebroDbContext>();
|
||||
var db = scope.ServiceProvider.GetRequiredService<CortexDbContext>();
|
||||
await db.Database.MigrateAsync();
|
||||
return;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ if (args.Contains("seed", StringComparer.OrdinalIgnoreCase))
|
||||
app.MapGet("/", () => Results.Redirect("/health"));
|
||||
app.MapGet("/health", () => Results.Ok(new
|
||||
{
|
||||
name = "Cerebro",
|
||||
name = "Cortex",
|
||||
status = "ok",
|
||||
utc = DateTimeOffset.UtcNow
|
||||
}));
|
||||
@@ -1,17 +1,17 @@
|
||||
using System.ComponentModel;
|
||||
using Cerebro.Api.Contracts;
|
||||
using Cerebro.Api.Services;
|
||||
using Cortex.Core.Contracts;
|
||||
using Cortex.Core.Services;
|
||||
using ModelContextProtocol.Server;
|
||||
|
||||
namespace Cerebro.Api.Tools;
|
||||
namespace Cortex.Api.Tools;
|
||||
|
||||
[McpServerToolType]
|
||||
public static class CerebroTools
|
||||
public static class CortexTools
|
||||
{
|
||||
[McpServerTool(Name = "CreateProject", UseStructuredContent = true, Destructive = false)]
|
||||
[Description("Create a new explicit Cerebro project. Items cannot be added until their project exists.")]
|
||||
[Description("Create a new explicit Cortex project. Items cannot be added until their project exists.")]
|
||||
public static Task<ProjectDto> CreateProject(
|
||||
ICerebroMemoryService memory,
|
||||
ICortexMemoryService memory,
|
||||
[Description("Human-readable project name. The stable slug is derived from this name.")] string name,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -19,9 +19,9 @@ public static class CerebroTools
|
||||
}
|
||||
|
||||
[McpServerTool(Name = "ListProjects", UseStructuredContent = true, ReadOnly = true, Destructive = false)]
|
||||
[Description("List existing Cerebro projects.")]
|
||||
[Description("List existing Cortex projects.")]
|
||||
public static Task<IReadOnlyList<ProjectDto>> ListProjects(
|
||||
ICerebroMemoryService memory,
|
||||
ICortexMemoryService memory,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return memory.ListProjectsAsync(cancellationToken);
|
||||
@@ -30,7 +30,7 @@ public static class CerebroTools
|
||||
[McpServerTool(Name = "AddItem", UseStructuredContent = true, Destructive = false)]
|
||||
[Description("Add a memory item to an existing explicit project.")]
|
||||
public static Task<MemoryItemDto> AddItem(
|
||||
ICerebroMemoryService memory,
|
||||
ICortexMemoryService memory,
|
||||
[Description("Existing project name or slug. The project must already exist.")] string project,
|
||||
[Description("One of: requirement, location, todo, note.")] string category,
|
||||
[Description("Short item title.")] string title,
|
||||
@@ -46,7 +46,7 @@ public static class CerebroTools
|
||||
[McpServerTool(Name = "FindItems", UseStructuredContent = true, ReadOnly = true, Destructive = false)]
|
||||
[Description("Find memory items with hybrid semantic and keyword search.")]
|
||||
public static Task<IReadOnlyList<SearchResultDto>> FindItems(
|
||||
ICerebroMemoryService memory,
|
||||
ICortexMemoryService memory,
|
||||
[Description("Natural language search query.")] string query,
|
||||
[Description("Project name or slug. Required unless searchAllProjects is true.")] string? project = null,
|
||||
[Description("Set true to search across all projects.")] bool searchAllProjects = false,
|
||||
@@ -60,7 +60,7 @@ public static class CerebroTools
|
||||
[McpServerTool(Name = "UpdateItem", UseStructuredContent = true, Destructive = true)]
|
||||
[Description("Update an existing memory item. Content-related changes automatically regenerate the embedding.")]
|
||||
public static Task<MemoryItemDto> UpdateItem(
|
||||
ICerebroMemoryService memory,
|
||||
ICortexMemoryService memory,
|
||||
[Description("Existing project name or slug.")] string project,
|
||||
[Description("Memory item id from find results.")] Guid id,
|
||||
[Description("Optional new category: requirement, location, todo, note.")] string? category = null,
|
||||
@@ -77,7 +77,7 @@ public static class CerebroTools
|
||||
[McpServerTool(Name = "DeleteItem", UseStructuredContent = true, Destructive = true)]
|
||||
[Description("Soft-delete an existing memory item from an explicit project.")]
|
||||
public static Task<MemoryItemDto> DeleteItem(
|
||||
ICerebroMemoryService memory,
|
||||
ICortexMemoryService memory,
|
||||
[Description("Existing project name or slug.")] string project,
|
||||
[Description("Memory item id from find results.")] Guid id,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"AllowedHosts": "localhost;127.0.0.1;cerebro-app",
|
||||
"AllowedHosts": "localhost;127.0.0.1;cortex-app",
|
||||
"ConnectionStrings": {
|
||||
"Cerebro": "Host=localhost;Port=54329;Database=cerebro;Username=cerebro;Password=cerebro_dev_password;GSS Encryption Mode=Disable"
|
||||
"Cortex": "Host=localhost;Port=54329;Database=cortex;Username=cortex;Password=cortex_dev_password;GSS Encryption Mode=Disable"
|
||||
},
|
||||
"Cerebro": {
|
||||
"Cortex": {
|
||||
"EmbeddingModel": "BAAI/bge-small-en-v1.5",
|
||||
"EmbeddingDimensions": 384
|
||||
},
|
||||
@@ -1,6 +1,6 @@
|
||||
using Cerebro.Api.Domain;
|
||||
using Cortex.Core.Domain;
|
||||
|
||||
namespace Cerebro.Api.Contracts;
|
||||
namespace Cortex.Core.Contracts;
|
||||
|
||||
public sealed record ProjectDto(Guid Id, string Name, string Slug, DateTimeOffset CreatedAt);
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="ModelContextProtocol.AspNetCore" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,9 +1,9 @@
|
||||
using Cerebro.Api.Domain;
|
||||
using Cortex.Core.Domain;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Cerebro.Api.Data;
|
||||
namespace Cortex.Core.Data;
|
||||
|
||||
public sealed class CerebroDbContext(DbContextOptions<CerebroDbContext> options) : DbContext(options)
|
||||
public sealed class CortexDbContext(DbContextOptions<CortexDbContext> options) : DbContext(options)
|
||||
{
|
||||
public DbSet<Project> Projects => Set<Project>();
|
||||
public DbSet<MemoryItem> MemoryItems => Set<MemoryItem>();
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
using Cerebro.Api.Domain;
|
||||
using Cortex.Core.Domain;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
|
||||
namespace Cerebro.Api.Data;
|
||||
namespace Cortex.Core.Data;
|
||||
|
||||
public sealed class DbClockInterceptor : SaveChangesInterceptor
|
||||
{
|
||||
@@ -1,25 +1,26 @@
|
||||
using Cerebro.Api.Services;
|
||||
using Cortex.Core.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Cerebro.Api.Data;
|
||||
namespace Cortex.Core.Data;
|
||||
|
||||
public static class SeedData
|
||||
{
|
||||
public static async Task SeedAsync(IServiceProvider services, CancellationToken cancellationToken)
|
||||
{
|
||||
var db = services.GetRequiredService<CerebroDbContext>();
|
||||
var db = services.GetRequiredService<CortexDbContext>();
|
||||
await db.Database.MigrateAsync(cancellationToken);
|
||||
|
||||
var memory = services.GetRequiredService<ICerebroMemoryService>();
|
||||
var memory = services.GetRequiredService<ICortexMemoryService>();
|
||||
var projects = await memory.ListProjectsAsync(cancellationToken);
|
||||
|
||||
if (projects.All(project => project.Slug != "cerebro"))
|
||||
if (projects.All(project => project.Slug != "cortex"))
|
||||
{
|
||||
await memory.CreateProjectAsync("Cerebro", cancellationToken);
|
||||
await memory.CreateProjectAsync("Cortex", cancellationToken);
|
||||
}
|
||||
|
||||
var existing = await memory.FindItemsAsync(
|
||||
new FindMemoryItemsRequest("Cerebro MCP server", "cerebro", false, null, 1),
|
||||
new FindMemoryItemsRequest("Cortex MCP server", "cortex", false, null, 1),
|
||||
cancellationToken);
|
||||
|
||||
if (existing.Count > 0)
|
||||
@@ -29,10 +30,10 @@ public static class SeedData
|
||||
|
||||
await memory.AddItemAsync(
|
||||
new AddMemoryItemRequest(
|
||||
"cerebro",
|
||||
"cortex",
|
||||
"requirement",
|
||||
"Cerebro runs as an HTTP MCP server",
|
||||
"The Cerebro MCP server is a .NET 10 ASP.NET Core app hosted by Kestrel and deployed locally with Docker.",
|
||||
"Cortex runs as an HTTP MCP server",
|
||||
"The Cortex MCP server is a .NET 10 ASP.NET Core app hosted by Kestrel and deployed locally with Docker.",
|
||||
["mcp", "dotnet", "docker"],
|
||||
"""{"source":"seed"}""",
|
||||
"active"),
|
||||
@@ -40,7 +41,7 @@ public static class SeedData
|
||||
|
||||
await memory.AddItemAsync(
|
||||
new AddMemoryItemRequest(
|
||||
"cerebro",
|
||||
"cortex",
|
||||
"note",
|
||||
"Embedding model choice",
|
||||
"Use BAAI/bge-small-en-v1.5 through a local Hugging Face Text Embeddings Inference container. The vector size is 384.",
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Cerebro.Api.Domain;
|
||||
namespace Cortex.Core.Domain;
|
||||
|
||||
public interface ITimestampedEntity
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Cerebro.Api.Domain;
|
||||
namespace Cortex.Core.Domain;
|
||||
|
||||
public enum MemoryCategory
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Cerebro.Api.Domain;
|
||||
namespace Cortex.Core.Domain;
|
||||
|
||||
public sealed class MemoryItem : ITimestampedEntity
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Cerebro.Api.Domain;
|
||||
namespace Cortex.Core.Domain;
|
||||
|
||||
public sealed class Project : ITimestampedEntity
|
||||
{
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
using Cerebro.Api.Data;
|
||||
using Cortex.Core.Data;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Cerebro.Api.Migrations;
|
||||
namespace Cortex.Core.Migrations;
|
||||
|
||||
[DbContext(typeof(CerebroDbContext))]
|
||||
[DbContext(typeof(CortexDbContext))]
|
||||
[Migration("20260708124000_InitialCreate")]
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
+9
-9
@@ -1,15 +1,15 @@
|
||||
using Cerebro.Api.Data;
|
||||
using Cerebro.Api.Domain;
|
||||
using Cortex.Core.Data;
|
||||
using Cortex.Core.Domain;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Cerebro.Api.Migrations;
|
||||
namespace Cortex.Core.Migrations;
|
||||
|
||||
[DbContext(typeof(CerebroDbContext))]
|
||||
public sealed class CerebroDbContextModelSnapshot : ModelSnapshot
|
||||
[DbContext(typeof(CortexDbContext))]
|
||||
public sealed class CortexDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
@@ -17,7 +17,7 @@ public sealed class CerebroDbContextModelSnapshot : ModelSnapshot
|
||||
.HasAnnotation("ProductVersion", "10.0.0")
|
||||
.HasPostgresExtension("vector");
|
||||
|
||||
modelBuilder.Entity("Cerebro.Api.Domain.Project", entity =>
|
||||
modelBuilder.Entity("Cortex.Core.Domain.Project", entity =>
|
||||
{
|
||||
entity.Property<Guid>("Id").HasColumnName("id").HasColumnType("uuid");
|
||||
entity.Property<DateTimeOffset>("CreatedAt").HasColumnName("created_at").HasColumnType("timestamp with time zone");
|
||||
@@ -29,7 +29,7 @@ public sealed class CerebroDbContextModelSnapshot : ModelSnapshot
|
||||
entity.ToTable("projects");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cerebro.Api.Domain.MemoryItem", entity =>
|
||||
modelBuilder.Entity("Cortex.Core.Domain.MemoryItem", entity =>
|
||||
{
|
||||
entity.Property<Guid>("Id").HasColumnName("id").HasColumnType("uuid");
|
||||
entity.Property<MemoryCategory>("Category").HasColumnName("category").HasMaxLength(40).HasConversion<string>();
|
||||
@@ -46,12 +46,12 @@ public sealed class CerebroDbContextModelSnapshot : ModelSnapshot
|
||||
entity.HasKey("Id");
|
||||
entity.HasIndex("DeletedAt");
|
||||
entity.HasIndex("ProjectId", "Category");
|
||||
entity.HasOne("Cerebro.Api.Domain.Project", "Project").WithMany("Items").HasForeignKey("ProjectId").OnDelete(DeleteBehavior.Cascade).IsRequired();
|
||||
entity.HasOne("Cortex.Core.Domain.Project", "Project").WithMany("Items").HasForeignKey("ProjectId").OnDelete(DeleteBehavior.Cascade).IsRequired();
|
||||
entity.Navigation("Project");
|
||||
entity.ToTable("memory_items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cerebro.Api.Domain.Project", entity =>
|
||||
modelBuilder.Entity("Cortex.Core.Domain.Project", entity =>
|
||||
{
|
||||
entity.Navigation("Items");
|
||||
});
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
namespace Cerebro.Api.Options;
|
||||
namespace Cortex.Core.Options;
|
||||
|
||||
public sealed class CerebroOptions
|
||||
public sealed class CortexOptions
|
||||
{
|
||||
public string EmbeddingModel { get; set; } = "BAAI/bge-small-en-v1.5";
|
||||
public int EmbeddingDimensions { get; set; } = 384;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Cerebro.Api.Options;
|
||||
namespace Cortex.Core.Options;
|
||||
|
||||
public sealed class EmbeddingOptions
|
||||
{
|
||||
+13
-12
@@ -1,25 +1,26 @@
|
||||
using System.Data;
|
||||
using System.Text.Json;
|
||||
using Cerebro.Api.Contracts;
|
||||
using Cerebro.Api.Data;
|
||||
using Cerebro.Api.Domain;
|
||||
using Cerebro.Api.Options;
|
||||
using Cortex.Core.Contracts;
|
||||
using Cortex.Core.Data;
|
||||
using Cortex.Core.Domain;
|
||||
using Cortex.Core.Options;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Npgsql;
|
||||
using NpgsqlTypes;
|
||||
|
||||
namespace Cerebro.Api.Services;
|
||||
namespace Cortex.Core.Services;
|
||||
|
||||
public sealed class CerebroMemoryService(
|
||||
CerebroDbContext db,
|
||||
public sealed class CortexMemoryService(
|
||||
CortexDbContext db,
|
||||
IEmbeddingClient embeddings,
|
||||
IOptions<CerebroOptions> options,
|
||||
IConfiguration configuration) : ICerebroMemoryService
|
||||
IOptions<CortexOptions> options,
|
||||
IConfiguration configuration) : ICortexMemoryService
|
||||
{
|
||||
private readonly CerebroOptions _options = options.Value;
|
||||
private readonly string _connectionString = configuration.GetConnectionString("Cerebro")
|
||||
?? throw new InvalidOperationException("Connection string 'Cerebro' is missing.");
|
||||
private readonly CortexOptions _options = options.Value;
|
||||
private readonly string _connectionString = configuration.GetConnectionString("Cortex")
|
||||
?? throw new InvalidOperationException("Connection string 'Cortex' is missing.");
|
||||
|
||||
public async Task<ProjectDto> CreateProjectAsync(string name, CancellationToken cancellationToken)
|
||||
{
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
using Cerebro.Api.Contracts;
|
||||
using Cortex.Core.Contracts;
|
||||
|
||||
namespace Cerebro.Api.Services;
|
||||
namespace Cortex.Core.Services;
|
||||
|
||||
public interface ICerebroMemoryService
|
||||
public interface ICortexMemoryService
|
||||
{
|
||||
Task<ProjectDto> CreateProjectAsync(string name, CancellationToken cancellationToken);
|
||||
Task<IReadOnlyList<ProjectDto>> ListProjectsAsync(CancellationToken cancellationToken);
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
namespace Cerebro.Api.Services;
|
||||
namespace Cortex.Core.Services;
|
||||
|
||||
public interface IEmbeddingClient
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Cerebro.Api.Services;
|
||||
namespace Cortex.Core.Services;
|
||||
|
||||
public static partial class Slug
|
||||
{
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Cerebro.Api.Options;
|
||||
using Cortex.Core.Options;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Cerebro.Api.Services;
|
||||
namespace Cortex.Core.Services;
|
||||
|
||||
public sealed class TeiEmbeddingClient(HttpClient httpClient, IOptions<EmbeddingOptions> options) : IEmbeddingClient
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace Cerebro.Api.Services;
|
||||
namespace Cortex.Core.Services;
|
||||
|
||||
public static class VectorLiteral
|
||||
{
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
@page "/Error"
|
||||
|
||||
<PageTitle>Error - Cerebro</PageTitle>
|
||||
<PageTitle>Error - Cortex</PageTitle>
|
||||
|
||||
<main class="shell">
|
||||
<section class="workspace">
|
||||
<h1>Something went wrong</h1>
|
||||
<p class="muted">Check the Cerebro web container logs for details.</p>
|
||||
<p class="muted">Check the Cortex web container logs for details.</p>
|
||||
</section>
|
||||
</main>
|
||||
+7
-7
@@ -1,19 +1,19 @@
|
||||
@page "/"
|
||||
@rendermode InteractiveServer
|
||||
@using Cerebro.Api.Contracts
|
||||
@using Cerebro.Api.Domain
|
||||
@using Cerebro.Api.Services
|
||||
@inject ICerebroMemoryService Memory
|
||||
@inject CerebroUiQueries Queries
|
||||
@using Cortex.Core.Contracts
|
||||
@using Cortex.Core.Domain
|
||||
@using Cortex.Core.Services
|
||||
@inject ICortexMemoryService Memory
|
||||
@inject CortexUiQueries Queries
|
||||
|
||||
<PageTitle>Cerebro</PageTitle>
|
||||
<PageTitle>Cortex</PageTitle>
|
||||
|
||||
<main class="app-shell">
|
||||
<aside class="sidebar">
|
||||
<div class="brand">
|
||||
<span class="brand-mark">C</span>
|
||||
<div>
|
||||
<h1>Cerebro</h1>
|
||||
<h1>Cortex</h1>
|
||||
<p>Project memory</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,15 +1,15 @@
|
||||
<Router AppAssembly="@typeof(Cerebro.Web.CerebroWebMarker).Assembly">
|
||||
<Router AppAssembly="@typeof(Cortex.Web.CortexWebMarker).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found - Cerebro</PageTitle>
|
||||
<PageTitle>Not found - Cortex</PageTitle>
|
||||
<LayoutView Layout="@typeof(Layout.MainLayout)">
|
||||
<main class="shell">
|
||||
<section class="workspace">
|
||||
<h1>Not found</h1>
|
||||
<p class="muted">That Cerebro page does not exist.</p>
|
||||
<p class="muted">That Cortex page does not exist.</p>
|
||||
</section>
|
||||
</main>
|
||||
</LayoutView>
|
||||
@@ -8,7 +8,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Cerebro.Api\Cerebro.Api.csproj" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Cortex.Core\Cortex.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,10 +1,10 @@
|
||||
using Cerebro.Api.Data;
|
||||
using Cerebro.Api.Domain;
|
||||
using Cortex.Core.Data;
|
||||
using Cortex.Core.Domain;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Cerebro.Web;
|
||||
namespace Cortex.Web;
|
||||
|
||||
public sealed class CerebroUiQueries(CerebroDbContext db)
|
||||
public sealed class CortexUiQueries(CortexDbContext db)
|
||||
{
|
||||
public async Task<IReadOnlyList<ProjectSummary>> GetProjectSummariesAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Cortex.Web;
|
||||
|
||||
public sealed class CortexWebMarker;
|
||||
@@ -1,8 +1,8 @@
|
||||
using Cerebro.Api.Data;
|
||||
using Cerebro.Api.Options;
|
||||
using Cerebro.Api.Services;
|
||||
using Cerebro.Web;
|
||||
using Cerebro.Web.Components;
|
||||
using Cortex.Core.Data;
|
||||
using Cortex.Core.Options;
|
||||
using Cortex.Core.Services;
|
||||
using Cortex.Web;
|
||||
using Cortex.Web.Components;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
@@ -10,13 +10,13 @@ var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Services.AddRazorComponents()
|
||||
.AddInteractiveServerComponents();
|
||||
|
||||
builder.Services.Configure<CerebroOptions>(builder.Configuration.GetSection("Cerebro"));
|
||||
builder.Services.Configure<CortexOptions>(builder.Configuration.GetSection("Cortex"));
|
||||
builder.Services.Configure<EmbeddingOptions>(builder.Configuration.GetSection("Embedding"));
|
||||
builder.Services.AddSingleton<DbClockInterceptor>();
|
||||
builder.Services.AddDbContext<CerebroDbContext>((services, options) =>
|
||||
builder.Services.AddDbContext<CortexDbContext>((services, options) =>
|
||||
{
|
||||
var connectionString = builder.Configuration.GetConnectionString("Cerebro")
|
||||
?? throw new InvalidOperationException("Connection string 'Cerebro' is missing.");
|
||||
var connectionString = builder.Configuration.GetConnectionString("Cortex")
|
||||
?? throw new InvalidOperationException("Connection string 'Cortex' is missing.");
|
||||
|
||||
options.UseNpgsql(connectionString);
|
||||
options.AddInterceptors(services.GetRequiredService<DbClockInterceptor>());
|
||||
@@ -28,8 +28,8 @@ builder.Services.AddHttpClient<IEmbeddingClient, TeiEmbeddingClient>((services,
|
||||
client.BaseAddress = new Uri(options.BaseUrl);
|
||||
});
|
||||
|
||||
builder.Services.AddScoped<ICerebroMemoryService, CerebroMemoryService>();
|
||||
builder.Services.AddScoped<CerebroUiQueries>();
|
||||
builder.Services.AddScoped<ICortexMemoryService, CortexMemoryService>();
|
||||
builder.Services.AddScoped<CortexUiQueries>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -40,10 +40,11 @@ if (!app.Environment.IsDevelopment())
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseAntiforgery();
|
||||
app.MapStaticAssets();
|
||||
|
||||
app.MapGet("/health", () => Results.Ok(new
|
||||
{
|
||||
name = "Cerebro Web",
|
||||
name = "Cortex Web",
|
||||
status = "ok",
|
||||
utc = DateTimeOffset.UtcNow
|
||||
}));
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Cerebro.Web": {
|
||||
"Cortex.Web": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"AllowedHosts": "localhost;127.0.0.1;cerebro-web",
|
||||
"AllowedHosts": "localhost;127.0.0.1;cortex-web",
|
||||
"ConnectionStrings": {
|
||||
"Cerebro": "Host=localhost;Port=54329;Database=cerebro;Username=cerebro;Password=cerebro_dev_password;GSS Encryption Mode=Disable"
|
||||
"Cortex": "Host=localhost;Port=54329;Database=cortex;Username=cortex;Password=cortex_dev_password;GSS Encryption Mode=Disable"
|
||||
},
|
||||
"Cerebro": {
|
||||
"Cortex": {
|
||||
"EmbeddingModel": "BAAI/bge-small-en-v1.5",
|
||||
"EmbeddingDimensions": 384
|
||||
},
|
||||
@@ -1,9 +0,0 @@
|
||||
using Xunit;
|
||||
|
||||
namespace Cerebro.IntegrationTests.Fixtures;
|
||||
|
||||
[CollectionDefinition(Name)]
|
||||
public sealed class CerebroTestCollection : ICollectionFixture<CerebroTestFixture>
|
||||
{
|
||||
public const string Name = "Cerebro test instance";
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Xunit;
|
||||
|
||||
namespace Cortex.IntegrationTests.Fixtures;
|
||||
|
||||
[CollectionDefinition(Name)]
|
||||
public sealed class CortexTestCollection : ICollectionFixture<CortexTestFixture>
|
||||
{
|
||||
public const string Name = "Cortex test instance";
|
||||
}
|
||||
+4
-4
@@ -3,15 +3,15 @@ using ModelContextProtocol.Client;
|
||||
using ModelContextProtocol.Protocol;
|
||||
using Xunit;
|
||||
|
||||
namespace Cerebro.IntegrationTests.Fixtures;
|
||||
namespace Cortex.IntegrationTests.Fixtures;
|
||||
|
||||
public sealed class CerebroTestFixture : IAsyncLifetime
|
||||
public sealed class CortexTestFixture : IAsyncLifetime
|
||||
{
|
||||
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
|
||||
private readonly HttpClient _healthClient = new();
|
||||
|
||||
public Uri BaseUrl { get; } = new(
|
||||
Environment.GetEnvironmentVariable("CEREBRO_TEST_BASE_URL") ?? "http://localhost:5217");
|
||||
Environment.GetEnvironmentVariable("CORTEX_TEST_BASE_URL") ?? "http://localhost:5217");
|
||||
|
||||
public Uri McpEndpoint => new(BaseUrl, "/mcp");
|
||||
|
||||
@@ -25,7 +25,7 @@ public sealed class CerebroTestFixture : IAsyncLifetime
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Cerebro test instance is not reachable at {BaseUrl}. Run .\\scripts\\deploy-test.ps1 first, or use .\\scripts\\test-integration.ps1.",
|
||||
$"Cortex test instance is not reachable at {BaseUrl}. Run .\\scripts\\deploy-test.ps1 first, or use .\\scripts\\test-integration.ps1.",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Cerebro.IntegrationTests.Support;
|
||||
namespace Cortex.IntegrationTests.Support;
|
||||
|
||||
public sealed record ProjectDto(
|
||||
[property: JsonPropertyName("id")] Guid Id,
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
using ModelContextProtocol.Client;
|
||||
using ModelContextProtocol.Protocol;
|
||||
|
||||
namespace Cerebro.IntegrationTests.Support;
|
||||
namespace Cortex.IntegrationTests.Support;
|
||||
|
||||
public static class McpTestClientExtensions
|
||||
{
|
||||
+9
-9
@@ -1,12 +1,12 @@
|
||||
using Cerebro.IntegrationTests.Fixtures;
|
||||
using Cerebro.IntegrationTests.Support;
|
||||
using Cortex.IntegrationTests.Fixtures;
|
||||
using Cortex.IntegrationTests.Support;
|
||||
using Xunit;
|
||||
|
||||
namespace Cerebro.IntegrationTests.Tests;
|
||||
namespace Cortex.IntegrationTests.Tests;
|
||||
|
||||
[Collection(CerebroTestCollection.Name)]
|
||||
[Collection(CortexTestCollection.Name)]
|
||||
[Trait("Category", "Integration")]
|
||||
public sealed class MemoryItemTests(CerebroTestFixture fixture)
|
||||
public sealed class MemoryItemTests(CortexTestFixture fixture)
|
||||
{
|
||||
[Fact]
|
||||
public async Task Add_item_fails_when_project_is_missing()
|
||||
@@ -29,7 +29,7 @@ public sealed class MemoryItemTests(CerebroTestFixture fixture)
|
||||
var projectName = fixture.NewProjectName("items");
|
||||
_ = await client.CreateProjectAsync(projectName);
|
||||
|
||||
var added = CerebroTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
var added = CortexTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
await client.AddItemAsync(
|
||||
projectName,
|
||||
"todo",
|
||||
@@ -41,7 +41,7 @@ public sealed class MemoryItemTests(CerebroTestFixture fixture)
|
||||
Assert.Equal("Todo", added.Category);
|
||||
Assert.Equal("BAAI/bge-small-en-v1.5", added.EmbeddingModel);
|
||||
|
||||
var updated = CerebroTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
var updated = CortexTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
await client.UpdateItemAsync(
|
||||
projectName,
|
||||
added.Id,
|
||||
@@ -51,12 +51,12 @@ public sealed class MemoryItemTests(CerebroTestFixture fixture)
|
||||
Assert.Contains("width", updated.Content);
|
||||
Assert.True(updated.UpdatedAt >= added.UpdatedAt);
|
||||
|
||||
var deleted = CerebroTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
var deleted = CortexTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
await client.DeleteItemAsync(projectName, added.Id));
|
||||
|
||||
Assert.Equal("deleted", deleted.Status);
|
||||
|
||||
var searchAfterDelete = CerebroTestFixture.ReadStructuredContent<SearchResultDto[]>(
|
||||
var searchAfterDelete = CortexTestFixture.ReadStructuredContent<SearchResultDto[]>(
|
||||
await client.FindItemsAsync("cabinet opening shelves", projectName));
|
||||
|
||||
Assert.DoesNotContain(searchAfterDelete, item => item.Id == added.Id);
|
||||
+7
-7
@@ -1,12 +1,12 @@
|
||||
using Cerebro.IntegrationTests.Fixtures;
|
||||
using Cerebro.IntegrationTests.Support;
|
||||
using Cortex.IntegrationTests.Fixtures;
|
||||
using Cortex.IntegrationTests.Support;
|
||||
using Xunit;
|
||||
|
||||
namespace Cerebro.IntegrationTests.Tests;
|
||||
namespace Cortex.IntegrationTests.Tests;
|
||||
|
||||
[Collection(CerebroTestCollection.Name)]
|
||||
[Collection(CortexTestCollection.Name)]
|
||||
[Trait("Category", "Integration")]
|
||||
public sealed class ProjectTests(CerebroTestFixture fixture)
|
||||
public sealed class ProjectTests(CortexTestFixture fixture)
|
||||
{
|
||||
[Fact]
|
||||
public async Task Create_project_then_list_projects()
|
||||
@@ -14,13 +14,13 @@ public sealed class ProjectTests(CerebroTestFixture fixture)
|
||||
await using var client = await fixture.CreateClientAsync();
|
||||
var projectName = fixture.NewProjectName("project");
|
||||
|
||||
var created = CerebroTestFixture.ReadStructuredContent<ProjectDto>(
|
||||
var created = CortexTestFixture.ReadStructuredContent<ProjectDto>(
|
||||
await client.CreateProjectAsync(projectName));
|
||||
|
||||
Assert.Equal(projectName, created.Name);
|
||||
Assert.StartsWith("it-project-", created.Slug);
|
||||
|
||||
var listed = CerebroTestFixture.ReadStructuredContent<ProjectDto[]>(
|
||||
var listed = CortexTestFixture.ReadStructuredContent<ProjectDto[]>(
|
||||
await client.CallToolAsync("ListProjects", new Dictionary<string, object?>()));
|
||||
|
||||
Assert.Contains(listed, project => project.Id == created.Id);
|
||||
+9
-9
@@ -1,12 +1,12 @@
|
||||
using Cerebro.IntegrationTests.Fixtures;
|
||||
using Cerebro.IntegrationTests.Support;
|
||||
using Cortex.IntegrationTests.Fixtures;
|
||||
using Cortex.IntegrationTests.Support;
|
||||
using Xunit;
|
||||
|
||||
namespace Cerebro.IntegrationTests.Tests;
|
||||
namespace Cortex.IntegrationTests.Tests;
|
||||
|
||||
[Collection(CerebroTestCollection.Name)]
|
||||
[Collection(CortexTestCollection.Name)]
|
||||
[Trait("Category", "Integration")]
|
||||
public sealed class SearchTests(CerebroTestFixture fixture)
|
||||
public sealed class SearchTests(CortexTestFixture fixture)
|
||||
{
|
||||
[Fact]
|
||||
public async Task Project_scoped_search_does_not_leak_between_projects()
|
||||
@@ -18,12 +18,12 @@ public sealed class SearchTests(CerebroTestFixture fixture)
|
||||
_ = await client.CreateProjectAsync(alpha);
|
||||
_ = await client.CreateProjectAsync(beta);
|
||||
|
||||
var alphaItem = CerebroTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
var alphaItem = CortexTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
await client.AddItemAsync(alpha, "location", "Charging brick", "The USB-C charging brick is in the blue backpack."));
|
||||
|
||||
_ = await client.AddItemAsync(beta, "location", "Charging brick", "The spare USB-C charging brick is in the garage drawer.");
|
||||
|
||||
var alphaResults = CerebroTestFixture.ReadStructuredContent<SearchResultDto[]>(
|
||||
var alphaResults = CortexTestFixture.ReadStructuredContent<SearchResultDto[]>(
|
||||
await client.FindItemsAsync("where is the charging brick", alpha));
|
||||
|
||||
Assert.Contains(alphaResults, result => result.Id == alphaItem.Id);
|
||||
@@ -38,12 +38,12 @@ public sealed class SearchTests(CerebroTestFixture fixture)
|
||||
|
||||
_ = await client.CreateProjectAsync(projectName);
|
||||
|
||||
var note = CerebroTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
var note = CortexTestFixture.ReadStructuredContent<MemoryItemDto>(
|
||||
await client.AddItemAsync(projectName, "note", "Shelf idea", "Use oak shelves for the reading nook."));
|
||||
|
||||
_ = await client.AddItemAsync(projectName, "todo", "Buy shelf brackets", "Buy black metal brackets for the oak shelves.");
|
||||
|
||||
var allProjects = CerebroTestFixture.ReadStructuredContent<SearchResultDto[]>(
|
||||
var allProjects = CortexTestFixture.ReadStructuredContent<SearchResultDto[]>(
|
||||
await client.FindItemsAsync("oak shelves reading nook", searchAllProjects: true, category: "note"));
|
||||
|
||||
Assert.Contains(allProjects, result => result.Id == note.Id);
|
||||
+4
-4
@@ -1,11 +1,11 @@
|
||||
using Cerebro.IntegrationTests.Fixtures;
|
||||
using Cortex.IntegrationTests.Fixtures;
|
||||
using Xunit;
|
||||
|
||||
namespace Cerebro.IntegrationTests.Tests;
|
||||
namespace Cortex.IntegrationTests.Tests;
|
||||
|
||||
[Collection(CerebroTestCollection.Name)]
|
||||
[Collection(CortexTestCollection.Name)]
|
||||
[Trait("Category", "Integration")]
|
||||
public sealed class SmokeTests(CerebroTestFixture fixture)
|
||||
public sealed class SmokeTests(CortexTestFixture fixture)
|
||||
{
|
||||
[Fact]
|
||||
public async Task Health_endpoint_is_available()
|
||||
Reference in New Issue
Block a user