Recipe: swap the LLM provider

  1. Anthropic or OpenAI
  2. Pick by environment
  3. Your own backend (Gemini, Mistral, local, …)

All providers implement AiResearchProvider, so switching is a constructor change.

Anthropic or OpenAI

use Gawrys\Counterparty\Ai\Research\{AnthropicResearchProvider, OpenAiResearchProvider};

$provider = $useOpenAi
    ? new OpenAiResearchProvider($http, $openAiKey)        // gpt-4o-mini by default
    : new AnthropicResearchProvider($http, $anthropicKey); // claude-haiku-4-5 by default

Pick by environment

The bundled demos choose by which key is present:

$anthropic = getenv('ANTHROPIC_API_KEY') ?: null;
$openai    = getenv('OPENAI_API_KEY') ?: null;

$provider = $anthropic !== null
    ? new AnthropicResearchProvider($http, $anthropic)
    : new OpenAiResearchProvider($http, (string) $openai);

Your own backend (Gemini, Mistral, local, …)

Implement one method; the base class handles JSON forcing, validation, retry and the tool loop:

use Gawrys\Counterparty\Ai\Research\{AbstractAiResearchProvider, ResearchRequest};

final readonly class GeminiResearchProvider extends AbstractAiResearchProvider
{
    public function __construct(
        private \Gawrys\Counterparty\Http\JsonHttpClient $http,
        private string $apiKey,
        private string $model = 'gemini-1.5-flash',
        \Gawrys\Counterparty\Ai\Research\ResearchResultParser $parser = new \Gawrys\Counterparty\Ai\Research\ResearchResultParser(),
    ) {
        parent::__construct($parser);
    }

    protected function complete(ResearchRequest $request, array $tools): string
    {
        // POST to your model with $request->systemPrompt / $request->userPrompt,
        // expose $tools for function calling, and return the raw findings JSON.
        // Use $this->runTool(), $this->encodeToolResult(), $this->objectList() for the loop.
    }
}

That is the entire cost of a new LLM backend: one complete() implementation.


Counterparty Verification - a due-diligence aid, not a compliance product. MIT licensed.

This site uses Just the Docs, a documentation theme for Jekyll.