trader.chat.context module¶
Rendering database rows into plain text a model prompt can carry.
Every function here is defensive on purpose: ChatService calls these against whatever ORDER BY … LIMIT handed back, and a chat turn must never crash because a row was empty or a JSON blob was oversized. This is the same grounding discipline trader.llm.prompt.build_messages uses for a trading decision, applied to a conversational answer instead.
- trader.chat.context.decision_context(decision)[source]¶
The exact recorded row a decision-explain answer must be grounded in.
Everything here is what the pipeline actually wrote to decisions — the action taken, what the strategy said (reasoning), what actually happened (outcome_note), and what it saw (inputs_json) — never a fresh re-evaluation of the symbol. Issue #14’s whole point is that the answer traces back to this exact row.
reasoning and outcome_note are deliberately separate lines (issue #25): before outcome_note existed, a buy/sell’s reasoning held an execution summary instead of the strategy’s rationale, so a decision-explain answer for a filled trade could only ever describe what happened, never why. outcome_note is None for a hold/reject/error, which have nothing to execute, so it prints as “not executed” rather than a blank line that reads like a recording gap.
- Parameters:
decision (Decision)
- Return type:
str
- trader.chat.context.performance_context(trips, total_realized_pl)[source]¶
Closed round trips and the running realized P/L, newest first.
- Parameters:
trips (Sequence[RoundTrip])
total_realized_pl (Decimal)
- Return type:
str
- trader.chat.context.positions_context(snapshot)[source]¶
The latest account/position snapshot, or an honest “none yet”.
- Parameters:
snapshot (AccountSnapshot | None)
- Return type:
str