reactor-runtime 2.7.7__tar.gz → 2.7.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/PKG-INFO +1 -1
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/pyproject.toml +2 -2
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/config.py +36 -1
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/defaults.py +12 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/model_state.py +30 -3
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/runtime_api.py +383 -1
- reactor_runtime-2.7.9/src/reactor_runtime/schema_validator.py +231 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/utils/messages.py +4 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime.egg-info/PKG-INFO +1 -1
- reactor_runtime-2.7.7/src/reactor_runtime/schema_validator.py +0 -123
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/README.md +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/setup.cfg +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/api/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/experiment/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/experiment/session.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/driver/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/driver/pipeline_executor.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/driver/step_result.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/events/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/events/connected.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/events/event.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/events/messages.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/events/upload.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/internal/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/internal/input_buffer.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/internal/output_buffer.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/internal/reactor_core.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/model/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/model/decorators.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/model/handlers.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/model/reactor_model.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/pipeline/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/pipeline/idle.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/pipeline/input_state.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/pipeline/reactor_pipeline.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/tracks/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/tracks/descriptors.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/tracks/input.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/tracks/output.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/interface/upload.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/backends/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/backends/base.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/backends/file.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/backends/otlp.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/helpers.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/nvml_sampler.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/plotting/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/plotting/plot_profiling.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/profiler.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/singleton.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/profiling/torch_chunk_profiler.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/recording/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/recording/chunk_encoder.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/recording/chunk_uploader.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/recording/config.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/recording/markers.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/recording/session_recorder.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/recording/sinks.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/recording/track_resolver.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/runtimes/headless/config.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/runtimes/headless/headless_runtime.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/runtimes/headless/input_feeder.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/runtimes/http/config.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/runtimes/http/http_runtime.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/runtimes/http/types.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/schema.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/serve/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/serve/__main__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/serve/commands/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/serve/commands/run.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/serve/commands/schema.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/serve/main.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/serve/utils/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/serve/utils/config.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/serve/utils/runtime.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/aiortc/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/aiortc/audio_track.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/aiortc/client.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/aiortc/frame_conversion.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/aiortc/ice_connection.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/aiortc/video_track.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/config.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/events.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/client.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/decoders/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/decoders/av1.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/decoders/base.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/decoders/factory.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/decoders/h264.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/decoders/h265.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/decoders/opus.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/decoders/vp8.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/decoders/vp9.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/encoders/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/encoders/av1.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/encoders/base.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/encoders/factory.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/encoders/h264.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/encoders/h265.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/encoders/opus.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/encoders/vp8.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/encoders/vp9.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/gst.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/gst_helpers.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/probes/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/probes/fps_probe.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/receiver/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/receiver/audio.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/receiver/base.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/receiver/video.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/sdp/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/sdp/bundle.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/sdp/codec.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/sdp/extmap.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/sdp/ice.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/sender/__init__.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/sender/audio.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/sender/base.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/sender/video.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/settings.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/gstreamer/signals.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/ice_uris.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/interface.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/media.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/transports/types.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/utils/launch.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/utils/loader.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/utils/log.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/utils/paths.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/utils/ports.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime/utils/typing.py +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime.egg-info/SOURCES.txt +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime.egg-info/dependency_links.txt +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime.egg-info/requires.txt +0 -0
- {reactor_runtime-2.7.7 → reactor_runtime-2.7.9}/src/reactor_runtime.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "reactor_runtime"
|
|
7
|
-
version = "2.7.
|
|
7
|
+
version = "2.7.9"
|
|
8
8
|
description = "Reactor runtime with public model API"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Reactor", email = "team@reactor.inc" }
|
|
@@ -87,4 +87,4 @@ gst = [
|
|
|
87
87
|
# Legacy releases used `X.Y.Z-g<short-sha>` (e.g. `1.4.1-g5660eed`); the wheel
|
|
88
88
|
# stripped the `-g<sha>` suffix. fetch-proto.py still understands that shape
|
|
89
89
|
# for back-compat with old pins, but new bumps should track the calendar format.
|
|
90
|
-
version = "1.
|
|
90
|
+
version = "1.20260527.14467"
|
|
@@ -81,6 +81,37 @@ def _reset_legacy_warning_for_tests() -> None:
|
|
|
81
81
|
_legacy_warned = False
|
|
82
82
|
|
|
83
83
|
|
|
84
|
+
@dataclass
|
|
85
|
+
class ModerationYamlConfig:
|
|
86
|
+
"""Top-level ``moderation:`` block parsed from ``reactor.yaml``.
|
|
87
|
+
|
|
88
|
+
Model authors declare here whether content moderation runs for their
|
|
89
|
+
model. Defaults to ``enabled: false`` so existing models opt in
|
|
90
|
+
explicitly. Operational tuning (thresholds, concurrency, backend
|
|
91
|
+
choice, ``OPENAI_API_KEY``) stays in environment variables — this
|
|
92
|
+
block carries only the policy decision the model author owns.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
enabled: bool = False
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
def from_dict(cls, raw: Optional[Dict[str, Any]]) -> "ModerationYamlConfig":
|
|
99
|
+
if not isinstance(raw, dict):
|
|
100
|
+
return cls()
|
|
101
|
+
enabled = raw.get("enabled", False)
|
|
102
|
+
# Strict bool check: `bool("false") is True` would silently flip
|
|
103
|
+
# moderation on for a YAML author who wrote `enabled: "false"`
|
|
104
|
+
# (quoted) or templated a `"0"` value. Safety-sensitive config —
|
|
105
|
+
# fail at parse time with a message that names the offending value.
|
|
106
|
+
if not isinstance(enabled, bool):
|
|
107
|
+
raise TypeError(
|
|
108
|
+
f"moderation.enabled in reactor.yaml must be a boolean, "
|
|
109
|
+
f"got {type(enabled).__name__}: {enabled!r}. "
|
|
110
|
+
'Did you accidentally quote the value (e.g. "false")?'
|
|
111
|
+
)
|
|
112
|
+
return cls(enabled=enabled)
|
|
113
|
+
|
|
114
|
+
|
|
84
115
|
@dataclass
|
|
85
116
|
class ReactorConfig:
|
|
86
117
|
"""Parsed ``reactor.yaml``.
|
|
@@ -119,6 +150,7 @@ class ReactorConfig:
|
|
|
119
150
|
config_overrides: List[str] = field(default_factory=list)
|
|
120
151
|
weights_path: Optional[str] = None
|
|
121
152
|
recording: RecordingConfig = field(default_factory=RecordingConfig)
|
|
153
|
+
moderation: ModerationYamlConfig = field(default_factory=ModerationYamlConfig)
|
|
122
154
|
|
|
123
155
|
@classmethod
|
|
124
156
|
def from_dict(cls, raw: Dict[str, Any]) -> "ReactorConfig":
|
|
@@ -135,8 +167,9 @@ class ReactorConfig:
|
|
|
135
167
|
runtime_section = raw.get("runtime")
|
|
136
168
|
model_section = raw.get("model")
|
|
137
169
|
|
|
138
|
-
# Recording
|
|
170
|
+
# Recording and moderation are top-level siblings to runtime: / model:.
|
|
139
171
|
recording = RecordingConfig.from_dict(raw.get("recording"))
|
|
172
|
+
moderation = ModerationYamlConfig.from_dict(raw.get("moderation"))
|
|
140
173
|
|
|
141
174
|
modern = isinstance(runtime_section, dict) or isinstance(model_section, dict)
|
|
142
175
|
|
|
@@ -161,6 +194,7 @@ class ReactorConfig:
|
|
|
161
194
|
config=runtime_section.get("config"),
|
|
162
195
|
weights_path=runtime_section.get("weights_path") or None,
|
|
163
196
|
recording=recording,
|
|
197
|
+
moderation=moderation,
|
|
164
198
|
)
|
|
165
199
|
|
|
166
200
|
if "model" not in raw:
|
|
@@ -177,4 +211,5 @@ class ReactorConfig:
|
|
|
177
211
|
config=raw.get("config"),
|
|
178
212
|
weights_path=raw.get("weights_path") or None,
|
|
179
213
|
recording=recording,
|
|
214
|
+
moderation=moderation,
|
|
180
215
|
)
|
|
@@ -51,6 +51,7 @@ class FieldInfo:
|
|
|
51
51
|
min_length: Optional[int] = None
|
|
52
52
|
max_length: Optional[int] = None
|
|
53
53
|
choices: Optional[List[Any]] = None
|
|
54
|
+
moderate: bool = True
|
|
54
55
|
|
|
55
56
|
|
|
56
57
|
def InputField(
|
|
@@ -63,6 +64,7 @@ def InputField(
|
|
|
63
64
|
min_length: Optional[int] = None,
|
|
64
65
|
max_length: Optional[int] = None,
|
|
65
66
|
choices: Optional[List[Any]] = None,
|
|
67
|
+
moderate: bool = True,
|
|
66
68
|
) -> Any:
|
|
67
69
|
"""Declare a default value and validation constraints for a field.
|
|
68
70
|
|
|
@@ -81,6 +83,13 @@ def InputField(
|
|
|
81
83
|
min_length: Minimum length for string/sequence values.
|
|
82
84
|
max_length: Maximum length for string/sequence values.
|
|
83
85
|
choices: Exhaustive list of allowed values.
|
|
86
|
+
moderate: Whether to submit this field's value to the content
|
|
87
|
+
moderation backend (when moderation is enabled platform-wide).
|
|
88
|
+
Defaults to ``True``. Only effective for free-text ``str``
|
|
89
|
+
fields (those without ``choices=``) and ``UploadedFile``
|
|
90
|
+
fields — typed, enum, and numeric fields are never moderated
|
|
91
|
+
because the schema validator rejects out-of-set payloads
|
|
92
|
+
before they reach the model.
|
|
84
93
|
"""
|
|
85
94
|
if default_factory is not None:
|
|
86
95
|
raise TypeError(
|
|
@@ -95,6 +104,7 @@ def InputField(
|
|
|
95
104
|
min_length=min_length,
|
|
96
105
|
max_length=max_length,
|
|
97
106
|
choices=choices,
|
|
107
|
+
moderate=moderate,
|
|
98
108
|
)
|
|
99
109
|
|
|
100
110
|
|
|
@@ -227,3 +237,5 @@ def field_info_to_json_schema(schema: Dict[str, Any], info: FieldInfo) -> None:
|
|
|
227
237
|
schema["maxLength"] = info.max_length
|
|
228
238
|
if info.choices is not None:
|
|
229
239
|
schema["enum"] = info.choices
|
|
240
|
+
if not info.moderate:
|
|
241
|
+
schema["x-reactor-moderate"] = False
|
|
@@ -31,6 +31,7 @@ class ModelEvent(Enum):
|
|
|
31
31
|
CLEANUP_COMPLETE = "cleanup_complete"
|
|
32
32
|
EVICTION = "eviction"
|
|
33
33
|
IDLING = "idling"
|
|
34
|
+
SESSION_ACTIVE = "session_active"
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
class ModelStateMachine:
|
|
@@ -72,6 +73,15 @@ class ModelStateMachine:
|
|
|
72
73
|
ModelEvent.IDLING: [
|
|
73
74
|
(ModelState.READY, ModelState.READY),
|
|
74
75
|
],
|
|
76
|
+
# SESSION_ACTIVE is the analog of IDLING during a live session: a
|
|
77
|
+
# periodic liveness ping sent while the runtime is serving a
|
|
78
|
+
# session (WAITING / STREAMING / ORPHANED). All three transitions
|
|
79
|
+
# are self-loops since the event carries no state change.
|
|
80
|
+
ModelEvent.SESSION_ACTIVE: [
|
|
81
|
+
(ModelState.WAITING, ModelState.WAITING),
|
|
82
|
+
(ModelState.STREAMING, ModelState.STREAMING),
|
|
83
|
+
(ModelState.ORPHANED, ModelState.ORPHANED),
|
|
84
|
+
],
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
def __init__(self, initial_state: ModelState = ModelState.CREATED):
|
|
@@ -98,7 +108,10 @@ class ModelStateMachine:
|
|
|
98
108
|
|
|
99
109
|
if to_state is None:
|
|
100
110
|
log_fn = logger.warning
|
|
101
|
-
|
|
111
|
+
# IDLING and SESSION_ACTIVE are high-frequency liveness pings;
|
|
112
|
+
# legitimate races with state transitions can produce rejected
|
|
113
|
+
# events that don't deserve a warning.
|
|
114
|
+
if event in (ModelEvent.IDLING, ModelEvent.SESSION_ACTIVE):
|
|
102
115
|
log_fn = logger.debug
|
|
103
116
|
log_fn(
|
|
104
117
|
"Illegal state transition",
|
|
@@ -108,7 +121,7 @@ class ModelStateMachine:
|
|
|
108
121
|
return False
|
|
109
122
|
|
|
110
123
|
log_fn = logger.info
|
|
111
|
-
if event
|
|
124
|
+
if event in (ModelEvent.IDLING, ModelEvent.SESSION_ACTIVE):
|
|
112
125
|
log_fn = logger.debug
|
|
113
126
|
|
|
114
127
|
log_fn(
|
|
@@ -145,7 +158,18 @@ class ModelStateMachine:
|
|
|
145
158
|
handler(**kwargs)
|
|
146
159
|
|
|
147
160
|
def _call_enter_handler(self, state: ModelState, previous_state: ModelState):
|
|
148
|
-
"""Call the appropriate on_enter_<state> method.
|
|
161
|
+
"""Call the appropriate on_enter_<state> method.
|
|
162
|
+
|
|
163
|
+
Self-loop transitions (``state == previous_state``) skip the
|
|
164
|
+
``on_enter_*`` hook — those hooks are designed to run on actual
|
|
165
|
+
state changes, not on every heartbeat. This matters for
|
|
166
|
+
liveness-ping events like ``IDLING`` and ``SESSION_ACTIVE`` whose
|
|
167
|
+
from/to states are identical: re-running ``on_enter_WAITING`` /
|
|
168
|
+
``on_enter_ORPHANED`` on every tick would, e.g., cancel and
|
|
169
|
+
restart the orphan timeout, preventing it from ever firing.
|
|
170
|
+
"""
|
|
171
|
+
if state == previous_state:
|
|
172
|
+
return
|
|
149
173
|
handler_name = f"on_enter_{state.value}"
|
|
150
174
|
handler = getattr(self, handler_name, None)
|
|
151
175
|
if handler:
|
|
@@ -191,6 +215,9 @@ class ModelStateMachine:
|
|
|
191
215
|
def on_before_idling(self, **kwargs):
|
|
192
216
|
pass
|
|
193
217
|
|
|
218
|
+
def on_before_session_active(self, **kwargs):
|
|
219
|
+
pass
|
|
220
|
+
|
|
194
221
|
# on_enter_<state> methods
|
|
195
222
|
def on_enter_CREATED(self, previous_state: ModelState):
|
|
196
223
|
pass
|