Skip to content

Chain Resolution

When a caller sends a Responses API request with previous_response_id, GodeX must reconstruct the entire conversation history by following parent pointers through the session store. This is the chain resolution step. The resolveResponseSessionChain function traverses the linked list of StoredResponseSession records from newest to oldest, validates structural integrity, reverses the collected turns into chronological order, and flattens each turn's request instructions, input, and response output into a single input_items array that the bridge runtime can feed into a provider's chat completions request.

Chain resolution is the foundation of GodeX's multi-turn conversation support. Without it, every request would be stateless and callers would need to replay full message history themselves.

At a Glance

ComponentFilePurpose
resolveResponseSessionChainchain.ts:26-98Main traversal function
requestHistoryItemschain.ts:100-107Converts request snapshot to ResponseItem[]
instructionInputItemschain.ts:109-120Wraps instructions as a system message
requestInputItemschain.ts:122-140Wraps input as user message(s)
ResponseSessionSnapshottypes.ts:69-76Resolved chain result type
ResolveResponseSessionOptionstypes.ts:78-83Configurable depth and incomplete handling
SessionErrorsession-error.tsDomain error with chain-specific codes

Traversal Algorithm

resolveResponseSessionChain (chain.ts:26-98) follows the previous_response_id linked list:

Step-by-step

  1. Initialise: Create a visited Set and empty turns array.
  2. Loop: While responseId is truthy:
    • Depth guard: If turns.length >= maxDepth (default 64), throw SESSION_CHAIN_DEPTH_EXCEEDED.
    • Cycle guard: If visited.has(responseId), throw SESSION_CHAIN_CYCLE_DETECTED.
    • Fetch: Call options.get(responseId) to retrieve the stored turn.
    • Missing guard: If the turn is null, throw SESSION_CHAIN_NOT_FOUND.
    • Status guard: If !includeIncomplete && turn.status !== "completed", throw SESSION_CHAIN_UNAVAILABLE.
    • Collect: Push the turn and set responseId = turn.previous_response_id.
  3. Reverse: turns.reverse() puts turns in chronological (oldest-first) order.
  4. Flatten: For each turn, concatenate requestHistoryItems(turn.request) + turn.response.output into input_items.

Integrity Guards

GuardError CodeDefault ThresholdTrigger
Max depthSESSION_CHAIN_DEPTH_EXCEEDED64Chain longer than max_depth
Cycle detectionSESSION_CHAIN_CYCLE_DETECTEDN/ASame responseId visited twice
Missing parentSESSION_CHAIN_NOT_FOUNDN/Aget(responseId) returns null
Incomplete statusSESSION_CHAIN_UNAVAILABLEN/ATurn status !== "completed" and include_incomplete is false

All errors are SessionError instances (session-error.ts:11-28) with the "session" domain and context including responseId and previousResponseId.

Chain Structure Diagram

Input Items Flattening

Each turn contributes two sets of items to the final input_items array.

requestHistoryItems

requestHistoryItems (chain.ts:100-107) combines:

SourceFunctionResult
instructionsinstructionInputItems{ type: "message", role: "system", content: [{ type: "input_text", text }] }
input (string)requestInputItems{ type: "message", role: "user", content: [{ type: "input_text", text }] }
input (array)requestInputItemsPassed through as-is (already ResponseItem[])
input (undefined)requestInputItemsEmpty array

The instructions-to-system-message conversion (chain.ts:109-120) only fires when instructions is present and non-empty. String inputs are wrapped in a user message (chain.ts:127-135).

Final Flattening

The input_items array is built by flat-mapping each turn (chain.ts:93-96):

input_items = turns.flatMap(turn => [
    ...requestHistoryItems(turn.request),   // system + user items
    ...turn.response.output,                // assistant items
])

This produces a single chronological array suitable for the bridge runtime to convert into provider-specific chat messages.

Options

OptionTypeDefaultDescription
max_depthnumber?64Maximum parent hops before depth-exceeded error
include_incompleteboolean?falseAllow non-completed responses in the chain

The ResolveResponseSessionChainOptions interface (chain.ts:19-24) extends ResolveResponseSessionOptions with a required get() function that the caller (session store) injects.

Error Scenarios

Cross-references

  • Session Stores -- the ResponseSessionStore implementations that provide the get() function injected into resolveResponseSessionChain

References