Skip to content
Merged
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
6 changes: 6 additions & 0 deletions docs/api/models/foundation/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
members:
- T0


::: timecopilot.models.foundation.tafsut
options:
members:
- Tafsut

::: timecopilot.models.foundation.tabpfn
options:
members:
Expand Down
21 changes: 20 additions & 1 deletion docs/changelogs/v0.0.31.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
### Features

* **foundationforecast library**: Foundation model implementations now live in the standalone [`foundationforecast`](https://pypi.org/project/foundationforecast/) package on PyPI (requires `foundationforecast>=0.1.2` for Tafsut). TimeCopilot re-exports them at `timecopilot.models.foundation.*` for backward compatibility. Model docstrings and core forecaster logic are maintained in the [foundationforecast](https://github.com/TimeCopilot/foundationforecast) repository. See [#368](https://github.com/TimeCopilot/timecopilot/pull/368).

* **Tafsut foundation model**: Added support for [Tafsut](https://github.com/Tafsut-FM/tafsut), a zero-shot probabilistic univariate time series foundation model. Use it via the `Tafsut` class. See the [model card](https://huggingface.co/Tafsut-FM/tafsut-univariate-base).

```python
import pandas as pd
from timecopilot.models.foundation.tafsut import Tafsut

df = pd.read_csv(
"https://timecopilot.s3.amazonaws.com/public/data/air_passengers.csv",
parse_dates=["ds"],
)

model = Tafsut()
fcst_df = model.forecast(df, h=12)
```

### Breaking Changes

* **GIFT-Eval moved to standalone package**: The in-repo `timecopilot.gift_eval` module was removed. GIFT-Eval integration now lives in the [`timecopilot-gift-eval`](https://pypi.org/project/timecopilot-gift-eval/) PyPI package (`timecopilot_gift_eval` import path). Install via `pip install "timecopilot[gift-eval]"` or `pip install timecopilot-gift-eval>=0.3.0`.
* **GIFT-Eval moved to standalone package**: The in-repo `timecopilot.gift_eval` module was removed. GIFT-Eval integration now lives in the [`timecopilot-gift-eval`](https://pypi.org/project/timecopilot-gift-eval/) PyPI package (`timecopilot_gift_eval` import path). Install via `pip install "timecopilot[gift-eval]"` or `pip install timecopilot-gift-eval>=0.3.0`. See [#369](https://github.com/TimeCopilot/timecopilot/pull/369).

**Migration:**

Expand Down
43 changes: 39 additions & 4 deletions docs/examples/agent-quickstart.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"\n",
"import pandas as pd\n",
"from timecopilot import TimeCopilot"
"from timecopilot import TimeCopilot\n"
]
},
{
Expand Down Expand Up @@ -148,20 +150,53 @@
"id": "59be5da5",
"metadata": {},
"source": [
"Initialize the forecasting agent. You can use any LLM by specifying the llm parameter.\n"
"## Initialize the forecasting agent\n",
"\n",
"You can use any LLM by specifying the `llm` parameter (for example, `openai:gpt-4o`). Before running the agent, set the API key for your chosen provider.\n"
]
},
{
"cell_type": "markdown",
"id": "4c7ab429",
"metadata": {},
"source": [
"### Set up your provider API key\n",
"\n",
"TimeCopilot reads credentials from environment variables. For OpenAI models, set `OPENAI_API_KEY`. If you use another provider, set the corresponding variable (for example, `GOOGLE_API_KEY` or `ANTHROPIC_API_KEY`) and update the `llm` string below.\n",
"\n",
"You can export the key in your shell or set it in the next cell before creating the agent.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1db1e491",
"metadata": {},
"outputs": [],
"source": [
"os.environ[\"OPENAI_API_KEY\"] = \"your-openai-api-key\""
]
},
{
"cell_type": "markdown",
"id": "7de8061e",
"metadata": {},
"source": [
"### Declare the forecasting agent"
]
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": null,
"id": "821101f6",
"metadata": {},
"outputs": [],
"source": [
"\n",
"tc = TimeCopilot(\n",
" llm=\"openai:gpt-4o\",\n",
" retries=3,\n",
")"
")\n"
]
},
{
Expand Down
464 changes: 34 additions & 430 deletions docs/examples/ts-foundation-models-comparison-quickstart.ipynb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ dependencies = [
"catboost>=1.2.10",
"datasets>=4.1.1",
"fire",
"foundationforecast>=0.1.1",
"foundationforecast>=0.1.2",
"fsspec>=2025.9.0",
"huggingface-hub>=0.36.2,<2.0",
"hydra-core>=1.3.2",
Expand Down Expand Up @@ -107,7 +107,7 @@ license = "MIT"
name = "timecopilot"
readme = "README.md"
requires-python = ">=3.10"
version = "0.0.30"
version = "0.0.31"

[project.optional-dependencies]
distributed = [
Expand Down
2 changes: 2 additions & 0 deletions tests/models/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from timecopilot.models.ensembles.median import MedianEnsemble
from timecopilot.models.foundation.chronos import Chronos
from timecopilot.models.foundation.moirai import Moirai
from timecopilot.models.foundation.tafsut import Tafsut
from timecopilot.models.foundation.timesfm import TimesFM
from timecopilot.models.foundation.toto import Toto
from timecopilot.models.ml import (
Expand Down Expand Up @@ -129,6 +130,7 @@ def disable_mps_session(monkeypatch):
batch_size=2,
repo_id="Salesforce/moirai-2.0-R-small",
),
Tafsut(context_length=512, batch_size=2),
]
if sys.version_info >= (3, 11):
from timecopilot.models.foundation.tirex import TiRex
Expand Down
3 changes: 2 additions & 1 deletion tests/models/foundation/test_shims.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@

from timecopilot.models.foundation.chronos import Chronos
from timecopilot.models.foundation.moirai import Moirai
from timecopilot.models.foundation.tafsut import Tafsut
from timecopilot.models.foundation.timegpt import TimeGPT
from timecopilot.models.foundation.timesfm import TimesFM
from timecopilot.models.foundation.toto import Toto
from timecopilot.models.utils.forecaster import Forecaster

SHIM_MODELS = [Chronos, Moirai, TimesFM, Toto, TimeGPT]
SHIM_MODELS = [Chronos, Moirai, Tafsut, TimesFM, Toto, TimeGPT]

if sys.version_info >= (3, 11):
from timecopilot.models.foundation.tirex import TiRex
Expand Down
19 changes: 19 additions & 0 deletions tests/models/foundation/test_tafsut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import numpy as np
import pandas as pd

from timecopilot import TimeCopilotForecaster
from timecopilot.models.foundation.tafsut import Tafsut


def test_tafsut_h1_single_uid():
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=[Tafsut(context_length=512, batch_size=1)])

fcst = tcf.forecast(df=df, h=1, freq="W")

assert isinstance(fcst, pd.DataFrame)
assert len(fcst) == 1
assert "unique_id" in fcst.columns
assert "ds" in fcst.columns
2 changes: 2 additions & 0 deletions timecopilot/models/foundation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from .chronos import Chronos, ChronosFinetuningConfig
from .moirai import Moirai
from .tafsut import Tafsut
from .timegpt import TimeGPT, TimeGPTFinetuningConfig
from .timesfm import TimesFM
from .toto import Toto
Expand All @@ -10,6 +11,7 @@
"Chronos",
"ChronosFinetuningConfig",
"Moirai",
"Tafsut",
"TimeGPT",
"TimeGPTFinetuningConfig",
"TimesFM",
Expand Down
10 changes: 10 additions & 0 deletions timecopilot/models/foundation/tafsut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from foundationforecast.models.tafsut import Tafsut as _Tafsut

from ..utils.forecaster import Forecaster


class Tafsut(_Tafsut, Forecaster):
pass


__all__ = ["Tafsut"]
28 changes: 23 additions & 5 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading