diff --git a/Directory.Build.props b/Directory.Build.props index 6843c07..ad74752 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,17 +1,17 @@ + + enable + enable + true + true + + + LICENSE - - true - - true - enable - enable - - diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000..6d45f3a --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,8 @@ + + + + $(NoWarn);1591;CS1591 + $(WarningsNotAsErrors);1591;CS1591 + + + diff --git a/src/Coven.Agents.OpenAI/AgentMaxLengthWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentMaxLengthWindowPolicy.cs index 3592d29..8bc12a6 100644 --- a/src/Coven.Agents.OpenAI/AgentMaxLengthWindowPolicy.cs +++ b/src/Coven.Agents.OpenAI/AgentMaxLengthWindowPolicy.cs @@ -10,14 +10,20 @@ public sealed class AgentMaxLengthWindowPolicy : IWindowPolicy + /// Creates a policy that emits when the total length of recent chunks reaches the maximum. + /// + /// Maximum total characters across the current window; must be greater than zero. public AgentMaxLengthWindowPolicy(int max) { ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0); _max = max; } + /// public int MinChunkLookback => 1; + /// public bool ShouldEmit(StreamWindow window) { int total = 0; diff --git a/src/Coven.Agents.OpenAI/AgentParagraphWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentParagraphWindowPolicy.cs index 44baef1..43f19a4 100644 --- a/src/Coven.Agents.OpenAI/AgentParagraphWindowPolicy.cs +++ b/src/Coven.Agents.OpenAI/AgentParagraphWindowPolicy.cs @@ -10,8 +10,10 @@ namespace Coven.Agents.OpenAI; /// public sealed class AgentParagraphWindowPolicy : IWindowPolicy { + /// public int MinChunkLookback => 2; + /// public bool ShouldEmit(StreamWindow window) { StringBuilder stringBuilder = new(); diff --git a/src/Coven.Agents.OpenAI/AgentThoughtMaxLengthWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtMaxLengthWindowPolicy.cs index 0ec1aff..7c8fc13 100644 --- a/src/Coven.Agents.OpenAI/AgentThoughtMaxLengthWindowPolicy.cs +++ b/src/Coven.Agents.OpenAI/AgentThoughtMaxLengthWindowPolicy.cs @@ -10,14 +10,20 @@ public sealed class AgentThoughtMaxLengthWindowPolicy : IWindowPolicy + /// Creates a policy that emits when the total length of recent thought chunks reaches the maximum. + /// + /// Maximum total characters across the current thought window; must be greater than zero. public AgentThoughtMaxLengthWindowPolicy(int max) { ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0); _max = max; } + /// public int MinChunkLookback => 1; + /// public bool ShouldEmit(StreamWindow window) { int total = 0; @@ -35,4 +41,3 @@ public bool ShouldEmit(StreamWindow window) return false; } } - diff --git a/src/Coven.Agents.OpenAI/AgentThoughtParagraphWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtParagraphWindowPolicy.cs index 480dfd7..9166152 100644 --- a/src/Coven.Agents.OpenAI/AgentThoughtParagraphWindowPolicy.cs +++ b/src/Coven.Agents.OpenAI/AgentThoughtParagraphWindowPolicy.cs @@ -10,8 +10,10 @@ namespace Coven.Agents.OpenAI; /// public sealed class AgentThoughtParagraphWindowPolicy : IWindowPolicy { + /// public int MinChunkLookback => 2; + /// public bool ShouldEmit(StreamWindow window) { StringBuilder stringBuilder = new(); @@ -32,4 +34,3 @@ public bool ShouldEmit(StreamWindow window) return concatenatedWindow.EndsWith("\r\n\r\n", StringComparison.Ordinal) || concatenatedWindow.EndsWith("\n\n", StringComparison.Ordinal); } } - diff --git a/src/Coven.Agents.OpenAI/AgentThoughtSentenceWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtSentenceWindowPolicy.cs index fe96807..06643e1 100644 --- a/src/Coven.Agents.OpenAI/AgentThoughtSentenceWindowPolicy.cs +++ b/src/Coven.Agents.OpenAI/AgentThoughtSentenceWindowPolicy.cs @@ -11,8 +11,10 @@ namespace Coven.Agents.OpenAI; public sealed class AgentThoughtSentenceWindowPolicy : IWindowPolicy { // 4 chunks should be generous for windowing sentence termination + /// public int MinChunkLookback => 4; + /// public bool ShouldEmit(StreamWindow window) { StringBuilder sb = new(); @@ -44,4 +46,3 @@ private static bool EndsWithSentenceBoundary(StringBuilder sb) return c is '.' or '!' or '?'; } } - diff --git a/src/Coven.Agents.OpenAI/AgentThoughtSummaryMarkerWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtSummaryMarkerWindowPolicy.cs index 7db789a..79529f6 100644 --- a/src/Coven.Agents.OpenAI/AgentThoughtSummaryMarkerWindowPolicy.cs +++ b/src/Coven.Agents.OpenAI/AgentThoughtSummaryMarkerWindowPolicy.cs @@ -11,8 +11,10 @@ namespace Coven.Agents.OpenAI; /// public sealed class AgentThoughtSummaryMarkerWindowPolicy : IWindowPolicy { + /// public int MinChunkLookback => 10; + /// public bool ShouldEmit(StreamWindow window) { StringBuilder stringBuilder = new(); diff --git a/src/Coven.Agents.OpenAI/AgentThoughtSummaryShatterPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtSummaryShatterPolicy.cs index 70fe1f8..c5d0249 100644 --- a/src/Coven.Agents.OpenAI/AgentThoughtSummaryShatterPolicy.cs +++ b/src/Coven.Agents.OpenAI/AgentThoughtSummaryShatterPolicy.cs @@ -24,6 +24,14 @@ private static class Grammar public static readonly string[] _paragraphBoundaries = ["\r\n\r\n", "\n\n", "\r\n"]; } + /// + /// Splits an into up to two entries at the first detected summary marker boundary. + /// + /// The source agent entry. + /// + /// Zero or more instances: at most two parts + /// when a boundary is present; otherwise no output. + /// public IEnumerable Shatter(AgentEntry entry) { if (entry is not AgentThought thought || string.IsNullOrEmpty(thought.Text)) diff --git a/src/Coven.Agents.OpenAI/Coven.Agents.OpenAI.csproj b/src/Coven.Agents.OpenAI/Coven.Agents.OpenAI.csproj index 71a852e..c7d8815 100644 --- a/src/Coven.Agents.OpenAI/Coven.Agents.OpenAI.csproj +++ b/src/Coven.Agents.OpenAI/Coven.Agents.OpenAI.csproj @@ -1,6 +1,12 @@ net10.0 + true + true + $(MSBuildProjectName) + OpenAI agent integration for Coven. + Coven + coven;agents;openai;llm;integration diff --git a/src/Coven.Agents.OpenAI/ReasoningEffort.cs b/src/Coven.Agents.OpenAI/ReasoningEffort.cs index ccb4601..0d57325 100644 --- a/src/Coven.Agents.OpenAI/ReasoningEffort.cs +++ b/src/Coven.Agents.OpenAI/ReasoningEffort.cs @@ -8,8 +8,10 @@ namespace Coven.Agents.OpenAI; /// public enum ReasoningEffort { + /// Minimal additional compute for reasoning. Low, + /// Balanced additional compute for reasoning. Medium, + /// Maximum additional compute for reasoning. High } - diff --git a/src/Coven.Agents/Coven.Agents.csproj b/src/Coven.Agents/Coven.Agents.csproj index a9fe0f8..c369201 100644 --- a/src/Coven.Agents/Coven.Agents.csproj +++ b/src/Coven.Agents/Coven.Agents.csproj @@ -1,6 +1,12 @@ net10.0 + true + true + $(MSBuildProjectName) + Agent abstractions and helpers for Coven. + Coven + coven;agents;abstractions diff --git a/src/Coven.Chat.Console/Coven.Chat.Console.csproj b/src/Coven.Chat.Console/Coven.Chat.Console.csproj index bb5ad95..d7b20f2 100644 --- a/src/Coven.Chat.Console/Coven.Chat.Console.csproj +++ b/src/Coven.Chat.Console/Coven.Chat.Console.csproj @@ -2,6 +2,12 @@ net10.0 + true + true + $(MSBuildProjectName) + Console chat adapter for Coven (stdin/stdout). + Coven + coven;agents;chat;console;adapter @@ -12,4 +18,3 @@ - diff --git a/src/Coven.Chat.Discord/Coven.Chat.Discord.csproj b/src/Coven.Chat.Discord/Coven.Chat.Discord.csproj index de87879..91b85b6 100644 --- a/src/Coven.Chat.Discord/Coven.Chat.Discord.csproj +++ b/src/Coven.Chat.Discord/Coven.Chat.Discord.csproj @@ -2,6 +2,12 @@ net10.0 + true + true + $(MSBuildProjectName) + Discord chat adapter for Coven using Discord.Net. + Coven + coven;agents;chat;discord;adapter diff --git a/src/Coven.Chat.Discord/DiscordScrivener.cs b/src/Coven.Chat.Discord/DiscordScrivener.cs index a858338..38a4c13 100644 --- a/src/Coven.Chat.Discord/DiscordScrivener.cs +++ b/src/Coven.Chat.Discord/DiscordScrivener.cs @@ -11,10 +11,11 @@ internal sealed class DiscordScrivener : IScrivener private readonly ILogger _logger; /// - /// + /// Wraps a keyed inner scrivener and forwards outbound efferent messages to Discord. /// - /// - /// + /// The keyed inner used for storage. + /// The gateway connection for sending messages to Discord. + /// Logger for diagnostic breadcrumbs. /// Because we are what we utilize, ensure that the inner scrivener is keyed in DI. public DiscordScrivener([FromKeyedServices("Coven.InternalDiscordScrivener")] IScrivener scrivener, DiscordGatewayConnection discordClient, ILogger logger) { diff --git a/src/Coven.Chat.Discord/DiscordTransmuter.cs b/src/Coven.Chat.Discord/DiscordTransmuter.cs index d8e509e..c9daa89 100644 --- a/src/Coven.Chat.Discord/DiscordTransmuter.cs +++ b/src/Coven.Chat.Discord/DiscordTransmuter.cs @@ -8,6 +8,12 @@ namespace Coven.Chat.Discord; /// public class DiscordTransmuter : IBiDirectionalTransmuter { + /// + /// Transmutes Discord-afferent entries into chat entries. + /// + /// The source Discord entry. + /// A cancellation token. + /// The mapped . public Task TransmuteAfferent(DiscordEntry Input, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -20,6 +26,12 @@ public Task TransmuteAfferent(DiscordEntry Input, CancellationToken c }; } + /// + /// Transmutes chat-efferent entries into Discord entries. + /// + /// The source chat entry. + /// A cancellation token. + /// The mapped . public Task TransmuteEfferent(ChatEntry Output, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/Coven.Chat/Coven.Chat.csproj b/src/Coven.Chat/Coven.Chat.csproj index 9571c58..cd6a2e7 100644 --- a/src/Coven.Chat/Coven.Chat.csproj +++ b/src/Coven.Chat/Coven.Chat.csproj @@ -1,6 +1,12 @@ net10.0 + true + true + $(MSBuildProjectName) + Chat primitives and windowing integration for Coven. + Coven + coven;agents;chat;windowing;journal diff --git a/src/Coven.Chat/Shattering/ChatChunkMaxLengthShatterPolicy.cs b/src/Coven.Chat/Shattering/ChatChunkMaxLengthShatterPolicy.cs index b77bf1c..f499bab 100644 --- a/src/Coven.Chat/Shattering/ChatChunkMaxLengthShatterPolicy.cs +++ b/src/Coven.Chat/Shattering/ChatChunkMaxLengthShatterPolicy.cs @@ -4,19 +4,31 @@ namespace Coven.Chat.Shattering; /// -/// 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 and ; other entries are ignored. /// public sealed class ChatChunkMaxLengthShatterPolicy : IShatterPolicy { private readonly int _max; + /// + /// Creates a new shatter policy. + /// + /// Maximum characters per emitted chunk. Must be greater than zero. public ChatChunkMaxLengthShatterPolicy(int max) { ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0); _max = max; } + /// + /// Splits supported entries into chunks not exceeding the configured maximum length. + /// + /// The input entry to consider. + /// + /// Zero or more instances representing the shattered output. + /// For unsupported entry types, yields nothing. + /// public IEnumerable Shatter(ChatEntry entry) { switch (entry) @@ -38,6 +50,9 @@ public IEnumerable Shatter(ChatEntry entry) } } + /// + /// Helper that splits raw text into fixed-size parts. + /// private IEnumerable Split(string? text) { string s = text ?? string.Empty; @@ -57,4 +72,3 @@ private IEnumerable Split(string? text) } } } - diff --git a/src/Coven.Chat/Shattering/ChatParagraphShatterPolicy.cs b/src/Coven.Chat/Shattering/ChatParagraphShatterPolicy.cs index b8c3d23..a68fcf3 100644 --- a/src/Coven.Chat/Shattering/ChatParagraphShatterPolicy.cs +++ b/src/Coven.Chat/Shattering/ChatParagraphShatterPolicy.cs @@ -14,6 +14,13 @@ namespace Coven.Chat.Shattering; /// public sealed class ChatParagraphShatterPolicy : IShatterPolicy { + /// + /// Splits supported draft entries into paragraph-sized segments. + /// + /// The entry to consider for shattering. + /// + /// Zero or more instances. For unsupported entry types, yields nothing. + /// public IEnumerable Shatter(ChatEntry entry) { switch (entry) diff --git a/src/Coven.Chat/Shattering/ChatSentenceShatterPolicy.cs b/src/Coven.Chat/Shattering/ChatSentenceShatterPolicy.cs index da194d5..e9c5124 100644 --- a/src/Coven.Chat/Shattering/ChatSentenceShatterPolicy.cs +++ b/src/Coven.Chat/Shattering/ChatSentenceShatterPolicy.cs @@ -14,6 +14,13 @@ namespace Coven.Chat.Shattering; /// public sealed class ChatSentenceShatterPolicy : IShatterPolicy { + /// + /// Splits supported draft entries into sentence-sized segments. + /// + /// The entry to consider for shattering. + /// + /// Zero or more instances. For unsupported entry types, yields nothing. + /// public IEnumerable Shatter(ChatEntry entry) { switch (entry) diff --git a/src/Coven.Chat/Windowing/ChatMaxLengthWindowPolicy.cs b/src/Coven.Chat/Windowing/ChatMaxLengthWindowPolicy.cs index 769058d..373c0b1 100644 --- a/src/Coven.Chat/Windowing/ChatMaxLengthWindowPolicy.cs +++ b/src/Coven.Chat/Windowing/ChatMaxLengthWindowPolicy.cs @@ -11,14 +11,20 @@ public sealed class ChatMaxLengthWindowPolicy : IWindowPolicy { private readonly int _max; + /// + /// Creates a policy that emits when the total length of recent chat chunks reaches the maximum. + /// + /// Maximum total characters across the current window; must be greater than zero. public ChatMaxLengthWindowPolicy(int max) { ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0); _max = max; } + /// public int MinChunkLookback => int.MaxValue; + /// public bool ShouldEmit(StreamWindow window) { int total = 0; @@ -36,4 +42,3 @@ public bool ShouldEmit(StreamWindow window) return false; } } - diff --git a/src/Coven.Chat/Windowing/ChatParagraphWindowPolicy.cs b/src/Coven.Chat/Windowing/ChatParagraphWindowPolicy.cs index daf78a0..fff4e37 100644 --- a/src/Coven.Chat/Windowing/ChatParagraphWindowPolicy.cs +++ b/src/Coven.Chat/Windowing/ChatParagraphWindowPolicy.cs @@ -10,8 +10,10 @@ namespace Coven.Chat.Windowing; /// public sealed class ChatParagraphWindowPolicy : IWindowPolicy { + /// public int MinChunkLookback => int.MaxValue; + /// public bool ShouldEmit(StreamWindow window) { StringBuilder sb = new(); @@ -52,4 +54,3 @@ private static string TrimEndExceptNewlines(string s) return end == s.Length ? s : s[..end]; } } - diff --git a/src/Coven.Chat/Windowing/ChatSentenceWindowPolicy.cs b/src/Coven.Chat/Windowing/ChatSentenceWindowPolicy.cs index 44688ad..593d307 100644 --- a/src/Coven.Chat/Windowing/ChatSentenceWindowPolicy.cs +++ b/src/Coven.Chat/Windowing/ChatSentenceWindowPolicy.cs @@ -11,8 +11,10 @@ namespace Coven.Chat.Windowing; public sealed class ChatSentenceWindowPolicy : IWindowPolicy { // 4 chunks should be generous for windowing sentence termination + /// public int MinChunkLookback => 4; + /// public bool ShouldEmit(StreamWindow window) { StringBuilder sb = new(); @@ -46,4 +48,3 @@ private static bool EndsWithSentenceBoundary(StringBuilder sb) return c is '.' or '!' or '?'; } } - diff --git a/src/Coven.Core.Streaming/ChainedShatterPolicy.cs b/src/Coven.Core.Streaming/ChainedShatterPolicy.cs index 9dff300..96fd030 100644 --- a/src/Coven.Core.Streaming/ChainedShatterPolicy.cs +++ b/src/Coven.Core.Streaming/ChainedShatterPolicy.cs @@ -14,6 +14,12 @@ public sealed class ChainedShatterPolicy(params IShatterPolicy[] { private readonly IShatterPolicy[] _policies = policies ?? []; + /// + /// Applies each shatter policy in order to the provided entry, forwarding + /// unchanged entries to subsequent policies and yielding only transformed outputs. + /// + /// The source entry to shatter. + /// Zero or more transformed entries produced by the chain. public IEnumerable Shatter(TEntry entry) { if (_policies.Length == 0) @@ -53,4 +59,3 @@ public IEnumerable Shatter(TEntry entry) } } } - diff --git a/src/Coven.Core.Streaming/CompositeWindowPolicy.cs b/src/Coven.Core.Streaming/CompositeWindowPolicy.cs index 5d71690..3fd450a 100644 --- a/src/Coven.Core.Streaming/CompositeWindowPolicy.cs +++ b/src/Coven.Core.Streaming/CompositeWindowPolicy.cs @@ -9,6 +9,12 @@ public sealed class CompositeWindowPolicy : IWindowPolicy { private readonly IReadOnlyList> _policies; + /// + /// Creates a composite policy that emits when any child policy emits. + /// Uses the maximum across children. + /// + /// One or more window policies to compose. + /// Thrown when no policies are provided. public CompositeWindowPolicy(params IWindowPolicy[] policies) { if (policies is null || policies.Length == 0) @@ -19,9 +25,10 @@ public CompositeWindowPolicy(params IWindowPolicy[] policies) MinChunkLookback = _policies.Max(s => s.MinChunkLookback); } + /// public int MinChunkLookback { get; } + /// public bool ShouldEmit(StreamWindow window) => _policies.Any(s => s.ShouldEmit(window)); } - diff --git a/src/Coven.Core.Streaming/Coven.Core.Streaming.csproj b/src/Coven.Core.Streaming/Coven.Core.Streaming.csproj index e1ed8ae..34225b5 100644 --- a/src/Coven.Core.Streaming/Coven.Core.Streaming.csproj +++ b/src/Coven.Core.Streaming/Coven.Core.Streaming.csproj @@ -2,6 +2,12 @@ net10.0 + true + true + $(MSBuildProjectName) + Streaming/windowing utilities and daemon for chunked message flows. + Coven + coven;agents;streaming;windowing;batching diff --git a/src/Coven.Core.Streaming/LambdaShatterPolicy.cs b/src/Coven.Core.Streaming/LambdaShatterPolicy.cs index f453f11..2556c30 100644 --- a/src/Coven.Core.Streaming/LambdaShatterPolicy.cs +++ b/src/Coven.Core.Streaming/LambdaShatterPolicy.cs @@ -1,11 +1,17 @@ // SPDX-License-Identifier: BUSL-1.1 namespace Coven.Core.Streaming; +/// +/// Shatter policy backed by a provided delegate. +/// +/// The entry type to shatter. +/// Delegate that produces zero or more entries for a given input. public sealed class LambdaShatterPolicy(Func> shatter) : IShatterPolicy { private readonly Func> _shatter = shatter ?? throw new ArgumentNullException(nameof(shatter)); + /// public IEnumerable Shatter(TEntry entry) => _shatter(entry); } diff --git a/src/Coven.Core.Streaming/StreamWindow.cs b/src/Coven.Core.Streaming/StreamWindow.cs index 0eb4892..1edd898 100644 --- a/src/Coven.Core.Streaming/StreamWindow.cs +++ b/src/Coven.Core.Streaming/StreamWindow.cs @@ -5,13 +5,13 @@ namespace Coven.Core.Streaming; /// Snapshot of the current streaming window passed to window policies. /// /// Chunk type under consideration. +/// Recent chunks in the window (respecting MinChunkLookback semantics). +/// Total number of chunks observed in the current buffer. +/// Timestamp when windowing started. +/// Timestamp of the last emit. public readonly record struct StreamWindow( -/// Recent chunks in the window (respecting MinChunkLookback semantics). -IEnumerable PendingChunks, -/// Total number of chunks observed in the current buffer. -int ChunkCount, -/// Timestamp when windowing started. -DateTimeOffset StartedAt, -/// Timestamp of the last emit. -DateTimeOffset LastEmitAt + IEnumerable PendingChunks, + int ChunkCount, + DateTimeOffset StartedAt, + DateTimeOffset LastEmitAt ); diff --git a/src/Coven.Core.Tests/Coven.Core.Tests.csproj b/src/Coven.Core.Tests/Coven.Core.Tests.csproj index 32a27fe..483afce 100644 --- a/src/Coven.Core.Tests/Coven.Core.Tests.csproj +++ b/src/Coven.Core.Tests/Coven.Core.Tests.csproj @@ -4,6 +4,7 @@ net10.0 false true + true diff --git a/src/Coven.Core/Coven.Core.csproj b/src/Coven.Core/Coven.Core.csproj index b3eb815..5f67fc7 100644 --- a/src/Coven.Core/Coven.Core.csproj +++ b/src/Coven.Core/Coven.Core.csproj @@ -1,17 +1,16 @@  - net10.0 - - + true + true + $(MSBuildProjectName) + Coven core runtime: MagikBlocks, builder, routing, journaling. + Coven + coven;agents;orchestration;runtime;routing;journal + - - - - - diff --git a/src/Coven.Core/GetWorkRequest.cs b/src/Coven.Core/GetWorkRequest.cs index 8ce82fe..130a970 100644 --- a/src/Coven.Core/GetWorkRequest.cs +++ b/src/Coven.Core/GetWorkRequest.cs @@ -2,7 +2,15 @@ namespace Coven.Core; -// A request to advance one unit of work in Pull mode. +/// +/// A single-step work request used in pull mode. +/// One instance is provided each time the work increment advances. +/// +/// Type of the current input value. +/// The current value to process for this step. +/// Optional tags that influence selection for this step. +/// Optional branch identifier to isolate tag state. +/// Cancellation token propagated from the orchestrator. public sealed record GetWorkRequest ( TIn Input, diff --git a/src/Coven.Core/IScrivener.cs b/src/Coven.Core/IScrivener.cs index 652e5f2..107c58d 100644 --- a/src/Coven.Core/IScrivener.cs +++ b/src/Coven.Core/IScrivener.cs @@ -52,6 +52,7 @@ public interface IScrivener where TJournalEntryType : notnull /// /// The derived entry type to match. /// Only consider entries strictly after this position. + /// Predicate to select the desired derived entry. /// A cancellation token. /// The first matching (journalPosition, entry) pair with the derived entry. Task<(long journalPosition, TDerived entry)> WaitForAsync(long afterPosition, Func match, CancellationToken cancellationToken = default) diff --git a/src/Coven.Core/InMemoryScrivener.cs b/src/Coven.Core/InMemoryScrivener.cs index f4d35a2..df1624c 100644 --- a/src/Coven.Core/InMemoryScrivener.cs +++ b/src/Coven.Core/InMemoryScrivener.cs @@ -5,7 +5,7 @@ namespace Coven.Core; /// -/// In-memory implementation of IScrivener journal with simple, single-process semantics; +/// In-memory implementation of with simple, single-process semantics; /// supports tailing, backward read, and predicate waits. /// /// The journal entry type. diff --git a/src/Coven.Core/Routing/BlockInvokerFactory.cs b/src/Coven.Core/Routing/BlockInvokerFactory.cs index 7a5013f..b7c918d 100644 --- a/src/Coven.Core/Routing/BlockInvokerFactory.cs +++ b/src/Coven.Core/Routing/BlockInvokerFactory.cs @@ -23,7 +23,7 @@ public static Func> Create(Magik Type taskOutType = typeof(Task<>).MakeGenericType(d.OutputType); ParameterExpression tParam = Expression.Parameter(taskOutType, "t"); - MemberExpression resultProp = Expression.Property(tParam, nameof(Task.Result)); + MemberExpression resultProp = Expression.Property(tParam, nameof(Task<>.Result)); UnaryExpression toObj = Expression.Convert(resultProp, typeof(object)); LambdaExpression mapLambda = Expression.Lambda(toObj, tParam); @@ -64,7 +64,7 @@ public static Func> Create(Magik // Build continuation: t => board.FinalizePullStep(sink, t.Result, branchId, blockTypeName) ParameterExpression tParam = Expression.Parameter(taskOutType, "t"); - MemberExpression resultProp = Expression.Property(tParam, nameof(Task.Result)); + MemberExpression resultProp = Expression.Property(tParam, nameof(Task<>.Result)); MethodInfo? boardFinalize = typeof(Board).GetMethod("FinalizePullStep", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new InvalidOperationException("Board.FinalizePullStep not found."); MethodInfo finalizeClosed = boardFinalize.MakeGenericMethod(d.OutputType); diff --git a/src/Coven.Daemonology.Tests/Coven.Daemonology.Tests.csproj b/src/Coven.Daemonology.Tests/Coven.Daemonology.Tests.csproj index ebfa52e..ef55ab4 100644 --- a/src/Coven.Daemonology.Tests/Coven.Daemonology.Tests.csproj +++ b/src/Coven.Daemonology.Tests/Coven.Daemonology.Tests.csproj @@ -4,6 +4,7 @@ net10.0 false true + true diff --git a/src/Coven.Daemonology/ContractDaemon.cs b/src/Coven.Daemonology/ContractDaemon.cs index 24a7051..a2bfaf4 100644 --- a/src/Coven.Daemonology/ContractDaemon.cs +++ b/src/Coven.Daemonology/ContractDaemon.cs @@ -5,12 +5,15 @@ namespace Coven.Daemonology; /// /// Represents a Daemon that is capable of meeting a "Status contract" such that when status changes, promise are completed. /// -/// The IScrivener that the contract Daemon uses to fulfill promises. +/// The used by the daemon to fulfill status promises. public abstract class ContractDaemon(IScrivener scrivener) : IDaemon, IDisposable { private readonly IScrivener _scrivener = scrivener ?? throw new ArgumentNullException(nameof(scrivener)); private readonly SemaphoreSlim _semaphoreSlim = new(1, 1); + /// + /// Current operational status of the daemon. + /// public Status Status { get; protected set; } /// @@ -123,6 +126,9 @@ protected async Task Fail(Exception error, CancellationToken cancellationToken = } } + /// + /// Releases resources held by the daemon. + /// public void Dispose() { _semaphoreSlim.Dispose(); diff --git a/src/Coven.Daemonology/Coven.Daemonology.csproj b/src/Coven.Daemonology/Coven.Daemonology.csproj index fd2044a..bb561d6 100644 --- a/src/Coven.Daemonology/Coven.Daemonology.csproj +++ b/src/Coven.Daemonology/Coven.Daemonology.csproj @@ -2,6 +2,12 @@ net10.0 + true + true + $(MSBuildProjectName) + Daemon scaffolding: status/failure contracts for long-running services. + Coven + coven;agents;daemon;status;hosting diff --git a/src/Coven.Daemonology/DaemonEvent.cs b/src/Coven.Daemonology/DaemonEvent.cs index e4e8a70..fcd590e 100644 --- a/src/Coven.Daemonology/DaemonEvent.cs +++ b/src/Coven.Daemonology/DaemonEvent.cs @@ -1,8 +1,10 @@ namespace Coven.Daemonology; +/// +/// Base record for daemon lifecycle events emitted to journals. +/// public abstract record DaemonEvent; internal sealed record StatusChanged(Status NewStatus) : DaemonEvent; internal sealed record FailureOccurred(Exception Exception) : DaemonEvent; - diff --git a/src/Coven.Spellcasting/Coven.Spellcasting.csproj b/src/Coven.Spellcasting/Coven.Spellcasting.csproj index b421ab4..0b56d10 100644 --- a/src/Coven.Spellcasting/Coven.Spellcasting.csproj +++ b/src/Coven.Spellcasting/Coven.Spellcasting.csproj @@ -3,6 +3,12 @@ net10.0 enable + true + true + $(MSBuildProjectName) + Spell contracts, schema generation, and spellbooks for Coven. + Coven + coven;agents;spell;schema;tools diff --git a/src/Coven.Spellcasting/ISpell.cs b/src/Coven.Spellcasting/ISpell.cs index 6a017df..198a0db 100644 --- a/src/Coven.Spellcasting/ISpell.cs +++ b/src/Coven.Spellcasting/ISpell.cs @@ -3,47 +3,65 @@ namespace Coven.Spellcasting; /// -/// Represents a tool that is usable by any agent. -/// Builds a definition from the input shape TIn -/// Produces TOut during tool execution. +/// A spell with typed input and output. +/// Builds its from and . /// +/// Input shape consumed by the spell. +/// Output shape produced by the spell. public interface ISpell : ISpell { - new SpellDefinition Definition - { - get => new( - SchemaGen.GetFriendlyName(typeof(TIn)), - SchemaGen.GenerateSchema(typeof(TIn)), - SchemaGen.GenerateSchema(typeof(TOut))); - } + /// + /// Canonical definition (name and schemas) for this spell. + /// + new SpellDefinition Definition => new( + SchemaGen.GetFriendlyName(typeof(TIn)), + SchemaGen.GenerateSchema(typeof(TIn)), + SchemaGen.GenerateSchema(typeof(TOut))); + + /// + /// Execute the spell with the provided input. + /// + /// The input payload to process. + /// The produced value. Task CastSpell(TIn Input); } /// -/// Represents a tool that is usable by any agent. -/// Builds a definition from the input shape TIn +/// A spell with typed input and no output. +/// Builds its from . /// +/// Input shape consumed by the spell. public interface ISpell : ISpell { - new SpellDefinition Definition - { - get => new( - SchemaGen.GetFriendlyName(typeof(TIn)), - SchemaGen.GenerateSchema(typeof(TIn))); - } + /// + /// Canonical definition (name and schemas) for this spell. + /// + new SpellDefinition Definition => new( + SchemaGen.GetFriendlyName(typeof(TIn)), + SchemaGen.GenerateSchema(typeof(TIn))); + + /// + /// Execute the spell with the provided input. + /// + /// The input payload to process. Task CastSpell(TIn Input); } /// -/// Represents a tool that is usable by any agent. -/// No input or output +/// Base spell contract usable by any agent. +/// No input or output. /// public interface ISpell { - SpellDefinition Definition - { - get => new(SchemaGen.GetFriendlyName(GetType())); - } + /// + /// Canonical definition (name and schemas) for this spell. + /// Default name derives from the implementing type. + /// + SpellDefinition Definition => new(SchemaGen.GetFriendlyName(GetType())); + + /// + /// Execute the spell. + /// Task CastSpell(); } diff --git a/src/Coven.Spellcasting/ISpellContract.cs b/src/Coven.Spellcasting/ISpellContract.cs index 36f8507..b856856 100644 --- a/src/Coven.Spellcasting/ISpellContract.cs +++ b/src/Coven.Spellcasting/ISpellContract.cs @@ -12,8 +12,5 @@ public interface ISpellContract /// Canonical spell definition (name and schemas). Prefer values supplied by the Spellbook. /// Default provides a friendly name; n-ary spell interfaces supply schema-aware defaults. /// - SpellDefinition Definition - { - get => new(SchemaGen.GetFriendlyName(GetType())); - } + SpellDefinition Definition => new(SchemaGen.GetFriendlyName(GetType())); } diff --git a/src/Coven.Spellcasting/Spellbook.cs b/src/Coven.Spellcasting/Spellbook.cs index 31b0a7b..26526e1 100644 --- a/src/Coven.Spellcasting/Spellbook.cs +++ b/src/Coven.Spellcasting/Spellbook.cs @@ -2,7 +2,30 @@ namespace Coven.Spellcasting; -public sealed record Spellbook( - IReadOnlyList Definitions, - IReadOnlyList Spells -); \ No newline at end of file +/// +/// Immutable collection of spell definitions and their corresponding instances. +/// Produced by for discovery and wiring. +/// +public sealed record Spellbook +{ + /// + /// All discovered spell definitions (names and schemas). + /// + public IReadOnlyList Definitions { get; init; } + + /// + /// The concrete spell instances corresponding to . + /// + public IReadOnlyList Spells { get; init; } + + /// + /// Create a new spellbook from definitions and spell instances. + /// + /// Canonical definitions for each spell. + /// Concrete spell instances. + public Spellbook(IReadOnlyList definitions, IReadOnlyList spells) + { + Definitions = definitions ?? throw new ArgumentNullException(nameof(definitions)); + Spells = spells ?? throw new ArgumentNullException(nameof(spells)); + } +} diff --git a/src/Coven.Spellcasting/SpellbookBuilder.cs b/src/Coven.Spellcasting/SpellbookBuilder.cs index 1dd839d..a8c6220 100644 --- a/src/Coven.Spellcasting/SpellbookBuilder.cs +++ b/src/Coven.Spellcasting/SpellbookBuilder.cs @@ -2,11 +2,19 @@ namespace Coven.Spellcasting; +/// +/// Builder for composing a from one or more spells. +/// public sealed class SpellbookBuilder { private readonly List _definitions = []; private readonly List _spells = []; + /// + /// Add a non-generic spell. + /// + /// The spell instance to include. + /// This builder for chaining. public SpellbookBuilder AddSpell(ISpell spell) { ArgumentNullException.ThrowIfNull(spell); @@ -15,6 +23,12 @@ public SpellbookBuilder AddSpell(ISpell spell) return this; } + /// + /// Add a typed-input spell. + /// + /// Input shape consumed by the spell. + /// The spell instance to include. + /// This builder for chaining. public SpellbookBuilder AddSpell(ISpell spell) { ArgumentNullException.ThrowIfNull(spell); @@ -23,6 +37,13 @@ public SpellbookBuilder AddSpell(ISpell spell) return this; } + /// + /// Add a typed-input/output spell. + /// + /// Input shape consumed by the spell. + /// Output shape produced by the spell. + /// The spell instance to include. + /// This builder for chaining. public SpellbookBuilder AddSpell(ISpell spell) { ArgumentNullException.ThrowIfNull(spell); @@ -31,6 +52,10 @@ public SpellbookBuilder AddSpell(ISpell spell) return this; } + /// + /// Build an immutable containing all added spells and definitions. + /// + /// The constructed spellbook. public Spellbook Build() { return new Spellbook(_definitions.AsReadOnly(), _spells.AsReadOnly()); diff --git a/src/Coven.Transmutation/Coven.Transmutation.csproj b/src/Coven.Transmutation/Coven.Transmutation.csproj index f3b4d7d..54e125d 100644 --- a/src/Coven.Transmutation/Coven.Transmutation.csproj +++ b/src/Coven.Transmutation/Coven.Transmutation.csproj @@ -1,7 +1,13 @@ - - - - net10.0 - - - + + + + net10.0 + true + true + $(MSBuildProjectName) + Transmutation interfaces for bridging domain types and protocols. + Coven + coven;agents;transmutation;mapping;conversion + + + diff --git a/src/samples/01.DiscordAgent/DiscordAgent.csproj b/src/samples/01.DiscordAgent/DiscordAgent.csproj index 6ecf4c7..29d4bb8 100644 --- a/src/samples/01.DiscordAgent/DiscordAgent.csproj +++ b/src/samples/01.DiscordAgent/DiscordAgent.csproj @@ -6,6 +6,7 @@ DiscordAgent enable enable + false diff --git a/src/toys/Coven.Toys.ConsoleChat/Coven.Toys.ConsoleChat.csproj b/src/toys/Coven.Toys.ConsoleChat/Coven.Toys.ConsoleChat.csproj index a3b8d3f..9cd8b9f 100644 --- a/src/toys/Coven.Toys.ConsoleChat/Coven.Toys.ConsoleChat.csproj +++ b/src/toys/Coven.Toys.ConsoleChat/Coven.Toys.ConsoleChat.csproj @@ -3,6 +3,7 @@ Exe net10.0 + false @@ -14,4 +15,3 @@ - diff --git a/src/toys/Coven.Toys.ConsoleOpenAI/Coven.Toys.ConsoleOpenAI.csproj b/src/toys/Coven.Toys.ConsoleOpenAI/Coven.Toys.ConsoleOpenAI.csproj index e19ffd6..5ead2a2 100644 --- a/src/toys/Coven.Toys.ConsoleOpenAI/Coven.Toys.ConsoleOpenAI.csproj +++ b/src/toys/Coven.Toys.ConsoleOpenAI/Coven.Toys.ConsoleOpenAI.csproj @@ -3,6 +3,7 @@ Exe net10.0 + false @@ -15,4 +16,3 @@ - diff --git a/src/toys/Coven.Toys.ConsoleOpenAIStreaming/Coven.Toys.ConsoleOpenAIStreaming.csproj b/src/toys/Coven.Toys.ConsoleOpenAIStreaming/Coven.Toys.ConsoleOpenAIStreaming.csproj index e19ffd6..5ead2a2 100644 --- a/src/toys/Coven.Toys.ConsoleOpenAIStreaming/Coven.Toys.ConsoleOpenAIStreaming.csproj +++ b/src/toys/Coven.Toys.ConsoleOpenAIStreaming/Coven.Toys.ConsoleOpenAIStreaming.csproj @@ -3,6 +3,7 @@ Exe net10.0 + false @@ -15,4 +16,3 @@ - diff --git a/src/toys/Coven.Toys.DiscordChat/Coven.Toys.DiscordChat.csproj b/src/toys/Coven.Toys.DiscordChat/Coven.Toys.DiscordChat.csproj index 85f92b0..e74d33b 100644 --- a/src/toys/Coven.Toys.DiscordChat/Coven.Toys.DiscordChat.csproj +++ b/src/toys/Coven.Toys.DiscordChat/Coven.Toys.DiscordChat.csproj @@ -1,9 +1,10 @@  - - Exe - net10.0 - + + Exe + net10.0 + false + diff --git a/src/toys/Coven.Toys.DiscordStreaming/Coven.Toys.DiscordStreaming.csproj b/src/toys/Coven.Toys.DiscordStreaming/Coven.Toys.DiscordStreaming.csproj index d40d5d8..0bde137 100644 --- a/src/toys/Coven.Toys.DiscordStreaming/Coven.Toys.DiscordStreaming.csproj +++ b/src/toys/Coven.Toys.DiscordStreaming/Coven.Toys.DiscordStreaming.csproj @@ -2,6 +2,7 @@ Exe net10.0 + false @@ -12,4 +13,3 @@ -