# LangChain4j

Use Laminarity from plain Java, streaming Java, Spring Boot, or a LangChain4j-backed agent provider.

> Verification: contract-tested; checked 2026-09-01; LangChain4j OpenAI integration 1.19.0, Spring Boot starter 1.19.0-beta29 — The plain Java example compiles on Java 17 and passes bearer-auth, max_completion_tokens, and response-parsing contract tests. Production-key certification is tracked separately.

## Add the dependency

```xml
<dependency>
  <groupId>dev.langchain4j</groupId>
  <artifactId>langchain4j-open-ai</artifactId>
  <version>1.19.0</version>
</dependency>
```

## Plain Java

Use `auto` for Laminarity selection and fallback. Set `modelName` to an id returned by `/v1/models` only when you intentionally want a direct, no-fallback request.

```java
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;

ChatModel model = OpenAiChatModel.builder()
    .baseUrl("https://api.laminarity.ai/v1")
    .apiKey(System.getenv("LAMINARITY_API_KEY"))
    .modelName("auto")
    .maxCompletionTokens(300)
    .build();

String answer = model.chat("Give me one launch checklist item.");
System.out.println(answer);
```

## Spring Boot

```properties
langchain4j.open-ai.chat-model.base-url=https://api.laminarity.ai/v1
langchain4j.open-ai.chat-model.api-key=${LAMINARITY_API_KEY}
langchain4j.open-ai.chat-model.model-name=auto
langchain4j.open-ai.chat-model.max-completion-tokens=300
langchain4j.open-ai.chat-model.max-retries=0
```

> Note: Keep provider retries at zero initially. Laminarity already owns fallback for `auto`, and a second retry layer can duplicate billable work.

## Reasoning and token limits

Prefer `maxCompletionTokens` over the deprecated `maxTokens`. Laminarity accepts both and translates the legacy field for modern compatible models.

Set `reasoningEffort` only when using a concrete model that advertises the requested effort in `/v1/models`. Leave it unset for `auto`, because Laminarity applies the selected model's execution profile.

```java
OpenAiChatModel model = OpenAiChatModel.builder()
    .baseUrl("https://api.laminarity.ai/v1")
    .apiKey(System.getenv("LAMINARITY_API_KEY"))
    .modelName("gpt-5.6-sol")
    .reasoningEffort("high")
    .maxCompletionTokens(1200)
    .maxRetries(0)
    .build();
```

## Streaming and tools

Use `OpenAiStreamingChatModel` for token streaming and LangChain4j AI Services or normal tool specifications for function calls. Begin with `auto`; pin a concrete model only when its tool and reasoning behavior is required.

Some wrappers do not retain Laminarity's additive `router_metadata`. Use the raw REST response or an OpenAI SDK when the selected provider and fallback trace must be inspected.

## OpenCode Java-port mapping

Treat the OpenCode provider id as UI configuration and LangChain4j as the HTTP transport. Resolve the selected OpenCode model to `modelName`, translate the selected variant to `reasoningEffort`, and never hard-code the project key in Java source.

Cache model discovery only briefly or refresh it on demand. `/v1/models` is project-specific, so a list obtained with one key must not be reused as an authority for another project.

## Compatibility boundary

Laminarity supports the Chat Completions path used by `OpenAiChatModel` and `OpenAiStreamingChatModel`. It does not provide LangChain4j embedding, image-generation, audio, or moderation endpoints.

Do not enable request and response logging in production when prompts may contain secrets or personal data.

## Upstream documentation

- [LangChain4j OpenAI integration](https://docs.langchain4j.dev/integrations/language-models/open-ai/)
- [LangChain4j repository](https://github.com/langchain4j/langchain4j)
