Commit graph

7 commits

Author SHA1 Message Date
Zero Liu
83f1f7070e
feat(models): flag non-vision models, guard image sends (#2627)
* feat(models): guard image sends to non-vision chat models

Add a shared modelSupportsVision() helper and block sends in
Chat.handleSendMessage when images are attached but the active chat
model is known to lack vision — Notice names the model and preserves
the typed text + images instead of failing silently.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(agent-mode): guard image sends to non-vision agent models

Enrich agent picker entries with capabilities derived from the
models.dev catalog (by provider + baseModelId), and apply the same
known-non-vision guard in AgentChatInput. Models we can't resolve in
the catalog keep capabilities undefined and are never falsely blocked.
Catalog access is threaded as a structural type to respect the
agent-mode ui import boundary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(byok): show model capabilities + add vision/reasoning overrides

Render read-only capability icons per model row in the Configure
provider dialog, and add a collapsible Advanced panel with per-model
vision/reasoning toggles. Overrides overlay onto ConfiguredModel.info
modalities/reasoning at save, surviving the catalog-first resolve
precedence (R1) and flowing through the existing bridge to become
CustomModel.capabilities.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(models): show modality icons in BYOK + agent pickers; hide reasoning icon

BYOK checklist and the agent-mode model picker derived capabilities from the
async models.dev catalog but never loaded/reacted to it, so no icons rendered
(legacy works only via hardcoded BUILTIN_CHAT_MODELS.capabilities). Warm the
catalog and re-render on change in both surfaces.

Hide the reasoning/"thinking" capability icon everywhere (ubiquitous on modern
frontier models) while keeping ModelCapability.REASONING in the data model so
runtime extended-thinking gating (chatModelManager, chain runners, Bedrock)
stays intact.

- CatalogLookup: optional ensureLoaded()/onChange(); useAgentModelPicker warms
  + re-renders on catalog populate
- ConfigureProviderBody: ensureLoaded + onChange bumps catalogMetadata memo;
  drop the Reasoning override toggle (keep Vision)
- model-display: remove reasoning icon + "Reasoning" text label

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(agent-models): show vision icon in agent pickers from persisted info

The settings agent model picker (ModelEnableList) rendered no capability
icons at all, and the chat agent picker derived them only from a live,
often-cold models.dev catalog lookup keyed by reported provider — so the
vision icon never showed reliably for agent models.

Source vision from each model's persisted ConfiguredModel.info.modalities
(the snapshot taken at setup, like Copilot Plus's explicit image input) —
the same single source of truth BYOK and legacy already use, no live
catalog required:

- EnabledModelEntry gains optional `capabilities`; the claude/codex and
  opencode enabled-entry builders populate it via capabilitiesFromConfiguredInfo
  (undefined when info has no modalities → picker still falls back to catalog)
- chat agent picker prefers enabled.capabilities over the catalog lookup
- ModelEnableList renders ModelCapabilityIcons; toRow derives them from info,
  so the settings agent + Quick Chat lists finally show the vision icon

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* update modality indicator

* refactor(byok): remove manual vision capability override

The "Advanced" section in the Configure Provider dialog let users
manually toggle a model's Vision capability — unintuitive, since
vision is already detected automatically from the models.dev catalog
(or the persisted snapshot). Remove the override entirely.

- Drop the Advanced collapsible + its override state/plumbing
  (capOverrides, applyCapsToModelInfo, CapFlags) and retire the
  Risk R1 override-preservation logic; capabilities now ride on each
  ModelInfo via resolveModelInfo.
- Fix the chat image-block notice that pointed at the now-removed
  "enable Vision in provider settings" path.

Automatic detection (modality icons, image-send guards) is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(agent-picker): drop live-catalog fallback; use persisted capabilities only

The "snapshot at save time" architecture already exists — every
ConfiguredModel.info carries modalities + reasoning, and all three agent
backends feed the picker capabilities from that persisted snapshot. The live
models.dev catalog in the picker was a redundant fallback, so this removes it
entirely along with the complex useCatalogVersion hook.

- agentModelPickerHelpers: delete CatalogLookup/CatalogModelInfo,
  capabilitiesFromModelInfo/lookupCatalogModelInfo/capabilitiesFromCatalog;
  drop the catalog param throughout; capabilities = enabled.capabilities.
- useAgentModelPicker: delete useCatalogVersion; drop catalog arg + memo dep.
- AgentHome: useAgentModelPicker(manager) — no longer threads catalogService.
- tests: replace catalog-enrichment specs with persisted-capability propagation.

ConfigureProviderDialog/ByokPanel keep the live catalog — they show
capabilities for not-yet-saved models, which have no persisted snapshot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(byok): show modality icon in BYOK settings model table

Render the shared capability icon inline after each model name in the
read-only BYOK table, reusing capabilitiesFromConfiguredInfo + the same
ModelCapabilityIcons treatment the Configure dialog already uses. Brings
the last model surface to parity: a muted eye-off marks models that can't
take image input (incl. text-only embeddings), vision-capable and
unknown-modality models stay silent.

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

* refactor(model-display): drop web-search globe badge; eye-off is the only modality signal

The no-vision eye-off is now the sole capability icon: web-search is no
longer badged with a globe, and getModelDisplayWithIcons stops appending a
"Websearch" suffix. hasCapabilityIcons/ModelCapabilityIcons reduce to a
single 'known to lack vision' check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(chat-picker): treat unknown model capabilities as unknown, not text-only

useChatModelPicker hand-rolled its capabilities array, always emitting an
empty (but defined) array even when ConfiguredModel.info.modalities was
absent. The Chat.tsx image guard reads a defined array as "known", so
legacy/manual/unknown snapshots got the eye-off icon and had images blocked.
Use capabilitiesFromConfiguredInfo() so capabilities stay undefined when
modalities are missing — matching the agent pickers and the intended
"unknown stays unblocked" semantics.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 00:02:47 -07:00
Zero Liu
710acc2436
chore(lint): enable obsidianmd/no-global-this and fix violations (#2413)
Removes the deferred `"off"` override and rewrites the 55 violations
(all in test/mocks/Node-script files) to use `window.*` instead of
`global.*`. Production code was already cleaned up in #2401.

- 18 test files + __mocks__/obsidian.js + jest.setup.js: mechanical
  `global.X` → `window.X` (Jest runs under jsdom, so window === globalThis)
- scripts/printPromptDebugEntry.ts: inline eslint-disable — Node-only
  debug script with no window available

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 01:14:47 -07:00
Zero Liu
17739cafa0
Enable basic obsidian eslint rules (#2410) 2026-05-13 00:49:49 -07:00
Zero Liu
c67c4fc200
fix(popout): document ownership and selection listener fixes (W4/9) (#2406)
* fix(popout): document ownership and selection listener fixes (W4/9)

Fifth of nine workspaces splitting #2397. Real popout-window
correctness fixes — semantic choices about which window owns a DOM
operation, plus selection-listener captured-document fixes.

- document → activeDocument where a generic active-window lookup is
  correct (SourcesModal, ChatViewLayout, ItemView/Notice mocks,
  TabContext, ChatInput keydown listener, CopilotView keyboard
  observer, TypeaheadMenuPortal, AddImageModal, and ?? document
  fallbacks across draggable-modal, menu-command-modal,
  CustomCommandChatModal, use-draggable, use-resizable, and
  QuickAskOverlay).
- document → root.ownerDocument in ChatSingleMessage's
  linkInlineCitations so DOM nodes end up in the citation's window;
  same pattern in the processMessage streaming block via
  contentRef.current.ownerDocument.
- New getEditorDocument(editor) helper in BasePillNode. createDOM and
  exportDOM now accept the LexicalEditor; pills create DOM in the
  editor's window (correct popout behavior). All 6 pill subclasses
  updated to match the new signature.
- main.ts: selectionListenerDocument captured at listener registration;
  remove uses the same document (fixes leak when activeDocument has
  drifted before unload).
- chatSelectionHighlightController.ts: getActiveViewOfType(MarkdownView)
  replaces the brittle activeLeaf type comparison.
- Test setup: (window as any).activeDocument = window.document in
  ChatSingleMessage.test; window.document.createElement in
  AgentPrompt.test Notice mock.

Behavior fix: chat in a popout window now creates DOM nodes in the
popout's document, not the focused window's document.

W0, W1, and #2402 already merged.

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

* fix(popout): prefer element.doc/.win over ownerDocument and activeDocument

Switch popout-window-sensitive call sites to Obsidian's `.doc` / `.win`
augmentations so DOM ops, listeners, portals, and positioning follow the
element's actual owner window. Recreate Lexical root on view migration to
rebind input handling after a leaf moves between windows. Document the
decision order in AGENTS.md and polyfill `Node.doc` / `Node.win` in
jest.setup.js so tests still run under jsdom.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* improve image upload implementation

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 21:28:04 -07:00
Zero Liu
ef3b0004d4
Avoid full vault scan on incremental indexing (#1148)
* Avoid full vault scan on incremental indexing
* Exclude inline tag
2025-02-02 16:24:15 -08:00
Logan Yang
321193993c
Format code (#521) 2024-08-21 15:16:22 -07:00
Logan Yang
65f62513e0
Pass multiple notes to prompt by setting folder as context using Copilot command (#265) 2024-01-27 22:51:54 -08:00