@polymorphism-tech/morph-spec 6.0.0 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +367 -366
- package/docs/CHEATSHEET.md +3 -3
- package/docs/QUICKSTART.md +4 -4
- package/framework/CLAUDE.md +13 -0
- package/framework/MORPH.md +57 -36
- package/framework/agents.json +132 -127
- package/framework/commands/morph-apply.md +4 -21
- package/framework/commands/morph-archive.md +1 -1
- package/framework/commands/morph-proposal.md +2 -0
- package/framework/hooks/claude-code/core/enforce-phase-writes.js +1 -1
- package/framework/hooks/claude-code/core/protect-spec-files.js +1 -1
- package/framework/hooks/claude-code/core/state-sync.js +212 -0
- package/framework/hooks/shared/phase-utils.js +5 -4
- package/framework/hooks/shared/state-reader.js +1 -1
- package/framework/phases.json +1 -1
- package/framework/rubrics/backend.json +41 -36
- package/framework/rules/ai-agents-standards.md +45 -15
- package/framework/rules/morph-workflow.md +15 -34
- package/framework/rules/neon-standards.md +25 -26
- package/framework/schemas/tasks.schema.json +35 -0
- package/framework/skills/core/morph-apply/SKILL.md +154 -0
- package/framework/skills/core/morph-brainstorming/SKILL.md +53 -30
- package/framework/skills/core/morph-implement/SKILL.md +25 -14
- package/framework/skills/core/morph-plan/SKILL.md +91 -23
- package/framework/skills/core/morph-proposal/SKILL.md +137 -0
- package/framework/skills/core/morph-review/SKILL.md +43 -7
- package/framework/skills/core/morph-stack-scan/SKILL.md +40 -1
- package/framework/standards/STANDARDS.json +1729 -1134
- package/framework/standards/ai-agents/agent-session.md +160 -0
- package/framework/standards/ai-agents/batching.md +193 -0
- package/framework/standards/ai-agents/context-providers.md +188 -0
- package/framework/standards/ai-agents/mcp-server.md +250 -0
- package/framework/standards/ai-agents/mcp-tools.md +197 -0
- package/framework/standards/ai-agents/middleware-patterns.md +207 -0
- package/framework/standards/ai-agents/modalities-image-gen.md +173 -0
- package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -0
- package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -0
- package/framework/standards/ai-agents/modalities-vision.md +201 -0
- package/framework/standards/ai-agents/multi-agent-patterns.md +155 -0
- package/framework/standards/ai-agents/production.md +114 -258
- package/framework/standards/ai-agents/prompts-in-db.md +214 -0
- package/framework/standards/ai-agents/providers/model-registry.md +158 -0
- package/framework/standards/ai-agents/rag-custom-pgvector.md +243 -0
- package/framework/standards/ai-agents/service-tier-flex.md +135 -0
- package/framework/standards/ai-agents/setup.md +142 -316
- package/framework/standards/ai-agents/structured-output.md +249 -0
- package/framework/standards/ai-agents/sweet-spot.md +109 -0
- package/framework/standards/ai-agents/workflows.md +114 -284
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +433 -429
- package/framework/standards/backend/api/validation.md +92 -88
- package/framework/standards/backend/database/postgresql/database.md +336 -332
- package/framework/standards/backend/database/vector-search-rag.md +599 -541
- package/framework/standards/backend/dotnet/fluent-validation-vsa.md +4 -0
- package/framework/standards/backend/dotnet/result-pattern.md +4 -0
- package/framework/standards/backend/dotnet/scalar-ui.md +176 -172
- package/framework/standards/backend/dotnet/scrutor.md +4 -0
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +278 -274
- package/framework/standards/backend/integrations/asaas/asaas-api.md +260 -216
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +354 -350
- package/framework/standards/backend/integrations/neon-auth/neon-auth.md +30 -19
- package/framework/standards/backend/integrations/resend/resend-email.md +400 -385
- package/framework/standards/data/nosql/cache/redis.md +106 -97
- package/framework/standards/data/nosql/cosmos-db.md +127 -118
- package/framework/standards/data/vector-search/rag-chunking.md +113 -104
- package/framework/standards/frontend/design-system/ai-image-generation.md +4 -0
- package/framework/standards/frontend/design-system/animations.md +164 -160
- package/framework/standards/frontend/design-system/naming.md +68 -64
- package/framework/standards/frontend/gsap/gsap-core.md +14 -8
- package/framework/standards/frontend/gsap/gsap-plugins.md +26 -21
- package/framework/standards/frontend/gsap/gsap-scrolltrigger.md +9 -7
- package/framework/standards/frontend/nextjs/app-router.md +127 -123
- package/framework/standards/frontend/nextjs/components.md +136 -132
- package/framework/standards/frontend/nextjs/data-fetching.md +130 -126
- package/framework/standards/frontend/nextjs/forms.md +134 -128
- package/framework/standards/frontend/nextjs/motion-patterns.md +328 -322
- package/framework/standards/frontend/nextjs/naming-conventions.md +71 -67
- package/framework/standards/frontend/nextjs/nextjs-patterns.md +229 -225
- package/framework/standards/frontend/nextjs/project-structure.md +106 -102
- package/framework/standards/frontend/nextjs/state-management.md +76 -72
- package/framework/standards/frontend/nextjs/testing.md +115 -111
- package/framework/standards/infrastructure/docker/easypanel-deploy.md +196 -192
- package/framework/standards/infrastructure/neon/neon-pgrag.md +6 -2
- package/framework/standards/infrastructure/neon/neon-pgvector.md +4 -0
- package/framework/standards/infrastructure/neon/neon-setup.md +5 -1
- package/framework/standards/integration/mcp/mcp-tools.md +471 -462
- package/framework/templates/REGISTRY.json +1745 -1239
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -0
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -0
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -0
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -0
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -0
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -0
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -0
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -0
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -0
- package/framework/templates/docs/onboarding.md +4 -4
- package/framework/templates/tasks.template.json +17 -0
- package/package.json +89 -83
- package/src/commands/project/init.js +16 -0
- package/src/commands/validation/validate-feature.js +1 -1
- package/src/core/paths/output-schema.js +6 -6
- package/src/core/state/state-manager.js +1 -1
- package/src/core/templates/template-registry.js +289 -256
- package/src/lib/detectors/design-system-detector.js +1 -1
- package/src/lib/generators/context-generator.js +516 -518
- package/src/lib/generators/scaffold-generator.js +23 -26
- package/src/lib/installers/memory-installer.js +138 -0
- package/src/lib/phase-chain/phase-validator.js +4 -4
- package/src/lib/risk-detector.js +80 -0
- package/src/lib/tasks/tasks-json-parser.js +185 -0
- package/src/scripts/setup-infra.js +25 -0
- package/src/utils/hooks-installer.js +59 -10
- package/framework/standards/infrastructure/neon/neon-semantic-kernel.md +0 -310
- package/framework/templates/integrations/semantic-kernel-neon.cs +0 -125
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
# Neon Semantic Kernel Vector Store Standard
|
|
2
|
-
|
|
3
|
-
> **Scope:** neon, dotnet-vsa
|
|
4
|
-
> **Layer:** 2 (on keyword)
|
|
5
|
-
> **Keywords:** semantic kernel, vector store, PostgresVectorStore, VectorStoreTextSearch, MAF
|
|
6
|
-
> **Load When:** semantic kernel postgres vector keywords detected
|
|
7
|
-
|
|
8
|
-
Stack: .NET VSA + Neon Serverless Postgres + Semantic Kernel
|
|
9
|
-
|
|
10
|
-
## Core Rules
|
|
11
|
-
|
|
12
|
-
- ALWAYS call `UseVector()` on `NpgsqlDataSourceBuilder` -- without it the vector store fails silently
|
|
13
|
-
- ALWAYS use `AddPostgresVectorStore()` for DI registration -- handles datasource lifecycle
|
|
14
|
-
- NEVER mix pgvector-dotnet `Vector` type with SK `ReadOnlyMemory<float>` -- SK uses its own mapping
|
|
15
|
-
- ALWAYS annotate data model properties with `[VectorStoreKey]`, `[VectorStoreData]`, `[VectorStoreVector]`
|
|
16
|
-
- Use `PostgresCollection<TKey, TRecord>` for typed collection access
|
|
17
|
-
|
|
18
|
-
## NuGet Packages
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
dotnet add package Microsoft.SemanticKernel.Connectors.PgVector --prerelease
|
|
22
|
-
dotnet add package Microsoft.SemanticKernel.Connectors.OpenAI
|
|
23
|
-
dotnet add package Npgsql
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## PostgresVectorStore Initialization
|
|
27
|
-
|
|
28
|
-
### Via Dependency Injection (Recommended)
|
|
29
|
-
|
|
30
|
-
```csharp
|
|
31
|
-
using Microsoft.Extensions.DependencyInjection;
|
|
32
|
-
using Microsoft.SemanticKernel;
|
|
33
|
-
using Npgsql;
|
|
34
|
-
|
|
35
|
-
var builder = WebApplication.CreateBuilder(args);
|
|
36
|
-
|
|
37
|
-
// Option 1: Connection string (UseVector applied automatically)
|
|
38
|
-
builder.Services.AddPostgresVectorStore(
|
|
39
|
-
builder.Configuration.GetConnectionString("DefaultConnection")!);
|
|
40
|
-
|
|
41
|
-
// Option 2: Manual NpgsqlDataSource (full control)
|
|
42
|
-
builder.Services.AddSingleton<NpgsqlDataSource>(sp =>
|
|
43
|
-
{
|
|
44
|
-
var dataSourceBuilder = new NpgsqlDataSourceBuilder(
|
|
45
|
-
builder.Configuration.GetConnectionString("DefaultConnection"));
|
|
46
|
-
dataSourceBuilder.UseVector();
|
|
47
|
-
return dataSourceBuilder.Build();
|
|
48
|
-
});
|
|
49
|
-
builder.Services.AddPostgresVectorStore();
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Direct Construction
|
|
53
|
-
|
|
54
|
-
```csharp
|
|
55
|
-
using Microsoft.SemanticKernel.Connectors.PgVector;
|
|
56
|
-
using Npgsql;
|
|
57
|
-
|
|
58
|
-
var dataSourceBuilder = new NpgsqlDataSourceBuilder(connectionString);
|
|
59
|
-
dataSourceBuilder.UseVector();
|
|
60
|
-
var dataSource = dataSourceBuilder.Build();
|
|
61
|
-
|
|
62
|
-
var vectorStore = new PostgresVectorStore(dataSource, ownsDataSource: true);
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## Data Model Definition
|
|
66
|
-
|
|
67
|
-
Annotate your record type with SK vector store attributes:
|
|
68
|
-
|
|
69
|
-
```csharp
|
|
70
|
-
using System;
|
|
71
|
-
using Microsoft.Extensions.VectorData;
|
|
72
|
-
|
|
73
|
-
public class KnowledgeEntry
|
|
74
|
-
{
|
|
75
|
-
[VectorStoreKey(StorageName = "id")]
|
|
76
|
-
public Guid Id { get; set; }
|
|
77
|
-
|
|
78
|
-
[VectorStoreData(StorageName = "title")]
|
|
79
|
-
public string Title { get; set; } = string.Empty;
|
|
80
|
-
|
|
81
|
-
[VectorStoreData(StorageName = "content")]
|
|
82
|
-
public string Content { get; set; } = string.Empty;
|
|
83
|
-
|
|
84
|
-
[VectorStoreData(StorageName = "source")]
|
|
85
|
-
public string? Source { get; set; }
|
|
86
|
-
|
|
87
|
-
[VectorStoreData(StorageName = "created_at")]
|
|
88
|
-
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
|
|
89
|
-
|
|
90
|
-
[VectorStoreVector(
|
|
91
|
-
Dimensions: 1536,
|
|
92
|
-
DistanceFunction = DistanceFunction.CosineDistance,
|
|
93
|
-
IndexKind = IndexKind.Hnsw,
|
|
94
|
-
StorageName = "embedding")]
|
|
95
|
-
public ReadOnlyMemory<float>? Embedding { get; set; }
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
This maps to the following Postgres table (auto-created by `EnsureCollectionExistsAsync`):
|
|
100
|
-
|
|
101
|
-
```sql
|
|
102
|
-
CREATE TABLE IF NOT EXISTS public."knowledge_entries" (
|
|
103
|
-
"id" UUID PRIMARY KEY NOT NULL,
|
|
104
|
-
"title" TEXT,
|
|
105
|
-
"content" TEXT,
|
|
106
|
-
"source" TEXT,
|
|
107
|
-
"created_at" TIMESTAMPTZ,
|
|
108
|
-
"embedding" VECTOR(1536)
|
|
109
|
-
);
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## Collection Operations
|
|
113
|
-
|
|
114
|
-
```csharp
|
|
115
|
-
using Microsoft.SemanticKernel.Connectors.PgVector;
|
|
116
|
-
|
|
117
|
-
// Get a typed collection
|
|
118
|
-
var collection = vectorStore.GetCollection<Guid, KnowledgeEntry>("knowledge_entries");
|
|
119
|
-
|
|
120
|
-
// Create table if it doesn't exist (includes HNSW index)
|
|
121
|
-
await collection.EnsureCollectionExistsAsync();
|
|
122
|
-
|
|
123
|
-
// Upsert a record
|
|
124
|
-
var entry = new KnowledgeEntry
|
|
125
|
-
{
|
|
126
|
-
Id = Guid.NewGuid(),
|
|
127
|
-
Title = "Neon Overview",
|
|
128
|
-
Content = "Neon is a serverless Postgres platform...",
|
|
129
|
-
Source = "docs",
|
|
130
|
-
Embedding = new ReadOnlyMemory<float>(embeddingVector)
|
|
131
|
-
};
|
|
132
|
-
await collection.UpsertAsync(entry);
|
|
133
|
-
|
|
134
|
-
// Get by key
|
|
135
|
-
var retrieved = await collection.GetAsync(entry.Id);
|
|
136
|
-
|
|
137
|
-
// Delete
|
|
138
|
-
await collection.DeleteAsync(entry.Id);
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## Embedding Generation with OpenAI
|
|
142
|
-
|
|
143
|
-
```csharp
|
|
144
|
-
using Microsoft.SemanticKernel;
|
|
145
|
-
using Microsoft.SemanticKernel.Connectors.OpenAI;
|
|
146
|
-
using Microsoft.SemanticKernel.Embeddings;
|
|
147
|
-
|
|
148
|
-
// Register embedding service
|
|
149
|
-
builder.Services.AddOpenAITextEmbeddingGeneration(
|
|
150
|
-
modelId: "text-embedding-3-small",
|
|
151
|
-
apiKey: builder.Configuration["OpenAI:ApiKey"]!);
|
|
152
|
-
|
|
153
|
-
// Generate embeddings
|
|
154
|
-
public class EmbeddingService(ITextEmbeddingGenerationService embeddingService)
|
|
155
|
-
{
|
|
156
|
-
public async Task<ReadOnlyMemory<float>> GenerateAsync(string text)
|
|
157
|
-
{
|
|
158
|
-
var embeddings = await embeddingService.GenerateEmbeddingsAsync([text]);
|
|
159
|
-
return embeddings[0];
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
public async Task<IList<ReadOnlyMemory<float>>> GenerateBatchAsync(IList<string> texts)
|
|
163
|
-
{
|
|
164
|
-
return await embeddingService.GenerateEmbeddingsAsync(texts);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## VectorStoreTextSearch Usage
|
|
170
|
-
|
|
171
|
-
`VectorStoreTextSearch<T>` provides a high-level search API that automatically generates embeddings for queries:
|
|
172
|
-
|
|
173
|
-
```csharp
|
|
174
|
-
using Microsoft.Extensions.VectorData;
|
|
175
|
-
using Microsoft.SemanticKernel.Data;
|
|
176
|
-
|
|
177
|
-
// Create text search from collection + embedding service
|
|
178
|
-
var textSearch = new VectorStoreTextSearch<KnowledgeEntry>(
|
|
179
|
-
collection,
|
|
180
|
-
embeddingGenerationService);
|
|
181
|
-
|
|
182
|
-
// Search with natural language
|
|
183
|
-
var query = "How does Neon branching work?";
|
|
184
|
-
KernelSearchResults<TextSearchResult> results = await textSearch.GetTextSearchResultsAsync(
|
|
185
|
-
query, new() { Top = 5, Skip = 0 });
|
|
186
|
-
|
|
187
|
-
await foreach (TextSearchResult result in results.Results)
|
|
188
|
-
{
|
|
189
|
-
Console.WriteLine($"Name: {result.Name}");
|
|
190
|
-
Console.WriteLine($"Value: {result.Value}");
|
|
191
|
-
Console.WriteLine($"Link: {result.Link}");
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Use as Kernel Plugin (RAG in Prompts)
|
|
196
|
-
|
|
197
|
-
```csharp
|
|
198
|
-
using Microsoft.SemanticKernel;
|
|
199
|
-
using Microsoft.SemanticKernel.Data;
|
|
200
|
-
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
|
|
201
|
-
|
|
202
|
-
var kernel = builder.Build();
|
|
203
|
-
|
|
204
|
-
// Register text search as a plugin
|
|
205
|
-
var searchPlugin = textSearch.CreateWithGetTextSearchResults("KnowledgeSearch");
|
|
206
|
-
kernel.Plugins.Add(searchPlugin);
|
|
207
|
-
|
|
208
|
-
// Use in prompt with automatic retrieval
|
|
209
|
-
var promptTemplate = """
|
|
210
|
-
{{#with (KnowledgeSearch-GetTextSearchResults query)}}
|
|
211
|
-
{{#each this}}
|
|
212
|
-
Name: {{Name}}
|
|
213
|
-
Value: {{Value}}
|
|
214
|
-
---
|
|
215
|
-
{{/each}}
|
|
216
|
-
{{/with}}
|
|
217
|
-
|
|
218
|
-
Based on the above context, answer: {{query}}
|
|
219
|
-
""";
|
|
220
|
-
|
|
221
|
-
var function = KernelFunctionFactory.CreateFromPrompt(
|
|
222
|
-
new PromptTemplateConfig
|
|
223
|
-
{
|
|
224
|
-
Template = promptTemplate,
|
|
225
|
-
TemplateFormat = "handlebars"
|
|
226
|
-
},
|
|
227
|
-
new HandlebarsPromptTemplateFactory());
|
|
228
|
-
|
|
229
|
-
var result = await kernel.InvokeAsync(function,
|
|
230
|
-
new KernelArguments { ["query"] = "How does Neon branching work?" });
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
## Integration with MAF Agents
|
|
234
|
-
|
|
235
|
-
Use the vector store as a plugin for ChatCompletionAgent to give agents vector memory:
|
|
236
|
-
|
|
237
|
-
```csharp
|
|
238
|
-
using Microsoft.SemanticKernel;
|
|
239
|
-
using Microsoft.SemanticKernel.Agents;
|
|
240
|
-
using Microsoft.SemanticKernel.Data;
|
|
241
|
-
|
|
242
|
-
// Build kernel with vector search plugin
|
|
243
|
-
var kernelBuilder = Kernel.CreateBuilder();
|
|
244
|
-
kernelBuilder.AddOpenAIChatCompletion("gpt-4o", apiKey);
|
|
245
|
-
kernelBuilder.AddOpenAITextEmbeddingGeneration("text-embedding-3-small", apiKey);
|
|
246
|
-
var kernel = kernelBuilder.Build();
|
|
247
|
-
|
|
248
|
-
// Register vector search as a kernel plugin
|
|
249
|
-
var searchPlugin = textSearch.CreateWithGetTextSearchResults("KnowledgeBase");
|
|
250
|
-
kernel.Plugins.Add(searchPlugin);
|
|
251
|
-
|
|
252
|
-
// Create agent with vector memory
|
|
253
|
-
var agent = new ChatCompletionAgent
|
|
254
|
-
{
|
|
255
|
-
Name = "KnowledgeAgent",
|
|
256
|
-
Instructions = """
|
|
257
|
-
You are a knowledge assistant. Use the KnowledgeBase plugin to search for
|
|
258
|
-
relevant information before answering questions. Always cite your sources.
|
|
259
|
-
""",
|
|
260
|
-
Kernel = kernel,
|
|
261
|
-
Arguments = new KernelArguments(
|
|
262
|
-
new OpenAIPromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() })
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
// Agent automatically calls vector search when needed
|
|
266
|
-
await foreach (var message in agent.InvokeAsync(chatHistory))
|
|
267
|
-
{
|
|
268
|
-
Console.WriteLine(message.Content);
|
|
269
|
-
}
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
## Service Registration Summary
|
|
273
|
-
|
|
274
|
-
```csharp
|
|
275
|
-
// Program.cs -- complete registration
|
|
276
|
-
var builder = WebApplication.CreateBuilder(args);
|
|
277
|
-
|
|
278
|
-
// 1. Vector store (Neon + pgvector)
|
|
279
|
-
builder.Services.AddPostgresVectorStore(
|
|
280
|
-
builder.Configuration.GetConnectionString("DefaultConnection")!);
|
|
281
|
-
|
|
282
|
-
// 2. Embedding generation
|
|
283
|
-
builder.Services.AddOpenAITextEmbeddingGeneration(
|
|
284
|
-
modelId: "text-embedding-3-small",
|
|
285
|
-
apiKey: builder.Configuration["OpenAI:ApiKey"]!);
|
|
286
|
-
|
|
287
|
-
// 3. Chat completion (for agents)
|
|
288
|
-
builder.Services.AddOpenAIChatCompletion(
|
|
289
|
-
modelId: "gpt-4o",
|
|
290
|
-
apiKey: builder.Configuration["OpenAI:ApiKey"]!);
|
|
291
|
-
|
|
292
|
-
// 4. Application services
|
|
293
|
-
builder.Services.AddSingleton<EmbeddingService>();
|
|
294
|
-
builder.Services.AddSingleton(sp =>
|
|
295
|
-
{
|
|
296
|
-
var vectorStore = sp.GetRequiredService<PostgresVectorStore>();
|
|
297
|
-
return vectorStore.GetCollection<Guid, KnowledgeEntry>("knowledge_entries");
|
|
298
|
-
});
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
## Common Mistakes
|
|
302
|
-
|
|
303
|
-
| Wrong | Right | Why |
|
|
304
|
-
|-------|-------|-----|
|
|
305
|
-
| Missing `UseVector()` on data source | Always call `dataSourceBuilder.UseVector()` | Vector type mapping fails without it |
|
|
306
|
-
| Using `float[]` for vector property | `ReadOnlyMemory<float>` with `[VectorStoreVector]` | SK connector expects its own vector types |
|
|
307
|
-
| No `StorageName` on attributes | Set `StorageName` for snake_case columns | C# PascalCase won't match Postgres columns |
|
|
308
|
-
| Creating collection without `EnsureCollectionExistsAsync` | Call before first upsert/search | Table and index won't exist |
|
|
309
|
-
| Hardcoded embedding dimensions | Match `Dimensions` to your model (1536 for ada-002/3-small) | Mismatch causes insertion errors |
|
|
310
|
-
| Using pgvector-dotnet `Vector` with SK | Use `ReadOnlyMemory<float>` | SK has its own type mapping layer |
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// SEMANTIC KERNEL + NEON PGVECTOR SETUP TEMPLATE
|
|
3
|
-
// Generated by MORPH Framework
|
|
4
|
-
// ============================================================
|
|
5
|
-
|
|
6
|
-
using Microsoft.Extensions.DependencyInjection;
|
|
7
|
-
using Microsoft.Extensions.VectorData;
|
|
8
|
-
using Microsoft.SemanticKernel;
|
|
9
|
-
using Microsoft.SemanticKernel.Connectors.PgVector;
|
|
10
|
-
using Microsoft.SemanticKernel.Connectors.OpenAI;
|
|
11
|
-
using Microsoft.SemanticKernel.Embeddings;
|
|
12
|
-
using Npgsql;
|
|
13
|
-
|
|
14
|
-
#nullable disable
|
|
15
|
-
|
|
16
|
-
namespace {{NAMESPACE}}.Infrastructure.AI;
|
|
17
|
-
|
|
18
|
-
// ============================================================
|
|
19
|
-
// 1. DATA MODEL — annotated for Semantic Kernel vector store
|
|
20
|
-
// ============================================================
|
|
21
|
-
|
|
22
|
-
public class KnowledgeEntry
|
|
23
|
-
{
|
|
24
|
-
[VectorStoreKey(StorageName = "id")]
|
|
25
|
-
public Guid Id { get; set; }
|
|
26
|
-
|
|
27
|
-
[VectorStoreData(StorageName = "title")]
|
|
28
|
-
public string Title { get; set; } = string.Empty;
|
|
29
|
-
|
|
30
|
-
[VectorStoreData(StorageName = "content", IsFullTextSearchable = true)]
|
|
31
|
-
public string Content { get; set; } = string.Empty;
|
|
32
|
-
|
|
33
|
-
[VectorStoreData(StorageName = "source")]
|
|
34
|
-
public string? Source { get; set; }
|
|
35
|
-
|
|
36
|
-
[VectorStoreVector(Dimensions: 1536, DistanceFunction.CosineSimilarity, StorageName = "embedding")]
|
|
37
|
-
public ReadOnlyMemory<float> Embedding { get; set; }
|
|
38
|
-
|
|
39
|
-
[VectorStoreData(StorageName = "created_at")]
|
|
40
|
-
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ============================================================
|
|
44
|
-
// 2. SERVICE REGISTRATION — add to Program.cs
|
|
45
|
-
// ============================================================
|
|
46
|
-
|
|
47
|
-
public static class SemanticKernelExtensions
|
|
48
|
-
{
|
|
49
|
-
public static IServiceCollection AddSemanticKernelWithNeon(
|
|
50
|
-
this IServiceCollection services,
|
|
51
|
-
string neonConnectionString,
|
|
52
|
-
string openAiApiKey,
|
|
53
|
-
string embeddingModel = "text-embedding-3-small")
|
|
54
|
-
{
|
|
55
|
-
// Neon PostgreSQL data source with pgvector
|
|
56
|
-
services.AddSingleton<NpgsqlDataSource>(sp =>
|
|
57
|
-
{
|
|
58
|
-
var builder = new NpgsqlDataSourceBuilder(neonConnectionString);
|
|
59
|
-
builder.UseVector();
|
|
60
|
-
return builder.Build();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Semantic Kernel with OpenAI + Postgres vector store
|
|
64
|
-
services.AddKernel();
|
|
65
|
-
|
|
66
|
-
services.AddOpenAITextEmbeddingGeneration(embeddingModel, openAiApiKey);
|
|
67
|
-
|
|
68
|
-
services.AddPostgresVectorStore();
|
|
69
|
-
|
|
70
|
-
// VectorStoreTextSearch for natural language queries
|
|
71
|
-
services.AddSingleton<VectorStoreTextSearch<KnowledgeEntry>>(sp =>
|
|
72
|
-
{
|
|
73
|
-
var vectorStore = sp.GetRequiredService<IVectorStore>();
|
|
74
|
-
var collection = vectorStore.GetCollection<Guid, KnowledgeEntry>("knowledge_entries");
|
|
75
|
-
var embeddingGenerator = sp.GetRequiredService<ITextEmbeddingGenerationService>();
|
|
76
|
-
|
|
77
|
-
return new VectorStoreTextSearch<KnowledgeEntry>(
|
|
78
|
-
collection, embeddingGenerator);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
return services;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// ============================================================
|
|
86
|
-
// SETUP INSTRUCTIONS
|
|
87
|
-
// ============================================================
|
|
88
|
-
//
|
|
89
|
-
// 1. Install NuGet packages:
|
|
90
|
-
//
|
|
91
|
-
// dotnet add package Microsoft.SemanticKernel.Connectors.PgVector --prerelease
|
|
92
|
-
// dotnet add package Microsoft.SemanticKernel.Connectors.OpenAI
|
|
93
|
-
// dotnet add package Npgsql
|
|
94
|
-
//
|
|
95
|
-
// 2. Add to Program.cs:
|
|
96
|
-
//
|
|
97
|
-
// builder.Services.AddSemanticKernelWithNeon(
|
|
98
|
-
// builder.Configuration.GetConnectionString("DefaultConnection")!,
|
|
99
|
-
// builder.Configuration["OpenAI:ApiKey"]!);
|
|
100
|
-
//
|
|
101
|
-
// 3. Create the database table (Neon SQL):
|
|
102
|
-
//
|
|
103
|
-
// CREATE EXTENSION IF NOT EXISTS vector;
|
|
104
|
-
// CREATE TABLE knowledge_entries (
|
|
105
|
-
// id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
106
|
-
// title TEXT NOT NULL,
|
|
107
|
-
// content TEXT NOT NULL,
|
|
108
|
-
// source TEXT,
|
|
109
|
-
// embedding vector(1536),
|
|
110
|
-
// created_at TIMESTAMPTZ DEFAULT now()
|
|
111
|
-
// );
|
|
112
|
-
// CREATE INDEX ON knowledge_entries USING hnsw (embedding vector_cosine_ops);
|
|
113
|
-
//
|
|
114
|
-
// 4. Use in a service or MAF agent:
|
|
115
|
-
//
|
|
116
|
-
// public class SearchService(VectorStoreTextSearch<KnowledgeEntry> search)
|
|
117
|
-
// {
|
|
118
|
-
// public async Task<IReadOnlyList<KnowledgeEntry>> SearchAsync(string query)
|
|
119
|
-
// {
|
|
120
|
-
// var results = await search.SearchAsync(query, new() { Top = 5 });
|
|
121
|
-
// return await results.Results.Select(r => r.Record).ToListAsync();
|
|
122
|
-
// }
|
|
123
|
-
// }
|
|
124
|
-
//
|
|
125
|
-
// ============================================================
|