feat: Add Pet Care Assistant Ability with Persistent Storage & Real-time APIs#107
feat: Add Pet Care Assistant Ability with Persistent Storage & Real-time APIs#107megz2020 wants to merge 19 commits intoopenhome-dev:devfrom
Conversation
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.
🔀 Branch Merge CheckPR direction: ✅ Passed — |
❌ Ability Validation Failed📚 How to fix
|
🔍 Lint Results🔧 Auto-formattedSome files were automatically cleaned and formatted with
✅
|
- 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
|
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. |
…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.
ea274e0 to
8bbed2f
Compare
|
Your ability is under review. Our team will reveiw it and provide feedback shortly. Thank you for your submission |
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
PetDataServicemanaging three JSON-based stores (Profiles, Activity Logs, and Reminders).asyncio.gatherandasyncio.to_threadfor non-blocking execution.Loom record : https://www.loom.com/share/8bab3807d4b843aca7f0e74a7ce5b0ef