#pragma once #include "generation.hpp" #include "segment.hpp" #include "tool.hpp" #include #include #include #include namespace ZShell::llm { class ChatSession; class Turn { public: Turn( ChatSession* session, ChatGeneration* generation, const ToolRegistry& registry); [[nodiscard]] ChatSession* session() const { return m_session; } [[nodiscard]] ChatGeneration* generation() const { return m_generation; } [[nodiscard]] const ToolRegistry& registry() const { return m_registry; } [[nodiscard]] QJsonArray contextMessages() const; [[nodiscard]] int transcriptTokens() const; [[nodiscard]] int promptBudgetTokens() const; [[nodiscard]] int targetRow() const; void resetRound(); [[nodiscard]] QJsonObject roundAssistantMessage(); [[nodiscard]] QJsonArray toolMessages() const; [[nodiscard]] bool roundHasCalls() const; struct Call { QString id; QString name; QString arguments; QPointer segment; bool seen = false; }; QList& calls() { return m_calls; } [[nodiscard]] const QList& calls() const { return m_calls; } QList& results() { return m_results; } [[nodiscard]] const QList& results() const { return m_results; } void appendToTranscript(const QJsonObject& message); [[nodiscard]] const QJsonArray& transcript() const { return m_transcript; } [[nodiscard]] int batchSize() const; [[nodiscard]] int outputBudgetChars() const; int round = 0; int pendingCalls = 0; bool roundDone = false; bool streamDone = false; bool toolPhase = false; bool approvalPending = false; bool contextRetryUsed = false; QString finishReason; private: void appendSandboxPreamble(QJsonArray& messages) const; ChatSession* m_session; ChatGeneration* m_generation; const ToolRegistry& m_registry; QJsonArray m_transcript; QList m_calls; QList m_results; qsizetype m_contentMark = 0; qsizetype m_reasoningMark = 0; }; } // namespace ZShell::llm