Skip to content

Release 0.13.3a1#394

Open
github-actions[bot] wants to merge 37 commits into
masterfrom
release-0.13.3a1
Open

Release 0.13.3a1#394
github-actions[bot] wants to merge 37 commits into
masterfrom
release-0.13.3a1

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Human review requested!

JarbasAl and others added 30 commits March 11, 2026 04:28
* feat: AsyncFakeBus alongside FakeBus

Adds an asyncio-native sibling to FakeBus that mirrors the surface of
ovos_bus_client.client.AsyncMessageBusClient (the [async] extra
shipped in ovos-bus-client 2.0).

ovos_utils.fakebus.AsyncFakeBus
- connect/close/emit/wait_for_message/wait_for_response: coroutines
- on/once/remove/remove_all_listeners: synchronous (matches the real
  AsyncMessageBusClient's handler-registration contract — pyee, no
  awaitable callbacks)
- Same session-context injection side effects as FakeBus, so multi-turn
  flows behave identically
- Lazy-imports from ovos_bus_client.session when present; gracefully
  degrades without it (same pattern as FakeBus)
- Backwards-compat shims (create_client, run_forever, run_in_thread) so
  it is a drop-in replacement anywhere FakeBus is currently used

Where this pays off
- Tests of code that calls 'await bus.emit(...)' or
  'await bus.wait_for_response(...)' (test_fakebus's sync equivalents
  cover that surface for the old client; this covers the new one).
- Runtime: in-process bus stand-in for asyncio-native components that
  do not need a real ovos-core (mirrors how FakeBus is used today by
  HiveMessageBusClient.connect(bus=FakeBus())).

Tests (test/unittests/test_async_fakebus.py, 19 tests)
- Lifecycle (construct/connect/close, session_id from kwarg)
- Handler registration (on/once/remove/remove_all_listeners + dispatch)
- emit side effects (session injection, raw 'message' event)
- wait_for_message (matched concurrently, timeout)
- wait_for_response (default <type>.response, explicit reply_type, timeout)
- Backwards-compat shims

No changes to existing FakeBus; all 23 existing FakeBus tests still pass.

* docs: add AsyncFakeBus to fakebus documentation

Documents the new AsyncFakeBus class alongside FakeBus in
docs/fakebus.md: coroutine/sync split table, key-methods table
with file:line citations, session-handling note, and a minimal
usage snippet. Updated docs/index.md module table and Contents
list to include AsyncFakeBus.

AI-Generated Change:
- Model: claude-sonnet-4-6
- Intent: keep docs accurate after feat: AsyncFakeBus alongside FakeBus (14ccc3d)
- Impact: updated docs/fakebus.md, docs/index.md; added citations; no stale content removed
- Verified via: manual review against ovos_utils/fakebus.py
* feat: expand_template delegates to ovos-spec-tools

ovos-utils' bracket expander is one of ~7 copies of the same logic
across the OVOS ecosystem. It now delegates to the OVOS-INTENT-1
reference expander, ovos_spec_tools.expand — the single conformant
implementation — instead of carrying its own.

- expand_template() is a thin wrapper over ovos_spec_tools.expand.
- adds the ovos-spec-tools dependency.

Behaviour change (conformance with OVOS-INTENT-1):
- a malformed template — a single-branch group, an empty sample, a
  slot-only template — now raises MalformedTemplate instead of silently
  producing a degenerate result. The old lenient behaviour was a bug.
- whitespace in a sample is normalized to single spaces; an emptied
  [optional] no longer leaves a double space.

Tests updated to the conformant output; a test added for the
malformed-template raise.

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

* feat: migrate lang and dialog onto ovos-spec-tools; deprecate the shims

Completes the ovos-utils migration onto ovos-spec-tools.

- lang.get_language_dir() delegates to ovos_spec_tools.closest_lang.
- dialog.py and file_utils.py use ovos_spec_tools.expand directly.
- expand_template, get_language_dir, MustacheDialogRenderer,
  load_dialogs and get_dialog are deprecated: each both emits a
  DeprecationWarning (visible to IDEs and tooling) and logs via the
  @deprecated helper, pointing callers at the ovos-spec-tools
  equivalent. The removal version is derived from version.py — the
  next major release (VERSION_MAJOR + 1).

standardize_lang_tag is left unchanged: its `macro` parameter has no
ovos-spec-tools equivalent and documented, tested behaviour.

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

* feat: migrate standardize_lang_tag to ovos-spec-tools

standardize_lang_tag now delegates to ovos_spec_tools.standardize_lang
and is deprecated (DeprecationWarning + the @deprecated log helper).

The `macro` parameter is kept for backward compatibility but no longer
affects the result: its region-stripping only ever happened on the
no-langcodes fallback path — inconsistent with the langcodes path,
which never stripped the region — so it was a latent bug.

geolocation.py now uses ovos_spec_tools.standardize_lang directly.
test_lang.py updated to the conformant behaviour.

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

* fix: standardize_lang_tag macro=True returns the bare language

Keep the `macro` parameter functional — when set, drop the region with
a plain .split("-")[0] on the standardized tag, so
standardize_lang_tag(x, macro=True) returns the bare primary language
subtag as before.

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

---------

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

* feat: fakebus Message is the ovos-spec-tools class directly; publish attached as a method

OVOS-MSG-1 lives in ovos-spec-tools 0.5.0a1+. The 165-line FakeMessage
class (with its _MutableMessage metaclass + dynamic __new__) is gone;
fakebus now re-exports the spec-tools Message directly and attaches the
one legacy convenience method downstream still uses:

    from ovos_spec_tools.message import Message as FakeMessage
    FakeMessage.publish = _publish_function

The MutableMessage metaclass / runtime indirection that tried to return
an ovos_bus_client.Message when bus-client was installed is no longer
needed: spec-tools is a hard dependency, the canonical class is always
present, and ovos-bus-client.Message is the **same** class.

What's gone:

* The historical reply() quirk that promoted data['destination'] into
  context['destination'] was always a bug.
* as_dict is now on the spec-tools Message itself; no need to define
  it here.

What stays:

* publish() — attached at module import; relay under a new topic, drop
  'target', no swap, no deep-copy of data;
* The deprecated ovos_utils.fakebus.Message alias for downstream
  callers still doing from ovos_utils.fakebus import Message.

pyproject pin: ovos-spec-tools>=0.5.0a1.

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

* chore: deprecate fakebus.FakeMessage.publish — slated for removal in next major

publish is a bus-client tradition outside OVOS-MSG-1 (the spec defines
forward / reply / response as the only normative derivations). Every
call now fires a DeprecationWarning via both warnings.warn and the
@deprecated decorator from ovos_utils.log, naming the next major
(computed f'{VERSION_MAJOR + 1}.0.0' from version.py) as the removal
target.

Migration: switch publish() callers to forward() or reply().

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

* fix: bump ovos-spec-tools to >=0.5.1a1 to pick up the empty-msg_type accept

0.5.0a1 still rejected empty `msg_type` at construction, which broke
the `Message("").forward(real_type, data)` scaffold pattern used by
the scheduler/event tests. 0.5.1a1 accepts empty at construction and
gates only on serialize/wire output. Align both pins.

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

* ci: align coverage workflow with build-tests (install extras, scope to test/unittests)

The coverage job was installing the base package only — test modules
that import `ovos_bus_client` / `ovos_config` failed at collection.
Match the build-tests config so coverage actually runs the suite.

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

* ci: pass install_extras as a pip arg, not an extras name

The gh-automations coverage workflow installs literally what install_extras
contains: `pip install ${install_extras}`. `extras` alone is meaningless;
`.[extras]` is what installs the optional-dependencies group.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…des semantics) (#377)

The spec-tools migration of `standardize_lang_tag` changed the
`macro` argument from its historic meaning (langcodes-defined
**macrolanguage substitution** — `cmn` -> `zh`, `nb` -> `no`)
to **"strip the region"** (`en-US` -> `en`) via
`tag.split('-')[0]`. Every caller that passes the default
`macro=True` (`ovos_bus_client.session`, many transformer
plugins, …) now gets region-stripped output — including OVOS's
`SessionManager`, which silently rewrites `session.lang` from
`en-US` to `en` on every message and breaks downstream consumers
that key on region (locale resource lookups, regional dialog,
ovoscope final-session assertions).

Restore the historic semantics by delegating to
`langcodes.standardize_tag(lang_code, macro=macro)` — which is what
the pre-migration body did (commit 9baa615). When langcodes is
unavailable, fall back to spec-tools' `standardize_lang` (also
region-preserving) and treat `macro` as a no-op.

Tests pin all three:
- macro=True preserves the region (`en-US` round-trips)
- macro=True substitutes macrolanguages (`cmn` -> `zh`)
- macro=False keeps both the region and the sublanguage

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
json_database~=0.10 resolves to >=0.10,<1.0, excluding json_database 1.x (now published, 1.0.2a1, which dropped the duplicate hivemind-json-db-plugin entry point). As ovos-utils is a foundational dependency, this cap blocks json_database 1.x from resolving anywhere in the OVOS alpha set. Widen to >=0.10,<2.0.0.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
FakeBus now uses ovos_spec_tools.NamespaceTranslator (the same logic as
MessageBusClient) so the test/satellite double bridges legacy<->ovos.* topics
and dedupes dual-listeners identically: emit() also dispatches the counterpart
topic(s); on() wraps migrated-topic handlers with the shared mirror-guard.
Both flags default on; override per-instance with modernize=/emit_legacy=.
Bumps ovos-spec-tools>=0.9.0a1 (NamespaceTranslator).
…383)

fakebus.py imports NamespaceTranslator from ovos_spec_tools at module top
level (unconditional), and that symbol first ships in ovos-spec-tools
0.10.0a1. The previous >=0.9.0a1 floor could resolve to a version without
it, making `import ovos_utils.fakebus` fail at install time.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* fix: translate mirrored payload onto counterpart topic in FakeBus

FakeBus mirrors MessageBusClient's namespace-migration bridge; it now
calls NamespaceTranslator.translate_payload() at its counterpart-emit
point so the mirrored Message carries the payload in the COUNTERPART
topic's shape instead of a verbatim copy. This keeps the test double
faithful to the real bus.

Identity transform for payload-compatible renames (behaviour unchanged);
reshaped per direction for the shape-changing renames (handler trio,
detach_intent, enable/disable_intent).

Pins ovos-spec-tools floor to >=0.14.1a1 (the version that will publish
the translate_payload API, ovos-spec-tools#42).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* ci: install in-flight spec-tools cross-dep from git

* ci: pre-install spec-tools conformance-message for coverage job

* fix: lower spec-tools floor to 0.14.0a1 (translate_payload branch version)

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* feat: mirror namespace migration in AsyncFakeBus + env/config flag parity

AsyncFakeBus now mirrors FakeBus / MessageBusClient namespace migration:
builds a NamespaceTranslator, wraps migrated-topic handlers with a
mirror-guard for dedup in on()/remove(), and dispatches counterpart
topics with translate_payload on emit().

Both FakeBus and AsyncFakeBus resolve modernize/emit_legacy the way the
real client's _bus_flag does: explicit kwarg wins, else env var ->
websocket.* config -> default True. A local _bus_flag helper mirrors the
semantics without importing from ovos-bus-client (layering). A _UNSET
sentinel distinguishes "kwarg omitted" from "kwarg passed True/False".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: drop obsolete spec-tools git-ref in CI; floor to published translate_payload

The build/coverage workflows pinned ovos-spec-tools@fix/conformance-message
via pre_install_pip because translate_payload was unpublished. It has shipped
since 0.16.1a1, so the git-ref is obsolete (and masked an inadequate
>=0.14.0a1 floor that cannot satisfy the FakeBus namespace-migration code).
Floor bumped to >=0.16.1a2 (the published min carrying the NamespaceTranslator
payload-transform API) and the CI git-ref removed — versions belong in
pyproject, not CI.

* chore: remove stray agent scratch files (AGENTS.md, TODO.md, console-script artifact)

* chore: drop requirements/*.txt — pyproject.toml is the single source of truth

The requirements/{requirements,extras}.txt files duplicated the inline
[project.dependencies] / [project.optional-dependencies] (pyproject was already
a superset — it additionally carried python-dateutil and packaging). Nothing
reads them (no setup.py/MANIFEST; CI installs .[extras]). Removed per the
pyproject-only packaging rule.

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…390)

The FakeBus shape-changing reshape tests asserted a
mycroft.skill.handler.* <-> ovos.intent.handler.* migration that does not
(and should not) exist — the handler-lifecycle trio is orchestrator-owned
spec topics, not a rename of the legacy per-skill handler events, so it was
correctly absent from ovos-spec-tools' MIGRATION_MAP. The tests therefore
failed (the spec listener was never reached).

Retarget them at an actual shape-changing pair from
MIGRATION_PAYLOAD_TRANSFORMS: detach_intent <-> ovos.intent.deregister,
which splits the compound "skill:intent" name into skill_id + intent_name
(and rejoins it in reverse). Same reshape coverage, real mapping.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
JarbasAl and others added 7 commits June 29, 2026 13:46
…389)

FakeBus mirrors the real MessageBusClient's default-session side effects.
ovos-bus-client deprecated SessionManager.update(make_default=True); the
broadcast payload is already default_session.serialize() (id == "default"),
so plain update(sess) syncs the default identically via the singleton
store — without tripping the deprecation warning on every FakeBus default
sync (notably in the e2e suites).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…y) (#393)

* fix: FakeBus folds the default session like any other (drop owner-only)

on_message no longer special-cases the default id: every session folds onto the
SessionManager singleton (value-passing; nothing is owner-only), matching the
spec-tools SessionManager and the real MessageBusClient.

* build: require ovos-bus-client>=2.6.2a2 (consistent SessionManager registry)

The FakeBus session integration (emit injects a session; the namespace-mirror
counterpart goes through Message.forward, which now stamps the session in
spec-tools >=1.2.x) needs ovos-bus-client's one-class SessionManager so emit and
forward read the SAME sessions registry. Under 2.6.2a1 the registry diverged
(subclass shadowing), so the original and mirrored copies carried different
session bytes and the receive-side mirror dedup fingerprint mismatched (handler
fired twice). 2.6.2a2 grafts onto the single registry, restoring consistency.
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