vrex-flow-engine 0.3.2__tar.gz → 0.3.3__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.
Files changed (42) hide show
  1. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/PKG-INFO +1 -1
  2. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/bridge/flow_client.py +48 -2
  3. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/bridge/flow_rpc.py +32 -0
  4. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/pool.py +3 -0
  5. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/pyproject.toml +1 -1
  6. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/vrex_flow_engine.egg-info/PKG-INFO +1 -1
  7. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/PYPI_README.md +0 -0
  8. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/__init__.py +0 -0
  9. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/bridge/__init__.py +0 -0
  10. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/bridge/flow_sdk.py +0 -0
  11. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/bridge/ws_server.py +0 -0
  12. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/catalog.py +0 -0
  13. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/cli/__init__.py +0 -0
  14. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/cli/app.py +0 -0
  15. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/cli/config.py +0 -0
  16. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/cli/dashboard.py +0 -0
  17. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/cli/health.py +0 -0
  18. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/cli/processes.py +0 -0
  19. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/cli/supervisor.py +0 -0
  20. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/config.py +0 -0
  21. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/ingest.py +0 -0
  22. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/job_store.py +0 -0
  23. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/jobs.py +0 -0
  24. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/main.py +0 -0
  25. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/media.py +0 -0
  26. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/media_store.py +0 -0
  27. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/openai/__init__.py +0 -0
  28. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/openai/_util.py +0 -0
  29. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/openai/images.py +0 -0
  30. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/openai/models.py +0 -0
  31. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/openai/uploads.py +0 -0
  32. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/openai/videos.py +0 -0
  33. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/posthog_client.py +0 -0
  34. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/session.py +0 -0
  35. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/video_context.py +0 -0
  36. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/flow_engine/video_context_store.py +0 -0
  37. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/setup.cfg +0 -0
  38. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/vrex_flow_engine.egg-info/SOURCES.txt +0 -0
  39. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/vrex_flow_engine.egg-info/dependency_links.txt +0 -0
  40. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/vrex_flow_engine.egg-info/entry_points.txt +0 -0
  41. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/vrex_flow_engine.egg-info/requires.txt +0 -0
  42. {vrex_flow_engine-0.3.2 → vrex_flow_engine-0.3.3}/vrex_flow_engine.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vrex-flow-engine
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Launcher + supervisor and OpenAI-compatible image/video generation service (Vrex Flow Engine).
5
5
  Author: Vrex
6
6
  License: Proprietary
@@ -12,8 +12,11 @@ Control flow:
12
12
  separate ``upload_request`` command (resumable upload, not batchexecute).
13
13
  4. That HTTP handler resolves the pending future by id.
14
14
  5. Inbound WS messages (``extension_ready``, ``session_captured``,
15
- ``session_lost``, ``pong``) update per-instance state. A fresh session
16
- triggers an account refresh (credits + paygate tier) through the bridge.
15
+ ``session_lost``, ``rpc_map``, ``pong``) update per-instance state. A fresh
16
+ session triggers an account refresh (credits + paygate tier) through the
17
+ bridge. ``rpc_map`` carries the ``method → rpcId`` table the extension
18
+ rebuilt from Flow's JS bundle; every ``rpc_request`` names its method so
19
+ the extension can substitute a rotated id.
17
20
  """
18
21
  from __future__ import annotations
19
22
 
@@ -61,6 +64,12 @@ class FlowClient:
61
64
  self._paygate_tier: Optional[int] = None
62
65
  self._credits: Optional[int] = None
63
66
  self._plan_code: Optional[int] = None
67
+ # RPC-id discovery pushed by the extension: Flow build label, the
68
+ # method → id map it read from the bundle, and the ids that differ
69
+ # from flow_rpc's constants (empty = everything still matches).
70
+ self._flow_build: Optional[str] = None
71
+ self._rpc_map_size: int = 0
72
+ self._rpc_ids_rotated: dict[str, dict[str, str]] = {}
64
73
  self._request_count = 0
65
74
  self._success_count = 0
66
75
  self._failed_count = 0
@@ -109,6 +118,18 @@ class FlowClient:
109
118
  def session_present(self) -> bool:
110
119
  return self._session_present
111
120
 
121
+ @property
122
+ def flow_build(self) -> Optional[str]:
123
+ return self._flow_build
124
+
125
+ @property
126
+ def rpc_map_size(self) -> int:
127
+ return self._rpc_map_size
128
+
129
+ @property
130
+ def rpc_ids_rotated(self) -> dict[str, dict[str, str]]:
131
+ return dict(self._rpc_ids_rotated)
132
+
112
133
  async def refresh_account(self) -> bool:
113
134
  """Resolve credits + paygate tier via the credits RPC. Returns True when
114
135
  the tier is cached. Runs through the extension, so it needs a live
@@ -153,6 +174,28 @@ class FlowClient:
153
174
  logger.warning("session_lost: %s", data.get("reason"))
154
175
  self._clear_session()
155
176
  return
177
+ if t == "rpc_map":
178
+ self._flow_build = data.get("build") if isinstance(data.get("build"), str) else None
179
+ discovered = data.get("map") if isinstance(data.get("map"), dict) else {}
180
+ self._rpc_map_size = len(discovered)
181
+ rotated: dict[str, dict[str, str]] = {}
182
+ for method, expected in flow_rpc.RPC_ID_BY_METHOD.items():
183
+ actual = discovered.get(method)
184
+ if isinstance(actual, str) and actual and actual != expected:
185
+ rotated[method] = {"expected": expected, "actual": actual}
186
+ self._rpc_ids_rotated = rotated
187
+ if rotated:
188
+ logger.warning(
189
+ "Flow build %s rotated %d rpc id(s); the extension resolves them by "
190
+ "method name, update flow_rpc.py when convenient: %s",
191
+ self._flow_build, len(rotated), rotated,
192
+ )
193
+ else:
194
+ logger.info(
195
+ "rpc_map from Flow build %s: %d methods, all known ids match",
196
+ self._flow_build, self._rpc_map_size,
197
+ )
198
+ return
156
199
  if t == "pong":
157
200
  return
158
201
  # Inbound response (legacy path; production flow uses HTTP callback)
@@ -248,6 +291,9 @@ class FlowClient:
248
291
  ``captcha_path`` is the single-path shorthand).
249
292
  """
250
293
  params: dict[str, Any] = {"rpcId": rpc_id, "payload": payload}
294
+ method = flow_rpc.RPC_METHOD_BY_ID.get(rpc_id)
295
+ if method:
296
+ params["method"] = method
251
297
  if captcha_action:
252
298
  params["captchaAction"] = captcha_action
253
299
  params["captchaPaths"] = captcha_paths or ([captcha_path] if captcha_path else [])
@@ -34,6 +34,38 @@ RPC_GENERATE_VIDEO = RPC_GENERATE_VIDEO_T2V # historical alias
34
34
  RPC_CHECK_MEDIA = "jwpduf"
35
35
  RPC_GET_MEDIA = "as29s"
36
36
 
37
+ # Known ids for methods whose payload has NOT been captured yet (kept so the
38
+ # rotation check covers them and porting them later starts from a known id).
39
+ RPC_GENERATE_VIDEO_EXTEND = "fZytfe"
40
+ RPC_GENERATE_VIDEO_EDIT = "jIps6"
41
+ RPC_GENERATE_VIDEO_UPSAMPLE = "p0UkFb"
42
+
43
+ # Backend method path behind each id, as declared in Flow's JS bundle
44
+ # (``new _.kx("nzlxg", …, "/VideoFxService.GetCredits")``). The ids are Wiz
45
+ # hashes Google may rotate; the method names are the stable anchor. The
46
+ # extension rebuilds ``method → id`` from the live bundle on every build
47
+ # change and resolves calls by method, so the ids here are the fallback.
48
+ RPC_METHOD_BY_ID: dict[str, str] = {
49
+ RPC_LIST_PROJECTS: "FlowService.GetProjects",
50
+ RPC_CREATE_PROJECT: "AiSandbox.CreateProject",
51
+ RPC_PROJECT_INFO: "AiSandbox.GetProject",
52
+ RPC_PROJECT_CONTENTS: "FlowService.GetProjectContents",
53
+ RPC_MODEL_CATALOG: "FlowService.GetModels",
54
+ RPC_ACCOUNT_CREDITS: "VideoFxService.GetCredits",
55
+ RPC_UPLOAD_IMAGE: "FlowService.UploadImage",
56
+ RPC_GENERATE_IMAGE: "FlowService.BatchGenerateImages",
57
+ RPC_GENERATE_VIDEO_T2V: "VideoFxService.BatchAsyncGenerateVideoText",
58
+ RPC_GENERATE_VIDEO_I2V: "VideoFxService.BatchAsyncGenerateVideoStartImage",
59
+ RPC_GENERATE_VIDEO_R2V: "VideoFxService.BatchAsyncGenerateVideoReferenceImages",
60
+ RPC_GENERATE_VIDEO_INTERPOLATION: "VideoFxService.BatchAsyncGenerateVideoStartAndEndImage",
61
+ RPC_GENERATE_VIDEO_EXTEND: "VideoFxService.BatchAsyncGenerateVideoExtendVideo",
62
+ RPC_GENERATE_VIDEO_EDIT: "VideoFxService.BatchAsyncGenerateVideoEditVideo",
63
+ RPC_GENERATE_VIDEO_UPSAMPLE: "VideoFxService.BatchAsyncGenerateVideoUpsampleVideo",
64
+ RPC_CHECK_MEDIA: "VideoFxService.BatchCheckAsyncVideoGenerationStatus",
65
+ RPC_GET_MEDIA: "FlowService.GetMedia",
66
+ }
67
+ RPC_ID_BY_METHOD: dict[str, str] = {m: i for i, m in RPC_METHOD_BY_ID.items()}
68
+
37
69
  # Video upload is NOT a batchexecute call: a cookie-authenticated resumable
38
70
  # upload (``x-goog-upload-*`` headers) against this path, project id appended.
39
71
  UPLOAD_VIDEO_PATH = "/upload/v1/flow/upload/video/{project_id}"
@@ -128,6 +128,9 @@ class PoolRegistry:
128
128
  "email": (inst.client.user_info or {}).get("email"),
129
129
  "paygate_tier": inst.client.paygate_tier,
130
130
  "credits": inst.client.credits,
131
+ "flow_build": inst.client.flow_build,
132
+ "rpc_map_size": inst.client.rpc_map_size,
133
+ "rpc_ids_rotated": inst.client.rpc_ids_rotated,
131
134
  "in_flight": inst.in_flight,
132
135
  "capacity": POOL_MAX_CONCURRENCY,
133
136
  }
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "vrex-flow-engine"
3
- version = "0.3.2"
3
+ version = "0.3.3"
4
4
  description = "Launcher + supervisor and OpenAI-compatible image/video generation service (Vrex Flow Engine)."
5
5
  # Neutral public description (the in-repo README.md carries the full internal docs).
6
6
  readme = "PYPI_README.md"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vrex-flow-engine
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Launcher + supervisor and OpenAI-compatible image/video generation service (Vrex Flow Engine).
5
5
  Author: Vrex
6
6
  License: Proprietary