* @brief Executes a single tool call and feeds its result back. */
| 1801 | * @brief Executes a single tool call and feeds its result back. |
| 1802 | */ |
| 1803 | void AI::Conversation::runToolCall(const QString& callId, |
| 1804 | const QString& name, |
| 1805 | const QJsonObject& arguments, |
| 1806 | bool autoConfirmSafe) |
| 1807 | { |
| 1808 | bool found = false; |
| 1809 | for (int i = m_uiMessages.size() - 1; i >= 0 && !found; --i) { |
| 1810 | const auto map = m_uiMessages.at(i).toMap(); |
| 1811 | const auto calls = map.value(QStringLiteral("toolCalls")).toList(); |
| 1812 | for (const auto& cv : calls) |
| 1813 | if (cv.toMap().value(QStringLiteral("callId")).toString() == callId) { |
| 1814 | found = true; |
| 1815 | break; |
| 1816 | } |
| 1817 | } |
| 1818 | if (!found) |
| 1819 | appendToolCallCard(callId, name, arguments, CallStatus::Running); |
| 1820 | else |
| 1821 | updateToolCallCard(callId, CallStatus::Running); |
| 1822 | |
| 1823 | const auto reply = m_dispatcher->executeCommand(name, arguments, autoConfirmSafe); |
| 1824 | const bool ok = reply.value(QStringLiteral("ok")).toBool(); |
| 1825 | qCDebug(serialStudioAI) << "Tool" << name << "result_ok=" << ok; |
| 1826 | |
| 1827 | recordToolResult(callId, name, reply); |
| 1828 | updateToolCallCard(callId, ok ? CallStatus::Done : CallStatus::Error, reply); |
| 1829 | releaseOutstandingToolResult(); |
| 1830 | |
| 1831 | const bool isMeta = name.startsWith(QStringLiteral("meta.")); |
| 1832 | const bool isExplicit = |
| 1833 | (name == QStringLiteral("project.save") || name == QStringLiteral("project.new") |
| 1834 | || name == QStringLiteral("project.open")); |
| 1835 | const auto safety = AI::CommandRegistry::instance().safetyOf(name); |
| 1836 | const bool isReadOnly = (safety == Safety::Safe); |
| 1837 | if (ok && !isMeta && !isExplicit && !isReadOnly) |
| 1838 | m_autoSaveTimer->start(); |
| 1839 | } |
| 1840 | |
| 1841 | /** |
| 1842 | * @brief Builds a budget-respecting replacement for an oversized tool result: keeps the |
nothing calls this directly
no test coverage detected