Skip to content

v0.4.0 — Dynamic subject and action fields on @cycles

Choose a tag to compare

@amavashev amavashev released this 27 Apr 23:52
· 23 commits to main since this release
8f8084c

What's Changed

The @cycles decorator now accepts callables on every previously-static field — six subject fields (tenant, workspace, app, workflow, agent, toolset), three action fields (action_kind, action_name, action_tags), and dimensions. Callables are invoked with the decorated function's *args, **kwargs at reservation time, enabling per-call budget routing and dynamic action labeling.

@cycles(
    estimate=lambda req, workspace_id: req.tokens * 10,
    workspace=lambda req, workspace_id: workspace_id,        # per-call routing
    action_kind=lambda req, *_: f"llm.{req.provider}",       # dynamic label
    action_name=lambda req, *_: req.model,
    dimensions=lambda req, *_: {"region": req.region},
)
def run_request(req: ResponseRequest, workspace_id: str) -> Response: ...

Mirrors the existing estimate / actual callable contract and re-aligns the Python client with the Java client's SpEL behavior shipped in cycles-spring-boot-starter 0.2.1.

Fallback semantics (preserved)

  • Subject callables returning None fall through to the client-config default.
  • action_kind / action_name returning None fall through to "unknown".
  • action_tags / dimensions returning None are omitted from the request.
  • Exceptions in user callables propagate fail-fast without creating a reservation.

No protocol or wire-format changes.

  • feat(decorator): support callables on subject and action fields by @amavashev in #46

Test coverage: 100% across all 13 modules (389 tests).

Full Changelog: v0.3.0...v0.4.0