/ archive / go-tui-standalone / PHASE_2_PLAN.md
PHASE_2_PLAN.md
  1  # Phase 1.5-1.7: Testing & Backend Integration Plan
  2  
  3  **Status:** Basic scaffold complete, moving to testing and backend
  4  
  5  ---
  6  
  7  ## Progress Update
  8  
  9  ### ✅ Completed (Phase 1.1-1.4)
 10  
 11  - [x] Go module initialized
 12  - [x] Dependencies installed
 13  - [x] Project structure created
 14  - [x] Basic Bubble Tea skeleton
 15  - [x] Message types defined
 16  - [x] Styled rendering with Lipgloss
 17  - [x] Binary compiles successfully
 18  
 19  **Files:** 6 Go files, 516 lines total
 20  **Binary:** 5.3 MB (debug build)
 21  
 22  ---
 23  
 24  ## Current: Phase 1.5-1.7 Testing
 25  
 26  ### What to Test
 27  
 28  1. **Basic rendering** ✓
 29     - Binary exists and runs
 30     - Welcome message displays
 31     - UI layout correct
 32  
 33  2. **Input handling** (needs terminal test)
 34     - Can type in textarea
 35     - Enter submits message
 36     - Message appears in viewport
 37  
 38  3. **Keyboard shortcuts** (needs terminal test)
 39     - Ctrl+C quits
 40     - PgUp/PgDn scroll
 41     - Textarea navigation works
 42  
 43  ### Testing Approach
 44  
 45  Since we're in a non-interactive environment, we need to:
 46  
 47  **Option 1:** Manual testing later
 48  - User runs `./kamaji-tui` in real terminal
 49  - Tests all features interactively
 50  
 51  **Option 2:** Continue development, test comprehensively at end
 52  - Add more features first
 53  - Test everything together
 54  
 55  **Recommendation:** Continue with Phase 2 (backend integration) and test comprehensively when we have real functionality.
 56  
 57  ---
 58  
 59  ## Next: Phase 2 - Python Backend Integration
 60  
 61  ### Goal
 62  Connect Go TUI to existing Python Kamaji backend
 63  
 64  ### Two Approaches
 65  
 66  #### Option A: Subprocess (Simpler)
 67  ```go
 68  func callPythonBackend(message string) (string, error) {
 69      cmd := exec.Command("python", "-m", "kamaji.cli", "ask", message)
 70      output, err := cmd.CombinedOutput()
 71      return string(output), err
 72  }
 73  ```
 74  
 75  **Pros:**
 76  - Simple to implement
 77  - Reuses existing kamaji CLI
 78  - No changes to Python code
 79  
 80  **Cons:**
 81  - Slower (process startup overhead)
 82  - No streaming
 83  - No agent transparency
 84  
 85  #### Option B: HTTP API (Better long-term)
 86  ```python
 87  # New file: kamaji/api.py
 88  from flask import Flask, request, jsonify
 89  from kamaji.llm import get_llm
 90  from kamaji.agent import create_agent_executor
 91  
 92  app = Flask(__name__)
 93  
 94  @app.route('/chat', methods=['POST'])
 95  def chat():
 96      message = request.json['message']
 97      # ... send to agent, return response
 98      return jsonify({'response': response})
 99  ```
100  
101  ```go
102  func callPythonAPI(message string) (string, error) {
103      resp, err := http.Post("http://localhost:5000/chat", 
104          "application/json",
105          strings.NewReader(fmt.Sprintf(`{"message": "%s"}`, message)))
106      // ... parse response
107  }
108  ```
109  
110  **Pros:**
111  - Fast (no process startup)
112  - Can stream responses
113  - Can send agent events (thinking, tools)
114  - Cleaner architecture
115  
116  **Cons:**
117  - Requires adding HTTP server to Python
118  - More complexity
119  - Need to manage server lifecycle
120  
121  ### Recommendation: Start with Option A, migrate to Option B
122  
123  **Phase 2.1:** Subprocess integration (quick proof of concept)
124  **Phase 2.2:** Add streaming HTTP API (better UX)
125  
126  ---
127  
128  ## Phase 2.1 Tasks (Subprocess Approach)
129  
130  ### 2.1.1: Implement subprocess call
131  
132  ```go
133  // backend.go
134  import (
135      "os/exec"
136      "strings"
137  )
138  
139  func callKamajiCLI(message string) tea.Cmd {
140      return func() tea.Msg {
141          // Call: python -m kamaji.cli ask "message"
142          cmd := exec.Command(
143              "python", "-m", "kamaji.cli", 
144              "ask", message,
145          )
146          
147          // Set working directory to kamaji root
148          cmd.Dir = "../"
149          
150          output, err := cmd.CombinedOutput()
151          if err != nil {
152              return errMsg(err)
153          }
154          
155          return backendResponseMsg(string(output))
156      }
157  }
158  ```
159  
160  ### 2.1.2: Update message submission
161  
162  ```go
163  // update.go - in KeyEnter handler
164  return m, callKamajiCLI(userMessage)
165  ```
166  
167  ### 2.1.3: Test end-to-end
168  
169  ```bash
170  ./kamaji-tui
171  # Type: "What is 2+2?"
172  # Should get LLM response back
173  ```
174  
175  ### 2.1.4: Handle errors gracefully
176  
177  ```go
178  case errMsg:
179      m.loading = false
180      m.messages = append(m.messages, Message{
181          Role: "system",
182          Content: StyledErrorMessage(msg),
183      })
184  ```
185  
186  ---
187  
188  ## Phase 2.2 Tasks (HTTP API)
189  
190  ### 2.2.1: Create Python HTTP API
191  
192  ```python
193  # kamaji/api_server.py
194  from flask import Flask, Response, request
195  from kamaji.agent import create_agent_executor
196  from kamaji.llm import get_llm
197  import json
198  
199  app = Flask(__name__)
200  
201  @app.route('/stream', methods=['POST'])
202  def stream_chat():
203      message = request.json['message']
204      
205      def generate():
206          # Setup agent with streaming callbacks
207          llm = get_llm()
208          agent = create_agent_executor(llm, callbacks=[
209              StreamingCallback(lambda event: yield json.dumps(event) + "\n")
210          ])
211          
212          # Run agent
213          result = agent.run(message)
214          
215          yield json.dumps({'type': 'final', 'content': result}) + "\n"
216      
217      return Response(generate(), mimetype='text/event-stream')
218  
219  if __name__ == '__main__':
220      app.run(port=5555)
221  ```
222  
223  ### 2.2.2: Implement Go HTTP client
224  
225  ```go
226  // backend.go
227  func streamFromAPI(message string) tea.Cmd {
228      return func() tea.Msg {
229          resp, err := http.Post(
230              "http://localhost:5555/stream",
231              "application/json",
232              strings.NewReader(fmt.Sprintf(`{"message": "%s"}`, message)),
233          )
234          if err != nil {
235              return errMsg(err)
236          }
237          
238          scanner := bufio.NewScanner(resp.Body)
239          for scanner.Scan() {
240              var event Event
241              json.Unmarshal(scanner.Bytes(), &event)
242              
243              // Send events to UI
244              // (need to design event passing)
245          }
246          
247          return nil
248      }
249  }
250  ```
251  
252  ### 2.2.3: Add event types for agent transparency
253  
254  ```go
255  // model.go
256  type Event struct {
257      Type    string  `json:"type"`    // thinking, tool, result, final
258      Content string  `json:"content"`
259      Tool    string  `json:"tool,omitempty"`
260      Timing  float64 `json:"timing,omitempty"`
261  }
262  ```
263  
264  ### 2.2.4: Update UI to show events in real-time
265  
266  As events stream in, append messages and update viewport
267  
268  ---
269  
270  ## Timeline
271  
272  **Phase 2.1 (Subprocess):** 2-3 hours
273  - Quick to implement
274  - Gets us working end-to-end
275  - Can test immediately
276  
277  **Phase 2.2 (HTTP API):** 4-6 hours
278  - Need to create Python API
279  - Implement streaming
280  - Wire up events
281  - More polished result
282  
283  **Total Phase 2:** ~6-9 hours (1 day)
284  
285  ---
286  
287  ## Decision Point
288  
289  **Should we:**
290  
291  A. Implement Phase 2.1 now (subprocess, quick) ✅ **RECOMMENDED**
292     - Gets us working faster
293     - Can demo immediately
294     - Easier to debug
295  
296  B. Skip to Phase 2.2 (HTTP API, better)
297     - More work upfront
298     - Better long-term
299     - Need to design API carefully
300  
301  C. Do both in sequence
302     - 2.1 first for quick validation
303     - Then 2.2 for production quality
304  
305  **Recommendation: Option C** - Start with subprocess (2.1) to validate quickly, then add HTTP API (2.2) for better UX.
306  
307  ---
308  
309  ## Next Immediate Steps
310  
311  1. ✅ Complete styled message rendering (done)
312  2. → Implement subprocess backend call (2.1.1)
313  3. → Test with real kamaji command (2.1.3)
314  4. → Handle errors gracefully (2.1.4)
315  5. → Update progress tracker
316  
317  **Let's implement Phase 2.1 now!**