1
0
Fork 0
Everything2Everything/src/Everything2Everything.Tests/LlmProviderTests.cs
Yun Chan b76d51f3c1 feat: AI 텍스트 Provider (LlmProvider) — OpenAI/Anthropic 요약·번역·교정
AI를 '키 없으면 비활성되는 부가 엣지'로 통합. 기존 변환에 무영향, 일반 변환과 충돌 없는 txt↔txt/md↔md self-edge만 노출.

- IChatClient + OpenAiChatClient/AnthropicChatClient (HttpClient 직접, SDK 의존 0)
- LlmProvider: summarize/translate/proofread/custom, ISettingsStore 키 + 환경변수(OPENAI_API_KEY/ANTHROPIC_API_KEY) 폴백
- CheckAvailabilityAsync 게이트: 키 없으면 NotReady → 그래프에서 실행 비활성
- ConvertOptions.Ai (백엔드/모델/작업/대상언어)
- 테스트 5개 (키 게이트·프롬프트 구성·그래프 엣지) — 총 34개 통과
2026-06-01 13:21:14 +09:00

68 lines
2.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Everything2Everything.Core;
using Everything2Everything.Core.Converters;
using Xunit;
namespace Everything2Everything.Tests;
public class LlmProviderTests
{
private sealed class FakeStore : ISettingsStore
{
private readonly Dictionary<string, string> _d = new();
public string? Get(string key) => _d.TryGetValue(key, out var v) ? v : null;
public void Set(string key, string value) => _d[key] = value;
public void Remove(string key) => _d.Remove(key);
public bool Contains(string key) => _d.ContainsKey(key);
}
private static bool EnvHasKey()
=> !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("OPENAI_API_KEY"))
|| !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY"));
[Fact]
public async Task NoKey_IsNotReady()
{
if (EnvHasKey()) return; // 환경변수 키가 있으면 이 단언은 건너뜀
var p = new LlmProvider(new FakeStore());
var a = await p.CheckAvailabilityAsync();
Assert.False(a.IsReady);
}
[Fact]
public async Task WithKey_IsReady()
{
var store = new FakeStore();
store.Set("openai.apikey", "sk-test-key");
var p = new LlmProvider(store);
var a = await p.CheckAvailabilityAsync();
Assert.True(a.IsReady);
}
[Fact]
public void BuildPrompt_Translate_IncludesTargetLanguage()
{
var (system, user) = LlmProvider.BuildPrompt(
new AiOptions { Task = "translate", TargetLanguage = "일본어" }, "hello");
Assert.Contains("일본어", system);
Assert.Equal("hello", user);
}
[Fact]
public void BuildPrompt_Summarize_MentionsSummary()
{
var (system, _) = LlmProvider.BuildPrompt(new AiOptions { Task = "summarize" }, "text");
Assert.Contains("요약", system);
}
[Fact]
public void DefaultGraph_HasAiTextSelfEdge()
{
var graph = Everything2EverythingBootstrap.CreateDefault().Providers.Graph;
// AI self-edge(txt→txt)가 그래프에 존재 — 키 없으면 실행 시 NotReady로 비활성되지만 엣지는 등록됨
Assert.NotNull(graph.FindBestPath(".txt", ".txt"));
Assert.NotNull(graph.FindBestPath(".md", ".md"));
}
}