Prechádzať zdrojové kódy

fix: pass workspace_id to tool execution, serialize tool_calls in messages

- Add workspaceId parameter to executeTool API
- Pass workspace_id in tool execution context
- Serialize tool_calls from message content when loading sessions
- Fixes "Tool requires workspace context" error
- Fixes tool calls disappearing after page refresh
fszontagh 7 mesiacov pred
rodič
commit
cbd5188ae2

+ 11 - 1
webserver/src/http_server.cpp

@@ -5922,14 +5922,24 @@ void HttpServer::HandleLlmGetSession(const httplib::Request& req, httplib::Respo
             m["id"] = msg.id();
             m["role"] = MessageRoleToString(msg.role());
 
-            // Extract text content from message parts
+            // Extract text content and tool_calls from message parts
             std::string msg_text;
+            nlohmann::json tool_calls_array = nlohmann::json::array();
             for (const auto& part : msg.content()) {
                 if (part.has_text()) {
                     msg_text += part.text();
+                } else if (part.has_tool_use()) {
+                    tool_calls_array.push_back({
+                        {"id", part.tool_use().id()},
+                        {"name", part.tool_use().name()},
+                        {"arguments", part.tool_use().arguments()}
+                    });
                 }
             }
             m["content"] = msg_text;
+            if (!tool_calls_array.empty()) {
+                m["tool_calls"] = tool_calls_array;
+            }
             m["created_at"] = msg.created_at().seconds();
 
             if (msg.has_page_context()) {

+ 4 - 1
webui/src/api/tools.ts

@@ -25,12 +25,14 @@ export async function getAvailableTools(workspaceId?: string): Promise<{ tools:
  * @param toolCallId - Tool call ID from LLM response
  * @param toolName - Name of the tool to execute
  * @param args - Tool arguments (parsed JSON)
+ * @param workspaceId - Workspace ID for workspace-scoped tools
  */
 export async function executeTool(
   sessionId: string,
   toolCallId: string,
   toolName: string,
-  args: Record<string, unknown>
+  args: Record<string, unknown>,
+  workspaceId?: string
 ): Promise<ExecuteToolResponse> {
   return apiClient.post<ExecuteToolResponse>(
     `/llm/sessions/${sessionId}/tools/execute`,
@@ -38,6 +40,7 @@ export async function executeTool(
       tool_call_id: toolCallId,
       tool_name: toolName,
       arguments: args,
+      workspace_id: workspaceId,
     }
   )
 }

+ 3 - 3
webui/src/contexts/ChatContext.tsx

@@ -314,7 +314,7 @@ export function ChatProvider({ children }: ChatProviderProps) {
   const executeTool = useCallback(async (
     sessionId: string,
     toolCall: ToolCall,
-    _workspaceId: string  // Reserved for future permission context
+    workspaceId: string
   ): Promise<ToolResult> => {
     // Update tool state to executing
     setPendingToolCalls(prev =>
@@ -334,8 +334,8 @@ export function ChatProvider({ children }: ChatProviderProps) {
         // If parsing fails, use empty object
       }
 
-      // Execute via API
-      const response = await toolsApi.executeTool(sessionId, toolCall.id, toolCall.name, args)
+      // Execute via API with workspace context
+      const response = await toolsApi.executeTool(sessionId, toolCall.id, toolCall.name, args, workspaceId)
 
       // Handle navigation if present
       if (response.navigation) {