mirror of
https://github.com/csunny/DB-GPT.git
synced 2026-07-16 17:15:22 +00:00
fix: fix skill workspace directory
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "dbgpt-acc-auto"
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
description = "Add your description here"
|
||||
authors = [
|
||||
{ name = "csunny", email = "cfqcsunny@gmail.com" }
|
||||
|
||||
@@ -1 +1 @@
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# https://github.com/astral-sh/uv/issues/2252#issuecomment-2624150395
|
||||
[project]
|
||||
name = "dbgpt-acc-flash-attn"
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
|
||||
@@ -1 +1 @@
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "dbgpt-app"
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
description = "Add your description here"
|
||||
authors = [
|
||||
{ name = "csunny", email = "cfqcsunny@gmail.com" }
|
||||
@@ -64,3 +64,21 @@ exclude = [
|
||||
"src/dbgpt_app/**/examples/*"
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.sdist.force-include]
|
||||
"../../skills/csv-data-analysis" = "skills/csv-data-analysis"
|
||||
"../../skills/skill-creator" = "skills/skill-creator"
|
||||
"../../skills/financial-report-analyzer" = "skills/financial-report-analyzer"
|
||||
"../../skills/walmart-sales-analyzer" = "skills/walmart-sales-analyzer"
|
||||
"../../skills/agent-browser" = "skills/agent-browser"
|
||||
"../../docker/examples/excel/Walmart_Sales.csv" = "examples/excel/Walmart_Sales.csv"
|
||||
"../../docker/examples/fin_report/pdf/2020-01-23__浙江海翔药业股份有限公司__002099__海翔药业__2019年__年度报告.pdf" = "examples/fin_report/pdf/2020-01-23__浙江海翔药业股份有限公司__002099__海翔药业__2019年__年度报告.pdf"
|
||||
|
||||
[tool.hatch.build.targets.wheel.force-include]
|
||||
"skills/csv-data-analysis" = "dbgpt_app/_builtin_skills/csv-data-analysis"
|
||||
"skills/skill-creator" = "dbgpt_app/_builtin_skills/skill-creator"
|
||||
"skills/financial-report-analyzer" = "dbgpt_app/_builtin_skills/financial-report-analyzer"
|
||||
"skills/walmart-sales-analyzer" = "dbgpt_app/_builtin_skills/walmart-sales-analyzer"
|
||||
"skills/agent-browser" = "dbgpt_app/_builtin_skills/agent-browser"
|
||||
"examples/excel/Walmart_Sales.csv" = "dbgpt_app/_builtin_examples/excel/Walmart_Sales.csv"
|
||||
"examples/fin_report/pdf/2020-01-23__浙江海翔药业股份有限公司__002099__海翔药业__2019年__年度报告.pdf" = "dbgpt_app/_builtin_examples/fin_report/pdf/2020-01-23__浙江海翔药业股份有限公司__002099__海翔药业__2019年__年度报告.pdf"
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
"""Builtin example files bundled with the dbgpt-app wheel.
|
||||
|
||||
This package exists solely as an anchor so that code can locate the
|
||||
bundled example data files via ``os.path.dirname(__file__)``.
|
||||
The actual data files are injected by hatch ``force-include`` at build
|
||||
time and are **not** present during source-code development.
|
||||
"""
|
||||
@@ -0,0 +1,6 @@
|
||||
"""Builtin skills bundled with dbgpt-app.
|
||||
|
||||
These skills are copied into the user's skills directory (~/.dbgpt/skills/)
|
||||
on first startup via ``ensure_builtin_skills()``. Do **not** modify files
|
||||
in this directory directly -- they will be overwritten on package upgrade.
|
||||
"""
|
||||
@@ -1 +1 @@
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
|
||||
@@ -124,6 +124,12 @@ def _migration_db_storage(
|
||||
# dest_root is the parent of meta_data/ (e.g. ~/.dbgpt/workspace/pilot/)
|
||||
pilot_root = os.path.dirname(default_meta_data_path)
|
||||
_ensure_pilot_workspace(pilot_root)
|
||||
|
||||
# Provision builtin skills for pip-installed users.
|
||||
from dbgpt.configs.model_config import SKILLS_DIR
|
||||
from dbgpt_app.initialization.skills_provisioning import ensure_builtin_skills
|
||||
|
||||
ensure_builtin_skills(SKILLS_DIR)
|
||||
if not disable_alembic_upgrade:
|
||||
from dbgpt.storage.metadata.db_manager import db
|
||||
from dbgpt.util._db_migration_utils import _ddl_init_and_upgrade
|
||||
|
||||
@@ -89,10 +89,11 @@ def mount_routers(app: FastAPI):
|
||||
|
||||
|
||||
def mount_static_files(app: FastAPI, param: ApplicationConfig):
|
||||
package_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
if param.service.web.new_web_ui:
|
||||
static_file_path = os.path.join(ROOT_PATH, "src", "dbgpt_app/static/web")
|
||||
static_file_path = os.path.join(package_dir, "static", "web")
|
||||
else:
|
||||
static_file_path = os.path.join(ROOT_PATH, "src", "dbgpt_app/static/old_web")
|
||||
static_file_path = os.path.join(package_dir, "static", "old_web")
|
||||
|
||||
os.makedirs(STATIC_MESSAGE_IMG_PATH, exist_ok=True)
|
||||
app.mount(
|
||||
@@ -172,25 +173,37 @@ def initialize_app(param: ApplicationConfig, args: List[str] = None):
|
||||
|
||||
# Register default data sources
|
||||
try:
|
||||
from dbgpt.configs.model_config import ROOT_PATH
|
||||
from dbgpt.configs.model_config import PILOT_PATH, ROOT_PATH
|
||||
from dbgpt_serve.datasource.manages.connect_config_db import ConnectConfigDao
|
||||
|
||||
dao = ConnectConfigDao()
|
||||
db_name = "Walmart_Sales"
|
||||
if not dao.get_by_names(db_name):
|
||||
db_absolute_path = os.path.join(
|
||||
ROOT_PATH, "docker/examples/dashboard/Walmart_Sales.db"
|
||||
)
|
||||
dao.add_file_db(
|
||||
db_name=db_name,
|
||||
db_type="sqlite",
|
||||
db_path=db_absolute_path,
|
||||
comment="Default Walmart Sales example database",
|
||||
)
|
||||
logger.info(
|
||||
f"Successfully registered default data source: "
|
||||
f"{db_name} at {db_absolute_path}"
|
||||
candidate_paths = [
|
||||
os.path.join(PILOT_PATH, "examples", "Walmart_Sales.db"),
|
||||
os.path.join(
|
||||
ROOT_PATH, "docker", "examples", "dashboard", "Walmart_Sales.db"
|
||||
),
|
||||
]
|
||||
db_absolute_path = next(
|
||||
(p for p in candidate_paths if os.path.isfile(p)), None
|
||||
)
|
||||
if db_absolute_path is None:
|
||||
logger.info(
|
||||
f"Skipping default data source '%s': file not found in any "
|
||||
f"{db_name} at {candidate_paths}"
|
||||
)
|
||||
else:
|
||||
dao.add_file_db(
|
||||
db_name=db_name,
|
||||
db_type="sqlite",
|
||||
db_path=db_absolute_path,
|
||||
comment="Default Walmart Sales example database",
|
||||
)
|
||||
logger.info(
|
||||
f"Successfully registered default data source: "
|
||||
f"{db_name} at {db_absolute_path}"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to register default data sources: {str(e)}")
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
"""Skills provisioning module for dbgpt-app pip package users.
|
||||
|
||||
Copies builtin skill templates from the installed package to the user's
|
||||
skills directory on first startup. Existing skills are never overwritten.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ensure_builtin_skills(skills_dir: str) -> None:
|
||||
"""Idempotently seed builtin skills into *skills_dir*.
|
||||
|
||||
On first run after ``pip install dbgpt-app``, the builtin skill
|
||||
templates bundled inside the wheel (``dbgpt_app/_builtin_skills/``)
|
||||
are copied to *skills_dir*. Skills that already exist in the
|
||||
destination are **never** overwritten so that user modifications are
|
||||
preserved.
|
||||
|
||||
This function is a no-op when:
|
||||
* ``dbgpt_app._builtin_skills`` cannot be imported (e.g. running
|
||||
from a source checkout where the force-include hasn't been
|
||||
triggered).
|
||||
* The builtin skills directory inside the package is empty.
|
||||
|
||||
Args:
|
||||
skills_dir: Absolute path to the target skills directory,
|
||||
e.g. ``~/.dbgpt/skills/``.
|
||||
"""
|
||||
try:
|
||||
import dbgpt_app._builtin_skills as _bs
|
||||
|
||||
builtin_root = os.path.dirname(_bs.__file__)
|
||||
except (ImportError, AttributeError):
|
||||
logger.debug("dbgpt_app._builtin_skills not available, skipping seed.")
|
||||
return
|
||||
|
||||
if not os.path.isdir(builtin_root):
|
||||
return
|
||||
|
||||
os.makedirs(skills_dir, exist_ok=True)
|
||||
|
||||
for entry in os.listdir(builtin_root):
|
||||
# Skip Python artifacts and hidden files
|
||||
if entry.startswith(("_", ".")) or entry == "__pycache__":
|
||||
continue
|
||||
|
||||
src = os.path.join(builtin_root, entry)
|
||||
dst = os.path.join(skills_dir, entry)
|
||||
|
||||
# Never overwrite existing skills (user may have modified them)
|
||||
if os.path.exists(dst):
|
||||
logger.debug("Builtin skill already exists, skipping: %s", dst)
|
||||
continue
|
||||
|
||||
if os.path.isdir(src):
|
||||
shutil.copytree(src, dst)
|
||||
logger.info("Provisioned builtin skill: %s", entry)
|
||||
else:
|
||||
shutil.copy2(src, dst)
|
||||
logger.info("Provisioned builtin skill file: %s", entry)
|
||||
|
||||
# Ensure user/ subdirectory exists for uploaded/imported skills
|
||||
user_dir = os.path.join(skills_dir, "user")
|
||||
os.makedirs(user_dir, exist_ok=True)
|
||||
@@ -19,7 +19,7 @@ from dbgpt._private.pydantic import BaseModel as _BaseModel
|
||||
from dbgpt.agent.resource.tool.base import tool
|
||||
from dbgpt.agent.skill.manage import get_skill_manager
|
||||
from dbgpt.component import ComponentType
|
||||
from dbgpt.configs.model_config import resolve_root_path
|
||||
from dbgpt.configs.model_config import SKILLS_DIR, resolve_root_path
|
||||
from dbgpt.core import PromptTemplate
|
||||
from dbgpt.model.cluster import WorkerManagerFactory
|
||||
from dbgpt_app.openapi.api_view_model import (
|
||||
@@ -38,7 +38,7 @@ if TYPE_CHECKING:
|
||||
|
||||
REACT_AGENT_MEMORY_CACHE: Dict[str, "GptsMemory"] = {}
|
||||
|
||||
DEFAULT_SKILLS_DIR = resolve_root_path("skills") or "skills"
|
||||
DEFAULT_SKILLS_DIR = SKILLS_DIR
|
||||
AUTO_DATA_MARKER_PATTERN = re.compile(
|
||||
r"###([A-Z0-9_]+)_START###\s*(.*?)\s*###\1_END###", re.DOTALL
|
||||
)
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
"""API endpoints for bundled example files.
|
||||
|
||||
Provides a single ``POST /v1/examples/use`` endpoint that copies a bundled
|
||||
example file to the user's upload directory so it can be used in
|
||||
conversations.
|
||||
|
||||
Example files are resolved in the following order:
|
||||
|
||||
1. ``docker/examples/`` under the source-code project root (dev mode).
|
||||
2. ``dbgpt_app/_builtin_examples/`` inside the installed wheel (PyPI mode).
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Body, Depends
|
||||
|
||||
@@ -12,32 +25,78 @@ router = APIRouter()
|
||||
CFG = Config()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Map of example IDs to their file paths (relative to project root)
|
||||
# Map of example IDs to their file info.
|
||||
# - ``source_path``: path relative to source-repo root (``docker/examples/…``).
|
||||
# - ``builtin_path``: path relative to ``_builtin_examples/`` inside the wheel.
|
||||
# - ``name``: the user-visible filename.
|
||||
EXAMPLE_FILES = {
|
||||
"walmart_sales": {
|
||||
"path": "docker/examples/excel/Walmart_Sales.csv",
|
||||
"source_path": "docker/examples/excel/Walmart_Sales.csv",
|
||||
"builtin_path": "excel/Walmart_Sales.csv",
|
||||
"name": "Walmart_Sales.csv",
|
||||
},
|
||||
"csv_visual_report": {
|
||||
"path": "docker/examples/excel/Walmart_Sales.csv",
|
||||
"source_path": "docker/examples/excel/Walmart_Sales.csv",
|
||||
"builtin_path": "excel/Walmart_Sales.csv",
|
||||
"name": "Walmart_Sales.csv",
|
||||
},
|
||||
"fin_report": {
|
||||
"path": (
|
||||
"source_path": (
|
||||
"docker/examples/fin_report/pdf/"
|
||||
"2020-01-23__浙江海翔药业股份有限公司__002099__海翔药业__2019年__年度报告.pdf"
|
||||
),
|
||||
"builtin_path": (
|
||||
"fin_report/pdf/"
|
||||
"2020-01-23__浙江海翔药业股份有限公司__002099__海翔药业__2019年__年度报告.pdf"
|
||||
),
|
||||
"name": (
|
||||
"2020-01-23__浙江海翔药业股份有限公司__002099__海翔药业__2019年__年度报告.pdf"
|
||||
),
|
||||
},
|
||||
"create_sql_skill": {
|
||||
"path": "docker/examples/txt/sql_skill.txt",
|
||||
"source_path": "docker/examples/txt/sql_skill.txt",
|
||||
"builtin_path": "txt/sql_skill.txt",
|
||||
"name": "sql_skill.txt",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _resolve_example_source(example: dict) -> Optional[str]:
|
||||
"""Return the absolute path to an example file, or *None* if not found.
|
||||
|
||||
Resolution order:
|
||||
1. ``docker/examples/…`` under ``SYSTEM_APP.work_dir`` or cwd (source-code
|
||||
development mode).
|
||||
2. ``_builtin_examples/…`` inside the installed ``dbgpt_app`` package
|
||||
(PyPI install mode).
|
||||
"""
|
||||
# --- 1. Source-code / work_dir mode ---
|
||||
base_dir = os.getcwd()
|
||||
if (
|
||||
CFG.SYSTEM_APP
|
||||
and hasattr(CFG.SYSTEM_APP, "work_dir")
|
||||
and CFG.SYSTEM_APP.work_dir
|
||||
):
|
||||
base_dir = CFG.SYSTEM_APP.work_dir
|
||||
|
||||
candidate = os.path.join(base_dir, example["source_path"])
|
||||
if os.path.isfile(candidate):
|
||||
return candidate
|
||||
|
||||
# --- 2. Builtin examples bundled in the wheel ---
|
||||
try:
|
||||
import dbgpt_app._builtin_examples as _be
|
||||
|
||||
builtin_root = os.path.dirname(_be.__file__)
|
||||
candidate = os.path.join(builtin_root, example["builtin_path"])
|
||||
if os.path.isfile(candidate):
|
||||
return candidate
|
||||
except (ImportError, AttributeError):
|
||||
pass
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@router.post("/v1/examples/use", response_model=Result[str])
|
||||
async def use_example_file(
|
||||
example_id: str = Body(..., embed=True),
|
||||
@@ -51,7 +110,11 @@ async def use_example_file(
|
||||
example = EXAMPLE_FILES[example_id]
|
||||
user_id = user_token.user_id or "default"
|
||||
|
||||
# Determine base directory
|
||||
source_path = _resolve_example_source(example)
|
||||
if source_path is None:
|
||||
return Result.failed(msg=f"Example file not found: {example['name']}")
|
||||
|
||||
# Determine upload base directory (same convention as python_upload_api)
|
||||
base_dir = os.getcwd()
|
||||
if (
|
||||
CFG.SYSTEM_APP
|
||||
@@ -60,28 +123,6 @@ async def use_example_file(
|
||||
):
|
||||
base_dir = CFG.SYSTEM_APP.work_dir
|
||||
|
||||
# Source file - try base_dir first, then project root
|
||||
source_path = os.path.join(base_dir, example["path"])
|
||||
if not os.path.exists(source_path):
|
||||
project_root = os.path.dirname(
|
||||
os.path.dirname(
|
||||
os.path.dirname(
|
||||
os.path.dirname(
|
||||
os.path.dirname(
|
||||
os.path.dirname(
|
||||
os.path.dirname(os.path.abspath(__file__))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
source_path = os.path.join(project_root, example["path"])
|
||||
|
||||
if not os.path.exists(source_path):
|
||||
return Result.failed(msg=f"Example file not found: {example['name']}")
|
||||
|
||||
# Target directory - same as python_upload_api
|
||||
upload_dir = os.path.join(base_dir, "python_uploads", user_id)
|
||||
os.makedirs(upload_dir, exist_ok=True)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "dbgpt-client"
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
description = "Add your description here"
|
||||
authors = [
|
||||
{ name = "csunny", email = "cfqcsunny@gmail.com" }
|
||||
|
||||
@@ -1 +1 @@
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "dbgpt"
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
description = """DB-GPT is an experimental open-source project that uses localized GPT \
|
||||
large models to interact with your data and environment. With this solution, you can be\
|
||||
assured that there is no risk of data leakage, and your data is 100% private and secure.\
|
||||
|
||||
@@ -1 +1 @@
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
|
||||
@@ -523,14 +523,9 @@ class SkillManager(BaseComponent):
|
||||
if hasattr(metadata, "path"):
|
||||
return metadata.path
|
||||
|
||||
skills_dir = os.environ.get("DBGPT_SKILLS_DIR")
|
||||
if not skills_dir:
|
||||
from dbgpt.configs.model_config import resolve_root_path
|
||||
from dbgpt.configs.model_config import SKILLS_DIR
|
||||
|
||||
skills_dir = resolve_root_path("skills")
|
||||
|
||||
if not skills_dir:
|
||||
skills_dir = "skills"
|
||||
skills_dir = SKILLS_DIR
|
||||
|
||||
# Search candidate subdirectories: direct, user/, claude/, project/, etc.
|
||||
subdirs = ["", "user", "claude", "project"]
|
||||
|
||||
@@ -375,3 +375,29 @@ KNOWLEDGE_CACHE_ROOT_PATH = os.path.join(
|
||||
KNOWLEDGE_UPLOAD_ROOT_PATH, "_knowledge_cache_"
|
||||
)
|
||||
BENCHMARK_DATA_ROOT_PATH = os.path.join(PILOT_PATH, "benchmark_meta_data")
|
||||
|
||||
|
||||
def _detect_skills_dir() -> str:
|
||||
"""Detect the skills directory path.
|
||||
|
||||
Priority:
|
||||
1. ``DBGPT_SKILLS_DIR`` environment variable (highest)
|
||||
2. ``{ROOT_PATH}/skills`` if it exists (source checkout)
|
||||
3. ``~/.dbgpt/skills`` (pip install mode)
|
||||
|
||||
Returns:
|
||||
str: Absolute path to the skills directory.
|
||||
"""
|
||||
env_dir = os.environ.get("DBGPT_SKILLS_DIR")
|
||||
if env_dir:
|
||||
return env_dir
|
||||
|
||||
source_dir = os.path.join(ROOT_PATH, "skills")
|
||||
if os.path.isdir(source_dir):
|
||||
return source_dir
|
||||
|
||||
home = os.environ.get("DBGPT_HOME", os.path.expanduser("~/.dbgpt"))
|
||||
return os.path.join(home, "skills")
|
||||
|
||||
|
||||
SKILLS_DIR = _detect_skills_dir()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "dbgpt-ext"
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
description = "Add your description here"
|
||||
authors = [
|
||||
{ name = "csunny", email = "cfqcsunny@gmail.com" }
|
||||
|
||||
@@ -1 +1 @@
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "dbgpt-sandbox"
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
description = "A secure sandbox execution environment for DB-GPT Agent"
|
||||
authors = [
|
||||
{ name = "csunny", email = "cfqcsunny@gmail.com" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "dbgpt-serve"
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
description = "Add your description here"
|
||||
authors = [
|
||||
{ name = "csunny", email = "cfqcsunny@gmail.com" }
|
||||
|
||||
@@ -1 +1 @@
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
|
||||
BIN
pilot/examples/Walmart_Sales.db
Normal file
BIN
pilot/examples/Walmart_Sales.db
Normal file
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "dbgpt-mono"
|
||||
version = "0.8.0rc1"
|
||||
version = "0.8.0rc5"
|
||||
description = """DB-GPT is an experimental open-source project that uses localized GPT \
|
||||
large models to interact with your data and environment. With this solution, you can be\
|
||||
assured that there is no risk of data leakage, and your data is 100% private and secure.\
|
||||
|
||||
Reference in New Issue
Block a user