236 lines
7.5 KiB
Plaintext
236 lines
7.5 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"id": "bee40edd-5f36-49e6-a64f-361674f1e681",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Chat with AI (type 'stop' or 'quit' to exit)\n",
|
|
"Note: First response may take longer while model loads\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdin",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"You: hi\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"Assistant: Hello! It's nice to meet you. Is there something I can help you with or would you like to chat for a bit?\n",
|
|
"Speech saved to response.mp3\n",
|
|
"Speed adjustment failed: [Errno 2] No such file or directory: 'ffprobe'. Using simple playback.\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/home/masih/anaconda3/lib/python3.12/site-packages/pydub/utils.py:198: RuntimeWarning: Couldn't find ffprobe or avprobe - defaulting to ffprobe, but may not work\n",
|
|
" warn(\"Couldn't find ffprobe or avprobe - defaulting to ffprobe, but may not work\", RuntimeWarning)\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdin",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"You: I don't know\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"Assistant: We can start with something simple then. Would you like to play a game, have a fun conversation, or just explore some topics together? I'm here to listen and help if you need it. What's been on your mind lately?\n",
|
|
"Speech saved to response.mp3\n",
|
|
"Speed adjustment failed: [Errno 2] No such file or directory: 'ffprobe'. Using simple playback.\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"/home/masih/anaconda3/lib/python3.12/site-packages/pydub/utils.py:198: RuntimeWarning: Couldn't find ffprobe or avprobe - defaulting to ffprobe, but may not work\n",
|
|
" warn(\"Couldn't find ffprobe or avprobe - defaulting to ffprobe, but may not work\", RuntimeWarning)\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdin",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\n",
|
|
"You: quit\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Conversation ended\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from ollama import Client\n",
|
|
"from gtts import gTTS\n",
|
|
"from playsound import playsound\n",
|
|
"import os\n",
|
|
"from pydub import AudioSegment\n",
|
|
"from pydub.playback import play\n",
|
|
"\n",
|
|
"# Configure ffmpeg paths - IMPORTANT: Replace with your actual conda path\n",
|
|
"ffprobe_path = \"/home/masih/anaconda3/bin/ffprobe\"\n",
|
|
"AudioSegment.ffprobe = ffprobe_path\n",
|
|
"os.environ[\"PATH\"] += os.pathsep + os.path.dirname(ffprobe_path)\n",
|
|
"\n",
|
|
"# Initialize Ollama client\n",
|
|
"client = Client(host='http://localhost:11434')\n",
|
|
"\n",
|
|
"system_prompt = (\n",
|
|
" \"You are a helpful and polite assistant. \"\n",
|
|
" \"Provide clear and concise responses. \"\n",
|
|
" \"Avoid repetition and maintain a friendly tone.\"\n",
|
|
")\n",
|
|
"\n",
|
|
"conversation_history = []\n",
|
|
"max_history_length = 5\n",
|
|
"\n",
|
|
"def generate_response(user_input):\n",
|
|
" global conversation_history\n",
|
|
" conversation_history.append(f\"User: {user_input}\")\n",
|
|
" \n",
|
|
" messages = [{'role': 'system', 'content': system_prompt}]\n",
|
|
" for interaction in conversation_history[-max_history_length:]:\n",
|
|
" try:\n",
|
|
" role_part, content = interaction.split(': ', 1)\n",
|
|
" messages.append({\n",
|
|
" 'role': role_part.lower(),\n",
|
|
" 'content': content\n",
|
|
" })\n",
|
|
" except ValueError:\n",
|
|
" continue\n",
|
|
" \n",
|
|
" try:\n",
|
|
" response = client.chat(\n",
|
|
" model='llama3.2', # Corrected model name\n",
|
|
" messages=messages,\n",
|
|
" options={\n",
|
|
" 'temperature': 0.7,\n",
|
|
" 'top_p': 0.9,\n",
|
|
" 'num_predict': 100\n",
|
|
" }\n",
|
|
" )\n",
|
|
" assistant_response = response['message']['content']\n",
|
|
" except Exception as e:\n",
|
|
" assistant_response = f\"Error: {str(e)}\"\n",
|
|
" \n",
|
|
" conversation_history.append(f\"Assistant: {assistant_response}\")\n",
|
|
" return assistant_response\n",
|
|
"\n",
|
|
"def text_to_speech(text, output_file=\"response.mp3\", lang='en'):\n",
|
|
" try:\n",
|
|
" if os.path.exists(output_file):\n",
|
|
" os.remove(output_file)\n",
|
|
" tts = gTTS(text=text, lang=lang)\n",
|
|
" tts.save(output_file)\n",
|
|
" print(f\"Speech saved to {output_file}\")\n",
|
|
" except Exception as e:\n",
|
|
" print(f\"Text-to-speech error: {e}\")\n",
|
|
"\n",
|
|
"def play_sound_with_speed(file_path, speed=1.2):\n",
|
|
" if not os.path.exists(file_path):\n",
|
|
" print(\"Audio file not found\")\n",
|
|
" return\n",
|
|
" \n",
|
|
" try:\n",
|
|
" # Try speed-adjusted playback\n",
|
|
" audio = AudioSegment.from_file(file_path)\n",
|
|
" altered_audio = audio._spawn(\n",
|
|
" audio.raw_data,\n",
|
|
" overrides={\"frame_rate\": int(audio.frame_rate * speed)}\n",
|
|
" )\n",
|
|
" play(altered_audio)\n",
|
|
" print(\"Playing at 1.2x speed\")\n",
|
|
" except Exception as e:\n",
|
|
" print(f\"Speed adjustment failed: {str(e)}. Using simple playback.\")\n",
|
|
" try:\n",
|
|
" playsound(file_path)\n",
|
|
" except Exception as fallback_e:\n",
|
|
" print(f\"All playback methods failed: {str(fallback_e)}\")\n",
|
|
"\n",
|
|
"print(\"Chat with AI (type 'stop' or 'quit' to exit)\")\n",
|
|
"print(\"Note: First response may take longer while model loads\")\n",
|
|
"\n",
|
|
"while True:\n",
|
|
" try:\n",
|
|
" user_input = input(\"\\nYou: \")\n",
|
|
" if user_input.lower() in ['stop', 'quit']:\n",
|
|
" print(\"Conversation ended\")\n",
|
|
" break\n",
|
|
" \n",
|
|
" response = generate_response(user_input)\n",
|
|
" print(f\"\\nAssistant: {response}\")\n",
|
|
" \n",
|
|
" text_to_speech(response)\n",
|
|
" play_sound_with_speed(\"response.mp3\")\n",
|
|
" \n",
|
|
" except KeyboardInterrupt:\n",
|
|
" print(\"\\nConversation interrupted\")\n",
|
|
" break\n",
|
|
" except Exception as e:\n",
|
|
" print(f\"Critical error: {str(e)}\")\n",
|
|
" break"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "d673f565-6002-4b90-8c1b-7df956f536a0",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "afbdf0c0-aa60-46a6-a2a1-044e58f26162",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python [conda env:base] *",
|
|
"language": "python",
|
|
"name": "conda-base-py"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.12.3"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|