Skip to main content
A Plugin is a way to compose lifecycles with a stable identity. Use one to keep the setup and teardown a condition needs at different execution scopes together. A Plugin does not configure an Agent or provide a second Sandbox command or resource system. Agent Skills, MCP servers, native Plugins, and configuration files still go directly to the Agent factory. Sandbox images and commands still belong in the sandbox declaration.

Define multiple lifecycles

Import every Plugin API from niceeval/plugin:
name names the Plugin family. instanceKey(options) distinguishes configurations within one family. Raise behaviorRevision when implementation semantics change so old results are no longer adopted exactly. A family with no options can omit instanceKey; its fixed instance key is "default". Each fragment can declare identity, and must provide at least setup or teardown.

Compose several Plugins in one place

plugins always accepts an array:
Setup runs in array order, and teardown runs in reverse order. If one Plugin’s setup fails, NiceEval still calls that occurrence’s teardown and continues with the other finishing callbacks.

Choose a lifecycle scope

One family can declare four fragments: The caller mounts an occurrence only in the plugins array of defineExperiment, defineEvalGroup, or defineEval. If an occurrence also declares a sandbox fragment, NiceEval automatically applies it to that owner’s physical Sandbox. SandboxLayer has no additional Plugin mounting syntax.
An Attempt adopted in full does not run Plugin lifecycles. During partial adoption, only scopes that actually run activate their lifecycles.

Inspect the plan first

First confirm the Plugin identity and the Attempts that need to run:
When you change setup or teardown behavior, raise behaviorRevision too. NiceEval cannot know that an old result corresponds to changed behavior when you change only a callback function body and leave its identity unchanged.

Continue reading