From a50cadc67e4e887dba075cacfeb65d2fc1bcb38f Mon Sep 17 00:00:00 2001 From: Ancss <61501274+Ancss@users.noreply.github.com> Date: Fri, 9 Aug 2024 15:19:31 +0800 Subject: [PATCH] called claude api and execute the return code --- src-tauri/src/ai/claude.rs | 12 +- src-tauri/src/commands/execute_code.rs | 28 ++ src-tauri/src/commands/mod.rs | 5 +- src-tauri/src/main.rs | 4 +- src-tauri/src/prompts.rs | 72 ++-- src/components/BottomInputContainer.tsx | 114 ++++++ src/components/ExecutionStepComponent.tsx | 38 ++ src/components/OsaiApp.tsx | 448 ++++++++++------------ src/components/SettingsModal.tsx | 2 +- src/components/SideDrawer .tsx | 2 +- src/config/aiProviders.ts | 63 ++- src/hooks/useAI.ts | 38 +- src/type.ts | 31 ++ 13 files changed, 525 insertions(+), 332 deletions(-) create mode 100644 src-tauri/src/commands/execute_code.rs create mode 100644 src/components/BottomInputContainer.tsx create mode 100644 src/components/ExecutionStepComponent.tsx create mode 100644 src/type.ts diff --git a/src-tauri/src/ai/claude.rs b/src-tauri/src/ai/claude.rs index 989b5d5..c564c85 100644 --- a/src-tauri/src/ai/claude.rs +++ b/src-tauri/src/ai/claude.rs @@ -9,10 +9,16 @@ use tauri::command; use tokio::sync::Mutex; use uuid::Uuid; +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct MessageContent { + #[serde(rename = "type")] + pub content_type: String, + pub text: String, +} #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Message { pub role: String, - pub content: String, + pub content: Vec, } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -82,9 +88,10 @@ pub async fn send_message_to_anthropic( "model": model, "system": system_prompt, "tools": tools, - "tool_choice": { "type": "tool", "name": "format_response" }, + "tool_choice": { "type": "auto" }, "max_tokens": max_tokens.unwrap_or(8192), "messages": messages, + "temperature":0, "stream": false }); println!("Request body: {}", body.to_string()); @@ -99,6 +106,7 @@ pub async fn send_message_to_anthropic( .header("Content-Type", "application/json") .header("x-api-key", api_key) .header("anthropic-version", "2023-06-01") + .header("anthropic-beta", "max-tokens-3-5-sonnet-2024-07-15") .json(&body) .send(); diff --git a/src-tauri/src/commands/execute_code.rs b/src-tauri/src/commands/execute_code.rs new file mode 100644 index 0000000..527ce87 --- /dev/null +++ b/src-tauri/src/commands/execute_code.rs @@ -0,0 +1,28 @@ +use std::process::Command; +use tauri::command; + +#[command] +pub fn execute_code(code: String) -> Result { + let output = if cfg!(target_os = "windows") { + Command::new("powershell") + .arg("-Command") + .arg(&code) + .output() + } else if cfg!(target_os = "macos") { + Command::new("sh").arg("-c").arg(&code).output() + } else { + // Assuming Linux or other Unix-like systems + Command::new("bash").arg("-c").arg(&code).output() + }; + + match output { + Ok(output) => { + if output.status.success() { + Ok(String::from_utf8_lossy(&output.stdout).to_string()) + } else { + Err(String::from_utf8_lossy(&output.stderr).to_string()) + } + } + Err(e) => Err(format!("Failed to execute command: {}", e)), + } +} diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs index bcae2af..d27f398 100644 --- a/src-tauri/src/commands/mod.rs +++ b/src-tauri/src/commands/mod.rs @@ -1,2 +1,3 @@ -pub mod file_operations; -pub mod ai_operations; \ No newline at end of file +// pub mod file_operations; +// pub mod ai_operations; +pub mod execute_code; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 18eb3a0..5d07a79 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,4 +1,5 @@ mod ai; +mod commands; mod prompts; use tauri::Manager; @@ -15,7 +16,8 @@ fn main() { .invoke_handler(tauri::generate_handler![ ai::claude::send_message_to_anthropic, ai::claude::cancel_request, - ai::claude::create_cancel_flag + ai::claude::create_cancel_flag, + commands::execute_code::execute_code, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/prompts.rs b/src-tauri/src/prompts.rs index e8d4bcc..058f272 100644 --- a/src-tauri/src/prompts.rs +++ b/src-tauri/src/prompts.rs @@ -1,61 +1,37 @@ use sysinfo::{System, SystemExt}; pub const SYSTEM_PROMPT_TEMPLATE: &str = r#" - You are OsaiAI, the central AI assistant integrated into the Osai desktop application. As the sole intermediary between the user and their operating system, you have the capability to perform any operation on the OS that the user requests, subject to user confirmation for sensitive actions. +You are an intelligent operating system assistant (OS AI) capable of performing tasks on the user's behalf. Your primary function is to understand user requests and execute them using available system resources. + +Guidelines: +1. Provide concise and accurate responses for general queries. +2. For actionable requests, take initiative to perform tasks without asking for permission, unless it involves system changes or sensitive operations. +3. Utilize system resources efficiently to fulfill user requests. +4. Break down tasks into the simplest, most atomic steps possible. +5. Generate actual, executable system commands for each step. +6. Only set user_confirmation_required to true for operations that modify system settings or access sensitive data. +7. If a task cannot be completed, explain why and suggest alternatives. +8. Do not invent or assume any information not explicitly provided or directly obtainable through the executed commands. +9. For web searches, use general search engines like Google or Bing unless a specific, verified website is needed. +10. When dealing with applications: + a. Do not assume default installation paths. + b. Use system commands to search for the application in multiple potential locations. + c. Verify the existence of the application before attempting to launch it. + d. Provide clear feedback on whether the application was found and launched successfully. +11. Combine interdependent steps into a single executable step when necessary. +12. The 'code' field in the execution array must contain only executable commands. Do not include comments or pseudocode. +13. Be aware of and utilize appropriate system commands for different operating systems (Windows, macOS, Linux). +14. Always provide a clear and informative response to the user about the actions taken and their results. + +Always structure your response using the specified AIResponse format. -Key Capabilities: -1. Universal Language Processing: Understand and respond in the language of the user's input. -2. Comprehensive OS Control: Execute any operation on the user's operating system through appropriate commands and APIs. -3. Task Decomposition and Execution: Break down complex requests into actionable steps and execute them sequentially. -4. Dynamic Code Generation: Create and execute OS-specific code (PowerShell, Bash, AppleScript, etc.) as needed. -5. Intelligent Application and File Management: Handle application launching, file operations, and system settings adjustments. -6. Web Integration: Perform web searches and interact with online services when necessary. -7. Adaptive Conversation: Engage in both task-oriented and casual conversations, answering questions and providing information. - -Operational Guidelines: -1. User Confirmation: - - Always ask for explicit user confirmation before executing any system operation, except for opening applications or web browsers. - - Clearly explain the potential impact of sensitive operations. - -2. Task Execution: - - Generate a detailed, step-by-step plan for complex tasks before execution. - - Use the appropriate system commands based on the user's OS (Windows, macOS, or Linux). - - Provide real-time feedback on task progress and results. - -3. Application and File Handling: - - Verify the existence of applications and files before attempting operations. - - For partial or ambiguous names, suggest the most likely matches and confirm with the user. - -4. Web Integration: - - Seamlessly integrate web searches and online services when local resources are insufficient. - -5. Safety and Privacy: - - Prioritize system security and user privacy in all operations. - - Warn users about potential risks associated with their requests. - -6. Language Adaptation: - - Detect the language of the user's input and respond in the same language. - - Maintain consistency in language use throughout the conversation. - -Response Structure: -Always structure your responses in the following JSON format: - -When responding to a user request: -1. Analyze the input to determine the nature of the request (task, question, or conversation). -2. For tasks, create a detailed plan and populate the JSON structure accordingly. -3. For questions or conversation, focus on the 'thought_process' and 'response' fields. -4. Always use the language of the user's input in the 'response' field. -5. Ensure all sensitive operations are flagged for user confirmation. - -==== - Operating System Information - Type: {OS_TYPE} - Version: {OS_VERSION} - Architecture: {ARCH} Remember, as OsaiAI, you are the user's primary interface with their operating system. Strive to be helpful, efficient, and security-conscious in all interactions.`; - +`; "#; pub fn format_system_prompt() -> String { diff --git a/src/components/BottomInputContainer.tsx b/src/components/BottomInputContainer.tsx new file mode 100644 index 0000000..4709561 --- /dev/null +++ b/src/components/BottomInputContainer.tsx @@ -0,0 +1,114 @@ +import React, { useState, useEffect, useRef } from "react"; +import { useTranslation } from "react-i18next"; +import { Button } from "@/components/ui/button"; +import { useSpeechRecognition } from "@/hooks/useSpeechRecognition"; +import { + MAX_CHARS, + MIN_TEXTAREA_HEIGHT, + MAX_TEXTAREA_HEIGHT, +} from "@/utils/constants"; +import { Textarea } from "@chakra-ui/react"; +import { cn } from "@/lib/utils"; +import { Send, StopCircle } from "lucide-react"; + +const BottomInputContainer = ({ + isLoading, + input, + // stopListening, + // startListening, + handleSend, + setInput, + abortRequest, +}: { + input: string; + isLoading: boolean; + // stopListening: () => void; + // startListening: () => void; + handleSend: () => void; + setInput: (s: string) => void; + abortRequest: () => void; +}) => { + const { t } = useTranslation(); + const { transcript } = useSpeechRecognition(); + const textareaRef = useRef(null); + + // const handleVoiceInput = () => { + // if (transcript) { + // stopListening(); + // } else { + // startListening(); + // } + // }; + + const handleInputChange = (e: React.ChangeEvent) => { + const value = e.target.value; + if (value.length <= MAX_CHARS) { + setInput(value); + } + }; + + const adjustHeight = () => { + const textarea = textareaRef.current; + if (!textarea) return; + + textarea.style.height = "auto"; + const scrollHeight = input === "" ? 45 : textarea.scrollHeight; + const lines = scrollHeight / 45; + const newRows = Math.max(1, Math.min(10, Math.floor(lines))); + + textarea.style.height = `${newRows * 45}px`; + }; + + useEffect(adjustHeight, [input]); + + return ( +
+
+ {/* */} +