Add CharaVault provider; optional gateway base URL for ChubAI/CharacterTavern - #18
Open
AdamsGH wants to merge 7 commits into
Open
Add CharaVault provider; optional gateway base URL for ChubAI/CharacterTavern#18AdamsGH wants to merge 7 commits into
AdamsGH wants to merge 7 commits into
Conversation
fetchWithProxy currently only retries through ST's /proxy/ on a thrown network error. Some upstreams (chub.ai is one example) accept the CORS preflight but reject the browser Origin/Referer with 401, 403 or 451 on the actual request. Treat those statuses the same way as a network failure: remember the origin and retry through /proxy/, which strips Origin and Referer. Other non-2xx statuses still propagate as before.
The chub provider already used fetchWithProxy for read paths (search, metadata) but not for the follow/unfollow/timeline/follows-list/import flows. Behind a regional block these calls fail because the direct fetch returns 401/403/451 and there is no retry. Route every chub.ai fetch through fetchWithProxy so the new fallback in provider-utils.js applies uniformly. Drive-by: replace the two inline `https://avatars.charhub.io/avatars/` strings with the existing CHUB_AVATAR_BASE constant they were already parallelling.
Adds charavault.net as an Online tab provider. Supports browsing and
search (with NSFW and lorebook filters), tag filtering, the visually
similar widget that the site backs with image hashes, linked lorebooks,
and full V2-card import.
Endpoints default to charavault.net direct. Two optional settings exist
for users who proxy CharaVault through a self-hosted gateway:
charavaultGatewayUrl - replaces the API base
charavaultGatewayKey - sent as Authorization: Bearer
There is also a charavaultAppPassword setting (X-App-Password header)
for users with their own app password; without it the provider uses the
public anonymous tier (lower rate limit, downloads disabled for some
cards). Empty by default, no built-in fallback.
Notes on two API quirks worth knowing:
- /api/cards/similar takes path= as the absolute server-side disk
path stored in entry.path, not the folder/file form the public docs
suggest. The folder/file form returns 404 for every card.
- The search-list entry carries has_lorebook; the per-card detail
entry does not. The import path threads the search row through so
the embedded extension metadata preserves the flag.
ChubAI and CharacterTavern each split their service across multiple
upstream hosts:
chub api.chub.ai, gateway.chub.ai, avatars.charhub.io
chartavern character-tavern.com (api + site), cards.character-tavern.com
The previous code hardcoded these as module-load constants. Replace them
with runtime helpers that read from settings each call. Defaults still
point at the real hosts, so out-of-the-box behaviour is unchanged.
For users who proxy through a self-hosted gateway, a single setting per
provider is enough: chubGatewayBaseUrl / chartavernGatewayBaseUrl. The
helpers append the conventional path (/v1/chub, /v1/ct, etc.) for each
host. Per-host overrides remain available for non-standard topologies.
chubGateway{Base,Api,Gateway,Avatar}Url
chartavernGateway{Base,Api,Site,Cdn}Url
chubGatewayKey, chartavernGatewayKey
When chubGatewayKey is set, getChubHeaders() uses it as Authorization
and forwards the user's chub.ai token via X-Chub-Token so the gateway
can re-attach it upstream.
Settings UI exposes Base URL and Bearer Key by default, with the
per-host overrides tucked into an "Advanced" details element.
…Vault favicon Three small fixes after exercising the gateway integration: 1. chartavern-api: ctFetch and fetchTopTags now pass the gateway Bearer key as Authorization. Without this, every search through a self-hosted gateway hit the gateway's auth wall and returned 401. 2. charavault-provider: restore the iconUrl getter (charavault.net does serve a favicon.ico, and the provider dropdown looks broken without one). Built from getCvCdnBase() so it follows the gateway override. 3. provider-utils.fetchWithProxy: stop retrying through ST /proxy/ on 401. 401 is a genuine auth failure and should propagate to the caller. Only 403 and 451, which signal origin-shaped rejection by the upstream, still trigger the proxy fallback.
The three providers that grew "Gateway (optional)" sections in the previous commits leave it to the user to figure out what kind of proxy goes in there. Add a one-liner pointing at charlib-proxy (github.com/AdamsGH/charlib-proxy), a small Node + Express passthrough that already exposes the path conventions baked into each provider's helper.
The CV grid card was using its own minimal layout (info+meta) that none of the shared CSS in browse-shared.css actually targeted, so the card looked anaemic next to chub's: no NSFW badge, no tag chips, no footer row of stats, no indexed date. Switch to the same shape every other provider uses: image-with-badges on top, body with name + creator-link + up to three tag chips, footer row with rating / tokens / downloads / date. The new fields all come from the existing search result (tags, nsfw, avg_rating, rating_count, download_count, indexed_at, description_preview) so no API changes.
Owner
|
Hey thanks for the PR, clearly a lot of work in here. I have to be upfront though, I don't have capacity to review something this size properly rigth now. Got a lot of uncommitted stuff locally and more in the pipeline. Not closing it, happy to come back to it when things settle. Appreciate you putting it together. |
Author
|
Sure, take your time. Will be glad if it help sometime. Btw, if needed - you can fully take proxy code, i wrote it for example only |
|
dam i wanted to do this as well but had issues nice to see that it works! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a new online provider (CharaVault) and lets the existing ChubAI / CharacterTavern providers route through a self-hosted gateway when the user opts in.
Six commits, each self-contained:
provider-utils: fall back to /proxy/ on 401/403/451- widensfetchWithProxyto retry through ST/proxy/on origin-shaped rejections, not just network errors. Generic; useful for any provider hitting a hostile upstream. Later commit narrows this back to 403/451 only after testing showed 401 is genuine auth-fail and should propagate.chub: route writes through fetchWithProxy, use CHUB_AVATAR_BASE- the chub provider already usedfetchWithProxyfor read paths but not for follow / unfollow / timeline / favorites / import. Behind a regional block those calls 401/403/451 and there is no retry. Routes every chub.ai fetch throughfetchWithProxyso the new fallback applies uniformly. Drive-by: replace two inlinehttps://avatars.charhub.io/avatars/strings with the existingCHUB_AVATAR_BASEconstant they already paralleled.Add CharaVault provider- newmodules/providers/charavault/provider for charavault.net. Supports browse + search (NSFW + lorebook filters), tag filtering, the visually-similar widget the site backs with image hashes, linked lorebooks, and full V2-card import. Endpoints default tocharavault.netdirect. Two optional settings (charavaultGatewayUrl,charavaultGatewayKey) let users proxy CharaVault. App-password is its own optional setting (charavaultAppPassword); the public anonymous tier works for read paths.chub, chartavern: optional gateway base URL and key- ChubAI and CharacterTavern each split their service across multiple upstream hosts (api.chub.ai+gateway.chub.ai+avatars.charhub.io;character-tavern.com/api+ the public site +cards.character-tavern.com). Replaces the module-load constants with runtime helpers that read from settings each call. Defaults still point at the real hosts; out-of-the-box behaviour is unchanged. For users who proxy through a self-hosted gateway, a single setting (chubGatewayBaseUrl/chartavernGatewayBaseUrl) is enough; helpers append the conventional path (/v1/chub,/v1/ct, etc.) for each host. Per-host overrides remain available for non-standard topologies. Settings UI exposes Base URL + Bearer Key by default with the per-host overrides tucked into an "Advanced" details element.chartavern: send Authorization on gateway-routed fetch; restore CharaVault favicon- small follow-up after exercising the integration end-to-end: pass the gateway Bearer key asAuthorizationon chartavern'sctFetch/fetchTopTags, restore theiconUrlgetter on the CharaVault provider (built fromgetCvCdnBase()so it follows the gateway override), and stop theprovider-utilsfallback from retrying on 401 (genuine auth-fail).link reference proxy implementation in gateway settings hints- one-line addition to the three new "Gateway (optional)" sections pointing atAdamsGH/charlib-proxy, a small Node + Express passthrough that already exposes the path conventions baked into each provider's helper. Optional reading material for users who want to actually run a proxy.API quirks worth knowing (CharaVault)
Discovered while writing the provider; preserved as comments in the code:
/api/cards/similartakespath=as the absolute server-side disk path stored inentry.path, not thefolder/fileform the public docs suggest. Thefolder/fileform returns 404 for every card.has_lorebook; the per-card detail entry does not. The import path threads the search row throughbuildCvCharacterCardso the embedded extension metadata preserves the flag.Testing
Built and exercised the new provider end-to-end against both the direct upstreams and a self-hosted proxy (
charlib-proxy):No changes to any other provider's behaviour.
Settings added (defaults are all empty /
null)