MICROSOFT AGENT FRAMEWORK · 0.16.0-rc.1
Action et approbation en processus
Autoriser une proposition exacte et vérifier l’écriture réelle en SQLite.
Objectifs
- Backlog SQLite et lecture après écriture
- Approbation et refus en processus
- Pipeline et frontière avec la décision durable
Le chemin d’une action
Demo090 assemble explicitement en C# : catalogue de confiance, analyse sans outil sensible, désérialisation, validation du draft, création d’une proposition figée, demande d’approbation, invocation et relecture. L’agent écrivain reçoit un unique outil create_backlog_item et un proposalId. Il ne reçoit pas de paramètres permettant de remplacer Title ou Summary après la revue. Ce pipeline n’est pas encore un graphe MAF Workflows.
- Catalogue → Analyse → BacklogDraft
- Validation hôte → Proposition figée
- Droit hôte + approbation exacte
- ToolOutcome → Relecture SQLite
Une base réelle, une preuve à relire
BacklogStore utilise Microsoft.Data.Sqlite et des paramètres SQL. Insert revalide le draft immédiatement avant l’écriture et retourne l’identifiant SQLite. List relit les vingt dernières lignes dans l’ordre décroissant des identifiants. La base par défaut est %LOCALAPPDATA%/MafBaseTechnique/lot005-backlog.db ; MAF_DEMO_DB_PATH sélectionne un chemin de travail isolé. Le démarrage ne fait aucun reset.
public IReadOnlyList<BacklogItem> List()
{
using var connection = Open();
using var command = connection.CreateCommand();
command.CommandText = "SELECT Id, Title, Kind, Priority, Component, Summary FROM BacklogItems ORDER BY Id DESC LIMIT 20";
using var reader = command.ExecuteReader();
var items = new List<BacklogItem>();
while (reader.Read()) items.Add(new(reader.GetInt64(0), reader.GetString(1), reader.GetString(2),
reader.GetString(3), reader.GetString(4), reader.GetString(5)));
return items;
Code source · Maf.Backlog · Dossier
Un refus peut laisser créer le fichier et sa table lors de la lecture : la preuve attendue est l’absence de nouvelle ligne métier, pas l’absence de fichier. Sur une base déjà remplie, comparer avant/après. Ne pas supprimer une base existante pour rendre une démonstration convaincante ; choisir un nouveau chemin de recette.
Approbation manuelle puis native
Demo070 demande la confirmation dans le corps de la fonction. Demo080 enveloppe la fonction dans ApprovalRequiredAIFunction : MAF retourne ToolApprovalRequestContent avant l’effet. Le host enregistre la demande et ses arguments ; la décision est construite par request.CreateResponse(bool) puis renvoyée dans un ChatMessage de rôle User, avec la même AgentSession. Seule la saisie exacte y approuve ; vide et toute autre réponse refusent.
ApprovalReview lie session, nom, identifiant d’appel et arguments. Un objet étranger, des arguments modifiés, une autre session ou une demande consommée sont rejetés. Plusieurs demandes sont revues séparément. La boucle de démo est limitée à quatre tours ; une demande encore pendante n’est jamais un succès. Aucune réponse d’approbation signifie aucune reprise autorisée.
var function = AIFunctionFactory.Create(gate.Create, "create_backlog_item");
var writer = chat.AsAIAgent(name: "BacklogWriter", instructions:
"Call create_backlog_item exactly once with the host proposal ID. Do not invent success. Report the tool outcome in English.",
tools: [new ApprovalRequiredAIFunction(function)]);
var session = await writer.CreateSessionAsync(stop.Token);
var review = new ApprovalReview(session, gate);
Le verrou reste dans le host
WriteGate copie aussi le tableau mutable de questions avant revue. Il refuse si le contrat est invalide, si canWrite est faux, si l’approbation manque, si l’identifiant ne correspond pas ou si la capacité est consommée. MAF_DEMO_READ_ONLY=1 retire le droit : même y ne peut le rendre. Une fois autorisée, l’invocation consomme le droit avant l’insertion ; un échec de stockage n’entraîne pas de réessai aveugle.
if (draft.Validate().Length != 0) result = new("Invalid", null, "Business contract failed.");
else if (!canWrite || !approved || consumed || proposalId != this.proposalId)
result = new("Refused", null, "Permission, approval or unused matching proposal is missing.");
else
{
consumed = true;
approved = false;
try { result = new("Created", store.Insert(draft), "SQLite write observed by the host."); }
Code source · Maf.Backlog · Dossier
L’approbation et la capacité vivent en mémoire ; SQLite conserve la ligne, pas cette décision. Redémarrer ou créer une autre proposition ne déduplique pas durablement la même intention. Les demandes persistées et le rejeu idempotent seront étudiés dans le parcours durable. Le commutateur read-only illustre une politique du host, sans implémenter l’authentification d’une application de production.
Manipulation complète : refuser puis approuver
$env:MAF_DEMO_DB_PATH = Join-Path $env:TEMP ('maf-foundations-' + [guid]::NewGuid().ToString('N') + '.db')
$env:MAF_DEMO_READ_ONLY = '0'
dotnet run --project demos/Demo090_CompletePipeline/Demo090.App.csproj -c Release --no-buildAvec un chat qualifié pour structure et outils, saisir list pour relever l’état initial. Soumettre en anglais : “Login fails for every known account since release 2.1. Reproduce with an existing account. Priority high, component Auth.” Lire le draft ; s’il reste des questions, préciser la demande et recommencer. À la demande d’approbation, répondre n. Vérifier les observations du host puis list : aucune nouvelle ligne. Soumettre de nouveau, examiner le nouveau draft et répondre y seulement s’il convient. Exiger Created et ItemId puis vérifier que list contient exactement les champs revus.
Quitter avec une ligne vide. Reprendre avec MAF_DEMO_READ_ONLY=1 et refaire une proposition : y ne doit pas créer de ligne. Retirer ensuite les surcharges dans ce terminal avec Remove-Item Env:MAF_DEMO_READ_ONLY et Remove-Item Env:MAF_DEMO_DB_PATH. Une absence d’appel, un schéma invalide ou une demande pendante reste un résultat explicite ; cette manipulation guidée n’annonce pas un nouvel essai de modèle réalisé pour le site.
Fiches et exercice
Prérequis
Pour poursuivre
- Demo070 — SQLite Backlog
- Demo080 — Approved Backlog
- Demo090 — Complete Pipeline
- Demo100 — Controlled Action
Précédent
Suivant
