Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<Project>
<PropertyGroup>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>


<PropertyGroup Condition="'$(IsPackable)' == 'true'">
<!-- Ensure all packable projects include the repository LICENSE -->
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<!-- Emit XML documentation for public APIs in packaged libraries -->
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup Condition="'$(IsPackable)' == 'true'">
<!-- Include the root LICENSE in the package at the top level -->
<None Include="$(MSBuildThisFileDirectory)LICENSE" Pack="true" PackagePath="" Visible="false" />
Expand Down
8 changes: 8 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project>
<!-- Apply after project evaluation so $(IsTestProject) is available -->
<PropertyGroup Condition="'$(IsTestProject)' == 'true'">
<NoWarn>$(NoWarn);1591;CS1591</NoWarn>
<WarningsNotAsErrors>$(WarningsNotAsErrors);1591;CS1591</WarningsNotAsErrors>
</PropertyGroup>
</Project>

6 changes: 6 additions & 0 deletions src/Coven.Agents.OpenAI/AgentMaxLengthWindowPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@ public sealed class AgentMaxLengthWindowPolicy : IWindowPolicy<AgentAfferentChun
{
private readonly int _max;

/// <summary>
/// Creates a policy that emits when the total length of recent chunks reaches the maximum.
/// </summary>
/// <param name="max">Maximum total characters across the current window; must be greater than zero.</param>
public AgentMaxLengthWindowPolicy(int max)
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0);
_max = max;
}

/// <inheritdoc />
public int MinChunkLookback => 1;

/// <inheritdoc />
public bool ShouldEmit(StreamWindow<AgentAfferentChunk> window)
{
int total = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/Coven.Agents.OpenAI/AgentParagraphWindowPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ namespace Coven.Agents.OpenAI;
/// </summary>
public sealed class AgentParagraphWindowPolicy : IWindowPolicy<AgentAfferentChunk>
{
/// <inheritdoc />
public int MinChunkLookback => 2;

/// <inheritdoc />
public bool ShouldEmit(StreamWindow<AgentAfferentChunk> window)
{
StringBuilder stringBuilder = new();
Expand Down
7 changes: 6 additions & 1 deletion src/Coven.Agents.OpenAI/AgentThoughtMaxLengthWindowPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@ public sealed class AgentThoughtMaxLengthWindowPolicy : IWindowPolicy<AgentAffer
{
private readonly int _max;

/// <summary>
/// Creates a policy that emits when the total length of recent thought chunks reaches the maximum.
/// </summary>
/// <param name="max">Maximum total characters across the current thought window; must be greater than zero.</param>
public AgentThoughtMaxLengthWindowPolicy(int max)
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0);
_max = max;
}

/// <inheritdoc />
public int MinChunkLookback => 1;

/// <inheritdoc />
public bool ShouldEmit(StreamWindow<AgentAfferentThoughtChunk> window)
{
int total = 0;
Expand All @@ -35,4 +41,3 @@ public bool ShouldEmit(StreamWindow<AgentAfferentThoughtChunk> window)
return false;
}
}

3 changes: 2 additions & 1 deletion src/Coven.Agents.OpenAI/AgentThoughtParagraphWindowPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ namespace Coven.Agents.OpenAI;
/// </summary>
public sealed class AgentThoughtParagraphWindowPolicy : IWindowPolicy<AgentAfferentThoughtChunk>
{
/// <inheritdoc />
public int MinChunkLookback => 2;

/// <inheritdoc />
public bool ShouldEmit(StreamWindow<AgentAfferentThoughtChunk> window)
{
StringBuilder stringBuilder = new();
Expand All @@ -32,4 +34,3 @@ public bool ShouldEmit(StreamWindow<AgentAfferentThoughtChunk> window)
return concatenatedWindow.EndsWith("\r\n\r\n", StringComparison.Ordinal) || concatenatedWindow.EndsWith("\n\n", StringComparison.Ordinal);
}
}

3 changes: 2 additions & 1 deletion src/Coven.Agents.OpenAI/AgentThoughtSentenceWindowPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ namespace Coven.Agents.OpenAI;
public sealed class AgentThoughtSentenceWindowPolicy : IWindowPolicy<AgentAfferentThoughtChunk>
{
// 4 chunks should be generous for windowing sentence termination
/// <inheritdoc />
public int MinChunkLookback => 4;

/// <inheritdoc />
public bool ShouldEmit(StreamWindow<AgentAfferentThoughtChunk> window)
{
StringBuilder sb = new();
Expand Down Expand Up @@ -44,4 +46,3 @@ private static bool EndsWithSentenceBoundary(StringBuilder sb)
return c is '.' or '!' or '?';
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ namespace Coven.Agents.OpenAI;
/// </summary>
public sealed class AgentThoughtSummaryMarkerWindowPolicy : IWindowPolicy<AgentAfferentThoughtChunk>
{
/// <inheritdoc />
public int MinChunkLookback => 10;

/// <inheritdoc />
public bool ShouldEmit(StreamWindow<AgentAfferentThoughtChunk> window)
{
StringBuilder stringBuilder = new();
Expand Down
8 changes: 8 additions & 0 deletions src/Coven.Agents.OpenAI/AgentThoughtSummaryShatterPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ private static class Grammar
public static readonly string[] _paragraphBoundaries = ["\r\n\r\n", "\n\n", "\r\n"];
}

/// <summary>
/// Splits an <see cref="AgentThought"/> into up to two entries at the first detected summary marker boundary.
/// </summary>
/// <param name="entry">The source agent entry.</param>
/// <returns>
/// Zero or more <see cref="AgentEntry"/> instances: at most two <see cref="AgentThought"/> parts
/// when a boundary is present; otherwise no output.
/// </returns>
public IEnumerable<AgentEntry> Shatter(AgentEntry entry)
{
if (entry is not AgentThought thought || string.IsNullOrEmpty(thought.Text))
Expand Down
6 changes: 6 additions & 0 deletions src/Coven.Agents.OpenAI/Coven.Agents.OpenAI.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<IsPackable>true</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageId>$(MSBuildProjectName)</PackageId>
<Description>OpenAI agent integration for Coven.</Description>
<Authors>Coven</Authors>
<PackageTags>coven;agents;openai;llm;integration</PackageTags>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 3 additions & 1 deletion src/Coven.Agents.OpenAI/ReasoningEffort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ namespace Coven.Agents.OpenAI;
/// </summary>
public enum ReasoningEffort
{
/// <summary>Minimal additional compute for reasoning.</summary>
Low,
/// <summary>Balanced additional compute for reasoning.</summary>
Medium,
/// <summary>Maximum additional compute for reasoning.</summary>
High
}

6 changes: 6 additions & 0 deletions src/Coven.Agents/Coven.Agents.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<IsPackable>true</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageId>$(MSBuildProjectName)</PackageId>
<Description>Agent abstractions and helpers for Coven.</Description>
<Authors>Coven</Authors>
<PackageTags>coven;agents;abstractions</PackageTags>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Coven.Core.Streaming\Coven.Core.Streaming.csproj" />
Expand Down
7 changes: 6 additions & 1 deletion src/Coven.Chat.Console/Coven.Chat.Console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<IsPackable>true</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageId>$(MSBuildProjectName)</PackageId>
<Description>Console chat adapter for Coven (stdin/stdout).</Description>
<Authors>Coven</Authors>
<PackageTags>coven;agents;chat;console;adapter</PackageTags>
</PropertyGroup>

<ItemGroup>
Expand All @@ -12,4 +18,3 @@
</ItemGroup>

</Project>

6 changes: 6 additions & 0 deletions src/Coven.Chat.Discord/Coven.Chat.Discord.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<IsPackable>true</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageId>$(MSBuildProjectName)</PackageId>
<Description>Discord chat adapter for Coven using Discord.Net.</Description>
<Authors>Coven</Authors>
<PackageTags>coven;agents;chat;discord;adapter</PackageTags>
</PropertyGroup>

<ItemGroup>
Expand Down
7 changes: 4 additions & 3 deletions src/Coven.Chat.Discord/DiscordScrivener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ internal sealed class DiscordScrivener : IScrivener<DiscordEntry>
private readonly ILogger _logger;

/// <summary>
///
/// Wraps a keyed inner scrivener and forwards outbound efferent messages to Discord.
/// </summary>
/// <param name="scrivener"></param>
/// <param name="discordClient"></param>
/// <param name="scrivener">The keyed inner <see cref="IScrivener{TJournalEntryType}"/> used for storage.</param>
/// <param name="discordClient">The gateway connection for sending messages to Discord.</param>
/// <param name="logger">Logger for diagnostic breadcrumbs.</param>
/// <remarks> Because we are what we utilize, ensure that the inner scrivener is keyed in DI.</remarks>
public DiscordScrivener([FromKeyedServices("Coven.InternalDiscordScrivener")] IScrivener<DiscordEntry> scrivener, DiscordGatewayConnection discordClient, ILogger<DiscordScrivener> logger)
{
Expand Down
12 changes: 12 additions & 0 deletions src/Coven.Chat.Discord/DiscordTransmuter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ namespace Coven.Chat.Discord;
/// </summary>
public class DiscordTransmuter : IBiDirectionalTransmuter<DiscordEntry, ChatEntry>
{
/// <summary>
/// Transmutes Discord-afferent entries into chat entries.
/// </summary>
/// <param name="Input">The source Discord entry.</param>
/// <param name="cancellationToken">A cancellation token.</param>
/// <returns>The mapped <see cref="ChatEntry"/>.</returns>
public Task<ChatEntry> TransmuteAfferent(DiscordEntry Input, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Expand All @@ -20,6 +26,12 @@ public Task<ChatEntry> TransmuteAfferent(DiscordEntry Input, CancellationToken c
};
}

/// <summary>
/// Transmutes chat-efferent entries into Discord entries.
/// </summary>
/// <param name="Output">The source chat entry.</param>
/// <param name="cancellationToken">A cancellation token.</param>
/// <returns>The mapped <see cref="DiscordEntry"/>.</returns>
public Task<DiscordEntry> TransmuteEfferent(ChatEntry Output, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Expand Down
6 changes: 6 additions & 0 deletions src/Coven.Chat/Coven.Chat.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<IsPackable>true</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageId>$(MSBuildProjectName)</PackageId>
<Description>Chat primitives and windowing integration for Coven.</Description>
<Authors>Coven</Authors>
<PackageTags>coven;agents;chat;windowing;journal</PackageTags>
</PropertyGroup>

<ItemGroup>
Expand Down
20 changes: 17 additions & 3 deletions src/Coven.Chat/Shattering/ChatChunkMaxLengthShatterPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@
namespace Coven.Chat.Shattering;

/// <summary>
/// Splits long chat text into <= max-length ChatChunk segments.
/// Applies to ChatOutgoingDraft and ChatChunk; other entries are ignored.
/// Splits long chat text into segments with length less than or equal to the configured maximum.
/// Applies to <see cref="ChatEfferentDraft"/> and <see cref="ChatChunk"/>; other entries are ignored.
/// </summary>
public sealed class ChatChunkMaxLengthShatterPolicy : IShatterPolicy<ChatEntry>
{
private readonly int _max;

/// <summary>
/// Creates a new shatter policy.
/// </summary>
/// <param name="max">Maximum characters per emitted chunk. Must be greater than zero.</param>
public ChatChunkMaxLengthShatterPolicy(int max)
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0);
_max = max;
}

/// <summary>
/// Splits supported entries into chunks not exceeding the configured maximum length.
/// </summary>
/// <param name="entry">The input entry to consider.</param>
/// <returns>
/// Zero or more <see cref="ChatEntry"/> instances representing the shattered output.
/// For unsupported entry types, yields nothing.
/// </returns>
public IEnumerable<ChatEntry> Shatter(ChatEntry entry)
{
switch (entry)
Expand All @@ -38,6 +50,9 @@ public IEnumerable<ChatEntry> Shatter(ChatEntry entry)
}
}

/// <summary>
/// Helper that splits raw text into fixed-size parts.
/// </summary>
private IEnumerable<string> Split(string? text)
{
string s = text ?? string.Empty;
Expand All @@ -57,4 +72,3 @@ private IEnumerable<string> Split(string? text)
}
}
}

7 changes: 7 additions & 0 deletions src/Coven.Chat/Shattering/ChatParagraphShatterPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ namespace Coven.Chat.Shattering;
/// </summary>
public sealed class ChatParagraphShatterPolicy : IShatterPolicy<ChatEntry>
{
/// <summary>
/// Splits supported draft entries into paragraph-sized <see cref="ChatChunk"/> segments.
/// </summary>
/// <param name="entry">The entry to consider for shattering.</param>
/// <returns>
/// Zero or more <see cref="ChatEntry"/> instances. For unsupported entry types, yields nothing.
/// </returns>
public IEnumerable<ChatEntry> Shatter(ChatEntry entry)
{
switch (entry)
Expand Down
7 changes: 7 additions & 0 deletions src/Coven.Chat/Shattering/ChatSentenceShatterPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ namespace Coven.Chat.Shattering;
/// </summary>
public sealed class ChatSentenceShatterPolicy : IShatterPolicy<ChatEntry>
{
/// <summary>
/// Splits supported draft entries into sentence-sized <see cref="ChatChunk"/> segments.
/// </summary>
/// <param name="entry">The entry to consider for shattering.</param>
/// <returns>
/// Zero or more <see cref="ChatEntry"/> instances. For unsupported entry types, yields nothing.
/// </returns>
public IEnumerable<ChatEntry> Shatter(ChatEntry entry)
{
switch (entry)
Expand Down
7 changes: 6 additions & 1 deletion src/Coven.Chat/Windowing/ChatMaxLengthWindowPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@ public sealed class ChatMaxLengthWindowPolicy : IWindowPolicy<ChatChunk>
{
private readonly int _max;

/// <summary>
/// Creates a policy that emits when the total length of recent chat chunks reaches the maximum.
/// </summary>
/// <param name="max">Maximum total characters across the current window; must be greater than zero.</param>
public ChatMaxLengthWindowPolicy(int max)
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0);
_max = max;
}

/// <inheritdoc />
public int MinChunkLookback => int.MaxValue;

/// <inheritdoc />
public bool ShouldEmit(StreamWindow<ChatChunk> window)
{
int total = 0;
Expand All @@ -36,4 +42,3 @@ public bool ShouldEmit(StreamWindow<ChatChunk> window)
return false;
}
}

3 changes: 2 additions & 1 deletion src/Coven.Chat/Windowing/ChatParagraphWindowPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ namespace Coven.Chat.Windowing;
/// </summary>
public sealed class ChatParagraphWindowPolicy : IWindowPolicy<ChatChunk>
{
/// <inheritdoc />
public int MinChunkLookback => int.MaxValue;

/// <inheritdoc />
public bool ShouldEmit(StreamWindow<ChatChunk> window)
{
StringBuilder sb = new();
Expand Down Expand Up @@ -52,4 +54,3 @@ private static string TrimEndExceptNewlines(string s)
return end == s.Length ? s : s[..end];
}
}

Loading