webscout 8.2.6__py3-none-any.whl → 8.2.8__py3-none-any.whl
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.
Potentially problematic release.
This version of webscout might be problematic. Click here for more details.
- webscout/AIauto.py +1 -1
- webscout/AIutel.py +298 -239
- webscout/Extra/Act.md +309 -0
- webscout/Extra/GitToolkit/gitapi/README.md +110 -0
- webscout/Extra/YTToolkit/README.md +375 -0
- webscout/Extra/YTToolkit/ytapi/README.md +44 -0
- webscout/Extra/YTToolkit/ytapi/extras.py +92 -19
- webscout/Extra/autocoder/autocoder.py +309 -114
- webscout/Extra/autocoder/autocoder_utiles.py +15 -15
- webscout/Extra/gguf.md +430 -0
- webscout/Extra/tempmail/README.md +488 -0
- webscout/Extra/weather.md +281 -0
- webscout/Litlogger/Readme.md +175 -0
- webscout/Provider/AISEARCH/DeepFind.py +41 -37
- webscout/Provider/AISEARCH/README.md +279 -0
- webscout/Provider/AISEARCH/__init__.py +0 -1
- webscout/Provider/AISEARCH/genspark_search.py +228 -86
- webscout/Provider/AISEARCH/hika_search.py +11 -11
- webscout/Provider/AISEARCH/scira_search.py +324 -322
- webscout/Provider/AllenAI.py +7 -14
- webscout/Provider/Blackboxai.py +518 -74
- webscout/Provider/Cloudflare.py +0 -1
- webscout/Provider/Deepinfra.py +23 -21
- webscout/Provider/Flowith.py +217 -0
- webscout/Provider/FreeGemini.py +250 -0
- webscout/Provider/GizAI.py +15 -5
- webscout/Provider/Glider.py +11 -8
- webscout/Provider/HeckAI.py +80 -52
- webscout/Provider/Koboldai.py +7 -4
- webscout/Provider/LambdaChat.py +2 -2
- webscout/Provider/Marcus.py +10 -18
- webscout/Provider/OPENAI/BLACKBOXAI.py +735 -0
- webscout/Provider/OPENAI/Cloudflare.py +378 -0
- webscout/Provider/OPENAI/FreeGemini.py +282 -0
- webscout/Provider/OPENAI/NEMOTRON.py +244 -0
- webscout/Provider/OPENAI/README.md +1253 -0
- webscout/Provider/OPENAI/__init__.py +8 -0
- webscout/Provider/OPENAI/ai4chat.py +293 -286
- webscout/Provider/OPENAI/api.py +810 -0
- webscout/Provider/OPENAI/base.py +217 -14
- webscout/Provider/OPENAI/c4ai.py +373 -367
- webscout/Provider/OPENAI/chatgpt.py +7 -0
- webscout/Provider/OPENAI/chatgptclone.py +7 -0
- webscout/Provider/OPENAI/chatsandbox.py +172 -0
- webscout/Provider/OPENAI/deepinfra.py +30 -20
- webscout/Provider/OPENAI/e2b.py +6 -0
- webscout/Provider/OPENAI/exaai.py +7 -0
- webscout/Provider/OPENAI/exachat.py +6 -0
- webscout/Provider/OPENAI/flowith.py +162 -0
- webscout/Provider/OPENAI/freeaichat.py +359 -352
- webscout/Provider/OPENAI/glider.py +323 -316
- webscout/Provider/OPENAI/groq.py +361 -354
- webscout/Provider/OPENAI/heckai.py +30 -64
- webscout/Provider/OPENAI/llmchatco.py +8 -0
- webscout/Provider/OPENAI/mcpcore.py +7 -0
- webscout/Provider/OPENAI/multichat.py +8 -0
- webscout/Provider/OPENAI/netwrck.py +356 -350
- webscout/Provider/OPENAI/opkfc.py +8 -0
- webscout/Provider/OPENAI/scirachat.py +471 -462
- webscout/Provider/OPENAI/sonus.py +9 -0
- webscout/Provider/OPENAI/standardinput.py +9 -1
- webscout/Provider/OPENAI/textpollinations.py +339 -329
- webscout/Provider/OPENAI/toolbaz.py +7 -0
- webscout/Provider/OPENAI/typefully.py +355 -0
- webscout/Provider/OPENAI/typegpt.py +358 -346
- webscout/Provider/OPENAI/uncovrAI.py +7 -0
- webscout/Provider/OPENAI/utils.py +103 -7
- webscout/Provider/OPENAI/venice.py +12 -0
- webscout/Provider/OPENAI/wisecat.py +19 -19
- webscout/Provider/OPENAI/writecream.py +7 -0
- webscout/Provider/OPENAI/x0gpt.py +7 -0
- webscout/Provider/OPENAI/yep.py +50 -21
- webscout/Provider/OpenGPT.py +1 -1
- webscout/Provider/TTI/AiForce/README.md +159 -0
- webscout/Provider/TTI/FreeAIPlayground/README.md +99 -0
- webscout/Provider/TTI/ImgSys/README.md +174 -0
- webscout/Provider/TTI/MagicStudio/README.md +101 -0
- webscout/Provider/TTI/Nexra/README.md +155 -0
- webscout/Provider/TTI/PollinationsAI/README.md +146 -0
- webscout/Provider/TTI/README.md +128 -0
- webscout/Provider/TTI/aiarta/README.md +134 -0
- webscout/Provider/TTI/artbit/README.md +100 -0
- webscout/Provider/TTI/fastflux/README.md +129 -0
- webscout/Provider/TTI/huggingface/README.md +114 -0
- webscout/Provider/TTI/piclumen/README.md +161 -0
- webscout/Provider/TTI/pixelmuse/README.md +79 -0
- webscout/Provider/TTI/talkai/README.md +139 -0
- webscout/Provider/TTS/README.md +192 -0
- webscout/Provider/TTS/__init__.py +2 -1
- webscout/Provider/TTS/speechma.py +500 -100
- webscout/Provider/TTS/sthir.py +94 -0
- webscout/Provider/TeachAnything.py +3 -7
- webscout/Provider/TextPollinationsAI.py +4 -2
- webscout/Provider/{aimathgpt.py → UNFINISHED/ChatHub.py} +88 -68
- webscout/Provider/UNFINISHED/liner_api_request.py +263 -0
- webscout/Provider/UNFINISHED/oivscode.py +351 -0
- webscout/Provider/UNFINISHED/test_lmarena.py +119 -0
- webscout/Provider/Writecream.py +11 -2
- webscout/Provider/__init__.py +8 -14
- webscout/Provider/ai4chat.py +4 -58
- webscout/Provider/asksteve.py +17 -9
- webscout/Provider/cerebras.py +3 -1
- webscout/Provider/koala.py +170 -268
- webscout/Provider/llmchat.py +3 -0
- webscout/Provider/lmarena.py +198 -0
- webscout/Provider/meta.py +7 -4
- webscout/Provider/samurai.py +223 -0
- webscout/Provider/scira_chat.py +4 -2
- webscout/Provider/typefully.py +23 -151
- webscout/__init__.py +4 -2
- webscout/cli.py +3 -28
- webscout/conversation.py +35 -35
- webscout/litagent/Readme.md +276 -0
- webscout/scout/README.md +402 -0
- webscout/swiftcli/Readme.md +323 -0
- webscout/version.py +1 -1
- webscout/webscout_search.py +2 -182
- webscout/webscout_search_async.py +1 -179
- webscout/zeroart/README.md +89 -0
- webscout/zeroart/__init__.py +134 -54
- webscout/zeroart/base.py +19 -13
- webscout/zeroart/effects.py +101 -99
- webscout/zeroart/fonts.py +1239 -816
- {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/METADATA +116 -74
- {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/RECORD +130 -103
- {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/WHEEL +1 -1
- webscout-8.2.8.dist-info/entry_points.txt +3 -0
- webscout-8.2.8.dist-info/top_level.txt +1 -0
- webscout/Provider/AISEARCH/ISou.py +0 -256
- webscout/Provider/ElectronHub.py +0 -773
- webscout/Provider/Free2GPT.py +0 -241
- webscout/Provider/GPTWeb.py +0 -249
- webscout/Provider/bagoodex.py +0 -145
- webscout/Provider/geminiprorealtime.py +0 -160
- webscout/scout/core.py +0 -881
- webscout-8.2.6.dist-info/entry_points.txt +0 -3
- webscout-8.2.6.dist-info/top_level.txt +0 -2
- webstoken/__init__.py +0 -30
- webstoken/classifier.py +0 -189
- webstoken/keywords.py +0 -216
- webstoken/language.py +0 -128
- webstoken/ner.py +0 -164
- webstoken/normalizer.py +0 -35
- webstoken/processor.py +0 -77
- webstoken/sentiment.py +0 -206
- webstoken/stemmer.py +0 -73
- webstoken/tagger.py +0 -60
- webstoken/tokenizer.py +0 -158
- /webscout/Provider/{Youchat.py → UNFINISHED/Youchat.py} +0 -0
- {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/licenses/LICENSE.md +0 -0
webscout/AIauto.py
CHANGED
webscout/AIutel.py
CHANGED
|
@@ -1,240 +1,299 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if not
|
|
24
|
-
return None
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
sanitized_chunk = sanitized_chunk
|
|
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
|
-
if
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
yield
|
|
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
|
-
|
|
1
|
+
import json
|
|
2
|
+
from typing import Union, Optional, Dict, Any, Iterable, Generator, List, Callable, Literal
|
|
3
|
+
import codecs
|
|
4
|
+
|
|
5
|
+
# Expanded encoding types
|
|
6
|
+
EncodingType = Literal['utf-8', 'utf-16', 'utf-32', 'ascii', 'latin1', 'cp1252', 'iso-8859-1',
|
|
7
|
+
'iso-8859-2', 'windows-1250', 'windows-1251', 'windows-1252', 'gbk', 'big5',
|
|
8
|
+
'shift_jis', 'euc-jp', 'euc-kr']
|
|
9
|
+
|
|
10
|
+
def _process_chunk(
|
|
11
|
+
chunk: str,
|
|
12
|
+
intro_value: str,
|
|
13
|
+
to_json: bool,
|
|
14
|
+
skip_markers: List[str],
|
|
15
|
+
strip_chars: Optional[str],
|
|
16
|
+
yield_raw_on_error: bool,
|
|
17
|
+
) -> Union[str, Dict[str, Any], None]:
|
|
18
|
+
"""Internal helper to sanitize and potentially parse a single chunk."""
|
|
19
|
+
if not isinstance(chunk, str):
|
|
20
|
+
return None
|
|
21
|
+
|
|
22
|
+
# Fast path for empty chunks
|
|
23
|
+
if not chunk:
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
# Use slicing for prefix removal (faster than startswith+slicing)
|
|
27
|
+
sanitized_chunk = chunk
|
|
28
|
+
if intro_value and len(chunk) >= len(intro_value) and chunk[:len(intro_value)] == intro_value:
|
|
29
|
+
sanitized_chunk = chunk[len(intro_value):]
|
|
30
|
+
|
|
31
|
+
# Optimize string stripping operations
|
|
32
|
+
if strip_chars is not None:
|
|
33
|
+
sanitized_chunk = sanitized_chunk.strip(strip_chars)
|
|
34
|
+
else:
|
|
35
|
+
# lstrip() is faster than strip() when we only need leading whitespace removed
|
|
36
|
+
sanitized_chunk = sanitized_chunk.lstrip()
|
|
37
|
+
|
|
38
|
+
# Skip empty chunks and markers
|
|
39
|
+
if not sanitized_chunk or any(marker == sanitized_chunk for marker in skip_markers):
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
# JSON parsing with optimized error handling
|
|
43
|
+
if to_json:
|
|
44
|
+
try:
|
|
45
|
+
# Only strip before JSON parsing if needed
|
|
46
|
+
if sanitized_chunk[0] not in '{[' or sanitized_chunk[-1] not in '}]':
|
|
47
|
+
sanitized_chunk = sanitized_chunk.strip()
|
|
48
|
+
return json.loads(sanitized_chunk)
|
|
49
|
+
except (json.JSONDecodeError, Exception):
|
|
50
|
+
return sanitized_chunk if yield_raw_on_error else None
|
|
51
|
+
|
|
52
|
+
return sanitized_chunk
|
|
53
|
+
|
|
54
|
+
def _decode_byte_stream(
|
|
55
|
+
byte_iterator: Iterable[bytes],
|
|
56
|
+
encoding: EncodingType = 'utf-8',
|
|
57
|
+
errors: str = 'replace',
|
|
58
|
+
buffer_size: int = 8192
|
|
59
|
+
) -> Generator[str, None, None]:
|
|
60
|
+
"""
|
|
61
|
+
Realtime byte stream decoder with flexible encoding support.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
byte_iterator: Iterator yielding bytes
|
|
65
|
+
encoding: Character encoding to use
|
|
66
|
+
errors: How to handle encoding errors ('strict', 'ignore', 'replace')
|
|
67
|
+
buffer_size: Size of internal buffer for performance tuning
|
|
68
|
+
"""
|
|
69
|
+
# Initialize decoder with the specified encoding
|
|
70
|
+
try:
|
|
71
|
+
decoder = codecs.getincrementaldecoder(encoding)(errors=errors)
|
|
72
|
+
except LookupError:
|
|
73
|
+
# Fallback to utf-8 if the encoding is not supported
|
|
74
|
+
decoder = codecs.getincrementaldecoder('utf-8')(errors=errors)
|
|
75
|
+
|
|
76
|
+
# Process byte stream in realtime
|
|
77
|
+
buffer = bytearray(buffer_size)
|
|
78
|
+
buffer_view = memoryview(buffer)
|
|
79
|
+
|
|
80
|
+
for chunk_bytes in byte_iterator:
|
|
81
|
+
if not chunk_bytes:
|
|
82
|
+
continue
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
# Use buffer for processing if chunk size is appropriate
|
|
86
|
+
if len(chunk_bytes) <= buffer_size:
|
|
87
|
+
buffer[:len(chunk_bytes)] = chunk_bytes
|
|
88
|
+
text = decoder.decode(buffer_view[:len(chunk_bytes)], final=False)
|
|
89
|
+
else:
|
|
90
|
+
text = decoder.decode(chunk_bytes, final=False)
|
|
91
|
+
|
|
92
|
+
if text:
|
|
93
|
+
yield text
|
|
94
|
+
except UnicodeDecodeError:
|
|
95
|
+
yield f"[Encoding Error: Could not decode bytes with {encoding}]\n"
|
|
96
|
+
|
|
97
|
+
# Final flush
|
|
98
|
+
try:
|
|
99
|
+
final_text = decoder.decode(b'', final=True)
|
|
100
|
+
if final_text:
|
|
101
|
+
yield final_text
|
|
102
|
+
except UnicodeDecodeError:
|
|
103
|
+
yield f"[Encoding Error: Could not decode final bytes with {encoding}]\n"
|
|
104
|
+
|
|
105
|
+
def sanitize_stream(
|
|
106
|
+
data: Union[str, Iterable[str], Iterable[bytes]],
|
|
107
|
+
intro_value: str = "data:",
|
|
108
|
+
to_json: bool = True,
|
|
109
|
+
skip_markers: Optional[List[str]] = None,
|
|
110
|
+
strip_chars: Optional[str] = None,
|
|
111
|
+
start_marker: Optional[str] = None,
|
|
112
|
+
end_marker: Optional[str] = None,
|
|
113
|
+
content_extractor: Optional[Callable[[Union[str, Dict[str, Any]]], Optional[Any]]] = None,
|
|
114
|
+
yield_raw_on_error: bool = True,
|
|
115
|
+
encoding: EncodingType = 'utf-8',
|
|
116
|
+
encoding_errors: str = 'replace',
|
|
117
|
+
buffer_size: int = 8192,
|
|
118
|
+
) -> Generator[Any, None, None]:
|
|
119
|
+
"""
|
|
120
|
+
Robust realtime stream processor that handles string/byte streams with correct marker extraction/skipping.
|
|
121
|
+
Now handles split markers, partial chunks, and skips lines containing (not just equal to) skip markers.
|
|
122
|
+
"""
|
|
123
|
+
effective_skip_markers = skip_markers or []
|
|
124
|
+
processing_active = start_marker is None
|
|
125
|
+
buffer = ""
|
|
126
|
+
found_start = False if start_marker else True
|
|
127
|
+
|
|
128
|
+
# Fast path for single string processing
|
|
129
|
+
if isinstance(data, str):
|
|
130
|
+
processed_item = None
|
|
131
|
+
if processing_active:
|
|
132
|
+
if to_json:
|
|
133
|
+
try:
|
|
134
|
+
data = data.strip()
|
|
135
|
+
if data:
|
|
136
|
+
processed_item = json.loads(data)
|
|
137
|
+
except json.JSONDecodeError:
|
|
138
|
+
processed_item = data if yield_raw_on_error else None
|
|
139
|
+
else:
|
|
140
|
+
processed_item = _process_chunk(
|
|
141
|
+
data, intro_value, False, effective_skip_markers,
|
|
142
|
+
strip_chars, yield_raw_on_error
|
|
143
|
+
)
|
|
144
|
+
if processed_item is not None:
|
|
145
|
+
if content_extractor:
|
|
146
|
+
try:
|
|
147
|
+
final_content = content_extractor(processed_item)
|
|
148
|
+
if final_content is not None:
|
|
149
|
+
yield final_content
|
|
150
|
+
except Exception:
|
|
151
|
+
pass
|
|
152
|
+
else:
|
|
153
|
+
yield processed_item
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
# Stream processing path
|
|
157
|
+
if not hasattr(data, '__iter__'):
|
|
158
|
+
raise TypeError(f"Input must be a string or an iterable, not {type(data).__name__}")
|
|
159
|
+
|
|
160
|
+
try:
|
|
161
|
+
iterator = iter(data)
|
|
162
|
+
first_item = next(iterator, None)
|
|
163
|
+
if first_item is None:
|
|
164
|
+
return
|
|
165
|
+
from itertools import chain
|
|
166
|
+
stream = chain([first_item], iterator)
|
|
167
|
+
|
|
168
|
+
# Determine if we're dealing with bytes or strings
|
|
169
|
+
if isinstance(first_item, bytes):
|
|
170
|
+
line_iterator = _decode_byte_stream(
|
|
171
|
+
stream,
|
|
172
|
+
encoding=encoding,
|
|
173
|
+
errors=encoding_errors,
|
|
174
|
+
buffer_size=buffer_size
|
|
175
|
+
)
|
|
176
|
+
elif isinstance(first_item, str):
|
|
177
|
+
line_iterator = stream
|
|
178
|
+
else:
|
|
179
|
+
raise TypeError(f"Stream must yield strings or bytes, not {type(first_item).__name__}")
|
|
180
|
+
|
|
181
|
+
for line in line_iterator:
|
|
182
|
+
if not line:
|
|
183
|
+
continue
|
|
184
|
+
buffer += line
|
|
185
|
+
while True:
|
|
186
|
+
# Look for start marker if needed
|
|
187
|
+
if not found_start and start_marker:
|
|
188
|
+
idx = buffer.find(start_marker)
|
|
189
|
+
if idx != -1:
|
|
190
|
+
found_start = True
|
|
191
|
+
buffer = buffer[idx + len(start_marker):]
|
|
192
|
+
else:
|
|
193
|
+
# Not found, keep buffering
|
|
194
|
+
buffer = buffer[-max(len(start_marker), 256):] # avoid unbounded growth
|
|
195
|
+
break
|
|
196
|
+
# Look for end marker if needed
|
|
197
|
+
if found_start and end_marker:
|
|
198
|
+
idx = buffer.find(end_marker)
|
|
199
|
+
if idx != -1:
|
|
200
|
+
chunk = buffer[:idx]
|
|
201
|
+
buffer = buffer[idx + len(end_marker):]
|
|
202
|
+
processing_active = False
|
|
203
|
+
else:
|
|
204
|
+
chunk = buffer
|
|
205
|
+
buffer = ""
|
|
206
|
+
processing_active = True
|
|
207
|
+
# Process chunk if we are in active region
|
|
208
|
+
if chunk and processing_active:
|
|
209
|
+
# Split into lines for skip marker logic
|
|
210
|
+
for subline in chunk.splitlines():
|
|
211
|
+
# Remove intro_value prefix if present
|
|
212
|
+
if intro_value and subline.startswith(intro_value):
|
|
213
|
+
subline = subline[len(intro_value):]
|
|
214
|
+
# Strip chars if needed
|
|
215
|
+
if strip_chars is not None:
|
|
216
|
+
subline = subline.strip(strip_chars)
|
|
217
|
+
else:
|
|
218
|
+
subline = subline.lstrip()
|
|
219
|
+
# Skip if matches any skip marker (using 'in')
|
|
220
|
+
if any(marker in subline for marker in effective_skip_markers):
|
|
221
|
+
continue
|
|
222
|
+
# Skip empty
|
|
223
|
+
if not subline:
|
|
224
|
+
continue
|
|
225
|
+
# JSON parse if needed
|
|
226
|
+
if to_json:
|
|
227
|
+
try:
|
|
228
|
+
if subline and (subline[0] in '{[' and subline[-1] in '}]'):
|
|
229
|
+
parsed = json.loads(subline)
|
|
230
|
+
result = parsed
|
|
231
|
+
else:
|
|
232
|
+
result = subline
|
|
233
|
+
except Exception:
|
|
234
|
+
result = subline if yield_raw_on_error else None
|
|
235
|
+
else:
|
|
236
|
+
result = subline
|
|
237
|
+
if result is not None:
|
|
238
|
+
if content_extractor:
|
|
239
|
+
try:
|
|
240
|
+
final_content = content_extractor(result)
|
|
241
|
+
if final_content is not None:
|
|
242
|
+
yield final_content
|
|
243
|
+
except Exception:
|
|
244
|
+
pass
|
|
245
|
+
else:
|
|
246
|
+
yield result
|
|
247
|
+
if not processing_active:
|
|
248
|
+
found_start = False
|
|
249
|
+
if idx == -1:
|
|
250
|
+
break
|
|
251
|
+
elif found_start:
|
|
252
|
+
# No end marker, process all buffered content
|
|
253
|
+
chunk = buffer
|
|
254
|
+
buffer = ""
|
|
255
|
+
if chunk:
|
|
256
|
+
for subline in chunk.splitlines():
|
|
257
|
+
if intro_value and subline.startswith(intro_value):
|
|
258
|
+
subline = subline[len(intro_value):]
|
|
259
|
+
if strip_chars is not None:
|
|
260
|
+
subline = subline.strip(strip_chars)
|
|
261
|
+
else:
|
|
262
|
+
subline = subline.lstrip()
|
|
263
|
+
if any(marker in subline for marker in effective_skip_markers):
|
|
264
|
+
continue
|
|
265
|
+
if not subline:
|
|
266
|
+
continue
|
|
267
|
+
if to_json:
|
|
268
|
+
try:
|
|
269
|
+
if subline and (subline[0] in '{[' and subline[-1] in '}]'):
|
|
270
|
+
parsed = json.loads(subline)
|
|
271
|
+
result = parsed
|
|
272
|
+
else:
|
|
273
|
+
result = subline
|
|
274
|
+
except Exception:
|
|
275
|
+
result = subline if yield_raw_on_error else None
|
|
276
|
+
else:
|
|
277
|
+
result = subline
|
|
278
|
+
if result is not None:
|
|
279
|
+
if content_extractor:
|
|
280
|
+
try:
|
|
281
|
+
final_content = content_extractor(result)
|
|
282
|
+
if final_content is not None:
|
|
283
|
+
yield final_content
|
|
284
|
+
except Exception:
|
|
285
|
+
pass
|
|
286
|
+
else:
|
|
287
|
+
yield result
|
|
288
|
+
break
|
|
289
|
+
else:
|
|
290
|
+
break
|
|
291
|
+
except Exception as e:
|
|
292
|
+
import sys
|
|
293
|
+
print(f"Stream processing error: {str(e)}", file=sys.stderr)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
from .conversation import Conversation
|
|
297
|
+
from .optimizers import Optimizers
|
|
298
|
+
from .Extra.autocoder import AutoCoder
|
|
240
299
|
from .prompt_manager import AwesomePrompts
|