webscout 8.2.5__py3-none-any.whl → 8.2.6__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 +112 -22
- webscout/AIutel.py +240 -344
- webscout/Extra/autocoder/autocoder.py +66 -5
- webscout/Provider/AISEARCH/scira_search.py +2 -1
- webscout/Provider/GizAI.py +6 -4
- webscout/Provider/Nemotron.py +218 -0
- webscout/Provider/OPENAI/scirachat.py +2 -1
- webscout/Provider/TeachAnything.py +8 -5
- webscout/Provider/WiseCat.py +1 -1
- webscout/Provider/WrDoChat.py +370 -0
- webscout/Provider/__init__.py +4 -6
- webscout/Provider/ai4chat.py +5 -3
- webscout/Provider/akashgpt.py +59 -66
- webscout/Provider/freeaichat.py +57 -43
- webscout/Provider/scira_chat.py +2 -1
- webscout/Provider/scnet.py +4 -1
- webscout/__init__.py +0 -1
- webscout/conversation.py +305 -446
- webscout/swiftcli/__init__.py +80 -794
- webscout/swiftcli/core/__init__.py +7 -0
- webscout/swiftcli/core/cli.py +297 -0
- webscout/swiftcli/core/context.py +104 -0
- webscout/swiftcli/core/group.py +241 -0
- webscout/swiftcli/decorators/__init__.py +28 -0
- webscout/swiftcli/decorators/command.py +221 -0
- webscout/swiftcli/decorators/options.py +220 -0
- webscout/swiftcli/decorators/output.py +252 -0
- webscout/swiftcli/exceptions.py +21 -0
- webscout/swiftcli/plugins/__init__.py +9 -0
- webscout/swiftcli/plugins/base.py +135 -0
- webscout/swiftcli/plugins/manager.py +262 -0
- webscout/swiftcli/utils/__init__.py +59 -0
- webscout/swiftcli/utils/formatting.py +252 -0
- webscout/swiftcli/utils/parsing.py +267 -0
- webscout/version.py +1 -1
- {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/METADATA +1 -1
- {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/RECORD +41 -28
- webscout/LLM.py +0 -442
- webscout/Provider/PizzaGPT.py +0 -228
- webscout/Provider/promptrefine.py +0 -193
- webscout/Provider/tutorai.py +0 -270
- {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/WHEEL +0 -0
- {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/entry_points.txt +0 -0
- {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.2.5.dist-info → webscout-8.2.6.dist-info}/top_level.txt +0 -0
webscout/AIutel.py
CHANGED
|
@@ -1,344 +1,240 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import platform
|
|
3
|
-
import subprocess
|
|
4
|
-
from typing import Union, Optional, Dict, Any, Iterable, Generator, List, Callable
|
|
5
|
-
import io
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
#
|
|
29
|
-
if
|
|
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
|
-
pass
|
|
161
|
-
|
|
162
|
-
if processed_item is None:
|
|
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
|
-
line_iterator =
|
|
206
|
-
else:
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
#
|
|
210
|
-
for line in line_iterator:
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
if processed is not None:
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
final_content
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
exit_on_error: bool = True,
|
|
242
|
-
stdout_error: bool = True,
|
|
243
|
-
help: str = None,
|
|
244
|
-
):
|
|
245
|
-
"""Run commands against system
|
|
246
|
-
Args:
|
|
247
|
-
command (str): shell command
|
|
248
|
-
exit_on_error (bool, optional): Exit on error. Defaults to True.
|
|
249
|
-
stdout_error (bool, optional): Print out the error. Defaults to True
|
|
250
|
-
help (str, optional): Help info in case of exception. Defaults to None.
|
|
251
|
-
Returns:
|
|
252
|
-
tuple : (is_successful, object[Exception|Subprocess.run])
|
|
253
|
-
"""
|
|
254
|
-
try:
|
|
255
|
-
# Run the command and capture the output
|
|
256
|
-
result = subprocess.run(
|
|
257
|
-
command,
|
|
258
|
-
shell=True,
|
|
259
|
-
check=True,
|
|
260
|
-
text=True,
|
|
261
|
-
stdout=subprocess.PIPE,
|
|
262
|
-
stderr=subprocess.PIPE,
|
|
263
|
-
)
|
|
264
|
-
return (True, result)
|
|
265
|
-
except subprocess.CalledProcessError as e:
|
|
266
|
-
if exit_on_error:
|
|
267
|
-
raise Exception(f"Command failed with exit code {e.returncode}") from e
|
|
268
|
-
else:
|
|
269
|
-
return (False, e)
|
|
270
|
-
|
|
271
|
-
class Updates:
|
|
272
|
-
"""Webscout latest release info"""
|
|
273
|
-
|
|
274
|
-
url = "https://api.github.com/repos/OE-LUCIFER/Webscout/releases/latest"
|
|
275
|
-
|
|
276
|
-
@property
|
|
277
|
-
def latest_version(self):
|
|
278
|
-
return self.latest(version=True)
|
|
279
|
-
|
|
280
|
-
def executable(self, system: str = platform.system()) -> str:
|
|
281
|
-
"""Url pointing to executable for particular system
|
|
282
|
-
|
|
283
|
-
Args:
|
|
284
|
-
system (str, optional): system name. Defaults to platform.system().
|
|
285
|
-
|
|
286
|
-
Returns:
|
|
287
|
-
str: url
|
|
288
|
-
"""
|
|
289
|
-
for entry in self.latest()["assets"]:
|
|
290
|
-
if entry.get("target") == system:
|
|
291
|
-
return entry.get("url")
|
|
292
|
-
|
|
293
|
-
def latest(self, whole: bool = False, version: bool = False) -> dict:
|
|
294
|
-
"""Check Webscout latest version info
|
|
295
|
-
|
|
296
|
-
Args:
|
|
297
|
-
whole (bool, optional): Return whole json response. Defaults to False.
|
|
298
|
-
version (bool, optional): return version only. Defaults to False.
|
|
299
|
-
|
|
300
|
-
Returns:
|
|
301
|
-
bool|dict: version str or whole dict info
|
|
302
|
-
"""
|
|
303
|
-
import requests
|
|
304
|
-
|
|
305
|
-
data = requests.get(self.url).json()
|
|
306
|
-
if whole:
|
|
307
|
-
return data
|
|
308
|
-
|
|
309
|
-
elif version:
|
|
310
|
-
return data.get("tag_name")
|
|
311
|
-
|
|
312
|
-
else:
|
|
313
|
-
sorted = dict(
|
|
314
|
-
tag_name=data.get("tag_name"),
|
|
315
|
-
tarball_url=data.get("tarball_url"),
|
|
316
|
-
zipball_url=data.get("zipball_url"),
|
|
317
|
-
html_url=data.get("html_url"),
|
|
318
|
-
body=data.get("body"),
|
|
319
|
-
)
|
|
320
|
-
whole_assets = []
|
|
321
|
-
for entry in data.get("assets"):
|
|
322
|
-
url = entry.get("browser_download_url")
|
|
323
|
-
assets = dict(url=url, size=entry.get("size"))
|
|
324
|
-
if ".deb" in url:
|
|
325
|
-
assets["target"] = "Debian"
|
|
326
|
-
elif ".exe" in url:
|
|
327
|
-
assets["target"] = "Windows"
|
|
328
|
-
elif "macos" in url:
|
|
329
|
-
assets["target"] = "Mac"
|
|
330
|
-
elif "linux" in url:
|
|
331
|
-
assets["target"] = "Linux"
|
|
332
|
-
|
|
333
|
-
whole_assets.append(assets)
|
|
334
|
-
sorted["assets"] = whole_assets
|
|
335
|
-
|
|
336
|
-
return sorted
|
|
337
|
-
|
|
338
|
-
from .conversation import Conversation
|
|
339
|
-
|
|
340
|
-
from .optimizers import Optimizers
|
|
341
|
-
|
|
342
|
-
from .Extra.autocoder import AutoCoder
|
|
343
|
-
|
|
344
|
-
from .prompt_manager import AwesomePrompts
|
|
1
|
+
import json
|
|
2
|
+
import platform
|
|
3
|
+
import subprocess
|
|
4
|
+
from typing import Union, Optional, Dict, Any, Iterable, Generator, List, Callable, Literal, Tuple
|
|
5
|
+
import io
|
|
6
|
+
from collections import deque
|
|
7
|
+
import codecs
|
|
8
|
+
|
|
9
|
+
# Expanded encoding types
|
|
10
|
+
EncodingType = Literal['utf-8', 'utf-16', 'utf-32', 'ascii', 'latin1', 'cp1252', 'iso-8859-1',
|
|
11
|
+
'iso-8859-2', 'windows-1250', 'windows-1251', 'windows-1252', 'gbk', 'big5',
|
|
12
|
+
'shift_jis', 'euc-jp', 'euc-kr']
|
|
13
|
+
|
|
14
|
+
def _process_chunk(
|
|
15
|
+
chunk: str,
|
|
16
|
+
intro_value: str,
|
|
17
|
+
to_json: bool,
|
|
18
|
+
skip_markers: List[str],
|
|
19
|
+
strip_chars: Optional[str],
|
|
20
|
+
yield_raw_on_error: bool,
|
|
21
|
+
) -> Union[str, Dict[str, Any], None]:
|
|
22
|
+
"""Internal helper to sanitize and potentially parse a single chunk."""
|
|
23
|
+
if not isinstance(chunk, str):
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
sanitized_chunk = chunk
|
|
27
|
+
|
|
28
|
+
# Check if chunk starts with intro_value + skip_marker combination
|
|
29
|
+
if intro_value and skip_markers:
|
|
30
|
+
for marker in skip_markers:
|
|
31
|
+
combined_marker = f"{intro_value}{marker}"
|
|
32
|
+
if sanitized_chunk.startswith(combined_marker):
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
if intro_value and sanitized_chunk.startswith(intro_value):
|
|
36
|
+
sanitized_chunk = sanitized_chunk[len(intro_value):]
|
|
37
|
+
|
|
38
|
+
if strip_chars is not None:
|
|
39
|
+
sanitized_chunk = sanitized_chunk.strip(strip_chars)
|
|
40
|
+
else:
|
|
41
|
+
sanitized_chunk = sanitized_chunk.lstrip()
|
|
42
|
+
|
|
43
|
+
# Check both standalone skip_markers and stripped version
|
|
44
|
+
if not sanitized_chunk or any(
|
|
45
|
+
marker in sanitized_chunk or sanitized_chunk == marker
|
|
46
|
+
for marker in skip_markers
|
|
47
|
+
):
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
if to_json:
|
|
51
|
+
try:
|
|
52
|
+
return json.loads(sanitized_chunk)
|
|
53
|
+
except (json.JSONDecodeError, Exception) as e:
|
|
54
|
+
return sanitized_chunk if yield_raw_on_error else None
|
|
55
|
+
|
|
56
|
+
return sanitized_chunk
|
|
57
|
+
|
|
58
|
+
def _decode_byte_stream(
|
|
59
|
+
byte_iterator: Iterable[bytes],
|
|
60
|
+
encoding: EncodingType = 'utf-8',
|
|
61
|
+
errors: str = 'replace'
|
|
62
|
+
) -> Generator[str, None, None]:
|
|
63
|
+
"""
|
|
64
|
+
Realtime byte stream decoder with flexible encoding support.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
byte_iterator: Iterator yielding bytes
|
|
68
|
+
encoding: Character encoding to use
|
|
69
|
+
errors: How to handle encoding errors ('strict', 'ignore', 'replace')
|
|
70
|
+
"""
|
|
71
|
+
# Initialize decoder with the specified encoding
|
|
72
|
+
try:
|
|
73
|
+
decoder = codecs.getincrementaldecoder(encoding)(errors=errors)
|
|
74
|
+
except LookupError:
|
|
75
|
+
# Fallback to utf-8 if the encoding is not supported
|
|
76
|
+
decoder = codecs.getincrementaldecoder('utf-8')(errors=errors)
|
|
77
|
+
|
|
78
|
+
# Process byte stream in realtime
|
|
79
|
+
for chunk_bytes in byte_iterator:
|
|
80
|
+
if not chunk_bytes:
|
|
81
|
+
continue
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
# Decode chunk with specified encoding
|
|
85
|
+
text = decoder.decode(chunk_bytes, final=False)
|
|
86
|
+
if text:
|
|
87
|
+
yield text
|
|
88
|
+
except UnicodeDecodeError:
|
|
89
|
+
yield f"[Encoding Error: Could not decode bytes with {encoding}]\n"
|
|
90
|
+
|
|
91
|
+
# Final flush
|
|
92
|
+
try:
|
|
93
|
+
final_text = decoder.decode(b'', final=True)
|
|
94
|
+
if final_text:
|
|
95
|
+
yield final_text
|
|
96
|
+
except UnicodeDecodeError:
|
|
97
|
+
yield f"[Encoding Error: Could not decode final bytes with {encoding}]\n"
|
|
98
|
+
def sanitize_stream(
|
|
99
|
+
data: Union[str, bytes, Iterable[str], Iterable[bytes]],
|
|
100
|
+
intro_value: str = "data:",
|
|
101
|
+
to_json: bool = True,
|
|
102
|
+
skip_markers: Optional[List[str]] = None,
|
|
103
|
+
strip_chars: Optional[str] = None,
|
|
104
|
+
start_marker: Optional[str] = None,
|
|
105
|
+
end_marker: Optional[str] = None,
|
|
106
|
+
content_extractor: Optional[Callable[[Union[str, Dict[str, Any]]], Optional[Any]]] = None,
|
|
107
|
+
yield_raw_on_error: bool = True,
|
|
108
|
+
encoding: EncodingType = 'utf-8',
|
|
109
|
+
encoding_errors: str = 'replace',
|
|
110
|
+
chunk_size: Optional[int] = None,
|
|
111
|
+
) -> Generator[Any, None, None]:
|
|
112
|
+
"""
|
|
113
|
+
Realtime stream processor that handles string/byte streams with minimal latency.
|
|
114
|
+
|
|
115
|
+
Features:
|
|
116
|
+
- Direct realtime processing of byte streams
|
|
117
|
+
- Optimized string handling and JSON parsing
|
|
118
|
+
- Robust error handling and validation
|
|
119
|
+
- Flexible encoding support
|
|
120
|
+
- Drop-in replacement for response.iter_content/iter_lines
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
data: Input data (string, string iterator, or bytes iterator)
|
|
124
|
+
intro_value: Prefix to remove from each chunk
|
|
125
|
+
to_json: Whether to parse chunks as JSON
|
|
126
|
+
skip_markers: Markers to skip
|
|
127
|
+
strip_chars: Characters to strip
|
|
128
|
+
start_marker: Processing start marker
|
|
129
|
+
end_marker: Processing end marker
|
|
130
|
+
content_extractor: Function to extract content
|
|
131
|
+
yield_raw_on_error: Yield raw content on JSON errors
|
|
132
|
+
encoding: Character encoding for byte streams ('utf-8', 'latin1', etc.)
|
|
133
|
+
encoding_errors: How to handle encoding errors ('strict', 'ignore', 'replace')
|
|
134
|
+
chunk_size: Chunk size for byte streams (None for default)
|
|
135
|
+
|
|
136
|
+
Yields:
|
|
137
|
+
Processed chunks (string or dictionary)
|
|
138
|
+
|
|
139
|
+
Example:
|
|
140
|
+
>>> # Process response content
|
|
141
|
+
>>> for chunk in sanitize_stream(response.iter_content()):
|
|
142
|
+
... process_chunk(chunk)
|
|
143
|
+
|
|
144
|
+
>>> # Process a stream with specific encoding
|
|
145
|
+
>>> for text in sanitize_stream(byte_stream, encoding='latin1', to_json=False):
|
|
146
|
+
... process_text(text)
|
|
147
|
+
"""
|
|
148
|
+
effective_skip_markers = skip_markers or []
|
|
149
|
+
processing_active = start_marker is None
|
|
150
|
+
|
|
151
|
+
if isinstance(data, (str, bytes)):
|
|
152
|
+
# Optimized single string/bytes processing
|
|
153
|
+
processed_item = None
|
|
154
|
+
if isinstance(data, bytes):
|
|
155
|
+
data = data.decode(encoding, errors=encoding_errors)
|
|
156
|
+
if to_json:
|
|
157
|
+
try:
|
|
158
|
+
processed_item = json.loads(data)
|
|
159
|
+
except json.JSONDecodeError:
|
|
160
|
+
pass
|
|
161
|
+
|
|
162
|
+
if processed_item is None:
|
|
163
|
+
if not processing_active and data == start_marker:
|
|
164
|
+
processing_active = True
|
|
165
|
+
elif processing_active and end_marker is not None and data == end_marker:
|
|
166
|
+
processing_active = False
|
|
167
|
+
|
|
168
|
+
if processing_active:
|
|
169
|
+
processed_item = _process_chunk(
|
|
170
|
+
data, intro_value, to_json, effective_skip_markers,
|
|
171
|
+
strip_chars, yield_raw_on_error
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
if processed_item is not None:
|
|
175
|
+
if content_extractor:
|
|
176
|
+
try:
|
|
177
|
+
final_content = content_extractor(processed_item)
|
|
178
|
+
if final_content is not None:
|
|
179
|
+
yield final_content
|
|
180
|
+
except Exception:
|
|
181
|
+
pass
|
|
182
|
+
else:
|
|
183
|
+
yield processed_item
|
|
184
|
+
|
|
185
|
+
elif hasattr(data, '__iter__') or hasattr(data, 'iter_content'):
|
|
186
|
+
# Efficient stream processing
|
|
187
|
+
try:
|
|
188
|
+
if hasattr(data, 'iter_content'):
|
|
189
|
+
data = data.iter_content(chunk_size=chunk_size)
|
|
190
|
+
first_item = next(iter(data))
|
|
191
|
+
except StopIteration:
|
|
192
|
+
return
|
|
193
|
+
|
|
194
|
+
from itertools import chain
|
|
195
|
+
stream = chain([first_item], data)
|
|
196
|
+
|
|
197
|
+
# Choose processing path based on type
|
|
198
|
+
if isinstance(first_item, bytes):
|
|
199
|
+
line_iterator = _decode_byte_stream(
|
|
200
|
+
stream,
|
|
201
|
+
encoding=encoding,
|
|
202
|
+
errors=encoding_errors
|
|
203
|
+
)
|
|
204
|
+
elif isinstance(first_item, str):
|
|
205
|
+
line_iterator = stream
|
|
206
|
+
else:
|
|
207
|
+
raise TypeError(f"Stream must yield strings or bytes, not {type(first_item).__name__}")
|
|
208
|
+
|
|
209
|
+
# Process stream efficiently
|
|
210
|
+
for line in line_iterator:
|
|
211
|
+
if not processing_active and start_marker is not None and line == start_marker:
|
|
212
|
+
processing_active = True
|
|
213
|
+
continue
|
|
214
|
+
if processing_active and end_marker is not None and line == end_marker:
|
|
215
|
+
processing_active = False
|
|
216
|
+
continue
|
|
217
|
+
|
|
218
|
+
if processing_active:
|
|
219
|
+
processed = _process_chunk(
|
|
220
|
+
line, intro_value, to_json, effective_skip_markers,
|
|
221
|
+
strip_chars, yield_raw_on_error
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
if processed is not None:
|
|
225
|
+
if content_extractor:
|
|
226
|
+
try:
|
|
227
|
+
final_content = content_extractor(processed)
|
|
228
|
+
if final_content is not None:
|
|
229
|
+
yield final_content
|
|
230
|
+
except Exception:
|
|
231
|
+
pass
|
|
232
|
+
else:
|
|
233
|
+
yield processed
|
|
234
|
+
else:
|
|
235
|
+
raise TypeError(f"Input must be a string or an iterable, not {type(data).__name__}")
|
|
236
|
+
|
|
237
|
+
from .conversation import Conversation
|
|
238
|
+
from .optimizers import Optimizers
|
|
239
|
+
from .Extra.autocoder import AutoCoder
|
|
240
|
+
from .prompt_manager import AwesomePrompts
|