Skip to content

Conversation

@xiaoyu10031
Copy link
Collaborator

@xiaoyu10031 xiaoyu10031 commented Dec 18, 2025

add a virtual printer device
cleanup function return False

Summary by Sourcery

Add a virtual printer debugging device that logs received messages and tracks basic status information.

New Features:

  • Introduce a VirtualPrinter device class that records and prints incoming payloads for debugging.
  • Register the virtual_printer in the device registry with actions for initialization, cleanup, post-initialization, and printing messages.

Bug Fixes:

  • Ensure the virtual printer cleanup operation updates status to offline while returning a failure indicator.

@sourcery-ai
Copy link

sourcery-ai bot commented Dec 18, 2025

Reviewer's Guide

Implements a new VirtualPrinter virtual device that logs and prints received message payloads, wires it into the device registry with appropriate action schemas and status fields, and ensures the cleanup routine reports failure after transitioning the device to an offline state.

Class diagram for the new VirtualPrinter device

classDiagram
    class BaseROS2DeviceNode

    class VirtualPrinter {
        - BaseROS2DeviceNode _ros_node
        - str device_id
        - dict config
        - Logger logger
        - dict data
        - str port
        - str prefix
        - bool pretty
        + VirtualPrinter(device_id: str, config: dict, kwargs: dict)
        + post_init(ros_node: BaseROS2DeviceNode) void
        + initialize() bool
        + cleanup() bool
        + print_message(content: Any, kwargs: dict) dict
        + receive(args: list, kwargs: dict) dict
        - _record_and_print(action: str, content: Any, kwargs: dict) void
        + status() str
        + message() str
        + last_received() Any
        + received_count() int
    }

    VirtualPrinter --> BaseROS2DeviceNode : uses
Loading

File-Level Changes

Change Details Files
Register a new virtual_printer device type in the device registry with actions and status schema for debugging payloads.
  • Add virtual_printer entry under virtual_device registry including category, description, and python class binding
  • Define action_value_mappings for auto-initialize, auto-cleanup, auto-post_init lifecycle actions using UniLabJsonCommand/Async schemas
  • Expose a print_message action that accepts a content payload and returns success plus a textual return_info
  • Declare status_types and init_param_schema fields so the framework can track last_received, message, received_count, and status
unilabos/registry/devices/virtual_device.yaml
Implement the VirtualPrinter Python device that records, pretty-prints, and logs all received messages, with explicit offline semantics on cleanup.
  • Create VirtualPrinter class with configurable device_id, port, prefix, and pretty-printing options resolved from constructor args/config
  • Initialize internal data structure and provide async initialize() to set Ready/Idle state and counters
  • Implement async cleanup() to set status to Offline and return False to indicate failure/termination semantics
  • Provide async print_message() and receive() methods that forward to a shared _record_and_print helper, returning structured success responses
  • Implement _record_and_print to timestamp, store, and pretty-print payloads, updating device data and logging via logger
  • Expose status, message, last_received, and received_count as read-only properties backed by the internal data dict
unilabos/devices/virtual/virtual_printer.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@xiaoyu10031 xiaoyu10031 marked this pull request as ready for review December 18, 2025 09:06
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • The print_message and receive methods return a message field in their result dicts, but the virtual_printer.print_message action schema only declares success and return_info; consider aligning the return shape with the schema or extending the schema to include message to avoid downstream assumptions breaking.
  • In _record_and_print, the kwargs argument is logged separately but receive currently passes kwargs={} while embedding the original kwargs inside content, which may be confusing for consumers expecting top-level kwargs in the record; consider either passing the real kwargs through or removing the extra kwargs field from the record.
  • Since this is a virtual device used for debugging, it may still be worth standardizing on logging (self.logger) instead of print (or gating print behind a config flag) to keep output behavior consistent with other devices and avoid noisy stdout in some deployments.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `print_message` and `receive` methods return a `message` field in their result dicts, but the `virtual_printer.print_message` action schema only declares `success` and `return_info`; consider aligning the return shape with the schema or extending the schema to include `message` to avoid downstream assumptions breaking.
- In `_record_and_print`, the `kwargs` argument is logged separately but `receive` currently passes `kwargs={}` while embedding the original kwargs inside `content`, which may be confusing for consumers expecting top-level kwargs in the record; consider either passing the real kwargs through or removing the extra `kwargs` field from the record.
- Since this is a virtual device used for debugging, it may still be worth standardizing on logging (`self.logger`) instead of `print` (or gating `print` behind a config flag) to keep output behavior consistent with other devices and avoid noisy stdout in some deployments.

## Individual Comments

### Comment 1
<location> `unilabos/registry/devices/virtual_device.yaml:2549-2558` </location>
<code_context>
+      type: object
+    data:
+      properties:
+        last_received:
+          type: object
+        message:
+          type: string
+        received_count:
+          type: integer
+        status:
+          type: string
+      required:
+      - status
+      - message
+      - received_count
+      - last_received
+      type: object
+  version: 1.0.0
</code_context>

<issue_to_address>
**issue (bug_risk):** `last_received` is declared required and non-nullable in schema but initialized to `None` in code.

In `init_param_schema.data`, `last_received` is required and typed as `object`, but `initialize()` sets it to `None`. This schema/runtime mismatch can break validation or serialization (JSON `object` vs `null`). Please either initialize it as `{}` or update the schema to allow `null` and/or make it optional.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +2549 to +2558
last_received:
type: object
message:
type: string
received_count:
type: integer
status:
type: string
required:
- status
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): last_received is declared required and non-nullable in schema but initialized to None in code.

In init_param_schema.data, last_received is required and typed as object, but initialize() sets it to None. This schema/runtime mismatch can break validation or serialization (JSON object vs null). Please either initialize it as {} or update the schema to allow null and/or make it optional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant