94 lines
4.2 KiB
Python
94 lines
4.2 KiB
Python
import os
|
|
|
|
from scripts import loggorilla
|
|
from tools import instrbase
|
|
|
|
schema_rp_instruction_use = {
|
|
"type": "function",
|
|
"function": {
|
|
"name": "rp_instruction_use",
|
|
"description": "CRITICAL ROLEPLAY VALIDATION TOOL: Use this tool ONLY when the character is interacting with a specific object, outfit, or location mentioned in the instruction files. This tool MUST be called to fetch the authoritative description before describing the item to ensure narrative consistency and prevent hallucination. DO NOT use if the character is not interacting with a specific listed item.",
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"directory": {
|
|
"type": "string",
|
|
"description": "The subdirectory within the 'instruction' folder (e.g., 'rp/item', 'rp/armor', 'rp/world', 'gameplay')."
|
|
},
|
|
"filename": {
|
|
"type": "string",
|
|
"description": "The name of the instruction file to read (e.g., 'rules.md', 'iron-sword.md')."
|
|
}
|
|
},
|
|
"required": ["directory", "filename"]
|
|
}
|
|
}
|
|
}
|
|
|
|
def rp_instruction_use(directory, filename):
|
|
loggorilla.fyinf("tools.smart_rp", f"Calling rp_instruction_use with directory='{directory}', filename='{filename}'")
|
|
current_file_dir = os.path.dirname(os.path.abspath(__file__))
|
|
project_root = os.path.dirname(current_file_dir)
|
|
base_dir = os.path.join(project_root, "instruction")
|
|
safe_directory = directory.lstrip('/').replace('..', '')
|
|
safe_filename = os.path.basename(filename)
|
|
file_path = os.path.join(base_dir, safe_directory, safe_filename)
|
|
|
|
if not os.path.exists(file_path):
|
|
res = f"Error: Roleplay instruction file not found at {file_path}"
|
|
loggorilla.fyinf("tools.smart_rp", f"File not found: {res}")
|
|
return res
|
|
|
|
try:
|
|
with open(file_path, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
loggorilla.fyinf("tools.smart_rp", f"Successfully read RP file. Content snippet: {content[:100]}...")
|
|
return content
|
|
except Exception as e:
|
|
res = f"Error reading RP file: {str(e)}"
|
|
loggorilla.fyinf("tools.smart_rp", f"Exception occurred: {res}")
|
|
return res
|
|
|
|
|
|
# ─── rp_instruction_char_use (private / per-character variant) ─────────────────
|
|
|
|
schema_rp_instruction_char_use = {
|
|
"type": "function",
|
|
"function": {
|
|
"name": "rp_instruction_char_use",
|
|
"description": (
|
|
"CRITICAL ROLEPLAY VALIDATION TOOL (character-scoped): Use this tool ONLY when the "
|
|
"character is interacting with a specific object, outfit, or location defined in this "
|
|
"character's PRIVATE roleplay instruction files, located at "
|
|
"agent/characters/<character>/instruction. This is the character-scoped variant of "
|
|
"rp_instruction_use — it must be called to fetch the authoritative description before "
|
|
"describing the item, to ensure narrative consistency and prevent hallucination. "
|
|
"DO NOT use if the character is not interacting with a specific listed item."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"directory": {
|
|
"type": "string",
|
|
"description": (
|
|
"The subdirectory within the character's own 'instruction' folder "
|
|
"(e.g., 'rp/item', 'rp/armor', 'rp/world', 'gameplay'). Pass an empty "
|
|
"string to read directly from the root of that folder."
|
|
)
|
|
},
|
|
"filename": {
|
|
"type": "string",
|
|
"description": "The name of the instruction file to read (e.g., 'rules.md', 'iron-sword.md')."
|
|
}
|
|
},
|
|
"required": ["directory", "filename"]
|
|
}
|
|
}
|
|
}
|
|
|
|
def rp_instruction_char_use(directory, filename):
|
|
return instrbase.read_instruction_file(
|
|
"tools.smart_rp", loggorilla, directory, filename,
|
|
label="roleplay instruction", caller="rp_instruction_char_use"
|
|
)
|