diff --git a/ChatView/ChatRootView.cpp b/ChatView/ChatRootView.cpp index 6a22701..a57b5ac 100644 --- a/ChatView/ChatRootView.cpp +++ b/ChatView/ChatRootView.cpp @@ -131,6 +131,7 @@ ChatRootView::ChatRootView(QQuickItem *parent) connect(m_chatModel, &ChatModel::modelReseted, this, [this]() { setRecentFilePath(QString{}); + m_tokenCounter->resetServerUsage(); m_fileEditController->clearCurrentRequestId(); }); auto maybeEmitTitle = [this] { @@ -231,8 +232,8 @@ ChatRootView::ChatRootView(QQuickItem *parent) m_clientInterface, &ClientInterface::messageUsageReceived, this, - [this](int promptTokens, int /*completionTokens*/, int /*cached*/, int /*reasoning*/) { - m_tokenCounter->recordServerUsage(promptTokens); + [this](int promptTokens, int /*completionTokens*/, int cachedTokens, int /*reasoning*/) { + m_tokenCounter->recordServerUsage(promptTokens, cachedTokens); }); connect( @@ -489,8 +490,6 @@ void ChatRootView::dispatchSend( } } - m_tokenCounter->recordSent(); - if (currentChatAgent().isEmpty()) loadAvailableChatAgents(); diff --git a/ChatView/InputTokenCounter.cpp b/ChatView/InputTokenCounter.cpp index 27c0794..05f9573 100644 --- a/ChatView/InputTokenCounter.cpp +++ b/ChatView/InputTokenCounter.cpp @@ -4,9 +4,6 @@ #include "InputTokenCounter.hpp" -#include - -#include "Logger.hpp" #include "context/ContextManager.hpp" #include "context/TokenUtils.hpp" @@ -49,8 +46,6 @@ void InputTokenCounter::setLinkedFiles(const QStringList &linkedFiles) void InputTokenCounter::recompute() { - int inputTokens = m_messageTokens; - const auto splitImageEstimate = [](const QStringList &paths, QStringList &textPaths) { int imageTokens = 0; for (const QString &p : paths) { @@ -62,15 +57,24 @@ void InputTokenCounter::recompute() return imageTokens; }; + int pendingTokens = m_messageTokens; if (!m_attachments.isEmpty()) { QStringList textPaths; - inputTokens += splitImageEstimate(m_attachments, textPaths); + pendingTokens += splitImageEstimate(m_attachments, textPaths); if (!textPaths.isEmpty()) { auto attachFiles = m_contextManager->getContentFiles(textPaths); - inputTokens += Context::TokenUtils::estimateFilesTokens(attachFiles); + pendingTokens += Context::TokenUtils::estimateFilesTokens(attachFiles); } } + if (m_hasServerUsage && m_history && !m_history->isEmpty()) { + m_inputTokens = m_serverInputTokens + pendingTokens; + emit inputTokensChanged(); + return; + } + + int inputTokens = pendingTokens; + if (!m_linkedFiles.isEmpty()) { QStringList textPaths; inputTokens += splitImageEstimate(m_linkedFiles, textPaths); @@ -87,33 +91,25 @@ void InputTokenCounter::recompute() } } - m_inputTokens = static_cast(inputTokens * m_calibrationFactor); + m_inputTokens = inputTokens; emit inputTokensChanged(); } -void InputTokenCounter::recordSent() +void InputTokenCounter::recordServerUsage(int promptTokens, int cachedTokens) { - m_lastSentEstimate = m_calibrationFactor > 0.0 - ? static_cast(m_inputTokens / m_calibrationFactor) - : m_inputTokens; -} - -void InputTokenCounter::recordServerUsage(int promptTokens) -{ - if (promptTokens <= 0 || m_lastSentEstimate <= 0) + const int serverInput = promptTokens + cachedTokens; + if (serverInput <= 0) return; - const double rawFactor - = static_cast(promptTokens) / static_cast(m_lastSentEstimate); - const double clamped = std::clamp(rawFactor, 0.5, 3.0); - m_calibrationFactor = 0.5 * m_calibrationFactor + 0.5 * clamped; - - LOG_MESSAGE(QString("Token calibration: server=%1 estimated=%2 ratio=%3 ema=%4") - .arg(promptTokens) - .arg(m_lastSentEstimate) - .arg(rawFactor, 0, 'f', 3) - .arg(m_calibrationFactor, 0, 'f', 3)); + m_serverInputTokens = serverInput; + m_hasServerUsage = true; + recompute(); +} +void InputTokenCounter::resetServerUsage() +{ + m_serverInputTokens = 0; + m_hasServerUsage = false; recompute(); } diff --git a/ChatView/InputTokenCounter.hpp b/ChatView/InputTokenCounter.hpp index 9f79982..4e7d366 100644 --- a/ChatView/InputTokenCounter.hpp +++ b/ChatView/InputTokenCounter.hpp @@ -34,8 +34,8 @@ public: void setLinkedFiles(const QStringList &linkedFiles); void recompute(); - void recordSent(); - void recordServerUsage(int promptTokens); + void recordServerUsage(int promptTokens, int cachedTokens); + void resetServerUsage(); signals: void inputTokensChanged(); @@ -48,8 +48,8 @@ private: QStringList m_linkedFiles; int m_messageTokens{0}; int m_inputTokens{0}; - int m_lastSentEstimate{0}; - double m_calibrationFactor{1.0}; + int m_serverInputTokens{0}; + bool m_hasServerUsage{false}; }; } // namespace QodeAssist::Chat