feat: add extraction schema, sidebar nav, few-shot prompting, and prompt settings
Overhaul extraction pipeline with new TradeItem model, conversation flow, and dedicated extraction endpoint. Add sidebar navigation with NavMenu component and landing page. Introduce few-shot prompting service and tests. Add prompt settings and email upload specs. Update OpenSpec tooling with improved export-spec and extract-feature commands. Archive completed changes and export full specs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -53,10 +53,50 @@ builder.Services.AddOpenAIChatCompletion(
|
||||
// any AI services (like the chat completion above) that are already registered.
|
||||
builder.Services.AddKernel();
|
||||
|
||||
// Register the ExtractionPlugin so the Kernel can expose its [KernelFunction] methods
|
||||
// as tools. When the LLM sees these tools, it can decide to call them during a conversation
|
||||
// to validate extracted data. The plugin is registered as a singleton via DI.
|
||||
builder.Services.AddSingleton<ChatAgent.Api.Plugins.ExtractionPlugin>();
|
||||
// --- External API Typed HttpClients ---
|
||||
//
|
||||
// Each extraction tool wraps an external API call. We register typed HttpClients
|
||||
// so that each service gets its own HttpClient with a pre-configured base URL.
|
||||
// AddHttpClient<T>() uses IHttpClientFactory under the hood, which manages
|
||||
// HttpClient lifetimes and avoids socket exhaustion.
|
||||
|
||||
builder.Services.AddHttpClient<ChatAgent.Api.Services.CounterpartyApiClient>(client =>
|
||||
{
|
||||
client.BaseAddress = new Uri(
|
||||
builder.Configuration["ExternalApis:CounterpartyBaseUrl"] ?? "http://localhost:5000/api/counterparty");
|
||||
});
|
||||
|
||||
builder.Services.AddHttpClient<ChatAgent.Api.Services.TradeApiClient>(client =>
|
||||
{
|
||||
client.BaseAddress = new Uri(
|
||||
builder.Configuration["ExternalApis:TradeBaseUrl"] ?? "http://localhost:5000/api/trade");
|
||||
});
|
||||
|
||||
builder.Services.AddHttpClient<ChatAgent.Api.Services.CurrencyApiClient>(client =>
|
||||
{
|
||||
client.BaseAddress = new Uri(
|
||||
builder.Configuration["ExternalApis:CurrencyBaseUrl"] ?? "http://localhost:5000/api/currency");
|
||||
});
|
||||
|
||||
// --- Few-Shot Prompting Service ---
|
||||
//
|
||||
// FewShotService loads the extraction instruction template and few-shot examples
|
||||
// from disk at startup. It pre-assembles a ChatHistory prefix that is cloned
|
||||
// for each extraction request. Registered as a singleton since examples don't
|
||||
// change at runtime.
|
||||
// Resolve the examples path relative to the content root so it works correctly
|
||||
// both when running the app normally and in WebApplicationFactory test contexts.
|
||||
var examplesRelativePath = builder.Configuration["Examples:FewShotPath"] ?? "examples/extraction";
|
||||
var examplesAbsolutePath = Path.IsPathRooted(examplesRelativePath)
|
||||
? examplesRelativePath
|
||||
: Path.Combine(builder.Environment.ContentRootPath, examplesRelativePath);
|
||||
builder.Services.AddSingleton(new ChatAgent.Api.Services.FewShotService(examplesAbsolutePath));
|
||||
|
||||
// Register the ExtractionPlugin with its typed HttpClient dependencies.
|
||||
// The plugin exposes [KernelFunction] methods as tools the LLM can call
|
||||
// to look up counterparties, validate trades, currencies, and the extraction schema.
|
||||
// Scoped lifetime because it depends on typed HttpClients (which are transient).
|
||||
builder.Services.AddScoped<ChatAgent.Api.Plugins.ExtractionPlugin>();
|
||||
|
||||
// AddCors() registers Cross-Origin Resource Sharing services.
|
||||
// CORS is REQUIRED because the Blazor WASM client runs on a different origin
|
||||
|
||||
Reference in New Issue
Block a user