webscout 8.2.8__py3-none-any.whl → 8.3__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 +34 -16
- webscout/AIbase.py +96 -37
- webscout/AIutel.py +491 -87
- webscout/Bard.py +441 -323
- webscout/Extra/GitToolkit/__init__.py +10 -10
- webscout/Extra/YTToolkit/ytapi/video.py +232 -232
- webscout/Litlogger/README.md +10 -0
- webscout/Litlogger/__init__.py +7 -59
- webscout/Litlogger/formats.py +4 -0
- webscout/Litlogger/handlers.py +103 -0
- webscout/Litlogger/levels.py +13 -0
- webscout/Litlogger/logger.py +92 -0
- webscout/Provider/AISEARCH/Perplexity.py +332 -358
- webscout/Provider/AISEARCH/felo_search.py +9 -35
- webscout/Provider/AISEARCH/genspark_search.py +30 -56
- webscout/Provider/AISEARCH/hika_search.py +4 -16
- webscout/Provider/AISEARCH/iask_search.py +410 -436
- webscout/Provider/AISEARCH/monica_search.py +4 -30
- webscout/Provider/AISEARCH/scira_search.py +6 -32
- webscout/Provider/AISEARCH/webpilotai_search.py +38 -64
- webscout/Provider/Blackboxai.py +155 -35
- webscout/Provider/ChatSandbox.py +2 -1
- webscout/Provider/Deepinfra.py +339 -339
- webscout/Provider/ExaChat.py +358 -358
- webscout/Provider/Gemini.py +169 -169
- webscout/Provider/GithubChat.py +1 -2
- webscout/Provider/Glider.py +3 -3
- webscout/Provider/HeckAI.py +172 -82
- webscout/Provider/LambdaChat.py +1 -0
- webscout/Provider/MCPCore.py +7 -3
- webscout/Provider/OPENAI/BLACKBOXAI.py +421 -139
- webscout/Provider/OPENAI/Cloudflare.py +38 -21
- webscout/Provider/OPENAI/FalconH1.py +457 -0
- webscout/Provider/OPENAI/FreeGemini.py +35 -18
- webscout/Provider/OPENAI/NEMOTRON.py +34 -34
- webscout/Provider/OPENAI/PI.py +427 -0
- webscout/Provider/OPENAI/Qwen3.py +304 -0
- webscout/Provider/OPENAI/README.md +952 -1253
- webscout/Provider/OPENAI/TwoAI.py +374 -0
- webscout/Provider/OPENAI/__init__.py +7 -1
- webscout/Provider/OPENAI/ai4chat.py +73 -63
- webscout/Provider/OPENAI/api.py +869 -644
- webscout/Provider/OPENAI/base.py +2 -0
- webscout/Provider/OPENAI/c4ai.py +34 -13
- webscout/Provider/OPENAI/chatgpt.py +575 -556
- webscout/Provider/OPENAI/chatgptclone.py +512 -487
- webscout/Provider/OPENAI/chatsandbox.py +11 -6
- webscout/Provider/OPENAI/copilot.py +258 -0
- webscout/Provider/OPENAI/deepinfra.py +327 -318
- webscout/Provider/OPENAI/e2b.py +140 -104
- webscout/Provider/OPENAI/exaai.py +420 -411
- webscout/Provider/OPENAI/exachat.py +448 -443
- webscout/Provider/OPENAI/flowith.py +7 -3
- webscout/Provider/OPENAI/freeaichat.py +12 -8
- webscout/Provider/OPENAI/glider.py +15 -8
- webscout/Provider/OPENAI/groq.py +5 -2
- webscout/Provider/OPENAI/heckai.py +311 -307
- webscout/Provider/OPENAI/llmchatco.py +9 -7
- webscout/Provider/OPENAI/mcpcore.py +18 -9
- webscout/Provider/OPENAI/multichat.py +7 -5
- webscout/Provider/OPENAI/netwrck.py +16 -11
- webscout/Provider/OPENAI/oivscode.py +290 -0
- webscout/Provider/OPENAI/opkfc.py +507 -496
- webscout/Provider/OPENAI/pydantic_imports.py +172 -0
- webscout/Provider/OPENAI/scirachat.py +29 -17
- webscout/Provider/OPENAI/sonus.py +308 -303
- webscout/Provider/OPENAI/standardinput.py +442 -433
- webscout/Provider/OPENAI/textpollinations.py +18 -11
- webscout/Provider/OPENAI/toolbaz.py +419 -413
- webscout/Provider/OPENAI/typefully.py +17 -10
- webscout/Provider/OPENAI/typegpt.py +21 -11
- webscout/Provider/OPENAI/uncovrAI.py +477 -462
- webscout/Provider/OPENAI/utils.py +90 -79
- webscout/Provider/OPENAI/venice.py +435 -425
- webscout/Provider/OPENAI/wisecat.py +387 -381
- webscout/Provider/OPENAI/writecream.py +166 -163
- webscout/Provider/OPENAI/x0gpt.py +26 -37
- webscout/Provider/OPENAI/yep.py +384 -356
- webscout/Provider/PI.py +2 -1
- webscout/Provider/TTI/README.md +55 -101
- webscout/Provider/TTI/__init__.py +4 -9
- webscout/Provider/TTI/aiarta.py +365 -0
- webscout/Provider/TTI/artbit.py +0 -0
- webscout/Provider/TTI/base.py +64 -0
- webscout/Provider/TTI/fastflux.py +200 -0
- webscout/Provider/TTI/magicstudio.py +201 -0
- webscout/Provider/TTI/piclumen.py +203 -0
- webscout/Provider/TTI/pixelmuse.py +225 -0
- webscout/Provider/TTI/pollinations.py +221 -0
- webscout/Provider/TTI/utils.py +11 -0
- webscout/Provider/TTS/__init__.py +2 -1
- webscout/Provider/TTS/base.py +159 -159
- webscout/Provider/TTS/openai_fm.py +129 -0
- webscout/Provider/TextPollinationsAI.py +308 -308
- webscout/Provider/TwoAI.py +239 -44
- webscout/Provider/UNFINISHED/Youchat.py +330 -330
- webscout/Provider/UNFINISHED/puterjs.py +635 -0
- webscout/Provider/UNFINISHED/test_lmarena.py +119 -119
- webscout/Provider/Writecream.py +246 -246
- webscout/Provider/__init__.py +2 -2
- webscout/Provider/ai4chat.py +33 -8
- webscout/Provider/granite.py +41 -6
- webscout/Provider/koala.py +169 -169
- webscout/Provider/oivscode.py +309 -0
- webscout/Provider/samurai.py +3 -2
- webscout/Provider/scnet.py +1 -0
- webscout/Provider/typegpt.py +3 -3
- webscout/Provider/uncovr.py +368 -368
- webscout/client.py +70 -0
- webscout/litprinter/__init__.py +58 -58
- webscout/optimizers.py +419 -419
- webscout/scout/README.md +3 -1
- webscout/scout/core/crawler.py +134 -64
- webscout/scout/core/scout.py +148 -109
- webscout/scout/element.py +106 -88
- webscout/swiftcli/Readme.md +323 -323
- webscout/swiftcli/plugins/manager.py +9 -2
- webscout/version.py +1 -1
- webscout/zeroart/__init__.py +134 -134
- webscout/zeroart/effects.py +100 -100
- webscout/zeroart/fonts.py +1238 -1238
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/METADATA +160 -35
- webscout-8.3.dist-info/RECORD +290 -0
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/WHEEL +1 -1
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/entry_points.txt +1 -0
- webscout/Litlogger/Readme.md +0 -175
- webscout/Litlogger/core/__init__.py +0 -6
- webscout/Litlogger/core/level.py +0 -23
- webscout/Litlogger/core/logger.py +0 -165
- webscout/Litlogger/handlers/__init__.py +0 -12
- webscout/Litlogger/handlers/console.py +0 -33
- webscout/Litlogger/handlers/file.py +0 -143
- webscout/Litlogger/handlers/network.py +0 -173
- webscout/Litlogger/styles/__init__.py +0 -7
- webscout/Litlogger/styles/colors.py +0 -249
- webscout/Litlogger/styles/formats.py +0 -458
- webscout/Litlogger/styles/text.py +0 -87
- webscout/Litlogger/utils/__init__.py +0 -6
- webscout/Litlogger/utils/detectors.py +0 -153
- webscout/Litlogger/utils/formatters.py +0 -200
- webscout/Provider/ChatGPTGratis.py +0 -194
- webscout/Provider/TTI/AiForce/README.md +0 -159
- webscout/Provider/TTI/AiForce/__init__.py +0 -22
- webscout/Provider/TTI/AiForce/async_aiforce.py +0 -224
- webscout/Provider/TTI/AiForce/sync_aiforce.py +0 -245
- webscout/Provider/TTI/FreeAIPlayground/README.md +0 -99
- webscout/Provider/TTI/FreeAIPlayground/__init__.py +0 -9
- webscout/Provider/TTI/FreeAIPlayground/async_freeaiplayground.py +0 -181
- webscout/Provider/TTI/FreeAIPlayground/sync_freeaiplayground.py +0 -180
- webscout/Provider/TTI/ImgSys/README.md +0 -174
- webscout/Provider/TTI/ImgSys/__init__.py +0 -23
- webscout/Provider/TTI/ImgSys/async_imgsys.py +0 -202
- webscout/Provider/TTI/ImgSys/sync_imgsys.py +0 -195
- webscout/Provider/TTI/MagicStudio/README.md +0 -101
- webscout/Provider/TTI/MagicStudio/__init__.py +0 -2
- webscout/Provider/TTI/MagicStudio/async_magicstudio.py +0 -111
- webscout/Provider/TTI/MagicStudio/sync_magicstudio.py +0 -109
- webscout/Provider/TTI/Nexra/README.md +0 -155
- webscout/Provider/TTI/Nexra/__init__.py +0 -22
- webscout/Provider/TTI/Nexra/async_nexra.py +0 -286
- webscout/Provider/TTI/Nexra/sync_nexra.py +0 -258
- webscout/Provider/TTI/PollinationsAI/README.md +0 -146
- webscout/Provider/TTI/PollinationsAI/__init__.py +0 -23
- webscout/Provider/TTI/PollinationsAI/async_pollinations.py +0 -311
- webscout/Provider/TTI/PollinationsAI/sync_pollinations.py +0 -265
- webscout/Provider/TTI/aiarta/README.md +0 -134
- webscout/Provider/TTI/aiarta/__init__.py +0 -2
- webscout/Provider/TTI/aiarta/async_aiarta.py +0 -482
- webscout/Provider/TTI/aiarta/sync_aiarta.py +0 -440
- webscout/Provider/TTI/artbit/README.md +0 -100
- webscout/Provider/TTI/artbit/__init__.py +0 -22
- webscout/Provider/TTI/artbit/async_artbit.py +0 -155
- webscout/Provider/TTI/artbit/sync_artbit.py +0 -148
- webscout/Provider/TTI/fastflux/README.md +0 -129
- webscout/Provider/TTI/fastflux/__init__.py +0 -22
- webscout/Provider/TTI/fastflux/async_fastflux.py +0 -261
- webscout/Provider/TTI/fastflux/sync_fastflux.py +0 -252
- webscout/Provider/TTI/huggingface/README.md +0 -114
- webscout/Provider/TTI/huggingface/__init__.py +0 -22
- webscout/Provider/TTI/huggingface/async_huggingface.py +0 -199
- webscout/Provider/TTI/huggingface/sync_huggingface.py +0 -195
- webscout/Provider/TTI/piclumen/README.md +0 -161
- webscout/Provider/TTI/piclumen/__init__.py +0 -23
- webscout/Provider/TTI/piclumen/async_piclumen.py +0 -268
- webscout/Provider/TTI/piclumen/sync_piclumen.py +0 -233
- webscout/Provider/TTI/pixelmuse/README.md +0 -79
- webscout/Provider/TTI/pixelmuse/__init__.py +0 -4
- webscout/Provider/TTI/pixelmuse/async_pixelmuse.py +0 -249
- webscout/Provider/TTI/pixelmuse/sync_pixelmuse.py +0 -182
- webscout/Provider/TTI/talkai/README.md +0 -139
- webscout/Provider/TTI/talkai/__init__.py +0 -4
- webscout/Provider/TTI/talkai/async_talkai.py +0 -229
- webscout/Provider/TTI/talkai/sync_talkai.py +0 -207
- webscout/Provider/UNFINISHED/oivscode.py +0 -351
- webscout-8.2.8.dist-info/RECORD +0 -334
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/licenses/LICENSE.md +0 -0
- {webscout-8.2.8.dist-info → webscout-8.3.dist-info}/top_level.txt +0 -0
|
@@ -3,37 +3,11 @@ from uuid import uuid4
|
|
|
3
3
|
import json
|
|
4
4
|
from typing import Any, Dict, Generator, Optional, Union
|
|
5
5
|
|
|
6
|
-
from webscout.AIbase import AISearch
|
|
6
|
+
from webscout.AIbase import AISearch, SearchResponse
|
|
7
7
|
from webscout import exceptions
|
|
8
8
|
from webscout.litagent import LitAgent
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class Response:
|
|
12
|
-
"""A wrapper class for API responses.
|
|
13
|
-
|
|
14
|
-
This class automatically converts response objects to their text representation
|
|
15
|
-
when printed or converted to string.
|
|
16
|
-
|
|
17
|
-
Attributes:
|
|
18
|
-
text (str): The text content of the response
|
|
19
|
-
|
|
20
|
-
Example:
|
|
21
|
-
>>> response = Response("Hello, world!")
|
|
22
|
-
>>> print(response)
|
|
23
|
-
Hello, world!
|
|
24
|
-
>>> str(response)
|
|
25
|
-
'Hello, world!'
|
|
26
|
-
"""
|
|
27
|
-
def __init__(self, text: str):
|
|
28
|
-
self.text = text
|
|
29
|
-
|
|
30
|
-
def __str__(self):
|
|
31
|
-
return self.text
|
|
32
|
-
|
|
33
|
-
def __repr__(self):
|
|
34
|
-
return self.text
|
|
35
|
-
|
|
36
|
-
|
|
37
11
|
class Felo(AISearch):
|
|
38
12
|
"""A class to interact with the Felo AI search API.
|
|
39
13
|
|
|
@@ -115,7 +89,7 @@ class Felo(AISearch):
|
|
|
115
89
|
prompt: str,
|
|
116
90
|
stream: bool = False,
|
|
117
91
|
raw: bool = False,
|
|
118
|
-
) -> Union[
|
|
92
|
+
) -> Union[SearchResponse, Generator[Union[Dict[str, str], SearchResponse], None, None]]:
|
|
119
93
|
"""Search using the Felo API and get AI-generated responses.
|
|
120
94
|
|
|
121
95
|
This method sends a search query to Felo and returns the AI-generated response.
|
|
@@ -126,13 +100,13 @@ class Felo(AISearch):
|
|
|
126
100
|
stream (bool, optional): If True, yields response chunks as they arrive.
|
|
127
101
|
If False, returns complete response. Defaults to False.
|
|
128
102
|
raw (bool, optional): If True, returns raw response dictionaries with 'text' key.
|
|
129
|
-
If False, returns
|
|
103
|
+
If False, returns SearchResponse objects that convert to text automatically.
|
|
130
104
|
Defaults to False.
|
|
131
105
|
|
|
132
106
|
Returns:
|
|
133
|
-
Union[
|
|
134
|
-
- If stream=False: Returns complete response as
|
|
135
|
-
- If stream=True: Yields response chunks as either Dict or
|
|
107
|
+
Union[SearchResponse, Generator[Union[Dict[str, str], SearchResponse], None, None]]:
|
|
108
|
+
- If stream=False: Returns complete response as SearchResponse object
|
|
109
|
+
- If stream=True: Yields response chunks as either Dict or SearchResponse objects
|
|
136
110
|
|
|
137
111
|
Raises:
|
|
138
112
|
APIConnectionError: If the API request fails
|
|
@@ -199,10 +173,10 @@ class Felo(AISearch):
|
|
|
199
173
|
if raw:
|
|
200
174
|
yield {"text": delta}
|
|
201
175
|
else:
|
|
202
|
-
yield
|
|
176
|
+
yield SearchResponse(delta)
|
|
203
177
|
except json.JSONDecodeError:
|
|
204
178
|
pass
|
|
205
|
-
self.last_response =
|
|
179
|
+
self.last_response = SearchResponse(streaming_text)
|
|
206
180
|
except requests.exceptions.RequestException as e:
|
|
207
181
|
raise exceptions.APIConnectionError(f"Request failed: {e}")
|
|
208
182
|
|
|
@@ -214,7 +188,7 @@ class Felo(AISearch):
|
|
|
214
188
|
else:
|
|
215
189
|
full_response += str(chunk)
|
|
216
190
|
if not raw:
|
|
217
|
-
self.last_response =
|
|
191
|
+
self.last_response = SearchResponse(full_response)
|
|
218
192
|
return self.last_response
|
|
219
193
|
|
|
220
194
|
return for_stream() if stream else for_non_stream()
|
|
@@ -5,37 +5,11 @@ import re
|
|
|
5
5
|
from typing import TypedDict, List, Iterator, cast, Dict, Optional, Generator, Union, Any
|
|
6
6
|
import requests
|
|
7
7
|
|
|
8
|
-
from webscout.AIbase import AISearch
|
|
8
|
+
from webscout.AIbase import AISearch, SearchResponse
|
|
9
9
|
from webscout import exceptions
|
|
10
10
|
from webscout.litagent import LitAgent
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class Response:
|
|
14
|
-
"""A wrapper class for Genspark API responses.
|
|
15
|
-
|
|
16
|
-
This class automatically converts response objects to their text representation
|
|
17
|
-
when printed or converted to string.
|
|
18
|
-
|
|
19
|
-
Attributes:
|
|
20
|
-
text (str): The text content of the response
|
|
21
|
-
|
|
22
|
-
Example:
|
|
23
|
-
>>> response = Response("Hello, world!")
|
|
24
|
-
>>> print(response)
|
|
25
|
-
Hello, world!
|
|
26
|
-
>>> str(response)
|
|
27
|
-
'Hello, world!'
|
|
28
|
-
"""
|
|
29
|
-
def __init__(self, text: str):
|
|
30
|
-
self.text = text
|
|
31
|
-
|
|
32
|
-
def __str__(self):
|
|
33
|
-
return self.text
|
|
34
|
-
|
|
35
|
-
def __repr__(self):
|
|
36
|
-
return self.text
|
|
37
|
-
|
|
38
|
-
|
|
39
13
|
class SourceDict(TypedDict, total=False):
|
|
40
14
|
url: str
|
|
41
15
|
title: str
|
|
@@ -67,8 +41,8 @@ class Genspark(AISearch):
|
|
|
67
41
|
"""
|
|
68
42
|
Strongly typed Genspark AI search API client.
|
|
69
43
|
|
|
70
|
-
Genspark provides a powerful search interface that returns AI-generated
|
|
71
|
-
based on web content. It supports both streaming and non-streaming
|
|
44
|
+
Genspark provides a powerful search interface that returns AI-generated SearchResponses
|
|
45
|
+
based on web content. It supports both streaming and non-streaming SearchResponses.
|
|
72
46
|
|
|
73
47
|
After a search, several attributes are populated with extracted data:
|
|
74
48
|
- `search_query_details` (dict): Information about the classified search query.
|
|
@@ -83,16 +57,16 @@ class Genspark(AISearch):
|
|
|
83
57
|
Basic Usage:
|
|
84
58
|
>>> from webscout import Genspark
|
|
85
59
|
>>> ai = Genspark()
|
|
86
|
-
>>> # Non-streaming example (text
|
|
87
|
-
>>>
|
|
88
|
-
>>> print(
|
|
60
|
+
>>> # Non-streaming example (text SearchResponse)
|
|
61
|
+
>>> SearchResponse_text = ai.search("What is Python?")
|
|
62
|
+
>>> print(SearchResponse_text)
|
|
89
63
|
Python is a high-level programming language...
|
|
90
64
|
>>> # Access additional data:
|
|
91
65
|
>>> # print(ai.sources_used)
|
|
92
66
|
|
|
93
|
-
>>> # Streaming example (mixed content: text
|
|
67
|
+
>>> # Streaming example (mixed content: text SearchResponse objects and event dicts)
|
|
94
68
|
>>> for item in ai.search("Tell me about AI", stream=True):
|
|
95
|
-
... if isinstance(item,
|
|
69
|
+
... if isinstance(item, SearchResponse):
|
|
96
70
|
... print(item, end="", flush=True)
|
|
97
71
|
... else:
|
|
98
72
|
... print(f"\n[EVENT: {item.get('event')}]")
|
|
@@ -100,7 +74,7 @@ class Genspark(AISearch):
|
|
|
100
74
|
[EVENT: status_update]
|
|
101
75
|
...
|
|
102
76
|
|
|
103
|
-
>>> # Raw streaming
|
|
77
|
+
>>> # Raw streaming SearchResponse format
|
|
104
78
|
>>> for raw_event_dict in ai.search("Hello", stream=True, raw=True):
|
|
105
79
|
... print(raw_event_dict)
|
|
106
80
|
{'type': 'result_start', ...}
|
|
@@ -121,7 +95,7 @@ class Genspark(AISearch):
|
|
|
121
95
|
log_raw_events: bool
|
|
122
96
|
headers: Dict[str, str]
|
|
123
97
|
cookies: Dict[str, str]
|
|
124
|
-
|
|
98
|
+
last_SearchResponse: Union[SearchResponse, Dict[str, Any], List[Any], None] # type: ignore[assignment]
|
|
125
99
|
search_query_details: Dict[str, Any]
|
|
126
100
|
status_updates: List[StatusUpdateDict]
|
|
127
101
|
final_search_results: Optional[List[Any]]
|
|
@@ -177,7 +151,7 @@ class Genspark(AISearch):
|
|
|
177
151
|
}
|
|
178
152
|
self.session.headers.update(self.headers)
|
|
179
153
|
self.session.proxies = proxies or {}
|
|
180
|
-
self.
|
|
154
|
+
self.last_SearchResponse = None
|
|
181
155
|
self._reset_search_data()
|
|
182
156
|
|
|
183
157
|
def _reset_search_data(self) -> None:
|
|
@@ -199,10 +173,10 @@ class Genspark(AISearch):
|
|
|
199
173
|
stream: bool = False,
|
|
200
174
|
raw: bool = False,
|
|
201
175
|
) -> Union[
|
|
202
|
-
|
|
176
|
+
SearchResponse, #type: ignore
|
|
203
177
|
Dict[str, Any],
|
|
204
178
|
List[dict],
|
|
205
|
-
Iterator[Union[dict,
|
|
179
|
+
Iterator[Union[dict, SearchResponse]], #type: ignore
|
|
206
180
|
]:
|
|
207
181
|
"""
|
|
208
182
|
Strongly typed search method for Genspark API.
|
|
@@ -212,13 +186,13 @@ class Genspark(AISearch):
|
|
|
212
186
|
raw: If True, yields/returns raw event dicts.
|
|
213
187
|
Returns:
|
|
214
188
|
- If stream=True, raw=True: Iterator[dict]
|
|
215
|
-
- If stream=True, raw=False: Iterator[
|
|
189
|
+
- If stream=True, raw=False: Iterator[SearchResponse | dict]
|
|
216
190
|
- If stream=False, raw=True: List[dict]
|
|
217
|
-
- If stream=False, raw=False:
|
|
191
|
+
- If stream=False, raw=False: SearchResponse
|
|
218
192
|
"""
|
|
219
193
|
self._reset_search_data()
|
|
220
194
|
url = f"{self.chat_endpoint}?query={requests.utils.quote(prompt)}"
|
|
221
|
-
def _process_stream() -> Iterator[Union[dict,
|
|
195
|
+
def _process_stream() -> Iterator[Union[dict, SearchResponse]]: #type: ignore
|
|
222
196
|
try:
|
|
223
197
|
with self.session.post(
|
|
224
198
|
url,
|
|
@@ -227,12 +201,12 @@ class Genspark(AISearch):
|
|
|
227
201
|
json={},
|
|
228
202
|
stream=True,
|
|
229
203
|
timeout=self.timeout,
|
|
230
|
-
) as
|
|
231
|
-
if not
|
|
204
|
+
) as SearchResponse:
|
|
205
|
+
if not SearchResponse.ok:
|
|
232
206
|
raise exceptions.APIConnectionError(
|
|
233
|
-
f"Failed to generate
|
|
207
|
+
f"Failed to generate SearchResponse - ({SearchResponse.status_code}, {SearchResponse.reason}) - {SearchResponse.text}"
|
|
234
208
|
)
|
|
235
|
-
for line in
|
|
209
|
+
for line in SearchResponse.iter_lines(decode_unicode=True):
|
|
236
210
|
if not line or not line.startswith("data: "):
|
|
237
211
|
continue
|
|
238
212
|
try:
|
|
@@ -292,7 +266,7 @@ class Genspark(AISearch):
|
|
|
292
266
|
if event_type == "result_field_delta" and field_name and field_name.startswith("streaming_detail_answer"):
|
|
293
267
|
delta_text = data.get("delta", "")
|
|
294
268
|
delta_text = re.sub(r"\[.*?\]\(.*?\)", "", delta_text)
|
|
295
|
-
yield
|
|
269
|
+
yield SearchResponse(delta_text)
|
|
296
270
|
elif event_type == "result_start":
|
|
297
271
|
processed_event_payload = {"event": "result_start", "data": {"id": result_id, "source": data.get("result_source"), "score": data.get("result_score")}}
|
|
298
272
|
elif event_type == "classify_query_result":
|
|
@@ -321,28 +295,28 @@ class Genspark(AISearch):
|
|
|
321
295
|
if stream:
|
|
322
296
|
return processed_stream_gen
|
|
323
297
|
else:
|
|
324
|
-
|
|
298
|
+
full_SearchResponse_text = ""
|
|
325
299
|
all_raw_events_for_this_search: List[dict] = []
|
|
326
300
|
for item in processed_stream_gen:
|
|
327
301
|
if raw:
|
|
328
302
|
all_raw_events_for_this_search.append(cast(dict, item))
|
|
329
303
|
else:
|
|
330
|
-
if isinstance(item,
|
|
331
|
-
|
|
304
|
+
if isinstance(item, SearchResponse):
|
|
305
|
+
full_SearchResponse_text += str(item)
|
|
332
306
|
if raw:
|
|
333
|
-
self.
|
|
307
|
+
self.last_SearchResponse = {"raw_events": all_raw_events_for_this_search}
|
|
334
308
|
return all_raw_events_for_this_search
|
|
335
309
|
else:
|
|
336
|
-
|
|
337
|
-
self.
|
|
338
|
-
return
|
|
310
|
+
final_text_SearchResponse = SearchResponse(full_SearchResponse_text)
|
|
311
|
+
self.last_SearchResponse = final_text_SearchResponse
|
|
312
|
+
return final_text_SearchResponse
|
|
339
313
|
|
|
340
314
|
if __name__ == "__main__":
|
|
341
315
|
from rich import print
|
|
342
316
|
ai = Genspark()
|
|
343
317
|
try:
|
|
344
|
-
|
|
345
|
-
for chunk in
|
|
318
|
+
SearchResponse = ai.search(input(">>> "), stream=True, raw=False)
|
|
319
|
+
for chunk in SearchResponse:
|
|
346
320
|
print(chunk, end="", flush=True)
|
|
347
321
|
except KeyboardInterrupt:
|
|
348
322
|
print("\nSearch interrupted by user.")
|
|
@@ -6,23 +6,11 @@ import time
|
|
|
6
6
|
import re
|
|
7
7
|
from typing import Dict, Optional, Generator, Union, Any
|
|
8
8
|
|
|
9
|
-
from webscout.AIbase import AISearch
|
|
9
|
+
from webscout.AIbase import AISearch, SearchResponse
|
|
10
10
|
from webscout import exceptions
|
|
11
11
|
from webscout.litagent import LitAgent
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class Response:
|
|
15
|
-
"""A wrapper class for Hika API responses."""
|
|
16
|
-
def __init__(self, text: str):
|
|
17
|
-
self.text = text
|
|
18
|
-
|
|
19
|
-
def __str__(self):
|
|
20
|
-
return self.text
|
|
21
|
-
|
|
22
|
-
def __repr__(self):
|
|
23
|
-
return self.text
|
|
24
|
-
|
|
25
|
-
|
|
26
14
|
class Hika(AISearch):
|
|
27
15
|
"""A class to interact with the Hika AI search API."""
|
|
28
16
|
|
|
@@ -88,7 +76,7 @@ class Hika(AISearch):
|
|
|
88
76
|
prompt: str,
|
|
89
77
|
stream: bool = False,
|
|
90
78
|
raw: bool = False,
|
|
91
|
-
) -> Union[
|
|
79
|
+
) -> Union[SearchResponse, Generator[Union[Dict[str, str], SearchResponse], None, None]]:
|
|
92
80
|
"""Search using the Hika API and get AI-generated responses."""
|
|
93
81
|
if not prompt or len(prompt) < 2:
|
|
94
82
|
raise exceptions.APIConnectionError("Search query must be at least 2 characters long")
|
|
@@ -141,7 +129,7 @@ class Hika(AISearch):
|
|
|
141
129
|
if raw:
|
|
142
130
|
yield {"text": clean_chunk}
|
|
143
131
|
else:
|
|
144
|
-
yield
|
|
132
|
+
yield SearchResponse(clean_chunk)
|
|
145
133
|
elif "references" in data:
|
|
146
134
|
# Optionally yield references if raw requested
|
|
147
135
|
if raw:
|
|
@@ -163,7 +151,7 @@ class Hika(AISearch):
|
|
|
163
151
|
if not raw:
|
|
164
152
|
# Clean up the response text one final time
|
|
165
153
|
cleaned_response = self.format_response(full_response)
|
|
166
|
-
self.last_response =
|
|
154
|
+
self.last_response = SearchResponse(cleaned_response)
|
|
167
155
|
return self.last_response
|
|
168
156
|
|
|
169
157
|
return for_stream() if stream else for_non_stream()
|