Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a toggleable "Log Messages" setting: frontend UI toggle, new API call to update OSC settings, backend settings endpoint and model, and OSC server flag/property that controls logging and appears in status responses. Changes
Sequence DiagramsequenceDiagram
participant User
participant UI
participant API
participant Server
participant OSC
User->>UI: toggle "Log Messages"
UI->>API: updateOscSettings({log_all_messages: true/false})
API->>Server: PUT /api/v1/osc/settings
Server->>OSC: set log_all_messages property
OSC-->>Server: return updated status (includes log_all_messages)
Server-->>API: 200 OK with status
API-->>UI: resolve with OscStatusResponse
UI->>UI: update optimistic status / handle errors
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/scope/server/osc_server.py (1)
125-130: Consider sampling unknown-message logs.A misconfigured OSC sender can hit this branch at message rate, and each event is now written at
INFOto both console and rotating file logs. A simple per-address rate limit or summary counter would make the new default much safer operationally.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/scope/server/osc_server.py` around lines 125 - 130, The current logger.info call for unknown OSC messages (the branch where path_info is None using logger.info with address and value) can flood logs; implement a sampling/rate-limit or summary counter keyed by address to reduce spam: add a small in-memory map (e.g., unknown_msg_counters or last_logged_timestamps) updated in the message handler that either logs only every Nth event per address or only once per time window, and increment an aggregated counter for suppressed events so you can periodically emit a summary log (e.g., "OSC UNKNOWN x occurrences for %s, last value=%r"). Update the branch that checks path_info is None to consult this map before calling logger.info and to increment the suppression counter instead of logging every event.frontend/src/lib/api.ts (1)
946-965: Return the server-confirmed OSC status from this helper.
PUT /api/v1/osc/settingsalready returnssrv.status(), but this helper drops that payload and forcesOscTab.tsxto re-create the state update locally. Returning a typed response would keep the frontend aligned with the backend contract and remove one partial state copy.♻️ Suggested refactor
export interface OscSettingsRequest { log_all_messages: boolean; } +export interface OscStatusResponse { + enabled: boolean; + listening: boolean; + port: number | null; + host: string | null; + log_all_messages: boolean; +} + export const updateOscSettings = async ( settings: OscSettingsRequest -): Promise<void> => { +): Promise<OscStatusResponse> => { const response = await fetch("/api/v1/osc/settings", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(settings), }); @@ if (!response.ok) { const errorText = await response.text(); throw new Error( `Update OSC settings failed: ${response.status} ${response.statusText}: ${errorText}` ); } + + return response.json(); };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/src/lib/api.ts` around lines 946 - 965, The updateOscSettings helper currently ignores the server response; modify updateOscSettings (which accepts OscSettingsRequest) to parse and return the typed server payload (the srv.status() object returned by PUT /api/v1/osc/settings) instead of void so callers like OscTab.tsx can use the server-confirmed status; keep the same error handling (throw on !response.ok) but after validating response.ok call await response.json(), validate/shape it to the expected status type, and return that parsed object to callers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@frontend/src/components/settings/OscTab.tsx`:
- Around line 104-105: The UI label in OscTab.tsx currently shows "Unknown only"
when status?.log_all_messages is false but the backend still logs
malformed/invalid OSC — update the off-state label in the JSX (near the span
using status?.log_all_messages) to accurately reflect behavior (e.g., "Unknown
and malformed" or "Unknown & invalid") so users understand malformed/invalid
messages are also logged when log_all_messages is off.
---
Nitpick comments:
In `@frontend/src/lib/api.ts`:
- Around line 946-965: The updateOscSettings helper currently ignores the server
response; modify updateOscSettings (which accepts OscSettingsRequest) to parse
and return the typed server payload (the srv.status() object returned by PUT
/api/v1/osc/settings) instead of void so callers like OscTab.tsx can use the
server-confirmed status; keep the same error handling (throw on !response.ok)
but after validating response.ok call await response.json(), validate/shape it
to the expected status type, and return that parsed object to callers.
In `@src/scope/server/osc_server.py`:
- Around line 125-130: The current logger.info call for unknown OSC messages
(the branch where path_info is None using logger.info with address and value)
can flood logs; implement a sampling/rate-limit or summary counter keyed by
address to reduce spam: add a small in-memory map (e.g., unknown_msg_counters or
last_logged_timestamps) updated in the message handler that either logs only
every Nth event per address or only once per time window, and increment an
aggregated counter for suppressed events so you can periodically emit a summary
log (e.g., "OSC UNKNOWN x occurrences for %s, last value=%r"). Update the branch
that checks path_info is None to consult this map before calling logger.info and
to increment the suppression counter instead of logging every event.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 164939d7-a8af-4341-af4f-98faaf8fe840
📒 Files selected for processing (4)
frontend/src/components/settings/OscTab.tsxfrontend/src/lib/api.tssrc/scope/server/app.pysrc/scope/server/osc_server.py
🚀 fal.ai Preview Deployment
TestingConnect to this preview deployment by running this on your branch: 🧪 E2E tests will run automatically against this deployment. |
✅ E2E Tests passed
Test ArtifactsCheck the workflow run for screenshots. |
Signed-off-by: Thom Shutt <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/scope/server/app.py (1)
675-703: Give the new OSC payload a response model.Both endpoints now define a shared frontend/backend contract, but they still return raw dicts. A small
OscStatusResponsemodel here would make FastAPI validatelog_all_messages/host/portand keep the OpenAPI schema in sync withsrc/scope/server/osc_server.py::status().♻️ Possible shape
+class OscStatusResponse(BaseModel): + enabled: bool + listening: bool + port: int | None + host: str | None + log_all_messages: bool + -@app.get("/api/v1/osc/status") +@app.get("/api/v1/osc/status", response_model=OscStatusResponse) async def osc_status(): ... -@app.put("/api/v1/osc/settings") +@app.put("/api/v1/osc/settings", response_model=OscStatusResponse) async def update_osc_settings(request: OscSettingsRequest): ...🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/scope/server/app.py` around lines 675 - 703, Add a FastAPI response model for the OSC status and use it on both endpoints: define a Pydantic model named OscStatusResponse matching the keys returned by get_osc_server().status() (enabled: bool, listening: bool, port: Optional[int], host: Optional[str], log_all_messages: bool), then annotate the osc_status() and update_osc_settings() route handlers with response_model=OscStatusResponse; continue to use get_osc_server() and srv.status() as the source of values but let FastAPI validate/serialize via the new OscStatusResponse model.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/scope/server/osc_server.py`:
- Around line 125-130: When path_info is None, avoid logging every frame by
introducing a small in-memory rate-limit/dedupe cache keyed by address (e.g.,
unknown_path_cache[address] = {count, last_logged_ts}); on first hit log as now
via logger.info, on subsequent hits within a suppression window (e.g., 30–60s
using time.monotonic()) increment count but skip writing the log, and when the
window expires log again including the number of suppressed repeats (and reset
count/last_logged_ts). Update the branch around path_info, address, value, and
logger.info to consult this cache, use thread-safe access if this handler can be
called from multiple threads (e.g., a simple lock), and include the
suppressed-count summary in the periodic log entry so repeated unknown-path
messages are collapsed rather than persisted each frame.
---
Nitpick comments:
In `@src/scope/server/app.py`:
- Around line 675-703: Add a FastAPI response model for the OSC status and use
it on both endpoints: define a Pydantic model named OscStatusResponse matching
the keys returned by get_osc_server().status() (enabled: bool, listening: bool,
port: Optional[int], host: Optional[str], log_all_messages: bool), then annotate
the osc_status() and update_osc_settings() route handlers with
response_model=OscStatusResponse; continue to use get_osc_server() and
srv.status() as the source of values but let FastAPI validate/serialize via the
new OscStatusResponse model.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 222d3d9e-275a-41ed-bded-ce04d9e475d8
📒 Files selected for processing (4)
frontend/src/components/settings/OscTab.tsxfrontend/src/lib/api.tssrc/scope/server/app.pysrc/scope/server/osc_server.py
🚧 Files skipped from review as they are similar to previous changes (1)
- frontend/src/components/settings/OscTab.tsx
| if path_info is None: | ||
| logger.info( | ||
| "OSC INVALID %s = %r reason=unknown path", | ||
| "OSC UNKNOWN %s = %r", | ||
| address, | ||
| value, | ||
| ) |
There was a problem hiding this comment.
Rate-limit unknown-path logging.
A broken sender can hit this branch at frame rate, and every INFO line is persisted by the rotating file handler in src/scope/server/app.py. That will churn the 5×5MB logs fast and bury the useful first failure. Please dedupe or rate-limit these entries per address, then emit a periodic summary of suppressed repeats.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/scope/server/osc_server.py` around lines 125 - 130, When path_info is
None, avoid logging every frame by introducing a small in-memory
rate-limit/dedupe cache keyed by address (e.g., unknown_path_cache[address] =
{count, last_logged_ts}); on first hit log as now via logger.info, on subsequent
hits within a suppression window (e.g., 30–60s using time.monotonic()) increment
count but skip writing the log, and when the window expires log again including
the number of suppressed repeats (and reset count/last_logged_ts). Update the
branch around path_info, address, value, and logger.info to consult this cache,
use thread-safe access if this handler can be called from multiple threads
(e.g., a simple lock), and include the suppressed-count summary in the periodic
log entry so repeated unknown-path messages are collapsed rather than persisted
each frame.
Instead of optimistically updating local state (which was not reverted on error), use the status response returned by PUT /api/v1/osc/settings to set the UI state. Also deduplicate the OscStatus interface into a shared OscStatusResponse type in api.ts. Co-Authored-By: Claude Opus 4.6 <[email protected]> Signed-off-by: Rafał Leszko <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]> Signed-off-by: Rafał Leszko <[email protected]>
leszko
left a comment
There was a problem hiding this comment.
Pushed some nit improvements. Other than that LGTM. Merging.
It now logs unrecognised messages by default (since this is a user error) and has a switch to enable logging of all messages for debugging an integration
Summary by CodeRabbit