Skip to content

Commit 4336b3b

Browse files
author
bittoby
committed
fix: solve merege conflict
2 parents 15a46df + a9ba42c commit 4336b3b

177 files changed

Lines changed: 25745 additions & 2071 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,4 @@ resources/prebuilt/cache/
6363

6464
*storybook.log
6565
storybook-static
66+
nul

backend/app/agent/prompt.py

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@
3030
Your integrated toolkits enable you to:
3131
3232
1. Skills System: You have access to a library of specialized skills that
33-
provide expert guidance for specific tasks. When a skill is referenced with
34-
double curly braces (e.g., {{pdf}} or {{data-analyzer}}), you should use
35-
`list_skills` to discover available skills and `load_skill` to retrieve the
36-
skill's full content. Skills contain tested code examples, best practices,
37-
and detailed instructions that you MUST follow as your PRIMARY reference when
38-
working on tasks that mention them.
33+
provide expert guidance for specific tasks. When a task references a skill
34+
with double curly braces (e.g., {{pdf}} or {{data-analyzer}}), or when you
35+
determine that an available skill is relevant to the task, you MUST use
36+
`load_skill` to retrieve the skill's full content BEFORE taking any other
37+
action on the task. Skills contain requirements, tested code examples, and
38+
best practices that you MUST follow as your PRIMARY reference. Do not begin
39+
executing the task until you have loaded and understood the relevant skill
40+
instructions.
3941
4042
2. WhatsApp Business Management (WhatsAppToolkit):
4143
- Send text and template messages to customers via the WhatsApp Business
@@ -151,12 +153,14 @@
151153
<capabilities>
152154
Your capabilities include:
153155
- **Skills System**: You have access to a library of specialized skills that
154-
provide expert guidance for specific tasks. When a skill is referenced with
155-
double curly braces (e.g., {{pdf}} or {{data-analyzer}}), you should use
156-
`list_skills` to discover available skills and `load_skill` to retrieve the
157-
skill's full content. Skills contain tested code examples, best practices,
158-
and detailed instructions that you MUST follow as your PRIMARY reference when
159-
working on tasks that mention them.
156+
provide expert guidance for specific tasks. When a task references a skill
157+
with double curly braces (e.g., {{pdf}} or {{data-analyzer}}), or when you
158+
determine that an available skill is relevant to the task, you MUST use
159+
`load_skill` to retrieve the skill's full content BEFORE taking any other
160+
action on the task. Skills contain requirements, tested code examples, and
161+
best practices that you MUST follow as your PRIMARY reference. Do not begin
162+
executing the task until you have loaded and understood the relevant skill
163+
instructions.
160164
- Video & Audio Analysis:
161165
- Download videos from URLs for analysis.
162166
- Transcribe speech from audio files to text with high accuracy
@@ -280,12 +284,14 @@
280284
Your capabilities include:
281285
- You can use ScreenshotToolkit to read image with given path.
282286
- **Skills System**: You have access to a library of specialized skills that
283-
provide expert guidance for specific tasks. When a skill is referenced with
284-
double curly braces (e.g., {{pdf}} or {{data-analyzer}}), you should use
285-
`list_skills` to discover available skills and `load_skill` to retrieve the
286-
skill's full content. Skills contain tested code examples, best practices,
287-
and detailed instructions that you MUST follow as your PRIMARY reference when
288-
working on tasks that mention them.
287+
provide expert guidance for specific tasks. When a task references a skill
288+
with double curly braces (e.g., {{pdf}} or {{data-analyzer}}), or when you
289+
determine that an available skill is relevant to the task, you MUST use
290+
`load_skill` to retrieve the skill's full content BEFORE taking any other
291+
action on the task. Skills contain requirements, tested code examples, and
292+
best practices that you MUST follow as your PRIMARY reference. Do not begin
293+
executing the task until you have loaded and understood the relevant skill
294+
instructions.
289295
- Document Reading:
290296
- Read and understand the content of various file formats including
291297
- PDF (.pdf)
@@ -438,12 +444,14 @@
438444
Your capabilities are extensive and powerful:
439445
- You can use ScreenshotToolkit to read image with given path.
440446
- **Skills System**: You have access to a library of specialized skills that
441-
provide expert guidance for specific tasks. When a skill is referenced with
442-
double curly braces (e.g., {{pdf}} or {{data-analyzer}}), you should use
443-
`list_skills` to discover available skills and `load_skill` to retrieve the
444-
skill's full content. Skills contain tested code examples, best practices,
445-
and detailed instructions that you MUST follow as your PRIMARY reference when
446-
working on tasks that mention them.
447+
provide expert guidance for specific tasks. When a task references a skill
448+
with double curly braces (e.g., {{pdf}} or {{data-analyzer}}), or when you
449+
determine that an available skill is relevant to the task, you MUST use
450+
`load_skill` to retrieve the skill's full content BEFORE taking any other
451+
action on the task. Skills contain requirements, tested code examples, and
452+
best practices that you MUST follow as your PRIMARY reference. Do not begin
453+
executing the task until you have loaded and understood the relevant skill
454+
instructions.
447455
- **Unrestricted Code Execution**: You can write and execute code in any
448456
language to solve a task. You MUST first save your code to a file (e.g.,
449457
`script.py`) and then run it from the terminal (e.g.,
@@ -614,12 +622,14 @@
614622
Your capabilities include:
615623
- You can use ScreenshotToolkit to read image with given path.
616624
- **Skills System**: You have access to a library of specialized skills that
617-
provide expert guidance for specific tasks. When a skill is referenced with
618-
double curly braces (e.g., {{pdf}} or {{data-analyzer}}), you should use
619-
`list_skills` to discover available skills and `load_skill` to retrieve the
620-
skill's full content. Skills contain tested code examples, best practices,
621-
and detailed instructions that you MUST follow as your PRIMARY reference when
622-
working on tasks that mention them.
625+
provide expert guidance for specific tasks. When a task references a skill
626+
with double curly braces (e.g., {{pdf}} or {{data-analyzer}}), or when you
627+
determine that an available skill is relevant to the task, you MUST use
628+
`load_skill` to retrieve the skill's full content BEFORE taking any other
629+
action on the task. Skills contain requirements, tested code examples, and
630+
best practices that you MUST follow as your PRIMARY reference. Do not begin
631+
executing the task until you have loaded and understood the relevant skill
632+
instructions.
623633
- Search and get information from the web using the search tools.
624634
- Use the rich browser related toolset to investigate websites.
625635
- Use the terminal tools to perform local operations. **IMPORTANT:** Before the

backend/app/controller/tool_controller.py

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import logging
1616
import os
17+
import shutil
1718
import time
1819

1920
from fastapi import APIRouter, HTTPException
@@ -712,16 +713,39 @@ def is_port_in_use(port):
712713
f"Electron browser script not found: {electron_script_path}"
713714
)
714715

715-
electron_cmd = "npx"
716-
electron_args = [
717-
electron_cmd,
716+
# Resolve npx path for Windows compatibility.
717+
# On Windows, subprocess.Popen uses CreateProcess which cannot
718+
# execute .cmd files directly. We resolve the full path and
719+
# invoke via cmd.exe.
720+
npx_cmd = None
721+
if os.name == "nt":
722+
eigent_npx = os.path.expanduser("~/.eigent/bin/npx.cmd")
723+
if os.path.exists(eigent_npx):
724+
npx_cmd = eigent_npx
725+
if not npx_cmd:
726+
npx_cmd = shutil.which("npx") or shutil.which("npx.cmd")
727+
if not npx_cmd:
728+
if os.name == "nt":
729+
raise FileNotFoundError(
730+
"npx not found. Please ensure Node.js is installed and npx is on your PATH."
731+
)
732+
npx_cmd = "npx"
733+
734+
base_args = [
735+
npx_cmd,
718736
"electron",
719737
electron_script_path,
720738
user_data_dir,
721739
str(cdp_port),
722740
"https://www.google.com",
723741
]
724742

743+
# On Windows, wrap with cmd.exe so .cmd execution is reliable
744+
if os.name == "nt":
745+
electron_args = ["cmd.exe", "/d", "/s", "/c"] + base_args
746+
else:
747+
electron_args = base_args
748+
725749
# Get the app's directory to run npx in the right context
726750
app_dir = os.path.dirname(
727751
os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
@@ -736,10 +760,17 @@ def is_port_in_use(port):
736760
logger.info(f"[PROFILE USER LOGIN] userData path: {user_data_dir}")
737761
logger.info(f"[PROFILE USER LOGIN] Electron args: {electron_args}")
738762

763+
# Ensure ~/.eigent/bin is on PATH for the spawned process
764+
env = os.environ.copy()
765+
eigent_bin = os.path.expanduser("~/.eigent/bin")
766+
if os.path.isdir(eigent_bin):
767+
env["PATH"] = eigent_bin + os.pathsep + env.get("PATH", "")
768+
739769
# Start process and capture output in real-time
740770
process = subprocess.Popen(
741771
electron_args,
742772
cwd=app_dir,
773+
env=env,
743774
stdout=subprocess.PIPE,
744775
stderr=subprocess.STDOUT, # Redirect stderr to stdout
745776
text=True,
@@ -793,6 +824,20 @@ async def log_electron_output():
793824
)
794825

795826

827+
@router.get("/browser/status", name="browser status")
828+
async def browser_status():
829+
"""Check if the login browser is currently open."""
830+
import socket
831+
832+
cdp_port = 9223
833+
834+
def is_port_in_use(port):
835+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
836+
return s.connect_ex(("localhost", port)) == 0
837+
838+
return {"is_open": is_port_in_use(cdp_port)}
839+
840+
796841
@router.get("/browser/cookies", name="list cookie domains")
797842
async def list_cookie_domains(search: str = None):
798843
"""

backend/app/model/model_platform.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"z.ai": "openai-compatible-model",
2121
"ModelArk": "openai-compatible-model",
2222
"grok": "openai-compatible-model",
23+
"llama.cpp": "openai-compatible-model",
2324
}
2425

2526

backend/tests/app/model/test_model_platform.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def test_normalize_model_platform_maps_known_aliases():
2626
assert normalize_model_platform("grok") == "openai-compatible-model"
2727
assert normalize_model_platform("z.ai") == "openai-compatible-model"
2828
assert normalize_model_platform("ModelArk") == "openai-compatible-model"
29+
assert normalize_model_platform("llama.cpp") == "openai-compatible-model"
2930

3031

3132
def test_normalize_model_platform_keeps_non_alias_unchanged():
@@ -43,7 +44,7 @@ class _Model(BaseModel):
4344
optional_model_platform: NormalizedOptionalModelPlatform = None
4445

4546
item = _Model(
46-
model_platform="grok",
47+
model_platform="llama.cpp",
4748
optional_model_platform="ModelArk",
4849
)
4950

docs/core/models/local-model.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ print(f"Server started on http://localhost:{port}")
3838
ollama pull qwen2.5:7b
3939
```
4040

41+
```bash
42+
# LLaMA.cpp server https://github.com/ggml-org/llama.cpp/tree/master/tools/server
43+
./llama-server -m /path/to/model.gguf --host 0.0.0.0 --port 8080
44+
```
45+
4146
2. Setting your model
4247

4348
![set_local_model](/docs/images/models_local_model.png)

docs/get_started/quick_start.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ Eigent can run in two modes. Your choice here affects how you are billed and wha
173173
- **Cloud Version:** We provide pre-configured, state-of-the-art models, including GPT-4.1, GPT-4.1 mini and Gemini 2.5 Pro. Using these models is the easiest way to get started and will be billed to your account based on usage (credits).
174174
- **Self-hosted Version:** You can connect your own models.
175175
- **Cloud Models:** Connect your personal accounts from providers like OpenAI, Anthropic, Qwen, Deepseek and Azure by entering your own API key.
176-
- **Local Models:** For advanced users, you can run models locally using Ollama, vLLM, or SGLang.
176+
- **Local Models:** For advanced users, you can run models locally using Ollama, vLLM, SGLang, LM Studio, or LLaMA.cpp server.
177177

178178
### **MCP Servers**
179179

electron/main/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -693,9 +693,10 @@ function registerIpcHandlers() {
693693
// Launch CDP browser with automatic port assignment
694694
ipcMain.handle('launch-cdp-browser', async () => {
695695
try {
696-
// 1. Find available port (9223–9300) by checking no CDP browser is listening
696+
// 1. Find available port (9224–9300) by checking no CDP browser is listening
697+
// Port 9223 is reserved for the login browser
697698
let port: number | null = null;
698-
for (let p = 9223; p < 9300; p++) {
699+
for (let p = 9224; p < 9300; p++) {
699700
if (
700701
!cdp_browser_pool.some((b) => b.port === p) &&
701702
!(await isCdpPortAlive(p))
@@ -705,7 +706,7 @@ function registerIpcHandlers() {
705706
}
706707
}
707708
if (port === null) {
708-
return { success: false, error: 'No available port in 9223-9299' };
709+
return { success: false, error: 'No available port in 9224-9299' };
709710
}
710711

711712
// 2. Find Playwright Chromium executable

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"@radix-ui/react-toggle-group": "^1.1.10",
7171
"@radix-ui/react-tooltip": "^1.2.7",
7272
"@stackframe/react": "file:package/@stackframe/react",
73+
"@tanstack/react-query": "^5.90.19",
7374
"@xterm/addon-fit": "^0.10.0",
7475
"@xterm/addon-web-links": "^0.11.0",
7576
"@xterm/xterm": "^5.5.0",
@@ -81,6 +82,7 @@
8182
"clsx": "^2.1.1",
8283
"cmdk": "^1.1.1",
8384
"csv-parser": "^3.2.0",
85+
"date-fns": "^3.6.0",
8486
"dompurify": "^3.2.7",
8587
"electron-log": "^5.4.0",
8688
"electron-updater": "^6.3.9",
@@ -101,6 +103,7 @@
101103
"next-themes": "^0.4.6",
102104
"papaparse": "^5.5.3",
103105
"postprocessing": "^6.37.8",
106+
"react-day-picker": "^9.13.0",
104107
"react-markdown": "^10.1.0",
105108
"react-resizable-panels": "^3.0.4",
106109
"react-router-dom": "^7.6.0",

server/.env.example

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,31 @@
11
debug=false
22
url_prefix=/api
33
secret_key=postgres
4-
database_url=postgresql://postgres:123456@localhost:5432/postgres
54
# Chat Share Secret Key
65
CHAT_SHARE_SECRET_KEY=put-your-secret-key-here
76
CHAT_SHARE_SALT=put-your-encode-salt-here
7+
8+
# Configuration if not running in docker
9+
# database_url=postgresql://postgres:123456@localhost:5432/eigent
10+
# redis_url=redis://localhost:6379/0
11+
# celery_broker_url=redis://localhost:6379/0
12+
# celery_result_url=redis://localhost:6379/0
13+
# SESSION_REDIS_URL=redis://localhost:6379/1
14+
15+
# Trigger Schedule Poller Configuration
16+
# ENABLE_TRIGGER_SCHEDULE_POLLER_TASK: Enable/disable scheduled trigger polling
17+
ENABLE_TRIGGER_SCHEDULE_POLLER_TASK=true
18+
# TRIGGER_SCHEDULE_POLLER_INTERVAL: Polling interval in minutes
19+
TRIGGER_SCHEDULE_POLLER_INTERVAL=1
20+
# TRIGGER_SCHEDULE_POLLER_BATCH_SIZE: Number of triggers to fetch per poll
21+
TRIGGER_SCHEDULE_POLLER_BATCH_SIZE=100
22+
# TRIGGER_SCHEDULE_MAX_DISPATCH_PER_TICK: Max triggers to dispatch per tick (0 = unlimited)
23+
TRIGGER_SCHEDULE_MAX_DISPATCH_PER_TICK=0
24+
# ENABLE_EXECUTION_TIMEOUT_CHECKER: Enable/disable execution timeout checking
25+
ENABLE_EXECUTION_TIMEOUT_CHECKER=true
26+
# EXECUTION_TIMEOUT_CHECKER_INTERVAL: check_execution_timeouts interval in minutes
27+
EXECUTION_TIMEOUT_CHECKER_INTERVAL=1
28+
# EXECUTION_PENDING_TIMEOUT_SECONDS: Timeout for pending executions (default 60 seconds)
29+
EXECUTION_PENDING_TIMEOUT_SECONDS=60
30+
# EXECUTION_RUNNING_TIMEOUT_SECONDS: Timeout for running executions (default 600 seconds / 10 minutes)
31+
EXECUTION_RUNNING_TIMEOUT_SECONDS=600

0 commit comments

Comments
 (0)