deerflow-code/offline-backend-20260512/backend/packages/harness/deerflow/config/skills_config.py
2026-09-07 18:24:55 +08:00

89 lines
3.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
from pathlib import Path
from pydantic import BaseModel, Field
from deerflow.config.runtime_paths import project_root, resolve_path
DEFAULT_ES_QUERY_ROUTING_PROMPT = """当用户的问题需要基于 Elasticsearch 查询语句(Query DSL)灵活构造、调整或执行查询时,必须优先使用 `es_query` 技能。
典型场景包括:根据用户条件动态组合 bool/must/filter/should、范围、聚合、排序或分页等 ES 查询;或者用户直接提供、要求修改 ES 语句并据此查询数据。
执行前先读取 `es_query` 技能的 SKILL.md,严格按照技能中的流程和参数调用;不要用通用搜索替代,也不要凭记忆臆测查询结果。
仅当问题确实需要 ES 数据查询时使用;纯概念解释、普通代码说明或与 ES 无关的问题不要调用。"""
class EsQueryRoutingConfig(BaseModel):
"""Prompt steering that routes flexible Elasticsearch queries to ``es_query``."""
enabled: bool = Field(
default=False,
description="Inject the es_query routing prompt into the agent system prompt.",
)
prompt: str = Field(
default=DEFAULT_ES_QUERY_ROUTING_PROMPT,
description="Editable system-prompt instructions for deciding when and how to use es_query.",
)
class SecurityScanConfig(BaseModel):
"""Toggle for the LLM-based skill security scanner."""
enabled: bool = Field(
default=True,
description=(
"When false, skip the LLM security scan applied to skill installs, "
"custom-skill edits, and rollbacks. The scan is then treated as 'allow'."
),
)
class SkillsConfig(BaseModel):
"""Configuration for skills system"""
use: str = Field(
default="deerflow.skills.storage.local_skill_storage:LocalSkillStorage",
description="Class path of the SkillStorage implementation.",
)
path: str | None = Field(
default=None,
description="Path to skills directory. If not specified, defaults to skills under the caller project root.",
)
container_path: str = Field(
default="/mnt/skills",
description="Path where skills are mounted in the sandbox container",
)
security_scan: SecurityScanConfig = Field(
default_factory=SecurityScanConfig,
description="LLM security-scan toggle for skill content.",
)
es_query_routing: EsQueryRoutingConfig = Field(
default_factory=EsQueryRoutingConfig,
description="Optional configurable routing prompt for the es_query skill.",
)
def get_skills_path(self) -> Path:
"""
Get the resolved skills directory path.
Returns:
Path to the skills directory
"""
if self.path:
# Use configured path (can be absolute or relative to project root)
return resolve_path(self.path)
if env_path := os.getenv("DEER_FLOW_SKILLS_PATH"):
return resolve_path(env_path)
return project_root() / "skills"
def get_skill_container_path(self, skill_name: str, category: str = "public") -> str:
"""
Get the full container path for a specific skill.
Args:
skill_name: Name of the skill (directory name)
category: Category of the skill (public or custom)
Returns:
Full path to the skill in the container
"""
return f"{self.container_path}/{category}/{skill_name}"