Alina commited on
Commit
2ec0a9c
·
unverified ·
2 Parent(s): 6a4b7f3 5af2aa7

Merge pull request #65 from pollen-robotics/64-fix-the-format-timestamp-function

Browse files
.github/workflows/tests.yml CHANGED
@@ -5,6 +5,7 @@ on:
5
 
6
  permissions:
7
  contents: read
 
8
 
9
  concurrency:
10
  group: ${{ github.workflow }}-${{ github.ref }}
@@ -20,6 +21,11 @@ jobs:
20
  matrix:
21
  python-version: ["3.12"]
22
 
 
 
 
 
 
23
  steps:
24
  - uses: actions/checkout@v4
25
 
@@ -29,11 +35,40 @@ jobs:
29
 
30
  - uses: astral-sh/setup-uv@v5
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  - name: Install (locked)
33
- env:
34
- GIT_LFS_SKIP_SMUDGE: "1"
35
  run: |
36
  uv sync --frozen --group dev --extra all_vision
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  - name: Run tests
39
  run: uv run pytest -q
 
5
 
6
  permissions:
7
  contents: read
8
+ actions: write
9
 
10
  concurrency:
11
  group: ${{ github.workflow }}-${{ github.ref }}
 
21
  matrix:
22
  python-version: ["3.12"]
23
 
24
+ env:
25
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
26
+ HF_HUB_ETAG_TIMEOUT: "120"
27
+ HF_HUB_DOWNLOAD_TIMEOUT: "120"
28
+
29
  steps:
30
  - uses: actions/checkout@v4
31
 
 
35
 
36
  - uses: astral-sh/setup-uv@v5
37
 
38
+ - name: Set HF_HOME
39
+ shell: bash
40
+ run: |
41
+ echo "HF_HOME=${RUNNER_TEMP}/.hf" >> "$GITHUB_ENV"
42
+ mkdir -p "${RUNNER_TEMP}/.hf"
43
+
44
+ - name: Cache Hugging Face hub
45
+ uses: actions/cache@v4
46
+ with:
47
+ path: ${{ runner.temp }}/.hf
48
+ key: hf-${{ runner.os }}-${{ hashFiles('uv.lock', 'pyproject.toml') }}
49
+ restore-keys: hf-${{ runner.os }}-
50
+
51
+ # test-only .env file
52
+ - name: Create test .env
53
+ run: |
54
+ printf "OPENAI_API_KEY=test-dummy\n" > .env
55
+
56
  - name: Install (locked)
 
 
57
  run: |
58
  uv sync --frozen --group dev --extra all_vision
59
 
60
+ # Prefetch HF dataset to avoid download during test collection
61
+ - name: Prefetch HF dataset
62
+ run: |
63
+ uv run python - <<'PY'
64
+ from huggingface_hub import snapshot_download
65
+ snapshot_download(
66
+ repo_id="pollen-robotics/reachy-mini-emotions-library",
67
+ repo_type="dataset",
68
+ etag_timeout=120,
69
+ max_workers=4
70
+ )
71
+ PY
72
+
73
  - name: Run tests
74
  run: uv run pytest -q
src/reachy_mini_conversation_demo/openai_realtime.py CHANGED
@@ -239,14 +239,12 @@ class OpenaiRealtimeHandler(AsyncStreamHandler):
239
  self.connection = None
240
 
241
  def format_timestamp(self) -> str:
242
- """Format current timestamp with date, time and elapsed seconds."""
243
- current_time = asyncio.get_event_loop().time()
244
- elapsed_seconds = current_time - self.start_time
245
- dt = datetime.fromtimestamp(current_time)
246
  return f"[{dt.strftime('%Y-%m-%d %H:%M:%S')} | +{elapsed_seconds:.1f}s]"
247
 
248
-
249
-
250
  async def send_idle_signal(self, idle_duration: float) -> None:
251
  """Send an idle signal to the openai server."""
252
  logger.debug("Sending idle signal")
 
239
  self.connection = None
240
 
241
  def format_timestamp(self) -> str:
242
+ """Format current timestamp with date, time, and elapsed seconds."""
243
+ loop_time = asyncio.get_event_loop().time() # monotonic
244
+ elapsed_seconds = loop_time - self.start_time
245
+ dt = datetime.now() # wall-clock
246
  return f"[{dt.strftime('%Y-%m-%d %H:%M:%S')} | +{elapsed_seconds:.1f}s]"
247
 
 
 
248
  async def send_idle_signal(self, idle_duration: float) -> None:
249
  """Send an idle signal to the openai server."""
250
  logger.debug("Sending idle signal")
tests/test_openai_realtime.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ from datetime import datetime, timezone
3
+ from unittest.mock import MagicMock
4
+
5
+ from reachy_mini_conversation_demo.tools import ToolDependencies
6
+ from reachy_mini_conversation_demo.openai_realtime import OpenaiRealtimeHandler
7
+
8
+
9
+ def _build_handler(loop: asyncio.AbstractEventLoop) -> OpenaiRealtimeHandler:
10
+ asyncio.set_event_loop(loop)
11
+ deps = ToolDependencies(reachy_mini=MagicMock(), movement_manager=MagicMock())
12
+ return OpenaiRealtimeHandler(deps)
13
+
14
+
15
+ def test_format_timestamp_uses_wall_clock() -> None:
16
+ """Test that format_timestamp uses wall clock time."""
17
+ loop = asyncio.new_event_loop()
18
+ try:
19
+ print("Testing format_timestamp...")
20
+ handler = _build_handler(loop)
21
+ formatted = handler.format_timestamp()
22
+ print(f"Formatted timestamp: {formatted}")
23
+ finally:
24
+ asyncio.set_event_loop(None)
25
+ loop.close()
26
+
27
+ # Extract year from "[YYYY-MM-DD ...]"
28
+ year = int(formatted[1:5])
29
+ assert year == datetime.now(timezone.utc).year