Parses structured log events.
| 140 | |
| 141 | |
| 142 | class LogParser: |
| 143 | """Parses structured log events.""" |
| 144 | |
| 145 | def __init__(self): |
| 146 | self.workflow = Workflow() |
| 147 | self._current_step: Optional[Step] = None |
| 148 | self._current_iteration: Optional[AgentIteration] = None |
| 149 | self._current_tool: Optional[Dict[str, Any]] = None |
| 150 | self._call_index: Dict[tuple, Dict[str, Any]] = {} |
| 151 | self._step_index: Dict[str, Step] = {} |
| 152 | self._iteration_index: Dict[tuple, AgentIteration] = {} |
| 153 | |
| 154 | def _get_step(self, step_id: str) -> Step: |
| 155 | step = self._step_index.get(step_id) |
| 156 | if step: |
| 157 | return step |
| 158 | step = Step( |
| 159 | step_id=step_id, |
| 160 | number=step_id, |
| 161 | name=f"Step {step_id}", |
| 162 | step_type="step", |
| 163 | ) |
| 164 | self._step_index[step_id] = step |
| 165 | self.workflow.steps.append(step) |
| 166 | return step |
| 167 | |
| 168 | def _get_iteration(self, step_id: str, iteration_number: int) -> AgentIteration: |
| 169 | key = (step_id, iteration_number) |
| 170 | iteration = self._iteration_index.get(key) |
| 171 | if iteration: |
| 172 | return iteration |
| 173 | step = self._get_step(step_id) |
| 174 | iteration = AgentIteration(number=iteration_number, max=0) |
| 175 | step.iterations.append(iteration) |
| 176 | self._iteration_index[key] = iteration |
| 177 | return iteration |
| 178 | |
| 179 | def parse_line(self, line: str) -> Optional[ParsedEvent]: |
| 180 | """Parse a single log line.""" |
| 181 | self.workflow.raw_lines.append(line) |
| 182 | |
| 183 | # Check for structured event |
| 184 | if EVENT_START in line and EVENT_END in line: |
| 185 | try: |
| 186 | start = line.index(EVENT_START) + len(EVENT_START) |
| 187 | end = line.index(EVENT_END) |
| 188 | event_json = line[start:end] |
| 189 | event_data = json.loads(event_json) |
| 190 | event = ParsedEvent( |
| 191 | type=event_data.get("type", "unknown"), |
| 192 | timestamp=event_data.get("timestamp", ""), |
| 193 | data=event_data.get("data", {}), |
| 194 | raw_line=line, |
| 195 | ) |
| 196 | self._process_event(event) |
| 197 | return event |
| 198 | except (json.JSONDecodeError, ValueError): |
| 199 | pass |
no outgoing calls
no test coverage detected