04: Build Result
此内容尚不支持你的语言。
buildResult constructs the GenerationTurnResult at every termination point of runToolLoop. It
merges NovelAI scene metadata into the response text, packages persona response entries, resolves
thought-log ownership, and returns the result to runGenerationTurn.
Result assembly and transformations
Section titled “Result assembly and transformations”The stage packages accumulated iteration state into a standardized structure:
-
Scene metadata suffix (
mergeDetails): NovelAI models can return structured scene metadata instreamResult.detailsContent. When present,mergeDetailsappends this metadata below the model response text under a[Scene Metadata]header. The merged text is a short-term-memory payload. The scene metadata is separated from the visible streaming buffer during chunk normalization, so Discord users never see it in the channel. -
Persona response packaging (
personaResponses): When the merged response text is non-empty, the stage creates a singleChatPersonaResponsecontaining the current persona’s nickname, text, persona ID, and lineage ID. When no text was produced (such as an error before generation, or a turn that delivered an expression only),personaResponsesis an empty array. -
Thought-log identity resolution (
resolveThoughtLogOwner): If an iteration emitted a thought log,resolveThoughtLogOwneridentifies the authoring entity for UI rendering:- User impersonation (
isUserImpersonation: true): maps to{ type: "user_impersonation", username, avatarUrl }. - Alter persona (
currentPersona.is_alter: true): maps to{ type: "persona", persona: currentPersona }. - Default persona: maps to
{ type: "default" }. If no thought log was produced,thoughtLogOwnerremainsundefined. The thought log preserves each request’s reasoning in order, with summaries and raw text grouped by request. Its source link points to the first streamed reply.
- User impersonation (
-
Direct delivery tracking (
toolResponseDelivered): The stage records whether a tool delivered output directly to the channel. When an expression was sent without additional assistant text,personaResponsesis empty whiletoolResponseDeliveredistrue. Downstream consumers use this flag to recognize the turn as completed rather than treating the empty text as an unexpected failure.
Handoff to the chat pipeline
Section titled “Handoff to the chat pipeline”The assembled GenerationTurnResult passes back up the chat pipeline:
- Attempt evaluation (
runGenerationTurn):runGenerationTurninspectsresult.status. If the attempt ended in a retryable status (errorortimeout) and fallback options remain, it keeps the messages this attempt posted and retries with the next key or model, which continues the reply from the posted text. Anerrorortimeoutresult joins the text every iteration posted, so a terminal failure still reaches short-term memory. - Delivery finalization (
responseSink.finalize): Once an attempt succeeds or fallbacks are exhausted,runGenerationTurnsends fallback model notices if applicable and invokesresponseSink.finalize(result)to conclude Discord message streaming. - Post-turn effects (
runPostTurnEffects): The root chat handler (tomoriChat) receives the result and runs post-turn effects:- Appends
result.personaResponsesto short-term memory dialogue history. - Records expression usage statistics.
- Handles empty-response retries, quota accounting, thought logs, and boomerang follow-ups.
- Appends
Constraints and invariants
Section titled “Constraints and invariants”- Pure assembly:
buildResultperforms no network, database, or cache I/O. It transforms in-memory iteration state into the final turn result. - Complete history:
streamResultspreserves everyStreamResultobject produced across all iterations, giving diagnostic loggers the complete record of intermediate tool attempts. - Distinguishable outcomes: Consumers treat empty
personaResponseswithtoolResponseDelivered: trueas a successful expression delivery, distinct from an unhandled empty response or a skipped turn.
Source pointers
Section titled “Source pointers”src/utils/chat/toolLoop.ts:buildResult,mergeDetails,resolveThoughtLogOwner.src/utils/chat/generationTurn.ts:runGenerationTurn.src/utils/chat/types.ts:GenerationTurnResult,ChatPersonaResponse.src/utils/chat/postTurnEffects.ts:runPostTurnEffects.