From 106bb827e798bf94c19e495966cd58ef59f488d0 Mon Sep 17 00:00:00 2001 From: Brian Strauch Date: Thu, 15 Oct 2026 19:58:26 -0700 Subject: [PATCH 1/5] Document standalone Spring AI package and Spring AI 2 migration --- docs/develop/java/integrations/spring-ai.mdx | 66 +++++++++++++------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/docs/develop/java/integrations/spring-ai.mdx b/docs/develop/java/integrations/spring-ai.mdx index d4878aba26..67bb6ad03c 100644 --- a/docs/develop/java/integrations/spring-ai.mdx +++ b/docs/develop/java/integrations/spring-ai.mdx @@ -10,53 +10,53 @@ tags: - Temporal SDKs - Integrations - AI Frameworks -description: Build durable AI agents in Java with the Temporal Spring AI integration. +description: Run Spring AI 2 agents on Temporal with durable model calls, Activity tools, and replay-safe orchestration using Spring Boot 4. --- import { ReleaseNoteHeader } from '@site/src/components'; [Spring AI](https://docs.spring.io/spring-ai/reference/) is an agent framework for Java applications — chat clients, tool calling, vector stores, embeddings, and MCP servers, all wired through Spring Boot. -The [Temporal Spring AI integration](https://central.sonatype.com/artifact/io.temporal/temporal-spring-ai) makes Spring AI agents durable: model calls run through Temporal Activities recorded in Event history, and tools are dispatched per their type so each kind lands in the right place in Workflow execution — Activity stubs and Nexus stubs as durable operations, `@SideEffectTool` classes wrapped in `Workflow.sideEffect`, and plain tools running directly in Workflow code. Agents retry on failure and replay deterministically without changing how you write Spring AI code. +The [Temporal Spring AI integration](https://central.sonatype.com/artifact/io.temporal/spring-ai) makes Spring AI agents durable: model calls run through Temporal Activities recorded in Event history, and tools are dispatched per their type so each kind lands in the right place in Workflow execution — Activity stubs and Nexus stubs as durable operations, `@SideEffectTool` classes wrapped in `Workflow.sideEffect`, and plain tools running directly in Workflow code. Agents retry on failure and replay deterministically without changing how you write Spring AI code. -The integration is built on the Temporal Java SDK's [Plugin system](/develop/plugins-guide) and is distributed as the `io.temporal:temporal-spring-ai` module alongside the existing [Spring Boot integration](/develop/java/integrations/spring-boot-integration). +The integration is built on the Temporal Java SDK's [Plugin system](/develop/plugins-guide) and is distributed as the standalone `io.temporal:spring-ai` module alongside the existing [Spring Boot integration](/develop/java/integrations/spring-boot-integration). ## Prerequisites -The integration requires all of the following on your application's classpath. The plugin won't auto-configure if any of these are missing or below the listed minimum: +The integration requires all of the following on your application's classpath: | Dependency | Minimum version | | ----------------- | --------------- | | Java | 17 | -| Spring Boot | 3.x | -| Spring AI | 1.1.0 | -| Temporal Java SDK | 1.35.0 | +| Spring Boot | 4.0.8 (4.x) | +| Spring AI | 2.0.1 (2.x) | +| Temporal Java SDK | 1.40.0 | -You also need the [`temporal-spring-boot-starter`](/develop/java/integrations/spring-boot-integration) and a Spring AI model starter (for example, `spring-ai-starter-model-openai`) — `temporal-spring-ai` does not pull in a model provider on its own. +You also need the [`temporal-spring-boot-starter`](/develop/java/integrations/spring-boot-integration) and a Spring AI model starter (for example, `spring-ai-starter-model-openai`). The integration does not pull in a model provider on its own. ## Add the dependency -Add `temporal-spring-ai` alongside `temporal-spring-boot-starter` and a Spring AI model starter (for example, `spring-ai-starter-model-openai`). +Add `io.temporal:spring-ai:0.1.0` alongside `temporal-spring-boot-starter` and a Spring AI model starter (for example, `spring-ai-starter-model-openai`). The Spring AI integration is versioned separately from the Temporal Java SDK. **[Apache Maven](https://maven.apache.org/):** ```xml io.temporal - temporal-spring-ai - ${temporal-sdk.version} + spring-ai + 0.1.0 ``` **[Gradle Groovy DSL](https://gradle.org/):** ```groovy -implementation "io.temporal:temporal-spring-ai:${temporalSdkVersion}" +implementation "io.temporal:spring-ai:0.1.0" ``` -When `temporal-spring-ai` is on the classpath, the `SpringAiPlugin` auto-registers `ChatModelActivity` with all Temporal Workers created by the Spring Boot integration. Optional Activities are auto-configured when their dependencies are present: +When `io.temporal:spring-ai` is on the classpath, the `SpringAiPlugin` auto-registers `ChatModelActivity` with all Temporal Workers created by the Spring Boot integration. Optional Activities are auto-configured when their dependencies are present: | Feature | Dependency | Registered Activity | | ------------ | --------------- | ------------------------ | @@ -64,6 +64,14 @@ When `temporal-spring-ai` is on the classpath, the `SpringAiPlugin` auto-registe | Embeddings | `spring-ai-rag` | `EmbeddingModelActivity` | | MCP | `spring-ai-mcp` | `McpClientActivity` | +### Upgrade from Spring AI 1 + +`io.temporal:spring-ai:0.1.0` targets Spring AI 2 and Spring Boot 4. Spring AI 1 / Spring Boot 3 applications should remain on `io.temporal:temporal-spring-ai:1.40.x`. + +Align your application's Spring AI and Spring Boot BOMs with the supported versions above. Spring AI 2 uses Jackson 3 and immutable chat options. Pass option builders to `ChatClient`, such as `.defaultOptions(OpenAiChatOptions.builder().reasoningEffort("high"))`, or call `.mutate()` on existing options. + +Spring AI 1 Workflow histories are incompatible with this upgrade. Complete existing executions before switching versions or use separate Worker deployments for the two versions. + ## Call a chat model from a Workflow Use `ActivityChatModel` as a Spring AI `ChatModel` inside a Workflow. Every call goes through a Temporal Activity, so model responses are durable and retried per your Activity options. @@ -106,12 +114,16 @@ public ChatWorkflowImpl(String systemPrompt) { // - Activity stubs (weatherTool) become durable AI tools // - plain workflow tool classes (stringTools) execute directly in workflow // - @SideEffectTool classes (timestampTools) are wrapped in sideEffect() - // - PromptChatMemoryAdvisor maintains conversation history + // - MessageChatMemoryAdvisor maintains conversation history this.chatClient = TemporalChatClient.builder(activityChatModel) .defaultSystem(systemPrompt) .defaultTools(weatherTool, stringTools, timestampTools) - .defaultAdvisors(PromptChatMemoryAdvisor.builder(chatMemory).build()) + .defaultAdvisors( + advisors -> + advisors + .advisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) + .param(ChatMemory.CONVERSATION_ID, Workflow.getInfo().getWorkflowId())) .build(); } @@ -335,6 +347,18 @@ Keys that neither match a registered `ChatModel` bean nor equal `"default"` caus `ActivityMcpClient.create()` and `create(ActivityOptions)` work the same way for MCP tool calls, with a 30-second default timeout. +### Disable provider retries + +Disable the provider SDK's retries so each Temporal Activity attempt makes one provider request. For the Spring Boot OpenAI chat model, set: + +```properties +spring.ai.openai.chat.max-retries=0 +``` + +For manually constructed OpenAI or Anthropic models, set `.maxRetries(0)` on the provider options before building the Worker's model. Setting retries on a Workflow prompt does not reconfigure an existing provider client. + +OpenAI HTTP failures retain their native exception types. The integration classifies retryable failures and honors provider retry delays; see the [provider retry reference](https://github.com/temporalio/ai-integrations/tree/main/java/spring-ai#provider-retries) for details. + ## Provider-specific chat options Provider-specific `ChatOptions` subclasses — for example, `AnthropicChatOptions` to enable extended thinking, or `OpenAiChatOptions` to set `reasoning_effort` — pass through the Activity boundary unchanged. Attach them via `ChatClient.defaultOptions(...)` and the plugin re-applies them on the Activity side before calling the underlying model: @@ -342,12 +366,8 @@ Provider-specific `ChatOptions` subclasses — for example, `AnthropicChatOption [springai/multimodel/src/main/java/io/temporal/samples/springai/multimodel/MultiModelWorkflowImpl.java](https://github.com/temporalio/samples-java/blob/main/springai/multimodel/src/main/java/io/temporal/samples/springai/multimodel/MultiModelWorkflowImpl.java) ```java -AnthropicChatOptions thinkingOptions = - AnthropicChatOptions.builder() - .thinking(AnthropicApi.ThinkingType.ENABLED, 1024) - .temperature(1.0) - .maxTokens(4096) - .build(); +AnthropicChatOptions.Builder thinkingOptions = + AnthropicChatOptions.builder().thinkingEnabled(1024).temperature(1.0).maxTokens(4096); chatClients.put( "think", TemporalChatClient.builder(anthropicModel) @@ -360,7 +380,7 @@ chatClients.put( ``` -The pass-through relies on the `ChatOptions` subclass overriding `copy()` to return its own type — every provider class shipped with Spring AI does. +Spring AI 2 options are immutable. Pass their builder to `defaultOptions(...)`, or call `.mutate()` on an existing options object. The integration preserves provider-specific fields across the Activity boundary. ## Media in messages @@ -389,6 +409,6 @@ new McpPlugin(); ## Resources -- [`temporal-spring-ai` README](https://github.com/temporalio/sdk-java/blob/main/contrib/temporal-spring-ai/README.md) — full reference for the module +- [Temporal Spring AI README](https://github.com/temporalio/ai-integrations/tree/main/java/spring-ai) — full reference for the standalone module - [Spring Boot integration](/develop/java/integrations/spring-boot-integration) — required companion module - [Plugin system](/develop/plugins-guide) — how integrations are registered with Workers and Clients From 3857c3913d29e94c63a76706c36de5ce3d561f79 Mon Sep 17 00:00:00 2001 From: Brian Strauch Date: Thu, 15 Oct 2026 20:07:29 -0700 Subject: [PATCH 2/5] Apply suggestion from @brianstrauch --- docs/develop/java/integrations/spring-ai.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/develop/java/integrations/spring-ai.mdx b/docs/develop/java/integrations/spring-ai.mdx index 67bb6ad03c..812c58826f 100644 --- a/docs/develop/java/integrations/spring-ai.mdx +++ b/docs/develop/java/integrations/spring-ai.mdx @@ -10,7 +10,7 @@ tags: - Temporal SDKs - Integrations - AI Frameworks -description: Run Spring AI 2 agents on Temporal with durable model calls, Activity tools, and replay-safe orchestration using Spring Boot 4. +description: Run Spring AI agents on Temporal with durable model calls, Activity tools, and replay-safe orchestration using Spring Boot. --- import { ReleaseNoteHeader } from '@site/src/components'; From 8aa8bf40a1ca4e9d565d1ccb3fedc1ad060e1c65 Mon Sep 17 00:00:00 2001 From: Brian Strauch Date: Thu, 15 Oct 2026 20:07:51 -0700 Subject: [PATCH 3/5] Apply batched suggestions from code review Co-authored-by: Brian Strauch --- docs/develop/java/integrations/spring-ai.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/develop/java/integrations/spring-ai.mdx b/docs/develop/java/integrations/spring-ai.mdx index 812c58826f..8d6b4ee786 100644 --- a/docs/develop/java/integrations/spring-ai.mdx +++ b/docs/develop/java/integrations/spring-ai.mdx @@ -38,7 +38,7 @@ You also need the [`temporal-spring-boot-starter`](/develop/java/integrations/sp ## Add the dependency -Add `io.temporal:spring-ai:0.1.0` alongside `temporal-spring-boot-starter` and a Spring AI model starter (for example, `spring-ai-starter-model-openai`). The Spring AI integration is versioned separately from the Temporal Java SDK. +Add `io.temporal:spring-ai` alongside `temporal-spring-boot-starter` and a Spring AI model starter (for example, `spring-ai-starter-model-openai`). The Spring AI integration is versioned separately from the Temporal Java SDK. **[Apache Maven](https://maven.apache.org/):** @@ -46,14 +46,14 @@ Add `io.temporal:spring-ai:0.1.0` alongside `temporal-spring-boot-starter` and a io.temporal spring-ai - 0.1.0 + ${temporal-spring-ai.version} ``` **[Gradle Groovy DSL](https://gradle.org/):** ```groovy -implementation "io.temporal:spring-ai:0.1.0" +implementation "io.temporal:spring-ai:${temporalSpringAiVersion}" ``` When `io.temporal:spring-ai` is on the classpath, the `SpringAiPlugin` auto-registers `ChatModelActivity` with all Temporal Workers created by the Spring Boot integration. Optional Activities are auto-configured when their dependencies are present: @@ -64,7 +64,7 @@ When `io.temporal:spring-ai` is on the classpath, the `SpringAiPlugin` auto-regi | Embeddings | `spring-ai-rag` | `EmbeddingModelActivity` | | MCP | `spring-ai-mcp` | `McpClientActivity` | -### Upgrade from Spring AI 1 +### Upgrade from Spring AI 1.x `io.temporal:spring-ai:0.1.0` targets Spring AI 2 and Spring Boot 4. Spring AI 1 / Spring Boot 3 applications should remain on `io.temporal:temporal-spring-ai:1.40.x`. @@ -380,7 +380,7 @@ chatClients.put( ``` -Spring AI 2 options are immutable. Pass their builder to `defaultOptions(...)`, or call `.mutate()` on an existing options object. The integration preserves provider-specific fields across the Activity boundary. +Spring AI options are immutable. Pass their builder to `defaultOptions(...)`, or call `.mutate()` on an existing options object. The integration preserves provider-specific fields across the Activity boundary. ## Media in messages From 810bd719670c42d5c2f08a7593e853a14f9fb8f6 Mon Sep 17 00:00:00 2001 From: Brian Strauch Date: Thu, 15 Oct 2026 20:09:50 -0700 Subject: [PATCH 4/5] Distinguish Java runtime from Spring AI classpath dependencies --- docs/develop/java/integrations/spring-ai.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/develop/java/integrations/spring-ai.mdx b/docs/develop/java/integrations/spring-ai.mdx index 8d6b4ee786..0ac041d825 100644 --- a/docs/develop/java/integrations/spring-ai.mdx +++ b/docs/develop/java/integrations/spring-ai.mdx @@ -25,11 +25,10 @@ The integration is built on the Temporal Java SDK's [Plugin system](/develop/plu ## Prerequisites -The integration requires all of the following on your application's classpath: +Run your application on Java 17 or later, with Spring Boot, Spring AI, and the Temporal Java SDK on its classpath at the versions below: | Dependency | Minimum version | | ----------------- | --------------- | -| Java | 17 | | Spring Boot | 4.0.8 (4.x) | | Spring AI | 2.0.1 (2.x) | | Temporal Java SDK | 1.40.0 | From 70bb9cda4fb24ed27a38fa04da38646c5a5765ab Mon Sep 17 00:00:00 2001 From: Brian Strauch Date: Thu, 15 Oct 2026 20:16:52 -0700 Subject: [PATCH 5/5] Link Spring AI compatibility requirements instead of duplicating versions --- docs/develop/java/integrations/spring-ai.mdx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/develop/java/integrations/spring-ai.mdx b/docs/develop/java/integrations/spring-ai.mdx index 0ac041d825..73e267de9b 100644 --- a/docs/develop/java/integrations/spring-ai.mdx +++ b/docs/develop/java/integrations/spring-ai.mdx @@ -25,13 +25,7 @@ The integration is built on the Temporal Java SDK's [Plugin system](/develop/plu ## Prerequisites -Run your application on Java 17 or later, with Spring Boot, Spring AI, and the Temporal Java SDK on its classpath at the versions below: - -| Dependency | Minimum version | -| ----------------- | --------------- | -| Spring Boot | 4.0.8 (4.x) | -| Spring AI | 2.0.1 (2.x) | -| Temporal Java SDK | 1.40.0 | +Your application needs a Java runtime, with Spring Boot, Spring AI, and the Temporal Java SDK on its classpath. Refer to the [integration's compatibility requirements](https://github.com/temporalio/ai-integrations/tree/main/java/spring-ai#requirements-and-installation) for supported versions. You also need the [`temporal-spring-boot-starter`](/develop/java/integrations/spring-boot-integration) and a Spring AI model starter (for example, `spring-ai-starter-model-openai`). The integration does not pull in a model provider on its own. @@ -67,7 +61,7 @@ When `io.temporal:spring-ai` is on the classpath, the `SpringAiPlugin` auto-regi `io.temporal:spring-ai:0.1.0` targets Spring AI 2 and Spring Boot 4. Spring AI 1 / Spring Boot 3 applications should remain on `io.temporal:temporal-spring-ai:1.40.x`. -Align your application's Spring AI and Spring Boot BOMs with the supported versions above. Spring AI 2 uses Jackson 3 and immutable chat options. Pass option builders to `ChatClient`, such as `.defaultOptions(OpenAiChatOptions.builder().reasoningEffort("high"))`, or call `.mutate()` on existing options. +Align your application's Spring AI and Spring Boot BOMs with the integration's compatibility requirements. Spring AI 2 uses Jackson 3 and immutable chat options. Pass option builders to `ChatClient`, such as `.defaultOptions(OpenAiChatOptions.builder().reasoningEffort("high"))`, or call `.mutate()` on existing options. Spring AI 1 Workflow histories are incompatible with this upgrade. Complete existing executions before switching versions or use separate Worker deployments for the two versions.