entari-plugin-hyw 3.4.1__py3-none-any.whl → 3.5.0rc1__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.

Files changed (91) hide show
  1. entari_plugin_hyw/__init__.py +14 -89
  2. entari_plugin_hyw/assets/card-dist/index.html +135 -0
  3. entari_plugin_hyw/assets/card-dist/logos/anthropic.svg +1 -0
  4. entari_plugin_hyw/assets/card-dist/logos/cerebras.svg +9 -0
  5. entari_plugin_hyw/assets/card-dist/logos/deepseek.png +0 -0
  6. entari_plugin_hyw/assets/card-dist/logos/gemini.svg +1 -0
  7. entari_plugin_hyw/assets/card-dist/logos/google.svg +1 -0
  8. entari_plugin_hyw/assets/card-dist/logos/grok.png +0 -0
  9. entari_plugin_hyw/assets/card-dist/logos/huggingface.png +0 -0
  10. entari_plugin_hyw/assets/card-dist/logos/microsoft.svg +15 -0
  11. entari_plugin_hyw/assets/card-dist/logos/minimax.png +0 -0
  12. entari_plugin_hyw/assets/card-dist/logos/mistral.png +0 -0
  13. entari_plugin_hyw/assets/card-dist/logos/nvida.png +0 -0
  14. entari_plugin_hyw/assets/card-dist/logos/openai.svg +1 -0
  15. entari_plugin_hyw/assets/card-dist/logos/openrouter.png +0 -0
  16. entari_plugin_hyw/assets/card-dist/logos/perplexity.svg +24 -0
  17. entari_plugin_hyw/assets/card-dist/logos/qwen.png +0 -0
  18. entari_plugin_hyw/assets/card-dist/logos/xai.png +0 -0
  19. entari_plugin_hyw/assets/card-dist/logos/xiaomi.png +0 -0
  20. entari_plugin_hyw/assets/card-dist/logos/zai.png +0 -0
  21. entari_plugin_hyw/assets/card-dist/vite.svg +1 -0
  22. entari_plugin_hyw/assets/icon/cerebras.svg +9 -0
  23. entari_plugin_hyw/card-ui/.gitignore +24 -0
  24. entari_plugin_hyw/card-ui/README.md +5 -0
  25. entari_plugin_hyw/card-ui/index.html +16 -0
  26. entari_plugin_hyw/card-ui/package-lock.json +2342 -0
  27. entari_plugin_hyw/card-ui/package.json +31 -0
  28. entari_plugin_hyw/card-ui/public/logos/anthropic.svg +1 -0
  29. entari_plugin_hyw/card-ui/public/logos/cerebras.svg +9 -0
  30. entari_plugin_hyw/card-ui/public/logos/deepseek.png +0 -0
  31. entari_plugin_hyw/card-ui/public/logos/gemini.svg +1 -0
  32. entari_plugin_hyw/card-ui/public/logos/google.svg +1 -0
  33. entari_plugin_hyw/card-ui/public/logos/grok.png +0 -0
  34. entari_plugin_hyw/card-ui/public/logos/huggingface.png +0 -0
  35. entari_plugin_hyw/card-ui/public/logos/microsoft.svg +15 -0
  36. entari_plugin_hyw/card-ui/public/logos/minimax.png +0 -0
  37. entari_plugin_hyw/card-ui/public/logos/mistral.png +0 -0
  38. entari_plugin_hyw/card-ui/public/logos/nvida.png +0 -0
  39. entari_plugin_hyw/card-ui/public/logos/openai.svg +1 -0
  40. entari_plugin_hyw/card-ui/public/logos/openrouter.png +0 -0
  41. entari_plugin_hyw/card-ui/public/logos/perplexity.svg +24 -0
  42. entari_plugin_hyw/card-ui/public/logos/qwen.png +0 -0
  43. entari_plugin_hyw/card-ui/public/logos/xai.png +0 -0
  44. entari_plugin_hyw/card-ui/public/logos/xiaomi.png +0 -0
  45. entari_plugin_hyw/card-ui/public/logos/zai.png +0 -0
  46. entari_plugin_hyw/card-ui/public/vite.svg +1 -0
  47. entari_plugin_hyw/card-ui/src/App.vue +216 -0
  48. entari_plugin_hyw/card-ui/src/assets/vue.svg +1 -0
  49. entari_plugin_hyw/card-ui/src/components/HelloWorld.vue +41 -0
  50. entari_plugin_hyw/card-ui/src/components/MarkdownContent.vue +330 -0
  51. entari_plugin_hyw/card-ui/src/components/SectionCard.vue +41 -0
  52. entari_plugin_hyw/card-ui/src/components/StageCard.vue +163 -0
  53. entari_plugin_hyw/card-ui/src/main.ts +5 -0
  54. entari_plugin_hyw/card-ui/src/style.css +8 -0
  55. entari_plugin_hyw/card-ui/src/types.ts +51 -0
  56. entari_plugin_hyw/card-ui/tsconfig.app.json +16 -0
  57. entari_plugin_hyw/card-ui/tsconfig.json +7 -0
  58. entari_plugin_hyw/card-ui/tsconfig.node.json +26 -0
  59. entari_plugin_hyw/card-ui/vite.config.ts +16 -0
  60. entari_plugin_hyw/core/config.py +0 -3
  61. entari_plugin_hyw/core/pipeline.py +136 -61
  62. entari_plugin_hyw/core/render_vue.py +255 -0
  63. entari_plugin_hyw/test_output/render_0.jpg +0 -0
  64. entari_plugin_hyw/test_output/render_1.jpg +0 -0
  65. entari_plugin_hyw/test_output/render_2.jpg +0 -0
  66. entari_plugin_hyw/test_output/render_3.jpg +0 -0
  67. entari_plugin_hyw/test_output/render_4.jpg +0 -0
  68. entari_plugin_hyw/tests/ui_test_output.jpg +0 -0
  69. entari_plugin_hyw/tests/verify_ui.py +139 -0
  70. entari_plugin_hyw/utils/misc.py +0 -3
  71. entari_plugin_hyw/utils/prompts.py +65 -63
  72. {entari_plugin_hyw-3.4.1.dist-info → entari_plugin_hyw-3.5.0rc1.dist-info}/METADATA +5 -2
  73. entari_plugin_hyw-3.5.0rc1.dist-info/RECORD +99 -0
  74. entari_plugin_hyw/assets/libs/highlight.css +0 -10
  75. entari_plugin_hyw/assets/libs/highlight.js +0 -1213
  76. entari_plugin_hyw/assets/libs/katex-auto-render.js +0 -1
  77. entari_plugin_hyw/assets/libs/katex.css +0 -1
  78. entari_plugin_hyw/assets/libs/katex.js +0 -1
  79. entari_plugin_hyw/assets/libs/tailwind.css +0 -1
  80. entari_plugin_hyw/assets/package-lock.json +0 -953
  81. entari_plugin_hyw/assets/package.json +0 -16
  82. entari_plugin_hyw/assets/tailwind.config.js +0 -12
  83. entari_plugin_hyw/assets/tailwind.input.css +0 -235
  84. entari_plugin_hyw/assets/template.html +0 -157
  85. entari_plugin_hyw/assets/template.html.bak +0 -157
  86. entari_plugin_hyw/assets/template.j2 +0 -400
  87. entari_plugin_hyw/core/render.py +0 -629
  88. entari_plugin_hyw/utils/prompts_cn.py +0 -119
  89. entari_plugin_hyw-3.4.1.dist-info/RECORD +0 -48
  90. {entari_plugin_hyw-3.4.1.dist-info → entari_plugin_hyw-3.5.0rc1.dist-info}/WHEEL +0 -0
  91. {entari_plugin_hyw-3.4.1.dist-info → entari_plugin_hyw-3.5.0rc1.dist-info}/top_level.txt +0 -0
@@ -12,9 +12,9 @@ from arclet.entari.event.command import CommandReceive
12
12
 
13
13
  from .core.hyw import HYW
14
14
  from .core.history import HistoryManager
15
- from .core.render import ContentRenderer
15
+ from .core.render_vue import ContentRenderer
16
16
  from .utils.misc import process_onebot_json, process_images, resolve_model_name
17
- from arclet.entari.event.lifespan import Cleanup
17
+ from arclet.entari.event.lifespan import Cleanup, Startup
18
18
 
19
19
  import os
20
20
  import secrets
@@ -69,6 +69,7 @@ class HywConfig(BasicConfModel):
69
69
  save_conversation: bool = False
70
70
  icon: str = "openai"
71
71
  render_timeout_ms: int = 6000
72
+ render_image_timeout_ms: int = 3000
72
73
  extra_body: Optional[Dict[str, Any]] = None
73
74
  vision_extra_body: Optional[Dict[str, Any]] = None
74
75
  instruct_extra_body: Optional[Dict[str, Any]] = None
@@ -100,12 +101,20 @@ renderer = ContentRenderer()
100
101
  hyw = HYW(config=conf)
101
102
 
102
103
 
103
-
104
+ @listen(Startup)
105
+ async def _hyw_startup():
106
+ try:
107
+ # Pre-launch browser
108
+ logger.info("HYW: Pre-launching renderer browser...")
109
+ await renderer.start()
110
+ except Exception as e:
111
+ logger.warning(f"HYW: Renderer warm-up failed: {e}")
104
112
 
105
113
  @listen(Cleanup, once=True)
106
114
  async def _hyw_cleanup():
107
115
  try:
108
116
  await hyw.close()
117
+ await renderer.close()
109
118
  except Exception as e:
110
119
  logger.warning(f"HYW cleanup error: {e}")
111
120
 
@@ -270,111 +279,27 @@ async def process_request(session: Session[MessageCreatedEvent], all_param: Opti
270
279
  with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as tf:
271
280
  output_path = tf.name
272
281
  model_used = final_resp.get("model_used")
273
- vision_model_used = final_resp.get("vision_model_used")
274
-
275
- # Helper to infer icon from model name
276
- def infer_icon_from_model(model_name: str) -> str:
277
- """Infer icon name from model name (e.g. 'google/gemini-3-flash' -> 'google' or 'gemini')"""
278
- if not model_name:
279
- return conf.icon
280
- name_lower = model_name.lower()
281
- # Check for known providers/models in the name
282
- known_icons = ["google", "gemini", "openai", "anthropic", "deepseek", "mistral",
283
- "qwen", "grok", "xai", "perplexity", "microsoft", "minimax", "nvidia"]
284
- for icon_name in known_icons:
285
- if icon_name in name_lower:
286
- return icon_name
287
- return conf.icon
288
-
289
- icon = conf.icon
290
- m_conf = None
291
- if model_used:
292
- m_conf = next((m for m in conf.models if m.get("name") == model_used), None)
293
- if m_conf:
294
- icon = m_conf.get("icon", infer_icon_from_model(model_used))
295
- else:
296
- # Model not in config list, infer from name
297
- icon = infer_icon_from_model(model_used)
298
282
 
299
283
  # Determine session short code
300
284
  if hist_key:
301
285
  display_session_id = history_manager.get_code_by_key(hist_key)
302
286
  if not display_session_id:
303
- # Should not happen if key exists, but fallback
304
287
  display_session_id = history_manager.generate_short_code()
305
288
  else:
306
- # New conversation, pre-generate code
307
289
  display_session_id = history_manager.generate_short_code()
308
290
 
309
- # Determine vision base url and icon
310
- vision_base_url = None
311
- vision_icon = None
312
-
313
- if vision_model_used:
314
- v_conf = next((m for m in conf.models if m.get("name") == vision_model_used), None)
315
- if v_conf:
316
- vision_base_url = v_conf.get("base_url")
317
- vision_icon = v_conf.get("icon", infer_icon_from_model(vision_model_used))
318
- else:
319
- vision_icon = infer_icon_from_model(vision_model_used)
320
-
321
- # Handle Vision Only Mode (suppress text model display)
322
- render_model_name = model_used or conf.model_name or "unknown"
323
- render_icon = icon
324
- render_base_url = m_conf.get("base_url", conf.base_url) if m_conf else conf.base_url
325
-
326
- if not model_used and vision_model_used:
327
- render_model_name = ""
328
- render_icon = ""
329
-
330
291
  # Use stats_list if available, otherwise standard stats
331
292
  stats_to_render = final_resp.get("stats_list", final_resp.get("stats", {}))
332
-
333
- # Determine Behavior Summary & Provider Name
334
-
335
- # 1. Behavior Summary
336
- behavior_summary = "Text Generation"
337
- if vision_model_used:
338
- behavior_summary = "Visual Analysis"
339
- elif any(s.get("name") == "Search" for s in final_resp.get("stages_used", []) or []):
340
- behavior_summary = "Search-Augmented"
341
-
342
- # 2. Provider Name
343
- # Try to get from m_conf (resolved above)
344
- provider_name = "Unknown Provider"
345
- if model_used and m_conf:
346
- provider_name = m_conf.get("provider", "Unknown Provider")
347
- elif not model_used and vision_model_used:
348
- # If only vision model used (unlikely but possible in code logic)
349
- if 'v_conf' in locals() and v_conf:
350
- provider_name = v_conf.get("provider", "Unknown Provider")
351
-
352
- # If still unknown and we have base_url, maybe use domain as last resort fallback?
353
- # User said: "provider does not automatically get from url if not filled"
354
- # So if it's "Unknown Provider", we leave it or maybe empty string?
355
- # Let's stick to "Unknown Provider" or just empty if we want to be clean.
356
- # But for UI validation it's better to show something if missing config.
357
293
 
358
294
  render_ok = await renderer.render(
359
295
  markdown_content=content,
360
296
  output_path=output_path,
361
- suggestions=[],
362
297
  stats=stats_to_render,
363
298
  references=structured.get("references", []),
364
299
  page_references=structured.get("page_references", []),
365
300
  image_references=structured.get("image_references", []),
366
- flow_steps=structured.get("flow_steps", []),
367
301
  stages_used=final_resp.get("stages_used", []),
368
- model_name=render_model_name,
369
- provider_name=provider_name,
370
- behavior_summary=behavior_summary,
371
- icon_config=render_icon,
372
- vision_model_name=vision_model_used,
373
- vision_base_url=vision_base_url,
374
- vision_icon_config=vision_icon,
375
- base_url=render_base_url,
376
- billing_info=final_resp.get("billing_info"),
377
- render_timeout_ms=conf.render_timeout_ms
302
+ image_timeout=conf.render_image_timeout_ms,
378
303
  )
379
304
 
380
305
  # Send & Save
@@ -473,7 +398,7 @@ async def handle_question_command(session: Session[MessageCreatedEvent], result:
473
398
 
474
399
  await process_request(session, args.get("all_param"), selected_model=None, selected_vision_model=None, conversation_key_override=None, local_mode=False)
475
400
 
476
- metadata("hyw", author=[{"name": "kumoSleeping", "email": "zjr2992@outlook.com"}], version="3.2.105", config=HywConfig)
401
+ metadata("hyw", author=[{"name": "kumoSleeping", "email": "zjr2992@outlook.com"}], version="3.5.0-rc1", config=HywConfig)
477
402
 
478
403
  @leto.on(CommandReceive)
479
404
  async def remove_at(content: MessageChain):