File size: 2,017 Bytes
8c424b3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
"""Tests for the camera tool."""

import base64
from io import BytesIO
from unittest.mock import MagicMock

import numpy as np
import pytest
from PIL import Image

from reachy_mini_conversation_app.tools.camera import Camera
from reachy_mini_conversation_app.tools.core_tools import ToolDependencies


@pytest.mark.asyncio
async def test_camera_tool_preserves_frame_color_for_uploaded_jpeg() -> None:
    """The JPEG uploaded to the model should preserve the intended frame color."""
    camera_worker = MagicMock()
    camera_worker.get_latest_frame.return_value = np.full((32, 32, 3), [0, 0, 255], dtype=np.uint8)

    deps = ToolDependencies(
        reachy_mini=MagicMock(),
        movement_manager=MagicMock(),
        camera_worker=camera_worker,
    )

    result = await Camera()(deps, question="What color is this?")

    assert "b64_im" in result

    jpeg_bytes = base64.b64decode(result["b64_im"])
    decoded = Image.open(BytesIO(jpeg_bytes)).convert("RGB")
    pixel = decoded.getpixel((0, 0))
    assert isinstance(pixel, tuple)
    red, green, blue = pixel

    assert red > 200
    assert green < 40
    assert blue < 40


@pytest.mark.asyncio
async def test_camera_tool_uses_local_vision_processor_when_available() -> None:
    """The camera tool should use on-demand local vision when configured."""
    camera_worker = MagicMock()
    camera_worker.get_latest_frame.return_value = np.zeros((32, 32, 3), dtype=np.uint8)

    vision_processor = MagicMock()
    vision_processor.process_image.return_value = "A red cup on a table."

    deps = ToolDependencies(
        reachy_mini=MagicMock(),
        movement_manager=MagicMock(),
        camera_worker=camera_worker,
        vision_processor=vision_processor,
    )

    result = await Camera()(deps, question="What do you see?")

    assert result == {"image_description": "A red cup on a table."}
    vision_processor.process_image.assert_called_once_with(
        camera_worker.get_latest_frame.return_value,
        "What do you see?",
    )