-
Notifications
You must be signed in to change notification settings - Fork 70
Comparing changes
Open a pull request
base repository: gooddata/gooddata-python-sdk
base: master
head repository: gooddata/gooddata-python-sdk
compare: ptom/mic-evaluations
- 7 commits
- 15 files changed
- 2 contributors
Commits on Aug 5, 2026
-
feat(gooddata-eval): capture agent reasoning steps in ChatResult
The SSE reasoning events were already being read to produce reasoning_step_count, but the step text itself was discarded. Keep it as reasoning_steps on ChatResult/ItemReport and surface it in the JSON report so eval consumers can inspect the agent's actual reasoning trace, not just how many steps it took.
Configuration menu - View commit details
-
Copy full SHA for 389905b - Browse repository at this point
Copy the full SHA 389905bView commit details -
test(gooddata-eval): cover multi-run reasoning_steps retention
Addresses CodeRabbit nitpick on PR #1708: a later run returning no reasoning events must not clobber an earlier run's captured steps (runner.py:120's `or` pattern, same as conversation_id/response_id).
Configuration menu - View commit details
-
Copy full SHA for da26fe4 - Browse repository at this point
Copy the full SHA da26fe4View commit details -
feat(gooddata-eval): capture reasoning_steps through the agentic-CLI …
…path 6001d2f wired ChatResult.reasoning_steps through runner.py's generic single-turn path only. The agentic-CLI path (cli/agentic_runner.py -> evaluate_agentic_*) builds its own ItemReport and never touched it, so agentic_alert_skill/agentic_metric_skill/agentic_conversation items could never produce a reasoning trace, no matter what the platform emitted. Accumulates reasoning_steps across every send_message call in each of the three evaluators' run loops, attaches it to the run/turn result, and surfaces it from evaluate_agentic_* either as the return value (pass) or as an attribute on the raised exception (fail) -- mirroring the existing conversation_id-on-exception idiom in ChatClient.ask(). run_agentic_items picks it up from either path onto ItemReport.reasoning_steps, which json_report.py already serializes unconditionally. general_question/guardrail/search_tool/visualization are left untouched -- their evaluate_agentic_* functions still return None, unchanged.
Configuration menu - View commit details
-
Copy full SHA for 8010bd4 - Browse repository at this point
Copy the full SHA 8010bd4View commit details -
feat(gooddata-eval): capture conversation_id/response_id through the …
…agentic-CLI path 8010bd4 wired reasoning_steps through cli/agentic_runner.py -> evaluate_agentic_*, but conversation_id/response_id stayed unset on ItemReport for every agentic kind (agentic_alert_skill/agentic_metric_skill/agentic_conversation) -- each ChatResult already carries both, and conversation_id was already threaded up to the Alert/Metric/ConversationRunResult layer, but neither ever reached the top-level evaluate_agentic_* return value or its failure exception, so run_agentic_items had nothing to read. Mirrors the reasoning_steps idiom exactly: widens each evaluate_agentic_*'s return from list[str] to (reasoning_steps, conversation_id, response_id), attaches all three to the raised exception on failure, and has run_agentic_items unpack either form (tuple or the untouched kinds' bare list/None) onto ItemReport.conversation_id /response_id. response_id is new at the RunResult layer for all three kinds -- captured as the last non-null value across a run's turns, same pattern already used for reasoning_steps accumulation. general_question/guardrail/search_tool/visualization untouched (already populated via the single-turn runner.py path, not this one). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 1c328c4 - Browse repository at this point
Copy the full SHA 1c328c4View commit details
Commits on Aug 6, 2026
-
fix(gooddata-eval): stop the metric-skill simulated user from droppin…
…g MAQL clauses agentic_metric_skill's simulated-user reply (generate_simulated_response) is what keeps a multi-turn metric-creation conversation going after the agent asks a clarifying question -- it prompts an LLM to answer as the user, using the fixture's expected_output.maql as its only source of truth. The prompt told it to "reply briefly" with no instruction to preserve the MAQL's structure. In practice it would silently drop a WHERE/filter clause, or paraphrase a label id, whenever the agent's question didn't happen to ask about that part directly -- so a well-behaved agent, faithfully following the (already-wrong) simulated answer, still failed the eval. Reproduced live twice against a real gdc-mic-ai-evaluation fixture ("Create a metric for total ecommerce spend", expects SELECT {metric/spend_amount_-_cutcgco} WHERE {label/ecommerce_indicator_code} = "1"): 1. Simulated reply dropped "_code" off ecommerce_indicator_code, anchoring the agent on a sibling attribute that doesn't have that filter. 2. Simulated reply picked one of 3 metric options the agent offered and said "please proceed with that" -- never mentioning the WHERE clause that expected_output required, even though it had it in hand. Confirmed via a 5x-repeated A/B test that this is a prompt problem, not a model-capability one: swapping gpt-4o-mini for gpt-4o under the OLD prompt did not fix it (still dropped the clause); the NEW prompt fixes it on the ORIGINAL gpt-4o-mini (1/5 -> 5/5 runs preserving the exact filter). Fix: instruct the simulating LLM to (a) ensure every clause of the expected MAQL is eventually satisfied even if the agent's question didn't ask about it, (b) quote field/label identifiers verbatim rather than paraphrase them, and (c) proactively add a filter the agent's own offered options omitted. Also drop "reply briefly" and raise max_tokens 150->300, since brevity was part of what squeezed the filter clause out. This brings metric_skill's simulated-user prompt in line with alert_skill's generate_simulated_alert_response, which already passes structured facts + explicit "proactively tell the agent X" instructions rather than one freely-paraphrased string -- not a new pattern for this codebase. Added a regression test asserting the sent prompt preserves clause-fidelity language and the raised max_tokens. Full gooddata-eval suite: 272 passed (9 pre-existing unrelated failures, confirmed identical on clean master before this change -- missing openai extra in test env, and two unrelated test files). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>Configuration menu - View commit details
-
Copy full SHA for b6f621e - Browse repository at this point
Copy the full SHA b6f621eView commit details -
test(gooddata-eval): assert exact MAQL string appears in simulated-us…
…er prompt Addresses CodeRabbit review comment on #1718: the regression test only checked for generic instruction words ("verbatim", "every clause"), not that expected_output["maql"] itself made it into the prompt -- a regression that stripped the metric/label reference or filter value entirely could still pass. Assert the exact MAQL string is present. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 3822a80 - Browse repository at this point
Copy the full SHA 3822a80View commit details -
fix(gooddata-eval): make MAQL comparison case-insensitive for keywords
_normalize_maql/_best_maql_match compare an agent's generated MAQL against expected_output.maql via exact string equality after whitespace/wrapper normalization -- but MAQL keywords (SELECT, FOR PREVIOUS, WHERE, BY, ...) are case-insensitive at the query-engine level (confirmed against the MAQL reference), while the comparison itself was fully case-sensitive. Reproduced live in gdc-mic-ai-evaluation, post the #1718 fix: fixture "Create a metric for the prior-year value of Active cards" expects SELECT {metric/active_card_count_-_txn_-_cutcgco} FOR Previous({label/process_date.year}) Agent produced, verbatim: SELECT {metric/active_card_count_-_txn_-_cutcgco} FOR PREVIOUS({label/process_date.year}) Byte-identical except FOR PREVIOUS vs FOR Previous -- scored as a fail. First fix attempt considered and rejected: lowercase everything outside {type/id} braces. That's wrong -- WHERE-clause literal values are ALSO outside braces (e.g. WHERE {label/status} = "Active") and are real, case-sensitive data, not keywords; blindly folding them would create a new false-positive risk (two genuinely different filter values scored as equal). Actual fix: per the MAQL reference, every literal value is quoted and every identifier lives inside {..} -- both are exhaustively structural markers, so protecting text inside either while casefolding everything else needs no keyword list at all (which would risk being incomplete against MAQL's large vocabulary: SELECT, BY, WHERE, HAVING, FOR PREVIOUS/NEXT/EACH, WITHOUT PF, TOP/BOTTOM, WITHIN, RANK family, RUNSUM family, IFNULL, CASE/WHEN, 15+ math functions, ...). Added _casefold_outside_protected(), applied as the final step in _normalize_maql. Tests added: - keyword case-insensitivity on the exact reproduced case (FOR PREVIOUS vs FOR Previous) - identifier case preserved ({metric/Mixed_Case_Id} untouched) - quoted literal case preserved AND still distinguishes real differences (WHERE x = "Active" vs WHERE x = "active" must stay a genuine mismatch -- this is the test that would have caught the rejected first draft) Updated the one existing test whose expected value assumed no case normalization ever happens (SELECT -> select). Full gooddata-eval suite: 274 passed, 9 pre-existing unrelated failures (missing openai extra in this test env; two unrelated test files) -- identical count to before this change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 3173acd - Browse repository at this point
Copy the full SHA 3173acdView commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff master...ptom/mic-evaluations