phone-a-friend-mcp-server 0.1.2__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/PKG-INFO +80 -109
  2. phone_a_friend_mcp_server-0.2.0/README.md +151 -0
  3. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/pyproject.toml +2 -1
  4. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/config.py +1 -0
  5. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/tools/fax_tool.py +24 -37
  6. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/tools/phone_tool.py +24 -30
  7. phone_a_friend_mcp_server-0.2.0/src/phone_a_friend_mcp_server/utils/__init__.py +1 -0
  8. phone_a_friend_mcp_server-0.2.0/src/phone_a_friend_mcp_server/utils/context_builder.py +93 -0
  9. phone_a_friend_mcp_server-0.2.0/tests/test_context_builder.py +105 -0
  10. phone_a_friend_mcp_server-0.2.0/tests/test_tools.py +122 -0
  11. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/uv.lock +12 -1
  12. phone_a_friend_mcp_server-0.1.2/README.md +0 -181
  13. phone_a_friend_mcp_server-0.1.2/tests/test_tools.py +0 -184
  14. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/.gitignore +0 -0
  15. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/.pre-commit-config.yaml +0 -0
  16. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/Dockerfile +0 -0
  17. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/LICENSE +0 -0
  18. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/__init__.py +0 -0
  19. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/__main__.py +0 -0
  20. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/client/__init__.py +0 -0
  21. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/server.py +0 -0
  22. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/tools/__init__.py +0 -0
  23. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/tools/base_tools.py +0 -0
  24. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/src/phone_a_friend_mcp_server/tools/tool_manager.py +0 -0
  25. {phone_a_friend_mcp_server-0.1.2 → phone_a_friend_mcp_server-0.2.0}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: phone-a-friend-mcp-server
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: MCP Server for Phone-a-Friend assistance
5
5
  Project-URL: GitHub, https://github.com/abhishekbhakat/phone-a-friend-mcp-server
6
6
  Project-URL: Issues, https://github.com/abhishekbhakat/phone-a-friend-mcp-server/issues
@@ -17,6 +17,7 @@ Requires-Dist: aiofiles>=24.1.0
17
17
  Requires-Dist: aiohttp>=3.12.7
18
18
  Requires-Dist: click>=8.2.1
19
19
  Requires-Dist: mcp>=1.9.2
20
+ Requires-Dist: pathspec>=0.12.1
20
21
  Requires-Dist: pydantic-ai-slim[anthropic,google,openai]>=0.2.14
21
22
  Requires-Dist: pydantic>=2.11.5
22
23
  Requires-Dist: pyyaml>=6.0.0
@@ -63,87 +64,106 @@ Primary AI → Phone-a-Friend MCP → OpenRouter → External AI (GPT-4, Claude,
63
64
  - Critical decision-making with high stakes
64
65
  - Problems requiring multiple perspectives
65
66
 
66
- ## Installation 🚀
67
+ ## Quick Start ⚡
68
+
69
+ Configure your MCP client (e.g., Claude Desktop) using the JSON block below—no cloning or manual installation required.
70
+ The `uv` runner will automatically download and execute the server package if it isn't present.
71
+
72
+ Add the following JSON configuration to your MCP client and replace `<YOUR_API_KEY>` with your key:
73
+
74
+ ```json
75
+ {
76
+ "mcpServers": {
77
+ "phone-a-friend": {
78
+ "command": "uv",
79
+ "args": [
80
+ "run",
81
+ "phone-a-friend-mcp-server",
82
+ "--provider", "openai",
83
+ "--api-key", "<YOUR_API_KEY>"
84
+ ]
85
+ }
86
+ }
87
+ }
88
+ ```
89
+ > That's it! You can now use the `phone_a_friend` tool in any compatible client. For more options, see the Advanced Configuration section.
67
90
 
68
- 1. Clone the repository:
69
- ```bash
70
- git clone https://github.com/abhishekbhakat/phone-a-friend-mcp-server.git
71
- cd phone-a-friend-mcp-server
72
- ```
91
+ ## Available Tools 🛠️
73
92
 
74
- 2. Install dependencies:
75
- ```bash
76
- uv pip install -e .
77
- ```
93
+ ### phone_a_friend
94
+ 📞 Consult external AI for critical thinking and complex reasoning. Makes API calls to get responses.
78
95
 
79
- 3. Configure API access (choose one method):
96
+ ### fax_a_friend
97
+ 📠 Generate master prompt file for manual AI consultation. Creates file for copy-paste workflow.
80
98
 
81
- **Option A: Environment Variables**
82
- ```bash
83
- export OPENROUTER_API_KEY="your-openrouter-key"
84
- # OR
85
- export OPENAI_API_KEY="your-openai-key"
86
- # OR
87
- export ANTHROPIC_API_KEY="your-anthropic-key"
88
- # OR
89
- export GOOGLE_API_KEY="your-google-key"
90
- ```
99
+ **Parameters**
91
100
 
92
- **Option B: CLI Arguments**
93
- ```bash
94
- phone-a-friend-mcp-server --api-key "your-api-key" --provider openai
95
- ```
101
+ *phone_a_friend*
96
102
 
97
- ## Usage 💡
103
+ - `all_related_context` (required): General, non-code context such as constraints, tracebacks, or high-level requirements.
104
+ - `file_list` (required): Array of file paths or glob patterns. **Just pass the paths** – the server automatically reads those files (skips anything in `.gitignore` or non-text/binary) and builds the full code context for the external AI.
105
+ - `task` (required): A clear, specific description of what you want the external AI to do.
98
106
 
99
- ### Command Line Options
100
- ```bash
107
+ *fax_a_friend*
101
108
 
102
- # Custom base URL (if needed)
103
- phone-a-friend-mcp-server --base-url "https://custom-api.example.com"
109
+ - `all_related_context` (required): Same as above.
110
+ - `file_list` (required): Same as above.
111
+ - `task` (required): Same as above.
112
+ - `output_directory` (required): Directory where the generated `fax_a_friend.md` master prompt file will be saved.
104
113
 
105
- # Temperature control (0.0 = deterministic, 2.0 = very creative)
106
- phone-a-friend-mcp-server --temperature 0.4
114
+ ## Advanced Configuration 🔧
107
115
 
108
- # Combined example
109
- phone-a-friend-mcp-server --api-key "sk-..." --provider openai --model "o3" -v
110
- ```
116
+ This section covers all configuration options, including environment variables, CLI flags, and model selection.
111
117
 
112
- ### Environment Variables (Optional)
113
- ```bash
118
+ ### Providers and API Keys
119
+
120
+ The server can be configured via CLI flags or environment variables.
114
121
 
115
- # Optional model overrides
116
- export PHONE_A_FRIEND_MODEL="your-preferred-model"
117
- export PHONE_A_FRIEND_PROVIDER="your-preferred-provider"
118
- export PHONE_A_FRIEND_BASE_URL="https://custom-api.example.com"
122
+ | Provider | CLI Flag | Environment Variable |
123
+ | :--- | :--- | :--- |
124
+ | OpenAI | `--provider openai` | `OPENAI_API_KEY` |
125
+ | OpenRouter | `--provider openrouter` | `OPENROUTER_API_KEY` |
126
+ | Anthropic | `--provider anthropic` | `ANTHROPIC_API_KEY` |
127
+ | Google | `--provider google` | `GOOGLE_API_KEY` |
119
128
 
120
- # Temperature control (0.0-2.0, where 0.0 = deterministic, 2.0 = very creative)
121
- export PHONE_A_FRIEND_TEMPERATURE=0.4
129
+ **CLI Example:**
130
+ ```bash
131
+ phone-a-friend-mcp-server --provider openai --api-key "sk-..."
122
132
  ```
123
133
 
124
- ## Model Selection 🤖
134
+ **Environment Variable Example:**
135
+ ```bash
136
+ export OPENAI_API_KEY="sk-..."
137
+ phone-a-friend-mcp-server
138
+ ```
125
139
 
126
- Default reasoning models to be selected:
127
- - **OpenAI**: o3
128
- - **Anthropic**: Claude 4 Opus
129
- - **Google**: Gemini 2.5 Pro Preview 05-06 (automatically set temperature to 0.0)
130
- - **OpenRouter**: For other models like Deepseek or Qwen
140
+ ### Model Selection
131
141
 
132
- You can override the auto-selection by setting `PHONE_A_FRIEND_MODEL` environment variable or using the `--model` CLI option.
142
+ You can override the default model for each provider.
133
143
 
134
- ## Available Tools 🛠️
144
+ | Provider | Default Model |
145
+ | :--- | :--- |
146
+ | **OpenAI** | `o3` |
147
+ | **Anthropic** | `Claude 4 Opus` |
148
+ | **Google** | `Gemini 2.5 Pro Preview 05-06` |
149
+ | **OpenRouter**| `anthropic/claude-4-opus` |
135
150
 
136
- ### phone_a_friend
137
- 📞 Consult external AI for critical thinking and complex reasoning. Makes API calls to get responses.
151
+ **Override with CLI:**
152
+ ```bash
153
+ phone-a-friend-mcp-server --model "gpt-4-turbo"
154
+ ```
138
155
 
139
- ### fax_a_friend
140
- 📠 Generate master prompt file for manual AI consultation. Creates file for copy-paste workflow.
156
+ **Override with Environment Variable:**
157
+ ```bash
158
+ export PHONE_A_FRIEND_MODEL="gpt-4-turbo"
159
+ ```
141
160
 
142
- **Parameters (both tools):**
143
- - `all_related_context` (required): All context related to the problem
144
- - `any_additional_context` (optional): Additional helpful context
145
- - `task` (required): Specific task or question for the AI
161
+ ### Additional Options
146
162
 
163
+ | Feature | CLI Flag | Environment Variable | Default |
164
+ | :--- | :--- | :--- | :--- |
165
+ | **Temperature** | `--temperature 0.5` | `PHONE_A_FRIEND_TEMPERATURE` | `0.4` |
166
+ | **Base URL** | `--base-url ...` | `PHONE_A_FRIEND_BASE_URL` | Provider default |
147
167
 
148
168
  ## Use Cases 🎯
149
169
 
@@ -151,55 +171,6 @@ You can override the auto-selection by setting `PHONE_A_FRIEND_MODEL` environmen
151
171
  2. For complex algorithms, data structures, or mathematical computations
152
172
  3. Frontend Development with React, Vue, CSS, or modern frontend frameworks
153
173
 
154
- ## Claude Desktop Configuration 🖥️
155
-
156
- To use Phone-a-Friend MCP server with Claude Desktop, add this configuration to your `claude_desktop_config.json` file:
157
-
158
- ### Configuration File Location
159
- - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
160
- - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
161
-
162
- ### Configuration
163
-
164
- **Option 1: Using uv (Recommended)**
165
- ```json
166
- {
167
- "mcpServers": {
168
- "phone-a-friend": {
169
- "command": "uvx",
170
- "args": [
171
- "--refresh",
172
- "phone-a-friend-mcp-server",
173
- ],
174
- "env": {
175
- "OPENROUTER_API_KEY": "your-openrouter-api-key",
176
- "PHONE_A_FRIEND_MODEL": "anthropic/claude-4-opus",
177
- "PHONE_A_FRIEND_TEMPERATURE": "0.4"
178
- }
179
- }
180
- }
181
- }
182
- ```
183
-
184
- ### Environment Variables in Configuration
185
-
186
- You can configure different AI providers directly in the Claude Desktop config:
187
-
188
- ```json
189
- {
190
- "mcpServers": {
191
- "phone-a-friend": {
192
- "command": "phone-a-friend-mcp-server",
193
- "env": {
194
- "OPENROUTER_API_KEY": "your-openrouter-api-key",
195
- "PHONE_A_FRIEND_MODEL": "anthropic/claude-4-opus",
196
- "PHONE_A_FRIEND_TEMPERATURE": "0.4"
197
- }
198
- }
199
- }
200
- }
201
- ```
202
-
203
174
  ## License 📄
204
175
 
205
176
  MIT License - see LICENSE file for details.
@@ -0,0 +1,151 @@
1
+ # Phone-a-Friend MCP Server 🧠📞
2
+
3
+ An AI-to-AI consultation system that enables one AI to "phone a friend" (another AI) for critical thinking, long context reasoning, and complex problem solving via OpenRouter.
4
+
5
+ ## The Problem 🤔
6
+
7
+ Sometimes an AI encounters complex problems that require:
8
+ - **Deep critical thinking** beyond immediate capabilities
9
+ - **Long context reasoning** with extensive information
10
+ - **Multi-step analysis** that benefits from external perspective
11
+ - **Specialized expertise** from different AI models
12
+
13
+ ## The Solution �
14
+
15
+ Phone-a-Friend MCP Server creates a **two-step consultation process**:
16
+
17
+ 1. **Context + Reasoning**: Package all relevant context and send to external AI for deep analysis
18
+ 2. **Extract Actionable Insights**: Process the reasoning response into usable format for the primary AI
19
+
20
+ This enables AI systems to leverage other AI models as "consultants" for complex reasoning tasks.
21
+
22
+ ## Architecture 🏗️
23
+
24
+ ```
25
+ Primary AI → Phone-a-Friend MCP → OpenRouter → External AI (GPT-4, Claude, etc.) → Processed Response → Primary AI
26
+ ```
27
+
28
+ **Sequential Workflow:**
29
+ 1. `analyze_context` - Gather and structure all relevant context
30
+ 2. `get_critical_thinking` - Send context to external AI via OpenRouter for reasoning
31
+ 3. `extract_actionable_insights` - Process response into actionable format
32
+
33
+ ## When to Use 🎯
34
+
35
+ **Ideal for:**
36
+ - Complex multi-step problems requiring deep analysis
37
+ - Situations needing long context reasoning (>100k tokens)
38
+ - Cross-domain expertise consultation
39
+ - Critical decision-making with high stakes
40
+ - Problems requiring multiple perspectives
41
+
42
+ ## Quick Start ⚡
43
+
44
+ Configure your MCP client (e.g., Claude Desktop) using the JSON block below—no cloning or manual installation required.
45
+ The `uv` runner will automatically download and execute the server package if it isn't present.
46
+
47
+ Add the following JSON configuration to your MCP client and replace `<YOUR_API_KEY>` with your key:
48
+
49
+ ```json
50
+ {
51
+ "mcpServers": {
52
+ "phone-a-friend": {
53
+ "command": "uv",
54
+ "args": [
55
+ "run",
56
+ "phone-a-friend-mcp-server",
57
+ "--provider", "openai",
58
+ "--api-key", "<YOUR_API_KEY>"
59
+ ]
60
+ }
61
+ }
62
+ }
63
+ ```
64
+ > That's it! You can now use the `phone_a_friend` tool in any compatible client. For more options, see the Advanced Configuration section.
65
+
66
+ ## Available Tools 🛠️
67
+
68
+ ### phone_a_friend
69
+ 📞 Consult external AI for critical thinking and complex reasoning. Makes API calls to get responses.
70
+
71
+ ### fax_a_friend
72
+ 📠 Generate master prompt file for manual AI consultation. Creates file for copy-paste workflow.
73
+
74
+ **Parameters**
75
+
76
+ *phone_a_friend*
77
+
78
+ - `all_related_context` (required): General, non-code context such as constraints, tracebacks, or high-level requirements.
79
+ - `file_list` (required): Array of file paths or glob patterns. **Just pass the paths** – the server automatically reads those files (skips anything in `.gitignore` or non-text/binary) and builds the full code context for the external AI.
80
+ - `task` (required): A clear, specific description of what you want the external AI to do.
81
+
82
+ *fax_a_friend*
83
+
84
+ - `all_related_context` (required): Same as above.
85
+ - `file_list` (required): Same as above.
86
+ - `task` (required): Same as above.
87
+ - `output_directory` (required): Directory where the generated `fax_a_friend.md` master prompt file will be saved.
88
+
89
+ ## Advanced Configuration 🔧
90
+
91
+ This section covers all configuration options, including environment variables, CLI flags, and model selection.
92
+
93
+ ### Providers and API Keys
94
+
95
+ The server can be configured via CLI flags or environment variables.
96
+
97
+ | Provider | CLI Flag | Environment Variable |
98
+ | :--- | :--- | :--- |
99
+ | OpenAI | `--provider openai` | `OPENAI_API_KEY` |
100
+ | OpenRouter | `--provider openrouter` | `OPENROUTER_API_KEY` |
101
+ | Anthropic | `--provider anthropic` | `ANTHROPIC_API_KEY` |
102
+ | Google | `--provider google` | `GOOGLE_API_KEY` |
103
+
104
+ **CLI Example:**
105
+ ```bash
106
+ phone-a-friend-mcp-server --provider openai --api-key "sk-..."
107
+ ```
108
+
109
+ **Environment Variable Example:**
110
+ ```bash
111
+ export OPENAI_API_KEY="sk-..."
112
+ phone-a-friend-mcp-server
113
+ ```
114
+
115
+ ### Model Selection
116
+
117
+ You can override the default model for each provider.
118
+
119
+ | Provider | Default Model |
120
+ | :--- | :--- |
121
+ | **OpenAI** | `o3` |
122
+ | **Anthropic** | `Claude 4 Opus` |
123
+ | **Google** | `Gemini 2.5 Pro Preview 05-06` |
124
+ | **OpenRouter**| `anthropic/claude-4-opus` |
125
+
126
+ **Override with CLI:**
127
+ ```bash
128
+ phone-a-friend-mcp-server --model "gpt-4-turbo"
129
+ ```
130
+
131
+ **Override with Environment Variable:**
132
+ ```bash
133
+ export PHONE_A_FRIEND_MODEL="gpt-4-turbo"
134
+ ```
135
+
136
+ ### Additional Options
137
+
138
+ | Feature | CLI Flag | Environment Variable | Default |
139
+ | :--- | :--- | :--- | :--- |
140
+ | **Temperature** | `--temperature 0.5` | `PHONE_A_FRIEND_TEMPERATURE` | `0.4` |
141
+ | **Base URL** | `--base-url ...` | `PHONE_A_FRIEND_BASE_URL` | Provider default |
142
+
143
+ ## Use Cases 🎯
144
+
145
+ 1. In-depth Reasoning for Vibe Coding
146
+ 2. For complex algorithms, data structures, or mathematical computations
147
+ 3. Frontend Development with React, Vue, CSS, or modern frontend frameworks
148
+
149
+ ## License 📄
150
+
151
+ MIT License - see LICENSE file for details.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "phone-a-friend-mcp-server"
3
- version = "0.1.2"
3
+ version = "0.2.0"
4
4
  description = "MCP Server for Phone-a-Friend assistance"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -15,6 +15,7 @@ dependencies = [
15
15
  "pydantic-ai-slim[openai,anthropic,google]>=0.2.14",
16
16
  "click>=8.2.1",
17
17
  "pyyaml>=6.0.0",
18
+ "pathspec>=0.12.1",
18
19
  ]
19
20
  classifiers = [
20
21
  "Development Status :: 3 - Alpha",
@@ -74,6 +74,7 @@ class PhoneAFriendConfig:
74
74
  """Get default temperature for specific models that benefit from it."""
75
75
  default_temperatures = {
76
76
  "gemini-2.5-pro-preview-06-05": 0.0,
77
+ "gemini-2.5-pro": 0.0,
77
78
  }
78
79
 
79
80
  return default_temperatures.get(self.model)
@@ -4,6 +4,7 @@ from typing import Any
4
4
  import aiofiles
5
5
 
6
6
  from phone_a_friend_mcp_server.tools.base_tools import BaseTool
7
+ from phone_a_friend_mcp_server.utils.context_builder import build_code_context
7
8
 
8
9
 
9
10
  class FaxAFriendTool(BaseTool):
@@ -35,9 +36,10 @@ refactors, design, migrations.
35
36
 
36
37
  This tool creates a file for manual AI consultation. After file creation,
37
38
  wait for the user to return with the external AI's response.
39
+ Replies must be exhaustively detailed. Do **NOT** include files ignored by .gitignore (e.g., *.pyc).
38
40
 
39
41
  Hard restrictions:
40
- • Generated prompt includes *only* the two context blocks you send.
42
+ • Generated prompt includes *only* the context you provide.
41
43
  • No memory, no internet, no tools.
42
44
  • You must spell out every fact it should rely on.
43
45
 
@@ -83,22 +85,17 @@ replacing <file="…"> blocks as needed. Commentary goes outside those tags."""
83
85
  "all_related_context": {
84
86
  "type": "string",
85
87
  "description": (
86
- "MANDATORY. Everything the friend AI needs to see:\n"
87
- "- The full <file_tree> block (ASCII tree).\n"
88
- '- One or more <file="…"> blocks with the current code.\n'
89
- "- Known constraints (Python version, allowed deps, runtime limits, etc.).\n"
90
- "- Any failing test output or traceback.\n"
91
- "If it's not here, the friend AI can't use it."
88
+ "MANDATORY. General, non-code context for the friend AI. "
89
+ "Include known constraints (Python version, allowed deps, etc.), "
90
+ "failing test output, or tracebacks. DO NOT include file contents here."
92
91
  ),
93
92
  },
94
- "any_additional_context": {
95
- "type": "string",
93
+ "file_list": {
94
+ "type": "array",
95
+ "items": {"type": "string"},
96
96
  "description": (
97
- "Optional extras that help but aren't core code:\n"
98
- "- Style guides, architecture docs, API specs.\n"
99
- "- Performance targets, security rules, deployment notes.\n"
100
- "- Similar past solutions or reference snippets.\n"
101
- "Skip it if there's nothing useful."
97
+ "MANDATORY. A list of file paths or glob patterns to be included in the code context. "
98
+ "The tool will automatically read these files, filter them against .gitignore, and build the context."
102
99
  ),
103
100
  },
104
101
  "task": {
@@ -122,29 +119,26 @@ replacing <file="…"> blocks as needed. Commentary goes outside those tags."""
122
119
  ),
123
120
  },
124
121
  },
125
- "required": ["all_related_context", "task", "output_directory"],
122
+ "required": ["all_related_context", "file_list", "task", "output_directory"],
126
123
  }
127
124
 
128
125
  async def run(self, **kwargs) -> dict[str, Any]:
129
126
  all_related_context = kwargs.get("all_related_context", "")
130
- any_additional_context = kwargs.get("any_additional_context", "")
127
+ file_list = kwargs.get("file_list", [])
131
128
  task = kwargs.get("task", "")
132
129
  output_directory = kwargs.get("output_directory", "")
133
130
 
134
- # Create master prompt using the same logic as phone_a_friend
135
- master_prompt = self._create_master_prompt(all_related_context, any_additional_context, task)
131
+ code_context = build_code_context(file_list)
132
+ master_prompt = self._create_master_prompt(all_related_context, code_context, task)
136
133
 
137
134
  try:
138
- # Validate and prepare output directory
139
135
  output_dir = self._prepare_output_directory(output_directory)
140
136
 
141
- # Create full file path
142
137
  file_path = os.path.join(output_dir, "fax_a_friend.md")
143
138
 
144
139
  async with aiofiles.open(file_path, "w", encoding="utf-8") as f:
145
140
  await f.write(master_prompt)
146
141
 
147
- # Get absolute path for user reference
148
142
  abs_path = os.path.abspath(file_path)
149
143
 
150
144
  return {
@@ -153,15 +147,15 @@ replacing <file="…"> blocks as needed. Commentary goes outside those tags."""
153
147
  "file_name": "fax_a_friend.md",
154
148
  "output_directory": output_dir,
155
149
  "prompt_length": len(master_prompt),
156
- "context_length": len(all_related_context + any_additional_context),
150
+ "context_length": len(master_prompt),
157
151
  "task": task,
158
152
  "instructions": self._get_manual_workflow_instructions(abs_path),
159
153
  }
160
154
 
161
155
  except Exception as e:
162
- return {"status": "failed", "error": str(e), "output_directory": output_directory, "context_length": len(all_related_context + any_additional_context), "task": task}
156
+ return {"status": "failed", "error": str(e), "output_directory": output_directory, "context_length": len(master_prompt), "task": task}
163
157
 
164
- def _create_master_prompt(self, all_related_context: str, any_additional_context: str, task: str) -> str:
158
+ def _create_master_prompt(self, all_related_context: str, code_context: str, task: str) -> str:
165
159
  """Create a comprehensive prompt identical to PhoneAFriendTool's version."""
166
160
 
167
161
  prompt_parts = [
@@ -171,23 +165,19 @@ replacing <file="…"> blocks as needed. Commentary goes outside those tags."""
171
165
  "=== TASK ===",
172
166
  task,
173
167
  "",
174
- "=== ALL RELATED CONTEXT ===",
168
+ "=== GENERAL CONTEXT ===",
175
169
  all_related_context,
170
+ "",
171
+ "=== CODE CONTEXT ===",
172
+ code_context,
176
173
  ]
177
174
 
178
- if any_additional_context.strip():
179
- prompt_parts.extend(
180
- [
181
- "",
182
- "=== ADDITIONAL CONTEXT ===",
183
- any_additional_context,
184
- ]
185
- )
186
-
187
175
  prompt_parts.extend(
188
176
  [
189
177
  "",
190
178
  "=== INSTRUCTIONS ===",
179
+ "- Provide exhaustive, step-by-step reasoning.",
180
+ "- Never include files matching .gitignore patterns.",
191
181
  "- Analyze the code and requirements step-by-step.",
192
182
  "- Show your reasoning and propose concrete changes.",
193
183
  '- Provide updated code using the XML format (<file_tree> plus <file="…"> blocks).',
@@ -204,17 +194,14 @@ replacing <file="…"> blocks as needed. Commentary goes outside those tags."""
204
194
  if not output_directory:
205
195
  raise ValueError("output_directory parameter is required")
206
196
 
207
- # Expand user path (~) and resolve relative paths
208
197
  expanded_path = os.path.expanduser(output_directory)
209
198
  resolved_path = os.path.abspath(expanded_path)
210
199
 
211
- # Create directory if it doesn't exist
212
200
  try:
213
201
  os.makedirs(resolved_path, exist_ok=True)
214
202
  except OSError as e:
215
203
  raise ValueError(f"Cannot create directory '{resolved_path}': {e}")
216
204
 
217
- # Check if directory is writable
218
205
  if not os.access(resolved_path, os.W_OK):
219
206
  raise ValueError(f"Directory '{resolved_path}' is not writable")
220
207