Skip to content

JohnWalker990/AI-Text-Adventure

Repository files navigation

JW.TextAdventure — Developer Documentation

⚠️ !! IMPORTANT !!
This project is just a little experiment to make some experience with the semantic kernel and agents. It is not for production use! At the current step it's just a prototype and a playground for myself.

Scope. This document explains what each component in the solution does, how the components interact (runtime and build‑time), and which contracts tie them together (APIs, streaming formats, data model). It also calls out notable implementation details, configuration, and gaps/TODOs discovered while reviewing the code.


1) Repository Map (Projects & Roles)

Project Type Purpose / Responsibilities Key Dependencies
JW.TA.Domain .NET class library Domain model (aggregates, entities, value objects, enums) and basic invariants EF Core attributes (data annotations)
JW.TA.Infrastructure .NET class library EF Core DbContext and persistence plumbing EF Core 9.0.8, SQL Server provider
JW.TA.Application .NET class library Application layer for slash‑command (CLI) parsing & routing; contains handlers that query the DbContext Infrastructure (DbContext), LINQ/Regex
JW.TA.Agents .NET class library LLM orchestration using Microsoft Semantic Kernel Agents; implements IGameOrchestrator (single‑turn, streaming) Microsoft.SemanticKernel.* (1.64.x), ModelContextProtocol
JW.TA.Api ASP.NET Core Web API Public HTTP API: chat streaming endpoint (NDJSON), world CRUD for MCP tools, dev seed, AOAI debug checks; DI composition root ASP.NET Core, EF Core, SK, IMcpClient (MCP)
JW.TA.MCPServer Python (FastMCP) MCP (Model Context Protocol) server exposing tools for dice/combat and persistence proxies that call the Web API; foundations for NDJSON streaming relay fastmcp, httpx, aiohttp, uvicorn
JW.TA.MCPTools Azure Functions (C# isolated) Placeholder Azure Functions host (currently a “Hello” function) intended as a future MCP tools ingress/egress point Azure Functions Worker v4
JW.TA.Client.Web Angular (esproj) Frontend (Angular) workspace; not included in detail here but CORS hints show local dev on port 51681 Angular CLI, Karma/Jasmine
JW.TA.Seed Console app Placeholder for seed/maintenance scripts
JW.TA.Contracts .NET class library Contracts placeholder (currently empty)

2) High‑Level Architecture

flowchart LR
  UI["Angular Frontend\nJW.TA.Client.Web"] -- "NDJSON POST /api/chat/stream" --> API["ASP.NET Core API\nJW.TA.Api"]

  subgraph "API Services"
    API -- "Routes to" --> ChatCtrl["ChatController\n/api/chat/stream"]
    API -- "Routes to" --> WorldCtrl["WorldController\n/api/world/*"]
    API -- "EF Core" --> DB["SQL Server"]
    ChatCtrl -- "DI" --> Orchestrator["IGameOrchestrator\n(SkGroupChatOrchestrator – JW.TA.Agents)"]
    Orchestrator -- "AOAI Chat" --> AOAI["Azure OpenAI\nChat Completions"]
    Orchestrator -. "optional: Tools via" .-> MCPClient["IMcpClient\n(Model Context Protocol)"]
  end

  subgraph "MCP (Python FastMCP)"
    MCPClient -- "HTTP /mcp" --> MCPSrv["FastMCP Server\nJW.TA.MCPServer"]
    MCPSrv --> ToolDice["MCP Tool: roll_dice / resolve_combat"]
    MCPSrv --> ToolDb["MCP Tool: db_upsert_entity / db_query"]
    ToolDb -- "REST" --> WorldCtrl
  end

  MCPSrv -. "kann NDJSON weiterleiten" .-> ChatCtrl

  subgraph "Azure Functions (optional/future)"
    AF["Azure Functions\nJW.TA.MCPTools"]:::faded
  end

  classDef faded fill:#eee,stroke:#ccc,color:#999
Loading
sequenceDiagram
  participant UI as Angular UI
  participant API as ASP.NET API (ChatController)
  participant ORCH as Orchestrator (SK Agents)
  participant AOAI as Azure OpenAI
  participant MCPc as IMcpClient
  participant MCPS as FastMCP Server
  participant TOOL as MCP Tool (z.B. db_upsert_entity)
  participant WORLD as WorldController
  participant DB as SQL Server

  UI->>API: POST /api/chat/stream {"message":"..."}
  alt CLI Command
    API->>API: Parse & Execute CLI
    API-->>UI: NDJSON {"type":"system"...} + {"type":"done"}
  else Narrative mit Tool
    API->>ORCH: RunTurnAsync()
    ORCH->>AOAI: ChatCompletion (Prompt/Turn)
    AOAI-->>ORCH: Tool-Call angefordert
    ORCH->>MCPc: Invoke tool (IMcpClient)
    MCPc->>MCPS: HTTP /mcp
    MCPS->>TOOL: Execute tool
    opt Proxy zur WebAPI/DB
      TOOL->>WORLD: POST /api/world/*
      WORLD->>DB: SQL
      DB-->>WORLD: OK
      WORLD-->>TOOL: IDs/Data
    end
    TOOL-->>MCPS: Tool-Result
    MCPS-->>MCPc: Result
    MCPc-->>ORCH: Result
    ORCH->>AOAI: Fortsetzen mit Tool-Result
    AOAI-->>ORCH: Finaler Text
    ORCH-->>API: Token-Stream
    API-->>UI: NDJSON {"type":"token"...} ... {"type":"done"}
  end
Loading

Narrative (runtime):

  1. Frontend calls POST /api/chat/stream with the player message.
  2. ChatController (API) first tries to parse slash‑commands. If it’s a CLI command, the router executes a handler and immediately streams a system block as NDJSON. If it’s regular text, the controller invokes IGameOrchestrator which streams the GM’s reply as NDJSON tokens.
  3. The orchestrator (SK Agents) talks to Azure OpenAI and returns a single, concise reply (single‑turn policy).
  4. WorldController exposes minimal CRUD/search endpoints used by external tools (like the MCP server) to persist generated content.
  5. The Python FastMCP server exposes MCP tools (db_upsert_entity, db_query, roll_dice, resolve_combat) and proxies persistence to the Web API.

3) Component Deep‑Dive

3.1 Domain Layer — JW.TA.Domain

Purpose. Clean domain model with invariants and audit fields.

Key types

  • BaseEntity / AggregateRoot: Id, CreatedAtUtc, UpdatedAtUtc, [Timestamp] RowVersion, domain events queue (in AggregateRoot).
  • Entities: Character, Item, InventoryItem (junction), Location, Monster, Quest, Encounter, CombatRound, Faction, RuleSet, GameEvent.
  • Enums: ItemType, Rarity, LocationType, QuestStatus, EncounterType, EncounterState.
  • Guard utilities for invariants (e.g., NotNullOrWhiteSpace, Min, NotNegative).

Notable design choices

  • JSON blobs for flexible attributes: many entities carry *Json strings (AttributesJson, StatsJson, LootTableJson, RewardJson, etc.) to keep schema flexible for LLM‑driven content.
  • Audit/concurrency baked into base types.

Interacts with

  • Infrastructure mapping via EF Core.
  • Application handlers query via DbContext.

⚠️ Attention: InventoryItem has no explicit key property. EF Core will require a key configuration (composite (CharacterId, ItemId)) via OnModelCreating. No configuration files are shown; you will need one.


3.2 Infrastructure — JW.TA.Infrastructure

Purpose. EF Core integration.

GameDbContext

  • Declares DbSet<> for all domain aggregates and junctions.
  • Applies configurations from assembly (placeholder hook).
  • Overrides SaveChanges/Async to apply audit timestamps via EF’s Property API; this respects the protected setters on base entities.

Interacts with

  • API registers DbContext (SQL Server).
  • Application handlers and controllers query and persist entities.

3.3 Application Layer (CLI) — JW.TA.Application

Purpose. Slash‑command parsing, routing, and execution with minimal, structured responses for the UI to render as “system” blocks.

Key flow

  • Parser (CliCommandParser): Detects lines starting with /, tokenizes (supports "quoted values" and --flag value), normalizes to CliCommand (Type, Subcommand, Flags, Args, Raw).

  • Router (CliCommandRouter): Finds the first ICliCommandHandler that supports the command and runs it.

  • Handlers:

    • Help: prints supported commands.
    • Inventory: lists items for --character <id>.
    • Skills: reads and prints AttributesJson for a character.
    • Map: show|list basic locations (optional --type, --top).
    • Save: appends a GameEvent SavePoint with a lightweight snapshot.
    • Login/Logout: MVP stubs (real auth deferred to UI/API auth).
  • Response format (CliResponse): Title, Lines, optional Footer. The API streams this as a single NDJSON “system” object.

Interacts with

  • API ChatController uses parser and router to short‑circuit chat turns for CLI commands.
  • DbContext for data retrieval and SavePoint events.

3.4 Agents / Orchestration — JW.TA.Agents

Purpose. Encapsulate GM turn orchestration using Semantic Kernel Agents with a single‑turn policy.

Key interfaces & classes

  • IGameOrchestratorRunTurnAsync(string, CancellationToken) returns token stream (IAsyncEnumerable<string>).

  • Managers to enforce “one GM reply per user message”:

    • SingleReplyRoundRobinManager (custom):

      • ShouldRequestUserInputfalse (single turn).
      • ShouldTerminate → true once a non‑user message appears after the last user message.
      • FilterResults → returns the last non‑user message after last user message.
  • SkGroupChatOrchestrator:

    • Builds SK Kernel (injected from API).
    • Creates GM agent, and optionally WorldBuilder + CombatAgent for trio mode.
    • Uses GroupChatOrchestration + the custom manager above.
    • Streams the final text by chunking to small tokens (32 chars) for NDJSON (Chunk() helper).
    • Options (AgentsOptions): TeamMode: "Single"|"Trio", MaxTurns (1 for Single, 2–3 for Trio).
  • StubGmOrchestrator: deterministic fallback if AOAI not configured (simply echoes "GM: " + message" in small chunks).

Interacts with

  • API DI resolves IGameOrchestrator to SkGroupChatOrchestrator.
  • Azure OpenAI chat completions via SK provider.
  • (Planned) MCP tools (IMcpClient registered in API for future use by agents).

ℹ️ GM prompt enforces German output for the narrative itself: "Sprich Deutsch. Du bist der Spielleiter (GM): Antworte kurz ...". The API/UI metadata is still English.


3.5 Web API — JW.TA.Api

Purpose. Public HTTP surface for the frontend and for tool integrations.

Composition root (Program.cs)

  • JSON options: enums as strings, camelCase, ignore nulls.

  • Config sources: appsettings.local.json (optional), environment variables.

  • Binds AgentsOptions from Agents section.

  • Registers IMcpClient using SSE transport (ModelContextProtocol) pointing to Mcp:BaseUrl. This is provisioned for future tool usage by agents or controllers.

  • Registers Azure OpenAI chat via SK:

    • AOAI:Endpoint (must not contain /openai per guard),
    • AOAI:Deployment,
    • AOAI:ApiKey.
  • Registers IGameOrchestrator as singleton SkGroupChatOrchestrator.

  • CORS for Angular dev on port 51681.

  • Response compression enabled.

  • DbContext (SQL Server) with migrations assembly in Infrastructure.

  • Registers CLI services (router + handlers).

  • Swagger in development.

Controllers

  • ChatController (POST /api/chat/stream):

    • Accepts: { "message": "<text>" }.

    • If the line is a CLI command (starts with /), parses and executes handler:

      • streams one NDJSON line: {"type":"system","data":{ "title":..., "lines":..., "footer":... }}, then {"type":"done"}.
    • Else invokes orchestrator, streaming lines: multiple {"type":"token","data":"..."} and finally {"type":"done"}.

    • Error cases stream {"type":"error","data":"..."} followed by {"type":"done"}.

  • WorldController (minimal persistence endpoints used by MCP tools):

    • POST /api/world/monster {name, level, stats?, loot?}{ id }
    • POST /api/world/monster/search { q: { name? }, top? }[ { id, name, level }, ... ]
    • POST /api/world/item {name, type, rarity, props?}{ id } (validates enums)
    • POST /api/world/item/search similarly
  • DevController

    • POST /api/dev/seed/basic creates a sample character, items, location, and an audit event. Returns resource IDs for quick testing.
  • DebugController

    • GET /api/debug/aoai/deployments (lists AOAI deployments by raw REST).
    • GET /api/debug/aoai/ping (asks the model to respond with “ok”).
    • ⚠️ Uses an undefined http variable. Inject HttpClient via DI: add a constructor parameter HttpClient http or [FromServices] HttpClient http in the action.

Interacts with

  • Frontend (CORS).
  • Agents (GM orchestration).
  • DbContext (persistence).
  • MCP (client registered; not yet used in controllers).

3.6 MCP Server (Python) — JW.TA.MCPServer

Purpose. A Model Context Protocol server offering tools to LLMs/agents. It also includes NDJSON streaming relay utilities for upstream sources.

Key parts

  • FastMCP app created via create_streamable_http_app(mcp, "/mcp", stateless_http=True).

  • Tools

    • roll_dice(formula, seed?) — deterministic NdM±K roller.
    • resolve_combat(attack, defense, seed) — MVP “to-hit + damage” resolver.
    • db_upsert_entity(kind, payload) — proxy to POST /api/world/{kind} on the Web API.
    • db_query(kind, q, top?) — proxy to POST /api/world/{kind}/search.
  • NDJSON relay (_stream_ndjson) Utility to open an upstream NDJSON HTTP stream and forward each line to the MCP client via ctx.report_progress(...). Accepts only standards‑compliant headers (avoids SSE specifics), with safety limits (max line size) and tolerant fallbacks if the upstream replies with JSON once.

    Currently this utility isn’t wired into a specific @mcp.tool, but it’s ready to be used if/when you want to expose a “proxy stream” tool to relay ChatController output.

  • Headers & middleware A StandardsOnlyMiddleware sets Cache-Control: no-cache, no-transform and keeps buffering off for proxies.

Interacts with

  • Web API WorldController for persistence/search.
  • (Future) Web API ChatController if you expose a stream relay tool.

Configuration

  • API_BASE_URL = "http://localhost:5000" (adjust to the API base address).
  • Uses .env if present (local‑only).
  • Run locally: python mcp_server.py (uvicorn on 127.0.0.1:8080).

3.7 Azure Functions (C# isolated) — JW.TA.MCPTools

Purpose. Placeholder Functions app named “MCP Tools”. It currently exposes only Function1 (“Welcome to Azure Functions!”).

Intended role

  • A future surface to host serverless MCP tools, or to receive Azure‑originating events/actions that must be fed into the MCP ecosystem (and possibly relayed upstream as NDJSON).

3.8 Angular Client — JW.TA.Client.Web

Purpose. Browser UI (Angular). The repo includes test scaffolding (karma.conf.js). CORS in the API allows local dev on http(s)://localhost:51681 and 127.0.0.1:51681.

Expected behavior

  • POST to /api/chat/stream and consume NDJSON:

    • {"type":"token","data":"..."}
    • {"type":"system","data":{ "title": string, "lines": string[], "footer": string? }}
    • {"type":"error","data":"..."}
    • {"type":"done"}

A simple NDJSON reader splits on \n and JSON‑parses each line.


4) Streaming & Protocols

4.1 Chat Streaming (NDJSON)

Endpoint: POST /api/chat/stream Request:

{ "message": "text from player (or /command ...)" }

Response (content type: application/x-ndjson; charset=utf-8): a sequence of newline‑delimited JSON objects:

  • LLM tokens (normal chat):

    {"type":"token","data":"partial text"}
    ...
    {"type":"done"}
  • CLI command:

    {"type":"system","data":{"title":"Inventory","lines":["3x Heiltrank (Common)","1x Eisen-Schwert (Rare)"],"footer":"Total items: 2"}}
    {"type":"done"}
  • Error:

    {"type":"error","data":"GM failed: ..."}
    {"type":"done"}

Notes

  • GM output is chunked into ~32‑char tokens by the orchestrator for a smoother stream.
  • The custom group‑chat manager ensures exactly one assistant reply per user message.

4.2 MCP Tools (HTTP)

Within the MCP server, tools use HTTP to call the Web API:

  • db_upsert_entity("monster", {...})POST /api/world/monster
  • db_query("item", {"name":"Heil"}, 10)POST /api/world/item/search

Result shape is always { "status": <http status>, "data": <parsed json or null> }.


5) Data Model (Snapshot)

classDiagram
  class Character {
    +Guid Id
    +string Name
    +int Level
    +string AttributesJson
    +decimal Gold
    +Guid? FactionId
  }
  class Item {
    +Guid Id
    +string Name
    +ItemType Type
    +Rarity Rarity
    +string PropertiesJson
  }
  class InventoryItem {
    +Guid CharacterId
    +Guid ItemId
    +int Quantity
  }
  class Location {
    +Guid Id
    +string Name
    +LocationType Type
    +string Region
    +string Description
    +Guid? ParentLocationId
  }
  class Monster {
    +Guid Id
    +string Name
    +int Level
    +string StatsJson
    +string LootTableJson
  }
  class Quest {
    +Guid Id
    +string Title
    +string Description
    +QuestStatus Status
    +Guid? AssignedToCharacterId
    +Guid? GivenByNpcId
    +string RewardJson
  }
  class Encounter {
    +Guid Id
    +EncounterType Type
    +EncounterState State
    +int Seed
    +Guid? LocationId
  }
  class CombatRound {
    +Guid Id
    +Guid EncounterId
    +int RoundNumber
    +string LogJson
  }
  class Faction {
    +Guid Id
    +string Name
    +string Description
  }
  class RuleSet {
    +Guid Id
    +string Name
    +string Version
    +bool IsActive
    +string RulesJson
  }
  class GameEvent {
    +Guid Id
    +string Type
    +string PayloadJson
    +string? ActorType
    +Guid? ActorId
    +string? CorrelationId
  }

  Character "1" -- "many" InventoryItem
  Item "1" -- "many" InventoryItem
  Location "0..1" <-- "many" Location : Parent
  Encounter "1" <-- "many" CombatRound
Loading

EF Core mapping note: add a composite key for InventoryItem:

modelBuilder.Entity<InventoryItem>()
  .HasKey(ii => new { ii.CharacterId, ii.ItemId });

6) End‑to‑End Flows (Sequences)

6.1 Player message → GM reply

sequenceDiagram
  participant UI as Angular UI
  participant API as ChatController
  participant CLI as Cli Router/Handlers
  participant GM as IGameOrchestrator
  participant AOAI as Azure OpenAI (via SK)

  UI->>API: POST /api/chat/stream {"message":"/inventory --character <id>"}
  API->>CLI: TryParse + Route
  CLI-->>API: CliResponse (Title/Lines)
  API-->>UI: {"type":"system", data:{...}}\n{"type":"done"}

  UI->>API: POST /api/chat/stream {"message":"I open the tavern door."}
  API->>GM: RunTurnAsync("I open the tavern door.")
  GM->>AOAI: ChatCompletion (SK Agents/GroupChat)
  AOAI-->>GM: "Short German narration..."
  GM-->>API: async stream of small tokens
  API-->>UI: {"type":"token","data":"..."} ... {"type":"done"}
Loading

6.2 Agent/tool writes world content (MCP proxy)

sequenceDiagram
  participant Agent as LLM/Agent (future)
  participant MCP as FastMCP Server
  participant API as WorldController
  participant DB as SQL

  Agent->>MCP: mcp.call(db_upsert_entity, "monster", {...})
  MCP->>API: POST /api/world/monster
  API->>DB: INSERT Monster
  DB-->>API: new Id
  API-->>MCP: { id: ... }
  MCP-->>Agent: { status:200, data:{ id: ... } }
Loading

7) Configuration & Environment

7.1 ASP.NET API (JW.TA.Api)

  • Azure OpenAI (required for real GM):

    • AOAI:Endpoint (e.g., https://<name>.openai.azure.com, do not include /openai)
    • AOAI:Deployment (model deployment name)
    • AOAI:ApiKey
  • MCP client:

    • Mcp:BaseUrl (e.g., http://127.0.0.1:8080/mcp)
  • Database:

    • SqlConnectionString (SQL Server)
  • Agents:

    • Agents:TeamMode = "Single" or "Trio"
    • Agents:MaxTurns = 1..n

Sample appsettings.local.json

{
  "AOAI": {
    "Endpoint": "https://<resource>.openai.azure.com",
    "Deployment": "gpt-5-mini",
    "ApiKey": "..."
  },
  "MCP": {
    "BaseUrl": "http://127.0.0.1:8080/mcp"
  },
  "Agents": {
    "TeamMode": "Trio",
    "MaxTurns": 5
  },
  "SqlConnectionString": "Server=.;Database=JW_TextAdventure;Trusted_Connection=True;TrustServerCertificate=True"
}

7.2 MCP Server (JW.TA.MCPServer)

  • API_BASE_URL in mcp_server.py → Web API base (default http://localhost:5000).

7.3 Azure Functions (JW.TA.MCPTools)

  • Currently no configuration required beyond standard Functions settings.

8) Local Development — Quickstart

  1. Prereqs

    • .NET 8 SDK, SQL Server (local), Node.js (Angular), Python 3.13 (for MCP).
  2. Database

    • Ensure SqlConnectionString points to a reachable SQL Server.
    • First run will apply migrations (see migration scope fix above).
  3. Run the API

    • cd JW.TA.Apidotnet run (defaults to http://localhost:5000)
  4. Run the MCP server (optional but useful for tool tests)

    • cd JW.TA.MCPServer → create venv, pip install -r requirements.txtpython mcp_server.py
    • Check it listens on 127.0.0.1:8080/mcp
  5. Seed minimal data

    • POST http://localhost:5000/api/dev/seed/basic
  6. Test chat (cURL)

    curl -N -H "Content-Type: application/json" \
      -d '{ "message": "/map list --top 5" }' \
      http://localhost:5000/api/chat/stream

    You should see NDJSON lines including a system block.

  7. Run Angular

    • Use your Angular dev server on port 51681 (per CORS). Implement an NDJSON reader that updates the UI progressively.

9) Extensibility Points

  • Add a CLI command

    1. Extend CliCommandType.
    2. Implement ICliCommandHandler (CanHandle and ExecuteAsync).
    3. Register the handler in DI (Program.cs).
  • Add a world entity

    1. Add a domain aggregate and EF mapping.
    2. Create endpoints in WorldController (create + search).
    3. Add MCP tools in Python to proxy to these endpoints.
  • Change GM team behavior

    • Adjust AgentsOptions (TeamMode, MaxTurns).
    • Extend SkGroupChatOrchestrator with specialized agents or per‑agent kernels.
  • Consume MCP tools from .NET

    • IMcpClient is already registered; wire it into the orchestrator or dedicated controllers to call MCP tools from C#.

10) Operational Notes & Observability

  • Audit trail: GameEvent is append‑only. CLI actions and seed logic record events.

  • Streaming hygiene:

    • HTTP response headers prevent buffering (no-transform) and set NDJSON content type.
    • The Python relay mirrors these headers if you choose to proxy streams via MCP.
  • Compression: Gzip enabled for HTTP responses (useful for non‑streaming responses).

  • Swagger: Available in Development for quick inspection of controllers.


11) Known Gaps / TODOs (from code review)

  1. EF mapping for InventoryItem Add composite key and relationships (else EF will complain about missing key).

  2. DebugController HttpClient Inject HttpClient (undefined http variable).

  3. Agents (minor compile issues)

    • In SkGroupChatOrchestrator.RunTurnAsync, linkedCts is referenced but not defined. Create a linked CTS from the method ct or remove.
    • Ensure all necessary using directives and package references match the preview packages used (Agents.Orchestration, Runtime.InProcess).
  4. Azure Functions project Currently a stub; wire to actual tools or remove until needed.

  5. Contracts project Empty; remove or populate with shared DTOs if you intend to use it between services.


12) API Reference (Quick)

POST /api/chat/stream

  • Body: { "message": string }
  • Return: NDJSON lines (token | system | error | done)

World endpoints (for MCP)

  • POST /api/world/monster{ id }
  • POST /api/world/monster/search[ { id, name, level } ]
  • POST /api/world/item{ id } (validates type, rarity)
  • POST /api/world/item/search[ { id, name, type, rarity } ]

Dev / Debug

  • POST /api/dev/seed/basic → IDs for created sample content
  • GET /api/debug/aoai/deployments → raw AOAI deployments JSON
  • GET /api/debug/aoai/ping{ ok: bool, text? | error?, message? }

13) Version & Dependency Matrix

  • .NET 8.0
  • EF Core 9.0.8 (SQL Server)
  • Semantic Kernel 1.64.0 (+ Agents preview packages)
  • ModelContextProtocol 0.3.0‑preview.4
  • Azure Functions Worker v4 (isolated, .NET 8)
  • Python 3.13 (FastMCP, aiohttp, httpx, uvicorn)
  • Angular (workspace scaffold; dev server CORS on port 51681)

14) Summary

  • The solution cleanly separates Domain, Application (CLI), Infrastructure (EF), Agents (GM orchestration), API, MCP server (tools/proxy), and Frontend concerns.
  • Chat flow is NDJSON streaming with an early CLI capture path.
  • Agents are designed for single‑turn, deterministic handoff via a custom GroupChat manager with optional team expansion.
  • MCP provides a bridge for procedural tools and persistence, enabling future agent/tool composition.
  • A small set of fixes (EF key, migration scope, HttpClient injection, a minor orchestrator variable) will make the current code production‑ready for local testing.

If you want, I can add developer‑facing README snippets (copy‑paste ready) for the root and each subproject, or provide a minimal Angular NDJSON service to plug into your UI.

About

Currently just an experiment and playground for myself to learn more about semantic kernel and MCP!

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors