Skip to content

refactor(errors): one failure-copy table and one budget matcher - #6867

Merged
senamakel merged 189 commits into
tinyhumansai:mainfrom
senamakel:w5-error-copy
Oct 1, 2026
Merged

senamakel merged 189 commits into
tinyhumansai:mainfrom
senamakel:w5-error-copy

Conversation

@senamakel

@senamakel senamakel commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Design note

Current state. User-facing failure copy was spread over web_chat/web_errors/{classify,budget,timeout,backend_error_code,retry,response_predicates}.rs, the loop-guard halt text (agent/tinyagents/middleware/{loop_guards,repeated_failure}.rs), and the budget-phrase matcher existed three times with deliberately different semantics: a regex list in web_chat, a whole-word list in the triage evaluator (agent/triage/evaluator/arm.rs), and the billing list in tinyinference_providers used by the loop guards. The error_type wire tokens were written inline at ~35 construction sites.

Target contract.

  1. Provider-text matchers move upstream (tinyinference, nested under tinyagents; PRs feat(llm,providers): one budget-phrase matcher with strictness modes; status-word failure predicates tinyinference#48, chore(deps): bump tinyinference for the shared budget matcher and failure predicates tinyagents#258): BudgetMatch::{Billing, Managed, Strict} + is_budget_message in tinyinference-providers, and the status-word predicates (is_rate_limit_text, is_timeout_text, is_auth_error_text, is_payment_required_text, is_server_error_text, is_context_length_text, is_model_unavailable_text, is_vision_unsupported_text, is_codex_token_expired_text, is_recoverable_failure_text) in tinyinference-llm::failure.
  2. ONE host copy table, inference/failure_copy/table.rs: FailureClass -> FailureCopy { error_type, source, retryable, copy }. web_errors/classify.rs and backend_error_code.rs are now just the ladder (which class?) and build the envelope from the table. Loop-guard halt summaries and the user-actionable escalation live in inference/failure_copy/halt.rs.
  3. ONE budget matcher. The three lists are three modes of the same upstream function, because they are not equivalent and a union would change classifications:
difference web_chat (Managed) triage (Strict) loop guard (Billing)
normalisation lowercase, -/_/whitespace runs -> one space lowercase, every non-alphanumeric -> space ASCII lowercase
matching regex/substring, budget.*exceed, add.*credits gap patterns whole-word sequences only substring
top up substring (so stop updating matches) whole word (does not match) no
out of credits yes yes no
budget exceeds yes via budget.*exceed yes no
insufficient budget / insufficient balance / credit balance is too low yes (OR Billing) no, deliberate: false positive hides a real fatal from Sentry yes
add credits, budget exceeded, no remaining credits yes yes yes

Each consumer keeps its own mode, so no classification changes. A corpus test compares each mode against a verbatim copy of its legacy implementation.

Stays host-side. The ladder order and which class an error maps to, the OpenHuman-own action-budget strings (SecurityPolicy), the turn-timeout marker, the harness-generated delegated-inference envelope markers, thresholds, and the Outcome/event plumbing.

Compatibility. Every user-facing string and every error_type / source / retryable value is byte-identical. Proof: web_chat/web_tests_error_copy_fixture_tests.rs has literal rows (input -> error_type, source, retryable, retry_after_ms, provider, fallback_available, message) for 37 inputs covering every class and every managed errorCode, captured from the pre-refactor binary before any code moved, plus literal halt-summary strings and the legacy-oracle budget corpus test. No persisted format is touched.

Frontend. app/src does not translate this copy: ChatRuntimeProvider renders chat_error.message verbatim and only branches on error_type (session_expired, cancelled, guardrail). No i18n added here. Follow-up: have the core emit the stable error_type plus params and let the frontend own localized text; the table in failure_copy/table.rs is the single place to key that from.

Changes

  • New inference/failure_copy/{mod,table,halt}.rs; classify.rs/backend_error_code.rs rebuilt on the table; budget.rs is a thin accessor over the shared matcher; response_predicates.rs deleted.
  • Triage is_inference_budget_exceeded and loop-guard budget detection call is_budget_message; loop_guards.rs keeps only thresholds and the repeat-call exemption.
  • vendor/tinyagents gitlink -> cc33ca71 (tinyagents#258, which bumps tinyinference#48).
  • Core src non-test lines: +723 / -853 vs base (the table is moved, not removed; net -130), plus ~300 lines of fixture tests.

Verification

  • cargo test -p openhuman --lib --features "$FEAT": 9093 passed, 3 failed, all pre-existing: credential_scrub::browser_confirmation_token_survives_without_exempting_page_credentials, composio::...connected_integrations_cache_is_keyed_per_credential, and flows::tinyflows::caps::tools::composio::...backend_dispatch_forwards_the_workflow_connection_id (flaky shared composio state; passes alone).
  • cargo check --tests -p openhuman -p openhuman-cli --features "$FEAT" and cargo check -p openhuman-embed -p openhuman-tinyhumans --tests: clean.
  • clippy on touched files: clean (one pre-existing unused import in flows/tinyflows/caps/mod.rs remains on base).
  • check-submodule-monotonic upstream/main HEAD: OK. rust:layout, check-agent-runtime-boundary: only the pre-existing entries. check-feature-forwarding, gated-test allowlist: OK.
  • cargo check --manifest-path crates/openhuman-app/Cargo.toml fails in dependency resolution (plist via starship-battery/tinymemory-gate), unrelated to this change. check-module-pins could not run (shallow submodule tags).
  • Merge order: tinyinference#48, then tinyagents#258, then this.

Summary by CodeRabbit

  • Improvements
    • Standardized inference error messages and classifications across chat responses, including clearer retry guidance for rate limits and billing issues.
    • Improved recognition of budget-related errors and clearer explanations when an agent cannot continue.
    • Added consistent summaries for repeated or stalled agent actions and prompts for errors that may require a connection.
  • Tests
    • Added coverage for error messages, retry details, budget detection, and agent halt summaries.

senamakel and others added 30 commits October 1, 2026 08:50
Remove the LocalAIDownloadSnackbar component, the LocalAIStep onboarding page, and all associated utility modules and tests for local AI bootstrap, chat gating, and message segmentation. The formatBytes helper is moved from localAiHelpers to a new format utility to keep the import alive for AppUpdatePrompt. This change eliminates the entire local AI download and setup flow, which is no longer needed.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The LocalAIDownloadSnackbar component has been removed from the App component and its associated test mock, as it is no longer needed. The AppUpdatePrompt component's comment has been updated to remove the reference to the removed component's visual conventions.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds a Playwright end-to-end test that verifies the retired `local-model-debug` settings route redirects to the Connections LLM tab. This ensures the redirect behaviour is preserved as the codebase evolves.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the local AI binary is not found, the application now returns a clear error message instead of crashing or hanging indefinitely. This improves the user experience by providing actionable feedback when the required AI component is unavailable.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The local AI command path was incorrectly resolving relative paths, causing failures when the application was launched from directories other than the project root. This change updates the path resolution logic to use the application's base directory instead of the current working directory, ensuring consistent behavior regardless of where the app is started from.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The RPC method service now gracefully handles responses where optional fields are absent, preventing runtime errors when the API returns partial data. This change ensures that the application remains stable when interacting with endpoints that do not always include every field in their response payloads.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the voice panel is opened on a system with no audio input or output devices, the component no longer throws an unhandled error. A guard now checks for the existence of device lists before attempting to access their first element, ensuring the panel renders gracefully in environments without audio hardware.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Fixed the voice panel key modal and provider chips components to properly handle state updates and display provider information. The key modal now correctly validates and saves API keys, while the provider chips show accurate connection status and available options.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…all and Piper management

Remove the voice installer API and its auto-install triggers from the voice panel, and update the local AI documentation to clarify that OpenHuman does not install, start, or manage local runtimes or models. The Piper voice installer was removed because the product no longer bundles or orchestrates local TTS engines; users must install Piper and its voices themselves. The local AI docs now describe the runtime as something the user runs independently, with OpenHuman connecting to it as a provider rather than managing its lifecycle.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds a new guide for running models locally, providing users with step-by-step instructions for setting up and using local inference without relying on external APIs.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The voice panel test was failing because it expected the old default voice identifier after the default was updated to a different voice. Changed the expected value in the test assertion to match the current default voice setting.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…nHuman does not install runtime

Rewrite the local models section to clarify that OpenHuman does not install Ollama, LM Studio, or any model weights — users must run their own runtime and pull models themselves. Remove the RAM tier presets table and the all-minilm warning, replace with instructions for adding a local provider in the app, and update the table headers and TTS row to match the new wording.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add unit tests for the VoicePanel component to verify that voice selection, speech rate adjustment, and voice preview functionality work correctly. This ensures the voice settings UI behaves as expected and prevents regressions during future changes.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Removed the fragment identifier from the cross-reference link in the local model guide, as the target page no longer uses that specific anchor.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Replace the simplified list of local AI components with detailed, actionable steps for configuring each piece, and clarify that local-only mode fails hard on missing runtimes rather than falling back to the cloud.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Removed the presets field from the local provider snapshot and deleted the functions that managed the Ollama daemon lifecycle, including toggling runtime enabled state and applying presets. The app no longer installs or controls the local AI runtime, as users are expected to run their own OpenAI-compatible endpoint independently.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the engines documentation to better explain how local providers are addressed using the `<provider>:<model>` format, and clarify that OpenHuman does not install runtimes or download models. Also improve the embedding section to note that users must pull models themselves and that dimension mismatches are caught at embed time.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Updated the AI settings API endpoint from `/ai-settings` to `/ai/settings` to match the backend routing structure. This fixes a 404 error when the frontend attempts to fetch or update AI configuration settings.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…uides

Update the child-safe companion, doctor assistant, move-to-new-pc, and recover-failed-installation guides to more accurately describe local model setup. The previous wording implied that enabling a local AI toggle or seeing a "ready" status was sufficient, but users must independently install the runtime, pull model weights, and explicitly route chat traffic to the local provider. The changes also clarify that OpenHuman does not download or manage model weights, and that the `local_only` privacy mode provides a stronger guarantee than simply adding a local provider.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a new feature preferences panel within the tools settings section, allowing users to configure their feature-specific options. This change adds the panel component, updates the core state store and API to support feature preference data, and includes the panel in the onboarding layout for initial setup.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…minology

Update the privacy-sensitive data guide to reflect that users run their own local AI runtime and add it as a provider, rather than OpenHuman turning on a built-in local model. The change also rephrases the checklist item to ask about routing to a local provider instead of checking if local AI is on and ready, making the instructions match the actual configuration workflow.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the test to verify that the "no tools configured" message appears when the tools list is empty, fixing a false positive where the test passed even when the message was not rendered.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
… and clarify local AI setup

Remove the `localModelConsentGiven` and `localModelDownloadStarted` fields from test fixtures in ToolsPanel and OnboardingLayout tests, as these flags are no longer part of the onboarding state. Update the gitbooks documentation for memory-tree, scoring, and privacy-and-security to clarify that users must run their own Ollama instance and pull models themselves, rather than relying on an automatic local AI setup.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Updated the model routing documentation to specify that local models require a runtime like Ollama, LM Studio, or MLX, and added a similar clarification to the getting-started guide about installing the runtime and pulling models yourself.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The Ollama state type has been reduced from seven states to five by removing `missing`, `starting`, and `error`, and adding `unreachable`. This change reflects that the application no longer manages the local runtime—it never installs, starts, or downloads anything—so states related to those operations are no longer meaningful. The `deriveOllamaState` function and its tests have been updated accordingly, mapping old managed-runtime states like `downloading` and `installing` to `stopped`, and treating `unreachable` as the offline indicator when the core cannot reach the user-configured endpoint.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Removed the ComposioPanel component and its registration in the settings route registry, as the composio integration is no longer supported. Also cleaned up references to composio in the VoiceSetupModal, Conversations feature, and the useVoiceSkillStatus hook to prevent broken imports and stale configuration.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
… features

Mark rows for model download, runtime install, daemon lifecycle, RAM tiers, and tier presets as retired, since OpenHuman no longer manages the local runtime — the user runs Ollama, LM Studio, or an OpenAI-compatible server independently and adds the endpoint as a provider. Correct several stale test paths that pointed to files that have moved upstream or no longer exist, and add a section-level note explaining the new architecture.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Updated the test file path in the coverage matrix for runtime failure handling to point to the correct location in the AIPanel test suite, reflecting that the probe and rollback logic is now tested through the component's test file rather than the previous path.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the module path referenced in AGENTS.md from `inference::local::ops::agent_chat_for` to `inference::host_runtime::ops::agent_chat_for` to reflect the actual location of the agent dispatch function.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Removed hundreds of translation strings across all 14 locale files that referenced local AI model downloading, installation, Piper setup, and related UI labels. This cleanup reflects the product decision to no longer bundle or manage local model downloads, instead directing users to self-install Ollama and Piper independently.

Auto-committed-on: macbook
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…es-components

chore(app): remove dead frontend pages, components, hooks and services
@tinysweeper

tinysweeper Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

⚠️ Review failed for fbdc3ab648cf. pull request exceeds review limits: 387 changed files (limit 500), 59011 changed lines (limit 50000)

YellowSnnowmann and others added 25 commits October 1, 2026 12:20
`remove_rpc` loaded the config after the source was already gone from the
registry, so a config read that failed turned a completed removal into an
error, and a caller retrying it would remove nothing. The removal now
stands; a record that cannot be cleared is logged and left behind, inert,
since nothing syncs the source again.
`engine_migrate` copied the keyed records only, so a switch left behind
document titles and tags, goals, the learned profile, every past
conversation and everything ingested into the summary tree. It now runs
tinymemory's `migrate::copy_all` (tinymemory#178): the records, then each
family both engines serve, then the ingested content, re-sent raw so the
new engine rebuilds its own summaries.

- The job reports the step under way and, once finished, what each step
  did; a step one engine cannot serve is named rather than failed.
- Re-sending content is the user's choice (`replay_content`, on by
  default), since hosted memory bills for what it reads again. Content the
  new engine refuses is reported in the note instead of holding the switch
  back: the old engine keeps it and its sync can bring it again.
- Into hosted memory, reader-based sources (`mem_src:` ids) are left out
  of the replay, because the host's own sync sends them from scratch.
- The module client forwards the new `EpisodicPortability` family, gated
  on the pinned artifact like every family after `Episodic`.
- The switch dialog lists what is copied, offers the content replay with
  a credits note for hosted memory, names the step under way, and the
  panel names what the new engine could not take.
Every 30-minute rebuild recomputed every facet and wrote each one back,
because decay alone moves the scores a little each cycle. On hosted memory
that is several billed requests per facet per cycle to record a change no
reader acts on.

A rebuild now skips a facet whose fields are unchanged and whose
confidence and stability moved by less than `REWRITE_TOLERANCE`. Decay is
exponential in the time since `last_seen_at`, so the next cycle, computing
from the older row, reaches the score a write-every-cycle would have; the
tolerance only bounds how stale the stored scores read in between.
A file removed from a synced folder stayed in hosted memory, because the
host's sync record dropped the item without telling the sink. The record
now keeps the id the sink answered for each item, and a folder sync that
no longer finds an item forgets it by that id.

Only a folder's walk is the whole source: an item missing from a feed or a
repository listing may just be past its window, so those stay. An empty
walk is taken as a folder that could not be read, not as every file
deleted, and a forget the sink refuses is retried on the next run.
Hosted memory has no model to summarise with, so `MemoryTree::summarise`
answers `Unsupported` and every hosted segment was left closed with no
recap. The archivist now folds such a segment with the host's own
`summarization` model, over the same turns and within the same input
budget, under the same deadline. The conversation already went to that
provider, so no new kind of data leaves the device.
… module mains

Co-authored-by: Medulla <medulla@tinyhumans.ai>
chore(i18n): prune 1,787 unused translation keys from all locales
…o merged module mains

Co-authored-by: Medulla <medulla@tinyhumans.ai>
…ilent-tests

test: stop silent no-op tests and un-ignore passing TODO-ignored tests
…to merged module mains

Co-authored-by: Medulla <medulla@tinyhumans.ai>
…eps-features

chore(core): prune dead deps, features and dead-code leftovers
Co-authored-by: Medulla <medulla@tinyhumans.ai>
refactor(inference): carry vendor Usage everywhere, billing as a thin host wrapper
…nature

fix(test): repair media_generation_e2e after the Files-folder change
…opy-everything

feat(memory): carry everything a store holds when switching engines (tinyhumansai#6718)
Updated the tinybox-core, tinybox-docker, and tinybox-jail crate versions from 0.1.10 to 0.1.11 in Cargo.lock, and advanced the vendor/tinybox submodule to the corresponding commit. This brings in the latest changes from the tinybox project.

Auto-committed-on: dragonfly
Updated the Cargo.lock to reflect version bumps for several tinybox crates from 0.1.10 to 0.1.11, and added the new tinybox-docker dependency along with its tokio dependency. This keeps the lockfile in sync with the updated crate versions and new dependency requirements.

Auto-committed-on: dragonfly
refactor(sandbox): run Docker sandbox through tinybox-docker one-shot
…e mains

Co-authored-by: Medulla <medulla@tinyhumans.ai>
refactor(agent): tool policy + approval gate as adapters over the harness policy seam
… mains

Co-authored-by: Medulla <medulla@tinyhumans.ai>
@senamakel
senamakel merged commit 1763f40 into tinyhumansai:main Oct 1, 2026
25 of 29 checks passed
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