Each tool implements Laravel\Ai\Contracts\Tool with description(),
handle(Request), and schema(JsonSchema). They share a common pattern:
- Constructor receives Workspace, optional Post, userId, and an optional
AttachmentCollector (resolves from container if not injected).
- handle() does the work (Image::of(), Audio::of(), or calls our custom
VideoGenerationService for Veo), persists media + usage log, pushes
the full attachment shape into the collector, and returns a short
text summary to the LLM.
- schema() exposes typed parameters with enum constraints and doc
strings so the LLM selects valid inputs.
Also fix the Ai::extend closure signature — MultipleInstanceManager
passes (app, config) not just (config) to custom creators.