* @brief Sends a new user message after gating on build availability and idle state. */
| 160 | * @brief Sends a new user message after gating on build availability and idle state. |
| 161 | */ |
| 162 | void AI::Conversation::start(const QString& userText) |
| 163 | { |
| 164 | const auto trimmed = userText.trimmed(); |
| 165 | if (trimmed.isEmpty()) |
| 166 | return; |
| 167 | |
| 168 | if (!SS_LICENSE_GUARD()) { |
| 169 | setLastError(tr("AI Assistant is not available in this build")); |
| 170 | Q_EMIT errorOccurred(m_lastError); |
| 171 | return; |
| 172 | } |
| 173 | |
| 174 | if (!m_provider || !m_dispatcher) { |
| 175 | setLastError(tr("AI subsystem not initialized")); |
| 176 | Q_EMIT errorOccurred(m_lastError); |
| 177 | return; |
| 178 | } |
| 179 | |
| 180 | if (m_busy) { |
| 181 | setLastError(tr("Already busy with a previous request")); |
| 182 | Q_EMIT errorOccurred(m_lastError); |
| 183 | return; |
| 184 | } |
| 185 | |
| 186 | m_cancelled = false; |
| 187 | m_summaryForced = false; |
| 188 | m_toolCallCount = 0; |
| 189 | m_retryCount = 0; |
| 190 | m_currentStopReason.clear(); |
| 191 | setLastError(QString()); |
| 192 | |
| 193 | m_pendingThinkingBlocks = QJsonArray(); |
| 194 | m_pendingToolUseBlocks = QJsonArray(); |
| 195 | m_pendingToolResultBlocks = QJsonArray(); |
| 196 | m_outstandingToolResults = 0; |
| 197 | |
| 198 | appendUserMessage(trimmed); |
| 199 | setBusy(true); |
| 200 | issueRequest(); |
| 201 | } |
| 202 | |
| 203 | /** |
| 204 | * @brief Aborts the in-flight reply and cancels any pending confirmations. |
no test coverage detected