Rueckmeldung nach Vertrauensstufe: drei Wege nach oben (#715)
- IAgentTool.ReadsForeignContent: Werkzeuge mit Aussenkontakt erklaeren sich selbst (WebFetch, WebMonitor, DirectAPI, Mail, RocketChat, Telegram, TelegramClient, SocialMediaManager, FTP, Database); AgentConfig.TreatAsForeignReader kann nur verschaerfen - ReportingLine: Stufe aus den Werkzeugen, "wer steht darueber", Pruefung des Wegs nach oben (nie Aenderungen an Aufgaben darueber, nur eine Ebene hoch, Fremdinhalt-Stufe gar kein Freitext) und Rahmung als untrusted_content - Engine: Nachricht und Spawn nach oben geprueft, Text der Fremdinhalt-Stufe kommt gerahmt an - Taskboard: task_create/update/comment, reopen und die Dubletten-Notiz folgen dem Berichtsweg - Dispatcher: Aufgaben von Agenten der Fremdinhalt-Stufe gehen gerahmt in den Lauf - TaskReports: Erledigt-Signal und Systemmeldung (in Pruefung, blockiert, abgebrochen) an den Auftraggeber, je Zustand einmal, gesammelt in einer offenen Aufgabe je Empfaenger - OrgBriefing nennt den Berichtsweg; WebUI zeigt Stufe und Schalter am Agenten Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e2ffe4b380
commit
3857a7cab2
@@ -6,6 +6,7 @@ using ClawdDotNet.Core.Audit;
|
||||
using ClawdDotNet.Core.Budget;
|
||||
using ClawdDotNet.Core.Config;
|
||||
using ClawdDotNet.Core.Memory;
|
||||
using ClawdDotNet.Core.Organisation;
|
||||
using ClawdDotNet.Core.Security;
|
||||
using ClawdDotNet.Core.Accounting;
|
||||
using ClawdDotNet.Core.Scheduling;
|
||||
@@ -57,7 +58,7 @@ public sealed class AgentEngine : IAgentMessageRouter, Staging.IFrozenCallExecut
|
||||
private string SystemPromptFor(AgentConfig agentConfig, bool hasTools)
|
||||
=> Organisation.OrgBriefing.WithSection(
|
||||
UntrustedContent.MitRegel(agentConfig.FullSystemPrompt, hasTools),
|
||||
Organisation.OrgBriefing.For(CurrentOrganisation(), agentConfig.AgentId, _clock.GetUtcNow().UtcDateTime));
|
||||
Organisation.OrgBriefing.For(CurrentOrganisation(), agentConfig.AgentId, _clock.GetUtcNow().UtcDateTime, TrustOf(agentConfig)));
|
||||
|
||||
/// <summary>
|
||||
/// Wie viele Weitergaben eine Delegationskette höchstens haben darf (B8).
|
||||
@@ -583,7 +584,7 @@ public sealed class AgentEngine : IAgentMessageRouter, Staging.IFrozenCallExecut
|
||||
// Umzug weiss der Agent sonst im laufenden Chat nichts davon. Der Rest
|
||||
// des bestehenden Systemprompts bleibt, wie er war (#193).
|
||||
var section = Organisation.OrgBriefing.For(
|
||||
CurrentOrganisation(), agentConfig.AgentId, _clock.GetUtcNow().UtcDateTime);
|
||||
CurrentOrganisation(), agentConfig.AgentId, _clock.GetUtcNow().UtcDateTime, TrustOf(agentConfig));
|
||||
var refreshed = Organisation.OrgBriefing.WithSection(messages[0].Content ?? "", section);
|
||||
if (refreshed != messages[0].Content)
|
||||
messages[0] = ChatMessage.System(refreshed);
|
||||
@@ -1107,6 +1108,16 @@ public sealed class AgentEngine : IAgentMessageRouter, Staging.IFrozenCallExecut
|
||||
: "Create a task for @human if it needs someone outside your reach.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// #715: The way up. An agent that reads foreign content writes nothing up the line, and
|
||||
/// nobody writes past its lead — the refusal names the way that is open.
|
||||
/// </summary>
|
||||
private string? CheckReportingLine(AgentConfig? fromConfig, string fromAgentId, string toAgentId)
|
||||
=> ReportingLine.CheckUpward(CurrentOrganisation(), TrustOf(fromConfig), fromAgentId, toAgentId, UpwardKind.Message);
|
||||
|
||||
private AgentTrust TrustOf(AgentConfig? agent)
|
||||
=> agent is null ? AgentTrust.Standard : ReportingLine.TrustOf(agent, _toolRegistry.Get);
|
||||
|
||||
public IReadOnlyList<AgentInfo> ListAgents(string callerAgentId)
|
||||
{
|
||||
var configs = _agentConfigProvider?.Invoke() ?? [];
|
||||
@@ -1152,12 +1163,16 @@ public sealed class AgentEngine : IAgentMessageRouter, Staging.IFrozenCallExecut
|
||||
if (CheckDelegation(chain, fromAgentId, toAgentId) is { } refused)
|
||||
return new AgentMessageResult(false, null, refused);
|
||||
|
||||
var callerChain = chain ?? DelegationChain.Root(fromAgentId);
|
||||
|
||||
var fromConfig = configs.FirstOrDefault(a => a.AgentId == fromAgentId);
|
||||
if (CheckReportingLine(fromConfig, fromAgentId, toAgentId) is { } notUp)
|
||||
return new AgentMessageResult(false, null, notUp);
|
||||
|
||||
var callerChain = chain ?? DelegationChain.Root(fromAgentId);
|
||||
var fromName = fromConfig?.DisplayName ?? fromAgentId;
|
||||
|
||||
var wrappedMessage = $"[Nachricht von Agent \"{fromName}\" ({fromAgentId})]\n\n{message}";
|
||||
// #715: What an agent of the foreign tier writes arrives as data, not as an order.
|
||||
var wrappedMessage = $"[Nachricht von Agent \"{fromName}\" ({fromAgentId})]\n\n"
|
||||
+ ReportingLine.Frame(TrustOf(fromConfig), fromAgentId, message);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1207,16 +1222,20 @@ public sealed class AgentEngine : IAgentMessageRouter, Staging.IFrozenCallExecut
|
||||
if (CheckDelegation(chain, fromAgentId, targetAgentId) is { } refused)
|
||||
return new AgentSpawnResult(false, targetAgentId, null, refused);
|
||||
|
||||
var fromConfig = configs.FirstOrDefault(a => a.AgentId == fromAgentId);
|
||||
if (CheckReportingLine(fromConfig, fromAgentId, targetAgentId) is { } notUp)
|
||||
return new AgentSpawnResult(false, targetAgentId, null, notUp);
|
||||
|
||||
var callerChain = chain ?? DelegationChain.Root(fromAgentId);
|
||||
|
||||
if (IsRunning(targetAgentId))
|
||||
return new AgentSpawnResult(false, targetAgentId, null,
|
||||
$"Agent '{targetConfig.DisplayName}' läuft bereits. Verwende send_message statt spawn.");
|
||||
|
||||
var fromConfig = configs.FirstOrDefault(a => a.AgentId == fromAgentId);
|
||||
var fromName = fromConfig?.DisplayName ?? fromAgentId;
|
||||
|
||||
var wrappedMessage = $"[Spawn-Auftrag von Agent \"{fromName}\" ({fromAgentId})]\n\n{taskMessage}";
|
||||
var wrappedMessage = $"[Spawn-Auftrag von Agent \"{fromName}\" ({fromAgentId})]\n\n"
|
||||
+ ReportingLine.Frame(TrustOf(fromConfig), fromAgentId, taskMessage);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1663,7 +1682,8 @@ public sealed class AgentEngine : IAgentMessageRouter, Staging.IFrozenCallExecut
|
||||
_taskRepository,
|
||||
chain ?? DelegationChain.Root(agentConfig.AgentId))
|
||||
{
|
||||
Organisation = CurrentOrganisation()
|
||||
Organisation = CurrentOrganisation(),
|
||||
Trust = ReportingLine.TrustOf(agentConfig, _toolRegistry.Get)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user