Skip to content

Commit 700c473

Browse files
mecemisclaude
andcommitted
docs: redraw the architecture diagram as two focused views
The single diagram mixed reference direction with runtime call flow, which produced crossing edges and a dependency chain floating apart from the rest. It also hid the four tools behind '4 kernel functions', and its palette read badly on a dark page. Split into a layer view (arrows are references) and a runtime view (arrows are calls), named the tools, and moved indexing out to the RAG section where it already had a diagram. Both render legibly against GitHub light and dark. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKgfqZwc1ZragsJwwkFcdz
1 parent 2bdb089 commit 700c473

1 file changed

Lines changed: 63 additions & 46 deletions

File tree

README.md

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -70,64 +70,81 @@ PostgreSQL 17 + pgvector · EF Core 10 · Docker Compose · xUnit v3 · GitHub A
7070

7171
## Architecture
7272

73-
Four layers, each depending only on the one below it. No microservices, no message bus, no CQRS —
74-
the interesting part of this problem is the agent, and everything else stays out of its way.
73+
Four projects, each depending only on the one beneath it. No microservices, no message bus, no
74+
CQRS — the interesting part of this problem is the agent, and everything else stays out of its way.
7575

7676
```mermaid
7777
flowchart TB
78-
client([HTTP client])
78+
api["<b>OperationsCopilot.Api</b> · host<br/><br/>POST /api/chat · test console · OpenAPI · health"]
79+
agent["<b>OperationsCopilot.Agent</b> · orchestration<br/><br/>ChatCompletionAgent · the four tools<br/>tool-call filter · system prompt"]
80+
infra["<b>OperationsCopilot.Infrastructure</b> · adapters<br/><br/>EF Core · pgvector search · chunk + index<br/>model clients · provider selection"]
81+
domain["<b>OperationsCopilot.Domain</b> · core<br/><br/>entities · query and chat contracts · interfaces<br/><i>no dependencies on anything above</i>"]
7982
80-
subgraph api["OperationsCopilot.Api — host"]
81-
endpoint["POST /api/chat<br/>validation · problem details · OpenAPI"]
82-
end
83+
api ==> agent ==> infra ==> domain
8384
84-
subgraph agent["OperationsCopilot.Agent — orchestration"]
85-
sk["ChatCompletionAgent<br/>FunctionChoiceBehavior.Auto"]
86-
tools["4 kernel functions"]
87-
filter["ToolCallTrackingFilter<br/>timing · budget · telemetry"]
88-
end
85+
classDef layer fill:#f7f7f5,stroke:#9a9a90,stroke-width:1px,color:#22221e,rx:6,ry:6
86+
classDef core fill:#eef1f6,stroke:#5b7aa8,stroke-width:1px,color:#16202e,rx:6,ry:6
87+
class api,agent,infra layer
88+
class domain core
89+
```
8990

90-
subgraph infra["OperationsCopilot.Infrastructure — adapters"]
91-
repo["OperationsRepository<br/>EF Core"]
92-
search["PgVectorKnowledgeBaseSearch<br/>cosine &lt;=&gt; + HNSW"]
93-
embed["IEmbeddingService<br/>Ollama · Azure · deterministic"]
94-
indexer["KnowledgeBaseIndexer<br/>chunk · embed · upsert"]
95-
end
91+
Arrows are *references*, not calls. The direction never reverses, which is what keeps the domain
92+
free of EF Core, Semantic Kernel and HTTP.
93+
94+
**Why the agent sits above infrastructure.** It orchestrates adapters, so it is the higher layer.
95+
Its plugins depend only on the domain interfaces (`IOperationsRepository`, `IKnowledgeBaseSearch`),
96+
which is what keeps them testable without a database. The one reference into infrastructure exists
97+
so the agent can ask `AiClientFactory` for a model client — endpoints, credentials and provider
98+
choice stay on the infrastructure side, and the agent only knows how to wire a client into
99+
Semantic Kernel.
96100

97-
subgraph domain["OperationsCopilot.Domain — core"]
98-
entities["Entities · queries · chat contracts · interfaces"]
101+
### What talks to what
102+
103+
The same system at run time. Here the arrows *are* calls, and the boundary worth noticing is
104+
which boxes sit outside the process.
105+
106+
```mermaid
107+
flowchart LR
108+
client([" client<br/>console or curl "])
109+
endpoint["POST /api/chat"]
110+
brain["Semantic Kernel agent"]
111+
chat{{"chat model<br/>Ollama · Azure OpenAI"}}
112+
113+
subgraph tools["the four tools — the model picks"]
114+
direction TB
115+
low["GetLowStockProducts"]
116+
sales["GetSalesSummary"]
117+
prod["GetProductDetails"]
118+
kb["SearchKnowledgeBase"]
99119
end
100120
101-
db[("PostgreSQL 17 + pgvector<br/>products · inventory · sales · document_chunks")]
102-
aoai{{"Ollama (local)<br/>or Azure OpenAI<br/>chat + embeddings"}}
103-
docs[/"docs/knowledge-base/*.md"/]
104-
105-
client --> endpoint --> sk
106-
sk <--> tools
107-
tools -.observed by.-> filter
108-
sk <--> aoai
109-
tools --> repo
110-
tools --> search
111-
search --> embed --> aoai
112-
docs --> indexer --> embed
113-
indexer --> db
114-
repo --> db
115-
search --> db
116-
117-
agent -.depends on.-> infra -.depends on.-> domain
118-
119-
classDef store fill:#e8f0fe,stroke:#4285f4,color:#111
120-
classDef ext fill:#fff4e5,stroke:#f9a825,color:#111
121+
embed{{"embedding model<br/>Ollama · Azure · deterministic"}}
122+
db[("PostgreSQL 17 + pgvector<br/>products · inventory · sales<br/>document_chunks")]
123+
124+
client --> endpoint --> brain
125+
brain <--> chat
126+
brain --> tools
127+
low --> db
128+
sales --> db
129+
prod --> db
130+
kb --> embed
131+
kb --> db
132+
133+
classDef ext fill:#fdf1dd,stroke:#c8860d,stroke-width:1px,color:#3d2a05
134+
classDef store fill:#e7eef8,stroke:#3f6fa8,stroke-width:1px,color:#122135
135+
classDef node fill:#f7f7f5,stroke:#9a9a90,color:#22221e
136+
class chat,embed ext
121137
class db store
122-
class aoai ext
138+
class client,endpoint,brain,low,sales,prod,kb node
139+
style tools fill:#fcfcfb,stroke:#c9c9c1,color:#5c5c55
123140
```
124141

125-
**Why the agent sits above infrastructure.** The agent orchestrates adapters, so it is the higher
126-
layer. Its plugins depend only on the domain interfaces (`IOperationsRepository`,
127-
`IKnowledgeBaseSearch`), which is what keeps them testable without a database. The reference to
128-
the infrastructure project exists so the agent can ask `AiClientFactory` for a model client —
129-
endpoints, credentials and provider choice stay on the infrastructure side, and the agent only
130-
knows how to wire a client into Semantic Kernel.
142+
Only two kinds of box leave the process: the models and the database. Chat and embeddings are
143+
drawn separately because they are two separate settings — one can run locally while the other
144+
runs in Azure. See [model providers](#model-providers).
145+
146+
Indexing is not shown here; it runs once at startup and is covered in
147+
[the RAG pipeline](#the-rag-pipeline).
131148

132149
---
133150

0 commit comments

Comments
 (0)