Skip to main content

What You’ll Learn

How to run the exact same goal with three different providers. The model construction changes, but AgentClient usage is identical.

The Pattern

Provider-specific code is isolated to model construction. Everything after AgentClient.create(model) is portable:
// Provider-specific: build the model
AgentModel model = buildModel(provider);

// Portable: same code regardless of provider
AgentClient client = AgentClient.create(model);
AgentClientResponse response = client.run("Create hello.txt with 'Hello!'");

Step 1: Run with Claude

ClaudeAgentModel model = ClaudeAgentModel.builder()
    .defaultOptions(ClaudeAgentOptions.builder()
        .model("claude-sonnet-4-5")
        .yolo(true)
        .build())
    .build();

AgentClient client = AgentClient.create(model);
AgentClientResponse response = client.run(
    "Create a file named hello.txt with 'Hello from Claude!'"
);

Step 2: Run with Codex

Swap the model — the client code is identical:
CodexAgentModel model = new CodexAgentModel(
    CodexClient.create(),
    CodexAgentOptions.builder()
        .model("gpt-5-codex")
        .skipGitCheck(true)
        .build(),
    null
);

AgentClient client = AgentClient.create(model);
AgentClientResponse response = client.run(
    "Create a file named hello.txt with 'Hello from Codex!'"
);
skipGitCheck(true) lets Codex work in any directory. Without it, Codex requires a git repository. See Codex Reference for details.

Step 3: Run with Gemini

GeminiAgentModel model = new GeminiAgentModel(
    GeminiClient.create(),
    GeminiAgentOptions.builder()
        .model("gemini-2.5-flash")
        .yolo(true)
        .build(),
    null
);

AgentClient client = AgentClient.create(model);
AgentClientResponse response = client.run(
    "Create a file named hello.txt with 'Hello from Gemini!'"
);

What Stayed the Same

Across all three providers, these two lines are identical:
AgentClient client = AgentClient.create(model);
AgentClientResponse response = client.run(goal);
The only difference is which model you construct. That’s the portable API — AgentClient doesn’t know or care which provider is behind it.

Provider Differences

While the client API is portable, providers have different capabilities:
CapabilityClaudeCodexGemini
Non-git directoryWorksWorks (skipGitCheck=true)Works
Structured outputJSON SchemaNot supportedNot supported
Session resumeSupportedNot supportedNot supported
Permission modesMultiplefull-auto onlyyolo only

With Spring Boot

In Spring Boot applications, you don’t construct models manually. Use starter dependencies and Maven profiles to switch providers without changing code at all — see the Switching Providers how-to guide.

Next Steps