entari-plugin-hyw 4.0.0rc9__py3-none-any.whl → 4.0.0rc10__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 entari-plugin-hyw might be problematic. Click here for more details.

@@ -162,6 +162,7 @@ class HywConfig(BasicConfModel):
162
162
  admins: List[str] = field(default_factory=list)
163
163
  models: List[Dict[str, Any]] = field(default_factory=list)
164
164
  question_command: str = "/q"
165
+ web_command: str = "/w"
165
166
  language: str = "Simplified Chinese"
166
167
  temperature: float = 0.4
167
168
 
@@ -169,7 +170,7 @@ class HywConfig(BasicConfModel):
169
170
  api_key: Optional[str] = None
170
171
  base_url: str = "https://openrouter.ai/api/v1"
171
172
 
172
- search_engine: str = "google"
173
+ search_engine: str = "duckduckgo"
173
174
 
174
175
  headless: bool = False
175
176
  save_conversation: bool = False
@@ -177,19 +178,14 @@ class HywConfig(BasicConfModel):
177
178
  quote: bool = False
178
179
  theme_color: str = "#ff0000"
179
180
 
180
- # Nested configurations
181
+ # Main model configuration (used for summary/main LLM calls)
181
182
  main: Optional[Dict[str, Any]] = None
182
- instruct: Optional[Dict[str, Any]] = None
183
- vision: Optional[Dict[str, Any]] = None
184
- deepsearch_instruct: Optional[Dict[str, Any]] = None
185
- deepsearch_agent: Optional[Dict[str, Any]] = None
186
183
 
187
184
  def __post_init__(self):
188
185
  self.theme_color = parse_color(self.theme_color)
189
186
 
190
187
  def to_hyw_core_config(self) -> HywCoreConfig:
191
188
  main_cfg = self.main or {}
192
- instruct_cfg = self.instruct or {}
193
189
 
194
190
  return HywCoreConfig.from_dict({
195
191
  "models": self.models,
@@ -207,20 +203,7 @@ class HywConfig(BasicConfModel):
207
203
  "summary_api_key": main_cfg.get("api_key"),
208
204
  "summary_base_url": main_cfg.get("base_url"),
209
205
  "summary_extra_body": main_cfg.get("extra_body"),
210
-
211
- # Map nested 'instruct' config to instruct stage
212
- "instruct_model": instruct_cfg.get("model_name"),
213
- "instruct_api_key": instruct_cfg.get("api_key"),
214
- "instruct_base_url": instruct_cfg.get("base_url"),
215
- "instruct_extra_body": instruct_cfg.get("extra_body"),
216
206
  })
217
-
218
- def get_model_config(self, stage: str) -> Dict[str, Any]:
219
- return {
220
- "model_name": self.model_name,
221
- "api_key": self.api_key,
222
- "base_url": self.base_url,
223
- }
224
207
 
225
208
 
226
209
  conf = plugin_config(HywConfig)
@@ -690,7 +673,7 @@ async def handle_question_command(session: Session[MessageCreatedEvent], result:
690
673
 
691
674
 
692
675
  # Search/Web Command (/w)
693
- alc_search = Alconna("/w", Args["query;?", AllParam])
676
+ alc_search = Alconna(conf.web_command, Args["query;?", AllParam])
694
677
 
695
678
  @command.on(alc_search)
696
679
  async def handle_web_command(session: Session[MessageCreatedEvent], result: Arparma):
@@ -756,6 +739,17 @@ async def handle_web_command(session: Session[MessageCreatedEvent], result: Arpa
756
739
 
757
740
  search_cache.cleanup()
758
741
  return
742
+ else:
743
+ # Reply to a non-cached message: append reply content to query
744
+ try:
745
+ # session.reply.origin.message is a list, wrap it in MessageChain
746
+ reply_msg = MessageChain(session.reply.origin.message)
747
+ reply_content = str(reply_msg.get(Text)).strip()
748
+ if reply_content:
749
+ query = f"{query} {reply_content}".strip() if query else reply_content
750
+ logger.info(f"/w appended reply content, new query: '{query}'")
751
+ except Exception as e:
752
+ logger.warning(f"/w failed to extract reply content: {e}")
759
753
 
760
754
  # No query and no cache context - nothing to do
761
755
  if not query:
@@ -805,8 +799,10 @@ async def handle_web_command(session: Session[MessageCreatedEvent], result: Arpa
805
799
  await session.send(filter_error)
806
800
  return
807
801
 
808
- # Search first
802
+ # Start search and tab pre-warming in parallel
803
+ local_renderer = await get_content_renderer()
809
804
  search_task = asyncio.create_task(core.search([search_query]))
805
+ tab_task = asyncio.create_task(local_renderer.prepare_tab())
810
806
 
811
807
  if conf.reaction:
812
808
  asyncio.create_task(react(session, "🔍"))
@@ -815,17 +811,25 @@ async def handle_web_command(session: Session[MessageCreatedEvent], result: Arpa
815
811
  flat_results = results[0] if results else []
816
812
 
817
813
  if not flat_results:
814
+ try: await tab_task
815
+ except: pass
818
816
  await session.send("Search returned no results.")
819
817
  return
820
818
 
821
819
  visible = [r for r in flat_results if not r.get("_hidden", False)]
822
820
 
823
821
  if not visible:
822
+ try: await tab_task
823
+ except: pass
824
824
  await session.send("Search returned no visible results.")
825
825
  return
826
826
 
827
827
  # === Filter Mode: Screenshot matching links ===
828
828
  if filters:
829
+ # No need for tab in filter/screenshot mode, cancel it
830
+ try: await tab_task
831
+ except: pass
832
+
829
833
  urls_to_screenshot = []
830
834
 
831
835
  for filter_type, filter_value, count in filters:
@@ -881,20 +885,42 @@ async def handle_web_command(session: Session[MessageCreatedEvent], result: Arpa
881
885
  await session.send("截图失败")
882
886
  return
883
887
 
884
- # === Normal Search Mode: Screenshot search results page ===
885
- search_service = core._search_service
886
- search_url = search_service._build_search_url(search_query)
888
+ # === Normal Search Mode: Render search results as Sources card ===
889
+
890
+ # Build references from search results for Sources card
891
+ references = []
892
+ for i, res in enumerate(visible[:10]):
893
+ references.append({
894
+ "title": res.get("title", f"Result {i+1}"),
895
+ "url": res.get("url", ""),
896
+ "snippet": res.get("content", "") or res.get("snippet", ""),
897
+ "original_idx": i + 1,
898
+ })
887
899
 
888
- # Handle address bar search marker
889
- if search_url.startswith("__ADDRESS_BAR_SEARCH__:"):
890
- import urllib.parse
891
- encoded_query = urllib.parse.quote_plus(search_query)
892
- search_url = f"https://www.google.com/search?q={encoded_query}"
900
+ try:
901
+ tab_id = await tab_task
902
+ except Exception:
903
+ tab_id = None
904
+
905
+ with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as tf:
906
+ output_path = tf.name
893
907
 
894
- b64_img = await core.screenshot(search_url)
908
+ # Render Sources card with search results (no markdown content, just references)
909
+ render_ok = await core.render(
910
+ markdown_content=f"# 搜索结果: {search_query}",
911
+ output_path=output_path,
912
+ stats={"total_time": 0},
913
+ references=references,
914
+ page_references=[],
915
+ stages_used=[{"name": "search", "description": f"搜索 \"{search_query}\"", "time": 0}],
916
+ tab_id=tab_id
917
+ )
895
918
 
896
- if b64_img:
897
- msg_chain = MessageChain(Image(src=f'data:image/jpeg;base64,{b64_img}'))
919
+ if render_ok and os.path.exists(output_path):
920
+ with open(output_path, "rb") as f:
921
+ img_data = base64.b64encode(f.read()).decode()
922
+
923
+ msg_chain = MessageChain(Image(src=f'data:image/png;base64,{img_data}'))
898
924
  if conf.quote:
899
925
  msg_chain = MessageChain(Quote(session.event.message.id)) + msg_chain
900
926
 
@@ -909,8 +935,10 @@ async def handle_web_command(session: Session[MessageCreatedEvent], result: Arpa
909
935
  mid = str(session.event.message.id) if getattr(session.event, "message", None) else str(session.event.id)
910
936
  context_id = f"guild_{session.guild.id}" if session.guild else "user"
911
937
  history_manager.remember(mid, [{"role": "user", "content": f"/w {query}"}], [], {}, context_id=context_id)
938
+
939
+ os.remove(output_path)
912
940
  else:
913
- await session.send(f"截图搜索页面失败: {search_url}")
941
+ await session.send("渲染搜索结果失败")
914
942
 
915
943
  search_cache.cleanup() # Lazy cleanup
916
944
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: entari_plugin_hyw
3
- Version: 4.0.0rc9
3
+ Version: 4.0.0rc10
4
4
  Summary: Use large language models to interpret chat messages
5
5
  Author-email: kumoSleeping <zjr2992@outlook.com>
6
6
  License: MIT
@@ -1,5 +1,5 @@
1
1
  entari_plugin_hyw/Untitled-1,sha256=wbsr5i9iorqBMIYK4aAnpNTek3mXbhvyo2YOYw38pE4,30187
2
- entari_plugin_hyw/__init__.py,sha256=laQrEH-CdofBg3EEqIEOTwJu0pHlMG0wIvdQo8AycZk,35057
2
+ entari_plugin_hyw/__init__.py,sha256=Fp82hv0D-Uu36POkjBWFVrZy_3JReBN0fxKFNrQwXIU,36258
3
3
  entari_plugin_hyw/history.py,sha256=0XJwbfvXH5T1EPt4G1J5wWMJsKi0FfmajY5cvw8CQWE,12065
4
4
  entari_plugin_hyw/misc.py,sha256=4ABzCHbEA87UCQfBX7AgAqACQwjQIhCSZuqHXPFGokg,5527
5
5
  entari_plugin_hyw/search_cache.py,sha256=7MIhTm5_YnZjc0aBaX7AE4AJp0VT8eU6ObR6mTkoerc,4285
@@ -9,14 +9,14 @@ hyw_core/core.py,sha256=G96C9mhmuXRwFOwIYm5M6q0ys1QD_2eQYvP89e_bmWg,10455
9
9
  hyw_core/definitions.py,sha256=syYMNy3vdey7VuSlD3JUZ0gjlp5tmVkGHup-nimT0X0,3264
10
10
  hyw_core/image_cache.py,sha256=t8pr1kgH2ngK9IhrBAhzUqhBWERNztUywMzgCFZEtQk,9899
11
11
  hyw_core/pipeline.py,sha256=ZWwF0DHa29-65lUMU1_Fem3xQmxl7X_vgeni0ErOb8Q,22826
12
- hyw_core/search.py,sha256=IqYCeWkIPpssLx8vHEv3qbqndLuPy5z6cE_L-IhNcNk,7468
13
- hyw_core/browser_control/__init__.py,sha256=X1vHZpYXLG-P1RRivVyK014WKnv48GN1ibF9TbMp_-c,1482
12
+ hyw_core/search.py,sha256=L9LF3s4o4-ypDRyevvIlAqC0pa7xNYv-nESAql9N-pk,7345
13
+ hyw_core/browser_control/__init__.py,sha256=IeMErRC6fbq1PJWNK3klSbarSrUwOM4yyd_kJ6uWCPM,1406
14
14
  hyw_core/browser_control/landing.html,sha256=wgqldumdylz69T83pvOkrigT1Mdb9GY0_KU0ceLGwdY,4642
15
- hyw_core/browser_control/manager.py,sha256=U8dVpkWTG5pcIE5WiSQSfTx4gEo9PnBbmBD0KZcLBbU,5513
16
- hyw_core/browser_control/renderer.py,sha256=hsCjJPMSCAvqTFtiAmyjaw0IE8xmbIjq5VK9dd70gfc,15539
17
- hyw_core/browser_control/service.py,sha256=tuNaEnxRZVkLgQczWnWDyEHXhyvhF9RboDmnT3OFX34,35905
15
+ hyw_core/browser_control/manager.py,sha256=-dHb0FamRsLfuU3jqX5cKaDo8DOOFV32zY912GuMdXU,6048
16
+ hyw_core/browser_control/renderer.py,sha256=s-QNIU-NMVQGLd_drLmeERgHsTm6C9XYm78CObt2KXc,17409
17
+ hyw_core/browser_control/service.py,sha256=YKRxXnpSkbso2osmwRlImPldUKMFsGrwgGoQqMuiGf8,36483
18
18
  hyw_core/browser_control/assets/index.html,sha256=BpbM0vD9OYicE5MBHSVLo3j_y-MpULI82PMqmBKpWT8,2328623
19
- hyw_core/browser_control/assets/card-dist/index.html,sha256=fNfT_0TgSZLqwuTtKAl3Wzc4lKRAY_rbWxc_mQHfaCs,2209006
19
+ hyw_core/browser_control/assets/card-dist/index.html,sha256=Xw-hQ5ctdQkK-1jV8_gqMdgVGNZDwWZvIAqNrh2eK7g,2210054
20
20
  hyw_core/browser_control/assets/card-dist/vite.svg,sha256=SnSK_UQ5GLsWWRyDTEAdrjPoeGGrXbrQgRw6O0qSFPs,1497
21
21
  hyw_core/browser_control/assets/card-dist/logos/anthropic.svg,sha256=ASsy1ypo3osNc3n-B0R81tk_dIFsVgg7qQORrd5T2kA,558
22
22
  hyw_core/browser_control/assets/card-dist/logos/cerebras.svg,sha256=bpmiiYTODwc06knTmPj3GQ7NNtosMog5lkggvB_Z-7M,44166
@@ -54,15 +54,17 @@ hyw_core/browser_control/assets/logos/qwen.png,sha256=eqLbnIPbjh2_PsODU_mmqjeD82
54
54
  hyw_core/browser_control/assets/logos/xai.png,sha256=uSulvvDVqoA4RUOW0ZAkdvBVM2rpyGJRZIbn5dEFspw,362
55
55
  hyw_core/browser_control/assets/logos/xiaomi.png,sha256=WHxlDFGU5FCjb-ure3ngdGG18-efYZUUfqA3_lqCUN0,4084
56
56
  hyw_core/browser_control/assets/logos/zai.png,sha256=K-gnabdsjMLInppHA1Op7Nyt33iegrx1x-yNlvCZ0Tc,2351
57
- hyw_core/browser_control/engines/__init__.py,sha256=G-bjcxWMaPZoR4tUz-OcGhZDkQwkXjK234qVEFvjEbE,338
57
+ hyw_core/browser_control/engines/__init__.py,sha256=01-jOjvtQcqWIwwY56ql3j00oSHGE2XhDHjkIi1Ij3Q,284
58
58
  hyw_core/browser_control/engines/base.py,sha256=q5y4SM1G6xS7-6TQ-nZz9iTWw3XonjJn01fWzoTxr6c,414
59
59
  hyw_core/browser_control/engines/default.py,sha256=BlHCQI4-rN9cEzLLfqvRD4bvhyP2G2KUGlo92J4kFNw,6092
60
60
  hyw_core/browser_control/engines/duckduckgo.py,sha256=QVYj1I6Fw6--2-f3DYdHVlOmeLPzet9qG4HUT7ynrSE,6789
61
- hyw_core/browser_control/engines/google.py,sha256=PmU0_n8UrnQ1oyYVS-Y_jLS6rzgkQZK_7yHlGeAUooY,6098
61
+ hyw_core/crawling/__init__.py,sha256=W5Be02uQueAyADFhPXVbDAFpNUJ_W7KdMtMr923_N24,437
62
+ hyw_core/crawling/completeness.py,sha256=iQoTHLXkXLCoT89NhoUO7P3_Zz8rfpa-2Wah_KvG-dI,12069
63
+ hyw_core/crawling/models.py,sha256=pCKe0k9xT3taSAlTlh0PazcLV0xYsm8p3XIkLHGf-LM,2353
62
64
  hyw_core/stages/__init__.py,sha256=W89cWpq-HBLi2FprtJQSjQNLzpbhM8ZCkqPG61D_imE,521
63
65
  hyw_core/stages/base.py,sha256=EfnTkISXbBNxjARykqIhmMrVqw2tqZl7ozJbJEbRnhI,2806
64
66
  hyw_core/stages/summary.py,sha256=ODOwhIAmBZJuA4KOhUP7Lygch7XSkshrTZj-MdZjbEs,7085
65
- entari_plugin_hyw-4.0.0rc9.dist-info/METADATA,sha256=ofBdYe9A6sFakK9NDDpnmTczWuh1mbm6OpzpLO1j3cc,3844
66
- entari_plugin_hyw-4.0.0rc9.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
67
- entari_plugin_hyw-4.0.0rc9.dist-info/top_level.txt,sha256=ah76OrufRX0okOl4Fv8MO6PXiT0IaZ1oG0eDrdAPoNo,27
68
- entari_plugin_hyw-4.0.0rc9.dist-info/RECORD,,
67
+ entari_plugin_hyw-4.0.0rc10.dist-info/METADATA,sha256=9xYusySUW6RTe5N51Y8hzawLbsqjQUm30EBG-UgpoxU,3845
68
+ entari_plugin_hyw-4.0.0rc10.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
69
+ entari_plugin_hyw-4.0.0rc10.dist-info/top_level.txt,sha256=ah76OrufRX0okOl4Fv8MO6PXiT0IaZ1oG0eDrdAPoNo,27
70
+ entari_plugin_hyw-4.0.0rc10.dist-info/RECORD,,
@@ -5,7 +5,7 @@ This subpackage provides:
5
5
  - BrowserManager: Shared browser instance management
6
6
  - PageService: Page fetching and screenshot capabilities
7
7
  - RenderService: Vue-based card rendering
8
- - Search engines: Bing, Google, DuckDuckGo adapters
8
+ - Search engines: DuckDuckGo adapter
9
9
  """
10
10
 
11
11
  from .manager import (
@@ -28,7 +28,6 @@ from .renderer import (
28
28
  )
29
29
 
30
30
  from .engines.base import SearchEngine
31
- from .engines.google import GoogleEngine
32
31
  from .engines.duckduckgo import DuckDuckGoEngine
33
32
  from .engines.default import DefaultEngine
34
33
 
@@ -59,7 +58,6 @@ __all__ = [
59
58
 
60
59
  # Search Engines
61
60
  "SearchEngine",
62
- "GoogleEngine",
63
61
  "DuckDuckGoEngine",
64
62
  "DefaultEngine",
65
63
  ]