Commit graph

847 commits

Author SHA1 Message Date
Logan Yang
0b6bb5a7bf
fix: support hidden directory chat save and history (#2188) (#2204)
When defaultSaveFolder is a hidden directory (e.g. .copilot/conversations),
Obsidian's metadata cache doesn't index it, causing saves to fail and
chat history to show empty.

Add adapter-level fallback utilities in src/utils/vaultAdapterUtils.ts:
- resolveFileByPath: vault lookup with synthetic TFile fallback
- listMarkdownFiles: folder listing with adapter fallback
- patchFrontmatter: processFrontMatter with adapter YAML patching fallback
- readFrontmatterViaAdapter: parse frontmatter from raw file content

Apply fallbacks across ChatPersistenceManager (save, load, list, find)
and main.ts (history picker, load, delete, title update, lastAccessedAt).

Also removes obsolete design docs from docs/.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 23:01:59 -08:00
Wenzheng Jiang
4439ed9916
fix: address Miyo PR review findings (privacy, dedup, architecture) (#2191)
* fix: address Miyo PR review findings (privacy, dedup, architecture)

- Gate request body logging behind debug flag to prevent note content
  leaking to vault log files on every upsert (P1 privacy fix)
- Replace duplicated grace period logic in findRelevantNotes with
  isSelfHostAccessValid() from plusUtils (P1 dedup fix)
- Spread-copy metadata in fromMiyoDocument to avoid mutating API response
- Remove dead if(enabled) branch in CopilotPlusSettings toggle handler
- Gate per-document upsert log lines behind debug to prevent log churn
- Rename misleading test; add no-embeddings fallback path test coverage
- Add TODO for cross-platform service discovery paths (Windows/Linux)
- Use this.client directly in MiyoSemanticRetriever.getExplicitChunks
  instead of VectorStoreManager singleton to avoid backend mismatch
- Remove unused apiKeyOverride param from buildHeaders; document dual auth
- Read pagination total only from first response in getIndexedFiles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: address PR review comments on Miyo retriever and index backend

- Guard response.documents with ?? [] in getExplicitChunks to prevent
  crash when backend omits the field or parseResponseJson returns {}
- Remove redundant getSettings().debug guard around logInfo calls since
  the logging utilities already respect the debug flag internally
- Document the debug-flag behavior in AGENTS.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: remove explicit path reads from Miyo semantic retriever

* fix: rename remaining enableMiyoSearch references

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 11:21:53 -08:00
Logan Yang
85192a3005
Rename enableMiyoSearch to enableMiyo and scope Miyo to Plus/agent chains (#2201)
- Rename `enableMiyoSearch` → `enableMiyo` across settings, UI, and all consumers
- Skip fulltext search in performLexicalSearch (Plus/agent path) when Miyo is active;
  filterRetriever still runs for tag/title matching
- VaultQA chain now passes `{ enableMiyo: false }` to RetrieverFactory so it never
  routes through Miyo
- Expose `RetrieverFactory.isMiyoActive()` for clean Miyo-state checks

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 21:27:54 -08:00
Wenzheng Jiang
ea552077d9
Add Miyo document parsing toggle and PDF parse-doc integration (#2199)
* feat: add miyo document parsing toggle for PDF parser

* refactor: consolidate miyo toggles into single enable flag
2026-02-21 20:11:11 -08:00
Logan Yang
30b54b6fdd
fix: Gemini 3 preview models image support (#2197)
* fix: upgrade @langchain/google-genai to fix Gemini 3 preview image support (#2178)

The @langchain/google-genai v1.0.0 had a hardcoded _isMultimodalModel check
that only recognized gemini-1.5, gemini-2, and "vision" model names. Gemini 3
preview models (gemini-3-flash-preview, gemini-3-pro-preview) were rejected
with "This model does not support images" when sending image content.

Upgrade to v1.0.2 which adds gemini-3 to the multimodal model pattern.
Also bump @google/generative-ai from ^0.21.0 to ^0.24.0 (required dep).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: update built-in Gemini Pro to 3.1 preview model IDs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:10:03 -08:00
Wenzheng Jiang
0812ca3e40
Miyo indexing: reset batch size on enable and apply updates after resume (#2198)
* Reset embedding batch size to default when enabling Miyo search

* Apply updated embedding batch size after indexing resume

* Fix indexing progress total after pause/resume
2026-02-20 08:31:18 -08:00
Logan Yang
c7fa37f69c
feat: add Firecrawl and Supadata self-host support for web search and YouTube (#2196)
* feat: add Firecrawl and Supadata self-host support for web search and YouTube

Self-host mode users can now use their own API keys for web search (Firecrawl)
and YouTube transcripts (Supadata) instead of routing through the Brevilabs
backend. Tools gracefully fall back to Brevilabs when no self-host key is set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add Perplexity Sonar as alternative self-host web search provider

Add provider dispatch pattern for self-host web search, supporting both
Firecrawl and Perplexity Sonar via a dropdown selector in settings UI.

Changes:
- Refactor selfHostWebSearch into provider dispatch (firecrawl/perplexity)
- Add hasSelfHostSearchKey() helper for provider-agnostic key checks
- Add settings UI dropdown for web search provider selection
- Fix Mention.ts YouTube transcription to route via Supadata in self-host mode
- Fix cached failed URL results never being retried (retry-on-error)
- Clear Miyo Search state when self-host mode is disabled
- Add 19 unit tests for selfHostServices

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:44:39 -08:00
Logan Yang
5ea26b1b7b
Add acp design doc (#2195) 2026-02-19 16:11:56 -08:00
Logan Yang
2da3fa8574
feat: self-host web search (Firecrawl) + YouTube (Supadata) (#2190)
* feat: add Firecrawl and Supadata self-host support for web search and YouTube

Self-host mode users can now use their own API keys for web search (Firecrawl)
and YouTube transcripts (Supadata) instead of routing through the Brevilabs
backend. Tools gracefully fall back to Brevilabs when no self-host key is set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: drop legacy Perplexity wrapper from self-host web search

selfHostWebSearch now returns { content, citations } directly instead of
wrapping results in the OpenAI-chat-completion shaped WebSearchResponse
that Brevilabs inherited from Perplexity. SearchTools unwraps each path
independently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: move Miyo Search under self-host conditional and improve description

Miyo Search toggle is now only visible when self-host mode is enabled,
grouped alongside Firecrawl and Supadata settings. Updated description
to be less technical and highlight vault size advantage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:23:39 -08:00
Logan Yang
795ed5ff6f
fix: hard cap L1 project context + payload diagnostics (#2192)
* docs: add token budget enforcement analysis and fix plan

Document root cause of context window overflow (2.7M tokens sent to 1M
model): L4 chat history bypasses all compaction systems. Add fix plan
with phased approach to enforce token budget at message assembly point.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: correct root cause analysis — L1 unbudgeted, not L4

Previous analysis incorrectly blamed L4 chat history as the primary
culprit. Investigation shows L4 stores only bare L5 text + compacted
responses. The real issue is systemic: no total payload enforcement,
with L1 (project context) being the largest unbudgeted layer and
PROJECT_COMPACT_THRESHOLD being blind to L1 size.

Updated fix plan to be model-agnostic (use autoCompactThreshold as
single budget, no model-specific lookup tables), added contextTurns
deprecation, and history guarantee principle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: hard cap L1 project context at 600k tokens + payload diagnostics

- Truncate project context at 2.4M chars (~600k tokens) to prevent
  total payload from exceeding model context windows (temporary fix
  until full token budget enforcement is implemented)
- Add per-layer token estimate logging when payload exceeds 2M chars
  to help diagnose context window overflow reports
- Document Obsidian CLI dev tools in CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 22:25:56 -08:00
Wenzheng Jiang
dc729fdba4
Miyo integration: backend + retriever (#2156)
* feat: integrate miyo search backend

* fix: avoid node builtins in miyo discovery

* chore: omit model name for miyo embeddings

* Revert "chore: omit model name for miyo embeddings"

This reverts commit 9d1622b7d8bd8243b5b2e301e356a42fd0c934de.

* Add Miyo debug logging for search and upsert

* Include vault path hash in Miyo source_id

* Lock Miyo embedding model in settings UI

* Update Miyo collection naming and search payloads

* Implement Miyo garbage collection

* Add Miyo time-range filters

* Remove Miyo embeddings and move Miyo search toggle

* Revert "Remove Miyo embeddings and move Miyo search toggle"

This reverts commit b0b787103561459dbd9128f6a96dad3d2914e6c9.

* refactor miyo indexing integration

* fix: resolve build type import and remove Miyo API requirement doc

* Add Miyo related-notes endpoint support for Relevant Notes

* Refine Miyo search toggle availability and indexing flow

* Update Miyo API fields and streamline relevant-notes Miyo flow
2026-02-18 18:01:18 -08:00
Logan Yang
edd1e5f00e
Fix indexing crash from ghost IDs in internalDocumentIDStore (#2182)
* Fix "Cannot set properties of undefined (setting 'embedding')" during indexing

Rebuild internalDocumentIDStore after loading partitioned chunks to eliminate
ghost IDs from removed documents that cause position mismatches. Also add
missing nchars field to Orama schema to match the OramaDocument interface.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove Notice popup spam for per-file indexing errors

Errors during indexing (e.g. "Semantic index database not found" when DB
isn't loaded yet) were triggering a Notice popup for every file event,
flooding the user with popups. Errors are already logged to console and
surfaced in the in-chat IndexingProgressCard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:25:40 -08:00
Logan Yang
ff27c472a4
Fix unwanted indexing + editor lag during indexing (#2189)
* Fix unwanted indexing when semantic search disabled + editor lag during indexing

Add defense-in-depth enableSemanticSearchV3 guard to both VectorStoreManager
and IndexOperations to prevent indexing when semantic search is off (fixes
plusUtils.applyPlusSettings bypass). Throttle Jotai atom updates to 500ms
intervals during indexing to reduce React re-renders. Yield to main thread
between batches to keep the editor responsive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove yieldToMainThread — existing awaits already yield to the event loop

The batch loop already has multiple await points (rateLimiter.wait,
embedDocuments, upsert, save) that yield to the main thread. The explicit
setTimeout(0) was redundant and added no user-perceived benefit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Guard throttled callback against stale indexing sessions

Cancel pending throttle timer in resetIndexingProgressState() so a
trailing write from a previous (failed/aborted) run cannot overwrite
the freshly-reset atom state of a new run. Also reorder declarations
so throttle variables are defined before the function that references them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:24:38 -08:00
Zero Liu
875cc0a34e
refactor: move badge close button to left icon overlay on hover (#2183)
* refactor: move badge close button to left icon overlay on hover

Centralize the icon + X overlay pattern in ContextBadgeWrapper instead of
copy-pasting the X button across all 8 badge types. The X now appears on
hover over the left icon position using invisible/visible toggling for
zero layout shift.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* support mobile

* fix keyboard control

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:12:18 -08:00
Wenzheng Jiang
ce8f406337
Fix tiny heading-only search chunks via coalescing (#2184) 2026-02-12 23:48:41 -08:00
wotan-allfather
b218dbf5b5
feat: add streamUsage config for 3rd party OpenAI-format providers (#2148)
Add optional streamUsage setting to CustomModel interface that allows users
to control whether stream_options is sent to the API. This fixes compatibility
with 3rd party providers (e.g., Databricks, MLFlow) that do not support the
stream_options parameter.

- Add streamUsage?: boolean to CustomModel interface in aiParams.ts
- Pass streamUsage to ChatOpenAI config for OPENAI_FORMAT and LM_STUDIO providers
- Add UI toggle in ModelAddDialog and ModelEditDialog with helpful tooltip
- Default to false to maintain compatibility with providers that error on stream_options

Closes #2046
2026-02-10 21:30:29 -08:00
Logan Yang
05831e345d
3.2.1 (#2177)
* Add v3.2.1 release notes

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* 3.2.1

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 20:48:05 -08:00
Logan Yang
c9b4042969
Fix ENAMETOOLONG error in Composer writeToFile tool (#2176)
Sanitize LLM-generated file paths before creating files to prevent
ENAMETOOLONG crashes on Linux (ext4 255-byte filename limit). Truncates
overlong basenames while preserving file extensions and multi-byte
character boundaries. Sanitization happens at the tool entry point so
the preview flow (ApplyView) also receives the safe path.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-10 20:24:43 -08:00
Logan Yang
9535bf5a74
Replace indexing Notice with in-chat progress card & fix phantom re-indexing (#2173)
* Replace indexing Notice with in-chat progress card & fix phantom re-indexing

Replace the Obsidian Notice popup for indexing progress with a persistent
in-chat progress card using the same Jotai atom pattern as project mode.

Key changes:
- New IndexingProgressCard component with progress bar, pause/resume/stop,
  error display, and auto-close on completion
- Jotai atom (indexingProgressAtom) driven by IndexOperations, read by React
- Card only appears when files actually need indexing (no flash on mode switch)
- User-initiated actions (refresh/reindex buttons) show "Index Up to Date"
  feedback with green check icon
- Fix phantom re-indexing: checkIndexIntegrity() is now diagnostic-only
- Fix progress bar accuracy: totalFiles counted after chunk preparation
- Remove duplicate completion Notices from ChatControls and RelevantNotes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix insert/replace at cursor including agent reasoning blocks (#2174)

Strip <!--AGENT_REASONING:...--> markers in cleanMessageForCopy() so
that "Insert / Replace at cursor" only inserts the actual AI response,
not the internal agent reasoning metadata.

Uses greedy .* (single-line) so the regex matches to the real closing
--> even if the JSON payload contains that sequence.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* Restore integrity check marking files for re-indexing

checkIndexIntegrity() was made diagnostic-only to fix phantom
re-indexing, but this left files with missing embeddings permanently
skipped. The real safeguard is clearFilesMissingEmbeddings() at the
start of each indexing run, which prevents the repeat cycle. Restore
the mark so the next indexing trigger picks up integrity failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 20:08:43 -08:00
Logan Yang
3e323ba8c8
Fix insert/replace at cursor including agent reasoning blocks (#2174)
Strip <!--AGENT_REASONING:...--> markers in cleanMessageForCopy() so
that "Insert / Replace at cursor" only inserts the actual AI response,
not the internal agent reasoning metadata.

Uses greedy .* (single-line) so the regex matches to the real closing
--> even if the JSON payload contains that sequence.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 19:54:52 -08:00
Logan Yang
6e6ada0431
Fix local search: simplify pipeline, extract FilterRetriever, fix grep filtering (#2172)
* Simplify search pipeline: remove expandedTerms, use metadata-cache tag matching

- Remove `expandedTerms` concept from QueryExpander, FullTextEngine, SearchCore,
  and all interfaces — LLM expansion now only produces `salientTerms` and
  `expandedQueries`, no separate related-term list
- Remove weighted 90/10 two-phase scoring from FullTextEngine; use single BM25+
  search with salient terms for ranking
- Replace tag-based `returnAll` mode with Obsidian metadata-cache tag matching:
  `getTagMatches()` uses `getAllTags()` with hierarchical prefix matching and
  injects tag-matched notes as guaranteed full-note documents (score 1.0)
- Remove `buildTagRecallQueries()` tag-hierarchy splitting from SearchCore
- Add `isGrepWorthy()` filter in GrepScanner to skip short ASCII terms (< 3 chars)
- Reduce default candidateLimit and grepLimit from 500 to 200
- Rewrite search v3 README to reflect current implementation
- Update all tests for removed fields and new tag-match injection behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix isGrepWorthy filtering out valid 2-char terms like "AI", "ML", "UI"

SearchCore lowercases all recall terms before passing to GrepScanner, so
acronym detection by casing is impossible. Lower the threshold to filter
only single-char terms — grep is capped at 200 results anyway, and BM25+
handles precision downstream.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Extract FilterRetriever from TieredLexicalRetriever for guaranteed filter matching

Move deterministic title/tag/time-range matching into standalone FilterRetriever
class that runs at the orchestration layer (SearchTools, VaultQAChainRunner,
customSearchDB). This ensures filter results bypass all downstream retriever
processing (top-K slicing, score normalization) and reach the LLM context via
separate <filterResults>/<searchResults> XML sections with continuous ID numbering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Cap FilterRetriever tag and time-range results to maxK/RETURN_ALL_LIMIT

Prevents unbounded filter result sets (e.g. common tags like #daily) from
blowing up prompt/context size and read latency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Clean up legacy parser, dead code, and DRY violations

- Remove parseLegacyFormat from QueryExpander (fall back to fallbackExpansion for non-XML LLM responses)
- Remove dead fuzzy variant generation in fallbackExpansion
- Remove deprecated expandQueries backward-compat method
- Extract shared mapDoc helper in SearchTools to eliminate duplicated document mapping
- Use existing toIsoString helper in formatSplitSearchResultsForLLM
- Add FilterRetriever cap regression tests for maxK and RETURN_ALL_LIMIT
- Convert legacy-format tests to XML format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Restore expanded limits for tag queries in VaultQAChainRunner

Pass returnAll: true when tagTerms are present so FilterRetriever
and the main retriever use RETURN_ALL_LIMIT instead of maxK cap.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Cap merged filter+search results to prevent oversized prompts

Filter and search results are now capped post-merge (filter results
prioritized) to prevent 100-200 doc payloads on tag-heavy queries.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add retrieval cap notice in VaultQA to prompt Copilot Plus upgrade

When merged filter+search results exceed the retrieval cap, the AI
is instructed to inform the user that some documents were omitted
and suggest upgrading to Copilot Plus for more complete answers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 16:01:55 -08:00
Logan Yang
c2fe511eb8
3.2.0 (#2170)
* Add RELEASES.md with full release history and v3.2.0 draft

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* 3.2.0

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 12:54:44 -08:00
Logan Yang
3de16740ec
Show Self-Host Mode section to all users with disabled toggle (#2169)
* Show Self-Host Mode section to all users with disabled toggle for non-lifetime

The Self-Host Mode settings section is now visible to everyone instead of
being hidden behind an eligibility check. The toggle is disabled (greyed out)
for users who are not on a lifetime plan (believer/supporter), making the
feature discoverable while preserving the access restriction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix self-host toggle not disabled after removing license key

Three issues fixed:
1. useIsSelfHostEligible() checked grace period before license key,
   so removing the key didn't revoke eligibility while in grace period.
   Moved license key check to the top and added auto-revocation of
   enableSelfHostMode when key is absent.
2. isSelfHostModeValid() didn't check license key at all, so backend
   code (RetrieverFactory, isPlusEnabled) continued to grant self-host
   access after key removal. Added license key guard.
3. useIsPlusUser() self-host bypass didn't check license key. Added
   the same guard for consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix self-host toggle not disabled when switching to non-lifetime key

useIsSelfHostEligible() trusted cached grace period / permanent
validation before consulting the API, so swapping from a believer
key to a plus key kept the toggle enabled.

Now always verifies via API when a license key is present. Cached
validation (grace period, permanent count) is only used as an
offline fallback when the API call fails. Also auto-revokes
enableSelfHostMode when the API confirms the key is not eligible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 11:34:45 -08:00
Logan Yang
69f668f7f3
Replace warning triangle with Build Index button in Relevant Notes (#2168)
* Replace warning triangle with Build Index button in Relevant Notes

Improves UX when semantic search is off or index is unavailable by replacing
the yellow warning triangle and text with a clear "Build Index" button that
enables semantic search (with confirmation modal) and triggers vault indexing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add reactive index signal and move Build Index button to header

- Create indexSignal pub-sub so UI reacts to external index changes
  (clear, rebuild, reindex) without manual refresh
- Fire notifyIndexChanged() from VectorStoreManager (single source)
- Move Build Index button to header area so it's always visible when
  !hasIndex, even when link-based relevant notes are showing
- Update help tooltip to mention semantic search requirement

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 22:39:00 -08:00
Logan Yang
35bc50b47c
Remove HyDE query rewriting from HybridRetriever (#2167)
HyDE (Hypothetical Document Embeddings) rewrites user queries into
hypothetical answer passages before embedding them for vector search.
This produces garbage for non-question queries like "find all my ai
digests" — the LLM generates an instructional essay instead of useful
search terms, polluting semantic results and causing Plus mode to miss
relevant notes that Agent mode finds via multiple search iterations.

Removing HyDE:
- Eliminates an extra LLM call per search (faster responses)
- Uses the raw query for vector embedding search (better matching)
- QueryExpander already handles LLM-based query expansion correctly
- hybridRetriever.ts is already marked DEPRECATED

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 16:56:51 -08:00
Logan Yang
baea3079c8
Update builtin models to latest versions across all providers (#2166)
- Add Claude Opus 4.6, Sonnet 4.5 (replacing Sonnet 4)
- Add Gemini 3 Flash/Pro preview (Google direct + OpenRouter)
- Add GPT-5.3 Codex, upgrade OpenRouter GPT to 5.2/5-mini
- Upgrade Grok 4-fast to 4.1-fast (xAI + OpenRouter)
- Remove Gemini 2.5 Flash Lite, demote GPT-4.1 to non-core
- Preview models are not core or project-enabled
- Extend thinking model detection for Claude Opus 4.x

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 16:34:58 -08:00
Logan Yang
cbe75e76a3
Fix search recall with note-diverse top-K and chunk-aware scoring (#2165)
* fix: improve search recall with note-diverse top-K, chunk-aware scoring, and adaptive cutoff module

- Add note-diverse top-K selection so every unique note gets representation
  before any note gets a second chunk slot (fixes "find my ai digests" missing notes)
- Fix GraphBoostCalculator: resolve chunk IDs to note paths for metadata lookups,
  deduplicate to note level in filterCandidates
- Fix FolderBoostCalculator: count unique notes per folder instead of raw chunks
- Bump title field weight 3→5 for stronger filename match priority
- Add AdaptiveCutoff module (standalone, not yet plugged in) for score-based
  adaptive result limiting — designed for future Jina Reranker v3 integration
- Extract shared chunkIdUtils for consistent chunk ID → note path conversion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Hardcode maxSourceChunks to 30 and remove user setting

Replace settings.maxSourceChunks with DEFAULT_MAX_SOURCE_CHUNKS (30)
across all retriever call sites. Remove the "Max Sources" slider from
QA settings — recall and precision are now handled automatically by
diverse top-K selection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: expose returnAll to LLM for exhaustive "find all" vault queries

Queries like "find all my AI digests" previously capped at 30 results.
Time-range and tag queries already bypassed this via shouldReturnAll,
but the trigger was mechanical. This exposes the returnAll concept to
both Agent chain (via tool schema + instructions) and CopilotPlus chain
(via planning prompt extraction) so the LLM can set it based on user
intent, returning up to 100 results when appropriate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: replace raw tool names with human-friendly summaries in reasoning block

Add explicit cases for all tools (getFileTree, getTagList, time tools,
updateMemory, indexVault, youtubeTranscription) so the agent reasoning
block never exposes internal tool names. Default fallbacks now show
"Processing" / "Done" instead of "Calling toolName" / "Completed toolName".
Failure messages also use the friendly summary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 13:31:59 -08:00
Wenzheng Jiang
bee0a66958
Miyo Integration Phase 1: abstract semantic index backend (#2155)
* refactor: abstract semantic index backend

* refactor: abstract get documents by path
2026-02-07 21:39:59 -08:00
Logan Yang
8cea1a6f17
Audit context envelope, tag alignment, artifact dedup, and logging (#2164)
* fix: align context block tags and make parseContextIntoSegments registry-driven

The context envelope L2 layer was silently dropping URL/media context across
turns due to three compounding issues:

1. Tag mismatch: Mention.ts created <youtube_transcript> blocks but the
   contextBlockRegistry expected <youtube_video_context>. Fixed the tag and
   inner element (<transcript> → <content>) to match the registry.

2. Missing registration: twitter_content blocks had no registry entry, so
   they were invisible to compaction and segment parsing. Added the entry.

3. Hardcoded parser: parseContextIntoSegments only matched <note_context>,
   <active_note>, and <prior_context> via hardcoded regexes, silently
   ignoring all URL/media block types. Rewrote it to dynamically build its
   regex from CONTEXT_BLOCK_TYPES, ensuring any future block type added to
   the registry is automatically handled.

Extracted parseContextIntoSegments into src/context/parseContextSegments.ts
as a standalone pure function for direct testability.

Added 19 new tests covering all registered block types, mixed blocks,
stable/unstable flags, and a registry completeness guard test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: context envelope improvements - regeneration, dedup, per-artifact IDs, XML escaping

Phase A: Fix regeneration from loaded chats by lazily reprocessing context
when contextEnvelope is missing (e.g., messages loaded from disk).

Phase B: Replace static segment IDs ("urls", "selected_text", "web_tabs")
with per-artifact IDs from parseContextIntoSegments, enabling accurate
smart referencing in LayerToMessagesConverter.

Phase C: Deduplicate L2 content by segment ID (last-write-wins) to prevent
linear growth when the same artifact appears across multiple turns.

Phase D: Escape note title/basename in XML context blocks for consistency
with URL/YouTube content. Keep path unescaped as it's used as identifier.

Additional fixes from Codex review:
- Unique IDs for blocks without source extractors (selected_text counter)
- Keep note.path raw to avoid dedup mismatch with TFile.path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: prevent context artifact duplication in LLM payload and L4 memory

CopilotPlusChainRunner was re-injecting processedText (which includes
context XML artifacts) into the user message via ensureUserQueryLabel,
bypassing the envelope's clean L2/L3/L5 separation. This caused context
like YouTube transcripts to appear 3x in the LLM payload.

Fix: use L5_USER envelope text (expanded user query without context XML)
instead of processedText for cleanedUserMessage, trimmedQuestion fallback,
and messageForAnalysis. Also fix BaseChainRunner.handleResponse to save
L5 text to L4 memory instead of processedText.

Other changes:
- Remove dead updateMemoryWithLoadedMessages from chainManager
- Update CONTEXT_ENGINEERING.md with example walkthrough, L4 behavior
  docs, and Phase 6 integration test suite roadmap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add chain runner envelope usage section and fix Step 0 log

Document per-runner envelope behavior, CopilotPlus/Agent tool flows,
and token efficiency audit in CONTEXT_ENGINEERING.md. Fix Step 0 log
to show L5 user query instead of processedText with context XML.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: trim trailing whitespace from chat input display text

Trailing newlines from Lexical editor were preserved in displayText
and rendered as empty lines in chat bubbles due to whitespace-pre-wrap.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 21:18:25 -08:00
Logan Yang
54ca66f5a3
Add twitter4llm support for Twitter/X URL processing (#2161)
Route Twitter/X URLs (x.com, twitter.com with /status/) to the new
brevilabs twitter4llm endpoint instead of the generic url4llm endpoint.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:54:18 -08:00
Logan Yang
b8efcc1c81
fix: remove tiktoken remote fetch from critical LLM path (#2160)
LangChain's default getNumTokens() fetches a ~3MB gpt2.json BPE
vocabulary from tiktoken.pages.dev at runtime. When this CDN is
unreachable, all LLM calls (stream, invoke) hang until timeout,
completely blocking the plugin. Override getNumTokens on every model
instance with a simple char-based estimation — modern LLM APIs return
accurate token usage in response metadata anyway.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:17:55 -08:00
Logan Yang
c93358df82
Implement modular context compaction architecture (#2159)
* refactor: modular context compaction architecture

Split context compaction into focused modules:
- contextBlockRegistry: single source of truth for block types
- compactionUtils: shared pure functions for truncation/extraction
- ChatHistoryCompactor: tool result compaction at memory save time
- L2ContextCompactor: L3→L2 context compaction with previews

Key changes:
- Never compact selected_text (non-recoverable content)
- Single consolidated re-fetch instruction at end of L2 context
- Write-time compaction via memoryManager.saveContext()
- Parse prior_context blocks in segment extraction
- Backwards compatibility via re-exports

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: use brace-balanced extraction for readNote JSON parsing

The previous regex-based approach stopped at the first closing brace,
truncating JSON payloads containing nested braces (e.g., code snippets).
This caused JSON.parse to fail and skip compaction entirely.

Now uses a proper brace-balanced parser that correctly handles:
- Nested objects and arrays
- Braces inside string literals
- Escaped characters in strings

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: preserve all documents in localSearch compaction

Previously, compactToolResultBlock used extractContentFromBlock which
only extracts the first <content> match. For localSearch results with
multiple <document> blocks, this caused all documents after the first
to be lost during compaction.

Now localSearch blocks are handled specially:
- All documents are extracted and preserved
- Each document keeps its title and path
- Content is truncated to preview length
- Output lists all documents with [[wikilink]] format

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: skip flaky composer integration tests

Skip composer integration tests due to intermittent 503 errors from
Gemini API causing CI failures. The tests depend on external API
availability which is unreliable.

TODO(@logancyang, @wenzhengjiang): Re-enable once composer is revamped.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: preserve all blocks when compacting multi-block L2 segments

When URL context segments contain multiple concatenated <url_content>
blocks (from processUrlList), the previous compaction only processed
the first block. Now detects multiple blocks of the same type and
compacts each one independently, preserving all URL context.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: preserve mixed XML block types during L2 compaction

The previous fix only handled multiple blocks of the same type. When
segments contain mixed block types (e.g., web_tab_context mixed with
youtube_video_context from processContextWebTabs), blocks of other
types were dropped.

Now uses CONTEXT_BLOCK_TYPES registry to match all known block types
and compacts each one independently, preserving all context regardless
of block type mix.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 21:52:33 -08:00
Emt-lin
c76235a326
fix: improve mobile keyboard/navbar CSS scoping and platform detection (#2157)
* fix: improve mobile keyboard/navbar CSS scoping and platform detection

* fix: clear drawer keyboard class when view moves out of drawer

Track the last drawer element so that when the Copilot view is moved
out of a drawer while the soft keyboard is open, the copilot-keyboard-open
class is properly removed from the old drawer, restoring its header/tab UI.
2026-02-06 10:09:47 -08:00
Logan Yang
aa71040702
Fix lm studio chat with only ending think tag (#2153)
* Fix missing opening <think> tag for models like nvidia/nemotron

Some models output thinking content with only a closing </think> tag
due to misconfigured chat templates in LM Studio. This adds post-processing
to detect and fix this by prepending the opening <think> tag, with a
warning logged to help users identify the template issue.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix agent mode to properly strip thinking tokens from response

Agent mode was showing thinking content in final responses because
streamModelResponse() bypassed ThinkBlockStreamer entirely. Now
integrates ThinkBlockStreamer with excludeThinking=true to properly
filter thinking tokens from all sources (Claude, Deepseek, OpenRouter,
LM Studio text-level <think> tags).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 22:05:31 -08:00
Logan Yang
27d7a667b2
Add reasoning/thinking token support for LM Studio (#2151)
* Add reasoning/thinking token support for LM Studio

- Use ChatOpenRouter for LM Studio to capture delta.reasoning from streaming responses
- Add enableReasoning and reasoningEffort config for LM Studio models
- Show Reasoning Effort UI for any model with REASONING capability enabled
- Consolidate duplicate OpenRouter reasoning effort UI into unified component
- Translate Chinese comments to English

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Update GPT-5 to GPT-5.2 and add xhigh reasoning effort

- Rename GPT_5 to GPT_5_2 (model name "gpt-5.2")
- Add XHIGH reasoning effort level for GPT-5.2 models
- Update ChatOpenRouter type to support "xhigh" effort
- Show Extra High option only for GPT-5.2 OpenAI models
- Translate Chinese comments to English

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix tool_calls not forwarded in ChatOpenRouter message conversion

The toOpenRouterMessages() method was only handling legacy function_call
but not modern tool_calls format, causing autonomous agent tool flows
to break for LM Studio and OpenRouter models.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 18:29:09 -08:00
Emt-lin
57e95c34e6
fix: GitHub Copilot mobile CORS bypass and auth UX improvements. (#2140)
# Conflicts:
#	src/LLMProviders/githubCopilot/GitHubCopilotProvider.ts
2026-02-04 17:32:56 -08:00
Emt-lin
918969fc18
feat: add PatternListEditor component for include/exclude settings (#2141)
* feat: add PatternListEditor component for include/exclude settings

Add a new PatternListEditor component to manage include/exclude patterns
in QA settings with support for folders, tags, notes, and file extensions.

- Collapsible list UI with smooth expand/collapse animation
- Dropdown menu for adding different pattern types via modals
- Robust URI decoding with try/catch to prevent settings page crash
- Pattern deduplication via getUniquePatterns helper
- Test coverage for malformed URI sequences

# Conflicts:
#	src/styles/tailwind.css

# Conflicts:
#	src/styles/tailwind.css

* chore: translate Chinese comments to English in PatternListEditor
2026-02-04 17:31:55 -08:00
Logan Yang
b128b25558
Agent UIUX Improvements (#2149)
* Use openrouter openai embedding small as default embedding model

* Increase agent max iterations to 16 and add 5-minute loop timeout

- Raise max tool call iterations limit from 8 to 16
- Add AGENT_LOOP_TIMEOUT_MS constant (5 minutes) to prevent runaway loops
- Update slider max in settings UI to match new limit
- Show appropriate message when loop exits due to timeout vs max iterations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Update agent reasoning spinner to sigma shape with smooth animation

- Change from 9-dot diamond to 7-dot sigma (Σ) pattern
- Animation traces sigma shape: top-right → top-left → center → bottom
- Use ease-in-out timing and gradual opacity transitions for smooth motion
- Adjust size to 13.5px for better alignment with text

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Improve agent reasoning step summaries and fix composer tool UX

- Add meaningful summaries for writeToFile/replaceInFile tools
  (e.g., "Writing to filename" instead of "Calling writeToFile")
- Show "Edit rejected" when user rejects changes in diff view
- Fix "Changes applied successfully" notice showing on reject
- Extract model's intermediate reasoning as finding summaries
- Add TODO doc for composer tool redesign to address 30s feedback gap

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Add self-host mode eligibility gating and permanent validation

- Increase tool timeout from 60s to 120s
- Show self-host mode section only to Believer/Supporter plan users
- Add permanent validation after 3 consecutive successful checks
- Add useIsSelfHostEligible hook for offline-friendly eligibility check
- Preserve permanent validation status when re-enabling self-host mode

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix self-host validation to require 14-day intervals between count increments

- Only increment validation count when 14+ days have passed since last check
- Document need for structured ComposerTools results in TODO doc
- Add TODO for no-op case handling in AgentReasoningState

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix self-host validation timer and offline re-enable issues

- Don't reset timestamp when < 14 days (preserves interval countdown)
- Allow permanently validated users to see section even if toggle is off
- Supports offline re-enable for users with 3+ successful validations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Wire refreshSelfHostModeValidation into plugin startup

Enables the 14-day periodic validation to actually increment the count
toward permanent self-host mode (3 successful checks).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Improve self-host mode validation with offline support and documentation

- Add grace period check in validateSelfHostMode for offline re-enable
- Change grace period from 14 to 15 days
- Add comprehensive documentation explaining validation flow
- Fix offline re-enable for users within grace period

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 17:10:28 -08:00
Logan Yang
54e341ca88
Update ollama (#2147)
* Update ollama chat model to fix thinking

* fix: consolidate tool call parsing and add actionable error logging

- Remove duplicate tool call parsing in AutonomousAgentChainRunner
  by using shared buildToolCallsFromChunks() function
- Add sanitizeToolArgs() to remove empty objects from tool args
  (fixes Ollama returning timeRange: {} which fails Zod validation)
- Add actionable logging for tool call failures with full args context
- Clean up unused parameters in AutonomousAgentChainRunner
- Simplify ToolManager.callTool to throw instead of swallowing errors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: add repeatPenalty for Ollama to reduce repetitive outputs

Local models via Ollama are prone to repetitive hallucination loops.
Adding repeatPenalty=1.1 applies a slight penalty to repeated tokens,
which helps reduce this pattern.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: increase Ollama context window to 128k

Default numCtx of 8192 causes prompt truncation with larger contexts.
Setting numCtx=131072 (128k) to support models with large context.
Ollama automatically caps at model's actual maximum if exceeded.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: handle Ollama empty object tool args at schema level

- Make timeRange inner fields (startTime, endTime) optional in schema
- Update validateTimeRange to handle empty or partial objects from LLMs
- Apply validation in all search tools (local, lexical, semantic)
- Remove sanitizeToolArgs function that was too aggressive
- Fixes tool calls that legitimately accept {} as valid input

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 22:18:39 -08:00
Logan Yang
308c88332d
Address quick ask (#2146)
* chore: translate Chinese comments to English and apply formatting

- Translate all Chinese comments in replaceGuard.ts to English for consistency
- Apply Prettier formatting to 33 files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: add unit tests for Quick Ask core modules

Add comprehensive tests for:
- replaceGuard.ts: validation logic, error messages, MapPos and Highlight strategies
- persistentHighlight.ts: CM6 state field, range mapping, show/hide behavior
- quickCommandPrompts.ts: placeholder appending logic

64 new test cases covering edge cases like:
- Leaf/editor/file change detection
- Document bounds validation
- Content change detection
- Range mapping through document changes
- Case-insensitive placeholder detection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 20:04:10 -08:00
Emt-lin
76520d0259
Add Editor "Quick Ask" Floating Panel + Persistent Selection Highlights (#2139)
* feat: implement floating quick command with AI-powered inline editing

Add a new floating quick command feature that allows users to interact
with AI directly from the editor. Key features include:

- Quick Ask panel with draggable modal interface
- Multiple interaction modes: ask, edit, and edit-direct
- Selection highlight and replace guard for safe text operations
- Streaming chat session support for real-time AI responses
- Context menu integration for quick access
- Resizable and draggable UI components

# Conflicts:
#	src/commands/CustomCommandChatModal.tsx
#	src/styles/tailwind.css

* feat: add persistent selection highlight for Chat panel

* refactor: extract persistent highlight factory and fix state consistency

* fix: improve popup positioning with flip logic and line-start trap fix

- Use selection.head instead of selection.to for anchor point
- Fix line-start trap: only apply when head is selection end
- Add flip logic: show above when not enough space below
- Add horizontal visibility check
- Single-line selection: center popup horizontally
- Multi-line selection: follow head position
- Cursor mode: align near cursor instead of centering
2026-02-03 17:37:33 -08:00
Zero Liu
800547534a
fix: prevent arrow keys from getting stuck in typeahead with no matches (#2137)
When the typeahead menu is triggered but the query matches nothing,
the menu visually disappears but state.isOpen remains true. Arrow key
handlers were checking only isOpen, intercepting events even with no
options to navigate. This trapped the cursor.

Add early return (return false) in ArrowDown/ArrowUp handlers when
options.length === 0, consistent with how Enter/Tab already handle
this case. Arrow keys now propagate normally for cursor movement
when there are no typeahead matches.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 11:06:04 -08:00
Logan Yang
1e3e0786ef
Migrate to native tool call in plus and agent (#2123)
* Implement self-host mode
* Migrate from XML tool calls to native tool calls and reimplement agent mode
* Use ChatOpenRouter for copilot-plus-flash for native tool call sse support
* Fix QA exclusion for search v3
* Update plan and remove debug messages in agent
* Migrate chains off of xml and clean up related logic
* Implement agent reasoning block
* Update css for responsiveness
* Implement agent query pre-expansion and proper reasoning block display for search
* Update agent docs
* Refine agent reason block
* Refine agent reasoning UX
* Fallback to plus non-agent if native tool call is not supported by the model
* Fix time filter query
* Update self-host description
* Skip agent reasoning block and old tool call banners during chat save and load
* Fix projects mode switch to plus and chat auto saves as non-project bug
2026-01-26 18:35:27 -08:00
Logan Yang
fdef63fe0e
fix: increase grep limit for larger vaults and unify chunking (#2117)
* fix: increase grep limit for larger vaults and enhance search prioritization
* fix: unify chunk management over index-free and semantic search
* fix: batch process files in prepareAllChunks to bypass ChunkManager's 1000-file limit
* fix: update regex to correctly find closing frontmatter delimiter at EOF
* fix: enhance security checks to prevent path traversal vulnerabilities
* fix: refactor to use shared ChunkManager instance across components for improved cache management
* fix: enhance cache retrieval in ChunkManager to support non-default chunk options
2026-01-19 11:43:38 -08:00
Logan Yang
382d88328e
3.1.5 (#2116) 2026-01-15 12:36:07 -08:00
Logan Yang
1d937cf50e
Adjust settings (#2115)
* feat: update setting slider value display and modify auto-compact threshold description

* feat: update auto-compact threshold description for clarity

* feat: improve display of large slider values with better formatting
2026-01-15 11:53:49 -08:00
Emt-lin
5bfb6fb6f5
fix: Github Copilot add streaming support and improve robustness (#2113)
- Add streaming response with SSE parsing (eventsource-parser)
- Add Accept: text/event-stream header and content-type validation
- Add empty output detection to prevent silent failures
- Unify token expiry logic between getAuthState() and getValidCopilotToken()
- Add proper resource cleanup with reader.cancel()
- Add request cancellation handling in GitHubCopilotAuth component
- Extract HTTP_STATUS_MESSAGES constant
- Remove fallback mechanism for simpler error handling
2026-01-15 11:31:48 -08:00
Emt-lin
957b62a9f3
Feat/default indicator and slash command fix (#2114)
* fix: record usage when selecting slash command from input

Slash commands selected via "/" in the chat input were not updating
lastUsedMs, causing recency sorting to not work properly. Other entry
points (command palette, context menu) already called recordUsage.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add default indicator for system prompts

- Rename "(Global)" to "(Default)" in system prompt dropdown labels
- Add "(Default)" marker in AdvancedSettings for selected default prompt
- Sync default flag to frontmatter when default system prompt changes
- Handle edge case when folder and default title change simultaneously
- Add logWarn when prompt file not found during default flag update

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 11:31:31 -08:00
Logan Yang
b740614d2d
Support openrouter embeddings (#2112)
* Remove auto-accept edit from settings

* feat: add OpenRouterAI support in embedding manager and model dialog
2026-01-14 17:00:09 -08:00
Logan Yang
ab0895a382
Remove transcript (#2111)
* feat: remove transcript formatting instructions from constants

* feat: remove Chinese summary and key takeaways sections from constants
2026-01-14 15:14:48 -08:00