MCPcopy Create free account
hub / github.com/Serial-Studio/Serial-Studio / recordToolResult

Method recordToolResult

app/src/AI/Conversation.cpp:1870–1920  ·  view source on GitHub ↗

* @brief Stores a tool_result block to be sent back in the next request. */

Source from the content-addressed store, hash-verified

1868 * @brief Stores a tool_result block to be sent back in the next request.
1869 */
1870void AI::Conversation::recordToolResult(const QString& callId,
1871 const QString& name,
1872 const QJsonObject& payload)
1873{
1874 if (!m_busy) {
1875 qCWarning(serialStudioAI) << "Dropping tool result for" << name << "(" << callId
1876 << "): no turn in flight (late completion after error/cancel)";
1877 return;
1878 }
1879
1880 const auto scrubbed = AI::Redactor::scrubObject(payload);
1881
1882 constexpr int kFsResultByteBudget = 48 * 1024;
1883 const bool isFsReadResult = name == QStringLiteral("fs.read")
1884 || name == QStringLiteral("fs.search")
1885 || name == QStringLiteral("fs.list");
1886 const int kMaxToolResultBytes =
1887 isFsReadResult ? kFsResultByteBudget
1888 : qBound(2048,
1889 m_provider ? m_provider->capabilities().toolResultByteBudget : 4096,
1890 16 * 1024);
1891
1892 QJsonObject effective = scrubbed;
1893 auto contentBytes = QJsonDocument(scrubbed).toJson(QJsonDocument::Compact);
1894 if (contentBytes.size() > kMaxToolResultBytes) {
1895 effective = makeTruncatedResult(scrubbed, contentBytes, kMaxToolResultBytes);
1896 contentBytes = QJsonDocument(effective).toJson(QJsonDocument::Compact);
1897 qCDebug(serialStudioAI) << "Tool result for" << name << "truncated to" << contentBytes.size()
1898 << "bytes";
1899 }
1900
1901 const auto sourceTag = name.isEmpty() ? QStringLiteral("tool_result") : name;
1902 QString wrapped;
1903 wrapped += QStringLiteral("<untrusted source=\"");
1904 wrapped += sourceTag.toHtmlEscaped();
1905 wrapped += QStringLiteral("\">\n");
1906 wrapped += neutralizeUntrustedDelimiter(QString::fromUtf8(contentBytes));
1907 wrapped += QStringLiteral("\n</untrusted>");
1908
1909 QJsonObject block;
1910 block[QStringLiteral("type")] = QStringLiteral("tool_result");
1911 block[QStringLiteral("tool_use_id")] = callId;
1912 block[QStringLiteral("content")] = wrapped;
1913 QJsonObject geminiPayload = effective;
1914 geminiPayload[QStringLiteral("__untrusted_source")] = sourceTag;
1915 block[QStringLiteral("_gemini_response")] = geminiPayload;
1916 if (!name.isEmpty())
1917 block[QStringLiteral("_tool_name")] = name;
1918
1919 m_pendingToolResultBlocks.append(block);
1920}
1921
1922/**
1923 * @brief Decrements the outstanding tool-result counter without underflowing past zero.

Callers

nothing calls this directly

Calls 7

makeTruncatedResultFunction · 0.85
isEmptyMethod · 0.80
capabilitiesMethod · 0.45
toJsonMethod · 0.45
sizeMethod · 0.45
appendMethod · 0.45

Tested by

no test coverage detected