Commit Graph
1197 Commits
Author SHA1 Message Date
Cyrus GrayandGitHub c204e1b561 fix(inference): disable Responses API fallback for ollama/lmstudio — stops 404 Sentry noise (TAURI-RUST-59Y) (#2902) 2026-05-29 14:41:26 +05:30
YellowSnnowmannandGitHub 823b52a8e9 fix(observability): demote WhatsApp ingest SQLite lock noise (#2917) 2026-05-29 14:39:45 +05:30
Mega MindGitHubsanil-23Claude Opus 4.7sanil-23cyrus@tinyhumans.ai <cyrus@tinyhumans.ai>Steven Enamakel
db3fdc2e6c feat(skills): scheduled dashboard + run/new pages + [github] preflight gate + composio-only GitHub I/O (#2882)
Co-authored-by: sanil-23 <sanil@alphahuman.xyz>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: sanil-23 <sanil@vezures.xyz>
Co-authored-by: cyrus@tinyhumans.ai <cyrus@tinyhumans.ai>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-29 10:17:58 +05:30
a41d9132ba fix(cwd_jail/windows): wire AppContainer network capabilities for jail.allow_net (#2637)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-28 21:10:56 -07:00
5a5cd43ea9 feat(search): add Querit provider (#2753)
Co-authored-by: wangxinwei03 <wangxinwei03@MacBook-Pro.local>
2026-05-28 21:06:26 -07:00
YOMXXXandGitHub 3278f2cb52 fix(conversations): release store lock during cold index rebuild (#2849) (#2886) 2026-05-29 09:29:01 +05:30
ebe364bad8 fix(inference): suppress spurious Sentry events for Ollama tool-schema rejection 400s (#2812)
Co-authored-by: Taimoor <astikkosapparel009@gmail.com>
2026-05-28 20:54:28 -07:00
dae1ef3489 perf(learning/user_profile): Aho-Corasick DFA for preference extraction + pattern coverage (#2878)
Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com>
2026-05-28 20:53:38 -07:00
mysma-9403andGitHub bc4de23782 perf(routing/quality): batch refusal detection via Aho-Corasick DFA (#2870) 2026-05-28 20:52:12 -07:00
e8075fdb4b fix(composio): update GitHub action slugs to current values (#2835)
Co-authored-by: Taimoor <astikkosapparel009@gmail.com>
2026-05-28 20:51:22 -07:00
dad5f42a38 fix(inference): fail-fast on empty model for cloud providers, demote nvidia-nim Sentry noise (#2811)
Co-authored-by: Taimoor <astikkosapparel009@gmail.com>
2026-05-28 20:50:55 -07:00
linruitaoandGitHub 1fdb3f76b0 fix(yuanbao): correct AuthBind plugin_version / bot_version mapping (#2804) 2026-05-28 20:49:39 -07:00
mysma-9403andGitHub 6881183857 perf(security): cache canonical workspace_dir to skip per-call canonicalize syscall (#2798) 2026-05-28 20:48:16 -07:00
mysma-9403andGitHub 95b4da3698 perf(tokenjuice): hoist gh table split regex to a Lazy<Regex> static (#2770) 2026-05-28 20:40:48 -07:00
6f188b3e9a docs(memory-tree): update stale comment on translate_query_global_args (#2713)
Co-authored-by: zahica1234 <i.milev001@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:32:09 -07:00
5bd47bbcf1 ci: extend Windows secrets ACL timeout (#2654)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-28 19:12:11 -07:00
b1b919a92a feat(meet-agent): Flow A second brain — orchestrator + tools + pre-roll + cache + barge-in
Co-authored-by: M3gA-Mind <megamind@mahadao.com>
2026-05-29 07:10:50 +05:30
c5c93c502e feat(events): live domain event stream log panel (#2653)
Co-authored-by: sanil-23 <sanil@vezures.xyz>
Co-authored-by: Claude <noreply@anthropic.com>
2026-05-29 05:04:23 +05:30
YellowSnnowmannandGitHub a211cac9fd fix(providers): dedup tool specs at wire boundary to prevent 400 "Tool names must be unique" (#2846) 2026-05-29 05:01:58 +05:30
0019789fb0 feat(gameplay): AI gameplay review and highlight workflows for streamers (#1674) (#2856)
Co-authored-by: Ayush Raj Chourasia <iter.student.alpha@gmail.com>
Co-authored-by: Srinivas Vaddi <38348871+vaddisrinivas@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 05:01:12 +05:30
1cd617c815 fix(observability): demote channel supervisor restart noise (Sentry TAURI-RUST-15/-BB) (#2879)
Co-authored-by: oxoxDev <nikhil@tinyhumans.ai>
2026-05-29 04:37:03 +05:30
oxoxDevandGitHub 336d811ca0 feat(core): pass in-process RPC bearer via internal handle, not process env (#2709) 2026-05-29 04:35:33 +05:30
4657d16c7c feat(wallet): bind prepared transaction quotes to originating chat session
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
2026-05-29 04:35:01 +05:30
oxoxDevandGitHub 894f312c07 fix(composio/triage): demote provider-config-rejection rollups (Sentry TAURI-RUST-1V) (#2689) 2026-05-29 04:26:12 +05:30
1ea0ddeac7 fix(observability): classify WS protocol HTTP-version handshake error as expected (Sentry CORE-RUST-DP) (#2792)
Co-authored-by: M3gA-Mind <megamind@mahadao.com>
2026-05-29 04:23:51 +05:30
CodeGhost21andGitHub 97d83a1f77 fix(inference): synth local-runtime entry for list_models when no cloud_providers row (Sentry TAURI-RUST-28Z) 2026-05-29 04:21:15 +05:30
oxoxDevandGitHub 0bd17ea5e4 fix(subconscious): preserve anyhow chain + retry DDL with busy_timeout on SQLITE_BUSY (#2851) 2026-05-29 04:17:42 +05:30
f407065635 feat(intelligence): add architecture diagram viewer (#2687)
Signed-off-by: sunilkumarvalmiki <g.sunilkumarvalmiki@gmail.com>
Co-authored-by: sanil-23 <sanil@vezures.xyz>
2026-05-29 04:12:32 +05:30
YellowSnnowmannandGitHub a6fd156131 fix(inference): default empty model to reasoning-v1 on OpenHuman backend (#2837) 2026-05-29 04:12:29 +05:30
cc088d7e70 fix(providers): include body snippet on list_models JSON parse failure (#2838)
## Summary

- Replace `response.json()` with read-as-text + `serde_json::from_str` in `list_configured_models_from_config` so the response body is preserved when JSON decoding fails.
- Append a sanitized + truncated body snippet to the `[providers][list_models] failed to parse JSON` error so the failure is diagnosable from the log/Sentry line alone.
- Add three async unit tests: HTML body returns a diagnostic snippet, empty body still surfaces the parse error, and a valid `/models` response still lists models (regression guard for the new text-then-parse path).

## Problem

Sentry issue **TAURI-RUST-12** — `[providers][list_models] failed to parse JSON: error decoding response body` — 376 events / 14d on the `tauri-rust` project.

`response.json()` in [src/openhuman/inference/provider/ops.rs:125](src/openhuman/inference/provider/ops.rs:125) (pre-change) consumes the body in the process of decoding it. When the decode fails — typically because the server returned HTML from a captive portal / corporate proxy login page, an upstream load-balancer 502 served as HTML with `200 OK`, or a wrong-path endpoint returning a non-JSON response — the body is gone by the time we format the error, so Sentry receives `error decoding response body` with no payload context.

We can't fix this server-side. We *can* stop discarding the diagnostic information at the call site so users and devs can identify the real cause from the error string instead of guessing.

## Solution

`src/openhuman/inference/provider/ops.rs`:

- After the `status.is_success()` check, call `response.text().await` instead of `response.json()`. The text path returns the raw body verbatim, which we can then both parse *and* embed in the diagnostic message.
- `serde_json::from_str(&raw_body)` reproduces the previous decode behaviour exactly — same JSON parser, same `serde_json::Error` shape. On failure, the closure sanitizes the body via the existing `sanitize_api_error` helper and truncates it through the existing `crate::openhuman::util::truncate_with_ellipsis(_, 300)` before appending it as `(body: …)`.
- Adds an explicit error for `response.text()` failure (`failed to read response body`) — a transport-layer concern distinct from JSON parsing.

**Design choices**

- Re-use the existing `sanitize_api_error` (strips ANSI / control chars, caps at `MAX_API_ERROR_CHARS`) and `truncate_with_ellipsis` helpers — same sanitization the non-2xx branch already applies a few lines above. No new redaction policy.
- Keep the canonical error prefix `[providers][list_models] failed to parse JSON:` so any existing log greps / Sentry classifiers continue to match.
- 300-character snippet cap matches the existing non-2xx branch's `truncated` cap and the codebase convention for "include enough for triage, not enough to flood logs."
- No change to the JSON parser, no change to what counts as a valid `/models` response, and no change to error semantics — the new branch returns `Err(...)` in exactly the same shape and code path as before. Callers see one extra clause appended to the message string.
- Body is only read on the success path (`status.is_success()`). The non-2xx branch already had its own `response.text()` + sanitize chain, untouched.

## Submission Checklist

- Tests added or updated (happy path + at least one failure / edge case) per [Testing Strategy](../gitbooks/developing/testing-strategy.md#failure-path-requirement)
- **Diff coverage ≥ 80%** — pending local `pnpm test:rust` run
- Coverage matrix updated — `N/A: diagnostic-only change, no new feature row`
- All affected feature IDs from the matrix are listed in the PR description under `## Related`
- No new external network dependencies introduced (uses existing axum-based mock pattern from `spawn_openrouter_probe_server`)
- Manual smoke checklist updated — `N/A: no release-cut surface touched`
- Linked issue closed via `Closes #NNN` — `N/A: Sentry-tracked issue, no GitHub issue yet`

## Impact

- **Runtime**: desktop (Rust core). No mobile / web / CLI surface change.
- **Performance**: negligible — one extra `String` allocation for the body (length already bounded by reqwest's response size limits) and one extra `serde_json::from_str` instead of `response.json()`'s internal equivalent. Happy path serialization cost is identical.
- **Security**: no new surface. Body is sanitized via the same helper the non-2xx branch already trusts; `truncate_with_ellipsis(_, 300)` caps the leak window. No PII redaction policy changes.
- **Migration / compatibility**: none. RPC schema, return type, error-string prefix all preserved. Callers that previously matched on `"failed to parse JSON"` still match — only a `(body: …)` suffix is added.

## Related

- Closes: Sentry [TAURI-RUST-12](https://sentry.tinyhumans.ai/organizations/tinyhumans/issues/100/?project=4&referrer=issue-list&statsPeriod=14d)


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Bug Fixes**
  * Improved model-listing response parsing and diagnostics: parsing now uses the raw response text and, on failure, error messages include a sanitized, truncated snippet of the body to aid troubleshooting. Non-2xx handling and subsequent response validation remain unchanged.

* **Tests**
  * Added tests covering HTML responses, empty bodies, and valid model-listing payloads.

<!-- review_stack_entry_start -->

[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2838?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: M3gA-Mind <megamind@mahadao.com>
2026-05-29 04:04:48 +05:30
Mega MindGitHubcyrus@tinyhumans.ai <cyrus@tinyhumans.ai>
32dd0be19a fix(rpc): register openhuman.system_info and add legacy alias (Sentry CORE-RUST-G0, closes #2871) (#2877)
Co-authored-by: cyrus@tinyhumans.ai <cyrus@tinyhumans.ai>
2026-05-29 04:04:24 +05:30
972e327381 feat(tool_policy): diagnostics RPC and Developer Options panel (#2715)
Co-authored-by: Srinivas Vaddi <38348871+vaddisrinivas@users.noreply.github.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Co-authored-by: Vladimir Yastreboff <vlad@vladimirs-air.lan>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: sanil-23 <sanil@vezures.xyz>
Co-authored-by: Claude <noreply@anthropic.com>
2026-05-29 04:01:55 +05:30
fa50ceb222 fix(inference): replay deepseek reasoning_content on tool-call turns (Sentry TAURI-RUST-4KB) (#2876)
Co-authored-by: Ghost Scripter <ghostscripter@zerolend.xyz>
2026-05-29 03:54:25 +05:30
ad6d600469 fix(agent): drop bisected tool_call/tool_result pairs before sending to provider (#2840)
## Summary

* Filter unpaired `AssistantToolCalls` and orphan `ToolResults` out of the wire payload in `NativeToolDispatcher::to_provider_messages` so a bisected tool cycle can no longer reach the provider.
* Strip trailing `assistant` messages that carry `tool_calls` without paired tool responses from a resumed transcript in `bound_cached_transcript_messages` (symmetric to the existing leading-orphan strip).
* Add `assistant_message_has_tool_calls` helper that peeks into the JSON-encoded `assistant` ChatMessage content to detect the tool_calls field at the `ChatMessage` boundary.
* Add 5 regression tests for `NativeToolDispatcher::to_provider_messages`: paired cycle, trailing unpaired, mid-history unpaired, orphan ToolResults, and multiple paired cycles back-to-back.

## Problem

Sentry issue **TAURI-RUST-7** — `OpenHuman API error (400 Bad Request): {"success":false,"error":"400 An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'. (insufficient tool messages following tool_calls message)"}` — 589 events / 14d on the `tauri-rust` project.

The OpenAI chat-completions contract requires every `assistant{tool_calls}` message to be immediately followed by `tool` messages — one for every `tool_call_id`. Any other ordering produces `400 An assistant message with 'tool_calls' must be followed by tool messages`.

Two reachable code paths in our harness produce a bisected pair:

1. **Mid-turn abort / resume**. `ConversationMessage::AssistantToolCalls` is pushed into `Agent::history` before the tool runner finishes. If the turn aborts (user cancel, error, process kill, max-iter cap) before the matching `ConversationMessage::ToolResults` is appended, history ends on a tool_calls with no follow-up. The next turn submits the whole history and the backend rejects it.
2. **Cached transcript bound**. `bound_cached_transcript_messages` (`turn.rs:1660`) keeps the tail of a resumed transcript. The existing leading-orphan strip handles a window that opens on a stray `tool` message, but it never stripped a *trailing* assistant tool_calls. A resume from a mid-cycle snapshot ships an unpaired tool_calls and the backend rejects.

`trim_history` already had a leading-orphan guard ([`[turn.rs:1637](https://chatgpt.com/c/src/openhuman/agent/harness/session/turn.rs:1637)`](src/openhuman/agent/harness/session/turn.rs:1637)). The symmetric trailing / unpaired case was uncovered.

## Solution

### `src/openhuman/agent/dispatcher.rs` — Native dispatcher only

`to_provider_messages` is the boundary that serialises `ConversationMessage` → `ChatMessage` (wire format). The Native dispatcher is the only impl affected — XML and PFormat dispatchers render tool results into a `user` role with inline `<tool_result>` tags, so the tool_calls/tool ordering rule doesn't apply to them and their impls are untouched.

Two-pass pairing in a single loop:

```rust
let mut paired_indices: Vec<usize> = Vec::with_capacity(history.len());
for (i, msg) in history.iter().enumerate() {
    match msg {
        AssistantToolCalls { .. } => {
            // Keep only if next is ToolResults.
            if matches!(history.get(i + 1), Some(ToolResults(_))) {
                paired_indices.push(i);
            } else { log::debug!("dropping unpaired AssistantToolCalls at index {i}"); }
        }
        ToolResults(_) => {
            // Keep only if the previous *emitted* index is a kept AssistantToolCalls.
            let preceded_by_kept = i > 0
                && matches!(history.get(i - 1), Some(AssistantToolCalls { .. }))
                && paired_indices.last() == Some(&(i - 1));
            if preceded_by_kept { paired_indices.push(i); }
            else { log::debug!("dropping orphan ToolResults at index {i}"); }
        }
        Chat(_) => paired_indices.push(i),
    }
}
```

The key invariant is `paired_indices.last() == Some(&(i - 1))` — that captures emitted-not-raw lookbehind. A bisected assistant tool_calls is dropped, which means the now-orphan tool results that physically followed it are also dropped, even though `history[i-1]` is still `AssistantToolCalls`. Symmetric drop in a single pass.

Second pass: `flat_map` over `paired_indices` runs the existing serialisation logic verbatim (assistant tool_calls → JSON-encoded ChatMessage; tool results → one tool ChatMessage per result). No serialisation change — only the input set is filtered.

### `src/openhuman/agent/harness/session/turn.rs` — cached transcript bound

This layer operates on `Vec<ChatMessage>`, not `ConversationMessage`. Can't pattern-match on enum variants because the dispatcher's serialisation packs both content and tool_calls into a single JSON-encoded string in the assistant `ChatMessage.content` (see `dispatcher.rs:484-490`). To detect tool_calls at this boundary the helper peeks inside the JSON:

```rust
fn assistant_message_has_tool_calls(msg: &ChatMessage) -> bool {
    if msg.role != "assistant" { return false; }
    let Ok(value) = serde_json::from_str::<serde_json::Value>(&msg.content) else { return false; };
    value.get("tool_calls").and_then(|tc| tc.as_array())
        .map(|arr| !arr.is_empty()).unwrap_or(false)
}
```

Non-assistant role → false. Non-JSON content (a plain text reply) → false. Missing field or empty array → false. Message kept in all those cases.

Then a `pop_while` after the existing leading-orphan strip:

```rust
while bounded.last().map(assistant_message_has_tool_calls).unwrap_or(false) {
    bounded.pop();
    dropped_tail += 1;
}
```

Symmetric to the existing leading-orphan strip — both ends of the bounded window now end on a clean turn boundary.

## Design choices

- Filter at the wire boundary, not at write time. Both write sites (turn loop, transcript restore) push into history without coordinating with each other. Centralising the guard at the serialisation boundary catches every code path that ends up shipping to a provider, present and future.

- Native dispatcher only. XML / PFormat dispatchers render tool results into user role with inline tags and aren't subject to the OpenAI tool ordering rule. Leaving their `to_provider_messages` untouched avoids unrelated behaviour change.

- What we drop the backend would have rejected anyway. Every dropped message would have triggered the same 400. Dropping client-side turns a hard failure into a recoverable turn — the rest of the well-formed history still flies.

- `log::debug!` on drop. Visibility into how often the guard fires without flooding warn-level logs.

-JSON-content inspection helper isolated and tested by the integration tests above. A `serde_json::from_str` parse failure means the content isn't the dispatcher's JSON envelope, so the message is a plain text assistant reply and must be kept — false return is correct.

## Submission Checklist

- Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy

- Diff coverage ≥ 80% — pending local pnpm test:rust run

- Coverage matrix updated — N/A: bug-fix behaviour-only change, no new feature row

- All affected feature IDs from the matrix are listed in the PR description under ## Related

- No new external network dependencies introduced

- Manual smoke checklist updated — N/A: no release-cut surface touched

- Linked issue closed via Closes #NNN — N/A: Sentry-tracked issue, no GitHub issue yet

## Impact

- Runtime: desktop (Rust core). No mobile / web / CLI surface change.

- Performance: one extra `Vec<usize>` allocation sized to `history.len()` in the dispatcher and one O(n) pass over the bounded transcript tail. Happy-path cost is two extra `matches!` checks per message. No measurable overhead on the chat hot path.

- Security: none — no new network surface, no new inputs trusted, no auth path touched.

- Migration / compatibility: none. Trait signatures, RPC schemas, and dispatcher output for fully-paired histories are unchanged. Previously-failing turns that hit the backend's 400 now succeed with a `log::debug!` line per dropped orphan.


## Related

- Closes: [TAURI-RUST-7](https://sentry.tinyhumans.ai/organizations/tinyhumans/issues/47/?project=4&referrer=issue-list&statsPeriod=14d)


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Bug Fixes**
  * Sanitized provider-bound message history to keep only well-formed assistant opener + matching tool-results (exact ID-set match, order-insensitive); orphaned or mismatched tool messages are dropped.
  * Hardened transcript trimming to strip partial/native tool-call envelopes at window edges so turns end on clean boundaries and log the count of stripped envelopes.

* **Tests**
  * Expanded regression suite covering pairing semantics, orphan/drop cases, ordering tolerance, and transcript-bounding behavior.

<!-- review_stack_entry_start -->

[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/tinyhumansai/openhuman/pull/2840?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: M3gA-Mind <megamind@mahadao.com>
2026-05-29 03:54:09 +05:30
Cyrus GrayandGitHub 78385d5c39 feat(ui): add Routines page — user-friendly scheduled tasks view 2026-05-29 03:39:49 +05:30
5fe8701f0e fix(observability): classify list_models 404 as ProviderUserState (Sentry TAURI-RUST-YJ) (#2873)
Co-authored-by: Ghost Scripter <ghostscripter@zerolend.xyz>
2026-05-29 03:39:24 +05:30
Mega MindGitHubcyrus@tinyhumans.ai <cyrus@tinyhumans.ai>
3833f9716b fix(cron): accept bare cron-expression string in Schedule deserializer (Sentry CORE-RUST-FY) (#2874)
Co-authored-by: cyrus@tinyhumans.ai <cyrus@tinyhumans.ai>
2026-05-29 03:39:07 +05:30
b78d5bf901 fix(core): fall back to other ports when preferred is OS-excluded (Windows WSAEACCES, Sentry TAURI-RUST-500) (#2816)
Co-authored-by: M3gA-Mind <megamind@mahadao.com>
2026-05-29 03:31:28 +05:30
JustinandGitHub de26734952 feat(mcp-registry): InstalledServer HTTP-remote transport (#2603) 2026-05-28 14:41:18 -07:00
a86aa6fbf8 docs(prompts): add zero-match search guardrail to SOUL.md/Personality (#2855)
Co-authored-by: zahica1234 <i.milev001@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 14:38:33 -07:00
65ae09c49f Add generated tool provenance and admission checks (#2549)
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
Co-authored-by: sanil-23 <sanil@vezures.xyz>
Co-authored-by: Claude <noreply@anthropic.com>
2026-05-29 03:03:40 +05:30
eac431a002 fix(observability): classify embedding API 401 'Invalid token' as SessionExpired (TAURI-RUST-4K5 regression) (#2869)
Co-authored-by: Claude <noreply@anthropic.com>
2026-05-29 02:17:16 +05:30
e83bfd6051 fix(observability): classify RPC filesystem path validation errors as expected (Sentry TAURI-RUST-4QH) (#2795)
Co-authored-by: M3gA-Mind <megamind@mahadao.com>
2026-05-29 01:08:25 +05:30
CodeGhost21andGitHub 7704836f06 fix(observability): classify 'does not support tools' provider 400 as user-state (Sentry TAURI-RUST-35 + 10 siblings) (#2796) 2026-05-29 00:55:54 +05:30
CodeGhost21andGitHub 14ff92b2bb fix(observability): classify OpenHuman/Embedding/streaming backend 'Invalid token' 401 as SessionExpired (TAURI-RUST-4P0 + 4K5 + 1EE) (#2786) 2026-05-29 00:50:38 +05:30
72cdfe9e6a fix(observability): classify web-channel empty-provider-response re-report as expected (Sentry TAURI-RUST-4Z1) (#2808)
Co-authored-by: M3gA-Mind <megamind@mahadao.com>
2026-05-29 00:48:16 +05:30
CodeGhost21andGitHub 1a404ac9c2 fix(backend_api): suppress Sentry on 401 via typed BackendApiError::Unauthorized (#2781) 2026-05-29 00:47:14 +05:30
29aeba82d4 fix(legacy_aliases): tolerate unquoted keys + skip comments in alias-table parser (#2865)
Co-authored-by: Claude <noreply@anthropic.com>
2026-05-29 00:45:18 +05:30
CodeGhost21andGitHub 9415fd1b01 fix: resolve Sentry issue 526 (#2815) 2026-05-29 00:44:15 +05:30
ef94b0b40d fix(observability): classify DeepSeek 'Insufficient Balance' 402 as user-state (Sentry TAURI-RUST-4ZF) (#2809)
Co-authored-by: M3gA-Mind <megamind@mahadao.com>
2026-05-29 00:36:28 +05:30