Skip to content

feat(models): monitor Hugging Face changes and unify updates - #582

Merged
LuqP2 merged 4 commits into
feat/model-huggingface-bindingsfrom
feat/model-huggingface-updates
Oct 8, 2026
Merged

LuqP2 merged 4 commits into
feat/model-huggingface-bindingsfrom
feat/model-huggingface-updates

Conversation

@LuqP2

@LuqP2 LuqP2 commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Hugging Face bindings can now be checked for changes alongside Civitai. A linked file changing, a new .safetensors appearing in the watched folder, or the linked file disappearing creates an HF event. Catalog, With updates and What's new expose both providers, while the navigation badge counts each local logical model once.

This is PR 4 of the Model Manager expansion, based on #581. Stack #580 contains #578 → #579 → #581 → #582, with this PR at position 4.

Behavior

  • Explicit HF monitoring opt-in, independent from Civitai. Legacy bindings default to main, the linked file's parent folder, nonrecursive and off. The original linked tag/commit remains intact.
  • Resolve the tracked revision once, then read linked paths and every watched-folder page at the same commit. Equivalent repository/revision/folder/recursion queries are grouped. Metadata only; no model downloads, automatic replacement, credentials or HF gallery.
  • The first complete snapshot and each changed scope establish a quiet baseline. README/license changes, commit-only changes and edits to older unrelated files do not create model events. Event identities use provider/scope/path/kind and a typed fingerprint, preferring LFS SHA-256.
  • Persist snapshots, events and seen/ignored/notified decisions together in a new HF preferences store (version 12 → 13) and the existing durable preference vault. Failed, incomplete, cancelled and rate-limited consultations preserve the last complete baseline and successful date. Provider backoff remains independent.
  • Reuse the Model Manager job mutex and 6-hour/24-hour/7-day schedule while the app is open. HF-only models do not require implicit Civitai identification, including bindings on secondary identical copies. Polling stops after the last local copy disappears.
  • Label provider events, preserve history and independent ignore/restore decisions, mark viewed only after a row is presented, and avoid repeated automatic notices for events already surfaced by manual checks. Discard late responses after unlinking, cancellation or a scope change.

Validation

  • 197 distinct tests passed across 15 focused suites, covering HF reconciliation/adapter/UI, catalog entry points, service lifecycle, preference migration, Civitai tracking, release presentation, cache restoration, catalog/Inspector contracts and storage/removal regressions. Fixtures and network/IPC responses are synthetic.
  • Changed TypeScript/TSX lint: no errors; existing warnings remain in the shared preferences test harness and root types.
  • Native JavaScript syntax checks and git diff --check passed.
  • Build/typecheck were left to the maintainer's workflow. Packaged acceptance, visual checks in both windows and live Hub behavior remain manual; PR 4 steps are documented in docs/MODEL-MANAGER-SMOKE.md.

@LuqP2
LuqP2 added this pull request to stack #580 October 8, 2026 01:52
@LuqP2
LuqP2 marked this pull request as ready for review October 8, 2026 02:14
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-08T13:21:11.445710Z 3081979 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: a0e7b375fc

ℹ️ 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 components/ModelsWorkspace.tsx Outdated

@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: 4d835d8d1d

ℹ️ 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".

<button className="w-full p-3 text-left" onClick={() => select(item.location.id)} onDoubleClick={() => openInspector(item.location.id)}><h3 className="truncate font-medium" title={presentation.name}>{presentation.name}</h3><p className="mt-1 truncate text-xs text-gray-300">{remote?.versionName || 'Local model'}</p><p className="mt-1 truncate text-xs text-gray-500">{presentation.baseModel || modelKindLabel(item.location.sourceKind)} · {formatBytes(item.location.size)}</p></button>
<ModelUsagePanel item={item} compact />
{updates > 0 && <button className="mx-3 mb-3 text-xs text-cyan-300 hover:underline" onClick={() => select(item.location.id, true)}>{updates} new release{updates === 1 ? '' : 's'}</button>}
{updates > 0 && <button className="mx-3 mb-3 text-xs text-cyan-300 hover:underline" onClick={() => select(item.location.id, true)}>{updates} new update{updates === 1 ? '' : 's'}</button>}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Open the provider-bound copy from update badges

When a byte-identical model's Civitai or Hugging Face binding exists only on a secondary copy, modelUpdateCounts now shows its unread updates on the primary copy's card, but this handler still selects that unbound primary location. Consequently ModelVersionLinks and HuggingFaceModelPanel derive no watch from the selected location, so clicking “new update” reveals nothing until the user manually chooses the linked copy. Resolve the copy containing the unread provider watch before opening the details.

Useful? React with 👍 / 👎.

@LuqP2
LuqP2 force-pushed the feat/model-huggingface-updates branch from 4d835d8 to 1d71e71 Compare October 8, 2026 11:53

@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: 1d71e71e2a

ℹ️ 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 services/modelLibrary/manager.ts Outdated
Comment thread services/modelLibrary/manager.ts Outdated
@LuqP2
LuqP2 force-pushed the feat/model-huggingface-updates branch 2 times, most recently from 063d0aa to aa10369 Compare October 8, 2026 13:01

@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: aa103698db

ℹ️ 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".

const failures = selectedModels.filter((model) => model.locationIds.some((id) => failed.has(id))).length;
const failedLocationIds = locationIds.filter((id) => selectedModels.some((model) => model.locationIds.includes(id) && model.locationIds.some((copyId) => failed.has(copyId))));
const hasHF = selectedIds.some((id) => state.catalog.locations.find((location) => location.id === id)?.huggingFace);
const message = locationIds.length === 1 ? `${initialName}: ${cancelled ? 'check stopped' : failures ? 'check failed' : updated ? hasHF ? 'new updates available — see the provider links on this model' : 'new versions available — see the Civitai links on this model' : hasHF ? 'no unread new updates' : 'no unread new versions'}.` : `${cancelled ? 'Stopped. ' : ''}${updated} model${updated === 1 ? '' : 's'} with unread updates · ${selectedModels.length - updated} caught up${failures ? ` · ${failures} could not be checked` : ''}.`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Exclude failed models from the caught-up total

When a batch check cannot reach either provider for a model that has no previously unread events, updated is false while failures is true, but this message still includes that model in selectedModels.length - updated. The result can say 1 caught up · 1 could not be checked, even though no successful check established that it is current; subtract failed models from the caught-up count.

Useful? React with 👍 / 👎.

@LuqP2
LuqP2 force-pushed the feat/model-huggingface-updates branch from aa10369 to 3081979 Compare October 8, 2026 13:17
@LuqP2
LuqP2 merged commit 132a15e into main Oct 8, 2026
2 checks passed
@LuqP2
LuqP2 deleted the feat/model-huggingface-updates branch October 8, 2026 13:39
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