Skip to content

feat: add shared node.invoke_native helper - #568

Merged
NeonDaniel merged 3 commits into
NeonGeckoCom:devfrom
OscillateLabsLLC:FEAT_NodeInvokeNativeHelper
Sep 9, 2026
Merged

NeonDaniel merged 3 commits into
NeonGeckoCom:devfrom
OscillateLabsLLC:FEAT_NodeInvokeNativeHelper

Conversation

@mikejgray

@mikejgray mikejgray commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds invoke_native_action, a shared helper for Node native actions. Any NeonSkill can call it from an if node: branch.

The helper does four things:

  1. Checks the Node's advertised capabilities. If the action is not supported, it speaks a message and stops.
  2. Registers a response handler, then sends the node.invoke_native request and waits for a reply matching the same action and session. The handler is removed once the wait ends.
  3. Applies two settings: confirm_on_success (silent by default) and per_action_timeouts (per-action override, fractional seconds allowed).
  4. Speaks the result through the calling skill's dialog files. There is no built-in fallback text: a skill that uses this helper must ship native_action_not_supported, native_action_success, native_action_timeout and native_action_error dialogs, plus one <NodeNativeAction value>.dialog (e.g. launch_camera_app.dialog) per action it invokes, holding the spoken name passed to the dialogs as {description}. The module docstring lists the keys and template variables. A missing file gets the standard OVOS behavior of speaking the key.

Test plan

  • 24 unit tests pass. Every test drives a FakeBus that replies from inside the invoke emit, so a response that arrives before emit() returns is exercised on every path. The earlier subscribe-after-emit implementation timed out on that case.
  • End-to-end test against a live Hub, using skill-launcher's node branch: pass on the initial revision. See feat: add node branch for bare app-launch requests skill-launcher#54 for the transcript. skill-launcher and skill-messaging need the dialog files above before they pick up this release.

CI note

Two unit_tests jobs previously failed on tests/hana_util_tests.py with a 504 from hana.neonaibeta.com. This is a live network call to an external server, unrelated to this PR.

@NeonDaniel NeonDaniel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Left some feedback on native_actions implementation. I think this generally makes sens, just a few details to work through

Comment thread neon_utils/native_actions.py Outdated
error_message: str = ""


def invoke_native_action(skill, message: Message, action: NodeNativeAction,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can skill be annotated as an OVOSSkill? NeonSkill extends, so should be a safe annotation unless there is some import edge case you're trying to avoid

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No, because there's a message kwarg at play that isn't present in OVOSSkill

Comment thread neon_utils/native_actions.py Outdated
Comment thread neon_utils/native_actions.py Outdated
Comment thread neon_utils/user_utils.py
Capability-gate, emit, await-response, and settings (confirm_on_success,
per_action_timeouts) logic for Node native actions, shared across every
consuming skill's `if node:` branch.
…on names

Address review feedback on the node.invoke_native helper:

- Register the response handler before emitting the request, so a reply
  that lands before emit() returns is not missed. The waiter filters on
  action and session and unregisters itself once the wait ends.
- Annotate `skill` as OVOSSkill.
- Look up the spoken name of an action from a skill dialog file named
  after the NodeNativeAction value (e.g. launch_camera_app.dialog) so
  the `description` passed to dialogs is localizable. English remains
  the fallback when no such file exists.
- Accept fractional per_action_timeouts values.

Tests now drive a FakeBus that replies synchronously from inside the
invoke emit, which the previous implementation timed out on.
@mikejgray
mikejgray force-pushed the FEAT_NodeInvokeNativeHelper branch from 6d82ada to 6eefb46 Compare September 4, 2026 21:14
@mikejgray
mikejgray marked this pull request as ready for review September 4, 2026 21:16
Drop the built-in English fallback text. Skills that call
invoke_native_action are NeonGecko-controlled and must ship the
native_action_* dialogs plus one <NodeNativeAction value>.dialog per
action they invoke; the module docstring lists them. A missing file
gets the standard OVOS behavior of speaking the key.

Annotate `skill` as NeonSkill rather than OVOSSkill: the helper passes
`message=` to speak_dialog, which only NeonSkill accepts.
@mikejgray
mikejgray requested a review from NeonDaniel September 4, 2026 21:24

@NeonDaniel NeonDaniel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Implementation looks good to me; tests are passing and there is no backwards-compat. to consider

@NeonDaniel
NeonDaniel merged commit b66ef96 into NeonGeckoCom:dev Sep 9, 2026
10 checks passed
mikejgray added a commit to OscillateLabsLLC/skill-messaging that referenced this pull request Sep 9, 2026
neon-utils~=1.12 does not resolve a prerelease, so the alpha published
from NeonGeckoCom/neon-utils#568 needs an explicit floor.
mikejgray added a commit to OscillateLabsLLC/skill-launcher that referenced this pull request Sep 9, 2026
neon-utils~=1.12 does not resolve a prerelease, so the alpha published
from NeonGeckoCom/neon-utils#568 needs an explicit floor.
@mikejgray
mikejgray deleted the FEAT_NodeInvokeNativeHelper branch September 9, 2026 02:06
mikejgray added a commit to OscillateLabsLLC/skill-messaging that referenced this pull request Sep 16, 2026
neon-utils~=1.12 does not resolve a prerelease, so the alpha published
from NeonGeckoCom/neon-utils#568 needs an explicit floor.
NeonDaniel pushed a commit to NeonGeckoCom/skill-messaging that referenced this pull request Sep 16, 2026
* feat: add node branch for single-shot sms/email compose

Adds a Node capability-gated path at the top of handle_send_sms and
handle_send_email, dispatching through neon-utils' shared
invoke_native_action helper. Reuses recipient/subject/body already
extracted by CMS_match_message_phrase; never enters the mobile
draft-and-confirm state machine.

Also adds test infrastructure for this skill (none existed before).

* fix: add per-action dialogs and reword timeout dialog

The neon-utils helper renders <NodeNativeAction value>.dialog for the
spoken action name and has no built-in fallback text, so both actions
this skill invokes need their own dialog file. Timeout wording matches
the review suggestion on skill-launcher#54.

* build: require neon-utils 1.14.2a5 for native_actions

neon-utils~=1.12 does not resolve a prerelease, so the alpha published
from NeonGeckoCom/neon-utils#568 needs an explicit floor.

* build: require neon-data-models 0.0.3a2 for NodeNativeAction

The enum this skill imports first shipped in the 0.0.3a2 prerelease;
the ~=0.0,>=0.0.2 spec resolves the 0.0.2 stable, which does not have
it.

* ci: enable skill_unit_tests now that test/test_skill.py exists

Requested in review. Intent and resource jobs stay off; this repo has
no test_intents.yaml or test_resources.yaml yet.

* build: request neon-utils[network] to match NeonCore's spec

NeonCore requires neon-utils[network]>=1.14.1 without allowing
prereleases, so pip resolved that node to 1.14.1 and it conflicted with
this skill's 1.14.2a5 floor on the plain neon-utils node. Requesting the
same extra lets one prerelease candidate satisfy both, as skill-launcher
already does. The same conflict would break a Hub install.

* build: sync skill.json requirement specs with requirements.txt

Upstream regenerated skill.json in #29, which dropped this branch's
neon-utils and neon-data-models floors. Match requirements.txt so the
update_skill_json workflow has nothing to push.

* test: list native action dialogs in test_resources.yaml

The resource test file landed upstream in #29 after these dialogs were
added; register them so the resource test covers them.
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.

2 participants