Skip to main content

Overview

The text_to_text_response() method generates text using the Agent’s configured LLM (Language Model). Use it for:
  • Generating conversational responses
  • Processing user input with AI
  • Classification and intent detection
  • Summarization and content generation
  • JSON extraction from unstructured text
This is the ONLY synchronous method in CapabilityWorker.Do NOT use await with text_to_text_response().

text_to_text_response()

Generates a text response using the configured LLM.

Signature

self.capability_worker.text_to_text_response(
    prompt_text: str,
    history: list = [],
    system_prompt: str = ""
) -> str
prompt_text
string
required
The current prompt or user input to send to the LLM
history
list
default:"[]"
Conversation history for multi-turn context. Each item is a dict with role (“user” or “assistant”) and content (string).Example:
[
    {"role": "user", "content": "Tell me about dogs"},
    {"role": "assistant", "content": "Dogs are loyal companions..."}
]
system_prompt
string
default:""
System-level instructions to control LLM behavior. Sets the personality, constraints, and output format.Example:
"You are a professional chef. Keep responses under 2 sentences."

Returns

response
string
The generated text from the LLM

Examples

Basic Usage

response = self.capability_worker.text_to_text_response(
    "What's the capital of France?"
)

await self.capability_worker.speak(response)

Conversation History

Maintain multi-turn context by passing conversation history:
self.history = []

async def chat_loop(self):
    system = "You are a helpful assistant. Keep answers under 2 sentences."
    
    while True:
        user_input = await self.capability_worker.user_response()
        
        if "exit" in user_input.lower():
            break
        
        # Add user message to history
        self.history.append({"role": "user", "content": user_input})
        
        # Generate response with full history
        response = self.capability_worker.text_to_text_response(
            user_input,
            history=self.history,
            system_prompt=system
        )
        
        # Add assistant response to history
        self.history.append({"role": "assistant", "content": response})
        
        await self.capability_worker.speak(response)
    
    self.capability_worker.resume_normal_flow()

System Prompts

Control LLM behavior with system prompts:
system = "You are a pirate captain. Speak like a pirate in all responses."

response = self.capability_worker.text_to_text_response(
    "What's the weather today?",
    system_prompt=system
)

# Result: "Arr, the skies be clear and the winds fair, matey!"

Advanced Patterns

Intent Classification

Use the LLM to classify user intent:
def classify_intent(self, user_input: str) -> dict:
    """Classify user input into categories."""
    
    prompt = (
        "Classify this user input. Return ONLY valid JSON.\n"
        '{"intent": "weather|timer|music|chat", "confidence": 0.0-1.0}\n\n'
        f"User: {user_input}"
    )
    
    raw = self.capability_worker.text_to_text_response(prompt)
    
    # Strip markdown code fences
    clean = raw.replace("```json", "").replace("```", "").strip()
    
    try:
        return json.loads(clean)
    except json.JSONDecodeError:
        self.worker.editor_logging_handler.error(f"Invalid JSON: {raw}")
        return {"intent": "unknown", "confidence": 0.0}

# Usage
user_input = await self.capability_worker.user_response()
result = self.classify_intent(user_input)

if result["intent"] == "weather" and result["confidence"] > 0.7:
    # Handle weather request
    pass

JSON Extraction

Extract structured data from unstructured text:
def extract_contact_info(self, text: str) -> dict:
    """Extract name and email from natural language."""
    
    system = "You extract contact info. Return ONLY valid JSON with 'name' and 'email' keys."
    
    prompt = f"Extract contact information from: {text}"
    
    raw = self.capability_worker.text_to_text_response(
        prompt,
        system_prompt=system
    )
    
    # Strip markdown fences (LLMs often wrap JSON in ```json ... ```)
    clean = raw.replace("```json", "").replace("```", "").strip()
    
    try:
        return json.loads(clean)
    except json.JSONDecodeError:
        return {"name": None, "email": None}

# Usage
user_input = "I'm John Doe and my email is [email protected]"
info = self.extract_contact_info(user_input)

self.worker.editor_logging_handler.info(f"Name: {info['name']}, Email: {info['email']}")

Summarization

async def summarize_conversation(self):
    """Summarize the current conversation history."""
    
    # Get full message history from Agent
    history = self.capability_worker.get_full_message_history()
    
    # Convert to text
    conversation_text = "\n".join(
        [f"{msg['role']}: {msg['content']}" for msg in history]
    )
    
    # Summarize
    summary = self.capability_worker.text_to_text_response(
        f"Summarize this conversation in 2-3 sentences:\n\n{conversation_text}"
    )
    
    await self.capability_worker.speak(f"Here's a summary: {summary}")

Translation

def translate(self, text: str, target_language: str) -> str:
    """Translate text to target language."""
    
    system = f"You are a translator. Translate all input to {target_language}. Return ONLY the translation."
    
    return self.capability_worker.text_to_text_response(
        text,
        system_prompt=system
    )

# Usage
spanish = self.translate("Hello, how are you?", "Spanish")
await self.capability_worker.speak(spanish)

Best Practices

Strip Markdown Code Fences

LLMs often wrap JSON in markdown code blocks. Always strip them:
# ✅ Good
raw = self.capability_worker.text_to_text_response(prompt)
clean = raw.replace("```json", "").replace("```", "").strip()
data = json.loads(clean)

# ❌ Bad
raw = self.capability_worker.text_to_text_response(prompt)
data = json.loads(raw)  # Will fail if wrapped in ```json ... ```

Be Specific in Prompts

# ✅ Good
prompt = "Give a 1-sentence summary of: {text}"

# ❌ Vague
prompt = "Summarize this: {text}"

Use System Prompts for Constraints

# ✅ Good
system = "Keep all responses under 2 sentences. Never use technical jargon."
response = self.capability_worker.text_to_text_response(query, system_prompt=system)

# ❌ Bad - constraints in every prompt
prompt = f"{query}. Keep response under 2 sentences and avoid jargon."

Handle JSON Parsing Errors

# ✅ Good
try:
    data = json.loads(clean_response)
except json.JSONDecodeError:
    self.worker.editor_logging_handler.error(f"Invalid JSON: {raw_response}")
    data = {}  # Fallback

# ❌ Bad
data = json.loads(clean_response)  # Crashes on invalid JSON

Common Pitfalls

Using await (Wrong!)

response = self.capability_worker.text_to_text_response("Hello")

Ignoring Markdown Fences

# ❌ Will fail
response = self.capability_worker.text_to_text_response(
    "Return JSON with name and age"
)
data = json.loads(response)  # Crashes if response is ```json\n{...}\n```

# ✅ Correct
response = self.capability_worker.text_to_text_response(
    "Return JSON with name and age"
)
clean = response.replace("```json", "").replace("```", "").strip()
data = json.loads(clean)

Not Maintaining History

# ❌ No context between turns
while True:
    user_input = await self.capability_worker.user_response()
    response = self.capability_worker.text_to_text_response(user_input)
    await self.capability_worker.speak(response)

# ✅ Maintains context
history = []
while True:
    user_input = await self.capability_worker.user_response()
    history.append({"role": "user", "content": user_input})
    
    response = self.capability_worker.text_to_text_response(
        user_input, 
        history=history
    )
    
    history.append({"role": "assistant", "content": response})
    await self.capability_worker.speak(response)

Performance Tips

Keep Prompts Concise

# ✅ Good
prompt = f"Respond to: {user_input}"

# ❌ Unnecessarily verbose
prompt = (
    "The user has provided the following input and would like "
    "you to generate a helpful, friendly, and concise response "
    f"to their query which is: {user_input}"
)

Reuse System Prompts

# ✅ Good - define once
class MyAbility(MatchingCapability):
    SYSTEM_PROMPT = "You are a helpful assistant. Keep answers under 2 sentences."
    
    def generate_response(self, user_input: str) -> str:
        return self.capability_worker.text_to_text_response(
            user_input,
            system_prompt=self.SYSTEM_PROMPT
        )

# ❌ Bad - redefine every time
def generate_response(self, user_input: str) -> str:
    system = "You are a helpful assistant. Keep answers under 2 sentences."
    return self.capability_worker.text_to_text_response(
        user_input,
        system_prompt=system
    )

Listening

Get user input with user_response()

Speaking

Speak LLM responses with speak()

Build docs developers (and LLMs) love