Merge claudedo/02f6746fd67b4217a581f2f911f6ff0d
This commit is contained in:
+55
-16
@@ -55,33 +55,64 @@ public sealed class ConfigMcpTools
|
||||
: new TaskConfigResult(true, new TaskConfigDto(cfg.Model, cfg.SystemPrompt, cfg.AgentPath, cfg.MaxTurns));
|
||||
}
|
||||
|
||||
// clearFields (not a per-field sentinel like UpdateList's "" for workingDir) because maxTurns is an
|
||||
// int? — there's no blank value to overload as "clear" for a number the way there is for a string.
|
||||
private static readonly string[] ConfigFieldNames = { "model", "systemPrompt", "agentPath", "maxTurns" };
|
||||
|
||||
private static HashSet<string> NormalizeClearFields(IReadOnlyList<string>? clearFields)
|
||||
{
|
||||
var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var field in clearFields ?? Array.Empty<string>())
|
||||
{
|
||||
if (!ConfigFieldNames.Contains(field, StringComparer.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException(
|
||||
$"Unknown clearFields entry '{field}'. Valid values: {string.Join(", ", ConfigFieldNames)}.");
|
||||
set.Add(field);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
[McpServerTool, Description(
|
||||
"Set a list's default model/system prompt/agent path/max turns — the fallback for tasks in this list " +
|
||||
"that don't override them. Passing all four as null clears the list config instead of setting one.")]
|
||||
"that don't override them. Only the fields you pass are changed; omitted fields keep their current " +
|
||||
"value. To clear a field instead, name it in clearFields; clearing all four deletes the list's config.")]
|
||||
public async Task<SetListConfigResult> SetListConfig(
|
||||
string listId, string? model = null, string? systemPrompt = null, string? agentPath = null,
|
||||
int? maxTurns = null, CancellationToken cancellationToken = default)
|
||||
int? maxTurns = null,
|
||||
[Description("Field names to explicitly clear: 'model', 'systemPrompt', 'agentPath', 'maxTurns'. " +
|
||||
"A field named here is cleared even if a value was also passed for it.")]
|
||||
IReadOnlyList<string>? clearFields = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
_ = await _lists.GetByIdAsync(listId, cancellationToken)
|
||||
?? throw new InvalidOperationException($"List {listId} not found.");
|
||||
|
||||
var m = model.NullIfBlank();
|
||||
var sp = systemPrompt.NullIfBlank();
|
||||
var ap = agentPath.NullIfBlank();
|
||||
var clear = NormalizeClearFields(clearFields);
|
||||
var existing = await _lists.GetConfigAsync(listId, cancellationToken);
|
||||
|
||||
var m = clear.Contains("model") ? null : model.NullIfBlank() ?? existing?.Model;
|
||||
var sp = clear.Contains("systemPrompt") ? null : systemPrompt.NullIfBlank() ?? existing?.SystemPrompt;
|
||||
var ap = clear.Contains("agentPath") ? null : agentPath.NullIfBlank() ?? existing?.AgentPath;
|
||||
var mt = clear.Contains("maxTurns") ? null : maxTurns ?? existing?.MaxTurns;
|
||||
|
||||
TaskConfigDto? config;
|
||||
if (m is null && sp is null && ap is null && maxTurns is null)
|
||||
if (m is null && sp is null && ap is null && mt is null && clear.Count > 0)
|
||||
{
|
||||
await _lists.DeleteConfigAsync(listId, cancellationToken);
|
||||
config = null;
|
||||
}
|
||||
else if (m is null && sp is null && ap is null && mt is null && existing is null)
|
||||
{
|
||||
config = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
await _lists.SetConfigAsync(new ListConfigEntity
|
||||
{
|
||||
ListId = listId, Model = m, SystemPrompt = sp, AgentPath = ap, MaxTurns = maxTurns,
|
||||
ListId = listId, Model = m, SystemPrompt = sp, AgentPath = ap, MaxTurns = mt,
|
||||
SessionSkills = existing?.SessionSkills, VerifyCommand = existing?.VerifyCommand,
|
||||
}, cancellationToken);
|
||||
config = new TaskConfigDto(m, sp, ap, maxTurns);
|
||||
config = new TaskConfigDto(m, sp, ap, mt);
|
||||
}
|
||||
|
||||
await _broadcaster.ListUpdated(listId);
|
||||
@@ -90,21 +121,29 @@ public sealed class ConfigMcpTools
|
||||
|
||||
[McpServerTool, Description(
|
||||
"Set per-task overrides for model/system prompt/agent path/max turns; these take precedence over the " +
|
||||
"list's default config for this one task. Pass null for any field to clear that override.")]
|
||||
"list's default config for this one task. Only the fields you pass are changed; omitted fields keep " +
|
||||
"their current override. To clear a field instead, name it in clearFields.")]
|
||||
public async Task<SetTaskConfigResult> SetTaskConfig(
|
||||
string taskId, string? model = null, string? systemPrompt = null, string? agentPath = null,
|
||||
int? maxTurns = null, CancellationToken cancellationToken = default)
|
||||
int? maxTurns = null,
|
||||
[Description("Field names to explicitly clear: 'model', 'systemPrompt', 'agentPath', 'maxTurns'. " +
|
||||
"A field named here is cleared even if a value was also passed for it.")]
|
||||
IReadOnlyList<string>? clearFields = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
_ = await _tasks.GetByIdAsync(taskId, cancellationToken)
|
||||
var task = await _tasks.GetByIdAsync(taskId, cancellationToken)
|
||||
?? throw new InvalidOperationException($"Task {taskId} not found.");
|
||||
|
||||
var m = model.NullIfBlank();
|
||||
var sp = systemPrompt.NullIfBlank();
|
||||
var ap = agentPath.NullIfBlank();
|
||||
var clear = NormalizeClearFields(clearFields);
|
||||
|
||||
await _tasks.UpdateAgentSettingsAsync(taskId, m, sp, ap, maxTurns, ct: cancellationToken);
|
||||
var m = clear.Contains("model") ? null : model.NullIfBlank() ?? task.Model;
|
||||
var sp = clear.Contains("systemPrompt") ? null : systemPrompt.NullIfBlank() ?? task.SystemPrompt;
|
||||
var ap = clear.Contains("agentPath") ? null : agentPath.NullIfBlank() ?? task.AgentPath;
|
||||
var mt = clear.Contains("maxTurns") ? null : maxTurns ?? task.MaxTurns;
|
||||
|
||||
await _tasks.UpdateAgentSettingsAsync(taskId, m, sp, ap, mt, task.SessionSkills, cancellationToken);
|
||||
await _broadcaster.TaskUpdated(taskId);
|
||||
return new SetTaskConfigResult(true, taskId, new TaskConfigDto(m, sp, ap, maxTurns));
|
||||
return new SetTaskConfigResult(true, taskId, new TaskConfigDto(m, sp, ap, mt));
|
||||
}
|
||||
|
||||
[McpServerTool, Description("Read this task's per-task overrides (model/system prompt/agent path/max turns), which take precedence over the list's default config. Returns { found: false, config: null } if none is set.")]
|
||||
|
||||
Reference in New Issue
Block a user