diff --git a/docs/ssot/PLAN.md b/docs/ssot/PLAN.md index 10b247c..666227d 100644 --- a/docs/ssot/PLAN.md +++ b/docs/ssot/PLAN.md @@ -193,7 +193,7 @@ Everything2Everything의 북극성은 "세상의 모든 변환을 원자(atomic) **Exit Criteria:** API 키 입력 시 PDF 요약·이미지 캡션·번역이 동작하고, 키가 없으면 AI 페어만 사라지고 모든 기존 변환은 100% 동작. -### P6 · 매트릭스 자동 극대화 + 헤드리스 CLI `effort:L` `risk:medium` `status:planned` · depends: P5 +### P6 · 매트릭스 자동 극대화 + 헤드리스 CLI `effort:L` `risk:medium` `status:in_progress` · depends: P5 **목표:** 앞 단계에서 쌓인 모든 엣지를 그래프가 자동 합성해 진짜 N×M·다방향을 완성하고(video→mp3→txt AI전사 등), 헤드리스 CLI로 자동화·스크립팅을 개방한다. **산출물:** diff --git a/docs/ssot/_data/status.json b/docs/ssot/_data/status.json index 09b3b0f..7aa979c 100644 --- a/docs/ssot/_data/status.json +++ b/docs/ssot/_data/status.json @@ -5,7 +5,7 @@ "P3": "in_progress", "P4": "in_progress", "P5": "in_progress", - "P6": "planned", + "P6": "in_progress", "P7": "in_progress", "P8": "planned" } diff --git a/docs/ssot/index.html b/docs/ssot/index.html index 824d6d3..bfd9371 100644 --- a/docs/ssot/index.html +++ b/docs/ssot/index.html @@ -445,7 +445,7 @@ footer{border-top:1px solid var(--line2);margin-top:60px;padding:30px 0;color:va
P6
매트릭스 자동 극대화 + 헤드리스 CLI
앞 단계에서 쌓인 모든 엣지를 그래프가 자동 합성해 진짜 N×M·다방향을 완성하고(video→mp3→txt AI전사 등), 헤드리스 CLI로 자동화·스크립팅을 개방한다.
-
예정LRISK mediumdepends · P5
+
진행중LRISK mediumdepends · P5

산출물

diff --git a/src/Everything2Everything.Core/Providers/ProviderRegistry.cs b/src/Everything2Everything.Core/Providers/ProviderRegistry.cs index 09dcd68..c2054d1 100644 --- a/src/Everything2Everything.Core/Providers/ProviderRegistry.cs +++ b/src/Everything2Everything.Core/Providers/ProviderRegistry.cs @@ -55,6 +55,18 @@ public sealed class ProviderRegistry } public IReadOnlyList OutputsForInput(string inputExtension) + { + // 그래프 reachability(transitive closure)로 멀티홉 변환까지 노출한다 (예: json→xlsx, svg→jpg). + // 동일 포맷(self-edge: txt→txt AI, png→png 압축)은 '다른 형식으로 변환' 목록에서 제외. + var input = ConversionPair.Normalize(inputExtension); + return _graph.ReachableOutputs(input, maxHops: 3, allowLossy: true) + .Where(o => !string.Equals(o, input, StringComparison.OrdinalIgnoreCase)) + .OrderBy(e => e, StringComparer.OrdinalIgnoreCase) + .ToList(); + } + + /// 1홉 직접 출력만 (그래프 reachability 이전의 좁은 목록이 필요한 곳용). + public IReadOnlyList DirectOutputsForInput(string inputExtension) { var input = ConversionPair.Normalize(inputExtension); return _outputsByInput.TryGetValue(input, out var list) diff --git a/src/Everything2Everything.Tests/ConversionGraphTests.cs b/src/Everything2Everything.Tests/ConversionGraphTests.cs index 7843a78..1a186a0 100644 --- a/src/Everything2Everything.Tests/ConversionGraphTests.cs +++ b/src/Everything2Everything.Tests/ConversionGraphTests.cs @@ -207,4 +207,20 @@ public class RegistryGraphIntegrationTests var path = graph.FindBestPath(".png", ".pdf", maxHops: 3); Assert.NotNull(path); } + + [Fact] + public void OutputsForInput_ExposesMultiHopReachable() + { + var reg = Everything2EverythingBootstrap.CreateDefault().Providers; + + var jsonOut = reg.OutputsForInput(".json"); + Assert.Contains(".csv", jsonOut); // 직접 + Assert.Contains(".xlsx", jsonOut); // 멀티홉 json→csv→xlsx + Assert.DoesNotContain(".json", jsonOut); // 동일 포맷 self 제외 + + var svgOut = reg.OutputsForInput(".svg"); + Assert.Contains(".png", svgOut); // 직접 + Assert.Contains(".jpg", svgOut); // 멀티홉 svg→png→jpg + Assert.Contains(".pdf", svgOut); // 직접 + } }