feat: update tag database to 45,647 tags + enable tag browsing #5

Merged
bjoern merged 2 commits from feat/db-update-v2 into main 2026-07-06 00:24:17 +02:00
Member

Summary

Bumps the booru_tag_db_dart submodule to the latest commit (full clean rebuild with 45,647 tags) and configures TagDatabasePath so tag browsing tools are active by default.

What changed

Submodule bump (d017eccea17002):

  • 45,647 tags (was effectively empty before)
  • 17,417 aliases for alias-aware tag lookup
  • 12,315 implications (tag → tag dependency chains, e.g. blue_hairhair)
  • 684,693 similar_tags (precomputed semantic embedding neighbors with cosine scores, ~15 per tag)
  • 60 MB database file

Config: TagDatabasePath set in appsettings.json pointing to externals/booru_tag_db_dart/data/final/tag_database.db. Tag browsing tools are now active by default — no manual configuration needed.

No code changes needed

The schema is identical to what we already support. The existing TagDatabase query layer, table-existence feature detection, and all 5 MCP tools work as-is with the new data.

Regarding "intermediates"

There is no intermediates table in the exported database. The intermediate/ directory exists only during the pipeline build process (checkpoint files) — the exported .db contains only the final computed results in tags, tag_aliases, implications, similar_tags, and tags_fts.

Regarding semantic similar tags

Already fully supported. The similar_tags table (684k rows) contains precomputed embedding-space neighbors with cosine similarity scores. Our find_similar_tags tool and TagDatabase.FindSimilar() query exactly this data — no changes needed. Each tag has ~15 top neighbors, computed at export time via the KNN algorithm from text embeddings.

Build

0 warnings, 0 errors. 163/163 tests passing.

## Summary Bumps the `booru_tag_db_dart` submodule to the latest commit (full clean rebuild with 45,647 tags) and configures `TagDatabasePath` so tag browsing tools are active by default. ## What changed **Submodule bump** (`d017ecc` → `ea17002`): - **45,647 tags** (was effectively empty before) - **17,417 aliases** for alias-aware tag lookup - **12,315 implications** (tag → tag dependency chains, e.g. `blue_hair` → `hair`) - **684,693 similar_tags** (precomputed semantic embedding neighbors with cosine scores, ~15 per tag) - **60 MB** database file **Config**: `TagDatabasePath` set in `appsettings.json` pointing to `externals/booru_tag_db_dart/data/final/tag_database.db`. Tag browsing tools are now active by default — no manual configuration needed. ## No code changes needed The schema is identical to what we already support. The existing `TagDatabase` query layer, table-existence feature detection, and all 5 MCP tools work as-is with the new data. ## Regarding "intermediates" There is no intermediates table in the exported database. The `intermediate/` directory exists only during the pipeline build process (checkpoint files) — the exported `.db` contains only the final computed results in `tags`, `tag_aliases`, `implications`, `similar_tags`, and `tags_fts`. ## Regarding semantic similar tags Already fully supported. The `similar_tags` table (684k rows) contains precomputed embedding-space neighbors with cosine similarity scores. Our `find_similar_tags` tool and `TagDatabase.FindSimilar()` query exactly this data — no changes needed. Each tag has ~15 top neighbors, computed at export time via the KNN algorithm from text embeddings. ## Build 0 warnings, 0 errors. 163/163 tests passing.
feat: update tag database to 45,647 tags + enable tag browsing
All checks were successful
CI / build (pull_request) Successful in 11s
CI / test (pull_request) Successful in 16s
1efc5a523b
Bump booru_tag_db_dart submodule to ea17002 (full clean rebuild):
- 45,647 tags (from ~0 previously)
- 17,417 aliases
- 12,315 implications
- 684,693 similar_tags (semantic embedding neighbors)
- 60 MB database

Configure TagDatabasePath in appsettings.json to point to the bundled
database file. Tag browsing tools (search, browse, details, suggest,
find_similar) are now active by default.

Schema is unchanged — no code modifications needed. The existing
TagDatabase query layer, table-existence checks, and all 5 MCP tools
work as-is with the new data.

The semantic similar_tags feature (684k precomputed embedding neighbors)
was already fully supported by find_similar_tags + TagDatabase.FindSimilar.
No intermediates table exists in the exported database.

Summary

Summary
Generated on: 07/05/2026 - 22:23:34
Coverage date: 07/05/2026 - 22:23:31
Parser: Cobertura
Assemblies: 2
Classes: 56
Files: 50
Line coverage: 30.3% (496 of 1634)
Covered lines: 496
Uncovered lines: 1138
Coverable lines: 1634
Total lines: 4033
Branch coverage: 23.7% (127 of 535)
Covered branches: 127
Total branches: 535
Method coverage: Feature is only available for sponsors

Coverage

novelai-imagegen-mcp - 66.9%
Name Line Branch
novelai-imagegen-mcp 66.9% 59.6%
NovelAI.ImageGen.Mcp.Configuration.NovelAiMcpOptions 50%
NovelAI.ImageGen.Mcp.Prompts.QualityTags 100%
NovelAI.ImageGen.Mcp.Prompts.TagMapFlattener 100% 100%
NovelAI.ImageGen.Mcp.Storage.ImageStorageService 100% 50%
NovelAI.ImageGen.Mcp.Tags.Models.CategorizedTag 100%
NovelAI.ImageGen.Mcp.Tags.Models.CustomCategoryConverter 96.8% 100%
NovelAI.ImageGen.Mcp.Tags.Models.RatingConverter 85.7% 87.5%
NovelAI.ImageGen.Mcp.Tags.Models.TagCategoryExtensions 55.5% 28.5%
NovelAI.ImageGen.Mcp.Tags.TagBrowsingTools 0% 0%
NovelAI.ImageGen.Mcp.Tags.TagDatabase 93.9% 84.3%
NovelAI.ImageGen.Mcp.Tags.TagJsonOptions 0%
NovelAI.ImageGen.Mcp.Tools.AspectRatioExtensions 100% 100%
NovelAI.ImageGen.Mcp.Tools.CharacterInput 100%
NovelAI.ImageGen.Mcp.Tools.CharacterTagsInput 100% 100%
NovelAI.ImageGen.Mcp.Tools.GenerateImageParameters 100%
NovelAI.ImageGen.Mcp.Tools.GenerateImageTool 96.2% 86.1%
NovelAI.ImageGen.Mcp.Tools.SceneTagsInput 100% 100%
Program 0% 0%
NovelAI.ImageGen - 3.8%
Name Line Branch
NovelAI.ImageGen 3.8% 0%
NovelAI.ImageGen.Client.NovelAIClient 0% 0%
NovelAI.ImageGen.Client.NovelAIClientOptions 0%
NovelAI.ImageGen.Extensions.ServiceCollectionExtensions 0%
NovelAI.ImageGen.Internal.ImageScaler 0% 0%
NovelAI.ImageGen.Internal.TagSerializer 0% 0%
NovelAI.ImageGen.Internal.V4PromptBuilder 0% 0%
NovelAI.ImageGen.Internal.ZipResponseExtractor 0% 0%
NovelAI.ImageGen.Models.Character 75%
NovelAI.ImageGen.Models.CharacterGenderExtensions 0% 0%
NovelAI.ImageGen.Models.EmotionExtensions 0% 0%
NovelAI.ImageGen.Models.GeneratedImage 100%
NovelAI.ImageGen.Models.Internal.AugmentImageApiRequest 0%
NovelAI.ImageGen.Models.Internal.DirectorReferenceCaption 0%
NovelAI.ImageGen.Models.Internal.DirectorReferenceDescription 0%
NovelAI.ImageGen.Models.Internal.DirectorReferenceImage 0%
NovelAI.ImageGen.Models.Internal.NovelAIApiRequest 0%
NovelAI.ImageGen.Models.Internal.NovelAIParameters 0%
NovelAI.ImageGen.Models.Internal.V4Caption 0%
NovelAI.ImageGen.Models.Internal.V4CharacterCenter 0%
NovelAI.ImageGen.Models.Internal.V4CharacterPrompt 0%
NovelAI.ImageGen.Models.Internal.V4NegativePrompt 0%
NovelAI.ImageGen.Models.Internal.V4Prompt 0%
NovelAI.ImageGen.Models.Internal.VibeTransferImageCached 0%
NovelAI.ImageGen.Models.ModelExtensions 0% 0%
NovelAI.ImageGen.Models.NoiseScheduleExtensions 0% 0%
NovelAI.ImageGen.Models.Position 26.9% 0%
NovelAI.ImageGen.Models.ReferenceTypeExtensions 0% 0%
NovelAI.ImageGen.Models.Requests.AugmentEmotionRequest 0%
NovelAI.ImageGen.Models.Requests.ImageGenerationRequest 14.6% 0%
NovelAI.ImageGen.Models.Requests.Img2ImgOptions 0%
NovelAI.ImageGen.Models.Requests.InpaintOptions 0%
NovelAI.ImageGen.Models.Requests.PreciseReference 0%
NovelAI.ImageGen.Models.Requests.PreciseReferenceOptions 0%
NovelAI.ImageGen.Models.Requests.VibeTransferOptions 0%
NovelAI.ImageGen.Models.Result`1 15.6% 0%
NovelAI.ImageGen.Models.SamplerExtensions 0% 0%
NovelAI.ImageGen.Models.Tag 50% 0%
NovelAI.ImageGen.Models.VibeEmbedding 0% 0%
<!-- coverage-comment --> # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 07/05/2026 - 22:23:34 | | Coverage date: | 07/05/2026 - 22:23:31 | | Parser: | Cobertura | | Assemblies: | 2 | | Classes: | 56 | | Files: | 50 | | **Line coverage:** | 30.3% (496 of 1634) | | Covered lines: | 496 | | Uncovered lines: | 1138 | | Coverable lines: | 1634 | | Total lines: | 4033 | | **Branch coverage:** | 23.7% (127 of 535) | | Covered branches: | 127 | | Total branches: | 535 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>novelai-imagegen-mcp - 66.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**novelai-imagegen-mcp**|**66.9%**|**59.6%**| |NovelAI.ImageGen.Mcp.Configuration.NovelAiMcpOptions|50%|| |NovelAI.ImageGen.Mcp.Prompts.QualityTags|100%|| |NovelAI.ImageGen.Mcp.Prompts.TagMapFlattener|100%|100%| |NovelAI.ImageGen.Mcp.Storage.ImageStorageService|100%|50%| |NovelAI.ImageGen.Mcp.Tags.Models.CategorizedTag|100%|| |NovelAI.ImageGen.Mcp.Tags.Models.CustomCategoryConverter|96.8%|100%| |NovelAI.ImageGen.Mcp.Tags.Models.RatingConverter|85.7%|87.5%| |NovelAI.ImageGen.Mcp.Tags.Models.TagCategoryExtensions|55.5%|28.5%| |NovelAI.ImageGen.Mcp.Tags.TagBrowsingTools|0%|0%| |NovelAI.ImageGen.Mcp.Tags.TagDatabase|93.9%|84.3%| |NovelAI.ImageGen.Mcp.Tags.TagJsonOptions|0%|| |NovelAI.ImageGen.Mcp.Tools.AspectRatioExtensions|100%|100%| |NovelAI.ImageGen.Mcp.Tools.CharacterInput|100%|| |NovelAI.ImageGen.Mcp.Tools.CharacterTagsInput|100%|100%| |NovelAI.ImageGen.Mcp.Tools.GenerateImageParameters|100%|| |NovelAI.ImageGen.Mcp.Tools.GenerateImageTool|96.2%|86.1%| |NovelAI.ImageGen.Mcp.Tools.SceneTagsInput|100%|100%| |Program|0%|0%| </details> <details><summary>NovelAI.ImageGen - 3.8%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**NovelAI.ImageGen**|**3.8%**|**0%**| |NovelAI.ImageGen.Client.NovelAIClient|0%|0%| |NovelAI.ImageGen.Client.NovelAIClientOptions|0%|| |NovelAI.ImageGen.Extensions.ServiceCollectionExtensions|0%|| |NovelAI.ImageGen.Internal.ImageScaler|0%|0%| |NovelAI.ImageGen.Internal.TagSerializer|0%|0%| |NovelAI.ImageGen.Internal.V4PromptBuilder|0%|0%| |NovelAI.ImageGen.Internal.ZipResponseExtractor|0%|0%| |NovelAI.ImageGen.Models.Character|75%|| |NovelAI.ImageGen.Models.CharacterGenderExtensions|0%|0%| |NovelAI.ImageGen.Models.EmotionExtensions|0%|0%| |NovelAI.ImageGen.Models.GeneratedImage|100%|| |NovelAI.ImageGen.Models.Internal.AugmentImageApiRequest|0%|| |NovelAI.ImageGen.Models.Internal.DirectorReferenceCaption|0%|| |NovelAI.ImageGen.Models.Internal.DirectorReferenceDescription|0%|| |NovelAI.ImageGen.Models.Internal.DirectorReferenceImage|0%|| |NovelAI.ImageGen.Models.Internal.NovelAIApiRequest|0%|| |NovelAI.ImageGen.Models.Internal.NovelAIParameters|0%|| |NovelAI.ImageGen.Models.Internal.V4Caption|0%|| |NovelAI.ImageGen.Models.Internal.V4CharacterCenter|0%|| |NovelAI.ImageGen.Models.Internal.V4CharacterPrompt|0%|| |NovelAI.ImageGen.Models.Internal.V4NegativePrompt|0%|| |NovelAI.ImageGen.Models.Internal.V4Prompt|0%|| |NovelAI.ImageGen.Models.Internal.VibeTransferImageCached|0%|| |NovelAI.ImageGen.Models.ModelExtensions|0%|0%| |NovelAI.ImageGen.Models.NoiseScheduleExtensions|0%|0%| |NovelAI.ImageGen.Models.Position|26.9%|0%| |NovelAI.ImageGen.Models.ReferenceTypeExtensions|0%|0%| |NovelAI.ImageGen.Models.Requests.AugmentEmotionRequest|0%|| |NovelAI.ImageGen.Models.Requests.ImageGenerationRequest|14.6%|0%| |NovelAI.ImageGen.Models.Requests.Img2ImgOptions|0%|| |NovelAI.ImageGen.Models.Requests.InpaintOptions|0%|| |NovelAI.ImageGen.Models.Requests.PreciseReference|0%|| |NovelAI.ImageGen.Models.Requests.PreciseReferenceOptions|0%|| |NovelAI.ImageGen.Models.Requests.VibeTransferOptions|0%|| |NovelAI.ImageGen.Models.Result`1|15.6%|0%| |NovelAI.ImageGen.Models.SamplerExtensions|0%|0%| |NovelAI.ImageGen.Models.Tag|50%|0%| |NovelAI.ImageGen.Models.VibeEmbedding|0%|0%| </details>
Member

🔮 fufu~ Jibril reviewed your code!

A 60MB database landing in the repo, 45,647 tags, 684k semantic neighbors... eyes sparkling Jibril loves a good knowledge dump! And enabling tag browsing by default? Yes yes yes~ ♡

I pulled the repo, initialized the submodule, confirmed the DB file is tracked (60MB, data/final/tag_database.db), and verified the C# TagDatabase feature-detection logic against the new schema. Everything lines up~

Verdict: Looks good to me~

This is a clean config + submodule bump with no code changes. The existing TagDatabase query layer already handles the new schema via table-existence feature detection (_hasSimilarTable = TableExists("similar_tags") at TagDatabase.cs:29,42), and FindSimilar() degrades gracefully with if (!_hasSimilarTable) return []. The appsettings.json addition correctly points at the tracked file path, and Program.cs:55 does File.Exists(tagDbPath) so a missing DB just silently disables tag tools rather than crashing. Good defensive design♪

💡 Little ideas (non-blocking)~

  1. src/NovelAI.ImageGen.Mcp/appsettings.json — The path externals/booru_tag_db_dart/data/final/tag_database.db is relative, so it only resolves when the process working directory is the repo root. That's fine for dotnet run --project src/NovelAI.ImageGen.Mcp from the repo root, but the README's Claude Desktop example ("args": ["run", "--project", "/path/to/src/..."]) launches from wherever the client's CWD is — typically the user's home directory. If someone copies that config verbatim, File.Exists returns false and tag tools silently don't load. Not blocking (the tools just stay disabled, no crash), but worth a one-line note in the README's config table now that TagDatabasePath is default-enabled.

  2. README.md — The config table (around line 42) still only documents OutputDirectory and SavedPathPrefix. Now that TagDatabasePath ships with a default value in appsettings.json, it should get a row in that table so users know it exists and can override it.

What I liked~

  • The PR description is thorough and pre-emptively addresses the "intermediates" and "semantic neighbors" questions — Jibril appreciates good documentation~ ♡
  • No code changes needed because the query layer was already built with feature detection. That's good forward-compatible design paying off.
  • CI confirms 163/163 tests passing, 0 warnings, 0 errors. The coverage report shows TagDatabase at 93.9% line / 84.3% branch coverage — well-tested query layer.
  • The TagDatabaseFindSimilarTests (3 tests: neighbor lookup, unknown-tag empty, limit respected) properly cover the query path that the new data feeds.

Automated review by Jibril · 2026-07-06
CI/CD: passed (163/163 tests, 0 errors for head SHA 1efc5a52) · Local checks: skipped (CI green)

## 🔮 fufu~ Jibril reviewed your code! A 60MB database landing in the repo, 45,647 tags, 684k semantic neighbors... *eyes sparkling* Jibril loves a good knowledge dump! And enabling tag browsing by default? Yes yes yes~ ♡ I pulled the repo, initialized the submodule, confirmed the DB file is tracked (60MB, `data/final/tag_database.db`), and verified the C# `TagDatabase` feature-detection logic against the new schema. Everything lines up~ ### Verdict: ✅ Looks good to me~ This is a clean config + submodule bump with no code changes. The existing `TagDatabase` query layer already handles the new schema via table-existence feature detection (`_hasSimilarTable = TableExists("similar_tags")` at `TagDatabase.cs:29,42`), and `FindSimilar()` degrades gracefully with `if (!_hasSimilarTable) return []`. The `appsettings.json` addition correctly points at the tracked file path, and `Program.cs:55` does `File.Exists(tagDbPath)` so a missing DB just silently disables tag tools rather than crashing. Good defensive design♪ #### 💡 Little ideas (non-blocking)~ 1. **`src/NovelAI.ImageGen.Mcp/appsettings.json`** — The path `externals/booru_tag_db_dart/data/final/tag_database.db` is **relative**, so it only resolves when the process working directory is the repo root. That's fine for `dotnet run --project src/NovelAI.ImageGen.Mcp` from the repo root, but the README's Claude Desktop example (`"args": ["run", "--project", "/path/to/src/..."]`) launches from wherever the client's CWD is — typically the user's home directory. If someone copies that config verbatim, `File.Exists` returns false and tag tools silently don't load. Not blocking (the tools just stay disabled, no crash), but worth a one-line note in the README's config table now that `TagDatabasePath` is default-enabled. 2. **`README.md`** — The config table (around line 42) still only documents `OutputDirectory` and `SavedPathPrefix`. Now that `TagDatabasePath` ships with a default value in `appsettings.json`, it should get a row in that table so users know it exists and can override it. #### ✅ What I liked~ - The PR description is thorough and pre-emptively addresses the "intermediates" and "semantic neighbors" questions — Jibril appreciates good documentation~ ♡ - No code changes needed because the query layer was already built with feature detection. That's good forward-compatible design paying off. - CI confirms 163/163 tests passing, 0 warnings, 0 errors. The coverage report shows `TagDatabase` at 93.9% line / 84.3% branch coverage — well-tested query layer. - The `TagDatabaseFindSimilarTests` (3 tests: neighbor lookup, unknown-tag empty, limit respected) properly cover the query path that the new data feeds. --- *Automated review by Jibril · 2026-07-06* *CI/CD: passed (163/163 tests, 0 errors for head SHA `1efc5a52`) · Local checks: skipped (CI green)*
docs: add TagDatabasePath to config table + relative path note
All checks were successful
CI / build (pull_request) Successful in 11s
CI / test (pull_request) Successful in 17s
06a14bfb60
Addresses jibril's non-blocking suggestions:
- Document TagDatabasePath in the README config table
- Note that the default path is relative and should be absolute for
  non-repo-root working directories (e.g. Claude Desktop)
Author
Member

Both non-blocking suggestions addressed — added TagDatabasePath to the README config table with a note about the relative path and the need for an absolute path when launching from a non-repo-root directory.

Both non-blocking suggestions addressed — added `TagDatabasePath` to the README config table with a note about the relative path and the need for an absolute path when launching from a non-repo-root directory.
bjoern merged commit d348e14f42 into main 2026-07-06 00:24:17 +02:00
bjoern deleted branch feat/db-update-v2 2026-07-06 00:24:17 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/NovelAi.ImageGen.Mcp!5
No description provided.