devme commited on
Commit
81cf97e
·
verified ·
1 Parent(s): 3bd4af7

Delete claude_stream.py

Browse files
Files changed (1) hide show
  1. claude_stream.py +0 -145
claude_stream.py DELETED
@@ -1,145 +0,0 @@
1
- import json
2
- import logging
3
- from pathlib import Path
4
- from typing import AsyncGenerator, Optional, Dict, Any, List, Set
5
-
6
- from utils import load_module
7
-
8
- logger = logging.getLogger(__name__)
9
-
10
- _parser = load_module("v2_claude_parser", "claude_parser.py")
11
- build_message_start = _parser.build_message_start
12
- build_content_block_start = _parser.build_content_block_start
13
- build_content_block_delta = _parser.build_content_block_delta
14
- build_content_block_stop = _parser.build_content_block_stop
15
- build_ping = _parser.build_ping
16
- build_message_stop = _parser.build_message_stop
17
- build_tool_use_start = _parser.build_tool_use_start
18
- build_tool_use_input_delta = _parser.build_tool_use_input_delta
19
-
20
- class ClaudeStreamHandler:
21
- def __init__(self, model: str, input_tokens: int = 0):
22
- self.model = model
23
- self.input_tokens = input_tokens
24
- self.response_buffer: List[str] = []
25
- self.content_block_index: int = -1
26
- self.content_block_started: bool = False
27
- self.content_block_start_sent: bool = False
28
- self.content_block_stop_sent: bool = False
29
- self.message_start_sent: bool = False
30
- self.conversation_id: Optional[str] = None
31
-
32
- # Tool use state
33
- self.current_tool_use: Optional[Dict[str, Any]] = None
34
- self.tool_input_buffer: List[str] = []
35
- self.tool_use_id: Optional[str] = None
36
- self.tool_name: Optional[str] = None
37
- self._processed_tool_use_ids: Set[str] = set()
38
- self.all_tool_inputs: List[str] = []
39
-
40
- async def handle_event(self, event_type: str, payload: Dict[str, Any]) -> AsyncGenerator[str, None]:
41
- """Process a single Amazon Q event and yield Claude SSE events."""
42
-
43
- # 1. Message Start (initial-response)
44
- if event_type == "initial-response":
45
- if not self.message_start_sent:
46
- conv_id = payload.get('conversationId', self.conversation_id or 'unknown')
47
- self.conversation_id = conv_id
48
- yield build_message_start(conv_id, self.model, self.input_tokens)
49
- self.message_start_sent = True
50
- yield build_ping()
51
-
52
- # 2. Content Block Delta (assistantResponseEvent)
53
- elif event_type == "assistantResponseEvent":
54
- content = payload.get("content", "")
55
-
56
- # Close any open tool use block
57
- if self.current_tool_use and not self.content_block_stop_sent:
58
- yield build_content_block_stop(self.content_block_index)
59
- self.content_block_stop_sent = True
60
- self.current_tool_use = None
61
-
62
- # Start content block if needed
63
- if not self.content_block_start_sent:
64
- self.content_block_index += 1
65
- yield build_content_block_start(self.content_block_index, "text")
66
- self.content_block_start_sent = True
67
- self.content_block_started = True
68
-
69
- # Send delta
70
- if content:
71
- self.response_buffer.append(content)
72
- yield build_content_block_delta(self.content_block_index, content)
73
-
74
- # 3. Tool Use (toolUseEvent)
75
- elif event_type == "toolUseEvent":
76
- tool_use_id = payload.get("toolUseId")
77
- tool_name = payload.get("name")
78
- tool_input = payload.get("input", {})
79
- is_stop = payload.get("stop", False)
80
-
81
- # Start new tool use
82
- if tool_use_id and tool_name and not self.current_tool_use:
83
- # Close previous text block if open
84
- if self.content_block_start_sent and not self.content_block_stop_sent:
85
- yield build_content_block_stop(self.content_block_index)
86
- self.content_block_stop_sent = True
87
-
88
- self._processed_tool_use_ids.add(tool_use_id)
89
- self.content_block_index += 1
90
-
91
- yield build_tool_use_start(self.content_block_index, tool_use_id, tool_name)
92
-
93
- self.content_block_started = True
94
- self.current_tool_use = {"toolUseId": tool_use_id, "name": tool_name}
95
- self.tool_use_id = tool_use_id
96
- self.tool_name = tool_name
97
- self.tool_input_buffer = []
98
- self.content_block_stop_sent = False
99
- self.content_block_start_sent = True
100
-
101
- # Accumulate input
102
- if self.current_tool_use and tool_input:
103
- fragment = ""
104
- if isinstance(tool_input, str):
105
- fragment = tool_input
106
- else:
107
- fragment = json.dumps(tool_input, ensure_ascii=False)
108
-
109
- self.tool_input_buffer.append(fragment)
110
- yield build_tool_use_input_delta(self.content_block_index, fragment)
111
-
112
- # Stop tool use
113
- if is_stop and self.current_tool_use:
114
- full_input = "".join(self.tool_input_buffer)
115
- self.all_tool_inputs.append(full_input)
116
-
117
- yield build_content_block_stop(self.content_block_index)
118
- self.content_block_stop_sent = True
119
- self.content_block_started = False
120
- self.current_tool_use = None
121
- self.tool_use_id = None
122
- self.tool_name = None
123
- self.tool_input_buffer = []
124
-
125
- # 4. Assistant Response End (assistantResponseEnd)
126
- elif event_type == "assistantResponseEnd":
127
- # Close any open block
128
- if self.content_block_started and not self.content_block_stop_sent:
129
- yield build_content_block_stop(self.content_block_index)
130
- self.content_block_stop_sent = True
131
-
132
- async def finish(self) -> AsyncGenerator[str, None]:
133
- """Send final events."""
134
- # Ensure last block is closed
135
- if self.content_block_started and not self.content_block_stop_sent:
136
- yield build_content_block_stop(self.content_block_index)
137
- self.content_block_stop_sent = True
138
-
139
- # Calculate output tokens (approximate)
140
- full_text = "".join(self.response_buffer)
141
- full_tool_input = "".join(self.all_tool_inputs)
142
- # Simple approximation: 4 chars per token
143
- output_tokens = max(1, (len(full_text) + len(full_tool_input)) // 4)
144
-
145
- yield build_message_stop(self.input_tokens, output_tokens, "end_turn")