Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Verdict Console Laravel Package

fissible/verdict-console

The Artisan console companion for Fissible Verdict. It adds CLI commands to inspect, toggle, and manage Laravel feature flags, letting you check rollout status, adjust targeting, and keep environments in sync from your terminal. Ideal for local debugging, CI, and deployments.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is the operator-facing half of a human-in-the-loop approval system: Verdict governs agent behavior, and fissible/verdict-console captures approval pauses, exposes them to an operator UI, and resumes the agent after a decision. It is early-stage software (0.x, low adoption), so treat the source and release notes as the primary documentation.

Minimal path to first value:

  1. Install it alongside your Laravel AI/Verdict stack:

    composer require fissible/verdict-console
    

    Pin an exact version in composer.json. In this 0.x line, the minor version is the breaking-change boundary.

  2. Run the package installer or manually publish its config, migrations, and routes. Check the package service provider for the actual publish tags and route registration—do not assume file names from this assessment.

  3. Migrate:

    php artisan migrate
    
  4. Register your agent(s) in the console’s resumable-agent registry. Implement ResumableAgents, including the v0.12.0 requirement:

    public function versionFor(string $key): ?string
    {
        // Return an opaque token that reflects what resolve() would rebuild.
        // Return null to decline versioning for this agent.
    }
    

    The registry can also accept a host-supplied version token per registration and return it without running host factories or matchers.

  5. Configure the operator UI’s authorization. The console is an approval surface, so decide who may approve, reject, and inspect conversations before exposing routes.

  6. First use case: put a Verdict approval gate around a consequential tool call. Run the agent normally. When the pause occurs, confirm the approval appears in the operator UI, approve or reject it, and verify the agent resumes with the expected participant and conversation state.

Where to look first:

  • The package README and source service provider for publish tags, config keys, and route names.
  • src/Contracts/ResumableAgents and related registry code for registration and versioning.
  • Migrations for the approval/receipt/conversation tables.
  • Listener comments, ParticipantUnresolvable, the ConversationParticipants contract, and the design notes around §6.3 for identity behavior.
  • The v0.12.0 release notes, especially the streaming and identity changes.

Implementation Patterns

Approval-gated tool execution. The core workflow is: agent attempts a tool call → Verdict issues an approval receipt and pauses execution → the console ingests the pause → an operator acts in the UI → the agent resumes or is rejected. Keep the approval decision handler idempotent and log the receipt/pause identifier. Do not treat “tool requested” as “tool executed”; the tool remains unexecuted until the flow completes.

Resumable agent registration. Use the registry as the single place that knows how to rebuild an agent from a stored key. versionFor() should return a token that tracks what resolve() would currently rebuild. Exact equality compares declarations for the same key only; it does not verify semantic equivalence, ordering, or compatibility. Returning null means “unversioned/incomparable,” not “same as anything.”

A practical pattern:

final class AgentRegistry implements ResumableAgents
{
    public function resolve(string $key): object
    {
        // Rebuild the agent for this key.
    }

    public function versionFor(string $key): ?string
    {
        // Hash the agent class, prompt version, tool set, model, etc.
        // Must change whenever resolve() would produce a meaningfully different agent.
    }
}

Participant-bound pauses. A pause captured for a participant must be resumed as that participant, never under an identity the host cannot reproduce. Ingestion-time checks enforce this; resolution-time fidelity depends on your host resolver. If you use conversation participants, implement the ConversationParticipants contract carefully and keep strict type/key comparisons intact.

Streaming adapters. If you expose a chat adapter, use ChatService::stream($user, $conversationId, $prompt) rather than duplicating authorization and ownership checks. The returned ChatStream is lazy and single-consumption. Important operational pattern:

  • Consume the stream to completion.
  • Call turn() only after full exhaustion.
  • Relay Error events to the client and propagate Laravel AI’s terminal exception.
  • Persist console ingestion and conversation state only after exhaustion.

A Verdict-gated pause arrives as the ToolApprovalRequest event with a receipt issued and the tool unexecuted. Because console ingestion and persistence land only when the iterator is exhausted, an adapter that breaks early can leave the approval invisible or the conversation inconsistent.

Operator UI integration. Wire approvals into your existing operations surface rather than building a second approval queue. Typical pattern: notify the responsible operator/team, deep-link to the console approval record, record who acted and why, then dispatch resume processing as a queued job. Keep business policy in your application; use the console for the human decision and audit trail.

Testing pattern. Bind a fake ResumableAgents implementation in tests, assert that versionFor() is called, simulate approval pauses, and exercise resume with the same participant identity. For streaming, add tests that exhaust the stream, test turn() before/during/after an early break, and assert that persistence happens only on completion. Also test mid-stream transport failures and confirm the Error event plus terminal exception path.

Gotchas and Tips

  • 0.x breaking changes are real. v0.12.0 added a required versionFor() method. Pin the package version and read every minor release note before upgrading. Custom ResumableAgents implementations must be updated when the contract changes.
  • versionFor() must track resolve(). A stale or overly stable token can make incompatible agent reconstructions look identical. Conversely, null is incomparable and will not match another token. There is no verified equivalence or compatibility claim behind the comparison.
  • Identity reproducibility is the hard part. Participant-bound pauses require that the host can reproduce the participant identity at resume time. If your resolver depends on request-scoped state, impersonation, or ephemeral IDs, you will hit ParticipantUnresolvable. Resolve participants from durable storage.
  • Do not break a chat stream early. turn() refuses before exhaustion, during iteration, after an abandoning break, and on re-iteration. Because ingestion and conversation persistence are deferred until exhaustion, an early break is not just a UI problem—it can strand an approval.
  • Handle stream transport failures explicitly. Mid-stream failures relay the Error event and then propagate Laravel AI’s terminal exception. Catch at the adapter boundary, surface a useful message, and do not assume partial persistence occurred.
  • The console owns identity policy at ingestion. The fourth drivability condition is console-owned, not delegated to upstream participant filtering. This matters when debugging why a pause was accepted or refused.
  • Sparse documentation and low adoption. With zero dependents and almost no public documentation, inspect source, tests, migrations, and release notes before designing around a behavior. Prefer small integration spikes over large assumptions.
  • Authorization is not optional. The operator UI can approve consequential tool calls. Put it behind authentication and explicit authorization policies, and audit every decision.
  • Debugging checklist: confirm migrations ran, the registry is bound, versionFor() returns the expected token, the pause receipt was ingested, the operator decision was persisted, the resume job used the correct participant, and the queue worker is running. Log the agent key, conversation key, receipt ID, and participant identity on both pause and resume.
  • Extension points to prefer: custom ResumableAgents, config overrides, the ConversationParticipants contract, and adapter-level stream consumption. Avoid patching core authorization seams or duplicating ownership checks outside ChatService.
  • Upgrade strategy: keep a smoke test that runs an approval-gated tool call end-to-end and a streaming test that exhausts a pause. Run both after every minor upgrade; they will catch most contract and persistence regressions.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console