temporal-spring-ai: accept ActivityOptions and classify non-retryable AI errors#2853
Open
donald-pinckney wants to merge 5 commits intospring-ai/activity-summariesfrom
Open
temporal-spring-ai: accept ActivityOptions and classify non-retryable AI errors#2853donald-pinckney wants to merge 5 commits intospring-ai/activity-summariesfrom
donald-pinckney wants to merge 5 commits intospring-ai/activity-summariesfrom
Conversation
2a76e4e to
f967316
Compare
This was referenced Apr 21, 2026
f967316 to
1310ba4
Compare
…e error classification Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ies UX wart The activity-summaries branch only overlays Summaries when the factories (forModel/create) built the stub. Users who need custom timeouts today fall back to the public constructor, which silently drops UI Summaries. The ActivityOptions overloads planned here are the proper fix: they let users customize the stub and keep Summary labels. Plan now also covers deprecating the public constructors with javadoc pointing at the factories. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
14f61a6 to
f038d46
Compare
… AI errors - ActivityChatModel.forDefault(ActivityOptions) and forModel(String, ActivityOptions) overloads added. New public defaultActivityOptions() returns the plugin's default bundle so callers can tweak one field without losing the other sensible defaults. - ActivityMcpClient.create(ActivityOptions) + defaultActivityOptions() added, mirroring the chat side. - Default RetryOptions for chat calls now mark org.springframework.ai.retry.NonTransientAiException and java.lang.IllegalArgumentException non-retryable. Default options for MCP calls mark IllegalArgumentException non-retryable. User-supplied ActivityOptions pass through verbatim — the plugin does not augment them. - new ActivityChatModel(...) and new ActivityMcpClient(activity) constructors are @deprecated with javadoc pointing at the factories — they still work at runtime but skip the UI Summary labels the plugin-owned stub path attaches, which is now called out explicitly. - README: new "Activity options and retry behavior" section documents the defaults, how to customize, and the Summary/factory connection. - Tests: two new suites — ActivityOptionsAndRetryTest covers the non-retryable classification (1 attempt for NonTransientAiException, 3 attempts for transient RuntimeException, custom task queue landing on the scheduled activity); ActivitySummaryTest gains a regression test asserting forDefault(customOptions) still emits UI Summaries. - build.gradle: spring-ai-retry added as a testImplementation so tests can reference NonTransientAiException directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Planning scratchpad — not part of the shipped artifact. Removed before merge. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Now that forDefault(ActivityOptions) / forModel(String, ActivityOptions) / create(ActivityOptions) exist, the (Duration, int) convenience overloads are asymmetric dead weight — they expose two of N ActivityOptions fields as positional parameters, and callers wanting anything else (heartbeats, task queue, custom retry backoff, ...) have to drop to the ActivityOptions path anyway. Removed pre-release so the API surface is consistent: no-arg → plugin defaults; ActivityOptions arg → caller options. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
f038d46 to
9528294
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Based on
spring-ai/activity-summaries— adds the chat/MCP Summary plumbing this PR builds onMerge that first; this PR will auto-retarget to
master.What was changed
ActivityChatModel.forDefault(ActivityOptions)andforModel(String, ActivityOptions)overloads added. New publicdefaultActivityOptions()returns the plugin's default bundle so callers can tweak one field (e.g., task queue) without losing the other sensible defaults.ActivityMcpClient.create(ActivityOptions)+defaultActivityOptions()added, mirroring the chat side.RetryOptionsfor chat calls now markorg.springframework.ai.retry.NonTransientAiExceptionandjava.lang.IllegalArgumentExceptionnon-retryable. Default options for MCP calls markIllegalArgumentExceptionnon-retryable. User-suppliedActivityOptionspass through verbatim — the plugin does not augment them.new ActivityChatModel(...)andnew ActivityMcpClient(activity)constructors are removed. The factories are now the sole construction path. The module is pre-release so there are no pinned callers to migrate; the deprecate-then-remove cycle would be pure noise.ActivityOptionsoverload.ActivityOptionsAndRetryTestcovers non-retryable classification (1 attempt forNonTransientAiException, 3 attempts for transientRuntimeException, custom task queue landing on the scheduled activity);ActivitySummaryTestgains a regression test assertingforDefault(customOptions)still emits UI Summaries.build.gradle:spring-ai-retryadded as atestImplementationso tests can referenceNonTransientAiExceptiondirectly.Why?
Two gaps the integration guide calls out:
doNotRetrylist, a bad API key or invalid-prompt error churned through retries + backoff before failing. The new defaults fail fast on clearly permanent failures while still retrying transient ones (network, 5xx, rate-limits).(timeout, maxAttempts)— no heartbeats, task queue override, priority, ordoNotRetry. Users hitting those needs had to call the public constructor with a hand-built stub. That path silently dropped the UI Summary labels the summaries branch (temporal-spring-ai: attach activity summaries for chat and MCP calls #2852) added, so users were forced to choose between customization and readability.The new
ActivityOptionsoverloads give users both. Removing the public constructors outright means users can't accidentally end up in a code path that skips UI labels — there's one way in, and it does the right thing.Depends on #2852 (activity-summaries). The summary regression test in this PR only passes because that branch already landed the
baseOptionsplumbing the new overloads thread through.