Skip to content

[OPIK-8102] [BE] [FE] feat: expose Gemini thinking config for Vertex AI and google_ai - #8024

Merged
AndreiCautisanu merged 18 commits into
mainfrom
andreic/OPIK-8102-gemini-thinking-config
Sep 3, 2026
Merged

[OPIK-8102] [BE] [FE] feat: expose Gemini thinking config for Vertex AI and google_ai#8024
AndreiCautisanu merged 18 commits into
mainfrom
andreic/OPIK-8102-gemini-thinking-config

Conversation

@AndreiCautisanu

@AndreiCautisanu AndreiCautisanu commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Details

Gemini thinking could not be configured. The Gemini 3 dropdown that existed did nothing, and 2.5 Flash Lite ships with thinking off so it could not be turned on at all. That was the customer report.

Adds a thinking level dropdown for every Gemini model that supports thinking, on both Vertex AI and google_ai. Sent as custom_parameters.thinking.level, same as Anthropic thinking.

Two things needed care:

  • The old flat thinking_level was being thrown away. The backend deserializes the playground body into langchain4j's ChatCompletionRequest, which drops unknown fields. custom_parameters is the only field taking arbitrary keys, so the level goes there.
  • Not every model takes a level. thinking_level only works on google_ai with Gemini 3+. Older models error, and Vertex has no level field at all. So the UI always shows a level and the backend converts it to thinking_budget where needed. Sending both is a 400, so only one is ever set.

Reviewing this

  • GeminiThinkingParams — decodes both shapes (JsonNode for rules, Map for the playground) and converts level to budget. One place, so the paths cannot disagree.
  • THINKING_LEVELS_BY_MODEL in modelUtils.ts — which levels each model allows, from Google's table. They vary per model: 3.7 Flash has no minimal, 3.1 Flash Lite only minimal and high. Adding a model is one line. Note new models arrive via an automated sync job that won't know to update this table.
  • Each model preselects its own documented default rather than always high: 2.5 gets auto, 2.5 Flash Lite off, 3.7/3.6/3.5 Flash medium. Opening the dropdown doesn't change model behaviour.
  • auto and off are ours, not Google's, and only on pre-Gemini-3 models. auto sends nothing, which is how you ask for a dynamic budget. off sends budget 0, only on 2.5 Flash Lite, since 2.5 Pro can't turn thinking off.

Behaviour change: prompts that sent no thinking config now send the model default. For 2.5 that default is auto, which still sends nothing.

Change checklist

  • User facing
  • Documentation update

Issues

  • Resolves OPIK-8102

AI-WATERMARK

AI-WATERMARK: yes

  • Tools: Claude Code
  • Model(s): claude-opus-5
  • Scope: Investigation, backend decoding and translation, frontend gating and request shaping, tests, this description.
  • Human verification: Author reviewed the diff and the level to budget numbers, and reproduced the Gemini 2.5 level rejection in the playground on the PR env.

Testing

  • Backend: mvn test -Dtest='com.comet.opik.infrastructure.llm.**' → 1156 pass, was 1077. spotless:check clean. VertexAIClientGeneratorTest checks the real outbound request body with WireMock, not internal state.
  • Frontend: npx vitest run → 2294 pass, was 2269. Typecheck and eslint --max-warnings=0 clean.
  • Manual: reproduced the Flash Lite case and the 2.5 rejection in the playground on the PR env.

Not run: full mvn verify, which fails locally on unrelated ClickHouse/Testcontainers problems, so relying on CI. Budget numbers are confirmed as sent but not as accepted for every model, so worth trying 2.5 Flash and a 3.x Flash before release.

Documentation

No docs change. This is a UI control, not a documented API surface, and the dropdown already has a tooltip.

AndreiCautisanu and others added 2 commits August 26, 2026 14:35
…king config

Gemini thinking cannot be configured on the Vertex provider because Opik builds
a protobuf GenerationConfig, and the 1.27.0 that langchain4j-vertex-ai-gemini
pins transitively has no thinking_config field. 1.52.0 adds
GenerationConfig.ThinkingConfig (include_thoughts, thinking_budget).

langchain4j's VertexAiGeminiChatModel builder exposes no thinking option either,
and Opik bypasses that builder anyway, so the protobuf is the only lever.

The org.jetbrains:annotations exclusion is required, not incidental: the bump
otherwise downgrades it to 13.0, whose @NotNull lacks TYPE_USE, which fails the
test sources' type-context usages and cascades into ~200 misleading
"cannot find symbol" errors on Lombok-generated members.

Verified: dependency tree resolves vertexai 1.52.0 with annotations held at
17.0.0, and the infrastructure.llm.** suites pass (1077 tests, 0 failures).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Gemini calls ran at Google's per-model default thinking behaviour with no way
to enable, tune, or disable it. Most visibly, Gemini 2.5 Flash Lite ships with
thinking off, so there was no way to turn it on at all.

Thinking is carried as custom_parameters.thinking.level, following the Anthropic
precedent. This matters on the playground path: the request body is a flat spread
of the config and deserializes into langchain4j's ChatCompletionRequest, which
discards unknown top-level fields — the pre-existing flat thinking_level was
being dropped silently. custom_parameters is the only free-form slot it captures.

The two providers do not expose the same knobs. Google AI Studio takes a thinking
level directly; the Vertex GenerationConfig.ThinkingConfig protobuf has only
thinking_budget and include_thoughts, so a level is translated into a budget
there. GeminiThinkingParams holds that translation and decodes both custom
parameter shapes (JsonNode for judge rules, Map for the playground).

Frontend: the level control was gated to Gemini 3 and now covers the 2.5 family
on both providers, with an "off" option and an off default for Flash Lite so its
disabled-by-default behaviour is preserved. Rule forms fold the selection into
custom_parameters on save and read it back on load, so it survives a round trip.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@AndreiCautisanu
AndreiCautisanu requested review from a team as code owners August 26, 2026 12:11
@github-actions github-actions Bot added java Pull requests that update Java code Frontend Backend tests Including test files, or tests related like configuration. typescript *.ts *.tsx 🔴 size/XL labels Aug 26, 2026
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

⏱️ pre-commit per-hook timing

Hook Description Result Duration
🌐 typecheck — frontend Whole-project tsc type check 17.49s
☕ spotless — java backend Format Java code 8.29s
🌐 eslint — frontend Lint + autofix JS/TS 6.15s
🛡️ semgrep — java backend sql Block SQL injection-prone string formatting 1.84s
Total (4 ran) 33.77s
⏭️ 40 skipped (no matching files changed)
Hook Description Result
🐍 trim trailing whitespace — python sdk Strip trailing whitespace ⏭️
🐍 fix end of files — python sdk Ensure files end in a newline ⏭️
🐍 ruff — python sdk Lint + autofix Python (ruff) ⏭️
🐍 ruff-format — python sdk Format Python code (ruff) ⏭️
🐍 mypy — python sdk Static type check ⏭️
🤖 trim trailing whitespace — optimizer Strip trailing whitespace ⏭️
🤖 fix end of files — optimizer Ensure files end in a newline ⏭️
🤖 check yaml — optimizer Validate YAML syntax ⏭️
🤖 check json — optimizer Validate JSON syntax ⏭️
🤖 check toml — optimizer Validate TOML syntax ⏭️
🤖 check for added large files — optimizer Block large files (>1MB) ⏭️
🔐 detect private key — optimizer Block committed private keys ⏭️
🤖 check for merge conflicts — optimizer Block merge-conflict markers ⏭️
🤖 check for case conflicts — optimizer Block case-only name clashes ⏭️
🤖 pyupgrade — optimizer Modernize Python syntax ⏭️
🤖 ruff — optimizer Lint + autofix Python (ruff) ⏭️
🤖 ruff-format — optimizer Format Python code (ruff) ⏭️
🤖 mypy — optimizer Static type check ⏭️
📓 nbstripout — optimizer notebooks Strip notebook output ⏭️
📝 markdownlint — optimizer Lint Markdown ⏭️
🔤 codespell — optimizer Fix common misspellings ⏭️
📊 radon cc — optimizer Cyclomatic-complexity gate ⏭️
📊 radon raw — optimizer Raw size metrics gate ⏭️
📊 xenon — optimizer Fail on complexity thresholds ⏭️
📊 lizard — optimizer Cyclomatic-complexity gate ⏭️
🧹 vulture — optimizer Find dead code ⏭️
🛡️ trim trailing whitespace — guardrails Strip trailing whitespace ⏭️
🛡️ fix end of files — guardrails Ensure files end in a newline ⏭️
🛡️ ruff — guardrails Lint + autofix Python (ruff) ⏭️
🛡️ ruff-format — guardrails Format Python code (ruff) ⏭️
🛡️ mypy — guardrails Static type check ⏭️
⚓ helm-docs Regenerate Helm chart README ⏭️
block non-public FE plugins Block non-public FE plugins ⏭️
🧪 pre-commit wrapper smoke tests Self-test the wrapper scripts ⏭️
🧪 rebaseline script tests Self-test the changelog re-baseline script ⏭️
📘 eslint — typescript sdk Lint + autofix JS/TS ⏭️
📘 typecheck — typescript sdk Whole-project tsc type check ⏭️
⚙️ actionlint — github workflows Lint GitHub Actions workflows ⏭️
🐳 hadolint — dockerfiles Lint Dockerfiles ⏭️
🌈 zizmor — github workflows security Security-scan GitHub Actions workflows ⏭️

@CometActions

CometActions commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

This change looks worth a test.

The thinking-level control is a pure lookup off the selected model (getThinkingLevelOptions / getDefaultThinkingLevel), and nothing in the e2e estate touches it — playground.configure-model-settings and online-evaluation.edit-rule are both covered: false, and grepping the whole suite for thinking or custom_parameters returns nothing. A wrong option list or default silently changes what a run is billed for, and Flash-Lite's off default is the one case where drift turns thinking ON for a model that shipped with it off. Specs for exactly this already exist in the stacked draft #8025 — but they were written against 69628ad and predate feat(llm): add an Auto thinking level: they assert Off/Low/Medium/High preselecting High for Gemini 2.5 Pro (now Auto/Low/Medium/High preselecting Auto) and High (Default) labels this PR deleted, so they fail against 1e21fa8. That draft wants refreshing, not a second proposal. Neither spec reaches your newest commit's case either: an unedited save of an Anthropic judge rule must keep custom_parameters.thinking.budget_tokens.

Would target playground.configure-model-settings, online-evaluation.edit-rule.

What it would check
  1. Seed throwaway Gemini and Vertex AI provider keys so their models are pickable, then open the Playground's Model parameters popover
  2. For each Gemini 2.5 and 3.x model on both providers, assert the WHOLE thinking-level option list and the preselected default, alternating providers between picks so carried-over config is not mistaken for a default
  3. Create a Gemini LLM-judge rule, set a non-default level, and check code.model.custom_parameters.thinking.level via the API; reopen it, re-save untouched, and confirm the dialog did not overwrite the level with the model default
  4. Create an Anthropic judge rule holding custom_parameters.thinking.budget_tokens, save it unchanged from the UI, and confirm the budget survives — the case commit 1e21fa8 is about
  5. Switch a variant between two Gemini models WITHIN one provider and see whether a stale level is reconciled; [OPIK-8102] [QA] E2E specs for the Gemini thinking level (from the #8024 exploration) #8025 reports it is not, and a stale off renders the control blank

Deploying a test environment for this PR and exploring it — results will follow in a comment.

Not testable yet. The half the PR is named for — a level reaching Google as thinking_level on Gemini 3, as a translated thinking_budget on 2.5 and on Vertex at every version, off as budget 0, and never both keys at once — is only observable in the request Opik sends upstream. The e2e estate wires OPENAI_API_KEY and ANTHROPIC_API_KEY only (end2end_suites_v2.yml), the Gemini entry in playground-models.yaml skips itself when GEMINI_API_KEY is unset, and the mock gateway at services/mock-token-auth/ is OpenAI-shaped so it cannot stand in for Gemini or Vertex. The same applies to ExperimentMessageRenderer now forwarding custom_parameters on experiment runs. So the control can be pinned and the wire cannot — that translation stays on GeminiThinkingParamsTest / GeminiThinkingConfigMapperTest / VertexAIClientGeneratorTest for now.

also touches Backend (Java API / internal)

Run

Advisory, from the QA test radar. Nothing here blocks this PR, and anything it proposes is a draft for review.

Re-checked after a push on 03 Sep 07:05 UTC — nothing the verdict depends on changed.

@CometActions CometActions added the test-environment Deploy Opik adhoc environment label Aug 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔄 Test environment deployment process has started

Phase 1: Deploying base version 2.2.42-6454 (from main branch) if environment doesn't exist
Phase 2: Building new images from PR branch andreic/OPIK-8102-gemini-thinking-config
Phase 3: Will deploy newly built version after build completes

You can monitor the progress here.

Comment thread apps/opik-frontend/src/lib/modelUtils.ts Outdated
@CometActions

Copy link
Copy Markdown
Collaborator

Test environment is now available!

To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml)

Access Information

The deployment has completed successfully and the version has been verified.

@CometActions

Copy link
Copy Markdown
Collaborator

🌙 Nightly cleanup: The test environment for this PR (pr-8024) has been cleaned up to free cluster resources. PVCs are preserved — re-deploy to restore the environment.

@CometActions CometActions removed the test-environment Deploy Opik adhoc environment label Aug 27, 2026
Base automatically changed from andreic/OPIK-8102-bump-google-cloud-vertexai to main August 27, 2026 07:09
Comment thread apps/opik-frontend/src/lib/modelUtils.ts Outdated
…gence

Follow-up on the review of this PR.

Backend:
- VertexAIClientGenerator: filter customParameters to object nodes before
  converting to a Map. custom_parameters is unvalidated free-form JSON and
  Jackson throws IllegalArgumentException on an array or scalar, which failed
  the whole evaluation run on a path that previously ignored the field.
- GeminiThinkingConfigMapper: resolve the off-level budget through
  budgetForLevel() so an explicit budget_tokens wins on Google AI Studio
  exactly as it does on Vertex, instead of the two providers disagreeing.
- ExperimentMessageRenderer: forward custom_parameters, which applyConfigs
  dropped, so a thinking level selected for an experiment reaches the request
  rather than falling back to the provider default.

Frontend:
- Split the 2.5 option list: only Flash and Flash Lite can disable thinking,
  so 2.5 Pro no longer offers "off" (a zero budget it rejects).
- updateProviderConfig: reconcile a stale thinkingLevel on model change,
  mirroring the OpenAI reasoningEffort and Anthropic thinkingEffort handling.
- getThinkingLevelOptions: drop the unreachable Vertex 3 Flash arm, which
  supportsVertexAIThinkingLevel does not enable.
- Rule form: strip the persisted thinking block before re-adding the validated
  selection, so a rejected level no longer survives the custom_parameters
  spread; merge into the existing block so budget_tokens and include_thoughts
  are kept across an unchanged round trip.
- sanitizeConfigForRequest: fold the level under custom_parameters only for
  callers that opt in, since the optimizer gateway consumes the same output as
  flat llm_model.parameters; merge rather than replace the thinking block.

Backend 1150 tests pass (1133 before, 17 added), spotless clean. Frontend 2280
pass (2269 before, 11 added), typecheck and eslint clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the dependencies Pull requests that update a dependency file label Aug 27, 2026
@CometActions CometActions added the test-environment Deploy Opik adhoc environment label Aug 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔄 Test environment deployment process has started

Phase 1: Deploying base version 2.2.42-6454 (from main branch) if environment doesn't exist
Phase 2: Building new images from PR branch andreic/OPIK-8102-gemini-thinking-config
Phase 3: Will deploy newly built version after build completes

You can monitor the progress here.

Comment thread apps/opik-frontend/src/lib/modelUtils.ts Outdated
Comment thread apps/opik-frontend/src/lib/modelUtils.ts Outdated
The thinking dropdown fell back to getDefaultThinkingLevel() for display only.
In the playground that matched what was sent, because getDefaultConfigByProvider
seeds thinkingLevel into the config; the rule form seeds no provider defaults, so
an untouched control read "Off" on 2.5 Flash Lite while persisting nothing and
letting the provider default apply.

updateProviderConfig already runs on model change in both forms, so the fix is to
have its Gemini/Vertex branch set the default when no level is held, not only
coerce a stale one. The displayed level is now the persisted and sent level.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@CometActions

Copy link
Copy Markdown
Collaborator

Test environment is now available!

To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml)

Access Information

The deployment has completed successfully and the version has been verified.

Comment thread apps/opik-frontend/src/lib/modelUtils.ts
Comment thread apps/opik-frontend/src/lib/modelUtils.ts
@CometActions

Copy link
Copy Markdown
Collaborator

🌙 Nightly cleanup: The test environment for this PR (pr-8024) has been cleaned up to free cluster resources. PVCs are preserved — re-deploy to restore the environment.

@CometActions CometActions removed the test-environment Deploy Opik adhoc environment label Aug 29, 2026

@aadereiko aadereiko left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Data loss: saving an LLM-judge rule deletes the persisted thinking block
    AddEditRuleDialog strips custom_parameters.thinking for any model in the level table, then re-adds it only if a valid, non-auto level exists. When the level is auto (or absent), nothing is re-added

  2. Optimizer: the saved level is silently reset to the model default on re-run
    Rules parse the level back out of custom_parameters.thinking.level on load. The optimizer form never does. convertOptimizationToFormData just merges the saved parameters blob into modelConfig, so thinkingLevel comes back undefined, and sanitizeConfigForRequest then substitutes the model default

  3. The optimizer doesn't go through ChatCompletionRequest

…evel

From @aadereiko's review.

1. Rule save deleted the persisted thinking block whenever the form produced no
   level of its own. The Anthropic case was already gated, but a Gemini model whose
   default level is "auto" (2.5 Pro/Flash) hits the same path: the block is stripped
   and nothing re-adds it, losing budget_tokens and include_thoughts on an unedited
   save. The strip is now limited to the two cases that need it — the form is putting
   a level back, or the form held a level this model rejects (a stale "off" carried
   onto a model that cannot disable thinking).

2. sanitizeConfigForRequest overwrote a level already nested under
   custom_parameters with the model default, because only the flat thinkingLevel
   counted as "stored". A caller that persists the sanitized output and reloads it
   has no flat field: the optimizer form merges a saved run's parameters blob
   wholesale, so a saved level was reset to the default on every re-run. A nested
   level now counts as stored, with the flat field still taking precedence.

Only reproduced on models whose default is a real level — on 2.5 the "auto" default
skips the fold, which is why the earlier optimizer test did not catch it.

Frontend 2301 tests pass (2298 before, 3 added), typecheck and eslint clean.
Backend untouched; spotless clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@CometActions CometActions added the test-environment Deploy Opik adhoc environment label Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🔄 Test environment deployment process has started

Phase 1: Deploying base version 2.2.45-6488 (from main branch) if environment doesn't exist
Phase 2: Building new images from PR branch andreic/OPIK-8102-gemini-thinking-config
Phase 3: Will deploy newly built version after build completes

You can monitor the progress here.

@CometActions

Copy link
Copy Markdown
Collaborator

Test environment is now available!

To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml)

Access Information

The deployment has completed successfully and the version has been verified.

aadereiko
aadereiko previously approved these changes Sep 2, 2026

@aadereiko aadereiko left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FE code looks good, thank you for addressing the comments :)

@thiagohora thiagohora left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opik reviewer (mined from your team's review history)

25 findings — 1 high · 24 medium · 0 low. Suppressed by team conventions: see suppressed.md.

React 👍/👎 on each comment — your feedback helps tune what it flags.

…discarded

From @thiagohora's review.

The high finding: GeminiThinkingConfigMapper honoured
custom_parameters.thinking.include_thoughts, but returnThinking is pinned to
Boolean.FALSE on the model (Gemma 4 returns thought parts unconditionally and they
would otherwise be concatenated into the answer). Verified in langchain4j 1.19's
PartsAndContentsMapper: at FALSE a thought part is neither collected into
thinking() nor appended to the text — it is dropped. So the flag billed for
thinking tokens and returned nothing.

Vertex has the mirror problem: nothing there filters thought parts, because
langchain4j builds the answer from ResponseHandler.getText(), which concatenates
every part with no thought check and has no returnThinking equivalent. Forwarding
include_thoughts would prepend the reasoning trace to the answer, and on the judge
path that breaks the JSON parse in OnlineScoringEngine, producing no scores.

Neither provider can currently surface thoughts, and the frontend never authors the
flag — it only preserves one already present. So it is no longer forwarded on either
path, with the reasoning recorded at both sites. Wire it up alongside a way to
actually return the thoughts.

Also corrected a comment that claimed Gemini 3+ "does not accept a budget", which
contradicted the Vertex path relying on exactly that. Gemini 3 does accept
thinking_budget — verified live on both providers earlier in this PR. The "off"
early-return is about "off" being meaningless on a model that cannot disable
thinking, not about budgets in general.

Test coverage for two smaller findings: budgetForLevel() with an explicit zero
budget alongside a level (0 must win, not read as absent), and the renderer's
non-object custom_parameters branch parameterised over array/string/number/boolean/
null instead of only an array.

Backend 1177 tests pass, spotless clean. Frontend 2314 pass, untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ertex

@thiagohora is right that the Anthropic half of that claim is false today, and
worse than merely inaccurate: LlmProviderAnthropicMapper declares no mapping for
thinking/customParameters, so the block never reaches AnthropicCreateMessageRequest,
while its thinkingEnabled(request) does read custom_parameters. Forwarding a
thinking block on that path therefore gates temperature/top_p off without enabling
thinking.

Wiring Anthropic thinking through the experiment path is its own change. Comment now
says what is actually true and why an Anthropic experiment should not carry the
block until then.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@thiagohora's second look at the OFF early-return was right on one half.

`{level: off, budget_tokens: 4096}` on a Gemini 3+ model hit the early return and
discarded the explicit budget, while the same input on 2.5 resolves through
budgetForLevel() and sends 4096 — contradicting what explicitBudgetWinsOverLevelOff
asserts for 2.5. The early return is now gated on there being no explicit budget, so
only the unusable level is dropped and the budget wins on both families.

The include_thoughts half of that finding is moot: cc47af6 stopped forwarding it
on every path, so the early return has nothing to discard there.

Also closes the second half of the renderer-test finding: applyConfigParameters has
configs present with no custom_parameters key and never asserted the outcome, so it
now asserts customParameters() stays null.

Backend 1178 tests pass, spotless clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@CometActions

Copy link
Copy Markdown
Collaborator

🌙 Nightly cleanup: The test environment for this PR (pr-8024) has been cleaned up to free cluster resources. PVCs are preserved — re-deploy to restore the environment.

@CometActions CometActions removed the test-environment Deploy Opik adhoc environment label Sep 3, 2026
…version-gate tests

Three more from @thiagohora's review, all of which turned out to be real.

sentGenerationConfig() returned path("generationConfig"), which degrades to a
MissingNode. Every negative assertion built on it passed for the wrong reason:
renaming the field to a typo left 20 of 23 tests green, including all four that
assert a thinking block is absent. It now uses get() and asserts the node exists —
the same sabotage fails 10.

levelOffDisablesThinking had the same defect one level down: MissingNode
.path("thinkingBudget").asInt() is 0, so isZero() succeeded whether budget 0 was
sent or nothing was. It now asserts the block and the field are present first.
Verified by removing the setThinkingConfig call: the test fails, where before it
would have passed.

modelAcceptsLevel coverage moved to GeminiThinkingParamsTest, where the method
lives, replacing two near-duplicates in the mapper suite. Extended with the
unversioned ids the heuristic cannot parse — gemini-omni-flash-preview,
gemini-flash-latest — which read as pre-3 and get a budget. That is the safe
direction: a budget is accepted on every generation, a level on a pre-3 model is
rejected outright. Recorded in the javadoc, since it looked accidental.

Also covers both accepted budget boundaries on the map path (0 and MAX_VALUE),
which only had rejection cases.

Backend 1172 tests pass, spotless clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@CometActions CometActions added the test-environment Deploy Opik adhoc environment label Sep 3, 2026
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🔄 Test environment deployment process has started

Phase 1: Deploying base version 2.2.45-6488 (from main branch) if environment doesn't exist
Phase 2: Building new images from PR branch andreic/OPIK-8102-gemini-thinking-config
Phase 3: Will deploy newly built version after build completes

You can monitor the progress here.

@CometActions

Copy link
Copy Markdown
Collaborator

Test environment is now available!

To configure additional Environment variables for your environment, run [Deploy Opik AdHoc Environment workflow] (https://github.com/comet-ml/comet-deployment/actions/workflows/deploy_opik_adhoc_env.yaml)

Access Information

The deployment has completed successfully and the version has been verified.

@AndreiCautisanu
AndreiCautisanu merged commit 380fac1 into main Sep 3, 2026
96 checks passed
@AndreiCautisanu
AndreiCautisanu deleted the andreic/OPIK-8102-gemini-thinking-config branch September 3, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backend Frontend java Pull requests that update Java code 🔴 size/XL test-environment Deploy Opik adhoc environment tests Including test files, or tests related like configuration. typescript *.ts *.tsx

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants