idk
This commit is contained in:
@@ -9,6 +9,7 @@ test_agent.py
|
|||||||
config.ini
|
config.ini
|
||||||
.voices/
|
.voices/
|
||||||
experimental/
|
experimental/
|
||||||
|
chrome_bundle/
|
||||||
.logs/
|
.logs/
|
||||||
.screenshots/*.png
|
.screenshots/*.png
|
||||||
.screenshots/*.jpg
|
.screenshots/*.jpg
|
||||||
|
|||||||
+47
-47
@@ -8,23 +8,23 @@
|
|||||||
[English](./README.md) | 繁體中文 | [日本語](./README_JP.md)
|
[English](./README.md) | 繁體中文 | [日本語](./README_JP.md)
|
||||||
|
|
||||||
|
|
||||||
*一个 **100% 本地替代 Manus AI** 的方案,这款支持语音的 AI 助理能够自主浏览网页、编写代码和规划任务,同时将所有数据保留在您的设备上。专为本地推理模型量身打造,完全在您自己的硬件上运行,确保完全的隐私保护和零云端依赖。*
|
*一个 **100% 本地替代 Manus AI** 的方案,這款支持語音的 AI 助理能够自主瀏覽網頁、编寫代码和規劃任務,同时將所有用戶資料保留在您的裝置上。專門為本地推理模型量身打造,完全在您自己的硬體上執行,确保完全的隐私保护和零雲端依賴。*
|
||||||
|
|
||||||
[](https://fosowl.github.io/agenticSeek.html)  [](https://discord.gg/8hGDaME3TC) [](https://x.com/Martin993886460)
|
[](https://fosowl.github.io/agenticSeek.html)  [](https://discord.gg/8hGDaME3TC) [](https://x.com/Martin993886460)
|
||||||
|
|
||||||
### 为什么选择 AgenticSeek?
|
### 为什么選擇 AgenticSeek?
|
||||||
|
|
||||||
* 🔒 完全本地化与隐私保护 - 所有功能都在您的设备上运行 — 无云端服务,无数据共享。您的文件、对话和搜索始终保持私密。
|
* 🔒 完全本地化與隐私保护 - 所有功能都在您的设备上運行 — 无云端服务,无数据共享。您的文件、对话和搜索始终保持私密。
|
||||||
|
|
||||||
* 🌐 智能网页浏览 - AgenticSeek 能够自主浏览互联网 — 搜索、阅读、提取信息、填写网页表单 — 全程无需人工操作。
|
* 🌐 智能網頁瀏覽 - AgenticSeek 能够自主瀏覽網頁 — 搜索、閱读、提取信息、填寫網页表單 — 全程无需人工操作。
|
||||||
|
|
||||||
* 💻 自主编码助手 - 需要代码?它可以编写、调试并运行 Python、C、Go、Java 等多种语言的程序 — 全程无需监督。
|
* 💻 自主编码助手 - 需要代码?它可以编寫、调试并運行 Python、C、Go、Java 等多种语言的程序 — 全程无需监督。
|
||||||
|
|
||||||
* 🧠 智能代理选择 - 您提问,它会自动选择最适合该任务的代理。就像拥有一个随时待命的专家团队。
|
* 🧠 智能代理选择 - 您提问,它會自动选择最适合该任务的代理。就像拥有一个随时待命的專家团队。
|
||||||
|
|
||||||
* 📋 规划与执行复杂任务 - 从旅行规划到复杂项目 — 它能将大型任务分解为步骤,并利用多个 AI 代理完成工作。
|
* 📋 规划與执行复杂任务 - 从旅行规划到复杂项目 — 它能將大型任务分解为步骤,并利用多个 AI 代理完成工作。
|
||||||
|
|
||||||
* 🎙️ 语音功能 - 清晰、快速、未来感十足的语音与语音转文本功能,让您能像科幻电影中一样与您的个人 AI 助手对话。
|
* 🎙️ 語音功能 - 清晰、快速、未来感十足的語音與語音轉文本功能,讓您能像科幻电影中一样與您的个人 AI 助手对话。
|
||||||
|
|
||||||
https://github.com/user-attachments/assets/4bd5faf6-459f-4f94-bd1d-238c4b331469
|
https://github.com/user-attachments/assets/4bd5faf6-459f-4f94-bd1d-238c4b331469
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ https://github.com/user-attachments/assets/4bd5faf6-459f-4f94-bd1d-238c4b331469
|
|||||||
|
|
||||||
確保已安裝了 Chrome driver,Docker 和 Python 3.10(或更新)。
|
確保已安裝了 Chrome driver,Docker 和 Python 3.10(或更新)。
|
||||||
|
|
||||||
我们强烈建议您使用 Python 3.10 进行设置,否则可能会发生依赖错误。
|
我们强烈建议您使用 Python 3.10 進行設定,否则可能會发生依赖错误。
|
||||||
|
|
||||||
有關於 Chrome driver 的問題,請參見 **Chromedriver** 部分。
|
有關於 Chrome driver 的問題,請參見 **Chromedriver** 部分。
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ source agentic_seek_env/bin/activate
|
|||||||
./install.sh
|
./install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
** 若要让文本转语音(TTS)功能支持中文,你需要安装 jieba(中文分词库)和 cn2an(中文数字转换库):**
|
** 若要將文字轉成語音(TTS)功能支持中文,你需要安装 jieba(中文分詞庫)和 cn2an(中文數字轉換庫):**
|
||||||
|
|
||||||
```
|
```
|
||||||
pip3 install jieba cn2an
|
pip3 install jieba cn2an
|
||||||
@@ -73,7 +73,7 @@ pip3 install jieba cn2an
|
|||||||
**手動安裝:**
|
**手動安裝:**
|
||||||
|
|
||||||
|
|
||||||
**注意:对于任何操作系统,请确保您安装的 ChromeDriver 与您已安装的 Chrome 版本匹配。运行 `google-chrome --version`。如果您的 Chrome 版本 > 135,请参阅已知问题**
|
**注意:對於不同作業系統,請確保已經安装的 ChromeDriver 與您已安装的 Chrome 版本一致。可以執行 `google-chrome --version`。如果您的 Chrome 版本 > 135,請參考已知问题**
|
||||||
|
|
||||||
- *Linux*:
|
- *Linux*:
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ pip3 install jieba cn2an
|
|||||||
|
|
||||||
安装依赖项:`sudo apt install -y alsa-utils portaudio19-dev python3-pyaudio libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1`
|
安装依赖项:`sudo apt install -y alsa-utils portaudio19-dev python3-pyaudio libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1`
|
||||||
|
|
||||||
安装与您的 Chrome 浏览器版本匹配的 ChromeDriver:
|
安装與您的 Chrome 瀏覽器版本匹配的 ChromeDriver:
|
||||||
`sudo apt install -y chromium-chromedriver`
|
`sudo apt install -y chromium-chromedriver`
|
||||||
|
|
||||||
安装 requirements:`pip3 install -r requirements.txt`
|
安装 requirements:`pip3 install -r requirements.txt`
|
||||||
@@ -104,11 +104,11 @@ pip3 install jieba cn2an
|
|||||||
|
|
||||||
安装 pyreadline3:`pip install pyreadline3`
|
安装 pyreadline3:`pip install pyreadline3`
|
||||||
|
|
||||||
手动安装 portaudio(例如,通过 vcpkg 或预编译的二进制文件),然后运行:`pip install pyaudio`
|
手动安装 portaudio(例如,通过 vcpkg 或預編譯的二進制文件),然後運行:`pip install pyaudio`
|
||||||
|
|
||||||
从以下网址手动下载并安装 chromedriver:https://sites.google.com/chromium.org/driver/getting-started
|
从以下網址手动下载并安装 chromedriver:https://sites.google.com/chromium.org/driver/getting-started
|
||||||
|
|
||||||
将 chromedriver 放置在包含在您的 PATH 中的目录中。
|
將 chromedriver 放置在包含在您的 PATH 中的目录中。
|
||||||
|
|
||||||
安装 requirements:`pip3 install -r requirements.txt`
|
安装 requirements:`pip3 install -r requirements.txt`
|
||||||
|
|
||||||
@@ -116,45 +116,45 @@ pip3 install jieba cn2an
|
|||||||
|
|
||||||
**建議至少使用 Deepseek 14B 以上參數的模型,較小的模型難以使用助理功能並且很快就會忘記上下文之間的關係。**
|
**建議至少使用 Deepseek 14B 以上參數的模型,較小的模型難以使用助理功能並且很快就會忘記上下文之間的關係。**
|
||||||
|
|
||||||
**本地运行助手**
|
**本地運行助手**
|
||||||
|
|
||||||
启动你的本地提供者,例如使用 ollama:
|
啟動你的本地提供者,例如使用 ollama:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ollama serve
|
ollama serve
|
||||||
```
|
```
|
||||||
|
|
||||||
请参阅下方支持的本地提供者列表。
|
请参閱下方支持的本地提供者列表。
|
||||||
|
|
||||||
修改 config.ini 文件以设置 provider_name 为支持的提供者,并将 provider_model 设置为该提供者支持的 LLM。我们推荐使用具有推理能力的模型,如 *Qwen* 或 *Deepseek*。
|
修改 config.ini 文件以設定 provider_name 为支持的提供者,并將 provider_model 設定为该提供者支持的 LLM。我们推荐使用具有推理能力的模型,如 *Qwen* 或 *Deepseek*。
|
||||||
|
|
||||||
请参见 README 末尾的 **FAQ** 部分了解所需硬件。
|
请参见 README 末尾的 **FAQ** 部分了解所需硬件。
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
[MAIN]
|
[MAIN]
|
||||||
is_local = True # 无论是在本地运行还是使用远程提供者。
|
is_local = True # 无论是在本地運行还是使用远程提供者。
|
||||||
provider_name = ollama # 或 lm-studio, openai 等..
|
provider_name = ollama # 或 lm-studio, openai 等..
|
||||||
provider_model = deepseek-r1:14b # 选择适合您硬件的模型
|
provider_model = deepseek-r1:14b # 选择适合您硬件的模型
|
||||||
provider_server_address = 127.0.0.1:11434
|
provider_server_address = 127.0.0.1:11434
|
||||||
agent_name = Jarvis # 您的 AI 助手的名称
|
agent_name = Jarvis # 您的 AI 助手的名称
|
||||||
recover_last_session = True # 是否恢复之前的会话
|
recover_last_session = True # 是否恢复之前的會话
|
||||||
save_session = True # 是否记住当前会话
|
save_session = True # 是否记住当前會话
|
||||||
speak = True # 文本转语音
|
speak = True # 文本轉語音
|
||||||
listen = False # 语音转文本,仅适用于命令行界面
|
listen = False # 語音轉文本,僅适用于命令行界面
|
||||||
work_dir = /Users/mlg/Documents/workspace # AgenticSeek 的工作空间。
|
work_dir = /Users/mlg/Documents/workspace # AgenticSeek 的工作空间。
|
||||||
jarvis_personality = False # 是否使用更"贾维斯"风格的性格,不推荐在小型模型上使用
|
jarvis_personality = False # 是否使用更"贾维斯"风格的性格,不推荐在小型模型上使用
|
||||||
languages = en zh # 语言列表,文本转语音将默认使用列表中的第一种语言
|
languages = en zh # 语言列表,文本轉語音將默认使用列表中的第一种语言
|
||||||
[BROWSER]
|
[BROWSER]
|
||||||
headless_browser = True # 是否使用无头浏览器,只有在使用网页界面时才推荐使用。
|
headless_browser = True # 是否使用无头瀏覽器,只有在使用網页界面时才推荐使用。
|
||||||
stealth_mode = True # 使用无法检测的 selenium 来减少浏览器检测
|
stealth_mode = True # 使用无法檢測的 selenium 来减少瀏覽器檢測
|
||||||
```
|
```
|
||||||
|
|
||||||
**本地提供者列表**
|
**本地提供者列表**
|
||||||
|
|
||||||
| 提供者 | 本地? | 描述 |
|
| 提供者 | 本地? | 描述 |
|
||||||
|-------------|--------|-------------------------------------------------------|
|
|-------------|--------|-------------------------------------------------------|
|
||||||
| ollama | 是 | 使用 ollama 作为 LLM 提供者,轻松本地运行 LLM |
|
| ollama | 是 | 使用 ollama 作为 LLM 提供者,轻松本地運行 LLM |
|
||||||
| lm-studio | 是 | 使用 LM Studio 本地运行 LLM(将 `provider_name` 设置为 `lm-studio`)|
|
| lm-studio | 是 | 使用 LM Studio 本地運行 LLM(將 `provider_name` 設定为 `lm-studio`)|
|
||||||
| openai | 否 | 使用兼容的 API |
|
| openai | 否 | 使用兼容的 API |
|
||||||
|
|
||||||
下一步: [Start services and run AgenticSeek](#Start-services-and-Run)
|
下一步: [Start services and run AgenticSeek](#Start-services-and-Run)
|
||||||
@@ -184,14 +184,14 @@ provider_server_address = 127.0.0.1:5000
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Start services and Run
|
## Start services and Run
|
||||||
(启动服务并运行)
|
(啟動服务并運行)
|
||||||
|
|
||||||
如果需要,请激活你的 Python 环境。
|
如果需要,请激活你的 Python 环境。
|
||||||
```sh
|
```sh
|
||||||
source agentic_seek_env/bin/activate
|
source agentic_seek_env/bin/activate
|
||||||
```
|
```
|
||||||
|
|
||||||
启动所需的服务。这将启动 `docker-compose.yml` 中的所有服务,包括:
|
啟動所需的服务。这將啟動 `docker-compose.yml` 中的所有服务,包括:
|
||||||
- searxng
|
- searxng
|
||||||
- redis(由 redis 提供支持)
|
- redis(由 redis 提供支持)
|
||||||
- 前端
|
- 前端
|
||||||
@@ -201,25 +201,25 @@ sudo ./start_services.sh # MacOS
|
|||||||
start ./start_services.cmd # Windows
|
start ./start_services.cmd # Windows
|
||||||
```
|
```
|
||||||
|
|
||||||
**选项 1:** 使用 CLI 界面运行。
|
**選項 1:** 使用 CLI 界面運行。
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
python3 cli.py
|
python3 cli.py
|
||||||
```
|
```
|
||||||
|
|
||||||
**选项 2:** 使用 Web 界面运行。
|
**選項 2:** 使用 Web 界面運行。
|
||||||
|
|
||||||
注意:目前我們建議您使用 CLI 界面。Web 界面仍在積極開發中。
|
注意:目前我們建議您使用 CLI 界面。Web 界面仍在積極開發中。
|
||||||
|
|
||||||
启动后端服务。
|
啟動後端服务。
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
python3 api.py
|
python3 api.py
|
||||||
```
|
```
|
||||||
|
|
||||||
访问 `http://localhost:3000/`,你应该会看到 Web 界面。
|
访问 `http://localhost:3000/`,你应该會看到 Web 界面。
|
||||||
|
|
||||||
请注意,目前 Web 界面不支持消息流式传输。
|
请注意,目前 Web 界面不支持消息流式傳輸。
|
||||||
|
|
||||||
|
|
||||||
*如果你不知道如何開始,請參閱 **Usage** 部分*
|
*如果你不知道如何開始,請參閱 **Usage** 部分*
|
||||||
@@ -228,9 +228,9 @@ python3 api.py
|
|||||||
|
|
||||||
## Usage (使用方法)
|
## Usage (使用方法)
|
||||||
|
|
||||||
为确保 agenticSeek 在中文环境下正常工作,请确保在 config.ini 中设置语言选项。
|
为确保 agenticSeek 在中文环境下正常工作,请确保在 config.ini 中設定语言選項。
|
||||||
languages = en zh
|
languages = en zh
|
||||||
更多信息请参阅 Config 部分
|
更多信息请参閱 Config 部分
|
||||||
|
|
||||||
確定所有的核心檔案都啟用了,也就是執行過這條命令 `./start_services.sh` 然後你就可以使用 `python3 cli.py` 來啟動 AgenticSeek 了!
|
確定所有的核心檔案都啟用了,也就是執行過這條命令 `./start_services.sh` 然後你就可以使用 `python3 cli.py` 來啟動 AgenticSeek 了!
|
||||||
|
|
||||||
@@ -287,11 +287,11 @@ python3 cli.py
|
|||||||
所以我們希望你在使用時,能明確地表明你希望他要怎麼做,下面給你一個範例!
|
所以我們希望你在使用時,能明確地表明你希望他要怎麼做,下面給你一個範例!
|
||||||
|
|
||||||
你該說:
|
你該說:
|
||||||
- 进行网络搜索,找出哪些国家最适合独自旅行
|
- 進行網路搜索,找出哪些国家最适合獨自旅行
|
||||||
|
|
||||||
|
|
||||||
而不是說:
|
而不是說:
|
||||||
- 你知道哪些国家适合独自旅行?
|
- 你知道哪些国家适合獨自旅行?
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -357,7 +357,7 @@ provider_server_address = x.x.x.x:3333
|
|||||||
|
|
||||||
## 語音轉文字
|
## 語音轉文字
|
||||||
|
|
||||||
请注意,目前语音转文字功能仅支持英语。
|
请注意,目前語音轉文字功能僅支援英语。
|
||||||
|
|
||||||
預設狀況下,語音轉文字功能是停用的。若要啟用它,請在 `config.ini` 檔案中,將 `listen` 選項設為 `True`:
|
預設狀況下,語音轉文字功能是停用的。若要啟用它,請在 `config.ini` 檔案中,將 `listen` 選項設為 `True`:
|
||||||
|
|
||||||
@@ -538,13 +538,13 @@ https://googlechromelabs.github.io/chrome-for-testing/
|
|||||||
|
|
||||||
**Q: 是否支持中文以外的语言?**
|
**Q: 是否支持中文以外的语言?**
|
||||||
|
|
||||||
DeepSeek R1 天生会说中文
|
DeepSeek R1 天生會说中文
|
||||||
|
|
||||||
但注意:代理路由系统只懂英文,所以必须通过 config.ini 的 languages 参数(如 languages = en zh)告诉系统:
|
但注意:代理路由系统只懂英文,所以必须通过 config.ini 的 languages 参数(如 languages = en zh)告诉系统:
|
||||||
|
|
||||||
如果不设置中文?后果可能是:你让它写代码,结果跳出来个"医生代理"(虽然我们根本没有这个代理... 但系统会一脸懵圈!)
|
如果不設定中文?後果可能是:你讓它寫代码,结果跳出来个"醫生代理"(虽然我们根本没有这个代理... 但系统會一脸懵圈!)
|
||||||
|
|
||||||
实际上会下载一个小型翻译模型来协助任务分配
|
实际上會下载一个小型翻译模型来协助任务分配
|
||||||
|
|
||||||
## 貢獻
|
## 貢獻
|
||||||
|
|
||||||
@@ -556,8 +556,8 @@ DeepSeek R1 天生会说中文
|
|||||||
|
|
||||||
## 维护者:
|
## 维护者:
|
||||||
|
|
||||||
> [Fosowl](https://github.com/Fosowl) | 巴黎时间
|
> [Fosowl](https://github.com/Fosowl) | 巴黎時間 | (有时很忙)
|
||||||
|
|
||||||
> [antoineVIVIES](https://github.com/antoineVIVIES) | Taipei Time
|
> [https://github.com/antoineVIVIES](https://github.com/antoineVIVIES) | 台北時間 | (經常很忙)
|
||||||
|
|
||||||
> [steveh8758](https://github.com/steveh8758) | 台北时间
|
> [steveh8758](https://github.com/steveh8758) | 台北時間 | (總是很忙)
|
||||||
|
|||||||
+8
-8
@@ -1,15 +1,15 @@
|
|||||||
[MAIN]
|
[MAIN]
|
||||||
is_local = True
|
is_local = False
|
||||||
provider_name = ollama
|
provider_name = together
|
||||||
provider_model = deepseek-r1:14b
|
provider_model = perplexity-ai/r1-1776
|
||||||
provider_server_address = 127.0.0.1:11434
|
provider_server_address = 127.0.0.1:5000
|
||||||
agent_name = Name_of_your_AI
|
agent_name = Jarvis
|
||||||
recover_last_session = False
|
recover_last_session = False
|
||||||
save_session = False
|
save_session = False
|
||||||
speak = False
|
speak = True
|
||||||
listen = False
|
listen = False
|
||||||
work_dir = /Users/mlg/Documents/workspace_for_agenticseek
|
work_dir = ${WORK_DIR}
|
||||||
jarvis_personality = False
|
jarvis_personality = True
|
||||||
languages = en
|
languages = en
|
||||||
[BROWSER]
|
[BROWSER]
|
||||||
headless_browser = True
|
headless_browser = True
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ server:
|
|||||||
# If your instance owns a /etc/searxng/settings.yml file, then set the following
|
# If your instance owns a /etc/searxng/settings.yml file, then set the following
|
||||||
# values there.
|
# values there.
|
||||||
|
|
||||||
secret_key: "1234bbd68b6c51ff0b9ccb77e39b1f20a3178b63e71496cbc89ef019f0341382" # Is overwritten by ${SEARXNG_SECRET}
|
secret_key: "2b3888dcb9503a911f9ef053b7828803724a59815ce901774d9d73fa63603360" # Is overwritten by ${SEARXNG_SECRET}
|
||||||
# Proxy image results through SearXNG. Is overwritten by ${SEARXNG_IMAGE_PROXY}
|
# Proxy image results through SearXNG. Is overwritten by ${SEARXNG_IMAGE_PROXY}
|
||||||
image_proxy: false
|
image_proxy: false
|
||||||
# 1.0 and 1.1 are supported
|
# 1.0 and 1.1 are supported
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
[uwsgi]
|
||||||
|
# Listening address
|
||||||
|
# default value: [::]:8080 (see Dockerfile)
|
||||||
|
http-socket = $(BIND_ADDRESS)
|
||||||
|
|
||||||
|
# Who will run the code
|
||||||
|
uid = searxng
|
||||||
|
gid = searxng
|
||||||
|
|
||||||
|
# Number of workers (usually CPU count)
|
||||||
|
# default value: %k (= number of CPU core, see Dockerfile)
|
||||||
|
workers = 4
|
||||||
|
|
||||||
|
# Number of threads per worker
|
||||||
|
# default value: 4 (see Dockerfile)
|
||||||
|
threads = 4
|
||||||
|
|
||||||
|
# The right granted on the created socket
|
||||||
|
chmod-socket = 666
|
||||||
|
|
||||||
|
# Plugin to use and interpreter config
|
||||||
|
single-interpreter = true
|
||||||
|
master = true
|
||||||
|
lazy-apps = true
|
||||||
|
enable-threads = 4
|
||||||
|
|
||||||
|
# Module to import
|
||||||
|
module = searx.webapp
|
||||||
|
|
||||||
|
# Virtualenv and python path
|
||||||
|
pythonpath = /usr/local/searxng/
|
||||||
|
chdir = /usr/local/searxng/searx/
|
||||||
|
|
||||||
|
# automatically set processes name to something meaningful
|
||||||
|
auto-procname = true
|
||||||
|
|
||||||
|
# Disable request logging for privacy
|
||||||
|
disable-logging = true
|
||||||
|
log-5xx = true
|
||||||
|
|
||||||
|
# Set the max size of a request (request-body excluded)
|
||||||
|
buffer-size = 8192
|
||||||
|
|
||||||
|
# No keep alive
|
||||||
|
# See https://github.com/searx/searx-docker/issues/24
|
||||||
|
add-header = Connection: close
|
||||||
|
|
||||||
|
# Follow SIGTERM convention
|
||||||
|
# See https://github.com/searxng/searxng/issues/3427
|
||||||
|
die-on-term
|
||||||
|
|
||||||
|
# uwsgi serves the static files
|
||||||
|
static-map = /static=/usr/local/searxng/searx/static
|
||||||
|
static-gzip-all = True
|
||||||
|
offload-threads = 4
|
||||||
Reference in New Issue
Block a user