Skip to content

refactor: migrate language matching & template expansion to ovos-spec-tools#411

Closed
JarbasAl wants to merge 5 commits into
devfrom
feat/use-ovos-spec-tools
Closed

refactor: migrate language matching & template expansion to ovos-spec-tools#411
JarbasAl wants to merge 5 commits into
devfrom
feat/use-ovos-spec-tools

Conversation

@JarbasAl

@JarbasAl JarbasAl commented May 22, 2026

Copy link
Copy Markdown
Member

Wave 2 of the OVOS-wide migration onto ovos-spec-tools (OpenVoiceOS/architecture#7).

Changes

  • resource_files.pylocate_lang_directories: langcodes.tag_distance
    ovos_spec_tools.lang_distance (same <10 threshold). VocabularyFile /
    IntentFile loading: ovos_utils.bracket_expansion.expand_template
    sorted(ovos_spec_tools.expand(...)).
  • skills/converse.py_get_closest_lang: langcodes.closest_match +
    standardize_lang_tag + a manual threshold → ovos_spec_tools.closest_lang
    (standardizes and thresholds internally).
  • pyproject.toml — adds ovos-spec-tools>=0.0.1a2.

All migrated symbols were internal imports — not re-exported — so no public
API changed and no deprecation shims were needed.

Behaviour changes — conformance with OVOS-INTENT-1

  • Single-spacing fix: the old expand_template left a double space when
    an optional segment was dropped (hello [there] worldhello␣␣world);
    the conformant expander yields hello world.
  • A malformed template now raises MalformedTemplate instead of being
    silently expanded leniently (no fallback added).

Deferred — follow-up (deliberately not done)

  • MustacheDialogRenderer / load_dialogs still come from ovos_utils.dialog.
    MustacheDialogRenderer is part of the public SkillResources API (a
    property type and constructor argument); swapping it onto
    ovos_spec_tools.DialogRenderer risks the skill resource API and is left as
    a separate change.
  • standardize_lang_tag in converse.py (message-language normalization,
    distinct from language matching) is left untouched.

Verification

test_resource_files.py passes (28 tests). The migration touches three files
(resource_files.py, converse.py, pyproject.toml).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Deprecations

    • Legacy dialog renderer and several legacy resource classes are deprecated and now emit warnings.
  • Improvements

    • Dialogs, intents and vocabularies use spec-based rendering/expansion for more consistent output.
    • Language matching for converse selection improved for better locale selection.
    • New runtime support for spec-based tooling.
  • Behavior changes

    • Skill dialog rendering consolidated into a new render flow with consistent fallbacks.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Migrates dialog/vocabulary/intent rendering to ovos-spec-tools (spec-based expand/render), changes locale matching to use lang_distance, adds deprecation shims for legacy resource classes and dialog_renderer, and updates OVOSSkill APIs to use the new render path.

Changes

Spec-based Resource Rendering and Deprecation

Layer / File(s) Summary
Imports, deprecation config, and locale matching
ovos_workshop/resource_files.py
Add module deprecation helpers and ovos-spec-tools imports; deprecate locate_base_directories/locate_lang_directories and switch locale ranking to lang_distance.
DialogFile rendering and Vocabulary expansion
ovos_workshop/resource_files.py
DialogFile now separates raw phrase loading and uses spec-based rendering (_spec_render with slots); VocabularyFile.load() now uses sorted expand(...) for permutations.
IntentFile expansion and rendering
ovos_workshop/resource_files.py
IntentFile.load() uses sorted expand() + flatten_list; IntentFile.render() replaced with spec-based rendering and slot/entity handling from self.data.
Legacy resource types deprecation wrappers
ovos_workshop/resource_files.py
Mark ResourceType, ResourceFile, and legacy file subclasses (QmlFile, JsonFile, ListFile, TemplateFile, RegexFile, WordFile) as deprecated and forward constructors to super().
SkillResources dialog_renderer shim and loader
ovos_workshop/resource_files.py
SkillResources marked deprecated; dialog_renderer becomes a deprecated property (warnings + @deprecated) while still lazily building MustacheDialogRenderer; _load_dialog_renderer() loads .dialog templates via load_template_file; render_dialog() calls resource_file.render().
Converse language matching update
ovos_workshop/skills/converse.py
Replace langcodes.closest_match with ovos_spec_tools.closest_lang and simplify _get_closest_lang to use it against registered matcher languages.
OVOSSkill dialog API updates and shims
ovos_workshop/skills/ovos.py
Add warnings/deprecated imports and VERSION_MAJOR; make OVOSSkill.dialog_renderer a deprecated shim, add render_dialog(), and update speak_dialog/get_response to use render_dialog().
Dependency declaration
pyproject.toml
Add ovos-spec-tools>=0.0.1a2 to project runtime dependencies.

Sequence Diagram(s)

sequenceDiagram
  participant OVOSSkill
  participant SkillResources
  participant DialogFile
  participant MustacheDialogRenderer
  OVOSSkill->>SkillResources: render_dialog(key, data)
  SkillResources->>DialogFile: resource_file.render()
  DialogFile->>MustacheDialogRenderer: _spec_render(template, slots=data)
  MustacheDialogRenderer-->>DialogFile: rendered utterance
  DialogFile-->>SkillResources: final dialog text
  SkillResources-->>OVOSSkill: returned utterance
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Poem

🐰 I hopped through templates, found spec's bright art,

Braces aligned, variants set apart,
Old renderers whisper a gentle goodbye,
New routes return utterances safe and spry,
Hooray — I wiggle my nose and applaud the new start!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: migration of language matching to lang_distance and template expansion to ovos_spec_tools.expand. It is concise, specific, and clearly reflects the primary refactoring work across resource_files.py and converse.py.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/use-ovos-spec-tools

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 and usage tips.

…ec-tools

Wave 2 of the OVOS migration (OpenVoiceOS/architecture#7). Replace
reimplemented language-matching and template-expansion logic with the
conformant reference implementation from ovos-spec-tools.

- resource_files.py: locate_lang_directories now uses
  ovos_spec_tools.lang_distance instead of langcodes.tag_distance;
  vocabulary/intent loading uses ovos_spec_tools.expand instead of
  ovos_utils.bracket_expansion.expand_template. expand is single-spaced
  per OVOS-INTENT-1, fixing double spaces left when an optional segment
  is dropped. sorted() preserves the previous deterministic ordering.
- converse.py: _get_closest_lang uses ovos_spec_tools.closest_lang,
  which standardizes both tags and applies the spec's distance-below-10
  threshold internally.
- Add ovos-spec-tools>=0.0.1a2 to dependencies.

All migrated symbols were internal-only; no public API changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@JarbasAl JarbasAl force-pushed the feat/use-ovos-spec-tools branch from 60f53e2 to 9ddcac5 Compare May 22, 2026 17:25
@github-actions

github-actions Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

Synchronizing... Check results have been successfully retrieved. 📡

I've aggregated the results of the automated checks for this PR below.

🔍 Lint

Another check completed successfully! 🏁

ruff: issues found — see job log

⚖️ License Check

I've checked the license history of this repo. 📜

✅ No license violations found (49 packages).

License distribution: 12× MIT License, 8× Apache Software License, 7× Apache-2.0, 7× MIT, 2× BSD-3-Clause, 2× ISC License (ISCL), 2× PSF-2.0, 2× Python Software Foundation License, +7 more

Full breakdown — 49 packages
Package Version License URL
audioop-lts 0.2.2 PSF-2.0 link
build 1.5.0 MIT link
certifi 2026.5.20 Mozilla Public License 2.0 (MPL 2.0) link
charset-normalizer 3.4.7 MIT link
click 8.4.1 BSD-3-Clause link
combo_lock 0.3.1 Apache-2.0 link
filelock 3.29.0 MIT link
idna 3.16 BSD-3-Clause link
importlib_metadata 9.0.0 Apache-2.0 link
json-database 0.10.1 MIT link
kthread 0.2.3 MIT License link
langcodes 3.5.1 MIT License link
markdown-it-py 4.2.0 MIT License link
mdurl 0.1.2 MIT License link
memory-tempfile 2.2.3 MIT License link
ovos-config 2.1.1 Apache-2.0 link
ovos-number-parser 0.5.1 Apache Software License link
ovos-option-matcher-fuzzy-plugin 0.0.1 Apache Software License link
ovos-plugin-manager 2.4.0a1 Apache-2.0 link
ovos-spec-tools 0.0.1a2 Apache-2.0 link
ovos-utils 0.8.5 Apache-2.0 link
ovos-workshop 8.2.0a1 Apache-2.0 link
ovos-yes-no-plugin 0.3.0 Apache Software License link
ovos_bus_client 1.5.0 Apache Software License link
packaging 26.2 Apache-2.0 OR BSD-2-Clause link
padacioso 1.0.0 apache-2.0 link
pexpect 4.9.0 ISC License (ISCL) link
ptyprocess 0.7.0 ISC License (ISCL) link
pyee 12.1.1 MIT License link
Pygments 2.20.0 BSD-2-Clause link
pyproject_hooks 1.2.0 MIT License link
python-dateutil 2.9.0.post0 Apache Software License; BSD License link
PyYAML 6.0.3 MIT License link
quebra-frases 0.3.7 Apache Software License link
RapidFuzz 3.14.5 MIT link
regex 2026.5.9 Apache-2.0 AND CNRI-Python link
requests 2.34.2 Apache Software License link
rich 13.9.4 MIT License link
rich-click 1.9.7 MIT License

Copyright (c) 2022 Phil Ewels

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
| link |
| simplematch | 1.4 | MIT License | link |
| six | 1.17.0 | MIT License | link |
| standard-aifc | 3.13.0 | Python Software Foundation License | link |
| standard-chunk | 3.13.0 | Python Software Foundation License | link |
| typing_extensions | 4.15.0 | PSF-2.0 | link |
| unicode-rbnf | 2.4.0 | MIT License | |
| urllib3 | 2.7.0 | MIT | link |
| watchdog | 6.0.0 | Apache Software License | link |
| websocket-client | 1.9.0 | Apache Software License | link |
| zipp | 4.1.0 | MIT | link |

Policy: Apache 2.0 (universal donor). StrongCopyleft / NetworkCopyleft / WeakCopyleft / Other / Error categories fail. MPL allowed.

🔒 Security (pip-audit)

Scanning the horizon for any zero-day threats. 🌅

✅ No known vulnerabilities found (68 packages scanned).

🔨 Build Tests

The build report is now ready for your review. 📝

Python Build Install Tests
3.10 ⚠️
3.11
3.12
3.13
3.14

❌ 3.10: Install OK, tests failed
Check job logs for details.

📋 Repo Health

Ensuring the repo is getting enough sleep (aka stable releases). 💤

✅ All required files present.

Latest Version: 8.2.0a1

ovos_workshop/version.py — Version file
README.md — README
LICENSE — License file
pyproject.toml — pyproject.toml
⚠️ setup.py — setup.py
CHANGELOG.md — Changelog
ovos_workshop/version.py has valid version block markers


Generated with ❤️ by OVOS Automations

Wave 2 of the OVOS migration (OpenVoiceOS/architecture#7). Replace the
reimplemented MustacheDialogRenderer-based dialog rendering with the
conformant reference renderer from ovos-spec-tools.

- resource_files.py: DialogFile.render / IntentFile.render now load the
  raw phrase list and render it with ovos_spec_tools.render, which
  expands (a|b)/[x] variants and fills {name} slots per OVOS-DIALOG-1.
  SkillResources.render_dialog renders directly without routing through
  a MustacheDialogRenderer. SkillResources keeps handling the legacy
  resource types (qml, json, list, value, regex, word, template) that
  ovos-spec-tools does not cover.
- ovos.py: OVOSSkill gains render_dialog, which renders via
  self.resources.render_dialog; speak_dialog and the get_response /
  ask on-fail flows call render_dialog instead of dialog_renderer.render.
- The SkillResources.dialog_renderer and OVOSSkill.dialog_renderer
  properties are kept as deprecated compat shims (warnings.warn +
  @deprecated) that lazily build a MustacheDialogRenderer for legacy
  callers; removal version computed from VERSION_MAJOR.

A missing .dialog file still falls back to the dialog name with dots
replaced by spaces (eg "record.not.found" -> "record not found"), the
documented contract of the previous renderer. Unfilled slots now raise
ovos_spec_tools.UnfilledSlot instead of being silently dropped.

BREAKING CHANGE: dialog rendering is now performed by
ovos_spec_tools.render. The dialog_renderer properties on SkillResources
and OVOSSkill are deprecated compat shims. A dialog phrase with a
{name} slot that has no value now raises UnfilledSlot instead of
producing a partially-rendered string.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ovos_workshop/resource_files.py (1)

93-101: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a deterministic tiebreaker to language-directory sorting.

Line 101 sorts only by distance. When two folders score the same, the final order falls back to iterdir() order, and downstream callers use the first result as the selected fallback language directory. That makes dialect selection nondeterministic across filesystems. Sort by (score, folder.name) here to keep the fallback stable.

Suggested fix
-    candidates = sorted(candidates, key=lambda k: k[1])
+    candidates = sorted(candidates, key=lambda k: (k[1], k[0].name))
🤖 Prompt for 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.

In `@ovos_workshop/resource_files.py` around lines 93 - 101, The sorting of
candidate language directories only uses the distance score, causing
nondeterministic order when scores tie; update the sort for candidates (after
collecting tuples (folder, score) using lang_distance) to use a deterministic
tiebreaker by sorting on (score, folder.name) instead of key=lambda k: k[1], so
tied scores are resolved consistently by folder.name.
🤖 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_workshop/resource_files.py`:
- Around line 642-648: The current shim that populates self._dialog_renderer
only iterates immediate children of each directory, missing nested .dialog
files; update the loop over base_dirs (where renderer =
MustacheDialogRenderer()) to walk directories recursively (e.g., use
Path.rglob("*.dialog") or an os.walk) and call
renderer.load_template_file(path.stem, str(path)) for each matching file so all
nested .dialog templates are loaded into the dialog renderer.

---

Outside diff comments:
In `@ovos_workshop/resource_files.py`:
- Around line 93-101: The sorting of candidate language directories only uses
the distance score, causing nondeterministic order when scores tie; update the
sort for candidates (after collecting tuples (folder, score) using
lang_distance) to use a deterministic tiebreaker by sorting on (score,
folder.name) instead of key=lambda k: k[1], so tied scores are resolved
consistently by folder.name.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1244fcab-d6d1-45b3-9ddf-e237cef099ea

📥 Commits

Reviewing files that changed from the base of the PR and between 779e54b and d8a6266.

📒 Files selected for processing (4)
  • ovos_workshop/resource_files.py
  • ovos_workshop/skills/converse.py
  • ovos_workshop/skills/ovos.py
  • pyproject.toml

Comment thread ovos_workshop/resource_files.py
DialogFile.render / IntentFile.render now raise FileNotFoundError when
the resource file is missing or empty, instead of silently returning
the resource name with dots replaced by spaces.

OVOSSkill.render_dialog stays polymorphic: speak_dialog / get_response
accept either a dialog key or a literal utterance, so a name with no
matching .dialog file is caught and returned verbatim as the utterance.
The silent dialog-name humanization is gone — a genuinely missing file
is now an error at the layer that owns the file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mark the entire resource_files module as deprecated. It predates the OVOS
formal specifications and is considered overengineered. Everything stays
fully functional for downstream consumers; nothing is removed.

All public names (ResourceType, ResourceFile and subclasses, SkillResources,
CoreResources, UserResources, RegexExtractor, locate_base_directories,
locate_lang_directories, find_resource) now carry the @deprecated decorator
plus an inner warnings.warn and a .. deprecated:: docstring notice.

Messages point downstream to the ovos-spec-tools replacements where they
exist (LocaleResources, render/DialogRenderer, expand, closest_lang/
standardize_lang); legacy types with no spec replacement (.qml, .json,
.list, .value, .rx, .word, .template) are flagged as not part of the OVOS
formal specifications.

To avoid the framework spamming deprecation warnings at itself (these
classes are built per-skill, per-language on hot paths), a _caller_is_internal
stack guard suppresses both the log notice and the DeprecationWarning when
the caller is ovos_workshop's own code; the warnings remain visible to
downstream callers.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • ovos_workshop/resource_files.py

Commit: 0cb47730caf2491c5edec1444d762bdb133875bb

The changes have been pushed to the feat/use-ovos-spec-tools branch.

Time taken: 2m 11s

Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
ovos_workshop/skills/ovos.py (1)

1780-1782: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Correct the misleading comment about fallback behavior.

The comment states that a missing .dialog file "falls back to the name with dots replaced by spaces", but the actual implementation at lines 461-465 returns name verbatim without any transformation. Per the library context, literal utterances are spoken without dot-to-space fallback.

📝 Proposed fix to correct the comment
         def on_fail_default(utterance):
             fail_data = data.copy()
             fail_data['utterance'] = utterance
-            # render_dialog renders a phrase via ovos_spec_tools.render; a
-            # missing .dialog file falls back to the name with dots replaced
-            # by spaces.
+            # render_dialog renders a phrase via ovos_spec_tools.render; if
+            # no .dialog file is found, the name is returned verbatim as a
+            # literal utterance.
             if on_fail:
                 return self.render_dialog(on_fail, fail_data)
🤖 Prompt for 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.

In `@ovos_workshop/skills/ovos.py` around lines 1780 - 1782, Update the misleading
comment for render_dialog to reflect actual behavior: instead of saying a
missing .dialog "falls back to the name with dots replaced by spaces", change
the comment to state that when a .dialog file is missing render_dialog
returns/speaks the literal name verbatim (no dot->space transformation).
Reference the render_dialog function and the code path that returns name so the
comment matches implementation.
ovos_workshop/resource_files.py (1)

831-846: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Guard SkillResources.dialog_renderer the same way as other deprecated APIs in resource_files.py.

SkillResources.dialog_renderer bypasses _deprecated_public() / _caller_is_internal() and always emits DeprecationWarning via an unconditional warnings.warn(...). Since OVOSSkill.dialog_renderer delegates to self.resources.dialog_renderer, framework-owned access to the shim can still spam deprecation noise (though OVOSSkill.dialog_renderer itself is also unguarded).

Proposed fix
     `@property`
-    `@deprecated`("dialog_renderer is deprecated; dialog rendering is handled by "
-                "ovos_spec_tools.render via SkillResources.render_dialog. "
-                "This compat shim will be removed.", _REMOVAL_VERSION)
+    `@_deprecated_public`(
+        "dialog_renderer is deprecated; dialog rendering is handled by "
+        "ovos_spec_tools.render via SkillResources.render_dialog. "
+        "This compat shim will be removed.")
     def dialog_renderer(self) -> MustacheDialogRenderer:
         """
         Get a dialog renderer object for these resources
@@
-        warnings.warn(
-            "dialog_renderer is deprecated; use SkillResources.render_dialog",
-            DeprecationWarning, stacklevel=3)
         if not self._dialog_renderer:
             self._load_dialog_renderer()
         return self._dialog_renderer
🤖 Prompt for 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.

In `@ovos_workshop/resource_files.py` around lines 831 - 846, The dialog_renderer
property currently always emits a DeprecationWarning; change it to follow the
same guards used by other deprecated APIs by only issuing the warning when the
public deprecation guard is active and the caller is not internal—i.e., call the
same helpers used elsewhere (e.g., _deprecated_public() and
_caller_is_internal()) inside the dialog_renderer getter and only run
warnings.warn(...) when _deprecated_public() is true and _caller_is_internal()
is false, leaving the rest of the lazy MustacheDialogRenderer construction
intact.
🧹 Nitpick comments (1)
ovos_workshop/skills/ovos.py (1)

461-465: ⚡ Quick win

Consider logging when dialog file is not found.

When a dialog key doesn't match a .dialog file, the method silently returns name verbatim, which means missing dialog files may go unnoticed. If name was intended as a dialog key (e.g., "skill.error"), it will be spoken literally, which could be confusing.

📝 Proposed enhancement to add debug logging
 try:
     return self.resources.render_dialog(name, data)
 except FileNotFoundError:
+    self.log.debug(f"No .dialog file found for '{name}'; treating as literal utterance")
     # `name` is not a dialog key — treat it as a literal utterance
     return name
🤖 Prompt for 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.

In `@ovos_workshop/skills/ovos.py` around lines 461 - 465, The FileNotFoundError
in the call to self.resources.render_dialog is silently swallowed and returns
name verbatim; update the except block to log the missing dialog (e.g.,
self.log.debug or self.log.warning) including the dialog key (name) and the
caught exception before returning name so missing .dialog files are visible in
logs; keep the catch for FileNotFoundError and only add the log call referencing
self.resources.render_dialog and the local variable name.
🤖 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.

Outside diff comments:
In `@ovos_workshop/resource_files.py`:
- Around line 831-846: The dialog_renderer property currently always emits a
DeprecationWarning; change it to follow the same guards used by other deprecated
APIs by only issuing the warning when the public deprecation guard is active and
the caller is not internal—i.e., call the same helpers used elsewhere (e.g.,
_deprecated_public() and _caller_is_internal()) inside the dialog_renderer
getter and only run warnings.warn(...) when _deprecated_public() is true and
_caller_is_internal() is false, leaving the rest of the lazy
MustacheDialogRenderer construction intact.

In `@ovos_workshop/skills/ovos.py`:
- Around line 1780-1782: Update the misleading comment for render_dialog to
reflect actual behavior: instead of saying a missing .dialog "falls back to the
name with dots replaced by spaces", change the comment to state that when a
.dialog file is missing render_dialog returns/speaks the literal name verbatim
(no dot->space transformation). Reference the render_dialog function and the
code path that returns name so the comment matches implementation.

---

Nitpick comments:
In `@ovos_workshop/skills/ovos.py`:
- Around line 461-465: The FileNotFoundError in the call to
self.resources.render_dialog is silently swallowed and returns name verbatim;
update the except block to log the missing dialog (e.g., self.log.debug or
self.log.warning) including the dialog key (name) and the caught exception
before returning name so missing .dialog files are visible in logs; keep the
catch for FileNotFoundError and only add the log call referencing
self.resources.render_dialog and the local variable name.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 49a31374-6580-4ce1-bd4d-668bb88b7356

📥 Commits

Reviewing files that changed from the base of the PR and between d8a6266 and 0cb4773.

📒 Files selected for processing (2)
  • ovos_workshop/resource_files.py
  • ovos_workshop/skills/ovos.py

@JarbasAl

Copy link
Copy Markdown
Member Author

Superseded by #412 (deprecate ovos_workshop.resource_files module — merged) and #413 (drop its usage from OVOSSkill — open). Closing.

@JarbasAl JarbasAl closed this May 23, 2026
@JarbasAl JarbasAl deleted the feat/use-ovos-spec-tools branch July 1, 2026 12:08
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