webscout 8.2.4__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/Extra/gguf.py +2 -0
- webscout/Provider/AISEARCH/scira_search.py +3 -5
- webscout/Provider/Aitopia.py +75 -51
- webscout/Provider/AllenAI.py +64 -67
- webscout/Provider/ChatGPTClone.py +33 -34
- webscout/Provider/ChatSandbox.py +342 -0
- webscout/Provider/Cloudflare.py +79 -32
- webscout/Provider/Deepinfra.py +69 -56
- webscout/Provider/ElectronHub.py +48 -39
- webscout/Provider/ExaChat.py +36 -20
- webscout/Provider/GPTWeb.py +24 -18
- webscout/Provider/GithubChat.py +52 -49
- webscout/Provider/GizAI.py +285 -0
- webscout/Provider/Glider.py +39 -28
- webscout/Provider/Groq.py +48 -20
- webscout/Provider/HeckAI.py +18 -36
- webscout/Provider/Jadve.py +30 -37
- webscout/Provider/LambdaChat.py +36 -59
- webscout/Provider/MCPCore.py +18 -21
- webscout/Provider/Marcus.py +23 -14
- webscout/Provider/Nemotron.py +218 -0
- webscout/Provider/Netwrck.py +35 -26
- webscout/Provider/OPENAI/__init__.py +1 -1
- webscout/Provider/OPENAI/exachat.py +4 -0
- webscout/Provider/OPENAI/scirachat.py +3 -4
- webscout/Provider/OPENAI/textpollinations.py +20 -22
- webscout/Provider/OPENAI/toolbaz.py +1 -0
- webscout/Provider/PI.py +22 -13
- webscout/Provider/StandardInput.py +42 -30
- webscout/Provider/TeachAnything.py +24 -12
- webscout/Provider/TextPollinationsAI.py +78 -76
- webscout/Provider/TwoAI.py +120 -88
- webscout/Provider/TypliAI.py +305 -0
- webscout/Provider/Venice.py +24 -22
- webscout/Provider/VercelAI.py +31 -12
- webscout/Provider/WiseCat.py +1 -1
- webscout/Provider/WrDoChat.py +370 -0
- webscout/Provider/__init__.py +11 -13
- webscout/Provider/ai4chat.py +5 -3
- webscout/Provider/akashgpt.py +59 -66
- webscout/Provider/asksteve.py +53 -44
- webscout/Provider/cerebras.py +77 -31
- webscout/Provider/chatglm.py +47 -37
- webscout/Provider/elmo.py +38 -32
- webscout/Provider/freeaichat.py +57 -43
- webscout/Provider/granite.py +24 -21
- webscout/Provider/hermes.py +27 -20
- webscout/Provider/learnfastai.py +25 -20
- webscout/Provider/llmchatco.py +48 -78
- webscout/Provider/multichat.py +13 -3
- webscout/Provider/scira_chat.py +50 -30
- webscout/Provider/scnet.py +27 -21
- webscout/Provider/searchchat.py +16 -24
- webscout/Provider/sonus.py +37 -39
- webscout/Provider/toolbaz.py +24 -46
- webscout/Provider/turboseek.py +37 -41
- webscout/Provider/typefully.py +30 -22
- webscout/Provider/typegpt.py +47 -51
- webscout/Provider/uncovr.py +46 -40
- webscout/__init__.py +0 -1
- webscout/cli.py +256 -0
- webscout/conversation.py +305 -448
- webscout/exceptions.py +3 -0
- 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.4.dist-info → webscout-8.2.6.dist-info}/METADATA +166 -45
- {webscout-8.2.4.dist-info → webscout-8.2.6.dist-info}/RECORD +89 -89
- {webscout-8.2.4.dist-info → webscout-8.2.6.dist-info}/WHEEL +1 -1
- webscout-8.2.6.dist-info/entry_points.txt +3 -0
- {webscout-8.2.4.dist-info → webscout-8.2.6.dist-info}/top_level.txt +0 -1
- inferno/__init__.py +0 -6
- inferno/__main__.py +0 -9
- inferno/cli.py +0 -6
- inferno/lol.py +0 -589
- webscout/LLM.py +0 -442
- webscout/Local/__init__.py +0 -12
- webscout/Local/__main__.py +0 -9
- webscout/Local/api.py +0 -576
- webscout/Local/cli.py +0 -516
- webscout/Local/config.py +0 -75
- webscout/Local/llm.py +0 -287
- webscout/Local/model_manager.py +0 -253
- webscout/Local/server.py +0 -721
- webscout/Local/utils.py +0 -93
- webscout/Provider/Chatify.py +0 -175
- webscout/Provider/PizzaGPT.py +0 -228
- webscout/Provider/askmyai.py +0 -158
- webscout/Provider/gaurish.py +0 -244
- webscout/Provider/promptrefine.py +0 -193
- webscout/Provider/tutorai.py +0 -270
- webscout-8.2.4.dist-info/entry_points.txt +0 -5
- {webscout-8.2.4.dist-info → webscout-8.2.6.dist-info}/licenses/LICENSE.md +0 -0
webscout/Provider/Netwrck.py
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import time
|
|
2
|
-
import uuid
|
|
3
|
-
import json
|
|
4
1
|
from typing import Any, Dict, Optional, Generator, Union
|
|
5
|
-
from
|
|
6
|
-
from datetime import date
|
|
7
|
-
from webscout.AIutel import Optimizers, Conversation, AwesomePrompts
|
|
2
|
+
from webscout.AIutel import Optimizers, Conversation, AwesomePrompts, sanitize_stream # Import sanitize_stream
|
|
8
3
|
from webscout.AIbase import Provider
|
|
9
4
|
from webscout import exceptions
|
|
10
5
|
from webscout.litagent import LitAgent
|
|
@@ -95,6 +90,15 @@ class Netwrck(Provider):
|
|
|
95
90
|
if callable(getattr(Optimizers, method)) and not method.startswith("__")
|
|
96
91
|
)
|
|
97
92
|
|
|
93
|
+
@staticmethod
|
|
94
|
+
def _netwrck_extractor(chunk: Union[str, Dict[str, Any]]) -> Optional[str]:
|
|
95
|
+
"""Removes surrounding quotes and handles potential escapes."""
|
|
96
|
+
if isinstance(chunk, str):
|
|
97
|
+
text = chunk.strip('"')
|
|
98
|
+
# Handle potential unicode escapes if they appear
|
|
99
|
+
# text = text.encode().decode('unicode_escape') # Uncomment if needed
|
|
100
|
+
return text
|
|
101
|
+
return None
|
|
98
102
|
def ask(
|
|
99
103
|
self,
|
|
100
104
|
prompt: str,
|
|
@@ -136,21 +140,18 @@ class Netwrck(Provider):
|
|
|
136
140
|
response.raise_for_status() # Check for HTTP errors
|
|
137
141
|
|
|
138
142
|
streaming_text = ""
|
|
139
|
-
#
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
# Handle potential decoding errors if chunks split mid-character
|
|
152
|
-
continue
|
|
153
|
-
|
|
143
|
+
# Use sanitize_stream
|
|
144
|
+
processed_stream = sanitize_stream(
|
|
145
|
+
data=response.iter_content(chunk_size=None), # Pass byte iterator
|
|
146
|
+
intro_value=None, # No prefix
|
|
147
|
+
to_json=False, # It's text
|
|
148
|
+
content_extractor=self._netwrck_extractor, # Use the quote stripper
|
|
149
|
+
yield_raw_on_error=True
|
|
150
|
+
)
|
|
151
|
+
for content_chunk in processed_stream:
|
|
152
|
+
if content_chunk and isinstance(content_chunk, str):
|
|
153
|
+
streaming_text += content_chunk
|
|
154
|
+
yield {"text": content_chunk} if not raw else content_chunk
|
|
154
155
|
# Update history after stream finishes
|
|
155
156
|
self.last_response = {"text": streaming_text} # Store aggregated text
|
|
156
157
|
self.conversation.update_chat_history(payload["query"], streaming_text)
|
|
@@ -174,11 +175,19 @@ class Netwrck(Provider):
|
|
|
174
175
|
)
|
|
175
176
|
response.raise_for_status() # Check for HTTP errors
|
|
176
177
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
#
|
|
180
|
-
|
|
181
|
-
|
|
178
|
+
response_text_raw = response.text # Get raw text
|
|
179
|
+
|
|
180
|
+
# Process the text using sanitize_stream
|
|
181
|
+
processed_stream = sanitize_stream(
|
|
182
|
+
data=response_text_raw,
|
|
183
|
+
intro_value=None,
|
|
184
|
+
to_json=False,
|
|
185
|
+
content_extractor=self._netwrck_extractor
|
|
186
|
+
)
|
|
187
|
+
# Aggregate the single result
|
|
188
|
+
text = "".join(list(processed_stream))
|
|
189
|
+
|
|
190
|
+
self.last_response = {"text": text} # Store processed text
|
|
182
191
|
self.conversation.update_chat_history(prompt, text)
|
|
183
192
|
|
|
184
193
|
# Return dict or raw string
|
|
@@ -35,6 +35,8 @@ MODEL_CONFIGS = {
|
|
|
35
35
|
"gemini-2.0-flash-thinking-exp-01-21",
|
|
36
36
|
"gemini-2.5-pro-exp-03-25",
|
|
37
37
|
"gemini-2.0-pro-exp-02-05",
|
|
38
|
+
"gemini-2.5-flash-preview-04-17",
|
|
39
|
+
|
|
38
40
|
|
|
39
41
|
],
|
|
40
42
|
},
|
|
@@ -83,6 +85,7 @@ MODEL_CONFIGS = {
|
|
|
83
85
|
},
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
|
|
86
89
|
class Completions(BaseCompletions):
|
|
87
90
|
def __init__(self, client: 'ExaChat'):
|
|
88
91
|
self._client = client
|
|
@@ -292,6 +295,7 @@ class ExaChat(OpenAICompatibleProvider):
|
|
|
292
295
|
"gemini-2.0-flash-thinking-exp-01-21",
|
|
293
296
|
"gemini-2.5-pro-exp-03-25",
|
|
294
297
|
"gemini-2.0-pro-exp-02-05",
|
|
298
|
+
"gemini-2.5-flash-preview-04-17",
|
|
295
299
|
|
|
296
300
|
# OpenRouter Models
|
|
297
301
|
"mistralai/mistral-small-3.1-24b-instruct:free",
|
|
@@ -324,15 +324,14 @@ class SciraChat(OpenAICompatibleProvider):
|
|
|
324
324
|
"""
|
|
325
325
|
|
|
326
326
|
AVAILABLE_MODELS = {
|
|
327
|
-
"scira-default": "Grok3",
|
|
328
|
-
"scira-grok-3
|
|
327
|
+
"scira-default": "Grok3-mini", # thinking model
|
|
328
|
+
"scira-grok-3": "Grok3",
|
|
329
|
+
"scira-anthropic": "Sonnet 3.7 thinking",
|
|
329
330
|
"scira-vision" : "Grok2-Vision", # vision model
|
|
330
331
|
"scira-4.1-mini": "GPT4.1-mini",
|
|
331
332
|
"scira-qwq": "QWQ-32B",
|
|
332
333
|
"scira-o4-mini": "o4-mini",
|
|
333
334
|
"scira-google": "gemini 2.5 flash"
|
|
334
|
-
|
|
335
|
-
|
|
336
335
|
}
|
|
337
336
|
|
|
338
337
|
def __init__(
|
|
@@ -268,28 +268,26 @@ class TextPollinations(OpenAICompatibleProvider):
|
|
|
268
268
|
"""
|
|
269
269
|
|
|
270
270
|
AVAILABLE_MODELS = [
|
|
271
|
-
"openai",
|
|
272
|
-
"openai-large",
|
|
273
|
-
"
|
|
274
|
-
"
|
|
275
|
-
"
|
|
276
|
-
"
|
|
277
|
-
"
|
|
278
|
-
"
|
|
279
|
-
"
|
|
280
|
-
"
|
|
281
|
-
"
|
|
282
|
-
"
|
|
283
|
-
"deepseek-reasoning",
|
|
284
|
-
"
|
|
285
|
-
"
|
|
286
|
-
"
|
|
287
|
-
"
|
|
288
|
-
"
|
|
289
|
-
"
|
|
290
|
-
"
|
|
291
|
-
"sur", # Sur AI Assistant (Mistral) (Scaleway) - vision capable
|
|
292
|
-
"openai-audio", # OpenAI GPT-4o-audio-preview (Azure) - vision and audio capable
|
|
271
|
+
"openai",
|
|
272
|
+
"openai-large",
|
|
273
|
+
"qwen-coder",
|
|
274
|
+
"llama",
|
|
275
|
+
"llamascout",
|
|
276
|
+
"mistral",
|
|
277
|
+
"unity",
|
|
278
|
+
"midijourney",
|
|
279
|
+
"rtist",
|
|
280
|
+
"searchgpt",
|
|
281
|
+
"evil",
|
|
282
|
+
"deepseek-reasoning",
|
|
283
|
+
"deepseek-reasoning-large",
|
|
284
|
+
"phi",
|
|
285
|
+
"llama-vision",
|
|
286
|
+
"hormoz",
|
|
287
|
+
"hypnosis-tracy",
|
|
288
|
+
"deepseek",
|
|
289
|
+
"sur",
|
|
290
|
+
"openai-audio",
|
|
293
291
|
]
|
|
294
292
|
|
|
295
293
|
def __init__(
|
webscout/Provider/PI.py
CHANGED
|
@@ -5,7 +5,7 @@ import json
|
|
|
5
5
|
import re
|
|
6
6
|
import threading
|
|
7
7
|
from webscout.AIutel import Optimizers
|
|
8
|
-
from webscout.AIutel import Conversation
|
|
8
|
+
from webscout.AIutel import Conversation, sanitize_stream # Import sanitize_stream
|
|
9
9
|
from webscout.AIutel import AwesomePrompts
|
|
10
10
|
from webscout.AIbase import Provider
|
|
11
11
|
from typing import Dict, Union, Any, Optional
|
|
@@ -122,6 +122,13 @@ class PiAI(Provider):
|
|
|
122
122
|
if self.is_conversation:
|
|
123
123
|
self.start_conversation()
|
|
124
124
|
|
|
125
|
+
@staticmethod
|
|
126
|
+
def _pi_extractor(chunk: Union[str, Dict[str, Any]]) -> Optional[str]:
|
|
127
|
+
"""Extracts text content from PiAI stream JSON objects."""
|
|
128
|
+
if isinstance(chunk, dict) and 'text' in chunk and chunk['text'] is not None:
|
|
129
|
+
return chunk.get("text")
|
|
130
|
+
return None
|
|
131
|
+
|
|
125
132
|
def start_conversation(self) -> str:
|
|
126
133
|
"""
|
|
127
134
|
Initializes a new conversation and returns the conversation ID.
|
|
@@ -245,17 +252,22 @@ class PiAI(Provider):
|
|
|
245
252
|
if line_bytes:
|
|
246
253
|
line = line_bytes.decode('utf-8')
|
|
247
254
|
full_raw_data_for_sids += line + "\n" # Accumulate for SID extraction
|
|
255
|
+
|
|
248
256
|
if line.startswith("data: "):
|
|
257
|
+
json_line_str = line[6:] # Get the JSON part as string
|
|
249
258
|
try:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
259
|
+
# Process this single JSON line string with sanitize_stream
|
|
260
|
+
processed_gen = sanitize_stream(
|
|
261
|
+
data=json_line_str,
|
|
262
|
+
to_json=True,
|
|
263
|
+
content_extractor=self._pi_extractor
|
|
264
|
+
)
|
|
265
|
+
chunk_text = next(processed_gen, None) # Get the single extracted text item
|
|
266
|
+
if chunk_text and isinstance(chunk_text, str):
|
|
253
267
|
streaming_text += chunk_text
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
continue
|
|
258
|
-
|
|
268
|
+
yield {"text": streaming_text} # Always yield dict with aggregated text
|
|
269
|
+
except (StopIteration, json.JSONDecodeError, UnicodeDecodeError):
|
|
270
|
+
continue # Skip if sanitize_stream fails or yields nothing
|
|
259
271
|
# Extract SIDs after processing the stream
|
|
260
272
|
sids = re.findall(r'"sid":"(.*?)"', full_raw_data_for_sids)
|
|
261
273
|
second_sid = sids[1] if len(sids) >= 2 else None
|
|
@@ -284,13 +296,10 @@ class PiAI(Provider):
|
|
|
284
296
|
else:
|
|
285
297
|
# For non-stream, collect all responses and return the final one
|
|
286
298
|
final_text = ""
|
|
287
|
-
#
|
|
299
|
+
# process_stream always yields dicts now
|
|
288
300
|
for res in process_stream():
|
|
289
301
|
if isinstance(res, dict) and "text" in res:
|
|
290
302
|
final_text = res["text"] # Keep updating with the latest aggregated text
|
|
291
|
-
# Handle raw JSON object case if raw=True was passed
|
|
292
|
-
elif raw and isinstance(res, dict) and 'text' in res and res['text'] is not None:
|
|
293
|
-
final_text += res['text'] # Append chunks if raw
|
|
294
303
|
|
|
295
304
|
# last_response and history are updated within process_stream
|
|
296
305
|
# Return the final aggregated response dict or raw text
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
from
|
|
2
|
-
import requests
|
|
3
|
-
import json
|
|
1
|
+
from curl_cffi.requests import Session
|
|
4
2
|
import uuid
|
|
5
3
|
import re
|
|
6
|
-
from
|
|
7
|
-
from typing import Any, Dict, Optional, Union, Generator
|
|
4
|
+
from typing import Any, Dict, Optional, Union
|
|
8
5
|
from webscout.AIutel import Optimizers
|
|
9
6
|
from webscout.AIutel import Conversation
|
|
10
|
-
from webscout.AIutel import AwesomePrompts
|
|
7
|
+
from webscout.AIutel import AwesomePrompts, sanitize_stream # Import sanitize_stream
|
|
11
8
|
from webscout.AIbase import Provider
|
|
12
9
|
from webscout import exceptions
|
|
13
10
|
from webscout.litagent import LitAgent
|
|
@@ -98,9 +95,9 @@ class StandardInputAI(Provider):
|
|
|
98
95
|
"ph_phc_f3wUUyCfmKlKtkc2pfT7OsdcW2mBEVGN2A87yEYbG3c_posthog": '''%7B%22distinct_id%22%3A%220195c7cc-ac8f-79ff-b901-e14a78fc2a67%22%2C%22%24sesid%22%3A%5B1744688627860%2C%220196377f-9f12-77e6-a9ea-0e9669423803%22%2C1744687832850%5D%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fstandard-input.com%2F%22%7D%7D'''
|
|
99
96
|
}
|
|
100
97
|
|
|
101
|
-
self.session =
|
|
98
|
+
self.session = Session() # Use curl_cffi Session
|
|
102
99
|
self.session.headers.update(self.headers)
|
|
103
|
-
self.session.proxies
|
|
100
|
+
self.session.proxies = proxies # Assign proxies directly
|
|
104
101
|
|
|
105
102
|
self.is_conversation = is_conversation
|
|
106
103
|
self.max_tokens_to_sample = max_tokens
|
|
@@ -153,6 +150,17 @@ class StandardInputAI(Provider):
|
|
|
153
150
|
|
|
154
151
|
return self.fingerprint
|
|
155
152
|
|
|
153
|
+
@staticmethod
|
|
154
|
+
def _standardinput_extractor(chunk: Union[str, Dict[str, Any]]) -> Optional[str]:
|
|
155
|
+
"""Extracts content from the StandardInput stream format '0:"..."'."""
|
|
156
|
+
if isinstance(chunk, str):
|
|
157
|
+
match = re.search(r'0:"(.*?)"(?=,|$)', chunk) # Look for 0:"...", possibly followed by comma or end of string
|
|
158
|
+
if match:
|
|
159
|
+
# Decode potential unicode escapes like \u00e9 and handle escaped quotes/backslashes
|
|
160
|
+
content = match.group(1).encode().decode('unicode_escape')
|
|
161
|
+
return content.replace('\\\\', '\\').replace('\\"', '"')
|
|
162
|
+
return None
|
|
163
|
+
|
|
156
164
|
def ask(
|
|
157
165
|
self,
|
|
158
166
|
prompt: str,
|
|
@@ -183,45 +191,48 @@ class StandardInputAI(Provider):
|
|
|
183
191
|
}
|
|
184
192
|
|
|
185
193
|
try:
|
|
186
|
-
|
|
194
|
+
# Use curl_cffi post with impersonate
|
|
195
|
+
response = self.session.post(
|
|
196
|
+
self.url,
|
|
197
|
+
cookies=self.cookies,
|
|
198
|
+
json=payload,
|
|
199
|
+
stream=True,
|
|
200
|
+
timeout=self.timeout,
|
|
201
|
+
impersonate="chrome120" # Add impersonate
|
|
202
|
+
)
|
|
203
|
+
|
|
187
204
|
if response.status_code != 200:
|
|
188
|
-
# Try to get response content for better error messages
|
|
189
205
|
try:
|
|
190
206
|
error_content = response.text
|
|
191
207
|
except:
|
|
192
208
|
error_content = "<could not read response content>"
|
|
193
209
|
|
|
194
210
|
if response.status_code in [403, 429]:
|
|
195
|
-
print(f"Received status code {response.status_code}, refreshing identity...")
|
|
196
211
|
self.refresh_identity()
|
|
197
|
-
response = self.session.post(
|
|
212
|
+
response = self.session.post(
|
|
213
|
+
self.url, cookies=self.cookies, json=payload, stream=True,
|
|
214
|
+
timeout=self.timeout, impersonate="chrome120"
|
|
215
|
+
)
|
|
198
216
|
if not response.ok:
|
|
199
217
|
raise exceptions.FailedToGenerateResponseError(
|
|
200
218
|
f"Failed to generate response after identity refresh - ({response.status_code}, {response.reason}) - {error_content}"
|
|
201
219
|
)
|
|
202
|
-
print("Identity refreshed successfully.")
|
|
203
220
|
else:
|
|
204
221
|
raise exceptions.FailedToGenerateResponseError(
|
|
205
222
|
f"Request failed with status code {response.status_code}. Response: {error_content}"
|
|
206
223
|
)
|
|
207
224
|
|
|
208
225
|
full_response = ""
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
match = re.search(r'0:"(.*?)"', line_str)
|
|
220
|
-
if match:
|
|
221
|
-
content = match.group(1)
|
|
222
|
-
full_response += content
|
|
223
|
-
continue
|
|
224
|
-
except: pass
|
|
226
|
+
# Use sanitize_stream
|
|
227
|
+
processed_stream = sanitize_stream(
|
|
228
|
+
data=response.iter_content(chunk_size=None), # Pass byte iterator
|
|
229
|
+
intro_value=None, # No simple prefix
|
|
230
|
+
to_json=False, # Content is not JSON
|
|
231
|
+
content_extractor=self._standardinput_extractor # Use the specific extractor
|
|
232
|
+
)
|
|
233
|
+
for content_chunk in processed_stream:
|
|
234
|
+
if content_chunk and isinstance(content_chunk, str):
|
|
235
|
+
full_response += content_chunk
|
|
225
236
|
|
|
226
237
|
self.last_response = {"text": full_response}
|
|
227
238
|
self.conversation.update_chat_history(prompt, full_response)
|
|
@@ -243,7 +254,8 @@ class StandardInputAI(Provider):
|
|
|
243
254
|
|
|
244
255
|
def get_message(self, response: dict) -> str:
|
|
245
256
|
assert isinstance(response, dict), "Response should be of dict data-type only"
|
|
246
|
-
|
|
257
|
+
# Extractor handles formatting
|
|
258
|
+
return response.get("text", "").replace('\\n', '\n').replace('\\n\\n', '\n\n')
|
|
247
259
|
|
|
248
260
|
if __name__ == "__main__":
|
|
249
261
|
print("-" * 100)
|
|
@@ -4,7 +4,7 @@ from typing import Union, Any, Dict
|
|
|
4
4
|
from webscout.AIbase import Provider # Import Provider base class
|
|
5
5
|
from webscout import exceptions # Import custom exceptions
|
|
6
6
|
from webscout.conversation import Conversation
|
|
7
|
-
from webscout.
|
|
7
|
+
from webscout.AIutel import Optimizers, sanitize_stream # Import sanitize_stream
|
|
8
8
|
from webscout.prompt_manager import AwesomePrompts
|
|
9
9
|
from webscout.litagent import LitAgent
|
|
10
10
|
|
|
@@ -131,13 +131,22 @@ class TeachAnything(Provider):
|
|
|
131
131
|
)
|
|
132
132
|
response.raise_for_status() # Check for HTTP errors
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
#
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
134
|
+
resp_text_raw = response.text # Get raw response text
|
|
135
|
+
|
|
136
|
+
# Process the text using sanitize_stream (even though it's not streaming)
|
|
137
|
+
# This keeps the pattern consistent, though it won't do much here
|
|
138
|
+
processed_stream = sanitize_stream(
|
|
139
|
+
data=resp_text_raw,
|
|
140
|
+
intro_value=None, # No prefix
|
|
141
|
+
to_json=False # It's plain text
|
|
140
142
|
)
|
|
143
|
+
|
|
144
|
+
# Extract the single result from the generator
|
|
145
|
+
resp_text = "".join(list(processed_stream)) # Aggregate potential chunks (should be one)
|
|
146
|
+
|
|
147
|
+
self.last_response = {"text": resp_text}
|
|
148
|
+
self.conversation.update_chat_history(prompt, resp_text)
|
|
149
|
+
|
|
141
150
|
# Return dict or raw string based on raw flag
|
|
142
151
|
return resp_text if raw else self.last_response
|
|
143
152
|
|
|
@@ -182,17 +191,20 @@ class TeachAnything(Provider):
|
|
|
182
191
|
# If stream=False, return the full message directly
|
|
183
192
|
return self.get_message(response_data)
|
|
184
193
|
|
|
185
|
-
def get_message(self, response: dict) -> str:
|
|
194
|
+
def get_message(self, response: Union[dict, str]) -> str:
|
|
186
195
|
"""Retrieves message only from response
|
|
187
196
|
|
|
188
197
|
Args:
|
|
189
|
-
response (dict): Response generated by `self.ask`
|
|
198
|
+
response (Union[dict, str]): Response generated by `self.ask`
|
|
190
199
|
|
|
191
200
|
Returns:
|
|
192
201
|
str: Message extracted
|
|
193
202
|
"""
|
|
194
|
-
|
|
195
|
-
|
|
203
|
+
if isinstance(response, str):
|
|
204
|
+
return response
|
|
205
|
+
elif isinstance(response, dict):
|
|
206
|
+
return response["text"]
|
|
207
|
+
raise ValueError("Response must be either dict or str")
|
|
196
208
|
|
|
197
209
|
|
|
198
210
|
if __name__ == '__main__':
|
|
@@ -218,4 +230,4 @@ if __name__ == '__main__':
|
|
|
218
230
|
except exceptions.FailedToGenerateResponseError as e:
|
|
219
231
|
print(f"\n[bold red]API Error:[/bold red] {e}")
|
|
220
232
|
except Exception as e:
|
|
221
|
-
print(f"\n[bold red]An unexpected error occurred:[/bold red] {e}")
|
|
233
|
+
print(f"\n[bold red]An unexpected error occurred:[/bold red] {e}")
|