Files
hao-ai-lab-FastVideo/v2/request/requests.py
T
SolitaryThinker 4e331eb7ff [refactor] v2: use absolute imports (v2.*) everywhere instead of relative
Mechanical conversion of every relative import under v2/ to an absolute v2.* path
(from .x / ..x / ...x -> from v2.<pkg>.x) so imports are unambiguous, grep-able, and
stable when code is copied/moved between entrypoints (VideoGenerator, CLI, server).

Surgical prefix-only rewrite: only the 'from <dots><module>' prefix changed — import
names, parentheses, multi-line formatting, comments, and ordering are byte-for-byte
preserved (no collapsing, no reorder, no unrelated reformatting).

- 471 imports across 125 files; v2/tests/ was already absolute (untouched).
- Validated: all 125 files compile, every 'from v2.* import' target resolves to a real
  module/package, zero relative imports remain (full sweep), CPU mini suite green
  (202 passed, 2 skipped).
2026-07-04 17:15:34 +00:00

98 lines
3.6 KiB
Python

"""Request + Session — the only currency crossing the product boundary (design_v3 §12).
"A typed ``Request`` carries ``task`` (declared, never inferred), ``inputs``
(ModalParts), AR ``sampling`` vs ``diffusion`` params, an ``OutputSpec``, and
per-node overrides." Products construct Requests; they never reach into the model.
"""
from __future__ import annotations
import itertools
from dataclasses import dataclass, field
from v2.request.cancel import CancelKind, CancelScope
from v2.request.modalpart import ImagePart, ModalPart, TextPart
from v2.request.params import DiffusionParams, OutputSpec, SamplingParams
from v2.request.streams import Stream
from v2.request.tasks import TaskType
_counter = itertools.count(1)
def new_request_id() -> str:
return f"req-{next(_counter)}"
@dataclass(frozen=True)
class Request:
request_id: str
task: TaskType
model_id: str # which ModelCard to run
inputs: tuple[ModalPart, ...] = ()
sampling: SamplingParams = field(default_factory=SamplingParams)
diffusion: DiffusionParams = field(default_factory=DiffusionParams)
outputs: OutputSpec = field(default_factory=OutputSpec)
node_params: dict[str, dict] = field(default_factory=dict) # per graph-node overrides
priority: int = 0
# --- convenience accessors (do not infer task from these; §12) ---
def prompt(self) -> str:
for p in self.inputs:
if isinstance(p, TextPart):
return p.text
return ""
def image(self):
for p in self.inputs:
if isinstance(p, ImagePart):
return p
return None
def node_override(self, node_id: str) -> dict:
return self.node_params.get(node_id, {})
def make_request(task: TaskType, model_id: str, prompt: str = "", *,
inputs: tuple[ModalPart, ...] | None = None,
sampling: SamplingParams | None = None,
diffusion: DiffusionParams | None = None,
outputs: OutputSpec | None = None,
node_params: dict[str, dict] | None = None,
priority: int = 0,
request_id: str | None = None) -> Request:
"""Ergonomic constructor used by the offline API and tests."""
parts: tuple[ModalPart, ...] = inputs if inputs is not None else ((TextPart(prompt),) if prompt else ())
return Request(
request_id=request_id or new_request_id(),
task=task, model_id=model_id, inputs=parts,
sampling=sampling or SamplingParams(),
diffusion=diffusion or DiffusionParams(),
outputs=outputs or OutputSpec(),
node_params=node_params or {},
priority=priority,
)
@dataclass
class Session:
"""A long-lived interactive context (design_v3 §12, §15e Dreamverse).
Holds prompt memory, media streams, a cancel scope, and a handle to
cross-request chunk-KV that persists for a game/scene session (self-forcing /
world-model rollout). Mutable by design.
"""
session_id: str
prompt_memory: list[str] = field(default_factory=list)
streams: dict[str, Stream] = field(default_factory=dict)
cancel_scope: CancelScope | None = None
kv_handle: object | None = None # persistent chunk-KV CacheHandle (see cache/)
def __post_init__(self):
if self.cancel_scope is None:
self.cancel_scope = CancelScope(kind=CancelKind.SESSION, target_id=self.session_id)
def push_text(self, text: str) -> None:
self.prompt_memory.append(text)
def stream(self, name: str) -> Stream:
return self.streams.setdefault(name, Stream(f"{self.session_id}:{name}"))