namespace ClawdDotNet.Web.Contracts;
// ─────────────────────────────────────────────────────────────────────────────
// Die Übertragungstypen der Weboberfläche.
//
// Warum es sie gibt, statt die Kerntypen zu serialisieren:
//
// 1. AgentConfig trägt Zugangsdaten. Ein `return agent;` hätte den
// Werkzeug-Konfigurationsbaum samt Passwörtern ins Netz geschickt — die Sorte
// Fehler, die niemandem auffällt, weil alles funktioniert.
// 2. Die Kerntypen ändern sich mit dem Kern. Ein neues Feld in TaskItem wäre sonst
// still eine API-Änderung, auf die sich jemand verlassen hat.
// 3. Die Grenze soll einen Prozesswechsel überstehen (siehe InstanceHttpHost). Über eine
// Prozessgrenze geht nur, was hier steht.
//
// Namen auf Englisch in camelCase wie im übrigen Code; die Beschreibungen auf Deutsch.
// ─────────────────────────────────────────────────────────────────────────────
/// Antwort auf einen verwaltenden Aufruf — dieselbe Form wie AdminResult.
public sealed record OutcomeDto(bool Ok, string Message);
/// Version, Bau und Instanz. Was auf der Info-Seite steht.
public sealed record InfoDto(
string AppVersion,
string BuildSummary,
string InstanceId,
string InstanceName,
bool EngineActive,
bool SchedulerActive,
bool StagingActive,
bool DeploymentcenterActive);
/// Erreichbarkeit und Guthaben bei OpenRouter.
public sealed record StatusDto(
bool ApiReachable,
string StatusText,
string CreditsText,
double? CreditBalance,
double? CreditRemaining);
/// Ein Agent, ohne alles, was ein Zugangsdatum sein könnte.
public sealed record AgentDto(
string AgentId,
string DisplayName,
string Model,
string Description,
string PromptCaching,
int MaxToolResultChars,
int MaxSteps,
int MaxContextTokens,
int TimeoutSeconds,
decimal DailyCostUsd,
long DailyTokens,
bool IsRunning,
IReadOnlyList Tools);
///
/// Ein Werkzeug am Agenten. Ohne die Einstellungen — die stehen in einem freien
/// Wörterbuch und enthalten regelmäßig Passwörter und Schlüssel. Was einstellbar ist und
/// ob etwas gesetzt ist, sagt .
///
public sealed record AgentToolDto(string Name, string Description, bool Enabled);
///
/// Die Einstellungen eines Werkzeugs, maskiert.
///
/// Ein Wert, dessen Name ein Zugangsdatum bezeichnet, kommt nie heraus. Statt
/// seiner steht in , ob überhaupt etwas gesetzt ist — mehr braucht
/// eine Anzeige nicht, und mehr darf sie nicht wissen.
///
public sealed record ToolSettingsDto(
string Name,
IReadOnlyDictionary Values,
IReadOnlyDictionary Secrets);
/// Eine Zeile im Chatverlauf.
public sealed record ChatEntryDto(
string Role,
string Content,
DateTime Timestamp,
string? Source);
/// Was der Browser schickt, wenn jemand etwas in den Chat tippt.
public sealed record SendMessageDto(string Message);
/// Ein Dienst der Instanz.
public sealed record ServiceDto(
string ServiceId,
string Name,
string Type,
int Port,
bool Enabled,
bool BuiltIn,
string Description);
/// Was einen neuen Dienst ausmacht.
public sealed record ServiceInputDto(string Name, string Type, int Port, string Description = "");
/// Ein neuer Agent.
public sealed record NewAgentDto(string AgentId, string DisplayName, string Model, string Description = "");
/// Eine Aufgabe vom Taskboard.
public sealed record TaskDto(
string Id,
string Title,
string Status,
string Type,
int Priority,
string Assignee,
bool RequireApproval,
string Acceptance,
IReadOnlyList BlockedBy,
string Body,
DateTime CreatedAt,
DateTime UpdatedAt,
TaskWhenDto? When = null,
DateTime? NextRunUtc = null,
TaskLastRunDto? LastRun = null,
string? Hinweis = null,
TaskBudgetMissDto? BudgetMiss = null);
///
/// #716: Runs of this task the budget refused — only present while something is open
/// (misses since the last run that took place, a pending catch-up or a deferral).
///
public sealed record TaskBudgetMissDto(int Count, DateTime? LastAt, DateTime? DeferredUntil, bool CatchUpPending, bool CarriedOver);
/// Der letzte Lauf einer Aufgabe (#594) - aus dem Beleg, samt Kosten.
public sealed record TaskLastRunDto(DateTime OccurredAt, string Status, decimal CostUsd, bool CostIsKnown, string ResultRef);
/// Was die Weboberflaeche beim Anlegen oder Aendern einer Aufgabe schickt (#594).
public sealed record TaskInputDto(
string Title,
string Body = "",
string Assignee = "",
string? WhenKind = null,
string? WhenValue = null,
string? TimeZone = null,
string Acceptance = "",
int Priority = 3);
/// Die Kostenprognose einer Instanz (#595).
public sealed record ForecastDto(
IReadOnlyList Tasks,
decimal TasksPerDay,
decimal OtherPerDay,
decimal TotalPerDay,
decimal TotalPerMonth,
decimal OneOffOpen,
int WithoutBasis,
IReadOnlyList BudgetWarnings);
/// Ein Agent, dessen geplante Aufgaben laut Prognose sein Tagesbudget uebersteigen (#608).
public sealed record ForecastBudgetDto(string AgentId, decimal CostPerDay, decimal BudgetPerDay);
/// Eine Zeile der Kostenprognose. Basis: Laeufe, Agent, Schaetzung oder Unbekannt.
public sealed record ForecastTaskDto(
string TaskId,
string Title,
string AgentId,
string Model,
double RunsPerDay,
bool OneOffOpen,
decimal? CostPerRun,
string Basis,
int Sample,
decimal CostPerDay);
///
/// Der Termin einer Aufgabe (cron, every, at) samt Zeitzone. Ohne ihn
/// war in der Oberflaeche eine stuendliche Aufgabe von einer einmaligen nicht zu
/// unterscheiden (#591).
///
public sealed record TaskWhenDto(string Kind, string Value, string TimeZone);
/// Ein eingefrorener Aufruf, der auf Freigabe wartet.
/// #641: Wie oft dieselbe Operation dieses Agenten zuletzt schon freigegeben wurde.
/// #641: Ob "Gleichartiges kuenftig erlauben" angeboten werden darf.
/// #641: Ob die Oberflaeche die Dauerfreigabe vorschlagen soll.
public sealed record StagedCallDto(
long Id,
string RunId,
string AgentId,
string Tool,
string? Action,
string Proposal,
string Status,
string ArgumentsJson,
DateTime CreatedAt,
int PreviousApprovals = 0,
bool CanAllowSimilar = false,
bool SuggestAllowSimilar = false);
/// #641: Eine Dauerfreigabe - "Gleichartiges kuenftig erlauben".
public sealed record StandingApprovalDto(
long Id,
string AgentId,
string Tool,
string Operation,
string GrantedBy,
DateTime GrantedAt,
long? SourceId,
DateTime? RevokedAt,
string? RevokedBy);
///
/// #641: Die Rechte eines Agenten an einem Werkzeug, je Operation.
/// Setting: "erlaubt", "verboten" oder "freigabe" (einzeln vorlegen) - so wie es in der
/// Konfiguration steht. Effective: was tatsaechlich geschieht ("auto", "approve",
/// "deny") - einschliesslich Dauerfreigaben und Werkzeugvorgabe.
///
public sealed record ToolRightsDto(
string Tool,
bool Configured,
IReadOnlyList Operations);
public sealed record ToolOperationDto(
string Operation,
string Setting,
string Effective,
string Reason,
bool AlwaysApproval,
long? StandingApprovalId);
/// #641: Neue Rechte. Allowed null = Liste entfernen, Vorgabe des Werkzeugs gilt.
public sealed record ToolRightsInputDto(IReadOnlyList? Allowed, IReadOnlyList? Denied);
/// Warum ein Vorschlag abgelehnt wurde.
public sealed record RejectDto(string Reason);
///
/// Ein Lauf mit dem, was er gekostet hat.
///
/// ist nicht schmückendes Beiwerk: Ohne geladene
/// Preisliste steht in eine Null, die „kostenlos" heißen könnte
/// und „unbekannt" heißt. Eine Anzeige, die das nicht unterscheidet, lügt.
///
public sealed record UsageDto(
long Id,
string AgentId,
string Model,
int PromptTokens,
int CompletionTokens,
int CachedTokens,
decimal CostUsd,
bool CostIsKnown,
string Status,
int StepCount,
DateTime OccurredAt);
/// Eine Protokollzeile.
public sealed record LogLineDto(string Module, string Level, string Text);
/// Eine interne Kommunikation zwischen Agenten (A2A, #208).
public sealed record AgentCommunicationDto(
string TargetAgentId,
string TargetAgentName,
string? SourceAgentId,
string? SourceAgentName,
string Role,
string Content,
DateTime Timestamp);