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:
75
tests/ChatAgent.Api.Tests/FewShotServiceTests.cs
Normal file
75
tests/ChatAgent.Api.Tests/FewShotServiceTests.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
// FewShotServiceTests.cs -- Tests for the FewShotService that loads few-shot
|
||||
// examples from disk and assembles ChatHistory prefixes.
|
||||
|
||||
using ChatAgent.Api.Services;
|
||||
using ChatAgent.Shared.Models;
|
||||
|
||||
namespace ChatAgent.Api.Tests;
|
||||
|
||||
public class FewShotServiceTests
|
||||
{
|
||||
// Path to the examples folder from the test bin directory.
|
||||
// WebApplicationFactory resolves content root to the API project,
|
||||
// but for direct unit tests we resolve from the test assembly location.
|
||||
private static string GetExamplesPath()
|
||||
{
|
||||
// Navigate from test bin/Debug/net9.0/ up to the repo root, then into examples/
|
||||
var testDir = AppContext.BaseDirectory;
|
||||
var repoRoot = Path.GetFullPath(Path.Combine(testDir, "..", "..", "..", "..", ".."));
|
||||
return Path.Combine(repoRoot, "examples", "extraction");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_LoadsInstructionTemplateAndExamples()
|
||||
{
|
||||
var service = new FewShotService(GetExamplesPath());
|
||||
|
||||
// Should have: 1 system message + 3 examples × 2 messages each = 7 messages
|
||||
Assert.Equal(7, service.PrefixMessageCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CloneWithEmail_AppendsEmailAsUserMessage()
|
||||
{
|
||||
var service = new FewShotService(GetExamplesPath());
|
||||
|
||||
var history = service.CloneWithEmail("<html><body>Test email</body></html>");
|
||||
|
||||
// Prefix (7) + 1 email user message = 8
|
||||
Assert.Equal(8, history.Count);
|
||||
// Last message should be the email
|
||||
Assert.Equal("<html><body>Test email</body></html>", history.Last().Content);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CloneWithEmailAndMessages_AppendsEmailAndFollowUps()
|
||||
{
|
||||
var service = new FewShotService(GetExamplesPath());
|
||||
|
||||
var followUp = new List<ChatMessage>
|
||||
{
|
||||
new() { Role = "assistant", Content = "Which counterparty?" },
|
||||
new() { Role = "user", Content = "Option 1" }
|
||||
};
|
||||
|
||||
var history = service.CloneWithEmailAndMessages("<html>email</html>", followUp);
|
||||
|
||||
// Prefix (7) + 1 email + 2 follow-up = 10
|
||||
Assert.Equal(10, history.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CloneWithEmail_DoesNotMutatePrefix()
|
||||
{
|
||||
var service = new FewShotService(GetExamplesPath());
|
||||
|
||||
// Clone twice — second clone should not include the first email
|
||||
var history1 = service.CloneWithEmail("email 1");
|
||||
var history2 = service.CloneWithEmail("email 2");
|
||||
|
||||
Assert.Equal(8, history1.Count);
|
||||
Assert.Equal(8, history2.Count);
|
||||
Assert.Equal("email 1", history1.Last().Content);
|
||||
Assert.Equal("email 2", history2.Last().Content);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user