Restructure into version-neutral core + V4 tree for upcoming v5 support #2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/v5-prep-version-trees"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Restructures the Dart project to mirror the C# NovelAI.ImageGen v5-prep restructure (commit
d0e216a). This prepares for V5 support by splitting version-specific code into a V4 tree, extracting shared infrastructure, and slimming the client.dart analyze: 0 issues.dart test: 104/104 passing.Changes
1. Extracted shared HTTP transport
Created
lib/src/internal/novelai_http_transport.dart:NovelAIHttpTransportwraps Dio, exposespostAsync/getAsyncreturningResult<Uint8List>parseErrorResponse,getStatusDescription, and allDioExceptionhandling2. Extracted V4ApiRequestBuilder
Created
lib/src/internal/v4/v4_api_request_builder.dart:V4ApiRequestBuilder.build(request, seed)— moved fromNovelAIClient._buildApiRequest_add*Datahelpers (preciseReference,vibeTransfer,img2Img,inpaint)3. Slimmed client
NovelAIClientnow orchestrates: validation →V4ApiRequestBuilder.build()→NovelAIHttpTransport.postAsync(). Removed ~250 lines of inline HTTP/error/payload code.4. V4 directory tree
Moved 16 source files + 3 test files into
v4/subtrees:lib/src/models/v4/— character, position, request models, character_genderlib/src/models/internal/v4/— director refs, api request, params, v4 prompt/caption/character_promptlib/src/internal/v4/— v4_prompt_builder, v4_api_request_builderVersion-neutral files stayed in place:
tag,generated_image,result,vibe_embedding, enums (model, sampler, noise_schedule, reference_type),image_scaler,tag_serializer,zip_response_extractor.What this enables
When V5 ships, adding support is now:
lib/src/internal/v5/v5_api_request_builder.dartlib/src/models/v5/with V5-specific request typesNo changes to the transport, enums, or version-neutral models needed.
Mirror the C# NovelAI.ImageGen v5-prep restructure (commit d0e216a): 1. Extract shared HTTP transport - Add lib/src/internal/novelai_http_transport.dart - Wraps Dio; postAsync/getAsync return Result<Uint8List> - Centralizes error parsing (parseErrorResponse, getStatusDescription) and DioException handling previously inlined in NovelAIClient 2. Extract V4ApiRequestBuilder - Add lib/src/internal/v4/v4_api_request_builder.dart - Moved _buildApiRequest + _add*Data helpers from NovelAIClient - build(request, seed) is deterministic; seed supplied by caller 3. Move V4-specific files into v4/ subtrees - lib/src/models/v4/ (character, position, request models, gender) - lib/src/models/internal/v4/ (director refs, api request, params, prompts) - lib/src/internal/v4/ (prompt + api request builders) - Version-neutral files (tag, result, enums, scalers) stay in place 4. Slim down NovelAIClient - Delegates payload building to V4ApiRequestBuilder - Delegates HTTP to NovelAIHttpTransport - Keeps seed generation + orchestration only 5. Update barrel exports, all moved-file imports, and test imports Verified: dart analyze clean, dart test 104/104 passing.🔮 fufu~ Jibril reviewed your code!
Ooooh~ a restructure to prepare for V5 support! Version-neutral core + version-specific trees... fufu~ this is the kind of architectural thinking that makes my wings flutter with excitement! ♡ Let me dig in~
Verdict: ✅ Looks good to me~
I cloned the repo, checked out
0ed9826, and verified everything locally:dart analyze: No issues found ✓ (confirmed independently)dart test: 104/104 passing ✓ (confirmed independently)I carefully compared the old
NovelAIClientagainst the extractedV4ApiRequestBuilderandNovelAIHttpTransport, line by line. This is a faithful, mechanical move — the_buildApiRequestbody, all four_add*Datahelpers, theparseErrorResponselogic, thegetStatusDescriptionswitch, and theDioExceptionhandling all landed in their new homes byte-for-byte identical in logic. No sneaky behavioral drift slipped in~ fufu~ ♡The seed externalization is wonderful — moving
request.seed ?? _generateRandomSeed()out of the builder and passingseedin as a parameter makesV4ApiRequestBuilder.build()deterministic and side-effect free. That's exactly right for something that will eventually be one of several version-strategy builders. The caller owns the randomness; the builder is pure. Oh? Oh! I love it~ ♪The barrel file reorganization is clean —
NovelAIHttpTransportandV4ApiRequestBuilderare correctly keptinternal(not exported), while the public V4 models get their own section. The version-neutral / version-specific split is consistent and sensible.✅ What I liked~
DioException→Result.faildance was triplicated acrossgenerateImage,encodeVibe, andvalidateApiKey. Now it's centralized inNovelAIHttpTransport._handleError+matchResult. Fufu~ three copies became one~_dioand_transportshare the same Dio instance while still allowing test injection of a customdio. Clean.generateImage(success, error, validation),encodeVibe, andvalidateApiKeythrough the new transport path, andV4PromptBuilderhas thorough unit tests covering auto/explicit/grid positions, negative prompts, and multi-character. The moved code paths are exercised.d0e216a).💡 Little ideas (non-blocking)~
validateApiKeysubtle behavior change — the old code used_dio.get<dynamic>()(no forcedresponseType), while the newgetAsyncforcesresponseType: ResponseType.bytes. This is benign (the response body is discarded —onSuccess: (_) => Result.ok(true)), and the tests pass. But it's worth being aware thatvalidateApiKeynow always downloads the full user-data payload as bytes instead of letting Dio stream it. No action needed unless the user-data endpoint returns something large — consider aHEADrequest someday if you want to skip the body entirely. ♪add*Datavisibility — the helpers onV4ApiRequestBuilder(addPreciseReferenceData,addVibeTransferData, etc.) were private (_add*) in the old client and are now public (add*). They're internal so it doesn't leak to consumers, but they could be file-private (_) if they're only called frombuild(). Tiny tidiness thing~ ♡Automated review by Jibril · 2026-07-08
CI/CD: absent for head SHA
0ed9826· Local checks:dart analyze0 issues ✓,dart test104/104 ✓ (both run by reviewer)Nit #2 fixed —
add*Datahelpers restored to_add*Data(file-private), matching the visibility they had in the old client. 104/104 tests still passing.Nit #1 (
validateApiKeydownloading the full body as bytes) acknowledged — benign since the body is discarded. A HEAD request optimization can be a future improvement.