143 lines
4.8 KiB
C#
143 lines
4.8 KiB
C#
using Nexus.Api.Data;
|
|
using Nexus.Api.Models;
|
|
using Nexus.Api.Services;
|
|
using Xunit;
|
|
|
|
namespace Nexus.Api.Tests;
|
|
|
|
public sealed class OpenClawChatServiceTests
|
|
{
|
|
[Fact]
|
|
public async Task Send_uses_durable_protocol_v4_run_and_canonical_agent_session()
|
|
{
|
|
var runId = Guid.NewGuid();
|
|
var runs = new CapturingRunService(runId, ok: true);
|
|
var service = new OpenClawChatService(runs);
|
|
var invocation = new OpenClawInvocationMetadata(
|
|
"idem-chat",
|
|
"corr-chat",
|
|
"owner",
|
|
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01");
|
|
|
|
var result = await service.SendAsync(
|
|
"coordinate this work",
|
|
"browser-conversation",
|
|
"Iris",
|
|
invocation);
|
|
|
|
Assert.NotNull(runs.Request);
|
|
Assert.Equal("iris", runs.Request.AgentId);
|
|
Assert.Equal("agent:iris:main", runs.Request.SessionKey);
|
|
Assert.Equal("coordinate this work", runs.Request.Prompt);
|
|
Assert.Equal(runId, result.RunId);
|
|
Assert.Equal("OpenClaw Protocol v4", result.Runtime);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Send_does_not_claim_success_when_gateway_dispatch_is_blocked()
|
|
{
|
|
var runs = new CapturingRunService(Guid.NewGuid(), ok: false);
|
|
var service = new OpenClawChatService(runs);
|
|
|
|
var exception = await Assert.ThrowsAsync<OpenClawChatDispatchException>(
|
|
() => service.SendAsync(
|
|
"coordinate this work",
|
|
"browser-conversation",
|
|
"iris",
|
|
new OpenClawInvocationMetadata(
|
|
"idem-chat",
|
|
"corr-chat",
|
|
"owner",
|
|
"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")));
|
|
|
|
Assert.Equal("blocked", exception.State);
|
|
}
|
|
|
|
private sealed class CapturingRunService(Guid runId, bool ok) :
|
|
IOpenClawRunService
|
|
{
|
|
public StartOpenClawRunRequest? Request { get; private set; }
|
|
|
|
public Task<OpenClawRunOperationDto> StartAsync(
|
|
StartOpenClawRunRequest request,
|
|
OpenClawInvocationMetadata invocation,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
Request = request;
|
|
var run = new OpenClawRunDto(
|
|
runId,
|
|
"Chat",
|
|
request.Prompt,
|
|
request.AgentId,
|
|
request.SessionKey,
|
|
ok ? "running" : "blocked",
|
|
request.TaskId,
|
|
request.ProjectId,
|
|
null,
|
|
null,
|
|
invocation.CorrelationId,
|
|
invocation.Actor,
|
|
ok ? null : "Gateway disconnected",
|
|
null,
|
|
false,
|
|
ok,
|
|
!ok,
|
|
false,
|
|
null,
|
|
DateTimeOffset.UtcNow,
|
|
DateTimeOffset.UtcNow,
|
|
null,
|
|
null);
|
|
return Task.FromResult(new OpenClawRunOperationDto(
|
|
ok,
|
|
ok ? "running" : "blocked",
|
|
ok ? "OpenClaw accepted the run." : "Gateway disconnected.",
|
|
run,
|
|
null,
|
|
DateTimeOffset.UtcNow));
|
|
}
|
|
|
|
public Task<OpenClawRunCollectionDto> GetAsync(
|
|
OpenClawRunQuery query,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotSupportedException();
|
|
|
|
public Task<OpenClawRunDto?> GetByIdAsync(
|
|
Guid id,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotSupportedException();
|
|
|
|
public Task<OpenClawRunOperationDto?> StopAsync(
|
|
Guid id,
|
|
string? reason,
|
|
OpenClawInvocationMetadata invocation,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotSupportedException();
|
|
|
|
public Task<OpenClawRunOperationDto?> ResumeAsync(
|
|
Guid id,
|
|
string? reason,
|
|
OpenClawInvocationMetadata invocation,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotSupportedException();
|
|
|
|
public Task<OpenClawRunOperationDto?> RetryAsync(
|
|
Guid id,
|
|
string? reason,
|
|
OpenClawInvocationMetadata invocation,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotSupportedException();
|
|
|
|
public Task<OpenClawRunHistoryResponse?> GetHistoryAsync(
|
|
Guid id,
|
|
int gatewayLimit = 200,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotSupportedException();
|
|
|
|
public Task ReconcileAsync(
|
|
GatewayEventEnvelope gatewayEvent,
|
|
CancellationToken cancellationToken = default) =>
|
|
throw new NotSupportedException();
|
|
}
|
|
}
|