Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,34 @@ For unstable multi-agent version, you also can run:
python run_flow.py
```

### Web interface (experimental)

Before launching the server ensure the optional web dependencies are installed:

```bash
pip install fastapi uvicorn pydantic
# or install everything from requirements.txt
pip install -r requirements.txt
```

To try the browser-based experience, start the FastAPI server:

```bash
uvicorn app.web.server:app --reload
```

Then open <http://localhost:8000> to access the chat UI. Each browser tab keeps its
own session and conversations are stored in memory while the server is running.

Alternatively, you can launch the bundled runner which wraps `uvicorn`:

```bash
python -m app.web.server --host 0.0.0.0 --port 8000
```

Pass `--reload` for auto-reload in development environments.


### Custom Adding Multiple Agents

Currently, besides the general OpenManus Agent, we have also integrated the DataAnalysis Agent, which is suitable for data analysis and data visualization tasks. You can add this agent to `run_flow` in `config.toml`.
Expand Down
62 changes: 52 additions & 10 deletions app/logger.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,70 @@
import logging
import sys
from datetime import datetime
from importlib.util import find_spec
from pathlib import Path

from loguru import logger as _logger
PROJECT_ROOT = Path(__file__).resolve().parents[1]

from app.config import PROJECT_ROOT

if find_spec("loguru") is not None:
from loguru import logger as _logger # type: ignore[import-not-found]

_loguru_available = True
else: # pragma: no cover - loguru expected in production environments
_loguru_available = False
_logger = logging.getLogger("app")


_print_level = "INFO"


def define_log_level(print_level="INFO", logfile_level="DEBUG", name: str = None):
"""Adjust the log level to above level"""
def define_log_level(
print_level: str = "INFO", logfile_level: str = "DEBUG", name: str | None = None
Comment on lines +22 to +23
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The function signature uses modern Python union syntax (str | None) but should be consistent with the typing imports. Consider using Optional[str] from typing module for broader compatibility.

Copilot uses AI. Check for mistakes.
):
"""Configure the application logger with sane defaults.
Uses *loguru* when available for richer logging capabilities while
gracefully falling back to the standard :mod:`logging` module when the
dependency is missing (for example in lightweight environments).
"""

global _print_level
_print_level = print_level

current_date = datetime.now()
formatted_date = current_date.strftime("%Y%m%d%H%M%S")
log_name = (
f"{name}_{formatted_date}" if name else formatted_date
) # name a log with prefix name
log_name = f"{name}_{formatted_date}" if name else formatted_date

log_dir: Path = PROJECT_ROOT / "logs"
log_dir.mkdir(parents=True, exist_ok=True)

if _loguru_available:
_logger.remove()
_logger.add(sys.stderr, level=print_level)
_logger.add(log_dir / f"{log_name}.log", level=logfile_level)
else:
_logger.setLevel(getattr(logging, logfile_level.upper(), logging.DEBUG))

for handler in list(_logger.handlers):
_logger.removeHandler(handler)

formatter = logging.Formatter(
"%(asctime)s | %(levelname)s | %(name)s | %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)

stream_handler = logging.StreamHandler(sys.stderr)
stream_handler.setLevel(getattr(logging, print_level.upper(), logging.INFO))
stream_handler.setFormatter(formatter)

file_handler = logging.FileHandler(log_dir / f"{log_name}.log")
file_handler.setLevel(getattr(logging, logfile_level.upper(), logging.DEBUG))
file_handler.setFormatter(formatter)

_logger.addHandler(stream_handler)
_logger.addHandler(file_handler)

_logger.remove()
_logger.add(sys.stderr, level=print_level)
_logger.add(PROJECT_ROOT / f"logs/{log_name}.log", level=logfile_level)
return _logger


Expand Down
Empty file added app/web/__init__.py
Empty file.
Loading
Loading