Skip to content

fix: unblock eligible self-host users' own web search and YouTube tools#2606

Merged
logancyang merged 2 commits into
v4-previewfrom
issue-145-selfhost-tools
Jun 14, 2026
Merged

fix: unblock eligible self-host users' own web search and YouTube tools#2606
logancyang merged 2 commits into
v4-previewfrom
issue-145-selfhost-tools

Conversation

@logancyang

Copy link
Copy Markdown
Owner

Summary

Eligible self-host users (Believer/Supporter with their own keys) were blocked from their own web search and YouTube transcription tools because the self-host toggle and its validation receipt are stored separately and could disagree.

Using a self-host tool requires isSelfHostModeValid() = enableSelfHostMode toggle AND isSelfHostAccessValid() (a valid selfHostModeValidatedAt + selfHostValidationCount). The primary cause: the legacy enableSelfHostedSearchenableSelfHostMode migration in sanitizeSettings seeded the toggle but never the validation receipt, leaving selfHostModeValidatedAt = null. So isSelfHostAccessValid() returned false, and:

  • YouTube (youtubeTranscription, registered isPlusOnly) hard-returned "requires a Copilot Plus subscription" at the gate in toolExecution.ts, never reaching the self-host supadataApiKey branch.
  • Web search (webSearch) fell through past the isSelfHostModeValid() && hasSelfHostSearchKey() routing in SearchTools.ts to the Brevilabs backend, which throws MissingPlusLicenseError.

Fix

Defensively seed the validation receipt in sanitizeSettings (after the legacy migration so the migrated toggle value is already applied): whenever the sanitized result has enableSelfHostMode === true but selfHostModeValidatedAt == null, set selfHostModeValidatedAt = Date.now() and selfHostValidationCount = max(existing || 0, 1). This covers both the migration gap and any "toggle on but receipt null" state.

This does not broaden access: we never seed when the toggle is off, and the periodic refreshSelfHostModeValidation() still disables the toggle and clears the receipt for genuinely ineligible plans on the next online launch.

How verified

  • npm run format — no changes (all files unchanged)
  • npm run lint — clean
  • npm test — 245 suites / 3691 tests pass
  • New unit tests cover: legacy-migration seeding, toggle-on-but-null-receipt seeding, the off-toggle guard (not seeded), no-overwrite of an existing receipt, and the isSelfHostModeValid() / isSelfHostAccessValid() grace/permanent/expired paths in plusUtils.

Scope

Tools path only (src/settings/model.ts + the gating it feeds in plusUtils.ts). Agent-mode self-host (src/agentMode/skills/) is a separate concern tracked in #146 and was intentionally not touched.

Closes logancyang/obsidian-copilot-preview#145

🤖 Generated with Claude Code

Self-host tools (web search, YouTube transcription) require
isSelfHostModeValid() = enableSelfHostMode toggle AND a valid validation
receipt (selfHostModeValidatedAt + selfHostValidationCount). The toggle
and receipt are stored separately and could disagree: the legacy
enableSelfHostedSearch -> enableSelfHostMode migration in sanitizeSettings
seeded the toggle but never the receipt, so isSelfHostAccessValid()
returned false on the selfHostModeValidatedAt == null check. As a result
YouTube hard-returned "requires a Copilot Plus subscription" and web
search fell through to the Brevilabs backend (MissingPlusLicenseError),
even for eligible Believer/Supporter users with their own keys.

Defensively seed the validation receipt in sanitizeSettings: whenever the
sanitized result has enableSelfHostMode === true but
selfHostModeValidatedAt == null, set selfHostModeValidatedAt = Date.now()
and selfHostValidationCount = max(existing || 0, 1). This is placed after
the legacy migration so the migrated toggle value is already applied, and
it covers both the migration gap and any "toggle on but receipt null"
state. We never seed when the toggle is off, so users who never enabled
self-host mode are not granted access, and periodic
refreshSelfHostModeValidation() still disables/clears for genuinely
ineligible plans.

Scope is the tools path only; agent-mode self-host (src/agentMode/skills)
is tracked separately in #146.

Adds unit tests for the sanitize seeding (migration + toggle-on-null-
receipt + the off-toggle guard + no-overwrite) and for the
isSelfHostModeValid()/isSelfHostAccessValid() paths in plusUtils.

Closes logancyang/obsidian-copilot-preview#145

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1da9e0d4a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/settings/model.ts Outdated
…t seeding

Per preview-phase policy (no migration/temporary logic), replace the defensive
receipt seeding in sanitizeSettings with a toggle-only gate.

isSelfHostModeValid() now returns enableSelfHostMode === true. The startup
refreshSelfHostModeValidation() still disables the toggle for genuinely
ineligible plans, so the toggle is a sufficient gate. This removes the buggy
seeding that re-stamped Date.now() on every restart (never persisted, so the
15-day grace renewed indefinitely) instead of persisting it.

isSelfHostAccessValid() and the grace/permanent machinery are left intact since
miyoUtils still depends on them; ripping those out is a follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@logancyang logancyang merged commit 894c21d into v4-preview Jun 14, 2026
2 checks passed
@logancyang logancyang deleted the issue-145-selfhost-tools branch June 14, 2026 04:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant