Add user_template to wrap user messages with sender context (name, id, username)
Configure via ai.prompt.user_template in config.json using {text}, {full_name},
{user_id}, {first_name}, {last_name}, {username} placeholders. Applied to both
history user messages and the current prompt. No-op when unset.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -289,6 +289,27 @@ class AIService:
|
|||||||
]
|
]
|
||||||
).strip()
|
).strip()
|
||||||
|
|
||||||
|
def _render_user_message(self, text: str, user: Any) -> str:
|
||||||
|
template = self.config.prompt.user_template
|
||||||
|
if not template or not text:
|
||||||
|
return text
|
||||||
|
first_name = str(getattr(user, "first_name", "") or "")
|
||||||
|
last_name = str(getattr(user, "last_name", "") or "")
|
||||||
|
username = str(getattr(user, "username", "") or "")
|
||||||
|
user_id = str(getattr(user, "id", "") or "")
|
||||||
|
full_name = f"{first_name} {last_name}".strip() or username or user_id
|
||||||
|
try:
|
||||||
|
return template.format_map({
|
||||||
|
"text": text,
|
||||||
|
"user_id": user_id,
|
||||||
|
"first_name": first_name,
|
||||||
|
"last_name": last_name,
|
||||||
|
"username": username,
|
||||||
|
"full_name": full_name,
|
||||||
|
})
|
||||||
|
except (KeyError, ValueError):
|
||||||
|
return text
|
||||||
|
|
||||||
async def build_messages(
|
async def build_messages(
|
||||||
self,
|
self,
|
||||||
ctx: "CommandContext",
|
ctx: "CommandContext",
|
||||||
@@ -303,8 +324,13 @@ class AIService:
|
|||||||
for item in history:
|
for item in history:
|
||||||
if not item.text:
|
if not item.text:
|
||||||
continue
|
continue
|
||||||
messages.append({"role": item.role, "content": item.text})
|
if item.role == "user":
|
||||||
messages.append({"role": "user", "content": prompt})
|
sender = getattr(item.message, "from_user", None)
|
||||||
|
content = self._render_user_message(item.text, sender)
|
||||||
|
else:
|
||||||
|
content = item.text
|
||||||
|
messages.append({"role": item.role, "content": content})
|
||||||
|
messages.append({"role": "user", "content": self._render_user_message(prompt, ctx.actor)})
|
||||||
return messages
|
return messages
|
||||||
|
|
||||||
async def _fetch_mcp_tool_schemas(self) -> list[dict]:
|
async def _fetch_mcp_tool_schemas(self) -> list[dict]:
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class AIPromptConfig:
|
|||||||
root: Path
|
root: Path
|
||||||
system_file: str = "system.md"
|
system_file: str = "system.md"
|
||||||
parts_dir: str = "parts"
|
parts_dir: str = "parts"
|
||||||
|
user_template: str | None = None
|
||||||
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
@@ -234,10 +235,13 @@ def _parse_ai_config(raw_ai: Any, *, root: Path) -> AIConfig | None:
|
|||||||
prompt_root = Path(str(prompt_raw.get("root", "prompts/ai"))).expanduser()
|
prompt_root = Path(str(prompt_raw.get("root", "prompts/ai"))).expanduser()
|
||||||
if not prompt_root.is_absolute():
|
if not prompt_root.is_absolute():
|
||||||
prompt_root = (root / prompt_root).resolve()
|
prompt_root = (root / prompt_root).resolve()
|
||||||
|
raw_user_template = prompt_raw.get("user_template")
|
||||||
|
user_template = str(raw_user_template).strip() if raw_user_template else None
|
||||||
prompt = AIPromptConfig(
|
prompt = AIPromptConfig(
|
||||||
root=prompt_root,
|
root=prompt_root,
|
||||||
system_file=str(prompt_raw.get("system_file", "system.md")),
|
system_file=str(prompt_raw.get("system_file", "system.md")),
|
||||||
parts_dir=str(prompt_raw.get("parts_dir", "parts")),
|
parts_dir=str(prompt_raw.get("parts_dir", "parts")),
|
||||||
|
user_template=user_template or None,
|
||||||
)
|
)
|
||||||
|
|
||||||
default_model = str(raw_ai.get("default_model", "")).strip()
|
default_model = str(raw_ai.get("default_model", "")).strip()
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
"prompt": {
|
"prompt": {
|
||||||
"root": "prompts/ai",
|
"root": "prompts/ai",
|
||||||
"system_file": "system.md",
|
"system_file": "system.md",
|
||||||
"parts_dir": "parts"
|
"parts_dir": "parts",
|
||||||
|
"user_template": "[{full_name} · id:{user_id}]\n{text}"
|
||||||
},
|
},
|
||||||
"image_understand": {
|
"image_understand": {
|
||||||
"api_key": "your_minimax_token_plan_key_here",
|
"api_key": "your_minimax_token_plan_key_here",
|
||||||
|
|||||||
Reference in New Issue
Block a user