Skip to content

perf: reuse session during converse matching - #846

Open
goldyfruit wants to merge 3 commits into
OpenVoiceOS:devfrom
goldyfruit:perf/reuse-converse-session
Open

perf: reuse session during converse matching#846
goldyfruit wants to merge 3 commits into
OpenVoiceOS:devfrom
goldyfruit:perf/reuse-converse-session

Conversation

@goldyfruit

@goldyfruit goldyfruit commented Aug 7, 2026

Copy link
Copy Markdown

Summary

  • reuse the already-folded live Session throughout one converse matcher call
  • avoid repeated deserialization, singleton-registry locking, and last-writer-wins refolds of the same message snapshot
  • keep direct helper callers backward compatible while ensuring timeout filtering survives until skill polling

Architecture

This is an internal state-reuse refactor. It does not skip converse, reorder intent pipelines, change message topics, alter public protocol behavior, or add traffic-manipulation hooks. A message snapshot is folded into the canonical live Session once; every stage in that matcher invocation then uses that same object.

Besides the latency reduction, this preserves timeout filtering. Previously, a later SessionManager.get(message) could refold the original wire snapshot after an expired skill had been removed, restoring stale state before polling.

Canary evidence

The exact-source 32-process canary compared three 400-client runs before and after this head. Every run delivered 400/400 semantically verified skill replies; persona and LLM escalation were disabled.

Stable observations (discarding the first post-rollout noisy run from both versions):

Stage Before After Change
converse prepare mean 49.7-50.3 ms 34.2-35.0 ms about 31% lower
converse poll mean 102.6-107.8 ms 53.0-55.6 ms about 49% lower
total converse mean 152.5-158.3 ms 87.4-90.7 ms about 43% lower
skill selection mean 291-302 ms 238-245 ms about 18% lower
end-to-end mean 1.54-1.58 s 1.49-1.51 s about 4% lower
end-to-end p95 2.25-2.39 s 2.23-2.31 s no regression

The canary image is composed only from explicit review heads, publishes SBOM/provenance, and verifies the single-fold source shape at build time.

Validation

  • Ruff passes on the touched files
  • 50 focused converse tests pass
  • regression coverage asserts one fold per matcher call
  • regression coverage asserts an expired skill is not restored before polling
  • official Ovoscope end-to-end check passes
  • all GitHub checks pass on Python 3.10 through 3.14
  • git diff --check passes
  • no CI files changed

A local all-in-one test process reported four order-dependent no-skill subtest failures after 360 passes; the same no-skill file passes in a clean process (2 tests and 4 subtests), and the official isolated Ovoscope job passes. This is retained here for transparent reproducibility rather than attributed to this change.

Summary by CodeRabbit

  • Bug Fixes

    • Improved conversation handling for more consistent skill matching.
    • Prevented expired skills from being selected or triggering converse events.
    • Reduced unnecessary session loading during conversation processing.
    • Improved synchronization of active conversation state across requests.
  • Tests

    • Added coverage for session reuse, expired-skill filtering, and compatibility with existing session formats.
    • Verified that expired skills are removed from conversation context before processing.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 188eb927-2e16-42d3-8f2d-5f49d53cd50d

📥 Commits

Reviewing files that changed from the base of the PR and between 9d35397 and 3c846f6.

📒 Files selected for processing (2)
  • ovos_core/intent_services/converse_service.py
  • test/unittests/test_converse_service.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/unittests/test_converse_service.py
  • ovos_core/intent_services/converse_service.py

📝 Walkthrough

Walkthrough

Converse state now uses Session.active_handlers dictionaries. match reuses one loaded session for response-mode selection, timeout filtering, and converse-skill collection. Tests cover handler expiration and session lookup reuse.

Changes

Converse session reuse

Layer / File(s) Summary
Active handler state
ovos_core/intent_services/converse_service.py, test/unittests/test_converse_service.py
Active-skill access and timeout tests now use handler dictionaries with skill_id and activated_at fields. Compatibility tests cover tuple reads and lossless writes.
Session-aware converse helpers
ovos_core/intent_services/converse_service.py
_collect_converse_skills and _check_converse_timeout accept an optional session and retain message-based lookup when no session is provided.
Match pipeline session reuse
ovos_core/intent_services/converse_service.py, test/unittests/test_converse_service.py
match reuses its loaded session for response-mode skill selection, timeout filtering, and converse-skill collection. Tests verify one session lookup and expired-handler removal before polling.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Match
  participant Session
  participant TimeoutCheck
  participant SkillCollector
  participant ConverseBus
  Match->>Session: load session once
  Match->>TimeoutCheck: filter active handlers using session
  Match->>SkillCollector: collect converse skills using session
  SkillCollector->>ConverseBus: poll converse candidates
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: reusing the session during converse matching.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@goldyfruit
goldyfruit marked this pull request as ready for review August 8, 2026 00:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ovos_core/intent_services/converse_service.py`:
- Around line 348-352: Update the _check_converse_timeout call path so the
filtered live session is serialized back into message.context["session"] before
message.forward() emits converse pings. Ensure _handle_activate cannot re-fold
the original snapshot and restore expired handlers, while preserving the
existing filtering in session.active_handlers and downstream
_collect_converse_skills behavior.
- Around line 100-109: Update the active_skills property getter to return
immutable (skill_id, activated_at) tuples, and change its setter to rebuild
session.active_handlers directly from the supplied tuples without calling
Session.activate_skill. Preserve each original activated_at value and the input
ordering exactly.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: adc95211-cb01-47ab-a4c7-d36602841fa1

📥 Commits

Reviewing files that changed from the base of the PR and between 005ab65 and 9d35397.

📒 Files selected for processing (2)
  • ovos_core/intent_services/converse_service.py
  • test/unittests/test_converse_service.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/unittests/test_converse_service.py

Comment thread ovos_core/intent_services/converse_service.py Outdated
Comment thread ovos_core/intent_services/converse_service.py
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