@@ -51,21 +51,41 @@ static void addCommonPayloadParams(QJsonObject &payload)
5151
5252static void addToolsToPayload (QJsonObject &payload)
5353{
54- if (settings ().tools .value ().isEmpty ())
55- return ;
54+ const QStringList enabledTools = settings ().enabledToolsList ();
55+
56+ const QStringList creatorsList = ToolFactory::instance ().creatorsList ();
57+ QStringList toolDefinitions;
58+ for (const QString &toolName : creatorsList) {
59+ std::unique_ptr<Tool> tool = ToolFactory::instance ().create (toolName);
60+ toolDefinitions << tool->toolDefinition ();
61+ }
5662
5763 QJsonArray toolsArr;
58- for (const QString &toolStr : settings (). tools . value ( )) {
64+ for (const QString &toolStr : std::as_const (toolDefinitions )) {
5965 QJsonParseError err;
6066 QJsonDocument doc = QJsonDocument::fromJson (toolStr.toUtf8 (), &err);
6167 if (err.error != QJsonParseError::NoError || !doc.isObject ()) {
6268 qWarning () << " Invalid tool JSON:" << err.errorString ();
6369 continue ;
6470 }
65- toolsArr.append (doc.object ());
71+
72+ // Extract the tool name so we can check whether it is enabled.
73+ const QJsonObject root = doc.object ();
74+ const QJsonObject functionObj = root.value (QStringLiteral (" function" )).toObject ();
75+ const QString toolName = functionObj.value (QStringLiteral (" name" )).toString ();
76+
77+ if (!enabledTools.contains (toolName)) {
78+ // Skip disabled tools – they must never be advertised to the server.
79+ qCInfo (llamaChatTools).nospace ()
80+ << " Tool '" << toolName << " ' is disabled, not adding it to payload." ;
81+ continue ;
82+ }
83+
84+ toolsArr.append (root);
6685 }
6786
68- payload[" tools" ] = toolsArr;
87+ if (!toolsArr.isEmpty ())
88+ payload[" tools" ] = toolsArr;
6989}
7090
7191ChatManager &ChatManager::instance ()
@@ -774,6 +794,30 @@ void ChatManager::executeToolAndSendResult(const QString &convId,
774794 const ToolCall &tool,
775795 std::function<void (qint64)> onChunk)
776796{
797+ // Check whether the requested tool is enabled.
798+ if (!settings ().enabledToolsList ().contains (tool.name )) {
799+ qCWarning (llamaChatTools) << " Tool" << tool.name
800+ << " was called but is disabled – skipping." ;
801+
802+ // Insert a synthetic “failed” tool‑result so the conversation can continue.
803+ Message toolMsg = createToolMessage (assistantMsg);
804+ QJsonObject toolJsonMsg;
805+ toolJsonMsg[" role" ] = " tool" ;
806+ toolJsonMsg[" tool_call_id" ] = tool.id ;
807+ toolJsonMsg[" name" ] = tool.name ;
808+ toolJsonMsg[" content" ] = QStringLiteral (" Tool disabled" );
809+ QVariantMap toolResultExtra;
810+ toolResultExtra[" tool_result" ] = toolJsonMsg;
811+ toolResultExtra[" tool_status" ] = QStringLiteral (" failed" );
812+ toolMsg.extra << toolResultExtra;
813+ m_storage->appendMsg (toolMsg, assistantMsg.id );
814+ onChunk (toolMsg.id );
815+
816+ // Continue the conversation as if the tool had returned an error.
817+ generateMessage (convId, toolMsg.id , onChunk);
818+ return ;
819+ }
820+
777821 QJsonParseError err;
778822 QJsonDocument doc = QJsonDocument::fromJson (tool.arguments .toUtf8 (), &err);
779823 if (err.error != QJsonParseError::NoError) {
0 commit comments