Skip to content

feat(gooddata-eval): let evaluations request a reasoning effort - #1709

Merged
hkad98 merged 1 commit into
gooddata:masterfrom
hkad98:jkd/eval-reasoning-effort
Aug 4, 2026
Merged

feat(gooddata-eval): let evaluations request a reasoning effort#1709
hkad98 merged 1 commit into
gooddata:masterfrom
hkad98:jkd/eval-reasoning-effort

Conversation

@hkad98

@hkad98 hkad98 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an optional reasoning effort to gooddata-eval, so an evaluation run can request LOW, MEDIUM or HIGH instead of always using the endpoint default.

It is sent as options.reasoningEffort on each chat message and threaded through ChatClient, the seven evaluate_agentic_* entry points, the agentic runner, and the CLI (--reasoning-effort).

Contract

Per the AI chat OpenAPI schema (/api/v1/schemas/gen-ai):

  • SendMessageOptions.reasoningEffort — camelCase, sibling of item on the send-message request body.
  • Typed as RequestedReasoningEffort, an enum of exactly LOW, MEDIUM, HIGH.
  • Nullable (anyOf: [$ref, null]), so omitting the key is valid and is what this change does by default.
  • Documented there as applying to that single message only, and not persisted.

The implementation mirrors all four: uppercase Literal, camelCase key, per-message send, key omitted when unset.

Why

The SDK had no way to set this, so every evaluation ran at whatever the endpoint defaults to. That makes reasoning effort the one request-level option the suite cannot vary, even though it plausibly affects both latency and answer quality — exactly the kind of thing an evaluation harness exists to measure.

The intent is for effort to become an evaluation dimension alongside model version, so the two can be compared in the same report.

Notes for reviewers

  • Default is None, which omits the key entirely and leaves the request payload byte-identical to before. There is a test asserting full-body equality for that case, so existing runs cannot be affected.
  • Both Langfuse writers record the effort. build_run_context suffixes the dataset-run name and adds run metadata; LangfuseSink suffixes its run name and reports the effort via trace tags. Metadata alone is not a breakdown dimension — the same reason model_version already uses first-class fields there. Without the run-name suffix, two runs differing only by effort share a name and merge in the report, which defeats the comparison.
  • Typed Literal["LOW", "MEDIUM", "HIGH"] to match the spec enum, with the CLI deriving its choices from that alias so the two cannot drift. An invalid value then fails locally instead of surfacing as a validation error partway through a run.
  • New parameters are appended to the end of the public evaluate_agentic_* signatures rather than inserted mid-list, so existing positional callers of this released package keep binding correctly.
  • Because the spec scopes the option to a single message, the value is re-sent on every send_message — which is what the multi-turn evaluators need.
  • The server honours it only when the corresponding organization feature is enabled, so setting it is a request rather than a guarantee. Noted in the README.
  • Summary items go through SummaryClient, whose request body has no equivalent option, so the flag applies to chat items only. Also noted in the README.

Testing

  • tests/test_sse_client.py — payload unchanged when unset; the option sent for each of LOW/MEDIUM/HIGH; applied to every message on a multi-turn client; propagated through ask().
  • tests/test_agentic_run_context.py — run-name suffix and run metadata, that the effort does not displace model_version, and that an unset effort leaves both unchanged.
  • tests/test_cli.py — the flag reaches ChatClient, and a value outside the enum is rejected by argparse.
  • 262 tests pass; ruff check, ruff format --check and ty check are clean.

Unrelated to the feature: this also removes an unused local in tests/test_cli.py that was already failing ruff on master.

Summary by CodeRabbit

  • New Features

    • Added a --reasoning-effort option with LOW, MEDIUM, and HIGH settings.
    • Applied reasoning-effort selection across chat, evaluations, and agentic workflows.
    • Added validation, normalization, and optional request forwarding for the selected setting.
    • Included the selected effort in evaluation metadata, run names, and trace tags.
  • Documentation

    • Documented supported reasoning-effort levels and feature-flag requirements.
  • Tests

    • Added coverage for CLI validation, request behavior, normalization, and metadata tracking.

@hkad98
hkad98 requested review from lupko and pcerny as code owners August 4, 2026 14:00
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4053dd98-c46e-4c67-91e9-721e9abea583

📥 Commits

Reviewing files that changed from the base of the PR and between 115c616 and 49949a5.

📒 Files selected for processing (17)
  • packages/gooddata-eval/README.md
  • packages/gooddata-eval/src/gooddata_eval/cli/agentic_runner.py
  • packages/gooddata-eval/src/gooddata_eval/cli/main.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/_langfuse.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/conversation.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/general_question.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/guardrail.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/metric_skill.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/search_tool.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/visualization.py
  • packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py
  • packages/gooddata-eval/src/gooddata_eval/core/config.py
  • packages/gooddata-eval/src/gooddata_eval/core/langfuse/sink.py
  • packages/gooddata-eval/tests/test_agentic_run_context.py
  • packages/gooddata-eval/tests/test_cli.py
  • packages/gooddata-eval/tests/test_sse_client.py
🚧 Files skipped from review as they are similar to previous changes (15)
  • packages/gooddata-eval/README.md
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/metric_skill.py
  • packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/visualization.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/search_tool.py
  • packages/gooddata-eval/tests/test_cli.py
  • packages/gooddata-eval/src/gooddata_eval/core/langfuse/sink.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/general_question.py
  • packages/gooddata-eval/src/gooddata_eval/cli/main.py
  • packages/gooddata-eval/src/gooddata_eval/cli/agentic_runner.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/conversation.py
  • packages/gooddata-eval/tests/test_agentic_run_context.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/guardrail.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/_langfuse.py

📝 Walkthrough

Walkthrough

This change adds optional ReasoningEffort support across CLI parsing, agentic evaluation, chat requests, and Langfuse metadata. Supported values are LOW, MEDIUM, and HIGH.

Changes

Reasoning effort support

Layer / File(s) Summary
Reasoning effort contract and chat transport
packages/gooddata-eval/src/gooddata_eval/core/config.py, packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py, packages/gooddata-eval/tests/test_sse_client.py
Defines ReasoningEffort, normalizes values, and adds the setting to RunConfig. ChatClient sends options.reasoningEffort when configured. Tests cover normalization, omission, repeated requests, and validation.
Agentic evaluator propagation
packages/gooddata-eval/src/gooddata_eval/cli/agentic_runner.py, packages/gooddata-eval/src/gooddata_eval/core/agentic/*.py
Agentic runners and evaluators accept reasoning_effort, forward it to ChatClient, and pass it to Langfuse run-context construction.
CLI option and dispatch wiring
packages/gooddata-eval/src/gooddata_eval/cli/main.py, packages/gooddata-eval/tests/test_cli.py
The CLI parses --reasoning-effort, stores it in RunConfig, and passes it to agentic execution, conversational chat, and LangfuseSink. Tests cover valid and invalid values.
Langfuse metadata and documentation
packages/gooddata-eval/src/gooddata_eval/core/agentic/_langfuse.py, packages/gooddata-eval/src/gooddata_eval/core/langfuse/sink.py, packages/gooddata-eval/tests/test_agentic_run_context.py, packages/gooddata-eval/README.md
Langfuse names, metadata, and tags include the selected effort. Tests cover normalization and invalid values. Documentation describes supported values and feature-flag behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant RunConfig
  participant AgenticEvaluator
  participant ChatClient
  participant Langfuse
  CLI->>RunConfig: Store reasoning_effort
  RunConfig->>AgenticEvaluator: Pass reasoning_effort
  AgenticEvaluator->>ChatClient: Construct with reasoning_effort
  ChatClient->>ChatClient: Add options.reasoningEffort
  AgenticEvaluator->>Langfuse: Record effort metadata and run name
Loading

Possibly related PRs

Suggested reviewers: lupko, pcerny, zdenekmusil-gd

Poem

A rabbit sends effort through the stream,
LOW, MEDIUM, HIGH in a typed dream.
ChatClient carries each request,
Langfuse records the selected effect.
CLI paths now hop in line. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.31% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: allowing evaluations to request a reasoning effort.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.91667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 78.34%. Comparing base (acfcc1a) to head (49949a5).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
...ddata-eval/src/gooddata_eval/cli/agentic_runner.py 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1709      +/-   ##
==========================================
+ Coverage   78.30%   78.34%   +0.04%     
==========================================
  Files         271      271              
  Lines       18689    18726      +37     
==========================================
+ Hits        14634    14671      +37     
  Misses       4055     4055              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py (1)

451-461: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Append reasoning_effort after the existing evaluator parameters.

These public evaluator signatures insert the new parameter before langfuse. Existing positional callers bind arguments to the wrong parameters. Keep the existing order and append reasoning_effort after run_metadata_extra.

  • packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py#L451-L461: move reasoning_effort after run_metadata_extra.
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/conversation.py#L394-L402: move reasoning_effort after run_metadata_extra.
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/general_question.py#L143-L152: move reasoning_effort after run_metadata_extra.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py` around
lines 451 - 461, Public evaluator signatures place reasoning_effort before
existing parameters, breaking positional callers. In
packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py lines
451-461, packages/gooddata-eval/src/gooddata_eval/core/agentic/conversation.py
lines 394-402, and
packages/gooddata-eval/src/gooddata_eval/core/agentic/general_question.py lines
143-152, move reasoning_effort after run_metadata_extra while preserving all
existing parameter order.
🧹 Nitpick comments (1)
packages/gooddata-eval/src/gooddata_eval/core/agentic/guardrail.py (1)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use keyword arguments for the growing build_run_context positional call.

All four call sites invoke build_run_context with the same 8-argument positional list, and this PR added reasoning_effort as the 8th positional argument at each site. Since most arguments share the type str | None, a future reordering or insertion in build_run_context's signature would silently misalign the callers instead of raising a type error. Convert each call to keyword arguments to remove this risk.

  • packages/gooddata-eval/src/gooddata_eval/core/agentic/guardrail.py#L185-194: call build_run_context with keyword arguments (e.g. dataset_name=dataset_name, run_timestamp=run_timestamp, ..., reasoning_effort=reasoning_effort).
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/metric_skill.py#L336-344: apply the same keyword-argument conversion.
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/search_tool.py#L179-187: apply the same keyword-argument conversion.
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/visualization.py#L302-310: apply the same keyword-argument conversion.
♻️ Example fix (guardrail.py)
         run_name_base, run_metadata = build_run_context(
-            host,
-            token,
-            workspace_id,
-            dataset_name,
-            run_timestamp,
-            model_version_override,
-            run_metadata_extra,
-            reasoning_effort,
+            host=host,
+            token=token,
+            workspace_id=workspace_id,
+            dataset_name=dataset_name,
+            run_timestamp=run_timestamp,
+            model_version_override=model_version_override,
+            run_metadata_extra=run_metadata_extra,
+            reasoning_effort=reasoning_effort,
         )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/gooddata-eval/src/gooddata_eval/core/agentic/guardrail.py` at line
1, Convert all four build_run_context call sites in guardrail.py,
metric_skill.py, search_tool.py, and visualization.py from positional arguments
to keyword arguments, including reasoning_effort and every existing parameter.
Preserve the current argument values and call behavior while making each
parameter explicitly named.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py`:
- Around line 252-266: Establish a single canonical form for reasoning_effort at
initialization time in the __init__ method (anchor site
packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py#L252-L266) by
validating or normalizing the parameter before storing it in
self._reasoning_effort, then reuse that same canonical value in two places: when
building the request options in
packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py#L290-L292 where
it is sent to the server, and in
packages/gooddata-eval/src/gooddata_eval/core/agentic/_langfuse.py#L413-L419
where it is used for the Langfuse suffix and metadata. This ensures invalid or
empty values are caught early and all downstream consumers see consistent,
validated reasoning_effort values.

In `@packages/gooddata-eval/src/gooddata_eval/core/config.py`:
- Line 23: Update LangfuseSink to accept and use reasoning_effort by adding a
reasoning_effort parameter to LangfuseSink.__init__(), then pass
config.reasoning_effort when instantiating LangfuseSink in the non-agentic
ChatClient path. Incorporate the reasoning_effort value into both the run name
construction (using the same pattern as the agentic build_run_context path with
a suffix) and the trace metadata dict, ensuring non-agentic runs are
distinguishable by effort level in Langfuse.

---

Outside diff comments:
In `@packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py`:
- Around line 451-461: Public evaluator signatures place reasoning_effort before
existing parameters, breaking positional callers. In
packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py lines
451-461, packages/gooddata-eval/src/gooddata_eval/core/agentic/conversation.py
lines 394-402, and
packages/gooddata-eval/src/gooddata_eval/core/agentic/general_question.py lines
143-152, move reasoning_effort after run_metadata_extra while preserving all
existing parameter order.

---

Nitpick comments:
In `@packages/gooddata-eval/src/gooddata_eval/core/agentic/guardrail.py`:
- Line 1: Convert all four build_run_context call sites in guardrail.py,
metric_skill.py, search_tool.py, and visualization.py from positional arguments
to keyword arguments, including reasoning_effort and every existing parameter.
Preserve the current argument values and call behavior while making each
parameter explicitly named.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2edfc7ab-3e28-4918-bff6-9c3a2e5575c5

📥 Commits

Reviewing files that changed from the base of the PR and between acfcc1a and e368629.

📒 Files selected for processing (13)
  • packages/gooddata-eval/src/gooddata_eval/cli/agentic_runner.py
  • packages/gooddata-eval/src/gooddata_eval/cli/main.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/_langfuse.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/conversation.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/general_question.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/guardrail.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/metric_skill.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/search_tool.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/visualization.py
  • packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py
  • packages/gooddata-eval/src/gooddata_eval/core/config.py
  • packages/gooddata-eval/tests/test_sse_client.py

Comment thread packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py Outdated
Comment thread packages/gooddata-eval/src/gooddata_eval/core/config.py Outdated
@hkad98
hkad98 force-pushed the jkd/eval-reasoning-effort branch from 110be83 to 115c616 Compare August 4, 2026 16:33

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/gooddata-eval/tests/test_sse_client.py (1)

383-390: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Exercise the ChatClient constructor default.

_capture_body_client always passes reasoning_effort at Line [388]. The unset-effort test therefore verifies explicit None, not omission of the constructor argument. If the constructor default changes, this test can still pass.

Forward **kwargs through _client_with_handler so the unset case omits the keyword.

Proposed test-helper change
-def _capture_body_client(captured, *, reasoning_effort=None):
+def _capture_body_client(captured, **kwargs):
     def handler(request):
         captured.append(json.loads(request.content))
         return httpx.Response(200, content=_OK_SSE)

-    client = ChatClient(host="https://example.invalid", token="t", workspace_id="w", reasoning_effort=reasoning_effort)
-    client._client = httpx.Client(transport=httpx.MockTransport(handler))
-    return client
+    return _client_with_handler(handler, **kwargs)

Also applies to: 393-397

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/gooddata-eval/tests/test_sse_client.py` around lines 383 - 390,
Update _capture_body_client to forward optional constructor arguments through
the existing _client_with_handler helper, ensuring the unset reasoning_effort
case omits the keyword entirely rather than passing None. Preserve explicit
reasoning_effort forwarding for tests that provide a value, and update the
affected call sites accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/gooddata-eval/tests/test_sse_client.py`:
- Around line 383-390: Update _capture_body_client to forward optional
constructor arguments through the existing _client_with_handler helper, ensuring
the unset reasoning_effort case omits the keyword entirely rather than passing
None. Preserve explicit reasoning_effort forwarding for tests that provide a
value, and update the affected call sites accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bb8d8e92-eef2-4a2c-aec8-c711f0038590

📥 Commits

Reviewing files that changed from the base of the PR and between 110be83 and 115c616.

📒 Files selected for processing (17)
  • packages/gooddata-eval/README.md
  • packages/gooddata-eval/src/gooddata_eval/cli/agentic_runner.py
  • packages/gooddata-eval/src/gooddata_eval/cli/main.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/_langfuse.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/conversation.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/general_question.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/guardrail.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/metric_skill.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/search_tool.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/visualization.py
  • packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py
  • packages/gooddata-eval/src/gooddata_eval/core/config.py
  • packages/gooddata-eval/src/gooddata_eval/core/langfuse/sink.py
  • packages/gooddata-eval/tests/test_agentic_run_context.py
  • packages/gooddata-eval/tests/test_cli.py
  • packages/gooddata-eval/tests/test_sse_client.py
🚧 Files skipped from review as they are similar to previous changes (16)
  • packages/gooddata-eval/src/gooddata_eval/core/config.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/guardrail.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/conversation.py
  • packages/gooddata-eval/src/gooddata_eval/cli/agentic_runner.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/metric_skill.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/general_question.py
  • packages/gooddata-eval/src/gooddata_eval/cli/main.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/search_tool.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/_langfuse.py
  • packages/gooddata-eval/README.md
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/alert_skill.py
  • packages/gooddata-eval/tests/test_agentic_run_context.py
  • packages/gooddata-eval/src/gooddata_eval/core/chat/sse_client.py
  • packages/gooddata-eval/tests/test_cli.py
  • packages/gooddata-eval/src/gooddata_eval/core/langfuse/sink.py
  • packages/gooddata-eval/src/gooddata_eval/core/agentic/visualization.py

@hkad98
hkad98 enabled auto-merge August 4, 2026 16:46
Adds an optional reasoning effort to `gooddata-eval`, so an evaluation run can
request `LOW`, `MEDIUM` or `HIGH` instead of always using the endpoint default.
Sent as `options.reasoningEffort` on each chat message and threaded through
ChatClient, all seven `evaluate_agentic_*` entry points, the agentic runner and
the CLI (`--reasoning-effort`).

Per the AI chat OpenAPI schema the field is `SendMessageOptions.reasoningEffort`,
typed as an enum of exactly LOW/MEDIUM/HIGH, nullable, and scoped to a single
message rather than persisted. The implementation mirrors all four: uppercase
`Literal`, camelCase key, re-sent per message, key omitted when unset.

Without this there is no way to evaluate at a non-default effort — the value is
read from the request body and the SDK never sent one, so effort was the one
request-level option the suite could not vary.

Both Langfuse writers record it. `build_run_context` suffixes the dataset-run
name and adds run metadata; `LangfuseSink` suffixes its run name and reports the
effort via trace `tags`, since metadata alone is not a breakdown dimension — the
same reason `model_version` already uses first-class fields there. Two runs
differing only by effort would otherwise share a name and merge in the report.

The value is normalized once at the boundary. The `Literal` only constrains
static callers, so without normalization a lowercase value reached the endpoint
as an out-of-enum request, and a blank value was sent yet skipped by the
writers' truthiness checks — leaving a run whose recorded identity disagreed
with what it requested. Blank now means unset and anything outside the enum
raises locally.

New parameters are appended to the end of the public `evaluate_agentic_*`
signatures rather than inserted mid-list, so existing positional callers of this
released package keep binding correctly.

Default is None, which omits the key and leaves the request payload
byte-identical to before.

Also drops an unused local in test_cli.py that was failing lint on master.
@hkad98
hkad98 force-pushed the jkd/eval-reasoning-effort branch from 115c616 to 49949a5 Compare August 4, 2026 17:19
@hkad98
hkad98 merged commit 78904a0 into gooddata:master Aug 4, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants