Files
wehub-resource-sync 7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

13 KiB
Raw Permalink Blame History

💥 Breaking Changes

  • llm.model no longer auto-fills gemma3:12b. Pre-1.7 installs silently downloaded a multi-GB Ollama binary on first use. The field is now empty by default — pick a model in Settings → LLM, or research will fail loudly with a clear ValueError. Existing users with a saved llm.model setting are unaffected; fresh installs see an inline warning in Settings (aria-live="polite") and a clear error on research start. Affects all built-in providers (openai, anthropic, ollama, lmstudio, llamacpp, google, openrouter, ionos, xai). (#3670)
  • llamacpp provider migrated from in-process to HTTP. No longer loads .gguf files in-process via llama-cpp-python — connects to llama-server's OpenAI-compatible HTTP endpoint instead. Removed settings: llm.llamacpp_model_path, llm.llamacpp_n_batch, llm.llamacpp_n_gpu_layers, llm.llamacpp_f16_kv. New settings: llm.llamacpp.url (default http://localhost:8080/v1), llm.llamacpp.api_key (optional, for auth proxies). Migration: run llama-server -m <your-model.gguf> and the default URL picks it up; alternatively use the openai_endpoint provider pointed at the same URL. (#3670)

🔒 Security

  • Fix LM Studio model detection (#3800) — the settings dropdown was silently dropping models for every auto-discovered provider except Ollama / OpenAI / Anthropic / OpenAI-Compatible-Endpoint, including LM Studio, Llama.cpp, Google Gemini, xAI, OpenRouter, and IONOS. While investigating, also fixed a separate credential-leak class where the route's auto-discovery loop sent every other provider's configured API key in the Authorization header to the local LM Studio / llama-server endpoint on every settings-page load. (#3800)

  • Fix SSRF parser-differential bypass (GHSA-g23j-2vwm-5c25). URLs containing backslash, whitespace, or ASCII control bytes are now rejected upfront by the SSRF validator and notification-URL validator; hostname extraction switched from urllib.parse.urlparse to urllib3.util.parse_url so the validator and the HTTP client agree on destination by construction. Credit: @Fushuling, @RacerZ-fighting.

  • Hardened SSRF defenses against AWS ECS task metadata (169.254.170.2, 169.254.170.23), Tencent Cloud (169.254.0.23), and AlibabaCloud (100.100.100.200) metadata endpoints — these are now always blocked alongside the existing AWS IMDS / Azure / OCI / DigitalOcean entry (169.254.169.254). Redacted credentials, path, and query from URL-rejection logs (operators with grep/regex tooling on the rejection log lines will see authority-only scheme://host:port instead of full URLs going forward).

  • SSRF defense-in-depth: block IPv6 transition prefixes that can wrap private IPv4 destinations on hosts with kernel sit0/NAT64 routes.

    • 2002::/16 (6to4, RFC 3056 — deprecated by RFC 7526)
    • 64:ff9b::/96 (NAT64 well-known, RFC 6052)
    • 64:ff9b:1::/48 (NAT64 local-use, RFC 8215 — same SSRF threat class as the WKP; missing it earned a HackerOne bounty against ssrf_filter)
    • 2001::/32 (Teredo, RFC 4380)
    • 100::/64 (IPv6 discard, RFC 6666)
    • ::/96 (IPv4-Compatible IPv6, RFC 4291 §2.5.5.1 — DEPRECATED 2006; same SSRF threat class as the transition prefixes)

    The metadata-IP block is hardened against IPv6-wrapped IMDS access: when an IPv6 destination falls in a NAT64 prefix, the embedded IPv4 is extracted and matched against ALWAYS_BLOCKED_METADATA_IPS, so [64:ff9b::a9fe:a9fe] cannot reach 169.254.169.254 even on a NAT64 host.

    Operators on IPv6-only deployments using DNS64+NAT64 (where outbound IPv4 traffic is synthesized through 64:ff9b::/96) can opt back in via the env-only setting security.allow_nat64 (LDR_SECURITY_ALLOW_NAT64=true). The opt-in is scoped strictly to the two NAT64 prefixes — 6to4, Teredo, and discard remain blocked unconditionally, and the IMDS embedded-IPv4 carve-out still applies.

New Features

  • LM Studio optional API key. New llm.lmstudio.api_key setting for LM Studio instances with authentication enabled. (#3670)
  • Release notes now use towncrier news fragments. Each PR drops one tiny changelog.d/<id>.<category>.md file (categories: breaking, security, feature, bugfix, removal, misc). At release prep, the maintainer runs pdm run towncrier build --version <X.Y.Z> --yes, which renders the fragments into docs/release_notes/<X.Y.Z>.md and removes them. Replaces the previous shared-file workflow, which scaled poorly at LDR's PR throughput. See changelog.d/README.md for the convention. (#3773)
  • New citation format: source-tagged with global numbering. Reports can now render citations as [arxiv-1], [openai.com-2], [arxiv-3] — the source tag identifies what kind of source each citation is (short URLClassifier tag for known academic sources, cleaned domain for generic web URLs, or the collection name for local RAG/library hits, e.g. [my-papers-4]), while the number stays the original global counter so labels never collide and inline citations match the bibliography order. Opt in via report.citation_format → "Source-tagged with global numbering"; the existing default remains Numbers with hyperlinks [1]. (#4012)
  • Context-overflow warnings (front-page banner, result-page banner, completion toast) now show a clickable action that takes you straight to the relevant diagnostics — historical warnings link to the context-overflow metrics page, while per-research warnings link to that research's overflow section on its details page.
  • Context-overflow warnings now include structured fields (research_id, model, provider) and detect both input-only and total-context (input+output) overflow. Four distinct tags ([provider-confirmed], [total-context], [estimated], [estimated-total-context]) make different overflow causes distinguishable in logs and alerts. Hosted providers (OpenAI, Anthropic, OpenRouter) get estimation-based detection so their truncation events are no longer invisible. The high-context VRAM warning now links directly to the context-overflow metrics page.
  • OpenAI-compatible runtime errors (LM Studio / vLLM / llama.cpp server / OpenRouter / custom endpoint) now surface a message that names the provider, configured base URL, and model. The existing Error type: <code> token convention is extended with seven openai_* codes (openai_connection_refused, openai_timeout, openai_auth, openai_permission_denied, openai_model_not_found, openai_bad_request, openai_unknown), and ErrorReporter maps each to the right ErrorCategory. The original exception text is preserved in a Details: suffix; userinfo embedded in a base URL (https://u:key@host/v1) is stripped before display.
  • The /metrics/context-overflow page is reorganised around per-research truncation diagnosis: redundant aggregate sections (Token Usage Overview, Token Usage Over Time, Model Usage Breakdown, Context Limit Distribution doughnut, Token Usage by Phase) are dropped in favour of empty-state messages and a recoloured and re-shaped scatter chart that buckets points by context-utilisation ratio (green circle / amber triangle / red diamond — shape gives a redundant signal for colourblind users) rather than per-limit dashed reference lines. Tooltips now explicitly label requests with unknown context limits or unknown token counts. The main /metrics dashboard gains a small Context Overflow summary panel linking to the full diagnostics page; on aggregation failure the panel shows rather than a misleading 0%.
  • Upload rate limits are now configurable via LDR_SECURITY_RATE_LIMIT_UPLOAD_USER and LDR_SECURITY_RATE_LIMIT_UPLOAD_IP. The default cap is raised from 10 per minute;100 per hour to 60 per minute;1000 per hour, unblocking bulk RAG library uploads.

🐛 Bug Fixes

  • Fix progress page log panel sizing so it uses CSS layout instead of JavaScript height calculations. (#2606)
  • Progress page current-task text now preserves line breaks and wraps long generated task messages instead of collapsing them into a hard-to-read wall of text. (#2609)
  • Live research log entries now keep the same newest-first visual order as loaded log history instead of appearing at the bottom of the log panel. (#2610)
  • Journal-quality dashboard ("Your Research") no longer shows orphan papers from deleted research sessions. Deleting a research session previously left behind Paper rows whose PaperAppearance had cascade-deleted, so the dashboard kept counting them. The aggregate top-200 query and the predatory-blocked count now exclude papers that have no remaining appearances. Per-research views were already correct. (#3544)
  • Fix the model dropdown in Settings to populate for every auto-discovered LLM provider, not just Ollama / OpenAI / Anthropic / OpenAI-Compatible-Endpoint. LM Studio, Llama.cpp, Google Gemini, xAI, OpenRouter, and IONOS were silently dropped by the frontend (processModelData) even when the backend returned their models correctly. (#3800)
  • Fix file descriptor exhaustion (#3816) caused by ChatOllama._async_client not being released alongside _client. _close_base_llm() now closes both the sync and async httpx clients owned by ChatOllama, addressing the eventpoll-FD growth seen in long-running deployments. (#3816)
  • Fix the research details "View Journals" button so it opens the scoped journal-quality dashboard instead of a missing page. (#3825)
  • Fix Download Manager failure after 2030 PDFs with UNIQUE constraint failed: documents.document_hash and the cascading PendingRollbackError that prevented further downloads. (#3827)
  • Fix login/registration over http://localhost:5001 on Docker Desktop. The session cookie's Secure flag is now driven purely by the request protocol (HTTPS) rather than by source-IP heuristics, so HTTP requests from any IP — including Docker Desktop's NAT gateway — now keep their cookies and CSRF tokens. (#3849)
  • Fix Ollama embedding indexing aborting with "input length exceeds the context length" (HTTP 500) by exposing a configurable embeddings.ollama.num_ctx setting. The new field appears on the embedding settings page when the Ollama provider is selected and ships with a default of 8192 tokens, which covers chunk sizes up to ~5000 characters for nomic-embed-text, mxbai-embed-large, bge-m3, and qwen3-embedding. (#3870)
  • LangGraph agent strategy error messages now include the exception type, and the 'str' object has no attribute 'model_dump' failure (issue #3897) is translated into a rich on-result-page recommendation listing the three possible causes — proxy/shim, serving stack, or model — with concrete remediation steps for each. (#3926)
  • The Context Overflow summary panel on /metrics now honors the dashboard's research-mode filter (Quick / Detailed / All) the same way the rest of the panels do.

📝 Other Changes

  • Added LDR_DISABLE_RATE_LIMITING as the canonical name for disabling HTTP rate limiting, matching the LDR_ env-var convention. The legacy DISABLE_RATE_LIMITING still works but emits a deprecation warning. Note: this is distinct from LDR_RATE_LIMITING_ENABLED, which controls the adaptive search-engine rate limiter — a different subsystem (#3905).
  • Migrated CI workflows to the canonical LDR_DISABLE_RATE_LIMITING env var (added in #3936) and closed a test-isolation gap in test_enabled_by_default that did not clear the canonical var.
  • Removed unused chart-rendering JavaScript on the context-overflow analytics page (token-usage-over-time stacked bar, model-token-stats table, context-limits-distribution doughnut, and the configured-limits list). These functions stopped being called when the page was reorganised to focus on truncation diagnosis (#3792); deleting them now drops ~200 lines of dead code without any user-visible change.
  • The prerelease Docker workflow now also re-points the floating prerelease tag at each new RC manifest. Testers can pin image: localdeepresearch/local-deep-research:prerelease in their compose file and run docker compose pull && docker compose up -d to fetch the latest RC without editing the tag each cycle. Versioned tags (prerelease-vX.Y.Z-<sha>) are still published for reproducible testing.