68 lines
2.0 KiB
C#
68 lines
2.0 KiB
C#
using Nexus.Api.Integrations;
|
|
using Nexus.Api.Models;
|
|
|
|
namespace Nexus.Api.Services;
|
|
|
|
public interface IOpenClawChatService
|
|
{
|
|
Task<AgentChatResult> SendAsync(
|
|
string message,
|
|
string conversationId,
|
|
string agentId,
|
|
OpenClawInvocationMetadata invocation,
|
|
CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The single Iris/agent chat dispatch path. Every message becomes a durable
|
|
/// Nexus run and crosses the Protocol-v4 chat.send boundary; Nexus never calls
|
|
/// OpenClaw's OpenAI-compatible /v1/chat/completions endpoint.
|
|
/// </summary>
|
|
public sealed class OpenClawChatService(IOpenClawRunService runs) :
|
|
IOpenClawChatService
|
|
{
|
|
public async Task<AgentChatResult> SendAsync(
|
|
string message,
|
|
string conversationId,
|
|
string agentId,
|
|
OpenClawInvocationMetadata invocation,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var normalizedAgent = agentId.Trim().ToLowerInvariant();
|
|
var operation = await runs.StartAsync(
|
|
new StartOpenClawRunRequest(
|
|
message,
|
|
normalizedAgent,
|
|
$"agent:{normalizedAgent}:main",
|
|
Title: $"Chat with {normalizedAgent}"),
|
|
invocation,
|
|
cancellationToken);
|
|
|
|
if (!operation.Ok)
|
|
{
|
|
throw new OpenClawChatDispatchException(
|
|
operation.State,
|
|
operation.Message,
|
|
operation.Run.Id);
|
|
}
|
|
|
|
return new AgentChatResult(
|
|
"OpenClaw Protocol v4",
|
|
normalizedAgent,
|
|
conversationId,
|
|
operation.Message,
|
|
operation.Run.Id,
|
|
operation.State,
|
|
operation.Operation);
|
|
}
|
|
}
|
|
|
|
public sealed class OpenClawChatDispatchException(
|
|
string state,
|
|
string message,
|
|
Guid runId) : InvalidOperationException(message)
|
|
{
|
|
public string State { get; } = state;
|
|
public Guid RunId { get; } = runId;
|
|
}
|