Showing sources coming from data providers (#559)
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Has been cancelled

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2025-09-25 19:47:18 +02:00
1 parent c3bbcacaed
commit 9587a07556
30 files changed
+223 -90

No files matched your search

@@ -1,17 +0,0 @@
namespace AIStudio.Provider;
/// <summary>
/// Data model for a source used in the response.
/// </summary>
public interface ISource
{
/// <summary>
/// The title of the source.
/// </summary>
public string Title { get; }
/// <summary>
/// The URL of the source.
/// </summary>
public string URL { get; }
}
@@ -30,7 +30,7 @@ public record ChatCompletionAnnotationStreamLine(string Id, string Object, uint
{
// Check if the annotation is of the expected type and extract the source information:
if (annotation is ChatCompletionAnnotatingURL urlAnnotation)
sources.Add(new Source(urlAnnotation.UrlCitation.Title, urlAnnotation.UrlCitation.URL));
sources.Add(new Source(urlAnnotation.UrlCitation.Title, urlAnnotation.UrlCitation.URL, SourceOrigin.LLM));
//
// Check for the unexpected annotation type of the Responses API.
@@ -46,7 +46,7 @@ public record ChatCompletionAnnotationStreamLine(string Id, string Object, uint
// we are calling the chat completion endpoint.
//
if (annotation is ResponsesAnnotatingUrlCitationData citationData)
sources.Add(new Source(citationData.Title, citationData.URL));
sources.Add(new Source(citationData.Title, citationData.URL, SourceOrigin.LLM));
}
}
@@ -32,11 +32,11 @@ public sealed record ResponsesAnnotationStreamLine(string Type, int AnnotationIn
// into that type, even though we are calling the Responses API endpoint.
//
if (this.Annotation is ChatCompletionAnnotatingURL urlAnnotation)
return [new Source(urlAnnotation.UrlCitation.Title, urlAnnotation.UrlCitation.URL)];
return [new Source(urlAnnotation.UrlCitation.Title, urlAnnotation.UrlCitation.URL, SourceOrigin.LLM)];
// Check for the expected annotation type of the Responses API:
if (this.Annotation is ResponsesAnnotatingUrlCitationData urlCitationData)
return [new Source(urlCitationData.Title, urlCitationData.URL)];
return [new Source(urlCitationData.Title, urlCitationData.URL, SourceOrigin.LLM)];
return [];
}
@@ -5,4 +5,4 @@ namespace AIStudio.Provider.Perplexity;
/// </summary>
/// <param name="Title">The title of the search result.</param>
/// <param name="URL">The URL of the search result.</param>
public sealed record SearchResult(string Title, string URL) : Source(Title, URL);
public sealed record SearchResult(string Title, string URL) : Source(Title, URL, SourceOrigin.LLM);
@@ -1,8 +0,0 @@
namespace AIStudio.Provider;
/// <summary>
/// Data model for a source used in the response.
/// </summary>
/// <param name="Title">The title of the source.</param>
/// <param name="URL">The URL of the source.</param>
public record Source(string Title, string URL) : ISource;
@@ -1,47 +0,0 @@
using System.Text;
using AIStudio.Tools.PluginSystem;
namespace AIStudio.Provider;
public static class SourceExtensions
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(SourceExtensions).Namespace, nameof(SourceExtensions));
/// <summary>
/// Converts a list of sources to a markdown-formatted string.
/// </summary>
/// <param name="sources">The list of sources to convert.</param>
/// <returns>A markdown-formatted string representing the sources.</returns>
public static string ToMarkdown(this IList<Source> sources)
{
var sb = new StringBuilder();
sb.Append("## ");
sb.AppendLine(TB("Sources"));
var sourceNum = 0;
foreach (var source in sources)
{
sb.Append($"- [{++sourceNum}] ");
sb.Append('[');
sb.Append(source.Title);
sb.Append("](");
sb.Append(source.URL);
sb.AppendLine(")");
}
return sb.ToString();
}
/// <summary>
/// Merges a list of added sources into an existing list of sources, avoiding duplicates based on URL and Title.
/// </summary>
/// <param name="sources">The existing list of sources to merge into.</param>
/// <param name="addedSources">The list of sources to add.</param>
public static void MergeSources(this IList<Source> sources, IList<ISource> addedSources)
{
foreach (var addedSource in addedSources)
if (sources.All(s => s.URL != addedSource.URL && s.Title != addedSource.Title))
sources.Add((Source)addedSource);
}
}