Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions tests/models/foundation/test_flowstate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import numpy as np
import pandas as pd

from timecopilot import TimeCopilotForecaster
from timecopilot.models.foundation.flowstate import FlowState


def test_flowstate_h1_single_uid():
# create simple weekly data for one unique_id
ds = pd.date_range("2024-01-01", periods=20, freq="W")
df = pd.DataFrame({"unique_id": "u1", "ds": ds, "y": np.arange(20)})

tcf = TimeCopilotForecaster(models=[FlowState()])

# this used to crash before the fix
fcst = tcf.forecast(df=df, h=1, freq="W")

# basic checks
assert isinstance(fcst, pd.DataFrame)
assert len(fcst) == 1
assert "unique_id" in fcst.columns
assert "ds" in fcst.columns
4 changes: 2 additions & 2 deletions timecopilot/models/foundation/flowstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ def _predict_batch(
batch_first=False,
).prediction_outputs
fcst = fcst.squeeze(-1).transpose(-1, -2) # now shape is (batch, h, quantiles)
fcst_mean = fcst[..., supported_quantiles.index(0.5)].squeeze()
fcst_mean_np = fcst_mean.detach().numpy()
fcst_mean = fcst[..., supported_quantiles.index(0.5)]
fcst_mean_np = fcst_mean.detach().numpy(force=True)
fcst_quantiles_np = fcst.detach().numpy() if quantiles is not None else None
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

This change fixes a shape edge case for h=1 and/or batch size 1, but there doesn’t appear to be a regression test covering the previously-crashing scenario (single unique_id, h=1). Adding a small pytest that exercises FlowState.forecast with n_series=1 and h=1 would prevent this from reappearing.

Suggested change
fcst_quantiles_np = fcst.detach().numpy() if quantiles is not None else None
# Ensure we never propagate scalar (0D) arrays, which can occur in edge cases
if fcst_mean_np.shape == ():
fcst_mean_np = np.expand_dims(fcst_mean_np, axis=0)
if quantiles is not None:
fcst_quantiles_np = fcst.detach().numpy()
if fcst_quantiles_np.shape == ():
fcst_quantiles_np = np.expand_dims(fcst_quantiles_np, axis=0)
else:
fcst_quantiles_np = None

Copilot uses AI. Check for mistakes.
return fcst_mean_np, fcst_quantiles_np

Expand Down