File size: 13,846 Bytes
0698457
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# Freeplay Traces Implementation Plan

## Overview

This document outlines the implementation plan for integrating Freeplay Traces into the existing Huge League Soccer application. Traces provide enhanced observability by grouping LLM interactions within a session, allowing us to track input questions, LLM responses, and associated metadata.

## Current Architecture

### Existing Freeplay Integration Points

1. **Session Management** (`api/server_gradio.py`)
   - `AppState.ensure_sessions()` - Creates Freeplay session on first user interaction
   - Session ID preserved across state changes

2. **Prompt Management** (`api/workflows/base.py`)
   - `call_model()` - Retrieves persona-specific prompts via `get_prompt_by_persona()`
   - Uses Freeplay prompt templates (casual_fan_prompt, super_fan_prompt)

3. **Session Recording** (`api/workflows/base.py`)
   - `should_continue()` - Records final LLM responses to Freeplay session
   - Uses `record_session()` method

## Proposed Traces Implementation

### AppState Enhancement

The `AppState` class will be enhanced to store the actual Freeplay session object, allowing direct access to `session.create_trace()` as shown in the original documentation.

### Modified Methods

```python
# api/utils/freeplay_helpers.py - Modified method
def record_session(self, state, end: Optional[float] = time.time(),
                  formatted_prompt: Optional[FormattedPrompt] = None,
                  prompt_vars: Optional[dict] = None,
                  trace_info: Optional[TraceInfo] = None):  # NEW PARAMETER
    # ... existing code ...
    payload = RecordPayload(
        # ... existing fields ...
        trace_info=trace_info  # NEW FIELD
    )
```

## Implementation Flow

### 1. AppState Enhancement
**Location:** `api/server_gradio.py` - `AppState` class

```python
class AppState(BaseModel):
    # ... existing fields ...
    freeplay_session_id: str = ""
    freeplay_session: Optional[Any] = None  # NEW: Store the actual session object
    
    def ensure_sessions(self):
        if not self.zep_session_id:
            self.zep_session_id = ZepClient() \
                .get_or_create_user(self.email, self.first_name, self.last_name) \
                .create_session() \
                .session_id
        if not self.freeplay_session_id:
            freeplay_client = FreeplayClient()
            self.freeplay_session = freeplay_client.create_session()  # Store session object
            self.freeplay_session_id = self.freeplay_session.session_id
```

### 2. User Input & Trace Creation
**Location:** `api/server_gradio.py` - `submit_helper()`

```python
def submit_helper(state, handler, user_query):
    state.ensure_sessions()  # Freeplay session already exists
    
    # Create trace directly on the session object
    trace_info = state.freeplay_session.create_trace(
        input=user_query, # optional metadata not included
    )
    
    # Pass trace_info to workflow
    workflow_bundle, workflow_state = build_workflow_with_state(
        handler=handler,
        zep_session_id=state.zep_session_id,
        freeplay_session_id=state.freeplay_session_id,
        email=state.email,
        first_name=state.first_name,
        last_name=state.last_name,
        persona=state.persona,
        messages=state.history,
        trace_info=trace_info,  # NEW: Pass trace_info to workflow
    )
```

### 3. Workflow State Enhancement
**Location:** `api/workflows/base.py` - `AgentState`

```python
class AgentState(TypedDict):
    # ... existing fields ...
    trace_info: Optional[TraceInfo] = None  # NEW
```

### 4. Workflow Builder Enhancement
**Location:** `api/workflows/base.py` - `build_workflow_with_state()`

```python
def build_workflow_with_state(handler: AsyncCallbackHandler,
                              zep_session_id: Optional[str] = None,
                              freeplay_session_id: Optional[str] = None,
                              email: Optional[str] = None,
                              first_name: Optional[str] = None,
                              last_name: Optional[str] = None,
                              persona: Optional[str] = None,
                              messages: Optional[List[BaseMessage]] = None,
                              trace_info: Optional[TraceInfo] = None) -> Tuple[WorkflowBundle, AgentState]:  # NEW PARAMETER
    """
    Utility to build workflow and initial state in one step.
    """
    bundle = build_workflow(handler)
    state = {
        "zep_session_id": zep_session_id,
        "freeplay_session_id": freeplay_session_id,
        "email": email,
        "first_name": first_name,
        "last_name": last_name,
        "persona": persona,
        "messages": messages or [],
        "start_time": time.time(),
        "zep_memory": None,
        "trace_info": trace_info,  # NEW: Populate trace_info in AgentState
    }
    return bundle, state
```

### 5. LLM Processing with Trace Association
**Location:** `api/workflows/base.py` - `call_model()`

```python
async def call_model(state: AgentState,
                     handler: AsyncCallbackHandler,
                     zep_client: ZepClient,
                     freeplay_client: FreeplayClient) -> dict:
    
    # ... existing prompt and LLM logic ...
    
    # Record trace output with LLM response
    if state.get("trace_info"):
        final_response = response.content if hasattr(response, 'content') else str(response)
        state["trace_info"].record_output(
            project_id=FREEPLAY_PROJECT_ID,
            output=final_response
        )
    
    return {'messages': [response], 'zep_memory': memory}
```

### 6. Session Recording with Trace
**Location:** `api/workflows/base.py` - `should_continue()`

```python
async def should_continue(state: AgentState,
                          handler: AsyncCallbackHandler,
                          zep_client: ZepClient,
                          freeplay_client: FreeplayClient) -> str:
    # ... existing logic ...
    
    if 'tool_calls' not in last_message.additional_kwargs:
        # Record session with trace association
        freeplay_client.record_session(state, trace_info=state.get("trace_info"))
        return 'end'
    return 'continue'
```

## Data Flow Diagram

```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   User Input    β”‚    β”‚  submit_helper   β”‚    β”‚ AppState        β”‚
β”‚                 β”‚    β”‚                  β”‚    β”‚                 β”‚
β”‚ "Tell me about  │───▢│ 1. ensure_sessions│───▢│ freeplay_sessionβ”‚
β”‚  Ryan Martinez" β”‚    β”‚ 2. create_trace() β”‚    β”‚ .create_trace() β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚ 3. pass trace_infoβ”‚    β”‚                 β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚                        β”‚
                                β–Ό                        β–Ό
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                       β”‚ build_workflow_  β”‚    β”‚   Trace Info    β”‚
                       β”‚ with_state()     β”‚    β”‚                 β”‚
                       β”‚                  β”‚    β”‚ - trace_id      β”‚
                       β”‚ - trace_info     β”‚    β”‚ - input         β”‚
                       β”‚ - user_query     β”‚    β”‚ - metadata      β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                       β”‚   AgentState     β”‚
                       β”‚                  β”‚
                       β”‚ - trace_info     β”‚
                       β”‚ - messages       β”‚
                       β”‚ - persona        β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                       β”‚   Workflow       β”‚
                       β”‚   Execution      β”‚
                       β”‚                  β”‚
                       β”‚ call_model()     β”‚
                       β”‚ - get_prompt()   β”‚
                       β”‚ - LLM call       β”‚
                       β”‚ - record_output()β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                       β”‚ should_continue()β”‚
                       β”‚                  β”‚
                       β”‚ record_session() β”‚
                       β”‚ with trace_info  β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                       β”‚ Freeplay Session β”‚
                       β”‚ Recording        β”‚
                       β”‚                  β”‚
                       β”‚ - Session ID     β”‚
                       β”‚ - Trace Info     β”‚
                       β”‚ - Input/Output   β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

## Trace Lifecycle

### 1. **Creation Phase**
- **Trigger:** User submits question
- **Location:** `submit_helper()`
- **Action:** Create trace with user input and metadata
- **Output:** `TraceInfo` object with `trace_id`

### 2. **Association Phase**
- **Trigger:** Workflow initialization
- **Location:** `build_workflow_with_state()`
- **Action:** Pass `trace_info` to workflow state
- **Output:** `AgentState` with trace context

### 3. **Processing Phase**
- **Trigger:** LLM interaction
- **Location:** `call_model()`
- **Action:** Record LLM output to trace
- **Output:** Trace with input/output pair

### 4. **Recording Phase**
- **Trigger:** Workflow completion
- **Location:** `should_continue()`
- **Action:** Associate trace with session recording
- **Output:** Complete session with trace linkage

## Benefits

### Enhanced Observability
- **Input/Output Tracking:** Complete visibility of user questions and LLM responses
- **Metadata Association:** Persona, user info, and interaction context
- **Performance Metrics:** Response times, tool usage, and evaluation results

### Debugging & Analysis
- **Trace Isolation:** Individual interactions can be analyzed separately
- **Session Context:** Traces maintain session-level context
- **Evaluation Support:** Built-in support for feedback and evaluation metrics

### Backward Compatibility
- **Optional Implementation:** Traces are opt-in, existing functionality unchanged
- **Graceful Degradation:** System works without traces if disabled
- **Incremental Rollout:** Can be enabled per user or session

## Implementation Phases

### Phase 1: AppState Enhancement
1. Add `freeplay_session` property to `AppState` class
2. Modify `ensure_sessions()` to store session object
3. Test session object storage and retrieval

### Phase 2: Workflow Integration
1. Update `AgentState` to include `trace_info` field
2. Modify `build_workflow_with_state()` to accept `trace_info` parameter
3. Update `call_model()` to record trace outputs
4. Update `should_continue()` to associate traces with sessions

### Phase 3: Server Integration
1. Update `submit_helper()` to create traces using session object
2. Pass `trace_info` through workflow initialization
3. Test complete trace lifecycle

### Phase 4: Session Recording Enhancement
1. Modify `record_session()` to accept `trace_info` parameter
2. Update `RecordPayload` to include trace information
3. Test session recording with trace association

### Phase 5: Testing & Validation
1. Unit tests for trace creation and recording
2. Integration tests for workflow trace integration
3. End-to-end tests for complete trace lifecycle
4. Performance impact assessment

## Risk Mitigation

### High Risk Areas
1. **Session State Management**
   - **Risk:** Breaking existing session flow
   - **Mitigation:** Optional trace parameters, backward compatibility

2. **Workflow State Changes**
   - **Risk:** Breaking existing state structure
   - **Mitigation:** Optional fields with defaults, thorough testing

### Medium Risk Areas
1. **Performance Impact**
   - **Risk:** Slowing down workflow execution
   - **Mitigation:** Lazy trace creation, optional features

2. **Data Consistency**
   - **Risk:** Trace/recording mismatches
   - **Mitigation:** Validation and error handling

## Success Criteria

1. **Functionality:** Traces created and recorded for all user interactions
2. **Performance:** No measurable impact on workflow execution time
3. **Compatibility:** All existing functionality continues to work
4. **Observability:** Complete trace data available in Freeplay dashboard
5. **Reliability:** Graceful handling of trace creation/recording failures

## Next Steps

1. **User Approval:** Review and approve implementation plan
2. **Phase 1 Implementation:** Begin with core infrastructure
3. **Testing Strategy:** Validate each phase before proceeding
4. **Documentation:** Update API documentation with trace features
5. **Monitoring:** Implement trace-specific logging and metrics