/provider and /model are registered with remote_invocable=False and
remote_admin_opt_in=True in src/openharness/commands/registry.py, but
OhmoSessionRuntimePool.stream_message intercepted them with
_handle_gateway_scoped_command before the remote-allowed gate ran, so the
contract was silently skipped for both commands.
Move the gateway-scoped intercept after the gating block so the existing
remote_admin_opt_in / allow_remote_admin_commands +
allowed_remote_admin_commands path governs them like every other admin
command. Add a regression test that asserts /provider and /model are
rejected unless the operator has opted in, and update the existing
positive test to set the opt-in so it continues to exercise the success
path.
Refs #280
Co-authored-by: glitch-ux <glitch-ux@users.noreply.github.com>
Close API clients when the runtime shuts down to release HTTP connection pool resources, and surface the active session ID in /session output.
Cherry-picked from PR #273. Excluded the embedded-wrapper session resolver and memory parser API changes because they need a narrower public API design.
Hooks now accept an optional priority field and HookRegistry returns hooks in stable highest-priority-first order.\n\nVerified with:\n- uv run pytest -o addopts='' tests/test_hooks tests/test_plugins/test_lifecycle_flow.py tests/test_plugins/test_loader.py tests/test_ui/test_runtime_plugin_tools.py -q\n- uv run ruff check src/openharness/hooks tests/test_hooks tests/test_plugins/test_lifecycle_flow.py tests/test_plugins/test_loader.py tests/test_ui/test_runtime_plugin_tools.py
Inject the active permission mode into the runtime system prompt so plan/default/full-auto state is visible to the model.
Refresh the engine model, effort, permission checker, and system prompt when runtime-affecting slash commands update settings.
Based-on: #268
Recognize win32 as a Windows platform alias and wrap missing platform lock modules in SwarmLockUnavailableError instead of leaking raw ImportError.
Based-on: #34
Prefer OPENHARNESS_<PROVIDER>_API_KEY variables over provider-native globals while resolving API-key auth. Keep provider-native variables as fallback and avoid applying unrelated native keys across active profiles.
Forward the OpenHarness-scoped auth/provider environment variables to spawned teammates.
Based-on: #93
Preserve subscription-auth failures instead of rewriting them as missing API keys, and point Claude/Codex subscription users at the correct login and provider commands.
Fixes#254
Forward OpenHarness config/data env vars to spawned teammates and apply CLI permission_mode overrides to Settings.permission.mode so full_auto survives sub-agent startup paths.
Fixes#274
ohmo init rewrites gateway.json without a domain field, undoing the
larksuite.com fix on every reconfigure. Add a domain selector so the
choice is persisted through init.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
REST client and WebSocket client both defaulted to open.feishu.cn; apps
created on open.larksuite.com were rejected with "Incorrect domain name".
Add `domain` field to FeishuConfig (default: https://open.feishu.cn for
backwards compatibility). Pass it to both lark.Client.builder().domain()
and lark.ws.Client(domain=).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(memory): add structured schema and usage index
Add schema-v1 frontmatter for memory files, including stable ids, deterministic signatures, soft delete metadata, TTL handling, and migration support for legacy stores.
Track recalled memories in usage_index.json so retrieval can prioritize useful memories and auto-dream can review stale unused entries before pruning.
Keep project and ohmo memory backends aligned under the same behavior while preserving runtime compatibility for unmigrated Markdown files.
* fix(memory): make backend migration defaults explicit
Remove the hard-coded nanobot name from Telegram /start and /help responses and sanitize dangling tool-use turns before continue_pending resumes a session.
`reasoning_content` is a non-standard field that some thinking-model
providers (Kimi k2.5 on Anthropic-format) require on every assistant
message with tool calls — even when empty. Other OpenAI-compatible
providers (Cerebras, NVIDIA NIM, OpenAI direct, etc.) reject the field
outright with a 400 ``wrong_api_format`` validation error.
Until now, ``_convert_assistant_message`` unconditionally emitted
``reasoning_content: ''`` for tool-using assistant messages. That hard-
breaks every strict-OpenAI provider on the very first tool turn.
Behaviour change:
- Captured non-empty reasoning is still always replayed.
- The empty-string fallback is now opt-in via
``OPENHARNESS_REQUIRE_EMPTY_REASONING_CONTENT=1``.
- Default behaviour matches strict-OpenAI providers, which is the
larger / standards-compliant population. Kimi-on-Anthropic users
set the env var in their dotfiles or settings.
Verified end-to-end against Cerebras gpt-oss-120b (previously 100%
failure rate from this field) — zero ``wrong_api_format`` errors.
Tests added: 6 cases covering captured-replay, opt-in matrix
(truthy/falsy values), and the no-tool-calls invariant.
`TelegramChannel.send` reads `self.config.reply_to_message` in the
outbound path, but the field was never declared on `TelegramConfig` —
only `ohmo init` (interactive mode) wrote it as a free-form key into
gateway.json. Configs that do not go through the interactive prompt —
`ohmo init --no-interactive`, pre-0.1.9 hand-written gateway.json, the
docs example — never have the key set, so every outbound message
crashes with `AttributeError: 'TelegramConfig' object has no attribute
'reply_to_message'` and the bot appears completely silent to the user.
Add `reply_to_message: bool = True` to `TelegramConfig` so the attribute
always exists. The default matches the interactive `ohmo init` default
(`default=bool(prior.get("reply_to_message", True))` in `ohmo/cli.py`),
so non-interactive and interactive configs that accept defaults behave
identically.
Same shape as #192 (proxy field), which added a missing `TelegramConfig`
attribute the implementation already assumed.
Closes#243
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add auto-dream memory consolidation with lock-based scheduling, manual /dream commands, backup/diff/rollback support, and ohmo integration for project and personal memory.
Add a configurable image_generation tool with OpenAI-compatible and Codex hosted providers, propagate generated media metadata through stream events, and let ohmo channels send generated image/file paths automatically.