-
Notifications
You must be signed in to change notification settings - Fork 0
3.15 Implementing Chat Mode
The goal of this task is to make the ModSmith assistant focus on "clarifying the user's mod requirements" instead of answering technical questions. The assistant should act like a patient product manager, using questions to turn vague ideas into clear descriptions, and ultimately guide the user to switch to Execute mode to generate the mod. The answers should be conversational, non-technical, and capable of steering the conversation back to requirements when the user goes off-topic.
After completing this task, users can use the CLI to have a requirement clarification dialogue with ModSmith:
modsmith chat "I want to make a new food"
modsmith chat # Enter interactive dialogue- Completed Task 1:
get_client()inmodsmith/llm/client.pyis available, and.envis configured. - Completed Task 11:
modsmith/cli.pyalready hasversionandgeneratecommands. -
richis installed (already declared inpyproject.toml).
Old positioning: Fabric mod development mentor (answers technical questions) New positioning: Mod requirements consultant (helps you articulate your idea)
| Dimension | Old design | New design |
|---|---|---|
| Role | Technical mentor | Requirements consultant |
| Primary goal | Explain concepts | Clarify requirements |
| Answer style | Technical, instructional | Conversational, everyday language |
| For technical questions | Detailed answers | Brief response + steer back to requirements |
| For non-requirement input | Direct answer | Gently steer the topic back to requirements |
| Final output | An explanation | An executable mod description |
Core principles:
- Requirements first: All dialogue revolves around "what do you want to make?"
- De-technicalize: Unless the user asks for technical details, avoid jargon. Say "heals when eaten," not "applies Regeneration status effect."
- Proactive guidance: When the user says "I have an idea," ask for key information; when the user goes off-topic, gently steer back.
- Structured clarification: Use a fixed set of dimensions to ask questions, avoiding rambling.
- Clear closure: When the requirements are clear enough, summarize them and prompt the user to switch to Execute.
A good mod requirement usually needs to clarify the following dimensions. The assistant should ask about them one by one as needed, not all at once:
| Dimension | Key question | Example |
|---|---|---|
| Item type | Is it an item, food, or tool? | "Is this more like a regular item, or something edible or usable?" |
| Name | What is it called? English/Chinese name? | "What do you want to call it?" |
| Purpose | What is it used for? | "Is it for eating, chopping things, or selling?" |
| Effect/attribute | What happens when it is used? | "Does eating it heal you? Or make you faster?" |
| Value | How strong is the effect? | "How much does it heal? For one second or one minute?" |
| Appearance | What should it look like? | "More red or more blue?" |
| How to obtain | How does the player get it? | "Crafted, dropped, or only from creative mode?" |
Dialogue strategies:
- Ask about 1–2 dimensions at a time, don't chain questions, or the user will feel pressured.
- Dynamically decide the next question based on the user's answer. For example, if the user says "heals when eaten," the next question should be "how much does it heal?"
- Allow the user to skip: if the user says "whatever," use reasonable defaults and don't press.
This module provides:
-
_build_chat_system_prompt() -> str: builds the Chat mode System Prompt. -
chat_response(user_input: str, history: list[dict] | None = None) -> str: single-turn dialogue, returns the response text.
Write the following complete code:
"""Chat mode: requirement clarification, no code generation."""
from modsmith.config import MINECRAFT_VERSION
from modsmith.llm.client import get_client, DEFAULT_MODEL
def _build_chat_system_prompt() -> str:
"""Build the Chat mode System Prompt.
Unlike Execute mode, this does not include the blueprint Schema and does not force JSON output.
Instead, it acts as a patient requirements consultant, helping the user turn vague ideas into a clear mod description.
"""
return f"""You are ModSmith's mod requirements consultant.
Your only goal: help the user turn a vague idea like "I want to make a XXX" into a clear, executable mod description. You are not responsible for writing code or answering complex technical questions—that is the job of Execute mode.
## How you work
1. **Understand first**: When the user says what they want to make, restate it in your own words to confirm you understood correctly.
2. **Clarify next**: Ask about key information as needed, but only 1–2 questions at a time. Do not chain questions.
3. **Summarize last**: When the information is sufficient, summarize the requirements in concise terms and prompt the user to generate the mod.
ModSmith currently **can only generate the following three types of items**:
- Basic item (basic): an item you can hold and stack, with no special function
- Food (food): edible, restores hunger and saturation, can apply status effects
- Tool (tool): can mine blocks and chop things, has durability, mining speed, and attack damage
ModSmith **cannot generate**:
- Blocks, plantable crops, entities, mobs, armor, potions, enchantments, etc.
## Dimensions for requirement clarification (ask as needed, not all required)
- **Item type**: regular item, food, or tool?
- **Name**: What is it called? Does it have a Chinese name?
- **Purpose**: What is it used for?
- **Effect**: What happens after eating/using it? (Only consider status effects such as healing, speed, night vision)
- **Value**: How long does the effect last, how much does it restore (if the user says "whatever," use reasonable defaults)
- **Appearance**: Roughly what color/shape should the texture be (if the user says "whatever," use "auto-generate")
**Do not** ask about how to obtain it, crafting recipes, planting steps, enchantments, durability repair, etc.—ModSmith does not generate those now.
## Answer style (very important)
- **Do not use technical jargon**: say "heals when eaten," not "applies Regeneration status effect"; say "can chop wood," not "inherits AxeItem."
- **Use everyday language**: chat like a friend; you can use "mm," "okay," "I see."
- **Keep it concise**: each reply should be 3–5 sentences. Do not write long paragraphs, do not write code blocks.
- **Do not proactively generate JSON**: if you need to show the requirements, use natural language, not blueprint format.
- **Do not write code examples**: even if asked about technical details, give only 1–2 sentences of explanation, then steer back to requirements.
## What to do when the user provides non-requirement input
The user may:
- Ask technical questions ("What is a registry?")
- Chat casually ("Nice weather today")
- Complain ("Making mods is so hard")
- Propose multiple unrelated ideas
For such input, you should:
1. **Respond briefly** (1–2 sentences), do not expand.
2. **Gently steer the topic back to requirements**, for example:
- "We can talk about that later ~ First, tell me what kind of mod you want to make?"
- "Haha, making mods does have a bit of a barrier, but ModSmith is here to make it easier. Do you have any ideas you want to implement?"
- "Sounds like you have a lot of ideas! Let's take them one at a time. What's the first one?"
## When the user's requirements are clear enough
Summarize in one paragraph, in a format like:
"Okay, here's what I understand:
Create a <type>, named <Chinese name> (<English name>).
<Effect description, e.g., heals half a heart after eating>.
Appearance: <color/shape description>.
If that's fine, you can run modsmith generate \\"<description>\\" to generate the mod,
or click the 'Generate Mod' button in the interface."
## Current environment
- Target Minecraft version: {MINECRAFT_VERSION}
- Types supported by ModSmith: basic item, food, tool
- If the user's requirement is outside these three (such as blocks, armor, mobs),
gently inform them: "That type isn't supported by ModSmith yet. Can we make a similar item first?"
## Output language
Reply in Simplified Chinese unless the user asks in another language.
"""
def chat_response(
user_input: str,
history: list[dict] | None = None,
) -> str:
"""Single-turn dialogue, returns the response text.
Args:
user_input: The user's question or description.
history: Previous dialogue history, formatted as [{"role": "user"/"assistant", "content": "..."}].
If None, this is the first turn.
Returns:
The LLM's natural language response.
Raises:
ValueError: When the API Key is not configured.
"""
client = get_client()
system_prompt = _build_chat_system_prompt()
messages = list(history) if history else []
messages.append({"role": "user", "content": user_input})
message = client.messages.create(
model=DEFAULT_MODEL,
max_tokens=1024,
system=system_prompt,
messages=messages,
)
return message.content[0].text.strip()Key changes:
- The role changes from "technical mentor" to "requirements consultant."
- Explicitly lists the 7 dimensions for requirement clarification, so the assistant knows what to ask.
- Explicitly requires de-technicalized, everyday, concise answers.
- Adds a strategy for "non-requirement input," with specific guiding phrases.
- Explicitly defines the closing format when requirements are clear, so the user knows when to switch.
- Explicitly handles out-of-scope requirements.
-
max_tokensis reduced from 2048 to 1024, because answers should be shorter.
Create at the project root:
"""Test Chat mode's requirement clarification ability."""
from modsmith.llm.chat import chat_response
TEST_INPUTS = [
# Scenario 1: Clear requirement
"I want to make an apple that heals when eaten",
# Scenario 2: Vague requirement (should ask follow-up)
"I want to make something new",
# Scenario 3: Non-requirement input (should steer back)
"Nice weather today",
# Scenario 4: Technical question (should answer briefly and steer back)
"What is Fabric's registry?",
# Scenario 5: Out-of-scope requirement
"I want to make a new mob",
]
for i, user_input in enumerate(TEST_INPUTS, 1):
print(f"\n{'='*60}")
print(f"Scenario {i}: {user_input}")
print('='*60)
answer = chat_response(user_input)
print(answer)Run:
python test_chat.pyExpected result:
| Scenario | Expected behavior |
|---|---|
| 1. Clear requirement | Briefly confirm, summarize the requirement, prompt to switch to Execute |
| 2. Vague requirement | Ask "What kind of thing? Edible, usable, or something else?" |
| 3. Non-requirement input | Brief response, then steer: "First, tell me what kind of mod you want to make?" |
| 4. Technical question | 1–2 sentence explanation, then steer: "Does what you want to make involve this?" |
| 5. Out-of-scope requirement | Gently inform, suggest making a similar item first |
If the response contains long technical explanations, code blocks, or JSON format, the System Prompt is not working; check it.
Open modsmith/cli.py and add at the end of the file:
from modsmith.llm.chat import chat_response as llm_chat_response
@app.command()
def chat(
question: str = typer.Argument(
None,
help="The question to ask or the mod to make. If not provided, enter interactive dialogue mode.",
),
) -> None:
"""Enter Chat mode and clarify your mod requirements with ModSmith."""
history: list[dict] = []
def _ask(q: str) -> None:
"""Perform one Q&A turn, update history, and print the answer."""
nonlocal history
history.append({"role": "user", "content": q})
try:
answer = llm_chat_response(q, history=history[:-1])
except Exception as e:
console.print(f"[bold red]❌ Dialogue failed:[/bold red] {e}")
history.pop()
return
history.append({"role": "assistant", "content": answer})
console.print("\n[bold cyan]ModSmith:[/bold cyan]")
console.print(answer)
console.print()
if question:
_ask(question)
return
console.print(Panel.fit(
"[bold cyan]Requirement Clarification[/bold cyan]\n"
"Tell me what you want to make, and ModSmith will help you articulate it.\n"
"Special commands: /quit to exit, /clear to clear history, /history to view history.",
title="ModSmith Chat",
))
while True:
try:
user_input = console.input("[bold green]You:[/bold green] ").strip()
except (EOFError, KeyboardInterrupt):
console.print("\n[dim]Goodbye![/dim]")
break
if not user_input:
continue
if user_input == "/quit":
console.print("[dim]Goodbye![/dim]")
break
if user_input == "/clear":
history.clear()
console.print("[dim]History cleared.[/dim]")
continue
if user_input == "/history":
if not history:
console.print("[dim](No history yet)[/dim]")
continue
for msg in history:
role = "You" if msg["role"] == "user" else "ModSmith"
console.print(f"[bold]{role}:[/bold] {msg['content']}\n")
continue
_ask(user_input)Key points:
- When
questionisNone, enter interactive dialogue; if provided, it's a single question. - History is maintained as a list, and the full history is passed to
chat_responseeach turn. - Supports three special commands:
/quit,/clear,/history.
modsmith chat "I want to make a new food"Expected output (illustrative):
Okay, a new food is a great idea! First, what would you like to call it?
Also, what effect should it have when eaten—healing, speed, or something else?
modsmith chat "Nice weather today"Expected output (illustrative):
Haha, it is a nice day ~ But let's talk about mods: is there anything you want to make?
modsmith chatExample interaction:
You: I want to make something fun
ModSmith:
Sure! "Fun" in what direction specifically—something edible, usable, or something else?
For example, a candy that makes you fly when eaten, or an axe that can chop trees?
You: A candy that makes you fly when eaten
ModSmith:
Interesting! How long should the flight effect last? A few seconds or a minute?
And what is it called? Does it have a Chinese name?
You: Call it Flying Candy, flies for 10 seconds
ModSmith:
Okay, here's what I understand: a food called "Flying Candy"
that grants 10 seconds of flight after eating.
If that's fine, you can run modsmith generate "Create a food called Flying Candy that grants 10 seconds of flight when eaten" to generate the mod.
You: /quit
Expected: The assistant acts like a product manager, gradually clarifying the idea.
| Problem | Cause | Solution |
|---|---|---|
| Answers are still technical | System Prompt not taking effect | Confirm chat.py uses the revised Prompt |
| Assistant does not ask follow-ups | User input is too clear | This is normal; only ask follow-ups when the requirement is vague |
| Assistant keeps asking endlessly | No closure judgment | Emphasize in the System Prompt: "Close immediately when information is sufficient" |
| Assistant outputs JSON | Prompt mixed up | Confirm Chat and Execute System Prompts are completely separate |
| Answers are too long |
max_tokens too large |
Already set to 1024; can lower further to 512 |
-
modsmith/llm/chat.pyis created, and the System Prompt plays the role of a requirements consultant rather than a technical mentor. - The System Prompt contains the 7 dimensions for requirement clarification.
- The System Prompt explicitly requires de-technicalized, everyday, concise answers.
- The System Prompt contains a strategy for non-requirement input, with example phrases.
- The System Prompt defines the closing format when requirements are clear.
- All 5 scenarios in
test_chat.pyproduce expected answers. -
modsmith chat "question"andmodsmith chatboth work normally. - Interactive dialogue supports
/quit,/clear, and/history.
After completing this task, ModSmith's Chat mode is no longer a "technical Q&A bot," but a "requirements consultant that helps you articulate your idea." Even users with no technical background can smoothly obtain an executable mod description through dialogue.
- Structured requirement summary: Output a formatted requirement summary at closing, convenient for filling into Execute.
-
Guide to Execute: Add a
/generatecommand in the CLI to trigger Execute directly based on the current dialogue summary. - Dialogue export: Export a dialogue as Markdown for archiving.
- Multi-item requirements: Support users describing multiple items in one dialogue, clarifying each one.
- Reverse check: Ask "Is there anything else you want to add?" at closing to avoid omissions.