Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.openhome.com/llms.txt

Use this file to discover all available pages before exploring further.

Thanks for wanting to contribute! This guide walks you from idea to merged PR. If you’re building great abilities with real, high-impact use cases, also check out What Makes a Good Ability.

Source on GitHub

The canonical CONTRIBUTING.md in the abilities repo. This page mirrors it — refer to the GitHub copy if anything looks out of date.

The Two-Minute Version

  1. Fork the openhome-dev/abilities repo
  2. Copy templates/basic-template/ to community/your-ability-name/
  3. Build your ability (edit main.py) and write a README.md
  4. Test it in the OpenHome Live Editor
  5. Open a Pull Request against dev
That’s it — maintainers will review and merge.

Branching & Merging Strategy

We use a simplified Git Flow. All contributions follow this flow:
ability/your-ability-name  →  dev  →  main
BranchPurposeWho merges
mainStable, production-ready. Always deployable.Maintainers only
devIntegration and testing. All PRs target this.Maintainers after review
ability/*, add-*Your working branch for a single ability/change.You push; maintainers merge to dev
Never open a PR directly to main. All PRs must target dev. PRs targeting main will be closed and you’ll be asked to re-open against dev.

How the Repo Is Organized

official/    ← Maintained by OpenHome. Don't submit PRs here.
community/   ← Your contributions go here.
templates/   ← Starting points. Copy one to get going.
docs/        ← Guides and API reference.
You submit to community/ only. Exceptional community abilities can be promoted to official over time.

Step-by-Step Guide

1. Fork and Clone

git clone https://github.com/YOUR_USERNAME/abilities.git
cd abilities
git remote add upstream https://github.com/OpenHome-dev/abilities.git
git fetch upstream
git checkout dev
git pull upstream dev

2. Create Your Ability Branch

Branch off dev — not main:
git checkout -b add-your-ability-name dev
Use a descriptive branch name like add-dad-jokes, add-pomodoro-timer, or fix-weather-error-handling.

3. Pick a Template

TemplateUse when
templates/basic-template/Simple ask → respond → done
templates/api-template/You’re calling an external API
templates/loop-template/Interactive / multi-turn conversation
cp -r templates/basic-template community/your-ability-name

4. Build Your Ability

Edit main.py. Every ability must:
  • Extend MatchingCapability
  • Have register_capability() (copy the boilerplate exactly from the template)
  • Have call() that sets up worker + capability_worker and launches async logic
  • Call self.capability_worker.resume_normal_flow() on every exit path
  • Handle errors with try/except
  • Use self.worker.editor_logging_handler for logging (never print())
Trigger words are configured in the OpenHome dashboard, not in code. The register_capability boilerplate reads a platform-managed config.json at runtime — you never create or edit that file.

Blocked Imports & Keywords

BlockedWhyUse instead
print()Bypasses structured loggingself.worker.editor_logging_handler
open() (raw)Unmanaged filesystem accessself.capability_worker.read_file() / write_file()
redisDirect datastore couplingPlatform-provided helpers
user_configCan leak/mutate global stateCapabilityWorker / worker APIs
exec()Insecure dynamic code executionNot allowed
pickle/dill/shelve/marshalInsecure deserializationNot allowed
Full list → Blocked Imports and Keywords.

5. Write Your README

Create community/your-ability-name/README.md using this format:
# Your Ability Name

![Community](https://img.shields.io/badge/OpenHome-Community-orange?style=flat-square)
![Author](https://img.shields.io/badge/Author-@yourusername-lightgrey?style=flat-square)

## What It Does
One or two sentences explaining what this ability does.

## Suggested Trigger Words
- "trigger phrase one"
- "another trigger"

## Setup
- Any API keys needed and where to get them
- Any other setup steps

## How It Works
Brief description of the conversation flow.

## Example Conversation
> **User:** "trigger phrase one"
> **AI:** "Response example..."

6. Test It

  • Zip your ability folder
  • Go to app.openhome.com → Abilities → Add Custom Ability
  • Upload and test in the Live Editor
  • Set trigger words in the dashboard
  • Make sure all exit paths work (say “stop”, “exit”, etc.)

7. Sync with dev Before Submitting

git fetch upstream
git rebase upstream/dev
Or use merge if you prefer:
git fetch upstream
git merge upstream/dev

8. Submit Your PR

git add community/your-ability-name/
git commit -m "Add your-ability-name community ability"
git push origin add-your-ability-name
Open a Pull Request on GitHub:
  • Base branch: dev (not main)
  • Compare branch: add-your-ability-name
  • Fill out the PR template completely

What Happens After You Open a PR

  1. Automated checks runvalidate-ability, path-check, security-scan, and linting must all pass.
  2. A maintainer reviews — typically within 3–5 business days.
  3. Feedback round — push additional commits to the same branch; the PR updates automatically.
  4. Merge to dev — once approved, a maintainer squash-merges your PR into dev.
  5. Promotion to main — periodically, maintainers validate dev and merge it into main. Your ability becomes available on the Marketplace at that point.

Review Checklist

Must Pass (Hard Requirements)

  • PR targets the dev branch (not main)
  • Files are in community/your-ability-name/ (not in official/)
  • main.py follows the SDK pattern (extends MatchingCapability, has register_capability + call)
  • README.md is present with description, suggested trigger words, and setup instructions
  • resume_normal_flow() is called on every exit path
  • No print() statements (use editor_logging_handler)
  • No blocked imports (redis, user_config, open())
  • No asyncio.sleep() or asyncio.create_task() (use session_tasks helpers)
  • No hardcoded API keys (use "YOUR_API_KEY_HERE" placeholders)
  • Error handling on all API calls and external operations

Nice to Have

  • Spoken responses are short and natural (this is voice, not text)
  • Exit/stop handling in any looping ability
  • Inline comments explaining non-obvious logic

What NOT to Do

Don’tDo instead
Open a PR to mainTarget dev — always
Branch off mainBranch off dev
Submit to official/Submit to community/
Use print()Use self.worker.editor_logging_handler.info()
Use asyncio.sleep()Use self.worker.session_tasks.sleep()
Use asyncio.create_task()Use self.worker.session_tasks.create()
Hardcode API keysUse placeholders + document in README
Forget resume_normal_flow()Call it on every exit path
Write long spoken responsesKeep it short — 1-2 sentences per speak() call
Push directly to dev or mainPush to your ability branch, open a PR

Promotion Path

Community abilities that stand out can be promoted to Official status:
CriteriaThreshold
Marketplace installs50+
StabilityNo critical bugs for 30+ days
Code qualityClean, follows SDK patterns
Author responsivenessResponds to issues
UsefulnessFills a real gap
When promoted, the ability moves from community/ to official/, gets the Official badge on Marketplace, and OpenHome takes over maintenance (author stays credited).

Getting Help

Discord

Ask questions and share works-in-progress with the community.

Report a Bug

Found a bug in an ability? Open an issue.

Suggest an Ability

Vote on and suggest new ability ideas in Discussions.

SDK Reference

Full SDK docs for ability authors.

License

By submitting a PR, you agree that your contribution is licensed under the MIT License. Original authorship is always credited in your ability’s README and in CONTRIBUTORS.md.