Skip to content

[caliper] solidify the metrics to mlflow - #158

Merged
openshift-merge-bot[bot] merged 15 commits into
openshift-psap:mainfrom
ashtarkb:mlflow-metrics
Aug 6, 2026
Merged

[caliper] solidify the metrics to mlflow#158
openshift-merge-bot[bot] merged 15 commits into
openshift-psap:mainfrom
ashtarkb:mlflow-metrics

Conversation

@ashtarkb

@ashtarkb ashtarkb commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Move metrics.json generation from mcp_gateway parser into caliper as a generic mechanism
  • After kpis.json is produced, caliper auto-generates per-run metrics.json + parameters.json using KPI ids as metric keys
  • MLflow export picks up these files without any project-specific code — works for all projects that produce kpis.json

Test plan

  • Verify kpis.json generation still works for mcp_gateway
  • Verify metrics.json files are created in test run directories from kpis.json
  • Verify MLflow export picks up generated metrics.json
  • Verify notifications comparison still works with new metric key format

Made with Cursor

Summary by CodeRabbit

  • New Features

    • Added conversion of schema-v2 KPI results into per-run metrics and parameters files.
    • Added support for logging scalar and two-dimensional KPI data to MLflow.
  • Bug Fixes

    • KPI conversion validates inputs and reports skipped, unmatched, or invalid runs.
    • Conversion failures are reported as warnings without failing the overall pipeline.
  • Changes

    • Updated metric handling to use KPI identifiers directly.
    • Parsing no longer generates per-run metrics or parameters files.
    • Replot settings now honor configured download-retention defaults.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ashtarkb, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 17 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5b50e063-d792-4cb7-99b8-77ff7fb37753

📥 Commits

Reviewing files that changed from the base of the PR and between 567aa7e and 8543da1.

📒 Files selected for processing (6)
  • projects/caliper/cli/commands.py
  • projects/caliper/cli/main.py
  • projects/caliper/engine/kpi/kpis_to_mlflow.py
  • projects/caliper/orchestration/cli_builder.py
  • projects/caliper/orchestration/postprocess.py
  • projects/core/library/replot.py
📝 Walkthrough

Walkthrough

The PR adds schema-v2 KPI conversion into per-run artifacts, updates MLflow handling for scalar and 2D metrics, removes parser-generated metric and parameter files from MCP Gateway, and adjusts replot configuration behavior.

Changes

KPI export pipeline

Layer / File(s) Summary
KPI artifact conversion and orchestration
projects/caliper/engine/kpi/metrics_from_kpis.py, projects/caliper/orchestration/postprocess.py
The pipeline validates schema-v2 kpis.json, matches artifact runs, writes metrics.json and parameters.json, and reports conversion status and warnings.
MLflow scalar and 2D metric export
projects/caliper/engine/file_export/mlflow_backend.py
Single-run and child-run exports validate 2D metric points and log y-values with x-values as MLflow steps. Scalar metric logging remains supported.
MCP Gateway KPI consumption
projects/mcp_gateway/orchestration/notifications.py, projects/mcp_gateway/postprocess/mcp_gateway/parsing/parsers.py, projects/mcp_gateway/postprocess/tests/test_mcp_gateway_plugin.py
Previous MLflow metrics are filtered by target KPI IDs. The parser no longer writes metric or parameter files. Tests verify that both files remain absent.
CLI and replot behavior
projects/caliper/cli/commands.py, projects/core/library/replot.py
The artifact export command removes a blank separator. The replot entrypoint passes None when --keep-download is not set.

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

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant KPIOrchestration
  participant generate_metrics_from_kpis
  participant ArtifactRunDirectories
  participant MetricsJson
  participant ParametersJson
  KPIOrchestration->>generate_metrics_from_kpis: Convert kpis.json
  generate_metrics_from_kpis->>ArtifactRunDirectories: Match test runs by marker files
  generate_metrics_from_kpis->>MetricsJson: Write scalar and 2D KPI values
  generate_metrics_from_kpis->>ParametersJson: Write test labels
  generate_metrics_from_kpis-->>KPIOrchestration: Return status and warnings
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% 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
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: improving Caliper metric generation and MLflow integration.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Move metrics.json generation from project-specific parsers into caliper
as a generic mechanism. After kpis.json is produced, caliper now
automatically writes per-run metrics.json and parameters.json files
using KPI ids as metric keys. The MLflow export backend picks these up
via _log_metrics_and_params_from_tree without any project-specific code.

- Add caliper/engine/kpi/metrics_from_kpis.py with generate_metrics_from_kpis()
- Wire into postprocess pipeline after kpis.json generation step
- Remove mcp_gateway-specific metrics.json/parameters.json writing
- Simplify mcp_gateway notifications MLflow metric key lookup
- Update tests to reflect new ownership

Co-authored-by: Cursor <cursoragent@cursor.com>
@ashtarkb

ashtarkb commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/test fournos mcp_gateway matrix-demo-1
/cluster avis-cluster
/pipeline forge-full
/version 0.7.1

@psap-forge-bot

psap-forge-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

🟢 Execution of mcp_gateway matrix-demo-1 🟢

Execution Engine Configuration

forge:
  args:
  - matrix-demo-1
  configOverrides:
    infrastructure.mcp_gateway_version: 0.7.1
  project: mcp_gateway

Artifact Links

Test Logs

00 Pre-Cleanup 2 seconds

01 Prepare 1 minute, 50 seconds

02 Preflight 1 minute, 18 seconds

03 Test 8 minutes, 32 seconds

04 Post-Cleanup 1 minute, 30 seconds

🔄 05 Export-Artifacts

Post-processing Status

  • parse: success
  • artifacts_to_kpis: success
  • ⏭️ kpis_to_csv: disabled

    kpi.kpis_to_csv disabled

  • ⏭️ artifacts_to_ai_data: disabled

    kpi.artifacts_to_ai_data disabled

  • ⏭️ s3_import: disabled

    s3_import disabled

  • ⏭️ analyse_kpis: disabled

    analyze disabled

  • ⏭️ s3_export: disabled

    s3_export disabled

@psap-forge-bot

psap-forge-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

@kpouget

kpouget commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

/test fournos llm_d janus cpt
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

@psap-forge-bot

psap-forge-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

🟢 Execution of mcp_gateway matrix-demo-1 🟢

Execution Engine Configuration

forge:
  args:
  - matrix-demo-1
  configOverrides:
    infrastructure.mcp_gateway_version: 0.7.1
  project: mcp_gateway

Artifact Links

Test Logs

00 Pre-Cleanup 1 second

01 Prepare 2 minutes, 48 seconds

02 Preflight 1 minute

03 Test 9 minutes, 13 seconds

04 Post-Cleanup 1 minute, 27 seconds

🔄 05 Export-Artifacts

Post-processing Status

  • parse: success
  • artifacts_to_kpis: success
  • ⏭️ kpis_to_csv: disabled

    kpi.kpis_to_csv disabled

  • ⏭️ artifacts_to_ai_data: disabled

    kpi.artifacts_to_ai_data disabled

  • ⏭️ s3_import: disabled

    s3_import disabled

  • ⏭️ analyse_kpis: disabled

    analyze disabled

  • ⏭️ s3_export: disabled

    s3_export disabled

@psap-forge-bot

psap-forge-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

@ashtarkb

ashtarkb commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d janus cpt
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

@psap-forge-bot

psap-forge-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

🟢 Execution of llm_d janus cpt 🟢

Execution Engine Configuration

forge:
  args:
  - janus
  - cpt
  configOverrides:
    caliper.replot.url: https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
  project: llm_d

Artifact Links

Test Logs

00 Replot 3 minutes, 20 seconds

🔄 01 Export-Artifacts

Post-processing Status

@psap-forge-bot

psap-forge-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown
🟢 Submission of llm_d janus cpt succeeded after 5 minutes 🟢
/test fournos llm_d janus cpt
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

@ashtarkb

ashtarkb commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d janus cpt
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

@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: 5

🤖 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 `@projects/caliper/cli/commands.py`:
- Around line 1032-1038: Update the exception handler around the artifacts
export failure to stop printing the raw exception and full traceback via
click.echo. Emit only a sanitized, generic user-facing error to stderr, and
route detailed diagnostics through the project’s protected logging mechanism
with secrets redacted.
- Around line 1030-1031: Update the callback invoking run_artifacts_export to
capture its returned exit code, and call ctx.exit(exit_code) whenever the value
is non-zero. Preserve successful completion when the result is zero and leave
exception handling unchanged.
- Around line 1030-1031: Update the call to artifacts_export in the CLI command
to pass mlflow_secrets_path as its dedicated argument, in addition to
mlflow_config_data=final_config. Ensure run_artifacts_export receives the
configured secrets path through that parameter so MLflow credentials are loaded
correctly.

In `@projects/caliper/engine/kpi/metrics_from_kpis.py`:
- Around line 121-124: Restrict the parameter construction in the labels
handling block to an explicit allowlist of known public parameter keys, and pass
only those entries to _write_json. Exclude all unknown labels and sensitive
values from parameters.json while preserving the existing string conversion for
allowed keys.

In `@projects/mcp_gateway/postprocess/tests/test_mcp_gateway_plugin.py`:
- Around line 68-75: Update test_parse_does_not_write_metrics_json and every
other MCPGatewayParser.parse invocation in this file to pass only the nodes
collection, such as [node], removing the tmp_path argument while preserving each
test’s existing assertions.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d2dd2fc1-9c30-4580-b9ae-df0fe69c7db9

📥 Commits

Reviewing files that changed from the base of the PR and between 5e46e88 and 8ccf6a3.

📒 Files selected for processing (7)
  • projects/caliper/cli/commands.py
  • projects/caliper/engine/file_export/artifacts_export_run.py
  • projects/caliper/engine/kpi/metrics_from_kpis.py
  • projects/caliper/orchestration/postprocess.py
  • projects/mcp_gateway/orchestration/notifications.py
  • projects/mcp_gateway/postprocess/mcp_gateway/parsing/parsers.py
  • projects/mcp_gateway/postprocess/tests/test_mcp_gateway_plugin.py

Comment thread projects/caliper/cli/commands.py Outdated
Comment on lines 1030 to 1031
mlflow_config_data=final_config,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | rg '(^|/)commands\.py$' | sed -n '1,50p'

echo "== inspect relevant lines =="
sed -n '980,1055p' projects/caliper/cli/commands.py

echo "== find run_artifacts_export definitions/usages =="
rg -n "def run_artifacts_export|run_artifacts_export\\(" projects/caliper projects -g '*.py' | sed -n '1,120p'

Repository: openshift-psap/forge

Length of output: 3509


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== artifacts_export_run outline/lines =="
wc -l projects/caliper/engine/file_export/artifacts_export_run.py
sed -n '1,180p' projects/caliper/engine/file_export/artifacts_export_run.py

echo "== orchestration export caller =="
wc -l projects/sbin/caliper/orchestration/export.py
sed -n '220,260p' projects/sbin/caliper/orchestration/export.py

Repository: openshift-psap/forge

Length of output: 6879


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== relevant artifacts_export_run lines =="
sed -n '180,254p' projects/caliper/engine/file_export/artifacts_export_run.py

echo "== locate orchestration export.py files =="
git ls-files | rg '(^|/)export\.py$' | sed -n '1,80p'

echo "== run_artifacts_export callers =="
rg -n "run_artifacts_export\\(" -g '*.py' . | sed -n '1,120p'

Repository: openshift-psap/forge

Length of output: 3752


Propagate the export exit code.

run_artifacts_export returns 1 or 4 for configuration and export failures. This callback ignores the returned value and exits successfully unless an exception is raised. Capture the result and call ctx.exit(exit_code) when it is non-zero.

🤖 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 `@projects/caliper/cli/commands.py` around lines 1030 - 1031, Update the
callback invoking run_artifacts_export to capture its returned exit code, and
call ctx.exit(exit_code) whenever the value is non-zero. Preserve successful
completion when the result is zero and leave exception handling unchanged.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Pass mlflow_secrets_path separately.

artifacts_export receives mlflow_secrets_path, but this call stores it only in final_config["secrets_path"]. run_artifacts_export loads the secrets file only from its separate mlflow_secrets_path argument at Lines 137-140 of projects/caliper/engine/file_export/artifacts_export_run.py. The CLI can therefore omit the configured MLflow credentials.

Pass the dedicated argument to preserve secret loading.

Proposed fix
         run_artifacts_export(
             from_path=from_path,
             backend=list(backend) if backend else ["mlflow"],
             dry_run=dry_run,
             verbose=verbose,
             status_yaml_path=status_yaml_path,
+            mlflow_secrets_path=mlflow_secrets_path,
             mlflow_config_data=final_config,
         )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mlflow_config_data=final_config,
)
run_artifacts_export(
from_path=from_path,
backend=list(backend) if backend else ["mlflow"],
dry_run=dry_run,
verbose=verbose,
status_yaml_path=status_yaml_path,
mlflow_secrets_path=mlflow_secrets_path,
mlflow_config_data=final_config,
)
🤖 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 `@projects/caliper/cli/commands.py` around lines 1030 - 1031, Update the call
to artifacts_export in the CLI command to pass mlflow_secrets_path as its
dedicated argument, in addition to mlflow_config_data=final_config. Ensure
run_artifacts_export receives the configured secrets path through that parameter
so MLflow credentials are loaded correctly.

Comment thread projects/caliper/cli/commands.py
Comment on lines +121 to +124
labels = test_entry.get("labels", {})
if labels:
params = {str(k): ("" if v is None else str(v)) for k, v in labels.items()}
_write_json(run_dir / PARAMETERS_FILE, params)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Do not persist every test label.

labels can contain sensitive values from project configuration. This code writes every value to parameters.json.

Allowlist known public parameter keys before calling _write_json. Do not serialize unknown labels.

As per coding guidelines, “Never write secrets or sensitive data—including passwords, tokens, pull secrets, certificates, API keys, or Secret data/stringData—to env.ARTIFACT_DIR, logs, or files.”

🤖 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 `@projects/caliper/engine/kpi/metrics_from_kpis.py` around lines 121 - 124,
Restrict the parameter construction in the labels handling block to an explicit
allowlist of known public parameter keys, and pass only those entries to
_write_json. Exclude all unknown labels and sensitive values from
parameters.json while preserving the existing string conversion for allowed
keys.

Source: Coding guidelines

Comment on lines +68 to +75
def test_parse_does_not_write_metrics_json(self, tmp_path: Path):
"""Parser no longer writes metrics.json — caliper handles it generically."""
node = _make_test_node(tmp_path, "run-a", SAMPLE_STATS_CSV, TEST_LABELS)
parser = MCPGatewayParser()

parser.parse(tmp_path, [node])

metrics_file = tmp_path / "run-a" / "metrics.json"
assert metrics_file.exists()
data = json.loads(metrics_file.read_text())
assert data["total_requests"] == 1000
assert data["requests_per_second"] == 31.5

def test_parse_writes_parameters_json(self, tmp_path: Path):
node = _make_test_node(tmp_path, "run-a", SAMPLE_STATS_CSV, TEST_LABELS)
parser = MCPGatewayParser()

parser.parse(tmp_path, [node])

params_file = tmp_path / "run-a" / "parameters.json"
assert params_file.exists()
data = json.loads(params_file.read_text())
assert data["preset"] == "smoke"
assert data["target"] == "gateway"
assert data["users"] == "16"
assert not (tmp_path / "run-a" / "metrics.json").exists()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Call MCPGatewayParser.parse with nodes only.

Line 73 passes tmp_path and [node]. MCPGatewayParser.parse accepts only nodes.

Update this call and the other test calls in this file to pass [node] only.

Proposed fix
-        parser.parse(tmp_path, [node])
+        parser.parse([node])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_parse_does_not_write_metrics_json(self, tmp_path: Path):
"""Parser no longer writes metrics.json — caliper handles it generically."""
node = _make_test_node(tmp_path, "run-a", SAMPLE_STATS_CSV, TEST_LABELS)
parser = MCPGatewayParser()
parser.parse(tmp_path, [node])
metrics_file = tmp_path / "run-a" / "metrics.json"
assert metrics_file.exists()
data = json.loads(metrics_file.read_text())
assert data["total_requests"] == 1000
assert data["requests_per_second"] == 31.5
def test_parse_writes_parameters_json(self, tmp_path: Path):
node = _make_test_node(tmp_path, "run-a", SAMPLE_STATS_CSV, TEST_LABELS)
parser = MCPGatewayParser()
parser.parse(tmp_path, [node])
params_file = tmp_path / "run-a" / "parameters.json"
assert params_file.exists()
data = json.loads(params_file.read_text())
assert data["preset"] == "smoke"
assert data["target"] == "gateway"
assert data["users"] == "16"
assert not (tmp_path / "run-a" / "metrics.json").exists()
def test_parse_does_not_write_metrics_json(self, tmp_path: Path):
"""Parser no longer writes metrics.json — caliper handles it generically."""
node = _make_test_node(tmp_path, "run-a", SAMPLE_STATS_CSV, TEST_LABELS)
parser = MCPGatewayParser()
parser.parse([node])
assert not (tmp_path / "run-a" / "metrics.json").exists()
🤖 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 `@projects/mcp_gateway/postprocess/tests/test_mcp_gateway_plugin.py` around
lines 68 - 75, Update test_parse_does_not_write_metrics_json and every other
MCPGatewayParser.parse invocation in this file to pass only the nodes
collection, such as [node], removing the tmp_path argument while preserving each
test’s existing assertions.

@psap-forge-bot

psap-forge-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

🟢 Execution of llm_d janus cpt 🟢

Execution Engine Configuration

forge:
  args:
  - janus
  - cpt
  configOverrides:
    caliper.replot.url: https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
  project: llm_d

Artifact Links

Test Logs

00 Replot 3 minutes, 30 seconds

🔄 01 Export-Artifacts

Post-processing Status

@psap-forge-bot

psap-forge-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown
🟢 Submission of llm_d janus cpt succeeded after 5 minutes 🟢
/test fournos llm_d janus cpt
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

- commands.py: remove duplicate mlflow_config_data kwarg, keep
  upload_workers from upstream
- artifacts_export_run.py: adopt upstream's _resolve_tracking_uri
  refactor over inline URI resolution

Co-authored-by: Cursor <cursoragent@cursor.com>
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 5, 2026
KPIs with is_2d=true (e.g. throughput curves, latency vs load) are now
extracted as {x,y} data points in metrics.json and logged as stepped
MLflow metrics so the UI renders them as curves.

Co-authored-by: Cursor <cursoragent@cursor.com>
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 5, 2026

@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: 1

🤖 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 `@projects/caliper/engine/kpi/metrics_from_kpis.py`:
- Around line 47-65: Reject nonintegral 2D x coordinates at both ingestion
points so MLflow never receives a truncated step: update _extract_2d_points in
projects/caliper/engine/kpi/metrics_from_kpis.py and the metrics.json loading
path in projects/caliper/engine/file_export/mlflow_backend.py to validate that
each 2D point’s x is an integer-valued scalar before accepting it. Keep the
existing sorting and point-shaping behavior for valid data, and filter or return
None for any payload containing a nonintegral x so _log_2d_metrics only sees
safe step values.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a6ed6d68-aa4a-4cae-89cf-d086e3ba2377

📥 Commits

Reviewing files that changed from the base of the PR and between 8ccf6a3 and 81ac154.

📒 Files selected for processing (6)
  • projects/caliper/cli/commands.py
  • projects/caliper/engine/file_export/mlflow_backend.py
  • projects/caliper/engine/kpi/metrics_from_kpis.py
  • projects/caliper/orchestration/postprocess.py
  • projects/mcp_gateway/postprocess/mcp_gateway/parsing/parsers.py
  • projects/mcp_gateway/postprocess/tests/test_mcp_gateway_plugin.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • projects/caliper/orchestration/postprocess.py
  • projects/mcp_gateway/postprocess/tests/test_mcp_gateway_plugin.py
  • projects/mcp_gateway/postprocess/mcp_gateway/parsing/parsers.py
  • projects/caliper/cli/commands.py

Comment thread projects/caliper/engine/kpi/kpis_to_mlflow.py
@kpouget

kpouget commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

/test fournos llm_d janus cpt-xks
/var caliper.postprocess.filtering.include_labels: [version=3.5.0-ea.2]
/var caliper.postprocess.s3.export.enabled: false
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

@psap-forge-bot

psap-forge-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

🟢 Execution of llm_d janus cpt 🟢

Execution Engine Configuration

forge:
  args:
  - janus
  - cpt
  configOverrides:
    caliper.replot.url: https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
  project: llm_d

Artifact Links

Test Logs

00 Replot 3 minutes, 35 seconds

🔄 01 Export-Artifacts

Post-processing Status

@psap-forge-bot

psap-forge-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
🟢 Submission of llm_d janus cpt succeeded after 7 minutes, 27 seconds 🟢
/test fournos llm_d janus cpt
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

@kpouget

kpouget commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

/test fournos llm_d janus cpt-xks
/var caliper.postprocess.filtering.include_labels: [version=3.5.0-ea.2]
/var caliper.postprocess.s3.export.enabled: false
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
/var caliper.replot.keep: true

The click is_flag=True default (False) prevented the config fallback
caliper.replot.keep from ever being consulted, so /var overrides had
no effect and the download directory was always cleaned up — deleting
the metrics.json files before the export step could read them.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ashtarkb

ashtarkb commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d janus cpt-xks
/var caliper.postprocess.filtering.include_labels: [version=3.5.0-ea.2]
/var caliper.postprocess.s3.export.enabled: false
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
/var caliper.replot.keep: true

@psap-forge-bot

psap-forge-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

🟢 Execution of llm_d janus cpt-xks 🟢

Execution Engine Configuration

forge:
  args:
  - janus
  - cpt-xks
  configOverrides:
    caliper.postprocess.filtering.include_labels:
    - version=3.5.0-ea.2
    caliper.postprocess.s3.export.enabled: false
    caliper.replot.keep: true
    caliper.replot.url: https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
  project: llm_d

Artifact Links

Test Logs

00 Replot 3 minutes, 4 seconds

🔄 01 Export-Artifacts

Post-processing Status

@psap-forge-bot

psap-forge-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
🟢 Submission of llm_d janus cpt-xks succeeded after 11 minutes, 5 seconds 🟢
/test fournos llm_d janus cpt-xks
/var caliper.postprocess.filtering.include_labels: [version=3.5.0-ea.2]
/var caliper.postprocess.s3.export.enabled: false
/var caliper.replot.keep: true
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

- Fix line length in replot.py for ruff format compliance.
- Raise ValueError in _log_2d_metrics when x values are non-integer
  or x/y are non-numeric, instead of silently skipping.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ashtarkb

ashtarkb commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

@kpouget take a look at the results.
I think looks good and now the nested runs include both parameters and metrics!

ashtarkb and others added 2 commits August 5, 2026 17:13
Cleaner than the or-None workaround: None default means "not passed"
so the config fallback is used, while --keep-download / --no-keep-download
explicitly override it.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@ashtarkb

ashtarkb commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d janus cpt-xks
/var caliper.postprocess.filtering.include_labels: [version=3.5.0-ea.2]
/var caliper.postprocess.s3.export.enabled: false
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
/var caliper.replot.keep: true

@psap-forge-bot

psap-forge-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

🟢 Execution of llm_d janus cpt-xks 🟢

Execution Engine Configuration

forge:
  args:
  - janus
  - cpt-xks
  configOverrides:
    caliper.postprocess.filtering.include_labels:
    - version=3.5.0-ea.2
    caliper.postprocess.s3.export.enabled: false
    caliper.replot.keep: true
    caliper.replot.url: https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
  project: llm_d

Artifact Links

Test Logs

00 Replot 3 minutes, 2 seconds

🔄 01 Export-Artifacts

Post-processing Status

@psap-forge-bot

psap-forge-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
🟢 Submission of llm_d janus cpt-xks succeeded after 9 minutes, 53 seconds 🟢
/test fournos llm_d janus cpt-xks
/var caliper.postprocess.filtering.include_labels: [version=3.5.0-ea.2]
/var caliper.postprocess.s3.export.enabled: false
/var caliper.replot.keep: true
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

@kpouget kpouget changed the title solidify the metrics to mlflow [caliper] solidify the metrics to mlflow Aug 5, 2026
Comment on lines +1073 to +1075
if not kpis_json_path.is_file():
logger.warning("kpis.json not found at %s, skipping metrics generation", kpis_json_path)
return

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.

this should be an error (and not here, in the engine, see next comment)

Consistent with the source_to_destination naming convention used
elsewhere: artifacts_to_kpis, kpis_to_csv, artifacts_to_ai_data.

Co-authored-by: Cursor <cursoragent@cursor.com>
return

try:
from projects.caliper.engine.kpi.metrics_from_kpis import generate_metrics_from_kpis

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.

this is breaking the encapsulation 🙃
can you add a command entrypoint for that, same as the existing transform steps

that makes Caliper easier to use independently from the Python code

else:
logger.warning("kpis-to-metrics: %s", result.get("error", "unknown error"))
except Exception as e:
logger.warning("kpis-to-metrics conversion failed (non-fatal): %s", e)

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.

should be fatal, and the export.py workflow should determine what to do with the failure

ashtarkb and others added 2 commits August 6, 2026 11:01
Replace direct engine import in postprocess.py with fork/exec
subprocess call via the new `caliper kpi kpis-to-mlflow` CLI command,
matching the pattern used by all other Caliper orchestration steps.

- Add kpis-to-mlflow click command in cli/commands.py
- Add build_kpis_to_mlflow_command in cli_builder.py
- Register command under kpi_group in cli/main.py
- Orchestrator catches step failure and records status, continuing
  remaining steps
- kpis_to_mlflow.py raises FileNotFoundError instead of swallowing

Co-authored-by: Cursor <cursoragent@cursor.com>
@ashtarkb

ashtarkb commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

/test fournos llm_d janus cpt-xks
/var caliper.postprocess.filtering.include_labels: [version=3.5.0-ea.2]
/var caliper.postprocess.s3.export.enabled: false
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
/var caliper.replot.keep: true

@psap-forge-bot

psap-forge-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

🟢 Execution of llm_d janus cpt-xks 🟢

Execution Engine Configuration

forge:
  args:
  - janus
  - cpt-xks
  configOverrides:
    caliper.postprocess.filtering.include_labels:
    - version=3.5.0-ea.2
    caliper.postprocess.s3.export.enabled: false
    caliper.replot.keep: true
    caliper.replot.url: https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd
  project: llm_d

Artifact Links

Test Logs

00 Replot 3 minutes, 12 seconds

🔄 01 Export-Artifacts

Post-processing Status

@psap-forge-bot

psap-forge-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown
🟢 Submission of llm_d janus cpt-xks succeeded after 10 minutes, 10 seconds 🟢
/test fournos llm_d janus cpt-xks
/var caliper.postprocess.filtering.include_labels: [version=3.5.0-ea.2]
/var caliper.postprocess.s3.export.enabled: false
/var caliper.replot.keep: true
/pipeline forge-replot
/clusterless
/replot.url https://mlflow.apps.psap-automation.ibm.rhperfscale.org/#/experiments/322/runs/8a13e32925dd44fda4103fe56cfc09d0?workspace=forge-llmd

Comment thread projects/caliper/orchestration/postprocess.py
Self-contained failure handling in _run_kpis_to_metrics_step,
consistent with all other _run_*_step methods.

Co-authored-by: Cursor <cursoragent@cursor.com>
@kpouget

kpouget commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 6, 2026
@ashtarkb

ashtarkb commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

/approve

@openshift-ci

openshift-ci Bot commented Aug 6, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ashtarkb

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 6, 2026
@openshift-merge-bot
openshift-merge-bot Bot merged commit 01c4aa5 into openshift-psap:main Aug 6, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants