mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 16:10:43 +00:00
db1da2f09614bdfd8f3961ff06c9a5dcdfe1234c
6607
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
db1da2f096 |
fix: MetricCardChart to use PanelSchemaRenderer (#13380)
- Replaced ChartRenderer with PanelSchemaRenderer in MetricCardChart.vue for consistent rendering. - Updated MetricCardChart.spec.ts to assert the panel schema and injected data correctly. - Introduced applyMeasuredYAxisLeftInset utility to adjust y-axis label spacing based on content width. - Enhanced convertPromQLData to call applyMeasuredYAxisLeftInset before returning options. - Added tests for applyMeasuredYAxisLeftInset to ensure correct behavior with various configurations. - Implemented compact preview adjustments in heatmap charts to optimize rendering in metrics explorer cards. |
||
|
|
7a88daa8d1 |
feat: self-correcting search errors with hint and did-you-mean suggestions (#13375)
Design at: #13375 ## What Search errors become self-correcting (AX track, D4): a mistyped field or function name now returns structured, minimal guidance instead of a raw engine error. ```json { "code": 20004, "message": "unknown field 'servce'", "suggestions": ["service"] } { "code": 20005, "message": "unknown function 'str_mach'", "hint": "usage: str_match(field, 'v')", "suggestions": ["str_match", "str_match_ignore_case"] } ``` The error body gains two optional fields, `hint` and `suggestions` (omitted when unset — existing clients see no change). Agents retry from error text; suggestion quality directly determines rounds-to-answer. ## Design - **No duplicated facts, fewer tokens than before.** `message` names the problem; `suggestions` is the only home for candidates; `hint` appears only with non-inferable info (a usage example, a UDS explanation, or a fallback when nothing similar was found — small schemas get the field list, wide schemas get pointed at the schema endpoint); `error_detail` is dropped on successful enrichment. The enriched error is smaller than the raw engine error it replaces. - **Wire format unchanged.** Candidates are embedded at the producer sites in the same textual shape DataFusion's Display uses ("No field named X. Valid fields are a, b."); parsing, ranking and formatting happen once at the HTTP edge (`core::error_suggest`, used by `map_error_to_http_response`). Mixed-version clusters are unaffected. - **Real schema, not the engine's view.** DataFusion only sees the pruned scan schema, so its valid-fields list is misleading (usually just `_timestamp`). The `_search` error path swaps it for the streams' actual schema fields before mapping; the typed `FieldNotFound` mapping no longer discards `valid_fields`; the validate path (including UDS violations) embeds real candidates at the producer. - **Ranking**: hand-rolled Levenshtein (no new dependency) + a prefix-distance rule so `satus` recalls both `status` and `status_code`; top 3. - **Function candidates**: the `DEFAULT_FUNCTIONS` UDF registry (with its own usage strings) + a static list of common SQL functions, with hand-kept signatures for the ones agents misuse most (`histogram`, `date_bin`, `date_format`, `approx_percentile_cont`, `spath`, `to_timestamp_micros`). - **Bug fix in passing**: `ErrorCodes::from_json` now round-trips codes 20011–20013 (`InvalidParams`, `RatelimitExceeded`, `SearchHistogramNotAvailable`) instead of degrading them to `ServerInternalError` when crossing nodes. ## Testing - 10 unit tests on the enrichment module (parsing both message shapes incl. backticked/qualified idents, suggestion ranking, prefix recall, UDS hint, no-match fallbacks, no-duplication contract) + round-trip tests for the new `from_json` codes. - E2E against a local instance: field typo → `suggestions: ["service"]`; function typo → usage example inline; unrelated name → field-list fallback hint; all responses shorter than the previous raw errors. - `cargo check --workspace --tests`, clippy, fmt clean. |
||
|
|
5478a2a3d7 |
ci: fix ENT e2e gate false failures (matching branch, stale run, cancelled) (#13373)
## In plain words The ENT e2e gate has been posting **false "🚫 Needs Review" failures** on real PRs. None of these were actual test failures — three separate bugs. (An earlier fix on #13284 was lost when that PR was recreated as #13318 without the workflow change, so this re-applies them cleanly on their own branch.) ## The three fixes | # | Bug | Symptom | Fix | |---|-----|---------|-----| | 1 | Always built against ENT **`main`** | Cross-repo feature PRs (e.g. Workflows v1) failed to **compile** — `cannot find function add_workflow` — because the enterprise code lives on the matching ENT branch, not main | Resolve a **same-named ENT branch** and build against it if it exists, else `main` (mirrors ENT's own `playwright.yml`) | | 2 | Correlation grabbed **stale runs** | Gate "completed" in ~3s reporting a **hours-old** run's failure for the same PR | Stamp dispatch time; only accept a run **created at/after** it, newest first | | 3 | `cancelled` treated as failure | A newer push superseded a run (engine `cancel-in-progress`) → false "specs failed" comment | Treat `cancelled`/`skipped`/empty as **neutral** — defer to the newer run, don't comment or fail | Only a genuine `failure`/`timed_out` now posts a comment or fails the gate. ## Notes - Pure CI, no AI. `ent-e2e-gate.yml` only. - Not a required check, so this doesn't block anything — it just stops the false-red noise. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
9d70e0e905 |
feat(synthetics): private locations — check-form picker, agent identity, install flow (#13308)
Design at: https://github.com/openobserve/designs/tree/main/synthetics |
||
|
|
d6c4c073d5 |
fix: UX for o2-ai (#13192)
resolves https://github.com/openobserve/o2-ai/issues/134 --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai> |
||
|
|
cbaf6042fb |
fix(navbar): prevent left-rail selection jumping to wrong tile on load (#13332)
Config APIs resolve after mount and insert/remove menu tiles in linksList, shifting the active tile. The selection pill's ResizeObserver never fires because the flex-constrained list doesn't resize, leaving the pill over the wrong tile (e.g. Dashboards while on Streams). - Gate the rail behind menuReady so it paints once its item list is settled, avoiding config-driven pop-in and layout shift. - Re-measure the selection pill when the rail's items change. --------- Co-authored-by: ktx-vaidehi <134508096+ktx-vaidehi@users.noreply.github.com> Co-authored-by: ktx-vaidehi <vaidehi.akhani@kiara.tech> |
||
|
|
f5114e5646 |
fix: agent-signals repopulate signals reliably; scope UI to LLM streams (#13348)
Companion to the o2-enterprise change. On a live instance the Agent Behavior/Graph views were empty because the rollup never re-processed the agent trace streams, and the stream pickers offered non-LLM streams. service_graph/processor.rs — discovery gap: the rollup discovered streams from a usage-windowed query, falling back to the schema cache only when usage was ENTIRELY empty. So any stream that dropped out of the current window's usage (producer paused, bursty ingest) was silently skipped forever on a busy instance — exactly how the agent streams went dark. Replace the all-or-nothing fallback with a union: usage-active streams ∪ every schema-cache trace stream (deduped). Idle windows are cheap no-ops, so this doesn't widen the worst case. agent_signals/processor.rs — always-on + stream-level LLM gate: drop the removed O2_AGENT_SIGNALS_ENABLED check, and add an early return that skips streams whose schema has no gen_ai_operation_name (mirrors the service-graph has_gen_ai gate) so non-LLM streams cost nothing. Thread has_agent_id into the SQL builders for the schema-gated agent-id predicate. AgentGraphPage/AgentBehaviorPage.vue — filter the stream picker to LLM streams (settings.is_llm_stream !== false), matching LLM Insights / Sessions. A plain service trace stream has no agents or signals to show here. |
||
|
|
e0fe62a9a0 | fix: traces page default flame graph and drag-drop option added (#13347) | ||
|
|
f1ffc974d7 | fix: stream page refresh, loading when delete and org dropdown update when new org added (#13369) | ||
|
|
f6560d7d02 |
refactor: decouple search from core (#13338)
## Summary - extract search orchestration from core into the `search_service` crate - keep the existing low-level `search` crate and directory names unchanged - extract usage reporting and audit services into dedicated crates - replace global async function pointers with narrow publisher traits - keep compatibility re-exports while updating workspace dependencies and feature propagation Companion enterprise PR: https://github.com/openobserve/o2-enterprise/pull/2229 ## Validation - `cargo check --workspace` - `cargo check -p search --tests` - `cargo test -p search_service --lib` (184 passed) - enterprise non-release build with the paired `o2-enterprise` manifest - `cargo fmt --all -- --check` - `git diff --check` |
||
|
|
47d92191c0 |
fix: apply threshold if the search event type is alert (#13355)
Ref - https://github.com/openobserve/openobserve/issues/13353 |
||
|
|
4b4598074f |
feat: trace/session evals (#13206)
- **add session and travel level evals fix quality page to show scoped scores improve quality page to allow drill down of scores improve the quality page UI to make it more indicative of health of agents.** - **Fix Quality dashboard runs, show agent ids** - **nats at least once delivery semantics + quality runs page changes** - **feat(evaluations): improve online evaluation workflows** --------- Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai> |
||
|
|
289ef51df4 |
feat: add agent_options.mode=partition to _search (collected partitioned execution) (#13360)
Design at: #13360 ## What `_search` gains `agent_options.mode` (`default` | `partition`, default `default`). Follow-up to #13343 in the Agent query-optimization (AX) track. ```json { "query": { "sql": "...", "start_time": ..., "end_time": ... }, "agent_options": { "mode": "partition", "output_format": "csv" } } ``` - `default`: current behavior, byte-for-byte unchanged — single search through the result cache path. - `partition`: runs the SSE-era backend partition loop (the `_search_stream` executor) and collects its event stream into this one response: partitions are scanned one by one, the scan stops early once enough rows are collected, and aggregation queries accumulate streaming-aggs cache per partition. ## Why Agent/MCP clients are request-response and cannot consume SSE, so they never benefited from the partitioned execution built for the UI. `partition` mode exposes that engine capability through the plain `_search` response: early termination cuts scanned bytes for top-n queries, and per-partition execution means exploratory queries with shifting time windows (the typical agent workload) hit progressively accumulated cache instead of invalidating a monolithic entry. `default` mode is deliberately kept (not replaced) so the two paths can be compared against each other — the partitioned collector is new, and the classic path serves as its correctness baseline. ## Design - **No changes to the streaming internals.** `streaming::collect` (new module) spawns the existing `process_search_stream_request` with its own mpsc channel and folds the events: plain queries append per-partition hit pages and sum scan counters; streaming-aggs events carry progressively merged state, so each replaces its predecessor while counters keep accumulating; `function_error` dedups, `is_partial` widens. This mirrors the established pattern multi-stream search already uses internally. - **Cancellation for free**: dropping the receiver (client disconnect) makes the partition loop stop on its next send. - `search_partition_mode()` is the single public entry: defaults `search_type`, parses the SQL once to derive the partition scan direction from `ORDER BY`, runs the collector, and attaches the `max_query_range` clamp note exactly like the cache path does. HTTP-layer concerns (URL param parsing) stay in the handler. - SQL parse errors now flow through the handler's common error arm (metrics reporting included) instead of an early return. ## Testing - Unit tests for the fold semantics: page append + counter sums, streaming-aggs replace-keep-counters, partial-flag widening + error dedup. - E2E against a local instance (2000 records): identical query in both modes returns **byte-identical hits** for detail queries (where + order by desc) and **identical row sets** for aggregations (group by + count/avg); `partition` composes with `output_format=csv`; unknown-field errors return the same 400/20004 in both modes. - Known limitation of the local run: data volume produced a single partition, so multi-partition early termination and per-partition streaming-aggs accumulation are exercised by unit tests and shared SSE code paths, not by the e2e. - `cargo check --workspace --tests`, clippy (no new warnings), fmt clean. |
||
|
|
f22b9c8a2d |
chore(deps): bump dompurify from 3.4.11 to 3.4.12 in /web (#13357)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.11 to 3.4.12. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/cure53/DOMPurify/releases">dompurify's releases</a>.</em></p> <blockquote> <h2>DOMPurify 3.4.12</h2> <ul> <li>Fixed an issue where a hook would not get called for custom elements, thanks <a href="https://github.com/Rikuxx0"><code>@Rikuxx0</code></a></li> <li>Hardened the handling of hooks removing elements, <a href="https://github.com/mkrause-bee360"><code>@mkrause-bee360</code></a></li> <li>Added support for a few new SVG attributes, thanks <a href="https://github.com/cbn-falias"><code>@cbn-falias</code></a> & <a href="https://github.com/Develop-KIM"><code>@Develop-KIM</code></a></li> <li>Hardened the handling of declarative partial updates</li> <li>Updated the documentation is several spots, README, wiki, etc.</li> <li>Bumped several dependencies where possible</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/cure53/DOMPurify/commit/a9ca1e537422319a557a9a2aa61f003b23b4a197"><code>a9ca1e5</code></a> release: 3.4.12 (<a href="https://redirect.github.com/cure53/DOMPurify/issues/1537">#1537</a>)</li> <li>See full diff in <a href="https://github.com/cure53/DOMPurify/compare/3.4.11...3.4.12">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/openobserve/openobserve/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
587089a01c |
chore(deps-dev): bump immutable from 5.1.5 to 5.1.9 in /web (#13359)
Bumps [immutable](https://github.com/immutable-js/immutable-js) from 5.1.5 to 5.1.9. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/immutable-js/immutable-js/releases">immutable's releases</a>.</em></p> <blockquote> <h2>v5.1.9</h2> <h2>What's Changed</h2> <ul> <li>fix(List): preserve undefined values when grown past 32 elements by <a href="https://github.com/spokodev"><code>@spokodev</code></a> / <a href="https://github.com/jdeniau"><code>@jdeniau</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2235">immutable-js/immutable-js#2235</a> (originated from <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2230">immutable-js/immutable-js#2230</a> )</li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/immutable-js/immutable-js/compare/v5.1.8...v5.1.9">https://github.com/immutable-js/immutable-js/compare/v5.1.8...v5.1.9</a></p> <h2>v5.1.8</h2> <h2>What's Changed</h2> <ul> <li>fix(List): guard oversized bounds in setListBounds. Fixes CVE <a href="https://github.com/immutable-js/immutable-js/security/advisories/GHSA-v56q-mh7h-f735">https://github.com/immutable-js/immutable-js/security/advisories/GHSA-v56q-mh7h-f735</a></li> <li>perf(Map): index large hash-collision buckets for faster lookups. Fixes CVE <a href="https://github.com/immutable-js/immutable-js/security/advisories/GHSA-xvcm-6775-5m9r">https://github.com/immutable-js/immutable-js/security/advisories/GHSA-xvcm-6775-5m9r</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/immutable-js/immutable-js/compare/v5.1.7...v5.1.8">https://github.com/immutable-js/immutable-js/compare/v5.1.7...v5.1.8</a></p> <h2>v5.1.7</h2> <h2>What's Changed</h2> <ul> <li>fix(Repeat): lastIndexOf returned size instead of size - 1 by <a href="https://github.com/chatman-media"><code>@chatman-media</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2227">immutable-js/immutable-js#2227</a></li> </ul> <h2>internal</h2> <ul> <li>Backport tests from 6.x branch by <a href="https://github.com/jdeniau"><code>@jdeniau</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2199">immutable-js/immutable-js#2199</a></li> <li>fix(IndexedCollection): <code>has(index)</code> on a lazy <code>Seq</code> of unknown size now checks index existence instead of searching for a value equal to the index by <a href="https://github.com/jdeniau"><code>@jdeniau</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2203">immutable-js/immutable-js#2203</a></li> <li>Better type for reduce if not ininitial value is given by <a href="https://github.com/jdeniau"><code>@jdeniau</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2205">immutable-js/immutable-js#2205</a></li> <li>Backport test from <a href="https://redirect.github.com/immutable-js/immutable-js/issues/2193">#2193</a> by <a href="https://github.com/jdeniau"><code>@jdeniau</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2207">immutable-js/immutable-js#2207</a></li> <li>backport tests from 6.x by <a href="https://github.com/jdeniau"><code>@jdeniau</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2213">immutable-js/immutable-js#2213</a></li> <li>Firefox link to non-French page by <a href="https://github.com/jdeniau"><code>@jdeniau</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2219">immutable-js/immutable-js#2219</a></li> <li>Bump esbuild and <code>@size-limit/preset-small-lib</code> by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2217">immutable-js/immutable-js#2217</a></li> <li>backport tests from <a href="https://redirect.github.com/immutable-js/immutable-js/issues/2210">#2210</a> by <a href="https://github.com/jdeniau"><code>@jdeniau</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2214">immutable-js/immutable-js#2214</a></li> <li>Bump shell-quote from 1.8.2 to 1.8.4 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2211">immutable-js/immutable-js#2211</a></li> <li>Bump <code>@tootallnate/once</code> from 2.0.0 to 2.0.1 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2190">immutable-js/immutable-js#2190</a></li> <li>Bump minimatch from 9.0.5 to 9.0.9 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2189">immutable-js/immutable-js#2189</a></li> <li>Bump <code>@codemirror/theme-one-dark</code> from 6.1.2 to 6.1.3 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2168">immutable-js/immutable-js#2168</a></li> <li>Bump form-data from 4.0.5 to 4.0.6 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2220">immutable-js/immutable-js#2220</a></li> <li>Bump typescript-eslint from 8.33.0 to 8.61.1 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2222">immutable-js/immutable-js#2222</a></li> <li>Bump <code>@rollup/plugin-commonjs</code> from 28.0.2 to 29.0.3 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2224">immutable-js/immutable-js#2224</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/chatman-media"><code>@chatman-media</code></a> made their first contribution in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2227">immutable-js/immutable-js#2227</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/immutable-js/immutable-js/compare/v5.1.6...v5.1.7">https://github.com/immutable-js/immutable-js/compare/v5.1.6...v5.1.7</a></p> <h2>v5.1.6</h2> <h2>What's Changed</h2> <ul> <li>fix(reverseFactory): read reversedSequence.size in __iterator instead of this by <a href="https://github.com/jdeniau"><code>@jdeniau</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2196">immutable-js/immutable-js#2196</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/immutable-js/immutable-js/blob/main/CHANGELOG.md">immutable's changelog</a>.</em></p> <blockquote> <h2>5.1.9</h2> <ul> <li>fix(List): a <code>List</code> grown past 32 elements while all its values are <code>undefined</code> no longer reads those values back as <code>null</code> (affected <code>get</code>, iteration, <code>toArray</code>, <code>equals</code> and <code>hashCode</code>)</li> </ul> <h2>5.1.8</h2> <ul> <li>fix(List): guard oversized bounds in setListBounds. Fixes CVE <a href="https://github.com/immutable-js/immutable-js/security/advisories/GHSA-v56q-mh7h-f735">https://github.com/immutable-js/immutable-js/security/advisories/GHSA-v56q-mh7h-f735</a></li> <li>perf(Map): index large hash-collision buckets for faster lookups. Fixes CVE <a href="https://github.com/immutable-js/immutable-js/security/advisories/GHSA-xvcm-6775-5m9r">https://github.com/immutable-js/immutable-js/security/advisories/GHSA-xvcm-6775-5m9r</a></li> </ul> <h2>4.3.9</h2> <ul> <li>fix(List): guard oversized bounds in setListBounds. Fixes CVE <a href="https://github.com/immutable-js/immutable-js/security/advisories/GHSA-v56q-mh7h-f735">https://github.com/immutable-js/immutable-js/security/advisories/GHSA-v56q-mh7h-f735</a></li> <li>perf(Map): index large hash-collision buckets for faster lookups. Fixes CVE <a href="https://github.com/immutable-js/immutable-js/security/advisories/GHSA-xvcm-6775-5m9r">https://github.com/immutable-js/immutable-js/security/advisories/GHSA-xvcm-6775-5m9r</a></li> </ul> <h2>5.1.7</h2> <ul> <li>fix(Repeat): lastIndexOf returned size instead of size - 1 by <a href="https://github.com/chatman-media"><code>@chatman-media</code></a> in <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2227">immutable-js/immutable-js#2227</a>. Fixes CVE <a href="https://github.com/immutable-js/immutable-js/security/advisories/GHSA-wf6x-7x77-mvgw">CVE-2026-29063 </a></li> <li>fix(IndexedCollection): <code>has(index)</code> on a lazy <code>Seq</code> of unknown size now checks index existence instead of searching for a value equal to the index <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2203">#2203</a></li> <li>[TypeScript]: <code>reduce</code>/<code>reduceRight</code> without an initial value now infer the result type from the collection's values when the reducer returns a value (e.g. <code>list.reduce((a, b) => a + b)</code> infers <code>number</code>), matching <code>Array#reduce</code>. Previously an explicit type argument was required. <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2205">#2205</a></li> </ul> <h2>5.1.6</h2> <ul> <li>fix(reverseFactory): read <code>reversedSequence.size</code> in <code>__iterator</code> instead of this <a href="https://redirect.github.com/immutable-js/immutable-js/pull/2196">#2196</a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/immutable-js/immutable-js/commit/329f7a680efa262c310b938a343295880eefe4fc"><code>329f7a6</code></a> 5.1.9</li> <li><a href="https://github.com/immutable-js/immutable-js/commit/21fabd92bc6cd6771918fc966004034fc10a06e0"><code>21fabd9</code></a> changelog</li> <li><a href="https://github.com/immutable-js/immutable-js/commit/009164facb3c69870c6ad4c6472b1baeb02fcdf7"><code>009164f</code></a> Merge pull request <a href="https://redirect.github.com/immutable-js/immutable-js/issues/2235">#2235</a> from immutable-js/fix/avoid-null-when-setsize33</li> <li><a href="https://github.com/immutable-js/immutable-js/commit/5b65bfbd583472eaa9686137a61db2a29d63cd36"><code>5b65bfb</code></a> fix(List): preserve undefined values when grown past 32 elements</li> <li><a href="https://github.com/immutable-js/immutable-js/commit/50bf39e94105f83f1132cce02b9ee6c45cc7d9ca"><code>50bf39e</code></a> Update CHANGELOG.md for versions 5.1.8 and 4.3.9</li> <li><a href="https://github.com/immutable-js/immutable-js/commit/6496539bd1e9dfa75ce11b053e7d70d79e9ac6f7"><code>6496539</code></a> 5.1.8</li> <li><a href="https://github.com/immutable-js/immutable-js/commit/808a83a071c9e22b8199ac256dc7e6e764198aac"><code>808a83a</code></a> Merge commit from fork</li> <li><a href="https://github.com/immutable-js/immutable-js/commit/e51d49fc612ded5ec4dfb94ff294d22074269b0f"><code>e51d49f</code></a> perf(Map): index large hash-collision buckets for faster lookups</li> <li><a href="https://github.com/immutable-js/immutable-js/commit/25c58b094f112dc32e9b0bca79c84f448d0d2a38"><code>25c58b0</code></a> fix typescript in tests</li> <li><a href="https://github.com/immutable-js/immutable-js/commit/a1a1ee412dcaa380ab325196283d06594ffe4b84"><code>a1a1ee4</code></a> Merge commit from fork</li> <li>Additional commits viewable in <a href="https://github.com/immutable-js/immutable-js/compare/v5.1.5...v5.1.9">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/openobserve/openobserve/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
5d56f7c4d1 | fix: initialize agent options in enterprise searches (#13361) | ||
|
|
e236c7e653 |
refactor: extract database layer into db crate (#13340)
## Summary - extract persistence, cache, watcher data access, and DB service modules from openobserve-core into a standalone workspace db crate - keep application orchestration that depends on search, organization provisioning, and other Core services behind the existing Core db facade - preserve existing call paths through re-exports while making the dependency direction openobserve-core -> db - move HTTP error mapping back to the Core/API boundary so db has no direct axum dependency - avoid provider/provisioner callback traits and function-pointer hooks ## Validation - cargo fmt --all - cargo check --all-targets - cargo check -p db --all-targets - Enterprise workspace: cargo check --all-targets --offline - Enterprise workspace: cargo check -p db --all-targets --features enterprise --offline Companion Enterprise manifest PR: openobserve/o2-enterprise#2230. |
||
|
|
2475602928 | fix: UI issues of missing imports and config spacing (#13331) | ||
|
|
e8f6c6846d |
fix(pipelines): make Pipeline Destinations search null-safe (#13345)
## What Fixes broken search on the **Pipeline Destinations** page (Management > Pipeline Destinations — "External targets for pipeline output"). Typing any query left the full list visible; search filtered nothing. ## Root cause Destinations without a type/URL/method render as **"—"** in the list and have those fields as `null`. `filterData()` called `.toLowerCase()` on them directly: ```js rows[i]["destination_type_name"].toLowerCase() // null → TypeError ``` Any search term that didn't match such a row's name reached this line mid-iteration and threw a `TypeError`. The exception aborted the `visibleRows` computed, which then kept its last value — the **full unfiltered list** — so search appeared to do nothing regardless of the query. A random non-matching string (the common case) triggers it every time, since it forces evaluation past every null-type row. ## Fix Guard each field with a `|| ""` fallback before `toLowerCase()` in `filterData()`. ## Test Added a regression test covering a **non-matching** query over a row with null `type`/`url`/`method` (this is what reproduces the crash — a matching-name term short-circuits the `||` before touching the null field). Verified it **fails without the source fix** and **passes with it**. Full spec: 36/36 passing. Fixes openobserve/o2-enterprise#2234 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
260d3bb634 |
feat(mcp): OAuth 2.0 sign-in (RFC 9728) + fix cross-org RBAC bypass and expired-JWT acceptance (#13344)
## What Adds **MCP OAuth 2.0 sign-in** support (RFC 9728 Protected Resource Metadata) so MCP clients — `claude mcp add`, Cursor, etc. — can discover the Dex authorization server and complete an OAuth flow against an OpenObserve MCP endpoint. While wiring this up, a security review of the shared auth path found **two authentication/authorization defects**, both fixed here. All changes are in OSS; the auth code paths are `#[cfg(feature = "enterprise")]` (Dex JWT validation + OpenFGA authorization), so the security impact is on the enterprise build. Tracking issue: **openobserve/o2-enterprise#2232**. ## Why - MCP clients had no way to discover the auth server, so OAuth sign-in couldn't complete. ## Changes ### MCP OAuth (RFC 9728) - `OAuthProtectedResourceMetadata` type + handler; public `.well-known/oauth-protected-resource` routes registered before auth nesting so discovery stays unauthenticated. - `WWW-Authenticate: resource_metadata=...` advertised on MCP 401 (mcp-path only), pointing clients at the per-org protected-resource metadata. - Return 404 for protected-resource metadata when Dex is disabled (don't advertise an unreachable auth server). - Header-injection hardening: the org id reflected into the `WWW-Authenticate` challenge is charset-allowlisted and **rejected** (not escaped), so a crafted org id can't append a second challenge. - MCP-path detection tightened (matches the org/`mcp` path segment, so a stream literally named `mcp` doesn't false-positive) and base_uri duplication fixed. |
||
|
|
39b2b3ca77 |
feat: add agent_options.output_format (csv/md_table) to _search response (#13343)
Design at: #13343 ## What `_search` gains an optional `agent_options.output_format` parameter (`json` | `csv` | `md_table`, default `json`). When set to `csv`/`md_table`, the response's `hits` array is rendered as a single compact string block: ```json { "query": { "sql": "...", "start_time": ..., "end_time": ... }, "agent_options": { "output_format": "csv" } } ``` Response then carries three new optional fields (never serialized otherwise): `format` (the format actually used), `data` (the formatted block), `advisory` (note about server-side formatting decisions), with `columns` reporting the column order and `hits` emptied. ## Why Agent/MCP consumers pay per token, and a JSON hits array repeats every key on every row — the repeated keys, not whitespace, are the dominant cost (minify only gets to ~78%). csv removes them: ~40% fewer tokens than minified JSON on typical log results, letting the same context budget hold ~1.7x more rows. `md_table` (~8% more than csv) aligns better for small result sets. This is the first piece of the Agent query-optimization (AX) track; `agent_options` is the extension point for the follow-ups (token-budget pagination, query budget/continuation). ## Design - **Serialization edge only**: formatting runs in the `_search` handler after `SearchService::cache::search` returns. Engine, partition scheduling and result cache always see original JSON hits; cached entries never contain formatted strings, and the cache key is unchanged, so a UI (json) query and an agent (csv) query share the same cache entry. - **Model-friendly escaping**: newlines inside cells become a literal `\n` so no record ever spans physical lines (multi-line RFC 4180 quoted cells are a known LLM parsing hazard); commas/quotes still get standard csv quoting so rows stay machine-parsable. `md_table` escapes `|`. Nested objects/arrays are minified JSON in the cell. - **Column order**: server-provided `columns` when present, otherwise first-seen key order with `_timestamp` promoted to the front. - **Sparse fallback**: results with >= 20 columns and > 50% empty cells (typical `select *` on a wide stream) fall back to ndjson — per-row keys are cheaper and less error-prone there than a mostly-empty grid. The fallback is announced via `advisory`, never silent. Non-object rows fall back the same way. - **Zero impact when unset**: requests without `agent_options` produce byte-for-byte identical responses. The remaining 9 files changed are mechanical `agent_options: None` additions to internal `Request` struct literals. - The `_search` `x-o2-mcp` tool description now mentions the option, and `SearchAgentOptions` flows into the generated OpenAPI/MCP tool schema automatically. ## Testing - 9 unit tests in `agent_format.rs`: json no-op, csv basics + `_timestamp` promotion, newline/comma/quote/nested escaping, missing/null cells, server column order, md_table pipe escaping, sparse fallback, non-object fallback, empty hits. - Verified against a running local instance: default path unchanged (no new keys), csv/md_table output with all escaping cases, sparse stream (32 cols, 90% empty) falls back to ndjson with advisory, invalid `output_format` returns 422 listing valid variants, `SearchAgentOptions` present in `/api-doc/openapi.json`. - `cargo check --workspace`, `cargo clippy -p openobserve-api-query`, `cargo fmt` clean. |
||
|
|
be31b47172 |
chore: update translations from en-US.json (#13154)
Auto-generated translation updates from the English source file (`web/src/locales/languages/en-US.json`). 🤖 Generated with automated translation workflow Co-authored-by: github-merge-queue[bot] <118344674+github-merge-queue[bot]@users.noreply.github.com> Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com> |
||
|
|
d015f1c748 |
feat(web): add loongcollector option in custom log ingestion (#13258)
This PR adds LoongCollector, **Alibaba’s self-developed log collector**, as a explicit custom log ingestion choice in the user interface. The LoongCollector log collection configuration as follows: ilucky@ubuntu:/.../loongcollector-3.3.5$ cat conf/continuous_pipeline_config/local/collector.yaml > enable: true inputs: \- Type: input_file FilePaths: - /tmp/*.log processors: \- Type: processor_json SourceKey: content flushers: \- Type: flusher_http RemoteURL: http://192.168.139.3:5080/api/default/default/_json Method: POST Headers: Authorization: Basic cm9vdEBleGFtcGxlLmNvbTpvMm9pX1hVcHBBeUdVd0J4VHZHbmpYY2c1eWJGblZFNFduak9D Compress: gzip <img width="2926" height="1194" alt="image" src="https://github.com/user-attachments/assets/ae2a5af6-ea03-4a41-833a-c53e7f692f9d" /> <img width="2932" height="990" alt="image" src="https://github.com/user-attachments/assets/1bed13bb-ec40-4200-a71a-1229a6884af6" /> <img width="2932" height="1196" alt="image" src="https://github.com/user-attachments/assets/79e54f4c-1c67-46c5-8fac-97506907da5e" /> |
||
|
|
010f572256 |
feat(cloud): manage organization AI credits (#13282)
## Summary - add shared lifetime AI credit limits and persisted per-organization usage tracking - expose used and total AI credits in organization management with an editable limit dialog - keep router quota caches synchronized and delegate billing and contract exhaustion policy to enterprise - clean up the redundant quota table only in non-cloud builds while preserving cloud credit data ## Companion PR - https://github.com/openobserve/o2-enterprise/pull/2208 ## Testing - cargo check --features cloud - cargo test -p openobserve-core --features cloud trial_quota::tests --lib - cargo test -p infra --features cloud m20260717_000001_drop_trial_quota_usage_for_non_cloud::tests --lib - cargo test -p infra m20260717_000001_drop_trial_quota_usage_for_non_cloud::tests --lib - cargo fmt checks for changed Rust packages - npm run type-check - 200 focused frontend unit tests covering organization management, billing usage, organization services, and required numeric input - live organization-management verification with per-org 0 used / 1,000 total values |
||
|
|
21d0907342 |
fix(logs): redesign log patterns UI (#13337)
## What Redesign of the log patterns UI. - **`PatternCard`** reworked: template tokens, a badges row (trend / rarity / anomaly), and inline frequency + percentage replace the old fixed count and action columns. - **`PatternVolumeCell`** (new) + **`usePatternVolume`** (new) render per-pattern volume sparklines. - **`PatternDetailsDialog`** now owns the include / exclude / create-alert actions that previously lived on each card. - **`patternUtils`** / **`usePatternActions`** extended to back the above. ## Test plan - `web` unit tests for the touched areas: 356 passing, 0 failing (`plugins/logs/patterns`, `plugins/logs/data-table`, `SearchResult`, `FieldValuesPanel`). - New spec coverage for `PatternVolumeCell`, `usePatternVolume`, and `patternUtils`. - `npm run type-check` clean. - `lint:design`, `lint:tokens`, `lint:token-purity` all clean. ## Notes Rebased onto latest `main`. Five conflicts came from main's repo-wide type-check pass (#13174), which made `OIcon`'s `name` prop required. Main's fix (`name=""` + slot) was kept in `CodeQueryEditor.vue`, `FieldValuesPanel.vue`, and `CellActions.vue`; in `PatternCard.vue` the surrounding block was removed by this redesign, so the deletion stands. |
||
|
|
899bb681a8 |
test(e2e): optimize/fix alpha1 Alerts, SDR & Pipelines shards (operator select scoping + editor/nav/data-flow races + ingestion 5xx resilience) (#13336)
## What
Consolidated stabilization of the **Alerts**, **SDR** and **Pipelines**
shards of the
alpha1 cloud E2E suite (`playwright_alpha1.yml`) to green — the shards
still failing
after the earlier per-module stabilization PRs merged. Rebased on
`main`.
Across these shards the original run had: **Alerts** 1 hard fail,
**SDR** 1 hard fail +
1 flake, **Pipelines** 1 hard fail + several flakes. Root causes were an
ambiguous
operator-select selector plus cloud data/UI-readiness races (editor &
node-sidebar mount,
hover-flyout nav, freshly-ingested destination streams lagging their
list/table) and
transient backend 5xx on ingestion.
**No `waitForTimeout` added as a fix, no `force:true`, no
`.first()`/`.nth()` band-aids,
no retry-count bumps to hide failures, no weakened assertions. No
worker-count,
parallelism, playwright-config or CI/yml changes** — test code only.
## Root cause & fixes
**Alerts**
1. **Operator select — strict-mode violation** (`alerts-e2e-flow`, state
management).
The operator control is an OSelect that renders an aria-hidden native
`<select><option>=</option>` alongside the visible popover item, so the
unscoped
`getByText('=', {exact})` matched **two** nodes. Scope the option click
to
`[data-test="alert-conditions-operator-select-popover"]` +
`getByRole('option')`
(excludes the aria-hidden native select, mirrors the working
`alertCreationWizard.js`
pattern), and gate on the popover open/close instead of the trailing
`waitForTimeout`s.
(`alertManagement.js`)
**SDR**
2. **Stream Detail button — 45s timeout under load**
(`multipleSDRPatterns` @slow,
`ingestionTimeHash`). `openStreamDetail` resolved the button by the
icon's title text,
which the OTable can render after the name cell, and the retry only
re-clicked a
possibly-detached row without re-fetching the list. Resolve by the
stable
`data-test="log-stream-schema-btn"` and reload + re-search the streams
list between
attempts, keyed to the real "detail sidebar open" signal
(`schema-update-settings-button`). (`streamAssociationPage.js`)
**Pipelines**
3. **Editor / node-sidebar mount race** (`selectStream`, all pipeline
flows). A bare click
on the stream-input button dead-waited the 45s action timeout when the
VueFlow editor +
NodeSidebar missed the first render under concurrent load. Moved a
**non-destructive**
mount guard into `addPipeline`: after clicking Add, if the button hasn't
rendered and
we're still on the list (add button visible), re-click to re-trigger
navigation — no
`page.reload()` (a reload of the editor route re-runs the auth callback
on cloud and
stalls the shard). (`pipelinesPage.js`)
4. **`openPipelineMenu` — hover-flyout nav timeout.** Routed through the
left-nav hover
flyout, which self-closes on settle and, under load, burned ~30s
retrying to open before
its goto fallback fired — tipping long condition tests over the 180s
test timeout.
Promoted the already-proven `goto` to the primary path and skipped the
flyout (it adds
no coverage here). (`pipelinesPage.js`)
5. **Destination-stream data-flow / render latency**
(`pipeline-dynamic`, query-source
flow). Extended `openTimestampMenu`'s re-search loop (destination stream
indexing can
lag past the old budget) and `waitForQueryNodeVisible` 30s→45s
(query-node canvas render
lags under full-shard load) — both within the CI test timeout, both exit
early on the
real signal. (`pipelinesPage.js`)
**Ingestion resilience (Pipelines + shared helper)**
6. **Transient backend 5xx aborted ingestion.** `fetchWithRetry` only
retried thrown
network errors; a `503`/`502` is a "successful" fetch, so ingestion
threw on the first
one when the env returned transient 5xx during load spikes. Retry 5xx
with backoff in
both ingestion helpers — a persistent 5xx still surfaces after
`maxRetries`, so genuine
outages aren't masked. (`pipelinesPage.js`, `ingestionPage.js`)
## Validation
- **CI — Alerts / SDR / Pipelines green (alpha cloud):**
[Pipeline](https://github.com/openobserve/o2-enterprise/actions/runs/29809833252).
[SDR,
Alerts](https://github.com/openobserve/o2-enterprise/actions/runs/29771293789)
- **Original failing run:**
https://github.com/openobserve/o2-enterprise/actions/runs/29720987587
- **Local (real alpha cloud, `playwright-alpha1.config.js`):** each
previously-failing test
re-run to green — `pipeline-conditions.spec.js` @ `--workers=3` 6/6,
`pipeline-dynamic`
72 & 97, `pipelines:180` (query source) solo; Alerts operator flow and
SDR
`openStreamDetail` verified against alpha. 5xx-retry control flow
verified (2xx/4xx
unchanged, transient 503 recovers, persistent 503 still surfaces).
## Notes
- 4 files change (3 page objects + the shared ingestion helper). No
specs, shared
cleanup/setup, config, or workflow files touched.
- Any residual Pipelines tail is cloud latency / env backend health
(e.g. runs where the
env returns sustained 503s) — not test code; the durable lever there is
cross-shard
concurrency / env capacity, out of scope for this PR.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
7e17e85f42 |
feat: add in-memory queue backend (ZO_QUEUE_STORE=memory) (#13330)
Design at: #13329 ## Summary Adds a bounded, process-local, in-memory queue backend selected with `ZO_QUEUE_STORE=memory`, so queue-dependent features can run in local single-process deployments without a NATS server. The NATS backend itself is unchanged. An unset `ZO_QUEUE_STORE` resolves to `memory` in local mode and `nats` in cluster mode (per review suggestion); explicit values are honored, and `memory` is rejected in cluster mode during config validation. ## Changes - **Config**: new strict `QueueStore` enum (`nats`|`memory`, unknown values are a startup error, no silent fallback); new `ZO_MEMORY_QUEUE_MAX_SIZE_MB` (default 64 MB, 0 falls back to the default, converted to bytes during validation); `memory` + `ZO_LOCAL_MODE=false` fails at startup. The two remaining call sites that parse `ZO_QUEUE_STORE` through `MetaStore` are migrated (the third, in `cluster/nats.rs`, actually wants the cluster coordinator and is fixed separately in #13333). - **Queue abstraction**: `infra::queue::Message` is now a struct with a private per-backend ack handle; callers use only `message()`/`ack()`. The coordinator event consumer no longer matches `Message::Nats`. Topic-name normalization (`format_key`) is shared by both backends. - **Memory backend** (`src/infra/src/queue/memory.rs`): - one global accounted-memory budget across all topics (payload + fixed per-entry/per-topic overhead); over-limit publish returns `QueueFull`/`MessageTooLarge`; unacked messages are never evicted - at-least-once delivery within the process lifetime; FIFO for first delivery; unique per-delivery token so a stale ack cannot remove a newer delivery attempt - redelivery on message drop, receiver loss, or a fixed 30s visibility timeout (matches the NATS `ack_wait` default); `max_age` expiration measured from original publish time - `All`/`Last`/`New` deliver policies; one active consumer per topic; re-subscribe after receiver closure is supported - the memory path never initializes or connects to NATS - **Errors**: structured `QueueError` variants with byte counts in capacity errors. - **Metrics**: `queue_memory_used_bytes`, `queue_memory_limit_bytes`, `queue_messages`, `queue_publish_total`, `queue_redelivery_total`, `queue_message_expired_total`, `queue_oldest_message_age_seconds`. ## Testing - 17 unit tests for the memory backend (capacity/accounting, deliver policies, redelivery, visibility timeout and stale ack via paused Tokio time, max_age expiration, consumer lifecycle), 8 config-validation tests. - Manual server smoke test: local mode + memory + invalid NATS address boots healthy (`/healthz`, ingest, search OK; zero NATS log lines); cluster mode + memory is rejected at startup with a clear error. - Enterprise call sites (`o2_ratelimit`, super-cluster) use only the opaque `message()`/`ack()` API — no enterprise changes needed. ## Notes for reviewers - There is currently no OSS local-mode queue caller; this backend is enabling infrastructure for upcoming local-mode features. - `purge` keeps the existing no-op behavior in both backends; sequence-based purge semantics need a separate proposal. |
||
|
|
4d58a1efe4 |
build: add UI code quality checks and enhance linting processe (#13174)
chore: update package.json scripts for improved type-checking fix: adjust frontmatter regex to handle BOM characters refactor: streamline error handling in dashboard data conversion style: clean up comments and formatting in various files |
||
|
|
b1604cc7b6 |
test(workflows): e2e + API tests for Workflows (#13318)
Adds automated test coverage for the Enterprise-only **Workflows** feature (now merged to main). Clean branch off `main` — test files only, no feature-code churn. **UI (Playwright · `tests/ui-testing`)** - `pages/workflowsPages/workflowsPage.js` — page object (verified `data-test` selectors, Save-tooltip JS-click workaround, slow-list waits, enterprise-availability probe). - `playwright-tests/Workflows/workflows-crud.spec.js` — build/name validation, list + search. - `playwright-tests/Workflows/workflows-negative.spec.js` — negative + NFR sweep (long/unicode/emoji names, list latency, console/network hygiene). - `pages/page-manager.js`, `pages/apiCleanup.js` (`cleanupWorkflows()` + cascade), `playwright-tests/cleanup.spec.js` (`wf_auto_*` prefixes). - `.github/workflows/playwright.yml` — `Workflows` testfolder in the matrix. **API (pytest · `tests/api-testing`)** - `tests/workflows/test_workflows.py` — full REST surface (create/list/update/enable/test/history/errors/retry/delete) + validation, auth (401), cross-org. **Behaviour**: Enterprise-gated (skips on OSS where the feature is off); self-cleaning (`wf_auto_*`). Verified live: **11 Playwright + 13 pytest passing**. Paired with the ENT matrix PR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
2abb10e54a |
fix(dashboards): repair delete from the Favorites view (#13327)
Deleting a favorited dashboard failed or left ghost rows behind: 1. Bulk delete sent activeFolderId as the `?folder=` param. In the Favorites view that is the `__favorites__` pseudo-folder id, which the backend 404s on — so bulk delete never worked there for any dashboard. Favorites can also span folders, which one folder-scoped call could not cover. Group the selection by each row's real folder_id and issue one call per folder; a normal folder view collapses to the single request it always was. 2. Nothing pruned the favorites setting when a dashboard was deleted, so the Favorites view kept rendering the row from its stored label. Add removeFavorites() and call it after single and bulk delete, plus a self-heal on entering Favorites for deletions made elsewhere (another tab, the dashboard view). It deliberately does not revert on a failed write — the dashboard is already gone, so restoring the row would recreate the ghost the cleanup exists to remove. 3. Folder navigation is cache-first, and bulk delete never touched the store, so the deleted rows reappeared in their source folder until a manual refresh. Add evictDashboardsFromCache(), mirroring what deleteDashboardById already does for the single-delete path. Only ids the backend did not report as unsuccessful are evicted, so a partial failure keeps the surviving rows visible. Also snapshot the selection before reading the `dashboards` computed in bulk delete — that computed resets selectedIds as a side effect, so the new folder-grouping could otherwise have deleted nothing. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Abhay Padamani <141122205+ktx-abhay@users.noreply.github.com> |
||
|
|
c7871126c5 |
fix: In traces 'status' field was getting added as 'Span Status' in spans mode (#13294)
## What changed Removes the automatic migration of the `status` field to `span_status` in spans search mode, and passes the current `searchMode` to column definition generation so `status` is treated as a generic data column in spans mode instead of getting traces-mode special column rendering. Alongside this, the TenstackTable header actions area gets a hover-visibility fix and the old `.logs-table` CSS block for column actions is deleted in favour of the generic `group-hover:visible` approach. ## Why The previous code was conflating the `status` data field (a legitimate user-configurable column in spans mode) with the "Span Status" column definition that is meaningful only in traces mode. This meant any user who had `status` saved in their spans column preferences would have it silently renamed to `span_status`, which either broke the column or showed incorrect data. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
4ebf1616ee |
fix: hide browser and device insights for non-browser tests in MonitorRuns (#13292)
## What changed Hides browser/device-related UI elements in `MonitorRuns.vue` for non-browser synthetic tests (http, tcp, tls, ssh) and adds a "Duration by Location (Avg)" breakdown card as a protocol-appropriate replacement. The steps tab, browser/device filter dropdowns, browser/device table columns, and the Pass Rate by Browser/Device breakdown cards are now gated behind an `isBrowser` check. ## Why Non-browser protocol tests (http, tcp, tls, ssh) do not produce browser engine or device data. Showing empty or meaningless browser/device columns, filters, and insight cards for these tests was confusing. The monitor type is resolved on first data refresh via `syntheticsService.get()`, defaulting to `isBrowser = true` as a safe fallback. Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
6dfcb8a44a |
ci: remove TestDino from e2e workflows (#13326)
## What Removes **all TestDino integration** from the Playwright e2e CI workflows. ### Removed - **Reporting/upload to TestDino** — the `upload_testdino` job, the `UPLOAD_TO_TESTDINO` env/var, and all `TESTDINO_API_TOKEN` usages. - **Rerun optimization** — the `check_rerun` step and the `tdpw last-failed` `RERUN_MODE` dispatch. ### Files - `.github/workflows/playwright.yml` (−444) - `.github/workflows/playwright_regression.yml` (−350) - `.github/workflows/playwright-auto-rerun.yml` (stale notice line) - `tests/ui-testing/playwright.config.js` (comment reword only) ### Behavior change "Re-run failed jobs" no longer targets only the previously-failed tests — a re-run now runs the **full matrix job**. Native GitHub re-run-failed-*jobs* still works. ### Kept `report.json` / merge-reports generation is untouched — still consumed by the Kinora and OpenObserve reporters. ### Follow-up (after merge) Revoke `TESTDINO_API_TOKEN` (repo secret) + delete the `UPLOAD_TO_TESTDINO` repo variable, and revoke the token in the TestDino dashboard. Paired ENT PR uses the same branch `test/remove-testdino`. ### Validation `actionlint` clean (no new findings) and zero TestDino references remain. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
784459fcf4 | fix: login form migration (#13334) | ||
|
|
9ede45bbf7 |
fix: Agent Behavior signals (loop/failure taxonomy) + Agent Graph fixes (#13279)
## What
Adds **Agent Behavior signals** — a PB-safe rollup that surfaces two
behavioural questions the platform couldn't answer before: *is an agent
stuck in a loop?* and *why is it failing?* Plus a batch of Agent Graph /
AI Observability UX and correctness fixes found while building it.
Companion changes land in **o2-enterprise**
(`feat/agent-signals-enterprise-split`): the SQL builders, mappers,
config-driven failure taxonomy, the service-graph agent-classification
fix, and the RBAC route entry.
## Backend (agent-signals)
- Bounded-key rollup co-located in the service-graph job
(alert-manager-only, reuses its watermark + self-ingest). Groups only on
agent/tool/class — never trace_id — so it stays PB-safe.
- Config-driven **failure taxonomy** (rules as data, evolvable without
code) + config-driven error-detail columns; ancestor-agent resolution so
error spans attribute to the owning agent.
- Read API `GET /{org}/traces/agent_signals` (dual `#[cfg]`, reads the
derived `_agent_signals` stream) + RBAC route entry (enterprise
`route_permissions`) mapping it to `traces` read.
- OSS/enterprise split respected: pure SQL/mapping in enterprise, thin
gated I/O in OSS.
- Fix: `traces/latest` only narrows to a UUIDv7 trace_id's embedded time
when that time is inside the caller's window (fixes "trace not found"
for time-shifted/re-ingested traces).
## Frontend (AI Observability)
- New **Agent Behavior** page under Monitor: looping-agents +
failure-taxonomy tables, each row opening an actionable detail drawer
(real grouped error messages / worst-repeat traces), click-through to
Trace Details in a new tab.
- Agent-node **Behavior tab** on the Agent Graph node drawer (reuses the
same signals).
- Nav rename: LLM Insights → **Insights**, LLM Sessions → **Sessions**.
- **Agent** is the default scope across the AI pages, with the
Agent|Stream toggle placed consistently (left scope bar); explicit
URL/localStorage choices still win.
- Removed the duplicate in-table refresh on Sessions.
## Agent Graph fixes
- **Agent classification**: agents that also call tools now correctly
classify as `service_type: "agent"` (they glow), fixing a latent
precedence bug where the tool/model client-role overrode the agent role
and `is_real_service` forced agents to plain services. Rust
`classify_entity` brought in line with the (already-correct) TS twin.
- **Drag-to-pan restored**: the shared ChartRenderer armed
`dataZoomSelect` cursor unconditionally, hijacking drag away from roam
pan. Disabled for this graph (no dataZoom).
- **Nodes scale on zoom** (`nodeScaleRatio: 1`) so zooming enlarges
nodes/labels, not just spacing.
## Testing
- Enterprise unit tests: agent-signals SQL/mappers/config,
classification precedence, RBAC route resolution — all pass.
- FE: type-check + lint clean.
- Verified end-to-end on real re-ingested introspection data: taxonomy
unclassified rate ~100% → ~1–3%, agents resolved, both agents
classify/glow, trace-open works.
## Notes
- `Cargo.toml`/`Cargo.lock` and unrelated Slack-bot files were
intentionally excluded from the commits (local build-config drift).
---------
Co-authored-by: ktx-vaidehi <vaidehi.akhani@kiara.tech>
Co-authored-by: ktx-vaidehi <134508096+ktx-vaidehi@users.noreply.github.com>
|
||
|
|
36518e49c1 |
fix: workflows add on (#13323)
Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com> Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com> |
||
|
|
8655024324 |
fix: use cluster_coordinator instead of queue_store in nats register check (#13333)
## Problem
`nats::register_and_keep_alive()` gates node registration on
`cfg.common.queue_store`:
```rust
let meta_store: config::meta::meta_store::MetaStore = cfg.common.queue_store.as_str().into();
if cfg.common.local_mode || meta_store != config::meta::meta_store::MetaStore::Nats {
return Ok(());
}
```
This is the wrong config knob. Whether a node registers to the cluster
is decided by the **cluster coordinator** backend, not the queue backend
— the dispatcher in `cluster/mod.rs` already routes here based on
`cfg.common.cluster_coordinator`. With this check on `queue_store`,
setting `ZO_QUEUE_STORE` to a non-NATS backend while the cluster
coordinator is still NATS makes the node silently skip cluster
registration.
## Fix
Check `cfg.common.cluster_coordinator` instead of
`cfg.common.queue_store`, matching the dispatch logic in
`cluster/mod.rs`.
|
||
|
|
2be4fc627c |
feat(web): add nightingale option in custom metric ingestion (#13264)
This PR adds nightingale as a explicit custom metric ingestion. github: https://github.com/ccfos/nightingale The configuration as follows: > [[Pushgw.Writers]] > Url = "http://localhost:5080/api/default/prometheus/api/v1/write" > BasicAuthUser = "root@example.com" > BasicAuthPass = "o2oi_XUppAyGUwBxTvGnjXcg5ybFnVE4WnjOC" <img width="2940" height="1004" alt="image" src="https://github.com/user-attachments/assets/1683255f-1591-4a40-bfe0-ea52c9484746" /> <img width="2926" height="1614" alt="image" src="https://github.com/user-attachments/assets/c3c3b181-5b6a-4104-b7e4-8857597dfd8e" /> Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com> |
||
|
|
424c64564e |
chore(deps): bump webpack-dev-server from 5.2.5 to 5.2.6 in /web (#13311)
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 5.2.5 to 5.2.6. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/webpack/webpack-dev-server/releases">webpack-dev-server's releases</a>.</em></p> <blockquote> <h2>v5.2.6</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: allow <code>undefined</code> as the <code>Server</code> constructor <code>options</code> argument again (by <a href="https://github.com/bjohansebas"><code>@bjohansebas</code></a> in <a href="https://redirect.github.com/webpack/webpack-dev-server/pull/5695">#5695</a>)</p> <p>Restores accepting <code>undefined</code> (defaulting it to <code>{}</code>) for the <code>options</code> argument, so passing a webpack config's optional <code>devServer</code> field type-checks and works as before.</p> </li> <li> <p>Protect the built-in state-changing routes (<code>/webpack-dev-server/invalidate</code> and <code>/webpack-dev-server/open-editor</code>) against cross-site request forgery. Requests are now checked with <code>Sec-Fetch-Site</code> (falling back to an <code>Origin</code>/<code>Host</code> comparison when it is absent), so a cross-site page can no longer trigger a rebuild or open a file in the editor. Same-origin requests, user-initiated navigations, and non-browser clients (e.g. curl) are unaffected. (by <a href="https://github.com/bjohansebas"><code>@bjohansebas</code></a> in <a href="https://redirect.github.com/webpack/webpack-dev-server/pull/5698">#5698</a>)</p> </li> <li> <p>Handle malformed <code>Host</code> and <code>Origin</code> header values gracefully when validating requests. (by <a href="https://github.com/bjohansebas"><code>@bjohansebas</code></a> in <a href="https://redirect.github.com/webpack/webpack-dev-server/pull/5699">#5699</a>)</p> </li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/webpack/webpack-dev-server/blob/v5.2.6/CHANGELOG.md">webpack-dev-server's changelog</a>.</em></p> <blockquote> <h2>5.2.6</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: allow <code>undefined</code> as the <code>Server</code> constructor <code>options</code> argument again (by <a href="https://github.com/bjohansebas"><code>@bjohansebas</code></a> in <a href="https://redirect.github.com/webpack/webpack-dev-server/pull/5695">#5695</a>)</p> <p>Restores accepting <code>undefined</code> (defaulting it to <code>{}</code>) for the <code>options</code> argument, so passing a webpack config's optional <code>devServer</code> field type-checks and works as before.</p> </li> <li> <p>Protect the built-in state-changing routes (<code>/webpack-dev-server/invalidate</code> and <code>/webpack-dev-server/open-editor</code>) against cross-site request forgery. Requests are now checked with <code>Sec-Fetch-Site</code> (falling back to an <code>Origin</code>/<code>Host</code> comparison when it is absent), so a cross-site page can no longer trigger a rebuild or open a file in the editor. Same-origin requests, user-initiated navigations, and non-browser clients (e.g. curl) are unaffected. (by <a href="https://github.com/bjohansebas"><code>@bjohansebas</code></a> in <a href="https://redirect.github.com/webpack/webpack-dev-server/pull/5698">#5698</a>)</p> </li> <li> <p>Handle malformed <code>Host</code> and <code>Origin</code> header values gracefully when validating requests. (by <a href="https://github.com/bjohansebas"><code>@bjohansebas</code></a> in <a href="https://redirect.github.com/webpack/webpack-dev-server/pull/5699">#5699</a>)</p> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/webpack/webpack-dev-server/commit/8a37b0ed89d07ca81532188fe19f080a2ee51475"><code>8a37b0e</code></a> chore(release): new release (<a href="https://redirect.github.com/webpack/webpack-dev-server/issues/5697">#5697</a>)</li> <li><a href="https://github.com/webpack/webpack-dev-server/commit/f21ed0f44aceb6132abb591ee8b60d770b6e489f"><code>f21ed0f</code></a> fix: handle malformed Host and Origin headers (<a href="https://redirect.github.com/webpack/webpack-dev-server/issues/5699">#5699</a>)</li> <li><a href="https://github.com/webpack/webpack-dev-server/commit/80cd9eea54975fe632a518d8bd902a260f374e7c"><code>80cd9ee</code></a> fix: reject cross-site requests to open-editor and invalidate endpoints (<a href="https://redirect.github.com/webpack/webpack-dev-server/issues/5698">#5698</a>)</li> <li><a href="https://github.com/webpack/webpack-dev-server/commit/308e853808fc8f5d0722276e1a87aa73c91859a5"><code>308e853</code></a> fix: handle undefined options in Server constructor (<a href="https://redirect.github.com/webpack/webpack-dev-server/issues/5695">#5695</a>)</li> <li><a href="https://github.com/webpack/webpack-dev-server/commit/8b2b9151f41e0d6157c8bd051cf5f16bce5dba17"><code>8b2b915</code></a> chore: update branch references from v4 to v5 in workflow configuration</li> <li><a href="https://github.com/webpack/webpack-dev-server/commit/870ed2258dda612c8feeaf8d971afd08233696ad"><code>870ed22</code></a> chore: add v5 branch to release workflow triggers</li> <li>See full diff in <a href="https://github.com/webpack/webpack-dev-server/compare/v5.2.5...v5.2.6">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com> |
||
|
|
c8971ed2ad |
chore(deps): bump actions/setup-node from 4 to 7 (#13303)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 7. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/setup-node/releases">actions/setup-node's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2>What's Changed</h2> <h3>Enhancements:</h3> <ul> <li>Add cache-primary-key and cache-matched-key as outputs by <a href="https://github.com/gowridurgad"><code>@gowridurgad</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1577">actions/setup-node#1577</a></li> <li>Migrate to ESM and upgrade dependencies by <a href="https://github.com/gowridurgad"><code>@gowridurgad</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1574">actions/setup-node#1574</a></li> </ul> <h3>Bug fixes:</h3> <ul> <li>Remove dummy NODE_AUTH_TOKEN export by <a href="https://github.com/gowridurgad"><code>@gowridurgad</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1558">actions/setup-node#1558</a></li> <li>Only use <code>mirrorToken</code> in <code>getManifest</code> if it's provided by <a href="https://github.com/deiga"><code>@deiga</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1548">actions/setup-node#1548</a></li> </ul> <h3>Documentation updates:</h3> <ul> <li>Add documentation for publishing to npm with Trusted Publisher (OIDC) by <a href="https://github.com/chiranjib-swain"><code>@chiranjib-swain</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1536">actions/setup-node#1536</a></li> <li>docs: Update restore-only cache documentation by <a href="https://github.com/priya-kinthali"><code>@priya-kinthali</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1550">actions/setup-node#1550</a></li> <li>docs: Update caching recommendations to mitigate cache poisoning risks by <a href="https://github.com/chiranjib-swain"><code>@chiranjib-swain</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1567">actions/setup-node#1567</a></li> </ul> <h3>Dependency update:</h3> <ul> <li>Upgrade <code>@actions/cache</code> to 5.1.0, log cache write denied by <a href="https://github.com/jasongin"><code>@jasongin</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1569">actions/setup-node#1569</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/chiranjib-swain"><code>@chiranjib-swain</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-node/pull/1536">actions/setup-node#1536</a></li> <li><a href="https://github.com/deiga"><code>@deiga</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-node/pull/1548">actions/setup-node#1548</a></li> <li><a href="https://github.com/jasongin"><code>@jasongin</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-node/pull/1569">actions/setup-node#1569</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/setup-node/compare/v6...v7.0.0">https://github.com/actions/setup-node/compare/v6...v7.0.0</a></p> <h2>v6.5.0</h2> <h2>What's Changed</h2> <ul> <li>Update <code>@actions/cache</code> to 5.1.0 and add security overrides for undici and fast-xml-parser by <a href="https://github.com/HarithaVattikuti"><code>@HarithaVattikuti</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1579">actions/setup-node#1579</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/setup-node/compare/v6.4.0...v6.5.0">https://github.com/actions/setup-node/compare/v6.4.0...v6.5.0</a></p> <h2>v6.4.0</h2> <h2>What's Changed</h2> <h3>Dependency updates:</h3> <ul> <li>Upgrade <a href="https://github.com/actions"><code>@actions</code></a> dependencies by <a href="https://github.com/Copilot"><code>@Copilot</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1525">actions/setup-node#1525</a></li> <li>Update Node.js versions in versions.yml and bump package to v6.4.0 by <a href="https://github.com/priya-kinthali"><code>@priya-kinthali</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1533">actions/setup-node#1533</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/Copilot"><code>@Copilot</code></a> made their first contribution in <a href="https://redirect.github.com/actions/setup-node/pull/1525">actions/setup-node#1525</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/setup-node/compare/v6...v6.4.0">https://github.com/actions/setup-node/compare/v6...v6.4.0</a></p> <h2>v6.3.0</h2> <h2>What's Changed</h2> <h3>Enhancements:</h3> <ul> <li>Support parsing <code>devEngines</code> field by <a href="https://github.com/susnux"><code>@susnux</code></a> in <a href="https://redirect.github.com/actions/setup-node/pull/1283">actions/setup-node#1283</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/setup-node/commit/820762786026740c76f36085b0efc47a31fe5020"><code>8207627</code></a> Migrate to ESM and upgrade dependencies (<a href="https://redirect.github.com/actions/setup-node/issues/1574">#1574</a>)</li> <li><a href="https://github.com/actions/setup-node/commit/04be95cf3511ea51ebf9f224ddfb99cc7ab87cd4"><code>04be95c</code></a> Add cache-primary-key and cache-matched-key as outputs (<a href="https://redirect.github.com/actions/setup-node/issues/1577">#1577</a>)</li> <li><a href="https://github.com/actions/setup-node/commit/7c2c68d20d402ed6a201ada70a81341941093140"><code>7c2c68d</code></a> docs: Update caching recommendations to mitigate cache poisoning risks (<a href="https://redirect.github.com/actions/setup-node/issues/1567">#1567</a>)</li> <li><a href="https://github.com/actions/setup-node/commit/6a61c0375d66246de94630495909f12cf8dac84d"><code>6a61c03</code></a> Merge pull request <a href="https://redirect.github.com/actions/setup-node/issues/1569">#1569</a> from jasongin/update-actions-cache-5.1.0</li> <li><a href="https://github.com/actions/setup-node/commit/30eb73b41ded577900c1ebf968ef95cdf8f7434f"><code>30eb73b</code></a> Resolve high-severity audit issues</li> <li><a href="https://github.com/actions/setup-node/commit/4e1a87a501d0302f99e30e2748568adcb388d09f"><code>4e1a87a</code></a> Update dist</li> <li><a href="https://github.com/actions/setup-node/commit/360237f0c01778d0c17291f75c56d6feae4f7574"><code>360237f</code></a> Strict equality</li> <li><a href="https://github.com/actions/setup-node/commit/4f8aac5beb2f0854bc79651567a18c67eb0b9de3"><code>4f8aac5</code></a> Bump <code>@actions/cache</code> to 5.1.0, log cache write denied</li> <li><a href="https://github.com/actions/setup-node/commit/f4a67bbeca970f103397d3d2b9462cf787cd2980"><code>f4a67bb</code></a> Only use <code>mirrorToken</code> in <code>getManifest</code> if it's provided (<a href="https://redirect.github.com/actions/setup-node/issues/1548">#1548</a>)</li> <li><a href="https://github.com/actions/setup-node/commit/0355742c943ddb13ca8a6b700f824231caa91e75"><code>0355742</code></a> Remove dummy NODE_AUTH_TOKEN export (<a href="https://redirect.github.com/actions/setup-node/issues/1558">#1558</a>)</li> <li>Additional commits viewable in <a href="https://github.com/actions/setup-node/compare/v4...v7">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com> |
||
|
|
d3ee4342dc | fix: frontend unit test in main (#13328) | ||
|
|
ed3c4081ca |
chore(deps): bump shell-quote from 1.8.4 to 1.10.0 in /web (#13310)
Bumps [shell-quote](https://github.com/ljharb/shell-quote) from 1.8.4 to 1.10.0. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/ljharb/shell-quote/blob/main/CHANGELOG.md">shell-quote's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/ljharb/shell-quote/compare/v1.9.0...v1.10.0">v1.10.0</a> - 2026-07-10</h2> <h3>Merged</h3> <ul> <li>[New] <code>parse</code>: add opt-in <code>splitUnquoted</code> option for shell field-splitting of unquoted expansions <a href="https://redirect.github.com/ljharb/shell-quote/pull/1"><code>[#1](https://github.com/ljharb/shell-quote/issues/1)</code></a></li> </ul> <h3>Commits</h3> <ul> <li>[Fix] <code>parse</code>: match nested <code>${...}</code> braces so nested parameter expansion is consumed as one substitution <a href="https://github.com/ljharb/shell-quote/commit/c0842c8a7a034066da2496a75e91cbe500ff736c"><code>c0842c8</code></a></li> <li>[Tests] <code>parse</code>: pin single-quote literalness and unmatched-quote handling <a href="https://github.com/ljharb/shell-quote/commit/a0d03e35c8ede24016502c4433b8f5d6b3100a62"><code>a0d03e3</code></a></li> <li>[readme] remove the space in js code fences so evalmd evaluates them <a href="https://github.com/ljharb/shell-quote/commit/2116fa36aeea77fe8d561b0db46b1f9b26b8cf1b"><code>2116fa3</code></a></li> <li>[Tests] <code>quote</code>: pin conservative escaping of <code>=</code>, <code>@</code>, <code>^</code>, <code>,</code>, <code>:</code>, <code>!</code> (<a href="https://redirect.github.com/ljharb/shell-quote/issues/11">#11</a>) <a href="https://github.com/ljharb/shell-quote/commit/1c36f3ff77d26d200620c1027e5c271050120b8e"><code>1c36f3f</code></a></li> <li>[readme] document that <code>quote</code> outputs POSIX quoting, not <code>cmd.exe</code>/PowerShell <a href="https://github.com/ljharb/shell-quote/commit/100e96e0ffadcca97d63dda15651c70b9f83507c"><code>100e96e</code></a></li> <li>[readme] document <code>parse</code>'s supported parameter-expansion subset <a href="https://github.com/ljharb/shell-quote/commit/e1c75cd6e4a3c60003792c7f2802587d328622cb"><code>e1c75cd</code></a></li> <li>[Fix] <code>parse</code>: a backslash inside single quotes must not escape the closing quote <a href="https://github.com/ljharb/shell-quote/commit/5d460a332b54b83153297fe7d1964330b28fa491"><code>5d460a3</code></a></li> <li>[readme] fix stale example outputs <a href="https://github.com/ljharb/shell-quote/commit/2de86f5d44f44d3ac9df36413d8a05f3534cdec6"><code>2de86f5</code></a></li> <li>[Tests] <code>quote</code>: pin that a backslash with whitespace is not doubled in single quotes (<a href="https://redirect.github.com/ljharb/shell-quote/issues/14">#14</a>) <a href="https://github.com/ljharb/shell-quote/commit/190e236bcf1d81caa8e40e8ea3bb11998575be71"><code>190e236</code></a></li> <li>[readme] <code>quote</code>: use output verbatim; do not re-quote it (<a href="https://redirect.github.com/ljharb/shell-quote/issues/11">#11</a>) <a href="https://github.com/ljharb/shell-quote/commit/1b364683b1e9e8d078fd3017cde82cf10c9c04a5"><code>1b36468</code></a></li> <li>[Refactor] <code>parse</code>: fix swapped <code>SINGLE_QUOTE</code>/<code>DOUBLE_QUOTE</code> variable names <a href="https://github.com/ljharb/shell-quote/commit/801af5c935b27d6dcda63b3975d5e92a7b6f887f"><code>801af5c</code></a></li> <li>[types] fix an error TS v6 ignores but v7 fails on <a href="https://github.com/ljharb/shell-quote/commit/59bbf8b81bf3236842deb72805744d489f650eba"><code>59bbf8b</code></a></li> <li>[Dev Deps] update <code>@arethetypeswrong/cli</code>, <code>evalmd</code> <a href="https://github.com/ljharb/shell-quote/commit/a04d47516e1cd5b1b4d3f720ddf97561ed0082fc"><code>a04d475</code></a></li> <li>[Dev Deps] update <code>@arethetypeswrong/ci</code>, <code>eslint</code> <a href="https://github.com/ljharb/shell-quote/commit/d390f9a92b97a04b1f799298634e90dc581021e6"><code>d390f9a</code></a></li> <li>[Tests] <code>quote</code>: the tilde test escapes every <code>~</code>, not just a leading one (<a href="https://redirect.github.com/ljharb/shell-quote/issues/9">#9</a>) <a href="https://github.com/ljharb/shell-quote/commit/617d119795c7b44d6e49a4d41f80195c4aa5735c"><code>617d119</code></a></li> </ul> <h2><a href="https://github.com/ljharb/shell-quote/compare/v1.8.4...v1.9.0">v1.9.0</a> - 2026-06-24</h2> <h3>Commits</h3> <ul> <li>[New] add types <a href="https://github.com/ljharb/shell-quote/commit/dca6e21a02df4cc1a83ed1b5baa4d82df134170a"><code>dca6e21</code></a></li> <li>[Dev Deps] update <code>eslint</code> <a href="https://github.com/ljharb/shell-quote/commit/9aa9e8f60991f8c4053a29e476795d891ff851ad"><code>9aa9e8f</code></a></li> <li>[Fix] <code>parse</code>: finalize tokens in linear time (GHSA-395f-4hp3-45gv) <a href="https://github.com/ljharb/shell-quote/commit/7ff5488599d01c323514f02f5efb74088dd134ec"><code>7ff5488</code></a></li> <li>[actions] update workflows <a href="https://github.com/ljharb/shell-quote/commit/75e849741ffaf2d3aa53ae0e18ef6bf9929ef478"><code>75e8497</code></a></li> <li>[actions] Windows + node 4/6/7: pin eslint to 9 before install, since npm 2/3 cannot stage eslint 10<code>@types/esrecurse</code> <a href="https://github.com/ljharb/shell-quote/commit/3fb739de44b81c69431947d54fbfc18998dd6d72"><code>3fb739d</code></a></li> <li>[actions] retry <code>npm install</code> on Windows to survive npm 2/3 staging-rename flake <a href="https://github.com/ljharb/shell-quote/commit/abe0163293c82963fa8a16cfaa87181846d5aced"><code>abe0163</code></a></li> <li>[actions] Windows + node 5/7: install deps with a modern node <a href="https://github.com/ljharb/shell-quote/commit/b4bafa2e7e58d53d9839b1c24976f61e54b43326"><code>b4bafa2</code></a></li> <li>[Fix] <code>quote</code>: escape leading <code>~</code> to prevent shell tilde-expansion <a href="https://github.com/ljharb/shell-quote/commit/7a76c1a12d8461c2234a1c655b943cee84cbff91"><code>7a76c1a</code></a></li> <li>[Dev Deps] update <code>auto-changelog</code>, <code>tape</code> <a href="https://github.com/ljharb/shell-quote/commit/7184b4458b65c17b931e126d8cb5f586c6717dc8"><code>7184b44</code></a></li> <li>[Dev Deps] apparently <code>jackspeak</code> is no longer in the graph <a href="https://github.com/ljharb/shell-quote/commit/9ba368a4057b9f498b0fef23b5b15543ef81b98c"><code>9ba368a</code></a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/ljharb/shell-quote/commit/64988d9a0e73a2ae710488952e3614958ef289d4"><code>64988d9</code></a> v1.10.0</li> <li><a href="https://github.com/ljharb/shell-quote/commit/617d119795c7b44d6e49a4d41f80195c4aa5735c"><code>617d119</code></a> [Tests] <code>quote</code>: the tilde test escapes every <code>~</code>, not just a leading one (<a href="https://redirect.github.com/ljharb/shell-quote/issues/9">#9</a>)</li> <li><a href="https://github.com/ljharb/shell-quote/commit/59bbf8b81bf3236842deb72805744d489f650eba"><code>59bbf8b</code></a> [types] fix an error TS v6 ignores but v7 fails on</li> <li><a href="https://github.com/ljharb/shell-quote/commit/190e236bcf1d81caa8e40e8ea3bb11998575be71"><code>190e236</code></a> [Tests] <code>quote</code>: pin that a backslash with whitespace is not doubled in singl...</li> <li><a href="https://github.com/ljharb/shell-quote/commit/a04d47516e1cd5b1b4d3f720ddf97561ed0082fc"><code>a04d475</code></a> [Dev Deps] update <code>@arethetypeswrong/cli</code>, <code>evalmd</code></li> <li><a href="https://github.com/ljharb/shell-quote/commit/b9545b39f4de17aa169410823c98acf58387e474"><code>b9545b3</code></a> [New] <code>parse</code>: add opt-in <code>splitUnquoted</code> option for shell field-splitting of...</li> <li><a href="https://github.com/ljharb/shell-quote/commit/1b364683b1e9e8d078fd3017cde82cf10c9c04a5"><code>1b36468</code></a> [readme] <code>quote</code>: use output verbatim; do not re-quote it (<a href="https://redirect.github.com/ljharb/shell-quote/issues/11">#11</a>)</li> <li><a href="https://github.com/ljharb/shell-quote/commit/1c36f3ff77d26d200620c1027e5c271050120b8e"><code>1c36f3f</code></a> [Tests] <code>quote</code>: pin conservative escaping of <code>=</code>, <code>@</code>, <code>^</code>, <code>,</code>, <code>:</code>, <code>!</code> (<a href="https://redirect.github.com/ljharb/shell-quote/issues/11">#11</a>)</li> <li><a href="https://github.com/ljharb/shell-quote/commit/e1c75cd6e4a3c60003792c7f2802587d328622cb"><code>e1c75cd</code></a> [readme] document <code>parse</code>'s supported parameter-expansion subset</li> <li><a href="https://github.com/ljharb/shell-quote/commit/c0842c8a7a034066da2496a75e91cbe500ff736c"><code>c0842c8</code></a> [Fix] <code>parse</code>: match nested <code>${...}</code> braces so nested parameter expansion is ...</li> <li>Additional commits viewable in <a href="https://github.com/ljharb/shell-quote/compare/v1.8.4...v1.10.0">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com> |
||
|
|
b835ff2f86 |
refactor: consolidate vrl/js into transform crate and extract super_cluster_queue crate (#13324)
## Summary Two crate-split refactors continuing the workspace decomposition: **1. `transform` crate (renamed from `openobserve-vrl`, `src/vrl` → `src/transform`)** - Now the only crate depending on `vrl`, `vector-enrichment` and `rquickjs` directly; downstream crates use `transform::vrl::` / `transform::vector_enrichment::` re-export paths and drop their direct dependencies - The QuickJS runtime (`common/utils/js.rs`) moved into `transform::js` (js_security checks gated behind the crate's `enterprise` feature); `apply_vrl_fn`, `convert_to_vrl`/`convert_from_vrl` and `TRANSFORM_FAILED` moved from core - Exception: `src/config` keeps its direct `vrl` dependency (it sits below `transform` in the dependency graph) **2. `super_cluster_queue` extracted from the root crate into a workspace member** - Only depends on `openobserve-core`, `infra`, `config` and `o2_enterprise`, so it builds in parallel with `api` and edits no longer recompile the root crate (which re-embeds `web/dist` on every rebuild) - Gated behind its own `enterprise` feature — compiles as an empty crate in OSS builds so `cargo --workspace` keeps working against the `o2_enterprise` stub; `vectorscan` wired through for `re_pattern.rs` - Root `lib.rs` re-exports the crate, so `openobserve::super_cluster_queue::init()` in `main.rs` is unchanged Pairs with the `Cargo.toml.openobserve` template sync PR in o2-enterprise (must merge together). ## Test plan - `cargo check --workspace --all-targets` (OSS) passes - `cargo check -p openobserve --no-default-features --features enterprise` with the synced enterprise template passes - `cargo clippy -p super_cluster_queue --features enterprise,vectorscan` — zero warnings - `cargo clippy -- -D warnings` (CI invocation) passes; `cargo fmt --all` clean |
||
|
|
05dc30b952 |
feat(dashboards): redesign gallery drawer and add migration links (#13313)
- Replace flat checkbox list in template gallery with grouped card grid, organised by category (Cloud, Kubernetes, Database, Networking, etc.) with category icon, colour coding, and item count badge per group - Add dark mode support throughout the gallery (body--dark overrides for all hardcoded light colours) - Add Migrate from Datadog / Grafana / Kibana / CloudWatch options under the Import dropdown (separated from Custom and Templates), each opening migration.openobserve.ai in a new tab --------- Co-authored-by: Kirtan Thakkar <kirtan@kiara.tech> |
||
|
|
79c524c7f9 |
test: heal dark-mode detection and logs scroll-container selectors after design-token migration (#13316)
## Why The 2026-07-21 scheduled Playwright Regression runs failed on **both** OSS ([run 29801668855](https://github.com/openobserve/openobserve/actions/runs/29801668855)) and ENT ([run 29801639539](https://github.com/openobserve/o2-enterprise/actions/runs/29801639539)) — same 4 tests, same shards (Traces-Regression, Logs-Regression). Root cause: the design-token migration (#13173, `f15e27e5fd`, merged 2026-07-20 evening — the only code change between the last green scheduled run and the failing one) removed Quasar entirely, breaking two page-object seams: | Failing test | Broken seam | |---|---| | `traces-bugs.spec.js` › trace values should be visible on hover in dark mode (@bug-4151) | `homePage.isDarkMode()` read the retired Quasar `body--dark` class on `<body>`. Dark mode is now the `.dark` class on `<html>` (set by `utils/theme.ts`). `themePage.js` was already migrated inside #13173 — `homePage.js` was missed. | | `logs-9044-7354.spec.js` › all 3 scroll-retention tests (#9044) | `getScrollContainerPosition()` / `scrollToResultsBottom()` navigated `pagination → .search-list → [class*="overflow-y-auto"]` — both hooks are gone. The results scroller is now the combined scroll area (`ref="scrollContainerRef"` in `logs/SearchResult.vue`). Helpers returned the `-1` "not found" sentinel, so `expect(scroll).toBeGreaterThan(10)` failed. | ## What Test-side only (no `web/` changes): - `homePage.isDarkMode()` → checks `document.documentElement.classList.contains('dark')`. - Logs scroll helpers → walk up from the `logs-search-result-pagination` anchor and pick the sibling child whose **computed** `overflow-y` is `auto`/`scroll`, so future utility-class renames don't break it again. Pagination helpers (`-page-N`, `-next`, `aria-current="page"`) already matched the new OPagination markup and needed no change. ## ENT ENT overrides none of these files — its regression workflow checks out OSS tests (`cp -r o2-enterprise/tests/* openobserve/tests/` overlays only ENT-owned files). The ENT scheduled run heals automatically once this merges; verified pre-merge by dispatching ENT `playwright_regression.yml` with `oss_branch: test/heal-dark-mode-scroll-selectors`. ## Verification All 4 previously-failing tests pass locally against a post-migration build (`main` @ `c523d0034c`, enterprise features): - `logs-9044-7354.spec.js` — 3 passed (49s) - `traces-bugs.spec.js -g "trace values should be visible on hover in dark mode"` — 1 passed (18s) OSS + ENT regression runs seeded against this branch (links in comments). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
048175094e | chore: removing glm5.2 review (#13314) | ||
|
|
1ad116eb96 |
fix: mcp issues (#13196)
Fixes several MCP-related API issues: - Enrich `x-o2-mcp` metadata with `summary_fields` on kv list, backfill list, alert templates, dashboard annotations, and search jobs so MCP tools return well-shaped summaries. - Add missing `org_id`/`dashboard_id` OpenAPI path params to the timed annotations list endpoint. - Return an empty result (instead of a 500) from pipeline history when the triggers stream doesn't exist yet. - Return a properly-shaped `PaginatedResponse` (preserving the query-range warning) from the traces `get_latest_users` endpoint when there are no matching hits. - Sanitize error-message headers so error responses propagate the real status/body instead of failing with a 500. |
||
|
|
fd85566742 |
feat: workflows version 1 (#13156)
This PR introduces workflows design at: https://github.com/openobserve/designs/blob/main/infrastructure/workflows/design.md --------- Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com> Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
209e263851 |
chore(deps): bump js-yaml from 4.2.0 to 4.3.0 in /web (#13312)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.2.0 to 4.3.0. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md">js-yaml's changelog</a>.</em></p> <blockquote> <h2>4.3.0, 3.15.0 - 2026-06-27</h2> <h3>Security</h3> <ul> <li>Backported <code>maxTotalMergeKeys</code> option.</li> </ul> <h2>[5.2.0] - 2026-06-26</h2> <h3>Added</h3> <ul> <li>Added <code>maxTotalMergeKeys</code> (10000) loader option to limit the total number of keys processed by YAML merge (<code><<</code>) across one <code>load()</code> / <code>loadAll()</code> call.</li> <li>Added <code>maxAliases</code> (-1) loader option to limit the number of YAML aliases per document.</li> </ul> <h3>Removed</h3> <ul> <li><code>maxMergeSeqLength</code> replaced with <code>maxTotalMergeKeys</code> for limiting YAML merge processing.</li> </ul> <h3>Fixed</h3> <ul> <li>Round-trip of integers with exponential form (>= <code>1e21</code>)</li> </ul> <h2>[5.1.0] - 2026-06-23</h2> <h3>Added</h3> <ul> <li>Collection tags can finalize an incrementally populated carrier into a different result value.</li> </ul> <h3>Changed</h3> <ul> <li>[breaking] <code>quoteStyle</code> now selects the preferred quote style; use the restored <code>forceQuotes</code> option to force quoting non-key strings.</li> </ul> <h2>[5.0.0] - 2026-06-20</h2> <h3>Added</h3> <ul> <li>Added named exports for schemas, tags, parser events and AST utilities.</li> <li>Reworked <code>JSON_SCHEMA</code> and <code>CORE_SCHEMA</code> with spec-compliant scalar resolution rules, and added <code>YAML11_SCHEMA</code>.</li> <li>Added <code>realMapTag</code> for lossless mappings with non-string and complex keys. Object-based mappings now reject complex keys instead of stringifying them.</li> <li>Added <code>dump()</code> <code>transform</code> option for changing the generated AST before rendering.</li> <li>Added <code>dump()</code> options <code>seqInlineFirst</code>, <code>flowBracketPadding</code>, <code>flowSkipCommaSpace</code>, <code>flowSkipColonSpace</code>, <code>quoteFlowKeys</code>, <code>quoteStyle</code> and <code>tagBeforeAnchor</code>.</li> <li>Added formal data layers (events and AST) for modular data pipelines. <ul> <li>Added low-level parser (to events), presenter and visitor APIs.</li> </ul> </li> <li>Added the <a href="https://github.com/yaml/yaml-test-suite">YAML Test Suite</a> to the test set.</li> </ul> <h3>Changed</h3> <ul> <li>See the <a href="https://github.com/nodeca/js-yaml/blob/master/docs/migrate_v4_to_v5.md">migration guide</a> for upgrade notes.</li> <li>Rewritten in TypeScript and reorganized the public API around flat named exports.</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/nodeca/js-yaml/commit/33d05b5d29a8c21360f620f7e1c1706e24522eda"><code>33d05b5</code></a> 4.3.0 released</li> <li><a href="https://github.com/nodeca/js-yaml/commit/663bfab6db2b4a146a9366fd685f069345be4ddb"><code>663bfab</code></a> Drop demo publish, to not override new v5 one.</li> <li><a href="https://github.com/nodeca/js-yaml/commit/1cb8c7b94bf75e15116869c1c0482dcb22785986"><code>1cb8c7b</code></a> Add v4-legacy tag for publish</li> <li><a href="https://github.com/nodeca/js-yaml/commit/02f27afad532763263cd2b6be35c24ee8e1f6157"><code>02f27af</code></a> Restore umd builds back to es5</li> <li><a href="https://github.com/nodeca/js-yaml/commit/8be84edaf15e7c394fa3b813179d1bcc280e87fb"><code>8be84ed</code></a> Fix es5 compatibility</li> <li><a href="https://github.com/nodeca/js-yaml/commit/59423c6f8cdc78742ac00e25a4dd39ef16b702e4"><code>59423c6</code></a> Replace <code>maxMergeSeqLength</code> option with <code>maxTotalMergeKeys</code> (more robust). Ba...</li> <li><a href="https://github.com/nodeca/js-yaml/commit/6842ef6a02df01ca7282ea01dc3c70787710c05d"><code>6842ef6</code></a> doc polish</li> <li>See full diff in <a href="https://github.com/nodeca/js-yaml/compare/4.2.0...4.3.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/openobserve/openobserve/network/alerts). </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com> |
||
|
|
5a4d3e5cc0 |
fix(anomaly-detection): apply threshold changes without a retrain (#13305)
## Problem Updating an anomaly-detection config's **threshold (percentile)** persisted `config.threshold` but had **no effect on detection** until the model was retrained — the detector uses the cutoff baked into the trained model. The obvious workaround (resetting `is_trained`) also silently failed, because `UpdateAnomalyConfigRequest` has no such field. Reported in openobserve/o2-enterprise#2212. ## Change (service-layer wiring) `update_config` now recomputes the trained model's baked cutoff **in place** when the threshold actually changes, instead of leaving it stale: - On a real threshold change — and only when the config is **trained**, has a **model version**, and is **not mid-retrain** — call the enterprise recompute helper, which re-derives the cutoff from the persisted training-score sidecar and writes it back to the same model version. **No retrain.** - If the model is **legacy** (no sidecar) or recompute fails, fall back to forcing a **one-time retrain** (`force_retrain_for_threshold`) so the change is never silently dropped. The fallback **skips a config already retraining** — the running train bakes the latest percentile itself. - **No new public API field.** `is_trained` stays internal; `/train` remains the manual retrain entry point. All new wiring is behind `#[cfg(feature = "enterprise")]`; the OSS build is unaffected. The core recompute logic lives in the enterprise repo per the OSS/enterprise split. ## Companion (required) The model-side logic (sidecar persistence + `recompute_threshold`) is in the enterprise PR — **merge together**: **openobserve/o2-enterprise#2214** Fixes-via: openobserve/o2-enterprise#2212 ## Verification Built the enterprise binary and drove the full flow against a running server (see the enterprise PR for the end-to-end capture): bug reproduced on the current build, then the fixed build recomputes in place with no retrain, detection picks up the new cutoff, and the legacy-fallback / no-op-PUT / mid-retrain-guard paths all behave. `cargo fmt --check` + `clippy -D warnings` clean. |