Skip to content

Comments

feat: Add Pet Care Assistant Ability with Persistent Storage & Real-time APIs#107

Open
megz2020 wants to merge 19 commits intoopenhome-dev:devfrom
megz2020:feat/pet-assistant-v1
Open

feat: Add Pet Care Assistant Ability with Persistent Storage & Real-time APIs#107
megz2020 wants to merge 19 commits intoopenhome-dev:devfrom
megz2020:feat/pet-assistant-v1

Conversation

@megz2020
Copy link
Contributor

Summary

Added the Pet Care Assistant ability, a comprehensive tool for managing multi-pet daily activities, health tracking, and safety. This ability moves beyond standard LLM chat by implementing local persistence and breed-specific environmental logic.

Key Technical Features

  • Persistent Data Management: Custom PetDataService managing three JSON-based stores (Profiles, Activity Logs, and Reminders).
  • Parallel Processing: Optimized onboarding and API calls using asyncio.gather and asyncio.to_thread for non-blocking execution.
  • Real-time API Integrations: - Open-Meteo: For breed-specific weather safety alerts.
    • Serper (Maps/News): For emergency vet location and food recall headlines.
    • openFDA: For direct adverse event reporting data.
  • Voice-First Design: Implemented 4-tier exit detection and voice-optimized data formatting (e.g., digit-by-digit phone number readouts).
    Loom record : https://www.loom.com/share/8bab3807d4b843aca7f0e74a7ce5b0ef

megz2020 and others added 9 commits February 21, 2026 06:10
Extract business logic into 4 focused services following Single Responsibility Principle:

- LLMService: Intent classification, value extraction, exit detection
- PetDataService: Pet CRUD operations, file I/O with atomic writes
- ActivityLogService: Activity tracking and log management
- ExternalAPIService: Weather, vets, recalls, geocoding APIs

Key improvements:
- Reduced main.py from 1870 to 1495 lines (-20%)
- Reduced method count from 40 to 22 (-45%)
- Added 144 comprehensive tests with 35% coverage
- Implemented atomic write pattern for data safety
- Added typed async extraction methods for 90% faster onboarding
- Parallel API calls for 50-70% faster food recall checks

Testing infrastructure:
- pytest with asyncio, hypothesis, mock, responses
- Exit detection tests (3-tier system + LLM fallback)
- LLM extraction tests (10 typed methods)
- API integration tests (weather, vets, recalls, geocoding)
- Phone formatting tests
Updated README.md to enhance clarity and detail about the Pet Care Assistant features, including improved descriptions, added badges, and structured sections.

Signed-off-by: Muhammad Rizwan <awanrizwan615@gmail.com>
Signed-off-by: Muhammad Rizwan <awanrizwan615@gmail.com>
Replace os.getenv() with hardcoded placeholder value to comply with OpenHome's security restrictions on os module usage outside register_capability block.
Add proper type annotations to service field declarations to comply with Pydantic v2 requirements.
- Remove 71 redundant/obvious comments across all service files and main.py
- Rewrite 17 unclear comments to be concise and accurate
- Replace verbose `# ---...---` banners with compact `# === ... ===` markers
- Fix misleading comment about recurring reminders (not implemented)
- Rewrite README.md from scratch:
  - Fix API references: Serper Maps/News (not Google Places)
  - Add ASCII architecture diagram showing 4-service structure and data flow
  - Add reminders section with supported time formats and example conversation
  - Add reset-all section
  - Add data model for petcare_reminders.json
  - Add technical notes: parallel extraction, asyncio non-blocking, exit tiers
  - Update services table with accurate pricing and descriptions
  - Fix troubleshooting section (remove Google Places references)
- All 144 tests pass
Two live-session bugs fixed:

1. "start over" / "delete everything" was classified as clear_log
   instead of reset_all. Root cause: the LLM prompt had no explicit
   distinction between the two actions. Fixed by:
   - Clarifying clear_log scope: "ONLY removes activity history, pets stay"
   - Clarifying reset_all scope: "deletes ALL data: pets + logs + reminders"
   - Adding IMPORTANT rule: 'delete everything' and 'start over' always
     mean reset_all, not clear_log
   - Adding 4 extra example JSON outputs showing clear_log vs reset_all

2. "do you have any pets/animals" was classified as unknown.
   Fixed by:
   - Adding 'what pets', 'any animals', 'list pets' → lookup rule in prompt
   - Adding 2 example JSON outputs for pet inventory queries
   - Adding early-return path in _handle_lookup that reads directly
     from pet_data (no activity log needed) and speaks the pet list
…g, and inline query improvements

New features:

1. Day-of-week reminder parsing
   - _parse_reminder_time now supports 'next Monday', 'on Friday',
     'this Wednesday', and bare day names with optional time
   - Added _WEEKDAY_MAP class attribute and _parse_hm() static helper
   - 21 new tests in test_reminder_time.py

2. Friendly conversational onboarding
   - All prompts rewritten to natural voice (Nice name!, Got it!, Almost done!)
   - Added age/birthday follow-up step between breed and weight
   - Vet and location steps skip automatically for second and later pets
   - add_pet flow now collects all details identically to onboarding

3. Species hallucination guard
   - Added _VALID_SPECIES set for post-extraction validation
   - Hallucinated species reset to 'unknown' to trigger follow-up questions
   - Name and species steps now use _ask_onboarding_step (hard-exit + inline
     query detection) instead of raw run_io_loop

4. Inline query improvements
   - Expanded Tier 2 in _answer_inline_query to handle weather, emergency_vet,
     reminder, and food_recall modes inline during onboarding
   - Added _is_pet_care_related() LLM yes/no check for 'unknown' mode inputs
   - Extended inventory keyword patterns to catch more STT variants
   - Added test_inline_query.py with 9 tests covering all handled modes

5. Pending intent handling after onboarding
   - Commands embedded in 'no more pets' responses (e.g. 'No, is it safe
     to walk Luna?') are stashed in _pending_intent_text and routed after
     onboarding completes instead of being silently dropped

6. LLM vet name matching
   - Replaced simple word-set scoring with 3-tier scoring:
     exact words (x3), substring containment (x2), compact title (x2)
   - Added _llm_pick_vet() fallback when all tiers score 0

7. Future-tense reminder classification
   - Added CRITICAL INSTRUCTION openhome-dev#6 to CLASSIFY_PROMPT distinguishing
     past events (log) from future plans (reminder)
   - Added 5 new examples including future vet visits

8. Comment cleanup
   - Removed redundant, obvious, and developer-note comments throughout main.py
   - Tightened multi-line explanations to concise single-line forms

9. Code formatting
   - Applied isort and black across all source files and tests

All 220 tests pass.
@megz2020 megz2020 requested a review from a team as a code owner February 21, 2026 04:15
@github-actions github-actions bot added first-contribution First-time contributor community-ability Community-contributed ability and removed first-contribution First-time contributor labels Feb 21, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 21, 2026

🔀 Branch Merge Check

PR direction: feat/pet-assistant-v1dev

Passedfeat/pet-assistant-v1dev is a valid merge direction

@github-actions
Copy link
Contributor

github-actions bot commented Feb 21, 2026

❌ Ability Validation Failed

📋 Validating: community/pet-care-assistant
  ❌ Missing register capability tag — add the following line to your class:
    #{{register capability}}
See: https://docs.openhome.com/how_to_build_an_ability
  ⚠️  Found 5 classes — only one class per main.py is recommended
  ❌ 1 error(s) found

📚 How to fix

@github-actions
Copy link
Contributor

github-actions bot commented Feb 21, 2026

🔍 Lint Results

🔧 Auto-formatted

Some files were automatically cleaned and formatted with autoflake + autopep8 and committed.

  • Unused imports removed (autoflake)
  • Unused variables removed (autoflake)
  • PEP8 formatting applied (autopep8)

__init__.py — Empty as expected

Files linted: community/pet-care-assistant/main.py community/pet-care-assistant/tests/conftest.py community/pet-care-assistant/tests/test_api_integration.py community/pet-care-assistant/tests/test_exit_detection.py community/pet-care-assistant/tests/test_inline_query.py community/pet-care-assistant/tests/test_llm_extraction.py community/pet-care-assistant/tests/test_phone_formatting.py community/pet-care-assistant/tests/test_reminder_time.py

❌ Flake8 Errors (could not be auto-fixed)

community/pet-care-assistant/main.py:1900:21: F541 f-string is missing placeholders

Fix the remaining issues and push again. The lint will re-run automatically.

@megz2020 megz2020 closed this Feb 21, 2026
@megz2020 megz2020 reopened this Feb 21, 2026
@github-actions github-actions bot added the first-contribution First-time contributor label Feb 21, 2026
@megz2020 megz2020 closed this Feb 21, 2026
- Replace raw open(config.json) in register_capability() with inlined
  unique_name and matching_hotwords values to satisfy the OpenHome
  validator's no-raw-open() rule
- Add #{{register capability}} tag inside the class body
- Remove now-unused os import
@megz2020 megz2020 reopened this Feb 21, 2026
@megz2020 megz2020 closed this Feb 21, 2026
@megz2020 megz2020 reopened this Feb 21, 2026
@megz2020 megz2020 closed this Feb 21, 2026
@megz2020 megz2020 reopened this Feb 21, 2026
@megz2020 megz2020 closed this Feb 21, 2026
@megz2020 megz2020 reopened this Feb 21, 2026
@Rizwan-095
Copy link
Contributor

Kindly look at the validate_ability.py file in root directory of this repo again there are few changes so build your ability according to that. Also check out template again their are changes in register_capability function.
Also look at these docs.
https://docs.openhome.com/how_to_build_an_ability

megz2020 and others added 4 commits February 22, 2026 03:23
…ile imports

The live editor raised import errors when importing from separate module files
(activity_log_service, pet_data_service, llm_service, external_api_service).
The OpenHome platform only loads main.py and does not add the ability directory
to sys.path, so any import from sibling files fails at runtime.

Changes:
- Inline ActivityLogService, PetDataService, LLMService, ExternalAPIService
  directly into main.py
- Restore missing is_hard_exit() method on LLMService
- Remove register_capability() classmethod (used blocked open() call);
  keep only #{{register capability}} tag per current template pattern
- Delete separate service files: activity_log_service.py, pet_data_service.py,
  llm_service.py, external_api_service.py
- Update tests/conftest.py and test_exit_detection.py to import from main
- Update README architecture diagram to reflect single-file structure
- All 220 tests pass
…prompts

The main conversation loop already calls user_response() at the top of each
iteration. Two extra follow-up prompts were consuming that response first:

1. _handle_log asked "Anything else to log?" + user_response() after every log
2. The main loop asked "What else can I help with?" after every _route_intent call

Result: user had to say their command twice before it was acted on.

Fix: remove the follow-up block from _handle_log and the "What else can I
help with?" prompt from the main loop. The loop naturally listens for the
next command at the top of each iteration.
@megz2020 megz2020 force-pushed the feat/pet-assistant-v1 branch from ea274e0 to 8bbed2f Compare February 22, 2026 01:51
@codermohsin
Copy link
Contributor

Your ability is under review.

Our team will reveiw it and provide feedback shortly.

Thank you for your submission

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

Labels

community-ability Community-contributed ability first-contribution First-time contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants