Fix critical prompt field error in all marketing tools

## Problem
All 4 marketing tools (contentvariant, subjectlines, platformadapt, factcheck)
were calling prepare_chat_style_prompt() which expects request.prompt field.
This caused "object has no field 'prompt'" errors in Claude Desktop.

## Root Cause
The prepare_prompt() methods were:
1. Building prompt_text string
2. Creating a copy of request
3. Setting request_copy.prompt = prompt_text
4. Calling prepare_chat_style_prompt(request_copy)

But ToolRequest (and subclasses) don't have a 'prompt' field, causing
AttributeError when prepare_chat_style_prompt tries to access it.

## Solution
Changed all prepare_prompt() methods to return the prompt string directly
instead of calling prepare_chat_style_prompt(). This is the correct pattern
for SimpleTool implementations.

## Files Changed
- tools/contentvariant.py: Removed copy() and prepare_chat_style_prompt() call
- tools/subjectlines.py: Removed copy() and prepare_chat_style_prompt() call
- tools/platformadapt.py: Removed copy() and prepare_chat_style_prompt() call
- tools/factcheck.py: Removed copy() and prepare_chat_style_prompt() call

## Testing
- Server startup:  All 7 tools load successfully
- Tool instantiation:  All tools initialize without errors

## Impact
This fixes the schema errors preventing users from using the new Phase 2 tools
in Claude Desktop. All tools should now work correctly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ben 2025-11-07 14:12:19 -04:00
parent 78127f03d7
commit f0bd374926
4 changed files with 8 additions and 36 deletions

View file

@ -108,15 +108,8 @@ class ContentVariantTool(SimpleTool):
"testing angles, and predicted audience responses."
)
# Build prompt text without mutating request object
prompt_text = "\n".join(prompt_parts)
# Create a new request-like object with the prompt for chat-style preparation
# This avoids mutating the original request object
from copy import copy
request_copy = copy(request)
request_copy.prompt = prompt_text
return self.prepare_chat_style_prompt(request_copy)
# Return the complete prompt
return "\n".join(prompt_parts)
def get_input_schema(self) -> dict:
"""Return the JSON schema for this tool's input"""

View file

@ -119,15 +119,8 @@ class FactCheckTool(SimpleTool):
"evidence summary, confidence level, sources, and recommendations if needed."
)
# Build prompt text without mutating request object
prompt_text = "\n".join(prompt_parts)
# Create a copy for chat-style preparation
from copy import copy
request_copy = copy(request)
request_copy.prompt = prompt_text
return self.prepare_chat_style_prompt(request_copy)
# Return the complete prompt
return "\n".join(prompt_parts)
def get_input_schema(self) -> dict:
"""Return the JSON schema for this tool's input"""

View file

@ -120,15 +120,8 @@ class PlatformAdaptTool(SimpleTool):
"adaptation rationale, and platform-specific optimizations applied."
)
# Build prompt text without mutating request object
prompt_text = "\n".join(prompt_parts)
# Create a copy for chat-style preparation
from copy import copy
request_copy = copy(request)
request_copy.prompt = prompt_text
return self.prepare_chat_style_prompt(request_copy)
# Return the complete prompt
return "\n".join(prompt_parts)
def get_input_schema(self) -> dict:
"""Return the JSON schema for this tool's input"""

View file

@ -122,15 +122,8 @@ class SubjectLinesTool(SimpleTool):
"\n\nGroup by psychological angle, include character counts, A/B testing rationale, and make each line genuinely different."
)
# Build prompt text without mutating request object
prompt_text = "\n".join(prompt_parts)
# Create a copy for chat-style preparation
from copy import copy
request_copy = copy(request)
request_copy.prompt = prompt_text
return self.prepare_chat_style_prompt(request_copy)
# Return the complete prompt
return "\n".join(prompt_parts)
def get_input_schema(self) -> dict:
"""Return the JSON schema for this tool's input"""