Fremde Laufzeiten: Claude Code und Befehl in der Sandbox, Egress-Proxy, Vorschlag statt Einsatz (#712)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7d6c2c9495
commit
367ea387f6
@@ -298,6 +298,81 @@ public sealed class AgentAdministration(AppHost host)
|
||||
: $"Prompt history of '{agent.DisplayName}': {Core.Transcripts.PromptHistorySettings.Describe(retentionDays.Value)}.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// #712: The runtime an agent works in. Checked here, not at the next run: a list of
|
||||
/// hosts that does not parse or a command-less command runtime would otherwise show up
|
||||
/// only as a failed run at night.
|
||||
/// </summary>
|
||||
public AdminResult SetRuntime(string agentId, Core.Runtimes.AgentRuntimeConfig runtime)
|
||||
{
|
||||
if (Find(agentId) is not { } agent)
|
||||
return AdminResult.Failure($"No agent with id '{agentId}'.");
|
||||
if (ValidateRuntime(runtime) is { } problem)
|
||||
return AdminResult.Failure(problem);
|
||||
|
||||
runtime.Kind = Core.Runtimes.RuntimeKinds.Normalize(runtime.Kind);
|
||||
runtime.AllowedTools = runtime.AllowedTools.Select(t => t.Trim()).Where(t => t.Length > 0).Distinct().ToList();
|
||||
runtime.Egress = runtime.Egress.Select(e => e.Trim()).Where(e => e.Length > 0).Distinct().ToList();
|
||||
runtime.Arguments = runtime.Arguments.ToList();
|
||||
agent.Runtime = runtime;
|
||||
PersistAgent(agent);
|
||||
host.SaveInstance(new InstanceChange(InstanceChangeKind.Agents, agentId));
|
||||
|
||||
return AdminResult.Success(runtime.IsForeign
|
||||
? $"'{agent.DisplayName}' now works in {runtime.Kind}, in the sandbox."
|
||||
: $"'{agent.DisplayName}' works natively again.");
|
||||
}
|
||||
|
||||
public static string? ValidateRuntime(Core.Runtimes.AgentRuntimeConfig runtime)
|
||||
{
|
||||
if (!Core.Runtimes.RuntimeKinds.IsKnown(runtime.Kind))
|
||||
return $"Unknown runtime '{runtime.Kind}' — known are {string.Join(", ", Core.Runtimes.RuntimeKinds.All)}.";
|
||||
if (runtime.MaxTurns is < 1 or > 500)
|
||||
return "Turns must be between 1 and 500.";
|
||||
if (runtime.TimeoutMinutes is < 1 or > 240)
|
||||
return "The time limit must be between 1 and 240 minutes.";
|
||||
if (Core.Runtimes.RuntimeKinds.Normalize(runtime.Kind) == Core.Runtimes.RuntimeKinds.Command
|
||||
&& string.IsNullOrWhiteSpace(runtime.Command))
|
||||
return "The command runtime needs a command.";
|
||||
// A tool name, possibly with a pattern in parentheses — never an option in disguise.
|
||||
if (runtime.AllowedTools.FirstOrDefault(t => t.TrimStart().StartsWith('-') || t.Contains(',')) is { } odd)
|
||||
return $"'{odd}' is not a tool name.";
|
||||
try
|
||||
{
|
||||
Core.Sandbox.EgressRules.Parse(runtime.Egress);
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
return ex.Message;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// #712: The instance's Claude Code account. Keys are only ever replaced, never read
|
||||
/// back; an empty value keeps the one there is.
|
||||
/// </summary>
|
||||
public AdminResult SetClaudeCode(string? executable, string? auth, string? apiKey, string? oauthToken)
|
||||
{
|
||||
var settings = host.Instance.ClaudeCode;
|
||||
var mode = string.IsNullOrWhiteSpace(auth) ? settings.Auth : auth.Trim().ToLowerInvariant();
|
||||
if (mode is not (Core.Runtimes.ClaudeCodeSettings.ApiKeyAuth or Core.Runtimes.ClaudeCodeSettings.SubscriptionAuth))
|
||||
return AdminResult.Failure($"Unknown sign-in '{auth}'.");
|
||||
|
||||
settings.Auth = mode;
|
||||
if (executable is not null)
|
||||
settings.Executable = executable.Trim();
|
||||
if (!string.IsNullOrWhiteSpace(apiKey))
|
||||
settings.ApiKey = apiKey.Trim();
|
||||
if (!string.IsNullOrWhiteSpace(oauthToken))
|
||||
settings.OAuthToken = oauthToken.Trim();
|
||||
host.SaveInstance(new InstanceChange(InstanceChangeKind.Settings));
|
||||
|
||||
return AdminResult.Success(settings.OnSubscription
|
||||
? "Claude Code runs on the subscription."
|
||||
: "Claude Code runs on the API key.");
|
||||
}
|
||||
|
||||
/// <summary>#660: Instance default retention of the prompt history, in days.</summary>
|
||||
public AdminResult SetDefaultPromptHistoryRetention(int retentionDays)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user