Skip to content

Commit 2da934d

Browse files
committed
feat(filters): upgrade markdown-normalizer to v1.2.7
- Fix Issue #49: resolve greedy regex matching in consecutive emphasis - Add LaTeX formula protection to prevent corruption of \times, \nu, etc. - Expand i18n support to 12 languages with strict alignment - Fix NameError in Request import during testing
1 parent 18ada2a commit 2da934d

File tree

16 files changed

+983
-1011
lines changed

16 files changed

+983
-1011
lines changed

GEMINI.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# OpenWebUI Extensions — Gemini CLI Project Context
2+
3+
> This file is loaded automatically by Gemini CLI as project-level instructions.
4+
> Full engineering spec: `.github/copilot-instructions.md`
5+
6+
---
7+
8+
## Project Overview
9+
10+
**openwebui-extensions** is a collection of OpenWebUI plugins authored by Fu-Jie.
11+
12+
Repository: `https://github.com/Fu-Jie/openwebui-extensions`
13+
14+
Plugin types: `actions` / `filters` / `pipes` / `pipelines` / `tools`
15+
16+
---
17+
18+
## Non-Negotiable Rules
19+
20+
1. **No auto-commit.** Never run `git commit`, `git push`, or `gh pr create` unless the user says "发布" / "release" / "commit it". Default output = local file changes only.
21+
2. **No silent failures.** All errors must surface via `__event_emitter__` notification or backend `logging`.
22+
3. **No hardcoded model IDs.** Default to the current conversation model; let `Valves` override.
23+
4. **Chinese responses.** Reply in Simplified Chinese for all planning, explanations, and status summaries. English only for code, commit messages, and docstrings.
24+
25+
---
26+
27+
## Plugin File Contract
28+
29+
Every plugin MUST be a **single-file i18n** Python module:
30+
31+
```text
32+
plugins/{type}/{name}/{name}.py ← single source file, built-in i18n
33+
plugins/{type}/{name}/README.md ← English docs
34+
plugins/{type}/{name}/README_CN.md ← Chinese docs
35+
```
36+
37+
### Docstring (required fields)
38+
39+
```python
40+
"""
41+
title: Plugin Display Name
42+
author: Fu-Jie
43+
author_url: https://github.com/Fu-Jie/openwebui-extensions
44+
funding_url: https://github.com/open-webui
45+
version: 0.1.0
46+
description: One-line description.
47+
"""
48+
```
49+
50+
### Required patterns
51+
52+
- `Valves(BaseModel)` with `UPPER_SNAKE_CASE` fields
53+
- `_get_user_context(__user__)` — never access `__user__` directly
54+
- `_get_chat_context(body, __metadata__)` — never infer IDs ad-hoc
55+
- `_emit_status(emitter, msg, done)` / `_emit_notification(emitter, content, type)`
56+
- Async I/O only — wrap sync calls with `asyncio.to_thread`
57+
- `logging` for backend logs — no bare `print()` in production
58+
59+
---
60+
61+
## Antigravity Development Rules
62+
63+
When the user invokes antigravity mode (high-speed iteration), enforce these safeguards automatically:
64+
65+
| Rule | Detail |
66+
|------|--------|
67+
| Small reversible edits | One logical change per file per operation |
68+
| Timeout guards | `asyncio.wait_for(..., timeout=2.0)` on all `__event_call__` JS executions |
69+
| Path sandbox | Verify every workspace path stays inside the repo root before read/write |
70+
| Fallback chains | API upload → DB + local copy; never a single point of failure |
71+
| Progressive status | `status(done=False)` at start, `status(done=True)` on end, `notification(error)` on failure |
72+
| Validate before emit | Check `emitter is not None` before every `await emitter(...)` |
73+
74+
---
75+
76+
## File Creation & Delivery Protocol (3-Step)
77+
78+
1. `local write` — create artifact inside workspace scope
79+
2. `publish_file_from_workspace(filename='...')` — migrate to OpenWebUI storage (S3-compatible)
80+
3. Return `/api/v1/files/{id}/content` download link in Markdown
81+
82+
Set `skip_rag=true` metadata on generated downloadable artifacts.
83+
84+
---
85+
86+
## Copilot SDK Tool Definition (critical)
87+
88+
```python
89+
from pydantic import BaseModel, Field
90+
from copilot import define_tool
91+
92+
class MyToolParams(BaseModel):
93+
query: str = Field(..., description="Search query")
94+
95+
my_tool = define_tool(
96+
name="my_tool",
97+
description="...",
98+
params_type=MyToolParams, # REQUIRED — prevents empty schema hallucination
99+
)(async_impl_fn)
100+
```
101+
102+
---
103+
104+
## Streaming Output Format (OpenWebUI 0.8.x)
105+
106+
- Reasoning: `<think>\n...\n</think>\n` — close BEFORE normal content or tool cards
107+
- Tool cards: `<details type="tool_calls" id="..." name="..." arguments="&quot;...&quot;" result="&quot;...&quot;" done="true">\n<summary>Tool Executed</summary>\n</details>\n\n`
108+
- Escape ALL `"` inside `arguments`/`result` attributes as `&quot;`
109+
- Status events via `__event_emitter__` — do NOT pollute the content stream with debug text
110+
111+
---
112+
113+
## Documentation Sync (when changing a plugin)
114+
115+
Must update ALL of these or the PR check fails:
116+
117+
1. `plugins/{type}/{name}/{name}.py` — version in docstring
118+
2. `plugins/{type}/{name}/README.md` — version, What's New
119+
3. `plugins/{type}/{name}/README_CN.md` — same
120+
4. `docs/plugins/{type}/{name}.md` — mirror README
121+
5. `docs/plugins/{type}/{name}.zh.md` — mirror README_CN
122+
6. `docs/plugins/{type}/index.md` — version badge
123+
7. `docs/plugins/{type}/index.zh.md` — version badge
124+
125+
---
126+
127+
## i18n & Language Standards
128+
129+
1. **Alignment**: Keep the number of supported languages in `TRANSLATIONS` consistent with major plugins (e.g., `smart-mind-map`).
130+
2. **Supported Languages**: en-US, zh-CN, zh-HK, zh-TW, ko-KR, ja-JP, fr-FR, de-DE, es-ES, it-IT, vi-VN, id-ID.
131+
3. **Fallback Map**: Must include variant redirects (e.g., `es-MX` -> `es-ES`, `fr-CA` -> `fr-FR`).
132+
4. **Tooltips**: All `description` fields in `Valves` must be **English only** to maintain clean UI.
133+
134+
---
135+
136+
## Commit Message Format
137+
138+
```text
139+
type(scope): brief English description
140+
141+
- Key change 1
142+
- Key change 2
143+
```
144+
145+
Types: `feat` / `fix` / `docs` / `refactor` / `chore`
146+
Scope: plugin folder name (e.g., `github-copilot-sdk`)
147+
148+
---
149+
150+
## Full Reference
151+
152+
`.github/copilot-instructions.md` — complete engineering specification (1000+ lines)
153+
`.agent/workflows/plugin-development.md` — step-by-step development workflow
154+
`.agent/rules/antigravity.md` — antigravity mode detailed rules
155+
`docs/development/copilot-engineering-plan.md` — design baseline

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ A collection of enhancements, plugins, and prompts for [OpenWebUI](https://githu
2626
| :---: | :--- | :---: | :---: | :---: | :---: |
2727
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | ![p1_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_version.json&style=flat) | ![p1_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_dl.json&style=flat) | ![p1_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--22-gray?style=flat) |
2828
| 🥈 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | ![p2_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_version.json&style=flat) | ![p2_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_dl.json&style=flat) | ![p2_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--13-gray?style=flat) |
29-
| 🥉 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | ![p3_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_version.json&style=flat) | ![p3_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_dl.json&style=flat) | ![p3_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--13-gray?style=flat) |
29+
| 🥉 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | ![p3_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_version.json&style=flat) | ![p3_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_dl.json&style=flat) | ![p3_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--24-gray?style=flat) |
3030
| 4️⃣ | [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | ![p4_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_version.json&style=flat) | ![p4_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_dl.json&style=flat) | ![p4_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--13-gray?style=flat) |
3131
| 5️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | ![p5_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_version.json&style=flat) | ![p5_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_dl.json&style=flat) | ![p5_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--21-gray?style=flat) |
3232
| 6️⃣ | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | ![p6_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_version.json&style=flat) | ![p6_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_dl.json&style=flat) | ![p6_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--13-gray?style=flat) |

README_CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ OpenWebUI 增强功能集合。包含个人开发与收集的插件、提示词
2323
| :---: | :--- | :---: | :---: | :---: | :---: |
2424
| 🥇 | [Smart Mind Map](https://openwebui.com/posts/turn_any_text_into_beautiful_mind_maps_3094c59a) | ![p1_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_version.json&style=flat) | ![p1_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_dl.json&style=flat) | ![p1_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p1_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--22-gray?style=flat) |
2525
| 🥈 | [Smart Infographic](https://openwebui.com/posts/smart_infographic_ad6f0c7f) | ![p2_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_version.json&style=flat) | ![p2_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_dl.json&style=flat) | ![p2_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p2_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--13-gray?style=flat) |
26-
| 🥉 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | ![p3_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_version.json&style=flat) | ![p3_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_dl.json&style=flat) | ![p3_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--13-gray?style=flat) |
26+
| 🥉 | [Markdown Normalizer](https://openwebui.com/posts/markdown_normalizer_baaa8732) | ![p3_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_version.json&style=flat) | ![p3_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_dl.json&style=flat) | ![p3_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p3_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--24-gray?style=flat) |
2727
| 4️⃣ | [Export to Word Enhanced](https://openwebui.com/posts/export_to_word_enhanced_formatting_fca6a315) | ![p4_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_version.json&style=flat) | ![p4_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_dl.json&style=flat) | ![p4_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p4_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--13-gray?style=flat) |
2828
| 5️⃣ | [Async Context Compression](https://openwebui.com/posts/async_context_compression_b1655bc8) | ![p5_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_version.json&style=flat) | ![p5_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_dl.json&style=flat) | ![p5_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p5_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--21-gray?style=flat) |
2929
| 6️⃣ | [Export to Excel](https://openwebui.com/posts/export_mulit_table_to_excel_244b8f9d) | ![p6_version](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_version.json&style=flat) | ![p6_dl](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_dl.json&style=flat) | ![p6_vw](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_p6_vw.json&style=flat) | ![updated](https://img.shields.io/badge/2026--02--13-gray?style=flat) |

docs/plugins/filters/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Filters act as middleware in the message pipeline:
5252

5353
Fixes common Markdown formatting issues in LLM outputs, including Mermaid syntax, code blocks, and LaTeX formulas.
5454

55-
**Version:** 1.2.4
55+
**Version:** 1.2.7
5656

5757
[:octicons-arrow-right-24: Documentation](markdown_normalizer.md)
5858

docs/plugins/filters/index.zh.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Filter 充当消息管线中的中间件:
5252

5353
修复 LLM 输出中常见的 Markdown 格式问题,包括 Mermaid 语法、代码块和 LaTeX 公式。
5454

55-
**版本:** 1.2.4
55+
**版本:** 1.2.7
5656

5757
[:octicons-arrow-right-24: 查看文档](markdown_normalizer.zh.md)
5858

0 commit comments

Comments
 (0)