with one click
python-feature-lifecycle
Guidance for package and feature lifecycle in the Agent Framework Python codebase, including stage meanings, feature-stage decorators, feature enums, and how to move APIs from one stage to the next.
Menu
Guidance for package and feature lifecycle in the Agent Framework Python codebase, including stage meanings, feature-stage decorators, feature enums, and how to move APIs from one stage to the next.
How to use the verify-samples tool to run, verify, and manage sample definitions in the Agent Framework repository. Use this when adding, updating, or running sample verification.
Coding standards, conventions, and patterns for developing Python code in the Agent Framework repository. Use this when writing or modifying Python source files in the python/ directory.
Validate, test, and debug regular expressions by executing them against sample inputs. Use when asked to build, verify, or explain a regex pattern.
When and how to escalate Contoso Outdoors customer-support tickets.
Contoso Outdoors customer-support tone and formatting guidelines.
Convert between common units using a multiplication factor. Use when asked to convert miles, kilometers, pounds, or kilograms.
| name | python-feature-lifecycle |
| description | Guidance for package and feature lifecycle in the Agent Framework Python codebase, including stage meanings, feature-stage decorators, feature enums, and how to move APIs from one stage to the next. |
Agent Framework uses lifecycle at two different levels:
These are related, but they are not the same thing.
If a package is still in beta / experimental preview, all public APIs in that package are experimental by default.
@experimental(...) everywhere in that package.Once a package moves forward, you can keep individual features behind:
That is the main use case for feature-stage decorators.
Use for features that are still unstable and may change or be removed without notice.
Feature-level code pattern:
from ._feature_stage import ExperimentalFeature, experimental
@experimental(feature_id=ExperimentalFeature.MY_FEATURE)
class MyFeature:
...
Behavior:
Enum setup:
ExperimentalFeatureUse for features that are nearly stable but may still receive small refinements before GA.
Feature-level code pattern:
from ._feature_stage import ReleaseCandidateFeature, release_candidate
@release_candidate(feature_id=ReleaseCandidateFeature.MY_FEATURE)
class MyFeature:
...
Behavior:
Enum setup:
ReleaseCandidateFeatureUse for stable GA APIs.
Code pattern:
ExperimentalFeatureReleaseCandidateFeatureIf a feature is fully released, remove any stage-specific feature annotation.
Use for APIs that still exist but should not be used for new code.
Code pattern:
import sys
if sys.version_info >= (3, 13):
from warnings import deprecated # type: ignore # pragma: no cover
else:
from typing_extensions import deprecated # type: ignore # pragma: no cover
@deprecated("MyOldFeature is deprecated. Use MyNewFeature instead.")
class MyOldFeature:
...
Behavior:
Deprecated APIs should not also carry feature-stage decorators.
| Feature stage | Expected annotation |
|---|---|
| Experimental | @experimental(feature_id=ExperimentalFeature.X) |
| Release candidate | @release_candidate(feature_id=ReleaseCandidateFeature.X) |
| Released | No feature-stage decorator |
| Deprecated | @deprecated("...") |
The feature enums are the inventory of currently staged features:
ExperimentalFeatureReleaseCandidateFeatureGuidance:
Minimal consumer guidance:
__feature_stage__ and __feature_id__ as optional staged metadata, not as stable contractsgetattr(obj, "__feature_stage__", None) and getattr(obj, "__feature_id__", None) rather than direct attribute accessExperimentalFeature.X, ReleaseCandidateFeature.X, or the continued presence of __feature_id__ after a feature moves stages or is releasedFor consumers, the enums are also re-exported from agent_framework.
For internal implementation code inside agent_framework, continue to import the enums and decorators from ._feature_stage.
Use the following rules:
@experimental(...) only for features that are intentionally still behind the package@experimental(...) or @release_candidate(...) only for features still being held backExperimentalFeature to ReleaseCandidateFeature@experimental(...) with @release_candidate(...)@experimental(...)ExperimentalFeature@release_candidate(...)ReleaseCandidateFeature@deprecated("...")Features do not have to pass through every stage.
Likewise, when a package advances, do not automatically move every feature with it.
__feature_stage__ and __feature_id__ as optional metadata; use getattr