feat(ui): complete Avalonia UI port with 7 main pages, tool settings & top MenuBar
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
using System.Text.Json;
|
||||
using ClawdDotNet.Core.State;
|
||||
using ClawdDotNet.Core.Tasks;
|
||||
using ClawdDotNet.Core.Tests.Infrastructure;
|
||||
using ClawdDotNet.Core.Tools;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Shouldly;
|
||||
|
||||
namespace ClawdDotNet.Core.Tests.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// Der tool_job-Dispatch — ersetzt den ToolJobScheduler. Ein fälliger Poll-Task tickt einen
|
||||
/// <see cref="IToolJobProvider"/> und weckt den Agenten nur, wenn der Tick etwas meldet.
|
||||
/// </summary>
|
||||
public sealed class ToolJobDispatchTests
|
||||
{
|
||||
private static TaskItem PollTask(string agent = "agent-a") => new()
|
||||
{
|
||||
Id = "tj-1",
|
||||
Title = "Poll",
|
||||
Type = TaskItemType.ToolJob,
|
||||
ToolName = "PollTool",
|
||||
JobTypeId = "poll",
|
||||
Assignee = "@" + agent
|
||||
};
|
||||
|
||||
private static EngineTaskDispatcher Dispatcher(EngineFixture fixture)
|
||||
=> new(fixture.Engine, () => fixture.Agents, "test-instance",
|
||||
fixture.Registry, fixture.StateStore, NullLoggerFactory.Instance);
|
||||
|
||||
[Fact]
|
||||
public async Task Ein_Poll_ohne_Fund_weckt_den_Agenten_nicht()
|
||||
{
|
||||
var tool = new FakeJobTool(ToolJobResult.NoAction("nichts Neues"));
|
||||
var fixture = new EngineFixture().WithTool(tool);
|
||||
fixture.AddAgent("agent-a", "PollTool");
|
||||
|
||||
var ok = await Dispatcher(fixture).DispatchAsync(PollTask(), default);
|
||||
|
||||
ok.ShouldBeTrue("ein Poll ohne Fund ist kein Fehler");
|
||||
tool.Ticks.ShouldBe(1);
|
||||
fixture.Client.ReceivedRequests.ShouldBeEmpty("kein Agent-Lauf, wenn nichts zu wecken war");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Ein_Poll_mit_Fund_weckt_den_Agenten()
|
||||
{
|
||||
var tool = new FakeJobTool(ToolJobResult.Wake("Neue Nachricht eingetroffen"));
|
||||
var fixture = new EngineFixture().WithTool(tool);
|
||||
fixture.AddAgent("agent-a", "PollTool");
|
||||
fixture.Client.RespondsWithText("verarbeitet");
|
||||
|
||||
var ok = await Dispatcher(fixture).DispatchAsync(PollTask(), default);
|
||||
|
||||
ok.ShouldBeTrue();
|
||||
tool.Ticks.ShouldBe(1);
|
||||
fixture.Client.ReceivedRequests.ShouldNotBeEmpty("der Agent wurde geweckt");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Ein_unbekanntes_Poll_Tool_meldet_einen_Fehler()
|
||||
{
|
||||
var fixture = new EngineFixture(); // PollTool nicht registriert
|
||||
fixture.AddAgent("agent-a");
|
||||
|
||||
(await Dispatcher(fixture).DispatchAsync(PollTask(), default)).ShouldBeFalse();
|
||||
}
|
||||
|
||||
/// <summary>Ein Tool, das zugleich Poll-Provider ist — zählt Ticks, liefert ein festes Ergebnis.</summary>
|
||||
private sealed class FakeJobTool(ToolJobResult result) : IAgentTool, IToolJobProvider
|
||||
{
|
||||
public int Ticks { get; private set; }
|
||||
|
||||
public string Name => "PollTool";
|
||||
public string Description => "Test-Poll";
|
||||
public JsonElement InputSchema { get; } =
|
||||
JsonDocument.Parse("""{ "type": "object" }""").RootElement.Clone();
|
||||
|
||||
public Task<ToolResult> ExecuteAsync(JsonElement input, AgentToolContext context, CancellationToken ct)
|
||||
=> Task.FromResult(ToolResult.Ok("ok"));
|
||||
|
||||
public IReadOnlyList<ToolJobDefinition> GetJobDefinitions() => [];
|
||||
|
||||
public Task<ToolJobResult> ExecuteJobAsync(
|
||||
string jobTypeId, IReadOnlyDictionary<string, object?> toolConfig, IStateStore stateStore,
|
||||
ILogger logger, CancellationToken ct, string? agentId = null, string? workspacePath = null)
|
||||
{
|
||||
Ticks++;
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user