feat(worker): expose max-turns override over signalr and mcp config tools
This commit is contained in:
18
src/ClaudeDo.Worker/External/ConfigMcpTools.cs
vendored
18
src/ClaudeDo.Worker/External/ConfigMcpTools.cs
vendored
@@ -6,7 +6,7 @@ using ModelContextProtocol.Server;
|
|||||||
|
|
||||||
namespace ClaudeDo.Worker.External;
|
namespace ClaudeDo.Worker.External;
|
||||||
|
|
||||||
public sealed record TaskConfigDto(string? Model, string? SystemPrompt, string? AgentPath);
|
public sealed record TaskConfigDto(string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns);
|
||||||
|
|
||||||
[McpServerToolType]
|
[McpServerToolType]
|
||||||
public sealed class ConfigMcpTools
|
public sealed class ConfigMcpTools
|
||||||
@@ -26,12 +26,12 @@ public sealed class ConfigMcpTools
|
|||||||
public async Task<TaskConfigDto?> GetListConfig(string listId, CancellationToken cancellationToken)
|
public async Task<TaskConfigDto?> GetListConfig(string listId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var cfg = await _lists.GetConfigAsync(listId, cancellationToken);
|
var cfg = await _lists.GetConfigAsync(listId, cancellationToken);
|
||||||
return cfg is null ? null : new TaskConfigDto(cfg.Model, cfg.SystemPrompt, cfg.AgentPath);
|
return cfg is null ? null : new TaskConfigDto(cfg.Model, cfg.SystemPrompt, cfg.AgentPath, cfg.MaxTurns);
|
||||||
}
|
}
|
||||||
|
|
||||||
[McpServerTool, Description("Set a list's default model/system prompt/agent path. Passing all three as null clears the list config.")]
|
[McpServerTool, Description("Set a list's default model/system prompt/agent path/max turns. Passing all four as null clears the list config.")]
|
||||||
public async Task SetListConfig(
|
public async Task SetListConfig(
|
||||||
string listId, string? model, string? systemPrompt, string? agentPath, CancellationToken cancellationToken)
|
string listId, string? model, string? systemPrompt, string? agentPath, int? maxTurns, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_ = await _lists.GetByIdAsync(listId, cancellationToken)
|
_ = await _lists.GetByIdAsync(listId, cancellationToken)
|
||||||
?? throw new InvalidOperationException($"List {listId} not found.");
|
?? throw new InvalidOperationException($"List {listId} not found.");
|
||||||
@@ -40,25 +40,25 @@ public sealed class ConfigMcpTools
|
|||||||
var sp = systemPrompt.NullIfBlank();
|
var sp = systemPrompt.NullIfBlank();
|
||||||
var ap = agentPath.NullIfBlank();
|
var ap = agentPath.NullIfBlank();
|
||||||
|
|
||||||
if (m is null && sp is null && ap is null)
|
if (m is null && sp is null && ap is null && maxTurns is null)
|
||||||
await _lists.DeleteConfigAsync(listId, cancellationToken);
|
await _lists.DeleteConfigAsync(listId, cancellationToken);
|
||||||
else
|
else
|
||||||
await _lists.SetConfigAsync(new ListConfigEntity
|
await _lists.SetConfigAsync(new ListConfigEntity
|
||||||
{
|
{
|
||||||
ListId = listId, Model = m, SystemPrompt = sp, AgentPath = ap,
|
ListId = listId, Model = m, SystemPrompt = sp, AgentPath = ap, MaxTurns = maxTurns,
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
|
|
||||||
await _broadcaster.ListUpdated(listId);
|
await _broadcaster.ListUpdated(listId);
|
||||||
}
|
}
|
||||||
|
|
||||||
[McpServerTool, Description("Set per-task config overrides (model/system prompt/agent path). Pass null for any field to clear that override.")]
|
[McpServerTool, Description("Set per-task config overrides (model/system prompt/agent path/max turns). Pass null for any field to clear that override.")]
|
||||||
public async Task SetTaskConfig(
|
public async Task SetTaskConfig(
|
||||||
string taskId, string? model, string? systemPrompt, string? agentPath, CancellationToken cancellationToken)
|
string taskId, string? model, string? systemPrompt, string? agentPath, int? maxTurns, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_ = await _tasks.GetByIdAsync(taskId, cancellationToken)
|
_ = await _tasks.GetByIdAsync(taskId, cancellationToken)
|
||||||
?? throw new InvalidOperationException($"Task {taskId} not found.");
|
?? throw new InvalidOperationException($"Task {taskId} not found.");
|
||||||
|
|
||||||
await _tasks.UpdateAgentSettingsAsync(taskId, model.NullIfBlank(), systemPrompt.NullIfBlank(), agentPath.NullIfBlank(), ct: cancellationToken);
|
await _tasks.UpdateAgentSettingsAsync(taskId, model.NullIfBlank(), systemPrompt.NullIfBlank(), agentPath.NullIfBlank(), maxTurns, cancellationToken);
|
||||||
await _broadcaster.TaskUpdated(taskId);
|
await _broadcaster.TaskUpdated(taskId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ public record ForceRemoveResultDto(bool Removed, string? Reason);
|
|||||||
public record MergeResultDto(string Status, IReadOnlyList<string> ConflictFiles, string? ErrorMessage);
|
public record MergeResultDto(string Status, IReadOnlyList<string> ConflictFiles, string? ErrorMessage);
|
||||||
public record MergeTargetsDto(string DefaultBranch, IReadOnlyList<string> LocalBranches);
|
public record MergeTargetsDto(string DefaultBranch, IReadOnlyList<string> LocalBranches);
|
||||||
public record UpdateListDto(string Id, string Name, string? WorkingDir, string DefaultCommitType);
|
public record UpdateListDto(string Id, string Name, string? WorkingDir, string DefaultCommitType);
|
||||||
public record UpdateListConfigDto(string ListId, string? Model, string? SystemPrompt, string? AgentPath);
|
public record UpdateListConfigDto(string ListId, string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns = null);
|
||||||
public record UpdateTaskAgentSettingsDto(string TaskId, string? Model, string? SystemPrompt, string? AgentPath);
|
public record UpdateTaskAgentSettingsDto(string TaskId, string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns = null);
|
||||||
public record ListConfigDto(string? Model, string? SystemPrompt, string? AgentPath);
|
public record ListConfigDto(string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns = null);
|
||||||
public record SeedResultDto(int Copied, int Skipped);
|
public record SeedResultDto(int Copied, int Skipped);
|
||||||
|
|
||||||
public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
||||||
@@ -340,7 +340,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
|||||||
var systemPrompt = dto.SystemPrompt.NullIfBlank();
|
var systemPrompt = dto.SystemPrompt.NullIfBlank();
|
||||||
var agentPath = dto.AgentPath.NullIfBlank();
|
var agentPath = dto.AgentPath.NullIfBlank();
|
||||||
|
|
||||||
if (model is null && systemPrompt is null && agentPath is null)
|
if (model is null && systemPrompt is null && agentPath is null && dto.MaxTurns is null)
|
||||||
{
|
{
|
||||||
await repo.DeleteConfigAsync(dto.ListId);
|
await repo.DeleteConfigAsync(dto.ListId);
|
||||||
}
|
}
|
||||||
@@ -352,6 +352,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
|||||||
Model = model,
|
Model = model,
|
||||||
SystemPrompt = systemPrompt,
|
SystemPrompt = systemPrompt,
|
||||||
AgentPath = agentPath,
|
AgentPath = agentPath,
|
||||||
|
MaxTurns = dto.MaxTurns,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +365,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
|||||||
var repo = new ListRepository(ctx);
|
var repo = new ListRepository(ctx);
|
||||||
var config = await repo.GetConfigAsync(listId);
|
var config = await repo.GetConfigAsync(listId);
|
||||||
if (config is null) return null;
|
if (config is null) return null;
|
||||||
return new ListConfigDto(config.Model, config.SystemPrompt, config.AgentPath);
|
return new ListConfigDto(config.Model, config.SystemPrompt, config.AgentPath, config.MaxTurns);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetTaskStatus(string taskId, string status)
|
public async Task SetTaskStatus(string taskId, string status)
|
||||||
@@ -411,7 +412,8 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
|||||||
dto.TaskId,
|
dto.TaskId,
|
||||||
dto.Model.NullIfBlank(),
|
dto.Model.NullIfBlank(),
|
||||||
dto.SystemPrompt.NullIfBlank(),
|
dto.SystemPrompt.NullIfBlank(),
|
||||||
dto.AgentPath.NullIfBlank());
|
dto.AgentPath.NullIfBlank(),
|
||||||
|
dto.MaxTurns);
|
||||||
|
|
||||||
await _broadcaster.TaskUpdated(dto.TaskId);
|
await _broadcaster.TaskUpdated(dto.TaskId);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user