Skip to content

Guided tour

FabrCore 2.0 · Release and package availability

These guides track the current 2.0 source. Stable 2.0.0 publication is pending; package commands show the release target. Until it is published, follow the source quick start or use a matching available prerelease set. Release migration · Runtime modes

MODULE 03 · LESSON 3.2

Build a plugin that participates in the agent lifecycle

Build a plugin that shares the owning agent's context and lifecycle.

Lesson 12 of 86 · FabrCore 2.0

Overview

IFabrCorePlugin.InitializeAsync receives AgentConfiguration and trusted services. This lets the plugin use a principal-bound connection, state or agent host without asking the model to supply infrastructure credentials. Its public described methods become callable tools.

Initialization binds trusted dependencies

InitializeAsync receives the owning agent's configuration and trusted services. Resolve the request-system client or connection there, instead of letting the model supply a base URL, principal or credential on every call. Per-agent initialization gives the plugin a defined owner and a point to validate its settings before requests arrive.

Registration and attachment are both required

The Host must discover the plugin implementation, and the instance's Plugins list must select its alias. Args entries using the documented plugin-alias:setting convention are configuration inputs, not automatic tool registration. The sample RequestPlugin uses fixture data; an HTTP-backed implementation can later keep the same narrow lookup interface while replacing its internal dependency.

Initialize and attach the request plugin

Download the Operations Desk source. The README lists project setup, package prerequisites and local ports.

  1. Add RequestPlugin.cs below to the agents assembly, then rebuild and restart the Host so discovery sees requests. The fixture has no external dependencies and performs no writes.
  2. Use the request below to create tool-assistant with the requests plugin. For an existing instance, use an explicit configuration update; ordinary ensure creation may retain its old plugin list.
  3. Send a message to tool-assistant asking it to look up SR-1042. Inspect the actual tool result, whose fixture status is Open.
RequestPlugin.cs · fixture implementation
using System.ComponentModel;
using FabrCore.Core;
using FabrCore.Sdk;

[PluginAlias("requests")]
[Description("Read fixture service requests. Does not update external systems.")]
public sealed class RequestPlugin : IFabrCorePlugin
{
    public Task InitializeAsync(AgentConfiguration config, IServiceProvider services)
        => Task.CompletedTask;

    [Description("Look up a service request by its exact ID. Returns null if absent.")]
    public Task<RequestRecord?> GetRequest(
        [Description("Request ID, for example SR-1042")] string requestId)
        => Task.FromResult(requestId == "SR-1042"
            ? new RequestRecord(requestId, "Printer unavailable", "Open") : null);
}
public sealed record RequestRecord(string Id, string Summary, string Status);
Provision a separate plugin-enabled AI instance · trusted localhost only
POST /fabrcoreapi/agent/create
x-user-handle: dev
Content-Type: application/json

[
  {
    "handle": "tool-assistant",
    "agentType": "ops-assistant",
    "models": "default",
    "plugins": ["requests"]
  }
]

Verify the selected plugin and returned fixture

  1. Deploy the plugin class, then inspect discovery for the requests alias. If the alias is absent, selecting it in an instance will not manufacture the implementation.
  2. Create or explicitly reconfigure a disposable AI instance with Plugins containing requests. Ask “Look up SR-1042 and report its status.” Inspect a real tool call and compare the result with the fixture in RequestPlugin.cs.
  3. Remove requests from that instance using an explicit update/reconfiguration and repeat. The agent should no longer have that lookup tool; a natural-language claim alone is not evidence of plugin attachment.

You have verified both discovery and per-instance attachment. Updating a JSON file without updating the existing instance is a common reason a plugin appears to be ignored.

If the result is different

Avoid singleton mutable per-agent state and duplicate tool registration. For external authentication, use connection credential references instead of secrets in Args.

Go deeper

Explore the related documentation.