pzp5700's picture
HF Space (clean): Paper2PPT + PPT Polish
d82bbe4
Raw
History Blame Contribute Delete
7.18 kB
import click
from pathlib import Path
from datetime import datetime
from jinja2 import Template
from typing import Optional
from dataflow_agent.logger import get_logger
log = get_logger(__name__)
TEMPLATE_DIR = Path(__file__).parent / "templates"
# ---------- util ----------
def to_snake(s: str) -> str:
import re
s = re.sub(r'[\- ]+', '_', s).strip('_')
parts = re.split(r'[_]', s)
return '_'.join(p.lower() for p in parts if p)
def to_camel(s: str) -> str:
return ''.join(p.capitalize() for p in to_snake(s).split('_'))
# ---------- CLI ----------
@click.group()
def cli():
"""DataFlow-Agent command line."""
pass
@cli.command("create")
@click.option("--wf_name", help="要创建的 workflow 名称")
@click.option("--agent_name", help="要创建的 agent 名称")
@click.option("--gradio_name", help="要创建的 gradio page 名称")
@click.option("--prompt_name", help="要创建的 prompt template 名称")
@click.option("--agent_as_tool_name", help="要创建的 agent-as-tool 名称")
@click.option("--state_name", help="要创建的 state 名称")
def create_artifact(wf_name: Optional[str] = None,
agent_name: Optional[str] = None,
gradio_name: Optional[str] = None,
prompt_name: Optional[str] = None,
agent_as_tool_name: Optional[str] = None,
state_name: Optional[str] = None):
"""
dfa create --wf_name xxx
dfa create --agent_name yyy
dfa create --gradio_name zzz
dfa create --prompt_name zzz
dfa create --agent_as_tool_name aaa
dfa create --state_name bbb
"""
opts = [bool(wf_name), bool(agent_name), bool(gradio_name), bool(prompt_name), bool(agent_as_tool_name), bool(state_name)]
if sum(opts) != 1:
click.echo(" --wf_name / --agent_name / --gradio_name / --prompt_name / --agent_as_tool_name / --state_name 必须且只能选一个", err=True)
raise SystemExit(1)
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# ------------------------------------------------------------------
# 1. Workflow
# ------------------------------------------------------------------
if wf_name:
wf_name_snake = to_snake(wf_name)
# 1.1 workflow 源码
wf_dest = Path(__file__).parent / "workflow" / f"wf_{wf_name_snake}.py"
wf_tpl_path = TEMPLATE_DIR / "workflow.py.jinja"
wf_context = dict(
wf_name=wf_name,
wf_name_snake=wf_name_snake,
entry="step1",
timestamp=timestamp,
)
_generate_file(wf_dest, wf_tpl_path, wf_context, "workflow")
# 1.2 对应测试
project_root = Path(__file__).parent.parent
test_dest = project_root / "tests" / f"test_{wf_name_snake}.py"
test_tpl = TEMPLATE_DIR / "test_workflow.py.jinja"
test_ctx = dict(
wf_name=wf_name,
wf_name_snake=wf_name_snake,
timestamp=timestamp,
)
_generate_file(test_dest, test_tpl, test_ctx, "test")
# ------------------------------------------------------------------
# 2. Agent
# ------------------------------------------------------------------
elif agent_name:
agent_snake = to_snake(agent_name)
dest = Path(__file__).parent / "agentroles" / "common_agents" / f"{agent_snake}_agent.py"
tpl_path = TEMPLATE_DIR / "agent.py.jinja"
ctx = dict(
agent_name=agent_name,
agent_name_snake=agent_snake,
agent_name_camel=to_camel(agent_name),
timestamp=timestamp,
)
_generate_file(dest, tpl_path, ctx, "agent")
# ------------------------------------------------------------------
# 3. Gradio Page
# ------------------------------------------------------------------
elif gradio_name:
page_snake = to_snake(gradio_name)
project_root = Path(__file__).parent.parent
dest = project_root / "gradio_app" / "pages" / f"page_{page_snake}.py"
tpl_path = TEMPLATE_DIR / "gradio_page.py.jinja"
ctx = dict(
page_name=gradio_name,
page_name_snake=page_snake,
timestamp=timestamp,
)
_generate_file(dest, tpl_path, ctx, "gradio page")
# ------------------------------------------------------------------
# 4. Prompt Template
# ------------------------------------------------------------------
elif prompt_name:
prompt_snake = to_snake(prompt_name)
dest = Path(__file__).parent / "promptstemplates" / "resources" / f"pt_{prompt_snake}_repo.py"
tpl_path = TEMPLATE_DIR / "prompt_repo.py.jinja"
ctx = dict(
prompt_name=prompt_name,
prompt_name_snake=prompt_snake,
prompt_name_camel=to_camel(prompt_name),
timestamp=timestamp,
)
_generate_file(dest, tpl_path, ctx, "prompt template")
# ------------------------------------------------------------------
# 5. Agent-as-Tool
# ------------------------------------------------------------------
elif agent_as_tool_name:
agent_snake = to_snake(agent_as_tool_name)
dest = Path(__file__).parent / "agentroles" / "common_agents" / f"{agent_snake}_agent.py"
tpl_path = TEMPLATE_DIR / "agent_as_tool_name.py.jinja"
ctx = dict(
agent_name=agent_as_tool_name,
agent_name_snake=agent_snake,
agent_name_camel=to_camel(agent_as_tool_name),
timestamp=timestamp,
)
_generate_file(dest, tpl_path, ctx, "agent-as-tool")
# ------------------------------------------------------------------
# 6. State
# ------------------------------------------------------------------
else:
state_snake = to_snake(state_name)
dest = Path(__file__).parent / "states" / f"{state_snake}_state.py"
tpl_path = TEMPLATE_DIR / "state_name.py.jinja"
ctx = dict(
state_name=state_name,
state_name_snake=state_snake,
state_name_camel=to_camel(state_name),
timestamp=timestamp,
)
_generate_file(dest, tpl_path, ctx, "state")
# ---------- helper ----------
def _generate_file(dest: Path, tpl_path: Path, context: dict, file_type: str):
"""
通用文件生成函数
"""
dest.parent.mkdir(parents=True, exist_ok=True)
if dest.exists():
# click.echo(f" {dest} 已存在,跳过生成")
log.error(f" {dest} 已存在,跳过生成")
return
if not tpl_path.exists():
log.error(f" 模板不存在: {tpl_path}", err=True)
raise SystemExit(1)
rendered = Template(tpl_path.read_text(encoding="utf-8")).render(**context)
dest.write_text(rendered, encoding="utf-8")
try:
rel_path = dest.relative_to(Path.cwd())
except ValueError:
rel_path = dest
log.critical(f" 已生成 {file_type}: {rel_path}")
if __name__ == "__main__":
cli()