Skip to main content

Agents Package Cheatsheet

Root namespace: Cognesy\Agents This file is a quick, code-aligned map of the package surface. For narrative guidance and examples, use packages/agents/docs/*.md.

1. Core Loop

  • AgentLoop (readonly)
    • main orchestrator, implements CanControlAgentLoop and CanAcceptEventHandler
    • key API: default(), execute(), iterate()
    • accessors: tools(), toolExecutor(), driver(), eventHandler(), interceptor()
    • composition API: withTool(), withTools(), withDriver(), withToolExecutor(), withInterceptor(), withEventHandler(), with()
    • event API: wiretap(), onEvent()
    • note: terminal executions are auto-reset on entry to execute() / iterate()
  • CanControlAgentLoop
    • contract: execute(AgentState): AgentState, iterate(AgentState): iterable

2. State Model

  • Data\AgentState
    • immutable runtime state
    • factories: empty(), fromArray()
    • identity: agentId(), parentAgentId(), llmConfig(), executionCount(), createdAt(), updatedAt()
    • common mutators: withUserMessage(string|\Stringable|Message), withSystemPrompt(string|\Stringable), withMetadata(), withMessages(), withMessageStore(), withLLMConfig(), with()
    • step mutators: withCurrentStep(), withCurrentStepCompleted(), withExecutionCompleted(), withExecutionContinued()
    • stop/failure: withStopSignal(), withFailure(), withExecutionStatus()
    • context access: context(), store(), messages(), metadata()
    • result access: finalResponse(), currentResponse(), hasFinalResponse()
    • execution access: execution(), status(), stepCount(), steps(), usage(), errors(), hasErrors()
    • last-step accessors: lastStep(), lastStepExecution(), lastStepToolExecutions(), lastToolExecution(), lastStepErrors(), lastStepType(), lastStepUsage(), lastStepDuration()
    • stop accessors: stopSignal(), stopReason(), stopSource()
    • control: shouldStop(), forNextExecution()
    • serialization: debug(), toArray(), fromArray()
  • Data\ExecutionState
    • per-execution transient state (executionId, status, steps, continuation)
  • Data\AgentStep
    • one loop step snapshot (inputMessages, outputMessages, inferenceResponse, toolExecutions, errors)
  • Data\StepExecution
    • completed step wrapper with timing
  • Data\ToolExecution
    • one executed tool call (value(), hasError(), errorAsString(), wasBlocked())
  • Data\ExecutionBudget
    • optional limits: maxSteps, maxTokens, maxSeconds, maxCost, deadline
    • factories: unlimited()
    • queries: isEmpty(), isExhausted()
  • Data\AgentId, Data\ExecutionId, Data\AgentStepId, Data\ToolExecutionId
    • typed ID value objects

3. Enums

  • Enums\ExecutionStatusPending, InProgress, Completed, Stopped, Failed
  • Enums\AgentStepTypeToolExecution, FinalResponse, Error

4. Collections

  • Collections\Tools
    • immutable named tool collection
    • key API: has(), get(), names(), all(), count(), isEmpty(), descriptions(), withTool(), withTools(), withToolRemoved(), merge(), toToolSchema(): ToolDefinitions
  • Collections\AgentSteps
  • Collections\StepExecutions
  • Collections\ToolExecutions
  • Collections\NameList

5. Tools

Contracts

  • Tool\Contracts\ToolInterface
    • use(mixed ...$args): Result
    • toToolSchema(): ToolDefinition
    • descriptor(): CanDescribeTool
  • Tool\Contracts\CanDescribeTool
    • name(), description(), metadata(), instructions()
  • Tool\Contracts\CanExecuteToolCalls
    • executeTools(ToolCalls, AgentState): ToolExecutions
  • Tool\Contracts\CanAccessAgentState
  • Tool\Contracts\CanAccessToolCall
  • Tool\Contracts\CanManageTools

Base classes

  • Tool\Tools\SimpleTool
  • Tool\Tools\ReflectiveSchemaTool
  • Tool\Tools\FunctionTool
  • Tool\Tools\StateAwareTool
  • Tool\Tools\BaseTool
  • Tool\Tools\ContextAwareTool
  • Tool\Tools\FakeTool

Runtime

  • Tool\ToolExecutor
  • Tool\ToolRegistry
  • Tool\ToolDescriptor

6. Drivers

  • Drivers\CanUseTools
  • Drivers\CanAcceptToolRuntime
  • Drivers\ToolCalling\ToolCallingDriver (default)
  • Drivers\ToolCalling\ToolExecutionFormatter
  • Drivers\ReAct\ReActDriver
  • Drivers\Testing\FakeAgentDriver
  • Drivers\Testing\ScenarioStep

7. Context

  • Context\AgentContext
  • Context\CanCompileMessages
  • Context\CanAcceptMessageCompiler
  • Context\ContextSections
Compilers:
  • Context\Compilers\ConversationWithCurrentToolTrace (default)
  • Context\Compilers\AllSections
  • Context\Compilers\SelectedSections

8. Continuation / Stop

  • Continuation\StopReason
  • Continuation\StopSignal
  • Continuation\StopSignals
  • Continuation\ExecutionContinuation
  • Continuation\AgentStopException

9. Hooks / Interception

  • Hook\Contracts\HookInterface
  • Hook\Data\HookContext
  • Hook\Data\RegisteredHook
  • Hook\Collections\RegisteredHooks
  • Hook\Enums\HookTrigger
    • values: BeforeExecution, BeforeStep, BeforeToolUse, AfterToolUse, AfterStep, OnStop, AfterExecution, OnError
  • Hook\Collections\HookTriggers
  • Hook\HookStack
Built-in hooks:
  • Hook\Hooks\CallableHook
  • Hook\Hooks\StepsLimitHook
  • Hook\Hooks\TokenUsageLimitHook
  • Hook\Hooks\ExecutionTimeLimitHook
  • Hook\Hooks\FinishReasonHook
  • Hook\Hooks\ApplyContextConfigHook
Interception:
  • Interception\CanInterceptAgentLifecycle
  • Interception\PassThroughInterceptor

10. Builder / Capabilities

  • Builder\AgentBuilder
  • Builder\AgentConfigurator
  • Builder\Contracts\CanProvideAgentCapability
  • Builder\Contracts\CanConfigureAgent
  • Builder\Contracts\CanComposeAgentLoop
  • Builder\Contracts\CanProvideDeferredTools
  • Builder\Collections\DeferredToolProviders
  • Builder\Data\DeferredToolContext
Capability registry:
  • Capability\AgentCapabilityRegistry
  • Capability\CanManageAgentCapabilities
Core capabilities:
  • Capability\Core\UseLLMConfig
  • Capability\Core\UseGuards
  • Capability\Core\UseTools
  • Capability\Core\UseToolFactory
  • Capability\Core\UseHook
  • Capability\Core\UseDriver
  • Capability\Core\UseDriverDecorator
  • Capability\Core\UseContextCompiler
  • Capability\Core\UseContextCompilerDecorator
  • Capability\Core\UseContextConfig
  • Capability\Core\UseReActConfig
Domain capabilities:
  • Capability\Bash\UseBash
  • Capability\Cancellation\UseCooperativeCancellation
    • adds checkpoint-based cooperative cancellation to the loop
    • cancellation is cooperative: stops at BeforeExecution / BeforeStep checkpoints only — does not interrupt in-flight HTTP or tool calls
    • requires a CanProvideCancellationSignal implementation; built-in: InMemoryCancellationSource
    • stop reason reported as StopReason::UserRequested
  • Capability\File\UseFileTools
    • installs: read_file, write_file, edit_file
    • standalone file tools also available: SearchFilesTool, ListDirTool
  • Capability\Metadata\UseMetadataTools
  • Capability\Subagent\UseSubagents
  • Capability\PlanningSubagent\UsePlanningSubagent
  • Capability\StructuredOutput\UseStructuredOutputs
  • Capability\Summarization\UseSummarization
  • Capability\SelfCritique\UseSelfCritique
  • Capability\Skills\UseSkills
  • Capability\Tasks\UseTaskPlanning
  • Capability\Tools\UseToolRegistry
  • Capability\ExecutionHistory\UseExecutionHistory
  • Capability\Retrospective\UseExecutionRetrospective
  • Capability\Broadcasting\UseAgentBroadcasting

11. Broadcasting

  • Broadcasting\AgentEventBroadcaster
  • Broadcasting\AgentBroadcastObserver
  • Broadcasting\BroadcastConfig
  • Broadcasting\CanBroadcastAgentEvents

12. Templates

  • Template\Data\AgentDefinition
    • core fields: name, description, systemPrompt, label, llmConfig, capabilities, tools, toolsDeny, skills, budget, metadata
    • tool semantics: tools === null means inherit all available tools
  • Template\AgentDefinitionLoader
  • Template\AgentDefinitionRegistry
  • Template\Contracts\CanManageAgentDefinitions
  • Template\Contracts\CanInstantiateAgentLoop
  • Template\Contracts\CanInstantiateAgentState
  • Template\Parsers\CanParseAgentDefinition
  • Template\Factory\DefinitionStateFactory
  • Template\Factory\DefinitionLoopFactory
  • parsers: Template\Parsers\MarkdownDefinitionParser, JsonDefinitionParser, YamlDefinitionParser

13. Sessions

Core:
  • Session\Data\SessionId
  • Session\Data\AgentSessionInfo
  • Session\Data\AgentSession
    • access: info(), definition(), state(), sessionId(), status(), version()
  • Session\SessionRuntime — preferred API for creating new sessions and applying actions to persisted sessions
  • Session\SessionRepository — low-level persistence boundary over a store implementation
  • Session\SessionFactory — low-level helper for constructing AgentSession instances before manual persistence
Contracts:
  • Session\Contracts\CanManageAgentSessions
  • Session\Contracts\CanExecuteSessionAction
  • Session\Contracts\CanStoreSessions
  • Session\Contracts\CanControlAgentSession
Stores:
  • Session\Store\InMemorySessionStore
  • Session\Store\FileSessionStore
Actions:
  • Session\Actions\SendMessage (accepts string|\Stringable|Message)
  • Session\Actions\ForkSession (returns a new branch session object; persist that fork via repository create(); for brand-new root sessions prefer SessionRuntime::create())
  • Session\Actions\ResumeSession
  • Session\Actions\SuspendSession
  • Session\Actions\ClearSession
  • Session\Actions\ChangeModel
  • Session\Actions\ChangeSystemPrompt (accepts string|\Stringable)
  • Session\Actions\WriteMetadata
  • Session\Actions\UpdateTask
Enums:
  • Session\Enums\SessionStatusActive, Suspended, Completed, Failed, Deleted
  • Session\Enums\AgentSessionStageAfterLoad, AfterAction, BeforeCreate, AfterCreate, BeforeSave, AfterSave
Session hooks:
  • Session\SessionHookStack
  • Session\RegisteredSessionHook
  • Session\PassThroughSessionController
  • Session\Collections\SessionInfoList
Exceptions:
  • Session\Exceptions\SessionNotFoundException
  • Session\Exceptions\SessionConflictException
  • Session\Exceptions\InvalidSessionFileException

14. Events

Agent events include:
  • AgentExecutionStarted, AgentStepStarted, AgentStepCompleted
  • AgentExecutionStopped, AgentExecutionCompleted, AgentExecutionFailed
  • AgentStateUpdated
  • ContinuationEvaluated, StopSignalReceived, TokenUsageReported
  • ToolCallStarted, ToolCallCompleted, ToolCallBlocked
  • InferenceRequestStarted, InferenceResponseReceived
  • SubagentSpawning, SubagentCompleted
  • HookExecuted, DecisionExtractionFailed, ValidationFailed
  • Events\AgentEvent (base class)
Event support:
  • Events\Support\AgentEventConsoleFormatter
  • Events\Support\AgentEventConsoleObserver
Session events include:
  • SessionLoaded, SessionActionExecuted, SessionSaved
  • SessionLoadFailed, SessionSaveFailed

15. Exceptions

  • Exceptions\AgentException (base)
  • Exceptions\AgentNotFoundException
  • Exceptions\InvalidToolException
  • Exceptions\InvalidToolArgumentsException
  • Exceptions\ToolCallBlockedException
  • Exceptions\ToolExecutionBlockedException
  • Exceptions\ToolExecutionException

16. Skills

  • Capability\Skills\Skill
    • immutable skill value object
    • standard fields: name, description, license, compatibility, metadata, allowedTools, body, path, resources
    • extension fields: disableModelInvocation, userInvocable, argumentHint, model, context, agent
    • key API: render(?string $arguments), renderMetadata(), toArray()
    • argument substitution: $ARGUMENTS, $ARGUMENTS[N], $N placeholders
  • Capability\Skills\SkillLibrary
    • discovers SKILL.md files in <path>/<skill-name>/SKILL.md
    • lazy-loads skill content on first access, caches result
    • key API: listSkills(modelInvocable, userInvocable), hasSkill(), getSkill(), renderSkillList()
    • resource discovery: scans scripts/, references/, assets/, examples/ subdirs
  • Capability\Skills\LoadSkillTool
    • tool exposed to LLM: load_skill(skill_name, list_skills, arguments)
    • user-invocable filtering on list mode
  • Capability\Skills\AppendSkillMetadataHook
    • injects skill names/descriptions as system message before first step
    • filters out disable-model-invocation: true skills
  • Capability\Skills\TrackActiveSkillHook
    • tracks active skill metadata (allowed-tools, model) in state after load_skill completes
  • Capability\Skills\SkillToolFilterHook
    • enforces allowed-tools restrictions; blocks non-allowed tools (except load_skill itself)
  • Capability\Skills\SkillModelOverrideHook
    • overrides LLMConfig when a skill with a model field is active
  • Capability\Skills\SkillForkExecutor
    • executes skills in a forked agent loop context
  • Capability\Skills\SkillPreprocessor
    • executes !command“ patterns in skill body before argument substitution
    • configurable working directory and timeout
    • opt-in: pass to UseSkills or LoadSkillTool constructor
  • Capability\Skills\UseSkills
    • capability that wires LoadSkillTool + hooks into agent
    • optional ?SkillPreprocessor for shell preprocessing
  • follows Agent Skills Open Standard (30+ tools)

17. Testing

  • Drivers\Testing\FakeAgentDriver
    • scripted loop steps via ScenarioStep
    • best for most deterministic agent-loop tests
  • Tests\Support\FakeInferenceDriver
    • queued raw InferenceResponse or streaming PartialInferenceDelta fixtures
    • use when the test sits closer to the inference boundary
  • Tool\Tools\FakeTool
    • deterministic tool double with fixed or callable-backed results
  • Tests\Support\FakeSubagentProvider
    • in-memory subagent definition registry for capability tests
  • Tests\Support\TestAgentLoop
    • small loop harness with explicit max-iteration stop behavior
  • Cognesy\Sandbox\Testing\FakeSandbox (from packages/sandbox, not agents)
    • deterministic process-execution seam for bash-backed tools

18. Docs Index

Read in this order:
  1. packages/agents/docs/01-introduction.md
  2. packages/agents/docs/testing-doubles.md
  3. packages/agents/docs/02-basic-agent.md
  4. packages/agents/docs/05-tools.md
  5. packages/agents/docs/06-building-tools.md
  6. packages/agents/docs/13-agent-builder.md
  7. packages/agents/docs/14-agent-templates.md
  8. packages/agents/docs/15-subagents.md
  9. packages/agents/docs/16-session-runtime.md
  10. packages/agents/docs/19-skills.md
  11. packages/agents/docs/21-evals.md
  12. packages/agents/docs/22-eval-assertions.md
  13. packages/agents/docs/23-eval-judges.md
  14. packages/agents/docs/24-eval-traces-and-artifacts.md
  15. packages/agents/docs/25-running-evals.md

19. Evals

Behavioral evals that grade an agent target with deterministic assertions and semantic judges. Narrative docs: docs/21-evals.md through docs/25-running-evals.md. Case definition:
  • Evals\AgentEval (readonly)
    • immutable definition of one eval case
    • factories: define(description, Closure(EvalContext): void $test, ?tags, ?judge)
    • key API: withId()
    • accessors: description(), test(), tags(), id(), judge()
  • Evals\AgentEvals (readonly, Countable, IteratorAggregate)
    • immutable collection of AgentEval
    • factories: none()
    • key API: with(), filtered(?glob, ?required, ?excluded)
    • accessors: all(), count()
  • Evals\AgentEvalSet (readonly)
    • groups evals built from a dataset
    • factories: fromDataset(EvalDataset, Closure(EvalDatasetRow): AgentEval $factory), of(AgentEval ...$evals)
    • accessors: evals(): AgentEvals
  • Evals\EvalTags (readonly, Countable, IteratorAggregate)
    • normalized (trimmed, deduped, sorted) tag set
    • factories: of(), none()
    • key API: has()
    • accessors: all(), count()
  • Evals\EvalDataset (readonly, Countable, IteratorAggregate)
    • list of EvalDatasetRow
    • factories: fromJson(), fromYaml()
  • Evals\EvalDatasetRow (readonly)
    • one dataset row
    • key API: value(key), string(key)
    • accessors: toArray()
  • Evals\EvalDiscovery (readonly)
    • finds *.eval.php files under a root and assigns ids
    • factories: in(root)
    • key API: discover(): AgentEvals
    • note: an eval file must return AgentEval|AgentEvalSet|array<AgentEval>; ids are the file’s path relative to the root (with a /NNNN suffix appended when one file yields more than one eval)
  • Evals\EvalCount (readonly)
    • count predicate for calledTool()/calledSubagent()/event() assertions
    • factories: atLeast(), atMost(), between(), satisfies(Closure(int): bool)
    • key API: matches(int)
  • Evals\EvalMatch (readonly)
    • value matcher for outputMatches() and ValueExpectation::matches()
    • factories: partial(array), regex(pattern), satisfies(Closure)
    • key API: matches(mixed)
  • Evals\EvalMatcher (readonly)
    • static matching helpers used throughout: matches() (exact equality unless given an EvalMatch or array), partial() (recursive partial-array match; lists require equal length, maps require only the listed keys)
Execution context & assertions:
  • Evals\EvalContext
    • passed into every eval’s test closure; owns the session, assertion collector, and log collector for one eval run
    • key API: send(), run(): AgentRun, expect(mixed): ValueExpectation, judge(): AgentJudgeAssertions, check(), require() (throws EvalRequirementFailed on failure), skip() (throws EvalSkipped), log(), newSession()
    • built-in assertions, each returning AssertionHandle: succeeded(), stopped(), messageIncludes(), outputEquals(), outputMatches(), calledTool(), notCalledTool(), toolOrder(), usedNoTools(), maxToolCalls(), stepCount(), maxSteps(), totalTokensAtMost(), noFailedActions(), calledSubagent(), event(), notEvent(), eventOrder(), eventsSatisfy()
    • accessors: assertions(), logs()
    • note: newSession() shares this context’s collectors with the new session — EvalRunner’s repeated trials deliberately construct a brand-new EvalContext instead, so trials never share collectors
  • Evals\AssertionCollector
    • records and defer-resolves assertion results for one eval run
    • key API: record(), recordLazy(placeholder, Closure(): AssertionResult $resolve), replace(), at(index), results(): AssertionResults
    • note: recordLazy()’s resolver runs at most once, at first read via at() or results() — this is the mechanism that makes a judge run at most once
  • Evals\AssertionHandle (readonly)
    • fluent handle returned by every EvalContext/ValueExpectation assertion
    • key API: gate(), soft(), atLeast(threshold), label(), result(): AssertionResult, replace()
  • Evals\AssertionResult (readonly)
    • one assertion’s outcome
    • factories: pass(), fail()
    • key API: withSeverity(), withScore(), withThreshold(), withLabel(), withJudgeScore(), passed(): bool (score >= threshold ?? 1.0)
    • accessors: name(), score(), severity(), threshold(), message(), label(), judgeScore(), judgeClass(), toArray()
  • Evals\AssertionResults (readonly, Countable, IteratorAggregate)
    • immutable collection of AssertionResult
    • key API: with(), hasFailedGate(), hasFailedSoft()
    • accessors: all(), count()
  • Evals\AssertionSeverityGate, Soft
  • Evals\ValueExpectation
    • fluent value assertion returned by EvalContext::expect()
    • key API: includes(), equals(), matches(string|EvalMatch), similarity() (Levenshtein-based, always Soft), satisfies(Closure); chain modifiers gate(), soft(), atLeast(), label()
    • note: the chain modifiers apply only to the LAST assertion this expectation recorded, not to every assertion the expectation has made
  • Evals\EvalRequirementFailed (extends RuntimeException) — thrown by EvalContext::require() on failure; caught internally by EvalRunner, not user-visible
  • Evals\EvalSkipped (extends RuntimeException) — thrown by EvalContext::skip(); caught internally by EvalRunner and turned into EvalVerdict::Skipped
Target & sessions:
  • Evals\CanRunAgentEvalTarget — contract: open(?EvalSessionRequest): CanUseAgentEvalSession
  • Evals\LocalAgentTarget (readonly)
    • runs eval sessions in-process
    • factories: fromFactory(Closure(): CanControlAgentLoop $factory, ?EvalTracePolicy)
  • Evals\HttpAgentTarget (readonly)
    • runs eval sessions against a remote agent server over HTTP
    • key API: open(), attach(sessionId), sendTurn(), policy()
    • note: applies its EvalTracePolicy (default safe()) to whatever the remote server sends, so the HTTP path is safe by default rather than degrading to verbatim serialization
  • Evals\CanUseAgentEvalSession — contract: send(message): EvalTurn, run(): AgentRun
  • Evals\LocalEvalSessionCanUseAgentEvalSession over an in-process CanControlAgentLoop
  • Evals\HttpEvalSessionCanUseAgentEvalSession over HttpAgentTarget; accessor: sessionId()
  • Evals\HttpTargetException (extends RuntimeException) — thrown on a non-2xx response, malformed JSON, or a missing sessionId
  • Evals\EvalSessionRequest (readonly) — optional caseId/description passed to CanRunAgentEvalTarget::open()
  • Evals\EvalTurn (readonly)
    • one turn of an eval session
    • accessors: index(), message(), run(): AgentRun, reply()
Run trace:
  • Evals\AgentRun (readonly)
    • immutable accumulated projection of an eval session, across turns
    • factories: fromState(), empty(), fromArray()
    • accessors: reply(), status(), succeeded(), tools(), events(), turns(), errors(), steps(), usage(), duration(), stepCount(), stopSignal(), llmProfile()
    • note: stopSignal() is the LAST turn’s resolved signal and does NOT aggregate across turns — per-turn signals live on EvalStep::stopSignal()
  • Evals\EvalStep (readonly)
    • immutable safe projection of one StepExecution
    • factories: fromStepExecution(), fromArray()
    • accessors: id(), turn(), index(), type(), outputMessages(), requestedToolCalls(), toolExecutions(), finishReason(), usage(), duration(), stopSignal(), errors(), hasErrors(), toArray()
    • note: carries no input messages and never serializes the raw InferenceResponse
  • Evals\EvalSteps (readonly, Countable, IteratorAggregate) — ordered EvalStep collection; key API: with(), last(), usage(), duration(), toArray()/fromArray()
  • Evals\EvalToolExecutions (readonly, Countable, IteratorAggregate) — collection of Data\ToolExecution
  • Evals\EvalEvents (readonly, Countable, IteratorAggregate) — collection of arbitrary agent event objects captured during a run
  • Evals\EvalTracePolicy (readonly)
    • controls how much of a tool payload lands in a serialized trace
    • factories: safe() (default everywhere), full() (explicit opt-in, never a default)
    • key API: digest(mixed): array{hash, bytes, preview}, isDigest(), withPreviewBytes(), toArray()/fromArray()
    • accessors: isFull(), previewBytes() (DEFAULT_PREVIEW_BYTES = 120)
    • note: safe() digests tool call arguments, tool results, AND error messages — there is no size threshold, short values are digested too; preview renders the value’s SHAPE (<string:N>, <int>, <array:N>, <object:N> past MAX_PREVIEW_DEPTH = 6), never the payload itself
Judging:
  • Evals\CanJudgeAgentEval — contract: judge(JudgeRequest): JudgeScore
  • Evals\AgentLoopJudge
    • agentic judge: runs a bounded AgentLoop that inspects the target’s AgentRun and submits a verdict via the submit_judgment terminal tool
    • factories: fromBuilder(callable(): CanComposeAgentLoop $builderFactory) — the factory must return a FRESH, not-yet-built builder on every call
    • accessors: llmProfile(), guardProfile(): array{configured, hooks}
    • note: every judge() call gets a fresh builder/loop/state/event-list/JudgeSubmissionInbox — nothing leaks between calls, even repeated calls on the same instance
    • note: installs NO guards of its own — warnIfGuardsMissing() only inspects the built loop’s profile for UseGuards and, if absent, dispatches Events\JudgeGuardsNotConfigured at most once per instance; it never substitutes a limit. Install Capability\Core\UseGuards explicitly
  • Evals\PolyglotAgentJudge (readonly) — lightweight judge backed by a raw LLM call expected to return {"score":..,"reason":..} JSON; factories: fromInference(Inference), fromInvoker(Closure(string): string)
  • Evals\FakeAgentJudge (readonly) — deterministic judge double; factories: fromScore(), fromClosure(Closure(JudgeRequest): JudgeScore)
  • Evals\JudgeRequest (readonly) — criterion, output, run: AgentRun (required, not optional), input, reference
  • Evals\JudgeScore (readonly) — score (validated [0,1]), reason (non-empty), evidence: JudgeEvidence, ?run: AgentRun
  • Evals\JudgeEvidence (readonly, Countable, IteratorAggregate) — ordered evidence strings backing a JudgeScore; factories: none(), of(); note: developer-visible support for the score, never hidden model reasoning
  • Evals\JudgeCriterionFactuality, Summarizes, ClosedQa, Sql
  • Evals\AgentJudgeAssertions (readonly)
    • returned by EvalContext::judge(); built-in criteria
    • key API: factuality(reference), summarizes(source), closedQa(question), sql(reference) — each returns JudgeExpectation
  • Evals\JudgeExpectation
    • fluent judge assertion chain
    • key API: on(output) (replaces only the graded output; retains the run), gate(), soft(), atLeast(), label()
    • note: the chain only accumulates state — the judge runs AT MOST ONCE, on first read of the recorded result (AssertionCollector::results()/at()); .on() never re-runs or re-judges. Severity defaults to Gate with no judge configured, Soft with one; a judge exception always forces Gate regardless of prior gate()/soft() calls
  • Evals\SubmitJudgmentTool (extends Tool\Tools\SimpleTool)
    • the judge’s terminal tool (submit_judgment); validates score/reason/evidence and records a JudgeSubmission into its JudgeSubmissionInbox
    • constant: TOOL_NAME
  • Evals\JudgeSubmission (readonly) — one validated submit_judgment call: score, reason, evidence
  • Evals\JudgeSubmissionInbox
    • mailbox shared between SubmitJudgmentTool and JudgeProtocolHook for one judge() call
    • key API: submit(), has(), get(), attempts()
    • note: holds at most one submission — submit() never overwrites; attempts() counts only tool-body invocations, so a call blocked by JudgeProtocolHook does NOT increment it
  • Evals\JudgeProtocolHook (readonly, implements Hook\Contracts\HookInterface)
    • enforces the terminal-submission protocol on BeforeToolUse/AfterStep: blocks a second submit_judgment call, skips (does not block) any other tool call once a submission is recorded, and adds a StopReason::Completed stop signal after the submission step
  • Evals\JudgeProtocolException (extends RuntimeException) — thrown by AgentLoopJudge::judge() when the protocol was violated (no submission, a blocked second submission, or a failed run); always converted to a Gate failure by JudgeExpectation::resolve()
  • Evals\JudgePromptRenderer (readonly) — renders the judge’s fixed system prompt and per-request user prompt; wraps the target trace in <untrusted-target-trace> markers (a labeling reduction, not a security boundary)
  • Evals\UseJudgeInference (readonly, implements Builder\Contracts\CanProvideAgentCapability)
    • recommended driver capability for judge builders passed to AgentLoopJudge::fromBuilder(): installs ToolCallingDriver with temperature: 0.0 by default (caller-supplied options win)
    • note: AgentLoopJudge never installs this on the developer’s behalf — it is documented as the recommended judge driver, not injected
Repetition:
  • Evals\EvalRepetition (readonly)
    • the N trials of one repeated case; present only when a case ran more than once
    • factories: fromTrials(list<EvalResult>, passRate)
    • accessors: trials(), trialCount(), passCount(), requiredPasses(), satisfied(), allSkipped(), judgeScoreMean() (null when nothing was judged), judgeScoreStdDev() (POPULATION deviation — divided by N, not N-1; 0.0 for a single score, never a division by zero), representative() (first non-Passed trial, else the first trial), toArray()
Verdict, running & config:
  • Evals\EvalVerdictPassed, Failed, Scored, Skipped
  • Evals\EvalVerdictResolver (readonly)
    • key API: resolve(AssertionResults, skipped, ?error): EvalVerdict (error or failed gate -> Failed; skipped -> Skipped; failed soft -> Scored; else Passed), resolveRepeated(EvalRepetition): EvalVerdict (all-skipped -> Skipped; satisfied k-of-N -> Passed; else Failed)
    • static: requiredPasses(trials, passRate): intceil(passRate * trials - 1e-9) clamped to [1, trials], guarding against IEEE-754 near-integer error
  • Evals\EvalExitCodeSuccess = 0, EvalFailure = 1, ConfigurationError = 2
  • Evals\EvalRunner (readonly)
    • key API: run(AgentEvals, ?EvalRunOptions): EvalRunResult
    • note: each repeated trial opens a FRESH EvalContext/session (never EvalContext::newSession(), which shares collectors); repeat=1 returns the trial’s EvalResult unchanged, not wrapped; the cooperative timeout is a per-trial budget, not per-case
  • Evals\EvalRunOptions (readonly)
    • factories: default()
    • key API: withFilter(), withTags(), withExcludedTags(), withStrict(), withSkipReport(), withVerbose(), withTimeout(), withRepeat(), withPassRate()
    • accessors: filter(), tags(), excludedTags(), strict(), skipReport(), verbose(), timeout(), repeat(), passRate()
    • note: constructor validates repeat >= 1 and passRate in (0, 1]; repetition only measures TARGET variance when the judge is separately pinned to a fixed temperature (e.g. via UseJudgeInference) — AgentLoopJudge never installs that for you
  • Evals\EvalConfig (readonly)
    • factories: default()
    • key API: withTarget(), withJudge(), withReporters(), withReporter()
    • accessors: target(), judge(), reporters()
  • Evals\EvalApplication (readonly)
    • CLI entry point
    • key API: run(argv, ?callable $stdout, ?callable $stderr): int
    • flags: --filter=<glob>, --tag=<tag> (repeatable), --exclude-tag=<tag> (repeatable), --strict, --timeout=<seconds>, --repeat=<n>, --pass-rate=<r>, --junit=<path>, --list, --verbose, --json, --skip-report, -h/--help
    • note: loads <root>/evals.config.php when present (must return EvalConfig); --repeat rejects a non-whole-number or fractional value outright rather than silently truncating or casting it
Logging:
  • Evals\EvalLog (readonly) — one log entry: message(), context(), toArray()
  • Evals\EvalLogs (readonly, Countable, IteratorAggregate) — immutable EvalLog collection; factories: none(); key API: with()
  • Evals\EvalLogCollector — mutable collector behind EvalContext::log(); key API: record(), logs(): EvalLogs
Reporting:
  • Evals\CanReportAgentEvals — contract: id(), onRunStarted(caseCount), onEvalCompleted(EvalResult), onRunCompleted(EvalRunResult)
  • Evals\CanFailAgentEvalTestSuite (extends CanReportAgentEvals) — marker for reporters that propagate the final assertion into the host test runner
  • Evals\ConsoleEvalReporter (readonly)
    • factories: fromWriter(Closure(string): void, verbose = false)
    • key API: withVerbose()
    • note: a repeated case prints a rate line (PASS 4/5 ... judge=0.88+/-0.06) instead of a single verdict; the judge= field is omitted — not printed as a fabricated 0.00 — when nothing in the case was judged
  • Evals\ArtifactEvalReporter
    • writes a full run’s artifacts to disk under .instructor/evals/<run>/: per-eval details.json, events.ndjson, target-trace.json, target-steps.jsonl, per-judged-assertion judges/NNN.json (+ -steps.jsonl), per-trial trials/NNN/ for repeated cases, and run-level summary.json/results.jsonl
    • constructor: root, ?ClockInterface $clock, ?Closure(): ?string $gitShaResolver, ?Closure(): ?string $packageVersionResolver
    • accessors: runDirectory()
    • note: never writes a raw target-messages.json conversation snapshot — that would bypass EvalTracePolicy::safe()’s digesting and reintroduce the exact leak class the trace hardening closed
  • Evals\JUnitEvalReporter — writes JUnit XML to the path given at construction
  • Evals\PHPUnitEvalReporter (implements CanFailAgentEvalTestSuite) — factories: default(); asserts EvalExitCode::Success via PHPUnit\Framework\Assert
  • Evals\PestEvalReporter (implements CanFailAgentEvalTestSuite) — factories: default(); asserts EvalExitCode::Success via a Pest Expectation
  • Evals\EvalReporters (readonly, IteratorAggregate)
    • immutable, id-deduplicated reporter collection
    • factories: none()
    • key API: with(), withVerboseConsole() (upgrades any ConsoleEvalReporter in the collection in place)
  • Evals\EvalTestFailureMessage — static fromResult(EvalRunResult): string; renders a CI-friendly multi-line failure summary (counts, per-eval failures, repetition rate, judge evidence)
Result:
  • Evals\EvalResult (readonly)
    • outcome of one eval case, possibly a repeated case’s aggregate
    • accessors: id(), description(), verdict(), assertions(), run(), duration(), error(), skipReason(), logs(), repetition(): ?EvalRepetition, trials(), trialCount(), passCount(), judgeScoreMean(), judgeScoreStdDev(), provenance(), tokens(): array{target, judge, total}, toArray(?envelope)
    • note: provenance()['judge']['temperature'] is always null — AgentLoopJudge’s built loop exposes no temperature accessor, and reporting an assumed default would fabricate a value the judge may not have used; guardsWarningObserved is derived only from the presence of a JudgeGuardsNotConfigured event on the judge’s own run, never from its absence
  • Evals\EvalRunResult (readonly, Countable, IteratorAggregate)
    • full result of one EvalRunner::run() call
    • key API: exitCode(?bool $strict = null): EvalExitCode (EvalFailure if any result Failed, or effective-strict with any result Scored; else EvalFailure if reporterErrors() !== []; else Success), provenance(), tokens(), toArray(?envelope)
    • accessors: all(), reporterErrors(), strict()
Events:
  • Evals\Events\JudgeGuardsNotConfigured (extends Events\AgentEvent) — dispatched at most once per AgentLoopJudge instance when its built judge loop has no UseGuards capability; capability, suggestedFix