22-tool architecture: log.query, user.ask, journal system deployed
New tools implemented and deployed to dev gateway: - log.query: focused event queries (chat/deaths/joins/actions), replaces 200-line dump - user.ask: risk-scaled clarifying questions, async with tellraw - journal.read/write: per-player files, cross-mode (God+Sudo share) All wired into langgraph_gateway.py _execute_tool and model-driven tool loop. Tool schemas updated (22 total). Deployed to CT 644 dev server. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
"""
|
||||
User Ask — clarifying questions sent to the player in-game.
|
||||
|
||||
The model sends a question via tellraw and the gateway stores the pending
|
||||
question state. The player's next chat message gets routed back as the
|
||||
tool result.
|
||||
|
||||
Risk-scaled: model should exhaust journal/state/log queries before asking.
|
||||
Low risk = just act creatively. High risk = ask first.
|
||||
|
||||
Implementation:
|
||||
1. Model emits: <tool_call>{"name": "user.ask", "arguments": {"question": "..."}}</tool_call>
|
||||
2. Gateway sends tellraw to the player
|
||||
3. Gateway stores pending_question in session state
|
||||
4. Player's next chat message becomes the tool result
|
||||
5. Model continues with the answer
|
||||
|
||||
For training: simulate the ask/answer flow with synthetic responses.
|
||||
For production: gateway handles the async wait.
|
||||
|
||||
Usage:
|
||||
from agent.tools.user_ask import handle_user_ask, format_ask_tellraw
|
||||
"""
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
|
||||
|
||||
def format_ask_tellraw(player: str, question: str, prefix: str = "[MORTDECAI]") -> str:
|
||||
"""Format a clarifying question as a tellraw command."""
|
||||
safe_q = question.replace('"', '\\"').replace("\\", "\\\\")
|
||||
return (
|
||||
f'tellraw {player} ['
|
||||
f'{{"text":"{prefix} ","color":"gold","bold":true}},'
|
||||
f'{{"text":"{safe_q}","color":"yellow","italic":true}}'
|
||||
f']'
|
||||
)
|
||||
|
||||
|
||||
def handle_user_ask(config: dict, arguments: dict, rcon_fn=None) -> Dict[str, Any]:
|
||||
"""
|
||||
Send a clarifying question to the player.
|
||||
|
||||
In production: sends tellraw and returns a pending state.
|
||||
The gateway is responsible for waiting for the player's response
|
||||
and feeding it back as the tool result.
|
||||
|
||||
In training: the response is simulated in the training data.
|
||||
|
||||
Args:
|
||||
config: server config
|
||||
arguments: {"player": str, "question": str}
|
||||
rcon_fn: function to execute RCON commands
|
||||
|
||||
Returns:
|
||||
{"ok": True, "status": "pending", "question": question}
|
||||
In production, the gateway replaces this with the actual player response.
|
||||
"""
|
||||
player = arguments.get("player", "")
|
||||
question = arguments.get("question", "")
|
||||
|
||||
if not player or not question:
|
||||
return {"ok": False, "error": "player and question required"}
|
||||
|
||||
# Send the question in-game
|
||||
if rcon_fn:
|
||||
prefix = config.get("god_chat_prefix", "[MORTDECAI]")
|
||||
cmd = format_ask_tellraw(player, question, prefix)
|
||||
try:
|
||||
rcon_fn(cmd)
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": f"Failed to send question: {e}"}
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"status": "pending",
|
||||
"player": player,
|
||||
"question": question,
|
||||
}
|
||||
Reference in New Issue
Block a user