entari-plugin-hyw 3.2.112__tar.gz → 3.3.0__tar.gz
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.
- {entari_plugin_hyw-3.2.112/src/entari_plugin_hyw.egg-info → entari_plugin_hyw-3.3.0}/PKG-INFO +8 -8
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/README.md +6 -1
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/pyproject.toml +2 -6
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/__init__.py +37 -32
- entari_plugin_hyw-3.3.0/src/entari_plugin_hyw/assets/libs/tailwind.css +1 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/tailwind.input.css +1 -1
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/template.j2 +103 -55
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/core/config.py +3 -4
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/core/pipeline.py +507 -282
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/core/render.py +184 -119
- entari_plugin_hyw-3.3.0/src/entari_plugin_hyw/utils/__init__.py +2 -0
- entari_plugin_hyw-3.3.0/src/entari_plugin_hyw/utils/browser.py +40 -0
- entari_plugin_hyw-3.3.0/src/entari_plugin_hyw/utils/playwright_tool.py +36 -0
- entari_plugin_hyw-3.3.0/src/entari_plugin_hyw/utils/prompts.py +128 -0
- entari_plugin_hyw-3.3.0/src/entari_plugin_hyw/utils/search.py +241 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0/src/entari_plugin_hyw.egg-info}/PKG-INFO +8 -8
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw.egg-info/SOURCES.txt +0 -1
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw.egg-info/requires.txt +1 -7
- entari_plugin_hyw-3.2.112/src/entari_plugin_hyw/assets/libs/tailwind.css +0 -1
- entari_plugin_hyw-3.2.112/src/entari_plugin_hyw/utils/__init__.py +0 -3
- entari_plugin_hyw-3.2.112/src/entari_plugin_hyw/utils/browser.py +0 -61
- entari_plugin_hyw-3.2.112/src/entari_plugin_hyw/utils/mcp_playwright.py +0 -128
- entari_plugin_hyw-3.2.112/src/entari_plugin_hyw/utils/playwright_tool.py +0 -46
- entari_plugin_hyw-3.2.112/src/entari_plugin_hyw/utils/prompts.py +0 -92
- entari_plugin_hyw-3.2.112/src/entari_plugin_hyw/utils/search.py +0 -193
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/MANIFEST.in +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/setup.cfg +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/anthropic.svg +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/deepseek.png +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/gemini.svg +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/google.svg +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/grok.png +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/microsoft.svg +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/minimax.png +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/mistral.png +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/nvida.png +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/openai.svg +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/openrouter.png +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/perplexity.svg +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/qwen.png +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/xai.png +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/icon/zai.png +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/libs/highlight.css +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/libs/highlight.js +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/libs/katex-auto-render.js +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/libs/katex.css +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/libs/katex.js +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/package-lock.json +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/package.json +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/tailwind.config.js +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/template.html +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/template.html.bak +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/core/__init__.py +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/core/history.py +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/core/hyw.py +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/core/render.py.bak +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/utils/misc.py +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw.egg-info/dependency_links.txt +0 -0
- {entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw.egg-info/top_level.txt +0 -0
{entari_plugin_hyw-3.2.112/src/entari_plugin_hyw.egg-info → entari_plugin_hyw-3.3.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: entari_plugin_hyw
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.0
|
|
4
4
|
Summary: Use large language models to interpret chat messages
|
|
5
5
|
Author-email: kumoSleeping <zjr2992@outlook.com>
|
|
6
6
|
License: MIT
|
|
@@ -18,15 +18,10 @@ Requires-Python: >=3.10
|
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
Requires-Dist: arclet-entari[full]>=0.16.5
|
|
20
20
|
Requires-Dist: openai
|
|
21
|
-
Requires-Dist: mcp
|
|
22
21
|
Requires-Dist: httpx
|
|
23
22
|
Requires-Dist: markdown>=3.10
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist: playwright>=1.56.0
|
|
23
|
+
Requires-Dist: crawl4ai>=0.7.8
|
|
26
24
|
Requires-Dist: jinja2>=3.0
|
|
27
|
-
Provides-Extra: playwright
|
|
28
|
-
Requires-Dist: playwright>=1.56.0; extra == "playwright"
|
|
29
|
-
Requires-Dist: trafilatura>=2.0.0; extra == "playwright"
|
|
30
25
|
Provides-Extra: dev
|
|
31
26
|
Requires-Dist: entari-plugin-server>=0.5.0; extra == "dev"
|
|
32
27
|
Requires-Dist: satori-python-adapter-onebot11>=0.2.5; extra == "dev"
|
|
@@ -43,7 +38,9 @@ Requires-Dist: satori-python-adapter-onebot11>=0.2.5; extra == "dev"
|
|
|
43
38
|
|
|
44
39
|
</div>
|
|
45
40
|
|
|
46
|
-
# v3.
|
|
41
|
+
# v3.3 迎来大幅度改动、现在图文不符
|
|
42
|
+
|
|
43
|
+
|
|
47
44
|
|
|
48
45
|
## 🎑 效果展示
|
|
49
46
|
|
|
@@ -140,3 +137,6 @@ hyw -t 一大段话。
|
|
|
140
137
|
### 引用回复
|
|
141
138
|
支持引用消息进行追问,机器人会自动读取被引用的消息作为上下文:
|
|
142
139
|
- **引用 + 命令**:机器人将理解被引用消息的内容(包括图片)通过 `MessageChain` 操作拼接 `Text`、`Image` 与部分 `Custom`。
|
|
140
|
+
|
|
141
|
+
UncleCode. (2024). Crawl4AI: Open-source LLM Friendly Web Crawler & Scraper [Computer software].
|
|
142
|
+
GitHub. https://github.com/unclecode/crawl4ai
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
</div>
|
|
12
12
|
|
|
13
|
-
# v3.
|
|
13
|
+
# v3.3 迎来大幅度改动、现在图文不符
|
|
14
|
+
|
|
15
|
+
|
|
14
16
|
|
|
15
17
|
## 🎑 效果展示
|
|
16
18
|
|
|
@@ -107,3 +109,6 @@ hyw -t 一大段话。
|
|
|
107
109
|
### 引用回复
|
|
108
110
|
支持引用消息进行追问,机器人会自动读取被引用的消息作为上下文:
|
|
109
111
|
- **引用 + 命令**:机器人将理解被引用消息的内容(包括图片)通过 `MessageChain` 操作拼接 `Text`、`Image` 与部分 `Custom`。
|
|
112
|
+
|
|
113
|
+
UncleCode. (2024). Crawl4AI: Open-source LLM Friendly Web Crawler & Scraper [Computer software].
|
|
114
|
+
GitHub. https://github.com/unclecode/crawl4ai
|
|
@@ -4,17 +4,15 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "entari_plugin_hyw"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.3.0"
|
|
8
8
|
description = "Use large language models to interpret chat messages"
|
|
9
9
|
authors = [{name = "kumoSleeping", email = "zjr2992@outlook.com"}]
|
|
10
10
|
dependencies = [
|
|
11
11
|
"arclet-entari[full]>=0.16.5",
|
|
12
12
|
"openai",
|
|
13
|
-
"mcp",
|
|
14
13
|
"httpx",
|
|
15
14
|
"markdown>=3.10",
|
|
16
|
-
"
|
|
17
|
-
"playwright>=1.56.0",
|
|
15
|
+
"crawl4ai>=0.7.8",
|
|
18
16
|
"jinja2>=3.0",
|
|
19
17
|
]
|
|
20
18
|
requires-python = ">=3.10"
|
|
@@ -31,7 +29,6 @@ classifiers = [
|
|
|
31
29
|
]
|
|
32
30
|
|
|
33
31
|
[project.optional-dependencies]
|
|
34
|
-
playwright = ["playwright>=1.56.0", "trafilatura>=2.0.0"]
|
|
35
32
|
dev = [
|
|
36
33
|
"entari-plugin-server>=0.5.0",
|
|
37
34
|
"satori-python-adapter-onebot11>=0.2.5",
|
|
@@ -48,4 +45,3 @@ include-package-data = true
|
|
|
48
45
|
[tool.setuptools.packages.find]
|
|
49
46
|
where = ["src"]
|
|
50
47
|
include = ["entari_plugin_hyw*"]
|
|
51
|
-
|
|
@@ -65,10 +65,8 @@ class HywConfig(BasicConfModel):
|
|
|
65
65
|
intruct_base_url: Optional[str] = None
|
|
66
66
|
intruct_system_prompt: Optional[str] = None
|
|
67
67
|
agent_system_prompt: Optional[str] = None
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
search_base_url: str = "https://duckduckgo.com/?q={query}&format=json&results_per_page={limit}"
|
|
71
|
-
image_search_base_url: str = "https://duckduckgo.com/?q={query}&iax=images&ia=images&format=json&results_per_page={limit}"
|
|
68
|
+
search_base_url: str = "https://lite.duckduckgo.com/lite/?q={query}"
|
|
69
|
+
image_search_base_url: str = "https://duckduckgo.com/?q={query}&iax=images&ia=images"
|
|
72
70
|
headless: bool = False
|
|
73
71
|
save_conversation: bool = False
|
|
74
72
|
icon: str = "openai"
|
|
@@ -89,8 +87,8 @@ class HywConfig(BasicConfModel):
|
|
|
89
87
|
intruct_output_price: Optional[float] = None
|
|
90
88
|
|
|
91
89
|
# Provider Names
|
|
92
|
-
search_name: str = "
|
|
93
|
-
search_provider: str = "
|
|
90
|
+
search_name: str = "DuckDuckGo"
|
|
91
|
+
search_provider: str = "Crawl4AI"
|
|
94
92
|
model_provider: Optional[str] = None
|
|
95
93
|
vision_model_provider: Optional[str] = None
|
|
96
94
|
intruct_model_provider: Optional[str] = None
|
|
@@ -102,13 +100,6 @@ history_manager = HistoryManager()
|
|
|
102
100
|
renderer = ContentRenderer()
|
|
103
101
|
hyw = HYW(config=conf)
|
|
104
102
|
|
|
105
|
-
@listen(Ready, once=True)
|
|
106
|
-
async def _hyw_warmup_mcp():
|
|
107
|
-
try:
|
|
108
|
-
await hyw.pipeline.warmup_mcp()
|
|
109
|
-
except Exception as e:
|
|
110
|
-
logger.warning(f"MCP Playwright warmup error: {e}")
|
|
111
|
-
|
|
112
103
|
@listen(Ready, once=True)
|
|
113
104
|
async def _run_ui_test():
|
|
114
105
|
"""Run UI rendering test on startup if configured."""
|
|
@@ -145,31 +136,43 @@ async def _run_ui_test():
|
|
|
145
136
|
|
|
146
137
|
# Mock Data for Full UI Test
|
|
147
138
|
stats = {
|
|
148
|
-
"
|
|
139
|
+
"total_time": 12.5,
|
|
149
140
|
"vision_duration": 3.2,
|
|
150
141
|
"cost": 0.0015
|
|
151
142
|
}
|
|
152
143
|
|
|
153
144
|
stages = [
|
|
154
|
-
{"name": "Vision", "model": "google/gemini-pro-vision", "time": 3.2, "cost": 0.0005, "provider": "Google"},
|
|
155
|
-
{"name": "Search", "model": "duckduckgo", "time": 1.5, "cost": 0.0, "provider": "DDG"
|
|
156
|
-
|
|
145
|
+
{"name": "Vision", "model": "google/gemini-pro-vision", "time": 3.2, "cost": 0.0005, "provider": "Google", "icon_config": "google"},
|
|
146
|
+
{"name": "Search", "model": "duckduckgo", "time": 1.5, "cost": 0.0, "provider": "DDG", "icon_config": "search",
|
|
147
|
+
"children": {"references": [
|
|
148
|
+
{"title": "Crawl4AI, Open-source LLM-Friendly Web Crawler & Scraper", "url": "https://docs.crawl4ai.com/core/llmtxt", "domain": "docs.crawl4ai.com"}
|
|
149
|
+
]}},
|
|
150
|
+
{"name": "Crawler", "model": "Crawl4AI", "time": 2.5, "cost": 0.0, "provider": "Page Fetcher", "icon_config": "browser",
|
|
151
|
+
"children": {"crawled_pages": [
|
|
152
|
+
{"title": "Quick Start - Crawl4AI Documentation (v0.7.x)", "url": "https://docs.crawl4ai.com/core/quickstart/", "domain": "docs.crawl4ai.com"},
|
|
153
|
+
{"title": "Crawl4AI Explained: The AI-Friendly Web Crawling Framework", "url": "https://scrapfly.io/blog/posts/crawl4AI-explained/", "domain": "scrapfly.io"},
|
|
154
|
+
{"title": "Llmtxt - Crawl4AI Documentation (v0.7.x)", "url": "https://docs.crawl4ai.com/core/llmtxt/", "domain": "docs.crawl4ai.com"},
|
|
155
|
+
{"title": "Multi-URL Crawling - Crawl4AI Documentation (v0.7.x)", "url": "https://docs.crawl4ai.com/advanced/multi-url-crawling/", "domain": "docs.crawl4ai.com"}
|
|
156
|
+
]}},
|
|
157
|
+
{"name": "Agent", "model": "anthropic/claude-3-5-sonnet", "time": 7.8, "cost": 0.0010, "provider": "Anthropic", "icon_config": "anthropic"}
|
|
157
158
|
]
|
|
158
159
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
{"
|
|
162
|
-
{"name": "click_element", "description": "clicking 'Downloads'", "icon": "click"}
|
|
160
|
+
# References come from search results
|
|
161
|
+
references = [
|
|
162
|
+
{"title": "Crawl4AI, Open-source LLM-Friendly Web Crawler & Scraper", "url": "https://docs.crawl4ai.com/core/llmtxt", "domain": "docs.crawl4ai.com"}
|
|
163
163
|
]
|
|
164
164
|
|
|
165
|
-
references
|
|
166
|
-
|
|
167
|
-
{"title": "
|
|
165
|
+
# Page references come from crawled pages
|
|
166
|
+
page_references = [
|
|
167
|
+
{"title": "Quick Start - Crawl4AI Documentation (v0.7.x)", "url": "https://docs.crawl4ai.com/core/quickstart/", "domain": "docs.crawl4ai.com"},
|
|
168
|
+
{"title": "Crawl4AI Explained: The AI-Friendly Web Crawling Framework", "url": "https://scrapfly.io/blog/posts/crawl4AI-explained/", "domain": "scrapfly.io"},
|
|
169
|
+
{"title": "Llmtxt - Crawl4AI Documentation (v0.7.x)", "url": "https://docs.crawl4ai.com/core/llmtxt/", "domain": "docs.crawl4ai.com"},
|
|
170
|
+
{"title": "Multi-URL Crawling - Crawl4AI Documentation (v0.7.x)", "url": "https://docs.crawl4ai.com/advanced/multi-url-crawling/", "domain": "docs.crawl4ai.com"}
|
|
168
171
|
]
|
|
169
172
|
|
|
170
173
|
output_dir = "data/cache"
|
|
171
174
|
os.makedirs(output_dir, exist_ok=True)
|
|
172
|
-
output_path = f"{output_dir}/ui_test_result.
|
|
175
|
+
output_path = f"{output_dir}/ui_test_result.jpg"
|
|
173
176
|
|
|
174
177
|
logger.info(f"UI TEST: Rendering to {output_path}...")
|
|
175
178
|
|
|
@@ -179,8 +182,9 @@ async def _run_ui_test():
|
|
|
179
182
|
output_path=output_path,
|
|
180
183
|
stats=stats,
|
|
181
184
|
stages_used=stages,
|
|
182
|
-
mcp_steps=mcp_steps,
|
|
183
185
|
references=references,
|
|
186
|
+
page_references=page_references,
|
|
187
|
+
flow_steps=[],
|
|
184
188
|
model_name="CLAUDE-3-5-SONNET",
|
|
185
189
|
provider_name="Anthropic",
|
|
186
190
|
behavior_summary="Automated Test",
|
|
@@ -429,7 +433,7 @@ async def process_request(session: Session[MessageCreatedEvent], all_param: Opti
|
|
|
429
433
|
|
|
430
434
|
# Render
|
|
431
435
|
import tempfile
|
|
432
|
-
with tempfile.NamedTemporaryFile(suffix=".
|
|
436
|
+
with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as tf:
|
|
433
437
|
output_path = tf.name
|
|
434
438
|
model_used = final_resp.get("model_used")
|
|
435
439
|
vision_model_used = final_resp.get("vision_model_used")
|
|
@@ -496,10 +500,10 @@ async def process_request(session: Session[MessageCreatedEvent], all_param: Opti
|
|
|
496
500
|
|
|
497
501
|
# 1. Behavior Summary
|
|
498
502
|
behavior_summary = "Text Generation"
|
|
499
|
-
if
|
|
500
|
-
behavior_summary = "Agentic Loop"
|
|
501
|
-
elif vision_model_used:
|
|
503
|
+
if vision_model_used:
|
|
502
504
|
behavior_summary = "Visual Analysis"
|
|
505
|
+
elif any(s.get("name") == "Search" for s in final_resp.get("stages_used", []) or []):
|
|
506
|
+
behavior_summary = "Search-Augmented"
|
|
503
507
|
|
|
504
508
|
# 2. Provider Name
|
|
505
509
|
# Try to get from m_conf (resolved above)
|
|
@@ -523,7 +527,8 @@ async def process_request(session: Session[MessageCreatedEvent], all_param: Opti
|
|
|
523
527
|
suggestions=[],
|
|
524
528
|
stats=stats_to_render,
|
|
525
529
|
references=structured.get("references", []),
|
|
526
|
-
|
|
530
|
+
page_references=structured.get("page_references", []),
|
|
531
|
+
flow_steps=structured.get("flow_steps", []),
|
|
527
532
|
stages_used=final_resp.get("stages_used", []),
|
|
528
533
|
model_name=render_model_name,
|
|
529
534
|
provider_name=provider_name,
|
|
@@ -539,7 +544,7 @@ async def process_request(session: Session[MessageCreatedEvent], all_param: Opti
|
|
|
539
544
|
|
|
540
545
|
# Send & Save
|
|
541
546
|
if not render_ok:
|
|
542
|
-
logger.error("Render failed; skipping reply. Check
|
|
547
|
+
logger.error("Render failed; skipping reply. Check Crawl4AI rendering status.")
|
|
543
548
|
if os.path.exists(output_path):
|
|
544
549
|
try:
|
|
545
550
|
os.remove(output_path)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.relative{position:relative}.-top-0\.5{top:-.125rem}.z-20{z-index:20}.m-0{margin:0}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-3{margin-bottom:.75rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.box-border{box-sizing:border-box}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.h-10{height:2.5rem}.h-2{height:.5rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-fit{height:-moz-fit-content;height:fit-content}.w-10{width:2.5rem}.w-2{width:.5rem}.w-3\.5{width:.875rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-full{width:100%}.min-w-0{min-width:0}.min-w-\[14px\]{min-width:14px}.min-w-\[16px\]{min-width:16px}.max-w-\[450px\]{max-width:450px}.max-w-\[80px\]{max-width:80px}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-default{cursor:default}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0{gap:0}.gap-0\.5{gap:.125rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.overflow-hidden,.truncate{overflow:hidden}.truncate{white-space:nowrap}.text-ellipsis,.truncate{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-sm{border-radius:.125rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l-2{border-left-width:2px}.border-blue-200{--tw-border-opacity:1;border-color:rgb(191 219 254/var(--tw-border-opacity,1))}.border-gray-100{--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.border-orange-200{--tw-border-opacity:1;border-color:rgb(254 215 170/var(--tw-border-opacity,1))}.border-white\/50{border-color:hsla(0,0%,100%,.5)}.bg-\[\#f2f2f2\]{--tw-bg-opacity:1;background-color:rgb(242 242 242/var(--tw-bg-opacity,1))}.bg-blue-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.bg-green-400{--tw-bg-opacity:1;background-color:rgb(74 222 128/var(--tw-bg-opacity,1))}.bg-orange-50{--tw-bg-opacity:1;background-color:rgb(255 247 237/var(--tw-bg-opacity,1))}.bg-pink-500{--tw-bg-opacity:1;background-color:rgb(236 72 153/var(--tw-bg-opacity,1))}.bg-purple-400{--tw-bg-opacity:1;background-color:rgb(192 132 252/var(--tw-bg-opacity,1))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.bg-white\/60{background-color:hsla(0,0%,100%,.6)}.bg-white\/80{background-color:hsla(0,0%,100%,.8)}.object-contain{-o-object-fit:contain;object-fit:contain}.p-0{padding:0}.p-2\.5{padding:.625rem}.px-0\.5{padding-left:.125rem;padding-right:.125rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3\.5{padding-top:.875rem;padding-bottom:.875rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-5{padding-bottom:1.25rem}.pb-8{padding-bottom:2rem}.pl-4{padding-left:1rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-5{padding-top:1.25rem}.pt-7{padding-top:1.75rem}.align-top{vertical-align:top}.font-mono{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace}.font-sans{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.text-\[10px\]{font-size:10px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[9px\]{font-size:9px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity,1))}.text-inherit{color:inherit}.text-orange-600{--tw-text-opacity:1;color:rgb(234 88 12/var(--tw-text-opacity,1))}.text-orange-700{--tw-text-opacity:1;color:rgb(194 65 12/var(--tw-text-opacity,1))}.text-pink-600{--tw-text-opacity:1;color:rgb(219 39 119/var(--tw-text-opacity,1))}.underline{text-decoration-line:underline}.no-underline{text-decoration-line:none}.decoration-gray-300{text-decoration-color:#d1d5db}.decoration-0{text-decoration-thickness:0}.decoration-1{text-decoration-thickness:1px}.underline-offset-2{text-underline-offset:2px}.opacity-80{opacity:.8}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-inset{--tw-ring-inset:inset}.ring-black\/5{--tw-ring-color:rgba(0,0,0,.05)}.backdrop-blur{--tw-backdrop-blur:blur(8px)}.backdrop-blur,.backdrop-blur-sm{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-shadow{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}pre::-webkit-scrollbar{height:8px;background-color:transparent}pre::-webkit-scrollbar-thumb{background-color:hsla(0,0%,100%,.2);border-radius:4px}.markdown-body h1{margin-top:1.5rem;margin-bottom:1rem;border-bottom-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1));padding-bottom:.5rem;font-size:1.5rem;line-height:2rem;font-weight:700;--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.markdown-body h2{margin-top:1.25rem;margin-bottom:.75rem;font-size:1.25rem}.markdown-body h2,.markdown-body h3{line-height:1.75rem;font-weight:700;--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.markdown-body h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.125rem}.markdown-body h4{margin-top:.75rem;margin-bottom:.5rem;font-size:1rem;line-height:1.5rem;font-weight:700;--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.markdown-body p{margin-bottom:1rem;line-height:1.75rem;--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.markdown-body ul{margin-bottom:1rem;list-style-type:disc}.markdown-body ul>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.markdown-body ul{padding-left:1.25rem;--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.markdown-body ol{margin-bottom:1rem;list-style-type:decimal}.markdown-body ol>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem*var(--tw-space-y-reverse))}.markdown-body ol{padding-left:1.25rem;--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.markdown-body li{padding-left:.25rem}.markdown-body li>p{margin-bottom:.25rem}.markdown-body a{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1));text-decoration-line:underline;text-decoration-color:#93c5fd;text-underline-offset:2px;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.markdown-body a:hover{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity,1));text-decoration-color:#1d4ed8}.markdown-body blockquote{margin-top:1rem;margin-bottom:1rem;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-left-width:4px;--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1));padding:.5rem .5rem .5rem 1rem;font-style:italic;--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.hljs-built_in,.hljs-keyword,.hljs-name,.hljs-selector-tag,.hljs-tag{color:#db2777!important}.hljs-addition,.hljs-attribute,.hljs-literal,.hljs-section,.hljs-string,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type{color:#d97706!important}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#9ca3af!important}.hljs-bullet,.hljs-number,.hljs-symbol{color:#ea580c!important}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.markdown-body code{border-radius:.25rem;--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1));padding:.125rem .375rem;font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:.875rem;line-height:1.25rem;--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity,1))}.markdown-body pre{margin-bottom:1rem;overflow-x:auto;border-radius:.5rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1));padding:1rem;font-size:.875rem;line-height:1.25rem;line-height:1.5;--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.markdown-body pre code{border-style:none;background-color:transparent;padding:0;--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity,1))}.markdown-body img{margin-top:1rem;margin-bottom:1rem;height:auto;max-width:60%;border-radius:.5rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1));--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.markdown-body table{margin-bottom:1rem;width:100%;border-collapse:collapse;font-size:.875rem;line-height:1.25rem}.markdown-body th{--tw-border-opacity:1;--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1));text-align:left;font-weight:600;--tw-text-opacity:1}.markdown-body td,.markdown-body th{border-width:1px;border-color:rgb(209 213 219/var(--tw-border-opacity,1));padding:.5rem 1rem;color:rgb(55 65 81/var(--tw-text-opacity,1))}.markdown-body td{--tw-border-opacity:1;--tw-text-opacity:1}.markdown-body hr{margin-top:1.5rem;margin-bottom:1.5rem;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1))}.markdown-body>:last-child{margin-bottom:0}.katex-display{overflow-x:auto;overflow-y:hidden;padding-top:.5rem;padding-bottom:.5rem}.mermaid{margin-top:1rem;margin-bottom:1rem;display:flex;justify-content:center;border-radius:.5rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1));padding:1rem}.citation-ref{display:inline-flex;align-items:center;justify-content:center;vertical-align:super;font-size:.75em;font-weight:700;color:#4b5563;background-color:#f3f4f6;border:1px solid #e5e7eb;border-radius:9999px;width:1.4em;height:1.4em;margin-left:2px;cursor:pointer;text-decoration:none!important;transition:all .2s;position:relative;line-height:1;box-shadow:none!important}.citation-ref:hover{background-color:#4b5563;color:#fff;text-decoration:none!important}.citation-tooltip{position:absolute;bottom:100%;left:50%;transform:translateX(-50%);margin-bottom:8px;background:#fff;border:1px solid #e5e7eb;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);border-radius:8px;padding:8px 12px;width:-moz-max-content;width:max-content;max-width:300px;z-index:50;opacity:0;visibility:hidden;transition:all .2s;pointer-events:none;font-size:12px;line-height:1.4;color:#374151;text-align:left;font-weight:400}.citation-ref:hover .citation-tooltip{opacity:1;visibility:visible;transform:translateX(-50%) translateY(-4px)}.citation-tooltip-title{font-weight:600;color:#111827;margin-bottom:2px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:280px}.citation-tooltip-url{color:#6b7280;font-size:10px;display:flex;align-items:center;gap:4px}.hover\:bg-gray-50:hover{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))}.hover\:text-black:hover{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.hover\:decoration-gray-500:hover{text-decoration-color:#6b7280}.hover\:shadow:hover{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.\[\&\>\*\:first-child\]\:\!mt-0>:first-child{margin-top:0!important}
|
{entari_plugin_hyw-3.2.112 → entari_plugin_hyw-3.3.0}/src/entari_plugin_hyw/assets/template.j2
RENAMED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</head>
|
|
20
20
|
|
|
21
21
|
<body class="bg-[#f2f2f2] p-0 box-border m-0 font-sans text-gray-800">
|
|
22
|
-
<div id="main-container" class="w-full max-w-[450px] flex flex-col gap-
|
|
22
|
+
<div id="main-container" class="w-full max-w-[450px] flex flex-col gap-0 mx-auto bg-[#f2f2f2] p-0 font-sans h-fit pb-8">
|
|
23
23
|
|
|
24
24
|
{# --- MACROS --- #}
|
|
25
25
|
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
{% endmacro %}
|
|
31
31
|
|
|
32
32
|
{% macro card_header(title, icon_html=None, subtitle_html=None, is_plain=False, icon_box_class=None) %}
|
|
33
|
-
{% set container_class = "flex items-center gap-3" if is_plain else "flex items-center gap-3 pb-3 mb-3 border-
|
|
33
|
+
{% set container_class = "flex items-center gap-3" if is_plain else "flex items-center gap-3 pb-3 mb-3 border-gray-100 border-b" %}
|
|
34
34
|
{% set default_box_class = icon_box_class if icon_box_class else "bg-gray-50 rounded-lg border border-gray-100" %}
|
|
35
35
|
<div class="{{ container_class }}">
|
|
36
36
|
{{ icon_container(icon_html, box_class=default_box_class) }}
|
|
@@ -73,16 +73,26 @@
|
|
|
73
73
|
|
|
74
74
|
{# --- MAIN CONTENT --- #}
|
|
75
75
|
|
|
76
|
+
<!-- Header: Feature Icons / Badges (Centered) -->
|
|
77
|
+
<!-- Increased top padding from pt-5 to pt-7 for more whitespace -->
|
|
78
|
+
<div class="pt-7 pb-5 px-6 flex justify-between items-center relative z-20">
|
|
79
|
+
<!-- Total Time Badge -->
|
|
80
|
+
<div class="flex items-center gap-1.5 px-3 py-1.5 bg-white/60 backdrop-blur rounded-lg shadow-sm border border-white/50">
|
|
81
|
+
<i class="ri-time-line text-gray-700 font-bold text-[13px]"></i>
|
|
82
|
+
<span class="text-[13px] font-bold text-gray-900 tracking-wide">{{ "%.1f"|format(total_time) }}s</span>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
76
86
|
<!-- Response Card (Content First) -->
|
|
77
|
-
<div class="bg-[#f2f2f2] rounded-2xl
|
|
78
|
-
<div id="markdown-content" class="markdown-body text-[15px] leading-relaxed text-gray-800">
|
|
87
|
+
<div class="bg-[#f2f2f2] rounded-2xl px-5 pt-0 pb-2 overflow-hidden">
|
|
88
|
+
<div id="markdown-content" class="markdown-body text-[15px] leading-relaxed text-gray-800 [&>*:first-child]:!mt-0">
|
|
79
89
|
{{ content_html | safe }}
|
|
80
90
|
</div>
|
|
81
91
|
</div>
|
|
82
92
|
|
|
83
93
|
<!-- Speculation Card (Optional) -->
|
|
84
94
|
{% if suggestions %}
|
|
85
|
-
<div class="flex flex-col gap-2 bg-[#f2f2f2] rounded-2xl
|
|
95
|
+
<div class="flex flex-col gap-2 bg-[#f2f2f2] rounded-2xl px-5 py-2 overflow-hidden">
|
|
86
96
|
{% set sug_icon %}
|
|
87
97
|
<i class="ri-magic-line text-lg text-pink-600"></i>
|
|
88
98
|
{% endset %}
|
|
@@ -100,7 +110,7 @@
|
|
|
100
110
|
{% endif %}
|
|
101
111
|
|
|
102
112
|
<!-- Pipeline & Children (Nested) -->
|
|
103
|
-
<div class="bg-[#f2f2f2] rounded-2xl
|
|
113
|
+
<div class="bg-[#f2f2f2] rounded-2xl px-5 pt-2 pb-5 overflow-hidden flex flex-col gap-4">
|
|
104
114
|
|
|
105
115
|
{% if stages %}
|
|
106
116
|
{% for stage in stages %}
|
|
@@ -111,13 +121,13 @@
|
|
|
111
121
|
{% set icon_box_class = color_class + " rounded-md border shrink-0" %}
|
|
112
122
|
|
|
113
123
|
{% set title_html %}
|
|
114
|
-
<span class="text-[
|
|
115
|
-
<span class="text-[
|
|
116
|
-
<span class="ml-auto text-[
|
|
124
|
+
<span class="text-[13px] font-bold uppercase text-gray-700 shrink-0">{{ stage.name }}</span>
|
|
125
|
+
<span class="text-[13px] font-medium text-gray-700 truncate min-w-0" title="{{ stage.model }}">{{ stage.model_short }}</span>
|
|
126
|
+
<span class="ml-auto text-[12px] text-gray-400 shrink-0 truncate max-w-[80px]">{{ stage.provider }}</span>
|
|
117
127
|
{% endset %}
|
|
118
128
|
|
|
119
129
|
{% set stats_html %}
|
|
120
|
-
<div class="flex items-center gap-3 text-[
|
|
130
|
+
<div class="flex items-center gap-3 text-[12px] text-gray-500 font-mono mt-0.5">
|
|
121
131
|
<span>{{ stage.time_str }}</span><span>{{ stage.cost_str }}</span>
|
|
122
132
|
</div>
|
|
123
133
|
{% endset %}
|
|
@@ -125,12 +135,12 @@
|
|
|
125
135
|
{{ list_card(stage.icon_html, title_html, subtitle_html=stats_html, is_compact=True, icon_box_class=icon_box_class) }}
|
|
126
136
|
|
|
127
137
|
{# Nested Children (Indent & Connect) #}
|
|
128
|
-
{% if stage.references or stage.
|
|
138
|
+
{% if stage.references or stage.flow_steps or stage.crawled_pages %}
|
|
129
139
|
<div class="ml-4 pl-4 border-l-2 border-gray-200 mt-2 flex flex-col gap-2">
|
|
130
140
|
|
|
131
141
|
{# References #}
|
|
132
142
|
{% if stage.references %}
|
|
133
|
-
<div class="text-[
|
|
143
|
+
<div class="text-[12px] uppercase font-bold text-blue-600 tracking-wider mb-1 mt-1">Search Results</div>
|
|
134
144
|
{% for ref in stage.references %}
|
|
135
145
|
{% set favicon_url = "https://www.google.com/s2/favicons?domain=" + ref.domain + "&sz=32" %}
|
|
136
146
|
|
|
@@ -140,42 +150,66 @@
|
|
|
140
150
|
|
|
141
151
|
{% set ref_icon_box = "bg-white rounded border border-gray-100 w-6 h-6 shrink-0" %}
|
|
142
152
|
|
|
143
|
-
{% set title_html = '<div class="text-[
|
|
144
|
-
{% set subtitle_html = '<div class="text-[
|
|
145
|
-
{% set right_html = '<div class="flex items-center justify-center min-w-[
|
|
153
|
+
{% set title_html = '<div class="text-[13px] font-medium text-gray-900 truncate underline decoration-gray-300 decoration-1 underline-offset-2 hover:text-black hover:decoration-gray-500 transition-colors">' + ref.title + '</div>' %}
|
|
154
|
+
{% set subtitle_html = '<div class="text-[12px] text-gray-700 truncate">' + ref.domain + '</div>' %}
|
|
155
|
+
{% set right_html = '<div class="flex items-center justify-center min-w-[16px] h-4 px-0.5 text-[10px] font-bold text-blue-600 bg-blue-50 border border-blue-200 rounded">' + (loop.index|string) + '</div>' %}
|
|
146
156
|
|
|
147
157
|
{{ list_card(ref_icon, title_html, subtitle_html=subtitle_html, link_url=ref.url, right_content_html=right_html, is_compact=True, icon_box_class=ref_icon_box) }}
|
|
148
158
|
{% endfor %}
|
|
149
159
|
{% endif %}
|
|
150
160
|
|
|
151
|
-
{#
|
|
152
|
-
{% if stage.
|
|
153
|
-
<div class="text-[
|
|
154
|
-
{% for step in stage.
|
|
161
|
+
{# Flow Steps #}
|
|
162
|
+
{% if stage.flow_steps %}
|
|
163
|
+
<div class="text-[12px] uppercase font-bold text-orange-600 tracking-wider mb-1 mt-1">Flow</div>
|
|
164
|
+
{% for step in stage.flow_steps %}
|
|
155
165
|
{% set icon_box_class = "rounded-md border border-gray-100 bg-white text-gray-500 shrink-0" %}
|
|
156
166
|
|
|
157
|
-
{% set title_html = '<div class="text-[
|
|
158
|
-
{% set subtitle_html = '<div class="text-[
|
|
159
|
-
{% set right_html = '<div class="flex items-center justify-center min-w-[
|
|
167
|
+
{% set title_html = '<div class="text-[13px] font-semibold text-gray-900 underline decoration-gray-300 decoration-1 underline-offset-2 truncate">' + step.description + '</div>' %}
|
|
168
|
+
{% set subtitle_html = '<div class="text-[12px] text-gray-700 leading-tight truncate">' + step.description + '</div>' %}
|
|
169
|
+
{% set right_html = '<div class="flex items-center justify-center min-w-[16px] h-4 px-0.5 text-[10px] font-bold text-orange-700 bg-orange-50 border border-orange-200 rounded">' + ('abcdefghijklmnopqrstuvwxyz'[loop.index0]) + '</div>' %}
|
|
160
170
|
|
|
161
171
|
{{ list_card(step.icon_svg, title_html, subtitle_html=subtitle_html, right_content_html=right_html, is_compact=True, icon_box_class=icon_box_class) }}
|
|
162
172
|
{% endfor %}
|
|
163
173
|
{% endif %}
|
|
164
174
|
|
|
175
|
+
{# Crawled Pages #}
|
|
176
|
+
{% if stage.crawled_pages %}
|
|
177
|
+
<div class="text-[12px] uppercase font-bold text-blue-600 tracking-wider mb-1 mt-1">Fetched Pages</div>
|
|
178
|
+
{% for page in stage.crawled_pages %}
|
|
179
|
+
{% set domain = page.url.split('/')[2] if page.url.split('/')|length > 2 else '' %}
|
|
180
|
+
{% set favicon_url = "https://www.google.com/s2/favicons?domain=" + domain + "&sz=32" %}
|
|
181
|
+
|
|
182
|
+
{% set page_icon %}
|
|
183
|
+
<img src="{{ favicon_url }}" class="w-3.5 h-3.5 rounded-sm opacity-80">
|
|
184
|
+
{% endset %}
|
|
185
|
+
|
|
186
|
+
{% set page_icon_box = "bg-white rounded border border-gray-100 w-6 h-6 shrink-0" %}
|
|
187
|
+
|
|
188
|
+
{% set title_html = '<div class="text-[13px] font-medium text-gray-900 truncate underline decoration-gray-300 decoration-1 underline-offset-2 hover:text-black hover:decoration-gray-500 transition-colors">' + page.title + '</div>' %}
|
|
189
|
+
{% set subtitle_html = '<div class="text-[12px] text-gray-500 truncate">' + domain + '</div>' %}
|
|
190
|
+
{% set right_html = '<div class="flex items-center justify-center min-w-[16px] h-4 px-0.5 text-[10px] font-bold text-orange-600 bg-orange-50 border border-orange-200 rounded">' + (loop.index|string) + '</div>' %}
|
|
191
|
+
|
|
192
|
+
{{ list_card(page_icon, title_html, subtitle_html=subtitle_html, link_url=page.url, right_content_html=right_html, is_compact=True, icon_box_class=page_icon_box) }}
|
|
193
|
+
{% endfor %}
|
|
194
|
+
{% endif %}
|
|
195
|
+
|
|
165
196
|
</div>
|
|
166
197
|
{% endif %}
|
|
167
198
|
</div>
|
|
168
199
|
{% endfor %}
|
|
169
200
|
{% endif %}
|
|
201
|
+
|
|
170
202
|
</div>
|
|
171
203
|
|
|
172
|
-
|
|
173
|
-
</div>
|
|
174
|
-
|
|
175
204
|
<script>window.REFERENCES = {{ references_json | safe }};</script>
|
|
176
205
|
|
|
177
206
|
<script>
|
|
178
207
|
document.addEventListener("DOMContentLoaded", () => {
|
|
208
|
+
// Initialize Syntax Highlighting
|
|
209
|
+
if (typeof hljs !== 'undefined') {
|
|
210
|
+
hljs.highlightAll();
|
|
211
|
+
}
|
|
212
|
+
|
|
179
213
|
// Render Math (KaTeX)
|
|
180
214
|
const contentDiv = document.getElementById("markdown-content");
|
|
181
215
|
if(typeof renderMathInElement !== 'undefined') {
|
|
@@ -190,8 +224,33 @@
|
|
|
190
224
|
});
|
|
191
225
|
}
|
|
192
226
|
|
|
193
|
-
// Process Citations
|
|
227
|
+
// Process Citations - handles `search:id` (blue) and `page:id` (orange) formats
|
|
194
228
|
function processCitations(rootNode) {
|
|
229
|
+
// 1. Handle citations inside <code> tags (generated by markdown backticks)
|
|
230
|
+
const codeElements = rootNode.querySelectorAll('code');
|
|
231
|
+
codeElements.forEach(code => {
|
|
232
|
+
const text = code.textContent.trim();
|
|
233
|
+
const match = /^(search|page):(\d+)$/i.exec(text);
|
|
234
|
+
if (match) {
|
|
235
|
+
const type = match[1].toLowerCase();
|
|
236
|
+
const id = match[2];
|
|
237
|
+
const isPage = type === "page";
|
|
238
|
+
const colorClass = isPage
|
|
239
|
+
? "text-orange-600 bg-orange-50 border-orange-200"
|
|
240
|
+
: "text-blue-600 bg-blue-50 border-blue-200";
|
|
241
|
+
|
|
242
|
+
const span = document.createElement("span");
|
|
243
|
+
// Using same badge style
|
|
244
|
+
span.innerHTML = `<span class="inline-flex items-center justify-center min-w-[14px] h-4 px-0.5 text-[9px] font-bold ${colorClass} border rounded align-top -top-0.5 relative mx-0.5 cursor-default" title="${type}:${id}">${id}</span>`;
|
|
245
|
+
|
|
246
|
+
// Replace the <code> element with our badge
|
|
247
|
+
if (code.parentNode) {
|
|
248
|
+
code.parentNode.replaceChild(span.firstElementChild, code);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// 2. Handle citations in plain text (fallback for non-backticked ones)
|
|
195
254
|
const walker = document.createTreeWalker(
|
|
196
255
|
rootNode,
|
|
197
256
|
NodeFilter.SHOW_TEXT,
|
|
@@ -202,8 +261,9 @@
|
|
|
202
261
|
const nodesToReplace = [];
|
|
203
262
|
let node;
|
|
204
263
|
while (node = walker.nextNode()) {
|
|
205
|
-
if (node.parentElement.tagName === "SCRIPT" || node.parentElement.tagName === "STYLE" || node.parentElement.tagName === "A") continue;
|
|
206
|
-
|
|
264
|
+
if (node.parentElement.tagName === "SCRIPT" || node.parentElement.tagName === "STYLE" || node.parentElement.tagName === "A" || node.parentElement.tagName === "CODE") continue;
|
|
265
|
+
// Match search:id or page:id
|
|
266
|
+
if (/(search|page):(\d+)/i.test(node.nodeValue)) {
|
|
207
267
|
nodesToReplace.push(node);
|
|
208
268
|
}
|
|
209
269
|
}
|
|
@@ -212,43 +272,31 @@
|
|
|
212
272
|
const fragment = document.createDocumentFragment();
|
|
213
273
|
let lastIndex = 0;
|
|
214
274
|
const text = textNode.nodeValue;
|
|
215
|
-
const regex =
|
|
275
|
+
const regex = /`?(search|page):(\d+)`?/gi;
|
|
216
276
|
let match;
|
|
217
277
|
|
|
218
278
|
while ((match = regex.exec(text)) !== null) {
|
|
219
279
|
fragment.appendChild(document.createTextNode(text.substring(lastIndex, match.index)));
|
|
220
280
|
|
|
221
|
-
const
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
span.innerHTML = `<a href="${url}" target="_blank" class="citation-ref" data-id="${id}">
|
|
233
|
-
${id}
|
|
234
|
-
<span class="citation-tooltip">
|
|
235
|
-
<span class="citation-tooltip-title">${title}</span>
|
|
236
|
-
<span class="citation-tooltip-url">
|
|
237
|
-
<img src="${favicon}" style="width:12px;height:12px;vertical-align:middle;margin-right:4px;">
|
|
238
|
-
${domain}
|
|
239
|
-
</span>
|
|
240
|
-
</span>
|
|
241
|
-
</a>`;
|
|
242
|
-
fragment.appendChild(span.firstElementChild);
|
|
243
|
-
} else {
|
|
244
|
-
fragment.appendChild(document.createTextNode(match[0]));
|
|
245
|
-
}
|
|
281
|
+
const type = match[1].toLowerCase();
|
|
282
|
+
const id = match[2];
|
|
283
|
+
|
|
284
|
+
const span = document.createElement("span");
|
|
285
|
+
const isPage = type === "page";
|
|
286
|
+
const colorClass = isPage
|
|
287
|
+
? "text-orange-600 bg-orange-50 border-orange-200"
|
|
288
|
+
: "text-blue-600 bg-blue-50 border-blue-200";
|
|
289
|
+
|
|
290
|
+
span.innerHTML = `<span class="inline-flex items-center justify-center min-w-[14px] h-4 px-0.5 text-[9px] font-bold ${colorClass} border rounded align-top -top-0.5 relative mx-0.5 cursor-default" title="${type}:${id}">${id}</span>`;
|
|
291
|
+
fragment.appendChild(span.firstElementChild);
|
|
246
292
|
|
|
247
293
|
lastIndex = regex.lastIndex;
|
|
248
294
|
}
|
|
249
295
|
|
|
250
296
|
fragment.appendChild(document.createTextNode(text.substring(lastIndex)));
|
|
251
|
-
textNode.parentNode
|
|
297
|
+
if (textNode.parentNode) {
|
|
298
|
+
textNode.parentNode.replaceChild(fragment, textNode);
|
|
299
|
+
}
|
|
252
300
|
});
|
|
253
301
|
}
|
|
254
302
|
|
|
@@ -15,19 +15,18 @@ class HYWConfig:
|
|
|
15
15
|
intruct_model_name: Optional[str] = None
|
|
16
16
|
intruct_api_key: Optional[str] = None
|
|
17
17
|
intruct_base_url: Optional[str] = None
|
|
18
|
-
search_base_url: str = "https://duckduckgo.com/?q={query}
|
|
19
|
-
image_search_base_url: str = "https://duckduckgo.com/?q={query}&iax=images&ia=images
|
|
18
|
+
search_base_url: str = "https://lite.duckduckgo.com/lite/?q={query}"
|
|
19
|
+
image_search_base_url: str = "https://duckduckgo.com/?q={query}&iax=images&ia=images"
|
|
20
20
|
extra_body: Optional[Dict[str, Any]] = None
|
|
21
21
|
temperature: float = 0.4
|
|
22
22
|
max_turns: int = 10
|
|
23
23
|
icon: str = "openai" # logo for primary model
|
|
24
24
|
vision_icon: Optional[str] = None # logo for vision model (falls back to icon when absent)
|
|
25
|
+
instruct_icon: Optional[str] = None # logo for instruct model
|
|
25
26
|
enable_browser_fallback: bool = False
|
|
26
27
|
vision_system_prompt: Optional[str] = None
|
|
27
28
|
intruct_system_prompt: Optional[str] = None
|
|
28
29
|
agent_system_prompt: Optional[str] = None
|
|
29
|
-
playwright_mcp_command: str = "npx"
|
|
30
|
-
playwright_mcp_args: Optional[List[str]] = None
|
|
31
30
|
input_price: Optional[float] = None # $ per 1M input tokens
|
|
32
31
|
output_price: Optional[float] = None # $ per 1M output tokens
|
|
33
32
|
vision_input_price: Optional[float] = None
|