Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -880,8 +880,8 @@ jobs:
release-smoke/bin/python -c
"import importlib.metadata as metadata;
import aisimulate, aisimulate_core, aiconfigurator, aiconfigurator_core;
assert aisimulate.__version__ == aisimulate_core.__version__ == '0.12.0';
assert metadata.version('aisimulate') == '0.12.0';
assert aisimulate.__version__ == aisimulate_core.__version__ == '0.13.0';
assert metadata.version('aisimulate') == '0.13.0';
installed = {dist.metadata['Name'].lower() for dist in metadata.distributions()};
forbidden = {'aisimulate-core', 'aiconfigurator', 'aiconfigurator-core'};
assert installed.isdisjoint(forbidden), installed & forbidden"
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ exclude = ["crates/tests/public-api"]
resolver = "3"

[workspace.package]
version = "0.12.0"
version = "0.13.0"
edition = "2024"
description = "Backend-neutral inference simulation and deployment configuration search"
authors = ["NVIDIA Inc. <sw-dl-dynamo@nvidia.com>"]
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ contract.
## AIConfigurator compatibility CLI

The `aisimulate` wheel preserves the established `aiconfigurator` command for
workflows that have not yet moved to the unified CLI. AISimulate 0.12.0 keeps
workflows that have not yet moved to the unified CLI. AISimulate 0.13.0 keeps
this compatibility surface, while new prediction and search integrations
should start with `aisimulate predict` and `aisimulate recommend`.

Expand Down Expand Up @@ -231,7 +231,7 @@ development, releases, issues, and pull requests; open all new issues and pull
requests in this repository.

The `aiconfigurator` compatibility command remains available from the
`aisimulate` wheel in 0.12.0. It is targeted for removal in AISimulate 0.13.0,
`aisimulate` wheel through 0.13.0. It is targeted for removal in AISimulate 0.14.0,
after every remaining AIC workflow has a verified replacement in the unified
`aisimulate` CLI. Until then, use the compatibility command for the workflows
identified in the migration guide.
Expand Down
2 changes: 1 addition & 1 deletion crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[package]
name = "aisimulate-core"
description = "Engine-neutral inference simulation, deterministic replay, and performance modeling"
version = "0.12.0"
version = "0.13.0"
edition.workspace = true
authors.workspace = true
license.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/core/perfmodel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ crate's `embed-python` feature, which enables PyO3's `auto-initialize` support:

```toml
[dependencies]
aisimulate-core = { version = "0.12.0", features = ["embed-python"] }
aisimulate-core = { version = "0.13.0", features = ["embed-python"] }
```

Applications that embed Python in an existing host may initialize the
Expand Down
2 changes: 1 addition & 1 deletion crates/tests/public-api/Cargo.lock

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

8 changes: 4 additions & 4 deletions docs/artifact-contract.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AISimulate artifact contract

AISimulate 0.12.0 has one product version and exactly two release artifacts:
AISimulate 0.13.0 has one product version and exactly two release artifacts:

| Artifact | Build manifest | Public purpose |
| --- | --- | --- |
Expand All @@ -17,7 +17,7 @@ live inside the `aisimulate` wheel and therefore do not add artifacts.
builds and validates the output directory afterward. A release build fails if
an additional wheel, source distribution, or crate appears.

Both artifacts use version `0.12.0`. The wheel builds its native extension from
Both artifacts use version `0.13.0`. The wheel builds its native extension from
the same Rust source as the published crate; it does not install a second core
distribution.

Expand All @@ -36,8 +36,8 @@ fails CI if either packaging copy differs byte-for-byte from its root original,
and the release-artifact validator checks the bytes installed in the wheel.

Nightly builds stamp a dev suffix with `scripts/apply_dev_version.py` before
building: the wheel becomes `0.12.0.devYYYYMMDD` (PEP 440) and the crate
`0.12.0-dev.YYYYMMDD` (SemVer — cargo rejects the PEP 440 spelling, and the
building: the wheel becomes `0.13.0.devYYYYMMDD` (PEP 440) and the crate
Comment thread
jasonqinzhou marked this conversation as resolved.
Resolved
`0.13.0-dev.YYYYMMDD` (SemVer — cargo rejects the PEP 440 spelling, and the
dotted date is a numeric identifier so pre-release versions order
numerically). The wheel form follows the ai-dynamo/dynamo nightly
convention. The release script accepts only this suffix pair and still
Expand Down
2 changes: 1 addition & 1 deletion docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ Main branch nightly CI builds the approved release surface: one `aisimulate` whe
architecture and one `aisimulate-core` Rust source crate. A changes guard compares
`main` with the last successful scheduled nightly. The build stamps a dev version using the original UTC run-creation date followed
by its zero-padded ten-digit workflow run number, for example
`0.12.0.dev202609170000001234`. Scheduled and manual runs have distinct versions;
`0.13.0.dev202609170000001234`. Scheduled and manual runs have distinct versions;
retries retain the same version, and later dates sort after earlier dates. Builds
use pinned tooling and record checksums and provenance.

Expand Down
4 changes: 2 additions & 2 deletions docs/cli/migrate-from-aiconfigurator.md
Original file line number Diff line number Diff line change
Expand Up @@ -1471,7 +1471,7 @@ aggregate-only SLA semantics, described in its feature guide.
### 6.2 Repository and release transition

AISimulate is the home for ongoing development, issues, and releases. The standalone
AIConfigurator repository is scheduled to archive after its final 0.12.0 release. AISimulate 0.12.0
keeps the AIC compatibility command; removal is targeted for 0.13.0 after all remaining workflows
AIConfigurator repository is scheduled to archive after its final 0.12.0 release. AISimulate 0.13.0
keeps the AIC compatibility command; removal is targeted for 0.14.0 after all remaining workflows
have verified unified-CLI replacements. See the [release transition policy](../../README.md#aiconfigurator-repository-transition)
and [repository history](../repository-history.md).
2 changes: 1 addition & 1 deletion docs/core-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ and unified native PyO3 extension. It does not depend on another core
distribution or on Dynamo. The crate owns the compiled engine, forward-pass
model, Replay runtime, KV-cache request/response types, and the embedded
Rust-to-Python construction path. The legacy `aiconfigurator_core` Python
namespace remains available during the AIC 0.12.0 compatibility window.
namespace remains available in AISimulate 0.13.0 for compatibility.

## Stable Python facade

Expand Down
2 changes: 1 addition & 1 deletion docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ to the intended environment.
## Use an internal nightly

The [nightly workflow](../.github/workflows/nightly-ci.yml) produces a wheel
version such as `0.12.0.devYYYYMMDD`, then stages artifacts to access-controlled
version such as `0.13.0.devYYYYMMDD`, then stages artifacts to access-controlled
Artifactory through the protected release environment. The run subsequently
checks the downloaded wheel and qualifies its FPE support matrix. Use a
successful completed nightly: a successful build, staging step, or dev suffix
Expand Down
4 changes: 2 additions & 2 deletions docs/repository-history.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ will publish its final 0.12.0 `aiconfigurator` and `aiconfigurator-core`
artifacts and then be archived; ongoing development, releases, issues, and pull
requests move to AISimulate.

The compatibility command remains in the AISimulate 0.12.0 wheel and is
targeted for removal in AISimulate 0.13.0. Removal is gated on verified unified
The compatibility command remains in the AISimulate 0.13.0 wheel and is
targeted for removal in AISimulate 0.14.0. Removal is gated on verified unified
CLI replacements for every remaining workflow in the migration guide.

For features already implemented by the standalone Sweeper, see
Expand Down
5 changes: 3 additions & 2 deletions python/aisimulate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ SPDX-License-Identifier: Apache-2.0
# AISimulate application (AIConfigurator compatibility source)

> This directory contains the complete AIConfigurator application migrated to
> the standalone AISimulate repository. It builds the `aisimulate` 0.12.0
> the standalone AISimulate repository. It builds the `aisimulate` 0.13.0
Comment thread
jasonqinzhou marked this conversation as resolved.
Resolved
> wheel, not a separate `aiconfigurator` wheel. The legacy import namespace and
> `aiconfigurator` executable remain compatibility surfaces alongside the public
> `aisimulate` prediction CLI. The original AIC
> `aisimulate` prediction CLI. Command removal is targeted for AISimulate 0.14.0,
> after every remaining workflow has a verified unified-CLI replacement. The original AIC
> documentation below is retained so existing workflows remain discoverable
> during the CLI parity and deprecation window.

Expand Down
2 changes: 1 addition & 1 deletion python/aisimulate/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

[project]
name = "aisimulate"
version = "0.12.0"
version = "0.13.0"
authors = [
{ name = "NVIDIA Inc.", email = "sw-dl-dynamo@nvidia.com" },
]
Expand Down
20 changes: 10 additions & 10 deletions python/aisimulate/src/aiconfigurator/deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,27 @@

logger = logging.getLogger(__name__)

_MIGRATION_GUIDE = "https://github.com/ai-dynamo/aiconfigurator/blob/main/docs/aisimulate_migration.md"
_MIGRATION_GUIDE = "https://github.com/ai-dynamo/aisimulate/blob/main/docs/cli/migrate-from-aiconfigurator.md"
_warned_entry_points: set[str] = set()

_P = ParamSpec("_P")
_R = TypeVar("_R")


def warn_legacy_cli(mode: str | None) -> None:
"""Warn once when the CLI is run from the legacy AIC distribution."""
"""Warn once when the legacy compatibility CLI is run."""

command = "aiconfigurator cli" + (f" {mode}" if mode else "")
key = f"cli:{mode or '<root>'}"
if key in _warned_entry_points:
return
_warned_entry_points.add(key)
message = (
f"`{command}` is running from the deprecated AIConfigurator "
"distribution, which is planned for removal in AIConfigurator 0.13.0. "
f"Install `aisimulate==0.12.0` and keep running `{command} ...`; "
"AISimulate preserves the established command name and arguments. "
f"`{command}` is a deprecated compatibility command shipped by AISimulate 0.13.0. "
"Command removal is targeted for AISimulate 0.14.0 after every remaining "
"workflow has a verified unified-CLI replacement. "
f"Until then, keep running `{command} ...`; AISimulate preserves the "
"established command name and arguments. "
f"Migration guide: {_MIGRATION_GUIDE}"
)
warnings.warn(message, DeprecationWarning, stacklevel=4)
Expand All @@ -51,10 +52,9 @@ def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _R:
if entry_point not in _warned_entry_points:
_warned_entry_points.add(entry_point)
warnings.warn(
f"`{entry_point}()` is deprecated and will be removed in "
"AIConfigurator 0.13.0. Migrate to "
"`aisimulate.sweeper.Sweeper(...).run(config)`. Installing "
"`aisimulate==0.12.0` temporarily retains the legacy "
f"`{entry_point}()` is deprecated. Migrate to "
"`aisimulate.sweeper.Sweeper(...).run(config)`. "
"AISimulate 0.13.0 temporarily retains the legacy "
f"`aiconfigurator` import namespace. Migration guide: {_MIGRATION_GUIDE}",
DeprecationWarning,
stacklevel=2,
Expand Down
2 changes: 1 addition & 1 deletion python/aisimulate/src/aisimulate_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""Public AISimulate core namespace.

The implementation keeps the ``aiconfigurator_core`` package importable for
the AIC 0.12.0 compatibility window. New consumers should import this module or
the AISimulate 0.13.0 compatibility window. New consumers should import this module or
``aisimulate_core.sdk``.
"""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,17 @@ def test_built_application_wheel_runs_installed_fpm_plan_and_resolves_runtime_as
cwd=unrelated_repository,
env=env,
)
installed_version = _run(
[
str(installed_python),
"-c",
"import importlib.metadata; print(importlib.metadata.version('aisimulate'))",
],
cwd=unrelated_repository,
env=env,
).stdout.strip()

assert "Verified installed AISimulate 0.12.0 FPM workflow" in completed.stdout
assert "installed:aisimulate==0.12.0:record-sha256:" in completed.stdout
assert f"Verified installed AISimulate {installed_version} FPM workflow" in completed.stdout
assert f"installed:aisimulate=={installed_version}:record-sha256:" in completed.stdout
assert unrelated_head not in completed.stdout
assert str(unrelated_repository) not in completed.stdout
9 changes: 6 additions & 3 deletions python/aisimulate/tests/unit/test_aisimulate_deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ def test_each_legacy_cli_mode_warns_without_renaming_the_command(monkeypatch, mo
assert f"`aiconfigurator cli {mode}`" in str(warning.message)
assert f"`aiconfigurator cli {mode} ...`" in str(warning.message)
assert "`aisimulate cli" not in str(warning.message)
assert "AIConfigurator 0.13.0" in str(warning.message)
assert "deprecated AIConfigurator distribution" in str(warning.message)
assert "AISimulate 0.13.0" in str(warning.message)
assert "removal is targeted for AISimulate 0.14.0" in str(warning.message)
assert "deprecated compatibility command" in str(warning.message)
assert "aisimulate==0.12.0" not in str(warning.message)
assert "preserves the established command name" in str(warning.message)
assert warning.filename == __file__

Expand Down Expand Up @@ -91,5 +93,6 @@ def test_each_legacy_sweeper_entry_point_warns_once_at_caller(entry_point) -> No
assert warning.category is DeprecationWarning
assert entry_point.__name__ in str(warning.message)
assert "aisimulate.sweeper.Sweeper" in str(warning.message)
assert "AIConfigurator 0.13.0" in str(warning.message)
assert "AISimulate 0.13.0" in str(warning.message)
assert "aisimulate==0.12.0" not in str(warning.message)
assert warning.filename == __file__
2 changes: 1 addition & 1 deletion python/aisimulate/uv.lock

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

2 changes: 1 addition & 1 deletion scripts/apply_dev_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
- [project].version in python/aisimulate/pyproject.toml (PEP 440 form)
- [package].version in crates/core/Cargo.toml and
[workspace.package].version in Cargo.toml (SemVer form: dash instead of
dot, so '0.12.0-dev.20260827' -- cargo rejects the PEP 440 spelling)
dot, so '0.13.0-dev.202609170000001234' -- cargo rejects the PEP 440 spelling)

The suffix is the UTC creation date followed by a ten-digit workflow run
number; legacy date-only suffixes remain accepted. The crate form keeps the
Expand Down
4 changes: 2 additions & 2 deletions scripts/build_release_artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
VERSION = "0.12.0"
VERSION = "0.13.0"
# Nightly CI stamps a dev suffix via scripts/apply_dev_version.py:
# PEP 440 `0.12.0.devYYYYMMDD` in the wheel, SemVer `0.12.0-dev.YYYYMMDD` in
# PEP 440 `0.13.0.devYYYYMMDD` in the wheel, SemVer `0.13.0-dev.YYYYMMDD` in
# the crate, optionally followed by a ten-digit run number in both formats.
# Cargo rejects the PEP 440 spelling. The release contract still
# anchors on VERSION; only this suffix pair is additionally accepted.
Expand Down
7 changes: 3 additions & 4 deletions tests/sweeper/test_packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,9 @@ def test_aisimulate_source_versions_are_synchronized():
core = tomllib.loads((repo_root / "crates/core/Cargo.toml").read_text())
workspace = tomllib.loads((repo_root / "Cargo.toml").read_text())

expected_python = "0.12.0"
expected_cargo = "0.12.0"
assert project["project"]["version"] == expected_python
assert core["package"]["version"] == expected_cargo
workspace_version = workspace["workspace"]["package"]["version"]
assert project["project"]["version"] == workspace_version
assert core["package"]["version"] == workspace_version
assert workspace["workspace"]["members"] == ["crates/core"]
assert project["tool"]["maturin"]["manifest-path"] == "../../crates/core/Cargo.toml"

Expand Down
20 changes: 16 additions & 4 deletions tests/test_ci_workflow_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import shutil
import subprocess
import sys
import tomllib
import zipfile
from pathlib import Path
from types import SimpleNamespace
Expand Down Expand Up @@ -2762,6 +2763,11 @@ def _nightly_version(created, number):
)


def _current_product_version():
manifest = tomllib.loads((REPOSITORY_ROOT / "python/aisimulate/pyproject.toml").read_text())
return manifest["project"]["version"]


def test_nightly_versions_are_unique_date_ordered_and_stable_across_retries():
from packaging.version import Version

Expand All @@ -2778,20 +2784,26 @@ def test_nightly_versions_are_unique_date_ordered_and_stable_across_retries():
versions.append(value["dev-version"])
assert json.loads(_nightly_version(date, number).stdout) == value
assert versions == ["202609170000001234", "202609170000001235", "202609180000001236"]
assert Version("0.12.0.dev20260917") < Version("0.12.0.dev" + versions[0])
assert [Version("0.12.0.dev" + v) for v in versions] == sorted(Version("0.12.0.dev" + v) for v in versions)
base_version = _current_product_version()
assert Version(f"{base_version}.dev20260917") < Version(f"{base_version}.dev{versions[0]}")
stamped_versions = [Version(f"{base_version}.dev{version}") for version in versions]
assert stamped_versions == sorted(stamped_versions)
for number in (0, -1, 10000000000, "invalid"):
assert _nightly_version("2026-09-17T00:00:00Z", number).returncode != 0


@pytest.mark.parametrize("suffix", [".dev20260917", ".dev202609170000001234"])
@pytest.mark.parametrize("base_version", ["0.12.0", "0.11.0"])
@pytest.mark.parametrize("base_version", [None, "0.12.0"], ids=["current", "historical"])
def test_current_release_tools_stamp_and_validate_historical_manifests(tmp_path, suffix, base_version):
current_version = _current_product_version()
base_version = base_version or current_version
for name in ("Cargo.toml", "crates/core/Cargo.toml", "python/aisimulate/pyproject.toml"):
target = tmp_path / name
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(
(REPOSITORY_ROOT / name).read_text().replace('version = "0.12.0"', f'version = "{base_version}"')
(REPOSITORY_ROOT / name)
.read_text()
.replace(f'version = "{current_version}"', f'version = "{base_version}"')
)
for args in (
["init", "-q"],
Expand Down
Loading