mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-17 15:53:31 +08:00
初始化:独立 oclaw 仓库首提交
- 在 oclaw/ 下重新初始化 Git 仓库 - 补齐子仓库 .gitignore,避免提交本地运行态数据(_local、node_modules、logs 等) - 提交当前工程代码与配置 Made-with: Cursor
This commit is contained in:
commit
ba3836f00f
579 changed files with 83112 additions and 0 deletions
97
prompts/loader.py
Normal file
97
prompts/loader.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from oclaw.platform.config.paths import PROJECT_ROOT
|
||||
from oclaw.prompts.frontmatter import parse_markdown_document
|
||||
|
||||
_VAR_RE = re.compile(r"\{\{\s*([a-zA-Z0-9_]+)\s*\}\}")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PromptDoc:
|
||||
frontmatter: dict[str, Any]
|
||||
body: str
|
||||
|
||||
|
||||
def _prompts_root() -> Path:
|
||||
return (PROJECT_ROOT / "oclaw" / "prompts").resolve()
|
||||
|
||||
|
||||
def _openclaw_prompts_root() -> Path:
|
||||
return (PROJECT_ROOT / "oclaw" / "prompts_openclaw").resolve()
|
||||
|
||||
|
||||
@lru_cache(maxsize=512)
|
||||
def load_prompt_doc(prompt_path: str) -> PromptDoc:
|
||||
p = (_prompts_root() / str(prompt_path)).resolve()
|
||||
if not p.exists():
|
||||
raise FileNotFoundError(f"prompt not found: {prompt_path}")
|
||||
raw = p.read_text(encoding="utf-8")
|
||||
fm, body = parse_markdown_document(raw, source=f"prompt:{prompt_path}")
|
||||
return PromptDoc(frontmatter=fm, body=body)
|
||||
|
||||
|
||||
@lru_cache(maxsize=512)
|
||||
def load_openclaw_prompt_doc(prompt_path: str) -> PromptDoc:
|
||||
p = (_openclaw_prompts_root() / str(prompt_path)).resolve()
|
||||
if not p.exists():
|
||||
raise FileNotFoundError(f"openclaw prompt not found: {prompt_path}")
|
||||
raw = p.read_text(encoding="utf-8")
|
||||
fm, body = parse_markdown_document(raw, source=f"openclaw_prompt:{prompt_path}")
|
||||
return PromptDoc(frontmatter=fm, body=body)
|
||||
|
||||
|
||||
def render_prompt_for_lang(stem: str, lang: str, *, variables: dict[str, Any] | None = None, strict: bool = True) -> str:
|
||||
suf = "en" if (lang or "zh").strip().lower().startswith("en") else "zh"
|
||||
return render_prompt(f"{stem}.{suf}.md", variables=variables, strict=strict)
|
||||
|
||||
|
||||
def render_prompt(prompt_path: str, *, variables: dict[str, Any] | None = None, strict: bool = True) -> str:
|
||||
doc = load_prompt_doc(prompt_path)
|
||||
vars_in = dict(variables or {})
|
||||
missing: set[str] = set()
|
||||
|
||||
def _repl(m: re.Match[str]) -> str:
|
||||
key = str(m.group(1) or "")
|
||||
if key in vars_in:
|
||||
return str(vars_in.get(key) or "")
|
||||
missing.add(key)
|
||||
return ""
|
||||
|
||||
out = _VAR_RE.sub(_repl, doc.body)
|
||||
if strict and missing:
|
||||
raise ValueError(f"missing prompt variables for {prompt_path}: {', '.join(sorted(missing))}")
|
||||
return out.strip()
|
||||
|
||||
|
||||
def render_openclaw_prompt(prompt_path: str, *, variables: dict[str, Any] | None = None, strict: bool = True) -> str:
|
||||
doc = load_openclaw_prompt_doc(prompt_path)
|
||||
vars_in = dict(variables or {})
|
||||
missing: set[str] = set()
|
||||
|
||||
def _repl(m: re.Match[str]) -> str:
|
||||
key = str(m.group(1) or "")
|
||||
if key in vars_in:
|
||||
return str(vars_in.get(key) or "")
|
||||
missing.add(key)
|
||||
return ""
|
||||
|
||||
out = _VAR_RE.sub(_repl, doc.body)
|
||||
if strict and missing:
|
||||
raise ValueError(f"missing openclaw prompt variables for {prompt_path}: {', '.join(sorted(missing))}")
|
||||
return out.strip()
|
||||
|
||||
|
||||
__all__ = [
|
||||
"PromptDoc",
|
||||
"load_prompt_doc",
|
||||
"load_openclaw_prompt_doc",
|
||||
"render_prompt",
|
||||
"render_prompt_for_lang",
|
||||
"render_openclaw_prompt",
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue